From 424ba496e6affc6d9421b1ce7147b34bf5c7913b Mon Sep 17 00:00:00 2001 From: Luke Bratch Date: Mon, 16 Sep 2019 20:21:06 +0100 Subject: Log user/channel mode setting in the replay and normal logs. --- TODO | 2 -- logging.c | 24 +++++++++++++++++++++++- logging.h | 4 ++++ message.c | 49 ++++++++++++++++++++++++++++--------------------- 4 files changed, 55 insertions(+), 24 deletions(-) diff --git a/TODO b/TODO index c21e482..b0eedee 100644 --- a/TODO +++ b/TODO @@ -1,3 +1 @@ All the TODOs sprinkled throughout the code! - -User/channel mode logging. diff --git a/logging.c b/logging.c index b000c28..2079822 100644 --- a/logging.c +++ b/logging.c @@ -52,6 +52,9 @@ // :oldnick!bar@baz NICK :newnick // Same manual 'channelname' prepending as LOG_QUIT above. // +// If LOG_MODE then it expects a string in the format: +// :nick!bar@baz MODE #channel foo bar [foo bar...] +// // With the ":foo!bar@baz "prefix being important for all // types. // @@ -292,6 +295,24 @@ int logline(char *str, struct ircdstate *ircdstate, char *basedir, int type) { break; + case LOG_MODE: + // Extract nick from prefix + extractnickfromprefix(tokens[0]); + + // Build a friendly message (e.g. "nick sets mode #channel +ov nick1 nick2") + if (!snprintf(line, MAXCHAR, "%s sets mode %s %s", tokens[0], tokens[2], str)) { + debugprint(DEBUG_CRIT, "logline(): Error while preparing friendly message for mode log message, returning!\n"); + return 0; + } + + // Build the log filename + if (!snprintf(filename, MAXCHAR, "%s/logs/%s.log", basedir, to)) { + debugprint(DEBUG_CRIT, "logline(): Error while preparing log filename for mode, returning!\n"); + return 0; + } + + break; + default : debugprint(DEBUG_CRIT, "logline(): Unknown log type '%d', returning 0.\n", type); return 0; @@ -352,7 +373,8 @@ int logline(char *str, struct ircdstate *ircdstate, char *basedir, int type) { return 0; } } - } else if (type == LOG_JOINPART || type == LOG_TOPIC || type == LOG_NETWORK || type == LOG_QUIT || type == LOG_NICK) { + } else if (type == LOG_JOINPART || type == LOG_TOPIC || type == LOG_NETWORK || + type == LOG_QUIT || type == LOG_NICK || LOG_MODE) { // Prepend the time string char line2[MAXCHAR]; if (!snprintf(line2, MAXCHAR, "%s %s", timestr, line)) { diff --git a/logging.h b/logging.h index c2b6d4f..b4db7e4 100644 --- a/logging.h +++ b/logging.h @@ -39,6 +39,7 @@ #define LOG_NETWORK 3 #define LOG_QUIT 4 #define LOG_NICK 5 +#define LOG_MODE 6 #define DEBUG_CRIT 0 #define DEBUG_SOME 1 #define DEBUG_FULL 2 @@ -78,6 +79,9 @@ // channelname :oldnick!bar@baz NICK :newnick // Same manual 'channelname' prepending as LOG_QUIT above. // +// If LOG_MODE then it expects a string in the format: +// :nick!bar@baz MODE #channel foo bar [foo bar...] +// // With the ":foo!bar@baz "prefix being important for all // types. // diff --git a/message.c b/message.c index e7139bc..95ffb3a 100644 --- a/message.c +++ b/message.c @@ -521,31 +521,38 @@ int processservermessage(SSL *server_ssl, char *str, struct client *clients, int debugprint(DEBUG_FULL, "Server MODE found and it is: %s with length %zd! Next token is '%s'. Analysing...\n", tokens[1], strlen(tokens[1]), tokens[2]); - // 4 tokens could be either our initial mode or a channel mode (or something else - TODO - what else?) - if (counter == 4) { - // Might be our initial mode (e.g. ":nick MODE nick :+iwz") - char comparison[MAXDATASIZE]; - snprintf(comparison, MAXDATASIZE, ":%s MODE %s :", ircdstate->ircnick, ircdstate->ircnick); - if (strncmp(str, comparison, strlen(comparison)) == 0) { - // Looks like it! - debugprint(DEBUG_FULL, "Our initial MODE found (%s), storing for later.\n", tokens[3]); - // Store in ircdstate for when clients connect and relay to current clients. - strcpy(ircdstate->mode, tokens[3]); - - // Relay to all current clients anyway - TODO - Necessary? - sendtoallclients(clients, str, sourcefd, settings); + // Might be our initial mode (e.g. ":nick MODE nick :+iwz") + char comparison[MAXDATASIZE]; + snprintf(comparison, MAXDATASIZE, ":%s MODE %s :", ircdstate->ircnick, ircdstate->ircnick); + if (strncmp(str, comparison, strlen(comparison)) == 0) { + // Looks like it! + debugprint(DEBUG_FULL, "Our initial MODE found (%s), storing for later.\n", tokens[3]); + // Store in ircdstate for when clients connect and relay to current clients. + strcpy(ircdstate->mode, tokens[3]); + + // Relay to all current clients anyway - TODO - Necessary? + sendtoallclients(clients, str, sourcefd, settings); - return 1; - } + return 1; + } - // Might be a channel mode (e.g. ":nick!user@host MODE #channel +s") - if (tokens[2][0] == '#') { - // Looks like it! Tell all clients. - debugprint(DEBUG_FULL, "Channel MODE found (%s %s), telling all clients.\n", tokens[2], tokens[3]); - sendtoallclients(clients, str, sourcefd, settings); + // Might be a channel mode (e.g. ":nick!user@host MODE #channel +s") + if (tokens[2][0] == '#') { + // Looks like it! Tell all clients. + debugprint(DEBUG_FULL, "Channel MODE found (%s %s), telling all clients.\n", tokens[2], tokens[3]); + sendtoallclients(clients, str, sourcefd, settings); - return 1; + // 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_MODE); } + + return 1; } // Relay to all current clients if not processed by the above -- cgit v1.2.3