summaryrefslogtreecommitdiff
path: root/src/plugins/irc/irc-protocol.c
diff options
context:
space:
mode:
authorSébastien Helleu <flashcode@flashtux.org>2021-06-19 17:50:07 +0200
committerSébastien Helleu <flashcode@flashtux.org>2021-06-19 18:22:49 +0200
commitef318cb70c3db60d7647fce3c498813a87c43b46 (patch)
tree2fcbbb16556755e9189db106de91cc224fc8ff6a /src/plugins/irc/irc-protocol.c
parent947f73bd506deec427e7393c6e2c696424415780 (diff)
downloadweechat-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.c147
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);
}
/*