aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/libcurl/Makefile.am7
-rw-r--r--docs/libcurl/curl_easy_escape.347
-rw-r--r--docs/libcurl/curl_easy_unescape.348
-rw-r--r--docs/libcurl/curl_escape.35
-rw-r--r--docs/libcurl/curl_unescape.37
-rw-r--r--include/curl/curl.h50
-rw-r--r--lib/config-tpf.h652
-rw-r--r--lib/easy.c189
-rw-r--r--lib/easyif.h7
-rw-r--r--lib/escape.c54
-rw-r--r--lib/escape.h4
-rw-r--r--lib/file.c4
-rw-r--r--lib/ftp.c69
-rw-r--r--lib/ldap.c12
-rw-r--r--lib/select.c24
-rw-r--r--lib/select.h4
-rw-r--r--lib/sendf.c51
-rw-r--r--lib/setup.h6
-rw-r--r--lib/ssluse.c12
-rw-r--r--lib/strerror.c10
-rw-r--r--lib/tftp.c5
-rw-r--r--lib/transfer.c12
-rw-r--r--lib/url.c55
-rw-r--r--lib/urldata.h20
-rw-r--r--src/main.c101
-rw-r--r--src/setup.h13
26 files changed, 1422 insertions, 46 deletions
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, <daniel@haxx.se>, 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 <curl/curl.h>
+.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, <daniel@haxx.se>, 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 <curl/curl.h>
+.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 <alloca.h> header file. */
+#define HAVE_ALLOCA_H 1
+
+/* Define to 1 if you have the <arpa/inet.h> header file. */
+#define HAVE_ARPA_INET_H 1
+
+/* Define to 1 if you have the <assert.h> 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 <crypto.h> header file. */
+/* #undef HAVE_CRYPTO_H */
+#define HAVE_CRYPTO_H 1
+
+/* Define to 1 if you have the <des.h> 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 <dlfcn.h> 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 <errno.h> header file. */
+#define HAVE_ERRNO_H 1
+
+/* Define to 1 if you have the <err.h> header file. */
+/* #undef HAVE_ERR_H */
+#define HAVE_ERR_H 1
+
+/* Define to 1 if you have the <fcntl.h> 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 <idn-free.h> 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 <inttypes.h> 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 <io.h> 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 <krb.h> 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 <libgen.h> 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 <limits.h> header file. */
+#define HAVE_LIMITS_H 1
+
+/* if your compiler supports LL */
+#define HAVE_LL 1
+
+/* Define to 1 if you have the <locale.h> 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 <malloc.h> header file. */
+#define HAVE_MALLOC_H 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the <netdb.h> header file. */
+#define HAVE_NETDB_H 1
+
+/* Define to 1 if you have the <netinet/in.h> header file. */
+#define HAVE_NETINET_IN_H 1
+
+/* Define to 1 if you have the <netinet/tcp.h> header file. */
+/* undef HAVE_NETINET_TCP_H */
+
+/* Define to 1 if you have the <net/if.h> 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 <openssl/crypto.h> header file. */
+/* #undef HAVE_OPENSSL_CRYPTO_H */
+#define HAVE_OPENSSL_CRYPTO_H 1
+
+/* Define to 1 if you have the <openssl/engine.h> header file. */
+/* #undef HAVE_OPENSSL_ENGINE_H */
+#define HAVE_OPENSSL_ENGINE_H 1
+
+/* Define to 1 if you have the <openssl/err.h> header file. */
+/* #undef HAVE_OPENSSL_ERR_H */
+#define HAVE_OPENSSL_ERR_H 1
+
+/* Define to 1 if you have the <openssl/pem.h> header file. */
+/* #undef HAVE_OPENSSL_PEM_H */
+#define HAVE_OPENSSL_PEM_H 1
+
+/* Define to 1 if you have the <openssl/pkcs12.h> header file. */
+/* #undef HAVE_OPENSSL_PKCS12_H */
+#define HAVE_OPENSSL_PKCS12_H 1
+
+/* Define to 1 if you have the <openssl/rsa.h> header file. */
+/* #undef HAVE_OPENSSL_RSA_H */
+#define HAVE_OPENSSL_RSA_H 1
+
+/* Define to 1 if you have the <openssl/ssl.h> header file. */
+/* #undef HAVE_OPENSSL_SSL_H */
+#define HAVE_OPENSSL_SSL_H 1
+
+/* Define to 1 if you have the <openssl/x509.h> 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 <pem.h> 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 <pwd.h> 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 <rsa.h> 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 <setjmp.h> 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 <sgtty.h> 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 <ssl.h> header file. */
+/* #undef HAVE_SSL_H */
+#define HAVE_SSL_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> 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 <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> 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 <sys/ioctl.h> header file. */
+#define HAVE_SYS_IOCTL_H 1
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#define HAVE_SYS_PARAM_H 1
+
+/* Define to 1 if you have the <sys/poll.h> header file. */
+/* #undef HAVE_SYS_POLL_H */
+
+/* Define to 1 if you have the <sys/resource.h> header file. */
+#define HAVE_SYS_RESOURCE_H 1
+
+/* Define to 1 if you have the <sys/select.h> header file. */
+#define HAVE_SYS_SELECT_H 1
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#define HAVE_SYS_SOCKET_H 1
+
+/* Define to 1 if you have the <sys/sockio.h> header file. */
+/* #undef HAVE_SYS_SOCKIO_H */
+#define HAVE_SYS_SOCKIO_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#define HAVE_SYS_TIME_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <sys/utime.h> header file. */
+/* #undef HAVE_SYS_UTIME_H */
+
+/* Define to 1 if you have the <termios.h> header file. */
+/* #undef HAVE_TERMIOS_H */
+
+/* Define to 1 if you have the <termio.h> header file. */
+/* #undef HAVE_TERMIO_H */
+
+/* Define to 1 if you have the <time.h> header file. */
+#define HAVE_TIME_H 1
+
+/* Define to 1 if you have the <tld.h> 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 <unistd.h> 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 <utime.h> header file. */
+#define HAVE_UTIME_H 1
+
+/* Define to 1 if you have the <winsock2.h> header file. */
+/* #undef HAVE_WINSOCK2_H */
+
+/* Define to 1 if you have the <winsock.h> 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 <x509.h> 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 <sys/time.h> and <time.h>. */
+#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 <sys/types.h> 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 <strings.h> /* for bzero, strcasecmp, and strncasecmp */
+#include <string.h> /* for strcpy and strlen */
+#include <stdlib.h> /* for rand and srand */
+#include <sys/socket.h> /* for select and ioctl*/
+#include <netdb.h> /* for in_addr_t definition */
+#include <tpf/sysapi.h> /* 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 <curl/mprintf.h>
+#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
+#include <iconv.h>
+/* 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, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, 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 <stdlib.h>
#include <string.h>
#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 <curl/mprintf.h>
@@ -39,8 +42,20 @@
/* 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;
char *testing_ptr = NULL;
@@ -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, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, 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, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, 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 <curl/curl.h>
#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 <string>.
- */
+/* Returns non-zero if the given string contains CR (\r) or LF (\n),
+ which are not allowed within RFC 959 <string>.
+ 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 <string.h>
#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 <curl/mprintf.h>
@@ -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 <rpc.h>
#endif
+#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
+#include <iconv.h>
+#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 <curlx.h> /* header from the libcurl directory */
+#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
+#include <iconv.h>
+/* 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 */