about summary refs log tree commit diff
path: root/handle.c
diff options
context:
space:
mode:
authorJune McEnroe <june@causal.agency>2018-08-10 23:31:20 -0400
committerJune McEnroe <june@causal.agency>2018-08-10 23:31:20 -0400
commit07c750d25cf26883507d46bf319e55d2e35d6a94 (patch)
treedcf7dbc50dd717a1190c2f034ff440badf5a525c /handle.c
parentMove process spawning onto the event loop (diff)
downloadcatgirl-07c750d25cf26883507d46bf319e55d2e35d6a94.tar.gz
catgirl-07c750d25cf26883507d46bf319e55d2e35d6a94.zip
Become multi-channel
There's a lot of UI missing for it, but it technically works.
Diffstat (limited to '')
-rw-r--r--handle.c163
1 files changed, 96 insertions, 67 deletions
diff --git a/handle.c b/handle.c
index be41828..faf44aa 100644
--- a/handle.c
+++ b/handle.c
@@ -74,6 +74,16 @@ static void shift(
 	va_end(ap);
 }
 
+static bool isSelf(const char *nick, const char *user) {
+	if (!user) return false;
+	if (!strcmp(user, self.user)) return true;
+	if (!strcmp(nick, self.nick)) {
+		if (strcmp(user, self.user)) selfUser(user);
+		return true;
+	}
+	return false;
+}
+
 typedef void (*Handler)(char *prefix, char *params);
 
 static void handlePing(char *prefix, char *params) {
@@ -84,104 +94,118 @@ static void handlePing(char *prefix, char *params) {
 static void handle432(char *prefix, char *params) {
 	char *mesg;
 	shift(prefix, NULL, NULL, NULL, params, 3, 0, NULL, NULL, &mesg);
-	uiLog(L"You can't use that name here");
-	uiFmt("Sheriff says, \"%s\"", mesg);
-	uiLog(L"Type /nick <name> to choose a new one");
+	uiLog(TAG_DEFAULT, L"You can't use that name here");
+	uiFmt(TAG_DEFAULT, "Sheriff says, \"%s\"", mesg);
+	uiLog(TAG_DEFAULT, L"Type /nick <name> to choose a new one");
 }
 
 static void handle001(char *prefix, char *params) {
 	char *nick;
 	shift(prefix, NULL, NULL, NULL, params, 1, 0, &nick);
-	if (strcmp(nick, chat.nick)) {
-		free(chat.nick);
-		chat.nick = strdup(nick);
-	}
-	ircFmt("JOIN %s\r\n", chat.join);
+	if (strcmp(nick, self.nick)) selfNick(nick);
+	tabTouch(TAG_DEFAULT, self.nick);
+	if (self.join) ircFmt("JOIN %s\r\n", self.join);
+	uiLog(TAG_DEFAULT, L"You have arrived");
+}
+
+static void handle372(char *prefix, char *params) {
+	char *mesg;
+	shift(prefix, NULL, NULL, NULL, params, 2, 0, NULL, &mesg);
+	if (mesg[0] == '-' && mesg[1] == ' ') mesg = &mesg[2];
+	uiFmt(TAG_DEFAULT, "%s", mesg);
 }
 
 static void handleJoin(char *prefix, char *params) {
 	char *nick, *user, *chan;
 	shift(prefix, &nick, &user, NULL, params, 1, 0, &chan);
+	struct Tag tag = tagFor(chan);
+	if (isSelf(nick, user)) {
+		tabTouch(TAG_DEFAULT, chan);
+		uiFocus(tag);
+	} else {
+		tabTouch(tag, nick);
+	}
 	uiFmt(
-		"\3%d%s\3 arrives in \3%d%s\3",
+		tag, "\3%d%s\3 arrives in \3%d%s\3",
 		color(user), nick, color(chan), chan
 	);
-	if (!strcmp(nick, chat.nick) && strcmp(user, chat.user)) {
-		free(chat.user);
-		chat.user = strdup(user);
-	}
-	tabTouch(nick);
 }
 
 static void handlePart(char *prefix, char *params) {
 	char *nick, *user, *chan, *mesg;
 	shift(prefix, &nick, &user, NULL, params, 1, 1, &chan, &mesg);
+	struct Tag tag = tagFor(chan);
+	(void)(isSelf(nick, user) ? tabClear(tag) : tabRemove(tag, nick));
 	if (mesg) {
 		uiFmt(
-			"\3%d%s\3 leaves \3%d%s\3, \"%s\"",
+			tag, "\3%d%s\3 leaves \3%d%s\3, \"%s\"",
 			color(user), nick, color(chan), chan, mesg
 		);
 	} else {
 		uiFmt(
-			"\3%d%s\3 leaves \3%d%s\3",
+			tag, "\3%d%s\3 leaves \3%d%s\3",
 			color(user), nick, color(chan), chan
 		);
 	}
-	tabRemove(nick);
-}
-
-static void handleQuit(char *prefix, char *params) {
-	char *nick, *user, *mesg;
-	shift(prefix, &nick, &user, NULL, params, 0, 1, &mesg);
-	if (mesg) {
-		char *quot = (mesg[0] == '"') ? "" : "\"";
-		uiFmt(
-			"\3%d%s\3 leaves, %s%s%s",
-			color(user), nick, quot, mesg, quot
-		);
-	} else {
-		uiFmt("\3%d%s\3 leaves", color(user), nick);
-	}
-	tabRemove(nick);
 }
 
 static void handleKick(char *prefix, char *params) {
 	char *nick, *user, *chan, *kick, *mesg;
 	shift(prefix, &nick, &user, NULL, params, 2, 1, &chan, &kick, &mesg);
+	struct Tag tag = tagFor(chan);
+	(void)(isSelf(nick, user) ? tabClear(tag) : tabRemove(tag, nick));
 	if (mesg) {
 		uiFmt(
-			"\3%d%s\3 kicks \3%d%s\3 out of \3%d%s\3, \"%s\"",
+			tag, "\3%d%s\3 kicks \3%d%s\3 out of \3%d%s\3, \"%s\"",
 			color(user), nick, color(kick), kick, color(chan), chan, mesg
 		);
 	} else {
 		uiFmt(
-			"\3%d%s\3 kicks \3%d%s\3 out of \3%d%s\3",
+			tag, "\3%d%s\3 kicks \3%d%s\3 out of \3%d%s\3",
 			color(user), nick, color(kick), kick, color(chan), chan
 		);
 	}
-	tabRemove(nick);
+}
+
+static void handleQuit(char *prefix, char *params) {
+	char *nick, *user, *mesg;
+	shift(prefix, &nick, &user, NULL, params, 0, 1, &mesg);
+	// TODO: Send to tags where nick is in tab.
+	tabRemove(TAG_ALL, nick);
+	if (mesg) {
+		char *quot = (mesg[0] == '"') ? "" : "\"";
+		uiFmt(
+			TAG_DEFAULT, "\3%d%s\3 leaves, %s%s%s",
+			color(user), nick, quot, mesg, quot
+		);
+	} else {
+		uiFmt(TAG_DEFAULT, "\3%d%s\3 leaves", color(user), nick);
+	}
 }
 
 static void handle332(char *prefix, char *params) {
 	char *chan, *topic;
 	shift(prefix, NULL, NULL, NULL, params, 3, 0, NULL, &chan, &topic);
+	struct Tag tag = tagFor(chan);
+	urlScan(tag, topic);
+	uiTopic(tag, topic);
 	uiFmt(
-		"The sign in \3%d%s\3 reads, \"%s\"",
+		tag, "The sign in \3%d%s\3 reads, \"%s\"",
 		color(chan), chan, topic
 	);
-	urlScan(topic);
-	uiTopicStr(topic);
 }
 
 static void handleTopic(char *prefix, char *params) {
 	char *nick, *user, *chan, *topic;
 	shift(prefix, &nick, &user, NULL, params, 2, 0, &chan, &topic);
+	struct Tag tag = tagFor(chan);
+	if (!isSelf(nick, user)) tabTouch(tag, nick);
+	urlScan(tag, topic);
+	uiTopic(tag, topic);
 	uiFmt(
-		"\3%d%s\3 places a new sign in \3%d%s\3, \"%s\"",
+		tag, "\3%d%s\3 places a new sign in \3%d%s\3, \"%s\"",
 		color(user), nick, color(chan), chan, topic
 	);
-	urlScan(topic);
-	uiTopicStr(topic);
 }
 
 static void handle366(char *prefix, char *params) {
@@ -190,17 +214,20 @@ static void handle366(char *prefix, char *params) {
 	ircFmt("WHO %s\r\n", chan);
 }
 
+// FIXME: Track tag?
 static struct {
 	char buf[4096];
 	size_t len;
 } who;
 
 static void handle352(char *prefix, char *params) {
-	char *user, *nick;
+	char *chan, *user, *nick;
 	shift(
 		prefix, NULL, NULL, NULL,
-		params, 6, 0, NULL, NULL, &user, NULL, NULL, &nick
+		params, 6, 0, NULL, &chan, &user, NULL, NULL, &nick
 	);
+	struct Tag tag = tagFor(chan);
+	if (!isSelf(nick, user)) tabTouch(tag, nick);
 	size_t cap = sizeof(who.buf) - who.len;
 	int len = snprintf(
 		&who.buf[who.len], cap,
@@ -208,14 +235,14 @@ static void handle352(char *prefix, char *params) {
 		(who.len ? ", " : ""), color(user), nick
 	);
 	if ((size_t)len < cap) who.len += len;
-	tabTouch(nick);
 }
 
 static void handle315(char *prefix, char *params) {
 	char *chan;
 	shift(prefix, NULL, NULL, NULL, params, 2, 0, NULL, &chan);
+	struct Tag tag = tagFor(chan);
 	uiFmt(
-		"In \3%d%s\3 are %s",
+		tag, "In \3%d%s\3 are %s",
 		color(chan), chan, who.buf
 	);
 	who.len = 0;
@@ -224,58 +251,58 @@ static void handle315(char *prefix, char *params) {
 static void handleNick(char *prefix, char *params) {
 	char *prev, *user, *next;
 	shift(prefix, &prev, &user, NULL, params, 1, 0, &next);
+	if (isSelf(prev, user)) selfNick(next);
+	// TODO: Send to tags where prev is in tab.
+	tabReplace(prev, next);
 	uiFmt(
-		"\3%d%s\3 is now known as \3%d%s\3",
+		TAG_DEFAULT, "\3%d%s\3 is now known as \3%d%s\3",
 		color(user), prev, color(user), next
 	);
-	if (!strcmp(user, chat.user)) {
-		free(chat.nick);
-		chat.nick = strdup(next);
-	}
-	tabReplace(prev, next);
 }
 
-static void handleCTCP(char *nick, char *user, char *mesg) {
+static void handleCTCP(struct Tag tag, char *nick, char *user, char *mesg) {
 	mesg = &mesg[1];
 	char *ctcp = strsep(&mesg, " ");
 	char *params = strsep(&mesg, "\1");
 	if (strcmp(ctcp, "ACTION")) return;
+	if (!isSelf(nick, user)) tabTouch(tag, nick);
+	urlScan(tag, params);
 	uiFmt(
-		"\3%d* %s\3 %s",
+		tag, "\3%d* %s\3 %s",
 		color(user), nick, params
 	);
-	if (strcmp(user, chat.user)) tabTouch(nick);
-	urlScan(params);
 }
 
 static void handlePrivmsg(char *prefix, char *params) {
-	char *nick, *user, *mesg;
-	shift(prefix, &nick, &user, NULL, params, 2, 0, NULL, &mesg);
+	char *nick, *user, *chan, *mesg;
+	shift(prefix, &nick, &user, NULL, params, 2, 0, &chan, &mesg);
+	struct Tag tag = (strcmp(chan, self.nick) ? tagFor(chan) : tagFor(nick));
 	if (mesg[0] == '\1') {
-		handleCTCP(nick, user, mesg);
+		handleCTCP(tag, nick, user, mesg);
 		return;
 	}
-	bool self = !strcmp(user, chat.user);
-	bool ping = !strncasecmp(mesg, chat.nick, strlen(chat.nick));
+	if (!isSelf(nick, user)) tabTouch(tag, nick);
+	urlScan(tag, mesg);
+	bool ping = !strncasecmp(mesg, self.nick, strlen(self.nick));
+	bool self = isSelf(nick, user);
 	uiFmt(
-		"%c\3%d%c%s%c\17 %s",
+		tag, "%c\3%d%c%s%c\17 %s",
 		ping["\17\26"], color(user), self["<("], nick, self[">)"], mesg
 	);
-	if (!self) tabTouch(nick);
 	if (ping) uiBeep();
-	urlScan(mesg);
 }
 
 static void handleNotice(char *prefix, char *params) {
 	char *nick, *user, *chan, *mesg;
 	shift(prefix, &nick, &user, NULL, params, 2, 0, &chan, &mesg);
-	if (strcmp(chan, chat.join)) return;
+	struct Tag tag = TAG_DEFAULT;
+	if (user) tag = (strcmp(chan, self.nick) ? tagFor(chan) : tagFor(nick));
+	if (!isSelf(nick, user)) tabTouch(tag, nick);
+	urlScan(tag, mesg);
 	uiFmt(
-		"\3%d-%s-\3 %s",
+		tag, "\3%d-%s-\3 %s",
 		color(user), nick, mesg
 	);
-	tabTouch(nick);
-	urlScan(mesg);
 }
 
 static const struct {
@@ -287,6 +314,8 @@ static const struct {
 	{ "332", handle332 },
 	{ "352", handle352 },
 	{ "366", handle366 },
+	{ "372", handle372 },
+	{ "375", handle372 },
 	{ "432", handle432 },
 	{ "433", handle432 },
 	{ "JOIN", handleJoin },