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