VirtualBox

source: vbox/trunk/src/libs/curl-7.83.1/lib/strerror.c@ 97138

最後變更 在這個檔案從97138是 95312,由 vboxsync 提交於 3 年 前

libs/{curl,libxml2}: OSE export fixes, bugref:8515

  • 屬性 svn:eol-style 設為 native
檔案大小: 27.5 KB
 
1/***************************************************************************
2 * _ _ ____ _
3 * Project ___| | | | _ \| |
4 * / __| | | | |_) | |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
7 *
8 * Copyright (C) 2004 - 2022, Daniel Stenberg, <[email protected]>, 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 https://curl.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 "curl_setup.h"
24
25#ifdef HAVE_STRERROR_R
26# if (!defined(HAVE_POSIX_STRERROR_R) && \
27 !defined(HAVE_GLIBC_STRERROR_R)) || \
28 (defined(HAVE_POSIX_STRERROR_R) && defined(HAVE_GLIBC_STRERROR_R))
29# error "strerror_r MUST be either POSIX, glibc style"
30# endif
31#endif
32
33#include <curl/curl.h>
34
35#ifdef USE_LIBIDN2
36#include <idn2.h>
37#endif
38
39#ifdef USE_WINDOWS_SSPI
40#include "curl_sspi.h"
41#endif
42
43#include "strerror.h"
44/* The last 3 #include files should be in this order */
45#include "curl_printf.h"
46#include "curl_memory.h"
47#include "memdebug.h"
48
49#if defined(WIN32) || defined(_WIN32_WCE)
50#define PRESERVE_WINDOWS_ERROR_CODE
51#endif
52
53const char *
54curl_easy_strerror(CURLcode error)
55{
56#ifndef CURL_DISABLE_VERBOSE_STRINGS
57 switch(error) {
58 case CURLE_OK:
59 return "No error";
60
61 case CURLE_UNSUPPORTED_PROTOCOL:
62 return "Unsupported protocol";
63
64 case CURLE_FAILED_INIT:
65 return "Failed initialization";
66
67 case CURLE_URL_MALFORMAT:
68 return "URL using bad/illegal format or missing URL";
69
70 case CURLE_NOT_BUILT_IN:
71 return "A requested feature, protocol or option was not found built-in in"
72 " this libcurl due to a build-time decision.";
73
74 case CURLE_COULDNT_RESOLVE_PROXY:
75 return "Couldn't resolve proxy name";
76
77 case CURLE_COULDNT_RESOLVE_HOST:
78 return "Couldn't resolve host name";
79
80 case CURLE_COULDNT_CONNECT:
81 return "Couldn't connect to server";
82
83 case CURLE_WEIRD_SERVER_REPLY:
84 return "Weird server reply";
85
86 case CURLE_REMOTE_ACCESS_DENIED:
87 return "Access denied to remote resource";
88
89 case CURLE_FTP_ACCEPT_FAILED:
90 return "FTP: The server failed to connect to data port";
91
92 case CURLE_FTP_ACCEPT_TIMEOUT:
93 return "FTP: Accepting server connect has timed out";
94
95 case CURLE_FTP_PRET_FAILED:
96 return "FTP: The server did not accept the PRET command.";
97
98 case CURLE_FTP_WEIRD_PASS_REPLY:
99 return "FTP: unknown PASS reply";
100
101 case CURLE_FTP_WEIRD_PASV_REPLY:
102 return "FTP: unknown PASV reply";
103
104 case CURLE_FTP_WEIRD_227_FORMAT:
105 return "FTP: unknown 227 response format";
106
107 case CURLE_FTP_CANT_GET_HOST:
108 return "FTP: can't figure out the host in the PASV response";
109
110 case CURLE_HTTP2:
111 return "Error in the HTTP2 framing layer";
112
113 case CURLE_FTP_COULDNT_SET_TYPE:
114 return "FTP: couldn't set file type";
115
116 case CURLE_PARTIAL_FILE:
117 return "Transferred a partial file";
118
119 case CURLE_FTP_COULDNT_RETR_FILE:
120 return "FTP: couldn't retrieve (RETR failed) the specified file";
121
122 case CURLE_QUOTE_ERROR:
123 return "Quote command returned error";
124
125 case CURLE_HTTP_RETURNED_ERROR:
126 return "HTTP response code said error";
127
128 case CURLE_WRITE_ERROR:
129 return "Failed writing received data to disk/application";
130
131 case CURLE_UPLOAD_FAILED:
132 return "Upload failed (at start/before it took off)";
133
134 case CURLE_READ_ERROR:
135 return "Failed to open/read local data from file/application";
136
137 case CURLE_OUT_OF_MEMORY:
138 return "Out of memory";
139
140 case CURLE_OPERATION_TIMEDOUT:
141 return "Timeout was reached";
142
143 case CURLE_FTP_PORT_FAILED:
144 return "FTP: command PORT failed";
145
146 case CURLE_FTP_COULDNT_USE_REST:
147 return "FTP: command REST failed";
148
149 case CURLE_RANGE_ERROR:
150 return "Requested range was not delivered by the server";
151
152 case CURLE_HTTP_POST_ERROR:
153 return "Internal problem setting up the POST";
154
155 case CURLE_SSL_CONNECT_ERROR:
156 return "SSL connect error";
157
158 case CURLE_BAD_DOWNLOAD_RESUME:
159 return "Couldn't resume download";
160
161 case CURLE_FILE_COULDNT_READ_FILE:
162 return "Couldn't read a file:// file";
163
164 case CURLE_LDAP_CANNOT_BIND:
165 return "LDAP: cannot bind";
166
167 case CURLE_LDAP_SEARCH_FAILED:
168 return "LDAP: search failed";
169
170 case CURLE_FUNCTION_NOT_FOUND:
171 return "A required function in the library was not found";
172
173 case CURLE_ABORTED_BY_CALLBACK:
174 return "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_OPTION:
186 return "An unknown option was passed in to libcurl";
187
188 case CURLE_SETOPT_OPTION_SYNTAX :
189 return "Malformed option provided in a setopt";
190
191 case CURLE_GOT_NOTHING:
192 return "Server returned nothing (no headers, no data)";
193
194 case CURLE_SSL_ENGINE_NOTFOUND:
195 return "SSL crypto engine not found";
196
197 case CURLE_SSL_ENGINE_SETFAILED:
198 return "Can not set SSL crypto engine as default";
199
200 case CURLE_SSL_ENGINE_INITFAILED:
201 return "Failed to initialise SSL crypto engine";
202
203 case CURLE_SEND_ERROR:
204 return "Failed sending data to the peer";
205
206 case CURLE_RECV_ERROR:
207 return "Failure when receiving data from the peer";
208
209 case CURLE_SSL_CERTPROBLEM:
210 return "Problem with the local SSL certificate";
211
212 case CURLE_SSL_CIPHER:
213 return "Couldn't use specified SSL cipher";
214
215 case CURLE_PEER_FAILED_VERIFICATION:
216 return "SSL peer certificate or SSH remote key was not OK";
217
218 case CURLE_SSL_CACERT_BADFILE:
219 return "Problem with the SSL CA cert (path? access rights?)";
220
221 case CURLE_BAD_CONTENT_ENCODING:
222 return "Unrecognized or bad HTTP Content or Transfer-Encoding";
223
224 case CURLE_FILESIZE_EXCEEDED:
225 return "Maximum file size exceeded";
226
227 case CURLE_USE_SSL_FAILED:
228 return "Requested SSL level failed";
229
230 case CURLE_SSL_SHUTDOWN_FAILED:
231 return "Failed to shut down the SSL connection";
232
233 case CURLE_SSL_CRL_BADFILE:
234 return "Failed to load CRL file (path? access rights?, format?)";
235
236 case CURLE_SSL_ISSUER_ERROR:
237 return "Issuer check against peer certificate failed";
238
239 case CURLE_SEND_FAIL_REWIND:
240 return "Send failed since rewinding of the data stream failed";
241
242 case CURLE_LOGIN_DENIED:
243 return "Login denied";
244
245 case CURLE_TFTP_NOTFOUND:
246 return "TFTP: File Not Found";
247
248 case CURLE_TFTP_PERM:
249 return "TFTP: Access Violation";
250
251 case CURLE_REMOTE_DISK_FULL:
252 return "Disk full or allocation exceeded";
253
254 case CURLE_TFTP_ILLEGAL:
255 return "TFTP: Illegal operation";
256
257 case CURLE_TFTP_UNKNOWNID:
258 return "TFTP: Unknown transfer ID";
259
260 case CURLE_REMOTE_FILE_EXISTS:
261 return "Remote file already exists";
262
263 case CURLE_TFTP_NOSUCHUSER:
264 return "TFTP: No such user";
265
266 case CURLE_CONV_FAILED:
267 return "Conversion failed";
268
269 case CURLE_REMOTE_FILE_NOT_FOUND:
270 return "Remote file not found";
271
272 case CURLE_SSH:
273 return "Error in the SSH layer";
274
275 case CURLE_AGAIN:
276 return "Socket not ready for send/recv";
277
278 case CURLE_RTSP_CSEQ_ERROR:
279 return "RTSP CSeq mismatch or invalid CSeq";
280
281 case CURLE_RTSP_SESSION_ERROR:
282 return "RTSP session error";
283
284 case CURLE_FTP_BAD_FILE_LIST:
285 return "Unable to parse FTP file list";
286
287 case CURLE_CHUNK_FAILED:
288 return "Chunk callback failed";
289
290 case CURLE_NO_CONNECTION_AVAILABLE:
291 return "The max connection limit is reached";
292
293 case CURLE_SSL_PINNEDPUBKEYNOTMATCH:
294 return "SSL public key does not match pinned public key";
295
296 case CURLE_SSL_INVALIDCERTSTATUS:
297 return "SSL server certificate status verification FAILED";
298
299 case CURLE_HTTP2_STREAM:
300 return "Stream error in the HTTP/2 framing layer";
301
302 case CURLE_RECURSIVE_API_CALL:
303 return "API function called from within callback";
304
305 case CURLE_AUTH_ERROR:
306 return "An authentication function returned an error";
307
308 case CURLE_HTTP3:
309 return "HTTP/3 error";
310
311 case CURLE_QUIC_CONNECT_ERROR:
312 return "QUIC connection error";
313
314 case CURLE_PROXY:
315 return "proxy handshake error";
316
317 case CURLE_SSL_CLIENTCERT:
318 return "SSL Client Certificate required";
319
320 /* error codes not used by current libcurl */
321 case CURLE_OBSOLETE20:
322 case CURLE_OBSOLETE24:
323 case CURLE_OBSOLETE29:
324 case CURLE_OBSOLETE32:
325 case CURLE_OBSOLETE40:
326 case CURLE_OBSOLETE44:
327 case CURLE_OBSOLETE46:
328 case CURLE_OBSOLETE50:
329 case CURLE_OBSOLETE51:
330 case CURLE_OBSOLETE57:
331 case CURLE_OBSOLETE62:
332 case CURLE_OBSOLETE76:
333 case CURL_LAST:
334 break;
335 }
336 /*
337 * By using a switch, gcc -Wall will complain about enum values
338 * which do not appear, helping keep this function up-to-date.
339 * By using gcc -Wall -Werror, you can't forget.
340 *
341 * A table would not have the same benefit. Most compilers will
342 * generate code very similar to a table in any case, so there
343 * is little performance gain from a table. And something is broken
344 * for the user's application, anyways, so does it matter how fast
345 * it _doesn't_ work?
346 *
347 * The line number for the error will be near this comment, which
348 * is why it is here, and not at the start of the switch.
349 */
350 return "Unknown error";
351#else
352 if(!error)
353 return "No error";
354 else
355 return "Error";
356#endif
357}
358
359const char *
360curl_multi_strerror(CURLMcode error)
361{
362#ifndef CURL_DISABLE_VERBOSE_STRINGS
363 switch(error) {
364 case CURLM_CALL_MULTI_PERFORM:
365 return "Please call curl_multi_perform() soon";
366
367 case CURLM_OK:
368 return "No error";
369
370 case CURLM_BAD_HANDLE:
371 return "Invalid multi handle";
372
373 case CURLM_BAD_EASY_HANDLE:
374 return "Invalid easy handle";
375
376 case CURLM_OUT_OF_MEMORY:
377 return "Out of memory";
378
379 case CURLM_INTERNAL_ERROR:
380 return "Internal error";
381
382 case CURLM_BAD_SOCKET:
383 return "Invalid socket argument";
384
385 case CURLM_UNKNOWN_OPTION:
386 return "Unknown option";
387
388 case CURLM_ADDED_ALREADY:
389 return "The easy handle is already added to a multi handle";
390
391 case CURLM_RECURSIVE_API_CALL:
392 return "API function called from within callback";
393
394 case CURLM_WAKEUP_FAILURE:
395 return "Wakeup is unavailable or failed";
396
397 case CURLM_BAD_FUNCTION_ARGUMENT:
398 return "A libcurl function was given a bad argument";
399
400 case CURLM_ABORTED_BY_CALLBACK:
401 return "Operation was aborted by an application callback";
402
403 case CURLM_LAST:
404 break;
405 }
406
407 return "Unknown error";
408#else
409 if(error == CURLM_OK)
410 return "No error";
411 else
412 return "Error";
413#endif
414}
415
416const char *
417curl_share_strerror(CURLSHcode error)
418{
419#ifndef CURL_DISABLE_VERBOSE_STRINGS
420 switch(error) {
421 case CURLSHE_OK:
422 return "No error";
423
424 case CURLSHE_BAD_OPTION:
425 return "Unknown share option";
426
427 case CURLSHE_IN_USE:
428 return "Share currently in use";
429
430 case CURLSHE_INVALID:
431 return "Invalid share handle";
432
433 case CURLSHE_NOMEM:
434 return "Out of memory";
435
436 case CURLSHE_NOT_BUILT_IN:
437 return "Feature not enabled in this library";
438
439 case CURLSHE_LAST:
440 break;
441 }
442
443 return "CURLSHcode unknown";
444#else
445 if(error == CURLSHE_OK)
446 return "No error";
447 else
448 return "Error";
449#endif
450}
451
452const char *
453curl_url_strerror(CURLUcode error)
454{
455#ifndef CURL_DISABLE_VERBOSE_STRINGS
456 switch(error) {
457 case CURLUE_OK:
458 return "No error";
459
460 case CURLUE_BAD_HANDLE:
461 return "An invalid CURLU pointer was passed as argument";
462
463 case CURLUE_BAD_PARTPOINTER:
464 return "An invalid 'part' argument was passed as argument";
465
466 case CURLUE_MALFORMED_INPUT:
467 return "Malformed input to a URL function";
468
469 case CURLUE_BAD_PORT_NUMBER:
470 return "Port number was not a decimal number between 0 and 65535";
471
472 case CURLUE_UNSUPPORTED_SCHEME:
473 return "This libcurl build doesn't support the given URL scheme";
474
475 case CURLUE_URLDECODE:
476 return "URL decode error, most likely because of rubbish in the input";
477
478 case CURLUE_OUT_OF_MEMORY:
479 return "A memory function failed";
480
481 case CURLUE_USER_NOT_ALLOWED:
482 return "Credentials was passed in the URL when prohibited";
483
484 case CURLUE_UNKNOWN_PART:
485 return "An unknown part ID was passed to a URL API function";
486
487 case CURLUE_NO_SCHEME:
488 return "No scheme part in the URL";
489
490 case CURLUE_NO_USER:
491 return "No user part in the URL";
492
493 case CURLUE_NO_PASSWORD:
494 return "No password part in the URL";
495
496 case CURLUE_NO_OPTIONS:
497 return "No options part in the URL";
498
499 case CURLUE_NO_HOST:
500 return "No host part in the URL";
501
502 case CURLUE_NO_PORT:
503 return "No port part in the URL";
504
505 case CURLUE_NO_QUERY:
506 return "No query part in the URL";
507
508 case CURLUE_NO_FRAGMENT:
509 return "No fragment part in the URL";
510
511 case CURLUE_NO_ZONEID:
512 return "No zoneid part in the URL";
513
514 case CURLUE_BAD_LOGIN:
515 return "Bad login part";
516
517 case CURLUE_BAD_IPV6:
518 return "Bad IPv6 address";
519
520 case CURLUE_BAD_HOSTNAME:
521 return "Bad hostname";
522
523 case CURLUE_BAD_FILE_URL:
524 return "Bad file:// URL";
525
526 case CURLUE_BAD_SLASHES:
527 return "Unsupported number of slashes";
528
529 case CURLUE_BAD_SCHEME:
530 return "Bad scheme";
531
532 case CURLUE_BAD_PATH:
533 return "Bad path";
534
535 case CURLUE_BAD_FRAGMENT:
536 return "Bad fragment";
537
538 case CURLUE_BAD_QUERY:
539 return "Bad query";
540
541 case CURLUE_BAD_PASSWORD:
542 return "Bad password";
543
544 case CURLUE_BAD_USER:
545 return "Bad user";
546
547 case CURLUE_LAST:
548 break;
549 }
550
551 return "CURLUcode unknown";
552#else
553 if(error == CURLUE_OK)
554 return "No error";
555 else
556 return "Error";
557#endif
558}
559
560#ifdef USE_WINSOCK
561/* This is a helper function for Curl_strerror that converts Winsock error
562 * codes (WSAGetLastError) to error messages.
563 * Returns NULL if no error message was found for error code.
564 */
565static const char *
566get_winsock_error (int err, char *buf, size_t len)
567{
568#ifndef CURL_DISABLE_VERBOSE_STRINGS
569 const char *p;
570#endif
571
572 if(!len)
573 return NULL;
574
575 *buf = '\0';
576
577#ifdef CURL_DISABLE_VERBOSE_STRINGS
578 (void)err;
579 return NULL;
580#else
581 switch(err) {
582 case WSAEINTR:
583 p = "Call interrupted";
584 break;
585 case WSAEBADF:
586 p = "Bad file";
587 break;
588 case WSAEACCES:
589 p = "Bad access";
590 break;
591 case WSAEFAULT:
592 p = "Bad argument";
593 break;
594 case WSAEINVAL:
595 p = "Invalid arguments";
596 break;
597 case WSAEMFILE:
598 p = "Out of file descriptors";
599 break;
600 case WSAEWOULDBLOCK:
601 p = "Call would block";
602 break;
603 case WSAEINPROGRESS:
604 case WSAEALREADY:
605 p = "Blocking call in progress";
606 break;
607 case WSAENOTSOCK:
608 p = "Descriptor is not a socket";
609 break;
610 case WSAEDESTADDRREQ:
611 p = "Need destination address";
612 break;
613 case WSAEMSGSIZE:
614 p = "Bad message size";
615 break;
616 case WSAEPROTOTYPE:
617 p = "Bad protocol";
618 break;
619 case WSAENOPROTOOPT:
620 p = "Protocol option is unsupported";
621 break;
622 case WSAEPROTONOSUPPORT:
623 p = "Protocol is unsupported";
624 break;
625 case WSAESOCKTNOSUPPORT:
626 p = "Socket is unsupported";
627 break;
628 case WSAEOPNOTSUPP:
629 p = "Operation not supported";
630 break;
631 case WSAEAFNOSUPPORT:
632 p = "Address family not supported";
633 break;
634 case WSAEPFNOSUPPORT:
635 p = "Protocol family not supported";
636 break;
637 case WSAEADDRINUSE:
638 p = "Address already in use";
639 break;
640 case WSAEADDRNOTAVAIL:
641 p = "Address not available";
642 break;
643 case WSAENETDOWN:
644 p = "Network down";
645 break;
646 case WSAENETUNREACH:
647 p = "Network unreachable";
648 break;
649 case WSAENETRESET:
650 p = "Network has been reset";
651 break;
652 case WSAECONNABORTED:
653 p = "Connection was aborted";
654 break;
655 case WSAECONNRESET:
656 p = "Connection was reset";
657 break;
658 case WSAENOBUFS:
659 p = "No buffer space";
660 break;
661 case WSAEISCONN:
662 p = "Socket is already connected";
663 break;
664 case WSAENOTCONN:
665 p = "Socket is not connected";
666 break;
667 case WSAESHUTDOWN:
668 p = "Socket has been shut down";
669 break;
670 case WSAETOOMANYREFS:
671 p = "Too many references";
672 break;
673 case WSAETIMEDOUT:
674 p = "Timed out";
675 break;
676 case WSAECONNREFUSED:
677 p = "Connection refused";
678 break;
679 case WSAELOOP:
680 p = "Loop??";
681 break;
682 case WSAENAMETOOLONG:
683 p = "Name too long";
684 break;
685 case WSAEHOSTDOWN:
686 p = "Host down";
687 break;
688 case WSAEHOSTUNREACH:
689 p = "Host unreachable";
690 break;
691 case WSAENOTEMPTY:
692 p = "Not empty";
693 break;
694 case WSAEPROCLIM:
695 p = "Process limit reached";
696 break;
697 case WSAEUSERS:
698 p = "Too many users";
699 break;
700 case WSAEDQUOT:
701 p = "Bad quota";
702 break;
703 case WSAESTALE:
704 p = "Something is stale";
705 break;
706 case WSAEREMOTE:
707 p = "Remote error";
708 break;
709#ifdef WSAEDISCON /* missing in SalfordC! */
710 case WSAEDISCON:
711 p = "Disconnected";
712 break;
713#endif
714 /* Extended Winsock errors */
715 case WSASYSNOTREADY:
716 p = "Winsock library is not ready";
717 break;
718 case WSANOTINITIALISED:
719 p = "Winsock library not initialised";
720 break;
721 case WSAVERNOTSUPPORTED:
722 p = "Winsock version not supported";
723 break;
724
725 /* getXbyY() errors (already handled in herrmsg):
726 * Authoritative Answer: Host not found */
727 case WSAHOST_NOT_FOUND:
728 p = "Host not found";
729 break;
730
731 /* Non-Authoritative: Host not found, or SERVERFAIL */
732 case WSATRY_AGAIN:
733 p = "Host not found, try again";
734 break;
735
736 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
737 case WSANO_RECOVERY:
738 p = "Unrecoverable error in call to nameserver";
739 break;
740
741 /* Valid name, no data record of requested type */
742 case WSANO_DATA:
743 p = "No data record of requested type";
744 break;
745
746 default:
747 return NULL;
748 }
749 strncpy(buf, p, len);
750 buf [len-1] = '\0';
751 return buf;
752#endif
753}
754#endif /* USE_WINSOCK */
755
756#if defined(WIN32) || defined(_WIN32_WCE)
757/* This is a helper function for Curl_strerror that converts Windows API error
758 * codes (GetLastError) to error messages.
759 * Returns NULL if no error message was found for error code.
760 */
761static const char *
762get_winapi_error(int err, char *buf, size_t buflen)
763{
764 char *p;
765 wchar_t wbuf[256];
766
767 if(!buflen)
768 return NULL;
769
770 *buf = '\0';
771 *wbuf = L'\0';
772
773 /* We return the local codepage version of the error string because if it is
774 output to the user's terminal it will likely be with functions which
775 expect the local codepage (eg fprintf, failf, infof).
776 FormatMessageW -> wcstombs is used for Windows CE compatibility. */
777 if(FormatMessageW((FORMAT_MESSAGE_FROM_SYSTEM |
778 FORMAT_MESSAGE_IGNORE_INSERTS), NULL, err,
779 LANG_NEUTRAL, wbuf, sizeof(wbuf)/sizeof(wchar_t), NULL)) {
780 size_t written = wcstombs(buf, wbuf, buflen - 1);
781 if(written != (size_t)-1)
782 buf[written] = '\0';
783 else
784 *buf = '\0';
785 }
786
787 /* Truncate multiple lines */
788 p = strchr(buf, '\n');
789 if(p) {
790 if(p > buf && *(p-1) == '\r')
791 *(p-1) = '\0';
792 else
793 *p = '\0';
794 }
795
796 return (*buf ? buf : NULL);
797}
798#endif /* WIN32 || _WIN32_WCE */
799
800/*
801 * Our thread-safe and smart strerror() replacement.
802 *
803 * The 'err' argument passed in to this function MUST be a true errno number
804 * as reported on this system. We do no range checking on the number before
805 * we pass it to the "number-to-message" conversion function and there might
806 * be systems that don't do proper range checking in there themselves.
807 *
808 * We don't do range checking (on systems other than Windows) since there is
809 * no good reliable and portable way to do it.
810 *
811 * On Windows different types of error codes overlap. This function has an
812 * order of preference when trying to match error codes:
813 * CRT (errno), Winsock (WSAGetLastError), Windows API (GetLastError).
814 *
815 * It may be more correct to call one of the variant functions instead:
816 * Call Curl_sspi_strerror if the error code is definitely Windows SSPI.
817 * Call Curl_winapi_strerror if the error code is definitely Windows API.
818 */
819const char *Curl_strerror(int err, char *buf, size_t buflen)
820{
821#ifdef PRESERVE_WINDOWS_ERROR_CODE
822 DWORD old_win_err = GetLastError();
823#endif
824 int old_errno = errno;
825 char *p;
826 size_t max;
827
828 if(!buflen)
829 return NULL;
830
831#ifndef WIN32
832 DEBUGASSERT(err >= 0);
833#endif
834
835 max = buflen - 1;
836 *buf = '\0';
837
838#if defined(WIN32) || defined(_WIN32_WCE)
839#if defined(WIN32)
840 /* 'sys_nerr' is the maximum errno number, it is not widely portable */
841 if(err >= 0 && err < sys_nerr)
842 strncpy(buf, sys_errlist[err], max);
843 else
844#endif
845 {
846 if(
847#ifdef USE_WINSOCK
848 !get_winsock_error(err, buf, max) &&
849#endif
850 !get_winapi_error((DWORD)err, buf, max))
851 msnprintf(buf, max, "Unknown error %d (%#x)", err, err);
852 }
853#else /* not Windows coming up */
854
855#if defined(HAVE_STRERROR_R) && defined(HAVE_POSIX_STRERROR_R)
856 /*
857 * The POSIX-style strerror_r() may set errno to ERANGE if insufficient
858 * storage is supplied via 'strerrbuf' and 'buflen' to hold the generated
859 * message string, or EINVAL if 'errnum' is not a valid error number.
860 */
861 if(0 != strerror_r(err, buf, max)) {
862 if('\0' == buf[0])
863 msnprintf(buf, max, "Unknown error %d", err);
864 }
865#elif defined(HAVE_STRERROR_R) && defined(HAVE_GLIBC_STRERROR_R)
866 /*
867 * The glibc-style strerror_r() only *might* use the buffer we pass to
868 * the function, but it always returns the error message as a pointer,
869 * so we must copy that string unconditionally (if non-NULL).
870 */
871 {
872 char buffer[256];
873 char *msg = strerror_r(err, buffer, sizeof(buffer));
874 if(msg)
875 strncpy(buf, msg, max);
876 else
877 msnprintf(buf, max, "Unknown error %d", err);
878 }
879#else
880 {
881 /* !checksrc! disable STRERROR 1 */
882 const char *msg = strerror(err);
883 if(msg)
884 strncpy(buf, msg, max);
885 else
886 msnprintf(buf, max, "Unknown error %d", err);
887 }
888#endif
889
890#endif /* end of not Windows */
891
892 buf[max] = '\0'; /* make sure the string is null-terminated */
893
894 /* strip trailing '\r\n' or '\n'. */
895 p = strrchr(buf, '\n');
896 if(p && (p - buf) >= 2)
897 *p = '\0';
898 p = strrchr(buf, '\r');
899 if(p && (p - buf) >= 1)
900 *p = '\0';
901
902 if(errno != old_errno)
903 errno = old_errno;
904
905#ifdef PRESERVE_WINDOWS_ERROR_CODE
906 if(old_win_err != GetLastError())
907 SetLastError(old_win_err);
908#endif
909
910 return buf;
911}
912
913/*
914 * Curl_winapi_strerror:
915 * Variant of Curl_strerror if the error code is definitely Windows API.
916 */
917#if defined(WIN32) || defined(_WIN32_WCE)
918const char *Curl_winapi_strerror(DWORD err, char *buf, size_t buflen)
919{
920#ifdef PRESERVE_WINDOWS_ERROR_CODE
921 DWORD old_win_err = GetLastError();
922#endif
923 int old_errno = errno;
924
925 if(!buflen)
926 return NULL;
927
928 *buf = '\0';
929
930#ifndef CURL_DISABLE_VERBOSE_STRINGS
931 if(!get_winapi_error(err, buf, buflen)) {
932 msnprintf(buf, buflen, "Unknown error %u (0x%08X)", err, err);
933 }
934#else
935 {
936 const char *txt = (err == ERROR_SUCCESS) ? "No error" : "Error";
937 strncpy(buf, txt, buflen);
938 buf[buflen - 1] = '\0';
939 }
940#endif
941
942 if(errno != old_errno)
943 errno = old_errno;
944
945#ifdef PRESERVE_WINDOWS_ERROR_CODE
946 if(old_win_err != GetLastError())
947 SetLastError(old_win_err);
948#endif
949
950 return buf;
951}
952#endif /* WIN32 || _WIN32_WCE */
953
954#ifdef USE_WINDOWS_SSPI
955/*
956 * Curl_sspi_strerror:
957 * Variant of Curl_strerror if the error code is definitely Windows SSPI.
958 */
959const char *Curl_sspi_strerror(int err, char *buf, size_t buflen)
960{
961#ifdef PRESERVE_WINDOWS_ERROR_CODE
962 DWORD old_win_err = GetLastError();
963#endif
964 int old_errno = errno;
965 const char *txt;
966
967 if(!buflen)
968 return NULL;
969
970 *buf = '\0';
971
972#ifndef CURL_DISABLE_VERBOSE_STRINGS
973
974 switch(err) {
975 case SEC_E_OK:
976 txt = "No error";
977 break;
978#define SEC2TXT(sec) case sec: txt = #sec; break
979 SEC2TXT(CRYPT_E_REVOKED);
980 SEC2TXT(SEC_E_ALGORITHM_MISMATCH);
981 SEC2TXT(SEC_E_BAD_BINDINGS);
982 SEC2TXT(SEC_E_BAD_PKGID);
983 SEC2TXT(SEC_E_BUFFER_TOO_SMALL);
984 SEC2TXT(SEC_E_CANNOT_INSTALL);
985 SEC2TXT(SEC_E_CANNOT_PACK);
986 SEC2TXT(SEC_E_CERT_EXPIRED);
987 SEC2TXT(SEC_E_CERT_UNKNOWN);
988 SEC2TXT(SEC_E_CERT_WRONG_USAGE);
989 SEC2TXT(SEC_E_CONTEXT_EXPIRED);
990 SEC2TXT(SEC_E_CROSSREALM_DELEGATION_FAILURE);
991 SEC2TXT(SEC_E_CRYPTO_SYSTEM_INVALID);
992 SEC2TXT(SEC_E_DECRYPT_FAILURE);
993 SEC2TXT(SEC_E_DELEGATION_POLICY);
994 SEC2TXT(SEC_E_DELEGATION_REQUIRED);
995 SEC2TXT(SEC_E_DOWNGRADE_DETECTED);
996 SEC2TXT(SEC_E_ENCRYPT_FAILURE);
997 SEC2TXT(SEC_E_ILLEGAL_MESSAGE);
998 SEC2TXT(SEC_E_INCOMPLETE_CREDENTIALS);
999 SEC2TXT(SEC_E_INCOMPLETE_MESSAGE);
1000 SEC2TXT(SEC_E_INSUFFICIENT_MEMORY);
1001 SEC2TXT(SEC_E_INTERNAL_ERROR);
1002 SEC2TXT(SEC_E_INVALID_HANDLE);
1003 SEC2TXT(SEC_E_INVALID_PARAMETER);
1004 SEC2TXT(SEC_E_INVALID_TOKEN);
1005 SEC2TXT(SEC_E_ISSUING_CA_UNTRUSTED);
1006 SEC2TXT(SEC_E_ISSUING_CA_UNTRUSTED_KDC);
1007 SEC2TXT(SEC_E_KDC_CERT_EXPIRED);
1008 SEC2TXT(SEC_E_KDC_CERT_REVOKED);
1009 SEC2TXT(SEC_E_KDC_INVALID_REQUEST);
1010 SEC2TXT(SEC_E_KDC_UNABLE_TO_REFER);
1011 SEC2TXT(SEC_E_KDC_UNKNOWN_ETYPE);
1012 SEC2TXT(SEC_E_LOGON_DENIED);
1013 SEC2TXT(SEC_E_MAX_REFERRALS_EXCEEDED);
1014 SEC2TXT(SEC_E_MESSAGE_ALTERED);
1015 SEC2TXT(SEC_E_MULTIPLE_ACCOUNTS);
1016 SEC2TXT(SEC_E_MUST_BE_KDC);
1017 SEC2TXT(SEC_E_NOT_OWNER);
1018 SEC2TXT(SEC_E_NO_AUTHENTICATING_AUTHORITY);
1019 SEC2TXT(SEC_E_NO_CREDENTIALS);
1020 SEC2TXT(SEC_E_NO_IMPERSONATION);
1021 SEC2TXT(SEC_E_NO_IP_ADDRESSES);
1022 SEC2TXT(SEC_E_NO_KERB_KEY);
1023 SEC2TXT(SEC_E_NO_PA_DATA);
1024 SEC2TXT(SEC_E_NO_S4U_PROT_SUPPORT);
1025 SEC2TXT(SEC_E_NO_TGT_REPLY);
1026 SEC2TXT(SEC_E_OUT_OF_SEQUENCE);
1027 SEC2TXT(SEC_E_PKINIT_CLIENT_FAILURE);
1028 SEC2TXT(SEC_E_PKINIT_NAME_MISMATCH);
1029 SEC2TXT(SEC_E_POLICY_NLTM_ONLY);
1030 SEC2TXT(SEC_E_QOP_NOT_SUPPORTED);
1031 SEC2TXT(SEC_E_REVOCATION_OFFLINE_C);
1032 SEC2TXT(SEC_E_REVOCATION_OFFLINE_KDC);
1033 SEC2TXT(SEC_E_SECPKG_NOT_FOUND);
1034 SEC2TXT(SEC_E_SECURITY_QOS_FAILED);
1035 SEC2TXT(SEC_E_SHUTDOWN_IN_PROGRESS);
1036 SEC2TXT(SEC_E_SMARTCARD_CERT_EXPIRED);
1037 SEC2TXT(SEC_E_SMARTCARD_CERT_REVOKED);
1038 SEC2TXT(SEC_E_SMARTCARD_LOGON_REQUIRED);
1039 SEC2TXT(SEC_E_STRONG_CRYPTO_NOT_SUPPORTED);
1040 SEC2TXT(SEC_E_TARGET_UNKNOWN);
1041 SEC2TXT(SEC_E_TIME_SKEW);
1042 SEC2TXT(SEC_E_TOO_MANY_PRINCIPALS);
1043 SEC2TXT(SEC_E_UNFINISHED_CONTEXT_DELETED);
1044 SEC2TXT(SEC_E_UNKNOWN_CREDENTIALS);
1045 SEC2TXT(SEC_E_UNSUPPORTED_FUNCTION);
1046 SEC2TXT(SEC_E_UNSUPPORTED_PREAUTH);
1047 SEC2TXT(SEC_E_UNTRUSTED_ROOT);
1048 SEC2TXT(SEC_E_WRONG_CREDENTIAL_HANDLE);
1049 SEC2TXT(SEC_E_WRONG_PRINCIPAL);
1050 SEC2TXT(SEC_I_COMPLETE_AND_CONTINUE);
1051 SEC2TXT(SEC_I_COMPLETE_NEEDED);
1052 SEC2TXT(SEC_I_CONTEXT_EXPIRED);
1053 SEC2TXT(SEC_I_CONTINUE_NEEDED);
1054 SEC2TXT(SEC_I_INCOMPLETE_CREDENTIALS);
1055 SEC2TXT(SEC_I_LOCAL_LOGON);
1056 SEC2TXT(SEC_I_NO_LSA_CONTEXT);
1057 SEC2TXT(SEC_I_RENEGOTIATE);
1058 SEC2TXT(SEC_I_SIGNATURE_NEEDED);
1059 default:
1060 txt = "Unknown error";
1061 }
1062
1063 if(err == SEC_E_ILLEGAL_MESSAGE) {
1064 msnprintf(buf, buflen,
1065 "SEC_E_ILLEGAL_MESSAGE (0x%08X) - This error usually occurs "
1066 "when a fatal SSL/TLS alert is received (e.g. handshake failed)."
1067 " More detail may be available in the Windows System event log.",
1068 err);
1069 }
1070 else {
1071 char txtbuf[80];
1072 char msgbuf[256];
1073
1074 msnprintf(txtbuf, sizeof(txtbuf), "%s (0x%08X)", txt, err);
1075
1076 if(get_winapi_error(err, msgbuf, sizeof(msgbuf)))
1077 msnprintf(buf, buflen, "%s - %s", txtbuf, msgbuf);
1078 else {
1079 strncpy(buf, txtbuf, buflen);
1080 buf[buflen - 1] = '\0';
1081 }
1082 }
1083
1084#else
1085 if(err == SEC_E_OK)
1086 txt = "No error";
1087 else
1088 txt = "Error";
1089 strncpy(buf, txt, buflen);
1090 buf[buflen - 1] = '\0';
1091#endif
1092
1093 if(errno != old_errno)
1094 errno = old_errno;
1095
1096#ifdef PRESERVE_WINDOWS_ERROR_CODE
1097 if(old_win_err != GetLastError())
1098 SetLastError(old_win_err);
1099#endif
1100
1101 return buf;
1102}
1103#endif /* USE_WINDOWS_SSPI */
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette