changeset 25576:2a6a37c7970b

* changed name of jabber_caps_calculate_hash() to jabber_caps_calculate_own_hash() * added function which parses a query node to internal caps structure
author Tobias Markmann <tfar@soc.pidgin.im>
date Sun, 22 Jun 2008 17:25:23 +0000
parents 26eabe8e739b
children f6272b156873
files libpurple/protocols/jabber/caps.c libpurple/protocols/jabber/caps.h libpurple/protocols/jabber/disco.c libpurple/protocols/jabber/presence.c
diffstat 4 files changed, 73 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/jabber/caps.c	Mon Jun 16 13:52:45 2008 +0000
+++ b/libpurple/protocols/jabber/caps.c	Sun Jun 22 17:25:23 2008 +0000
@@ -114,7 +114,7 @@
 void jabber_caps_init(void) {
 	capstable = g_hash_table_new_full(jabber_caps_hash, jabber_caps_compare, jabber_caps_destroy_key, jabber_caps_destroy_value);
 	jabber_caps_load();
-	jabber_caps_calculate_hash();
+	jabber_caps_calculate_own_hash();
 }
 
 static void jabber_caps_load(void) {
@@ -448,6 +448,7 @@
 	/* TODO: Better error checking! */
 
 	if (query) {
+		
 		JabberCapsValue *value = g_new0(JabberCapsValue, 1);
 		JabberCapsKey *key = g_new0(JabberCapsKey, 1);
 
@@ -512,12 +513,12 @@
 
 	key->node = (char *)node;
 	key->ver = (char *)ver;
-
+	
 	client = g_hash_table_lookup(capstable, key);
 
 	g_free(key);
 
-	if(!client) {
+//	if(!client) {
 		JabberIq *iq = jabber_iq_new_query(js,JABBER_IQ_GET,"http://jabber.org/protocol/disco#info");
 		xmlnode *query = xmlnode_get_child_with_namespace(iq->node,"query","http://jabber.org/protocol/disco#info");
 		char *nodever = g_strdup_printf("%s#%s", node, ver);
@@ -527,6 +528,7 @@
 
 		jabber_iq_set_callback(iq,jabber_caps_client_iqcb,userdata);
 		jabber_iq_send(iq);
+#if 0
 	} else {
 		GList *iter;
 		/* fetch unknown exts only */
@@ -560,6 +562,7 @@
 		/* maybe we have all data available anyways? This is the ideal case where no network traffic is necessary */
 		jabber_caps_get_info_check_completion(userdata);
 	}
+#endif
 }
 
 static gint jabber_caps_jabber_identity_compare(gconstpointer a, gconstpointer b) {
@@ -587,8 +590,50 @@
 	return strcmp(ac->namespace, bc->namespace);
 }
 
+JabberCapsClientInfo *jabber_caps_parse_client_info(xmlnode *query) {
+	xmlnode *child;
+	
+	if (!query) return 0;
+	if (strcmp(query->xmlns,"http://jabber.org/protocol/disco#info")) return 0;
+	
+	JabberCapsClientInfo *info = g_new0(JabberCapsClientInfo, 1);
+	
+	for(child = query->child; child; child = child->next) {
+		if (!strcmp(child->name,"identity")) {
+			/* parse identity */
+			const char *category = xmlnode_get_attrib(child, "category");
+			const char *type = xmlnode_get_attrib(child, "type");
+			const char *name = xmlnode_get_attrib(child, "name");
 
-void jabber_caps_calculate_hash() {
+			JabberCapsIdentity *id = g_new0(JabberCapsIdentity, 1);
+			id->category = g_strdup(category);
+			id->type = g_strdup(type);
+			id->name = g_strdup(name);
+			
+			info->identities = g_list_append(info->identities, id);
+		} else if (!strcmp(child->name, "feature")) {
+			/* parse feature */
+			const char *var = xmlnode_get_attrib(child, "var");
+			if(!var)
+				continue;
+			info->features = g_list_append(info->features, g_strdup(var));
+		} else if (!strcmp(child->name, "x")) {
+			if (!strcmp(child->xmlns, "jabber:x:data")) {
+				/* x-data form */
+				xmlnode *dataform = xmlnode_copy(child);
+				info->forms = g_list_append(info->forms, dataform);
+			}
+		}
+	}
+	return info;
+}
+
+gchar *jabber_caps_calcualte_hash(JabberCapsClientInfo *info) {
+	if (!info) return 0;
+	
+}
+
+void jabber_caps_calculate_own_hash() {
 	gchar *verification = 0;
 	gchar *free_verification;
 	gchar *identity_string, *feature_string;
@@ -650,7 +695,7 @@
 	caps_hash = verification;
 }
 
-const gchar* jabber_caps_get_hash() {
+const gchar* jabber_caps_get_own_hash() {
 	return caps_hash;
 }
 
--- a/libpurple/protocols/jabber/caps.h	Mon Jun 16 13:52:45 2008 +0000
+++ b/libpurple/protocols/jabber/caps.h	Sun Jun 22 17:25:23 2008 +0000
@@ -32,11 +32,13 @@
 	char *category;
 	char *type;
 	char *name;
+	char *lang;
 } JabberCapsIdentity;
 
 struct _JabberCapsClientInfo {
 	GList *identities; /* JabberCapsIdentity */
 	GList *features; /* char * */
+	GList *forms; /* xmlnode * */
 };
 
 typedef void (*jabber_caps_get_info_cb)(JabberCapsClientInfo *info, gpointer user_data);
@@ -46,12 +48,29 @@
 void jabber_caps_get_info(JabberStream *js, const char *who, const char *node, const char *ver, const char *ext, jabber_caps_get_info_cb cb, gpointer user_data);
 void jabber_caps_free_clientinfo(JabberCapsClientInfo *clientinfo);
 
+/**
+ *	Processes a query-node and returns a JabberCapsClientInfo object with all relevant info.
+ *	
+ *	@param 	query 	A query object.
+ *	@return 		A JabberCapsClientInfo object.
+ */
+JabberCapsClientInfo *jabber_caps_parse_client_info(xmlnode *query);
 
-void jabber_caps_calculate_hash();
+/**
+ *	Takes a JabberCapsClientInfo pointer and returns the caps hash according to
+ *	XEP-0115 Version 1.5.
+ *
+ *	@param info A JabberCapsClientInfo pointer.
+ *	@return		The base64 encoded SHA-1 hash; needs to be freed if not needed 
+ *				any furthermore. 
+ */
+gchar *jabber_caps_calcualte_hash(JabberCapsClientInfo *info);
+
+void jabber_caps_calculate_own_hash();
 
 /** Get the current caps hash.
  * 	@ret hash
 **/
-const gchar* jabber_caps_get_hash();
+const gchar* jabber_caps_get_own_hash();
 
 #endif /* _PURPLE_JABBER_CAPS_H_ */
--- a/libpurple/protocols/jabber/disco.c	Mon Jun 16 13:52:45 2008 +0000
+++ b/libpurple/protocols/jabber/disco.c	Sun Jun 22 17:25:23 2008 +0000
@@ -91,7 +91,7 @@
 		const char *node_uri = NULL;
 		
 		// create custom caps node URI
-		node_uri = g_strconcat(CAPS0115_NODE, "#", jabber_caps_get_hash(), NULL);
+		node_uri = g_strconcat(CAPS0115_NODE, "#", jabber_caps_get_own_hash(), NULL);
 
 		if((in_query = xmlnode_get_child(packet, "query"))) {
 			node = xmlnode_get_attrib(in_query, "node");
--- a/libpurple/protocols/jabber/presence.c	Mon Jun 16 13:52:45 2008 +0000
+++ b/libpurple/protocols/jabber/presence.c	Sun Jun 22 17:25:23 2008 +0000
@@ -265,7 +265,7 @@
 	xmlnode_set_namespace(c, "http://jabber.org/protocol/caps");
 	xmlnode_set_attrib(c, "node", CAPS0115_NODE);
 	xmlnode_set_attrib(c, "hash", "sha-1");
-	xmlnode_set_attrib(c, "ver", jabber_caps_get_hash());
+	xmlnode_set_attrib(c, "ver", jabber_caps_get_own_hash());
 
 #if 0
 	if(js != NULL) {