1*2aa5774dSbluhm /* $OpenBSD: log.c,v 1.2 2017/03/13 21:20:56 bluhm Exp $ */ 2*2aa5774dSbluhm 3b034567aSjca /* 4b034567aSjca * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> 5b034567aSjca * 6b034567aSjca * Permission to use, copy, modify, and distribute this software for any 7b034567aSjca * purpose with or without fee is hereby granted, provided that the above 8b034567aSjca * copyright notice and this permission notice appear in all copies. 9b034567aSjca * 10b034567aSjca * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11b034567aSjca * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12b034567aSjca * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13b034567aSjca * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14b034567aSjca * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15b034567aSjca * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16b034567aSjca * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17b034567aSjca */ 18b034567aSjca 19b034567aSjca #include <err.h> 20b034567aSjca #include <errno.h> 21b034567aSjca #include <netdb.h> 22b034567aSjca #include <stdarg.h> 23b034567aSjca #include <stdio.h> 24b034567aSjca #include <stdlib.h> 25b034567aSjca #include <string.h> 26b034567aSjca #include <syslog.h> 27b034567aSjca #include <time.h> 28b034567aSjca #include <unistd.h> 29b034567aSjca 30b034567aSjca #include "log.h" 31b034567aSjca 32b034567aSjca static int debug; 33b034567aSjca 34b034567aSjca static char *logqueue; 35b034567aSjca 36b034567aSjca #define LOGQUEUE_SIZE 1024 37b034567aSjca 38b034567aSjca void logit(int, const char *, ...); 39b034567aSjca void vlog(int pri, const char *fmt, va_list ap); 40b034567aSjca 41b034567aSjca void 42b034567aSjca log_init(int n_debug) 43b034567aSjca { 44b034567aSjca extern char *__progname; 45b034567aSjca 46b034567aSjca if (logqueue == NULL) { 47b034567aSjca logqueue = calloc(LOGQUEUE_SIZE, 1); 48b034567aSjca if (logqueue == NULL) 49b034567aSjca err(1, NULL); 50b034567aSjca } 51b034567aSjca 52b034567aSjca debug = n_debug; 53b034567aSjca 54b034567aSjca if (!debug) 55b034567aSjca openlog(__progname, LOG_PID | LOG_NDELAY, LOG_DAEMON); 56b034567aSjca 57b034567aSjca tzset(); 58b034567aSjca } 59b034567aSjca 60b034567aSjca void 61b034567aSjca logit(int pri, const char *fmt, ...) 62b034567aSjca { 63b034567aSjca va_list ap; 64b034567aSjca 65b034567aSjca va_start(ap, fmt); 66b034567aSjca vlog(pri, fmt, ap); 67b034567aSjca va_end(ap); 68b034567aSjca } 69b034567aSjca 70b034567aSjca void 71b034567aSjca log_enqueue(const char *fmt, ...) 72b034567aSjca { 73b034567aSjca char tmpbuf[LOGQUEUE_SIZE]; 74b034567aSjca va_list ap; 75b034567aSjca 76b034567aSjca va_start(ap, fmt); 77b034567aSjca (void)vsnprintf(tmpbuf, sizeof(tmpbuf), fmt, ap); 78b034567aSjca va_end(ap); 79b034567aSjca (void)strlcat(logqueue, tmpbuf, LOGQUEUE_SIZE); 80b034567aSjca } 81b034567aSjca 82b034567aSjca 83b034567aSjca void 84b034567aSjca vlog(int pri, const char *fmt, va_list ap) 85b034567aSjca { 86b034567aSjca char tmpbuf[1024]; 87b034567aSjca char logbuf[LOGQUEUE_SIZE + sizeof(tmpbuf)]; 88b034567aSjca 89b034567aSjca if (pri == LOG_DEBUG && !debug) { 90b034567aSjca logqueue[0] = '\0'; 91b034567aSjca return; 92b034567aSjca } 93b034567aSjca 94b034567aSjca (void)vsnprintf(tmpbuf, sizeof(tmpbuf), fmt, ap); 95b034567aSjca (void)strlcpy(logbuf, logqueue, sizeof(logbuf)); 96b034567aSjca (void)strlcat(logbuf, tmpbuf, sizeof(tmpbuf)); 97b034567aSjca 98b034567aSjca logqueue[0] = '\0'; 99b034567aSjca 100b034567aSjca if (debug) { 101b034567aSjca fprintf(stderr, "%s\n", logbuf); 102b034567aSjca fflush(stderr); 103b034567aSjca } else 104b034567aSjca syslog(pri, "%s", logbuf); 105b034567aSjca } 106b034567aSjca 107b034567aSjca void 108b034567aSjca log_warn(const char *emsg, ...) 109b034567aSjca { 110b034567aSjca char *nfmt; 111b034567aSjca va_list ap; 112b034567aSjca 113b034567aSjca if (emsg == NULL) 114b034567aSjca logit(LOG_CRIT, "%s", strerror(errno)); 115b034567aSjca else { 116b034567aSjca va_start(ap, emsg); 117b034567aSjca 118b034567aSjca /* best effort to even work in out of memory situations */ 119b034567aSjca if (asprintf(&nfmt, "%s: %s", emsg, strerror(errno)) == -1) { 120b034567aSjca /* we tried it... */ 121b034567aSjca vlog(LOG_CRIT, emsg, ap); 122b034567aSjca logit(LOG_CRIT, "%s", strerror(errno)); 123b034567aSjca } else { 124b034567aSjca vlog(LOG_CRIT, nfmt, ap); 125b034567aSjca free(nfmt); 126b034567aSjca } 127b034567aSjca va_end(ap); 128b034567aSjca } 129b034567aSjca } 130b034567aSjca 131b034567aSjca void 132b034567aSjca log_warnx(const char *emsg, ...) 133b034567aSjca { 134b034567aSjca va_list ap; 135b034567aSjca 136b034567aSjca va_start(ap, emsg); 137b034567aSjca vlog(LOG_CRIT, emsg, ap); 138b034567aSjca va_end(ap); 139b034567aSjca } 140b034567aSjca 141b034567aSjca void 142b034567aSjca log_info(const char *emsg, ...) 143b034567aSjca { 144b034567aSjca va_list ap; 145b034567aSjca 146b034567aSjca va_start(ap, emsg); 147b034567aSjca vlog(LOG_INFO, emsg, ap); 148b034567aSjca va_end(ap); 149b034567aSjca } 150b034567aSjca 151b034567aSjca void 152b034567aSjca log_debug(const char *emsg, ...) 153b034567aSjca { 154b034567aSjca va_list ap; 155b034567aSjca 156b034567aSjca va_start(ap, emsg); 157b034567aSjca vlog(LOG_DEBUG, emsg, ap); 158b034567aSjca va_end(ap); 159b034567aSjca } 160b034567aSjca 161b034567aSjca void 162b034567aSjca fatal(const char *emsg) 163b034567aSjca { 164b034567aSjca extern char *__progname; 165b034567aSjca extern __dead void rtdexit(void); 166b034567aSjca 167b034567aSjca if (emsg == NULL) 168b034567aSjca logit(LOG_CRIT, "fatal in %s: %s", __progname, 169b034567aSjca strerror(errno)); 170b034567aSjca else 171b034567aSjca if (errno) 172b034567aSjca logit(LOG_CRIT, "fatal in %s: %s: %s", 173b034567aSjca __progname, emsg, strerror(errno)); 174b034567aSjca else 175b034567aSjca logit(LOG_CRIT, "fatal in %s: %s", 176b034567aSjca __progname, emsg); 177b034567aSjca 178b034567aSjca rtdexit(); 179b034567aSjca } 180b034567aSjca 181b034567aSjca void 182b034567aSjca fatalx(const char *emsg) 183b034567aSjca { 184b034567aSjca errno = 0; 185b034567aSjca fatal(emsg); 186b034567aSjca } 187