summaryrefslogtreecommitdiff
path: root/logging.c
diff options
context:
space:
mode:
authorLuke Bratch <luke@bratch.co.uk>2019-05-19 18:20:33 +0100
committerLuke Bratch <luke@bratch.co.uk>2019-05-19 18:20:33 +0100
commita5880d645c2bbf8dfae6daabb1d3c3c66e3c310b (patch)
treeb9ecd641458038dc1ae09cfbd2cbc61f7fbd9d2d /logging.c
parent1b3539a50d29a8956aa0bd2e668681e8afb968c0 (diff)
Rewrite logging function to enable logging JOINs/PARTs as well as PRIVMSGs.
Diffstat (limited to 'logging.c')
-rw-r--r--logging.c151
1 files changed, 119 insertions, 32 deletions
diff --git a/logging.c b/logging.c
index 569a243..a3fdda4 100644
--- a/logging.c
+++ b/logging.c
@@ -2,26 +2,46 @@
// 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.
+// nick and is used to determine which log file to write to
+// if the type is LOG_PRIVMSG.
// '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:
+//
+// If LOG_PRIVMSG then it expects a string in the format:
// :from!bar@baz PRIVMSG to :hello world
-// With the ":foo!bar@baz "prefix being important.
+//
+// If LOG_JOINPART then
+// Expects a string in the format:
+// :nick!bar@baz JOIN :#blabouncer
+// or
+// :nick!bar@baz PART #blabouncer
+//
+// With the ":foo!bar@baz "prefix being important for either
+// type.
+//
// Returns 1 on success or 0 on failure.
-int logprivmsg(char *str, char *ournick, char *basedir) {
- // First, extract the "from" nick and the "to" nick or channel by splitting up the string
+int logline(char *str, char *ournick, char *basedir, int type) {
+ // Filename to write to, gets built as we go
+ char filename[MAXCHAR];
+
+ // Log line to ultimately write, gets built as we go
+ char line[MAXCHAR];
- // Track which space-separated token within this response we're on
- int counter = 0;
- // Build array of each space-separated token (TODO - Use counter to stop splitting once we reach some reasonable value - i.e. once we're definitely past commands and into just free text)
+ // Variables for LOG_JOINPART (can't define directly inside switch case)
+ int pos;
+
+ // Build array of each space-separated token
char tokens[MAXTOKENS][MAXDATASIZE];
char *token;
// Split out the first three space-separated parts of the string, leaving the rest.
+ // If LOG_PRIVMSG:
// This gets us the prefix (containing the "from" nick), the PRIVMSG command (not needed),
// and the "to" nick or channel. Plus the rest of the string intact (which is the actual
// message).
+ // If LOG_JOINPART:
+ // This gets us the prefix (containing the joined/parted nick), the JOIN/PART command (not needed),
+ // and the channel name.
for (int i = 0; i < 3; i++) {
// Try to split
if ((token = strsep(&str, " ")) == NULL) {
@@ -30,27 +50,81 @@ int logprivmsg(char *str, char *ournick, char *basedir) {
}
// Copy into the token array (strlen + 1 to get the NULL terminator)
strncpy(tokens[i], token, strlen(token) + 1);
- counter++;
+ printf("logline(): extracted '%s'.\n", tokens[i]);
}
- // Extract the username from the prefix
- extractnickfromprefix(tokens[0]);
-
- // Remove the leading ":" from the real message
- stripprefix(str);
-
- // Build the log filename
- 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/logs/%s.log", basedir, tokens[0]);
- } else {
- // Otherwise log it in the "to" log file
- snprintf(filename, MAXCHAR, "%s/logs/%s.log", basedir, tokens[2]);
+ switch(type) {
+ case LOG_PRIVMSG:
+ // Extract the username from the prefix
+ extractnickfromprefix(tokens[0]);
+
+ // Remove the leading ":" from the real message
+ stripprefix(str);
+
+ // Build the log filename
+ // 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/logs/%s.log", basedir, tokens[0]);
+ } else {
+ // Otherwise log it in the "to" log file
+ snprintf(filename, MAXCHAR, "%s/logs/%s.log", basedir, tokens[2]);
+ }
+
+ printf("logline(): Logging PRIVMSG from '%s' to '%s' message '%s' in filename '%s'.\n", tokens[0], tokens[2], str, filename);
+
+ break;
+
+ case LOG_JOINPART:
+ // Find the start of the channel name
+
+ // If it's a JOIN
+ if (tokens[2][0] == ':') {
+ pos = 1;
+ } else if (tokens[2][0] == '#') {
+ // Perhaps it's a PART
+ pos = 0;
+ } else {
+ // If not found, return 0
+ return 0;
+ }
+
+ snprintf(filename, MAXCHAR, "%s/logs/%s.log", basedir, tokens[2] + pos);
+
+ printf("logline(): Logging JOIN/PART to/from '%s' in filename '%s'.\n", tokens[2] + pos, filename);
+
+ // Build a friendly message (e.g. ":nick!user@host JOIN #channel" -> "nick (user@host) has joined #channel")
+
+ // Find the bang in the prefix
+ char *ret;
+ int posbang;
+ if ((ret = strstr(tokens[0], "!")) != NULL) {
+ // Position within str of "!"
+ posbang = ret - tokens[0];
+ } else {
+ // No idea what happened, let's abandon ship
+ return 0;
+ }
+
+ // Make it a null character
+ tokens[0][posbang] = '\0';
+
+ // Swap JOINed or PARTed for a friendly word
+ if (strncmp(tokens[1], "JOIN", strlen("JOIN")) == 0) {
+ snprintf(tokens[1], strlen("joined") + 1, "joined");
+ } else if (strncmp(tokens[1], "PART", strlen("PART")) == 0) {
+ snprintf(tokens[1], strlen("left") + 1, "left");
+ }
+
+ // Copy the nick, then user@host, then whether it was a join or part, then the channel name the string to send
+ snprintf(line, MAXCHAR, "%s (%s) has %s %s", tokens[0] + 1, tokens[0] + posbang + 1, tokens[1], tokens[2] + pos);
+
+ break;
+
+ default :
+ printf("Unknown log type '%d', returning 0.\n", type);
+ return 0;
}
- 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);
@@ -60,12 +134,11 @@ int logprivmsg(char *str, char *ournick, char *basedir) {
printf("Error creating log directory '%s'.\n", logdir);
exit(1);
} else {
- printf("Created log directory '%s'.\n", logdir);
+ printf("logline(): log directory '%s'.\n", logdir);
}
}
FILE *fp;
- char line[MAXCHAR];
int bytes = 0;
@@ -86,13 +159,27 @@ int logprivmsg(char *str, char *ournick, char *basedir) {
snprintf(timestr, MAXCHAR, "%s", asctime(timeinfo));
timestr[strlen(timestr) - 1] = '\0';
- // Prepend the time string and "from" nick
- if (!snprintf(line, MAXCHAR, "%s <%s> %s", timestr, tokens[0], str)) {
- fprintf(stderr, "Error while log string to write!\n");
- exit(1);
+ if (type == LOG_PRIVMSG) {
+ // Prepend the time string and "from" nick
+ if (!snprintf(line, MAXCHAR, "%s <%s> %s", timestr, tokens[0], str)) {
+ fprintf(stderr, "Error while preparing log string to write!\n");
+ exit(1);
+ }
+ } else if (type == LOG_JOINPART) {
+ // Prepend the time string
+ char line2[MAXCHAR];
+ if (!snprintf(line2, MAXCHAR, "%s %s", timestr, line)) {
+ fprintf(stderr, "Error while preparing log string to write!\n");
+ exit(1);
+ }
+ // Copy back to line to write
+ snprintf(line, MAXCHAR, "%s", line2);
}
- printf("Complete log string to write: '%s', length '%ld'.\n", line, strlen(line));
+ // Ensure the line finishes with CRLF
+ appendcrlf(line);
+
+ printf("logline(): Complete log string to write: '%s', length '%ld'.\n", line, strlen(line));
// Write complete line to file
if ((bytes = fprintf(fp, line)) < 0) {