1*4643be29Sbrad /* $OpenBSD: log.c,v 1.3 2005/04/22 00:56:25 brad Exp $ */ 2*4643be29Sbrad 3*4643be29Sbrad /* 4*4643be29Sbrad * log.c 5*4643be29Sbrad * 6*4643be29Sbrad * Based on err.c, which was adapted from OpenBSD libc *err* *warn* code. 7*4643be29Sbrad * 8*4643be29Sbrad * Copyright (c) 2005 Nick Mathewson <nickm@freehaven.net> 9*4643be29Sbrad * 10*4643be29Sbrad * Copyright (c) 2000 Dug Song <dugsong@monkey.org> 11*4643be29Sbrad * 12*4643be29Sbrad * Copyright (c) 1993 13*4643be29Sbrad * The Regents of the University of California. All rights reserved. 14*4643be29Sbrad * 15*4643be29Sbrad * Redistribution and use in source and binary forms, with or without 16*4643be29Sbrad * modification, are permitted provided that the following conditions 17*4643be29Sbrad * are met: 18*4643be29Sbrad * 1. Redistributions of source code must retain the above copyright 19*4643be29Sbrad * notice, this list of conditions and the following disclaimer. 20*4643be29Sbrad * 2. Redistributions in binary form must reproduce the above copyright 21*4643be29Sbrad * notice, this list of conditions and the following disclaimer in the 22*4643be29Sbrad * documentation and/or other materials provided with the distribution. 23*4643be29Sbrad * 3. Neither the name of the University nor the names of its contributors 24*4643be29Sbrad * may be used to endorse or promote products derived from this software 25*4643be29Sbrad * without specific prior written permission. 26*4643be29Sbrad * 27*4643be29Sbrad * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 28*4643be29Sbrad * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29*4643be29Sbrad * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30*4643be29Sbrad * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 31*4643be29Sbrad * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32*4643be29Sbrad * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33*4643be29Sbrad * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34*4643be29Sbrad * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35*4643be29Sbrad * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36*4643be29Sbrad * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37*4643be29Sbrad * SUCH DAMAGE. 38*4643be29Sbrad */ 39*4643be29Sbrad 40*4643be29Sbrad #ifdef HAVE_CONFIG_H 41*4643be29Sbrad #include "config.h" 42*4643be29Sbrad #endif 43*4643be29Sbrad 44*4643be29Sbrad #ifdef WIN32 45*4643be29Sbrad #define WIN32_LEAN_AND_MEAN 46*4643be29Sbrad #include <windows.h> 47*4643be29Sbrad #undef WIN32_LEAN_AND_MEAN 48*4643be29Sbrad #include "misc.h" 49*4643be29Sbrad #endif 50*4643be29Sbrad #include <sys/types.h> 51*4643be29Sbrad #include <sys/tree.h> 52*4643be29Sbrad #ifdef HAVE_SYS_TIME_H 53*4643be29Sbrad #include <sys/time.h> 54*4643be29Sbrad #else 55*4643be29Sbrad #include <sys/_time.h> 56*4643be29Sbrad #endif 57*4643be29Sbrad #include <stdio.h> 58*4643be29Sbrad #include <stdlib.h> 59*4643be29Sbrad #include <stdarg.h> 60*4643be29Sbrad #include <string.h> 61*4643be29Sbrad #include <errno.h> 62*4643be29Sbrad #include "event.h" 63*4643be29Sbrad 64*4643be29Sbrad #include "log.h" 65*4643be29Sbrad 66*4643be29Sbrad static void _warn_helper(int severity, int log_errno, const char *fmt, 67*4643be29Sbrad va_list ap); 68*4643be29Sbrad static void event_log(int severity, const char *msg); 69*4643be29Sbrad 70*4643be29Sbrad static int 71*4643be29Sbrad event_vsnprintf(char *str, size_t size, const char *format, va_list args) 72*4643be29Sbrad { 73*4643be29Sbrad int r; 74*4643be29Sbrad if (size == 0) 75*4643be29Sbrad return -1; 76*4643be29Sbrad #ifdef WIN32 77*4643be29Sbrad r = _vsnprintf(str, size, format, args); 78*4643be29Sbrad #else 79*4643be29Sbrad r = vsnprintf(str, size, format, args); 80*4643be29Sbrad #endif 81*4643be29Sbrad str[size-1] = '\0'; 82*4643be29Sbrad if (r < 0 || ((size_t)r) >= size) { 83*4643be29Sbrad /* different platforms behave differently on overflow; 84*4643be29Sbrad * handle both kinds. */ 85*4643be29Sbrad return -1; 86*4643be29Sbrad } 87*4643be29Sbrad return r; 88*4643be29Sbrad } 89*4643be29Sbrad 90*4643be29Sbrad void 91*4643be29Sbrad event_err(int eval, const char *fmt, ...) 92*4643be29Sbrad { 93*4643be29Sbrad va_list ap; 94*4643be29Sbrad 95*4643be29Sbrad va_start(ap, fmt); 96*4643be29Sbrad _warn_helper(_EVENT_LOG_ERR, errno, fmt, ap); 97*4643be29Sbrad va_end(ap); 98*4643be29Sbrad exit(eval); 99*4643be29Sbrad } 100*4643be29Sbrad 101*4643be29Sbrad void 102*4643be29Sbrad event_warn(const char *fmt, ...) 103*4643be29Sbrad { 104*4643be29Sbrad va_list ap; 105*4643be29Sbrad 106*4643be29Sbrad va_start(ap, fmt); 107*4643be29Sbrad _warn_helper(_EVENT_LOG_WARN, errno, fmt, ap); 108*4643be29Sbrad va_end(ap); 109*4643be29Sbrad } 110*4643be29Sbrad 111*4643be29Sbrad void 112*4643be29Sbrad event_errx(int eval, const char *fmt, ...) 113*4643be29Sbrad { 114*4643be29Sbrad va_list ap; 115*4643be29Sbrad 116*4643be29Sbrad va_start(ap, fmt); 117*4643be29Sbrad _warn_helper(_EVENT_LOG_ERR, -1, fmt, ap); 118*4643be29Sbrad va_end(ap); 119*4643be29Sbrad exit(eval); 120*4643be29Sbrad } 121*4643be29Sbrad 122*4643be29Sbrad void 123*4643be29Sbrad event_warnx(const char *fmt, ...) 124*4643be29Sbrad { 125*4643be29Sbrad va_list ap; 126*4643be29Sbrad 127*4643be29Sbrad va_start(ap, fmt); 128*4643be29Sbrad _warn_helper(_EVENT_LOG_WARN, -1, fmt, ap); 129*4643be29Sbrad va_end(ap); 130*4643be29Sbrad } 131*4643be29Sbrad 132*4643be29Sbrad void 133*4643be29Sbrad event_msgx(const char *fmt, ...) 134*4643be29Sbrad { 135*4643be29Sbrad va_list ap; 136*4643be29Sbrad 137*4643be29Sbrad va_start(ap, fmt); 138*4643be29Sbrad _warn_helper(_EVENT_LOG_MSG, -1, fmt, ap); 139*4643be29Sbrad va_end(ap); 140*4643be29Sbrad } 141*4643be29Sbrad 142*4643be29Sbrad void 143*4643be29Sbrad _event_debugx(const char *fmt, ...) 144*4643be29Sbrad { 145*4643be29Sbrad va_list ap; 146*4643be29Sbrad 147*4643be29Sbrad va_start(ap, fmt); 148*4643be29Sbrad _warn_helper(_EVENT_LOG_DEBUG, -1, fmt, ap); 149*4643be29Sbrad va_end(ap); 150*4643be29Sbrad } 151*4643be29Sbrad 152*4643be29Sbrad static void 153*4643be29Sbrad _warn_helper(int severity, int log_errno, const char *fmt, va_list ap) 154*4643be29Sbrad { 155*4643be29Sbrad char buf[1024]; 156*4643be29Sbrad size_t len; 157*4643be29Sbrad 158*4643be29Sbrad if (fmt != NULL) 159*4643be29Sbrad event_vsnprintf(buf, sizeof(buf), fmt, ap); 160*4643be29Sbrad else 161*4643be29Sbrad buf[0] = '\0'; 162*4643be29Sbrad 163*4643be29Sbrad if (log_errno >= 0) { 164*4643be29Sbrad len = strlen(buf); 165*4643be29Sbrad if (len < sizeof(buf) - 3) { 166*4643be29Sbrad snprintf(buf + len, sizeof(buf) - len, ": %s", 167*4643be29Sbrad strerror(log_errno)); 168*4643be29Sbrad } 169*4643be29Sbrad } 170*4643be29Sbrad 171*4643be29Sbrad event_log(severity, buf); 172*4643be29Sbrad } 173*4643be29Sbrad 174*4643be29Sbrad static event_log_cb log_fn = NULL; 175*4643be29Sbrad 176*4643be29Sbrad void 177*4643be29Sbrad event_set_log_callback(event_log_cb cb) 178*4643be29Sbrad { 179*4643be29Sbrad log_fn = cb; 180*4643be29Sbrad } 181*4643be29Sbrad 182*4643be29Sbrad static void 183*4643be29Sbrad event_log(int severity, const char *msg) 184*4643be29Sbrad { 185*4643be29Sbrad if (log_fn) 186*4643be29Sbrad log_fn(severity, msg); 187*4643be29Sbrad else { 188*4643be29Sbrad const char *severity_str; 189*4643be29Sbrad switch (severity) { 190*4643be29Sbrad case _EVENT_LOG_DEBUG: 191*4643be29Sbrad severity_str = "debug"; 192*4643be29Sbrad break; 193*4643be29Sbrad case _EVENT_LOG_MSG: 194*4643be29Sbrad severity_str = "msg"; 195*4643be29Sbrad break; 196*4643be29Sbrad case _EVENT_LOG_WARN: 197*4643be29Sbrad severity_str = "warn"; 198*4643be29Sbrad break; 199*4643be29Sbrad case _EVENT_LOG_ERR: 200*4643be29Sbrad severity_str = "err"; 201*4643be29Sbrad break; 202*4643be29Sbrad default: 203*4643be29Sbrad severity_str = "???"; 204*4643be29Sbrad break; 205*4643be29Sbrad } 206*4643be29Sbrad (void)fprintf(stderr, "[%s] %s\n", severity_str, msg); 207*4643be29Sbrad } 208*4643be29Sbrad } 209