summary refs log tree commit diff
diff options
context:
space:
mode:
authorJune McEnroe <june@causal.agency>2020-02-25 18:06:41 -0500
committerJune McEnroe <june@causal.agency>2020-02-25 18:11:11 -0500
commitdde937cec56b3f6563322d37121308d3f5f5ac39 (patch)
tree2aa278588e31c07b23796f352dc5d6fb08c37c04
parentBump buffer sizes to allow for tags (diff)
downloadpounce-dde937cec56b3f6563322d37121308d3f5f5ac39.tar.gz
pounce-dde937cec56b3f6563322d37121308d3f5f5ac39.zip
Request server-time from the server and filter tags for clients
This doesn't yet, but it will break the "robustness principle" according
to which a server "SHOULD NOT" assume that a client capable of parsing
one tag is capable of parsing all tags. In future, TagCaps will have all
other caps that use tags ORed into it, and only if the client supports
none of them will tags be filtered out.
-rw-r--r--bounce.h3
-rw-r--r--client.c21
-rw-r--r--pounce.13
-rw-r--r--state.c2
4 files changed, 24 insertions, 5 deletions
diff --git a/bounce.h b/bounce.h
index f95bdc8..da52592 100644
--- a/bounce.h
+++ b/bounce.h
@@ -43,6 +43,7 @@ enum { MessageCap = 8191 + 512 };
 
 enum { ParamCap = 15 };
 struct Message {
+	char *tags;
 	char *origin;
 	char *cmd;
 	char *params[ParamCap];
@@ -50,6 +51,7 @@ struct Message {
 
 static inline struct Message parse(char *line) {
 	struct Message msg = {0};
+	if (line[0] == '@') msg.tags = 1 + strsep(&line, " ");
 	if (line[0] == ':') msg.origin = 1 + strsep(&line, " ");
 	msg.cmd = strsep(&line, " ");
 	for (size_t i = 0; line && i < ParamCap; ++i) {
@@ -79,6 +81,7 @@ enum Cap {
 #define X(name, id) BIT(id),
 	ENUM_CAP
 #undef X
+	TagCaps = CapServerTime,
 };
 
 static const char *CapNames[] = {
diff --git a/client.c b/client.c
index 93b1716..8a4e86f 100644
--- a/client.c
+++ b/client.c
@@ -315,6 +315,10 @@ size_t clientDiff(const struct Client *client) {
 }
 
 static int wordcmp(const char *line, size_t i, const char *word) {
+	if (line[0] == '@') {
+		line += strcspn(line, " ");
+		if (*line) line++;
+	}
 	while (i--) {
 		line += strcspn(line, " ");
 		if (*line) line++;
@@ -421,6 +425,12 @@ static const char *filterUserhostInNames(const char *line) {
 	);
 }
 
+static const char *filterTags(const char *line) {
+	if (line[0] != '@') return line;
+	const char *sp = strchr(line, ' ');
+	return (sp ? sp + 1 : NULL);
+}
+
 static Filter *Filters[] = {
 	[CapAccountNotifyBit] = filterAccountNotify,
 	[CapAwayNotifyBit] = filterAwayNotify,
@@ -441,18 +451,23 @@ void clientConsume(struct Client *client) {
 		if (!Filters[i]) continue;
 		if (diff & (1 << i)) line = Filters[i](line);
 	}
+	if (stateCaps & TagCaps && !(client->caps & TagCaps)) {
+		if (line) line = filterTags(line);
+	}
 	if (!line) {
 		ringConsume(NULL, client->consumer);
 		return;
 	}
 
-	if (client->caps & CapServerTime) {
+	if (client->caps & CapServerTime && !(stateCaps & CapServerTime)) {
 		char ts[sizeof("YYYY-MM-DDThh:mm:ss")];
 		struct tm *tm = gmtime(&time.tv_sec);
 		strftime(ts, sizeof(ts), "%FT%T", tm);
 		clientFormat(
-			client, "@time=%s.%03dZ %s\r\n",
-			ts, (int)(time.tv_usec / 1000), line
+			client, "@time=%s.%03dZ%c%s\r\n",
+			ts, (int)(time.tv_usec / 1000),
+			(line[0] == '@' ? ';' : ' '),
+			(line[0] == '@' ? &line[1] : line)
 		);
 	} else {
 		clientFormat(client, "%s\r\n", line);
diff --git a/pounce.1 b/pounce.1
index c55310b..7ed431f 100644
--- a/pounce.1
+++ b/pounce.1
@@ -1,4 +1,4 @@
-.Dd February 18, 2020
+.Dd February 25, 2020
 .Dt POUNCE 1
 .Os
 .
@@ -343,6 +343,7 @@ is supported:
 .Sy extended-join ,
 .Sy invite-notify ,
 .Sy multi-prefix ,
+.Sy server-time ,
 .Sy userhost-in-names .
 .
 .Pp
diff --git a/state.c b/state.c
index a661ce7..c714628 100644
--- a/state.c
+++ b/state.c
@@ -75,7 +75,7 @@ static void handleCap(struct Message *msg) {
 	enum Cap caps = capParse(msg->params[2]);
 
 	if (!strcmp(msg->params[1], "LS")) {
-		caps &= ~(CapSASL | CapServerTime | CapUnsupported);
+		caps &= ~(CapSASL | CapUnsupported);
 		serverFormat("CAP REQ :%s\r\n", capList(caps));
 
 	} else if (!strcmp(msg->params[1], "ACK")) {
June McEnroe There are probably better things to sort by but title definitely always exists. 2021-09-13Swap-remove tags as they're foundJune McEnroe This makes it even faster. From ~1s on a sqlite3.c amalgamation to ~0.85s. 2021-09-12Replace htagml regex with strncmpJune McEnroe Since ctags only ever produces regular expressions of the form /^re$/ or /^re/ with no other special characters, instead unescape the pattern and simply use strncmp. Running on a sqlite3.c amalgamation, the regex version takes ~37s while the strncmp version takes ~1s, producing identical output. Big win! 2021-09-11Also defer printing comment for lone close-parensJune McEnroe 2021-09-10Publish "git-comment"June McEnroe 2021-09-10Add git comment --pretty optionJune McEnroe 2021-09-08Defer printing comment if line is blank or closing braceJune McEnroe This fixes badly indented comments. 2021-09-08Up default min-repeat to 30 linesJune McEnroe 2021-09-08Handle dirty lines in git-commentJune McEnroe 2021-09-08Document and install git-commentJune McEnroe 2021-09-08Add repeat and all options to git-commentJune McEnroe 2021-09-08Add group threshold to git-commentJune McEnroe