From b26c961730cc87c3077549e6576c680c0a023dce Mon Sep 17 00:00:00 2001 From: James Booth Date: Sun, 14 Aug 2016 00:15:03 +0100 Subject: Move caps_create -> stanza_create_caps_from_query_element --- src/xmpp/stanza.c | 135 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) (limited to 'src/xmpp/stanza.c') diff --git a/src/xmpp/stanza.c b/src/xmpp/stanza.c index fa7d9e52..f883d8ed 100644 --- a/src/xmpp/stanza.c +++ b/src/xmpp/stanza.c @@ -1723,6 +1723,141 @@ stanza_parse_caps(xmpp_stanza_t *const stanza) return caps; } +EntityCapabilities* +stanza_create_caps_from_query_element(xmpp_stanza_t *query) +{ + char *software = NULL; + char *software_version = NULL; + char *os = NULL; + char *os_version = NULL; + + xmpp_stanza_t *softwareinfo = xmpp_stanza_get_child_by_ns(query, STANZA_NS_DATA); + if (softwareinfo) { + DataForm *form = form_create(softwareinfo); + FormField *formField = NULL; + + char *form_type = form_get_form_type_field(form); + if (g_strcmp0(form_type, STANZA_DATAFORM_SOFTWARE) == 0) { + GSList *field = form->fields; + while (field) { + formField = field->data; + if (formField->values) { + if (strcmp(formField->var, "software") == 0) { + software = strdup(formField->values->data); + } else if (strcmp(formField->var, "software_version") == 0) { + software_version = strdup(formField->values->data); + } else if (strcmp(formField->var, "os") == 0) { + os = strdup(formField->values->data); + } else if (strcmp(formField->var, "os_version") == 0) { + os_version = strdup(formField->values->data); + } + } + field = g_slist_next(field); + } + } + + form_destroy(form); + } + + xmpp_stanza_t *child = xmpp_stanza_get_children(query); + GSList *identity_stanzas = NULL; + GSList *features = NULL; + while (child) { + if (g_strcmp0(xmpp_stanza_get_name(child), "feature") == 0) { + features = g_slist_append(features, strdup(xmpp_stanza_get_attribute(child, "var"))); + } + if (g_strcmp0(xmpp_stanza_get_name(child), "identity") == 0) { + identity_stanzas = g_slist_append(identity_stanzas, child); + } + + child = xmpp_stanza_get_next(child); + } + + // find identity by locale + const gchar* const *langs = g_get_language_names(); + int num_langs = g_strv_length((gchar**)langs); + xmpp_stanza_t *found = NULL; + GSList *curr_identity = identity_stanzas; + while (curr_identity) { + xmpp_stanza_t *id_stanza = curr_identity->data; + const char *stanza_lang = xmpp_stanza_get_attribute(id_stanza, "xml:lang"); + if (stanza_lang) { + int i = 0; + for (i = 0; i < num_langs; i++) { + if (g_strcmp0(langs[i], stanza_lang) == 0) { + found = id_stanza; + break; + } + } + } + if (found) { + break; + } + curr_identity = g_slist_next(curr_identity); + } + + // not lang match, use default with no lang + if (!found) { + curr_identity = identity_stanzas; + while (curr_identity) { + xmpp_stanza_t *id_stanza = curr_identity->data; + const char *stanza_lang = xmpp_stanza_get_attribute(id_stanza, "xml:lang"); + if (!stanza_lang) { + found = id_stanza; + break; + } + + curr_identity = g_slist_next(curr_identity); + } + } + + // no matching lang, no identity without lang, use first + if (!found) { + if (identity_stanzas) { + found = identity_stanzas->data; + } + } + + g_slist_free(identity_stanzas); + + const char *category = NULL; + const char *type = NULL; + const char *name = NULL; + if (found) { + category = xmpp_stanza_get_attribute(found, "category"); + type = xmpp_stanza_get_attribute(found, "type"); + name = xmpp_stanza_get_attribute(found, "name"); + } + + EntityCapabilities *new_caps = malloc(sizeof(struct entity_capabilities_t)); + + if (category || type || name) { + DiscoIdentity *identity = malloc(sizeof(struct disco_identity_t)); + identity->category = category ? strdup(category) : NULL; + identity->type = type ? strdup(type) : NULL; + identity->name = name ? strdup(name) : NULL; + new_caps->identity = identity; + } else { + new_caps->identity = NULL; + } + + if (software || software_version || os || os_version) { + SoftwareVersion *software_versionp = malloc(sizeof(struct software_version_t)); + software_versionp->software = software; + software_versionp->software_version = software_version; + software_versionp->os = os; + software_versionp->os_version = os_version; + } + + if (features) { + new_caps->features = features; + } else { + new_caps->features = NULL; + } + + return new_caps; +} + char* stanza_get_error_message(xmpp_stanza_t *stanza) { -- cgit 1.4.1-2-gfad0