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