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