mirror of
https://github.com/simtactics/niotso.git
synced 2025-03-20 10:11:21 +00:00
333 lines
5.8 KiB
C
333 lines
5.8 KiB
C
|
/*
|
||
|
* src/interfaces/libpq/win32.c
|
||
|
*
|
||
|
*
|
||
|
* 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-2011, PostgreSQL Global Development Group
|
||
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
/* Make stuff compile faster by excluding not used stuff */
|
||
|
|
||
|
#define VC_EXTRALEAN
|
||
|
#ifndef __MINGW32__
|
||
|
#define NOGDI
|
||
|
#endif
|
||
|
#define NOCRYPT
|
||
|
|
||
|
#include "postgres_fe.h"
|
||
|
|
||
|
#include "win32.h"
|
||
|
|
||
|
/* Declared here to avoid pulling in all includes, which causes name collissions */
|
||
|
#ifdef ENABLE_NLS
|
||
|
extern char *
|
||
|
libpq_gettext(const char *msgid)
|
||
|
__attribute__((format_arg(1)));
|
||
|
#else
|
||
|
#define libpq_gettext(x) (x)
|
||
|
#endif
|
||
|
|
||
|
|
||
|
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, "Cannot 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, "Cannot send after socket shutdown"
|
||
|
},
|
||
|
{
|
||
|
WSAETOOMANYREFS, "Too many references, cannot 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, char *strerrbuf, size_t buflen)
|
||
|
{
|
||
|
unsigned long flags;
|
||
|
int offs,
|
||
|
i;
|
||
|
int success = LookupWSErrorMessage(err, strerrbuf);
|
||
|
|
||
|
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_ENGLISH, SUBLANG_DEFAULT),
|
||
|
strerrbuf, buflen - 64,
|
||
|
0
|
||
|
);
|
||
|
}
|
||
|
|
||
|
if (!success)
|
||
|
sprintf(strerrbuf, libpq_gettext("Unknown socket error (0x%08X/%i)"), err, err);
|
||
|
else
|
||
|
{
|
||
|
strerrbuf[buflen - 1] = '\0';
|
||
|
offs = strlen(strerrbuf);
|
||
|
if (offs > (int) buflen - 64)
|
||
|
offs = buflen - 64;
|
||
|
sprintf(strerrbuf + offs, " (0x%08X/%i)", err, err);
|
||
|
}
|
||
|
return strerrbuf;
|
||
|
}
|