diff --git a/ChangeLog.adoc b/ChangeLog.adoc index 0c1c0b39b..2b5f10786 100644 --- a/ChangeLog.adoc +++ b/ChangeLog.adoc @@ -67,6 +67,7 @@ New features:: * relay: make TLS certificate/key loading error handling more verbose (issue #1558) * relay: add modifiers "relay_client_irc_in", "relay_client_irc_out1" and "relay_client_irc_out" in irc protocol * relay: add support of capability "echo-message" in irc protocol (issue #1949) + * relay: add handshake option "escape_commands" in weechat protocol Bug fixes:: diff --git a/doc/en/weechat_relay_protocol.en.adoc b/doc/en/weechat_relay_protocol.en.adoc index 0ca1fbf49..4ef031b5a 100644 --- a/doc/en/weechat_relay_protocol.en.adoc +++ b/doc/en/weechat_relay_protocol.en.adoc @@ -98,7 +98,7 @@ List of available commands (detail in next chapters): [[command_handshake]] === handshake -_WeeChat ≥ 2.9, updated in version 3.5._ +_WeeChat ≥ 2.9, updated in versions 3.5, 4.0.0._ Perform an handshake between the client and WeeChat: this is required in most cases to know the session settings and prepare the authentication with the @@ -131,6 +131,11 @@ Arguments: *** _zstd_: compress with https://facebook.github.io/zstd/[Zstandard ^↗^^]: better compression and much faster than _zlib_ for both compression and decompression _(WeeChat ≥ 3.5)_ +** _escape_commands_: commands sent by the client to relay must be escaped: + all backslashes are interpreted and a single backslash must be escaped (`\\`); + this allows for example the client to send multiline messages (chars `\n` are + converted to newlines, see <>) + _(WeeChat ≥ 4.0.0)_ Notes about option _password_hash_algo_: @@ -602,7 +607,7 @@ Request an _infolist_. [IMPORTANT] Content of infolist is a duplication of actual data. Wherever possible, use -command <>, which is direct access to data (it is +<>, which is direct access to data (it is faster, uses less memory and returns smaller objects in message). Syntax: @@ -964,6 +969,14 @@ input core.weechat /help filter input irc.libera.#weechat hello! ---- +* Send multiline message to #test channel (option _escape_commands_ must have + been enabled in <> and requires + WeeChat ≥ 4.0.0): + +---- +input irc.ergo.#test this message has\n2 lines +---- + [[command_completion]] === completion @@ -1211,7 +1224,7 @@ Arguments: specify all buffers * _options_: one of following keywords, separated by commas (default is _buffers,upgrade,buffer,nicklist_ for "*" and _buffer,nicklist_ for a buffer); - see <> for values + see <> for values [NOTE] When using buffer "*", the other buffers synchronized (using a name) are kept. + diff --git a/doc/fr/weechat_relay_protocol.fr.adoc b/doc/fr/weechat_relay_protocol.fr.adoc index 51eeb3c49..e3e87b4bb 100644 --- a/doc/fr/weechat_relay_protocol.fr.adoc +++ b/doc/fr/weechat_relay_protocol.fr.adoc @@ -102,7 +102,7 @@ Liste des commandes disponibles (détail dans les chapitres suivants) : [[command_handshake]] === handshake -_WeeChat ≥ 2.9, mis à jour dans la version 3.5._ +_WeeChat ≥ 2.9, mis à jour dans les versions 3.5, 4.0.0._ Effectuer une poignée de main entre le client et WeeChat : cela est obligatoire dans la plupart des cas pour connaître les paramètres de la session et préparer @@ -138,6 +138,12 @@ Paramètres : *** _zstd_ : compresser avec https://facebook.github.io/zstd/[Zstandard ^↗^^] : meilleure compression et bien plus rapide que _zlib_ pour la compression et la décompression _(WeeChat ≥ 3.5)_ +** _escape_commands_ : les commandes envoyées par le client vers _relay_ doivent + être échappées : toutes les barres obliques inverses sont interprétées et une + barre oblique inverse simple doit être échappée (`\\`) ; cela autorise + par exemple un client à envoyer des messages multi-lignes (les caractères + `\n` sont remplacés par des nouvelles lignes, voir la <>) + _(WeeChat ≥ 4.0.0)_ Notes à propos de l'option _password_hash_algo_ : @@ -614,7 +620,7 @@ Demander une _infolist_. [IMPORTANT] Le contenu de l'infolist est une duplication des données. Dans la mesure du -possible, utilisez plutôt la commande <>, qui est un accès +possible, utilisez plutôt la <>, qui est un accès direct aux données (cela est plus rapide, utilise moins de mémoire et retourne des objets plus petits dans le message). @@ -978,6 +984,14 @@ input core.weechat /help filter input irc.libera.#weechat bonjour ! ---- +* Envoyer un message multi-lignes au canal #test (l'option _escape_commands_ + doit avoir été activée dans la <> et + requiert WeeChat ≥ 4.0.0) : + +---- +input irc.ergo.#test ce message a\n2 lignes +---- + [[command_completion]] === completion @@ -1228,7 +1242,7 @@ Paramètres : spécifier tous les tampons * _options_ : un ou plusieurs mots-clés, séparés par des virgules (le défaut est _buffers,upgrade,buffer,nicklist_ pour "*" et _buffer,nicklist_ pour un - tampon) ; voir <> pour les valeurs + tampon) ; voir la <> pour les valeurs [NOTE] En utilisant le tampon "*", les autres tampons synchronisés (en utilisant un diff --git a/doc/ja/weechat_relay_protocol.ja.adoc b/doc/ja/weechat_relay_protocol.ja.adoc index 55afb5370..b279e2f6d 100644 --- a/doc/ja/weechat_relay_protocol.ja.adoc +++ b/doc/ja/weechat_relay_protocol.ja.adoc @@ -106,7 +106,8 @@ _リレー_ プラグインは _IRC プロキシ_ のように振舞います ( [[command_handshake]] === handshake -_WeeChat ≥ 2.9, updated in version 3.5._ +// TRANSLATION MISSING +_WeeChat ≥ 2.9, updated in versions 3.5, 4.0.0._ Perform an handshake between the client and WeeChat: this is required in most cases to know the session settings and prepare the authentication with the @@ -140,6 +141,12 @@ Arguments: *** _zstd_: compress with https://facebook.github.io/zstd/[Zstandard ^↗^^]: better compression and much faster than _zlib_ for both compression and decompression _(WeeChat ≥ 3.5)_ +// TRANSLATION MISSING +** _escape_commands_: commands sent by the client to relay must be escaped: + all backslashes are interpreted and a single backslash must be escaped (`\\`); + this allows for example the client to send multiline messages (chars `\n` are + converted to newlines, see <>) + _(WeeChat ≥ 4.0.0)_ Notes about option _password_hash_algo_: @@ -985,6 +992,15 @@ input core.weechat /help filter input irc.libera.#weechat hello! ---- +// TRANSLATION MISSING +* Send multiline message to #test channel (option _escape_commands_ must have + been enabled in <> and requires + WeeChat ≥ 4.0.0): + +---- +input irc.ergo.#test this message has\n2 lines +---- + // TRANSLATION MISSING [[command_completion]] === completion diff --git a/doc/sr/weechat_relay_protocol.sr.adoc b/doc/sr/weechat_relay_protocol.sr.adoc index 8ebc338f6..b76d26949 100644 --- a/doc/sr/weechat_relay_protocol.sr.adoc +++ b/doc/sr/weechat_relay_protocol.sr.adoc @@ -92,7 +92,8 @@ _клијенти_ су повезани са _релејем_ као што ј [[command_handshake]] === handshake -_WeeChat ≥ 2.9, ажурирано у верзији 3.5._ +// TRANSLATION MISSING +_WeeChat ≥ 2.9, updated in versions 3.5, 4.0.0._ Извршава руковање између клијента и програма WeeChat: ово је у већини случајева неопходно како би се сазнале поставке сесије и припремила аутентификација командом _init_. @@ -122,6 +123,12 @@ _WeeChat ≥ 2.9, ажурирано у верзији 3.5._ *** _zstd_: компресија са https://facebook.github.io/zstd/[Zstandard ^↗^^]: боља компресија, као и много бржа компресија и декомпресија у односу на _zlib_ _(WeeChat ≥ 3.5)_ +// TRANSLATION MISSING +** _escape_commands_: commands sent by the client to relay must be escaped: + all backslashes are interpreted and a single backslash must be escaped (`\\`); + this allows for example the client to send multiline messages (chars `\n` are + converted to newlines, see <>) + _(WeeChat ≥ 4.0.0)_ Напомене у вези опције _password_hash_algo_: @@ -911,6 +918,15 @@ input core.weechat /help filter input irc.libera.#weechat здраво! ---- +// TRANSLATION MISSING +* Send multiline message to #test channel (option _escape_commands_ must have + been enabled in <> and requires + WeeChat ≥ 4.0.0): + +---- +input irc.ergo.#test this message has\n2 lines +---- + [[command_completion]] === completion diff --git a/src/plugins/relay/weechat/relay-weechat-protocol.c b/src/plugins/relay/weechat/relay-weechat-protocol.c index f44259f39..e27c6308d 100644 --- a/src/plugins/relay/weechat/relay-weechat-protocol.c +++ b/src/plugins/relay/weechat/relay-weechat-protocol.c @@ -203,6 +203,10 @@ relay_weechat_protocol_handshake_reply (struct t_relay_client *client, hashtable, "compression", relay_weechat_compression_string[RELAY_WEECHAT_DATA(client, compression)]); + weechat_hashtable_set ( + hashtable, + "escape_commands", + RELAY_WEECHAT_DATA(client, escape_commands) ? "on" : "off"); msg = relay_weechat_msg_new (id); if (msg) @@ -315,6 +319,12 @@ RELAY_WEECHAT_PROTOCOL_CALLBACK(handshake) weechat_string_free_split (compressions); } } + else if (strcmp (options[i], "escape_commands") == 0) + { + RELAY_WEECHAT_DATA(client, escape_commands) = + (weechat_strcmp (pos, "on") == 0) ? + 1 : 0; + } } } weechat_string_free_split_command (options); @@ -1742,7 +1752,8 @@ RELAY_WEECHAT_PROTOCOL_CALLBACK(quit) void relay_weechat_protocol_recv (struct t_relay_client *client, const char *data) { - char *pos, *id, *command, **argv, **argv_eol; + const char *ptr_data; + char *data_unescaped, *pos, *id, *command, **argv, **argv_eol; int i, argc, return_code; struct t_relay_weechat_protocol_cb protocol_cb[] = { { "handshake", &relay_weechat_protocol_cb_handshake }, @@ -1775,35 +1786,44 @@ relay_weechat_protocol_recv (struct t_relay_client *client, const char *data) data); } - /* extract id */ + data_unescaped = NULL; + ptr_data = data; id = NULL; - if (data[0] == '(') + command = NULL; + argv = NULL; + argv_eol = NULL; + + if (RELAY_WEECHAT_DATA(client, escape_commands)) { - pos = strchr (data, ')'); + data_unescaped = weechat_string_convert_escaped_chars (data); + if (data_unescaped) + ptr_data = data_unescaped; + } + + /* extract id */ + if (ptr_data[0] == '(') + { + pos = strchr (ptr_data, ')'); if (pos) { - id = weechat_strndup (data + 1, pos - data - 1); - data = pos + 1; - while (data[0] == ' ') + id = weechat_strndup (ptr_data + 1, pos - ptr_data - 1); + ptr_data = pos + 1; + while (ptr_data[0] == ' ') { - data++; + ptr_data++; } } } /* search end of data */ - pos = strchr (data, ' '); + pos = strchr (ptr_data, ' '); if (pos) - command = weechat_strndup (data, pos - data); + command = weechat_strndup (ptr_data, pos - ptr_data); else - command = strdup (data); + command = strdup (ptr_data); if (!command) - { - if (id) - free (id); - return; - } + goto end; argc = 0; argv = NULL; @@ -1868,6 +1888,9 @@ relay_weechat_protocol_recv (struct t_relay_client *client, const char *data) } } +end: + if (data_unescaped) + free (data_unescaped); if (id) free (id); free (command); diff --git a/src/plugins/relay/weechat/relay-weechat.c b/src/plugins/relay/weechat/relay-weechat.c index e07a949e8..c61aacf3a 100644 --- a/src/plugins/relay/weechat/relay-weechat.c +++ b/src/plugins/relay/weechat/relay-weechat.c @@ -184,6 +184,7 @@ relay_weechat_alloc (struct t_relay_client *client) RELAY_WEECHAT_DATA(client, password_ok) = 0; RELAY_WEECHAT_DATA(client, totp_ok) = 0; RELAY_WEECHAT_DATA(client, compression) = RELAY_WEECHAT_COMPRESSION_OFF; + RELAY_WEECHAT_DATA(client, escape_commands) = 0; RELAY_WEECHAT_DATA(client, buffers_sync) = weechat_hashtable_new (32, WEECHAT_HASHTABLE_STRING, @@ -237,6 +238,8 @@ relay_weechat_alloc_with_infolist (struct t_relay_client *client, RELAY_WEECHAT_DATA(client, totp_ok) = 1; RELAY_WEECHAT_DATA(client, compression) = weechat_infolist_integer ( infolist, "compression"); + RELAY_WEECHAT_DATA(client, escape_commands) = weechat_infolist_integer ( + infolist, "escape_commands"); /* sync of buffers */ RELAY_WEECHAT_DATA(client, buffers_sync) = weechat_hashtable_new ( @@ -357,6 +360,8 @@ relay_weechat_add_to_infolist (struct t_infolist_item *item, return 0; if (!weechat_infolist_new_var_integer (item, "compression", RELAY_WEECHAT_DATA(client, compression))) return 0; + if (!weechat_infolist_new_var_integer (item, "escape_commands", RELAY_WEECHAT_DATA(client, escape_commands))) + return 0; if (!weechat_hashtable_add_to_infolist (RELAY_WEECHAT_DATA(client, buffers_sync), item, "buffers_sync")) return 0; @@ -376,6 +381,7 @@ relay_weechat_print_log (struct t_relay_client *client) weechat_log_printf (" password_ok . . . . . . : %d", RELAY_WEECHAT_DATA(client, password_ok)); weechat_log_printf (" totp_ok . . . . . . . . : %d", RELAY_WEECHAT_DATA(client, totp_ok)); weechat_log_printf (" compression . . . . . . : %d", RELAY_WEECHAT_DATA(client, compression)); + weechat_log_printf (" escape_commands . . . . : %d", RELAY_WEECHAT_DATA(client, escape_commands)); weechat_log_printf (" buffers_sync. . . . . . : 0x%lx (hashtable: '%s')", RELAY_WEECHAT_DATA(client, buffers_sync), weechat_hashtable_get_string (RELAY_WEECHAT_DATA(client, buffers_sync), diff --git a/src/plugins/relay/weechat/relay-weechat.h b/src/plugins/relay/weechat/relay-weechat.h index c38f47b78..469536aac 100644 --- a/src/plugins/relay/weechat/relay-weechat.h +++ b/src/plugins/relay/weechat/relay-weechat.h @@ -44,13 +44,15 @@ struct t_relay_weechat_data /* handshake status */ int handshake_done; /* 1 if handshake has been done */ + /* handshake options */ + enum t_relay_weechat_compression compression; /* compression type */ + int escape_commands; /* 1 if backslashes are interpreted */ + /* in commands sent by client */ + /* authentication status (init command) */ int password_ok; /* password received and OK? */ int totp_ok; /* TOTP received and OK? */ - /* options set by client (init command) */ - enum t_relay_weechat_compression compression; /* compression type */ - /* sync of buffers */ struct t_hashtable *buffers_sync; /* buffers synchronized (events */ /* received for these buffers) */