xref: /freebsd/usr.sbin/autofs/log.c (revision a466cc55373fc3cf86837f09da729535b57e69a1)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2012 The FreeBSD Foundation
5  *
6  * This software was developed by Edward Tomasz Napierala under sponsorship
7  * from the FreeBSD Foundation.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  *
30  */
31 
32 #include <sys/cdefs.h>
33 __FBSDID("$FreeBSD$");
34 
35 #include <errno.h>
36 #include <stdarg.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <syslog.h>
41 #include <vis.h>
42 
43 #include "common.h"
44 
45 static int log_level = 0;
46 static char *peer_name = NULL;
47 static char *peer_addr = NULL;
48 
49 #define	MSGBUF_LEN	1024
50 
51 void
52 log_init(int level)
53 {
54 
55 	log_level = level;
56 	openlog(getprogname(), LOG_NDELAY | LOG_PID, LOG_DAEMON);
57 }
58 
59 void
60 log_set_peer_name(const char *name)
61 {
62 
63 	/*
64 	 * XXX: Turn it into assertion?
65 	 */
66 	if (peer_name != NULL)
67 		log_errx(1, "%s called twice", __func__);
68 	if (peer_addr == NULL)
69 		log_errx(1, "%s called before log_set_peer_addr", __func__);
70 
71 	peer_name = checked_strdup(name);
72 }
73 
74 void
75 log_set_peer_addr(const char *addr)
76 {
77 
78 	/*
79 	 * XXX: Turn it into assertion?
80 	 */
81 	if (peer_addr != NULL)
82 		log_errx(1, "%s called twice", __func__);
83 
84 	peer_addr = checked_strdup(addr);
85 }
86 
87 static void
88 log_common(int priority, int log_errno, const char *fmt, va_list ap)
89 {
90 	static char msgbuf[MSGBUF_LEN];
91 	static char msgbuf_strvised[MSGBUF_LEN * 4 + 1];
92 	char *errstr;
93 	int ret;
94 
95 	ret = vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap);
96 	if (ret < 0) {
97 		fprintf(stderr, "%s: snprintf failed", getprogname());
98 		syslog(LOG_CRIT, "snprintf failed");
99 		exit(1);
100 	}
101 
102 	ret = strnvis(msgbuf_strvised, sizeof(msgbuf_strvised), msgbuf, VIS_NL);
103 	if (ret < 0) {
104 		fprintf(stderr, "%s: strnvis failed", getprogname());
105 		syslog(LOG_CRIT, "strnvis failed");
106 		exit(1);
107 	}
108 
109 	if (log_errno == -1) {
110 		if (peer_name != NULL) {
111 			fprintf(stderr, "%s: %s (%s): %s\n", getprogname(),
112 			    peer_addr, peer_name, msgbuf_strvised);
113 			syslog(priority, "%s (%s): %s",
114 			    peer_addr, peer_name, msgbuf_strvised);
115 		} else if (peer_addr != NULL) {
116 			fprintf(stderr, "%s: %s: %s\n", getprogname(),
117 			    peer_addr, msgbuf_strvised);
118 			syslog(priority, "%s: %s",
119 			    peer_addr, msgbuf_strvised);
120 		} else {
121 			fprintf(stderr, "%s: %s\n", getprogname(), msgbuf_strvised);
122 			syslog(priority, "%s", msgbuf_strvised);
123 		}
124 
125 	} else {
126 		errstr = strerror(log_errno);
127 
128 		if (peer_name != NULL) {
129 			fprintf(stderr, "%s: %s (%s): %s: %s\n", getprogname(),
130 			    peer_addr, peer_name, msgbuf_strvised, errstr);
131 			syslog(priority, "%s (%s): %s: %s",
132 			    peer_addr, peer_name, msgbuf_strvised, errstr);
133 		} else if (peer_addr != NULL) {
134 			fprintf(stderr, "%s: %s: %s: %s\n", getprogname(),
135 			    peer_addr, msgbuf_strvised, errstr);
136 			syslog(priority, "%s: %s: %s",
137 			    peer_addr, msgbuf_strvised, errstr);
138 		} else {
139 			fprintf(stderr, "%s: %s: %s\n", getprogname(),
140 			    msgbuf_strvised, errstr);
141 			syslog(priority, "%s: %s",
142 			    msgbuf_strvised, errstr);
143 		}
144 	}
145 }
146 
147 void
148 log_err(int eval, const char *fmt, ...)
149 {
150 	va_list ap;
151 
152 	va_start(ap, fmt);
153 	log_common(LOG_CRIT, errno, fmt, ap);
154 	va_end(ap);
155 
156 	exit(eval);
157 }
158 
159 void
160 log_errx(int eval, const char *fmt, ...)
161 {
162 	va_list ap;
163 
164 	va_start(ap, fmt);
165 	log_common(LOG_CRIT, -1, fmt, ap);
166 	va_end(ap);
167 
168 	exit(eval);
169 }
170 
171 void
172 log_warn(const char *fmt, ...)
173 {
174 	va_list ap;
175 
176 	va_start(ap, fmt);
177 	log_common(LOG_WARNING, errno, fmt, ap);
178 	va_end(ap);
179 }
180 
181 void
182 log_warnx(const char *fmt, ...)
183 {
184 	va_list ap;
185 
186 	va_start(ap, fmt);
187 	log_common(LOG_WARNING, -1, fmt, ap);
188 	va_end(ap);
189 }
190 
191 void
192 log_debugx(const char *fmt, ...)
193 {
194 	va_list ap;
195 
196 	if (log_level == 0)
197 		return;
198 
199 	va_start(ap, fmt);
200 	log_common(LOG_DEBUG, -1, fmt, ap);
201 	va_end(ap);
202 }
203