diff libpurple/protocols/jabber/buddy.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/buddy.c	Wed Dec 17 04:33:00 2008 +0000
+++ b/libpurple/protocols/jabber/buddy.c	Fri Dec 19 04:11:07 2008 +0000
@@ -181,7 +181,11 @@
 		jbr->commands = g_list_delete_link(jbr->commands, jbr->commands);
 	}
 
-	jabber_caps_client_info_unref(jbr->caps);
+	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);
+	}
 	g_free(jbr->name);
 	g_free(jbr->status);
 	g_free(jbr->thread_id);
@@ -2509,14 +2513,27 @@
 jabber_resource_has_capability(const JabberBuddyResource *jbr, const gchar *cap)
 {
 	const GList *node = NULL;
+	const JabberCapsNodeExts *exts;
 
-	if (!jbr->caps) {
+	if (!jbr->caps.info) {
 		purple_debug_error("jabber",
 			"Unable to find caps: nothing known about buddy\n");
 		return FALSE;
 	}
 
-	node = g_list_find_custom(jbr->caps->features, cap, (GCompareFunc)strcmp);
+	node = g_list_find_custom(jbr->caps.info->features, cap, (GCompareFunc)strcmp);
+	if (!node && jbr->caps.exts && jbr->caps.info->exts) {
+		const GList *ext;
+		exts = jbr->caps.info->exts;
+		/* Walk through all the enabled caps, checking each list for the cap.
+		 * Don't check it twice, though. */
+		for (ext = jbr->caps.exts; ext && !node; ext = ext->next) {
+			GList *features = g_hash_table_lookup(exts->exts, ext->data);
+			if (features)
+				node = g_list_find_custom(features, cap, (GCompareFunc)strcmp);
+		}
+	}
+
 	/* TODO: Are these messages actually useful? */
 	if (node)
 		purple_debug_info("jabber", "Found cap: %s\n", cap);