diff options
author | Luke Bratch <luke@bratch.co.uk> | 2019-05-19 15:59:08 +0100 |
---|---|---|
committer | Luke Bratch <luke@bratch.co.uk> | 2019-05-19 15:59:08 +0100 |
commit | 4b17824d5d2859a6410a28c18ef0c97ddd708d07 (patch) | |
tree | 2e42b9702cd9050f13e1f0eecfa6d758d34b77f2 | |
parent | fa964744e02997d81083f1bab5194086754c2b6f (diff) |
Add support for automatically JOINing channels specified in the configuration file.
-rw-r--r-- | blabouncer.c | 67 | ||||
-rw-r--r-- | blabouncer.conf | 3 |
2 files changed, 66 insertions, 4 deletions
diff --git a/blabouncer.c b/blabouncer.c index 022301f..fffc164 100644 --- a/blabouncer.c +++ b/blabouncer.c @@ -1,12 +1,9 @@ // TODO: -// - Might need to change channel struct nicks to be channel struct user struct with its own nick/modes/etc. -// - Get CAP from server and relay to client // - Should replay log do more than PRIVMSGs? -// - Configurable auto channels -// - Comma separated channel list in JOINs/PARTs // - Perhaps rename clients.ssl and server_ssl since they may not even be OpenSSL sockets // - Is it possible to replay JOINs/PARTs accurately? // - Remove any old channel name/mode/prefix code that isn't needed any more +// - Move debug output into some debug function // "server" means the real IRC server // "client" means bouncer clients @@ -53,6 +50,7 @@ #define MAXUSERNAMELEN 64 // Randomly picked (TODO - is there an actual maximum username length?) #define MAXREALNAMELEN 128 // Randomly picked (TODO - is there an actual maximum real name length?) #define MAXPORTLEN 6 // Up to 65535, so 5 characters + 1 for null +#define MAXAUTOCHANLEN 1024 // Randomly picked maximum length of the auto channel list struct channel { char name[MAXCHANLENGTH]; @@ -86,6 +84,7 @@ struct settings { char ircnick[MAXNICKLENGTH]; // In both settings and ircdstrings as settings is from our file whereas server may change ircdstrings copy char ircusername[MAXUSERNAMELEN]; // (Is this also true for the username? Can the server change that?) char ircrealname[MAXREALNAMELEN]; + char autochannels[MAXAUTOCHANLEN]; char ircserver[HOST_NAME_MAX]; char ircserverport[MAXPORTLEN]; char conffile[PATH_MAX]; @@ -575,6 +574,53 @@ int numclients(struct client *clients) { return count; } +// Join any channels that were configured to be automatically +// joined in the configuration file. +// Returns 1 on success or 0 on failure. +int joinautochannels(SSL *server_ssl, struct client *clients, struct settings *settings) { + if (strlen(settings->autochannels) == 0) { + // None configured + printf("joinautochannels(): none configured.\n"); + return 1; + } + + // Split string up into each channel + char tokens[MAXAUTOCHANLEN][MAXCHANLENGTH]; + int counter = 0; + + // Copy to a temporary string + char *strcopy = strdup(settings->autochannels); + // Keep track of initial pointer for free()ing later + char *strcopyPtr = strcopy; + + char *token; + + // Split on commas + while ((token = strsep(&strcopy, ",")) != NULL) { + if (*token == '\0') continue; // Skip consecutive matches + printf(" >> Auto channel: '%s', length '%ld'.\n", token, strlen(token)); + // Copy into the token array (strlen + 1 to get the NULL terminator) + strncpy(tokens[counter], token, strlen(token) + 1); + if (strlen(tokens[counter]) > MAXCHANLENGTH) { + printf("error: channel name '%s' from configuration file too long, max length is '%d'.\n", tokens[counter], MAXCHANLENGTH); + exit(1); + } + counter++; + } + + // Join all the channels + for (int i = 0; i < counter; i++) { + printf("joinautochannels(): Joining '%s'.\n", tokens[i]); + char joinmsg[MAXDATASIZE]; + snprintf(joinmsg, MAXDATASIZE, "JOIN %s", tokens[i]); + sendtoserver(server_ssl, joinmsg, strlen(joinmsg), 0, clients, settings); + } + + free(strcopyPtr); + // TODO - Can we fail here? Return 0 if so and make callers handle this if so. + return 1; +} + // Figure out what to do with each CRLF-split IRC message (if anything) // by splitting out the different components by space character (ASCII 0x20). // @@ -683,6 +729,8 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli // Receiving greeting 004 means we're now registered // Request IRCv3 multi-prefix extension so we can more accurately inform new clients about current user prefixes sendtoserver(server_ssl, "CAP REQ multi-prefix", strlen("CAP REQ multi-prefix"), 0, clients, settings); + // Join any auto channels set in the configuration file + joinautochannels(server_ssl, clients, settings); free(strcopyPtr); return 1; } @@ -2031,6 +2079,17 @@ int main(int argc, char *argv[]) { exit(1); } + // What, if anything, are the configured auto channels? + if (!getconfstr("channels", settings.conffile, settings.autochannels)) { + settings.autochannels[0] = '\0'; + } else { + // If something was set, make sure it's not too long + if (strlen(settings.autochannels) >= MAXAUTOCHANLEN) { + printf("main(): 'channels' option in configuration file is too long.\n"); + exit(1); + } + } + // What is the real IRC server address? if (!getconfstr("ircserver", settings.conffile, settings.ircserver)) { printf("main(): error getting 'ircserver' from configuration file.\n"); diff --git a/blabouncer.conf b/blabouncer.conf index 7297f9b..fbbf3ce 100644 --- a/blabouncer.conf +++ b/blabouncer.conf @@ -10,6 +10,9 @@ nick3 = "bbounce3" username = "bounceusr" realname = "Mr Bla Bouncer" +# Channels to automatically join (comma-separated list) +#channels = "#blabouncer,#test" + # How many seconds of replay log should be sent to connecting clients replayseconds = "7200" |