diff -u3 -H -B -w -r CVS-latest\lib\connect.c lib\connect.c --- CVS-latest\lib\connect.c Tue Mar 23 16:48:27 2004 +++ lib\connect.c Tue Mar 23 17:15:20 2004 @@ -86,6 +86,7 @@ #include "urldata.h" #include "sendf.h" #include "if2ip.h" +#include "curl_strerror.h" #include "connect.h" /* The last #include file should be: */ @@ -295,7 +296,7 @@ if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, data->set.device, strlen(data->set.device)+1) != 0) { /* printf("Failed to BINDTODEVICE, socket: %d device: %s error: %s\n", - sockfd, data->set.device, strerror(Curl_ourerrno())); */ + sockfd, data->set.device, Curl_strerror(Curl_ourerrno())); */ infof(data, "SO_BINDTODEVICE %s failed\n", data->set.device); /* This is typically "errno 1, error: Operation not permitted" if @@ -353,36 +354,7 @@ } #endif if(!bindworked) { - int err = Curl_ourerrno(); - switch(err) { - case EBADF: - failf(data, "Invalid descriptor: %d", err); - break; - case EINVAL: - failf(data, "Invalid request: %d", err); - break; - case EACCES: - failf(data, "Address is protected, user not superuser: %d", err); - break; - case ENOTSOCK: - failf(data, - "Argument is a descriptor for a file, not a socket: %d", - err); - break; - case EFAULT: - failf(data, "Inaccessable memory error: %d", err); - break; - case ENAMETOOLONG: - failf(data, "Address too long: %d", err); - break; - case ENOMEM: - failf(data, "Insufficient kernel memory was available: %d", err); - break; - default: - failf(data, "errno %d", err); - break; - } /* end of switch(err) */ - + failf(data, Curl_strerror(conn,Curl_ourerrno())); return CURLE_HTTP_PORT_FAILED; } /* end of else */ @@ -489,8 +461,8 @@ } else if(1 != rc) { int error = Curl_ourerrno(); - failf(data, "Failed connect to %s:%d, errno: %d", - conn->hostname, conn->port, error); + failf(data, "Failed connect to %s:%d; %s", + conn->hostname, conn->port, Curl_strerror(conn,error)); return CURLE_COULDNT_CONNECT; } /* @@ -652,8 +624,8 @@ break; default: /* unknown error, fallthrough and try another address! */ - failf(data, "Failed to connect to %s IP number %d: %d", - hostname, aliasindex+1, error); + failf(data, "Failed to connect to %s IP number %d: %s", + hostname, aliasindex+1, Curl_strerror(conn,error)); break; } } diff -u3 -H -B -w -r CVS-latest\lib\curl_strerror.c lib\curl_strerror.c --- CVS-latest\lib\curl_strerror.c Mon Mar 15 12:51:32 2004 +++ lib\curl_strerror.c Tue Mar 23 17:04:28 2004 @@ -21,6 +21,12 @@ ***************************************************************************/ #include +#include "setup.h" +#include +#include +#include + +#include "urldata.h" const char * curl_easy_strerror(CURLcode error) @@ -293,4 +299,231 @@ } return "CURLSH unknown"; +} + +#if defined(WIN32) && !defined(__CYGWIN__) + +/* This function handles most / all (?) Winsock errors cURL is able to produce. + */ +static const char * +get_winsock_error (int err, char *buf, size_t len) +{ +#ifndef HAVE_NLS +#define _(str) str +#endif + + char *p; + + switch (err) + { + case WSAEINTR: + p = _("Call interrupted."); + break; + case WSAEBADF: + p = _("Bad file"); + break; + case WSAEACCES: + p = _("Bad access"); + break; + case WSAEFAULT: + p = _("Bad argument"); + break; + case WSAEINVAL: + p = _("Invalid arguments"); + break; + case WSAEMFILE: + p = _("Out of file descriptors"); + break; + case WSAEWOULDBLOCK: + p = _("Call would block"); + break; + case WSAEINPROGRESS: + case WSAEALREADY: + p = _("Blocking call progress"); + break; + case WSAENOTSOCK: + p = _("Descriptor is not a socket."); + break; + case WSAEDESTADDRREQ: + p = _("Need destination address"); + break; + case WSAEMSGSIZE: + p = _("Bad message size"); + break; + case WSAEPROTOTYPE: + p = _("Bad protocol"); + break; + case WSAENOPROTOOPT: + p = _("Protocol option is unsupported"); + break; + case WSAEPROTONOSUPPORT: + p = _("Protocol is unsupported"); + break; + case WSAESOCKTNOSUPPORT: + p = _("Socket is unsupported"); + break; + case WSAEOPNOTSUPP: + p = _("Operation not supported"); + break; + case WSAEAFNOSUPPORT: + p = _("Address family not supported"); + break; + case WSAEPFNOSUPPORT: + p = _("Protocol family not supported"); + break; + case WSAEADDRINUSE: + p = _("Address already in use"); + break; + case WSAEADDRNOTAVAIL: + p = _("Address not available"); + break; + case WSAENETDOWN: + p = _("Network down"); + break; + case WSAENETUNREACH: + p = _("Network unreachable"); + break; + case WSAENETRESET: + p = _("Network has been reset"); + break; + case WSAECONNABORTED: + p = _("Connection was aborted"); + break; + case WSAECONNRESET: + p = _("Connection was reset"); + break; + case WSAENOBUFS: + p = _("No buffer space"); + break; + case WSAEISCONN: + p = _("Socket is already connected"); + break; + case WSAENOTCONN: + p = _("Socket is not connected"); + break; + case WSAESHUTDOWN: + p = _("Socket has been shut down"); + break; + case WSAETOOMANYREFS: + p = _("Too many references"); + break; + case WSAETIMEDOUT: + p = _("Timed out"); + break; + case WSAECONNREFUSED: + p = _("Connection refused"); + break; + case WSAELOOP: + p = _("Loop??"); + break; + case WSAENAMETOOLONG: + p = _("Name too long"); + break; + case WSAEHOSTDOWN: + p = _("Host down"); + break; + case WSAEHOSTUNREACH: + p = _("Host unreachable"); + break; + case WSAENOTEMPTY: + p = _("Not empty"); + break; + case WSAEPROCLIM: + p = _("Process limit reached"); + break; + case WSAEUSERS: + p = _("Too many users"); + break; + case WSAEDQUOT: + p = _("Bad quota"); + break; + case WSAESTALE: + p = _("Something is stale"); + break; + case WSAEREMOTE: + p = _("Remote error"); + break; + case WSAEDISCON: + p = _("Disconnected"); + break; + + /* Extended Winsock errors */ + case WSASYSNOTREADY: + p = _("Winsock library is not ready"); + break; + case WSANOTINITIALISED: + p = _("Winsock library not initalised"); + break; + case WSAVERNOTSUPPORTED: + p = _("Winsock version not supported."); + break; + + /* getXbyY() errors (already handled in herrmsg): + * Authoritative Answer: Host not found */ + case WSAHOST_NOT_FOUND: + p = _("Host not found"); + break; + + /* Non-Authoritative: Host not found, or SERVERFAIL */ + case WSATRY_AGAIN: + p = _("Host not found, try again"); + break; + + /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */ + case WSANO_RECOVERY: + p = _("Unrecoverable error in call to nameserver"); + break; + + /* Valid name, no data record of requested type */ + case WSANO_DATA: + p = _("No data record of requested type"); + break; + + default: + return NULL; + } + strncpy (buf, p, len); + buf [len-1] = '\0'; + return buf; +} +#endif /* WIN32 && !__CYGWIN__ */ + +/* + * Our thread-safe and smart strerror() replacement. + */ +const char *Curl_strerror (struct connectdata *conn, int err) +{ + char *buf, *p; + size_t max; + + if (!conn) + return ("No 'conn' data"); + + buf = conn->syserr_buf; + max = sizeof(conn->syserr_buf)-1; + *buf = '\0'; + if (err >= 0 && err < sys_nerr) { + /* These should be atomic and hopefully thread-safe */ +#ifdef HAVE_STRERROR_R + strerror_r (err, buf, max); /* this may set ERANGE! */ +#else + strncpy (buf, strerror(err), max); +#endif + *(buf+max) = '\0'; + } +#if defined(WIN32) && !defined(__CYGWIN__) + else { + if (!get_winsock_error (err, buf, max) && + !FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, + LANG_NEUTRAL, buf, max, NULL)) + snprintf (buf, max, "Unknown error %d (%#x)", err, err); + } +#endif + + /* strip trailing '\r\n' or '\n'. */ + if ((p = strrchr(buf,'\n')) != NULL && (p - buf) >= 2) + *p = '\0'; + if ((p = strrchr(buf,'\r')) != NULL && (p - buf) >= 1) + *p = '\0'; + return buf; } diff -u3 -H -B -w -r CVS-latest\lib\ftp.c lib\ftp.c --- CVS-latest\lib\ftp.c Wed Mar 17 13:46:45 2004 +++ lib\ftp.c Tue Mar 23 17:02:47 2004 @@ -91,6 +91,7 @@ #include "strequal.h" #include "ssluse.h" #include "connect.h" +#include "curl_strerror.h" #if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL) #include "inet_ntoa_r.h" @@ -1138,6 +1139,7 @@ const char *mode[] = { "EPRT", "LPRT", "PORT", NULL }; char **modep; int rc; + int error; /* * we should use Curl_if2ip? given pickiness of recent ftpd, @@ -1172,6 +1174,7 @@ } portsock = CURL_SOCKET_BAD; + error = 0; for (ai = res; ai; ai = ai->ai_next) { /* * Workaround for AIX5 getaddrinfo() problem (it doesn't set ai_socktype): @@ -1180,16 +1183,20 @@ ai->ai_socktype = hints.ai_socktype; portsock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); - if (portsock == CURL_SOCKET_BAD) + if (portsock == CURL_SOCKET_BAD) { + error = Curl_ourerrno(); continue; + } if (bind(portsock, ai->ai_addr, ai->ai_addrlen) < 0) { + error = Curl_ourerrno(); sclose(portsock); portsock = CURL_SOCKET_BAD; continue; } if (listen(portsock, 1) < 0) { + error = Curl_ourerrno(); sclose(portsock); portsock = CURL_SOCKET_BAD; continue; @@ -1199,13 +1206,13 @@ } freeaddrinfo(res); if (portsock == CURL_SOCKET_BAD) { - failf(data, "%s", strerror(errno)); + failf(data, "%s", Curl_strerror(conn,error)); return CURLE_FTP_PORT_FAILED; } sslen = sizeof(ss); if (getsockname(portsock, sa, &sslen) < 0) { - failf(data, "%s", strerror(errno)); + failf(data, "%s", Curl_strerror(conn,Curl_ourerrno())); return CURLE_FTP_PORT_FAILED; } diff -u3 -H -B -w -r CVS-latest\lib\urldata.h lib\urldata.h --- CVS-latest\lib\urldata.h Tue Mar 23 17:01:31 2004 +++ lib\urldata.h Tue Mar 23 17:13:05 2004 @@ -572,6 +572,8 @@ int sockerror; /* errno stored by Curl_read() if the underlying layer returns error */ + char syserr_buf [256]; /* buffer for Curl_strerror() */ + #if defined(USE_ARES) || defined(USE_THREADING_GETHOSTBYNAME) /* data used for the asynch name resolve callback */ struct Curl_async async; Only in lib: version.c