changeset 24701:93f0249b4ff4

merge of '2c63599660bb7ed2aa17389e548fbc0511b797ac' and 'ce75e981fb02f075fc398b19d6ad5d2805046d0c'
author Mark Doliner <mark@kingant.net>
date Fri, 12 Dec 2008 04:02:08 +0000
parents bf2ca2c5ac40 (diff) 128a77f3b3c4 (current diff)
children 19198eac578b
files
diffstat 48 files changed, 160 insertions(+), 166 deletions(-) [+]
line wrap: on
line diff
--- a/COPYRIGHT	Fri Dec 12 04:01:39 2008 +0000
+++ b/COPYRIGHT	Fri Dec 12 04:02:08 2008 +0000
@@ -207,6 +207,7 @@
 Benjamin Kahn
 Anders Kaseorg
 Praveen Karadakal
+Jaromír Karmazín
 John Kelm
 Jochen Kemnade
 Akuke Kok
--- a/ChangeLog	Fri Dec 12 04:01:39 2008 +0000
+++ b/ChangeLog	Fri Dec 12 04:02:08 2008 +0000
@@ -23,6 +23,11 @@
 	* 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
+	  (Jaromír Karmazín)
 
 	Gadu-Gadu:
 	* Fix some problems with Gadu-Gadu buddy icons (Adam Strzelecki)
@@ -42,6 +47,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 +72,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/account.c	Fri Dec 12 04:01:39 2008 +0000
+++ b/libpurple/account.c	Fri Dec 12 04:02:08 2008 +0000
@@ -75,6 +75,7 @@
 	gpointer userdata;
 	PurpleAccountRequestAuthorizationCb auth_cb;
 	PurpleAccountRequestAuthorizationCb deny_cb;
+	guint ref;
 } PurpleAccountRequestInfo;
 
 static PurpleAccountUiOps *account_ui_ops = NULL;
@@ -1211,6 +1212,18 @@
 		ui_ops->request_add(account, remote_user, id, alias, message);
 }
 
+static PurpleAccountRequestInfo *
+purple_account_request_info_unref(PurpleAccountRequestInfo *info)
+{
+	if (--info->ref)
+		return info;
+
+	/* TODO: This will leak info->user_data, but there is no callback to just clean that up */
+	g_free(info->user);
+	g_free(info);
+	return NULL;
+}
+
 static void
 purple_account_request_close_info(PurpleAccountRequestInfo *info)
 {
@@ -1221,11 +1234,7 @@
 	if (ops != NULL && ops->close_account_request != NULL)
 		ops->close_account_request(info->ui_handle);
 
-	/* TODO: This will leak info->user_data, but there is no callback to just clean that up */
-
-	g_free(info->user);
-	g_free(info);
-
+	purple_account_request_info_unref(info);
 }
 
 void
@@ -1278,8 +1287,7 @@
 	purple_signal_emit(purple_accounts_get_handle(),
 			"account-authorization-granted", info->account, info->user);
 
-	g_free(info->user);
-	g_free(info);
+	purple_account_request_info_unref(info);
 }
 
 static void
@@ -1294,8 +1302,7 @@
 	purple_signal_emit(purple_accounts_get_handle(),
 			"account-authorization-denied", info->account, info->user);
 
-	g_free(info->user);
-	g_free(info);
+	purple_account_request_info_unref(info);
 }
 
 void *
@@ -1332,11 +1339,18 @@
 		info->deny_cb   = deny_cb;
 		info->userdata  = user_data;
 		info->user      = g_strdup(remote_user);
+		info->ref       = 2;  /* We hold an extra ref to make sure info remains valid
+		                         if any of the callbacks are called synchronously. We
+		                         unref it after the function call */
+
 		info->ui_handle = ui_ops->request_authorize(account, remote_user, id, alias, message,
 							    on_list, request_auth_cb, request_deny_cb, info);
 
-		handles = g_list_append(handles, info);
-		return info->ui_handle;
+		info = purple_account_request_info_unref(info);
+		if (info) {
+			handles = g_list_append(handles, info);
+			return info->ui_handle;
+		}
 	}
 
 	return NULL;
--- a/libpurple/blist.h	Fri Dec 12 04:01:39 2008 +0000
+++ b/libpurple/blist.h	Fri Dec 12 04:02:08 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	Fri Dec 12 04:01:39 2008 +0000
+++ b/libpurple/cmds.h	Fri Dec 12 04:02:08 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	Fri Dec 12 04:01:39 2008 +0000
+++ b/libpurple/connection.h	Fri Dec 12 04:02:08 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	Fri Dec 12 04:01:39 2008 +0000
+++ b/libpurple/conversation.h	Fri Dec 12 04:02:08 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	Fri Dec 12 04:01:39 2008 +0000
+++ b/libpurple/plugins/perl/common/Account.xs	Fri Dec 12 04:02:08 2008 +0000
@@ -107,7 +107,7 @@
     t_GL = NULL;
     t_len = av_len((AV *)SvRV(status_types));
 
-    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);
@@ -209,7 +209,7 @@
     t_GL = NULL;
     t_len = av_len((AV *)SvRV(list));
 
-    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);
@@ -238,13 +238,13 @@
     t_GL1 = NULL;
     t_len = av_len((AV *)SvRV(A));
 
-    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));
 
-    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	Fri Dec 12 04:01:39 2008 +0000
+++ b/libpurple/plugins/perl/common/AccountOpts.xs	Fri Dec 12 04:02:08 2008 +0000
@@ -44,7 +44,7 @@
 	t_GL = NULL;
 	t_len = av_len((AV *)SvRV(values));
 
-	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);
@@ -132,7 +132,7 @@
 	t_GL = NULL;
 	t_len = av_len((AV *)SvRV(values));
 
-	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/Certificate.xs	Fri Dec 12 04:01:39 2008 +0000
+++ b/libpurple/plugins/perl/common/Certificate.xs	Fri Dec 12 04:02:08 2008 +0000
@@ -231,8 +231,8 @@
 		int len = 0, i = 0;
 		struct cb_data *d = NULL;
 	PPCODE:
-		len = av_len(cert_chain) + 1;
-		for(i = 0; i < len; i++) {
+		len = av_len(cert_chain);
+		for(i = 0; i <= len; i++) {
 			SV **sv = av_fetch(cert_chain, i, 0);
 			if(!sv || !purple_perl_is_ref_object(*sv)) {
 				g_list_free(l);
--- a/libpurple/plugins/perl/common/Conversation.xs	Fri Dec 12 04:01:39 2008 +0000
+++ b/libpurple/plugins/perl/common/Conversation.xs	Fri Dec 12 04:02:08 2008 +0000
@@ -336,7 +336,7 @@
 	t_GL = NULL;
 	t_len = av_len((AV *)SvRV(users));
 
-	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) {
@@ -374,7 +374,7 @@
 	t_GL = NULL;
 	t_len = av_len((AV *)SvRV(ignored));
 
-	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) {
@@ -431,19 +431,19 @@
 	t_GL_users = NULL;
 	t_len = av_len((AV *)SvRV(users));
 
-	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));
 
-	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));
 
-	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	Fri Dec 12 04:01:39 2008 +0000
+++ b/libpurple/plugins/perl/common/Prefs.xs	Fri Dec 12 04:02:08 2008 +0000
@@ -53,7 +53,7 @@
 	t_GL = NULL;
 	t_len = av_len((AV *)SvRV(value));
 
-	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);
@@ -75,7 +75,7 @@
 	t_GL = NULL;
 	t_len = av_len((AV *)SvRV(value));
 
-	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);
@@ -204,7 +204,7 @@
 	t_GL = NULL;
 	t_len = av_len((AV *)SvRV(value));
 
-	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);
@@ -226,7 +226,7 @@
 	t_GL = NULL;
 	t_len = av_len((AV *)SvRV(value));
 
-	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	Fri Dec 12 04:01:39 2008 +0000
+++ b/libpurple/plugins/perl/common/Roomlist.xs	Fri Dec 12 04:02:08 2008 +0000
@@ -80,7 +80,7 @@
 	t_GL = NULL;
 	t_len = av_len((AV *)SvRV(fields));
 
-	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	Fri Dec 12 04:01:39 2008 +0000
+++ b/libpurple/plugins/perl/common/Status.xs	Fri Dec 12 04:02:08 2008 +0000
@@ -85,7 +85,7 @@
 	t_GL = NULL;
 	t_len = av_len((AV *)SvRV(source_list));
 
-	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);
@@ -381,7 +381,7 @@
 	t_GL = NULL;
 	t_len = av_len((AV *)SvRV(status_types));
 
-	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	Fri Dec 12 04:01:39 2008 +0000
+++ b/libpurple/protocols/bonjour/bonjour_ft.h	Fri Dec 12 04:02:08 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	Fri Dec 12 04:01:39 2008 +0000
+++ b/libpurple/protocols/jabber/auth.c	Fri Dec 12 04:02:08 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	Fri Dec 12 04:01:39 2008 +0000
+++ b/libpurple/protocols/jabber/buddy.c	Fri Dec 12 04:02:08 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	Fri Dec 12 04:01:39 2008 +0000
+++ b/libpurple/protocols/jabber/jutil.c	Fri Dec 12 04:02:08 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	Fri Dec 12 04:01:39 2008 +0000
+++ b/libpurple/protocols/jabber/jutil.h	Fri Dec 12 04:02:08 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	Fri Dec 12 04:01:39 2008 +0000
+++ b/libpurple/protocols/jabber/presence.c	Fri Dec 12 04:02:08 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	Fri Dec 12 04:01:39 2008 +0000
+++ b/libpurple/protocols/jabber/si.c	Fri Dec 12 04:02:08 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	Fri Dec 12 04:01:39 2008 +0000
+++ b/libpurple/protocols/msn/contact.h	Fri Dec 12 04:02:08 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	Fri Dec 12 04:01:39 2008 +0000
+++ b/libpurple/protocols/msn/servconn.h	Fri Dec 12 04:02:08 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	Fri Dec 12 04:01:39 2008 +0000
+++ b/libpurple/protocols/msn/slpcall.h	Fri Dec 12 04:02:08 2008 +0000
@@ -37,7 +37,7 @@
 typedef enum
 {
 	MSN_SLPCALL_ANY,
-	MSN_SLPCALL_DC,
+	MSN_SLPCALL_DC
 
 } MsnSlpCallType;
 
--- a/libpurple/protocols/msn/switchboard.h	Fri Dec 12 04:01:39 2008 +0000
+++ b/libpurple/protocols/msn/switchboard.h	Fri Dec 12 04:02:08 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/oscar/family_locate.c	Fri Dec 12 04:01:39 2008 +0000
+++ b/libpurple/protocols/oscar/family_locate.c	Fri Dec 12 04:02:08 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	Fri Dec 12 04:01:39 2008 +0000
+++ b/libpurple/protocols/oscar/oscar.c	Fri Dec 12 04:02:08 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	Fri Dec 12 04:01:39 2008 +0000
+++ b/libpurple/protocols/oscar/oscar.h	Fri Dec 12 04:02:08 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	Fri Dec 12 04:01:39 2008 +0000
+++ b/libpurple/protocols/qq/buddy_info.c	Fri Dec 12 04:02:08 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 {
--- a/libpurple/protocols/qq/buddy_info.h	Fri Dec 12 04:01:39 2008 +0000
+++ b/libpurple/protocols/qq/buddy_info.h	Fri Dec 12 04:02:08 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	Fri Dec 12 04:01:39 2008 +0000
+++ b/libpurple/protocols/qq/buddy_opt.c	Fri Dec 12 04:02:08 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 {
--- a/libpurple/protocols/qq/buddy_opt.h	Fri Dec 12 04:01:39 2008 +0000
+++ b/libpurple/protocols/qq/buddy_opt.h	Fri Dec 12 04:02:08 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.h	Fri Dec 12 04:01:39 2008 +0000
+++ b/libpurple/protocols/qq/group.h	Fri Dec 12 04:02:08 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	Fri Dec 12 04:01:39 2008 +0000
+++ b/libpurple/protocols/qq/group_info.h	Fri Dec 12 04:02:08 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	Fri Dec 12 04:01:39 2008 +0000
+++ b/libpurple/protocols/qq/group_join.c	Fri Dec 12 04:02:08 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 {
--- a/libpurple/protocols/qq/im.h	Fri Dec 12 04:01:39 2008 +0000
+++ b/libpurple/protocols/qq/im.h	Fri Dec 12 04:02:08 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_define.h	Fri Dec 12 04:01:39 2008 +0000
+++ b/libpurple/protocols/qq/qq_define.h	Fri Dec 12 04:02:08 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_process.h	Fri Dec 12 04:01:39 2008 +0000
+++ b/libpurple/protocols/qq/qq_process.h	Fri Dec 12 04:02:08 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	Fri Dec 12 04:01:39 2008 +0000
+++ b/libpurple/protocols/qq/qq_trans.c	Fri Dec 12 04:02:08 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	Fri Dec 12 04:01:39 2008 +0000
+++ b/libpurple/protocols/sametime/sametime.c	Fri Dec 12 04:02:08 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	Fri Dec 12 04:01:39 2008 +0000
+++ b/libpurple/protocols/silc10/wb.c	Fri Dec 12 04:02:08 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	Fri Dec 12 04:01:39 2008 +0000
+++ b/libpurple/protocols/yahoo/yahoochat.c	Fri Dec 12 04:02:08 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	Fri Dec 12 04:01:39 2008 +0000
+++ b/libpurple/protocols/yahoo/ycht.h	Fri Dec 12 04:02:08 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	Fri Dec 12 04:01:39 2008 +0000
+++ b/libpurple/protocols/zephyr/zephyr.c	Fri Dec 12 04:02:08 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	Fri Dec 12 04:01:39 2008 +0000
+++ b/libpurple/prpl.h	Fri Dec 12 04:02:08 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	Fri Dec 12 04:01:39 2008 +0000
+++ b/libpurple/smiley.c	Fri Dec 12 04:02:08 2008 +0000
@@ -288,7 +288,7 @@
 {
 	PROP_0,
 	PROP_SHORTCUT,
-	PROP_IMGSTORE,
+	PROP_IMGSTORE
 };
 
 #define PROP_SHORTCUT_S "shortcut"
--- a/pidgin/gtkutils.c	Fri Dec 12 04:01:39 2008 +0000
+++ b/pidgin/gtkutils.c	Fri Dec 12 04:02:08 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	Fri Dec 12 04:01:39 2008 +0000
+++ b/pidgin/plugins/perl/common/GtkIMHtml.xs	Fri Dec 12 04:02:08 2008 +0000
@@ -173,7 +173,7 @@
 	t_GL = NULL;
 	t_len = av_len((AV *)SvRV(unused));
 
-	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));
 	}