From 3da7a891304852d62fe83dc329904a90aec04e96 Mon Sep 17 00:00:00 2001 From: Berke Viktor Date: Sat, 3 Nov 2012 18:29:08 +0100 Subject: [PATCH] More robust CAP management and CAP multi-prefix support --- src/common/proto-irc.c | 45 +++++++++++++++++++++++++++++++++------------ src/common/server.c | 1 + src/common/text.c | 4 ++-- src/common/textevents.in | 4 ++-- 4 files changed, 38 insertions(+), 16 deletions(-) diff --git a/src/common/proto-irc.c b/src/common/proto-irc.c index dac43d6..9b8fd1a 100644 --- a/src/common/proto-irc.c +++ b/src/common/proto-irc.c @@ -1016,7 +1016,10 @@ process_named_msg (session *sess, char *type, char *word[], char *word_eol[]) else if(len == 3) { guint32 t; - char *pass; + guint32 want_cap; /* format the CAP REQ string based on previous capabilities being requested or not */ + guint32 want_sasl; /* CAP END shouldn't be sent when SASL is requested, it needs further responses */ + char *pass; /* buffer for SASL password */ + char buffer[256]; /* buffer for requesting capabilities and emitting the signal */ t = WORDL((guint8)type[0], (guint8)type[1], (guint8)type[2], (guint8)type[3]); switch (t) @@ -1024,14 +1027,19 @@ process_named_msg (session *sess, char *type, char *word[], char *word_eol[]) case WORDL('C','A','P','\0'): if (strncasecmp (word[4], "ACK", 3) == 0) { - /* should acknowledge only one at a time, but just make sure we don't miss anything, use word_eol */ - EMIT_SIGNAL (XP_TE_CAPACK, sess->server->server_session, word[1], ++word_eol[5], NULL, NULL, 0); + EMIT_SIGNAL (XP_TE_CAPACK, sess->server->server_session, word[1], word[5][0]==':' ? ++word_eol[5] : word_eol[5], NULL, NULL, 0); - if (strncasecmp (word[5][0]==':' ? word[5] + 1 : word[5], "identify-msg", 12) == 0) + if (strstr (word_eol[5], "identify-msg") != 0) { serv->have_idmsg = TRUE; } - if (strncasecmp (word[5][0]==':' ? word[5] + 1 : word[5], "sasl", 12) == 0) + + if (strstr (word_eol[5], "multi-prefix") != 0) + { + serv->have_namesx = TRUE; + } + + if (strstr (word_eol[5], "sasl") != 0) { serv->have_sasl = TRUE; EMIT_SIGNAL (XP_TE_SASLAUTH, serv->server_session, sess->server->sasluser, NULL, NULL, NULL, 0); @@ -1044,21 +1052,34 @@ process_named_msg (session *sess, char *type, char *word[], char *word_eol[]) } else if (strncasecmp (word[4], "LS", 2) == 0) { - EMIT_SIGNAL (XP_TE_CAPLIST, serv->server_session, word[1], ++word_eol[5], NULL, NULL, 0); + EMIT_SIGNAL (XP_TE_CAPLIST, serv->server_session, word[1], word[5][0]==':' ? ++word_eol[5] : word_eol[5], NULL, NULL, 0); + want_cap = 0; + want_sasl = 0; if (strstr (word_eol[5], "identify-msg") != 0) { - EMIT_SIGNAL (XP_TE_CAPREQ, sess->server->server_session, "identify-msg", NULL, NULL, NULL, 0); - tcp_send_len (serv, "CAP REQ :identify-msg\r\n", 23); + strcpy (buffer, "CAP REQ :identify-msg"); + want_cap = 1; + } + if (strstr (word_eol[5], "multi-prefix") != 0) + { + want_cap ? strcat (buffer, " multi-prefix") : strcpy (buffer, "CAP REQ :multi-prefix"); + want_cap = 1; } - /* if the SASL password is set, request SASL auth */ if (strstr (word_eol[5], "sasl") != 0 && strlen (sess->server->saslpassword) != 0) { - EMIT_SIGNAL (XP_TE_CAPREQ, sess->server->server_session, "sasl", NULL, NULL, NULL, 0); - tcp_send_len (serv, "CAP REQ :sasl\r\n", 23); + want_cap ? strcat (buffer, " sasl") : strcpy (buffer, "CAP REQ :sasl"); + want_sasl = 1; } - else + + if (want_cap) + { + /* buffer + 9 = emit buffer without "CAP REQ :" */ + EMIT_SIGNAL (XP_TE_CAPREQ, sess->server->server_session, buffer + 9, NULL, NULL, NULL, 0); + tcp_sendf (serv, "%s\r\n", buffer); + } + if (!want_sasl) { /* if we use SASL, CAP END is dealt via raw numerics */ tcp_send_len (serv, "CAP END\r\n", 9); diff --git a/src/common/server.c b/src/common/server.c index 5d3c2d3..9d427b2 100644 --- a/src/common/server.c +++ b/src/common/server.c @@ -1808,6 +1808,7 @@ server_set_defaults (server *serv) serv->have_whox = FALSE; serv->have_capab = FALSE; serv->have_idmsg = FALSE; + serv->have_sasl = FALSE; serv->have_except = FALSE; } diff --git a/src/common/text.c b/src/common/text.c index c862cbf..c80a513 100644 --- a/src/common/text.c +++ b/src/common/text.c @@ -960,7 +960,7 @@ static char * const pevt_privmsg_help[] = { static char * const pevt_capack_help[] = { N_("Server Name"), - N_("Acknowledged Capability") + N_("Acknowledged Capabilities") }; static char * const pevt_caplist_help[] = { @@ -969,7 +969,7 @@ static char * const pevt_caplist_help[] = { }; static char * const pevt_capreq_help[] = { - N_("Requested Capability") + N_("Requested Capabilities") }; static char * const pevt_changenick_help[] = { diff --git a/src/common/textevents.in b/src/common/textevents.in index f1e98bf..aa6d7ec 100644 --- a/src/common/textevents.in +++ b/src/common/textevents.in @@ -25,7 +25,7 @@ n0 Capability Acknowledgement XP_TE_CAPACK pevt_capack_help -%C29*%O$tCapability acknowledged: %C29$2%O +%C29*%O$tCapabilities acknowledged: %C29$2%O 2 Capability List @@ -37,7 +37,7 @@ pevt_caplist_help Capability Request XP_TE_CAPREQ pevt_capreq_help -%C23*%O$tCapability requested: %C29$1%O +%C23*%O$tCapabilities requested: %C29$1%O 1 Change Nick -- 2.11.4.GIT