# HG changeset patch # User Tobias Markmann # Date 1214155523 0 # Node ID 2a6a37c7970be2f26fd667b7c3900f0330c20430 # Parent 26eabe8e739b94a2c64a9b76a996ff19da2bcc80 * changed name of jabber_caps_calculate_hash() to jabber_caps_calculate_own_hash() * added function which parses a query node to internal caps structure diff -r 26eabe8e739b -r 2a6a37c7970b libpurple/protocols/jabber/caps.c --- 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; } diff -r 26eabe8e739b -r 2a6a37c7970b libpurple/protocols/jabber/caps.h --- 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_ */ diff -r 26eabe8e739b -r 2a6a37c7970b libpurple/protocols/jabber/disco.c --- 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"); diff -r 26eabe8e739b -r 2a6a37c7970b libpurple/protocols/jabber/presence.c --- 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) {