summary refs log tree commit diff
diff options
context:
space:
mode:
authorJune McEnroe <june@causal.agency>2019-10-23 00:48:08 -0400
committerJune McEnroe <june@causal.agency>2019-10-23 00:48:08 -0400
commit36ef043193ad08f66e02d8d15a1b751736a7dc4c (patch)
tree60dd21351b1a3154c92e66cf9228815ed42b4515
parentClean up state somewhat (diff)
downloadpounce-36ef043193ad08f66e02d8d15a1b751736a7dc4c.tar.gz
pounce-36ef043193ad08f66e02d8d15a1b751736a7dc4c.zip
Don't assume commands have targets and handle ERROR
-rw-r--r--state.c37
1 files changed, 20 insertions, 17 deletions
diff --git a/state.c b/state.c
index e277954..da777da 100644
--- a/state.c
+++ b/state.c
@@ -68,47 +68,50 @@ enum { ParamCap = 15 };
 struct Command {
 	const char *origin;
 	const char *name;
-	const char *target;
 	const char *params[ParamCap];
 };
 typedef void Handler(struct Command);
 
 static void handleCap(struct Command cmd) {
-	bool ack = cmd.params[0] && !strcmp(cmd.params[0], "ACK");
-	bool sasl = cmd.params[1] && !strcmp(cmd.params[1], "sasl");
+	bool ack = cmd.params[1] && !strcmp(cmd.params[1], "ACK");
+	bool sasl = cmd.params[2] && !strcmp(cmd.params[2], "sasl");
 	if (!ack || !sasl) errx(EX_CONFIG, "server does not support SASL");
 	serverAuth();
 }
 
 static void handleReplyWelcome(struct Command cmd) {
-	if (!cmd.params[0]) errx(EX_PROTOCOL, "RPL_WELCOME without message");
+	if (!cmd.params[1]) errx(EX_PROTOCOL, "RPL_WELCOME without message");
 	set(&intro.origin, cmd.origin);
-	set(&intro.welcome, cmd.params[0]);
-	set(&nick, cmd.target);
+	set(&nick, cmd.params[0]);
+	set(&intro.welcome, cmd.params[1]);
 }
 static void handleReplyYourHost(struct Command cmd) {
-	if (!cmd.params[0]) errx(EX_PROTOCOL, "RPL_YOURHOST without message");
-	set(&intro.yourHost, cmd.params[0]);
+	if (!cmd.params[1]) errx(EX_PROTOCOL, "RPL_YOURHOST without message");
+	set(&intro.yourHost, cmd.params[1]);
 }
 static void handleReplyCreated(struct Command cmd) {
-	if (!cmd.params[0]) errx(EX_PROTOCOL, "RPL_CREATED without message");
-	set(&intro.created, cmd.params[0]);
+	if (!cmd.params[1]) errx(EX_PROTOCOL, "RPL_CREATED without message");
+	set(&intro.created, cmd.params[1]);
 }
 static void handleReplyMyInfo(struct Command cmd) {
-	if (!cmd.params[3]) errx(EX_PROTOCOL, "RPL_MYINFO without 4 parameters");
-	set(&intro.myInfo[0], cmd.params[0]);
-	set(&intro.myInfo[1], cmd.params[1]);
-	set(&intro.myInfo[2], cmd.params[2]);
-	set(&intro.myInfo[3], cmd.params[3]);
+	if (!cmd.params[4]) errx(EX_PROTOCOL, "RPL_MYINFO without 4 parameters");
+	set(&intro.myInfo[0], cmd.params[1]);
+	set(&intro.myInfo[1], cmd.params[2]);
+	set(&intro.myInfo[2], cmd.params[3]);
+	set(&intro.myInfo[3], cmd.params[4]);
 }
 
 static void handleReplyISupport(struct Command cmd) {
-	for (size_t i = 0; i < ParamCap; ++i) {
+	for (size_t i = 1; i < ParamCap; ++i) {
 		if (!cmd.params[i] || strchr(cmd.params[i], ' ')) break;
 		iSupportSet(cmd.params[i]);
 	}
 }
 
+static void handleError(struct Command cmd) {
+	errx(EX_UNAVAILABLE, "%s", cmd.params[0]);
+}
+
 static const struct {
 	const char *cmd;
 	Handler *fn;
@@ -119,6 +122,7 @@ static const struct {
 	{ "004", handleReplyMyInfo },
 	{ "005", handleReplyISupport },
 	{ "CAP", handleCap },
+	{ "ERROR", handleError },
 };
 static const size_t HandlersLen = sizeof(Handlers) / sizeof(Handlers[0]);
 
@@ -130,7 +134,6 @@ void stateParse(char *line) {
 	}
 
 	cmd.name = strsep(&line, " ");
-	cmd.target = strsep(&line, " ");
 	for (size_t i = 0; line && i < ParamCap; ++i) {
 		if (line[0] == ':') {
 			cmd.params[i] = line;