From 714faeb2e6330a65de6eddbff48a12a6e6f00abc Mon Sep 17 00:00:00 2001 From: James Booth Date: Sun, 29 Mar 2015 00:55:33 +0000 Subject: [PATCH] Add callback data to room disco info response handler --- src/command/commands.c | 2 +- src/server_events.c | 9 +-- src/server_events.h | 2 +- src/xmpp/iq.c | 121 ++++++++++++++++++++++++++++++++--------- src/xmpp/xmpp.h | 2 +- tests/xmpp/stub_xmpp.c | 2 +- 6 files changed, 103 insertions(+), 35 deletions(-) diff --git a/src/command/commands.c b/src/command/commands.c index 86285a46..76da2a93 100644 --- a/src/command/commands.c +++ b/src/command/commands.c @@ -1867,7 +1867,7 @@ cmd_info(gchar **args, struct cmd_help_t help) } } else { ProfMucWin *mucwin = wins_get_current_muc(); - iq_room_info_request(mucwin->roomjid); + iq_room_info_request(mucwin->roomjid, TRUE); ui_show_room_info(mucwin); return TRUE; } diff --git a/src/server_events.c b/src/server_events.c index 882c308c..bab6cb13 100644 --- a/src/server_events.c +++ b/src/server_events.c @@ -162,10 +162,12 @@ handle_disco_info(const char *from, GSList *identities, GSList *features) } void -handle_room_disco_info(const char * const room, GSList *identities, GSList *features) +handle_room_disco_info(const char * const room, GSList *identities, GSList *features, gboolean display) { muc_set_features(room, features); - ui_show_room_disco_info(room, identities, features); + if (display) { + ui_show_room_disco_info(room, identities, features); + } } void @@ -699,8 +701,7 @@ handle_muc_self_online(const char * const room, const char * const nick, gboolea ui_room_join(room, TRUE); } - // TODO send disco info request to room - iq_room_info_request(room); + iq_room_info_request(room, FALSE); muc_invites_remove(room); muc_roster_set_complete(room); diff --git a/src/server_events.h b/src/server_events.h index 403c5bb5..b03e11be 100644 --- a/src/server_events.h +++ b/src/server_events.h @@ -58,7 +58,7 @@ void handle_room_message(const char * const room_jid, const char * const nick, const char * const message); void handle_room_join_error(const char * const room, const char * const err); void handle_room_info_error(const char * const room, const char * const error); -void handle_room_disco_info(const char * const room, GSList *identities, GSList *features); +void handle_room_disco_info(const char * const room, GSList *identities, GSList *features, gboolean display); void handle_room_affiliation_list_result_error(const char * const room, const char * const affiliation, const char * const error); void handle_room_affiliation_list(const char * const room, const char * const affiliation, GSList *jids); diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c index 573a50ef..2cbed0dd 100644 --- a/src/xmpp/iq.c +++ b/src/xmpp/iq.c @@ -58,11 +58,17 @@ #define HANDLE(ns, type, func) xmpp_handler_add(conn, func, ns, STANZA_NAME_IQ, type, ctx) +typedef struct p_room_info_data_t { + char *room; + gboolean display; +} ProfRoomInfoData; + static int _error_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata); static int _ping_get_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata); static int _version_get_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata); static int _disco_info_get_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata); static int _disco_info_response_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata); +static int _room_info_response_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata); static int _version_result_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata); static int _disco_items_result_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata); static int _disco_items_get_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata); @@ -178,14 +184,18 @@ iq_disco_info_request(gchar *jid) } void -iq_room_info_request(const char * const room) +iq_room_info_request(const char * const room, gboolean display_result) { xmpp_conn_t * const conn = connection_get_conn(); xmpp_ctx_t * const ctx = connection_get_ctx(); char *id = create_unique_id("room_disco_info"); xmpp_stanza_t *iq = stanza_create_disco_info_iq(ctx, id, room, NULL); - xmpp_id_handler_add(conn, _disco_info_response_handler, id, strdup(room)); + ProfRoomInfoData *cb_data = malloc(sizeof(ProfRoomInfoData)); + cb_data->room = strdup(room); + cb_data->display = display_result; + + xmpp_id_handler_add(conn, _room_info_response_handler, id, cb_data); free(id); @@ -1337,6 +1347,82 @@ _item_destroy(DiscoItem *item) } } +static int +_room_info_response_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, + void * const userdata) +{ + const char *type = xmpp_stanza_get_type(stanza); + ProfRoomInfoData *cb_data = (ProfRoomInfoData *)userdata; + log_info("Received diso#info response for room: %s", cb_data->room); + + // handle error responses + if (g_strcmp0(type, STANZA_TYPE_ERROR) == 0) { + if (cb_data->display) { + char *error_message = stanza_get_error_message(stanza); + handle_room_info_error(cb_data->room, error_message); + free(error_message); + } + free(cb_data->room); + free(cb_data); + return 0; + } + + xmpp_stanza_t *query = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY); + + if (query != NULL) { + xmpp_stanza_t *child = xmpp_stanza_get_children(query); + GSList *identities = NULL; + GSList *features = NULL; + while (child != NULL) { + const char *stanza_name = xmpp_stanza_get_name(child); + if (g_strcmp0(stanza_name, STANZA_NAME_FEATURE) == 0) { + const char *var = xmpp_stanza_get_attribute(child, STANZA_ATTR_VAR); + if (var != NULL) { + features = g_slist_append(features, strdup(var)); + } + } else if (g_strcmp0(stanza_name, STANZA_NAME_IDENTITY) == 0) { + const char *name = xmpp_stanza_get_attribute(child, STANZA_ATTR_NAME); + const char *type = xmpp_stanza_get_attribute(child, STANZA_ATTR_TYPE); + const char *category = xmpp_stanza_get_attribute(child, STANZA_ATTR_CATEGORY); + + if ((name != NULL) || (category != NULL) || (type != NULL)) { + DiscoIdentity *identity = malloc(sizeof(struct disco_identity_t)); + + if (name != NULL) { + identity->name = strdup(name); + } else { + identity->name = NULL; + } + if (category != NULL) { + identity->category = strdup(category); + } else { + identity->category = NULL; + } + if (type != NULL) { + identity->type = strdup(type); + } else { + identity->type = NULL; + } + + identities = g_slist_append(identities, identity); + } + } + + child = xmpp_stanza_get_next(child); + } + + handle_room_disco_info(cb_data->room, identities, features, cb_data->display); + + g_slist_free_full(features, free); + g_slist_free_full(identities, (GDestroyNotify)_identity_destroy); + } + + free(cb_data->room); + free(cb_data); + + return 0; +} + static int _disco_info_response_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) @@ -1344,28 +1430,16 @@ _disco_info_response_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const sta const char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); const char *type = xmpp_stanza_get_type(stanza); - char *room = NULL; - if (userdata) { - room = (char *) userdata; - log_info("Received diso#info response for room: %s", room); + if (from) { + log_info("Received diso#info response from: %s", from); } else { - room = NULL; - if (from) { - log_info("Received diso#info response from: %s", from); - } else { - log_info("Received diso#info response"); - } + log_info("Received diso#info response"); } // handle error responses if (g_strcmp0(type, STANZA_TYPE_ERROR) == 0) { char *error_message = stanza_get_error_message(stanza); - if (room) { - handle_room_info_error(room, error_message); - free(room); - } else { - handle_disco_info_error(from, error_message); - } + handle_disco_info_error(from, error_message); free(error_message); return 0; } @@ -1414,20 +1488,13 @@ _disco_info_response_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const sta child = xmpp_stanza_get_next(child); } - if (room) { - handle_room_disco_info(room, identities, features); - } else { - handle_disco_info(from, identities, features); - } + handle_disco_info(from, identities, features); g_slist_free_full(features, free); g_slist_free_full(identities, (GDestroyNotify)_identity_destroy); } - if (room) { - free(room); - } - return 1; + return 0; } static int diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h index af9e30cc..1dc0c131 100644 --- a/src/xmpp/xmpp.h +++ b/src/xmpp/xmpp.h @@ -192,7 +192,7 @@ void iq_send_caps_request_for_jid(const char * const to, const char * const id, const char * const node, const char * const ver); void iq_send_caps_request_legacy(const char * const to, const char * const id, const char * const node, const char * const ver); -void iq_room_info_request(const char * const room); +void iq_room_info_request(const char * const room, gboolean display_result); void iq_room_affiliation_list(const char * const room, char *affiliation); void iq_room_affiliation_set(const char * const room, const char * const jid, char *affiliation, const char * const reason); diff --git a/tests/xmpp/stub_xmpp.c b/tests/xmpp/stub_xmpp.c index 21c9862d..1e57f7a8 100644 --- a/tests/xmpp/stub_xmpp.c +++ b/tests/xmpp/stub_xmpp.c @@ -151,7 +151,7 @@ void iq_send_caps_request_for_jid(const char * const to, const char * const id, const char * const node, const char * const ver) {} void iq_send_caps_request_legacy(const char * const to, const char * const id, const char * const node, const char * const ver) {} -void iq_room_info_request(const char * const room) {} +void iq_room_info_request(const char * const room, gboolean display) {} void iq_room_affiliation_list(const char * const room, char *affiliation) {} void iq_room_affiliation_set(const char * const room, const char * const jid, char *affiliation, const char * const reason) {}