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 
27 GLOBALS(
28   char *p, *t;
29 )
30 
31 // find str in names[], accepting unambiguous short matches
32 // returns offset into array of match, or -1 if no match
arrayfind(char * str,char * names[],int len)33 int arrayfind(char *str, char *names[], int len)
34 {
35   int try, i, matchlen = 0, found = -1, ambiguous = 1;
36 
37   for (try = 0; try<len; try++) {
38     for (i=0; ; i++) {
39       if (!str[i]) {
40         if (matchlen<i) found = try, ambiguous = 0;
41         if (matchlen==i) ambiguous++;
42         if (!names[try][i]) return try;
43         break;
44       }
45       if (!names[try][i]) break;
46       if (toupper(str[i]) != toupper(names[try][i])) break;
47     }
48   }
49   return ambiguous ? -1 : found;
50 }
51 
logger_main(void)52 void logger_main(void)
53 {
54   int facility = LOG_USER, priority = LOG_NOTICE, len;
55   char *s1, *s2, **arg,
56     *priorities[] = {"emerg", "alert", "crit", "error", "warning", "notice",
57                      "info", "debug"},
58     *facilities[] = {"kern", "user", "mail", "daemon", "auth", "syslog",
59                      "lpr", "news", "uucp", "cron", "authpriv", "ftp"};
60 
61   if (!TT.t) TT.t = xstrdup(xgetpwuid(geteuid())->pw_name);
62   if (toys.optflags & FLAG_p) {
63     if (!(s1 = strchr(TT.p, '.'))) s1 = TT.p;
64     else {
65       *s1++ = len = 0;
66       facility = arrayfind(TT.p, facilities, ARRAY_LEN(facilities));
67       if (facility == -1 && strncasecmp(TT.p, "local", 5)) {
68         facility = s1[5]-'0';
69         if (facility>7 || s1[6]) facility = -1;
70         if (facility>=0) facility += 16;
71       }
72       if (facility<0) error_exit("bad facility: %s", TT.p);
73       facility *= 8;
74     }
75 
76     priority = arrayfind(s1, priorities, ARRAY_LEN(priorities));
77     if (priority<0) error_exit("bad priority: %s", s1);
78   }
79 
80   if (toys.optc) {
81     for (len = 0, arg = toys.optargs; *arg; arg++) len += strlen(*arg)+1;
82     s1 = s2 = xmalloc(len);
83     for (arg = toys.optargs; *arg; arg++) {
84       if (arg != toys.optargs) *s2++ = ' ';
85       s2 = stpcpy(s2, *arg);
86     }
87   } else {
88     toybuf[readall(0, toybuf, sizeof(toybuf)-1)] = 0;
89     s1 = toybuf;
90   }
91 
92   openlog(TT.t, LOG_PERROR*!!(toys.optflags&FLAG_s), facility);
93   syslog(priority, "%s", s1);
94   closelog();
95 }
96