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