summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chat.h15
-rw-r--r--command.c30
-rw-r--r--ignore.c89
3 files changed, 77 insertions, 57 deletions
diff --git a/chat.h b/chat.h
index c7af680..b06d383 100644
--- a/chat.h
+++ b/chat.h
@@ -353,13 +353,16 @@ void urlOpenCount(uint id, uint count);
void urlOpenMatch(uint id, const char *str);
void urlCopyMatch(uint id, const char *str);
-enum { IgnoreCap = 256 };
+enum { IgnoreCap = 64 };
extern struct Ignore {
- size_t len;
- char *patterns[IgnoreCap];
-} ignore;
-const char *ignoreAdd(const char *pattern);
-bool ignoreRemove(const char *pattern);
+ char *mask;
+ char *cmd;
+ char *chan;
+ char *mesg;
+} ignores[IgnoreCap];
+struct Ignore ignoreParse(char *pattern);
+struct Ignore ignoreAdd(const char *pattern);
+bool ignoreRemove(struct Ignore ignore);
enum Heat ignoreCheck(enum Heat heat, uint id, const struct Message *msg);
extern bool logEnable;
diff --git a/command.c b/command.c
index 43870f1..c71bebc 100644
--- a/command.c
+++ b/command.c
@@ -388,16 +388,19 @@ static void commandCopy(uint id, char *params) {
static void commandIgnore(uint id, char *params) {
if (params) {
- const char *pattern = ignoreAdd(params);
+ struct Ignore ignore = ignoreAdd(params);
uiFormat(
- id, Cold, NULL, "Ignoring \3%02d%s\3",
- Brown, pattern
+ id, Cold, NULL, "Ignoring \3%02d%s %s %s %s",
+ Brown, ignore.mask,
+ (ignore.cmd ?: ""), (ignore.chan ?: ""), (ignore.mesg ?: "")
);
} else {
- for (size_t i = 0; i < ignore.len; ++i) {
+ for (size_t i = 0; i < IgnoreCap && ignores[i].mask; ++i) {
uiFormat(
- Network, Warm, NULL, "Ignoring \3%02d%s\3",
- Brown, ignore.patterns[i]
+ Network, Warm, NULL, "Ignoring \3%02d%s %s %s %s",
+ Brown, ignores[i].mask,
+ (ignores[i].cmd ?: ""), (ignores[i].chan ?: ""),
+ (ignores[i].mesg ?: "")
);
}
}
@@ -405,14 +408,13 @@ static void commandIgnore(uint id, char *params) {
static void commandUnignore(uint id, char *params) {
if (!params) return;
- if (ignoreRemove(params)) {
- uiFormat(
- id, Cold, NULL, "No longer ignoring \3%02d%s\3",
- Brown, params
- );
- } else {
- uiFormat(id, Cold, NULL, "Not ignoring \3%02d%s\3", Brown, params);
- }
+ struct Ignore ignore = ignoreParse(params);
+ bool found = ignoreRemove(ignore);
+ uiFormat(
+ id, Cold, NULL, "%s ignoring \3%02d%s %s %s %s",
+ (found ? "No longer" : "Not"), Brown, ignore.mask,
+ (ignore.cmd ?: ""), (ignore.chan ?: ""), (ignore.mesg ?: "")
+ );
}
static void commandExec(uint id, char *params) {
diff --git a/ignore.c b/ignore.c
index f8e4d59..5a9d296 100644
--- a/ignore.c
+++ b/ignore.c
@@ -35,55 +35,70 @@
#include "chat.h"
-struct Ignore ignore;
+struct Ignore ignores[IgnoreCap];
+static size_t len;
-const char *ignoreAdd(const char *pattern) {
- if (ignore.len == IgnoreCap) errx(EX_CONFIG, "ignore limit exceeded");
- uint ex = 0, sp = 0;
- for (const char *ch = pattern; *ch; ++ch) {
- if (*ch == '!') ex++;
- if (*ch == ' ') sp++;
- }
- char **dest = &ignore.patterns[ignore.len++];
- int n = 0;
- if (!ex && !sp) {
- n = asprintf(dest, "%s!*@* * * *", pattern);
- } else if (sp < 1) {
- n = asprintf(dest, "%s * * *", pattern);
- } else if (sp < 2) {
- n = asprintf(dest, "%s * *", pattern);
- } else if (sp < 3) {
- n = asprintf(dest, "%s *", pattern);
+struct Ignore ignoreParse(char *pattern) {
+ struct Ignore ignore = {0};
+ ignore.mask = strsep(&pattern, " ");
+ ignore.cmd = strsep(&pattern, " ");
+ ignore.chan = strsep(&pattern, " ");
+ ignore.mesg = pattern;
+ return ignore;
+}
+
+struct Ignore ignoreAdd(const char *pattern) {
+ if (len == IgnoreCap) errx(EX_CONFIG, "ignore limit exceeded");
+ char *own;
+ if (!strchr(pattern, '!') && !strchr(pattern, ' ')) {
+ int n = asprintf(&own, "%s!*@*", pattern);
+ if (n < 0) err(EX_OSERR, "asprintf");
} else {
- *dest = strdup(pattern);
+ own = strdup(pattern);
+ if (!own) err(EX_OSERR, "strdup");
}
- if (n < 0) err(EX_OSERR, "asprintf");
- if (!*dest) err(EX_OSERR, "strdup");
- return *dest;
+ struct Ignore ignore = ignoreParse(own);
+ ignores[len++] = ignore;
+ return ignore;
}
-bool ignoreRemove(const char *pattern) {
+bool ignoreRemove(struct Ignore ignore) {
bool found = false;
- for (size_t i = 0; i < ignore.len; ++i) {
- if (strcasecmp(ignore.patterns[i], pattern)) continue;
- free(ignore.patterns[i]);
- ignore.patterns[i] = ignore.patterns[--ignore.len];
+ for (size_t i = len - 1; i < len; --i) {
+ if (!ignores[i].cmd != !ignore.cmd) continue;
+ if (!ignores[i].chan != !ignore.chan) continue;
+ if (!ignores[i].mesg != !ignore.mesg) continue;
+ if (strcasecmp(ignores[i].mask, ignore.mask)) continue;
+ if (ignore.cmd && strcasecmp(ignores[i].cmd, ignore.cmd)) continue;
+ if (ignore.chan && strcasecmp(ignores[i].chan, ignore.chan)) continue;
+ if (ignore.mesg && strcasecmp(ignores[i].mesg, ignore.mesg)) continue;
+ free(ignores[i].mask);
+ ignores[i] = ignores[--len];
+ ignores[len] = (struct Ignore) {0};
found = true;
}
return found;
}
+static bool ignoreTest(
+ struct Ignore ignore, const char *mask, uint id, const struct Message *msg
+) {
+ if (fnmatch(ignore.mask, mask, FNM_CASEFOLD)) return false;
+ if (!ignore.cmd) return true;
+ if (fnmatch(ignore.cmd, msg->cmd, FNM_CASEFOLD)) return false;
+ if (!ignore.chan) return true;
+ if (fnmatch(ignore.chan, idNames[id], FNM_CASEFOLD)) return false;
+ if (!ignore.mesg) return true;
+ if (!msg->params[1]) return false;
+ return !fnmatch(ignore.mesg, msg->params[1], FNM_CASEFOLD);
+}
+
enum Heat ignoreCheck(enum Heat heat, uint id, const struct Message *msg) {
- if (!ignore.len) return heat;
- char match[512];
- snprintf(
- match, sizeof(match), "%s!%s@%s %s %s %s",
- msg->nick, msg->user, msg->host,
- msg->cmd, idNames[id], (msg->params[1] ?: "")
- );
- for (size_t i = 0; i < ignore.len; ++i) {
- if (fnmatch(ignore.patterns[i], match, FNM_CASEFOLD)) continue;
- return Ice;
+ if (!len) return heat;
+ char mask[512];
+ snprintf(mask, sizeof(mask), "%s!%s@%s", msg->nick, msg->user, msg->host);
+ for (size_t i = 0; i < len; ++i) {
+ if (ignoreTest(ignores[i], mask, id, msg)) return Ice;
}
return heat;
}