diff options
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/hexchat.h | 1 | ||||
-rw-r--r-- | src/common/inbound.c | 37 | ||||
-rw-r--r-- | src/common/proto-irc.c | 2 | ||||
-rw-r--r-- | src/common/server.c | 1 |
4 files changed, 35 insertions, 6 deletions
diff --git a/src/common/hexchat.h b/src/common/hexchat.h index fb389179..a29ea1d8 100644 --- a/src/common/hexchat.h +++ b/src/common/hexchat.h @@ -572,6 +572,7 @@ typedef struct server unsigned int sasl_mech; /* mechanism for sasl auth */ unsigned int sent_saslauth:1; /* have sent AUTHENICATE yet */ unsigned int sent_capend:1; /* have sent CAP END yet */ + unsigned int waiting_on_cap:1; /* waiting on another line of CAP LS */ #ifdef USE_OPENSSL unsigned int use_ssl:1; /* is server SSL capable? */ unsigned int accept_invalid_cert:1;/* ignore result of server's cert. verify */ diff --git a/src/common/inbound.c b/src/common/inbound.c index 3df0c520..0d24532f 100644 --- a/src/common/inbound.c +++ b/src/common/inbound.c @@ -1735,12 +1735,23 @@ void inbound_cap_ls (server *serv, char *nick, char *extensions_str, const message_tags_data *tags_data) { - char buffer[256]; /* buffer for requesting capabilities and emitting the signal */ + char buffer[500]; /* buffer for requesting capabilities and emitting the signal */ gboolean want_cap = FALSE; /* format the CAP REQ string based on previous capabilities being requested or not */ gboolean want_sasl = FALSE; /* CAP END shouldn't be sent when SASL is requested, it needs further responses */ char **extensions; int i; + if (g_str_has_prefix (extensions_str, "* ")) + { + serv->waiting_on_cap = TRUE; + extensions_str += 2; + extensions_str += extensions_str[0] == ':' ? 1 : 0; + } + else + { + serv->waiting_on_cap = FALSE; + } + EMIT_SIGNAL_TIMESTAMP (XP_TE_CAPLIST, serv->server_session, nick, extensions_str, NULL, NULL, 0, tags_data->timestamp); @@ -1750,9 +1761,17 @@ inbound_cap_ls (server *serv, char *nick, char *extensions_str, for (i=0; extensions[i]; i++) { - const char *extension = extensions[i]; + char *extension = extensions[i]; + char *value; gsize x; + /* CAP 3.2 can provide values */ + if ((value = strchr (extension, '='))) + { + *value = '\0'; + value++; + } + /* if the SASL password is set AND auth mode is set to SASL, request SASL auth */ if (!g_strcmp0 (extension, "sasl") && ((serv->loginmethod == LOGIN_SASL && strlen (serv->password) != 0) @@ -1785,7 +1804,7 @@ inbound_cap_ls (server *serv, char *nick, char *extensions_str, tags_data->timestamp); tcp_sendf (serv, "%s\r\n", g_strchomp (buffer)); } - if (!want_sasl) + if (!want_sasl && !serv->waiting_on_cap) { /* if we use SASL, CAP END is dealt via raw numerics */ serv->sent_capend = TRUE; @@ -1796,14 +1815,22 @@ inbound_cap_ls (server *serv, char *nick, char *extensions_str, void inbound_cap_nak (server *serv, const message_tags_data *tags_data) { - serv->sent_capend = TRUE; - tcp_send_len (serv, "CAP END\r\n", 9); + if (!serv->waiting_on_cap && !serv->sent_capend) + { + serv->sent_capend = TRUE; + tcp_send_len (serv, "CAP END\r\n", 9); + } } void inbound_cap_list (server *serv, char *nick, char *extensions, const message_tags_data *tags_data) { + if (g_str_has_prefix (extensions, "* ")) + { + extensions += 2; + extensions += extensions[0] == ':' ? 1 : 0; + } EMIT_SIGNAL_TIMESTAMP (XP_TE_CAPACK, serv->server_session, nick, extensions, NULL, NULL, 0, tags_data->timestamp); } diff --git a/src/common/proto-irc.c b/src/common/proto-irc.c index 6fe601ed..4174e182 100644 --- a/src/common/proto-irc.c +++ b/src/common/proto-irc.c @@ -48,7 +48,7 @@ static void irc_login (server *serv, char *user, char *realname) { - tcp_sendf (serv, "CAP LS\r\n"); /* start with CAP LS as Charybdis sasl.txt suggests */ + tcp_sendf (serv, "CAP LS 302\r\n"); /* start with CAP LS as Charybdis sasl.txt suggests */ serv->sent_capend = FALSE; /* track if we have finished */ if (serv->password[0] && serv->loginmethod == LOGIN_PASS) diff --git a/src/common/server.c b/src/common/server.c index 8ff81553..926a9f43 100644 --- a/src/common/server.c +++ b/src/common/server.c @@ -1732,6 +1732,7 @@ server_set_defaults (server *serv) serv->nickcount = 1; serv->end_of_motd = FALSE; + serv->sent_capend = FALSE; serv->is_away = FALSE; serv->supports_watch = FALSE; serv->supports_monitor = FALSE; |