1*c0785a05Sreyk /* $OpenBSD: log.c,v 1.9 2018/05/15 11:19:21 reyk Exp $ */
25d465952Smartinh
35d465952Smartinh /*
45d465952Smartinh * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
55d465952Smartinh *
65d465952Smartinh * Permission to use, copy, modify, and distribute this software for any
75d465952Smartinh * purpose with or without fee is hereby granted, provided that the above
85d465952Smartinh * copyright notice and this permission notice appear in all copies.
95d465952Smartinh *
105d465952Smartinh * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
115d465952Smartinh * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
125d465952Smartinh * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
135d465952Smartinh * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14fdd30f56Sbenno * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15fdd30f56Sbenno * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16fdd30f56Sbenno * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
175d465952Smartinh */
185d465952Smartinh
195d465952Smartinh #include <stdio.h>
205d465952Smartinh #include <stdlib.h>
21*c0785a05Sreyk #include <stdarg.h>
225d465952Smartinh #include <string.h>
235d465952Smartinh #include <syslog.h>
24*c0785a05Sreyk #include <errno.h>
255d465952Smartinh #include <time.h>
265d465952Smartinh
27*c0785a05Sreyk static int debug;
28*c0785a05Sreyk static int verbose;
29*c0785a05Sreyk const char *log_procname;
305d465952Smartinh
31*c0785a05Sreyk void log_init(int, int);
32*c0785a05Sreyk void log_procinit(const char *);
33*c0785a05Sreyk void log_setverbose(int);
34*c0785a05Sreyk int log_getverbose(void);
35*c0785a05Sreyk void log_warn(const char *, ...)
36*c0785a05Sreyk __attribute__((__format__ (printf, 1, 2)));
37*c0785a05Sreyk void log_warnx(const char *, ...)
38*c0785a05Sreyk __attribute__((__format__ (printf, 1, 2)));
39*c0785a05Sreyk void log_info(const char *, ...)
40*c0785a05Sreyk __attribute__((__format__ (printf, 1, 2)));
41*c0785a05Sreyk void log_debug(const char *, ...)
42*c0785a05Sreyk __attribute__((__format__ (printf, 1, 2)));
43*c0785a05Sreyk void logit(int, const char *, ...)
44*c0785a05Sreyk __attribute__((__format__ (printf, 2, 3)));
45*c0785a05Sreyk void vlog(int, const char *, va_list)
46*c0785a05Sreyk __attribute__((__format__ (printf, 2, 0)));
47*c0785a05Sreyk __dead void fatal(const char *, ...)
48*c0785a05Sreyk __attribute__((__format__ (printf, 1, 2)));
49*c0785a05Sreyk __dead void fatalx(const char *, ...)
50*c0785a05Sreyk __attribute__((__format__ (printf, 1, 2)));
515d465952Smartinh
525d465952Smartinh void
log_init(int n_debug,int facility)53*c0785a05Sreyk log_init(int n_debug, int facility)
545d465952Smartinh {
555d465952Smartinh extern char *__progname;
565d465952Smartinh
575d465952Smartinh debug = n_debug;
58*c0785a05Sreyk verbose = n_debug;
59*c0785a05Sreyk log_procinit(__progname);
605d465952Smartinh
615d465952Smartinh if (!debug)
62*c0785a05Sreyk openlog(__progname, LOG_PID | LOG_NDELAY, facility);
635d465952Smartinh
645d465952Smartinh tzset();
655d465952Smartinh }
665d465952Smartinh
675d465952Smartinh void
log_procinit(const char * procname)68*c0785a05Sreyk log_procinit(const char *procname)
69*c0785a05Sreyk {
70*c0785a05Sreyk if (procname != NULL)
71*c0785a05Sreyk log_procname = procname;
72*c0785a05Sreyk }
73*c0785a05Sreyk
74*c0785a05Sreyk void
log_setverbose(int v)75*c0785a05Sreyk log_setverbose(int v)
765d465952Smartinh {
775d465952Smartinh verbose = v;
785d465952Smartinh }
795d465952Smartinh
80*c0785a05Sreyk int
log_getverbose(void)81*c0785a05Sreyk log_getverbose(void)
82*c0785a05Sreyk {
83*c0785a05Sreyk return (verbose);
84*c0785a05Sreyk }
85*c0785a05Sreyk
865d465952Smartinh void
logit(int pri,const char * fmt,...)875d465952Smartinh logit(int pri, const char *fmt, ...)
885d465952Smartinh {
895d465952Smartinh va_list ap;
905d465952Smartinh
915d465952Smartinh va_start(ap, fmt);
925d465952Smartinh vlog(pri, fmt, ap);
935d465952Smartinh va_end(ap);
945d465952Smartinh }
955d465952Smartinh
965d465952Smartinh void
vlog(int pri,const char * fmt,va_list ap)975d465952Smartinh vlog(int pri, const char *fmt, va_list ap)
985d465952Smartinh {
995d465952Smartinh char *nfmt;
100*c0785a05Sreyk int saved_errno = errno;
1015d465952Smartinh
1025d465952Smartinh if (debug) {
1035d465952Smartinh /* best effort in out of mem situations */
1045d465952Smartinh if (asprintf(&nfmt, "%s\n", fmt) == -1) {
1055d465952Smartinh vfprintf(stderr, fmt, ap);
1065d465952Smartinh fprintf(stderr, "\n");
1075d465952Smartinh } else {
1085d465952Smartinh vfprintf(stderr, nfmt, ap);
1095d465952Smartinh free(nfmt);
1105d465952Smartinh }
1115d465952Smartinh fflush(stderr);
1125d465952Smartinh } else
1135d465952Smartinh vsyslog(pri, fmt, ap);
114*c0785a05Sreyk
115*c0785a05Sreyk errno = saved_errno;
1165d465952Smartinh }
1175d465952Smartinh
1185d465952Smartinh void
log_warn(const char * emsg,...)1195d465952Smartinh log_warn(const char *emsg, ...)
1205d465952Smartinh {
1215d465952Smartinh char *nfmt;
1225d465952Smartinh va_list ap;
123*c0785a05Sreyk int saved_errno = errno;
1245d465952Smartinh
1255d465952Smartinh /* best effort to even work in out of memory situations */
1265d465952Smartinh if (emsg == NULL)
127*c0785a05Sreyk logit(LOG_ERR, "%s", strerror(saved_errno));
1285d465952Smartinh else {
1295d465952Smartinh va_start(ap, emsg);
1305d465952Smartinh
131*c0785a05Sreyk if (asprintf(&nfmt, "%s: %s", emsg,
132*c0785a05Sreyk strerror(saved_errno)) == -1) {
1335d465952Smartinh /* we tried it... */
1349b2c1562Sbluhm vlog(LOG_ERR, emsg, ap);
135*c0785a05Sreyk logit(LOG_ERR, "%s", strerror(saved_errno));
1365d465952Smartinh } else {
1379b2c1562Sbluhm vlog(LOG_ERR, nfmt, ap);
1385d465952Smartinh free(nfmt);
1395d465952Smartinh }
1405d465952Smartinh va_end(ap);
1415d465952Smartinh }
142*c0785a05Sreyk
143*c0785a05Sreyk errno = saved_errno;
1445d465952Smartinh }
1455d465952Smartinh
1465d465952Smartinh void
log_warnx(const char * emsg,...)1475d465952Smartinh log_warnx(const char *emsg, ...)
1485d465952Smartinh {
1495d465952Smartinh va_list ap;
1505d465952Smartinh
1515d465952Smartinh va_start(ap, emsg);
1529b2c1562Sbluhm vlog(LOG_ERR, emsg, ap);
1535d465952Smartinh va_end(ap);
1545d465952Smartinh }
1555d465952Smartinh
1565d465952Smartinh void
log_info(const char * emsg,...)1575d465952Smartinh log_info(const char *emsg, ...)
1585d465952Smartinh {
1595d465952Smartinh va_list ap;
1605d465952Smartinh
1615d465952Smartinh va_start(ap, emsg);
1625d465952Smartinh vlog(LOG_INFO, emsg, ap);
1635d465952Smartinh va_end(ap);
1645d465952Smartinh }
1655d465952Smartinh
1665d465952Smartinh void
log_debug(const char * emsg,...)1675d465952Smartinh log_debug(const char *emsg, ...)
1685d465952Smartinh {
1695d465952Smartinh va_list ap;
1705d465952Smartinh
171*c0785a05Sreyk if (verbose > 1) {
1725d465952Smartinh va_start(ap, emsg);
1735d465952Smartinh vlog(LOG_DEBUG, emsg, ap);
1745d465952Smartinh va_end(ap);
1755d465952Smartinh }
1765d465952Smartinh }
1775d465952Smartinh
178*c0785a05Sreyk static void
vfatalc(int code,const char * emsg,va_list ap)179*c0785a05Sreyk vfatalc(int code, const char *emsg, va_list ap)
1805d465952Smartinh {
181*c0785a05Sreyk static char s[BUFSIZ];
182*c0785a05Sreyk const char *sep;
1835d465952Smartinh
184*c0785a05Sreyk if (emsg != NULL) {
185*c0785a05Sreyk (void)vsnprintf(s, sizeof(s), emsg, ap);
186*c0785a05Sreyk sep = ": ";
187*c0785a05Sreyk } else {
188*c0785a05Sreyk s[0] = '\0';
189*c0785a05Sreyk sep = "";
190*c0785a05Sreyk }
191*c0785a05Sreyk if (code)
192*c0785a05Sreyk logit(LOG_CRIT, "%s: %s%s%s",
193*c0785a05Sreyk log_procname, s, sep, strerror(code));
194*c0785a05Sreyk else
195*c0785a05Sreyk logit(LOG_CRIT, "%s%s%s", log_procname, sep, s);
196*c0785a05Sreyk }
197*c0785a05Sreyk
198*c0785a05Sreyk void
fatal(const char * emsg,...)199*c0785a05Sreyk fatal(const char *emsg, ...)
200*c0785a05Sreyk {
201*c0785a05Sreyk va_list ap;
202*c0785a05Sreyk
203*c0785a05Sreyk va_start(ap, emsg);
204*c0785a05Sreyk vfatalc(errno, emsg, ap);
205*c0785a05Sreyk va_end(ap);
2065d465952Smartinh exit(1);
2075d465952Smartinh }
2085d465952Smartinh
2095d465952Smartinh void
fatalx(const char * emsg,...)210*c0785a05Sreyk fatalx(const char *emsg, ...)
2115d465952Smartinh {
212*c0785a05Sreyk va_list ap;
213*c0785a05Sreyk
214*c0785a05Sreyk va_start(ap, emsg);
215*c0785a05Sreyk vfatalc(0, emsg, ap);
216*c0785a05Sreyk va_end(ap);
217*c0785a05Sreyk exit(1);
2185d465952Smartinh }
219