xref: /freebsd/sbin/hastd/pjdlog.c (revision e3031161eb793252cee9eff1da883e6baeb6567f)
132115b10SPawel Jakub Dawidek /*-
232115b10SPawel Jakub Dawidek  * Copyright (c) 2009-2010 The FreeBSD Foundation
332115b10SPawel Jakub Dawidek  * All rights reserved.
432115b10SPawel Jakub Dawidek  *
532115b10SPawel Jakub Dawidek  * This software was developed by Pawel Jakub Dawidek under sponsorship from
632115b10SPawel Jakub Dawidek  * the FreeBSD Foundation.
732115b10SPawel Jakub Dawidek  *
832115b10SPawel Jakub Dawidek  * Redistribution and use in source and binary forms, with or without
932115b10SPawel Jakub Dawidek  * modification, are permitted provided that the following conditions
1032115b10SPawel Jakub Dawidek  * are met:
1132115b10SPawel Jakub Dawidek  * 1. Redistributions of source code must retain the above copyright
1232115b10SPawel Jakub Dawidek  *    notice, this list of conditions and the following disclaimer.
1332115b10SPawel Jakub Dawidek  * 2. Redistributions in binary form must reproduce the above copyright
1432115b10SPawel Jakub Dawidek  *    notice, this list of conditions and the following disclaimer in the
1532115b10SPawel Jakub Dawidek  *    documentation and/or other materials provided with the distribution.
1632115b10SPawel Jakub Dawidek  *
1732115b10SPawel Jakub Dawidek  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
1832115b10SPawel Jakub Dawidek  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1932115b10SPawel Jakub Dawidek  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2032115b10SPawel Jakub Dawidek  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
2132115b10SPawel Jakub Dawidek  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2232115b10SPawel Jakub Dawidek  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2332115b10SPawel Jakub Dawidek  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2432115b10SPawel Jakub Dawidek  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2532115b10SPawel Jakub Dawidek  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2632115b10SPawel Jakub Dawidek  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2732115b10SPawel Jakub Dawidek  * SUCH DAMAGE.
2832115b10SPawel Jakub Dawidek  *
2932115b10SPawel Jakub Dawidek  * $FreeBSD$
3032115b10SPawel Jakub Dawidek  */
3132115b10SPawel Jakub Dawidek 
3232115b10SPawel Jakub Dawidek #include <sys/cdefs.h>
3332115b10SPawel Jakub Dawidek __FBSDID("$FreeBSD$");
3432115b10SPawel Jakub Dawidek 
3532115b10SPawel Jakub Dawidek #include <assert.h>
3632115b10SPawel Jakub Dawidek #include <errno.h>
3732115b10SPawel Jakub Dawidek #include <stdarg.h>
3832115b10SPawel Jakub Dawidek #include <stdio.h>
3932115b10SPawel Jakub Dawidek #include <stdlib.h>
4032115b10SPawel Jakub Dawidek #include <string.h>
4132115b10SPawel Jakub Dawidek #include <syslog.h>
4232115b10SPawel Jakub Dawidek 
4332115b10SPawel Jakub Dawidek #include "pjdlog.h"
4432115b10SPawel Jakub Dawidek 
4532115b10SPawel Jakub Dawidek static int pjdlog_mode = PJDLOG_MODE_STD;
4632115b10SPawel Jakub Dawidek static int pjdlog_debug_level = 0;
4732115b10SPawel Jakub Dawidek static char pjdlog_prefix[128];
4832115b10SPawel Jakub Dawidek 
4932115b10SPawel Jakub Dawidek /*
5032115b10SPawel Jakub Dawidek  * Configure where the logs should go.
5132115b10SPawel Jakub Dawidek  * By default they are send to stdout/stderr, but after going into background
5232115b10SPawel Jakub Dawidek  * (eg. by calling daemon(3)) application is responsible for changing mode to
5332115b10SPawel Jakub Dawidek  * PJDLOG_MODE_SYSLOG, so logs will be send to syslog.
5432115b10SPawel Jakub Dawidek  */
5532115b10SPawel Jakub Dawidek void
5632115b10SPawel Jakub Dawidek pjdlog_mode_set(int mode)
5732115b10SPawel Jakub Dawidek {
5832115b10SPawel Jakub Dawidek 
5932115b10SPawel Jakub Dawidek 	assert(mode == PJDLOG_MODE_STD || mode == PJDLOG_MODE_SYSLOG);
6032115b10SPawel Jakub Dawidek 
6132115b10SPawel Jakub Dawidek 	pjdlog_mode = mode;
6232115b10SPawel Jakub Dawidek }
6332115b10SPawel Jakub Dawidek 
6432115b10SPawel Jakub Dawidek /*
6532115b10SPawel Jakub Dawidek  * Return current mode.
6632115b10SPawel Jakub Dawidek  */
6732115b10SPawel Jakub Dawidek int
6832115b10SPawel Jakub Dawidek pjdlog_mode_get(void)
6932115b10SPawel Jakub Dawidek {
7032115b10SPawel Jakub Dawidek 
7132115b10SPawel Jakub Dawidek 	return (pjdlog_mode);
7232115b10SPawel Jakub Dawidek }
7332115b10SPawel Jakub Dawidek 
7432115b10SPawel Jakub Dawidek /*
7532115b10SPawel Jakub Dawidek  * Set debug level. All the logs above the level specified here will be
7632115b10SPawel Jakub Dawidek  * ignored.
7732115b10SPawel Jakub Dawidek  */
7832115b10SPawel Jakub Dawidek void
7932115b10SPawel Jakub Dawidek pjdlog_debug_set(int level)
8032115b10SPawel Jakub Dawidek {
8132115b10SPawel Jakub Dawidek 
8232115b10SPawel Jakub Dawidek 	assert(level >= 0);
8332115b10SPawel Jakub Dawidek 
8432115b10SPawel Jakub Dawidek 	pjdlog_debug_level = level;
8532115b10SPawel Jakub Dawidek }
8632115b10SPawel Jakub Dawidek 
8732115b10SPawel Jakub Dawidek /*
8832115b10SPawel Jakub Dawidek  * Return current debug level.
8932115b10SPawel Jakub Dawidek  */
9032115b10SPawel Jakub Dawidek int
9132115b10SPawel Jakub Dawidek pjdlog_debug_get(void)
9232115b10SPawel Jakub Dawidek {
9332115b10SPawel Jakub Dawidek 
9432115b10SPawel Jakub Dawidek 	return (pjdlog_debug_level);
9532115b10SPawel Jakub Dawidek }
9632115b10SPawel Jakub Dawidek 
9732115b10SPawel Jakub Dawidek /*
9832115b10SPawel Jakub Dawidek  * Set prefix that will be used before each log.
9932115b10SPawel Jakub Dawidek  * Setting prefix to NULL will remove it.
10032115b10SPawel Jakub Dawidek  */
10132115b10SPawel Jakub Dawidek void
10232115b10SPawel Jakub Dawidek pjdlog_prefix_set(const char *fmt, ...)
10332115b10SPawel Jakub Dawidek {
10432115b10SPawel Jakub Dawidek 	va_list ap;
10532115b10SPawel Jakub Dawidek 
10632115b10SPawel Jakub Dawidek 	va_start(ap, fmt);
10732115b10SPawel Jakub Dawidek 	pjdlog_prefix_setv(fmt, ap);
10832115b10SPawel Jakub Dawidek 	va_end(ap);
10932115b10SPawel Jakub Dawidek }
11032115b10SPawel Jakub Dawidek 
11132115b10SPawel Jakub Dawidek /*
11232115b10SPawel Jakub Dawidek  * Set prefix that will be used before each log.
11332115b10SPawel Jakub Dawidek  * Setting prefix to NULL will remove it.
11432115b10SPawel Jakub Dawidek  */
11532115b10SPawel Jakub Dawidek void
11632115b10SPawel Jakub Dawidek pjdlog_prefix_setv(const char *fmt, va_list ap)
11732115b10SPawel Jakub Dawidek {
11832115b10SPawel Jakub Dawidek 
11932115b10SPawel Jakub Dawidek 	assert(fmt != NULL);
12032115b10SPawel Jakub Dawidek 
12132115b10SPawel Jakub Dawidek 	vsnprintf(pjdlog_prefix, sizeof(pjdlog_prefix), fmt, ap);
12232115b10SPawel Jakub Dawidek }
12332115b10SPawel Jakub Dawidek 
12432115b10SPawel Jakub Dawidek /*
12532115b10SPawel Jakub Dawidek  * Convert log level into string.
12632115b10SPawel Jakub Dawidek  */
12732115b10SPawel Jakub Dawidek static const char *
12832115b10SPawel Jakub Dawidek pjdlog_level_string(int loglevel)
12932115b10SPawel Jakub Dawidek {
13032115b10SPawel Jakub Dawidek 
13132115b10SPawel Jakub Dawidek 	switch (loglevel) {
13232115b10SPawel Jakub Dawidek 	case LOG_EMERG:
13332115b10SPawel Jakub Dawidek 		return ("EMERG");
13432115b10SPawel Jakub Dawidek 	case LOG_ALERT:
13532115b10SPawel Jakub Dawidek 		return ("ALERT");
13632115b10SPawel Jakub Dawidek 	case LOG_CRIT:
13732115b10SPawel Jakub Dawidek 		return ("CRIT");
13832115b10SPawel Jakub Dawidek 	case LOG_ERR:
13932115b10SPawel Jakub Dawidek 		return ("ERROR");
14032115b10SPawel Jakub Dawidek 	case LOG_WARNING:
14132115b10SPawel Jakub Dawidek 		return ("WARNING");
14232115b10SPawel Jakub Dawidek 	case LOG_NOTICE:
14332115b10SPawel Jakub Dawidek 		return ("NOTICE");
14432115b10SPawel Jakub Dawidek 	case LOG_INFO:
14532115b10SPawel Jakub Dawidek 		return ("INFO");
14632115b10SPawel Jakub Dawidek 	case LOG_DEBUG:
14732115b10SPawel Jakub Dawidek 		return ("DEBUG");
14832115b10SPawel Jakub Dawidek 	}
14932115b10SPawel Jakub Dawidek 	assert(!"Invalid log level.");
15032115b10SPawel Jakub Dawidek 	abort();	/* XXX: gcc */
15132115b10SPawel Jakub Dawidek }
15232115b10SPawel Jakub Dawidek 
15332115b10SPawel Jakub Dawidek /*
15432115b10SPawel Jakub Dawidek  * Common log routine.
15532115b10SPawel Jakub Dawidek  */
15632115b10SPawel Jakub Dawidek void
15732115b10SPawel Jakub Dawidek pjdlog_common(int loglevel, int debuglevel, int error, const char *fmt, ...)
15832115b10SPawel Jakub Dawidek {
15932115b10SPawel Jakub Dawidek 	va_list ap;
16032115b10SPawel Jakub Dawidek 
16132115b10SPawel Jakub Dawidek 	va_start(ap, fmt);
16232115b10SPawel Jakub Dawidek 	pjdlogv_common(loglevel, debuglevel, error, fmt, ap);
16332115b10SPawel Jakub Dawidek 	va_end(ap);
16432115b10SPawel Jakub Dawidek }
16532115b10SPawel Jakub Dawidek 
16632115b10SPawel Jakub Dawidek /*
16732115b10SPawel Jakub Dawidek  * Common log routine, which can handle regular log level as well as debug
16832115b10SPawel Jakub Dawidek  * level. We decide here where to send the logs (stdout/stderr or syslog).
16932115b10SPawel Jakub Dawidek  */
17032115b10SPawel Jakub Dawidek void
17132115b10SPawel Jakub Dawidek pjdlogv_common(int loglevel, int debuglevel, int error, const char *fmt,
17232115b10SPawel Jakub Dawidek     va_list ap)
17332115b10SPawel Jakub Dawidek {
17432115b10SPawel Jakub Dawidek 
17532115b10SPawel Jakub Dawidek 	assert(loglevel == LOG_EMERG || loglevel == LOG_ALERT ||
17632115b10SPawel Jakub Dawidek 	    loglevel == LOG_CRIT || loglevel == LOG_ERR ||
17732115b10SPawel Jakub Dawidek 	    loglevel == LOG_WARNING || loglevel == LOG_NOTICE ||
17832115b10SPawel Jakub Dawidek 	    loglevel == LOG_INFO || loglevel == LOG_DEBUG);
17932115b10SPawel Jakub Dawidek 	assert(loglevel != LOG_DEBUG || debuglevel > 0);
18032115b10SPawel Jakub Dawidek 	assert(error >= -1);
18132115b10SPawel Jakub Dawidek 
18232115b10SPawel Jakub Dawidek 	/* Ignore debug above configured level. */
18332115b10SPawel Jakub Dawidek 	if (loglevel == LOG_DEBUG && debuglevel > pjdlog_debug_level)
18432115b10SPawel Jakub Dawidek 		return;
18532115b10SPawel Jakub Dawidek 
18632115b10SPawel Jakub Dawidek 	switch (pjdlog_mode) {
18732115b10SPawel Jakub Dawidek 	case PJDLOG_MODE_STD:
18832115b10SPawel Jakub Dawidek 	    {
18932115b10SPawel Jakub Dawidek 		FILE *out;
19032115b10SPawel Jakub Dawidek 
19132115b10SPawel Jakub Dawidek 		/*
19232115b10SPawel Jakub Dawidek 		 * We send errors and warning to stderr and the rest to stdout.
19332115b10SPawel Jakub Dawidek 		 */
19432115b10SPawel Jakub Dawidek 		switch (loglevel) {
19532115b10SPawel Jakub Dawidek 		case LOG_EMERG:
19632115b10SPawel Jakub Dawidek 		case LOG_ALERT:
19732115b10SPawel Jakub Dawidek 		case LOG_CRIT:
19832115b10SPawel Jakub Dawidek 		case LOG_ERR:
19932115b10SPawel Jakub Dawidek 		case LOG_WARNING:
20032115b10SPawel Jakub Dawidek 			out = stderr;
20132115b10SPawel Jakub Dawidek 			break;
20232115b10SPawel Jakub Dawidek 		case LOG_NOTICE:
20332115b10SPawel Jakub Dawidek 		case LOG_INFO:
20432115b10SPawel Jakub Dawidek 		case LOG_DEBUG:
20532115b10SPawel Jakub Dawidek 			out = stdout;
20632115b10SPawel Jakub Dawidek 			break;
20732115b10SPawel Jakub Dawidek 		default:
20832115b10SPawel Jakub Dawidek 			assert(!"Invalid loglevel.");
20932115b10SPawel Jakub Dawidek 			abort();	/* XXX: gcc */
21032115b10SPawel Jakub Dawidek 		}
21132115b10SPawel Jakub Dawidek 
21232115b10SPawel Jakub Dawidek 		fprintf(out, "[%s]", pjdlog_level_string(loglevel));
21332115b10SPawel Jakub Dawidek 		/* Attach debuglevel if this is debug log. */
21432115b10SPawel Jakub Dawidek 		if (loglevel == LOG_DEBUG)
21532115b10SPawel Jakub Dawidek 			fprintf(out, "[%d]", debuglevel);
21632115b10SPawel Jakub Dawidek 		fprintf(out, " ");
21732115b10SPawel Jakub Dawidek 		fprintf(out, "%s", pjdlog_prefix);
21832115b10SPawel Jakub Dawidek 		vfprintf(out, fmt, ap);
21932115b10SPawel Jakub Dawidek 		if (error != -1)
22032115b10SPawel Jakub Dawidek 			fprintf(out, ": %s.", strerror(error));
22132115b10SPawel Jakub Dawidek 		fprintf(out, "\n");
22232115b10SPawel Jakub Dawidek 		break;
22332115b10SPawel Jakub Dawidek 	    }
22432115b10SPawel Jakub Dawidek 	case PJDLOG_MODE_SYSLOG:
22532115b10SPawel Jakub Dawidek 	    {
22632115b10SPawel Jakub Dawidek 		char log[1024];
22732115b10SPawel Jakub Dawidek 		int len;
22832115b10SPawel Jakub Dawidek 
22932115b10SPawel Jakub Dawidek 		len = snprintf(log, sizeof(log), "%s", pjdlog_prefix);
23032115b10SPawel Jakub Dawidek 		if ((size_t)len < sizeof(log))
23120ec52dcSPawel Jakub Dawidek 			len += vsnprintf(log + len, sizeof(log) - len, fmt, ap);
23232115b10SPawel Jakub Dawidek 		if (error != -1 && (size_t)len < sizeof(log)) {
23332115b10SPawel Jakub Dawidek 			(void)snprintf(log + len, sizeof(log) - len, ": %s.",
23432115b10SPawel Jakub Dawidek 			    strerror(error));
23532115b10SPawel Jakub Dawidek 		}
23632115b10SPawel Jakub Dawidek 		syslog(loglevel, "%s", log);
23732115b10SPawel Jakub Dawidek 		break;
23832115b10SPawel Jakub Dawidek 	    }
23932115b10SPawel Jakub Dawidek 	default:
24032115b10SPawel Jakub Dawidek 		assert(!"Invalid mode.");
24132115b10SPawel Jakub Dawidek 	}
24232115b10SPawel Jakub Dawidek }
24332115b10SPawel Jakub Dawidek 
24432115b10SPawel Jakub Dawidek /*
24532115b10SPawel Jakub Dawidek  * Regular logs.
24632115b10SPawel Jakub Dawidek  */
24732115b10SPawel Jakub Dawidek void
24832115b10SPawel Jakub Dawidek pjdlogv(int loglevel, const char *fmt, va_list ap)
24932115b10SPawel Jakub Dawidek {
25032115b10SPawel Jakub Dawidek 
25132115b10SPawel Jakub Dawidek 	/* LOG_DEBUG is invalid here, pjdlogv?_debug() should be used. */
25232115b10SPawel Jakub Dawidek 	assert(loglevel == LOG_EMERG || loglevel == LOG_ALERT ||
25332115b10SPawel Jakub Dawidek 	    loglevel == LOG_CRIT || loglevel == LOG_ERR ||
25432115b10SPawel Jakub Dawidek 	    loglevel == LOG_WARNING || loglevel == LOG_NOTICE ||
25532115b10SPawel Jakub Dawidek 	    loglevel == LOG_INFO);
25632115b10SPawel Jakub Dawidek 
25732115b10SPawel Jakub Dawidek 	pjdlogv_common(loglevel, 0, -1, fmt, ap);
25832115b10SPawel Jakub Dawidek }
25932115b10SPawel Jakub Dawidek 
26032115b10SPawel Jakub Dawidek /*
26132115b10SPawel Jakub Dawidek  * Regular logs.
26232115b10SPawel Jakub Dawidek  */
26332115b10SPawel Jakub Dawidek void
26432115b10SPawel Jakub Dawidek pjdlog(int loglevel, const char *fmt, ...)
26532115b10SPawel Jakub Dawidek {
26632115b10SPawel Jakub Dawidek 	va_list ap;
26732115b10SPawel Jakub Dawidek 
26832115b10SPawel Jakub Dawidek 	va_start(ap, fmt);
26932115b10SPawel Jakub Dawidek 	pjdlogv(loglevel, fmt, ap);
27032115b10SPawel Jakub Dawidek 	va_end(ap);
27132115b10SPawel Jakub Dawidek }
27232115b10SPawel Jakub Dawidek 
27332115b10SPawel Jakub Dawidek /*
27432115b10SPawel Jakub Dawidek  * Debug logs.
27532115b10SPawel Jakub Dawidek  */
27632115b10SPawel Jakub Dawidek void
27732115b10SPawel Jakub Dawidek pjdlogv_debug(int debuglevel, const char *fmt, va_list ap)
27832115b10SPawel Jakub Dawidek {
27932115b10SPawel Jakub Dawidek 
28032115b10SPawel Jakub Dawidek 	pjdlogv_common(LOG_DEBUG, debuglevel, -1, fmt, ap);
28132115b10SPawel Jakub Dawidek }
28232115b10SPawel Jakub Dawidek 
28332115b10SPawel Jakub Dawidek /*
28432115b10SPawel Jakub Dawidek  * Debug logs.
28532115b10SPawel Jakub Dawidek  */
28632115b10SPawel Jakub Dawidek void
28732115b10SPawel Jakub Dawidek pjdlog_debug(int debuglevel, const char *fmt, ...)
28832115b10SPawel Jakub Dawidek {
28932115b10SPawel Jakub Dawidek 	va_list ap;
29032115b10SPawel Jakub Dawidek 
29132115b10SPawel Jakub Dawidek 	va_start(ap, fmt);
29232115b10SPawel Jakub Dawidek 	pjdlogv_debug(debuglevel, fmt, ap);
29332115b10SPawel Jakub Dawidek 	va_end(ap);
29432115b10SPawel Jakub Dawidek }
29532115b10SPawel Jakub Dawidek 
29632115b10SPawel Jakub Dawidek /*
29732115b10SPawel Jakub Dawidek  * Error logs with errno logging.
29832115b10SPawel Jakub Dawidek  */
29932115b10SPawel Jakub Dawidek void
30032115b10SPawel Jakub Dawidek pjdlogv_errno(int loglevel, const char *fmt, va_list ap)
30132115b10SPawel Jakub Dawidek {
30232115b10SPawel Jakub Dawidek 
30332115b10SPawel Jakub Dawidek 	pjdlogv_common(loglevel, 0, errno, fmt, ap);
30432115b10SPawel Jakub Dawidek }
30532115b10SPawel Jakub Dawidek 
30632115b10SPawel Jakub Dawidek /*
30732115b10SPawel Jakub Dawidek  * Error logs with errno logging.
30832115b10SPawel Jakub Dawidek  */
30932115b10SPawel Jakub Dawidek void
31032115b10SPawel Jakub Dawidek pjdlog_errno(int loglevel, const char *fmt, ...)
31132115b10SPawel Jakub Dawidek {
31232115b10SPawel Jakub Dawidek 	va_list ap;
31332115b10SPawel Jakub Dawidek 
31432115b10SPawel Jakub Dawidek 	va_start(ap, fmt);
31532115b10SPawel Jakub Dawidek 	pjdlogv_errno(loglevel, fmt, ap);
31632115b10SPawel Jakub Dawidek 	va_end(ap);
31732115b10SPawel Jakub Dawidek }
31832115b10SPawel Jakub Dawidek 
31932115b10SPawel Jakub Dawidek /*
32032115b10SPawel Jakub Dawidek  * Log error, errno and exit.
32132115b10SPawel Jakub Dawidek  */
32232115b10SPawel Jakub Dawidek void
32332115b10SPawel Jakub Dawidek pjdlogv_exit(int exitcode, const char *fmt, va_list ap)
32432115b10SPawel Jakub Dawidek {
32532115b10SPawel Jakub Dawidek 
32632115b10SPawel Jakub Dawidek 	pjdlogv_errno(LOG_ERR, fmt, ap);
32732115b10SPawel Jakub Dawidek 	exit(exitcode);
328*e3031161SPawel Jakub Dawidek 	/* NOTREACHED */
32932115b10SPawel Jakub Dawidek }
33032115b10SPawel Jakub Dawidek 
33132115b10SPawel Jakub Dawidek /*
33232115b10SPawel Jakub Dawidek  * Log error, errno and exit.
33332115b10SPawel Jakub Dawidek  */
33432115b10SPawel Jakub Dawidek void
33532115b10SPawel Jakub Dawidek pjdlog_exit(int exitcode, const char *fmt, ...)
33632115b10SPawel Jakub Dawidek {
33732115b10SPawel Jakub Dawidek 	va_list ap;
33832115b10SPawel Jakub Dawidek 
33932115b10SPawel Jakub Dawidek 	va_start(ap, fmt);
34032115b10SPawel Jakub Dawidek 	pjdlogv_exit(exitcode, fmt, ap);
34132115b10SPawel Jakub Dawidek 	/* NOTREACHED */
34232115b10SPawel Jakub Dawidek 	va_end(ap);
34332115b10SPawel Jakub Dawidek }
34432115b10SPawel Jakub Dawidek 
34532115b10SPawel Jakub Dawidek /*
34632115b10SPawel Jakub Dawidek  * Log error and exit.
34732115b10SPawel Jakub Dawidek  */
34832115b10SPawel Jakub Dawidek void
34932115b10SPawel Jakub Dawidek pjdlogv_exitx(int exitcode, const char *fmt, va_list ap)
35032115b10SPawel Jakub Dawidek {
35132115b10SPawel Jakub Dawidek 
35232115b10SPawel Jakub Dawidek 	pjdlogv(LOG_ERR, fmt, ap);
35332115b10SPawel Jakub Dawidek 	exit(exitcode);
354*e3031161SPawel Jakub Dawidek 	/* NOTREACHED */
35532115b10SPawel Jakub Dawidek }
35632115b10SPawel Jakub Dawidek 
35732115b10SPawel Jakub Dawidek /*
35832115b10SPawel Jakub Dawidek  * Log error and exit.
35932115b10SPawel Jakub Dawidek  */
36032115b10SPawel Jakub Dawidek void
36132115b10SPawel Jakub Dawidek pjdlog_exitx(int exitcode, const char *fmt, ...)
36232115b10SPawel Jakub Dawidek {
36332115b10SPawel Jakub Dawidek 	va_list ap;
36432115b10SPawel Jakub Dawidek 
36532115b10SPawel Jakub Dawidek 	va_start(ap, fmt);
36632115b10SPawel Jakub Dawidek 	pjdlogv_exitx(exitcode, fmt, ap);
36732115b10SPawel Jakub Dawidek 	/* NOTREACHED */
36832115b10SPawel Jakub Dawidek 	va_end(ap);
36932115b10SPawel Jakub Dawidek }
370