1/* errwarn.c
2
3   Errors and warnings... */
4
5/*
6 * Copyright (c) 1995 RadioMail Corporation.
7 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
8 * Copyright (c) 1996-2003 by Internet Software Consortium
9 *
10 * Permission to use, copy, modify, and distribute this software for any
11 * purpose with or without fee is hereby granted, provided that the above
12 * copyright notice and this permission notice appear in all copies.
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 *   http://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#ifndef lint
35static char copyright[] =
36"$Id: errwarn.c,v 1.3 2005/08/11 17:13:30 drochner Exp $ Copyright (c) 2004 Internet Systems Consortium.  All rights reserved.\n";
37#endif /* not lint */
38
39#include <omapip/omapip_p.h>
40#include <errno.h>
41
42#ifdef DEBUG
43int log_perror = -1;
44#else
45int log_perror = 1;
46#endif
47int log_priority;
48void (*log_cleanup) (void);
49
50#define CVT_BUF_MAX 1023
51static char mbuf [CVT_BUF_MAX + 1];
52static char fbuf [CVT_BUF_MAX + 1];
53
54/* Log an error message, then exit... */
55
56void log_fatal (const char * fmt, ... )
57{
58  va_list list;
59
60  do_percentm (fbuf, fmt);
61
62  /* %Audit% This is log output. %2004.06.17,Safe%
63   * If we truncate we hope the user can get a hint from the log.
64   */
65  va_start (list, fmt);
66  fmt = fbuf;
67  vsnprintf (mbuf, sizeof mbuf, fmt, list);
68  va_end (list);
69
70#ifndef DEBUG
71  syslog (log_priority | LOG_ERR, "%s", mbuf);
72#endif
73
74  /* Also log it to stderr? */
75  if (log_perror) {
76	  write (STDERR_FILENO, mbuf, strlen (mbuf));
77	  write (STDERR_FILENO, "\n", 1);
78  }
79
80#if !defined (NOMINUM)
81  log_error ("%s", "");
82  log_error ("If you did not get this software from ftp.isc.org, please");
83  log_error ("get the latest from ftp.isc.org and install that before");
84  log_error ("requesting help.");
85  log_error ("%s", "");
86  log_error ("If you did get this software from ftp.isc.org and have not");
87  log_error ("yet read the README, please read it before requesting help.");
88  log_error ("If you intend to request help from the dhcp-server@isc.org");
89  log_error ("mailing list, please read the section on the README about");
90  log_error ("submitting bug reports and requests for help.");
91  log_error ("%s", "");
92  log_error ("Please do not under any circumstances send requests for");
93  log_error ("help directly to the authors of this software - please");
94  log_error ("send them to the appropriate mailing list as described in");
95  log_error ("the README file.");
96  log_error ("%s", "");
97  log_error ("exiting.");
98#endif
99  if (log_cleanup)
100	  (*log_cleanup) ();
101  exit (1);
102}
103
104/* Log an error message... */
105
106int log_error (const char * fmt, ...)
107{
108  va_list list;
109
110  do_percentm (fbuf, fmt);
111
112  /* %Audit% This is log output. %2004.06.17,Safe%
113   * If we truncate we hope the user can get a hint from the log.
114   */
115  va_start (list, fmt);
116  fmt = fbuf;
117  vsnprintf (mbuf, sizeof mbuf, fmt, list);
118  va_end (list);
119
120#ifndef DEBUG
121  syslog (log_priority | LOG_ERR, "%s", mbuf);
122#endif
123
124  if (log_perror) {
125	  write (STDERR_FILENO, mbuf, strlen (mbuf));
126	  write (STDERR_FILENO, "\n", 1);
127  }
128
129  return 0;
130}
131
132/* Log a note... */
133
134int log_info (const char *fmt, ...)
135{
136  va_list list;
137
138  do_percentm (fbuf, fmt);
139
140  /* %Audit% This is log output. %2004.06.17,Safe%
141   * If we truncate we hope the user can get a hint from the log.
142   */
143  va_start (list, fmt);
144  fmt = fbuf;
145  vsnprintf (mbuf, sizeof mbuf, fmt, list);
146  va_end (list);
147
148#ifndef DEBUG
149  syslog (log_priority | LOG_INFO, "%s", mbuf);
150#endif
151
152  if (log_perror) {
153	  write (STDERR_FILENO, mbuf, strlen (mbuf));
154	  write (STDERR_FILENO, "\n", 1);
155  }
156
157  return 0;
158}
159
160/* Log a debug message... */
161
162int log_debug (const char *fmt, ...)
163{
164  va_list list;
165
166  do_percentm (fbuf, fmt);
167
168  /* %Audit% This is log output. %2004.06.17,Safe%
169   * If we truncate we hope the user can get a hint from the log.
170   */
171  va_start (list, fmt);
172  fmt = fbuf;
173  vsnprintf (mbuf, sizeof mbuf, fmt, list);
174  va_end (list);
175
176#ifndef DEBUG
177  syslog (log_priority | LOG_DEBUG, "%s", mbuf);
178#endif
179
180  if (log_perror) {
181	  write (STDERR_FILENO, mbuf, strlen (mbuf));
182	  write (STDERR_FILENO, "\n", 1);
183  }
184
185  return 0;
186}
187
188/* Find %m in the input string and substitute an error message string. */
189
190void do_percentm (obuf, ibuf)
191     char *obuf;
192     const char *ibuf;
193{
194	const char *s = ibuf;
195	char *p = obuf;
196	int infmt = 0;
197	const char *m;
198	int len = 0;
199
200	while (*s) {
201		if (infmt) {
202			if (*s == 'm') {
203#ifndef __CYGWIN32__
204				m = strerror (errno);
205#else
206				m = pWSAError ();
207#endif
208				if (!m)
209					m = "<unknown error>";
210				len += strlen (m);
211				if (len > CVT_BUF_MAX)
212					goto out;
213				strcpy (p - 1, m);
214				p += strlen (p);
215				++s;
216			} else {
217				if (++len > CVT_BUF_MAX)
218					goto out;
219				*p++ = *s++;
220			}
221			infmt = 0;
222		} else {
223			if (*s == '%')
224				infmt = 1;
225			if (++len > CVT_BUF_MAX)
226				goto out;
227			*p++ = *s++;
228		}
229	}
230      out:
231	*p = 0;
232}
233
234#ifdef NO_STRERROR
235char *strerror (err)
236	int err;
237{
238	extern char *sys_errlist [];
239	extern int sys_nerr;
240	static char errbuf [128];
241
242	if (err < 0 || err >= sys_nerr) {
243		sprintf (errbuf, "Error %d", err);
244		return errbuf;
245	}
246	return sys_errlist [err];
247}
248#endif /* NO_STRERROR */
249
250#ifdef _WIN32
251char *pWSAError ()
252{
253  int err = WSAGetLastError ();
254
255  switch (err)
256    {
257    case WSAEACCES:
258      return "Permission denied";
259    case WSAEADDRINUSE:
260      return "Address already in use";
261    case WSAEADDRNOTAVAIL:
262      return "Cannot assign requested address";
263    case WSAEAFNOSUPPORT:
264      return "Address family not supported by protocol family";
265    case WSAEALREADY:
266      return "Operation already in progress";
267    case WSAECONNABORTED:
268      return "Software caused connection abort";
269    case WSAECONNREFUSED:
270      return "Connection refused";
271    case WSAECONNRESET:
272      return "Connection reset by peer";
273    case WSAEDESTADDRREQ:
274      return "Destination address required";
275    case WSAEFAULT:
276      return "Bad address";
277    case WSAEHOSTDOWN:
278      return "Host is down";
279    case WSAEHOSTUNREACH:
280      return "No route to host";
281    case WSAEINPROGRESS:
282      return "Operation now in progress";
283    case WSAEINTR:
284      return "Interrupted function call";
285    case WSAEINVAL:
286      return "Invalid argument";
287    case WSAEISCONN:
288      return "Socket is already connected";
289    case WSAEMFILE:
290      return "Too many open files";
291    case WSAEMSGSIZE:
292      return "Message too long";
293    case WSAENETDOWN:
294      return "Network is down";
295    case WSAENETRESET:
296      return "Network dropped connection on reset";
297    case WSAENETUNREACH:
298      return "Network is unreachable";
299    case WSAENOBUFS:
300      return "No buffer space available";
301    case WSAENOPROTOOPT:
302      return "Bad protocol option";
303    case WSAENOTCONN:
304      return "Socket is not connected";
305    case WSAENOTSOCK:
306      return "Socket operation on non-socket";
307    case WSAEOPNOTSUPP:
308      return "Operation not supported";
309    case WSAEPFNOSUPPORT:
310      return "Protocol family not supported";
311    case WSAEPROCLIM:
312      return "Too many processes";
313    case WSAEPROTONOSUPPORT:
314      return "Protocol not supported";
315    case WSAEPROTOTYPE:
316      return "Protocol wrong type for socket";
317    case WSAESHUTDOWN:
318      return "Cannot send after socket shutdown";
319    case WSAESOCKTNOSUPPORT:
320      return "Socket type not supported";
321    case WSAETIMEDOUT:
322      return "Connection timed out";
323    case WSAEWOULDBLOCK:
324      return "Resource temporarily unavailable";
325    case WSAHOST_NOT_FOUND:
326      return "Host not found";
327#if 0
328    case WSA_INVALID_HANDLE:
329      return "Specified event object handle is invalid";
330    case WSA_INVALID_PARAMETER:
331      return "One or more parameters are invalid";
332    case WSAINVALIDPROCTABLE:
333      return "Invalid procedure table from service provider";
334    case WSAINVALIDPROVIDER:
335      return "Invalid service provider version number";
336    case WSA_IO_PENDING:
337      return "Overlapped operations will complete later";
338    case WSA_IO_INCOMPLETE:
339      return "Overlapped I/O event object not in signaled state";
340    case WSA_NOT_ENOUGH_MEMORY:
341      return "Insufficient memory available";
342#endif
343    case WSANOTINITIALISED:
344      return "Successful WSAStartup not yet performer";
345    case WSANO_DATA:
346      return "Valid name, no data record of requested type";
347    case WSANO_RECOVERY:
348      return "This is a non-recoverable error";
349#if 0
350    case WSAPROVIDERFAILEDINIT:
351      return "Unable to initialize a service provider";
352    case WSASYSCALLFAILURE:
353      return "System call failure";
354#endif
355    case WSASYSNOTREADY:
356      return "Network subsystem is unavailable";
357    case WSATRY_AGAIN:
358      return "Non-authoritative host not found";
359    case WSAVERNOTSUPPORTED:
360      return "WINSOCK.DLL version out of range";
361    case WSAEDISCON:
362      return "Graceful shutdown in progress";
363#if 0
364    case WSA_OPERATION_ABORTED:
365      return "Overlapped operation aborted";
366#endif
367    }
368  return "Unknown WinSock error";
369}
370#endif /* _WIN32 */
371