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