1 /* $OpenBSD: log.c,v 1.5 2011/08/20 19:03:39 sthen Exp $ */ 2 3 /* 4 * Copyright (c) 2009 Claudio Jeker <claudio@openbsd.org> 5 * Copyright (c) 2003, 2004 Henning Brauer <henning@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 #include <sys/types.h> 20 #include <sys/queue.h> 21 #include <sys/socket.h> 22 #include <sys/uio.h> 23 24 #include <scsi/iscsi.h> 25 26 #include <errno.h> 27 #include <event.h> 28 #include <netdb.h> 29 #include <stdarg.h> 30 #include <stdio.h> 31 #include <stdlib.h> 32 #include <string.h> 33 #include <syslog.h> 34 #include <unistd.h> 35 36 #include "iscsid.h" 37 #include "log.h" 38 39 int debug; 40 int verbose; 41 42 void logit(int, const char *, ...); 43 44 void 45 log_init(int n_debug) 46 { 47 extern char *__progname; 48 49 debug = n_debug; 50 51 if (!debug) 52 openlog(__progname, LOG_PID | LOG_NDELAY, LOG_DAEMON); 53 54 tzset(); 55 } 56 57 void 58 log_verbose(int v) 59 { 60 verbose = v; 61 } 62 63 void 64 logit(int pri, const char *fmt, ...) 65 { 66 va_list ap; 67 68 va_start(ap, fmt); 69 vlog(pri, fmt, ap); 70 va_end(ap); 71 } 72 73 void 74 vlog(int pri, const char *fmt, va_list ap) 75 { 76 char *nfmt; 77 78 if (debug) { 79 /* best effort in out of mem situations */ 80 if (asprintf(&nfmt, "%s\n", fmt) == -1) { 81 vfprintf(stderr, fmt, ap); 82 fprintf(stderr, "\n"); 83 } else { 84 vfprintf(stderr, nfmt, ap); 85 free(nfmt); 86 } 87 fflush(stderr); 88 } else 89 vsyslog(pri, fmt, ap); 90 } 91 92 void 93 log_warn(const char *emsg, ...) 94 { 95 char *nfmt; 96 va_list ap; 97 98 /* best effort to even work in out of memory situations */ 99 if (emsg == NULL) 100 logit(LOG_CRIT, "%s", strerror(errno)); 101 else { 102 va_start(ap, emsg); 103 104 if (asprintf(&nfmt, "%s: %s", emsg, strerror(errno)) == -1) { 105 /* we tried it... */ 106 vlog(LOG_CRIT, emsg, ap); 107 logit(LOG_CRIT, "%s", strerror(errno)); 108 } else { 109 vlog(LOG_CRIT, nfmt, ap); 110 free(nfmt); 111 } 112 va_end(ap); 113 } 114 } 115 116 void 117 log_warnx(const char *emsg, ...) 118 { 119 va_list ap; 120 121 va_start(ap, emsg); 122 vlog(LOG_CRIT, emsg, ap); 123 va_end(ap); 124 } 125 126 void 127 log_info(const char *emsg, ...) 128 { 129 va_list ap; 130 131 va_start(ap, emsg); 132 vlog(LOG_INFO, emsg, ap); 133 va_end(ap); 134 } 135 136 void 137 log_debug(const char *emsg, ...) 138 { 139 va_list ap; 140 141 if (verbose) { 142 va_start(ap, emsg); 143 vlog(LOG_DEBUG, emsg, ap); 144 va_end(ap); 145 } 146 } 147 148 void 149 fatal(const char *emsg) 150 { 151 if (emsg == NULL) 152 logit(LOG_CRIT, "fatal: %s", strerror(errno)); 153 else 154 if (errno) 155 logit(LOG_CRIT, "fatal: %s: %s", emsg, strerror(errno)); 156 else 157 logit(LOG_CRIT, "fatal: %s", emsg); 158 159 exit(1); 160 } 161 162 void 163 fatalx(const char *emsg) 164 { 165 errno = 0; 166 fatal(emsg); 167 } 168 169 void 170 log_hexdump(void *buf, size_t len) 171 { 172 u_char b[16]; 173 size_t i, j, l; 174 175 if (!debug) 176 return; 177 178 for (i = 0; i < len; i += l) { 179 fprintf(stderr, "%4zi:", i); 180 l = sizeof(b) < len - i ? sizeof(b) : len - i; 181 bcopy((char *)buf + i, b, l); 182 183 for (j = 0; j < sizeof(b); j++) { 184 if (j % 2 == 0) 185 fprintf(stderr, " "); 186 if (j % 8 == 0) 187 fprintf(stderr, " "); 188 if (j < l) 189 fprintf(stderr, "%02x", (int)b[j]); 190 else 191 fprintf(stderr, " "); 192 } 193 fprintf(stderr, " |"); 194 for (j = 0; j < l; j++) { 195 if (b[j] >= 0x20 && b[j] <= 0x7e) 196 fprintf(stderr, "%c", b[j]); 197 else 198 fprintf(stderr, "."); 199 } 200 fprintf(stderr, "|\n"); 201 } 202 } 203 204 void 205 log_pdu(struct pdu *p, int all) 206 { 207 struct iscsi_pdu *pdu; 208 void *b; 209 size_t s; 210 211 if (!debug) 212 return; 213 214 if (!(pdu = pdu_getbuf(p, NULL, PDU_HEADER))) { 215 log_debug("empty pdu"); 216 return; 217 } 218 219 fprintf(stderr, "PDU: op %x%s flags %02x%02x%02x ahs %d len %d\n", 220 ISCSI_PDU_OPCODE(pdu->opcode), ISCSI_PDU_I(pdu) ? " I" : "", 221 pdu->flags, pdu->_reserved1[0], pdu->_reserved1[1], 222 pdu->ahslen, pdu->datalen[0] << 16 | pdu->datalen[1] << 8 | 223 pdu->datalen[2]); 224 fprintf(stderr, " lun %02x%02x%02x%02x%02x%02x%02x%02x itt %u " 225 "cmdsn %u expstatsn %u\n", pdu->lun[0], pdu->lun[1], pdu->lun[2], 226 pdu->lun[3], pdu->lun[4], pdu->lun[5], pdu->lun[6], pdu->lun[7], 227 ntohl(pdu->itt), ntohl(pdu->cmdsn), ntohl(pdu->expstatsn)); 228 log_hexdump(pdu, sizeof(*pdu)); 229 230 if (all && (b = pdu_getbuf(p, &s, PDU_DATA))) 231 log_hexdump(b, s); 232 } 233