From 243d947c43a4f71c2a027e9909a154ab48c09907 Mon Sep 17 00:00:00 2001 From: Luke Bratch Date: Wed, 8 May 2019 14:13:11 +0100 Subject: Remove PARTed channels from channel array so new clients don't JOIN previously PARTed channels --- blabouncer.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 9 deletions(-) (limited to 'blabouncer.c') diff --git a/blabouncer.c b/blabouncer.c index f0e57dd..d3ba587 100644 --- a/blabouncer.c +++ b/blabouncer.c @@ -6,7 +6,6 @@ // - Do we actually need to store the modes in the channel struct? // - Get CAP from server and relay to client // - Add blabouncer MOTD (375, 372, 376) -// - Need to delete channels from struct when PARTing them // - "01:53:47 -!- ServerMode/#test [b] by irc.tghost.co.uk" on existing clients when new client connects // // Example WHOIS reply: @@ -153,11 +152,29 @@ int sendtoserver(int *serversockfd, char *str, int str_len) { return 0; } +int removechannel(struct channel *channels, char *name) { + printf("removechannel(): given \"%s\".\n", name); + + // Find the channel in the channel array... + for (int i = 0; i < MAXCHANNELS; i++) { + if (strncmp(channels[i].name, name, strlen(name)) == 0) { + // ..and NULL its name (0th character = '\0') + channels[i].name[0] = '\0'; + printf("removechannel(): channel removed.\n"); + return 1; + } + } + + perror("error: removechannel() didn't remove a channel\n"); + + // TODO - Make a failed return do something to callers + return 0; +} + int createchannel(struct channel *channels, char *name, char *topic, char *topicwho, char *topicwhen, char *modes, char *namestype) { printf("createchannel(): given \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", and \"%s\".\n", name, topic, topicwho, topicwhen, modes, namestype); - - // Find a free slot in the array (with the channel name is not set (0th character is '\0')... + // Find a free slot in the array (when the channel name is not set (0th character is '\0'))... for (int i = 0; i < MAXCHANNELS; i++) { if (!channels[i].name[0]) { // ...and set the name and topic @@ -168,10 +185,12 @@ int createchannel(struct channel *channels, char *name, char *topic, char *topic strncpy(channels[i].modes, modes, strlen(modes)); strncpy(channels[i].namestype, topic, strlen(namestype)); return 1; - break; + break; // TODO - This should be safe to remove since return is hit first } } + perror("error: createchannel() didn't create a channel\n"); + // TODO - Make a failed return do something to callers return 0; } @@ -387,6 +406,16 @@ int processircmessage(int *serversockfd, int *clientsockfd, char *str, int sourc return 1; } + // Server PART received? Remove from our local channel list. + if (strncmp(tokens[1], "PART", strlen(tokens[1])) == 0) { + printf("Server PART found and it is: %s with length %zd! Next token is '%s'. Adding to local channel list.\n", tokens[0], strlen(tokens[0]), tokens[2]); + removechannel(channels, tokens[2]); + + // And then send to all clients + sendtoallclients(clientsockfd, fdmax, arr_clients, str, sourcefd); + return 1; + } + // Channel topics/names/nicks/etc. // Server 332 (RPL_TOPIC) set the channel topic if (strncmp(tokens[1], "332", strlen(tokens[1])) == 0) { @@ -414,6 +443,7 @@ int processircmessage(int *serversockfd, int *clientsockfd, char *str, int sourc addusertochannel(channels, tokens[4], tokens[i]); } } + // Don't return if we got here because this means we didn't process something above } @@ -542,7 +572,15 @@ int processircmessage(int *serversockfd, int *clientsockfd, char *str, int sourc close(sourcefd); disconnectclient(sourcefd, arr_clients); return 1; - } + } + + // Just send PART to server and let it talk back to clients as required + if (strncmp(tokens[0], "PART", strlen(tokens[0])) == 0) { + printf("Client PART found and it is: %s with length %zd! Sending to server...\n", tokens[0], strlen(tokens[0])); + sendtoserver(serversockfd, str, strlen(str)); + return 1; + } + break; default: fprintf(stderr, "Unexpected raw IRC string source!\n"); @@ -601,7 +639,7 @@ int processrawstring(int *serversockfd, int *clientsockfd, char *str, int source for (int i = 0; i < messagecount; i++) { // Copy to a temporary string so we still have the original in case it's not processed char *messagecopy = strdup(messages[i]); - if (processircmessage(serversockfd, clientsockfd, messagecopy, source, fdmax, arr_clients, sourcefd, ircdstrings, channels)) { + if (processircmessage(serversockfd, clientsockfd, messagecopy, source, fdmax, arr_clients, sourcefd, ircdstrings, channels)) { printf("Message processed: \"%s\", NULLing...\n", messages[i]); messages[i][0] = '\0'; } @@ -616,19 +654,19 @@ int processrawstring(int *serversockfd, int *clientsockfd, char *str, int source case SOURCE_SERVER: // If message(s) were from the real IRC server // Relay/send to all clients ("except" = 0 because this should send to all clients) // TODO - Is this really going to send the original string if we have messed it with it in processrawstring() and friends!? - printf("bouncer-server: sending \"%s\" to all clients, length %zd.\n", messages[i], strlen(messages[i])); + printf("bouncer-server: sending unprocessed messasge \"%s\" to all clients, length %zd.\n", messages[i], strlen(messages[i])); sendtoallclients(clientsockfd, fdmax, arr_clients, messages[i], EXCEPT_NONE); break; case SOURCE_CLIENT: // If message(s) were from a real IRC client // Send to server - printf("bouncer-client: sending \"%s\" to the server, length %zd.\n", messages[i], strlen(messages[i])); + printf("bouncer-client: sending unprocessed messasge \"%s\" to the server, length %zd.\n", messages[i], strlen(messages[i])); sendtoserver(serversockfd, messages[i], strlen(messages[i])); // send the same thing to all *other* clients (all except for source fd) sendtoallclients(clientsockfd, fdmax, arr_clients, messages[i], sourcefd); break; default: - fprintf(stderr, "Unexpected raw IRC string source!\n"); + fprintf(stderr, "Unexpected raw IRC string source for unprocessed messasge \"%s\", length %zd.!\n", messages[i], strlen(messages[i])); exit(1); } } -- cgit v1.2.3