From c1c002aea9d1f3a4438a657de669de75bcbe50e9 Mon Sep 17 00:00:00 2001 From: "C. McEnroe" Date: Thu, 27 Feb 2020 03:53:13 -0500 Subject: Set consumer pos with CAP REQ causal.agency/consumer=n So the spec doesn't say I can use cap values in CAP REQ. But it also doesn't explicitly say I can't. --- bounce.h | 1 + client.c | 7 ++++++- ring.c | 5 +++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/bounce.h b/bounce.h index d5f4170..f8ab0c0 100644 --- a/bounce.h +++ b/bounce.h @@ -144,6 +144,7 @@ extern bool verbose; void ringAlloc(size_t len); void ringProduce(const char *line); size_t ringConsumer(const char *name); +void ringSet(size_t consumer, size_t pos); size_t ringPos(size_t consumer); size_t ringDiff(size_t consumer); const char *ringPeek(struct timeval *time, size_t consumer); diff --git a/client.c b/client.c index a335b99..66d07d0 100644 --- a/client.c +++ b/client.c @@ -47,6 +47,7 @@ struct Client { struct tls *tls; enum Need need; size_t consumer; + size_t setPos; enum Cap caps; char buf[MessageCap]; size_t len; @@ -118,6 +119,7 @@ static void maybeSync(struct Client *client) { if (client->need == NeedPass) passRequired(client); if (!client->need) { stateSync(client); + if (client->setPos) ringSet(client->consumer, client->setPos); if (!(client->caps & CapPassive) && !active++) { serverFormat("AWAY\r\n"); } @@ -193,9 +195,12 @@ static void handleCap(struct Client *client, struct Message *msg) { } else if (!strcmp(msg->params[0], "REQ") && msg->params[1]) { if (client->need) client->need |= NeedCapEnd; - enum Cap caps = capParse(msg->params[1], NULL); + enum Cap caps = capParse(msg->params[1], values); if (caps == (avail & caps)) { client->caps |= caps; + if (caps & CapConsumer && values[CapConsumerBit]) { + client->setPos = strtoull(values[CapConsumerBit], NULL, 10); + } clientFormat(client, ":%s CAP * ACK :%s\r\n", ORIGIN, msg->params[1]); } else { clientFormat(client, ":%s CAP * NAK :%s\r\n", ORIGIN, msg->params[1]); diff --git a/ring.c b/ring.c index 90e6f2a..254c285 100644 --- a/ring.c +++ b/ring.c @@ -81,6 +81,11 @@ size_t ringConsumer(const char *name) { return consumers.len++; } +void ringSet(size_t consumer, size_t pos) { + assert(consumer < consumers.len); + if (pos <= producer) consumers.ptr[consumer].pos = pos; +} + size_t ringPos(size_t consumer) { assert(consumer < consumers.len); return consumers.ptr[consumer].pos; -- cgit 1.4.1