From 5e5590b04774ff5c3d53ede62ddac677383f7692 Mon Sep 17 00:00:00 2001 From: James Booth Date: Tue, 5 Feb 2013 23:06:30 +0000 Subject: [PATCH] Show detailed software/os information if available in capabilities --- src/ui/windows.c | 69 +++++++++++++++++++++++++++++++---------- src/xmpp/capabilities.c | 49 ++++++++++++++++++++++++++--- src/xmpp/capabilities.h | 5 ++- src/xmpp/iq.c | 56 +++++++++++++++++++++++---------- src/xmpp/stanza.h | 2 ++ src/xmpp/xmpp.h | 8 ++++- 6 files changed, 150 insertions(+), 39 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; } + DataForm *form = NULL; + FormField *formField = NULL; + + 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; + xmpp_stanza_t *identity = xmpp_stanza_get_child_by_name(query, "identity"); - - if (identity == NULL) { - return 1; + 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 *category = xmpp_stanza_get_attribute(identity, "category"); - if (category == NULL) { - 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); + } + } } - if (strcmp(category, "client") != 0) { - return 1; - } - - const char *name = xmpp_stanza_get_attribute(identity, "name"); - if (name == 0) { - return 1; - } - - 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