changeset 24697:546d882f96f8

merge of '6de8f788571b507b2c76125cc65f88db49c60790' and '9b445b58d5e8b6ea8a6564f20865c206fce08d5a'
author Sadrul Habib Chowdhury <imadil@gmail.com>
date Thu, 11 Dec 2008 21:12:39 +0000
parents 98ec72f8f3cc (current diff) 370fd1834371 (diff)
children 36851084b5f2 65cfc59858cf
files
diffstat 52 files changed, 194 insertions(+), 229 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Thu Dec 11 21:10:57 2008 +0000
+++ b/ChangeLog	Thu Dec 11 21:12:39 2008 +0000
@@ -23,6 +23,10 @@
 	* On MSN, the Games and Office media can now be set and displayed (in
 	  addition to the previous Music media). The Media status text now shows
 	  the album, if possible. 
+	* Fix use of av_len in perl bindings to fix some off-by-one bugs (Paul
+	  Aurich)
+	* On ICQ, advertise the ICQ 6 typing capability.  This should fix the
+	  reports of typing notifications not working with third-party clients.
 
 	Gadu-Gadu:
 	* Fix some problems with Gadu-Gadu buddy icons (Adam Strzelecki)
@@ -42,6 +46,10 @@
 	* Send "client-accepts-full-bind-result" attribute during SASL login.
 	  This will fix Google Talk login failures if the user configures the
 	  wrong domain for his/her account.
+	* Support new <metadata/> element to indicate no XEP-0084 User Avatar
+	  (Paul Aurich)
+	* Fix SHA1 avatar checksum errors that occur when one of the bytes in a
+	  checksum begins with 0 (Paul Aurich)
 	
 	Zephyr:
 	* Enable auto-reply, to emulate 'zaway' (Toby Schaffer)
@@ -63,7 +71,6 @@
 	  buddylist.  (Thanks to Casey Ho)
 	* Fix a crash when closing an authorization minidialog with the X then
 	  immediately going offline (Paul Aurich)
-	* Fix compatibility with old GTK+ yet again
 
 	Finch:
 	* Allow binding meta+arrow keys for actions.
--- a/libpurple/blist.h	Thu Dec 11 21:10:57 2008 +0000
+++ b/libpurple/blist.h	Thu Dec 11 21:12:39 2008 +0000
@@ -71,7 +71,7 @@
 
 typedef enum
 {
-	PURPLE_BLIST_NODE_FLAG_NO_SAVE      = 1 << 0, /**< node should not be saved with the buddy list */
+	PURPLE_BLIST_NODE_FLAG_NO_SAVE      = 1 << 0 /**< node should not be saved with the buddy list */
 
 } PurpleBlistNodeFlags;
 
--- a/libpurple/cmds.h	Thu Dec 11 21:10:57 2008 +0000
+++ b/libpurple/cmds.h	Thu Dec 11 21:12:39 2008 +0000
@@ -38,7 +38,7 @@
 	PURPLE_CMD_STATUS_NOT_FOUND,
 	PURPLE_CMD_STATUS_WRONG_ARGS,
 	PURPLE_CMD_STATUS_WRONG_PRPL,
-	PURPLE_CMD_STATUS_WRONG_TYPE,
+	PURPLE_CMD_STATUS_WRONG_TYPE
 } PurpleCmdStatus;
 
 /** Commands registered with the core return one of these values when run.
@@ -51,7 +51,7 @@
 typedef enum _PurpleCmdRet {
 	PURPLE_CMD_RET_OK,       /**< Everything's okay; Don't look for another command to call. */
 	PURPLE_CMD_RET_FAILED,   /**< The command failed, but stop looking.*/
-	PURPLE_CMD_RET_CONTINUE, /**< Continue, looking for other commands with the same name to call. */
+	PURPLE_CMD_RET_CONTINUE /**< Continue, looking for other commands with the same name to call. */
 } PurpleCmdRet;
 
 #define PURPLE_CMD_FUNC(func) ((PurpleCmdFunc)func)
@@ -76,7 +76,7 @@
 	PURPLE_CMD_P_PLUGIN    =  3000,
 	PURPLE_CMD_P_ALIAS     =  4000,
 	PURPLE_CMD_P_HIGH      =  5000,
-	PURPLE_CMD_P_VERY_HIGH =  6000,
+	PURPLE_CMD_P_VERY_HIGH =  6000
 } PurpleCmdPriority;
 
 /** Flags used to set various properties of commands.  Every command should
@@ -93,7 +93,7 @@
 	/** Command is usable only for a particular prpl. */
 	PURPLE_CMD_FLAG_PRPL_ONLY        = 0x04,
 	/** Incorrect arguments to this command should be accepted anyway. */
-	PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS = 0x08,
+	PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS = 0x08
 } PurpleCmdFlag;
 
 
--- a/libpurple/connection.h	Thu Dec 11 21:10:57 2008 +0000
+++ b/libpurple/connection.h	Thu Dec 11 21:12:39 2008 +0000
@@ -44,7 +44,7 @@
 	PURPLE_CONNECTION_NO_FONTSIZE = 0x0020, /**< Connection does not send/receive font sizes */
 	PURPLE_CONNECTION_NO_URLDESC = 0x0040,  /**< Connection does not support descriptions with links */ 
 	PURPLE_CONNECTION_NO_IMAGES = 0x0080,  /**< Connection does not support sending of images */
-	PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY = 0x0100, /**< Connection supports sending and receiving custom smileys */
+	PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY = 0x0100 /**< Connection supports sending and receiving custom smileys */
 
 } PurpleConnectionFlags;
 
--- a/libpurple/conversation.h	Thu Dec 11 21:10:57 2008 +0000
+++ b/libpurple/conversation.h	Thu Dec 11 21:12:39 2008 +0000
@@ -84,7 +84,7 @@
 	PURPLE_CONV_UPDATE_TITLE,
 	PURPLE_CONV_UPDATE_CHATLEFT,
 
-	PURPLE_CONV_UPDATE_FEATURES, /**< The features for a chat have changed */
+	PURPLE_CONV_UPDATE_FEATURES  /**< The features for a chat have changed */
 
 } PurpleConvUpdateType;
 
@@ -126,7 +126,7 @@
 	PURPLE_MESSAGE_NOTIFY      = 0x2000, /**< Message is a notification */
 	PURPLE_MESSAGE_NO_LINKIFY  = 0x4000, /**< Message should not be auto-
 										   linkified @since 2.1.0 */
-	PURPLE_MESSAGE_INVISIBLE   = 0x8000, /**< Message should not be displayed */
+	PURPLE_MESSAGE_INVISIBLE   = 0x8000  /**< Message should not be displayed */
 } PurpleMessageFlags;
 
 /**
@@ -139,7 +139,7 @@
 	PURPLE_CBFLAGS_HALFOP        = 0x0002, /**< Half-op                      */
 	PURPLE_CBFLAGS_OP            = 0x0004, /**< Channel Op or Moderator      */
 	PURPLE_CBFLAGS_FOUNDER       = 0x0008, /**< Channel Founder              */
-	PURPLE_CBFLAGS_TYPING        = 0x0010, /**< Currently typing             */
+	PURPLE_CBFLAGS_TYPING        = 0x0010  /**< Currently typing             */
 
 } PurpleConvChatBuddyFlags;
 
--- a/libpurple/plugins/perl/common/Account.xs	Thu Dec 11 21:10:57 2008 +0000
+++ b/libpurple/plugins/perl/common/Account.xs	Thu Dec 11 21:12:39 2008 +0000
@@ -105,9 +105,9 @@
     int i, t_len;
 PPCODE:
     t_GL = NULL;
-    t_len = av_len((AV *)SvRV(status_types));
+    t_len = av_len((AV *)SvRV(status_types)) + 1;
 
-    for (i = 0; i < t_len; i++)
+    for (i = 0; i <= t_len; i++)
         t_GL = g_list_append(t_GL, SvPVutf8_nolen(*av_fetch((AV *)SvRV(status_types), i, 0)));
 
     purple_account_set_status_types(account, t_GL);
@@ -207,9 +207,9 @@
     int i, t_len;
 PPCODE:
     t_GL = NULL;
-    t_len = av_len((AV *)SvRV(list));
+    t_len = av_len((AV *)SvRV(list)) + 1;
 
-    for (i = 0; i < t_len; i++)
+    for (i = 0; i <= t_len; i++)
         t_GL = g_list_append(t_GL, SvPVutf8_nolen(*av_fetch((AV *)SvRV(list), i, 0)));
 
     purple_account_add_buddies(account, t_GL);
@@ -236,15 +236,15 @@
     int i, t_len;
 PPCODE:
     t_GL1 = NULL;
-    t_len = av_len((AV *)SvRV(A));
+    t_len = av_len((AV *)SvRV(A)) + 1;
 
-    for (i = 0; i < t_len; i++)
+    for (i = 0; i <= t_len; i++)
         t_GL1 = g_list_append(t_GL1, SvPVutf8_nolen(*av_fetch((AV *)SvRV(A), i, 0)));
 
     t_GL2 = NULL;
-    t_len = av_len((AV *)SvRV(B));
+    t_len = av_len((AV *)SvRV(B)) + 1;
 
-    for (i = 0; i < t_len; i++)
+    for (i = 0; i <= t_len; i++)
         t_GL2 = g_list_append(t_GL2, SvPVutf8_nolen(*av_fetch((AV *)SvRV(B), i, 0)));
 
     purple_account_remove_buddies(account, t_GL1, t_GL2);
--- a/libpurple/plugins/perl/common/AccountOpts.xs	Thu Dec 11 21:10:57 2008 +0000
+++ b/libpurple/plugins/perl/common/AccountOpts.xs	Thu Dec 11 21:12:39 2008 +0000
@@ -42,9 +42,9 @@
 	int i, t_len;
 CODE:
 	t_GL = NULL;
-	t_len = av_len((AV *)SvRV(values));
+	t_len = av_len((AV *)SvRV(values)) + 1;
 
-	for (i = 0; i < t_len; i++)
+	for (i = 0; i <= t_len; i++)
 		t_GL = g_list_append(t_GL, SvPVutf8_nolen(*av_fetch((AV *)SvRV(values), i, 0)));
 
 	RETVAL  = purple_account_option_list_new(text, pref_name, t_GL);
@@ -130,9 +130,9 @@
 	int i, t_len;
 PPCODE:
 	t_GL = NULL;
-	t_len = av_len((AV *)SvRV(values));
+	t_len = av_len((AV *)SvRV(values)) + 1;
 
-	for (i = 0; i < t_len; i++)
+	for (i = 0; i <= t_len; i++)
 		t_GL = g_list_append(t_GL, SvPVutf8_nolen(*av_fetch((AV *)SvRV(values), i, 0)));
 
 	purple_account_option_set_list(option, t_GL);
--- a/libpurple/plugins/perl/common/Conversation.xs	Thu Dec 11 21:10:57 2008 +0000
+++ b/libpurple/plugins/perl/common/Conversation.xs	Thu Dec 11 21:12:39 2008 +0000
@@ -334,9 +334,9 @@
 	int i, t_len;
 PPCODE:
 	t_GL = NULL;
-	t_len = av_len((AV *)SvRV(users));
+	t_len = av_len((AV *)SvRV(users)) + 1;
 
-	for (i = 0; i < t_len; i++)
+	for (i = 0; i <= t_len; i++)
 		t_GL = g_list_append(t_GL, SvPVutf8_nolen(*av_fetch((AV *)SvRV(users), i, 0)));
 
 	for (l = purple_conv_chat_set_users(chat, t_GL); l != NULL; l = l->next) {
@@ -372,9 +372,9 @@
 	int i, t_len;
 PPCODE:
 	t_GL = NULL;
-	t_len = av_len((AV *)SvRV(ignored));
+	t_len = av_len((AV *)SvRV(ignored)) + 1;
 
-	for (i = 0; i < t_len; i++)
+	for (i = 0; i <= t_len; i++)
 		t_GL = g_list_append(t_GL, SvPVutf8_nolen(*av_fetch((AV *)SvRV(ignored), i, 0)));
 
 	for (l = purple_conv_chat_set_ignored(chat, t_GL); l != NULL; l = l->next) {
@@ -429,21 +429,21 @@
 	int i, t_len;
 PPCODE:
 	t_GL_users = NULL;
-	t_len = av_len((AV *)SvRV(users));
+	t_len = av_len((AV *)SvRV(users)) + 1;
 
-	for (i = 0; i < t_len; i++)
+	for (i = 0; i <= t_len; i++)
 		t_GL_users = g_list_append(t_GL_users, SvPVutf8_nolen(*av_fetch((AV *)SvRV(users), i, 0)));
 
 	t_GL_flags = NULL;
-	t_len = av_len((AV *)SvRV(flags));
+	t_len = av_len((AV *)SvRV(flags)) + 1;
 
-	for (i = 0; i < t_len; i++)
+	for (i = 0; i <= t_len; i++)
 		t_GL_flags = g_list_append(t_GL_flags, SvPVutf8_nolen(*av_fetch((AV *)SvRV(flags), i, 0)));
 
 	t_GL_extra_msgs = NULL;
-	t_len = av_len((AV *)SvRV(extra_msgs));
+	t_len = av_len((AV *)SvRV(extra_msgs)) + 1;
 
-	for (i = 0; i < t_len; i++)
+	for (i = 0; i <= t_len; i++)
 		t_GL_extra_msgs = g_list_append(t_GL_extra_msgs, SvPVutf8_nolen(*av_fetch((AV *)SvRV(extra_msgs), i, 0)));
 
 	purple_conv_chat_add_users(chat, t_GL_users, t_GL_extra_msgs, t_GL_flags, new_arrivals);
--- a/libpurple/plugins/perl/common/Prefs.xs	Thu Dec 11 21:10:57 2008 +0000
+++ b/libpurple/plugins/perl/common/Prefs.xs	Thu Dec 11 21:12:39 2008 +0000
@@ -51,9 +51,9 @@
 	int i, t_len;
 PPCODE:
 	t_GL = NULL;
-	t_len = av_len((AV *)SvRV(value));
+	t_len = av_len((AV *)SvRV(value)) + 1;
 
-	for (i = 0; i < t_len; i++)
+	for (i = 0; i <= t_len; i++)
 		t_GL = g_list_append(t_GL, SvPVutf8_nolen(*av_fetch((AV *)SvRV(value), i, 0)));
 
 	purple_prefs_add_string_list(name, t_GL);
@@ -73,9 +73,9 @@
 	int i, t_len;
 PPCODE:
 	t_GL = NULL;
-	t_len = av_len((AV *)SvRV(value));
+	t_len = av_len((AV *)SvRV(value)) + 1;
 
-	for (i = 0; i < t_len; i++)
+	for (i = 0; i <= t_len; i++)
 		t_GL = g_list_append(t_GL, SvPVutf8_nolen(*av_fetch((AV *)SvRV(value), i, 0)));
 
 	purple_prefs_add_path_list(name, t_GL);
@@ -202,9 +202,9 @@
 	int i, t_len;
 PPCODE:
 	t_GL = NULL;
-	t_len = av_len((AV *)SvRV(value));
+	t_len = av_len((AV *)SvRV(value)) + 1;
 
-	for (i = 0; i < t_len; i++)
+	for (i = 0; i <= t_len; i++)
 		t_GL = g_list_append(t_GL, SvPVutf8_nolen(*av_fetch((AV *)SvRV(value), i, 0)));
 
 	purple_prefs_set_string_list(name, t_GL);
@@ -224,9 +224,9 @@
 	int i, t_len;
 PPCODE:
 	t_GL = NULL;
-	t_len = av_len((AV *)SvRV(value));
+	t_len = av_len((AV *)SvRV(value)) + 1;
 
-	for (i = 0; i < t_len; i++)
+	for (i = 0; i <= t_len; i++)
 		t_GL = g_list_append(t_GL, SvPVutf8_nolen(*av_fetch((AV *)SvRV(value), i, 0)));
 
 	purple_prefs_set_path_list(name, t_GL);
--- a/libpurple/plugins/perl/common/Roomlist.xs	Thu Dec 11 21:10:57 2008 +0000
+++ b/libpurple/plugins/perl/common/Roomlist.xs	Thu Dec 11 21:12:39 2008 +0000
@@ -78,9 +78,9 @@
 	int i, t_len;
 PPCODE:
 	t_GL = NULL;
-	t_len = av_len((AV *)SvRV(fields));
+	t_len = av_len((AV *)SvRV(fields)) + 1;
 
-	for (i = 0; i < t_len; i++)
+	for (i = 0; i <= t_len; i++)
 		t_GL = g_list_append(t_GL, SvPVutf8_nolen(*av_fetch((AV *)SvRV(fields), i, 0)));
 
 	purple_roomlist_set_fields(list, t_GL);
--- a/libpurple/plugins/perl/common/Status.xs	Thu Dec 11 21:10:57 2008 +0000
+++ b/libpurple/plugins/perl/common/Status.xs	Thu Dec 11 21:12:39 2008 +0000
@@ -83,9 +83,9 @@
 	int i, t_len;
 PPCODE:
 	t_GL = NULL;
-	t_len = av_len((AV *)SvRV(source_list));
+	t_len = av_len((AV *)SvRV(source_list)) + 1;
 
-	for (i = 0; i < t_len; i++) {
+	for (i = 0; i <= t_len; i++) {
 		t_GL = g_list_append(t_GL, SvPVutf8_nolen(*av_fetch((AV *)SvRV(source_list), i, 0)));
 	}
 	purple_presence_add_list(presence, t_GL);
@@ -379,9 +379,9 @@
 	int i, t_len;
 CODE:
 	t_GL = NULL;
-	t_len = av_len((AV *)SvRV(status_types));
+	t_len = av_len((AV *)SvRV(status_types)) + 1;
 
-	for (i = 0; i < t_len; i++) {
+	for (i = 0; i <= t_len; i++) {
 		t_GL = g_list_append(t_GL, SvPVutf8_nolen(*av_fetch((AV *)SvRV(status_types), i, 0)));
 	}
 	RETVAL = (PurpleStatusType *)purple_status_type_find_with_id(t_GL, id);
--- a/libpurple/protocols/bonjour/bonjour_ft.h	Thu Dec 11 21:10:57 2008 +0000
+++ b/libpurple/protocols/bonjour/bonjour_ft.h	Thu Dec 11 21:12:39 2008 +0000
@@ -27,7 +27,7 @@
 typedef enum {
 	XEP_BYTESTREAMS = 1,
 	XEP_IBB = 2,
-	XEP_UNKNOWN = 4,
+	XEP_UNKNOWN = 4
 } XepSiMode;
 
 struct _XepXfer
--- a/libpurple/protocols/jabber/auth.c	Thu Dec 11 21:10:57 2008 +0000
+++ b/libpurple/protocols/jabber/auth.c	Thu Dec 11 21:12:39 2008 +0000
@@ -613,9 +613,7 @@
 	} else if(!strcmp(type, "result")) {
 		query = xmlnode_get_child(packet, "query");
 		if(js->stream_id && xmlnode_get_child(query, "digest")) {
-			unsigned char hashval[20];
-			char *s, h[41], *p;
-			int i;
+			char *s, *hash;
 
 			iq = jabber_iq_new_query(js, JABBER_IQ_SET, "jabber:iq:auth");
 			query = xmlnode_get_child(iq->node, "query");
@@ -626,14 +624,9 @@
 
 			x = xmlnode_new_child(query, "digest");
 			s = g_strdup_printf("%s%s", js->stream_id, pw);
-
-			purple_cipher_digest_region("sha1", (guchar *)s, strlen(s),
-									  sizeof(hashval), hashval, NULL);
-
-			p = h;
-			for(i=0; i<20; i++, p+=2)
-				snprintf(p, 3, "%02x", hashval[i]);
-			xmlnode_insert_data(x, h, -1);
+			hash = jabber_calculate_data_sha1sum(s, strlen(s));
+			xmlnode_insert_data(x, hash, -1);
+			g_free(hash);
 			g_free(s);
 			jabber_iq_set_callback(iq, auth_old_result_cb, NULL);
 			jabber_iq_send(iq);
--- a/libpurple/protocols/jabber/buddy.c	Thu Dec 11 21:10:57 2008 +0000
+++ b/libpurple/protocols/jabber/buddy.c	Thu Dec 11 21:12:39 2008 +0000
@@ -19,7 +19,6 @@
  *
  */
 #include "internal.h"
-#include "cipher.h"
 #include "debug.h"
 #include "imgstore.h"
 #include "prpl.h"
@@ -451,9 +450,6 @@
 		gsize avatar_len;
 		xmlnode *photo, *binval, *type;
 		gchar *enc;
-		int i;
-		unsigned char hashval[20];
-		char *p, hash[41];
 
 		if(!vc_node) {
 			vc_node = xmlnode_new("vCard");
@@ -473,16 +469,7 @@
 		binval = xmlnode_new_child(photo, "BINVAL");
 		enc = purple_base64_encode(avatar_data, avatar_len);
 
-		purple_cipher_digest_region("sha1", avatar_data,
-								  avatar_len, sizeof(hashval),
-								  hashval, NULL);
-
-		purple_imgstore_unref(img);
-
-		p = hash;
-		for(i=0; i<20; i++, p+=2)
-			snprintf(p, 3, "%02x", hashval[i]);
-		js->avatar_hash = g_strdup(hash);
+		js->avatar_hash = jabber_calculate_data_sha1sum(avatar_data, avatar_len);
 
 		xmlnode_insert_data(binval, enc, -1);
 		g_free(enc);
@@ -545,19 +532,9 @@
 				char *lengthstring, *widthstring, *heightstring;
 				
 				/* compute the sha1 hash */
-				PurpleCipherContext *ctx;
-				unsigned char digest[20];
-				char *hash;
+				char *hash = jabber_calculate_data_sha1sum(purple_imgstore_get_data(img), purple_imgstore_get_size(img));
 				char *base64avatar;
 				
-				ctx = purple_cipher_context_new_by_name("sha1", NULL);
-				purple_cipher_context_append(ctx, purple_imgstore_get_data(img), purple_imgstore_get_size(img));
-				purple_cipher_context_digest(ctx, sizeof(digest), digest, NULL);
-				purple_cipher_context_destroy(ctx);
-				
-				/* convert digest to a string */
-				hash = g_strdup_printf("%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x",digest[0],digest[1],digest[2],digest[3],digest[4],digest[5],digest[6],digest[7],digest[8],digest[9],digest[10],digest[11],digest[12],digest[13],digest[14],digest[15],digest[16],digest[17],digest[18],digest[19]);
-				
 				publish = xmlnode_new("publish");
 				xmlnode_set_attrib(publish,"node",AVATARNAMESPACEDATA);
 				
@@ -1407,31 +1384,25 @@
 						(bintext = xmlnode_get_data(child))) {
 					gsize size;
 					guchar *data;
-					int i;
-					unsigned char hashval[20];
-					char *p, hash[41];
 					gboolean photo = (strcmp(child->name, "PHOTO") == 0);
 
 					data = purple_base64_decode(bintext, &size);
 					if (data) {
 						char *img_text;
+						char *hash;
 
 						jbi->vcard_imgids = g_slist_prepend(jbi->vcard_imgids, GINT_TO_POINTER(purple_imgstore_add_with_id(g_memdup(data, size), size, "logo.png")));
 						img_text = g_strdup_printf("<img id='%d'>", GPOINTER_TO_INT(jbi->vcard_imgids->data));
 
 						purple_notify_user_info_add_pair(user_info, (photo ? _("Photo") : _("Logo")), img_text);
 
-						purple_cipher_digest_region("sha1", (guchar *)data, size,
-								sizeof(hashval), hashval, NULL);
-						p = hash;
-						for(i=0; i<20; i++, p+=2)
-							snprintf(p, 3, "%02x", hashval[i]);
-
+						hash = jabber_calculate_data_sha1sum(data, size);
 						purple_buddy_icons_set_for_user(js->gc->account, bare_jid,
 								data, size, hash);
-						g_free(bintext);
+						g_free(hash);
 						g_free(img_text);
 					}
+					g_free(bintext);
 				}
 			}
 			g_free(text);
@@ -1525,9 +1496,12 @@
 		purple_buddy_icons_set_for_user(purple_connection_get_account(js->gc), from, NULL, 0, NULL);
 	} else {
 		xmlnode *info, *goodinfo = NULL;
-		
+		gboolean has_children = FALSE;
+
 		/* iterate over all info nodes to get one we can use */
 		for(info = metadata->child; info; info = info->next) {
+			if(info->type == XMLNODE_TYPE_TAG)
+				has_children = TRUE;
 			if(info->type == XMLNODE_TYPE_TAG && !strcmp(info->name,"info")) {
 				const char *type = xmlnode_get_attrib(info,"type");
 				const char *id = xmlnode_get_attrib(info,"id");
@@ -1542,7 +1516,9 @@
 					goodinfo = info;
 			}
 		}
-		if(goodinfo) {
+		if(has_children == FALSE) {
+			purple_buddy_icons_set_for_user(purple_connection_get_account(js->gc), from, NULL, 0, NULL);
+		} else if(goodinfo) {
 			const char *url = xmlnode_get_attrib(goodinfo, "url");
 			const char *id = xmlnode_get_attrib(goodinfo,"id");
 			
--- a/libpurple/protocols/jabber/jutil.c	Thu Dec 11 21:10:57 2008 +0000
+++ b/libpurple/protocols/jabber/jutil.c	Thu Dec 11 21:12:39 2008 +0000
@@ -20,7 +20,9 @@
  */
 #include "internal.h"
 #include "account.h"
+#include "cipher.h"
 #include "conversation.h"
+#include "debug.h"
 #include "server.h"
 #include "util.h"
 #include "xmlnode.h"
@@ -236,3 +238,29 @@
 	return NULL;
 }
 
+/* The same as purple_util_get_image_checksum, but guaranteed to remain SHA1 */
+char *
+jabber_calculate_data_sha1sum(gconstpointer data, size_t len)
+{
+	PurpleCipherContext *context;
+	static gchar digest[41];
+
+	context = purple_cipher_context_new_by_name("sha1", NULL);
+	if (context == NULL)
+	{
+		purple_debug_error("jabber", "Could not find sha1 cipher\n");
+		g_return_val_if_reached(NULL);
+	}
+
+	/* Hash the data */
+	purple_cipher_context_append(context, data, len);
+	if (!purple_cipher_context_digest_to_str(context, sizeof(digest), digest, NULL))
+	{
+		purple_debug_error("jabber", "Failed to get SHA-1 digest.\n");
+		g_return_val_if_reached(NULL);
+	}
+	purple_cipher_context_destroy(context);
+
+	return g_strdup(digest);
+}
+
--- a/libpurple/protocols/jabber/jutil.h	Thu Dec 11 21:10:57 2008 +0000
+++ b/libpurple/protocols/jabber/jutil.h	Thu Dec 11 21:12:39 2008 +0000
@@ -42,4 +42,5 @@
 
 PurpleConversation *jabber_find_unnormalized_conv(const char *name, PurpleAccount *account);
 
+char *jabber_calculate_data_sha1sum(gconstpointer data, size_t len);
 #endif /* _PURPLE_JABBER_JUTIL_H_ */
--- a/libpurple/protocols/jabber/presence.c	Thu Dec 11 21:10:57 2008 +0000
+++ b/libpurple/protocols/jabber/presence.c	Thu Dec 11 21:12:39 2008 +0000
@@ -21,7 +21,6 @@
 #include "internal.h"
 
 #include "account.h"
-#include "cipher.h"
 #include "conversation.h"
 #include "debug.h"
 #include "notify.h"
@@ -349,19 +348,12 @@
 				(( (binval = xmlnode_get_child(photo, "BINVAL")) &&
 				(text = xmlnode_get_data(binval))) ||
 				(text = xmlnode_get_data(photo)))) {
-			unsigned char hashval[20];
-			char hash[41], *p;
-			int i;
+			char *hash;
 
 			data = purple_base64_decode(text, &size);
-
-			purple_cipher_digest_region("sha1", data, size,
-					sizeof(hashval), hashval, NULL);
-			p = hash;
-			for(i=0; i<20; i++, p+=2)
-				snprintf(p, 3, "%02x", hashval[i]);
-
+			hash = jabber_calculate_data_sha1sum(data, size);
 			purple_buddy_icons_set_for_user(js->gc->account, from, data, size, hash);
+			g_free(hash);
 			g_free(text);
 		}
 	}
--- a/libpurple/protocols/jabber/si.c	Thu Dec 11 21:10:57 2008 +0000
+++ b/libpurple/protocols/jabber/si.c	Thu Dec 11 21:12:39 2008 +0000
@@ -23,7 +23,6 @@
 #include "internal.h"
 
 #include "blist.h"
-#include "cipher.h"
 #include "debug.h"
 #include "ft.h"
 #include "request.h"
@@ -183,9 +182,6 @@
 {
 	JabberSIXfer *jsx = xfer->data;
 	JabberBytestreamsStreamhost *streamhost;
-	char *dstaddr, *p;
-	int i;
-	unsigned char hashval[20];
 	JabberID *dstjid;
 
 	if(!jsx->streamhosts) {
@@ -221,6 +217,7 @@
 	/* TODO: Deal with zeroconf */
 
 	if(dstjid != NULL && streamhost->host && streamhost->port > 0) {
+		char *dstaddr, *hash;
 		jsx->gpi = purple_proxy_info_new();
 		purple_proxy_info_set_type(jsx->gpi, PURPLE_PROXY_SOCKS5);
 		purple_proxy_info_set_host(jsx->gpi, streamhost->host);
@@ -234,17 +231,13 @@
 			dstaddr = g_strdup_printf("%s%s@%s/%s%s@%s/%s", jsx->stream_id, dstjid->node, dstjid->domain, dstjid->resource,
 				jsx->js->user->node, jsx->js->user->domain, jsx->js->user->resource);
 
-		purple_cipher_digest_region("sha1", (guchar *)dstaddr, strlen(dstaddr),
-				sizeof(hashval), hashval, NULL);
-		g_free(dstaddr);
-		dstaddr = g_malloc(41);
-		p = dstaddr;
-		for(i=0; i<20; i++, p+=2)
-			snprintf(p, 3, "%02x", hashval[i]);
+		/* Per XEP-0065, the 'host' must be SHA1(SID + from JID + to JID) */
+		hash = jabber_calculate_data_sha1sum(dstaddr, strlen(dstaddr));
 
 		jsx->connect_data = purple_proxy_connect_socks5(NULL, jsx->gpi,
-				dstaddr, 0,
+				hash, 0,
 				jabber_si_bytestreams_connect_cb, xfer);
+		g_free(hash);
 		g_free(dstaddr);
 
 		/* When selecting a streamhost, timeout after STREAMHOST_CONNECT_TIMEOUT seconds, otherwise it takes forever */
@@ -361,11 +354,9 @@
 {
 	PurpleXfer *xfer = data;
 	JabberSIXfer *jsx = xfer->data;
-	int i;
 	char buffer[256];
 	int len;
-	char *dstaddr, *p;
-	unsigned char hashval[20];
+	char *dstaddr, *hash;
 	const char *host;
 
 	purple_debug_info("jabber", "in jabber_si_xfer_bytestreams_send_read_again_cb\n");
@@ -421,23 +412,20 @@
 			jsx->js->user->node, jsx->js->user->domain,
 			jsx->js->user->resource, xfer->who);
 
-	purple_cipher_digest_region("sha1", (guchar *)dstaddr, strlen(dstaddr),
-				    sizeof(hashval), hashval, NULL);
-	g_free(dstaddr);
-	dstaddr = g_malloc(41);
-	p = dstaddr;
-	for(i=0; i<20; i++, p+=2)
-		snprintf(p, 3, "%02x", hashval[i]);
+	/* Per XEP-0065, the 'host' must be SHA1(SID + from JID + to JID) */
+	hash = jabber_calculate_data_sha1sum(dstaddr, strlen(dstaddr));
 
-	if(jsx->rxqueue[4] != 40 || strncmp(dstaddr, jsx->rxqueue+5, 40) ||
+	if(jsx->rxqueue[4] != 40 || strncmp(hash, jsx->rxqueue+5, 40) ||
 			jsx->rxqueue[45] != 0x00 || jsx->rxqueue[46] != 0x00) {
 		purple_debug_error("jabber", "someone connected with the wrong info!\n");
 		close(source);
 		purple_xfer_cancel_remote(xfer);
+		g_free(hash);
 		g_free(dstaddr);
 		return;
 	}
 
+	g_free(hash);
 	g_free(dstaddr);
 
 	g_free(jsx->rxqueue);
--- a/libpurple/protocols/msn/contact.h	Thu Dec 11 21:10:57 2008 +0000
+++ b/libpurple/protocols/msn/contact.h	Thu Dec 11 21:12:39 2008 +0000
@@ -616,7 +616,7 @@
 	MSN_ADD_GROUP       = 0x10,
 	MSN_DEL_GROUP       = 0x20,
 	MSN_RENAME_GROUP    = 0x40,
-	MSN_UPDATE_INFO     = 0x80,
+	MSN_UPDATE_INFO     = 0x80
 } MsnCallbackAction;
 
 typedef struct _MsnCallbackState MsnCallbackState;
--- a/libpurple/protocols/msn/servconn.h	Thu Dec 11 21:10:57 2008 +0000
+++ b/libpurple/protocols/msn/servconn.h	Thu Dec 11 21:12:39 2008 +0000
@@ -40,7 +40,7 @@
 	MSN_SERVCONN_ERROR_NONE,
 	MSN_SERVCONN_ERROR_CONNECT,
 	MSN_SERVCONN_ERROR_WRITE,
-	MSN_SERVCONN_ERROR_READ,
+	MSN_SERVCONN_ERROR_READ
 
 } MsnServConnError;
 
--- a/libpurple/protocols/msn/slpcall.h	Thu Dec 11 21:10:57 2008 +0000
+++ b/libpurple/protocols/msn/slpcall.h	Thu Dec 11 21:12:39 2008 +0000
@@ -37,7 +37,7 @@
 typedef enum
 {
 	MSN_SLPCALL_ANY,
-	MSN_SLPCALL_DC,
+	MSN_SLPCALL_DC
 
 } MsnSlpCallType;
 
--- a/libpurple/protocols/msn/switchboard.h	Thu Dec 11 21:10:57 2008 +0000
+++ b/libpurple/protocols/msn/switchboard.h	Thu Dec 11 21:12:39 2008 +0000
@@ -57,7 +57,7 @@
 typedef enum
 {
 	MSN_SB_FLAG_IM = 0x01, /**< This switchboard is being used for a conversation. */
-	MSN_SB_FLAG_FT = 0x02, /**< This switchboard is being used for file transfer. */
+	MSN_SB_FLAG_FT = 0x02  /**< This switchboard is being used for file transfer. */
 
 } MsnSBFlag;
 
--- a/libpurple/protocols/myspace/myspace.c	Thu Dec 11 21:10:57 2008 +0000
+++ b/libpurple/protocols/myspace/myspace.c	Thu Dec 11 21:12:39 2008 +0000
@@ -1334,28 +1334,21 @@
 {
 	MsimSession *session;
 	time_t delta;
-	gchar *errmsg;
 
 	session = (MsimSession *)data;
 
 	g_return_val_if_fail(MSIM_SESSION_VALID(session), FALSE);
 
 	delta = time(NULL) - session->last_comm;
+
 	/* purple_debug_info("msim", "msim_check_alive: delta=%d\n", delta); */
 	if (delta >= MSIM_KEEPALIVE_INTERVAL) {
-	        errmsg = g_strdup_printf(ngettext("Connection to server lost (no data received within %d second)",
-						  "Connection to server lost (no data received within %d seconds)",
-						  (int)delta),
-					 (int)delta);
-
-		purple_debug_info("msim", "msim_check_alive: %s > interval of %d, presumed dead\n",
-				errmsg, MSIM_KEEPALIVE_INTERVAL);
+		purple_debug_info("msim",
+				"msim_check_alive: %zu > interval of %d, presumed dead\n",
+				delta, MSIM_KEEPALIVE_INTERVAL);
 		purple_connection_error_reason(session->gc,
-				PURPLE_CONNECTION_ERROR_NETWORK_ERROR, errmsg);
-
-		purple_notify_error(session->gc, NULL, errmsg, NULL);
-
-		g_free(errmsg);
+				PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+				_("Lost connection with server"));
 
 		return FALSE;
 	}
--- a/libpurple/protocols/oscar/family_locate.c	Thu Dec 11 21:10:57 2008 +0000
+++ b/libpurple/protocols/oscar/family_locate.c	Thu Dec 11 21:12:39 2008 +0000
@@ -203,11 +203,9 @@
 	 {0x2e, 0x7a, 0x64, 0x75, 0xfa, 0xdf, 0x4d, 0xc8,
 	  0x88, 0x6f, 0xea, 0x35, 0x95, 0xfd, 0xb6, 0xdf}},
 
-	/*
-	{OSCAR_CAPABILITY_ICQ2GO,
+	{OSCAR_CAPABILITY_TYPING,
 	 {0x56, 0x3f, 0xc8, 0x09, 0x0b, 0x6f, 0x41, 0xbd,
 	  0x9f, 0x79, 0x42, 0x26, 0x09, 0xdf, 0xa2, 0xf3}},
-	*/
 
 	/*
 	 * Chat is oddball.
--- a/libpurple/protocols/oscar/oscar.c	Thu Dec 11 21:10:57 2008 +0000
+++ b/libpurple/protocols/oscar/oscar.c	Thu Dec 11 21:12:39 2008 +0000
@@ -68,7 +68,7 @@
 
 static OscarCapability purple_caps = (OSCAR_CAPABILITY_CHAT | OSCAR_CAPABILITY_BUDDYICON | OSCAR_CAPABILITY_DIRECTIM |
 									  OSCAR_CAPABILITY_SENDFILE | OSCAR_CAPABILITY_UNICODE | OSCAR_CAPABILITY_INTEROPERATE |
-									  OSCAR_CAPABILITY_SHORTCAPS);
+									  OSCAR_CAPABILITY_SHORTCAPS | OSCAR_CAPABILITY_TYPING);
 
 static guint8 features_aim[] = {0x01, 0x01, 0x01, 0x02};
 static guint8 features_icq[] = {0x01, 0x06};
--- a/libpurple/protocols/oscar/oscar.h	Thu Dec 11 21:10:57 2008 +0000
+++ b/libpurple/protocols/oscar/oscar.h	Thu Dec 11 21:12:39 2008 +0000
@@ -362,8 +362,9 @@
 	OSCAR_CAPABILITY_LIVEVIDEO            = 0x02000000,
 	OSCAR_CAPABILITY_CAMERA               = 0x04000000,
 	OSCAR_CAPABILITY_ICHAT_SCREENSHARE    = 0x08000000,
-	OSCAR_CAPABILITY_GENERICUNKNOWN       = 0x10000000,
-	OSCAR_CAPABILITY_LAST                 = 0x20000000
+	OSCAR_CAPABILITY_TYPING               = 0x10000000,
+	OSCAR_CAPABILITY_GENERICUNKNOWN       = 0x20000000,
+	OSCAR_CAPABILITY_LAST                 = 0x40000000
 } OscarCapability;
 
 /*
--- a/libpurple/protocols/qq/buddy_info.c	Thu Dec 11 21:10:57 2008 +0000
+++ b/libpurple/protocols/qq/buddy_info.c	Thu Dec 11 21:12:39 2008 +0000
@@ -87,7 +87,7 @@
 	QQ_INFO_UNKNOW3, QQ_INFO_UNKNOW4, QQ_INFO_UNKNOW5,
 	QQ_INFO_IS_PUB_MOBILE, QQ_INFO_IS_PUB_CONTACT, QQ_INFO_COLLEGE, QQ_INFO_HOROSCOPE,
 	QQ_INFO_ZODIAC, QQ_INFO_BLOOD, QQ_INFO_SHOW, QQ_INFO_UNKNOW6,
-	QQ_INFO_LAST_2007, QQ_INFO_LAST,
+	QQ_INFO_LAST_2007, QQ_INFO_LAST
 };
 
 enum {
@@ -95,7 +95,7 @@
 };
 
 enum {
-	QQ_FIELD_LABEL = 0, QQ_FIELD_STRING, QQ_FIELD_MULTI, QQ_FIELD_BOOL, QQ_FIELD_CHOICE,
+	QQ_FIELD_LABEL = 0, QQ_FIELD_STRING, QQ_FIELD_MULTI, QQ_FIELD_BOOL, QQ_FIELD_CHOICE
 };
 
 typedef struct {
@@ -504,8 +504,6 @@
 {
 	PurpleAccount *account = purple_connection_get_account(gc);
 	const gchar *icon_path = purple_account_get_buddy_icon_path(account);
-	gchar **segments;
-	gint index;
 
 	g_return_if_fail(icon_path != NULL);
 
@@ -514,12 +512,6 @@
 	 *  purple_imgstore_get_filename is always new file
 	 *  QQ buddy may set custom icon if level is over 16 */
 	purple_debug_info("QQ", "Change my icon to %s\n", icon_path);
-	segments = g_strsplit_set(icon_path, G_DIR_SEPARATOR_S, 0);
-	for (index = 0; segments[index] != NULL; index++) {
-		purple_debug_info("QQ", "Split to %s\n", segments[index]);
-	}
-
-	g_strfreev(segments);
 }
 
 gchar *qq_get_icon_name(gint face)
--- a/libpurple/protocols/qq/buddy_info.h	Thu Dec 11 21:10:57 2008 +0000
+++ b/libpurple/protocols/qq/buddy_info.h	Thu Dec 11 21:12:39 2008 +0000
@@ -71,7 +71,7 @@
 	QQ_BUDDY_INFO_MODIFY_BASE,
 	QQ_BUDDY_INFO_MODIFY_EXT,
 	QQ_BUDDY_INFO_MODIFY_ADDR,
-	QQ_BUDDY_INFO_MODIFY_CONTACT,
+	QQ_BUDDY_INFO_MODIFY_CONTACT
 };
 
 gchar *qq_get_icon_name(gint face);
--- a/libpurple/protocols/qq/buddy_opt.c	Thu Dec 11 21:10:57 2008 +0000
+++ b/libpurple/protocols/qq/buddy_opt.c	Thu Dec 11 21:12:39 2008 +0000
@@ -46,7 +46,7 @@
 enum {
 	QQ_MY_AUTH_APPROVE = 0x30,	/* ASCII value of "0" */
 	QQ_MY_AUTH_REJECT = 0x31,	/* ASCII value of "1" */
-	QQ_MY_AUTH_REQUEST = 0x32,	/* ASCII value of "2" */
+	QQ_MY_AUTH_REQUEST = 0x32	/* ASCII value of "2" */
 };
 
 typedef struct _qq_buddy_req {
@@ -317,9 +317,9 @@
 	add_req->auth_len = 0;
 
 	who = uid_to_purple_name(uid);
-	msg = g_strdup_printf(_("%u needs Q&A"), uid);
-	purple_request_input(gc, _("Add buddy Q&A"), msg,
-			_("Input answer here"),
+	msg = g_strdup_printf(_("%u requires verification"), uid);
+	purple_request_input(gc, _("Add buddy question"), msg,
+			_("Enter answer here"),
 			NULL,
 			TRUE, FALSE, NULL,
 			_("Send"), G_CALLBACK(add_buddy_question_cb),
@@ -616,7 +616,7 @@
 	qq_buddy_req *add_req = (qq_buddy_req *)data;
 	gchar *who = uid_to_purple_name(add_req->uid);
 	purple_request_input(add_req->gc, NULL, _("Authorization denied message:"),
-			NULL, _("Sorry, You are not my style."), TRUE, FALSE, NULL,
+			NULL, _("Sorry, you're not my style."), TRUE, FALSE, NULL,
 			_("OK"), G_CALLBACK(buddy_add_deny_reason_cb),
 			_("Cancel"), G_CALLBACK(buddy_add_deny_noreason_cb),
 			purple_connection_get_account(add_req->gc), who, NULL,
@@ -661,9 +661,9 @@
 	}
 
 	who = uid_to_purple_name(uid);
-	msg = g_strdup_printf(_("%u needs authentication"), uid);
+	msg = g_strdup_printf(_("%u needs authorization"), uid);
 	purple_request_input(gc, _("Add buddy authorize"), msg,
-			_("Input request here"),
+			_("Enter request here"),
 			_("Would you be my friend?"),
 			TRUE, FALSE, NULL,
 			_("Send"), G_CALLBACK(add_buddy_auth_cb),
--- a/libpurple/protocols/qq/buddy_opt.h	Thu Dec 11 21:10:57 2008 +0000
+++ b/libpurple/protocols/qq/buddy_opt.h	Thu Dec 11 21:12:39 2008 +0000
@@ -38,14 +38,14 @@
 	QQ_AUTH_INFO_TEMP_SESSION = 0x0003,
 	QQ_AUTH_INFO_CLUSTER = 0x0002,
 	QQ_AUTH_INFO_REMOVE_BUDDY = 0x0006,
-	QQ_AUTH_INFO_UPDATE_BUDDY_INFO = 0x0007,
+	QQ_AUTH_INFO_UPDATE_BUDDY_INFO = 0x0007
 };
 
 enum {
 	QQ_QUESTION_GET = 0x01,
 	QQ_QUESTION_SET = 0x02,
 	QQ_QUESTION_REQUEST = 0x03,		/* get question only*/
-	QQ_QUESTION_ANSWER = 0x04,
+	QQ_QUESTION_ANSWER = 0x04
 };
 
 void qq_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group);
--- a/libpurple/protocols/qq/group.c	Thu Dec 11 21:10:57 2008 +0000
+++ b/libpurple/protocols/qq/group.c	Thu Dec 11 21:12:39 2008 +0000
@@ -116,7 +116,7 @@
 	return qd->roomlist;
 }
 
-/* free roomlist space, I have no idea when this one is called ... */
+/* free roomlist space, I have no idea when this one is called... */
 void qq_roomlist_cancel(PurpleRoomlist *list)
 {
 	qq_data *qd;
--- a/libpurple/protocols/qq/group.h	Thu Dec 11 21:10:57 2008 +0000
+++ b/libpurple/protocols/qq/group.h	Thu Dec 11 21:12:39 2008 +0000
@@ -37,7 +37,7 @@
 	QQ_ROOM_ROLE_NO = 0x00,	/* default 0x00 means not member */
 	QQ_ROOM_ROLE_YES,
 	QQ_ROOM_ROLE_REQUESTING,
-	QQ_ROOM_ROLE_ADMIN,
+	QQ_ROOM_ROLE_ADMIN
 } qq_room_role;
 
 typedef struct _qq_room_data qq_room_data;
--- a/libpurple/protocols/qq/group_info.h	Thu Dec 11 21:10:57 2008 +0000
+++ b/libpurple/protocols/qq/group_info.h	Thu Dec 11 21:12:39 2008 +0000
@@ -31,7 +31,7 @@
 
 enum {
 	QQ_ROOM_INFO_UPDATE_ONLY = 0,
-	QQ_ROOM_INFO_DISPLAY,
+	QQ_ROOM_INFO_DISPLAY
 };
 
 gint qq_request_room_get_buddies(PurpleConnection *gc, guint32 room_id, gint update_class);
--- a/libpurple/protocols/qq/group_join.c	Thu Dec 11 21:10:57 2008 +0000
+++ b/libpurple/protocols/qq/group_join.c	Thu Dec 11 21:12:39 2008 +0000
@@ -44,7 +44,7 @@
 enum {
 	QQ_ROOM_JOIN_OK = 0x01,
 	QQ_ROOM_JOIN_NEED_AUTH = 0x02,
-	QQ_ROOM_JOIN_DENIED = 0x03,
+	QQ_ROOM_JOIN_DENIED = 0x03
 };
 
 enum {
@@ -219,11 +219,11 @@
 
 	rmd = qq_room_data_find(gc, id);
 	if (rmd != NULL) {
-		msg = g_strdup_printf(_("Succeeded joining Qun %s (%u)"), rmd->title_utf8, rmd->ext_id);
+		msg = g_strdup_printf(_("Successfully joined Qun %s (%u)"), rmd->title_utf8, rmd->ext_id);
 		qq_got_message(gc, msg);
 		g_free(msg);
 	} else {
-		qq_got_message(gc, _("Succeeded joining Qun"));
+		qq_got_message(gc, _("Successfully joined Qun"));
 	}
 }
 
--- a/libpurple/protocols/qq/group_opt.c	Thu Dec 11 21:10:57 2008 +0000
+++ b/libpurple/protocols/qq/group_opt.c	Thu Dec 11 21:12:39 2008 +0000
@@ -122,7 +122,7 @@
 
 	who = uid_to_purple_name(add_req->member);
 	purple_request_input(add_req->gc, NULL, _("Authorization denied message:"),
-			NULL, _("Sorry, you are not our style ..."), TRUE, FALSE, NULL,
+			NULL, _("Sorry, you are not our style"), TRUE, FALSE, NULL,
 			_("OK"), G_CALLBACK(member_join_deny_reason_cb),
 			_("Cancel"), G_CALLBACK(member_join_deny_noreason_cb),
 			purple_connection_get_account(add_req->gc), who, NULL,
@@ -204,7 +204,7 @@
 
 	purple_debug_info("QQ", "Succeed in modify members for room %u\n", rmd->ext_id);
 
-	qq_room_got_chat_in(gc, id, 0, _("Successfully changed Qun member"), now);
+	qq_room_got_chat_in(gc, id, 0, _("Successfully changed Qun members"), now);
 }
 
 void qq_room_change_info(PurpleConnection *gc, qq_room_data *rmd)
@@ -347,7 +347,7 @@
 
 	purple_request_action(gc, _("QQ Qun Operation"),
 			    _("You have successfully created a Qun"),
-			    _("Would you like to set up the detail information now?"),
+			    _("Would you like to set up detailed information now?"),
 			    1,
 				purple_connection_get_account(gc), NULL, NULL,
 				add_req, 2,
@@ -519,7 +519,7 @@
 		rmd->my_role = QQ_ROOM_ROLE_YES;
 	}
 
-	msg = g_strdup_printf(_("<b>Joinning Qun %u is approved by admin %u for %s</b>"),
+	msg = g_strdup_printf(_("<b>Joining Qun %u is approved by admin %u for %s</b>"),
 			ext_id, admin_uid, reason);
 	now = time(NULL);
 	qq_room_got_chat_in(gc, id, 0, msg, now);
--- a/libpurple/protocols/qq/im.h	Thu Dec 11 21:10:57 2008 +0000
+++ b/libpurple/protocols/qq/im.h	Thu Dec 11 21:12:39 2008 +0000
@@ -45,7 +45,7 @@
 	QQ_MSG_SYS_30 = 0x0030,
 	QQ_MSG_SYS_4C = 0x004C,
 	QQ_MSG_EXTEND = 0x0084,
-	QQ_MSG_EXTEND_85 = 0x0085,
+	QQ_MSG_EXTEND_85 = 0x0085
 };
 
 typedef struct {
--- a/libpurple/protocols/qq/qq.c	Thu Dec 11 21:10:57 2008 +0000
+++ b/libpurple/protocols/qq/qq.c	Thu Dec 11 21:12:39 2008 +0000
@@ -496,7 +496,7 @@
 	icon_path = qq_get_icon_path(icon_name);
 	g_free(icon_name);
 
-	purple_debug_info("QQ", "Change prev icon %s to ...\n", icon_path);
+	purple_debug_info("QQ", "Change prev icon %s to...\n", icon_path);
 	purple_request_file(action, _("Select icon..."), icon_path,
 			FALSE,
 			G_CALLBACK(qq_change_icon_cb), NULL,
--- a/libpurple/protocols/qq/qq_base.c	Thu Dec 11 21:10:57 2008 +0000
+++ b/libpurple/protocols/qq/qq_base.c	Thu Dec 11 21:12:39 2008 +0000
@@ -424,7 +424,7 @@
 			qq_hex_dump(PURPLE_DEBUG_WARNING, "QQ", data, data_len,
 					">>> [default] decrypt and dump");
 			error = g_strdup_printf(
-						_("Unknown reply code when login (0x%02X)"),
+						_("Unknown reply code when logging in (0x%02X)"),
 						ret );
 			reason = PURPLE_CONNECTION_ERROR_OTHER_ERROR;
 			break;
@@ -464,14 +464,16 @@
 	qq_data *qd;
 	gchar **segments;
 
-	g_return_val_if_fail(data != NULL && data_len != 0, FALSE);
+	g_return_val_if_fail(data != NULL, FALSE);
+	g_return_val_if_fail(data_len != 0, FALSE);
 
 	qd = (qq_data *) gc->proto_data;
 
 	/* qq_show_packet("Keep alive reply packet", data, len); */
 
 	/* the last one is 60, don't know what it is */
-	if (NULL == (segments = split_data(data, data_len, "\x1f", 6)))
+	segments = split_data(data, data_len, "\x1f", 6);
+	if (segments == NULL)
 			return TRUE;
 
 	/* segments[0] and segment[1] are all 0x30 ("0") */
@@ -479,7 +481,7 @@
 	if(0 == qd->online_total) {
 		purple_connection_error_reason(gc,
 				PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
-				_("Keep alive error"));
+				_("Lost connection with server"));
 	}
 	qd->my_ip.s_addr = inet_addr(segments[3]);
 	qd->my_port = strtol(segments[4], NULL, 10);
@@ -528,7 +530,7 @@
 	if(0 == qd->online_total) {
 		purple_connection_error_reason(gc,
 				PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
-				_("Keep alive error"));
+				_("Lost connection with server"));
 	}
 
 	bytes += qq_getIP(&qd->my_ip, data + bytes);
@@ -572,7 +574,7 @@
 	if(0 == qd->online_total) {
 		purple_connection_error_reason(gc,
 				PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
-				_("Keep alive error"));
+				_("Lost connection with server"));
 	}
 
 	bytes += qq_getIP(&qd->my_ip, data + bytes);
@@ -653,7 +655,7 @@
 	if (data_len < 15) {
 		purple_connection_error_reason(gc,
 				PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR,
-				_("Can not decrypt get server reply"));
+				_("Could not decrypt server reply"));
 		return QQ_LOGIN_REPLY_ERR;
 	}
 
@@ -745,7 +747,7 @@
 	qd->send_seq++;
 	qq_send_cmd_encrypted(gc, QQ_CMD_TOKEN_EX, qd->send_seq, buf, bytes, TRUE);
 
-	purple_connection_update_progress(gc, _("Requesting captcha ..."), 3, QQ_CONNECT_STEPS);
+	purple_connection_update_progress(gc, _("Requesting captcha"), 3, QQ_CONNECT_STEPS);
 }
 
 static void request_token_ex_code(PurpleConnection *gc,
@@ -790,7 +792,7 @@
 	qd->send_seq++;
 	qq_send_cmd_encrypted(gc, QQ_CMD_TOKEN_EX, qd->send_seq, buf, bytes, TRUE);
 
-	purple_connection_update_progress(gc, _("Checking code of captcha ..."), 3, QQ_CONNECT_STEPS);
+	purple_connection_update_progress(gc, _("Checking captcha"), 3, QQ_CONNECT_STEPS);
 }
 
 typedef struct {
@@ -813,7 +815,7 @@
 
 	purple_connection_error_reason(captcha_req->gc,
 			PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED,
-			_("Failed captcha verify"));
+			_("Failed captcha verification"));
 }
 
 static void captcha_input_ok_cb(qq_captcha_request *captcha_req,
@@ -872,8 +874,8 @@
 	purple_request_field_group_add_field(group, field);
 
 	purple_request_fields(account,
-		_("QQ Captcha Verifying"),
-		_("QQ Captcha Verifying"),
+		_("QQ Captcha Verification"),
+		_("QQ Captcha Verification"),
 		_("Enter the text from the image"),
 		fields,
 		_("OK"), G_CALLBACK(captcha_input_ok_cb),
@@ -1111,7 +1113,7 @@
 			qq_hex_dump(PURPLE_DEBUG_WARNING, "QQ", data, data_len,
 					">>> [default] decrypt and dump");
 			error = g_strdup_printf(
-						_("Unknown reply code when checking password (0x%02X)"),
+						_("Unknown reply when checking password (0x%02X)"),
 						ret );
 			reason = PURPLE_CONNECTION_ERROR_OTHER_ERROR;
 			break;
@@ -1257,7 +1259,7 @@
 				/* Missing get server before login*/
 			default:
 				error = g_strdup_printf(
-						_("Unknown reply code when login (0x%02X):\n%s"),
+						_("Unknown reply code when logging in (0x%02X):\n%s"),
 						ret, msg_utf8);
 				break;
 		}
@@ -1446,7 +1448,7 @@
 				break;
 			default:
 				error = g_strdup_printf(
-						_("Unknown reply code when login (0x%02X):\n%s"),
+						_("Unknown reply code when logging in (0x%02X):\n%s"),
 						ret, msg_utf8);
 				break;
 		}
--- a/libpurple/protocols/qq/qq_define.h	Thu Dec 11 21:10:57 2008 +0000
+++ b/libpurple/protocols/qq/qq_define.h	Thu Dec 11 21:12:39 2008 +0000
@@ -74,7 +74,7 @@
 	QQ_CMD_ADD_BUDDY_NO_AUTH_EX = 0x00A7,			/* add friend without auth */
 	QQ_CMD_ADD_BUDDY_AUTH_EX = 0x00A8, 				/* add buddy with auth */
 	QQ_CMD_BUDDY_CHECK_CODE =  0x00B5,
-	QQ_CMD_BUDDY_QUESTION =  0x00B7,
+	QQ_CMD_BUDDY_QUESTION =  0x00B7
 };
 
 const gchar *qq_get_cmd_desc(gint type);
@@ -104,7 +104,7 @@
 	QQ_ROOM_CMD_TEMP_QUIT = 0x32,
 	QQ_ROOM_CMD_TEMP_GET_INFO = 0x33,
 	QQ_ROOM_CMD_TEMP_SEND_IM = 0x35,
-	QQ_ROOM_CMD_TEMP_GET_MEMBERS = 0x37,
+	QQ_ROOM_CMD_TEMP_GET_MEMBERS = 0x37
 };
 
 const gchar *qq_get_room_cmd_desc(gint room_cmd);
@@ -119,7 +119,7 @@
 	QQ_SERVER_BUDDY_ADDING_EX = 40,
 	QQ_SERVER_BUDDY_ADD_REQUEST_EX = 41,
 	QQ_SERVER_BUDDY_ADDED_ANSWER = 42,
-	QQ_SERVER_BUDDY_ADDED_EX = 43,
+	QQ_SERVER_BUDDY_ADDED_EX = 43
 };
 
 enum {
@@ -128,7 +128,7 @@
 	QQ_BUDDY_CHANGE_TO_OFFLINE = 20,
 	QQ_BUDDY_ONLINE_AWAY = 30,
 	QQ_BUDDY_ONLINE_INVISIBLE = 40,
-	QQ_BUDDY_ONLINE_BUSY = 50,
+	QQ_BUDDY_ONLINE_BUSY = 50
 };
 
 gboolean is_online(guint8 status);
--- a/libpurple/protocols/qq/qq_network.c	Thu Dec 11 21:10:57 2008 +0000
+++ b/libpurple/protocols/qq/qq_network.c	Thu Dec 11 21:12:39 2008 +0000
@@ -376,7 +376,7 @@
 			/* No worries */
 			return;
 
-		error_msg = g_strdup_printf(_("Lost connection with server: %d, %s"), errno, g_strerror(errno));
+		error_msg = g_strdup_printf(_("Lost connection with server:\n%s"), g_strerror(errno));
 		purple_connection_error_reason(gc,
 				PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 				error_msg);
@@ -773,12 +773,12 @@
 	set_all_keys( gc );
 
 	if (qd->client_version >= 2007) {
-		purple_connection_update_progress(gc, _("Get server ..."), 2, QQ_CONNECT_STEPS);
+		purple_connection_update_progress(gc, _("Getting server"), 2, QQ_CONNECT_STEPS);
 		qq_request_get_server(gc);
 		return;
 	}
 
-	purple_connection_update_progress(gc, _("Request token"), 2, QQ_CONNECT_STEPS);
+	purple_connection_update_progress(gc, _("Requesting token"), 2, QQ_CONNECT_STEPS);
 	qq_request_token(gc);
 }
 
@@ -935,7 +935,7 @@
 		return FALSE;
 	}
 
-	purple_connection_update_progress(gc, _("Connecting to server ..."), 1, QQ_CONNECT_STEPS);
+	purple_connection_update_progress(gc, _("Connecting to server"), 1, QQ_CONNECT_STEPS);
 
 	purple_debug_info("QQ", "Connect to %s:%d\n", server, port);
 
@@ -986,7 +986,7 @@
 	g_return_if_fail(gc != NULL && gc->proto_data != NULL);
 	qd = (qq_data *) gc->proto_data;
 
-	purple_debug_info("QQ", "Disconnecting ...\n");
+	purple_debug_info("QQ", "Disconnecting...\n");
 
 	if (qd->network_watcher > 0) {
 		purple_debug_info("QQ", "Remove network watcher\n");
--- a/libpurple/protocols/qq/qq_process.c	Thu Dec 11 21:10:57 2008 +0000
+++ b/libpurple/protocols/qq/qq_process.c	Thu Dec 11 21:12:39 2008 +0000
@@ -87,7 +87,7 @@
 
 	if (data[0] != 0) {
 		purple_debug_warning("QQ", "Failed sent IM\n");
-		purple_notify_error(gc, _("Error"), _("Failed to send IM."), NULL);
+		purple_notify_error(gc, _("Error"), _("Unable to send message."), NULL);
 		return;
 	}
 
@@ -948,7 +948,7 @@
 		qq_show_packet("Can not decrypted", rcved, rcved_len);
 		purple_connection_error_reason(gc,
 				PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR,
-				_("Can not decrypt login reply"));
+				_("Could not decrypt login reply"));
 		return QQ_LOGIN_REPLY_ERR;
 	}
 
--- a/libpurple/protocols/qq/qq_process.h	Thu Dec 11 21:10:57 2008 +0000
+++ b/libpurple/protocols/qq/qq_process.h	Thu Dec 11 21:12:39 2008 +0000
@@ -35,7 +35,7 @@
 	QQ_CMD_CLASS_UPDATE_ALL,
 	QQ_CMD_CLASS_UPDATE_ONLINE,
 	QQ_CMD_CLASS_UPDATE_BUDDY,
-	QQ_CMD_CLASS_UPDATE_ROOM,
+	QQ_CMD_CLASS_UPDATE_ROOM
 };
 
 guint8 qq_proc_login_cmds(PurpleConnection *gc,  guint16 cmd, guint16 seq,
--- a/libpurple/protocols/qq/qq_trans.c	Thu Dec 11 21:10:57 2008 +0000
+++ b/libpurple/protocols/qq/qq_trans.c	Thu Dec 11 21:12:39 2008 +0000
@@ -39,7 +39,7 @@
 	QQ_TRANS_IS_SERVER = 0x01,			/* Is server command or client command */
 	QQ_TRANS_IS_IMPORT = 0x02,			/* Only notice if not get reply; or resend, disconn if reties get 0*/
 	QQ_TRANS_REMAINED = 0x04,				/* server command before login*/
-	QQ_TRANS_IS_REPLY = 0x08,				/* server command before login*/
+	QQ_TRANS_IS_REPLY = 0x08				/* server command before login*/
 };
 
 struct _qq_transaction {
--- a/libpurple/protocols/sametime/sametime.c	Thu Dec 11 21:10:57 2008 +0000
+++ b/libpurple/protocols/sametime/sametime.c	Thu Dec 11 21:12:39 2008 +0000
@@ -158,7 +158,7 @@
   blist_choice_LOCAL = 1, /**< local only */
   blist_choice_MERGE = 2, /**< merge from server */
   blist_choice_STORE = 3, /**< merge from and save to server */
-  blist_choice_SYNCH = 4, /**< sync with server */
+  blist_choice_SYNCH = 4  /**< sync with server */
 };
 
 
--- a/libpurple/protocols/silc10/wb.c	Thu Dec 11 21:10:57 2008 +0000
+++ b/libpurple/protocols/silc10/wb.c	Thu Dec 11 21:12:39 2008 +0000
@@ -61,14 +61,14 @@
 /* Commands */
 typedef enum {
 	SILCPURPLE_WB_DRAW 	= 0x01,
-	SILCPURPLE_WB_CLEAR	= 0x02,
+	SILCPURPLE_WB_CLEAR	= 0x02
 } SilcPurpleWbCommand;
 
 /* Brush size */
 typedef enum {
 	SILCPURPLE_WB_BRUSH_SMALL = 2,
 	SILCPURPLE_WB_BRUSH_MEDIUM = 5,
-	SILCPURPLE_WB_BRUSH_LARGE = 10,
+	SILCPURPLE_WB_BRUSH_LARGE = 10
 } SilcPurpleWbBrushSize;
 
 /* Brush color (XXX Purple should provide default colors) */
@@ -85,7 +85,7 @@
 	SILCPURPLE_WB_COLOR_TAN		= 12093547,
 	SILCPURPLE_WB_COLOR_BROWN		= 5256485,
 	SILCPURPLE_WB_COLOR_GREY		= 11184810,
-	SILCPURPLE_WB_COLOR_WHITE		= 16777215,
+	SILCPURPLE_WB_COLOR_WHITE		= 16777215
 } SilcPurpleWbColor;
 
 typedef struct {
--- a/libpurple/protocols/yahoo/yahoochat.c	Thu Dec 11 21:10:57 2008 +0000
+++ b/libpurple/protocols/yahoo/yahoochat.c	Thu Dec 11 21:12:39 2008 +0000
@@ -1180,7 +1180,7 @@
 
 enum yahoo_room_type {
 	yrt_yahoo,
-	yrt_user,
+	yrt_user
 };
 
 struct yahoo_chatxml_state {
--- a/libpurple/protocols/yahoo/ycht.h	Thu Dec 11 21:10:57 2008 +0000
+++ b/libpurple/protocols/yahoo/ycht.h	Thu Dec 11 21:12:39 2008 +0000
@@ -43,7 +43,7 @@
 	YCHT_SERVICE_CHATMSG = 0x41,
 	YCHT_SERVICE_CHATMSG_EMOTE = 0x43,
 	YCHT_SERVICE_PING = 0x62,
-	YCHT_SERVICE_ONLINE_FRIENDS = 0x68,
+	YCHT_SERVICE_ONLINE_FRIENDS = 0x68
 } ycht_service;
 /*
 yahoo: YCHT Service: 0x11 Version: 0x100
--- a/libpurple/protocols/zephyr/zephyr.c	Thu Dec 11 21:10:57 2008 +0000
+++ b/libpurple/protocols/zephyr/zephyr.c	Thu Dec 11 21:12:39 2008 +0000
@@ -64,7 +64,7 @@
 	PURPLE_ZEPHYR_NONE, /* Non-kerberized ZEPH0.2 */
 	PURPLE_ZEPHYR_KRB4, /* ZEPH0.2 w/ KRB4 support */
 	PURPLE_ZEPHYR_TZC,  /* tzc executable proxy */
-	PURPLE_ZEPHYR_INTERGALACTIC_KRB4, /* Kerberized ZEPH0.3 */
+	PURPLE_ZEPHYR_INTERGALACTIC_KRB4 /* Kerberized ZEPH0.3 */
 } zephyr_connection_type;
 
 struct _zephyr_account {
--- a/libpurple/prpl.h	Thu Dec 11 21:10:57 2008 +0000
+++ b/libpurple/prpl.h	Thu Dec 11 21:12:39 2008 +0000
@@ -189,7 +189,7 @@
 	 * Used as a hint that unknown commands should not be sent as messages.
 	 * @since 2.1.0
 	 */
-	OPT_PROTO_SLASH_COMMANDS_NATIVE = 0x00000400,
+	OPT_PROTO_SLASH_COMMANDS_NATIVE = 0x00000400
 
 } PurpleProtocolOptions;
 
--- a/libpurple/smiley.c	Thu Dec 11 21:10:57 2008 +0000
+++ b/libpurple/smiley.c	Thu Dec 11 21:12:39 2008 +0000
@@ -288,7 +288,7 @@
 {
 	PROP_0,
 	PROP_SHORTCUT,
-	PROP_IMGSTORE,
+	PROP_IMGSTORE
 };
 
 #define PROP_SHORTCUT_S "shortcut"
--- a/pidgin/gtkutils.c	Thu Dec 11 21:10:57 2008 +0000
+++ b/pidgin/gtkutils.c	Thu Dec 11 21:12:39 2008 +0000
@@ -3276,13 +3276,7 @@
 static void
 combo_box_changed_cb(GtkComboBox *combo_box, GtkEntry *entry)
 {
-#if GTK_CHECK_VERSION(2, 6, 0)
 	char *text = gtk_combo_box_get_active_text(combo_box);
-#else
-	GtkWidget *widget = gtk_bin_get_child(GTK_BIN(combo_box));
-	char *text = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
-#endif
-
 	gtk_entry_set_text(entry, text ? text : "");
 	g_free(text);
 }
--- a/pidgin/plugins/perl/common/GtkIMHtml.xs	Thu Dec 11 21:10:57 2008 +0000
+++ b/pidgin/plugins/perl/common/GtkIMHtml.xs	Thu Dec 11 21:12:39 2008 +0000
@@ -171,9 +171,9 @@
 	int i, t_len;
 PPCODE:
 	t_GL = NULL;
-	t_len = av_len((AV *)SvRV(unused));
+	t_len = av_len((AV *)SvRV(unused)) + 1;
 
-	for (i = 0; i < t_len; i++) {
+	for (i = 0; i <= t_len; i++) {
 		STRLEN t_sl;
 		t_GL = g_slist_append(t_GL, SvPV(*av_fetch((AV *)SvRV(unused), i, 0), t_sl));
 	}