summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Bratch <luke@bratch.co.uk>2025-08-09 10:54:48 +0100
committerLuke Bratch <luke@bratch.co.uk>2025-08-09 10:54:48 +0100
commit2136716bdf99b108d64268088742f258ed79fe29 (patch)
tree30e42b5fac978f97ae5d0f0c04948d12738f2826
parentb2089e21606aed1a6aaa9644dbe0d2fe998ae1e0 (diff)
List all missing required configuration file options at startup.
-rw-r--r--TODO2
-rw-r--r--blabouncer.c110
-rw-r--r--structures.h1
3 files changed, 62 insertions, 51 deletions
diff --git a/TODO b/TODO
index f736661..df0cdb9 100644
--- a/TODO
+++ b/TODO
@@ -65,5 +65,3 @@ NickServ HELP with SA receiving full message in one go? e.g. oper 05/01/2025 10:
/NAMES doesn't show names in client.
Allow specifying time zone for timestamps in config.
-
-List all missing configuration options if any are missing at startup.
diff --git a/blabouncer.c b/blabouncer.c
index b57fb4a..b4c88df 100644
--- a/blabouncer.c
+++ b/blabouncer.c
@@ -1085,50 +1085,47 @@ int main(int argc, char *argv[]) {
// Populate settings from configuration file
// TODO - Try to share some/all of this code with the rehash() settings loading
+ int conffail = 0;
+ char conffailmsg[STDERRMAX];
+
// What is the auto replay mode?
if (!getconfstr("replaymode", settings.conffile, settings.replaymode)) {
- printf("main(): error getting 'replaymode' from configuration file. (Recent upgrade? See blabouncer.conf.example for required settings.)\n");
- exit(1);
- } else {
- if (strcmp(settings.replaymode, "none") && strcmp(settings.replaymode, "time") && strcmp(settings.replaymode, "lastspoke") &&
- strcmp(settings.replaymode, "noclients") && strcmp(settings.replaymode, "lastchange") && strcmp(settings.replaymode, "perclient")) {
- printf("main(): replaymode in configuration file must be one of \"none\", \"time\", \"lastspoke\", \"noclients\", \"lastchange\" or \"perclient\".\n");
- exit(1);
- }
+ conffail = 1;
+ strncat(conffailmsg, "Error getting 'replaymode' from configuration file.\n", sizeof conffailmsg - strlen(conffailmsg) - 1);
}
// How many seconds of replay log should automatically be replayed - TODO - Can we do error checking on this?
settings.replayseconds = getconfint("replayseconds", settings.conffile);
// Don't worry if replaymode != "time"
- if (errno == ECONFINT && strcmp(settings.replaymode, "time") == 0) {
- printf("main(): error getting 'replayseconds' from configuration file. (Recent upgrade? See blabouncer.conf.example for required settings.)\n");
- exit(1);
+ if (errno == ECONFINT && strncmp(settings.replaymode, "time", strlen("time")) == 0) {
+ conffail = 1;
+ strncat(conffailmsg, "Error getting 'replayseconds' from configuration file with 'replaymode' set to \"time\".\n", sizeof conffailmsg - strlen(conffailmsg) - 1);
}
// Should sending replay logs include a datestamp?
settings.replaydates= getconfint("replaydates", settings.conffile);
if (errno == ECONFINT) {
- printf("main(): error getting 'replaydates' from configuration file. (Recent upgrade? See blabouncer.conf.example for required settings.)\n");
- exit(1);
+ conffail = 1;
+ strncat(conffailmsg, "Error getting 'replaydates' from configuration file.\n", sizeof conffailmsg - strlen(conffailmsg) - 1);
}
// What is the bouncer password?
if (!getconfstr("password", settings.conffile, settings.password)) {
- printf("main(): error getting 'password' from configuration file. (Recent upgrade? See blabouncer.conf.example for required settings.)\n");
- exit(1);
+ conffail = 1;
+ strncat(conffailmsg, "Error getting 'password' from configuration file.\n", sizeof conffailmsg - strlen(conffailmsg) - 1);
}
// What port should the bouncer listen on?
if (!getconfstr("clientport", settings.conffile, settings.clientport)) {
- printf("main(): error getting 'clientport' from configuration file. (Recent upgrade? See blabouncer.conf.example for required settings.)\n");
- exit(1);
+ conffail = 1;
+ strncat(conffailmsg, "Error getting 'clientport' from configuration file.\n", sizeof conffailmsg - strlen(conffailmsg) - 1);
}
// What are the configured nick(s)?
int ret = getconfarr("nicks", settings.conffile, settings.ircnicks);
if (!ret) {
- printf("main(): error getting any 'nicks' from configuration file. (Recent upgrade? See blabouncer.conf.example for required settings.)\n");
- exit(1);
+ conffail = 1;
+ strncat(conffailmsg, "Error getting any 'nicks' from configuration file.\n", sizeof conffailmsg - strlen(conffailmsg) - 1);
} else if (ret == -1) {
// Error reading an array line from the configuration file
// Remove any newlines from the middle of the string so error printing works nicely
@@ -1150,14 +1147,14 @@ int main(int argc, char *argv[]) {
// What is the configured username?
if (!getconfstr("username", settings.conffile, settings.ircusername)) {
- printf("main(): error getting 'username' from configuration file. (Recent upgrade? See blabouncer.conf.example for required settings.)\n");
- exit(1);
+ conffail = 1;
+ strncat(conffailmsg, "Error getting 'username' from configuration file.\n", sizeof conffailmsg - strlen(conffailmsg) - 1);
}
// What is the configured real name?
if (!getconfstr("realname", settings.conffile, settings.ircrealname)) {
- printf("main(): error getting 'realname' from configuration file. (Recent upgrade? See blabouncer.conf.example for required settings.)\n");
- exit(1);
+ conffail = 1;
+ strncat(conffailmsg, "Error getting 'realname' from configuration file.\n", sizeof conffailmsg - strlen(conffailmsg) - 1);
}
// What, if anything, are the configured auto channels?
@@ -1188,14 +1185,14 @@ int main(int argc, char *argv[]) {
// What is the real IRC server address?
if (!getconfstr("ircserver", settings.conffile, settings.ircserver)) {
- printf("main(): error getting 'ircserver' from configuration file. (Recent upgrade? See blabouncer.conf.example for required settings.)\n");
- exit(1);
+ conffail = 1;
+ strncat(conffailmsg, "Error getting 'ircserver' from configuration file.\n", sizeof conffailmsg - strlen(conffailmsg) - 1);
}
// What is the real IRC server port?
if (!getconfstr("ircserverport", settings.conffile, settings.ircserverport)) {
- printf("main(): error getting 'ircserverport' from configuration file. (Recent upgrade? See blabouncer.conf.example for required settings.)\n");
- exit(1);
+ conffail = 1;
+ strncat(conffailmsg, "Error getting 'ircserverport' from configuration file.\n", sizeof conffailmsg - strlen(conffailmsg) - 1);
}
// What is the real IRC server password, if any?
@@ -1228,15 +1225,15 @@ int main(int argc, char *argv[]) {
// Should the bouncer use TLS for the IRC server?
settings.servertls = getconfint("servertls", settings.conffile);
if (errno == ECONFINT) {
- printf("main(): error getting 'servertls' from configuration file. (Recent upgrade? See blabouncer.conf.example for required settings.)\n");
- exit(1);
+ conffail = 1;
+ strncat(conffailmsg, "Error getting 'servertls' from configuration file.\n", sizeof conffailmsg - strlen(conffailmsg) - 1);
}
// Should the bouncer use TLS for clients?
settings.clienttls = getconfint("clienttls", settings.conffile);
if (errno == ECONFINT) {
- printf("main(): error getting 'clienttls' from configuration file. (Recent upgrade? See blabouncer.conf.example for required settings.)\n");
- exit(1);
+ conffail = 1;
+ strncat(conffailmsg, "Error getting 'clienttls' from configuration file.\n", sizeof conffailmsg - strlen(conffailmsg) - 1);
}
// If so, load the certificates
@@ -1274,64 +1271,64 @@ int main(int argc, char *argv[]) {
// Is logging enabled?
settings.logging = getconfint("logging", settings.conffile);
if (errno == ECONFINT) {
- printf("main(): error getting 'logging' from configuration file. (Recent upgrade? See blabouncer.conf.example for required settings.)\n");
- exit(1);
+ conffail = 1;
+ strncat(conffailmsg, "Error getting 'logging' from configuration file.\n", sizeof conffailmsg - strlen(conffailmsg) - 1);
}
// Is replay logging enabled?
settings.replaylogging = getconfint("replaylogging", settings.conffile);
if (errno == ECONFINT) {
- printf("main(): error getting 'replaylogging' from configuration file. (Recent upgrade? See blabouncer.conf.example for required settings.)\n");
- exit(1);
+ conffail = 1;
+ strncat(conffailmsg, "Error getting 'replaylogging' from configuration file.\n", sizeof conffailmsg - strlen(conffailmsg) - 1);
}
// Is alerting (NOTICE) upon a new connection enabled?
settings.alertconnect = getconfint("alertconnect", settings.conffile);
if (errno == ECONFINT) {
- printf("main(): error getting 'alertconnect' from configuration file. (Recent upgrade? See blabouncer.conf.example for required settings.)\n");
- exit(1);
+ conffail = 1;
+ strncat(conffailmsg, "Error getting 'alertconnect' from configuration file.\n", sizeof conffailmsg - strlen(conffailmsg) - 1);
}
// Is alerting (NOTICE) upon a failed authentication enabled?
settings.alertauthfail = getconfint("alertauthfail", settings.conffile);
if (errno == ECONFINT) {
- printf("main(): error getting 'alertauthfail' from configuration file. (Recent upgrade? See blabouncer.conf.example for required settings.)\n");
- exit(1);
+ conffail = 1;
+ strncat(conffailmsg, "Error getting 'alertauthfail' from configuration file.\n", sizeof conffailmsg - strlen(conffailmsg) - 1);
}
// Is alerting (NOTICE) upon a successful authentication enabled?
settings.alertauthsuccess = getconfint("alertauthsuccess", settings.conffile);
if (errno == ECONFINT) {
- printf("main(): error getting 'alertauthsuccess' from configuration file. (Recent upgrade? See blabouncer.conf.example for required settings.)\n");
- exit(1);
+ conffail = 1;
+ strncat(conffailmsg, "Error getting 'alertauthsuccess' from configuration file.\n", sizeof conffailmsg - strlen(conffailmsg) - 1);
}
// Is alerting (NOTICE) upon unauthenticated client disconnections enabled?
settings.alertunautheddisconnect = getconfint("alertunautheddisconnect", settings.conffile);
if (errno == ECONFINT) {
- printf("main(): error getting 'alertunautheddisconnect' from configuration file. (Recent upgrade? See blabouncer.conf.example for required settings.)\n");
- exit(1);
+ conffail = 1;
+ strncat(conffailmsg, "Error getting 'alertunautheddisconnect' from configuration file.\n", sizeof conffailmsg - strlen(conffailmsg) - 1);
}
// Is alerting (NOTICE) upon authenticated client disconnections enabled?
settings.alertautheddisconnect = getconfint("alertautheddisconnect", settings.conffile);
if (errno == ECONFINT) {
- printf("main(): error getting 'alertautheddisconnect' from configuration file. (Recent upgrade? See blabouncer.conf.example for required settings.)\n");
- exit(1);
+ conffail = 1;
+ strncat(conffailmsg, "Error getting 'alertautheddisconnect' from configuration file.\n", sizeof conffailmsg - strlen(conffailmsg) - 1);
}
// How many debug logs should we keep?
settings.debugkeep = getconfint("debugkeep", settings.conffile);
if (errno == ECONFINT) {
- printf("main(): error getting 'debugkeep' from configuration file. (Recent upgrade? See blabouncer.conf.example for required settings.)\n");
- exit(1);
+ conffail = 1;
+ strncat(conffailmsg, "Error getting 'debugkeep' from configuration file.\n", sizeof conffailmsg - strlen(conffailmsg) - 1);
}
// Is debugging enabled?
debug = getconfint("debug", settings.conffile);
if (errno == ECONFINT) {
- printf("main(): error getting 'debug' from configuration file. (Recent upgrade? See blabouncer.conf.example for required settings.)\n");
- exit(1);
+ conffail = 1;
+ strncat(conffailmsg, "Error getting 'debug' from configuration file.\n", sizeof conffailmsg - strlen(conffailmsg) - 1);
}
if (!snprintf(debugpath, PATH_MAX, "%s/debug/debug.txt", settings.basedir)) {
fprintf(stderr, "Error while preparing debug path location!\n");
@@ -1344,6 +1341,21 @@ int main(int argc, char *argv[]) {
exit(1);
}
+ // Make sure configuration options were read OK
+ if (conffail) {
+ fprintf(stderr, "Error getting the following configuration option(s) from the configuration file.\nRecent upgrade? See blabouncer.conf.example for required options.\n\n");
+ fprintf(stderr, "%s", conffailmsg);
+ exit(1);
+ }
+
+ // Make sure replaymode was valid
+ if (strncmp(settings.replaymode, "none", sizeof(settings.replaymode)) && strncmp(settings.replaymode, "time", sizeof(settings.replaymode)) &&
+ strncmp(settings.replaymode, "lastspoke", sizeof(settings.replaymode)) && strncmp(settings.replaymode, "noclients", sizeof(settings.replaymode)) &&
+ strncmp(settings.replaymode, "lastchange", sizeof(settings.replaymode)) && strncmp(settings.replaymode, "perclient", sizeof(settings.replaymode))) {
+ printf("main(): replaymode in configuration file must be one of \"none\", \"time\", \"lastspoke\", \"noclients\", \"lastchange\" or \"perclient\".\n");
+ exit(1);
+ }
+
// Make sure the debug directory exists
if (stat(debugdir, &st) == -1) {
if (mkdir(debugdir, 0700)) {
diff --git a/structures.h b/structures.h
index 60292ed..c4d20e0 100644
--- a/structures.h
+++ b/structures.h
@@ -32,6 +32,7 @@
#define MAXCONFARR 40 // Max number of entries that a configuration array can have
#define MAXCHANNICKS 8192 // Maximum number of nicks to track per channel
#define AUTHTIMEOUT 130 // How many seconds to give clients to authenticate, checked at most every SELECTTIMEOUT seconds
+#define STDERRMAX 8192 // Maximum number of bytes we're willing to build into STDERR output
struct ircdstate {
char greeting001[MAXDATASIZE];