1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 2004 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
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 http://curl.haxx.se/docs/copyright.html.
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.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 * $Id: strerror.c,v 1.1.1.1 2008-09-23 16:32:05 hoffman Exp $
22 ***************************************************************************/
26 #ifdef HAVE_STRERROR_R
27 #if !defined(HAVE_POSIX_STRERROR_R) && !defined(HAVE_GLIBC_STRERROR_R)
28 #error "you MUST have either POSIX or glibc strerror_r if strerror_r is found"
29 #endif /* !POSIX && !glibc */
30 #endif /* HAVE_STRERROR_R */
32 #include <curl/curl.h>
43 #define _MPRINTF_REPLACE /* use our functions only */
44 #include <curl/mprintf.h>
46 #if defined(HAVE_STRERROR_R) && defined(HAVE_NO_STRERROR_R_DECL)
47 #ifdef HAVE_POSIX_STRERROR_R
48 /* seen on AIX 5100-02 gcc 2.9 */
49 extern int strerror_r(int errnum
, char *strerrbuf
, size_t buflen
);
51 extern char *strerror_r(int errnum
, char *buf
, size_t buflen
);
56 curl_easy_strerror(CURLcode error
)
58 #ifndef CURL_DISABLE_VERBOSE_STRINGS
63 case CURLE_UNSUPPORTED_PROTOCOL
:
64 return "Unsupported protocol";
66 case CURLE_FAILED_INIT
:
67 return "Failed initialization";
69 case CURLE_URL_MALFORMAT
:
70 return "URL using bad/illegal format or missing URL";
72 case CURLE_COULDNT_RESOLVE_PROXY
:
73 return "Couldn't resolve proxy name";
75 case CURLE_COULDNT_RESOLVE_HOST
:
76 return "Couldn't resolve host name";
78 case CURLE_COULDNT_CONNECT
:
79 return "Couldn't connect to server";
81 case CURLE_FTP_WEIRD_SERVER_REPLY
:
82 return "FTP: weird server reply";
84 case CURLE_REMOTE_ACCESS_DENIED
:
85 return "Access denied to remote resource";
87 case CURLE_FTP_WEIRD_PASS_REPLY
:
88 return "FTP: unknown PASS reply";
90 case CURLE_FTP_WEIRD_PASV_REPLY
:
91 return "FTP: unknown PASV reply";
93 case CURLE_FTP_WEIRD_227_FORMAT
:
94 return "FTP: unknown 227 response format";
96 case CURLE_FTP_CANT_GET_HOST
:
97 return "FTP: can't figure out the host in the PASV response";
99 case CURLE_FTP_COULDNT_SET_TYPE
:
100 return "FTP: couldn't set file type";
102 case CURLE_PARTIAL_FILE
:
103 return "Transferred a partial file";
105 case CURLE_FTP_COULDNT_RETR_FILE
:
106 return "FTP: couldn't retrieve (RETR failed) the specified file";
108 case CURLE_QUOTE_ERROR
:
109 return "Quote command returned error";
111 case CURLE_HTTP_RETURNED_ERROR
:
112 return "HTTP response code said error";
114 case CURLE_WRITE_ERROR
:
115 return "Failed writing received data to disk/application";
117 case CURLE_UPLOAD_FAILED
:
118 return "Upload failed (at start/before it took off)";
120 case CURLE_READ_ERROR
:
121 return "Failed to open/read local data from file/application";
123 case CURLE_OUT_OF_MEMORY
:
124 return "Out of memory";
126 case CURLE_OPERATION_TIMEDOUT
:
127 return "Timeout was reached";
129 case CURLE_FTP_PORT_FAILED
:
130 return "FTP: command PORT failed";
132 case CURLE_FTP_COULDNT_USE_REST
:
133 return "FTP: command REST failed";
135 case CURLE_RANGE_ERROR
:
136 return "Requested range was not delivered by the server";
138 case CURLE_HTTP_POST_ERROR
:
139 return "Internal problem setting up the POST";
141 case CURLE_SSL_CONNECT_ERROR
:
142 return "SSL connect error";
144 case CURLE_BAD_DOWNLOAD_RESUME
:
145 return "Couldn't resume download";
147 case CURLE_FILE_COULDNT_READ_FILE
:
148 return "Couldn't read a file:// file";
150 case CURLE_LDAP_CANNOT_BIND
:
151 return "LDAP: cannot bind";
153 case CURLE_LDAP_SEARCH_FAILED
:
154 return "LDAP: search failed";
156 case CURLE_FUNCTION_NOT_FOUND
:
157 return "A required function in the library was not found";
159 case CURLE_ABORTED_BY_CALLBACK
:
160 return "Operation was aborted by an application callback";
162 case CURLE_BAD_FUNCTION_ARGUMENT
:
163 return "A libcurl function was given a bad argument";
165 case CURLE_INTERFACE_FAILED
:
166 return "Failed binding local connection end";
168 case CURLE_TOO_MANY_REDIRECTS
:
169 return "Number of redirects hit maximum amount";
171 case CURLE_UNKNOWN_TELNET_OPTION
:
172 return "User specified an unknown telnet option";
174 case CURLE_TELNET_OPTION_SYNTAX
:
175 return "Malformed telnet option";
177 case CURLE_PEER_FAILED_VERIFICATION
:
178 return "SSL peer certificate or SSH md5 fingerprint was not OK";
180 case CURLE_GOT_NOTHING
:
181 return "Server returned nothing (no headers, no data)";
183 case CURLE_SSL_ENGINE_NOTFOUND
:
184 return "SSL crypto engine not found";
186 case CURLE_SSL_ENGINE_SETFAILED
:
187 return "Can not set SSL crypto engine as default";
189 case CURLE_SSL_ENGINE_INITFAILED
:
190 return "Failed to initialise SSL crypto engine";
192 case CURLE_SEND_ERROR
:
193 return "Failed sending data to the peer";
195 case CURLE_RECV_ERROR
:
196 return "Failure when receiving data from the peer";
198 case CURLE_SSL_CERTPROBLEM
:
199 return "Problem with the local SSL certificate";
201 case CURLE_SSL_CIPHER
:
202 return "Couldn't use specified SSL cipher";
204 case CURLE_SSL_CACERT
:
205 return "Peer certificate cannot be authenticated with known CA certificates";
207 case CURLE_SSL_CACERT_BADFILE
:
208 return "Problem with the SSL CA cert (path? access rights?)";
210 case CURLE_BAD_CONTENT_ENCODING
:
211 return "Unrecognized HTTP Content-Encoding";
213 case CURLE_LDAP_INVALID_URL
:
214 return "Invalid LDAP URL";
216 case CURLE_FILESIZE_EXCEEDED
:
217 return "Maximum file size exceeded";
219 case CURLE_USE_SSL_FAILED
:
220 return "Requested SSL level failed";
222 case CURLE_SSL_SHUTDOWN_FAILED
:
223 return "Failed to shut down the SSL connection";
225 case CURLE_SSL_CRL_BADFILE
:
226 return "Failed to load CRL file (path? access rights?, format?)";
228 case CURLE_SSL_ISSUER_ERROR
:
229 return "Issuer check against peer certificate failed";
231 case CURLE_SEND_FAIL_REWIND
:
232 return "Send failed since rewinding of the data stream failed";
234 case CURLE_LOGIN_DENIED
:
235 return "Login denied";
237 case CURLE_TFTP_NOTFOUND
:
238 return "TFTP: File Not Found";
240 case CURLE_TFTP_PERM
:
241 return "TFTP: Access Violation";
243 case CURLE_REMOTE_DISK_FULL
:
244 return "Disk full or allocation exceeded";
246 case CURLE_TFTP_ILLEGAL
:
247 return "TFTP: Illegal operation";
249 case CURLE_TFTP_UNKNOWNID
:
250 return "TFTP: Unknown transfer ID";
252 case CURLE_REMOTE_FILE_EXISTS
:
253 return "Remote file already exists";
255 case CURLE_TFTP_NOSUCHUSER
:
256 return "TFTP: No such user";
258 case CURLE_CONV_FAILED
:
259 return "Conversion failed";
261 case CURLE_CONV_REQD
:
262 return "Caller must register CURLOPT_CONV_ callback options";
264 case CURLE_REMOTE_FILE_NOT_FOUND
:
265 return "Remote file not found";
268 return "Error in the SSH layer";
271 return "Socket not ready for send/recv";
273 /* error codes not used by current libcurl */
274 case CURLE_OBSOLETE4
:
275 case CURLE_OBSOLETE10
:
276 case CURLE_OBSOLETE12
:
277 case CURLE_OBSOLETE16
:
278 case CURLE_OBSOLETE20
:
279 case CURLE_OBSOLETE24
:
280 case CURLE_OBSOLETE29
:
281 case CURLE_OBSOLETE32
:
282 case CURLE_OBSOLETE40
:
283 case CURLE_OBSOLETE44
:
284 case CURLE_OBSOLETE46
:
285 case CURLE_OBSOLETE50
:
286 case CURLE_OBSOLETE57
:
291 * By using a switch, gcc -Wall will complain about enum values
292 * which do not appear, helping keep this function up-to-date.
293 * By using gcc -Wall -Werror, you can't forget.
295 * A table would not have the same benefit. Most compilers will
296 * generate code very similar to a table in any case, so there
297 * is little performance gain from a table. And something is broken
298 * for the user's application, anyways, so does it matter how fast
301 * The line number for the error will be near this comment, which
302 * is why it is here, and not at the start of the switch.
304 return "Unknown error";
306 if(error
== CURLE_OK
)
314 curl_multi_strerror(CURLMcode error
)
316 #ifndef CURL_DISABLE_VERBOSE_STRINGS
318 case CURLM_CALL_MULTI_PERFORM
:
319 return "Please call curl_multi_perform() soon";
324 case CURLM_BAD_HANDLE
:
325 return "Invalid multi handle";
327 case CURLM_BAD_EASY_HANDLE
:
328 return "Invalid easy handle";
330 case CURLM_OUT_OF_MEMORY
:
331 return "Out of memory";
333 case CURLM_INTERNAL_ERROR
:
334 return "Internal error";
336 case CURLM_BAD_SOCKET
:
337 return "Invalid socket argument";
339 case CURLM_UNKNOWN_OPTION
:
340 return "Unknown option";
346 return "Unknown error";
348 if(error
== CURLM_OK
)
356 curl_share_strerror(CURLSHcode error
)
358 #ifndef CURL_DISABLE_VERBOSE_STRINGS
363 case CURLSHE_BAD_OPTION
:
364 return "Unknown share option";
367 return "Share currently in use";
369 case CURLSHE_INVALID
:
370 return "Invalid share handle";
373 return "Out of memory";
379 return "CURLSHcode unknown";
381 if(error
== CURLSHE_OK
)
390 /* This function handles most / all (?) Winsock errors cURL is able to produce.
393 get_winsock_error (int err
, char *buf
, size_t len
)
397 #ifndef CURL_DISABLE_VERBOSE_STRINGS
400 p
= "Call interrupted";
412 p
= "Invalid arguments";
415 p
= "Out of file descriptors";
418 p
= "Call would block";
422 p
= "Blocking call in progress";
425 p
= "Descriptor is not a socket";
427 case WSAEDESTADDRREQ
:
428 p
= "Need destination address";
431 p
= "Bad message size";
437 p
= "Protocol option is unsupported";
439 case WSAEPROTONOSUPPORT
:
440 p
= "Protocol is unsupported";
442 case WSAESOCKTNOSUPPORT
:
443 p
= "Socket is unsupported";
446 p
= "Operation not supported";
448 case WSAEAFNOSUPPORT
:
449 p
= "Address family not supported";
451 case WSAEPFNOSUPPORT
:
452 p
= "Protocol family not supported";
455 p
= "Address already in use";
457 case WSAEADDRNOTAVAIL
:
458 p
= "Address not available";
464 p
= "Network unreachable";
467 p
= "Network has been reset";
469 case WSAECONNABORTED
:
470 p
= "Connection was aborted";
473 p
= "Connection was reset";
476 p
= "No buffer space";
479 p
= "Socket is already connected";
482 p
= "Socket is not connected";
485 p
= "Socket has been shut down";
487 case WSAETOOMANYREFS
:
488 p
= "Too many references";
493 case WSAECONNREFUSED
:
494 p
= "Connection refused";
499 case WSAENAMETOOLONG
:
505 case WSAEHOSTUNREACH
:
506 p
= "Host unreachable";
512 p
= "Process limit reached";
515 p
= "Too many users";
521 p
= "Something is stale";
526 #ifdef WSAEDISCON /* missing in SalfordC! */
531 /* Extended Winsock errors */
533 p
= "Winsock library is not ready";
535 case WSANOTINITIALISED
:
536 p
= "Winsock library not initialised";
538 case WSAVERNOTSUPPORTED
:
539 p
= "Winsock version not supported";
542 /* getXbyY() errors (already handled in herrmsg):
543 * Authoritative Answer: Host not found */
544 case WSAHOST_NOT_FOUND
:
545 p
= "Host not found";
548 /* Non-Authoritative: Host not found, or SERVERFAIL */
550 p
= "Host not found, try again";
553 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
555 p
= "Unrecoverable error in call to nameserver";
558 /* Valid name, no data record of requested type */
560 p
= "No data record of requested type";
572 strncpy (buf
, p
, len
);
576 #endif /* USE_WINSOCK */
579 * Our thread-safe and smart strerror() replacement.
581 * The 'err' argument passed in to this function MUST be a true errno number
582 * as reported on this system. We do no range checking on the number before
583 * we pass it to the "number-to-message" conversion function and there might
584 * be systems that don't do proper range checking in there themselves.
586 * We don't do range checking (on systems other than Windows) since there is
587 * no good reliable and portable way to do it.
589 const char *Curl_strerror(struct connectdata
*conn
, int err
)
595 DEBUGASSERT(err
>= 0);
597 buf
= conn
->syserr_buf
;
598 max
= sizeof(conn
->syserr_buf
)-1;
608 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
, NULL
, err
,
609 LANG_NEUTRAL
, wbuf
, sizeof(wbuf
)/sizeof(wchar_t), NULL
);
610 wcstombs(buf
,wbuf
,max
);
615 /* 'sys_nerr' is the maximum errno number, it is not widely portable */
616 if(err
>= 0 && err
< sys_nerr
)
617 strncpy(buf
, strerror(err
), max
);
619 if(!get_winsock_error(err
, buf
, max
) &&
620 !FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
, NULL
, err
,
621 LANG_NEUTRAL
, buf
, (DWORD
)max
, NULL
))
622 snprintf(buf
, max
, "Unknown error %d (%#x)", err
, err
);
625 #else /* not USE_WINSOCK coming up */
627 /* These should be atomic and hopefully thread-safe */
628 #ifdef HAVE_STRERROR_R
629 /* There are two different APIs for strerror_r(). The POSIX and the GLIBC
631 #ifdef HAVE_POSIX_STRERROR_R
632 strerror_r(err
, buf
, max
);
633 /* this may set errno to ERANGE if insufficient storage was supplied via
634 'strerrbuf' and 'buflen' to contain the generated message string, or
635 EINVAL if the value of 'errnum' is not a valid error number.*/
638 /* HAVE_GLIBC_STRERROR_R */
640 char *msg
= strerror_r(err
, buffer
, sizeof(buffer
));
641 /* this version of strerror_r() only *might* use the buffer we pass to
642 the function, but it always returns the error message as a pointer,
643 so we must copy that string unconditionally (if non-NULL) */
645 strncpy(buf
, msg
, max
);
647 snprintf(buf
, max
, "Unknown error %d", err
);
649 #endif /* end of HAVE_GLIBC_STRERROR_R */
650 #else /* HAVE_STRERROR_R */
651 strncpy(buf
, strerror(err
), max
);
652 #endif /* end of HAVE_STRERROR_R */
653 #endif /* end of ! USE_WINSOCK */
655 buf
[max
] = '\0'; /* make sure the string is zero terminated */
657 /* strip trailing '\r\n' or '\n'. */
658 if((p
= strrchr(buf
,'\n')) != NULL
&& (p
- buf
) >= 2)
660 if((p
= strrchr(buf
,'\r')) != NULL
&& (p
- buf
) >= 1)
667 * Return error-string for libidn status as returned from idna_to_ascii_lz().
669 const char *Curl_idn_strerror (struct connectdata
*conn
, int err
)
671 #ifdef HAVE_IDNA_STRERROR
673 return idna_strerror((Idna_rc
) err
);
681 buf
= conn
->syserr_buf
;
682 max
= sizeof(conn
->syserr_buf
)-1;
684 #ifndef CURL_DISABLE_VERBOSE_STRINGS
685 switch ((Idna_rc
)err
) {
689 case IDNA_STRINGPREP_ERROR
:
690 str
= "Error in string preparation";
692 case IDNA_PUNYCODE_ERROR
:
693 str
= "Error in Punycode operation";
695 case IDNA_CONTAINS_NON_LDH
:
696 str
= "Illegal ASCII characters";
698 case IDNA_CONTAINS_MINUS
:
699 str
= "Contains minus";
701 case IDNA_INVALID_LENGTH
:
702 str
= "Invalid output length";
704 case IDNA_NO_ACE_PREFIX
:
705 str
= "No ACE prefix (\"xn--\")";
707 case IDNA_ROUNDTRIP_VERIFY_ERROR
:
708 str
= "Round trip verify error";
710 case IDNA_CONTAINS_ACE_PREFIX
:
711 str
= "Already have ACE prefix (\"xn--\")";
713 case IDNA_ICONV_ERROR
:
714 str
= "Locale conversion failed";
716 case IDNA_MALLOC_ERROR
:
717 str
= "Allocation failed";
719 case IDNA_DLOPEN_ERROR
:
720 str
= "dlopen() error";
723 snprintf(buf
, max
, "error %d", (int)err
);
728 if((Idna_rc
)err
== IDNA_SUCCESS
)
734 strncpy(buf
, str
, max
);
739 #endif /* USE_LIBIDN */