about summary refs log tree commit diff
diff options
context:
space:
mode:
-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")) {