diff options
Diffstat (limited to 'src/interfaces')
-rw-r--r-- | src/interfaces/libpq/fe-misc.c | 47 | ||||
-rw-r--r-- | src/interfaces/libpq/win32.c | 182 | ||||
-rw-r--r-- | src/interfaces/libpq/win32.mak | 7 |
3 files changed, 187 insertions, 49 deletions
diff --git a/src/interfaces/libpq/fe-misc.c b/src/interfaces/libpq/fe-misc.c index 190d378fd9a..643c81055fc 100644 --- a/src/interfaces/libpq/fe-misc.c +++ b/src/interfaces/libpq/fe-misc.c @@ -25,7 +25,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.69 2002/04/15 23:34:17 momjian Exp $ + * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.70 2002/04/24 02:26:06 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -37,8 +37,6 @@ #include <time.h> #ifdef WIN32 -#define WIN32_LEAN_AND_MEAN -#include <windows.h> #include "win32.h" #else #include <unistd.h> @@ -894,46 +892,3 @@ libpq_gettext(const char *msgid) return dgettext("libpq", msgid); } #endif /* ENABLE_NLS */ - -#ifdef WIN32 -/* - * strerror replacement for windows: - * - * This works on WIN2000 and newer, but we don't know where to find WinSock - * error strings on older Windows flavors. If you know, clue us in. - */ -const char * -winsock_strerror(int eno) -{ - static char err_buf[512]; -#define WSSE_MAXLEN (sizeof(err_buf)-1-13) /* 13 for " (0x00000000)" */ - int length; - - /* First try the "system table", this works on Win2k and up */ - - if (FormatMessage( - FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, - 0, - eno, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - err_buf, - WSSE_MAXLEN, - NULL)) - goto WSSE_GOODEXIT; - - /* Insert other possible lookup methods here ... */ - - /* Everything failed, just tell the user that we don't know the desc */ - - strcpy(err_buf, "Socket error, no description available."); - -WSSE_GOODEXIT: - - length = strlen(err_buf); - sprintf(err_buf + (length < WSSE_MAXLEN ? length : WSSE_MAXLEN), - " (0x%08X)", eno); - - return err_buf; -} - -#endif diff --git a/src/interfaces/libpq/win32.c b/src/interfaces/libpq/win32.c new file mode 100644 index 00000000000..9c7d379456c --- /dev/null +++ b/src/interfaces/libpq/win32.c @@ -0,0 +1,182 @@ +/* + * FILE + * win32.c + * + * DESCRIPTION + * Win32 support functions. + * + * Contains table and functions for looking up win32 socket error + * descriptions. But will/may contain other win32 helper functions + * for libpq. + * + * The error constants are taken from the Frambak Bakfram LGSOCKET + * library guys who in turn took them from the Winsock FAQ. + * + * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + */ + +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#include <winsock.h> +#include <stdio.h> +#include "win32.h" + +static struct WSErrorEntry { + DWORD error; + const char* description; +} WSErrors [] = { + {0, "No error"}, + {WSAEINTR, "Interrupted system call"}, + {WSAEBADF, "Bad file number"}, + {WSAEACCES, "Permission denied"}, + {WSAEFAULT, "Bad address"}, + {WSAEINVAL, "Invalid argument"}, + {WSAEMFILE, "Too many open sockets"}, + {WSAEWOULDBLOCK, "Operation would block"}, + {WSAEINPROGRESS, "Operation now in progress"}, + {WSAEALREADY, "Operation already in progress"}, + {WSAENOTSOCK, "Socket operation on non-socket"}, + {WSAEDESTADDRREQ, "Destination address required"}, + {WSAEMSGSIZE, "Message too long"}, + {WSAEPROTOTYPE, "Protocol wrong type for socket"}, + {WSAENOPROTOOPT, "Bad protocol option"}, + {WSAEPROTONOSUPPORT, "Protocol not supported"}, + {WSAESOCKTNOSUPPORT, "Socket type not supported"}, + {WSAEOPNOTSUPP, "Operation not supported on socket"}, + {WSAEPFNOSUPPORT, "Protocol family not supported"}, + {WSAEAFNOSUPPORT, "Address family not supported"}, + {WSAEADDRINUSE, "Address already in use"}, + {WSAEADDRNOTAVAIL, "Can't assign requested address"}, + {WSAENETDOWN, "Network is down"}, + {WSAENETUNREACH, "Network is unreachable"}, + {WSAENETRESET, "Net connection reset"}, + {WSAECONNABORTED, "Software caused connection abort"}, + {WSAECONNRESET, "Connection reset by peer"}, + {WSAENOBUFS, "No buffer space available"}, + {WSAEISCONN, "Socket is already connected"}, + {WSAENOTCONN, "Socket is not connected"}, + {WSAESHUTDOWN, "Can't send after socket shutdown"}, + {WSAETOOMANYREFS, "Too many references, can't splice"}, + {WSAETIMEDOUT, "Connection timed out"}, + {WSAECONNREFUSED, "Connection refused"}, + {WSAELOOP, "Too many levels of symbolic links"}, + {WSAENAMETOOLONG, "File name too long"}, + {WSAEHOSTDOWN, "Host is down"}, + {WSAEHOSTUNREACH, "No route to host"}, + {WSAENOTEMPTY, "Directory not empty"}, + {WSAEPROCLIM, "Too many processes"}, + {WSAEUSERS, "Too many users"}, + {WSAEDQUOT, "Disc quota exceeded"}, + {WSAESTALE, "Stale NFS file handle"}, + {WSAEREMOTE, "Too many levels of remote in path"}, + {WSASYSNOTREADY, "Network system is unavailable"}, + {WSAVERNOTSUPPORTED, "Winsock version out of range"}, + {WSANOTINITIALISED, "WSAStartup not yet called"}, + {WSAEDISCON, "Graceful shutdown in progress"}, + {WSAHOST_NOT_FOUND, "Host not found"}, + {WSATRY_AGAIN, "NA Host not found / SERVFAIL"}, + {WSANO_RECOVERY, "Non recoverable FORMERR||REFUSED||NOTIMP"}, + {WSANO_DATA, "No host data of that type was found"}, + {0,0} /* End of table */ +}; + + +/* + * Returns 0 if not found, linear but who cares, at this moment + * we're already in pain :) + */ + +static int LookupWSErrorMessage(DWORD err,char*dest) +{ + struct WSErrorEntry *e; + for (e = WSErrors;e->description;e++) + { + if (e->error == err) + { + strcpy(dest,e->description); + return 1; + } + } + return 0; +} + + +struct MessageDLL{ + const char *dll_name; + void *handle; + int loaded; /* BOOL */ +}dlls[]={ + {"netmsg.dll",0,0}, + {"winsock.dll",0,0}, + {"wsock32.dll",0,0}, + {"ws2_32.dll",0,0}, + {"wsock32n.dll",0,0}, + {"mswsock.dll",0,0}, + {"ws2help.dll",0,0}, + {"ws2thk.dll",0,0}, + {0,0,1} /* Last one, no dll, always loaded */ +}; + +#define DLLS_SIZE (sizeof(dlls)/sizeof(struct MessageDLL)) + +/* + * Returns a description of the socket error by first trying + * to find it in the lookup table, and if that fails, tries + * to load any of the winsock dlls to find that message. + * The DLL thing works from Nt4 (spX ?) up, but some special + * versions of winsock might have this aswell (seen on Win98 SE + * special install) / Magnus Naeslund (mag@fbab.net) + * + */ + +const char *winsock_strerror(int err){ + static char buf[512]; /* Not threadsafe */ + unsigned long flags; + int offs,i; + int success = LookupWSErrorMessage(err,buf); + + for (i=0;!success && i<DLLS_SIZE;i++) + { + + if (!dlls[i].loaded) + { + dlls[i].loaded = 1; /* Only load once */ + dlls[i].handle = (void*)LoadLibraryEx( + dlls[i].dll_name, + 0, + LOAD_LIBRARY_AS_DATAFILE); + } + + if (dlls[i].dll_name && !dlls[i].handle) + continue; /* Didn't load */ + + flags = FORMAT_MESSAGE_FROM_SYSTEM + | FORMAT_MESSAGE_IGNORE_INSERTS + | (dlls[i].handle?FORMAT_MESSAGE_FROM_HMODULE:0); + + success = 0 != FormatMessage( + flags, + dlls[i].handle,err, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + buf,sizeof(buf)-64, + 0 + ); + } + + if (!success) + { + sprintf(buf,"Unknown socket error (0x%08X/%lu)",err,err); + } + else + { + buf[sizeof(buf)-1]='\0'; + offs = strlen(buf); + if (offs>sizeof(buf)-64) + offs = sizeof(buf)-64; + sprintf(buf+offs," (0x%08X/%lu)",err,err); + } + return buf; +} + diff --git a/src/interfaces/libpq/win32.mak b/src/interfaces/libpq/win32.mak index ea433eafac3..98b4e986ef9 100644 --- a/src/interfaces/libpq/win32.mak +++ b/src/interfaces/libpq/win32.mak @@ -64,6 +64,7 @@ CLEAN : -@erase "$(INTDIR)\fe-print.obj" -@erase "$(INTDIR)\pqexpbuffer.obj" -@erase "$(OUTDIR)\libpqdll.obj" + -@erase "$(OUTDIR)\win32.obj" -@erase "$(OUTDIR)\libpq.lib" -@erase "$(OUTDIR)\libpq.dll" -@erase "$(OUTDIR)\libpq.res" @@ -96,6 +97,7 @@ CPP_SBRS=. LIB32=link.exe -lib LIB32_FLAGS=/nologo /out:"$(OUTDIR)\libpq.lib" LIB32_OBJS= \ + "$(OUTDIR)\win32.obj" \ "$(INTDIR)\dllist.obj" \ "$(INTDIR)\md5.obj" \ "$(INTDIR)\fe-auth.obj" \ @@ -113,9 +115,8 @@ LIB32_OBJS = $(LIB32_OBJS) "$(INTDIR)\wchar.obj" "$(INTDIR)\encnames.obj" RSC_PROJ=/l 0x409 /fo"$(INTDIR)\libpq.res" LINK32=link.exe -LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ - advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib wsock32.lib\ - odbccp32.lib /nologo /subsystem:windows /dll /incremental:no\ +LINK32_FLAGS=kernel32.lib user32.lib advapi32.lib wsock32.lib\ + /nologo /subsystem:windows /dll /incremental:no\ /pdb:"$(OUTDIR)\libpqdll.pdb" /machine:I386 /out:"$(OUTDIR)\libpq.dll"\ /implib:"$(OUTDIR)\libpqdll.lib" /def:libpqdll.def LINK32_OBJS= \ |