1/***************************************************************************
2 *                                  _   _ ____  _
3 *  Project                     ___| | | |  _ \| |
4 *                             / __| | | | |_) | |
5 *                            | (__| |_| |  _ <| |___
6 *                             \___|\___/|_| \_\_____|
7 *
8 * Copyright (C) 2004 - 2011, 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 ***************************************************************************/
22
23#include "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#include <stdlib.h>
38#include <string.h>
39#include <errno.h>
40
41#ifdef USE_LIBIDN
42#include <idna.h>
43#endif
44
45#include "strerror.h"
46
47#define _MPRINTF_REPLACE /* use our functions only */
48#include <curl/mprintf.h>
49
50
51const char *
52curl_easy_strerror(CURLcode error)
53{
54#ifndef CURL_DISABLE_VERBOSE_STRINGS
55  switch (error) {
56  case CURLE_OK:
57    return "No error";
58
59  case CURLE_UNSUPPORTED_PROTOCOL:
60    return "Unsupported protocol";
61
62  case CURLE_FAILED_INIT:
63    return "Failed initialization";
64
65  case CURLE_URL_MALFORMAT:
66    return "URL using bad/illegal format or missing URL";
67
68  case CURLE_NOT_BUILT_IN:
69    return "A requested feature, protocol or option was not found built-in in"
70      " this libcurl due to a build-time decision.";
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_PRET_FAILED:
88    return "FTP: The server did not accept the PRET command.";
89
90  case CURLE_FTP_WEIRD_PASS_REPLY:
91    return "FTP: unknown PASS reply";
92
93  case CURLE_FTP_WEIRD_PASV_REPLY:
94    return "FTP: unknown PASV reply";
95
96  case CURLE_FTP_WEIRD_227_FORMAT:
97    return "FTP: unknown 227 response format";
98
99  case CURLE_FTP_CANT_GET_HOST:
100    return "FTP: can't figure out the host in the PASV response";
101
102  case CURLE_FTP_COULDNT_SET_TYPE:
103    return "FTP: couldn't set file type";
104
105  case CURLE_PARTIAL_FILE:
106    return "Transferred a partial file";
107
108  case CURLE_FTP_COULDNT_RETR_FILE:
109    return "FTP: couldn't retrieve (RETR failed) the specified file";
110
111  case CURLE_QUOTE_ERROR:
112    return "Quote command returned error";
113
114  case CURLE_HTTP_RETURNED_ERROR:
115    return "HTTP response code said error";
116
117  case CURLE_WRITE_ERROR:
118    return "Failed writing received data to disk/application";
119
120  case CURLE_UPLOAD_FAILED:
121    return "Upload failed (at start/before it took off)";
122
123  case CURLE_READ_ERROR:
124    return "Failed to open/read local data from file/application";
125
126  case CURLE_OUT_OF_MEMORY:
127    return "Out of memory";
128
129  case CURLE_OPERATION_TIMEDOUT:
130    return "Timeout was reached";
131
132  case CURLE_FTP_PORT_FAILED:
133    return "FTP: command PORT failed";
134
135  case CURLE_FTP_COULDNT_USE_REST:
136    return "FTP: command REST failed";
137
138  case CURLE_RANGE_ERROR:
139    return "Requested range was not delivered by the server";
140
141  case CURLE_HTTP_POST_ERROR:
142    return "Internal problem setting up the POST";
143
144  case CURLE_SSL_CONNECT_ERROR:
145    return "SSL connect error";
146
147  case CURLE_BAD_DOWNLOAD_RESUME:
148    return "Couldn't resume download";
149
150  case CURLE_FILE_COULDNT_READ_FILE:
151    return "Couldn't read a file:// file";
152
153  case CURLE_LDAP_CANNOT_BIND:
154    return "LDAP: cannot bind";
155
156  case CURLE_LDAP_SEARCH_FAILED:
157    return "LDAP: search failed";
158
159  case CURLE_FUNCTION_NOT_FOUND:
160    return "A required function in the library was not found";
161
162  case CURLE_ABORTED_BY_CALLBACK:
163    return "Operation was aborted by an application callback";
164
165  case CURLE_BAD_FUNCTION_ARGUMENT:
166    return "A libcurl function was given a bad argument";
167
168  case CURLE_INTERFACE_FAILED:
169    return "Failed binding local connection end";
170
171  case CURLE_TOO_MANY_REDIRECTS :
172    return "Number of redirects hit maximum amount";
173
174  case CURLE_UNKNOWN_OPTION:
175    return "An unknown option was passed in to libcurl";
176
177  case CURLE_TELNET_OPTION_SYNTAX :
178    return "Malformed telnet option";
179
180  case CURLE_PEER_FAILED_VERIFICATION:
181    return "SSL peer certificate or SSH remote key was not OK";
182
183  case CURLE_GOT_NOTHING:
184    return "Server returned nothing (no headers, no data)";
185
186  case CURLE_SSL_ENGINE_NOTFOUND:
187    return "SSL crypto engine not found";
188
189  case CURLE_SSL_ENGINE_SETFAILED:
190    return "Can not set SSL crypto engine as default";
191
192  case CURLE_SSL_ENGINE_INITFAILED:
193    return "Failed to initialise SSL crypto engine";
194
195  case CURLE_SEND_ERROR:
196    return "Failed sending data to the peer";
197
198  case CURLE_RECV_ERROR:
199    return "Failure when receiving data from the peer";
200
201  case CURLE_SSL_CERTPROBLEM:
202    return "Problem with the local SSL certificate";
203
204  case CURLE_SSL_CIPHER:
205    return "Couldn't use specified SSL cipher";
206
207  case CURLE_SSL_CACERT:
208    return "Peer certificate cannot be authenticated with given CA "
209      "certificates";
210
211  case CURLE_SSL_CACERT_BADFILE:
212    return "Problem with the SSL CA cert (path? access rights?)";
213
214  case CURLE_BAD_CONTENT_ENCODING:
215    return "Unrecognized or bad HTTP Content or Transfer-Encoding";
216
217  case CURLE_LDAP_INVALID_URL:
218    return "Invalid LDAP URL";
219
220  case CURLE_FILESIZE_EXCEEDED:
221    return "Maximum file size exceeded";
222
223  case CURLE_USE_SSL_FAILED:
224    return "Requested SSL level failed";
225
226  case CURLE_SSL_SHUTDOWN_FAILED:
227    return "Failed to shut down the SSL connection";
228
229  case CURLE_SSL_CRL_BADFILE:
230    return "Failed to load CRL file (path? access rights?, format?)";
231
232  case CURLE_SSL_ISSUER_ERROR:
233    return "Issuer check against peer certificate failed";
234
235  case CURLE_SEND_FAIL_REWIND:
236    return "Send failed since rewinding of the data stream failed";
237
238  case CURLE_LOGIN_DENIED:
239    return "Login denied";
240
241  case CURLE_TFTP_NOTFOUND:
242    return "TFTP: File Not Found";
243
244  case CURLE_TFTP_PERM:
245    return "TFTP: Access Violation";
246
247  case CURLE_REMOTE_DISK_FULL:
248    return "Disk full or allocation exceeded";
249
250  case CURLE_TFTP_ILLEGAL:
251    return "TFTP: Illegal operation";
252
253  case CURLE_TFTP_UNKNOWNID:
254    return "TFTP: Unknown transfer ID";
255
256  case CURLE_REMOTE_FILE_EXISTS:
257    return "Remote file already exists";
258
259  case CURLE_TFTP_NOSUCHUSER:
260    return "TFTP: No such user";
261
262  case CURLE_CONV_FAILED:
263    return "Conversion failed";
264
265  case CURLE_CONV_REQD:
266    return "Caller must register CURLOPT_CONV_ callback options";
267
268  case CURLE_REMOTE_FILE_NOT_FOUND:
269    return "Remote file not found";
270
271  case CURLE_SSH:
272    return "Error in the SSH layer";
273
274  case CURLE_AGAIN:
275    return "Socket not ready for send/recv";
276
277  case CURLE_RTSP_CSEQ_ERROR:
278    return "RTSP CSeq mismatch or invalid CSeq";
279
280  case CURLE_RTSP_SESSION_ERROR:
281    return "RTSP session error";
282
283  case CURLE_FTP_BAD_FILE_LIST:
284    return "Unable to parse FTP file list";
285
286  case CURLE_CHUNK_FAILED:
287    return "Chunk callback failed";
288
289    /* error codes not used by current libcurl */
290  case CURLE_OBSOLETE10:
291  case CURLE_OBSOLETE12:
292  case CURLE_OBSOLETE16:
293  case CURLE_OBSOLETE20:
294  case CURLE_OBSOLETE24:
295  case CURLE_OBSOLETE29:
296  case CURLE_OBSOLETE32:
297  case CURLE_OBSOLETE40:
298  case CURLE_OBSOLETE44:
299  case CURLE_OBSOLETE46:
300  case CURLE_OBSOLETE50:
301  case CURLE_OBSOLETE57:
302  case CURL_LAST:
303    break;
304  }
305  /*
306   * By using a switch, gcc -Wall will complain about enum values
307   * which do not appear, helping keep this function up-to-date.
308   * By using gcc -Wall -Werror, you can't forget.
309   *
310   * A table would not have the same benefit.  Most compilers will
311   * generate code very similar to a table in any case, so there
312   * is little performance gain from a table.  And something is broken
313   * for the user's application, anyways, so does it matter how fast
314   * it _doesn't_ work?
315   *
316   * The line number for the error will be near this comment, which
317   * is why it is here, and not at the start of the switch.
318   */
319  return "Unknown error";
320#else
321  if(error == CURLE_OK)
322    return "No error";
323  else
324    return "Error";
325#endif
326}
327
328const char *
329curl_multi_strerror(CURLMcode error)
330{
331#ifndef CURL_DISABLE_VERBOSE_STRINGS
332  switch (error) {
333  case CURLM_CALL_MULTI_PERFORM:
334    return "Please call curl_multi_perform() soon";
335
336  case CURLM_OK:
337    return "No error";
338
339  case CURLM_BAD_HANDLE:
340    return "Invalid multi handle";
341
342  case CURLM_BAD_EASY_HANDLE:
343    return "Invalid easy handle";
344
345  case CURLM_OUT_OF_MEMORY:
346    return "Out of memory";
347
348  case CURLM_INTERNAL_ERROR:
349    return "Internal error";
350
351  case CURLM_BAD_SOCKET:
352    return "Invalid socket argument";
353
354  case CURLM_UNKNOWN_OPTION:
355    return "Unknown option";
356
357  case CURLM_LAST:
358    break;
359  }
360
361  return "Unknown error";
362#else
363  if(error == CURLM_OK)
364    return "No error";
365  else
366    return "Error";
367#endif
368}
369
370const char *
371curl_share_strerror(CURLSHcode error)
372{
373#ifndef CURL_DISABLE_VERBOSE_STRINGS
374  switch (error) {
375  case CURLSHE_OK:
376    return "No error";
377
378  case CURLSHE_BAD_OPTION:
379    return "Unknown share option";
380
381  case CURLSHE_IN_USE:
382    return "Share currently in use";
383
384  case CURLSHE_INVALID:
385    return "Invalid share handle";
386
387  case CURLSHE_NOMEM:
388    return "Out of memory";
389
390  case CURLSHE_LAST:
391    break;
392  }
393
394  return "CURLSHcode unknown";
395#else
396  if(error == CURLSHE_OK)
397    return "No error";
398  else
399    return "Error";
400#endif
401}
402
403#ifdef USE_WINSOCK
404
405/* This function handles most / all (?) Winsock errors cURL is able to produce.
406 */
407static const char *
408get_winsock_error (int err, char *buf, size_t len)
409{
410  const char *p;
411
412#ifndef CURL_DISABLE_VERBOSE_STRINGS
413  switch (err) {
414  case WSAEINTR:
415    p = "Call interrupted";
416    break;
417  case WSAEBADF:
418    p = "Bad file";
419    break;
420  case WSAEACCES:
421    p = "Bad access";
422    break;
423  case WSAEFAULT:
424    p = "Bad argument";
425    break;
426  case WSAEINVAL:
427    p = "Invalid arguments";
428    break;
429  case WSAEMFILE:
430    p = "Out of file descriptors";
431    break;
432  case WSAEWOULDBLOCK:
433    p = "Call would block";
434    break;
435  case WSAEINPROGRESS:
436  case WSAEALREADY:
437    p = "Blocking call in progress";
438    break;
439  case WSAENOTSOCK:
440    p = "Descriptor is not a socket";
441    break;
442  case WSAEDESTADDRREQ:
443    p = "Need destination address";
444    break;
445  case WSAEMSGSIZE:
446    p = "Bad message size";
447    break;
448  case WSAEPROTOTYPE:
449    p = "Bad protocol";
450    break;
451  case WSAENOPROTOOPT:
452    p = "Protocol option is unsupported";
453    break;
454  case WSAEPROTONOSUPPORT:
455    p = "Protocol is unsupported";
456    break;
457  case WSAESOCKTNOSUPPORT:
458    p = "Socket is unsupported";
459    break;
460  case WSAEOPNOTSUPP:
461    p = "Operation not supported";
462    break;
463  case WSAEAFNOSUPPORT:
464    p = "Address family not supported";
465    break;
466  case WSAEPFNOSUPPORT:
467    p = "Protocol family not supported";
468    break;
469  case WSAEADDRINUSE:
470    p = "Address already in use";
471    break;
472  case WSAEADDRNOTAVAIL:
473    p = "Address not available";
474    break;
475  case WSAENETDOWN:
476    p = "Network down";
477    break;
478  case WSAENETUNREACH:
479    p = "Network unreachable";
480    break;
481  case WSAENETRESET:
482    p = "Network has been reset";
483    break;
484  case WSAECONNABORTED:
485    p = "Connection was aborted";
486    break;
487  case WSAECONNRESET:
488    p = "Connection was reset";
489    break;
490  case WSAENOBUFS:
491    p = "No buffer space";
492    break;
493  case WSAEISCONN:
494    p = "Socket is already connected";
495    break;
496  case WSAENOTCONN:
497    p = "Socket is not connected";
498    break;
499  case WSAESHUTDOWN:
500    p = "Socket has been shut down";
501    break;
502  case WSAETOOMANYREFS:
503    p = "Too many references";
504    break;
505  case WSAETIMEDOUT:
506    p = "Timed out";
507    break;
508  case WSAECONNREFUSED:
509    p = "Connection refused";
510    break;
511  case WSAELOOP:
512    p = "Loop??";
513    break;
514  case WSAENAMETOOLONG:
515    p = "Name too long";
516    break;
517  case WSAEHOSTDOWN:
518    p = "Host down";
519    break;
520  case WSAEHOSTUNREACH:
521    p = "Host unreachable";
522    break;
523  case WSAENOTEMPTY:
524    p = "Not empty";
525    break;
526  case WSAEPROCLIM:
527    p = "Process limit reached";
528    break;
529  case WSAEUSERS:
530    p = "Too many users";
531    break;
532  case WSAEDQUOT:
533    p = "Bad quota";
534    break;
535  case WSAESTALE:
536    p = "Something is stale";
537    break;
538  case WSAEREMOTE:
539    p = "Remote error";
540    break;
541#ifdef WSAEDISCON  /* missing in SalfordC! */
542  case WSAEDISCON:
543    p = "Disconnected";
544    break;
545#endif
546    /* Extended Winsock errors */
547  case WSASYSNOTREADY:
548    p = "Winsock library is not ready";
549    break;
550  case WSANOTINITIALISED:
551    p = "Winsock library not initialised";
552    break;
553  case WSAVERNOTSUPPORTED:
554    p = "Winsock version not supported";
555    break;
556
557    /* getXbyY() errors (already handled in herrmsg):
558     * Authoritative Answer: Host not found */
559  case WSAHOST_NOT_FOUND:
560    p = "Host not found";
561    break;
562
563    /* Non-Authoritative: Host not found, or SERVERFAIL */
564  case WSATRY_AGAIN:
565    p = "Host not found, try again";
566    break;
567
568    /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
569  case WSANO_RECOVERY:
570    p = "Unrecoverable error in call to nameserver";
571    break;
572
573    /* Valid name, no data record of requested type */
574  case WSANO_DATA:
575    p = "No data record of requested type";
576    break;
577
578  default:
579    return NULL;
580  }
581#else
582  if(err == CURLE_OK)
583    return NULL;
584  else
585    p = "error";
586#endif
587  strncpy (buf, p, len);
588  buf [len-1] = '\0';
589  return buf;
590}
591#endif   /* USE_WINSOCK */
592
593/*
594 * Our thread-safe and smart strerror() replacement.
595 *
596 * The 'err' argument passed in to this function MUST be a true errno number
597 * as reported on this system. We do no range checking on the number before
598 * we pass it to the "number-to-message" conversion function and there might
599 * be systems that don't do proper range checking in there themselves.
600 *
601 * We don't do range checking (on systems other than Windows) since there is
602 * no good reliable and portable way to do it.
603 */
604const char *Curl_strerror(struct connectdata *conn, int err)
605{
606  char *buf, *p;
607  size_t max;
608  int old_errno = ERRNO;
609
610  DEBUGASSERT(conn);
611  DEBUGASSERT(err >= 0);
612
613  buf = conn->syserr_buf;
614  max = sizeof(conn->syserr_buf)-1;
615  *buf = '\0';
616
617#ifdef USE_WINSOCK
618
619#ifdef _WIN32_WCE
620  {
621    wchar_t wbuf[256];
622    wbuf[0] = L'\0';
623
624    FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err,
625                  LANG_NEUTRAL, wbuf, sizeof(wbuf)/sizeof(wchar_t), NULL);
626    wcstombs(buf,wbuf,max);
627  }
628#else
629  /* 'sys_nerr' is the maximum errno number, it is not widely portable */
630  if(err >= 0 && err < sys_nerr)
631    strncpy(buf, strerror(err), max);
632  else {
633    if(!get_winsock_error(err, buf, max) &&
634        !FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err,
635                       LANG_NEUTRAL, buf, (DWORD)max, NULL))
636      snprintf(buf, max, "Unknown error %d (%#x)", err, err);
637  }
638#endif
639
640#else /* not USE_WINSOCK coming up */
641
642#if defined(HAVE_STRERROR_R) && defined(HAVE_POSIX_STRERROR_R)
643 /*
644  * The POSIX-style strerror_r() may set errno to ERANGE if insufficient
645  * storage is supplied via 'strerrbuf' and 'buflen' to hold the generated
646  * message string, or EINVAL if 'errnum' is not a valid error number.
647  */
648  if(0 != strerror_r(err, buf, max)) {
649    if('\0' == buf[0])
650      snprintf(buf, max, "Unknown error %d", err);
651  }
652#elif defined(HAVE_STRERROR_R) && defined(HAVE_GLIBC_STRERROR_R)
653 /*
654  * The glibc-style strerror_r() only *might* use the buffer we pass to
655  * the function, but it always returns the error message as a pointer,
656  * so we must copy that string unconditionally (if non-NULL).
657  */
658  {
659    char buffer[256];
660    char *msg = strerror_r(err, buffer, sizeof(buffer));
661    if(msg)
662      strncpy(buf, msg, max);
663    else
664      snprintf(buf, max, "Unknown error %d", err);
665  }
666#elif defined(HAVE_STRERROR_R) && defined(HAVE_VXWORKS_STRERROR_R)
667 /*
668  * The vxworks-style strerror_r() does use the buffer we pass to the function.
669  * The buffer size should be at least MAXERRSTR_SIZE (150) defined in rtsold.h
670  */
671  {
672    char buffer[256];
673    if(OK == strerror_r(err, buffer))
674      strncpy(buf, buffer, max);
675    else
676      snprintf(buf, max, "Unknown error %d", err);
677  }
678#else
679  {
680    char *msg = strerror(err);
681    if(msg)
682      strncpy(buf, msg, max);
683    else
684      snprintf(buf, max, "Unknown error %d", err);
685  }
686#endif
687
688#endif /* end of ! USE_WINSOCK */
689
690  buf[max] = '\0'; /* make sure the string is zero terminated */
691
692  /* strip trailing '\r\n' or '\n'. */
693  if((p = strrchr(buf,'\n')) != NULL && (p - buf) >= 2)
694     *p = '\0';
695  if((p = strrchr(buf,'\r')) != NULL && (p - buf) >= 1)
696     *p = '\0';
697
698  if(old_errno != ERRNO)
699    SET_ERRNO(old_errno);
700
701  return buf;
702}
703
704#ifdef USE_LIBIDN
705/*
706 * Return error-string for libidn status as returned from idna_to_ascii_lz().
707 */
708const char *Curl_idn_strerror (struct connectdata *conn, int err)
709{
710#ifdef HAVE_IDNA_STRERROR
711  (void)conn;
712  return idna_strerror((Idna_rc) err);
713#else
714  const char *str;
715  char *buf;
716  size_t max;
717
718  DEBUGASSERT(conn);
719
720  buf = conn->syserr_buf;
721  max = sizeof(conn->syserr_buf)-1;
722  *buf = '\0';
723
724#ifndef CURL_DISABLE_VERBOSE_STRINGS
725  switch ((Idna_rc)err) {
726    case IDNA_SUCCESS:
727      str = "No error";
728      break;
729    case IDNA_STRINGPREP_ERROR:
730      str = "Error in string preparation";
731      break;
732    case IDNA_PUNYCODE_ERROR:
733      str = "Error in Punycode operation";
734      break;
735    case IDNA_CONTAINS_NON_LDH:
736      str = "Illegal ASCII characters";
737      break;
738    case IDNA_CONTAINS_MINUS:
739      str = "Contains minus";
740      break;
741    case IDNA_INVALID_LENGTH:
742      str = "Invalid output length";
743      break;
744    case IDNA_NO_ACE_PREFIX:
745      str = "No ACE prefix (\"xn--\")";
746      break;
747    case IDNA_ROUNDTRIP_VERIFY_ERROR:
748      str = "Round trip verify error";
749      break;
750    case IDNA_CONTAINS_ACE_PREFIX:
751      str = "Already have ACE prefix (\"xn--\")";
752      break;
753    case IDNA_ICONV_ERROR:
754      str = "Locale conversion failed";
755      break;
756    case IDNA_MALLOC_ERROR:
757      str = "Allocation failed";
758      break;
759    case IDNA_DLOPEN_ERROR:
760      str = "dlopen() error";
761      break;
762    default:
763      snprintf(buf, max, "error %d", err);
764      str = NULL;
765      break;
766  }
767#else
768  if((Idna_rc)err == IDNA_SUCCESS)
769    str = "No error";
770  else
771    str = "Error";
772#endif
773  if(str)
774    strncpy(buf, str, max);
775  buf[max] = '\0';
776  return (buf);
777#endif
778}
779#endif  /* USE_LIBIDN */
780