summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Bratch <luke@bratch.co.uk>2019-05-12 20:56:55 +0100
committerLuke Bratch <luke@bratch.co.uk>2019-05-12 20:56:55 +0100
commite18e670f43f0e7b126f209c040126aa02511fa32 (patch)
tree798e297304c0ce051847359ebf32af63503b67c8
parent34836ab2c9124e17d80bd8e8a1601398297391a8 (diff)
Completely rewrite configuration file reading to remove lots of duplicated code and to simplify things. Alter everything that called the old functions.
-rw-r--r--blabouncer.c46
-rw-r--r--config.c259
-rw-r--r--config.h17
-rw-r--r--functions.c4
4 files changed, 130 insertions, 196 deletions
diff --git a/blabouncer.c b/blabouncer.c
index d96ec09..5da18e0 100644
--- a/blabouncer.c
+++ b/blabouncer.c
@@ -70,6 +70,8 @@
#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 CONFFILE "blabouncer.conf"
+
struct channel {
char name[MAXCHANLENGTH];
char topic[MAXDATASIZE]; // TODO - Is there a particular maximum topic length?
@@ -91,7 +93,6 @@ struct ircdstrings {
char nickuserhost[MAXDATASIZE]; // TODO - Make sure this changes when nick changes, if that's meant to happen.
char ircnick[MAXNICKLENGTH]; // TODO - Make sure this changes when nick changes
char ircusername[MAXUSERNAMELEN];
- char ircrealname[MAXREALNAMELEN];
char currentmsg[MAXDATASIZE]; // Holding area for the current server-received IRC message being processed in case it needs building across multiple reads (i.e. a truncated/split message)
};
@@ -99,6 +100,9 @@ struct ircdstrings {
struct settings {
int replayseconds;
char clientport[MAXPORTLEN];
+ 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];
};
int debugmode = 0;
@@ -665,7 +669,7 @@ int processircmessage(int *serversockfd, int *clientsockfd, char *str, int sourc
case SOURCE_CLIENT: // If message(s) were from a real IRC client
// PASS received? User is trying to log in, check their password.
if (strncmp(tokens[0], "PASS", strlen(tokens[0])) == 0) {
- if (checkpassword(tokens[1])) {
+ if (checkpassword(tokens[1], CONFFILE)) {
printf("Password accepted! Setting fd %d to authenticated.\n", sourcefd);
// Find the client in the clients array and set them as authenticated
for (int i = 0; i < MAXCLIENTS; i++) {
@@ -1049,11 +1053,11 @@ void dochat(int *serversockfd, int *clientsockfd, struct settings *settings) {
ircdstrings.nickuserhost[0] = '\0';
ircdstrings.ircnick[0] = '\0';
ircdstrings.ircusername[0] = '\0';
- ircdstrings.ircrealname[0] = '\0';
ircdstrings.currentmsg[0] = '\0';
- // Read required things from configuration file
- readnames(ircdstrings.ircnick, ircdstrings.ircusername, ircdstrings.ircrealname);
+ // Populate nick and username from our configuration file for now, real IRCd may change them later (TODO - Is this true of username?)
+ strcpy(ircdstrings.ircnick, settings->ircnick);
+ strcpy(ircdstrings.ircusername, settings->ircusername);
// Send our NICK
snprintf(outgoingmsg, MAXDATASIZE, "NICK %s", ircdstrings.ircnick); // TODO - Check for success (with return code)
@@ -1061,7 +1065,7 @@ void dochat(int *serversockfd, int *clientsockfd, struct settings *settings) {
sendtoserver(serversockfd, outgoingmsg, strlen(outgoingmsg), 0, arr_clients, arr_authed);
// Send our USER
- snprintf(outgoingmsg, MAXDATASIZE, "USER %s 8 * : %s", ircdstrings.ircusername, ircdstrings.ircrealname); // TODO - Check for success (with return code)
+ snprintf(outgoingmsg, MAXDATASIZE, "USER %s 8 * : %s", ircdstrings.ircusername, settings->ircrealname); // TODO - Check for success (with return code)
// TODO - Send a more intelligent/correct USER string
// sourcefd = 0 as this is a trusted message
sendtoserver(serversockfd, outgoingmsg, strlen(outgoingmsg), 0, arr_clients, arr_authed);
@@ -1278,8 +1282,34 @@ int main(int argc, char *argv[]) {
// Structure of our various settings which are to either be read from the configuration file or set at runtime
struct settings settings;
- settings.replayseconds = confreplayseconds();
- confclientport(settings.clientport);
+
+ // Populate said settings
+
+ // How many seconds of replay log should automatically be replayed - TODO - Can we do error checking on this?
+ settings.replayseconds = getconfint("replayseconds", CONFFILE);
+ // What port should the bouncer listen on
+ if (!getconfstr("clientport", CONFFILE, settings.clientport)) {
+ printf("main(): error getting clientport from configuration file.\n");
+ exit(1);
+ }
+
+ // What is the configured nick?
+ if (!getconfstr("nick", CONFFILE, settings.ircnick)) {
+ printf("main(): error getting nick from configuration file.\n");
+ exit(1);
+ }
+
+ // What is the configured username?
+ if (!getconfstr("username", CONFFILE, settings.ircusername)) {
+ printf("main(): error getting username from configuration file.\n");
+ exit(1);
+ }
+
+ // What is the configured real name?
+ if (!getconfstr("realname", CONFFILE, settings.ircrealname)) {
+ printf("main(): error getting real name from configuration file.\n");
+ exit(1);
+ }
// TODO: see if any of this can be shared (i.e. 1. avoid code duplication, and 2. see if variables can be shared between client/server sockets)
diff --git a/config.c b/config.c
index d652147..168b780 100644
--- a/config.c
+++ b/config.c
@@ -1,227 +1,128 @@
#include "config.h"
-// TODO - Multiple functions here (at least readnames(), replayseconds() and checkpassword()) have the file opening code, rewrite.
+// Sets 'dest' to the value of the configuration option with name
+// 'confname' from configuration file 'filename'.
+// Returns 1 for success or 0 for error/failure.
+int getconfstr(char *confname, char *filename, char* dest) {
+ FILE *fp;
+ char *ret;
+ char str[MAXCHAR];
-// TODO - Can isconf() and getconf() just be merged into one function?
+ // Set strings to zero-length to begin
+ dest[0] = '\0';
-// Check to see if a line is the configuration option specified by
-// checking to see if str starts with conf followed by a space, a tab,
-// or an equals sign.
-// Returns the length of the name of the requested option if found, or
-// zero if not.
-long int isconf(char *str, char *conf) {
- char *ret;
- char substr[MAXCHAR];
- long int len = strlen(conf);
+ // Length of requested configuration option name
+ long int namelen = strlen(confname);
- // Ensure the next character is an equals sign, a space, or a tab
- if (str[len] != '=' && str[len] != ' ' && str[len] != ' ') {
- return 0;
+ fp = fopen(filename, "r");
+
+ if (fp == NULL) {
+ printf("error: could not open configuration file '%s'.\n", filename);
+ exit(1);
}
+ // Loop through the whole file, looking for the requested configuration option
+ while (fgets(str, MAXCHAR, fp) != NULL) {
+ char substr[MAXCHAR];
- strncpy(substr, str, len);
- substr[len] = '\0';
+ // Check if the next character after the length of the requested option
+ // name is an equals sign, a space, or a tab
+ if (str[namelen] != '=' && str[namelen] != ' ' && str[namelen] != ' ') {
+ // If it isn't this can't have been our option
+ continue;
+ }
+ // Copy the number of characters that the requested option name is long
+ // to a temporary string
+ strncpy(substr, str, namelen);
+ substr[namelen] = '\0';
- if (!(ret = strstr(substr, conf)) == 0) {
- return len;
+ // If the resulting temporary string contains the requested option name,
+ // we have found our configuration option and it is in the current 'str'
+ if (!(ret = strstr(substr, confname)) == 0) {
+ break;
+ }
}
- return 0;
-}
+ // If we got here, then either we found the configuration option or we ran out of file
+
+ // If str is NULL then we ran out of file
+ if (ret == NULL) {
+ printf("Error reading configuration option '%s', did not find it in configuration file '%s'.\n", confname, filename);
+ return 0;
+ }
-// Extracts the value of a configuration option from a string. Expects
-// to receive the string and the number of characters long that the
-// configuration option name is.
-void getconf(char *str, long int start) {
- long int len = strlen(str);
long int pos;
- char conf[MAXCHAR];
+ char conf[MAXCHAR]; // Temporary string to build configuration value in
- for (long int i = start; i < len; i++) {
+ // Starting from the end of the option name, find the position of the start of the configuration value
+ // (including its double quotes) by skipping over everything that isn't an equals sign, a space, or a tab
+ for (size_t i = namelen; i < strlen(str); i++) {
if (str[i] == '=' || str[i] == ' ' || str[i] == ' ') {
continue;
} else {
+ // Record current/final position in string
pos = i;
break;
}
}
- strncpy(conf, str + pos, len - pos - 1); // Copy remainder to new string and lop off the newline
- conf[len - pos - 1] = '\0'; // Null terminate
+ strncpy(conf, str + pos, strlen(str) - pos - 1); // Copy remainder to new string and lop off the newline
+ conf[strlen(str) - pos - 1] = '\0'; // Null terminate
// Check for start and end quotes
if (conf[0] != '"' || conf[strlen(conf) - 1] != '"') {
- printf("Error reading configuration option, not enclosed in double quotes!\n");
+ printf("Error reading configuration option '%s', not enclosed in double quotes in configuration file '%s'!\n", confname, filename);
exit(1);
}
- strncpy(str, conf + 1, strlen(conf) - 2); // Copy result back to original string without quotes
- str[strlen(conf) - 2] = '\0'; // Null terminate
-}
-
-int readnames(char *nick, char *username, char *realname) {
- FILE *fp;
- char str[MAXCHAR];
- char* filename = "blabouncer.conf";
+ strncpy(dest, conf + 1, strlen(conf) - 2); // Copy result to destination string without quotes
+ dest[strlen(conf) - 2] = '\0'; // Null terminate
- // Set all strings to zero-length to begin
- nick[0] = '\0';
- username[0] = '\0';
- realname[0] = '\0';
-
- fp = fopen(filename, "r");
-
- if (fp == NULL) {
- printf("error: could not open configuration file '%s'.\n", filename);
- exit(1);
- }
-
- while (fgets(str, MAXCHAR, fp) != NULL) {
- long int len;
- if ((len = isconf(str, "nick"))) {
- getconf(str, len);
- strncpy(nick, str, strlen(str));
- nick[strlen(str)] = '\0';
- printf("Nick is: '%s', length '%ld'.\n", nick, strlen(nick));
- } else if ((len = isconf(str, "username"))) {
- getconf(str, len);
- strncpy(username, str, strlen(str));
- username[strlen(str)] = '\0';
- printf("Username is: '%s', length '%ld'.\n", username, strlen(username));
- } else if ((len = isconf(str, "realname"))) {
- getconf(str, len);
- strncpy(realname, str, strlen(str));
- realname[strlen(str)] = '\0';
- printf("Real name is: '%s', length '%ld'.\n", realname, strlen(realname));
- }
- }
-
- // Ensure we have everything required
- if (!strlen(nick) || !strlen(username) || !strlen(realname)) {
- printf("Failed to read nick and/or username and/or real name from configuration file.\n");
- exit(1);
- }
+ printf("getconfstr(): returning '%s'.\n", dest);
+ // Close fine and return success
fclose(fp);
return 1;
}
-// Return the replayseconds configuration option
-// (How many seconds of replay should be sent to connecting clients)
-int confreplayseconds() {
- FILE *fp;
- char str[MAXCHAR];
- char* filename = "blabouncer.conf";
-
- char secondsstr[MAXCHAR];
- int seconds;
-
- fp = fopen(filename, "r");
-
- if (fp == NULL) {
- printf("error: could not open configuration file '%s'.\n", filename);
+// Returns the value of the configuration option with name
+// 'confname' from configuration file 'filename'.
+int getconfint(char *confname, char *filename) {
+ char result[MAXCHAR];
+ if (!getconfstr(confname, filename, result)) {
+ printf("getconfint(): error getting configuration option '%s' from configuration file '%s'.\n", confname, filename);
+ // TODO - Do something useful here instead of exiting
exit(1);
}
- while (fgets(str, MAXCHAR, fp) != NULL) {
- long int len;
- if ((len = isconf(str, "replayseconds"))) {
- getconf(str, len);
- strncpy(secondsstr, str, strlen(str));
- secondsstr[strlen(str)] = '\0';
- printf("secondsstr is: '%s', length '%ld'.\n", secondsstr, strlen(secondsstr));
- seconds = strtol(secondsstr, NULL, 10); // Convert resulting string to an integer, base 10
- printf("seconds is: '%d'.\n", seconds);
- }
- }
-
- fclose(fp);
- return seconds;
+ return strtol(result, NULL, 10); // Convert resulting string to an integer, base 10
}
// Check the password provided in the string 'str' against what is in
-// the config file.
+// the configuration file 'filename'.
// Return 0 for password mismatch, or 1 for password match.
-int checkpassword(char *password) {
- FILE *fp;
- char str[MAXCHAR];
- char* filename = "blabouncer.conf";
-
- fp = fopen(filename, "r");
-
- if (fp == NULL) {
- printf("error: could not open configuration file '%s'.\n", filename);
- exit(1);
- }
-
- while (fgets(str, MAXCHAR, fp) != NULL) {
- long int len;
- if ((len = isconf(str, "password"))) {
- getconf(str, len);
- printf("confpassword is: '%s', length '%ld'.\n", str, strlen(str));
- // Ensure password are the same length
- if (strlen(str) != strlen(password)) {
- printf("Password length mismatch!\n");
- fclose(fp);
- return 0;
- }
- // Ensure passwords match
- if (strncmp(str, password, strlen(password)) == 0) {
- printf("confpassword matches password.\n");
- fclose(fp);
- return 1;
- } else {
- printf("confpassword does NOT match password!\n");
- fclose(fp);
- return 0;
- }
- }
- }
-
- fclose(fp);
- printf("No password read from configuration file, quitting.\n");
- exit(1);
-}
+int checkpassword(char *password, char *filename) {
+ char confpassword[MAXCHAR];
-int confclientport(char *clientport) {
- FILE *fp;
- char str[MAXCHAR];
- char* filename = "blabouncer.conf";
-
- // Set all strings to zero-length to begin
- clientport[0] = '\0';
-
- fp = fopen(filename, "r");
-
- if (fp == NULL) {
- printf("error: could not open configuration file '%s'.\n", filename);
- exit(1);
- }
-
- while (fgets(str, MAXCHAR, fp) != NULL) {
- long int len;
- if ((len = isconf(str, "clientport"))) {
- getconf(str, len);
- strncpy(clientport, str, strlen(str));
- clientport[strlen(str)] = '\0';
- printf("clientport is: '%s', length '%ld'.\n", clientport, strlen(clientport));
- }
+ if (!getconfstr("password", filename, confpassword)) {
+ printf("checkpassword(): error getting configuration option 'password' from configuration file '%s'.\n", filename);
+ return 0;
}
- // Ensure we have everything required
- if (!strlen(clientport)) {
- printf("Failed to read clientport from configuration file.\n");
- exit(1);
+ // Ensure passwords are the same length
+ if (strlen(password) != strlen(confpassword)) {
+ printf("Password length mismatch!\n");
+ return 0;
}
-
- int portint = strtol(clientport, NULL, 10); // Convert resulting string to an integer, base 10
- // Ensure port is valid
- if (portint < 1 || portint > 65535) {
- printf("Invalid clientport value in configuration file.\n");
- exit(1);
+ // Ensure passwords match
+ if (strncmp(password, confpassword, strlen(password)) == 0) {
+ printf("confpassword matches password.\n");
+ return 1;
+ } else {
+ printf("confpassword does NOT match password!\n");
+ return 0;
}
- fclose(fp);
- return 1;
+ printf("checkpassword(): unexpectedly got to end of function, quitting.\n");
+ exit(1);
}
diff --git a/config.h b/config.h
index 156d8ad..3e96c19 100644
--- a/config.h
+++ b/config.h
@@ -7,12 +7,19 @@
#define MAXCHAR 1000
-int readnames(char *nick, char *username, char *realname);
+// Sets 'dest' to the value of the configuration option with name
+// 'confname' from configuration file 'filename'.
+// Returns 1 for success or 0 for error/failure as per what
+// getconfstr() returns.
+int getconfstr(char *confname, char *filename, char* dest);
-int confreplayseconds();
+// Returns the avlue of the configuration option with name
+// 'confname' from configuration file 'filename'.
+int getconfint(char *confname, char *filename);
-int checkpassword(char *password);
-
-int confclientport(char *port);
+// Check the password provided in the string 'str' against what is in
+// the configuration file 'filename'.
+// Return 0 for password mismatch, or 1 for password match.
+int checkpassword(char *password, char *filename);
#endif
diff --git a/functions.c b/functions.c
index c6bea40..1d7d7d6 100644
--- a/functions.c
+++ b/functions.c
@@ -66,7 +66,6 @@ void stripprefix(char *string) {
// Copy the old string into a new one, but...
for (size_t i = 1; i < strlen(string); i++) {
- printf("i: %zd. strlen: %zd.\n", i, strlen(string));
string2[i - 1] = string[i];
}
@@ -98,7 +97,6 @@ void extractfinalparameter(char *string) {
// Find the colon
for (size_t i = 0; i < strlen(string); i++) {
- printf("i: %zd. strlen: %zd.\n", i, strlen(string));
if (string[i] == ':') {
printf("Found colon at position %zd!\n", i);
colonpos = i;
@@ -114,7 +112,6 @@ void extractfinalparameter(char *string) {
// Build a new string starting from the next position after the colon
int counter = 0;
for (size_t i = colonpos + 1; i < strlen(string); i++) {
- printf("i: %zd. strlen: %zd.\n", i, strlen(string));
string2[counter] = string[i];
counter++;
}
@@ -144,7 +141,6 @@ void extractnickfromprefix(char *string) {
// Find the bang
for (size_t i = 0; i < strlen(string); i++) {
- printf("i: %zd. strlen: %zd.\n", i, strlen(string));
if (string[i] == '!') {
printf("Found bang at position %zd!\n", i);
bangpos = i;