diff libpurple/protocols/bonjour/buddy.c @ 18847:2bf2bd713955

Calculate the icon hash instead of using the current phsh value - iChat seems to update the TXT record before updating the NULL record containing image data, this causes the old image to be retrieved - perhaps we should re-fetch when this happens?
author Daniel Atallah <daniel.atallah@gmail.com>
date Thu, 09 Aug 2007 02:17:18 +0000
parents 7bf6b9a70b41
children f773aa054dca
line wrap: on
line diff
--- a/libpurple/protocols/bonjour/buddy.c	Wed Aug 08 22:47:38 2007 +0000
+++ b/libpurple/protocols/bonjour/buddy.c	Thu Aug 09 02:17:18 2007 +0000
@@ -18,6 +18,7 @@
 #include <stdlib.h>
 
 #include "internal.h"
+#include "cipher.h"
 #include "buddy.h"
 #include "account.h"
 #include "blist.h"
@@ -106,11 +107,10 @@
 	PurpleBuddy *buddy;
 	PurpleGroup *group;
 	PurpleAccount *account = bonjour_buddy->account;
-	const char *status_id, *first, *last, *old_hash, *new_hash;
-	gchar *alias = NULL;
+	const char *status_id, *old_hash, *new_hash;
 
 	/* Translate between the Bonjour status and the Purple status */
-	if (g_ascii_strcasecmp("dnd", bonjour_buddy->status) == 0)
+	if (bonjour_buddy->status != NULL && g_ascii_strcasecmp("dnd", bonjour_buddy->status) == 0)
 		status_id = BONJOUR_STATUS_ID_AWAY;
 	else
 		status_id = BONJOUR_STATUS_ID_AVAILABLE;
@@ -138,15 +138,21 @@
 	}
 
 	/* Create the alias for the buddy using the first and the last name */
-	first = bonjour_buddy->first;
-	last = bonjour_buddy->last;
-	if ((first && *first) || (last && *last))
-		alias = g_strdup_printf("%s%s%s",
-					(first && *first ? first : ""),
-					(first && *first && last && *last ? " " : ""),
-					(last && *last ? last : ""));
-	serv_got_alias(purple_account_get_connection(account), buddy->name, alias);
-	g_free(alias);
+	if (bonjour_buddy->nick)
+		serv_got_alias(purple_account_get_connection(account), buddy->name, bonjour_buddy->nick);
+	else {
+		gchar *alias = NULL;
+		const char *first, *last;
+		first = bonjour_buddy->first;
+		last = bonjour_buddy->last;
+		if ((first && *first) || (last && *last))
+			alias = g_strdup_printf("%s%s%s",
+						(first && *first ? first : ""),
+						(first && *first && last && *last ? " " : ""),
+						(last && *last ? last : ""));
+		serv_got_alias(purple_account_get_connection(account), buddy->name, alias);
+		g_free(alias);
+	}
 
 	/* Set the user's status */
 	if (bonjour_buddy->msg != NULL)
@@ -166,12 +172,46 @@
 	new_hash = (bonjour_buddy->phsh && *(bonjour_buddy->phsh)) ? bonjour_buddy->phsh : NULL;
 	if (new_hash && (!old_hash || strcmp(old_hash, new_hash) != 0)) {
 		/* Look up the new icon data */
+		/* TODO: Make sure the hash assigned to the retrieved buddy icon is the same
+		 * as what we looked up. */
 		bonjour_dns_sd_retrieve_buddy_icon(bonjour_buddy);
-	} else
+	} else if (!new_hash)
 		purple_buddy_icons_set_for_user(account, buddy->name, NULL, 0, NULL);
 }
 
 /**
+ * We got the buddy icon data; deal with it
+ */
+void bonjour_buddy_got_buddy_icon(BonjourBuddy *buddy, gconstpointer data, gsize len) {
+	/* Recalculate the hash instead of using the current phsh to make sure it is accurate for the icon. */
+	int i;
+	gchar *enc;
+	char *p, hash[41];
+	unsigned char hashval[20];
+
+	if (data == NULL || len == 0)
+		return;
+
+	enc = purple_base64_encode(data, len);
+
+	purple_cipher_digest_region("sha1", data,
+				    len, sizeof(hashval),
+				    hashval, NULL);
+
+	p = hash;
+	for(i=0; i<20; i++, p+=2)
+		snprintf(p, 3, "%02x", hashval[i]);
+
+	purple_debug_info("bonjour", "Got buddy icon for %s icon hash='%s' phsh='%s'.\n", buddy->name,
+			  hash, buddy->phsh ? buddy->phsh : "(null)");
+
+	purple_buddy_icons_set_for_user(buddy->account, buddy->name,
+		g_memdup(data, len), len, hash);
+
+	g_free(enc);
+}
+
+/**
  * Deletes a buddy from memory.
  */
 void