xref: /dflybsd-src/crypto/openssh/log.c (revision 18de8d7fff95ec279dc99590be94fa1e199430dc)
1*18de8d7fSPeter Avalos /* $OpenBSD: log.c,v 1.41 2008/06/10 04:50:25 dtucker Exp $ */
2*18de8d7fSPeter Avalos /*
3*18de8d7fSPeter Avalos  * Author: Tatu Ylonen <ylo@cs.hut.fi>
4*18de8d7fSPeter Avalos  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
5*18de8d7fSPeter Avalos  *                    All rights reserved
6*18de8d7fSPeter Avalos  *
7*18de8d7fSPeter Avalos  * As far as I am concerned, the code I have written for this software
8*18de8d7fSPeter Avalos  * can be used freely for any purpose.  Any derived versions of this
9*18de8d7fSPeter Avalos  * software must be clearly marked as such, and if the derived work is
10*18de8d7fSPeter Avalos  * incompatible with the protocol description in the RFC file, it must be
11*18de8d7fSPeter Avalos  * called by a name other than "ssh" or "Secure Shell".
12*18de8d7fSPeter Avalos  */
13*18de8d7fSPeter Avalos /*
14*18de8d7fSPeter Avalos  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
15*18de8d7fSPeter Avalos  *
16*18de8d7fSPeter Avalos  * Redistribution and use in source and binary forms, with or without
17*18de8d7fSPeter Avalos  * modification, are permitted provided that the following conditions
18*18de8d7fSPeter Avalos  * are met:
19*18de8d7fSPeter Avalos  * 1. Redistributions of source code must retain the above copyright
20*18de8d7fSPeter Avalos  *    notice, this list of conditions and the following disclaimer.
21*18de8d7fSPeter Avalos  * 2. Redistributions in binary form must reproduce the above copyright
22*18de8d7fSPeter Avalos  *    notice, this list of conditions and the following disclaimer in the
23*18de8d7fSPeter Avalos  *    documentation and/or other materials provided with the distribution.
24*18de8d7fSPeter Avalos  *
25*18de8d7fSPeter Avalos  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
26*18de8d7fSPeter Avalos  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
27*18de8d7fSPeter Avalos  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
28*18de8d7fSPeter Avalos  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
29*18de8d7fSPeter Avalos  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30*18de8d7fSPeter Avalos  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31*18de8d7fSPeter Avalos  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32*18de8d7fSPeter Avalos  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33*18de8d7fSPeter Avalos  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34*18de8d7fSPeter Avalos  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35*18de8d7fSPeter Avalos  */
36*18de8d7fSPeter Avalos 
37*18de8d7fSPeter Avalos #include "includes.h"
38*18de8d7fSPeter Avalos 
39*18de8d7fSPeter Avalos #include <sys/types.h>
40*18de8d7fSPeter Avalos 
41*18de8d7fSPeter Avalos #include <stdarg.h>
42*18de8d7fSPeter Avalos #include <stdio.h>
43*18de8d7fSPeter Avalos #include <stdlib.h>
44*18de8d7fSPeter Avalos #include <string.h>
45*18de8d7fSPeter Avalos #include <syslog.h>
46*18de8d7fSPeter Avalos #include <unistd.h>
47*18de8d7fSPeter Avalos #include <errno.h>
48*18de8d7fSPeter Avalos #if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H)
49*18de8d7fSPeter Avalos # include <vis.h>
50*18de8d7fSPeter Avalos #endif
51*18de8d7fSPeter Avalos 
52*18de8d7fSPeter Avalos #include "xmalloc.h"
53*18de8d7fSPeter Avalos #include "log.h"
54*18de8d7fSPeter Avalos 
55*18de8d7fSPeter Avalos static LogLevel log_level = SYSLOG_LEVEL_INFO;
56*18de8d7fSPeter Avalos static int log_on_stderr = 1;
57*18de8d7fSPeter Avalos static int log_facility = LOG_AUTH;
58*18de8d7fSPeter Avalos static char *argv0;
59*18de8d7fSPeter Avalos 
60*18de8d7fSPeter Avalos extern char *__progname;
61*18de8d7fSPeter Avalos 
62*18de8d7fSPeter Avalos #define LOG_SYSLOG_VIS	(VIS_CSTYLE|VIS_NL|VIS_TAB|VIS_OCTAL)
63*18de8d7fSPeter Avalos #define LOG_STDERR_VIS	(VIS_SAFE|VIS_OCTAL)
64*18de8d7fSPeter Avalos 
65*18de8d7fSPeter Avalos /* textual representation of log-facilities/levels */
66*18de8d7fSPeter Avalos 
67*18de8d7fSPeter Avalos static struct {
68*18de8d7fSPeter Avalos 	const char *name;
69*18de8d7fSPeter Avalos 	SyslogFacility val;
70*18de8d7fSPeter Avalos } log_facilities[] = {
71*18de8d7fSPeter Avalos 	{ "DAEMON",	SYSLOG_FACILITY_DAEMON },
72*18de8d7fSPeter Avalos 	{ "USER",	SYSLOG_FACILITY_USER },
73*18de8d7fSPeter Avalos 	{ "AUTH",	SYSLOG_FACILITY_AUTH },
74*18de8d7fSPeter Avalos #ifdef LOG_AUTHPRIV
75*18de8d7fSPeter Avalos 	{ "AUTHPRIV",	SYSLOG_FACILITY_AUTHPRIV },
76*18de8d7fSPeter Avalos #endif
77*18de8d7fSPeter Avalos 	{ "LOCAL0",	SYSLOG_FACILITY_LOCAL0 },
78*18de8d7fSPeter Avalos 	{ "LOCAL1",	SYSLOG_FACILITY_LOCAL1 },
79*18de8d7fSPeter Avalos 	{ "LOCAL2",	SYSLOG_FACILITY_LOCAL2 },
80*18de8d7fSPeter Avalos 	{ "LOCAL3",	SYSLOG_FACILITY_LOCAL3 },
81*18de8d7fSPeter Avalos 	{ "LOCAL4",	SYSLOG_FACILITY_LOCAL4 },
82*18de8d7fSPeter Avalos 	{ "LOCAL5",	SYSLOG_FACILITY_LOCAL5 },
83*18de8d7fSPeter Avalos 	{ "LOCAL6",	SYSLOG_FACILITY_LOCAL6 },
84*18de8d7fSPeter Avalos 	{ "LOCAL7",	SYSLOG_FACILITY_LOCAL7 },
85*18de8d7fSPeter Avalos 	{ NULL,		SYSLOG_FACILITY_NOT_SET }
86*18de8d7fSPeter Avalos };
87*18de8d7fSPeter Avalos 
88*18de8d7fSPeter Avalos static struct {
89*18de8d7fSPeter Avalos 	const char *name;
90*18de8d7fSPeter Avalos 	LogLevel val;
91*18de8d7fSPeter Avalos } log_levels[] =
92*18de8d7fSPeter Avalos {
93*18de8d7fSPeter Avalos 	{ "QUIET",	SYSLOG_LEVEL_QUIET },
94*18de8d7fSPeter Avalos 	{ "FATAL",	SYSLOG_LEVEL_FATAL },
95*18de8d7fSPeter Avalos 	{ "ERROR",	SYSLOG_LEVEL_ERROR },
96*18de8d7fSPeter Avalos 	{ "INFO",	SYSLOG_LEVEL_INFO },
97*18de8d7fSPeter Avalos 	{ "VERBOSE",	SYSLOG_LEVEL_VERBOSE },
98*18de8d7fSPeter Avalos 	{ "DEBUG",	SYSLOG_LEVEL_DEBUG1 },
99*18de8d7fSPeter Avalos 	{ "DEBUG1",	SYSLOG_LEVEL_DEBUG1 },
100*18de8d7fSPeter Avalos 	{ "DEBUG2",	SYSLOG_LEVEL_DEBUG2 },
101*18de8d7fSPeter Avalos 	{ "DEBUG3",	SYSLOG_LEVEL_DEBUG3 },
102*18de8d7fSPeter Avalos 	{ NULL,		SYSLOG_LEVEL_NOT_SET }
103*18de8d7fSPeter Avalos };
104*18de8d7fSPeter Avalos 
105*18de8d7fSPeter Avalos SyslogFacility
106*18de8d7fSPeter Avalos log_facility_number(char *name)
107*18de8d7fSPeter Avalos {
108*18de8d7fSPeter Avalos 	int i;
109*18de8d7fSPeter Avalos 
110*18de8d7fSPeter Avalos 	if (name != NULL)
111*18de8d7fSPeter Avalos 		for (i = 0; log_facilities[i].name; i++)
112*18de8d7fSPeter Avalos 			if (strcasecmp(log_facilities[i].name, name) == 0)
113*18de8d7fSPeter Avalos 				return log_facilities[i].val;
114*18de8d7fSPeter Avalos 	return SYSLOG_FACILITY_NOT_SET;
115*18de8d7fSPeter Avalos }
116*18de8d7fSPeter Avalos 
117*18de8d7fSPeter Avalos const char *
118*18de8d7fSPeter Avalos log_facility_name(SyslogFacility facility)
119*18de8d7fSPeter Avalos {
120*18de8d7fSPeter Avalos 	u_int i;
121*18de8d7fSPeter Avalos 
122*18de8d7fSPeter Avalos 	for (i = 0;  log_facilities[i].name; i++)
123*18de8d7fSPeter Avalos 		if (log_facilities[i].val == facility)
124*18de8d7fSPeter Avalos 			return log_facilities[i].name;
125*18de8d7fSPeter Avalos 	return NULL;
126*18de8d7fSPeter Avalos }
127*18de8d7fSPeter Avalos 
128*18de8d7fSPeter Avalos LogLevel
129*18de8d7fSPeter Avalos log_level_number(char *name)
130*18de8d7fSPeter Avalos {
131*18de8d7fSPeter Avalos 	int i;
132*18de8d7fSPeter Avalos 
133*18de8d7fSPeter Avalos 	if (name != NULL)
134*18de8d7fSPeter Avalos 		for (i = 0; log_levels[i].name; i++)
135*18de8d7fSPeter Avalos 			if (strcasecmp(log_levels[i].name, name) == 0)
136*18de8d7fSPeter Avalos 				return log_levels[i].val;
137*18de8d7fSPeter Avalos 	return SYSLOG_LEVEL_NOT_SET;
138*18de8d7fSPeter Avalos }
139*18de8d7fSPeter Avalos 
140*18de8d7fSPeter Avalos const char *
141*18de8d7fSPeter Avalos log_level_name(LogLevel level)
142*18de8d7fSPeter Avalos {
143*18de8d7fSPeter Avalos 	u_int i;
144*18de8d7fSPeter Avalos 
145*18de8d7fSPeter Avalos 	for (i = 0; log_levels[i].name != NULL; i++)
146*18de8d7fSPeter Avalos 		if (log_levels[i].val == level)
147*18de8d7fSPeter Avalos 			return log_levels[i].name;
148*18de8d7fSPeter Avalos 	return NULL;
149*18de8d7fSPeter Avalos }
150*18de8d7fSPeter Avalos 
151*18de8d7fSPeter Avalos /* Error messages that should be logged. */
152*18de8d7fSPeter Avalos 
153*18de8d7fSPeter Avalos void
154*18de8d7fSPeter Avalos error(const char *fmt,...)
155*18de8d7fSPeter Avalos {
156*18de8d7fSPeter Avalos 	va_list args;
157*18de8d7fSPeter Avalos 
158*18de8d7fSPeter Avalos 	va_start(args, fmt);
159*18de8d7fSPeter Avalos 	do_log(SYSLOG_LEVEL_ERROR, fmt, args);
160*18de8d7fSPeter Avalos 	va_end(args);
161*18de8d7fSPeter Avalos }
162*18de8d7fSPeter Avalos 
163*18de8d7fSPeter Avalos void
164*18de8d7fSPeter Avalos sigdie(const char *fmt,...)
165*18de8d7fSPeter Avalos {
166*18de8d7fSPeter Avalos #ifdef DO_LOG_SAFE_IN_SIGHAND
167*18de8d7fSPeter Avalos 	va_list args;
168*18de8d7fSPeter Avalos 
169*18de8d7fSPeter Avalos 	va_start(args, fmt);
170*18de8d7fSPeter Avalos 	do_log(SYSLOG_LEVEL_FATAL, fmt, args);
171*18de8d7fSPeter Avalos 	va_end(args);
172*18de8d7fSPeter Avalos #endif
173*18de8d7fSPeter Avalos 	_exit(1);
174*18de8d7fSPeter Avalos }
175*18de8d7fSPeter Avalos 
176*18de8d7fSPeter Avalos 
177*18de8d7fSPeter Avalos /* Log this message (information that usually should go to the log). */
178*18de8d7fSPeter Avalos 
179*18de8d7fSPeter Avalos void
180*18de8d7fSPeter Avalos logit(const char *fmt,...)
181*18de8d7fSPeter Avalos {
182*18de8d7fSPeter Avalos 	va_list args;
183*18de8d7fSPeter Avalos 
184*18de8d7fSPeter Avalos 	va_start(args, fmt);
185*18de8d7fSPeter Avalos 	do_log(SYSLOG_LEVEL_INFO, fmt, args);
186*18de8d7fSPeter Avalos 	va_end(args);
187*18de8d7fSPeter Avalos }
188*18de8d7fSPeter Avalos 
189*18de8d7fSPeter Avalos /* More detailed messages (information that does not need to go to the log). */
190*18de8d7fSPeter Avalos 
191*18de8d7fSPeter Avalos void
192*18de8d7fSPeter Avalos verbose(const char *fmt,...)
193*18de8d7fSPeter Avalos {
194*18de8d7fSPeter Avalos 	va_list args;
195*18de8d7fSPeter Avalos 
196*18de8d7fSPeter Avalos 	va_start(args, fmt);
197*18de8d7fSPeter Avalos 	do_log(SYSLOG_LEVEL_VERBOSE, fmt, args);
198*18de8d7fSPeter Avalos 	va_end(args);
199*18de8d7fSPeter Avalos }
200*18de8d7fSPeter Avalos 
201*18de8d7fSPeter Avalos /* Debugging messages that should not be logged during normal operation. */
202*18de8d7fSPeter Avalos 
203*18de8d7fSPeter Avalos void
204*18de8d7fSPeter Avalos debug(const char *fmt,...)
205*18de8d7fSPeter Avalos {
206*18de8d7fSPeter Avalos 	va_list args;
207*18de8d7fSPeter Avalos 
208*18de8d7fSPeter Avalos 	va_start(args, fmt);
209*18de8d7fSPeter Avalos 	do_log(SYSLOG_LEVEL_DEBUG1, fmt, args);
210*18de8d7fSPeter Avalos 	va_end(args);
211*18de8d7fSPeter Avalos }
212*18de8d7fSPeter Avalos 
213*18de8d7fSPeter Avalos void
214*18de8d7fSPeter Avalos debug2(const char *fmt,...)
215*18de8d7fSPeter Avalos {
216*18de8d7fSPeter Avalos 	va_list args;
217*18de8d7fSPeter Avalos 
218*18de8d7fSPeter Avalos 	va_start(args, fmt);
219*18de8d7fSPeter Avalos 	do_log(SYSLOG_LEVEL_DEBUG2, fmt, args);
220*18de8d7fSPeter Avalos 	va_end(args);
221*18de8d7fSPeter Avalos }
222*18de8d7fSPeter Avalos 
223*18de8d7fSPeter Avalos void
224*18de8d7fSPeter Avalos debug3(const char *fmt,...)
225*18de8d7fSPeter Avalos {
226*18de8d7fSPeter Avalos 	va_list args;
227*18de8d7fSPeter Avalos 
228*18de8d7fSPeter Avalos 	va_start(args, fmt);
229*18de8d7fSPeter Avalos 	do_log(SYSLOG_LEVEL_DEBUG3, fmt, args);
230*18de8d7fSPeter Avalos 	va_end(args);
231*18de8d7fSPeter Avalos }
232*18de8d7fSPeter Avalos 
233*18de8d7fSPeter Avalos /*
234*18de8d7fSPeter Avalos  * Initialize the log.
235*18de8d7fSPeter Avalos  */
236*18de8d7fSPeter Avalos 
237*18de8d7fSPeter Avalos void
238*18de8d7fSPeter Avalos log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr)
239*18de8d7fSPeter Avalos {
240*18de8d7fSPeter Avalos #if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT)
241*18de8d7fSPeter Avalos 	struct syslog_data sdata = SYSLOG_DATA_INIT;
242*18de8d7fSPeter Avalos #endif
243*18de8d7fSPeter Avalos 
244*18de8d7fSPeter Avalos 	argv0 = av0;
245*18de8d7fSPeter Avalos 
246*18de8d7fSPeter Avalos 	switch (level) {
247*18de8d7fSPeter Avalos 	case SYSLOG_LEVEL_QUIET:
248*18de8d7fSPeter Avalos 	case SYSLOG_LEVEL_FATAL:
249*18de8d7fSPeter Avalos 	case SYSLOG_LEVEL_ERROR:
250*18de8d7fSPeter Avalos 	case SYSLOG_LEVEL_INFO:
251*18de8d7fSPeter Avalos 	case SYSLOG_LEVEL_VERBOSE:
252*18de8d7fSPeter Avalos 	case SYSLOG_LEVEL_DEBUG1:
253*18de8d7fSPeter Avalos 	case SYSLOG_LEVEL_DEBUG2:
254*18de8d7fSPeter Avalos 	case SYSLOG_LEVEL_DEBUG3:
255*18de8d7fSPeter Avalos 		log_level = level;
256*18de8d7fSPeter Avalos 		break;
257*18de8d7fSPeter Avalos 	default:
258*18de8d7fSPeter Avalos 		fprintf(stderr, "Unrecognized internal syslog level code %d\n",
259*18de8d7fSPeter Avalos 		    (int) level);
260*18de8d7fSPeter Avalos 		exit(1);
261*18de8d7fSPeter Avalos 	}
262*18de8d7fSPeter Avalos 
263*18de8d7fSPeter Avalos 	log_on_stderr = on_stderr;
264*18de8d7fSPeter Avalos 	if (on_stderr)
265*18de8d7fSPeter Avalos 		return;
266*18de8d7fSPeter Avalos 
267*18de8d7fSPeter Avalos 	switch (facility) {
268*18de8d7fSPeter Avalos 	case SYSLOG_FACILITY_DAEMON:
269*18de8d7fSPeter Avalos 		log_facility = LOG_DAEMON;
270*18de8d7fSPeter Avalos 		break;
271*18de8d7fSPeter Avalos 	case SYSLOG_FACILITY_USER:
272*18de8d7fSPeter Avalos 		log_facility = LOG_USER;
273*18de8d7fSPeter Avalos 		break;
274*18de8d7fSPeter Avalos 	case SYSLOG_FACILITY_AUTH:
275*18de8d7fSPeter Avalos 		log_facility = LOG_AUTH;
276*18de8d7fSPeter Avalos 		break;
277*18de8d7fSPeter Avalos #ifdef LOG_AUTHPRIV
278*18de8d7fSPeter Avalos 	case SYSLOG_FACILITY_AUTHPRIV:
279*18de8d7fSPeter Avalos 		log_facility = LOG_AUTHPRIV;
280*18de8d7fSPeter Avalos 		break;
281*18de8d7fSPeter Avalos #endif
282*18de8d7fSPeter Avalos 	case SYSLOG_FACILITY_LOCAL0:
283*18de8d7fSPeter Avalos 		log_facility = LOG_LOCAL0;
284*18de8d7fSPeter Avalos 		break;
285*18de8d7fSPeter Avalos 	case SYSLOG_FACILITY_LOCAL1:
286*18de8d7fSPeter Avalos 		log_facility = LOG_LOCAL1;
287*18de8d7fSPeter Avalos 		break;
288*18de8d7fSPeter Avalos 	case SYSLOG_FACILITY_LOCAL2:
289*18de8d7fSPeter Avalos 		log_facility = LOG_LOCAL2;
290*18de8d7fSPeter Avalos 		break;
291*18de8d7fSPeter Avalos 	case SYSLOG_FACILITY_LOCAL3:
292*18de8d7fSPeter Avalos 		log_facility = LOG_LOCAL3;
293*18de8d7fSPeter Avalos 		break;
294*18de8d7fSPeter Avalos 	case SYSLOG_FACILITY_LOCAL4:
295*18de8d7fSPeter Avalos 		log_facility = LOG_LOCAL4;
296*18de8d7fSPeter Avalos 		break;
297*18de8d7fSPeter Avalos 	case SYSLOG_FACILITY_LOCAL5:
298*18de8d7fSPeter Avalos 		log_facility = LOG_LOCAL5;
299*18de8d7fSPeter Avalos 		break;
300*18de8d7fSPeter Avalos 	case SYSLOG_FACILITY_LOCAL6:
301*18de8d7fSPeter Avalos 		log_facility = LOG_LOCAL6;
302*18de8d7fSPeter Avalos 		break;
303*18de8d7fSPeter Avalos 	case SYSLOG_FACILITY_LOCAL7:
304*18de8d7fSPeter Avalos 		log_facility = LOG_LOCAL7;
305*18de8d7fSPeter Avalos 		break;
306*18de8d7fSPeter Avalos 	default:
307*18de8d7fSPeter Avalos 		fprintf(stderr,
308*18de8d7fSPeter Avalos 		    "Unrecognized internal syslog facility code %d\n",
309*18de8d7fSPeter Avalos 		    (int) facility);
310*18de8d7fSPeter Avalos 		exit(1);
311*18de8d7fSPeter Avalos 	}
312*18de8d7fSPeter Avalos 
313*18de8d7fSPeter Avalos 	/*
314*18de8d7fSPeter Avalos 	 * If an external library (eg libwrap) attempts to use syslog
315*18de8d7fSPeter Avalos 	 * immediately after reexec, syslog may be pointing to the wrong
316*18de8d7fSPeter Avalos 	 * facility, so we force an open/close of syslog here.
317*18de8d7fSPeter Avalos 	 */
318*18de8d7fSPeter Avalos #if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT)
319*18de8d7fSPeter Avalos 	openlog_r(argv0 ? argv0 : __progname, LOG_PID, log_facility, &sdata);
320*18de8d7fSPeter Avalos 	closelog_r(&sdata);
321*18de8d7fSPeter Avalos #else
322*18de8d7fSPeter Avalos 	openlog(argv0 ? argv0 : __progname, LOG_PID, log_facility);
323*18de8d7fSPeter Avalos 	closelog();
324*18de8d7fSPeter Avalos #endif
325*18de8d7fSPeter Avalos }
326*18de8d7fSPeter Avalos 
327*18de8d7fSPeter Avalos #define MSGBUFSIZ 1024
328*18de8d7fSPeter Avalos 
329*18de8d7fSPeter Avalos void
330*18de8d7fSPeter Avalos do_log(LogLevel level, const char *fmt, va_list args)
331*18de8d7fSPeter Avalos {
332*18de8d7fSPeter Avalos #if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT)
333*18de8d7fSPeter Avalos 	struct syslog_data sdata = SYSLOG_DATA_INIT;
334*18de8d7fSPeter Avalos #endif
335*18de8d7fSPeter Avalos 	char msgbuf[MSGBUFSIZ];
336*18de8d7fSPeter Avalos 	char fmtbuf[MSGBUFSIZ];
337*18de8d7fSPeter Avalos 	char *txt = NULL;
338*18de8d7fSPeter Avalos 	int pri = LOG_INFO;
339*18de8d7fSPeter Avalos 	int saved_errno = errno;
340*18de8d7fSPeter Avalos 
341*18de8d7fSPeter Avalos 	if (level > log_level)
342*18de8d7fSPeter Avalos 		return;
343*18de8d7fSPeter Avalos 
344*18de8d7fSPeter Avalos 	switch (level) {
345*18de8d7fSPeter Avalos 	case SYSLOG_LEVEL_FATAL:
346*18de8d7fSPeter Avalos 		if (!log_on_stderr)
347*18de8d7fSPeter Avalos 			txt = "fatal";
348*18de8d7fSPeter Avalos 		pri = LOG_CRIT;
349*18de8d7fSPeter Avalos 		break;
350*18de8d7fSPeter Avalos 	case SYSLOG_LEVEL_ERROR:
351*18de8d7fSPeter Avalos 		if (!log_on_stderr)
352*18de8d7fSPeter Avalos 			txt = "error";
353*18de8d7fSPeter Avalos 		pri = LOG_ERR;
354*18de8d7fSPeter Avalos 		break;
355*18de8d7fSPeter Avalos 	case SYSLOG_LEVEL_INFO:
356*18de8d7fSPeter Avalos 		pri = LOG_INFO;
357*18de8d7fSPeter Avalos 		break;
358*18de8d7fSPeter Avalos 	case SYSLOG_LEVEL_VERBOSE:
359*18de8d7fSPeter Avalos 		pri = LOG_INFO;
360*18de8d7fSPeter Avalos 		break;
361*18de8d7fSPeter Avalos 	case SYSLOG_LEVEL_DEBUG1:
362*18de8d7fSPeter Avalos 		txt = "debug1";
363*18de8d7fSPeter Avalos 		pri = LOG_DEBUG;
364*18de8d7fSPeter Avalos 		break;
365*18de8d7fSPeter Avalos 	case SYSLOG_LEVEL_DEBUG2:
366*18de8d7fSPeter Avalos 		txt = "debug2";
367*18de8d7fSPeter Avalos 		pri = LOG_DEBUG;
368*18de8d7fSPeter Avalos 		break;
369*18de8d7fSPeter Avalos 	case SYSLOG_LEVEL_DEBUG3:
370*18de8d7fSPeter Avalos 		txt = "debug3";
371*18de8d7fSPeter Avalos 		pri = LOG_DEBUG;
372*18de8d7fSPeter Avalos 		break;
373*18de8d7fSPeter Avalos 	default:
374*18de8d7fSPeter Avalos 		txt = "internal error";
375*18de8d7fSPeter Avalos 		pri = LOG_ERR;
376*18de8d7fSPeter Avalos 		break;
377*18de8d7fSPeter Avalos 	}
378*18de8d7fSPeter Avalos 	if (txt != NULL) {
379*18de8d7fSPeter Avalos 		snprintf(fmtbuf, sizeof(fmtbuf), "%s: %s", txt, fmt);
380*18de8d7fSPeter Avalos 		vsnprintf(msgbuf, sizeof(msgbuf), fmtbuf, args);
381*18de8d7fSPeter Avalos 	} else {
382*18de8d7fSPeter Avalos 		vsnprintf(msgbuf, sizeof(msgbuf), fmt, args);
383*18de8d7fSPeter Avalos 	}
384*18de8d7fSPeter Avalos 	strnvis(fmtbuf, msgbuf, sizeof(fmtbuf),
385*18de8d7fSPeter Avalos 	    log_on_stderr ? LOG_STDERR_VIS : LOG_SYSLOG_VIS);
386*18de8d7fSPeter Avalos 	if (log_on_stderr) {
387*18de8d7fSPeter Avalos 		snprintf(msgbuf, sizeof msgbuf, "%s\r\n", fmtbuf);
388*18de8d7fSPeter Avalos 		write(STDERR_FILENO, msgbuf, strlen(msgbuf));
389*18de8d7fSPeter Avalos 	} else {
390*18de8d7fSPeter Avalos #if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT)
391*18de8d7fSPeter Avalos 		openlog_r(argv0 ? argv0 : __progname, LOG_PID, log_facility, &sdata);
392*18de8d7fSPeter Avalos 		syslog_r(pri, &sdata, "%.500s", fmtbuf);
393*18de8d7fSPeter Avalos 		closelog_r(&sdata);
394*18de8d7fSPeter Avalos #else
395*18de8d7fSPeter Avalos 		openlog(argv0 ? argv0 : __progname, LOG_PID, log_facility);
396*18de8d7fSPeter Avalos 		syslog(pri, "%.500s", fmtbuf);
397*18de8d7fSPeter Avalos 		closelog();
398*18de8d7fSPeter Avalos #endif
399*18de8d7fSPeter Avalos 	}
400*18de8d7fSPeter Avalos 	errno = saved_errno;
401*18de8d7fSPeter Avalos }
402