ISC DHCP  4.3.5
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) 2009,2014 by Internet Systems Consortium, Inc. ("ISC")
8  * Copyright (c) 2004,2007 by Internet Systems Consortium, Inc. ("ISC")
9  * Copyright (c) 1996-2003 by Internet Software Consortium
10  *
11  * Permission to use, copy, modify, and distribute this software for any
12  * purpose with or without fee is hereby granted, provided that the above
13  * copyright notice and this permission notice appear in all copies.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
16  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
17  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
18  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22  *
23  * Internet Systems Consortium, Inc.
24  * 950 Charter Street
25  * Redwood City, CA 94063
26  * <info@isc.org>
27  * https://www.isc.org/
28  *
29  * This software was written for RadioMail Corporation by Ted Lemon
30  * under a contract with Vixie Enterprises. Further modifications have
31  * been made for Internet Systems Consortium under a contract
32  * with Vixie Laboratories.
33  */
34 
35 #include "dhcpd.h"
36 
37 #include <omapip/omapip_p.h>
38 #include <errno.h>
39 #include <syslog.h>
40 
41 #ifdef DEBUG
42 int log_perror = -1;
43 #else
44 int log_perror = 1;
45 #endif
46 void (*log_cleanup) (void);
47 
48 #define CVT_BUF_MAX 1023
49 static char mbuf [CVT_BUF_MAX + 1];
50 static char fbuf [CVT_BUF_MAX + 1];
51 
52 // get BUG_REPORT_URL from /etc/os-release
53 char * bug_report_url(void) {
54  FILE * file = fopen("/etc/os-release", "r");
55  size_t len;
56  char * line = NULL;
57  char * url = NULL;
58  size_t url_len = 256;
59 
60  url = (char *) malloc(url_len * sizeof(char));
61  strcpy(url, "https://bugzilla.redhat.com/");
62 
63  if (!file)
64  return url;
65 
66  while ((getline(&line, &len, file)) != -1) {
67  if (strstr(line, "BUG_REPORT_URL") != NULL) {
68  char * start = strchr(line, '=');
69  char * rquotes = strrchr(line, '"');
70 
71  if (rquotes != NULL) {
72  *rquotes = '\0';
73  strncpy(url, start+2, url_len);
74  } else {
75  strncpy(url, start+1, url_len);
76  }
77  url[url_len-1] = '\0';
78  fclose(file);
79  return url;
80  }
81  }
82  fclose(file);
83  return url;
84 }
85 
86 
87 /* Log an error message, then exit... */
88 
89 void log_fatal (const char * fmt, ... )
90 {
91  va_list list;
92 
93  do_percentm (fbuf, fmt);
94 
95  /* %Audit% This is log output. %2004.06.17,Safe%
96  * If we truncate we hope the user can get a hint from the log.
97  */
98  va_start (list, fmt);
99  vsnprintf (mbuf, sizeof mbuf, fbuf, list);
100  va_end (list);
101 
102 #ifndef DEBUG
103  syslog (LOG_ERR, "%s", mbuf);
104 #endif
105 
106  /* Also log it to stderr? */
107  if (log_perror) {
108  IGNORE_RET (write (STDERR_FILENO, mbuf, strlen (mbuf)));
109  IGNORE_RET (write (STDERR_FILENO, "\n", 1));
110  }
111 
112  log_error ("%s", "");
113  log_error ("This version of ISC DHCP is based on the release available");
114  log_error ("on ftp.isc.org. Features have been added and other changes");
115  log_error ("have been made to the base software release in order to make");
116  log_error ("it work better with this distribution.");
117  log_error ("%s", "");
118  log_error ("Please report issues with this software via: ");
119  log_error ("%s", bug_report_url());
120  log_error ("%s", "");
121  log_error ("exiting.");
122 
123  if (log_cleanup)
124  (*log_cleanup) ();
125  exit (1);
126 }
127 
128 /* Log an error message... */
129 
130 int log_error (const char * fmt, ...)
131 {
132  va_list list;
133 
134  do_percentm (fbuf, fmt);
135 
136  /* %Audit% This is log output. %2004.06.17,Safe%
137  * If we truncate we hope the user can get a hint from the log.
138  */
139  va_start (list, fmt);
140  vsnprintf (mbuf, sizeof mbuf, fbuf, list);
141  va_end (list);
142 
143 #ifndef DEBUG
144  syslog (LOG_ERR, "%s", mbuf);
145 #endif
146 
147  if (log_perror) {
148  IGNORE_RET (write (STDERR_FILENO, mbuf, strlen (mbuf)));
149  IGNORE_RET (write (STDERR_FILENO, "\n", 1));
150  }
151 
152  return 0;
153 }
154 
155 /* Log a note... */
156 
157 int log_info (const char *fmt, ...)
158 {
159  va_list list;
160 
161  do_percentm (fbuf, fmt);
162 
163  /* %Audit% This is log output. %2004.06.17,Safe%
164  * If we truncate we hope the user can get a hint from the log.
165  */
166  va_start (list, fmt);
167  vsnprintf (mbuf, sizeof mbuf, fbuf, list);
168  va_end (list);
169 
170 #ifndef DEBUG
171  syslog (LOG_INFO, "%s", mbuf);
172 #endif
173 
174  if (log_perror) {
175  IGNORE_RET (write (STDERR_FILENO, mbuf, strlen (mbuf)));
176  IGNORE_RET (write (STDERR_FILENO, "\n", 1));
177  }
178 
179  return 0;
180 }
181 
182 /* Log a debug message... */
183 
184 int log_debug (const char *fmt, ...)
185 {
186  va_list list;
187 
188  do_percentm (fbuf, fmt);
189 
190  /* %Audit% This is log output. %2004.06.17,Safe%
191  * If we truncate we hope the user can get a hint from the log.
192  */
193  va_start (list, fmt);
194  vsnprintf (mbuf, sizeof mbuf, fbuf, list);
195  va_end (list);
196 
197 #ifndef DEBUG
198  syslog (LOG_DEBUG, "%s", mbuf);
199 #endif
200 
201  if (log_perror) {
202  IGNORE_RET (write (STDERR_FILENO, mbuf, strlen (mbuf)));
203  IGNORE_RET (write (STDERR_FILENO, "\n", 1));
204  }
205 
206  return 0;
207 }
208 
209 /* Find %m in the input string and substitute an error message string. */
210 
211 void do_percentm (obuf, ibuf)
212  char *obuf;
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 > CVT_BUF_MAX)
233  goto out;
234  strcpy (p - 1, m);
235  p += strlen (p);
236  ++s;
237  } else {
238  if (++len > CVT_BUF_MAX)
239  goto out;
240  *p++ = *s++;
241  }
242  infmt = 0;
243  } else {
244  if (*s == '%')
245  infmt = 1;
246  if (++len > CVT_BUF_MAX)
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 */
const char int line
Definition: dhcpd.h:3723
int log_debug(const char *fmt,...)
Definition: errwarn.c:184
#define STDERR_FILENO
Definition: osdep.h:288
char * bug_report_url(void)
Definition: errwarn.c:53
int log_error(const char *fmt,...)
Definition: errwarn.c:130
void log_fatal(const char *fmt,...)
Definition: errwarn.c:89
int log_perror
Definition: errwarn.c:44
void(* log_cleanup)(void)
Definition: errwarn.c:46
void do_percentm(char *obuf, const char *ibuf)
Definition: errwarn.c:211
#define CVT_BUF_MAX
Definition: errwarn.c:48
const char * file
Definition: dhcpd.h:3723
int log_info(const char *fmt,...)
Definition: errwarn.c:157
#define IGNORE_RET(x)
Definition: cdefs.h:55