From 7ac369cbe46739beac37d97642b65b98c46ffc4d Mon Sep 17 00:00:00 2001 From: Luke Bratch Date: Sun, 31 Mar 2024 22:17:16 +0100 Subject: Handle server KICK commands. --- message.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'message.c') diff --git a/message.c b/message.c index f9e65a2..9d85f63 100644 --- a/message.c +++ b/message.c @@ -247,6 +247,7 @@ int processservermessage(SSL *server_ssl, char *str, struct client *clients, int } // Remove the PARTing nick from our local channel struct + // TODO - don't bother with this if we did removechannel() above? if (!removenickfromchannel(tokens[0], tokens[2], channels, ircdstate->maxchannelcount)) { debugprint(DEBUG_CRIT, "Failed to remove nick from channel struct.\n"); } @@ -268,6 +269,43 @@ int processservermessage(SSL *server_ssl, char *str, struct client *clients, int return 1; } + // Server KICK received? Remove from our local channel list if it's us. + if (strncmp(tokens[1], "KICK", strlen(tokens[1])) == 0 && counter >= 3) { + debugprint(DEBUG_FULL, "Server KICK found and it is: %s with length %zd! Next token is '%s'. Removing from local channel list if it's us.\n", tokens[0], strlen(tokens[0]), tokens[2]); + + // If the user being KICKed is us, then we must have left a channel, so remove it from our local channel array. + // (If it's not us, then it's another user being KICKed from a channel, so just pass straight through to letting all our clients know.) + if ((strlen(tokens[3]) == strlen(ircdstate->ircnick)) && (strncmp(tokens[3], ircdstate->ircnick, strlen(tokens[3])) == 0)) { + debugprint(DEBUG_FULL, "Server KICK: nick is ours ('%s' vs '%s').\n", tokens[3], ircdstate->ircnick); + removechannel(channels, ircdstate->maxchannelcount, tokens[2]); + } else { + debugprint(DEBUG_FULL, "Server KICK: nick is NOT ours ('%s' vs '%s').\n", tokens[3], ircdstate->ircnick); + } + + // Remove the KICKed nick from our local channel struct + // TODO - removenickfromchannel() first argument expects ":nick!user@host" but we're passing "nick" here + // TODO - don't bother with this if we did removechannel() above? + if (!removenickfromchannel(tokens[3], tokens[2], channels, ircdstate->maxchannelcount)) { + debugprint(DEBUG_CRIT, "Server KICK: Failed to remove nick from channel struct.\n"); + } + + // And then send to all clients + sendtoallclients(clients, str, sourcefd, settings); + + // TODO - Consider whether replay for KICK needs to be special (like TOPIC/JOIN/PART/NICK/QUIT in sanitisereplay()) + // Write to replay log if replay logging enabled + if (settings->replaylogging) { + writereplayline(str, settings->basedir); + } + + // Write to normal log if logging enabled + if (settings->logging) { + logline(str, ircdstate, settings->basedir, LOG_KICK); + } + + return 1; + } + // Server QUIT received? Tell all clients and also remove the user from our local channels struct. if (strncmp(tokens[1], "QUIT", strlen(tokens[1])) == 0) { debugprint(DEBUG_FULL, "Server QUIT found and it is: %s with length %zd! Next token is '%s'.\n", tokens[0], strlen(tokens[0]), tokens[2]); -- cgit v1.2.3