xref: /openbsd/usr.sbin/radiusd/log.c (revision a7ca44b8)
1*a7ca44b8Syasuoka /*	$OpenBSD: log.c,v 1.1 2015/07/21 04:06:04 yasuoka Exp $ */
2*a7ca44b8Syasuoka 
3*a7ca44b8Syasuoka /*
4*a7ca44b8Syasuoka  * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
5*a7ca44b8Syasuoka  *
6*a7ca44b8Syasuoka  * Permission to use, copy, modify, and distribute this software for any
7*a7ca44b8Syasuoka  * purpose with or without fee is hereby granted, provided that the above
8*a7ca44b8Syasuoka  * copyright notice and this permission notice appear in all copies.
9*a7ca44b8Syasuoka  *
10*a7ca44b8Syasuoka  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11*a7ca44b8Syasuoka  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12*a7ca44b8Syasuoka  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13*a7ca44b8Syasuoka  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14*a7ca44b8Syasuoka  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15*a7ca44b8Syasuoka  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16*a7ca44b8Syasuoka  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*a7ca44b8Syasuoka  */
18*a7ca44b8Syasuoka 
19*a7ca44b8Syasuoka #include <errno.h>
20*a7ca44b8Syasuoka #include <stdarg.h>
21*a7ca44b8Syasuoka #include <stdio.h>
22*a7ca44b8Syasuoka #include <stdlib.h>
23*a7ca44b8Syasuoka #include <string.h>
24*a7ca44b8Syasuoka #include <syslog.h>
25*a7ca44b8Syasuoka #include <time.h>
26*a7ca44b8Syasuoka 
27*a7ca44b8Syasuoka #include "log.h"
28*a7ca44b8Syasuoka 
29*a7ca44b8Syasuoka int		 log_debug_use_syslog = 0;
30*a7ca44b8Syasuoka static int	 log_initialized = 0;
31*a7ca44b8Syasuoka static int	 debug = 0;
32*a7ca44b8Syasuoka 
33*a7ca44b8Syasuoka void	 logit(int, const char *, ...);
34*a7ca44b8Syasuoka 
35*a7ca44b8Syasuoka void
36*a7ca44b8Syasuoka log_init(int n_debug)
37*a7ca44b8Syasuoka {
38*a7ca44b8Syasuoka 	extern char	*__progname;
39*a7ca44b8Syasuoka 
40*a7ca44b8Syasuoka 	debug = n_debug;
41*a7ca44b8Syasuoka 
42*a7ca44b8Syasuoka 	if (!debug)
43*a7ca44b8Syasuoka 		openlog(__progname, LOG_PID | LOG_NDELAY, LOG_DAEMON);
44*a7ca44b8Syasuoka 
45*a7ca44b8Syasuoka 	tzset();
46*a7ca44b8Syasuoka 	log_initialized++;
47*a7ca44b8Syasuoka }
48*a7ca44b8Syasuoka 
49*a7ca44b8Syasuoka void
50*a7ca44b8Syasuoka logit(int pri, const char *fmt, ...)
51*a7ca44b8Syasuoka {
52*a7ca44b8Syasuoka 	va_list	ap;
53*a7ca44b8Syasuoka 
54*a7ca44b8Syasuoka 	va_start(ap, fmt);
55*a7ca44b8Syasuoka 	vlog(pri, fmt, ap);
56*a7ca44b8Syasuoka 	va_end(ap);
57*a7ca44b8Syasuoka }
58*a7ca44b8Syasuoka 
59*a7ca44b8Syasuoka void
60*a7ca44b8Syasuoka vlog(int pri, const char *fmt, va_list ap)
61*a7ca44b8Syasuoka {
62*a7ca44b8Syasuoka 	char			 fmtbuf[1024];
63*a7ca44b8Syasuoka 	time_t			 curr;
64*a7ca44b8Syasuoka 	struct tm		 tm;
65*a7ca44b8Syasuoka 	u_int			 i = 0, j;
66*a7ca44b8Syasuoka 	static struct {
67*a7ca44b8Syasuoka 		int		 v;
68*a7ca44b8Syasuoka 		const char	*l;
69*a7ca44b8Syasuoka 	} syslog_prionames[] = {
70*a7ca44b8Syasuoka #define	NV(_l)	{ _l, #_l }
71*a7ca44b8Syasuoka 		NV(LOG_DEBUG),
72*a7ca44b8Syasuoka 		NV(LOG_INFO),
73*a7ca44b8Syasuoka 		NV(LOG_NOTICE),
74*a7ca44b8Syasuoka 		NV(LOG_WARNING),
75*a7ca44b8Syasuoka 		NV(LOG_ERR),
76*a7ca44b8Syasuoka 		NV(LOG_ALERT),
77*a7ca44b8Syasuoka 		NV(LOG_CRIT),
78*a7ca44b8Syasuoka #undef NV
79*a7ca44b8Syasuoka 		{ -1, NULL }
80*a7ca44b8Syasuoka 	};
81*a7ca44b8Syasuoka 
82*a7ca44b8Syasuoka 	if (log_initialized && !debug) {
83*a7ca44b8Syasuoka 		vsyslog(pri, fmt, ap);
84*a7ca44b8Syasuoka 		return;
85*a7ca44b8Syasuoka 	}
86*a7ca44b8Syasuoka 	if (log_initialized) {
87*a7ca44b8Syasuoka 		time(&curr);
88*a7ca44b8Syasuoka 		localtime_r(&curr, &tm);
89*a7ca44b8Syasuoka 		strftime(fmtbuf, sizeof(fmtbuf), "%Y-%m-%d %H:%M:%S:", &tm);
90*a7ca44b8Syasuoka 		for (i = 0; syslog_prionames[i].v != -1; i++) {
91*a7ca44b8Syasuoka 			if (syslog_prionames[i].v == LOG_PRI(pri)) {
92*a7ca44b8Syasuoka 				strlcat(fmtbuf, syslog_prionames[i].l + 4,
93*a7ca44b8Syasuoka 				    sizeof(fmtbuf));
94*a7ca44b8Syasuoka 				strlcat(fmtbuf, ": ", sizeof(fmtbuf));
95*a7ca44b8Syasuoka 				break;
96*a7ca44b8Syasuoka 			}
97*a7ca44b8Syasuoka 		}
98*a7ca44b8Syasuoka 		i = strlen(fmtbuf);
99*a7ca44b8Syasuoka 	}
100*a7ca44b8Syasuoka 	for (j = 0; i < sizeof(fmtbuf) - 2 && fmt[j] != '\0'; j++) {
101*a7ca44b8Syasuoka 		if (fmt[j] == '%' && fmt[j + 1] == 'm') {
102*a7ca44b8Syasuoka 			++j;
103*a7ca44b8Syasuoka 			fmtbuf[i] = '\0';
104*a7ca44b8Syasuoka 			strlcat(fmtbuf, strerror(errno), sizeof(fmtbuf) - 1);
105*a7ca44b8Syasuoka 			i = strlen(fmtbuf);
106*a7ca44b8Syasuoka 		} else
107*a7ca44b8Syasuoka 			fmtbuf[i++] = fmt[j];
108*a7ca44b8Syasuoka 	}
109*a7ca44b8Syasuoka 	fmtbuf[i++] = '\n';
110*a7ca44b8Syasuoka 	fmtbuf[i++] = '\0';
111*a7ca44b8Syasuoka 
112*a7ca44b8Syasuoka 	vfprintf(stderr, fmtbuf, ap);
113*a7ca44b8Syasuoka }
114*a7ca44b8Syasuoka 
115*a7ca44b8Syasuoka 
116*a7ca44b8Syasuoka void
117*a7ca44b8Syasuoka log_warn(const char *emsg, ...)
118*a7ca44b8Syasuoka {
119*a7ca44b8Syasuoka 	char	*nfmt;
120*a7ca44b8Syasuoka 	va_list	 ap;
121*a7ca44b8Syasuoka 
122*a7ca44b8Syasuoka 	/* best effort to even work in out of memory situations */
123*a7ca44b8Syasuoka 	if (emsg == NULL)
124*a7ca44b8Syasuoka 		logit(LOG_WARNING, "%s", strerror(errno));
125*a7ca44b8Syasuoka 	else {
126*a7ca44b8Syasuoka 		va_start(ap, emsg);
127*a7ca44b8Syasuoka 
128*a7ca44b8Syasuoka 		if (asprintf(&nfmt, "%s: %s", emsg, strerror(errno)) == -1) {
129*a7ca44b8Syasuoka 			/* we tried it... */
130*a7ca44b8Syasuoka 			vlog(LOG_WARNING, emsg, ap);
131*a7ca44b8Syasuoka 			logit(LOG_WARNING, "%s", strerror(errno));
132*a7ca44b8Syasuoka 		} else {
133*a7ca44b8Syasuoka 			vlog(LOG_WARNING, nfmt, ap);
134*a7ca44b8Syasuoka 			free(nfmt);
135*a7ca44b8Syasuoka 		}
136*a7ca44b8Syasuoka 		va_end(ap);
137*a7ca44b8Syasuoka 	}
138*a7ca44b8Syasuoka }
139*a7ca44b8Syasuoka 
140*a7ca44b8Syasuoka void
141*a7ca44b8Syasuoka log_warnx(const char *emsg, ...)
142*a7ca44b8Syasuoka {
143*a7ca44b8Syasuoka 	va_list	 ap;
144*a7ca44b8Syasuoka 
145*a7ca44b8Syasuoka 	va_start(ap, emsg);
146*a7ca44b8Syasuoka 	vlog(LOG_WARNING, emsg, ap);
147*a7ca44b8Syasuoka 	va_end(ap);
148*a7ca44b8Syasuoka }
149*a7ca44b8Syasuoka 
150*a7ca44b8Syasuoka void
151*a7ca44b8Syasuoka log_info(const char *emsg, ...)
152*a7ca44b8Syasuoka {
153*a7ca44b8Syasuoka 	va_list	 ap;
154*a7ca44b8Syasuoka 
155*a7ca44b8Syasuoka 	va_start(ap, emsg);
156*a7ca44b8Syasuoka 	vlog(LOG_INFO, emsg, ap);
157*a7ca44b8Syasuoka 	va_end(ap);
158*a7ca44b8Syasuoka }
159*a7ca44b8Syasuoka 
160*a7ca44b8Syasuoka void
161*a7ca44b8Syasuoka log_debug(const char *emsg, ...)
162*a7ca44b8Syasuoka {
163*a7ca44b8Syasuoka 	va_list	 ap;
164*a7ca44b8Syasuoka 
165*a7ca44b8Syasuoka 	if (debug || log_debug_use_syslog) {
166*a7ca44b8Syasuoka 		va_start(ap, emsg);
167*a7ca44b8Syasuoka 		vlog(LOG_DEBUG, emsg, ap);
168*a7ca44b8Syasuoka 		va_end(ap);
169*a7ca44b8Syasuoka 	}
170*a7ca44b8Syasuoka }
171*a7ca44b8Syasuoka 
172*a7ca44b8Syasuoka void
173*a7ca44b8Syasuoka fatal(const char *emsg)
174*a7ca44b8Syasuoka {
175*a7ca44b8Syasuoka 	if (emsg == NULL)
176*a7ca44b8Syasuoka 		logit(LOG_CRIT, "fatal: %s", strerror(errno));
177*a7ca44b8Syasuoka 	else
178*a7ca44b8Syasuoka 		if (errno)
179*a7ca44b8Syasuoka 			logit(LOG_CRIT, "fatal: %s: %s",
180*a7ca44b8Syasuoka 			    emsg, strerror(errno));
181*a7ca44b8Syasuoka 		else
182*a7ca44b8Syasuoka 			logit(LOG_CRIT, "fatal: %s", emsg);
183*a7ca44b8Syasuoka 
184*a7ca44b8Syasuoka 	exit(1);
185*a7ca44b8Syasuoka }
186*a7ca44b8Syasuoka 
187*a7ca44b8Syasuoka void
188*a7ca44b8Syasuoka fatalx(const char *emsg)
189*a7ca44b8Syasuoka {
190*a7ca44b8Syasuoka 	errno = 0;
191*a7ca44b8Syasuoka 	fatal(emsg);
192*a7ca44b8Syasuoka }
193