From e9d4ad3c33b81ff56c4e4b2cac4aad559a303104 Mon Sep 17 00:00:00 2001 From: Luke Bratch Date: Sun, 15 Sep 2019 14:47:44 +0100 Subject: Start tracking nicks in channels (upon JOIN/PART/QUIT/NICK) and use that to correctly log QUITs in the replay log and normal log(s). --- message.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) (limited to 'message.c') diff --git a/message.c b/message.c index ed27173..869a1ce 100644 --- a/message.c +++ b/message.c @@ -197,6 +197,11 @@ int processservermessage(SSL *server_ssl, char *str, struct client *clients, int debugprint(DEBUG_FULL, "Server JOIN: nick is NOT ours ('%s' vs '%s').\n", prefixcopy, ircdstate->ircnick); } + // Add the JOINing nick to our local channel struct + if (!addnicktochannel(tokens[0], tokens[2], channels)) { + debugprint(DEBUG_CRIT, "Failed to add nick to channel struct.\n"); + } + // And then send to all clients sendtoallclients(clients, str, sourcefd, settings); @@ -231,6 +236,11 @@ int processservermessage(SSL *server_ssl, char *str, struct client *clients, int debugprint(DEBUG_FULL, "Server PART: nick is NOT ours ('%s' vs '%s').\n", prefixcopy, ircdstate->ircnick); } + // Remove the PARTing nick from our local channel struct + if (!removenickfromchannel(tokens[0], tokens[2], channels)) { + debugprint(DEBUG_CRIT, "Failed to remove nick from channel struct.\n"); + } + // And then send to all clients sendtoallclients(clients, str, sourcefd, settings); @@ -248,6 +258,45 @@ int processservermessage(SSL *server_ssl, char *str, struct client *clients, int 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]); + + // And then send to all clients + sendtoallclients(clients, str, sourcefd, settings); + + // Write to replay log if replay logging enabled + if (settings->replaylogging) { + writereplayline(str, settings->basedir); + } + + // Get each channel the QUITting user was in, and log the quit from that channel + if (settings->logging) { + char quitnick[MAXNICKLENGTH]; + strcpy(quitnick, tokens[0]); + extractnickfromprefix(quitnick); + for (int i = 0; i < MAXCHANNELS; i++) { + if (channels[i].name[0]) { + for (int j = 0; j < MAXCHANNICKS; j++) { + if (strlen(channels[i].nicks[j]) == strlen(quitnick) && !strcmp(channels[i].nicks[j], quitnick)) { + char logstring[MAXDATASIZE]; + snprintf(logstring, MAXDATASIZE, "%s %s", channels[i].name, str); + logline(logstring, ircdstate, settings->basedir, LOG_QUIT); + break; + } + } + } + } + } + + // Remove the QUITting nick from our local channel struct + if (!removenickfromallchannels(tokens[0], channels)) { + debugprint(DEBUG_CRIT, "Failed to remove nick from channel structs.\n"); + } + + return 1; + } + // Channel topics/names/nicks/etc. // Server 331 (RPL_NOTOPIC) the topic is blank which we track by having a set timestamp of 0 if (strncmp(tokens[1], "331", strlen(tokens[1])) == 0) { @@ -288,6 +337,12 @@ int processservermessage(SSL *server_ssl, char *str, struct client *clients, int } } } + + // Update our local channels struct with all nicks from this RPL_NAMREPLY + if (!addnamereplytochannel(str, channels)) { + debugprint(DEBUG_CRIT, "Failed to add RPL_NAMREPLY to channels.\n"); + } + return 1; // Server 366 (RPL_ENDOFNAMES), relay to all clients if we've just JOINed the channel, or relay to // and decrement from any clients who were waiting on RPL_NAMREPLY if it's an existing channel. @@ -420,6 +475,11 @@ int processservermessage(SSL *server_ssl, char *str, struct client *clients, int free(prefixcopy); } + // Update old nick to the new nick in our local channel struct + if (!updatenickinallchannels(tokens[0], tokens[2], channels)) { + debugprint(DEBUG_CRIT, "Failed to update old nick to new nick in channels.\n"); + } + // Relay to all clients sendtoallclients(clients, str, sourcefd, settings); -- cgit v1.2.3