From 4799ca04b4c41e2de223478727240180062c6dab Mon Sep 17 00:00:00 2001 From: Debarshi Ray Date: Fri, 25 Mar 2011 16:48:44 +0200 Subject: [PATCH] Handle ERROR messages A new MessageSpec was added for it. Fixes: https://bugs.freedesktop.org/35239 --- src/idle-connection.c | 33 +++++++++++++++++++++++++++++++++ src/idle-parser.c | 1 + src/idle-parser.h | 3 ++- 3 files changed, 36 insertions(+), 1 deletions(-) diff --git a/src/idle-connection.c b/src/idle-connection.c index d8fada9..8615a91 100644 --- a/src/idle-connection.c +++ b/src/idle-connection.c @@ -28,6 +28,7 @@ #define DBUS_API_SUBJECT_TO_CHANGE #include +#include #include #include #include @@ -190,6 +191,7 @@ static void _iface_disconnected(TpBaseConnection *self); static void _iface_shut_down(TpBaseConnection *self); static gboolean _iface_start_connecting(TpBaseConnection *self, GError **error); +static IdleParserHandlerResult _error_handler(IdleParser *parser, IdleParserMessageCode code, GValueArray *args, gpointer user_data); static IdleParserHandlerResult _erroneous_nickname_handler(IdleParser *parser, IdleParserMessageCode code, GValueArray *args, gpointer user_data); static IdleParserHandlerResult _nick_handler(IdleParser *parser, IdleParserMessageCode code, GValueArray *args, gpointer user_data); static IdleParserHandlerResult _nickname_in_use_handler(IdleParser *parser, IdleParserMessageCode code, GValueArray *args, gpointer user_data); @@ -636,6 +638,7 @@ static void _start_connecting_continue(IdleConnection *conn) { g_signal_connect(sconn, "received", (GCallback)(sconn_received_cb), conn); + idle_parser_add_handler(conn->parser, IDLE_PARSER_CMD_ERROR, _error_handler, conn); idle_parser_add_handler(conn->parser, IDLE_PARSER_NUMERIC_ERRONEOUSNICKNAME, _erroneous_nickname_handler, conn); idle_parser_add_handler(conn->parser, IDLE_PARSER_NUMERIC_NICKNAMEINUSE, _nickname_in_use_handler, conn); idle_parser_add_handler(conn->parser, IDLE_PARSER_NUMERIC_WELCOME, _welcome_handler, conn); @@ -851,6 +854,36 @@ idle_connection_get_max_message_length(IdleConnection *conn) return IRC_MSG_MAXLEN - 100; } +static IdleParserHandlerResult _error_handler(IdleParser *parser, IdleParserMessageCode code, GValueArray *args, gpointer user_data) { + IdleConnection *conn = IDLE_CONNECTION(user_data); + GHashTable *details = NULL; + TpConnectionStatus status = conn->parent.status; + TpConnectionStatusReason reason = (status == TP_CONNECTION_STATUS_CONNECTING) + ? TP_CONNECTION_STATUS_REASON_AUTHENTICATION_FAILED + : TP_CONNECTION_STATUS_REASON_NETWORK_ERROR; + const gchar *msg = g_value_get_string(g_value_array_get_nth(args, 0)); + const gchar *begin = strchr(msg, '('); + const gchar *end = strrchr(msg, ')'); + const gchar *error_name = (status == TP_CONNECTION_STATUS_CONNECTING) ? TP_ERROR_STR_AUTHENTICATION_FAILED : TP_ERROR_STR_NETWORK_ERROR; + gchar *server_msg = NULL; + guint length; + + if (begin != NULL && end != NULL && begin < end - 1) { + begin++; + end--; + length = end - begin + 1; + server_msg = g_new0(gchar, length + 1); + strncpy(server_msg, begin, length); + server_msg[length] = '\0'; + details = tp_asv_new ("server-message", G_TYPE_STRING, server_msg, NULL); + } + + tp_base_connection_disconnect_with_dbus_error(TP_BASE_CONNECTION(conn), error_name, details, reason); + g_free(server_msg); + + return IDLE_PARSER_HANDLER_RESULT_HANDLED; +} + static IdleParserHandlerResult _erroneous_nickname_handler(IdleParser *parser, IdleParserMessageCode code, GValueArray *args, gpointer user_data) { IdleConnection *conn = IDLE_CONNECTION(user_data); diff --git a/src/idle-parser.c b/src/idle-parser.c index 5fba70c..446d43f 100644 --- a/src/idle-parser.c +++ b/src/idle-parser.c @@ -72,6 +72,7 @@ struct _MessageSpec { * '.' - Same as ':', but optional */ static const MessageSpec message_specs[] = { + {"ERROR", "I:", IDLE_PARSER_CMD_ERROR}, {"PING", "Is", IDLE_PARSER_CMD_PING}, {"INVITE", "cIcr", IDLE_PARSER_PREFIXCMD_INVITE}, diff --git a/src/idle-parser.h b/src/idle-parser.h index 47e97b8..f5053cb 100644 --- a/src/idle-parser.h +++ b/src/idle-parser.h @@ -46,7 +46,8 @@ G_BEGIN_DECLS (G_TYPE_INSTANCE_GET_CLASS((obj), IDLE_TYPE_PARSER, IdleParserClass)) typedef enum { - IDLE_PARSER_CMD_PING = 0, + IDLE_PARSER_CMD_ERROR = 0, + IDLE_PARSER_CMD_PING, IDLE_PARSER_PREFIXCMD_INVITE, IDLE_PARSER_PREFIXCMD_JOIN, -- 1.7.4