gboolean caps_jid_has_feature(const char *const jid, const char *const feature) { EntityCapabilities *caps = caps_lookup(jid); if (caps == NULL) { return FALSE; } GSList *found = g_slist_find_custom(caps->features, feature, (GCompareFunc)g_strcmp0); gboolean result = found != NULL; caps_destroy(caps); return result; }
void win_show_occupant_info(ProfWin *window, const char *const room, Occupant *occupant) { const char *presence_str = string_from_resource_presence(occupant->presence); const char *occupant_affiliation = muc_occupant_affiliation_str(occupant); const char *occupant_role = muc_occupant_role_str(occupant); theme_item_t presence_colour = theme_main_presence_attrs(presence_str); win_print(window, '!', 0, NULL, NO_EOL, presence_colour, "", occupant->nick); win_vprint(window, '!', 0, NULL, NO_DATE | NO_EOL, presence_colour, "", " is %s", presence_str); if (occupant->status) { win_vprint(window, '!', 0, NULL, NO_DATE | NO_EOL, presence_colour, "", ", \"%s\"", occupant->status); } win_newline(window); if (occupant->jid) { win_vprint(window, '!', 0, NULL, 0, 0, "", " Jid: %s", occupant->jid); } win_vprint(window, '!', 0, NULL, 0, 0, "", " Affiliation: %s", occupant_affiliation); win_vprint(window, '!', 0, NULL, 0, 0, "", " Role: %s", occupant_role); Jid *jidp = jid_create_from_bare_and_resource(room, occupant->nick); EntityCapabilities *caps = caps_lookup(jidp->fulljid); jid_destroy(jidp); if (caps) { // show identity if (caps->identity) { DiscoIdentity *identity = caps->identity; win_print(window, '!', 0, NULL, NO_EOL, 0, "", " Identity: "); if (identity->name) { win_print(window, '!', 0, NULL, NO_DATE | NO_EOL, 0, "", identity->name); if (identity->category || identity->type) { win_print(window, '-', 0, NULL, NO_DATE | NO_EOL, 0, "", " "); } } if (identity->type) { win_print(window, '!', 0, NULL, NO_DATE | NO_EOL, 0, "", identity->type); if (identity->category) { win_print(window, '!', 0, NULL, NO_DATE | NO_EOL, 0, "", " "); } } if (identity->category) { win_print(window, '!', 0, NULL, NO_DATE | NO_EOL, 0, "", identity->category); } win_newline(window); } if (caps->software_version) { SoftwareVersion *software_version = caps->software_version; if (software_version->software) { win_vprint(window, '!', 0, NULL, NO_EOL, 0, "", " Software: %s", software_version->software); } if (software_version->software_version) { win_vprint(window, '!', 0, NULL, NO_DATE | NO_EOL, 0, "", ", %s", software_version->software_version); } if (software_version->software || software_version->software_version) { win_newline(window); } if (software_version->os) { win_vprint(window, '!', 0, NULL, NO_EOL, 0, "", " OS: %s", software_version->os); } if (software_version->os_version) { win_vprint(window, '!', 0, NULL, NO_DATE | NO_EOL, 0, "", ", %s", software_version->os_version); } if (software_version->os || software_version->os_version) { win_newline(window); } } caps_destroy(caps); } win_print(window, '-', 0, NULL, 0, 0, "", ""); }
void win_show_info(ProfWin *window, PContact contact) { const char *barejid = p_contact_barejid(contact); const char *name = p_contact_name(contact); const char *presence = p_contact_presence(contact); const char *sub = p_contact_subscription(contact); GDateTime *last_activity = p_contact_last_activity(contact); theme_item_t presence_colour = theme_main_presence_attrs(presence); win_print(window, '-', 0, NULL, 0, 0, "", ""); win_print(window, '-', 0, NULL, NO_EOL, presence_colour, "", barejid); if (name) { win_vprint(window, '-', 0, NULL, NO_DATE | NO_EOL, presence_colour, "", " (%s)", name); } win_print(window, '-', 0, NULL, NO_DATE, 0, "", ":"); if (sub) { win_vprint(window, '-', 0, NULL, 0, 0, "", "Subscription: %s", sub); } if (last_activity) { GDateTime *now = g_date_time_new_now_local(); GTimeSpan span = g_date_time_difference(now, last_activity); int hours = span / G_TIME_SPAN_HOUR; span = span - hours * G_TIME_SPAN_HOUR; int minutes = span / G_TIME_SPAN_MINUTE; span = span - minutes * G_TIME_SPAN_MINUTE; int seconds = span / G_TIME_SPAN_SECOND; if (hours > 0) { win_vprint(window, '-', 0, NULL, 0, 0, "", "Last activity: %dh%dm%ds", hours, minutes, seconds); } else { win_vprint(window, '-', 0, NULL, 0, 0, "", "Last activity: %dm%ds", minutes, seconds); } g_date_time_unref(now); } GList *resources = p_contact_get_available_resources(contact); GList *ordered_resources = NULL; if (resources) { win_print(window, '-', 0, NULL, 0, 0, "", "Resources:"); // sort in order of availability GList *curr = resources; while (curr) { Resource *resource = curr->data; ordered_resources = g_list_insert_sorted(ordered_resources, resource, (GCompareFunc)resource_compare_availability); curr = g_list_next(curr); } } g_list_free(resources); GList *curr = ordered_resources; while (curr) { Resource *resource = curr->data; const char *resource_presence = string_from_resource_presence(resource->presence); theme_item_t presence_colour = theme_main_presence_attrs(resource_presence); win_vprint(window, '-', 0, NULL, NO_EOL, presence_colour, "", " %s (%d), %s", resource->name, resource->priority, resource_presence); if (resource->status) { win_vprint(window, '-', 0, NULL, NO_DATE | NO_EOL, presence_colour, "", ", \"%s\"", resource->status); } win_newline(window); Jid *jidp = jid_create_from_bare_and_resource(barejid, resource->name); EntityCapabilities *caps = caps_lookup(jidp->fulljid); jid_destroy(jidp); if (caps) { // show identity if (caps->identity) { DiscoIdentity *identity = caps->identity; win_print(window, '-', 0, NULL, NO_EOL, 0, "", " Identity: "); if (identity->name) { win_print(window, '-', 0, NULL, NO_DATE | NO_EOL, 0, "", identity->name); if (identity->category || identity->type) { win_print(window, '-', 0, NULL, NO_DATE | NO_EOL, 0, "", " "); } } if (identity->type) { win_print(window, '-', 0, NULL, NO_DATE | NO_EOL, 0, "", identity->type); if (identity->category) { win_print(window, '-', 0, NULL, NO_DATE | NO_EOL, 0, "", " "); } } if (identity->category) { win_print(window, '-', 0, NULL, NO_DATE | NO_EOL, 0, "", identity->category); } win_newline(window); } if (caps->software_version) { SoftwareVersion *software_version = caps->software_version; if (software_version->software) { win_vprint(window, '-', 0, NULL, NO_EOL, 0, "", " Software: %s", software_version->software); } if (software_version->software_version) { win_vprint(window, '-', 0, NULL, NO_DATE | NO_EOL, 0, "", ", %s", software_version->software_version); } if (software_version->software || software_version->software_version) { win_newline(window); } if (software_version->os) { win_vprint(window, '-', 0, NULL, NO_EOL, 0, "", " OS: %s", software_version->os); } if (software_version->os_version) { win_vprint(window, '-', 0, NULL, NO_DATE | NO_EOL, 0, "", ", %s", software_version->os_version); } if (software_version->os || software_version->os_version) { win_newline(window); } } caps_destroy(caps); } curr = g_list_next(curr); } g_list_free(ordered_resources); }
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; }