1 1.3 christos /* $NetBSD: log.c,v 1.3 2018/01/13 12:36:35 christos Exp $ */ 2 1.1 christos 3 1.1 christos /*- 4 1.1 christos * Copyright (c) 2017 The NetBSD Foundation, Inc. 5 1.1 christos * Copyright (c) 2016 The DragonFly Project 6 1.1 christos * Copyright (c) 2012 The FreeBSD Foundation 7 1.1 christos * All rights reserved. 8 1.1 christos * 9 1.1 christos * This code is derived from software contributed to The NetBSD Foundation 10 1.1 christos * by Tomohiro Kusumi <kusumi.tomohiro (at) gmail.com>. 11 1.1 christos * 12 1.1 christos * This software was developed by Edward Tomasz Napierala under sponsorship 13 1.1 christos * from the FreeBSD Foundation. 14 1.1 christos * 15 1.1 christos * Redistribution and use in source and binary forms, with or without 16 1.1 christos * modification, are permitted provided that the following conditions 17 1.1 christos * are met: 18 1.1 christos * 1. Redistributions of source code must retain the above copyright 19 1.1 christos * notice, this list of conditions and the following disclaimer. 20 1.1 christos * 2. Redistributions in binary form must reproduce the above copyright 21 1.1 christos * notice, this list of conditions and the following disclaimer in the 22 1.1 christos * documentation and/or other materials provided with the distribution. 23 1.1 christos * 24 1.1 christos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 25 1.1 christos * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 1.1 christos * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 1.1 christos * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 28 1.1 christos * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 1.1 christos * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 1.1 christos * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 1.1 christos * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 1.1 christos * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 1.1 christos * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 1.1 christos * SUCH DAMAGE. 35 1.1 christos * 36 1.1 christos */ 37 1.1 christos #include <sys/cdefs.h> 38 1.3 christos __RCSID("$NetBSD: log.c,v 1.3 2018/01/13 12:36:35 christos Exp $"); 39 1.1 christos 40 1.1 christos #include <errno.h> 41 1.1 christos #include <stdarg.h> 42 1.1 christos #include <stdio.h> 43 1.1 christos #include <stdlib.h> 44 1.1 christos #include <string.h> 45 1.1 christos #include <syslog.h> 46 1.1 christos #include <vis.h> 47 1.1 christos 48 1.1 christos #include "common.h" 49 1.1 christos 50 1.1 christos static int log_level = 0; 51 1.1 christos static char *peer_name = NULL; 52 1.1 christos static char *peer_addr = NULL; 53 1.1 christos 54 1.1 christos #define MSGBUF_LEN 1024 55 1.1 christos 56 1.1 christos void 57 1.1 christos log_init(int level) 58 1.1 christos { 59 1.1 christos 60 1.1 christos log_level = level; 61 1.1 christos openlog(getprogname(), LOG_NDELAY | LOG_PID, LOG_DAEMON); 62 1.1 christos } 63 1.1 christos 64 1.1 christos void 65 1.1 christos log_set_peer_name(const char *name) 66 1.1 christos { 67 1.1 christos 68 1.1 christos /* 69 1.1 christos * XXX: Turn it into assertion? 70 1.1 christos */ 71 1.1 christos if (peer_name != NULL) 72 1.1 christos log_errx(1, "%s called twice", __func__); 73 1.1 christos if (peer_addr == NULL) 74 1.1 christos log_errx(1, "%s called before log_set_peer_addr", __func__); 75 1.1 christos 76 1.1 christos peer_name = checked_strdup(name); 77 1.1 christos } 78 1.1 christos 79 1.1 christos void 80 1.1 christos log_set_peer_addr(const char *addr) 81 1.1 christos { 82 1.1 christos 83 1.1 christos /* 84 1.1 christos * XXX: Turn it into assertion? 85 1.1 christos */ 86 1.1 christos if (peer_addr != NULL) 87 1.1 christos log_errx(1, "%s called twice", __func__); 88 1.1 christos 89 1.1 christos peer_addr = checked_strdup(addr); 90 1.1 christos } 91 1.1 christos 92 1.2 christos static __printflike(3, 0) void 93 1.1 christos log_common(int priority, int log_errno, const char *fmt, va_list ap) 94 1.1 christos { 95 1.1 christos static char msgbuf[MSGBUF_LEN]; 96 1.1 christos static char msgbuf_strvised[MSGBUF_LEN * 4 + 1]; 97 1.1 christos char *errstr; 98 1.1 christos int ret; 99 1.1 christos 100 1.1 christos ret = vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap); 101 1.1 christos if (ret < 0) { 102 1.1 christos fprintf(stderr, "%s: snprintf failed", getprogname()); 103 1.1 christos syslog(LOG_CRIT, "snprintf failed"); 104 1.3 christos exit(EXIT_FAILURE); 105 1.1 christos } 106 1.1 christos 107 1.1 christos ret = strnvis(msgbuf_strvised, sizeof(msgbuf_strvised), msgbuf, VIS_NL); 108 1.1 christos if (ret < 0) { 109 1.1 christos fprintf(stderr, "%s: strnvis failed", getprogname()); 110 1.1 christos syslog(LOG_CRIT, "strnvis failed"); 111 1.3 christos exit(EXIT_FAILURE); 112 1.1 christos } 113 1.1 christos 114 1.1 christos if (log_errno == -1) { 115 1.1 christos if (peer_name != NULL) { 116 1.1 christos fprintf(stderr, "%s: %s (%s): %s\n", getprogname(), 117 1.1 christos peer_addr, peer_name, msgbuf_strvised); 118 1.1 christos syslog(priority, "%s (%s): %s", 119 1.1 christos peer_addr, peer_name, msgbuf_strvised); 120 1.1 christos } else if (peer_addr != NULL) { 121 1.1 christos fprintf(stderr, "%s: %s: %s\n", getprogname(), 122 1.1 christos peer_addr, msgbuf_strvised); 123 1.1 christos syslog(priority, "%s: %s", 124 1.1 christos peer_addr, msgbuf_strvised); 125 1.1 christos } else { 126 1.1 christos fprintf(stderr, "%s: %s\n", getprogname(), 127 1.1 christos msgbuf_strvised); 128 1.1 christos syslog(priority, "%s", msgbuf_strvised); 129 1.1 christos } 130 1.1 christos 131 1.1 christos } else { 132 1.1 christos errstr = strerror(log_errno); 133 1.1 christos 134 1.1 christos if (peer_name != NULL) { 135 1.1 christos fprintf(stderr, "%s: %s (%s): %s: %s\n", getprogname(), 136 1.1 christos peer_addr, peer_name, msgbuf_strvised, errstr); 137 1.1 christos syslog(priority, "%s (%s): %s: %s", 138 1.1 christos peer_addr, peer_name, msgbuf_strvised, errstr); 139 1.1 christos } else if (peer_addr != NULL) { 140 1.1 christos fprintf(stderr, "%s: %s: %s: %s\n", getprogname(), 141 1.1 christos peer_addr, msgbuf_strvised, errstr); 142 1.1 christos syslog(priority, "%s: %s: %s", 143 1.1 christos peer_addr, msgbuf_strvised, errstr); 144 1.1 christos } else { 145 1.1 christos fprintf(stderr, "%s: %s: %s\n", getprogname(), 146 1.1 christos msgbuf_strvised, errstr); 147 1.1 christos syslog(priority, "%s: %s", 148 1.1 christos msgbuf_strvised, errstr); 149 1.1 christos } 150 1.1 christos } 151 1.1 christos } 152 1.1 christos 153 1.3 christos __dead void 154 1.1 christos log_err(int eval, const char *fmt, ...) 155 1.1 christos { 156 1.1 christos va_list ap; 157 1.1 christos 158 1.1 christos va_start(ap, fmt); 159 1.1 christos log_common(LOG_CRIT, errno, fmt, ap); 160 1.1 christos va_end(ap); 161 1.1 christos 162 1.1 christos exit(eval); 163 1.1 christos } 164 1.1 christos 165 1.3 christos __dead void 166 1.1 christos log_errx(int eval, const char *fmt, ...) 167 1.1 christos { 168 1.1 christos va_list ap; 169 1.1 christos 170 1.1 christos va_start(ap, fmt); 171 1.1 christos log_common(LOG_CRIT, -1, fmt, ap); 172 1.1 christos va_end(ap); 173 1.1 christos 174 1.1 christos exit(eval); 175 1.1 christos } 176 1.1 christos 177 1.1 christos void 178 1.1 christos log_warn(const char *fmt, ...) 179 1.1 christos { 180 1.1 christos va_list ap; 181 1.1 christos 182 1.1 christos va_start(ap, fmt); 183 1.1 christos log_common(LOG_WARNING, errno, fmt, ap); 184 1.1 christos va_end(ap); 185 1.1 christos } 186 1.1 christos 187 1.1 christos void 188 1.1 christos log_warnx(const char *fmt, ...) 189 1.1 christos { 190 1.1 christos va_list ap; 191 1.1 christos 192 1.1 christos va_start(ap, fmt); 193 1.1 christos log_common(LOG_WARNING, -1, fmt, ap); 194 1.1 christos va_end(ap); 195 1.1 christos } 196 1.1 christos 197 1.1 christos void 198 1.1 christos log_debugx(const char *fmt, ...) 199 1.1 christos { 200 1.1 christos va_list ap; 201 1.1 christos 202 1.1 christos if (log_level == 0) 203 1.1 christos return; 204 1.1 christos 205 1.1 christos va_start(ap, fmt); 206 1.1 christos log_common(LOG_DEBUG, -1, fmt, ap); 207 1.1 christos va_end(ap); 208 1.1 christos } 209