about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--bounce.c2
-rw-r--r--bounce.h1
-rw-r--r--client.c29
3 files changed, 31 insertions, 1 deletions
diff --git a/bounce.c b/bounce.c
index 8f8d38f..990a61d 100644
--- a/bounce.c
+++ b/bounce.c
@@ -304,6 +304,7 @@ int main(int argc, char *argv[]) {
 		{ .val = 'C', .name = "local-cert", required_argument },
 		{ .val = 'H', .name = "local-host", required_argument },
 		{ .val = 'K', .name = "local-priv", required_argument },
+		{ .val = 'L', .name = "palaver", no_argument },
 		{ .val = 'N', .name = "no-names", no_argument },
 		{ .val = 'P', .name = "local-port", required_argument },
 		{ .val = 'Q', .name = "queue-interval", required_argument },
@@ -356,6 +357,7 @@ int main(int argc, char *argv[]) {
 			break; case 'H': bindHost = optarg;
 			break; case 'K': snprintf(privPath, sizeof(privPath), "%s", optarg);
 			break; case 'N': stateNoNames = true;
+			break; case 'L': clientCaps |= CapPalaverApp;
 			break; case 'P': bindPort = optarg;
 			break; case 'Q': serverQueueInterval = parseInterval(optarg);
 			break; case 'R': blindReq |= capParse(optarg, NULL);
diff --git a/bounce.h b/bounce.h
index 4aa61b2..986bd5a 100644
--- a/bounce.h
+++ b/bounce.h
@@ -87,6 +87,7 @@ static inline struct Message parse(char *line) {
 	X("labeled-response", CapLabeledResponse) \
 	X("message-tags", CapMessageTags) \
 	X("multi-prefix", CapMultiPrefix) \
+	X("palaverapp.com", CapPalaverApp) \
 	X("sasl", CapSASL) \
 	X("server-time", CapServerTime) \
 	X("setname", CapSetname) \
diff --git a/client.c b/client.c
index dc33288..d0df0aa 100644
--- a/client.c
+++ b/client.c
@@ -296,6 +296,27 @@ static void handleTagmsg(struct Client *client, struct Message *msg) {
 	serverFormat("@%s TAGMSG %s\r\n", msg->tags, msg->params[0]);
 }
 
+static void handlePalaver(struct Client *client, struct Message *msg) {
+	if (client->need & NeedPass || !msg->params[0]) return;
+	char line[MessageCap];
+	if (msg->params[3]) {
+		snprintf(
+			line, sizeof(line), "PALAVER %s %s %s %s",
+			msg->params[0], msg->params[1], msg->params[2], msg->params[3]
+		);
+	} else if (msg->params[2]) {
+		snprintf(
+			line, sizeof(line), "PALAVER %s %s %s",
+			msg->params[0], msg->params[1], msg->params[2]
+		);
+	} else {
+		snprintf(line, sizeof(line), "PALAVER %s", msg->params[0]);
+	}
+	size_t diff = ringDiff(client->consumer);
+	ringProduce(line);
+	if (!diff) ringConsume(NULL, client->consumer);
+}
+
 static const struct {
 	const char *cmd;
 	Handler *fn;
@@ -305,6 +326,7 @@ static const struct {
 	{ "CAP", handleCap, false },
 	{ "NICK", handleNick, false },
 	{ "NOTICE", handlePrivmsg, true },
+	{ "PALAVER", handlePalaver, false },
 	{ "PASS", handlePass, false },
 	{ "PRIVMSG", handlePrivmsg, true },
 	{ "QUIT", handleQuit, true },
@@ -504,6 +526,10 @@ static const char *filterMultiPrefix(const char *line) {
 	}
 }
 
+static const char *filterPalaverApp(const char *line) {
+	return (wordcmp(line, 0, "PALAVER") ? line : NULL);
+}
+
 static const char *filterSetname(const char *line) {
 	return (wordcmp(line, 0, "SETNAME") ? line : NULL);
 }
@@ -535,6 +561,7 @@ static Filter *Filters[] = {
 	[CapLabeledResponseBit] = filterLabeledResponse,
 	[CapMessageTagsBit] = filterMessageTags,
 	[CapMultiPrefixBit] = filterMultiPrefix,
+	[CapPalaverAppBit] = filterPalaverApp,
 	[CapSetnameBit] = filterSetname,
 	[CapUserhostInNamesBit] = filterUserhostInNames,
 };
@@ -557,7 +584,7 @@ void clientConsume(struct Client *client) {
 	if (stateCaps & TagCaps && !(client->caps & TagCaps)) {
 		line = filterTags(line);
 	}
-	enum Cap diff = client->caps ^ stateCaps;
+	enum Cap diff = client->caps ^ (clientCaps | stateCaps);
 	for (size_t i = 0; line && i < ARRAY_LEN(Filters); ++i) {
 		if (!Filters[i]) continue;
 		if (diff & (1 << i)) line = Filters[i](line);