summaryrefslogtreecommitdiff
path: root/logging.c
blob: 569a2430107d88ff003ebc8f0efc18748c9b8f1b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#include "logging.h"

// 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, 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
  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)
  char tokens[MAXTOKENS][MAXDATASIZE];
  char *token;

  // Split out the first three space-separated parts of the string, leaving the rest.
  // 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).
  for (int i = 0; i < 3; i++) {
    // Try to split
    if ((token = strsep(&str, " ")) == NULL) {
      printf("Error splitting string for logging, exiting!\n");
      exit(1);
    }
    // Copy into the token array (strlen + 1 to get the NULL terminator)
    strncpy(tokens[i], token, strlen(token) + 1);
    counter++;
  }

  // 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]);
  }

  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];

  int bytes = 0;

  fp = fopen(filename, "a");

  if (fp == NULL) {
    printf("error: could not open log file '%s' for writing.\n", filename);
    exit(1);
  }

  // Get a current time string to prepend - TODO - Make this customisable.
  time_t rawtime;
  struct tm * timeinfo;
  time(&rawtime);
  timeinfo = localtime(&rawtime);
  // Strip the trailing newline
  char timestr[MAXCHAR];
  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);
  }

  printf("Complete log string to write: '%s', length '%ld'.\n", line, strlen(line));

  // Write complete line to file
  if ((bytes = fprintf(fp, line)) < 0) {
    printf("error: could not write to log file.\n");
    exit(1);
  }

  fclose(fp);
  return bytes;
}