summaryrefslogtreecommitdiff
path: root/blabouncer.c
diff options
context:
space:
mode:
authorLuke Bratch <luke@bratch.co.uk>2019-05-19 15:59:08 +0100
committerLuke Bratch <luke@bratch.co.uk>2019-05-19 15:59:08 +0100
commit4b17824d5d2859a6410a28c18ef0c97ddd708d07 (patch)
tree2e42b9702cd9050f13e1f0eecfa6d758d34b77f2 /blabouncer.c
parentfa964744e02997d81083f1bab5194086754c2b6f (diff)
Add support for automatically JOINing channels specified in the configuration file.
Diffstat (limited to 'blabouncer.c')
-rw-r--r--blabouncer.c67
1 files changed, 63 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");