const char * irc_info_info_irc_is_channel_cb (void *data, const char *info_name, const char *arguments) { char *pos_comma, *server; const char *pos_channel; static char str_true[2] = "1"; struct t_irc_server *ptr_server; /* make C compiler happy */ (void) data; (void) info_name; ptr_server = NULL; pos_channel = arguments; pos_comma = strchr (arguments, ','); if (pos_comma) { pos_channel = pos_comma + 1; server = dogechat_strndup (arguments, pos_comma - arguments); if (server) { ptr_server = irc_server_search (server); free (server); } } if (irc_channel_is_channel (ptr_server, pos_channel)) return str_true; return NULL; }
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; }
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) { const char *ptr_message, *pos, *pos2, *pos3, *pos4; if (tags) *tags = NULL; if (message_without_tags) *message_without_tags = NULL; if (nick) *nick = NULL; if (host) *host = NULL; if (command) *command = NULL; if (channel) *channel = NULL; if (arguments) *arguments = NULL; if (!message) return; ptr_message = message; /* * we will use this message as example: * * @tags :[email protected] PRIVMSG #channel :hello! */ if (ptr_message[0] == '@') { /* * read tags (they are optional and enabled only if client enabled * a server capability, see: * http://ircv3.atheme.org/specification/message-tags-3.2) */ pos = strchr (ptr_message, ' '); if (pos) { if (tags) *tags = weechat_strndup (message + 1, pos - (message + 1)); ptr_message = pos + 1; while (ptr_message[0] == ' ') { ptr_message++; } } } if (message_without_tags) *message_without_tags = strdup (ptr_message); /* now we have: ptr_message --> ":[email protected] PRIVMSG #channel :hello!" */ if (ptr_message[0] == ':') { /* read host/nick */ pos2 = strchr (ptr_message, '!'); pos = strchr (ptr_message, ' '); if (pos2 && (!pos || pos > pos2)) { if (nick) *nick = weechat_strndup (ptr_message + 1, pos2 - (ptr_message + 1)); } else if (pos) { if (nick) *nick = weechat_strndup (ptr_message + 1, pos - (ptr_message + 1)); } if (pos) { if (host) *host = weechat_strndup (ptr_message + 1, pos - (ptr_message + 1)); ptr_message = pos + 1; while (ptr_message[0] == ' ') { ptr_message++; } } } /* now we have: ptr_message --> "PRIVMSG #channel :hello!" */ if (ptr_message[0]) { pos = strchr (ptr_message, ' '); if (pos) { if (command) *command = weechat_strndup (ptr_message, pos - ptr_message); pos++; while (pos[0] == ' ') { pos++; } /* now we have: pos --> "#channel :hello!" */ if (arguments) *arguments = strdup (pos); if (pos[0] != ':') { if (irc_channel_is_channel (server, pos)) { pos2 = strchr (pos, ' '); if (channel) { if (pos2) *channel = weechat_strndup (pos, pos2 - pos); else *channel = strdup (pos); } } else { pos2 = strchr (pos, ' '); if (nick && !*nick) { if (pos2) *nick = weechat_strndup (pos, pos2 - pos); else *nick = strdup (pos); } if (pos2) { pos3 = pos2; pos2++; while (pos2[0] == ' ') { pos2++; } if (irc_channel_is_channel (server, pos2)) { pos4 = strchr (pos2, ' '); if (channel) { if (pos4) *channel = weechat_strndup (pos2, pos4 - pos2); else *channel = strdup (pos2); } } else if (channel && !*channel) { *channel = weechat_strndup (pos, pos3 - pos); } } } } } else { if (command) *command = strdup (ptr_message); } } }
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; }
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 **text, int *pos_command, int *pos_arguments, int *pos_channel, int *pos_text) { const char *ptr_message, *pos, *pos2, *pos3, *pos4; if (tags) *tags = NULL; if (message_without_tags) *message_without_tags = NULL; if (nick) *nick = NULL; if (host) *host = NULL; if (command) *command = NULL; if (channel) *channel = NULL; if (arguments) *arguments = NULL; if (text) *text = NULL; if (pos_command) *pos_command = -1; if (pos_arguments) *pos_arguments = -1; if (pos_channel) *pos_channel = -1; if (pos_text) *pos_text = -1; if (!message) return; ptr_message = message; /* * we will use this message as example: * * @time=2015-06-27T16:40:35.000Z :nick!user@host PRIVMSG #weechat :hello! */ if (ptr_message[0] == '@') { /* * read tags (they are optional and enabled only if client enabled * a server capability, see: * http://ircv3.atheme.org/specification/message-tags-3.2) */ pos = strchr (ptr_message, ' '); if (pos) { if (tags) { *tags = weechat_strndup (ptr_message + 1, pos - (ptr_message + 1)); } ptr_message = pos + 1; while (ptr_message[0] == ' ') { ptr_message++; } } } if (message_without_tags) *message_without_tags = strdup (ptr_message); /* now we have: ptr_message --> ":nick!user@host PRIVMSG #weechat :hello!" */ if (ptr_message[0] == ':') { /* read host/nick */ pos3 = strchr (ptr_message, '@'); pos2 = strchr (ptr_message, '!'); pos = strchr (ptr_message, ' '); /* if the prefix doesn't contain a '!', split the nick at '@' */ if (!pos2 || (pos && pos2 > pos)) pos2 = pos3; if (pos2 && (!pos || pos > pos2)) { if (nick) *nick = weechat_strndup (ptr_message + 1, pos2 - (ptr_message + 1)); } else if (pos) { if (nick) *nick = weechat_strndup (ptr_message + 1, pos - (ptr_message + 1)); } if (pos) { if (host) *host = weechat_strndup (ptr_message + 1, pos - (ptr_message + 1)); ptr_message = pos + 1; while (ptr_message[0] == ' ') { ptr_message++; } } else { if (host) *host = strdup (ptr_message + 1); ptr_message += strlen (ptr_message); } } /* now we have: ptr_message --> "PRIVMSG #weechat :hello!" */ if (ptr_message[0]) { pos = strchr (ptr_message, ' '); if (pos) { if (command) *command = weechat_strndup (ptr_message, pos - ptr_message); if (pos_command) *pos_command = ptr_message - message; pos++; while (pos[0] == ' ') { pos++; } /* now we have: pos --> "#weechat :hello!" */ if (arguments) *arguments = strdup (pos); if (pos_arguments) *pos_arguments = pos - message; if ((pos[0] == ':') && ((strncmp (ptr_message, "JOIN ", 5) == 0) || (strncmp (ptr_message, "PART ", 5) == 0))) { pos++; } 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)) { pos2 = strchr (pos, ' '); if (channel) { if (pos2) *channel = weechat_strndup (pos, pos2 - pos); else *channel = strdup (pos); } if (pos_channel) *pos_channel = pos - message; if (pos2) { while (pos2[0] == ' ') { pos2++; } if (pos2[0] == ':') pos2++; if (text) *text = strdup (pos2); if (pos_text) *pos_text = pos2 - message; } } else { pos2 = strchr (pos, ' '); if (nick && !*nick) { if (pos2) *nick = weechat_strndup (pos, pos2 - pos); else *nick = strdup (pos); } if (pos2) { pos3 = pos2; pos2++; while (pos2[0] == ' ') { pos2++; } if (irc_channel_is_channel (server, pos2)) { pos4 = strchr (pos2, ' '); if (channel) { if (pos4) *channel = weechat_strndup (pos2, pos4 - pos2); else *channel = strdup (pos2); } if (pos_channel) *pos_channel = pos2 - message; 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) || (pos_channel && (*pos_channel < 0))) { if (channel) *channel = weechat_strndup (pos, pos3 - pos); if (pos_channel) *pos_channel = pos - message; } } } } } else { if (command) *command = strdup (ptr_message); if (pos_command) *pos_command = ptr_message - message; } } }
const char * irc_info_get_info_cb (void *data, const char *info_name, const char *arguments) { char *pos_comma, *pos_comma2, *server, *channel, *host; const char *nick; static char str_true[2] = "1"; struct t_irc_server *ptr_server; struct t_irc_channel *ptr_channel; /* make C compiler happy */ (void) data; if (weechat_strcasecmp (info_name, "irc_is_channel") == 0) { if (irc_channel_is_channel (arguments)) return str_true; return NULL; } else if (weechat_strcasecmp (info_name, "irc_nick") == 0) { ptr_server = irc_server_search (arguments); if (ptr_server) return ptr_server->nick; return NULL; } else if (weechat_strcasecmp (info_name, "irc_nick_from_host") == 0) { return irc_protocol_get_nick_from_host (arguments); } else if (weechat_strcasecmp (info_name, "irc_buffer") == 0) { if (arguments && arguments[0]) { server = NULL; channel = NULL; host = NULL; ptr_server = NULL; ptr_channel = NULL; pos_comma = strchr (arguments, ','); if (pos_comma) { server = weechat_strndup (arguments, pos_comma - arguments); pos_comma2 = strchr (pos_comma + 1, ','); if (pos_comma2) { channel = weechat_strndup (pos_comma + 1, pos_comma2 - pos_comma - 1); host = strdup (pos_comma2 + 1); } else channel = strdup (pos_comma + 1); } else { if (irc_channel_is_channel (arguments)) channel = strdup (arguments); else server = strdup (arguments); } /* replace channel by nick in host if channel is not a channel (private ?) */ if (channel && host) { if (!irc_channel_is_channel (channel)) { free (channel); channel = NULL; nick = irc_protocol_get_nick_from_host (host); if (nick) channel = strdup (nick); } } /* search for server or channel buffer */ if (server) { ptr_server = irc_server_search (server); if (ptr_server && channel) ptr_channel = irc_channel_search (ptr_server, channel); } if (server) free (server); if (channel) free (channel); if (host) free (host); if (ptr_channel) { irc_info_create_string_with_pointer (&ptr_channel->buffer_as_string, ptr_channel->buffer); return ptr_channel->buffer_as_string; } if (ptr_server) { irc_info_create_string_with_pointer (&ptr_server->buffer_as_string, ptr_server->buffer); return ptr_server->buffer_as_string; } } } return NULL; }
int irc_ignore_check (struct t_irc_server *server, const char *channel, const char *nick, const char *host) { struct t_irc_ignore *ptr_ignore; int server_match, channel_match; char *pos; if (!server) return 0; /* * if nick is the same as server, then we will not ignore * (it is possible when connected to an irc proxy) */ if (nick && server->nick && (irc_server_strcasecmp (server, server->nick, nick) == 0)) { return 0; } for (ptr_ignore = irc_ignore_list; ptr_ignore; ptr_ignore = ptr_ignore->next_ignore) { if (strcmp (ptr_ignore->server, "*") == 0) server_match = 1; else server_match = (weechat_strcasecmp (ptr_ignore->server, server->name) == 0); channel_match = 0; if (!channel || (strcmp (ptr_ignore->channel, "*") == 0)) channel_match = 1; else { if (irc_channel_is_channel (server, channel)) { channel_match = (weechat_strcasecmp (ptr_ignore->channel, channel) == 0); } else if (nick) { channel_match = (weechat_strcasecmp (ptr_ignore->channel, nick) == 0); } } if (server_match && channel_match) { if (nick && (regexec (ptr_ignore->regex_mask, nick, 0, NULL, 0) == 0)) return 1; if (host) { if (regexec (ptr_ignore->regex_mask, host, 0, NULL, 0) == 0) return 1; if (!strchr (ptr_ignore->mask, '!')) { pos = strchr (host, '!'); if (pos && (regexec (ptr_ignore->regex_mask, pos + 1, 0, NULL, 0) == 0)) { return 1; } } } } } return 0; }
const char * irc_info_info_irc_buffer_cb (void *data, const char *info_name, const char *arguments) { char *pos_comma, *pos_comma2, *server, *channel, *host; const char *nick; struct t_irc_server *ptr_server; struct t_irc_channel *ptr_channel; /* make C compiler happy */ (void) data; (void) info_name; if (!arguments || !arguments[0]) return NULL; server = NULL; channel = NULL; host = NULL; ptr_server = NULL; ptr_channel = NULL; pos_comma = strchr (arguments, ','); if (pos_comma) { server = dogechat_strndup (arguments, pos_comma - arguments); pos_comma2 = strchr (pos_comma + 1, ','); if (pos_comma2) { channel = dogechat_strndup (pos_comma + 1, pos_comma2 - pos_comma - 1); host = strdup (pos_comma2 + 1); } else channel = strdup (pos_comma + 1); } else { if (irc_server_search (arguments)) server = strdup (arguments); else channel = strdup (arguments); } if (server) ptr_server = irc_server_search (server); /* * replace channel by nick in host if channel is not a channel * (private ?) */ if (channel && host) { if (!irc_channel_is_channel (ptr_server, channel)) { free (channel); channel = NULL; nick = irc_message_get_nick_from_host (host); if (nick) channel = strdup (nick); } } /* search for server or channel buffer */ if (server && ptr_server && channel) ptr_channel = irc_channel_search (ptr_server, channel); if (server) free (server); if (channel) free (channel); if (host) free (host); if (ptr_channel) { irc_info_create_string_with_pointer (&ptr_channel->buffer_as_string, ptr_channel->buffer); return ptr_channel->buffer_as_string; } if (ptr_server) { irc_info_create_string_with_pointer (&ptr_server->buffer_as_string, ptr_server->buffer); return ptr_server->buffer_as_string; } return NULL; }