From 5a4b43848ac21b3d831f00ce11136e20f820f0a0 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 7 Apr 2006 21:50:47 +0000 Subject: First commit of David McCreedy's EBCDIC and TPF changes. --- docs/libcurl/Makefile.am | 7 +- docs/libcurl/curl_easy_escape.3 | 47 +++ docs/libcurl/curl_easy_unescape.3 | 48 +++ docs/libcurl/curl_escape.3 | 5 + docs/libcurl/curl_unescape.3 | 7 +- include/curl/curl.h | 50 ++- lib/config-tpf.h | 652 ++++++++++++++++++++++++++++++++++++++ lib/easy.c | 189 +++++++++++ lib/easyif.h | 7 + lib/escape.c | 54 +++- lib/escape.h | 4 +- lib/file.c | 4 +- lib/ftp.c | 69 +++- lib/ldap.c | 12 +- lib/select.c | 24 +- lib/select.h | 4 + lib/sendf.c | 51 +++ lib/setup.h | 6 + lib/ssluse.c | 12 + lib/strerror.c | 10 + lib/tftp.c | 5 +- lib/transfer.c | 12 + lib/url.c | 55 +++- lib/urldata.h | 20 ++ src/main.c | 101 +++++- src/setup.h | 13 + 26 files changed, 1422 insertions(+), 46 deletions(-) create mode 100644 docs/libcurl/curl_easy_escape.3 create mode 100644 docs/libcurl/curl_easy_unescape.3 create mode 100644 lib/config-tpf.h diff --git a/docs/libcurl/Makefile.am b/docs/libcurl/Makefile.am index caea9b9aa..77d2f87d3 100644 --- a/docs/libcurl/Makefile.am +++ b/docs/libcurl/Makefile.am @@ -16,7 +16,7 @@ man_MANS = curl_easy_cleanup.3 curl_easy_getinfo.3 curl_easy_init.3 \ curl_share_init.3 curl_share_setopt.3 libcurl.3 libcurl-easy.3 \ libcurl-multi.3 libcurl-share.3 libcurl-errors.3 curl_easy_strerror.3 \ curl_multi_strerror.3 curl_share_strerror.3 curl_global_init_mem.3 \ - libcurl-tutorial.3 curl_easy_reset.3 + libcurl-tutorial.3 curl_easy_reset.3 curl_easy_escape.3 curl_easy_unescape.3 HTMLPAGES = curl_easy_cleanup.html curl_easy_getinfo.html \ curl_easy_init.html curl_easy_perform.html curl_easy_setopt.html \ @@ -32,7 +32,8 @@ HTMLPAGES = curl_easy_cleanup.html curl_easy_getinfo.html \ libcurl.html libcurl-multi.html libcurl-easy.html libcurl-share.html \ libcurl-errors.html curl_easy_strerror.html curl_multi_strerror.html \ curl_share_strerror.html curl_global_init_mem.html \ - libcurl-tutorial.html curl_easy_reset.html + libcurl-tutorial.html curl_easy_reset.html curl_easy_escape.html \ + curl_easy_unescape.html PDFPAGES = curl_easy_cleanup.pdf curl_easy_getinfo.pdf \ curl_easy_init.pdf curl_easy_perform.pdf curl_easy_setopt.pdf \ @@ -48,7 +49,7 @@ PDFPAGES = curl_easy_cleanup.pdf curl_easy_getinfo.pdf \ libcurl-multi.pdf libcurl-easy.pdf libcurl-share.pdf \ libcurl-errors.pdf curl_easy_strerror.pdf curl_multi_strerror.pdf \ curl_share_strerror.pdf curl_global_init_mem.pdf libcurl-tutorial.pdf \ - curl_easy_reset.pdf + curl_easy_reset.pdf curl_easy_escape.pdf curl_easy_unescape.pdf CLEANFILES = $(HTMLPAGES) $(PDFPAGES) diff --git a/docs/libcurl/curl_easy_escape.3 b/docs/libcurl/curl_easy_escape.3 new file mode 100644 index 000000000..73c09b4f1 --- /dev/null +++ b/docs/libcurl/curl_easy_escape.3 @@ -0,0 +1,47 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2006, Daniel Stenberg, , et al. +.\" * +.\" * This software is licensed as described in the file COPYING, which +.\" * you should have received as part of this distribution. The terms +.\" * are also available at http://curl.haxx.se/docs/copyright.html. +.\" * +.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell +.\" * copies of the Software, and permit persons to whom the Software is +.\" * furnished to do so, under the terms of the COPYING file. +.\" * +.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +.\" * KIND, either express or implied. +.\" * +.\" * $Id$ +.\" ************************************************************************** +.\" +.TH curl_easy_escape 3 "7 April 2006" "libcurl 7.15.4" "libcurl Manual" +.SH NAME +curl_easy_escape - URL encodes the given string +.SH SYNOPSIS +.B #include +.sp +.BI "char *curl_easy_escape( CURL *" curl ", char *" url ", int "length " );" +.ad +.SH DESCRIPTION +This function converts the given input string to an URL encoded string and +returns that as a new allocated string. All input characters that are not a-z, +A-Z or 0-9 are converted to their "URL escaped" version (%NN where NN is a +two-digit hexadecimal number). + +If the \fBlength\fP argument is set to 0 (zero), curl_easy_escape() uses +strlen() on the input \fBurl\fP to find out the size. + +You must \fIcurl_free(3)\fP the returned string when you're done with it. +.SH AVAILABILITY +Added in 7.15.4 and replaces the old curl_escape() function. +.SH RETURN VALUE +A pointer to a zero terminated string or NULL if it failed. +.SH "SEE ALSO" +.BR curl_easy_unescape "(3), " curl_free "(3), " RFC 2396 diff --git a/docs/libcurl/curl_easy_unescape.3 b/docs/libcurl/curl_easy_unescape.3 new file mode 100644 index 000000000..6b0e6b5fa --- /dev/null +++ b/docs/libcurl/curl_easy_unescape.3 @@ -0,0 +1,48 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2006, Daniel Stenberg, , et al. +.\" * +.\" * This software is licensed as described in the file COPYING, which +.\" * you should have received as part of this distribution. The terms +.\" * are also available at http://curl.haxx.se/docs/copyright.html. +.\" * +.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell +.\" * copies of the Software, and permit persons to whom the Software is +.\" * furnished to do so, under the terms of the COPYING file. +.\" * +.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +.\" * KIND, either express or implied. +.\" * +.\" * $Id$ +.\" ************************************************************************** +.\" +.TH curl_easy_unescape 3 "7 April 2006" "libcurl 7.15.4" "libcurl Manual" +.SH NAME +curl_easy_unescape - URL decodes the given string +.SH SYNOPSIS +.B #include +.sp +.BI "char *curl_easy_unescape( CURL *" curl ", char *" url ", int "inlength +.BI ", int *" outlength " );" +.ad +.SH DESCRIPTION +This function converts the given URL encoded input string to a "plain string" +and returns that in an allocated memory area. All input characters that are +URL encoded (%XX where XX is a two-digit hexadecimal number) are converted to +their binary versions. + +If the \fBlength\fP argument is set to 0 (zero), curl_easy_unescape() will use +strlen() on the input \fIurl\fP string to find out the size. + +You must \fIcurl_free(3)\fP the returned string when you're done with it. +.SH AVAILABILITY +Added in 7.15.4 and replaces the old curl_unescape() function. +.SH RETURN VALUE +A pointer to a zero terminated string or NULL if it failed. +.SH "SEE ALSO" +.I curl_easy_escape(3), curl_free(3), RFC 2396 diff --git a/docs/libcurl/curl_escape.3 b/docs/libcurl/curl_escape.3 index 66eba1477..2007d69ef 100644 --- a/docs/libcurl/curl_escape.3 +++ b/docs/libcurl/curl_escape.3 @@ -11,6 +11,8 @@ curl_escape - URL encodes the given string .BI "char *curl_escape( char *" url ", int "length " );" .ad .SH DESCRIPTION +Obsolete function. Use \fIcurl_easy_escape(3)\fP instead! + This function will convert the given input string to an URL encoded string and return that as a new allocated string. All input characters that are not a-z, A-Z or 0-9 will be converted to their "URL escaped" version (%NN where NN is a @@ -20,6 +22,9 @@ If the 'length' argument is set to 0, curl_escape() will use strlen() on the input 'url' string to find out the size. You must curl_free() the returned string when you're done with it. +.SH AVAILABILITY +Since 7.15.4, \fIcurl_easy_escape(3)\fP should be used. This function will +be removed in a future release. .SH RETURN VALUE A pointer to a zero terminated string or NULL if it failed. .SH "SEE ALSO" diff --git a/docs/libcurl/curl_unescape.3 b/docs/libcurl/curl_unescape.3 index 1d2b059fc..d4c5797b0 100644 --- a/docs/libcurl/curl_unescape.3 +++ b/docs/libcurl/curl_unescape.3 @@ -11,6 +11,8 @@ curl_unescape - URL decodes the given string .BI "char *curl_unescape( char *" url ", int "length " );" .ad .SH DESCRIPTION +Obsolete function. Use \fIcurl_easy_unescape(3)\fP instead! + This function will convert the given URL encoded input string to a "plain string" and return that as a new allocated string. All input characters that are URL encoded (%XX where XX is a two-digit hexadecimal number) will be @@ -20,7 +22,10 @@ If the 'length' argument is set to 0, curl_unescape() will use strlen() on the input 'url' string to find out the size. You must curl_free() the returned string when you're done with it. +.SH AVAILABILITY +Since 7.15.4, \fIcurl_easy_unescape(3)\fP should be used. This function will +be removed in a future release. .SH RETURN VALUE A pointer to a zero terminated string or NULL if it failed. .SH "SEE ALSO" -.I curl_escape(3), curl_free(3), RFC 2396 +.I curl_easy_escape(3), curl_easy_unescape(3), curl_free(3), RFC 2396 diff --git a/include/curl/curl.h b/include/curl/curl.h index b4043a2c4..14999c49e 100644 --- a/include/curl/curl.h +++ b/include/curl/curl.h @@ -268,6 +268,10 @@ typedef enum { CURLE_FTP_COULDNT_STOR_FILE, /* 25 - failed FTP upload */ CURLE_READ_ERROR, /* 26 - could open/read from file */ CURLE_OUT_OF_MEMORY, /* 27 */ + /* Note: CURLE_OUT_OF_MEMORY may sometimes indicate a conversion error + instead of a memory allocation error if CURL_DOES_CONVERSIONS + is defined + */ CURLE_OPERATION_TIMEOUTED, /* 28 - the timeout time was reached */ CURLE_FTP_COULDNT_SET_ASCII, /* 29 - TYPE A failed */ CURLE_FTP_PORT_FAILED, /* 30 - FTP PORT operation failed */ @@ -318,9 +322,18 @@ typedef enum { CURLE_TFTP_UNKNOWNID, /* 72 - Unknown transfer ID */ CURLE_TFTP_EXISTS, /* 73 - File already exists */ CURLE_TFTP_NOSUCHUSER, /* 74 - No such user */ + CURLE_CONV_FAILED, /* 75 - conversion failed */ + CURLE_CONV_REQD, /* 76 - caller must register conversion + callbacks using curl_easy_setopt options + CURLOPT_CONV_FROM_NETWORK_FUNCTION, + CURLOPT_CONV_TO_NETWORK_FUNCTION, and + CURLOPT_CONV_FROM_UTF8_FUNCTION */ CURL_LAST /* never use! */ } CURLcode; +/* This prototype applies to all conversion callbacks */ +typedef CURLcode (*curl_conv_callback)(char *buffer, size_t length); + typedef CURLcode (*curl_ssl_ctx_callback)(CURL *curl, /* easy handle */ void *ssl_ctx, /* actually an OpenSSL SSL_CTX */ @@ -937,6 +950,19 @@ typedef enum { extracting it with CURLINFO_LASTSOCKET */ CINIT(CONNECT_ONLY, LONG, 141), + /* Function that will be called to convert from the + network encoding (instead of using the iconv calls in libcurl) */ + CINIT(CONV_FROM_NETWORK_FUNCTION, FUNCTIONPOINT, 142), + + /* Function that will be called to convert to the + network encoding (instead of using the iconv calls in libcurl) */ + CINIT(CONV_TO_NETWORK_FUNCTION, FUNCTIONPOINT, 143), + + /* Function that will be called to convert from UTF8 + (instead of using the iconv calls in libcurl) + Note that this is used only for SSL certificate processing */ + CINIT(CONV_FROM_UTF8_FUNCTION, FUNCTIONPOINT, 144), + CURLOPT_LASTENTRY /* the last unused */ } CURLoption; @@ -1146,7 +1172,7 @@ CURL_EXTERN char *curl_getenv(const char *variable); CURL_EXTERN char *curl_version(void); /* - * NAME curl_escape() + * NAME curl_easy_escape() * * DESCRIPTION * @@ -1154,18 +1180,34 @@ CURL_EXTERN char *curl_version(void); * %XX versions). This function returns a new allocated string or NULL if an * error occurred. */ -CURL_EXTERN char *curl_escape(const char *string, int length); +CURL_EXTERN char *curl_easy_escape(CURL *handle, + const char *string, + int length); + +/* the previous version: */ +CURL_EXTERN char *curl_escape(const char *string, + int length); + /* - * NAME curl_unescape() + * NAME curl_easy_unescape() * * DESCRIPTION * * Unescapes URL encoding in strings (converts all %XX codes to their 8bit * versions). This function returns a new allocated string or NULL if an error * occurred. + * Conversion Note: On non-ASCII platforms the ASCII %XX codes are + * converted into the host encoding. */ -CURL_EXTERN char *curl_unescape(const char *string, int length); +CURL_EXTERN char *curl_easy_unescape(CURL *handle, + const char *string, + int length, + int *outlength); + +/* the previous version */ +CURL_EXTERN char *curl_unescape(const char *string, + int length); /* * NAME curl_free() diff --git a/lib/config-tpf.h b/lib/config-tpf.h new file mode 100644 index 000000000..63a1e6607 --- /dev/null +++ b/lib/config-tpf.h @@ -0,0 +1,652 @@ +#ifndef __LIBCONFIGTPF_H +#define __LIBCONFIGTPF_H + +/* ================================================================ */ +/* lib/config-tpf.h - Hand crafted config file for TPF */ +/* ================================================================ */ + +/* ---------------------------------------------------------------- */ +/* FEATURES, FUNCTIONS, and DEFINITIONS */ +/* ---------------------------------------------------------------- */ + +/* when building libcurl itself */ +/* #undef BUILDING_LIBCURL */ + +/* to disable cookies support */ +/* #undef CURL_DISABLE_COOKIES */ + +/* to disable cryptographic authentication */ +/* #undef CURL_DISABLE_CRYPTO_AUTH */ + +/* to disable DICT */ +#define CURL_DISABLE_DICT 1 + +/* to disable FILE */ +#define CURL_DISABLE_FILE 1 + +/* to disable FTP */ +/* #undef CURL_DISABLE_FTP */ + +/* to disable HTTP */ +#define CURL_DISABLE_HTTP 1 + +/* to disable LDAP */ +#define CURL_DISABLE_LDAP 1 + +/* to disable TELNET */ +#define CURL_DISABLE_TELNET 1 + +/* to disable TFTP */ +#define CURL_DISABLE_TFTP 1 + +/* to disable verbose strings */ +/* #undef CURL_DISABLE_VERBOSE_STRINGS */ + +/* when not building a shared library */ +/* #undef CURL_STATICLIB */ + +/* Set to explicitly specify we don't want to use thread-safe functions */ +/* #undef DISABLED_THREADSAFE */ +#define DISABLED_THREADSAFE 1 + +/* lber dynamic library file */ +/* #undef DL_LBER_FILE */ + +/* ldap dynamic library file */ +/* #undef DL_LDAP_FILE */ + +/* your Entropy Gathering Daemon socket pathname */ +/* #undef EGD_SOCKET */ + +/* Define if you want to enable IPv6 support */ +/* #undef ENABLE_IPV6 */ + +/* Define to 1 if you have the header file. */ +#define HAVE_ALLOCA_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_ARPA_INET_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_ASSERT_H 1 + +/* Define to 1 if you have the `basename' function. */ +#define HAVE_BASENAME 1 + +/* Define to 1 if you have the `closesocket' function. */ +/* #undef HAVE_CLOSESOCKET */ + +/* Define to 1 if you have the `CRYPTO_cleanup_all_ex_data' function. */ +/* #undef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA */ +#define HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_CRYPTO_H */ +#define HAVE_CRYPTO_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_DES_H */ +#define HAVE_DES_H 1 + +/* disabled non-blocking sockets */ +/* #undef HAVE_DISABLED_NONBLOCKING */ + +/* Define to 1 if you have the header file. */ +#define HAVE_DLFCN_H 1 + +/* Define to 1 if you have the `dlopen' function. */ +#define HAVE_DLOPEN 1 + +/* Define to 1 if you have the `ENGINE_load_builtin_engines' function. */ +/* #undef HAVE_ENGINE_LOAD_BUILTIN_ENGINES */ +#define HAVE_ENGINE_LOAD_BUILTIN_ENGINES 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_ERRNO_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_ERR_H */ +#define HAVE_ERR_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* use FIONBIO for non-blocking sockets */ +/* #undef HAVE_FIONBIO */ +#define HAVE_FIONBIO 1 + +/* Define to 1 if you have the `ftruncate' function. */ +#define HAVE_FTRUNCATE 1 + +/* Define if getaddrinfo exists and works */ +/* #undef HAVE_GETADDRINFO */ + +/* Define to 1 if you have the `geteuid' function. */ +#define HAVE_GETEUID 1 + +/* Define to 1 if you have the `gethostbyaddr' function. */ +#define HAVE_GETHOSTBYADDR 1 + +/* If you have gethostbyname */ +#define HAVE_GETHOSTBYNAME 1 + +/* Define to 1 if you have the `gethostbyname_r' function. */ +/* #undef HAVE_GETHOSTBYNAME_R */ + +/* gethostbyname_r() takes 3 args */ +/* #undef HAVE_GETHOSTBYNAME_R_3 */ + +/* gethostbyname_r() takes 5 args */ +/* #undef HAVE_GETHOSTBYNAME_R_5 */ + +/* gethostbyname_r() takes 6 args */ +/* #define HAVE_GETHOSTBYNAME_R_6 1 */ + +/* Define to 1 if you have the `getpass_r' function. */ +/* #undef HAVE_GETPASS_R */ + +/* Define to 1 if you have the `getpwuid' function. */ +#define HAVE_GETPWUID 1 + +/* Define to 1 if you have the `getrlimit' function. */ +#define HAVE_GETRLIMIT 1 + +/* Define to 1 if you have the `gettimeofday' function. */ +#define HAVE_GETTIMEOFDAY 1 + +/* we have a glibc-style strerror_r() */ +/* #undef HAVE_GLIBC_STRERROR_R */ + +/* Define to 1 if you have the `gmtime_r' function. */ +#define HAVE_GMTIME_R 1 + +/* if you have the gssapi libraries */ +/* #undef HAVE_GSSAPI */ + +/* if you have the Heimdal gssapi libraries */ +/* #undef HAVE_GSSHEIMDAL */ + +/* if you have the MIT gssapi libraries */ +/* #undef HAVE_GSSMIT */ + +/* Define to 1 if you have the `iconv' functions. */ +#define HAVE_ICONV + +/* Define to 1 if you have the `idna_strerror' function. */ +/* #undef HAVE_IDNA_STRERROR */ + +/* Define to 1 if you have the `idn_free' function. */ +/* #undef HAVE_IDN_FREE */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_IDN_FREE_H */ + +/* Define to 1 if you have the `inet_addr' function. */ +#define HAVE_INET_ADDR 1 + +/* Define to 1 if you have the `inet_ntoa' function. */ +#define HAVE_INET_NTOA 1 + +/* Define to 1 if you have the `inet_ntoa_r' function. */ +/* #undef HAVE_INET_NTOA_R */ + +/* inet_ntoa_r() is declared */ +/* #undef HAVE_INET_NTOA_R_DECL */ + +/* Define to 1 if you have the `inet_pton' function. */ +/* #undef HAVE_INET_PTON */ + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* use ioctlsocket() for non-blocking sockets */ +/* #undef HAVE_IOCTLSOCKET */ + +/* use Ioctlsocket() for non-blocking sockets */ +/* #undef HAVE_IOCTLSOCKET_CASE */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_IO_H */ + +/* if you have the Kerberos4 libraries (including -ldes) */ +/* #undef HAVE_KRB4 */ + +/* Define to 1 if you have the `krb_get_our_ip_for_realm' function. */ +/* #undef HAVE_KRB_GET_OUR_IP_FOR_REALM */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_KRB_H */ + +/* Define to 1 if you have the `dl' library (-ldl). */ +#define HAVE_LIBDL 1 + +/* Define to 1 if you have the header file. */ +/* #define HAVE_LIBGEN_H 1 */ + +/* Define to 1 if you have the `idn' library (-lidn). */ +/* #undef HAVE_LIBIDN */ + +/* Define to 1 if you have the `resolv' library (-lresolv). */ +/* #undef HAVE_LIBRESOLV */ + +/* Define to 1 if you have the `resolve' library (-lresolve). */ +/* #undef HAVE_LIBRESOLVE */ + +/* Define to 1 if you have the `socket' library (-lsocket). */ +/* #undef HAVE_LIBSOCKET */ + +/* Define to 1 if you have the `ssl' library (-lssl). */ +/* #undef HAVE_LIBSSL */ +#define HAVE_LIBSSL + +/* if zlib is available */ +/* #undef HAVE_LIBZ */ + +/* Define to 1 if you have the header file. */ +#define HAVE_LIMITS_H 1 + +/* if your compiler supports LL */ +#define HAVE_LL 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_LOCALE_H 1 + +/* Define to 1 if you have the `localtime_r' function. */ +#define HAVE_LOCALTIME_R 1 + +/* if your compiler supports long long */ +#define HAVE_LONGLONG 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MALLOC_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_NETDB_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_NETINET_IN_H 1 + +/* Define to 1 if you have the header file. */ +/* undef HAVE_NETINET_TCP_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_NET_IF_H 1 + +/* Define if NI_WITHSCOPEID exists and works */ +/* #undef HAVE_NI_WITHSCOPEID */ + +/* we have no strerror_r() proto */ +/* #undef HAVE_NO_STRERROR_R_DECL */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_OPENSSL_CRYPTO_H */ +#define HAVE_OPENSSL_CRYPTO_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_OPENSSL_ENGINE_H */ +#define HAVE_OPENSSL_ENGINE_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_OPENSSL_ERR_H */ +#define HAVE_OPENSSL_ERR_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_OPENSSL_PEM_H */ +#define HAVE_OPENSSL_PEM_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_OPENSSL_PKCS12_H */ +#define HAVE_OPENSSL_PKCS12_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_OPENSSL_RSA_H */ +#define HAVE_OPENSSL_RSA_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_OPENSSL_SSL_H */ +#define HAVE_OPENSSL_SSL_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_OPENSSL_X509_H */ +#define HAVE_OPENSSL_X509_H 1 + +/* use O_NONBLOCK for non-blocking sockets */ +/* #undef HAVE_O_NONBLOCK 1 */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_PEM_H */ +#define HAVE_PEM_H 1 + +/* Define to 1 if you have the `perror' function. */ +#define HAVE_PERROR 1 + +/* Define to 1 if you have the `pipe' function. */ +#define HAVE_PIPE 1 + +/* Define to 1 if you have the `poll' function. */ +/* #undef HAVE_POLL */ + +/* If you have a fine poll */ +/* #undef HAVE_POLL_FINE */ + +/* we have a POSIX-style strerror_r() */ +/* #undef HAVE_POSIX_STRERROR_R */ +/* #define HAVE_POSIX_STRERROR_R 1 */ + +/* Define to 1 if you have the header file. */ +#define HAVE_PWD_H 1 + +/* Define to 1 if you have the `RAND_egd' function. */ +/* #undef HAVE_RAND_EGD */ +#define HAVE_RAND_EGD 1 + +/* Define to 1 if you have the `RAND_screen' function. */ +/* #undef HAVE_RAND_SCREEN */ + +/* Define to 1 if you have the `RAND_status' function. */ +/* #undef HAVE_RAND_STATUS */ +#define HAVE_RAND_STATUS 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_RSA_H */ +#define HAVE_RSA_H 1 + +/* Define to 1 if you have the `select' function. */ +#define HAVE_SELECT 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SETJMP_H 1 + +/* Define to 1 if you have the `setlocale' function. */ +#define HAVE_SETLOCALE 1 + +/* Define to 1 if you have the `setrlimit' function. */ +#define HAVE_SETRLIMIT 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SGTTY_H 1 */ + +/* Define to 1 if you have the `sigaction' function. */ +#define HAVE_SIGACTION 1 + +/* Define to 1 if you have the `siginterrupt' function. */ +/* #undef HAVE_SIGINTERRUPT */ + +/* Define to 1 if you have the `signal' function. */ +#define HAVE_SIGNAL 1 + +/* If you have sigsetjmp */ +/* #undef HAVE_SIGSETJMP */ + +/* Define to 1 if you have the `socket' function. */ +#define HAVE_SOCKET 1 + +/* use SO_NONBLOCK for non-blocking sockets */ +/* #undef HAVE_SO_NONBLOCK */ + +/* Define this if you have the SPNEGO library fbopenssl */ +/* #undef HAVE_SPNEGO */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SSL_H */ +#define HAVE_SSL_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the `strcasecmp' function. */ +#define HAVE_STRCASECMP 1 + +/* Define to 1 if you have the `strcmpi' function. */ +/* #undef HAVE_STRCMPI */ + +/* Define to 1 if you have the `strdup' function. */ +#define HAVE_STRDUP 1 + +/* Define to 1 if you have the `strerror_r' function. */ +#define HAVE_STRERROR_R 1 + +/* Define to 1 if you have the `stricmp' function. */ +/* #undef HAVE_STRICMP */ +#define HAVE_STRICMP + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the `strlcat' function. */ +/* #undef HAVE_STRLCAT */ + +/* Define to 1 if you have the `strlcpy' function. */ +/* #undef HAVE_STRLCPY */ + +/* Define to 1 if you have the `strstr' function. */ +#define HAVE_STRSTR 1 + +/* Define to 1 if you have the `strtok_r' function. */ +#define HAVE_STRTOK_R 1 + +/* Define to 1 if you have the `strtoll' function. */ +#define HAVE_STRTOLL 1 + +/* if struct sockaddr_storage is defined */ +/* undef HAVE_STRUCT_SOCKADDR_STORAGE */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_IOCTL_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_PARAM_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_POLL_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_RESOURCE_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_SELECT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_SOCKET_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_SOCKIO_H */ +#define HAVE_SYS_SOCKIO_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_UTIME_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_TERMIOS_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_TERMIO_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_TIME_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_TLD_H */ + +/* Define to 1 if you have the `tld_strerror' function. */ +/* #undef HAVE_TLD_STRERROR */ + +/* Define to 1 if you have the `uname' function. */ +/* #undef HAVE_UNAME */ + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to 1 if you have the `utime' function. */ +#define HAVE_UTIME 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UTIME_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_WINSOCK2_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_WINSOCK_H */ + +/* Define this symbol if your OS supports changing the contents of argv */ +/* #undef HAVE_WRITABLE_ARGV */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_X509_H */ +#define undef HAVE_X509_H 1 + +/* if you have the zlib.h header file */ +/* #undef HAVE_ZLIB_H */ + +/* If you lack a fine basename() prototype */ +/* #undef NEED_BASENAME_PROTO */ + +/* need REENTRANT defined */ +/* #undef NEED_REENTRANT */ + +#define HAVE_GLIBC_STRERROR_R + +/* cpu-machine-OS */ +#define OS "s390x-ibm-tpf" + +/* Name of package */ +#define PACKAGE "curl" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "a suitable curl mailing list => http://curl.haxx.se/mail/" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "curl" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "curl -" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "curl" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "-" + +/* a suitable file to read random data from */ +/* #undef RANDOM_FILE */ + +/* Define as the return type of signal handlers (`int' or `void'). */ +#define RETSIGTYPE void + +/* Define to the type of arg 1 for `select'. */ +#define SELECT_TYPE_ARG1 int + +/* Define to the type of args 2, 3 and 4 for `select'. */ +#define SELECT_TYPE_ARG234 (fd_set *) + +/* Define to the type of arg 5 for `select'. */ +#define SELECT_TYPE_ARG5 (struct timeval *) + +/* The size of a `curl_off_t', as computed by sizeof. */ +#define SIZEOF_CURL_OFF_T 8 + +/* The size of a `long', as computed by sizeof. */ +#define SIZEOF_LONG 8 + +/* The size of a `size_t', as computed by sizeof. */ +#define SIZEOF_SIZE_T 8 + +/* The size of a `time_t', as computed by sizeof. */ +#define SIZEOF_TIME_T 8 + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define to 1 if you can safely include both and . */ +#define TIME_WITH_SYS_TIME 1 + +/* Define if you want to enable ares support */ +/* #undef USE_ARES */ + +/* if GnuTLS is enabled */ +/* #undef USE_GNUTLS */ + +/* If you want to build curl with the built-in manual */ +/* #undef USE_MANUAL */ + +/* if OpenSSL is in use */ +/* #undef USE_OPENSSL */ +#define USE_OPENSSL + +/* if SSL is enabled */ +/* #undef USE_SSLEAY */ +#define USE_SSLEAY + +/* to enable SSPI support */ +/* #undef USE_WINDOWS_SSPI */ + +/* Version number of package */ +#define VERSION "not-used" + +/* Define to 1 if on AIX 3. + System headers sometimes define this. + We just want to avoid a redefinition error message. */ +#ifndef _ALL_SOURCE +/* # undef _ALL_SOURCE */ +#endif + +/* Number of bits in a file offset, on hosts where this is settable. */ +/* #undef _FILE_OFFSET_BITS */ + +/* Define for large files, on AIX-style hosts. */ +/* #undef _LARGE_FILES */ + +/* define this if you need it to compile thread-safe code */ +/* #undef _THREAD_SAFE */ + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + +/* type to use in place of in_addr_t if not defined */ +/* #undef in_addr_t */ + +/* Define to `unsigned' if does not define. */ +/* #undef size_t */ + +/* type to use in place of socklen_t if not defined */ +/* #undef socklen_t */ + +/* the signed version of size_t */ +/* #undef ssize_t */ + +#define CURL_DOES_CONVERSIONS +#ifndef CURL_ICONV_CODESET_OF_HOST +#define CURL_ICONV_CODESET_OF_HOST "IBM-1047" +#endif + +/* ---------------------------------------------------------------- */ +/* HEADER FILES */ +/* ---------------------------------------------------------------- */ + +#include /* for bzero, strcasecmp, and strncasecmp */ +#include /* for strcpy and strlen */ +#include /* for rand and srand */ +#include /* for select and ioctl*/ +#include /* for in_addr_t definition */ +#include /* for tpf_process_signals */ + +#endif /* __LIBCONFIGTPF_H */ diff --git a/lib/easy.c b/lib/easy.c index d86b755fb..fdbb6a0e2 100644 --- a/lib/easy.c +++ b/lib/easy.c @@ -83,10 +83,22 @@ #include "memory.h" #include "progress.h" #include "easyif.h" +#include "sendf.h" /* for failf function prototype */ #define _MPRINTF_REPLACE /* use our functions only */ #include +#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV) +#include +/* set default codesets for iconv */ +#ifndef CURL_ICONV_CODESET_OF_NETWORK +#define CURL_ICONV_CODESET_OF_NETWORK "ISO8859-1" +#endif +#ifndef CURL_ICONV_CODESET_FOR_UTF8 +#define CURL_ICONV_CODESET_FOR_UTF8 "UTF-8" +#endif +#endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */ + /* The last #include file should be: */ #include "memdebug.h" @@ -656,3 +668,180 @@ void curl_easy_reset(CURL *curl) data->set.ssl.CAfile = (char *)CURL_CA_BUNDLE; #endif } + +#ifdef CURL_DOES_CONVERSIONS +/* + * Curl_convert_to_network() is an internal function + * for performing ASCII conversions on non-ASCII platforms. + */ +CURLcode Curl_convert_to_network(struct SessionHandle *data, + char *buffer, size_t length) +{ + CURLcode rc; + + if(data->set.convtonetwork) { + /* use translation callback */ + rc = data->set.convtonetwork(buffer, length); + if(rc != CURLE_OK) { + failf(data, + "CURLOPT_CONV_TO_NETWORK_FUNCTION callback returned %i: %s", + rc, curl_easy_strerror(rc)); + } + return(rc); + } else { +#ifdef HAVE_ICONV + /* do the translation ourselves */ + char *input_ptr, *output_ptr; + size_t in_bytes, out_bytes, rc; + + /* open an iconv conversion descriptor if necessary */ + if(data->outbound_cd == (iconv_t)-1) { + data->outbound_cd = iconv_open(CURL_ICONV_CODESET_OF_NETWORK, + CURL_ICONV_CODESET_OF_HOST); + if(data->outbound_cd == (iconv_t)-1) { + failf(data, + "The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s", + CURL_ICONV_CODESET_OF_NETWORK, + CURL_ICONV_CODESET_OF_HOST, + errno, strerror(errno)); + return CURLE_CONV_FAILED; + } + } + /* call iconv */ + input_ptr = output_ptr = buffer; + in_bytes = out_bytes = length; + rc = iconv(data->outbound_cd, &input_ptr, &in_bytes, + &output_ptr, &out_bytes); + if ((rc == -1) || (in_bytes != 0)) { + failf(data, + "The Curl_convert_to_network iconv call failed with errno %i: %s", + errno, strerror(errno)); + return CURLE_CONV_FAILED; + } +#else + failf(data, "CURLOPT_CONV_TO_NETWORK_FUNCTION callback required"); + return CURLE_CONV_REQD; +#endif /* HAVE_ICONV */ + } + + return CURLE_OK; +} + +/* + * Curl_convert_from_network() is an internal function + * for performing ASCII conversions on non-ASCII platforms. + */ +CURLcode Curl_convert_from_network(struct SessionHandle *data, + char *buffer, size_t length) +{ + CURLcode rc; + + if(data->set.convfromnetwork) { + /* use translation callback */ + rc = data->set.convfromnetwork(buffer, length); + if(rc != CURLE_OK) { + failf(data, + "CURLOPT_CONV_FROM_NETWORK_FUNCTION callback returned %i: %s", + rc, curl_easy_strerror(rc)); + } + return(rc); + } else { +#ifdef HAVE_ICONV + /* do the translation ourselves */ + char *input_ptr, *output_ptr; + size_t in_bytes, out_bytes, rc; + + /* open an iconv conversion descriptor if necessary */ + if(data->inbound_cd == (iconv_t)-1) { + data->inbound_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST, + CURL_ICONV_CODESET_OF_NETWORK); + if(data->inbound_cd == (iconv_t)-1) { + failf(data, + "The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s", + CURL_ICONV_CODESET_OF_HOST, + CURL_ICONV_CODESET_OF_NETWORK, + errno, strerror(errno)); + return CURLE_CONV_FAILED; + } + } + /* call iconv */ + input_ptr = output_ptr = buffer; + in_bytes = out_bytes = length; + rc = iconv(data->inbound_cd, &input_ptr, &in_bytes, + &output_ptr, &out_bytes); + if ((rc == -1) || (in_bytes != 0)) { + failf(data, + "The Curl_convert_from_network iconv call failed with errno %i: %s", + errno, strerror(errno)); + return CURLE_CONV_FAILED; + } +#else + failf(data, "CURLOPT_CONV_FROM_NETWORK_FUNCTION callback required"); + return CURLE_CONV_REQD; +#endif /* HAVE_ICONV */ + } + + return CURLE_OK; +} + +/* + * Curl_convert_from_utf8() is an internal function + * for performing UTF-8 conversions on non-ASCII platforms. + */ +CURLcode Curl_convert_from_utf8(struct SessionHandle *data, + char *buffer, size_t length) +{ + CURLcode rc; + + if(data->set.convfromutf8) { + /* use translation callback */ + rc = data->set.convfromutf8(buffer, length); + if(rc != CURLE_OK) { + failf(data, + "CURLOPT_CONV_FROM_UTF8_FUNCTION callback returned %i: %s", + rc, curl_easy_strerror(rc)); + } + return(rc); + } else { +#ifdef HAVE_ICONV + /* do the translation ourselves */ + char *input_ptr, *output_ptr; + size_t in_bytes, out_bytes, rc; + + /* open an iconv conversion descriptor if necessary */ + if(data->utf8_cd == (iconv_t)-1) { + data->utf8_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST, + CURL_ICONV_CODESET_FOR_UTF8); + if(data->utf8_cd == (iconv_t)-1) { + failf(data, + "The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s", + CURL_ICONV_CODESET_OF_HOST, + CURL_ICONV_CODESET_FOR_UTF8, + errno, strerror(errno)); + return CURLE_CONV_FAILED; + } + } + /* call iconv */ + input_ptr = output_ptr = buffer; + in_bytes = out_bytes = length; + rc = iconv(data->utf8_cd, &input_ptr, &in_bytes, &output_ptr, &out_bytes); + if ((rc == -1) || (in_bytes != 0)) { + failf(data, + "The Curl_convert_from_utf8 iconv call failed with errno %i: %s", + errno, strerror(errno)); + return CURLE_CONV_FAILED; + } + if (output_ptr < input_ptr) { + /* null terminate the now shorter output string */ + *output_ptr = 0x00; + } +#else + failf(data, "CURLOPT_CONV_FROM_UTF8_FUNCTION callback required"); + return CURLE_CONV_REQD; +#endif /* HAVE_ICONV */ + } + + return CURLE_OK; +} + +#endif /* CURL_DOES_CONVERSIONS */ diff --git a/lib/easyif.h b/lib/easyif.h index 0f4f5703e..5c1646ad8 100644 --- a/lib/easyif.h +++ b/lib/easyif.h @@ -28,4 +28,11 @@ */ void Curl_easy_addmulti(struct SessionHandle *data, void *multi); +CURLcode Curl_convert_to_network(struct SessionHandle *data, + char *buffer, size_t length); +CURLcode Curl_convert_from_network(struct SessionHandle *data, + char *buffer, size_t length); +CURLcode Curl_convert_from_utf8(struct SessionHandle *data, + char *buffer, size_t length); + #endif /* __EASYIF_H */ diff --git a/lib/escape.c b/lib/escape.c index 4466d4cc9..c569902f6 100644 --- a/lib/escape.c +++ b/lib/escape.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2004, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2006, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -32,6 +32,9 @@ #include #include #include "memory.h" +/* urldata.h and easyif.h are included for Curl_convert_... prototypes */ +#include "urldata.h" +#include "easyif.h" #define _MPRINTF_REPLACE /* use our functions only */ #include @@ -39,7 +42,19 @@ /* The last #include file should be: */ #include "memdebug.h" +/* for ABI-compatibility with previous versions */ char *curl_escape(const char *string, int inlength) +{ + return curl_easy_escape(NULL, string, inlength); +} + +/* for ABI-compatibility with previous versions */ +char *curl_unescape(const char *string, int length) +{ + return curl_easy_unescape(NULL, string, length, NULL); +} + +char *curl_easy_escape(CURL *handle, const char *string, int inlength) { size_t alloc = (inlength?(size_t)inlength:strlen(string))+1; char *ns; @@ -49,6 +64,10 @@ char *curl_escape(const char *string, int inlength) int strindex=0; size_t length; +#ifndef CURL_DOES_CONVERSIONS + /* avoid compiler warnings */ + (void)handle; +#endif ns = malloc(alloc); if(!ns) return NULL; @@ -72,6 +91,17 @@ char *curl_escape(const char *string, int inlength) ns = testing_ptr; } } + +#ifdef CURL_DOES_CONVERSIONS +/* escape sequences are always in ASCII so convert them on non-ASCII hosts */ + if (!handle || + (Curl_convert_to_network(handle, &in, 1) != CURLE_OK)) { + /* Curl_convert_to_network calls failf if unsuccessful */ + free(ns); + return NULL; + } +#endif /* CURL_DOES_CONVERSIONS */ + snprintf(&ns[strindex], 4, "%%%02X", in); strindex+=3; @@ -90,7 +120,8 @@ char *curl_escape(const char *string, int inlength) (in >= 'A' && in <= 'F') || \ (in >= '0' && in <= '9')) -char *curl_unescape(const char *string, int length) +char *curl_easy_unescape(CURL *handle, const char *string, int length, + int *olen) { int alloc = (length?length:(int)strlen(string))+1; char *ns = malloc(alloc); @@ -98,6 +129,10 @@ char *curl_unescape(const char *string, int length) int strindex=0; long hex; +#ifndef CURL_DOES_CONVERSIONS + /* avoid compiler warnings */ + (void)handle; +#endif if( !ns ) return NULL; @@ -114,6 +149,17 @@ char *curl_unescape(const char *string, int length) hex = strtol(hexstr, &ptr, 16); in = (unsigned char)hex; /* this long is never bigger than 255 anyway */ + +#ifdef CURL_DOES_CONVERSIONS +/* escape sequences are always in ASCII so convert them on non-ASCII hosts */ + if (!handle || + (Curl_convert_from_network(handle, &in, 1) != CURLE_OK)) { + /* Curl_convert_from_network calls failf if unsuccessful */ + free(ns); + return NULL; + } +#endif /* CURL_DOES_CONVERSIONS */ + string+=2; alloc-=2; } @@ -122,6 +168,10 @@ char *curl_unescape(const char *string, int length) string++; } ns[strindex]=0; /* terminate it */ + + if(olen) + /* store output size */ + *olen = strindex; return ns; } diff --git a/lib/escape.h b/lib/escape.h index b37271ddd..a0a0209c4 100644 --- a/lib/escape.h +++ b/lib/escape.h @@ -8,7 +8,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2005, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2006, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -26,7 +26,5 @@ /* Escape and unescape URL encoding in strings. The functions return a new * allocated string or NULL if an error occurred. */ -char *curl_escape(const char *string, int length); -char *curl_unescape(const char *string, int length); #endif diff --git a/lib/file.c b/lib/file.c index b62581763..d39b12d43 100644 --- a/lib/file.c +++ b/lib/file.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2005, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2006, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -102,7 +102,7 @@ */ CURLcode Curl_file_connect(struct connectdata *conn) { - char *real_path = curl_unescape(conn->path, 0); + char *real_path = curl_easy_unescape(conn->data, conn->path, 0, NULL); struct FILEPROTO *file; int fd; #if defined(WIN32) || defined(MSDOS) || defined(__EMX__) diff --git a/lib/ftp.c b/lib/ftp.c index 2c6fc7981..7296b684a 100644 --- a/lib/ftp.c +++ b/lib/ftp.c @@ -72,6 +72,7 @@ #include #include "urldata.h" #include "sendf.h" +#include "easyif.h" /* for Curl_convert_... prototypes */ #include "if2ip.h" #include "hostip.h" @@ -159,12 +160,15 @@ static void freedirs(struct FTP *ftp) } } -/* Returns non-zero iff the given string contains CR (0x0D) or LF (0x0A), which - are not allowed within RFC 959 . - */ +/* Returns non-zero if the given string contains CR (\r) or LF (\n), + which are not allowed within RFC 959 . + Note: The input string is in the client's encoding which might + not be ASCII, so escape sequences \r & \n must be used instead + of hex values 0x0d & 0x0a. +*/ static bool isBadFtpString(const char *string) { - return strchr(string, 0x0D) != NULL || strchr(string, 0x0A) != NULL; + return strchr(string, '\r') != NULL || strchr(string, '\n') != NULL; } /*********************************************************************** @@ -295,6 +299,14 @@ static CURLcode ftp_readresp(curl_socket_t sockfd, /* EWOULDBLOCK */ return CURLE_OK; /* return */ +#ifdef CURL_DOES_CONVERSIONS + if((res == CURLE_OK) && (gotbytes > 0)) { + /* convert from the network encoding */ + result = res = Curl_convert_from_network(data, ptr, gotbytes); + /* Curl_convert_from_network calls failf if unsuccessful */ + } +#endif /* CURL_DOES_CONVERSIONS */ + if(CURLE_OK != res) keepon = FALSE; } @@ -518,6 +530,14 @@ CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */ /* EWOULDBLOCK */ continue; /* go looping again */ +#ifdef CURL_DOES_CONVERSIONS + if((res == CURLE_OK) && (gotbytes > 0)) { + /* convert from the network encoding */ + result = res = Curl_convert_from_network(data, ptr, gotbytes); + /* Curl_convert_from_network calls failf if unsuccessful */ + } +#endif /* CURL_DOES_CONVERSIONS */ + if(CURLE_OK != res) keepon = FALSE; } @@ -1309,6 +1329,8 @@ static CURLcode ftp_state_post_mdtm(struct connectdata *conn) NBFTPSENDF(conn, "TYPE %c", data->set.ftp_ascii?'A':'I'); state(conn, FTP_TYPE); + /* keep track of our current transfer type */ + data->ftp_in_ascii_mode = data->set.ftp_ascii; } else result = ftp_state_post_type(conn); @@ -2871,7 +2893,8 @@ CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode status) if(ftp->prevpath) free(ftp->prevpath); - path = curl_unescape(conn->path, 0); /* get the "raw" path */ + /* get the "raw" path */ + path = curl_easy_unescape(conn->data, conn->path, 0, NULL); if(!path) return CURLE_OUT_OF_MEMORY; @@ -3067,6 +3090,8 @@ static CURLcode ftp_transfertype(struct connectdata *conn, ascii?"ASCII":"binary"); return ascii? CURLE_FTP_COULDNT_SET_ASCII:CURLE_FTP_COULDNT_SET_BINARY; } + /* keep track of our current transfer type */ + data->ftp_in_ascii_mode = ascii; return CURLE_OK; } @@ -3168,6 +3193,8 @@ CURLcode Curl_ftp_nextconnect(struct connectdata *conn) if(data->set.upload) { NBFTPSENDF(conn, "TYPE %c", data->set.ftp_ascii?'A':'I'); state(conn, FTP_STOR_TYPE); + /* keep track of our current transfer type */ + data->ftp_in_ascii_mode = data->set.ftp_ascii; } else { /* download */ @@ -3182,10 +3209,14 @@ CURLcode Curl_ftp_nextconnect(struct connectdata *conn) need to set ASCII transfer mode. */ NBFTPSENDF(conn, "TYPE A", NULL); state(conn, FTP_LIST_TYPE); + /* keep track of our current transfer type */ + data->ftp_in_ascii_mode = 1; } else { NBFTPSENDF(conn, "TYPE %c", data->set.ftp_ascii?'A':'I'); state(conn, FTP_RETR_TYPE); + /* keep track of our current transfer type */ + data->ftp_in_ascii_mode = data->set.ftp_ascii; } } result = ftp_easy_statemach(conn); @@ -3308,6 +3339,14 @@ CURLcode Curl_nbftpsendf(struct connectdata *conn, ftp_respinit(conn); +#ifdef CURL_DOES_CONVERSIONS + res = Curl_convert_to_network(data, s, write_len); + /* Curl_convert_to_network calls failf if unsuccessful */ + if(res != CURLE_OK) { + return res; + } +#endif /* CURL_DOES_CONVERSIONS */ + res = Curl_write(conn, conn->sock[FIRSTSOCKET], sptr, write_len, &bytes_written); @@ -3357,6 +3396,14 @@ CURLcode Curl_ftpsendf(struct connectdata *conn, bytes_written=0; write_len = strlen(s); +#ifdef CURL_DOES_CONVERSIONS + res = Curl_convert_to_network(conn->data, s, write_len); + /* Curl_convert_to_network calls failf if unsuccessful */ + if(res != CURLE_OK) { + return(res); + } +#endif /* CURL_DOES_CONVERSIONS */ + while(1) { res = Curl_write(conn, conn->sock[FIRSTSOCKET], sptr, write_len, &bytes_written); @@ -3747,7 +3794,8 @@ CURLcode ftp_parse_url_path(struct connectdata *conn) if(!ftp->dirs) return CURLE_OUT_OF_MEMORY; - ftp->dirs[0] = curl_unescape(cur_pos, (int)(slash_pos-cur_pos)); + ftp->dirs[0] = curl_easy_unescape(conn->data, cur_pos, + (int)(slash_pos-cur_pos), NULL); if(!ftp->dirs[0]) { free(ftp->dirs); return CURLE_OUT_OF_MEMORY; @@ -3777,8 +3825,9 @@ CURLcode ftp_parse_url_path(struct connectdata *conn) requires a parameter and a non-existant parameter a) doesn't work on many servers and b) has no effect on the others. */ int len = (int)(slash_pos - cur_pos + absolute_dir); - ftp->dirs[ftp->dirdepth] = curl_unescape(cur_pos - absolute_dir, len); - + ftp->dirs[ftp->dirdepth] = curl_easy_unescape(conn->data, + cur_pos - absolute_dir, + len, NULL); if (!ftp->dirs[ftp->dirdepth]) { /* run out of memory ... */ failf(data, "no memory"); freedirs(ftp); @@ -3815,7 +3864,7 @@ CURLcode ftp_parse_url_path(struct connectdata *conn) } if(*ftp->file) { - ftp->file = curl_unescape(ftp->file, 0); + ftp->file = curl_easy_unescape(conn->data, ftp->file, 0, NULL); if(NULL == ftp->file) { freedirs(ftp); failf(data, "no memory"); @@ -3842,7 +3891,7 @@ CURLcode ftp_parse_url_path(struct connectdata *conn) if(ftp->prevpath) { /* prevpath is "raw" so we convert the input path before we compare the strings */ - char *path = curl_unescape(conn->path, 0); + char *path = curl_easy_unescape(conn->data, conn->path, 0, NULL); if(!path) return CURLE_OUT_OF_MEMORY; diff --git a/lib/ldap.c b/lib/ldap.c index d71b513f8..71f145936 100644 --- a/lib/ldap.c +++ b/lib/ldap.c @@ -498,31 +498,31 @@ static char **split_str (char *str) /* * Unescape the LDAP-URL components */ -static bool unescape_elements (LDAPURLDesc *ludp) +static bool unescape_elements (void *data, LDAPURLDesc *ludp) { int i; if (ludp->lud_filter) { - ludp->lud_filter = curl_unescape(ludp->lud_filter, 0); + ludp->lud_filter = curl_easy_unescape(data, ludp->lud_filter, 0); if (!ludp->lud_filter) return (FALSE); } for (i = 0; ludp->lud_attrs && ludp->lud_attrs[i]; i++) { - ludp->lud_attrs[i] = curl_unescape(ludp->lud_attrs[i], 0); + ludp->lud_attrs[i] = curl_easy_unescape(data, ludp->lud_attrs[i], 0); if (!ludp->lud_attrs[i]) return (FALSE); } for (i = 0; ludp->lud_exts && ludp->lud_exts[i]; i++) { - ludp->lud_exts[i] = curl_unescape(ludp->lud_exts[i], 0); + ludp->lud_exts[i] = curl_easy_unescape(data, ludp->lud_exts[i], 0); if (!ludp->lud_exts[i]) return (FALSE); } if (ludp->lud_dn) { char *dn = ludp->lud_dn; - char *new_dn = curl_unescape(dn, 0); + char *new_dn = curl_easy_unescape(data, dn, 0); free(dn); ludp->lud_dn = new_dn; @@ -633,7 +633,7 @@ static int _ldap_url_parse2 (const struct connectdata *conn, LDAPURLDesc *ludp) LDAP_TRACE (("exts[%d] '%s'\n", i, ludp->lud_exts[i])); success: - if (!unescape_elements(ludp)) + if (!unescape_elements(conn->data, ludp)) return LDAP_NO_MEMORY; return LDAP_SUCCESS; } diff --git a/lib/select.c b/lib/select.c index f370b1110..343dc469f 100644 --- a/lib/select.c +++ b/lib/select.c @@ -50,8 +50,8 @@ #include "connect.h" #include "select.h" -#ifdef WIN32 -#define VERIFY_SOCK(x) /* Win-sockets are not in range [0..FD_SETSIZE> */ +#if defined(WIN32) || defined(TPF) +#define VERIFY_SOCK(x) /* sockets are not in range [0..FD_SETSIZE] */ #else #define VALID_SOCK(s) (((s) >= 0) && ((s) < FD_SETSIZE)) #define VERIFY_SOCK(x) do { \ @@ -261,3 +261,23 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms) #endif return r; } + +#ifdef TPF +/* + * This is a replacement for select() on the TPF platform. + * It is used whenever libcurl calls select(). + * The call below to tpf_process_signals() is required because + * TPF's select calls are not signal interruptible. + * + * Return values are the same as select's. + */ +int tpf_select_libcurl(int maxfds, fd_set* reads, fd_set* writes, + fd_set* excepts, struct timeval* tv) +{ + int rc; + + rc = tpf_select_bsd(maxfds, reads, writes, excepts, tv); + tpf_process_signals(); + return(rc); +} +#endif /* TPF */ diff --git a/lib/select.h b/lib/select.h index c3cb22057..f448b8460 100644 --- a/lib/select.h +++ b/lib/select.h @@ -51,5 +51,9 @@ int Curl_select(curl_socket_t readfd, curl_socket_t writefd, int timeout_ms); int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms); +#ifdef TPF +int tpf_select_libcurl(int maxfds, fd_set* reads, fd_set* writes, + fd_set* excepts, struct timeval* tv); +#endif #endif diff --git a/lib/sendf.c b/lib/sendf.c index 4469da798..dda70c42b 100644 --- a/lib/sendf.c +++ b/lib/sendf.c @@ -59,6 +59,7 @@ #include #include "memory.h" #include "strerror.h" +#include "easyif.h" /* for the Curl_convert_from_network prototype */ /* The last #include file should be: */ #include "memdebug.h" @@ -293,6 +294,28 @@ CURLcode Curl_client_write(struct SessionHandle *data, if(0 == len) len = strlen(ptr); +#ifdef CURL_DOES_CONVERSIONS + if(type & CLIENTWRITE_BODY) { + if(data->ftp_in_ascii_mode) { + /* convert from the network encoding */ + size_t rc; + rc = Curl_convert_from_network(data, ptr, len); + /* Curl_convert_from_network calls failf if unsuccessful */ + if(rc != CURLE_OK) { + return(rc); + } + } + if (len) { + wrote = data->set.fwrite(ptr, 1, len, data->set.out); + } else { + wrote = len; + } + if(wrote != len) { + failf (data, "Failed writing body"); + return CURLE_WRITE_ERROR; + } + } +#else if(type & CLIENTWRITE_BODY) { wrote = data->set.fwrite(ptr, 1, len, data->set.out); if(wrote != len) { @@ -300,6 +323,8 @@ CURLcode Curl_client_write(struct SessionHandle *data, return CURLE_WRITE_ERROR; } } +#endif /* CURL_DOES_CONVERSIONS */ + if((type & CLIENTWRITE_HEADER) && (data->set.fwrite_header || data->set.writeheader) ) { /* @@ -309,6 +334,9 @@ CURLcode Curl_client_write(struct SessionHandle *data, curl_write_callback writeit= data->set.fwrite_header?data->set.fwrite_header:data->set.fwrite; + /* Note: The header is in the host encoding + regardless of the ftp transfer mode (ASCII/Image) */ + wrote = writeit(ptr, 1, len, data->set.writeheader); if(wrote != len) { failf (data, "Failed writing header"); @@ -375,6 +403,29 @@ static int showit(struct SessionHandle *data, curl_infotype type, static const char * const s_infotype[CURLINFO_END] = { "* ", "< ", "> ", "{ ", "} ", "{ ", "} " }; +#ifdef CURL_DOES_CONVERSIONS + char buf[BUFSIZE+1]; + + switch(type) { + case CURLINFO_HEADER_OUT: + /* assume output headers are ASCII */ + /* copy the data into my buffer so the original is unchanged */ + if (size > BUFSIZE) { + size = BUFSIZE; /* truncate if necessary */ + buf[BUFSIZE] = '\0'; + } + memcpy(buf, ptr, size); + Curl_convert_from_network(data, buf, size); + /* Curl_convert_from_network calls failf if unsuccessful */ + /* we might as well continue even if it fails... */ + ptr = buf; /* switch pointer to use my buffer instead */ + break; + default: + /* leave everything else as-is */ + break; + } +#endif /* CURL_DOES_CONVERSIONS */ + if(data->set.fdebug) return (*data->set.fdebug)(data, type, ptr, size, data->set.debugdata); diff --git a/lib/setup.h b/lib/setup.h index ea8b4691c..fc64698dd 100644 --- a/lib/setup.h +++ b/lib/setup.h @@ -67,6 +67,12 @@ #include "amigaos.h" #endif +#ifdef TPF +#include "config-tpf.h" /* hand-modified TPF config.h */ +/* change which select is used for libcurl */ +#define select(a,b,c,d,e) tpf_select_libcurl(a,b,c,d,e) +#endif + #endif /* HAVE_CONFIG_H */ /* diff --git a/lib/ssluse.c b/lib/ssluse.c index 7be5a7cad..60d174fd1 100644 --- a/lib/ssluse.c +++ b/lib/ssluse.c @@ -68,6 +68,7 @@ #endif #include "memory.h" +#include "easyif.h" /* for Curl_convert_from_utf8 prototype */ /* The last #include file should be: */ #include "memdebug.h" @@ -972,6 +973,17 @@ static CURLcode verifyhost(struct connectdata *conn, if (peer_CN == nulstr) peer_CN = NULL; +#ifdef CURL_DOES_CONVERSIONS + else { + /* convert peer_CN from UTF8 */ + size_t rc; + rc = Curl_convert_from_utf8(data, peer_CN, strlen(peer_CN)); + /* Curl_convert_from_utf8 calls failf if unsuccessful */ + if (rc != CURLE_OK) { + return(rc); + } + } +#endif /* CURL_DOES_CONVERSIONS */ if (!peer_CN) { if(data->set.ssl.verifyhost > 1) { diff --git a/lib/strerror.c b/lib/strerror.c index 216ac2964..b690fc1b7 100644 --- a/lib/strerror.c +++ b/lib/strerror.c @@ -132,7 +132,11 @@ curl_easy_strerror(CURLcode error) return "failed to open/read local data from file/application"; case CURLE_OUT_OF_MEMORY: +#ifdef CURL_DOES_CONVERSIONS + return "conversion failed -or- out of memory"; +#else return "out of memory"; +#endif /* CURL_DOES_CONVERSIONS */ case CURLE_OPERATION_TIMEOUTED: return "a timeout was reached"; @@ -266,6 +270,12 @@ curl_easy_strerror(CURLcode error) case CURLE_TFTP_NOSUCHUSER: return "TFTP: No such user";; + case CURLE_CONV_FAILED: + return "conversion failed"; + + case CURLE_CONV_REQD: + return "caller must register CURLOPT_CONV_ callback options"; + case CURLE_URL_MALFORMAT_USER: /* not used by current libcurl */ case CURLE_MALFORMAT_USER: /* not used by current libcurl */ case CURLE_BAD_CALLING_ORDER: /* not used by current libcurl */ diff --git a/lib/tftp.c b/lib/tftp.c index 711bf1720..9c459a975 100644 --- a/lib/tftp.c +++ b/lib/tftp.c @@ -261,11 +261,10 @@ static void tftp_send_first(tftp_state_data_t *state, tftp_event_t event) if(data->set.upload) { /* If we are uploading, send an WRQ */ state->spacket.event = htons(TFTP_EVENT_WRQ); - filename = curl_unescape(filename, (int)strlen(filename)); + filename = curl_easy_unescape(data, filename, 0, NULL); state->conn->upload_fromhere = (char *)state->spacket.u.data.data; - if(data->set.infilesize != -1) { + if(data->set.infilesize != -1) Curl_pgrsSetUploadSize(data, data->set.infilesize); - } } else { /* If we are downloading, send an RRQ */ diff --git a/lib/transfer.c b/lib/transfer.c index 6fa8f6334..6bd2dc904 100644 --- a/lib/transfer.c +++ b/lib/transfer.c @@ -101,6 +101,7 @@ #include "share.h" #include "memory.h" #include "select.h" +#include "easyif.h" /* for Curl_convert_to_network prototype */ #define _MPRINTF_REPLACE /* use our functions only */ #include @@ -167,6 +168,17 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp) *nreadp = nread; +#ifdef CURL_DOES_CONVERSIONS + if(data->ftp_in_ascii_mode) { + CURLcode res; + res = Curl_convert_to_network(data, conn->upload_fromhere, nread); + /* Curl_convert_to_network calls failf if unsuccessful */ + if(res != CURLE_OK) { + return(res); + } + } +#endif /* CURL_DOES_CONVERSIONS */ + return CURLE_OK; } diff --git a/lib/url.c b/lib/url.c index 3b5eb97b3..a21ef5ba6 100644 --- a/lib/url.c +++ b/lib/url.c @@ -265,6 +265,19 @@ CURLcode Curl_close(struct SessionHandle *data) ares_destroy(data->state.areschannel); #endif +#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV) + /* close iconv conversion descriptors */ + if (data->inbound_cd != (iconv_t)-1) { + iconv_close(data->inbound_cd); + } + if (data->outbound_cd != (iconv_t)-1) { + iconv_close(data->outbound_cd); + } + if (data->utf8_cd != (iconv_t)-1) { + iconv_close(data->utf8_cd); + } +#endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */ + /* No longer a dirty share, if it exists */ if (data->share) data->share->dirty--; @@ -318,6 +331,18 @@ CURLcode Curl_open(struct SessionHandle **curl) /* use fread as default function to read input */ data->set.fread = (curl_read_callback)fread; + /* conversion callbacks for non-ASCII hosts */ + data->set.convfromnetwork = (curl_conv_callback)NULL; + data->set.convtonetwork = (curl_conv_callback)NULL; + data->set.convfromutf8 = (curl_conv_callback)NULL; + +#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV) + /* conversion descriptors for iconv calls */ + data->outbound_cd = (iconv_t)-1; + data->inbound_cd = (iconv_t)-1; + data->utf8_cd = (iconv_t)-1; +#endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */ + data->set.infilesize = -1; /* we don't know any size */ data->set.postfieldsize = -1; data->set.maxredirs = -1; /* allow any amount by default */ @@ -1167,6 +1192,24 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* When set to NULL, reset to our internal default function */ data->set.fread = (curl_read_callback)fread; break; + case CURLOPT_CONV_FROM_NETWORK_FUNCTION: + /* + * "Convert from network encoding" callback + */ + data->set.convfromnetwork = va_arg(param, curl_conv_callback); + break; + case CURLOPT_CONV_TO_NETWORK_FUNCTION: + /* + * "Convert to network encoding" callback + */ + data->set.convtonetwork = va_arg(param, curl_conv_callback); + break; + case CURLOPT_CONV_FROM_UTF8_FUNCTION: + /* + * "Convert from UTF-8 encoding" callback + */ + data->set.convfromutf8 = va_arg(param, curl_conv_callback); + break; case CURLOPT_IOCTLFUNCTION: /* * I/O control callback. Might be NULL. @@ -2795,11 +2838,11 @@ static CURLcode CreateConnection(struct SessionHandle *data, "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^\n]", proxyuser, proxypasswd); - conn->proxyuser = curl_unescape(proxyuser,0); + conn->proxyuser = curl_easy_unescape(data, proxyuser, 0, NULL); if(!conn->proxyuser) return CURLE_OUT_OF_MEMORY; - conn->proxypasswd = curl_unescape(proxypasswd,0); + conn->proxypasswd = curl_easy_unescape(data, proxypasswd, 0, NULL); if(!conn->proxypasswd) return CURLE_OUT_OF_MEMORY; } @@ -3236,13 +3279,13 @@ static CURLcode CreateConnection(struct SessionHandle *data, username or password with reserved characters like ':' in them. */ Curl_safefree(conn->proxyuser); - conn->proxyuser = curl_unescape(proxyuser,0); + conn->proxyuser = curl_easy_unescape(data, proxyuser, 0, NULL); if(!conn->proxyuser) res = CURLE_OUT_OF_MEMORY; else { Curl_safefree(conn->proxypasswd); - conn->proxypasswd = curl_unescape(proxypasswd,0); + conn->proxypasswd = curl_easy_unescape(data, proxypasswd, 0, NULL); if(!conn->proxypasswd) res = CURLE_OUT_OF_MEMORY; @@ -3378,7 +3421,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, sscanf(userpass, ":%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]", passwd); if(user[0]) { - char *newname=curl_unescape(user, 0); + char *newname=curl_easy_unescape(data, user, 0, NULL); if(!newname) return CURLE_OUT_OF_MEMORY; if(strlen(newname) < sizeof(user)) @@ -3390,7 +3433,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, } if (passwd[0]) { /* we have a password found in the URL, decode it! */ - char *newpasswd=curl_unescape(passwd, 0); + char *newpasswd=curl_easy_unescape(data, passwd, 0, NULL); if(!newpasswd) return CURLE_OUT_OF_MEMORY; if(strlen(newpasswd) < sizeof(passwd)) diff --git a/lib/urldata.h b/lib/urldata.h index 6843925e0..a970b7377 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -219,6 +219,10 @@ typedef enum { #include #endif +#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV) +#include +#endif + /* Struct used for NTLM challenge-response authentication */ struct ntlmdata { curlntlm state; @@ -1007,6 +1011,15 @@ struct UserDefined { curl_progress_callback fprogress; /* function for progress information */ curl_debug_callback fdebug; /* function that write informational data */ curl_ioctl_callback ioctl; /* function for I/O control */ + + /* the 3 curl_conv_callback functions below are used on non-ASCII hosts */ + /* function to convert from the network encoding: */ + curl_conv_callback convfromnetwork; + /* function to convert to the network encoding: */ + curl_conv_callback convtonetwork; + /* function to convert from UTF-8 encoding: */ + curl_conv_callback convfromutf8; + void *progress_client; /* pointer to pass to the progress callback */ void *ioctl_client; /* pointer to pass to the ioctl callback */ long timeout; /* in seconds, 0 means no timeout */ @@ -1137,6 +1150,13 @@ struct SessionHandle { struct UrlState state; /* struct for fields used for state info and other dynamic purposes */ struct PureInfo info; /* stats, reports and info data */ + /* set by ftp_transfertype for use by Curl_client_write and others */ + bool ftp_in_ascii_mode; +#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV) + iconv_t outbound_cd; /* for translating to the network encoding */ + iconv_t inbound_cd; /* for translating from the network encoding */ + iconv_t utf8_cd; /* for translating to UTF8 */ +#endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */ }; #define LIBCURL_NAME "libcurl" diff --git a/src/main.c b/src/main.c index 10aafd81c..4c432f19c 100644 --- a/src/main.c +++ b/src/main.c @@ -104,6 +104,14 @@ versions instead */ #include /* header from the libcurl directory */ +#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV) +#include +/* set default codesets for iconv */ +#ifndef CURL_ICONV_CODESET_OF_NETWORK +#define CURL_ICONV_CODESET_OF_NETWORK "ISO8859-1" +#endif +#endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */ + /* The last #include file should be: */ #ifdef CURLDEBUG #ifndef CURLTOOLDEBUG @@ -153,7 +161,9 @@ typedef enum { } HttpReq; /* Just a set of bits */ +#ifndef CONF_DEFAULT #define CONF_DEFAULT 0 +#endif #define CONF_AUTO_REFERER (1<<4) /* the automatic referer-system please! */ #define CONF_HEADER (1<<8) /* throw the header out too */ @@ -211,6 +221,10 @@ char *strdup(char *str) #define struct_stat struct stat #endif +#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV) +iconv_t inbound_cd = (iconv_t)-1; +#endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */ + #ifdef WIN32 /* * Truncate a file handle at a 64-bit position 'where'. @@ -420,6 +434,12 @@ static CURLcode main_init(void) static void main_free(void) { curl_global_cleanup(); +#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV) + /* close iconv conversion descriptor */ + if (inbound_cd != (iconv_t)-1) { + iconv_close(inbound_cd); + } +#endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */ } static int SetHTTPrequest(struct Configurable *config, @@ -2924,10 +2944,77 @@ void progressbarinit(struct ProgressData *bar, bar->out = config->errors; } +#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV) +/* + * convert_from_network() is an internal function + * for performing ASCII conversions on non-ASCII platforms. + */ +CURLcode +convert_from_network(char *buffer, size_t length) +{ + CURLcode rc; + + /* translate from the network encoding to the host encoding */ + char *input_ptr, *output_ptr; + size_t in_bytes, out_bytes; + + /* open an iconv conversion descriptor if necessary */ + if(inbound_cd == (iconv_t)-1) { + inbound_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST, + CURL_ICONV_CODESET_OF_NETWORK); + if(inbound_cd == (iconv_t)-1) { + return CURLE_CONV_FAILED; + } + } + /* call iconv */ + input_ptr = output_ptr = buffer; + in_bytes = out_bytes = length; + rc = iconv(inbound_cd, &input_ptr, &in_bytes, + &output_ptr, &out_bytes); + if ((rc == -1) || (in_bytes != 0)) { + return CURLE_CONV_FAILED; + } + + return CURLE_OK; +} + +static +char convert_char(curl_infotype infotype, char this_char) { +/* determine how this specific character should be displayed */ + switch(infotype) { + case CURLINFO_DATA_IN: + case CURLINFO_DATA_OUT: + case CURLINFO_SSL_DATA_IN: + case CURLINFO_SSL_DATA_OUT: + /* data, treat as ASCII */ + if ((this_char >= 0x20) && (this_char < 0x7f)) { + /* printable ASCII hex value: convert to host encoding */ + convert_from_network(&this_char, 1); + } else { + /* non-printable ASCII, use a replacement character */ + return(UNPRINTABLE_CHAR); + } + /* fall through to default */ + default: + /* treat as host encoding */ + if (isprint(this_char) + && (this_char != '\t') + && (this_char != '\r') + && (this_char != '\n')) { + /* printable characters excluding tabs and line end characters */ + return(this_char); + } + break; + } + /* non-printable, use a replacement character */ + return(UNPRINTABLE_CHAR); +} +#endif /* CURL_DOES_CONVERSIONS */ + static void dump(char *timebuf, const char *text, FILE *stream, unsigned char *ptr, size_t size, - trace tracetype) + trace tracetype, curl_infotype infotype) { size_t i; size_t c; @@ -2960,8 +3047,14 @@ void dump(char *timebuf, const char *text, i+=(c+2-width); break; } +#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV) + /* convert to host encoding and print this character */ + fprintf(stream, "%c", convert_char(infotype, ptr[i+c])); +#else + (void)infotype; fprintf(stream, "%c", - (ptr[i+c]>=0x20) && (ptr[i+c]<0x80)?ptr[i+c]:'.'); + (ptr[i+c]>=0x20) && (ptr[i+c]<0x80)?ptr[i+c]:UNPRINTABLE_CHAR); +#endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */ /* check again for 0D0A, to avoid an extra \n if it's at width */ if ((tracetype == TRACE_ASCII) && (i+c+2 < size) && ptr[i+c+1]==0x0D && ptr[i+c+2]==0x0A) { @@ -3084,7 +3177,7 @@ int my_trace(CURL *handle, curl_infotype type, break; } - dump(timebuf, text, output, data, size, config->tracetype); + dump(timebuf, text, output, data, size, config->tracetype, type); return 0; } @@ -3652,7 +3745,7 @@ operate(struct Configurable *config, int argc, char *argv[]) filep = uploadfile; /* URL encode the file name */ - filep = curl_escape(filep, 0 /* use strlen */); + filep = curl_easy_escape(curl, filep, 0 /* use strlen */); if(filep) { diff --git a/src/setup.h b/src/setup.h index 934ce9ca1..61726d61b 100644 --- a/src/setup.h +++ b/src/setup.h @@ -60,6 +60,14 @@ #include "config-amigaos.h" #endif +#ifdef TPF +#include "config-tpf.h" +/* change which select is used for the curl command line tool */ +#define select(a,b,c,d,e) tpf_select_bsd(a,b,c,d,e) +/* and turn off the progress meter */ +#define CONF_DEFAULT (0|CONF_NOPROGRESS) +#endif + #endif /* HAVE_CONFIG_H */ #if defined(CURLDEBUG) && defined(CURLTOOLDEBUG) @@ -162,4 +170,9 @@ int fileno( FILE *stream); #define SIZEOF_CURL_OFF_T sizeof(curl_off_t) #endif +#ifndef UNPRINTABLE_CHAR +/* define what to use for unprintable characters */ +#define UNPRINTABLE_CHAR '.' +#endif + #endif /* __SRC_CURL_SETUP_H */ -- cgit v1.2.3