summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Bratch <luke@bratch.co.uk>2019-05-16 20:59:51 +0100
committerLuke Bratch <luke@bratch.co.uk>2019-05-16 20:59:51 +0100
commit968cee422ab1d61b4234127892d75f0497d8d8c2 (patch)
tree16b65ca2c52ec553cb7584d2259f5d3c11ec5902
parenta299b62e913df71bdd1c4b41d61d3fb098f12be7 (diff)
Add a configurable base directory for things like logs, defaulting to $HOME/.blabouncer/.
-rw-r--r--blabouncer.c31
-rw-r--r--blabouncer.conf4
-rw-r--r--logging.c21
-rw-r--r--logging.h6
-rw-r--r--replay.c28
-rw-r--r--replay.h7
6 files changed, 76 insertions, 21 deletions
diff --git a/blabouncer.c b/blabouncer.c
index 3f9004d..59cf8c1 100644
--- a/blabouncer.c
+++ b/blabouncer.c
@@ -16,6 +16,7 @@
// - Customise logging (disabling it, log file location)
// - Alert when clients connect/authenticate/disconnect
// - Perhaps rename arr_ssl and server_ssl since they may not even be OpenSSL sockets
+// - Is it possible to replay JOINs/PARTs accurately?
//
// Example WHOIS reply:
// BOUNCER-SERVER RECEIVED: :irc.tghost.co.uk 307 blabounce l_bratch :is identified for this nick
@@ -35,6 +36,7 @@
#include <arpa/inet.h>
#include <sys/select.h>
#include <time.h>
+#include <sys/stat.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/bio.h>
@@ -103,6 +105,7 @@ struct settings {
char keyfile[PATH_MAX];
int clienttls;
int servertls;
+ char basedir[PATH_MAX];
};
// Return index of requested client FD within arr_clients
@@ -439,7 +442,7 @@ int doreplay(int sourcefd, int replayseconds, int arr_clients[], int arr_authed[
char outgoingmsg[MAXDATASIZE];
// Figure out how many lines to replay
- int numlines = replaylines(replayseconds);
+ int numlines = replaylines(replayseconds, settings->basedir);
printf("Replay log lines: '%d'.\n", numlines);
if (numlines < 0) {
@@ -453,7 +456,7 @@ int doreplay(int sourcefd, int replayseconds, int arr_clients[], int arr_authed[
// Replay those lines!
for (int i = 0; i < numlines; i++) {
- if (!readreplayline(replayseconds, i, outgoingmsg)) {
+ if (!readreplayline(replayseconds, i, outgoingmsg, settings->basedir)) {
printf("Error requesting replay line.\n");
exit(1);
}
@@ -686,10 +689,10 @@ int processircmessage(SSL *server_ssl, int *clientsockfd, char *str, int source,
sendtoallclients(clientsockfd, fdmax, arr_clients, str, sourcefd, arr_authed, arr_ssl, settings);
// Write to replay log
- writereplayline(str);
+ writereplayline(str, settings->basedir);
// Write to normal log
- logprivmsg(str, settings->ircnick);
+ logprivmsg(str, settings->ircnick, settings->basedir);
return 1;
}
@@ -873,10 +876,10 @@ int processircmessage(SSL *server_ssl, int *clientsockfd, char *str, int source,
sendtoallclients(clientsockfd, fdmax, arr_clients, outgoingmsg, sourcefd, arr_authed, arr_ssl, settings);
// Write to replay log
- writereplayline(outgoingmsg);
+ writereplayline(outgoingmsg, settings->basedir);
// Write to normal log
- logprivmsg(outgoingmsg, settings->ircnick);
+ logprivmsg(outgoingmsg, settings->ircnick, settings->basedir);
return 1;
}
@@ -1438,6 +1441,22 @@ int main(int argc, char *argv[]) {
}
}
+ // Is the base directory set? If not, use the default.
+ if (!getconfstr("basedir", settings.conffile, settings.basedir)) {
+ snprintf(settings.basedir, PATH_MAX, "%s/.blabouncer/", getenv("HOME"));
+ }
+
+ // Make sure the base directory exists
+ struct stat st = {0};
+ if (stat(settings.basedir, &st) == -1) {
+ if (mkdir(settings.basedir, 0700)) {
+ printf("Error creating base directory '%s'.\n", settings.basedir);
+ exit(1);
+ } else {
+ printf("Created base directory '%s'.\n", settings.basedir);
+ }
+ }
+
// 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)
// TODO: track fdmax - kind of doing this now with arr_clients and num_clients but might be pointlessly tracking both in some places (?)
diff --git a/blabouncer.conf b/blabouncer.conf
index d90d35b..cf9591b 100644
--- a/blabouncer.conf
+++ b/blabouncer.conf
@@ -37,3 +37,7 @@ certfile = "cert.pem"
# Certificate key file
# If clienttls = "0" then this need not be set
keyfile = "key.pem"
+
+# Base directory (defaults to $HOME/.blabouncer/)
+# Things such as the logs directory will be placed below this
+#basedir = "/home/foo/.blabouncer/"
diff --git a/logging.c b/logging.c
index e0f5f1f..569a243 100644
--- a/logging.c
+++ b/logging.c
@@ -3,11 +3,13 @@
// Write the line 'str' to the relevant log file such as
// '#channel.log' or 'nickname.log'. 'ournick' is our own
// nick and is used to determine which log file to write to.
+// 'basedir' is the directory in which the 'logs' directory
+// will be created in which logs are to be written.
// Expects a string in the format:
// :from!bar@baz PRIVMSG to :hello world
// With the ":foo!bar@baz "prefix being important.
// Returns 1 on success or 0 on failure.
-int logprivmsg(char *str, char *ournick) {
+int logprivmsg(char *str, char *ournick, char *basedir) {
// First, extract the "from" nick and the "to" nick or channel by splitting up the string
// Track which space-separated token within this response we're on
@@ -41,14 +43,27 @@ int logprivmsg(char *str, char *ournick) {
char filename[MAXCHAR];
// If the message was sent to us, then log it in the sender's log file
if (strncmp(tokens[2], ournick, strlen(tokens[0])) == 0) {
- snprintf(filename, MAXCHAR, "%s.log", tokens[0]);
+ snprintf(filename, MAXCHAR, "%s/logs/%s.log", basedir, tokens[0]);
} else {
// Otherwise log it in the "to" log file
- snprintf(filename, MAXCHAR, "%s.log", tokens[2]);
+ snprintf(filename, MAXCHAR, "%s/logs/%s.log", basedir, tokens[2]);
}
printf("logprivmsg(): Logging from '%s' to '%s' message '%s' in filename '%s'.\n", tokens[0], tokens[2], str, filename);
+ // Make sure the log directory exists
+ char logdir[PATH_MAX];
+ snprintf(logdir, PATH_MAX, "%s/logs/", basedir);
+ struct stat st = {0};
+ if (stat(logdir, &st) == -1) {
+ if (mkdir(logdir, 0700)) {
+ printf("Error creating log directory '%s'.\n", logdir);
+ exit(1);
+ } else {
+ printf("Created log directory '%s'.\n", logdir);
+ }
+ }
+
FILE *fp;
char line[MAXCHAR];
diff --git a/logging.h b/logging.h
index 289f348..726bb4d 100644
--- a/logging.h
+++ b/logging.h
@@ -4,6 +4,8 @@
#include <stdio.h>
#include <string.h>
#include <time.h>
+#include <limits.h>
+#include <sys/stat.h>
#include "functions.h"
@@ -17,10 +19,12 @@
// Write the line 'str' to the relevant log file such as
// '#channel.log' or 'nickname.log'. 'ournick' is our own
// nick and is used to determine which log file to write to.
+// 'basedir' is the directory in which the 'logs' directory
+// will be created in which logs are to be written.
// Expects a string in the format:
// :from!bar@baz PRIVMSG to :hello world
// With the ":foo!bar@baz "prefix being important.
// Returns 1 on success or 0 on failure.
-int logprivmsg(char *str, char *ournick);
+int logprivmsg(char *str, char *ournick, char *basedir);
#endif
diff --git a/replay.c b/replay.c
index 3c2c920..a898a7b 100644
--- a/replay.c
+++ b/replay.c
@@ -137,10 +137,14 @@ void formattime(char *str) {
}
// Return the number of lines in the replay log since 'seconds' seconds ago, or -1 if there a problem.
-int replaylines(int seconds) {
+// 'basedir' is the directory in which to find 'replay.log'.
+int replaylines(int seconds, char *basedir) {
FILE *fp;
char str[MAXCHAR];
- char* filename = "replay.log";
+ char filename[PATH_MAX];
+
+ // Build path
+ snprintf(filename, PATH_MAX, "%s/replay.log", basedir);
int numlines = 0;
@@ -175,14 +179,18 @@ int replaylines(int seconds) {
}
// Set 'str' to the line in the log with a timestamp of greater than 'seconds'
-// seconds ago, plus however many lines 'linenum' is set to.
+// seconds ago, plus however many lines 'linenum' is set to. 'basedir' is the
+// directory in which to find 'replay.log'.
// Also modify the line to include a timestamp in the form "[HH:MM:SS]".
// Returns 1 on success, or 0 on failure.
// TODO - This is horribly inefficient since it re-reads the entire file each call, rewrite this!
-int readreplayline(int seconds, int linenum, char *str) {
+int readreplayline(int seconds, int linenum, char *str, char *basedir) {
FILE *fp;
char line[MAXCHAR];
- char* filename = "replay.log";
+ char filename[PATH_MAX];
+
+ // Build path
+ snprintf(filename, PATH_MAX, "%s/replay.log", basedir);
int count = 0;
@@ -226,15 +234,19 @@ int readreplayline(int seconds, int linenum, char *str) {
}
// Write the line 'str' to the replay log file after prepending it with
-// the current unixtime timestamp.
+// the current unixtime timestamp. 'basedir' is the directory in which
+// to write to 'replay.log'.
// Expects a string in the format:
// :from!bar@baz PRIVMSG to :hello world
// With the ":foo!bar@baz "prefix being important.
// Returns 1 on success or 0 on failure.
-int writereplayline(char *str) {
+int writereplayline(char *str, char *basedir) {
FILE *fp;
char line[MAXCHAR];
- char* filename = "replay.log";
+ char filename[PATH_MAX];
+
+ // Build path
+ snprintf(filename, PATH_MAX, "%s/replay.log", basedir);
int bytes = 0;
diff --git a/replay.h b/replay.h
index 7f1e331..983e05b 100644
--- a/replay.h
+++ b/replay.h
@@ -7,15 +7,16 @@
#include <stdlib.h>
#include <time.h>
#include <ctype.h>
+#include <limits.h>
#define MAXCHAR 1000
#define TIMELEN 11 // 32-bit unixtime is up to 10 characters (+1 for null char) // TODO - Make this Year 2038 proof
#define TIMELENF 11 // [HH:MM:SS] = 10 characters + 1 for null char
-int replaylines(int seconds);
+int replaylines(int seconds, char *basedir);
-int readreplayline(int seconds, int linenum, char *str);
+int readreplayline(int seconds, int linenum, char *str, char *basedir);
-int writereplayline(char *str);
+int writereplayline(char *str, char *basedir);
#endif