From 4057b7dd5852575a415cca8f465b4d419dcbdf9d Mon Sep 17 00:00:00 2001 From: Diogo Sousa Date: Sun, 23 Jun 2013 16:24:30 +0100 Subject: [PATCH] Now inbound_cap_ls() can enable extensions when a bouncer uses a namespace for the extension server-time. --- src/common/hexchat.h | 1 + src/common/inbound.c | 115 +++++++++++++++++++++++++++-------------- src/common/proto-irc.c | 10 ++-- src/common/server.c | 1 + 4 files changed, 82 insertions(+), 45 deletions(-) diff --git a/src/common/hexchat.h b/src/common/hexchat.h index 1a759f14..ca9f9c44 100644 --- a/src/common/hexchat.h +++ b/src/common/hexchat.h @@ -593,6 +593,7 @@ typedef struct server unsigned int have_idmsg:1; /* freenode's IDENTIFY-MSG */ unsigned int have_accnotify:1; /* cap account-notify */ unsigned int have_extjoin:1; /* cap extended-join */ + unsigned int have_server_time:1; /* cap server-time */ unsigned int have_sasl:1; /* SASL capability */ unsigned int have_except:1; /* ban exemptions +e */ unsigned int have_invite:1; /* invite exemptions +I */ diff --git a/src/common/inbound.c b/src/common/inbound.c index a37ca31b..82f5826a 100644 --- a/src/common/inbound.c +++ b/src/common/inbound.c @@ -1239,7 +1239,8 @@ inbound_next_nick (session *sess, char *nick, int error, break; default: - EMIT_SIGNAL_TIMESTAMP (XP_TE_NICKFAIL, sess, NULL, NULL, NULL, NULL, 0); + EMIT_SIGNAL_TIMESTAMP (XP_TE_NICKFAIL, sess, NULL, NULL, NULL, NULL, 0, + tags_data->timestamp); } } @@ -1549,32 +1550,37 @@ inbound_cap_ack (server *serv, char *nick, char *extensions, EMIT_SIGNAL_TIMESTAMP (XP_TE_CAPACK, serv->server_session, nick, extensions, NULL, NULL, 0, tags_data->timestamp); - if (strstr (extensions, "identify-msg") != 0) + if (strstr (extensions, "identify-msg") != NULL) { serv->have_idmsg = TRUE; } - if (strstr (extensions, "multi-prefix") != 0) + if (strstr (extensions, "multi-prefix") != NULL) { serv->have_namesx = TRUE; } - if (strstr (extensions, "away-notify") != 0) + if (strstr (extensions, "away-notify") != NULL) { serv->have_awaynotify = TRUE; } - if (strstr (extensions, "account-notify") != 0) + if (strstr (extensions, "account-notify") != NULL) { serv->have_accnotify = TRUE; } - if (strstr (extensions, "extended-join") != 0) + if (strstr (extensions, "extended-join") != NULL) { serv->have_extjoin = TRUE; } - if (strstr (extensions, "sasl") != 0) + if (strstr (extensions, "server-time") != NULL) + { + serv->have_server_time = TRUE; + } + + if (strstr (extensions, "sasl") != NULL) { char *user; @@ -1594,53 +1600,82 @@ inbound_cap_ack (server *serv, char *nick, char *extensions, } void -inbound_cap_ls (server *serv, char *nick, char *extensions, +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 */ 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 **extensions; + int i; - EMIT_SIGNAL_TIMESTAMP (XP_TE_CAPLIST, serv->server_session, nick, extensions, - NULL, NULL, 0, tags_data->timestamp); + EMIT_SIGNAL_TIMESTAMP (XP_TE_CAPLIST, serv->server_session, nick, + extensions_str, NULL, NULL, 0, tags_data->timestamp); want_cap = 0; want_sasl = 0; + extensions = g_strsplit (extensions_str, " ", 0); + strcpy (buffer, "CAP REQ :"); - if (strstr (extensions, "identify-msg") != 0) + for (i=0; extensions[i]; i++) { - strcat (buffer, "identify-msg "); - want_cap = 1; - } - if (strstr (extensions, "multi-prefix") != 0) - { - strcat (buffer, "multi-prefix "); - want_cap = 1; - } - if (strstr (extensions, "away-notify") != 0) - { - strcat (buffer, "away-notify "); - want_cap = 1; - } - if (strstr (extensions, "account-notify") != 0) - { - strcat (buffer, "account-notify "); - want_cap = 1; - } - if (strstr (extensions, "extended-join") != 0) - { - strcat (buffer, "extended-join "); - want_cap = 1; - } - /* if the SASL password is set AND auth mode is set to SASL, request SASL auth */ - if (strstr (extensions, "sasl") != 0 && strlen (serv->password) != 0 && serv->loginmethod == LOGIN_SASL) - { - strcat (buffer, "sasl "); - want_cap = 1; - want_sasl = 1; + const char *extension = extensions[i]; + + if (!strcmp (extension, "identify-msg")) + { + strcat (buffer, "identify-msg "); + want_cap = 1; + } + if (!strcmp (extension, "multi-prefix")) + { + strcat (buffer, "multi-prefix "); + want_cap = 1; + } + if (!strcmp (extension, "away-notify")) + { + strcat (buffer, "away-notify "); + want_cap = 1; + } + if (!strcmp (extension, "account-notify")) + { + strcat (buffer, "account-notify "); + want_cap = 1; + } + if (!strcmp (extension, "extended-join")) + { + strcat (buffer, "extended-join "); + want_cap = 1; + } + + /* bouncers can prefix a name space to the extension so we should use. + * znc uses "znc.in/server-time". + */ + if (!strcmp (extension, "znc.in/server-time")) + { + strcat (buffer, "znc.in/server-time"); + strcat (buffer, " "); + } + else if (!strcmp (extension, "server-time")) + { + /* ignore. it is best to have server-time explicitly enabled or have + * a option in the preferences (or per server). + */ + } + + /* if the SASL password is set AND auth mode is set to SASL, request SASL auth */ + if (serv->loginmethod == LOGIN_SASL + && strcmp (extension, "sasl") != 0 + && strlen (serv->password) != 0) + { + strcat (buffer, "sasl "); + want_cap = 1; + want_sasl = 1; + } } + g_strfreev (extensions); + if (want_cap) { /* buffer + 9 = emit buffer without "CAP REQ :" */ diff --git a/src/common/proto-irc.c b/src/common/proto-irc.c index 3c9a63e5..875247e7 100644 --- a/src/common/proto-irc.c +++ b/src/common/proto-irc.c @@ -1384,9 +1384,9 @@ handle_message_tag_time (const char *time, message_tags_data *tags_data) * * See http://ircv3.atheme.org/specification/message-tags-3.2 */ -/* TODO:orium: we should ignore capabilities not enabled! */ static void -handle_message_tags (const char *tags_str, message_tags_data *tags_data) +handle_message_tags (server *serv, const char *tags_str, + message_tags_data *tags_data) { char **tags; int i; @@ -1407,7 +1407,7 @@ handle_message_tags (const char *tags_str, message_tags_data *tags_data) *value = '\0'; value++; - if (!strcmp (key, "time")) + if (serv->have_server_time && !strcmp (key, "time")) handle_message_tag_time (value, tags_data); } @@ -1447,7 +1447,7 @@ irc_inline (server *serv, char *buf, int len) *sep = '\0'; buf = sep + 1; - handle_message_tags(tags, &tags_data); + handle_message_tags(serv, tags, &tags_data); } url_check_line (buf, len); @@ -1495,7 +1495,7 @@ irc_inline (server *serv, char *buf, int len) if (*text == ':') text++; - process_numeric (sess, atoi (word[2]), word, word_eol, text, &tags_data); // TODO:orium (data tags) + process_numeric (sess, atoi (word[2]), word, word_eol, text, &tags_data); } else { process_named_msg (sess, type, word, word_eol, &tags_data); diff --git a/src/common/server.c b/src/common/server.c index 99e7563e..e59a7ee3 100644 --- a/src/common/server.c +++ b/src/common/server.c @@ -1895,6 +1895,7 @@ server_set_defaults (server *serv) serv->have_idmsg = FALSE; serv->have_accnotify = FALSE; serv->have_extjoin = FALSE; + serv->have_server_time = FALSE; serv->have_sasl = FALSE; serv->have_except = FALSE; serv->have_invite = FALSE;