diff options
Diffstat (limited to 'src/plugins/trigger/trigger-config.c')
-rw-r--r-- | src/plugins/trigger/trigger-config.c | 692 |
1 files changed, 692 insertions, 0 deletions
diff --git a/src/plugins/trigger/trigger-config.c b/src/plugins/trigger/trigger-config.c new file mode 100644 index 000000000..a9cfe7e09 --- /dev/null +++ b/src/plugins/trigger/trigger-config.c @@ -0,0 +1,692 @@ +/* + * trigger-config.c - trigger configuration options (file trigger.conf) + * + * Copyright (C) 2014 Sébastien Helleu <flashcode@flashtux.org> + * + * This file is part of WeeChat, the extensible chat client. + * + * WeeChat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * WeeChat is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WeeChat. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "../weechat-plugin.h" +#include "trigger.h" +#include "trigger-config.h" + + +struct t_config_file *trigger_config_file = NULL; +struct t_config_section *trigger_config_section_trigger = NULL; + +/* trigger config, look section */ + +struct t_config_option *trigger_config_look_enabled; +struct t_config_option *trigger_config_look_monitor_strip_colors; + +/* trigger config, color section */ + +struct t_config_option *trigger_config_color_flag_command; +struct t_config_option *trigger_config_color_flag_conditions; +struct t_config_option *trigger_config_color_flag_regex; +struct t_config_option *trigger_config_color_flag_return_code; +struct t_config_option *trigger_config_color_regex; +struct t_config_option *trigger_config_color_replace; +struct t_config_option *trigger_config_color_trigger; +struct t_config_option *trigger_config_color_trigger_disabled; + +char *trigger_config_default_list[][1 + TRIGGER_NUM_OPTIONS] = +{ + /* beep on highlight/private message */ + { "beep", "on", + "print", + "", + "${tg_highlight} || ${tg_msg_pv}", + "", + "/print -stderr \\a", + "ok" }, + /* hide passwords in commands */ + { "cmd_pass", "on", + "modifier", + "5000|input_text_display;5000|history_add;5000|irc_command_auth", + "", + "==^(" + "(/(msg|quote) +nickserv " + "+(id|identify|register|ghost \\S+|release \\S+|regain \\S+) +)|" + "/oper +\\S+ +|" + "/quote pass +|" + "/set +\\S*password\\S* +|" + "/secure +(passphrase|decrypt|set \\S+) +)" + "(.*)" + "==$1$.*+", + "", + "" }, + /* hide password in IRC auth message displayed */ + { "msg_auth", "on", + "modifier", + "5000|irc_message_auth", + "", + "==^(.*(id|identify|register|ghost \\S+|release \\S+) +)(.*)==$1$.*+", + "", + "" }, + /* hide server password in commands /server and /connect */ + { "server_pass", "on", + "modifier", + "5000|input_text_display;5000|history_add", + "", + "==^(/(server|connect) .*-(sasl_)?password=)(\\S+)(.*)==$1$.*4$5" + "", + "" }, + { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }, +}; + + +/* + * Callback for changes on option "trigger.look.enabled". + */ + +void +trigger_config_change_enabled (void *data, struct t_config_option *option) +{ + /* make C compiler happy */ + (void) data; + + trigger_enabled = weechat_config_boolean (option); +} + +/* + * Callback for changes on option "trigger.trigger.xxx.enabled". + */ + +void +trigger_config_change_trigger_enabled (void *data, + struct t_config_option *option) +{ + struct t_trigger *ptr_trigger; + + /* make C compiler happy */ + (void) data; + + ptr_trigger = trigger_search_with_option (option); + if (!ptr_trigger) + return; + + if (weechat_config_boolean (option)) + trigger_hook (ptr_trigger); + else + trigger_unhook (ptr_trigger); +} + +/* + * Callback for changes on option "trigger.trigger.xxx.hook". + */ + +void +trigger_config_change_trigger_hook (void *data, struct t_config_option *option) +{ + struct t_trigger *ptr_trigger; + + /* make C compiler happy */ + (void) data; + + ptr_trigger = trigger_search_with_option (option); + if (!ptr_trigger) + return; + + if (ptr_trigger->options[TRIGGER_OPTION_ARGUMENTS]) + trigger_hook (ptr_trigger); +} + +/* + * Callback for changes on option "trigger.trigger.xxx.arguments". + */ + +void +trigger_config_change_trigger_arguments (void *data, + struct t_config_option *option) +{ + struct t_trigger *ptr_trigger; + + /* make C compiler happy */ + (void) data; + + ptr_trigger = trigger_search_with_option (option); + if (!ptr_trigger) + return; + + if (ptr_trigger->options[TRIGGER_OPTION_HOOK]) + trigger_hook (ptr_trigger); +} + +/* + * Callback for changes on option "trigger.trigger.xxx.regex". + */ + +void +trigger_config_change_trigger_regex (void *data, struct t_config_option *option) +{ + struct t_trigger *ptr_trigger; + + /* make C compiler happy */ + (void) data; + + ptr_trigger = trigger_search_with_option (option); + if (!ptr_trigger) + return; + + trigger_split_regex (ptr_trigger->name, weechat_config_string (option), + &ptr_trigger->regex_count, &ptr_trigger->regex); +} + +/* + * Callback for changes on option "trigger.trigger.xxx.command". + */ + +void +trigger_config_change_trigger_command (void *data, + struct t_config_option *option) +{ + struct t_trigger *ptr_trigger; + + /* make C compiler happy */ + (void) data; + + ptr_trigger = trigger_search_with_option (option); + if (!ptr_trigger) + return; + + trigger_split_command (weechat_config_string (option), + &ptr_trigger->commands_count, + &ptr_trigger->commands); +} + +/* + * Creates an option for a trigger. + * + * Returns pointer to new option, NULL if error. + */ + +struct t_config_option * +trigger_config_create_trigger_option (const char *trigger_name, int index_option, + const char *value) +{ + struct t_config_option *ptr_option; + int length; + char *option_name; + + ptr_option = NULL; + + length = strlen (trigger_name) + 1 + + strlen (trigger_option_string[index_option]) + 1; + option_name = malloc (length); + if (!option_name) + return NULL; + + snprintf (option_name, length, "%s.%s", + trigger_name, trigger_option_string[index_option]); + + switch (index_option) + { + case TRIGGER_OPTION_ENABLED: + ptr_option = weechat_config_new_option ( + trigger_config_file, trigger_config_section_trigger, + option_name, "boolean", + N_("if disabled, the hooks are removed from trigger, so it is " + "not called any more"), + NULL, 0, 0, value, NULL, 0, NULL, NULL, + &trigger_config_change_trigger_enabled, NULL, NULL, NULL); + break; + case TRIGGER_OPTION_HOOK: + ptr_option = weechat_config_new_option ( + trigger_config_file, trigger_config_section_trigger, + option_name, "integer", + N_("type of hook used"), + trigger_hook_option_values, + 0, 0, value, NULL, 0, NULL, NULL, + &trigger_config_change_trigger_hook, NULL, NULL, NULL); + break; + case TRIGGER_OPTION_ARGUMENTS: + ptr_option = weechat_config_new_option ( + trigger_config_file, trigger_config_section_trigger, + option_name, "string", + N_("arguments for the hook (depend on the hook type, see /help " + "trigger)"), + NULL, 0, 0, value, NULL, 0, NULL, NULL, + &trigger_config_change_trigger_arguments, NULL, NULL, NULL); + break; + case TRIGGER_OPTION_CONDITIONS: + ptr_option = weechat_config_new_option ( + trigger_config_file, trigger_config_section_trigger, + option_name, "string", + N_("condition(s) for running the command (it is checked in " + "hook callback) (note: content is evaluated when trigger is " + "run, see /help eval)"), + NULL, 0, 0, value, NULL, 0, + NULL, NULL, NULL, NULL, NULL, NULL); + break; + case TRIGGER_OPTION_REGEX: + ptr_option = weechat_config_new_option ( + trigger_config_file, trigger_config_section_trigger, + option_name, "string", + N_("replace text with a POSIX extended regular expression (it " + "is done only if conditions are OK, and before running the " + "command) (note: content is evaluated on trigger creation, " + "see /help eval); format is: \"/regex/replace/var\" (var " + "is the hashtable variable to replace, it is optional), " + "many regex can be separated by a space, for example: " + "\"/regex1/replace1/var1 /regex2/replace2/var2\"; the " + "separator \"/\" can be replaced by any char (one or more " + "identical chars), except '\\' and parentheses; matching " + "groups can be used in replace: $0 to $99, $+ for last " + "match and $.cN to replace all chars of group N by char c"), + NULL, 0, 0, value, NULL, 0, NULL, NULL, + &trigger_config_change_trigger_regex, NULL, NULL, NULL); + break; + case TRIGGER_OPTION_COMMAND: + ptr_option = weechat_config_new_option ( + trigger_config_file, trigger_config_section_trigger, + option_name, "string", + N_("command(s) to run if conditions are OK, after regex " + "replacements (many commands can be separated by semicolons)"), + NULL, 0, 0, value, NULL, 0, NULL, NULL, + &trigger_config_change_trigger_command, NULL, NULL, NULL); + break; + case TRIGGER_OPTION_RETURN_CODE: + ptr_option = weechat_config_new_option ( + trigger_config_file, trigger_config_section_trigger, + option_name, "integer", + N_("return code for hook callback (see plugin API reference to " + "know where ok_eat or error can be used efficiently)"), + "ok|ok_eat|error", 0, 0, value, NULL, 0, + NULL, NULL, NULL, NULL, NULL, NULL); + break; + case TRIGGER_NUM_OPTIONS: + break; + } + + free (option_name); + + return ptr_option; +} + +/* + * Creates option for a temporary trigger (when reading configuration file). + */ + +void +trigger_config_create_option_temp (struct t_trigger *temp_trigger, + int index_option, const char *value) +{ + struct t_config_option *new_option; + + new_option = trigger_config_create_trigger_option (temp_trigger->name, + index_option, value); + if (new_option + && (index_option >= 0) && (index_option < TRIGGER_NUM_OPTIONS)) + { + temp_trigger->options[index_option] = new_option; + } +} + +/* + * Uses temporary triggers (created by reading configuration file). + */ + +void +trigger_config_use_temp_triggers () +{ + struct t_trigger *ptr_temp_trigger, *next_temp_trigger; + int i, num_options_ok; + + for (ptr_temp_trigger = triggers_temp; ptr_temp_trigger; + ptr_temp_trigger = ptr_temp_trigger->next_trigger) + { + num_options_ok = 0; + for (i = 0; i < TRIGGER_NUM_OPTIONS; i++) + { + if (!ptr_temp_trigger->options[i]) + { + ptr_temp_trigger->options[i] = + trigger_config_create_trigger_option (ptr_temp_trigger->name, + i, + trigger_option_default[i]); + } + if (ptr_temp_trigger->options[i]) + num_options_ok++; + } + + if (num_options_ok == TRIGGER_NUM_OPTIONS) + { + trigger_new_with_options (ptr_temp_trigger->name, + ptr_temp_trigger->options); + } + else + { + for (i = 0; i < TRIGGER_NUM_OPTIONS; i++) + { + if (ptr_temp_trigger->options[i]) + { + weechat_config_option_free (ptr_temp_trigger->options[i]); + ptr_temp_trigger->options[i] = NULL; + } + } + } + } + + /* free all temporary triggers */ + while (triggers_temp) + { + next_temp_trigger = triggers_temp->next_trigger; + + if (triggers_temp->name) + free (triggers_temp->name); + free (triggers_temp); + + triggers_temp = next_temp_trigger; + } + last_trigger_temp = NULL; +} + +/* + * Reads a trigger option in trigger configuration file. + */ + +int +trigger_config_trigger_read_cb (void *data, struct t_config_file *config_file, + struct t_config_section *section, + const char *option_name, const char *value) +{ + char *pos_option, *trigger_name; + struct t_trigger *ptr_temp_trigger; + int index_option; + + /* make C compiler happy */ + (void) data; + (void) config_file; + (void) section; + + if (!option_name) + return WEECHAT_CONFIG_OPTION_SET_OK_SAME_VALUE; + + pos_option = strchr (option_name, '.'); + if (!pos_option) + return WEECHAT_CONFIG_OPTION_SET_OK_SAME_VALUE; + + trigger_name = weechat_strndup (option_name, pos_option - option_name); + if (!trigger_name) + return WEECHAT_CONFIG_OPTION_SET_OK_SAME_VALUE; + + pos_option++; + + /* search temporary trigger */ + for (ptr_temp_trigger = triggers_temp; ptr_temp_trigger; + ptr_temp_trigger = ptr_temp_trigger->next_trigger) + { + if (strcmp (ptr_temp_trigger->name, trigger_name) == 0) + break; + } + if (!ptr_temp_trigger) + { + /* create new temporary trigger */ + ptr_temp_trigger = trigger_alloc (trigger_name); + if (ptr_temp_trigger) + trigger_add (ptr_temp_trigger, &triggers_temp, &last_trigger_temp); + } + + if (ptr_temp_trigger) + { + index_option = trigger_search_option (pos_option); + if (index_option >= 0) + { + trigger_config_create_option_temp (ptr_temp_trigger, index_option, + value); + } + else + { + weechat_printf (NULL, + _("%sWarning: unknown option for section \"%s\": " + "%s (value: \"%s\")"), + weechat_prefix ("error"), + TRIGGER_CONFIG_SECTION_TRIGGER, + option_name, value); + } + } + + free (trigger_name); + + return WEECHAT_CONFIG_OPTION_SET_OK_SAME_VALUE; +} + +/* + * Writes default triggers in trigger configuration file. + */ + +int +trigger_config_trigger_write_default_cb (void *data, + struct t_config_file *config_file, + const char *section_name) +{ + int i, j, quotes; + char option_name[512]; + + /* make C compiler happy */ + (void) data; + + if (!weechat_config_write_line (config_file, section_name, NULL)) + return WEECHAT_CONFIG_WRITE_ERROR; + + for (i = 0; trigger_config_default_list[i][0]; i++) + { + for (j = 0; j < TRIGGER_NUM_OPTIONS; j++) + { + snprintf (option_name, sizeof (option_name), + "%s.%s", + trigger_config_default_list[i][0], + trigger_option_string[j]); + quotes = (j & (TRIGGER_OPTION_ARGUMENTS | TRIGGER_OPTION_CONDITIONS | + TRIGGER_OPTION_REGEX | TRIGGER_OPTION_COMMAND)); + if (!weechat_config_write_line (config_file, option_name, "%s%s%s", + (quotes) ? "\"" : "", + trigger_config_default_list[i][j + 1], + (quotes) ? "\"" : "")) + { + return WEECHAT_CONFIG_WRITE_ERROR; + } + } + } + + return WEECHAT_CONFIG_WRITE_OK; +} + +/* + * Reloads trigger configuration file. + */ + +int +trigger_config_reload_cb (void *data, struct t_config_file *config_file) +{ + int rc; + + /* make C compiler happy */ + (void) data; + + trigger_free_all (); + + rc = weechat_config_reload (config_file); + + trigger_config_use_temp_triggers (); + + return rc; +} + +/* + * Initializes trigger configuration file. + * + * Returns: + * 1: OK + * 0: error + */ + +int +trigger_config_init () +{ + struct t_config_section *ptr_section; + + trigger_config_file = weechat_config_new (TRIGGER_CONFIG_NAME, + &trigger_config_reload_cb, NULL); + if (!trigger_config_file) + return 0; + + /* look */ + ptr_section = weechat_config_new_section (trigger_config_file, "look", + 0, 0, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL); + if (!ptr_section) + { + weechat_config_free (trigger_config_file); + return 0; + } + + trigger_config_look_enabled = weechat_config_new_option ( + trigger_config_file, ptr_section, + "enabled", "boolean", + N_("enable trigger support"), + NULL, 0, 0, "on", NULL, 0, NULL, NULL, + &trigger_config_change_enabled, NULL, NULL, NULL); + trigger_config_look_monitor_strip_colors = weechat_config_new_option ( + trigger_config_file, ptr_section, + "monitor_strip_colors", "boolean", + N_("strip colors in hashtable values displayed on monitor buffer"), + NULL, 0, 0, "off", NULL, 0, NULL, NULL, + NULL, NULL, NULL, NULL); + + /* color */ + ptr_section = weechat_config_new_section (trigger_config_file, "color", + 0, 0, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL); + if (!ptr_section) + { + weechat_config_free (trigger_config_file); + return 0; + } + + trigger_config_color_flag_command = weechat_config_new_option ( + trigger_config_file, ptr_section, + "flag_command", "color", + N_("text color for command flag (in /trigger list)"), + NULL, 0, 0, "lightgreen", NULL, 0, + NULL, NULL, NULL, NULL, NULL, NULL); + trigger_config_color_flag_conditions = weechat_config_new_option ( + trigger_config_file, ptr_section, + "flag_conditions", "color", + N_("text color for conditions flag (in /trigger list)"), + NULL, 0, 0, "yellow", NULL, 0, + NULL, NULL, NULL, NULL, NULL, NULL); + trigger_config_color_flag_regex = weechat_config_new_option ( + trigger_config_file, ptr_section, + "flag_regex", "color", + N_("text color for regex flag (in /trigger list)"), + NULL, 0, 0, "lightcyan", NULL, 0, + NULL, NULL, NULL, NULL, NULL, NULL); + trigger_config_color_flag_return_code = weechat_config_new_option ( + trigger_config_file, ptr_section, + "flag_return_code", "color", + N_("text color for return code flag (in /trigger list)"), + NULL, 0, 0, "lightmagenta", NULL, 0, + NULL, NULL, NULL, NULL, NULL, NULL); + trigger_config_color_regex = weechat_config_new_option ( + trigger_config_file, ptr_section, + "regex", "color", + N_("text color for regular expressions"), + NULL, 0, 0, "white", NULL, 0, + NULL, NULL, NULL, NULL, NULL, NULL); + trigger_config_color_replace = weechat_config_new_option ( + trigger_config_file, ptr_section, + "replace", "color", + N_("text color for replacement text (for regular expressions)"), + NULL, 0, 0, "cyan", NULL, 0, + NULL, NULL, NULL, NULL, NULL, NULL); + trigger_config_color_trigger = weechat_config_new_option ( + trigger_config_file, ptr_section, + "trigger", "color", + N_("text color for trigger name"), + NULL, 0, 0, "green", NULL, 0, + NULL, NULL, NULL, NULL, NULL, NULL); + trigger_config_color_trigger_disabled = weechat_config_new_option ( + trigger_config_file, ptr_section, + "trigger_disabled", "color", + N_("text color for disabled trigger name"), + NULL, 0, 0, "red", NULL, 0, + NULL, NULL, NULL, NULL, NULL, NULL); + + /* trigger */ + ptr_section = weechat_config_new_section (trigger_config_file, + TRIGGER_CONFIG_SECTION_TRIGGER, + 0, 0, + &trigger_config_trigger_read_cb, NULL, + NULL, NULL, + &trigger_config_trigger_write_default_cb, NULL, + NULL, NULL, + NULL, NULL); + if (!ptr_section) + { + weechat_config_free (trigger_config_file); + return 0; + } + + trigger_config_section_trigger = ptr_section; + + return 1; +} + +/* + * Reads trigger configuration file. + */ + +int +trigger_config_read () +{ + int rc; + + rc = weechat_config_read (trigger_config_file); + + trigger_config_use_temp_triggers (); + + return rc; +} + +/* + * Writes trigger configuration file. + */ + +int +trigger_config_write () +{ + return weechat_config_write (trigger_config_file); +} + +/* + * Frees trigger configuration. + */ + +void +trigger_config_free () +{ + weechat_config_free (trigger_config_file); +} |