static EntityCapabilities* _caps_by_ver(const char *const ver) { if (!g_key_file_has_group(cache, ver)) { return NULL; } char *category = g_key_file_get_string(cache, ver, "category", NULL); char *type = g_key_file_get_string(cache, ver, "type", NULL); char *name = g_key_file_get_string(cache, ver, "name", NULL); char *software = g_key_file_get_string(cache, ver, "software", NULL); char *software_version = g_key_file_get_string(cache, ver, "software_version", NULL); char *os = g_key_file_get_string(cache, ver, "os", NULL); char *os_version = g_key_file_get_string(cache, ver, "os_version", NULL); gsize features_len = 0; gchar **features_list = g_key_file_get_string_list(cache, ver, "features", &features_len, NULL); GSList *features = NULL; if (features_list && features_len > 0) { int i; for (i = 0; i < features_len; i++) { features = g_slist_append(features, features_list[i]); } } EntityCapabilities *result = caps_create( category, type, name, software, software_version, os, os_version, features); g_free(category); g_free(type); g_free(name); g_free(software); g_free(software_version); g_free(os); g_free(os_version); if (features_list) { g_strfreev(features_list); } g_slist_free(features); return result; }
static EntityCapabilities* _caps_copy(EntityCapabilities *caps) { if (!caps) { return NULL; } const char *const categoty = caps->identity ? caps->identity->category : NULL; const char *const type = caps->identity ? caps->identity->type : NULL; const char *const name = caps->identity ? caps->identity->name : NULL; const char *const software = caps->software_version ? caps->software_version->software : NULL; const char *const software_version = caps->software_version ? caps->software_version->software_version : NULL; const char *const os = caps->software_version ? caps->software_version->os : NULL; const char *const os_version = caps->software_version ? caps->software_version->os_version : NULL; return caps_create(categoty, type, name, software, software_version, os, os_version, caps->features); }
static int _caps_response_handler(xmpp_conn_t *const conn, xmpp_stanza_t * const stanza, void * const userdata) { const char *id = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_ID); xmpp_stanza_t *query = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY); if (id) { log_info("Capabilities response handler fired for id %s", id); } else { 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 *type = xmpp_stanza_get_type(stanza); // handle error responses if (g_strcmp0(type, STANZA_TYPE_ERROR) == 0) { char *error_message = stanza_get_error_message(stanza); log_warning("Error received for capabilities response from %s: ", from, error_message); free(error_message); return 0; } if (query == NULL) { log_warning("No query element found."); return 0; } char *node = xmpp_stanza_get_attribute(query, STANZA_ATTR_NODE); if (node == NULL) { log_warning("No node attribute found"); return 0; } // validate sha1 gchar **split = g_strsplit(node, "#", -1); char *given_sha1 = split[1]; char *generated_sha1 = caps_create_sha1_str(query); if (g_strcmp0(given_sha1, generated_sha1) != 0) { log_warning("Generated sha-1 does not match given:"); log_warning("Generated : %s", generated_sha1); log_warning("Given : %s", given_sha1); } else { log_info("Valid SHA-1 hash found: %s", given_sha1); if (caps_contains(given_sha1)) { log_info("Capabilties cached: %s", given_sha1); } else { log_info("Capabilities not cached: %s, storing", given_sha1); Capabilities *capabilities = caps_create(query); caps_add(given_sha1, capabilities); caps_destroy(capabilities); } caps_map(from, given_sha1); } g_free(generated_sha1); g_strfreev(split); return 0; }