diff options
-rw-r--r-- | bounce.h | 3 | ||||
-rw-r--r-- | client.c | 14 | ||||
-rw-r--r-- | ring.c | 5 |
3 files changed, 19 insertions, 3 deletions
diff --git a/bounce.h b/bounce.h index 1eb5ce9..d5f4170 100644 --- a/bounce.h +++ b/bounce.h @@ -70,6 +70,7 @@ static inline struct Message parse(char *line) { X("away-notify", CapAwayNotify) \ X("batch", CapBatch) \ X("cap-notify", CapCapNotify) \ + X("causal.agency/consumer", CapConsumer) \ X("causal.agency/passive", CapPassive) \ X("chghost", CapChghost) \ X("extended-join", CapExtendedJoin) \ @@ -91,6 +92,7 @@ enum Cap { TagCaps = 0 | CapAccountTag | CapBatch + | CapConsumer | CapLabeledResponse | CapMessageTags | CapServerTime, @@ -142,6 +144,7 @@ extern bool verbose; void ringAlloc(size_t len); void ringProduce(const char *line); size_t ringConsumer(const char *name); +size_t ringPos(size_t consumer); size_t ringDiff(size_t consumer); const char *ringPeek(struct timeval *time, size_t consumer); const char *ringConsume(struct timeval *time, size_t consumer); diff --git a/client.c b/client.c index 3a1d9d6..74fa38a 100644 --- a/client.c +++ b/client.c @@ -165,9 +165,9 @@ static void handlePass(struct Client *client, struct Message *msg) { static void handleCap(struct Client *client, struct Message *msg) { if (!msg->params[0]) msg->params[0] = ""; - enum Cap avail = CapServerTime | CapPassive | (stateCaps & ~CapSASL); + enum Cap avail = (stateCaps & ~CapSASL) + | CapServerTime | CapConsumer | CapPassive | (clientCA ? CapSASL : 0); const char *values[CapBits] = { [CapSASLBit] = "EXTERNAL" }; - if (clientCA) avail |= CapSASL; if (!strcmp(msg->params[0], "END")) { if (!client->need) return; @@ -553,8 +553,16 @@ void clientConsume(struct Client *client) { struct tm *tm = gmtime(&time.tv_sec); strftime(ts, sizeof(ts), "%FT%T", tm); clientFormat( - client, "@time=%s.%03dZ%c%s\r\n", + client, "@time=%s.%03dZ;causal.agency/id=%zu%c%s\r\n", ts, (int)(time.tv_usec / 1000), + ringPos(client->consumer), + (line[0] == '@' ? ';' : ' '), + (line[0] == '@' ? &line[1] : line) + ); + } else if (client->caps & CapConsumer) { + clientFormat( + client, "@causal.agency/id=%zu%c%s\r\n", + ringPos(client->consumer), (line[0] == '@' ? ';' : ' '), (line[0] == '@' ? &line[1] : line) ); diff --git a/ring.c b/ring.c index 2d41666..90e6f2a 100644 --- a/ring.c +++ b/ring.c @@ -81,6 +81,11 @@ size_t ringConsumer(const char *name) { return consumers.len++; } +size_t ringPos(size_t consumer) { + assert(consumer < consumers.len); + return consumers.ptr[consumer].pos; +} + size_t ringDiff(size_t consumer) { assert(consumer < consumers.len); return producer - consumers.ptr[consumer].pos; |