From 62e67b22e721d2e08c4a4d5dbc85e404fd2ba507 Mon Sep 17 00:00:00 2001 From: Luke Bratch Date: Sun, 19 May 2019 22:08:40 +0100 Subject: Don't log replay TOPIC/JOIN/PART if we're not in that channel, and don't ever replay them if they were from ourself. --- blabouncer.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 74 insertions(+), 4 deletions(-) (limited to 'blabouncer.c') diff --git a/blabouncer.c b/blabouncer.c index a6a811a..6d473c9 100644 --- a/blabouncer.c +++ b/blabouncer.c @@ -417,7 +417,7 @@ int channelgotnames(struct channel *channels, char *name) { if (strncmp(channels[i].name, name, strlen(name)) == 0) { if (channels[i].gotnames) { printf("channelgotnames(): channel '%s' gotnames was set, returning '%d'.\n", channels[i].name, channels[i].gotnames); - return channels[i].gotnames; + return i; } else { printf("channelgotnames(): channel '%s' gotnames was not set, returning '%d'.\n", channels[i].name, channels[i].gotnames); return 0; @@ -430,11 +430,34 @@ int channelgotnames(struct channel *channels, char *name) { return 0; } +// Check if we are in a channel named "name" or not. +// Return 1 if we are, or 0 if not. +int inchannel(struct channel *channels, char *name) { + // Make sure the name doesn't have any trailing CR or LF + // (But only if name is at least two characters long already) + if (strlen(name) >= 2) { + while (name[strlen(name) - 1] == '\r' || name[strlen(name) - 1] == '\n') { + name[strlen(name) - 1] = '\0'; + } + } + + for (int i = 0; i < MAXCHANNELS; i++) { + if (strncmp(channels[i].name, name, strlen(name)) == 0) { + printf("inchannel(): in channel '%s'.\n", name); + return 1; + } + } + + // We're not in the channel + printf("inchannel(): NOT in channel '%s'.\n", name); + return 0; +} + // Send the requested number of lines of replay log to the requested client // 'sourcefd' is the client to send to, and replayseconds is the number of // seconds of replay to replay. // Returns 1 for success or 0 for failure. -int doreplay(int sourcefd, int replayseconds, struct client *clients, struct settings *settings, struct ircdstrings *ircdstrings) { +int doreplay(int sourcefd, int replayseconds, struct client *clients, struct settings *settings, struct ircdstrings *ircdstrings, struct channel *channels) { char outgoingmsg[MAXDATASIZE]; // Figure out how many lines to replay @@ -460,6 +483,53 @@ int doreplay(int sourcefd, int replayseconds, struct client *clients, struct set printf("Error requesting replay line.\n"); exit(1); } + + // Check if the replay line is a TOPIC, a JOIN, or a PART so we don't + // replay those if we are not currently in the channel they are from + // otherwise clients and state go a bit mad. + // Never replay them if they are from us. + + // Copy to a temporary string + char *strcopy = strdup(outgoingmsg); + // Keep track of initial pointer for free()ing later + char *strcopyPtr = strcopy; + + // Build array of each space-separated token + char tokens[3][MAXDATASIZE]; + char *token; + + for (int j = 0; j < 3; j++) { + // Try to split + if ((token = strsep(&strcopy, " ")) == NULL) { + printf("doreplay(): error splitting string on iteration %d, exiting!\n", j); + exit(1); + } + // Copy into the token array (strlen + 1 to get the NULL terminator) + strncpy(tokens[j], token, strlen(token) + 1); + } + + if (strncmp(tokens[1], "TOPIC", strlen("TOPIC")) == 0 || + strncmp(tokens[1], "JOIN", strlen("JOIN")) == 0 || + strncmp(tokens[1], "PART", strlen("PART")) == 0) { + // Skip over colon if present in channel name + int offset = 0; + if (tokens[2][0] == ':') { + offset = 1; + } + + // To make sure it's not us + extractnickfromprefix(tokens[0]); + + // Check if we're currently in this channel or if the log line is from us + if (!inchannel(channels, tokens[2] + offset) || strncmp(tokens[0], ircdstrings->ircnick, strlen(tokens[0])) == 0) { + printf("Not sending '%s' replay line '%s'.\n", tokens[1], outgoingmsg); + free(strcopyPtr); + continue; + } + } + + free(strcopyPtr); + printf("Sending replay line: '%s'.\n", outgoingmsg); sendtoclient(sourcefd, outgoingmsg, clients, settings); } @@ -1303,7 +1373,7 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli clients[arrindex(clients, sourcefd)].registered = 1; // Catch the client up with the default number of seconds of replay - doreplay(sourcefd, settings->replayseconds, clients, settings, ircdstrings); + doreplay(sourcefd, settings->replayseconds, clients, settings, ircdstrings, channels); free(strcopyPtr); return 1; @@ -1488,7 +1558,7 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli return 1; } - doreplay(sourcefd, replayseconds, clients, settings, ircdstrings); + doreplay(sourcefd, replayseconds, clients, settings, ircdstrings, channels); free(strcopyPtr); return 1; // Unrecognised BLABOUNCER command received, send some help instructions -- cgit v1.2.3