--- xchat-2.4.4/src/common/proto-irc.c.multiline 2005-06-27 08:35:54.000000000 -0400 +++ xchat-2.4.4/src/common/proto-irc.c 2005-06-27 08:36:25.000000000 -0400 @@ -824,6 +824,10 @@ } if (!strcmp ("PRIVMSG", type)) { +#define M_QUOTE '\020' +#define X_DELIM '\001' +#define X_QUOTE '\134' + char *to = word[3]; int len; int id = FALSE; /* identified */ @@ -842,17 +846,59 @@ text++; } len = strlen (text); - if (text[0] == 1 && text[len - 1] == 1) /* ctcp */ - { - text[len - 1] = 0; - text++; - if (strncasecmp (text, "ACTION", 6) != 0) - flood_check (nick, ip, serv, sess, 0); - if (strncasecmp (text, "DCC ", 4) == 0) - /* redo this with handle_quotes TRUE */ - process_data_init (word[1], word_eol[1], word, word_eol, TRUE); - ctcp_handle (sess, to, nick, text, word, word_eol); - } else + + { /* find and dequote low-level CTCP quoting */ + char *ptr = text; + + while ((ptr = strchr(ptr, M_QUOTE)) != NULL) { + switch(*(ptr+1)) { + case 'r': + *(ptr+1) = '\r'; + break; + case 'n': + *(ptr+1) = '\n'; + break; + case '0': + *(ptr+1) = 0; + break; + } + memmove(ptr, ptr+1, strlen(ptr+1)+1); + ptr++; + } + } + + { /* find, handle, and remove CTCP messages */ + char *start, *end; + + while (((start = strchr(text, X_DELIM)) != NULL) && ((end = strchr(start+1, X_DELIM)) != NULL)) { + *end = 0; + + if (strncasecmp(start+1, "ACTION ", sizeof("ACTION ")-1) != 0) + flood_check(nick, ip, serv, sess, 0); + if (strncasecmp(text, "DCC ", sizeof("DCC ")-1) == 0) + /* redo this with handle_quotes TRUE */ + process_data_init (word[1], word_eol[1], word, word_eol, TRUE); + + { /* inline CTCP dequote */ + char *ptr = start+1; + + while ((ptr = strchr(ptr, X_QUOTE)) != NULL) { + switch(*(ptr+1)) { + case 'a': + *(ptr+1) = X_DELIM; + break; + } + memmove(ptr, ptr+1, strlen(ptr+1)+1); + ptr++; + } + } + + ctcp_handle(sess, to, nick, start+1, word, word_eol); + memmove(start, end+1, strlen(end+1)+1); + } + } + + if (*text != 0) { if (is_channel (serv, to)) { --- xchat-2.4.4/src/common/ctcp.c.multiline 2005-06-27 08:35:44.000000000 -0400 +++ xchat-2.4.4/src/common/ctcp.c 2005-06-27 08:39:15.000000000 -0400 @@ -58,13 +58,15 @@ struct popup *pop; GSList *list = ctcp_list; - po = strchr (ctcp, '\001'); - if (po) - *po = 0; - - po = strchr (word_eol[5], '\001'); - if (po) - *po = 0; +// handled by PRIVMSG handler +// po = strchr (ctcp, '\001'); +// if (po) +// *po = 0; + +// this appears to be superfluous, but I am not sure; leaving it uncommented causes breakage +// po = strchr (word_eol[5], '\001'); +// if (po) +// *po = 0; while (list) { @@ -129,7 +131,7 @@ if (!strcasecmp (msg, "VERSION") && !prefs.hidever) { - snprintf (outbuf, sizeof (outbuf), "VERSION xchat "VERSION" %s", + snprintf (outbuf, sizeof (outbuf), "VERSION xchat:"VERSION":%s", get_cpu_str ()); serv->p_nctcp (serv, nick, outbuf); } @@ -138,9 +140,10 @@ { if (!strncasecmp (msg, "SOUND", 5)) { - po = strchr (word[5], '\001'); - if (po) - po[0] = 0; +// handled by PRIVMSG handler +// po = strchr (word[5], '\001'); +// if (po) +// po[0] = 0; if (is_channel (sess->server, to)) { @@ -168,9 +171,10 @@ } generic: - po = strchr (msg, '\001'); - if (po) - po[0] = 0; +// handled by PRIVMSG handler +// po = strchr (msg, '\001'); +// if (po) +// po[0] = 0; if (!is_channel (sess->server, to)) {