strerror.c 19 KB

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