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--; }
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], ®ex_count, ®ex) < 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 (®ex_count, ®ex); if (commands) weechat_string_free_split (commands); }
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; }
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], ®ex_count, ®ex); trigger_regex_free (®ex_count, ®ex); 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; }