1 /* $OpenBSD: logger.c,v 1.19 2022/12/04 23:50:48 cheloha Exp $ */
2 /* $NetBSD: logger.c,v 1.4 1994/12/22 06:27:00 jtc Exp $ */
3
4 /*
5 * Copyright (c) 1983, 1993
6 * The Regents of the University of California. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the University nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32
33 #include <errno.h>
34 #include <unistd.h>
35 #include <limits.h>
36 #include <stdlib.h>
37 #include <stdio.h>
38 #include <ctype.h>
39 #include <string.h>
40 #include <err.h>
41
42 #define SYSLOG_NAMES
43 #include <syslog.h>
44
45 int decode(char *, CODE *);
46 int pencode(char *);
47 void usage(void);
48
49 /*
50 * logger -- read and log utility
51 *
52 * Reads from an input and arranges to write the result on the system
53 * log.
54 */
55 int
main(int argc,char * argv[])56 main(int argc, char *argv[])
57 {
58 int ch, logflags, pri;
59 char *tag, buf[1024];
60
61 tag = NULL;
62 pri = LOG_NOTICE;
63 logflags = 0;
64 while ((ch = getopt(argc, argv, "cf:ip:st:")) != -1)
65 switch(ch) {
66 case 'c': /* log to console */
67 logflags |= LOG_CONS;
68 break;
69 case 'f': /* file to log */
70 if (freopen(optarg, "r", stdin) == NULL) {
71 (void)fprintf(stderr, "logger: %s: %s.\n",
72 optarg, strerror(errno));
73 exit(1);
74 }
75 break;
76 case 'i': /* log process id also */
77 logflags |= LOG_PID;
78 break;
79 case 'p': /* priority */
80 pri = pencode(optarg);
81 break;
82 case 's': /* log to standard error */
83 logflags |= LOG_PERROR;
84 break;
85 case 't': /* tag */
86 tag = optarg;
87 break;
88 default:
89 usage();
90 }
91 argc -= optind;
92 argv += optind;
93
94 /* setup for logging */
95 openlog(tag ? tag : getlogin(), logflags, 0);
96 (void) fclose(stdout);
97
98 if (pledge("stdio", NULL) == -1)
99 err(1, "pledge");
100
101 /* log input line if appropriate */
102 if (argc > 0) {
103 char *p, *endp;
104 size_t len;
105
106 for (p = buf, endp = buf + sizeof(buf) - 2; *argv;) {
107 len = strlen(*argv);
108 if (p + len > endp && p > buf) {
109 syslog(pri, "%s", buf);
110 p = buf;
111 }
112 if (len > sizeof(buf) - 1)
113 syslog(pri, "%s", *argv++);
114 else {
115 if (p != buf)
116 *p++ = ' ';
117 bcopy(*argv++, p, len);
118 *(p += len) = '\0';
119 }
120 }
121 if (p != buf)
122 syslog(pri, "%s", buf);
123 } else
124 while (fgets(buf, sizeof(buf), stdin) != NULL)
125 syslog(pri, "%s", buf);
126 exit(0);
127 }
128
129 /*
130 * Decode a symbolic name to a numeric value
131 */
132 int
pencode(char * s)133 pencode(char *s)
134 {
135 char *save;
136 int fac, lev;
137
138 for (save = s; *s && *s != '.'; ++s);
139 if (*s) {
140 *s = '\0';
141 fac = decode(save, facilitynames);
142 if (fac < 0) {
143 (void)fprintf(stderr,
144 "logger: unknown facility name: %s.\n", save);
145 exit(1);
146 }
147 *s++ = '.';
148 }
149 else {
150 fac = 0;
151 s = save;
152 }
153 lev = decode(s, prioritynames);
154 if (lev < 0) {
155 (void)fprintf(stderr,
156 "logger: unknown priority name: %s.\n", save);
157 exit(1);
158 }
159 return ((lev & LOG_PRIMASK) | (fac & LOG_FACMASK));
160 }
161
162 int
decode(char * name,CODE * codetab)163 decode(char *name, CODE *codetab)
164 {
165 CODE *c;
166
167 if (isdigit((unsigned char)*name)) {
168 const char *errstr;
169 int n = strtonum(name, 0, INT_MAX, &errstr);
170 if (!errstr)
171 return (n);
172 }
173
174 for (c = codetab; c->c_name; c++)
175 if (!strcasecmp(name, c->c_name))
176 return (c->c_val);
177
178 return (-1);
179 }
180
181 void
usage(void)182 usage(void)
183 {
184 (void)fprintf(stderr,
185 "usage: logger [-cis] [-f file] [-p pri] [-t tag] [message ...]\n");
186 exit(1);
187 }
188