From 609f3ba6c2db4f04e1e11304459d4fc42babd8ff Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Sun, 3 Jan 2016 19:49:18 +0100 Subject: [PATCH 1/2] Clean up the ignore_find API to make it more powerful. This way we prevent the creation of duplicate ignores since the old code skipped the ignore_find call when a pattern was specified. It should also cover all the cases where the ignores would be wrongly overwritten, such as the case outlined in #78. --- src/core/ignore.c | 28 ++++++++++++++++------------ src/core/ignore.h | 9 +++++++-- src/fe-common/core/fe-ignore.c | 8 ++++---- src/irc/flood/autoignore.c | 2 +- 4 files changed, 28 insertions(+), 19 deletions(-) diff --git a/src/core/ignore.c b/src/core/ignore.c index fd3c8a38..ee9e180d 100644 --- a/src/core/ignore.c +++ b/src/core/ignore.c @@ -186,15 +186,8 @@ int ignore_check(SERVER_REC *server, const char *nick, const char *host, return ignore_check_replies(chanrec, text, level); } -IGNORE_REC *ignore_find(const char *servertag, const char *mask, - char **channels) -{ - return ignore_find_noact(servertag, mask, channels, 0); -} - - -IGNORE_REC *ignore_find_noact(const char *servertag, const char *mask, - char **channels, int noact) +IGNORE_REC *ignore_find(const char *servertag, const char *mask, const char *pattern, + char **channels, const int flags) { GSList *tmp; char **chan; @@ -216,18 +209,29 @@ IGNORE_REC *ignore_find_noact(const char *servertag, const char *mask, continue; } - if (noact && (rec->level & MSGLEVEL_NO_ACT) == 0) + if ((flags & IGNORE_FIND_NOACT) && (rec->level & MSGLEVEL_NO_ACT) == 0) continue; - if (!noact && (rec->level & MSGLEVEL_NO_ACT) != 0) + if (!(flags & IGNORE_FIND_NOACT) && (rec->level & MSGLEVEL_NO_ACT) != 0) continue; if ((rec->mask == NULL && mask != NULL) || - (rec->mask != NULL && mask == NULL)) continue; + (rec->mask != NULL && mask == NULL)) + continue; if (rec->mask != NULL && g_ascii_strcasecmp(rec->mask, mask) != 0) continue; + /* match the pattern too if requested */ + if (flags & IGNORE_FIND_PATTERN) { + if ((rec->pattern == NULL && pattern != NULL) || + (rec->pattern != NULL && pattern == NULL)) + continue; + + if (rec->pattern != NULL && g_ascii_strcasecmp(rec->pattern, pattern) != 0) + continue; + } + if ((channels == NULL && rec->channels == NULL)) return rec; /* no channels - ok */ diff --git a/src/core/ignore.h b/src/core/ignore.h index 46025d4c..0901e795 100644 --- a/src/core/ignore.h +++ b/src/core/ignore.h @@ -31,8 +31,13 @@ extern GSList *ignores; int ignore_check(SERVER_REC *server, const char *nick, const char *host, const char *channel, const char *text, int level); -IGNORE_REC *ignore_find(const char *servertag, const char *mask, char **channels); -IGNORE_REC *ignore_find_noact(const char *servertag, const char *mask, char **channels, int noact); +enum { + IGNORE_FIND_PATTERN = 0x01, // Match the pattern + IGNORE_FIND_NOACT = 0x02, // Exclude the targets with NOACT level +}; + +IGNORE_REC *ignore_find(const char *servertag, const char *mask, const char *pattern, + char **channels, const int flags); void ignore_add_rec(IGNORE_REC *rec); void ignore_update_rec(IGNORE_REC *rec); diff --git a/src/fe-common/core/fe-ignore.c b/src/fe-common/core/fe-ignore.c index d2f9de27..2799e15f 100644 --- a/src/fe-common/core/fe-ignore.c +++ b/src/fe-common/core/fe-ignore.c @@ -158,8 +158,8 @@ static void cmd_ignore(const char *data) channels = (chanarg == NULL || *chanarg == '\0') ? NULL : g_strsplit(chanarg, ",", -1); - rec = patternarg != NULL ? NULL: ignore_find_noact(servertag, mask, channels, - (level & MSGLEVEL_NO_ACT)); + rec = ignore_find(servertag, mask, patternarg, channels, + IGNORE_FIND_PATTERN | ((level & MSGLEVEL_NO_ACT) ? IGNORE_FIND_NOACT : 0)); new_ignore = rec == NULL; if (rec == NULL) { @@ -237,9 +237,9 @@ static void cmd_unignore(const char *data) chans[0] = mask; mask = NULL; } - rec = ignore_find_noact("*", mask, (char **) chans, 0); + rec = ignore_find("*", mask, NULL, (char **) chans, 0); if (rec == NULL) { - rec = ignore_find_noact("*", mask, (char **) chans, 1); + rec = ignore_find("*", mask, NULL, (char **) chans, IGNORE_FIND_NOACT); } } diff --git a/src/irc/flood/autoignore.c b/src/irc/flood/autoignore.c index 250a1fe8..4708cb03 100644 --- a/src/irc/flood/autoignore.c +++ b/src/irc/flood/autoignore.c @@ -66,7 +66,7 @@ static void sig_flood(IRC_SERVER_REC *server, const char *nick, const char *host mask = g_strdup_printf("%s!%s", nick, host); if (level & check_level) { - rec = ignore_find(server->tag, mask, NULL); + rec = ignore_find(server->tag, mask, NULL, NULL, 0); if (rec == NULL) autoignore_add(server, mask, level); else From dbee606c60c4d8d7c6e5cabd1241fc182ae6c4a3 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Sun, 3 Jan 2016 21:19:46 +0100 Subject: [PATCH 2/2] Don't break the API. Have a ignore_find_full method that is the one that all the new code should be using and provide some working stubs for ignore_find and ignore_find_noact. --- src/core/ignore.c | 12 +++++++++++- src/core/ignore.h | 9 +++++++-- src/fe-common/core/fe-ignore.c | 6 +++--- src/irc/flood/autoignore.c | 2 +- 4 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/core/ignore.c b/src/core/ignore.c index ee9e180d..8d5a27c2 100644 --- a/src/core/ignore.c +++ b/src/core/ignore.c @@ -186,7 +186,7 @@ int ignore_check(SERVER_REC *server, const char *nick, const char *host, return ignore_check_replies(chanrec, text, level); } -IGNORE_REC *ignore_find(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) { GSList *tmp; @@ -257,6 +257,16 @@ IGNORE_REC *ignore_find(const char *servertag, const char *mask, const char *pat return NULL; } +IGNORE_REC *ignore_find(const char *servertag, const char *mask, char **channels) +{ + return ignore_find_full(servertag, mask, NULL, channels, 0); +} + +IGNORE_REC *ignore_find_noact(const char *servertag, const char *mask, char **channels, int noact) +{ + return ignore_find_full(servertag, mask, NULL, channels, IGNORE_FIND_NOACT); +} + static void ignore_set_config(IGNORE_REC *rec) { CONFIG_NODE *node; diff --git a/src/core/ignore.h b/src/core/ignore.h index 0901e795..f889740f 100644 --- a/src/core/ignore.h +++ b/src/core/ignore.h @@ -36,8 +36,13 @@ enum { IGNORE_FIND_NOACT = 0x02, // Exclude the targets with NOACT level }; -IGNORE_REC *ignore_find(const char *servertag, const char *mask, const char *pattern, - char **channels, const int flags); +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); +IGNORE_REC *ignore_find_noact(const char *servertag, const char *mask, char **channels, int noact); void ignore_add_rec(IGNORE_REC *rec); void ignore_update_rec(IGNORE_REC *rec); diff --git a/src/fe-common/core/fe-ignore.c b/src/fe-common/core/fe-ignore.c index 2799e15f..a809ac91 100644 --- a/src/fe-common/core/fe-ignore.c +++ b/src/fe-common/core/fe-ignore.c @@ -158,7 +158,7 @@ static void cmd_ignore(const char *data) channels = (chanarg == NULL || *chanarg == '\0') ? NULL : g_strsplit(chanarg, ",", -1); - rec = ignore_find(servertag, mask, patternarg, channels, + rec = ignore_find_full(servertag, mask, patternarg, channels, IGNORE_FIND_PATTERN | ((level & MSGLEVEL_NO_ACT) ? IGNORE_FIND_NOACT : 0)); new_ignore = rec == NULL; @@ -237,9 +237,9 @@ static void cmd_unignore(const char *data) chans[0] = mask; mask = NULL; } - rec = ignore_find("*", mask, NULL, (char **) chans, 0); + rec = ignore_find_full("*", mask, NULL, (char **) chans, 0); if (rec == NULL) { - rec = ignore_find("*", mask, NULL, (char **) chans, IGNORE_FIND_NOACT); + rec = ignore_find_full("*", mask, NULL, (char **) chans, IGNORE_FIND_NOACT); } } diff --git a/src/irc/flood/autoignore.c b/src/irc/flood/autoignore.c index 4708cb03..86ff3ec5 100644 --- a/src/irc/flood/autoignore.c +++ b/src/irc/flood/autoignore.c @@ -66,7 +66,7 @@ static void sig_flood(IRC_SERVER_REC *server, const char *nick, const char *host mask = g_strdup_printf("%s!%s", nick, host); if (level & check_level) { - rec = ignore_find(server->tag, mask, NULL, NULL, 0); + rec = ignore_find_full(server->tag, mask, NULL, NULL, 0); if (rec == NULL) autoignore_add(server, mask, level); else