d8dbcbae13ec8fb07d304006ddcb29925f32f109
[dragonfly.git] / sbin / dhclient / errwarn.c
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 }