aboutsummaryrefslogtreecommitdiff
path: root/src/interfaces
diff options
context:
space:
mode:
Diffstat (limited to 'src/interfaces')
-rw-r--r--src/interfaces/libpq/fe-misc.c47
-rw-r--r--src/interfaces/libpq/win32.c182
-rw-r--r--src/interfaces/libpq/win32.mak7
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= \