irc: improve split of privmsg, add split of some other messages (bug #29879), add new info_hashtable "irc_message_split", split irc messages in relay plugin

List of new features/bugs fixed:
- improve split of privmsg: keep CTCP in split
- add split of messages: ison, join, notice, wallops, 005, 353
- add new info_hashtable "irc_message_split" (for plugins/scripts)
- in relay plugin: split irc messages sent to clients of irc proxy
v2.8-utf8proc
Sebastien Helleu 2011-08-26 10:31:37 +02:00
parent ebf72c7eda
commit 4853a530b6
35 changed files with 1013 additions and 197 deletions

View File

@ -64,6 +64,10 @@ Version 0.3.6 (under dev!)
description for option when function is called)
* scripts: fix crash with scripts not auto-loaded having a buffer opened after
/upgrade (input/close callbacks for buffer not set properly)
* irc: add new info_hashtable "irc_message_split"
* irc: improve split of privmsg message (keep ctcp), add split of ison, join,
notice, wallops, 005, 353 (bug #29879)
* irc: rename info_hashtable "irc_parse_message" to "irc_message_parse"
* irc: use color "default" for any invalid color in option
weechat.color.chat_nick_colors
* irc: send WHO command to check away nicks only if channel was not parted
@ -269,6 +273,7 @@ Version 0.3.4 (2011-01-16)
* irc: add signal "irc_input_send"
* rmodifier: new plugin "rmodifier": alter modifier strings with regular
expressions (bug #26964)
* relay: split of messages sent to clients of irc proxy
* relay: beta version of IRC proxy, now relay plugin is compiled by default
* scripts: add missing function "infolist_reset_item_cursor" in API (bug #31057)
* python: add info "python2_bin" (path to python 2.x interpreter)

View File

@ -136,6 +136,7 @@
'isupport' (string) +
'prefix_modes' (string) +
'prefix_chars' (string) +
'nick_max_length' (integer) +
'reconnect_delay' (integer) +
'reconnect_start' (time) +
'command_time' (time) +

View File

@ -2,6 +2,8 @@
|========================================
| Erweiterung | Name | Beschreibung | Hashtable (Eingabe) | Hashtable (Ausgabe)
| irc | irc_parse_message | Parse eine IRC Nachricht | "message": IRC Nachricht | "nick": nick, "host": host, "command": command, "channel": channel, "arguments": arguments (beinhaltet Channel)
| irc | irc_message_parse | Parse eine IRC Nachricht | "message": IRC Nachricht | "nick": nick, "host": host, "command": command, "channel": channel, "arguments": arguments (beinhaltet Channel)
| irc | irc_message_split | split an IRC message (to fit in 512 bytes) | "message": IRC message, "server": server name (optional) | "msg1" ... "msgN": messages to send (without final "\r\n"), "args1" ... "argsN": arguments of messages
|========================================

View File

@ -729,17 +729,17 @@ weechat.hook_modifier("irc_in_privmsg", "modifier_cb", "")
[WARNING]
Eine fehlerhafte Nachricht kann WeeChat zum Absturz bringen oder andere ernsthafte Probleme erzeugen!
[[irc_parse_message]]
[[irc_message_parse]]
Nachrichten parsen
^^^^^^^^^^^^^^^^^^
_Neu in Version 0.3.4._
Man kann IRC Nachrichten mittels einer info_hashtable mit dem Namen "irc_parse_message" parsen.
Man kann IRC Nachrichten mittels einer info_hashtable mit dem Namen "irc_message_parse" parsen.
[source,python]
----------------------------------------
dict = weechat.info_get_hashtable("irc_parse_message",
dict = weechat.info_get_hashtable("irc_message_parse",
{ "message": ":nick!user@host PRIVMSG #weechat :message here" })
weechat.prnt("", "dict: %s" % dict)

View File

@ -136,6 +136,7 @@
'isupport' (string) +
'prefix_modes' (string) +
'prefix_chars' (string) +
'nick_max_length' (integer) +
'reconnect_delay' (integer) +
'reconnect_start' (time) +
'command_time' (time) +

View File

@ -2,6 +2,8 @@
|========================================
| Plugin | Name | Description | Hashtable (input) | Hashtable (output)
| irc | irc_parse_message | parse an IRC message | "message": IRC message | "nick": nick, "host": host, "command": command, "channel": channel, "arguments": arguments (includes channel)
| irc | irc_message_parse | parse an IRC message | "message": IRC message | "nick": nick, "host": host, "command": command, "channel": channel, "arguments": arguments (includes channel)
| irc | irc_message_split | split an IRC message (to fit in 512 bytes) | "message": IRC message, "server": server name (optional) | "msg1" ... "msgN": messages to send (without final "\r\n"), "args1" ... "argsN": arguments of messages
|========================================

View File

@ -11089,7 +11089,7 @@ if (hashtable_in)
{
weechat_hashtable_set (hashtable_in, "message",
":nick!user@host PRIVMSG #weechat :message here");
hashtable_out = weechat_info_get_hashtable ("irc_parse_message",
hashtable_out = weechat_info_get_hashtable ("irc_message_parse",
hashtable_in);
/*
* now hashtable_out has following keys/values:
@ -11114,7 +11114,7 @@ dict = weechat.info_get_hashtable(info_name, dict_in)
# example
dict_in = { "message": ":nick!user@host PRIVMSG #weechat :message here" }
weechat.prnt("", "message parsed: %s"
% weechat.info_get_hashtable("irc_parse_message", dict_in))
% weechat.info_get_hashtable("irc_message_parse", dict_in))
----------------------------------------
[[infolists]]

View File

@ -713,17 +713,17 @@ weechat.hook_modifier("irc_in_privmsg", "modifier_cb", "")
[WARNING]
A malformed message could crash WeeChat or cause severe problems!
[[irc_parse_message]]
[[irc_message_parse]]
Parse message
^^^^^^^^^^^^^
_New in version 0.3.4._
You can parse an IRC message with info_hashtable called "irc_parse_message".
You can parse an IRC message with info_hashtable called "irc_message_parse".
[source,python]
----------------------------------------
dict = weechat.info_get_hashtable("irc_parse_message",
dict = weechat.info_get_hashtable("irc_message_parse",
{ "message": ":nick!user@host PRIVMSG #weechat :message here" })
weechat.prnt("", "dict: %s" % dict)

View File

@ -136,6 +136,7 @@
'isupport' (string) +
'prefix_modes' (string) +
'prefix_chars' (string) +
'nick_max_length' (integer) +
'reconnect_delay' (integer) +
'reconnect_start' (time) +
'command_time' (time) +

View File

@ -2,6 +2,8 @@
|========================================
| Extension | Nom | Description | Hashtable (entrée) | Hashtable (sortie)
| irc | irc_parse_message | analyse un message IRC | "message": message IRC | "nick": pseudo, "host": nom d'hôte, "command": commande, "channel": canal, "arguments": paramètres (inclut le canal)
| irc | irc_message_parse | analyse un message IRC | "message": message IRC | "nick": pseudo, "host": nom d'hôte, "command": commande, "channel": canal, "arguments": paramètres (inclut le canal)
| irc | irc_message_split | découper un message IRC (pour tenir dans les 512 octets) | "message": message IRC, "server": nom du serveur (optionnel) | "msg1" ... "msgN": messages à envoyer (sans le "\r\n" final), "args1" ... "argsN": paramètres des messages
|========================================

View File

@ -11271,7 +11271,7 @@ if (hashtable_in)
{
weechat_hashtable_set (hashtable_in, "message",
":nick!user@host PRIVMSG #weechat :message ici");
hashtable_out = weechat_info_get_hashtable ("irc_parse_message",
hashtable_out = weechat_info_get_hashtable ("irc_message_parse",
hashtable_in);
/*
* maintenant hashtable_out a les clés/valeurs suivantes :
@ -11296,7 +11296,7 @@ dict = weechat.info_get_hashtable(info_name, dict_in)
# exemple
dict_in = { "message": ":nick!user@host PRIVMSG #weechat :message ici" }
weechat.prnt("", "message analysé: %s"
% weechat.info_get_hashtable("irc_parse_message", dict_in))
% weechat.info_get_hashtable("irc_message_parse", dict_in))
----------------------------------------
[[infolists]]

View File

@ -732,18 +732,18 @@ weechat.hook_modifier("irc_in_privmsg", "modifier_cb", "")
Un message mal formé peut provoquer un plantage de WeeChat ou de sérieux
problèmes !
[[irc_parse_message]]
[[irc_message_parse]]
Analyser un message
^^^^^^^^^^^^^^^^^^^
_Nouveau dans la version 0.3.4._
Vous pouvez analyser un message IRC avec l'info_hashtable appelée
"irc_parse_message".
"irc_message_parse".
[source,python]
----------------------------------------
dict = weechat.info_get_hashtable("irc_parse_message",
dict = weechat.info_get_hashtable("irc_message_parse",
{ "message": ":nick!user@host PRIVMSG #weechat :message ici" })
weechat.prnt("", "dict: %s" % dict)

View File

@ -136,6 +136,7 @@
'isupport' (string) +
'prefix_modes' (string) +
'prefix_chars' (string) +
'nick_max_length' (integer) +
'reconnect_delay' (integer) +
'reconnect_start' (time) +
'command_time' (time) +

View File

@ -2,6 +2,8 @@
|========================================
| Plugin | Nome | Descrizione | Tabella hash (input) | Tabella hash (output)
| irc | irc_parse_message | controlla un messaggio IRC | "messaggio": messaggio IRC | "nick": nick, "host": nome host, "command": comando, "channel": canale, "arguments": argomenti (include il canale)
| irc | irc_message_parse | controlla un messaggio IRC | "messaggio": messaggio IRC | "nick": nick, "host": nome host, "command": comando, "channel": canale, "arguments": argomenti (include il canale)
| irc | irc_message_split | split an IRC message (to fit in 512 bytes) | "message": IRC message, "server": server name (optional) | "msg1" ... "msgN": messages to send (without final "\r\n"), "args1" ... "argsN": arguments of messages
|========================================

View File

@ -11188,7 +11188,7 @@ if (hashtable_in)
{
weechat_hashtable_set (hashtable_in, "message",
":nick!user@host PRIVMSG #weechat :message here");
hashtable_out = weechat_info_get_hashtable ("irc_parse_message",
hashtable_out = weechat_info_get_hashtable ("irc_message_parse",
hashtable_in);
/*
* now hashtable_out has following keys/values:
@ -11213,7 +11213,7 @@ dict = weechat.info_get_hashtable(info_name, dict_in)
# esempio
dict_in = { "message": ":nick!user@host PRIVMSG #weechat :message here" }
weechat.prnt("", "message parsed: %s"
% weechat.info_get_hashtable("irc_parse_message", dict_in))
% weechat.info_get_hashtable("irc_message_parse", dict_in))
----------------------------------------
[[infolists]]

View File

@ -732,18 +732,18 @@ weechat.hook_modifier("irc_in_privmsg", "modifier_cb", "")
A malformed message could crash WeeChat or cause severe problems!
Un messaggio errato può mandare in crash WeeChat o causare seri problemi!
[[irc_parse_message]]
[[irc_message_parse]]
Verifica messaggio
^^^^^^^^^^^^^^^^^^
_Novità nella versione 0.3.4._
È possibile verificare un messaggio irc con una info_hashtable chiamata
"irc_parse_message".
"irc_message_parse".
[source,python]
----------------------------------------
dict = weechat.info_get_hashtable("irc_parse_message",
dict = weechat.info_get_hashtable("irc_message_parse",
{ "message": ":nick!user@host PRIVMSG #weechat :message here" })
weechat.prnt("", "dict: %s" % dict)

View File

@ -20,7 +20,7 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat 0.3.6-dev\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
"POT-Creation-Date: 2011-08-20 08:17+0200\n"
"POT-Creation-Date: 2011-08-26 10:17+0200\n"
"PO-Revision-Date: 2011-07-05 15:37+0200\n"
"Last-Translator: Jiri Golembiovsky <golemj@gmail.com>\n"
"Language-Team: weechat-dev <weechat-dev@nongnu.org>\n"
@ -5743,6 +5743,18 @@ msgstr ""
"\"nick\": přezdívka, \"host\": host, \"command\": příkaz, \"channel\": "
"kanál, \"arguments\": argumenty (včetně kanálu)"
msgid "split an IRC message (to fit in 512 bytes)"
msgstr ""
msgid "\"message\": IRC message, \"server\": server name (optional)"
msgstr ""
#. TRANSLATORS: please do not translate key names (enclosed by quotes)
msgid ""
"\"msg1\" ... \"msgN\": messages to send (without final \"\\r\\n\"), "
"\"args1\" ... \"argsN\": arguments of messages"
msgstr ""
msgid "list of IRC servers"
msgstr "seznam IRC serverů"

View File

@ -22,7 +22,7 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat 0.3.6-dev\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
"POT-Creation-Date: 2011-08-20 08:17+0200\n"
"POT-Creation-Date: 2011-08-26 10:17+0200\n"
"PO-Revision-Date: 2011-08-15 10:10+0100\n"
"Last-Translator: Nils Görs\n"
"Language-Team: weechat-dev <weechat-dev@nongnu.org>\n"
@ -6100,6 +6100,18 @@ msgstr ""
"\"nick\": nick, \"host\": host, \"command\": command, \"channel\": channel, "
"\"arguments\": arguments (beinhaltet Channel)"
msgid "split an IRC message (to fit in 512 bytes)"
msgstr ""
msgid "\"message\": IRC message, \"server\": server name (optional)"
msgstr ""
#. TRANSLATORS: please do not translate key names (enclosed by quotes)
msgid ""
"\"msg1\" ... \"msgN\": messages to send (without final \"\\r\\n\"), "
"\"args1\" ... \"argsN\": arguments of messages"
msgstr ""
msgid "list of IRC servers"
msgstr "Liste der IRC-Server"

View File

@ -21,7 +21,7 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat 0.3.6-dev\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
"POT-Creation-Date: 2011-08-20 08:17+0200\n"
"POT-Creation-Date: 2011-08-26 10:17+0200\n"
"PO-Revision-Date: 2011-07-05 15:37+0200\n"
"Last-Translator: Elián Hanisch <lambdae2@gmail.com>\n"
"Language-Team: weechat-dev <weechat-dev@nongnu.org>\n"
@ -5840,6 +5840,18 @@ msgstr ""
"\"nick\": apodo, \"host\": host, \"command\": comando, \"channel\": canal, "
"\"arguments\": argumentos (incluye el canal)"
msgid "split an IRC message (to fit in 512 bytes)"
msgstr ""
msgid "\"message\": IRC message, \"server\": server name (optional)"
msgstr ""
#. TRANSLATORS: please do not translate key names (enclosed by quotes)
msgid ""
"\"msg1\" ... \"msgN\": messages to send (without final \"\\r\\n\"), "
"\"args1\" ... \"argsN\": arguments of messages"
msgstr ""
msgid "list of IRC servers"
msgstr "lista de servidores IRC"

View File

@ -21,8 +21,8 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat 0.3.6-dev\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
"POT-Creation-Date: 2011-08-20 08:17+0200\n"
"PO-Revision-Date: 2011-08-20 08:18+0200\n"
"POT-Creation-Date: 2011-08-26 10:17+0200\n"
"PO-Revision-Date: 2011-08-26 10:08+0200\n"
"Last-Translator: Sebastien Helleu <flashcode@flashtux.org>\n"
"Language-Team: weechat-dev <weechat-dev@nongnu.org>\n"
"Language: French\n"
@ -5962,6 +5962,20 @@ msgstr ""
"\"nick\": pseudo, \"host\": nom d'hôte, \"command\": commande, \"channel\": "
"canal, \"arguments\": paramètres (inclut le canal)"
msgid "split an IRC message (to fit in 512 bytes)"
msgstr "découper un message IRC (pour tenir dans les 512 octets)"
msgid "\"message\": IRC message, \"server\": server name (optional)"
msgstr "\"message\": message IRC, \"server\": nom du serveur (optionnel)"
#. TRANSLATORS: please do not translate key names (enclosed by quotes)
msgid ""
"\"msg1\" ... \"msgN\": messages to send (without final \"\\r\\n\"), "
"\"args1\" ... \"argsN\": arguments of messages"
msgstr ""
"\"msg1\" ... \"msgN\": messages à envoyer (sans le \"\\r\\n\" final), "
"\"args1\" ... \"argsN\": paramètres des messages"
msgid "list of IRC servers"
msgstr "liste des serveurs IRC"

View File

@ -20,7 +20,7 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat 0.3.6-dev\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
"POT-Creation-Date: 2011-08-20 08:17+0200\n"
"POT-Creation-Date: 2011-08-26 10:17+0200\n"
"PO-Revision-Date: 2011-05-15 10:51+0200\n"
"Last-Translator: Andras Voroskoi <voroskoi@frugalware.org>\n"
"Language-Team: weechat-dev <weechat-dev@nongnu.org>\n"
@ -5346,6 +5346,18 @@ msgid ""
"\"arguments\": arguments (includes channel)"
msgstr ""
msgid "split an IRC message (to fit in 512 bytes)"
msgstr ""
msgid "\"message\": IRC message, \"server\": server name (optional)"
msgstr ""
#. TRANSLATORS: please do not translate key names (enclosed by quotes)
msgid ""
"\"msg1\" ... \"msgN\": messages to send (without final \"\\r\\n\"), "
"\"args1\" ... \"argsN\": arguments of messages"
msgstr ""
#, fuzzy
msgid "list of IRC servers"
msgstr "IRC szerver portja"

View File

@ -20,7 +20,7 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat 0.3.6-dev\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
"POT-Creation-Date: 2011-08-20 08:17+0200\n"
"POT-Creation-Date: 2011-08-26 10:17+0200\n"
"PO-Revision-Date: 2011-08-16 17:48+0200\n"
"Last-Translator: Marco Paolone <marcopaolone@gmail.com>\n"
"Language-Team: weechat-dev <weechat-dev@nongnu.org>\n"
@ -5916,6 +5916,18 @@ msgstr ""
"\"nick\": nick, \"host\": nome host, \"command\": comando, \"channel\": "
"canale, \"arguments\": argomenti (include il canale)"
msgid "split an IRC message (to fit in 512 bytes)"
msgstr ""
msgid "\"message\": IRC message, \"server\": server name (optional)"
msgstr ""
#. TRANSLATORS: please do not translate key names (enclosed by quotes)
msgid ""
"\"msg1\" ... \"msgN\": messages to send (without final \"\\r\\n\"), "
"\"args1\" ... \"argsN\": arguments of messages"
msgstr ""
msgid "list of IRC servers"
msgstr "elenco di server IRC"

View File

@ -21,7 +21,7 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat 0.3.6-dev\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
"POT-Creation-Date: 2011-08-20 08:17+0200\n"
"POT-Creation-Date: 2011-08-26 10:17+0200\n"
"PO-Revision-Date: 2011-07-05 15:38+0200\n"
"Last-Translator: Krzysztof Koroscik <soltys@szluug.org>\n"
"Language-Team: weechat-dev <weechat-dev@nongnu.org>\n"
@ -5797,6 +5797,18 @@ msgstr ""
"\"nick\": nick, \"host\": host, \"komenda\": komenda, \"kanał\": kanał, "
"\"argumenty\": argumenty (włączając kanał)"
msgid "split an IRC message (to fit in 512 bytes)"
msgstr ""
msgid "\"message\": IRC message, \"server\": server name (optional)"
msgstr ""
#. TRANSLATORS: please do not translate key names (enclosed by quotes)
msgid ""
"\"msg1\" ... \"msgN\": messages to send (without final \"\\r\\n\"), "
"\"args1\" ... \"argsN\": arguments of messages"
msgstr ""
msgid "list of IRC servers"
msgstr "lista serwerów IRC"

View File

@ -20,7 +20,7 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat 0.3.6-dev\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
"POT-Creation-Date: 2011-08-20 08:17+0200\n"
"POT-Creation-Date: 2011-08-26 10:17+0200\n"
"PO-Revision-Date: 2011-05-15 10:52+0200\n"
"Last-Translator: Ivan Sichmann Freitas <ivansichfreitas@gmail.com>\n"
"Language-Team: weechat-dev <weechat-dev@nongnu.org>\n"
@ -5227,6 +5227,18 @@ msgid ""
"\"arguments\": arguments (includes channel)"
msgstr ""
msgid "split an IRC message (to fit in 512 bytes)"
msgstr ""
msgid "\"message\": IRC message, \"server\": server name (optional)"
msgstr ""
#. TRANSLATORS: please do not translate key names (enclosed by quotes)
msgid ""
"\"msg1\" ... \"msgN\": messages to send (without final \"\\r\\n\"), "
"\"args1\" ... \"argsN\": arguments of messages"
msgstr ""
msgid "list of IRC servers"
msgstr ""

View File

@ -20,7 +20,7 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat 0.3.6-dev\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
"POT-Creation-Date: 2011-08-20 08:17+0200\n"
"POT-Creation-Date: 2011-08-26 10:17+0200\n"
"PO-Revision-Date: 2011-05-15 10:52+0200\n"
"Last-Translator: Pavel Shevchuk <stlwrt@gmail.com>\n"
"Language-Team: weechat-dev <weechat-dev@nongnu.org>\n"
@ -5361,6 +5361,18 @@ msgid ""
"\"arguments\": arguments (includes channel)"
msgstr ""
msgid "split an IRC message (to fit in 512 bytes)"
msgstr ""
msgid "\"message\": IRC message, \"server\": server name (optional)"
msgstr ""
#. TRANSLATORS: please do not translate key names (enclosed by quotes)
msgid ""
"\"msg1\" ... \"msgN\": messages to send (without final \"\\r\\n\"), "
"\"args1\" ... \"argsN\": arguments of messages"
msgstr ""
#, fuzzy
msgid "list of IRC servers"
msgstr "порт IRC сервера"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
"POT-Creation-Date: 2011-08-20 08:17+0200\n"
"POT-Creation-Date: 2011-08-26 10:17+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -4598,6 +4598,18 @@ msgid ""
"\"arguments\": arguments (includes channel)"
msgstr ""
msgid "split an IRC message (to fit in 512 bytes)"
msgstr ""
msgid "\"message\": IRC message, \"server\": server name (optional)"
msgstr ""
#. TRANSLATORS: please do not translate key names (enclosed by quotes)
msgid ""
"\"msg1\" ... \"msgN\": messages to send (without final \"\\r\\n\"), "
"\"args1\" ... \"argsN\": arguments of messages"
msgstr ""
msgid "list of IRC servers"
msgstr ""

View File

@ -334,20 +334,16 @@ irc_command_allserv (void *data, struct t_gui_buffer *buffer, int argc,
}
/*
* irc_command_me_channel: send a ctcp action to a channel
* irc_command_me_channel_display: display a ctcp action on channel
*/
void
irc_command_me_channel (struct t_irc_server *server,
struct t_irc_channel *channel,
const char *arguments)
irc_command_me_channel_display (struct t_irc_server *server,
struct t_irc_channel *channel,
const char *arguments)
{
char *string;
irc_server_sendf (server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL,
"PRIVMSG %s :\01ACTION %s\01",
channel->name,
(arguments && arguments[0]) ? arguments : "");
string = (arguments && arguments[0]) ?
irc_color_decode (arguments,
weechat_config_boolean (irc_config_network_colors_receive)) : NULL;
@ -365,6 +361,42 @@ irc_command_me_channel (struct t_irc_server *server,
free (string);
}
/*
* irc_command_me_channel: send a ctcp action to a channel
*/
void
irc_command_me_channel (struct t_irc_server *server,
struct t_irc_channel *channel,
const char *arguments)
{
struct t_hashtable *hashtable;
int number;
char hash_key[32];
const char *str_args;
hashtable = irc_server_sendf (server,
IRC_SERVER_SEND_OUTQ_PRIO_HIGH | IRC_SERVER_SEND_RETURN_HASHTABLE,
NULL,
"PRIVMSG %s :\01ACTION %s\01",
channel->name,
(arguments && arguments[0]) ? arguments : "");
if (hashtable)
{
number = 1;
while (1)
{
snprintf (hash_key, sizeof (hash_key), "args%d", number);
str_args = weechat_hashtable_get (hashtable, hash_key);
if (!str_args)
break;
irc_command_me_channel_display (server, channel, str_args);
number++;
}
weechat_hashtable_free (hashtable);
}
}
/*
* irc_command_me_all_channels: send a ctcp action to all channels of a server
*/
@ -1737,7 +1769,7 @@ irc_command_ison (void *data, struct t_gui_buffer *buffer, int argc,
if (argc > 1)
{
irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL,
"ISON %s", argv_eol[1]);
"ISON :%s", argv_eol[1]);
}
else
{
@ -2682,9 +2714,10 @@ int
irc_command_notice (void *data, struct t_gui_buffer *buffer, int argc,
char **argv, char **argv_eol)
{
char *string;
int arg_nick, arg_text;
char *string, hash_key[32], *str_args;
int arg_nick, arg_text, number;
struct t_irc_channel *ptr_channel;
struct t_hashtable *hashtable;
IRC_BUFFER_GET_SERVER(buffer);
@ -2703,28 +2736,42 @@ irc_command_notice (void *data, struct t_gui_buffer *buffer, int argc,
}
IRC_COMMAND_CHECK_SERVER("notice", 1);
string = irc_color_decode (argv_eol[arg_text],
weechat_config_boolean (irc_config_network_colors_receive));
ptr_channel = irc_channel_search (ptr_server, argv[arg_nick]);
weechat_printf_tags ((ptr_channel) ? ptr_channel->buffer : ptr_server->buffer,
"notify_none,no_highlight",
"%s%s%s%s -> %s%s%s: %s",
weechat_prefix ("network"),
IRC_COLOR_NOTICE,
/* TRANSLATORS: "Notice" is command name in IRC protocol (translation is frequently the same word) */
_("Notice"),
IRC_COLOR_CHAT,
(irc_channel_is_channel (argv[arg_nick])) ?
IRC_COLOR_CHAT_CHANNEL : IRC_COLOR_CHAT_NICK,
argv[arg_nick],
IRC_COLOR_CHAT,
(string) ? string : argv_eol[arg_text]);
if (string)
free (string);
irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL,
"NOTICE %s :%s",
argv[arg_nick], argv_eol[arg_text]);
hashtable = irc_server_sendf (ptr_server,
IRC_SERVER_SEND_OUTQ_PRIO_HIGH | IRC_SERVER_SEND_RETURN_HASHTABLE,
NULL,
"NOTICE %s :%s",
argv[arg_nick], argv_eol[arg_text]);
if (hashtable)
{
number = 1;
while (1)
{
snprintf (hash_key, sizeof (hash_key), "args%d", number);
str_args = weechat_hashtable_get (hashtable, hash_key);
if (!str_args)
break;
string = irc_color_decode (str_args,
weechat_config_boolean (irc_config_network_colors_receive));
weechat_printf_tags ((ptr_channel) ? ptr_channel->buffer : ptr_server->buffer,
"notify_none,no_highlight",
"%s%s%s%s -> %s%s%s: %s",
weechat_prefix ("network"),
IRC_COLOR_NOTICE,
/* TRANSLATORS: "Notice" is command name in IRC protocol (translation is frequently the same word) */
_("Notice"),
IRC_COLOR_CHAT,
(irc_channel_is_channel (argv[arg_nick])) ?
IRC_COLOR_CHAT_CHANNEL : IRC_COLOR_CHAT_NICK,
argv[arg_nick],
IRC_COLOR_CHAT,
(string) ? string : str_args);
if (string)
free (string);
number++;
}
weechat_hashtable_free (hashtable);
}
}
else
{

View File

@ -240,23 +240,34 @@ struct t_hashtable *
irc_info_get_info_hashtable_cb (void *data, const char *info_name,
struct t_hashtable *hashtable)
{
const char *message;
const char *server, *message;
struct t_irc_server *ptr_server;
struct t_hashtable *value;
/* make C compiler happy */
(void) data;
if (weechat_strcasecmp (info_name, "irc_parse_message") == 0)
if (!hashtable)
return NULL;
if (weechat_strcasecmp (info_name, "irc_message_parse") == 0)
{
if (hashtable)
message = weechat_hashtable_get (hashtable, "message");
if (message)
{
message = (const char *)weechat_hashtable_get (hashtable,
"message");
if (message)
{
value = irc_message_parse_to_hashtable (message);
return value;
}
value = irc_message_parse_to_hashtable (message);
return value;
}
}
else if (weechat_strcasecmp (info_name, "irc_message_split") == 0)
{
server = weechat_hashtable_get (hashtable, "server");
ptr_server = (server) ? irc_server_search (server) : NULL;
message = weechat_hashtable_get (hashtable, "message");
if (message)
{
value = irc_message_split (ptr_server, message);
return value;
}
}
@ -592,7 +603,7 @@ irc_info_init ()
&irc_info_get_info_cb, NULL);
/* info_hashtable hooks */
weechat_hook_info_hashtable ("irc_parse_message",
weechat_hook_info_hashtable ("irc_message_parse",
N_("parse an IRC message"),
N_("\"message\": IRC message"),
/* TRANSLATORS: please do not translate key names (enclosed by quotes) */
@ -600,6 +611,15 @@ irc_info_init ()
"\"command\": command, \"channel\": channel, "
"\"arguments\": arguments (includes channel)"),
&irc_info_get_info_hashtable_cb, NULL);
weechat_hook_info_hashtable ("irc_message_split",
N_("split an IRC message (to fit in 512 bytes)"),
N_("\"message\": IRC message, \"server\": server "
"name (optional)"),
/* TRANSLATORS: please do not translate key names (enclosed by quotes) */
N_("\"msg1\" ... \"msgN\": messages to send "
"(without final \"\\r\\n\"), "
"\"args1\" ... \"argsN\": arguments of messages"),
&irc_info_get_info_hashtable_cb, NULL);
/* infolist hooks */
weechat_hook_infolist ("irc_server",

View File

@ -22,6 +22,7 @@
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "../weechat-plugin.h"
@ -85,8 +86,9 @@ void
irc_input_send_user_message (struct t_gui_buffer *buffer, int flags,
const char *tags, char *message)
{
int max_length;
char *pos, *pos_max, *last_space, *pos_next, *next, saved_char;
int number;
char hash_key[32], *str_args;
struct t_hashtable *hashtable;
IRC_BUFFER_GET_SERVER_CHANNEL(buffer);
@ -100,45 +102,24 @@ irc_input_send_user_message (struct t_gui_buffer *buffer, int flags,
weechat_prefix ("error"), IRC_PLUGIN_NAME);
return;
}
next = NULL;
last_space = NULL;
saved_char = '\0';
max_length = 512 - 16 - 65 - 10 - strlen (ptr_server->nick) -
strlen (ptr_channel->name);
if (max_length > 0)
hashtable = irc_server_sendf (ptr_server,
flags | IRC_SERVER_SEND_RETURN_HASHTABLE,
tags,
"PRIVMSG %s :%s",
ptr_channel->name, message);
if (hashtable)
{
if ((int)strlen (message) > max_length)
number = 1;
while (1)
{
pos = message;
pos_max = message + max_length;
while (pos[0])
{
if (pos[0] == ' ')
last_space = pos;
pos_next = weechat_utf8_next_char (pos);
if (pos_next > pos_max)
break;
pos = pos_next;
}
if (last_space && (last_space < pos))
pos = last_space + 1;
saved_char = pos[0];
pos[0] = '\0';
next = pos;
snprintf (hash_key, sizeof (hash_key), "args%d", number);
str_args = weechat_hashtable_get (hashtable, hash_key);
if (!str_args)
break;
irc_input_user_message_display (buffer, str_args);
number++;
}
}
irc_server_sendf (ptr_server, flags, tags,
"PRIVMSG %s :%s", ptr_channel->name, message);
irc_input_user_message_display (buffer, message);
if (next)
{
next[0] = saved_char;
irc_input_send_user_message (buffer, flags, tags, next);
weechat_hashtable_free (hashtable);
}
}

View File

@ -338,3 +338,523 @@ irc_message_replace_vars (struct t_irc_server *server,
/* return result */
return res;
}
/*
* irc_message_split_add: add a message + arguments in hashtable
*/
void
irc_message_split_add (struct t_hashtable *hashtable, int number,
const char *message, const char *arguments)
{
char key[32];
if (message)
{
snprintf (key, sizeof (key), "msg%d", number);
weechat_hashtable_set (hashtable, key, message);
if (weechat_irc_plugin->debug >= 2)
{
weechat_printf (NULL,
"irc_message_split_add >> %s='%s' (%d bytes)",
key, message,
strlen (message));
}
}
if (arguments)
{
snprintf (key, sizeof (key), "args%d", number);
weechat_hashtable_set (hashtable, key, arguments);
if (weechat_irc_plugin->debug >= 2)
{
weechat_printf (NULL,
"irc_message_split_add >> %s='%s'",
key, arguments);
}
}
}
/*
* irc_message_split_string: split "arguments" using delimiter and max length
* messages added to hashtable are:
* host + command + target + XXX + suffix
* (where XXX is part of "arguments")
* return 1 if split ok, 0 if error
*/
int
irc_message_split_string (struct t_hashtable *hashtable,
const char *host,
const char *command,
const char *target,
const char *prefix,
const char *arguments,
const char *suffix,
const char delimiter,
int max_length_host)
{
const char *pos, *pos_max, *pos_next, *pos_last_delim;
char message[1024], *dup_arguments;
int max_length, number;
/*
* Examples of arguments for this function:
*
* message..: :nick!user@host.com PRIVMSG #channel :Hello world!
* arguments:
* host : ":nick!user@host.com"
* command : "PRIVMSG"
* target : "#channel"
* prefix : ":"
* arguments: "Hello world!"
* suffix : ""
*
* message..: :nick!user@host.com PRIVMSG #channel :\01ACTION is eating\01
* arguments:
* host : ":nick!user@host.com"
* command : "PRIVMSG"
* target : "#channel"
* prefix : ":\01ACTION "
* arguments: "is eating"
* suffix : "\01"
*/
max_length = 510;
if (max_length_host >= 0)
max_length -= max_length_host;
else
max_length -= (host) ? strlen (host) + 1 : 0;
max_length -= strlen (command) + 1;
if (target)
max_length -= strlen (target);
if (prefix)
max_length -= strlen (prefix);
if (suffix)
max_length -= strlen (suffix);
if (max_length < 2)
return 0;
/* debug message */
if (weechat_irc_plugin->debug >= 2)
{
weechat_printf (NULL,
"irc_message_split_string: host='%s', command='%s', "
"target='%s', prefix='%s', arguments='%s', "
"suffix='%s', max_length=%d",
host, command, target, prefix, arguments, suffix,
max_length);
}
number = 1;
if (!arguments || !arguments[0])
{
snprintf (message, sizeof (message), "%s%s%s %s%s%s%s",
(host) ? host : "",
(host) ? " " : "",
command,
(target) ? target : "",
(target && target[0]) ? " " : "",
(prefix) ? prefix : "",
(suffix) ? suffix : "");
irc_message_split_add (hashtable, 1, message, "");
return 1;
}
while (arguments && arguments[0])
{
pos = arguments;
pos_max = pos + max_length;
pos_last_delim = NULL;
while (pos && pos[0])
{
if (pos[0] == delimiter)
pos_last_delim = pos;
pos_next = weechat_utf8_next_char (pos);
if (pos_next > pos_max)
break;
pos = pos_next;
}
if (pos[0] && pos_last_delim)
pos = pos_last_delim;
dup_arguments = weechat_strndup (arguments, pos - arguments);
if (dup_arguments)
{
snprintf (message, sizeof (message), "%s%s%s %s%s%s%s%s",
(host) ? host : "",
(host) ? " " : "",
command,
(target) ? target : "",
(target && target[0]) ? " " : "",
(prefix) ? prefix : "",
dup_arguments,
(suffix) ? suffix : "");
irc_message_split_add (hashtable, number, message, dup_arguments);
number++;
free (dup_arguments);
}
arguments = (pos == pos_last_delim) ? pos + 1 : pos;
}
return 1;
}
/*
* irc_message_split_join: split a JOIN message, taking care of keeping
* channel keys with channel names
* return 1 if split ok, 0 if error
*/
int
irc_message_split_join (struct t_hashtable *hashtable,
const char *host, const char *arguments)
{
int number, channels_count, keys_count, length, length_no_channel;
int length_to_add, index_channel;
char **channels, **keys, *pos, *str;
char msg_to_send[2048], keys_to_add[2048];
number = 1;
channels = NULL;
channels_count = 0;
keys = NULL;
keys_count = 0;
pos = strchr (arguments, ' ');
if (pos)
{
str = weechat_strndup (arguments, pos - arguments);
if (!str)
return 0;
channels = weechat_string_split (str, ",", 0, 0, &channels_count);
free (str);
while (pos[0] == ' ')
{
pos++;
}
if (pos[0])
keys = weechat_string_split (pos, ",", 0, 0, &keys_count);
}
else
{
channels = weechat_string_split (arguments, ",", 0, 0, &channels_count);
}
snprintf (msg_to_send, sizeof (msg_to_send), "%s%sJOIN",
(host) ? host : "",
(host) ? " " : "");
length = strlen (msg_to_send);
length_no_channel = length;
keys_to_add[0] = '\0';
index_channel = 0;
while (index_channel < channels_count)
{
length_to_add = 1 + strlen (channels[index_channel]);
if (index_channel < keys_count)
length_to_add += 1 + strlen (keys[index_channel]);
if ((length + length_to_add < 510) || (length == length_no_channel))
{
if (length + length_to_add < (int)sizeof (msg_to_send))
{
strcat (msg_to_send, (length == length_no_channel) ? " " : ",");
strcat (msg_to_send, channels[index_channel]);
}
if (index_channel < keys_count)
{
if (strlen (keys_to_add) + 1 +
strlen (keys[index_channel]) < (int)sizeof (keys_to_add))
{
strcat (keys_to_add, (keys_to_add[0]) ? "," : " ");
strcat (keys_to_add, keys[index_channel]);
}
}
length += length_to_add;
index_channel++;
}
else
{
strcat (msg_to_send, keys_to_add);
irc_message_split_add (hashtable, number,
msg_to_send,
msg_to_send + length_no_channel + 1);
number++;
snprintf (msg_to_send, sizeof (msg_to_send), "%s%sJOIN",
(host) ? host : "",
(host) ? " " : "");
length = strlen (msg_to_send);
keys_to_add[0] = '\0';
}
}
if (length > length_no_channel)
{
strcat (msg_to_send, keys_to_add);
irc_message_split_add (hashtable, number,
msg_to_send,
msg_to_send + length_no_channel + 1);
}
if (channels)
weechat_string_free_split (channels);
if (keys)
weechat_string_free_split (keys);
return 1;
}
/*
* irc_message_split_privmsg: split a PRIVMSG message, taking care of keeping
* the '\01' char used in CTCP messages
* return 1 if split ok, 0 if error
*/
int
irc_message_split_privmsg (struct t_hashtable *hashtable,
char *host, char *command, char *target,
char *arguments, int max_length_host)
{
char prefix[512], suffix[2], *pos, saved_char;
int length, rc;
/*
* message sent looks like:
* PRIVMSG #channel :hello world!
*
* when IRC server sends message to other people, message looks like:
* :nick!user@host.com PRIVMSG #channel :hello world!
*/
/* for CTCP, target2 will be '\01xxxx' and suffix '\01' */
prefix[0] = '\0';
suffix[0] = '\0';
length = strlen (arguments);
if ((arguments[0] == '\01')
&& (arguments[length - 1] == '\01'))
{
pos = strchr (arguments, ' ');
if (pos)
{
pos++;
saved_char = pos[0];
pos[0] = '\0';
snprintf (prefix, sizeof (prefix), ":%s", arguments);
pos[0] = saved_char;
arguments[length - 1] = '\0';
arguments = pos;
suffix[0] = '\01';
suffix[1] = '\0';
}
}
if (!prefix[0])
strcpy (prefix, ":");
rc = irc_message_split_string (hashtable, host, command, target,
prefix, arguments, suffix,
' ', max_length_host);
return rc;
}
/*
* irc_message_split_005: split a 005 message (isupport)
* return 1 if split ok, 0 if error
*/
int
irc_message_split_005 (struct t_hashtable *hashtable,
char *host, char *command, char *target, char *arguments)
{
char *pos, suffix[512];
/*
* 005 message looks like:
* :server 005 mynick MODES=4 CHANLIMIT=#:20 NICKLEN=16 USERLEN=10
* HOSTLEN=63 TOPICLEN=450 KICKLEN=450 CHANNELLEN=30 KEYLEN=23
* CHANTYPES=# PREFIX=(ov)@+ CASEMAPPING=ascii CAPAB IRCD=dancer
* :are available on this server
*/
/* search suffix */
suffix[0] = '\0';
pos = strstr (arguments, " :");
if (pos)
{
snprintf (suffix, sizeof (suffix), "%s", pos);
pos[0] = '\0';
}
return irc_message_split_string (hashtable, host, command, target,
NULL, arguments, suffix, ' ', -1);
}
/*
* irc_message_split: split an IRC message about to be sent to IRC server
* The maximum length of an IRC message is 510 bytes for
* user data + final "\r\n", so full size is 512 bytes.
* The split takes care about type of message to do a split
* at best place in message.
* The hashtable returned contains keys "msg1", "msg2", ...,
* "msgN" with split of message (these messages do not
* include the final "\r\n").
* Hashtable contains "args1", "args2", ..., "argsN" with
* split of arguments only (no host/command here).
* Each message in hashtable has command and arguments, and
* then is ready to be sent to IRC server.
*/
struct t_hashtable *
irc_message_split (struct t_irc_server *server, const char *message)
{
struct t_hashtable *hashtable;
char **argv, **argv_eol, *host, *command, *arguments, target[512];
int split_ok, argc, index_args, max_length_nick, max_length_host;
split_ok = 0;
host = NULL;
command = NULL;
arguments = NULL;
index_args = 0;
/* debug message */
if (weechat_irc_plugin->debug >= 2)
weechat_printf (NULL, "irc_message_split: message='%s'", message);
hashtable = weechat_hashtable_new (8,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
NULL,
NULL);
if (!hashtable)
return NULL;
if (!message || !message[0])
goto end;
argv = weechat_string_split (message, " ", 0, 0, &argc);
argv_eol = weechat_string_split (message, " ", 1, 0, NULL);
if (argc < 2)
goto end;
if (argv[0][0] == ':')
{
if (argc < 3)
goto end;
host = argv[0];
command = argv[1];
arguments = argv_eol[2];
index_args = 2;
}
else
{
command = argv[0];
arguments = argv_eol[1];
index_args = 1;
}
max_length_nick = (server && (server->nick_max_length > 0)) ?
server->nick_max_length : 16;
max_length_host = 1 + /* ":" */
max_length_nick + /* nick */
1 + /* "!" */
63 + /* host */
1; /* " " */
if ((weechat_strcasecmp (command, "ison") == 0)
|| (weechat_strcasecmp (command, "wallops") == 0))
{
split_ok = irc_message_split_string (hashtable, host, command,
NULL, ":",
(argv_eol[index_args][0] == ':') ?
argv_eol[index_args] + 1 : argv_eol[index_args],
NULL, ' ', max_length_host);
}
else if (weechat_strcasecmp (command, "join") == 0)
{
/* split join (if it's more than 510 bytes) */
if (strlen (message) > 510)
split_ok = irc_message_split_join (hashtable, host, arguments);
}
else if (weechat_strcasecmp (command, "notice") == 0)
{
if (index_args + 1 <= argc - 1)
{
split_ok = irc_message_split_string (hashtable, host, command,
argv[index_args], ":",
(argv_eol[index_args + 1][0] == ':') ?
argv_eol[index_args + 1] + 1 : argv_eol[index_args + 1],
NULL, ' ', max_length_host);
}
}
else if (weechat_strcasecmp (command, "privmsg") == 0)
{
/* split privmsg */
if (index_args + 1 <= argc - 1)
{
split_ok = irc_message_split_privmsg (hashtable, host, command,
argv[index_args],
(argv_eol[index_args + 1][0] == ':') ?
argv_eol[index_args + 1] + 1 : argv_eol[index_args + 1],
max_length_host);
}
}
else if (weechat_strcasecmp (command, "005") == 0)
{
/* split 005 (isupport) */
if (index_args + 1 <= argc - 1)
{
split_ok = irc_message_split_005 (hashtable, host, command,
argv[index_args],
(argv_eol[index_args + 1][0] == ':') ?
argv_eol[index_args + 1] + 1 : argv_eol[index_args + 1]);
}
}
else if (weechat_strcasecmp (command, "353") == 0)
{
/*
* split 353 (list of users on channel):
* :server 353 mynick = #channel :mynick nick1 @nick2 +nick3
*/
if (index_args + 2 <= argc - 1)
{
if (irc_channel_is_channel (argv[index_args + 1]))
{
snprintf (target, sizeof (target), "%s %s",
argv[index_args], argv[index_args + 1]);
split_ok = irc_message_split_string (hashtable, host, command,
target, ":",
(argv_eol[index_args + 2][0] == ':') ?
argv_eol[index_args + 2] + 1 : argv_eol[index_args + 2],
NULL, ' ', -1);
}
else
{
if (index_args + 3 <= argc - 1)
{
snprintf (target, sizeof (target), "%s %s %s",
argv[index_args], argv[index_args + 1],
argv[index_args + 2]);
split_ok = irc_message_split_string (hashtable, host, command,
target, ":",
(argv_eol[index_args + 3][0] == ':') ?
argv_eol[index_args + 3] + 1 : argv_eol[index_args + 3],
NULL, ' ', -1);
}
}
}
}
end:
if (!split_ok
|| (weechat_hashtable_get_integer (hashtable, "items_count") == 0))
{
irc_message_split_add (hashtable, 1, message, arguments);
}
weechat_string_free_split (argv);
weechat_string_free_split (argv_eol);
return hashtable;
}

View File

@ -32,5 +32,7 @@ extern const char *irc_message_get_address_from_host (const char *host);
extern char *irc_message_replace_vars (struct t_irc_server *server,
struct t_irc_channel *channel,
const char *string);
extern struct t_hashtable *irc_message_split (struct t_irc_server *server,
const char *message);
#endif /* __WEECHAT_IRC_MESSAGE_H */

View File

@ -1908,9 +1908,9 @@ IRC_PROTOCOL_CALLBACK(001)
IRC_PROTOCOL_CALLBACK(005)
{
char *pos, *pos2, *pos_start;
int length_isupport, length;
char *pos, *pos2, *pos_start, *error;
int length_isupport, length, nick_max_length;
/*
* 005 message looks like:
* :server 005 mynick MODES=4 CHANLIMIT=#:20 NICKLEN=16 USERLEN=10
@ -1938,6 +1938,22 @@ IRC_PROTOCOL_CALLBACK(005)
pos2[0] = ' ';
}
/* save max nick length */
pos = strstr (argv_eol[3], "NICKLEN=");
if (pos)
{
pos += 8;
pos2 = strchr (pos, ' ');
if (pos2)
pos2[0] = '\0';
error = NULL;
nick_max_length = (int)strtol (pos, &error, 10);
if (error && !error[0] && (nick_max_length > 0))
server->nick_max_length = nick_max_length;
if (pos2)
pos2[0] = ' ';
}
/* save whole message (concatenate to existing isupport, if any) */
pos_start = NULL;
pos = strstr (argv_eol[3], " :");

View File

@ -633,6 +633,7 @@ irc_server_alloc (const char *name)
new_server->isupport = NULL;
new_server->prefix_modes = NULL;
new_server->prefix_chars = NULL;
new_server->nick_max_length = 0;
new_server->reconnect_delay = 0;
new_server->reconnect_start = 0;
new_server->command_time = 0;
@ -1738,32 +1739,85 @@ irc_server_send_one_msg (struct t_irc_server *server, int flags,
/*
* irc_server_sendf: send formatted data to IRC server
* many messages may be sent, separated by '\n'
* if flags contains "IRC_SERVER_SEND_RETURN_HASHTABLE", then
* hashtable with split of message is returned
* (see function irc_message_split() in irc-message.c)
* note: hashtable must be freed after use
*/
void
struct t_hashtable *
irc_server_sendf (struct t_irc_server *server, int flags, const char *tags,
const char *format, ...)
{
va_list args;
static char buffer[4096];
char **items;
int i, items_count;
char **items, hash_key[32];
const char *str_message, *str_args;
int i, items_count, number, ret_number, rc;
struct t_hashtable *hashtable, *ret_hashtable;
if (!server)
return;
return NULL;
va_start (args, format);
vsnprintf (buffer, sizeof (buffer) - 1, format, args);
va_end (args);
items = weechat_string_split (buffer, "\n", 0, 0, &items_count);
weechat_va_format (format);
if (!vbuffer)
return NULL;
ret_hashtable = NULL;
ret_number = 1;
if (flags & IRC_SERVER_SEND_RETURN_HASHTABLE)
{
ret_hashtable = weechat_hashtable_new (8,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
NULL,
NULL);
}
rc = 1;
items = weechat_string_split (vbuffer, "\n", 0, 0, &items_count);
for (i = 0; i < items_count; i++)
{
if (!irc_server_send_one_msg (server, flags, items[i], tags))
break;
/* split message if needed (max is 512 bytes including final "\r\n") */
hashtable = irc_message_split (server, items[i]);
if (hashtable)
{
number = 1;
while (1)
{
snprintf (hash_key, sizeof (hash_key), "msg%d", number);
str_message = weechat_hashtable_get (hashtable, hash_key);
if (!str_message)
break;
snprintf (hash_key, sizeof (hash_key), "args%d", number);
str_args = weechat_hashtable_get (hashtable, hash_key);
rc = irc_server_send_one_msg (server, flags, str_message, tags);
if (!rc)
break;
if (ret_hashtable)
{
snprintf (hash_key, sizeof (hash_key), "msg%d", ret_number);
weechat_hashtable_set (ret_hashtable, hash_key, str_message);
if (str_args)
{
snprintf (hash_key, sizeof (hash_key), "args%d", ret_number);
weechat_hashtable_set (ret_hashtable, hash_key, str_args);
}
ret_number++;
}
number++;
}
weechat_hashtable_free (hashtable);
if (!rc)
break;
}
}
if (items)
weechat_string_free_split (items);
free (vbuffer);
return ret_hashtable;
}
/*
@ -3550,14 +3604,14 @@ irc_server_autojoin_channels (struct t_irc_server *server)
if (ptr_channel->key)
{
irc_server_sendf (server,
IRC_SERVER_SEND_OUTQ_PRIO_LOW, NULL,
IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL,
"JOIN %s %s",
ptr_channel->name, ptr_channel->key);
}
else
{
irc_server_sendf (server,
IRC_SERVER_SEND_OUTQ_PRIO_LOW, NULL,
IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL,
"JOIN %s",
ptr_channel->name);
}
@ -3995,6 +4049,7 @@ irc_server_hdata_server_cb (void *data, const char *hdata_name)
WEECHAT_HDATA_VAR(struct t_irc_server, isupport, STRING, NULL);
WEECHAT_HDATA_VAR(struct t_irc_server, prefix_modes, STRING, NULL);
WEECHAT_HDATA_VAR(struct t_irc_server, prefix_chars, STRING, NULL);
WEECHAT_HDATA_VAR(struct t_irc_server, nick_max_length, INTEGER, NULL);
WEECHAT_HDATA_VAR(struct t_irc_server, reconnect_delay, INTEGER, NULL);
WEECHAT_HDATA_VAR(struct t_irc_server, reconnect_start, TIME, NULL);
WEECHAT_HDATA_VAR(struct t_irc_server, command_time, TIME, NULL);
@ -4180,6 +4235,8 @@ irc_server_add_to_infolist (struct t_infolist *infolist,
return 0;
if (!weechat_infolist_new_var_string (ptr_item, "prefix_chars", server->prefix_chars))
return 0;
if (!weechat_infolist_new_var_integer (ptr_item, "nick_max_length", server->nick_max_length))
return 0;
if (!weechat_infolist_new_var_integer (ptr_item, "reconnect_delay", server->reconnect_delay))
return 0;
if (!weechat_infolist_new_var_time (ptr_item, "reconnect_start", server->reconnect_start))
@ -4481,6 +4538,7 @@ irc_server_print_log ()
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);
weechat_log_printf (" nick_max_length. . . : %d", ptr_server->nick_max_length);
weechat_log_printf (" reconnect_delay. . . : %d", ptr_server->reconnect_delay);
weechat_log_printf (" reconnect_start. . . : %ld", ptr_server->reconnect_start);
weechat_log_printf (" command_time . . . . : %ld", ptr_server->command_time);

View File

@ -98,8 +98,9 @@ enum t_irc_server_option
#define IRC_SERVER_NUM_OUTQUEUES_PRIO 2
/* flags for irc_server_sendf() */
#define IRC_SERVER_SEND_OUTQ_PRIO_HIGH 1
#define IRC_SERVER_SEND_OUTQ_PRIO_LOW 2
#define IRC_SERVER_SEND_OUTQ_PRIO_HIGH 1
#define IRC_SERVER_SEND_OUTQ_PRIO_LOW 2
#define IRC_SERVER_SEND_RETURN_HASHTABLE 4
/* output queue of messages to server (for sending slowly to server) */
@ -154,6 +155,7 @@ struct t_irc_server
char *isupport; /* copy of message 005 (ISUPPORT) */
char *prefix_modes; /* prefix modes from msg 005 (eg "aohv") */
char *prefix_chars; /* prefix chars from msg 005 (eg "&@%+") */
int nick_max_length; /* max lenth of nick (from msg 005) */
int reconnect_delay; /* current reconnect delay (growing) */
time_t reconnect_start; /* this time + delay = reconnect time */
time_t command_time; /* this time + command_delay = time to */
@ -240,8 +242,10 @@ extern void irc_server_send_signal (struct t_irc_server *server,
const char *full_message,
const char *tags);
extern void irc_server_set_send_default_tags (const char *tags);
extern void irc_server_sendf (struct t_irc_server *server, int flags,
const char *tags, const char *format, ...);
extern struct t_hashtable *irc_server_sendf (struct t_irc_server *server,
int flags,
const char *tags,
const char *format, ...);
extern struct t_irc_server *irc_server_search (const char *server_name);
extern void irc_server_set_buffer_title (struct t_irc_server *server);
extern struct t_gui_buffer *irc_server_create_buffer (struct t_irc_server *server);

View File

@ -91,11 +91,11 @@ relay_client_irc_command_ignored (const char *irc_command)
}
/*
* relay_client_irc_parse_message: parse IRC message
* relay_client_irc_message_parse: parse IRC message
*/
struct t_hashtable *
relay_client_irc_parse_message (const char *message)
relay_client_irc_message_parse (const char *message)
{
struct t_hashtable *hash_msg, *hash_parsed;
@ -115,7 +115,7 @@ relay_client_irc_parse_message (const char *message)
goto end;
}
weechat_hashtable_set (hash_msg, "message", message);
hash_parsed = weechat_info_get_hashtable ("irc_parse_message",
hash_parsed = weechat_info_get_hashtable ("irc_message_parse",
hash_msg);
if (!hash_parsed)
{
@ -139,55 +139,77 @@ end:
int
relay_client_irc_sendf (struct t_relay_client *client, const char *format, ...)
{
va_list args;
static char buffer[4096];
int length, num_sent;
char *pos;
int length, num_sent, total_sent, number;
char *pos, hash_key[32], *message;
const char *str_message;
struct t_hashtable *hashtable_in, *hashtable_out;
if (!client)
return 0;
va_start (args, format);
vsnprintf (buffer, sizeof (buffer) - 3, format, args);
va_end (args);
weechat_va_format (format);
if (!vbuffer)
return 0;
if (weechat_relay_plugin->debug >= 2)
{
weechat_printf (NULL, "%s: send: %s",
RELAY_PLUGIN_NAME, buffer);
}
total_sent = 0;
length = strlen (buffer);
pos = strchr (buffer, '\r');
pos = strchr (vbuffer, '\r');
if (pos)
pos[0] = '\0';
pos = strchr (vbuffer, '\n');
if (pos)
pos[0] = '\0';
relay_raw_print (client, 1, buffer);
if (pos)
pos[0] = '\r';
else
hashtable_in = weechat_hashtable_new (8,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
NULL,
NULL);
if (hashtable_in)
{
buffer[length] = '\r';
buffer[length + 1] = '\n';
buffer[length + 2] = '\0';
length += 2;
weechat_hashtable_set (hashtable_in, "server", client->protocol_args);
weechat_hashtable_set (hashtable_in, "message", vbuffer);
hashtable_out = weechat_info_get_hashtable ("irc_message_split",
hashtable_in);
if (hashtable_out)
{
number = 1;
while (1)
{
snprintf (hash_key, sizeof (hash_key), "msg%d", number);
str_message = weechat_hashtable_get (hashtable_out, hash_key);
if (!str_message)
break;
relay_raw_print (client, 1, str_message);
length = strlen (str_message) + 16 + 1;
message = malloc (length);
if (message)
{
snprintf (message, length, "%s\r\n", str_message);
num_sent = send (client->sock, message, strlen (message), 0);
if (num_sent >= 0)
total_sent += num_sent;
else
{
weechat_printf (NULL,
_("%s%s: error sending data to client: %s"),
weechat_prefix ("error"), RELAY_PLUGIN_NAME,
strerror (errno));
}
free (message);
}
number++;
}
weechat_hashtable_free (hashtable_out);
}
weechat_hashtable_free (hashtable_in);
}
num_sent = send (client->sock, buffer, length, 0);
client->bytes_sent += total_sent;
if (num_sent >= 0)
client->bytes_sent += num_sent;
else
{
weechat_printf (NULL,
_("%s%s: error sending data to client: %s"),
weechat_prefix ("error"), RELAY_PLUGIN_NAME,
strerror (errno));
}
free (vbuffer);
return num_sent;
return total_sent;
}
/*
@ -220,7 +242,7 @@ relay_client_irc_signal_irc_in2_cb (void *data, const char *signal,
ptr_msg);
}
hash_parsed = relay_client_irc_parse_message (ptr_msg);
hash_parsed = relay_client_irc_message_parse (ptr_msg);
if (hash_parsed)
{
irc_nick = weechat_hashtable_get (hash_parsed, "nick");
@ -360,7 +382,7 @@ relay_client_irc_signal_irc_outtags_cb (void *data, const char *signal,
if (relay_client_irc_tag_relay_client_id (tags) == client->id)
goto end;
hash_parsed = relay_client_irc_parse_message (ptr_message);
hash_parsed = relay_client_irc_message_parse (ptr_message);
if (hash_parsed)
{
irc_command = weechat_hashtable_get (hash_parsed, "command");
@ -588,33 +610,41 @@ relay_client_irc_input_send (struct t_relay_client *client,
int flags,
const char *format, ...)
{
va_list args;
static char buffer[4096];
int length;
char buf_beginning[1024], *buf;
int length_beginning, length_vbuffer;
snprintf (buffer, sizeof (buffer),
weechat_va_format (format);
if (!vbuffer)
return;
snprintf (buf_beginning, sizeof (buf_beginning),
"%s;%s;%d;relay_client_%d;",
client->protocol_args,
(irc_channel) ? irc_channel : "",
flags,
client->id);
length = strlen (buffer);
va_start (args, format);
vsnprintf (buffer + length, sizeof (buffer) - 1 - length, format, args);
va_end (args);
if (weechat_relay_plugin->debug >= 2)
length_beginning = strlen (buf_beginning);
length_vbuffer = strlen (vbuffer);
buf = malloc (length_beginning + length_vbuffer + 1);
if (buf)
{
weechat_printf (NULL,
"%s: irc_input_send: \"%s\"",
RELAY_PLUGIN_NAME, buffer);
memcpy (buf, buf_beginning, length_beginning);
memcpy (buf + length_beginning, vbuffer, length_vbuffer);
buf[length_beginning + length_vbuffer] = '\0';
if (weechat_relay_plugin->debug >= 2)
{
weechat_printf (NULL,
"%s: irc_input_send: \"%s\"",
RELAY_PLUGIN_NAME, buf);
}
weechat_hook_signal_send ("irc_input_send",
WEECHAT_HOOK_SIGNAL_STRING,
buf);
free (buf);
}
weechat_hook_signal_send ("irc_input_send",
WEECHAT_HOOK_SIGNAL_STRING,
buffer);
free (vbuffer);
}
/*
@ -690,7 +720,7 @@ relay_client_irc_recv_one_msg (struct t_relay_client *client, char *data)
relay_raw_print (client, 0, data);
/* parse IRC message */
hash_parsed = relay_client_irc_parse_message (data);
hash_parsed = relay_client_irc_message_parse (data);
if (!hash_parsed)
goto end;
irc_command = weechat_hashtable_get (hash_parsed, "command");
@ -826,7 +856,6 @@ relay_client_irc_recv_one_msg (struct t_relay_client *client, char *data)
{
isupport++;
}
/* TODO: split this message into many messages */
relay_client_irc_sendf (client,
":%s 005 %s %s :are supported "
"by this server",