diff options
author | Sébastien Helleu <flashcode@flashtux.org> | 2021-06-19 17:50:07 +0200 |
---|---|---|
committer | Sébastien Helleu <flashcode@flashtux.org> | 2021-06-19 18:22:49 +0200 |
commit | ef318cb70c3db60d7647fce3c498813a87c43b46 (patch) | |
tree | 2fcbbb16556755e9189db106de91cc224fc8ff6a /src/plugins/irc/irc-protocol.c | |
parent | 947f73bd506deec427e7393c6e2c696424415780 (diff) | |
download | weechat-ef318cb70c3db60d7647fce3c498813a87c43b46.zip |
irc: enable all capabilities by default (supported by both server and WeeChat) (closes #320)
Capabilities can be excluded with the format: "*,!account-*,!extended-join".
Diffstat (limited to 'src/plugins/irc/irc-protocol.c')
-rw-r--r-- | src/plugins/irc/irc-protocol.c | 147 |
1 files changed, 108 insertions, 39 deletions
diff --git a/src/plugins/irc/irc-protocol.c b/src/plugins/irc/irc-protocol.c index 40e49adcc..1d6dca990 100644 --- a/src/plugins/irc/irc-protocol.c +++ b/src/plugins/irc/irc-protocol.c @@ -590,16 +590,83 @@ irc_protocol_cap_print_cb (void *data, } /* + * Get capabilities to enable on the server (server option "capabilities" with + * "sasl" if requested, "*" is replaced by all supported capabilities). + * + * Note: result must be freed after use. + */ + +char * +irc_protocol_cap_to_enable (const char *capabilities, int sasl_requested) +{ + char **str_caps, **caps, *supported_caps; + int i, num_caps; + + str_caps = weechat_string_dyn_alloc (128); + if (!str_caps) + return NULL; + + if (capabilities && capabilities[0]) + { + caps = weechat_string_split ( + capabilities, + ",", + NULL, + WEECHAT_STRING_SPLIT_STRIP_LEFT + | WEECHAT_STRING_SPLIT_STRIP_RIGHT + | WEECHAT_STRING_SPLIT_COLLAPSE_SEPS, + 0, + &num_caps); + if (caps) + { + for (i = 0; i < num_caps; i++) + { + if (strcmp (caps[i], "*") == 0) + { + supported_caps = weechat_string_replace ( + IRC_COMMAND_CAP_SUPPORTED_COMPLETION, + "|", + ","); + if (supported_caps) + { + if (*str_caps[0]) + weechat_string_dyn_concat (str_caps, ",", -1); + weechat_string_dyn_concat (str_caps, supported_caps, -1); + free (supported_caps); + } + } + else + { + if (*str_caps[0]) + weechat_string_dyn_concat (str_caps, ",", -1); + weechat_string_dyn_concat (str_caps, caps[i], -1); + } + } + weechat_string_free_split (caps); + } + } + + if (sasl_requested) + { + if (*str_caps[0]) + weechat_string_dyn_concat (str_caps, ",", -1); + weechat_string_dyn_concat (str_caps, "sasl", -1); + } + + return weechat_string_dyn_free (str_caps, 0); +} + +/* * Synchronizes requested capabilities for IRC server. */ void irc_protocol_cap_sync (struct t_irc_server *server, int sasl) { - char *cap_option, *cap_req, **caps_requested; + char **caps_server, *caps_to_enable, **list_caps_to_enable, **cap_req; const char *ptr_cap_option; int sasl_requested, sasl_to_do, sasl_fail; - int i, length, num_caps_requested; + int i, num_caps_server; sasl_requested = (sasl) ? irc_server_sasl_enabled (server) : 0; sasl_to_do = 0; @@ -607,59 +674,59 @@ irc_protocol_cap_sync (struct t_irc_server *server, int sasl) ptr_cap_option = IRC_SERVER_OPTION_STRING( server, IRC_SERVER_OPTION_CAPABILITIES); - length = ((ptr_cap_option && ptr_cap_option[0]) ? - strlen (ptr_cap_option) : 0) + 16; - cap_option = malloc (length); - cap_req = malloc (length); - if (cap_option && cap_req) - { - cap_option[0] = '\0'; - if (ptr_cap_option && ptr_cap_option[0]) - strcat (cap_option, ptr_cap_option); - if (sasl && sasl_requested) - { - if (cap_option[0]) - strcat (cap_option, ","); - strcat (cap_option, "sasl"); - } - cap_req[0] = '\0'; - caps_requested = weechat_string_split ( - cap_option, + + cap_req = weechat_string_dyn_alloc (128); + + caps_to_enable = irc_protocol_cap_to_enable (ptr_cap_option, + sasl_requested); + list_caps_to_enable = weechat_string_split ( + caps_to_enable, + ",", + NULL, + WEECHAT_STRING_SPLIT_STRIP_LEFT + | WEECHAT_STRING_SPLIT_STRIP_RIGHT + | WEECHAT_STRING_SPLIT_COLLAPSE_SEPS, + 0, + NULL); + if (list_caps_to_enable) + { + caps_server = weechat_string_split ( + weechat_hashtable_get_string (server->cap_ls, "keys"), ",", NULL, WEECHAT_STRING_SPLIT_STRIP_LEFT | WEECHAT_STRING_SPLIT_STRIP_RIGHT | WEECHAT_STRING_SPLIT_COLLAPSE_SEPS, 0, - &num_caps_requested); - if (caps_requested) + &num_caps_server); + if (caps_server) { - for (i = 0; i < num_caps_requested; i++) + for (i = 0; i < num_caps_server; i++) { - if (weechat_hashtable_has_key (server->cap_ls, - caps_requested[i]) && - !weechat_hashtable_has_key (server->cap_list, - caps_requested[i])) + if (!weechat_hashtable_has_key (server->cap_list, + caps_server[i]) + && weechat_string_match_list (caps_server[i], + (const char **)list_caps_to_enable, + 0)) { - if (sasl && strcmp (caps_requested[i], "sasl") == 0) + if (sasl && strcmp (caps_server[i], "sasl") == 0) sasl_to_do = 1; - if (cap_req[0]) - strcat (cap_req, " "); - strcat (cap_req, caps_requested[i]); + if (*cap_req[0]) + weechat_string_dyn_concat (cap_req, " ", -1); + weechat_string_dyn_concat (cap_req, caps_server[i], -1); } } - weechat_string_free_split (caps_requested); + weechat_string_free_split (caps_server); } - if (cap_req[0]) + if (*cap_req[0]) { weechat_printf ( server->buffer, _("%s%s: client capability, requesting: %s"), weechat_prefix ("network"), IRC_PLUGIN_NAME, - cap_req); - irc_server_sendf (server, 0, NULL, - "CAP REQ :%s", cap_req); + *cap_req); + irc_server_sendf (server, 0, NULL, "CAP REQ :%s", *cap_req); } if (sasl) @@ -687,11 +754,13 @@ irc_protocol_cap_sync (struct t_irc_server *server, int sasl) } } } + weechat_string_free_split (list_caps_to_enable); } - if (cap_option) - free (cap_option); + + if (caps_to_enable) + free (caps_to_enable); if (cap_req) - free (cap_req); + weechat_string_dyn_free (cap_req, 1); } /* |