189580Smsmith/*-
2139749Simp * Copyright (c) 2012 The FreeBSD Foundation
3129449Sscottl * All rights reserved.
4129449Sscottl *
5129449Sscottl * This software was developed by Edward Tomasz Napierala under sponsorship
689580Smsmith * from the FreeBSD Foundation.
789580Smsmith *
889580Smsmith * Redistribution and use in source and binary forms, with or without
989580Smsmith * modification, are permitted provided that the following conditions
1089580Smsmith * are met:
1189580Smsmith * 1. Redistributions of source code must retain the above copyright
1289580Smsmith *    notice, this list of conditions and the following disclaimer.
1389580Smsmith * 2. Redistributions in binary form must reproduce the above copyright
1489580Smsmith *    notice, this list of conditions and the following disclaimer in the
1589580Smsmith *    documentation and/or other materials provided with the distribution.
1689580Smsmith *
1789580Smsmith * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1889580Smsmith * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1989580Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2089580Smsmith * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2189580Smsmith * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2289580Smsmith * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2389580Smsmith * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2489580Smsmith * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2589580Smsmith * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2689580Smsmith * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2789580Smsmith * SUCH DAMAGE.
2889580Smsmith *
2989580Smsmith */
3089580Smsmith
3189580Smsmith#include <sys/cdefs.h>
3289580Smsmith__FBSDID("$FreeBSD: releng/11.0/usr.sbin/ctld/log.c 296897 2016-03-15 11:03:45Z trasz $");
3389580Smsmith
3489580Smsmith#include <errno.h>
3589580Smsmith#include <stdarg.h>
3689580Smsmith#include <stdio.h>
3789580Smsmith#include <stdlib.h>
38120477Sscottl#include <string.h>
3989580Smsmith#include <syslog.h>
4089580Smsmith#include <vis.h>
4189580Smsmith
4289580Smsmith#include "ctld.h"
43120477Sscottl
44129449Sscottlstatic int log_level = 0;
4589580Smsmithstatic char *peer_name = NULL;
4689580Smsmithstatic char *peer_addr = NULL;
4789580Smsmith
4889580Smsmith#define	MSGBUF_LEN	1024
4989580Smsmith
50143063Sjoergvoid
51143063Sjoerglog_init(int level)
52143063Sjoerg{
53143063Sjoerg
5489580Smsmith	log_level = level;
55129449Sscottl	openlog(getprogname(), LOG_NDELAY | LOG_PID, LOG_DAEMON);
5689580Smsmith}
57120477Sscottl
58120477Sscottlvoid
59120477Sscottllog_set_peer_name(const char *name)
60120477Sscottl{
6189580Smsmith
6289580Smsmith	/*
6389580Smsmith	 * XXX: Turn it into assertion?
6489580Smsmith	 */
6589580Smsmith	if (peer_name != NULL)
66254379Sjkim		log_errx(1, "%s called twice", __func__);
6789580Smsmith	if (peer_addr == NULL)
6889580Smsmith		log_errx(1, "%s called before log_set_peer_addr", __func__);
6989580Smsmith
7089580Smsmith	peer_name = checked_strdup(name);
7189580Smsmith}
7289580Smsmith
7389580Smsmithvoid
7489580Smsmithlog_set_peer_addr(const char *addr)
7589580Smsmith{
7689580Smsmith
7789580Smsmith	/*
7889580Smsmith	 * XXX: Turn it into assertion?
7989580Smsmith	 */
8089580Smsmith	if (peer_addr != NULL)
8189580Smsmith		log_errx(1, "%s called twice", __func__);
8289580Smsmith
8389580Smsmith	peer_addr = checked_strdup(addr);
8489580Smsmith}
8589580Smsmith
8689580Smsmithstatic void
8789580Smsmithlog_common(int priority, int log_errno, const char *fmt, va_list ap)
8889580Smsmith{
8989580Smsmith	static char msgbuf[MSGBUF_LEN];
9089580Smsmith	static char msgbuf_strvised[MSGBUF_LEN * 4 + 1];
9189580Smsmith	char *errstr;
9289580Smsmith	int ret;
9389580Smsmith
9489580Smsmith	ret = vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap);
9589580Smsmith	if (ret < 0) {
9689580Smsmith		fprintf(stderr, "%s: snprintf failed", getprogname());
9789580Smsmith		syslog(LOG_CRIT, "snprintf failed");
9889580Smsmith		exit(1);
9989580Smsmith	}
10089580Smsmith
10189580Smsmith	ret = strnvis(msgbuf_strvised, sizeof(msgbuf_strvised), msgbuf, VIS_NL);
10289580Smsmith	if (ret < 0) {
10389580Smsmith		fprintf(stderr, "%s: strnvis failed", getprogname());
10489580Smsmith		syslog(LOG_CRIT, "strnvis failed");
10589580Smsmith		exit(1);
10689580Smsmith	}
10789580Smsmith
10889580Smsmith	if (log_errno == -1) {
10989580Smsmith		if (peer_name != NULL) {
11089580Smsmith			fprintf(stderr, "%s: %s (%s): %s\n", getprogname(),
11189580Smsmith			    peer_addr, peer_name, msgbuf_strvised);
11289580Smsmith			syslog(priority, "%s (%s): %s",
11389580Smsmith			    peer_addr, peer_name, msgbuf_strvised);
11489580Smsmith		} else if (peer_addr != NULL) {
11589580Smsmith			fprintf(stderr, "%s: %s: %s\n", getprogname(),
11689580Smsmith			    peer_addr, msgbuf_strvised);
11789580Smsmith			syslog(priority, "%s: %s",
11889580Smsmith			    peer_addr, msgbuf_strvised);
11989580Smsmith		} else {
12089580Smsmith			fprintf(stderr, "%s: %s\n", getprogname(), msgbuf_strvised);
12189580Smsmith			syslog(priority, "%s", msgbuf_strvised);
12289580Smsmith		}
12389580Smsmith
12489580Smsmith	} else {
12589580Smsmith		errstr = strerror(log_errno);
12689580Smsmith
12789580Smsmith		if (peer_name != NULL) {
12889580Smsmith			fprintf(stderr, "%s: %s (%s): %s: %s\n", getprogname(),
12989580Smsmith			    peer_addr, peer_name, msgbuf_strvised, errstr);
13089580Smsmith			syslog(priority, "%s (%s): %s: %s",
13189580Smsmith			    peer_addr, peer_name, msgbuf_strvised, errstr);
13289580Smsmith		} else if (peer_addr != NULL) {
13389580Smsmith			fprintf(stderr, "%s: %s: %s: %s\n", getprogname(),
13489580Smsmith			    peer_addr, msgbuf_strvised, errstr);
13589580Smsmith			syslog(priority, "%s: %s: %s",
13689580Smsmith			    peer_addr, msgbuf_strvised, errstr);
13789580Smsmith		} else {
13889580Smsmith			fprintf(stderr, "%s: %s: %s\n", getprogname(),
13989580Smsmith			    msgbuf_strvised, errstr);
14089580Smsmith			syslog(priority, "%s: %s",
14189580Smsmith			    msgbuf_strvised, errstr);
14289580Smsmith		}
14389580Smsmith	}
14489580Smsmith}
14589580Smsmith
14689580Smsmithvoid
14789580Smsmithlog_err(int eval, const char *fmt, ...)
14889580Smsmith{
14989580Smsmith	va_list ap;
15089580Smsmith
15189580Smsmith	va_start(ap, fmt);
152114001Sscottl	log_common(LOG_CRIT, errno, fmt, ap);
15389580Smsmith	va_end(ap);
15489580Smsmith
15589580Smsmith	exit(eval);
15689580Smsmith}
15789580Smsmith
15889580Smsmithvoid
159129449Sscottllog_errx(int eval, const char *fmt, ...)
160129449Sscottl{
161129449Sscottl	va_list ap;
162129449Sscottl
16389580Smsmith	va_start(ap, fmt);
16489580Smsmith	log_common(LOG_CRIT, -1, fmt, ap);
16589580Smsmith	va_end(ap);
16689580Smsmith
16789580Smsmith	exit(eval);
16889580Smsmith}
16989580Smsmith
17089580Smsmithvoid
17189580Smsmithlog_warn(const char *fmt, ...)
17289580Smsmith{
17389580Smsmith	va_list ap;
17489580Smsmith
17589580Smsmith	va_start(ap, fmt);
17689580Smsmith	log_common(LOG_WARNING, errno, fmt, ap);
17789580Smsmith	va_end(ap);
17889580Smsmith}
17989580Smsmith
18089580Smsmithvoid
18189580Smsmithlog_warnx(const char *fmt, ...)
18289580Smsmith{
18389580Smsmith	va_list ap;
18489580Smsmith
18589580Smsmith	va_start(ap, fmt);
18689580Smsmith	log_common(LOG_WARNING, -1, fmt, ap);
18789580Smsmith	va_end(ap);
18889580Smsmith}
18989580Smsmith
19089580Smsmithvoid
19189580Smsmithlog_debugx(const char *fmt, ...)
19289580Smsmith{
19389580Smsmith	va_list ap;
19489580Smsmith
19589580Smsmith	if (log_level == 0)
19689580Smsmith		return;
19789580Smsmith
19889580Smsmith	va_start(ap, fmt);
19989580Smsmith	log_common(LOG_DEBUG, -1, fmt, ap);
20089580Smsmith	va_end(ap);
20189580Smsmith}
20289580Smsmith