Репозиторий ALT Linux backports/2.4
Последнее обновление: 9 июля 2008 | Пакетов: 497 | Посещений: 1592036
 поиск   регистрация   авторизация 
 
Группа :: Сети/Чат
Пакет: gaim

 Главная   Изменения   Спек   Патчи   Загрузить   Bugs and FR 

Патч: gaim-0.79.oscar.encoding.bobuk.patch


diff -bBpurN gaim-0.79.old/src/protocols/oscar/aim.h gaim-0.79/src/protocols/oscar/aim.h
--- gaim-0.79.old/src/protocols/oscar/aim.h	2004-05-20 06:03:34.000000000 +0400
+++ gaim-0.79/src/protocols/oscar/aim.h	2004-06-25 11:59:40.846187920 +0400
@@ -683,8 +683,8 @@ struct aim_chat_roominfo {
 
 #define AIM_IMFLAGS_AWAY		0x0001 /* mark as an autoreply */
 #define AIM_IMFLAGS_ACK			0x0002 /* request a receipt notice */
-#define AIM_IMFLAGS_UNICODE		0x0004
-#define AIM_IMFLAGS_ISO_8859_1		0x0008
+#define AIM_IMFLAGS_UNICODE		0x0004 /* Message encoded by Unicode */ 
+#define AIM_IMFLAGS_8BIT_CHARSET	0x0008 /* Message encoded local specific 8 bit charset */
 #define AIM_IMFLAGS_BUDDYREQ		0x0010 /* buddy icon requested */
 #define AIM_IMFLAGS_HASICON		0x0020 /* already has icon */
 #define AIM_IMFLAGS_SUBENC_MACINTOSH	0x0040 /* damn that Steve Jobs! */
diff -bBpurN gaim-0.79.old/src/protocols/oscar/faimconfig.h gaim-0.79/src/protocols/oscar/faimconfig.h
--- gaim-0.79.old/src/protocols/oscar/faimconfig.h	2001-09-12 04:39:51.000000000 +0400
+++ gaim-0.79/src/protocols/oscar/faimconfig.h	2004-06-25 11:59:39.324419264 +0400
@@ -40,6 +40,11 @@
 #define FAIM_LOGIN_PORT 5190
 
 /*
+ * Default 8 bit charset.
+ */
+#define FAIM_DEFAULT_CHARSET "ISO-8859-1"
+
+/*
  * Size of the SNAC caching hash.
  *
  * Default: 16
diff -bBpurN gaim-0.79.old/src/protocols/oscar/ft.c gaim-0.79/src/protocols/oscar/ft.c
--- gaim-0.79.old/src/protocols/oscar/ft.c	2004-05-26 08:55:10.000000000 +0400
+++ gaim-0.79/src/protocols/oscar/ft.c	2004-06-25 11:59:37.126753360 +0400
@@ -309,7 +309,7 @@ faim_export int aim_odc_send_typing(aim_
  * @param conn The already-connected ODC connection.
  * @param msg Null-terminated string to send.
  * @param len The length of the message to send, including binary data.
- * @param encoding 0 for ascii, 2 for Unicode, 3 for ISO 8859-1.
+ * @param encoding 0 for ascii, 2 for Unicode, 3 for 8 bit local charset
  * @param isawaymsg 0 if this is not an auto-response, 1 if it is.
  * @return Return 0 if no errors, otherwise return the error number.
  */
@@ -864,7 +864,7 @@ faim_export int aim_oft_sendheader(aim_s
 	fh->lsizeoffset = 0x10;
 
 	/* apparently 0 is ASCII, 2 is UCS-2 */
-	/* it is likely that 3 is ISO 8859-1 */
+	/* it is likely that 3 is 8 bit local charset */
 	/* I think "nlanguage" might be the same thing as "subenc" in im.c */
 	fh->nencode = 0x0000;
 	fh->nlanguage = 0x0000;
diff -bBpurN gaim-0.79.old/src/protocols/oscar/im.c gaim-0.79/src/protocols/oscar/im.c
--- gaim-0.79.old/src/protocols/oscar/im.c	2004-05-20 04:14:14.000000000 +0400
+++ gaim-0.79/src/protocols/oscar/im.c	2004-06-25 11:59:35.706969200 +0400
@@ -205,8 +205,8 @@ static int aim_im_paraminfo(aim_session_
  *                        made up of UNICODE duples.  If you set
  *                        this, you'd better be damn sure you know
  *                        what you're doing.
- *   AIM_IMFLAGS_ISO_8859_1 -- The message contains the ASCII8 subset
- *                        known as ISO-8859-1.  
+ *   AIM_IMFLAGS_8BIT_CHARSET -- The message contains the local specific 8 bit charset 
+ *                        
  *
  * Generally, you should use the lowest encoding possible to send
  * your message.  If you only use basic punctuation and the generic
@@ -237,6 +237,7 @@ static int aim_im_paraminfo(aim_session_
  * XXX - more precise verification that we never send SNACs larger than 8192
  * XXX - check SNAC size for multipart
  *
+ * ISO-8859-1 changed to user definable charset. Olleg
  */
 faim_export int aim_im_sendch1_ext(aim_session_t *sess, struct aim_sendimext_args *args)
 {
@@ -1317,9 +1318,9 @@ faim_export void aim_mpmsg_free(aim_sess
 static int incomingim_ch1_parsemsgs(aim_session_t *sess, fu8_t *data, int len, struct aim_incomingim_ch1_args *args)
 {
 	static const fu16_t charsetpri[] = {
-		0x0000, /* ASCII first */
-		0x0003, /* then ISO-8859-1 */
 		0x0002, /* UNICODE as last resort */
+		0x0003, /* then local specific 8bit charset */
+		0x0000, /* ASCII first */
 	};
 	static const int charsetpricount = 3;
 	int i;
@@ -1393,7 +1394,7 @@ static int incomingim_ch1_parsemsgs(aim_
 			else if (args->charset == 0x0002)
 				args->icbmflags |= AIM_IMFLAGS_UNICODE;
 			else if (args->charset == 0x0003)
-				args->icbmflags |= AIM_IMFLAGS_ISO_8859_1;
+				args->icbmflags |= AIM_IMFLAGS_8BIT_CHARSET;
 			else if (args->charset == 0xffff)
 				; /* no encoding (yeep!) */
 
diff -bBpurN gaim-0.79.old/src/protocols/oscar/oscar.c gaim-0.79/src/protocols/oscar/oscar.c
--- gaim-0.79.old/src/protocols/oscar/oscar.c	2004-06-25 02:22:22.000000000 +0400
+++ gaim-0.79/src/protocols/oscar/oscar.c	2004-06-25 11:59:31.770567624 +0400
@@ -309,37 +309,59 @@ static void oscar_free_buddyinfo(void *d
 	g_free(bi);
 }
 
-static fu32_t oscar_encoding_check(const char *utf8)
+static gchar* oscar_convert(const gchar *str, gssize len, const gchar *to_codeset, const gchar *from_codeset, gsize *bytes_written) {
+	gchar *r;
+	GError *err=NULL;
+	g_return_val_if_fail(str != NULL, NULL);
+	r= g_convert(str,len,to_codeset,from_codeset,NULL,bytes_written,&err);
+	if (err) {
+		gaim_debug_error("oscar","Error converting from %s to %s: %s\n",from_codeset,to_codeset,err->message);
+		g_error_free(err);
+	}
+	return r;
+}
+static gchar* oscar_unicode_to_utf8(const gchar* str, gssize len) {
+	g_return_val_if_fail(str != NULL, NULL);
+	return oscar_convert(str,len,"UTF-8","UCS-2BE",NULL);
+}
+static gchar* oscar_unicode_from_utf8(const gchar* str, gssize len, gsize *bytes_written) {
+	g_return_val_if_fail(str != NULL, NULL);
+	return oscar_convert(str,len,"UCS-2BE","UTF-8",bytes_written);
+}
+static gchar* oscar_charset_to_utf8(const gchar* str, gssize len) {
+	g_return_val_if_fail(str != NULL, NULL);
+	return oscar_convert(str,len,"UTF-8",gaim_prefs_get_string("/plugins/prpl/oscar/charset"),NULL);
+}
+static gchar* oscar_charset_from_utf8(const gchar* str, gssize len, gsize *bytes_written) {
+	g_return_val_if_fail(str != NULL, NULL);
+	return oscar_convert(str,len,gaim_prefs_get_string("/plugins/prpl/oscar/charset"),"UTF-8",bytes_written);
+}
+
+static fu32_t oscar_encoding_check(const gchar *utf8, gssize len)
 {
 	int i = 0;
 	fu32_t encodingflag = 0;
+	gchar *tmp;
 
 	/* Determine how we can send this message.  Per the warnings elsewhere 
 	 * in this file, these little checks determine the simplest encoding 
 	 * we can use for a given message send using it. */
-	while (utf8[i]) {
+	while (utf8[i] && i<len) {
 		if ((unsigned char)utf8[i] > 0x7f) {
 			/* not ASCII! */
-			encodingflag = AIM_IMFLAGS_ISO_8859_1;
+			encodingflag = AIM_IMFLAGS_8BIT_CHARSET;
 			break;
 		}
 		i++;
 	}
-	while (utf8[i]) {
-		/* ISO-8859-1 is 0x00-0xbf in the first byte
-		 * followed by 0xc0-0xc3 in the second */
-		if ((unsigned char)utf8[i] < 0x80) {
-			i++;
-			continue;
-		} else if (((unsigned char)utf8[i] & 0xfc) == 0xc0 &&
-			   ((unsigned char)utf8[i + 1] & 0xc0) == 0x80) {
-			i += 2;
-			continue;
-		}
+	if (encodingflag) { // Not ASCII7
+	    // Can I convert from utf8 to 8 bit charset?	
+	    tmp = g_convert(utf8,len,gaim_prefs_get_string("/plugins/prpl/oscar/charset"),"UTF-8",NULL,NULL,NULL);
+	    if (tmp) // Okey, converted
+		    g_free(tmp);
+	    else // I can't, thus unicode
 		encodingflag = AIM_IMFLAGS_UNICODE;
-		break;
 	}
-
 	return encodingflag;
 }
 
@@ -373,21 +395,21 @@ static gchar *oscar_encoding_extract(con
  */
 static fu32_t oscar_encoding_parse(const char *encoding)
 {
+	const char* const charset= gaim_prefs_get_string("/plugins/prpl/oscar/charset");
 	if ((encoding == NULL) || encoding[0] == '\0') {
-		gaim_debug_warning("oscar", "Empty encoding, assuming ASCII\n");
-		return 0;
+		gaim_debug_warning("oscar", "Empty encoding, assuming %s\n",charset);
+		return AIM_IMFLAGS_8BIT_CHARSET;
 	}
 
 	if (!strcmp(encoding, "us-ascii") || !strcmp(encoding, "utf-8")) {
 		/* UTF-8 is our native encoding, ASCII is a proper subset */
 		return 0;
-	} else if (!strcmp(encoding, "iso-8859-1")) {
-		return AIM_IMFLAGS_ISO_8859_1;
+	} else if (!g_ascii_strcasecmp(encoding,charset)) {
+		return AIM_IMFLAGS_8BIT_CHARSET;
 	} else if (!strcmp(encoding, "unicode-2-0")) {
 		return AIM_IMFLAGS_UNICODE;
 	} else {
-		gaim_debug_warning("oscar",
-				   "Unrecognized character encoding '%s', attempting to convert to utf8 anyway\n", encoding);
+		gaim_debug_info("oscar","Unexpected character encoding '%s', attempting to convert to utf8\n", encoding);
 		return 99;
 	}
 }
@@ -399,18 +421,18 @@ gchar *oscar_encoding_to_utf8(const char
 
 	switch (flags) {
 	case 0:
-		utf8 = g_convert(text, textlen, "UTF-8", "UTF-8", NULL, NULL, NULL);
+		utf8 = g_strndup(text, textlen);
 		break;
-	case AIM_IMFLAGS_ISO_8859_1:
-		utf8 = g_convert(text, textlen, "UTF-8", "ISO-8859-1", NULL, NULL, NULL);
+	case AIM_IMFLAGS_8BIT_CHARSET:
+		utf8 = oscar_charset_to_utf8(text, textlen);
 		break;
 	case AIM_IMFLAGS_UNICODE:
-		utf8 = g_convert(text, textlen, "UTF-8", "UCS-2BE", NULL, NULL, NULL);
+		utf8 = oscar_unicode_to_utf8(text, textlen);
 		break;
 	case 99:
-		utf8 = g_convert(text, textlen, "UTF-8", encoding, NULL, NULL, NULL);
+		utf8 = oscar_convert(text, textlen, "UTF-8", encoding,NULL);
 		if (utf8 == NULL) {
-			utf8 = g_convert(text, textlen, "UTF-8", "UTF-8", NULL, NULL, NULL);
+			utf8 = g_strndup(text, textlen);
 		}
 		break;
 	}
@@ -538,7 +560,7 @@ static void oscar_string_append(GString 
 {
 	gchar *utf8;
 
-	if (value && value[0] && (utf8 = gaim_utf8_try_convert(value))) {
+	if (value && value[0] && (utf8 = oscar_charset_to_utf8(value,strlen(value)))) {
 		g_string_append_printf(str, "%s<b>%s:</b> %s", newline, name, utf8);
 		g_free(utf8);
 	}
@@ -3016,10 +3038,9 @@ static int incomingim_chan1(aim_session_
 	GaimAccount *account = gaim_connection_get_account(gc);
 	gchar *tmp;
 	GaimConvImFlags flags = 0;
-	gsize convlen;
-	GError *err = NULL;
 	struct buddyinfo *bi;
 	const char *iconfile;
+	const char* const charset=gaim_prefs_get_string("/plugins/prpl/oscar/charset"); 
 
 	bi = g_hash_table_lookup(od->buddyinfo, gaim_normalize(account, userinfo->sn));
 	if (!bi) {
@@ -3089,13 +3110,9 @@ static int incomingim_chan1(aim_session_
 		if (!args->msg || !args->msglen)
 			return 1;
 
-		tmp = g_convert(args->msg, args->msglen, "UTF-8", "UCS-2BE", NULL, &convlen, &err);
-		if (err) {
-			gaim_debug_info("oscar",
-					   "Unicode IM conversion: %s\n", err->message);
+		tmp = oscar_unicode_to_utf8(args->msg, args->msglen);
+		if (!tmp)
 			tmp = g_strdup(_("(There was an error receiving this message)"));
-			g_error_free(err);
-		}
 	} else {
 		/* This will get executed for both AIM_IMFLAGS_ISO_8859_1 and
 		 * unflagged messages, which are ASCII.  That's OK because
@@ -3104,20 +3121,19 @@ static int incomingim_chan1(aim_session_
 		 * gaim (everything before 0.60) and other broken clients
 		 * that will happily send ISO-8859-1 without marking it as
 		 * such */
-		if (args->icbmflags & AIM_IMFLAGS_ISO_8859_1)
-			gaim_debug_info("oscar",
-					   "Received ISO-8859-1 IM\n");
+		/* ISO-8859-1 changed to preferable charset. Suppose 8 bit charset will be
+		   superset of ASCII7 (for instance to work with licq).
+		   Olleg 
+		 */ 
+		if (args->icbmflags & AIM_IMFLAGS_8BIT_CHARSET) 
+			gaim_debug_info("oscar", "Received %s IM\n",charset);
 
 		if (!args->msg || !args->msglen)
 			return 1;
 
-		tmp = g_convert(args->msg, args->msglen, "UTF-8", "ISO-8859-1", NULL, &convlen, &err);
-		if (err) {
-			gaim_debug_info("oscar",
-					   "ISO-8859-1 IM conversion: %s\n", err->message);
+		tmp = oscar_charset_to_utf8(args->msg, args->msglen);
+		if (!tmp)
 			tmp = g_strdup(_("(There was an error receiving this message)"));
-			g_error_free(err);
-		}
 	}
 
 	/*
@@ -3463,7 +3479,6 @@ static void gaim_icq_buddyadd(struct nam
 static int incomingim_chan4(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_t *userinfo, struct aim_incomingim_ch4_args *args, time_t t) {
 	GaimConnection *gc = sess->aux_data;
 	gchar **msg1, **msg2;
-	GError *err = NULL;
 	int i, numtoks;
 
 	if (!args->type || !args->msg || !args->uin)
@@ -3478,13 +3493,7 @@ static int incomingim_chan4(aim_session_
 	msg2 = (gchar **)g_malloc((numtoks+1)*sizeof(gchar *));
 	for (i=0; msg1[i]; i++) {
 		gaim_str_strip_cr(msg1[i]);
-		msg2[i] = g_convert(msg1[i], strlen(msg1[i]), "UTF-8", "ISO-8859-1", NULL, NULL, &err);
-		if (err) {
-			gaim_debug_error("oscar",
-					   "Error converting a string from ISO-8859-1 to "
-					   "UTF-8 in oscar ICBM channel 4 parsing\n");
-			g_error_free(err);
-		}
+		msg2[i] = oscar_charset_to_utf8(msg1[i], strlen(msg1[i]));
 	}
 	msg2[i] = NULL;
 
@@ -4839,14 +4848,14 @@ static int gaim_icqinfo(aim_session_t *s
 	}
 	oscar_string_append(str, "\n<br>", _("First Name"), info->first);
 	oscar_string_append(str, "\n<br>", _("Last Name"), info->last);
-	if (info->email && info->email[0] && (utf8 = gaim_utf8_try_convert(info->email))) {
+	if (info->email && info->email[0] && (utf8 = oscar_charset_to_utf8(info->email,strlen(info->email)))) {
 		g_string_append_printf(str, "\n<br><b>%s:</b> <a href=\"mailto:%s\">%s</a>", _("Email Address"), utf8, utf8);
 		g_free(utf8);
 	}
 	if (info->numaddresses && info->email2) {
 		int i;
 		for (i = 0; i < info->numaddresses; i++) {
-			if (info->email2[i] && info->email2[i][0] && (utf8 = gaim_utf8_try_convert(info->email2[i]))) {
+			if (info->email2[i] && info->email2[i][0] && (utf8 = oscar_charset_to_utf8(info->email2[i],strlen(info->email2[i])))) {
 				g_string_append_printf(str, "\n<br><b>%s:</b> <a href=\"mailto%s\">%s</a>", _("Email Address"), utf8, utf8);
 				g_free(utf8);
 			}
@@ -4869,11 +4878,11 @@ static int gaim_icqinfo(aim_session_t *s
 		snprintf(age, sizeof(age), "%hhd", info->age);
 		oscar_string_append(str, "\n<br>", _("Age"), age);
 	}
-	if (info->personalwebpage && info->personalwebpage[0] && (utf8 = gaim_utf8_try_convert(info->personalwebpage))) {
+	if (info->personalwebpage && info->personalwebpage[0] && (utf8 = oscar_charset_to_utf8(info->personalwebpage,strlen(info->personalwebpage)))) {
 		g_string_append_printf(str, "\n<br><b>%s:</b> <a href=\"%s\">%s</a>", _("Personal Web Page"), utf8, utf8);
 		g_free(utf8);
 	}
-	if (info->info && info->info[0] && (utf8 = gaim_utf8_try_convert(info->info))) {
+	if (info->info && info->info[0] && (utf8 = oscar_charset_to_utf8(info->info,strlen(info->info)))) {
 		g_string_append_printf(str, "<hr><b>%s:</b><br>%s", _("Additional Information"), utf8);
 		g_free(utf8);
 	}
@@ -4899,7 +4908,7 @@ static int gaim_icqinfo(aim_session_t *s
 		oscar_string_append(str, "\n<br>", _("Company"), info->workcompany);
 		oscar_string_append(str, "\n<br>", _("Division"), info->workdivision);
 		oscar_string_append(str, "\n<br>", _("Position"), info->workposition);
-		if (info->workwebpage && info->workwebpage[0] && (utf8 = gaim_utf8_try_convert(info->workwebpage))) {
+		if (info->workwebpage && info->workwebpage[0] && (utf8 = oscar_charset_to_utf8(info->workwebpage,strlen(info->workwebpage)))) {
 			g_string_append_printf(str, "\n<br><b>%s:</b> <a href=\"%s\">%s</a>", _("Web Page"), utf8, utf8);
 			g_free(utf8);
 		}
@@ -4926,7 +4935,7 @@ static int gaim_icqalias(aim_session_t *
 	info = va_arg(ap, struct aim_icq_info *);
 	va_end(ap);
 
-	if (info->uin && info->nick && info->nick[0] && (utf8 = gaim_utf8_try_convert(info->nick))) {
+	if (info->uin && info->nick && info->nick[0] && (utf8 = oscar_charset_to_utf8(info->nick,strlen(info->nick)))) {
 		g_snprintf(who, sizeof(who), "%u", info->uin);
 		serv_got_alias(gc, who, utf8);
 		if ((b = gaim_find_buddy(gc->account, who))) {
@@ -5136,6 +5145,7 @@ static int oscar_send_im(GaimConnection 
 	int ret = 0;
 	GError *err = NULL;
 	const char *iconfile = gaim_account_get_buddy_icon(gaim_connection_get_account(gc));
+	const char* const charset= gaim_prefs_get_string("/plugins/prpl/oscar/charset");
 	char *tmpmsg = NULL, *tmpmsg2 = NULL;
 
 	if (dim && dim->connected) {
@@ -5236,42 +5246,37 @@ static int oscar_send_im(GaimConnection 
 				tmpmsg = gaim_strdup_withhtml(message);
 		}
 		len = strlen(tmpmsg);
-
-		args.flags |= oscar_encoding_check(tmpmsg);
+                int encoding= oscar_encoding_check(tmpmsg,len);
+                if (encoding) {
+                  aim_userinfo_t *userinfo=aim_locate_finduserinfo(od->sess,name);
+                  if (userinfo && (userinfo->capabilities & AIM_CAPS_ICQUTF8)) {
+                    encoding= AIM_IMFLAGS_UNICODE;
+                    gaim_debug_info("oscar","Destination support unicode, unicode prefered.\n");
+                  } else {
+                    gaim_debug_info("oscar","Destination does not support unicode, use the simplest encoding.\n");
+                  }
+                }
+                args.flags |= encoding;
 		if (args.flags & AIM_IMFLAGS_UNICODE) {
 			gaim_debug_info("oscar", "Sending Unicode IM\n");
 			args.charset = 0x0002;
 			args.charsubset = 0x0000;
-			args.msg = g_convert(tmpmsg, len, "UCS-2BE", "UTF-8", NULL, &len, &err);
-			if (err) {
-				gaim_debug_error("oscar",
-						   "Error converting a unicode message: %s\n", err->message);
+			args.msg = oscar_unicode_from_utf8(tmpmsg, len, &len);
+			if (!args.msg) {
 				gaim_debug_error("oscar",
 						   "This really shouldn't happen!\n");
 				/* We really shouldn't try to send the
 				 * IM now, but I'm not sure what to do */
-				g_error_free(err);
+				/* g_error_free(err); */
 			}
-		} else if (args.flags & AIM_IMFLAGS_ISO_8859_1) {
-			gaim_debug_info("oscar",
-					   "Sending ISO-8859-1 IM\n");
+		} else if (args.flags & AIM_IMFLAGS_8BIT_CHARSET) {
+			gaim_debug_info("oscar", "Sending %s IM\n",charset);
 			args.charset = 0x0003;
 			args.charsubset = 0x0000;
-			args.msg = g_convert(tmpmsg, len, "ISO-8859-1", "UTF-8", NULL, &len, &err);
-			if (err) {
-				gaim_debug_error("oscar",
-						   "conversion error: %s\n", err->message);
+			args.msg = oscar_charset_from_utf8(tmpmsg, len, &len);
+			if (!args.msg) {
 				gaim_debug_error("oscar",
-						   "Someone tell Ethan his 8859-1 detection is wrong\n");
-				args.flags ^= AIM_IMFLAGS_ISO_8859_1 | AIM_IMFLAGS_UNICODE;
-				len = strlen(tmpmsg);
-				g_error_free(err);
-				args.msg = g_convert(tmpmsg, len, "UCS-2BE", "UTF8", NULL, &len, &err);
-				if (err) {
-					gaim_debug_error("oscar",
-							   "Error in unicode fallback: %s\n", err->message);
-					g_error_free(err);
-				}
+						   "This really shouldn't happen!\n");
 			}
 		} else {
 			args.charset = 0x0000;
@@ -5335,17 +5340,20 @@ static void oscar_set_info(GaimConnectio
 	}
 		
 	text_html = gaim_strdup_withhtml(text);
-	flags = oscar_encoding_check(text_html);
+	msglen = strlen(text_html);
+	flags = oscar_encoding_check(text_html,msglen);
 	if (flags & AIM_IMFLAGS_UNICODE) {
-		msg = g_convert(text_html, strlen(text_html), "UCS-2BE", "UTF-8", NULL, &msglen, NULL);
+		msg = oscar_unicode_from_utf8(text_html, msglen, &msglen);
 		aim_locate_setprofile(od->sess, "unicode-2-0", msg, (msglen > od->rights.maxsiglen ? od->rights.maxsiglen : msglen), NULL, NULL, 0);
 		g_free(msg);
-	} else if (flags & AIM_IMFLAGS_ISO_8859_1) {
-		msg = g_convert(text_html, strlen(text_html), "ISO-8859-1", "UTF-8", NULL, &msglen, NULL);
-		aim_locate_setprofile(od->sess, "iso-8859-1", msg, (msglen > od->rights.maxsiglen ? od->rights.maxsiglen : msglen), NULL, NULL, 0);
+	} else if (flags & AIM_IMFLAGS_8BIT_CHARSET) {
+		const gchar* const charset=gaim_prefs_get_string("/plugins/prpl/oscar/charset");
+		gchar *low_charset=g_ascii_strdown(charset,strlen(charset));
+		msg = oscar_charset_from_utf8(text_html, msglen, &msglen);
+		aim_locate_setprofile(od->sess, low_charset, msg, (msglen > od->rights.maxsiglen ? od->rights.maxsiglen : msglen), NULL, NULL, 0);
+		g_free(low_charset);
 		g_free(msg);
 	} else {
-		msglen = strlen(text_html);
 		aim_locate_setprofile(od->sess, "us-ascii", text_html, (msglen > od->rights.maxsiglen ? od->rights.maxsiglen : msglen), NULL, NULL, 0);
 	}
 
@@ -5408,21 +5416,24 @@ static void oscar_set_away_aim(GaimConne
 	}
 
 	text_html = gaim_strdup_withhtml(text);
-	flags = oscar_encoding_check(text_html);
+	msglen=strlen(text_html);
+	flags = oscar_encoding_check(text_html,msglen);
 	if (flags & AIM_IMFLAGS_UNICODE) {
-		msg = g_convert(text_html, strlen(text_html), "UCS-2BE", "UTF-8", NULL, &msglen, NULL);
+		msg = oscar_unicode_from_utf8(text_html, msglen, &msglen);
 		aim_locate_setprofile(od->sess, NULL, NULL, 0, "unicode-2-0", msg, 
 			(msglen > od->rights.maxawaymsglen ? od->rights.maxawaymsglen : msglen));
 		g_free(msg);
 		gc->away = g_strndup(text, od->rights.maxawaymsglen/2);
-	} else if (flags & AIM_IMFLAGS_ISO_8859_1) {
-		msg = g_convert(text_html, strlen(text_html), "ISO-8859-1", "UTF-8", NULL, &msglen, NULL);
-		aim_locate_setprofile(od->sess, NULL, NULL, 0, "iso-8859-1", msg, 
+	} else if (flags & AIM_IMFLAGS_8BIT_CHARSET) {
+		const gchar* const charset=gaim_prefs_get_string("/plugins/prpl/oscar/charset");
+		gchar* low_charset=g_ascii_strdown(charset,strlen(charset));
+		msg = oscar_charset_from_utf8(text_html, msglen, &msglen);
+		aim_locate_setprofile(od->sess, NULL, NULL, 0, low_charset, msg, 
 			(msglen > od->rights.maxawaymsglen ? od->rights.maxawaymsglen : msglen));
+		g_free(low_charset);
 		g_free(msg);
 		gc->away = g_strndup(text_html, od->rights.maxawaymsglen);
 	} else {
-		msglen = strlen(text_html);
 		aim_locate_setprofile(od->sess, NULL, NULL, 0, "us-ascii", text_html, 
 			(msglen > od->rights.maxawaymsglen ? od->rights.maxawaymsglen : msglen));
 		gc->away = g_strndup(text_html, od->rights.maxawaymsglen);
@@ -5837,9 +5848,9 @@ static int gaim_ssi_parselist(aim_sessio
 			case 0x0000: { /* Buddy */
 				if (curitem->name) {
 					char *gname = aim_ssi_itemlist_findparentname(sess->ssi.local, curitem->name);
-					char *gname_utf8 = gname ? gaim_utf8_try_convert(gname) : NULL;
+					char *gname_utf8 = gname ? oscar_charset_to_utf8(gname,strlen(gname)) : NULL;
 					char *alias = aim_ssi_getalias(sess->ssi.local, gname, curitem->name);
-					char *alias_utf8 = alias ? gaim_utf8_try_convert(alias) : NULL;
+					char *alias_utf8 = alias ? oscar_charset_to_utf8(alias,strlen(alias)) : NULL;
 					b = gaim_find_buddy(gc->account, curitem->name);
 					/* Should gname be freed here? -- elb */
 					/* Not with the current code, but that might be cleaner -- med */
@@ -5999,9 +6010,9 @@ static int gaim_ssi_parseadd(aim_session
 		return 1;
 
 	gname = aim_ssi_itemlist_findparentname(sess->ssi.local, name);
-	gname_utf8 = gname ? gaim_utf8_try_convert(gname) : NULL;
+	gname_utf8 = gname ? oscar_charset_to_utf8(gname,strlen(gname)) : NULL;
 	alias = aim_ssi_getalias(sess->ssi.local, gname, name);
-	alias_utf8 = alias ? gaim_utf8_try_convert(alias) : NULL;
+	alias_utf8 = alias ? oscar_charset_to_utf8(alias,strlen(alias)) : NULL;
 	b = gaim_find_buddy(gc->account, name);
 	free(alias);
 
@@ -6271,7 +6282,7 @@ static int oscar_send_chat(GaimConnectio
 	GaimConversation *conv = NULL;
 	struct chat_connection *c = NULL;
 	char *buf, *buf2;
-	char *charset = NULL;
+	const char* charset= gaim_prefs_get_string("/plugins/prpl/oscar/charset");
 	int encoding;
 	gsize len;
 
@@ -6290,36 +6301,14 @@ static int oscar_send_chat(GaimConnectio
 		                        "You cannot send IM Images in AIM chats."),
 		                        GAIM_MESSAGE_ERROR, time(NULL));
 
-	encoding = oscar_encoding_check(buf);
+	encoding = oscar_encoding_check(buf,len);
 	if (encoding & AIM_IMFLAGS_UNICODE) {
 		gaim_debug_info("oscar", "Sending Unicode chat\n");
 		charset = "unicode-2-0";
-		buf2 = g_convert(buf, len, "UCS-2BE", "UTF-8", NULL, &len, &err);
-		if (err) {
-			gaim_debug_error("oscar",
-					   "Error converting to unicode-2-0: %s\n", err->message);
-			g_error_free(err);
-		}
-	} else if (encoding & AIM_IMFLAGS_ISO_8859_1) {
-		gaim_debug_info("oscar", "Sending ISO-8859-1 chat\n");
-		charset = "iso-8859-1";
-		buf2 = g_convert(buf, len, "ISO-8859-1", "UTF-8", NULL, &len, &err);
-		if (err) {
-			gaim_debug_error("oscar",
-					   "Error converting to iso-8859-1: %s\n", err->message);
-			g_error_free(err);
-			err = NULL;
-
-			gaim_debug_info("oscar", "Falling back to Unicode\n");
-			charset = "unicode-2-0";
-			buf2 = g_convert(buf, len, "UCS-2BE", "UTF-8", NULL, &len, &err);
-			if (err) {
-				gaim_debug_error("oscar",
-						   "Error converting to unicode-2-0: %s\n",
-						   err->message);
-				g_error_free(err);
-			}
-		}
+		buf2 = oscar_unicode_from_utf8(buf, len, &len);
+	} else if (encoding & AIM_IMFLAGS_8BIT_CHARSET) {
+		gaim_debug_info("oscar", "Sending %s chat\n", charset);
+		buf2 = oscar_charset_from_utf8(buf, len, &len);
 	} else {
 	  charset = "us-ascii";
 	  buf2 = g_strdup(buf);
@@ -6331,7 +6320,9 @@ static int oscar_send_chat(GaimConnectio
 		return -E2BIG;
 	}
 
-	aim_chat_send_im(od->sess, c->conn, 0, buf2, len, charset, "en");
+	gchar* low_charset=g_ascii_strdown(charset,strlen(charset));
+	aim_chat_send_im(od->sess, c->conn, 0, buf2, len, low_charset, "en");
+	g_free(low_charset);
 	g_free(buf2);
 
 	return 0;
@@ -6721,7 +6712,7 @@ static void oscar_buddycb_edit_comment(G
 	if (!(g = gaim_find_buddys_group(buddy)))
 		return;
 	comment = aim_ssi_getcomment(od->sess->ssi.local, g->name, buddy->name);
-	comment_utf8 = comment ? gaim_utf8_try_convert(comment) : NULL;
+	comment_utf8 = comment ? oscar_charset_to_utf8(comment,strlen(comment)) : NULL;
 
 	data->gc = gc;
 	data->name = g_strdup(buddy->name);
@@ -7145,6 +7136,24 @@ static void oscar_convo_closed(GaimConne
 	oscar_direct_im_destroy(od, dim);
 }
 
+static GaimPluginPrefFrame *
+get_plugin_pref_frame(GaimPlugin *plugin) {
+	GaimPluginPrefFrame *frame;
+	GaimPluginPref *ppref;
+
+	frame = gaim_plugin_pref_frame_new();
+
+	ppref = gaim_plugin_pref_new_with_name_and_label("/plugins/prpl/oscar/charset",_("Default 8 bit charset"));
+	gaim_plugin_pref_frame_add(frame, ppref);
+
+	return frame;
+}
+
+static GaimPluginUiInfo prefs_info = {
+	get_plugin_pref_frame
+};
+
+
 static GaimPluginProtocolInfo prpl_info =
 {
 	GAIM_PRPL_API_VERSION,
@@ -7235,6 +7244,7 @@ static GaimPluginInfo info =
 
 	NULL,                                             /**< ui_info        */
 	&prpl_info,                                       /**< extra_info     */
+	&prefs_info,                                      /**< prefs_info      */
 	NULL,
 	oscar_actions
 };
@@ -7252,8 +7262,10 @@ init_plugin(GaimPlugin *plugin)
 	option = gaim_account_option_int_new(_("Auth port"), "port", 5190);
 	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
 											   option);
-
 	my_protocol = plugin;
+
+	gaim_prefs_add_none("/plugins/prpl/oscar");
+	gaim_prefs_add_string("/plugins/prpl/oscar/charset", FAIM_DEFAULT_CHARSET);
 }
 
 GAIM_INIT_PLUGIN(oscar, init_plugin, info);
 
design & coding: Vladimir Lettiev aka crux © 2004-2005