1 /*	$OpenBSD: errwarn.c,v 1.6 2005/04/18 16:39:25 moritz 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 #include <unistd.h>
46 #include <errno.h>
47 
48 #include "dhcpd.h"
49 
50 static void do_percentm(char *obuf, size_t size, char *ibuf);
51 
52 static char mbuf[1024];
53 static char fbuf[1024];
54 
55 int warnings_occurred;
56 
57 /*
58  * Log an error message, then exit.
59  */
60 void
error(char * fmt,...)61 error(char *fmt, ...)
62 {
63 	va_list list;
64 
65 	do_percentm(fbuf, sizeof(fbuf), fmt);
66 
67 	va_start(list, fmt);
68 	vsnprintf(mbuf, sizeof(mbuf), fbuf, list);
69 	va_end(list);
70 
71 	/* Also log it to stderr? */
72 	if (log_perror) {
73 		write(STDERR_FILENO, mbuf, strlen(mbuf));
74 		write(STDERR_FILENO, "\n", 1);
75 	} else
76 		syslog(log_priority | LOG_ERR, "%s", mbuf);
77 
78 	if (log_perror) {
79 		fprintf(stderr, "exiting.\n");
80 		fflush(stderr);
81 	} else
82 		syslog(LOG_CRIT, "exiting.");
83 
84 	exit(1);
85 }
86 
87 /*
88  * Log a warning message...
89  */
90 int
warning(char * fmt,...)91 warning(char *fmt, ...)
92 {
93 	va_list list;
94 
95 	do_percentm(fbuf, sizeof(fbuf), fmt);
96 
97 	va_start(list, fmt);
98 	vsnprintf(mbuf, sizeof(mbuf), fbuf, list);
99 	va_end(list);
100 
101 	if (log_perror) {
102 		write(STDERR_FILENO, mbuf, strlen(mbuf));
103 		write(STDERR_FILENO, "\n", 1);
104 	} else
105 		syslog(log_priority | LOG_ERR, "%s", mbuf);
106 
107 	return (0);
108 }
109 
110 /*
111  * Log a note...
112  */
113 int
note(char * fmt,...)114 note(char *fmt, ...)
115 {
116 	va_list list;
117 
118 	do_percentm(fbuf, sizeof(fbuf), fmt);
119 
120 	va_start(list, fmt);
121 	vsnprintf(mbuf, sizeof(mbuf), fbuf, list);
122 	va_end(list);
123 
124 	if (log_perror) {
125 		write(STDERR_FILENO, mbuf, strlen(mbuf));
126 		write(STDERR_FILENO, "\n", 1);
127 	} else
128 		syslog(log_priority | LOG_INFO, "%s", mbuf);
129 
130 	return (0);
131 }
132 
133 /*
134  * Log a debug message...
135  */
136 int
debug(char * fmt,...)137 debug(char *fmt, ...)
138 {
139 	va_list list;
140 
141 	do_percentm(fbuf, sizeof(fbuf), fmt);
142 
143 	va_start(list, fmt);
144 	vsnprintf(mbuf, sizeof(mbuf), fbuf, list);
145 	va_end(list);
146 
147 	if (log_perror) {
148 		write(STDERR_FILENO, mbuf, strlen(mbuf));
149 		write(STDERR_FILENO, "\n", 1);
150 	} else
151 		syslog(log_priority | LOG_DEBUG, "%s", mbuf);
152 
153 	return (0);
154 }
155 
156 /*
157  * Find %m in the input string and substitute an error message string.
158  */
159 static void
do_percentm(char * obuf,size_t size,char * ibuf)160 do_percentm(char *obuf, size_t size, char *ibuf)
161 {
162 	char ch;
163 	char *s = ibuf;
164 	char *t = obuf;
165 	size_t prlen;
166 	size_t fmt_left;
167 	int saved_errno = errno;
168 
169 	/*
170 	 * We wouldn't need this mess if printf handled %m, or if
171 	 * strerror() had been invented before syslog().
172 	 */
173 	for (fmt_left = size; (ch = *s); ++s) {
174 		if (ch == '%' && s[1] == 'm') {
175 			++s;
176 			prlen = snprintf(t, fmt_left, "%s",
177 			    strerror(saved_errno));
178 			if (prlen == -1)
179 				prlen = 0;
180 			if (prlen >= fmt_left)
181 				prlen = fmt_left - 1;
182 			t += prlen;
183 			fmt_left -= prlen;
184 		} else {
185 			if (fmt_left > 1) {
186 				*t++ = ch;
187 				fmt_left--;
188 			}
189 		}
190 	}
191 	*t = '\0';
192 }
193 
194 int
parse_warn(char * fmt,...)195 parse_warn(char *fmt, ...)
196 {
197 	va_list list;
198 	static char spaces[] =
199 	    "                                        "
200 	    "                                        "; /* 80 spaces */
201 	struct iovec iov[6];
202 
203 	do_percentm(mbuf, sizeof(mbuf), fmt);
204 	snprintf(fbuf, sizeof(fbuf), "%s line %d: %s", tlname, lexline, mbuf);
205 	va_start(list, fmt);
206 	vsnprintf(mbuf, sizeof(mbuf), fbuf, list);
207 	va_end(list);
208 
209 	if (log_perror) {
210 		iov[0].iov_base = mbuf;
211 		iov[0].iov_len = strlen(mbuf);
212 		iov[1].iov_base = "\n";
213 		iov[1].iov_len = 1;
214 		iov[2].iov_base = token_line;
215 		iov[2].iov_len = strlen(token_line);
216 		iov[3].iov_base = "\n";
217 		iov[3].iov_len = 1;
218 		iov[4].iov_base = spaces;
219 		iov[4].iov_len = lexchar - 1;
220 		iov[5].iov_base = "^\n";
221 		iov[5].iov_len = 2;
222 		writev(STDERR_FILENO, iov, sizeof(iov)/sizeof(iov[0]));
223 	} else {
224 		syslog(log_priority | LOG_ERR, "%s", mbuf);
225 		syslog(log_priority | LOG_ERR, "%s", token_line);
226 		if (lexline < 81)
227 			syslog(log_priority | LOG_ERR,
228 			    "%s^", &spaces[sizeof(spaces) - lexchar]);
229 	}
230 
231 	warnings_occurred = 1;
232 
233 	return (0);
234 }
235