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