about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorJames Booth <boothj5@gmail.com>2014-09-20 23:50:19 +0100
committerJames Booth <boothj5@gmail.com>2014-09-20 23:50:19 +0100
commit2fb998912380a8bb391bdb14b0106385acc5daf6 (patch)
tree64c0bd8a0d410187669ffa40272765eff93eb6b2
parent6e19476f6fe115ddcd96b69949f2d0576cdae254 (diff)
downloadprofani-tty-2fb998912380a8bb391bdb14b0106385acc5daf6.tar.gz
Added jid->hash lookup for capabilities
-rw-r--r--src/muc.c5
-rw-r--r--src/resource.c8
-rw-r--r--src/resource.h3
-rw-r--r--src/ui/console.c162
-rw-r--r--src/ui/ui.h2
-rw-r--r--src/ui/window.c72
-rw-r--r--src/xmpp/capabilities.c24
-rw-r--r--src/xmpp/capabilities.h1
-rw-r--r--src/xmpp/iq.c12
-rw-r--r--src/xmpp/presence.c29
-rw-r--r--src/xmpp/xmpp.h1
11 files changed, 169 insertions, 150 deletions
diff --git a/src/muc.c b/src/muc.c
index 3aef0220..3c937670 100644
--- a/src/muc.c
+++ b/src/muc.c
@@ -454,8 +454,7 @@ muc_nick_in_roster(const char * const room, const char * const nick)
  */
 gboolean
 muc_add_to_roster(const char * const room, const char * const nick,
-    const char * const show, const char * const status,
-    const char * const caps_str)
+    const char * const show, const char * const status)
 {
     ChatRoom *chat_room = g_hash_table_lookup(rooms, room);
     gboolean updated = FALSE;
@@ -472,7 +471,7 @@ muc_add_to_roster(const char * const room, const char * const nick,
         }
         PContact contact = p_contact_new(nick, NULL, NULL, NULL, NULL, FALSE);
         resource_presence_t resource_presence = resource_presence_from_string(show);
-        Resource *resource = resource_new(nick, resource_presence, status, 0, caps_str);
+        Resource *resource = resource_new(nick, resource_presence, status, 0);
         p_contact_set_presence(contact, resource);
         g_hash_table_replace(chat_room->roster, strdup(nick), contact);
     }
diff --git a/src/resource.c b/src/resource.c
index b0e1c48e..844cb1d3 100644
--- a/src/resource.c
+++ b/src/resource.c
@@ -40,7 +40,7 @@
 #include <resource.h>
 
 Resource * resource_new(const char * const name, resource_presence_t presence,
-    const char * const status, const int priority, const char * const caps_str)
+    const char * const status, const int priority)
 {
     assert(name != NULL);
     Resource *new_resource = malloc(sizeof(struct resource_t));
@@ -52,11 +52,6 @@ Resource * resource_new(const char * const name, resource_presence_t presence,
         new_resource->status = NULL;
     }
     new_resource->priority = priority;
-    if (caps_str != NULL) {
-        new_resource->caps_str = strdup(caps_str);
-    } else {
-        new_resource->caps_str = NULL;
-    }
 
     return new_resource;
 }
@@ -96,7 +91,6 @@ void resource_destroy(Resource *resource)
     if (resource != NULL) {
         free(resource->name);
         free(resource->status);
-        free(resource->caps_str);
         free(resource);
     }
 }
diff --git a/src/resource.h b/src/resource.h
index 342e1a2a..5c39d969 100644
--- a/src/resource.h
+++ b/src/resource.h
@@ -42,11 +42,10 @@ typedef struct resource_t {
     resource_presence_t presence;
     char *status;
     int priority;
-    char *caps_str;
 } Resource;
 
 Resource * resource_new(const char * const name, resource_presence_t presence,
-    const char * const status, const int priority, const char * const caps_str);
+    const char * const status, const int priority);
 void resource_destroy(Resource *resource);
 
 int resource_compare_availability(Resource *first, Resource *second);
diff --git a/src/ui/console.c b/src/ui/console.c
index 583900d9..1bf76aa9 100644
--- a/src/ui/console.c
+++ b/src/ui/console.c
@@ -282,65 +282,64 @@ _cons_show_info(PContact pcontact)
 }
 
 static void
-_cons_show_caps(const char * const contact, Resource *resource)
+_cons_show_caps(const char * const fulljid, Resource *resource)
 {
     ProfWin *console = wins_get_console();
     cons_show("");
     const char *resource_presence = string_from_resource_presence(resource->presence);
 
     int presence_colour = win_presence_colour(resource_presence);
-    win_save_vprint(console, '-', NULL, NO_EOL, presence_colour, "", "%s", contact);
+    win_save_vprint(console, '-', NULL, NO_EOL, presence_colour, "", "%s", fulljid);
     win_save_print(console, '-', NULL, NO_DATE, 0, "", ":");
 
-    if (resource->caps_str != NULL) {
-        Capabilities *caps = caps_get(resource->caps_str);
-        if (caps != NULL) {
-            // show identity
-            if ((caps->category != NULL) || (caps->type != NULL) || (caps->name != NULL)) {
-                win_save_print(console, '-', NULL, NO_EOL, 0, "", "Identity: ");
-                if (caps->name != NULL) {
-                    win_save_print(console, '-', NULL, NO_DATE | NO_EOL, 0, "", caps->name);
-                    if ((caps->category != NULL) || (caps->type != NULL)) {
-                        win_save_print(console, '-', NULL, NO_DATE | NO_EOL, 0, "", " ");
-                    }
-                }
-                if (caps->type != NULL) {
-                    win_save_print(console, '-', NULL, NO_DATE | NO_EOL, 0, "", caps->type);
-                    if (caps->category != NULL) {
-                        win_save_print(console, '-', NULL, NO_DATE | NO_EOL, 0, "", " ");
-                    }
+    Capabilities *caps = caps_lookup(fulljid);
+
+    if (caps) {
+        // show identity
+        if ((caps->category != NULL) || (caps->type != NULL) || (caps->name != NULL)) {
+            win_save_print(console, '-', NULL, NO_EOL, 0, "", "Identity: ");
+            if (caps->name != NULL) {
+                win_save_print(console, '-', NULL, NO_DATE | NO_EOL, 0, "", caps->name);
+                if ((caps->category != NULL) || (caps->type != NULL)) {
+                    win_save_print(console, '-', NULL, NO_DATE | NO_EOL, 0, "", " ");
                 }
+            }
+            if (caps->type != NULL) {
+                win_save_print(console, '-', NULL, NO_DATE | NO_EOL, 0, "", caps->type);
                 if (caps->category != NULL) {
-                    win_save_print(console, '-', NULL, NO_DATE | NO_EOL, 0, "", caps->category);
+                    win_save_print(console, '-', NULL, NO_DATE | NO_EOL, 0, "", " ");
                 }
-                win_save_newline(console);
-            }
-            if (caps->software != NULL) {
-                win_save_vprint(console, '-', NULL, NO_EOL, 0, "", "Software: %s", caps->software);
-            }
-            if (caps->software_version != NULL) {
-                win_save_vprint(console, '-', NULL, NO_DATE | NO_EOL, 0, "", ", %s", caps->software_version);
-            }
-            if ((caps->software != NULL) || (caps->software_version != NULL)) {
-                win_save_newline(console);
-            }
-            if (caps->os != NULL) {
-                win_save_vprint(console, '-', NULL, NO_EOL, 0, "", "OS: %s", caps->os);
             }
-            if (caps->os_version != NULL) {
-                win_save_vprint(console, '-', NULL, NO_DATE | NO_EOL, 0, "", ", %s", caps->os_version);
-            }
-            if ((caps->os != NULL) || (caps->os_version != NULL)) {
-                win_save_newline(console);
+            if (caps->category != NULL) {
+                win_save_print(console, '-', NULL, NO_DATE | NO_EOL, 0, "", caps->category);
             }
+            win_save_newline(console);
+        }
+        if (caps->software != NULL) {
+            win_save_vprint(console, '-', NULL, NO_EOL, 0, "", "Software: %s", caps->software);
+        }
+        if (caps->software_version != NULL) {
+            win_save_vprint(console, '-', NULL, NO_DATE | NO_EOL, 0, "", ", %s", caps->software_version);
+        }
+        if ((caps->software != NULL) || (caps->software_version != NULL)) {
+            win_save_newline(console);
+        }
+        if (caps->os != NULL) {
+            win_save_vprint(console, '-', NULL, NO_EOL, 0, "", "OS: %s", caps->os);
+        }
+        if (caps->os_version != NULL) {
+            win_save_vprint(console, '-', NULL, NO_DATE | NO_EOL, 0, "", ", %s", caps->os_version);
+        }
+        if ((caps->os != NULL) || (caps->os_version != NULL)) {
+            win_save_newline(console);
+        }
 
-            if (caps->features != NULL) {
-                win_save_println(console, "Features:");
-                GSList *feature = caps->features;
-                while (feature != NULL) {
-                    win_save_vprint(console, '-', NULL, 0, 0, "", " %s", feature->data);
-                    feature = g_slist_next(feature);
-                }
+        if (caps->features != NULL) {
+            win_save_println(console, "Features:");
+            GSList *feature = caps->features;
+            while (feature != NULL) {
+                win_save_vprint(console, '-', NULL, 0, 0, "", " %s", feature->data);
+                feature = g_slist_next(feature);
             }
         }
     }
@@ -733,48 +732,47 @@ _cons_show_account(ProfAccount *account)
                 win_save_vprint(console, '-', NULL, NO_DATE | NO_EOL, presence_colour, "", ", \"%s\"", resource->status);
             }
             win_save_vprint(console, '-', NULL, NO_DATE, 0, "", "");
-
-            if (resource->caps_str != NULL) {
-                Capabilities *caps = caps_get(resource->caps_str);
-                if (caps != NULL) {
-                    // show identity
-                    if ((caps->category != NULL) || (caps->type != NULL) || (caps->name != NULL)) {
-                        win_save_print(console, '-', NULL, NO_EOL, 0, "", "    Identity: ");
-                        if (caps->name != NULL) {
-                            win_save_print(console, '-', NULL, NO_DATE | NO_EOL, 0, "", caps->name);
-                            if ((caps->category != NULL) || (caps->type != NULL)) {
-                                win_save_print(console, '-', NULL, NO_DATE | NO_EOL, 0, "", " ");
-                            }
-                        }
-                        if (caps->type != NULL) {
-                            win_save_print(console, '-', NULL, NO_DATE | NO_EOL, 0, "", caps->type);
-                            if (caps->category != NULL) {
-                                win_save_print(console, '-', NULL, NO_DATE | NO_EOL, 0, "", " ");
-                            }
+            Jid *jidp = jid_create_from_bare_and_resource(account->jid, resource->name);
+            Capabilities *caps = caps_lookup(jidp->fulljid);
+
+            if (caps != NULL) {
+                // show identity
+                if ((caps->category != NULL) || (caps->type != NULL) || (caps->name != NULL)) {
+                    win_save_print(console, '-', NULL, NO_EOL, 0, "", "    Identity: ");
+                    if (caps->name != NULL) {
+                        win_save_print(console, '-', NULL, NO_DATE | NO_EOL, 0, "", caps->name);
+                        if ((caps->category != NULL) || (caps->type != NULL)) {
+                            win_save_print(console, '-', NULL, NO_DATE | NO_EOL, 0, "", " ");
                         }
+                    }
+                    if (caps->type != NULL) {
+                        win_save_print(console, '-', NULL, NO_DATE | NO_EOL, 0, "", caps->type);
                         if (caps->category != NULL) {
-                            win_save_print(console, '-', NULL, NO_DATE | NO_EOL, 0, "", caps->category);
+                            win_save_print(console, '-', NULL, NO_DATE | NO_EOL, 0, "", " ");
                         }
-                        win_save_newline(console);
-                    }
-                    if (caps->software != NULL) {
-                        win_save_vprint(console, '-', NULL, NO_EOL, 0, "", "    Software: %s", caps->software);
-                    }
-                    if (caps->software_version != NULL) {
-                        win_save_vprint(console, '-', NULL, NO_DATE | NO_EOL, 0, "", ", %s", caps->software_version);
-                    }
-                    if ((caps->software != NULL) || (caps->software_version != NULL)) {
-                        win_save_newline(console);
                     }
-                    if (caps->os != NULL) {
-                        win_save_vprint(console, '-', NULL, NO_EOL, 0, "", "    OS: %s", caps->os);
-                    }
-                    if (caps->os_version != NULL) {
-                        win_save_vprint(console, '-', NULL, NO_DATE | NO_EOL, 0, "", ", %s", caps->os_version);
-                    }
-                    if ((caps->os != NULL) || (caps->os_version != NULL)) {
-                        win_save_newline(console);
+                    if (caps->category != NULL) {
+                        win_save_print(console, '-', NULL, NO_DATE | NO_EOL, 0, "", caps->category);
                     }
+                    win_save_newline(console);
+                }
+                if (caps->software != NULL) {
+                    win_save_vprint(console, '-', NULL, NO_EOL, 0, "", "    Software: %s", caps->software);
+                }
+                if (caps->software_version != NULL) {
+                    win_save_vprint(console, '-', NULL, NO_DATE | NO_EOL, 0, "", ", %s", caps->software_version);
+                }
+                if ((caps->software != NULL) || (caps->software_version != NULL)) {
+                    win_save_newline(console);
+                }
+                if (caps->os != NULL) {
+                    win_save_vprint(console, '-', NULL, NO_EOL, 0, "", "    OS: %s", caps->os);
+                }
+                if (caps->os_version != NULL) {
+                    win_save_vprint(console, '-', NULL, NO_DATE | NO_EOL, 0, "", ", %s", caps->os_version);
+                }
+                if ((caps->os != NULL) || (caps->os_version != NULL)) {
+                    win_save_newline(console);
                 }
             }
 
diff --git a/src/ui/ui.h b/src/ui/ui.h
index 0d0bdc10..82327d03 100644
--- a/src/ui/ui.h
+++ b/src/ui/ui.h
@@ -234,7 +234,7 @@ void (*cons_show_roster_group)(const char * const group, GSList * list);
 void (*cons_show_wins)(void);
 void (*cons_show_status)(const char * const barejid);
 void (*cons_show_info)(PContact pcontact);
-void (*cons_show_caps)(const char * const contact, Resource *resource);
+void (*cons_show_caps)(const char * const fulljid, Resource *resource);
 void (*cons_show_themes)(GSList *themes);
 void (*cons_show_aliases)(GList *aliases);
 void (*cons_show_login_success)(ProfAccount *account);
diff --git a/src/ui/window.c b/src/ui/window.c
index 21591bae..fd21ae1a 100644
--- a/src/ui/window.c
+++ b/src/ui/window.c
@@ -235,47 +235,47 @@ win_show_info(ProfWin *window, PContact contact)
         }
         win_save_newline(window);
 
-        if (resource->caps_str != NULL) {
-            Capabilities *caps = caps_get(resource->caps_str);
-            if (caps != NULL) {
-                // show identity
-                if ((caps->category != NULL) || (caps->type != NULL) || (caps->name != NULL)) {
-                    win_save_print(window, '-', NULL, NO_EOL, 0, "", "    Identity: ");
-                    if (caps->name != NULL) {
-                        win_save_print(window, '-', NULL, NO_DATE | NO_EOL, 0, "", caps->name);
-                        if ((caps->category != NULL) || (caps->type != NULL)) {
-                            win_save_print(window, '-', NULL, NO_DATE | NO_EOL, 0, "", " ");
-                        }
-                    }
-                    if (caps->type != NULL) {
-                        win_save_print(window, '-', NULL, NO_DATE | NO_EOL, 0, "", caps->type);
-                        if (caps->category != NULL) {
-                            win_save_print(window, '-', NULL, NO_DATE | NO_EOL, 0, "", " ");
-                        }
+        Jid *jidp = jid_create_from_bare_and_resource(barejid, resource->name);
+        Capabilities *caps = caps_lookup(jidp->fulljid);
+
+        if (caps) {
+            // show identity
+            if ((caps->category != NULL) || (caps->type != NULL) || (caps->name != NULL)) {
+                win_save_print(window, '-', NULL, NO_EOL, 0, "", "    Identity: ");
+                if (caps->name != NULL) {
+                    win_save_print(window, '-', NULL, NO_DATE | NO_EOL, 0, "", caps->name);
+                    if ((caps->category != NULL) || (caps->type != NULL)) {
+                        win_save_print(window, '-', NULL, NO_DATE | NO_EOL, 0, "", " ");
                     }
+                }
+                if (caps->type != NULL) {
+                    win_save_print(window, '-', NULL, NO_DATE | NO_EOL, 0, "", caps->type);
                     if (caps->category != NULL) {
-                        win_save_print(window, '-', NULL, NO_DATE | NO_EOL, 0, "", caps->category);
+                        win_save_print(window, '-', NULL, NO_DATE | NO_EOL, 0, "", " ");
                     }
-                    win_save_newline(window);
-                }
-                if (caps->software != NULL) {
-                    win_save_vprint(window, '-', NULL, NO_EOL, 0, "", "    Software: %s", caps->software);
-                }
-                if (caps->software_version != NULL) {
-                    win_save_vprint(window, '-', NULL, NO_DATE | NO_EOL, 0, "", ", %s", caps->software_version);
-                }
-                if ((caps->software != NULL) || (caps->software_version != NULL)) {
-                    win_save_newline(window);
-                }
-                if (caps->os != NULL) {
-                    win_save_vprint(window, '-', NULL, NO_EOL, 0, "", "    OS: %s", caps->os);
-                }
-                if (caps->os_version != NULL) {
-                    win_save_vprint(window, '-', NULL, NO_DATE | NO_EOL, 0, "", ", %s", caps->os_version);
                 }
-                if ((caps->os != NULL) || (caps->os_version != NULL)) {
-                    win_save_newline(window);
+                if (caps->category != NULL) {
+                    win_save_print(window, '-', NULL, NO_DATE | NO_EOL, 0, "", caps->category);
                 }
+                win_save_newline(window);
+            }
+            if (caps->software != NULL) {
+                win_save_vprint(window, '-', NULL, NO_EOL, 0, "", "    Software: %s", caps->software);
+            }
+            if (caps->software_version != NULL) {
+                win_save_vprint(window, '-', NULL, NO_DATE | NO_EOL, 0, "", ", %s", caps->software_version);
+            }
+            if ((caps->software != NULL) || (caps->software_version != NULL)) {
+                win_save_newline(window);
+            }
+            if (caps->os != NULL) {
+                win_save_vprint(window, '-', NULL, NO_EOL, 0, "", "    OS: %s", caps->os);
+            }
+            if (caps->os_version != NULL) {
+                win_save_vprint(window, '-', NULL, NO_DATE | NO_EOL, 0, "", ", %s", caps->os_version);
+            }
+            if ((caps->os != NULL) || (caps->os_version != NULL)) {
+                win_save_newline(window);
             }
         }
 
diff --git a/src/xmpp/capabilities.c b/src/xmpp/capabilities.c
index 30f5aef8..5c93976d 100644
--- a/src/xmpp/capabilities.c
+++ b/src/xmpp/capabilities.c
@@ -50,6 +50,7 @@
 #include "xmpp/form.h"
 
 static GHashTable *capabilities;
+static GHashTable *jid_lookup;
 
 static void _caps_destroy(Capabilities *caps);
 
@@ -58,6 +59,7 @@ caps_init(void)
 {
     capabilities = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
         (GDestroyNotify)_caps_destroy);
+    jid_lookup = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
 }
 
 void
@@ -66,6 +68,12 @@ caps_add(const char * const ver, Capabilities *caps)
     g_hash_table_insert(capabilities, strdup(ver), caps);
 }
 
+void
+caps_map(const char * const jid, const char * const ver)
+{
+    g_hash_table_insert(jid_lookup, strdup(jid), strdup(ver));
+}
+
 gboolean
 caps_contains(const char * const caps_ver)
 {
@@ -78,6 +86,20 @@ _caps_get(const char * const caps_str)
     return g_hash_table_lookup(capabilities, caps_str);
 }
 
+static Capabilities *
+_caps_lookup(const char * const jid)
+{
+    char *ver = g_hash_table_lookup(jid_lookup, jid);
+    if (ver) {
+        Capabilities *caps = g_hash_table_lookup(capabilities, ver);
+        if (caps) {
+            return caps;
+        }
+    }
+
+    return NULL;
+}
+
 char *
 caps_create_sha1_str(xmpp_stanza_t * const query)
 {
@@ -365,6 +387,7 @@ static void
 _caps_close(void)
 {
     g_hash_table_destroy(capabilities);
+    g_hash_table_destroy(jid_lookup);
 }
 
 static void
@@ -389,5 +412,6 @@ void
 capabilities_init_module(void)
 {
     caps_get = _caps_get;
+    caps_lookup = _caps_lookup;
     caps_close = _caps_close;
 }
diff --git a/src/xmpp/capabilities.h b/src/xmpp/capabilities.h
index 71a1edb5..bb8b92af 100644
--- a/src/xmpp/capabilities.h
+++ b/src/xmpp/capabilities.h
@@ -41,6 +41,7 @@
 
 void caps_init(void);
 void caps_add(const char * const ver, Capabilities *caps);
+void caps_map(const char * const jid, const char * const ver);
 gboolean caps_contains(const char * const caps_ver);
 char* caps_create_sha1_str(xmpp_stanza_t * const query);
 xmpp_stanza_t* caps_create_query_response_stanza(xmpp_ctx_t * const ctx);
diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c
index 2a228d74..dc6e4cfd 100644
--- a/src/xmpp/iq.c
+++ b/src/xmpp/iq.c
@@ -348,6 +348,12 @@ _caps_response_handler(xmpp_conn_t *const conn, xmpp_stanza_t * const stanza,
         log_info("Capabilities response handler fired");
     }
 
+    const char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
+    if (!from) {
+        log_info("No from attribute");
+        return 0;
+    }
+
     char *node = xmpp_stanza_get_attribute(query, STANZA_ATTR_NODE);
     if (node == NULL) {
         log_warning("No node attribute found");
@@ -367,12 +373,14 @@ _caps_response_handler(xmpp_conn_t *const conn, xmpp_stanza_t * const stanza,
         log_info("Valid SHA-1 hash found: %s", given_sha1);
 
         if (caps_contains(given_sha1)) {
-            log_info("Capabilties cached");
+            log_info("Capabilties cached: %s", given_sha1);
         } else {
-            log_info("Capabilities not cached, storing");
+            log_info("Capabilities not cached: %s, storing", given_sha1);
             Capabilities *capabilities = caps_create(query);
             caps_add(given_sha1, capabilities);
         }
+
+        caps_map(from, given_sha1);
     }
 
     g_free(generated_sha1);
diff --git a/src/xmpp/presence.c b/src/xmpp/presence.c
index 2672b277..ff5e5982 100644
--- a/src/xmpp/presence.c
+++ b/src/xmpp/presence.c
@@ -592,19 +592,17 @@ _available_handler(xmpp_conn_t * const conn,
             log_info("Hash %s supported");
 
             char *ver = stanza_get_caps_ver(stanza);
-            if (caps_contains(ver)) {
-                log_info("Capabilities cached");
-            } else {
-                log_info("Capabilities not cached, sending service discovery request");
-                char *node = stanza_caps_get_node(stanza);
-                char *id = create_unique_id("caps");
-
-                iq_send_caps_request(from, id, node, ver);
+            if (ver) {
+                if (caps_contains(ver)) {
+                    log_info("Capabilities cached: %s", ver);
+                    caps_map(from, ver);
+                } else {
+                    log_info("Capabilities not cached: %s, sending service discovery request", ver);
+                    char *node = stanza_caps_get_node(stanza);
+                    char *id = create_unique_id("caps");
 
-                // send service discovery request
-                // with id handler to validate response,
-                // generate hash,
-                // if match, cache against hash
+                    iq_send_caps_request(from, id, node, ver);
+                }
             }
 
         // no hash, or not supported
@@ -619,17 +617,14 @@ _available_handler(xmpp_conn_t * const conn,
         }
     }
 
-    char *caps_key = strdup("hello");
-
     // create Resource
     Resource *resource = NULL;
     resource_presence_t presence = resource_presence_from_string(show_str);
     if (from_jid->resourcepart == NULL) { // hack for servers that do not send full jid
-        resource = resource_new("__prof_default", presence, status_str, priority, caps_key);
+        resource = resource_new("__prof_default", presence, status_str, priority);
     } else {
-        resource = resource_new(from_jid->resourcepart, presence, status_str, priority, caps_key);
+        resource = resource_new(from_jid->resourcepart, presence, status_str, priority);
     }
-    free(caps_key);
     free(status_str);
     free(show_str);
 
diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h
index c05a3b21..1d5a45a9 100644
--- a/src/xmpp/xmpp.h
+++ b/src/xmpp/xmpp.h
@@ -194,6 +194,7 @@ void (*iq_send_caps_request)(const char * const to, const char * const id,
 
 // caps functions
 Capabilities* (*caps_get)(const char * const caps_str);
+Capabilities* (*caps_lookup)(const char * const jid);
 void (*caps_close)(void);
 
 gboolean (*bookmark_add)(const char *jid, const char *nick, const char *password, const char *autojoin_str);