diff options
author | Sebastien Helleu <flashcode@flashtux.org> | 2007-10-31 18:30:21 +0100 |
---|---|---|
committer | Sebastien Helleu <flashcode@flashtux.org> | 2007-10-31 18:30:21 +0100 |
commit | 90262cbcfea07e26236f15b46db02e73e8a43fc3 (patch) | |
tree | 696afac6bb8b7d8b8d395b98cab47c79c7d548b7 /src/plugins | |
parent | 2ab46db3adc2aed13572cc14074415e7751bb52a (diff) | |
download | weechat-90262cbcfea07e26236f15b46db02e73e8a43fc3.zip |
Added trigger plugin
Diffstat (limited to 'src/plugins')
-rw-r--r-- | src/plugins/trigger/CMakeLists.txt | 21 | ||||
-rw-r--r-- | src/plugins/trigger/Makefile.am | 30 | ||||
-rw-r--r-- | src/plugins/trigger/dump.c | 148 | ||||
-rw-r--r-- | src/plugins/trigger/trigger-libc.c | 463 | ||||
-rw-r--r-- | src/plugins/trigger/trigger-libc.h | 40 | ||||
-rw-r--r-- | src/plugins/trigger/trigger-libirc.c | 333 | ||||
-rw-r--r-- | src/plugins/trigger/trigger-libirc.h | 40 | ||||
-rw-r--r-- | src/plugins/trigger/trigger.c | 927 | ||||
-rw-r--r-- | src/plugins/trigger/trigger.h | 52 |
9 files changed, 2054 insertions, 0 deletions
diff --git a/src/plugins/trigger/CMakeLists.txt b/src/plugins/trigger/CMakeLists.txt new file mode 100644 index 000000000..d06107be6 --- /dev/null +++ b/src/plugins/trigger/CMakeLists.txt @@ -0,0 +1,21 @@ +# Copyright (c) 2003-2007 FlashCode <flashcode@flashtux.org> +# +# This program 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. +# +# This program 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 this program. If not, see <http://www.gnu.org/licenses/>. +# + +ADD_LIBRARY(trigger MODULE trigger.c trigger.h trigger-libc.c trigger-libc.h +trigger-libirc.c trigger-libirc.h) +SET_TARGET_PROPERTIES(trigger PROPERTIES PREFIX "") + +INSTALL(TARGETS trigger LIBRARY DESTINATION lib/${PROJECT_NAME}/plugins) diff --git a/src/plugins/trigger/Makefile.am b/src/plugins/trigger/Makefile.am new file mode 100644 index 000000000..81d92db5e --- /dev/null +++ b/src/plugins/trigger/Makefile.am @@ -0,0 +1,30 @@ +# Copyright (c) 2003-2007 FlashCode <flashcode@flashtux.org> +# +# This program 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. +# +# This program 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 this program. If not, see <http://www.gnu.org/licenses/>. +# + +INCLUDES = -DLOCALEDIR=\"$(datadir)/locale\" $(TRIGGER_CFLAGS) + +libdir = ${weechat_libdir}/plugins + +lib_LTLIBRARIES = trigger.la + +trigger_la_SOURCES = trigger.c \ + trigger.h \ + trigger-libc.c \ + trigger-libc.h \ + trigger-libirc.c \ + trigger-libirc.h +trigger_la_LDFLAGS = -module +trigger_la_LIBADD = $(TRIGGER_LFLAGS) diff --git a/src/plugins/trigger/dump.c b/src/plugins/trigger/dump.c new file mode 100644 index 000000000..7a92809a8 --- /dev/null +++ b/src/plugins/trigger/dump.c @@ -0,0 +1,148 @@ +int +weechat_trigger_match (t_weechat_trigger *ptr_ign, + char *pattern, char *commands, + char *channels, char *servers) +{ + if (strcasecmp (ptr_ign->pattern, pattern) == 0 + && strcasecmp (ptr_ign->commands, commands) == 0 + && strcasecmp (ptr_ign->channels, channels) == 0 + && strcasecmp (ptr_ign->servers, servers) == 0) + return 1; + + return 0; +} + +t_weechat_trigger * +weechat_trigger_search (char *pattern, char *commands, + char *channels, char *servers) +{ + t_weechat_trigger *l; + + l = weechat_trigger_list; + while (l) + { + if (weechat_trigger_match (l, pattern, commands, channels, servers)) + return l; + l = l->next_trigger; + } + + return NULL; +} +int +weechat_trigger_add (t_weechat_plugin *plugin, + char *pattern, char *commands, + char *channels, char *servers) +{ + t_weechat_trigger *new; + + if (!pattern) + return 0; + if (weechat_trigger_search (pattern, commands, channels, servers)) + { + return 2; + } + + new = weechat_trigger_alloc (pattern, commands, channels, servers); + if (new) + { + if (weechat_trigger_last) + { + weechat_trigger_last->next_trigger = new; + new->prev_trigger = weechat_trigger_last; + weechat_trigger_last = new; + } + else + { + weechat_trigger_list = new; + weechat_trigger_last = new; + } + + return 1; + } + else + plugin->print_server (plugin, "Unable to add trigger, memory allocation failed."); + + return 0; +} + +int +weechat_trigger_list_del (char *pattern, char *commands, + char *channels, char *servers) +{ + char *error; + int number; + t_weechat_trigger *p, *l; + + if (!pattern || !weechat_trigger_list) + return 0; + + error = NULL; + number = strtol (pattern, &error, 10); + p = NULL; + + if (error && (error[0] == '\0') && number > 0) + { + l = weechat_trigger_list; + while (l && number >= 0) + { + number--; + if (number == 0) + p = l; + l = l->next_trigger; + } + } + else + p = weechat_trigger_search (pattern, commands, channels, servers); + + if (p) + { + if (p->prev_trigger) + p->prev_trigger->next_trigger = p->next_trigger; + + if (p->next_trigger) + p->next_trigger->prev_trigger = p->prev_trigger; + + if (p == weechat_trigger_list) + weechat_trigger_list = p->next_trigger; + + if (p == weechat_trigger_last) + weechat_trigger_last = p->prev_trigger; + + weechat_trigger_free (p); + return 1; + } + + return 0; +} + + /* + server = plugin->get_info (plugin, "server", NULL); + if (!server) + server = strdup ("*"); + + if (argc >= 4) + ret = weechat_trigger_add (plugin, argv[0], argv[1], argv[2], argv[3]); + else if (argc == 3) + ret = weechat_trigger_add (plugin, argv[0], argv[1], argv[2], server); + else if (argc == 2) + ret = weechat_trigger_add (plugin, argv[0], argv[1], "*", server); + else if (argc == 1) + ret = weechat_trigger_add (plugin, argv[0], "*", "*", server); + else + { + ret = weechat_trigger_list (plugin); + ret = 1; + } + + if (server) + free (server); + + if (argc > 0 && ret == 1) + plugin->print_server (plugin, "Trigger: new trigger: on %s/%s: trigger %s from %s", + weechat_trigger_last->servers, weechat_trigger_last->channels, + weechat_trigger_last->commands, weechat_trigger_last->pattern); + else if (ret == 2) + plugin->print_server (plugin, "Trigger: trigger already exists."); + else if (ret == 0) + plugin->print_server (plugin, "Trigger: error: unable to add trigger."); + */ diff --git a/src/plugins/trigger/trigger-libc.c b/src/plugins/trigger/trigger-libc.c new file mode 100644 index 000000000..d8b278660 --- /dev/null +++ b/src/plugins/trigger/trigger-libc.c @@ -0,0 +1,463 @@ +/* + * Copyright (c) 2003-2006 by FlashCode <flashcode@flashtux.org> + * See README for License detail, AUTHORS for developers list. + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* weechat-trigger-libirc.c: Tiny libc */ + +/* + * c_is_number: return 1 if string is an number + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <ctype.h> + +#include <fnmatch.h> +#undef FNM_CASEFOLD +#define FNM_CASEFOLD (1 << 4) + +/* + * c_is_number : is a string a number (an integer) + * return : 1 if true else 0 + */ + +int +c_is_number (char *s) +{ + int i, l, r; + + if (!s) + return 0; + + r = 1; + l = strlen (s); + for (i=0; i<l; i++) + { + if (!isdigit(s[i])) + { + r = 0; + break; + } + } + return r; +} + +/* + * c_to_number : convert a string to a number (an integer) + * return the number + */ + +int +c_to_number (char *s) +{ + int number = 0; + + if (c_is_number (s) == 1) + number = strtol (s, NULL, 10); + + return number; +} + +/* + * c_strndup: strndup function (not existing in FreeBSD and maybe other) + */ + +char * +c_strndup (char *string, int length) +{ + char *result; + + if ((int)strlen (string) < length) + return strdup (string); + + result = (char *)malloc (length + 1); + if (!result) + return NULL; + + memcpy (result, string, length); + result[length] = '\0'; + + return result; +} + +/* + * c_ascii_tolower: locale independant string conversion to lower case + */ + +void +c_ascii_tolower (char *string) +{ + while (string && string[0]) + { + if ((string[0] >= 'A') && (string[0] <= 'Z')) + string[0] += ('a' - 'A'); + string++; + } +} + +/* + * c_ascii_toupper: locale independant string conversion to upper case + */ + +void +c_ascii_toupper (char *string) +{ + while (string && string[0]) + { + if ((string[0] >= 'a') && (string[0] <= 'z')) + string[0] -= ('a' - 'A'); + string++; + } +} + +/* + * weechat_strreplace: replace a string by new one in a string + * note: returned value has to be free() after use + */ + +char * +c_weechat_strreplace (char *string, char *search, char *replace) +{ + char *pos, *new_string; + int length1, length2, length_new, count; + + if (!string || !search || !replace) + return NULL; + + length1 = strlen (search); + length2 = strlen (replace); + + /* count number of strings to replace */ + count = 0; + pos = string; + while (pos && pos[0] && (pos = strstr (pos, search))) + { + count++; + pos += length1; + } + + /* easy: no string to replace! */ + if (count == 0) + return strdup (string); + + /* compute needed memory for new string */ + length_new = strlen (string) - (count * length1) + (count * length2) + 1; + + /* allocate new string */ + new_string = (char *)malloc (length_new * sizeof (char)); + if (!new_string) + return strdup (string); + + /* replace all occurences */ + new_string[0] = '\0'; + while (string && string[0]) + { + pos = strstr (string, search); + if (pos) + { + strncat (new_string, string, pos - string); + strcat (new_string, replace); + pos += length1; + } + else + strcat (new_string, string); + string = pos; + } + return new_string; +} + +/* + * explode_string: explode a string according to separators + */ + +char ** +c_explode_string (char *string, char *separators, int num_items_max, + int *num_items) +{ + int i, n_items; + char **array; + char *ptr, *ptr1, *ptr2; + + if (num_items != NULL) + *num_items = 0; + + n_items = num_items_max; + + if (!string || !string[0]) + return NULL; + + if (num_items_max == 0) + { + /* calculate number of items */ + ptr = string; + i = 1; + while ((ptr = strpbrk (ptr, separators))) + { + while (strchr (separators, ptr[0]) != NULL) + ptr++; + i++; + } + n_items = i; + } + + array = + (char **) malloc ((num_items_max ? n_items : n_items + 1) * + sizeof (char *)); + + ptr1 = string; + ptr2 = string; + + for (i = 0; i < n_items; i++) + { + while (strchr (separators, ptr1[0]) != NULL) + ptr1++; + if (i == (n_items - 1) || (ptr2 = strpbrk (ptr1, separators)) == NULL) + if ((ptr2 = strchr (ptr1, '\r')) == NULL) + if ((ptr2 = strchr (ptr1, '\n')) == NULL) + ptr2 = strchr (ptr1, '\0'); + + if ((ptr1 == NULL) || (ptr2 == NULL)) + { + array[i] = NULL; + } + else + { + if (ptr2 - ptr1 > 0) + { + array[i] = + (char *) malloc ((ptr2 - ptr1 + 1) * sizeof (char)); + array[i] = strncpy (array[i], ptr1, ptr2 - ptr1); + array[i][ptr2 - ptr1] = '\0'; + ptr1 = ++ptr2; + } + else + { + array[i] = NULL; + } + } + } + if (num_items_max == 0) + { + array[i] = NULL; + if (num_items != NULL) + *num_items = i; + } + else + { + if (num_items != NULL) + *num_items = num_items_max; + } + + return array; +} + +/* + * c_free_exploded_string: free an exploded string + */ + +void +c_free_exploded_string (char **exploded_string) +{ + int i; + + if (exploded_string) + { + for (i = 0; exploded_string[i]; i++) + free (exploded_string[i]); + free (exploded_string); + } +} + +/* + * c_split_multi_command: split a list of commands separated by 'sep' + * and ecscaped with '\' + * - empty commands are removed + * - spaces on the left of each commands are stripped + * Result must be freed with free_multi_command + */ + +char ** +c_split_multi_command (char *command, char sep) +{ + int nb_substr, arr_idx, str_idx, type; + char **array; + char *buffer, *ptr, *p; + + if (command == NULL) + return NULL; + + nb_substr = 1; + ptr = command; + while ( (p = strchr(ptr, sep)) != NULL) + { + nb_substr++; + ptr = ++p; + } + + array = (char **) malloc ((nb_substr + 1) * sizeof(char *)); + if (!array) + return NULL; + + buffer = (char *) malloc ( (strlen(command) + 1) * sizeof (char)); + if (!buffer) + { + free (array); + return NULL; + } + + ptr = command; + str_idx = 0; + arr_idx = 0; + while(*ptr != '\0') + { + type = 0; + if (*ptr == ';') + { + if (ptr == command) + type = 1; + else if ( *(ptr-1) != '\\') + type = 1; + else if ( *(ptr-1) == '\\') + type = 2; + } + if (type == 1) + { + buffer[str_idx] = '\0'; + str_idx = -1; + p = buffer; + /* strip white spaces a the begining of the line */ + while (*p == ' ') p++; + if (p && p[0]) + array[arr_idx++] = strdup (p); + } + else if (type == 2) + buffer[--str_idx] = *ptr; + else + buffer[str_idx] = *ptr; + str_idx++; + ptr++; + } + + buffer[str_idx] = '\0'; + p = buffer; + while (*p == ' ') p++; + if (p && p[0]) + array[arr_idx++] = strdup (p); + + array[arr_idx] = NULL; + + free (buffer); + + array = (char **) realloc (array, (arr_idx + 1) * sizeof(char *)); + + return array; +} + +/* + * c_free_multi_command : free a list of commands splitted + * with split_multi_command + */ + +void +c_free_multi_command (char **commands) +{ + int i; + + if (commands) + { + for (i = 0; commands[i]; i++) + free (commands[i]); + free (commands); + } +} + +/* + * c_join_string : join a list of string with 'sep' as glue + * result must be freed with c_free_joined_string + */ + +char * +c_join_string(char **list, char *sep) +{ + int i, len; + char *str; + + str = NULL; + if (list) + { + len = 0; + for (i = 0; list[i]; i++) + len += strlen (list[i]); + + len += i*strlen (sep) + 1; + str = (char *) malloc (len * sizeof(char)); + if (str) + { + for (i = 0; list[i]; i++) + { + if (i == 0) + strcpy (str, list[i]); + else + { + strcat (str, sep); + strcat (str, list[i]); + } + } + } + } + + return str; +} + +/* + * c_free_joined_string : free a string joined with c_join_string + */ + +void +c_free_joined_string (char *str) +{ + free (str); +} + +/* + * c_match_string : case sensitive matching + * return 1 if it matches else 0 + * + */ +int +c_match_string (char *string, char *pattern) +{ + if (!string || !pattern) + return 0; + return fnmatch (pattern, string, 0) == 0 ? 1 : 0; +} + + +/* + * c_imatch_string : case insensitive matching + * return 1 if it matches else 0 + * + */ +int +c_imatch_string (char *string, char *pattern) +{ + if (!string || !pattern) + return 0; + return fnmatch (pattern, string, FNM_CASEFOLD) == 0 ? 1 : 0; +} diff --git a/src/plugins/trigger/trigger-libc.h b/src/plugins/trigger/trigger-libc.h new file mode 100644 index 000000000..0a4f16804 --- /dev/null +++ b/src/plugins/trigger/trigger-libc.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2003-2006 by FlashCode <flashcode@flashtux.org> + * See README for License detail, AUTHORS for developers list. + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* weechat-trigger-libirc.c: Tiny libc */ + +#ifndef WEECHAT_TRIGGER_LIBC__H +#define WEECHAT_TRIGGER_LIBC__H 1 + +int c_is_number (char *); +int c_to_number (char *); +char *c_strndup (char *, int); +void c_ascii_tolower (char *); +void c_ascii_toupper (char *); +char *c_weechat_strreplace (char *, char *, char *); +char **c_explode_string (char *, char *, int, int *); +void c_free_exploded_string (char **); +char **c_split_multi_command (char *, char); +void c_free_multi_command (char **); +char *c_join_string(char **, char *); +void c_free_joined_string (char *); +int c_match_string (char *, char *); +int c_imatch_string (char *, char *); + +#endif /* WEECHAT_TRIGGER_LIBC__H */ diff --git a/src/plugins/trigger/trigger-libirc.c b/src/plugins/trigger/trigger-libirc.c new file mode 100644 index 000000000..92b829e0b --- /dev/null +++ b/src/plugins/trigger/trigger-libirc.c @@ -0,0 +1,333 @@ +/* + * Copyright (c) 2003-2006 by FlashCode <flashcode@flashtux.org> + * See README for License detail, AUTHORS for developers list. + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* weechat-trigger-libirc.c: Tiny libirc for trigger plugin */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +#include "weechat-trigger-libc.h" +#include "weechat-trigger-libirc.h" + +typedef struct irc_msg_type +{ + char *command; + void (*parser) (irc_msg *, char *); +} irc_msg_type; + +void irc_parse_common (irc_msg *, char *); +void irc_parse_join (irc_msg *, char *); +void irc_parse_kick (irc_msg *, char *); +void irc_parse_mode (irc_msg *, char *); +void irc_parse_nick (irc_msg *, char *); +void irc_parse_privmsg (irc_msg *, char *); +void irc_parse_quit (irc_msg *, char *); +void irc_parse_wallops (irc_msg *, char *); + +irc_msg_type irc_msg_types[] = +{ + /* kill and error commands to add */ + { "invite", irc_parse_common }, + { "join", irc_parse_join }, + { "kick", irc_parse_kick }, + { "mode", irc_parse_mode }, + { "nick", irc_parse_nick }, + { "notice", irc_parse_common }, + { "part", irc_parse_common }, + { "ping", irc_parse_common }, + { "pong", irc_parse_common }, + { "privmsg", irc_parse_privmsg }, + { "quit", irc_parse_quit }, + { "topic", irc_parse_common }, + { "wallops", irc_parse_wallops }, + {NULL, NULL } +}; + +char *irc_ctcp_types[] = +{ + "action", "dcc", "sed", "finger", "version", "source", + "userinfo", "clientinfo","errmsg", "ping", "time", + NULL +}; + +void irc_parse_userhost (irc_msg *m) +{ + char *excl, *ar; + + if (m && m->userhost) + { + excl = strchr (m->userhost, '!'); + if (excl) { + m->nick = c_strndup (m->userhost, excl-m->userhost); + ar = strchr (excl, '@'); + if (ar) + { + m->user = c_strndup (excl+1, ar-excl-1); + ar++; + m->host = strdup (ar); + } + } + else + m->host = strdup (m->userhost); + } +} + +void irc_parse_common (irc_msg *m, char *p) +{ + char *spc; + + p++; + if (p && *p) + { + spc = strchr (p, ' '); + if (spc) + { + m->channel = c_strndup (p, spc-p); + spc++; + if (spc && *spc && spc[0] == ':') + m->message = strdup (spc+1); + } + } +} + + +void irc_parse_snotice (irc_msg *m, char *p) +{ + char *c; + + if (p) + { + c = strchr (p, ':'); + c++; + if (c && *c) + { + m->message = strdup (c); + m->command = strdup ("notice"); + } + } +} + +void irc_parse_privmsg (irc_msg *m, char *p) +{ + char ctcp_buf[32]; + char *c, *d; + char **it; + + irc_parse_common (m, p); + + c = m->message; + if (c) + { + if (*c == '\x01') + { + c++; + d = strchr(c, '\x01'); + if (d) + { + for (it = irc_ctcp_types; *it; it++) + { + if (strncasecmp (c, *it, strlen(*it)) == 0) + { + snprintf (ctcp_buf, sizeof(ctcp_buf), "ctcp-%s", *it); + free (m->command); + m->command = strdup (ctcp_buf); + c += strlen(*it); + d = c_strndup (c+1, d-c+1); + free (m->message); + m->message = d; + break; + } + } + } + } + } +} + +void irc_parse_join (irc_msg *m, char *p) +{ + p++; + if (p && *p && p[0] == ':') + { + m->channel = strdup (p+1); + } +} + +void irc_parse_nick (irc_msg *m, char *p) +{ + p++; + if (p && *p && p[0] == ':') + { + m->message = strdup (p+1); + } +} + +void irc_parse_mode (irc_msg *m, char *p) +{ + char *spc; + + p++; + if (p && *p) + { + spc = strchr (p, ' '); + if (spc) + { + m->channel = c_strndup (p, spc-p); + spc++; + if (spc && *spc) + m->message = strdup (spc); + } + } +} + +void irc_parse_quit (irc_msg *m, char *p) +{ + p++; + if (p && *p && p[0] == ':') + { + m->message = strdup (p+1); + } +} + +void irc_parse_kick (irc_msg *m, char *p) +{ + char *spc1, *spc2; + + p++; + if (p && *p) + { + spc1 = strchr (p, ' '); + if (spc1) + { + m->channel = c_strndup (p, spc1-p); + spc1++; + if (spc1 && *spc1) + { + spc2 = strchr(spc1, ' '); + if (spc2) + { + m->data = c_strndup (spc1, spc2-spc1); + spc2++; + if (spc2 && *spc2 && spc2[0] == ':') + m->message = strdup (spc2+1); + } + } + } + } +} + +void irc_parse_wallops (irc_msg *m, char *p) +{ + p++; + if (p && *p && p[0] == ':') + { + m->message = strdup (p+1); + } +} + +void irc_parse_numeric (irc_msg *m, char *p) +{ + char *spc1, *spc2; + + p++; + if (p && *p) + { + spc1 = strchr (p, ' '); + if (spc1) + { + spc2 = strchr (spc1, ' '); + spc2++; + if (spc2 && *spc2 && spc2[0] == ':') + m->message = strdup (spc2+1); + } + } +} + + + +irc_msg *irc_parse_msg (char *msg) +{ + irc_msg *m; + char *spc1, *spc2; + irc_msg_type *it; + + m = (irc_msg *) malloc(sizeof(irc_msg)); + + if (m) + { + m->userhost = NULL; + m->nick = NULL; + m->user = NULL; + m->host = NULL; + m->command = NULL; + m->channel = NULL; + m->message = NULL; + m->data = NULL; + + if (msg && msg[0] == ':') + { + spc1 = strchr (msg, ' '); + if (spc1) + { + spc1++; + spc2 = strchr (spc1, ' '); + if (spc2) + { + m->command = c_strndup (spc1, spc2-spc1); + c_ascii_tolower (m->command); + + m->userhost = c_strndup (msg+1, spc1-msg-2); + irc_parse_userhost (m); + + if (c_is_number (m->command)) + irc_parse_numeric (m, spc2); + else + for (it = irc_msg_types; it->command; it++) + { + if (strcmp (m->command, it->command) == 0) + { + it->parser (m, spc2); + break; + } + } + } + } + } + + if (msg && strncasecmp("NOTICE ", msg, 7) == 0) + irc_parse_snotice (m, msg); + } + return m; +} + +void irc_msg_free (irc_msg *m) +{ + if (m) + { + if (m->userhost) free (m->userhost); + if (m->nick) free (m->nick); + if (m->user) free (m->user); + if (m->host) free (m->host); + if (m->command) free (m->command); + if (m->channel) free (m->channel); + if (m->message) free (m->message); + if (m->data) free (m->data); + free (m); + } +} diff --git a/src/plugins/trigger/trigger-libirc.h b/src/plugins/trigger/trigger-libirc.h new file mode 100644 index 000000000..1d48f4093 --- /dev/null +++ b/src/plugins/trigger/trigger-libirc.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2003-2006 by FlashCode <flashcode@flashtux.org> + * See README for License detail, AUTHORS for developers list. + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* weechat-trigger-libirc.c: Tiny libirc for trigger plugin */ + +#ifndef WEECHAT_TRIGGER_LIBIRC__H +#define WEECHAT_TRIGGER_LIBIRC__H 1 + +typedef struct irc_msg +{ + char *userhost; + char *nick; + char *user; + char *host; + char *command; + char *channel; + char *message; + char *data; +} irc_msg; + +irc_msg *irc_parse_msg (char *); +void irc_msg_free (irc_msg *); + +#endif /* WEECHAT_TRIGGER_LIBIRC__H */ diff --git a/src/plugins/trigger/trigger.c b/src/plugins/trigger/trigger.c new file mode 100644 index 000000000..44b410af3 --- /dev/null +++ b/src/plugins/trigger/trigger.c @@ -0,0 +1,927 @@ +/* + * Copyright (c) 2003-2006 by FlashCode <flashcode@flashtux.org> + * See README for License detail, AUTHORS for developers list. + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* weechat-trigger.c: Trigger plugin for WeeChat */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "../weechat-plugin.h" +#include "weechat-trigger.h" +#include "weechat-trigger-libirc.h" +#include "weechat-trigger-libc.h" + +t_weechat_trigger *weechat_trigger_list = NULL; +t_weechat_trigger *weechat_trigger_last = NULL; + +t_weechat_trigger *weechat_trigger_alloc (char *pattern, char *domain, char *commands, + char *channels, char *servers, + char *action, char *cmd) +{ + t_weechat_trigger *new; + + new = (t_weechat_trigger *) malloc (sizeof (t_weechat_trigger)); + if (new) + { + new->pattern = strdup (pattern); + new->domain = strdup (domain); + + new->commands = c_explode_string (commands, ",", 0, NULL); + new->channels = c_explode_string (channels, ",", 0, NULL); + new->servers = c_explode_string (servers, ",", 0, NULL); + new->action = strdup (action); + + if (cmd) + new->cmds = c_split_multi_command (cmd, ';'); + else + new->cmds = NULL; + + new->prev_trigger = NULL; + new->next_trigger = NULL; + } + return new; +} + +void weechat_trigger_free (t_weechat_trigger *trig) +{ + if (trig) + { + if (trig->pattern) + free (trig->pattern); + if (trig->domain) + free (trig->domain); + if (trig->commands) + c_free_exploded_string (trig->commands); + if (trig->channels) + c_free_exploded_string (trig->channels); + if (trig->servers) + c_free_exploded_string (trig->servers); + if (trig->action) + free (trig->action); + if (trig->cmds) + c_free_multi_command (trig->cmds); + free (trig); + } +} + +int +weechat_trigger_action_exists (char *action) +{ + if (strcasecmp(action, "ignore") == 0 + || strcasecmp(action, "display") == 0 + || strcasecmp(action, "highlight") == 0 + || strcasecmp(action, "run") == 0) + return 1; + + return 0; +} + +int +weechat_trigger_domain_exists (char *action) +{ + if (strcasecmp(action, "*") == 0 + || strcasecmp(action, "user") == 0 + || strcasecmp(action, "nick") == 0 + || strcasecmp(action, "userhost") == 0 + || strcasecmp(action, "msg") == 0) + return 1; + + return 0; +} + +/* + * weechat_trigger_add : create and add a new trigger in triggers list + * return : + * 0 : adding was successfull + * 1 : memory error + * 2 : bad arguments + */ + +int +weechat_trigger_add (int argc, char **argv) +{ + int ret = 2; + char *rcmd; + t_weechat_trigger *trig = NULL; + + if (argc == 6) + { + if (weechat_trigger_action_exists (argv[5]) + && strcasecmp (argv[5], "run") != 0) + { + trig = weechat_trigger_alloc ( + argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], NULL); + if (!trig) + ret = 1; + } + } + else if (argc > 6) + { + if (strcasecmp (argv[5], "run") == 0) + { + rcmd = c_join_string (&argv[6], " "); + if (rcmd) + { + trig = weechat_trigger_alloc ( + argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], rcmd); + c_free_joined_string (rcmd); + if (!trig) + ret = 1; + } + } + } + + if (trig) + { + if (weechat_trigger_last) + { + weechat_trigger_last->next_trigger = trig; + trig->prev_trigger = weechat_trigger_last; + weechat_trigger_last = trig; + } + else + { + weechat_trigger_list = trig; + weechat_trigger_last = trig; + } + ret = 0; + } + + return ret; +} + +/* + * + */ + +int +weechat_trigger_move (int from, int to) +{ + t_weechat_trigger *l, *f, *t; + int ret, i; + + if (from == to) + return 0; + + ret = 1; + f = NULL; + t = NULL; + l = weechat_trigger_list; + i = 0; + while (l) + { + i++; + if (i == from) + f = l; + if (i == to) + t = l; + l = l->next_trigger; + } + + if (f && t) + { + if (weechat_trigger_list == f) + weechat_trigger_list = f->next_trigger; + + if (weechat_trigger_last == f) + weechat_trigger_last = f->prev_trigger; + + if (f->prev_trigger) + f->prev_trigger->next_trigger = f->next_trigger; + if (f->next_trigger) + f->next_trigger->prev_trigger = f->prev_trigger; + + if (to > from && !t->next_trigger) + { + t->next_trigger = f; + f->prev_trigger = t; + f->next_trigger = NULL; + + weechat_trigger_last = f; + } + else + { + if (to > from && t->next_trigger) + t = t->next_trigger; + + if (t->prev_trigger) + t->prev_trigger->next_trigger = f; + f->next_trigger = t; + f->prev_trigger = t->prev_trigger; + t->prev_trigger = f; + + if (t == weechat_trigger_list) + weechat_trigger_list = f; + } + + ret = 0; + } + + return ret; +} + +/* + * weechat_trigger_move : remove a trigger trigger in triggers list + * by its number + * return : 0 = success ; 1 = failed + */ + +int +weechat_trigger_remove (int n) +{ + t_weechat_trigger *l, *p; + int ret; + + ret = 1; + l = weechat_trigger_list; + p = NULL; + while (l && n >= 0) + { + n--; + if (n == 0) { + p = l; + break; + } + l = l->next_trigger; + } + + if (p) + { + if (p->prev_trigger) + p->prev_trigger->next_trigger = p->next_trigger; + + if (p->next_trigger) + p->next_trigger->prev_trigger = p->prev_trigger; + + if (p == weechat_trigger_list) + weechat_trigger_list = p->next_trigger; + + if (p == weechat_trigger_last) + weechat_trigger_last = p->prev_trigger; + + weechat_trigger_free (p); + ret = 0; + } + + return ret; +} + +void +weechat_trigger_display (t_weechat_plugin *plugin) +{ + t_weechat_trigger *l; + int i; + char *commands, *channels, *servers, *cmds; + + if (weechat_trigger_list) + { + plugin->print_server (plugin, "Trigger list:"); + l = weechat_trigger_list; + i = 1; + while (l) + { + commands = c_join_string (l->commands, ","); + channels = c_join_string (l->channels, ","); + servers = c_join_string (l->servers, ","); + cmds = c_join_string (l->cmds, ";"); + + if (strcasecmp (l->action, "run") == 0) + plugin->print_server (plugin, + "[%d] pattern '%s/%s' for irc command(s) '%s'" + " for channel(s) '%s' on server(s) '%s'" + " do '%s' command(s) '%s'", + i, l->pattern, l->domain, commands, channels, + servers, l->action, cmds); + else + plugin->print_server (plugin, + "[%d] pattern '%s/%s' for irc command(s) '%s'" + " for channel(s) '%s' on server(s) '%s'" + " do '%s'", + i, l->pattern, l->domain, commands, channels, + servers, l->action); + + if (commands) c_free_joined_string (commands); + if (channels) c_free_joined_string (channels); + if (servers) c_free_joined_string (servers); + if (cmds) c_free_joined_string (cmds); + l = l->next_trigger; + i++; + } + } + else + plugin->print_server (plugin, "Trigger list: no trigger defined."); +} + +/* + * weechat_trigger_cmd: /trigger command + */ + +int +weechat_trigger_cmd (t_weechat_plugin *plugin, + int cmd_argc, char **cmd_argv, + char *handler_args, void *handler_pointer) +{ + int argc, ret, n1, n2; + char **argv; + + /* make C compiler happy */ + (void) cmd_argc; + (void) handler_args; + (void) handler_pointer; + + ret = 0; + + if (cmd_argv[2]) + argv = c_explode_string (cmd_argv[2], " ", 0, &argc); + else + { + argv = NULL; + argc = 0; + } + + if (argv) + { + if (strcasecmp (argv[0], "add") == 0) + { + if (argc >= 7) + { + switch (weechat_trigger_add (argc-1, &argv[1])) + { + case 0: + plugin->print_server (plugin, "Trigger: trigger successfully created"); + break; + case 1: + plugin->print_server (plugin, "Trigger error: memory error while creating trigger"); + break; + case 2: + plugin->print_server (plugin, "Trigger error: 'action' or 'domain' option seems misused"); + break; + } + } + else + plugin->print_server (plugin, "Trigger error: missing arguments"); + } + else if (strcasecmp (argv[0], "move") == 0) + { + if (argc == 3) + { + n1 = c_to_number (argv[1]); + n2 = c_to_number (argv[2]); + if (n1 > 0 && n2 > 0) + { + if (weechat_trigger_move (n1, n2) == 0) + plugin->print_server (plugin, "Trigger: trigger sucessfully moved from psotion %d to %d", n1, n2); + else + plugin->print_server (plugin, "Trigger error: fail to move from %d to %d, number(s) seems invalid", n1, n2); + } + else + plugin->print_server (plugin, "Trigger error: fail to move from %d to %d, number(s) seems invalid", n1, n2); + } + else + plugin->print_server (plugin, "Trigger error: fail to move, missing or too much arguments"); + + } + else if (strcasecmp (argv[0], "remove") == 0) + { + if (argc == 2) + { + n1 = c_to_number (argv[1]); + if (n1 > 0) + { + if (weechat_trigger_remove (n1) == 0) + plugin->print_server (plugin, "Trigger: trigger number %d sucessfully removed", n1); + else + plugin->print_server (plugin, "Trigger error: fail to remove trigger number %d, number out of bound", n1); + } + else + plugin->print_server (plugin, "Trigger error: fail to remove trigger number %d, number seems invalid", n1); + } + else + plugin->print_server (plugin, "Trigger error: fail to remove trigger, missing or too much arguments"); + } + else + weechat_trigger_display (plugin); + + c_free_exploded_string (argv); + } + else + weechat_trigger_display (plugin); + + return PLUGIN_RC_OK; +} + +/* + * weechat_trigger_match: find if a trigger match an irc message + * return : 0 if it does match + * 1 if it doesn't match + * 2 if irc message can't be parsed + */ +irc_msg * +weechat_trigger_match(t_weechat_trigger *trigger, char *msg, char *server, int *ret) +{ + irc_msg *imsg; + int match_c, match_h, match_s; + char **pp; + + imsg = irc_parse_msg (msg); + *ret = 1; + match_c = 0; + match_h = 0; + match_s = 0; + + if (imsg) + { + /* + p->print_server(p, + "uh=[%s] n=[%s] u=[%s] h=[%s] com=[%s] chan=[%s] srv=[%s] msg=[%s]", + imsg->userhost, imsg->nick, imsg->user, imsg->host, + imsg->command, imsg->channel, server, imsg->message); + */ + + + if ( + (imsg->user + && ((strcasecmp(trigger->domain, "*") == 0) + || (strcasecmp(trigger->domain, "user") == 0)) + && c_imatch_string (imsg->user, trigger->pattern)) + || + (imsg->nick + && ((strcasecmp(trigger->domain, "*") == 0) + || strcasecmp(trigger->domain, "nick") == 0) + && c_imatch_string (imsg->nick, trigger->pattern)) + || + (imsg->userhost + && ((strcasecmp(trigger->domain, "*") == 0) + || (strcasecmp(trigger->domain, "userhost") == 0)) + && c_imatch_string (imsg->userhost, trigger->pattern)) + || + (imsg->message + && ((strcasecmp(trigger->domain, "*") == 0) + || (strcasecmp(trigger->domain, "msg") == 0)) + && c_imatch_string (imsg->message, trigger->pattern)) + ) + { + if (!imsg->command) + match_c = 1; + else if (trigger->commands) + { + for (pp = trigger->commands; *pp; pp++) + { + if (c_imatch_string (imsg->command, *pp)) + { + match_c = 1; + break; + } + } + } + + if (match_c) + { + if (!imsg->channel) + match_h = 1; + else if (trigger->channels) + { + for(pp = trigger->channels; *pp; pp++) + { + if (c_imatch_string (imsg->channel, *pp)) + { + match_h = 1; + break; + } + } + } + } + + if (match_h) + { + if (!server) + match_s = 1; + else if (trigger->servers) + { + for(pp = trigger->servers; *pp; pp++) + { + if (c_imatch_string (server, *pp)) + { + match_s = 1; + break; + } + } + } + } + } + + *ret = ((match_c == 1) && (match_h == 1) && (match_s == 1)) ? 0 : 1; + } + else + *ret = 2; + + return imsg; +} + +/* + * weechat_trigger_msg: trigger handler + */ + +int +weechat_trigger_msg (t_weechat_plugin *plugin, + int argc, char **argv, + char *handler_args, void *handler_pointer) +{ + t_weechat_trigger *l; + int ret, i, j, match; + char *ccom, *tcom; + irc_msg *imsg; + + /* make C compiler happy */ + (void) argc; + (void) handler_args; + (void) handler_pointer; + + ret = PLUGIN_RC_OK; + l = weechat_trigger_list; + i = 0; + + while (l) + { + i++; + /* argv[0] = server name */ + imsg = weechat_trigger_match (l, argv[2], argv[0], &match); + + if (imsg && match == 2) + { + plugin->print_server (plugin, "Trigger error: error while parsing irc message : [%s]", argv[2]); + irc_msg_free (imsg); + } + else if (imsg && match == 0) + { + if (strcasecmp (l->action, "display") == 0) + plugin->print_server (plugin, "Trigger display: matching trigger number %d with message [%s]", i, argv[2]); + else if (strcasecmp (l->action, "ignore") == 0) + ret = PLUGIN_RC_OK_IGNORE_WEECHAT; + else if (strcasecmp (l->action, "highlight") == 0) + ret = PLUGIN_RC_OK_WITH_HIGHLIGHT; + else if (l->cmds && strcasecmp (l->action, "run") == 0) + { + for(j = 0; l->cmds[j]; j++) + { + /* formatting commands by replacing with defined values */ + ccom = strdup (l->cmds[j]); + if (ccom) + { + tcom = c_weechat_strreplace (ccom, "%uh", imsg->userhost == NULL ? "" : imsg->userhost); + if (tcom) + { + if (ccom) free (ccom); + ccom = tcom; + } + + tcom = c_weechat_strreplace (ccom, "%n", imsg->nick == NULL ? "" : imsg->nick); + if (tcom) + { + if (ccom) free (ccom); + ccom = tcom; + } + + tcom = c_weechat_strreplace (ccom, "%u", imsg->user == NULL ? "" : imsg->user); + if (tcom) + { + if (ccom) free (ccom); + ccom = tcom; + } + + tcom = c_weechat_strreplace (ccom, "%h", imsg->host == NULL ? "" : imsg->host); + if (tcom) + { + if (ccom) free (ccom); + ccom = tcom; + } + + tcom = c_weechat_strreplace (ccom, "%c", imsg->command == NULL ? "" : imsg->command); + if (tcom) + { + if (ccom) free (ccom); + ccom = tcom; + } + + tcom = c_weechat_strreplace (ccom, "%C", imsg->channel == NULL ? "" : imsg->channel); + if (tcom) + { + if (ccom) free (ccom); + ccom = tcom; + } + + tcom = c_weechat_strreplace (ccom, "%S", argv[0] == NULL ? "" : argv[0]); + if (tcom) + { + if (ccom) free (ccom); + ccom = tcom; + } + + tcom = c_weechat_strreplace (ccom, "%d", imsg->data == NULL ? "" : imsg->data); + if (tcom) + { + if (ccom) free (ccom); + ccom = tcom; + } + + plugin->exec_command (plugin, NULL, NULL, ccom); + free (ccom); + } + else + plugin->exec_command (plugin, NULL, NULL, l->cmds[j]); + } + } + irc_msg_free (imsg); + } + + l = l->next_trigger; + } + + return ret; +} + +/* + * weechat_trigger_tmsg: /tmsg command + */ + +int +weechat_trigger_tmsg (t_weechat_plugin *plugin, + int cmd_argc, char **cmd_argv, + char *handler_args, void *handler_pointer) +{ + int argc; + char **argv, *srv, *chan, *cmd; + + /* make C compiler happy */ + (void) cmd_argc; + (void) handler_args; + (void) handler_pointer; + + if (cmd_argv[2]) + argv = c_explode_string (cmd_argv[2], " ", 0, &argc); + else + { + argv = NULL; + argc = 0; + } + + if (argv && argc>=3) + { + srv = (strcmp (argv[0], "*") == 0) ? NULL : argv[0]; + chan = (strcmp (argv[1], "*") == 0) ? NULL : argv[1]; + + cmd = c_join_string (&argv[2], " "); + plugin->exec_command (plugin, srv, chan, (cmd == NULL) ? "" : cmd); + if (cmd) + c_free_joined_string (cmd); + } + else + plugin->print_server (plugin, "Trigger error: wrong argument count for command \"tmsg\""); + + if (argv) + c_free_exploded_string (argv); + + return PLUGIN_RC_OK; +} + + + +/* + * weechat_trigger_edit: load/save triggers from/in a file + */ +int +weechat_trigger_edit (t_weechat_plugin *plugin, int todo) +{ + t_weechat_trigger *l; + int len, ret, argc; + char **argv, *commands, *channels, *servers, *cmds; + char *weechat_dir, *triggerrc, line[1024], *p, *q; + FILE *f; + + ret = 0; + + if ((todo != CONF_LOAD) && (todo != CONF_SAVE)) + return -1; + + weechat_dir = plugin->get_info (plugin, "weechat_dir", NULL); + if (!weechat_dir) + return -1; + + len = strlen (weechat_dir) + strlen(DIR_SEP) + strlen(CONF_FILE) + 1; + triggerrc = (char *) malloc (len * sizeof(char)); + if (!triggerrc) + return -1; + + snprintf (triggerrc, len, "%s%s%s", weechat_dir, DIR_SEP, CONF_FILE); + + /* saving */ + if (todo == CONF_SAVE) + { + f = fopen (triggerrc, "w"); + if (!f) { + plugin->print_server (plugin, "Trigger plugin: error, unable to write file '%s'", triggerrc); + return -1; + } + + fprintf (f, "#\n"); + fprintf (f, "#WeeChat trigger plugin config file\n"); + fprintf (f, "# BE CAREFUL - DO NOT EDIT BY HAND\n"); + fprintf (f, "#\n\n"); + + l = weechat_trigger_list; + while (l) + { + commands = c_join_string (l->commands, ","); + channels = c_join_string (l->channels, ","); + servers = c_join_string (l->servers, ","); + cmds = c_join_string (l->cmds, ";"); + + if (strcasecmp (l->action, "run") == 0) + fprintf (f, "%s %s %s %s %s %s %s\n", + l->pattern, l->domain, commands, + channels, servers, l->action, cmds); + else + fprintf (f, "%s %s %s %s %s %s\n", + l->pattern, l->domain, commands, + channels, servers, l->action); + + ret++; + l = l->next_trigger; + } + fclose(f); + } + + /* loading */ + if (todo == CONF_LOAD) + { + f = fopen (triggerrc, "r"); + if (!f) { + plugin->print_server (plugin, "Trigger plugin: error, unable to read file '%s'", triggerrc); + return -1; + } + + while (!feof (f)) + { + p = fgets (line, sizeof (line), f); + if (p) + { + /* skip spaces ans tabs */ + while(p[0] == ' ' || p[0] == '\t') + p++; + /* skip comments and empty lines */ + if ((p[0] != '#') && (p[0] != '\r') && (p[0] != '\n')) + { + q = strrchr (p, '\n'); + if (q) + *q = '\0'; + argv = c_explode_string (p, " ", 0, &argc); + if (argv && argc >= 7) + { + if (weechat_trigger_add (argc, argv) == 0) + ret++; + else + plugin->print_server (plugin, "Trigger: failed to load trigger \"%s\"", p); + } + if (argv) + c_free_exploded_string (argv); + } + } + } + fclose(f); + } + + return ret; +} + +/* + * weechat_plugin_init: init trigger plugin + */ + +int +weechat_plugin_init (t_weechat_plugin *plugin) +{ + t_plugin_handler *cmd_handler_trigger, *cmd_handler_tmsg, *msg_handler; + int n; + + weechat_trigger_list = NULL; + weechat_trigger_last = NULL; + + /* loading saved triggers */ + n = weechat_trigger_edit (plugin, CONF_LOAD); + switch (n) + { + case -1: + plugin->print_server (plugin, "Trigger plugin starting: error"); + break; + case 0: + plugin->print_server (plugin, "Trigger plugin starting: no triggers found"); + break; + default: + plugin->print_server (plugin, "Trigger plugin starting: %d triggers found and loaded", n); + } + + /* add trigger command handler */ + cmd_handler_trigger = plugin->cmd_handler_add (plugin, "trigger", + "Trigger actions on IRC messages by nicks/hosts, irc messages, commands, channels and servers", + " [ list ] | [ add pattern domain [type(s) | command(s)] channel(s) server(s) [action [cmd]] ] | [ move from_num to_num ] | [ remove num ]", + " 'list': list triggers\n" + " 'add': create a new trigger\n" + " pattern: pattern to match\n" + " domain: domain where the pattern is searched (user, nick, userhost, msg)\n" + " type(s): messages types to trigger (privmsg, ctcp-$type, dcc, join, part, quit, ...).\n" + " command(s): irc commands to trigger.\n" + " channel(s): channels to trigger.\n" + " server(s): servers to trigger.\n" + " action: action to perform if trigger match (ignore, display, highlight, run)\n" + " cmd: irc or WeeChat command(s) to run if action is 'run'\n" + " possible replacements in command(s) :\n" + " %uh : userhost mask\n" + " %n : nickname\n" + " %u : username\n" + " %h : hostname\n" + " %c : irc command\n" + " %C : channel name\n" + " %S : server name\n" + " %d : extra data\n" + " 'move': move trigger position in trigger's list\n" + " from_num: current trigger position\n" + " to_num: future trigger position\n" + "'remove': remove a trigger\n" + " num: position of the trigger to remove\n" + "\n" + "Multiples values separated by commas can be set for fields : type(s), command(s), channel(s) and server(s).\n" + "It's possible to use wildcards for fields : pattern, type(s), command(s), channel(s) and server(s) options.\n\n", + "list|add|move|remove *|%n *|user|nick|userhost|msg *|%I|ctcp-action|ctcp-dcc|ctcp-sed|ctcp-finger|ctcp-version|ctcp-source|ctcp-userinfo|ctcp-clientinfo|ctcp-errmsg|ctcp-ping|ctcp-time *|%c *|%s ignore|display|highlight|run", + &weechat_trigger_cmd, + NULL, NULL); + + /* add messge modifier */ + msg_handler = plugin->msg_handler_add (plugin, "*", + &weechat_trigger_msg, + NULL, NULL); + + + /* add tmsg command handler */ + cmd_handler_tmsg = plugin->cmd_handler_add (plugin, "tmsg", + "Send a message to a channel", + " server receiver text", + "server: server ('*' = current server)\n" + "channel: channel ('*' = current channel)\n" + "text: text to send\n", + "*|%s *|%c", + &weechat_trigger_tmsg, + NULL, NULL); + + return PLUGIN_RC_OK; +} + +/* + * weechat_plugin_end: end trigger plugin + */ + +void +weechat_plugin_end (t_weechat_plugin *plugin) +{ + t_weechat_trigger *l; + int n; + + /* make C compiler happy */ + (void) plugin; + + n = weechat_trigger_edit (plugin, CONF_SAVE); + switch (n) + { + case -1: + plugin->print_server (plugin, "Trigger plugin ending: error"); + break; + case 0: + plugin->print_server (plugin, "Trigger plugin ending: no triggers to save"); + break; + default: + plugin->print_server (plugin, "Trigger plugin ending: saving %d triggers", n); + } + + while (weechat_trigger_list) + { + l = weechat_trigger_list; + weechat_trigger_list = weechat_trigger_list->next_trigger; + weechat_trigger_free (l); + } +} diff --git a/src/plugins/trigger/trigger.h b/src/plugins/trigger/trigger.h new file mode 100644 index 000000000..fcaaaf94a --- /dev/null +++ b/src/plugins/trigger/trigger.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2003-2006 by FlashCode <flashcode@flashtux.org> + * See README for License detail, AUTHORS for developers list. + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* weechat-trigger.h: Trigger plugin support for WeeChat */ + +#ifndef WEECHAT_TRIGGER__H +#define WEECHAT_TRIGGER__H 1 + +#define _PLUGIN_NAME "trigger" +#define _PLUGIN_VERSION "0.1" +#define _PLUGIN_DESC "Trigger plugin for WeeChat" + +char plugin_name[] = _PLUGIN_NAME; +char plugin_version[] = _PLUGIN_VERSION; +char plugin_description[] = _PLUGIN_DESC; + +typedef struct t_weechat_trigger +{ + char *pattern; + char *domain; + char **commands; + char **channels; + char **servers; + char *action; + char **cmds; + + struct t_weechat_trigger *prev_trigger; + struct t_weechat_trigger *next_trigger; +} t_weechat_trigger; + +#define CONF_FILE "trigger.rc" +#define CONF_SAVE 1 +#define CONF_LOAD 2 +#define DIR_SEP "/" + +#endif /* WEECHAT_TRIGGER__H */ |