diff options
-rw-r--r-- | TODO | 2 | ||||
-rw-r--r-- | blabouncer.c | 2 | ||||
-rw-r--r-- | functions.c | 13 | ||||
-rw-r--r-- | message.c | 3 | ||||
-rw-r--r-- | replay.c | 23 | ||||
-rw-r--r-- | replay.h | 2 | ||||
-rw-r--r-- | structures.h | 1 |
7 files changed, 36 insertions, 10 deletions
@@ -10,4 +10,4 @@ Ensure replayed lines don't exceed IRC message maximum length due to inserted ti Log server messages to file. -Is there a way to log nick changes to the normal log despite not tracking channels or nicks in each channel? +Is there a way to log nick changes to the normal log despite not tracking nicks in each channel? (We do track channel names themselves.) diff --git a/blabouncer.c b/blabouncer.c index 7d8dc06..cfc1f2d 100644 --- a/blabouncer.c +++ b/blabouncer.c @@ -413,6 +413,8 @@ void dochat(int *serversockfd, int *clientsockfd, struct settings *settings) { ircdstate.reconnecting = 0; ircdstate.clientchangetime = time(NULL); ircdstate.clientsnonetime = time(NULL); + // Record the time we launched (for comparisons later) + ircdstate.launchtime = time(NULL); // Struct of client codes // Used to track the last time a client identifying as a given client connected to handle auto replay for a known client. diff --git a/functions.c b/functions.c index bbbd9dd..0a03ca9 100644 --- a/functions.c +++ b/functions.c @@ -811,7 +811,7 @@ int doreplay(int sourcefd, int replayseconds, struct client *clients, struct set // Replay those lines! for (int i = 0; i < numlines; i++) { - if (!readreplayline(replayseconds, i, outgoingmsg, settings->basedir, settings->replaydates)) { + if (!readreplayline(replayseconds, i, outgoingmsg, settings, ircdstate)) { debugprint(DEBUG_CRIT, "Error requesting replay line.\n"); return 0; } @@ -860,6 +860,17 @@ int doreplay(int sourcefd, int replayseconds, struct client *clients, struct set } } + // Separate special check for if a NICK change is from us but it isn't our current nick + if (strncmp(tokens[1], "NICK", strlen("NICK")) == 0) { + extractnickfromprefix(tokens[0]); + + if (strncmp(tokens[0], ircdstate->ircnick, strlen(tokens[0])) == 0) { + debugprint(DEBUG_FULL, "Not sending '%s' replay line '%s'.\n", tokens[1], outgoingmsg); + free(strcopyPtr); + continue; + } + } + free(strcopyPtr); debugprint(DEBUG_FULL, "Sending replay line: '%s'.\n", outgoingmsg); @@ -416,7 +416,8 @@ int processservermessage(SSL *server_ssl, char *str, struct client *clients, int writereplayline(str, settings->basedir); } - // TODO - Is there a way to log nick changes to the normal log despite not tracking channels or nicks in each channel? + // TODO - Is there a way to log nick changes to the normal log despite not tracking nicks in each channel? + // (We do track channel names themselves.) free(svrprefixcopy); return 1; @@ -219,19 +219,21 @@ int replaylines(int seconds, char *basedir) { } // Set 'str' to the line in the log with a timestamp of greater than 'seconds' -// seconds ago, plus however many lines 'linenum' is set to. 'basedir' is the -// directory in which to find 'replay.log'. +// seconds ago, plus however many lines 'linenum' is set to. // Also modify the line to include a timestamp in the form "[HH:MM:SS]", or [DD/MM/YY HH:MM:SS] -// if replaydates == 1. +// if settings.replaydates == 1. // Returns 1 on success, or 0 on failure. // TODO - This is horribly inefficient since it re-reads the entire file each call, rewrite this! -int readreplayline(int seconds, int linenum, char *str, char *basedir, int replaydates) { +int readreplayline(int seconds, int linenum, char *str, struct settings *settings, struct ircdstate *ircdstate) { FILE *fp; char line[MAXCHAR]; char filename[PATH_MAX]; // Build path - snprintf(filename, PATH_MAX, "%s/replay.log", basedir); + if (!snprintf(filename, PATH_MAX, "%s/replay.log", settings->basedir)) { + debugprint(DEBUG_CRIT, "debuglog(): Error while preparing replay path, exiting!\n"); + exit(1); + } int count = 0; @@ -257,10 +259,19 @@ int readreplayline(int seconds, int linenum, char *str, char *basedir, int repla // If the line is within range of the requested time... if (timestamp >= timenow - seconds) { + // ...and it wasn't before blabouncer launched... + if (timestamp <= ircdstate->launchtime) { + // Don't replay if this replay line happened before blabouncer launched, + // to avoid weird synchronisation issues with uncertain events from before + // we launched. + debugprint(DEBUG_FULL, "readreplayline(): Ignoring line '%s' from before we launched.\n", line); + continue; + } + // ...and it is the current requested line then return it if (count == linenum) { // Insert our formatted [HH:MM:SS] timestamp into the message - formattime(line, replaydates); + formattime(line, settings->replaydates); strncpy(str, line, strlen(line)); str[strlen(line)] = '\0'; @@ -40,7 +40,7 @@ int replaylines(int seconds, char *basedir); -int readreplayline(int seconds, int linenum, char *str, char *basedir, int replaydates); +int readreplayline(int seconds, int linenum, char *str, struct settings *settings, struct ircdstate *ircdstate); // Returns the number of seconds ago that 'nick' last spoke, or -1 if there is a problem. // 'basedir' is the directory in which to find 'replay.log'. diff --git a/structures.h b/structures.h index 66c34d0..e58c1b1 100644 --- a/structures.h +++ b/structures.h @@ -52,6 +52,7 @@ struct ircdstate { char oldnick[MAXNICKLENGTH]; // Set temporarily if we end up reconnecting in case we need to tell existing clients about a nick change int clientchangetime; // The last time a client registered or disconnected int clientsnonetime; // The last time there were no clients registered + int launchtime; // The time blabouncer was launched }; // Structure of settings either to be read from the configuration file or set/changed at runtime |