Patrick Welche <prlw1@cam.ac.uk>
[netbsd-mini2440.git] / external / bsd / ntp / dist / lib / isc / win32 / strerror.c
blob2259b5125edb36f0d88b36a44ee1ae7366118362
1 /* $NetBSD$ */
3 /*
4 * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (C) 2001, 2002 Internet Software Consortium.
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
20 /* Id: strerror.c,v 1.8 2007/06/19 23:47:19 tbox Exp */
22 #include <config.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include <winsock2.h>
28 #include <isc/mutex.h>
29 #include <isc/once.h>
30 #include <isc/print.h>
31 #include <isc/strerror.h>
32 #include <isc/util.h>
35 * Forward declarations
38 char *
39 FormatError(int error);
41 char *
42 GetWSAErrorMessage(int errval);
44 char *
45 NTstrerror(int err, BOOL *bfreebuf);
48 * We need to do this this way for profiled locks.
51 static isc_mutex_t isc_strerror_lock;
52 static void init_lock(void) {
53 RUNTIME_CHECK(isc_mutex_init(&isc_strerror_lock) == ISC_R_SUCCESS);
57 * This routine needs to free up any buffer allocated by FormatMessage
58 * if that routine gets used.
61 void
62 isc__strerror(int num, char *buf, size_t size) {
63 char *msg;
64 BOOL freebuf;
65 unsigned int unum = num;
66 static isc_once_t once = ISC_ONCE_INIT;
68 REQUIRE(buf != NULL);
70 RUNTIME_CHECK(isc_once_do(&once, init_lock) == ISC_R_SUCCESS);
72 LOCK(&isc_strerror_lock);
73 freebuf = FALSE;
74 msg = NTstrerror(num, &freebuf);
75 if (msg != NULL)
76 snprintf(buf, size, "%s", msg);
77 else
78 snprintf(buf, size, "Unknown error: %u", unum);
79 if(freebuf && msg != NULL) {
80 LocalFree(msg);
82 UNLOCK(&isc_strerror_lock);
86 * Note this will cause a memory leak unless the memory allocated here
87 * is freed by calling LocalFree. isc__strerror does this before unlocking.
88 * This only gets called if there is a system type of error and will likely
89 * be an unusual event.
91 char *
92 FormatError(int error) {
93 LPVOID lpMsgBuf = NULL;
94 FormatMessage(
95 FORMAT_MESSAGE_ALLOCATE_BUFFER |
96 FORMAT_MESSAGE_FROM_SYSTEM |
97 FORMAT_MESSAGE_IGNORE_INSERTS,
98 NULL,
99 error,
100 /* Default language */
101 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
102 (LPTSTR) &lpMsgBuf,
104 NULL);
106 return (lpMsgBuf);
110 * This routine checks the error value and calls the WSA Windows Sockets
111 * Error message function GetWSAErrorMessage below if it's within that range
112 * since those messages are not available in the system error messages.
114 char *
115 NTstrerror(int err, BOOL *bfreebuf) {
116 char *retmsg = NULL;
118 /* Copy the error value first in case of other errors */
119 DWORD errval = err;
121 *bfreebuf = FALSE;
123 /* Get the Winsock2 error messages */
124 if (errval >= WSABASEERR && errval <= (WSABASEERR + 1015)) {
125 retmsg = GetWSAErrorMessage(errval);
126 if (retmsg != NULL)
127 return (retmsg);
130 * If it's not one of the standard Unix error codes,
131 * try a system error message
133 if (errval > (DWORD) _sys_nerr) {
134 *bfreebuf = TRUE;
135 return (FormatError(errval));
136 } else {
137 return (strerror(errval));
142 * This is a replacement for perror
144 void __cdecl
145 NTperror(char *errmsg) {
146 /* Copy the error value first in case of other errors */
147 int errval = errno;
148 BOOL bfreebuf = FALSE;
149 char *msg;
151 msg = NTstrerror(errval, &bfreebuf);
152 fprintf(stderr, "%s: %s\n", errmsg, msg);
153 if(bfreebuf == TRUE) {
154 LocalFree(msg);
160 * Return the error string related to Winsock2 errors.
161 * This function is necessary since FormatMessage knows nothing about them
162 * and there is no function to get them.
164 char *
165 GetWSAErrorMessage(int errval) {
166 char *msg;
168 switch (errval) {
170 case WSAEINTR:
171 msg = "Interrupted system call";
172 break;
174 case WSAEBADF:
175 msg = "Bad file number";
176 break;
178 case WSAEACCES:
179 msg = "Permission denied";
180 break;
182 case WSAEFAULT:
183 msg = "Bad address";
184 break;
186 case WSAEINVAL:
187 msg = "Invalid argument";
188 break;
190 case WSAEMFILE:
191 msg = "Too many open sockets";
192 break;
194 case WSAEWOULDBLOCK:
195 msg = "Operation would block";
196 break;
198 case WSAEINPROGRESS:
199 msg = "Operation now in progress";
200 break;
202 case WSAEALREADY:
203 msg = "Operation already in progress";
204 break;
206 case WSAENOTSOCK:
207 msg = "Socket operation on non-socket";
208 break;
210 case WSAEDESTADDRREQ:
211 msg = "Destination address required";
212 break;
214 case WSAEMSGSIZE:
215 msg = "Message too long";
216 break;
218 case WSAEPROTOTYPE:
219 msg = "Protocol wrong type for socket";
220 break;
222 case WSAENOPROTOOPT:
223 msg = "Bad protocol option";
224 break;
226 case WSAEPROTONOSUPPORT:
227 msg = "Protocol not supported";
228 break;
230 case WSAESOCKTNOSUPPORT:
231 msg = "Socket type not supported";
232 break;
234 case WSAEOPNOTSUPP:
235 msg = "Operation not supported on socket";
236 break;
238 case WSAEPFNOSUPPORT:
239 msg = "Protocol family not supported";
240 break;
242 case WSAEAFNOSUPPORT:
243 msg = "Address family not supported";
244 break;
246 case WSAEADDRINUSE:
247 msg = "Address already in use";
248 break;
250 case WSAEADDRNOTAVAIL:
251 msg = "Can't assign requested address";
252 break;
254 case WSAENETDOWN:
255 msg = "Network is down";
256 break;
258 case WSAENETUNREACH:
259 msg = "Network is unreachable";
260 break;
262 case WSAENETRESET:
263 msg = "Net connection reset";
264 break;
266 case WSAECONNABORTED:
267 msg = "Software caused connection abort";
268 break;
270 case WSAECONNRESET:
271 msg = "Connection reset by peer";
272 break;
274 case WSAENOBUFS:
275 msg = "No buffer space available";
276 break;
278 case WSAEISCONN:
279 msg = "Socket is already connected";
280 break;
282 case WSAENOTCONN:
283 msg = "Socket is not connected";
284 break;
286 case WSAESHUTDOWN:
287 msg = "Can't send after socket shutdown";
288 break;
290 case WSAETOOMANYREFS:
291 msg = "Too many references: can't splice";
292 break;
294 case WSAETIMEDOUT:
295 msg = "Connection timed out";
296 break;
298 case WSAECONNREFUSED:
299 msg = "Connection refused";
300 break;
302 case WSAELOOP:
303 msg = "Too many levels of symbolic links";
304 break;
306 case WSAENAMETOOLONG:
307 msg = "File name too long";
308 break;
310 case WSAEHOSTDOWN:
311 msg = "Host is down";
312 break;
314 case WSAEHOSTUNREACH:
315 msg = "No route to host";
316 break;
318 case WSAENOTEMPTY:
319 msg = "Directory not empty";
320 break;
322 case WSAEPROCLIM:
323 msg = "Too many processes";
324 break;
326 case WSAEUSERS:
327 msg = "Too many users";
328 break;
330 case WSAEDQUOT:
331 msg = "Disc quota exceeded";
332 break;
334 case WSAESTALE:
335 msg = "Stale NFS file handle";
336 break;
338 case WSAEREMOTE:
339 msg = "Too many levels of remote in path";
340 break;
342 case WSASYSNOTREADY:
343 msg = "Network system is unavailable";
344 break;
346 case WSAVERNOTSUPPORTED:
347 msg = "Winsock version out of range";
348 break;
350 case WSANOTINITIALISED:
351 msg = "WSAStartup not yet called";
352 break;
354 case WSAEDISCON:
355 msg = "Graceful shutdown in progress";
356 break;
358 case WSAHOST_NOT_FOUND:
359 msg = "Host not found";
360 break;
362 case WSANO_DATA:
363 msg = "No host data of that type was found";
364 break;
366 default:
367 msg = NULL;
368 break;
370 return (msg);
374 * These error messages are more informative about CryptAPI Errors than the
375 * standard error messages
378 char *
379 GetCryptErrorMessage(int errval) {
380 char *msg;
382 switch (errval) {
384 case NTE_BAD_FLAGS:
385 msg = "The dwFlags parameter has an illegal value.";
386 break;
387 case NTE_BAD_KEYSET:
388 msg = "The Registry entry for the key container "
389 "could not be opened and may not exist.";
390 break;
391 case NTE_BAD_KEYSET_PARAM:
392 msg = "The pszContainer or pszProvider parameter "
393 "is set to an illegal value.";
394 break;
395 case NTE_BAD_PROV_TYPE:
396 msg = "The value of the dwProvType parameter is out "
397 "of range. All provider types must be from "
398 "1 to 999, inclusive.";
399 break;
400 case NTE_BAD_SIGNATURE:
401 msg = "The provider DLL signature did not verify "
402 "correctly. Either the DLL or the digital "
403 "signature has been tampered with.";
404 break;
405 case NTE_EXISTS:
406 msg = "The dwFlags parameter is CRYPT_NEWKEYSET, but the key"
407 " container already exists.";
408 break;
409 case NTE_KEYSET_ENTRY_BAD:
410 msg = "The Registry entry for the pszContainer key container "
411 "was found (in the HKEY_CURRENT_USER window), but is "
412 "corrupt. See the section System Administration for "
413 " etails about CryptoAPI's Registry usage.";
414 break;
415 case NTE_KEYSET_NOT_DEF:
416 msg = "No Registry entry exists in the HKEY_CURRENT_USER "
417 "window for the key container specified by "
418 "pszContainer.";
419 break;
420 case NTE_NO_MEMORY:
421 msg = "The CSP ran out of memory during the operation.";
422 break;
423 case NTE_PROV_DLL_NOT_FOUND:
424 msg = "The provider DLL file does not exist or is not on the "
425 "current path.";
426 break;
427 case NTE_PROV_TYPE_ENTRY_BAD:
428 msg = "The Registry entry for the provider type specified by "
429 "dwProvType is corrupt. This error may relate to "
430 "either the user default CSP list or the machine "
431 "default CSP list. See the section System "
432 "Administration for details about CryptoAPI's "
433 "Registry usage.";
434 break;
435 case NTE_PROV_TYPE_NO_MATCH:
436 msg = "The provider type specified by dwProvType does not "
437 "match the provider type found in the Registry. Note "
438 "that this error can only occur when pszProvider "
439 "specifies an actual CSP name.";
440 break;
441 case NTE_PROV_TYPE_NOT_DEF:
442 msg = "No Registry entry exists for the provider type "
443 "specified by dwProvType.";
444 break;
445 case NTE_PROVIDER_DLL_FAIL:
446 msg = "The provider DLL file could not be loaded, and "
447 "may not exist. If it exists, then the file is "
448 "not a valid DLL.";
449 break;
450 case NTE_SIGNATURE_FILE_BAD:
451 msg = "An error occurred while loading the DLL file image, "
452 "prior to verifying its signature.";
453 break;
455 default:
456 msg = NULL;
457 break;
459 return msg;