From dd7a95dbd42242ad096168d0839c591cb4fad06c Mon Sep 17 00:00:00 2001 From: Debarshi Ray Date: Fri, 18 Mar 2011 04:02:29 +0200 Subject: [PATCH] Handle RPL_WHOISCHANNELS messages in response to RequestContactInfo Fixes: https://bugs.freedesktop.org/34796 --- src/idle-contact-info.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ src/idle-parser.c | 1 + src/idle-parser.h | 1 + 3 files changed, 48 insertions(+), 0 deletions(-) diff --git a/src/idle-contact-info.c b/src/idle-contact-info.c index afd3598..f259428 100644 --- a/src/idle-contact-info.c +++ b/src/idle-contact-info.c @@ -33,6 +33,7 @@ typedef struct _ContactInfoRequest ContactInfoRequest; struct _ContactInfoRequest { guint handle; const gchar *nick; + GSList *channels; gboolean is_away; GPtrArray *contact_info; DBusGMethodInvocation *context; @@ -123,6 +124,7 @@ static void _dequeue_request_contact_info(IdleConnection *conn) { if (request->contact_info != NULL) g_boxed_free(TP_ARRAY_TYPE_CONTACT_INFO_FIELD_LIST, request->contact_info); + g_slist_free_full(request->channels, g_free); g_free(request); if (g_queue_is_empty(conn->contact_info_requests)) @@ -138,6 +140,7 @@ static void _queue_request_contact_info(IdleConnection *conn, guint handle, cons request = g_new0(ContactInfoRequest, 1); request->handle = handle; request->nick = nick; + request->channels = NULL; request->is_away = FALSE; request->contact_info = NULL; request->context = context; @@ -215,7 +218,11 @@ static IdleParserHandlerResult _away_handler(IdleParser *parser, IdleParserMessa static IdleParserHandlerResult _end_of_whois_handler(IdleParser *parser, IdleParserMessageCode code, GValueArray *args, gpointer user_data) { IdleConnection *conn = IDLE_CONNECTION(user_data); ContactInfoRequest *request; + GSList *node; + const gchar **channel_values; const gchar *field_values[2] = {NULL, NULL}; + guint i; + guint length; if (!_is_valid_response(conn, args)) return IDLE_PARSER_HANDLER_RESULT_NOT_HANDLED; @@ -225,6 +232,19 @@ static IdleParserHandlerResult _end_of_whois_handler(IdleParser *parser, IdlePar if (request->contact_info == NULL) request->contact_info = dbus_g_type_specialized_construct(TP_ARRAY_TYPE_CONTACT_INFO_FIELD_LIST); + if (request->channels != NULL) { + request->channels = g_slist_reverse(request->channels); + length = g_slist_length(request->channels); + channel_values = g_new0(const gchar *, length + 1); + + for (node = request->channels, i = 0; node; node = g_slist_next(node), i++) + channel_values[i] = (const gchar *) node->data; + channel_values[i] = NULL; + + _insert_contact_field(request->contact_info, "x-irc-channels", NULL, channel_values); + g_free(channel_values); + } + if (request->is_away == FALSE) { field_values[0] = g_strdup_printf("%d", TP_CONNECTION_PRESENCE_TYPE_AVAILABLE); _insert_contact_field(request->contact_info, "x-presence-type", NULL, field_values); @@ -284,6 +304,31 @@ cleanup: return IDLE_PARSER_HANDLER_RESULT_NOT_HANDLED; } +static IdleParserHandlerResult _whois_channels_handler(IdleParser *parser, IdleParserMessageCode code, GValueArray *args, gpointer user_data) { + IdleConnection *conn = IDLE_CONNECTION(user_data); + ContactInfoRequest *request; + gchar **channelsv; + gchar *channels; + guint i; + + if (!_is_valid_response(conn, args)) + return IDLE_PARSER_HANDLER_RESULT_NOT_HANDLED; + + request = g_queue_peek_head(conn->contact_info_requests); + + channels = g_value_dup_string(g_value_array_get_nth(args, 1)); + g_strchomp(channels); + channelsv = g_strsplit(channels, " ", -1); + + for (i = 0; channelsv[i] != NULL; i++) + /* We will reverse the list later because there can be multiple RPL_WHOISCHANNELS. */ + request->channels = g_slist_prepend(request->channels, (gpointer) channelsv[i]); + + g_free(channelsv); + g_free(channels); + return IDLE_PARSER_HANDLER_RESULT_NOT_HANDLED; +} + static IdleParserHandlerResult _whois_idle_handler(IdleParser *parser, IdleParserMessageCode code, GValueArray *args, gpointer user_data) { IdleConnection *conn = IDLE_CONNECTION(user_data); ContactInfoRequest *request; @@ -364,6 +409,7 @@ void idle_contact_info_init (IdleConnection *conn) { conn->contact_info_requests = g_queue_new(); idle_parser_add_handler(conn->parser, IDLE_PARSER_NUMERIC_WHOISUSER, _whois_user_handler, conn); + idle_parser_add_handler(conn->parser, IDLE_PARSER_NUMERIC_WHOISCHANNELS, _whois_channels_handler, conn); idle_parser_add_handler(conn->parser, IDLE_PARSER_NUMERIC_AWAY, _away_handler, conn); idle_parser_add_handler(conn->parser, IDLE_PARSER_NUMERIC_WHOISIDLE, _whois_idle_handler, conn); idle_parser_add_handler(conn->parser, IDLE_PARSER_NUMERIC_ENDOFWHOIS, _end_of_whois_handler, conn); diff --git a/src/idle-parser.c b/src/idle-parser.c index f595553..8110757 100644 --- a/src/idle-parser.c +++ b/src/idle-parser.c @@ -108,6 +108,7 @@ static const MessageSpec message_specs[] = { {"333", "IIIrcd", IDLE_PARSER_NUMERIC_TOPIC_STAMP}, {"305", "III", IDLE_PARSER_NUMERIC_UNAWAY}, {"001", "IIc", IDLE_PARSER_NUMERIC_WELCOME}, + {"319", "IIIc.", IDLE_PARSER_NUMERIC_WHOISCHANNELS}, {"311", "IIIcssI:", IDLE_PARSER_NUMERIC_WHOISUSER}, {"317", "IIIcd", IDLE_PARSER_NUMERIC_WHOISIDLE}, diff --git a/src/idle-parser.h b/src/idle-parser.h index f586380..8aa3a78 100644 --- a/src/idle-parser.h +++ b/src/idle-parser.h @@ -82,6 +82,7 @@ typedef enum { IDLE_PARSER_NUMERIC_TOPIC_STAMP, IDLE_PARSER_NUMERIC_UNAWAY, IDLE_PARSER_NUMERIC_WELCOME, + IDLE_PARSER_NUMERIC_WHOISCHANNELS, IDLE_PARSER_NUMERIC_WHOISUSER, IDLE_PARSER_NUMERIC_WHOISIDLE, -- 1.7.4