1255570Strasz/*- 2255570Strasz * Copyright (c) 2012 The FreeBSD Foundation 3255570Strasz * All rights reserved. 4255570Strasz * 5255570Strasz * This software was developed by Edward Tomasz Napierala under sponsorship 6255570Strasz * from the FreeBSD Foundation. 7255570Strasz * 8255570Strasz * Redistribution and use in source and binary forms, with or without 9255570Strasz * modification, are permitted provided that the following conditions 10255570Strasz * are met: 11255570Strasz * 1. Redistributions of source code must retain the above copyright 12255570Strasz * notice, this list of conditions and the following disclaimer. 13255570Strasz * 2. Redistributions in binary form must reproduce the above copyright 14255570Strasz * notice, this list of conditions and the following disclaimer in the 15255570Strasz * documentation and/or other materials provided with the distribution. 16255570Strasz * 17255570Strasz * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18255570Strasz * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19255570Strasz * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20255570Strasz * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21255570Strasz * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22255570Strasz * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23255570Strasz * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24255570Strasz * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25255570Strasz * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26255570Strasz * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27255570Strasz * SUCH DAMAGE. 28255570Strasz * 29255570Strasz */ 30255570Strasz 31270888Strasz#include <sys/cdefs.h> 32270888Strasz__FBSDID("$FreeBSD$"); 33270888Strasz 34255570Strasz#include <errno.h> 35255570Strasz#include <stdarg.h> 36255570Strasz#include <stdio.h> 37255570Strasz#include <stdlib.h> 38255570Strasz#include <string.h> 39255570Strasz#include <syslog.h> 40255570Strasz#include <vis.h> 41255570Strasz 42255570Strasz#include "ctld.h" 43255570Strasz 44255570Straszstatic int log_level = 0; 45255570Straszstatic char *peer_name = NULL; 46255570Straszstatic char *peer_addr = NULL; 47255570Strasz 48255570Strasz#define MSGBUF_LEN 1024 49255570Strasz 50255570Straszvoid 51255570Straszlog_init(int level) 52255570Strasz{ 53255570Strasz 54255570Strasz log_level = level; 55255570Strasz openlog(getprogname(), LOG_NDELAY | LOG_PID, LOG_DAEMON); 56255570Strasz} 57255570Strasz 58255570Straszvoid 59255570Straszlog_set_peer_name(const char *name) 60255570Strasz{ 61255570Strasz 62255570Strasz /* 63255570Strasz * XXX: Turn it into assertion? 64255570Strasz */ 65255570Strasz if (peer_name != NULL) 66255570Strasz log_errx(1, "%s called twice", __func__); 67255570Strasz if (peer_addr == NULL) 68255570Strasz log_errx(1, "%s called before log_set_peer_addr", __func__); 69255570Strasz 70255570Strasz peer_name = checked_strdup(name); 71255570Strasz} 72255570Strasz 73255570Straszvoid 74255570Straszlog_set_peer_addr(const char *addr) 75255570Strasz{ 76255570Strasz 77255570Strasz /* 78255570Strasz * XXX: Turn it into assertion? 79255570Strasz */ 80255570Strasz if (peer_addr != NULL) 81255570Strasz log_errx(1, "%s called twice", __func__); 82255570Strasz 83255570Strasz peer_addr = checked_strdup(addr); 84255570Strasz} 85255570Strasz 86255570Straszstatic void 87255570Straszlog_common(int priority, int log_errno, const char *fmt, va_list ap) 88255570Strasz{ 89255570Strasz static char msgbuf[MSGBUF_LEN]; 90255570Strasz static char msgbuf_strvised[MSGBUF_LEN * 4 + 1]; 91255570Strasz int ret; 92255570Strasz 93255570Strasz ret = vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap); 94255570Strasz if (ret < 0) { 95255570Strasz fprintf(stderr, "%s: snprintf failed", getprogname()); 96255570Strasz syslog(LOG_CRIT, "snprintf failed"); 97255570Strasz exit(1); 98255570Strasz } 99255570Strasz 100255570Strasz ret = strnvis(msgbuf_strvised, sizeof(msgbuf_strvised), msgbuf, VIS_NL); 101255570Strasz if (ret < 0) { 102255570Strasz fprintf(stderr, "%s: strnvis failed", getprogname()); 103255570Strasz syslog(LOG_CRIT, "strnvis failed"); 104255570Strasz exit(1); 105255570Strasz } 106255570Strasz 107255570Strasz if (log_errno == -1) { 108255570Strasz if (peer_name != NULL) { 109255570Strasz fprintf(stderr, "%s: %s (%s): %s\n", getprogname(), 110255570Strasz peer_addr, peer_name, msgbuf_strvised); 111255570Strasz syslog(priority, "%s (%s): %s", 112255570Strasz peer_addr, peer_name, msgbuf_strvised); 113255570Strasz } else if (peer_addr != NULL) { 114255570Strasz fprintf(stderr, "%s: %s: %s\n", getprogname(), 115255570Strasz peer_addr, msgbuf_strvised); 116255570Strasz syslog(priority, "%s: %s", 117255570Strasz peer_addr, msgbuf_strvised); 118255570Strasz } else { 119255570Strasz fprintf(stderr, "%s: %s\n", getprogname(), msgbuf_strvised); 120255570Strasz syslog(priority, "%s", msgbuf_strvised); 121255570Strasz } 122255570Strasz 123255570Strasz } else { 124255570Strasz if (peer_name != NULL) { 125255570Strasz fprintf(stderr, "%s: %s (%s): %s: %s\n", getprogname(), 126255570Strasz peer_addr, peer_name, msgbuf_strvised, strerror(errno)); 127255570Strasz syslog(priority, "%s (%s): %s: %s", 128255570Strasz peer_addr, peer_name, msgbuf_strvised, strerror(errno)); 129255570Strasz } else if (peer_addr != NULL) { 130255570Strasz fprintf(stderr, "%s: %s: %s: %s\n", getprogname(), 131255570Strasz peer_addr, msgbuf_strvised, strerror(errno)); 132255570Strasz syslog(priority, "%s: %s: %s", 133255570Strasz peer_addr, msgbuf_strvised, strerror(errno)); 134255570Strasz } else { 135255570Strasz fprintf(stderr, "%s: %s: %s\n", getprogname(), 136255570Strasz msgbuf_strvised, strerror(errno)); 137255570Strasz syslog(priority, "%s: %s", 138255570Strasz msgbuf_strvised, strerror(errno)); 139255570Strasz } 140255570Strasz } 141255570Strasz} 142255570Strasz 143255570Straszvoid 144255570Straszlog_err(int eval, const char *fmt, ...) 145255570Strasz{ 146255570Strasz va_list ap; 147255570Strasz 148255570Strasz va_start(ap, fmt); 149255570Strasz log_common(LOG_CRIT, errno, fmt, ap); 150255570Strasz va_end(ap); 151255570Strasz 152255570Strasz exit(eval); 153255570Strasz} 154255570Strasz 155255570Straszvoid 156255570Straszlog_errx(int eval, const char *fmt, ...) 157255570Strasz{ 158255570Strasz va_list ap; 159255570Strasz 160255570Strasz va_start(ap, fmt); 161255570Strasz log_common(LOG_CRIT, -1, fmt, ap); 162255570Strasz va_end(ap); 163255570Strasz 164255570Strasz exit(eval); 165255570Strasz} 166255570Strasz 167255570Straszvoid 168255570Straszlog_warn(const char *fmt, ...) 169255570Strasz{ 170255570Strasz va_list ap; 171255570Strasz 172255570Strasz va_start(ap, fmt); 173255570Strasz log_common(LOG_WARNING, errno, fmt, ap); 174255570Strasz va_end(ap); 175255570Strasz} 176255570Strasz 177255570Straszvoid 178255570Straszlog_warnx(const char *fmt, ...) 179255570Strasz{ 180255570Strasz va_list ap; 181255570Strasz 182255570Strasz va_start(ap, fmt); 183255570Strasz log_common(LOG_WARNING, -1, fmt, ap); 184255570Strasz va_end(ap); 185255570Strasz} 186255570Strasz 187255570Straszvoid 188255570Straszlog_debugx(const char *fmt, ...) 189255570Strasz{ 190255570Strasz va_list ap; 191255570Strasz 192255570Strasz if (log_level == 0) 193255570Strasz return; 194255570Strasz 195255570Strasz va_start(ap, fmt); 196255570Strasz log_common(LOG_DEBUG, -1, fmt, ap); 197255570Strasz va_end(ap); 198255570Strasz} 199