prevent compiler warning
[platform/upstream/curl.git] / lib / strerror.c
1 /***************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 2004, 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 #include <curl/curl.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <errno.h>
29
30 #ifdef USE_LIBIDN
31 #include <idna.h>
32 #endif
33
34 #include "strerror.h"
35
36 #define _MPRINTF_REPLACE /* use our functions only */
37 #include <curl/mprintf.h>
38
39 #ifdef HAVE_NO_STRERROR_R_DECL
40 #ifdef HAVE_POSIX_STRERROR_R
41 /* seen on AIX 5100-02 gcc 2.9 */
42 extern int strerror_r(int errnum, char *strerrbuf, size_t buflen);
43 #else
44 extern char *strerror_r(int errnum, char *buf, size_t buflen);
45 #endif
46 #endif
47
48 const char *
49 curl_easy_strerror(CURLcode error)
50 {
51 #ifndef CURL_DISABLE_VERBOSE_STRINGS
52   switch (error) {
53   case CURLE_OK:
54     return "no error";
55
56   case CURLE_UNSUPPORTED_PROTOCOL:
57     return "unsupported protocol";
58
59   case CURLE_FAILED_INIT:
60     return "failed init";
61
62   case CURLE_URL_MALFORMAT:
63     return "URL using bad/illegal format or missing URL";
64
65   case CURLE_COULDNT_RESOLVE_PROXY:
66     return "couldnt resolve proxy name";
67
68   case CURLE_COULDNT_RESOLVE_HOST:
69     return "couldnt resolve host name";
70
71   case CURLE_COULDNT_CONNECT:
72     return "couldn't connect to server";
73
74   case CURLE_FTP_WEIRD_SERVER_REPLY:
75     return "FTP: weird server reply";
76
77   case CURLE_FTP_ACCESS_DENIED:
78     return "FTP: access denied";
79
80   case CURLE_FTP_USER_PASSWORD_INCORRECT:
81     return "FTP: user and/or password incorrect";
82
83   case CURLE_FTP_WEIRD_PASS_REPLY:
84     return "FTP: unknown PASS reply";
85
86   case CURLE_FTP_WEIRD_USER_REPLY:
87     return "FTP: unknown USER reply";
88
89   case CURLE_FTP_WEIRD_PASV_REPLY:
90     return "FTP: unknown PASV reply";
91
92   case CURLE_FTP_WEIRD_227_FORMAT:
93     return "FTP: unknown 227 response format";
94
95   case CURLE_FTP_CANT_GET_HOST:
96     return "FTP: can't figure out the host in the PASV response";
97
98   case CURLE_FTP_CANT_RECONNECT:
99     return "FTP: can't connect to server the response code is unknown";
100
101   case CURLE_FTP_COULDNT_SET_BINARY:
102     return "FTP: couldn't set binary mode";
103
104   case CURLE_PARTIAL_FILE:
105     return "Transferred a partial file";
106
107   case CURLE_FTP_COULDNT_RETR_FILE:
108     return "FTP: couldn't retrieve (RETR failed) the specified file";
109
110   case CURLE_FTP_WRITE_ERROR:
111     return "FTP: the post-transfer acknowledge response was not OK";
112
113   case CURLE_FTP_QUOTE_ERROR:
114     return "FTP: a quote command returned error";
115
116   case CURLE_HTTP_RETURNED_ERROR:
117     return "HTTP response code said error";
118
119   case CURLE_WRITE_ERROR:
120     return "failed writing received data to disk/application";
121
122   case CURLE_FTP_COULDNT_STOR_FILE:
123     return "failed FTP upload (the STOR command)";
124
125   case CURLE_READ_ERROR:
126     return "failed to open/read local data from file/application";
127
128   case CURLE_OUT_OF_MEMORY:
129     return "out of memory";
130
131   case CURLE_OPERATION_TIMEOUTED:
132     return "a timeout was reached";
133
134   case CURLE_FTP_COULDNT_SET_ASCII:
135     return "FTP could not set ASCII mode (TYPE A)";
136
137   case CURLE_FTP_PORT_FAILED:
138     return "FTP command PORT failed";
139
140   case CURLE_FTP_COULDNT_USE_REST:
141     return "FTP command REST failed";
142
143   case CURLE_FTP_COULDNT_GET_SIZE:
144     return "FTP command SIZE failed";
145
146   case CURLE_HTTP_RANGE_ERROR:
147     return "a range was requested but the server did not deliver it";
148
149   case CURLE_HTTP_POST_ERROR:
150     return "internal problem setting up the POST";
151
152   case CURLE_SSL_CONNECT_ERROR:
153     return "SSL connect error";
154
155   case CURLE_BAD_DOWNLOAD_RESUME:
156     return "couldn't resume download";
157
158   case CURLE_FILE_COULDNT_READ_FILE:
159     return "couldn't read a file:// file";
160
161   case CURLE_LDAP_CANNOT_BIND:
162     return "LDAP: cannot bind";
163
164   case CURLE_LDAP_SEARCH_FAILED:
165     return "LDAP: search failed";
166
167   case CURLE_LIBRARY_NOT_FOUND:
168     return "a required shared library was not found";
169
170   case CURLE_FUNCTION_NOT_FOUND:
171     return "a required function in the shared library was not found";
172
173   case CURLE_ABORTED_BY_CALLBACK:
174     return "the operation was aborted by an application callback";
175
176   case CURLE_BAD_FUNCTION_ARGUMENT:
177     return "a libcurl function was given a bad argument";
178
179   case CURLE_INTERFACE_FAILED:
180     return "failed binding local connection end";
181
182   case CURLE_TOO_MANY_REDIRECTS :
183     return "number of redirects hit maximum amount";
184
185   case CURLE_UNKNOWN_TELNET_OPTION:
186     return "User specified an unknown option";
187
188   case CURLE_TELNET_OPTION_SYNTAX :
189     return "Malformed telnet option";
190
191   case CURLE_SSL_PEER_CERTIFICATE:
192     return "SSL peer certificate was not ok";
193
194   case CURLE_GOT_NOTHING:
195     return "server returned nothing (no headers, no data)";
196
197   case CURLE_SSL_ENGINE_NOTFOUND:
198     return "SSL crypto engine not found";
199
200   case CURLE_SSL_ENGINE_SETFAILED:
201     return "can not set SSL crypto engine as default";
202
203   case CURLE_SSL_ENGINE_INITFAILED:
204     return "failed to initialise SSL crypto engine";
205
206   case CURLE_SEND_ERROR:
207     return "failed sending data to the peer";
208
209   case CURLE_RECV_ERROR:
210     return "failure when receiving data from the peer";
211
212   case CURLE_SHARE_IN_USE:
213     return "share is already in use";
214
215   case CURLE_SSL_CERTPROBLEM:
216     return "problem with the local SSL certificate";
217
218   case CURLE_SSL_CIPHER:
219     return "couldn't use specified SSL cipher";
220
221   case CURLE_SSL_CACERT:
222     return "problem with the SSL CA cert (path? access rights?)";
223
224   case CURLE_BAD_CONTENT_ENCODING:
225     return "Unrecognized HTTP Content-Encoding";
226
227   case CURLE_LDAP_INVALID_URL:
228     return "Invalid LDAP URL";
229
230   case CURLE_FILESIZE_EXCEEDED:
231     return "Maximum file size exceeded";
232
233   case CURLE_FTP_SSL_FAILED:
234     return "Requested FTP SSL level failed";
235
236   case CURLE_SEND_FAIL_REWIND:
237     return "Send failed since rewinding of the data stream failed";
238
239   case CURLE_LOGIN_DENIED:
240     return "FTP: login denied";;
241
242   case CURLE_URL_MALFORMAT_USER: /* not used by current libcurl */
243   case CURLE_MALFORMAT_USER:     /* not used by current libcurl */
244   case CURLE_BAD_CALLING_ORDER:  /* not used by current libcurl */
245   case CURLE_BAD_PASSWORD_ENTERED:/* not used by current libcurl */
246   case CURLE_OBSOLETE:           /* not used by current libcurl */
247   case CURL_LAST:
248     break;
249   }
250   /*
251    * By using a switch, gcc -Wall will complain about enum values
252    * which do not appear, helping keep this function up-to-date.
253    * By using gcc -Wall -Werror, you can't forget.
254    *
255    * A table would not have the same benefit.  Most compilers will
256    * generate code very similar to a table in any case, so there
257    * is little performance gain from a table.  And something is broken
258    * for the user's application, anyways, so does it matter how fast
259    * it _doesn't_ work?
260    *
261    * The line number for the error will be near this comment, which
262    * is why it is here, and not at the start of the switch.
263    */
264   return "unknown error";
265 #else
266   if (error == CURLE_OK)
267     return "no error";
268   else
269     return "error";
270 #endif
271 }
272
273 const char *
274 curl_multi_strerror(CURLMcode error)
275 {
276 #ifndef CURL_DISABLE_VERBOSE_STRINGS
277   switch (error) {
278   case CURLM_CALL_MULTI_PERFORM:
279     return "please call curl_multi_perform() soon";
280
281   case CURLM_OK:
282     return "no error";
283
284   case CURLM_BAD_HANDLE:
285     return "invalid multi handle";
286
287   case CURLM_BAD_EASY_HANDLE:
288     return "invalid easy handle";
289
290   case CURLM_OUT_OF_MEMORY:
291     return "out of memory";
292
293   case CURLM_INTERNAL_ERROR:
294     return "internal error";
295
296   case CURLM_LAST:
297     break;
298   }
299
300   return "unknown error";
301 #else
302   if (error == CURLM_OK)
303     return "no error";
304   else
305     return "error";
306 #endif
307 }
308
309 const char *
310 curl_share_strerror(CURLSHcode error)
311 {
312 #ifndef CURL_DISABLE_VERBOSE_STRINGS
313   switch (error) {
314   case CURLSHE_OK:
315     return "no error";
316
317   case CURLSHE_BAD_OPTION:
318     return "unknown share option";
319
320   case CURLSHE_IN_USE:
321     return "share currently in use";
322
323   case CURLSHE_INVALID:
324     return "invalid share handle";
325
326   case CURLSHE_NOMEM:
327     return "out of memory";
328
329   case CURLSHE_LAST:
330     break;
331   }
332
333   return "CURLSH unknown";
334 #else
335   if (error == CURLSHE_OK)
336     return "no error";
337   else
338     return "error";
339 #endif
340 }
341
342 #if defined(WIN32) && !defined(__CYGWIN__)
343
344 /* This function handles most / all (?) Winsock errors cURL is able to produce.
345  */
346 static const char *
347 get_winsock_error (int err, char *buf, size_t len)
348 {
349   const char *p;
350
351 #ifndef CURL_DISABLE_VERBOSE_STRINGS
352   switch (err) {
353   case WSAEINTR:
354     p = "Call interrupted.";
355     break;
356   case WSAEBADF:
357     p = "Bad file";
358     break;
359   case WSAEACCES:
360     p = "Bad access";
361     break;
362   case WSAEFAULT:
363     p = "Bad argument";
364     break;
365   case WSAEINVAL:
366     p = "Invalid arguments";
367     break;
368   case WSAEMFILE:
369     p = "Out of file descriptors";
370     break;
371   case WSAEWOULDBLOCK:
372     p = "Call would block";
373     break;
374   case WSAEINPROGRESS:
375   case WSAEALREADY:
376     p = "Blocking call in progress";
377     break;
378   case WSAENOTSOCK:
379     p = "Descriptor is not a socket.";
380     break;
381   case WSAEDESTADDRREQ:
382     p = "Need destination address";
383     break;
384   case WSAEMSGSIZE:
385     p = "Bad message size";
386     break;
387   case WSAEPROTOTYPE:
388     p = "Bad protocol";
389     break;
390   case WSAENOPROTOOPT:
391     p = "Protocol option is unsupported";
392     break;
393   case WSAEPROTONOSUPPORT:
394     p = "Protocol is unsupported";
395     break;
396   case WSAESOCKTNOSUPPORT:
397     p = "Socket is unsupported";
398     break;
399   case WSAEOPNOTSUPP:
400     p = "Operation not supported";
401     break;
402   case WSAEAFNOSUPPORT:
403     p = "Address family not supported";
404     break;
405   case WSAEPFNOSUPPORT:
406     p = "Protocol family not supported";
407     break;
408   case WSAEADDRINUSE:
409     p = "Address already in use";
410     break;
411   case WSAEADDRNOTAVAIL:
412     p = "Address not available";
413     break;
414   case WSAENETDOWN:
415     p = "Network down";
416     break;
417   case WSAENETUNREACH:
418     p = "Network unreachable";
419     break;
420   case WSAENETRESET:
421     p = "Network has been reset";
422     break;
423   case WSAECONNABORTED:
424     p = "Connection was aborted";
425     break;
426   case WSAECONNRESET:
427     p = "Connection was reset";
428     break;
429   case WSAENOBUFS:
430     p = "No buffer space";
431     break;
432   case WSAEISCONN:
433     p = "Socket is already connected";
434     break;
435   case WSAENOTCONN:
436     p = "Socket is not connected";
437     break;
438   case WSAESHUTDOWN:
439     p = "Socket has been shut down";
440     break;
441   case WSAETOOMANYREFS:
442     p = "Too many references";
443     break;
444   case WSAETIMEDOUT:
445     p = "Timed out";
446     break;
447   case WSAECONNREFUSED:
448     p = "Connection refused";
449     break;
450   case WSAELOOP:
451     p = "Loop??";
452     break;
453   case WSAENAMETOOLONG:
454     p = "Name too long";
455     break;
456   case WSAEHOSTDOWN:
457     p = "Host down";
458     break;
459   case WSAEHOSTUNREACH:
460     p = "Host unreachable";
461     break;
462   case WSAENOTEMPTY:
463     p = "Not empty";
464     break;
465   case WSAEPROCLIM:
466     p = "Process limit reached";
467     break;
468   case WSAEUSERS:
469     p = "Too many users";
470     break;
471   case WSAEDQUOT:
472     p = "Bad quota";
473     break;
474   case WSAESTALE:
475     p = "Something is stale";
476     break;
477   case WSAEREMOTE:
478     p = "Remote error";
479     break;
480   case WSAEDISCON:
481     p = "Disconnected";
482     break;
483
484     /* Extended Winsock errors */
485   case WSASYSNOTREADY:
486     p = "Winsock library is not ready";
487     break;
488   case WSANOTINITIALISED:
489     p = "Winsock library not initalised";
490     break;
491   case WSAVERNOTSUPPORTED:
492     p = "Winsock version not supported.";
493     break;
494
495     /* getXbyY() errors (already handled in herrmsg):
496      * Authoritative Answer: Host not found */
497   case WSAHOST_NOT_FOUND:
498     p = "Host not found";
499     break;
500
501     /* Non-Authoritative: Host not found, or SERVERFAIL */
502   case WSATRY_AGAIN:
503     p = "Host not found, try again";
504     break;
505
506     /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
507   case WSANO_RECOVERY:
508     p = "Unrecoverable error in call to nameserver";
509     break;
510
511     /* Valid name, no data record of requested type */
512   case WSANO_DATA:
513     p = "No data record of requested type";
514     break;
515
516   default:
517     return NULL;
518   }
519 #else
520   if (error == CURLE_OK)
521     return NULL;
522   else
523     p = "error";
524 #endif
525   strncpy (buf, p, len);
526   buf [len-1] = '\0';
527   return buf;
528 }
529 #endif   /* WIN32 && !__CYGWIN__ */
530
531 /*
532  * Our thread-safe and smart strerror() replacement.
533  *
534  * The 'err' argument passed in to this function MUST be a true errno number
535  * as reported on this system. We do no range checking on the number before
536  * we pass it to the "number-to-message" convertion function and there might
537  * be systems that don't do proper range checking in there themselves.
538  *
539  * We don't do range checking (on systems other than Windows) since there is
540  * no good reliable and portable way to do it.
541  */
542 const char *Curl_strerror(struct connectdata *conn, int err)
543 {
544   char *buf, *p;
545   size_t max;
546
547   curlassert(conn);
548   curlassert(err >= 0);
549
550   buf = conn->syserr_buf;
551   max = sizeof(conn->syserr_buf)-1;
552   *buf = '\0';
553
554 #if defined(WIN32) && !defined(__CYGWIN__)
555
556 #ifdef _WIN32_WCE
557   buf[0]=0;
558   {
559     wchar_t wbuf[256];
560
561     FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err,
562                   LANG_NEUTRAL, wbuf, sizeof(wbuf)/sizeof(wchar_t), NULL);
563     wcstombs(buf,wbuf,max);
564   }
565
566 #else
567
568   /* 'sys_nerr' is the maximum errno number, it is not widely portable */
569   if (err >= 0 && err < sys_nerr)
570     strncpy(buf, strerror(err), max);
571   else {
572     if (!get_winsock_error(err, buf, max) &&
573         !FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err,
574                        LANG_NEUTRAL, buf, max, NULL))
575       snprintf(buf, max, "Unknown error %d (%#x)", err, err);
576   }
577 #endif
578 #else /* not native Windows coming up */
579
580   /* These should be atomic and hopefully thread-safe */
581 #ifdef HAVE_STRERROR_R
582   /* There are two different APIs for strerror_r(). The POSIX and the GLIBC
583      versions. */
584 #ifdef HAVE_POSIX_STRERROR_R
585   strerror_r(err, buf, max);
586   /* this may set errno to ERANGE if insufficient storage was supplied via
587      'strerrbuf' and 'buflen' to contain the generated message string, or
588      EINVAL if the value of 'errnum' is not a valid error number.*/
589 #else
590   {
591     /* HAVE_GLIBC_STRERROR_R */
592     char buffer[256];
593     char *msg = strerror_r(err, buffer, sizeof(buffer));
594     /* this version of strerror_r() only *might* use the buffer we pass to
595        the function, but it always returns the error message as a pointer,
596        so we must copy that string unconditionally */
597     strncpy(buf, msg, max);
598   }
599 #endif /* end of HAVE_GLIBC_STRERROR_R */
600 #else /* HAVE_STRERROR_R */
601   strncpy(buf, strerror(err), max);
602 #endif /* end of HAVE_STRERROR_R */
603 #endif /* end of ! Windows */
604
605   buf[max] = '\0'; /* make sure the string is zero terminated */
606
607   /* strip trailing '\r\n' or '\n'. */
608   if ((p = strrchr(buf,'\n')) != NULL && (p - buf) >= 2)
609      *p = '\0';
610   if ((p = strrchr(buf,'\r')) != NULL && (p - buf) >= 1)
611      *p = '\0';
612   return buf;
613 }
614
615 #ifdef USE_LIBIDN
616 /*
617  * Return error-string for libidn status as returned from idna_to_ascii_lz().
618  */
619 const char *Curl_idn_strerror (struct connectdata *conn, int err)
620 {
621 #ifdef HAVE_IDNA_STRERROR
622   (void)conn;
623   return idna_strerror((Idna_rc) err);
624 #else
625   const char *str;
626   char *buf;
627   size_t max;
628
629   curlassert(conn);
630
631   buf = conn->syserr_buf;
632   max = sizeof(conn->syserr_buf)-1;
633
634 #ifndef CURL_DISABLE_VERBOSE_STRINGS
635   switch ((Idna_rc)err) {
636     case IDNA_SUCCESS:
637       str = "No error";
638       break;
639     case IDNA_STRINGPREP_ERROR:
640       str = "Error in string preparation";
641       break;
642     case IDNA_PUNYCODE_ERROR:
643       str = "Error in Punycode operation";
644       break;
645     case IDNA_CONTAINS_NON_LDH:
646       str = "Illegal ASCII characters";
647       break;
648     case IDNA_CONTAINS_MINUS:
649       str = "Contains minus";
650       break;
651     case IDNA_INVALID_LENGTH:
652       str = "Invalid output length";
653       break;
654     case IDNA_NO_ACE_PREFIX:
655       str = "No ACE prefix (\"xn--\")";
656       break;
657     case IDNA_ROUNDTRIP_VERIFY_ERROR:
658       str = "Roundtrip verify error";
659       break;
660     case IDNA_CONTAINS_ACE_PREFIX:
661       str = "Already have ACE prefix (\"xn--\")";
662       break;
663     case IDNA_ICONV_ERROR:
664       str = "Locale conversion failed";
665       break;
666     case IDNA_MALLOC_ERROR:
667       str = "Allocation failed";
668       break;
669     case IDNA_DLOPEN_ERROR:
670       str = "dlopen() error";
671       break;
672     default:
673       snprintf(buf, max, "error %d", (int)err);
674       str = NULL;
675       break;
676   }
677 #else
678   if ((Idna_rc)err == IDNA_SUCCESS)
679     str = "No error";
680   else
681     str = "error";
682 #endif
683   if (str)
684     strncpy(buf, str, max);
685   buf[max] = '\0';
686   return (buf);
687 #endif
688 }
689 #endif  /* USE_LIBIDN */