diff options
Diffstat (limited to 'src/plugins/irc')
-rw-r--r-- | src/plugins/irc/irc-info.c | 4 | ||||
-rw-r--r-- | src/plugins/irc/irc-message.c | 135 | ||||
-rw-r--r-- | src/plugins/irc/irc-message.h | 7 | ||||
-rw-r--r-- | src/plugins/irc/irc-notify.c | 5 | ||||
-rw-r--r-- | src/plugins/irc/irc-server.c | 100 |
5 files changed, 186 insertions, 65 deletions
diff --git a/src/plugins/irc/irc-info.c b/src/plugins/irc/irc-info.c index 469bc6e25..b235e1f50 100644 --- a/src/plugins/irc/irc-info.c +++ b/src/plugins/irc/irc-info.c @@ -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", diff --git a/src/plugins/irc/irc-message.c b/src/plugins/irc/irc-message.c index ccf456cb1..01ffcc17f 100644 --- a/src/plugins/irc/irc-message.c +++ b/src/plugins/irc/irc-message.c @@ -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,11 +341,48 @@ 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. */ diff --git a/src/plugins/irc/irc-message.h b/src/plugins/irc/irc-message.h index 1e7b2cde7..bb3051d57 100644 --- a/src/plugins/irc/irc-message.h +++ b/src/plugins/irc/irc-message.h @@ -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, diff --git a/src/plugins/irc/irc-notify.c b/src/plugins/irc/irc-notify.c index c1a0575f0..653df5a11 100644 --- a/src/plugins/irc/irc-notify.c +++ b/src/plugins/irc/irc-notify.c @@ -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) diff --git a/src/plugins/irc/irc-server.c b/src/plugins/irc/irc-server.c index 346680c23..e40f86f40 100644 --- a/src/plugins/irc/irc-server.c +++ b/src/plugins/irc/irc-server.c @@ -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); - } - else - { - snprintf (modifier_data, sizeof (modifier_data), - "%s.%s", - weechat_plugin->name, - server->name); + 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); } - 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 = |