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