xref: /openbsd-src/usr.sbin/smtpd/log.c (revision 9b2c1562932ce8ef5a9c88720f87a65f2e0ed290)
1*9b2c1562Sbluhm /*	$OpenBSD: log.c,v 1.20 2017/03/21 12:06:56 bluhm Exp $	*/
23ef9cbf7Sgilles 
33ef9cbf7Sgilles /*
43ef9cbf7Sgilles  * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
53ef9cbf7Sgilles  *
63ef9cbf7Sgilles  * Permission to use, copy, modify, and distribute this software for any
73ef9cbf7Sgilles  * purpose with or without fee is hereby granted, provided that the above
83ef9cbf7Sgilles  * copyright notice and this permission notice appear in all copies.
93ef9cbf7Sgilles  *
103ef9cbf7Sgilles  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
113ef9cbf7Sgilles  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
123ef9cbf7Sgilles  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
133ef9cbf7Sgilles  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14f24248b7Sreyk  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15f24248b7Sreyk  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16f24248b7Sreyk  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
173ef9cbf7Sgilles  */
183ef9cbf7Sgilles 
193ef9cbf7Sgilles #include <stdio.h>
203ef9cbf7Sgilles #include <stdlib.h>
21f24248b7Sreyk #include <stdarg.h>
223ef9cbf7Sgilles #include <string.h>
233ef9cbf7Sgilles #include <syslog.h>
24f24248b7Sreyk #include <errno.h>
2544c6c770Schl #include <time.h>
263ef9cbf7Sgilles 
27871fc12cSreyk static int	 debug;
28871fc12cSreyk static int	 verbose;
29f24248b7Sreyk const char	*log_procname;
303ef9cbf7Sgilles 
31f24248b7Sreyk void	log_init(int, int);
32f24248b7Sreyk void	log_procinit(const char *);
33871fc12cSreyk void	log_setverbose(int);
34871fc12cSreyk int	log_getverbose(void);
35f24248b7Sreyk void	log_warn(const char *, ...)
36f24248b7Sreyk 	    __attribute__((__format__ (printf, 1, 2)));
37f24248b7Sreyk void	log_warnx(const char *, ...)
38f24248b7Sreyk 	    __attribute__((__format__ (printf, 1, 2)));
39f24248b7Sreyk void	log_info(const char *, ...)
40f24248b7Sreyk 	    __attribute__((__format__ (printf, 1, 2)));
41f24248b7Sreyk void	log_debug(const char *, ...)
42f24248b7Sreyk 	    __attribute__((__format__ (printf, 1, 2)));
43654fac80Scloder void	logit(int, const char *, ...)
44f24248b7Sreyk 	    __attribute__((__format__ (printf, 2, 3)));
45f24248b7Sreyk void	vlog(int, const char *, va_list)
46f24248b7Sreyk 	    __attribute__((__format__ (printf, 2, 0)));
47f24248b7Sreyk __dead void fatal(const char *, ...)
48f24248b7Sreyk 	    __attribute__((__format__ (printf, 1, 2)));
49f24248b7Sreyk __dead void fatalx(const char *, ...)
50f24248b7Sreyk 	    __attribute__((__format__ (printf, 1, 2)));
513ef9cbf7Sgilles 
523ef9cbf7Sgilles void
log_init(int n_debug,int facility)53f24248b7Sreyk log_init(int n_debug, int facility)
543ef9cbf7Sgilles {
553ef9cbf7Sgilles 	extern char	*__progname;
563ef9cbf7Sgilles 
57f24248b7Sreyk 	debug = n_debug;
58f24248b7Sreyk 	verbose = n_debug;
59f24248b7Sreyk 	log_procinit(__progname);
60f24248b7Sreyk 
61f24248b7Sreyk 	if (!debug)
62f24248b7Sreyk 		openlog(__progname, LOG_PID | LOG_NDELAY, facility);
633ef9cbf7Sgilles 
643ef9cbf7Sgilles 	tzset();
653ef9cbf7Sgilles }
663ef9cbf7Sgilles 
673ef9cbf7Sgilles void
log_procinit(const char * procname)68f24248b7Sreyk log_procinit(const char *procname)
69f24248b7Sreyk {
70f24248b7Sreyk 	if (procname != NULL)
71f24248b7Sreyk 		log_procname = procname;
72f24248b7Sreyk }
73f24248b7Sreyk 
74f24248b7Sreyk void
log_setverbose(int v)75871fc12cSreyk log_setverbose(int v)
76ba0c8f48Schl {
77ba0c8f48Schl 	verbose = v;
78ba0c8f48Schl }
79ba0c8f48Schl 
80871fc12cSreyk int
log_getverbose(void)81871fc12cSreyk log_getverbose(void)
82871fc12cSreyk {
83871fc12cSreyk 	return (verbose);
84871fc12cSreyk }
85871fc12cSreyk 
86ba0c8f48Schl void
logit(int pri,const char * fmt,...)873ef9cbf7Sgilles logit(int pri, const char *fmt, ...)
883ef9cbf7Sgilles {
893ef9cbf7Sgilles 	va_list	ap;
903ef9cbf7Sgilles 
913ef9cbf7Sgilles 	va_start(ap, fmt);
923ef9cbf7Sgilles 	vlog(pri, fmt, ap);
933ef9cbf7Sgilles 	va_end(ap);
943ef9cbf7Sgilles }
953ef9cbf7Sgilles 
963ef9cbf7Sgilles void
vlog(int pri,const char * fmt,va_list ap)973ef9cbf7Sgilles vlog(int pri, const char *fmt, va_list ap)
983ef9cbf7Sgilles {
993ef9cbf7Sgilles 	char	*nfmt;
100f24248b7Sreyk 	int	 saved_errno = errno;
1013ef9cbf7Sgilles 
102f24248b7Sreyk 	if (debug) {
1033ef9cbf7Sgilles 		/* best effort in out of mem situations */
1043ef9cbf7Sgilles 		if (asprintf(&nfmt, "%s\n", fmt) == -1) {
1053ef9cbf7Sgilles 			vfprintf(stderr, fmt, ap);
1063ef9cbf7Sgilles 			fprintf(stderr, "\n");
1073ef9cbf7Sgilles 		} else {
1083ef9cbf7Sgilles 			vfprintf(stderr, nfmt, ap);
1093ef9cbf7Sgilles 			free(nfmt);
1103ef9cbf7Sgilles 		}
1113ef9cbf7Sgilles 		fflush(stderr);
1123ef9cbf7Sgilles 	} else
1133ef9cbf7Sgilles 		vsyslog(pri, fmt, ap);
1143ef9cbf7Sgilles 
115f24248b7Sreyk 	errno = saved_errno;
116f24248b7Sreyk }
1173ef9cbf7Sgilles 
1183ef9cbf7Sgilles void
log_warn(const char * emsg,...)1193ef9cbf7Sgilles log_warn(const char *emsg, ...)
1203ef9cbf7Sgilles {
1213ef9cbf7Sgilles 	char		*nfmt;
1223ef9cbf7Sgilles 	va_list		 ap;
123f24248b7Sreyk 	int		 saved_errno = errno;
1243ef9cbf7Sgilles 
1253ef9cbf7Sgilles 	/* best effort to even work in out of memory situations */
1263ef9cbf7Sgilles 	if (emsg == NULL)
127*9b2c1562Sbluhm 		logit(LOG_ERR, "%s", strerror(saved_errno));
1283ef9cbf7Sgilles 	else {
1293ef9cbf7Sgilles 		va_start(ap, emsg);
1303ef9cbf7Sgilles 
131f24248b7Sreyk 		if (asprintf(&nfmt, "%s: %s", emsg,
132f24248b7Sreyk 		    strerror(saved_errno)) == -1) {
1333ef9cbf7Sgilles 			/* we tried it... */
134*9b2c1562Sbluhm 			vlog(LOG_ERR, emsg, ap);
135*9b2c1562Sbluhm 			logit(LOG_ERR, "%s", strerror(saved_errno));
1363ef9cbf7Sgilles 		} else {
137*9b2c1562Sbluhm 			vlog(LOG_ERR, nfmt, ap);
1383ef9cbf7Sgilles 			free(nfmt);
1393ef9cbf7Sgilles 		}
1403ef9cbf7Sgilles 		va_end(ap);
1413ef9cbf7Sgilles 	}
142f24248b7Sreyk 
143f24248b7Sreyk 	errno = saved_errno;
1443ef9cbf7Sgilles }
1453ef9cbf7Sgilles 
1463ef9cbf7Sgilles void
log_warnx(const char * emsg,...)1473ef9cbf7Sgilles log_warnx(const char *emsg, ...)
1483ef9cbf7Sgilles {
1493ef9cbf7Sgilles 	va_list	 ap;
1503ef9cbf7Sgilles 
1513ef9cbf7Sgilles 	va_start(ap, emsg);
152*9b2c1562Sbluhm 	vlog(LOG_ERR, emsg, ap);
1533ef9cbf7Sgilles 	va_end(ap);
1543ef9cbf7Sgilles }
1553ef9cbf7Sgilles 
1563ef9cbf7Sgilles void
log_info(const char * emsg,...)1573ef9cbf7Sgilles log_info(const char *emsg, ...)
1583ef9cbf7Sgilles {
1593ef9cbf7Sgilles 	va_list	 ap;
1603ef9cbf7Sgilles 
1613ef9cbf7Sgilles 	va_start(ap, emsg);
1623ef9cbf7Sgilles 	vlog(LOG_INFO, emsg, ap);
1633ef9cbf7Sgilles 	va_end(ap);
1643ef9cbf7Sgilles }
1653ef9cbf7Sgilles 
1663ef9cbf7Sgilles void
log_debug(const char * emsg,...)1673ef9cbf7Sgilles log_debug(const char *emsg, ...)
1683ef9cbf7Sgilles {
1693ef9cbf7Sgilles 	va_list	 ap;
1703ef9cbf7Sgilles 
171f24248b7Sreyk 	if (verbose > 1) {
172bfe8e0bcSeric 		va_start(ap, emsg);
173bfe8e0bcSeric 		vlog(LOG_DEBUG, emsg, ap);
174bfe8e0bcSeric 		va_end(ap);
175bfe8e0bcSeric 	}
176bfe8e0bcSeric }
177bfe8e0bcSeric 
178be216e8fSeric static void
vfatalc(int code,const char * emsg,va_list ap)179f24248b7Sreyk vfatalc(int code, const char *emsg, va_list ap)
1803ef9cbf7Sgilles {
181f24248b7Sreyk 	static char	s[BUFSIZ];
182f24248b7Sreyk 	const char	*sep;
1833ef9cbf7Sgilles 
184f24248b7Sreyk 	if (emsg != NULL) {
185f24248b7Sreyk 		(void)vsnprintf(s, sizeof(s), emsg, ap);
186f24248b7Sreyk 		sep = ": ";
187f24248b7Sreyk 	} else {
188f24248b7Sreyk 		s[0] = '\0';
189f24248b7Sreyk 		sep = "";
190be216e8fSeric 	}
191f24248b7Sreyk 	if (code)
192f24248b7Sreyk 		logit(LOG_CRIT, "%s: %s%s%s",
193f24248b7Sreyk 		    log_procname, s, sep, strerror(code));
194be216e8fSeric 	else
195f24248b7Sreyk 		logit(LOG_CRIT, "%s%s%s", log_procname, sep, s);
196be216e8fSeric }
197be216e8fSeric 
198be216e8fSeric void
fatal(const char * emsg,...)199be216e8fSeric fatal(const char *emsg, ...)
200be216e8fSeric {
201be216e8fSeric 	va_list	ap;
202be216e8fSeric 
203be216e8fSeric 	va_start(ap, emsg);
204f24248b7Sreyk 	vfatalc(errno, emsg, ap);
205be216e8fSeric 	va_end(ap);
2063ef9cbf7Sgilles 	exit(1);
2073ef9cbf7Sgilles }
2083ef9cbf7Sgilles 
2093ef9cbf7Sgilles void
fatalx(const char * emsg,...)210be216e8fSeric fatalx(const char *emsg, ...)
2113ef9cbf7Sgilles {
212be216e8fSeric 	va_list	ap;
213be216e8fSeric 
214be216e8fSeric 	va_start(ap, emsg);
215f24248b7Sreyk 	vfatalc(0, emsg, ap);
216be216e8fSeric 	va_end(ap);
217be216e8fSeric 	exit(1);
2183ef9cbf7Sgilles }
219