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.2 2007/03/15 19:22:13 andy 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
:
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_FTP_ACCESS_DENIED
:
85 return "FTP: access denied";
87 case CURLE_FTP_WEIRD_PASS_REPLY
:
88 return "FTP: unknown PASS reply";
90 case CURLE_FTP_WEIRD_USER_REPLY
:
91 return "FTP: unknown USER reply";
93 case CURLE_FTP_WEIRD_PASV_REPLY
:
94 return "FTP: unknown PASV reply";
96 case CURLE_FTP_WEIRD_227_FORMAT
:
97 return "FTP: unknown 227 response format";
99 case CURLE_FTP_CANT_GET_HOST
:
100 return "FTP: can't figure out the host in the PASV response";
102 case CURLE_FTP_CANT_RECONNECT
:
103 return "FTP: can't connect to server the response code is unknown";
105 case CURLE_FTP_COULDNT_SET_BINARY
:
106 return "FTP: couldn't set binary mode";
108 case CURLE_PARTIAL_FILE
:
109 return "Transferred a partial file";
111 case CURLE_FTP_COULDNT_RETR_FILE
:
112 return "FTP: couldn't retrieve (RETR failed) the specified file";
114 case CURLE_FTP_WRITE_ERROR
:
115 return "FTP: the post-transfer acknowledge response was not OK";
117 case CURLE_FTP_QUOTE_ERROR
:
118 return "FTP: a quote command returned error";
120 case CURLE_HTTP_RETURNED_ERROR
:
121 return "HTTP response code said error";
123 case CURLE_WRITE_ERROR
:
124 return "failed writing received data to disk/application";
126 case CURLE_FTP_COULDNT_STOR_FILE
:
127 return "failed FTP upload (the STOR command)";
129 case CURLE_READ_ERROR
:
130 return "failed to open/read local data from file/application";
132 case CURLE_OUT_OF_MEMORY
:
133 #ifdef CURL_DOES_CONVERSIONS
134 return "conversion failed -or- out of memory";
136 return "out of memory";
137 #endif /* CURL_DOES_CONVERSIONS */
139 case CURLE_OPERATION_TIMEOUTED
:
140 return "a timeout was reached";
142 case CURLE_FTP_COULDNT_SET_ASCII
:
143 return "FTP could not set ASCII mode (TYPE A)";
145 case CURLE_FTP_PORT_FAILED
:
146 return "FTP command PORT failed";
148 case CURLE_FTP_COULDNT_USE_REST
:
149 return "FTP command REST failed";
151 case CURLE_FTP_COULDNT_GET_SIZE
:
152 return "FTP command SIZE failed";
154 case CURLE_HTTP_RANGE_ERROR
:
155 return "a range was requested but the server did not deliver it";
157 case CURLE_HTTP_POST_ERROR
:
158 return "internal problem setting up the POST";
160 case CURLE_SSL_CONNECT_ERROR
:
161 return "SSL connect error";
163 case CURLE_BAD_DOWNLOAD_RESUME
:
164 return "couldn't resume download";
166 case CURLE_FILE_COULDNT_READ_FILE
:
167 return "couldn't read a file:// file";
169 case CURLE_LDAP_CANNOT_BIND
:
170 return "LDAP: cannot bind";
172 case CURLE_LDAP_SEARCH_FAILED
:
173 return "LDAP: search failed";
175 case CURLE_LIBRARY_NOT_FOUND
:
176 return "a required shared library was not found";
178 case CURLE_FUNCTION_NOT_FOUND
:
179 return "a required function in the shared library was not found";
181 case CURLE_ABORTED_BY_CALLBACK
:
182 return "the operation was aborted by an application callback";
184 case CURLE_BAD_FUNCTION_ARGUMENT
:
185 return "a libcurl function was given a bad argument";
187 case CURLE_INTERFACE_FAILED
:
188 return "failed binding local connection end";
190 case CURLE_TOO_MANY_REDIRECTS
:
191 return "number of redirects hit maximum amount";
193 case CURLE_UNKNOWN_TELNET_OPTION
:
194 return "User specified an unknown option";
196 case CURLE_TELNET_OPTION_SYNTAX
:
197 return "Malformed telnet option";
199 case CURLE_SSL_PEER_CERTIFICATE
:
200 return "SSL peer certificate was not ok";
202 case CURLE_GOT_NOTHING
:
203 return "server returned nothing (no headers, no data)";
205 case CURLE_SSL_ENGINE_NOTFOUND
:
206 return "SSL crypto engine not found";
208 case CURLE_SSL_ENGINE_SETFAILED
:
209 return "can not set SSL crypto engine as default";
211 case CURLE_SSL_ENGINE_INITFAILED
:
212 return "failed to initialise SSL crypto engine";
214 case CURLE_SEND_ERROR
:
215 return "failed sending data to the peer";
217 case CURLE_RECV_ERROR
:
218 return "failure when receiving data from the peer";
220 case CURLE_SHARE_IN_USE
:
221 return "share is already in use";
223 case CURLE_SSL_CERTPROBLEM
:
224 return "problem with the local SSL certificate";
226 case CURLE_SSL_CIPHER
:
227 return "couldn't use specified SSL cipher";
229 case CURLE_SSL_CACERT
:
230 return "peer certificate cannot be authenticated with known CA certificates";
232 case CURLE_SSL_CACERT_BADFILE
:
233 return "problem with the SSL CA cert (path? access rights?)";
235 case CURLE_BAD_CONTENT_ENCODING
:
236 return "Unrecognized HTTP Content-Encoding";
238 case CURLE_LDAP_INVALID_URL
:
239 return "Invalid LDAP URL";
241 case CURLE_FILESIZE_EXCEEDED
:
242 return "Maximum file size exceeded";
244 case CURLE_FTP_SSL_FAILED
:
245 return "Requested FTP SSL level failed";
247 case CURLE_SSL_SHUTDOWN_FAILED
:
248 return "Failed to shut down the SSL connection";
250 case CURLE_SEND_FAIL_REWIND
:
251 return "Send failed since rewinding of the data stream failed";
253 case CURLE_LOGIN_DENIED
:
254 return "FTP: login denied";
256 case CURLE_TFTP_NOTFOUND
:
257 return "TFTP: File Not Found";
259 case CURLE_TFTP_PERM
:
260 return "TFTP: Access Violation";
262 case CURLE_TFTP_DISKFULL
:
263 return "TFTP: Disk full or allocation exceeded";
265 case CURLE_TFTP_ILLEGAL
:
266 return "TFTP: Illegal operation";
268 case CURLE_TFTP_UNKNOWNID
:
269 return "TFTP: Unknown transfer ID";
271 case CURLE_TFTP_EXISTS
:
272 return "TFTP: File already exists";
274 case CURLE_TFTP_NOSUCHUSER
:
275 return "TFTP: No such user";
277 case CURLE_CONV_FAILED
:
278 return "conversion failed";
280 case CURLE_CONV_REQD
:
281 return "caller must register CURLOPT_CONV_ callback options";
283 case CURLE_REMOTE_FILE_NOT_FOUND
:
284 return "Remote file not found";
287 return "Error in the SSH layer";
289 /* error codes not used by current libcurl */
290 case CURLE_URL_MALFORMAT_USER
:
291 case CURLE_FTP_USER_PASSWORD_INCORRECT
:
292 case CURLE_MALFORMAT_USER
:
293 case CURLE_BAD_CALLING_ORDER
:
294 case CURLE_BAD_PASSWORD_ENTERED
:
300 * By using a switch, gcc -Wall will complain about enum values
301 * which do not appear, helping keep this function up-to-date.
302 * By using gcc -Wall -Werror, you can't forget.
304 * A table would not have the same benefit. Most compilers will
305 * generate code very similar to a table in any case, so there
306 * is little performance gain from a table. And something is broken
307 * for the user's application, anyways, so does it matter how fast
310 * The line number for the error will be near this comment, which
311 * is why it is here, and not at the start of the switch.
313 return "unknown error";
315 if (error
== CURLE_OK
)
323 curl_multi_strerror(CURLMcode error
)
325 #ifndef CURL_DISABLE_VERBOSE_STRINGS
327 case CURLM_CALL_MULTI_PERFORM
:
328 return "please call curl_multi_perform() soon";
333 case CURLM_BAD_HANDLE
:
334 return "invalid multi handle";
336 case CURLM_BAD_EASY_HANDLE
:
337 return "invalid easy handle";
339 case CURLM_OUT_OF_MEMORY
:
340 return "out of memory";
342 case CURLM_INTERNAL_ERROR
:
343 return "internal error";
345 case CURLM_BAD_SOCKET
:
346 return "invalid socket argument";
348 case CURLM_UNKNOWN_OPTION
:
349 return "unknown option";
355 return "unknown error";
357 if (error
== CURLM_OK
)
365 curl_share_strerror(CURLSHcode error
)
367 #ifndef CURL_DISABLE_VERBOSE_STRINGS
372 case CURLSHE_BAD_OPTION
:
373 return "unknown share option";
376 return "share currently in use";
378 case CURLSHE_INVALID
:
379 return "invalid share handle";
382 return "out of memory";
388 return "CURLSH unknown";
390 if (error
== CURLSHE_OK
)
399 /* This function handles most / all (?) Winsock errors cURL is able to produce.
402 get_winsock_error (int err
, char *buf
, size_t len
)
406 #ifndef CURL_DISABLE_VERBOSE_STRINGS
409 p
= "Call interrupted.";
421 p
= "Invalid arguments";
424 p
= "Out of file descriptors";
427 p
= "Call would block";
431 p
= "Blocking call in progress";
434 p
= "Descriptor is not a socket.";
436 case WSAEDESTADDRREQ
:
437 p
= "Need destination address";
440 p
= "Bad message size";
446 p
= "Protocol option is unsupported";
448 case WSAEPROTONOSUPPORT
:
449 p
= "Protocol is unsupported";
451 case WSAESOCKTNOSUPPORT
:
452 p
= "Socket is unsupported";
455 p
= "Operation not supported";
457 case WSAEAFNOSUPPORT
:
458 p
= "Address family not supported";
460 case WSAEPFNOSUPPORT
:
461 p
= "Protocol family not supported";
464 p
= "Address already in use";
466 case WSAEADDRNOTAVAIL
:
467 p
= "Address not available";
473 p
= "Network unreachable";
476 p
= "Network has been reset";
478 case WSAECONNABORTED
:
479 p
= "Connection was aborted";
482 p
= "Connection was reset";
485 p
= "No buffer space";
488 p
= "Socket is already connected";
491 p
= "Socket is not connected";
494 p
= "Socket has been shut down";
496 case WSAETOOMANYREFS
:
497 p
= "Too many references";
502 case WSAECONNREFUSED
:
503 p
= "Connection refused";
508 case WSAENAMETOOLONG
:
514 case WSAEHOSTUNREACH
:
515 p
= "Host unreachable";
521 p
= "Process limit reached";
524 p
= "Too many users";
530 p
= "Something is stale";
535 #ifdef WSAEDISCON /* missing in SalfordC! */
540 /* Extended Winsock errors */
542 p
= "Winsock library is not ready";
544 case WSANOTINITIALISED
:
545 p
= "Winsock library not initialised";
547 case WSAVERNOTSUPPORTED
:
548 p
= "Winsock version not supported.";
551 /* getXbyY() errors (already handled in herrmsg):
552 * Authoritative Answer: Host not found */
553 case WSAHOST_NOT_FOUND
:
554 p
= "Host not found";
557 /* Non-Authoritative: Host not found, or SERVERFAIL */
559 p
= "Host not found, try again";
562 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
564 p
= "Unrecoverable error in call to nameserver";
567 /* Valid name, no data record of requested type */
569 p
= "No data record of requested type";
576 if (error
== CURLE_OK
)
581 strncpy (buf
, p
, len
);
585 #endif /* USE_WINSOCK */
588 * Our thread-safe and smart strerror() replacement.
590 * The 'err' argument passed in to this function MUST be a true errno number
591 * as reported on this system. We do no range checking on the number before
592 * we pass it to the "number-to-message" convertion function and there might
593 * be systems that don't do proper range checking in there themselves.
595 * We don't do range checking (on systems other than Windows) since there is
596 * no good reliable and portable way to do it.
598 const char *Curl_strerror(struct connectdata
*conn
, int err
)
604 curlassert(err
>= 0);
606 buf
= conn
->syserr_buf
;
607 max
= sizeof(conn
->syserr_buf
)-1;
617 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
, NULL
, err
,
618 LANG_NEUTRAL
, wbuf
, sizeof(wbuf
)/sizeof(wchar_t), NULL
);
619 wcstombs(buf
,wbuf
,max
);
624 /* 'sys_nerr' is the maximum errno number, it is not widely portable */
625 if (err
>= 0 && err
< sys_nerr
)
626 strncpy(buf
, strerror(err
), max
);
628 if (!get_winsock_error(err
, buf
, max
) &&
629 !FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
, NULL
, err
,
630 LANG_NEUTRAL
, buf
, (DWORD
)max
, NULL
))
631 snprintf(buf
, max
, "Unknown error %d (%#x)", err
, err
);
634 #else /* not USE_WINSOCK coming up */
636 /* These should be atomic and hopefully thread-safe */
637 #ifdef HAVE_STRERROR_R
638 /* There are two different APIs for strerror_r(). The POSIX and the GLIBC
640 #ifdef HAVE_POSIX_STRERROR_R
641 strerror_r(err
, buf
, max
);
642 /* this may set errno to ERANGE if insufficient storage was supplied via
643 'strerrbuf' and 'buflen' to contain the generated message string, or
644 EINVAL if the value of 'errnum' is not a valid error number.*/
647 /* HAVE_GLIBC_STRERROR_R */
649 char *msg
= strerror_r(err
, buffer
, sizeof(buffer
));
650 /* this version of strerror_r() only *might* use the buffer we pass to
651 the function, but it always returns the error message as a pointer,
652 so we must copy that string unconditionally (if non-NULL) */
654 strncpy(buf
, msg
, max
);
656 snprintf(buf
, max
, "Unknown error %d", err
);
658 #endif /* end of HAVE_GLIBC_STRERROR_R */
659 #else /* HAVE_STRERROR_R */
660 strncpy(buf
, strerror(err
), max
);
661 #endif /* end of HAVE_STRERROR_R */
662 #endif /* end of ! USE_WINSOCK */
664 buf
[max
] = '\0'; /* make sure the string is zero terminated */
666 /* strip trailing '\r\n' or '\n'. */
667 if ((p
= strrchr(buf
,'\n')) != NULL
&& (p
- buf
) >= 2)
669 if ((p
= strrchr(buf
,'\r')) != NULL
&& (p
- buf
) >= 1)
676 * Return error-string for libidn status as returned from idna_to_ascii_lz().
678 const char *Curl_idn_strerror (struct connectdata
*conn
, int err
)
680 #ifdef HAVE_IDNA_STRERROR
682 return idna_strerror((Idna_rc
) err
);
690 buf
= conn
->syserr_buf
;
691 max
= sizeof(conn
->syserr_buf
)-1;
693 #ifndef CURL_DISABLE_VERBOSE_STRINGS
694 switch ((Idna_rc
)err
) {
698 case IDNA_STRINGPREP_ERROR
:
699 str
= "Error in string preparation";
701 case IDNA_PUNYCODE_ERROR
:
702 str
= "Error in Punycode operation";
704 case IDNA_CONTAINS_NON_LDH
:
705 str
= "Illegal ASCII characters";
707 case IDNA_CONTAINS_MINUS
:
708 str
= "Contains minus";
710 case IDNA_INVALID_LENGTH
:
711 str
= "Invalid output length";
713 case IDNA_NO_ACE_PREFIX
:
714 str
= "No ACE prefix (\"xn--\")";
716 case IDNA_ROUNDTRIP_VERIFY_ERROR
:
717 str
= "Roundtrip verify error";
719 case IDNA_CONTAINS_ACE_PREFIX
:
720 str
= "Already have ACE prefix (\"xn--\")";
722 case IDNA_ICONV_ERROR
:
723 str
= "Locale conversion failed";
725 case IDNA_MALLOC_ERROR
:
726 str
= "Allocation failed";
728 case IDNA_DLOPEN_ERROR
:
729 str
= "dlopen() error";
732 snprintf(buf
, max
, "error %d", (int)err
);
737 if ((Idna_rc
)err
== IDNA_SUCCESS
)
743 strncpy(buf
, str
, max
);
748 #endif /* USE_LIBIDN */