/* syslogd.c - a system logging utility.
 *
 * Copyright 2013 Madhur Verma <mad.flexi@gmail.com>
 * Copyright 2013 Kyungwan Han <asura321@gmail.com>
 *
 * No Standard

USE_SYSLOGD(NEWTOY(syslogd,">0l#<1>8=8R:b#<0>99=1s#<0=200m#<0>71582787=20O:p:f:a:nSKLD", TOYFLAG_SBIN|TOYFLAG_STAYROOT))

config SYSLOGD
  bool "syslogd"
  default n
  help
  usage: syslogd  [-a socket] [-O logfile] [-f config file] [-m interval]
                  [-p socket] [-s SIZE] [-b N] [-R HOST] [-l N] [-nSLKD]

  System logging utility

  -a      Extra unix socket for listen
  -O FILE Default log file <DEFAULT: /var/log/messages>
  -f FILE Config file <DEFAULT: /etc/syslog.conf>
  -p      Alternative unix domain socket <DEFAULT : /dev/log>
  -n      Avoid auto-backgrounding.
  -S      Smaller output
  -m MARK interval <DEFAULT: 20 minutes> (RANGE: 0 to 71582787)
  -R HOST Log to IP or hostname on PORT (default PORT=514/UDP)"
  -L      Log locally and via network (default is network only if -R)"
  -s SIZE Max size (KB) before rotation (default:200KB, 0=off)
  -b N    rotated logs to keep (default:1, max=99, 0=purge)
  -K      Log to kernel printk buffer (use dmesg to read it)
  -l N    Log only messages more urgent than prio(default:8 max:8 min:1)
  -D      Drop duplicates
*/

#define FOR_syslogd
#define SYSLOG_NAMES
#include "toys.h"

// UNIX Sockets for listening
struct unsocks {
  struct unsocks *next;
  char *path;
  struct sockaddr_un sdu;
  int sd;
};

// Log file entry to log into.
struct logfile {
  struct logfile *next;
  char *filename;
  uint32_t facility[8];
  uint8_t level[LOG_NFACILITIES];
  int logfd;
  struct sockaddr_in saddr;
};

GLOBALS(
  char *socket;
  char *config_file;
  char *unix_socket;
  char *logfile;
  long interval;
  long rot_size;
  long rot_count;
  char *remote_log;
  long log_prio;

  struct unsocks *lsocks;  // list of listen sockets
  struct logfile *lfiles;  // list of write logfiles
  int sigfd[2];
)

// Lookup numerical code from name
// Also used in logger
int logger_lookup(int where, char *key)
{
  CODE *w = ((CODE *[]){facilitynames, prioritynames})[where];

  for (; w->c_name; w++)
    if (!strcasecmp(key, w->c_name)) return w->c_val;

  return -1;
}

//search the given name and return its value
static char *dec(int val, CODE *clist, char *buf)
{
  for (; clist->c_name; clist++) 
    if (val == clist->c_val) return clist->c_name;
  sprintf(buf, "%u", val);

  return buf;
}

/*
 * recurses the logfile list and resolves config
 * for evry file and updates facilty and log level bits.
 */
static int resolve_config(struct logfile *file, char *config)
{
  char *tk;

  for (tk = strtok(config, "; \0"); tk; tk = strtok(NULL, "; \0")) {
    char *fac = tk, *lvl;
    int i = 0;
    unsigned facval = 0;
    uint8_t set, levval, bits = 0;

    tk = strchr(fac, '.');
    if (!tk) return -1;
    *tk = '\0';
    lvl = tk + 1;

    for (;;) {
      char *nfac = strchr(fac, ',');

      if (nfac) *nfac = '\0';
      if (*fac == '*') {
        facval = 0xFFFFFFFF;
        if (fac[1]) return -1;
      } else {
        if ((i = logger_lookup(0, fac)) == -1) return -1;
        facval |= (1 << LOG_FAC(i));
      }
      if (nfac) fac = nfac + 1;
      else break;
    }

    levval = 0;
    for (tk = "!=*"; *tk; tk++, bits <<= 1) {
      if (*lvl == *tk) {
        bits++;
        lvl++;
      }
    }
    if (bits & 2) levval = 0xff;
    if (*lvl) {
      if ((i = logger_lookup(1, lvl)) == -1) return -1;
      levval |= (bits & 4) ? LOG_MASK(i) : LOG_UPTO(i);
      if (bits & 8) levval = ~levval;
    }

    for (i = 0, set = levval; set; set >>= 1, i++)
      if (set & 0x1) file->facility[i] |= ~facval;
    for (i = 0; i < LOG_NFACILITIES; facval >>= 1, i++)
      if (facval & 0x1) file->level[i] |= ~levval;
  }

  return 0;
}

// Parse config file and update the log file list.
static int parse_config_file(void)
{
  struct logfile *file;
  FILE *fp;
  char *confline, *tk[2];
  int len, lineno = 0;
  size_t linelen;
  /*
   * if -K then open only /dev/kmsg
   * all other log files are neglected
   * thus no need to open config either.
   */
  if (toys.optflags & FLAG_K) {
    file = xzalloc(sizeof(struct logfile));
    file->filename = xstrdup("/dev/kmsg");
    TT.lfiles = file;
    return 0;
  }
  /*
   * if -R then add remote host to log list
   * if -L is not provided all other log
   * files are neglected thus no need to
   * open config either so just return.
   */
  if (toys.optflags & FLAG_R) {
    file = xzalloc(sizeof(struct logfile));
    file->filename = xmprintf("@%s",TT.remote_log);
    TT.lfiles = file;
    if (!(toys.optflags & FLAG_L)) return 0;
  }
  /*
   * Read config file and add logfiles to the list
   * with their configuration.
   */
  if (!(fp = fopen(TT.config_file, "r")) && (toys.optflags & FLAG_f))
    perror_exit("can't open '%s'", TT.config_file);

  for (linelen = 0; fp;) {
    confline = NULL;
    len = getline(&confline, &linelen, fp);
    if (len <= 0) break;
    lineno++;
    for (; *confline == ' '; confline++, len--) ;
    if ((confline[0] == '#') || (confline[0] == '\n')) continue;
    tk[0] = confline;
    for (; len && !(*tk[0]==' ' || *tk[0]=='\t'); tk[0]++, len--);
    for (tk[1] = tk[0]; len && (*tk[1]==' ' || *tk[1]=='\t'); tk[1]++, len--);
    if (!len || (len == 1 && *tk[1] == '\n')) {
      error_msg("error in '%s' at line %d", TT.config_file, lineno);
      return -1;
    }
    else if (*(tk[1] + len - 1) == '\n') *(tk[1] + len - 1) = '\0';
    *tk[0] = '\0';
    if (*tk[1] != '*') {
      file = TT.lfiles;
      while (file && strcmp(file->filename, tk[1])) file = file->next;
      if (!file) {
        file = xzalloc(sizeof(struct logfile));
        file->filename = xstrdup(tk[1]);
        file->next = TT.lfiles;
        TT.lfiles = file;
      }
      if (resolve_config(file, confline) == -1) {
        error_msg("error in '%s' at line %d", TT.config_file, lineno);
        return -1;
      }
    }
    free(confline);
  }
  /*
   * Can't open config file or support is not enabled
   * adding default logfile to the head of list.
   */
  if (!fp){
    file = xzalloc(sizeof(struct logfile));
    file->filename = xstrdup((toys.optflags & FLAG_O) ?
                     TT.logfile : "/var/log/messages"); //DEFLOGFILE
    file->next = TT.lfiles;
    TT.lfiles = file;
  } else fclose(fp);
  return 0;
}

// open every log file in list.
static void open_logfiles(void)
{
  struct logfile *tfd;

  for (tfd = TT.lfiles; tfd; tfd = tfd->next) {
    char *p, *tmpfile;
    long port = 514;

    if (*tfd->filename == '@') { // network
      struct addrinfo *info, rp;

      tmpfile = xstrdup(tfd->filename + 1);
      if ((p = strchr(tmpfile, ':'))) {
        char *endptr;

        *p = '\0';
        port = strtol(++p, &endptr, 10);
        if (*endptr || endptr == p || port < 0 || port > 65535)
          error_exit("bad port in %s", tfd->filename);
      }
      memset(&rp, 0, sizeof(rp));
      rp.ai_family = AF_INET;
      rp.ai_socktype = SOCK_DGRAM;
      rp.ai_protocol = IPPROTO_UDP;

      if (getaddrinfo(tmpfile, NULL, &rp, &info) || !info) 
        perror_exit("BAD ADDRESS: can't find : %s ", tmpfile);
      ((struct sockaddr_in*)info->ai_addr)->sin_port = htons(port);
      memcpy(&tfd->saddr, info->ai_addr, info->ai_addrlen);
      freeaddrinfo(info);

      tfd->logfd = xsocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
      free(tmpfile);
    } else tfd->logfd = open(tfd->filename, O_CREAT | O_WRONLY | O_APPEND, 0666);
    if (tfd->logfd < 0) {
      tfd->filename = "/dev/console";
      tfd->logfd = open(tfd->filename, O_APPEND);
    }
  }
}

//write to file with rotation
static int write_rotate(struct logfile *tf, int len)
{
  int size, isreg;
  struct stat statf;
  isreg = (!fstat(tf->logfd, &statf) && S_ISREG(statf.st_mode));
  size = statf.st_size;

  if ((toys.optflags & FLAG_s) || (toys.optflags & FLAG_b)) {
    if (TT.rot_size && isreg && (size + len) > (TT.rot_size*1024)) {
      if (TT.rot_count) { /* always 0..99 */
        int i = strlen(tf->filename) + 3 + 1;
        char old_file[i];
        char new_file[i];
        i = TT.rot_count - 1;
        while (1) {
          sprintf(new_file, "%s.%d", tf->filename, i);
          if (!i) break;
          sprintf(old_file, "%s.%d", tf->filename, --i);
          rename(old_file, new_file);
        }
        rename(tf->filename, new_file);
        unlink(tf->filename);
        close(tf->logfd);
        tf->logfd = open(tf->filename, O_CREAT | O_WRONLY | O_APPEND, 0666);
        if (tf->logfd < 0) {
          perror_msg("can't open %s", tf->filename);
          return -1;
        }
      }
      ftruncate(tf->logfd, 0);
    }
  }
  return write(tf->logfd, toybuf, len);
}

//Parse messege and write to file.
static void logmsg(char *msg, int len)
{
  time_t now;
  char *p, *ts, *lvlstr, *facstr;
  struct utsname uts;
  int pri = 0;
  struct logfile *tf = TT.lfiles;

  char *omsg = msg;
  int olen = len, fac, lvl;
  
  if (*msg == '<') { // Extract the priority no.
    pri = (int) strtoul(msg + 1, &p, 10);
    if (*p == '>') msg = p + 1;
  }
  /* Jan 18 00:11:22 msg...
   * 01234567890123456
   */
  if (len < 16 || msg[3] != ' ' || msg[6] != ' ' || msg[9] != ':'
      || msg[12] != ':' || msg[15] != ' ') {
    time(&now);
    ts = ctime(&now) + 4; /* skip day of week */
  } else {
    now = 0;
    ts = msg;
    msg += 16;
  }
  ts[15] = '\0';
  fac = LOG_FAC(pri);
  lvl = LOG_PRI(pri);

  if (toys.optflags & FLAG_K) len = sprintf(toybuf, "<%d> %s\n", pri, msg);
  else {
    char facbuf[12], pribuf[12];

    facstr = dec(pri & LOG_FACMASK, facilitynames, facbuf);
    lvlstr = dec(LOG_PRI(pri), prioritynames, pribuf);

    p = "local";
    if (!uname(&uts)) p = uts.nodename;
    if (toys.optflags & FLAG_S) len = sprintf(toybuf, "%s %s\n", ts, msg);
    else len = sprintf(toybuf, "%s %s %s.%s %s\n", ts, p, facstr, lvlstr, msg);
  }
  if (lvl >= TT.log_prio) return;

  for (; tf; tf = tf->next) {
    if (tf->logfd > 0) {
      if (!((tf->facility[lvl] & (1 << fac)) || (tf->level[fac] & (1<<lvl)))) {
        int wlen, isNetwork = *tf->filename == '@';
        if (isNetwork)
          wlen = sendto(tf->logfd, omsg, olen, 0, (struct sockaddr*)&tf->saddr, sizeof(tf->saddr));
        else wlen = write_rotate(tf, len);
        if (wlen < 0) perror_msg("write failed file : %s ", tf->filename + isNetwork);
      }
    }
  }
}

/*
 * closes all read and write fds
 * and frees all nodes and lists
 */
static void cleanup(void)
{
  while (TT.lsocks) {
    struct unsocks *fnode = TT.lsocks;

    if (fnode->sd >= 0) {
      close(fnode->sd);
      unlink(fnode->path);
    }
    TT.lsocks = fnode->next;
    free(fnode);
  }

  while (TT.lfiles) {
    struct logfile *fnode = TT.lfiles;

    free(fnode->filename);
    if (fnode->logfd >= 0) close(fnode->logfd);
    TT.lfiles = fnode->next;
    free(fnode);
  }
}

static void signal_handler(int sig)
{
  unsigned char ch = sig;
  if (write(TT.sigfd[1], &ch, 1) != 1) error_msg("can't send signal");
}

void syslogd_main(void)
{
  struct unsocks *tsd;
  int nfds, retval, last_len=0;
  struct timeval tv;
  fd_set rfds;        // fds for reading
  char *temp, *buffer = (toybuf +2048), *last_buf = (toybuf + 3072); //these two buffs are of 1K each

  if ((toys.optflags & FLAG_p) && (strlen(TT.unix_socket) > 108))
    error_exit("Socket path should not be more than 108");

  TT.config_file = (toys.optflags & FLAG_f) ?
                   TT.config_file : "/etc/syslog.conf"; //DEFCONFFILE
init_jumpin:
  tsd = xzalloc(sizeof(struct unsocks));

  tsd->path = (toys.optflags & FLAG_p) ? TT.unix_socket : "/dev/log"; // DEFLOGSOCK
  TT.lsocks = tsd;

  if (toys.optflags & FLAG_a) {
    for (temp = strtok(TT.socket, ":"); temp; temp = strtok(NULL, ":")) {
      if (strlen(temp) > 107) temp[108] = '\0';
      tsd = xzalloc(sizeof(struct unsocks));
      tsd->path = temp;
      tsd->next = TT.lsocks;
      TT.lsocks = tsd;
    }
  }
  /*
   * initializes unsock_t structure
   * and opens socket for reading
   * and adds to global lsock list.
  */
  nfds = 0;
  for (tsd = TT.lsocks; tsd; tsd = tsd->next) {
    tsd->sdu.sun_family = AF_UNIX;
    strcpy(tsd->sdu.sun_path, tsd->path);
    tsd->sd = socket(AF_UNIX, SOCK_DGRAM, 0);
    if (tsd->sd < 0) {
      perror_msg("OPEN SOCKS : failed");
      continue;
    }
    unlink(tsd->sdu.sun_path);
    if (bind(tsd->sd, (struct sockaddr *) &tsd->sdu, sizeof(tsd->sdu))) {
      perror_msg("BIND SOCKS : failed sock : %s", tsd->sdu.sun_path);
      close(tsd->sd);
      continue;
    }
    chmod(tsd->path, 0777);
    nfds++;
  }
  if (!nfds) {
    error_msg("Can't open single socket for listenning.");
    goto clean_and_exit;
  }

  // Setup signals
  xpipe(TT.sigfd);

  fcntl(TT.sigfd[1] , F_SETFD, FD_CLOEXEC);
  fcntl(TT.sigfd[0] , F_SETFD, FD_CLOEXEC);
  int flags = fcntl(TT.sigfd[1], F_GETFL);
  fcntl(TT.sigfd[1], F_SETFL, flags | O_NONBLOCK);
  signal(SIGHUP, signal_handler);
  signal(SIGTERM, signal_handler);
  signal(SIGINT, signal_handler);
  signal(SIGQUIT, signal_handler);

  if (parse_config_file() == -1) goto clean_and_exit;
  open_logfiles();
  if (!(toys.optflags & FLAG_n)) {
    daemon(0, 0);
    //don't daemonize again if SIGHUP received.
    toys.optflags |= FLAG_n;
  }
  xpidfile("syslogd");

  logmsg("<46>Toybox: syslogd started", 27); //27 : the length of message
  for (;;) {
    // Add opened socks to rfds for select()
    FD_ZERO(&rfds);
    for (tsd = TT.lsocks; tsd; tsd = tsd->next) FD_SET(tsd->sd, &rfds);
    FD_SET(TT.sigfd[0], &rfds);
    tv.tv_usec = 0;
    tv.tv_sec = TT.interval*60;

    retval = select(TT.sigfd[0] + 1, &rfds, NULL, NULL, (TT.interval)?&tv:NULL);
    if (retval < 0) {
      if (errno != EINTR) perror_msg("Error in select ");
    }
    else if (!retval) logmsg("<46>-- MARK --", 14);
    else if (FD_ISSET(TT.sigfd[0], &rfds)) { /* May be a signal */
      unsigned char sig;

      if (read(TT.sigfd[0], &sig, 1) != 1) {
        error_msg("signal read failed.\n");
        continue;
      }
      switch(sig) {
        case SIGTERM:    /* FALLTHROUGH */
        case SIGINT:     /* FALLTHROUGH */
        case SIGQUIT:
          logmsg("<46>syslogd exiting", 19);
          if (CFG_TOYBOX_FREE ) cleanup();
          signal(sig, SIG_DFL);
          sigset_t ss;
          sigemptyset(&ss);
          sigaddset(&ss, sig);
          sigprocmask(SIG_UNBLOCK, &ss, NULL);
          raise(sig);
          _exit(1);  /* Should not reach it */
          break;
        case SIGHUP:
          logmsg("<46>syslogd exiting", 19);
          cleanup(); //cleanup is done, as we restart syslog.
          goto init_jumpin;
        default: break;
      }
    } else { /* Some activity on listen sockets. */
      for (tsd = TT.lsocks; tsd; tsd = tsd->next) {
        int sd = tsd->sd;
        if (FD_ISSET(sd, &rfds)) {
          int len = read(sd, buffer, 1023); //buffer is of 1K, hence readingonly 1023 bytes, 1 for NUL
          if (len > 0) {
            buffer[len] = '\0';
            if((toys.optflags & FLAG_D) && (len == last_len))
              if (!memcmp(last_buf, buffer, len)) break;

            memcpy(last_buf, buffer, len);
            last_len = len;
            logmsg(buffer, len);
          }
          break;
        }
      }
    }
  }
clean_and_exit:
  logmsg("<46>syslogd exiting", 19);
  if (CFG_TOYBOX_FREE ) cleanup();
}
