aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorC. McEnroe <june@causal.agency>2020-02-27 03:31:30 -0500
committerC. McEnroe <june@causal.agency>2020-02-27 03:31:30 -0500
commit1af25ef2e6dfd4cc6fc2e4e32e9cbb379fcf0c24 (patch)
tree680e291068b425b800499a3881965cc6d4235a1f
parentRe-sort STANDARDS section (diff)
downloadpounce-1af25ef2e6dfd4cc6fc2e4e32e9cbb379fcf0c24.tar.gz
pounce-1af25ef2e6dfd4cc6fc2e4e32e9cbb379fcf0c24.zip
Add causal.agency/consumer capability
-rw-r--r--bounce.h3
-rw-r--r--client.c14
-rw-r--r--ring.c5
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;