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