mirror of
https://github.com/weechat/weechat.git
synced 2026-06-28 13:56:37 +02:00
irc: decode/encode only text in IRC messages and not the headers (bug #29886, closes #218, closes #451)
This commit is contained in:
@@ -846,7 +846,9 @@ irc_info_init ()
|
||||
/* TRANSLATORS: please do not translate key names (enclosed by quotes) */
|
||||
N_("\"tags\": tags, \"message_without_tags\": message without the "
|
||||
"tags, \"nick\": nick, \"host\": host, \"command\": command, "
|
||||
"\"channel\": channel, \"arguments\": arguments (includes channel)"),
|
||||
"\"channel\": channel, \"arguments\": arguments (includes channel), "
|
||||
"\"text\": text (for example user message), \"pos_text\": index of "
|
||||
"text in message (\"-1\" if no text found)"),
|
||||
&irc_info_info_hashtable_irc_message_parse_cb, NULL);
|
||||
weechat_hook_info_hashtable (
|
||||
"irc_message_split",
|
||||
|
||||
+118
-17
@@ -30,21 +30,37 @@
|
||||
|
||||
|
||||
/*
|
||||
* Parses an IRC message and returns pointers to:
|
||||
* - tags
|
||||
* - message without tags
|
||||
* - host
|
||||
* - command
|
||||
* - channel
|
||||
* - target nick
|
||||
* - arguments (if any)
|
||||
* Parses an IRC message and returns:
|
||||
* - tags (string)
|
||||
* - message without tags (string)
|
||||
* - nick (string)
|
||||
* - host (string)
|
||||
* - command (string)
|
||||
* - channel (string)
|
||||
* - arguments (string)
|
||||
* - text (string)
|
||||
* - pos_text (integer: text index in message)
|
||||
*
|
||||
* Example:
|
||||
* @time=2015-06-27T16:40:35.000Z :nick!user@host PRIVMSG #weechat :hello!
|
||||
*
|
||||
* Result:
|
||||
* tags: "time=2015-06-27T16:40:35.000Z"
|
||||
* msg_without_tags: ":nick!user@host PRIVMSG #weechat :hello!"
|
||||
* nick: "nick"
|
||||
* host: "nick!user@host"
|
||||
* command: "PRIVMSG"
|
||||
* channel: "#weechat"
|
||||
* arguments: "#weechat :hello!"
|
||||
* text: "hello!"
|
||||
* pos_text: 65
|
||||
*/
|
||||
|
||||
void
|
||||
irc_message_parse (struct t_irc_server *server, const char *message,
|
||||
char **tags, char **message_without_tags, char **nick,
|
||||
char **host, char **command, char **channel,
|
||||
char **arguments)
|
||||
char **arguments, char **text, int *pos_text)
|
||||
{
|
||||
const char *ptr_message, *pos, *pos2, *pos3, *pos4;
|
||||
|
||||
@@ -62,6 +78,10 @@ irc_message_parse (struct t_irc_server *server, const char *message,
|
||||
*channel = NULL;
|
||||
if (arguments)
|
||||
*arguments = NULL;
|
||||
if (text)
|
||||
*text = NULL;
|
||||
if (pos_text)
|
||||
*pos_text = -1;
|
||||
|
||||
if (!message)
|
||||
return;
|
||||
@@ -71,7 +91,7 @@ irc_message_parse (struct t_irc_server *server, const char *message,
|
||||
/*
|
||||
* we will use this message as example:
|
||||
*
|
||||
* @tags :FlashCode!n=flash@host.com PRIVMSG #channel :hello!
|
||||
* @time=2015-06-27T16:40:35.000Z :nick!user@host PRIVMSG #weechat :hello!
|
||||
*/
|
||||
|
||||
if (ptr_message[0] == '@')
|
||||
@@ -85,7 +105,10 @@ irc_message_parse (struct t_irc_server *server, const char *message,
|
||||
if (pos)
|
||||
{
|
||||
if (tags)
|
||||
*tags = weechat_strndup (message + 1, pos - (message + 1));
|
||||
{
|
||||
*tags = weechat_strndup (ptr_message + 1,
|
||||
pos - (ptr_message + 1));
|
||||
}
|
||||
ptr_message = pos + 1;
|
||||
while (ptr_message[0] == ' ')
|
||||
{
|
||||
@@ -97,7 +120,7 @@ irc_message_parse (struct t_irc_server *server, const char *message,
|
||||
if (message_without_tags)
|
||||
*message_without_tags = strdup (ptr_message);
|
||||
|
||||
/* now we have: ptr_message --> ":FlashCode!n=flash@host.com PRIVMSG #channel :hello!" */
|
||||
/* now we have: ptr_message --> ":nick!user@host PRIVMSG #weechat :hello!" */
|
||||
if (ptr_message[0] == ':')
|
||||
{
|
||||
/* read host/nick */
|
||||
@@ -135,7 +158,7 @@ irc_message_parse (struct t_irc_server *server, const char *message,
|
||||
}
|
||||
}
|
||||
|
||||
/* now we have: ptr_message --> "PRIVMSG #channel :hello!" */
|
||||
/* now we have: ptr_message --> "PRIVMSG #weechat :hello!" */
|
||||
if (ptr_message[0])
|
||||
{
|
||||
pos = strchr (ptr_message, ' ');
|
||||
@@ -148,7 +171,7 @@ irc_message_parse (struct t_irc_server *server, const char *message,
|
||||
{
|
||||
pos++;
|
||||
}
|
||||
/* now we have: pos --> "#channel :hello!" */
|
||||
/* now we have: pos --> "#weechat :hello!" */
|
||||
if (arguments)
|
||||
*arguments = strdup (pos);
|
||||
if ((pos[0] == ':')
|
||||
@@ -157,7 +180,14 @@ irc_message_parse (struct t_irc_server *server, const char *message,
|
||||
{
|
||||
pos++;
|
||||
}
|
||||
if (pos[0] != ':')
|
||||
if (pos[0] == ':')
|
||||
{
|
||||
if (text)
|
||||
*text = strdup (pos + 1);
|
||||
if (pos_text)
|
||||
*pos_text = pos - message + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (irc_channel_is_channel (server, pos))
|
||||
{
|
||||
@@ -169,6 +199,19 @@ irc_message_parse (struct t_irc_server *server, const char *message,
|
||||
else
|
||||
*channel = strdup (pos);
|
||||
}
|
||||
if (pos2)
|
||||
{
|
||||
while (pos2[0] == ' ')
|
||||
{
|
||||
pos2++;
|
||||
}
|
||||
if (pos2[0] == ':')
|
||||
pos2++;
|
||||
if (text)
|
||||
*text = strdup (pos2);
|
||||
if (pos_text)
|
||||
*pos_text = pos2 - message;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -198,6 +241,19 @@ irc_message_parse (struct t_irc_server *server, const char *message,
|
||||
else
|
||||
*channel = strdup (pos2);
|
||||
}
|
||||
if (pos4)
|
||||
{
|
||||
while (pos4[0] == ' ')
|
||||
{
|
||||
pos4++;
|
||||
}
|
||||
if (pos4[0] == ':')
|
||||
pos4++;
|
||||
if (text)
|
||||
*text = strdup (pos4);
|
||||
if (pos_text)
|
||||
*pos_text = pos4 - message;
|
||||
}
|
||||
}
|
||||
else if (channel && !*channel)
|
||||
{
|
||||
@@ -224,6 +280,8 @@ irc_message_parse (struct t_irc_server *server, const char *message,
|
||||
* - command
|
||||
* - channel
|
||||
* - arguments
|
||||
* - text
|
||||
* - pos_text
|
||||
*
|
||||
* Note: hashtable must be freed after use.
|
||||
*/
|
||||
@@ -233,12 +291,14 @@ irc_message_parse_to_hashtable (struct t_irc_server *server,
|
||||
const char *message)
|
||||
{
|
||||
char *tags,*message_without_tags, *nick, *host, *command, *channel;
|
||||
char *arguments;
|
||||
char *arguments, *text, str_pos_text[32];
|
||||
char empty_str[1] = { '\0' };
|
||||
int pos_text;
|
||||
struct t_hashtable *hashtable;
|
||||
|
||||
irc_message_parse (server, message, &tags, &message_without_tags, &nick,
|
||||
&host, &command, &channel, &arguments);
|
||||
&host, &command, &channel, &arguments, &text,
|
||||
&pos_text);
|
||||
|
||||
hashtable = weechat_hashtable_new (32,
|
||||
WEECHAT_HASHTABLE_STRING,
|
||||
@@ -262,6 +322,10 @@ irc_message_parse_to_hashtable (struct t_irc_server *server,
|
||||
(channel) ? channel : empty_str);
|
||||
weechat_hashtable_set (hashtable, "arguments",
|
||||
(arguments) ? arguments : empty_str);
|
||||
weechat_hashtable_set (hashtable, "text",
|
||||
(text) ? text : empty_str);
|
||||
snprintf (str_pos_text, sizeof (str_pos_text), "%d", pos_text);
|
||||
weechat_hashtable_set (hashtable, "pos_text", str_pos_text);
|
||||
|
||||
if (tags)
|
||||
free (tags);
|
||||
@@ -277,10 +341,47 @@ irc_message_parse_to_hashtable (struct t_irc_server *server,
|
||||
free (channel);
|
||||
if (arguments)
|
||||
free (arguments);
|
||||
if (text)
|
||||
free (text);
|
||||
|
||||
return hashtable;
|
||||
}
|
||||
|
||||
/*
|
||||
* Encodes/decodes an IRC message using a charset.
|
||||
*/
|
||||
|
||||
char *
|
||||
irc_message_convert_charset (const char *message, int pos_start,
|
||||
const char *modifier, const char *modifier_data)
|
||||
{
|
||||
char *text, *msg_result;
|
||||
int length;
|
||||
|
||||
text = weechat_hook_modifier_exec (modifier, modifier_data,
|
||||
message + pos_start);
|
||||
if (!text)
|
||||
return NULL;
|
||||
|
||||
length = pos_start + strlen (text) + 1;
|
||||
msg_result = malloc (length);
|
||||
if (msg_result)
|
||||
{
|
||||
msg_result[0] = '\0';
|
||||
if (pos_start > 0)
|
||||
{
|
||||
memcpy (msg_result, message, pos_start);
|
||||
msg_result[pos_start] = '\0';
|
||||
}
|
||||
strcat (msg_result, text);
|
||||
}
|
||||
|
||||
free (text);
|
||||
|
||||
return msg_result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Gets nick from host in an IRC message.
|
||||
*/
|
||||
|
||||
@@ -26,9 +26,14 @@ struct t_irc_channel;
|
||||
extern void irc_message_parse (struct t_irc_server *server, const char *message,
|
||||
char **tags, char **message_without_tags,
|
||||
char **nick, char **host, char **command,
|
||||
char **channel, char **arguments);
|
||||
char **channel, char **arguments, char **text,
|
||||
int *pos_text);
|
||||
extern struct t_hashtable *irc_message_parse_to_hashtable (struct t_irc_server *server,
|
||||
const char *message);
|
||||
extern char *irc_message_convert_charset (const char *message,
|
||||
int pos_start,
|
||||
const char *modifier,
|
||||
const char *modifier_data);
|
||||
extern const char *irc_message_get_nick_from_host (const char *host);
|
||||
extern const char *irc_message_get_address_from_host (const char *host);
|
||||
extern char *irc_message_replace_vars (struct t_irc_server *server,
|
||||
|
||||
@@ -835,7 +835,7 @@ irc_notify_hsignal_cb (void *data, const char *signal,
|
||||
for (i = 0; i < num_messages; i++)
|
||||
{
|
||||
irc_message_parse (ptr_server, messages[i], NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, &arguments);
|
||||
NULL, NULL, NULL, &arguments, NULL, NULL);
|
||||
if (arguments)
|
||||
{
|
||||
pos = strchr (arguments, ' ');
|
||||
@@ -917,7 +917,8 @@ irc_notify_hsignal_cb (void *data, const char *signal,
|
||||
for (i = 0; i < num_messages; i++)
|
||||
{
|
||||
irc_message_parse (ptr_server, messages[0], NULL, NULL,
|
||||
NULL, NULL, &irc_cmd, NULL, &arguments);
|
||||
NULL, NULL, &irc_cmd, NULL, &arguments,
|
||||
NULL, NULL);
|
||||
if (irc_cmd && arguments)
|
||||
{
|
||||
if (strcmp (irc_cmd, "401") == 0)
|
||||
|
||||
@@ -2051,7 +2051,7 @@ irc_server_send_one_msg (struct t_irc_server *server, int flags,
|
||||
const char *ptr_msg, *ptr_chan_nick;
|
||||
char *new_msg, *pos, *tags_to_send, *msg_encoded;
|
||||
char str_modifier[128], modifier_data[256];
|
||||
int rc, queue_msg, add_to_queue, first_message, anti_flood;
|
||||
int rc, queue_msg, add_to_queue, first_message, anti_flood, pos_text;
|
||||
time_t time_now;
|
||||
struct t_irc_redirect *ptr_redirect;
|
||||
|
||||
@@ -2079,25 +2079,30 @@ irc_server_send_one_msg (struct t_irc_server *server, int flags,
|
||||
ptr_msg = (new_msg) ? new_msg : message;
|
||||
|
||||
msg_encoded = NULL;
|
||||
ptr_chan_nick = (channel) ? channel : nick;
|
||||
if (ptr_chan_nick)
|
||||
irc_message_parse (server, ptr_msg, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, &pos_text);
|
||||
if (pos_text >= 0)
|
||||
{
|
||||
snprintf (modifier_data, sizeof (modifier_data),
|
||||
"%s.%s.%s",
|
||||
weechat_plugin->name,
|
||||
server->name,
|
||||
ptr_chan_nick);
|
||||
ptr_chan_nick = (channel) ? channel : nick;
|
||||
if (ptr_chan_nick)
|
||||
{
|
||||
snprintf (modifier_data, sizeof (modifier_data),
|
||||
"%s.%s.%s",
|
||||
weechat_plugin->name,
|
||||
server->name,
|
||||
ptr_chan_nick);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf (modifier_data, sizeof (modifier_data),
|
||||
"%s.%s",
|
||||
weechat_plugin->name,
|
||||
server->name);
|
||||
}
|
||||
msg_encoded = irc_message_convert_charset (ptr_msg, pos_text,
|
||||
"charset_encode",
|
||||
modifier_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf (modifier_data, sizeof (modifier_data),
|
||||
"%s.%s",
|
||||
weechat_plugin->name,
|
||||
server->name);
|
||||
}
|
||||
msg_encoded = weechat_hook_modifier_exec ("charset_encode",
|
||||
modifier_data,
|
||||
ptr_msg);
|
||||
|
||||
if (msg_encoded)
|
||||
ptr_msg = msg_encoded;
|
||||
@@ -2270,7 +2275,7 @@ irc_server_sendf (struct t_irc_server *server, int flags, const char *tags,
|
||||
{
|
||||
/* run modifier "irc_out1_xxx" (like "irc_out_xxx", but before split) */
|
||||
irc_message_parse (server, items[i], NULL, NULL,
|
||||
&nick, NULL, &command, &channel, NULL);
|
||||
&nick, NULL, &command, &channel, NULL, NULL, NULL);
|
||||
snprintf (str_modifier, sizeof (str_modifier),
|
||||
"irc_out1_%s",
|
||||
(command) ? command : "unknown");
|
||||
@@ -2507,6 +2512,7 @@ irc_server_msgq_flush ()
|
||||
char *tags, *nick, *host, *command, *channel, *arguments;
|
||||
char *msg_decoded, *msg_decoded_without_color;
|
||||
char str_modifier[128], modifier_data[256];
|
||||
int pos_text;
|
||||
|
||||
while (irc_recv_msgq)
|
||||
{
|
||||
@@ -2528,7 +2534,7 @@ irc_server_msgq_flush ()
|
||||
|
||||
irc_message_parse (irc_recv_msgq->server,
|
||||
ptr_data, NULL, NULL, NULL, NULL,
|
||||
&command, NULL, NULL);
|
||||
&command, NULL, NULL, NULL, NULL);
|
||||
snprintf (str_modifier, sizeof (str_modifier),
|
||||
"irc_in_%s",
|
||||
(command) ? command : "unknown");
|
||||
@@ -2568,41 +2574,47 @@ irc_server_msgq_flush ()
|
||||
|
||||
irc_message_parse (irc_recv_msgq->server, ptr_msg,
|
||||
&tags, NULL, &nick, &host,
|
||||
&command, &channel, &arguments);
|
||||
&command, &channel, &arguments,
|
||||
NULL, &pos_text);
|
||||
|
||||
/* convert charset for message */
|
||||
if (channel
|
||||
&& irc_channel_is_channel (irc_recv_msgq->server,
|
||||
channel))
|
||||
msg_decoded = NULL;
|
||||
if (pos_text >= 0)
|
||||
{
|
||||
snprintf (modifier_data, sizeof (modifier_data),
|
||||
"%s.%s.%s",
|
||||
weechat_plugin->name,
|
||||
irc_recv_msgq->server->name,
|
||||
channel);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (nick && (!host || (strcmp (nick, host) != 0)))
|
||||
/* convert charset for message */
|
||||
if (channel
|
||||
&& irc_channel_is_channel (irc_recv_msgq->server,
|
||||
channel))
|
||||
{
|
||||
snprintf (modifier_data,
|
||||
sizeof (modifier_data),
|
||||
snprintf (modifier_data, sizeof (modifier_data),
|
||||
"%s.%s.%s",
|
||||
weechat_plugin->name,
|
||||
irc_recv_msgq->server->name,
|
||||
nick);
|
||||
channel);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf (modifier_data,
|
||||
sizeof (modifier_data),
|
||||
"%s.%s",
|
||||
weechat_plugin->name,
|
||||
irc_recv_msgq->server->name);
|
||||
if (nick && (!host || (strcmp (nick, host) != 0)))
|
||||
{
|
||||
snprintf (modifier_data,
|
||||
sizeof (modifier_data),
|
||||
"%s.%s.%s",
|
||||
weechat_plugin->name,
|
||||
irc_recv_msgq->server->name,
|
||||
nick);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf (modifier_data,
|
||||
sizeof (modifier_data),
|
||||
"%s.%s",
|
||||
weechat_plugin->name,
|
||||
irc_recv_msgq->server->name);
|
||||
}
|
||||
}
|
||||
msg_decoded = irc_message_convert_charset (
|
||||
ptr_msg, pos_text,
|
||||
"charset_decode", modifier_data);
|
||||
}
|
||||
msg_decoded = weechat_hook_modifier_exec (
|
||||
"charset_decode", modifier_data, ptr_msg);
|
||||
|
||||
/* replace WeeChat internal color codes by "?" */
|
||||
msg_decoded_without_color =
|
||||
|
||||
Reference in New Issue
Block a user