diff libpurple/protocols/jabber/presence.c @ 25784:05693f6885a4

Support old (XEP v1.3) Entity Capabilities alongside the new ones. The ext structures from v1.3 are stored in a ref-counted structure that is shared among all instances of the ClientInfo that share the same 'node' (unique per client). exts are only used for v1.3-entity capabilities clients and are not shared with caps that specify the 'hash' attribute (required in v1.5). The jabber_caps_cbplususerdata is also ref-counted and will never leak, even if some disco#info responses from a client return errors.
author Paul Aurich <paul@darkrain42.org>
date Fri, 19 Dec 2008 04:11:07 +0000
parents 6bdcdb77ce77
children 5ad14a53e266
line wrap: on
line diff
--- a/libpurple/protocols/jabber/presence.c	Wed Dec 17 04:33:00 2008 +0000
+++ b/libpurple/protocols/jabber/presence.c	Fri Dec 19 04:11:07 2008 +0000
@@ -382,7 +382,9 @@
 	char *from;
 } JabberPresenceCapabilities;
 
-static void jabber_presence_set_capabilities(JabberCapsClientInfo *info, JabberPresenceCapabilities *userdata)
+static void
+jabber_presence_set_capabilities(JabberCapsClientInfo *info, GList *exts,
+                                 JabberPresenceCapabilities *userdata)
 {
 	JabberBuddyResource *jbr;
 	char *resource = g_utf8_strrchr(userdata->from, -1, '/');
@@ -392,11 +394,22 @@
 	if (!jbr) {
 		g_free(userdata->from);
 		g_free(userdata);
+		jabber_caps_client_info_unref(info);
+		if (exts) {
+			g_list_foreach(exts, (GFunc)g_free, NULL);
+			g_list_free(exts);
+		}
 		return;
 	}
 
-	jabber_caps_client_info_unref(jbr->caps);
-	jbr->caps = info;
+	jabber_caps_client_info_unref(jbr->caps.info);
+	if (jbr->caps.exts) {
+		g_list_foreach(jbr->caps.exts, (GFunc)g_free, NULL);
+		g_list_free(jbr->caps.exts);
+	}
+
+	jbr->caps.info = info;
+	jbr->caps.exts = exts;
 
 	if (jabber_resource_has_capability(jbr, "http://jabber.org/protocol/commands")) {
 		JabberIq *iq = jabber_iq_new_query(userdata->js, JABBER_IQ_GET, "http://jabber.org/protocol/disco#items");
@@ -751,13 +764,16 @@
 				const char *node = xmlnode_get_attrib(caps,"node");
 				const char *ver = xmlnode_get_attrib(caps,"ver");
 				const char *hash = xmlnode_get_attrib(caps,"hash");
-				
-				if(node && ver && hash) {
+				const char *ext = xmlnode_get_attrib(caps,"ext");
+
+				/* v1.3 uses: node, ver, and optionally ext.
+				 * v1.5 uses: node, ver, and hash. */
+				if (node && ver) {
 					JabberPresenceCapabilities *userdata = g_new0(JabberPresenceCapabilities, 1);
 					userdata->js = js;
 					userdata->jb = jb;
 					userdata->from = g_strdup(from);
-					jabber_caps_get_info(js, from, node, ver, hash,
+					jabber_caps_get_info(js, from, node, ver, hash, ext,
 					    (jabber_caps_get_info_cb)jabber_presence_set_capabilities,
 					    userdata);
 				}