diff options
Diffstat (limited to 'src/plugins/irc')
-rw-r--r-- | src/plugins/irc/irc-channel.c | 260 | ||||
-rw-r--r-- | src/plugins/irc/irc-channel.h | 11 | ||||
-rw-r--r-- | src/plugins/irc/irc-config.c | 12 | ||||
-rw-r--r-- | src/plugins/irc/irc-config.h | 1 | ||||
-rw-r--r-- | src/plugins/irc/irc-protocol.c | 64 | ||||
-rw-r--r-- | src/plugins/irc/irc-server.c | 56 | ||||
-rw-r--r-- | src/plugins/irc/irc-upgrade.c | 38 |
7 files changed, 417 insertions, 25 deletions
diff --git a/src/plugins/irc/irc-channel.c b/src/plugins/irc/irc-channel.c index f9366a5c2..a26a1b19a 100644 --- a/src/plugins/irc/irc-channel.c +++ b/src/plugins/irc/irc-channel.c @@ -293,6 +293,7 @@ irc_channel_new (struct t_irc_server *server, int channel_type, new_channel->nicks_speaking[1] = NULL; new_channel->nicks_speaking_time = NULL; new_channel->last_nick_speaking_time = NULL; + new_channel->join_smart_filtered = NULL; new_channel->buffer = new_buffer; new_channel->buffer_as_string = NULL; @@ -721,6 +722,254 @@ irc_channel_nick_speaking_time_rename (struct t_irc_server *server, } /* + * Adds a nick in hashtable "join_smart_filtered" (creates the hashtable if + * needed). + */ + +void +irc_channel_join_smart_filtered_add (struct t_irc_channel *channel, + const char *nick, + time_t join_time) +{ + /* return if unmasking of smart filtered joins is disabled */ + if (weechat_config_integer (irc_config_look_smart_filter_join_unmask) == 0) + return; + + /* create hashtable if needed */ + if (!channel->join_smart_filtered) + { + channel->join_smart_filtered = weechat_hashtable_new (64, + WEECHAT_HASHTABLE_STRING, + WEECHAT_HASHTABLE_TIME, + NULL, + NULL); + } + if (!channel->join_smart_filtered) + return; + + weechat_hashtable_set (channel->join_smart_filtered, nick, &join_time); +} + +/* + * Renames a nick in hashtable "join_smart_filtered". + */ + +void +irc_channel_join_smart_filtered_rename (struct t_irc_channel *channel, + const char *old_nick, + const char *new_nick) +{ + time_t *ptr_time, join_time; + + /* return if hashtable does not exist in channel */ + if (!channel->join_smart_filtered) + return; + + /* search old_nick in hashtable */ + ptr_time = weechat_hashtable_get (channel->join_smart_filtered, old_nick); + if (!ptr_time) + return; + + /* remove old_nick, add new_nick with time of old_nick */ + join_time = *ptr_time; + weechat_hashtable_remove (channel->join_smart_filtered, old_nick); + weechat_hashtable_set (channel->join_smart_filtered, new_nick, &join_time); +} + +/* + * Removes a nick in hashtable "join_smart_filtered". + */ + +void +irc_channel_join_smart_filtered_remove (struct t_irc_channel *channel, + const char *nick) +{ + /* return if hashtable does not exist in channel */ + if (!channel->join_smart_filtered) + return; + + weechat_hashtable_remove (channel->join_smart_filtered, nick); +} + +/* + * Unmasks a smart filtered join if nick is in hashtable "join_smart_filtered", + * then removes nick from hashtable. + */ + +void +irc_channel_join_smart_filtered_unmask (struct t_irc_channel *channel, + const char *nick) +{ + int i, unmask_delay, length_tags, nick_found, join, nick_changed; + int smart_filtered, remove_smart_filter; + time_t *ptr_time, date_min; + struct t_hdata *hdata_line, *hdata_line_data; + struct t_gui_line *own_lines; + struct t_gui_line *line; + struct t_gui_line_data *line_data; + const char **tags, *irc_nick1, *irc_nick2; + char *new_tags, *nick_to_search; + struct t_hashtable *hashtable; + + /* return if hashtable does not exist in channel */ + if (!channel->join_smart_filtered) + return; + + /* return if unmasking of smart filtered joins is disabled */ + unmask_delay = weechat_config_integer (irc_config_look_smart_filter_join_unmask); + if (unmask_delay == 0) + return; + + /* check if nick is in hashtable "join_smart_filtered" */ + ptr_time = weechat_hashtable_get (channel->join_smart_filtered, nick); + if (!ptr_time) + return; + + /* + * the min date allowed to unmask a join (a join older than this date will + * not be unmasked) + */ + date_min = time (NULL) - (unmask_delay * 60); + + /* + * if the join is too old (older than current time - unmask delay), just + * remove nick from hashtable and return + */ + if (*ptr_time < date_min) + { + weechat_hashtable_remove (channel->join_smart_filtered, nick); + return; + } + + /* get hdata and pointers on last line in buffer */ + own_lines = weechat_hdata_pointer (weechat_hdata_get ("buffer"), + channel->buffer, "own_lines"); + if (!own_lines) + return; + line = weechat_hdata_pointer (weechat_hdata_get ("lines"), + own_lines, "last_line"); + if (!line) + return; + hdata_line = weechat_hdata_get ("line"); + hdata_line_data = weechat_hdata_get ("line_data"); + + /* the nick to search in messages (track nick changes) */ + nick_to_search = strdup (nick); + if (!nick_to_search) + return; + + /* loop on lines until we find the join */ + while (line) + { + line_data = weechat_hdata_pointer (hdata_line, line, "data"); + if (!line_data) + break; + + /* exit loop if we reach the unmask delay */ + if (weechat_hdata_time (hdata_line_data, line_data, "date_printed") < date_min) + break; + + /* check tags in line */ + length_tags = 0; + nick_found = 0; + join = 0; + nick_changed = 0; + irc_nick1 = NULL; + irc_nick2 = NULL; + smart_filtered = 0; + tags = weechat_hdata_pointer (hdata_line_data, line_data, "tags_array"); + for (i = 0; tags[i]; i++) + { + if (strncmp (tags[i], "nick_", 5) == 0) + { + if (strcmp (tags[i] + 5, nick_to_search) == 0) + nick_found = 1; + } + else if (strcmp (tags[i], "irc_join") == 0) + join = 1; + else if (strcmp (tags[i], "irc_nick") == 0) + nick_changed = 1; + else if (strncmp (tags[i], "irc_nick1_", 10) == 0) + irc_nick1 = tags[i] + 10; + else if (strncmp (tags[i], "irc_nick2_", 10) == 0) + irc_nick2 = tags[i] + 10; + else if (strcmp (tags[i], "irc_smart_filter") == 0) + smart_filtered = 1; + length_tags += strlen (tags[i]) + 1; + } + + /* check if we must remove tag "irc_smart_filter" in line */ + remove_smart_filter = 0; + if (nick_changed && irc_nick1 && irc_nick2 + && (strcmp (irc_nick2, nick_to_search) == 0)) + { + /* update the nick to search if the line is a message "nick" */ + free (nick_to_search); + nick_to_search = strdup (irc_nick1); + if (!nick_to_search) + break; + remove_smart_filter = 1; + } + else if (nick_found && join && smart_filtered) + { + remove_smart_filter = 1; + } + + if (remove_smart_filter) + { + /* + * unmask a "nick" or "join" message: remove the tag + * "irc_smart_filter" + */ + new_tags = malloc (length_tags); + if (new_tags) + { + /* build a string with all tags, except "irc_smart_filter" */ + new_tags[0] = '\0'; + for (i = 0; tags[i]; i++) + { + if (strcmp (tags[i], "irc_smart_filter") != 0) + { + if (new_tags[0]) + strcat (new_tags, ","); + strcat (new_tags, tags[i]); + } + } + hashtable = weechat_hashtable_new (4, + WEECHAT_HASHTABLE_STRING, + WEECHAT_HASHTABLE_STRING, + NULL, + NULL); + if (hashtable) + { + /* update tags in line (remove tag "irc_smart_filter") */ + weechat_hashtable_set (hashtable, "tags_array", new_tags); + weechat_hdata_update (hdata_line_data, line_data, hashtable); + weechat_hashtable_free (hashtable); + } + free (new_tags); + } + + /* + * exit loop if the message was the join (if it's a nick change, + * then we loop until we find the join) + */ + if (join) + break; + } + + /* continue with previous line in buffer */ + line = weechat_hdata_move (hdata_line, line, -1); + } + + if (nick_to_search) + free (nick_to_search); + + weechat_hashtable_remove (channel->join_smart_filtered, nick); +} + + +/* * Rejoins a channel (for example after kick). */ @@ -867,6 +1116,8 @@ irc_channel_free (struct t_irc_server *server, struct t_irc_channel *channel) if (channel->nicks_speaking[1]) weechat_list_free (channel->nicks_speaking[1]); irc_channel_nick_speaking_time_free_all (channel); + if (channel->join_smart_filtered) + weechat_hashtable_free (channel->join_smart_filtered); if (channel->buffer_as_string) free (channel->buffer_as_string); @@ -925,6 +1176,7 @@ irc_channel_hdata_channel_cb (void *data, const char *hdata_name) WEECHAT_HDATA_VAR(struct t_irc_channel, nicks_speaking, POINTER, 0, NULL, NULL); WEECHAT_HDATA_VAR(struct t_irc_channel, nicks_speaking_time, POINTER, 0, NULL, "irc_channel_speaking"); WEECHAT_HDATA_VAR(struct t_irc_channel, last_nick_speaking_time, POINTER, 0, NULL, "irc_channel_speaking"); + WEECHAT_HDATA_VAR(struct t_irc_channel, join_smart_filtered, HASHTABLE, 0, NULL, NULL); WEECHAT_HDATA_VAR(struct t_irc_channel, buffer, POINTER, 0, NULL, "buffer"); WEECHAT_HDATA_VAR(struct t_irc_channel, buffer_as_string, STRING, 0, NULL, NULL); WEECHAT_HDATA_VAR(struct t_irc_channel, prev_channel, POINTER, 0, NULL, hdata_name); @@ -1059,6 +1311,10 @@ irc_channel_add_to_infolist (struct t_infolist *infolist, i++; } } + if (!weechat_infolist_new_var_string (ptr_item, "join_smart_filtered", + weechat_hashtable_get_string (channel->join_smart_filtered, + "keys_values"))) + return 0; return 1; } @@ -1098,6 +1354,10 @@ irc_channel_print_log (struct t_irc_channel *channel) weechat_log_printf (" nicks_speaking[1]. . . . : 0x%lx", channel->nicks_speaking[1]); weechat_log_printf (" nicks_speaking_time. . . : 0x%lx", channel->nicks_speaking_time); weechat_log_printf (" last_nick_speaking_time. : 0x%lx", channel->last_nick_speaking_time); + weechat_log_printf (" join_smart_filtered. . . : 0x%lx (hashtable: '%s')", + channel->join_smart_filtered, + weechat_hashtable_get_string (channel->join_smart_filtered, + "keys_values")); weechat_log_printf (" buffer . . . . . . . . . : 0x%lx", channel->buffer); weechat_log_printf (" buffer_as_string . . . . : '%s'", channel->buffer_as_string); weechat_log_printf (" prev_channel . . . . . . : 0x%lx", channel->prev_channel); diff --git a/src/plugins/irc/irc-channel.h b/src/plugins/irc/irc-channel.h index 65c5cb055..ada35adfd 100644 --- a/src/plugins/irc/irc-channel.h +++ b/src/plugins/irc/irc-channel.h @@ -67,6 +67,7 @@ struct t_irc_channel struct t_irc_channel_speaking *nicks_speaking_time; /* for smart filter */ /* of join/part/quit messages */ struct t_irc_channel_speaking *last_nick_speaking_time; + struct t_hashtable *join_smart_filtered; /* smart filtered joins */ struct t_gui_buffer *buffer; /* buffer allocated for channel */ char *buffer_as_string; /* used to return buffer info */ struct t_irc_channel *prev_channel; /* link to previous channel */ @@ -118,6 +119,16 @@ extern void irc_channel_nick_speaking_time_rename (struct t_irc_server *server, struct t_irc_channel *channel, const char *old_nick, const char *new_nick); +extern void irc_channel_join_smart_filtered_add (struct t_irc_channel *channel, + const char *nick, + time_t join_time); +extern void irc_channel_join_smart_filtered_rename (struct t_irc_channel *channel, + const char *old_nick, + const char *new_nick); +extern void irc_channel_join_smart_filtered_remove (struct t_irc_channel *channel, + const char *nick); +extern void irc_channel_join_smart_filtered_unmask (struct t_irc_channel *channel, + const char *nick); extern void irc_channel_rejoin (struct t_irc_server *server, struct t_irc_channel *channel); extern int irc_channel_autorejoin_cb (void *data, int remaining_calls); diff --git a/src/plugins/irc/irc-config.c b/src/plugins/irc/irc-config.c index eee061e2f..9c9d40bad 100644 --- a/src/plugins/irc/irc-config.c +++ b/src/plugins/irc/irc-config.c @@ -94,6 +94,7 @@ struct t_config_option *irc_config_look_raw_messages; struct t_config_option *irc_config_look_smart_filter; struct t_config_option *irc_config_look_smart_filter_delay; struct t_config_option *irc_config_look_smart_filter_join; +struct t_config_option *irc_config_look_smart_filter_join_unmask; struct t_config_option *irc_config_look_smart_filter_quit; struct t_config_option *irc_config_look_smart_filter_nick; struct t_config_option *irc_config_look_topic_strip_colors; @@ -2309,6 +2310,15 @@ irc_config_init () /* TRANSLATORS: please do not translate "join" */ N_("enable smart filter for \"join\" messages"), NULL, 0, 0, "on", NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL); + irc_config_look_smart_filter_join_unmask = weechat_config_new_option ( + irc_config_file, ptr_section, + "smart_filter_join_unmask", "integer", + N_("delay for unmasking a join message that was filtered with tag " + "\"irc_smart_filter\" (in minutes): if a nick jas joined max N " + "minutes ago and then says something on channel (message, notice or " + "update on topic), the join is unmasked, as well as nick changes " + "after this join (0 = disable: never unmask a join)"), + NULL, 0, 60*24*7, "30", NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL); irc_config_look_smart_filter_quit = weechat_config_new_option ( irc_config_file, ptr_section, "smart_filter_quit", "boolean", @@ -2319,7 +2329,7 @@ irc_config_init () irc_config_file, ptr_section, "smart_filter_nick", "boolean", /* TRANSLATORS: please do not translate "nick" */ - N_("enable smart filter for \"nick\" messages"), + N_("enable smart filter for \"nick\" messages (nick changes)"), NULL, 0, 0, "on", NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL); irc_config_look_topic_strip_colors = weechat_config_new_option ( irc_config_file, ptr_section, diff --git a/src/plugins/irc/irc-config.h b/src/plugins/irc/irc-config.h index bacdf7990..0f0d3d45c 100644 --- a/src/plugins/irc/irc-config.h +++ b/src/plugins/irc/irc-config.h @@ -129,6 +129,7 @@ extern struct t_config_option *irc_config_look_raw_messages; extern struct t_config_option *irc_config_look_smart_filter; extern struct t_config_option *irc_config_look_smart_filter_delay; extern struct t_config_option *irc_config_look_smart_filter_join; +extern struct t_config_option *irc_config_look_smart_filter_join_unmask; extern struct t_config_option *irc_config_look_smart_filter_quit; extern struct t_config_option *irc_config_look_smart_filter_nick; extern struct t_config_option *irc_config_look_topic_strip_colors; diff --git a/src/plugins/irc/irc-protocol.c b/src/plugins/irc/irc-protocol.c index e9de72f3a..8252830db 100644 --- a/src/plugins/irc/irc-protocol.c +++ b/src/plugins/irc/irc-protocol.c @@ -508,7 +508,7 @@ IRC_PROTOCOL_CALLBACK(join) struct t_irc_nick *ptr_nick; struct t_irc_channel_speaking *ptr_nick_speaking; char *pos_channel; - int local_join, display_host; + int local_join, display_host, smart_filter; IRC_PROTOCOL_MIN_ARGS(3); IRC_PROTOCOL_CHECK_HOST; @@ -578,16 +578,23 @@ IRC_PROTOCOL_CALLBACK(join) display_host = (local_join) ? weechat_config_boolean (irc_config_look_display_host_join_local) : weechat_config_boolean (irc_config_look_display_host_join); + + /* + * "smart" filter the join message is it's not a join from myself, if + * smart filtering is enabled, and if nick was not speaking in channel + */ + smart_filter = (!local_join + && weechat_config_boolean (irc_config_look_smart_filter) + && weechat_config_boolean (irc_config_look_smart_filter_join) + && !ptr_nick_speaking); + + /* display the join */ weechat_printf_date_tags (irc_msgbuffer_get_target_buffer (server, NULL, command, NULL, ptr_channel->buffer), date, irc_protocol_tags (command, - (local_join - || !weechat_config_boolean (irc_config_look_smart_filter) - || !weechat_config_boolean (irc_config_look_smart_filter_join) - || ptr_nick_speaking) ? - NULL : "irc_smart_filter", + smart_filter ? "irc_smart_filter" : NULL, nick), _("%s%s%s%s%s%s%s%s%s%s has joined %s%s%s"), weechat_prefix ("join"), @@ -604,6 +611,14 @@ IRC_PROTOCOL_CALLBACK(join) pos_channel, IRC_COLOR_MESSAGE_JOIN); + /* + * if join is smart filtered, save the nick in hashtable, and if nick + * is speaking shortly after the join, it will be unmasked + * (option irc.look.smart_filter_join_unmask) + */ + if (smart_filter) + irc_channel_join_smart_filtered_add (ptr_channel, nick, time (NULL)); + /* display message in private if private has flag "has_quit_server" */ if (!local_join) irc_channel_display_nick_back_in_pv (server, ptr_nick, nick); @@ -996,6 +1011,8 @@ IRC_PROTOCOL_CALLBACK(nick) nick, new_nick); irc_channel_nick_speaking_time_rename (server, ptr_channel, nick, new_nick); + irc_channel_join_smart_filtered_rename (ptr_channel, + nick, new_nick); } if (old_color) @@ -1078,6 +1095,14 @@ IRC_PROTOCOL_CALLBACK(notice) { /* notice for channel */ ptr_channel = irc_channel_search (server, pos_target); + + /* + * unmask a smart filtered join if it is in hashtable + * "join_smart_filtered" of channel + */ + if (ptr_channel) + irc_channel_join_smart_filtered_unmask (ptr_channel, nick); + ptr_nick = irc_nick_search (server, ptr_channel, nick); weechat_printf_date_tags ((ptr_channel) ? ptr_channel->buffer : server->buffer, date, @@ -1390,7 +1415,12 @@ IRC_PROTOCOL_CALLBACK(part) } } else + { + /* part from another user */ + irc_channel_join_smart_filtered_remove (ptr_channel, + ptr_nick->name); irc_nick_free (server, ptr_channel, ptr_nick); + } } } @@ -1506,6 +1536,12 @@ IRC_PROTOCOL_CALLBACK(privmsg) ptr_channel = irc_channel_search (server, pos_target); if (ptr_channel) { + /* + * unmask a smart filtered join if it is in hashtable + * "join_smart_filtered" of channel + */ + irc_channel_join_smart_filtered_unmask (ptr_channel, nick); + /* CTCP to channel */ if ((pos_args[0] == '\01') && (pos_args[strlen (pos_args) - 1] == '\01')) @@ -1673,10 +1709,10 @@ IRC_PROTOCOL_CALLBACK(quit) if (ptr_nick || (irc_server_strcasecmp (server, ptr_channel->name, nick) == 0)) { - /* display quit message */ + local_quit = (irc_server_strcasecmp (server, nick, server->nick) == 0); if (!irc_ignore_check (server, ptr_channel->name, nick, host)) { - local_quit = (irc_server_strcasecmp (server, nick, server->nick) == 0); + /* display quit message */ ptr_nick_speaking = NULL; if (ptr_channel->type == IRC_CHANNEL_TYPE_CHANNEL) { @@ -1749,6 +1785,11 @@ IRC_PROTOCOL_CALLBACK(quit) IRC_COLOR_MESSAGE_QUIT); } } + if (!local_quit && ptr_nick) + { + irc_channel_join_smart_filtered_remove (ptr_channel, + ptr_nick->name); + } if (ptr_nick) irc_nick_free (server, ptr_channel, ptr_nick); } @@ -1855,6 +1896,13 @@ IRC_PROTOCOL_CALLBACK(topic) ptr_nick = irc_nick_search (server, ptr_channel, nick); ptr_buffer = (ptr_channel) ? ptr_channel->buffer : server->buffer; + /* + * unmask a smart filtered join if it is in hashtable + * "join_smart_filtered" of channel + */ + if (ptr_channel) + irc_channel_join_smart_filtered_unmask (ptr_channel, nick); + if (pos_topic && pos_topic[0]) { topic_color = irc_color_decode (pos_topic, diff --git a/src/plugins/irc/irc-server.c b/src/plugins/irc/irc-server.c index 8327f159c..771368c3f 100644 --- a/src/plugins/irc/irc-server.c +++ b/src/plugins/irc/irc-server.c @@ -2688,14 +2688,11 @@ void irc_server_check_join_manual_cb (void *data, struct t_hashtable *hashtable, const void *key, const void *value) { - struct t_irc_server *server; + /* make C compiler happy */ + (void) data; - server = (struct t_irc_server *)data; - if (server) - { - if (*((time_t *)value) + (60 * 10) < time (NULL)) - weechat_hashtable_remove (hashtable, key); - } + if (*((time_t *)value) + (60 * 10) < time (NULL)) + weechat_hashtable_remove (hashtable, key); } /* @@ -2707,13 +2704,33 @@ void irc_server_check_join_noswitch_cb (void *data, struct t_hashtable *hashtable, const void *key, const void *value) { - struct t_irc_server *server; + /* make C compiler happy */ + (void) data; - server = (struct t_irc_server *)data; - if (server) + if (*((time_t *)value) + (60 * 10) < time (NULL)) + weechat_hashtable_remove (hashtable, key); +} + +/* + * Callback called for each smart filtered join of a channel: deletes old + * entries in the hashtable. + */ + +void +irc_server_check_join_smart_filtered_cb (void *data, + struct t_hashtable *hashtable, + const void *key, const void *value) +{ + int unmask_delay; + + /* make C compiler happy */ + (void) data; + + unmask_delay = weechat_config_integer (irc_config_look_smart_filter_join_unmask); + if ((unmask_delay == 0) + || (*((time_t *)value) < time (NULL) - (unmask_delay * 60))) { - if (*((time_t *)value) + (60 * 10) < time (NULL)) - weechat_hashtable_remove (hashtable, key); + weechat_hashtable_remove (hashtable, key); } } @@ -2725,6 +2742,7 @@ int irc_server_timer_cb (void *data, int remaining_calls) { struct t_irc_server *ptr_server; + struct t_irc_channel *ptr_channel; struct t_irc_redirect *ptr_redirect, *ptr_next_redirect; time_t current_time; static struct timeval tv; @@ -2835,10 +2853,20 @@ irc_server_timer_cb (void *data, int remaining_calls) { weechat_hashtable_map (ptr_server->join_manual, &irc_server_check_join_manual_cb, - ptr_server); + NULL); weechat_hashtable_map (ptr_server->join_noswitch, &irc_server_check_join_noswitch_cb, - ptr_server); + NULL); + for (ptr_channel = ptr_server->channels; ptr_channel; + ptr_channel = ptr_channel->next_channel) + { + if (ptr_channel->join_smart_filtered) + { + weechat_hashtable_map (ptr_channel->join_smart_filtered, + &irc_server_check_join_smart_filtered_cb, + NULL); + } + } ptr_server->last_data_purge = current_time; } } diff --git a/src/plugins/irc/irc-upgrade.c b/src/plugins/irc/irc-upgrade.c index e262c88de..3a9568a06 100644 --- a/src/plugins/irc/irc-upgrade.c +++ b/src/plugins/irc/irc-upgrade.c @@ -284,8 +284,10 @@ irc_upgrade_read_cb (void *data, int object_id, struct t_infolist *infolist) { - int flags, sock, size, i, index; - char *buf, option_name[64]; + int flags, sock, size, i, index, nicks_count; + long number; + time_t join_time; + char *buf, option_name[64], **nicks, *nick_join, *pos, *error; const char *buffer_name, *str, *nick; struct t_irc_nick *ptr_nick; struct t_irc_redirect *ptr_redirect; @@ -482,6 +484,38 @@ irc_upgrade_read_cb (void *data, option_name)); index++; } + str = weechat_infolist_string (infolist, "join_smart_filtered"); + if (str) + { + nicks = weechat_string_split (str, ",", 0, 0, + &nicks_count); + if (nicks) + { + for (i = 0; i < nicks_count; i++) + { + pos = strchr (nicks[i], ':'); + if (pos) + { + nick_join = weechat_strndup (nicks[i], + pos - nicks[i]); + if (nick_join) + { + error = NULL; + number = strtol (pos + 1, &error, 10); + if (error && !error[0]) + { + join_time = (time_t)number; + irc_channel_join_smart_filtered_add (irc_upgrade_current_channel, + nick_join, + join_time); + } + free (nick_join); + } + } + } + weechat_string_free_split (nicks); + } + } } } break; |