xref: /openbsd-src/usr.sbin/syslogd/log.c (revision e7418ebce4c571099dc6904f2f8057bb78d3a3da)
1 /*	$OpenBSD: log.c,v 1.3 2017/04/06 14:55:43 bluhm Exp $	*/
2 
3 /*
4  * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
5  * Copyright (c) 2017 Alexander Bluhm <bluhm@openbsd.org>
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include <err.h>
21 #include <errno.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <syslog.h>
26 #include <time.h>
27 
28 #include "log.h"
29 #include "syslogd.h"
30 
31 static int		 debug;
32 static int		 verbose;
33 static int		 facility;
34 static const char	*log_procname;
35 static char		*debug_ebuf;
36 static size_t		 debug_length;
37 
38 void
39 log_init(int n_debug, int fac)
40 {
41 	extern char	*__progname;
42 
43 	debug = n_debug;
44 	verbose = n_debug;
45 	facility = fac;
46 	log_procinit(__progname);
47 
48 	if (debug_ebuf == NULL)
49 		if ((debug_ebuf = malloc(ERRBUFSIZE)) == NULL)
50 			err(1, "allocate debug buffer");
51 	debug_ebuf[0] = '\0';
52 	debug_length = 0;
53 
54 	tzset();
55 }
56 
57 void
58 log_procinit(const char *procname)
59 {
60 	if (procname != NULL)
61 		log_procname = procname;
62 }
63 
64 void
65 log_setdebug(int d)
66 {
67 	debug = d;
68 }
69 
70 int
71 log_getdebug(void)
72 {
73 	return (debug);
74 }
75 
76 void
77 log_setverbose(int v)
78 {
79 	verbose = v;
80 }
81 
82 int
83 log_getverbose(void)
84 {
85 	return (verbose);
86 }
87 
88 void
89 logit(int pri, const char *fmt, ...)
90 {
91 	va_list	ap;
92 
93 	va_start(ap, fmt);
94 	vlog(pri, fmt, ap);
95 	va_end(ap);
96 }
97 
98 void
99 vlog(int pri, const char *fmt, va_list ap)
100 {
101 	char	 ebuf[ERRBUFSIZE];
102 	size_t	 l;
103 	int	 saved_errno = errno;
104 
105 	if (debug) {
106 		l = snprintf(ebuf, sizeof(ebuf), "%s: ", log_procname);
107 		if (l < sizeof(ebuf))
108 			vsnprintf(ebuf+l, sizeof(ebuf)-l, fmt, ap);
109 		fprintf(stderr, "%s\n", ebuf);
110 		fflush(stderr);
111 	} else
112 		vlogmsg(facility|pri, log_procname, fmt, ap);
113 
114 	errno = saved_errno;
115 }
116 
117 void
118 log_warn(const char *emsg, ...)
119 {
120 	char	 ebuf[ERRBUFSIZE];
121 	size_t	 l;
122 	va_list	 ap;
123 	int	 saved_errno = errno;
124 
125 	/* best effort to even work in out of memory situations */
126 	if (emsg == NULL)
127 		logit(LOG_ERR, "%s", strerror(saved_errno));
128 	else {
129 		va_start(ap, emsg);
130 		l = vsnprintf(ebuf, sizeof(ebuf), emsg, ap);
131 		if (l < sizeof(ebuf))
132 			snprintf(ebuf+l, sizeof(ebuf)-l, ": %s",
133 			    strerror(saved_errno));
134 		logit(LOG_ERR, "%s", ebuf);
135 		va_end(ap);
136 	}
137 	errno = saved_errno;
138 }
139 
140 void
141 log_warnx(const char *emsg, ...)
142 {
143 	va_list	 ap;
144 
145 	va_start(ap, emsg);
146 	vlog(LOG_ERR, emsg, ap);
147 	va_end(ap);
148 }
149 
150 void
151 log_info(int pri, const char *emsg, ...)
152 {
153 	va_list	 ap;
154 
155 	va_start(ap, emsg);
156 	vlog(pri, emsg, ap);
157 	va_end(ap);
158 }
159 
160 void
161 log_debug(const char *emsg, ...)
162 {
163 	va_list	 ap;
164 	int	 saved_errno;
165 
166 	if (verbose) {
167 		saved_errno = errno;
168 		va_start(ap, emsg);
169 		if (debug_length < ERRBUFSIZE - 1)
170 			vsnprintf(debug_ebuf + debug_length,
171 			    ERRBUFSIZE - debug_length, emsg, ap);
172 		fprintf(stderr, "%s\n", debug_ebuf);
173 		fflush(stderr);
174 		va_end(ap);
175 		errno = saved_errno;
176 	}
177 	debug_ebuf[0] = '\0';
178 	debug_length = 0;
179 }
180 
181 void
182 log_debugadd(const char *emsg, ...)
183 {
184 	size_t	 l;
185 	va_list	 ap;
186 	int	 saved_errno;
187 
188 	if (verbose) {
189 		saved_errno = errno;
190 		va_start(ap, emsg);
191 		if (debug_length < ERRBUFSIZE - 1) {
192 			l = vsnprintf(debug_ebuf + debug_length,
193 			    ERRBUFSIZE - debug_length, emsg, ap);
194 			if (l < ERRBUFSIZE - debug_length)
195 				debug_length += l;
196 			else
197 				debug_length = ERRBUFSIZE - 1;
198 		}
199 		va_end(ap);
200 		errno = saved_errno;
201 	}
202 }
203 
204 static void
205 vfatalc(int error, const char *emsg, va_list ap)
206 {
207 	char		 ebuf[ERRBUFSIZE];
208 	const char	*sep;
209 
210 	if (emsg != NULL) {
211 		(void)vsnprintf(ebuf, sizeof(ebuf), emsg, ap);
212 		sep = ": ";
213 	} else {
214 		ebuf[0] = '\0';
215 		sep = "";
216 	}
217 	if (error)
218 		logit(LOG_CRIT, "fatal in %s: %s%s%s",
219 		    log_procname, ebuf, sep, strerror(error));
220 	else
221 		logit(LOG_CRIT, "fatal in %s%s%s", log_procname, sep, ebuf);
222 }
223 
224 void
225 fatal(const char *emsg, ...)
226 {
227 	va_list	ap;
228 
229 	va_start(ap, emsg);
230 	vfatalc(errno, emsg, ap);
231 	va_end(ap);
232 	die(0);
233 }
234 
235 void
236 fatalx(const char *emsg, ...)
237 {
238 	va_list	ap;
239 
240 	va_start(ap, emsg);
241 	vfatalc(0, emsg, ap);
242 	va_end(ap);
243 	die(0);
244 }
245