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