1 /* logger.c - Log messages.
2 *
3 * Copyright 2013 Ilya Kuzmich <ilya.kuzmich@gmail.com>
4 *
5 * See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/logger.html
6 *
7 * Deviations from posix: specified manner and format, defined implementation.
8
9 USE_LOGGER(NEWTOY(logger, "st:p:", TOYFLAG_USR|TOYFLAG_BIN))
10
11 config LOGGER
12 bool "logger"
13 default y
14 help
15 usage: logger [-s] [-t TAG] [-p [FACILITY.]PRIORITY] [message...]
16
17 Log message (or stdin) to syslog.
18
19 -s Also write message to stderr
20 -t Use TAG instead of username to identify message source
21 -p Specify PRIORITY with optional FACILITY. Default is "user.notice"
22 */
23
24 #define FOR_logger
25 #include "toys.h"
26
GLOBALS(char * priority;char * ident;)27 GLOBALS(
28 char *priority;
29 char *ident;
30 )
31
32 // find str in names[], accepting unambiguous short matches
33 // returns offset into array of match, or -1 if no match
34 int arrayfind(char *str, char *names[], int len)
35 {
36 int try, i, matchlen = 0, found = -1, ambiguous = 1;
37
38 for (try = 0; try<len; try++) {
39 for (i=0; ; i++) {
40 if (!str[i]) {
41 if (matchlen<i) found = try, ambiguous = 0;
42 if (matchlen==i) ambiguous++;
43 if (!names[try][i]) return try;
44 break;
45 }
46 if (!names[try][i]) break;
47 if (toupper(str[i]) != toupper(names[try][i])) break;
48 }
49 }
50 return ambiguous ? -1 : found;
51 }
52
logger_main(void)53 void logger_main(void)
54 {
55 int facility = LOG_USER, priority = LOG_NOTICE, len;
56 char *s1, *s2, **arg,
57 *priorities[] = {"emerg", "alert", "crit", "error", "warning", "notice",
58 "info", "debug"},
59 *facilities[] = {"kern", "user", "mail", "daemon", "auth", "syslog",
60 "lpr", "news", "uucp", "cron", "authpriv", "ftp"};
61
62 if (!TT.ident) TT.ident = xstrdup(xgetpwuid(geteuid())->pw_name);
63 if (toys.optflags & FLAG_p) {
64 if (!(s1 = strchr(TT.priority, '.'))) s1 = TT.priority;
65 else {
66 *s1++ = len = 0;
67 facility = arrayfind(TT.priority, facilities, ARRAY_LEN(facilities));
68 if (facility == -1 && strncasecmp(TT.priority, "local", 5)) {
69 facility = s1[5]-'0';
70 if (facility>7 || s1[6]) facility = -1;
71 if (facility>=0) facility += 16;
72 }
73 if (facility<0) error_exit("bad facility: %s", TT.priority);
74 facility *= 8;
75 }
76
77 priority = arrayfind(s1, priorities, ARRAY_LEN(priorities));
78 if (priority<0) error_exit("bad priority: %s", s1);
79 }
80
81 if (toys.optc) {
82 for (len = 0, arg = toys.optargs; *arg; arg++) len += strlen(*arg)+1;
83 s1 = s2 = xmalloc(len);
84 for (arg = toys.optargs; *arg; arg++) {
85 if (arg != toys.optargs) *s2++ = ' ';
86 s2 = stpcpy(s2, *arg);
87 }
88 } else {
89 toybuf[readall(0, toybuf, sizeof(toybuf)-1)] = 0;
90 s1 = toybuf;
91 }
92
93 openlog(TT.ident, LOG_PERROR*!!(toys.optflags&FLAG_s), facility);
94 syslog(priority, "%s", s1);
95 closelog();
96 }
97