Пример #1
0
void
trigger_free (struct t_trigger *trigger)
{
    int i;

    if (!trigger)
        return;

    /* remove trigger from triggers list */
    if (trigger->prev_trigger)
        (trigger->prev_trigger)->next_trigger = trigger->next_trigger;
    if (trigger->next_trigger)
        (trigger->next_trigger)->prev_trigger = trigger->prev_trigger;
    if (triggers == trigger)
        triggers = trigger->next_trigger;
    if (last_trigger == trigger)
        last_trigger = trigger->prev_trigger;

    /* free data */
    trigger_unhook (trigger);
    trigger_regex_free (&trigger->regex_count, &trigger->regex);
    if (trigger->name)
        free (trigger->name);
    for (i = 0; i < TRIGGER_NUM_OPTIONS; i++)
    {
        if (trigger->options[i])
            weechat_config_option_free (trigger->options[i]);
    }
    if (trigger->commands)
        weechat_string_free_split (trigger->commands);

    free (trigger);

    triggers_count--;
}
Пример #2
0
void
trigger_command_list_default (int verbose)
{
    int i, regex_count, commands_count;
    struct t_trigger_regex *regex;
    char **commands;

    regex_count = 0;
    regex = NULL;
    commands_count = 0;
    commands = NULL;

    weechat_printf_date_tags (NULL, 0, "no_trigger", "");
    weechat_printf_date_tags (NULL, 0, "no_trigger",
                              _("List of default triggers:"));

    for (i = 0; trigger_config_default_list[i][0]; i++)
    {
        if (trigger_regex_split (trigger_config_default_list[i][5],
                                 &regex_count,
                                 &regex) < 0)
            continue;
        trigger_split_command (trigger_config_default_list[i][6],
                               &commands_count,
                               &commands);
        trigger_command_display_trigger_internal (
            trigger_config_default_list[i][0],
            weechat_config_string_to_boolean (trigger_config_default_list[i][1]),
            trigger_config_default_list[i][2],
            trigger_config_default_list[i][3],
            trigger_config_default_list[i][4],
            0,
            0,
            0,
            regex_count,
            regex,
            commands_count,
            commands,
            trigger_search_return_code (trigger_config_default_list[i][7]),
            verbose);
    }

    trigger_regex_free (&regex_count, &regex);
    if (commands)
        weechat_string_free_split (commands);
}
Пример #3
0
int
trigger_regex_split (const char *str_regex,
                     int *regex_count, struct t_trigger_regex **regex)
{
    const char *ptr_regex, *pos, *pos_replace, *pos_replace_end;
    const char *pos_next_regex;
    char *delimiter, *str_regex_escaped;
    int rc, index, length_delimiter;
    struct t_trigger_regex *new_regex;

    rc = 0;
    delimiter = NULL;
    str_regex_escaped = NULL;

    if (!regex_count || !regex)
        goto end;

    /* remove any existing regex */
    trigger_regex_free (regex_count, regex);

    if (!str_regex || !str_regex[0])
        goto end;

    /* min 3 chars, for example: "/a/" */
    if (strlen (str_regex) < 3)
        goto format_error;

    /* parse regular expressions in the option */
    ptr_regex = str_regex;
    while (ptr_regex && ptr_regex[0])
    {
        if (delimiter)
        {
            free (delimiter);
            delimiter = NULL;
        }

        /* search the delimiter (which can be more than one char) */
        pos = weechat_utf8_next_char (ptr_regex);
        while (pos[0] && (weechat_utf8_charcmp (ptr_regex, pos) == 0))
        {
            pos = weechat_utf8_next_char (pos);
        }
        if (!pos[0])
            goto format_error;
        delimiter = weechat_strndup (ptr_regex, pos - ptr_regex);
        if (!delimiter)
            goto memory_error;

        length_delimiter = strlen (delimiter);

        ptr_regex = pos;
        if (!ptr_regex[0])
            goto format_error;

        /* search the start of replacement string */
        pos_replace = strstr (ptr_regex, delimiter);
        if (!pos_replace)
            goto format_error;

        /* search the end of replacement string */
        pos_replace_end = strstr (pos_replace + length_delimiter, delimiter);

        new_regex = realloc (*regex,
                             (*regex_count + 1) * sizeof ((*regex)[0]));
        if (!new_regex)
            goto memory_error;

        *regex = new_regex;
        (*regex_count)++;
        index = *regex_count - 1;

        /* initialize new regex */
        (*regex)[index].variable = NULL;
        (*regex)[index].str_regex = NULL;
        (*regex)[index].regex = NULL;
        (*regex)[index].replace = NULL;
        (*regex)[index].replace_escaped = NULL;

        /* set string with regex */
        (*regex)[index].str_regex = weechat_strndup (ptr_regex,
                                                     pos_replace - ptr_regex);
        if (!(*regex)[index].str_regex)
            goto memory_error;
        str_regex_escaped = weechat_string_convert_escaped_chars ((*regex)[index].str_regex);
        if (!str_regex_escaped)
            goto memory_error;

        /* set regex */
        (*regex)[index].regex = malloc (sizeof (*(*regex)[index].regex));
        if (!(*regex)[index].regex)
            goto memory_error;
        if (weechat_string_regcomp ((*regex)[index].regex,
                                    str_regex_escaped,
                                    REG_EXTENDED | REG_ICASE) != 0)
        {
            free ((*regex)[index].regex);
            (*regex)[index].regex = NULL;
            goto compile_error;
        }

        /* set replace and replace_eval */
        (*regex)[index].replace = (pos_replace_end) ?
            weechat_strndup (pos_replace + length_delimiter,
                             pos_replace_end - pos_replace - length_delimiter) :
            strdup (pos_replace + length_delimiter);
        if (!(*regex)[index].replace)
            goto memory_error;
        (*regex)[index].replace_escaped =
            weechat_string_convert_escaped_chars ((*regex)[index].replace);
        if (!(*regex)[index].replace_escaped)
            goto memory_error;

        if (!pos_replace_end)
            break;

        /* set variable (optional) */
        ptr_regex = pos_replace_end + length_delimiter;
        if (!ptr_regex[0])
            break;
        if (ptr_regex[0] == ' ')
            pos_next_regex = ptr_regex;
        else
        {
            pos_next_regex = strchr (ptr_regex, ' ');
            (*regex)[index].variable = (pos_next_regex) ?
                weechat_strndup (ptr_regex, pos_next_regex - ptr_regex) :
                strdup (ptr_regex);
            if (!(*regex)[index].variable)
                goto memory_error;
        }
        if (!pos_next_regex)
            break;

        /* skip spaces before next regex */
        ptr_regex = pos_next_regex + 1;
        while (ptr_regex[0] == ' ')
        {
            ptr_regex++;
        }
    }

    goto end;

format_error:
    rc = -1;
    goto end;

compile_error:
    rc = -2;
    goto end;

memory_error:
    rc = -3;
    goto end;

end:
    if (delimiter)
        free (delimiter);
    if (str_regex_escaped)
        free (str_regex_escaped);
    if (rc < 0)
        trigger_regex_free (regex_count, regex);

    return rc;
}
Пример #4
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;
}