diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | README.7 | 4 | ||||
-rw-r--r-- | chat.c | 2 | ||||
-rw-r--r-- | chat.h | 15 | ||||
-rw-r--r-- | command.c | 23 | ||||
-rw-r--r-- | filter.c (renamed from ignore.c) | 71 | ||||
-rw-r--r-- | handle.c | 16 |
7 files changed, 68 insertions, 65 deletions
diff --git a/Makefile b/Makefile index 2c3061d..5caa3ba 100644 --- a/Makefile +++ b/Makefile @@ -13,8 +13,8 @@ OBJS += command.o OBJS += complete.o OBJS += config.o OBJS += edit.o +OBJS += filter.o OBJS += handle.o -OBJS += ignore.o OBJS += irc.o OBJS += log.o OBJS += ui.o diff --git a/README.7 b/README.7 index 0261d3e..03a535d 100644 --- a/README.7 +++ b/README.7 @@ -1,4 +1,4 @@ -.Dd November 11, 2020 +.Dd January 16, 2021 .Dt README 7 .Os "Causal Agency" .\" To view this file, run: man ./README.7 @@ -167,7 +167,7 @@ line editing tab complete .It Pa url.c URL detection -.It Pa ignore.c +.It Pa filter.c message filtering .It Pa log.c chat logging diff --git a/chat.c b/chat.c index b4458be..cdea9a0 100644 --- a/chat.c +++ b/chat.c @@ -243,7 +243,7 @@ int main(int argc, char *argv[]) { break; case 'e': sasl = true; break; case 'g': genCert(optarg); break; case 'h': host = optarg; - break; case 'i': ignoreAdd(optarg); + break; case 'i': filterAdd(Ice, optarg); break; case 'j': self.join = optarg; break; case 'k': priv = optarg; break; case 'l': logEnable = true; diff --git a/chat.h b/chat.h index e027fa5..1b1c338 100644 --- a/chat.h +++ b/chat.h @@ -361,17 +361,18 @@ void urlCopyMatch(uint id, const char *str); int urlSave(FILE *file); void urlLoad(FILE *file, size_t version); -enum { IgnoreCap = 64 }; -extern struct Ignore { +enum { FilterCap = 64 }; +extern struct Filter { + enum Heat heat; 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); +} filters[FilterCap]; +struct Filter filterParse(enum Heat heat, char *pattern); +struct Filter filterAdd(enum Heat heat, const char *pattern); +bool filterRemove(struct Filter filter); +enum Heat filterCheck(enum Heat heat, uint id, const struct Message *msg); extern bool logEnable; void logFormat(uint id, const time_t *time, const char *format, ...) diff --git a/command.c b/command.c index f6db311..f266878 100644 --- a/command.c +++ b/command.c @@ -388,19 +388,20 @@ static void commandCopy(uint id, char *params) { static void commandIgnore(uint id, char *params) { if (params) { - struct Ignore ignore = ignoreAdd(params); + struct Filter filter = filterAdd(Ice, params); uiFormat( id, Cold, NULL, "Ignoring \3%02d%s %s %s %s", - Brown, ignore.mask, - (ignore.cmd ?: ""), (ignore.chan ?: ""), (ignore.mesg ?: "") + Brown, filter.mask, + (filter.cmd ?: ""), (filter.chan ?: ""), (filter.mesg ?: "") ); } else { - for (size_t i = 0; i < IgnoreCap && ignores[i].mask; ++i) { + for (size_t i = 0; i < FilterCap && filters[i].mask; ++i) { + if (filters[i].heat != Ice) continue; uiFormat( Network, Warm, NULL, "Ignoring \3%02d%s %s %s %s", - Brown, ignores[i].mask, - (ignores[i].cmd ?: ""), (ignores[i].chan ?: ""), - (ignores[i].mesg ?: "") + Brown, filters[i].mask, + (filters[i].cmd ?: ""), (filters[i].chan ?: ""), + (filters[i].mesg ?: "") ); } } @@ -408,12 +409,12 @@ static void commandIgnore(uint id, char *params) { static void commandUnignore(uint id, char *params) { if (!params) return; - struct Ignore ignore = ignoreParse(params); - bool found = ignoreRemove(ignore); + struct Filter filter = filterParse(Ice, params); + bool found = filterRemove(filter); 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 ?: "") + (found ? "No longer" : "Not"), Brown, filter.mask, + (filter.cmd ?: ""), (filter.chan ?: ""), (filter.mesg ?: "") ); } diff --git a/ignore.c b/filter.c index 5a9d296..2a7d564 100644 --- a/ignore.c +++ b/filter.c @@ -35,20 +35,20 @@ #include "chat.h" -struct Ignore ignores[IgnoreCap]; +struct Filter filters[FilterCap]; static size_t len; -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 Filter filterParse(enum Heat heat, char *pattern) { + struct Filter filter = { .heat = heat }; + filter.mask = strsep(&pattern, " "); + filter.cmd = strsep(&pattern, " "); + filter.chan = strsep(&pattern, " "); + filter.mesg = pattern; + return filter; } -struct Ignore ignoreAdd(const char *pattern) { - if (len == IgnoreCap) errx(EX_CONFIG, "ignore limit exceeded"); +struct Filter filterAdd(enum Heat heat, const char *pattern) { + if (len == FilterCap) errx(EX_CONFIG, "filter limit exceeded"); char *own; if (!strchr(pattern, '!') && !strchr(pattern, ' ')) { int n = asprintf(&own, "%s!*@*", pattern); @@ -57,48 +57,49 @@ struct Ignore ignoreAdd(const char *pattern) { own = strdup(pattern); if (!own) err(EX_OSERR, "strdup"); } - struct Ignore ignore = ignoreParse(own); - ignores[len++] = ignore; - return ignore; + struct Filter filter = filterParse(heat, own); + filters[len++] = filter; + return filter; } -bool ignoreRemove(struct Ignore ignore) { +bool filterRemove(struct Filter filter) { bool found = false; 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}; + if (filters[i].heat != filter.heat) continue; + if (!filters[i].cmd != !filter.cmd) continue; + if (!filters[i].chan != !filter.chan) continue; + if (!filters[i].mesg != !filter.mesg) continue; + if (strcasecmp(filters[i].mask, filter.mask)) continue; + if (filter.cmd && strcasecmp(filters[i].cmd, filter.cmd)) continue; + if (filter.chan && strcasecmp(filters[i].chan, filter.chan)) continue; + if (filter.mesg && strcasecmp(filters[i].mesg, filter.mesg)) continue; + free(filters[i].mask); + filters[i] = filters[--len]; + filters[len] = (struct Filter) {0}; found = true; } return found; } -static bool ignoreTest( - struct Ignore ignore, const char *mask, uint id, const struct Message *msg +static bool filterTest( + struct Filter filter, 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 (fnmatch(filter.mask, mask, FNM_CASEFOLD)) return false; + if (!filter.cmd) return true; + if (fnmatch(filter.cmd, msg->cmd, FNM_CASEFOLD)) return false; + if (!filter.chan) return true; + if (fnmatch(filter.chan, idNames[id], FNM_CASEFOLD)) return false; + if (!filter.mesg) return true; if (!msg->params[1]) return false; - return !fnmatch(ignore.mesg, msg->params[1], FNM_CASEFOLD); + return !fnmatch(filter.mesg, msg->params[1], FNM_CASEFOLD); } -enum Heat ignoreCheck(enum Heat heat, uint id, const struct Message *msg) { +enum Heat filterCheck(enum Heat heat, uint id, const struct Message *msg) { 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; + if (filterTest(filters[i], mask, id, msg)) return filters[i].heat; } return heat; } diff --git a/handle.c b/handle.c index 9c5fac3..702196b 100644 --- a/handle.c +++ b/handle.c @@ -343,7 +343,7 @@ static void handleJoin(struct Message *msg) { msg->params[2] = NULL; } uiFormat( - id, ignoreCheck(Cold, id, msg), tagTime(msg), + id, filterCheck(Cold, id, msg), tagTime(msg), "\3%02d%s\3\t%s%s%sarrives in \3%02d%s\3", hash(msg->user), msg->nick, (msg->params[2] ? "(" : ""), @@ -373,7 +373,7 @@ static void handlePart(struct Message *msg) { completeClear(id); } completeRemove(id, msg->nick); - enum Heat heat = ignoreCheck(Cold, id, msg); + enum Heat heat = filterCheck(Cold, id, msg); if (heat > Ice) urlScan(id, msg->nick, msg->params[1]); uiFormat( id, heat, tagTime(msg), @@ -423,7 +423,7 @@ static void handleNick(struct Message *msg) { set(&idNames[id], msg->params[0]); } uiFormat( - id, ignoreCheck(Cold, id, msg), tagTime(msg), + id, filterCheck(Cold, id, msg), tagTime(msg), "\3%02d%s\3\tis now known as \3%02d%s\3", hash(msg->user), msg->nick, hash(msg->user), msg->params[0] ); @@ -440,7 +440,7 @@ static void handleSetname(struct Message *msg) { require(msg, true, 1); for (uint id; (id = completeID(msg->nick));) { uiFormat( - id, ignoreCheck(Cold, id, msg), tagTime(msg), + id, filterCheck(Cold, id, msg), tagTime(msg), "\3%02d%s\3\tis now known as \3%02d%s\3 (%s)", hash(msg->user), msg->nick, hash(msg->user), msg->nick, msg->params[0] @@ -451,7 +451,7 @@ static void handleSetname(struct Message *msg) { static void handleQuit(struct Message *msg) { require(msg, true, 0); for (uint id; (id = completeID(msg->nick));) { - enum Heat heat = ignoreCheck(Cold, id, msg); + enum Heat heat = filterCheck(Cold, id, msg); if (heat > Ice) urlScan(id, msg->nick, msg->params[0]); uiFormat( id, heat, tagTime(msg), @@ -473,7 +473,7 @@ static void handleInvite(struct Message *msg) { require(msg, true, 2); if (!strcmp(msg->params[0], self.nick)) { uiFormat( - Network, ignoreCheck(Hot, Network, msg), tagTime(msg), + Network, filterCheck(Hot, Network, msg), tagTime(msg), "\3%02d%s\3\tinvites you to \3%02d%s\3", hash(msg->user), msg->nick, hash(msg->params[1]), msg->params[1] ); @@ -1199,7 +1199,7 @@ static void handlePrivmsg(struct Message *msg) { bool notice = (msg->cmd[0] == 'N'); bool action = isAction(msg); bool mention = !mine && isMention(msg); - enum Heat heat = ignoreCheck((mention || query ? Hot : Warm), id, msg); + enum Heat heat = filterCheck((mention || query ? Hot : Warm), id, msg); if (!notice && !mine && heat > Ice) { completeTouch(id, msg->nick, hash(msg->user)); } @@ -1212,7 +1212,7 @@ static void handlePrivmsg(struct Message *msg) { logFormat(id, tagTime(msg), "-%s- %s", msg->nick, msg->params[1]); } uiFormat( - id, ignoreCheck(Warm, id, msg), tagTime(msg), + id, filterCheck(Warm, id, msg), tagTime(msg), "\3%d-%s-\3%d\t%s", hash(msg->user), msg->nick, LightGray, msg->params[1] ); |