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