summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--catgirl.114
-rw-r--r--chat.h3
-rw-r--r--filter.c29
3 files changed, 45 insertions, 1 deletions
diff --git a/catgirl.1 b/catgirl.1
index c5ac74e..9954def 100644
--- a/catgirl.1
+++ b/catgirl.1
@@ -935,6 +935,20 @@ catgirl freenode
.Re
.It
.Rs
+.%A James Wheare
+.%T Reply Client Tag
+.%I IRCv3 Working Group
+.%U https://ircv3.net/specs/client-tags/reply
+.Re
+.It
+.Rs
+.%A James Wheare
+.%T Message IDs
+.%I IRCv3 Working Group
+.%U https://ircv3.net/specs/extensions/message-ids
+.Re
+.It
+.Rs
.%A K. Zeilenga, Ed.
.%T The PLAIN Simple Authentication and Security Layer (SASL) Mechanism
.%I IETF
diff --git a/chat.h b/chat.h
index eb826a8..fadbc30 100644
--- a/chat.h
+++ b/chat.h
@@ -171,6 +171,7 @@ extern struct Network {
X("chghost", CapChghost) \
X("extended-join", CapExtendedJoin) \
X("invite-notify", CapInviteNotify) \
+ X("message-tags", CapMessageTags) \
X("multi-prefix", CapMultiPrefix) \
X("sasl", CapSASL) \
X("server-time", CapServerTime) \
@@ -205,7 +206,9 @@ static inline void set(char **field, const char *value) {
}
#define ENUM_TAG \
+ X("+draft/reply", TagReply) \
X("causal.agency/pos", TagPos) \
+ X("msgid", TagMsgID) \
X("time", TagTime)
enum Tag {
diff --git a/filter.c b/filter.c
index a648d8b..63c3369 100644
--- a/filter.c
+++ b/filter.c
@@ -94,12 +94,39 @@ static bool filterTest(
return !fnmatch(filter.mesg, msg->params[1], FNM_CASEFOLD);
}
+enum { IcedCap = 8 };
+static struct {
+ size_t len;
+ char *msgIDs[IcedCap];
+} iced;
+
+static void icedPush(const char *msgID) {
+ if (!msgID) return;
+ size_t i = iced.len % IcedCap;
+ free(iced.msgIDs[i]);
+ iced.msgIDs[i] = strdup(msgID);
+ if (!iced.msgIDs[i]) err(EX_OSERR, "strdup");
+ iced.len++;
+}
+
enum Heat filterCheck(enum Heat heat, uint id, const struct Message *msg) {
if (!len) return heat;
+
+ if (msg->tags[TagReply]) {
+ for (size_t i = 0; i < IcedCap; ++i) {
+ if (!iced.msgIDs[i]) continue;
+ if (strcmp(msg->tags[TagReply], iced.msgIDs[i])) continue;
+ icedPush(msg->tags[TagMsgID]);
+ return Ice;
+ }
+ }
+
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 (filterTest(filters[i], mask, id, msg)) return filters[i].heat;
+ if (!filterTest(filters[i], mask, id, msg)) continue;
+ if (filters[i].heat == Ice) icedPush(msg->tags[TagMsgID]);
+ return filters[i].heat;
}
return heat;
}