about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--src/ui/windows.c69
-rw-r--r--src/xmpp/capabilities.c49
-rw-r--r--src/xmpp/capabilities.h5
-rw-r--r--src/xmpp/iq.c54
-rw-r--r--src/xmpp/stanza.h2
-rw-r--r--src/xmpp/xmpp.h8
6 files changed, 149 insertions, 38 deletions
diff --git a/src/ui/windows.c b/src/ui/windows.c
index 88d34ad2..331e78eb 100644
--- a/src/ui/windows.c
+++ b/src/ui/windows.c
@@ -2427,28 +2427,26 @@ _win_show_info(WINDOW *win, PContact pcontact)
     wprintw(win, "\n");
     _win_show_time(win, '-');
     _presence_colour_on(win, presence);
-    wprintw(win, "%s:\n", jid);
-    _presence_colour_off(win, presence);
-
+    wprintw(win, "%s", jid);
     if (name != NULL) {
-        _win_show_time(win, '-');
-        wprintw(win, "Name          : %s\n", name);
-    }
-
-    if (sub != NULL) {
-        _win_show_time(win, '-');
-        wprintw(win, "Subscription  : %s\n", sub);
+        wprintw(win, " (%s)", name);
     }
+    wprintw(win, ":\n");
+    _presence_colour_off(win, presence);
 
     _win_show_time(win, '-');
     wprintw(win, "Presence      : ");
     _presence_colour_on(win, presence);
-    wprintw(win, "%s\n", presence);
+    wprintw(win, "%s", presence);
+    if (status != NULL) {
+        wprintw(win, ", \"%s\"", status);
+    }
+    wprintw(win, "\n");
     _presence_colour_off(win, presence);
 
-    if (status != NULL) {
+    if (sub != NULL) {
         _win_show_time(win, '-');
-        wprintw(win, "Message       : %s\n", status);
+        wprintw(win, "Subscription  : %s\n", sub);
     }
 
     if (last_activity != NULL) {
@@ -2478,9 +2476,48 @@ _win_show_info(WINDOW *win, PContact pcontact)
 
     if (caps_str != NULL) {
         Capabilities *caps = caps_get(caps_str);
-        if ((caps != NULL) && (caps->client != NULL)) {
-            _win_show_time(win, '-');
-            wprintw(win, "Client        : %s\n", caps->client);
+        if (caps != NULL) {
+            // show identity
+            if ((caps->category != NULL) || (caps->type != NULL) || (caps->name != NULL)) {
+                _win_show_time(win, '-');
+                wprintw(win, "Identity      : ");
+                if (caps->name != NULL) {
+                    wprintw(win, "%s", caps->name);
+                    if ((caps->category != NULL) || (caps->type != NULL)) {
+                        wprintw(win, " ");
+                    }
+                }
+                if (caps->type != NULL) {
+                    wprintw(win, "%s", caps->type);
+                    if (caps->category != NULL) {
+                        wprintw(win, " ");
+                    }
+                }
+                if (caps->category != NULL) {
+                    wprintw(win, "%s", caps->category);
+                }
+                wprintw(win, "\n");
+            }
+            if (caps->software != NULL) {
+                _win_show_time(win, '-');
+                wprintw(win, "Software      : %s", caps->software);
+            }
+            if (caps->software_version != NULL) {
+                wprintw(win, ", %s", caps->software_version);
+            }
+            if ((caps->software != NULL) || (caps->software_version != NULL)) {
+                wprintw(win, "\n");
+            }
+            if (caps->os != NULL) {
+                _win_show_time(win, '-');
+                wprintw(win, "OS            : %s", caps->os);
+            }
+            if (caps->os_version != NULL) {
+                wprintw(win, ", %s\n", caps->os_version);
+            }
+            if ((caps->os != NULL) || (caps->os_version != NULL)) {
+                wprintw(win, "\n");
+            }
         }
     }
 
diff --git a/src/xmpp/capabilities.c b/src/xmpp/capabilities.c
index 8ff5bf88..e8e45b97 100644
--- a/src/xmpp/capabilities.c
+++ b/src/xmpp/capabilities.c
@@ -45,14 +45,47 @@ caps_init(void)
 }
 
 void
-caps_add(const char * const caps_str, const char * const client)
+caps_add(const char * const caps_str, const char * const category,
+    const char * const type, const char * const name,
+    const char * const software, const char * const software_version,
+    const char * const os, const char * const os_version)
 {
     Capabilities *new_caps = malloc(sizeof(struct capabilities_t));
 
-    if (client != NULL) {
-        new_caps->client = strdup(client);
+    if (category != NULL) {
+        new_caps->category = strdup(category);
     } else {
-        new_caps->client = NULL;
+        new_caps->category = NULL;
+    }
+    if (type != NULL) {
+        new_caps->type = strdup(type);
+    } else {
+        new_caps->type = NULL;
+    }
+    if (name != NULL) {
+        new_caps->name = strdup(name);
+    } else {
+        new_caps->name = NULL;
+    }
+    if (software != NULL) {
+        new_caps->software = strdup(software);
+    } else {
+        new_caps->software = NULL;
+    }
+    if (software_version != NULL) {
+        new_caps->software_version = strdup(software_version);
+    } else {
+        new_caps->software_version = NULL;
+    }
+    if (os != NULL) {
+        new_caps->os = strdup(os);
+    } else {
+        new_caps->os = NULL;
+    }
+    if (os_version != NULL) {
+        new_caps->os_version = strdup(os_version);
+    } else {
+        new_caps->os_version = NULL;
     }
 
     g_hash_table_insert(capabilities, strdup(caps_str), new_caps);
@@ -244,7 +277,13 @@ static void
 _caps_destroy(Capabilities *caps)
 {
     if (caps != NULL) {
-        FREE_SET_NULL(caps->client);
+        FREE_SET_NULL(caps->category);
+        FREE_SET_NULL(caps->type);
+        FREE_SET_NULL(caps->name);
+        FREE_SET_NULL(caps->software);
+        FREE_SET_NULL(caps->software_version);
+        FREE_SET_NULL(caps->os);
+        FREE_SET_NULL(caps->os_version);
         FREE_SET_NULL(caps);
     }
 }
diff --git a/src/xmpp/capabilities.h b/src/xmpp/capabilities.h
index d4d3d524..f2729adc 100644
--- a/src/xmpp/capabilities.h
+++ b/src/xmpp/capabilities.h
@@ -28,7 +28,10 @@
 #include "xmpp/xmpp.h"
 
 void caps_init(void);
-void caps_add(const char * const caps_str, const char * const client);
+void caps_add(const char * const caps_str, const char * const category,
+    const char * const type, const char * const name,
+    const char * const software, const char * const software_version,
+    const char * const os, const char * const os_version);
 gboolean caps_contains(const char * const caps_str);
 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 51e3b615..7a5c2d24 100644
--- a/src/xmpp/iq.c
+++ b/src/xmpp/iq.c
@@ -315,28 +315,52 @@ _iq_handle_discoinfo_result(xmpp_conn_t * const conn, xmpp_stanza_t * const stan
             return 1;
         }
 
-        xmpp_stanza_t *identity = xmpp_stanza_get_child_by_name(query, "identity");
+        DataForm *form = NULL;
+        FormField *formField = NULL;
 
-        if (identity == NULL) {
-            return 1;
-        }
-
-        const char *category = xmpp_stanza_get_attribute(identity, "category");
-        if (category == NULL) {
-            return 1;
-        }
+        const char *category = NULL;
+        const char *type = NULL;
+        const char *name = NULL;
+        const char *software = NULL;
+        const char *software_version = NULL;
+        const char *os = NULL;
+        const char *os_version = NULL;
 
-        if (strcmp(category, "client") != 0) {
-            return 1;
+        xmpp_stanza_t *identity = xmpp_stanza_get_child_by_name(query, "identity");
+        if (identity != NULL) {
+            category = xmpp_stanza_get_attribute(identity, "category");
+            type = xmpp_stanza_get_attribute(identity, "type");
+            name = xmpp_stanza_get_attribute(identity, "name");
         }
 
-        const char *name = xmpp_stanza_get_attribute(identity, "name");
-        if (name == 0) {
-            return 1;
+        xmpp_stanza_t *softwareinfo = xmpp_stanza_get_child_by_ns(query, STANZA_NS_DATA);
+        if (softwareinfo != NULL) {
+            form = stanza_create_form(softwareinfo);
+
+            if (g_strcmp0(form->form_type, STANZA_DATAFORM_SOFTWARE) == 0) {
+                GSList *field = form->fields;
+                while (field != NULL) {
+                    formField = field->data;
+                    if (formField->values != NULL) {
+                        if (strcmp(formField->var, "software") == 0) {
+                            software = formField->values->data;
+                        } else if (strcmp(formField->var, "software_version") == 0) {
+                            software_version = formField->values->data;
+                        } else if (strcmp(formField->var, "os") == 0) {
+                            os = formField->values->data;
+                        } else if (strcmp(formField->var, "os_version") == 0) {
+                            os_version = formField->values->data;
+                        }
+                    }
+                    field = g_slist_next(field);
+                }
+            }
         }
 
-        caps_add(caps_key, name);
+        caps_add(caps_key, category, type, name, software, software_version,
+            os, os_version);
 
+        //stanza_destroy_form(form);
         free(caps_key);
 
         return 1;
diff --git a/src/xmpp/stanza.h b/src/xmpp/stanza.h
index 03bd9eec..1ae08ac7 100644
--- a/src/xmpp/stanza.h
+++ b/src/xmpp/stanza.h
@@ -94,6 +94,8 @@
 #define STANZA_NS_DATA "jabber:x:data"
 #define STANZA_NS_VERSION "jabber:iq:version"
 
+#define STANZA_DATAFORM_SOFTWARE "urn:xmpp:dataforms:softwareinfo"
+
 typedef struct form_field_t {
     char *var;
     GSList *values;
diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h
index f5783425..41367e75 100644
--- a/src/xmpp/xmpp.h
+++ b/src/xmpp/xmpp.h
@@ -47,7 +47,13 @@ typedef enum {
 } jabber_subscr_t;
 
 typedef struct capabilities_t {
-    char *client;
+    char *category;
+    char *type;
+    char *name;
+    char *software;
+    char *software_version;
+    char *os;
+    char *os_version;
 } Capabilities;
 
 // connection functions