diff --git a/NEWS b/NEWS index 571d251e..30208f39 100644 --- a/NEWS +++ b/NEWS @@ -3352,7 +3352,7 @@ v0.7.1 1999-03-08 Timo Sirainen [unstable] You can use these levels, ALL is set by default: ALL, CRAP, PUBLIC, MSGS, NOTICES, WALLOPS, SNOTES, ACTIONS, DCC, - CTCP, CLIENTNOTICES, CLIENTERRORS + CTCP, CLIENTNOTICE, CLIENTERROR + Automatically create query window when received msg (option) + No more "WHO: unknown commmand"s, all unknown commands are sent to server just like they were written @@ -3613,7 +3613,7 @@ v0.3.0 1999-01-18 Timo Sirainen - /UNIGNORE - ignore page added to preferences - ignore levels: ALL, CRAP, CHAN, PUBLIC, MSGS, NOTICES, WALLOPS, - SNOTES, ACTIONS, DCC, CTCP, CLIENTNOTICES, CLIENTERRORS + SNOTES, ACTIONS, DCC, CTCP, CLIENTNOTICE, CLIENTERROR + autoignoring msg and ctcp flooders + options page added to preferences + invite lists (channel mode I) diff --git a/docs/help/in/hilight.in b/docs/help/in/hilight.in index 49a73a7b..06809edf 100644 --- a/docs/help/in/hilight.in +++ b/docs/help/in/hilight.in @@ -18,6 +18,7 @@ -network: Matches only on the given network. -channels: Matches only on the given channels. -priority: The priority to use when multiple highlights match. + -comment: Comment for internal use. The text to highlight on; if no argument is given, the list of highlights will be displayed. diff --git a/docs/help/in/ignore.in b/docs/help/in/ignore.in index 26dd63bb..af88628f 100644 --- a/docs/help/in/ignore.in +++ b/docs/help/in/ignore.in @@ -7,6 +7,7 @@ -regexp: Indicates that the pattern is a regular expression. -full: Indicates that the pattern must match a full word. + -oldpattern: The text pattern to edit. -pattern: The text pattern to ignore. -except: Negates the ignore. -replies: Also ignore nicknames who are talking to anyone who matches @@ -16,6 +17,7 @@ -time: The timeout to automatically remove the ignore. Accepts units specified in days, hours, minutes, seconds, milliseconds, or no unit for seconds. + -comment: Comment for internal use. The mask, channels and levels to ignore; if no argument is provided, the list of ignores will be displayed. @@ -31,6 +33,7 @@ later be revealed using /WINDOW HIDELEVEL -HIDDEN The special level 'NOHILIGHT' can be used to suppress hilights without actually ignoring the message. + The old pattern '*' can be used to edit the first ignore matching the mask. %9Examples:%9 @@ -48,8 +51,8 @@ /IGNORE #irssi NO_ACT JOINS PARTS QUITS /IGNORE mike NO_ACT -MSGS /IGNORE mike HIDDEN PUBLIC JOINS PARTS QUITS - /IGNORE -time 5days christmas PUBLICS - /IGNORE -time 300 mike PUBLICS + /IGNORE -time 5days christmas PUBLIC + /IGNORE -time 300 mike PUBLIC %9See also:%9 ACCEPT, SILENCE, UNIGNORE diff --git a/src/common.h b/src/common.h index 4e9b5c79..9e2aa593 100644 --- a/src/common.h +++ b/src/common.h @@ -6,7 +6,7 @@ #define IRSSI_GLOBAL_CONFIG "irssi.conf" /* config file name in /etc/ */ #define IRSSI_HOME_CONFIG "config" /* config file name in ~/.irssi/ */ -#define IRSSI_ABI_VERSION 58 +#define IRSSI_ABI_VERSION 59 #define DEFAULT_SERVER_ADD_PORT 6667 #define DEFAULT_SERVER_ADD_TLS_PORT 6697 diff --git a/src/core/ignore.c b/src/core/ignore.c index da892c1e..e2ff818d 100644 --- a/src/core/ignore.c +++ b/src/core/ignore.c @@ -243,23 +243,33 @@ IGNORE_REC *ignore_find_full(const char *servertag, const char *mask, const char continue; } - if ((flags & IGNORE_FIND_NOACT) && (rec->level & MSGLEVEL_NO_ACT) == 0) - continue; + if (!(flags & IGNORE_FIND_ANY)) { + if ((flags & IGNORE_FIND_NO_ACT) && (rec->level & MSGLEVEL_NO_ACT) == 0) + continue; - if (!(flags & IGNORE_FIND_NOACT) && (rec->level & MSGLEVEL_NO_ACT) != 0) - continue; + if (!(flags & IGNORE_FIND_NO_ACT) && (rec->level & MSGLEVEL_NO_ACT) != 0) + continue; - if ((flags & IGNORE_FIND_HIDDEN) && (rec->level & MSGLEVEL_HIDDEN) == 0) - continue; + if ((flags & IGNORE_FIND_HIDDEN) && (rec->level & MSGLEVEL_HIDDEN) == 0) + continue; - if (!(flags & IGNORE_FIND_HIDDEN) && (rec->level & MSGLEVEL_HIDDEN) != 0) - continue; + if (!(flags & IGNORE_FIND_HIDDEN) && (rec->level & MSGLEVEL_HIDDEN) != 0) + continue; - if ((flags & IGNORE_FIND_NOHILIGHT) && (rec->level & MSGLEVEL_NOHILIGHT) == 0) - continue; + if ((flags & IGNORE_FIND_NOHILIGHT) && + (rec->level & MSGLEVEL_NOHILIGHT) == 0) + continue; - if (!(flags & IGNORE_FIND_NOHILIGHT) && (rec->level & MSGLEVEL_NOHILIGHT) != 0) - continue; + if (!(flags & IGNORE_FIND_NOHILIGHT) && + (rec->level & MSGLEVEL_NOHILIGHT) != 0) + continue; + + if ((flags & IGNORE_FIND_EXCEPT) && (rec->exception == 0)) + continue; + + if (!(flags & IGNORE_FIND_EXCEPT) && (rec->exception != 0)) + continue; + } if ((rec->mask == NULL && mask != NULL) || (rec->mask != NULL && mask == NULL)) @@ -303,11 +313,6 @@ IGNORE_REC *ignore_find_full(const char *servertag, const char *mask, const char return NULL; } -IGNORE_REC *ignore_find(const char *servertag, const char *mask, char **channels) -{ - return ignore_find_full(servertag, mask, NULL, channels, 0); -} - static void ignore_set_config(IGNORE_REC *rec) { CONFIG_NODE *node; @@ -333,6 +338,7 @@ static void ignore_set_config(IGNORE_REC *rec) if (rec->unignore_time != 0) iconfig_node_set_int(node, "unignore_time", rec->unignore_time); iconfig_node_set_str(node, "servertag", rec->servertag); + iconfig_node_set_str(node, "comment", rec->comment); if (rec->channels != NULL && *rec->channels != NULL) { node = iconfig_node_section(node, "channels", NODE_TYPE_LIST); @@ -403,13 +409,14 @@ static void ignore_destroy(IGNORE_REC *rec, int send_signal) if (rec->channels != NULL) g_strfreev(rec->channels); g_free_not_null(rec->mask); g_free_not_null(rec->servertag); + g_free_not_null(rec->comment); g_free_not_null(rec->pattern); g_free(rec); } void ignore_update_rec(IGNORE_REC *rec) { - if (rec->level == 0) { + if ((rec->level & ~(MSGLEVEL_NO_ACT | MSGLEVEL_HIDDEN | MSGLEVEL_NOHILIGHT)) == 0) { /* unignored everything */ ignore_remove_config(rec); ignore_destroy(rec, TRUE); @@ -424,7 +431,7 @@ void ignore_update_rec(IGNORE_REC *rec) ignore_init_rec(rec); signal_emit("ignore changed", 1, rec); } - nickmatch_rebuild(nickmatch); + nickmatch_rebuild(nickmatch); } static int unignore_timeout(void) @@ -480,6 +487,7 @@ static void read_ignores(void) rec->replies = config_node_get_bool(node, "replies", FALSE); rec->unignore_time = config_node_get_int(node, "unignore_time", 0); rec->servertag = g_strdup(config_node_get_str(node, "servertag", 0)); + rec->comment = g_strdup(config_node_get_str(node, "comment", 0)); node = iconfig_node_section(node, "channels", -1); if (node != NULL) rec->channels = config_node_get_list(node); @@ -518,8 +526,8 @@ static void ignore_nick_cache(GHashTable *list, CHANNEL_REC *channel, if (matches == NULL) g_hash_table_remove(list, nick); - else - g_hash_table_insert(list, nick, matches); + else + g_hash_table_insert(list, nick, matches); } void ignore_init(void) diff --git a/src/core/ignore.h b/src/core/ignore.h index 739514a9..7509f207 100644 --- a/src/core/ignore.h +++ b/src/core/ignore.h @@ -9,6 +9,7 @@ struct _IGNORE_REC { int level; /* ignore these levels */ char *mask; /* nick mask */ char *servertag; /* this is for autoignoring */ + char *comment; /* comment, for internal use only */ char **channels; /* ignore only in these channels */ char *pattern; /* text body must match this pattern */ @@ -32,18 +33,16 @@ int ignore_check_plus(SERVER_REC *server, const char *nick, const char *host, enum { IGNORE_FIND_PATTERN = 0x01, /* Match the pattern */ - IGNORE_FIND_NOACT = 0x02, /* Exclude the targets with NOACT level */ - IGNORE_FIND_HIDDEN = 0x04, /* Exclude the targets with HIDDEN level */ - IGNORE_FIND_NOHILIGHT = 0x08, /* Exclude the targets with NOHILIGHT level */ + IGNORE_FIND_NO_ACT = 0x02, /* Find the targets with NO_ACT level */ + IGNORE_FIND_HIDDEN = 0x04, /* Find the targets with HIDDEN level */ + IGNORE_FIND_NOHILIGHT = 0x08, /* Find the targets with NOHILIGHT level */ + IGNORE_FIND_EXCEPT = 0x10, /* Find negated ignore */ + IGNORE_FIND_ANY = 0x20, /* Find ignore based on mask only */ }; IGNORE_REC *ignore_find_full (const char *servertag, const char *mask, const char *pattern, char **channels, const int flags); -/* Convenience wrappers around ignore_find_full, for compatibility purpose */ - -IGNORE_REC *ignore_find(const char *servertag, const char *mask, char **channels); - void ignore_add_rec(IGNORE_REC *rec); void ignore_update_rec(IGNORE_REC *rec); diff --git a/src/core/levels.c b/src/core/levels.c index 0cd99b10..c45cda1a 100644 --- a/src/core/levels.c +++ b/src/core/levels.c @@ -52,28 +52,63 @@ static const char *levels[] = { /* clang-format on */ }; +/* the levels which should be printed without plural-s */ +static char levels_no_s[] = { + /* clang-format off */ + 0, + 0, + 1 /* PUBLIC */, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1 /* CLIENTNOTICE */, + 0, + 1 /* CLIENTERROR */, + 1 /* HILIGHT */, + -1 + /* clang-format on */ +}; + +G_STATIC_ASSERT(G_N_ELEMENTS(levels) == G_N_ELEMENTS(levels_no_s)); + int level_get(const char *level) { int n, len, match; - if (g_ascii_strcasecmp(level, "ALL") == 0 || g_strcmp0(level, "*") == 0) + len = strlen(level); + if (len == 0) + return 0; + + /* partial match allowed, if it uniquely identifies the special level */ + if (g_ascii_strncasecmp("ALL", level, MAX(len, 2)) == 0 || g_strcmp0(level, "*") == 0) return MSGLEVEL_ALL; - if (g_ascii_strcasecmp(level, "NEVER") == 0) + if (g_ascii_strncasecmp("NEVER", level, MAX(len, 2)) == 0) return MSGLEVEL_NEVER; - if (g_ascii_strcasecmp(level, "NO_ACT") == 0) + if (g_ascii_strncasecmp("NO_ACT", level, MAX(len, 3)) == 0 || + g_ascii_strncasecmp("NOACT", level, MAX(len, 3)) == 0) return MSGLEVEL_NO_ACT; - if (g_ascii_strcasecmp(level, "NOHILIGHT") == 0) + if (g_ascii_strncasecmp("NOHILIGHT", level, MAX(len, 3)) == 0) return MSGLEVEL_NOHILIGHT; - if (g_ascii_strcasecmp(level, "HIDDEN") == 0) + if (g_ascii_strncasecmp("HIDDEN", level, MAX(len, 3)) == 0) return MSGLEVEL_HIDDEN; - len = strlen(level); - if (len == 0) return 0; - /* partial match allowed, as long as it's the only one that matches */ match = 0; for (n = 0; levels[n] != NULL; n++) { @@ -125,7 +160,8 @@ int level2bits(const char *level, int *errorp) } else if (errorp != NULL) *errorp = TRUE; - while (*str == ' ') str++; + while (*str == ' ') + str++; if (*str == '\0') break; ptr = str; @@ -157,7 +193,9 @@ char *bits2level(int bits) } else { for (n = 0; levels[n] != NULL; n++) { if (bits & (1L << n)) - g_string_append_printf(str, "%s ", levels[n]); + g_string_append_printf(str, "%.*s ", + (int) (strlen(levels[n]) - levels_no_s[n]), + levels[n]); } } @@ -178,7 +216,7 @@ char *bits2level(int bits) int combine_level(int dest, const char *src) { char **list, **item, *itemname; - int itemlevel; + int itemlevel, len; g_return_val_if_fail(src != NULL, dest); @@ -186,8 +224,9 @@ int combine_level(int dest, const char *src) for (item = list; *item != NULL; item++) { itemname = *item + (**item == '+' || **item == '-' || **item == '^' ? 1 : 0); itemlevel = level_get(itemname); + len = strlen(itemname); - if (g_ascii_strcasecmp(itemname, "NONE") == 0) + if (g_ascii_strncasecmp("NONE", itemname, MAX(len, 3)) == 0) dest = 0; else if (**item == '-') dest &= ~(itemlevel); diff --git a/src/core/nickmatch-cache.h b/src/core/nickmatch-cache.h index bae99c1d..9adc67b0 100644 --- a/src/core/nickmatch-cache.h +++ b/src/core/nickmatch-cache.h @@ -1,6 +1,8 @@ #ifndef IRSSI_CORE_NICKMATCH_CACHE_H #define IRSSI_CORE_NICKMATCH_CACHE_H +#include + typedef void (*NICKMATCH_REBUILD_FUNC) (GHashTable *list, CHANNEL_REC *channel, NICK_REC *nick); diff --git a/src/fe-common/core/chat-completion.c b/src/fe-common/core/chat-completion.c index be16db7e..5c8a7d0c 100644 --- a/src/fe-common/core/chat-completion.c +++ b/src/fe-common/core/chat-completion.c @@ -1,21 +1,21 @@ /* - chat-completion.c : irssi +chat-completion.c : irssi - Copyright (C) 1999-2000 Timo Sirainen + Copyright (C) 1999-2000 Timo Sirainen - 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 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. + 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "module.h" @@ -649,7 +649,7 @@ static int only_nicks(const char *linestart) int i = 1; char prev; - // at the beginning of the line + /* at the beginning of the line */ if (*linestart == '\0') { return TRUE; } diff --git a/src/fe-common/core/fe-ignore.c b/src/fe-common/core/fe-ignore.c index 3594b6f6..cf5feee2 100644 --- a/src/fe-common/core/fe-ignore.c +++ b/src/fe-common/core/fe-ignore.c @@ -70,6 +70,8 @@ static void ignore_print(int index, IGNORE_REC *rec) g_string_append_printf(options, "-network %s ", rec->servertag); if (rec->pattern != NULL) g_string_append_printf(options, "-pattern %s ", rec->pattern); + if (rec->comment != NULL) + g_string_append_printf(options, "-comment %s ", rec->comment); if (rec->unignore_time != 0) { ts = *localtime(&rec->unignore_time); strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &ts); @@ -114,19 +116,24 @@ static void cmd_ignore_show(void) printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, TXT_IGNORE_FOOTER); } -/* SYNTAX: IGNORE [-regexp | -full] [-pattern ] [-except] [-replies] - [-network ] [-channels ] [-time