diff options
author | June McEnroe <june@causal.agency> | 2020-02-25 18:06:41 -0500 |
---|---|---|
committer | June McEnroe <june@causal.agency> | 2020-02-25 18:11:11 -0500 |
commit | dde937cec56b3f6563322d37121308d3f5f5ac39 (patch) | |
tree | 2aa278588e31c07b23796f352dc5d6fb08c37c04 | |
parent | Bump buffer sizes to allow for tags (diff) | |
download | pounce-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.h | 3 | ||||
-rw-r--r-- | client.c | 21 | ||||
-rw-r--r-- | pounce.1 | 3 | ||||
-rw-r--r-- | state.c | 2 |
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")) { |