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