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