00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #define VC_EXTRALEAN
00026 #ifndef __MINGW32__
00027 #define NOGDI
00028 #endif
00029 #define NOCRYPT
00030
00031 #include "postgres_fe.h"
00032
00033 #include "win32.h"
00034
00035
00036 #ifdef ENABLE_NLS
00037 extern char *
00038 libpq_gettext(const char *msgid)
00039 __attribute__((format_arg(1)));
00040 #else
00041 #define libpq_gettext(x) (x)
00042 #endif
00043
00044
00045 static struct WSErrorEntry
00046 {
00047 DWORD error;
00048 const char *description;
00049 } WSErrors[] =
00050
00051 {
00052 {
00053 0, "No error"
00054 },
00055 {
00056 WSAEINTR, "Interrupted system call"
00057 },
00058 {
00059 WSAEBADF, "Bad file number"
00060 },
00061 {
00062 WSAEACCES, "Permission denied"
00063 },
00064 {
00065 WSAEFAULT, "Bad address"
00066 },
00067 {
00068 WSAEINVAL, "Invalid argument"
00069 },
00070 {
00071 WSAEMFILE, "Too many open sockets"
00072 },
00073 {
00074 WSAEWOULDBLOCK, "Operation would block"
00075 },
00076 {
00077 WSAEINPROGRESS, "Operation now in progress"
00078 },
00079 {
00080 WSAEALREADY, "Operation already in progress"
00081 },
00082 {
00083 WSAENOTSOCK, "Socket operation on non-socket"
00084 },
00085 {
00086 WSAEDESTADDRREQ, "Destination address required"
00087 },
00088 {
00089 WSAEMSGSIZE, "Message too long"
00090 },
00091 {
00092 WSAEPROTOTYPE, "Protocol wrong type for socket"
00093 },
00094 {
00095 WSAENOPROTOOPT, "Bad protocol option"
00096 },
00097 {
00098 WSAEPROTONOSUPPORT, "Protocol not supported"
00099 },
00100 {
00101 WSAESOCKTNOSUPPORT, "Socket type not supported"
00102 },
00103 {
00104 WSAEOPNOTSUPP, "Operation not supported on socket"
00105 },
00106 {
00107 WSAEPFNOSUPPORT, "Protocol family not supported"
00108 },
00109 {
00110 WSAEAFNOSUPPORT, "Address family not supported"
00111 },
00112 {
00113 WSAEADDRINUSE, "Address already in use"
00114 },
00115 {
00116 WSAEADDRNOTAVAIL, "Cannot assign requested address"
00117 },
00118 {
00119 WSAENETDOWN, "Network is down"
00120 },
00121 {
00122 WSAENETUNREACH, "Network is unreachable"
00123 },
00124 {
00125 WSAENETRESET, "Net connection reset"
00126 },
00127 {
00128 WSAECONNABORTED, "Software caused connection abort"
00129 },
00130 {
00131 WSAECONNRESET, "Connection reset by peer"
00132 },
00133 {
00134 WSAENOBUFS, "No buffer space available"
00135 },
00136 {
00137 WSAEISCONN, "Socket is already connected"
00138 },
00139 {
00140 WSAENOTCONN, "Socket is not connected"
00141 },
00142 {
00143 WSAESHUTDOWN, "Cannot send after socket shutdown"
00144 },
00145 {
00146 WSAETOOMANYREFS, "Too many references, cannot splice"
00147 },
00148 {
00149 WSAETIMEDOUT, "Connection timed out"
00150 },
00151 {
00152 WSAECONNREFUSED, "Connection refused"
00153 },
00154 {
00155 WSAELOOP, "Too many levels of symbolic links"
00156 },
00157 {
00158 WSAENAMETOOLONG, "File name too long"
00159 },
00160 {
00161 WSAEHOSTDOWN, "Host is down"
00162 },
00163 {
00164 WSAEHOSTUNREACH, "No route to host"
00165 },
00166 {
00167 WSAENOTEMPTY, "Directory not empty"
00168 },
00169 {
00170 WSAEPROCLIM, "Too many processes"
00171 },
00172 {
00173 WSAEUSERS, "Too many users"
00174 },
00175 {
00176 WSAEDQUOT, "Disc quota exceeded"
00177 },
00178 {
00179 WSAESTALE, "Stale NFS file handle"
00180 },
00181 {
00182 WSAEREMOTE, "Too many levels of remote in path"
00183 },
00184 {
00185 WSASYSNOTREADY, "Network system is unavailable"
00186 },
00187 {
00188 WSAVERNOTSUPPORTED, "Winsock version out of range"
00189 },
00190 {
00191 WSANOTINITIALISED, "WSAStartup not yet called"
00192 },
00193 {
00194 WSAEDISCON, "Graceful shutdown in progress"
00195 },
00196 {
00197 WSAHOST_NOT_FOUND, "Host not found"
00198 },
00199 {
00200 WSATRY_AGAIN, "NA Host not found / SERVFAIL"
00201 },
00202 {
00203 WSANO_RECOVERY, "Non recoverable FORMERR||REFUSED||NOTIMP"
00204 },
00205 {
00206 WSANO_DATA, "No host data of that type was found"
00207 },
00208 {
00209 0, 0
00210 }
00211 };
00212
00213
00214
00215
00216
00217
00218
00219 static int
00220 LookupWSErrorMessage(DWORD err, char *dest)
00221 {
00222 struct WSErrorEntry *e;
00223
00224 for (e = WSErrors; e->description; e++)
00225 {
00226 if (e->error == err)
00227 {
00228 strcpy(dest, e->description);
00229 return 1;
00230 }
00231 }
00232 return 0;
00233 }
00234
00235
00236 struct MessageDLL
00237 {
00238 const char *dll_name;
00239 void *handle;
00240 int loaded;
00241 } dlls[] =
00242
00243 {
00244 {
00245 "netmsg.dll", 0, 0
00246 },
00247 {
00248 "winsock.dll", 0, 0
00249 },
00250 {
00251 "wsock32.dll", 0, 0
00252 },
00253 {
00254 "ws2_32.dll", 0, 0
00255 },
00256 {
00257 "wsock32n.dll", 0, 0
00258 },
00259 {
00260 "mswsock.dll", 0, 0
00261 },
00262 {
00263 "ws2help.dll", 0, 0
00264 },
00265 {
00266 "ws2thk.dll", 0, 0
00267 },
00268 {
00269 0, 0, 1
00270 }
00271 };
00272
00273 #define DLLS_SIZE (sizeof(dlls)/sizeof(struct MessageDLL))
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285 const char *
00286 winsock_strerror(int err, char *strerrbuf, size_t buflen)
00287 {
00288 unsigned long flags;
00289 int offs,
00290 i;
00291 int success = LookupWSErrorMessage(err, strerrbuf);
00292
00293 for (i = 0; !success && i < DLLS_SIZE; i++)
00294 {
00295
00296 if (!dlls[i].loaded)
00297 {
00298 dlls[i].loaded = 1;
00299 dlls[i].handle = (void *) LoadLibraryEx(
00300 dlls[i].dll_name,
00301 0,
00302 LOAD_LIBRARY_AS_DATAFILE);
00303 }
00304
00305 if (dlls[i].dll_name && !dlls[i].handle)
00306 continue;
00307
00308 flags = FORMAT_MESSAGE_FROM_SYSTEM
00309 | FORMAT_MESSAGE_IGNORE_INSERTS
00310 | (dlls[i].handle ? FORMAT_MESSAGE_FROM_HMODULE : 0);
00311
00312 success = 0 != FormatMessage(
00313 flags,
00314 dlls[i].handle, err,
00315 MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT),
00316 strerrbuf, buflen - 64,
00317 0
00318 );
00319 }
00320
00321 if (!success)
00322 sprintf(strerrbuf, libpq_gettext("unrecognized socket error: 0x%08X/%d"), err, err);
00323 else
00324 {
00325 strerrbuf[buflen - 1] = '\0';
00326 offs = strlen(strerrbuf);
00327 if (offs > (int) buflen - 64)
00328 offs = buflen - 64;
00329 sprintf(strerrbuf + offs, " (0x%08X/%d)", err, err);
00330 }
00331 return strerrbuf;
00332 }