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