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). --- logging.c | 43 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) (limited to 'logging.c') diff --git a/logging.c b/logging.c index ff41911..f6fa23e 100644 --- a/logging.c +++ b/logging.c @@ -40,6 +40,14 @@ // If LOG_NETWORK then it just logs the string verbatim in // a file named 'ircdstate->ircdname'.log. // +// If LOG_QUIT then it expects a string in the format: +// channelname :nick!bar@baz QUIT :bla bla bla +// 'channelname' probably has to be prepended manually by the +// caller since it doesn't feature in the raw message from +// the IRCd. We need it in logline() to log to the relevant +// channel log file. The caller probably has to call logline() +// multiple times for each channel the nick was in. +// // With the ":foo!bar@baz "prefix being important for all // types. // @@ -224,6 +232,37 @@ int logline(char *str, struct ircdstate *ircdstate, char *basedir, int type) { break; + case LOG_QUIT: + // Build a friendly message (e.g. "#channel :nick!user@host QUIT :foo bar baz" -> "nick (user@host) has quit (foo bar baz)") + + // Find the bang in the prefix + // (ret and posbang defined above in case LOG_JOINPART) + if ((ret = strstr(tokens[1], "!")) != NULL) { + // Position within str of "!" + posbang = ret - tokens[1]; + } else { + // No idea what happened, let's abandon ship + debugprint(DEBUG_CRIT, "logline(): Unable to find '!' within nick!user@host, returning!\n"); + return 0; + } + + // Make it a null character + tokens[1][posbang] = '\0'; + + // Strip the prefix from the quit message + stripprefix(str); + + // Build a friendly message (e.g. "nick (user@host) has quit (Quit: message)") + snprintf(line, MAXCHAR, "%s (%s) has quit (%s)", tokens[1] + 1, tokens[1] + posbang + 1, str); + + // Build the log filename + if (!snprintf(filename, MAXCHAR, "%s/logs/%s.log", basedir, tokens[0])) { + debugprint(DEBUG_CRIT, "logline(): Error while preparing log filename for quit, returning!\n"); + return 0; + } + + break; + default : debugprint(DEBUG_CRIT, "logline(): Unknown log type '%d', returning 0.\n", type); return 0; @@ -284,7 +323,7 @@ int logline(char *str, struct ircdstate *ircdstate, char *basedir, int type) { return 0; } } - } else if (type == LOG_JOINPART || type == LOG_TOPIC || type == LOG_NETWORK) { + } else if (type == LOG_JOINPART || type == LOG_TOPIC || type == LOG_NETWORK || type == LOG_QUIT) { // Prepend the time string char line2[MAXCHAR]; if (!snprintf(line2, MAXCHAR, "%s %s", timestr, line)) { @@ -300,7 +339,7 @@ int logline(char *str, struct ircdstate *ircdstate, char *basedir, int type) { // Ensure the line finishes with CRLF appendcrlf(line); - debugprint(DEBUG_FULL, "logline(): Complete log string to write: '%s', length '%ld'.\n", line, strlen(line)); + debugprint(DEBUG_FULL, "logline(): Complete log string to write: '%s' to '%s', length '%ld'.\n", line, filename, strlen(line)); // Write complete line to file if ((bytes = fprintf(fp, "%s", line)) < 0) { -- cgit v1.2.3