1 /* $OpenBSD: log.c,v 1.4 2017/04/28 14:52:13 bluhm Exp $ */ 2 3 /* 4 * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> 5 * Copyright (c) 2017 Alexander Bluhm <bluhm@openbsd.org> 6 * 7 * Permission to use, copy, modify, and distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 #include <err.h> 21 #include <errno.h> 22 #include <stdio.h> 23 #include <stdlib.h> 24 #include <string.h> 25 #include <syslog.h> 26 #include <time.h> 27 28 #include "log.h" 29 #include "syslogd.h" 30 31 static int verbose; 32 static int facility; 33 static const char *log_procname; 34 static char *debug_ebuf; 35 static size_t debug_length; 36 37 void 38 log_init(int n_debug, int fac) 39 { 40 extern char *__progname; 41 42 verbose = n_debug; 43 facility = fac; 44 log_procinit(__progname); 45 46 if (debug_ebuf == NULL) 47 if ((debug_ebuf = malloc(ERRBUFSIZE)) == NULL) 48 err(1, "allocate debug buffer"); 49 debug_ebuf[0] = '\0'; 50 debug_length = 0; 51 52 tzset(); 53 } 54 55 void 56 log_procinit(const char *procname) 57 { 58 if (procname != NULL) 59 log_procname = procname; 60 } 61 62 void 63 log_setverbose(int v) 64 { 65 verbose = v; 66 } 67 68 int 69 log_getverbose(void) 70 { 71 return (verbose); 72 } 73 74 void 75 logit(int pri, const char *fmt, ...) 76 { 77 va_list ap; 78 79 va_start(ap, fmt); 80 vlog(pri, fmt, ap); 81 va_end(ap); 82 } 83 84 void 85 vlog(int pri, const char *fmt, va_list ap) 86 { 87 int saved_errno = errno; 88 89 vlogmsg(facility|pri, log_procname, fmt, ap); 90 91 errno = saved_errno; 92 } 93 94 void 95 log_warn(const char *emsg, ...) 96 { 97 char ebuf[ERRBUFSIZE]; 98 size_t l; 99 va_list ap; 100 int saved_errno = errno; 101 102 /* best effort to even work in out of memory situations */ 103 if (emsg == NULL) 104 logit(LOG_ERR, "%s", strerror(saved_errno)); 105 else { 106 va_start(ap, emsg); 107 l = vsnprintf(ebuf, sizeof(ebuf), emsg, ap); 108 if (l < sizeof(ebuf)) 109 snprintf(ebuf+l, sizeof(ebuf)-l, ": %s", 110 strerror(saved_errno)); 111 logit(LOG_ERR, "%s", ebuf); 112 va_end(ap); 113 } 114 errno = saved_errno; 115 } 116 117 void 118 log_warnx(const char *emsg, ...) 119 { 120 va_list ap; 121 122 va_start(ap, emsg); 123 vlog(LOG_ERR, emsg, ap); 124 va_end(ap); 125 } 126 127 void 128 log_info(int pri, const char *emsg, ...) 129 { 130 va_list ap; 131 132 va_start(ap, emsg); 133 vlog(pri, emsg, ap); 134 va_end(ap); 135 } 136 137 void 138 log_debug(const char *emsg, ...) 139 { 140 va_list ap; 141 int saved_errno; 142 143 if (verbose) { 144 saved_errno = errno; 145 va_start(ap, emsg); 146 if (debug_length < ERRBUFSIZE - 1) 147 vsnprintf(debug_ebuf + debug_length, 148 ERRBUFSIZE - debug_length, emsg, ap); 149 fprintf(stderr, "%s\n", debug_ebuf); 150 fflush(stderr); 151 va_end(ap); 152 errno = saved_errno; 153 } 154 debug_ebuf[0] = '\0'; 155 debug_length = 0; 156 } 157 158 void 159 log_debugadd(const char *emsg, ...) 160 { 161 size_t l; 162 va_list ap; 163 int saved_errno; 164 165 if (verbose) { 166 saved_errno = errno; 167 va_start(ap, emsg); 168 if (debug_length < ERRBUFSIZE - 1) { 169 l = vsnprintf(debug_ebuf + debug_length, 170 ERRBUFSIZE - debug_length, emsg, ap); 171 if (l < ERRBUFSIZE - debug_length) 172 debug_length += l; 173 else 174 debug_length = ERRBUFSIZE - 1; 175 } 176 va_end(ap); 177 errno = saved_errno; 178 } 179 } 180 181 static void 182 vfatalc(int error, const char *emsg, va_list ap) 183 { 184 char ebuf[ERRBUFSIZE]; 185 const char *sep; 186 187 if (emsg != NULL) { 188 (void)vsnprintf(ebuf, sizeof(ebuf), emsg, ap); 189 sep = ": "; 190 } else { 191 ebuf[0] = '\0'; 192 sep = ""; 193 } 194 if (error) 195 logit(LOG_CRIT, "fatal in %s: %s%s%s", 196 log_procname, ebuf, sep, strerror(error)); 197 else 198 logit(LOG_CRIT, "fatal in %s%s%s", log_procname, sep, ebuf); 199 } 200 201 void 202 fatal(const char *emsg, ...) 203 { 204 va_list ap; 205 206 va_start(ap, emsg); 207 vfatalc(errno, emsg, ap); 208 va_end(ap); 209 die(0); 210 } 211 212 void 213 fatalx(const char *emsg, ...) 214 { 215 va_list ap; 216 217 va_start(ap, emsg); 218 vfatalc(0, emsg, ap); 219 va_end(ap); 220 die(0); 221 } 222