- Axel Tillequin and Arnaud Ebalard added support for CURLOPT_ISSUERCERT, for
[platform/upstream/curl.git] / lib / strerror.c
1 /***************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 2004 - 2007, 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 http://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  * $Id$
22  ***************************************************************************/
23
24 #include "setup.h"
25
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 */
31
32 #include <curl/curl.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <errno.h>
36
37 #ifdef USE_LIBIDN
38 #include <idna.h>
39 #endif
40
41 #include "strerror.h"
42
43 #define _MPRINTF_REPLACE /* use our functions only */
44 #include <curl/mprintf.h>
45
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);
50 #else
51 extern char *strerror_r(int errnum, char *buf, size_t buflen);
52 #endif
53 #endif
54
55 const char *
56 curl_easy_strerror(CURLcode error)
57 {
58 #ifndef CURL_DISABLE_VERBOSE_STRINGS
59   switch (error) {
60   case CURLE_OK:
61     return "No error";
62
63   case CURLE_UNSUPPORTED_PROTOCOL:
64     return "Unsupported protocol";
65
66   case CURLE_FAILED_INIT:
67     return "Failed initialization";
68
69   case CURLE_URL_MALFORMAT:
70     return "URL using bad/illegal format or missing URL";
71
72   case CURLE_COULDNT_RESOLVE_PROXY:
73     return "Couldn't resolve proxy name";
74
75   case CURLE_COULDNT_RESOLVE_HOST:
76     return "Couldn't resolve host name";
77
78   case CURLE_COULDNT_CONNECT:
79     return "Couldn't connect to server";
80
81   case CURLE_FTP_WEIRD_SERVER_REPLY:
82     return "FTP: weird server reply";
83
84   case CURLE_REMOTE_ACCESS_DENIED:
85     return "Access denied to remote resource";
86
87   case CURLE_FTP_WEIRD_PASS_REPLY:
88     return "FTP: unknown PASS reply";
89
90   case CURLE_FTP_WEIRD_PASV_REPLY:
91     return "FTP: unknown PASV reply";
92
93   case CURLE_FTP_WEIRD_227_FORMAT:
94     return "FTP: unknown 227 response format";
95
96   case CURLE_FTP_CANT_GET_HOST:
97     return "FTP: can't figure out the host in the PASV response";
98
99   case CURLE_FTP_COULDNT_SET_TYPE:
100     return "FTP: couldn't set file type";
101
102   case CURLE_PARTIAL_FILE:
103     return "Transferred a partial file";
104
105   case CURLE_FTP_COULDNT_RETR_FILE:
106     return "FTP: couldn't retrieve (RETR failed) the specified file";
107
108   case CURLE_QUOTE_ERROR:
109     return "Quote command returned error";
110
111   case CURLE_HTTP_RETURNED_ERROR:
112     return "HTTP response code said error";
113
114   case CURLE_WRITE_ERROR:
115     return "Failed writing received data to disk/application";
116
117   case CURLE_UPLOAD_FAILED:
118     return "Upload failed (at start/before it took off)";
119
120   case CURLE_READ_ERROR:
121     return "Failed to open/read local data from file/application";
122
123   case CURLE_OUT_OF_MEMORY:
124     return "Out of memory";
125
126   case CURLE_OPERATION_TIMEDOUT:
127     return "Timeout was reached";
128
129   case CURLE_FTP_PORT_FAILED:
130     return "FTP: command PORT failed";
131
132   case CURLE_FTP_COULDNT_USE_REST:
133     return "FTP: command REST failed";
134
135   case CURLE_RANGE_ERROR:
136     return "Requested range was not delivered by the server";
137
138   case CURLE_HTTP_POST_ERROR:
139     return "Internal problem setting up the POST";
140
141   case CURLE_SSL_CONNECT_ERROR:
142     return "SSL connect error";
143
144   case CURLE_BAD_DOWNLOAD_RESUME:
145     return "Couldn't resume download";
146
147   case CURLE_FILE_COULDNT_READ_FILE:
148     return "Couldn't read a file:// file";
149
150   case CURLE_LDAP_CANNOT_BIND:
151     return "LDAP: cannot bind";
152
153   case CURLE_LDAP_SEARCH_FAILED:
154     return "LDAP: search failed";
155
156   case CURLE_FUNCTION_NOT_FOUND:
157     return "A required function in the library was not found";
158
159   case CURLE_ABORTED_BY_CALLBACK:
160     return "Operation was aborted by an application callback";
161
162   case CURLE_BAD_FUNCTION_ARGUMENT:
163     return "A libcurl function was given a bad argument";
164
165   case CURLE_INTERFACE_FAILED:
166     return "Failed binding local connection end";
167
168   case CURLE_TOO_MANY_REDIRECTS :
169     return "Number of redirects hit maximum amount";
170
171   case CURLE_UNKNOWN_TELNET_OPTION:
172     return "User specified an unknown telnet option";
173
174   case CURLE_TELNET_OPTION_SYNTAX :
175     return "Malformed telnet option";
176
177   case CURLE_PEER_FAILED_VERIFICATION:
178     return "SSL peer certificate or SSH md5 fingerprint was not OK";
179
180   case CURLE_GOT_NOTHING:
181     return "Server returned nothing (no headers, no data)";
182
183   case CURLE_SSL_ENGINE_NOTFOUND:
184     return "SSL crypto engine not found";
185
186   case CURLE_SSL_ENGINE_SETFAILED:
187     return "Can not set SSL crypto engine as default";
188
189   case CURLE_SSL_ENGINE_INITFAILED:
190     return "Failed to initialise SSL crypto engine";
191
192   case CURLE_SEND_ERROR:
193     return "Failed sending data to the peer";
194
195   case CURLE_RECV_ERROR:
196     return "Failure when receiving data from the peer";
197
198   case CURLE_SSL_CERTPROBLEM:
199     return "Problem with the local SSL certificate";
200
201   case CURLE_SSL_CIPHER:
202     return "Couldn't use specified SSL cipher";
203
204   case CURLE_SSL_CACERT:
205     return "Peer certificate cannot be authenticated with known CA certificates";
206
207   case CURLE_SSL_CACERT_BADFILE:
208     return "Problem with the SSL CA cert (path? access rights?)";
209
210   case CURLE_BAD_CONTENT_ENCODING:
211     return "Unrecognized HTTP Content-Encoding";
212
213   case CURLE_LDAP_INVALID_URL:
214     return "Invalid LDAP URL";
215
216   case CURLE_FILESIZE_EXCEEDED:
217     return "Maximum file size exceeded";
218
219   case CURLE_USE_SSL_FAILED:
220     return "Requested SSL level failed";
221
222   case CURLE_SSL_SHUTDOWN_FAILED:
223     return "Failed to shut down the SSL connection";
224
225   case CURLE_SSL_CRL_BADFILE:
226     return "Failed to load CRL file (path? access rights?, format?)";
227
228   case CURLE_SSL_ISSUER_ERROR:
229     return "Issuer check against peer certificate failed";
230
231   case CURLE_SEND_FAIL_REWIND:
232     return "Send failed since rewinding of the data stream failed";
233
234   case CURLE_LOGIN_DENIED:
235     return "Login denied";
236
237   case CURLE_TFTP_NOTFOUND:
238     return "TFTP: File Not Found";
239
240   case CURLE_TFTP_PERM:
241     return "TFTP: Access Violation";
242
243   case CURLE_REMOTE_DISK_FULL:
244     return "Disk full or allocation exceeded";
245
246   case CURLE_TFTP_ILLEGAL:
247     return "TFTP: Illegal operation";
248
249   case CURLE_TFTP_UNKNOWNID:
250     return "TFTP: Unknown transfer ID";
251
252   case CURLE_REMOTE_FILE_EXISTS:
253     return "Remote file already exists";
254
255   case CURLE_TFTP_NOSUCHUSER:
256     return "TFTP: No such user";
257
258   case CURLE_CONV_FAILED:
259     return "Conversion failed";
260
261   case CURLE_CONV_REQD:
262     return "Caller must register CURLOPT_CONV_ callback options";
263
264   case CURLE_REMOTE_FILE_NOT_FOUND:
265     return "Remote file not found";
266
267   case CURLE_SSH:
268     return "Error in the SSH layer";
269
270   case CURLE_AGAIN:
271     return "Socket not ready for send/recv";
272
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:
287   case CURL_LAST:
288     break;
289   }
290   /*
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.
294    *
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
299    * it _doesn't_ work?
300    *
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.
303    */
304   return "Unknown error";
305 #else
306   if(error == CURLE_OK)
307     return "No error";
308   else
309     return "Error";
310 #endif
311 }
312
313 const char *
314 curl_multi_strerror(CURLMcode error)
315 {
316 #ifndef CURL_DISABLE_VERBOSE_STRINGS
317   switch (error) {
318   case CURLM_CALL_MULTI_PERFORM:
319     return "Please call curl_multi_perform() soon";
320
321   case CURLM_OK:
322     return "No error";
323
324   case CURLM_BAD_HANDLE:
325     return "Invalid multi handle";
326
327   case CURLM_BAD_EASY_HANDLE:
328     return "Invalid easy handle";
329
330   case CURLM_OUT_OF_MEMORY:
331     return "Out of memory";
332
333   case CURLM_INTERNAL_ERROR:
334     return "Internal error";
335
336   case CURLM_BAD_SOCKET:
337     return "Invalid socket argument";
338
339   case CURLM_UNKNOWN_OPTION:
340     return "Unknown option";
341
342   case CURLM_LAST:
343     break;
344   }
345
346   return "Unknown error";
347 #else
348   if(error == CURLM_OK)
349     return "No error";
350   else
351     return "Error";
352 #endif
353 }
354
355 const char *
356 curl_share_strerror(CURLSHcode error)
357 {
358 #ifndef CURL_DISABLE_VERBOSE_STRINGS
359   switch (error) {
360   case CURLSHE_OK:
361     return "No error";
362
363   case CURLSHE_BAD_OPTION:
364     return "Unknown share option";
365
366   case CURLSHE_IN_USE:
367     return "Share currently in use";
368
369   case CURLSHE_INVALID:
370     return "Invalid share handle";
371
372   case CURLSHE_NOMEM:
373     return "Out of memory";
374
375   case CURLSHE_LAST:
376     break;
377   }
378
379   return "CURLSHcode unknown";
380 #else
381   if(error == CURLSHE_OK)
382     return "No error";
383   else
384     return "Error";
385 #endif
386 }
387
388 #ifdef USE_WINSOCK
389
390 /* This function handles most / all (?) Winsock errors cURL is able to produce.
391  */
392 static const char *
393 get_winsock_error (int err, char *buf, size_t len)
394 {
395   const char *p;
396
397 #ifndef CURL_DISABLE_VERBOSE_STRINGS
398   switch (err) {
399   case WSAEINTR:
400     p = "Call interrupted";
401     break;
402   case WSAEBADF:
403     p = "Bad file";
404     break;
405   case WSAEACCES:
406     p = "Bad access";
407     break;
408   case WSAEFAULT:
409     p = "Bad argument";
410     break;
411   case WSAEINVAL:
412     p = "Invalid arguments";
413     break;
414   case WSAEMFILE:
415     p = "Out of file descriptors";
416     break;
417   case WSAEWOULDBLOCK:
418     p = "Call would block";
419     break;
420   case WSAEINPROGRESS:
421   case WSAEALREADY:
422     p = "Blocking call in progress";
423     break;
424   case WSAENOTSOCK:
425     p = "Descriptor is not a socket";
426     break;
427   case WSAEDESTADDRREQ:
428     p = "Need destination address";
429     break;
430   case WSAEMSGSIZE:
431     p = "Bad message size";
432     break;
433   case WSAEPROTOTYPE:
434     p = "Bad protocol";
435     break;
436   case WSAENOPROTOOPT:
437     p = "Protocol option is unsupported";
438     break;
439   case WSAEPROTONOSUPPORT:
440     p = "Protocol is unsupported";
441     break;
442   case WSAESOCKTNOSUPPORT:
443     p = "Socket is unsupported";
444     break;
445   case WSAEOPNOTSUPP:
446     p = "Operation not supported";
447     break;
448   case WSAEAFNOSUPPORT:
449     p = "Address family not supported";
450     break;
451   case WSAEPFNOSUPPORT:
452     p = "Protocol family not supported";
453     break;
454   case WSAEADDRINUSE:
455     p = "Address already in use";
456     break;
457   case WSAEADDRNOTAVAIL:
458     p = "Address not available";
459     break;
460   case WSAENETDOWN:
461     p = "Network down";
462     break;
463   case WSAENETUNREACH:
464     p = "Network unreachable";
465     break;
466   case WSAENETRESET:
467     p = "Network has been reset";
468     break;
469   case WSAECONNABORTED:
470     p = "Connection was aborted";
471     break;
472   case WSAECONNRESET:
473     p = "Connection was reset";
474     break;
475   case WSAENOBUFS:
476     p = "No buffer space";
477     break;
478   case WSAEISCONN:
479     p = "Socket is already connected";
480     break;
481   case WSAENOTCONN:
482     p = "Socket is not connected";
483     break;
484   case WSAESHUTDOWN:
485     p = "Socket has been shut down";
486     break;
487   case WSAETOOMANYREFS:
488     p = "Too many references";
489     break;
490   case WSAETIMEDOUT:
491     p = "Timed out";
492     break;
493   case WSAECONNREFUSED:
494     p = "Connection refused";
495     break;
496   case WSAELOOP:
497     p = "Loop??";
498     break;
499   case WSAENAMETOOLONG:
500     p = "Name too long";
501     break;
502   case WSAEHOSTDOWN:
503     p = "Host down";
504     break;
505   case WSAEHOSTUNREACH:
506     p = "Host unreachable";
507     break;
508   case WSAENOTEMPTY:
509     p = "Not empty";
510     break;
511   case WSAEPROCLIM:
512     p = "Process limit reached";
513     break;
514   case WSAEUSERS:
515     p = "Too many users";
516     break;
517   case WSAEDQUOT:
518     p = "Bad quota";
519     break;
520   case WSAESTALE:
521     p = "Something is stale";
522     break;
523   case WSAEREMOTE:
524     p = "Remote error";
525     break;
526 #ifdef WSAEDISCON  /* missing in SalfordC! */
527   case WSAEDISCON:
528     p = "Disconnected";
529     break;
530 #endif
531     /* Extended Winsock errors */
532   case WSASYSNOTREADY:
533     p = "Winsock library is not ready";
534     break;
535   case WSANOTINITIALISED:
536     p = "Winsock library not initialised";
537     break;
538   case WSAVERNOTSUPPORTED:
539     p = "Winsock version not supported";
540     break;
541
542     /* getXbyY() errors (already handled in herrmsg):
543      * Authoritative Answer: Host not found */
544   case WSAHOST_NOT_FOUND:
545     p = "Host not found";
546     break;
547
548     /* Non-Authoritative: Host not found, or SERVERFAIL */
549   case WSATRY_AGAIN:
550     p = "Host not found, try again";
551     break;
552
553     /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
554   case WSANO_RECOVERY:
555     p = "Unrecoverable error in call to nameserver";
556     break;
557
558     /* Valid name, no data record of requested type */
559   case WSANO_DATA:
560     p = "No data record of requested type";
561     break;
562
563   default:
564     return NULL;
565   }
566 #else
567   if(err == CURLE_OK)
568     return NULL;
569   else
570     p = "error";
571 #endif
572   strncpy (buf, p, len);
573   buf [len-1] = '\0';
574   return buf;
575 }
576 #endif   /* USE_WINSOCK */
577
578 /*
579  * Our thread-safe and smart strerror() replacement.
580  *
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.
585  *
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.
588  */
589 const char *Curl_strerror(struct connectdata *conn, int err)
590 {
591   char *buf, *p;
592   size_t max;
593
594   DEBUGASSERT(conn);
595   DEBUGASSERT(err >= 0);
596
597   buf = conn->syserr_buf;
598   max = sizeof(conn->syserr_buf)-1;
599   *buf = '\0';
600
601 #ifdef USE_WINSOCK
602
603 #ifdef _WIN32_WCE
604   buf[0]=0;
605   {
606     wchar_t wbuf[256];
607
608     FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err,
609                   LANG_NEUTRAL, wbuf, sizeof(wbuf)/sizeof(wchar_t), NULL);
610     wcstombs(buf,wbuf,max);
611   }
612
613 #else
614
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);
618   else {
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);
623   }
624 #endif
625 #else /* not USE_WINSOCK coming up */
626
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
630      versions. */
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.*/
636 #else
637   {
638     /* HAVE_GLIBC_STRERROR_R */
639     char buffer[256];
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) */
644     if(msg)
645       strncpy(buf, msg, max);
646     else
647       snprintf(buf, max, "Unknown error %d", err);
648   }
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 */
654
655   buf[max] = '\0'; /* make sure the string is zero terminated */
656
657   /* strip trailing '\r\n' or '\n'. */
658   if((p = strrchr(buf,'\n')) != NULL && (p - buf) >= 2)
659      *p = '\0';
660   if((p = strrchr(buf,'\r')) != NULL && (p - buf) >= 1)
661      *p = '\0';
662   return buf;
663 }
664
665 #ifdef USE_LIBIDN
666 /*
667  * Return error-string for libidn status as returned from idna_to_ascii_lz().
668  */
669 const char *Curl_idn_strerror (struct connectdata *conn, int err)
670 {
671 #ifdef HAVE_IDNA_STRERROR
672   (void)conn;
673   return idna_strerror((Idna_rc) err);
674 #else
675   const char *str;
676   char *buf;
677   size_t max;
678
679   DEBUGASSERT(conn);
680
681   buf = conn->syserr_buf;
682   max = sizeof(conn->syserr_buf)-1;
683
684 #ifndef CURL_DISABLE_VERBOSE_STRINGS
685   switch ((Idna_rc)err) {
686     case IDNA_SUCCESS:
687       str = "No error";
688       break;
689     case IDNA_STRINGPREP_ERROR:
690       str = "Error in string preparation";
691       break;
692     case IDNA_PUNYCODE_ERROR:
693       str = "Error in Punycode operation";
694       break;
695     case IDNA_CONTAINS_NON_LDH:
696       str = "Illegal ASCII characters";
697       break;
698     case IDNA_CONTAINS_MINUS:
699       str = "Contains minus";
700       break;
701     case IDNA_INVALID_LENGTH:
702       str = "Invalid output length";
703       break;
704     case IDNA_NO_ACE_PREFIX:
705       str = "No ACE prefix (\"xn--\")";
706       break;
707     case IDNA_ROUNDTRIP_VERIFY_ERROR:
708       str = "Round trip verify error";
709       break;
710     case IDNA_CONTAINS_ACE_PREFIX:
711       str = "Already have ACE prefix (\"xn--\")";
712       break;
713     case IDNA_ICONV_ERROR:
714       str = "Locale conversion failed";
715       break;
716     case IDNA_MALLOC_ERROR:
717       str = "Allocation failed";
718       break;
719     case IDNA_DLOPEN_ERROR:
720       str = "dlopen() error";
721       break;
722     default:
723       snprintf(buf, max, "error %d", (int)err);
724       str = NULL;
725       break;
726   }
727 #else
728   if((Idna_rc)err == IDNA_SUCCESS)
729     str = "No error";
730   else
731     str = "Error";
732 #endif
733   if(str)
734     strncpy(buf, str, max);
735   buf[max] = '\0';
736   return (buf);
737 #endif
738 }
739 #endif  /* USE_LIBIDN */