diff options
author | Jonathon Jongsma <jonathon.jongsma@collabora.co.uk> | 2009-02-13 15:20:43 -0600 |
---|---|---|
committer | Jonathon Jongsma <jonathon.jongsma@collabora.co.uk> | 2009-02-13 15:20:43 -0600 |
commit | 5edc8f54cafe32ac1daf37a9c940ee81b2ce92f8 (patch) | |
tree | b79f831d58ac63a2bebfc09bd9b34950df96c373 | |
parent | c573b2b2cfffd13062dee546a150798ec4356cb3 (diff) |
Store our user host prefix to calculate max msg length
After logging in, query information about ourselves so that we know what prefix
string will be tacked onto the beginning of our messages by the server when they
are relayed on to other users. This will allow us to calculate our max message
length properly.
This patch also adds a new API method idle_connection_get_max_message_length()
that allows others to query this information without knowing anything about the
actual host / prefix string.
-rw-r--r-- | src/idle-connection.c | 46 | ||||
-rw-r--r-- | src/idle-connection.h | 1 | ||||
-rw-r--r-- | src/idle-parser.c | 1 | ||||
-rw-r--r-- | src/idle-parser.h | 1 |
4 files changed, 49 insertions, 0 deletions
diff --git a/src/idle-connection.c b/src/idle-connection.c index 6c2d645..b12aba4 100644 --- a/src/idle-connection.c +++ b/src/idle-connection.c @@ -141,6 +141,12 @@ struct _IdleConnectionPrivate { char *quit_message; gboolean use_ssl; + /* the string used by the a server as a prefix to any messages we send that + * it relays to other users. We need to know this so we can keep our sent + * messages short enough that they still fit in the 512-byte limit even with + * this prefix added */ + char *relay_prefix; + /* output message queue */ GQueue *msg_queue; @@ -176,6 +182,7 @@ static IdleParserHandlerResult _nickname_in_use_handler(IdleParser *parser, Idle static IdleParserHandlerResult _ping_handler(IdleParser *parser, IdleParserMessageCode code, GValueArray *args, gpointer user_data); static IdleParserHandlerResult _version_privmsg_handler(IdleParser *parser, IdleParserMessageCode code, GValueArray *args, gpointer user_data); static IdleParserHandlerResult _welcome_handler(IdleParser *parser, IdleParserMessageCode code, GValueArray *args, gpointer user_data); +static IdleParserHandlerResult _whois_user_handler(IdleParser *parser, IdleParserMessageCode code, GValueArray *args, gpointer user_data); static void sconn_status_changed_cb(IdleServerConnectionIface *sconn, IdleServerConnectionState state, IdleServerConnectionStateReason reason, IdleConnection *conn); static void sconn_received_cb(IdleServerConnectionIface *sconn, gchar *raw_msg, IdleConnection *conn); @@ -330,6 +337,7 @@ static void idle_connection_finalize (GObject *object) { g_free(priv->password); g_free(priv->realname); g_free(priv->charset); + g_free(priv->relay_prefix); g_free(priv->quit_message); while ((msg = g_queue_pop_head(priv->msg_queue)) != NULL) @@ -495,6 +503,7 @@ static gboolean _iface_start_connecting(TpBaseConnection *self, GError **error) 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); + idle_parser_add_handler(conn->parser, IDLE_PARSER_NUMERIC_WHOISUSER, _whois_user_handler, conn); idle_parser_add_handler(conn->parser, IDLE_PARSER_CMD_PING, _ping_handler, conn); @@ -688,6 +697,16 @@ void idle_connection_send(IdleConnection *conn, const gchar *msg) { return _send_with_priority(conn, msg, SERVER_CMD_NORMAL_PRIORITY); } +gsize +idle_connection_get_max_message_length(IdleConnection *conn) +{ + IdleConnectionPrivate *priv = IDLE_CONNECTION_GET_PRIVATE(conn); + if (priv->relay_prefix != NULL) { + return IRC_MSG_MAXLEN - (strlen(priv->relay_prefix) + 1); + } + return IRC_MSG_MAXLEN; +} + static IdleParserHandlerResult _erroneous_nickname_handler(IdleParser *parser, IdleParserMessageCode code, GValueArray *args, gpointer user_data) { IdleConnection *conn = IDLE_CONNECTION(user_data); @@ -764,6 +783,29 @@ static IdleParserHandlerResult _welcome_handler(IdleParser *parser, IdleParserMe return IDLE_PARSER_HANDLER_RESULT_HANDLED; } +static IdleParserHandlerResult +_whois_user_handler(IdleParser *parser, IdleParserMessageCode code, GValueArray *args, gpointer user_data) +{ + IdleConnection *conn = IDLE_CONNECTION(user_data); + IdleConnectionPrivate *priv = IDLE_CONNECTION_GET_PRIVATE(conn); + + /* message format: <nick> <user> <host> * :<real name> */ + TpHandle handle = g_value_get_uint(g_value_array_get_nth(args, 0)); + TpHandle self = tp_base_connection_get_self_handle(TP_BASE_CONNECTION(conn)); + if (handle == self) { + if (priv->relay_prefix != NULL) { + g_free(priv->relay_prefix); + } + const char* user = g_value_get_string(g_value_array_get_nth(args, 1)); + const char* host = g_value_get_string(g_value_array_get_nth(args, 2)); + priv->relay_prefix = g_strdup_printf("%s!%s@%s", priv->nickname, user, host); + IDLE_DEBUG("user host prefix = %s", priv->relay_prefix); + + return IDLE_PARSER_HANDLER_RESULT_HANDLED; + } + return IDLE_PARSER_HANDLER_RESULT_NOT_HANDLED; +} + static void irc_handshakes(IdleConnection *conn) { IdleConnectionPrivate *priv; gchar msg[IRC_MSG_MAXLEN + 1]; @@ -783,6 +825,10 @@ static void irc_handshakes(IdleConnection *conn) { g_snprintf(msg, IRC_MSG_MAXLEN + 1, "USER %s %u * :%s", priv->nickname, 8, priv->realname); idle_connection_send(conn, msg); + + /* gather some information about ourselves */ + g_snprintf(msg, IRC_MSG_MAXLEN + 1, "WHOIS %s", priv->nickname); + idle_connection_send(conn, msg); } static void send_quit_request(IdleConnection *conn) { diff --git a/src/idle-connection.h b/src/idle-connection.h index 718bdb1..9cd3eb0 100644 --- a/src/idle-connection.h +++ b/src/idle-connection.h @@ -62,6 +62,7 @@ GType idle_connection_get_type(void); void idle_connection_canon_nick_receive(IdleConnection *conn, TpHandle handle, const gchar *canon_nick); void idle_connection_emit_queued_aliases_changed(IdleConnection *conn); void idle_connection_send(IdleConnection *conn, const gchar *msg); +void idle_connection_get_max_message_length(IdleConnection *conn); G_END_DECLS diff --git a/src/idle-parser.c b/src/idle-parser.c index 5b5214b..dcc8e44 100644 --- a/src/idle-parser.c +++ b/src/idle-parser.c @@ -94,6 +94,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}, + {"311", "IIIcssI:", IDLE_PARSER_NUMERIC_WHOISUSER}, {"317", "IIIcd", IDLE_PARSER_NUMERIC_WHOISIDLE}, {NULL, NULL, IDLE_PARSER_LAST_MESSAGE_CODE} diff --git a/src/idle-parser.h b/src/idle-parser.h index 0f190c9..9385602 100644 --- a/src/idle-parser.h +++ b/src/idle-parser.h @@ -80,6 +80,7 @@ typedef enum { IDLE_PARSER_NUMERIC_TOPIC_STAMP, IDLE_PARSER_NUMERIC_UNAWAY, IDLE_PARSER_NUMERIC_WELCOME, + IDLE_PARSER_NUMERIC_WHOISUSER, IDLE_PARSER_NUMERIC_WHOISIDLE, IDLE_PARSER_LAST_MESSAGE_CODE |