Home | History | Annotate | Download | only in lib
      1 /***************************************************************************
      2  *                                  _   _ ____  _
      3  *  Project                     ___| | | |  _ \| |
      4  *                             / __| | | | |_) | |
      5  *                            | (__| |_| |  _ <| |___
      6  *                             \___|\___/|_| \_\_____|
      7  *
      8  * Copyright (C) 2004 - 2019, Daniel Stenberg, <daniel (at) haxx.se>, et al.
      9  *
     10  * This software is licensed as described in the file COPYING, which
     11  * you should have received as part of this distribution. The terms
     12  * are also available at https://curl.haxx.se/docs/copyright.html.
     13  *
     14  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
     15  * copies of the Software, and permit persons to whom the Software is
     16  * furnished to do so, under the terms of the COPYING file.
     17  *
     18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
     19  * KIND, either express or implied.
     20  *
     21  ***************************************************************************/
     22 
     23 #include "curl_setup.h"
     24 
     25 #ifdef HAVE_STRERROR_R
     26 #  if (!defined(HAVE_POSIX_STRERROR_R) && \
     27        !defined(HAVE_GLIBC_STRERROR_R) && \
     28        !defined(HAVE_VXWORKS_STRERROR_R)) || \
     29       (defined(HAVE_POSIX_STRERROR_R) && defined(HAVE_VXWORKS_STRERROR_R)) || \
     30       (defined(HAVE_GLIBC_STRERROR_R) && defined(HAVE_VXWORKS_STRERROR_R)) || \
     31       (defined(HAVE_POSIX_STRERROR_R) && defined(HAVE_GLIBC_STRERROR_R))
     32 #    error "strerror_r MUST be either POSIX, glibc or vxworks-style"
     33 #  endif
     34 #endif
     35 
     36 #include <curl/curl.h>
     37 
     38 #ifdef USE_LIBIDN2
     39 #include <idn2.h>
     40 #endif
     41 
     42 #ifdef USE_WINDOWS_SSPI
     43 #include "curl_sspi.h"
     44 #endif
     45 
     46 #include "strerror.h"
     47 /* The last 3 #include files should be in this order */
     48 #include "curl_printf.h"
     49 #include "curl_memory.h"
     50 #include "memdebug.h"
     51 
     52 #if defined(WIN32) || defined(_WIN32_WCE)
     53 #define PRESERVE_WINDOWS_ERROR_CODE
     54 #endif
     55 
     56 const char *
     57 curl_easy_strerror(CURLcode error)
     58 {
     59 #ifndef CURL_DISABLE_VERBOSE_STRINGS
     60   switch(error) {
     61   case CURLE_OK:
     62     return "No error";
     63 
     64   case CURLE_UNSUPPORTED_PROTOCOL:
     65     return "Unsupported protocol";
     66 
     67   case CURLE_FAILED_INIT:
     68     return "Failed initialization";
     69 
     70   case CURLE_URL_MALFORMAT:
     71     return "URL using bad/illegal format or missing URL";
     72 
     73   case CURLE_NOT_BUILT_IN:
     74     return "A requested feature, protocol or option was not found built-in in"
     75       " this libcurl due to a build-time decision.";
     76 
     77   case CURLE_COULDNT_RESOLVE_PROXY:
     78     return "Couldn't resolve proxy name";
     79 
     80   case CURLE_COULDNT_RESOLVE_HOST:
     81     return "Couldn't resolve host name";
     82 
     83   case CURLE_COULDNT_CONNECT:
     84     return "Couldn't connect to server";
     85 
     86   case CURLE_WEIRD_SERVER_REPLY:
     87     return "Weird server reply";
     88 
     89   case CURLE_REMOTE_ACCESS_DENIED:
     90     return "Access denied to remote resource";
     91 
     92   case CURLE_FTP_ACCEPT_FAILED:
     93     return "FTP: The server failed to connect to data port";
     94 
     95   case CURLE_FTP_ACCEPT_TIMEOUT:
     96     return "FTP: Accepting server connect has timed out";
     97 
     98   case CURLE_FTP_PRET_FAILED:
     99     return "FTP: The server did not accept the PRET command.";
    100 
    101   case CURLE_FTP_WEIRD_PASS_REPLY:
    102     return "FTP: unknown PASS reply";
    103 
    104   case CURLE_FTP_WEIRD_PASV_REPLY:
    105     return "FTP: unknown PASV reply";
    106 
    107   case CURLE_FTP_WEIRD_227_FORMAT:
    108     return "FTP: unknown 227 response format";
    109 
    110   case CURLE_FTP_CANT_GET_HOST:
    111     return "FTP: can't figure out the host in the PASV response";
    112 
    113   case CURLE_HTTP2:
    114     return "Error in the HTTP2 framing layer";
    115 
    116   case CURLE_FTP_COULDNT_SET_TYPE:
    117     return "FTP: couldn't set file type";
    118 
    119   case CURLE_PARTIAL_FILE:
    120     return "Transferred a partial file";
    121 
    122   case CURLE_FTP_COULDNT_RETR_FILE:
    123     return "FTP: couldn't retrieve (RETR failed) the specified file";
    124 
    125   case CURLE_QUOTE_ERROR:
    126     return "Quote command returned error";
    127 
    128   case CURLE_HTTP_RETURNED_ERROR:
    129     return "HTTP response code said error";
    130 
    131   case CURLE_WRITE_ERROR:
    132     return "Failed writing received data to disk/application";
    133 
    134   case CURLE_UPLOAD_FAILED:
    135     return "Upload failed (at start/before it took off)";
    136 
    137   case CURLE_READ_ERROR:
    138     return "Failed to open/read local data from file/application";
    139 
    140   case CURLE_OUT_OF_MEMORY:
    141     return "Out of memory";
    142 
    143   case CURLE_OPERATION_TIMEDOUT:
    144     return "Timeout was reached";
    145 
    146   case CURLE_FTP_PORT_FAILED:
    147     return "FTP: command PORT failed";
    148 
    149   case CURLE_FTP_COULDNT_USE_REST:
    150     return "FTP: command REST failed";
    151 
    152   case CURLE_RANGE_ERROR:
    153     return "Requested range was not delivered by the server";
    154 
    155   case CURLE_HTTP_POST_ERROR:
    156     return "Internal problem setting up the POST";
    157 
    158   case CURLE_SSL_CONNECT_ERROR:
    159     return "SSL connect error";
    160 
    161   case CURLE_BAD_DOWNLOAD_RESUME:
    162     return "Couldn't resume download";
    163 
    164   case CURLE_FILE_COULDNT_READ_FILE:
    165     return "Couldn't read a file:// file";
    166 
    167   case CURLE_LDAP_CANNOT_BIND:
    168     return "LDAP: cannot bind";
    169 
    170   case CURLE_LDAP_SEARCH_FAILED:
    171     return "LDAP: search failed";
    172 
    173   case CURLE_FUNCTION_NOT_FOUND:
    174     return "A required function in the library was not found";
    175 
    176   case CURLE_ABORTED_BY_CALLBACK:
    177     return "Operation was aborted by an application callback";
    178 
    179   case CURLE_BAD_FUNCTION_ARGUMENT:
    180     return "A libcurl function was given a bad argument";
    181 
    182   case CURLE_INTERFACE_FAILED:
    183     return "Failed binding local connection end";
    184 
    185   case CURLE_TOO_MANY_REDIRECTS :
    186     return "Number of redirects hit maximum amount";
    187 
    188   case CURLE_UNKNOWN_OPTION:
    189     return "An unknown option was passed in to libcurl";
    190 
    191   case CURLE_TELNET_OPTION_SYNTAX :
    192     return "Malformed telnet option";
    193 
    194   case CURLE_GOT_NOTHING:
    195     return "Server returned nothing (no headers, no data)";
    196 
    197   case CURLE_SSL_ENGINE_NOTFOUND:
    198     return "SSL crypto engine not found";
    199 
    200   case CURLE_SSL_ENGINE_SETFAILED:
    201     return "Can not set SSL crypto engine as default";
    202 
    203   case CURLE_SSL_ENGINE_INITFAILED:
    204     return "Failed to initialise SSL crypto engine";
    205 
    206   case CURLE_SEND_ERROR:
    207     return "Failed sending data to the peer";
    208 
    209   case CURLE_RECV_ERROR:
    210     return "Failure when receiving data from the peer";
    211 
    212   case CURLE_SSL_CERTPROBLEM:
    213     return "Problem with the local SSL certificate";
    214 
    215   case CURLE_SSL_CIPHER:
    216     return "Couldn't use specified SSL cipher";
    217 
    218   case CURLE_PEER_FAILED_VERIFICATION:
    219     return "SSL peer certificate or SSH remote key was not OK";
    220 
    221   case CURLE_SSL_CACERT_BADFILE:
    222     return "Problem with the SSL CA cert (path? access rights?)";
    223 
    224   case CURLE_BAD_CONTENT_ENCODING:
    225     return "Unrecognized or bad HTTP Content or Transfer-Encoding";
    226 
    227   case CURLE_LDAP_INVALID_URL:
    228     return "Invalid LDAP URL";
    229 
    230   case CURLE_FILESIZE_EXCEEDED:
    231     return "Maximum file size exceeded";
    232 
    233   case CURLE_USE_SSL_FAILED:
    234     return "Requested SSL level failed";
    235 
    236   case CURLE_SSL_SHUTDOWN_FAILED:
    237     return "Failed to shut down the SSL connection";
    238 
    239   case CURLE_SSL_CRL_BADFILE:
    240     return "Failed to load CRL file (path? access rights?, format?)";
    241 
    242   case CURLE_SSL_ISSUER_ERROR:
    243     return "Issuer check against peer certificate failed";
    244 
    245   case CURLE_SEND_FAIL_REWIND:
    246     return "Send failed since rewinding of the data stream failed";
    247 
    248   case CURLE_LOGIN_DENIED:
    249     return "Login denied";
    250 
    251   case CURLE_TFTP_NOTFOUND:
    252     return "TFTP: File Not Found";
    253 
    254   case CURLE_TFTP_PERM:
    255     return "TFTP: Access Violation";
    256 
    257   case CURLE_REMOTE_DISK_FULL:
    258     return "Disk full or allocation exceeded";
    259 
    260   case CURLE_TFTP_ILLEGAL:
    261     return "TFTP: Illegal operation";
    262 
    263   case CURLE_TFTP_UNKNOWNID:
    264     return "TFTP: Unknown transfer ID";
    265 
    266   case CURLE_REMOTE_FILE_EXISTS:
    267     return "Remote file already exists";
    268 
    269   case CURLE_TFTP_NOSUCHUSER:
    270     return "TFTP: No such user";
    271 
    272   case CURLE_CONV_FAILED:
    273     return "Conversion failed";
    274 
    275   case CURLE_CONV_REQD:
    276     return "Caller must register CURLOPT_CONV_ callback options";
    277 
    278   case CURLE_REMOTE_FILE_NOT_FOUND:
    279     return "Remote file not found";
    280 
    281   case CURLE_SSH:
    282     return "Error in the SSH layer";
    283 
    284   case CURLE_AGAIN:
    285     return "Socket not ready for send/recv";
    286 
    287   case CURLE_RTSP_CSEQ_ERROR:
    288     return "RTSP CSeq mismatch or invalid CSeq";
    289 
    290   case CURLE_RTSP_SESSION_ERROR:
    291     return "RTSP session error";
    292 
    293   case CURLE_FTP_BAD_FILE_LIST:
    294     return "Unable to parse FTP file list";
    295 
    296   case CURLE_CHUNK_FAILED:
    297     return "Chunk callback failed";
    298 
    299   case CURLE_NO_CONNECTION_AVAILABLE:
    300     return "The max connection limit is reached";
    301 
    302   case CURLE_SSL_PINNEDPUBKEYNOTMATCH:
    303     return "SSL public key does not match pinned public key";
    304 
    305   case CURLE_SSL_INVALIDCERTSTATUS:
    306     return "SSL server certificate status verification FAILED";
    307 
    308   case CURLE_HTTP2_STREAM:
    309     return "Stream error in the HTTP/2 framing layer";
    310 
    311   case CURLE_RECURSIVE_API_CALL:
    312     return "API function called from within callback";
    313 
    314     /* error codes not used by current libcurl */
    315   case CURLE_OBSOLETE20:
    316   case CURLE_OBSOLETE24:
    317   case CURLE_OBSOLETE29:
    318   case CURLE_OBSOLETE32:
    319   case CURLE_OBSOLETE40:
    320   case CURLE_OBSOLETE44:
    321   case CURLE_OBSOLETE46:
    322   case CURLE_OBSOLETE50:
    323   case CURLE_OBSOLETE51:
    324   case CURLE_OBSOLETE57:
    325   case CURL_LAST:
    326     break;
    327   }
    328   /*
    329    * By using a switch, gcc -Wall will complain about enum values
    330    * which do not appear, helping keep this function up-to-date.
    331    * By using gcc -Wall -Werror, you can't forget.
    332    *
    333    * A table would not have the same benefit.  Most compilers will
    334    * generate code very similar to a table in any case, so there
    335    * is little performance gain from a table.  And something is broken
    336    * for the user's application, anyways, so does it matter how fast
    337    * it _doesn't_ work?
    338    *
    339    * The line number for the error will be near this comment, which
    340    * is why it is here, and not at the start of the switch.
    341    */
    342   return "Unknown error";
    343 #else
    344   if(!error)
    345     return "No error";
    346   else
    347     return "Error";
    348 #endif
    349 }
    350 
    351 const char *
    352 curl_multi_strerror(CURLMcode error)
    353 {
    354 #ifndef CURL_DISABLE_VERBOSE_STRINGS
    355   switch(error) {
    356   case CURLM_CALL_MULTI_PERFORM:
    357     return "Please call curl_multi_perform() soon";
    358 
    359   case CURLM_OK:
    360     return "No error";
    361 
    362   case CURLM_BAD_HANDLE:
    363     return "Invalid multi handle";
    364 
    365   case CURLM_BAD_EASY_HANDLE:
    366     return "Invalid easy handle";
    367 
    368   case CURLM_OUT_OF_MEMORY:
    369     return "Out of memory";
    370 
    371   case CURLM_INTERNAL_ERROR:
    372     return "Internal error";
    373 
    374   case CURLM_BAD_SOCKET:
    375     return "Invalid socket argument";
    376 
    377   case CURLM_UNKNOWN_OPTION:
    378     return "Unknown option";
    379 
    380   case CURLM_ADDED_ALREADY:
    381     return "The easy handle is already added to a multi handle";
    382 
    383   case CURLM_RECURSIVE_API_CALL:
    384     return "API function called from within callback";
    385 
    386   case CURLM_LAST:
    387     break;
    388   }
    389 
    390   return "Unknown error";
    391 #else
    392   if(error == CURLM_OK)
    393     return "No error";
    394   else
    395     return "Error";
    396 #endif
    397 }
    398 
    399 const char *
    400 curl_share_strerror(CURLSHcode error)
    401 {
    402 #ifndef CURL_DISABLE_VERBOSE_STRINGS
    403   switch(error) {
    404   case CURLSHE_OK:
    405     return "No error";
    406 
    407   case CURLSHE_BAD_OPTION:
    408     return "Unknown share option";
    409 
    410   case CURLSHE_IN_USE:
    411     return "Share currently in use";
    412 
    413   case CURLSHE_INVALID:
    414     return "Invalid share handle";
    415 
    416   case CURLSHE_NOMEM:
    417     return "Out of memory";
    418 
    419   case CURLSHE_NOT_BUILT_IN:
    420     return "Feature not enabled in this library";
    421 
    422   case CURLSHE_LAST:
    423     break;
    424   }
    425 
    426   return "CURLSHcode unknown";
    427 #else
    428   if(error == CURLSHE_OK)
    429     return "No error";
    430   else
    431     return "Error";
    432 #endif
    433 }
    434 
    435 #ifdef USE_WINSOCK
    436 
    437 /* This function handles most / all (?) Winsock errors curl is able to produce.
    438  */
    439 static const char *
    440 get_winsock_error (int err, char *buf, size_t len)
    441 {
    442 #ifdef PRESERVE_WINDOWS_ERROR_CODE
    443   DWORD old_win_err = GetLastError();
    444 #endif
    445   int old_errno = errno;
    446   const char *p;
    447 
    448 #ifndef CURL_DISABLE_VERBOSE_STRINGS
    449   switch(err) {
    450   case WSAEINTR:
    451     p = "Call interrupted";
    452     break;
    453   case WSAEBADF:
    454     p = "Bad file";
    455     break;
    456   case WSAEACCES:
    457     p = "Bad access";
    458     break;
    459   case WSAEFAULT:
    460     p = "Bad argument";
    461     break;
    462   case WSAEINVAL:
    463     p = "Invalid arguments";
    464     break;
    465   case WSAEMFILE:
    466     p = "Out of file descriptors";
    467     break;
    468   case WSAEWOULDBLOCK:
    469     p = "Call would block";
    470     break;
    471   case WSAEINPROGRESS:
    472   case WSAEALREADY:
    473     p = "Blocking call in progress";
    474     break;
    475   case WSAENOTSOCK:
    476     p = "Descriptor is not a socket";
    477     break;
    478   case WSAEDESTADDRREQ:
    479     p = "Need destination address";
    480     break;
    481   case WSAEMSGSIZE:
    482     p = "Bad message size";
    483     break;
    484   case WSAEPROTOTYPE:
    485     p = "Bad protocol";
    486     break;
    487   case WSAENOPROTOOPT:
    488     p = "Protocol option is unsupported";
    489     break;
    490   case WSAEPROTONOSUPPORT:
    491     p = "Protocol is unsupported";
    492     break;
    493   case WSAESOCKTNOSUPPORT:
    494     p = "Socket is unsupported";
    495     break;
    496   case WSAEOPNOTSUPP:
    497     p = "Operation not supported";
    498     break;
    499   case WSAEAFNOSUPPORT:
    500     p = "Address family not supported";
    501     break;
    502   case WSAEPFNOSUPPORT:
    503     p = "Protocol family not supported";
    504     break;
    505   case WSAEADDRINUSE:
    506     p = "Address already in use";
    507     break;
    508   case WSAEADDRNOTAVAIL:
    509     p = "Address not available";
    510     break;
    511   case WSAENETDOWN:
    512     p = "Network down";
    513     break;
    514   case WSAENETUNREACH:
    515     p = "Network unreachable";
    516     break;
    517   case WSAENETRESET:
    518     p = "Network has been reset";
    519     break;
    520   case WSAECONNABORTED:
    521     p = "Connection was aborted";
    522     break;
    523   case WSAECONNRESET:
    524     p = "Connection was reset";
    525     break;
    526   case WSAENOBUFS:
    527     p = "No buffer space";
    528     break;
    529   case WSAEISCONN:
    530     p = "Socket is already connected";
    531     break;
    532   case WSAENOTCONN:
    533     p = "Socket is not connected";
    534     break;
    535   case WSAESHUTDOWN:
    536     p = "Socket has been shut down";
    537     break;
    538   case WSAETOOMANYREFS:
    539     p = "Too many references";
    540     break;
    541   case WSAETIMEDOUT:
    542     p = "Timed out";
    543     break;
    544   case WSAECONNREFUSED:
    545     p = "Connection refused";
    546     break;
    547   case WSAELOOP:
    548     p = "Loop??";
    549     break;
    550   case WSAENAMETOOLONG:
    551     p = "Name too long";
    552     break;
    553   case WSAEHOSTDOWN:
    554     p = "Host down";
    555     break;
    556   case WSAEHOSTUNREACH:
    557     p = "Host unreachable";
    558     break;
    559   case WSAENOTEMPTY:
    560     p = "Not empty";
    561     break;
    562   case WSAEPROCLIM:
    563     p = "Process limit reached";
    564     break;
    565   case WSAEUSERS:
    566     p = "Too many users";
    567     break;
    568   case WSAEDQUOT:
    569     p = "Bad quota";
    570     break;
    571   case WSAESTALE:
    572     p = "Something is stale";
    573     break;
    574   case WSAEREMOTE:
    575     p = "Remote error";
    576     break;
    577 #ifdef WSAEDISCON  /* missing in SalfordC! */
    578   case WSAEDISCON:
    579     p = "Disconnected";
    580     break;
    581 #endif
    582     /* Extended Winsock errors */
    583   case WSASYSNOTREADY:
    584     p = "Winsock library is not ready";
    585     break;
    586   case WSANOTINITIALISED:
    587     p = "Winsock library not initialised";
    588     break;
    589   case WSAVERNOTSUPPORTED:
    590     p = "Winsock version not supported";
    591     break;
    592 
    593     /* getXbyY() errors (already handled in herrmsg):
    594      * Authoritative Answer: Host not found */
    595   case WSAHOST_NOT_FOUND:
    596     p = "Host not found";
    597     break;
    598 
    599     /* Non-Authoritative: Host not found, or SERVERFAIL */
    600   case WSATRY_AGAIN:
    601     p = "Host not found, try again";
    602     break;
    603 
    604     /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
    605   case WSANO_RECOVERY:
    606     p = "Unrecoverable error in call to nameserver";
    607     break;
    608 
    609     /* Valid name, no data record of requested type */
    610   case WSANO_DATA:
    611     p = "No data record of requested type";
    612     break;
    613 
    614   default:
    615     return NULL;
    616   }
    617 #else
    618   if(!err)
    619     return NULL;
    620   else
    621     p = "error";
    622 #endif
    623   strncpy(buf, p, len);
    624   buf [len-1] = '\0';
    625 
    626   if(errno != old_errno)
    627     errno = old_errno;
    628 
    629 #ifdef PRESERVE_WINDOWS_ERROR_CODE
    630   if(old_win_err != GetLastError())
    631     SetLastError(old_win_err);
    632 #endif
    633 
    634   return buf;
    635 }
    636 #endif   /* USE_WINSOCK */
    637 
    638 /*
    639  * Our thread-safe and smart strerror() replacement.
    640  *
    641  * The 'err' argument passed in to this function MUST be a true errno number
    642  * as reported on this system. We do no range checking on the number before
    643  * we pass it to the "number-to-message" conversion function and there might
    644  * be systems that don't do proper range checking in there themselves.
    645  *
    646  * We don't do range checking (on systems other than Windows) since there is
    647  * no good reliable and portable way to do it.
    648  */
    649 const char *Curl_strerror(int err, char *buf, size_t buflen)
    650 {
    651 #ifdef PRESERVE_WINDOWS_ERROR_CODE
    652   DWORD old_win_err = GetLastError();
    653 #endif
    654   int old_errno = errno;
    655   char *p;
    656   size_t max;
    657 
    658   DEBUGASSERT(err >= 0);
    659 
    660   max = buflen - 1;
    661   *buf = '\0';
    662 
    663 #ifdef USE_WINSOCK
    664 
    665 #ifdef _WIN32_WCE
    666   {
    667     wchar_t wbuf[256];
    668     wbuf[0] = L'\0';
    669 
    670     FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err,
    671                   LANG_NEUTRAL, wbuf, sizeof(wbuf)/sizeof(wchar_t), NULL);
    672     wcstombs(buf, wbuf, max);
    673   }
    674 #else
    675   /* 'sys_nerr' is the maximum errno number, it is not widely portable */
    676   if(err >= 0 && err < sys_nerr)
    677     strncpy(buf, strerror(err), max);
    678   else {
    679     if(!get_winsock_error(err, buf, max) &&
    680        !FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err,
    681                        LANG_NEUTRAL, buf, (DWORD)max, NULL))
    682       msnprintf(buf, max, "Unknown error %d (%#x)", err, err);
    683   }
    684 #endif
    685 
    686 #else /* not USE_WINSOCK coming up */
    687 
    688 #if defined(HAVE_STRERROR_R) && defined(HAVE_POSIX_STRERROR_R)
    689  /*
    690   * The POSIX-style strerror_r() may set errno to ERANGE if insufficient
    691   * storage is supplied via 'strerrbuf' and 'buflen' to hold the generated
    692   * message string, or EINVAL if 'errnum' is not a valid error number.
    693   */
    694   if(0 != strerror_r(err, buf, max)) {
    695     if('\0' == buf[0])
    696       msnprintf(buf, max, "Unknown error %d", err);
    697   }
    698 #elif defined(HAVE_STRERROR_R) && defined(HAVE_GLIBC_STRERROR_R)
    699  /*
    700   * The glibc-style strerror_r() only *might* use the buffer we pass to
    701   * the function, but it always returns the error message as a pointer,
    702   * so we must copy that string unconditionally (if non-NULL).
    703   */
    704   {
    705     char buffer[256];
    706     char *msg = strerror_r(err, buffer, sizeof(buffer));
    707     if(msg)
    708       strncpy(buf, msg, max);
    709     else
    710       msnprintf(buf, max, "Unknown error %d", err);
    711   }
    712 #elif defined(HAVE_STRERROR_R) && defined(HAVE_VXWORKS_STRERROR_R)
    713  /*
    714   * The vxworks-style strerror_r() does use the buffer we pass to the function.
    715   * The buffer size should be at least NAME_MAX (256)
    716   */
    717   {
    718     char buffer[256];
    719     if(OK == strerror_r(err, buffer))
    720       strncpy(buf, buffer, max);
    721     else
    722       msnprintf(buf, max, "Unknown error %d", err);
    723   }
    724 #else
    725   {
    726     char *msg = strerror(err);
    727     if(msg)
    728       strncpy(buf, msg, max);
    729     else
    730       msnprintf(buf, max, "Unknown error %d", err);
    731   }
    732 #endif
    733 
    734 #endif /* end of ! USE_WINSOCK */
    735 
    736   buf[max] = '\0'; /* make sure the string is zero terminated */
    737 
    738   /* strip trailing '\r\n' or '\n'. */
    739   p = strrchr(buf, '\n');
    740   if(p && (p - buf) >= 2)
    741     *p = '\0';
    742   p = strrchr(buf, '\r');
    743   if(p && (p - buf) >= 1)
    744     *p = '\0';
    745 
    746   if(errno != old_errno)
    747     errno = old_errno;
    748 
    749 #ifdef PRESERVE_WINDOWS_ERROR_CODE
    750   if(old_win_err != GetLastError())
    751     SetLastError(old_win_err);
    752 #endif
    753 
    754   return buf;
    755 }
    756 
    757 #ifdef USE_WINDOWS_SSPI
    758 const char *Curl_sspi_strerror(int err, char *buf, size_t buflen)
    759 {
    760 #ifdef PRESERVE_WINDOWS_ERROR_CODE
    761   DWORD old_win_err = GetLastError();
    762 #endif
    763   int old_errno = errno;
    764   const char *txt;
    765   char *outbuf;
    766   size_t outmax;
    767 #ifndef CURL_DISABLE_VERBOSE_STRINGS
    768   char txtbuf[80];
    769   char msgbuf[256];
    770   char *p, *str, *msg = NULL;
    771   bool msg_formatted = FALSE;
    772 #endif
    773 
    774   outbuf = buf;
    775   outmax = buflen - 1;
    776   *outbuf = '\0';
    777 
    778 #ifndef CURL_DISABLE_VERBOSE_STRINGS
    779 
    780   switch(err) {
    781     case SEC_E_OK:
    782       txt = "No error";
    783       break;
    784     case CRYPT_E_REVOKED:
    785       txt = "CRYPT_E_REVOKED";
    786       break;
    787     case SEC_E_ALGORITHM_MISMATCH:
    788       txt = "SEC_E_ALGORITHM_MISMATCH";
    789       break;
    790     case SEC_E_BAD_BINDINGS:
    791       txt = "SEC_E_BAD_BINDINGS";
    792       break;
    793     case SEC_E_BAD_PKGID:
    794       txt = "SEC_E_BAD_PKGID";
    795       break;
    796     case SEC_E_BUFFER_TOO_SMALL:
    797       txt = "SEC_E_BUFFER_TOO_SMALL";
    798       break;
    799     case SEC_E_CANNOT_INSTALL:
    800       txt = "SEC_E_CANNOT_INSTALL";
    801       break;
    802     case SEC_E_CANNOT_PACK:
    803       txt = "SEC_E_CANNOT_PACK";
    804       break;
    805     case SEC_E_CERT_EXPIRED:
    806       txt = "SEC_E_CERT_EXPIRED";
    807       break;
    808     case SEC_E_CERT_UNKNOWN:
    809       txt = "SEC_E_CERT_UNKNOWN";
    810       break;
    811     case SEC_E_CERT_WRONG_USAGE:
    812       txt = "SEC_E_CERT_WRONG_USAGE";
    813       break;
    814     case SEC_E_CONTEXT_EXPIRED:
    815       txt = "SEC_E_CONTEXT_EXPIRED";
    816       break;
    817     case SEC_E_CROSSREALM_DELEGATION_FAILURE:
    818       txt = "SEC_E_CROSSREALM_DELEGATION_FAILURE";
    819       break;
    820     case SEC_E_CRYPTO_SYSTEM_INVALID:
    821       txt = "SEC_E_CRYPTO_SYSTEM_INVALID";
    822       break;
    823     case SEC_E_DECRYPT_FAILURE:
    824       txt = "SEC_E_DECRYPT_FAILURE";
    825       break;
    826     case SEC_E_DELEGATION_POLICY:
    827       txt = "SEC_E_DELEGATION_POLICY";
    828       break;
    829     case SEC_E_DELEGATION_REQUIRED:
    830       txt = "SEC_E_DELEGATION_REQUIRED";
    831       break;
    832     case SEC_E_DOWNGRADE_DETECTED:
    833       txt = "SEC_E_DOWNGRADE_DETECTED";
    834       break;
    835     case SEC_E_ENCRYPT_FAILURE:
    836       txt = "SEC_E_ENCRYPT_FAILURE";
    837       break;
    838     case SEC_E_ILLEGAL_MESSAGE:
    839       txt = "SEC_E_ILLEGAL_MESSAGE";
    840       break;
    841     case SEC_E_INCOMPLETE_CREDENTIALS:
    842       txt = "SEC_E_INCOMPLETE_CREDENTIALS";
    843       break;
    844     case SEC_E_INCOMPLETE_MESSAGE:
    845       txt = "SEC_E_INCOMPLETE_MESSAGE";
    846       break;
    847     case SEC_E_INSUFFICIENT_MEMORY:
    848       txt = "SEC_E_INSUFFICIENT_MEMORY";
    849       break;
    850     case SEC_E_INTERNAL_ERROR:
    851       txt = "SEC_E_INTERNAL_ERROR";
    852       break;
    853     case SEC_E_INVALID_HANDLE:
    854       txt = "SEC_E_INVALID_HANDLE";
    855       break;
    856     case SEC_E_INVALID_PARAMETER:
    857       txt = "SEC_E_INVALID_PARAMETER";
    858       break;
    859     case SEC_E_INVALID_TOKEN:
    860       txt = "SEC_E_INVALID_TOKEN";
    861       break;
    862     case SEC_E_ISSUING_CA_UNTRUSTED:
    863       txt = "SEC_E_ISSUING_CA_UNTRUSTED";
    864       break;
    865     case SEC_E_ISSUING_CA_UNTRUSTED_KDC:
    866       txt = "SEC_E_ISSUING_CA_UNTRUSTED_KDC";
    867       break;
    868     case SEC_E_KDC_CERT_EXPIRED:
    869       txt = "SEC_E_KDC_CERT_EXPIRED";
    870       break;
    871     case SEC_E_KDC_CERT_REVOKED:
    872       txt = "SEC_E_KDC_CERT_REVOKED";
    873       break;
    874     case SEC_E_KDC_INVALID_REQUEST:
    875       txt = "SEC_E_KDC_INVALID_REQUEST";
    876       break;
    877     case SEC_E_KDC_UNABLE_TO_REFER:
    878       txt = "SEC_E_KDC_UNABLE_TO_REFER";
    879       break;
    880     case SEC_E_KDC_UNKNOWN_ETYPE:
    881       txt = "SEC_E_KDC_UNKNOWN_ETYPE";
    882       break;
    883     case SEC_E_LOGON_DENIED:
    884       txt = "SEC_E_LOGON_DENIED";
    885       break;
    886     case SEC_E_MAX_REFERRALS_EXCEEDED:
    887       txt = "SEC_E_MAX_REFERRALS_EXCEEDED";
    888       break;
    889     case SEC_E_MESSAGE_ALTERED:
    890       txt = "SEC_E_MESSAGE_ALTERED";
    891       break;
    892     case SEC_E_MULTIPLE_ACCOUNTS:
    893       txt = "SEC_E_MULTIPLE_ACCOUNTS";
    894       break;
    895     case SEC_E_MUST_BE_KDC:
    896       txt = "SEC_E_MUST_BE_KDC";
    897       break;
    898     case SEC_E_NOT_OWNER:
    899       txt = "SEC_E_NOT_OWNER";
    900       break;
    901     case SEC_E_NO_AUTHENTICATING_AUTHORITY:
    902       txt = "SEC_E_NO_AUTHENTICATING_AUTHORITY";
    903       break;
    904     case SEC_E_NO_CREDENTIALS:
    905       txt = "SEC_E_NO_CREDENTIALS";
    906       break;
    907     case SEC_E_NO_IMPERSONATION:
    908       txt = "SEC_E_NO_IMPERSONATION";
    909       break;
    910     case SEC_E_NO_IP_ADDRESSES:
    911       txt = "SEC_E_NO_IP_ADDRESSES";
    912       break;
    913     case SEC_E_NO_KERB_KEY:
    914       txt = "SEC_E_NO_KERB_KEY";
    915       break;
    916     case SEC_E_NO_PA_DATA:
    917       txt = "SEC_E_NO_PA_DATA";
    918       break;
    919     case SEC_E_NO_S4U_PROT_SUPPORT:
    920       txt = "SEC_E_NO_S4U_PROT_SUPPORT";
    921       break;
    922     case SEC_E_NO_TGT_REPLY:
    923       txt = "SEC_E_NO_TGT_REPLY";
    924       break;
    925     case SEC_E_OUT_OF_SEQUENCE:
    926       txt = "SEC_E_OUT_OF_SEQUENCE";
    927       break;
    928     case SEC_E_PKINIT_CLIENT_FAILURE:
    929       txt = "SEC_E_PKINIT_CLIENT_FAILURE";
    930       break;
    931     case SEC_E_PKINIT_NAME_MISMATCH:
    932       txt = "SEC_E_PKINIT_NAME_MISMATCH";
    933       break;
    934     case SEC_E_POLICY_NLTM_ONLY:
    935       txt = "SEC_E_POLICY_NLTM_ONLY";
    936       break;
    937     case SEC_E_QOP_NOT_SUPPORTED:
    938       txt = "SEC_E_QOP_NOT_SUPPORTED";
    939       break;
    940     case SEC_E_REVOCATION_OFFLINE_C:
    941       txt = "SEC_E_REVOCATION_OFFLINE_C";
    942       break;
    943     case SEC_E_REVOCATION_OFFLINE_KDC:
    944       txt = "SEC_E_REVOCATION_OFFLINE_KDC";
    945       break;
    946     case SEC_E_SECPKG_NOT_FOUND:
    947       txt = "SEC_E_SECPKG_NOT_FOUND";
    948       break;
    949     case SEC_E_SECURITY_QOS_FAILED:
    950       txt = "SEC_E_SECURITY_QOS_FAILED";
    951       break;
    952     case SEC_E_SHUTDOWN_IN_PROGRESS:
    953       txt = "SEC_E_SHUTDOWN_IN_PROGRESS";
    954       break;
    955     case SEC_E_SMARTCARD_CERT_EXPIRED:
    956       txt = "SEC_E_SMARTCARD_CERT_EXPIRED";
    957       break;
    958     case SEC_E_SMARTCARD_CERT_REVOKED:
    959       txt = "SEC_E_SMARTCARD_CERT_REVOKED";
    960       break;
    961     case SEC_E_SMARTCARD_LOGON_REQUIRED:
    962       txt = "SEC_E_SMARTCARD_LOGON_REQUIRED";
    963       break;
    964     case SEC_E_STRONG_CRYPTO_NOT_SUPPORTED:
    965       txt = "SEC_E_STRONG_CRYPTO_NOT_SUPPORTED";
    966       break;
    967     case SEC_E_TARGET_UNKNOWN:
    968       txt = "SEC_E_TARGET_UNKNOWN";
    969       break;
    970     case SEC_E_TIME_SKEW:
    971       txt = "SEC_E_TIME_SKEW";
    972       break;
    973     case SEC_E_TOO_MANY_PRINCIPALS:
    974       txt = "SEC_E_TOO_MANY_PRINCIPALS";
    975       break;
    976     case SEC_E_UNFINISHED_CONTEXT_DELETED:
    977       txt = "SEC_E_UNFINISHED_CONTEXT_DELETED";
    978       break;
    979     case SEC_E_UNKNOWN_CREDENTIALS:
    980       txt = "SEC_E_UNKNOWN_CREDENTIALS";
    981       break;
    982     case SEC_E_UNSUPPORTED_FUNCTION:
    983       txt = "SEC_E_UNSUPPORTED_FUNCTION";
    984       break;
    985     case SEC_E_UNSUPPORTED_PREAUTH:
    986       txt = "SEC_E_UNSUPPORTED_PREAUTH";
    987       break;
    988     case SEC_E_UNTRUSTED_ROOT:
    989       txt = "SEC_E_UNTRUSTED_ROOT";
    990       break;
    991     case SEC_E_WRONG_CREDENTIAL_HANDLE:
    992       txt = "SEC_E_WRONG_CREDENTIAL_HANDLE";
    993       break;
    994     case SEC_E_WRONG_PRINCIPAL:
    995       txt = "SEC_E_WRONG_PRINCIPAL";
    996       break;
    997     case SEC_I_COMPLETE_AND_CONTINUE:
    998       txt = "SEC_I_COMPLETE_AND_CONTINUE";
    999       break;
   1000     case SEC_I_COMPLETE_NEEDED:
   1001       txt = "SEC_I_COMPLETE_NEEDED";
   1002       break;
   1003     case SEC_I_CONTEXT_EXPIRED:
   1004       txt = "SEC_I_CONTEXT_EXPIRED";
   1005       break;
   1006     case SEC_I_CONTINUE_NEEDED:
   1007       txt = "SEC_I_CONTINUE_NEEDED";
   1008       break;
   1009     case SEC_I_INCOMPLETE_CREDENTIALS:
   1010       txt = "SEC_I_INCOMPLETE_CREDENTIALS";
   1011       break;
   1012     case SEC_I_LOCAL_LOGON:
   1013       txt = "SEC_I_LOCAL_LOGON";
   1014       break;
   1015     case SEC_I_NO_LSA_CONTEXT:
   1016       txt = "SEC_I_NO_LSA_CONTEXT";
   1017       break;
   1018     case SEC_I_RENEGOTIATE:
   1019       txt = "SEC_I_RENEGOTIATE";
   1020       break;
   1021     case SEC_I_SIGNATURE_NEEDED:
   1022       txt = "SEC_I_SIGNATURE_NEEDED";
   1023       break;
   1024     default:
   1025       txt = "Unknown error";
   1026   }
   1027 
   1028   if(err == SEC_E_OK)
   1029     strncpy(outbuf, txt, outmax);
   1030   else if(err == SEC_E_ILLEGAL_MESSAGE)
   1031     msnprintf(outbuf, outmax,
   1032               "SEC_E_ILLEGAL_MESSAGE (0x%08X) - This error usually occurs "
   1033               "when a fatal SSL/TLS alert is received (e.g. handshake failed)."
   1034               " More detail may be available in the Windows System event log.",
   1035               err);
   1036   else {
   1037     str = txtbuf;
   1038     msnprintf(txtbuf, sizeof(txtbuf), "%s (0x%08X)", txt, err);
   1039     txtbuf[sizeof(txtbuf)-1] = '\0';
   1040 
   1041 #ifdef _WIN32_WCE
   1042     {
   1043       wchar_t wbuf[256];
   1044       wbuf[0] = L'\0';
   1045 
   1046       if(FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
   1047                        FORMAT_MESSAGE_IGNORE_INSERTS,
   1048                        NULL, err, LANG_NEUTRAL,
   1049                        wbuf, sizeof(wbuf)/sizeof(wchar_t), NULL)) {
   1050         wcstombs(msgbuf, wbuf, sizeof(msgbuf)-1);
   1051         msg_formatted = TRUE;
   1052       }
   1053     }
   1054 #else
   1055     if(FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM |
   1056                       FORMAT_MESSAGE_IGNORE_INSERTS,
   1057                       NULL, err, LANG_NEUTRAL,
   1058                       msgbuf, sizeof(msgbuf)-1, NULL)) {
   1059       msg_formatted = TRUE;
   1060     }
   1061 #endif
   1062     if(msg_formatted) {
   1063       msgbuf[sizeof(msgbuf)-1] = '\0';
   1064       /* strip trailing '\r\n' or '\n' */
   1065       p = strrchr(msgbuf, '\n');
   1066       if(p && (p - msgbuf) >= 2)
   1067         *p = '\0';
   1068       p = strrchr(msgbuf, '\r');
   1069       if(p && (p - msgbuf) >= 1)
   1070         *p = '\0';
   1071       msg = msgbuf;
   1072     }
   1073     if(msg)
   1074       msnprintf(outbuf, outmax, "%s - %s", str, msg);
   1075     else
   1076       strncpy(outbuf, str, outmax);
   1077   }
   1078 
   1079 #else
   1080 
   1081   if(err == SEC_E_OK)
   1082     txt = "No error";
   1083   else
   1084     txt = "Error";
   1085 
   1086   strncpy(outbuf, txt, outmax);
   1087 
   1088 #endif
   1089 
   1090   outbuf[outmax] = '\0';
   1091 
   1092   if(errno != old_errno)
   1093     errno = old_errno;
   1094 
   1095 #ifdef PRESERVE_WINDOWS_ERROR_CODE
   1096   if(old_win_err != GetLastError())
   1097     SetLastError(old_win_err);
   1098 #endif
   1099 
   1100   return outbuf;
   1101 }
   1102 #endif /* USE_WINDOWS_SSPI */
   1103