1270096Strasz/*- 2270096Strasz * Copyright (c) 2012 The FreeBSD Foundation 3270096Strasz * All rights reserved. 4270096Strasz * 5270096Strasz * This software was developed by Edward Tomasz Napierala under sponsorship 6270096Strasz * from the FreeBSD Foundation. 7270096Strasz * 8270096Strasz * Redistribution and use in source and binary forms, with or without 9270096Strasz * modification, are permitted provided that the following conditions 10270096Strasz * are met: 11270096Strasz * 1. Redistributions of source code must retain the above copyright 12270096Strasz * notice, this list of conditions and the following disclaimer. 13270096Strasz * 2. Redistributions in binary form must reproduce the above copyright 14270096Strasz * notice, this list of conditions and the following disclaimer in the 15270096Strasz * documentation and/or other materials provided with the distribution. 16270096Strasz * 17270096Strasz * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18270096Strasz * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19270096Strasz * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20270096Strasz * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21270096Strasz * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22270096Strasz * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23270096Strasz * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24270096Strasz * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25270096Strasz * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26270096Strasz * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27270096Strasz * SUCH DAMAGE. 28270096Strasz * 29270096Strasz */ 30270096Strasz 31270897Strasz#include <sys/cdefs.h> 32270897Strasz__FBSDID("$FreeBSD$"); 33270897Strasz 34270096Strasz#include <errno.h> 35270096Strasz#include <stdarg.h> 36270096Strasz#include <stdio.h> 37270096Strasz#include <stdlib.h> 38270096Strasz#include <string.h> 39270096Strasz#include <syslog.h> 40270096Strasz#include <vis.h> 41270096Strasz 42270096Strasz#include "common.h" 43270096Strasz 44270096Straszstatic int log_level = 0; 45270096Straszstatic char *peer_name = NULL; 46270096Straszstatic char *peer_addr = NULL; 47270096Strasz 48270096Strasz#define MSGBUF_LEN 1024 49270096Strasz 50270096Straszvoid 51270096Straszlog_init(int level) 52270096Strasz{ 53270096Strasz 54270096Strasz log_level = level; 55270096Strasz openlog(getprogname(), LOG_NDELAY | LOG_PID, LOG_DAEMON); 56270096Strasz} 57270096Strasz 58270096Straszvoid 59270096Straszlog_set_peer_name(const char *name) 60270096Strasz{ 61270096Strasz 62270096Strasz /* 63270096Strasz * XXX: Turn it into assertion? 64270096Strasz */ 65270096Strasz if (peer_name != NULL) 66270096Strasz log_errx(1, "%s called twice", __func__); 67270096Strasz if (peer_addr == NULL) 68270096Strasz log_errx(1, "%s called before log_set_peer_addr", __func__); 69270096Strasz 70270096Strasz peer_name = checked_strdup(name); 71270096Strasz} 72270096Strasz 73270096Straszvoid 74270096Straszlog_set_peer_addr(const char *addr) 75270096Strasz{ 76270096Strasz 77270096Strasz /* 78270096Strasz * XXX: Turn it into assertion? 79270096Strasz */ 80270096Strasz if (peer_addr != NULL) 81270096Strasz log_errx(1, "%s called twice", __func__); 82270096Strasz 83270096Strasz peer_addr = checked_strdup(addr); 84270096Strasz} 85270096Strasz 86270096Straszstatic void 87270096Straszlog_common(int priority, int log_errno, const char *fmt, va_list ap) 88270096Strasz{ 89270096Strasz static char msgbuf[MSGBUF_LEN]; 90270096Strasz static char msgbuf_strvised[MSGBUF_LEN * 4 + 1]; 91270096Strasz int ret; 92270096Strasz 93270096Strasz ret = vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap); 94270096Strasz if (ret < 0) { 95270096Strasz fprintf(stderr, "%s: snprintf failed", getprogname()); 96270096Strasz syslog(LOG_CRIT, "snprintf failed"); 97270096Strasz exit(1); 98270096Strasz } 99270096Strasz 100270096Strasz ret = strnvis(msgbuf_strvised, sizeof(msgbuf_strvised), msgbuf, VIS_NL); 101270096Strasz if (ret < 0) { 102270096Strasz fprintf(stderr, "%s: strnvis failed", getprogname()); 103270096Strasz syslog(LOG_CRIT, "strnvis failed"); 104270096Strasz exit(1); 105270096Strasz } 106270096Strasz 107270096Strasz if (log_errno == -1) { 108270096Strasz if (peer_name != NULL) { 109270096Strasz fprintf(stderr, "%s: %s (%s): %s\n", getprogname(), 110270096Strasz peer_addr, peer_name, msgbuf_strvised); 111270096Strasz syslog(priority, "%s (%s): %s", 112270096Strasz peer_addr, peer_name, msgbuf_strvised); 113270096Strasz } else if (peer_addr != NULL) { 114270096Strasz fprintf(stderr, "%s: %s: %s\n", getprogname(), 115270096Strasz peer_addr, msgbuf_strvised); 116270096Strasz syslog(priority, "%s: %s", 117270096Strasz peer_addr, msgbuf_strvised); 118270096Strasz } else { 119270096Strasz fprintf(stderr, "%s: %s\n", getprogname(), msgbuf_strvised); 120270096Strasz syslog(priority, "%s", msgbuf_strvised); 121270096Strasz } 122270096Strasz 123270096Strasz } else { 124270096Strasz if (peer_name != NULL) { 125270096Strasz fprintf(stderr, "%s: %s (%s): %s: %s\n", getprogname(), 126270096Strasz peer_addr, peer_name, msgbuf_strvised, strerror(errno)); 127270096Strasz syslog(priority, "%s (%s): %s: %s", 128270096Strasz peer_addr, peer_name, msgbuf_strvised, strerror(errno)); 129270096Strasz } else if (peer_addr != NULL) { 130270096Strasz fprintf(stderr, "%s: %s: %s: %s\n", getprogname(), 131270096Strasz peer_addr, msgbuf_strvised, strerror(errno)); 132270096Strasz syslog(priority, "%s: %s: %s", 133270096Strasz peer_addr, msgbuf_strvised, strerror(errno)); 134270096Strasz } else { 135270096Strasz fprintf(stderr, "%s: %s: %s\n", getprogname(), 136270096Strasz msgbuf_strvised, strerror(errno)); 137270096Strasz syslog(priority, "%s: %s", 138270096Strasz msgbuf_strvised, strerror(errno)); 139270096Strasz } 140270096Strasz } 141270096Strasz} 142270096Strasz 143270096Straszvoid 144270096Straszlog_err(int eval, const char *fmt, ...) 145270096Strasz{ 146270096Strasz va_list ap; 147270096Strasz 148270096Strasz va_start(ap, fmt); 149270096Strasz log_common(LOG_CRIT, errno, fmt, ap); 150270096Strasz va_end(ap); 151270096Strasz 152270096Strasz exit(eval); 153270096Strasz} 154270096Strasz 155270096Straszvoid 156270096Straszlog_errx(int eval, const char *fmt, ...) 157270096Strasz{ 158270096Strasz va_list ap; 159270096Strasz 160270096Strasz va_start(ap, fmt); 161270096Strasz log_common(LOG_CRIT, -1, fmt, ap); 162270096Strasz va_end(ap); 163270096Strasz 164270096Strasz exit(eval); 165270096Strasz} 166270096Strasz 167270096Straszvoid 168270096Straszlog_warn(const char *fmt, ...) 169270096Strasz{ 170270096Strasz va_list ap; 171270096Strasz 172270096Strasz va_start(ap, fmt); 173270096Strasz log_common(LOG_WARNING, errno, fmt, ap); 174270096Strasz va_end(ap); 175270096Strasz} 176270096Strasz 177270096Straszvoid 178270096Straszlog_warnx(const char *fmt, ...) 179270096Strasz{ 180270096Strasz va_list ap; 181270096Strasz 182270096Strasz va_start(ap, fmt); 183270096Strasz log_common(LOG_WARNING, -1, fmt, ap); 184270096Strasz va_end(ap); 185270096Strasz} 186270096Strasz 187270096Straszvoid 188270096Straszlog_debugx(const char *fmt, ...) 189270096Strasz{ 190270096Strasz va_list ap; 191270096Strasz 192270096Strasz if (log_level == 0) 193270096Strasz return; 194270096Strasz 195270096Strasz va_start(ap, fmt); 196270096Strasz log_common(LOG_DEBUG, -1, fmt, ap); 197270096Strasz va_end(ap); 198270096Strasz} 199