mirror of
https://github.com/weechat/weechat.git
synced 2026-06-12 14:14:48 +02:00
irc: add support of capability "draft/multiline" (closes #1923)
This commit is contained in:
+1
-1
@@ -40,7 +40,7 @@ New features::
|
||||
* api: add optional argument with version in info "version_number"
|
||||
* alias: use lower case for default aliases, rename all aliases to lower case on upgrade (issue #1872)
|
||||
* irc: rename "ssl" options to "tls", connect with TLS and port 6697 by default
|
||||
* irc: add support of capability "batch" (issue #1292)
|
||||
* irc: add support of capabilities "batch" and "draft/multiline" (issue #1292, issue #1923)
|
||||
* irc: add command `/rules` (issue #1864)
|
||||
* irc: add command `/knock` (issue #7)
|
||||
* irc: add server option "registered_mode", add fields "authentication_method" and "sasl_mechanism_used" in server (issue #1625)
|
||||
|
||||
@@ -3472,6 +3472,7 @@ WeeChat unterstützt folgende https://ircv3.net/irc/[IRCv3 extensions ^↗^,win
|
||||
* <<irc_ircv3_batch,batch>>
|
||||
* <<irc_ircv3_cap_notify,cap-notify>>
|
||||
* <<irc_ircv3_chghost,chghost>>
|
||||
* <<irc_ircv3_draft/multiline,draft/multiline>>
|
||||
* <<irc_ircv3_extended_join,extended-join>>
|
||||
* <<irc_ircv3_invite_notify,invite-notify>>
|
||||
* <<irc_ircv3_message_tags,message-tags>>
|
||||
@@ -3599,6 +3600,60 @@ Beispiele:
|
||||
-- alice (user@example.com) hat den Host nach test.com geändert
|
||||
....
|
||||
|
||||
// TRANSLATION MISSING
|
||||
[[irc_ircv3_draft_multiline]]
|
||||
===== draft/multiline
|
||||
|
||||
Specification: https://ircv3.net/specs/extensions/multiline[multiline ^↗^,window=_blank]
|
||||
|
||||
This capability allows the client and server to send messages with multiple lines,
|
||||
using the <<irc_ircv3_batch,batch>> capability, that must be enabled as well.
|
||||
|
||||
There are limits in term of bytes or number of lines in a multiline message
|
||||
that are given in the capability sent by the server, for example:
|
||||
|
||||
....
|
||||
CAP alice LS * :draft/multiline=max-bytes=4096,max-lines=24
|
||||
....
|
||||
|
||||
This sets a limit of 4096 bytes and 24 lines for a multiline batched content.
|
||||
|
||||
If the limits are not given by the server, the default in WeeChat are:
|
||||
|
||||
* max bytes: 4096
|
||||
* max lines: 24
|
||||
|
||||
Only standard messages and those send by the <<command_irc_notice,/notice>>
|
||||
command can be multiline. +
|
||||
ACTION CTCP messages sent with command <<command_irc_me,/me>> are not affected
|
||||
by this capability. That means multiline actions are sent as multiple actions.
|
||||
|
||||
[WARNING]
|
||||
As the specification is a "draft", it may change and the multiline support can
|
||||
possibly break at any time in WeeChat. +
|
||||
The capability is automatically enabled if the server supports it and can be
|
||||
disabled with this command:
|
||||
`/set irc.server_default.capabilities "*,!draft/multiline"`. +
|
||||
When the capability is disabled, a multiline message is sent as multiple messages,
|
||||
as if they were sent sequentially to the server.
|
||||
|
||||
Example of IRC messages sent for a user message with two lines (`this is a test`
|
||||
/ `on two lines`), send to channel #test:
|
||||
|
||||
....
|
||||
BATCH +i8Je7M7gquddoyC9 draft/multiline #test
|
||||
@batch=i8Je7M7gquddoyC9 PRIVMSG #test :this is a test
|
||||
@batch=i8Je7M7gquddoyC9 PRIVMSG #test :on two lines
|
||||
BATCH -i8Je7M7gquddoyC9
|
||||
....
|
||||
|
||||
Display of the message sent in WeeChat:
|
||||
|
||||
....
|
||||
19:01:45 alice | this is a test
|
||||
| on two lines
|
||||
....
|
||||
|
||||
[[irc_ircv3_extended_join]]
|
||||
===== extended-join
|
||||
|
||||
|
||||
@@ -3408,6 +3408,7 @@ WeeChat supports the following https://ircv3.net/irc/[IRCv3 extensions ^↗^,wi
|
||||
* <<irc_ircv3_batch,batch>>
|
||||
* <<irc_ircv3_cap_notify,cap-notify>>
|
||||
* <<irc_ircv3_chghost,chghost>>
|
||||
* <<irc_ircv3_draft/multiline,draft/multiline>>
|
||||
* <<irc_ircv3_extended_join,extended-join>>
|
||||
* <<irc_ircv3_invite_notify,invite-notify>>
|
||||
* <<irc_ircv3_message_tags,message-tags>>
|
||||
@@ -3535,6 +3536,59 @@ Example:
|
||||
-- alice (user@example.com) has changed host to test.com
|
||||
....
|
||||
|
||||
[[irc_ircv3_draft_multiline]]
|
||||
===== draft/multiline
|
||||
|
||||
Specification: https://ircv3.net/specs/extensions/multiline[multiline ^↗^,window=_blank]
|
||||
|
||||
This capability allows the client and server to send messages with multiple lines,
|
||||
using the <<irc_ircv3_batch,batch>> capability, that must be enabled as well.
|
||||
|
||||
There are limits in term of bytes or number of lines in a multiline message
|
||||
that are given in the capability sent by the server, for example:
|
||||
|
||||
....
|
||||
CAP alice LS * :draft/multiline=max-bytes=4096,max-lines=24
|
||||
....
|
||||
|
||||
This sets a limit of 4096 bytes and 24 lines for a multiline batched content.
|
||||
|
||||
If the limits are not given by the server, the default in WeeChat are:
|
||||
|
||||
* max bytes: 4096
|
||||
* max lines: 24
|
||||
|
||||
Only standard messages and those send by the <<command_irc_notice,/notice>>
|
||||
command can be multiline. +
|
||||
ACTION CTCP messages sent with command <<command_irc_me,/me>> are not affected
|
||||
by this capability. That means multiline actions are sent as multiple actions.
|
||||
|
||||
[WARNING]
|
||||
As the specification is a "draft", it may change and the multiline support can
|
||||
possibly break at any time in WeeChat. +
|
||||
The capability is automatically enabled if the server supports it and can be
|
||||
disabled with this command:
|
||||
`/set irc.server_default.capabilities "*,!draft/multiline"`. +
|
||||
When the capability is disabled, a multiline message is sent as multiple messages,
|
||||
as if they were sent sequentially to the server.
|
||||
|
||||
Example of IRC messages sent for a user message with two lines (`this is a test`
|
||||
/ `on two lines`), send to channel #test:
|
||||
|
||||
....
|
||||
BATCH +i8Je7M7gquddoyC9 draft/multiline #test
|
||||
@batch=i8Je7M7gquddoyC9 PRIVMSG #test :this is a test
|
||||
@batch=i8Je7M7gquddoyC9 PRIVMSG #test :on two lines
|
||||
BATCH -i8Je7M7gquddoyC9
|
||||
....
|
||||
|
||||
Display of the message sent in WeeChat:
|
||||
|
||||
....
|
||||
19:01:45 alice | this is a test
|
||||
| on two lines
|
||||
....
|
||||
|
||||
[[irc_ircv3_extended_join]]
|
||||
===== extended-join
|
||||
|
||||
|
||||
@@ -3512,6 +3512,7 @@ WeeChat supporte les https://ircv3.net/irc/[extensions IRCv3 ^↗^,window=_blan
|
||||
* <<irc_ircv3_batch,batch>>
|
||||
* <<irc_ircv3_cap_notify,cap-notify>>
|
||||
* <<irc_ircv3_chghost,chghost>>
|
||||
* <<irc_ircv3_draft/multiline,draft/multiline>>
|
||||
* <<irc_ircv3_extended_join,extended-join>>
|
||||
* <<irc_ircv3_invite_notify,invite-notify>>
|
||||
* <<irc_ircv3_message_tags,message-tags>>
|
||||
@@ -3641,6 +3642,65 @@ Exemple :
|
||||
-- alice (user@example.com) a changé d'hôte pour test.com
|
||||
....
|
||||
|
||||
[[irc_ircv3_draft_multiline]]
|
||||
===== draft/multiline
|
||||
|
||||
Spécification : https://ircv3.net/specs/extensions/multiline[multiline ^↗^,window=_blank]
|
||||
|
||||
Cette capacité autorise le client et le serveur à envoyer des messages avec
|
||||
plusieurs lignes, en utilisant la capacité <<irc_ircv3_batch,batch>>, qui doit
|
||||
être activée également.
|
||||
|
||||
Il y a des limites en terme d'octets ou nombre de lignes dans un message
|
||||
multi-lignes qui sont données dans la capacité envoyée par le serveur,
|
||||
par exemple :
|
||||
|
||||
....
|
||||
CAP alice LS * :draft/multiline=max-bytes=4096,max-lines=24
|
||||
....
|
||||
|
||||
Cela fixe la limite à 4096 octets et 24 lignes pour un contenu "batch"
|
||||
multi-lignes.
|
||||
|
||||
Si les limites ne sont pas envoyées par le serveur, celles par défaut dans
|
||||
WeeChat sont :
|
||||
|
||||
* max octets : 4096
|
||||
* max lignes : 24
|
||||
|
||||
Seuls les messages standards et ceux envoyés avec la commande
|
||||
<<command_irc_notice,/notice>> peuvent être multi-lignes. +
|
||||
Les messages ACTION CTCP envoyés par avec la commande <<command_irc_me,/me>>
|
||||
ne sont pas affectés par cette capacité. Cela signifie que les actions
|
||||
multi-lignes sont envoyées sous forme de plusieurs actions.
|
||||
|
||||
[WARNING]
|
||||
Comme la spécification est un brouillon (« draft »), elle peut changer et le
|
||||
support "multiline" peut être cassé à tout moment dans WeeChat. +
|
||||
La capacité est automatiquement activée si le serveur la supporte et peut être
|
||||
désactivée avec cette commande :
|
||||
`/set irc.server_default.capabilities "*,!draft/multiline"`. +
|
||||
Lorsque la capacité est désactivée, un message multi-lignes est envoyé sous
|
||||
forme de plusieurs messages, comme s'ils avaient été envoyés séquentiellement
|
||||
au serveur.
|
||||
|
||||
Exemple de messages IRC envoyés pour un message utilisateur avec deux lignes
|
||||
(`ceci est un test` / `sur deux lignes`), envoyé au canal #test :
|
||||
|
||||
....
|
||||
BATCH +i8Je7M7gquddoyC9 draft/multiline #test
|
||||
@batch=i8Je7M7gquddoyC9 PRIVMSG #test :ceci est un test
|
||||
@batch=i8Je7M7gquddoyC9 PRIVMSG #test :sur deux lignes
|
||||
BATCH -i8Je7M7gquddoyC9
|
||||
....
|
||||
|
||||
Affichage du message envoyé dans WeeChat :
|
||||
|
||||
....
|
||||
19:01:45 alice | ceci est un test
|
||||
| sur deux lignes
|
||||
....
|
||||
|
||||
[[irc_ircv3_extended_join]]
|
||||
===== extended-join
|
||||
|
||||
|
||||
@@ -3698,6 +3698,7 @@ WeeChat supports the following https://ircv3.net/irc/[IRCv3 extensions ^↗^,wi
|
||||
* <<irc_ircv3_batch,batch>>
|
||||
* <<irc_ircv3_cap_notify,cap-notify>>
|
||||
* <<irc_ircv3_chghost,chghost>>
|
||||
* <<irc_ircv3_draft/multiline,draft/multiline>>
|
||||
* <<irc_ircv3_extended_join,extended-join>>
|
||||
* <<irc_ircv3_invite_notify,invite-notify>>
|
||||
* <<irc_ircv3_message_tags,message-tags>>
|
||||
@@ -3825,6 +3826,60 @@ Example:
|
||||
-- alice (user@example.com) has changed host to test.com
|
||||
....
|
||||
|
||||
// TRANSLATION MISSING
|
||||
[[irc_ircv3_draft_multiline]]
|
||||
===== draft/multiline
|
||||
|
||||
Specification: https://ircv3.net/specs/extensions/multiline[multiline ^↗^,window=_blank]
|
||||
|
||||
This capability allows the client and server to send messages with multiple lines,
|
||||
using the <<irc_ircv3_batch,batch>> capability, that must be enabled as well.
|
||||
|
||||
There are limits in term of bytes or number of lines in a multiline message
|
||||
that are given in the capability sent by the server, for example:
|
||||
|
||||
....
|
||||
CAP alice LS * :draft/multiline=max-bytes=4096,max-lines=24
|
||||
....
|
||||
|
||||
This sets a limit of 4096 bytes and 24 lines for a multiline batched content.
|
||||
|
||||
If the limits are not given by the server, the default in WeeChat are:
|
||||
|
||||
* max bytes: 4096
|
||||
* max lines: 24
|
||||
|
||||
Only standard messages and those send by the <<command_irc_notice,/notice>>
|
||||
command can be multiline. +
|
||||
ACTION CTCP messages sent with command <<command_irc_me,/me>> are not affected
|
||||
by this capability. That means multiline actions are sent as multiple actions.
|
||||
|
||||
[WARNING]
|
||||
As the specification is a "draft", it may change and the multiline support can
|
||||
possibly break at any time in WeeChat. +
|
||||
The capability is automatically enabled if the server supports it and can be
|
||||
disabled with this command:
|
||||
`/set irc.server_default.capabilities "*,!draft/multiline"`. +
|
||||
When the capability is disabled, a multiline message is sent as multiple messages,
|
||||
as if they were sent sequentially to the server.
|
||||
|
||||
Example of IRC messages sent for a user message with two lines (`this is a test`
|
||||
/ `on two lines`), send to channel #test:
|
||||
|
||||
....
|
||||
BATCH +i8Je7M7gquddoyC9 draft/multiline #test
|
||||
@batch=i8Je7M7gquddoyC9 PRIVMSG #test :this is a test
|
||||
@batch=i8Je7M7gquddoyC9 PRIVMSG #test :on two lines
|
||||
BATCH -i8Je7M7gquddoyC9
|
||||
....
|
||||
|
||||
Display of the message sent in WeeChat:
|
||||
|
||||
....
|
||||
19:01:45 alice | this is a test
|
||||
| on two lines
|
||||
....
|
||||
|
||||
[[irc_ircv3_extended_join]]
|
||||
===== extended-join
|
||||
|
||||
|
||||
@@ -3564,6 +3564,7 @@ WeeChat supports the following https://ircv3.net/irc/[IRCv3 extensions ^↗^,wi
|
||||
* <<irc_ircv3_cap_notify,cap-notify>>
|
||||
* <<irc_ircv3_batch,batch>>
|
||||
* <<irc_ircv3_chghost,chghost>>
|
||||
* <<irc_ircv3_draft/multiline,draft/multiline>>
|
||||
* <<irc_ircv3_extended_join,extended-join>>
|
||||
* <<irc_ircv3_invite_notify,invite-notify>>
|
||||
* <<irc_ircv3_message_tags,message-tags>>
|
||||
@@ -3692,6 +3693,60 @@ Example:
|
||||
-- alice (user@example.com) がホストを test.com に変更しました
|
||||
....
|
||||
|
||||
// TRANSLATION MISSING
|
||||
[[irc_ircv3_draft_multiline]]
|
||||
===== draft/multiline
|
||||
|
||||
Specification: https://ircv3.net/specs/extensions/multiline[multiline ^↗^,window=_blank]
|
||||
|
||||
This capability allows the client and server to send messages with multiple lines,
|
||||
using the <<irc_ircv3_batch,batch>> capability, that must be enabled as well.
|
||||
|
||||
There are limits in term of bytes or number of lines in a multiline message
|
||||
that are given in the capability sent by the server, for example:
|
||||
|
||||
....
|
||||
CAP alice LS * :draft/multiline=max-bytes=4096,max-lines=24
|
||||
....
|
||||
|
||||
This sets a limit of 4096 bytes and 24 lines for a multiline batched content.
|
||||
|
||||
If the limits are not given by the server, the default in WeeChat are:
|
||||
|
||||
* max bytes: 4096
|
||||
* max lines: 24
|
||||
|
||||
Only standard messages and those send by the <<command_irc_notice,/notice>>
|
||||
command can be multiline. +
|
||||
ACTION CTCP messages sent with command <<command_irc_me,/me>> are not affected
|
||||
by this capability. That means multiline actions are sent as multiple actions.
|
||||
|
||||
[WARNING]
|
||||
As the specification is a "draft", it may change and the multiline support can
|
||||
possibly break at any time in WeeChat. +
|
||||
The capability is automatically enabled if the server supports it and can be
|
||||
disabled with this command:
|
||||
`/set irc.server_default.capabilities "*,!draft/multiline"`. +
|
||||
When the capability is disabled, a multiline message is sent as multiple messages,
|
||||
as if they were sent sequentially to the server.
|
||||
|
||||
Example of IRC messages sent for a user message with two lines (`this is a test`
|
||||
/ `on two lines`), send to channel #test:
|
||||
|
||||
....
|
||||
BATCH +i8Je7M7gquddoyC9 draft/multiline #test
|
||||
@batch=i8Je7M7gquddoyC9 PRIVMSG #test :this is a test
|
||||
@batch=i8Je7M7gquddoyC9 PRIVMSG #test :on two lines
|
||||
BATCH -i8Je7M7gquddoyC9
|
||||
....
|
||||
|
||||
Display of the message sent in WeeChat:
|
||||
|
||||
....
|
||||
19:01:45 alice | this is a test
|
||||
| on two lines
|
||||
....
|
||||
|
||||
[[irc_ircv3_extended_join]]
|
||||
===== extended-join
|
||||
|
||||
|
||||
@@ -3452,6 +3452,7 @@ WeeChat wspiera następujące https://ircv3.net/irc/[rozszerzenia IRCv3 ^↗^,w
|
||||
* <<irc_ircv3_batch,batch>>
|
||||
* <<irc_ircv3_cap_notify,cap-notify>>
|
||||
* <<irc_ircv3_chghost,chghost>>
|
||||
* <<irc_ircv3_draft/multiline,draft/multiline>>
|
||||
* <<irc_ircv3_extended_join,extended-join>>
|
||||
* <<irc_ircv3_invite_notify,invite-notify>>
|
||||
* <<irc_ircv3_message_tags,message-tags>>
|
||||
@@ -3580,6 +3581,60 @@ Przykłady:
|
||||
-- alice (user@example.com) zmienił hosta na test.com
|
||||
....
|
||||
|
||||
// TRANSLATION MISSING
|
||||
[[irc_ircv3_draft_multiline]]
|
||||
===== draft/multiline
|
||||
|
||||
Specification: https://ircv3.net/specs/extensions/multiline[multiline ^↗^,window=_blank]
|
||||
|
||||
This capability allows the client and server to send messages with multiple lines,
|
||||
using the <<irc_ircv3_batch,batch>> capability, that must be enabled as well.
|
||||
|
||||
There are limits in term of bytes or number of lines in a multiline message
|
||||
that are given in the capability sent by the server, for example:
|
||||
|
||||
....
|
||||
CAP alice LS * :draft/multiline=max-bytes=4096,max-lines=24
|
||||
....
|
||||
|
||||
This sets a limit of 4096 bytes and 24 lines for a multiline batched content.
|
||||
|
||||
If the limits are not given by the server, the default in WeeChat are:
|
||||
|
||||
* max bytes: 4096
|
||||
* max lines: 24
|
||||
|
||||
Only standard messages and those send by the <<command_irc_notice,/notice>>
|
||||
command can be multiline. +
|
||||
ACTION CTCP messages sent with command <<command_irc_me,/me>> are not affected
|
||||
by this capability. That means multiline actions are sent as multiple actions.
|
||||
|
||||
[WARNING]
|
||||
As the specification is a "draft", it may change and the multiline support can
|
||||
possibly break at any time in WeeChat. +
|
||||
The capability is automatically enabled if the server supports it and can be
|
||||
disabled with this command:
|
||||
`/set irc.server_default.capabilities "*,!draft/multiline"`. +
|
||||
When the capability is disabled, a multiline message is sent as multiple messages,
|
||||
as if they were sent sequentially to the server.
|
||||
|
||||
Example of IRC messages sent for a user message with two lines (`this is a test`
|
||||
/ `on two lines`), send to channel #test:
|
||||
|
||||
....
|
||||
BATCH +i8Je7M7gquddoyC9 draft/multiline #test
|
||||
@batch=i8Je7M7gquddoyC9 PRIVMSG #test :this is a test
|
||||
@batch=i8Je7M7gquddoyC9 PRIVMSG #test :on two lines
|
||||
BATCH -i8Je7M7gquddoyC9
|
||||
....
|
||||
|
||||
Display of the message sent in WeeChat:
|
||||
|
||||
....
|
||||
19:01:45 alice | this is a test
|
||||
| on two lines
|
||||
....
|
||||
|
||||
[[irc_ircv3_extended_join]]
|
||||
===== extended-join
|
||||
|
||||
|
||||
@@ -3202,6 +3202,7 @@ WeeChat подржава следећа https://ircv3.net/irc/[IRCv3 проши
|
||||
* <<irc_ircv3_batch,batch>>
|
||||
* <<irc_ircv3_cap_notify,cap-notify>>
|
||||
* <<irc_ircv3_chghost,chghost>>
|
||||
* <<irc_ircv3_draft/multiline,draft/multiline>>
|
||||
* <<irc_ircv3_extended_join,extended-join>>
|
||||
* <<irc_ircv3_invite_notify,invite-notify>>
|
||||
* <<irc_ircv3_message_tags,message-tags>>
|
||||
@@ -3328,6 +3329,60 @@ later, when the batch ends.
|
||||
-- alice (user@example.com) је променио свој хост на test.com
|
||||
....
|
||||
|
||||
// TRANSLATION MISSING
|
||||
[[irc_ircv3_draft_multiline]]
|
||||
===== draft/multiline
|
||||
|
||||
Specification: https://ircv3.net/specs/extensions/multiline[multiline ^↗^,window=_blank]
|
||||
|
||||
This capability allows the client and server to send messages with multiple lines,
|
||||
using the <<irc_ircv3_batch,batch>> capability, that must be enabled as well.
|
||||
|
||||
There are limits in term of bytes or number of lines in a multiline message
|
||||
that are given in the capability sent by the server, for example:
|
||||
|
||||
....
|
||||
CAP alice LS * :draft/multiline=max-bytes=4096,max-lines=24
|
||||
....
|
||||
|
||||
This sets a limit of 4096 bytes and 24 lines for a multiline batched content.
|
||||
|
||||
If the limits are not given by the server, the default in WeeChat are:
|
||||
|
||||
* max bytes: 4096
|
||||
* max lines: 24
|
||||
|
||||
Only standard messages and those send by the <<command_irc_notice,/notice>>
|
||||
command can be multiline. +
|
||||
ACTION CTCP messages sent with command <<command_irc_me,/me>> are not affected
|
||||
by this capability. That means multiline actions are sent as multiple actions.
|
||||
|
||||
[WARNING]
|
||||
As the specification is a "draft", it may change and the multiline support can
|
||||
possibly break at any time in WeeChat. +
|
||||
The capability is automatically enabled if the server supports it and can be
|
||||
disabled with this command:
|
||||
`/set irc.server_default.capabilities "*,!draft/multiline"`. +
|
||||
When the capability is disabled, a multiline message is sent as multiple messages,
|
||||
as if they were sent sequentially to the server.
|
||||
|
||||
Example of IRC messages sent for a user message with two lines (`this is a test`
|
||||
/ `on two lines`), send to channel #test:
|
||||
|
||||
....
|
||||
BATCH +i8Je7M7gquddoyC9 draft/multiline #test
|
||||
@batch=i8Je7M7gquddoyC9 PRIVMSG #test :this is a test
|
||||
@batch=i8Je7M7gquddoyC9 PRIVMSG #test :on two lines
|
||||
BATCH -i8Je7M7gquddoyC9
|
||||
....
|
||||
|
||||
Display of the message sent in WeeChat:
|
||||
|
||||
....
|
||||
19:01:45 alice | this is a test
|
||||
| on two lines
|
||||
....
|
||||
|
||||
[[irc_ircv3_extended_join]]
|
||||
===== extended-join
|
||||
|
||||
|
||||
+194
-3
@@ -30,7 +30,9 @@
|
||||
#include "irc-batch.h"
|
||||
#include "irc-message.h"
|
||||
#include "irc-protocol.h"
|
||||
#include "irc-raw.h"
|
||||
#include "irc-server.h"
|
||||
#include "irc-tag.h"
|
||||
|
||||
|
||||
/*
|
||||
@@ -58,6 +60,31 @@ irc_batch_search (struct t_irc_server *server, const char *reference)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generates a random batch reference with `size` chars (the next one is the
|
||||
* final '\0', so the string must be at least size + 1 bytes long).
|
||||
*/
|
||||
|
||||
void
|
||||
irc_batch_generate_random_ref (char *string, int size)
|
||||
{
|
||||
const char *chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"0123456789";
|
||||
|
||||
int i, length_chars;
|
||||
|
||||
if (!string || (size < 0))
|
||||
return;
|
||||
|
||||
length_chars = strlen (chars);
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
string[i] = chars[rand() % length_chars];
|
||||
}
|
||||
string[size] = '\0';
|
||||
}
|
||||
|
||||
/*
|
||||
* Adds a batch to list of batched events.
|
||||
*/
|
||||
@@ -199,6 +226,7 @@ irc_batch_process_messages (struct t_irc_server *server,
|
||||
struct t_irc_batch *batch)
|
||||
{
|
||||
char **list_messages, *command, *channel, modifier_data[1024], *new_messages;
|
||||
char *message;
|
||||
int i, count_messages;
|
||||
|
||||
if (!batch || !batch->messages)
|
||||
@@ -229,8 +257,12 @@ irc_batch_process_messages (struct t_irc_server *server,
|
||||
{
|
||||
for (i = 0; i < count_messages; i++)
|
||||
{
|
||||
message = weechat_string_replace (list_messages[i], "\r", "\n");
|
||||
if (!message)
|
||||
continue;
|
||||
|
||||
irc_message_parse (server,
|
||||
list_messages[i],
|
||||
message,
|
||||
NULL, /* tags */
|
||||
NULL, /* message_without_tags */
|
||||
NULL, /* nick */
|
||||
@@ -246,9 +278,15 @@ irc_batch_process_messages (struct t_irc_server *server,
|
||||
NULL, /* pos_arguments */
|
||||
NULL, /* pos_channel */
|
||||
NULL); /* pos_text */
|
||||
|
||||
/* add raw message */
|
||||
irc_raw_print (server, IRC_RAW_FLAG_RECV, message);
|
||||
|
||||
/* call receive callback, ignoring batch tags */
|
||||
irc_protocol_recv_command (server, list_messages[i], command,
|
||||
channel, 1);
|
||||
irc_protocol_recv_command (server, message, command, channel, 1);
|
||||
|
||||
if (message)
|
||||
free (message);
|
||||
if (command)
|
||||
free (command);
|
||||
if (channel)
|
||||
@@ -317,6 +355,159 @@ irc_batch_end_batch (struct t_irc_server *server, const char *reference)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Processes multiline batch: convert multiple messages into a single one,
|
||||
* that can include newline chars ("\r" that are converted later to "\n").
|
||||
*
|
||||
* Parameter "target" is the batch target (channel or nick name).
|
||||
*
|
||||
* Note: result must be freed after use.
|
||||
*/
|
||||
|
||||
char *
|
||||
irc_batch_process_multiline (struct t_irc_server *server,
|
||||
const char *messages, const char *target)
|
||||
{
|
||||
char **result, **list_messages;
|
||||
char *tags, *host, *command, *channel, *text;
|
||||
int i, count_messages;
|
||||
struct t_hashtable *hash_tags;
|
||||
|
||||
result = weechat_string_dyn_alloc (256);
|
||||
|
||||
list_messages = weechat_string_split (messages, "\n", NULL, 0, 0,
|
||||
&count_messages);
|
||||
if (!list_messages)
|
||||
goto end;
|
||||
|
||||
hash_tags = weechat_hashtable_new (32,
|
||||
WEECHAT_HASHTABLE_STRING,
|
||||
WEECHAT_HASHTABLE_STRING,
|
||||
NULL, NULL);
|
||||
|
||||
for (i = 0; i < count_messages; i++)
|
||||
{
|
||||
irc_message_parse (server,
|
||||
list_messages[i],
|
||||
&tags,
|
||||
NULL, /* message_without_tags */
|
||||
NULL, /* nick */
|
||||
NULL, /* user */
|
||||
&host,
|
||||
&command,
|
||||
&channel,
|
||||
NULL, /* arguments */
|
||||
&text,
|
||||
NULL, /* params */
|
||||
NULL, /* num_params */
|
||||
NULL, /* pos_command */
|
||||
NULL, /* pos_arguments */
|
||||
NULL, /* pos_channel */
|
||||
NULL); /* pos_text */
|
||||
if (host
|
||||
&& command
|
||||
&& ((strcmp (command, "PRIVMSG") == 0)
|
||||
|| (strcmp (command, "NOTICE") == 0))
|
||||
&& channel
|
||||
&& (strcmp (channel, target) == 0))
|
||||
{
|
||||
if (hash_tags)
|
||||
{
|
||||
weechat_hashtable_remove_all (hash_tags);
|
||||
if (tags && tags[0])
|
||||
irc_tag_parse (tags, hash_tags, NULL);
|
||||
}
|
||||
if (*result[0])
|
||||
{
|
||||
if (!hash_tags
|
||||
|| !weechat_hashtable_has_key (hash_tags,
|
||||
"draft/multiline-concat"))
|
||||
{
|
||||
weechat_string_dyn_concat (result, "\r", -1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tags && tags[0])
|
||||
{
|
||||
weechat_string_dyn_concat (result, "@", -1);
|
||||
weechat_string_dyn_concat (result, tags, -1);
|
||||
weechat_string_dyn_concat (result, " ", -1);
|
||||
}
|
||||
weechat_string_dyn_concat (result, ":", -1);
|
||||
weechat_string_dyn_concat (result, host, -1);
|
||||
weechat_string_dyn_concat (result, " ", -1);
|
||||
weechat_string_dyn_concat (result, command, -1);
|
||||
weechat_string_dyn_concat (result, " ", -1);
|
||||
weechat_string_dyn_concat (result, target, -1);
|
||||
weechat_string_dyn_concat (result, " :", -1);
|
||||
}
|
||||
if (text)
|
||||
weechat_string_dyn_concat (result, text, -1);
|
||||
}
|
||||
if (tags)
|
||||
free (tags);
|
||||
if (host)
|
||||
free (host);
|
||||
if (command)
|
||||
free (command);
|
||||
if (channel)
|
||||
free (channel);
|
||||
if (text)
|
||||
free (text);
|
||||
}
|
||||
|
||||
end:
|
||||
if (hash_tags)
|
||||
weechat_hashtable_free (hash_tags);
|
||||
if (list_messages)
|
||||
weechat_string_free_split (list_messages);
|
||||
|
||||
return weechat_string_dyn_free (result, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Callback for modifier "irc_batch".
|
||||
*/
|
||||
|
||||
char *
|
||||
irc_batch_modifier_cb (const void *pointer, void *data,
|
||||
const char *modifier, const char *modifier_data,
|
||||
const char *string)
|
||||
{
|
||||
struct t_irc_server *ptr_server;
|
||||
char **items, *result;
|
||||
int num_items;
|
||||
|
||||
/* make C compiler happy */
|
||||
(void) pointer;
|
||||
(void) data;
|
||||
(void) modifier;
|
||||
|
||||
result = NULL;
|
||||
|
||||
if (!modifier_data)
|
||||
return NULL;
|
||||
|
||||
items = weechat_string_split (modifier_data, ",", NULL, 0, 3, &num_items);
|
||||
if (!items)
|
||||
return NULL;
|
||||
|
||||
if (items && (num_items > 1))
|
||||
{
|
||||
ptr_server = irc_server_search (items[0]);
|
||||
if (ptr_server && (num_items > 2)
|
||||
&& (strcmp (items[1], "draft/multiline") == 0))
|
||||
{
|
||||
result = irc_batch_process_multiline (ptr_server, string, items[2]);
|
||||
}
|
||||
}
|
||||
if (items)
|
||||
weechat_string_free_split (items);
|
||||
|
||||
return (result) ? result : strdup (string);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns hdata for batch.
|
||||
*/
|
||||
|
||||
@@ -39,6 +39,7 @@ struct t_irc_batch
|
||||
struct t_irc_batch *next_batch; /* link to next batch */
|
||||
};
|
||||
|
||||
extern void irc_batch_generate_random_ref (char *string, int size);
|
||||
extern struct t_irc_batch *irc_batch_search (struct t_irc_server *server,
|
||||
const char *reference);
|
||||
extern struct t_irc_batch *irc_batch_start_batch (struct t_irc_server *server,
|
||||
@@ -54,6 +55,11 @@ extern void irc_batch_end_batch (struct t_irc_server *server,
|
||||
extern void irc_batch_free (struct t_irc_server *server,
|
||||
struct t_irc_batch *batch);
|
||||
extern void irc_batch_free_all (struct t_irc_server *server);
|
||||
extern char *irc_batch_modifier_cb (const void *pointer, void *data,
|
||||
const char *modifier,
|
||||
const char *modifier_data,
|
||||
const char *string);
|
||||
|
||||
extern struct t_hdata *irc_batch_hdata_batch_cb (const void *pointer,
|
||||
void *data,
|
||||
const char *hdata_name);
|
||||
|
||||
@@ -330,6 +330,7 @@ irc_channel_create_buffer (struct t_irc_server *server,
|
||||
|
||||
if (buffer_created)
|
||||
{
|
||||
weechat_buffer_set (ptr_buffer, "input_multiline", "1");
|
||||
if (!weechat_buffer_get_integer (ptr_buffer, "short_name_is_set"))
|
||||
weechat_buffer_set (ptr_buffer, "short_name", channel_name);
|
||||
}
|
||||
|
||||
@@ -1105,27 +1105,38 @@ irc_command_me_channel (struct t_irc_server *server,
|
||||
const char *arguments)
|
||||
{
|
||||
struct t_arraylist *list_messages;
|
||||
int i, list_size;
|
||||
char **list_arguments;
|
||||
int i, j, list_size, count_arguments;
|
||||
|
||||
list_messages = irc_server_sendf (
|
||||
server,
|
||||
IRC_SERVER_SEND_OUTQ_PRIO_HIGH | IRC_SERVER_SEND_RETURN_LIST,
|
||||
NULL,
|
||||
"PRIVMSG %s :\01ACTION %s\01",
|
||||
channel->name,
|
||||
(arguments && arguments[0]) ? arguments : "");
|
||||
if (list_messages)
|
||||
list_arguments = weechat_string_split ((arguments) ? arguments : "",
|
||||
"\n", NULL, 0, 0, &count_arguments);
|
||||
if (!list_arguments)
|
||||
return;
|
||||
|
||||
for (i = 0; i < count_arguments; i++)
|
||||
{
|
||||
list_size = weechat_arraylist_size (list_messages);
|
||||
for (i = 0; i < list_size; i++)
|
||||
list_messages = irc_server_sendf (
|
||||
server,
|
||||
IRC_SERVER_SEND_OUTQ_PRIO_HIGH | IRC_SERVER_SEND_RETURN_LIST,
|
||||
NULL,
|
||||
"PRIVMSG %s :\01ACTION %s\01",
|
||||
channel->name,
|
||||
list_arguments[i]);
|
||||
if (list_messages)
|
||||
{
|
||||
irc_command_me_channel_display (
|
||||
server,
|
||||
channel,
|
||||
(const char *)weechat_arraylist_get (list_messages, i));
|
||||
list_size = weechat_arraylist_size (list_messages);
|
||||
for (j = 0; j < list_size; j++)
|
||||
{
|
||||
irc_command_me_channel_display (
|
||||
server,
|
||||
channel,
|
||||
(const char *)weechat_arraylist_get (list_messages, j));
|
||||
}
|
||||
weechat_arraylist_free (list_messages);
|
||||
}
|
||||
weechat_arraylist_free (list_messages);
|
||||
}
|
||||
|
||||
weechat_string_free_split (list_arguments);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -6950,8 +6961,8 @@ irc_command_init ()
|
||||
"\n"
|
||||
"Capabilities supported by WeeChat are: "
|
||||
"account-notify, away-notify, batch, cap-notify, chghost, "
|
||||
"extended-join, invite-notify, message-tags, multi-prefix, "
|
||||
"server-time, setname, userhost-in-names.\n"
|
||||
"draft/multiline, extended-join, invite-notify, message-tags, "
|
||||
"multi-prefix, server-time, setname, userhost-in-names.\n"
|
||||
"\n"
|
||||
"The capabilities to automatically enable on servers can be set "
|
||||
"in option irc.server_default.capabilities (or by server in "
|
||||
|
||||
@@ -59,8 +59,8 @@ struct t_irc_channel;
|
||||
*/
|
||||
#define IRC_COMMAND_CAP_SUPPORTED \
|
||||
"account-notify|away-notify|batch|cap-notify|chghost|" \
|
||||
"extended-join|invite-notify|message-tags|multi-prefix|" \
|
||||
"server-time|setname|userhost-in-names"
|
||||
"draft/multiline|extended-join|invite-notify|message-tags|" \
|
||||
"multi-prefix|server-time|setname|userhost-in-names"
|
||||
|
||||
/* list of supported CTCPs (for completion in command /ctcp) */
|
||||
#define IRC_COMMAND_CTCP_SUPPORTED_COMPLETION \
|
||||
|
||||
+355
-94
@@ -26,6 +26,8 @@
|
||||
|
||||
#include "../weechat-plugin.h"
|
||||
#include "irc.h"
|
||||
#include "irc-message.h"
|
||||
#include "irc-batch.h"
|
||||
#include "irc-channel.h"
|
||||
#include "irc-color.h"
|
||||
#include "irc-config.h"
|
||||
@@ -529,6 +531,112 @@ irc_message_parse_to_hashtable (struct t_irc_server *server,
|
||||
return hashtable;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parses capability value.
|
||||
*
|
||||
* For example for this capability:
|
||||
* draft/multiline=max-bytes=4096,max-lines=24
|
||||
*
|
||||
* The input value must be: "max-bytes=4096,max-lines=24"
|
||||
* The output is a hashtable with following keys/values (as strings):
|
||||
*
|
||||
* "max-bytes": "4096"
|
||||
* "max-lines": "24"
|
||||
*
|
||||
* Note: hashtable must be freed after use.
|
||||
*/
|
||||
|
||||
struct t_hashtable *
|
||||
irc_message_parse_cap_value (const char *value)
|
||||
{
|
||||
struct t_hashtable *hashtable;
|
||||
char **items, *key;
|
||||
const char *pos;
|
||||
int i, count_items;
|
||||
|
||||
if (!value)
|
||||
return NULL;
|
||||
|
||||
hashtable = weechat_hashtable_new (32,
|
||||
WEECHAT_HASHTABLE_STRING,
|
||||
WEECHAT_HASHTABLE_STRING,
|
||||
NULL, NULL);
|
||||
if (!hashtable)
|
||||
return NULL;
|
||||
|
||||
items = weechat_string_split (value, ",", NULL, 0, 0, &count_items);
|
||||
if (items)
|
||||
{
|
||||
for (i = 0; i < count_items; i++)
|
||||
{
|
||||
pos = strchr (items[i], '=');
|
||||
if (pos)
|
||||
{
|
||||
key = weechat_strndup (items[i], pos - items[i]);
|
||||
if (key)
|
||||
{
|
||||
weechat_hashtable_set (hashtable, key, pos + 1);
|
||||
free (key);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
weechat_hashtable_set (hashtable, items[i], NULL);
|
||||
}
|
||||
}
|
||||
weechat_string_free_split (items);
|
||||
}
|
||||
|
||||
return hashtable;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parses "draft/multiline" cap value and extract:
|
||||
* - max-bytes: maximum allowed total byte length of multiline batched content
|
||||
* - max-lines: maximum allowed number of lines in a multiline batch content
|
||||
*/
|
||||
|
||||
void
|
||||
irc_message_parse_cap_multiline_value (struct t_irc_server *server,
|
||||
const char *value)
|
||||
{
|
||||
struct t_hashtable *values;
|
||||
const char *ptr_value;
|
||||
char *error;
|
||||
long number;
|
||||
|
||||
if (!server)
|
||||
return;
|
||||
|
||||
server->multiline_max_bytes = IRC_SERVER_MULTILINE_DEFAULT_MAX_BYTES;
|
||||
server->multiline_max_lines = IRC_SERVER_MULTILINE_DEFAULT_MAX_LINES;
|
||||
|
||||
if (!value)
|
||||
return;
|
||||
|
||||
values = irc_message_parse_cap_value (value);
|
||||
if (!values)
|
||||
return;
|
||||
|
||||
ptr_value = (const char *)weechat_hashtable_get (values, "max-bytes");
|
||||
if (ptr_value)
|
||||
{
|
||||
number = strtol (ptr_value, &error, 10);
|
||||
if (error && !error[0])
|
||||
server->multiline_max_bytes = number;
|
||||
}
|
||||
|
||||
ptr_value = (const char *)weechat_hashtable_get (values, "max-lines");
|
||||
if (ptr_value)
|
||||
{
|
||||
number = strtol (ptr_value, &error, 10);
|
||||
if (error && !error[0])
|
||||
server->multiline_max_lines = number;
|
||||
}
|
||||
|
||||
weechat_hashtable_free (values);
|
||||
}
|
||||
|
||||
/*
|
||||
* Encodes/decodes an IRC message using a charset.
|
||||
*
|
||||
@@ -762,24 +870,27 @@ irc_message_replace_vars (struct t_irc_server *server,
|
||||
*/
|
||||
|
||||
void
|
||||
irc_message_split_add (struct t_hashtable *hashtable, int number,
|
||||
irc_message_split_add (struct t_irc_message_split_context *context,
|
||||
const char *tags, const char *message,
|
||||
const char *arguments)
|
||||
{
|
||||
char key[32], value[32], *buf;
|
||||
int length;
|
||||
|
||||
if (!context)
|
||||
return;
|
||||
|
||||
if (message)
|
||||
{
|
||||
length = ((tags) ? strlen (tags) : 0) + strlen (message) + 1;
|
||||
buf = malloc (length);
|
||||
if (buf)
|
||||
{
|
||||
snprintf (key, sizeof (key), "msg%d", number);
|
||||
snprintf (key, sizeof (key), "msg%d", context->number);
|
||||
snprintf (buf, length, "%s%s",
|
||||
(tags) ? tags : "",
|
||||
message);
|
||||
weechat_hashtable_set (hashtable, key, buf);
|
||||
weechat_hashtable_set (context->hashtable, key, buf);
|
||||
if (weechat_irc_plugin->debug >= 2)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
@@ -787,12 +898,13 @@ irc_message_split_add (struct t_hashtable *hashtable, int number,
|
||||
key, buf, length - 1);
|
||||
}
|
||||
free (buf);
|
||||
context->total_bytes += length;
|
||||
}
|
||||
}
|
||||
if (arguments)
|
||||
{
|
||||
snprintf (key, sizeof (key), "args%d", number);
|
||||
weechat_hashtable_set (hashtable, key, arguments);
|
||||
snprintf (key, sizeof (key), "args%d", context->number);
|
||||
weechat_hashtable_set (context->hashtable, key, arguments);
|
||||
if (weechat_irc_plugin->debug >= 2)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
@@ -800,8 +912,8 @@ irc_message_split_add (struct t_hashtable *hashtable, int number,
|
||||
key, arguments);
|
||||
}
|
||||
}
|
||||
snprintf (value, sizeof (value), "%d", number);
|
||||
weechat_hashtable_set (hashtable, "count", value);
|
||||
snprintf (value, sizeof (value), "%d", context->number);
|
||||
weechat_hashtable_set (context->hashtable, "count", value);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -837,7 +949,7 @@ irc_message_split_add (struct t_hashtable *hashtable, int number,
|
||||
*/
|
||||
|
||||
int
|
||||
irc_message_split_string (struct t_hashtable *hashtable,
|
||||
irc_message_split_string (struct t_irc_message_split_context *context,
|
||||
const char *tags,
|
||||
const char *host,
|
||||
const char *command,
|
||||
@@ -851,7 +963,9 @@ irc_message_split_string (struct t_hashtable *hashtable,
|
||||
{
|
||||
const char *pos, *pos_max, *pos_next, *pos_last_delim;
|
||||
char message[8192], *dup_arguments;
|
||||
int number;
|
||||
|
||||
if (!context)
|
||||
return 0;
|
||||
|
||||
max_length -= 2; /* by default: 512 - 2 = 510 bytes */
|
||||
if (max_length_nick_user_host >= 0)
|
||||
@@ -880,8 +994,6 @@ irc_message_split_string (struct t_hashtable *hashtable,
|
||||
max_length);
|
||||
}
|
||||
|
||||
number = 1;
|
||||
|
||||
if (!arguments || !arguments[0])
|
||||
{
|
||||
snprintf (message, sizeof (message), "%s%s%s %s%s%s%s",
|
||||
@@ -892,7 +1004,8 @@ irc_message_split_string (struct t_hashtable *hashtable,
|
||||
(target && target[0]) ? " " : "",
|
||||
(prefix) ? prefix : "",
|
||||
(suffix) ? suffix : "");
|
||||
irc_message_split_add (hashtable, 1, tags, message, "");
|
||||
irc_message_split_add (context, tags, message, "");
|
||||
(context->number)++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -924,9 +1037,8 @@ irc_message_split_string (struct t_hashtable *hashtable,
|
||||
(prefix) ? prefix : "",
|
||||
dup_arguments,
|
||||
(suffix) ? suffix : "");
|
||||
irc_message_split_add (hashtable, number, tags, message,
|
||||
dup_arguments);
|
||||
number++;
|
||||
irc_message_split_add (context, tags, message, dup_arguments);
|
||||
(context->number)++;
|
||||
free (dup_arguments);
|
||||
}
|
||||
arguments = (pos == pos_last_delim) ? pos + 1 : pos;
|
||||
@@ -945,16 +1057,14 @@ irc_message_split_string (struct t_hashtable *hashtable,
|
||||
*/
|
||||
|
||||
int
|
||||
irc_message_split_authenticate (struct t_hashtable *hashtable,
|
||||
irc_message_split_authenticate (struct t_irc_message_split_context *context,
|
||||
const char *tags, const char *host,
|
||||
const char *command, const char *arguments)
|
||||
{
|
||||
int number, length;
|
||||
int length;
|
||||
char message[8192], *args;
|
||||
const char *ptr_args;
|
||||
|
||||
number = 1;
|
||||
|
||||
length = 0;
|
||||
ptr_args = arguments;
|
||||
while (ptr_args && ptr_args[0])
|
||||
@@ -972,9 +1082,9 @@ irc_message_split_authenticate (struct t_hashtable *hashtable,
|
||||
(host) ? " " : "",
|
||||
command,
|
||||
args);
|
||||
irc_message_split_add (hashtable, number, tags, message, args);
|
||||
irc_message_split_add (context, tags, message, args);
|
||||
free (args);
|
||||
number++;
|
||||
(context->number)++;
|
||||
ptr_args += length;
|
||||
}
|
||||
|
||||
@@ -984,8 +1094,8 @@ irc_message_split_authenticate (struct t_hashtable *hashtable,
|
||||
(host) ? host : "",
|
||||
(host) ? " " : "",
|
||||
command);
|
||||
irc_message_split_add (hashtable, number, tags, message, "+");
|
||||
number++;
|
||||
irc_message_split_add (context, tags, message, "+");
|
||||
(context->number)++;
|
||||
}
|
||||
|
||||
return 1;
|
||||
@@ -1001,20 +1111,18 @@ irc_message_split_authenticate (struct t_hashtable *hashtable,
|
||||
*/
|
||||
|
||||
int
|
||||
irc_message_split_join (struct t_hashtable *hashtable,
|
||||
irc_message_split_join (struct t_irc_message_split_context *context,
|
||||
const char *tags, const char *host,
|
||||
const char *arguments,
|
||||
int max_length)
|
||||
{
|
||||
int number, channels_count, keys_count, length, length_no_channel;
|
||||
int channels_count, keys_count, length, length_no_channel;
|
||||
int length_to_add, index_channel;
|
||||
char **channels, **keys, *pos, *str;
|
||||
char msg_to_send[16384], keys_to_add[16384];
|
||||
|
||||
max_length -= 2; /* by default: 512 - 2 = 510 bytes */
|
||||
|
||||
number = 1;
|
||||
|
||||
channels = NULL;
|
||||
channels_count = 0;
|
||||
keys = NULL;
|
||||
@@ -1087,11 +1195,11 @@ irc_message_split_join (struct t_hashtable *hashtable,
|
||||
else
|
||||
{
|
||||
strcat (msg_to_send, keys_to_add);
|
||||
irc_message_split_add (hashtable, number,
|
||||
irc_message_split_add (context,
|
||||
tags,
|
||||
msg_to_send,
|
||||
msg_to_send + length_no_channel + 1);
|
||||
number++;
|
||||
(context->number)++;
|
||||
snprintf (msg_to_send, sizeof (msg_to_send), "%s%sJOIN",
|
||||
(host) ? host : "",
|
||||
(host) ? " " : "");
|
||||
@@ -1103,7 +1211,7 @@ irc_message_split_join (struct t_hashtable *hashtable,
|
||||
if (length > length_no_channel)
|
||||
{
|
||||
strcat (msg_to_send, keys_to_add);
|
||||
irc_message_split_add (hashtable, number,
|
||||
irc_message_split_add (context,
|
||||
tags,
|
||||
msg_to_send,
|
||||
msg_to_send + length_no_channel + 1);
|
||||
@@ -1117,26 +1225,79 @@ irc_message_split_join (struct t_hashtable *hashtable,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Starts batch for multiline message.
|
||||
*/
|
||||
|
||||
void
|
||||
irc_message_start_batch (struct t_irc_message_split_context *context,
|
||||
const char *target, const char *batch_ref)
|
||||
{
|
||||
char msg_batch[4096], args_batch[4096];
|
||||
|
||||
snprintf (msg_batch, sizeof (msg_batch),
|
||||
"BATCH +%s draft/multiline %s",
|
||||
batch_ref,
|
||||
target);
|
||||
snprintf (args_batch, sizeof (args_batch),
|
||||
"+%s draft/multiline %s",
|
||||
batch_ref,
|
||||
target);
|
||||
irc_message_split_add (context, NULL, msg_batch, args_batch);
|
||||
(context->number)++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ends batch for multiline message.
|
||||
*/
|
||||
|
||||
void
|
||||
irc_message_end_batch (struct t_irc_message_split_context *context,
|
||||
const char *batch_ref)
|
||||
{
|
||||
char msg_batch[4096], args_batch[4096];
|
||||
|
||||
snprintf (msg_batch, sizeof (msg_batch),
|
||||
"BATCH -%s",
|
||||
batch_ref);
|
||||
snprintf (args_batch, sizeof (args_batch),
|
||||
"-%s",
|
||||
batch_ref);
|
||||
irc_message_split_add (context, NULL, msg_batch, args_batch);
|
||||
(context->number)++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Splits a PRIVMSG or NOTICE message, taking care of keeping the '\01' char
|
||||
* used in CTCP messages.
|
||||
*
|
||||
* If multiline == 1, the message is split on newline chars ('\n') and is sent
|
||||
* using BATCH command (to group messages together).
|
||||
*
|
||||
* Returns:
|
||||
* 1: OK
|
||||
* 0: error
|
||||
*/
|
||||
|
||||
int
|
||||
irc_message_split_privmsg_notice (struct t_hashtable *hashtable,
|
||||
const char *tags, const char *host,
|
||||
const char *command, const char *target,
|
||||
irc_message_split_privmsg_notice (struct t_irc_message_split_context *context,
|
||||
const char *tags,
|
||||
const char *host,
|
||||
const char *command,
|
||||
const char *target,
|
||||
const char *arguments,
|
||||
int max_length_nick_user_host,
|
||||
int max_length)
|
||||
int max_length,
|
||||
int multiline,
|
||||
int multiline_max_bytes,
|
||||
int multiline_max_lines)
|
||||
{
|
||||
char *arguments2, prefix[4096], suffix[2], *pos, saved_char;
|
||||
char prefix[4096], suffix[2], *pos, saved_char, name[256];
|
||||
char tags_multiline[4096], **list_lines, batch_ref[16 + 1];
|
||||
char **multiline_args;
|
||||
const char *ptr_args;
|
||||
int length, rc;
|
||||
int i, length, length_tags, rc, count_lines, batch_lines;
|
||||
int index_multiline_args;
|
||||
|
||||
/*
|
||||
* message sent looks like:
|
||||
@@ -1146,41 +1307,122 @@ irc_message_split_privmsg_notice (struct t_hashtable *hashtable,
|
||||
* :nick!user@host.com PRIVMSG #channel :hello world!
|
||||
*/
|
||||
|
||||
arguments2 = strdup (arguments);
|
||||
if (!arguments2)
|
||||
return 0;
|
||||
rc = 1;
|
||||
|
||||
ptr_args = arguments2;
|
||||
|
||||
/* for CTCP, prefix will be ":\01xxxx " and suffix "\01" */
|
||||
prefix[0] = '\0';
|
||||
suffix[0] = '\0';
|
||||
length = strlen (arguments2);
|
||||
if ((arguments2[0] == '\01')
|
||||
&& (arguments2[length - 1] == '\01'))
|
||||
if (multiline)
|
||||
{
|
||||
pos = strchr (arguments2, ' ');
|
||||
if (pos)
|
||||
index_multiline_args = 1;
|
||||
multiline_args = weechat_string_dyn_alloc (256);
|
||||
if (!multiline_args)
|
||||
return 0;
|
||||
|
||||
irc_batch_generate_random_ref (batch_ref, sizeof (batch_ref) - 1);
|
||||
|
||||
/* start batch */
|
||||
irc_message_start_batch (context, target, batch_ref);
|
||||
|
||||
/* add messages */
|
||||
list_lines = weechat_string_split (arguments, "\n", NULL, 0, 0,
|
||||
&count_lines);
|
||||
if (list_lines)
|
||||
{
|
||||
pos++;
|
||||
saved_char = pos[0];
|
||||
pos[0] = '\0';
|
||||
snprintf (prefix, sizeof (prefix), ":%s", arguments2);
|
||||
pos[0] = saved_char;
|
||||
arguments2[length - 1] = '\0';
|
||||
ptr_args = pos;
|
||||
suffix[0] = '\01';
|
||||
suffix[1] = '\0';
|
||||
batch_lines = 0;
|
||||
for (i = 0; i < count_lines; i++)
|
||||
{
|
||||
if (tags && tags[0])
|
||||
{
|
||||
snprintf (tags_multiline, sizeof (tags_multiline),
|
||||
"@batch=%s;%s",
|
||||
batch_ref,
|
||||
tags + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf (tags_multiline, sizeof (tags_multiline),
|
||||
"@batch=%s ",
|
||||
batch_ref);
|
||||
}
|
||||
length_tags = strlen (tags_multiline);
|
||||
rc &= irc_message_split_string (
|
||||
context, tags_multiline, host, command, target, ":",
|
||||
list_lines[i], "", ' ', max_length_nick_user_host,
|
||||
max_length);
|
||||
if (batch_lines > 0)
|
||||
weechat_string_dyn_concat (multiline_args, "\n", -1);
|
||||
weechat_string_dyn_concat (multiline_args,
|
||||
list_lines[i], -1);
|
||||
batch_lines++;
|
||||
if ((i < count_lines - 1)
|
||||
&& ((batch_lines >= multiline_max_lines)
|
||||
|| (context->total_bytes + length_tags
|
||||
+ (int)strlen (list_lines[i + 1]) >= multiline_max_bytes)))
|
||||
{
|
||||
/* start new batch if we have reached max lines/bytes */
|
||||
irc_message_end_batch (context, batch_ref);
|
||||
snprintf (name, sizeof (name),
|
||||
"multiline_args%d", index_multiline_args);
|
||||
weechat_hashtable_set (context->hashtable, name,
|
||||
*multiline_args);
|
||||
weechat_string_dyn_copy (multiline_args, NULL);
|
||||
index_multiline_args++;
|
||||
irc_batch_generate_random_ref (batch_ref,
|
||||
sizeof (batch_ref) - 1);
|
||||
context->total_bytes = 0;
|
||||
irc_message_start_batch (context, target, batch_ref);
|
||||
batch_lines = 0;
|
||||
}
|
||||
}
|
||||
weechat_string_free_split (list_lines);
|
||||
}
|
||||
|
||||
/* end batch */
|
||||
irc_message_end_batch (context, batch_ref);
|
||||
|
||||
snprintf (name, sizeof (name),
|
||||
"multiline_args%d", index_multiline_args);
|
||||
weechat_hashtable_set (context->hashtable, name, *multiline_args);
|
||||
weechat_string_dyn_free (multiline_args, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
list_lines = weechat_string_split (arguments, "\n", NULL, 0, 0,
|
||||
&count_lines);
|
||||
if (list_lines)
|
||||
{
|
||||
for (i = 0; i < count_lines; i++)
|
||||
{
|
||||
/* for CTCP, prefix is ":\01xxxx " and suffix "\01" */
|
||||
prefix[0] = '\0';
|
||||
suffix[0] = '\0';
|
||||
ptr_args = list_lines[i];
|
||||
length = strlen (list_lines[i]);
|
||||
if ((list_lines[i][0] == '\01')
|
||||
&& (list_lines[i][length - 1] == '\01'))
|
||||
{
|
||||
pos = strchr (list_lines[i], ' ');
|
||||
if (pos)
|
||||
{
|
||||
pos++;
|
||||
saved_char = pos[0];
|
||||
pos[0] = '\0';
|
||||
snprintf (prefix, sizeof (prefix), ":%s", list_lines[i]);
|
||||
pos[0] = saved_char;
|
||||
list_lines[i][length - 1] = '\0';
|
||||
ptr_args = pos;
|
||||
suffix[0] = '\01';
|
||||
suffix[1] = '\0';
|
||||
}
|
||||
}
|
||||
if (!prefix[0])
|
||||
strcpy (prefix, ":");
|
||||
rc = irc_message_split_string (context, tags, host, command, target,
|
||||
prefix, ptr_args, suffix,
|
||||
' ', max_length_nick_user_host,
|
||||
max_length);
|
||||
}
|
||||
weechat_string_free_split (list_lines);
|
||||
}
|
||||
}
|
||||
if (!prefix[0])
|
||||
strcpy (prefix, ":");
|
||||
|
||||
rc = irc_message_split_string (hashtable, tags, host, command, target,
|
||||
prefix, ptr_args, suffix,
|
||||
' ', max_length_nick_user_host, max_length);
|
||||
|
||||
free (arguments2);
|
||||
|
||||
return rc;
|
||||
}
|
||||
@@ -1194,7 +1436,7 @@ irc_message_split_privmsg_notice (struct t_hashtable *hashtable,
|
||||
*/
|
||||
|
||||
int
|
||||
irc_message_split_005 (struct t_hashtable *hashtable,
|
||||
irc_message_split_005 (struct t_irc_message_split_context *context,
|
||||
const char *tags, const char *host, const char *command,
|
||||
const char *target, const char *arguments,
|
||||
int max_length)
|
||||
@@ -1218,7 +1460,7 @@ irc_message_split_005 (struct t_hashtable *hashtable,
|
||||
pos[0] = '\0';
|
||||
}
|
||||
|
||||
return irc_message_split_string (hashtable, tags, host, command, target,
|
||||
return irc_message_split_string (context, tags, host, command, target,
|
||||
NULL, arguments, suffix, ' ', -1,
|
||||
max_length);
|
||||
}
|
||||
@@ -1254,11 +1496,16 @@ irc_message_split_005 (struct t_hashtable *hashtable,
|
||||
struct t_hashtable *
|
||||
irc_message_split (struct t_irc_server *server, const char *message)
|
||||
{
|
||||
struct t_hashtable *hashtable;
|
||||
struct t_irc_message_split_context split_context;
|
||||
char **argv, **argv_eol, *tags, *host, *command, *arguments, target[4096];
|
||||
char *pos, monitor_action[3];
|
||||
int split_ok, argc, index_args, max_length_nick, max_length_user;
|
||||
int max_length_host, max_length_nick_user_host, split_msg_max_length;
|
||||
int multiline, multiline_max_bytes, multiline_max_lines;
|
||||
|
||||
split_context.hashtable = NULL;
|
||||
split_context.number = 1;
|
||||
split_context.total_bytes = 0;
|
||||
|
||||
split_ok = 0;
|
||||
tags = NULL;
|
||||
@@ -1267,22 +1514,23 @@ irc_message_split (struct t_irc_server *server, const char *message)
|
||||
arguments = NULL;
|
||||
argv = NULL;
|
||||
argv_eol = NULL;
|
||||
multiline = 0;
|
||||
|
||||
if (server)
|
||||
{
|
||||
split_msg_max_length = IRC_SERVER_OPTION_INTEGER(
|
||||
server, IRC_SERVER_OPTION_SPLIT_MSG_MAX_LENGTH);
|
||||
|
||||
/*
|
||||
* split disabled? use a very high max_length so the message should
|
||||
* never be split
|
||||
*/
|
||||
/* if split disabled, use a high max_length to prevent any split */
|
||||
if (split_msg_max_length == 0)
|
||||
split_msg_max_length = INT_MAX - 16;
|
||||
multiline_max_bytes = server->multiline_max_bytes;
|
||||
multiline_max_lines = server->multiline_max_lines;
|
||||
}
|
||||
else
|
||||
{
|
||||
split_msg_max_length = 512; /* max length by default */
|
||||
split_msg_max_length = 512;
|
||||
multiline_max_bytes = 0;
|
||||
multiline_max_lines = 0;
|
||||
}
|
||||
|
||||
/* debug message */
|
||||
@@ -1292,11 +1540,11 @@ irc_message_split (struct t_irc_server *server, const char *message)
|
||||
message, split_msg_max_length);
|
||||
}
|
||||
|
||||
hashtable = weechat_hashtable_new (32,
|
||||
WEECHAT_HASHTABLE_STRING,
|
||||
WEECHAT_HASHTABLE_STRING,
|
||||
NULL, NULL);
|
||||
if (!hashtable)
|
||||
split_context.hashtable = weechat_hashtable_new (32,
|
||||
WEECHAT_HASHTABLE_STRING,
|
||||
WEECHAT_HASHTABLE_STRING,
|
||||
NULL, NULL);
|
||||
if (!split_context.hashtable)
|
||||
return NULL;
|
||||
|
||||
if (!message || !message[0])
|
||||
@@ -1342,6 +1590,17 @@ irc_message_split (struct t_irc_server *server, const char *message)
|
||||
index_args = 1;
|
||||
}
|
||||
|
||||
multiline = (
|
||||
((weechat_strcasecmp (command, "privmsg") == 0)
|
||||
|| (weechat_strcasecmp (command, "notice") == 0))
|
||||
&& message
|
||||
&& strchr (message, '\n')
|
||||
&& (index_args + 1 <= argc - 1)
|
||||
&& (weechat_strncmp (argv[index_args + 1], "\01", 1) != 0)
|
||||
&& (weechat_strncmp (argv[index_args + 1], ":\01", 2) != 0)
|
||||
&& weechat_hashtable_has_key (server->cap_list, "batch")
|
||||
&& weechat_hashtable_has_key (server->cap_list, "draft/multiline"));
|
||||
|
||||
max_length_nick = (server && (server->nick_max_length > 0)) ?
|
||||
server->nick_max_length : 16;
|
||||
max_length_user = (server && (server->user_max_length > 0)) ?
|
||||
@@ -1361,7 +1620,7 @@ irc_message_split (struct t_irc_server *server, const char *message)
|
||||
{
|
||||
/* AUTHENTICATE UzXAmVffxuzFy77XWBGwABBQAgdinelBrKZaR3wE7nsIETuTVY= */
|
||||
split_ok = irc_message_split_authenticate (
|
||||
hashtable, tags, host, command, arguments);
|
||||
&split_context, tags, host, command, arguments);
|
||||
}
|
||||
else if ((weechat_strcasecmp (command, "ison") == 0)
|
||||
|| (weechat_strcasecmp (command, "wallops") == 0))
|
||||
@@ -1371,7 +1630,7 @@ irc_message_split (struct t_irc_server *server, const char *message)
|
||||
* WALLOPS :some text here
|
||||
*/
|
||||
split_ok = irc_message_split_string (
|
||||
hashtable, tags, host, command, NULL, ":",
|
||||
&split_context, tags, host, command, NULL, ":",
|
||||
(argv_eol[index_args][0] == ':') ?
|
||||
argv_eol[index_args] + 1 : argv_eol[index_args],
|
||||
NULL, ' ', max_length_nick_user_host, split_msg_max_length);
|
||||
@@ -1388,14 +1647,14 @@ irc_message_split (struct t_irc_server *server, const char *message)
|
||||
snprintf (monitor_action, sizeof (monitor_action),
|
||||
"%c ", argv_eol[index_args][0]);
|
||||
split_ok = irc_message_split_string (
|
||||
hashtable, tags, host, command, NULL, monitor_action,
|
||||
&split_context, tags, host, command, NULL, monitor_action,
|
||||
argv_eol[index_args] + 2, NULL, ',', max_length_nick_user_host,
|
||||
split_msg_max_length);
|
||||
}
|
||||
else
|
||||
{
|
||||
split_ok = irc_message_split_string (
|
||||
hashtable, tags, host, command, NULL, ":",
|
||||
&split_context, tags, host, command, NULL, ":",
|
||||
(argv_eol[index_args][0] == ':') ?
|
||||
argv_eol[index_args] + 1 : argv_eol[index_args],
|
||||
NULL, ',', max_length_nick_user_host, split_msg_max_length);
|
||||
@@ -1407,7 +1666,7 @@ irc_message_split (struct t_irc_server *server, const char *message)
|
||||
if ((int)strlen (message) > split_msg_max_length - 2)
|
||||
{
|
||||
/* split join if it's too long */
|
||||
split_ok = irc_message_split_join (hashtable, tags, host,
|
||||
split_ok = irc_message_split_join (&split_context, tags, host,
|
||||
arguments, split_msg_max_length);
|
||||
}
|
||||
}
|
||||
@@ -1421,10 +1680,11 @@ irc_message_split (struct t_irc_server *server, const char *message)
|
||||
if (index_args + 1 <= argc - 1)
|
||||
{
|
||||
split_ok = irc_message_split_privmsg_notice (
|
||||
hashtable, tags, host, command, argv[index_args],
|
||||
&split_context, tags, host, command, argv[index_args],
|
||||
(argv_eol[index_args + 1][0] == ':') ?
|
||||
argv_eol[index_args + 1] + 1 : argv_eol[index_args + 1],
|
||||
max_length_nick_user_host, split_msg_max_length);
|
||||
max_length_nick_user_host, split_msg_max_length,
|
||||
multiline, multiline_max_bytes, multiline_max_lines);
|
||||
}
|
||||
}
|
||||
else if (weechat_strcasecmp (command, "005") == 0)
|
||||
@@ -1433,7 +1693,7 @@ irc_message_split (struct t_irc_server *server, const char *message)
|
||||
if (index_args + 1 <= argc - 1)
|
||||
{
|
||||
split_ok = irc_message_split_005 (
|
||||
hashtable, tags, host, command, argv[index_args],
|
||||
&split_context, tags, host, command, argv[index_args],
|
||||
(argv_eol[index_args + 1][0] == ':') ?
|
||||
argv_eol[index_args + 1] + 1 : argv_eol[index_args + 1],
|
||||
split_msg_max_length);
|
||||
@@ -1452,7 +1712,7 @@ irc_message_split (struct t_irc_server *server, const char *message)
|
||||
snprintf (target, sizeof (target), "%s %s",
|
||||
argv[index_args], argv[index_args + 1]);
|
||||
split_ok = irc_message_split_string (
|
||||
hashtable, tags, host, command, target, ":",
|
||||
&split_context, tags, host, command, target, ":",
|
||||
(argv_eol[index_args + 2][0] == ':') ?
|
||||
argv_eol[index_args + 2] + 1 : argv_eol[index_args + 2],
|
||||
NULL, ' ', -1, split_msg_max_length);
|
||||
@@ -1465,7 +1725,7 @@ irc_message_split (struct t_irc_server *server, const char *message)
|
||||
argv[index_args], argv[index_args + 1],
|
||||
argv[index_args + 2]);
|
||||
split_ok = irc_message_split_string (
|
||||
hashtable, tags, host, command, target, ":",
|
||||
&split_context, tags, host, command, target, ":",
|
||||
(argv_eol[index_args + 3][0] == ':') ?
|
||||
argv_eol[index_args + 3] + 1 : argv_eol[index_args + 3],
|
||||
NULL, ' ', -1, split_msg_max_length);
|
||||
@@ -1476,10 +1736,11 @@ irc_message_split (struct t_irc_server *server, const char *message)
|
||||
|
||||
end:
|
||||
if (!split_ok
|
||||
|| (weechat_hashtable_get_integer (hashtable, "items_count") == 0))
|
||||
|| (weechat_hashtable_get_integer (split_context.hashtable,
|
||||
"items_count") == 0))
|
||||
{
|
||||
irc_message_split_add (hashtable,
|
||||
(message) ? 1 : 0,
|
||||
split_context.number = (message) ? 1 : 0;
|
||||
irc_message_split_add (&split_context,
|
||||
tags,
|
||||
message,
|
||||
arguments);
|
||||
@@ -1492,5 +1753,5 @@ end:
|
||||
if (argv_eol)
|
||||
weechat_string_free_split (argv_eol);
|
||||
|
||||
return hashtable;
|
||||
return split_context.hashtable;
|
||||
}
|
||||
|
||||
@@ -20,6 +20,14 @@
|
||||
#ifndef WEECHAT_PLUGIN_IRC_MESSAGE_H
|
||||
#define WEECHAT_PLUGIN_IRC_MESSAGE_H
|
||||
|
||||
struct t_irc_message_split_context
|
||||
{
|
||||
struct t_hashtable *hashtable; /* hashtable with msgs/args/count */
|
||||
int number; /* current msg index (starts to 1) */
|
||||
long total_bytes; /* total bytes of messages split */
|
||||
/* (+ 1 byte between each message) */
|
||||
};
|
||||
|
||||
struct t_irc_server;
|
||||
struct t_irc_channel;
|
||||
|
||||
@@ -35,6 +43,9 @@ extern void irc_message_parse (struct t_irc_server *server, const char *message,
|
||||
int *pos_channel, int *pos_text);
|
||||
extern struct t_hashtable *irc_message_parse_to_hashtable (struct t_irc_server *server,
|
||||
const char *message);
|
||||
extern struct t_hashtable *irc_message_parse_cap_value (const char *value);
|
||||
extern void irc_message_parse_cap_multiline_value (struct t_irc_server *server,
|
||||
const char *value);
|
||||
extern char *irc_message_convert_charset (const char *message,
|
||||
int pos_start,
|
||||
const char *modifier,
|
||||
|
||||
@@ -966,6 +966,11 @@ IRC_PROTOCOL_CALLBACK(cap)
|
||||
{
|
||||
weechat_hashtable_set (server->cap_ls,
|
||||
str_name, pos_value + 1);
|
||||
if (strcmp (str_name, "draft/multiline") == 0)
|
||||
{
|
||||
irc_message_parse_cap_multiline_value (
|
||||
server, pos_value + 1);
|
||||
}
|
||||
free (str_name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1681,6 +1681,8 @@ irc_server_alloc (const char *name)
|
||||
WEECHAT_HASHTABLE_STRING,
|
||||
NULL,
|
||||
NULL);
|
||||
new_server->multiline_max_bytes = IRC_SERVER_MULTILINE_DEFAULT_MAX_BYTES;
|
||||
new_server->multiline_max_lines = IRC_SERVER_MULTILINE_DEFAULT_MAX_LINES;
|
||||
new_server->isupport = NULL;
|
||||
new_server->prefix_modes = NULL;
|
||||
new_server->prefix_chars = NULL;
|
||||
@@ -2749,11 +2751,14 @@ irc_server_outqueue_send (struct t_irc_server *server)
|
||||
{
|
||||
switch (priority)
|
||||
{
|
||||
case 0:
|
||||
case 0: /* immediate send */
|
||||
anti_flood = 0;
|
||||
break;
|
||||
case 1: /* high priority */
|
||||
anti_flood = IRC_SERVER_OPTION_INTEGER(
|
||||
server, IRC_SERVER_OPTION_ANTI_FLOOD_PRIO_HIGH);
|
||||
break;
|
||||
default:
|
||||
default: /* low priority */
|
||||
anti_flood = IRC_SERVER_OPTION_INTEGER(
|
||||
server, IRC_SERVER_OPTION_ANTI_FLOOD_PRIO_LOW);
|
||||
break;
|
||||
@@ -2950,14 +2955,19 @@ irc_server_send_one_msg (struct t_irc_server *server, int flags,
|
||||
|
||||
/* get queue from flags */
|
||||
queue_msg = 0;
|
||||
if (flags & IRC_SERVER_SEND_OUTQ_PRIO_HIGH)
|
||||
if (flags & IRC_SERVER_SEND_OUTQ_PRIO_IMMEDIATE)
|
||||
queue_msg = 1;
|
||||
else if (flags & IRC_SERVER_SEND_OUTQ_PRIO_LOW)
|
||||
else if (flags & IRC_SERVER_SEND_OUTQ_PRIO_HIGH)
|
||||
queue_msg = 2;
|
||||
else if (flags & IRC_SERVER_SEND_OUTQ_PRIO_LOW)
|
||||
queue_msg = 3;
|
||||
|
||||
switch (queue_msg - 1)
|
||||
{
|
||||
case 0:
|
||||
anti_flood = 0;
|
||||
break;
|
||||
case 1:
|
||||
anti_flood = IRC_SERVER_OPTION_INTEGER(
|
||||
server, IRC_SERVER_OPTION_ANTI_FLOOD_PRIO_HIGH);
|
||||
break;
|
||||
@@ -3090,7 +3100,7 @@ irc_server_sendf (struct t_irc_server *server, int flags, const char *tags,
|
||||
char hash_key[32], *nick, *command, *channel, *new_msg;
|
||||
char str_modifier[128];
|
||||
const char *str_message, *str_args, *ptr_msg;
|
||||
int number;
|
||||
int number, multiline;
|
||||
struct t_hashtable *hashtable;
|
||||
struct t_arraylist *list_messages;
|
||||
|
||||
@@ -3163,6 +3173,26 @@ irc_server_sendf (struct t_irc_server *server, int flags, const char *tags,
|
||||
hashtable = irc_message_split (server, ptr_msg);
|
||||
if (hashtable)
|
||||
{
|
||||
multiline = 0;
|
||||
if (weechat_hashtable_has_key (hashtable, "multiline_args1"))
|
||||
{
|
||||
multiline = 1;
|
||||
if (list_messages)
|
||||
{
|
||||
number = 1;
|
||||
while (1)
|
||||
{
|
||||
snprintf (hash_key, sizeof (hash_key),
|
||||
"multiline_args%d", number);
|
||||
str_args = weechat_hashtable_get (hashtable, hash_key);
|
||||
if (!str_args)
|
||||
break;
|
||||
weechat_arraylist_add (list_messages, strdup (str_args));
|
||||
number++;
|
||||
}
|
||||
}
|
||||
flags |= IRC_SERVER_SEND_OUTQ_PRIO_IMMEDIATE;
|
||||
}
|
||||
number = 1;
|
||||
while (1)
|
||||
{
|
||||
@@ -3173,8 +3203,7 @@ irc_server_sendf (struct t_irc_server *server, int flags, const char *tags,
|
||||
if (!irc_server_send_one_msg (server, flags, str_message,
|
||||
nick, command, channel, tags))
|
||||
break;
|
||||
|
||||
if (list_messages)
|
||||
if (!multiline && list_messages)
|
||||
{
|
||||
snprintf (hash_key, sizeof (hash_key), "args%d", number);
|
||||
str_args = weechat_hashtable_get (hashtable, hash_key);
|
||||
@@ -5620,6 +5649,8 @@ irc_server_disconnect (struct t_irc_server *server, int switch_address,
|
||||
weechat_hashtable_remove_all (server->cap_ls);
|
||||
server->checking_cap_list = 0;
|
||||
weechat_hashtable_remove_all (server->cap_list);
|
||||
server->multiline_max_bytes = IRC_SERVER_MULTILINE_DEFAULT_MAX_BYTES;
|
||||
server->multiline_max_lines = IRC_SERVER_MULTILINE_DEFAULT_MAX_LINES;
|
||||
server->is_away = 0;
|
||||
server->away_time = 0;
|
||||
server->lag = 0;
|
||||
@@ -6286,6 +6317,8 @@ irc_server_hdata_server_cb (const void *pointer, void *data,
|
||||
WEECHAT_HDATA_VAR(struct t_irc_server, cap_ls, HASHTABLE, 0, NULL, NULL);
|
||||
WEECHAT_HDATA_VAR(struct t_irc_server, checking_cap_list, INTEGER, 0, NULL, NULL);
|
||||
WEECHAT_HDATA_VAR(struct t_irc_server, cap_list, HASHTABLE, 0, NULL, NULL);
|
||||
WEECHAT_HDATA_VAR(struct t_irc_server, multiline_max_bytes, INTEGER, 0, NULL, NULL);
|
||||
WEECHAT_HDATA_VAR(struct t_irc_server, multiline_max_lines, INTEGER, 0, NULL, NULL);
|
||||
WEECHAT_HDATA_VAR(struct t_irc_server, isupport, STRING, 0, NULL, NULL);
|
||||
WEECHAT_HDATA_VAR(struct t_irc_server, prefix_modes, STRING, 0, NULL, NULL);
|
||||
WEECHAT_HDATA_VAR(struct t_irc_server, prefix_chars, STRING, 0, NULL, NULL);
|
||||
@@ -6558,6 +6591,12 @@ irc_server_add_to_infolist (struct t_infolist *infolist,
|
||||
return 0;
|
||||
if (!weechat_infolist_new_var_integer (ptr_item, "checking_cap_list", 0))
|
||||
return 0;
|
||||
if (!weechat_infolist_new_var_integer (ptr_item, "multiline_max_bytes",
|
||||
IRC_SERVER_MULTILINE_DEFAULT_MAX_BYTES))
|
||||
return 0;
|
||||
if (!weechat_infolist_new_var_integer (ptr_item, "multiline_max_lines",
|
||||
IRC_SERVER_MULTILINE_DEFAULT_MAX_LINES))
|
||||
return 0;
|
||||
if (!weechat_infolist_new_var_integer (ptr_item, "is_away", 0))
|
||||
return 0;
|
||||
if (!weechat_infolist_new_var_string (ptr_item, "away_message", NULL))
|
||||
@@ -6623,6 +6662,10 @@ irc_server_add_to_infolist (struct t_infolist *infolist,
|
||||
return 0;
|
||||
if (!weechat_hashtable_add_to_infolist (server->cap_list, ptr_item, "cap_list"))
|
||||
return 0;
|
||||
if (!weechat_infolist_new_var_integer (ptr_item, "multiline_max_bytes", server->multiline_max_bytes))
|
||||
return 0;
|
||||
if (!weechat_infolist_new_var_integer (ptr_item, "multiline_max_lines", server->multiline_max_lines))
|
||||
return 0;
|
||||
if (!weechat_infolist_new_var_integer (ptr_item, "is_away", server->is_away))
|
||||
return 0;
|
||||
if (!weechat_infolist_new_var_string (ptr_item, "away_message", server->away_message))
|
||||
@@ -7042,6 +7085,8 @@ irc_server_print_log ()
|
||||
weechat_log_printf (" cap_list. . . . . . . . . : 0x%lx (hashtable: '%s')",
|
||||
ptr_server->cap_list,
|
||||
weechat_hashtable_get_string (ptr_server->cap_list, "keys_values"));
|
||||
weechat_log_printf (" multiline_max_bytes . . . : %d", ptr_server->multiline_max_bytes);
|
||||
weechat_log_printf (" multiline_max_lines . . . : %d", ptr_server->multiline_max_lines);
|
||||
weechat_log_printf (" isupport. . . . . . . . . : '%s'", ptr_server->isupport);
|
||||
weechat_log_printf (" prefix_modes. . . . . . . : '%s'", ptr_server->prefix_modes);
|
||||
weechat_log_printf (" prefix_chars. . . . . . . : '%s'", ptr_server->prefix_chars);
|
||||
|
||||
@@ -126,16 +126,21 @@ enum t_irc_server_option
|
||||
#define IRC_SERVER_DEFAULT_NICKS "weechat1,weechat2,weechat3,weechat4,weechat5"
|
||||
|
||||
/* number of queues for sending messages */
|
||||
#define IRC_SERVER_NUM_OUTQUEUES_PRIO 2
|
||||
#define IRC_SERVER_NUM_OUTQUEUES_PRIO 3
|
||||
|
||||
/* flags for irc_server_sendf() */
|
||||
#define IRC_SERVER_SEND_OUTQ_PRIO_HIGH (1 << 0)
|
||||
#define IRC_SERVER_SEND_OUTQ_PRIO_LOW (1 << 1)
|
||||
#define IRC_SERVER_SEND_RETURN_LIST (1 << 2)
|
||||
#define IRC_SERVER_SEND_OUTQ_PRIO_IMMEDIATE (1 << 0)
|
||||
#define IRC_SERVER_SEND_OUTQ_PRIO_HIGH (1 << 1)
|
||||
#define IRC_SERVER_SEND_OUTQ_PRIO_LOW (1 << 2)
|
||||
#define IRC_SERVER_SEND_RETURN_LIST (1 << 3)
|
||||
|
||||
/* version strings */
|
||||
#define IRC_SERVER_VERSION_CAP "302"
|
||||
|
||||
/* multiline default limits */
|
||||
#define IRC_SERVER_MULTILINE_DEFAULT_MAX_BYTES 4096
|
||||
#define IRC_SERVER_MULTILINE_DEFAULT_MAX_LINES 24
|
||||
|
||||
/* casemapping (string comparisons for nicks/channels) */
|
||||
enum t_irc_server_casemapping
|
||||
{
|
||||
@@ -232,6 +237,8 @@ struct t_irc_server
|
||||
struct t_hashtable *cap_ls; /* list of supported capabilities */
|
||||
int checking_cap_list; /* 1 if checking enabled capabilities */
|
||||
struct t_hashtable *cap_list; /* list of enabled capabilities */
|
||||
int multiline_max_bytes; /* max bytes for multiline batch */
|
||||
int multiline_max_lines; /* max lines for multiline batch */
|
||||
char *isupport; /* copy of message 005 (ISUPPORT) */
|
||||
char *prefix_modes; /* prefix modes from msg 005 (eg "ohv") */
|
||||
char *prefix_chars; /* prefix chars from msg 005 (eg "@%+") */
|
||||
@@ -267,9 +274,11 @@ struct t_irc_server
|
||||
time_t last_user_message; /* time of last user message (anti flood)*/
|
||||
time_t last_away_check; /* time of last away check on server */
|
||||
time_t last_data_purge; /* time of last purge (some hashtables) */
|
||||
struct t_irc_outqueue *outqueue[2]; /* queue for outgoing messages */
|
||||
struct t_irc_outqueue *outqueue[IRC_SERVER_NUM_OUTQUEUES_PRIO];
|
||||
/* queue for outgoing messages */
|
||||
/* with 2 priorities (high/low) */
|
||||
struct t_irc_outqueue *last_outqueue[2]; /* last outgoing message */
|
||||
struct t_irc_outqueue *last_outqueue[IRC_SERVER_NUM_OUTQUEUES_PRIO];
|
||||
/* last outgoing message */
|
||||
struct t_irc_redirect *redirects; /* command redirections */
|
||||
struct t_irc_redirect *last_redirect; /* last command redirection */
|
||||
struct t_irc_notify *notify_list; /* list of notify */
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "../weechat-plugin.h"
|
||||
#include "irc.h"
|
||||
#include "irc-bar-item.h"
|
||||
#include "irc-batch.h"
|
||||
#include "irc-buffer.h"
|
||||
#include "irc-channel.h"
|
||||
#include "irc-color.h"
|
||||
@@ -238,6 +239,8 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[])
|
||||
&irc_tag_modifier_cb, NULL, NULL);
|
||||
weechat_hook_modifier ("irc_tag_unescape_value",
|
||||
&irc_tag_modifier_cb, NULL, NULL);
|
||||
weechat_hook_modifier ("irc_batch",
|
||||
&irc_batch_modifier_cb, NULL, NULL);
|
||||
|
||||
/* hook completions */
|
||||
irc_completion_init ();
|
||||
|
||||
@@ -69,6 +69,31 @@ TEST(IrcBatch, Search)
|
||||
irc_server_free (server);
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests functions:
|
||||
* irc_batch_generate_random_ref
|
||||
*/
|
||||
|
||||
TEST(IrcBatch, GenerateRandomRef)
|
||||
{
|
||||
char str[16 + 1];
|
||||
|
||||
strcpy (str, "ABC");
|
||||
irc_batch_generate_random_ref (NULL, 8);
|
||||
irc_batch_generate_random_ref (str, -1);
|
||||
STRCMP_EQUAL("ABC", str);
|
||||
|
||||
strcpy (str, "ABC");
|
||||
irc_batch_generate_random_ref (str, 0);
|
||||
LONGS_EQUAL(0, strlen (str));
|
||||
str[0] = '\0';
|
||||
irc_batch_generate_random_ref (str, 8);
|
||||
LONGS_EQUAL(8, strlen (str));
|
||||
str[0] = '\0';
|
||||
irc_batch_generate_random_ref (str, 16);
|
||||
LONGS_EQUAL(16, strlen (str));
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests functions:
|
||||
* irc_batch_add_to_list
|
||||
@@ -110,6 +135,7 @@ TEST(IrcBatch, StartBatch)
|
||||
STRCMP_EQUAL("params", batch->parameters);
|
||||
CHECK(batch->start_time > 0);
|
||||
POINTERS_EQUAL(NULL, batch->messages);
|
||||
|
||||
LONGS_EQUAL(0, batch->end_received);
|
||||
LONGS_EQUAL(0, batch->messages_processed);
|
||||
irc_batch_free (server, batch);
|
||||
@@ -197,6 +223,16 @@ TEST(IrcBatch, EndBatch)
|
||||
/* tested in test-irc-protocol.cpp */
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests functions:
|
||||
* irc_batch_process_multiline
|
||||
*/
|
||||
|
||||
TEST(IrcBatch, ProcessMultiline)
|
||||
{
|
||||
/* tested in test-irc-protocol.cpp */
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests functions:
|
||||
* irc_batch_hdata_batch_cb
|
||||
|
||||
@@ -841,6 +841,78 @@ TEST(IrcMessage, ParseToHashtable)
|
||||
hashtable_free (hashtable);
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests functions:
|
||||
* irc_message_parse_cap_value
|
||||
*/
|
||||
|
||||
TEST(IrcMessage, ParseCapValue)
|
||||
{
|
||||
struct t_hashtable *hashtable;
|
||||
|
||||
POINTERS_EQUAL(NULL, irc_message_parse_cap_value (NULL));
|
||||
|
||||
hashtable = irc_message_parse_cap_value ("");
|
||||
CHECK(hashtable);
|
||||
LONGS_EQUAL(0, hashtable->items_count);
|
||||
hashtable_free (hashtable);
|
||||
|
||||
hashtable = irc_message_parse_cap_value ("key1=value1,key2,key3=123");
|
||||
CHECK(hashtable);
|
||||
LONGS_EQUAL(3, hashtable->items_count);
|
||||
STRCMP_EQUAL("value1", (const char *)hashtable_get (hashtable, "key1"));
|
||||
POINTERS_EQUAL(NULL, (const char *)hashtable_get (hashtable, "key2"));
|
||||
STRCMP_EQUAL("123", (const char *)hashtable_get (hashtable, "key3"));
|
||||
hashtable_free (hashtable);
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests functions:
|
||||
* irc_message_parse_multiline_value
|
||||
*/
|
||||
|
||||
TEST(IrcMessage, ParseCapMultilineValue)
|
||||
{
|
||||
struct t_irc_server *server;
|
||||
|
||||
server = irc_server_alloc ("test_multiline");
|
||||
CHECK(server);
|
||||
|
||||
irc_message_parse_cap_multiline_value (NULL, NULL);
|
||||
|
||||
server->multiline_max_bytes = 0;
|
||||
server->multiline_max_lines = 0;
|
||||
irc_message_parse_cap_multiline_value (server, NULL);
|
||||
LONGS_EQUAL(IRC_SERVER_MULTILINE_DEFAULT_MAX_BYTES, server->multiline_max_bytes);
|
||||
LONGS_EQUAL(IRC_SERVER_MULTILINE_DEFAULT_MAX_LINES, server->multiline_max_lines);
|
||||
|
||||
server->multiline_max_bytes = 0;
|
||||
server->multiline_max_lines = 0;
|
||||
irc_message_parse_cap_multiline_value (server, "");
|
||||
LONGS_EQUAL(IRC_SERVER_MULTILINE_DEFAULT_MAX_BYTES, server->multiline_max_bytes);
|
||||
LONGS_EQUAL(IRC_SERVER_MULTILINE_DEFAULT_MAX_LINES, server->multiline_max_lines);
|
||||
|
||||
server->multiline_max_bytes = 0;
|
||||
server->multiline_max_lines = 0;
|
||||
irc_message_parse_cap_multiline_value (server, "max-bytes=2048");
|
||||
LONGS_EQUAL(2048, server->multiline_max_bytes);
|
||||
LONGS_EQUAL(IRC_SERVER_MULTILINE_DEFAULT_MAX_LINES, server->multiline_max_lines);
|
||||
|
||||
server->multiline_max_bytes = 0;
|
||||
server->multiline_max_lines = 0;
|
||||
irc_message_parse_cap_multiline_value (server, "max-lines=8");
|
||||
LONGS_EQUAL(IRC_SERVER_MULTILINE_DEFAULT_MAX_BYTES, server->multiline_max_bytes);
|
||||
LONGS_EQUAL(8, server->multiline_max_lines);
|
||||
|
||||
server->multiline_max_bytes = 0;
|
||||
server->multiline_max_lines = 0;
|
||||
irc_message_parse_cap_multiline_value (server, "max-bytes=2048,max-lines=8");
|
||||
LONGS_EQUAL(2048, server->multiline_max_bytes);
|
||||
LONGS_EQUAL(8, server->multiline_max_lines);
|
||||
|
||||
irc_server_free (server);
|
||||
}
|
||||
|
||||
char *
|
||||
convert_irc_charset_cb (const void *pointer, void *data,
|
||||
const char *modifier, const char *modifier_data,
|
||||
@@ -1039,6 +1111,8 @@ TEST(IrcMessage, Split)
|
||||
{
|
||||
struct t_irc_server *server;
|
||||
struct t_hashtable *hashtable;
|
||||
const char *ptr_msg, *pos1, *pos2;
|
||||
char batch_ref[512], msg[4096];
|
||||
|
||||
server = irc_server_alloc ("test_split_msg");
|
||||
CHECK(server);
|
||||
@@ -1607,6 +1681,254 @@ TEST(IrcMessage, Split)
|
||||
(const char *)hashtable_get (hashtable, "args3"));
|
||||
hashtable_free (hashtable);
|
||||
|
||||
/* PRIVMSG with multiline: BATCH is used */
|
||||
hashtable_set (server->cap_list, "batch", NULL);
|
||||
hashtable_set (server->cap_list, "draft/multiline", NULL);
|
||||
hashtable = irc_message_split (server, "PRIVMSG #channel :test\n\nline 3");
|
||||
CHECK(hashtable);
|
||||
LONGS_EQUAL(12, hashtable->items_count);
|
||||
STRCMP_EQUAL("5",
|
||||
(const char *)hashtable_get (hashtable, "count"));
|
||||
ptr_msg = (const char *)hashtable_get (hashtable, "msg1");
|
||||
CHECK(ptr_msg);
|
||||
STRNCMP_EQUAL("BATCH +", ptr_msg, 7);
|
||||
pos1 = ptr_msg + 7;
|
||||
pos2 = strchr (pos1, ' ');
|
||||
CHECK(pos2);
|
||||
memcpy (batch_ref, pos1, pos2 - pos1);
|
||||
batch_ref[pos2 - pos1] = '\0';
|
||||
snprintf (msg, sizeof (msg),
|
||||
"BATCH +%s draft/multiline #channel", batch_ref);
|
||||
STRCMP_EQUAL(msg, (const char *)hashtable_get (hashtable, "msg1"));
|
||||
snprintf (msg, sizeof (msg),
|
||||
"+%s draft/multiline #channel", batch_ref);
|
||||
STRCMP_EQUAL(msg, (const char *)hashtable_get (hashtable, "args1"));
|
||||
snprintf (msg, sizeof (msg),
|
||||
"@batch=%s PRIVMSG #channel :test", batch_ref);
|
||||
STRCMP_EQUAL(msg, (const char *)hashtable_get (hashtable, "msg2"));
|
||||
STRCMP_EQUAL("test", (const char *)hashtable_get (hashtable, "args2"));
|
||||
snprintf (msg, sizeof (msg),
|
||||
"@batch=%s PRIVMSG #channel :", batch_ref);
|
||||
STRCMP_EQUAL(msg, (const char *)hashtable_get (hashtable, "msg3"));
|
||||
STRCMP_EQUAL("", (const char *)hashtable_get (hashtable, "args3"));
|
||||
snprintf (msg, sizeof (msg),
|
||||
"@batch=%s PRIVMSG #channel :line 3", batch_ref);
|
||||
STRCMP_EQUAL(msg, (const char *)hashtable_get (hashtable, "msg4"));
|
||||
STRCMP_EQUAL("line 3", (const char *)hashtable_get (hashtable, "args4"));
|
||||
snprintf (msg, sizeof (msg),
|
||||
"BATCH -%s", batch_ref);
|
||||
STRCMP_EQUAL(msg, (const char *)hashtable_get (hashtable, "msg5"));
|
||||
snprintf (msg, sizeof (msg),
|
||||
"-%s", batch_ref);
|
||||
STRCMP_EQUAL(msg, (const char *)hashtable_get (hashtable, "args5"));
|
||||
STRCMP_EQUAL("test\n\nline 3",
|
||||
(const char *)hashtable_get (hashtable, "multiline_args1"));
|
||||
hashtable_free (hashtable);
|
||||
hashtable_remove (server->cap_list, "batch");
|
||||
hashtable_remove (server->cap_list, "draft/multiline");
|
||||
|
||||
/* NOTICE with multiline: BATCH is used */
|
||||
hashtable_set (server->cap_list, "batch", NULL);
|
||||
hashtable_set (server->cap_list, "draft/multiline", NULL);
|
||||
hashtable = irc_message_split (server, "NOTICE #channel :\ntest\nline 2");
|
||||
CHECK(hashtable);
|
||||
LONGS_EQUAL(12, hashtable->items_count);
|
||||
STRCMP_EQUAL("5",
|
||||
(const char *)hashtable_get (hashtable, "count"));
|
||||
ptr_msg = (const char *)hashtable_get (hashtable, "msg1");
|
||||
CHECK(ptr_msg);
|
||||
STRNCMP_EQUAL("BATCH +", ptr_msg, 7);
|
||||
pos1 = ptr_msg + 7;
|
||||
pos2 = strchr (pos1, ' ');
|
||||
CHECK(pos2);
|
||||
memcpy (batch_ref, pos1, pos2 - pos1);
|
||||
batch_ref[pos2 - pos1] = '\0';
|
||||
snprintf (msg, sizeof (msg),
|
||||
"BATCH +%s draft/multiline #channel", batch_ref);
|
||||
STRCMP_EQUAL(msg, (const char *)hashtable_get (hashtable, "msg1"));
|
||||
snprintf (msg, sizeof (msg),
|
||||
"+%s draft/multiline #channel", batch_ref);
|
||||
STRCMP_EQUAL(msg, (const char *)hashtable_get (hashtable, "args1"));
|
||||
snprintf (msg, sizeof (msg),
|
||||
"@batch=%s NOTICE #channel :", batch_ref);
|
||||
STRCMP_EQUAL(msg, (const char *)hashtable_get (hashtable, "msg2"));
|
||||
STRCMP_EQUAL("", (const char *)hashtable_get (hashtable, "args2"));
|
||||
snprintf (msg, sizeof (msg),
|
||||
"@batch=%s NOTICE #channel :test", batch_ref);
|
||||
STRCMP_EQUAL(msg, (const char *)hashtable_get (hashtable, "msg3"));
|
||||
STRCMP_EQUAL("test", (const char *)hashtable_get (hashtable, "args3"));
|
||||
snprintf (msg, sizeof (msg),
|
||||
"@batch=%s NOTICE #channel :line 2", batch_ref);
|
||||
STRCMP_EQUAL(msg, (const char *)hashtable_get (hashtable, "msg4"));
|
||||
STRCMP_EQUAL("line 2", (const char *)hashtable_get (hashtable, "args4"));
|
||||
snprintf (msg, sizeof (msg),
|
||||
"BATCH -%s", batch_ref);
|
||||
STRCMP_EQUAL(msg, (const char *)hashtable_get (hashtable, "msg5"));
|
||||
snprintf (msg, sizeof (msg),
|
||||
"-%s", batch_ref);
|
||||
STRCMP_EQUAL(msg, (const char *)hashtable_get (hashtable, "args5"));
|
||||
STRCMP_EQUAL("\ntest\nline 2",
|
||||
(const char *)hashtable_get (hashtable, "multiline_args1"));
|
||||
hashtable_free (hashtable);
|
||||
hashtable_remove (server->cap_list, "batch");
|
||||
hashtable_remove (server->cap_list, "draft/multiline");
|
||||
|
||||
/* PRIVMSG with multiline exceeding "max-lines" */
|
||||
server->multiline_max_bytes = IRC_SERVER_MULTILINE_DEFAULT_MAX_BYTES;
|
||||
server->multiline_max_lines = 3;
|
||||
hashtable_set (server->cap_list, "batch", NULL);
|
||||
hashtable_set (server->cap_list, "draft/multiline", NULL);
|
||||
hashtable = irc_message_split (
|
||||
server,
|
||||
"PRIVMSG #channel :test\nline 2\nline 3\nline 4");
|
||||
CHECK(hashtable);
|
||||
LONGS_EQUAL(19, hashtable->items_count);
|
||||
STRCMP_EQUAL("8",
|
||||
(const char *)hashtable_get (hashtable, "count"));
|
||||
ptr_msg = (const char *)hashtable_get (hashtable, "msg1");
|
||||
CHECK(ptr_msg);
|
||||
STRNCMP_EQUAL("BATCH +", ptr_msg, 7);
|
||||
pos1 = ptr_msg + 7;
|
||||
pos2 = strchr (pos1, ' ');
|
||||
CHECK(pos2);
|
||||
memcpy (batch_ref, pos1, pos2 - pos1);
|
||||
batch_ref[pos2 - pos1] = '\0';
|
||||
snprintf (msg, sizeof (msg),
|
||||
"BATCH +%s draft/multiline #channel", batch_ref);
|
||||
STRCMP_EQUAL(msg, (const char *)hashtable_get (hashtable, "msg1"));
|
||||
snprintf (msg, sizeof (msg),
|
||||
"+%s draft/multiline #channel", batch_ref);
|
||||
STRCMP_EQUAL(msg, (const char *)hashtable_get (hashtable, "args1"));
|
||||
snprintf (msg, sizeof (msg),
|
||||
"@batch=%s PRIVMSG #channel :test", batch_ref);
|
||||
STRCMP_EQUAL(msg, (const char *)hashtable_get (hashtable, "msg2"));
|
||||
STRCMP_EQUAL("test", (const char *)hashtable_get (hashtable, "args2"));
|
||||
snprintf (msg, sizeof (msg),
|
||||
"@batch=%s PRIVMSG #channel :line 2", batch_ref);
|
||||
STRCMP_EQUAL(msg, (const char *)hashtable_get (hashtable, "msg3"));
|
||||
STRCMP_EQUAL("line 2", (const char *)hashtable_get (hashtable, "args3"));
|
||||
snprintf (msg, sizeof (msg),
|
||||
"@batch=%s PRIVMSG #channel :line 3", batch_ref);
|
||||
STRCMP_EQUAL(msg, (const char *)hashtable_get (hashtable, "msg4"));
|
||||
STRCMP_EQUAL("line 3", (const char *)hashtable_get (hashtable, "args4"));
|
||||
snprintf (msg, sizeof (msg),
|
||||
"BATCH -%s", batch_ref);
|
||||
STRCMP_EQUAL(msg, (const char *)hashtable_get (hashtable, "msg5"));
|
||||
snprintf (msg, sizeof (msg),
|
||||
"-%s", batch_ref);
|
||||
STRCMP_EQUAL(msg, (const char *)hashtable_get (hashtable, "args5"));
|
||||
ptr_msg = (const char *)hashtable_get (hashtable, "msg6");
|
||||
CHECK(ptr_msg);
|
||||
STRNCMP_EQUAL("BATCH +", ptr_msg, 7);
|
||||
pos1 = ptr_msg + 7;
|
||||
pos2 = strchr (pos1, ' ');
|
||||
CHECK(pos2);
|
||||
memcpy (batch_ref, pos1, pos2 - pos1);
|
||||
batch_ref[pos2 - pos1] = '\0';
|
||||
snprintf (msg, sizeof (msg),
|
||||
"BATCH +%s draft/multiline #channel", batch_ref);
|
||||
STRCMP_EQUAL(msg, (const char *)hashtable_get (hashtable, "msg6"));
|
||||
snprintf (msg, sizeof (msg),
|
||||
"+%s draft/multiline #channel", batch_ref);
|
||||
STRCMP_EQUAL(msg, (const char *)hashtable_get (hashtable, "args6"));
|
||||
snprintf (msg, sizeof (msg),
|
||||
"@batch=%s PRIVMSG #channel :line 4", batch_ref);
|
||||
STRCMP_EQUAL(msg, (const char *)hashtable_get (hashtable, "msg7"));
|
||||
STRCMP_EQUAL("line 4", (const char *)hashtable_get (hashtable, "args7"));
|
||||
snprintf (msg, sizeof (msg),
|
||||
"BATCH -%s", batch_ref);
|
||||
STRCMP_EQUAL(msg, (const char *)hashtable_get (hashtable, "msg8"));
|
||||
snprintf (msg, sizeof (msg),
|
||||
"-%s", batch_ref);
|
||||
STRCMP_EQUAL(msg, (const char *)hashtable_get (hashtable, "args8"));
|
||||
STRCMP_EQUAL("test\nline 2\nline 3",
|
||||
(const char *)hashtable_get (hashtable, "multiline_args1"));
|
||||
STRCMP_EQUAL("line 4",
|
||||
(const char *)hashtable_get (hashtable, "multiline_args2"));
|
||||
hashtable_free (hashtable);
|
||||
hashtable_remove (server->cap_list, "batch");
|
||||
hashtable_remove (server->cap_list, "draft/multiline");
|
||||
|
||||
/* PRIVMSG with multiline exceeding "max-bytes" */
|
||||
server->multiline_max_bytes = 200;
|
||||
server->multiline_max_lines = IRC_SERVER_MULTILINE_DEFAULT_MAX_LINES;
|
||||
hashtable_set (server->cap_list, "batch", NULL);
|
||||
hashtable_set (server->cap_list, "draft/multiline", NULL);
|
||||
hashtable = irc_message_split (
|
||||
server,
|
||||
"PRIVMSG #channel :test\n"
|
||||
"this is a loooooooooooooooong line 2\n"
|
||||
"this is a loooooooooooooooong line 3\n"
|
||||
"this is a loooooooooooooooong line 4");
|
||||
CHECK(hashtable);
|
||||
LONGS_EQUAL(19, hashtable->items_count);
|
||||
STRCMP_EQUAL("8", (const char *)hashtable_get (hashtable, "count"));
|
||||
ptr_msg = (const char *)hashtable_get (hashtable, "msg1");
|
||||
CHECK(ptr_msg);
|
||||
STRNCMP_EQUAL("BATCH +", ptr_msg, 7);
|
||||
pos1 = ptr_msg + 7;
|
||||
pos2 = strchr (pos1, ' ');
|
||||
CHECK(pos2);
|
||||
memcpy (batch_ref, pos1, pos2 - pos1);
|
||||
batch_ref[pos2 - pos1] = '\0';
|
||||
snprintf (msg, sizeof (msg),
|
||||
"BATCH +%s draft/multiline #channel", batch_ref);
|
||||
STRCMP_EQUAL(msg, (const char *)hashtable_get (hashtable, "msg1"));
|
||||
snprintf (msg, sizeof (msg),
|
||||
"+%s draft/multiline #channel", batch_ref);
|
||||
STRCMP_EQUAL(msg, (const char *)hashtable_get (hashtable, "args1"));
|
||||
snprintf (msg, sizeof (msg),
|
||||
"@batch=%s PRIVMSG #channel :test", batch_ref);
|
||||
STRCMP_EQUAL(msg, (const char *)hashtable_get (hashtable, "msg2"));
|
||||
STRCMP_EQUAL("test", (const char *)hashtable_get (hashtable, "args2"));
|
||||
snprintf (msg, sizeof (msg),
|
||||
"@batch=%s PRIVMSG #channel :this is a loooooooooooooooong line 2", batch_ref);
|
||||
STRCMP_EQUAL(msg, (const char *)hashtable_get (hashtable, "msg3"));
|
||||
STRCMP_EQUAL("this is a loooooooooooooooong line 2", (const char *)hashtable_get (hashtable, "args3"));
|
||||
snprintf (msg, sizeof (msg),
|
||||
"BATCH -%s", batch_ref);
|
||||
STRCMP_EQUAL(msg, (const char *)hashtable_get (hashtable, "msg4"));
|
||||
snprintf (msg, sizeof (msg),
|
||||
"-%s", batch_ref);
|
||||
STRCMP_EQUAL(msg, (const char *)hashtable_get (hashtable, "args4"));
|
||||
ptr_msg = (const char *)hashtable_get (hashtable, "msg5");
|
||||
CHECK(ptr_msg);
|
||||
STRNCMP_EQUAL("BATCH +", ptr_msg, 7);
|
||||
pos1 = ptr_msg + 7;
|
||||
pos2 = strchr (pos1, ' ');
|
||||
CHECK(pos2);
|
||||
memcpy (batch_ref, pos1, pos2 - pos1);
|
||||
batch_ref[pos2 - pos1] = '\0';
|
||||
snprintf (msg, sizeof (msg),
|
||||
"BATCH +%s draft/multiline #channel", batch_ref);
|
||||
STRCMP_EQUAL(msg, (const char *)hashtable_get (hashtable, "msg5"));
|
||||
snprintf (msg, sizeof (msg),
|
||||
"+%s draft/multiline #channel", batch_ref);
|
||||
STRCMP_EQUAL(msg, (const char *)hashtable_get (hashtable, "args5"));
|
||||
snprintf (msg, sizeof (msg),
|
||||
"@batch=%s PRIVMSG #channel :this is a loooooooooooooooong line 3", batch_ref);
|
||||
STRCMP_EQUAL(msg, (const char *)hashtable_get (hashtable, "msg6"));
|
||||
STRCMP_EQUAL("this is a loooooooooooooooong line 3", (const char *)hashtable_get (hashtable, "args6"));
|
||||
snprintf (msg, sizeof (msg),
|
||||
"@batch=%s PRIVMSG #channel :this is a loooooooooooooooong line 4", batch_ref);
|
||||
STRCMP_EQUAL(msg, (const char *)hashtable_get (hashtable, "msg7"));
|
||||
STRCMP_EQUAL("this is a loooooooooooooooong line 4", (const char *)hashtable_get (hashtable, "args7"));
|
||||
snprintf (msg, sizeof (msg),
|
||||
"BATCH -%s", batch_ref);
|
||||
STRCMP_EQUAL(msg, (const char *)hashtable_get (hashtable, "msg8"));
|
||||
snprintf (msg, sizeof (msg),
|
||||
"-%s", batch_ref);
|
||||
STRCMP_EQUAL(msg, (const char *)hashtable_get (hashtable, "args8"));
|
||||
STRCMP_EQUAL("test\n"
|
||||
"this is a loooooooooooooooong line 2",
|
||||
(const char *)hashtable_get (hashtable, "multiline_args1"));
|
||||
STRCMP_EQUAL("this is a loooooooooooooooong line 3\n"
|
||||
"this is a loooooooooooooooong line 4",
|
||||
(const char *)hashtable_get (hashtable, "multiline_args2"));
|
||||
hashtable_free (hashtable);
|
||||
hashtable_remove (server->cap_list, "batch");
|
||||
hashtable_remove (server->cap_list, "draft/multiline");
|
||||
|
||||
/* 005: no split */
|
||||
hashtable = irc_message_split (server, "005 nick " MSG_005);
|
||||
CHECK(hashtable);
|
||||
|
||||
@@ -67,8 +67,8 @@ extern char *irc_protocol_cap_to_enable (const char *capabilities,
|
||||
"CHANTYPES=# CHANMODES=eIbq,k,flj,CFLMPQScgimnprstuz " \
|
||||
"MONITOR=100"
|
||||
#define IRC_ALL_CAPS "account-notify,away-notify,batch,cap-notify," \
|
||||
"chghost,extended-join,invite-notify,message-tags,multi-prefix," \
|
||||
"server-time,setname,userhost-in-names"
|
||||
"chghost,draft/multiline,extended-join,invite-notify,message-tags," \
|
||||
"multi-prefix,server-time,setname,userhost-in-names"
|
||||
|
||||
#define WEE_CHECK_CAP_TO_ENABLE(__result, __string, __sasl_requested) \
|
||||
str = irc_protocol_cap_to_enable (__string, __sasl_requested); \
|
||||
@@ -804,6 +804,10 @@ TEST(IrcProtocolWithServer, batch)
|
||||
|
||||
SRV_INIT_JOIN2;
|
||||
|
||||
/* assume "batch" and "draft/multiline" capabilities are enabled in server */
|
||||
hashtable_set (ptr_server->cap_list, "batch", NULL);
|
||||
hashtable_set (ptr_server->cap_list, "draft/multiline", NULL);
|
||||
|
||||
/* not enough parameters */
|
||||
RECV(":server BATCH");
|
||||
CHECK_ERROR_PARAMS("batch", 0, 1);
|
||||
@@ -917,6 +921,29 @@ TEST(IrcProtocolWithServer, batch)
|
||||
CHECK_CHAN("bob test ref2");
|
||||
POINTERS_EQUAL(NULL, irc_batch_search (ptr_server, "ref1"));
|
||||
POINTERS_EQUAL(NULL, irc_batch_search (ptr_server, "ref2"));
|
||||
|
||||
/* multiline */
|
||||
RECV(":server BATCH +ref draft/multiline #test");
|
||||
CHECK_NO_MSG;
|
||||
RECV("@batch=ref :bob!user_b@host_b PRIVMSG #test :line 1");
|
||||
CHECK_NO_MSG;
|
||||
RECV("@batch=ref :bob!user_b@host_b PRIVMSG #test :line 2");
|
||||
CHECK_NO_MSG;
|
||||
RECV(":server BATCH -ref");
|
||||
CHECK_CHAN("bob line 1\n"
|
||||
"line 2");
|
||||
|
||||
/* multiline with CTCP */
|
||||
RECV(":server BATCH +ref draft/multiline #test");
|
||||
CHECK_NO_MSG;
|
||||
RECV("@batch=ref :bob!user_b@host_b PRIVMSG #test :"
|
||||
"\x01" "ACTION is testing");
|
||||
CHECK_NO_MSG;
|
||||
RECV("@batch=ref :bob!user_b@host_b PRIVMSG #test :again" "\x01");
|
||||
CHECK_NO_MSG;
|
||||
RECV(":server BATCH -ref");
|
||||
CHECK_CHAN(" * bob is testing\n"
|
||||
"again");
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user