master xplshn/aruu / cmd / posix / logger.c
  1/* See LICENSE file for copyright and license details. */
  2
  3#include <stdio.h>
  4#include <stdlib.h>
  5#include <string.h>
  6#include <strings.h>
  7#define SYSLOG_NAMES
  8#include <syslog.h>
  9#include <unistd.h>
 10
 11#include "util.h"
 12
 13static int
 14decodetable(CODE *table, char *name)
 15{
 16  CODE *c;
 17
 18  for (c = table; c->c_name; c++)
 19    if (!strcasecmp(name, c->c_name))
 20      return c->c_val;
 21  eprintf("invalid priority name: %s\n", name);
 22
 23  return -1; /* not reached */
 24}
 25
 26static int
 27decodepri(char *pri)
 28{
 29  char *lev, *fac = pri;
 30
 31  if (!(lev = strchr(pri, '.')))
 32    eprintf("invalid priority name: %s\n", pri);
 33  *lev++ = '\0';
 34  if (!*lev)
 35    eprintf("invalid priority name: %s\n", pri);
 36
 37  return (decodetable(facilitynames, fac) & LOG_FACMASK)
 38         | (decodetable(prioritynames, lev) & LOG_PRIMASK);
 39}
 40
 41static void
 42usage(void)
 43{
 44  eprintf("usage: %s [-is] [-p priority] [-t tag] [message ...]\n", argv0);
 45}
 46
 47// ?man logger: log messages
 48// ?man arguments: message ...
 49// ?man add messages to the system log
 50int
 51main(int argc, char *argv[])
 52{
 53  size_t sz;
 54  int    logflags = 0, priority = LOG_NOTICE, i;
 55  char  *buf = NULL, *tag = NULL;
 56
 57  ARGBEGIN
 58  {
 59    // ?man -i: interactive mode or prompt for confirmation
 60    case 'i':
 61      logflags |= LOG_PID;
 62      break;
 63    // ?man -p:str: preserve file attributes
 64    case 'p':
 65      priority = decodepri(EARGF(usage()));
 66      break;
 67    // ?man -s: silent mode or print summary
 68    case 's':
 69      logflags |= LOG_PERROR;
 70      break;
 71    // ?man -t:str: sort or specify timestamp
 72    case 't':
 73      tag = EARGF(usage());
 74      break;
 75    default:
 76      usage();
 77  }
 78  ARGEND
 79
 80  openlog(tag ? tag : getlogin(), logflags, 0);
 81
 82  if (!argc) {
 83    while (getline(&buf, &sz, stdin) > 0)
 84      syslog(priority, "%s", buf);
 85  } else {
 86    for (i = 0, sz = 0; i < argc; i++)
 87      sz += strlen(argv[i]);
 88    sz += argc;
 89    buf = ecalloc(1, sz);
 90    for (i = 0; i < argc; i++) {
 91      estrlcat(buf, argv[i], sz);
 92      if (i + 1 < argc)
 93        estrlcat(buf, " ", sz);
 94    }
 95    syslog(priority, "%s", buf);
 96  }
 97
 98  closelog();
 99
100  return fshut(stdin, "<stdin>");
101}