win32 doesn't need and even doesn't build if we extern declare sys_nerr
[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 #include "strerror.h"
31
32 #define _MPRINTF_REPLACE /* use our functions only */
33 #include <curl/mprintf.h>
34
35 const char *
36 curl_easy_strerror(CURLcode error)
37 {
38   switch (error) {
39   case CURLE_OK:
40     return "no error";
41
42   case CURLE_UNSUPPORTED_PROTOCOL:
43     return "unsupported protocol";
44
45   case CURLE_FAILED_INIT:
46     return "failed init";
47
48   case CURLE_URL_MALFORMAT:
49     return "url malformat";
50
51   case CURLE_URL_MALFORMAT_USER:
52     return "url malformat user";
53
54   case CURLE_COULDNT_RESOLVE_PROXY:
55     return "couldnt resolve proxy";
56
57   case CURLE_COULDNT_RESOLVE_HOST:
58     return "couldnt resolve host";
59
60   case CURLE_COULDNT_CONNECT:
61     return "couldn't connect";
62
63   case CURLE_FTP_WEIRD_SERVER_REPLY:
64     return "ftp weird server reply";
65
66   case CURLE_FTP_ACCESS_DENIED:
67     return "ftp access denied";
68
69   case CURLE_FTP_USER_PASSWORD_INCORRECT:
70     return "ftp user password incorrect";
71
72   case CURLE_FTP_WEIRD_PASS_REPLY:
73     return "ftp weird pass reply";
74
75   case CURLE_FTP_WEIRD_USER_REPLY:
76     return "ftp weird user reply";
77
78   case CURLE_FTP_WEIRD_PASV_REPLY:
79     return "ftp weird pasv reply";
80
81   case CURLE_FTP_WEIRD_227_FORMAT:
82     return "ftp weird 227 format";
83
84   case CURLE_FTP_CANT_GET_HOST:
85     return "ftp cant get host";
86
87   case CURLE_FTP_CANT_RECONNECT:
88     return "ftp can't reconnect";
89
90   case CURLE_FTP_COULDNT_SET_BINARY:
91     return "ftp couldn't set binary";
92
93   case CURLE_PARTIAL_FILE:
94     return "partial file";
95
96   case CURLE_FTP_COULDNT_RETR_FILE:
97     return "ftp couldn't retr file";
98
99   case CURLE_FTP_WRITE_ERROR:
100     return "ftp write error";
101
102   case CURLE_FTP_QUOTE_ERROR:
103     return "ftp quote error";
104
105   case CURLE_HTTP_NOT_FOUND:
106     return "http not found";
107
108   case CURLE_WRITE_ERROR:
109     return "write error";
110
111   case CURLE_MALFORMAT_USER:
112     return "user name is illegally specified";
113
114   case CURLE_FTP_COULDNT_STOR_FILE:
115     return "failed FTP upload";
116
117   case CURLE_READ_ERROR:
118     return "could open/read from file";
119
120   case CURLE_OUT_OF_MEMORY:
121     return "out of memory";
122
123   case CURLE_OPERATION_TIMEOUTED:
124     return "the timeout time was reached";
125
126   case CURLE_FTP_COULDNT_SET_ASCII:
127     return "TYPE A failed";
128
129   case CURLE_FTP_PORT_FAILED:
130     return "FTP PORT operation failed";
131
132   case CURLE_FTP_COULDNT_USE_REST:
133     return "the REST command failed";
134
135   case CURLE_FTP_COULDNT_GET_SIZE:
136     return "the SIZE command failed";
137
138   case CURLE_HTTP_RANGE_ERROR:
139     return "RANGE \"command\" didn't work";
140
141   case CURLE_HTTP_POST_ERROR:
142     return "http post error";
143
144   case CURLE_SSL_CONNECT_ERROR:
145     return "wrong when connecting with SSL";
146
147   case CURLE_FTP_BAD_DOWNLOAD_RESUME:
148     return "couldn't resume download";
149
150   case CURLE_FILE_COULDNT_READ_FILE:
151     return "file couldn't read 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_LIBRARY_NOT_FOUND:
160     return "library not found";
161
162   case CURLE_FUNCTION_NOT_FOUND:
163     return "function not found";
164
165   case CURLE_ABORTED_BY_CALLBACK:
166     return "aborted by callback";
167
168   case CURLE_BAD_FUNCTION_ARGUMENT:
169     return "bad function argument";
170
171   case CURLE_BAD_CALLING_ORDER:
172     return "bad calling order";
173
174   case CURLE_HTTP_PORT_FAILED:
175     return "HTTP Interface operation failed";
176
177   case CURLE_BAD_PASSWORD_ENTERED:
178     return "my getpass() returns fail";
179
180   case CURLE_TOO_MANY_REDIRECTS :
181     return "catch endless re-direct loops";
182
183   case CURLE_UNKNOWN_TELNET_OPTION:
184     return "User specified an unknown option";
185
186   case CURLE_TELNET_OPTION_SYNTAX :
187     return "Malformed telnet option";
188
189   case CURLE_OBSOLETE:
190     return "obsolete";
191
192   case CURLE_SSL_PEER_CERTIFICATE:
193     return "peer's certificate wasn't ok";
194
195   case CURLE_GOT_NOTHING:
196     return "when this is a specific error";
197
198   case CURLE_SSL_ENGINE_NOTFOUND:
199     return "SSL crypto engine not found";
200
201   case CURLE_SSL_ENGINE_SETFAILED:
202     return "can not set SSL crypto engine as default";
203
204   case CURLE_SEND_ERROR:
205     return "failed sending network data";
206
207   case CURLE_RECV_ERROR:
208     return "failure in receiving network data";
209
210   case CURLE_SHARE_IN_USE:
211     return "CURLE_SHARE_IN_USER";
212
213   case CURLE_SSL_CERTPROBLEM:
214     return "problem with the local certificate";
215
216   case CURLE_SSL_CIPHER:
217     return "couldn't use specified cipher";
218
219   case CURLE_SSL_CACERT:
220     return "problem with the CA cert (path? access rights?)";
221
222   case CURLE_BAD_CONTENT_ENCODING:
223     return "Unrecognized transfer encoding";
224
225   case CURLE_LDAP_INVALID_URL:
226     return "Invalid LDAP URL";
227
228   case CURLE_FILESIZE_EXCEEDED:
229     return "Maximum file size exceeded";
230
231   case CURLE_FTP_SSL_FAILED:
232     return "Requested FTP SSL level failed";
233
234   case CURL_LAST:
235     break;
236   }
237   /*
238    * By using a switch, gcc -Wall will complain about enum values
239    * which do not appear, helping keep this function up-to-date.
240    * By using gcc -Wall -Werror, you can't forget.
241    *
242    * A table would not have the same benefit.  Most compilers will
243    * generate code very similar to a table in any case, so there
244    * is little performance gain from a table.  And something is broken
245    * for the user's application, anyways, so does it matter how fast
246    * it _doesn't_ work?
247    *
248    * The line number for the error will be near this comment, which
249    * is why it is here, and not at the start of the switch.
250    */
251   return "CURLcode unknown";
252 }
253
254 const char *
255 curl_multi_strerror(CURLMcode error)
256 {
257   switch (error)
258   {
259   case CURLM_CALL_MULTI_PERFORM:
260     return "please call curl_multi_perform() soon";
261
262   case CURLM_OK:
263     return "no error";
264
265   case CURLM_BAD_HANDLE:
266     return "CURLM not valid multi handle";
267
268   case CURLM_BAD_EASY_HANDLE:
269     return "CURLM not valid easy handle";
270
271   case CURLM_OUT_OF_MEMORY:
272     return "CURLM libcurl out of memory";
273
274   case CURLM_INTERNAL_ERROR:
275     return "CURLM libcurl internal bug";
276
277   case CURLM_LAST:
278     break;
279   }
280
281   return "CURLMcode unknown";
282 }
283
284 const char *
285 curl_share_strerror(CURLSHcode error)
286 {
287   switch (error)
288   {
289   case CURLSHE_OK:
290     return "no error";
291
292   case CURLSHE_BAD_OPTION:
293     return "CURLSH bad option";
294
295   case CURLSHE_IN_USE:
296     return "CURLSH in use";
297
298   case CURLSHE_INVALID:
299     return "CURLSH invalid";
300
301   case CURLSHE_LAST:
302     break;
303   }
304
305   return "CURLSH unknown";
306 }
307
308 #if defined(WIN32) && !defined(__CYGWIN__)
309
310 /* This function handles most / all (?) Winsock errors cURL is able to produce.
311  */
312 static const char *
313 get_winsock_error (int err, char *buf, size_t len)
314 {
315   char *p;
316
317   switch (err)
318   {
319     case WSAEINTR:
320         p = "Call interrupted.";
321         break;
322     case WSAEBADF:
323         p = "Bad file";
324         break;
325     case WSAEACCES:
326         p = "Bad access";
327         break;
328     case WSAEFAULT:
329         p = "Bad argument";
330         break;
331     case WSAEINVAL:
332         p = "Invalid arguments";
333         break;
334     case WSAEMFILE:
335         p = "Out of file descriptors";
336         break;
337     case WSAEWOULDBLOCK:
338         p = "Call would block";
339         break;
340     case WSAEINPROGRESS:
341     case WSAEALREADY:
342         p = "Blocking call in progress";
343         break;
344     case WSAENOTSOCK:
345         p = "Descriptor is not a socket.";
346         break;
347     case WSAEDESTADDRREQ:
348         p = "Need destination address";
349         break;
350     case WSAEMSGSIZE:
351         p = "Bad message size";
352         break;
353     case WSAEPROTOTYPE:
354         p = "Bad protocol";
355         break;
356     case WSAENOPROTOOPT:
357         p = "Protocol option is unsupported";
358         break;
359     case WSAEPROTONOSUPPORT:
360         p = "Protocol is unsupported";
361         break;
362     case WSAESOCKTNOSUPPORT:
363         p = "Socket is unsupported";
364         break;
365     case WSAEOPNOTSUPP:
366         p = "Operation not supported";
367         break;
368     case WSAEAFNOSUPPORT:
369         p = "Address family not supported";
370         break;
371     case WSAEPFNOSUPPORT:
372         p = "Protocol family not supported";
373         break;
374     case WSAEADDRINUSE:
375         p = "Address already in use";
376         break;
377     case WSAEADDRNOTAVAIL:
378         p = "Address not available";
379         break;
380     case WSAENETDOWN:
381         p = "Network down";
382         break;
383     case WSAENETUNREACH:
384         p = "Network unreachable";
385         break;
386     case WSAENETRESET:
387         p = "Network has been reset";
388         break;
389     case WSAECONNABORTED:
390         p = "Connection was aborted";
391         break;
392     case WSAECONNRESET:
393         p = "Connection was reset";
394         break;
395     case WSAENOBUFS:
396         p = "No buffer space";
397         break;
398     case WSAEISCONN:
399         p = "Socket is already connected";
400         break;
401     case WSAENOTCONN:
402         p = "Socket is not connected";
403         break;
404     case WSAESHUTDOWN:
405         p = "Socket has been shut down";
406         break;
407     case WSAETOOMANYREFS:
408         p = "Too many references";
409         break;
410     case WSAETIMEDOUT:
411         p = "Timed out";
412         break;
413     case WSAECONNREFUSED:
414         p = "Connection refused";
415         break;
416     case WSAELOOP:
417         p = "Loop??";
418         break;
419     case WSAENAMETOOLONG:
420         p = "Name too long";
421         break;
422     case WSAEHOSTDOWN:
423         p = "Host down";
424         break;
425     case WSAEHOSTUNREACH:
426         p = "Host unreachable";
427         break;
428     case WSAENOTEMPTY:
429         p = "Not empty";
430         break;
431     case WSAEPROCLIM:
432         p = "Process limit reached";
433         break;
434     case WSAEUSERS:
435         p = "Too many users";
436         break;
437     case WSAEDQUOT:
438         p = "Bad quota";
439         break;
440     case WSAESTALE:
441         p = "Something is stale";
442         break;
443     case WSAEREMOTE:
444         p = "Remote error";
445         break;
446     case WSAEDISCON:
447         p = "Disconnected";
448         break;
449
450     /* Extended Winsock errors */
451     case WSASYSNOTREADY:
452         p = "Winsock library is not ready";
453         break;
454     case WSANOTINITIALISED:
455         p = "Winsock library not initalised";
456         break;
457     case WSAVERNOTSUPPORTED:
458         p = "Winsock version not supported.";
459         break;
460
461     /* getXbyY() errors (already handled in herrmsg):
462      * Authoritative Answer: Host not found */
463     case WSAHOST_NOT_FOUND:
464         p = "Host not found";
465         break;
466
467     /* Non-Authoritative: Host not found, or SERVERFAIL */
468     case WSATRY_AGAIN:
469         p = "Host not found, try again";
470         break;
471
472     /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
473     case WSANO_RECOVERY:
474         p = "Unrecoverable error in call to nameserver";
475         break;
476
477     /* Valid name, no data record of requested type */
478     case WSANO_DATA:
479         p = "No data record of requested type";
480         break;
481
482     default:
483         return NULL;
484   }
485   strncpy (buf, p, len);
486   buf [len-1] = '\0';
487   return buf;
488 }
489 #endif   /* WIN32 && !__CYGWIN__ */
490
491 #ifndef WIN32
492 extern int sys_nerr;
493 #endif
494
495 /*
496  * Our thread-safe and smart strerror() replacement.
497  */
498 const char *Curl_strerror(struct connectdata *conn, int err)
499 {
500   char *buf, *p;
501   size_t max;
502
503   curlassert(conn);
504
505   buf = conn->syserr_buf;
506   max = sizeof(conn->syserr_buf)-1;
507   *buf = '\0';
508   if (err >= 0 && err < sys_nerr) {
509     /* These should be atomic and hopefully thread-safe */
510 #ifdef HAVE_STRERROR_R
511 #ifdef HAVE_POSIX_STRERROR_R
512     strerror_r(err, buf, max); 
513     /* this may set errno to ERANGE if insufficient storage was supplied via
514        strerrbuf and buflen to contain the generated message string, or EINVAL
515        if the value of errnum is not a valid error number.*/
516 #else
517     /* HAVE_GLIBC_STRERROR_R */
518     char buffer[256];
519     char *msg = strerror_r(err, buffer, sizeof(buffer));
520     strncpy(buf, msg, max);
521 #endif
522 #else
523     strncpy(buf, strerror(err), max);
524 #endif
525     *(buf+max) = '\0';
526   }
527   else
528 #if defined(WIN32) && !defined(__CYGWIN__)
529     if (!get_winsock_error (err, buf, max) &&
530         !FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, err,
531                         LANG_NEUTRAL, buf, max, NULL))
532 #endif
533      snprintf(buf, max, "Unknown error %d (%#x)", err, err);
534
535   /* strip trailing '\r\n' or '\n'. */
536   if ((p = strrchr(buf,'\n')) != NULL && (p - buf) >= 2)
537      *p = '\0';
538   if ((p = strrchr(buf,'\r')) != NULL && (p - buf) >= 1)
539      *p = '\0';
540   return buf;
541 }