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