This commit is contained in:
John R. Dennison 2026-02-27 02:46:04 -08:00 committed by GitHub
commit 1db0394c2f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 280 additions and 117 deletions

4
NEWS
View file

@ -3352,7 +3352,7 @@ v0.7.1 1999-03-08 Timo Sirainen <a@sicom.fi> [unstable]
You can use these levels, ALL is set by default: You can use these levels, ALL is set by default:
ALL, CRAP, PUBLIC, MSGS, NOTICES, WALLOPS, SNOTES, ACTIONS, DCC, ALL, CRAP, PUBLIC, MSGS, NOTICES, WALLOPS, SNOTES, ACTIONS, DCC,
CTCP, CLIENTNOTICES, CLIENTERRORS CTCP, CLIENTNOTICE, CLIENTERROR
+ Automatically create query window when received msg (option) + Automatically create query window when received msg (option)
+ No more "WHO: unknown commmand"s, all unknown commands are sent to + No more "WHO: unknown commmand"s, all unknown commands are sent to
server just like they were written server just like they were written
@ -3613,7 +3613,7 @@ v0.3.0 1999-01-18 Timo Sirainen <a@sicom.fi>
- /UNIGNORE <mask> <ignore level> - /UNIGNORE <mask> <ignore level>
- ignore page added to preferences - ignore page added to preferences
- ignore levels: ALL, CRAP, CHAN, PUBLIC, MSGS, NOTICES, WALLOPS, - 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 + autoignoring msg and ctcp flooders
+ options page added to preferences + options page added to preferences
+ invite lists (channel mode I) + invite lists (channel mode I)

View file

@ -18,6 +18,7 @@
-network: Matches only on the given network. -network: Matches only on the given network.
-channels: Matches only on the given channels. -channels: Matches only on the given channels.
-priority: The priority to use when multiple highlights match. -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 The text to highlight on; if no argument is given, the list of highlights
will be displayed. will be displayed.

View file

@ -7,6 +7,7 @@
-regexp: Indicates that the pattern is a regular expression. -regexp: Indicates that the pattern is a regular expression.
-full: Indicates that the pattern must match a full word. -full: Indicates that the pattern must match a full word.
-oldpattern: The text pattern to edit.
-pattern: The text pattern to ignore. -pattern: The text pattern to ignore.
-except: Negates the ignore. -except: Negates the ignore.
-replies: Also ignore nicknames who are talking to anyone who matches -replies: Also ignore nicknames who are talking to anyone who matches
@ -16,6 +17,7 @@
-time: The timeout to automatically remove the ignore. -time: The timeout to automatically remove the ignore.
Accepts units specified in days, hours, minutes, seconds, Accepts units specified in days, hours, minutes, seconds,
milliseconds, or no unit for 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 The mask, channels and levels to ignore; if no argument is provided, the
list of ignores will be displayed. list of ignores will be displayed.
@ -31,6 +33,7 @@
later be revealed using /WINDOW HIDELEVEL -HIDDEN later be revealed using /WINDOW HIDELEVEL -HIDDEN
The special level 'NOHILIGHT' can be used to suppress hilights without actually The special level 'NOHILIGHT' can be used to suppress hilights without actually
ignoring the message. ignoring the message.
The old pattern '*' can be used to edit the first ignore matching the mask.
%9Examples:%9 %9Examples:%9
@ -48,8 +51,8 @@
/IGNORE #irssi NO_ACT JOINS PARTS QUITS /IGNORE #irssi NO_ACT JOINS PARTS QUITS
/IGNORE mike NO_ACT -MSGS /IGNORE mike NO_ACT -MSGS
/IGNORE mike HIDDEN PUBLIC JOINS PARTS QUITS /IGNORE mike HIDDEN PUBLIC JOINS PARTS QUITS
/IGNORE -time 5days christmas PUBLICS /IGNORE -time 5days christmas PUBLIC
/IGNORE -time 300 mike PUBLICS /IGNORE -time 300 mike PUBLIC
%9See also:%9 ACCEPT, SILENCE, UNIGNORE %9See also:%9 ACCEPT, SILENCE, UNIGNORE

View file

@ -6,7 +6,7 @@
#define IRSSI_GLOBAL_CONFIG "irssi.conf" /* config file name in /etc/ */ #define IRSSI_GLOBAL_CONFIG "irssi.conf" /* config file name in /etc/ */
#define IRSSI_HOME_CONFIG "config" /* config file name in ~/.irssi/ */ #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_PORT 6667
#define DEFAULT_SERVER_ADD_TLS_PORT 6697 #define DEFAULT_SERVER_ADD_TLS_PORT 6697

View file

@ -243,23 +243,33 @@ IGNORE_REC *ignore_find_full(const char *servertag, const char *mask, const char
continue; continue;
} }
if ((flags & IGNORE_FIND_NOACT) && (rec->level & MSGLEVEL_NO_ACT) == 0) if (!(flags & IGNORE_FIND_ANY)) {
continue; if ((flags & IGNORE_FIND_NO_ACT) && (rec->level & MSGLEVEL_NO_ACT) == 0)
continue;
if (!(flags & IGNORE_FIND_NOACT) && (rec->level & MSGLEVEL_NO_ACT) != 0) if (!(flags & IGNORE_FIND_NO_ACT) && (rec->level & MSGLEVEL_NO_ACT) != 0)
continue; continue;
if ((flags & IGNORE_FIND_HIDDEN) && (rec->level & MSGLEVEL_HIDDEN) == 0) if ((flags & IGNORE_FIND_HIDDEN) && (rec->level & MSGLEVEL_HIDDEN) == 0)
continue; continue;
if (!(flags & IGNORE_FIND_HIDDEN) && (rec->level & MSGLEVEL_HIDDEN) != 0) if (!(flags & IGNORE_FIND_HIDDEN) && (rec->level & MSGLEVEL_HIDDEN) != 0)
continue; continue;
if ((flags & IGNORE_FIND_NOHILIGHT) && (rec->level & MSGLEVEL_NOHILIGHT) == 0) if ((flags & IGNORE_FIND_NOHILIGHT) &&
continue; (rec->level & MSGLEVEL_NOHILIGHT) == 0)
continue;
if (!(flags & IGNORE_FIND_NOHILIGHT) && (rec->level & MSGLEVEL_NOHILIGHT) != 0) if (!(flags & IGNORE_FIND_NOHILIGHT) &&
continue; (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) || if ((rec->mask == NULL && mask != NULL) ||
(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; 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) static void ignore_set_config(IGNORE_REC *rec)
{ {
CONFIG_NODE *node; CONFIG_NODE *node;
@ -333,6 +338,7 @@ static void ignore_set_config(IGNORE_REC *rec)
if (rec->unignore_time != 0) if (rec->unignore_time != 0)
iconfig_node_set_int(node, "unignore_time", rec->unignore_time); iconfig_node_set_int(node, "unignore_time", rec->unignore_time);
iconfig_node_set_str(node, "servertag", rec->servertag); iconfig_node_set_str(node, "servertag", rec->servertag);
iconfig_node_set_str(node, "comment", rec->comment);
if (rec->channels != NULL && *rec->channels != NULL) { if (rec->channels != NULL && *rec->channels != NULL) {
node = iconfig_node_section(node, "channels", NODE_TYPE_LIST); 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); if (rec->channels != NULL) g_strfreev(rec->channels);
g_free_not_null(rec->mask); g_free_not_null(rec->mask);
g_free_not_null(rec->servertag); g_free_not_null(rec->servertag);
g_free_not_null(rec->comment);
g_free_not_null(rec->pattern); g_free_not_null(rec->pattern);
g_free(rec); g_free(rec);
} }
void ignore_update_rec(IGNORE_REC *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 */ /* unignored everything */
ignore_remove_config(rec); ignore_remove_config(rec);
ignore_destroy(rec, TRUE); ignore_destroy(rec, TRUE);
@ -424,7 +431,7 @@ void ignore_update_rec(IGNORE_REC *rec)
ignore_init_rec(rec); ignore_init_rec(rec);
signal_emit("ignore changed", 1, rec); signal_emit("ignore changed", 1, rec);
} }
nickmatch_rebuild(nickmatch); nickmatch_rebuild(nickmatch);
} }
static int unignore_timeout(void) static int unignore_timeout(void)
@ -480,6 +487,7 @@ static void read_ignores(void)
rec->replies = config_node_get_bool(node, "replies", FALSE); rec->replies = config_node_get_bool(node, "replies", FALSE);
rec->unignore_time = config_node_get_int(node, "unignore_time", 0); rec->unignore_time = config_node_get_int(node, "unignore_time", 0);
rec->servertag = g_strdup(config_node_get_str(node, "servertag", 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); node = iconfig_node_section(node, "channels", -1);
if (node != NULL) rec->channels = config_node_get_list(node); 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) if (matches == NULL)
g_hash_table_remove(list, nick); g_hash_table_remove(list, nick);
else else
g_hash_table_insert(list, nick, matches); g_hash_table_insert(list, nick, matches);
} }
void ignore_init(void) void ignore_init(void)

View file

@ -9,6 +9,7 @@ struct _IGNORE_REC {
int level; /* ignore these levels */ int level; /* ignore these levels */
char *mask; /* nick mask */ char *mask; /* nick mask */
char *servertag; /* this is for autoignoring */ char *servertag; /* this is for autoignoring */
char *comment; /* comment, for internal use only */
char **channels; /* ignore only in these channels */ char **channels; /* ignore only in these channels */
char *pattern; /* text body must match this pattern */ 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 { enum {
IGNORE_FIND_PATTERN = 0x01, /* Match the pattern */ IGNORE_FIND_PATTERN = 0x01, /* Match the pattern */
IGNORE_FIND_NOACT = 0x02, /* Exclude the targets with NOACT level */ IGNORE_FIND_NO_ACT = 0x02, /* Find the targets with NO_ACT level */
IGNORE_FIND_HIDDEN = 0x04, /* Exclude the targets with HIDDEN level */ IGNORE_FIND_HIDDEN = 0x04, /* Find the targets with HIDDEN level */
IGNORE_FIND_NOHILIGHT = 0x08, /* Exclude the targets with NOHILIGHT 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, IGNORE_REC *ignore_find_full (const char *servertag, const char *mask, const char *pattern,
char **channels, const int flags); 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_add_rec(IGNORE_REC *rec);
void ignore_update_rec(IGNORE_REC *rec); void ignore_update_rec(IGNORE_REC *rec);

View file

@ -52,28 +52,63 @@ static const char *levels[] = {
/* clang-format on */ /* 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 level_get(const char *level)
{ {
int n, len, match; 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; return MSGLEVEL_ALL;
if (g_ascii_strcasecmp(level, "NEVER") == 0) if (g_ascii_strncasecmp("NEVER", level, MAX(len, 2)) == 0)
return MSGLEVEL_NEVER; 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; return MSGLEVEL_NO_ACT;
if (g_ascii_strcasecmp(level, "NOHILIGHT") == 0) if (g_ascii_strncasecmp("NOHILIGHT", level, MAX(len, 3)) == 0)
return MSGLEVEL_NOHILIGHT; return MSGLEVEL_NOHILIGHT;
if (g_ascii_strcasecmp(level, "HIDDEN") == 0) if (g_ascii_strncasecmp("HIDDEN", level, MAX(len, 3)) == 0)
return MSGLEVEL_HIDDEN; return MSGLEVEL_HIDDEN;
len = strlen(level);
if (len == 0) return 0;
/* partial match allowed, as long as it's the only one that matches */ /* partial match allowed, as long as it's the only one that matches */
match = 0; match = 0;
for (n = 0; levels[n] != NULL; n++) { for (n = 0; levels[n] != NULL; n++) {
@ -125,7 +160,8 @@ int level2bits(const char *level, int *errorp)
} else if (errorp != NULL) } else if (errorp != NULL)
*errorp = TRUE; *errorp = TRUE;
while (*str == ' ') str++; while (*str == ' ')
str++;
if (*str == '\0') break; if (*str == '\0') break;
ptr = str; ptr = str;
@ -157,7 +193,9 @@ char *bits2level(int bits)
} else { } else {
for (n = 0; levels[n] != NULL; n++) { for (n = 0; levels[n] != NULL; n++) {
if (bits & (1L << 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) int combine_level(int dest, const char *src)
{ {
char **list, **item, *itemname; char **list, **item, *itemname;
int itemlevel; int itemlevel, len;
g_return_val_if_fail(src != NULL, dest); 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++) { for (item = list; *item != NULL; item++) {
itemname = *item + (**item == '+' || **item == '-' || **item == '^' ? 1 : 0); itemname = *item + (**item == '+' || **item == '-' || **item == '^' ? 1 : 0);
itemlevel = level_get(itemname); 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; dest = 0;
else if (**item == '-') else if (**item == '-')
dest &= ~(itemlevel); dest &= ~(itemlevel);

View file

@ -1,6 +1,8 @@
#ifndef IRSSI_CORE_NICKMATCH_CACHE_H #ifndef IRSSI_CORE_NICKMATCH_CACHE_H
#define IRSSI_CORE_NICKMATCH_CACHE_H #define IRSSI_CORE_NICKMATCH_CACHE_H
#include <irssi/src/common.h>
typedef void (*NICKMATCH_REBUILD_FUNC) (GHashTable *list, typedef void (*NICKMATCH_REBUILD_FUNC) (GHashTable *list,
CHANNEL_REC *channel, NICK_REC *nick); CHANNEL_REC *channel, NICK_REC *nick);

View file

@ -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 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License along 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., with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#include "module.h" #include "module.h"
@ -649,7 +649,7 @@ static int only_nicks(const char *linestart)
int i = 1; int i = 1;
char prev; char prev;
// at the beginning of the line /* at the beginning of the line */
if (*linestart == '\0') { if (*linestart == '\0') {
return TRUE; return TRUE;
} }

View file

@ -70,6 +70,8 @@ static void ignore_print(int index, IGNORE_REC *rec)
g_string_append_printf(options, "-network %s ", rec->servertag); g_string_append_printf(options, "-network %s ", rec->servertag);
if (rec->pattern != NULL) if (rec->pattern != NULL)
g_string_append_printf(options, "-pattern %s ", rec->pattern); 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) { if (rec->unignore_time != 0) {
ts = *localtime(&rec->unignore_time); ts = *localtime(&rec->unignore_time);
strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &ts); 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); printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, TXT_IGNORE_FOOTER);
} }
/* SYNTAX: IGNORE [-regexp | -full] [-pattern <pattern>] [-except] [-replies] /* SYNTAX: IGNORE [-regexp | -full] [-oldpattern <pattern>] [-pattern <pattern>] [-except]
[-network <network>] [-channels <channel>] [-time <time>] <mask> [<levels>] [-replies] [-network <network>] [-channels <channel>] [-comment <comment>]
IGNORE [-regexp | -full] [-pattern <pattern>] [-except] [-replies] [-time <time>] <mask> [<levels>]
[-network <network>] [-time <time>] <channels> [<levels>] */ IGNORE [-regexp | -full] [-oldpattern <pattern>] [-pattern <pattern>] [-except]
[-replies] [-network <network>] [-time <time>] [-comment <comment>] <channels>
[<levels>]
IGNORE [-regexp | -noregexp | -full | -nofull] [-pattern <pattern>] [-except | -noexcept]
[-replies | -noreplies] [-network <network>] [-channels <channel>]
[-comment <comment] [-time <time>] [-mask <mask>] <id> [<levels>] */
/* NOTE: -network replaces the old -ircnet flag. */ /* NOTE: -network replaces the old -ircnet flag. */
static void cmd_ignore(const char *data) static void cmd_ignore(const char *data)
{ {
GHashTable *optlist; GHashTable *optlist;
IGNORE_REC *rec; IGNORE_REC *rec;
char *patternarg, *chanarg, *mask, *levels, *timestr, *servertag; char *oldpattern, *patternarg, *chanarg, *mask, *levels, *timestr, *servertag, *comment;
char **channels; char **channels;
void *free_arg; void *free_arg;
int new_ignore, msecs, level, flags; int new_ignore, modify_ignore, msecs, level, nolev, flags, exception;
if (*data == '\0') { if (*data == '\0') {
cmd_ignore_show(); cmd_ignore_show();
@ -138,16 +145,22 @@ static void cmd_ignore(const char *data)
"ignore", &optlist, &mask, &levels)) "ignore", &optlist, &mask, &levels))
return; return;
oldpattern = g_hash_table_lookup(optlist, "oldpattern");
patternarg = g_hash_table_lookup(optlist, "pattern"); patternarg = g_hash_table_lookup(optlist, "pattern");
chanarg = g_hash_table_lookup(optlist, "channels"); if (oldpattern == NULL)
oldpattern = patternarg;
chanarg = g_hash_table_lookup(optlist, "channels");
servertag = g_hash_table_lookup(optlist, "network"); servertag = g_hash_table_lookup(optlist, "network");
comment = g_hash_table_lookup(optlist, "comment");
exception = g_hash_table_lookup(optlist, "except") != NULL;
/* Allow -ircnet for backwards compatibility */ /* Allow -ircnet for backwards compatibility */
if (!servertag) if (!servertag)
servertag = g_hash_table_lookup(optlist, "ircnet"); servertag = g_hash_table_lookup(optlist, "ircnet");
if (*mask == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); if (*mask == '\0')
if (*levels == '\0') levels = "ALL"; cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
level = level2bits(levels, NULL); level = level2bits(levels, NULL);
nolev = (~combine_level(MSGLEVEL_ALL, levels)) & MSGLEVEL_ALL;
msecs = 0; msecs = 0;
timestr = g_hash_table_lookup(optlist, "time"); timestr = g_hash_table_lookup(optlist, "time");
@ -164,68 +177,150 @@ static void cmd_ignore(const char *data)
channels = (chanarg == NULL || *chanarg == '\0') ? NULL : channels = (chanarg == NULL || *chanarg == '\0') ? NULL :
g_strsplit(chanarg, ",", -1); g_strsplit(chanarg, ",", -1);
flags = IGNORE_FIND_PATTERN; if (is_numeric(mask, '\0')) {
if (level & MSGLEVEL_NO_ACT) /* with index number */
flags |= IGNORE_FIND_NOACT; GSList *tmp;
if (level & MSGLEVEL_HIDDEN)
flags |= IGNORE_FIND_HIDDEN;
if (level & MSGLEVEL_NOHILIGHT)
flags |= IGNORE_FIND_NOHILIGHT;
rec = ignore_find_full(servertag, mask, patternarg, channels, flags); if (oldpattern != patternarg) {
g_strfreev(channels);
cmd_param_error(CMDERR_OPTION_UNKNOWN);
}
if ((g_hash_table_lookup(optlist, "except") != NULL &&
g_hash_table_lookup(optlist, "noexcept") != NULL) ||
(g_hash_table_lookup(optlist, "regexp") != NULL &&
g_hash_table_lookup(optlist, "noregexp") != NULL) ||
(g_hash_table_lookup(optlist, "full") != NULL &&
g_hash_table_lookup(optlist, "nofull") != NULL) ||
(g_hash_table_lookup(optlist, "replies") != NULL &&
g_hash_table_lookup(optlist, "noreplies") != NULL)) {
g_strfreev(channels);
cmd_param_error(CMDERR_OPTION_AMBIGUOUS);
}
tmp = g_slist_nth(ignores, atoi(mask) - 1);
if (tmp == NULL) {
printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_IGNORE_NOT_FOUND, mask);
g_strfreev(channels);
cmd_params_free(free_arg);
return;
} else {
rec = tmp->data;
mask = g_hash_table_lookup(optlist, "mask");
modify_ignore = TRUE;
}
} else {
if (g_hash_table_lookup(optlist, "mask") != NULL) {
g_strfreev(channels);
cmd_param_error(CMDERR_OPTION_UNKNOWN);
}
flags = (oldpattern == NULL || g_strcmp0(oldpattern, "*") != 0) ?
IGNORE_FIND_PATTERN :
0;
if (level & MSGLEVEL_NO_ACT)
flags |= IGNORE_FIND_NO_ACT;
if (level & MSGLEVEL_HIDDEN)
flags |= IGNORE_FIND_HIDDEN;
if (level & MSGLEVEL_NOHILIGHT)
flags |= IGNORE_FIND_NOHILIGHT;
if (exception)
flags |= IGNORE_FIND_EXCEPT;
rec = ignore_find_full(servertag, mask, oldpattern, channels, flags);
modify_ignore = FALSE;
}
new_ignore = rec == NULL; new_ignore = rec == NULL;
if (rec == NULL) { if (rec == NULL) {
rec = g_new0(IGNORE_REC, 1); rec = g_new0(IGNORE_REC, 1);
}
if (new_ignore || (modify_ignore && mask != NULL)) {
rec->mask = mask == NULL || *mask == '\0' || rec->mask = mask == NULL || *mask == '\0' ||
g_strcmp0(mask, "*") == 0 ? NULL : g_strdup(mask); g_strcmp0(mask, "*") == 0 ? NULL : g_strdup(mask);
rec->channels = channels; }
if (new_ignore || (modify_ignore && chanarg != NULL)) {
rec->channels =
(channels == NULL || g_strcmp0(*channels, "*") == 0) ? NULL : channels;
} else { } else {
g_free_and_null(rec->pattern);
g_strfreev(channels); g_strfreev(channels);
} }
rec->level = combine_level(rec->level, levels); rec->level = combine_level(rec->level, levels);
if (rec->level == MSGLEVEL_NO_ACT) { if (new_ignore && rec->level == 0 && nolev != 0) {
/* If only NO_ACT was specified add all levels; it makes no
* sense on its own. */
rec->level |= MSGLEVEL_ALL;
}
if (rec->level == MSGLEVEL_HIDDEN) {
/* If only HIDDEN was specified add all levels; it makes no
* sense on its own. */
rec->level |= MSGLEVEL_ALL;
}
if (rec->level == MSGLEVEL_NOHILIGHT) {
/* If only NOHILIGHT was specified add all levels; it makes no
* sense on its own. */
rec->level |= MSGLEVEL_ALL;
}
if (new_ignore && rec->level == 0) {
/* tried to unignore levels from nonexisting ignore */ /* tried to unignore levels from nonexisting ignore */
printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_IGNORE_NOT_FOUND,
TXT_IGNORE_NOT_FOUND, rec->mask); mask == NULL ? (chanarg == NULL ? "*" : chanarg) : mask);
g_free(rec->mask); g_free(rec->mask);
g_strfreev(rec->channels); g_strfreev(rec->channels);
g_free(rec); g_free(rec);
cmd_params_free(free_arg); cmd_params_free(free_arg);
return; return;
} }
rec->servertag = (servertag == NULL || *servertag == '\0') ?
NULL : g_strdup(servertag); if (nolev == 0 &&
rec->pattern = (patternarg == NULL || *patternarg == '\0') ? (rec->level & ~(MSGLEVEL_NO_ACT | MSGLEVEL_HIDDEN | MSGLEVEL_NOHILIGHT)) == 0) {
NULL : g_strdup(patternarg); /* If only NO_ACT / HIDDEN / NOHILIGHT was specified, add all levels; it makes no
rec->exception = g_hash_table_lookup(optlist, "except") != NULL; * sense on its own. */
rec->regexp = g_hash_table_lookup(optlist, "regexp") != NULL; rec->level |= MSGLEVEL_ALL;
rec->fullword = g_hash_table_lookup(optlist, "full") != NULL; }
rec->replies = g_hash_table_lookup(optlist, "replies") != NULL;
if (new_ignore || (modify_ignore && servertag != NULL)) {
g_free(rec->servertag);
rec->servertag =
servertag == NULL || *servertag == '\0' || g_strcmp0(servertag, "*") == 0 ?
NULL :
g_strdup(servertag);
}
if (comment != NULL) {
g_free(rec->comment);
rec->comment = *comment == '\0' ? NULL : g_strdup(comment);
}
if (patternarg != NULL && g_strcmp0(patternarg, "*") != 0) {
g_free(rec->pattern);
rec->pattern = *patternarg == '\0' ? NULL : g_strdup(patternarg);
}
if (modify_ignore) {
if (g_hash_table_lookup(optlist, "except") != NULL)
rec->exception = TRUE;
else if (g_hash_table_lookup(optlist, "noexcept") != NULL)
rec->exception = FALSE;
} else {
rec->exception = exception;
}
if (modify_ignore) {
if (g_hash_table_lookup(optlist, "regexp") != NULL)
rec->regexp = TRUE;
else if (g_hash_table_lookup(optlist, "noregexp") != NULL)
rec->regexp = FALSE;
if (g_hash_table_lookup(optlist, "full") != NULL)
rec->fullword = TRUE;
else if (g_hash_table_lookup(optlist, "nofull") != NULL)
rec->fullword = FALSE;
if (g_hash_table_lookup(optlist, "replies") != NULL)
rec->replies = TRUE;
else if (g_hash_table_lookup(optlist, "noreplies") != NULL)
rec->replies = FALSE;
} else if (new_ignore || patternarg != NULL) {
rec->regexp = g_hash_table_lookup(optlist, "regexp") != NULL;
rec->fullword = g_hash_table_lookup(optlist, "full") != NULL;
rec->replies = g_hash_table_lookup(optlist, "replies") != NULL;
}
if (msecs != 0) if (msecs != 0)
rec->unignore_time = time(NULL)+msecs/1000; rec->unignore_time = time(NULL)+msecs/1000;
else if (modify_ignore && timestr != NULL)
rec->unignore_time = 0;
if (new_ignore) if (new_ignore)
ignore_add_rec(rec); ignore_add_rec(rec);
@ -266,10 +361,7 @@ static void cmd_unignore(const char *data)
chans[0] = mask; chans[0] = mask;
mask = NULL; mask = NULL;
} }
rec = ignore_find_full("*", mask, NULL, (char **) chans, 0); rec = ignore_find_full("*", mask, NULL, (char **) chans, IGNORE_FIND_ANY);
if (rec == NULL) {
rec = ignore_find_full("*", mask, NULL, (char **) chans, IGNORE_FIND_NOACT);
}
} }
if (rec != NULL) { if (rec != NULL) {
@ -305,7 +397,10 @@ void fe_ignore_init(void)
signal_add("ignore created", (SIGNAL_FUNC) sig_ignore_created); signal_add("ignore created", (SIGNAL_FUNC) sig_ignore_created);
signal_add("ignore changed", (SIGNAL_FUNC) sig_ignore_created); signal_add("ignore changed", (SIGNAL_FUNC) sig_ignore_created);
command_set_options("ignore", "regexp full except replies -network -ircnet -time -pattern -channels"); command_set_options(
"ignore",
"regexp noregexp full nofull except noexcept replies noreplies -network ~-ircnet -time "
"-oldpattern -pattern -mask -channels -comment");
} }
void fe_ignore_deinit(void) void fe_ignore_deinit(void)

View file

@ -81,6 +81,8 @@ static void hilight_add_config(HILIGHT_REC *rec)
if (rec->regexp) iconfig_node_set_bool(node, "regexp", TRUE); if (rec->regexp) iconfig_node_set_bool(node, "regexp", TRUE);
if (rec->case_sensitive) iconfig_node_set_bool(node, "matchcase", TRUE); if (rec->case_sensitive) iconfig_node_set_bool(node, "matchcase", TRUE);
if (rec->servertag) iconfig_node_set_str(node, "servertag", rec->servertag); if (rec->servertag) iconfig_node_set_str(node, "servertag", rec->servertag);
if (rec->comment)
iconfig_node_set_str(node, "comment", rec->comment);
if (rec->channels != NULL && *rec->channels != NULL) { if (rec->channels != NULL && *rec->channels != NULL) {
node = iconfig_node_section(node, "channels", NODE_TYPE_LIST); node = iconfig_node_section(node, "channels", NODE_TYPE_LIST);
@ -107,6 +109,7 @@ static void hilight_destroy(HILIGHT_REC *rec)
g_free_not_null(rec->color); g_free_not_null(rec->color);
g_free_not_null(rec->act_color); g_free_not_null(rec->act_color);
g_free_not_null(rec->servertag); g_free_not_null(rec->servertag);
g_free_not_null(rec->comment);
g_free(rec->text); g_free(rec->text);
g_free(rec); g_free(rec);
} }
@ -505,7 +508,7 @@ static void read_hilight_config(void)
CONFIG_NODE *node; CONFIG_NODE *node;
HILIGHT_REC *rec; HILIGHT_REC *rec;
GSList *tmp; GSList *tmp;
char *text, *color, *servertag; char *text, *color, *servertag, *comment;
hilights_destroy_all(); hilights_destroy_all();
@ -551,6 +554,8 @@ static void read_hilight_config(void)
servertag = config_node_get_str(node, "servertag", NULL); servertag = config_node_get_str(node, "servertag", NULL);
rec->servertag = servertag == NULL || *servertag == '\0' ? NULL : rec->servertag = servertag == NULL || *servertag == '\0' ? NULL :
g_strdup(servertag); g_strdup(servertag);
comment = config_node_get_str(node, "comment", NULL);
rec->comment = comment == NULL || *comment == '\0' ? NULL : g_strdup(comment);
hilight_init_rec(rec); hilight_init_rec(rec);
node = iconfig_node_section(node, "channels", -1); node = iconfig_node_section(node, "channels", -1);
@ -588,6 +593,8 @@ static void hilight_print(int index, HILIGHT_REC *rec)
g_string_append_printf(options, "-priority %d ", rec->priority); g_string_append_printf(options, "-priority %d ", rec->priority);
if (rec->servertag != NULL) if (rec->servertag != NULL)
g_string_append_printf(options, "-network %s ", rec->servertag); g_string_append_printf(options, "-network %s ", rec->servertag);
if (rec->comment != NULL)
g_string_append_printf(options, "-comment %s ", rec->comment);
if (rec->color != NULL) if (rec->color != NULL)
g_string_append_printf(options, "-color %s ", rec->color); g_string_append_printf(options, "-color %s ", rec->color);
if (rec->act_color != NULL) if (rec->act_color != NULL)
@ -626,12 +633,13 @@ static void cmd_hilight_show(void)
/* SYNTAX: HILIGHT [-nick | -word | -line] [-mask | -full | -matchcase | -regexp] /* SYNTAX: HILIGHT [-nick | -word | -line] [-mask | -full | -matchcase | -regexp]
[-color <color>] [-actcolor <color>] [-level <level>] [-priority <number>] [-color <color>] [-actcolor <color>] [-level <level>] [-priority <number>]
[-network <network>] [-channels <channels>] <text> */ [-network <network>] [-channels <channels>] [-comment <comment>] <text> */
static void cmd_hilight(const char *data) static void cmd_hilight(const char *data)
{ {
GHashTable *optlist; GHashTable *optlist;
HILIGHT_REC *rec; HILIGHT_REC *rec;
char *colorarg, *actcolorarg, *levelarg, *priorityarg, *chanarg, *text, *servertag; char *colorarg, *actcolorarg, *levelarg, *priorityarg, *chanarg, *text, *servertag,
*comment;
char **channels; char **channels;
void *free_arg; void *free_arg;
@ -652,6 +660,7 @@ static void cmd_hilight(const char *data)
colorarg = g_hash_table_lookup(optlist, "color"); colorarg = g_hash_table_lookup(optlist, "color");
actcolorarg = g_hash_table_lookup(optlist, "actcolor"); actcolorarg = g_hash_table_lookup(optlist, "actcolor");
servertag = g_hash_table_lookup(optlist, "network"); servertag = g_hash_table_lookup(optlist, "network");
comment = g_hash_table_lookup(optlist, "comment");
if (*text == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); if (*text == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
@ -709,6 +718,11 @@ static void cmd_hilight(const char *data)
if (*servertag != '\0') if (*servertag != '\0')
rec->servertag = g_strdup(servertag); rec->servertag = g_strdup(servertag);
} }
if (comment != NULL) {
g_free_and_null(rec->comment);
if (*comment != '\0')
rec->comment = g_strdup(comment);
}
hilight_create(rec); hilight_create(rec);
@ -802,7 +816,8 @@ void hilight_text_init(void)
command_bind("hilight", NULL, (SIGNAL_FUNC) cmd_hilight); command_bind("hilight", NULL, (SIGNAL_FUNC) cmd_hilight);
command_bind("dehilight", NULL, (SIGNAL_FUNC) cmd_dehilight); command_bind("dehilight", NULL, (SIGNAL_FUNC) cmd_dehilight);
command_set_options("hilight", "-color -actcolor -level -priority -network -channels nick word line mask full regexp matchcase"); command_set_options("hilight", "-color -actcolor -level -priority -network -channels "
"-comment nick word line mask full regexp matchcase");
} }
void hilight_text_deinit(void) void hilight_text_deinit(void)

View file

@ -23,6 +23,7 @@ struct _HILIGHT_REC {
unsigned int case_sensitive:1;/* `text' must match case */ unsigned int case_sensitive:1;/* `text' must match case */
Regex *preg; Regex *preg;
char *servertag; char *servertag;
char *comment;
}; };
extern GSList *hilights; extern GSList *hilights;

View file

@ -186,10 +186,10 @@ void fe_irc_server_init(void)
command_bind("server list", NULL, (SIGNAL_FUNC) cmd_server_list); command_bind("server list", NULL, (SIGNAL_FUNC) cmd_server_list);
command_set_options("server add", command_set_options("server add",
"-ircnet -network -cmdspeed -cmdmax -querychans starttls " "~-ircnet -network -cmdspeed -cmdmax -querychans starttls "
"nostarttls disallow_starttls nodisallow_starttls cap nocap"); "nostarttls disallow_starttls nodisallow_starttls cap nocap");
command_set_options("server modify", command_set_options("server modify",
"-ircnet -network -cmdspeed -cmdmax -querychans starttls nostarttls " "~-ircnet -network -cmdspeed -cmdmax -querychans starttls nostarttls "
"disallow_starttls nodisallow_starttls cap nocap"); "disallow_starttls nodisallow_starttls cap nocap");
} }

View file

@ -1056,7 +1056,7 @@ void irc_commands_init(void)
signal_add("whois end", (SIGNAL_FUNC) event_end_of_whois); signal_add("whois end", (SIGNAL_FUNC) event_end_of_whois);
signal_add("whowas event", (SIGNAL_FUNC) event_whowas); signal_add("whowas event", (SIGNAL_FUNC) event_whowas);
command_set_options("connect", "+ircnet starttls disallow_starttls nocap"); command_set_options("connect", "~+ircnet starttls disallow_starttls nocap");
command_set_options("topic", "delete"); command_set_options("topic", "delete");
command_set_options("list", "yes"); command_set_options("list", "yes");
command_set_options("away", "one all"); command_set_options("away", "one all");