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