Annotation of embedaddon/curl/lib/strerror.c, revision 1.1.1.1

1.1       misho       1: /***************************************************************************
                      2:  *                                  _   _ ____  _
                      3:  *  Project                     ___| | | |  _ \| |
                      4:  *                             / __| | | | |_) | |
                      5:  *                            | (__| |_| |  _ <| |___
                      6:  *                             \___|\___/|_| \_\_____|
                      7:  *
                      8:  * Copyright (C) 2004 - 2020, Daniel Stenberg, <daniel@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:   case CURLE_AUTH_ERROR:
                    315:     return "An authentication function returned an error";
                    316: 
                    317:   case CURLE_HTTP3:
                    318:     return "HTTP/3 error";
                    319: 
                    320:   case CURLE_QUIC_CONNECT_ERROR:
                    321:     return "QUIC connection error";
                    322: 
                    323:     /* error codes not used by current libcurl */
                    324:   case CURLE_OBSOLETE20:
                    325:   case CURLE_OBSOLETE24:
                    326:   case CURLE_OBSOLETE29:
                    327:   case CURLE_OBSOLETE32:
                    328:   case CURLE_OBSOLETE40:
                    329:   case CURLE_OBSOLETE44:
                    330:   case CURLE_OBSOLETE46:
                    331:   case CURLE_OBSOLETE50:
                    332:   case CURLE_OBSOLETE51:
                    333:   case CURLE_OBSOLETE57:
                    334:   case CURL_LAST:
                    335:     break;
                    336:   }
                    337:   /*
                    338:    * By using a switch, gcc -Wall will complain about enum values
                    339:    * which do not appear, helping keep this function up-to-date.
                    340:    * By using gcc -Wall -Werror, you can't forget.
                    341:    *
                    342:    * A table would not have the same benefit.  Most compilers will
                    343:    * generate code very similar to a table in any case, so there
                    344:    * is little performance gain from a table.  And something is broken
                    345:    * for the user's application, anyways, so does it matter how fast
                    346:    * it _doesn't_ work?
                    347:    *
                    348:    * The line number for the error will be near this comment, which
                    349:    * is why it is here, and not at the start of the switch.
                    350:    */
                    351:   return "Unknown error";
                    352: #else
                    353:   if(!error)
                    354:     return "No error";
                    355:   else
                    356:     return "Error";
                    357: #endif
                    358: }
                    359: 
                    360: const char *
                    361: curl_multi_strerror(CURLMcode error)
                    362: {
                    363: #ifndef CURL_DISABLE_VERBOSE_STRINGS
                    364:   switch(error) {
                    365:   case CURLM_CALL_MULTI_PERFORM:
                    366:     return "Please call curl_multi_perform() soon";
                    367: 
                    368:   case CURLM_OK:
                    369:     return "No error";
                    370: 
                    371:   case CURLM_BAD_HANDLE:
                    372:     return "Invalid multi handle";
                    373: 
                    374:   case CURLM_BAD_EASY_HANDLE:
                    375:     return "Invalid easy handle";
                    376: 
                    377:   case CURLM_OUT_OF_MEMORY:
                    378:     return "Out of memory";
                    379: 
                    380:   case CURLM_INTERNAL_ERROR:
                    381:     return "Internal error";
                    382: 
                    383:   case CURLM_BAD_SOCKET:
                    384:     return "Invalid socket argument";
                    385: 
                    386:   case CURLM_UNKNOWN_OPTION:
                    387:     return "Unknown option";
                    388: 
                    389:   case CURLM_ADDED_ALREADY:
                    390:     return "The easy handle is already added to a multi handle";
                    391: 
                    392:   case CURLM_RECURSIVE_API_CALL:
                    393:     return "API function called from within callback";
                    394: 
                    395:   case CURLM_WAKEUP_FAILURE:
                    396:     return "Wakeup is unavailable or failed";
                    397: 
                    398:   case CURLM_BAD_FUNCTION_ARGUMENT:
                    399:     return "A libcurl function was given a bad argument";
                    400: 
                    401:   case CURLM_LAST:
                    402:     break;
                    403:   }
                    404: 
                    405:   return "Unknown error";
                    406: #else
                    407:   if(error == CURLM_OK)
                    408:     return "No error";
                    409:   else
                    410:     return "Error";
                    411: #endif
                    412: }
                    413: 
                    414: const char *
                    415: curl_share_strerror(CURLSHcode error)
                    416: {
                    417: #ifndef CURL_DISABLE_VERBOSE_STRINGS
                    418:   switch(error) {
                    419:   case CURLSHE_OK:
                    420:     return "No error";
                    421: 
                    422:   case CURLSHE_BAD_OPTION:
                    423:     return "Unknown share option";
                    424: 
                    425:   case CURLSHE_IN_USE:
                    426:     return "Share currently in use";
                    427: 
                    428:   case CURLSHE_INVALID:
                    429:     return "Invalid share handle";
                    430: 
                    431:   case CURLSHE_NOMEM:
                    432:     return "Out of memory";
                    433: 
                    434:   case CURLSHE_NOT_BUILT_IN:
                    435:     return "Feature not enabled in this library";
                    436: 
                    437:   case CURLSHE_LAST:
                    438:     break;
                    439:   }
                    440: 
                    441:   return "CURLSHcode unknown";
                    442: #else
                    443:   if(error == CURLSHE_OK)
                    444:     return "No error";
                    445:   else
                    446:     return "Error";
                    447: #endif
                    448: }
                    449: 
                    450: #ifdef USE_WINSOCK
                    451: /* This is a helper function for Curl_strerror that converts Winsock error
                    452:  * codes (WSAGetLastError) to error messages.
                    453:  * Returns NULL if no error message was found for error code.
                    454:  */
                    455: static const char *
                    456: get_winsock_error (int err, char *buf, size_t len)
                    457: {
                    458: #ifndef CURL_DISABLE_VERBOSE_STRINGS
                    459:   const char *p;
                    460: #endif
                    461: 
                    462:   if(!len)
                    463:     return NULL;
                    464: 
                    465:   *buf = '\0';
                    466: 
                    467: #ifdef CURL_DISABLE_VERBOSE_STRINGS
                    468:   (void)err;
                    469:   return NULL;
                    470: #else
                    471:   switch(err) {
                    472:   case WSAEINTR:
                    473:     p = "Call interrupted";
                    474:     break;
                    475:   case WSAEBADF:
                    476:     p = "Bad file";
                    477:     break;
                    478:   case WSAEACCES:
                    479:     p = "Bad access";
                    480:     break;
                    481:   case WSAEFAULT:
                    482:     p = "Bad argument";
                    483:     break;
                    484:   case WSAEINVAL:
                    485:     p = "Invalid arguments";
                    486:     break;
                    487:   case WSAEMFILE:
                    488:     p = "Out of file descriptors";
                    489:     break;
                    490:   case WSAEWOULDBLOCK:
                    491:     p = "Call would block";
                    492:     break;
                    493:   case WSAEINPROGRESS:
                    494:   case WSAEALREADY:
                    495:     p = "Blocking call in progress";
                    496:     break;
                    497:   case WSAENOTSOCK:
                    498:     p = "Descriptor is not a socket";
                    499:     break;
                    500:   case WSAEDESTADDRREQ:
                    501:     p = "Need destination address";
                    502:     break;
                    503:   case WSAEMSGSIZE:
                    504:     p = "Bad message size";
                    505:     break;
                    506:   case WSAEPROTOTYPE:
                    507:     p = "Bad protocol";
                    508:     break;
                    509:   case WSAENOPROTOOPT:
                    510:     p = "Protocol option is unsupported";
                    511:     break;
                    512:   case WSAEPROTONOSUPPORT:
                    513:     p = "Protocol is unsupported";
                    514:     break;
                    515:   case WSAESOCKTNOSUPPORT:
                    516:     p = "Socket is unsupported";
                    517:     break;
                    518:   case WSAEOPNOTSUPP:
                    519:     p = "Operation not supported";
                    520:     break;
                    521:   case WSAEAFNOSUPPORT:
                    522:     p = "Address family not supported";
                    523:     break;
                    524:   case WSAEPFNOSUPPORT:
                    525:     p = "Protocol family not supported";
                    526:     break;
                    527:   case WSAEADDRINUSE:
                    528:     p = "Address already in use";
                    529:     break;
                    530:   case WSAEADDRNOTAVAIL:
                    531:     p = "Address not available";
                    532:     break;
                    533:   case WSAENETDOWN:
                    534:     p = "Network down";
                    535:     break;
                    536:   case WSAENETUNREACH:
                    537:     p = "Network unreachable";
                    538:     break;
                    539:   case WSAENETRESET:
                    540:     p = "Network has been reset";
                    541:     break;
                    542:   case WSAECONNABORTED:
                    543:     p = "Connection was aborted";
                    544:     break;
                    545:   case WSAECONNRESET:
                    546:     p = "Connection was reset";
                    547:     break;
                    548:   case WSAENOBUFS:
                    549:     p = "No buffer space";
                    550:     break;
                    551:   case WSAEISCONN:
                    552:     p = "Socket is already connected";
                    553:     break;
                    554:   case WSAENOTCONN:
                    555:     p = "Socket is not connected";
                    556:     break;
                    557:   case WSAESHUTDOWN:
                    558:     p = "Socket has been shut down";
                    559:     break;
                    560:   case WSAETOOMANYREFS:
                    561:     p = "Too many references";
                    562:     break;
                    563:   case WSAETIMEDOUT:
                    564:     p = "Timed out";
                    565:     break;
                    566:   case WSAECONNREFUSED:
                    567:     p = "Connection refused";
                    568:     break;
                    569:   case WSAELOOP:
                    570:     p = "Loop??";
                    571:     break;
                    572:   case WSAENAMETOOLONG:
                    573:     p = "Name too long";
                    574:     break;
                    575:   case WSAEHOSTDOWN:
                    576:     p = "Host down";
                    577:     break;
                    578:   case WSAEHOSTUNREACH:
                    579:     p = "Host unreachable";
                    580:     break;
                    581:   case WSAENOTEMPTY:
                    582:     p = "Not empty";
                    583:     break;
                    584:   case WSAEPROCLIM:
                    585:     p = "Process limit reached";
                    586:     break;
                    587:   case WSAEUSERS:
                    588:     p = "Too many users";
                    589:     break;
                    590:   case WSAEDQUOT:
                    591:     p = "Bad quota";
                    592:     break;
                    593:   case WSAESTALE:
                    594:     p = "Something is stale";
                    595:     break;
                    596:   case WSAEREMOTE:
                    597:     p = "Remote error";
                    598:     break;
                    599: #ifdef WSAEDISCON  /* missing in SalfordC! */
                    600:   case WSAEDISCON:
                    601:     p = "Disconnected";
                    602:     break;
                    603: #endif
                    604:     /* Extended Winsock errors */
                    605:   case WSASYSNOTREADY:
                    606:     p = "Winsock library is not ready";
                    607:     break;
                    608:   case WSANOTINITIALISED:
                    609:     p = "Winsock library not initialised";
                    610:     break;
                    611:   case WSAVERNOTSUPPORTED:
                    612:     p = "Winsock version not supported";
                    613:     break;
                    614: 
                    615:     /* getXbyY() errors (already handled in herrmsg):
                    616:      * Authoritative Answer: Host not found */
                    617:   case WSAHOST_NOT_FOUND:
                    618:     p = "Host not found";
                    619:     break;
                    620: 
                    621:     /* Non-Authoritative: Host not found, or SERVERFAIL */
                    622:   case WSATRY_AGAIN:
                    623:     p = "Host not found, try again";
                    624:     break;
                    625: 
                    626:     /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
                    627:   case WSANO_RECOVERY:
                    628:     p = "Unrecoverable error in call to nameserver";
                    629:     break;
                    630: 
                    631:     /* Valid name, no data record of requested type */
                    632:   case WSANO_DATA:
                    633:     p = "No data record of requested type";
                    634:     break;
                    635: 
                    636:   default:
                    637:     return NULL;
                    638:   }
                    639:   strncpy(buf, p, len);
                    640:   buf [len-1] = '\0';
                    641:   return buf;
                    642: #endif
                    643: }
                    644: #endif   /* USE_WINSOCK */
                    645: 
                    646: #if defined(WIN32) || defined(_WIN32_WCE)
                    647: /* This is a helper function for Curl_strerror that converts Windows API error
                    648:  * codes (GetLastError) to error messages.
                    649:  * Returns NULL if no error message was found for error code.
                    650:  */
                    651: static const char *
                    652: get_winapi_error(int err, char *buf, size_t buflen)
                    653: {
                    654:   char *p;
                    655: 
                    656:   if(!buflen)
                    657:     return NULL;
                    658: 
                    659:   *buf = '\0';
                    660: 
                    661: #ifdef _WIN32_WCE
                    662:   {
                    663:     wchar_t wbuf[256];
                    664:     wbuf[0] = L'\0';
                    665: 
                    666:     if(FormatMessage((FORMAT_MESSAGE_FROM_SYSTEM |
                    667:                       FORMAT_MESSAGE_IGNORE_INSERTS), NULL, err,
                    668:                      LANG_NEUTRAL, wbuf, sizeof(wbuf)/sizeof(wchar_t), NULL)) {
                    669:       size_t written = wcstombs(buf, wbuf, buflen - 1);
                    670:       if(written != (size_t)-1)
                    671:         buf[written] = '\0';
                    672:       else
                    673:         *buf = '\0';
                    674:     }
                    675:   }
                    676: #else
                    677:   if(!FormatMessageA((FORMAT_MESSAGE_FROM_SYSTEM |
                    678:                       FORMAT_MESSAGE_IGNORE_INSERTS), NULL, err,
                    679:                      LANG_NEUTRAL, buf, (DWORD)buflen, NULL)) {
                    680:     *buf = '\0';
                    681:   }
                    682: #endif
                    683: 
                    684:   /* Truncate multiple lines */
                    685:   p = strchr(buf, '\n');
                    686:   if(p) {
                    687:     if(p > buf && *(p-1) == '\r')
                    688:       *(p-1) = '\0';
                    689:     else
                    690:       *p = '\0';
                    691:   }
                    692: 
                    693:   return (*buf ? buf : NULL);
                    694: }
                    695: #endif /* WIN32 || _WIN32_WCE */
                    696: 
                    697: /*
                    698:  * Our thread-safe and smart strerror() replacement.
                    699:  *
                    700:  * The 'err' argument passed in to this function MUST be a true errno number
                    701:  * as reported on this system. We do no range checking on the number before
                    702:  * we pass it to the "number-to-message" conversion function and there might
                    703:  * be systems that don't do proper range checking in there themselves.
                    704:  *
                    705:  * We don't do range checking (on systems other than Windows) since there is
                    706:  * no good reliable and portable way to do it.
                    707:  *
                    708:  * On Windows different types of error codes overlap. This function has an
                    709:  * order of preference when trying to match error codes:
                    710:  * CRT (errno), Winsock (WSAGetLastError), Windows API (GetLastError).
                    711:  *
                    712:  * It may be more correct to call one of the variant functions instead:
                    713:  * Call Curl_sspi_strerror if the error code is definitely Windows SSPI.
                    714:  * Call Curl_winapi_strerror if the error code is definitely Windows API.
                    715:  */
                    716: const char *Curl_strerror(int err, char *buf, size_t buflen)
                    717: {
                    718: #ifdef PRESERVE_WINDOWS_ERROR_CODE
                    719:   DWORD old_win_err = GetLastError();
                    720: #endif
                    721:   int old_errno = errno;
                    722:   char *p;
                    723:   size_t max;
                    724: 
                    725:   if(!buflen)
                    726:     return NULL;
                    727: 
                    728:   DEBUGASSERT(err >= 0);
                    729: 
                    730:   max = buflen - 1;
                    731:   *buf = '\0';
                    732: 
                    733: #if defined(WIN32) || defined(_WIN32_WCE)
                    734: #if defined(WIN32)
                    735:   /* 'sys_nerr' is the maximum errno number, it is not widely portable */
                    736:   if(err >= 0 && err < sys_nerr)
                    737:     strncpy(buf, strerror(err), max);
                    738:   else
                    739: #endif
                    740:   {
                    741:     if(
                    742: #ifdef USE_WINSOCK
                    743:        !get_winsock_error(err, buf, max) &&
                    744: #endif
                    745:        !get_winapi_error((DWORD)err, buf, max))
                    746:       msnprintf(buf, max, "Unknown error %d (%#x)", err, err);
                    747:   }
                    748: #else /* not Windows coming up */
                    749: 
                    750: #if defined(HAVE_STRERROR_R) && defined(HAVE_POSIX_STRERROR_R)
                    751:  /*
                    752:   * The POSIX-style strerror_r() may set errno to ERANGE if insufficient
                    753:   * storage is supplied via 'strerrbuf' and 'buflen' to hold the generated
                    754:   * message string, or EINVAL if 'errnum' is not a valid error number.
                    755:   */
                    756:   if(0 != strerror_r(err, buf, max)) {
                    757:     if('\0' == buf[0])
                    758:       msnprintf(buf, max, "Unknown error %d", err);
                    759:   }
                    760: #elif defined(HAVE_STRERROR_R) && defined(HAVE_GLIBC_STRERROR_R)
                    761:  /*
                    762:   * The glibc-style strerror_r() only *might* use the buffer we pass to
                    763:   * the function, but it always returns the error message as a pointer,
                    764:   * so we must copy that string unconditionally (if non-NULL).
                    765:   */
                    766:   {
                    767:     char buffer[256];
                    768:     char *msg = strerror_r(err, buffer, sizeof(buffer));
                    769:     if(msg)
                    770:       strncpy(buf, msg, max);
                    771:     else
                    772:       msnprintf(buf, max, "Unknown error %d", err);
                    773:   }
                    774: #elif defined(HAVE_STRERROR_R) && defined(HAVE_VXWORKS_STRERROR_R)
                    775:  /*
                    776:   * The vxworks-style strerror_r() does use the buffer we pass to the function.
                    777:   * The buffer size should be at least NAME_MAX (256)
                    778:   */
                    779:   {
                    780:     char buffer[256];
                    781:     if(OK == strerror_r(err, buffer))
                    782:       strncpy(buf, buffer, max);
                    783:     else
                    784:       msnprintf(buf, max, "Unknown error %d", err);
                    785:   }
                    786: #else
                    787:   {
                    788:     char *msg = strerror(err);
                    789:     if(msg)
                    790:       strncpy(buf, msg, max);
                    791:     else
                    792:       msnprintf(buf, max, "Unknown error %d", err);
                    793:   }
                    794: #endif
                    795: 
                    796: #endif /* end of not Windows */
                    797: 
                    798:   buf[max] = '\0'; /* make sure the string is zero terminated */
                    799: 
                    800:   /* strip trailing '\r\n' or '\n'. */
                    801:   p = strrchr(buf, '\n');
                    802:   if(p && (p - buf) >= 2)
                    803:     *p = '\0';
                    804:   p = strrchr(buf, '\r');
                    805:   if(p && (p - buf) >= 1)
                    806:     *p = '\0';
                    807: 
                    808:   if(errno != old_errno)
                    809:     errno = old_errno;
                    810: 
                    811: #ifdef PRESERVE_WINDOWS_ERROR_CODE
                    812:   if(old_win_err != GetLastError())
                    813:     SetLastError(old_win_err);
                    814: #endif
                    815: 
                    816:   return buf;
                    817: }
                    818: 
                    819: /*
                    820:  * Curl_winapi_strerror:
                    821:  * Variant of Curl_strerror if the error code is definitely Windows API.
                    822:  */
                    823: #if defined(WIN32) || defined(_WIN32_WCE)
                    824: const char *Curl_winapi_strerror(DWORD err, char *buf, size_t buflen)
                    825: {
                    826: #ifdef PRESERVE_WINDOWS_ERROR_CODE
                    827:   DWORD old_win_err = GetLastError();
                    828: #endif
                    829:   int old_errno = errno;
                    830: 
                    831:   if(!buflen)
                    832:     return NULL;
                    833: 
                    834:   *buf = '\0';
                    835: 
                    836: #ifndef CURL_DISABLE_VERBOSE_STRINGS
                    837:   if(!get_winapi_error(err, buf, buflen)) {
                    838:     msnprintf(buf, buflen, "Unknown error %u (0x%08X)", err, err);
                    839:   }
                    840: #else
                    841:   {
                    842:     const char *txt = (err == ERROR_SUCCESS) ? "No error" : "Error";
                    843:     strncpy(buf, txt, buflen);
                    844:     buf[buflen - 1] = '\0';
                    845:   }
                    846: #endif
                    847: 
                    848:   if(errno != old_errno)
                    849:     errno = old_errno;
                    850: 
                    851: #ifdef PRESERVE_WINDOWS_ERROR_CODE
                    852:   if(old_win_err != GetLastError())
                    853:     SetLastError(old_win_err);
                    854: #endif
                    855: 
                    856:   return buf;
                    857: }
                    858: #endif /* WIN32 || _WIN32_WCE */
                    859: 
                    860: #ifdef USE_WINDOWS_SSPI
                    861: /*
                    862:  * Curl_sspi_strerror:
                    863:  * Variant of Curl_strerror if the error code is definitely Windows SSPI.
                    864:  */
                    865: const char *Curl_sspi_strerror(int err, char *buf, size_t buflen)
                    866: {
                    867: #ifdef PRESERVE_WINDOWS_ERROR_CODE
                    868:   DWORD old_win_err = GetLastError();
                    869: #endif
                    870:   int old_errno = errno;
                    871:   const char *txt;
                    872: 
                    873:   if(!buflen)
                    874:     return NULL;
                    875: 
                    876:   *buf = '\0';
                    877: 
                    878: #ifndef CURL_DISABLE_VERBOSE_STRINGS
                    879: 
                    880:   switch(err) {
                    881:     case SEC_E_OK:
                    882:       txt = "No error";
                    883:       break;
                    884: #define SEC2TXT(sec) case sec: txt = #sec; break
                    885:     SEC2TXT(CRYPT_E_REVOKED);
                    886:     SEC2TXT(SEC_E_ALGORITHM_MISMATCH);
                    887:     SEC2TXT(SEC_E_BAD_BINDINGS);
                    888:     SEC2TXT(SEC_E_BAD_PKGID);
                    889:     SEC2TXT(SEC_E_BUFFER_TOO_SMALL);
                    890:     SEC2TXT(SEC_E_CANNOT_INSTALL);
                    891:     SEC2TXT(SEC_E_CANNOT_PACK);
                    892:     SEC2TXT(SEC_E_CERT_EXPIRED);
                    893:     SEC2TXT(SEC_E_CERT_UNKNOWN);
                    894:     SEC2TXT(SEC_E_CERT_WRONG_USAGE);
                    895:     SEC2TXT(SEC_E_CONTEXT_EXPIRED);
                    896:     SEC2TXT(SEC_E_CROSSREALM_DELEGATION_FAILURE);
                    897:     SEC2TXT(SEC_E_CRYPTO_SYSTEM_INVALID);
                    898:     SEC2TXT(SEC_E_DECRYPT_FAILURE);
                    899:     SEC2TXT(SEC_E_DELEGATION_POLICY);
                    900:     SEC2TXT(SEC_E_DELEGATION_REQUIRED);
                    901:     SEC2TXT(SEC_E_DOWNGRADE_DETECTED);
                    902:     SEC2TXT(SEC_E_ENCRYPT_FAILURE);
                    903:     SEC2TXT(SEC_E_ILLEGAL_MESSAGE);
                    904:     SEC2TXT(SEC_E_INCOMPLETE_CREDENTIALS);
                    905:     SEC2TXT(SEC_E_INCOMPLETE_MESSAGE);
                    906:     SEC2TXT(SEC_E_INSUFFICIENT_MEMORY);
                    907:     SEC2TXT(SEC_E_INTERNAL_ERROR);
                    908:     SEC2TXT(SEC_E_INVALID_HANDLE);
                    909:     SEC2TXT(SEC_E_INVALID_PARAMETER);
                    910:     SEC2TXT(SEC_E_INVALID_TOKEN);
                    911:     SEC2TXT(SEC_E_ISSUING_CA_UNTRUSTED);
                    912:     SEC2TXT(SEC_E_ISSUING_CA_UNTRUSTED_KDC);
                    913:     SEC2TXT(SEC_E_KDC_CERT_EXPIRED);
                    914:     SEC2TXT(SEC_E_KDC_CERT_REVOKED);
                    915:     SEC2TXT(SEC_E_KDC_INVALID_REQUEST);
                    916:     SEC2TXT(SEC_E_KDC_UNABLE_TO_REFER);
                    917:     SEC2TXT(SEC_E_KDC_UNKNOWN_ETYPE);
                    918:     SEC2TXT(SEC_E_LOGON_DENIED);
                    919:     SEC2TXT(SEC_E_MAX_REFERRALS_EXCEEDED);
                    920:     SEC2TXT(SEC_E_MESSAGE_ALTERED);
                    921:     SEC2TXT(SEC_E_MULTIPLE_ACCOUNTS);
                    922:     SEC2TXT(SEC_E_MUST_BE_KDC);
                    923:     SEC2TXT(SEC_E_NOT_OWNER);
                    924:     SEC2TXT(SEC_E_NO_AUTHENTICATING_AUTHORITY);
                    925:     SEC2TXT(SEC_E_NO_CREDENTIALS);
                    926:     SEC2TXT(SEC_E_NO_IMPERSONATION);
                    927:     SEC2TXT(SEC_E_NO_IP_ADDRESSES);
                    928:     SEC2TXT(SEC_E_NO_KERB_KEY);
                    929:     SEC2TXT(SEC_E_NO_PA_DATA);
                    930:     SEC2TXT(SEC_E_NO_S4U_PROT_SUPPORT);
                    931:     SEC2TXT(SEC_E_NO_TGT_REPLY);
                    932:     SEC2TXT(SEC_E_OUT_OF_SEQUENCE);
                    933:     SEC2TXT(SEC_E_PKINIT_CLIENT_FAILURE);
                    934:     SEC2TXT(SEC_E_PKINIT_NAME_MISMATCH);
                    935:     SEC2TXT(SEC_E_POLICY_NLTM_ONLY);
                    936:     SEC2TXT(SEC_E_QOP_NOT_SUPPORTED);
                    937:     SEC2TXT(SEC_E_REVOCATION_OFFLINE_C);
                    938:     SEC2TXT(SEC_E_REVOCATION_OFFLINE_KDC);
                    939:     SEC2TXT(SEC_E_SECPKG_NOT_FOUND);
                    940:     SEC2TXT(SEC_E_SECURITY_QOS_FAILED);
                    941:     SEC2TXT(SEC_E_SHUTDOWN_IN_PROGRESS);
                    942:     SEC2TXT(SEC_E_SMARTCARD_CERT_EXPIRED);
                    943:     SEC2TXT(SEC_E_SMARTCARD_CERT_REVOKED);
                    944:     SEC2TXT(SEC_E_SMARTCARD_LOGON_REQUIRED);
                    945:     SEC2TXT(SEC_E_STRONG_CRYPTO_NOT_SUPPORTED);
                    946:     SEC2TXT(SEC_E_TARGET_UNKNOWN);
                    947:     SEC2TXT(SEC_E_TIME_SKEW);
                    948:     SEC2TXT(SEC_E_TOO_MANY_PRINCIPALS);
                    949:     SEC2TXT(SEC_E_UNFINISHED_CONTEXT_DELETED);
                    950:     SEC2TXT(SEC_E_UNKNOWN_CREDENTIALS);
                    951:     SEC2TXT(SEC_E_UNSUPPORTED_FUNCTION);
                    952:     SEC2TXT(SEC_E_UNSUPPORTED_PREAUTH);
                    953:     SEC2TXT(SEC_E_UNTRUSTED_ROOT);
                    954:     SEC2TXT(SEC_E_WRONG_CREDENTIAL_HANDLE);
                    955:     SEC2TXT(SEC_E_WRONG_PRINCIPAL);
                    956:     SEC2TXT(SEC_I_COMPLETE_AND_CONTINUE);
                    957:     SEC2TXT(SEC_I_COMPLETE_NEEDED);
                    958:     SEC2TXT(SEC_I_CONTEXT_EXPIRED);
                    959:     SEC2TXT(SEC_I_CONTINUE_NEEDED);
                    960:     SEC2TXT(SEC_I_INCOMPLETE_CREDENTIALS);
                    961:     SEC2TXT(SEC_I_LOCAL_LOGON);
                    962:     SEC2TXT(SEC_I_NO_LSA_CONTEXT);
                    963:     SEC2TXT(SEC_I_RENEGOTIATE);
                    964:     SEC2TXT(SEC_I_SIGNATURE_NEEDED);
                    965:     default:
                    966:       txt = "Unknown error";
                    967:   }
                    968: 
                    969:   if(err == SEC_E_ILLEGAL_MESSAGE) {
                    970:     msnprintf(buf, buflen,
                    971:               "SEC_E_ILLEGAL_MESSAGE (0x%08X) - This error usually occurs "
                    972:               "when a fatal SSL/TLS alert is received (e.g. handshake failed)."
                    973:               " More detail may be available in the Windows System event log.",
                    974:               err);
                    975:   }
                    976:   else {
                    977:     char txtbuf[80];
                    978:     char msgbuf[256];
                    979: 
                    980:     msnprintf(txtbuf, sizeof(txtbuf), "%s (0x%08X)", txt, err);
                    981: 
                    982:     if(get_winapi_error(err, msgbuf, sizeof(msgbuf)))
                    983:       msnprintf(buf, buflen, "%s - %s", txtbuf, msgbuf);
                    984:     else {
                    985:       strncpy(buf, txtbuf, buflen);
                    986:       buf[buflen - 1] = '\0';
                    987:     }
                    988:   }
                    989: 
                    990: #else
                    991:   if(err == SEC_E_OK)
                    992:     txt = "No error";
                    993:   else
                    994:     txt = "Error";
                    995:   strncpy(buf, txt, buflen);
                    996:   buf[buflen - 1] = '\0';
                    997: #endif
                    998: 
                    999:   if(errno != old_errno)
                   1000:     errno = old_errno;
                   1001: 
                   1002: #ifdef PRESERVE_WINDOWS_ERROR_CODE
                   1003:   if(old_win_err != GetLastError())
                   1004:     SetLastError(old_win_err);
                   1005: #endif
                   1006: 
                   1007:   return buf;
                   1008: }
                   1009: #endif /* USE_WINDOWS_SSPI */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>