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