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