diff --git a/lib/isc/win32/errno2result.c b/lib/isc/win32/errno2result.c index 5e1acdb388..8ef9831326 100644 --- a/lib/isc/win32/errno2result.c +++ b/lib/isc/win32/errno2result.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: errno2result.c,v 1.4 2001/07/17 20:29:24 gson Exp $ */ +/* $Id: errno2result.c,v 1.5 2001/09/04 03:22:17 mayer Exp $ */ #include @@ -63,371 +63,3 @@ isc__errno2result(int posixerrno) { } } -/* - * Note this will cause a memory leak unless the memory allocated here - * is freed by calling LocalFree - */ -char * -FormatError(int error) { - LPVOID lpMsgBuf; - FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - error, - /* Default language */ - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR) &lpMsgBuf, - 0, - NULL); - - return (lpMsgBuf); -} - -char * __cdecl -NTstrMessage(int err) { - char *retmsg = NULL; - - /* Copy the error value first in case of other errors */ - DWORD errval = err; - - /* Get the Winsock2 error messages */ - if (errval >= WSABASEERR && errval <= (WSABASEERR + 1015)) { - retmsg = GetWSAErrorMessage(errval); - if (retmsg != NULL) - return (retmsg); - } - /* - * If it's not one of the standard Unix error codes, - * try a system error message - */ - if (errval > (DWORD) _sys_nerr) { - return (FormatError(errval)); - } else { - return (strerror(errval)); - } -} - -char * __cdecl -NTstrerror(int err) { - /* Copy the error value first in case of other errors */ - DWORD errval = err; - - return (NTstrMessage(errval)); -} - -/* - * This is a replacement for perror, but it also reports the error value. - */ -void __cdecl -NTperror(char *errmsg) { - /* Copy the error value first in case of other errors */ - int errval = errno; - - fprintf(stderr, "%s: %s\n", errmsg, NTstrMessage(errval)); -} - -/* - * Return the error string related to Winsock2 errors. - * This function is necessary since FormatMessage knows nothing about them - * and there is no function to get them. - */ -char * -GetWSAErrorMessage(int errval) { - char *msg; - - switch (errval) { - - case WSAEINTR: - msg = "Interrupted system call"; - break; - - case WSAEBADF: - msg = "Bad file number"; - break; - - case WSAEACCES: - msg = "Permission denied"; - break; - - case WSAEFAULT: - msg = "Bad address"; - break; - - case WSAEINVAL: - msg = "Invalid argument"; - break; - - case WSAEMFILE: - msg = "Too many open sockets"; - break; - - case WSAEWOULDBLOCK: - msg = "Operation would block"; - break; - - case WSAEINPROGRESS: - msg = "Operation now in progress"; - break; - - case WSAEALREADY: - msg = "Operation already in progress"; - break; - - case WSAENOTSOCK: - msg = "Socket operation on non-socket"; - break; - - case WSAEDESTADDRREQ: - msg = "Destination address required"; - break; - - case WSAEMSGSIZE: - msg = "Message too long"; - break; - - case WSAEPROTOTYPE: - msg = "Protocol wrong type for socket"; - break; - - case WSAENOPROTOOPT: - msg = "Bad protocol option"; - break; - - case WSAEPROTONOSUPPORT: - msg = "Protocol not supported"; - break; - - case WSAESOCKTNOSUPPORT: - msg = "Socket type not supported"; - break; - - case WSAEOPNOTSUPP: - msg = "Operation not supported on socket"; - break; - - case WSAEPFNOSUPPORT: - msg = "Protocol family not supported"; - break; - - case WSAEAFNOSUPPORT: - msg = "Address family not supported"; - break; - - case WSAEADDRINUSE: - msg = "Address already in use"; - break; - - case WSAEADDRNOTAVAIL: - msg = "Can't assign requested address"; - break; - - case WSAENETDOWN: - msg = "Network is down"; - break; - - case WSAENETUNREACH: - msg = "Network is unreachable"; - break; - - case WSAENETRESET: - msg = "Net connection reset"; - break; - - case WSAECONNABORTED: - msg = "Software caused connection abort"; - break; - - case WSAECONNRESET: - msg = "Connection reset by peer"; - break; - - case WSAENOBUFS: - msg = "No buffer space available"; - break; - - case WSAEISCONN: - msg = "Socket is already connected"; - break; - - case WSAENOTCONN: - msg = "Socket is not connected"; - break; - - case WSAESHUTDOWN: - msg = "Can't send after socket shutdown"; - break; - - case WSAETOOMANYREFS: - msg = "Too many references: can't splice"; - break; - - case WSAETIMEDOUT: - msg = "Connection timed out"; - break; - - case WSAECONNREFUSED: - msg = "Connection refused"; - break; - - case WSAELOOP: - msg = "Too many levels of symbolic links"; - break; - - case WSAENAMETOOLONG: - msg = "File name too long"; - break; - - case WSAEHOSTDOWN: - msg = "Host is down"; - break; - - case WSAEHOSTUNREACH: - msg = "No route to host"; - break; - - case WSAENOTEMPTY: - msg = "Directory not empty"; - break; - - case WSAEPROCLIM: - msg = "Too many processes"; - break; - - case WSAEUSERS: - msg = "Too many users"; - break; - - case WSAEDQUOT: - msg = "Disc quota exceeded"; - break; - - case WSAESTALE: - msg = "Stale NFS file handle"; - break; - - case WSAEREMOTE: - msg = "Too many levels of remote in path"; - break; - - case WSASYSNOTREADY: - msg = "Network system is unavailable"; - break; - - case WSAVERNOTSUPPORTED: - msg = "Winsock version out of range"; - break; - - case WSANOTINITIALISED: - msg = "WSAStartup not yet called"; - break; - - case WSAEDISCON: - msg = "Graceful shutdown in progress"; - break; -/* - case WSAHOST_NOT_FOUND: - msg = "Host not found"; - break; - - case WSANO_DATA: - msg = "No host data of that type was found"; - break; -*/ - default: - msg = NULL; - break; - } - return (msg); -} - -/* - * These error messages are more informative about CryptAPI Errors than the - * standard error messages - */ - -char * -GetCryptErrorMessage(int errval) { - char *msg; - - switch (errval) { - - case NTE_BAD_FLAGS: - msg = "The dwFlags parameter has an illegal value."; - break; - case NTE_BAD_KEYSET: - msg = "The Registry entry for the key container " - "could not be opened and may not exist."; - break; - case NTE_BAD_KEYSET_PARAM: - msg = "The pszContainer or pszProvider parameter " - "is set to an illegal value."; - break; - case NTE_BAD_PROV_TYPE: - msg = "The value of the dwProvType parameter is out " - "of range. All provider types must be from " - "1 to 999, inclusive."; - break; - case NTE_BAD_SIGNATURE: - msg = "The provider DLL signature did not verify " - "correctly. Either the DLL or the digital " - "signature has been tampered with."; - break; - case NTE_EXISTS: - msg = "The dwFlags parameter is CRYPT_NEWKEYSET, but the key" - " container already exists."; - break; - case NTE_KEYSET_ENTRY_BAD: - msg = "The Registry entry for the pszContainer key container " - "was found (in the HKEY_CURRENT_USER window), but is " - "corrupt. See the section System Administration for " - " etails about CryptoAPI's Registry usage."; - break; - case NTE_KEYSET_NOT_DEF: - msg = "No Registry entry exists in the HKEY_CURRENT_USER " - "window for the key container specified by " - "pszContainer."; - break; - case NTE_NO_MEMORY: - msg = "The CSP ran out of memory during the operation."; - break; - case NTE_PROV_DLL_NOT_FOUND: - msg = "The provider DLL file does not exist or is not on the " - "current path."; - break; - case NTE_PROV_TYPE_ENTRY_BAD: - msg = "The Registry entry for the provider type specified by " - "dwProvType is corrupt. This error may relate to " - "either the user default CSP list or the machine " - "default CSP list. See the section System " - "Administration for details about CryptoAPI's " - "Registry usage."; - break; - case NTE_PROV_TYPE_NO_MATCH: - msg = "The provider type specified by dwProvType does not " - "match the provider type found in the Registry. Note " - "that this error can only occur when pszProvider " - "specifies an actual CSP name."; - break; - case NTE_PROV_TYPE_NOT_DEF: - msg = "No Registry entry exists for the provider type " - "specified by dwProvType."; - break; - case NTE_PROVIDER_DLL_FAIL: - msg = "The provider DLL file could not be loaded, and " - "may not exist. If it exists, then the file is " - "not a valid DLL."; - break; - case NTE_SIGNATURE_FILE_BAD: - msg = "An error occurred while loading the DLL file image, " - "prior to verifying its signature."; - break; - - default: - msg = NULL; - break; - } - return msg; -} - diff --git a/lib/isc/win32/errno2result.h b/lib/isc/win32/errno2result.h index 51645b38ab..bbaff98c74 100644 --- a/lib/isc/win32/errno2result.h +++ b/lib/isc/win32/errno2result.h @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: errno2result.h,v 1.4 2001/07/17 20:29:25 gson Exp $ */ +/* $Id: errno2result.h,v 1.5 2001/09/04 03:22:18 mayer Exp $ */ #ifndef UNIX_ERRNO2RESULT_H #define UNIX_ERRNO2RESULT_H 1 @@ -32,15 +32,6 @@ ISC_LANG_BEGINDECLS isc_result_t isc__errno2result(int posixerrno); -char * -isc_FormatError(int error); - -char * -GetWSAErrorMessage(int errval); - -char * __cdecl -NTstrerror(int err); - ISC_LANG_ENDDECLS #endif /* UNIX_ERRNO2RESULT_H */ diff --git a/lib/isc/win32/include/isc/strerror.h b/lib/isc/win32/include/isc/strerror.h new file mode 100644 index 0000000000..9c095f7210 --- /dev/null +++ b/lib/isc/win32/include/isc/strerror.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM + * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL + * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* $Id: strerror.h,v 1.1 2001/09/04 03:22:23 mayer Exp $ */ + +#ifndef ISC_STRERROR_H +#define ISC_STRERROR_H + +#include + +#include + +ISC_LANG_BEGINDECLS + +#define ISC_STRERRORSIZE 128 + +/* + * Provide a thread safe wrapper to strerrror(). + * 'buf' is always returned. + * + * Requires: + * 'buf' to be non NULL. + */ +char * +isc__strerror(int num, char *buf, size_t bufsize); + +ISC_LANG_ENDDECLS + +#endif /* ISC_STRERROR_H */ diff --git a/lib/isc/win32/interfaceiter.c b/lib/isc/win32/interfaceiter.c index 77950f4270..619907af7c 100644 --- a/lib/isc/win32/interfaceiter.c +++ b/lib/isc/win32/interfaceiter.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: interfaceiter.c,v 1.4 2001/07/17 20:29:27 gson Exp $ */ +/* $Id: interfaceiter.c,v 1.5 2001/09/04 03:22:19 mayer Exp $ */ /* * Note that this code will need to be revisited to support IPv6 Interfaces. @@ -35,9 +35,9 @@ #include #include #include +#include #include #include -#include "errno2result.h" /* Common utility functions */ @@ -101,6 +101,7 @@ get_addr(unsigned int family, isc_netaddr_t *dst, struct sockaddr *src) { isc_result_t isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) { + char strbuf[ISC_STRERRORSIZE]; isc_interfaceiter_t *iter; isc_result_t result; int error; @@ -123,8 +124,8 @@ isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) { */ if ((iter->socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { UNEXPECTED_ERROR(__FILE__, __LINE__, - "making interface scan socket: %s", - strerror(errno)); + "making interface scan socket: %s", + isc__strerror(errno, strbuf, sizeof(strbuf))); result = ISC_R_UNEXPECTED; goto socket_failure; } @@ -151,8 +152,9 @@ isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) { if (error != WSAEFAULT && error != WSAENOBUFS) { errno = error; UNEXPECTED_ERROR(__FILE__, __LINE__, - "get interface configuration: %s", - NTstrerror(error)); + "get interface configuration: %s", + isc__strerror(error,strbuf, + sizeof(strbuf))); result = ISC_R_UNEXPECTED; goto ioctl_failure; } diff --git a/lib/isc/win32/libisc.def b/lib/isc/win32/libisc.def index 88d9906a0b..52b91f5e46 100644 --- a/lib/isc/win32/libisc.def +++ b/lib/isc/win32/libisc.def @@ -363,7 +363,6 @@ isc_thread_setconcurrency isc_interval_set isc_time_subtract isc_interval_iszero -isc_time_set isc_time_settoepoch isc_time_isepoch isc_time_now @@ -372,8 +371,6 @@ isc_time_compare isc_time_add isc_time_subtract isc_time_microdiff -isc_time_seconds -isc_time_secondsastimet isc_time_nanoseconds isc_keyboard_open isc_keyboard_close @@ -422,7 +419,8 @@ isc_ntfile_open isc_ntfile_close isc_ntfile_read isc_ntfile_write - +isc_file_truncate +isc__strerror ; Exported Data diff --git a/lib/isc/win32/libisc.dsp b/lib/isc/win32/libisc.dsp index a9a4b46545..a524db672a 100644 --- a/lib/isc/win32/libisc.dsp +++ b/lib/isc/win32/libisc.dsp @@ -173,6 +173,10 @@ SOURCE=.\stdtime.c # End Source File # Begin Source File +SOURCE=.\strerror.c +# End Source File +# Begin Source File + SOURCE=.\syslog.c # End Source File # Begin Source File @@ -461,6 +465,10 @@ SOURCE=.\include\isc\stdtime.h # End Source File # Begin Source File +SOURCE=.\include\isc\strerror.h +# End Source File +# Begin Source File + SOURCE=..\include\isc\string.h # End Source File # Begin Source File diff --git a/lib/isc/win32/libisc.mak b/lib/isc/win32/libisc.mak index aa366c2d43..c6814b7d25 100644 --- a/lib/isc/win32/libisc.mak +++ b/lib/isc/win32/libisc.mak @@ -25,6 +25,10 @@ NULL= NULL=nul !ENDIF +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + !IF "$(CFG)" == "libisc - Win32 Release" OUTDIR=.\Release @@ -86,6 +90,7 @@ CLEAN : -@erase "$(INTDIR)\socket.obj" -@erase "$(INTDIR)\stdio.obj" -@erase "$(INTDIR)\stdtime.obj" + -@erase "$(INTDIR)\strerror.obj" -@erase "$(INTDIR)\string.obj" -@erase "$(INTDIR)\symtab.obj" -@erase "$(INTDIR)\syslog.obj" @@ -103,42 +108,8 @@ CLEAN : "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" -CPP=cl.exe CPP_PROJ=/nologo /MD /W3 /GX /O2 /I "./" /I "../../../" /I "include" /I "../include" /I "win32" /I "../../isccfg/include" /D "WIN32" /D "NDEBUG" /D "__STDC__" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBISC_EXPORTS" /Fp"$(INTDIR)\libisc.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c - -.c{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.c{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -MTL=midl.exe MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 -RSC=rc.exe BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\libisc.bsc" BSC32_SBRS= \ @@ -208,7 +179,8 @@ LINK32_OBJS= \ "$(INTDIR)\symtab.obj" \ "$(INTDIR)\task.obj" \ "$(INTDIR)\taskpool.obj" \ - "$(INTDIR)\timer.obj" + "$(INTDIR)\timer.obj" \ + "$(INTDIR)\strerror.obj" "..\..\..\Build\Release\libisc.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< @@ -331,6 +303,8 @@ CLEAN : -@erase "$(INTDIR)\stdio.sbr" -@erase "$(INTDIR)\stdtime.obj" -@erase "$(INTDIR)\stdtime.sbr" + -@erase "$(INTDIR)\strerror.obj" + -@erase "$(INTDIR)\strerror.sbr" -@erase "$(INTDIR)\string.obj" -@erase "$(INTDIR)\string.sbr" -@erase "$(INTDIR)\symtab.obj" @@ -362,42 +336,8 @@ CLEAN : "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" -CPP=cl.exe CPP_PROJ=/nologo /MDd /W3 /Gm /GX /ZI /Od /I "./" /I "../../../" /I "include" /I "../include" /I "win32" /I "../../isccfg/include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "__STDC__" /D "_MBCS" /D "_USRDLL" /D "LIBISC_EXPORTS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\libisc.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c - -.c{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.c{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -MTL=midl.exe MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 -RSC=rc.exe BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\libisc.bsc" BSC32_SBRS= \ @@ -461,7 +401,8 @@ BSC32_SBRS= \ "$(INTDIR)\symtab.sbr" \ "$(INTDIR)\task.sbr" \ "$(INTDIR)\taskpool.sbr" \ - "$(INTDIR)\timer.sbr" + "$(INTDIR)\timer.sbr" \ + "$(INTDIR)\strerror.sbr" "$(OUTDIR)\libisc.bsc" : "$(OUTDIR)" $(BSC32_SBRS) $(BSC32) @<< @@ -533,7 +474,8 @@ LINK32_OBJS= \ "$(INTDIR)\symtab.obj" \ "$(INTDIR)\task.obj" \ "$(INTDIR)\taskpool.obj" \ - "$(INTDIR)\timer.obj" + "$(INTDIR)\timer.obj" \ + "$(INTDIR)\strerror.obj" "..\..\..\Build\Debug\libisc.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< @@ -542,6 +484,36 @@ LINK32_OBJS= \ !ENDIF +.c{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.c{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + !IF "$(NO_EXTERNAL_DEPS)" != "1" !IF EXISTS("libisc.dep") @@ -871,6 +843,22 @@ SOURCE=.\stdtime.c "$(INTDIR)\stdtime.obj" "$(INTDIR)\stdtime.sbr" : $(SOURCE) "$(INTDIR)" +!ENDIF + +SOURCE=.\strerror.c + +!IF "$(CFG)" == "libisc - Win32 Release" + + +"$(INTDIR)\strerror.obj" : $(SOURCE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "libisc - Win32 Debug" + + +"$(INTDIR)\strerror.obj" "$(INTDIR)\strerror.sbr" : $(SOURCE) "$(INTDIR)" + + !ENDIF SOURCE=.\syslog.c diff --git a/lib/isc/win32/strerror.c b/lib/isc/win32/strerror.c new file mode 100644 index 0000000000..a3345d1d53 --- /dev/null +++ b/lib/isc/win32/strerror.c @@ -0,0 +1,454 @@ +/* + * Copyright (C) 2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM + * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL + * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* $Id: strerror.c,v 1.1 2001/09/04 03:22:23 mayer Exp $ */ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +/* + * Forward declarations + */ + +char * +FormatError(int error); + +char * +GetWSAErrorMessage(int errval); + +char * __cdecl +NTstrerror(int err); + +/* + * We need to do this this way for profiled locks. + * Note that freebuf is only used if the FormatMessage function needs + * to be used. + */ + +static BOOL freebuf = FALSE; +static isc_mutex_t isc_strerror_lock; +static void init_lock(void) { + RUNTIME_CHECK(isc_mutex_init(&isc_strerror_lock) == ISC_R_SUCCESS); +} + +/* + * This routine needs to free up any buffer allocated by FormatMessage + * if that routine gets used. + */ + +char * +isc__strerror(int num, char *buf, size_t size) { + char *msg; + unsigned int unum = num; + static isc_once_t once = ISC_ONCE_INIT; + + REQUIRE(buf != NULL); + + RUNTIME_CHECK(isc_once_do(&once, init_lock) == ISC_R_SUCCESS); + + LOCK(&isc_strerror_lock); + freebuf = FALSE; + msg = NTstrerror(num); + if (msg != NULL) + snprintf(buf, size, "%s", msg); + else + snprintf(buf, size, "Unknown error: %u", unum); + if(freebuf == TRUE) { + LocalFree(msg); + freebuf = FALSE; + } + UNLOCK(&isc_strerror_lock); + return (buf); +} + +/* + * Note this will cause a memory leak unless the memory allocated here + * is freed by calling LocalFree. isc__strerror does this before unlocking. + * This only gets called if there is a system type of error and will likely + * be an unusual event. + */ +char * +FormatError(int error) { + LPVOID lpMsgBuf = NULL; + freebuf = TRUE; + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + error, + /* Default language */ + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR) &lpMsgBuf, + 0, + NULL); + + return (lpMsgBuf); +} + +/* + * This routine checks the error value and calls the WSA Windows Sockets + * Error message function GetWSAErrorMessage below if it's within that range + * since those messages are not available in the system error messages. + */ +char * __cdecl +NTstrerror(int err) { + char *retmsg = NULL; + + /* Copy the error value first in case of other errors */ + DWORD errval = err; + + /* Get the Winsock2 error messages */ + if (errval >= WSABASEERR && errval <= (WSABASEERR + 1015)) { + retmsg = GetWSAErrorMessage(errval); + if (retmsg != NULL) + return (retmsg); + } + /* + * If it's not one of the standard Unix error codes, + * try a system error message + */ + if (errval > (DWORD) _sys_nerr) { + return (FormatError(errval)); + } else { + return (strerror(errval)); + } +} + +/* + * This is a replacement for perror + */ +void __cdecl +NTperror(char *errmsg) { + /* Copy the error value first in case of other errors */ + int errval = errno; + + fprintf(stderr, "%s: %s\n", errmsg, NTstrerror(errval)); +} + +/* + * Return the error string related to Winsock2 errors. + * This function is necessary since FormatMessage knows nothing about them + * and there is no function to get them. + */ +char * +GetWSAErrorMessage(int errval) { + char *msg; + + switch (errval) { + + case WSAEINTR: + msg = "Interrupted system call"; + break; + + case WSAEBADF: + msg = "Bad file number"; + break; + + case WSAEACCES: + msg = "Permission denied"; + break; + + case WSAEFAULT: + msg = "Bad address"; + break; + + case WSAEINVAL: + msg = "Invalid argument"; + break; + + case WSAEMFILE: + msg = "Too many open sockets"; + break; + + case WSAEWOULDBLOCK: + msg = "Operation would block"; + break; + + case WSAEINPROGRESS: + msg = "Operation now in progress"; + break; + + case WSAEALREADY: + msg = "Operation already in progress"; + break; + + case WSAENOTSOCK: + msg = "Socket operation on non-socket"; + break; + + case WSAEDESTADDRREQ: + msg = "Destination address required"; + break; + + case WSAEMSGSIZE: + msg = "Message too long"; + break; + + case WSAEPROTOTYPE: + msg = "Protocol wrong type for socket"; + break; + + case WSAENOPROTOOPT: + msg = "Bad protocol option"; + break; + + case WSAEPROTONOSUPPORT: + msg = "Protocol not supported"; + break; + + case WSAESOCKTNOSUPPORT: + msg = "Socket type not supported"; + break; + + case WSAEOPNOTSUPP: + msg = "Operation not supported on socket"; + break; + + case WSAEPFNOSUPPORT: + msg = "Protocol family not supported"; + break; + + case WSAEAFNOSUPPORT: + msg = "Address family not supported"; + break; + + case WSAEADDRINUSE: + msg = "Address already in use"; + break; + + case WSAEADDRNOTAVAIL: + msg = "Can't assign requested address"; + break; + + case WSAENETDOWN: + msg = "Network is down"; + break; + + case WSAENETUNREACH: + msg = "Network is unreachable"; + break; + + case WSAENETRESET: + msg = "Net connection reset"; + break; + + case WSAECONNABORTED: + msg = "Software caused connection abort"; + break; + + case WSAECONNRESET: + msg = "Connection reset by peer"; + break; + + case WSAENOBUFS: + msg = "No buffer space available"; + break; + + case WSAEISCONN: + msg = "Socket is already connected"; + break; + + case WSAENOTCONN: + msg = "Socket is not connected"; + break; + + case WSAESHUTDOWN: + msg = "Can't send after socket shutdown"; + break; + + case WSAETOOMANYREFS: + msg = "Too many references: can't splice"; + break; + + case WSAETIMEDOUT: + msg = "Connection timed out"; + break; + + case WSAECONNREFUSED: + msg = "Connection refused"; + break; + + case WSAELOOP: + msg = "Too many levels of symbolic links"; + break; + + case WSAENAMETOOLONG: + msg = "File name too long"; + break; + + case WSAEHOSTDOWN: + msg = "Host is down"; + break; + + case WSAEHOSTUNREACH: + msg = "No route to host"; + break; + + case WSAENOTEMPTY: + msg = "Directory not empty"; + break; + + case WSAEPROCLIM: + msg = "Too many processes"; + break; + + case WSAEUSERS: + msg = "Too many users"; + break; + + case WSAEDQUOT: + msg = "Disc quota exceeded"; + break; + + case WSAESTALE: + msg = "Stale NFS file handle"; + break; + + case WSAEREMOTE: + msg = "Too many levels of remote in path"; + break; + + case WSASYSNOTREADY: + msg = "Network system is unavailable"; + break; + + case WSAVERNOTSUPPORTED: + msg = "Winsock version out of range"; + break; + + case WSANOTINITIALISED: + msg = "WSAStartup not yet called"; + break; + + case WSAEDISCON: + msg = "Graceful shutdown in progress"; + break; +/* + case WSAHOST_NOT_FOUND: + msg = "Host not found"; + break; + + case WSANO_DATA: + msg = "No host data of that type was found"; + break; +*/ + default: + msg = NULL; + break; + } + return (msg); +} + +/* + * These error messages are more informative about CryptAPI Errors than the + * standard error messages + */ + +char * +GetCryptErrorMessage(int errval) { + char *msg; + + switch (errval) { + + case NTE_BAD_FLAGS: + msg = "The dwFlags parameter has an illegal value."; + break; + case NTE_BAD_KEYSET: + msg = "The Registry entry for the key container " + "could not be opened and may not exist."; + break; + case NTE_BAD_KEYSET_PARAM: + msg = "The pszContainer or pszProvider parameter " + "is set to an illegal value."; + break; + case NTE_BAD_PROV_TYPE: + msg = "The value of the dwProvType parameter is out " + "of range. All provider types must be from " + "1 to 999, inclusive."; + break; + case NTE_BAD_SIGNATURE: + msg = "The provider DLL signature did not verify " + "correctly. Either the DLL or the digital " + "signature has been tampered with."; + break; + case NTE_EXISTS: + msg = "The dwFlags parameter is CRYPT_NEWKEYSET, but the key" + " container already exists."; + break; + case NTE_KEYSET_ENTRY_BAD: + msg = "The Registry entry for the pszContainer key container " + "was found (in the HKEY_CURRENT_USER window), but is " + "corrupt. See the section System Administration for " + " etails about CryptoAPI's Registry usage."; + break; + case NTE_KEYSET_NOT_DEF: + msg = "No Registry entry exists in the HKEY_CURRENT_USER " + "window for the key container specified by " + "pszContainer."; + break; + case NTE_NO_MEMORY: + msg = "The CSP ran out of memory during the operation."; + break; + case NTE_PROV_DLL_NOT_FOUND: + msg = "The provider DLL file does not exist or is not on the " + "current path."; + break; + case NTE_PROV_TYPE_ENTRY_BAD: + msg = "The Registry entry for the provider type specified by " + "dwProvType is corrupt. This error may relate to " + "either the user default CSP list or the machine " + "default CSP list. See the section System " + "Administration for details about CryptoAPI's " + "Registry usage."; + break; + case NTE_PROV_TYPE_NO_MATCH: + msg = "The provider type specified by dwProvType does not " + "match the provider type found in the Registry. Note " + "that this error can only occur when pszProvider " + "specifies an actual CSP name."; + break; + case NTE_PROV_TYPE_NOT_DEF: + msg = "No Registry entry exists for the provider type " + "specified by dwProvType."; + break; + case NTE_PROVIDER_DLL_FAIL: + msg = "The provider DLL file could not be loaded, and " + "may not exist. If it exists, then the file is " + "not a valid DLL."; + break; + case NTE_SIGNATURE_FILE_BAD: + msg = "An error occurred while loading the DLL file image, " + "prior to verifying its signature."; + break; + + default: + msg = NULL; + break; + } + return msg; +} +