diff options
Diffstat (limited to 'Utilities/cmcurl/lib/strerror.c')
-rw-r--r-- | Utilities/cmcurl/lib/strerror.c | 706 |
1 files changed, 541 insertions, 165 deletions
diff --git a/Utilities/cmcurl/lib/strerror.c b/Utilities/cmcurl/lib/strerror.c index 74c3457..66033f2 100644 --- a/Utilities/cmcurl/lib/strerror.c +++ b/Utilities/cmcurl/lib/strerror.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2004 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2004 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -18,21 +18,22 @@ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * - * $Id$ ***************************************************************************/ -#include "setup.h" +#include "curl_setup.h" #ifdef HAVE_STRERROR_R -#if !defined(HAVE_POSIX_STRERROR_R) && !defined(HAVE_GLIBC_STRERROR_R) -#error "you MUST have either POSIX or glibc strerror_r if strerror_r is found" -#endif /* !POSIX && !glibc */ -#endif /* HAVE_STRERROR_R */ +# if (!defined(HAVE_POSIX_STRERROR_R) && \ + !defined(HAVE_GLIBC_STRERROR_R) && \ + !defined(HAVE_VXWORKS_STRERROR_R)) || \ + (defined(HAVE_POSIX_STRERROR_R) && defined(HAVE_VXWORKS_STRERROR_R)) || \ + (defined(HAVE_GLIBC_STRERROR_R) && defined(HAVE_VXWORKS_STRERROR_R)) || \ + (defined(HAVE_POSIX_STRERROR_R) && defined(HAVE_GLIBC_STRERROR_R)) +# error "strerror_r MUST be either POSIX, glibc or vxworks-style" +# endif +#endif #include <curl/curl.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> #ifdef USE_LIBIDN #include <idna.h> @@ -43,14 +44,9 @@ #define _MPRINTF_REPLACE /* use our functions only */ #include <curl/mprintf.h> -#if defined(HAVE_STRERROR_R) && defined(HAVE_NO_STRERROR_R_DECL) -#ifdef HAVE_POSIX_STRERROR_R -/* seen on AIX 5100-02 gcc 2.9 */ -extern int strerror_r(int errnum, char *strerrbuf, size_t buflen); -#else -extern char *strerror_r(int errnum, char *buf, size_t buflen); -#endif -#endif +#include "curl_memory.h" +/* The last #include file should be: */ +#include "memdebug.h" const char * curl_easy_strerror(CURLcode error) @@ -58,13 +54,13 @@ curl_easy_strerror(CURLcode error) #ifndef CURL_DISABLE_VERBOSE_STRINGS switch (error) { case CURLE_OK: - return "no error"; + return "No error"; case CURLE_UNSUPPORTED_PROTOCOL: - return "unsupported protocol"; + return "Unsupported protocol"; case CURLE_FAILED_INIT: - return "failed init"; + return "Failed initialization"; case CURLE_URL_MALFORMAT: return "URL using bad/illegal format or missing URL"; @@ -74,26 +70,32 @@ curl_easy_strerror(CURLcode error) " this libcurl due to a build-time decision."; case CURLE_COULDNT_RESOLVE_PROXY: - return "couldn't resolve proxy name"; + return "Couldn't resolve proxy name"; case CURLE_COULDNT_RESOLVE_HOST: - return "couldn't resolve host name"; + return "Couldn't resolve host name"; case CURLE_COULDNT_CONNECT: - return "couldn't connect to server"; + return "Couldn't connect to server"; case CURLE_FTP_WEIRD_SERVER_REPLY: return "FTP: weird server reply"; - case CURLE_FTP_ACCESS_DENIED: - return "FTP: access denied"; + case CURLE_REMOTE_ACCESS_DENIED: + return "Access denied to remote resource"; + + case CURLE_FTP_ACCEPT_FAILED: + return "FTP: The server failed to connect to data port"; + + case CURLE_FTP_ACCEPT_TIMEOUT: + return "FTP: Accepting server connect has timed out"; + + case CURLE_FTP_PRET_FAILED: + return "FTP: The server did not accept the PRET command."; case CURLE_FTP_WEIRD_PASS_REPLY: return "FTP: unknown PASS reply"; - case CURLE_FTP_WEIRD_USER_REPLY: - return "FTP: unknown USER reply"; - case CURLE_FTP_WEIRD_PASV_REPLY: return "FTP: unknown PASV reply"; @@ -103,11 +105,11 @@ curl_easy_strerror(CURLcode error) case CURLE_FTP_CANT_GET_HOST: return "FTP: can't figure out the host in the PASV response"; - case CURLE_FTP_CANT_RECONNECT: - return "FTP: can't connect to server the response code is unknown"; + case CURLE_HTTP2: + return "Error in the HTTP2 framing layer"; - case CURLE_FTP_COULDNT_SET_BINARY: - return "FTP: couldn't set binary mode"; + case CURLE_FTP_COULDNT_SET_TYPE: + return "FTP: couldn't set file type"; case CURLE_PARTIAL_FILE: return "Transferred a partial file"; @@ -115,60 +117,47 @@ curl_easy_strerror(CURLcode error) case CURLE_FTP_COULDNT_RETR_FILE: return "FTP: couldn't retrieve (RETR failed) the specified file"; - case CURLE_FTP_WRITE_ERROR: - return "FTP: the post-transfer acknowledge response was not OK"; - - case CURLE_FTP_QUOTE_ERROR: - return "FTP: a quote command returned error"; + case CURLE_QUOTE_ERROR: + return "Quote command returned error"; case CURLE_HTTP_RETURNED_ERROR: return "HTTP response code said error"; case CURLE_WRITE_ERROR: - return "failed writing received data to disk/application"; + return "Failed writing received data to disk/application"; - case CURLE_FTP_COULDNT_STOR_FILE: - return "failed FTP upload (the STOR command)"; + case CURLE_UPLOAD_FAILED: + return "Upload failed (at start/before it took off)"; case CURLE_READ_ERROR: - return "failed to open/read local data from file/application"; + return "Failed to open/read local data from file/application"; case CURLE_OUT_OF_MEMORY: -#ifdef CURL_DOES_CONVERSIONS - return "conversion failed -or- out of memory"; -#else - return "out of memory"; -#endif /* CURL_DOES_CONVERSIONS */ - - case CURLE_OPERATION_TIMEOUTED: - return "a timeout was reached"; + return "Out of memory"; - case CURLE_FTP_COULDNT_SET_ASCII: - return "FTP could not set ASCII mode (TYPE A)"; + case CURLE_OPERATION_TIMEDOUT: + return "Timeout was reached"; case CURLE_FTP_PORT_FAILED: - return "FTP command PORT failed"; + return "FTP: command PORT failed"; case CURLE_FTP_COULDNT_USE_REST: - return "FTP command REST failed"; + return "FTP: command REST failed"; - case CURLE_FTP_COULDNT_GET_SIZE: - return "FTP command SIZE failed"; - - case CURLE_HTTP_RANGE_ERROR: - return "a range was requested but the server did not deliver it"; + case CURLE_RANGE_ERROR: + return "Requested range was not delivered by the server"; case CURLE_HTTP_POST_ERROR: - return "internal problem setting up the POST"; + return "Internal problem setting up the POST"; case CURLE_SSL_CONNECT_ERROR: return "SSL connect error"; case CURLE_BAD_DOWNLOAD_RESUME: - return "couldn't resume download"; + return "Couldn't resume download"; case CURLE_FILE_COULDNT_READ_FILE: - return "couldn't read a file:// file"; + return "Couldn't read a file:// file"; case CURLE_LDAP_CANNOT_BIND: return "LDAP: cannot bind"; @@ -176,68 +165,63 @@ curl_easy_strerror(CURLcode error) case CURLE_LDAP_SEARCH_FAILED: return "LDAP: search failed"; - case CURLE_LIBRARY_NOT_FOUND: - return "a required shared library was not found"; - case CURLE_FUNCTION_NOT_FOUND: - return "a required function in the shared library was not found"; + return "A required function in the library was not found"; case CURLE_ABORTED_BY_CALLBACK: - return "the operation was aborted by an application callback"; + return "Operation was aborted by an application callback"; case CURLE_BAD_FUNCTION_ARGUMENT: - return "a libcurl function was given a bad argument"; + return "A libcurl function was given a bad argument"; case CURLE_INTERFACE_FAILED: - return "failed binding local connection end"; + return "Failed binding local connection end"; case CURLE_TOO_MANY_REDIRECTS : - return "number of redirects hit maximum amount"; + return "Number of redirects hit maximum amount"; - case CURLE_UNKNOWN_TELNET_OPTION: - return "User specified an unknown option"; + case CURLE_UNKNOWN_OPTION: + return "An unknown option was passed in to libcurl"; case CURLE_TELNET_OPTION_SYNTAX : return "Malformed telnet option"; - case CURLE_SSL_PEER_CERTIFICATE: - return "SSL peer certificate was not ok"; + case CURLE_PEER_FAILED_VERIFICATION: + return "SSL peer certificate or SSH remote key was not OK"; case CURLE_GOT_NOTHING: - return "server returned nothing (no headers, no data)"; + return "Server returned nothing (no headers, no data)"; case CURLE_SSL_ENGINE_NOTFOUND: return "SSL crypto engine not found"; case CURLE_SSL_ENGINE_SETFAILED: - return "can not set SSL crypto engine as default"; + return "Can not set SSL crypto engine as default"; case CURLE_SSL_ENGINE_INITFAILED: - return "failed to initialise SSL crypto engine"; + return "Failed to initialise SSL crypto engine"; case CURLE_SEND_ERROR: - return "failed sending data to the peer"; + return "Failed sending data to the peer"; case CURLE_RECV_ERROR: - return "failure when receiving data from the peer"; - - case CURLE_SHARE_IN_USE: - return "share is already in use"; + return "Failure when receiving data from the peer"; case CURLE_SSL_CERTPROBLEM: - return "problem with the local SSL certificate"; + return "Problem with the local SSL certificate"; case CURLE_SSL_CIPHER: - return "couldn't use specified SSL cipher"; + return "Couldn't use specified SSL cipher"; case CURLE_SSL_CACERT: - return "peer certificate cannot be authenticated with known CA certificates"; + return "Peer certificate cannot be authenticated with given CA " + "certificates"; case CURLE_SSL_CACERT_BADFILE: - return "problem with the SSL CA cert (path? access rights?)"; + return "Problem with the SSL CA cert (path? access rights?)"; case CURLE_BAD_CONTENT_ENCODING: - return "Unrecognized HTTP Content-Encoding"; + return "Unrecognized or bad HTTP Content or Transfer-Encoding"; case CURLE_LDAP_INVALID_URL: return "Invalid LDAP URL"; @@ -245,17 +229,23 @@ curl_easy_strerror(CURLcode error) case CURLE_FILESIZE_EXCEEDED: return "Maximum file size exceeded"; - case CURLE_FTP_SSL_FAILED: - return "Requested FTP SSL level failed"; + case CURLE_USE_SSL_FAILED: + return "Requested SSL level failed"; case CURLE_SSL_SHUTDOWN_FAILED: return "Failed to shut down the SSL connection"; + case CURLE_SSL_CRL_BADFILE: + return "Failed to load CRL file (path? access rights?, format?)"; + + case CURLE_SSL_ISSUER_ERROR: + return "Issuer check against peer certificate failed"; + case CURLE_SEND_FAIL_REWIND: return "Send failed since rewinding of the data stream failed"; case CURLE_LOGIN_DENIED: - return "FTP: login denied"; + return "Login denied"; case CURLE_TFTP_NOTFOUND: return "TFTP: File Not Found"; @@ -263,8 +253,8 @@ curl_easy_strerror(CURLcode error) case CURLE_TFTP_PERM: return "TFTP: Access Violation"; - case CURLE_TFTP_DISKFULL: - return "TFTP: Disk full or allocation exceeded"; + case CURLE_REMOTE_DISK_FULL: + return "Disk full or allocation exceeded"; case CURLE_TFTP_ILLEGAL: return "TFTP: Illegal operation"; @@ -272,17 +262,17 @@ curl_easy_strerror(CURLcode error) case CURLE_TFTP_UNKNOWNID: return "TFTP: Unknown transfer ID"; - case CURLE_TFTP_EXISTS: - return "TFTP: File already exists"; + case CURLE_REMOTE_FILE_EXISTS: + return "Remote file already exists"; case CURLE_TFTP_NOSUCHUSER: return "TFTP: No such user"; case CURLE_CONV_FAILED: - return "conversion failed"; + return "Conversion failed"; case CURLE_CONV_REQD: - return "caller must register CURLOPT_CONV_ callback options"; + return "Caller must register CURLOPT_CONV_ callback options"; case CURLE_REMOTE_FILE_NOT_FOUND: return "Remote file not found"; @@ -290,12 +280,34 @@ curl_easy_strerror(CURLcode error) case CURLE_SSH: return "Error in the SSH layer"; + case CURLE_AGAIN: + return "Socket not ready for send/recv"; + + case CURLE_RTSP_CSEQ_ERROR: + return "RTSP CSeq mismatch or invalid CSeq"; + + case CURLE_RTSP_SESSION_ERROR: + return "RTSP session error"; + + case CURLE_FTP_BAD_FILE_LIST: + return "Unable to parse FTP file list"; + + case CURLE_CHUNK_FAILED: + return "Chunk callback failed"; + + case CURLE_NO_CONNECTION_AVAILABLE: + return "The max connection limit is reached"; + /* error codes not used by current libcurl */ - case CURLE_FTP_USER_PASSWORD_INCORRECT: - case CURLE_MALFORMAT_USER: - case CURLE_BAD_CALLING_ORDER: - case CURLE_BAD_PASSWORD_ENTERED: - case CURLE_OBSOLETE: + case CURLE_OBSOLETE20: + case CURLE_OBSOLETE24: + case CURLE_OBSOLETE29: + case CURLE_OBSOLETE32: + case CURLE_OBSOLETE40: + case CURLE_OBSOLETE44: + case CURLE_OBSOLETE46: + case CURLE_OBSOLETE50: + case CURLE_OBSOLETE57: case CURL_LAST: break; } @@ -313,12 +325,12 @@ curl_easy_strerror(CURLcode error) * The line number for the error will be near this comment, which * is why it is here, and not at the start of the switch. */ - return "unknown error"; + return "Unknown error"; #else - if (error == CURLE_OK) - return "no error"; + if(error == CURLE_OK) + return "No error"; else - return "error"; + return "Error"; #endif } @@ -328,39 +340,42 @@ curl_multi_strerror(CURLMcode error) #ifndef CURL_DISABLE_VERBOSE_STRINGS switch (error) { case CURLM_CALL_MULTI_PERFORM: - return "please call curl_multi_perform() soon"; + return "Please call curl_multi_perform() soon"; case CURLM_OK: - return "no error"; + return "No error"; case CURLM_BAD_HANDLE: - return "invalid multi handle"; + return "Invalid multi handle"; case CURLM_BAD_EASY_HANDLE: - return "invalid easy handle"; + return "Invalid easy handle"; case CURLM_OUT_OF_MEMORY: - return "out of memory"; + return "Out of memory"; case CURLM_INTERNAL_ERROR: - return "internal error"; + return "Internal error"; case CURLM_BAD_SOCKET: - return "invalid socket argument"; + return "Invalid socket argument"; case CURLM_UNKNOWN_OPTION: - return "unknown option"; + return "Unknown option"; + + case CURLM_ADDED_ALREADY: + return "The easy handle is already added to a multi handle"; case CURLM_LAST: break; } - return "unknown error"; + return "Unknown error"; #else - if (error == CURLM_OK) - return "no error"; + if(error == CURLM_OK) + return "No error"; else - return "error"; + return "Error"; #endif } @@ -370,30 +385,33 @@ curl_share_strerror(CURLSHcode error) #ifndef CURL_DISABLE_VERBOSE_STRINGS switch (error) { case CURLSHE_OK: - return "no error"; + return "No error"; case CURLSHE_BAD_OPTION: - return "unknown share option"; + return "Unknown share option"; case CURLSHE_IN_USE: - return "share currently in use"; + return "Share currently in use"; case CURLSHE_INVALID: - return "invalid share handle"; + return "Invalid share handle"; case CURLSHE_NOMEM: - return "out of memory"; + return "Out of memory"; + + case CURLSHE_NOT_BUILT_IN: + return "Feature not enabled in this library"; case CURLSHE_LAST: break; } - return "CURLSH unknown"; + return "CURLSHcode unknown"; #else - if (error == CURLSHE_OK) - return "no error"; + if(error == CURLSHE_OK) + return "No error"; else - return "error"; + return "Error"; #endif } @@ -409,7 +427,7 @@ get_winsock_error (int err, char *buf, size_t len) #ifndef CURL_DISABLE_VERBOSE_STRINGS switch (err) { case WSAEINTR: - p = "Call interrupted."; + p = "Call interrupted"; break; case WSAEBADF: p = "Bad file"; @@ -434,7 +452,7 @@ get_winsock_error (int err, char *buf, size_t len) p = "Blocking call in progress"; break; case WSAENOTSOCK: - p = "Descriptor is not a socket."; + p = "Descriptor is not a socket"; break; case WSAEDESTADDRREQ: p = "Need destination address"; @@ -548,7 +566,7 @@ get_winsock_error (int err, char *buf, size_t len) p = "Winsock library not initialised"; break; case WSAVERNOTSUPPORTED: - p = "Winsock version not supported."; + p = "Winsock version not supported"; break; /* getXbyY() errors (already handled in herrmsg): @@ -576,7 +594,7 @@ get_winsock_error (int err, char *buf, size_t len) return NULL; } #else - if (error == CURLE_OK) + if(err == CURLE_OK) return NULL; else p = "error"; @@ -592,7 +610,7 @@ get_winsock_error (int err, char *buf, size_t len) * * The 'err' argument passed in to this function MUST be a true errno number * as reported on this system. We do no range checking on the number before - * we pass it to the "number-to-message" convertion function and there might + * we pass it to the "number-to-message" conversion function and there might * be systems that don't do proper range checking in there themselves. * * We don't do range checking (on systems other than Windows) since there is @@ -602,9 +620,10 @@ const char *Curl_strerror(struct connectdata *conn, int err) { char *buf, *p; size_t max; + int old_errno = ERRNO; - curlassert(conn); - curlassert(err >= 0); + DEBUGASSERT(conn); + DEBUGASSERT(err >= 0); buf = conn->syserr_buf; max = sizeof(conn->syserr_buf)-1; @@ -613,64 +632,87 @@ const char *Curl_strerror(struct connectdata *conn, int err) #ifdef USE_WINSOCK #ifdef _WIN32_WCE - buf[0]=0; { wchar_t wbuf[256]; + wbuf[0] = L'\0'; FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, LANG_NEUTRAL, wbuf, sizeof(wbuf)/sizeof(wchar_t), NULL); wcstombs(buf,wbuf,max); } - #else - /* 'sys_nerr' is the maximum errno number, it is not widely portable */ - if (err >= 0 && err < sys_nerr) + if(err >= 0 && err < sys_nerr) strncpy(buf, strerror(err), max); else { - if (!get_winsock_error(err, buf, max) && - !FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, + if(!get_winsock_error(err, buf, max) && + !FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, LANG_NEUTRAL, buf, (DWORD)max, NULL)) snprintf(buf, max, "Unknown error %d (%#x)", err, err); } #endif + #else /* not USE_WINSOCK coming up */ - /* These should be atomic and hopefully thread-safe */ -#ifdef HAVE_STRERROR_R - /* There are two different APIs for strerror_r(). The POSIX and the GLIBC - versions. */ -#ifdef HAVE_POSIX_STRERROR_R - strerror_r(err, buf, max); - /* this may set errno to ERANGE if insufficient storage was supplied via - 'strerrbuf' and 'buflen' to contain the generated message string, or - EINVAL if the value of 'errnum' is not a valid error number.*/ -#else +#if defined(HAVE_STRERROR_R) && defined(HAVE_POSIX_STRERROR_R) + /* + * The POSIX-style strerror_r() may set errno to ERANGE if insufficient + * storage is supplied via 'strerrbuf' and 'buflen' to hold the generated + * message string, or EINVAL if 'errnum' is not a valid error number. + */ + if(0 != strerror_r(err, buf, max)) { + if('\0' == buf[0]) + snprintf(buf, max, "Unknown error %d", err); + } +#elif defined(HAVE_STRERROR_R) && defined(HAVE_GLIBC_STRERROR_R) + /* + * The glibc-style strerror_r() only *might* use the buffer we pass to + * the function, but it always returns the error message as a pointer, + * so we must copy that string unconditionally (if non-NULL). + */ { - /* HAVE_GLIBC_STRERROR_R */ char buffer[256]; char *msg = strerror_r(err, buffer, sizeof(buffer)); - /* this version of strerror_r() only *might* use the buffer we pass to - the function, but it always returns the error message as a pointer, - so we must copy that string unconditionally (if non-NULL) */ if(msg) strncpy(buf, msg, max); else snprintf(buf, max, "Unknown error %d", err); } -#endif /* end of HAVE_GLIBC_STRERROR_R */ -#else /* HAVE_STRERROR_R */ - strncpy(buf, strerror(err), max); -#endif /* end of HAVE_STRERROR_R */ +#elif defined(HAVE_STRERROR_R) && defined(HAVE_VXWORKS_STRERROR_R) + /* + * The vxworks-style strerror_r() does use the buffer we pass to the function. + * The buffer size should be at least NAME_MAX (256) + */ + { + char buffer[256]; + if(OK == strerror_r(err, buffer)) + strncpy(buf, buffer, max); + else + snprintf(buf, max, "Unknown error %d", err); + } +#else + { + char *msg = strerror(err); + if(msg) + strncpy(buf, msg, max); + else + snprintf(buf, max, "Unknown error %d", err); + } +#endif + #endif /* end of ! USE_WINSOCK */ buf[max] = '\0'; /* make sure the string is zero terminated */ /* strip trailing '\r\n' or '\n'. */ - if ((p = strrchr(buf,'\n')) != NULL && (p - buf) >= 2) + if((p = strrchr(buf,'\n')) != NULL && (p - buf) >= 2) *p = '\0'; - if ((p = strrchr(buf,'\r')) != NULL && (p - buf) >= 1) + if((p = strrchr(buf,'\r')) != NULL && (p - buf) >= 1) *p = '\0'; + + if(old_errno != ERRNO) + SET_ERRNO(old_errno); + return buf; } @@ -688,10 +730,11 @@ const char *Curl_idn_strerror (struct connectdata *conn, int err) char *buf; size_t max; - curlassert(conn); + DEBUGASSERT(conn); buf = conn->syserr_buf; max = sizeof(conn->syserr_buf)-1; + *buf = '\0'; #ifndef CURL_DISABLE_VERBOSE_STRINGS switch ((Idna_rc)err) { @@ -717,7 +760,7 @@ const char *Curl_idn_strerror (struct connectdata *conn, int err) str = "No ACE prefix (\"xn--\")"; break; case IDNA_ROUNDTRIP_VERIFY_ERROR: - str = "Roundtrip verify error"; + str = "Round trip verify error"; break; case IDNA_CONTAINS_ACE_PREFIX: str = "Already have ACE prefix (\"xn--\")"; @@ -732,20 +775,353 @@ const char *Curl_idn_strerror (struct connectdata *conn, int err) str = "dlopen() error"; break; default: - snprintf(buf, max, "error %d", (int)err); + snprintf(buf, max, "error %d", err); str = NULL; break; } #else - if ((Idna_rc)err == IDNA_SUCCESS) + if((Idna_rc)err == IDNA_SUCCESS) str = "No error"; else - str = "error"; + str = "Error"; #endif - if (str) + if(str) strncpy(buf, str, max); buf[max] = '\0'; return (buf); #endif } #endif /* USE_LIBIDN */ + +#ifdef USE_WINDOWS_SSPI +const char *Curl_sspi_strerror (struct connectdata *conn, int err) +{ +#ifndef CURL_DISABLE_VERBOSE_STRINGS + char txtbuf[80]; + char msgbuf[sizeof(conn->syserr_buf)]; + char *p, *str, *msg = NULL; + bool msg_formatted = FALSE; + int old_errno; +#endif + const char *txt; + char *outbuf; + size_t outmax; + + DEBUGASSERT(conn); + + outbuf = conn->syserr_buf; + outmax = sizeof(conn->syserr_buf)-1; + *outbuf = '\0'; + +#ifndef CURL_DISABLE_VERBOSE_STRINGS + + old_errno = ERRNO; + + switch (err) { + case SEC_E_OK: + txt = "No error"; + break; + case SEC_E_ALGORITHM_MISMATCH: + txt = "SEC_E_ALGORITHM_MISMATCH"; + break; + case SEC_E_BAD_BINDINGS: + txt = "SEC_E_BAD_BINDINGS"; + break; + case SEC_E_BAD_PKGID: + txt = "SEC_E_BAD_PKGID"; + break; + case SEC_E_BUFFER_TOO_SMALL: + txt = "SEC_E_BUFFER_TOO_SMALL"; + break; + case SEC_E_CANNOT_INSTALL: + txt = "SEC_E_CANNOT_INSTALL"; + break; + case SEC_E_CANNOT_PACK: + txt = "SEC_E_CANNOT_PACK"; + break; + case SEC_E_CERT_EXPIRED: + txt = "SEC_E_CERT_EXPIRED"; + break; + case SEC_E_CERT_UNKNOWN: + txt = "SEC_E_CERT_UNKNOWN"; + break; + case SEC_E_CERT_WRONG_USAGE: + txt = "SEC_E_CERT_WRONG_USAGE"; + break; + case SEC_E_CONTEXT_EXPIRED: + txt = "SEC_E_CONTEXT_EXPIRED"; + break; + case SEC_E_CROSSREALM_DELEGATION_FAILURE: + txt = "SEC_E_CROSSREALM_DELEGATION_FAILURE"; + break; + case SEC_E_CRYPTO_SYSTEM_INVALID: + txt = "SEC_E_CRYPTO_SYSTEM_INVALID"; + break; + case SEC_E_DECRYPT_FAILURE: + txt = "SEC_E_DECRYPT_FAILURE"; + break; + case SEC_E_DELEGATION_POLICY: + txt = "SEC_E_DELEGATION_POLICY"; + break; + case SEC_E_DELEGATION_REQUIRED: + txt = "SEC_E_DELEGATION_REQUIRED"; + break; + case SEC_E_DOWNGRADE_DETECTED: + txt = "SEC_E_DOWNGRADE_DETECTED"; + break; + case SEC_E_ENCRYPT_FAILURE: + txt = "SEC_E_ENCRYPT_FAILURE"; + break; + case SEC_E_ILLEGAL_MESSAGE: + txt = "SEC_E_ILLEGAL_MESSAGE"; + break; + case SEC_E_INCOMPLETE_CREDENTIALS: + txt = "SEC_E_INCOMPLETE_CREDENTIALS"; + break; + case SEC_E_INCOMPLETE_MESSAGE: + txt = "SEC_E_INCOMPLETE_MESSAGE"; + break; + case SEC_E_INSUFFICIENT_MEMORY: + txt = "SEC_E_INSUFFICIENT_MEMORY"; + break; + case SEC_E_INTERNAL_ERROR: + txt = "SEC_E_INTERNAL_ERROR"; + break; + case SEC_E_INVALID_HANDLE: + txt = "SEC_E_INVALID_HANDLE"; + break; + case SEC_E_INVALID_PARAMETER: + txt = "SEC_E_INVALID_PARAMETER"; + break; + case SEC_E_INVALID_TOKEN: + txt = "SEC_E_INVALID_TOKEN"; + break; + case SEC_E_ISSUING_CA_UNTRUSTED: + txt = "SEC_E_ISSUING_CA_UNTRUSTED"; + break; + case SEC_E_ISSUING_CA_UNTRUSTED_KDC: + txt = "SEC_E_ISSUING_CA_UNTRUSTED_KDC"; + break; + case SEC_E_KDC_CERT_EXPIRED: + txt = "SEC_E_KDC_CERT_EXPIRED"; + break; + case SEC_E_KDC_CERT_REVOKED: + txt = "SEC_E_KDC_CERT_REVOKED"; + break; + case SEC_E_KDC_INVALID_REQUEST: + txt = "SEC_E_KDC_INVALID_REQUEST"; + break; + case SEC_E_KDC_UNABLE_TO_REFER: + txt = "SEC_E_KDC_UNABLE_TO_REFER"; + break; + case SEC_E_KDC_UNKNOWN_ETYPE: + txt = "SEC_E_KDC_UNKNOWN_ETYPE"; + break; + case SEC_E_LOGON_DENIED: + txt = "SEC_E_LOGON_DENIED"; + break; + case SEC_E_MAX_REFERRALS_EXCEEDED: + txt = "SEC_E_MAX_REFERRALS_EXCEEDED"; + break; + case SEC_E_MESSAGE_ALTERED: + txt = "SEC_E_MESSAGE_ALTERED"; + break; + case SEC_E_MULTIPLE_ACCOUNTS: + txt = "SEC_E_MULTIPLE_ACCOUNTS"; + break; + case SEC_E_MUST_BE_KDC: + txt = "SEC_E_MUST_BE_KDC"; + break; + case SEC_E_NOT_OWNER: + txt = "SEC_E_NOT_OWNER"; + break; + case SEC_E_NO_AUTHENTICATING_AUTHORITY: + txt = "SEC_E_NO_AUTHENTICATING_AUTHORITY"; + break; + case SEC_E_NO_CREDENTIALS: + txt = "SEC_E_NO_CREDENTIALS"; + break; + case SEC_E_NO_IMPERSONATION: + txt = "SEC_E_NO_IMPERSONATION"; + break; + case SEC_E_NO_IP_ADDRESSES: + txt = "SEC_E_NO_IP_ADDRESSES"; + break; + case SEC_E_NO_KERB_KEY: + txt = "SEC_E_NO_KERB_KEY"; + break; + case SEC_E_NO_PA_DATA: + txt = "SEC_E_NO_PA_DATA"; + break; + case SEC_E_NO_S4U_PROT_SUPPORT: + txt = "SEC_E_NO_S4U_PROT_SUPPORT"; + break; + case SEC_E_NO_TGT_REPLY: + txt = "SEC_E_NO_TGT_REPLY"; + break; + case SEC_E_OUT_OF_SEQUENCE: + txt = "SEC_E_OUT_OF_SEQUENCE"; + break; + case SEC_E_PKINIT_CLIENT_FAILURE: + txt = "SEC_E_PKINIT_CLIENT_FAILURE"; + break; + case SEC_E_PKINIT_NAME_MISMATCH: + txt = "SEC_E_PKINIT_NAME_MISMATCH"; + break; + case SEC_E_POLICY_NLTM_ONLY: + txt = "SEC_E_POLICY_NLTM_ONLY"; + break; + case SEC_E_QOP_NOT_SUPPORTED: + txt = "SEC_E_QOP_NOT_SUPPORTED"; + break; + case SEC_E_REVOCATION_OFFLINE_C: + txt = "SEC_E_REVOCATION_OFFLINE_C"; + break; + case SEC_E_REVOCATION_OFFLINE_KDC: + txt = "SEC_E_REVOCATION_OFFLINE_KDC"; + break; + case SEC_E_SECPKG_NOT_FOUND: + txt = "SEC_E_SECPKG_NOT_FOUND"; + break; + case SEC_E_SECURITY_QOS_FAILED: + txt = "SEC_E_SECURITY_QOS_FAILED"; + break; + case SEC_E_SHUTDOWN_IN_PROGRESS: + txt = "SEC_E_SHUTDOWN_IN_PROGRESS"; + break; + case SEC_E_SMARTCARD_CERT_EXPIRED: + txt = "SEC_E_SMARTCARD_CERT_EXPIRED"; + break; + case SEC_E_SMARTCARD_CERT_REVOKED: + txt = "SEC_E_SMARTCARD_CERT_REVOKED"; + break; + case SEC_E_SMARTCARD_LOGON_REQUIRED: + txt = "SEC_E_SMARTCARD_LOGON_REQUIRED"; + break; + case SEC_E_STRONG_CRYPTO_NOT_SUPPORTED: + txt = "SEC_E_STRONG_CRYPTO_NOT_SUPPORTED"; + break; + case SEC_E_TARGET_UNKNOWN: + txt = "SEC_E_TARGET_UNKNOWN"; + break; + case SEC_E_TIME_SKEW: + txt = "SEC_E_TIME_SKEW"; + break; + case SEC_E_TOO_MANY_PRINCIPALS: + txt = "SEC_E_TOO_MANY_PRINCIPALS"; + break; + case SEC_E_UNFINISHED_CONTEXT_DELETED: + txt = "SEC_E_UNFINISHED_CONTEXT_DELETED"; + break; + case SEC_E_UNKNOWN_CREDENTIALS: + txt = "SEC_E_UNKNOWN_CREDENTIALS"; + break; + case SEC_E_UNSUPPORTED_FUNCTION: + txt = "SEC_E_UNSUPPORTED_FUNCTION"; + break; + case SEC_E_UNSUPPORTED_PREAUTH: + txt = "SEC_E_UNSUPPORTED_PREAUTH"; + break; + case SEC_E_UNTRUSTED_ROOT: + txt = "SEC_E_UNTRUSTED_ROOT"; + break; + case SEC_E_WRONG_CREDENTIAL_HANDLE: + txt = "SEC_E_WRONG_CREDENTIAL_HANDLE"; + break; + case SEC_E_WRONG_PRINCIPAL: + txt = "SEC_E_WRONG_PRINCIPAL"; + break; + case SEC_I_COMPLETE_AND_CONTINUE: + txt = "SEC_I_COMPLETE_AND_CONTINUE"; + break; + case SEC_I_COMPLETE_NEEDED: + txt = "SEC_I_COMPLETE_NEEDED"; + break; + case SEC_I_CONTEXT_EXPIRED: + txt = "SEC_I_CONTEXT_EXPIRED"; + break; + case SEC_I_CONTINUE_NEEDED: + txt = "SEC_I_CONTINUE_NEEDED"; + break; + case SEC_I_INCOMPLETE_CREDENTIALS: + txt = "SEC_I_INCOMPLETE_CREDENTIALS"; + break; + case SEC_I_LOCAL_LOGON: + txt = "SEC_I_LOCAL_LOGON"; + break; + case SEC_I_NO_LSA_CONTEXT: + txt = "SEC_I_NO_LSA_CONTEXT"; + break; + case SEC_I_RENEGOTIATE: + txt = "SEC_I_RENEGOTIATE"; + break; + case SEC_I_SIGNATURE_NEEDED: + txt = "SEC_I_SIGNATURE_NEEDED"; + break; + default: + txt = "Unknown error"; + } + + if(err == SEC_E_OK) + strncpy(outbuf, txt, outmax); + else { + str = txtbuf; + snprintf(txtbuf, sizeof(txtbuf), "%s (0x%04X%04X)", + txt, (err >> 16) & 0xffff, err & 0xffff); + txtbuf[sizeof(txtbuf)-1] = '\0'; + +#ifdef _WIN32_WCE + { + wchar_t wbuf[256]; + wbuf[0] = L'\0'; + + if(FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, err, LANG_NEUTRAL, + wbuf, sizeof(wbuf)/sizeof(wchar_t), NULL)) { + wcstombs(msgbuf,wbuf,sizeof(msgbuf)-1); + msg_formatted = TRUE; + } + } +#else + if(FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, err, LANG_NEUTRAL, + msgbuf, sizeof(msgbuf)-1, NULL)) { + msg_formatted = TRUE; + } +#endif + if(msg_formatted) { + msgbuf[sizeof(msgbuf)-1] = '\0'; + /* strip trailing '\r\n' or '\n' */ + if((p = strrchr(msgbuf,'\n')) != NULL && (p - msgbuf) >= 2) + *p = '\0'; + if((p = strrchr(msgbuf,'\r')) != NULL && (p - msgbuf) >= 1) + *p = '\0'; + msg = msgbuf; + } + if(msg) + snprintf(outbuf, outmax, "%s - %s", str, msg); + else + strncpy(outbuf, str, outmax); + } + + if(old_errno != ERRNO) + SET_ERRNO(old_errno); + +#else + + if(err == SEC_E_OK) + txt = "No error"; + else + txt = "Error"; + + strncpy(outbuf, txt, outmax); + +#endif + + outbuf[outmax] = '\0'; + + return outbuf; +} +#endif /* USE_WINDOWS_SSPI */ |