summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Bratch <luke@bratch.co.uk>2021-01-18 21:51:00 +0000
committerLuke Bratch <luke@bratch.co.uk>2021-01-18 21:51:00 +0000
commita16d9bdecb572bb266a84ec90767d613ce8ce255 (patch)
tree865c745fab117969647ea722334f35304595a7d5
parent323e273bc7dbc2b244e536a10b6c370651c76b8a (diff)
Make the "channels" configuration file entry an array.
-rw-r--r--TODO4
-rw-r--r--blabouncer.c27
-rw-r--r--blabouncer.conf.example9
-rw-r--r--config.c9
-rw-r--r--functions.c46
-rw-r--r--structures.h4
6 files changed, 51 insertions, 48 deletions
diff --git a/TODO b/TODO
index edf1fdb..8d04065 100644
--- a/TODO
+++ b/TODO
@@ -4,8 +4,6 @@ Configurable rotation of replay and debug logs.
Configurable timestamp format in logs.
-Add a make install/uninstall/etc., add an "INSTALL" file, include a dependency listing.
-
macOS compiler may need limits.h included in structures.h.
"Starting log replay...." followed by "Unable to read replay log file!" even though replay seemed to work?
@@ -16,6 +14,6 @@ Can memory usage be reduced further? (e.g. better channel struct management)
Ability to load new certificate whilst running.
-Make the "channels" configuration file entry an array.
+JOINing a channel that is a substring of another channel breaks all sorts (e.g. both #blabouncer and #blabounce).
Crash when requesting 30 hour replay.
diff --git a/blabouncer.c b/blabouncer.c
index 982d504..89add3e 100644
--- a/blabouncer.c
+++ b/blabouncer.c
@@ -1052,12 +1052,27 @@ int main(int argc, char *argv[]) {
}
// 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");
+ ret = getconfarr("channels", settings.conffile, settings.autochannels);
+ if (!ret) {
+ for (int i = 0; i < MAXCONFARR; i++) {
+ settings.autochannels[i][0] = '\0';
+ }
+ } else if (ret == -1) {
+ // Remove any newlines from the middle of the string so error printing works nicely
+ for (size_t i = 0; i < strlen(settings.autochannels[0]) - 1; i++) {
+ if (settings.autochannels[0][i] == '\n') {
+ settings.autochannels[0][i] = ' ';
+ }
+ }
+ printf("main(): error getting 'autochannels' from configuration file: %s", settings.autochannels[0]);
+ exit(1);
+ }
+
+ // Make sure channel/key pairs aren't too long (since getconfarr() has to use MAXDATASIZE for all string lengths)
+ for (int i = 0; i < MAXCONFARR; i++) {
+ // +1 for the space between channel name and keys
+ if (settings.autochannels[i][0] && strlen(settings.autochannels[i]) > MAXCHANLENGTH + 1 + MAXCHANKEYLEN) {
+ printf("main(): error: specified channel name/key pair '%s' is too long, maximum lengths are %d (name) and %d (key).\n", settings.autochannels[i], MAXCHANLENGTH, MAXCHANKEYLEN);
exit(1);
}
}
diff --git a/blabouncer.conf.example b/blabouncer.conf.example
index 0513fdc..d77689c 100644
--- a/blabouncer.conf.example
+++ b/blabouncer.conf.example
@@ -32,9 +32,12 @@ nicks = {
username = "bounceusr"
realname = "Mr Bla Bouncer"
-# Channels to automatically join (comma-separated list, defaults to none)
-# Put channel keywords/passwords after channel names following a space.
-#channels = "#blabouncer keyword,#test"
+# Channels to automatically join (defaults to none)
+# Put channel keys/passwords after channel names (separated with a space)
+channels = {
+ "#blabouncer keyword"
+ "#test"
+}
# Auto replay mode upon a bouncer client connecting
# "none" = Don't auto replay
diff --git a/config.c b/config.c
index 5b706b0..3fa28a7 100644
--- a/config.c
+++ b/config.c
@@ -344,9 +344,12 @@ int createconfigfile(char *filename) {
"username = \"bounceusr\"\n"
"realname = \"Mr Bla Bouncer\"\n"
"\n"
- "# Channels to automatically join (comma-separated list, defaults to none)\n"
- "# Put channel keywords/passwords after channel names following a space.\n"
- "#channels = \"#blabouncer keyword,#test\"\n"
+ "# Channels to automatically join (defaults to none)\n"
+ "# Put channel keys/passwords after channel names (separated with a space)\n"
+ "channels = {\n"
+ " \"#blabouncer keyword\"\n"
+ " \"#test\"\n"
+ "}\n"
"\n"
"# Auto replay mode upon a bouncer client connecting\n"
"# \"none\" = Don't auto replay\n"
diff --git a/functions.c b/functions.c
index 5dd7586..6ed1d2f 100644
--- a/functions.c
+++ b/functions.c
@@ -1027,47 +1027,31 @@ int numclients(struct client *clients) {
// 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) {
+ if (settings->autochannels[0][0] == '\0') {
// None configured
debugprint(DEBUG_FULL, "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
- if (counter >= MAXAUTOCHANLEN) break; // Too many tokens
- debugprint(DEBUG_FULL, " >> 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);
- debugprint(DEBUG_CRIT, "error: channel name '%s' from configuration file too long, max length is '%d'.\n", tokens[counter], MAXCHANLENGTH);
- exit(1);
+ // Join all the channels
+ for (int i = 0; i < MAXCONFARR; i++) {
+ // Unless there are none left in the array
+ if (settings->autochannels[i][0] == '\0') {
+ debugprint(DEBUG_FULL, "joinautochannels(): Finishing joining %d channels.\n", i);
+ return 1;
}
- counter++;
- }
- // Join all the channels
- for (int i = 0; i < counter; i++) {
- debugprint(DEBUG_FULL, "joinautochannels(): Joining '%s'.\n", tokens[i]);
+ debugprint(DEBUG_FULL, "joinautochannels(): Joining '%s'.\n", settings->autochannels[i]);
char joinmsg[MAXDATASIZE];
- snprintf(joinmsg, MAXDATASIZE, "JOIN %s", tokens[i]);
- sendtoserver(server_ssl, joinmsg, strlen(joinmsg), 0, clients, settings);
+ if (!snprintf(joinmsg, MAXDATASIZE, "JOIN %s", settings->autochannels[i])) {
+ fprintf(stderr, "joinautochannels(): Error while preparing JOIN message!\n");
+ debugprint(DEBUG_CRIT, "joinautochannels(): Error while preparing JOIN message\n");
+ joinmsg[0] = '\0';
+ } else {
+ 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;
}
diff --git a/structures.h b/structures.h
index 26b7439..9e5f575 100644
--- a/structures.h
+++ b/structures.h
@@ -22,11 +22,11 @@
#define MAXDATASIZE 513 // max number of bytes we can get at once (RFC2812 says 512, plus one for null terminator)
#define MAXCHANLENGTH 50 // 50 according to RFC 2811 and RFC 2822
+#define MAXCHANKEYLEN 24 // Maxium channel key length, 23 determined by testing various clients/servers (plus one for null terminator)
#define MAXNICKLENGTH 64 // Randomly picked (TODO - is there an actual maximum number (ignoring the RFC preference of 9)?)
#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
#define CLIENTCODELEN 17 // Max length of a client code + 1 for null
#define MAXCLIENTCODES 64 // Max number of client codes to track
#define MAXCONFARR 10 // Max number of entries that a configuration array can have
@@ -67,7 +67,7 @@ struct settings {
char ircusername[MAXUSERNAMELEN]; // (Is this also true for the username? Can the server change that?)
char ircrealname[MAXREALNAMELEN];
char password[MAXDATASIZE];
- char autochannels[MAXAUTOCHANLEN];
+ char autochannels[MAXCONFARR][MAXDATASIZE]; // MAXDATASIZE instead of MAXCHANLENGTH + 1 + MAXCHANKEYLEN so getconfarr() only has one string size to deal with
char ircserver[HOST_NAME_MAX];
char ircserverport[MAXPORTLEN];
char ircserverpassword[MAXDATASIZE - 5]; // -5 for "PASS "