1*9b2c1562Sbluhm /* $OpenBSD: log.c,v 1.20 2017/03/21 12:06:56 bluhm Exp $ */
23ef9cbf7Sgilles
33ef9cbf7Sgilles /*
43ef9cbf7Sgilles * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
53ef9cbf7Sgilles *
63ef9cbf7Sgilles * Permission to use, copy, modify, and distribute this software for any
73ef9cbf7Sgilles * purpose with or without fee is hereby granted, provided that the above
83ef9cbf7Sgilles * copyright notice and this permission notice appear in all copies.
93ef9cbf7Sgilles *
103ef9cbf7Sgilles * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
113ef9cbf7Sgilles * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
123ef9cbf7Sgilles * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
133ef9cbf7Sgilles * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14f24248b7Sreyk * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15f24248b7Sreyk * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16f24248b7Sreyk * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
173ef9cbf7Sgilles */
183ef9cbf7Sgilles
193ef9cbf7Sgilles #include <stdio.h>
203ef9cbf7Sgilles #include <stdlib.h>
21f24248b7Sreyk #include <stdarg.h>
223ef9cbf7Sgilles #include <string.h>
233ef9cbf7Sgilles #include <syslog.h>
24f24248b7Sreyk #include <errno.h>
2544c6c770Schl #include <time.h>
263ef9cbf7Sgilles
27871fc12cSreyk static int debug;
28871fc12cSreyk static int verbose;
29f24248b7Sreyk const char *log_procname;
303ef9cbf7Sgilles
31f24248b7Sreyk void log_init(int, int);
32f24248b7Sreyk void log_procinit(const char *);
33871fc12cSreyk void log_setverbose(int);
34871fc12cSreyk int log_getverbose(void);
35f24248b7Sreyk void log_warn(const char *, ...)
36f24248b7Sreyk __attribute__((__format__ (printf, 1, 2)));
37f24248b7Sreyk void log_warnx(const char *, ...)
38f24248b7Sreyk __attribute__((__format__ (printf, 1, 2)));
39f24248b7Sreyk void log_info(const char *, ...)
40f24248b7Sreyk __attribute__((__format__ (printf, 1, 2)));
41f24248b7Sreyk void log_debug(const char *, ...)
42f24248b7Sreyk __attribute__((__format__ (printf, 1, 2)));
43654fac80Scloder void logit(int, const char *, ...)
44f24248b7Sreyk __attribute__((__format__ (printf, 2, 3)));
45f24248b7Sreyk void vlog(int, const char *, va_list)
46f24248b7Sreyk __attribute__((__format__ (printf, 2, 0)));
47f24248b7Sreyk __dead void fatal(const char *, ...)
48f24248b7Sreyk __attribute__((__format__ (printf, 1, 2)));
49f24248b7Sreyk __dead void fatalx(const char *, ...)
50f24248b7Sreyk __attribute__((__format__ (printf, 1, 2)));
513ef9cbf7Sgilles
523ef9cbf7Sgilles void
log_init(int n_debug,int facility)53f24248b7Sreyk log_init(int n_debug, int facility)
543ef9cbf7Sgilles {
553ef9cbf7Sgilles extern char *__progname;
563ef9cbf7Sgilles
57f24248b7Sreyk debug = n_debug;
58f24248b7Sreyk verbose = n_debug;
59f24248b7Sreyk log_procinit(__progname);
60f24248b7Sreyk
61f24248b7Sreyk if (!debug)
62f24248b7Sreyk openlog(__progname, LOG_PID | LOG_NDELAY, facility);
633ef9cbf7Sgilles
643ef9cbf7Sgilles tzset();
653ef9cbf7Sgilles }
663ef9cbf7Sgilles
673ef9cbf7Sgilles void
log_procinit(const char * procname)68f24248b7Sreyk log_procinit(const char *procname)
69f24248b7Sreyk {
70f24248b7Sreyk if (procname != NULL)
71f24248b7Sreyk log_procname = procname;
72f24248b7Sreyk }
73f24248b7Sreyk
74f24248b7Sreyk void
log_setverbose(int v)75871fc12cSreyk log_setverbose(int v)
76ba0c8f48Schl {
77ba0c8f48Schl verbose = v;
78ba0c8f48Schl }
79ba0c8f48Schl
80871fc12cSreyk int
log_getverbose(void)81871fc12cSreyk log_getverbose(void)
82871fc12cSreyk {
83871fc12cSreyk return (verbose);
84871fc12cSreyk }
85871fc12cSreyk
86ba0c8f48Schl void
logit(int pri,const char * fmt,...)873ef9cbf7Sgilles logit(int pri, const char *fmt, ...)
883ef9cbf7Sgilles {
893ef9cbf7Sgilles va_list ap;
903ef9cbf7Sgilles
913ef9cbf7Sgilles va_start(ap, fmt);
923ef9cbf7Sgilles vlog(pri, fmt, ap);
933ef9cbf7Sgilles va_end(ap);
943ef9cbf7Sgilles }
953ef9cbf7Sgilles
963ef9cbf7Sgilles void
vlog(int pri,const char * fmt,va_list ap)973ef9cbf7Sgilles vlog(int pri, const char *fmt, va_list ap)
983ef9cbf7Sgilles {
993ef9cbf7Sgilles char *nfmt;
100f24248b7Sreyk int saved_errno = errno;
1013ef9cbf7Sgilles
102f24248b7Sreyk if (debug) {
1033ef9cbf7Sgilles /* best effort in out of mem situations */
1043ef9cbf7Sgilles if (asprintf(&nfmt, "%s\n", fmt) == -1) {
1053ef9cbf7Sgilles vfprintf(stderr, fmt, ap);
1063ef9cbf7Sgilles fprintf(stderr, "\n");
1073ef9cbf7Sgilles } else {
1083ef9cbf7Sgilles vfprintf(stderr, nfmt, ap);
1093ef9cbf7Sgilles free(nfmt);
1103ef9cbf7Sgilles }
1113ef9cbf7Sgilles fflush(stderr);
1123ef9cbf7Sgilles } else
1133ef9cbf7Sgilles vsyslog(pri, fmt, ap);
1143ef9cbf7Sgilles
115f24248b7Sreyk errno = saved_errno;
116f24248b7Sreyk }
1173ef9cbf7Sgilles
1183ef9cbf7Sgilles void
log_warn(const char * emsg,...)1193ef9cbf7Sgilles log_warn(const char *emsg, ...)
1203ef9cbf7Sgilles {
1213ef9cbf7Sgilles char *nfmt;
1223ef9cbf7Sgilles va_list ap;
123f24248b7Sreyk int saved_errno = errno;
1243ef9cbf7Sgilles
1253ef9cbf7Sgilles /* best effort to even work in out of memory situations */
1263ef9cbf7Sgilles if (emsg == NULL)
127*9b2c1562Sbluhm logit(LOG_ERR, "%s", strerror(saved_errno));
1283ef9cbf7Sgilles else {
1293ef9cbf7Sgilles va_start(ap, emsg);
1303ef9cbf7Sgilles
131f24248b7Sreyk if (asprintf(&nfmt, "%s: %s", emsg,
132f24248b7Sreyk strerror(saved_errno)) == -1) {
1333ef9cbf7Sgilles /* we tried it... */
134*9b2c1562Sbluhm vlog(LOG_ERR, emsg, ap);
135*9b2c1562Sbluhm logit(LOG_ERR, "%s", strerror(saved_errno));
1363ef9cbf7Sgilles } else {
137*9b2c1562Sbluhm vlog(LOG_ERR, nfmt, ap);
1383ef9cbf7Sgilles free(nfmt);
1393ef9cbf7Sgilles }
1403ef9cbf7Sgilles va_end(ap);
1413ef9cbf7Sgilles }
142f24248b7Sreyk
143f24248b7Sreyk errno = saved_errno;
1443ef9cbf7Sgilles }
1453ef9cbf7Sgilles
1463ef9cbf7Sgilles void
log_warnx(const char * emsg,...)1473ef9cbf7Sgilles log_warnx(const char *emsg, ...)
1483ef9cbf7Sgilles {
1493ef9cbf7Sgilles va_list ap;
1503ef9cbf7Sgilles
1513ef9cbf7Sgilles va_start(ap, emsg);
152*9b2c1562Sbluhm vlog(LOG_ERR, emsg, ap);
1533ef9cbf7Sgilles va_end(ap);
1543ef9cbf7Sgilles }
1553ef9cbf7Sgilles
1563ef9cbf7Sgilles void
log_info(const char * emsg,...)1573ef9cbf7Sgilles log_info(const char *emsg, ...)
1583ef9cbf7Sgilles {
1593ef9cbf7Sgilles va_list ap;
1603ef9cbf7Sgilles
1613ef9cbf7Sgilles va_start(ap, emsg);
1623ef9cbf7Sgilles vlog(LOG_INFO, emsg, ap);
1633ef9cbf7Sgilles va_end(ap);
1643ef9cbf7Sgilles }
1653ef9cbf7Sgilles
1663ef9cbf7Sgilles void
log_debug(const char * emsg,...)1673ef9cbf7Sgilles log_debug(const char *emsg, ...)
1683ef9cbf7Sgilles {
1693ef9cbf7Sgilles va_list ap;
1703ef9cbf7Sgilles
171f24248b7Sreyk if (verbose > 1) {
172bfe8e0bcSeric va_start(ap, emsg);
173bfe8e0bcSeric vlog(LOG_DEBUG, emsg, ap);
174bfe8e0bcSeric va_end(ap);
175bfe8e0bcSeric }
176bfe8e0bcSeric }
177bfe8e0bcSeric
178be216e8fSeric static void
vfatalc(int code,const char * emsg,va_list ap)179f24248b7Sreyk vfatalc(int code, const char *emsg, va_list ap)
1803ef9cbf7Sgilles {
181f24248b7Sreyk static char s[BUFSIZ];
182f24248b7Sreyk const char *sep;
1833ef9cbf7Sgilles
184f24248b7Sreyk if (emsg != NULL) {
185f24248b7Sreyk (void)vsnprintf(s, sizeof(s), emsg, ap);
186f24248b7Sreyk sep = ": ";
187f24248b7Sreyk } else {
188f24248b7Sreyk s[0] = '\0';
189f24248b7Sreyk sep = "";
190be216e8fSeric }
191f24248b7Sreyk if (code)
192f24248b7Sreyk logit(LOG_CRIT, "%s: %s%s%s",
193f24248b7Sreyk log_procname, s, sep, strerror(code));
194be216e8fSeric else
195f24248b7Sreyk logit(LOG_CRIT, "%s%s%s", log_procname, sep, s);
196be216e8fSeric }
197be216e8fSeric
198be216e8fSeric void
fatal(const char * emsg,...)199be216e8fSeric fatal(const char *emsg, ...)
200be216e8fSeric {
201be216e8fSeric va_list ap;
202be216e8fSeric
203be216e8fSeric va_start(ap, emsg);
204f24248b7Sreyk vfatalc(errno, emsg, ap);
205be216e8fSeric va_end(ap);
2063ef9cbf7Sgilles exit(1);
2073ef9cbf7Sgilles }
2083ef9cbf7Sgilles
2093ef9cbf7Sgilles void
fatalx(const char * emsg,...)210be216e8fSeric fatalx(const char *emsg, ...)
2113ef9cbf7Sgilles {
212be216e8fSeric va_list ap;
213be216e8fSeric
214be216e8fSeric va_start(ap, emsg);
215f24248b7Sreyk vfatalc(0, emsg, ap);
216be216e8fSeric va_end(ap);
217be216e8fSeric exit(1);
2183ef9cbf7Sgilles }
219