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