Ejemplo n.º 1
0
int
weechat_aspell_check_word (struct t_aspell_speller_buffer *speller_buffer,
                           const char *word)
{
    int i;

    /* word too small? then do not check word */
    if ((weechat_config_integer (weechat_aspell_config_check_word_min_length) > 0)
        && ((int)strlen (word) < weechat_config_integer (weechat_aspell_config_check_word_min_length)))
        return 1;

    /* word is a number? then do not check word */
    if (weechat_aspell_string_is_simili_number (word))
        return 1;

    /* check word with all spellers (order is important) */
    if (speller_buffer->spellers)
    {
        for (i = 0; speller_buffer->spellers[i]; i++)
        {
#ifdef USE_ENCHANT
            if (enchant_dict_check (speller_buffer->spellers[i], word, strlen (word)) == 0)
#else
            if (aspell_speller_check (speller_buffer->spellers[i], word, -1) == 1)
#endif /* USE_ENCHANT */
                return 1;
        }
    }

    /* misspelled word! */
    return 0;
}
Ejemplo n.º 2
0
int
logger_backlog_signal_cb (void *data, const char *signal,
                          const char *type_data, void *signal_data)
{
    struct t_logger_buffer *ptr_logger_buffer;

    /* make C compiler happy */
    (void) data;
    (void) signal;
    (void) type_data;

    if (weechat_config_integer (logger_config_look_backlog) >= 0)
    {
        ptr_logger_buffer = logger_buffer_search_buffer (signal_data);
        if (ptr_logger_buffer && ptr_logger_buffer->log_enabled)
        {
            if (!ptr_logger_buffer->log_filename)
                logger_set_log_filename (ptr_logger_buffer);

            if (ptr_logger_buffer->log_filename)
            {
                ptr_logger_buffer->log_enabled = 0;

                logger_backlog (signal_data,
                                ptr_logger_buffer->log_filename,
                                weechat_config_integer (logger_config_look_backlog));

                ptr_logger_buffer->log_enabled = 1;
            }
        }
    }

    return WEECHAT_RC_OK;
}
Ejemplo n.º 3
0
int
irc_completion_channel_nicks_cb (void *data, const char *completion_item,
                                 struct t_gui_buffer *buffer,
                                 struct t_gui_completion *completion)
{
    struct t_irc_nick *ptr_nick;

    IRC_BUFFER_GET_SERVER_CHANNEL(buffer);

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

    if (ptr_channel)
    {
        switch (ptr_channel->type)
        {
            case IRC_CHANNEL_TYPE_CHANNEL:
                for (ptr_nick = ptr_channel->nicks; ptr_nick;
                     ptr_nick = ptr_nick->next_nick)
                {
                    weechat_hook_completion_list_add (completion,
                                                      ptr_nick->name,
                                                      1,
                                                      WEECHAT_LIST_POS_SORT);
                }
                /* add recent speakers on channel */
                if (weechat_config_integer (irc_config_look_nick_completion_smart) == IRC_CONFIG_NICK_COMPLETION_SMART_SPEAKERS)
                {
                    irc_completion_channel_nicks_add_speakers (completion, ptr_server, ptr_channel, 0);
                }
                /* add nicks whose make highlights on me recently on this channel */
                if (weechat_config_integer (irc_config_look_nick_completion_smart) == IRC_CONFIG_NICK_COMPLETION_SMART_SPEAKERS_HIGHLIGHTS)
                {
                    irc_completion_channel_nicks_add_speakers (completion, ptr_server, ptr_channel, 1);
                }
                /* add self nick at the end */
                weechat_hook_completion_list_add (completion,
                                                  ptr_server->nick,
                                                  1,
                                                  WEECHAT_LIST_POS_END);
                break;
            case IRC_CHANNEL_TYPE_PRIVATE:
                /* remote nick */
                weechat_hook_completion_list_add (completion,
                                                  ptr_channel->name,
                                                  1,
                                                  WEECHAT_LIST_POS_SORT);
                /* add self nick at the end */
                weechat_hook_completion_list_add (completion,
                                                  ptr_server->nick,
                                                  1,
                                                  WEECHAT_LIST_POS_END);
                break;
        }
        ptr_channel->nick_completion_reset = 0;
    }

    return WEECHAT_RC_OK;
}
Ejemplo n.º 4
0
struct t_gui_buffer *
irc_msgbuffer_get_target_buffer (struct t_irc_server *server, const char *nick,
                                 const char *message, const char *alias,
                                 struct t_gui_buffer *default_buffer)
{
    struct t_config_option *ptr_option;
    int target;
    struct t_gui_buffer *ptr_buffer;
    struct t_irc_channel *ptr_channel;
    struct t_weechat_plugin *buffer_plugin;

    ptr_option = NULL;

    if (message && message[0])
        ptr_option = irc_msgbuffer_get_option (server, message);
    if (!ptr_option && alias && alias[0])
        ptr_option = irc_msgbuffer_get_option (server, alias);

    if (!ptr_option)
    {
        if (default_buffer)
            return default_buffer;
        return (server) ? server->buffer : NULL;
    }

    target = weechat_config_integer (ptr_option);
    switch (target)
    {
        case IRC_MSGBUFFER_TARGET_WEECHAT:
            return NULL;
            break;
        case IRC_MSGBUFFER_TARGET_SERVER:
            return (server) ? server->buffer : NULL;
            break;
        case IRC_MSGBUFFER_TARGET_CURRENT:
            break;
        case IRC_MSGBUFFER_TARGET_PRIVATE:
            ptr_channel = irc_channel_search (server, nick);
            if (ptr_channel)
                return ptr_channel->buffer;
            if (weechat_config_integer (irc_config_look_msgbuffer_fallback) ==
                IRC_CONFIG_LOOK_MSGBUFFER_FALLBACK_SERVER)
            {
                return (server) ? server->buffer : NULL;
            }
            break;
        default:
            return (server) ? server->buffer : NULL;
            break;
    }

    ptr_buffer = weechat_current_buffer ();
    buffer_plugin = weechat_buffer_get_pointer (ptr_buffer, "plugin");
    if (buffer_plugin == weechat_irc_plugin)
        return ptr_buffer;

    return (server) ? server->buffer : NULL;
}
Ejemplo n.º 5
0
int
xfer_network_connect (struct t_xfer *xfer)
{
    if (xfer->type == XFER_TYPE_CHAT_SEND)
        xfer->status = XFER_STATUS_WAITING;
    else
        xfer->status = XFER_STATUS_CONNECTING;
    
    if (xfer->sock < 0)
    {
        xfer->sock = socket (AF_INET, SOCK_STREAM, 0);
        if (xfer->sock < 0)
            return 0;
    }
    
    if (XFER_IS_SEND(xfer->type))
    {
        /* listen to socket */
        if (fcntl (xfer->sock, F_SETFL, O_NONBLOCK) == -1)
            return 0;	
        if (listen (xfer->sock, 1) == -1)
            return 0;
        if (fcntl (xfer->sock, F_SETFL, 0) == -1)
            return 0;

        xfer->hook_fd = weechat_hook_fd (xfer->sock,
                                         1, 0, 0,
                                         &xfer_network_fd_cb,
                                         xfer);
        
        /* add timeout */
        if (weechat_config_integer (xfer_config_network_timeout) > 0)
        {
            xfer->hook_timer = weechat_hook_timer (weechat_config_integer (xfer_config_network_timeout) * 1000,
                                                   0, 1,
                                                   &xfer_network_timer_cb,
                                                   xfer);
        }
    }
    
    /* for chat receiving, connect to listening host */
    if (xfer->type == XFER_TYPE_CHAT_RECV)
    {
        if (fcntl (xfer->sock, F_SETFL, O_NONBLOCK) == -1)
            return 0;
        weechat_network_connect_to (xfer->proxy, xfer->sock, xfer->address,
                                    xfer->port);
        
        xfer->hook_fd = weechat_hook_fd (xfer->sock,
                                         1, 0, 0,
                                         &xfer_chat_recv_cb,
                                         xfer);
    }
    
    /* for file receiving, connection is made in child process (blocking) */
    
    return 1;
}
Ejemplo n.º 6
0
int
weechat_aspell_check_word (struct t_gui_buffer *buffer,
                           struct t_aspell_speller_buffer *speller_buffer,
                           const char *word)
{
    const char *buffer_type, *buffer_nick, *buffer_channel;
    int i;

    /* word too small? then do not check word */
    if ((weechat_config_integer (weechat_aspell_config_check_word_min_length) > 0)
        && ((int)strlen (word) < weechat_config_integer (weechat_aspell_config_check_word_min_length)))
        return 1;

    /* word is a number? then do not check word */
    if (weechat_aspell_string_is_simili_number (word))
        return 1;

    /* word is a nick of nicklist on this buffer? then do not check word */
    if (weechat_nicklist_search_nick (buffer, NULL, word))
        return 1;

    /* for "private" buffers, ignore self and remote nicks */
    buffer_type = weechat_buffer_get_string (buffer, "localvar_type");
    if (buffer_type && (strcmp (buffer_type, "private") == 0))
    {
        /* check self nick */
        buffer_nick = weechat_buffer_get_string (buffer, "localvar_nick");
        if (buffer_nick && (weechat_strcasecmp (buffer_nick, word) == 0))
            return 1;
        /* check remote nick */
        buffer_channel = weechat_buffer_get_string (buffer, "localvar_channel");
        if (buffer_channel && (weechat_strcasecmp (buffer_channel, word) == 0))
            return 1;
    }

    /* check word with all spellers for this buffer (order is important) */
    if (speller_buffer->spellers)
    {
        for (i = 0; speller_buffer->spellers[i]; i++)
        {
#ifdef USE_ENCHANT
            if (enchant_dict_check (speller_buffer->spellers[i], word, strlen (word)) == 0)
#else
            if (aspell_speller_check (speller_buffer->spellers[i], word, -1) == 1)
#endif
                return 1;
        }
    }

    /* misspelled word! */
    return 0;
}
Ejemplo n.º 7
0
int
logger_get_level_for_buffer (struct t_gui_buffer *buffer)
{
    const char *no_log;
    char *name, *option_name, *ptr_end;
    struct t_config_option *ptr_option;

    /* no log for buffer if local variable "no_log" is defined for buffer */
    no_log = weechat_buffer_get_string (buffer, "localvar_no_log");
    if (no_log && no_log[0])
        return 0;

    name = logger_build_option_name (buffer);
    if (!name)
        return LOGGER_LEVEL_DEFAULT;

    option_name = strdup (name);
    if (option_name)
    {
        ptr_end = option_name + strlen (option_name);
        while (ptr_end >= option_name)
        {
            ptr_option = logger_config_get_level (option_name);
            if (ptr_option)
            {
                free (option_name);
                free (name);
                return weechat_config_integer (ptr_option);
            }
            ptr_end--;
            while ((ptr_end >= option_name) && (ptr_end[0] != '.'))
            {
                ptr_end--;
            }
            if ((ptr_end >= option_name) && (ptr_end[0] == '.'))
                ptr_end[0] = '\0';
        }
        ptr_option = logger_config_get_level (option_name);

        free (option_name);
        free (name);

        if (ptr_option)
            return weechat_config_integer (ptr_option);
    }
    else
        free (name);

    /* nothing found => return default level */
    return LOGGER_LEVEL_DEFAULT;
}
Ejemplo n.º 8
0
char *
irc_bar_item_lag (void *data, struct t_gui_bar_item *item,
                  struct t_gui_window *window, struct t_gui_buffer *buffer,
                  struct t_hashtable *extra_info)
{
    char buf[128];
    struct t_irc_server *server;

    /* make C compiler happy */
    (void) data;
    (void) item;
    (void) window;
    (void) extra_info;

    if (!buffer)
        return NULL;

    irc_buffer_get_server_and_channel (buffer, &server, NULL);

    if (server
        && (server->lag >= weechat_config_integer (irc_config_network_lag_min_show)))
    {
        snprintf (buf, sizeof (buf),
                  ((server->lag_check_time.tv_sec == 0) || (server->lag < 1000)) ?
                  "%s: %s%.3f" : "%s: %s%.0f",
                  _("Lag"),
                  (server->lag_check_time.tv_sec == 0) ?
                  IRC_COLOR_ITEM_LAG_FINISHED : IRC_COLOR_ITEM_LAG_COUNTING,
                  ((float)(server->lag)) / 1000);
        return strdup (buf);
    }

    return NULL;
}
Ejemplo n.º 9
0
void
relay_raw_print (struct t_relay_client *client, int flags,
                 const char *format, ...)
{
    struct t_relay_raw_message *new_raw_message;

    weechat_va_format (format);
    if (!vbuffer)
        return;

    /* auto-open Relay raw buffer if debug for irc plugin is >= 1 */
    if (!relay_raw_buffer && (weechat_relay_plugin->debug >= 1))
        relay_raw_open (0);

    new_raw_message = relay_raw_message_add (client, flags, vbuffer);
    if (new_raw_message)
    {
        if (relay_raw_buffer)
            relay_raw_message_print (new_raw_message);
        if (weechat_config_integer (relay_config_look_raw_messages) == 0)
            relay_raw_message_free (new_raw_message);
    }

    free (vbuffer);
}
Ejemplo n.º 10
0
int
weechat_aspell_check_word (struct t_gui_buffer *buffer, const char *word)
{
    struct t_aspell_speller *ptr_speller;
    int rc;
    
    rc = 0;
    
    /* word too small? then do not check word */
    if ((weechat_config_integer (weechat_aspell_config_check_word_min_length) > 0)
        && ((int)strlen (word) < weechat_config_integer (weechat_aspell_config_check_word_min_length)))
        rc = 1;
    else
    {
        /* word is URL? then do not check word */
        if (weechat_aspell_string_is_url (word))
            rc = 1;
        else
        {
            /* word is a number? then do not check word */
            if (weechat_aspell_string_is_simili_number (word))
                rc = 1;
            else
            {
                /* word is a nick of nicklist on this buffer? then do not check word */
                if (weechat_nicklist_search_nick (buffer, NULL, word))
                    rc = 1;
                else
                {
                    /* check word with all spellers for this buffer (order is important) */
                    for (ptr_speller = weechat_aspell_spellers; ptr_speller;
                         ptr_speller = ptr_speller->next_speller)
                    {
                        if (aspell_speller_check (ptr_speller->speller, word, -1) == 1)
                        {
                            rc = 1;
                            break;
                        }
                    }
                }
            }
        }
    }
    
    return rc;
}
Ejemplo n.º 11
0
void
irc_notify_hook_timer_ison ()
{
    if (irc_notify_timer_ison)
        weechat_unhook (irc_notify_timer_ison);

    irc_notify_timer_ison = weechat_hook_timer (
        60 * 1000 * weechat_config_integer (irc_config_network_notify_check_ison),
        0, 0, &irc_notify_timer_ison_cb, NULL, NULL);
}
Ejemplo n.º 12
0
void
irc_notify_hook_timer_whois ()
{
    if (irc_notify_timer_whois)
        weechat_unhook (irc_notify_timer_whois);

    irc_notify_timer_whois = weechat_hook_timer (
        60 * 1000 * weechat_config_integer (irc_config_network_notify_check_whois),
        0, 0, &irc_notify_timer_whois_cb, NULL, NULL);
}
Ejemplo n.º 13
0
void
irc_raw_message_remove_old ()
{
    int max_messages;
    
    max_messages = weechat_config_integer (irc_config_look_raw_messages);
    while (irc_raw_messages && (irc_raw_messages_count >= max_messages))
    {
        irc_raw_message_free (irc_raw_messages);
    }
}
Ejemplo n.º 14
0
void
relay_raw_message_remove_old ()
{
    int max_messages;

    max_messages = weechat_config_integer (relay_config_look_raw_messages);
    while (relay_raw_messages && (relay_raw_messages_count >= max_messages))
    {
        relay_raw_message_free (relay_raw_messages);
    }
}
Ejemplo n.º 15
0
void
logger_config_flush_delay_change (const void *pointer, void *data,
                                  struct t_config_option *option)
{
    /* make C compiler happy */
    (void) pointer;
    (void) data;
    (void) option;

    if (logger_config_loading)
        return;

    if (logger_timer)
    {
        if (weechat_logger_plugin->debug)
        {
            weechat_printf_date_tags (
                NULL, 0, "no_log",
                "%s: stopping timer", LOGGER_PLUGIN_NAME);
        }
        weechat_unhook (logger_timer);
        logger_timer = NULL;
    }

    if (weechat_config_integer (logger_config_file_flush_delay) > 0)
    {
        if (weechat_logger_plugin->debug)
        {
            weechat_printf_date_tags (
                NULL, 0, "no_log",
                "%s: starting timer (interval: %d seconds)",
                LOGGER_PLUGIN_NAME,
                weechat_config_integer (logger_config_file_flush_delay));
        }
        logger_timer = weechat_hook_timer (weechat_config_integer (logger_config_file_flush_delay) * 1000,
                                           0, 0,
                                           &logger_timer_cb, NULL, NULL);
    }
}
Ejemplo n.º 16
0
char *
irc_bar_item_buffer_plugin (void *data, struct t_gui_bar_item *item,
                            struct t_gui_window *window,
                            struct t_gui_buffer *buffer,
                            struct t_hashtable *extra_info)
{
    char buf[512];
    struct t_weechat_plugin *ptr_plugin;
    const char *name;
    struct t_irc_server *server;
    struct t_irc_channel *channel;

    /* make C compiler happy */
    (void) data;
    (void) item;
    (void) window;
    (void) extra_info;

    if (!buffer)
        return NULL;

    ptr_plugin = weechat_buffer_get_pointer (buffer, "plugin");
    name = weechat_plugin_get_name (ptr_plugin);
    if (ptr_plugin == weechat_irc_plugin)
    {
        irc_buffer_get_server_and_channel (buffer, &server, &channel);
        if (server && channel
            && (weechat_config_integer (irc_config_look_item_display_server) == IRC_CONFIG_LOOK_ITEM_DISPLAY_SERVER_PLUGIN))
        {
            snprintf (buf, sizeof (buf), "%s%s/%s%s",
                      name,
                      IRC_COLOR_BAR_DELIM,
                      IRC_COLOR_BAR_FG,
                      server->name);
        }
        else
        {
            snprintf (buf, sizeof (buf), "%s", name);
        }
    }
    else
    {
        snprintf (buf, sizeof (buf), "%s", name);
    }
    return strdup (buf);
}
Ejemplo n.º 17
0
/**
 * Return a friend's Tox ID in short form. Return value must be freed.
 */
char *
twc_get_friend_id_short(Tox *tox, int32_t friend_number)
{
    uint8_t client_id[TOX_PUBLIC_KEY_SIZE];
    TOX_ERR_FRIEND_GET_PUBLIC_KEY err;
    size_t short_id_length = weechat_config_integer(twc_config_short_id_size);
    char *hex_address = malloc(short_id_length + 1);

    tox_friend_get_public_key(tox, friend_number, client_id, &err);

    /* return a zero public key on failure */
    if (err != TOX_ERR_FRIEND_GET_PUBLIC_KEY_OK)
        memset(client_id, 0, TOX_PUBLIC_KEY_SIZE);

    twc_bin2hex(client_id, short_id_length / 2, hex_address);

    return hex_address;
}
Ejemplo n.º 18
0
void
trigger_command_display_trigger (struct t_trigger *trigger, int verbose)
{
    trigger_command_display_trigger_internal (
        trigger->name,
        weechat_config_boolean (trigger->options[TRIGGER_OPTION_ENABLED]),
        weechat_config_string (trigger->options[TRIGGER_OPTION_HOOK]),
        weechat_config_string (trigger->options[TRIGGER_OPTION_ARGUMENTS]),
        weechat_config_string (trigger->options[TRIGGER_OPTION_CONDITIONS]),
        trigger->hooks_count,
        trigger->hook_count_cb,
        trigger->hook_count_cmd,
        trigger->regex_count,
        trigger->regex,
        trigger->commands_count,
        trigger->commands,
        weechat_config_integer (trigger->options[TRIGGER_OPTION_RETURN_CODE]),
        verbose);
}
Ejemplo n.º 19
0
void
irc_raw_print (struct t_irc_server *server, int send, int modified,
               const char *message)
{
    struct t_irc_raw_message *new_raw_message;
    
    if (!message)
        return;
    
    if (!irc_raw_buffer && (weechat_irc_plugin->debug >= 1))
        irc_raw_open (0);
    
    new_raw_message = irc_raw_message_add (server, send, modified, message);
    if (new_raw_message)
    {
        if (irc_raw_buffer)
            irc_raw_message_print (new_raw_message);
        if (weechat_config_integer (irc_config_look_raw_messages) == 0)
            irc_raw_message_free (new_raw_message);
    }
}
Ejemplo n.º 20
0
void
irc_raw_print (struct t_irc_server *server, int flags,
               const char *message)
{
    struct t_irc_raw_message *new_raw_message;

    if (!message)
        return;

    /* auto-open IRC raw buffer if debug for irc plugin is >= 1 */
    if (!irc_raw_buffer && (weechat_irc_plugin->debug >= 1))
        irc_raw_open (0);

    new_raw_message = irc_raw_message_add (server, flags, message);
    if (new_raw_message)
    {
        if (irc_raw_buffer)
            irc_raw_message_print (new_raw_message);
        if (weechat_config_integer (irc_config_look_raw_messages) == 0)
            irc_raw_message_free (new_raw_message);
    }
}
Ejemplo n.º 21
0
void
logger_set_buffer (struct t_gui_buffer *buffer, const char *value)
{
    char *name;
    struct t_config_option *ptr_option;

    name = logger_build_option_name (buffer);
    if (!name)
        return;

    if (logger_config_set_level (name, value) != WEECHAT_CONFIG_OPTION_SET_ERROR)
    {
        ptr_option = logger_config_get_level (name);
        if (ptr_option)
        {
            weechat_printf (NULL, _("%s: \"%s\" => level %d"),
                            LOGGER_PLUGIN_NAME, name,
                            weechat_config_integer (ptr_option));
        }
    }

    free (name);
}
Ejemplo n.º 22
0
int
trigger_command_trigger (void *data, struct t_gui_buffer *buffer, int argc,
                         char **argv, char **argv_eol)
{
    struct t_trigger *ptr_trigger, *ptr_trigger2;
    struct t_trigger_regex *regex;
    char *value, **sargv, **items, input[1024], str_pos[16];
    int rc, i, type, count, index_option, enable, sargc, num_items, add_rc;
    int regex_count, regex_rc;

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

    rc = WEECHAT_RC_OK;
    sargv = NULL;

    /* list all triggers */
    if ((argc == 1)
        || ((argc == 2) && (weechat_strcasecmp (argv[1], "list") == 0)))
    {
        trigger_command_list (_("List of triggers:"), 0);
        goto end;
    }

    /* full list of all triggers */
    if ((argc == 2) && (weechat_strcasecmp (argv[1], "listfull") == 0))
    {
        trigger_command_list (_("List of triggers:"), 1);
        goto end;
    }

    /* list of default triggers */
    if ((argc == 2) && (weechat_strcasecmp (argv[1], "listdefault") == 0))
    {
        trigger_command_list_default (1);
        goto end;
    }

    /* add a trigger */
    if ((weechat_strcasecmp (argv[1], "add") == 0)
        || (weechat_strcasecmp (argv[1], "addoff") == 0)
        || (weechat_strcasecmp (argv[1], "addreplace") == 0))
    {
        sargv = weechat_string_split_shell (argv_eol[2], &sargc);
        if (!sargv || (sargc < 2))
            goto error;
        if (!trigger_name_valid (sargv[0]))
        {
            weechat_printf_tags (NULL, "no_trigger",
                                 _("%s%s: invalid name for trigger"),
                                 weechat_prefix ("error"), TRIGGER_PLUGIN_NAME);
            goto end;
        }
        type = trigger_search_hook_type (sargv[1]);
        if (type < 0)
        {
            weechat_printf_tags (NULL, "no_trigger",
                                 _("%s%s: invalid hook type \"%s\""),
                                 weechat_prefix ("error"), TRIGGER_PLUGIN_NAME,
                                 sargv[1]);
            goto end;
        }
        if ((sargc > 4) && sargv[4][0])
        {
            regex_count = 0;
            regex = NULL;
            regex_rc = trigger_regex_split (sargv[4], &regex_count, &regex);
            trigger_regex_free (&regex_count, &regex);
            switch (regex_rc)
            {
                case 0: /* OK */
                    break;
                case -1: /* format error */
                    weechat_printf (NULL,
                                    _("%s%s: invalid format for regular "
                                      "expression"),
                                    weechat_prefix ("error"),
                                    TRIGGER_PLUGIN_NAME);
                    goto end;
                    break;
                case -2: /* regex compilation error */
                    weechat_printf (NULL,
                                    _("%s%s: invalid regular expression "
                                      "(compilation failed)"),
                                    weechat_prefix ("error"),
                                    TRIGGER_PLUGIN_NAME);
                    goto end;
                    break;
                case -3: /* memory error */
                    weechat_printf (NULL,
                                    _("%s%s: not enough memory"),
                                    weechat_prefix ("error"),
                                    TRIGGER_PLUGIN_NAME);
                    goto end;
                    break;
            }
        }
        if ((sargc > 6) && sargv[6][0]
            && (trigger_search_return_code (sargv[6]) < 0))
        {
            weechat_printf_tags (NULL, "no_trigger",
                                 _("%s%s: invalid return code \"%s\""),
                                 weechat_prefix ("error"), TRIGGER_PLUGIN_NAME,
                                 sargv[6]);
            goto end;
        }
        ptr_trigger = trigger_search (sargv[0]);
        if (ptr_trigger)
        {
            if (weechat_strcasecmp (argv[1], "addreplace") == 0)
            {
                if (ptr_trigger)
                    trigger_free (ptr_trigger);
            }
            else
            {
                weechat_printf_tags (NULL, "no_trigger",
                                     _("%s%s: trigger \"%s\" already exists "
                                       "(choose another name or use option "
                                       "\"addreplace\" to overwrite it)"),
                                     weechat_prefix ("error"),
                                     TRIGGER_PLUGIN_NAME, sargv[0]);
                goto end;
            }
        }
        ptr_trigger = trigger_alloc (sargv[0]);
        if (!ptr_trigger)
        {
            weechat_printf_tags (NULL, "no_trigger",
                                 _("%s%s: failed to create trigger \"%s\""),
                                 weechat_prefix ("error"), TRIGGER_PLUGIN_NAME,
                                 sargv[0]);
            goto end;
        }
        ptr_trigger = trigger_new (
            sargv[0],                      /* name */
            (weechat_strcasecmp (argv[1], "addoff") == 0) ? "off" : "on",
            sargv[1],                      /* hook */
            (sargc > 2) ? sargv[2] : "",   /* arguments */
            (sargc > 3) ? sargv[3] : "",   /* conditions */
            (sargc > 4) ? sargv[4] : "",   /* regex */
            (sargc > 5) ? sargv[5] : "",   /* command */
            (sargc > 6) ? sargv[6] : "");  /* return code */
        if (ptr_trigger)
        {
            weechat_printf_tags (NULL, "no_trigger",
                                 _("Trigger \"%s\" created"), sargv[0]);
        }
        else
        {
            weechat_printf_tags (NULL, "no_trigger",
                                 _("%s%s: failed to create trigger \"%s\""),
                                 weechat_prefix ("error"), TRIGGER_PLUGIN_NAME,
                                 sargv[0]);
        }
        goto end;
    }

    /* add trigger command in input (to help trigger creation) */
    if (weechat_strcasecmp (argv[1], "addinput") == 0)
    {
        type = TRIGGER_HOOK_SIGNAL;
        if (argc >= 3)
        {
            type = trigger_search_hook_type (argv[2]);
            if (type < 0)
            {
                weechat_printf_tags (NULL, "no_trigger",
                                     _("%s%s: invalid hook type \"%s\""),
                                     weechat_prefix ("error"),
                                     TRIGGER_PLUGIN_NAME, argv[2]);
                goto end;
            }
        }
        items = weechat_string_split (trigger_hook_default_rc[type], ",", 0, 0,
                                      &num_items);
        snprintf (input, sizeof (input),
                  "/trigger add name %s \"%s\" \"%s\" \"%s\" \"%s\"%s%s%s",
                  trigger_hook_type_string[type],
                  trigger_hook_default_arguments[type],
                  TRIGGER_HOOK_DEFAULT_CONDITIONS,
                  TRIGGER_HOOK_DEFAULT_REGEX,
                  TRIGGER_HOOK_DEFAULT_COMMAND,
                  (items && (num_items > 0)) ? " \"" : "",
                  (items && (num_items > 0)) ? items[0] : "",
                  (items && (num_items > 0)) ? "\"" : "");
        weechat_buffer_set (buffer, "input", input);
        weechat_buffer_set (buffer, "input_pos", "13");
        goto end;
    }

    /*
     * get command to create a trigger, and according to option:
     * - input: put the command in input
     * - output: send the command to the buffer
     * - recreate: same as input, but the trigger is first deleted
     */
    if ((weechat_strcasecmp (argv[1], "input") == 0)
        || (weechat_strcasecmp (argv[1], "output") == 0)
        || (weechat_strcasecmp (argv[1], "recreate") == 0))
    {
        if (argc < 3)
            goto error;
        ptr_trigger = trigger_search (argv[2]);
        if (!ptr_trigger)
        {
            weechat_printf_tags (NULL, "no_trigger",
                                 _("%s%s: trigger \"%s\" not found"),
                                 weechat_prefix ("error"), TRIGGER_PLUGIN_NAME,
                                 argv[2]);
            goto end;
        }
        add_rc = trigger_hook_default_rc[weechat_config_integer (ptr_trigger->options[TRIGGER_OPTION_HOOK])][0];
        snprintf (input, sizeof (input),
                  "//trigger %s %s %s \"%s\" \"%s\" \"%s\" \"%s\"%s%s%s",
                  (weechat_strcasecmp (argv[1], "recreate") == 0) ? "addreplace" : "add",
                  ptr_trigger->name,
                  weechat_config_string (ptr_trigger->options[TRIGGER_OPTION_HOOK]),
                  weechat_config_string (ptr_trigger->options[TRIGGER_OPTION_ARGUMENTS]),
                  weechat_config_string (ptr_trigger->options[TRIGGER_OPTION_CONDITIONS]),
                  weechat_config_string (ptr_trigger->options[TRIGGER_OPTION_REGEX]),
                  weechat_config_string (ptr_trigger->options[TRIGGER_OPTION_COMMAND]),
                  (add_rc) ? " \"" : "",
                  (add_rc) ? weechat_config_string (ptr_trigger->options[TRIGGER_OPTION_RETURN_CODE]) : "",
                  (add_rc) ? "\"" : "");
        if (weechat_strcasecmp (argv[1], "output") == 0)
        {
            weechat_command (buffer, input);
        }
        else
        {
            weechat_buffer_set (buffer, "input", input + 1);
            snprintf (str_pos, sizeof (str_pos),
                      "%d", weechat_utf8_strlen (input + 1));
            weechat_buffer_set (buffer, "input_pos", str_pos);
        }
        goto end;
    }

    /* set option in a trigger */
    if (weechat_strcasecmp (argv[1], "set") == 0)
    {
        if (argc < 5)
            goto error;
        ptr_trigger = trigger_search (argv[2]);
        if (!ptr_trigger)
        {
            weechat_printf_tags (NULL, "no_trigger",
                                 _("%s%s: trigger \"%s\" not found"),
                                 weechat_prefix ("error"), TRIGGER_PLUGIN_NAME,
                                 argv[2]);
            goto end;
        }
        if (weechat_strcasecmp (argv[3], "name") == 0)
        {
            trigger_command_rename (ptr_trigger, argv[4]);
            goto end;
        }
        value = weechat_string_remove_quotes (argv_eol[4], "'\"");
        if (value)
        {
            index_option = trigger_search_option (argv[3]);
            if (index_option >= 0)
            {
                weechat_config_option_set (ptr_trigger->options[index_option],
                                           value, 1);
                weechat_printf_tags (NULL, "no_trigger",
                                     _("Trigger \"%s\" updated"),
                                     ptr_trigger->name);
            }
            else
            {
                weechat_printf_tags (NULL, "no_trigger",
                                     _("%s%s: trigger option \"%s\" not "
                                       "found"),
                                     weechat_prefix ("error"),
                                     TRIGGER_PLUGIN_NAME, argv[3]);
            }
            free (value);
        }
        goto end;
    }

    /* rename a trigger */
    if (weechat_strcasecmp (argv[1], "rename") == 0)
    {
        if (argc < 4)
            goto error;
        ptr_trigger = trigger_search (argv[2]);
        if (!ptr_trigger)
        {
            weechat_printf_tags (NULL, "no_trigger",
                                 _("%s%s: trigger \"%s\" not found"),
                                 weechat_prefix ("error"), TRIGGER_PLUGIN_NAME,
                                 argv[2]);
            goto end;
        }
        trigger_command_rename (ptr_trigger, argv[3]);
        goto end;
    }

    /* copy a trigger */
    if (weechat_strcasecmp (argv[1], "copy") == 0)
    {
        if (argc < 4)
            goto error;
        ptr_trigger = trigger_search (argv[2]);
        if (!ptr_trigger)
        {
            weechat_printf_tags (NULL, "no_trigger",
                                 _("%s%s: trigger \"%s\" not found"),
                                 weechat_prefix ("error"), TRIGGER_PLUGIN_NAME,
                                 argv[2]);
            goto end;
        }
        /* check that new name is valid */
        if (!trigger_name_valid (argv[3]))
        {
            weechat_printf_tags (NULL, "no_trigger",
                                 _("%s%s: invalid name for trigger"),
                                 weechat_prefix ("error"), TRIGGER_PLUGIN_NAME);
            goto end;
        }
        /* check that no trigger already exists with the new name */
        if (trigger_search (argv[3]))
        {
            weechat_printf_tags (NULL, "no_trigger",
                                 _("%s%s: trigger \"%s\" already "
                                   "exists"),
                                 weechat_prefix ("error"), TRIGGER_PLUGIN_NAME,
                                 argv[3]);
            goto end;
        }
        /* copy the trigger */
        ptr_trigger2 = trigger_copy (ptr_trigger, argv[3]);
        if (ptr_trigger2)
        {
            weechat_printf_tags (NULL, "no_trigger",
                                 _("Trigger \"%s\" copied to \"%s\""),
                                 ptr_trigger->name, ptr_trigger2->name);
        }
        else
        {
            weechat_printf_tags (NULL, "no_trigger",
                                 _("%s%s: failed to copy trigger "
                                   "\"%s\""),
                                 weechat_prefix ("error"), TRIGGER_PLUGIN_NAME,
                                 ptr_trigger->name);
        }
        goto end;
    }

    /* enable/disable/toggle/restart trigger(s) */
    if ((weechat_strcasecmp (argv[1], "enable") == 0)
        || (weechat_strcasecmp (argv[1], "disable") == 0)
        || (weechat_strcasecmp (argv[1], "toggle") == 0)
        || (weechat_strcasecmp (argv[1], "restart") == 0))
    {
        if (argc < 3)
        {
            if (weechat_strcasecmp (argv[1], "restart") == 0)
                goto error;
            if (weechat_strcasecmp (argv[1], "enable") == 0)
                weechat_config_option_set (trigger_config_look_enabled, "1", 1);
            else if (weechat_strcasecmp (argv[1], "disable") == 0)
                weechat_config_option_set (trigger_config_look_enabled, "0", 1);
            else if (weechat_strcasecmp (argv[1], "toggle") == 0)
            {
                weechat_config_option_set (trigger_config_look_enabled,
                                           (trigger_enabled) ? "0" : "1",
                                           1);
            }
            trigger_command_display_status ();
            goto end;
        }
        enable = -1;
        if (weechat_strcasecmp (argv[1], "enable") == 0)
            enable = 1;
        else if (weechat_strcasecmp (argv[1], "disable") == 0)
            enable = 0;
        else if (weechat_strcasecmp (argv[1], "restart") == 0)
            enable = 2;
        if (weechat_strcasecmp (argv[2], "-all") == 0)
        {
            for (ptr_trigger = triggers; ptr_trigger;
                 ptr_trigger = ptr_trigger->next_trigger)
            {
                trigger_command_set_enabled (ptr_trigger, enable, 0);
            }
        }
        else
        {
            for (i = 2; i < argc; i++)
            {
                ptr_trigger = trigger_search (argv[i]);
                if (ptr_trigger)
                    trigger_command_set_enabled (ptr_trigger, enable, 1);
                else
                {
                    weechat_printf_tags (NULL, "no_trigger",
                                         _("%sTrigger \"%s\" not found"),
                                         weechat_prefix ("error"), argv[i]);
                }
            }
        }
        goto end;
    }

    /* delete trigger(s) */
    if (weechat_strcasecmp (argv[1], "del") == 0)
    {
        if (argc < 3)
            goto error;
        if (weechat_strcasecmp (argv[2], "-all") == 0)
        {
            count = triggers_count;
            trigger_free_all ();
            if (count > 0)
                weechat_printf_tags (NULL, "no_trigger",
                                     _("%d triggers removed"), count);
        }
        else
        {
            for (i = 2; i < argc; i++)
            {
                ptr_trigger = trigger_search (argv[i]);
                if (ptr_trigger)
                {
                    trigger_free (ptr_trigger);
                    weechat_printf_tags (NULL, "no_trigger",
                                         _("Trigger \"%s\" removed"), argv[i]);
                }
                else
                {
                    weechat_printf_tags (NULL, "no_trigger",
                                         _("%sTrigger \"%s\" not found"),
                                         weechat_prefix ("error"), argv[i]);
                }
            }
        }
        goto end;
    }

    /* show detailed info on a trigger */
    if (weechat_strcasecmp (argv[1], "show") == 0)
    {
        if (argc < 3)
            goto error;
        ptr_trigger = trigger_search (argv[2]);
        if (!ptr_trigger)
        {
            weechat_printf_tags (NULL, "no_trigger",
                                 _("%s%s: trigger \"%s\" not found"),
                                 weechat_prefix ("error"), TRIGGER_PLUGIN_NAME,
                                 argv[2]);
            goto end;
        }
        weechat_printf_tags (NULL, "no_trigger", "");
        weechat_printf_tags (NULL, "no_trigger", _("Trigger:"));
        trigger_command_display_trigger (ptr_trigger, 2);
        goto end;
    }

    /* restore default triggers */
    if (weechat_strcasecmp (argv[1], "default") == 0)
    {
        if ((argc >= 3) && (weechat_strcasecmp (argv[2], "-yes") == 0))
        {
            trigger_free_all ();
            trigger_create_default ();
            trigger_command_list (_("Default triggers restored:"), 0);
        }
        else
        {
            weechat_printf (NULL,
                            _("%s%s: \"-yes\" argument is required for "
                              "restoring default triggers (security reason)"),
                            weechat_prefix ("error"), TRIGGER_PLUGIN_NAME);
        }
        goto end;
    }

    /* open the trigger monitor buffer */
    if (weechat_strcasecmp (argv[1], "monitor") == 0)
    {
        trigger_buffer_open ((argc > 2) ? argv_eol[2] : NULL, 1);
        goto end;
    }

error:
    rc = WEECHAT_RC_ERROR;

end:
    if (sargv)
        weechat_string_free_split (sargv);

    return rc;
}
Ejemplo n.º 23
0
void
xfer_dcc_send_file_child (struct t_xfer *xfer)
{
    int num_read, num_sent, blocksize;
    static char buffer[XFER_BLOCKSIZE_MAX];
    uint32_t ack;
    time_t last_sent, new_time, last_second;
    long sent_last_second;
    
    blocksize = xfer->blocksize;
    if (weechat_config_integer (xfer_config_network_speed_limit) > 0)
    {
        if (blocksize > weechat_config_integer (xfer_config_network_speed_limit) * 1024)
            blocksize = weechat_config_integer (xfer_config_network_speed_limit) * 1024;
    }
    
    last_sent = time (NULL);
    last_second = time (NULL);
    sent_last_second = 0;
    while (1)
    {
        /* read DCC ACK (sent by receiver) */
        if (xfer->pos > xfer->ack)
        {
            /* we should receive ACK for packets sent previously */
            while (1)
            {
                num_read = recv (xfer->sock, (char *) &ack, 4, MSG_PEEK);
                if ((num_read < 1) &&
                    ((num_read != -1) || (errno != EAGAIN)))
                {
                    xfer_network_write_pipe (xfer, XFER_STATUS_FAILED,
                                             XFER_ERROR_SEND_BLOCK);
                    return;
                }
                if (num_read == 4)
                {
                    recv (xfer->sock, (char *) &ack, 4, 0);
                    xfer->ack = ntohl (ack);
                    
                    /* DCC send ok? */
                    if ((xfer->pos >= xfer->size)
                        && (xfer->ack >= xfer->size))
                    {
                        xfer_network_write_pipe (xfer, XFER_STATUS_DONE,
                                                 XFER_NO_ERROR);
                        return;
                    }
                }
                else
                    break;
            }
        }
        
        /* send a block to receiver */
        if ((xfer->pos < xfer->size) &&
             (xfer->fast_send || (xfer->pos <= xfer->ack)))
        {
            if ((weechat_config_integer (xfer_config_network_speed_limit) > 0)
                && (sent_last_second >= weechat_config_integer (xfer_config_network_speed_limit) * 1024))
            {
                /* we're sending too fast (according to speed limit set by user) */
                usleep (100);
            }
            else
            {
                lseek (xfer->file, xfer->pos, SEEK_SET);
                num_read = read (xfer->file, buffer, blocksize);
                if (num_read < 1)
                {
                    xfer_network_write_pipe (xfer, XFER_STATUS_FAILED,
                                             XFER_ERROR_READ_LOCAL);
                    return;
                }
                num_sent = send (xfer->sock, buffer, num_read, 0);
                if (num_sent < 0)
                {
                    /* socket is temporarily not available (receiver can't receive
                       amount of data we sent ?!) */
                    if (errno == EAGAIN)
                        usleep (1000);
                    else
                    {
                        xfer_network_write_pipe (xfer, XFER_STATUS_FAILED,
                                                 XFER_ERROR_SEND_BLOCK);
                        return;
                    }
                }
                if (num_sent > 0)
                {
                    xfer->pos += (unsigned long) num_sent;
                    sent_last_second += (unsigned long) num_sent;
                    new_time = time (NULL);
                    if (last_sent != new_time)
                    {
                        last_sent = new_time;
                        xfer_network_write_pipe (xfer, XFER_STATUS_ACTIVE,
                                                 XFER_NO_ERROR);
                    }
                }
            }
        }
        else
            usleep (1000);
        
        if (time (NULL) > last_second)
        {
            last_second = time (NULL);
            sent_last_second = 0;
        }
    }
}
Ejemplo n.º 24
0
void
trigger_callback_replace_regex (struct t_trigger *trigger,
                                struct t_hashtable *pointers,
                                struct t_hashtable *extra_vars,
                                int display_monitor)
{
    char *value;
    const char *ptr_key, *ptr_value;
    int i, pointers_allocated;

    pointers_allocated = 0;

    if (trigger->regex_count == 0)
        return;

    if (!pointers)
    {
        pointers = weechat_hashtable_new (32,
                                          WEECHAT_HASHTABLE_STRING,
                                          WEECHAT_HASHTABLE_POINTER,
                                          NULL,
                                          NULL);
        if (!pointers)
            return;
        pointers_allocated = 1;
    }

    for (i = 0; i < trigger->regex_count; i++)
    {
        /* if regex is not set (invalid), skip it */
        if (!trigger->regex[i].regex)
            continue;

        ptr_key = (trigger->regex[i].variable) ?
            trigger->regex[i].variable :
            trigger_hook_regex_default_var[weechat_config_integer (trigger->options[TRIGGER_OPTION_HOOK])];
        if (!ptr_key || !ptr_key[0])
        {
            if (trigger_buffer && display_monitor)
            {
                weechat_printf_tags (trigger_buffer, "no_trigger",
                                     "\t  regex %d: %s",
                                     i + 1, _("no variable"));
            }
            continue;
        }

        ptr_value = weechat_hashtable_get (extra_vars, ptr_key);
        if (!ptr_value)
        {
            if (trigger_buffer && display_monitor)
            {
                weechat_printf_tags (trigger_buffer, "no_trigger",
                                     "\t  regex %d (%s): %s",
                                     i + 1, ptr_key, _("empty variable"));
            }
            continue;
        }

        weechat_hashtable_set (pointers, "regex", trigger->regex[i].regex);
        weechat_hashtable_set (trigger_callback_hashtable_options_regex,
                               "regex_replace",
                               trigger->regex[i].replace_escaped);

        value = weechat_string_eval_expression (
            ptr_value,
            pointers,
            extra_vars,
            trigger_callback_hashtable_options_regex);

        if (value)
        {
            /* display debug info on trigger buffer */
            if (trigger_buffer && display_monitor)
            {
                weechat_printf_tags (trigger_buffer, "no_trigger",
                                     "\t  regex %d %s(%s%s%s)%s: "
                                     "%s\"%s%s%s\"",
                                     i + 1,
                                     weechat_color ("chat_delimiters"),
                                     weechat_color ("reset"),
                                     ptr_key,
                                     weechat_color ("chat_delimiters"),
                                     weechat_color ("reset"),
                                     weechat_color ("chat_delimiters"),
                                     weechat_color ("reset"),
                                     value,
                                     weechat_color ("chat_delimiters"));
            }
            weechat_hashtable_set (extra_vars, ptr_key, value);
            free (value);
        }
    }

    if (pointers_allocated)
        weechat_hashtable_free (pointers);
    else
        weechat_hashtable_remove (pointers, "regex");
}
Ejemplo n.º 25
0
void
relay_weechat_msg_send (struct t_relay_client *client,
                        struct t_relay_weechat_msg *msg)
{
    uint32_t size32;
    char compression, raw_message[1024];
    int rc;
    Bytef *dest;
    uLongf dest_size;
    struct timeval tv1, tv2;
    long time_diff;

    if (weechat_config_integer (relay_config_network_compression_level) > 0)
    {
        switch (RELAY_WEECHAT_DATA(client, compression))
        {
            case RELAY_WEECHAT_COMPRESSION_ZLIB:
                dest_size = compressBound (msg->data_size - 5);
                dest = malloc (dest_size + 5);
                if (dest)
                {
                    gettimeofday (&tv1, NULL);
                    rc = compress2 (dest + 5, &dest_size,
                                    (Bytef *)(msg->data + 5), msg->data_size - 5,
                                    weechat_config_integer (relay_config_network_compression_level));
                    gettimeofday (&tv2, NULL);
                    time_diff = weechat_util_timeval_diff (&tv1, &tv2);
                    if ((rc == Z_OK) && ((int)dest_size + 5 < msg->data_size))
                    {
                        /* set size and compression flag */
                        size32 = htonl ((uint32_t)(dest_size + 5));
                        memcpy (dest, &size32, 4);
                        dest[4] = RELAY_WEECHAT_COMPRESSION_ZLIB;

                        /* display message in raw buffer */
                        snprintf (raw_message, sizeof (raw_message),
                                  "obj: %d/%d bytes (%d%%, %ldms), id: %s",
                                  (int)dest_size + 5,
                                  msg->data_size,
                                  100 - ((((int)dest_size + 5) * 100) / msg->data_size),
                                  time_diff,
                                  msg->id);

                        /* send compressed data */
                        relay_client_send (client, (const char *)dest, dest_size + 5,
                                           raw_message);

                        free (dest);
                        return;
                    }
                    free (dest);
                }
                break;
            default:
                break;
        }
    }

    /* compression failed (or not asked), send uncompressed message */

    /* set size and compression flag */
    size32 = htonl ((uint32_t)msg->data_size);
    relay_weechat_msg_set_bytes (msg, 0, &size32, 4);
    compression = RELAY_WEECHAT_COMPRESSION_OFF;
    relay_weechat_msg_set_bytes (msg, 4, &compression, 1);

    /* send uncompressed data */
    snprintf (raw_message, sizeof (raw_message),
              "obj: %d bytes, id: %s", msg->data_size, msg->id);
    relay_client_send (client, msg->data, msg->data_size, raw_message);
}
Ejemplo n.º 26
0
char *
weechat_aspell_modifier_cb (void *data, const char *modifier,
                            const char *modifier_data, const char *string)
{
    long unsigned int value;
    struct t_gui_buffer *buffer;
    struct t_aspell_speller_buffer *ptr_speller_buffer;
    char *result, *ptr_string, *pos_space, *ptr_end, *ptr_end_valid, save_end;
    char *word_for_suggestions, *old_suggestions, *suggestions;
    char *word_and_suggestions;
    const char *color_normal, *color_error, *ptr_suggestions;
    int utf8_char_int, char_size;
    int length, index_result, length_word, word_ok;
    int length_color_normal, length_color_error, rc;
    int input_pos, current_pos, word_start_pos, word_end_pos, word_end_pos_valid;

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

    if (!aspell_enabled)
        return NULL;

    if (!string)
        return NULL;

    rc = sscanf (modifier_data, "%lx", &value);
    if ((rc == EOF) || (rc == 0))
        return NULL;

    buffer = (struct t_gui_buffer *)value;

    /* check text during search only if option is enabled */
    if (weechat_buffer_get_integer (buffer, "text_search")
        && !weechat_config_boolean (weechat_aspell_config_check_during_search))
        return NULL;

    /* get structure with speller info for buffer */
    ptr_speller_buffer = weechat_hashtable_get (weechat_aspell_speller_buffer,
                                                buffer);
    if (!ptr_speller_buffer)
    {
        ptr_speller_buffer = weechat_aspell_speller_buffer_new (buffer);
        if (!ptr_speller_buffer)
            return NULL;
    }
    if (!ptr_speller_buffer->spellers)
        return NULL;

    /*
     * for performance: return last string built if input string is the
     * same (and cursor position is the same, if suggestions are enabled)
     */
    input_pos = weechat_buffer_get_integer (buffer, "input_pos");
    if (ptr_speller_buffer->modifier_string
        && (strcmp (string, ptr_speller_buffer->modifier_string) == 0)
        && ((weechat_config_integer (weechat_aspell_config_check_suggestions) < 0)
            || (input_pos == ptr_speller_buffer->input_pos)))
    {
        return (ptr_speller_buffer->modifier_result) ?
            strdup (ptr_speller_buffer->modifier_result) : NULL;
    }

    /* free last modifier string and result */
    if (ptr_speller_buffer->modifier_string)
    {
        free (ptr_speller_buffer->modifier_string);
        ptr_speller_buffer->modifier_string = NULL;
    }
    if (ptr_speller_buffer->modifier_result)
    {
        free (ptr_speller_buffer->modifier_result);
        ptr_speller_buffer->modifier_result = NULL;
    }

    word_for_suggestions = NULL;

    /* save last modifier string received */
    ptr_speller_buffer->modifier_string = strdup (string);
    ptr_speller_buffer->input_pos = input_pos;

    color_normal = weechat_color ("bar_fg");
    length_color_normal = strlen (color_normal);
    color_error = weechat_color (weechat_config_string (weechat_aspell_config_color_misspelled));
    length_color_error = strlen (color_error);

    length = strlen (string);
    result = malloc (length + (length * length_color_error) + 1);

    if (result)
    {
        result[0] = '\0';

        ptr_string = ptr_speller_buffer->modifier_string;
        index_result = 0;

        /* check if string is a command */
        if (!weechat_string_input_for_buffer (ptr_string))
        {
            char_size = weechat_utf8_char_size (ptr_string);
            ptr_string += char_size;
            pos_space = ptr_string;
            while (pos_space && pos_space[0] && (pos_space[0] != ' '))
            {
                pos_space = weechat_utf8_next_char (pos_space);
            }
            if (!pos_space || !pos_space[0])
            {
                free (result);
                return NULL;
            }

            pos_space[0] = '\0';

            /* exit if command is not authorized for spell checking */
            if (!weechat_aspell_command_authorized (ptr_string))
            {
                free (result);
                return NULL;
            }
            memcpy (result + index_result,
                    ptr_speller_buffer->modifier_string,
                    char_size);
            index_result += char_size;
            strcpy (result + index_result, ptr_string);
            index_result += strlen (ptr_string);

            pos_space[0] = ' ';
            ptr_string = pos_space;
        }

        current_pos = 0;
        while (ptr_string[0])
        {
            /* find start of word: it must start with an alphanumeric char */
            utf8_char_int = weechat_utf8_char_int (ptr_string);
            while ((!iswalnum (utf8_char_int)) || iswspace (utf8_char_int))
            {
                char_size = weechat_utf8_char_size (ptr_string);
                memcpy (result + index_result, ptr_string, char_size);
                index_result += char_size;
                ptr_string += char_size;
                current_pos++;
                if (!ptr_string[0])
                    break;
                utf8_char_int = weechat_utf8_char_int (ptr_string);
            }
            if (!ptr_string[0])
                break;

            word_start_pos = current_pos;
            word_end_pos = current_pos;
            word_end_pos_valid = current_pos;

            /* find end of word: ' and - allowed in word, but not at the end */
            ptr_end_valid = ptr_string;
            ptr_end = weechat_utf8_next_char (ptr_string);
            utf8_char_int = weechat_utf8_char_int (ptr_end);
            while (iswalnum (utf8_char_int) || (utf8_char_int == '\'')
                   || (utf8_char_int == '-'))
            {
                word_end_pos++;
                if (iswalnum (utf8_char_int))
                {
                    /* pointer to last alphanumeric char in the word */
                    ptr_end_valid = ptr_end;
                    word_end_pos_valid = word_end_pos;
                }
                ptr_end = weechat_utf8_next_char (ptr_end);
                if (!ptr_end[0])
                    break;
                utf8_char_int = weechat_utf8_char_int (ptr_end);
            }
            ptr_end = weechat_utf8_next_char (ptr_end_valid);
            word_end_pos = word_end_pos_valid;
            word_ok = 0;
            if (weechat_aspell_string_is_url (ptr_string))
            {
                /*
                 * word is an URL, then it is OK, and search for next space
                 * (will be end of word)
                 */
                word_ok = 1;
                if (ptr_end[0])
                {
                    utf8_char_int = weechat_utf8_char_int (ptr_end);
                    while (!iswspace (utf8_char_int))
                    {
                        ptr_end = weechat_utf8_next_char (ptr_end);
                        if (!ptr_end[0])
                            break;
                        utf8_char_int = weechat_utf8_char_int (ptr_end);
                    }
                }
            }
            save_end = ptr_end[0];
            ptr_end[0] = '\0';
            length_word = ptr_end - ptr_string;

            if (!word_ok)
            {
                if ((save_end != '\0')
                    || (weechat_config_integer (weechat_aspell_config_check_real_time)))
                {
                    word_ok = weechat_aspell_check_word (buffer,
                                                         ptr_speller_buffer,
                                                         ptr_string);
                    if (!word_ok && (input_pos >= word_start_pos))
                    {
                        /*
                         * if word is misspelled and that cursor is after
                         * the beginning of this word, save the word (we will
                         * look for suggestions after this loop)
                         */
                        if (word_for_suggestions)
                            free (word_for_suggestions);
                        word_for_suggestions = strdup (ptr_string);
                    }
                }
                else
                    word_ok = 1;
            }

            /* add error color */
            if (!word_ok)
            {
                strcpy (result + index_result, color_error);
                index_result += length_color_error;
            }

            /* add word */
            strcpy (result + index_result, ptr_string);
            index_result += length_word;

            /* add normal color (after misspelled word) */
            if (!word_ok)
            {
                strcpy (result + index_result, color_normal);
                index_result += length_color_normal;
            }

            if (save_end == '\0')
                break;

            ptr_end[0] = save_end;
            ptr_string = ptr_end;
            current_pos = word_end_pos + 1;
        }
        result[index_result] = '\0';
    }

    /* save old suggestions in buffer */
    ptr_suggestions = weechat_buffer_get_string (buffer,
                                                 "localvar_aspell_suggest");
    old_suggestions = (ptr_suggestions) ? strdup (ptr_suggestions) : NULL;

    /* if there is a misspelled word, get suggestions and set them in buffer */
    if (word_for_suggestions)
    {
        suggestions = weechat_aspell_get_suggestions (ptr_speller_buffer,
                                                      word_for_suggestions);
        if (suggestions)
        {
            length = strlen (word_for_suggestions) + 1 /* ":" */
                + strlen (suggestions) + 1;
            word_and_suggestions = malloc (length);
            if (word_and_suggestions)
            {
                snprintf (word_and_suggestions, length, "%s:%s",
                          word_for_suggestions, suggestions);
                weechat_buffer_set (buffer, "localvar_set_aspell_suggest",
                                    word_and_suggestions);
                free (word_and_suggestions);
            }
            else
            {
                weechat_buffer_set (buffer, "localvar_del_aspell_suggest", "");
            }
            free (suggestions);
        }
        else
        {
            weechat_buffer_set (buffer, "localvar_del_aspell_suggest", "");
        }
        free (word_for_suggestions);
    }
    else
    {
        weechat_buffer_set (buffer, "localvar_del_aspell_suggest", "");
    }

    /*
     * if suggestions have changed, update the bar item
     * and send signal "aspell_suggest"
     */
    ptr_suggestions = weechat_buffer_get_string (buffer,
                                                 "localvar_aspell_suggest");
    if ((old_suggestions && !ptr_suggestions)
        || (!old_suggestions && ptr_suggestions)
        || (old_suggestions && ptr_suggestions
            && (strcmp (old_suggestions, ptr_suggestions) != 0)))
    {
        weechat_bar_item_update ("aspell_suggest");
        weechat_hook_signal_send ("aspell_suggest",
                                  WEECHAT_HOOK_SIGNAL_POINTER, buffer);
    }
    if (old_suggestions)
        free (old_suggestions);

    if (!result)
        return NULL;

    ptr_speller_buffer->modifier_result = strdup (result);

    return result;
}
Ejemplo n.º 27
0
char *
weechat_aspell_get_suggestions (struct t_aspell_speller_buffer *speller_buffer,
                                const char *word)
{
    int i, size, max_suggestions, num_suggestions;
    char *suggestions, *suggestions2;
    const char *ptr_word;
#ifdef USE_ENCHANT
    char **elements;
    size_t num_elements;
#else
    const AspellWordList *list;
    AspellStringEnumeration *elements;
#endif

    max_suggestions = weechat_config_integer (weechat_aspell_config_check_suggestions);
    if (max_suggestions < 0)
        return NULL;

    size = 1;
    suggestions = malloc (size);
    if (!suggestions)
        return NULL;

    suggestions[0] = '\0';
    if (speller_buffer->spellers)
    {
        for (i = 0; speller_buffer->spellers[i]; i++)
        {
#ifdef USE_ENCHANT
            elements = enchant_dict_suggest (speller_buffer->spellers[i], word,
                                             -1, &num_elements);
            if (elements)
            {
                if (num_elements > 0)
                {
                    num_suggestions = 0;
                    while ((ptr_word = elements[num_suggestions]) != NULL)
                    {
                        size += strlen (ptr_word) + ((suggestions[0]) ? 1 : 0);
                        suggestions2 = realloc (suggestions, size);
                        if (!suggestions2)
                        {
                            free (suggestions);
                            enchant_dict_free_string_list (speller_buffer->spellers[i],
                                                           elements);
                            return NULL;
                        }
                        suggestions = suggestions2;
                        if (suggestions[0])
                            strcat (suggestions, (num_suggestions == 0) ? "/" : ",");
                        strcat (suggestions, ptr_word);
                        num_suggestions++;
                        if ((max_suggestions >= 0) && (num_suggestions == max_suggestions))
                            break;
                    }
                }
                enchant_dict_free_string_list (speller_buffer->spellers[i], elements);
            }
#else
            list = aspell_speller_suggest (speller_buffer->spellers[i], word, -1);
            if (list)
            {
                elements = aspell_word_list_elements (list);
                num_suggestions = 0;
                while ((ptr_word = aspell_string_enumeration_next (elements)) != NULL)
                {
                    size += strlen (ptr_word) + ((suggestions[0]) ? 1 : 0);
                    suggestions2 = realloc (suggestions, size);
                    if (!suggestions2)
                    {
                        free (suggestions);
                        delete_aspell_string_enumeration (elements);
                        return NULL;
                    }
                    suggestions = suggestions2;
                    if (suggestions[0])
                        strcat (suggestions, (num_suggestions == 0) ? "/" : ",");
                    strcat (suggestions, ptr_word);
                    num_suggestions++;
                    if ((max_suggestions >= 0) && (num_suggestions == max_suggestions))
                        break;
                }
                delete_aspell_string_enumeration (elements);
            }
#endif
        }
    }

    /* no suggestions found */
    if (!suggestions[0])
    {
        free (suggestions);
        return NULL;
    }

    return suggestions;
}
Ejemplo n.º 28
0
void
trigger_print_log ()
{
    struct t_trigger *ptr_trigger;
    int i;

    for (ptr_trigger = triggers; ptr_trigger;
         ptr_trigger = ptr_trigger->next_trigger)
    {
        weechat_log_printf ("");
        weechat_log_printf ("[trigger (addr:0x%lx)]", ptr_trigger);
        weechat_log_printf ("  name. . . . . . . . . . : '%s'",  ptr_trigger->name);
        weechat_log_printf ("  enabled . . . . . . . . : %d",
                            weechat_config_integer (ptr_trigger->options[TRIGGER_OPTION_ENABLED]));
        weechat_log_printf ("  hook . .  . . . . . . . : %d ('%s')",
                            weechat_config_integer (ptr_trigger->options[TRIGGER_OPTION_HOOK]),
                            trigger_hook_type_string[weechat_config_integer (ptr_trigger->options[TRIGGER_OPTION_HOOK])]);
        weechat_log_printf ("  arguments . . . . . . . : '%s'",
                            weechat_config_string (ptr_trigger->options[TRIGGER_OPTION_ARGUMENTS]));
        weechat_log_printf ("  conditions. . . . . . . : '%s'",
                            weechat_config_string (ptr_trigger->options[TRIGGER_OPTION_CONDITIONS]));
        weechat_log_printf ("  regex . . . . . . . . . : '%s'",
                            weechat_config_string (ptr_trigger->options[TRIGGER_OPTION_REGEX]));
        weechat_log_printf ("  command . . . . . . . . : '%s'",
                            weechat_config_string (ptr_trigger->options[TRIGGER_OPTION_COMMAND]));
        weechat_log_printf ("  return_code . . . . . . : %d ('%s')",
                            weechat_config_integer (ptr_trigger->options[TRIGGER_OPTION_RETURN_CODE]),
                            trigger_return_code_string[weechat_config_integer (ptr_trigger->options[TRIGGER_OPTION_RETURN_CODE])]);
        weechat_log_printf ("  hooks_count . . . . . . : %d",    ptr_trigger->hooks_count);
        weechat_log_printf ("  hooks . . . . . . . . . : 0x%lx", ptr_trigger->hooks);
        for (i = 0; i < ptr_trigger->hooks_count; i++)
        {
            weechat_log_printf ("    hooks[%03d]. . . . . . : 0x%lx",
                                i, ptr_trigger->hooks[i]);
        }
        weechat_log_printf ("  hook_count_cb . . . . . : %lu",   ptr_trigger->hook_count_cb);
        weechat_log_printf ("  hook_count_cmd. . . . . : %lu",   ptr_trigger->hook_count_cmd);
        weechat_log_printf ("  hook_running. . . . . . : %d",    ptr_trigger->hook_running);
        weechat_log_printf ("  hook_print_buffers. . . : '%s'",  ptr_trigger->hook_print_buffers);
        weechat_log_printf ("  regex_count . . . . . . : %d",    ptr_trigger->regex_count);
        weechat_log_printf ("  regex . . . . . . . . . : 0x%lx", ptr_trigger->regex);
        for (i = 0; i < ptr_trigger->regex_count; i++)
        {
            weechat_log_printf ("    regex[%03d].variable . . . : '%s'",
                                i, ptr_trigger->regex[i].variable);
            weechat_log_printf ("    regex[%03d].str_regex. . . : '%s'",
                                i, ptr_trigger->regex[i].str_regex);
            weechat_log_printf ("    regex[%03d].regex. . . . . : 0x%lx",
                                i, ptr_trigger->regex[i].regex);
            weechat_log_printf ("    regex[%03d].replace. . . . : '%s'",
                                i, ptr_trigger->regex[i].replace);
            weechat_log_printf ("    regex[%03d].replace_escaped: '%s'",
                                i, ptr_trigger->regex[i].replace_escaped);
        }
        weechat_log_printf ("  commands_count. . . . . : %d",    ptr_trigger->commands_count);
        weechat_log_printf ("  commands. . . . . . . . : 0x%lx", ptr_trigger->commands);
        if (ptr_trigger->commands)
        {
            for (i = 0; ptr_trigger->commands[i]; i++)
            {
                weechat_log_printf ("    commands[%03d] . . . . : '%s'",
                                    i, ptr_trigger->commands[i]);
            }
        }
        weechat_log_printf ("  prev_trigger. . . . . . : 0x%lx", ptr_trigger->prev_trigger);
        weechat_log_printf ("  next_trigger. . . . . . : 0x%lx", ptr_trigger->next_trigger);
    }
}
Ejemplo n.º 29
0
void
trigger_hook (struct t_trigger *trigger)
{
    char **argv, **argv_eol, *tags, *message, *error1, *error2, *error3;
    int i, argc, strip_colors;
    long interval, align_second, max_calls;

    trigger_unhook (trigger);

    argv = weechat_string_split (weechat_config_string (trigger->options[TRIGGER_OPTION_ARGUMENTS]),
                                 ";", 0, 0, &argc);
    argv_eol = weechat_string_split (weechat_config_string (trigger->options[TRIGGER_OPTION_ARGUMENTS]),
                                     ";", 1, 0, NULL);

    switch (weechat_config_integer (trigger->options[TRIGGER_OPTION_HOOK]))
    {
        case TRIGGER_HOOK_SIGNAL:
            if (argv && (argc >= 1))
            {
                trigger->hooks = malloc (argc * sizeof (trigger->hooks[0]));
                if (trigger->hooks)
                {
                    trigger->hooks_count = argc;
                    for (i = 0; i < argc; i++)
                    {
                        trigger->hooks[i] = weechat_hook_signal (
                            argv[i],
                            &trigger_callback_signal_cb,
                            trigger);
                    }
                }
            }
            break;
        case TRIGGER_HOOK_HSIGNAL:
            if (argv && (argc >= 1))
            {
                trigger->hooks = malloc (argc * sizeof (trigger->hooks[0]));
                if (trigger->hooks)
                {
                    trigger->hooks_count = argc;
                    for (i = 0; i < argc; i++)
                    {
                        trigger->hooks[i] = weechat_hook_hsignal (
                            argv[i],
                            &trigger_callback_hsignal_cb,
                            trigger);
                    }
                }
            }
            break;
        case TRIGGER_HOOK_MODIFIER:
            if (argv && (argc >= 1))
            {
                trigger->hooks = malloc (argc * sizeof (trigger->hooks[0]));
                if (trigger->hooks)
                {
                    trigger->hooks_count = argc;
                    for (i = 0; i < argc; i++)
                    {
                        trigger->hooks[i] = weechat_hook_modifier (
                            argv[i],
                            &trigger_callback_modifier_cb,
                            trigger);
                    }
                }
            }
            break;
        case TRIGGER_HOOK_PRINT:
            tags = NULL;
            message = NULL;
            strip_colors = 0;
            if (argv && (argc >= 1))
            {
                if (strcmp (argv[0], "*") != 0)
                    trigger->hook_print_buffers = strdup (argv[0]);
                if ((argc >= 2) && (strcmp (argv[1], "*") != 0))
                    tags = argv[1];
                if ((argc >= 3) && (strcmp (argv[2], "*") != 0))
                    message = argv[2];
                if (argc >= 4)
                    strip_colors = (strcmp (argv[3], "0") != 0) ? 1 : 0;
            }
            trigger->hooks = malloc (sizeof (trigger->hooks[0]));
            if (trigger->hooks)
            {
                trigger->hooks_count = 1;
                trigger->hooks[0] = weechat_hook_print (
                    NULL,
                    tags,
                    message,
                    strip_colors,
                    &trigger_callback_print_cb,
                    trigger);
            }
            break;
        case TRIGGER_HOOK_COMMAND:
            if (argv && (argc >= 1))
            {
                trigger->hooks = malloc (sizeof (trigger->hooks[0]));
                if (trigger->hooks)
                {
                    trigger->hooks_count = 1;
                    trigger->hooks[0] = weechat_hook_command (
                        argv[0],  /* command */
                        (argc > 1) ? argv[1] : "",  /* description */
                        (argc > 2) ? argv[2] : "",  /* arguments */
                        (argc > 3) ? argv[3] : "",  /* description of args */
                        (argc > 4) ? argv[4] : "",  /* completion */
                        &trigger_callback_command_cb,
                        trigger);
                }
            }
            break;
        case TRIGGER_HOOK_COMMAND_RUN:
            if (argv && (argc >= 1))
            {
                trigger->hooks = malloc (argc * sizeof (trigger->hooks[0]));
                if (trigger->hooks)
                {
                    trigger->hooks_count = argc;
                    for (i = 0; i < argc; i++)
                    {
                        trigger->hooks[i] = weechat_hook_command_run (
                            argv[i],
                            &trigger_callback_command_run_cb,
                            trigger);
                    }
                }
            }
            break;
        case TRIGGER_HOOK_TIMER:
            if (argv && (argc >= 1))
            {
                error1 = NULL;
                error2 = NULL;
                error3 = NULL;
                interval = strtol (argv[0], &error1, 10);
                align_second = strtol ((argc >= 2) ? argv[1] : "0", &error2, 10);
                max_calls = strtol ((argc >= 3) ? argv[2] : "0", &error3, 10);
                if (error1 && !error1[0]
                    && error2 && !error2[0]
                    && error3 && !error3[0]
                    && (interval > 0)
                    && (align_second >= 0)
                    && (max_calls >= 0))
                {
                    trigger->hooks = malloc (sizeof (trigger->hooks[0]));
                    if (trigger->hooks)
                    {
                        trigger->hooks_count = 1;
                        trigger->hooks[0] = weechat_hook_timer (
                            interval,
                            (int)align_second,
                            (int)max_calls,
                            &trigger_callback_timer_cb,
                            trigger);
                    }
                }
            }
            break;
        case TRIGGER_HOOK_CONFIG:
            if (argv && (argc >= 1))
            {
                trigger->hooks = malloc (argc * sizeof (trigger->hooks[0]));
                if (trigger->hooks)
                {
                    trigger->hooks_count = argc;
                    for (i = 0; i < argc; i++)
                    {
                        trigger->hooks[i] = weechat_hook_config (
                            argv[i],
                            &trigger_callback_config_cb,
                            trigger);
                    }
                }
            }
            break;
        case TRIGGER_HOOK_FOCUS:
            if (argv && (argc >= 1))
            {
                trigger->hooks = malloc (argc * sizeof (trigger->hooks[0]));
                if (trigger->hooks)
                {
                    trigger->hooks_count = argc;
                    for (i = 0; i < argc; i++)
                    {
                        trigger->hooks[i] = weechat_hook_focus (
                            argv[i],
                            &trigger_callback_focus_cb,
                            trigger);
                    }
                }
            }
            break;
    }

    if (!trigger->hooks)
    {
        weechat_printf (NULL,
                        _("%s%s: unable to create hook for trigger \"%s\" "
                          "(bad arguments)"),
                        weechat_prefix ("error"), TRIGGER_PLUGIN_NAME,
                        trigger->name);
    }

    if (argv)
        weechat_string_free_split (argv);
    if (argv_eol)
        weechat_string_free_split (argv_eol);
}
Ejemplo n.º 30
0
void
exec_end_command (struct t_exec_cmd *exec_cmd, int return_code)
{
    struct t_gui_buffer *ptr_buffer;
    struct t_hashtable *hashtable;
    char str_number[32], *output;
    int i, buffer_type;

    if (exec_cmd->hsignal)
    {
        hashtable = weechat_hashtable_new (32,
                                           WEECHAT_HASHTABLE_STRING,
                                           WEECHAT_HASHTABLE_STRING,
                                           NULL, NULL);
        if (hashtable)
        {
            weechat_hashtable_set (hashtable, "command", exec_cmd->command);
            snprintf (str_number, sizeof (str_number), "%d", exec_cmd->number);
            weechat_hashtable_set (hashtable, "number", str_number);
            weechat_hashtable_set (hashtable, "name", exec_cmd->name);
            output = exec_decode_color (exec_cmd, exec_cmd->output[EXEC_STDOUT]);
            weechat_hashtable_set (hashtable, "out", output);
            if (output)
                free (output);
            output = exec_decode_color (exec_cmd, exec_cmd->output[EXEC_STDERR]);
            weechat_hashtable_set (hashtable, "err", output);
            if (output)
                free (output);
            snprintf (str_number, sizeof (str_number), "%d", return_code);
            weechat_hashtable_set (hashtable, "rc", str_number);
            weechat_hook_hsignal_send (exec_cmd->hsignal, hashtable);
            weechat_hashtable_free (hashtable);
        }
    }
    else
    {
        ptr_buffer = weechat_buffer_search ("==", exec_cmd->buffer_full_name);

        /* display the last line of output (if not ending with '\n') */
        exec_display_line (exec_cmd, ptr_buffer, EXEC_STDOUT,
                           exec_cmd->output[EXEC_STDOUT]);
        exec_display_line (exec_cmd, ptr_buffer, EXEC_STDERR,
                           exec_cmd->output[EXEC_STDERR]);

        /*
         * display return code (only if command is not detached, if output is
         * NOT sent to buffer, and if command is not piped)
         */
        if (exec_cmd->display_rc
            && !exec_cmd->detached && !exec_cmd->output_to_buffer
            && !exec_cmd->pipe_command)
        {
            buffer_type = weechat_buffer_get_integer (ptr_buffer, "type");
            if (return_code >= 0)
            {
                if (buffer_type == 1)
                {
                    weechat_printf_y (ptr_buffer, -1,
                                      ("%s: end of command %d (\"%s\"), "
                                       "return code: %d"),
                                      EXEC_PLUGIN_NAME, exec_cmd->number,
                                      exec_cmd->command, return_code);
                }
                else
                {
                    weechat_printf_date_tags (
                        ptr_buffer, 0, "exec_rc",
                        _("%s: end of command %d (\"%s\"), "
                          "return code: %d"),
                        EXEC_PLUGIN_NAME, exec_cmd->number,
                        exec_cmd->command, return_code);
                }
            }
            else
            {
                if (buffer_type == 1)
                {
                    weechat_printf_y (ptr_buffer, -1,
                                      _("%s: unexpected end of command %d "
                                        "(\"%s\")"),
                                      EXEC_PLUGIN_NAME, exec_cmd->number,
                                      exec_cmd->command);
                }
                else
                {
                    weechat_printf_date_tags (
                        ptr_buffer, 0, "exec_rc",
                        _("%s: unexpected end of command %d "
                          "(\"%s\")"),
                        EXEC_PLUGIN_NAME, exec_cmd->number,
                        exec_cmd->command);
                }
            }
        }
    }

    /* (re)set some variables after the end of command */
    exec_cmd->hook = NULL;
    exec_cmd->pid = 0;
    exec_cmd->end_time = time (NULL);
    exec_cmd->return_code = return_code;
    for (i = 0; i < 2; i++)
    {
        if (exec_cmd->output[i])
        {
            free (exec_cmd->output[i]);
            exec_cmd->output[i] = NULL;
        }
        exec_cmd->output_size[i] = 0;
    }

    /* schedule a timer to remove the executed command */
    if (weechat_config_integer (exec_config_command_purge_delay) >= 0)
    {
        weechat_hook_timer (1 + (1000 * weechat_config_integer (exec_config_command_purge_delay)),
                            0, 1,
                            &exec_timer_delete_cb, exec_cmd, NULL);
    }
}