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}