1 /* $OpenBSD: src/sbin/dhclient/errwarn.c,v 1.17 2009/11/26 23:14:29 krw Exp $ */ 2 3 /* Errors and warnings... */ 4 5 /* 6 * Copyright (c) 1996 The Internet Software Consortium. 7 * All Rights Reserved. 8 * Copyright (c) 1995 RadioMail Corporation. All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. Neither the name of RadioMail Corporation, the Internet Software 20 * Consortium nor the names of its contributors may be used to endorse 21 * or promote products derived from this software without specific 22 * prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY RADIOMAIL CORPORATION, THE INTERNET 25 * SOFTWARE CONSORTIUM AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR 26 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 27 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28 * ARE DISCLAIMED. IN NO EVENT SHALL RADIOMAIL CORPORATION OR CONTRIBUTORS 29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 35 * OF THE POSSIBILITY OF SUCH DAMAGE. 36 * 37 * This software was written for RadioMail Corporation by Ted Lemon 38 * under a contract with Vixie Enterprises. Further modifications have 39 * been made for the Internet Software Consortium under a contract 40 * with Vixie Laboratories. 41 */ 42 43 #include <sys/types.h> 44 #include <sys/uio.h> 45 46 #include <errno.h> 47 #include <unistd.h> 48 49 #include "dhcpd.h" 50 51 static void do_percentm(char *obuf, size_t size, char *ibuf); 52 53 static char mbuf[1024]; 54 static char fbuf[1024]; 55 56 int warnings_occurred; 57 58 /* 59 * Log an error message, then exit. 60 */ 61 void 62 error(char *fmt, ...) 63 { 64 va_list list; 65 66 do_percentm(fbuf, sizeof(fbuf), fmt); 67 68 va_start(list, fmt); 69 vsnprintf(mbuf, sizeof(mbuf), fbuf, list); 70 va_end(list); 71 72 #ifndef DEBUG 73 syslog(LOG_ERR, "%s", mbuf); 74 #endif 75 76 /* Also log it to stderr? */ 77 if (log_perror) { 78 write(STDERR_FILENO, mbuf, strlen(mbuf)); 79 write(STDERR_FILENO, "\n", 1); 80 } 81 82 if (log_perror) { 83 fflush(stderr); 84 } 85 exit(1); 86 } 87 88 /* 89 * Log a warning message... 90 */ 91 int 92 warning(char *fmt, ...) 93 { 94 va_list list; 95 96 do_percentm(fbuf, sizeof(fbuf), fmt); 97 98 va_start(list, fmt); 99 vsnprintf(mbuf, sizeof(mbuf), fbuf, list); 100 va_end(list); 101 102 #ifndef DEBUG 103 syslog(LOG_ERR, "%s", mbuf); 104 #endif 105 106 if (log_perror) { 107 write(STDERR_FILENO, mbuf, strlen(mbuf)); 108 write(STDERR_FILENO, "\n", 1); 109 } 110 111 return (0); 112 } 113 114 /* 115 * Log a note... 116 */ 117 int 118 note(char *fmt, ...) 119 { 120 va_list list; 121 122 do_percentm(fbuf, sizeof(fbuf), fmt); 123 124 va_start(list, fmt); 125 vsnprintf(mbuf, sizeof(mbuf), fbuf, list); 126 va_end(list); 127 128 #ifndef DEBUG 129 syslog(LOG_INFO, "%s", mbuf); 130 #endif 131 132 if (log_perror) { 133 write(STDERR_FILENO, mbuf, strlen(mbuf)); 134 write(STDERR_FILENO, "\n", 1); 135 } 136 137 return (0); 138 } 139 140 #ifdef DEBUG 141 /* 142 * Log a debug message... 143 */ 144 int 145 debug(char *fmt, ...) 146 { 147 va_list list; 148 149 do_percentm(fbuf, sizeof(fbuf), fmt); 150 151 va_start(list, fmt); 152 vsnprintf(mbuf, sizeof(mbuf), fbuf, list); 153 va_end(list); 154 155 syslog(LOG_DEBUG, "%s", mbuf); 156 157 if (log_perror) { 158 write(STDERR_FILENO, mbuf, strlen(mbuf)); 159 write(STDERR_FILENO, "\n", 1); 160 } 161 162 return (0); 163 } 164 #endif 165 /* 166 * Find %m in the input string and substitute an error message string. 167 */ 168 static void 169 do_percentm(char *obuf, size_t size, char *ibuf) 170 { 171 char ch; 172 char *s = ibuf; 173 char *t = obuf; 174 int prlen; 175 ssize_t fmt_left; 176 int saved_errno = errno; 177 178 /* 179 * We wouldn't need this mess if printf handled %m, or if 180 * strerror() had been invented before syslog(). 181 */ 182 for (fmt_left = size; (ch = *s); ++s) { 183 if (ch == '%' && s[1] == 'm') { 184 ++s; 185 prlen = snprintf(t, fmt_left, "%s", 186 strerror(saved_errno)); 187 if (prlen == -1) 188 prlen = 0; 189 else if (prlen >= fmt_left) 190 prlen = fmt_left - 1; 191 t += prlen; 192 fmt_left -= prlen; 193 } else { 194 if (fmt_left > 1) { 195 *t++ = ch; 196 fmt_left--; 197 } 198 } 199 } 200 *t = '\0'; 201 } 202 203 int 204 parse_warn(char *fmt, ...) 205 { 206 va_list list; 207 static char spaces[] = 208 " " 209 " "; /* 80 spaces */ 210 struct iovec iov[6]; 211 size_t iovcnt; 212 213 do_percentm(mbuf, sizeof(mbuf), fmt); 214 snprintf(fbuf, sizeof(fbuf), "%s line %d: %s", tlname, lexline, mbuf); 215 va_start(list, fmt); 216 vsnprintf(mbuf, sizeof(mbuf), fbuf, list); 217 va_end(list); 218 219 #ifndef DEBUG 220 syslog(LOG_ERR, "%s", mbuf); 221 syslog(LOG_ERR, "%s", token_line); 222 if (lexchar < 81) 223 syslog(LOG_ERR, "%*c", lexchar, '^'); 224 #endif 225 226 if (log_perror) { 227 iov[0].iov_base = mbuf; 228 iov[0].iov_len = strlen(mbuf); 229 iov[1].iov_base = "\n"; 230 iov[1].iov_len = 1; 231 iov[2].iov_base = token_line; 232 iov[2].iov_len = strlen(token_line); 233 iov[3].iov_base = "\n"; 234 iov[3].iov_len = 1; 235 iovcnt = 4; 236 if (lexchar < 81) { 237 iov[4].iov_base = spaces; 238 iov[4].iov_len = lexchar - 1; 239 iov[5].iov_base = "^\n"; 240 iov[5].iov_len = 2; 241 iovcnt += 2; 242 } 243 writev(STDERR_FILENO, iov, iovcnt); 244 } 245 warnings_occurred = 1; 246 return (0); 247 } 248