about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--bounce.h7
-rw-r--r--client.c2
-rw-r--r--state.c9
3 files changed, 12 insertions, 6 deletions
diff --git a/bounce.h b/bounce.h
index 5aff027..1eb5ce9 100644
--- a/bounce.h
+++ b/bounce.h
@@ -102,19 +102,20 @@ static const char *CapNames[] = {
 #undef X
 };
 
-static inline enum Cap capParse(const char *list) {
+static inline enum Cap capParse(const char *list, const char *values[CapBits]) {
 	enum Cap caps = 0;
 	while (*list) {
 		enum Cap cap = CapUnsupported;
-		size_t len = strcspn(list, " ");
+		size_t len = strcspn(list, "= ");
 		for (size_t i = 0; i < ARRAY_LEN(CapNames); ++i) {
 			if (len != strlen(CapNames[i])) continue;
 			if (strncmp(list, CapNames[i], len)) continue;
 			cap = 1 << i;
+			if (list[len] == '=' && values) values[i] = &list[len + 1];
 			break;
 		}
 		caps |= cap;
-		list += len;
+		list += strcspn(list, " ");
 		if (*list) list++;
 	}
 	return caps;
diff --git a/client.c b/client.c
index 92ca632..3a1d9d6 100644
--- a/client.c
+++ b/client.c
@@ -193,7 +193,7 @@ 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]);
+		enum Cap caps = capParse(msg->params[1], NULL);
 		if (caps == (avail & caps)) {
 			client->caps |= caps;
 			clientFormat(client, ":%s CAP * ACK :%s\r\n", ORIGIN, msg->params[1]);
diff --git a/state.c b/state.c
index 71c2763..d667971 100644
--- a/state.c
+++ b/state.c
@@ -48,7 +48,7 @@ void stateLogin(
 	const char *pass, bool sasl, const char *plain,
 	const char *nick, const char *user, const char *real
 ) {
-	serverFormat("CAP LS\r\n");
+	serverFormat("CAP LS 302\r\n");
 	if (pass) serverFormat("PASS :%s\r\n", pass);
 	if (sasl) {
 		serverFormat("CAP REQ :%s\r\n", capList(CapSASL, NULL));
@@ -72,7 +72,12 @@ void stateLogin(
 
 static void handleCap(struct Message *msg) {
 	require(msg, false, 3);
-	enum Cap caps = capParse(msg->params[2]);
+	enum Cap caps;
+	if (!strcmp(msg->params[2], "*") && msg->params[3]) {
+		caps = capParse(msg->params[3], NULL);
+	} else {
+		caps = capParse(msg->params[2], NULL);
+	}
 
 	if (!strcmp(msg->params[1], "LS") || !strcmp(msg->params[1], "NEW")) {
 		caps &= ~(CapSASL | CapUnsupported);