ISC DHCP  4.4.2-P1
A reference DHCPv4 and DHCPv6 implementation
errwarn.c
Go to the documentation of this file.
1 /* errwarn.c
2 
3  Errors and warnings... */
4 
5 /*
6  * Copyright (c) 1995 RadioMail Corporation.
7  * Copyright (c) 2004-2019 by Internet Systems Consortium, Inc. ("ISC")
8  * Copyright (c) 1996-2003 by Internet Software Consortium
9  *
10  * This Source Code Form is subject to the terms of the Mozilla Public
11  * License, v. 2.0. If a copy of the MPL was not distributed with this
12  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
15  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
17  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
20  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21  *
22  * Internet Systems Consortium, Inc.
23  * 950 Charter Street
24  * Redwood City, CA 94063
25  * <info@isc.org>
26  * https://www.isc.org/
27  *
28  * This software was written for RadioMail Corporation by Ted Lemon
29  * under a contract with Vixie Enterprises. Further modifications have
30  * been made for Internet Systems Consortium under a contract
31  * with Vixie Laboratories.
32  */
33 
34 #include "dhcpd.h"
35 
36 #include <omapip/omapip_p.h>
37 #include <errno.h>
38 #include <syslog.h>
39 
40 #ifdef DEBUG
41 int log_perror = -1;
42 #else
43 int log_perror = 1;
44 #endif
45 void (*log_cleanup) (void);
46 
47 #define CVT_BUF_MAX 1023
48 static char mbuf [CVT_BUF_MAX + 1];
49 static char fbuf [CVT_BUF_MAX + 1];
50 
51 // get BUG_REPORT_URL from /etc/os-release
52 char * bug_report_url(void) {
53  FILE * file = fopen("/etc/os-release", "r");
54  size_t len;
55  char * line = NULL;
56  char * url = NULL;
57  size_t url_len = 256;
58 
59  url = (char *) malloc(url_len * sizeof(char));
60  strcpy(url, "https://bugzilla.redhat.com/");
61 
62  if (!file)
63  return url;
64 
65  while ((getline(&line, &len, file)) != -1) {
66  if (strstr(line, "BUG_REPORT_URL") != NULL) {
67  char * start = strchr(line, '=');
68  char * rquotes = strrchr(line, '"');
69 
70  if (rquotes != NULL) {
71  *rquotes = '\0';
72  strncpy(url, start+2, url_len);
73  } else {
74  strncpy(url, start+1, url_len);
75  }
76  url[url_len-1] = '\0';
77  fclose(file);
78  return url;
79  }
80  }
81  fclose(file);
82  return url;
83 }
84 
85 
86 /* Log an error message, then exit... */
87 
88 void log_fatal (const char * fmt, ... )
89 {
90  va_list list;
91 
92  do_percentm (fbuf, sizeof fbuf, fmt);
93 
94  /* %Audit% This is log output. %2004.06.17,Safe%
95  * If we truncate we hope the user can get a hint from the log.
96  */
97  va_start (list, fmt);
98  vsnprintf (mbuf, sizeof mbuf, fbuf, list);
99  va_end (list);
100 
101 #ifndef DEBUG
102  syslog (LOG_ERR, "%s", mbuf);
103 #endif
104 
105  /* Also log it to stderr? */
106  if (log_perror) {
107  IGNORE_RET (write (STDERR_FILENO, mbuf, strlen (mbuf)));
108  IGNORE_RET (write (STDERR_FILENO, "\n", 1));
109  }
110 
111  log_error ("%s", "");
112  log_error ("This version of ISC DHCP is based on the release available");
113  log_error ("on ftp.isc.org. Features have been added and other changes");
114  log_error ("have been made to the base software release in order to make");
115  log_error ("it work better with this distribution.");
116  log_error ("%s", "");
117  log_error ("Please report issues with this software via: ");
118  log_error ("%s", bug_report_url());
119  log_error ("%s", "");
120  log_error ("exiting.");
121 
122  if (log_cleanup)
123  (*log_cleanup) ();
124  exit (1);
125 }
126 
127 /* Log an error message... */
128 
129 int log_error (const char * fmt, ...)
130 {
131  va_list list;
132 
133  do_percentm (fbuf, sizeof fbuf, fmt);
134 
135  /* %Audit% This is log output. %2004.06.17,Safe%
136  * If we truncate we hope the user can get a hint from the log.
137  */
138  va_start (list, fmt);
139  vsnprintf (mbuf, sizeof mbuf, fbuf, list);
140  va_end (list);
141 
142 #ifndef DEBUG
143  syslog (LOG_ERR, "%s", mbuf);
144 #endif
145 
146  if (log_perror) {
147  IGNORE_RET (write (STDERR_FILENO, mbuf, strlen (mbuf)));
148  IGNORE_RET (write (STDERR_FILENO, "\n", 1));
149  }
150 
151  return 0;
152 }
153 
154 /* Log a note... */
155 
156 int log_info (const char *fmt, ...)
157 {
158  va_list list;
159 
160  do_percentm (fbuf, sizeof fbuf, fmt);
161 
162  /* %Audit% This is log output. %2004.06.17,Safe%
163  * If we truncate we hope the user can get a hint from the log.
164  */
165  va_start (list, fmt);
166  vsnprintf (mbuf, sizeof mbuf, fbuf, list);
167  va_end (list);
168 
169 #ifndef DEBUG
170  syslog (LOG_INFO, "%s", mbuf);
171 #endif
172 
173  if (log_perror) {
174  IGNORE_RET (write (STDERR_FILENO, mbuf, strlen (mbuf)));
175  IGNORE_RET (write (STDERR_FILENO, "\n", 1));
176  }
177 
178  return 0;
179 }
180 
181 /* Log a debug message... */
182 
183 int log_debug (const char *fmt, ...)
184 {
185  va_list list;
186 
187  do_percentm (fbuf, sizeof fbuf, fmt);
188 
189  /* %Audit% This is log output. %2004.06.17,Safe%
190  * If we truncate we hope the user can get a hint from the log.
191  */
192  va_start (list, fmt);
193  vsnprintf (mbuf, sizeof mbuf, fbuf, list);
194  va_end (list);
195 
196 #ifndef DEBUG
197  syslog (LOG_DEBUG, "%s", mbuf);
198 #endif
199 
200  if (log_perror) {
201  IGNORE_RET (write (STDERR_FILENO, mbuf, strlen (mbuf)));
202  IGNORE_RET (write (STDERR_FILENO, "\n", 1));
203  }
204 
205  return 0;
206 }
207 
208 /* Find %m in the input string and substitute an error message string. */
209 
210 void do_percentm (obuf, obufsize, ibuf)
211  char *obuf;
212  size_t obufsize;
213  const char *ibuf;
214 {
215  const char *s = ibuf;
216  char *p = obuf;
217  int infmt = 0;
218  const char *m;
219  int len = 0;
220 
221  while (*s) {
222  if (infmt) {
223  if (*s == 'm') {
224 #ifndef __CYGWIN32__
225  m = strerror (errno);
226 #else
227  m = pWSAError ();
228 #endif
229  if (!m)
230  m = "<unknown error>";
231  len += strlen (m);
232  if (len > obufsize - 1)
233  goto out;
234  strcpy (p - 1, m);
235  p += strlen (p);
236  ++s;
237  } else {
238  if (++len > obufsize - 1)
239  goto out;
240  *p++ = *s++;
241  }
242  infmt = 0;
243  } else {
244  if (*s == '%')
245  infmt = 1;
246  if (++len > obufsize - 1)
247  goto out;
248  *p++ = *s++;
249  }
250  }
251  out:
252  *p = 0;
253 }
254 
255 #ifdef NO_STRERROR
256 char *strerror (err)
257  int err;
258 {
259  extern char *sys_errlist [];
260  extern int sys_nerr;
261  static char errbuf [128];
262 
263  if (err < 0 || err >= sys_nerr) {
264  sprintf (errbuf, "Error %d", err);
265  return errbuf;
266  }
267  return sys_errlist [err];
268 }
269 #endif /* NO_STRERROR */
270 
271 #ifdef _WIN32
272 char *pWSAError ()
273 {
274  int err = WSAGetLastError ();
275 
276  switch (err)
277  {
278  case WSAEACCES:
279  return "Permission denied";
280  case WSAEADDRINUSE:
281  return "Address already in use";
282  case WSAEADDRNOTAVAIL:
283  return "Cannot assign requested address";
284  case WSAEAFNOSUPPORT:
285  return "Address family not supported by protocol family";
286  case WSAEALREADY:
287  return "Operation already in progress";
288  case WSAECONNABORTED:
289  return "Software caused connection abort";
290  case WSAECONNREFUSED:
291  return "Connection refused";
292  case WSAECONNRESET:
293  return "Connection reset by peer";
294  case WSAEDESTADDRREQ:
295  return "Destination address required";
296  case WSAEFAULT:
297  return "Bad address";
298  case WSAEHOSTDOWN:
299  return "Host is down";
300  case WSAEHOSTUNREACH:
301  return "No route to host";
302  case WSAEINPROGRESS:
303  return "Operation now in progress";
304  case WSAEINTR:
305  return "Interrupted function call";
306  case WSAEINVAL:
307  return "Invalid argument";
308  case WSAEISCONN:
309  return "Socket is already connected";
310  case WSAEMFILE:
311  return "Too many open files";
312  case WSAEMSGSIZE:
313  return "Message too long";
314  case WSAENETDOWN:
315  return "Network is down";
316  case WSAENETRESET:
317  return "Network dropped connection on reset";
318  case WSAENETUNREACH:
319  return "Network is unreachable";
320  case WSAENOBUFS:
321  return "No buffer space available";
322  case WSAENOPROTOOPT:
323  return "Bad protocol option";
324  case WSAENOTCONN:
325  return "Socket is not connected";
326  case WSAENOTSOCK:
327  return "Socket operation on non-socket";
328  case WSAEOPNOTSUPP:
329  return "Operation not supported";
330  case WSAEPFNOSUPPORT:
331  return "Protocol family not supported";
332  case WSAEPROCLIM:
333  return "Too many processes";
334  case WSAEPROTONOSUPPORT:
335  return "Protocol not supported";
336  case WSAEPROTOTYPE:
337  return "Protocol wrong type for socket";
338  case WSAESHUTDOWN:
339  return "Cannot send after socket shutdown";
340  case WSAESOCKTNOSUPPORT:
341  return "Socket type not supported";
342  case WSAETIMEDOUT:
343  return "Connection timed out";
344  case WSAEWOULDBLOCK:
345  return "Resource temporarily unavailable";
346  case WSAHOST_NOT_FOUND:
347  return "Host not found";
348 #if 0
349  case WSA_INVALID_HANDLE:
350  return "Specified event object handle is invalid";
351  case WSA_INVALID_PARAMETER:
352  return "One or more parameters are invalid";
353  case WSAINVALIDPROCTABLE:
354  return "Invalid procedure table from service provider";
355  case WSAINVALIDPROVIDER:
356  return "Invalid service provider version number";
357  case WSA_IO_PENDING:
358  return "Overlapped operations will complete later";
359  case WSA_IO_INCOMPLETE:
360  return "Overlapped I/O event object not in signaled state";
361  case WSA_NOT_ENOUGH_MEMORY:
362  return "Insufficient memory available";
363 #endif
364  case WSANOTINITIALISED:
365  return "Successful WSAStartup not yet performer";
366  case WSANO_DATA:
367  return "Valid name, no data record of requested type";
368  case WSANO_RECOVERY:
369  return "This is a non-recoverable error";
370 #if 0
371  case WSAPROVIDERFAILEDINIT:
372  return "Unable to initialize a service provider";
373  case WSASYSCALLFAILURE:
374  return "System call failure";
375 #endif
376  case WSASYSNOTREADY:
377  return "Network subsystem is unavailable";
378  case WSATRY_AGAIN:
379  return "Non-authoritative host not found";
380  case WSAVERNOTSUPPORTED:
381  return "WINSOCK.DLL version out of range";
382  case WSAEDISCON:
383  return "Graceful shutdown in progress";
384 #if 0
385  case WSA_OPERATION_ABORTED:
386  return "Overlapped operation aborted";
387 #endif
388  }
389  return "Unknown WinSock error";
390 }
391 #endif /* _WIN32 */
#define IGNORE_RET(x)
Definition: cdefs.h:54
const char int line
Definition: dhcpd.h:3793
const char * file
Definition: dhcpd.h:3793
void(* log_cleanup)(void)
Definition: errwarn.c:45
int log_debug(const char *fmt,...)
Definition: errwarn.c:183
void do_percentm(char *obuf, size_t obufsize, const char *ibuf)
Definition: errwarn.c:210
char * bug_report_url(void)
Definition: errwarn.c:52
int log_perror
Definition: errwarn.c:43
void log_fatal(const char *fmt,...)
Definition: errwarn.c:88
int log_info(const char *fmt,...)
Definition: errwarn.c:156
#define CVT_BUF_MAX
Definition: errwarn.c:47
int log_error(const char *fmt,...)
Definition: errwarn.c:129
#define STDERR_FILENO
Definition: osdep.h:287