changeset 5289:cfbd0cb3f18b

[gaim-migrate @ 5661] this implements the receiving side of JEP-0008 (User Avatars) which most Gaim users know better as Buddy Icons. Only one client I know of actually sends them, and it's on windows. This doesn't handle multiple resources right, but I'll fix that after my exam. committer: Tailor Script <tailor@pidgin.im>
author Nathan Walp <nwalp@pidgin.im>
date Sat, 03 May 2003 16:08:46 +0000
parents 92cbe9541c3b
children 1f9e349b4e09
files src/protocols/jabber/jabber.c src/util.c
diffstat 2 files changed, 81 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/protocols/jabber/jabber.c	Sat May 03 06:37:29 2003 +0000
+++ b/src/protocols/jabber/jabber.c	Sat May 03 16:08:46 2003 +0000
@@ -1444,6 +1444,59 @@
 	}
 }
 
+static void jabber_handleavatar(gjconn gjc, xmlnode querynode, char *from) {
+	char *buddy;
+	char *encoded;
+	char *icon;
+	int iconlen;
+	xmlnode data;
+
+	if((buddy = get_realwho(gjc, from, FALSE, NULL)) == NULL)
+		return;
+
+	data = xmlnode_get_tag(querynode, "data");
+
+	if(!data) {
+		g_free(buddy);
+		return;
+	}
+
+	encoded = xmlnode_get_data(data);
+
+	if(!encoded) {
+		g_free(buddy);
+		return;
+	}
+
+	frombase64(encoded, &icon, &iconlen);
+	set_icon_data(GJ_GC(gjc), buddy, icon, iconlen);
+	g_free(icon);
+	g_free(buddy);
+}
+
+static void jabber_request_buddy_avatar(struct gaim_connection *gc, char *who) {
+	xmlnode x;
+	char *id;
+	char *realwho;
+	struct jabber_data *jd = gc->proto_data;
+	gjconn gjc = jd->gjc;
+
+	if((realwho = get_realwho(gjc, who, TRUE, NULL)) == NULL)
+		return;
+
+	x = jutil_iqnew(JPACKET__GET, "jabber:iq:avatar");
+	xmlnode_put_attrib(x, "to", realwho);
+
+	g_free(realwho);
+
+	id = gjab_getid(gjc);
+	xmlnode_put_attrib(x, "id", id);
+
+	gjab_send(gjc, x);
+
+	xmlnode_free(x);
+}
+
 static void jabber_handlepresence(gjconn gjc, jpacket p)
 {
 	char *to, *from, *type;
@@ -1506,9 +1559,6 @@
 		}
 	}
 
-	if ((y = xmlnode_get_tag(p->x, "priority")))
-		priority = atoi(xmlnode_get_data(y));
-
 	/* um. we're going to check if it's a chat. if it isn't, and there are pending
 	 * chats, create the chat. if there aren't pending chats and we don't have the
 	 * buddy on our list, simply bail out. */
@@ -1534,6 +1584,29 @@
 		jabber_track_away(gjc, p, type);
 	}
 
+	for(y = xmlnode_get_firstchild(p->x); y; y = xmlnode_get_nextsibling(y)) {
+		if(!strcmp(xmlnode_get_name(y), "priority")) {
+			priority = atoi(xmlnode_get_data(y));
+		} else if(!strcmp(xmlnode_get_name(y), "x")) {
+			if(!strcmp(xmlnode_get_attrib(y, "xmlns"), "jabber:x:avatar")) {
+				xmlnode hash = xmlnode_get_tag(y, "hash");
+				if(hash) {
+					char *old_hash = gaim_buddy_get_setting(b, "icon_checksum");
+					char *new_hash = xmlnode_get_data(hash);
+					if(!old_hash || strcmp(old_hash, new_hash)) {
+						jabber_request_buddy_avatar(GJ_GC(gjc), from);
+						gaim_buddy_set_setting(b, "icon_checksum", new_hash);
+						gaim_blist_save();
+					}
+				} else {
+					gaim_buddy_set_setting(b, "icon_checksum", NULL);
+					gaim_blist_save();
+				}
+			}
+		}
+	}
+
+
 
 	if (!cnv) {
 		/* this is where we handle presence information for "regular" buddies */
@@ -2219,6 +2292,8 @@
 			} else if (vcard) {
 				jabber_track_queries(gjc->queries, id, TRUE);	/* delete query track */
 				jabber_handlevcard(gjc, vcard, from);
+			} else if(NSCHECK(querynode, "jabber:iq:avatar")) {
+				jabber_handleavatar(gjc, querynode, from);
 			} else if((xmlns = xmlnode_get_attrib(querynode, "xmlns")) != NULL) {
 				gaim_debug(GAIM_DEBUG_MISC, "jabber",
 						   "jabber:iq:query: %s\n", xmlns);
--- a/src/util.c	Sat May 03 06:37:29 2003 +0000
+++ b/src/util.c	Sat May 03 16:08:46 2003 +0000
@@ -430,6 +430,9 @@
 			tmp = 62;
 		} else if (*c == '/') {
 			tmp = 63;
+		} else if (*c == '\r' || *c == '\n') {
+			c++;
+			continue;
 		} else if (*c == '=') {
 			if (n == 3) {
 				out = g_realloc(out, len + 2);