1 /* 2 * Copyright (c) 2005 The DragonFly Project. All rights reserved. 3 * 4 * This code is derived from software contributed to The DragonFly Project 5 * by Matthew Dillon <dillon@backplane.com> 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * 3. Neither the name of The DragonFly Project nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific, prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 * $DragonFly: src/usr.sbin/dntpd/log.c,v 1.5 2007/06/26 00:40:35 dillon Exp $ 35 */ 36 37 #include "defs.h" 38 39 static void vlogline(int level, int newline, const char *ctl, va_list va) 40 __printflike(3, 0); 41 42 int log_stderr = 1; 43 44 void 45 logerr(const char *ctl, ...) 46 { 47 int saved_errno; 48 va_list va; 49 50 saved_errno = errno; 51 va_start(va, ctl); 52 vlogline(0, 0, ctl, va); 53 logerrstr(": %s", strerror(saved_errno)); 54 va_end(va); 55 56 } 57 58 void 59 logerrstr(const char *ctl, ...) 60 { 61 va_list va; 62 63 va_start(va, ctl); 64 vlogline(0, 1, ctl, va); 65 va_end(va); 66 } 67 68 /* 69 * logdebug() does not add the '\n', allowing multiple calls to generate 70 * a debugging log line. The buffer is accumulated until a newline is 71 * detected, then syslogged. 72 */ 73 void 74 _logdebug(int level, const char *ctl, ...) 75 { 76 va_list va; 77 78 if (level <= debug_level) { 79 va_start(va, ctl); 80 vlogline(level, 0, ctl, va); 81 va_end(va); 82 } 83 } 84 85 void 86 _logdebuginfo(server_info_t info, int level, const char *ctl, ...) 87 { 88 va_list va; 89 char *str = NULL; 90 int ipstrpad; 91 92 if (level <= debug_level) { 93 va_start(va, ctl); 94 95 vasprintf(&str, ctl, va); 96 if (str) { 97 if (info->ipstr == NULL || strcmp(info->target, info->ipstr) == 0) { 98 _logdebug(level, "%s: %s", info->target, str); 99 } else { 100 if ((ipstrpad = 15 - strlen(info->ipstr)) < 0) 101 ipstrpad = 0; 102 _logdebug(level, "%s %*.*s(%s): %s", info->target, 103 ipstrpad, ipstrpad, "", 104 info->ipstr, str); 105 } 106 free(str); 107 } 108 va_end(va); 109 } 110 } 111 112 static void 113 vlogline(int level, int newline, const char *ctl, va_list va) 114 { 115 static char line_build[1024]; 116 static int line_index; 117 int priority; 118 va_list vacopy; 119 120 /* 121 * Output to stderr directly but build the log line for syslog. 122 */ 123 if (level <= debug_level) { 124 va_copy(vacopy, va); 125 if (log_stderr) { 126 vfprintf(stderr, ctl, va); 127 if (newline) 128 fprintf(stderr, "\n"); 129 fflush(stderr); 130 } 131 if (debug_opt == 0) { 132 vsnprintf(line_build + line_index, sizeof(line_build) - line_index, 133 ctl, vacopy); 134 line_index += strlen(line_build + line_index); 135 if (line_index && line_build[line_index-1] == '\n') { 136 newline = 1; 137 --line_index; 138 } 139 if (newline) { 140 switch(level) { 141 case 0: 142 case 1: 143 case 2: 144 priority = LOG_NOTICE; 145 break; 146 case 3: 147 priority = LOG_INFO; 148 break; 149 default: 150 priority = LOG_DEBUG; 151 break; 152 } 153 syslog(priority, "%*.*s", line_index, line_index, line_build); 154 line_index = 0; 155 } 156 } 157 va_end(vacopy); 158 } 159 } 160 161