changeset 25467:be098f796b32

yaz patch has been applied.
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Wed, 25 Apr 2007 07:57:26 +0000
parents 46a28577399d
children bf77cf06b082
files autogen.sh configure.ac libpurple/conversation.c libpurple/notify.c libpurple/protocols/jabber/jabber.c libpurple/protocols/jabber/message.c libpurple/protocols/msn/msg.c libpurple/protocols/msn/msn.c libpurple/protocols/msn/switchboard.c libpurple/protocols/oscar/family_icbm.c libpurple/protocols/oscar/oscar.c libpurple/protocols/yahoo/util.c libpurple/protocols/yahoo/yahoo.c libpurple/protocols/yahoo/yahoo_profile.c libpurple/util.c libpurple/util.h pidgin/gtkconv.c pidgin/gtkimhtml.c pidgin/gtkimhtmltoolbar.h pidgin/gtkmain.c pidgin/gtkprefs.c
diffstat 21 files changed, 470 insertions(+), 60 deletions(-) [+]
line wrap: on
line diff
--- a/autogen.sh	Wed Apr 25 07:51:56 2007 +0000
+++ b/autogen.sh	Wed Apr 25 07:57:26 2007 +0000
@@ -69,5 +69,5 @@
 echo;
 echo "Running ./configure ${CONFIGURE_ARGS} $@"
 echo;
-./configure ${CONFIGURE_ARGS} $@
+#./configure ${CONFIGURE_ARGS} $@
 
--- a/configure.ac	Wed Apr 25 07:51:56 2007 +0000
+++ b/configure.ac	Wed Apr 25 07:57:26 2007 +0000
@@ -52,7 +52,7 @@
 	;;
 esac
 
-ALL_LINGUAS="af am ar az bg bn bs ca ca@valencia cs da de dz el en_AU en_CA en_GB eo es et eu fa fi fr gl gu he hi hu id it ja ka kn ko ku lt mk my_MM nb ne nl nn pa pl pt_BR pt ps ro ru sk sl sq sr sr@Latn sv ta te th tr uk vi xh zh_CN zh_HK zh_TW"
+ALL_LINGUAS=""
 AM_GLIB_GNU_GETTEXT
 
 dnl we don't use autobreak on cygwin!!
--- a/libpurple/conversation.c	Wed Apr 25 07:51:56 2007 +0000
+++ b/libpurple/conversation.c	Wed Apr 25 07:57:26 2007 +0000
@@ -1093,17 +1093,27 @@
 			  PurpleMessageFlags flags, time_t mtime)
 {
 	PurpleConversation *c;
+	char *tmpmessage = NULL;
 
 	g_return_if_fail(im != NULL);
 	g_return_if_fail(message != NULL);
 
 	c = purple_conv_im_get_conversation(im);
 
+	// yaz
+	if (purple_prefs_get_bool("/core/conversations/msnstyle")) {
+		tmpmessage = g_strdup_printf("<br>%s", message);
+	} else {
+		tmpmessage = g_strdup_printf("%s", message);
+	}
+
 	/* Raise the window, if specified in prefs. */
 	if (c->ui_ops != NULL && c->ui_ops->write_im != NULL)
-		c->ui_ops->write_im(c, who, message, flags, mtime);
+		c->ui_ops->write_im(c, who, tmpmessage, flags, mtime);
 	else
-		purple_conversation_write(c, who, message, flags, mtime);
+		purple_conversation_write(c, who, tmpmessage, flags, mtime);
+
+	g_free(tmpmessage);
 }
 
 gboolean purple_conv_present_error(const char *who, PurpleAccount *account, const char *what)
--- a/libpurple/notify.c	Wed Apr 25 07:51:56 2007 +0000
+++ b/libpurple/notify.c	Wed Apr 25 07:57:26 2007 +0000
@@ -449,6 +449,9 @@
 		purple_signal_emit(purple_notify_get_handle(), "displaying-userinfo",
 						 purple_connection_get_account(gc), who, user_info);
 
+		g_return_val_if_fail(g_utf8_validate(who, -1, NULL), NULL); //yaz
+		g_return_val_if_fail(g_utf8_validate(user_info, -1, NULL), NULL); //yaz
+
 		info->ui_handle = ops->notify_userinfo(gc, who, user_info);
 		info->cb = cb;
 		info->cb_user_data = user_data;
--- a/libpurple/protocols/jabber/jabber.c	Wed Apr 25 07:51:56 2007 +0000
+++ b/libpurple/protocols/jabber/jabber.c	Wed Apr 25 07:57:26 2007 +0000
@@ -348,8 +348,8 @@
 
 void jabber_send(JabberStream *js, xmlnode *packet)
 {
-	char *txt;
-	int len;
+	char *txt, *utf;
+	int len, utflen;
 
 	purple_signal_emit(my_protocol, "jabber-sending-xmlnode", js->gc, &packet);
 
@@ -358,8 +358,9 @@
 		return;
 
 	txt = xmlnode_to_str(packet, &len);
-	jabber_send_raw(js, txt, len);
-	g_free(txt);
+	utf = botch_utf(txt, len, &utflen); //yaz
+	jabber_send_raw(js, utf, utflen);
+	g_free(txt); g_free(utf);
 }
 
 void jabber_keepalive(PurpleConnection *gc)
--- a/libpurple/protocols/jabber/message.c	Wed Apr 25 07:51:56 2007 +0000
+++ b/libpurple/protocols/jabber/message.c	Wed Apr 25 07:57:26 2007 +0000
@@ -321,13 +321,22 @@
 				jm->thread_id = xmlnode_get_data(child);
 		} else if(!strcmp(child->name, "body")) {
 			if(!jm->body) {
-				char *msg = xmlnode_to_str(child, NULL);
+				char *tmp, *msg;
+				int len;
+				tmp = xmlnode_to_str(child, NULL);
+				msg = sanitize_utf(tmp, strlen(tmp), &len);
 				jm->body = purple_strdup_withhtml(msg);
-				g_free(msg);
+				g_free(msg); g_free(tmp);
 			}
 		} else if(!strcmp(child->name, "html")) {
-			if(!jm->xhtml && xmlnode_get_child(child, "body"))
-				jm->xhtml = xmlnode_to_str(child, NULL);
+			if(!jm->xhtml && xmlnode_get_child(child, "body")){
+				char *tmp, *msg;
+				int len;
+				tmp = xmlnode_to_str(child, NULL);
+				msg = sanitize_utf(tmp, strlen(tmp), &len);
+				jm->xhtml = msg;
+				g_free(tmp);
+			}
 		} else if(!strcmp(child->name, "active")) {
 			jm->chat_state = JM_STATE_ACTIVE;
 			jm->typing_style |= JM_TS_JEP_0085;
--- a/libpurple/protocols/msn/msg.c	Wed Apr 25 07:51:56 2007 +0000
+++ b/libpurple/protocols/msn/msg.c	Wed Apr 25 07:57:26 2007 +0000
@@ -525,9 +525,7 @@
 
 	if (data != NULL && len > 0)
 	{
-		msg->body = g_malloc0(len + 1);
-		memcpy(msg->body, data, len);
-		msg->body_len = len;
+		msg->body = botch_utf((void *)data, len, &msg->body_len); /* yaz */
 	}
 	else
 	{
--- a/libpurple/protocols/msn/msn.c	Wed Apr 25 07:51:56 2007 +0000
+++ b/libpurple/protocols/msn/msn.c	Wed Apr 25 07:57:26 2007 +0000
@@ -141,6 +141,8 @@
 	msn_cmdproc_send(cmdproc, "REA", "%s %s",
 					 purple_account_get_username(account),
 					 alias);
+	//yaz
+	purple_account_set_alias(account, entry); //oct16
 }
 
 static void
@@ -250,6 +252,13 @@
 					   _("Cancel"), NULL, gc);
 }
 
+// XXX should not use this function?? --yaz
+static void
+msn_set_friendly_name(PurpleConnection *gc, const char *name, const char *alias)
+{
+	msn_act_id(gc, alias);
+}
+
 static void
 msn_show_set_home_phone(PurplePluginAction *action)
 {
@@ -2037,7 +2046,8 @@
 	NULL,					/* register_user */
 	NULL,					/* get_cb_info */
 	NULL,					/* get_cb_away */
-	NULL,					/* alias_buddy */
+//	msn_set_friendly_name,			/* alias_buddy <- temporary suppressed due to severe side effect */
+	NULL,				/* alias_buddy */
 	msn_group_buddy,		/* group_buddy */
 	msn_rename_group,		/* rename_group */
 	NULL,					/* buddy_free */
--- a/libpurple/protocols/msn/switchboard.c	Wed Apr 25 07:51:56 2007 +0000
+++ b/libpurple/protocols/msn/switchboard.c	Wed Apr 25 07:57:26 2007 +0000
@@ -885,13 +885,17 @@
 	}
 	else
 	{
-		serv_got_im(gc, passport, body_final, 0, time(NULL));
+		char *yaz_body_final;
+		yaz_body_final = purple_strreplace(body_final, "\r\n", "<br>"); // replace 0D 0A with <br>
+		purple_debug_info("yaz msn", "yaz_body_final=%s\n", yaz_body_final);
+		serv_got_im(gc, passport, yaz_body_final, 0, time(NULL));
 		if (swboard->conv == NULL)
 		{
 			swboard->conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM,
 									passport, purple_connection_get_account(gc));
 			swboard->flag |= MSN_SB_FLAG_IM;
 		}
+		g_free(yaz_body_final);
 	}
 
 	g_free(body_final);
--- a/libpurple/protocols/oscar/family_icbm.c	Wed Apr 25 07:51:56 2007 +0000
+++ b/libpurple/protocols/oscar/family_icbm.c	Wed Apr 25 07:57:26 2007 +0000
@@ -51,6 +51,10 @@
 #include "win32dep.h"
 #endif
 
+/* yaz */
+#include "debug.h"
+#include "../../util.h"
+
 /**
  * Add a standard ICBM header to the given bstream with the given
  * information.
@@ -453,6 +457,9 @@
 	guchar cookie[8];
 	aim_tlvlist_t *otl = NULL, *itl = NULL;
 	ByteStream hdrbs;
+	// yaz
+	char *ucs = NULL;
+	int bytes;
 
 	if (!od || !(conn = flap_connection_findbygroup(od, 0x0004)))
 		return -EINVAL;
@@ -492,15 +499,51 @@
 	 * raw data, followed by a series of TLVs.
 	 *
 	 */
+#if 0
 	byte_stream_new(&hdrbs, 2+8+16+6+4+4+strlen(msg)+4+2+1+strlen(roomname)+2);
 
 	byte_stream_put16(&hdrbs, 0x0000); /* Unknown! */
 	byte_stream_putraw(&hdrbs, cookie, sizeof(cookie)); /* I think... */
 	byte_stream_putcaps(&hdrbs, OSCAR_CAPABILITY_CHAT);
-
+#endif
+	//yaz
+	// convert msg to ascii first. if it succeed, send as plain ascii.
+	// if it fails, convert msg into ucs-2be, and send it. 
+	ucs = g_convert(msg, strlen(msg), "ASCII", "UTF-8", NULL, &bytes, NULL);
+	if(ucs){
+		byte_stream_new(&hdrbs, 2+8+16+6+4+4+strlen(msg)+4+2+1+strlen(roomname)+2);
+
+		byte_stream_put16(&hdrbs, 0x0000); /* Unknown! */
+		byte_stream_putraw(&hdrbs, cookie, sizeof(cookie)); /* I think... */
+		byte_stream_putcaps(&hdrbs, OSCAR_CAPABILITY_CHAT);
+
+		aim_tlvlist_add_16(&itl, 0x000a, 0x0001);
+		aim_tlvlist_add_noval(&itl, 0x000f);
+		aim_tlvlist_add_raw(&itl, 0x000c, strlen(msg), msg);
+		free(ucs);
+	} else {
+		byte_stream_new(&hdrbs, 2+8+16+6+4+4+strlen(msg)+4+2+1+strlen(roomname)+2+4+11);
+
+		byte_stream_put16(&hdrbs, 0x0000); /* Unknown! */
+		byte_stream_putraw(&hdrbs, cookie, sizeof(cookie)); /* I think... */
+		byte_stream_putcaps(&hdrbs, OSCAR_CAPABILITY_CHAT);
+
+		aim_tlvlist_add_16(&itl, 0x000a, 0x0001);
+		aim_tlvlist_add_raw(&itl, 0x000d, 11, "unicode-2-0");
+		aim_tlvlist_add_noval(&itl, 0x000f);
+		//yaz
+		ucs = g_convert(msg, strlen(msg), "UCS-2BE", "UTF-8", NULL, &bytes, NULL);
+		if(ucs){
+			botch_ucs(ucs, bytes);
+			aim_tlvlist_add_raw(&itl, 0x000c, bytes, ucs);
+			free(ucs);
+		}
+	}
+#if 0
 	aim_tlvlist_add_16(&itl, 0x000a, 0x0001);
 	aim_tlvlist_add_noval(&itl, 0x000f);
 	aim_tlvlist_add_str(&itl, 0x000c, msg);
+#endif
 	aim_tlvlist_add_chatroom(&itl, 0x2711, exchange, roomname, instance);
 	aim_tlvlist_write(&hdrbs, &itl);
 
--- a/libpurple/protocols/oscar/oscar.c	Wed Apr 25 07:51:56 2007 +0000
+++ b/libpurple/protocols/oscar/oscar.c	Wed Apr 25 07:57:26 2007 +0000
@@ -280,7 +280,8 @@
 
 	/* Make sure encoding begins with charset= */
 	if (strncmp(encoding, "text/aolrtf; charset=", 21) &&
-		strncmp(encoding, "text/x-aolrtf; charset=", 23))
+	    strncmp(encoding, "text/x-aolrtf; charset=", 23) &&
+	    strncmp(encoding, "text/plain; charset=", 20)) /* for iChat */
 	{
 		return NULL;
 	}
@@ -302,7 +303,25 @@
 	gchar *utf8 = NULL;
 
 	if ((encoding == NULL) || encoding[0] == '\0') {
-		purple_debug_info("oscar", "Empty encoding, assuming UTF-8\n");
+		purple_debug_info("yaz oscar", "Empty encoding, validate as UTF-8\n");
+		if(g_utf8_validate(text, textlen, NULL)){
+			size_t newlen;
+			utf8 = sanitize_utf(text, textlen, &newlen);
+			goto done;
+		}
+		// not UTF-8
+		purple_debug_info("yaz oscar", "Empty encoding, assuming UCS-2BE\n");
+		sanitize_ucs(text, textlen);
+		utf8 = g_convert(text, textlen, "UTF-8", "UCS-2BE", NULL, NULL, NULL);
+		if(utf8){
+			if(!g_utf8_validate(utf8, strlen(utf8), NULL)){
+				purple_debug_info("yaz oscar", "Invalid conversion\n");
+				g_free(utf8);
+				utf8 = NULL;
+			}
+		} else {
+			purple_debug_info("yaz oscar", "Conversion failed\n");
+		}
 	} else if (!strcasecmp(encoding, "iso-8859-1")) {
 		utf8 = g_convert(text, textlen, "UTF-8", "iso-8859-1", NULL, NULL, NULL);
 	} else if (!strcasecmp(encoding, "ISO-8859-1-Windows-3.1-Latin-1") ||
@@ -310,6 +329,7 @@
 	{
 		utf8 = g_convert(text, textlen, "UTF-8", "Windows-1252", NULL, NULL, NULL);
 	} else if (!strcasecmp(encoding, "unicode-2-0")) {
+		sanitize_ucs(text, textlen);
 		utf8 = g_convert(text, textlen, "UTF-8", "UCS-2BE", NULL, NULL, NULL);
 	} else if (strcasecmp(encoding, "utf-8")) {
 		purple_debug_warning("oscar", "Unrecognized character encoding \"%s\", "
@@ -330,7 +350,7 @@
 		else
 			utf8 = g_strndup(text, textlen);
 	}
-
+done:
 	return utf8;
 }
 
@@ -487,6 +507,7 @@
 		if ((b != NULL) && (PURPLE_BUDDY_IS_ONLINE(b)))
 		{
 			*msg = g_convert(from, strlen(from), "UCS-2BE", "UTF-8", NULL, &msglen, NULL);
+			botch_ucs(*msg, msglen);
 			if (*msg != NULL)
 			{
 				*charset = AIM_CHARSET_UNICODE;
@@ -521,6 +542,7 @@
 	 * Nothing else worked, so send as UCS-2BE.
 	 */
 	*msg = g_convert(from, strlen(from), "UCS-2BE", "UTF-8", NULL, &msglen, &err);
+	botch_ucs(*msg, msglen);
 	if (*msg != NULL) {
 		*charset = AIM_CHARSET_UNICODE;
 		*charsubset = 0x0000;
@@ -1986,6 +2008,8 @@
 		tmp = purple_plugin_oscar_decode_im_part(account, userinfo->sn, curpart->charset,
 				curpart->charsubset, curpart->data, curpart->datalen);
 		if (tmp != NULL) {
+			purple_str_strip_char(tmp, 0x0d); // yaz: strip CR
+//			purple_debug_info("yaz oscar", "tmp=%s",tmp);
 			g_string_append(message, tmp);
 			g_free(tmp);
 		}
@@ -2086,6 +2110,7 @@
 		char *encoding, *utf8name, *tmp;
 		GHashTable *components;
 
+//		purple_debug_info("yaz oscar", "chat request %s\n", args->msg);
 		if (!args->info.chat.roominfo.name || !args->info.chat.roominfo.exchange) {
 			g_free(message);
 			return 1;
@@ -2108,6 +2133,8 @@
 		g_hash_table_replace(components, g_strdup("room"), utf8name);
 		g_hash_table_replace(components, g_strdup("exchange"),
 				g_strdup_printf("%d", args->info.chat.roominfo.exchange));
+		purple_debug_info("yaz oscar", "about to call serv_got_chat_invite\n");
+//		purple_debug_info("yaz oscar", "name=%s message=%s\n", name ? name : args->info.chat.roominfo.name, message);
 		serv_got_chat_invite(gc,
 				     utf8name,
 				     userinfo->sn,
@@ -2339,7 +2366,7 @@
 	 * for this suck-ass part of the protocol by splitting the string into at
 	 * most 1 baby string.
 	 */
-	msg1 = g_strsplit(args->msg, "\376", (args->type == 0x01 ? 1 : 0));
+	msg1 = g_strsplit(args->msg, "\376", (args->type == 0x01 ? 1 : 0)); // \376 is 0xfe
 	for (numtoks=0; msg1[numtoks]; numtoks++);
 	msg2 = (gchar **)g_malloc((numtoks+1)*sizeof(gchar *));
 	for (i=0; msg1[i]; i++) {
@@ -4390,6 +4417,7 @@
 	charset = oscar_charset_check(str);
 	if (charset == AIM_CHARSET_UNICODE) {
 		encoded = g_convert(str, strlen(str), "UCS-2BE", "UTF-8", NULL, ret_len, NULL);
+		botch_ucs(encoded, *ret_len);
 		*encoding = "unicode-2-0";
 	} else if (charset == AIM_CHARSET_CUSTOM) {
 		encoded = g_convert(str, strlen(str), "ISO-8859-1", "UTF-8", NULL, ret_len, NULL);
@@ -5410,7 +5438,7 @@
 		charsetstr = "unicode-2-0";
 	else if (charset == AIM_CHARSET_CUSTOM)
 		charsetstr = "iso-8859-1";
-	aim_chat_send_im(od, c->conn, 0, buf2, len, charsetstr, "en");
+	aim_chat_send_im(od, c->conn, 0, buf2, len, charsetstr, "JA");
 	g_free(buf2);
 
 	return 0;
--- a/libpurple/protocols/yahoo/util.c	Wed Apr 25 07:51:56 2007 +0000
+++ b/libpurple/protocols/yahoo/util.c	Wed Apr 25 07:57:26 2007 +0000
@@ -29,6 +29,7 @@
 #include "prpl.h"
 
 #include "yahoo.h"
+#include "util.h"
 
 #include <string.h>
 
@@ -47,7 +48,8 @@
 char *yahoo_string_encode(PurpleConnection *gc, const char *str, gboolean *utf8)
 {
 	struct yahoo_data *yd = gc->proto_data;
-	char *ret;
+	char *ret, *strtmp;
+	int newlen;
 	const char *to_codeset;
 
 	if (yd->jp && utf8 && *utf8)
@@ -61,7 +63,12 @@
 	else
 		to_codeset = purple_account_get_string(purple_connection_get_account(gc), "local_charset",  "ISO-8859-1");
 
-	ret = g_convert_with_fallback(str, strlen(str), to_codeset, "UTF-8", "?", NULL, NULL, NULL);
+	strtmp = sanitize_utf((char *)str, strlen((char *)str), &newlen);
+
+	ret = g_convert_with_fallback(strtmp, strlen(strtmp), to_codeset, "UTF-8", "?", NULL, NULL, NULL);
+
+	g_free(strtmp);
+
 	if (ret)
 		return ret;
 	else
@@ -79,8 +86,9 @@
 char *yahoo_string_decode(PurpleConnection *gc, const char *str, gboolean utf8)
 {
 	struct yahoo_data *yd = gc->proto_data;
-	char *ret;
-	const char *from_codeset;
+	char *ret, *tmp;
+	char *from_codeset;
+	int newlen;
 
 	if (utf8) {
 		if (g_utf8_validate(str, -1, NULL))
@@ -92,10 +100,21 @@
 	else
 		from_codeset = purple_account_get_string(purple_connection_get_account(gc), "local_charset",  "ISO-8859-1");
 
-	ret = g_convert_with_fallback(str, strlen(str), "UTF-8", from_codeset, NULL, NULL, NULL, NULL);
+	/* yaz: it's a kind of voodoo to avoid malconversion of "~". */
+	tmp = g_convert(str, strlen(str), "EUC-JP", from_codeset, NULL, NULL, NULL);
+	if(tmp) { 
+		ret = g_convert(tmp, strlen(tmp), "UTF-8", "EUC-JP", NULL, NULL, NULL);
+		g_free(tmp);
+	} else {
+		ret = g_convert_with_fallback(str, strlen(str), "UTF-8", from_codeset, NULL, NULL, NULL, NULL);
+	}
 
-	if (ret)
+	if (ret){
+		tmp = ret;
+		ret = botch_utf(ret, strlen(ret), &newlen);
+		g_free(tmp);
 		return ret;
+	}
 	else
 		return g_strdup("");
 }
--- a/libpurple/protocols/yahoo/yahoo.c	Wed Apr 25 07:51:56 2007 +0000
+++ b/libpurple/protocols/yahoo/yahoo.c	Wed Apr 25 07:57:26 2007 +0000
@@ -4070,7 +4070,7 @@
 	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
 
 
-#if 0
+#if 1
 	option = purple_account_option_string_new(_("Chat room list URL"), "room_list", YAHOO_ROOMLIST_URL);
 	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
 
--- a/libpurple/protocols/yahoo/yahoo_profile.c	Wed Apr 25 07:51:56 2007 +0000
+++ b/libpurple/protocols/yahoo/yahoo_profile.c	Wed Apr 25 07:57:26 2007 +0000
@@ -22,6 +22,7 @@
  */
 
 #define PHOTO_SUPPORT 1
+//original is 1 --yaz
 
 #include "internal.h"
 #include "debug.h"
@@ -737,6 +738,7 @@
 
 #endif /* PHOTO_SUPPORT */
 
+#define PROF_LEN (1024 * 10)
 static void yahoo_got_info(PurpleUtilFetchUrlData *url_data, gpointer user_data,
 		const gchar *url_text, size_t len, const gchar *error_message)
 {
@@ -987,6 +989,9 @@
 			g_free(stripped);
 			stripped = purple_utf8_ncr_decode(p);
 			stripped_len = strlen(stripped);
+
+            purple_debug_misc("yahoo", "after utf8 conversion: stripped@1 = (%s)\n",
+                              stripped); //payload --yaz
 			g_free(p);
 		}
 	}
@@ -998,7 +1003,7 @@
 				strings->charset, NULL, NULL, NULL);
 		yahoo_remove_nonbreaking_spaces(last_updated_utf8_string);
 
-		purple_debug_misc("yahoo", "after utf8 conversion: stripped = (%s)\n", stripped);
+		purple_debug_misc("yahoo", "after utf8 conversion: stripped = (%s)\n", stripped); //payload --yaz
 	}
 
 	if (profile_state == PROFILE_STATE_DEFAULT) {
@@ -1030,47 +1035,48 @@
 		}
 	}
 #endif /* PHOTO_SUPPORT */
+	purple_debug_info("yahoo", "email = %s\n", strings->my_email_string);
 
 	/* extract their Email address and put it in */
 	found |= purple_markup_extract_info_field(stripped, stripped_len, user_info,
 			strings->my_email_string, (yd->jp ? 4 : 1), " ", 0,
-			strings->private_string, _("E-Mail"), 0, NULL, NULL);
-
+            strings->private_string, _("E-Mail"), 0, NULL, NULL);
+#if 0
 	/* extract the Nickname if it exists */
 	found |= purple_markup_extract_info_field(stripped, stripped_len, user_info,
 			"Nickname:", 1, "\n", '\n',
-			NULL, _("Nickname"), 0, NULL, NULL);
+            NULL, _("Nickname"), 0, NULL, NULL);
 
 	/* extract their RealName and put it in */
 	found |= purple_markup_extract_info_field(stripped, stripped_len, user_info,
 			strings->realname_string, (yd->jp ? 3 : 1), "\n", '\n',
-			NULL, _("Real Name"), 0, NULL, NULL);
+            NULL, _("Real Name"), 0, NULL, NULL);
 
 	/* extract their Location and put it in */
 	found |= purple_markup_extract_info_field(stripped, stripped_len, user_info,
 			strings->location_string, (yd->jp ? 4 : 2), "\n", '\n',
-			NULL, _("Location"), 0, NULL, NULL);
+            NULL, _("Location"), 0, NULL, NULL);
 
 	/* extract their Age and put it in */
 	found |= purple_markup_extract_info_field(stripped, stripped_len, user_info,
 			strings->age_string, (yd->jp ? 2 : 3), "\n", '\n',
-			NULL, _("Age"), 0, NULL, NULL);
+            NULL, _("Age"), 0, NULL, NULL);
 
 	/* extract their MaritalStatus and put it in */
 	found |= purple_markup_extract_info_field(stripped, stripped_len, user_info,
 			strings->maritalstatus_string, (yd->jp ? 2 : 3), "\n", '\n',
-			strings->no_answer_string, _("Marital Status"), 0, NULL, NULL);
+            strings->no_answer_string, _("Marital Status"), 0, NULL, NULL);
 
 	/* extract their Gender and put it in */
 	found |= purple_markup_extract_info_field(stripped, stripped_len, user_info,
 			strings->gender_string, (yd->jp ? 2 : 3), "\n", '\n',
-			strings->no_answer_string, _("Gender"), 0, NULL, NULL);
+            strings->no_answer_string, _("Gender"), 0, NULL, NULL);
 
 	/* extract their Occupation and put it in */
 	found |= purple_markup_extract_info_field(stripped, stripped_len, user_info,
 			strings->occupation_string, 2, "\n", '\n',
-			NULL, _("Occupation"), 0, NULL, NULL);
-
+            NULL, _("Occupation"), 0, NULL, NULL);
+#endif
 	/* Hobbies, Latest News, and Favorite Quote are a bit different, since
 	 * the values can contain embedded newlines... but any or all of them
 	 * can also not appear.  The way we delimit them is to successively
@@ -1079,18 +1085,18 @@
 	 * next thing to follow this bunch.  (For Yahoo Japan, we check for
 	 * the "Description" ("Self PR") heading instead of "Links".)
 	 */
-
+#if 0
 	if (!purple_markup_extract_info_field(stripped, stripped_len, user_info,
 			strings->hobbies_string, (yd->jp ? 3 : 1), strings->latest_news_string,
-			'\n', "\n", _("Hobbies"), 0, NULL, NULL))
+            '\n', "\n", _("Hobbies"), 0, NULL, NULL))
 	{
 		if (!purple_markup_extract_info_field(stripped, stripped_len, user_info,
 				strings->hobbies_string, 1, strings->favorite_quote_string,
-				'\n', "\n", _("Hobbies"), 0, NULL, NULL))
+                '\n', "\n", _("Hobbies"), 0, NULL, NULL))
 		{
 			found |= purple_markup_extract_info_field(stripped, stripped_len, user_info,
 					strings->hobbies_string, 1, strings->links_string,
-					'\n', "\n", _("Hobbies"), 0, NULL, NULL);
+                    '\n', "\n", _("Hobbies"), 0, NULL, NULL);
 		}
 		else
 			found = TRUE;
@@ -1100,7 +1106,7 @@
 
 	if (!purple_markup_extract_info_field(stripped, stripped_len, user_info,
 			strings->latest_news_string, 1, strings->favorite_quote_string,
-			'\n', "\n", _("Latest News"), 0, NULL, NULL))
+            '\n', "\n", _("Latest News"), 0, NULL, NULL))
 	{
 		found |= purple_markup_extract_info_field(stripped, stripped_len, user_info,
 				strings->latest_news_string, (yd->jp ? 2 : 1), strings->links_string,
@@ -1111,7 +1117,7 @@
 
 	found |= purple_markup_extract_info_field(stripped, stripped_len, user_info,
 			strings->favorite_quote_string, 1, strings->links_string,
-			'\n', "\n", _("Favorite Quote"), 0, NULL, NULL);
+            '\n', "\n", _("Favorite Quote"), 0, NULL, NULL);
 
 	/* Home Page will either be "No home page specified",
 	 * or "Home Page: " and a link.
@@ -1125,7 +1131,7 @@
 		{
 			found |= purple_markup_extract_info_field(stripped, stripped_len, user_info,
 					strings->home_page_string, 1, "\n", 0, NULL,
-					_("Home Page"), 1, NULL, NULL);
+                    _("Home Page"), 1, NULL, NULL);
 		}
 	}
 
@@ -1140,7 +1146,7 @@
 	{
 		if (purple_markup_extract_info_field(stripped, stripped_len, user_info,
 				strings->cool_link_1_string, 1, "\n", 0, NULL,
-				_("Cool Link 1"), 1, NULL, NULL))
+                _("Cool Link 1"), 1, NULL, NULL))
 		{
 			found = TRUE;
 			if (purple_markup_extract_info_field(stripped, stripped_len, user_info,
@@ -1158,13 +1164,14 @@
 		/* see if Member Since is there, and if so, extract it. */
 		found |= purple_markup_extract_info_field(stripped, stripped_len, user_info,
 				"Member Since:", 1, last_updated_utf8_string,
-				'\n', NULL, _("Member Since"), 0, NULL, yahoo_info_date_reformat);
+                '\n', NULL, _("Member Since"), 0, NULL, yahoo_info_date_reformat);
 
 		/* extract the Last Updated date and put it in */
 		found |= purple_markup_extract_info_field(stripped, stripped_len, user_info,
 				last_updated_utf8_string, (yd->jp ? 2 : 1), (yd->jp ? "\n" : " "), (yd->jp ? 0 : '\n'), NULL,
-				_("Last Update"), 0, NULL, (yd->jp ? NULL : yahoo_info_date_reformat));
+                _("Last Update"), 0, NULL, (yd->jp ? NULL : yahoo_info_date_reformat));
 	}
+#endif
 	} /* if (profile_state == PROFILE_STATE_DEFAULT) */
 
 	if(!found)
--- a/libpurple/util.c	Wed Apr 25 07:51:56 2007 +0000
+++ b/libpurple/util.c	Wed Apr 25 07:57:26 2007 +0000
@@ -1153,6 +1153,8 @@
 		return FALSE;
 
 	q = strstr(p, end_token);
+	if(q == NULL) //yaz
+		return FALSE;
 
 	/* Trim leading blanks */
 	while (*p != '\n' && g_ascii_isspace(*p)) {
@@ -1165,7 +1167,7 @@
 	}
 
 	/* Don't bother with null strings */
-	if (p == q)
+	if (p >= q)
 		return FALSE;
 
 	if (q != NULL && (!no_value_token ||
@@ -4215,3 +4217,234 @@
 #endif /* HAVE_SIGNAL_H */
 #endif /* !_WIN32 */
 }
+
+
+void botch_ucs(gchar *ucs, gssize len)
+{
+	gint i;
+
+ 	for(i=0;i<len;i+=2){
+ 		switch(*(ucs+i)){
+ 		case 0x00:
+ 			switch(*(ucs+i+1)){
+ 			case 0xa2:	// ¢
+ 				*(ucs+i) = 0xff;
+ 				*(ucs+i+1) = 0xe0;
+ 				break;
+ 			case 0xa3:	// £
+ 				*(ucs+i) = 0xff;
+				*(ucs+i+1) = 0xe1;
+ 				break;
+ 			case 0xac:	// ¬
+ 				*(ucs+i) = 0xff;
+ 				*(ucs+i+1) = 0xe2;
+ 				break;
+ 			}
+ 			break;
+ 		case 0x20:	// ‖
+ 			if(*(ucs+i+1) == 0x16){
+ 				*(ucs+i) = 0x22;
+				*(ucs+i+1) = 0x25;
+ 			}
+ 			break;
+ 		case 0x22:	// −
+ 			if(*(ucs+i+1) == 0x12){
+ 				*(ucs+i) = 0xff;
+ 				*(ucs+i+1) = 0x0d;
+ 			}
+ 			break;
+ 		case 0x30:	// 〜
+ 			if(*(ucs+i+1) == 0x1c){
+ 				*(ucs+i) = 0xff;
+ 				*(ucs+i+1) = 0x5e;
+ 			}
+ 			break;
+ 		}
+ 	}
+
+}
+
+void sanitize_ucs(gchar *ucs, gssize len)
+{
+	gint i;
+
+	for(i=0;i<len;i+=2){
+		switch(*(ucs+i)){
+		case 0x22:
+			switch(*(ucs+i+1)){
+			case 0x25:	// ‖
+				*(ucs+i) = 0x20;
+				*(ucs+i+1) = 0x16;
+				break;
+			}
+			break;
+		case 0xff:
+			switch(*(ucs+i+1)){
+			case 0x0d:	// −
+				*(ucs+i) = 0x22;
+				*(ucs+i+1) = 0x12;
+				break;
+			case 0x5e:	// 〜
+				*(ucs+i) = 0x30;
+				*(ucs+i+1) = 0x1c;
+				break;
+			case 0xe0:	// ¢
+				*(ucs+i) = 0x00;
+				*(ucs+i+1) = 0xa2;
+				break;
+			case 0xe1:	// £
+				*(ucs+i) = 0x00;
+				*(ucs+i+1) = 0xa3;
+				break;
+			case 0xe2:	// ¬
+				*(ucs+i) = 0x00;
+				*(ucs+i+1) = 0xac;
+				break;
+			}
+			break;
+		}
+	}
+}
+
+guchar *sanitize_utf(unsigned char *msg, size_t len, size_t *newlen)
+{
+	gint i;
+	size_t bytes;
+	unsigned char *utf;
+
+	utf = g_strndup(msg, len);
+
+	bytes = len;
+
+	for(i=0;i<len;i++){
+		switch(*(utf+i)){
+		case 0xe2:
+			if(*(utf+i+1) == 0x88) {
+				if(*(utf+i+2) == 0xa5) {	// ‖
+					*(utf+i) = 0xe2;
+					*(utf+i+1) = 0x80;
+					*(utf+i+2) = 0x96;
+				}
+			}
+			break;
+		case 0xef:
+			switch(*(utf+i+1)){
+			case 0xbc:
+				if(*(utf+i+2) == 0x8d) {	// −
+					*(utf+i) = 0xe2;
+					*(utf+i+1) = 0x88;
+					*(utf+i+2) = 0x92;
+				}
+				break;
+			case 0xbd:
+				if(*(utf+i+2) == 0x9e) {	// 〜
+					*(utf+i) = 0xe3;
+					*(utf+i+1) = 0x80;
+					*(utf+i+2) = 0x9c;
+				}
+				break;
+			case 0xbf:
+				switch(*(utf+i+2)){
+			       case 0xa0:// ¢
+				       *(utf+i) = 0xc2;
+				       *(utf+i+1) = 0xa2;
+				       memmove(utf+i+2, utf+i+3,
+					       len-i-3); //1byte詰める
+				       bytes--;
+				       break;
+			       case 0xa1:	// £
+				       *(utf+i) = 0xc2;
+				       *(utf+i+1) = 0xa3;
+				       memmove(utf+i+2, utf+i+3,
+					       len-i-3); //1byte詰める
+				       bytes--;
+				       break;
+			       case 0xa2:	// ¬
+				       *(utf+i) = 0xc2;
+				       *(utf+i+1) = 0xac;
+				       memmove(utf+i+2, utf+i+3,
+					       len-i-3); //1byte詰める
+				       bytes--;
+				       break;
+			       }
+			       break;
+			}
+			break;
+		}
+	}
+	*(utf+bytes)= 0x00; //terminate
+	*newlen = bytes;
+	return utf;
+}
+
+
+guchar *botch_utf(const void *msg, size_t len, size_t *newlen)
+{
+ 	int i,bytes;
+	unsigned char *utf;
+
+	bytes = len;
+
+	utf = g_malloc0(bytes*3/2+1); /* new length might be 3/2 in the worst case */
+	memcpy(utf, msg, bytes);
+	
+ 	for(i=0;i<bytes;i++){
+ 		switch(*(utf+i)){
+ 		case 0xc2:
+ 			switch(*(utf+i+1)){
+ 			case 0xa2:	// ¢
+ 				*(utf+i) = 0xef;
+ 				*(utf+i+1) = 0xbf;
+				memmove(utf+i+3, utf+i+2, bytes-i-2);
+				*(utf+i+2) = 0xa0;
+				bytes++;
+ 				break;
+ 			case 0xa3:	// £
+ 				*(utf+i) = 0xef;
+ 				*(utf+i+1) = 0xbf;
+				memmove(utf+i+3, utf+i+2, bytes-i-2);
+				*(utf+i+2) = 0xa1;
+				bytes++;
+ 				break;
+ 			case 0xac:	// ¬
+ 				*(utf+i) = 0xef;
+ 				*(utf+i+1) = 0xbf;
+				memmove(utf+i+3, utf+i+2, bytes-i-2);
+				*(utf+i+2) = 0xa2;
+				bytes++;
+ 				break;
+ 			}
+ 			break;
+ 		case 0xe2:
+			switch(*(utf+i+1)){
+			case 0x80:	// ‖
+				if(*(utf+i+2) == 0x96){
+					*(utf+i) = 0xe2;
+					*(utf+i+1) = 0x88;
+					*(utf+i+2) = 0xa5;
+				}
+				break;
+			case 0x88:	// −
+				if(*(utf+i+1) == 0x92){
+					*(utf+i) = 0xef;
+					*(utf+i+1) = 0xbc;
+					*(utf+i+2) = 0x8d;
+				}
+				break;
+			}
+			break;
+ 		case 0xe3:	// 〜
+ 			if(*(utf+i+1) == 0x80){
+				if(*(utf+i+2) == 0x9c){
+					*(utf+i) = 0xef;
+					*(utf+i+1) = 0xbd;
+					*(utf+i+2) = 0x9e;
+				}
+ 			}
+ 			break;
+ 		} //switch
+ 	}
+	*(utf+bytes) = 0x00; //terminate
+	*newlen = bytes;
+	return utf;
+}
--- a/libpurple/util.h	Wed Apr 25 07:51:56 2007 +0000
+++ b/libpurple/util.h	Wed Apr 25 07:57:26 2007 +0000
@@ -1122,4 +1122,10 @@
 }
 #endif
 
+/* to address incompatibility with cp932. */
+void botch_ucs(gchar *ucs, gssize len);
+void sanitize_ucs(gchar *ucs, gssize len);
+guchar *botch_utf(const void *utf, size_t len, size_t *newlen);
+guchar *sanitize_utf(unsigned char *msg, size_t len, size_t *newlen);
+
 #endif /* _PURPLE_UTIL_H_ */
--- a/pidgin/gtkconv.c	Wed Apr 25 07:51:56 2007 +0000
+++ b/pidgin/gtkconv.c	Wed Apr 25 07:57:26 2007 +0000
@@ -130,6 +130,10 @@
 static GdkColor *nick_colors = NULL;
 static guint nbr_nick_colors;
 
+/* yaz. If you want to use shortcut keys that may conflict with
+   inputmethods, change this to 1. */
+#define ENABLE_SHORTCUT 0
+
 typedef struct {
 	GtkWidget *window;
 
@@ -2760,20 +2764,33 @@
 
 	{ "/Conversation/sep0", NULL, NULL, 0, "<Separator>", NULL },
 
+#if ENABLE_SHORTCUT
 	{ N_("/Conversation/_Find..."), NULL, menu_find_cb, 0,
 			"<StockItem>", GTK_STOCK_FIND },
+#else
+	{ N_("/Conversation/_Find..."), NULL, menu_find_cb, 0,
+			"<Item>" },
+#endif
 	{ N_("/Conversation/View _Log"), NULL, menu_view_log_cb, 0, "<Item>", NULL },
 	{ N_("/Conversation/_Save As..."), NULL, menu_save_as_cb, 0,
 			"<StockItem>", GTK_STOCK_SAVE_AS },
+#if ENABLE_SHORTCUT
 	{ N_("/Conversation/Clea_r Scrollback"), "<CTL>L", menu_clear_cb, 0, "<StockItem>", GTK_STOCK_CLEAR },
-
+#else
+	{ N_("/Conversation/Clea_r Scrollback"), "<CTL>L", menu_clear_cb, 0, "<Item>" },
+#endif
 	{ "/Conversation/sep1", NULL, NULL, 0, "<Separator>", NULL },
 
 	{ N_("/Conversation/Se_nd File..."), NULL, menu_send_file_cb, 0, "<StockItem>", PIDGIN_STOCK_FILE_TRANSFER },
 	{ N_("/Conversation/Add Buddy _Pounce..."), NULL, menu_add_pounce_cb,
 			0, "<Item>", NULL },
+#if ENABLE_SHORTCUT
 	{ N_("/Conversation/_Get Info"), "<CTL>O", menu_get_info_cb, 0,
 			"<StockItem>", PIDGIN_STOCK_TOOLBAR_USER_INFO },
+#else
+	{ N_("/Conversation/_Get Info"), NULL, menu_get_info_cb, 0,
+			"<StockItem>", PIDGIN_STOCK_TOOLBAR_USER_INFO },
+#endif
 	{ N_("/Conversation/In_vite..."), NULL, menu_invite_cb, 0,
 			"<Item>", NULL },
 	{ N_("/Conversation/M_ore"), NULL, NULL, 0, "<Branch>", NULL },
@@ -3337,7 +3354,12 @@
 		gtk_widget_destroy(win->menu.send_to);
 
 	/* Build the Send To menu */
+
+#if ENABLE_SHORTCUT
 	win->menu.send_to = gtk_menu_item_new_with_mnemonic(_("_Send To"));
+#else
+	win->menu.send_to = gtk_menu_item_new_with_mnemonic(_("Send To"));
+#endif
 	gtk_widget_show(win->menu.send_to);
 
 	menu = gtk_menu_new();
@@ -3811,7 +3833,9 @@
 	PurpleConversation *conv = gtkconv->active_conv;
 	PidginChatPane *gtkchat;
 	char *new_topic;
-	const char *current_topic;
+//	const char *current_topic;
+	char dummy[] = "No Topic";
+	char *current_topic = NULL;
 
 	gc      = purple_conversation_get_gc(conv);
 
@@ -3824,8 +3848,13 @@
 	gtkconv = PIDGIN_CONVERSATION(conv);
 	gtkchat = gtkconv->u.chat;
 	new_topic = g_strdup(gtk_entry_get_text(GTK_ENTRY(gtkchat->topic_text)));
+//	purple_debug_info("yaz gtkconv", "new_topic=%s\n", new_topic);
 	current_topic = purple_conv_chat_get_topic(PURPLE_CONV_CHAT(conv));
 
+	if(!current_topic)
+ 		current_topic = dummy;
+//	purple_debug_info("yaz gtkconv", "current_topic=%s\n", current_topic);
+
 	if(current_topic && !g_utf8_collate(new_topic, current_topic)){
 		g_free(new_topic);
 		return;
--- a/pidgin/gtkimhtml.c	Wed Apr 25 07:51:56 2007 +0000
+++ b/pidgin/gtkimhtml.c	Wed Apr 25 07:57:26 2007 +0000
@@ -95,6 +95,10 @@
                            gint              y,
                            guint             time);
 
+/* yaz. If you want to use shortcut keys that may conflict with
+   inputmethods, change this to 1. */
+#define ENABLE_SHORTCUT 0
+
 static void preinsert_cb(GtkTextBuffer *buffer, GtkTextIter *iter, gchar *text, gint len, GtkIMHtml *imhtml);
 static void insert_cb(GtkTextBuffer *buffer, GtkTextIter *iter, gchar *text, gint len, GtkIMHtml *imhtml);
 static void delete_cb(GtkTextBuffer *buffer, GtkTextIter *iter, GtkTextIter *end, GtkIMHtml *imhtml);
@@ -402,10 +406,11 @@
 static gint
 gtk_imhtml_tip (gpointer data)
 {
-	GtkIMHtml *imhtml = data;
+	GtkIMHtml *imhtml = (GtkIMHtml *)data;
 	PangoFontMetrics *font_metrics;
 	PangoLayout *layout;
 	PangoFont *font;
+	PangoLanguage *lang;
 
 	gint gap, x, y, h, w, scr_w, baseline_skip;
 
@@ -446,7 +451,9 @@
 		return FALSE;
 	}
 
-	font_metrics = pango_font_get_metrics(font, NULL);
+	lang = pango_context_get_language (pango_layout_get_context(layout));
+	font_metrics = pango_font_get_metrics(font, lang); //it's ok.
+//	font_metrics = pango_font_get_metrics(font, NULL); //crash!
 
 	pango_layout_get_pixel_size(layout, &scr_w, NULL);
 	gap = PANGO_PIXELS((pango_font_metrics_get_ascent(font_metrics) +
@@ -551,14 +558,15 @@
 			g_source_remove(GTK_IMHTML(imhtml)->tip_timer);
 		GTK_IMHTML(imhtml)->tip_timer = 0;
 	}
-
+//yaz here bomb explodes
+#if 1
 	if (tip){
 		if (!GTK_IMHTML(imhtml)->editable)
 			gdk_window_set_cursor(win, GTK_IMHTML(imhtml)->hand_cursor);
 		GTK_IMHTML(imhtml)->tip_timer = g_timeout_add (TOOLTIP_TIMEOUT,
 							       gtk_imhtml_tip, imhtml);
 	}
-
+#endif
 	GTK_IMHTML(imhtml)->tip = tip;
 	g_slist_free(tags);
 	return FALSE;
--- a/pidgin/gtkimhtmltoolbar.h	Wed Apr 25 07:51:56 2007 +0000
+++ b/pidgin/gtkimhtmltoolbar.h	Wed Apr 25 07:57:26 2007 +0000
@@ -30,7 +30,7 @@
 extern "C" {
 #endif
 
-#define DEFAULT_FONT_FACE "Helvetica 12"
+#define DEFAULT_FONT_FACE "Sans 12"
 
 #define GTK_TYPE_IMHTMLTOOLBAR            (gtk_imhtmltoolbar_get_type ())
 #define GTK_IMHTMLTOOLBAR(obj)            (GTK_CHECK_CAST ((obj), GTK_TYPE_IMHTMLTOOLBAR, GtkIMHtmlToolbar))
--- a/pidgin/gtkmain.c	Wed Apr 25 07:51:56 2007 +0000
+++ b/pidgin/gtkmain.c	Wed Apr 25 07:57:26 2007 +0000
@@ -207,10 +207,12 @@
 		purple_debug_warning("sighandler", "Caught signal %d\n", sig);
 		purple_connections_disconnect_all();
 		break;
+#if 1
 	case SIGSEGV:
 		fprintf(stderr, "%s", segfault_message);
 		abort();
 		break;
+#endif
 	case SIGCHLD:
 		/* Restore signal catching */
 		signal(SIGCHLD, sighandler);
--- a/pidgin/gtkprefs.c	Wed Apr 25 07:51:56 2007 +0000
+++ b/pidgin/gtkprefs.c	Wed Apr 25 07:57:26 2007 +0000
@@ -917,7 +917,7 @@
 #endif
 
 	pidgin_prefs_checkbox(_("Use smooth-scrolling"), PIDGIN_PREFS_ROOT "/conversations/use_smooth_scrolling", vbox);
-
+	pidgin_prefs_checkbox(_("Use msn messenger style"), "/core/conversations/msnstyle", vbox);//yaz
 #ifdef _WIN32
 	pidgin_prefs_checkbox(_("F_lash window when IMs are received"), PIDGIN_PREFS_ROOT "/win32/blink_im", vbox);
 #endif