1171169Smlaier/*	$OpenBSD: err.c,v 1.2 2002/06/25 15:50:15 mickey Exp $	*/
2171169Smlaier
3171169Smlaier/*
4171169Smlaier * log.c
5171169Smlaier *
6171169Smlaier * Based on err.c, which was adapted from OpenBSD libc *err* *warn* code.
7171169Smlaier *
8171169Smlaier * Copyright (c) 2005 Nick Mathewson <nickm@freehaven.net>
9171169Smlaier *
10171169Smlaier * Copyright (c) 2000 Dug Song <dugsong@monkey.org>
11171169Smlaier *
12171169Smlaier * Copyright (c) 1993
13171169Smlaier *	The Regents of the University of California.  All rights reserved.
14171169Smlaier *
15171169Smlaier * Redistribution and use in source and binary forms, with or without
16171169Smlaier * modification, are permitted provided that the following conditions
17171169Smlaier * are met:
18171169Smlaier * 1. Redistributions of source code must retain the above copyright
19171169Smlaier *    notice, this list of conditions and the following disclaimer.
20171169Smlaier * 2. Redistributions in binary form must reproduce the above copyright
21171169Smlaier *    notice, this list of conditions and the following disclaimer in the
22171169Smlaier *    documentation and/or other materials provided with the distribution.
23171169Smlaier * 3. Neither the name of the University nor the names of its contributors
24171169Smlaier *    may be used to endorse or promote products derived from this software
25171169Smlaier *    without specific prior written permission.
26171169Smlaier *
27171169Smlaier * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28171169Smlaier * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29171169Smlaier * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30171169Smlaier * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31171169Smlaier * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32171169Smlaier * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33171169Smlaier * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34171169Smlaier * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35171169Smlaier * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36171169Smlaier * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37171169Smlaier * SUCH DAMAGE.
38171169Smlaier */
39171169Smlaier
40171169Smlaier#ifdef HAVE_CONFIG_H
41171169Smlaier#include "config.h"
42171169Smlaier#endif
43171169Smlaier
44171169Smlaier#ifdef WIN32
45171169Smlaier#define WIN32_LEAN_AND_MEAN
46171169Smlaier#include <windows.h>
47171169Smlaier#undef WIN32_LEAN_AND_MEAN
48171169Smlaier#include "misc.h"
49171169Smlaier#endif
50171169Smlaier#include <sys/types.h>
51171169Smlaier#include <sys/tree.h>
52171169Smlaier#ifdef HAVE_SYS_TIME_H
53171169Smlaier#include <sys/time.h>
54171169Smlaier#else
55171169Smlaier#include <sys/_time.h>
56171169Smlaier#endif
57171169Smlaier#include <stdio.h>
58171169Smlaier#include <stdlib.h>
59171169Smlaier#include <stdarg.h>
60171169Smlaier#include <string.h>
61171169Smlaier#include <errno.h>
62171169Smlaier#include "event.h"
63171169Smlaier
64171169Smlaier#include "log.h"
65171169Smlaier
66171169Smlaierstatic void _warn_helper(int severity, int log_errno, const char *fmt,
67171169Smlaier                         va_list ap);
68171169Smlaierstatic void event_log(int severity, const char *msg);
69171169Smlaier
70171169Smlaierstatic int
71171169Smlaierevent_vsnprintf(char *str, size_t size, const char *format, va_list args)
72171169Smlaier{
73171169Smlaier	int r;
74171169Smlaier	if (size == 0)
75171169Smlaier		return -1;
76171169Smlaier#ifdef WIN32
77171169Smlaier	r = _vsnprintf(str, size, format, args);
78171169Smlaier#else
79171169Smlaier	r = vsnprintf(str, size, format, args);
80171169Smlaier#endif
81171169Smlaier	str[size-1] = '\0';
82171169Smlaier	if (r < 0 || ((size_t)r) >= size) {
83171169Smlaier		/* different platforms behave differently on overflow;
84171169Smlaier		 * handle both kinds. */
85171169Smlaier		return -1;
86171169Smlaier	}
87171169Smlaier	return r;
88171169Smlaier}
89171169Smlaier
90171169Smlaierstatic int
91171169Smlaierevent_snprintf(char *str, size_t size, const char *format, ...)
92171169Smlaier{
93171169Smlaier    va_list ap;
94171169Smlaier    int r;
95171169Smlaier    va_start(ap, format);
96171169Smlaier    r = event_vsnprintf(str, size, format, ap);
97171169Smlaier    va_end(ap);
98171169Smlaier    return r;
99171169Smlaier}
100171169Smlaier
101171169Smlaiervoid
102171169Smlaierevent_err(int eval, const char *fmt, ...)
103171169Smlaier{
104171169Smlaier	va_list ap;
105171169Smlaier
106171169Smlaier	va_start(ap, fmt);
107171169Smlaier	_warn_helper(_EVENT_LOG_ERR, errno, fmt, ap);
108171169Smlaier	va_end(ap);
109171169Smlaier	exit(eval);
110171169Smlaier}
111171169Smlaier
112171169Smlaiervoid
113171169Smlaierevent_warn(const char *fmt, ...)
114171169Smlaier{
115171169Smlaier	va_list ap;
116171169Smlaier
117171169Smlaier	va_start(ap, fmt);
118171169Smlaier	_warn_helper(_EVENT_LOG_WARN, errno, fmt, ap);
119171169Smlaier	va_end(ap);
120171169Smlaier}
121171169Smlaier
122171169Smlaiervoid
123171169Smlaierevent_errx(int eval, const char *fmt, ...)
124171169Smlaier{
125171169Smlaier	va_list ap;
126171169Smlaier
127171169Smlaier	va_start(ap, fmt);
128171169Smlaier	_warn_helper(_EVENT_LOG_ERR, -1, fmt, ap);
129171169Smlaier	va_end(ap);
130171169Smlaier	exit(eval);
131171169Smlaier}
132171169Smlaier
133171169Smlaiervoid
134171169Smlaierevent_warnx(const char *fmt, ...)
135171169Smlaier{
136171169Smlaier	va_list ap;
137171169Smlaier
138171169Smlaier	va_start(ap, fmt);
139171169Smlaier	_warn_helper(_EVENT_LOG_WARN, -1, fmt, ap);
140171169Smlaier	va_end(ap);
141171169Smlaier}
142171169Smlaier
143171169Smlaiervoid
144171169Smlaierevent_msgx(const char *fmt, ...)
145171169Smlaier{
146171169Smlaier	va_list ap;
147171169Smlaier
148171169Smlaier	va_start(ap, fmt);
149171169Smlaier	_warn_helper(_EVENT_LOG_MSG, -1, fmt, ap);
150171169Smlaier	va_end(ap);
151171169Smlaier}
152171169Smlaier
153171169Smlaiervoid
154171169Smlaier_event_debugx(const char *fmt, ...)
155171169Smlaier{
156171169Smlaier	va_list ap;
157171169Smlaier
158171169Smlaier	va_start(ap, fmt);
159171169Smlaier	_warn_helper(_EVENT_LOG_DEBUG, -1, fmt, ap);
160171169Smlaier	va_end(ap);
161171169Smlaier}
162171169Smlaier
163171169Smlaierstatic void
164171169Smlaier_warn_helper(int severity, int log_errno, const char *fmt, va_list ap)
165171169Smlaier{
166171169Smlaier	char buf[1024];
167171169Smlaier	size_t len;
168171169Smlaier
169171169Smlaier	if (fmt != NULL)
170171169Smlaier		event_vsnprintf(buf, sizeof(buf), fmt, ap);
171171169Smlaier	else
172171169Smlaier		buf[0] = '\0';
173171169Smlaier
174171169Smlaier	if (log_errno >= 0) {
175171169Smlaier		len = strlen(buf);
176171169Smlaier		if (len < sizeof(buf) - 3) {
177171169Smlaier			event_snprintf(buf + len, sizeof(buf) - len, ": %s",
178171169Smlaier			    strerror(log_errno));
179171169Smlaier		}
180171169Smlaier	}
181171169Smlaier
182171169Smlaier	event_log(severity, buf);
183171169Smlaier}
184171169Smlaier
185171169Smlaierstatic event_log_cb log_fn = NULL;
186171169Smlaier
187171169Smlaiervoid
188171169Smlaierevent_set_log_callback(event_log_cb cb)
189171169Smlaier{
190171169Smlaier	log_fn = cb;
191171169Smlaier}
192171169Smlaier
193171169Smlaierstatic void
194171169Smlaierevent_log(int severity, const char *msg)
195171169Smlaier{
196171169Smlaier	if (log_fn)
197171169Smlaier		log_fn(severity, msg);
198171169Smlaier	else {
199171169Smlaier		const char *severity_str;
200171169Smlaier		switch (severity) {
201171169Smlaier		case _EVENT_LOG_DEBUG:
202171169Smlaier			severity_str = "debug";
203171169Smlaier			break;
204171169Smlaier		case _EVENT_LOG_MSG:
205171169Smlaier			severity_str = "msg";
206171169Smlaier			break;
207171169Smlaier		case _EVENT_LOG_WARN:
208171169Smlaier			severity_str = "warn";
209171169Smlaier			break;
210171169Smlaier		case _EVENT_LOG_ERR:
211171169Smlaier			severity_str = "err";
212171169Smlaier			break;
213171169Smlaier		default:
214171169Smlaier			severity_str = "???";
215171169Smlaier			break;
216171169Smlaier		}
217171169Smlaier		(void)fprintf(stderr, "[%s] %s\n", severity_str, msg);
218171169Smlaier	}
219171169Smlaier}
220