struct t_hashtable * irc_message_split (struct t_irc_server *server, const char *message) { struct t_hashtable *hashtable; char **argv, **argv_eol, *tags, *host, *command, *arguments, target[512]; char *pos; int split_ok, argc, index_args, max_length_nick, max_length_host; split_ok = 0; tags = NULL; host = NULL; command = NULL; arguments = NULL; index_args = 0; argv = NULL; argv_eol = NULL; /* debug message */ if (weechat_irc_plugin->debug >= 2) weechat_printf (NULL, "irc_message_split: message='%s'", message); hashtable = weechat_hashtable_new (32, WEECHAT_HASHTABLE_STRING, WEECHAT_HASHTABLE_STRING, NULL, NULL); if (!hashtable) return NULL; if (!message || !message[0]) goto end; if (message[0] == '@') { pos = strchr (message, ' '); if (pos) { tags = weechat_strndup (message, pos - message + 1); message = pos + 1; } } argv = weechat_string_split (message, " ", 0, 0, &argc); argv_eol = weechat_string_split (message, " ", 2, 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, tags, 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, tags, host, arguments); } } else if ((weechat_strcasecmp (command, "privmsg") == 0) || (weechat_strcasecmp (command, "notice") == 0)) { /* split privmsg/notice */ if (index_args + 1 <= argc - 1) { split_ok = irc_message_split_privmsg_notice (hashtable, 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_host); } } else if (weechat_strcasecmp (command, "005") == 0) { /* split 005 (isupport) */ if (index_args + 1 <= argc - 1) { split_ok = irc_message_split_005 (hashtable, tags, 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 (server, argv[index_args + 1])) { snprintf (target, sizeof (target), "%s %s", argv[index_args], argv[index_args + 1]); split_ok = irc_message_split_string (hashtable, tags, 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, tags, 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, tags, message, arguments); } if (tags) free (tags); if (argv) weechat_string_free_split (argv); if (argv_eol) weechat_string_free_split (argv_eol); return hashtable; }
struct t_hashtable * irc_message_split (struct t_irc_server *server, const char *message) { struct t_hashtable *hashtable; char **argv, **argv_eol, *tags, *host, *command, *arguments, target[512]; char *pos, monitor_action[3]; int split_ok, argc, index_args, max_length_nick, max_length_host; split_ok = 0; tags = NULL; host = NULL; command = NULL; arguments = NULL; index_args = 0; argv = NULL; argv_eol = NULL; /* debug message */ if (weechat_irc_plugin->debug >= 2) weechat_printf (NULL, "irc_message_split: message='%s'", message); hashtable = weechat_hashtable_new (32, WEECHAT_HASHTABLE_STRING, WEECHAT_HASHTABLE_STRING, NULL, NULL); if (!hashtable) return NULL; if (!message || !message[0]) goto end; if (message[0] == '@') { pos = strchr (message, ' '); if (pos) { tags = weechat_strndup (message, pos - message + 1); message = pos + 1; } } argv = weechat_string_split (message, " ", 0, 0, &argc); argv_eol = weechat_string_split (message, " ", 2, 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)) { /* * ISON :nick1 nick2 nick3 * WALLOPS :some text here */ split_ok = irc_message_split_string ( hashtable, tags, 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, "monitor") == 0) { /* * MONITOR + nick1,nick2,nick3 * MONITOR - nick1,nick2,nick3 */ if (((argv_eol[index_args][0] == '+') || (argv_eol[index_args][0] == '-')) && (argv_eol[index_args][1] == ' ')) { 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, argv_eol[index_args] + 2, NULL, ',', max_length_host); } else { split_ok = irc_message_split_string ( hashtable, tags, 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) { /* JOIN #channel1,#channel2,#channel3 key1,key2 */ if (strlen (message) > 510) { /* split join if it's more than 510 bytes */ split_ok = irc_message_split_join (hashtable, tags, host, arguments); } } else if ((weechat_strcasecmp (command, "privmsg") == 0) || (weechat_strcasecmp (command, "notice") == 0)) { /* * PRIVMSG target :some text here * NOTICE target :some text here */ if (index_args + 1 <= argc - 1) { split_ok = irc_message_split_privmsg_notice ( hashtable, 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_host); } } else if (weechat_strcasecmp (command, "005") == 0) { /* :server 005 nick MODES=4 CHANLIMIT=#:20 NICKLEN=16 USERLEN=10 ... */ if (index_args + 1 <= argc - 1) { split_ok = irc_message_split_005 ( hashtable, tags, 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) { /* * list of users on channel: * :server 353 mynick = #channel :mynick nick1 @nick2 +nick3 */ if (index_args + 2 <= argc - 1) { if (irc_channel_is_channel (server, argv[index_args + 1])) { snprintf (target, sizeof (target), "%s %s", argv[index_args], argv[index_args + 1]); split_ok = irc_message_split_string ( hashtable, tags, 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, tags, 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, tags, message, arguments); } if (tags) free (tags); if (argv) weechat_string_free_split (argv); if (argv_eol) weechat_string_free_split (argv_eol); return hashtable; }