xref: /freebsd/sbin/dhclient/errwarn.c (revision 2008043f386721d58158e37e0d7e50df8095942d)
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 #include <errno.h>
47 
48 #include "dhcpd.h"
49 
50 static void do_percentm(char *obuf, size_t size, const 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
61 error(const 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 #ifndef DEBUG
72 	cap_syslog(capsyslog, log_priority | LOG_ERR, "%s", mbuf);
73 #endif
74 
75 	/* Also log it to stderr? */
76 	if (log_perror) {
77 		write(2, mbuf, strlen(mbuf));
78 		write(2, "\n", 1);
79 	}
80 
81 	cap_syslog(capsyslog, LOG_CRIT, "exiting.");
82 	if (log_perror) {
83 		fprintf(stderr, "exiting.\n");
84 		fflush(stderr);
85 	}
86 	if (pidfile != NULL)
87 		pidfile_remove(pidfile);
88 	exit(1);
89 }
90 
91 /*
92  * Log a warning message...
93  */
94 int
95 warning(const 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 	cap_syslog(capsyslog, log_priority | LOG_ERR, "%s", mbuf);
107 #endif
108 
109 	if (log_perror) {
110 		write(2, mbuf, strlen(mbuf));
111 		write(2, "\n", 1);
112 	}
113 
114 	return (0);
115 }
116 
117 /*
118  * Log a note...
119  */
120 int
121 note(const 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 	cap_syslog(capsyslog, log_priority | LOG_INFO, "%s", mbuf);
133 #endif
134 
135 	if (log_perror) {
136 		write(2, mbuf, strlen(mbuf));
137 		write(2, "\n", 1);
138 	}
139 
140 	return (0);
141 }
142 
143 /*
144  * Log a debug message...
145  */
146 int
147 debug(const 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 	cap_syslog(capsyslog, log_priority | LOG_DEBUG, "%s", mbuf);
159 #endif
160 
161 	if (log_perror) {
162 		write(2, mbuf, strlen(mbuf));
163 		write(2, "\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, const char *ibuf)
174 {
175 	char ch;
176 	const char *s = ibuf;
177 	char *t = obuf;
178 	size_t prlen;
179 	size_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 >= fmt_left)
192 				prlen = fmt_left - 1;
193 			t += prlen;
194 			fmt_left -= prlen;
195 		} else {
196 			if (fmt_left > 1) {
197 				*t++ = ch;
198 				fmt_left--;
199 			}
200 		}
201 	}
202 	*t = '\0';
203 }
204 
205 int
206 parse_warn(const char *fmt, ...)
207 {
208 	va_list list;
209 	static char spaces[] =
210 	    "                                        "
211 	    "                                        "; /* 80 spaces */
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 	cap_syslog(capsyslog, log_priority | LOG_ERR, "%s", mbuf);
221 	cap_syslog(capsyslog, log_priority | LOG_ERR, "%s", token_line);
222 	if (lexline < 81)
223 		cap_syslog(capsyslog, log_priority | LOG_ERR,
224 		    "%s^", &spaces[sizeof(spaces) - lexchar]);
225 #endif
226 
227 	if (log_perror) {
228 		write(2, mbuf, strlen(mbuf));
229 		write(2, "\n", 1);
230 		write(2, token_line, strlen(token_line));
231 		write(2, "\n", 1);
232 		write(2, spaces, lexchar - 1);
233 		write(2, "^\n", 2);
234 	}
235 
236 	warnings_occurred = 1;
237 
238 	return (0);
239 }
240