Exemplo n.º 1
0
int
irc_mode_channel_set (struct t_irc_server *server,
                      struct t_irc_channel *channel,
                      const char *host,
                      const char *modes,
                      const char *modes_arguments)
{
    const char *pos, *ptr_arg;
    char set_flag, **argv, chanmode_type;
    int argc, current_arg, update_channel_modes, channel_modes_updated;
    int smart_filter, end_modes;
    struct t_irc_nick *ptr_nick;
    struct t_irc_modelist *ptr_modelist;
    struct t_irc_modelist_item *ptr_item;

    if (!server || !channel || !modes)
        return 0;

    channel_modes_updated = 0;
    argc = 0;
    argv = NULL;
    if (modes_arguments)
    {
        argv = weechat_string_split (modes_arguments, " ",
                                     WEECHAT_STRING_SPLIT_STRIP_LEFT
                                     | WEECHAT_STRING_SPLIT_STRIP_RIGHT
                                     | WEECHAT_STRING_SPLIT_COLLAPSE_SEPS,
                                     0, &argc);
    }

    current_arg = 0;

    smart_filter = (weechat_config_boolean (irc_config_look_smart_filter)
                    && weechat_config_string (irc_config_look_smart_filter_mode)
                    && weechat_config_string (irc_config_look_smart_filter_mode)[0]) ? 1 : 0;

    end_modes = 0;
    set_flag = '+';
    pos = modes;
    while (pos[0])
    {
        switch (pos[0])
        {
            case ':':
                break;
            case ' ':
                end_modes = 1;
                break;
            case '+':
                set_flag = '+';
                break;
            case '-':
                set_flag = '-';
                break;
            default:
                update_channel_modes = 1;
                chanmode_type = irc_mode_get_chanmode_type (server, pos[0]);
                ptr_arg = NULL;
                switch (chanmode_type)
                {
                    case 'A': /* always argument */
                        update_channel_modes = 0;
                        ptr_arg = (current_arg < argc) ?
                            argv[current_arg] : NULL;
                        break;
                    case 'B': /* always argument */
                        ptr_arg = (current_arg < argc) ?
                            argv[current_arg] : NULL;
                        break;
                    case 'C': /* argument if set */
                        ptr_arg = ((set_flag == '+') && (current_arg < argc)) ?
                            argv[current_arg] : NULL;
                        break;
                    case 'D': /* no argument */
                        break;
                }
                if (ptr_arg)
                {
                    if (ptr_arg[0] == ':')
                        ptr_arg++;
                    current_arg++;
                }

                if (smart_filter
                    && !irc_mode_smart_filtered (server, pos[0]))
                {
                    smart_filter = 0;
                }

                if (pos[0] == 'k')
                {
                    /* channel key */
                    if (set_flag == '-')
                    {
                        if (channel->key)
                        {
                            free (channel->key);
                            channel->key = NULL;
                        }
                    }
                    else if ((set_flag == '+')
                             && ptr_arg && (strcmp (ptr_arg, "*") != 0))
                    {
                        /* replace key for +k, but ignore "*" as new key */
                        if (channel->key)
                            free (channel->key);
                        channel->key = strdup (ptr_arg);
                    }
                }
                else if (pos[0] == 'l')
                {
                    /* channel limit */
                    if (set_flag == '-')
                        channel->limit = 0;
                    if ((set_flag == '+') && ptr_arg)
                    {
                        channel->limit = atoi (ptr_arg);
                    }
                }
                else if ((chanmode_type != 'A')
                         && (irc_server_get_prefix_mode_index (server,
                                                               pos[0]) >= 0))
                {
                    /* mode for nick */
                    update_channel_modes = 0;
                    if (ptr_arg)
                    {
                        ptr_nick = irc_nick_search (server, channel,
                                                    ptr_arg);
                        if (ptr_nick)
                        {
                            irc_nick_set_mode (server, channel, ptr_nick,
                                               (set_flag == '+'), pos[0]);
                            /*
                             * disable smart filtering if mode is sent
                             * to me, or based on the nick speaking time
                             */
                            if (smart_filter
                                && ((irc_server_strcasecmp (server,
                                                            ptr_nick->name,
                                                            server->nick) == 0)
                                    || irc_channel_nick_speaking_time_search (server,
                                                                              channel,
                                                                              ptr_nick->name,
                                                                              1)))
                            {
                                smart_filter = 0;
                            }
                        }
                    }
                }
                else if (chanmode_type == 'A')
                {
                    /* modelist modes */
                    if (ptr_arg)
                    {
                        ptr_modelist = irc_modelist_search (channel, pos[0]);
                        if (ptr_modelist)
                        {
                            if (set_flag == '+')
                            {
                                irc_modelist_item_new (ptr_modelist, ptr_arg,
                                                       host, time (NULL));
                            }
                            else if (set_flag == '-')
                            {
                                ptr_item = irc_modelist_item_search_mask (
                                    ptr_modelist, ptr_arg);
                                if (ptr_item)
                                    irc_modelist_item_free (ptr_modelist, ptr_item);
                            }
                        }
                    }
                }

                if (update_channel_modes)
                {
                    irc_mode_channel_update (server, channel, set_flag,
                                             pos[0], ptr_arg);
                    channel_modes_updated = 1;
                }
                break;
        }
        if (end_modes)
            break;
        pos++;
    }

    if (argv)
        weechat_string_free_split (argv);

    if (channel_modes_updated)
        weechat_bar_item_update ("buffer_modes");

    return smart_filter;
}
Exemplo n.º 2
0
int
irc_upgrade_read_cb (void *data,
                     struct t_upgrade_file *upgrade_file,
                     int object_id,
                     struct t_infolist *infolist)
{
    int flags, sock, size, i, index, nicks_count, num_items;
    long number;
    time_t join_time;
    char *buf, option_name[64], **nicks, *nick_join, *pos, *error;
    char **items;
    const char *buffer_name, *str, *nick;
    struct t_irc_nick *ptr_nick;
    struct t_irc_redirect *ptr_redirect;
    struct t_irc_notify *ptr_notify;
    struct t_gui_buffer *ptr_buffer;

    /* make C compiler happy */
    (void) data;
    (void) upgrade_file;

    weechat_infolist_reset_item_cursor (infolist);
    while (weechat_infolist_next (infolist))
    {
        switch (object_id)
        {
            case IRC_UPGRADE_TYPE_SERVER:
                irc_upgrade_current_server = irc_server_search (weechat_infolist_string (infolist, "name"));
                if (irc_upgrade_current_server)
                {
                    irc_upgrade_current_server->temp_server =
                        weechat_infolist_integer (infolist, "temp_server");
                    irc_upgrade_current_server->buffer = NULL;
                    buffer_name = weechat_infolist_string (infolist, "buffer_name");
                    if (buffer_name && buffer_name[0])
                    {
                        ptr_buffer = weechat_buffer_search (IRC_PLUGIN_NAME,
                                                            buffer_name);
                        if (ptr_buffer)
                            irc_upgrade_current_server->buffer = ptr_buffer;
                    }
                    irc_upgrade_current_server->index_current_address =
                        weechat_infolist_integer (infolist, "index_current_address");
                    str = weechat_infolist_string (infolist, "current_address");
                    if (str)
                    {
                        irc_upgrade_current_server->current_address = strdup (str);
                        irc_upgrade_current_server->current_port = weechat_infolist_integer (infolist, "current_port");
                    }
                    else
                    {
                        if (irc_upgrade_current_server->index_current_address < irc_upgrade_current_server->addresses_count)
                        {
                            irc_upgrade_current_server->current_address =
                                strdup (irc_upgrade_current_server->addresses_array[irc_upgrade_current_server->index_current_address]);
                            irc_upgrade_current_server->current_port =
                                irc_upgrade_current_server->ports_array[irc_upgrade_current_server->index_current_address];
                        }
                    }
                    str = weechat_infolist_string (infolist, "current_ip");
                    if (str)
                        irc_upgrade_current_server->current_ip = strdup (str);
                    sock = weechat_infolist_integer (infolist, "sock");
                    if (sock >= 0)
                    {
                        irc_upgrade_current_server->sock = sock;
                        irc_upgrade_current_server->hook_fd = weechat_hook_fd (irc_upgrade_current_server->sock,
                                                                               1, 0, 0,
                                                                               &irc_server_recv_cb,
                                                                               irc_upgrade_current_server);
                    }
                    irc_upgrade_current_server->is_connected = weechat_infolist_integer (infolist, "is_connected");
                    irc_upgrade_current_server->ssl_connected = weechat_infolist_integer (infolist, "ssl_connected");
                    irc_upgrade_current_server->disconnected = weechat_infolist_integer (infolist, "disconnected");
                    str = weechat_infolist_string (infolist, "unterminated_message");
                    if (str)
                        irc_upgrade_current_server->unterminated_message = strdup (str);
                    str = weechat_infolist_string (infolist, "nick");
                    if (str)
                        irc_server_set_nick (irc_upgrade_current_server, str);
                    str = weechat_infolist_string (infolist, "nick_modes");
                    if (str)
                        irc_upgrade_current_server->nick_modes = strdup (str);
                    str = weechat_infolist_string (infolist, "isupport");
                    if (str)
                        irc_upgrade_current_server->isupport = strdup (str);
                    /*
                     * "prefix" is not any more in this infolist (since
                     * WeeChat 0.3.4), but we read it to keep compatibility
                     * with old WeeChat versions, on /upgrade)
                     */
                    str = weechat_infolist_string (infolist, "prefix");
                    if (str)
                        irc_server_set_prefix_modes_chars (irc_upgrade_current_server, str);
                    /* "prefix_modes" is new in WeeChat 0.3.4 */
                    str = weechat_infolist_string (infolist, "prefix_modes");
                    if (str)
                    {
                        if (irc_upgrade_current_server->prefix_modes)
                            free (irc_upgrade_current_server->prefix_modes);
                        irc_upgrade_current_server->prefix_modes = strdup (str);
                    }
                    /* "prefix_chars" is new in WeeChat 0.3.4 */
                    str = weechat_infolist_string (infolist, "prefix_chars");
                    if (str)
                    {
                        if (irc_upgrade_current_server->prefix_chars)
                            free (irc_upgrade_current_server->prefix_chars);
                        irc_upgrade_current_server->prefix_chars = strdup (str);
                    }
                    irc_upgrade_current_server->nick_max_length = weechat_infolist_integer (infolist, "nick_max_length");
                    irc_upgrade_current_server->casemapping = weechat_infolist_integer (infolist, "casemapping");
                    str = weechat_infolist_string (infolist, "chantypes");
                    if (str)
                        irc_upgrade_current_server->chantypes = strdup (str);
                    str = weechat_infolist_string (infolist, "chanmodes");
                    if (str)
                        irc_upgrade_current_server->chanmodes = strdup (str);
                    else
                    {
                        str = irc_server_get_isupport_value (irc_upgrade_current_server,
                                                             "CHANMODES");
                        if (str)
                            irc_upgrade_current_server->chanmodes = strdup (str);
                    }
                    /* "monitor" is new in WeeChat 0.4.3 */
                    if (weechat_infolist_search_var (infolist, "monitor"))
                    {
                        irc_upgrade_current_server->monitor = weechat_infolist_integer (infolist, "monitor");
                    }
                    else
                    {
                        /* WeeChat <= 0.4.2 */
                        str = irc_server_get_isupport_value (irc_upgrade_current_server,
                                                             "MONITOR");
                        if (str)
                        {
                            error = NULL;
                            number = strtol (str, &error, 10);
                            if (error && !error[0])
                                irc_upgrade_current_server->monitor = (int)number;
                        }
                    }
                    irc_upgrade_current_server->reconnect_delay = weechat_infolist_integer (infolist, "reconnect_delay");
                    irc_upgrade_current_server->reconnect_start = weechat_infolist_time (infolist, "reconnect_start");
                    irc_upgrade_current_server->command_time = weechat_infolist_time (infolist, "command_time");
                    irc_upgrade_current_server->reconnect_join = weechat_infolist_integer (infolist, "reconnect_join");
                    irc_upgrade_current_server->disable_autojoin = weechat_infolist_integer (infolist, "disable_autojoin");
                    irc_upgrade_current_server->is_away = weechat_infolist_integer (infolist, "is_away");
                    str = weechat_infolist_string (infolist, "away_message");
                    if (str)
                        irc_upgrade_current_server->away_message = strdup (str);
                    irc_upgrade_current_server->away_time = weechat_infolist_time (infolist, "away_time");
                    irc_upgrade_current_server->lag = weechat_infolist_integer (infolist, "lag");
                    buf = weechat_infolist_buffer (infolist, "lag_check_time", &size);
                    if (buf)
                        memcpy (&(irc_upgrade_current_server->lag_check_time), buf, size);
                    irc_upgrade_current_server->lag_next_check = weechat_infolist_time (infolist, "lag_next_check");
                    irc_upgrade_current_server->lag_last_refresh = weechat_infolist_time (infolist, "lag_last_refresh");
                    irc_upgrade_current_server->last_user_message = weechat_infolist_time (infolist, "last_user_message");
                    irc_upgrade_current_server->last_away_check = weechat_infolist_time (infolist, "last_away_check");
                    irc_upgrade_current_server->last_data_purge = weechat_infolist_time (infolist, "last_data_purge");
                }
                break;
            case IRC_UPGRADE_TYPE_CHANNEL:
                if (irc_upgrade_current_server)
                {
                    irc_upgrade_current_channel = irc_channel_new (irc_upgrade_current_server,
                                                                   weechat_infolist_integer (infolist, "type"),
                                                                   weechat_infolist_string (infolist, "name"),
                                                                   0, 0);
                    if (irc_upgrade_current_channel)
                    {
                        str = weechat_infolist_string (infolist, "topic");
                        if (str)
                            irc_channel_set_topic (irc_upgrade_current_channel, str);
                        str = weechat_infolist_string (infolist, "modes");
                        if (str)
                            irc_upgrade_current_channel->modes = strdup (str);
                        irc_upgrade_current_channel->limit = weechat_infolist_integer (infolist, "limit");
                        str = weechat_infolist_string (infolist, "key");
                        if (str)
                            irc_upgrade_current_channel->key = strdup (str);
                        str = weechat_infolist_string (infolist, "join_msg_received");
                        if (str)
                        {
                            items = weechat_string_split (str, ",", 0, 0,
                                                          &num_items);
                            if (items)
                            {
                                for (i = 0; i < num_items; i++)
                                {
                                    weechat_hashtable_set (irc_upgrade_current_channel->join_msg_received,
                                                           items[i], "1");
                                }
                                weechat_string_free_split (items);
                            }
                        }
                        irc_upgrade_current_channel->checking_away = weechat_infolist_integer (infolist, "checking_away");
                        str = weechat_infolist_string (infolist, "away_message");
                        if (str)
                            irc_upgrade_current_channel->away_message = strdup (str);
                        irc_upgrade_current_channel->has_quit_server = weechat_infolist_integer (infolist, "has_quit_server");
                        irc_upgrade_current_channel->cycle = weechat_infolist_integer (infolist, "cycle");
                        irc_upgrade_current_channel->part = weechat_infolist_integer (infolist, "part");
                        irc_upgrade_current_channel->nick_completion_reset = weechat_infolist_integer (infolist, "nick_completion_reset");
                        for (i = 0; i < 2; i++)
                        {
                            index = 0;
                            while (1)
                            {
                                snprintf (option_name, sizeof (option_name),
                                          "nick_speaking%d_%05d", i, index);
                                nick = weechat_infolist_string (infolist, option_name);
                                if (!nick)
                                    break;
                                irc_channel_nick_speaking_add (irc_upgrade_current_channel,
                                                               nick,
                                                               i);
                                index++;
                            }
                        }
                        index = 0;
                        while (1)
                        {
                            snprintf (option_name, sizeof (option_name),
                                      "nick_speaking_time_nick_%05d", index);
                            nick = weechat_infolist_string (infolist, option_name);
                            if (!nick)
                                break;
                            snprintf (option_name, sizeof (option_name),
                                      "nick_speaking_time_time_%05d", index);
                            irc_channel_nick_speaking_time_add (irc_upgrade_current_server,
                                                                irc_upgrade_current_channel,
                                                                nick,
                                                                weechat_infolist_time (infolist,
                                                                                       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;
            case IRC_UPGRADE_TYPE_NICK:
                if (irc_upgrade_current_server && irc_upgrade_current_channel)
                {
                    ptr_nick = irc_nick_new (irc_upgrade_current_server,
                                             irc_upgrade_current_channel,
                                             weechat_infolist_string (infolist, "name"),
                                             weechat_infolist_string (infolist, "host"),
                                             weechat_infolist_string (infolist, "prefixes"),
                                             weechat_infolist_integer (infolist, "away"));
                    if (ptr_nick)
                    {
                        /*
                         * "flags" is not any more in this infolist (since
                         * WeeChat 0.3.4), but we read it to keep compatibility
                         * with old WeeChat versions, on /upgrade)
                         * We try to restore prefixes with old flags, but
                         * this is approximation, it's not sure we will
                         * restore good prefixes here (a /names on channel
                         * will fix problem if prefixes are wrong).
                         * Flags were defined in irc-nick.h:
                         *   #define IRC_NICK_CHANOWNER  1
                         *   #define IRC_NICK_CHANADMIN  2
                         *   #define IRC_NICK_CHANADMIN2 4
                         *   #define IRC_NICK_OP         8
                         *   #define IRC_NICK_HALFOP     16
                         *   #define IRC_NICK_VOICE      32
                         *   #define IRC_NICK_AWAY       64
                         *   #define IRC_NICK_CHANUSER   128
                         */
                        flags = weechat_infolist_integer (infolist, "flags");
                        if (flags > 0)
                        {
                            /* channel owner */
                            if (flags & 1)
                            {
                                irc_nick_set_mode (irc_upgrade_current_server,
                                                   irc_upgrade_current_channel,
                                                   ptr_nick, 1, 'q');
                            }
                            /* channel admin */
                            if ((flags & 2) || (flags & 4))
                            {
                                irc_nick_set_mode (irc_upgrade_current_server,
                                                   irc_upgrade_current_channel,
                                                   ptr_nick, 1, 'a');
                            }
                            /* op */
                            if (flags & 8)
                            {
                                irc_nick_set_mode (irc_upgrade_current_server,
                                                   irc_upgrade_current_channel,
                                                   ptr_nick, 1, 'o');
                            }
                            /* half-op */
                            if (flags & 16)
                            {
                                irc_nick_set_mode (irc_upgrade_current_server,
                                                   irc_upgrade_current_channel,
                                                   ptr_nick, 1, 'h');
                            }
                            /* voice */
                            if (flags & 32)
                            {
                                irc_nick_set_mode (irc_upgrade_current_server,
                                                   irc_upgrade_current_channel,
                                                   ptr_nick, 1, 'v');
                            }
                            /* away */
                            if (flags & 64)
                            {
                                irc_nick_set_away (irc_upgrade_current_server,
                                                   irc_upgrade_current_channel,
                                                   ptr_nick, 1);
                            }
                            /* channel user */
                            if (flags & 128)
                            {
                                irc_nick_set_mode (irc_upgrade_current_server,
                                                   irc_upgrade_current_channel,
                                                   ptr_nick, 1, 'u');
                            }
                        }
                    }
                }
                break;
            case IRC_UPGRADE_TYPE_REDIRECT:
                if (irc_upgrade_current_server)
                {
                    ptr_redirect = irc_redirect_new_with_commands (
                        irc_upgrade_current_server,
                        weechat_infolist_string (infolist, "pattern"),
                        weechat_infolist_string (infolist, "signal"),
                        weechat_infolist_integer (infolist, "count"),
                        weechat_infolist_string (infolist, "string"),
                        weechat_infolist_integer (infolist, "timeout"),
                        weechat_infolist_string (infolist, "cmd_start"),
                        weechat_infolist_string (infolist, "cmd_stop"),
                        weechat_infolist_string (infolist, "cmd_extra"),
                        weechat_infolist_string (infolist, "cmd_filter"));
                    if (ptr_redirect)
                    {
                        ptr_redirect->current_count = weechat_infolist_integer (infolist, "current_count");
                        str = weechat_infolist_string (infolist, "command");
                        if (str)
                            ptr_redirect->command = strdup (str);
                        ptr_redirect->assigned_to_command = weechat_infolist_integer (infolist, "assigned_to_command");
                        ptr_redirect->start_time = weechat_infolist_time (infolist, "start_time");
                        ptr_redirect->cmd_start_received = weechat_infolist_integer (infolist, "cmd_start_received");
                        ptr_redirect->cmd_stop_received = weechat_infolist_integer (infolist, "cmd_stop_received");
                        str = weechat_infolist_string (infolist, "output");
                        if (str)
                            ptr_redirect->output = strdup (str);
                        ptr_redirect->output_size = weechat_infolist_integer (infolist, "output_size");
                    }
                }
                break;
            case IRC_UPGRADE_TYPE_REDIRECT_PATTERN:
                irc_redirect_pattern_new (
                    weechat_infolist_string (infolist, "name"),
                    weechat_infolist_integer (infolist, "temp_pattern"),
                    weechat_infolist_integer (infolist, "timeout"),
                    weechat_infolist_string (infolist, "cmd_start"),
                    weechat_infolist_string (infolist, "cmd_stop"),
                    weechat_infolist_string (infolist, "cmd_extra"));
                break;
            case IRC_UPGRADE_TYPE_NOTIFY:
                if (irc_upgrade_current_server)
                {
                    ptr_notify = irc_notify_search (irc_upgrade_current_server,
                                                    weechat_infolist_string (infolist, "nick"));
                    if (ptr_notify)
                    {
                        ptr_notify->is_on_server = weechat_infolist_integer (infolist, "is_on_server");
                        str = weechat_infolist_string (infolist, "away_message");
                        if (str)
                            ptr_notify->away_message = strdup (str);
                    }
                }
                break;
            case IRC_UPGRADE_TYPE_RAW_MESSAGE:
                irc_raw_message_add_to_list (weechat_infolist_time (infolist, "date"),
                                             weechat_infolist_string (infolist, "prefix"),
                                             weechat_infolist_string (infolist, "message"));
                break;
        }
    }

    return WEECHAT_RC_OK;
}
Exemplo n.º 3
0
int
irc_mode_channel_set (struct t_irc_server *server,
                      struct t_irc_channel *channel,
                      const char *modes)
{
    char *pos_args, *str_modes, set_flag, **argv, *pos, *ptr_arg, chanmode_type;
    int argc, current_arg, update_channel_modes, channel_modes_updated;
    int smart_filter;
    struct t_irc_nick *ptr_nick;

    if (!server || !channel || !modes)
        return 0;

    channel_modes_updated = 0;
    argc = 0;
    argv = NULL;
    pos_args = strchr (modes, ' ');
    if (pos_args)
    {
        str_modes = weechat_strndup (modes, pos_args - modes);
        if (!str_modes)
            return 0;
        pos_args++;
        while (pos_args[0] == ' ')
            pos_args++;
        argv = weechat_string_split (pos_args, " ", 0, 0, &argc);
    }
    else
    {
        str_modes = strdup (modes);
        if (!str_modes)
            return 0;
    }

    current_arg = 0;

    smart_filter = (weechat_config_boolean (irc_config_look_smart_filter)
                    && weechat_config_string (irc_config_look_smart_filter_mode)
                    && weechat_config_string (irc_config_look_smart_filter_mode)[0]) ? 1 : 0;

    if (str_modes && str_modes[0])
    {
        set_flag = '+';
        pos = str_modes;
        while (pos && pos[0])
        {
            switch (pos[0])
            {
                case ':':
                case ' ':
                    break;
                case '+':
                    set_flag = '+';
                    break;
                case '-':
                    set_flag = '-';
                    break;
                default:
                    update_channel_modes = 1;
                    chanmode_type = irc_mode_get_chanmode_type (server, pos[0]);
                    ptr_arg = NULL;
                    switch (chanmode_type)
                    {
                        case 'A': /* always argument */
                            update_channel_modes = 0;
                            ptr_arg = (current_arg < argc) ?
                                argv[current_arg] : NULL;
                            break;
                        case 'B': /* always argument */
                            ptr_arg = (current_arg < argc) ?
                                argv[current_arg] : NULL;
                            break;
                        case 'C': /* argument if set */
                            ptr_arg = ((set_flag == '+') && (current_arg < argc)) ?
                                argv[current_arg] : NULL;
                            break;
                        case 'D': /* no argument */
                            break;
                    }
                    if (ptr_arg)
                        current_arg++;

                    if (smart_filter
                        && !irc_mode_smart_filtered (server, pos[0]))
                    {
                        smart_filter = 0;
                    }

                    if (pos[0] == 'k')
                    {
                        /* channel key */
                        if (set_flag == '-')
                        {
                            if (channel->key)
                            {
                                free (channel->key);
                                channel->key = NULL;
                            }
                        }
                        else if ((set_flag == '+')
                                 && ptr_arg && (strcmp (ptr_arg, "*") != 0))
                        {
                            /* replace key for +k, but ignore "*" as new key */
                            if (channel->key)
                                free (channel->key);
                            channel->key = strdup (ptr_arg);
                        }
                    }
                    else if (pos[0] == 'l')
                    {
                        /* channel limit */
                        if (set_flag == '-')
                            channel->limit = 0;
                        if ((set_flag == '+') && ptr_arg)
                        {
                            channel->limit = atoi (ptr_arg);
                        }
                    }
                    else if ((chanmode_type != 'A')
                             && (irc_server_get_prefix_mode_index (server,
                                                                   pos[0]) >= 0))
                    {
                        /* mode for nick */
                        update_channel_modes = 0;
                        if (ptr_arg)
                        {
                            ptr_nick = irc_nick_search (server, channel,
                                                        ptr_arg);
                            if (ptr_nick)
                            {
                                irc_nick_set_mode (server, channel, ptr_nick,
                                                   (set_flag == '+'), pos[0]);
                                if (smart_filter
                                    && irc_channel_nick_speaking_time_search (server,
                                                                              channel,
                                                                              ptr_nick->name,
                                                                              1))
                                {
                                    smart_filter = 0;
                                }
                            }
                        }
                    }
                    if (update_channel_modes)
                    {
                        irc_mode_channel_update (server, channel, set_flag,
                                                 pos[0], ptr_arg);
                        channel_modes_updated = 1;
                    }
                    break;
            }
            pos++;
        }
    }

    if (str_modes)
        free (str_modes);
    if (argv)
        weechat_string_free_split (argv);

    if (channel_modes_updated)
        weechat_bar_item_update ("buffer_modes");

    return smart_filter;
}