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