summaryrefslogtreecommitdiff
path: root/src/plugins
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
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')
-rw-r--r--src/plugins/irc/irc-command.c4
-rw-r--r--src/plugins/irc/irc-command.h2
-rw-r--r--src/plugins/irc/irc-config.c7
-rw-r--r--src/plugins/irc/irc-protocol.c147
-rw-r--r--src/plugins/irc/irc-server.c2
5 files changed, 117 insertions, 45 deletions
diff --git a/src/plugins/irc/irc-command.c b/src/plugins/irc/irc-command.c
index 9c8d88087..05a18ee5f 100644
--- a/src/plugins/irc/irc-command.c
+++ b/src/plugins/irc/irc-command.c
@@ -6513,8 +6513,8 @@ irc_command_init ()
" /cap req multi-prefix away-notify"),
"ls"
" || list"
- " || req " IRC_COMMAND_CAP_SUPPORTED_COMPLETION
- " || ack " IRC_COMMAND_CAP_SUPPORTED_COMPLETION
+ " || req " IRC_COMMAND_CAP_SUPPORTED_COMPLETION "|%*"
+ " || ack " IRC_COMMAND_CAP_SUPPORTED_COMPLETION "|%*"
" || end",
&irc_command_cap, NULL, NULL);
weechat_hook_command (
diff --git a/src/plugins/irc/irc-command.h b/src/plugins/irc/irc-command.h
index e9a82cdb7..cacfafcb1 100644
--- a/src/plugins/irc/irc-command.h
+++ b/src/plugins/irc/irc-command.h
@@ -56,7 +56,7 @@ struct t_irc_channel;
/* list of supported capabilities (for completion in command /cap) */
#define IRC_COMMAND_CAP_SUPPORTED_COMPLETION \
"account-notify|away-notify|cap-notify|chghost|extended-join|" \
- "invite-notify|multi-prefix|server-time|setname|userhost-in-names|%*"
+ "invite-notify|multi-prefix|server-time|setname|userhost-in-names"
/* list of supported CTCPs (for completion in command /ctcp) */
#define IRC_COMMAND_CTCP_SUPPORTED_COMPLETION \
diff --git a/src/plugins/irc/irc-config.c b/src/plugins/irc/irc-config.c
index 353621e46..8434041aa 100644
--- a/src/plugins/irc/irc-config.c
+++ b/src/plugins/irc/irc-config.c
@@ -1842,8 +1842,11 @@ irc_config_server_new_option (struct t_config_file *config_file,
/* TRANSLATORS: please keep words "client capabilities" between brackets if translation is different (see fr.po) */
N_("comma-separated list of client capabilities to enable for "
"server if they are available (see /help cap for a list of "
- "capabilities supported by WeeChat) "
- "(example: \"away-notify,multi-prefix\")"),
+ "capabilities supported by WeeChat); \"*\" enables all "
+ "capabilities by default (supported by both server and "
+ "WeeChat); wildcard \"*\" is allowed; a capability "
+ "beginning with \"!\" is excluded "
+ "(example: \"*,!account-*,!extended-join\")"),
NULL, 0, 0,
default_value, value,
null_value_allowed,
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);
}
/*
diff --git a/src/plugins/irc/irc-server.c b/src/plugins/irc/irc-server.c
index 97d9691a7..d20c7479c 100644
--- a/src/plugins/irc/irc-server.c
+++ b/src/plugins/irc/irc-server.c
@@ -87,7 +87,7 @@ char *irc_server_options[IRC_SERVER_NUM_OPTIONS][2] =
{ "ssl_fingerprint", "" },
{ "ssl_verify", "on" },
{ "password", "" },
- { "capabilities", "" },
+ { "capabilities", "*" },
{ "sasl_mechanism", "plain" },
{ "sasl_username", "" },
{ "sasl_password", "" },