diff --git a/src/command/commands.c b/src/command/commands.c index 3c120a6a..f9d5c343 100644 --- a/src/command/commands.c +++ b/src/command/commands.c @@ -2081,6 +2081,7 @@ cmd_room(gchar **args, struct cmd_help_t help) } if (g_strcmp0(args[0], "info") == 0) { + iq_room_info_request(room); ui_show_room_info(window, room); return TRUE; } diff --git a/src/server_events.c b/src/server_events.c index 6d4d9031..613e6618 100644 --- a/src/server_events.c +++ b/src/server_events.c @@ -154,6 +154,12 @@ handle_disco_info(const char *from, GSList *identities, GSList *features) cons_show_disco_info(from, identities, features); } +void +handle_room_disco_info(const char * const room, GSList *identities, GSList *features) +{ + ui_show_room_disco_info(room, identities, features); +} + void handle_disco_info_error(const char * const from, const char * const error) { @@ -164,6 +170,12 @@ handle_disco_info_error(const char * const from, const char * const error) } } +void +handle_room_info_error(const char * const room, const char * const error) +{ + ui_handle_room_info_error(room, error); +} + void handle_room_list(GSList *rooms, const char *conference_node) { diff --git a/src/server_events.h b/src/server_events.h index 952c3397..188a6558 100644 --- a/src/server_events.h +++ b/src/server_events.h @@ -57,6 +57,8 @@ void handle_room_history(const char * const room_jid, const char * const nick, 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_duck_result(const char * const result); void handle_incoming_message(char *from, char *message, gboolean priv); void handle_delayed_message(char *from, char *message, GTimeVal tv_stamp, diff --git a/src/ui/core.c b/src/ui/core.c index 1d106d6b..c07118af 100644 --- a/src/ui/core.c +++ b/src/ui/core.c @@ -1382,6 +1382,56 @@ _ui_room_join(const char * const room, gboolean focus) } } +static void +_ui_handle_room_info_error(const char * const room, const char * const error) +{ + ProfWin *window = wins_get_by_recipient(room); + if (window) { + win_save_vprint(window, '!', NULL, 0, 0, "", "Room info request failed: %s", error); + win_save_print(window, '-', NULL, 0, 0, "", ""); + } +} + +static void +_ui_show_room_disco_info(const char * const room, GSList *identities, GSList *features) +{ + ProfWin *window = wins_get_by_recipient(room); + if (window) { + if (((identities != NULL) && (g_slist_length(identities) > 0)) || + ((features != NULL) && (g_slist_length(features) > 0))) { + if (identities != NULL) { + win_save_print(window, '!', NULL, 0, 0, "", " Identities:"); + } + while (identities != NULL) { + DiscoIdentity *identity = identities->data; // anme trpe, cat + GString *identity_str = g_string_new(" "); + if (identity->name != NULL) { + identity_str = g_string_append(identity_str, identity->name); + identity_str = g_string_append(identity_str, " "); + } + if (identity->type != NULL) { + identity_str = g_string_append(identity_str, identity->type); + identity_str = g_string_append(identity_str, " "); + } + if (identity->category != NULL) { + identity_str = g_string_append(identity_str, identity->category); + } + win_save_print(window, '!', NULL, 0, 0, "", identity_str->str); + g_string_free(identity_str, FALSE); + identities = g_slist_next(identities); + } + + if (features != NULL) { + win_save_print(window, '!', NULL, 0, 0, "", " Features:"); + } + while (features != NULL) { + win_save_vprint(window, '!', NULL, 0, 0, "", " %s", features->data); + features = g_slist_next(features); + } + } + } +} + static void _ui_room_roster(const char * const room, GList *roster, const char * const presence) { @@ -2645,4 +2695,6 @@ ui_init_module(void) ui_show_room_info = _ui_show_room_info; ui_show_room_role_list = _ui_show_room_role_list; ui_show_room_affiliation_list = _ui_show_room_affiliation_list; + ui_handle_room_info_error = _ui_handle_room_info_error; + ui_show_room_disco_info = _ui_show_room_disco_info; } diff --git a/src/ui/ui.h b/src/ui/ui.h index 9955b7f9..53f684a2 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -140,6 +140,8 @@ void (*ui_room_destroyed)(const char * const room_jid); void (*ui_show_room_info)(ProfWin *window, const char * const room); void (*ui_show_room_role_list)(ProfWin *window, const char * const room, muc_role_t role); void (*ui_show_room_affiliation_list)(ProfWin *window, const char * const room, muc_affiliation_t affiliation); +void (*ui_handle_room_info_error)(const char * const room, const char * const error); +void (*ui_show_room_disco_info)(const char * const room, GSList *identities, GSList *features); void (*ui_room_broadcast)(const char * const room_jid, const char * const message); diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c index 10355332..83da7c9b 100644 --- a/src/xmpp/iq.c +++ b/src/xmpp/iq.c @@ -152,6 +152,20 @@ _iq_disco_info_request(gchar *jid) xmpp_stanza_release(iq); } +static void +_iq_room_info_request(gchar *room) +{ + 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, room); + + xmpp_send(conn, iq); + xmpp_stanza_release(iq); +} + static void _iq_send_caps_request(const char * const to, const char * const id, const char * const node, const char * const ver) @@ -814,15 +828,30 @@ static int _disco_info_response_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { - log_info("Received diso#info response"); - 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); + } else { + room = NULL; + if (from) { + log_info("Received diso#info response from: %s", from); + } else { + 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); - handle_disco_info_error(from, error_message); + if (room) { + handle_room_info_error(room, error_message); + } else { + handle_disco_info_error(from, error_message); + } free(error_message); return 0; } @@ -871,7 +900,12 @@ _disco_info_response_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const sta child = xmpp_stanza_get_next(child); } - handle_disco_info(from, identities, features); + if (room) { + handle_room_disco_info(room, identities, features); + } else { + handle_disco_info(from, identities, features); + } + g_slist_free_full(features, free); g_slist_free_full(identities, (GDestroyNotify)_identity_destroy); } @@ -942,4 +976,5 @@ iq_init_module(void) iq_room_config_cancel = _iq_room_config_cancel; iq_submit_room_config = _iq_submit_room_config; iq_send_caps_request = _iq_send_caps_request; + iq_room_info_request = _iq_room_info_request; } diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h index b1dcb627..58539479 100644 --- a/src/xmpp/xmpp.h +++ b/src/xmpp/xmpp.h @@ -191,6 +191,7 @@ void (*iq_room_config_cancel)(const char * const room_jid); void (*iq_send_ping)(const char * const target); void (*iq_send_caps_request)(const char * const to, const char * const id, const char * const node, const char * const ver); +void (*iq_room_info_request)(gchar *room); // caps functions Capabilities* (*caps_lookup)(const char * const jid);