1*1454e1a7Sotto /* $OpenBSD: log.c,v 1.19 2019/07/03 05:04:19 otto Exp $ */
2914fd659Shenning
3914fd659Shenning /*
4914fd659Shenning * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
5914fd659Shenning *
6914fd659Shenning * Permission to use, copy, modify, and distribute this software for any
7914fd659Shenning * purpose with or without fee is hereby granted, provided that the above
8914fd659Shenning * copyright notice and this permission notice appear in all copies.
9914fd659Shenning *
10914fd659Shenning * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11914fd659Shenning * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12914fd659Shenning * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13914fd659Shenning * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14579813e4Sreyk * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15579813e4Sreyk * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16579813e4Sreyk * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17914fd659Shenning */
18914fd659Shenning
19914fd659Shenning #include <stdio.h>
20914fd659Shenning #include <stdlib.h>
21579813e4Sreyk #include <stdarg.h>
22914fd659Shenning #include <string.h>
23914fd659Shenning #include <syslog.h>
24579813e4Sreyk #include <errno.h>
251836f377Shenning #include <time.h>
268d2ac903Sotto #include "log.h"
27914fd659Shenning
288d2ac903Sotto static int dest;
29871fc12cSreyk static int verbose;
30579813e4Sreyk const char *log_procname;
31914fd659Shenning
32914fd659Shenning void
log_init(int n_dest,int n_verbose,int facility)338d2ac903Sotto log_init(int n_dest, int n_verbose, int facility)
34914fd659Shenning {
35914fd659Shenning extern char *__progname;
36914fd659Shenning
378d2ac903Sotto dest = n_dest;
388d2ac903Sotto verbose = n_verbose;
39579813e4Sreyk log_procinit(__progname);
40579813e4Sreyk
418d2ac903Sotto if (dest & LOG_TO_SYSLOG)
42579813e4Sreyk openlog(__progname, LOG_PID | LOG_NDELAY, facility);
431836f377Shenning
441836f377Shenning tzset();
45914fd659Shenning }
46914fd659Shenning
47914fd659Shenning void
log_procinit(const char * procname)48579813e4Sreyk log_procinit(const char *procname)
49579813e4Sreyk {
50579813e4Sreyk if (procname != NULL)
51579813e4Sreyk log_procname = procname;
52579813e4Sreyk }
53579813e4Sreyk
54579813e4Sreyk void
log_setverbose(int v)55871fc12cSreyk log_setverbose(int v)
5695ca2e79Sbcook {
5795ca2e79Sbcook verbose = v;
5895ca2e79Sbcook }
5995ca2e79Sbcook
60871fc12cSreyk int
log_getverbose(void)61871fc12cSreyk log_getverbose(void)
62871fc12cSreyk {
63871fc12cSreyk return (verbose);
64871fc12cSreyk }
65871fc12cSreyk
6695ca2e79Sbcook void
logit(int pri,const char * fmt,...)67914fd659Shenning logit(int pri, const char *fmt, ...)
68914fd659Shenning {
69914fd659Shenning va_list ap;
70914fd659Shenning
71914fd659Shenning va_start(ap, fmt);
72914fd659Shenning vlog(pri, fmt, ap);
73914fd659Shenning va_end(ap);
74914fd659Shenning }
75914fd659Shenning
76914fd659Shenning void
vlog(int pri,const char * fmt,va_list ap)77914fd659Shenning vlog(int pri, const char *fmt, va_list ap)
78914fd659Shenning {
79914fd659Shenning char *nfmt;
809f5ef5a9Sreyk int saved_errno = errno;
81*1454e1a7Sotto va_list ap2;
82914fd659Shenning
83*1454e1a7Sotto va_copy(ap2, ap);
848d2ac903Sotto if (dest & LOG_TO_STDERR) {
85914fd659Shenning /* best effort in out of mem situations */
86914fd659Shenning if (asprintf(&nfmt, "%s\n", fmt) == -1) {
87914fd659Shenning vfprintf(stderr, fmt, ap);
88914fd659Shenning fprintf(stderr, "\n");
89914fd659Shenning } else {
90914fd659Shenning vfprintf(stderr, nfmt, ap);
91914fd659Shenning free(nfmt);
92914fd659Shenning }
93914fd659Shenning fflush(stderr);
948d2ac903Sotto }
958d2ac903Sotto if (dest & LOG_TO_SYSLOG)
96*1454e1a7Sotto vsyslog(pri, fmt, ap2);
97*1454e1a7Sotto va_end(ap2);
98914fd659Shenning
999f5ef5a9Sreyk errno = saved_errno;
1009f5ef5a9Sreyk }
101914fd659Shenning
102914fd659Shenning void
log_warn(const char * emsg,...)103914fd659Shenning log_warn(const char *emsg, ...)
104914fd659Shenning {
105914fd659Shenning char *nfmt;
106914fd659Shenning va_list ap;
107a6bfe157Sreyk int saved_errno = errno;
108914fd659Shenning
109914fd659Shenning /* best effort to even work in out of memory situations */
110914fd659Shenning if (emsg == NULL)
1119b2c1562Sbluhm logit(LOG_ERR, "%s", strerror(saved_errno));
112914fd659Shenning else {
113914fd659Shenning va_start(ap, emsg);
114914fd659Shenning
115a6bfe157Sreyk if (asprintf(&nfmt, "%s: %s", emsg,
116a6bfe157Sreyk strerror(saved_errno)) == -1) {
117914fd659Shenning /* we tried it... */
1189b2c1562Sbluhm vlog(LOG_ERR, emsg, ap);
1199b2c1562Sbluhm logit(LOG_ERR, "%s", strerror(saved_errno));
120914fd659Shenning } else {
1219b2c1562Sbluhm vlog(LOG_ERR, nfmt, ap);
122914fd659Shenning free(nfmt);
123914fd659Shenning }
124914fd659Shenning va_end(ap);
125914fd659Shenning }
1269f5ef5a9Sreyk
1279f5ef5a9Sreyk errno = saved_errno;
128914fd659Shenning }
129914fd659Shenning
130914fd659Shenning void
log_warnx(const char * emsg,...)131914fd659Shenning log_warnx(const char *emsg, ...)
132914fd659Shenning {
133914fd659Shenning va_list ap;
134914fd659Shenning
135914fd659Shenning va_start(ap, emsg);
1369b2c1562Sbluhm vlog(LOG_ERR, emsg, ap);
137914fd659Shenning va_end(ap);
138914fd659Shenning }
139914fd659Shenning
140914fd659Shenning void
log_info(const char * emsg,...)141914fd659Shenning log_info(const char *emsg, ...)
142914fd659Shenning {
143914fd659Shenning va_list ap;
144914fd659Shenning
145914fd659Shenning va_start(ap, emsg);
146914fd659Shenning vlog(LOG_INFO, emsg, ap);
147914fd659Shenning va_end(ap);
148914fd659Shenning }
149914fd659Shenning
150914fd659Shenning void
log_debug(const char * emsg,...)151914fd659Shenning log_debug(const char *emsg, ...)
152914fd659Shenning {
153914fd659Shenning va_list ap;
154914fd659Shenning
155579813e4Sreyk if (verbose > 1) {
15695ca2e79Sbcook va_start(ap, emsg);
15795ca2e79Sbcook vlog(LOG_DEBUG, emsg, ap);
15895ca2e79Sbcook va_end(ap);
15995ca2e79Sbcook }
16095ca2e79Sbcook }
16195ca2e79Sbcook
16295ca2e79Sbcook static void
vfatalc(int code,const char * emsg,va_list ap)1639f5ef5a9Sreyk vfatalc(int code, const char *emsg, va_list ap)
16495ca2e79Sbcook {
165579813e4Sreyk static char s[BUFSIZ];
166579813e4Sreyk const char *sep;
16795ca2e79Sbcook
168579813e4Sreyk if (emsg != NULL) {
169579813e4Sreyk (void)vsnprintf(s, sizeof(s), emsg, ap);
170579813e4Sreyk sep = ": ";
171579813e4Sreyk } else {
172579813e4Sreyk s[0] = '\0';
173579813e4Sreyk sep = "";
17495ca2e79Sbcook }
1759f5ef5a9Sreyk if (code)
176579813e4Sreyk logit(LOG_CRIT, "%s: %s%s%s",
1779f5ef5a9Sreyk log_procname, s, sep, strerror(code));
17895ca2e79Sbcook else
179579813e4Sreyk logit(LOG_CRIT, "%s%s%s", log_procname, sep, s);
18095ca2e79Sbcook }
18195ca2e79Sbcook
18295ca2e79Sbcook void
fatal(const char * emsg,...)18395ca2e79Sbcook fatal(const char *emsg, ...)
18495ca2e79Sbcook {
18595ca2e79Sbcook va_list ap;
18695ca2e79Sbcook
18795ca2e79Sbcook va_start(ap, emsg);
1889f5ef5a9Sreyk vfatalc(errno, emsg, ap);
18995ca2e79Sbcook va_end(ap);
190914fd659Shenning exit(1);
191914fd659Shenning }
192914fd659Shenning
193914fd659Shenning void
fatalx(const char * emsg,...)19495ca2e79Sbcook fatalx(const char *emsg, ...)
195914fd659Shenning {
19695ca2e79Sbcook va_list ap;
19795ca2e79Sbcook
19895ca2e79Sbcook va_start(ap, emsg);
1999f5ef5a9Sreyk vfatalc(0, emsg, ap);
20095ca2e79Sbcook va_end(ap);
20195ca2e79Sbcook exit(1);
202914fd659Shenning }
203