diff options
author | Luke Bratch <luke@bratch.co.uk> | 2019-05-19 18:20:33 +0100 |
---|---|---|
committer | Luke Bratch <luke@bratch.co.uk> | 2019-05-19 18:20:33 +0100 |
commit | a5880d645c2bbf8dfae6daabb1d3c3c66e3c310b (patch) | |
tree | b9ecd641458038dc1ae09cfbd2cbc61f7fbd9d2d /logging.c | |
parent | 1b3539a50d29a8956aa0bd2e668681e8afb968c0 (diff) |
Rewrite logging function to enable logging JOINs/PARTs as well as PRIVMSGs.
Diffstat (limited to 'logging.c')
-rw-r--r-- | logging.c | 151 |
1 files changed, 119 insertions, 32 deletions
@@ -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) { |