1*9b2c1562Sbluhm /* $OpenBSD: log.c,v 1.64 2017/03/21 12:06:55 bluhm Exp $ */
2a16c0992Shenning
3a16c0992Shenning /*
4050527e1Shenning * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
5a16c0992Shenning *
6a16c0992Shenning * Permission to use, copy, modify, and distribute this software for any
7a16c0992Shenning * purpose with or without fee is hereby granted, provided that the above
8a16c0992Shenning * copyright notice and this permission notice appear in all copies.
9a16c0992Shenning *
10a16c0992Shenning * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11a16c0992Shenning * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12a16c0992Shenning * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13a16c0992Shenning * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14a16c0992Shenning * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15a16c0992Shenning * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16a16c0992Shenning * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17a16c0992Shenning */
18a16c0992Shenning
19a16c0992Shenning #include <stdio.h>
20a16c0992Shenning #include <stdlib.h>
215e3f6f95Sbenno #include <stdarg.h>
22a16c0992Shenning #include <string.h>
23ea8300d4Shenning #include <syslog.h>
245e3f6f95Sbenno #include <errno.h>
2514359072Shenning #include <time.h>
26a16c0992Shenning
27bea482a9Shenning #include "log.h"
28a16c0992Shenning
295e3f6f95Sbenno static int debug;
305e3f6f95Sbenno static int verbose;
315e3f6f95Sbenno static const char *log_procname;
32a16c0992Shenning
33a16c0992Shenning void
log_init(int n_debug,int facility)345e3f6f95Sbenno log_init(int n_debug, int facility)
35a16c0992Shenning {
365ed087acShenning extern char *__progname;
375ed087acShenning
38a16c0992Shenning debug = n_debug;
395e3f6f95Sbenno verbose = n_debug;
405e3f6f95Sbenno log_procinit(__progname);
41a16c0992Shenning
42a16c0992Shenning if (!debug)
435e3f6f95Sbenno openlog(__progname, LOG_PID | LOG_NDELAY, facility);
4414359072Shenning
4514359072Shenning tzset();
46a16c0992Shenning }
47a16c0992Shenning
48a16c0992Shenning void
log_procinit(const char * procname)495e3f6f95Sbenno log_procinit(const char *procname)
505e3f6f95Sbenno {
515e3f6f95Sbenno if (procname != NULL)
525e3f6f95Sbenno log_procname = procname;
535e3f6f95Sbenno }
545e3f6f95Sbenno
555e3f6f95Sbenno void
log_setverbose(int v)565e3f6f95Sbenno log_setverbose(int v)
57d6b35cfbSclaudio {
58d6b35cfbSclaudio verbose = v;
59d6b35cfbSclaudio }
60d6b35cfbSclaudio
615e3f6f95Sbenno int
log_getverbose(void)625e3f6f95Sbenno log_getverbose(void)
635e3f6f95Sbenno {
645e3f6f95Sbenno return (verbose);
655e3f6f95Sbenno }
665e3f6f95Sbenno
67d6b35cfbSclaudio void
logit(int pri,const char * fmt,...)68a16c0992Shenning logit(int pri, const char *fmt, ...)
69a16c0992Shenning {
70a16c0992Shenning va_list ap;
71a16c0992Shenning
72a16c0992Shenning va_start(ap, fmt);
73a16c0992Shenning vlog(pri, fmt, ap);
74a16c0992Shenning va_end(ap);
75a16c0992Shenning }
76a16c0992Shenning
77a16c0992Shenning void
vlog(int pri,const char * fmt,va_list ap)78a16c0992Shenning vlog(int pri, const char *fmt, va_list ap)
79a16c0992Shenning {
801f975a75Shenning char *nfmt;
815e3f6f95Sbenno int saved_errno = errno;
821f975a75Shenning
83a16c0992Shenning if (debug) {
841f975a75Shenning /* best effort in out of mem situations */
851f975a75Shenning if (asprintf(&nfmt, "%s\n", fmt) == -1) {
86a16c0992Shenning vfprintf(stderr, fmt, ap);
87a16c0992Shenning fprintf(stderr, "\n");
881f975a75Shenning } else {
891f975a75Shenning vfprintf(stderr, nfmt, ap);
901f975a75Shenning free(nfmt);
911f975a75Shenning }
92ede7e4feShenning fflush(stderr);
93a16c0992Shenning } else
94a16c0992Shenning vsyslog(pri, fmt, ap);
955e3f6f95Sbenno
965e3f6f95Sbenno errno = saved_errno;
97a16c0992Shenning }
98a16c0992Shenning
99a16c0992Shenning void
log_warn(const char * emsg,...)1008013a801Shenning log_warn(const char *emsg, ...)
101c3187f2eShenning {
102c3187f2eShenning char *nfmt;
103c3187f2eShenning va_list ap;
1045e3f6f95Sbenno int saved_errno = errno;
105c3187f2eShenning
106c3187f2eShenning /* best effort to even work in out of memory situations */
107c3187f2eShenning if (emsg == NULL)
108*9b2c1562Sbluhm logit(LOG_ERR, "%s", strerror(saved_errno));
109c3187f2eShenning else {
1105336afd4Shenning va_start(ap, emsg);
1115336afd4Shenning
1125e3f6f95Sbenno if (asprintf(&nfmt, "%s: %s", emsg,
1135e3f6f95Sbenno strerror(saved_errno)) == -1) {
114c3187f2eShenning /* we tried it... */
115*9b2c1562Sbluhm vlog(LOG_ERR, emsg, ap);
116*9b2c1562Sbluhm logit(LOG_ERR, "%s", strerror(saved_errno));
1175336afd4Shenning } else {
118*9b2c1562Sbluhm vlog(LOG_ERR, nfmt, ap);
1195336afd4Shenning free(nfmt);
120c3187f2eShenning }
121c3187f2eShenning va_end(ap);
122c3187f2eShenning }
1235e3f6f95Sbenno
1245e3f6f95Sbenno errno = saved_errno;
1255336afd4Shenning }
126c3187f2eShenning
127c3187f2eShenning void
log_warnx(const char * emsg,...)128364326eeShenning log_warnx(const char *emsg, ...)
129364326eeShenning {
130364326eeShenning va_list ap;
131364326eeShenning
132364326eeShenning va_start(ap, emsg);
133*9b2c1562Sbluhm vlog(LOG_ERR, emsg, ap);
134364326eeShenning va_end(ap);
135364326eeShenning }
136364326eeShenning
137364326eeShenning void
log_info(const char * emsg,...)138364326eeShenning log_info(const char *emsg, ...)
139364326eeShenning {
140364326eeShenning va_list ap;
141364326eeShenning
142364326eeShenning va_start(ap, emsg);
143364326eeShenning vlog(LOG_INFO, emsg, ap);
144364326eeShenning va_end(ap);
145364326eeShenning }
146364326eeShenning
147364326eeShenning void
log_debug(const char * emsg,...)148ea8300d4Shenning log_debug(const char *emsg, ...)
149ea8300d4Shenning {
150ea8300d4Shenning va_list ap;
151ea8300d4Shenning
152d6b35cfbSclaudio if (verbose) {
153ea8300d4Shenning va_start(ap, emsg);
154ea8300d4Shenning vlog(LOG_DEBUG, emsg, ap);
155ea8300d4Shenning va_end(ap);
156ea8300d4Shenning }
1574b69215fShenning }
158ea8300d4Shenning
1595e3f6f95Sbenno static void
vfatalc(int code,const char * emsg,va_list ap)1605e3f6f95Sbenno vfatalc(int code, const char *emsg, va_list ap)
1615e3f6f95Sbenno {
1625e3f6f95Sbenno static char s[BUFSIZ];
1635e3f6f95Sbenno const char *sep;
1645e3f6f95Sbenno
1655e3f6f95Sbenno if (emsg != NULL) {
1665e3f6f95Sbenno (void)vsnprintf(s, sizeof(s), emsg, ap);
1675e3f6f95Sbenno sep = ": ";
1685e3f6f95Sbenno } else {
1695e3f6f95Sbenno s[0] = '\0';
1705e3f6f95Sbenno sep = "";
1715e3f6f95Sbenno }
1725e3f6f95Sbenno if (code)
1735e3f6f95Sbenno logit(LOG_CRIT, "fatal in %s: %s%s%s",
1745e3f6f95Sbenno log_procname, s, sep, strerror(code));
1755e3f6f95Sbenno else
1765e3f6f95Sbenno logit(LOG_CRIT, "fatal in %s%s%s", log_procname, sep, s);
1775e3f6f95Sbenno }
1785e3f6f95Sbenno
179ea8300d4Shenning void
fatal(const char * emsg,...)18049db16b7Sbenno fatal(const char *emsg, ...)
181a16c0992Shenning {
18249db16b7Sbenno va_list ap;
18349db16b7Sbenno
18449db16b7Sbenno va_start(ap, emsg);
1855e3f6f95Sbenno vfatalc(errno, emsg, ap);
18649db16b7Sbenno va_end(ap);
1872e09f5e3Shenning exit(1);
188a16c0992Shenning }
189a16c0992Shenning
190a16c0992Shenning void
fatalx(const char * emsg,...)1915e3f6f95Sbenno fatalx(const char *emsg, ...)
192f87a5020Shenning {
1935e3f6f95Sbenno va_list ap;
1945e3f6f95Sbenno
1955e3f6f95Sbenno va_start(ap, emsg);
1965e3f6f95Sbenno vfatalc(0, emsg, ap);
1975e3f6f95Sbenno va_end(ap);
1985e3f6f95Sbenno exit(1);
199f87a5020Shenning }
200