Mercurial > pidgin
changeset 32793:b4c2802af7f8
Print unknown IRC numerics to channels if we can associate them.
Basically, if they are of the form:
<routing> <numeric> <...> <channel> <more>
... then we print <numeric>: <more> to <channel>. Thanks to marienz
from Freenode for suggesting this.
Fixes #15090
author | Ethan Blanton <elb@pidgin.im> |
---|---|
date | Sun, 06 May 2012 14:45:01 +0000 |
parents | 670296a688dc |
children | a359399cc0ce |
files | ChangeLog libpurple/protocols/irc/msgs.c |
diffstat | 2 files changed, 72 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Sun May 06 06:05:11 2012 +0000 +++ b/ChangeLog Sun May 06 14:45:01 2012 +0000 @@ -5,6 +5,8 @@ * Disable periodic WHO timer. IRC channel user lists will no longer automatically display away status, but libpurple will be much kinder to the network. + * Print unknown numerics to channel windows if we can associate + them. Thanks to Marien Zwart. (#15090) version 2.10.3 (03/26/2012): MSN:
--- a/libpurple/protocols/irc/msgs.c Sun May 06 06:05:11 2012 +0000 +++ b/libpurple/protocols/irc/msgs.c Sun May 06 14:45:01 2012 +0000 @@ -112,9 +112,78 @@ irc->timer = purple_timeout_add_seconds(45, (GSourceFunc)irc_blist_timeout, (gpointer)irc); } +/* This function is ugly, but it's really an error handler. */ void irc_msg_default(struct irc_conn *irc, const char *name, const char *from, char **args) { - char *clean; + int i; + const char *end, *cur, *numeric = NULL; + char *clean, *tmp, *convname; + PurpleConversation *convo; + + for (cur = args[0], i = 0; i < 4; i++) { + end = strchr(cur, ' '); + if (end == NULL) { + goto undirected; + } + /* Check for 3-digit numeric in second position */ + if (i == 1) { + if (end - cur != 3 + || !isdigit(cur[0]) || !isdigit(cur[1]) + || !isdigit(cur[2])) { + goto undirected; + } + /* Save the numeric for printing to the channel */ + numeric = cur; + } + /* Don't advance cur if we're on the final iteration. */ + if (i != 3) { + cur = end + 1; + } + } + + /* At this point, cur is the beginning of the fourth position, + * end is the following space, and there are remaining + * arguments. We'll check to see if this argument is a + * currently active conversation (private message or channel, + * either one), and print the numeric to that conversation if it + * is. */ + + tmp = g_strndup(cur, end - cur); + convname = purple_utf8_salvage(tmp); + g_free(tmp); + + /* Check for an existing conversation */ + convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_ANY, + convname, + irc->account); + g_free(convname); + + if (convo == NULL) { + goto undirected; + } + + /* end + 1 is the first argument past the target. The initial + * arguments we've skipped are routing info, numeric, recipient + * (this account's nick, most likely), and target (this + * channel). If end + 1 is an ASCII :, skip it, because it's + * meaningless in this context. This won't catch all + * :-arguments, but it'll catch the easy case. */ + if (*++end == ':') { + end++; + } + + /* We then print "numeric: remainder". */ + clean = purple_utf8_salvage(end); + tmp = g_strdup_printf("%.3s: %s", numeric, clean); + g_free(clean); + purple_conversation_write(convo, "", tmp, + PURPLE_MESSAGE_SYSTEM|PURPLE_MESSAGE_NO_LOG + |PURPLE_MESSAGE_RAW|PURPLE_MESSAGE_NO_LINKIFY, + time(NULL)); + g_free(tmp); + return; + + undirected: /* This, too, should be escaped somehow (smarter) */ clean = purple_utf8_salvage(args[0]); purple_debug(PURPLE_DEBUG_INFO, "irc", "Unrecognized message: %s\n", clean);