Move the prpl icon checksum code into the core, so we can delete the rlaager.gaim_migration

Wed, 25 Apr 2007 00:56:13 +0000

author
Richard Laager <rlaager@pidgin.im>
date
Wed, 25 Apr 2007 00:56:13 +0000
branch
rlaager.gaim_migration
changeset 16534
2ab9e23f99d9
parent 16533
91e3e84b05f2
child 16535
ef62fab62fcb

Move the prpl icon checksum code into the core, so we can delete the
checksum if the cache file disappears.

See ticket #223

libpurple/buddyicon.c file | annotate | diff | comparison | revisions
libpurple/buddyicon.h file | annotate | diff | comparison | revisions
libpurple/protocols/jabber/buddy.c file | annotate | diff | comparison | revisions
libpurple/protocols/jabber/presence.c file | annotate | diff | comparison | revisions
libpurple/protocols/msn/slp.c file | annotate | diff | comparison | revisions
libpurple/protocols/oscar/oscar.c file | annotate | diff | comparison | revisions
libpurple/protocols/qq/buddy_info.c file | annotate | diff | comparison | revisions
libpurple/protocols/qq/buddy_info.h file | annotate | diff | comparison | revisions
libpurple/protocols/yahoo/yahoo.c file | annotate | diff | comparison | revisions
libpurple/protocols/yahoo/yahoo.h file | annotate | diff | comparison | revisions
libpurple/protocols/yahoo/yahoo_picture.c file | annotate | diff | comparison | revisions
--- a/libpurple/buddyicon.c	Tue Apr 24 20:23:50 2007 +0000
+++ b/libpurple/buddyicon.c	Wed Apr 25 00:56:13 2007 +0000
@@ -38,9 +38,10 @@
 struct _PurpleBuddyIcon
 {
 	PurpleAccount *account;    /**< The account the user is on.          */
-	char *username;            /**< The username the icon belongs to.    */
 	PurpleStoredImage *img;    /**< The id of the stored image with the
 	                                the icon data.                       */
+	char *username;            /**< The username the icon belongs to.    */
+	char *checksum;            /**< The protocol checksum.               */
 	int ref_count;             /**< The buddy icon reference count.      */
 };
 
@@ -196,7 +197,7 @@
 	g_free(path);
 }
 
-gboolean
+static gboolean
 value_equals(gpointer key, gpointer value, gpointer user_data)
 {
 	return (value == user_data);
@@ -265,6 +266,7 @@
 
 	icon->account = account;
 	icon->username = g_strdup(username);
+	icon->checksum = NULL;
 
 	icon_cache = g_hash_table_lookup(account_cache, account);
 
@@ -282,7 +284,8 @@
 
 PurpleBuddyIcon *
 purple_buddy_icon_new(PurpleAccount *account, const char *username,
-                      void *icon_data, size_t icon_len)
+                      void *icon_data, size_t icon_len,
+                      const char *checksum)
 {
 	PurpleBuddyIcon *icon;
 
@@ -305,7 +308,7 @@
 	/* purple_buddy_icon_set_data() sets img, but it
 	 * references img first, so we need to initialize it */
 	icon->img = NULL;
-	purple_buddy_icon_set_data(icon, icon_data, icon_len);
+	purple_buddy_icon_set_data(icon, icon_data, icon_len, checksum);
 
 	return icon;
 }
@@ -338,6 +341,7 @@
 			g_hash_table_remove(icon_cache, purple_buddy_icon_get_username(icon));
 
 		g_free(icon->username);
+		g_free(icon->checksum);
 		purple_imgstore_unref(icon->img);
 
 		PURPLE_DBUS_UNREGISTER_POINTER(icon);
@@ -388,11 +392,24 @@
 			purple_blist_node_set_string((PurpleBlistNode *)buddy,
 			                             "buddy_icon",
 			                             filename);
+
+			if (icon->checksum && *icon->checksum)
+			{
+				purple_blist_node_set_string((PurpleBlistNode *)buddy,
+				                             "icon_checksum",
+				                             icon->checksum);
+			}
+			else
+			{
+				purple_blist_node_remove_setting((PurpleBlistNode *)buddy,
+				                                 "icon_checksum");
+			}
 			ref_filename(filename);
 		}
 		else
 		{
 			purple_blist_node_remove_setting((PurpleBlistNode *)buddy, "buddy_icon");
+			purple_blist_node_remove_setting((PurpleBlistNode *)buddy, "icon_checksum");
 		}
 		unref_filename(old_icon);
 		g_free(old_icon);
@@ -407,7 +424,8 @@
 }
 
 void
-purple_buddy_icon_set_data(PurpleBuddyIcon *icon, guchar *data, size_t len)
+purple_buddy_icon_set_data(PurpleBuddyIcon *icon, guchar *data,
+                           size_t len, const char *checksum)
 {
 	PurpleStoredImage *old_img;
 
@@ -419,6 +437,8 @@
 	if (data != NULL && len > 0)
 		icon->img = purple_buddy_icon_data_new(data, len, NULL);
 
+	icon->checksum = g_strdup(checksum);
+
 	purple_buddy_icon_update(icon);
 
 	purple_imgstore_unref(old_img);
@@ -440,6 +460,14 @@
 	return icon->username;
 }
 
+const char *
+purple_buddy_icon_get_checksum(const PurpleBuddyIcon *icon)
+{
+	g_return_val_if_fail(icon != NULL, NULL);
+
+	return icon->checksum;
+}
+
 gconstpointer
 purple_buddy_icon_get_data(const PurpleBuddyIcon *icon, size_t *len)
 {
@@ -467,7 +495,8 @@
 
 void
 purple_buddy_icons_set_for_user(PurpleAccount *account, const char *username,
-                                void *icon_data, size_t icon_len)
+                                void *icon_data, size_t icon_len,
+                                const char *checksum)
 {
 	g_return_if_fail(account  != NULL);
 	g_return_if_fail(username != NULL);
@@ -479,21 +508,28 @@
 		icon = purple_buddy_icons_find(account, username);
 
 		if (icon != NULL)
-			purple_buddy_icon_set_data(icon, icon_data, icon_len);
+			purple_buddy_icon_set_data(icon, icon_data, icon_len, checksum);
 	}
 	else
 	{
-		PurpleBuddyIcon *icon = purple_buddy_icon_new(account, username, icon_data, icon_len);
+		PurpleBuddyIcon *icon = purple_buddy_icon_new(account, username, icon_data, icon_len, checksum);
 		purple_buddy_icon_unref(icon);
 	}
 }
 
+const char *
+purple_buddy_icons_get_checksum_for_user(PurpleBuddy *buddy)
+{
+	return purple_blist_node_get_string((PurpleBlistNode*)buddy,
+	                                    "icon_checksum");
+}
+
 static gboolean
 read_icon_file(const char *path, guchar **data, size_t *len)
 {
 	GError *err = NULL;
 
-	if (!g_file_get_contents(path, data, len, &err))
+	if (!g_file_get_contents(path, (gchar **)data, len, &err))
 	{
 		purple_debug_error("buddyicon", "Error reading %s: %s\n",
 		                   path, err->message);
@@ -546,11 +582,14 @@
 			char *path = g_build_filename(dirname, protocol_icon_file, NULL);
 			if (read_icon_file(path, &data, &len))
 			{
+				const char *checksum;
+
 				if (icon == NULL)
 					icon = purple_buddy_icon_create(account, username);
 				icon->ref_count = 0;
 				icon->img = NULL;
-				purple_buddy_icon_set_data(icon, data, len);
+				checksum = g_strdup(purple_blist_node_get_string((PurpleBlistNode*)b, "icon_checksum"));
+				purple_buddy_icon_set_data(icon, data, len, checksum);
 				g_free(data);
 			}
 			g_free(path);
@@ -749,12 +788,43 @@
 		ref_filename(new_filename);
 
 		g_free(new_filename);
+
+		if (!strcmp(setting_name, "buddy_icon"))
+		{
+			const char *hash;
+
+			hash = purple_blist_node_get_string(node, "avatar_hash");
+			if (hash != NULL)
+			{
+				purple_blist_node_set_string(node, "icon_checksum", hash);
+				purple_blist_node_remove_setting(node, "avatar_hash");
+			}
+			else
+			{
+				int checksum = purple_blist_node_get_int(node, "icon_checksum");
+				if (checksum != 0)
+				{
+					char *checksum_str = g_strdup_printf("%i", checksum);
+					purple_blist_node_remove_setting(node, "icon_checksum");
+					purple_blist_node_set_string(node, "icon_checksum", checksum_str);
+					g_free(checksum_str);
+				}
+			}
+		}
 	}
 	else
 	{
 		/* If the icon is gone, drop the setting... */
 		purple_blist_node_remove_setting(node,
 		                                 setting_name);
+
+		if (!strcmp(setting_name, "buddy_icon"))
+		{
+			purple_blist_node_remove_setting(node,
+			                                 "avatar_hash");
+			purple_blist_node_remove_setting(node,
+			                                 "icon_checksum");
+		}
 		g_free(path);
 	}
 }
@@ -806,6 +876,8 @@
 					{
 						purple_blist_node_remove_setting(node,
 						                                 "buddy_icon");
+						purple_blist_node_remove_setting(node,
+						                                 "icon_checksum");
 					}
 					else
 						ref_filename(filename);
--- a/libpurple/buddyicon.h	Tue Apr 24 20:23:50 2007 +0000
+++ b/libpurple/buddyicon.h	Wed Apr 25 00:56:13 2007 +0000
@@ -54,11 +54,13 @@
  * @param username  The username the icon belongs to.
  * @param icon_data The buddy icon data.
  * @param icon_len  The buddy icon length.
+ * @param checksum  A protocol checksum from the prpl or @c NULL.
  *
  * @return The buddy icon structure.
  */
 PurpleBuddyIcon *purple_buddy_icon_new(PurpleAccount *account, const char *username,
-								void *icon_data, size_t icon_len);
+                                       void *icon_data, size_t icon_len,
+                                       const char *checksum);
 
 /**
  * Increments the reference count on a buddy icon.
@@ -93,8 +95,11 @@
  * @param icon The buddy icon.
  * @param data The buddy icon data received over the wire.
  * @param len  The length of the data in @a data.
+ * @param checksum  A protocol checksum from the prpl or @c NULL.
  */
-void purple_buddy_icon_set_data(PurpleBuddyIcon *icon, guchar *data, size_t len);
+void
+purple_buddy_icon_set_data(PurpleBuddyIcon *icon, guchar *data,
+                           size_t len, const char *checksum);
 
 /**
  * Returns the buddy icon's account.
@@ -115,6 +120,17 @@
 const char *purple_buddy_icon_get_username(const PurpleBuddyIcon *icon);
 
 /**
+ * Returns the buddy icon's checksum.
+ *
+ * This function is really only for prpl use.
+ *
+ * @param icon The buddy icon.
+ *
+ * @return The checksum.
+ */
+const char *purple_buddy_icon_get_checksum(const PurpleBuddyIcon *icon);
+
+/**
  * Returns the buddy icon's data.
  *
  * @param icon The buddy icon.
@@ -149,12 +165,27 @@
  * @param username  The username of the user.
  * @param icon_data The icon data.
  * @param icon_len  The length of the icon data.
+ * @param checksum  A protocol checksum from the prpl or @c NULL.
  *
  * @return The buddy icon set, or NULL if no icon was set.
  */
 void
 purple_buddy_icons_set_for_user(PurpleAccount *account, const char *username,
-                                void *icon_data, size_t icon_len);
+                                void *icon_data, size_t icon_len,
+                                const char *checksum);
+
+/**
+ * Returns the checksum for the buddy icon of a specified buddy.
+ *
+ * This avoids loading the icon image data from the cache if it's
+ * not already loaded for some other reason.
+ *
+ * @param buddy The buddy
+ *
+ * @return The checksum.
+ */
+const char *
+purple_buddy_icons_get_checksum_for_user(PurpleBuddy *buddy);
 
 /**
  * Returns the buddy icon information for a user.
--- a/libpurple/protocols/jabber/buddy.c	Tue Apr 24 20:23:50 2007 +0000
+++ b/libpurple/protocols/jabber/buddy.c	Wed Apr 25 00:56:13 2007 +0000
@@ -965,15 +965,14 @@
 							photo ? _("Photo") : _("Logo"),
 							GPOINTER_TO_INT(jbi->vcard_imgids->data));
 
-					purple_buddy_icons_set_for_user(js->gc->account, bare_jid,
-							data, size);
-
 					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]);
-					purple_blist_node_set_string((PurpleBlistNode*)b, "avatar_hash", hash);
+
+					purple_buddy_icons_set_for_user(js->gc->account, bare_jid,
+							data, size, hash);
 
 					g_free(data);
 					g_free(bintext);
--- a/libpurple/protocols/jabber/presence.c	Tue Apr 24 20:23:50 2007 +0000
+++ b/libpurple/protocols/jabber/presence.c	Wed Apr 25 00:56:13 2007 +0000
@@ -201,7 +201,6 @@
 static void jabber_vcard_parse_avatar(JabberStream *js, xmlnode *packet, gpointer blah)
 {
 	JabberBuddy *jb = NULL;
-	PurpleBuddy *b = NULL;
 	xmlnode *vcard, *photo, *binval;
 	char *text;
 	guchar *data;
@@ -221,21 +220,20 @@
 				(( (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;
+
 			data = purple_base64_decode(text, &size);
 
-			purple_buddy_icons_set_for_user(js->gc->account, from, data, size);
-			if((b = purple_find_buddy(js->gc->account, from))) {
-				unsigned char hashval[20];
-				char hash[41], *p;
-				int i;
+			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]);
 
-				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]);
-				purple_blist_node_set_string((PurpleBlistNode*)b, "avatar_hash", hash);
-			}
+			purple_buddy_icons_set_for_user(js->gc->account, from, data, size, hash);
+
 			g_free(data);
 			g_free(text);
 		}
@@ -520,7 +518,7 @@
 		}
 
 		if(avatar_hash) {
-			const char *avatar_hash2 = purple_blist_node_get_string((PurpleBlistNode*)b, "avatar_hash");
+			const char *avatar_hash2 = purple_buddy_icons_get_checksum_for_user(b);
 			if(!avatar_hash2 || strcmp(avatar_hash, avatar_hash2)) {
 				JabberIq *iq;
 				xmlnode *vcard;
--- a/libpurple/protocols/msn/slp.c	Tue Apr 24 20:23:50 2007 +0000
+++ b/libpurple/protocols/msn/slp.c	Wed Apr 25 00:56:13 2007 +0000
@@ -870,7 +870,7 @@
 	if (buddy == NULL)
 		return FALSE;
 
-	old = purple_blist_node_get_string((PurpleBlistNode *)buddy, "icon_checksum");
+	old = purple_buddy_icons_get_checksum_for_user(buddy);
 	new = msn_object_get_sha1(obj);
 
 	if (new == NULL)
@@ -956,22 +956,7 @@
 
 	if (obj == NULL)
 	{
-		/* It seems the user has not set a msnobject */
-		GSList *sl, *list;
-
-		list = purple_find_buddies(account, user->passport);
-
-		for (sl = list; sl != NULL; sl = sl->next)
-		{
-			PurpleBuddy *buddy = (PurpleBuddy *)sl->data;
-			if (buddy->icon)
-				purple_blist_node_remove_setting((PurpleBlistNode*)buddy, "icon_checksum");
-		}
-		g_slist_free(list);
-
-		/* TODO: I think we need better buddy icon core functions. */
-		purple_buddy_icons_set_for_user(account, user->passport, NULL, 0);
-
+		purple_buddy_icons_set_for_user(account, user->passport, NULL, 0, NULL);
 		return;
 	}
 
@@ -1001,7 +986,6 @@
 	MsnUserList *userlist;
 	const char *info;
 	PurpleAccount *account;
-	GSList *sl, *list;
 
 	g_return_if_fail(slpcall != NULL);
 
@@ -1013,18 +997,8 @@
 	userlist = slpcall->slplink->session->userlist;
 	account = slpcall->slplink->session->account;
 
-	/* TODO: I think we need better buddy icon core functions. */
 	purple_buddy_icons_set_for_user(account, slpcall->slplink->remote_user,
-								  (void *)data, size);
-
-	list = purple_find_buddies(account, slpcall->slplink->remote_user);
-
-	for (sl = list; sl != NULL; sl = sl->next)
-	{
-		PurpleBuddy *buddy = (PurpleBuddy *)sl->data;
-		purple_blist_node_set_string((PurpleBlistNode*)buddy, "icon_checksum", info);
-	}
-	g_slist_free(list);
+								  (void *)data, size, info);
 
 #if 0
 	/* Free one window slot */
@@ -1103,7 +1077,6 @@
 		MsnObject *my_obj = NULL;
 		gchar *data = NULL;
 		gsize len = 0;
-		GSList *sl, *list;
 
 #ifdef MSN_DEBUG_UD
 		purple_debug_info("msn", "Requesting our own user display\n");
@@ -1120,18 +1093,9 @@
 		}
 
 		/* TODO: I think we need better buddy icon core functions. */
-		purple_buddy_icons_set_for_user(account, user->passport, (void *)data, len);
+		purple_buddy_icons_set_for_user(account, user->passport, (void *)data, len, info);
 		g_free(data);
 
-		list = purple_find_buddies(account, user->passport);
-
-		for (sl = list; sl != NULL; sl = sl->next)
-		{
-			PurpleBuddy *buddy = (PurpleBuddy *)sl->data;
-			purple_blist_node_set_string((PurpleBlistNode*)buddy, "icon_checksum", info);
-		}
-		g_slist_free(list);
-
 		/* Free one window slot */
 		session->userlist->buddy_icon_window++;
 
--- a/libpurple/protocols/oscar/oscar.c	Tue Apr 24 20:23:50 2007 +0000
+++ b/libpurple/protocols/oscar/oscar.c	Wed Apr 25 00:56:13 2007 +0000
@@ -1841,34 +1841,14 @@
 	bi->ipaddr = info->icqinfo.ipaddr;
 
 	if (info->iconcsumlen) {
-		const char *filename, *saved_b16 = NULL;
-		char *b16 = NULL, *filepath = NULL;
+		const char *saved_b16 = NULL;
+		char *b16 = NULL;
 		PurpleBuddy *b = NULL;
 
 		b16 = purple_base16_encode(info->iconcsum, info->iconcsumlen);
 		b = purple_find_buddy(account, info->sn);
-		/*
-		 * If for some reason the checksum is valid, but cached file is not..
-		 * we want to know.
-		 */
 		if (b != NULL)
-			filename = purple_blist_node_get_string((PurpleBlistNode*)b, "buddy_icon");
-		else
-			filename = NULL;
-		if (filename != NULL) {
-			if (g_file_test(filename, G_FILE_TEST_EXISTS))
-				saved_b16 = purple_blist_node_get_string((PurpleBlistNode*)b,
-						"icon_checksum");
-			else {
-				filepath = g_build_filename(purple_buddy_icons_get_cache_dir(),
-											filename, NULL);
-				if (g_file_test(filepath, G_FILE_TEST_EXISTS))
-					saved_b16 = purple_blist_node_get_string((PurpleBlistNode*)b,
-															"icon_checksum");
-				g_free(filepath);
-			}
-		} else
-			saved_b16 = NULL;
+			saved_b16 = purple_buddy_icons_get_checksum_for_user(b);
 
 		if (!b16 || !saved_b16 || strcmp(b16, saved_b16)) {
 			GSList *cur = od->requesticon;
@@ -2177,7 +2157,8 @@
 	{
 		purple_buddy_icons_set_for_user(account, userinfo->sn,
 									  args->info.icon.icon,
-									  args->info.icon.length);
+									  args->info.icon.length,
+									  NULL);
 	}
 
 	else if (args->type & OSCAR_CAPABILITY_ICQSERVERRELAY)
@@ -3273,16 +3254,10 @@
 	 * no icon is set.  Ignore these.
 	 */
 	if ((iconlen > 0) && (iconlen != 90)) {
-		char *b16;
-		PurpleBuddy *b;
+		char *b16 = purple_base16_encode(iconcsum, iconcsumlen);
 		purple_buddy_icons_set_for_user(purple_connection_get_account(gc),
-									  sn, icon, iconlen);
-		b16 = purple_base16_encode(iconcsum, iconcsumlen);
-		b = purple_find_buddy(gc->account, sn);
-		if ((b16 != NULL) && (b != NULL)) {
-			purple_blist_node_set_string((PurpleBlistNode*)b, "icon_checksum", b16);
-			g_free(b16);
-		}
+									  sn, icon, iconlen, b16);
+		g_free(b16);
 	}
 
 	cur = od->requesticon;
--- a/libpurple/protocols/qq/buddy_info.c	Tue Apr 24 20:23:50 2007 +0000
+++ b/libpurple/protocols/qq/buddy_info.c	Wed Apr 25 00:56:13 2007 +0000
@@ -531,21 +531,17 @@
 	qq_send_packet_get_info(gc, qd->uid, FALSE);
 }
 
-void qq_set_buddy_icon_for_user(PurpleAccount *account, const gchar *who, const gchar *iconfile)
+void qq_set_buddy_icon_for_user(PurpleAccount *account, const gchar *who, const gchar *icon_num, const gchar *iconfile)
 {
-	FILE *file;
-	struct stat st;
+	gchar *data;
+	gsize len;
 
-	g_return_if_fail(g_stat(iconfile, &st) == 0);
-	file = g_fopen(iconfile, "rb");
-	if (file) {
-		PurpleBuddyIcon *icon;
-		size_t data_len;
-		gchar *data = g_new(gchar, st.st_size + 1);
-		data_len = fread(data, 1, st.st_size, file);
-		fclose(file);
-		purple_buddy_icons_set_for_user(account, who, data, data_len);
-		// TODO: Set a blist setting or something
+	if (!g_file_get_contents(iconfile, &data, &len, NULL))
+		g_return_if_reached();
+	else
+	{
+		purple_buddy_icons_set_for_user(account, who, data, len, icon_num);
+		g_free(data);
 	}
 }
 
@@ -599,26 +595,29 @@
 	/* tell server my icon changed */
 	_qq_send_packet_modify_face(gc, icon_num);
 	/* display in blist */
-	qq_set_buddy_icon_for_user(account, account->username, icon_path);
+	qq_set_buddy_icon_for_user(account, account->username, icon, icon_path);
 }
 
 
 static void _qq_update_buddy_icon(PurpleAccount *account, const gchar *name, gint face)
 {
-	gchar *icon_path;
 	PurpleBuddyIcon *icon = purple_buddy_icons_find(account, name);
 	gchar *icon_num_str = face_to_icon_str(face);
-	// TODO: This needs to use a blist setting or something.
-	const gchar *old_path = NULL;
-	const gchar *buddy_icon_dir = qq_buddy_icon_dir();
+	const gchar *old_icon_num = purple_buddy_icon_get_checksum(icon);
+
+	if (icon == NULL || old_icon_num == NULL ||
+	    strcmp(icon_num_str, old_icon_num))
+	{
+		gchar *icon_path;
 
-	icon_path = g_strconcat(buddy_icon_dir, G_DIR_SEPARATOR_S, QQ_ICON_PREFIX, 
-			icon_num_str, QQ_ICON_SUFFIX, NULL);
-	if (icon == NULL || old_path == NULL 
-		|| g_ascii_strcasecmp(icon_path, old_path) != 0)
-		qq_set_buddy_icon_for_user(account, name, icon_path);
+		icon_path = g_strconcat(qq_buddy_icon_dir(), G_DIR_SEPARATOR_S,
+		                        QQ_ICON_PREFIX, icon_num_str,
+		                        QQ_ICON_SUFFIX, NULL);
+
+		qq_set_buddy_icon_for_user(account, name, icon_num_str, icon_path);
+		g_free(icon_path);
+	}
 	g_free(icon_num_str);
-	g_free(icon_path);
 }
 
 /* after getting info or modify myself, refresh the buddy list accordingly */
--- a/libpurple/protocols/qq/buddy_info.h	Tue Apr 24 20:23:50 2007 +0000
+++ b/libpurple/protocols/qq/buddy_info.h	Wed Apr 25 00:56:13 2007 +0000
@@ -87,7 +87,7 @@
 void qq_refresh_buddy_and_myself(contact_info *info, PurpleConnection *gc);
 void qq_send_packet_get_info(PurpleConnection *gc, guint32 uid, gboolean show_window);
 void qq_set_my_buddy_icon(PurpleConnection *gc, const gchar *iconfile);
-void qq_set_buddy_icon_for_user(PurpleAccount *account, const gchar *who, const gchar *iconfile);
+void qq_set_buddy_icon_for_user(PurpleAccount *account, const gchar *who, const gchar *icon_num, const gchar *iconfile);
 void qq_prepare_modify_info(PurpleConnection *gc);
 void qq_process_modify_info_reply(guint8 *buf, gint buf_len, PurpleConnection *gc);
 void qq_process_get_info_reply(guint8 *buf, gint buf_len, PurpleConnection *gc);
--- a/libpurple/protocols/yahoo/yahoo.c	Tue Apr 24 20:23:50 2007 +0000
+++ b/libpurple/protocols/yahoo/yahoo.c	Wed Apr 25 00:56:13 2007 +0000
@@ -342,6 +342,8 @@
 		}
 		case 192: /* Pictures, aka Buddy Icons, checksum */
 		{
+			/* FIXME: Please, if you know this protocol,
+			 * FIXME: fix up the strtol() stuff if possible. */
 			int cksum = strtol(pair->value, NULL, 10);
 			PurpleBuddy *b;
 
@@ -353,9 +355,7 @@
 			if (!cksum || (cksum == -1)) {
 				if (f)
 					yahoo_friend_set_buddy_icon_need_request(f, TRUE);
-				purple_buddy_icons_set_for_user(gc->account, name, NULL, 0);
-				if (b)
-					purple_blist_node_remove_setting((PurpleBlistNode *)b, YAHOO_ICON_CHECKSUM_KEY);
+				purple_buddy_icons_set_for_user(gc->account, name, NULL, 0, NULL);
 				break;
 			}
 
@@ -363,7 +363,7 @@
 				break;
 
 			yahoo_friend_set_buddy_icon_need_request(f, FALSE);
-			if (b && cksum != purple_blist_node_get_int((PurpleBlistNode*)b, YAHOO_ICON_CHECKSUM_KEY))
+			if (b && cksum != strtol(purple_buddy_icons_get_checksum_for_user(b), NULL, 10))
 				yahoo_send_picture_request(gc, name);
 
 			break;
--- a/libpurple/protocols/yahoo/yahoo.h	Tue Apr 24 20:23:50 2007 +0000
+++ b/libpurple/protocols/yahoo/yahoo.h	Wed Apr 25 00:56:13 2007 +0000
@@ -48,7 +48,6 @@
 
 #define WEBMESSENGER_URL "http://login.yahoo.com/config/login?.src=pg"
 
-#define YAHOO_ICON_CHECKSUM_KEY "icon_checksum"
 #define YAHOO_PICURL_SETTING "picture_url"
 #define YAHOO_PICCKSUM_SETTING "picture_checksum"
 #define YAHOO_PICEXPIRE_SETTING "picture_expire"
--- a/libpurple/protocols/yahoo/yahoo_picture.c	Tue Apr 24 20:23:50 2007 +0000
+++ b/libpurple/protocols/yahoo/yahoo_picture.c	Wed Apr 25 00:56:13 2007 +0000
@@ -49,7 +49,6 @@
 {
 	struct yahoo_fetch_picture_data *d;
 	struct yahoo_data *yd;
-	PurpleBuddy *b;
 
 	d = user_data;
 	yd = d->gc->proto_data;
@@ -60,10 +59,9 @@
 	} else if (len == 0) {
 		purple_debug_error("yahoo", "Fetched an icon with length 0.  Strange.\n");
 	} else {
-		purple_buddy_icons_set_for_user(purple_connection_get_account(d->gc), d->who, (void *)pic_data, len);
-		b = purple_find_buddy(purple_connection_get_account(d->gc), d->who);
-		if (b)
-			purple_blist_node_set_int((PurpleBlistNode*)b, YAHOO_ICON_CHECKSUM_KEY, d->checksum);
+		char *checksum = g_strdup_printf("%i", d->checksum);
+		purple_buddy_icons_set_for_user(purple_connection_get_account(d->gc), d->who, (void *)pic_data, len, checksum);
+		g_free(checksum);
 	}
 
 	g_free(d->who);
@@ -117,7 +115,9 @@
 		PurpleUtilFetchUrlData *url_data;
 		struct yahoo_fetch_picture_data *data;
 		PurpleBuddy *b = purple_find_buddy(gc->account, who);
-		if (b && (checksum == purple_blist_node_get_int((PurpleBlistNode*)b, YAHOO_ICON_CHECKSUM_KEY)))
+
+		/* FIXME: Cleanup this strtol() stuff if possible. */
+		if (b && (checksum == strtol(purple_buddy_icons_get_checksum_for_user(b), NULL, 10)))
 			return;
 
 		data = g_new0(struct yahoo_fetch_picture_data, 1);
@@ -166,11 +166,8 @@
 		if (icon == 2)
 			yahoo_send_picture_request(gc, who);
 		else if ((icon == 0) || (icon == 1)) {
-			PurpleBuddy *b = purple_find_buddy(gc->account, who);
 			YahooFriend *f;
-			purple_buddy_icons_set_for_user(gc->account, who, NULL, 0);
-			if (b)
-				purple_blist_node_remove_setting((PurpleBlistNode *)b, YAHOO_ICON_CHECKSUM_KEY);
+			purple_buddy_icons_set_for_user(gc->account, who, NULL, 0, NULL);
 			if ((f = yahoo_friend_find(gc, who)))
 				yahoo_friend_set_buddy_icon_need_request(f, TRUE);
 			purple_debug_misc("yahoo", "Setting user %s's icon to NULL.\n", who);
@@ -203,7 +200,9 @@
 
 	if (who) {
 		PurpleBuddy *b = purple_find_buddy(gc->account, who);
-		if (b && (checksum != purple_blist_node_get_int((PurpleBlistNode*)b, YAHOO_ICON_CHECKSUM_KEY)))
+
+		/* FIXME: Cleanup this strtol() stuff if possible. */
+		if (b && (checksum != strtol(purple_buddy_icons_get_checksum_for_user(b), NULL, 10)))
 			yahoo_send_picture_request(gc, who);
 	}
 }
@@ -276,11 +275,8 @@
 		if (avatar == 2)
 			yahoo_send_picture_request(gc, who);
 		else if ((avatar == 0) || (avatar == 1)) {
-			PurpleBuddy *b = purple_find_buddy(gc->account, who);
 			YahooFriend *f;
-			purple_buddy_icons_set_for_user(gc->account, who, NULL, 0);
-			if (b)
-				purple_blist_node_remove_setting((PurpleBlistNode *)b, YAHOO_ICON_CHECKSUM_KEY);
+			purple_buddy_icons_set_for_user(gc->account, who, NULL, 0, NULL);
 			if ((f = yahoo_friend_find(gc, who)))
 				yahoo_friend_set_buddy_icon_need_request(f, TRUE);
 			purple_debug_misc("yahoo", "Setting user %s's icon to NULL.\n", who);

mercurial