From 3ad91bf9d39c22dc6941068e6fdc1453988f0b07 Mon Sep 17 00:00:00 2001
From: Andy Cedilnik <andy.cedilnik@kitware.com>
Date: Thu, 9 Jan 2003 23:26:37 -0500
Subject: New version of libcurl

---
 Source/CTest/Curl/CMakeLists.txt     |   19 +-
 Source/CTest/Curl/arpa_telnet.h      |   20 +-
 Source/CTest/Curl/base64.c           |   16 +-
 Source/CTest/Curl/base64.h           |   16 +-
 Source/CTest/Curl/ca-bundle.h        |   31 +
 Source/CTest/Curl/config.h.in        |  545 ++++++++++-------
 Source/CTest/Curl/connect.c          |  195 ++++--
 Source/CTest/Curl/connect.h          |   27 +-
 Source/CTest/Curl/content_encoding.c |  122 ++++
 Source/CTest/Curl/content_encoding.h |   34 ++
 Source/CTest/Curl/cookie.c           |  106 +++-
 Source/CTest/Curl/cookie.h           |   23 +-
 Source/CTest/Curl/curl/curl.h        |  351 +++++++++--
 Source/CTest/Curl/curl/easy.h        |   16 +-
 Source/CTest/Curl/curl/stdcheaders.h |   16 +-
 Source/CTest/Curl/curl/types.h       |   16 +-
 Source/CTest/Curl/dict.c             |   16 +-
 Source/CTest/Curl/dict.h             |   19 +-
 Source/CTest/Curl/easy.c             |   23 +-
 Source/CTest/Curl/escape.c           |   40 +-
 Source/CTest/Curl/escape.h           |   16 +-
 Source/CTest/Curl/file.c             |   36 +-
 Source/CTest/Curl/file.h             |   18 +-
 Source/CTest/Curl/formdata.c         |  427 ++++++++-----
 Source/CTest/Curl/formdata.h         |   29 +-
 Source/CTest/Curl/ftp.c              |  520 ++++++++--------
 Source/CTest/Curl/ftp.h              |   24 +-
 Source/CTest/Curl/getenv.c           |   16 +-
 Source/CTest/Curl/getinfo.c          |   34 +-
 Source/CTest/Curl/getinfo.h          |   16 +-
 Source/CTest/Curl/getpass.c          |   56 +-
 Source/CTest/Curl/getpass.h          |   16 +-
 Source/CTest/Curl/hash.c             |  311 +++++-----
 Source/CTest/Curl/hash.h             |   77 +--
 Source/CTest/Curl/hostip.c           |  396 ++++++++----
 Source/CTest/Curl/hostip.h           |   53 +-
 Source/CTest/Curl/http.c             |  197 +++---
 Source/CTest/Curl/http.h             |   20 +-
 Source/CTest/Curl/http_chunks.c      |   47 +-
 Source/CTest/Curl/http_chunks.h      |   17 +-
 Source/CTest/Curl/if2ip.c            |   16 +-
 Source/CTest/Curl/if2ip.h            |   16 +-
 Source/CTest/Curl/krb4.c             |    6 +-
 Source/CTest/Curl/krb4.h             |   16 +-
 Source/CTest/Curl/ldap.c             |   20 +-
 Source/CTest/Curl/ldap.h             |   19 +-
 Source/CTest/Curl/llist.c            |   42 +-
 Source/CTest/Curl/llist.h            |   32 +-
 Source/CTest/Curl/memdebug.c         |   30 +-
 Source/CTest/Curl/memdebug.h         |   23 +
 Source/CTest/Curl/mprintf.c          |   21 +-
 Source/CTest/Curl/multi.c            |  297 +++++++--
 Source/CTest/Curl/netrc.c            |   68 ++-
 Source/CTest/Curl/netrc.h            |   21 +-
 Source/CTest/Curl/progress.c         |   39 +-
 Source/CTest/Curl/progress.h         |   18 +-
 Source/CTest/Curl/security.c         |    2 +
 Source/CTest/Curl/security.h         |   16 +-
 Source/CTest/Curl/sendf.c            |  184 ++++--
 Source/CTest/Curl/sendf.h            |   21 +-
 Source/CTest/Curl/setup.h            |   30 +-
 Source/CTest/Curl/speedcheck.c       |   16 +-
 Source/CTest/Curl/speedcheck.h       |   16 +-
 Source/CTest/Curl/ssluse.c           |   72 ++-
 Source/CTest/Curl/ssluse.h           |   16 +-
 Source/CTest/Curl/strequal.c         |   16 +-
 Source/CTest/Curl/strequal.h         |   20 +-
 Source/CTest/Curl/strtok.c           |   16 +-
 Source/CTest/Curl/strtok.h           |   16 +-
 Source/CTest/Curl/telnet.c           |   37 +-
 Source/CTest/Curl/telnet.h           |   19 +-
 Source/CTest/Curl/timeval.c          |   66 +-
 Source/CTest/Curl/timeval.h          |   16 +-
 Source/CTest/Curl/transfer.c         |  834 ++++++++++++++++++--------
 Source/CTest/Curl/transfer.h         |   19 +-
 Source/CTest/Curl/url.c              | 1092 +++++++++++++++++++++++++---------
 Source/CTest/Curl/url.h              |   20 +-
 Source/CTest/Curl/urldata.h          |  124 +++-
 Source/CTest/Curl/version.c          |  146 ++++-
 79 files changed, 5044 insertions(+), 2431 deletions(-)
 create mode 100644 Source/CTest/Curl/ca-bundle.h
 create mode 100644 Source/CTest/Curl/content_encoding.c
 create mode 100644 Source/CTest/Curl/content_encoding.h

diff --git a/Source/CTest/Curl/CMakeLists.txt b/Source/CTest/Curl/CMakeLists.txt
index 898d64f..515b411 100644
--- a/Source/CTest/Curl/CMakeLists.txt
+++ b/Source/CTest/Curl/CMakeLists.txt
@@ -2,7 +2,8 @@ CMAKE_MINIMUM_REQUIRED(VERSION 1.5)
 PROJECT(LIBCURL C)
 
 SET(PACKAGE "curl")
-SET(VERSION "7.9.5")
+SET(VERSION "7.10.2")
+SET(PACKAGE_TARNAME " ")
 SET(OPERATING_SYSTEM ${CMAKE_SYSTEM_NAME})
 
 SET(CMAKE_C_FLAGS "${CMAKE_ANSI_CFLAGS} ${CMAKE_C_FLAGS}")
@@ -52,6 +53,7 @@ SET(libCurl_SRCS
     llist.c
     hash.c
     multi.c
+    content_encoding.c
     )
 
 IF(WIN32)
@@ -86,6 +88,11 @@ IF(HAVE_LIBWS2_32)
   SET(CURL_LIBS ${CURL_LIBS} ws2_32)
 ENDIF(HAVE_LIBWS2_32)
 
+CHECK_LIBRARY_EXISTS("z;${CURL_LIBS}" inflateEnd "" HAVE_LIBZ)
+IF(HAVE_LIBZ)
+  SET(CURL_LIBS ${CURL_LIBS} z)
+ENDIF(HAVE_LIBZ)
+
 SET(CMAKE_REQUIRED_LIBRARIES ${CURL_LIBS})
 
 CHECK_INCLUDE_FILE("sys/types.h"    HAVE_SYS_TYPES_H)
@@ -97,6 +104,8 @@ CHECK_INCLUDE_FILE("fcntl.h"    HAVE_FCNTL_H)
 CHECK_INCLUDE_FILE("malloc.h"    HAVE_MALLOC_H)
 CHECK_INCLUDE_FILE("memory.h"    HAVE_MEMORY_H)
 CHECK_INCLUDE_FILE("netdb.h"    HAVE_NETDB_H)
+CHECK_INCLUDE_FILE("zlib.h"    HAVE_ZLIB_H)
+CHECK_INCLUDE_FILE("sys/poll.h"    HAVE_SYS_POLL_H)
 CHECK_INCLUDE_FILE("netinet/in.h"    HAVE_NETINET_IN_H)
 CHECK_INCLUDE_FILE("sys/socket.h"    HAVE_SYS_SOCKET_H)
 
@@ -140,6 +149,7 @@ CHECK_INCLUDE_FILE("winsock.h"    HAVE_WINSOCK_H)
 CHECK_INCLUDE_FILE("sockio.h"    HAVE_SOCKIO_H)
 CHECK_INCLUDE_FILE("sys/sockio.h"    HAVE_SYS_SOCKIO_H)
 CHECK_INCLUDE_FILE("x509.h"    HAVE_X509_H)
+CHECK_INCLUDE_FILE("setjmp.h"    HAVE_SETJMP_H)
 
 CHECK_TYPE_SIZE(ssize_t  SIZEOF_SSIZE_T)
 CHECK_TYPE_SIZE("long double"  SIZEOF_LONG_DOUBLE)
@@ -153,6 +163,7 @@ CHECK_FUNCTION_EXISTS(_doprnt        HAVE_DOPRNT)
 CHECK_FUNCTION_EXISTS(vprintf        HAVE_VPRINTF)
 
 CHECK_FUNCTION_EXISTS(socket            HAVE_SOCKET)
+CHECK_FUNCTION_EXISTS(poll              HAVE_POLL)
 CHECK_FUNCTION_EXISTS(select            HAVE_SELECT)
 CHECK_FUNCTION_EXISTS(strdup            HAVE_STRDUP)
 CHECK_FUNCTION_EXISTS(strstr            HAVE_STRSTR)
@@ -175,6 +186,12 @@ CHECK_FUNCTION_EXISTS(closesocket       HAVE_CLOSESOCKET)
 CHECK_FUNCTION_EXISTS(setvbuf           HAVE_SETVBUF)
 CHECK_FUNCTION_EXISTS(sigaction         HAVE_SIGACTION)
 CHECK_FUNCTION_EXISTS(signal            HAVE_SIGNAL)
+CHECK_FUNCTION_EXISTS(sigsetjmp         HAVE_SIGSETJMP)
+CHECK_FUNCTION_EXISTS(__sigsetjmp       HAVE___SIGSETJMP)
+IF(HAVE___SIGSETJMP)
+  SET(HAVE_SIGSETJMP 1)
+ENDIF(HAVE___SIGSETJMP)
+
 CHECK_FUNCTION_EXISTS(getpass_r         HAVE_GETPASS_R)
 CHECK_FUNCTION_EXISTS(strlcat           HAVE_STRLCAT)
 CHECK_FUNCTION_EXISTS(getpwuid          HAVE_GETPWUID)
diff --git a/Source/CTest/Curl/arpa_telnet.h b/Source/CTest/Curl/arpa_telnet.h
index 52ac66b..2cf0241 100644
--- a/Source/CTest/Curl/arpa_telnet.h
+++ b/Source/CTest/Curl/arpa_telnet.h
@@ -1,28 +1,28 @@
 #ifndef __ARPA_TELNET_H
 #define __ARPA_TELNET_H
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
-
+ ***************************************************************************/
+#ifndef CURL_DISABLE_TELNET
 /*
  * Telnet option defines. Add more here if in need.
  */
@@ -97,5 +97,5 @@ static const char *telnetcmds[]=
 #define TELCMD_OK(x) ( ((unsigned int)(x) >= TELCMD_MINIMUM) && \
                        ((unsigned int)(x) <= TELCMD_MAXIMUM) )
 #define TELCMD(x)    telnetcmds[(x)-TELCMD_MINIMUM]
-
+#endif
 #endif
diff --git a/Source/CTest/Curl/base64.c b/Source/CTest/Curl/base64.c
index af4beb2..41c451a 100644
--- a/Source/CTest/Curl/base64.c
+++ b/Source/CTest/Curl/base64.c
@@ -1,25 +1,25 @@
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2001, Andrew Francis and Daniel Stenberg
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 
 /* Base64 encoding/decoding
  *
diff --git a/Source/CTest/Curl/base64.h b/Source/CTest/Curl/base64.h
index 55f86d5..5bda7d6 100644
--- a/Source/CTest/Curl/base64.h
+++ b/Source/CTest/Curl/base64.h
@@ -1,27 +1,27 @@
 #ifndef __BASE64_H
 #define __BASE64_H
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 int Curl_base64_encode(const void *data, int size, char **str);
 int Curl_base64_decode(const char *str, void *data);
 #endif
diff --git a/Source/CTest/Curl/ca-bundle.h b/Source/CTest/Curl/ca-bundle.h
new file mode 100644
index 0000000..1545372
--- /dev/null
+++ b/Source/CTest/Curl/ca-bundle.h
@@ -0,0 +1,31 @@
+#ifndef __CA_BUNDLE_H
+#define __CA_BUNDLE_H
+/*****************************************************************************
+ *                                  _   _ ____  _     
+ *  Project                     ___| | | |  _ \| |    
+ *                             / __| | | | |_) | |    
+ *                            | (__| |_| |  _ <| |___ 
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2002, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * In order to be useful for every potential user, curl and libcurl are
+ * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ *
+ * 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 MPL or the MIT/X-derivate
+ * licenses. You may pick one of these licenses.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * $Id$
+ *****************************************************************************/
+
+#ifndef CURL_CA_BUNDLE
+/* Set this to the full path file name of the ca cert bundle */
+#undef CURL_CA_BUNDLE
+#endif
+
+#endif /* __CA_BUNDLE_H */
diff --git a/Source/CTest/Curl/config.h.in b/Source/CTest/Curl/config.h.in
index 50d0a78..9a61b06 100644
--- a/Source/CTest/Curl/config.h.in
+++ b/Source/CTest/Curl/config.h.in
@@ -1,33 +1,33 @@
-/* lib/config.h.in.  Generated automatically from configure.in by autoheader.  */
+/* lib/config.h.in.  Generated from configure.in by autoheader.  */
 /* Name of this package! */
-#define PACKAGE "${PACKAGE}"
+#cmakedefine PACKAGE                    "${PACKAGE}"
 
 /* Version number of this archive. */
-#define VERSION "${VERSION}"
+#cmakedefine VERSION                    "${VERSION}"
 
 /* Define if you have the getpass function.  */
-#cmakedefine HAVE_GETPASS	${HAVE_GETPASS}
+#cmakedefine HAVE_GETPASS               ${HAVE_GETPASS}
 
 /* Define cpu-machine-OS */
-#define OS "${OPERATING_SYSTEM}"
+#define OS         "${OPERATING_SYSTEM}"
 
 /* Define if you have the gethostbyaddr_r() function with 5 arguments */
-#cmakedefine HAVE_GETHOSTBYADDR_R_5	${HAVE_GETHOSTBYADDR_R_5}
+#cmakedefine HAVE_GETHOSTBYADDR_R_5             ${HAVE_GETHOSTBYADDR_R_5}
 
 /* Define if you have the gethostbyaddr_r() function with 7 arguments */
-#cmakedefine HAVE_GETHOSTBYADDR_R_7	${HAVE_GETHOSTBYADDR_R_7}
+#cmakedefine HAVE_GETHOSTBYADDR_R_7             ${HAVE_GETHOSTBYADDR_R_7}
 
 /* Define if you have the gethostbyaddr_r() function with 8 arguments */
-#cmakedefine HAVE_GETHOSTBYADDR_R_8	${HAVE_GETHOSTBYADDR_R_8}
+#cmakedefine HAVE_GETHOSTBYADDR_R_8             ${HAVE_GETHOSTBYADDR_R_8}
 
 /* Define if you have the gethostbyname_r() function with 3 arguments */
-#cmakedefine HAVE_GETHOSTBYNAME_R_3	${HAVE_GETHOSTBYNAME_R_3}
+#cmakedefine HAVE_GETHOSTBYNAME_R_3             ${HAVE_GETHOSTBYNAME_R_3}
 
 /* Define if you have the gethostbyname_r() function with 5 arguments */
-#cmakedefine HAVE_GETHOSTBYNAME_R_5	${HAVE_GETHOSTBYNAME_R_5}
+#cmakedefine HAVE_GETHOSTBYNAME_R_5             ${HAVE_GETHOSTBYNAME_R_5}
 
 /* Define if you have the gethostbyname_r() function with 6 arguments */
-#cmakedefine HAVE_GETHOSTBYNAME_R_6	${HAVE_GETHOSTBYNAME_R_6}
+#cmakedefine HAVE_GETHOSTBYNAME_R_6             ${HAVE_GETHOSTBYNAME_R_6}
 
 /* Define if you have the inet_ntoa_r function declared. */
 #cmakedefine HAVE_INET_NTOA_R_DECL	${HAVE_INET_NTOA_R_DECL}
@@ -36,342 +36,433 @@
 #cmakedefine HAVE_GETSERVBYNAME         ${HAVE_GETSERVBYNAME}
 
 /* Define if you need the _REENTRANT define for some functions */
-#cmakedefine NEED_REENTRANT	${NEED_REENTRANT}
+#cmakedefine NEED_REENTRANT             ${NEED_REENTRANT}
 
 /* Define if you have the Kerberos4 libraries (including -ldes) */
-#cmakedefine KRB4	${KRB4}
+#cmakedefine KRB4               ${KRB4}
 
 /* Define if you want to enable IPv6 support */
-#cmakedefine ENABLE_IPV6	${ENABLE_IPV6}
+#cmakedefine ENABLE_IPV6                ${ENABLE_IPV6}
 
 /* Define this to 'int' if ssize_t is not an available typedefed type */
-#cmakedefine ssize_t	${ssize_t}
+#cmakedefine ssize_t            ${ssize_t}
 
 /* Define this to 'int' if socklen_t is not an available typedefed type */
-#cmakedefine socklen_t	${socklen_t}
+#cmakedefine socklen_t          ${socklen_t}
 
 /* Define this as a suitable file to read random data from */
 #cmakedefine RANDOM_FILE	"${RANDOM_FILE}"
 
 /* Define this to your Entropy Gathering Daemon socket pathname */
-#cmakedefine EGD_SOCKET	${EGD_SOCKET}
+#cmakedefine EGD_SOCKET         ${EGD_SOCKET}
 
 /* Define if you have a working OpenSSL installation */
-#cmakedefine OPENSSL_ENABLED	${OPENSSL_ENABLED}
+#cmakedefine OPENSSL_ENABLED            ${OPENSSL_ENABLED}
 
 /* Define the one correct non-blocking socket method below */
-#cmakedefine HAVE_FIONBIO	${HAVE_FIONBIO}
-#cmakedefine HAVE_IOCTLSOCKET	${HAVE_IOCTLSOCKET}
-#cmakedefine HAVE_IOCTLSOCKET_CASE	${HAVE_IOCTLSOCKET_CASE}
-#cmakedefine HAVE_O_NONBLOCK	${HAVE_O_NONBLOCK}
-#cmakedefine HAVE_DISABLED_NONBLOCKING	${HAVE_DISABLED_NONBLOCKING}
+#cmakedefine HAVE_FIONBIO               ${HAVE_FIONBIO}
+#cmakedefine HAVE_IOCTLSOCKET           ${HAVE_IOCTLSOCKET}
+#cmakedefine HAVE_IOCTLSOCKET_CASE              ${HAVE_IOCTLSOCKET_CASE}
+#cmakedefine HAVE_O_NONBLOCK            ${HAVE_O_NONBLOCK}
+#cmakedefine HAVE_DISABLED_NONBLOCKING          ${HAVE_DISABLED_NONBLOCKING}
 
 /* Define this to 'int' if in_addr_t is not an available typedefed type */
-#cmakedefine in_addr_t	${in_addr_t}
+#cmakedefine in_addr_t          ${in_addr_t}
+
+/* Define to disable DICT */
+#cmakedefine CURL_DISABLE_DICT          ${CURL_DISABLE_DICT}
+
+/* Define to disable FILE */
+#cmakedefine CURL_DISABLE_FILE          ${CURL_DISABLE_FILE}
+
+/* Define to disable FTP */
+#cmakedefine CURL_DISABLE_FTP           ${CURL_DISABLE_FTP}
+
+/* Define to disable GOPHER */
+#cmakedefine CURL_DISABLE_GOPHER                ${CURL_DISABLE_GOPHER}
+
+/* Define to disable HTTP */
+#cmakedefine CURL_DISABLE_HTTP          ${CURL_DISABLE_HTTP}
+
+/* Define to disable LDAP */
+#cmakedefine CURL_DISABLE_LDAP          ${CURL_DISABLE_LDAP}
+
+/* Define to disable TELNET */
+#cmakedefine CURL_DISABLE_TELNET                ${CURL_DISABLE_TELNET}
+
+/* Define if you have zlib present */
+#cmakedefine HAVE_LIBZ          ${HAVE_LIBZ}
+
+/* CA bundle full path name */
+#cmakedefine CURL_CA_BUNDLE             ${CURL_CA_BUNDLE}
+
+/* to disable FILE */
+#cmakedefine CURL_DISABLE_FILE          ${CURL_DISABLE_FILE}
+
+/* to disable FTP */
+#cmakedefine CURL_DISABLE_FTP           ${CURL_DISABLE_FTP}
+
+/* to disable GOPHER */
+#cmakedefine CURL_DISABLE_GOPHER                ${CURL_DISABLE_GOPHER}
+
+/* to disable HTTP */
+#cmakedefine CURL_DISABLE_HTTP          ${CURL_DISABLE_HTTP}
+
+/* to disable LDAP */
+#cmakedefine CURL_DISABLE_LDAP          ${CURL_DISABLE_LDAP}
+
+/* to disable TELNET */
+#cmakedefine CURL_DISABLE_TELNET                ${CURL_DISABLE_TELNET}
 
 /* Set to explicitly specify we don't want to use thread-safe functions */
-#cmakedefine DISABLED_THREADSAFE	${DISABLED_THREADSAFE}
+#cmakedefine DISABLED_THREADSAFE                ${DISABLED_THREADSAFE}
+
+/* your Entropy Gathering Daemon socket pathname */
+#cmakedefine EGD_SOCKET         ${EGD_SOCKET}
 
 /* Define if you want to enable IPv6 support */
-#cmakedefine ENABLE_IPV6	${ENABLE_IPV6}
+#cmakedefine ENABLE_IPV6                ${ENABLE_IPV6}
+
+/* Define to 1 if you have the <alloca.h> header file. */
+#cmakedefine HAVE_ALLOCA_H              ${HAVE_ALLOCA_H}
 
-/* Define if you have the <alloca.h> header file. */
-#cmakedefine HAVE_ALLOCA_H	${HAVE_ALLOCA_H}
+/* Define to 1 if you have the <arpa/inet.h> header file. */
+#cmakedefine HAVE_ARPA_INET_H           ${HAVE_ARPA_INET_H}
 
-/* Define if you have the <arpa/inet.h> header file. */
-#cmakedefine HAVE_ARPA_INET_H	${HAVE_ARPA_INET_H}
+/* Define to 1 if you have the `closesocket' function. */
+#cmakedefine HAVE_CLOSESOCKET           ${HAVE_CLOSESOCKET}
 
-/* Define if you have the `closesocket' function. */
-#cmakedefine HAVE_CLOSESOCKET	${HAVE_CLOSESOCKET}
+/* Define to 1 if you have the <crypto.h> header file. */
+#cmakedefine HAVE_CRYPTO_H              ${HAVE_CRYPTO_H}
 
-/* Define if you have the <crypto.h> header file. */
-#cmakedefine HAVE_CRYPTO_H	${HAVE_CRYPTO_H}
+/* Define to 1 if you have the <des.h> header file. */
+#cmakedefine HAVE_DES_H         ${HAVE_DES_H}
 
-/* Define if you have the <des.h> header file. */
-#cmakedefine HAVE_DES_H	${HAVE_DES_H}
+/* to disable NON-BLOCKING connections */
+#cmakedefine HAVE_DISABLED_NONBLOCKING          ${HAVE_DISABLED_NONBLOCKING}
 
-/* Define if you have the <dlfcn.h> header file. */
-#cmakedefine HAVE_DLFCN_H	${HAVE_DLFCN_H}
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#cmakedefine HAVE_DLFCN_H               ${HAVE_DLFCN_H}
 
-/* Define if you have the `dlopen' function. */
-#cmakedefine HAVE_DLOPEN	${HAVE_DLOPEN}
+/* Define to 1 if you have the `dlopen' function. */
+#cmakedefine HAVE_DLOPEN                ${HAVE_DLOPEN}
 
-/* Define if you have the <err.h> header file. */
-#cmakedefine HAVE_ERR_H	${HAVE_ERR_H}
+/* Define to 1 if you have the <err.h> header file. */
+#cmakedefine HAVE_ERR_H         ${HAVE_ERR_H}
 
-/* Define if you have the <fcntl.h> header file. */
-#cmakedefine HAVE_FCNTL_H	${HAVE_FCNTL_H}
+/* Define to 1 if you have the <fcntl.h> header file. */
+#cmakedefine HAVE_FCNTL_H               ${HAVE_FCNTL_H}
 
 /* Define if getaddrinfo exists and works */
-#cmakedefine HAVE_GETADDRINFO	${HAVE_GETADDRINFO}
+#cmakedefine HAVE_GETADDRINFO           ${HAVE_GETADDRINFO}
 
-/* Define if you have the `geteuid' function. */
-#cmakedefine HAVE_GETEUID	${HAVE_GETEUID}
+/* Define to 1 if you have the `geteuid' function. */
+#cmakedefine HAVE_GETEUID               ${HAVE_GETEUID}
 
-/* Define if you have the `gethostbyaddr' function. */
-#cmakedefine HAVE_GETHOSTBYADDR	${HAVE_GETHOSTBYADDR}
+/* Define to 1 if you have the `gethostbyaddr' function. */
+#cmakedefine HAVE_GETHOSTBYADDR         ${HAVE_GETHOSTBYADDR}
 
-/* Define if you have the `gethostbyaddr_r' function. */
-#cmakedefine HAVE_GETHOSTBYADDR_R	${HAVE_GETHOSTBYADDR_R}
+/* Define to 1 if you have the `gethostbyaddr_r' function. */
+#cmakedefine HAVE_GETHOSTBYADDR_R               ${HAVE_GETHOSTBYADDR_R}
 
-/* Define if you have the `gethostbyname_r' function. */
-#cmakedefine HAVE_GETHOSTBYNAME_R	${HAVE_GETHOSTBYNAME_R}
+/* Define to 1 if you have the `gethostbyname_r' function. */
+#cmakedefine HAVE_GETHOSTBYNAME_R               ${HAVE_GETHOSTBYNAME_R}
 
-/* Define if you have the `gethostname' function. */
-#cmakedefine HAVE_GETHOSTNAME	${HAVE_GETHOSTNAME}
+/* Define to 1 if you have the `getpass_r' function. */
+#cmakedefine HAVE_GETPASS_R             ${HAVE_GETPASS_R}
 
-/* Define if you have the `getpass_r' function. */
-#cmakedefine HAVE_GETPASS_R	${HAVE_GETPASS_R}
+/* Define to 1 if you have the `getpwuid' function. */
+#cmakedefine HAVE_GETPWUID              ${HAVE_GETPWUID}
 
-/* Define if you have the `getpwuid' function. */
-#cmakedefine HAVE_GETPWUID	${HAVE_GETPWUID}
+/* Define to 1 if you have the `gettimeofday' function. */
+#cmakedefine HAVE_GETTIMEOFDAY          ${HAVE_GETTIMEOFDAY}
 
-/* Define if you have the `gettimeofday' function. */
-#cmakedefine HAVE_GETTIMEOFDAY	${HAVE_GETTIMEOFDAY}
+/* Define to 1 if you have the `gmtime_r' function. */
+#cmakedefine HAVE_GMTIME_R              ${HAVE_GMTIME_R}
 
-/* Define if you have the `gmtime_r' function. */
-#cmakedefine HAVE_GMTIME_R	${HAVE_GMTIME_R}
+/* Define to 1 if you have the `inet_addr' function. */
+#cmakedefine HAVE_INET_ADDR             ${HAVE_INET_ADDR}
 
-/* Define if you have the `inet_addr' function. */
-#cmakedefine HAVE_INET_ADDR	${HAVE_INET_ADDR}
+/* Define to 1 if you have the `inet_ntoa' function. */
+#cmakedefine HAVE_INET_NTOA             ${HAVE_INET_NTOA}
 
-/* Define if you have the `inet_ntoa' function. */
-#cmakedefine HAVE_INET_NTOA	${HAVE_INET_NTOA}
+/* Define to 1 if you have the `inet_ntoa_r' function. */
+#cmakedefine HAVE_INET_NTOA_R           ${HAVE_INET_NTOA_R}
 
-/* Define if you have the `inet_ntoa_r' function. */
-#cmakedefine HAVE_INET_NTOA_R	${HAVE_INET_NTOA_R}
+/* Define to 1 if you have the <inttypes.h> header file. */
+#cmakedefine HAVE_INTTYPES_H            ${HAVE_INTTYPES_H}
 
-/* Define if you have the <inttypes.h> header file. */
-#cmakedefine HAVE_INTTYPES_H	${HAVE_INTTYPES_H}
+/* Define to 1 if you have the <io.h> header file. */
+#cmakedefine HAVE_IO_H          ${HAVE_IO_H}
 
-/* Define if you have the <io.h> header file. */
-#cmakedefine HAVE_IO_H	${HAVE_IO_H}
+/* Define to 1 if you have the `krb_get_our_ip_for_realm' function. */
+#cmakedefine HAVE_KRB_GET_OUR_IP_FOR_REALM              ${HAVE_KRB_GET_OUR_IP_FOR_REALM}
 
-/* Define if you have the `krb_get_our_ip_for_realm' function. */
-#cmakedefine HAVE_KRB_GET_OUR_IP_FOR_REALM	${HAVE_KRB_GET_OUR_IP_FOR_REALM}
-/* Define if you have the <krb.h> header file. */
-#cmakedefine HAVE_KRB_H	${HAVE_KRB_H}
+/* Define to 1 if you have the <krb.h> header file. */
+#cmakedefine HAVE_KRB_H         ${HAVE_KRB_H}
 
-/* Define if you have the `crypto' library (-lcrypto). */
-#cmakedefine HAVE_LIBCRYPTO	${HAVE_LIBCRYPTO}
+/* Define to 1 if you have the `crypto' library (-lcrypto). */
+#cmakedefine HAVE_LIBCRYPTO             ${HAVE_LIBCRYPTO}
 
-/* Define if you have the `dl' library (-ldl). */
-#cmakedefine HAVE_LIBDL	${HAVE_LIBDL}
+/* Define to 1 if you have the `dl' library (-ldl). */
+#cmakedefine HAVE_LIBDL         ${HAVE_LIBDL}
 
-/* Define if you have the `nsl' library (-lnsl). */
-#cmakedefine HAVE_LIBNSL	${HAVE_LIBNSL}
+/* Define to 1 if you have the `nsl' library (-lnsl). */
+#cmakedefine HAVE_LIBNSL                ${HAVE_LIBNSL}
 
-/* Define if you have the `resolv' library (-lresolv). */
-#cmakedefine HAVE_LIBRESOLV	${HAVE_LIBRESOLV}
+/* Define to 1 if you have the `resolv' library (-lresolv). */
+#cmakedefine HAVE_LIBRESOLV             ${HAVE_LIBRESOLV}
 
-/* Define if you have the `resolve' library (-lresolve). */
-#cmakedefine HAVE_LIBRESOLVE	${HAVE_LIBRESOLVE}
+/* Define to 1 if you have the `resolve' library (-lresolve). */
+#cmakedefine HAVE_LIBRESOLVE            ${HAVE_LIBRESOLVE}
 
-/* Define if you have the `socket' library (-lsocket). */
-#cmakedefine HAVE_LIBSOCKET	${HAVE_LIBSOCKET}
+/* Define to 1 if you have the `socket' library (-lsocket). */
+#cmakedefine HAVE_LIBSOCKET             ${HAVE_LIBSOCKET}
 
-/* Define if you have the `ssl' library (-lssl). */
-#cmakedefine HAVE_LIBSSL	${HAVE_LIBSSL}
+/* Define to 1 if you have the `ssl' library (-lssl). */
+#cmakedefine HAVE_LIBSSL                ${HAVE_LIBSSL}
 
-/* Define if you have the `ucb' library (-lucb). */
+/* Define to 1 if you have the `ucb' library (-lucb). */
 #cmakedefine HAVE_LIBUCB	${HAVE_LIBUCB}
 
-/* Define if you have the `localtime_r' function. */
-#cmakedefine HAVE_LOCALTIME_R	${HAVE_LOCALTIME_R}
+/* If zlib is available */
+#cmakedefine HAVE_LIBZ          ${HAVE_LIBZ}
+
+/* Define to 1 if you have the `localtime_r' function. */
+#cmakedefine HAVE_LOCALTIME_R           ${HAVE_LOCALTIME_R}
+
+/* Define to 1 if you have the <malloc.h> header file. */
+#cmakedefine HAVE_MALLOC_H              ${HAVE_MALLOC_H}
+
+/* Define to 1 if you have the <memory.h> header file. */
+#cmakedefine HAVE_MEMORY_H              ${HAVE_MEMORY_H}
+
+/* Define to 1 if you have the <netdb.h> header file. */
+#cmakedefine HAVE_NETDB_H               ${HAVE_NETDB_H}
+
+/* Define to 1 if you have the <netinet/if_ether.h> header file. */
+#cmakedefine HAVE_NETINET_IF_ETHER_H            ${HAVE_NETINET_IF_ETHER_H}
+
+/* Define to 1 if you have the <netinet/in.h> header file. */
+#cmakedefine HAVE_NETINET_IN_H          ${HAVE_NETINET_IN_H}
 
-/* Define if you have the <malloc.h> header file. */
-#cmakedefine HAVE_MALLOC_H	${HAVE_MALLOC_H}
+/* Define to 1 if you have the <net/if.h> header file. */
+#cmakedefine HAVE_NET_IF_H              ${HAVE_NET_IF_H}
 
-/* Define if you have the <memory.h> header file. */
-#cmakedefine HAVE_MEMORY_H	${HAVE_MEMORY_H}
+/* Define to 1 if you have the <openssl/crypto.h> header file. */
+#cmakedefine HAVE_OPENSSL_CRYPTO_H              ${HAVE_OPENSSL_CRYPTO_H}
 
-/* Define if you have the <netdb.h> header file. */
-#cmakedefine HAVE_NETDB_H	${HAVE_NETDB_H}
+/* Define to 1 if you have the <openssl/engine.h> header file. */
+#cmakedefine HAVE_OPENSSL_ENGINE_H              ${HAVE_OPENSSL_ENGINE_H}
 
-/* Define if you have the <netinet/if_ether.h> header file. */
-#cmakedefine HAVE_NETINET_IF_ETHER_H	${HAVE_NETINET_IF_ETHER_H}
+/* Define to 1 if you have the <openssl/err.h> header file. */
+#cmakedefine HAVE_OPENSSL_ERR_H         ${HAVE_OPENSSL_ERR_H}
 
-/* Define if you have the <netinet/in.h> header file. */
-#cmakedefine HAVE_NETINET_IN_H	${HAVE_NETINET_IN_H}
+/* Define to 1 if you have the <openssl/pem.h> header file. */
+#cmakedefine HAVE_OPENSSL_PEM_H         ${HAVE_OPENSSL_PEM_H}
 
-/* Define if you have the <net/if.h> header file. */
-#cmakedefine HAVE_NET_IF_H	${HAVE_NET_IF_H}
+/* Define to 1 if you have the <openssl/rsa.h> header file. */
+#cmakedefine HAVE_OPENSSL_RSA_H         ${HAVE_OPENSSL_RSA_H}
 
-/* Define if you have the <openssl/crypto.h> header file. */
-#cmakedefine HAVE_OPENSSL_CRYPTO_H	${HAVE_OPENSSL_CRYPTO_H}
+/* Define to 1 if you have the <openssl/ssl.h> header file. */
+#cmakedefine HAVE_OPENSSL_SSL_H         ${HAVE_OPENSSL_SSL_H}
 
-/* Define if you have the <openssl/engine.h> header file. */
-#cmakedefine HAVE_OPENSSL_ENGINE_H	${HAVE_OPENSSL_ENGINE_H}
+/* Define to 1 if you have the <openssl/x509.h> header file. */
+#cmakedefine HAVE_OPENSSL_X509_H                ${HAVE_OPENSSL_X509_H}
 
-/* Define if you have the <openssl/err.h> header file. */
-#cmakedefine HAVE_OPENSSL_ERR_H	${HAVE_OPENSSL_ERR_H}
+/* Define to 1 if you have the <pem.h> header file. */
+#cmakedefine HAVE_PEM_H         ${HAVE_PEM_H}
 
-/* Define if you have the <openssl/pem.h> header file. */
-#cmakedefine HAVE_OPENSSL_PEM_H	${HAVE_OPENSSL_PEM_H}
+/* Define to 1 if you have the `perror' function. */
+#cmakedefine HAVE_PERROR                ${HAVE_PERROR}
 
-/* Define if you have the <openssl/rsa.h> header file. */
-#cmakedefine HAVE_OPENSSL_RSA_H	${HAVE_OPENSSL_RSA_H}
+/* Define to 1 if you have the `poll' function. */
+#cmakedefine HAVE_POLL          ${HAVE_POLL}
 
-/* Define if you have the <openssl/ssl.h> header file. */
-#cmakedefine HAVE_OPENSSL_SSL_H	${HAVE_OPENSSL_SSL_H}
+/* Define to 1 if you have the <pwd.h> header file. */
+#cmakedefine HAVE_PWD_H         ${HAVE_PWD_H}
 
-/* Define if you have the <openssl/x509.h> header file. */
-#cmakedefine HAVE_OPENSSL_X509_H	${HAVE_OPENSSL_X509_H}
+/* Define to 1 if you have the `RAND_egd' function. */
+#cmakedefine HAVE_RAND_EGD              ${HAVE_RAND_EGD}
 
-/* Define if you have the <pem.h> header file. */
-#cmakedefine HAVE_PEM_H	${HAVE_PEM_H}
+/* Define to 1 if you have the `RAND_screen' function. */
+#cmakedefine HAVE_RAND_SCREEN           ${HAVE_RAND_SCREEN}
 
-/* Define if you have the `perror' function. */
-#cmakedefine HAVE_PERROR	${HAVE_PERROR}
+/* Define to 1 if you have the `RAND_status' function. */
+#cmakedefine HAVE_RAND_STATUS           ${HAVE_RAND_STATUS}
 
-/* Define if you have the <pwd.h> header file. */
-#cmakedefine HAVE_PWD_H	${HAVE_PWD_H}
+/* Define to 1 if you have the <rsa.h> header file. */
+#cmakedefine HAVE_RSA_H         ${HAVE_RSA_H}
 
-/* Define if you have the `RAND_egd' function. */
-#cmakedefine HAVE_RAND_EGD	${HAVE_RAND_EGD}
+/* Define to 1 if you have the `select' function. */
+#cmakedefine HAVE_SELECT                ${HAVE_SELECT}
 
-/* Define if you have the `RAND_screen' function. */
-#cmakedefine HAVE_RAND_SCREEN	${HAVE_RAND_SCREEN}
+/* Define to 1 if you have the <setjmp.h> header file. */
+#cmakedefine HAVE_SETJMP_H              ${HAVE_SETJMP_H}
 
-/* Define if you have the `RAND_status' function. */
-#cmakedefine HAVE_RAND_STATUS	${HAVE_RAND_STATUS}
+/* Define to 1 if you have the `setvbuf' function. */
+#cmakedefine HAVE_SETVBUF               ${HAVE_SETVBUF}
 
-/* Define if you have the <rsa.h> header file. */
-#cmakedefine HAVE_RSA_H	${HAVE_RSA_H}
+/* Define to 1 if you have the <sgtty.h> header file. */
+#cmakedefine HAVE_SGTTY_H               ${HAVE_SGTTY_H}
 
-/* Define if you have the `select' function. */
-#cmakedefine HAVE_SELECT	${HAVE_SELECT}
+/* Define to 1 if you have the `sigaction' function. */
+#cmakedefine HAVE_SIGACTION             ${HAVE_SIGACTION}
 
-/* Define if you have the `setvbuf' function. */
-#cmakedefine HAVE_SETVBUF	${HAVE_SETVBUF}
+/* Define to 1 if you have the `signal' function. */
+#cmakedefine HAVE_SIGNAL                ${HAVE_SIGNAL}
 
-/* Define if you have the <sgtty.h> header file. */
-#cmakedefine HAVE_SGTTY_H	${HAVE_SGTTY_H}
+/* If you have sigsetjmp */
+#cmakedefine HAVE_SIGSETJMP             ${HAVE_SIGSETJMP}
 
-/* Define if you have the `sigaction' function. */
-#cmakedefine HAVE_SIGACTION	${HAVE_SIGACTION}
+/* Define to 1 if you have the `socket' function. */
+#cmakedefine HAVE_SOCKET                ${HAVE_SOCKET}
 
-/* Define if you have the `signal' function. */
-#cmakedefine HAVE_SIGNAL	${HAVE_SIGNAL}
+/* Define to 1 if you have the <ssl.h> header file. */
+#cmakedefine HAVE_SSL_H         ${HAVE_SSL_H}
 
-/* Define if you have the `socket' function. */
-#cmakedefine HAVE_SOCKET	${HAVE_SOCKET}
+/* Define to 1 if you have the <stdint.h> header file. */
+#cmakedefine HAVE_STDINT_H              ${HAVE_STDINT_H}
 
-/* Define if you have the <ssl.h> header file. */
-#cmakedefine HAVE_SSL_H	${HAVE_SSL_H}
+/* Define to 1 if you have the <stdlib.h> header file. */
+#cmakedefine HAVE_STDLIB_H              ${HAVE_STDLIB_H}
 
-/* Define if you have the <stdint.h> header file. */
-#cmakedefine HAVE_STDINT_H	${HAVE_STDINT_H}
+/* Define to 1 if you have the `strcasecmp' function. */
+#cmakedefine HAVE_STRCASECMP            ${HAVE_STRCASECMP}
 
-/* Define if you have the <stdlib.h> header file. */
-#cmakedefine HAVE_STDLIB_H	${HAVE_STDLIB_H}
+/* Define to 1 if you have the `strcmpi' function. */
+#cmakedefine HAVE_STRCMPI               ${HAVE_STRCMPI}
 
-/* Define if you have the `strcasecmp' function. */
-#cmakedefine HAVE_STRCASECMP	${HAVE_STRCASECMP}
+/* Define to 1 if you have the `strdup' function. */
+#cmakedefine HAVE_STRDUP                ${HAVE_STRDUP}
 
-/* Define if you have the `strcmpi' function. */
-#cmakedefine HAVE_STRCMPI	${HAVE_STRCMPI}
+/* Define to 1 if you have the `strftime' function. */
+#cmakedefine HAVE_STRFTIME              ${HAVE_STRFTIME}
 
-/* Define if you have the `strdup' function. */
-#cmakedefine HAVE_STRDUP	${HAVE_STRDUP}
+/* Define to 1 if you have the `stricmp' function. */
+#cmakedefine HAVE_STRICMP               ${HAVE_STRICMP}
 
-/* Define if you have the `strftime' function. */
-#cmakedefine HAVE_STRFTIME	${HAVE_STRFTIME}
+/* Define to 1 if you have the <strings.h> header file. */
+#cmakedefine HAVE_STRINGS_H             ${HAVE_STRINGS_H}
 
-/* Define if you have the `stricmp' function. */
-#cmakedefine HAVE_STRICMP	${HAVE_STRICMP}
+/* Define to 1 if you have the <string.h> header file. */
+#cmakedefine HAVE_STRING_H              ${HAVE_STRING_H}
 
-/* Define if you have the <strings.h> header file. */
-#cmakedefine HAVE_STRINGS_H	${HAVE_STRINGS_H}
+/* Define to 1 if you have the `strlcat' function. */
+#cmakedefine HAVE_STRLCAT               ${HAVE_STRLCAT}
 
-/* Define if you have the <string.h> header file. */
-#cmakedefine HAVE_STRING_H	${HAVE_STRING_H}
+/* Define to 1 if you have the `strlcpy' function. */
+#cmakedefine HAVE_STRLCPY               ${HAVE_STRLCPY}
 
-/* Define if you have the `strlcat' function. */
-#cmakedefine HAVE_STRLCAT	${HAVE_STRLCAT}
+/* Define to 1 if you have the `strstr' function. */
+#cmakedefine HAVE_STRSTR                ${HAVE_STRSTR}
 
-/* Define if you have the `strlcpy' function. */
-#cmakedefine HAVE_STRLCPY	${HAVE_STRLCPY}
+/* Define to 1 if you have the `strtok_r' function. */
+#cmakedefine HAVE_STRTOK_R              ${HAVE_STRTOK_R}
 
-/* Define if you have the `strstr' function. */
-#cmakedefine HAVE_STRSTR	${HAVE_STRSTR}
+/* Define to 1 if you have the <sys/param.h> header file. */
+#cmakedefine HAVE_SYS_PARAM_H           ${HAVE_SYS_PARAM_H}
 
-/* Define if you have the `strtok_r' function. */
-#cmakedefine HAVE_STRTOK_R	${HAVE_STRTOK_R}
+/* Define to 1 if you have the <sys/poll.h> header file. */
+#cmakedefine HAVE_SYS_POLL_H            ${HAVE_SYS_POLL_H}
 
-/* Define if you have the <sys/param.h> header file. */
-#cmakedefine HAVE_SYS_PARAM_H	${HAVE_SYS_PARAM_H}
+/* Define to 1 if you have the <sys/select.h> header file. */
+#cmakedefine HAVE_SYS_SELECT_H          ${HAVE_SYS_SELECT_H}
 
-/* Define if you have the <sys/select.h> header file. */
-#cmakedefine HAVE_SYS_SELECT_H	${HAVE_SYS_SELECT_H}
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#cmakedefine HAVE_SYS_SOCKET_H          ${HAVE_SYS_SOCKET_H}
 
-/* Define if you have the <sys/socket.h> header file. */
-#cmakedefine HAVE_SYS_SOCKET_H	${HAVE_SYS_SOCKET_H}
+/* Define to 1 if you have the <sys/sockio.h> header file. */
+#cmakedefine HAVE_SYS_SOCKIO_H          ${HAVE_SYS_SOCKIO_H}
 
-/* Define if you have the <sys/sockio.h> header file. */
-#cmakedefine HAVE_SYS_SOCKIO_H	${HAVE_SYS_SOCKIO_H}
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#cmakedefine HAVE_SYS_STAT_H            ${HAVE_SYS_STAT_H}
 
-/* Define if you have the <sys/stat.h> header file. */
-#cmakedefine HAVE_SYS_STAT_H	${HAVE_SYS_STAT_H}
+/* Define to 1 if you have the <sys/time.h> header file. */
+#cmakedefine HAVE_SYS_TIME_H            ${HAVE_SYS_TIME_H}
 
-/* Define if you have the <sys/time.h> header file. */
-#cmakedefine HAVE_SYS_TIME_H	${HAVE_SYS_TIME_H}
+/* Define to 1 if you have the <sys/types.h> header file. */
+#cmakedefine HAVE_SYS_TYPES_H           ${HAVE_SYS_TYPES_H}
 
-/* Define if you have the <sys/types.h> header file. */
-#cmakedefine HAVE_SYS_TYPES_H	${HAVE_SYS_TYPES_H}
+/* Define to 1 if you have the <sys/utime.h> header file. */
+#cmakedefine HAVE_SYS_UTIME_H           ${HAVE_SYS_UTIME_H}
 
-/* Define if you have the <sys/utime.h> header file. */
-#cmakedefine HAVE_SYS_UTIME_H	${HAVE_SYS_UTIME_H}
+/* Define to 1 if you have the `tcgetattr' function. */
+#cmakedefine HAVE_TCGETATTR             ${HAVE_TCGETATTR}
 
-/* Define if you have the `tcgetattr' function. */
-#cmakedefine HAVE_TCGETATTR	${HAVE_TCGETATTR}
+/* Define to 1 if you have the `tcsetattr' function. */
+#cmakedefine HAVE_TCSETATTR             ${HAVE_TCSETATTR}
 
-/* Define if you have the `tcsetattr' function. */
-#cmakedefine HAVE_TCSETATTR	${HAVE_TCSETATTR}
+/* Define to 1 if you have the <termios.h> header file. */
+#cmakedefine HAVE_TERMIOS_H             ${HAVE_TERMIOS_H}
 
-/* Define if you have the <termios.h> header file. */
-#cmakedefine HAVE_TERMIOS_H	${HAVE_TERMIOS_H}
+/* Define to 1 if you have the <termio.h> header file. */
+#cmakedefine HAVE_TERMIO_H              ${HAVE_TERMIO_H}
 
-/* Define if you have the <termio.h> header file. */
-#cmakedefine HAVE_TERMIO_H	${HAVE_TERMIO_H}
+/* Define to 1 if you have the <time.h> header file. */
+#cmakedefine HAVE_TIME_H                ${HAVE_TIME_H}
 
-/* Define if you have the <time.h> header file. */
-#cmakedefine HAVE_TIME_H	${HAVE_TIME_H}
+/* Define to 1 if you have the `uname' function. */
+#cmakedefine HAVE_UNAME         ${HAVE_UNAME}
 
-/* Define if you have the `uname' function. */
-#cmakedefine HAVE_UNAME	${HAVE_UNAME}
+/* Define to 1 if you have the <unistd.h> header file. */
+#cmakedefine HAVE_UNISTD_H              ${HAVE_UNISTD_H}
 
-/* Define if you have the <unistd.h> header file. */
-#cmakedefine HAVE_UNISTD_H	${HAVE_UNISTD_H}
+/* Define to 1 if you have the `utime' function. */
+#cmakedefine HAVE_UTIME         ${HAVE_UTIME}
 
-/* Define if you have the `utime' function. */
-#cmakedefine HAVE_UTIME	${HAVE_UTIME}
+/* Define to 1 if you have the <utime.h> header file. */
+#cmakedefine HAVE_UTIME_H               ${HAVE_UTIME_H}
 
-/* Define if you have the <utime.h> header file. */
-#cmakedefine HAVE_UTIME_H	${HAVE_UTIME_H}
+/* Define to 1 if you have the <winsock.h> header file. */
+#cmakedefine HAVE_WINSOCK_H             ${HAVE_WINSOCK_H}
 
-/* Define if you have the <winsock.h> header file. */
-#cmakedefine HAVE_WINSOCK_H	${HAVE_WINSOCK_H}
+/* Define to 1 if you have the <x509.h> header file. */
+#cmakedefine HAVE_X509_H                ${HAVE_X509_H}
 
-/* Define if you have the <x509.h> header file. */
-#cmakedefine HAVE_X509_H	${HAVE_X509_H}
+/* if you have the zlib.h header file */
+#cmakedefine HAVE_ZLIB_H                ${HAVE_ZLIB_H}
+
+/* if you have the Kerberos4 libraries (including -ldes) */
+#cmakedefine KRB4               ${KRB4}
+
+/* cpu-machine-OS */
+#define OS         "${OPERATING_SYSTEM}"
 
 /* Name of package */
-#cmakedefine PACKAGE	"${PACKAGE}"
+#cmakedefine PACKAGE            "${PACKAGE}"
+
+/* Define to the address where bug reports for this package should be sent. */
+#cmakedefine PACKAGE_BUGREPORT          ${PACKAGE_BUGREPORT}
+
+/* Define to the full name of this package. */
+#cmakedefine PACKAGE_NAME               "${PACKAGE_NAME}"
+
+/* Define to the full name and version of this package. */
+#cmakedefine PACKAGE_STRING             "${PACKAGE_STRING}"
+
+/* Define to the one symbol short name of this package. */
+#cmakedefine PACKAGE_TARNAME            "${PACKAGE_TARNAME}"
+
+/* Define to the version of this package. */
+#cmakedefine PACKAGE_VERSION            "${PACKAGE_VERSION}"
+
+/* a suitable file to read random data from */
+#cmakedefine RANDOM_FILE                "${RANDOM_FILE}"
 
 /* Define as the return type of signal handlers (`int' or `void'). */
-#cmakedefine RETSIGTYPE	${RETSIGTYPE}
+#cmakedefine RETSIGTYPE         ${RETSIGTYPE}
 
-/* Define if you have the ANSI C header files. */
-#cmakedefine STDC_HEADERS	${STDC_HEADERS}
+/* Define to 1 if you have the ANSI C header files. */
+#cmakedefine STDC_HEADERS               ${STDC_HEADERS}
 
-/* Define if you can safely include both <sys/time.h> and <time.h>. */
-#cmakedefine TIME_WITH_SYS_TIME	${TIME_WITH_SYS_TIME}
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#cmakedefine TIME_WITH_SYS_TIME         ${TIME_WITH_SYS_TIME}
 
 /* Version number of package */
-#cmakedefine VERSION	"${VERSION}"
+#cmakedefine VERSION            "${VERSION}"
 
-/* Define if on AIX 3.
+/* Define to 1 if on AIX 3.
    System headers sometimes define this.
    We just want to avoid a redefinition error message.  */
 #ifndef _ALL_SOURCE
@@ -379,22 +470,22 @@
 #endif
 
 /* Number of bits in a file offset, on hosts where this is settable. */
-#cmakedefine _FILE_OFFSET_BITS	${_FILE_OFFSET_BITS}
+#cmakedefine _FILE_OFFSET_BITS          ${_FILE_OFFSET_BITS}
 
 /* Define for large files, on AIX-style hosts. */
-#cmakedefine _LARGE_FILES	${_LARGE_FILES}
+#cmakedefine _LARGE_FILES               ${_LARGE_FILES}
 
 /* Define to empty if `const' does not conform to ANSI C. */
-#cmakedefine const	${const}
+#cmakedefine const              ${const}
 
 /* type to use in place of in_addr_t if not defined */
-#cmakedefine in_addr_t	${in_addr_t}
+#cmakedefine in_addr_t          ${in_addr_t}
 
 /* Define to `unsigned' if <sys/types.h> does not define. */
-#cmakedefine size_t	${size_t}
+#cmakedefine size_t             ${size_t}
 
 /* type to use in place of socklen_t if not defined */
-#cmakedefine socklen_t	${socklen_t}
+#cmakedefine socklen_t          ${socklen_t}
 
 /* Define to `int' if <sys/types.h> does not define. */
 #cmakedefine ssize_t	${ssize_t}
@@ -402,7 +493,7 @@
 /* Define if you don't have vprintf but do have _doprnt.  */
 #cmakedefine HAVE_DOPRNT ${HAVE_DOPRNT}
 
-/* Define if you have the vprintf function.  */
+/* Define to 1 if you have the vprintf function.  */
 #cmakedefine HAVE_VPRINTF ${HAVE_VPRINTF}
 
 /* The number of bytes in a long double.  */
diff --git a/Source/CTest/Curl/connect.c b/Source/CTest/Curl/connect.c
index 77ceff0..eb6f4f3 100644
--- a/Source/CTest/Curl/connect.c
+++ b/Source/CTest/Curl/connect.c
@@ -1,25 +1,25 @@
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 
 #include "setup.h"
 
@@ -185,7 +185,6 @@ int waitconnect(int sockfd, /* socket */
   return 0;
 }
 
-#ifndef ENABLE_IPV6
 static CURLcode bindlocal(struct connectdata *conn,
                           int sockfd)
 {
@@ -207,22 +206,28 @@ static CURLcode bindlocal(struct connectdata *conn,
    *************************************************************/
   if (strlen(data->set.device)<255) {
     struct sockaddr_in sa;
-    struct hostent *h=NULL;
-    char *hostdataptr=NULL;
+    struct Curl_dns_entry *h=NULL;
     size_t size;
     char myhost[256] = "";
     in_addr_t in;
 
     if(Curl_if2ip(data->set.device, myhost, sizeof(myhost))) {
-      h = Curl_resolv(data, myhost, 0, &hostdataptr);
+      /*
+       * We now have the numerical IPv4-style x.y.z.w in the 'myhost' buffer
+       */
+      h = Curl_resolv(data, myhost, 0);
     }
     else {
       if(strlen(data->set.device)>1) {
-        h = Curl_resolv(data, data->set.device, 0, &hostdataptr);
-      }
-      if(h) {
-        /* we know data->set.device is shorter than the myhost array */
-        strcpy(myhost, data->set.device);
+        /*
+         * This was not an interface, resolve the name as a host name
+         * or IP number
+         */
+        h = Curl_resolv(data, data->set.device, 0);
+        if(h) {
+          /* we know data->set.device is shorter than the myhost array */
+          strcpy(myhost, data->set.device);
+        }
       }
     }
 
@@ -242,11 +247,19 @@ static CURLcode bindlocal(struct connectdata *conn,
     if (INADDR_NONE != in) {
 
       if ( h ) {
+        Curl_addrinfo *addr = h->addr;
+
+        Curl_resolv_unlock(h);
+        /* we don't need it anymore after this function has returned */
+
         memset((char *)&sa, 0, sizeof(sa));
-        memcpy((char *)&sa.sin_addr,
-               h->h_addr,
-               h->h_length);
+#ifdef ENABLE_IPV6
+        memcpy((char *)&sa.sin_addr, addr->ai_addr, addr->ai_addrlen);        
+        sa.sin_family = addr->ai_family;
+#else
+        memcpy((char *)&sa.sin_addr, addr->h_addr, addr->h_length);
         sa.sin_family = AF_INET;
+#endif
         sa.sin_addr.s_addr = in;
         sa.sin_port = 0; /* get any port */
         
@@ -314,7 +327,7 @@ static CURLcode bindlocal(struct connectdata *conn,
 
   return CURLE_HTTP_PORT_FAILED;
 }
-#endif /* end of ipv4-specific section */
+
 
 static
 int socketerror(int sockfd)
@@ -330,21 +343,89 @@ int socketerror(int sockfd)
 }
 
 /*
+ * Curl_is_connected() is used from the multi interface to check if the
+ * firstsocket has connected.
+ */
+
+CURLcode Curl_is_connected(struct connectdata *conn,
+                           int sockfd,
+                           bool *connected)
+{
+  int rc;
+  struct SessionHandle *data = conn->data;
+
+  *connected = FALSE; /* a very negative world view is best */
+
+  if(data->set.timeout || data->set.connecttimeout) {
+    /* there is a timeout set */
+
+    /* Evaluate in milliseconds how much time that has passed */
+    long has_passed = Curl_tvdiff(Curl_tvnow(), data->progress.start);
+
+    /* subtract the most strict timeout of the ones */
+    if(data->set.timeout && data->set.connecttimeout) {
+      if (data->set.timeout < data->set.connecttimeout)
+        has_passed -= data->set.timeout*1000;
+      else 
+        has_passed -= data->set.connecttimeout*1000;
+    }
+    else if(data->set.timeout)
+      has_passed -= data->set.timeout*1000;
+    else
+      has_passed -= data->set.connecttimeout*1000;
+
+    if(has_passed > 0 ) {
+      /* time-out, bail out, go home */
+      failf(data, "Connection time-out");
+      return CURLE_OPERATION_TIMEOUTED;
+    }
+  }
+
+  /* check for connect without timeout as we want to return immediately */
+  rc = waitconnect(sockfd, 0);
+
+  if(0 == rc) {
+    int err = socketerror(sockfd);
+    if ((0 == err) || (EISCONN == err)) {
+      /* we are connected, awesome! */
+      *connected = TRUE;
+      return CURLE_OK;
+    }
+    /* nope, not connected for real */
+    if(err)
+      return CURLE_COULDNT_CONNECT;
+  }
+
+  /*
+   * If the connection phase is "done" here, we should attempt to connect
+   * to the "next address" in the Curl_hostaddr structure that we resolved
+   * before. But we don't have that struct around anymore and we can't just
+   * keep a pointer since the cache might in fact have gotten pruned by the
+   * time we want to read this... Alas, we don't do this yet.
+   */
+
+  return CURLE_OK;
+}
+
+
+/*
  * TCP connect to the given host with timeout, proxy or remote doesn't matter.
  * There might be more than one IP address to try out. Fill in the passed
  * pointer with the connected socket.
  */
 
 CURLcode Curl_connecthost(struct connectdata *conn,  /* context */
-                          Curl_addrinfo *remotehost, /* use one in here */
+                          struct Curl_dns_entry *remotehost, /* use this one */
                           int port,                  /* connect to this */
                           int *sockconn,             /* the connected socket */
-                          Curl_ipconnect **addr)     /* the one we used */
+                          Curl_ipconnect **addr,     /* the one we used */
+                          bool *connected)           /* really connected? */
 {
   struct SessionHandle *data = conn->data;
   int rc;
   int sockfd=-1;
   int aliasindex=0;
+  char *hostname;
 
   struct timeval after;
   struct timeval before = Curl_tvnow();
@@ -353,6 +434,9 @@ CURLcode Curl_connecthost(struct connectdata *conn,  /* context */
    * Figure out what maximum time we have left
    *************************************************************/
   long timeout_ms=300000; /* milliseconds, default to five minutes */
+
+  *connected = FALSE; /* default to not connected */
+
   if(data->set.timeout || data->set.connecttimeout) {
     double has_passed;
 
@@ -385,6 +469,13 @@ CURLcode Curl_connecthost(struct connectdata *conn,  /* context */
     }
   }
 
+  hostname = data->change.proxy?conn->proxyhost:conn->hostname;
+  infof(data, "About to connect() to %s%s%s:%d\n",
+        conn->bits.ipv6_ip?"[":"",
+        hostname,
+        conn->bits.ipv6_ip?"]":"",
+        port);
+
 #ifdef ENABLE_IPV6
   /*
    * Connecting with IPv6 support is so much easier and cleanly done
@@ -393,11 +484,19 @@ CURLcode Curl_connecthost(struct connectdata *conn,  /* context */
     struct addrinfo *ai;
     port =0; /* prevent compiler warning */
 
-    for (ai = remotehost; ai; ai = ai->ai_next, aliasindex++) {
+    for (ai = remotehost->addr; ai; ai = ai->ai_next, aliasindex++) {
       sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
       if (sockfd < 0)
         continue;
 
+      if(conn->data->set.device) {
+        /* user selected to bind the outgoing socket to a specified "device"
+           before doing connect */
+        CURLcode res = bindlocal(conn, sockfd);
+        if(res)
+          return res;
+      }
+
       /* set socket non-blocking */
       Curl_nonblock(sockfd, TRUE);
 
@@ -417,17 +516,21 @@ CURLcode Curl_connecthost(struct connectdata *conn,  /* context */
         case EAGAIN:
 #endif
         case EINTR:
-
           /* asynchronous connect, wait for connect or timeout */
+          if(data->state.used_interface == Curl_if_multi)
+            /* don't hang when doing multi */
+            timeout_ms = 0;
+
           rc = waitconnect(sockfd, timeout_ms);
           break;
         case ECONNREFUSED: /* no one listening */
         default:
           /* unknown error, fallthrough and try another address! */
-          failf(data, "Failed to connect");
+          failf(data, "Failed connect to %s: %d", hostname, error);
           break;
         }
       }
+
       if(0 == rc) {
         /* we might be connected, if the socket says it is OK! Ask it! */
         int err;
@@ -435,10 +538,17 @@ CURLcode Curl_connecthost(struct connectdata *conn,  /* context */
         err = socketerror(sockfd);
         if ((0 == err) || (EISCONN == err)) {
           /* we are connected, awesome! */
+          *connected = TRUE; /* this is truly a connect */
           break;
         }
+        failf(data, "socket error: %d", err);
         /* we are _not_ connected, it was a false alert, continue please */
       }
+      else if(data->state.used_interface == Curl_if_multi) {
+        /* When running the multi interface, we bail out here */
+        rc = 0;
+        break;
+      }
 
       /* connect failed or timed out */
       sclose(sockfd);
@@ -454,10 +564,8 @@ CURLcode Curl_connecthost(struct connectdata *conn,  /* context */
       before = after;
       continue;
     }
-    if (sockfd < 0) {
-      failf(data, "connect() failed");
+    if (sockfd < 0)
       return CURLE_COULDNT_CONNECT;
-    }
 
     /* leave the socket in non-blocking mode */
 
@@ -468,7 +576,7 @@ CURLcode Curl_connecthost(struct connectdata *conn,  /* context */
   /*
    * Connecting with IPv4-only support
    */
-  if(!remotehost->h_addr_list[0]) {
+  if(!remotehost->addr->h_addr_list[0]) {
     /* If there is no addresses in the address list, then we return
        error right away */
     failf(data, "no address available");
@@ -495,17 +603,17 @@ CURLcode Curl_connecthost(struct connectdata *conn,  /* context */
   /* This is the loop that attempts to connect to all IP-addresses we
      know for the given host. One by one. */
   for(rc=-1, aliasindex=0;
-      rc && (struct in_addr *)remotehost->h_addr_list[aliasindex];
+      rc && (struct in_addr *)remotehost->addr->h_addr_list[aliasindex];
       aliasindex++) {
     struct sockaddr_in serv_addr;
 
     /* do this nasty work to do the connect */
     memset((char *) &serv_addr, '\0', sizeof(serv_addr));
     memcpy((char *)&(serv_addr.sin_addr),
-           (struct in_addr *)remotehost->h_addr_list[aliasindex],
+           (struct in_addr *)remotehost->addr->h_addr_list[aliasindex],
            sizeof(struct in_addr));
-    serv_addr.sin_family = remotehost->h_addrtype;
-    serv_addr.sin_port = htons(port);
+    serv_addr.sin_family = remotehost->addr->h_addrtype;
+    serv_addr.sin_port = htons((unsigned short)port);
   
     rc = connect(sockfd, (struct sockaddr *)&serv_addr,
                  sizeof(serv_addr));
@@ -523,13 +631,17 @@ CURLcode Curl_connecthost(struct connectdata *conn,  /* context */
          */
       case EAGAIN:
 #endif
-
         /* asynchronous connect, wait for connect or timeout */
+        if(data->state.used_interface == Curl_if_multi)
+          /* don't hang when doing multi */
+          timeout_ms = 0;
+
         rc = waitconnect(sockfd, timeout_ms);
         break;
       default:
         /* unknown error, fallthrough and try another address! */
-        failf(data, "Failed to connect to IP number %d", aliasindex+1);
+        failf(data, "Failed to connect to %s IP number %d: %d",
+              hostname, aliasindex+1, error);
         break;
       }
     }
@@ -538,6 +650,7 @@ CURLcode Curl_connecthost(struct connectdata *conn,  /* context */
       int err = socketerror(sockfd);
       if ((0 == err) || (EISCONN == err)) {
         /* we are connected, awesome! */
+        *connected = TRUE; /* this is a true connect */
         break;
       }
       /* nope, not connected for real */
@@ -545,6 +658,12 @@ CURLcode Curl_connecthost(struct connectdata *conn,  /* context */
     }
 
     if(0 != rc) {
+      if(data->state.used_interface == Curl_if_multi) {
+        /* When running the multi interface, we bail out here */
+        rc = 0;
+        break;
+      }
+
       /* get a new timeout for next attempt */
       after = Curl_tvnow();
       timeout_ms -= Curl_tvdiff(after, before);
@@ -561,7 +680,7 @@ CURLcode Curl_connecthost(struct connectdata *conn,  /* context */
     /* no good connect was made */
     sclose(sockfd);
     *sockconn = -1;
-    failf(data, "Couldn't connect to host");
+    failf(data, "Connect failed");
     return CURLE_COULDNT_CONNECT;
   }
 
@@ -569,7 +688,7 @@ CURLcode Curl_connecthost(struct connectdata *conn,  /* context */
 
   if(addr)
     /* this is the address we've connected to */
-    *addr = (struct in_addr *)remotehost->h_addr_list[aliasindex];
+    *addr = (struct in_addr *)remotehost->addr->h_addr_list[aliasindex];
 #endif
 
   /* allow NULL-pointers to get passed in */
diff --git a/Source/CTest/Curl/connect.h b/Source/CTest/Curl/connect.h
index f8c10db..fdbecec 100644
--- a/Source/CTest/Curl/connect.h
+++ b/Source/CTest/Curl/connect.h
@@ -1,35 +1,40 @@
 #ifndef __CONNECT_H
 #define __CONNECT_H
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 
 int Curl_nonblock(int socket,    /* operate on this */
                   int nonblock   /* TRUE or FALSE */);
 
+CURLcode Curl_is_connected(struct connectdata *conn,
+                           int sockfd,
+                           bool *connected);
+
 CURLcode Curl_connecthost(struct connectdata *conn,
-                          Curl_addrinfo *host, /* connect to this */
+                          struct Curl_dns_entry *host, /* connect to this */
                           int port,       /* connect to this port number */
                           int *sockconn,  /* not set if error is returned */
-                          Curl_ipconnect **addr /* the one we used */
-                          ); /*  index we used */
+                          Curl_ipconnect **addr, /* the one we used */
+                          bool *connected /* truly connected? */
+                          );
 #endif
diff --git a/Source/CTest/Curl/content_encoding.c b/Source/CTest/Curl/content_encoding.c
new file mode 100644
index 0000000..80d9eec
--- /dev/null
+++ b/Source/CTest/Curl/content_encoding.c
@@ -0,0 +1,122 @@
+/***************************************************************************
+ *                                  _   _ ____  _     
+ *  Project                     ___| | | |  _ \| |    
+ *                             / __| | | | |_) | |    
+ *                            | (__| |_| |  _ <| |___ 
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2002, 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$
+ ***************************************************************************/
+
+#include "setup.h"
+
+#ifdef HAVE_LIBZ
+
+#include "urldata.h"
+#include <curl/curl.h>
+#include <curl/types.h>
+#include "sendf.h"
+
+#define DSIZ 4096               /* buffer size for decompressed data */
+
+
+static CURLcode
+process_zlib_error(struct SessionHandle *data, z_stream *z)
+{
+  if (z->msg)
+    failf (data, "Error while processing content unencoding.\n%s",
+           z->msg);
+  else
+    failf (data, "Error while processing content unencoding.\n"
+           "Unknown failure within decompression software.");
+
+  return CURLE_BAD_CONTENT_ENCODING;
+}
+
+static CURLcode
+exit_zlib(z_stream *z, bool *zlib_init, CURLcode result)
+{
+  inflateEnd(z);
+  *zlib_init = 0;
+  return result;
+}
+
+CURLcode
+Curl_unencode_deflate_write(struct SessionHandle *data, 
+                            struct Curl_transfer_keeper *k,
+                            ssize_t nread)
+{
+  int status;                   /* zlib status */
+  int result;                   /* Curl_client_write status */
+  char decomp[DSIZ];            /* Put the decompressed data here. */
+  z_stream *z = &k->z;          /* zlib state structure */
+              
+  /* Initialize zlib? */
+  if (!k->zlib_init) {
+    z->zalloc = (alloc_func)Z_NULL;
+    z->zfree = (free_func)Z_NULL;
+    z->opaque = 0;              /* of dubious use 08/27/02 jhrg */
+    if (inflateInit(z) != Z_OK)
+      return process_zlib_error(data, z);
+    k->zlib_init = 1;
+  }
+
+  /* Set the compressed input when this fucntion is called */
+  z->next_in = (Bytef *)k->str;
+  z->avail_in = nread;
+
+  /* because the buffer size is fixed, iteratively decompress
+     and transfer to the client via client_write. */
+  for (;;) {
+    /* (re)set buffer for decompressed output for every iteration */
+    z->next_out = (Bytef *)&decomp[0];
+    z->avail_out = DSIZ;
+
+    status = inflate(z, Z_SYNC_FLUSH);
+    if (status == Z_OK || status == Z_STREAM_END) {
+      result = Curl_client_write(data, CLIENTWRITE_BODY, decomp, 
+                                 DSIZ - z->avail_out);
+      /* if !CURLE_OK, clean up, return */
+      if (result) {              
+        return exit_zlib(z, &k->zlib_init, result);
+      }
+
+      /* Done?; clean up, return */
+      if (status == Z_STREAM_END) {
+        if (inflateEnd(z) == Z_OK)
+          return exit_zlib(z, &k->zlib_init, result);
+        else
+          return exit_zlib(z, &k->zlib_init, process_zlib_error(data, z));
+      }
+
+      /* Done with these bytes, exit */
+      if (status == Z_OK && z->avail_in == 0 && z->avail_out > 0) 
+        return result;
+    }
+    else {                      /* Error; exit loop, handle below */
+      return exit_zlib(z, &k->zlib_init, process_zlib_error(data, z));
+    }
+  }
+}
+#endif /* HAVE_LIBZ */
+
+/*
+ * local variables:
+ * eval: (load-file "../curl-mode.el")
+ * end:
+ * vim600: fdm=marker
+ * vim: et sw=2 ts=2 sts=2 tw=78
+ */
diff --git a/Source/CTest/Curl/content_encoding.h b/Source/CTest/Curl/content_encoding.h
new file mode 100644
index 0000000..2e7676b
--- /dev/null
+++ b/Source/CTest/Curl/content_encoding.h
@@ -0,0 +1,34 @@
+/***************************************************************************
+ *                                  _   _ ____  _     
+ *  Project                     ___| | | |  _ \| |    
+ *                             / __| | | | |_) | |    
+ *                            | (__| |_| |  _ <| |___ 
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2002, 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$
+ ***************************************************************************/
+
+CURLcode Curl_unencode_deflate_write(struct SessionHandle *data, 
+                                     struct Curl_transfer_keeper *k, 
+                                     ssize_t nread);
+          
+/*
+ * local variables:
+ * eval: (load-file "../curl-mode.el")
+ * end:
+ * vim600: fdm=marker
+ * vim: et sw=2 ts=2 sts=2 tw=78
+ */
diff --git a/Source/CTest/Curl/cookie.c b/Source/CTest/Curl/cookie.c
index 4593530..a5af458 100644
--- a/Source/CTest/Curl/cookie.c
+++ b/Source/CTest/Curl/cookie.c
@@ -1,25 +1,25 @@
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2002, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 
 /***
 
@@ -79,6 +79,8 @@ Example set of cookies:
 
 #include "setup.h"
 
+#ifndef CURL_DISABLE_HTTP
+
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
@@ -93,6 +95,21 @@ Example set of cookies:
 #include "memdebug.h"
 #endif
 
+static void
+free_cookiemess(struct Cookie *co)
+{
+  if(co->domain)
+    free(co->domain);
+  if(co->path)
+    free(co->path);
+  if(co->name)
+    free(co->name);
+  if(co->value)
+    free(co->value);
+
+  free(co);
+}
+
 /****************************************************************************
  *
  * Curl_cookie_add()
@@ -104,7 +121,7 @@ Example set of cookies:
 struct Cookie *
 Curl_cookie_add(struct CookieInfo *c,
                 bool httpheader, /* TRUE if HTTP header-style line */
-                char *lineptr,   /* first non-space of the line */
+                char *lineptr,   /* first character of the line */
                 char *domain)    /* default domain */
 {
   struct Cookie *clist;
@@ -129,6 +146,10 @@ Curl_cookie_add(struct CookieInfo *c,
     /* This line was read off a HTTP-header */
     char *sep;
     semiptr=strchr(lineptr, ';'); /* first, find a semicolon */
+
+    while(*lineptr && isspace((int)*lineptr))
+      lineptr++;
+
     ptr = lineptr;
     do {
       /* we have a <what>=<this> pair or a 'secure' word here */
@@ -145,6 +166,8 @@ Curl_cookie_add(struct CookieInfo *c,
                        name, what)) {
           /* this is a <name>=<what> pair */
 
+          char *whatptr;
+
           /* Strip off trailing whitespace from the 'what' */
           int len=strlen(what);
           while(len && isspace((int)what[len-1])) {
@@ -152,15 +175,21 @@ Curl_cookie_add(struct CookieInfo *c,
             len--;
           }
 
+          /* Skip leading whitespace from the 'what' */
+          whatptr=what;
+          while(isspace((int)*whatptr)) {
+            whatptr++;
+          }
+
           if(strequal("path", name)) {
-            co->path=strdup(what);
+            co->path=strdup(whatptr);
           }
           else if(strequal("domain", name)) {
-            co->domain=strdup(what);
-            co->field1= (what[0]=='.')?2:1;
+            co->domain=strdup(whatptr);
+            co->field1= (whatptr[0]=='.')?2:1;
           }
           else if(strequal("version", name)) {
-            co->version=strdup(what);
+            co->version=strdup(whatptr);
           }
           else if(strequal("max-age", name)) {
             /* Defined in RFC2109:
@@ -172,17 +201,17 @@ Curl_cookie_add(struct CookieInfo *c,
                cookie should be discarded immediately.
 
              */
-            co->maxage = strdup(what);
+            co->maxage = strdup(whatptr);
             co->expires =
               atoi((*co->maxage=='\"')?&co->maxage[1]:&co->maxage[0]) + now;
           }
           else if(strequal("expires", name)) {
-            co->expirestr=strdup(what);
+            co->expirestr=strdup(whatptr);
             co->expires = curl_getdate(what, &now);
           }
           else if(!co->name) {
             co->name = strdup(name);
-            co->value = strdup(what);
+            co->value = strdup(whatptr);
           }
           /*
             else this is the second (or more) name we don't know
@@ -318,22 +347,19 @@ Curl_cookie_add(struct CookieInfo *c,
     if(7 != fields) {
       /* we did not find the sufficient number of fields to recognize this
          as a valid line, abort and go home */
-
-      if(co->domain)
-        free(co->domain);
-      if(co->path)
-        free(co->path);
-      if(co->name)
-        free(co->name);
-      if(co->value)
-        free(co->value);
-
-      free(co);
+      free_cookiemess(co);
       return NULL;
     }
 
   }
 
+  if(!c->running &&    /* read from a file */
+     c->newsession &&  /* clean session cookies */
+     !co->expires) {   /* this is a session cookie since it doesn't expire! */
+    free_cookiemess(co);
+    return NULL;
+  }
+
   co->livecookie = c->running;
 
   /* now, we have parsed the incoming line, we must now check if this
@@ -347,7 +373,13 @@ Curl_cookie_add(struct CookieInfo *c,
       /* the names are identical */
 
       if(clist->domain && co->domain) {
-        if(strequal(clist->domain, co->domain))
+        if(strequal(clist->domain, co->domain) ||
+           (clist->domain[0]=='.' &&
+            strequal(&(clist->domain[1]), co->domain)) ||
+           (co->domain[0]=='.' &&
+            strequal(clist->domain, &(co->domain[1]))) )
+          /* The domains are identical, or at least identical if you skip the
+             preceeding dot */
           replace_old=TRUE;
       }
       else if(!clist->domain && !co->domain)
@@ -448,8 +480,12 @@ Curl_cookie_add(struct CookieInfo *c,
  * Inits a cookie struct to read data from a local file. This is always
  * called before any cookies are set. File may be NULL.
  *
+ * If 'newsession' is TRUE, discard all "session cookies" on read from file.
+ *
  ****************************************************************************/
-struct CookieInfo *Curl_cookie_init(char *file, struct CookieInfo *inc)
+struct CookieInfo *Curl_cookie_init(char *file,
+                                    struct CookieInfo *inc,
+                                    bool newsession)
 {
   char line[MAX_COOKIE_LINE];
   struct CookieInfo *c;
@@ -477,11 +513,13 @@ struct CookieInfo *Curl_cookie_init(char *file, struct CookieInfo *inc)
   else
     fp = file?fopen(file, "r"):NULL;
 
+  c->newsession = newsession; /* new session? */
+
   if(fp) {
     char *lineptr;
     bool headerline;
     while(fgets(line, MAX_COOKIE_LINE, fp)) {
-      if(strnequal("Set-Cookie:", line, 11)) {
+      if(checkprefix("Set-Cookie:", line)) {
         /* This is a cookie line, get it! */
         lineptr=&line[11];
         headerline=TRUE;
@@ -499,7 +537,7 @@ struct CookieInfo *Curl_cookie_init(char *file, struct CookieInfo *inc)
       fclose(fp);
   }
 
-  c->running = TRUE; /* now, we're running */
+  c->running = TRUE;          /* now, we're running */
 
   return c;
 }
@@ -549,8 +587,8 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
 
             /* now check the left part of the path with the cookies path
                requirement */
-            if(!co->path ||
-               strnequal(path, co->path, strlen(co->path))) {
+           if(!co->path ||
+              checkprefix(co->path, path) ) {
 
                /* and now, we know this is a match and we should create an
                   entry for the return-linked-list */
@@ -729,6 +767,8 @@ int main(int argc, char **argv)
 
 #endif
 
+#endif /* CURL_DISABLE_HTTP */
+
 /*
  * local variables:
  * eval: (load-file "../curl-mode.el")
diff --git a/Source/CTest/Curl/cookie.h b/Source/CTest/Curl/cookie.h
index f5eba37..77ac059 100644
--- a/Source/CTest/Curl/cookie.h
+++ b/Source/CTest/Curl/cookie.h
@@ -1,27 +1,27 @@
 #ifndef __COOKIE_H
 #define __COOKIE_H
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 
 #include <stdio.h>
 #ifdef WIN32
@@ -55,9 +55,10 @@ struct CookieInfo {
   /* linked list of cookies we know of */
   struct Cookie *cookies;
 
-  char *filename; /* file we read from/write to */
-  bool running;   /* state info, for cookie adding information */
+  char *filename;  /* file we read from/write to */
+  bool running;    /* state info, for cookie adding information */
   long numcookies; /* number of cookies in the "jar" */
+  bool newsession; /* new session, discard session cookies on load */
 };
 
 /* This is the maximum line length we accept for a cookie line */
@@ -75,7 +76,7 @@ struct CookieInfo {
 struct Cookie *Curl_cookie_add(struct CookieInfo *, bool header, char *line,
                                char *domain);
 
-struct CookieInfo *Curl_cookie_init(char *, struct CookieInfo *);
+struct CookieInfo *Curl_cookie_init(char *, struct CookieInfo *, bool);
 struct Cookie *Curl_cookie_getlist(struct CookieInfo *, char *, char *, bool);
 void Curl_cookie_freelist(struct Cookie *);
 void Curl_cookie_cleanup(struct CookieInfo *);
diff --git a/Source/CTest/Curl/curl/curl.h b/Source/CTest/Curl/curl/curl.h
index b6bc3a6..c56c965 100644
--- a/Source/CTest/Curl/curl/curl.h
+++ b/Source/CTest/Curl/curl/curl.h
@@ -1,27 +1,27 @@
 #ifndef __CURL_CURL_H
 #define __CURL_CURL_H
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2002, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 
 #include <stdio.h>
 /* The include stuff here is mainly for time_t! */
@@ -49,22 +49,31 @@
 #define FALSE 0
 #endif
 
-#include <curl/types.h>
+#include "types.h"
 
 #ifdef  __cplusplus
 extern "C" {
 #endif
 
-struct HttpPost {
-  struct HttpPost *next; /* next entry in the list */
+/* stupid #define trick to preserve functionality with older code, but
+   making it use our name space for the future */
+#define HttpPost curl_httppost
+
+struct curl_httppost {
+  struct curl_httppost *next; /* next entry in the list */
   char *name;     /* pointer to allocated name */
   long namelength; /* length of name length */
   char *contents; /* pointer to allocated data contents */
   long contentslength; /* length of contents field */
+
+        /* CMC: Added support for buffer uploads */
+        char *buffer; /* pointer to allocated buffer contents */
+        long bufferlength; /* length of buffer field */
+
   char *contenttype; /* Content-Type */
   struct curl_slist* contentheader; /* list of extra headers for this form */
-  struct HttpPost *more; /* if one field name has more than one file, this
-                            link should link to following files */
+  struct curl_httppost *more; /* if one field name has more than one file, this
+                                 link should link to following files */
   long flags;     /* as defined below */
 #define HTTPPOST_FILENAME (1<<0) /* specified content is a file name */
 #define HTTPPOST_READFILE (1<<1) /* specified content is a file name */
@@ -72,6 +81,13 @@ struct HttpPost {
                                    do not free in formfree */
 #define HTTPPOST_PTRCONTENTS (1<<3) /* contents is only stored pointer
                                        do not free in formfree */
+
+/* CMC: Added support for buffer uploads */
+#define HTTPPOST_BUFFER (1<<4) /* upload file from buffer */
+#define HTTPPOST_PTRBUFFER (1<<5) /* upload file from pointer contents */
+
+  char *showfilename; /* The file name to show. If not set, the actual
+                         file name will be used (if this is a file part) */
 };
 
 typedef int (*curl_progress_callback)(void *clientp,
@@ -80,6 +96,8 @@ typedef int (*curl_progress_callback)(void *clientp,
                                       double ultotal,
                                       double ulnow);
 
+#define CURL_MAX_WRITE_SIZE 20480
+
 typedef size_t (*curl_write_callback)(char *buffer,
                                       size_t size,
                                       size_t nitems,
@@ -95,6 +113,23 @@ typedef int (*curl_passwd_callback)(void *clientp,
                                     char *buffer,
                                     int buflen);
 
+/* the kind of data that is passed to information_callback*/
+typedef enum {
+  CURLINFO_TEXT = 0,
+  CURLINFO_HEADER_IN,    /* 1 */
+  CURLINFO_HEADER_OUT,   /* 2 */
+  CURLINFO_DATA_IN,      /* 3 */
+  CURLINFO_DATA_OUT,     /* 4 */
+  CURLINFO_END
+} curl_infotype;
+
+typedef int (*curl_debug_callback)
+       (CURL *handle,      /* the handle/transfer this concerns */
+        curl_infotype type, /* what kind of data */
+        char *data,        /* points to the data */
+        size_t size,       /* size of the data pointed to */
+        void *userp);      /* whatever the user please */
+  
 /* All possible error codes from all sorts of curl functions. Future versions
    may return other values, stay prepared.
 
@@ -139,7 +174,7 @@ typedef enum {
   CURLE_HTTP_RANGE_ERROR,        /* 33 - RANGE "command" didn't work */
   CURLE_HTTP_POST_ERROR,         /* 34 */
   CURLE_SSL_CONNECT_ERROR,       /* 35 - wrong when connecting with SSL */
-  CURLE_FTP_BAD_DOWNLOAD_RESUME, /* 36 - couldn't resume download */
+  CURLE_BAD_DOWNLOAD_RESUME,     /* 36 - couldn't resume download */
   CURLE_FILE_COULDNT_READ_FILE,  /* 37 */
   CURLE_LDAP_CANNOT_BIND,        /* 38 */
   CURLE_LDAP_SEARCH_FAILED,      /* 39 */
@@ -157,11 +192,28 @@ typedef enum {
   CURLE_SSL_PEER_CERTIFICATE,    /* 51 - peer's certificate wasn't ok */
   CURLE_GOT_NOTHING,             /* 52 - when this is a specific error */
   CURLE_SSL_ENGINE_NOTFOUND,     /* 53 - SSL crypto engine not found */
-  CURLE_SSL_ENGINE_SETFAILED,    /* 54 - can not set SSL crypto engine as default */
+  CURLE_SSL_ENGINE_SETFAILED,    /* 54 - can not set SSL crypto engine as
+                                    default */
+  CURLE_SEND_ERROR,              /* 55 - failed sending network data */
+  CURLE_RECV_ERROR,              /* 56 - failure in receiving network data */
+  CURLE_SHARE_IN_USE,            /* 57 - share is in use */
+  CURLE_SSL_CERTPROBLEM,         /* 58 - problem with the local certificate */
+  CURLE_SSL_CIPHER,              /* 59 - couldn't use specified cipher */
+  CURLE_SSL_CACERT,              /* 60 - problem with the CA cert (path?) */
+  CURLE_BAD_CONTENT_ENCODING,    /* 61 - Unrecognized transfer encoding */
 
   CURL_LAST /* never use! */
 } CURLcode;
 
+/* Make a spelling correction for the operation timed-out define */
+#define CURLE_OPERATION_TIMEDOUT CURLE_OPERATION_TIMEOUTED
+
+typedef enum {
+  CURLPROXY_HTTP = 0,
+  CURLPROXY_SOCKS4 = 4,
+  CURLPROXY_SOCKS5 = 5
+} curl_proxytype;
+
 /* this was the error code 50 in 7.7.3 and a few earlier versions, this
    is no longer used by libcurl but is instead #defined here only to not
    make programs break */
@@ -169,22 +221,47 @@ typedef enum {
 
 /* This is just to make older programs not break: */
 #define CURLE_FTP_PARTIAL_FILE CURLE_PARTIAL_FILE
+#define CURLE_FTP_BAD_DOWNLOAD_RESUME CURLE_BAD_DOWNLOAD_RESUME
 
 #define CURL_ERROR_SIZE 256
 
+/* long may be 32 or 64 bits, but we should never depend on anything else
+   but 32 */
+#define CURLOPTTYPE_LONG          0
+#define CURLOPTTYPE_OBJECTPOINT   10000
+#define CURLOPTTYPE_FUNCTIONPOINT 20000
+
 /* name is uppercase CURLOPT_<name>,
    type is one of the defined CURLOPTTYPE_<type>
    number is unique identifier */
 #ifdef CINIT
 #undef CINIT
 #endif
-#define CINIT(name,type,number) CURLOPT_ ## name = CURLOPTTYPE_ ## type + number
+/*
+ * Figure out if we can use the ## operator, which is supported by ISO/ANSI C
+ * and C++. Some compilers support it without setting __STDC__ or __cplusplus
+ * so we need to carefully check for them too. We don't use configure-checks
+ * for these since we want these headers to remain generic and working for all
+ * platforms.
+ */
+#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) || \
+  defined(__HP_aCC) || defined(__BORLANDC__)
+  /* This compiler is believed to have an ISO compatible preprocessor */
+#define CURL_ISOCPP
+#else
+  /* This compiler is believed NOT to have an ISO compatible preprocessor */
+#undef CURL_ISOCPP
+#endif
 
-/* long may be 32 or 64 bits, but we should never depend on anything else
-   but 32 */
-#define CURLOPTTYPE_LONG          0
-#define CURLOPTTYPE_OBJECTPOINT   10000
-#define CURLOPTTYPE_FUNCTIONPOINT 20000
+#ifdef CURL_ISOCPP
+#define CINIT(name,type,number) CURLOPT_ ## name = CURLOPTTYPE_ ## type + number
+#else
+/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */
+#define LONG          CURLOPTTYPE_LONG
+#define OBJECTPOINT   CURLOPTTYPE_OBJECTPOINT
+#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT
+#define CINIT(name,type,number) CURLOPT_/**/name = type + number
+#endif
 
 typedef enum {
   CINIT(NOTHING, LONG, 0), /********* the first one is unused ************/
@@ -344,7 +421,11 @@ typedef enum {
   CINIT(FTPLISTONLY, LONG, 48),  /* Use NLST when listing ftp dir */
 
   CINIT(FTPAPPEND, LONG, 50),    /* Append instead of overwrite on upload! */
-  CINIT(NETRC, LONG, 51),        /* read user+password from .netrc */
+
+  /* Specify whether to read the user+password from the .netrc or the URL.
+   * This must be one of the CURL_NETRC_* enums below. */
+  CINIT(NETRC, LONG, 51),
+
   CINIT(FOLLOWLOCATION, LONG, 52),  /* use Location: Luke! */
 
   /* This FTPASCII name is now obsolete, to be removed, use the TRANSFERTEXT
@@ -496,10 +577,49 @@ typedef enum {
 
   /* send linked-list of pre-transfer QUOTE commands (Wesley Laxton)*/
   CINIT(PREQUOTE, OBJECTPOINT, 93),
+
+  /* set the debug function */
+  CINIT(DEBUGFUNCTION, FUNCTIONPOINT, 94),
+
+  /* set the data for the debug function */
+  CINIT(DEBUGDATA, OBJECTPOINT, 95),
+
+  /* mark this as start of a cookie session */
+  CINIT(COOKIESESSION, LONG, 96),
+
+  /* The CApath directory used to validate the peer certificate
+     this option is used only if SSL_VERIFYPEER is true */
+  CINIT(CAPATH, OBJECTPOINT, 97),
+
+  /* Instruct libcurl to use a smaller receive buffer */
+  CINIT(BUFFERSIZE, LONG, 98),
+
+  /* Instruct libcurl to not use any signal/alarm handlers, even when using
+     timeouts. This option is useful for multi-threaded applications.
+     See libcurl-the-guide for more background information. */
+  CINIT(NOSIGNAL, LONG, 99),
   
-  CURLOPT_LASTENTRY /* the last unusued */
+  /* Provide a CURLShare for mutexing non-ts data */
+  CINIT(SHARE, OBJECTPOINT, 100),
+
+  /* indicates type of proxy. accepted values are CURLPROXY_HTTP (default),
+     CURLPROXY_SOCKS4 and CURLPROXY_SOCKS5. */
+  CINIT(PROXYTYPE, LONG, 101),
+
+  /* Set the Accept-Encoding string. Use this to tell a server you would like
+     the response to be compressed. */
+  CINIT(ENCODING, OBJECTPOINT, 102),
+ 
+
+  CURLOPT_LASTENTRY /* the last unused */
 } CURLoption;
 
+  /* two convenient "aliases" that follow the name scheme better */
+#define CURLOPT_WRITEDATA CURLOPT_FILE
+#define CURLOPT_READDATA  CURLOPT_INFILE 
+#define CURLOPT_HEADERDATA CURLOPT_WRITEHEADER
+
+
   /* These enums are for use with the CURLOPT_HTTP_VERSION option. */
 enum {
   CURL_HTTP_VERSION_NONE, /* setting this means we don't care, and that we'd
@@ -511,6 +631,18 @@ enum {
   CURL_HTTP_VERSION_LAST /* *ILLEGAL* http version */
 };
 
+  /* These enums are for use with the CURLOPT_NETRC option. */
+enum CURL_NETRC_OPTION {
+  CURL_NETRC_IGNORED,     /* The .netrc will never be read.
+                           * This is the default. */
+  CURL_NETRC_OPTIONAL,    /* A user:password in the URL will be preferred
+                           * to one in the .netrc. */
+  CURL_NETRC_REQUIRED,    /* A user:password in the URL will be ignored.
+                           * Unless one is set programmatically, the .netrc
+                           * will be queried. */
+  CURL_NETRC_LAST
+};
+
 enum {
   CURL_SSLVERSION_DEFAULT,
   CURL_SSLVERSION_TLSv1,
@@ -522,15 +654,26 @@ enum {
 
 
 typedef enum {
-  TIMECOND_NONE,
+  CURL_TIMECOND_NONE,
 
-  TIMECOND_IFMODSINCE,
-  TIMECOND_IFUNMODSINCE,
-  TIMECOND_LASTMOD,
+  CURL_TIMECOND_IFMODSINCE,
+  CURL_TIMECOND_IFUNMODSINCE,
+  CURL_TIMECOND_LASTMOD,
 
-  TIMECOND_LAST
+  CURL_TIMECOND_LAST
 } curl_TimeCond;
 
+/* for backwards compatibility */
+#ifndef TIMECOND_IFMODSINCE
+#define TIMECOND_IFMODSINCE CURL_TIMECOND_IFMODSINCE
+#endif
+#ifndef TIMECOND_IFUNMODSINCE
+#define TIMECOND_IFUNMODSINCE CURL_TIMECOND_IFUNMODSINCE
+#endif
+#ifndef TIMECOND_LASTMOD
+#define TIMECOND_LASTMOD CURL_TIMECOND_LASTMOD
+#endif
+
 #ifdef __BEOS__
 #include <support/SupportDefs.h>
 #endif
@@ -548,16 +691,21 @@ extern int (curl_strnequal)(const char *s1, const char *s2, size_t n);
 #define strequal(a,b) curl_strequal(a,b)
 #define strnequal(a,b,c) curl_strnequal(a,b,c)
 
-/* external form function */
-int curl_formparse(char *string,
-                   struct HttpPost **httppost,
-                   struct HttpPost **last_post);
+/* DEPRECATED function to build formdata */
+int curl_formparse(char *, struct curl_httppost **,
+                   struct curl_httppost **_post);
 
 /* name is uppercase CURLFORM_<name> */
 #ifdef CFINIT
 #undef CFINIT
 #endif
+
+#ifdef CURL_ISOCPP
 #define CFINIT(name) CURLFORM_ ## name
+#else
+/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */
+#define CFINIT(name) CURLFORM_/**/name
+#endif
 
 typedef enum {
   CFINIT(NOTHING),        /********* the first one is unused ************/
@@ -571,29 +719,65 @@ typedef enum {
   CFINIT(CONTENTSLENGTH),
   CFINIT(FILECONTENT),
   CFINIT(ARRAY),
-  CFINIT(ARRAY_START), /* below are the options allowed within a array */
+  CFINIT(OBSOLETE),
   CFINIT(FILE),
+
+  CFINIT(BUFFER),
+  CFINIT(BUFFERPTR),
+  CFINIT(BUFFERLENGTH),
+
   CFINIT(CONTENTTYPE),
   CFINIT(CONTENTHEADER),
+  CFINIT(FILENAME),
   CFINIT(END),
-  CFINIT(ARRAY_END),   /* up are the options allowed within a array */
+  CFINIT(OBSOLETE2),
 
   CURLFORM_LASTENTRY /* the last unusued */
 } CURLformoption;
 
+#undef CFINIT /* done */
+
 /* structure to be used as parameter for CURLFORM_ARRAY */
 struct curl_forms {
         CURLformoption          option;
         const char              *value;
 };
 
-/* new external form function */
-int curl_formadd(struct HttpPost **httppost,
-                 struct HttpPost **last_post,
+/* use this for multipart formpost building */
+/* Returns code for curl_formadd()
+ * 
+ * Returns:
+ * CURL_FORMADD_OK             on success
+ * CURL_FORMADD_MEMORY         if the FormInfo allocation fails
+ * CURL_FORMADD_OPTION_TWICE   if one option is given twice for one Form
+ * CURL_FORMADD_NULL           if a null pointer was given for a char
+ * CURL_FORMADD_MEMORY         if the allocation of a FormInfo struct failed
+ * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used
+ * CURL_FORMADD_INCOMPLETE     if the some FormInfo is not complete (or error)
+ * CURL_FORMADD_MEMORY         if a HttpPost struct cannot be allocated
+ * CURL_FORMADD_MEMORY         if some allocation for string copying failed.
+ * CURL_FORMADD_ILLEGAL_ARRAY  if an illegal option is used in an array
+ *
+ ***************************************************************************/
+typedef enum {
+  CURL_FORMADD_OK, /* first, no error */
+
+  CURL_FORMADD_MEMORY,
+  CURL_FORMADD_OPTION_TWICE,
+  CURL_FORMADD_NULL,
+  CURL_FORMADD_UNKNOWN_OPTION,
+  CURL_FORMADD_INCOMPLETE,
+  CURL_FORMADD_ILLEGAL_ARRAY,
+
+  CURL_FORMADD_LAST /* last */
+} CURLFORMcode;
+
+CURLFORMcode curl_formadd(struct curl_httppost **httppost,
+                 struct curl_httppost **last_post,
                  ...);
 
 /* cleanup a form: */
-void curl_formfree(struct HttpPost *form);
+void curl_formfree(struct curl_httppost *form);
 
 /* Unix and Win32 getenv function call, this returns a malloc()'ed string that
    MUST be free()ed after usage is complete. */
@@ -606,6 +790,9 @@ char *curl_version(void);
  * allocated string or NULL if an error occurred.  */
 char *curl_escape(const char *string, int length);
 char *curl_unescape(const char *string, int length);
+/* 20020912 WJM. Provide for a de-allocation in the same translation unit
+   that did the allocation. Added in libcurl 7.10 */
+void curl_free(void *p);
 
 /* curl_global_init() should be invoked exactly once for each application that
    uses libcurl */
@@ -616,8 +803,8 @@ CURLcode curl_global_init(long flags);
 void curl_global_cleanup(void);
 
 /* This is the version number */
-#define LIBCURL_VERSION "7.9.5"
-#define LIBCURL_VERSION_NUM 0x070905
+#define LIBCURL_VERSION "7.10.2"
+#define LIBCURL_VERSION_NUM 0x070a02
 
 /* linked-list structure for the CURLOPT_QUOTE option (and other) */
 struct curl_slist {
@@ -671,14 +858,18 @@ typedef enum {
 
   CURLINFO_CONTENT_TYPE = CURLINFO_STRING + 18,
 
+  CURLINFO_REDIRECT_TIME   = CURLINFO_DOUBLE + 19,
+  CURLINFO_REDIRECT_COUNT  = CURLINFO_LONG + 20,
+
   /* Fill in new entries here! */
 
-  CURLINFO_LASTONE          = 19
+  CURLINFO_LASTONE          = 21
 } CURLINFO;
 
-/* unfortunately, the easy.h include file needs the options and info stuff
-   before it can be included! */
-#include <curl/easy.h> /* nothing in curl is fun without the easy stuff */
+/* unfortunately, the easy.h and multi.h include files need options and info
+  stuff before they can be included! */
+#include "easy.h" /* nothing in curl is fun without the easy stuff */
+#include "multi.h"
 
 typedef enum {
   CURLCLOSEPOLICY_NONE, /* first, never use this */
@@ -698,6 +889,78 @@ typedef enum {
 #define CURL_GLOBAL_NOTHING 0
 #define CURL_GLOBAL_DEFAULT CURL_GLOBAL_ALL
 
+
+/*****************************************************************************
+ * Setup defines, protos etc for the sharing stuff.
+ */
+
+/* Different types of locks that a share can aquire */
+typedef enum {
+  CURL_LOCK_TYPE_NONE = 0,
+  CURL_LOCK_TYPE_COOKIE = 1<<0,
+  CURL_LOCK_TYPE_DNS = 1<<1,
+  CURL_LOCK_TYPE_SSL_SESSION = 2<<1,
+  CURL_LOCK_TYPE_CONNECT = 2<<2,
+  CURL_LOCK_TYPE_LAST
+} curl_lock_type;
+
+typedef void (*curl_lock_function)(CURL *, curl_lock_type, void *);
+typedef void (*curl_unlock_function)(CURL *, curl_lock_type, void *);
+
+typedef struct {
+  unsigned int specifier;
+  unsigned int locked;
+  unsigned int dirty;
+  
+  curl_lock_function lockfunc;
+  curl_unlock_function unlockfunc;
+  void *clientdata;
+} curl_share;
+
+curl_share *curl_share_init (void);
+CURLcode curl_share_setopt (curl_share *, curl_lock_type, int);
+CURLcode curl_share_set_lock_function (curl_share *, curl_lock_function);
+CURLcode curl_share_set_unlock_function (curl_share *, curl_unlock_function);
+CURLcode curl_share_set_lock_data (curl_share *, void *);
+CURLcode curl_share_destroy (curl_share *);
+
+/****************************************************************************
+ * Structures for querying information about the curl library at runtime.
+ */
+
+typedef enum {
+  CURLVERSION_FIRST,
+  CURLVERSION_LAST /* never actually use this */
+} CURLversion;
+
+/* The 'CURLVERSION_NOW' is the symbolic name meant to be used by
+   basicly all programs ever, that want to get version information. It is
+   meant to be a built-in version number for what kind of struct the caller
+   expects. If the struct ever changes, we redfine the NOW to another enum
+   from above. */
+#define CURLVERSION_NOW CURLVERSION_FIRST
+
+typedef struct {
+  CURLversion age;          /* age of the returned struct */
+  const char *version;      /* LIBCURL_VERSION */
+  unsigned int version_num; /* LIBCURL_VERSION_NUM */
+  const char *host;         /* OS/host/cpu/machine when configured */
+  int features;             /* bitmask, see defines below */
+  char *ssl_version;        /* human readable string */
+  long ssl_version_num;     /* number */
+  const char *libz_version;       /* human readable string */
+  /* protocols is terminated by an entry with a NULL protoname */
+  const char **protocols;
+} curl_version_info_data;
+
+#define CURL_VERSION_IPV6      (1<<0)
+#define CURL_VERSION_KERBEROS4 (1<<1)
+#define CURL_VERSION_SSL       (1<<2)
+#define CURL_VERSION_LIBZ      (1<<3)
+
+/* returns a pointer to a static copy of the version info struct */
+curl_version_info_data *curl_version_info(CURLversion);
+
 #ifdef  __cplusplus
 }
 #endif
diff --git a/Source/CTest/Curl/curl/easy.h b/Source/CTest/Curl/curl/easy.h
index d3545ff..47f4e96 100644
--- a/Source/CTest/Curl/curl/easy.h
+++ b/Source/CTest/Curl/curl/easy.h
@@ -1,27 +1,27 @@
 #ifndef __CURL_EASY_H
 #define __CURL_EASY_H
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 #ifdef  __cplusplus
 extern "C" {
 #endif
diff --git a/Source/CTest/Curl/curl/stdcheaders.h b/Source/CTest/Curl/curl/stdcheaders.h
index 3fbaaf7..35648b5 100644
--- a/Source/CTest/Curl/curl/stdcheaders.h
+++ b/Source/CTest/Curl/curl/stdcheaders.h
@@ -1,27 +1,27 @@
 #ifndef __STDC_HEADERS_H
 #define __STDC_HEADERS_H
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
diff --git a/Source/CTest/Curl/curl/types.h b/Source/CTest/Curl/curl/types.h
index 05f73bf..5598880 100644
--- a/Source/CTest/Curl/curl/types.h
+++ b/Source/CTest/Curl/curl/types.h
@@ -1,27 +1,27 @@
 #ifndef __CURL_TYPES_H
 #define __CURL_TYPES_H
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 typedef void CURL;
 typedef void CURLconnect;
 
diff --git a/Source/CTest/Curl/dict.c b/Source/CTest/Curl/dict.c
index d5068ff..94257c9 100644
--- a/Source/CTest/Curl/dict.c
+++ b/Source/CTest/Curl/dict.c
@@ -1,25 +1,25 @@
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 
 #include "setup.h"
 
diff --git a/Source/CTest/Curl/dict.h b/Source/CTest/Curl/dict.h
index 348403d..537e486 100644
--- a/Source/CTest/Curl/dict.h
+++ b/Source/CTest/Curl/dict.h
@@ -1,29 +1,30 @@
 #ifndef __DICT_H
 #define __DICT_H
 
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
+#ifndef CURL_DISABLE_DICT
 CURLcode Curl_dict(struct connectdata *conn);
 CURLcode Curl_dict_done(struct connectdata *conn);
-
+#endif
 #endif
diff --git a/Source/CTest/Curl/easy.c b/Source/CTest/Curl/easy.c
index 45de7e8..b128180 100644
--- a/Source/CTest/Curl/easy.c
+++ b/Source/CTest/Curl/easy.c
@@ -1,25 +1,25 @@
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 
 #include "setup.h"
 
@@ -238,7 +238,7 @@ CURLcode curl_easy_perform(CURL *curl)
       data->hostcache = Curl_global_host_cache_get();
     }
     else {
-      data->hostcache = curl_hash_alloc(7, Curl_freeaddrinfo);
+      data->hostcache = Curl_hash_alloc(7, Curl_freeaddrinfo);
     }
   }
 
@@ -249,7 +249,7 @@ void curl_easy_cleanup(CURL *curl)
 {
   struct SessionHandle *data = (struct SessionHandle *)curl;
   if (!Curl_global_host_cache_use(data)) {
-    curl_hash_destroy(data->hostcache);
+    Curl_hash_destroy(data->hostcache);
   }
   Curl_close(data);
 }
@@ -312,7 +312,8 @@ CURL *curl_easy_duphandle(CURL *incurl)
     /* If cookies are enabled in the parent handle, we enable them
        in the clone as well! */
     outcurl->cookies = Curl_cookie_init(data->cookies->filename,
-                                        outcurl->cookies);
+                                        outcurl->cookies,
+                                        data->set.cookiesession);
 
   /* duplicate all values in 'change' */
   if(data->change.url) {
diff --git a/Source/CTest/Curl/escape.c b/Source/CTest/Curl/escape.c
index 88f4359..0ec7ae5 100644
--- a/Source/CTest/Curl/escape.c
+++ b/Source/CTest/Curl/escape.c
@@ -1,25 +1,25 @@
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 
 /* Escape and unescape URL encoding in strings. The functions return a new
  * allocated string or NULL if an error occurred.  */
@@ -48,11 +48,9 @@ char *curl_escape(const char *string, int length)
   length = alloc-1;
   while(length--) {
     in = *string;
-    if(' ' == in)
-      ns[index++] = '+';
-    else if(!(in >= 'a' && in <= 'z') &&
-            !(in >= 'A' && in <= 'Z') &&
-            !(in >= '0' && in <= '9')) {
+    if(!(in >= 'a' && in <= 'z') &&
+       !(in >= 'A' && in <= 'Z') &&
+       !(in >= '0' && in <= '9')) {
       /* encode it */
       newlen += 2; /* the size grows with two, since this'll become a %XX */
       if(newlen > alloc) {
@@ -82,19 +80,10 @@ char *curl_unescape(const char *string, int length)
   unsigned char in;
   int index=0;
   unsigned int hex;
-  char querypart=FALSE; /* everything to the right of a '?' letter is
-                           the "query part" where '+' should become ' '.
-                           RFC 2316, section 3.10 */
   
   while(--alloc > 0) {
     in = *string;
-    if(querypart && ('+' == in))
-      in = ' ';
-    else if(!querypart && ('?' == in)) {
-      /* we have "walked in" to the query part */
-      querypart=TRUE;
-    }
-    else if('%' == in) {
+    if('%' == in) {
       /* encoded part */
       if(sscanf(string+1, "%02X", &hex)) {
         in = hex;
@@ -111,6 +100,11 @@ char *curl_unescape(const char *string, int length)
   
 }
 
+void curl_free(void *p)
+{
+  free(p);
+}
+
 /*
  * local variables:
  * eval: (load-file "../curl-mode.el")
diff --git a/Source/CTest/Curl/escape.h b/Source/CTest/Curl/escape.h
index cda6a65..5808207 100644
--- a/Source/CTest/Curl/escape.h
+++ b/Source/CTest/Curl/escape.h
@@ -1,28 +1,28 @@
 #ifndef __ESCAPE_H
 #define __ESCAPE_H
 
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 /* Escape and unescape URL encoding in strings. The functions return a new
  * allocated string or NULL if an error occurred.  */
 
diff --git a/Source/CTest/Curl/file.c b/Source/CTest/Curl/file.c
index b2270aa..59b9bac 100644
--- a/Source/CTest/Curl/file.c
+++ b/Source/CTest/Curl/file.c
@@ -1,28 +1,29 @@
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 
 #include "setup.h"
 
+#ifndef CURL_DISABLE_FILE
 /* -- WIN32 approved -- */
 #include <stdio.h>
 #include <string.h>
@@ -140,7 +141,7 @@ CURLcode Curl_file(struct connectdata *conn)
   */
   CURLcode res = CURLE_OK;
   struct stat statbuf;
-  ssize_t expected_size=-1;
+  double expected_size=-1;
   ssize_t nread;
   struct SessionHandle *data = conn->data;
   char *buf = data->state.buffer;
@@ -155,9 +156,19 @@ CURLcode Curl_file(struct connectdata *conn)
 /*VMS?? -- This only works reliable for STREAMLF files */
   if( -1 != fstat(fd, &statbuf)) {
     /* we could stat it, then read out the size */
-    expected_size = statbuf.st_size;
+    expected_size = (double)statbuf.st_size;
   }
 
+  /* Added by Dolbneff A.V & Spiridonoff A.V */
+  if (conn->resume_from <= expected_size)
+    expected_size -= conn->resume_from;
+  else
+    /* Is this error code suitable in such situation? */
+    return CURLE_FTP_BAD_DOWNLOAD_RESUME;
+
+  if (expected_size == 0)
+    return CURLE_OK;
+
   /* The following is a shortcut implementation of file reading
      this is both more efficient than the former call to download() and
      it avoids problems with select() and recv() on file descriptors
@@ -165,6 +176,10 @@ CURLcode Curl_file(struct connectdata *conn)
   if(expected_size != -1)
     Curl_pgrsSetDownloadSize(data, expected_size);
 
+  if(conn->resume_from)
+    /* Added by Dolbneff A.V & Spiridonoff A.V */
+    lseek(fd, conn->resume_from, SEEK_SET);
+
   while (res == CURLE_OK) {
     nread = read(fd, buf, BUFSIZE-1);
 
@@ -204,3 +219,4 @@ CURLcode Curl_file(struct connectdata *conn)
  * vim600: fdm=marker
  * vim: et sw=2 ts=2 sts=2 tw=78
  */
+#endif
diff --git a/Source/CTest/Curl/file.h b/Source/CTest/Curl/file.h
index 83ffa39..b11dcb7 100644
--- a/Source/CTest/Curl/file.h
+++ b/Source/CTest/Curl/file.h
@@ -1,28 +1,30 @@
 #ifndef __FILE_H
 #define __FILE_H
 
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
+#ifndef CURL_DISABLE_FILE
 CURLcode Curl_file(struct connectdata *conn);
 CURLcode Curl_file_connect(struct connectdata *conn);
 #endif
+#endif
diff --git a/Source/CTest/Curl/formdata.c b/Source/CTest/Curl/formdata.c
index e464559..b3503f3 100644
--- a/Source/CTest/Curl/formdata.c
+++ b/Source/CTest/Curl/formdata.c
@@ -1,25 +1,25 @@
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 
 /*
   Debug the form generator stand-alone by compiling this source file with:
@@ -109,6 +109,8 @@ Content-Disposition: form-data; name="FILECONTENT"
 
 #include "setup.h"
 
+#ifndef CURL_DISABLE_HTTP
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -171,8 +173,8 @@ static void GetStr(char **string,
 
 static
 int FormParse(char *input,
-              struct HttpPost **httppost,
-              struct HttpPost **last_post)
+              struct curl_httppost **httppost,
+              struct curl_httppost **last_post)
 {
   /* nextarg MUST be a string in the format 'name=contents' and we'll
      build a linked list with the info */
@@ -186,8 +188,8 @@ int FormParse(char *input,
   char *prevtype = NULL;
   char *sep;
   char *sep2;
-  struct HttpPost *post;
-  struct HttpPost *subpost; /* a sub-node */
+  struct curl_httppost *post;
+  struct curl_httppost *subpost; /* a sub-node */
   unsigned int i;
 
   /* Preallocate contents to the length of input to make sure we don't
@@ -296,9 +298,9 @@ int FormParse(char *input,
           /* For the first file name, we allocate and initiate the main list
              node */
 
-          post = (struct HttpPost *)malloc(sizeof(struct HttpPost));
+          post = (struct curl_httppost *)malloc(sizeof(struct curl_httppost));
           if(post) {
-            memset(post, 0, sizeof(struct HttpPost));
+            memset(post, 0, sizeof(struct curl_httppost));
             GetStr(&post->name, name);      /* get the name */
             GetStr(&post->contents, contp); /* get the contents */
             post->contentslength = 0;
@@ -320,9 +322,10 @@ int FormParse(char *input,
         else {
           /* we add a file name to the previously allocated node, known as
              'post' now */
-          subpost =(struct HttpPost *)malloc(sizeof(struct HttpPost));
+          subpost =(struct curl_httppost *)
+            malloc(sizeof(struct curl_httppost));
           if(subpost) {
-             memset(subpost, 0, sizeof(struct HttpPost));
+             memset(subpost, 0, sizeof(struct curl_httppost));
              GetStr(&subpost->name, name);      /* get the name */
              GetStr(&subpost->contents, contp); /* get the contents */
              subpost->contentslength = 0;
@@ -342,9 +345,9 @@ int FormParse(char *input,
       } while(sep && *sep); /* loop if there's another file name */
     }
     else {
-      post = (struct HttpPost *)malloc(sizeof(struct HttpPost));
+      post = (struct curl_httppost *)malloc(sizeof(struct curl_httppost));
       if(post) {
-        memset(post, 0, sizeof(struct HttpPost));
+        memset(post, 0, sizeof(struct curl_httppost));
         GetStr(&post->name, name);      /* get the name */
         if( contp[0]=='<' ) {
           GetStr(&post->contents, contp+1); /* get the contents */
@@ -378,8 +381,8 @@ int FormParse(char *input,
 }
 
 int curl_formparse(char *input,
-                   struct HttpPost **httppost,
-                   struct HttpPost **last_post)
+                   struct curl_httppost **httppost,
+                   struct curl_httppost **last_post)
 {
   return FormParse(input, httppost, last_post);
 }
@@ -394,27 +397,37 @@ int curl_formparse(char *input,
  * Returns newly allocated HttpPost on success and NULL if malloc failed.
  *
  ***************************************************************************/
-static struct HttpPost * AddHttpPost(char * name,
-                                     long namelength,
-                                     char * value,
-                                     long contentslength,
-                                     char *contenttype,
-                                     long flags,
-                                     struct curl_slist* contentHeader,
-                                     struct HttpPost *parent_post,
-                                     struct HttpPost **httppost,
-                                     struct HttpPost **last_post)
+static struct curl_httppost *
+AddHttpPost(char * name, long namelength,
+            char * value, long contentslength,
+
+            /* CMC: Added support for buffer uploads */
+            char * buffer, long bufferlength,
+
+            char *contenttype,
+            long flags,
+            struct curl_slist* contentHeader,
+            char *showfilename,
+            struct curl_httppost *parent_post,
+            struct curl_httppost **httppost,
+            struct curl_httppost **last_post)
 {
-  struct HttpPost *post;
-  post = (struct HttpPost *)malloc(sizeof(struct HttpPost));
+  struct curl_httppost *post;
+  post = (struct curl_httppost *)malloc(sizeof(struct curl_httppost));
   if(post) {
-    memset(post, 0, sizeof(struct HttpPost));
+    memset(post, 0, sizeof(struct curl_httppost));
     post->name = name;
     post->namelength = name?(namelength?namelength:(long)strlen(name)):0;
     post->contents = value;
     post->contentslength = contentslength;
+
+    /* CMC: Added support for buffer uploads */
+    post->buffer = buffer;
+    post->bufferlength = bufferlength;
+
     post->contenttype = contenttype;
     post->contentheader = contentHeader;
+    post->showfilename = showfilename;
     post->flags = flags;
   }
   else
@@ -600,44 +613,31 @@ static int AllocAndCopy (char **buffer, int buffer_length)
  * CURLFORM_FILE, "filename1", CURLFORM_FILE, "filename2", CURLFORM_END);
  *
  * Returns:
- * FORMADD_OK             on success
- * FORMADD_MEMORY         if the FormInfo allocation fails
- * FORMADD_OPTION_TWICE   if one option is given twice for one Form
- * FORMADD_NULL           if a null pointer was given for a char
- * FORMADD_MEMORY         if the allocation of a FormInfo struct failed
- * FORMADD_UNKNOWN_OPTION if an unknown option was used
- * FORMADD_INCOMPLETE     if the some FormInfo is not complete (or an error)
- * FORMADD_MEMORY         if a HttpPost struct cannot be allocated
- * FORMADD_MEMORY         if some allocation for string copying failed.
- * FORMADD_ILLEGAL_ARRAY  if an illegal option is used in an array
+ * CURL_FORMADD_OK             on success
+ * CURL_FORMADD_MEMORY         if the FormInfo allocation fails
+ * CURL_FORMADD_OPTION_TWICE   if one option is given twice for one Form
+ * CURL_FORMADD_NULL           if a null pointer was given for a char
+ * CURL_FORMADD_MEMORY         if the allocation of a FormInfo struct failed
+ * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used
+ * CURL_FORMADD_INCOMPLETE     if the some FormInfo is not complete (or an error)
+ * CURL_FORMADD_MEMORY         if a HttpPost struct cannot be allocated
+ * CURL_FORMADD_MEMORY         if some allocation for string copying failed.
+ * CURL_FORMADD_ILLEGAL_ARRAY  if an illegal option is used in an array
  *
  ***************************************************************************/
 
-typedef enum {
-  FORMADD_OK, /* first, no error */
-
-  FORMADD_MEMORY,
-  FORMADD_OPTION_TWICE,
-  FORMADD_NULL,
-  FORMADD_UNKNOWN_OPTION,
-  FORMADD_INCOMPLETE,
-  FORMADD_ILLEGAL_ARRAY,
-
-  FORMADD_LAST /* last */
-} FORMcode;
-
 static
-FORMcode FormAdd(struct HttpPost **httppost,
-                 struct HttpPost **last_post,
-                 va_list params)
+CURLFORMcode FormAdd(struct curl_httppost **httppost,
+                     struct curl_httppost **last_post,
+                     va_list params)
 {
   FormInfo *first_form, *current_form, *form;
-  FORMcode return_value = FORMADD_OK;
+  CURLFORMcode return_value = CURL_FORMADD_OK;
   const char *prevtype = NULL;
-  struct HttpPost *post = NULL;
+  struct curl_httppost *post = NULL;
   CURLformoption option;
   struct curl_forms *forms = NULL;
-  const char *array_value; /* value read from an array */
+  char *array_value=NULL; /* value read from an array */
 
   /* This is a state variable, that if TRUE means that we're parsing an
      array that we got passed to us. If FALSE we're parsing the input
@@ -653,7 +653,7 @@ FORMcode FormAdd(struct HttpPost **httppost,
     current_form = first_form;
   }
   else
-    return FORMADD_MEMORY;
+    return CURL_FORMADD_MEMORY;
 
   /*
    * Loop through all the options set.
@@ -661,14 +661,14 @@ FORMcode FormAdd(struct HttpPost **httppost,
   while (1) {
 
     /* break if we have an error to report */
-    if (return_value != FORMADD_OK)
+    if (return_value != CURL_FORMADD_OK)
       break;
 
     /* first see if we have more parts of the array param */
     if ( array_state ) {
       /* get the upcoming option from the given array */
       option = forms->option;
-      array_value = forms->value;
+      array_value = (char *)forms->value;
 
       forms++; /* advance this to next entry */
       if (CURLFORM_END == option) {
@@ -676,16 +676,6 @@ FORMcode FormAdd(struct HttpPost **httppost,
         array_state = FALSE;
         continue;
       }
-      else {
-        /* check that the option is OK in an array */
-
-        /* Daniel's note: do we really need to do this? */
-        if ( (option <= CURLFORM_ARRAY_START) ||
-             (option >= CURLFORM_ARRAY_END) ) {
-          return_value = FORMADD_ILLEGAL_ARRAY;
-          break;
-        }
-      }
     }
     else {
       /* This is not array-state, get next option */
@@ -696,11 +686,16 @@ FORMcode FormAdd(struct HttpPost **httppost,
 
     switch (option) {
     case CURLFORM_ARRAY:
-      forms = va_arg(params, struct curl_forms *);
-      if (forms)
-        array_state = TRUE;
-      else
-        return_value = FORMADD_NULL;
+      if(array_state)
+        /* we don't support an array from within an array */
+        return_value = CURL_FORMADD_ILLEGAL_ARRAY;
+      else {
+        forms = va_arg(params, struct curl_forms *);
+        if (forms)
+          array_state = TRUE;
+        else
+          return_value = CURL_FORMADD_NULL;
+      }
       break;
 
       /*
@@ -710,20 +705,22 @@ FORMcode FormAdd(struct HttpPost **httppost,
       current_form->flags |= HTTPPOST_PTRNAME; /* fall through */
     case CURLFORM_COPYNAME:
       if (current_form->name)
-        return_value = FORMADD_OPTION_TWICE;
+        return_value = CURL_FORMADD_OPTION_TWICE;
       else {
-        char *name = va_arg(params, char *);
+        char *name = array_state?
+          array_value:va_arg(params, char *);
         if (name)
           current_form->name = name; /* store for the moment */
         else
-          return_value = FORMADD_NULL;
+          return_value = CURL_FORMADD_NULL;
       }
       break;
     case CURLFORM_NAMELENGTH:
       if (current_form->namelength)
-        return_value = FORMADD_OPTION_TWICE;
+        return_value = CURL_FORMADD_OPTION_TWICE;
       else
-        current_form->namelength = va_arg(params, long);
+        current_form->namelength =
+          array_state?(long)array_value:va_arg(params, long);
       break;
 
       /*
@@ -733,117 +730,179 @@ FORMcode FormAdd(struct HttpPost **httppost,
       current_form->flags |= HTTPPOST_PTRCONTENTS; /* fall through */
     case CURLFORM_COPYCONTENTS:
       if (current_form->value)
-        return_value = FORMADD_OPTION_TWICE;
+        return_value = CURL_FORMADD_OPTION_TWICE;
       else {
-        char *value = va_arg(params, char *);
+        char *value =
+          array_state?array_value:va_arg(params, char *);
         if (value)
           current_form->value = value; /* store for the moment */
         else
-          return_value = FORMADD_NULL;
+          return_value = CURL_FORMADD_NULL;
       }
       break;
     case CURLFORM_CONTENTSLENGTH:
       if (current_form->contentslength)
-        return_value = FORMADD_OPTION_TWICE;
+        return_value = CURL_FORMADD_OPTION_TWICE;
       else
-        current_form->contentslength = va_arg(params, long);
+        current_form->contentslength =
+          array_state?(long)array_value:va_arg(params, long);
       break;
 
       /* Get contents from a given file name */
     case CURLFORM_FILECONTENT:
       if (current_form->flags != 0)
-        return_value = FORMADD_OPTION_TWICE;
+        return_value = CURL_FORMADD_OPTION_TWICE;
       else {
-        char *filename = va_arg(params, char *);
+        char *filename = array_state?
+          array_value:va_arg(params, char *);
         if (filename) {
           current_form->value = strdup(filename);
           current_form->flags |= HTTPPOST_READFILE;
         }
         else
-          return_value = FORMADD_NULL;
+          return_value = CURL_FORMADD_NULL;
       }
       break;
 
       /* We upload a file */
     case CURLFORM_FILE:
       {
-        const char *filename = NULL;
-        if (array_state)
-          filename = array_value;
-        else
-          filename = va_arg(params, const char *);
+        char *filename = array_state?array_value:
+          va_arg(params, char *);
+
         if (current_form->value) {
           if (current_form->flags & HTTPPOST_FILENAME) {
             if (filename) {
               if (!(current_form = AddFormInfo(strdup(filename),
                                                NULL, current_form)))
-                return_value = FORMADD_MEMORY;
+                return_value = CURL_FORMADD_MEMORY;
             }
             else
-              return_value = FORMADD_NULL;
+              return_value = CURL_FORMADD_NULL;
           }
           else
-            return_value = FORMADD_OPTION_TWICE;
+            return_value = CURL_FORMADD_OPTION_TWICE;
         }
         else {
           if (filename)
             current_form->value = strdup(filename);
           else
-            return_value = FORMADD_NULL;
+            return_value = CURL_FORMADD_NULL;
           current_form->flags |= HTTPPOST_FILENAME;
         }
         break;
       }
-    case CURLFORM_CONTENTTYPE:
+
+    /* CMC: Added support for buffer uploads */
+    case CURLFORM_BUFFER:
       {
-        const char *contenttype = NULL;
-        if (array_state)
-          contenttype = array_value;
+        char *filename = array_state?array_value:
+          va_arg(params, char *);
+
+        if (current_form->value) {
+          if (current_form->flags & HTTPPOST_BUFFER) {
+            if (filename) {
+              if (!(current_form = AddFormInfo(strdup(filename),
+                                               NULL, current_form)))
+                return_value = CURL_FORMADD_MEMORY;
+            }
+            else
+              return_value = CURL_FORMADD_NULL;
+          }
+          else
+            return_value = CURL_FORMADD_OPTION_TWICE;
+        }
+        else {
+          if (filename)
+            current_form->value = strdup(filename);
+          else
+            return_value = CURL_FORMADD_NULL;
+          current_form->flags |= HTTPPOST_BUFFER;
+        }
+        break;
+      }
+      
+    /* CMC: Added support for buffer uploads */
+    case CURLFORM_BUFFERPTR:
+        current_form->flags |= HTTPPOST_PTRBUFFER;
+      if (current_form->buffer)
+        return_value = CURL_FORMADD_OPTION_TWICE;
+      else {
+        char *buffer =
+          array_state?array_value:va_arg(params, char *);
+        if (buffer)
+          current_form->buffer = buffer; /* store for the moment */
         else
-          contenttype = va_arg(params, const char *);
+          return_value = CURL_FORMADD_NULL;
+      }
+      break;
+
+    /* CMC: Added support for buffer uploads */
+    case CURLFORM_BUFFERLENGTH:
+      if (current_form->bufferlength)
+        return_value = CURL_FORMADD_OPTION_TWICE;
+      else
+        current_form->bufferlength =
+          array_state?(long)array_value:va_arg(params, long);
+      break;
+
+    case CURLFORM_CONTENTTYPE:
+      {
+        char *contenttype =
+          array_state?array_value:va_arg(params, char *);
         if (current_form->contenttype) {
           if (current_form->flags & HTTPPOST_FILENAME) {
             if (contenttype) {
               if (!(current_form = AddFormInfo(NULL,
                                                strdup(contenttype),
                                                current_form)))
-                return_value = FORMADD_MEMORY;
+                return_value = CURL_FORMADD_MEMORY;
             }
             else
-              return_value = FORMADD_NULL;
+              return_value = CURL_FORMADD_NULL;
           }
           else
-            return_value = FORMADD_OPTION_TWICE;
+            return_value = CURL_FORMADD_OPTION_TWICE;
         }
         else {
           if (contenttype)
             current_form->contenttype = strdup(contenttype);
           else
-            return_value = FORMADD_NULL;
+            return_value = CURL_FORMADD_NULL;
         }
         break;
       }
     case CURLFORM_CONTENTHEADER:
       {
-        struct curl_slist* list = NULL;
-        if( array_state )
-          list = (struct curl_slist*)array_value;
-        else
-          list = va_arg(params,struct curl_slist*);
+        /* this "cast increases required alignment of target type" but
+           we consider it OK anyway */
+        struct curl_slist* list = array_state?
+          (struct curl_slist*)array_value:
+          va_arg(params, struct curl_slist*);
         
         if( current_form->contentheader )
-          return_value = FORMADD_OPTION_TWICE;
+          return_value = CURL_FORMADD_OPTION_TWICE;
         else
           current_form->contentheader = list;
         
         break;
       }
+    case CURLFORM_FILENAME:
+      {
+        char *filename = array_state?array_value:
+          va_arg(params, char *);
+        if( current_form->showfilename )
+          return_value = CURL_FORMADD_OPTION_TWICE;
+        else
+          current_form->showfilename = strdup(filename);
+        break;
+      }
     default:
-      return_value = FORMADD_UNKNOWN_OPTION;
+      return_value = CURL_FORMADD_UNKNOWN_OPTION;
     }
   }
 
-  if(FORMADD_OK == return_value) {
+  if(CURL_FORMADD_OK == return_value) {
     /* go through the list, check for copleteness and if everything is
      * alright add the HttpPost item otherwise set return_value accordingly */
     
@@ -856,14 +915,21 @@ FORMcode FormAdd(struct HttpPost **httppost,
              (form->flags & HTTPPOST_FILENAME) ) ||
            ( (form->flags & HTTPPOST_FILENAME) &&
              (form->flags & HTTPPOST_PTRCONTENTS) ) ||
+
+           /* CMC: Added support for buffer uploads */
+           ( (!form->buffer) &&
+             (form->flags & HTTPPOST_BUFFER) &&
+             (form->flags & HTTPPOST_PTRBUFFER) ) ||
+
            ( (form->flags & HTTPPOST_READFILE) &&
              (form->flags & HTTPPOST_PTRCONTENTS) )
            ) {
-        return_value = FORMADD_INCOMPLETE;
+        return_value = CURL_FORMADD_INCOMPLETE;
         break;
       }
       else {
-        if ( (form->flags & HTTPPOST_FILENAME) &&
+        if ( ((form->flags & HTTPPOST_FILENAME) ||
+              (form->flags & HTTPPOST_BUFFER)) &&
              !form->contenttype ) {
           /* our contenttype is missing */
           form->contenttype
@@ -873,28 +939,36 @@ FORMcode FormAdd(struct HttpPost **httppost,
              (form == first_form) ) {
           /* copy name (without strdup; possibly contains null characters) */
           if (AllocAndCopy(&form->name, form->namelength)) {
-            return_value = FORMADD_MEMORY;
+            return_value = CURL_FORMADD_MEMORY;
             break;
           }
         }
         if ( !(form->flags & HTTPPOST_FILENAME) &&
              !(form->flags & HTTPPOST_READFILE) && 
-             !(form->flags & HTTPPOST_PTRCONTENTS) ) {
+             !(form->flags & HTTPPOST_PTRCONTENTS) &&
+
+             /* CMC: Added support for buffer uploads */
+             !(form->flags & HTTPPOST_PTRBUFFER) ) {
+
           /* copy value (without strdup; possibly contains null characters) */
           if (AllocAndCopy(&form->value, form->contentslength)) {
-            return_value = FORMADD_MEMORY;
+            return_value = CURL_FORMADD_MEMORY;
             break;
           }
         }
         post = AddHttpPost(form->name, form->namelength,
                            form->value, form->contentslength,
+
+                           /* CMC: Added support for buffer uploads */
+                           form->buffer, form->bufferlength,
+
                            form->contenttype, form->flags,
-                           form->contentheader,
+                           form->contentheader, form->showfilename,
                            post, httppost,
                            last_post);
         
         if(!post)
-          return_value = FORMADD_MEMORY;
+          return_value = CURL_FORMADD_MEMORY;
 
         if (form->contenttype)
           prevtype = form->contenttype;
@@ -915,12 +989,12 @@ FORMcode FormAdd(struct HttpPost **httppost,
   return return_value;
 }
 
-int curl_formadd(struct HttpPost **httppost,
-                 struct HttpPost **last_post,
+CURLFORMcode curl_formadd(struct curl_httppost **httppost,
+                 struct curl_httppost **last_post,
                  ...)
 {
   va_list arg;
-  int result;
+  CURLFORMcode result;
   va_start(arg, last_post);
   result = FormAdd(httppost, last_post, arg);
   va_end(arg);
@@ -975,8 +1049,8 @@ char *Curl_FormBoundary(void)
                               the same form won't be identical */
   int i;
 
-  static char table64[]=
-    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+  static char table62[]=
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
 
   retstring = (char *)malloc(BOUNDARY_LENGTH);
 
@@ -988,7 +1062,7 @@ char *Curl_FormBoundary(void)
   strcpy(retstring, "curl"); /* bonus commercials 8*) */
 
   for(i=4; i<(BOUNDARY_LENGTH-1); i++) {
-    retstring[i] = table64[rand()%64];
+    retstring[i] = table62[rand()%62];
   }
   retstring[BOUNDARY_LENGTH-1]=0; /* zero terminate */
 
@@ -1009,9 +1083,9 @@ void Curl_formclean(struct FormData *form)
 }
 
 /* external function to free up a whole form post chain */
-void curl_formfree(struct HttpPost *form)
+void curl_formfree(struct curl_httppost *form)
 {
-  struct HttpPost *next;
+  struct curl_httppost *next;
 
   if(!form)
     /* no form to free, just get out of this */
@@ -1030,27 +1104,31 @@ void curl_formfree(struct HttpPost *form)
       free(form->contents); /* free the contents */
     if(form->contenttype)
       free(form->contenttype); /* free the content type */
+    if(form->showfilename)
+      free(form->showfilename); /* free the faked file name */
     free(form);       /* free the struct */
 
   } while((form=next)); /* continue */
 }
 
-struct FormData *Curl_getFormData(struct HttpPost *post,
-                                  int *sizep)
+CURLcode Curl_getFormData(struct FormData **finalform,
+                          struct curl_httppost *post,
+                          int *sizep)
 {
   struct FormData *form = NULL;
   struct FormData *firstform;
-
-  struct HttpPost *file;
+  struct curl_httppost *file;
+  CURLcode result = CURLE_OK;
 
   int size =0;
   char *boundary;
   char *fileboundary=NULL;
   struct curl_slist* curList;
 
+  *finalform=NULL; /* default form is empty */
 
   if(!post)
-    return NULL; /* no input => no output! */
+    return result; /* no input => no output! */
 
   boundary = Curl_FormBoundary();
   
@@ -1093,16 +1171,29 @@ struct FormData *Curl_getFormData(struct HttpPost *post,
     file = post;
 
     do {
+
+      /* If 'showfilename' is set, that is a faked name passed on to us
+         to use to in the formpost. If that is not set, the actually used
+         local file name should be added. */
+
       if(post->more) {
         /* if multiple-file */
         size += AddFormDataf(&form,
-                             "\r\n--%s\r\nContent-Disposition: attachment; filename=\"%s\"",
-                             fileboundary, file->contents);
+                             "\r\n--%s\r\nContent-Disposition: "
+                             "attachment; filename=\"%s\"",
+                             fileboundary,
+                             (file->showfilename?file->showfilename:
+                              file->contents));
       }
-      else if(post->flags & HTTPPOST_FILENAME) {
+      else if((post->flags & HTTPPOST_FILENAME) ||
+
+              /* CMC: Added support for buffer uploads */
+              (post->flags & HTTPPOST_BUFFER)) {
+
         size += AddFormDataf(&form,
                              "; filename=\"%s\"",
-                             post->contents);
+                             (post->showfilename?post->showfilename:
+                              post->contents));
       }
       
       if(file->contenttype) {
@@ -1127,7 +1218,7 @@ struct FormData *Curl_getFormData(struct HttpPost *post,
        */
       
       if(file->contenttype &&
-         !strnequal("text/", file->contenttype, 5)) {
+         !checkprefix("text/", file->contenttype)) {
         /* this is not a text content, mention our binary encoding */
         size += AddFormData(&form, "\r\nContent-Transfer-Encoding: binary", 0);
       }
@@ -1144,24 +1235,34 @@ struct FormData *Curl_getFormData(struct HttpPost *post,
 
         fileread = strequal("-", file->contents)?stdin:
           /* binary read for win32 crap */
-/*VMS??*/ fopen(file->contents, "rb");  /* ONLY ALLOWS FOR STREAM FILES ON VMS */
-/*VMS?? Stream files are OK, as are FIXED & VAR files WITHOUT implied CC */
-/*VMS?? For implied CC, every record needs to have a \n appended & 1 added to SIZE */
+          /*VMS??*/ fopen(file->contents, "rb");  /* ONLY ALLOWS FOR STREAM FILES ON VMS */
+        /*VMS?? Stream files are OK, as are FIXED & VAR files WITHOUT implied CC */
+        /*VMS?? For implied CC, every record needs to have a \n appended & 1 added to SIZE */
         if(fileread) {
-          while((nread = fread(buffer, 1, 1024, fileread))) {
-            size += AddFormData(&form,
-                                buffer,
-                                nread);
-          }
+          while((nread = fread(buffer, 1, 1024, fileread)))
+            size += AddFormData(&form, buffer, nread);
+
           if(fileread != stdin)
             fclose(fileread);
         }
         else {
+#if 0
           /* File wasn't found, add a nothing field! */
           size += AddFormData(&form, "", 0);
+#endif
+          Curl_formclean(firstform);
+          free(boundary);
+          *finalform = NULL;
+          return CURLE_READ_ERROR;
         }
+
+        /* CMC: Added support for buffer uploads */
+      } else if (post->flags & HTTPPOST_BUFFER) {
+          /* include contents of buffer */
+          size += AddFormData(&form, post->buffer, post->bufferlength);
       }
- else {
+
+      else {
         /* include the contents we got */
         size += AddFormData(&form, post->contents, post->contentslength);
       }
@@ -1187,7 +1288,9 @@ struct FormData *Curl_getFormData(struct HttpPost *post,
 
   free(boundary);
 
-  return firstform;
+  *finalform=firstform;
+
+  return result;
 }
 
 int Curl_FormInit(struct Form *form, struct FormData *formdata )
@@ -1294,8 +1397,8 @@ int Curl_FormReadOneLine(char *buffer,
 
 #ifdef _FORM_DEBUG
 int FormAddTest(const char * errormsg,
-                 struct HttpPost **httppost,
-                 struct HttpPost **last_post,
+                 struct curl_httppost **httppost,
+                 struct curl_httppost **last_post,
                  ...)
 {
   int result;
@@ -1341,8 +1444,8 @@ int main()
   int size;
   int nread;
   char buffer[4096];
-  struct HttpPost *httppost=NULL;
-  struct HttpPost *last_post=NULL;
+  struct curl_httppost *httppost=NULL;
+  struct curl_httppost *last_post=NULL;
   struct curl_forms forms[4];
 
   struct FormData *form;
@@ -1451,9 +1554,9 @@ int main(int argc, char **argv)
 #endif
   int i;
   char *nextarg;
-  struct HttpPost *httppost=NULL;
-  struct HttpPost *last_post=NULL;
-  struct HttpPost *post;
+  struct curl_httppost *httppost=NULL;
+  struct curl_httppost *last_post=NULL;
+  struct curl_httppost *post;
   int size;
   int nread;
   char buffer[4096];
@@ -1492,6 +1595,8 @@ int main(int argc, char **argv)
 
 #endif
 
+#endif /* CURL_DISABLE_HTTP */
+
 /*
  * local variables:
  * eval: (load-file "../curl-mode.el")
diff --git a/Source/CTest/Curl/formdata.h b/Source/CTest/Curl/formdata.h
index 817c0d6..d1cc674 100644
--- a/Source/CTest/Curl/formdata.h
+++ b/Source/CTest/Curl/formdata.h
@@ -1,28 +1,28 @@
 #ifndef __FORMDATA_H
 #define __FORMDATA_H
 
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 /* plain and simple linked list with lines to send */
 struct FormData {
   struct FormData *next;
@@ -44,14 +44,23 @@ typedef struct FormInfo {
   long contentslength;
   char *contenttype;
   long flags;
+
+                /* CMC: Added support for buffer uploads */
+  char *buffer;      /* pointer to existing buffer used for file upload */
+        long bufferlength;   
+
+  char *showfilename; /* The file name to show. If not set, the actual
+                         file name will be used */
   struct curl_slist* contentheader;
   struct FormInfo *more;
 } FormInfo;
 
 int Curl_FormInit(struct Form *form, struct FormData *formdata );
 
-struct FormData *Curl_getFormData(struct HttpPost *post,
-                                  int *size);
+CURLcode
+Curl_getFormData(struct FormData **,
+                 struct HttpPost *post,
+                 int *size);
 
 /* fread() emulation */
 int Curl_FormReader(char *buffer,
diff --git a/Source/CTest/Curl/ftp.c b/Source/CTest/Curl/ftp.c
index 127971b..ac5f841 100644
--- a/Source/CTest/Curl/ftp.c
+++ b/Source/CTest/Curl/ftp.c
@@ -1,28 +1,29 @@
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 
 #include "setup.h"
 
+#ifndef CURL_DISABLE_FTP
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
@@ -210,16 +211,6 @@ int Curl_GetFTPResponse(char *buf,
   if (ftpcode)
     *ftpcode = 0; /* 0 for errors */
 
-  if(data->set.timeout) {
-    /* if timeout is requested, find out how much remaining time we have */
-    timeout = data->set.timeout - /* timeout time */
-      Curl_tvdiff(Curl_tvnow(), conn->now)/1000; /* spent time */
-    if(timeout <=0 ) {
-      failf(data, "Transfer aborted due to timeout");
-      return -SELECT_TIMEOUT; /* already too little time */
-    }
-  }
-
   FD_ZERO (&readfd);            /* clear it */
   FD_SET (sockfd, &readfd);     /* read socket */
 
@@ -235,11 +226,22 @@ int Curl_GetFTPResponse(char *buf,
   keepon=TRUE;
 
   while((nread<BUFSIZE) && (keepon && !error)) {
-    readfd = rkeepfd;              /* set every lap */
-    interval.tv_sec = timeout;
-    interval.tv_usec = 0;
+    /* check and reset timeout value every lap */
+    if(data->set.timeout) {
+      /* if timeout is requested, find out how much remaining time we have */
+      timeout = data->set.timeout - /* timeout time */
+        Curl_tvdiff(Curl_tvnow(), conn->now)/1000; /* spent time */
+      if(timeout <=0 ) {
+        failf(data, "Transfer aborted due to timeout");
+        return -SELECT_TIMEOUT; /* already too little time */
+      }
+    }
+
+    if(!ftp->cache) {
+      readfd = rkeepfd;            /* set every lap */
+      interval.tv_sec = timeout;
+      interval.tv_usec = 0;
 
-    if(!ftp->cache)
       switch (select (sockfd+1, &readfd, NULL, NULL, &interval)) {
       case -1: /* select() error, stop reading */
         error = SELECT_ERROR;
@@ -253,6 +255,7 @@ int Curl_GetFTPResponse(char *buf,
         error = SELECT_OK;
         break;
       }
+    }
     if(SELECT_OK == error) {
       /*
        * This code previously didn't use the kerberos sec_read() code
@@ -301,11 +304,8 @@ int Curl_GetFTPResponse(char *buf,
             CURLcode result;
 
             /* output debug output if that is requested */
-            if(data->set.verbose) {
-              fputs("< ", data->set.err);
-              fwrite(line_start, perline, 1, data->set.err);
-              /* no need to output LF here, it is part of the data */
-            }
+            if(data->set.verbose)
+              Curl_debug(data, CURLINFO_HEADER_IN, line_start, perline);
 
             /*
              * We pass all response-lines to the callback function registered
@@ -387,33 +387,10 @@ int Curl_GetFTPResponse(char *buf,
   return nread; /* total amount of bytes read */
 }
 
-#ifndef ENABLE_IPV6
 /*
- * This function is only used by code that works on IPv4. When we add proper
- * support for that functionality with IPv6, this function can go in again.
+ * Curl_ftp_connect() should do everything that is to be considered a part of
+ * the connection phase.
  */
-/* -- who are we? -- */
-static char *getmyhost(char *buf, int buf_size)
-{
-#if defined(HAVE_GETHOSTNAME)
-  gethostname(buf, buf_size);
-#elif defined(HAVE_UNAME)
-  struct utsname ugnm;
-  strncpy(buf, uname(&ugnm) < 0 ? "localhost" : ugnm.nodename, buf_size - 1);
-  buf[buf_size - 1] = '\0';
-#else
-  /* We have no means of finding the local host name! */
-  strncpy(buf, "localhost", buf_size);
-  buf[buf_size - 1] = '\0';
-#endif
-  return buf;
-}
-
-#endif /* ipv4-only function */
-
-
-/* ftp_connect() should do everything that is to be considered a part
-   of the connection phase. */
 CURLcode Curl_ftp_connect(struct connectdata *conn)
 {
   /* this is FTP and no proxy */
@@ -622,8 +599,10 @@ CURLcode Curl_ftp_done(struct connectdata *conn)
   CURLcode result=CURLE_OK;
 
   if(data->set.upload) {
-    if((-1 != data->set.infilesize) && (data->set.infilesize != *ftp->bytecountp)) {
-      failf(data, "Wrote only partial file (%d out of %d bytes)",
+    if((-1 != data->set.infilesize) &&
+       (data->set.infilesize != *ftp->bytecountp) &&
+       !data->set.crlf) {
+      failf(data, "Uploaded unaligned file size (%d out of %d bytes)",
             *ftp->bytecountp, data->set.infilesize);
       return CURLE_PARTIAL_FILE;
     }
@@ -634,9 +613,9 @@ CURLcode Curl_ftp_done(struct connectdata *conn)
       failf(data, "Received only partial file: %d bytes", *ftp->bytecountp);
       return CURLE_PARTIAL_FILE;
     }
-    else if(!conn->bits.resume_done &&
-            !data->set.no_body &&
-            (0 == *ftp->bytecountp)) {
+    else if(!ftp->dont_check &&
+            !*ftp->bytecountp &&
+            (conn->size>0)) {
       /* We consider this an error, but there's no true FTP error received
          why we need to continue to "read out" the server response too.
          We don't want to leave a "waiting" server reply if we'll get told
@@ -653,21 +632,25 @@ CURLcode Curl_ftp_done(struct connectdata *conn)
   sclose(conn->secondarysocket);
   conn->secondarysocket = -1;
 
-  if(!data->set.no_body && !conn->bits.resume_done) {  
-    /* now let's see what the server says about the transfer we
-       just performed: */
+  if(!ftp->no_transfer) {
+    /* now let's see what the server says about the transfer we just
+       performed: */
     nread = Curl_GetFTPResponse(buf, conn, &ftpcode);
     if(nread < 0)
       return CURLE_OPERATION_TIMEOUTED;
 
-    /* 226 Transfer complete, 250 Requested file action okay, completed. */
-    if((ftpcode != 226) && (ftpcode != 250)) {
-      failf(data, "server did not report OK, got %d", ftpcode);
-      return CURLE_FTP_WRITE_ERROR;
+    if(!ftp->dont_check) {
+      /* 226 Transfer complete, 250 Requested file action okay, completed. */
+      if((ftpcode != 226) && (ftpcode != 250)) {
+        failf(data, "server did not report OK, got %d", ftpcode);
+        return CURLE_FTP_WRITE_ERROR;
+      }
     }
   }
 
-  conn->bits.resume_done = FALSE; /* clean this for next connection */
+  /* clear these for next connection */
+  ftp->no_transfer = FALSE;
+  ftp->dont_check = FALSE; 
 
   /* Send any post-transfer QUOTE strings? */
   if(!result && data->set.postquote)
@@ -728,8 +711,7 @@ CURLcode ftp_cwd(struct connectdata *conn, char *path)
   CURLcode result;
   
   FTPSENDF(conn, "CWD %s", path);
-  nread = Curl_GetFTPResponse(
-                              conn->data->state.buffer, conn, &ftpcode);
+  nread = Curl_GetFTPResponse(conn->data->state.buffer, conn, &ftpcode);
   if (nread < 0)
     return CURLE_OPERATION_TIMEOUTED;
 
@@ -898,15 +880,19 @@ ftp_pasv_verbose(struct connectdata *conn,
   /* Bjorn Reese (November 28 2001):
      The Tru64 man page on gethostbyaddr_r() says that
      the hostent struct must be filled with zeroes before the call to
-     gethostbyaddr_r(). */
+     gethostbyaddr_r(). 
+
+     ... as must be struct hostent_data Craig Markwardt 19 Sep 2002. */
 
-  memset(hostent_buf, 0, sizeof(struct hostent));
+  memset(hostent_buf, 0, sizeof(struct hostent)+sizeof(struct hostent_data));
 
   if(gethostbyaddr_r((char *) &address,
                      sizeof(address), AF_INET,
                      (struct hostent *)hostent_buf,
-                     hostent_buf + sizeof(*answer)))
+                     (struct hostent_data *)(hostent_buf + sizeof(*answer))))
     answer=NULL;
+  else
+    answer=(struct hostent *)hostent_buf;
                            
 #  endif
 #  ifdef HAVE_GETHOSTBYADDR_R_7
@@ -914,7 +900,7 @@ ftp_pasv_verbose(struct connectdata *conn,
   answer = gethostbyaddr_r((char *) &address, sizeof(address), AF_INET,
                            (struct hostent *)bigbuf,
                            hostent_buf + sizeof(*answer),
-                           sizeof(hostent_buf) - sizeof(*answer),
+                           sizeof(bigbuf) - sizeof(*answer),
                            &h_errnop);
 #  endif
 #  ifdef HAVE_GETHOSTBYADDR_R_8
@@ -922,7 +908,7 @@ ftp_pasv_verbose(struct connectdata *conn,
   if(gethostbyaddr_r((char *) &address, sizeof(address), AF_INET,
                      (struct hostent *)hostent_buf,
                      hostent_buf + sizeof(*answer),
-                     sizeof(hostent_buf) - sizeof(*answer),
+                     sizeof(bigbuf) - sizeof(*answer),
                      &answer,
                      &h_errnop))
     answer=NULL; /* error */
@@ -1013,7 +999,6 @@ CURLcode ftp_use_port(struct connectdata *conn)
 #endif
   unsigned char *ap;
   unsigned char *pp;
-  int alen, plen;
   char portmsgbuf[4096], tmp[4096];
 
   const char *mode[] = { "EPRT", "LPRT", "PORT", NULL };
@@ -1064,18 +1049,19 @@ CURLcode ftp_use_port(struct connectdata *conn)
   }
   freeaddrinfo(res);
   if (portsock < 0) {
-    failf(data, strerror(errno));
+    failf(data, "%s", strerror(errno));
     return CURLE_FTP_PORT_FAILED;
   }
 
   sslen = sizeof(ss);
   if (getsockname(portsock, sa, &sslen) < 0) {
-    failf(data, strerror(errno));
+    failf(data, "%s", strerror(errno));
     return CURLE_FTP_PORT_FAILED;
   }
 
   for (modep = (char **)mode; modep && *modep; modep++) {
     int lprtaf, eprtaf;
+    int alen=0, plen=0;
     
     switch (sa->sa_family) {
     case AF_INET:
@@ -1197,30 +1183,42 @@ CURLcode ftp_use_port(struct connectdata *conn)
    *
    */
   struct sockaddr_in sa;
-  struct hostent *h=NULL;
-  char *hostdataptr=NULL;
+  struct Curl_dns_entry *h=NULL;
   unsigned short porttouse;
   char myhost[256] = "";
+  bool sa_filled_in = FALSE;
 
   if(data->set.ftpport) {
     if(Curl_if2ip(data->set.ftpport, myhost, sizeof(myhost))) {
-      h = Curl_resolv(data, myhost, 0, &hostdataptr);
+      h = Curl_resolv(data, myhost, 0);
     }
     else {
       int len = strlen(data->set.ftpport);
       if(len>1)
-        h = Curl_resolv(data, data->set.ftpport, 0, &hostdataptr);
+        h = Curl_resolv(data, data->set.ftpport, 0);
       if(h)
         strcpy(myhost, data->set.ftpport); /* buffer overflow risk */
     }
   }
   if(! *myhost) {
-    char *tmp_host = getmyhost(myhost, sizeof(myhost));
-    h=Curl_resolv(data, tmp_host, 0, &hostdataptr);
+    /* pick a suitable default here */
+
+    socklen_t sslen;
+    
+    sslen = sizeof(sa);
+    if (getsockname(conn->firstsocket, (struct sockaddr *)&sa, &sslen) < 0) {
+      failf(data, "getsockname() failed");
+      return CURLE_FTP_PORT_FAILED;
+    }
+
+    sa_filled_in = TRUE; /* the sa struct is filled in */
   }
-  infof(data, "We connect from %s\n", myhost);
-  
-  if ( h ) {
+
+  if(h)
+    /* when we return from here, we can forget about this */
+    Curl_resolv_unlock(h);
+
+  if ( h || sa_filled_in) {
     if( (portsock = socket(AF_INET, SOCK_STREAM, 0)) >= 0 ) {
       int size;
       
@@ -1229,12 +1227,15 @@ CURLcode ftp_use_port(struct connectdata *conn)
          we fail before the true secondary stuff is made */
       conn->secondarysocket = portsock;
 
-      memset((char *)&sa, 0, sizeof(sa));
-      memcpy((char *)&sa.sin_addr,
-             h->h_addr,
-             h->h_length);
-      sa.sin_family = AF_INET;
-      sa.sin_addr.s_addr = INADDR_ANY;
+      if(!sa_filled_in) {
+        memset((char *)&sa, 0, sizeof(sa));
+        memcpy((char *)&sa.sin_addr,
+               h->addr->h_addr,
+               h->addr->h_length);
+        sa.sin_family = AF_INET;
+        sa.sin_addr.s_addr = INADDR_ANY;
+      }
+
       sa.sin_port = 0;
       size = sizeof(sa);
       
@@ -1252,19 +1253,16 @@ CURLcode ftp_use_port(struct connectdata *conn)
         
         if ( listen(portsock, 1) < 0 ) {
           failf(data, "listen(2) failed on socket");
-          free(hostdataptr);
           return CURLE_FTP_PORT_FAILED;
         }
       }
       else {
         failf(data, "bind(2) failed on socket");
-        free(hostdataptr);
         return CURLE_FTP_PORT_FAILED;
       }
     }
     else {
       failf(data, "socket(2) failed (%s)");
-      free(hostdataptr);
       return CURLE_FTP_PORT_FAILED;
     }
   }
@@ -1278,7 +1276,10 @@ CURLcode ftp_use_port(struct connectdata *conn)
 #endif
     struct in_addr in;
     unsigned short ip[5];
-    (void) memcpy(&in.s_addr, *h->h_addr_list, sizeof (in.s_addr));
+    (void) memcpy(&in.s_addr,
+                  h?*h->addr->h_addr_list:(char *)&sa.sin_addr.s_addr,
+                  sizeof (in.s_addr));
+
 #ifdef HAVE_INET_NTOA_R
     /* ignore the return code from inet_ntoa_r() as it is int or
        char * depending on system */
@@ -1289,6 +1290,9 @@ CURLcode ftp_use_port(struct connectdata *conn)
     sscanf( inet_ntoa(in), "%hu.%hu.%hu.%hu",
             &ip[0], &ip[1], &ip[2], &ip[3]);
 #endif
+    infof(data, "Telling server to connect to %d.%d.%d.%d:%d\n",
+          ip[0], ip[1], ip[2], ip[3], porttouse);
+  
     result=Curl_ftpsendf(conn, "PORT %d,%d,%d,%d,%d,%d",
                          ip[0], ip[1], ip[2], ip[3],
                          porttouse >> 8,
@@ -1320,14 +1324,15 @@ CURLcode ftp_use_port(struct connectdata *conn)
  */
 
 static
-CURLcode ftp_use_pasv(struct connectdata *conn)
+CURLcode ftp_use_pasv(struct connectdata *conn,
+                      bool *connected)
 {
   struct SessionHandle *data = conn->data;
   ssize_t nread;
   char *buf = data->state.buffer; /* this is our buffer */
   int ftpcode; /* receive FTP response codes in this */
   CURLcode result;
-  Curl_addrinfo *addr=NULL;
+  struct Curl_dns_entry *addr=NULL;
   Curl_ipconnect *conninfo;
 
   /*
@@ -1358,8 +1363,7 @@ CURLcode ftp_use_pasv(struct connectdata *conn)
 #endif
   int modeoff;
   unsigned short connectport; /* the local port connect() should use! */
-  unsigned short newport; /* remote port, not necessary the local one */
-  char *hostdataptr=NULL;
+  unsigned short newport=0; /* remote port, not necessary the local one */
   
   /* newhost must be able to hold a full IP-style address in ASCII, which
      in the IPv6 case means 5*8-1 = 39 letters */
@@ -1368,7 +1372,7 @@ CURLcode ftp_use_pasv(struct connectdata *conn)
   
   for (modeoff = (data->set.ftp_use_epsv?0:1);
        mode[modeoff]; modeoff++) {
-    result = Curl_ftpsendf(conn, mode[modeoff]);
+    result = Curl_ftpsendf(conn, "%s", mode[modeoff]);
     if(result)
       return result;
     nread = Curl_GetFTPResponse(buf, conn, &ftpcode);
@@ -1449,18 +1453,21 @@ CURLcode ftp_use_pasv(struct connectdata *conn)
   if(data->change.proxy) {
     /*
      * This is a tunnel through a http proxy and we need to connect to the
-     * proxy again here. We already have the name info for it since the
-     * previous lookup.
+     * proxy again here.
+     *
+     * We don't want to rely on a former host lookup that might've expired
+     * now, instead we remake the lookup here and now!
      */
-    addr = conn->hostaddr;
+    addr = Curl_resolv(data, conn->proxyhost, conn->port);
     connectport =
-      (unsigned short)conn->port; /* we connect to the proxy's port */
+      (unsigned short)conn->port; /* we connect to the proxy's port */    
+
   }
   else {
     /* normal, direct, ftp connection */
-    addr = Curl_resolv(data, newhostp, newport, &hostdataptr);
+    addr = Curl_resolv(data, newhostp, newport);
     if(!addr) {
-      failf(data, "Can't resolve new host %s", newhost);
+      failf(data, "Can't resolve new host %s:%d", newhostp, newport);
       return CURLE_FTP_CANT_GET_HOST;
     }
     connectport = newport; /* we connect to the remote port */
@@ -1470,12 +1477,21 @@ CURLcode ftp_use_pasv(struct connectdata *conn)
                             addr,
                             connectport,
                             &conn->secondarysocket,
-                            &conninfo);
+                            &conninfo,
+                            connected);
+
+  Curl_resolv_unlock(addr); /* we're done using this address */
+
+  /*
+   * When this is used from the multi interface, this might've returned with
+   * the 'connected' set to FALSE and thus we are now awaiting a non-blocking
+   * connect to connect and we should not be "hanging" here waiting.
+   */
   
   if((CURLE_OK == result) &&       
      data->set.verbose)
     /* this just dumps information about this second connection */
-    ftp_pasv_verbose(conn, conninfo, newhost, connectport);
+    ftp_pasv_verbose(conn, conninfo, newhostp, connectport);
   
   if(CURLE_OK != result)
     return result;
@@ -1483,7 +1499,7 @@ CURLcode ftp_use_pasv(struct connectdata *conn)
   if (data->set.tunnel_thru_httpproxy) {
     /* We want "seamless" FTP operations through HTTP proxy tunnel */
     result = Curl_ConnectHTTPProxyTunnel(conn, conn->secondarysocket,
-                                         newhost, newport);
+                                         newhostp, newport);
     if(CURLE_OK != result)
       return result;
   }
@@ -1491,125 +1507,24 @@ CURLcode ftp_use_pasv(struct connectdata *conn)
   return CURLE_OK;
 }
 
-/***********************************************************************
- *
- * ftp_perform()
+/*
+ * Curl_ftp_nextconnect()
  *
- * This is the actual DO function for FTP. Get a file/directory according to
- * the options previously setup.
+ * This function shall be called when the second FTP connection has been
+ * established and is confirmed connected.
  */
 
-static
-CURLcode ftp_perform(struct connectdata *conn)
+CURLcode Curl_ftp_nextconnect(struct connectdata *conn)
 {
-  /* this is FTP and no proxy */
-  ssize_t nread;
-  CURLcode result;
   struct SessionHandle *data=conn->data;
   char *buf = data->state.buffer; /* this is our buffer */
+  CURLcode result;
+  ssize_t nread;
+  int ftpcode; /* for ftp status */
 
   /* the ftp struct is already inited in ftp_connect() */
   struct FTP *ftp = conn->proto.ftp;
-
   long *bytecountp = ftp->bytecountp;
-  int ftpcode; /* for ftp status */
-
-  /* Send any QUOTE strings? */
-  if(data->set.quote) {
-    if ((result = ftp_sendquote(conn, data->set.quote)) != CURLE_OK)
-      return result;
-  }
-    
-  /* This is a re-used connection. Since we change directory to where the
-     transfer is taking place, we must now get back to the original dir
-     where we ended up after login: */
-  if (conn->bits.reuse) {
-    if ((result = ftp_cwd(conn, ftp->entrypath)) != CURLE_OK)
-      return result;
-  }
-
-  /* change directory first! */
-  if(ftp->dir && ftp->dir[0]) {
-    if ((result = ftp_cwd(conn, ftp->dir)) != CURLE_OK)
-        return result;
-  }
-
-  /* Requested time of file? */
-  if(data->set.get_filetime && ftp->file) {
-    result = ftp_getfiletime(conn, ftp->file);
-    if(result)
-      return result;
-  }
-
-  /* If we have selected NOBODY and HEADER, it means that we only want file
-     information. Which in FTP can't be much more than the file size and
-     date. */
-  if(data->set.no_body && data->set.include_header) {
-    /* The SIZE command is _not_ RFC 959 specified, and therefor many servers
-       may not support it! It is however the only way we have to get a file's
-       size! */
-    ssize_t filesize;
-
-    /* Some servers return different sizes for different modes, and thus we
-       must set the proper type before we check the size */
-    result = ftp_transfertype(conn, data->set.ftp_ascii);
-    if(result)
-      return result;
-
-    /* failing to get size is not a serious error */
-    result = ftp_getsize(conn, ftp->file, &filesize);
-
-    if(CURLE_OK == result) {
-      sprintf(buf, "Content-Length: %d\r\n", filesize);
-      result = Curl_client_write(data, CLIENTWRITE_BOTH, buf, 0);
-      if(result)
-        return result;
-    }
-
-    /* If we asked for a time of the file and we actually got one as
-       well, we "emulate" a HTTP-style header in our output. */
-
-#ifdef HAVE_STRFTIME
-    if(data->set.get_filetime && data->info.filetime) {
-      struct tm *tm;
-#ifdef HAVE_LOCALTIME_R
-      struct tm buffer;
-      tm = (struct tm *)localtime_r(&data->info.filetime, &buffer);
-#else
-      tm = localtime((unsigned long *)&data->info.filetime);
-#endif
-      /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
-      strftime(buf, BUFSIZE-1, "Last-Modified: %a, %d %b %Y %H:%M:%S %Z\r\n",
-               tm);
-      result = Curl_client_write(data, CLIENTWRITE_BOTH, buf, 0);
-      if(result)
-        return result;
-    }
-#endif
-
-    return CURLE_OK;
-  }
-
-  if(data->set.no_body)
-    /* don't transfer the data */
-    ;
-  /* Get us a second connection up and connected */
-  else if(data->set.ftp_use_port) {
-    /* We have chosen to use the PORT command */
-    result = ftp_use_port(conn);
-    if(CURLE_OK == result)
-      /* we have the data connection ready */
-      infof(data, "Connected the data stream with PORT!\n");
-  }
-  else {
-    /* We have chosen (this is default) to use the PASV command */
-    result = ftp_use_pasv(conn);
-    if(CURLE_OK == result)
-      infof(data, "Connected the data stream with PASV!\n");
-  }
-  
-  if(result)
-    return result;
 
   if(data->set.upload) {
 
@@ -1688,10 +1603,9 @@ CURLcode ftp_perform(struct connectdata *conn)
             /* no data to transfer */
             result=Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
             
-            /* Set resume done so that we won't get any error in
-             * Curl_ftp_done() because we didn't transfer the amount of bytes
-             * that the local file file obviously is */
-            conn->bits.resume_done = TRUE; 
+            /* Set no_transfer so that we won't get any error in
+             * Curl_ftp_done() because we didn't transfer anything! */
+            ftp->no_transfer = TRUE; 
 
             return CURLE_OK;
           }
@@ -1780,6 +1694,7 @@ CURLcode ftp_perform(struct connectdata *conn)
       }
       infof(data, "range-download from %d to %d, totally %d bytes\n",
             from, to, totalsize);
+      ftp->dont_check = TRUE; /* dont check for successful transfer */
     }
 
     if((data->set.ftp_list_only) || !ftp->file) {
@@ -1872,11 +1787,9 @@ CURLcode ftp_perform(struct connectdata *conn)
           result=Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
           infof(data, "File already completely downloaded\n");
 
-          /* Set resume done so that we won't get any error in Curl_ftp_done()
-           * because we didn't transfer the amount of bytes that the remote
-           * file obviously is */
-          conn->bits.resume_done = TRUE; 
-
+          /* Set no_transfer so that we won't get any error in Curl_ftp_done()
+           * because we didn't transfer the any file */
+          ftp->no_transfer = TRUE;
           return CURLE_OK;
         }
         
@@ -1990,6 +1903,128 @@ CURLcode ftp_perform(struct connectdata *conn)
 
 /***********************************************************************
  *
+ * ftp_perform()
+ *
+ * This is the actual DO function for FTP. Get a file/directory according to
+ * the options previously setup.
+ */
+
+static
+CURLcode ftp_perform(struct connectdata *conn,
+                     bool *connected)  /* for the TCP connect status after
+                                          PASV / PORT */
+{
+  /* this is FTP and no proxy */
+  CURLcode result=CURLE_OK;
+  struct SessionHandle *data=conn->data;
+  char *buf = data->state.buffer; /* this is our buffer */
+
+  /* the ftp struct is already inited in ftp_connect() */
+  struct FTP *ftp = conn->proto.ftp;
+
+  /* Send any QUOTE strings? */
+  if(data->set.quote) {
+    if ((result = ftp_sendquote(conn, data->set.quote)) != CURLE_OK)
+      return result;
+  }
+    
+  /* This is a re-used connection. Since we change directory to where the
+     transfer is taking place, we must now get back to the original dir
+     where we ended up after login: */
+  if (conn->bits.reuse && ftp->entrypath) {
+    if ((result = ftp_cwd(conn, ftp->entrypath)) != CURLE_OK)
+      return result;
+  }
+
+  /* change directory first! */
+  if(ftp->dir && ftp->dir[0]) {
+    if ((result = ftp_cwd(conn, ftp->dir)) != CURLE_OK)
+        return result;
+  }
+
+  /* Requested time of file? */
+  if(data->set.get_filetime && ftp->file) {
+    result = ftp_getfiletime(conn, ftp->file);
+    if(result)
+      return result;
+  }
+
+  /* If we have selected NOBODY and HEADER, it means that we only want file
+     information. Which in FTP can't be much more than the file size and
+     date. */
+  if(data->set.no_body && data->set.include_header && ftp->file) {
+    /* The SIZE command is _not_ RFC 959 specified, and therefor many servers
+       may not support it! It is however the only way we have to get a file's
+       size! */
+    ssize_t filesize;
+
+    ftp->no_transfer = TRUE; /* this means no actual transfer is made */
+    
+    /* Some servers return different sizes for different modes, and thus we
+       must set the proper type before we check the size */
+    result = ftp_transfertype(conn, data->set.ftp_ascii);
+    if(result)
+      return result;
+
+    /* failing to get size is not a serious error */
+    result = ftp_getsize(conn, ftp->file, &filesize);
+
+    if(CURLE_OK == result) {
+      sprintf(buf, "Content-Length: %d\r\n", filesize);
+      result = Curl_client_write(data, CLIENTWRITE_BOTH, buf, 0);
+      if(result)
+        return result;
+    }
+
+    /* If we asked for a time of the file and we actually got one as
+       well, we "emulate" a HTTP-style header in our output. */
+
+#ifdef HAVE_STRFTIME
+    if(data->set.get_filetime && data->info.filetime) {
+      struct tm *tm;
+#ifdef HAVE_LOCALTIME_R
+      struct tm buffer;
+      tm = (struct tm *)localtime_r(&data->info.filetime, &buffer);
+#else
+      tm = localtime((unsigned long *)&data->info.filetime);
+#endif
+      /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
+      strftime(buf, BUFSIZE-1, "Last-Modified: %a, %d %b %Y %H:%M:%S %Z\r\n",
+               tm);
+      result = Curl_client_write(data, CLIENTWRITE_BOTH, buf, 0);
+      if(result)
+        return result;
+    }
+#endif
+
+    return CURLE_OK;
+  }
+
+  if(data->set.no_body)
+    /* doesn't really transfer any data */
+    ftp->no_transfer = TRUE;
+  /* Get us a second connection up and connected */
+  else if(data->set.ftp_use_port) {
+    /* We have chosen to use the PORT command */
+    result = ftp_use_port(conn);
+    if(CURLE_OK == result) {
+      /* we have the data connection ready */
+      infof(data, "Ordered connect of the data stream with PORT!\n");
+      *connected = TRUE; /* mark us "still connected" */
+    }
+  }
+  else {
+    /* We have chosen (this is default) to use the PASV command */
+    result = ftp_use_pasv(conn, connected);
+    if(connected)
+      infof(data, "Connected the data stream with PASV!\n");
+  }
+  
+  return result;
+}
+
+/***********************************************************************
+ *
  * Curl_ftp()
  *
  * This function is registered as 'curl_do' function. It decodes the path
@@ -2000,6 +2035,7 @@ CURLcode ftp_perform(struct connectdata *conn)
 CURLcode Curl_ftp(struct connectdata *conn)
 {
   CURLcode retcode;
+  bool connected;
 
   struct SessionHandle *data = conn->data;
   struct FTP *ftp;
@@ -2046,15 +2082,15 @@ CURLcode Curl_ftp(struct connectdata *conn)
   else
     ftp->dir = NULL;
 
-  retcode = ftp_perform(conn);
-
-  /* clean up here, success or error doesn't matter */
-  if(ftp->file)
-    free(ftp->file);
-  if(ftp->dir)
-    free(ftp->dir);
+  retcode = ftp_perform(conn, &connected);
 
-  ftp->file = ftp->dir = NULL; /* zero */
+  if(CURLE_OK == retcode) {
+    if(connected)
+      retcode = Curl_ftp_nextconnect(conn);
+    else
+      /* since we didn't connect now, we want do_more to get called */
+      conn->bits.do_more = TRUE;
+  }
 
   return retcode;
 }
@@ -2081,10 +2117,7 @@ CURLcode Curl_ftpsendf(struct connectdata *conn,
   va_start(ap, fmt);
   vsnprintf(s, 250, fmt, ap);
   va_end(ap);
-
-  if(conn->data->set.verbose)
-    fprintf(conn->data->set.err, "> %s\n", s);
-
+  
   strcat(s, "\r\n"); /* append a trailing CRLF */
 
   bytes_written=0;
@@ -2097,6 +2130,9 @@ CURLcode Curl_ftpsendf(struct connectdata *conn,
     if(CURLE_OK != res)
       break;
 
+    if(conn->data->set.verbose)
+      Curl_debug(conn->data, CURLINFO_HEADER_OUT, sptr, bytes_written);
+
     if(bytes_written != write_len) {
       write_len -= bytes_written;
       sptr += bytes_written;
@@ -2125,6 +2161,12 @@ CURLcode Curl_ftp_disconnect(struct connectdata *conn)
       free(ftp->entrypath);
     if(ftp->cache)
       free(ftp->cache);
+    if(ftp->file)
+      free(ftp->file);
+    if(ftp->dir)
+      free(ftp->dir);
+
+    ftp->file = ftp->dir = NULL; /* zero */
   }
   return CURLE_OK;
 }
@@ -2136,3 +2178,5 @@ CURLcode Curl_ftp_disconnect(struct connectdata *conn)
  * vim600: fdm=marker
  * vim: et sw=2 ts=2 sts=2 tw=78
  */
+
+#endif /* CURL_DISABLE_FTP */
diff --git a/Source/CTest/Curl/ftp.h b/Source/CTest/Curl/ftp.h
index a88cc72..2f8c15a 100644
--- a/Source/CTest/Curl/ftp.h
+++ b/Source/CTest/Curl/ftp.h
@@ -1,37 +1,37 @@
 #ifndef __FTP_H
 #define __FTP_H
-
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
+
+#ifndef CURL_DISABLE_FTP
 CURLcode Curl_ftp(struct connectdata *conn);
 CURLcode Curl_ftp_done(struct connectdata *conn);
 CURLcode Curl_ftp_connect(struct connectdata *conn);
 CURLcode Curl_ftp_disconnect(struct connectdata *conn);
-
 CURLcode Curl_ftpsendf(struct connectdata *, const char *fmt, ...);
-
-/* The kerberos stuff needs this: */
 int Curl_GetFTPResponse(char *buf, struct connectdata *conn,
                         int *ftpcode);
+CURLcode Curl_ftp_nextconnect(struct connectdata *conn);
+#endif
 
 #endif
diff --git a/Source/CTest/Curl/getenv.c b/Source/CTest/Curl/getenv.c
index 66bca30..e19bad2 100644
--- a/Source/CTest/Curl/getenv.c
+++ b/Source/CTest/Curl/getenv.c
@@ -1,25 +1,25 @@
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 
 #include "setup.h"
 
diff --git a/Source/CTest/Curl/getinfo.c b/Source/CTest/Curl/getinfo.c
index b05e51b..6639833 100644
--- a/Source/CTest/Curl/getinfo.c
+++ b/Source/CTest/Curl/getinfo.c
@@ -1,25 +1,25 @@
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 
 #include "setup.h"
 
@@ -35,6 +35,11 @@
 #include        <stdlib.h>
 #endif
 
+/* Make this the last #include */
+#ifdef MALLOCDEBUG
+#include "memdebug.h"
+#endif
+
 /*
  * This is supposed to be called in the beginning of a permform() session
  * and should reset all session-info variables
@@ -49,6 +54,7 @@ CURLcode Curl_initinfo(struct SessionHandle *data)
   pro->t_pretransfer = 0;
   pro->t_starttransfer = 0;
   pro->timespent = 0;
+  pro->t_redirect = 0;
 
   info->httpcode = 0;
   info->httpversion=0;
@@ -66,9 +72,9 @@ CURLcode Curl_initinfo(struct SessionHandle *data)
 CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...)
 {
   va_list arg;
-  long *param_longp;
-  double *param_doublep;
-  char **param_charp;
+  long *param_longp=NULL;
+  double *param_doublep=NULL;
+  char **param_charp=NULL;
   va_start(arg, info);
 
   switch(info&CURLINFO_TYPEMASK) {
@@ -143,6 +149,12 @@ CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...)
   case CURLINFO_CONTENT_LENGTH_UPLOAD:
     *param_doublep = data->progress.size_ul;
     break;
+  case CURLINFO_REDIRECT_TIME:
+    *param_doublep =  data->progress.t_redirect;
+    break;
+  case CURLINFO_REDIRECT_COUNT:
+    *param_longp = data->set.followlocation;
+    break;
   case CURLINFO_CONTENT_TYPE:
     *param_charp = data->info.contenttype;
     break;
diff --git a/Source/CTest/Curl/getinfo.h b/Source/CTest/Curl/getinfo.h
index 23fdff1..dd30afb 100644
--- a/Source/CTest/Curl/getinfo.h
+++ b/Source/CTest/Curl/getinfo.h
@@ -1,27 +1,27 @@
 #ifndef __GETINFO_H
 #define __GETINFO_H
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...);
 CURLcode Curl_initinfo(struct SessionHandle *data);
 
diff --git a/Source/CTest/Curl/getpass.c b/Source/CTest/Curl/getpass.c
index fd0d6fe..d0f4eda 100644
--- a/Source/CTest/Curl/getpass.c
+++ b/Source/CTest/Curl/getpass.c
@@ -1,5 +1,5 @@
 /* ============================================================================
- * Copyright (C) 1998 Angus Mackay. All rights reserved; 
+ * Copyright (C) 1998 - 2002, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * Redistribution and use are freely permitted provided that:
  *
@@ -93,14 +93,10 @@ char *getpass_r(const char *prompt, char *buffer, size_t buflen)
 #include "memdebug.h"
 #endif
 
-/* no perror? make an fprintf! */
-#ifndef HAVE_PERROR
-#  define perror(x) fprintf(stderr, "Error in: %s\n", x)
-#endif
-
 char *getpass_r(const char *prompt, char *buffer, size_t buflen)
 {
   FILE *infp;
+  char infp_fclose = 0;
   FILE *outfp;
   RETSIGTYPE (*sigint)();
 #ifndef __EMX__
@@ -127,41 +123,30 @@ char *getpass_r(const char *prompt, char *buffer, size_t buflen)
   sigtstp = signal(SIGTSTP, SIG_IGN);
 #endif
 
-  if( (infp=fopen("/dev/tty", "r")) == NULL )
-  {
+  infp=fopen("/dev/tty", "r");
+  if( NULL == infp )
     infp = stdin;
-  }
-  if( (outfp=fopen("/dev/tty", "w")) == NULL )
-  {
-    outfp = stderr;
-  }
+  else
+    infp_fclose = 1;
+
+  outfp = stderr;
+
   infd = fileno(infp);
   outfd = fileno(outfp);
 
   /* dissable echo */
 #ifdef HAVE_TERMIOS_H
-  if(tcgetattr(outfd, &orig) != 0)
-  {
-    ; /*perror("tcgetattr");*/
-  }
+  tcgetattr(outfd, &orig);
+
   noecho = orig;
   noecho.c_lflag &= ~ECHO;
-  if(tcsetattr(outfd, TCSANOW, &noecho) != 0)
-  {
-    ; /*perror("tcgetattr");*/
-  }
+  tcsetattr(outfd, TCSANOW, &noecho);
 #else
 #  ifdef HAVE_TERMIO_H
-  if(ioctl(outfd, TCGETA, &orig) != 0)
-  {
-    ; /*perror("ioctl");*/
-  }
+  ioctl(outfd, TCGETA, &orig);
   noecho = orig;
   noecho.c_lflag &= ~ECHO;
-  if(ioctl(outfd, TCSETA, &noecho) != 0)
-  {
-    ; /*perror("ioctl");*/
-  }
+  ioctl(outfd, TCSETA, &noecho);
 #  else
 #  endif
 #endif
@@ -187,16 +172,10 @@ char *getpass_r(const char *prompt, char *buffer, size_t buflen)
    * user types more than buflen
    */
 #ifdef HAVE_TERMIOS_H
-  if(tcsetattr(outfd, TCSAFLUSH, &orig) != 0)
-  {
-    ; /*perror("tcgetattr");*/
-  }
+  tcsetattr(outfd, TCSAFLUSH, &orig);
 #else
 #  ifdef HAVE_TERMIO_H
-  if(ioctl(outfd, TCSETA, &orig) != 0)
-  {
-    ; /*perror("ioctl");*/
-  }
+  ioctl(outfd, TCSETA, &orig);
 #  else
 #  endif
 #endif
@@ -206,6 +185,9 @@ char *getpass_r(const char *prompt, char *buffer, size_t buflen)
   signal(SIGTSTP, sigtstp);
 #endif
 
+  if(infp_fclose)
+    fclose(infp);
+
   return buffer; /* we always return success */
 }
 #endif /* VMS */
diff --git a/Source/CTest/Curl/getpass.h b/Source/CTest/Curl/getpass.h
index 249a26e..475d275 100644
--- a/Source/CTest/Curl/getpass.h
+++ b/Source/CTest/Curl/getpass.h
@@ -1,27 +1,27 @@
 #ifndef __GETPASS_H
 #define __GETPASS_H
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 #ifndef HAVE_GETPASS_R
 /* If there's a system-provided function named like this, we trust it is
    also found in one of the standard headers. */
diff --git a/Source/CTest/Curl/hash.c b/Source/CTest/Curl/hash.c
index 584c30e..56e7077 100644
--- a/Source/CTest/Curl/hash.c
+++ b/Source/CTest/Curl/hash.c
@@ -1,30 +1,31 @@
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2002, Daniel Stenberg, <daniel@haxx.se>, et al
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 
 #include "setup.h"
 
 #include <string.h>
 #include <stdlib.h>
+
 #include "hash.h"
 #include "llist.h"
 
@@ -34,55 +35,45 @@
 #endif
 
 
-static unsigned long 
-curl_hash_str(const char *key, unsigned int key_length)
+/* {{{ static unsigned long _hash_str (const char *, size_t)
+ */
+static unsigned long
+_hash_str (const char *key, size_t key_length)
 {
-  register unsigned long h = 0;
-  register unsigned long g;
-  register char *p = (char *) key;
-  register char *end = (char *) key + key_length;
-
-  while (p < end) {
-    h = (h << 4) + *p++;
-    if ((g = (h & 0xF0000000))) {
-      h = h ^ (g >> 24);
-      h = h ^ g;
-    }
+  char *end = (char *) key + key_length;
+  unsigned long h = 5381;
+
+  while (key < end) {
+    h += h << 5;
+    h ^= (unsigned long) *key++;
   }
 
   return h;
 }
+/* }}} */
 
-static unsigned long 
-curl_hash_num(unsigned long key)
-{
-  key += ~(key << 15);
-  key ^= (key >> 10);
-  key += (key << 3);
-  key ^= (key >> 6);
-  key += (key << 11);
-  key ^= (key >> 16);
-
-  return key;
-}
-
+/* {{{ static void _hash_element_dtor (void *, void *)
+ */
 static void 
-hash_element_dtor(void *u, void *ele)
+_hash_element_dtor (void *user, void *element)
 {
-  curl_hash_element *e = (curl_hash_element *) ele; 
-  curl_hash         *h = (curl_hash *) u; 
-        
-  if (e->key.type == CURL_HASH_KEY_IS_STRING) {
-    free(e->key.value.str.val);
+  curl_hash         *h = (curl_hash *) user;
+  curl_hash_element *e = (curl_hash_element *) element;
+
+  if (e->key) {
+    free(e->key);
   }
+
   h->dtor(e->ptr);
 
   free(e);
-  e = NULL;
 }
+/* }}} */
 
+/* {{{ void curl_hash_init (curl_hash *, int, curl_hash_dtor)
+ */
 void 
-curl_hash_init(curl_hash *h, int slots, curl_hash_dtor dtor)
+Curl_hash_init (curl_hash *h, int slots, curl_hash_dtor dtor)
 {
   int i;
 
@@ -91,116 +82,110 @@ curl_hash_init(curl_hash *h, int slots, curl_hash_dtor dtor)
   h->slots = slots;  
 
   h->table = (curl_llist **) malloc(slots * sizeof(curl_llist *));
-  for (i = 0; i < h->slots; ++i) {
-    h->table[i] = curl_llist_alloc((curl_llist_dtor) hash_element_dtor);
+  for (i = 0; i < slots; ++i) {
+    h->table[i] = Curl_llist_alloc((curl_llist_dtor) _hash_element_dtor);
   }
 }
+/* }}} */
 
+/* {{{ curl_hash *curl_hash_alloc (int, curl_hash_dtor)
+ */
 curl_hash *
-curl_hash_alloc(int slots, curl_hash_dtor dtor)
+Curl_hash_alloc (int slots, curl_hash_dtor dtor)
 {
   curl_hash *h;
 
-  h = (curl_hash *)malloc(sizeof(curl_hash));
-  if(NULL == h)
+  h = (curl_hash *) malloc(sizeof(curl_hash));
+  if (NULL == h)
     return NULL;
 
-  curl_hash_init(h, slots, dtor);
+  Curl_hash_init(h, slots, dtor);
 
   return h;
 }
+/* }}} */
 
-#define FIND_SLOT(__h, __s_key, __s_key_len, __n_key) \
-  ((__s_key ? curl_hash_str(__s_key, __s_key_len) : curl_hash_num(__n_key)) % (__h)->slots)
-
-#define KEY_CREATE(__k, __s_key, __s_key_len, __n_key, __dup) \
-  if (__s_key) { \
-    if (__dup) { \
-      (__k)->value.str.val = (char *) malloc(__s_key_len); \
-      memcpy((__k)->value.str.val, __s_key, __s_key_len); \
-    } else { \
-      (__k)->value.str.val = __s_key; \
-    } \
-    (__k)->value.str.len = __s_key_len; \
-    (__k)->type = CURL_HASH_KEY_IS_STRING; \
-  } else { \
-    (__k)->value.num = __n_key; \
-    (__k)->type = CURL_HASH_KEY_IS_NUM; \
+/* {{{ static int _hash_key_compare (char *, size_t, char *, size_t)
+ */
+static int 
+_hash_key_compare (char *key1, size_t key1_len, char *key2, size_t key2_len)
+{
+  if (key1_len == key2_len && 
+      *key1 == *key2 &&
+      memcmp(key1, key2, key1_len) == 0) {
+    return 1;
   }
 
-#define MIN(a, b) (a > b ? b : a)
+  return 0;
+}
+/* }}} */
 
-static int 
-curl_hash_key_compare(curl_hash_key *key1, curl_hash_key *key2)
+/* {{{ static int _mk_hash_element (curl_hash_element **, char *, size_t, const void *)
+ */
+static int
+_mk_hash_element (curl_hash_element **e, char *key, size_t key_len, const void *p)
 {
-  if (key1->type == CURL_HASH_KEY_IS_NUM) {
-    if (key2->type == CURL_HASH_KEY_IS_STRING)
-      return 0;
+  *e = (curl_hash_element *) malloc(sizeof(curl_hash_element));
+  (*e)->key = strdup(key);
+  (*e)->key_len = key_len;
+  (*e)->ptr = (void *) p;
+  return 0;
+}
+/* }}} */
 
-    if (key1->value.num == key2->value.num)
-      return 1;
-  } else {
-    if (key2->type == CURL_HASH_KEY_IS_NUM)
-      return 0;
+#define find_slot(__h, __k, __k_len) (_hash_str(__k, __k_len) % (__h)->slots)
 
-    if (memcmp(key1->value.str.val, key2->value.str.val, 
-               MIN(key1->value.str.len, key2->value.str.len)) == 0)
-      return 1;
-  }
+#define FETCH_LIST \
+  curl_llist *l = h->table[find_slot(h, key, key_len)]
 
-  return 0;
-}
 
+/* {{{ int curl_hash_add (curl_hash *, char *, size_t, const void *)
+ */
 int 
-curl_hash_add_or_update(curl_hash *h, char *str_key, unsigned int str_key_len, 
-                        unsigned long num_key, const void *p)
+Curl_hash_add (curl_hash *h, char *key, size_t key_len, const void *p)
 {
-  curl_hash_element  *e;
-  curl_hash_key       tmp;
-  curl_llist         *l; 
+  curl_hash_element  *he;
   curl_llist_element *le;
-  int                slot;
-
-  slot = FIND_SLOT(h, str_key, str_key_len, num_key);
-  l = h->table[slot];
-  KEY_CREATE(&tmp, str_key, str_key_len, num_key, 0);
-  for (le = CURL_LLIST_HEAD(l); le != NULL; le = CURL_LLIST_NEXT(le)) {
-    if (curl_hash_key_compare(&tmp, &((curl_hash_element *) CURL_LLIST_VALP(le))->key)) {
-      curl_hash_element *to_update = CURL_LLIST_VALP(le);
-      h->dtor(to_update->ptr);
-      to_update->ptr = (void *) p;
+  FETCH_LIST;
+
+  for (le = CURL_LLIST_HEAD(l);
+       le != NULL;
+       le = CURL_LLIST_NEXT(le)) {
+    he = (curl_hash_element *) CURL_LLIST_VALP(le);
+    if (_hash_key_compare(he->key, he->key_len, key, key_len)) {
+      h->dtor(he->ptr);
+      he->ptr = (void *) p;
       return 1;
     }
   }
 
-  e = (curl_hash_element *) malloc(sizeof(curl_hash_element));
-  KEY_CREATE(&e->key, str_key, str_key_len, num_key, 1);
-  e->ptr = (void *) p;
+  if (_mk_hash_element(&he, key, key_len, p) != 0) 
+    return 0;
 
-  if (curl_llist_insert_next(l, CURL_LLIST_TAIL(l), e)) {
+  if (Curl_llist_insert_next(l, CURL_LLIST_TAIL(l), he)) {
     ++h->size;
     return 1;
-  } else {
-    return 0;
   }
+
+  return 0;
 }
+/* }}} */
 
+/* {{{ int curl_hash_delete (curl_hash *, char *, size_t)
+ */
 int 
-curl_hash_extended_delete(curl_hash *h, char *str_key, unsigned int str_key_len, 
-                          unsigned long num_key)
+Curl_hash_delete(curl_hash *h, char *key, size_t key_len)
 {
-  curl_llist         *l;
+  curl_hash_element  *he;
   curl_llist_element *le;
-  curl_hash_key       tmp;
-  int                slot;
-
-  slot = FIND_SLOT(h, str_key, str_key_len, num_key);
-  l = h->table[slot];
-
-  KEY_CREATE(&tmp, str_key, str_key_len, num_key, 0);
-  for (le = CURL_LLIST_HEAD(l); le != NULL; le = CURL_LLIST_NEXT(le)) {
-    if (curl_hash_key_compare(&tmp, &((curl_hash_element *) CURL_LLIST_VALP(le))->key)) {
-      curl_llist_remove(l, le, (void *) h);
+  FETCH_LIST;
+
+  for (le = CURL_LLIST_HEAD(l);
+       le != NULL;
+       le = CURL_LLIST_NEXT(le)) {
+    he = CURL_LLIST_VALP(le);
+    if (_hash_key_compare(he->key, he->key_len, key, key_len)) {
+      Curl_llist_remove(l, le, (void *) h);
       --h->size;
       return 1;
     }
@@ -208,73 +193,111 @@ curl_hash_extended_delete(curl_hash *h, char *str_key, unsigned int str_key_len,
 
   return 0;
 }
+/* }}} */
 
-int 
-curl_hash_extended_find(curl_hash *h, char *str_key, unsigned int str_key_len, 
-                        unsigned long num_key, void **p)
+/* {{{ int curl_hash_pick (curl_hash *, char *, size_t, void **)
+ */
+void *
+Curl_hash_pick(curl_hash *h, char *key, size_t key_len)
 {
-  curl_llist         *l;
   curl_llist_element *le;
-  curl_hash_key       tmp;
-  int                slot;
-
-  slot = FIND_SLOT(h, str_key, str_key_len, num_key);
-  l = h->table[slot];
-
-  KEY_CREATE(&tmp, str_key, str_key_len, num_key, 0);
-  for (le = CURL_LLIST_HEAD(l); le != NULL; le = CURL_LLIST_NEXT(le)) {
-    if (curl_hash_key_compare(&tmp, &((curl_hash_element *) CURL_LLIST_VALP(le))->key)) {
-      *p = ((curl_hash_element *) CURL_LLIST_VALP(le))->ptr;
-      return 1;
+  curl_hash_element  *he;
+  FETCH_LIST;
+
+  for (le = CURL_LLIST_HEAD(l);
+       le != NULL;
+       le = CURL_LLIST_NEXT(le)) {
+    he = CURL_LLIST_VALP(le);
+    if (_hash_key_compare(he->key, he->key_len, key, key_len)) {
+      return he->ptr;
     }
   }
 
-  return 0;
+  return NULL;
 }
+/* }}} */
 
+/* {{{ void curl_hash_apply (curl_hash *, void *, void (*)(void *, curl_hash_element *))
+ */
 void 
-curl_hash_apply(curl_hash *h, void *user, void (*cb)(void *, curl_hash_element *))
+Curl_hash_apply(curl_hash *h, void *user,
+                void (*cb)(void *user, void *ptr))
 {
   curl_llist_element  *le;
   int                  i;
 
   for (i = 0; i < h->slots; ++i) {
-    for (le = CURL_LLIST_HEAD(h->table[i]); le != NULL; le = CURL_LLIST_NEXT(le)) {
-      cb(user, (curl_hash_element *) CURL_LLIST_VALP(le));
+    for (le = CURL_LLIST_HEAD(h->table[i]);
+         le != NULL;
+         le = CURL_LLIST_NEXT(le)) {
+      curl_hash_element *el = CURL_LLIST_VALP(le);
+      cb(user, el->ptr);
     }
   }
 }
+/* }}} */
 
+/* {{{ void curl_hash_clean (curl_hash *)
+ */
 void
-curl_hash_clean(curl_hash *h)
+Curl_hash_clean(curl_hash *h)
 {
   int i;
 
   for (i = 0; i < h->slots; ++i) {
-    curl_llist_destroy(h->table[i], (void *) h);
+    Curl_llist_destroy(h->table[i], (void *) h);
   }
 
   free(h->table);
-  h->table = NULL;
 }
+/* }}} */
 
-size_t 
-curl_hash_count(curl_hash *h)
+/* {{{ void curl_hash_clean_with_criterium (curl_hash *, void *,
+   int (*)(void *, void *))
+ */
+void
+Curl_hash_clean_with_criterium(curl_hash *h, void *user,
+                               int (*comp)(void *, void *))
+{
+  curl_llist_element *le;
+  curl_llist_element *lnext;
+  int i;
+
+  for (i = 0; i < h->slots; ++i) {
+    le = CURL_LLIST_HEAD(h->table[i]);
+    while(le != NULL)
+      if (comp(user, ((curl_hash_element *) CURL_LLIST_VALP(le))->ptr)) {
+        lnext = CURL_LLIST_NEXT(le);
+        Curl_llist_remove(h->table[i], le, (void *) h);
+        --h->size;
+        le = lnext;
+      }
+      else
+        le = CURL_LLIST_NEXT(le);
+  }
+}
+
+/* {{{ int curl_hash_count (curl_hash *)
+ */
+int 
+Curl_hash_count(curl_hash *h)
 {
   return h->size;
 }
+/* }}} */
 
+/* {{{ void curl_hash_destroy (curl_hash *)
+ */
 void 
-curl_hash_destroy(curl_hash *h)
+Curl_hash_destroy(curl_hash *h)
 {
-  if (!h) {
+  if (!h)
     return;
-  }
 
-  curl_hash_clean(h);
+  Curl_hash_clean(h);
   free(h);
-  h = NULL;
 }
+/* }}} */
 
 /*
  * local variables:
diff --git a/Source/CTest/Curl/hash.h b/Source/CTest/Curl/hash.h
index d6117ce..c3464c3 100644
--- a/Source/CTest/Curl/hash.h
+++ b/Source/CTest/Curl/hash.h
@@ -1,27 +1,27 @@
 #ifndef __HASH_H
 #define __HASH_H
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 
 #include "setup.h"
 
@@ -29,9 +29,6 @@
 
 #include "llist.h"
 
-#define CURL_HASH_KEY_IS_STRING 0
-#define CURL_HASH_KEY_IS_NUM    1
-
 typedef void (*curl_hash_dtor)(void *);
 
 typedef struct _curl_hash {
@@ -41,45 +38,31 @@ typedef struct _curl_hash {
   size_t           size;
 } curl_hash;
 
-typedef struct _curl_hash_key {
-  union {
-    struct {
-      char *val;
-      unsigned int len;
-    } str;
-
-    unsigned long num;
-  } value;
-
-  int type;
-} curl_hash_key;
-
 typedef struct _curl_hash_element {
-  curl_hash_key  key;
-  void          *ptr;
+  void   *ptr;
+  char   *key;
+  size_t key_len;
 } curl_hash_element;
 
 
-void curl_hash_init(curl_hash *h, int slots, curl_hash_dtor dtor);
-curl_hash *curl_hash_alloc(int slots, curl_hash_dtor dtor);
-int curl_hash_add_or_update(curl_hash *h, char *str_key, unsigned int str_key_len, 
-                             unsigned long num_key, const void *p);
-int curl_hash_extended_delete(curl_hash *h, char *str_key, unsigned int str_key_len, 
-                               unsigned long num_key);
-int curl_hash_extended_find(curl_hash *h, char *str_key, unsigned int str_key_len, 
-                             unsigned long num_key, void **p);
-void curl_hash_apply(curl_hash *h, void *user, void (*cb)(void *, curl_hash_element *));
-size_t curl_hash_count(curl_hash *h);
-void curl_hash_clean(curl_hash *h);
-void curl_hash_destroy(curl_hash *h);
-
-#define curl_hash_find(h, key, key_len, p) curl_hash_extended_find(h, key, key_len, 0, p)
-#define curl_hash_delete(h, key, key_len) curl_hash_extended_delete(h, key, key_len, 0)
-#define curl_hash_add(h, key, key_len, p) curl_hash_add_or_update(h, key, key_len, 0, p)
-#define curl_hash_update curl_hash_add
-#define curl_hash_index_find(h, key, p) curl_hash_extended_find(h, NULL, 0, key, p)
-#define curl_hash_index_delete(h, key) curl_hash_extended_delete(h, NULL, 0, key)
-#define curl_hash_index_add(h, key, p) curl_hash_add_or_update(h, NULL, 0, key, p)
-#define curl_hash_index_update curl_hash_index_add
+void Curl_hash_init(curl_hash *, int, curl_hash_dtor);
+curl_hash *Curl_hash_alloc(int, curl_hash_dtor);
+int Curl_hash_add(curl_hash *, char *, size_t, const void *);
+int Curl_hash_delete(curl_hash *h, char *key, size_t key_len);
+void *Curl_hash_pick(curl_hash *, char *, size_t);
+void Curl_hash_apply(curl_hash *h, void *user,
+                     void (*cb)(void *user, void *ptr));
+int Curl_hash_count(curl_hash *h);
+void Curl_hash_clean(curl_hash *h);
+void Curl_hash_clean_with_criterium(curl_hash *h, void *user, int (*comp)(void *, void *));
+void Curl_hash_destroy(curl_hash *h);
 
 #endif
+
+/*
+ * local variables:
+ * eval: (load-file "../curl-mode.el")
+ * end:
+ * vim600: fdm=marker
+ * vim: et sw=2 ts=2 sts=2 tw=78
+ */
diff --git a/Source/CTest/Curl/hostip.c b/Source/CTest/Curl/hostip.c
index 489dfab..07fb1d2 100644
--- a/Source/CTest/Curl/hostip.c
+++ b/Source/CTest/Curl/hostip.c
@@ -1,25 +1,25 @@
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 
 #include "setup.h"
 
@@ -56,6 +56,10 @@
 #endif
 #endif
 
+#ifdef HAVE_SETJMP_H
+#include <setjmp.h>
+#endif
+
 #include "urldata.h"
 #include "sendf.h"
 #include "hostip.h"
@@ -76,10 +80,15 @@
 static curl_hash hostname_cache;
 static int host_cache_initialized;
 
+static Curl_addrinfo *my_getaddrinfo(struct SessionHandle *data,
+                                       char *hostname,
+                                       int port,
+                                       char **bufp);
+
 void Curl_global_host_cache_init(void)
 {
   if (!host_cache_initialized) {
-    curl_hash_init(&hostname_cache, 7, Curl_freeaddrinfo);
+    Curl_hash_init(&hostname_cache, 7, Curl_freeaddrinfo);
     host_cache_initialized = 1;
   }
 }
@@ -92,16 +101,11 @@ curl_hash *Curl_global_host_cache_get(void)
 void Curl_global_host_cache_dtor(void)
 {
   if (host_cache_initialized) {
-    curl_hash_clean(&hostname_cache);
+    Curl_hash_clean(&hostname_cache);
     host_cache_initialized = 0;
   }
 }
 
-struct curl_dns_cache_entry {
-  Curl_addrinfo *addr;
-  time_t timestamp;
-};
-
 /* count the number of characters that an integer takes up */
 static int _num_chars(int i)
 {
@@ -125,7 +129,7 @@ static int _num_chars(int i)
 
 /* Create a hostcache id */
 static char *
-_create_hostcache_id(char *server, int port, ssize_t *entry_len)
+create_hostcache_id(char *server, int port, ssize_t *entry_len)
 {
   char *id = NULL;
 
@@ -152,70 +156,132 @@ _create_hostcache_id(char *server, int port, ssize_t *entry_len)
   return id;
 }
 
+struct hostcache_prune_data {
+  int cache_timeout;
+  int now;
+};
+
+static int
+hostcache_timestamp_remove(void *datap, void *hc)
+{
+  struct hostcache_prune_data *data = 
+    (struct hostcache_prune_data *) datap;
+  struct Curl_dns_entry *c = (struct Curl_dns_entry *) hc;
+  
+  if ((data->now - c->timestamp < data->cache_timeout) ||
+      c->inuse) {
+    /* please don't remove */
+    return 0;
+  }
+  
+  /* fine, remove */
+  return 1;
+}
+
+static void
+hostcache_prune(curl_hash *hostcache, int cache_timeout, int now)
+{
+  struct hostcache_prune_data user;
+
+  user.cache_timeout = cache_timeout;
+  user.now = now;
+  
+  Curl_hash_clean_with_criterium(hostcache, 
+                                 (void *) &user, 
+                                 hostcache_timestamp_remove);
+}
+
+#if defined(MALLOCDEBUG) && defined(AGGRESIVE_TEST)
+/* Called from Curl_done() to check that there's no DNS cache entry with
+   a non-zero counter left. */
+void Curl_scan_cache_used(void *user, void *ptr)
+{
+  struct Curl_dns_entry *e = ptr;
+  (void)user; /* prevent compiler warning */
+  if(e->inuse) {
+    fprintf(stderr, "*** WARNING: locked DNS cache entry detected: %s\n",
+            e->entry_id);
+    /* perform a segmentation fault to draw attention */
+    *(void **)0 = 0;
+  }
+}
+#endif
+
 /* Macro to save redundant free'ing of entry_id */
-#define _hostcache_return(__v) \
+#define HOSTCACHE_RETURN(dns) \
 { \
   free(entry_id); \
-  return (__v); \
+  return dns; \
 }
 
-Curl_addrinfo *Curl_resolv(struct SessionHandle *data,
-                           char *hostname,
-                           int port,
-                           char **bufp)
+#ifdef HAVE_SIGSETJMP
+/* Beware this is a global and unique instance */
+sigjmp_buf curl_jmpenv;
+#endif
+
+struct Curl_dns_entry *Curl_resolv(struct SessionHandle *data,
+                                   char *hostname,
+                                   int port)
 {
   char *entry_id = NULL;
-  struct curl_dns_cache_entry *p = NULL;
+  struct Curl_dns_entry *dns = NULL;
   ssize_t entry_len;
   time_t now;
-
-  /* If the host cache timeout is 0, we don't do DNS cach'ing
-     so fall through */
-  if (data->set.dns_cache_timeout == 0) {
-    return Curl_getaddrinfo(data, hostname, port, bufp);
+  char *bufp;
+
+#ifdef HAVE_SIGSETJMP
+  /* this allows us to time-out from the name resolver, as the timeout
+     will generate a signal and we will siglongjmp() from that here */
+  if(!data->set.no_signal && sigsetjmp(curl_jmpenv, 1)) {
+    /* this is coming from a siglongjmp() */
+    failf(data, "name lookup time-outed");
+    return NULL;
   }
+#endif
 
   /* Create an entry id, based upon the hostname and port */
   entry_len = strlen(hostname);
-  entry_id = _create_hostcache_id(hostname, port, &entry_len);
-  /* If we can't create the entry id, don't cache, just fall-through
-     to the plain Curl_getaddrinfo() */
-  if (!entry_id) {
-    return Curl_getaddrinfo(data, hostname, port, bufp);
-  }
+  entry_id = create_hostcache_id(hostname, port, &entry_len);
+  /* If we can't create the entry id, fail */
+  if (!entry_id)
+    return NULL;
   
-  time(&now);
   /* See if its already in our dns cache */
-  if (entry_id && curl_hash_find(data->hostcache, entry_id, entry_len+1, (void **) &p)) {
-    /* Do we need to check for a cache timeout? */
-    if (data->set.dns_cache_timeout != -1) {
-      /* Return if the entry has not timed out */
-      if ((now - p->timestamp) < data->set.dns_cache_timeout) {
-        _hostcache_return(p->addr);
-      }
+  dns = Curl_hash_pick(data->hostcache, entry_id, entry_len+1);
+
+  if (!dns) {
+    Curl_addrinfo *addr = my_getaddrinfo(data, hostname, port, &bufp);
+    
+    if (!addr) {
+      HOSTCACHE_RETURN(NULL);
     }
-    else {
-      _hostcache_return(p->addr);
+
+    /* Create a new cache entry */
+    dns = (struct Curl_dns_entry *) malloc(sizeof(struct Curl_dns_entry));
+    if (!dns) {
+      Curl_freeaddrinfo(addr);
+      HOSTCACHE_RETURN(NULL);
     }
-  }
 
-  /* Create a new cache entry */
-  p = (struct curl_dns_cache_entry *) malloc(sizeof(struct curl_dns_cache_entry));
-  if (!p) {
-   _hostcache_return(NULL);
+    dns->inuse = 0;
+    dns->addr = addr;
+    /* Save it in our host cache */
+    Curl_hash_add(data->hostcache, entry_id, entry_len+1, (const void *) dns);
   }
+  time(&now);
 
-  p->addr = Curl_getaddrinfo(data, hostname, port, bufp);
-  if (!p->addr) {
-    free(p);
-    _hostcache_return(NULL);
-  }
-  p->timestamp = now;
+  dns->timestamp = now;
+  dns->inuse++;         /* mark entry as in-use */
+#ifdef MALLOCDEBUG
+  dns->entry_id = entry_id;
+#endif
 
-  /* Save it in our host cache */
-  curl_hash_update(data->hostcache, entry_id, entry_len+1, (const void *) p);
+  /* Remove outdated and unused entries from the hostcache */
+  hostcache_prune(data->hostcache, 
+                  data->set.dns_cache_timeout, 
+                  now);
 
-  _hostcache_return(p->addr);
+  HOSTCACHE_RETURN(dns);
 }
 
 /*
@@ -225,7 +291,7 @@ Curl_addrinfo *Curl_resolv(struct SessionHandle *data,
  */
 void Curl_freeaddrinfo(void *freethis)
 {
-  struct curl_dns_cache_entry *p = (struct curl_dns_cache_entry *) freethis;
+  struct Curl_dns_entry *p = (struct Curl_dns_entry *) freethis;
 
 #ifdef ENABLE_IPV6
   freeaddrinfo(p->addr);
@@ -283,23 +349,37 @@ void curl_freeaddrinfo(struct addrinfo *freethis,
  * memory we need to free after use. That meory *MUST* be freed with
  * Curl_freeaddrinfo(), nothing else.
  */
-Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data,
-                                char *hostname,
-                                int port,
-                                char **bufp)
+static Curl_addrinfo *my_getaddrinfo(struct SessionHandle *data,
+                                     char *hostname,
+                                     int port,
+                                     char **bufp)
 {
   struct addrinfo hints, *res;
   int error;
   char sbuf[NI_MAXSERV];
-
+  int s, pf = PF_UNSPEC;
+
+  /* see if we have an IPv6 stack */
+  s = socket(PF_INET6, SOCK_DGRAM, 0);
+  if (s < 0)
+    /* Some non-IPv6 stacks have been found to make very slow name resolves
+     * when PF_UNSPEC is used, so thus we switch to a mere PF_INET lookup if
+     * the stack seems to be a non-ipv6 one. */
+    pf = PF_INET;
+  else
+    /* This seems to be an IPv6-capable stack, use PF_UNSPEC for the widest
+     * possible checks. And close the socket again.
+     */
+    sclose(s);
+ 
   memset(&hints, 0, sizeof(hints));
-  hints.ai_family = PF_INET;
+  hints.ai_family = pf;
   hints.ai_socktype = SOCK_STREAM;
   hints.ai_flags = AI_CANONNAME;
   snprintf(sbuf, sizeof(sbuf), "%d", port);
   error = getaddrinfo(hostname, sbuf, &hints, &res);
   if (error) {
-    infof(data, "getaddrinfo(3) failed for %s\n", hostname);    
+    infof(data, "getaddrinfo(3) failed for %s:%d\n", hostname, port);    
     return NULL;
   }
   *bufp=(char *)res; /* make it point to the result struct */
@@ -309,22 +389,24 @@ Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data,
 #else /* following code is IPv4-only */
 
 #ifndef HAVE_GETHOSTBYNAME_R
+static void hostcache_fixoffset(struct hostent *h, int offset);
 /**
  * Performs a "deep" copy of a hostent into a buffer (returns a pointer to the
  * copy). Make absolutely sure the destination buffer is big enough!
  *
  * Keith McGuigan 
  * 10/3/2001 */
-static struct hostent* pack_hostent(char* buf, struct hostent* orig)
+static struct hostent* pack_hostent(char** buf, struct hostent* orig)
 {
-  char* bufptr;
+  char *bufptr;
+  char *newbuf;
   struct hostent* copy;
 
   int i;
-  char* str;
+  char *str;
   int len;
 
-  bufptr = buf;
+  bufptr = *buf;
   copy = (struct hostent*)bufptr;
 
   bufptr += sizeof(struct hostent);
@@ -334,10 +416,12 @@ static struct hostent* pack_hostent(char* buf, struct hostent* orig)
   bufptr += len;
 
   /* we align on even 64bit boundaries for safety */
-#define MEMALIGN(x) (((unsigned long)(x)&0xfffffff8)+8)
+#define MEMALIGN(x) ((x)+(8-(((unsigned long)(x))&0x7)))
 
   /* This must be aligned properly to work on many CPU architectures! */
-  copy->h_aliases = (char**)MEMALIGN(bufptr);
+  bufptr = MEMALIGN(bufptr);
+  
+  copy->h_aliases = (char**)bufptr;
 
   /* Figure out how many aliases there are */
   for (i = 0; orig->h_aliases[i] != NULL; ++i);
@@ -359,7 +443,7 @@ static struct hostent* pack_hostent(char* buf, struct hostent* orig)
   copy->h_length = orig->h_length;
     
   /* align it for (at least) 32bit accesses */
-  bufptr = (char *)MEMALIGN(bufptr);
+  bufptr = MEMALIGN(bufptr);
 
   copy->h_addr_list = (char**)bufptr;
 
@@ -380,6 +464,18 @@ static struct hostent* pack_hostent(char* buf, struct hostent* orig)
   }
   copy->h_addr_list[i] = NULL;
 
+  /* now, shrink the allocated buffer to the size we actually need, which
+     most often is only a fraction of the original alloc */
+  newbuf=(char *)realloc(*buf, (int)bufptr-(int)(*buf));
+
+  /* if the alloc moved, we need to adjust things again */
+  if(newbuf != *buf)
+    hostcache_fixoffset((struct hostent*)newbuf, (int)newbuf-(int)*buf);
+
+  /* setup the return */
+  *buf = newbuf;
+  copy = (struct hostent*)newbuf;
+
   return copy;
 }
 #endif
@@ -405,18 +501,34 @@ static char *MakeIP(unsigned long num,char *addr, int addr_len)
   return (addr);
 }
 
-/* The original code to this function was once stolen from the Dancer source
-   code, written by Bjorn Reese, it has since been patched and modified
-   considerably. */
-
 #ifndef INADDR_NONE
 #define INADDR_NONE (in_addr_t) ~0
 #endif
 
-Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data,
-                                char *hostname,
-                                int port,
-                                char **bufp)
+static void hostcache_fixoffset(struct hostent *h, int offset)
+{
+  int i=0;
+  h->h_name=(char *)((long)h->h_name+offset);
+  h->h_aliases=(char **)((long)h->h_aliases+offset);
+  while(h->h_aliases[i]) {
+    h->h_aliases[i]=(char *)((long)h->h_aliases[i]+offset);
+    i++;
+  }
+  h->h_addr_list=(char **)((long)h->h_addr_list+offset);
+  i=0;
+  while(h->h_addr_list[i]) {
+    h->h_addr_list[i]=(char *)((long)h->h_addr_list[i]+offset);
+    i++;
+  }
+}
+
+/* The original code to this function was once stolen from the Dancer source
+   code, written by Bjorn Reese, it has since been patched and modified
+   considerably. */
+static Curl_addrinfo *my_getaddrinfo(struct SessionHandle *data,
+                                     char *hostname,
+                                     int port,
+                                     char **bufp)
 {
   struct hostent *h = NULL;
   in_addr_t in;
@@ -427,51 +539,116 @@ Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data,
    * everything. OSF1 is known to require at least 8872 bytes. The buffer
    * required for storing all possible aliases and IP numbers is according to
    * Stevens' Unix Network Programming 2nd editor, p. 304: 8192 bytes! */
-  int *buf = (int *)malloc(CURL_NAMELOOKUP_SIZE);
-  if(!buf)
-    return NULL; /* major failure */
-  *bufp = (char *)buf;
-
   port=0; /* unused in IPv4 code */
   ret = 0; /* to prevent the compiler warning */
 
   if ( (in=inet_addr(hostname)) != INADDR_NONE ) {
     struct in_addr *addrentry;
-
-    h = (struct hostent*)buf;
-    h->h_addr_list = (char**)(buf + sizeof(*h));
-    addrentry = (struct in_addr*)(h->h_addr_list + 2);
+    struct namebuf {
+        struct hostent hostentry;
+        char *h_addr_list[2];
+        struct in_addr addrentry;
+        char h_name[128];
+    } *buf = (struct namebuf *)malloc(sizeof(struct namebuf));
+    if(!buf)
+      return NULL; /* major failure */
+    *bufp = (char *)buf;
+
+    h = &buf->hostentry;
+    h->h_addr_list = &buf->h_addr_list[0];
+    addrentry = &buf->addrentry;
     addrentry->s_addr = in;
     h->h_addr_list[0] = (char*)addrentry;
     h->h_addr_list[1] = NULL;
     h->h_addrtype = AF_INET;
     h->h_length = sizeof(*addrentry);
-    h->h_name = *(h->h_addr_list) + h->h_length;
-    /* bad one h->h_name = (char*)(h->h_addr_list + h->h_length); */
-    MakeIP(ntohl(in),h->h_name, CURL_NAMELOOKUP_SIZE - (long)(h->h_name) + (long)buf);
+    h->h_name = &buf->h_name[0];
+    MakeIP(ntohl(in), h->h_name, sizeof(buf->h_name));
   }
 #if defined(HAVE_GETHOSTBYNAME_R)
   else {
     int h_errnop;
+    int res=ERANGE;
+    int step_size=200;
+    int *buf = (int *)malloc(CURL_NAMELOOKUP_SIZE);
+    if(!buf)
+      return NULL; /* major failure */
+    *bufp=(char *)buf;
+
      /* Workaround for gethostbyname_r bug in qnx nto. It is also _required_
         for some of these functions. */
     memset(buf, 0, CURL_NAMELOOKUP_SIZE);
 #ifdef HAVE_GETHOSTBYNAME_R_5
     /* Solaris, IRIX and more */
-    if ((h = gethostbyname_r(hostname,
-                             (struct hostent *)buf,
-                             (char *)buf + sizeof(struct hostent),
-                             CURL_NAMELOOKUP_SIZE - sizeof(struct hostent),
-                             &h_errnop)) == NULL )
+    (void)res; /* prevent compiler warning */
+    while(!h) {
+      h = gethostbyname_r(hostname,
+                          (struct hostent *)buf,
+                          (char *)buf + sizeof(struct hostent),
+                          step_size - sizeof(struct hostent),
+                          &h_errnop);
+
+      /* If the buffer is too small, it returns NULL and sets errno to
+         ERANGE. The errno is thread safe if this is compiled with
+         -D_REENTRANT as then the 'errno' variable is a macro defined to
+         get used properly for threads. */
+
+      if(h || (errno != ERANGE))
+        break;
+      
+      step_size+=200;
+    }
+
+#ifdef MALLOCDEBUG
+    infof(data, "gethostbyname_r() uses %d bytes\n", step_size);
+#endif
+
+    if(h) {
+      int offset;
+      h=(struct hostent *)realloc(buf, step_size);
+      offset=(long)h-(long)buf;
+      hostcache_fixoffset(h, offset);
+      buf=(int *)h;
+      *bufp=(char *)buf;
+    }
+    else
 #endif
 #ifdef HAVE_GETHOSTBYNAME_R_6
     /* Linux */
-    if( gethostbyname_r(hostname,
-                        (struct hostent *)buf,
-                        (char *)buf + sizeof(struct hostent),
-                        CURL_NAMELOOKUP_SIZE - sizeof(struct hostent),
-                        &h, /* DIFFERENCE */
-                        &h_errnop))
+    do {
+      res=gethostbyname_r(hostname,
+                          (struct hostent *)buf,
+                          (char *)buf + sizeof(struct hostent),
+                          step_size - sizeof(struct hostent),
+                          &h, /* DIFFERENCE */
+                          &h_errnop);
+      /* Redhat 8, using glibc 2.2.93 changed the behavior. Now all of a
+         sudden this function seems to be setting EAGAIN if the given buffer
+         size is too small. Previous versions are known to return ERANGE for
+         the same. */
+
+      if((ERANGE == res) || (EAGAIN == res)) {
+        step_size+=200;
+        continue;
+      }
+      break;
+    } while(1);
+
+    if(!h) /* failure */
+      res=1;
+    
+#ifdef MALLOCDEBUG
+    infof(data, "gethostbyname_r() uses %d bytes\n", step_size);
+#endif
+    if(!res) {
+      int offset;
+      h=(struct hostent *)realloc(buf, step_size);
+      offset=(long)h-(long)buf;
+      hostcache_fixoffset(h, offset);
+      buf=(int *)h;
+      *bufp=(char *)buf;
+    }
+    else
 #endif
 #ifdef HAVE_GETHOSTBYNAME_R_3
     /* AIX, Digital Unix, HPUX 10, more? */
@@ -484,8 +661,8 @@ Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data,
        * size dilemma. */
 
       ret = gethostbyname_r(hostname,
-                          (struct hostent *)buf,
-                          (struct hostent_data *)(buf + sizeof(struct hostent)));
+                            (struct hostent *)buf,
+                            (struct hostent_data *)((char *)buf + sizeof(struct hostent)));
     else
       ret = -1; /* failure, too smallish buffer size */
     
@@ -504,14 +681,17 @@ Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data,
   else {
     if ((h = gethostbyname(hostname)) == NULL ) {
       infof(data, "gethostbyname(2) failed for %s\n", hostname);
-      free(buf);
       *bufp=NULL;
     }
     else 
+    {
+      char *buf=(char *)malloc(CURL_NAMELOOKUP_SIZE);
       /* we make a copy of the hostent right now, right here, as the
          static one we got a pointer to might get removed when we don't
          want/expect that */
-      h = pack_hostent((char *)buf, h);
+      h = pack_hostent(&buf, h);
+      *bufp=(char *)buf;
+    }
 #endif
   }
   return (h);
diff --git a/Source/CTest/Curl/hostip.h b/Source/CTest/Curl/hostip.h
index 6910071..78a17e2 100644
--- a/Source/CTest/Curl/hostip.h
+++ b/Source/CTest/Curl/hostip.h
@@ -1,28 +1,29 @@
 #ifndef __HOSTIP_H
 #define __HOSTIP_H
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 
+#include "setup.h"
 #include "hash.h"
 
 struct addrinfo;
@@ -35,16 +36,34 @@ curl_hash *Curl_global_host_cache_get(void);
 
 #define Curl_global_host_cache_use(__p) ((__p)->set.global_dns_cache)
 
-Curl_addrinfo *Curl_resolv(struct SessionHandle *data,
-                           char *hostname,
-                           int port,
-                           char **bufp);
+struct Curl_dns_entry {
+  Curl_addrinfo *addr;
+  time_t timestamp;
+  long inuse;      /* use-counter, make very sure you decrease this
+                      when you're done using the address you received */
+#ifdef MALLOCDEBUG
+  char *entry_id;
+#endif
+};
+
+/*
+ * Curl_resolv() returns an entry with the info for the specified host
+ * and port.
+ *
+ * The returned data *MUST* be "unlocked" with Curl_resolv_unlock() after
+ * use, or we'll leak memory!
+ */
+
+struct Curl_dns_entry *Curl_resolv(struct SessionHandle *data,
+                                   char *hostname,
+                                   int port);
+
+/* unlock a previously resolved dns entry */
+#define Curl_resolv_unlock(dns) dns->inuse--
+
+/* for debugging purposes only: */
+void Curl_scan_cache_used(void *user, void *ptr);
 
-/* Get name info */
-Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data,
-                                char *hostname,
-                                int port,
-                                char **bufp);
 /* free name info */
 void Curl_freeaddrinfo(void *freethis);
 
diff --git a/Source/CTest/Curl/http.c b/Source/CTest/Curl/http.c
index 1413618..24794e2 100644
--- a/Source/CTest/Curl/http.c
+++ b/Source/CTest/Curl/http.c
@@ -1,28 +1,29 @@
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 
 #include "setup.h"
 
+#ifndef CURL_DISABLE_HTTP
 /* -- WIN32 approved -- */
 #include <stdio.h>
 #include <string.h>
@@ -133,12 +134,6 @@ CURLcode add_buffer_send(int sockfd, struct connectdata *conn, send_buffer *in,
   char *ptr;
   int size;
 
-  if(conn->data->set.verbose) {
-    fputs("> ", conn->data->set.err);
-    /* this data _may_ contain binary stuff */
-    fwrite(in->buffer, in->size_used, 1, conn->data->set.err);
-  }
-
   /* The looping below is required since we use non-blocking sockets, but due
      to the circumstances we will just loop and try again and again etc */
 
@@ -150,6 +145,10 @@ CURLcode add_buffer_send(int sockfd, struct connectdata *conn, send_buffer *in,
     if(CURLE_OK != res)
       break;
 
+    if(conn->data->set.verbose)
+      /* this data _may_ contain binary stuff */
+      Curl_debug(conn->data, CURLINFO_HEADER_OUT, ptr, amount);
+
     if(amount != size) {
       size -= amount;
       ptr += amount;
@@ -163,7 +162,7 @@ CURLcode add_buffer_send(int sockfd, struct connectdata *conn, send_buffer *in,
     free(in->buffer);
   free(in);
 
-  *bytes_written = amount;
+  *bytes_written += amount;
 
   return res;
 }
@@ -364,11 +363,8 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
                the line isn't really terminated until the LF comes */
 
             /* output debug output if that is requested */
-            if(data->set.verbose) {
-              fputs("< ", data->set.err);
-              fwrite(line_start, perline, 1, data->set.err);
-              /* no need to output LF here, it is part of the data */
-            }
+            if(data->set.verbose)
+              Curl_debug(data, CURLINFO_DATA_IN, line_start, perline);
             
             if('\r' == line_start[0]) {
               /* end of headers */
@@ -392,7 +388,7 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
   } /* while there's buffer left and loop is requested */
 
   if(error)
-    return CURLE_READ_ERROR;
+    return CURLE_RECV_ERROR;
 
   if(200 != httperror) {
     if(407 == httperror)
@@ -400,7 +396,7 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
       failf(data, "Proxy requires authorization!");
     else 
       failf(data, "Received error code %d from proxy", httperror);
-    return CURLE_READ_ERROR;
+    return CURLE_RECV_ERROR;
   }
 
   infof (data, "Proxy replied to CONNECT request\n");
@@ -424,7 +420,7 @@ CURLcode Curl_http_connect(struct connectdata *conn)
    * has occured, can we start talking SSL
    */
 
-  if(data->change.proxy &&
+  if(conn->bits.httpproxy &&
      ((conn->protocol & PROT_HTTPS) || data->set.tunnel_thru_httpproxy)) {
 
     /* either HTTPS over proxy, OR explicitly asked for a tunnel */
@@ -453,23 +449,21 @@ CURLcode Curl_http_connect(struct connectdata *conn)
 CURLcode Curl_http_done(struct connectdata *conn)
 {
   struct SessionHandle *data;
-  long *bytecount = &conn->bytecount;
   struct HTTP *http;
 
   data=conn->data;
   http=conn->proto.http;
 
   if(HTTPREQ_POST_FORM == data->set.httpreq) {
-    *bytecount = http->readbytecount + http->writebytecount;
+    conn->bytecount = http->readbytecount + http->writebytecount;
       
     Curl_formclean(http->sendit); /* Now free that whole lot */
 
     data->set.fread = http->storefread; /* restore */
     data->set.in = http->in; /* restore */
   }
-  else if(HTTPREQ_PUT == data->set.httpreq) {
-    *bytecount = http->readbytecount + http->writebytecount;
-  }
+  else if(HTTPREQ_PUT == data->set.httpreq)
+    conn->bytecount = http->readbytecount + http->writebytecount;
 
   if(0 == (http->readbytecount + conn->headerbytecount)) {
     /* nothing was read from the HTTP server, this can't be right
@@ -491,7 +485,7 @@ CURLcode Curl_http(struct connectdata *conn)
   struct Cookie *co=NULL; /* no cookies from start */
   char *ppath = conn->ppath; /* three previous function arguments */
   char *host = conn->name;
-  long *bytecount = &conn->bytecount;
+  const char *te = ""; /* tranfer-encoding */
 
   if(!conn->proto.http) {
     /* Only allocate this struct if we don't already have it! */
@@ -553,12 +547,20 @@ CURLcode Curl_http(struct connectdata *conn)
     conn->allocptr.cookie = aprintf("Cookie: %s\015\012", data->set.cookie);
   }
 
+  if(conn->bits.upload_chunky) {
+    if(!checkheaders(data, "Transfer-Encoding:")) {
+      te = "Transfer-Encoding: chunked\r\n";
+    }
+    /* else
+       our header was already added, what to do now? */
+  }
+
   if(data->cookies) {
     co = Curl_cookie_getlist(data->cookies,
                              host, ppath,
-                             conn->protocol&PROT_HTTPS?TRUE:FALSE);
+                             (conn->protocol&PROT_HTTPS?TRUE:FALSE));
   }
-  if (data->change.proxy &&
+  if (data->change.proxy && *data->change.proxy &&
       !data->set.tunnel_thru_httpproxy &&
       !(conn->protocol&PROT_HTTPS))  {
     /* The path sent to the proxy is in fact the entire URL */
@@ -567,7 +569,13 @@ CURLcode Curl_http(struct connectdata *conn)
   if(HTTPREQ_POST_FORM == data->set.httpreq) {
     /* we must build the whole darned post sequence first, so that we have
        a size of the whole shebang before we start to send it */
-    http->sendit = Curl_getFormData(data->set.httppost, &http->postsize);
+     result = Curl_getFormData(&http->sendit, data->set.httppost,
+                               &http->postsize);
+     if(CURLE_OK != result) {
+       /* Curl_getFormData() doesn't use failf() */
+       failf(data, "failed creating formpost data");
+       return result;
+     }
   }
 
   if(!checkheaders(data, "Host:")) {
@@ -579,13 +587,22 @@ CURLcode Curl_http(struct connectdata *conn)
     if(conn->allocptr.host)
       free(conn->allocptr.host);
 
+    /* When building Host: headers, we must put the host name within
+       [brackets] if the host name is a plain IPv6-address. RFC2732-style. */
+       
     if(((conn->protocol&PROT_HTTPS) && (conn->remote_port == PORT_HTTPS)) ||
        (!(conn->protocol&PROT_HTTPS) && (conn->remote_port == PORT_HTTP)) )
       /* If (HTTPS on port 443) OR (non-HTTPS on port 80) then don't include
          the port number in the host string */
-      conn->allocptr.host = aprintf("Host: %s\r\n", host);
+      conn->allocptr.host = aprintf("Host: %s%s%s\r\n",
+                                    conn->bits.ipv6_ip?"[":"",
+                                    host,
+                                    conn->bits.ipv6_ip?"]":"");
     else
-      conn->allocptr.host = aprintf("Host: %s:%d\r\n", host,
+      conn->allocptr.host = aprintf("Host: %s%s%s:%d\r\n",
+                                    conn->bits.ipv6_ip?"[":"",
+                                    host,
+                                    conn->bits.ipv6_ip?"]":"",
                                     conn->remote_port);
   }
 
@@ -661,6 +678,9 @@ CURLcode Curl_http(struct connectdata *conn)
      */
     if((data->set.httpreq == HTTPREQ_GET) &&
        !checkheaders(data, "Range:")) {
+      /* if a line like this was already allocated, free the previous one */
+      if(conn->allocptr.rangeline)
+        free(conn->allocptr.rangeline);
       conn->allocptr.rangeline = aprintf("Range: bytes=%s\r\n", conn->range);
     }
     else if((data->set.httpreq != HTTPREQ_GET) &&
@@ -705,7 +725,9 @@ CURLcode Curl_http(struct connectdata *conn)
                 "%s" /* host */
                 "%s" /* pragma */
                 "%s" /* accept */
-                "%s", /* referer */
+                "%s" /* accept-encoding */
+                "%s" /* referer */
+                "%s",/* transfer-encoding */
 
                 data->set.customrequest?data->set.customrequest:
                 (data->set.no_body?"HEAD":
@@ -725,7 +747,10 @@ CURLcode Curl_http(struct connectdata *conn)
                 (conn->allocptr.host?conn->allocptr.host:""), /* Host: host */
                 http->p_pragma?http->p_pragma:"",
                 http->p_accept?http->p_accept:"",
-                (data->change.referer && conn->allocptr.ref)?conn->allocptr.ref:"" /* Referer: <data> <CRLF> */
+                (data->set.encoding && *data->set.encoding && conn->allocptr.accept_encoding)?
+                conn->allocptr.accept_encoding:"", /* 08/28/02 jhrg */
+                (data->change.referer && conn->allocptr.ref)?conn->allocptr.ref:"" /* Referer: <data> <CRLF> */,
+                te
                 );
 
     if(co) {
@@ -780,16 +805,16 @@ CURLcode Curl_http(struct connectdata *conn)
       strcpy(buf, "no strftime() support");
 #endif
       switch(data->set.timecondition) {
-      case TIMECOND_IFMODSINCE:
+      case CURL_TIMECOND_IFMODSINCE:
       default:
         add_bufferf(req_buffer,
                     "If-Modified-Since: %s\r\n", buf);
         break;
-      case TIMECOND_IFUNMODSINCE:
+      case CURL_TIMECOND_IFUNMODSINCE:
         add_bufferf(req_buffer,
                     "If-Unmodified-Since: %s\r\n", buf);
         break;
-      case TIMECOND_LASTMOD:
+      case CURL_TIMECOND_LASTMOD:
         add_bufferf(req_buffer,
                     "Last-Modified: %s\r\n", buf);
         break;
@@ -814,7 +839,9 @@ CURLcode Curl_http(struct connectdata *conn)
       headers = headers->next;
     }
 
-    if(HTTPREQ_POST_FORM == data->set.httpreq) {
+    switch(data->set.httpreq) {
+
+    case HTTPREQ_POST_FORM:
       if(Curl_FormInit(&http->form, http->sendit)) {
         failf(data, "Internal HTTP POST error!");
         return CURLE_HTTP_POST_ERROR;
@@ -883,9 +910,9 @@ CURLcode Curl_http(struct connectdata *conn)
         Curl_formclean(http->sendit); /* free that whole lot */
         return result;
       }
-    }
-    else if(HTTPREQ_PUT == data->set.httpreq) {
-      /* Let's PUT the data to the server! */
+      break;
+
+    case HTTPREQ_PUT: /* Let's PUT the data to the server! */
 
       if(data->set.infilesize>0) {
         add_bufferf(req_buffer,
@@ -911,51 +938,53 @@ CURLcode Curl_http(struct connectdata *conn)
                                &http->writebytecount);
       if(result)
         return result;
-      
-    }
-    else {
-      if(HTTPREQ_POST == data->set.httpreq) {
-        /* this is the simple POST, using x-www-form-urlencoded style */
-
-        if(!data->set.postfields) {
-          /*
-           * This is an attempt to do a POST without having anything to
-           * actually send. Let's make a NULL pointer equal "" here. Good/bad
-           * ?
-           */
-          data->set.postfields = (char *)"";
-          data->set.postfieldsize = 0; /* it might been set to something illegal,
-                                      anything > 0 would be! */
-        }
+      break;
 
-        if(!checkheaders(data, "Content-Length:"))
-          /* we allow replacing this header, although it isn't very wise to
-             actually set your own */
-          add_bufferf(req_buffer,
-                      "Content-Length: %d\r\n",
-                      (data->set.postfieldsize?data->set.postfieldsize:
-                       strlen(data->set.postfields)) );
+    case HTTPREQ_POST:
+      /* this is the simple POST, using x-www-form-urlencoded style */
 
-        if(!checkheaders(data, "Content-Type:"))
-          add_bufferf(req_buffer,
-                      "Content-Type: application/x-www-form-urlencoded\r\n");
+      if(!checkheaders(data, "Content-Length:"))
+        /* we allow replacing this header, although it isn't very wise to
+           actually set your own */
+        add_bufferf(req_buffer,
+                    "Content-Length: %d\r\n",
+                    data->set.postfieldsize?
+                    data->set.postfieldsize:
+                    (data->set.postfields?strlen(data->set.postfields):0) );
 
-        /* and here comes the actual data */
-        if(data->set.postfieldsize) {
-          add_buffer(req_buffer, "\r\n", 2);
-          add_buffer(req_buffer, data->set.postfields,
-                     data->set.postfieldsize);
-        }
-        else {
-          add_bufferf(req_buffer,
-                      "\r\n"
-                      "%s",
-                      data->set.postfields );
-        }
+      if(!checkheaders(data, "Content-Type:"))
+        add_bufferf(req_buffer,
+                    "Content-Type: application/x-www-form-urlencoded\r\n");
+
+      add_buffer(req_buffer, "\r\n", 2);
+
+      /* and here comes the actual data */
+      if(data->set.postfieldsize && data->set.postfields) {
+        add_buffer(req_buffer, data->set.postfields,
+                   data->set.postfieldsize);
       }
+      else if(data->set.postfields)
+        add_bufferf(req_buffer,
+                    "%s",
+                    data->set.postfields );
+
+      /* issue the request */
+      result = add_buffer_send(conn->firstsocket, conn, req_buffer,
+                               &data->info.request_size);
+
+      if(result)
+        failf(data, "Failed sending HTTP POST request");
       else
-        add_buffer(req_buffer, "\r\n", 2);
+        result =
+          Curl_Transfer(conn, conn->firstsocket, -1, TRUE,
+                        &http->readbytecount,
+                        data->set.postfields?-1:conn->firstsocket,
+                        data->set.postfields?NULL:&http->writebytecount);
+      break;
 
+    default:
+      add_buffer(req_buffer, "\r\n", 2);
+      
       /* issue the request */
       result = add_buffer_send(conn->firstsocket, conn, req_buffer,
                                &data->info.request_size);
@@ -964,7 +993,8 @@ CURLcode Curl_http(struct connectdata *conn)
         failf(data, "Failed sending HTTP request");
       else
         /* HTTP GET/HEAD download: */
-        result = Curl_Transfer(conn, conn->firstsocket, -1, TRUE, bytecount,
+        result = Curl_Transfer(conn, conn->firstsocket, -1, TRUE,
+                               &http->readbytecount,
                                -1, NULL); /* nothing to upload */
     }
     if(result)
@@ -983,3 +1013,4 @@ CURLcode Curl_http(struct connectdata *conn)
  * vim600: fdm=marker
  * vim: et sw=2 ts=2 sts=2 tw=78
  */
+#endif
diff --git a/Source/CTest/Curl/http.h b/Source/CTest/Curl/http.h
index abd96ba..d78322c 100644
--- a/Source/CTest/Curl/http.h
+++ b/Source/CTest/Curl/http.h
@@ -1,29 +1,29 @@
 #ifndef __HTTP_H
 #define __HTTP_H
 
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
-
+ ***************************************************************************/
+#ifndef CURL_DISABLE_HTTP
 /* ftp can use this as well */
 CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
                                      int tunnelsocket,
@@ -38,5 +38,5 @@ CURLcode Curl_http_connect(struct connectdata *conn);
 void Curl_httpchunk_init(struct connectdata *conn);
 CHUNKcode Curl_httpchunk_read(struct connectdata *conn, char *datap,
                               ssize_t length, ssize_t *wrote);
-
+#endif
 #endif
diff --git a/Source/CTest/Curl/http_chunks.c b/Source/CTest/Curl/http_chunks.c
index 1754079..6d2a640 100644
--- a/Source/CTest/Curl/http_chunks.c
+++ b/Source/CTest/Curl/http_chunks.c
@@ -1,27 +1,28 @@
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 #include "setup.h"
 
+#ifndef CURL_DISABLE_HTTP
 /* -- WIN32 approved -- */
 #include <stdio.h>
 #include <string.h>
@@ -32,6 +33,8 @@
 #include "urldata.h" /* it includes http_chunks.h */
 #include "sendf.h"   /* for the client write stuff */
 
+#include "content_encoding.h"   /* 08/29/02 jhrg */
+
 #define _MPRINTF_REPLACE /* use our functions only */
 #include <curl/mprintf.h>
 
@@ -171,7 +174,32 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
       piece = (ch->datasize >= length)?length:ch->datasize;
 
       /* Write the data portion available */
-      result = Curl_client_write(conn->data, CLIENTWRITE_BODY, datap, piece);
+      /* Added content-encoding here; untested but almost identical to the
+         tested code in transfer.c. 08/29/02 jhrg */
+#ifdef HAVE_LIBZ
+      switch (conn->keep.content_encoding) {
+        case IDENTITY:
+#endif
+          result = Curl_client_write(conn->data, CLIENTWRITE_BODY, datap,
+                                     piece);
+#ifdef HAVE_LIBZ
+          break;
+
+        case DEFLATE: 
+          result = Curl_unencode_deflate_write(conn->data, &conn->keep, piece);
+          break;
+
+        case GZIP:
+        case COMPRESS:
+        default:
+          failf (conn->data,
+                 "Unrecognized content encoding type. "
+                 "libcurl understands `identity' and `deflate' "
+                 "content encodings.");
+          return CHUNKE_BAD_ENCODING;
+      }
+#endif
+
       if(result)
         return CHUNKE_WRITE_ERROR;
       *wrote += piece;
@@ -228,3 +256,4 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
  * vim600: fdm=marker
  * vim: et sw=2 ts=2 sts=2 tw=78
  */
+#endif /* CURL_DISABLE_HTTP */
diff --git a/Source/CTest/Curl/http_chunks.h b/Source/CTest/Curl/http_chunks.h
index c3e54a3..1b15d6c 100644
--- a/Source/CTest/Curl/http_chunks.h
+++ b/Source/CTest/Curl/http_chunks.h
@@ -1,27 +1,27 @@
 #ifndef __HTTP_CHUNKS_H
 #define __HTTP_CHUNKS_H
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 /*
  * The longest possible hexadecimal number we support in a chunked transfer.
  * Weird enough, RFC2616 doesn't set a maximum size! Since we use strtoul()
@@ -73,6 +73,7 @@ typedef enum {
   CHUNKE_BAD_CHUNK,
   CHUNKE_WRITE_ERROR,
   CHUNKE_STATE_ERROR,
+  CHUNKE_BAD_ENCODING,
   CHUNKE_LAST
 } CHUNKcode;
 
diff --git a/Source/CTest/Curl/if2ip.c b/Source/CTest/Curl/if2ip.c
index 0a63730..5f958d3 100644
--- a/Source/CTest/Curl/if2ip.c
+++ b/Source/CTest/Curl/if2ip.c
@@ -1,25 +1,25 @@
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 
 #include "setup.h"
 
diff --git a/Source/CTest/Curl/if2ip.h b/Source/CTest/Curl/if2ip.h
index 2fbb471..2be0ea5 100644
--- a/Source/CTest/Curl/if2ip.h
+++ b/Source/CTest/Curl/if2ip.h
@@ -1,27 +1,27 @@
 #ifndef __IF2IP_H
 #define __IF2IP_H
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 #include "setup.h"
 
 #if ! defined(WIN32) && ! defined(__BEOS__) && !defined(__CYGWIN32__)
diff --git a/Source/CTest/Curl/krb4.c b/Source/CTest/Curl/krb4.c
index a182bea..ab38d30 100644
--- a/Source/CTest/Curl/krb4.c
+++ b/Source/CTest/Curl/krb4.c
@@ -40,6 +40,7 @@
 
 #include "setup.h"
 
+#ifndef CURL_DISABLE_FTP
 #ifdef KRB4
 
 #include "security.h"
@@ -197,7 +198,7 @@ krb4_auth(void *app_data, struct connectdata *conn)
   int checksum;
   u_int32_t cs;
   struct krb4_data *d = app_data;
-  char *host = conn->hostaddr->h_name;
+  char *host = conn->hostname;
   ssize_t nread;
   int l = sizeof(conn->local_addr);
   struct SessionHandle *data = conn->data;
@@ -362,7 +363,7 @@ void Curl_krb_kauth(struct connectdata *conn)
   if (strcmp ((char*)tktcopy.dat + 8,
               KRB_TICKET_GRANTING_TICKET) != 0) {
     afs_string_to_key (passwd,
-                       krb_realmofhost(conn->hostaddr->h_name),
+                       krb_realmofhost(conn->hostname),
                        &key);
     des_key_sched (&key, schedule);
     des_pcbc_encrypt((des_cblock*)tkt.dat, (des_cblock*)tktcopy.dat,
@@ -391,6 +392,7 @@ void Curl_krb_kauth(struct connectdata *conn)
 }
 
 #endif /* KRB4 */
+#endif /* CURL_DISABLE_FTP */
 
 /*
  * local variables:
diff --git a/Source/CTest/Curl/krb4.h b/Source/CTest/Curl/krb4.h
index 6880486..8057058 100644
--- a/Source/CTest/Curl/krb4.h
+++ b/Source/CTest/Curl/krb4.h
@@ -1,27 +1,27 @@
 #ifndef __KRB4_H
 #define __KRB4_H
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 void Curl_krb_kauth(struct connectdata *conn);
 
 #endif
diff --git a/Source/CTest/Curl/ldap.c b/Source/CTest/Curl/ldap.c
index 9080669..a1ef6fe 100644
--- a/Source/CTest/Curl/ldap.c
+++ b/Source/CTest/Curl/ldap.c
@@ -1,28 +1,29 @@
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 
 #include "setup.h"
 
+#ifndef CURL_DISABLE_LDAP
 /* -- WIN32 approved -- */
 #include <stdio.h>
 #include <string.h>
@@ -147,7 +148,7 @@ CURLcode Curl_ldap(struct connectdata *conn)
   int ldaptext;
   struct SessionHandle *data=conn->data;
   
-  infof(data, "LDAP: %s %s\n", data->change.url);
+  infof(data, "LDAP: %s\n", data->change.url);
 
   DynaOpen();
   if (libldap == NULL) {
@@ -229,3 +230,4 @@ CURLcode Curl_ldap(struct connectdata *conn)
  * vim600: fdm=marker
  * vim: et sw=2 ts=2 sts=2 tw=78
  */
+#endif
diff --git a/Source/CTest/Curl/ldap.h b/Source/CTest/Curl/ldap.h
index c9ab7c8..2be32a8 100644
--- a/Source/CTest/Curl/ldap.h
+++ b/Source/CTest/Curl/ldap.h
@@ -1,29 +1,30 @@
 #ifndef __LDAP_H
 #define __LDAP_H
 
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
+#ifndef CURL_DISABLE_LDAP
 CURLcode Curl_ldap(struct connectdata *conn);
 CURLcode Curl_ldap_done(struct connectdata *conn);
-
+#endif
 #endif /* __LDAP_H */
diff --git a/Source/CTest/Curl/llist.c b/Source/CTest/Curl/llist.c
index 0d969ae..a9e65a8 100644
--- a/Source/CTest/Curl/llist.c
+++ b/Source/CTest/Curl/llist.c
@@ -1,25 +1,25 @@
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2002, Daniel Stenberg, <daniel@haxx.se>, et al
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 
 #include "setup.h"
 
@@ -33,7 +33,7 @@
 #include "memdebug.h"
 #endif
 void 
-curl_llist_init(curl_llist *l, curl_llist_dtor dtor)
+Curl_llist_init(curl_llist *l, curl_llist_dtor dtor)
 {
   l->size = 0;
   l->dtor = dtor;
@@ -42,7 +42,7 @@ curl_llist_init(curl_llist *l, curl_llist_dtor dtor)
 }
 
 curl_llist *
-curl_llist_alloc(curl_llist_dtor dtor)
+Curl_llist_alloc(curl_llist_dtor dtor)
 {
   curl_llist *list;
 
@@ -50,13 +50,13 @@ curl_llist_alloc(curl_llist_dtor dtor)
   if(NULL == list)
     return NULL;
 
-  curl_llist_init(list, dtor);
+  Curl_llist_init(list, dtor);
 
   return list;
 }
 
 int
-curl_llist_insert_next(curl_llist *list, curl_llist_element *e, const void *p)
+Curl_llist_insert_next(curl_llist *list, curl_llist_element *e, const void *p)
 {
   curl_llist_element  *ne;
 
@@ -84,7 +84,7 @@ curl_llist_insert_next(curl_llist *list, curl_llist_element *e, const void *p)
 }
 
 int 
-curl_llist_insert_prev(curl_llist *list, curl_llist_element *e, const void *p)
+Curl_llist_insert_prev(curl_llist *list, curl_llist_element *e, const void *p)
 {
   curl_llist_element *ne;
 
@@ -111,7 +111,7 @@ curl_llist_insert_prev(curl_llist *list, curl_llist_element *e, const void *p)
 }
 
 int 
-curl_llist_remove(curl_llist *list, curl_llist_element *e, void *user)
+Curl_llist_remove(curl_llist *list, curl_llist_element *e, void *user)
 {
   if (e == NULL || list->size == 0)
     return 1;
@@ -139,28 +139,28 @@ curl_llist_remove(curl_llist *list, curl_llist_element *e, void *user)
 }
 
 int 
-curl_llist_remove_next(curl_llist *list, curl_llist_element *e, void *user)
+Curl_llist_remove_next(curl_llist *list, curl_llist_element *e, void *user)
 {
-  return curl_llist_remove(list, e->next, user);
+  return Curl_llist_remove(list, e->next, user);
 }
 
 int 
-curl_llist_remove_prev(curl_llist *list, curl_llist_element *e, void *user)
+Curl_llist_remove_prev(curl_llist *list, curl_llist_element *e, void *user)
 {
-  return curl_llist_remove(list, e->prev, user);
+  return Curl_llist_remove(list, e->prev, user);
 }
 
 size_t 
-curl_llist_count(curl_llist *list)
+Curl_llist_count(curl_llist *list)
 {
   return list->size;
 }
 
 void 
-curl_llist_destroy(curl_llist *list, void *user)
+Curl_llist_destroy(curl_llist *list, void *user)
 {
   while (list->size > 0) {
-    curl_llist_remove(list, CURL_LLIST_TAIL(list), user);
+    Curl_llist_remove(list, CURL_LLIST_TAIL(list), user);
   }
 
   free(list);
diff --git a/Source/CTest/Curl/llist.h b/Source/CTest/Curl/llist.h
index f598a1c..fa38e74 100644
--- a/Source/CTest/Curl/llist.h
+++ b/Source/CTest/Curl/llist.h
@@ -1,27 +1,27 @@
 #ifndef __LLIST_H
 #define __LLIST_H
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 
 #include "setup.h"
 #include <stddef.h>
@@ -44,14 +44,14 @@ typedef struct _curl_llist {
   size_t size;
 } curl_llist;
 
-void curl_llist_init(curl_llist *, curl_llist_dtor);
-curl_llist *curl_llist_alloc(curl_llist_dtor);
-int curl_llist_insert_next(curl_llist *, curl_llist_element *, const void *);
-int curl_llist_insert_prev(curl_llist *, curl_llist_element *, const void *);
-int curl_llist_remove(curl_llist *, curl_llist_element *, void *);
-int curl_llist_remove_next(curl_llist *, curl_llist_element *, void *);
-size_t curl_llist_count(curl_llist *);
-void curl_llist_destroy(curl_llist *, void *);
+void Curl_llist_init(curl_llist *, curl_llist_dtor);
+curl_llist *Curl_llist_alloc(curl_llist_dtor);
+int Curl_llist_insert_next(curl_llist *, curl_llist_element *, const void *);
+int Curl_llist_insert_prev(curl_llist *, curl_llist_element *, const void *);
+int Curl_llist_remove(curl_llist *, curl_llist_element *, void *);
+int Curl_llist_remove_next(curl_llist *, curl_llist_element *, void *);
+size_t Curl_llist_count(curl_llist *);
+void Curl_llist_destroy(curl_llist *, void *);
 
 #define CURL_LLIST_HEAD(__l) ((__l)->head)
 #define CURL_LLIST_TAIL(__l) ((__l)->tail)
diff --git a/Source/CTest/Curl/memdebug.c b/Source/CTest/Curl/memdebug.c
index 9cb22d5..996aebb 100644
--- a/Source/CTest/Curl/memdebug.c
+++ b/Source/CTest/Curl/memdebug.c
@@ -1,26 +1,26 @@
 #ifdef MALLOCDEBUG
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 
 #include "setup.h"
 
@@ -49,7 +49,9 @@
 
 struct memdebug {
   int size;
-  char mem[1];
+  double mem[1];
+  /* I'm hoping this is the thing with the strictest alignment
+   * requirements.  That also means we waste some space :-( */
 };
 
 /*
@@ -200,7 +202,15 @@ FILE *curl_fopen(const char *file, const char *mode,
 
 int curl_fclose(FILE *file, int line, const char *source)
 {
-  int res=(fclose)(file);
+  int res;
+
+  if(NULL == file) {
+    fprintf(stderr, "ILLEGAL flose() on NULL at %s:%d\n",
+            source, line);
+    exit(2);
+  }
+
+  res=(fclose)(file);
   if(logfile)
     fprintf(logfile, "FILE %s:%d fclose(%p)\n",
             source, line, file);
diff --git a/Source/CTest/Curl/memdebug.h b/Source/CTest/Curl/memdebug.h
index 3c5c090..3fa87ac 100644
--- a/Source/CTest/Curl/memdebug.h
+++ b/Source/CTest/Curl/memdebug.h
@@ -1,4 +1,26 @@
 #ifdef MALLOCDEBUG
+/***************************************************************************
+ *                                  _   _ ____  _     
+ *  Project                     ___| | | |  _ \| |    
+ *                             / __| | | | |_) | |    
+ *                            | (__| |_| |  _ <| |___ 
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2002, 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$
+ ***************************************************************************/
 
 #include "setup.h"
 
@@ -35,6 +57,7 @@ FILE *curl_fopen(const char *file, const char *mode, int line,
 int curl_fclose(FILE *file, int line, const char *source);
 
 /* Set this symbol on the command-line, recompile all lib-sources */
+#undef strdup
 #define strdup(ptr) curl_dostrdup(ptr, __LINE__, __FILE__)
 #define malloc(size) curl_domalloc(size, __LINE__, __FILE__)
 #define realloc(ptr,size) curl_dorealloc(ptr, size, __LINE__, __FILE__)
diff --git a/Source/CTest/Curl/mprintf.c b/Source/CTest/Curl/mprintf.c
index b039d8d..4d3630a 100644
--- a/Source/CTest/Curl/mprintf.c
+++ b/Source/CTest/Curl/mprintf.c
@@ -1028,7 +1028,6 @@ static int alloc_addbyter(int output, FILE *data)
   infop->len++;
 
   return output; /* fputc() returns like this on success */
-
 }
 
 char *curl_maprintf(const char *format, ...)
@@ -1044,12 +1043,17 @@ char *curl_maprintf(const char *format, ...)
   va_start(ap_save, format);
   retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save);
   va_end(ap_save);
-  if(info.len) {
+  if(-1 == retcode) {
+    if(info.alloc)
+      free(info.buffer);
+    return NULL;
+  }
+  if(info.alloc) {
     info.buffer[info.len] = 0; /* we terminate this with a zero byte */
     return info.buffer;
   }
   else
-    return NULL;
+    return strdup("");
 }
 
 char *curl_mvaprintf(const char *format, va_list ap_save)
@@ -1062,13 +1066,18 @@ char *curl_mvaprintf(const char *format, va_list ap_save)
   info.alloc = 0;
 
   retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save);
-  info.buffer[info.len] = 0; /* we terminate this with a zero byte */
-  if(info.len) {
+  if(-1 == retcode) {
+    if(info.alloc)
+      free(info.buffer);
+    return NULL;
+  }
+
+  if(info.alloc) {
     info.buffer[info.len] = 0; /* we terminate this with a zero byte */
     return info.buffer;
   }
   else
-    return NULL;
+    return strdup("");
 }
 
 static int storebuffer(int output, FILE *data)
diff --git a/Source/CTest/Curl/multi.c b/Source/CTest/Curl/multi.c
index bfd3949..f901f3a 100644
--- a/Source/CTest/Curl/multi.c
+++ b/Source/CTest/Curl/multi.c
@@ -1,36 +1,40 @@
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 
 #include "setup.h"
 #include <stdlib.h>
 #include <string.h>
 #include <curl/curl.h>
 
-#include "multi.h" /* will become <curl/multi.h> soon */
-
 #include "urldata.h"
 #include "transfer.h"
 #include "url.h"
+#include "connect.h"
+
+/* The last #include file should be: */
+#ifdef MALLOCDEBUG
+#include "memdebug.h"
+#endif
 
 struct Curl_message {
   /* the 'CURLMsg' is the part that is visible to the external user */
@@ -40,11 +44,13 @@ struct Curl_message {
 
 typedef enum {
   CURLM_STATE_INIT,
-  CURLM_STATE_CONNECT,
-  CURLM_STATE_DO,
-  CURLM_STATE_PERFORM,
-  CURLM_STATE_DONE,
-  CURLM_STATE_COMPLETED,
+  CURLM_STATE_CONNECT,     /* connect has been sent off */
+  CURLM_STATE_WAITCONNECT, /* we're awaiting the connect to finalize */
+  CURLM_STATE_DO,          /* send off the request (part 1) */
+  CURLM_STATE_DO_MORE,     /* send off the request (part 2) */
+  CURLM_STATE_PERFORM,     /* transfer data */
+  CURLM_STATE_DONE,        /* post data transfer operation */
+  CURLM_STATE_COMPLETED,   /* operation complete */
 
   CURLM_STATE_LAST /* not a true state, never use this */
 } CURLMstate;
@@ -59,6 +65,13 @@ struct Curl_one_easy {
 
   CURLMstate state;  /* the handle's state */
   CURLcode result;   /* previous result */
+
+  struct Curl_message *msg; /* A pointer to one single posted message.
+                               Cleanup should be done on this pointer NOT on
+                               the linked list in Curl_multi.  This message
+                               will be deleted when this handle is removed
+                               from the multi-handle */
+  int msg_num; /* number of messages left in 'msg' to return */
 };
 
 
@@ -78,10 +91,8 @@ struct Curl_multi {
   /* This is the amount of entries in the linked list above. */
   int num_easy;
 
-  /* this is a linked list of posted messages */
-  struct Curl_message *msgs;
-  /* amount of messages in the queue */
-  int num_msgs;
+  int num_msgs; /* total amount of messages in the easy handles */
+
   /* Hostname cache */
   curl_hash *hostcache;
 };
@@ -171,6 +182,9 @@ CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
     /* If the 'state' is not INIT or COMPLETED, we might need to do something
        nice to put the easy_handle in a good known state when this returns. */
 
+    /* clear out the usage of the shared DNS cache */
+    easy->easy_handle->hostcache = NULL;
+    
     /* make the previous node point to our next */
     if(easy->prev)
       easy->prev->next = easy->next;
@@ -180,6 +194,8 @@ CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
     
     /* NOTE NOTE NOTE
        We do not touch the easy handle here! */
+    if (easy->msg)
+      free(easy->msg);
     free(easy);
 
     multi->num_easy--; /* one less to care about now */
@@ -211,6 +227,32 @@ CURLMcode curl_multi_fdset(CURLM *multi_handle,
     switch(easy->state) {
     default:
       break;
+    case CURLM_STATE_WAITCONNECT:
+    case CURLM_STATE_DO_MORE:
+      {
+        /* when we're waiting for a connect, we wait for the socket to
+           become writable */
+        struct connectdata *conn = easy->easy_conn;
+        int sockfd;
+
+        if(CURLM_STATE_WAITCONNECT == easy->state) {
+          sockfd = conn->firstsocket;
+          FD_SET(sockfd, write_fd_set);
+        }
+        else {
+          /* When in DO_MORE state, we could be either waiting for us
+             to connect to a remote site, or we could wait for that site
+             to connect to us. It makes a difference in the way: if we
+             connect to the site we wait for the socket to become writable, if 
+             the site connects to us we wait for it to become readable */
+          sockfd = conn->secondarysocket;
+          FD_SET(sockfd, write_fd_set);
+        }
+
+        if(sockfd > *max_fd)
+          *max_fd = sockfd;
+      }
+      break;
     case CURLM_STATE_PERFORM:
       /* This should have a set of file descriptors for us to set.  */
       /* after the transfer is done, go DONE */
@@ -237,6 +279,8 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
   struct Curl_one_easy *easy;
   bool done;
   CURLMcode result=CURLM_OK;
+  struct Curl_message *msg = NULL;
+  bool connected;
 
   *running_handles = 0; /* bump this once for every living handle */
 
@@ -245,14 +289,23 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
 
   easy=multi->easy.next;
   while(easy) {
+
+#ifdef MALLOCDEBUG
+    fprintf(stderr, "HANDLE %p: State: %x\n",
+            (char *)easy, easy->state);
+#endif
+
     switch(easy->state) {
     case CURLM_STATE_INIT:
       /* init this transfer. */
       easy->result=Curl_pretransfer(easy->easy_handle);
+
       if(CURLE_OK == easy->result) {
         /* after init, go CONNECT */
         easy->state = CURLM_STATE_CONNECT;
         result = CURLM_CALL_MULTI_PERFORM; 
+        
+        easy->easy_handle->state.used_interface = Curl_if_multi;
       }
       break;
     case CURLM_STATE_CONNECT:
@@ -261,7 +314,7 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
       }
       else {
         if (multi->hostcache == NULL) {
-          multi->hostcache = curl_hash_alloc(7, Curl_freeaddrinfo);
+          multi->hostcache = Curl_hash_alloc(7, Curl_freeaddrinfo);
         }
 
         easy->easy_handle->hostcache = multi->hostcache;
@@ -270,43 +323,133 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
       /* Connect. We get a connection identifier filled in. */
       easy->result = Curl_connect(easy->easy_handle, &easy->easy_conn);
 
-      /* after connect, go DO */
+      /* after the connect has been sent off, go WAITCONNECT */
       if(CURLE_OK == easy->result) {
-        easy->state = CURLM_STATE_DO;
+        easy->state = CURLM_STATE_WAITCONNECT;
         result = CURLM_CALL_MULTI_PERFORM; 
       }
       break;
+
+    case CURLM_STATE_WAITCONNECT:
+      {
+        bool connected;
+        easy->result = Curl_is_connected(easy->easy_conn,
+                                         easy->easy_conn->firstsocket,
+                                         &connected);
+        if(connected)
+          easy->result = Curl_protocol_connect(easy->easy_conn, NULL);
+
+        if(CURLE_OK != easy->result) {
+          /* failure detected */
+          Curl_disconnect(easy->easy_conn); /* close the connection */
+          easy->easy_conn = NULL;           /* no more connection */
+          break;
+        }
+
+        if(connected) {
+          /* after the connect has completed, go DO */
+          easy->state = CURLM_STATE_DO;
+          result = CURLM_CALL_MULTI_PERFORM; 
+        }
+      }
+      break;
+
     case CURLM_STATE_DO:
       /* Do the fetch or put request */
       easy->result = Curl_do(&easy->easy_conn);
-      /* after do, go PERFORM */
       if(CURLE_OK == easy->result) {
-        if(CURLE_OK == Curl_readwrite_init(easy->easy_conn)) {
+
+        /* after do, go PERFORM... or DO_MORE */
+        if(easy->easy_conn->bits.do_more) {
+          /* we're supposed to do more, but we need to sit down, relax
+             and wait a little while first */
+          easy->state = CURLM_STATE_DO_MORE;
+          result = CURLM_OK;
+        }
+        else {
+          /* we're done with the DO, now PERFORM */
+          easy->result = Curl_readwrite_init(easy->easy_conn);
+          if(CURLE_OK == easy->result) {
+            easy->state = CURLM_STATE_PERFORM;
+            result = CURLM_CALL_MULTI_PERFORM; 
+          }
+        }
+      }
+      break;
+
+    case CURLM_STATE_DO_MORE:
+      /*
+       * First, check if we really are ready to do more.
+       */
+      easy->result = Curl_is_connected(easy->easy_conn,
+                                       easy->easy_conn->secondarysocket,
+                                       &connected);
+      if(connected) {
+        /*
+         * When we are connected, DO MORE and then go PERFORM
+         */
+        easy->result = Curl_do_more(easy->easy_conn);
+
+        if(CURLE_OK == easy->result)
+          easy->result = Curl_readwrite_init(easy->easy_conn);
+
+        if(CURLE_OK == easy->result) {
           easy->state = CURLM_STATE_PERFORM;
           result = CURLM_CALL_MULTI_PERFORM; 
         }
       }
       break;
+
     case CURLM_STATE_PERFORM:
       /* read/write data if it is ready to do so */
       easy->result = Curl_readwrite(easy->easy_conn, &done);
-      /* hm, when we follow redirects, we may need to go back to the CONNECT
-         state */
+
+      if(easy->result)  {
+        /* The transfer phase returned error, we mark the connection to get
+         * closed to prevent being re-used. This is becasue we can't
+         * possibly know if the connection is in a good shape or not now. */
+        easy->easy_conn->bits.close = TRUE;
+
+        if(-1 !=easy->easy_conn->secondarysocket) {
+          /* if we failed anywhere, we must clean up the secondary socket if
+             it was used */
+          sclose(easy->easy_conn->secondarysocket);
+          easy->easy_conn->secondarysocket=-1;
+        }
+        Curl_posttransfer(easy->easy_handle);
+        Curl_done(easy->easy_conn);
+      }
+
       /* after the transfer is done, go DONE */
-      if(TRUE == done) {
+      else if(TRUE == done) {
+
         /* call this even if the readwrite function returned error */
-        easy->result = Curl_posttransfer(easy->easy_handle);
-        easy->state = CURLM_STATE_DONE;
-        result = CURLM_CALL_MULTI_PERFORM; 
+        Curl_posttransfer(easy->easy_handle);
+
+        /* When we follow redirects, must to go back to the CONNECT state */
+        if(easy->easy_conn->newurl) {
+          easy->result = Curl_follow(easy->easy_handle,
+                                     strdup(easy->easy_conn->newurl));
+          if(CURLE_OK == easy->result) {
+            easy->state = CURLM_STATE_CONNECT;
+            result = CURLM_CALL_MULTI_PERFORM;
+          }
+        }
+        else {
+          easy->state = CURLM_STATE_DONE;
+          result = CURLM_CALL_MULTI_PERFORM; 
+        }
       }
       break;
     case CURLM_STATE_DONE:
       /* post-transfer command */
       easy->result = Curl_done(easy->easy_conn);
-      /* after we have DONE what we're supposed to do, go COMPLETED */
-      if(CURLE_OK == easy->result)
-        easy->state = CURLM_STATE_COMPLETED;
+
+      /* after we have DONE what we're supposed to do, go COMPLETED, and
+         it doesn't matter what the Curl_done() returned! */
+      easy->state = CURLM_STATE_COMPLETED;
       break;
+
     case CURLM_STATE_COMPLETED:
       /* this is a completed transfer, it is likely to still be connected */
 
@@ -317,30 +460,66 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
       return CURLM_INTERNAL_ERROR;
     }
 
-    if((CURLM_STATE_COMPLETED != easy->state) &&
-       (CURLE_OK != easy->result)) {
-      /*
-       * If an error was returned, and we aren't in completed now,
-       * then we go to completed and consider this transfer aborted.
-       */
-      easy->state = CURLM_STATE_COMPLETED;
+    if(CURLM_STATE_COMPLETED != easy->state) {
+      if(CURLE_OK != easy->result)
+        /*
+         * If an error was returned, and we aren't in completed state now,
+         * then we go to completed and consider this transfer aborted.  */
+        easy->state = CURLM_STATE_COMPLETED;
+      else
+        /* this one still lives! */
+        (*running_handles)++;
+    }
+
+    if ((CURLM_STATE_COMPLETED == easy->state) && !easy->msg) {
+      /* clear out the usage of the shared DNS cache */
+      easy->easy_handle->hostcache = NULL;
+
+      /* now add a node to the Curl_message linked list with this info */
+      msg = (struct Curl_message *)malloc(sizeof(struct Curl_message));
+
+      if(!msg)
+        return CURLM_OUT_OF_MEMORY;
+
+      msg->extmsg.msg = CURLMSG_DONE;
+      msg->extmsg.easy_handle = easy->easy_handle;
+      msg->extmsg.data.result = easy->result;
+      msg->next=NULL;
+
+      easy->msg = msg;
+      easy->msg_num = 1; /* there is one unread message here */
+
+      multi->num_msgs++; /* increase message counter */
     }
-    else if(CURLM_STATE_COMPLETED != easy->state)
-      /* this one still lives! */
-      (*running_handles)++;
 
     easy = easy->next; /* operate on next handle */
   }
+
   return result;
 }
 
 CURLMcode curl_multi_cleanup(CURLM *multi_handle)
 {
   struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
+  struct Curl_one_easy *easy;
+  struct Curl_one_easy *nexteasy;
+
   if(GOOD_MULTI_HANDLE(multi)) {
     multi->type = 0; /* not good anymore */
-    curl_hash_destroy(multi->hostcache);
+    Curl_hash_destroy(multi->hostcache);
+
     /* remove all easy handles */
+    easy = multi->easy.next;
+    while(easy) {
+      nexteasy=easy->next;
+      /* clear out the usage of the shared DNS cache */
+      easy->easy_handle->hostcache = NULL;
+
+      if (easy->msg)
+        free(easy->msg);
+      free(easy);
+      easy = nexteasy;
+    }
 
     free(multi);
 
@@ -350,7 +529,35 @@ CURLMcode curl_multi_cleanup(CURLM *multi_handle)
     return CURLM_BAD_HANDLE;
 }
 
-CURLMsg *curl_multi_info_read(CURLM *multi_handle, int *msgs_in_queue);
+CURLMsg *curl_multi_info_read(CURLM *multi_handle, int *msgs_in_queue)
+{
+  struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
+
+  if(GOOD_MULTI_HANDLE(multi)) {
+    struct Curl_one_easy *easy;
+    
+    if(!multi->num_msgs)
+      return NULL; /* no messages left to return */
+
+    easy=multi->easy.next;
+    while(easy) {
+      if(easy->msg_num) {
+        easy->msg_num--;
+        break;
+      }
+      easy = easy->next;
+    }
+    if(!easy)
+      return NULL; /* this means internal count confusion really */
+
+    multi->num_msgs--;
+    *msgs_in_queue = multi->num_msgs;
+
+    return &easy->msg->extmsg;
+  }
+  else
+    return NULL;
+}
 
 /*
  * local variables:
diff --git a/Source/CTest/Curl/netrc.c b/Source/CTest/Curl/netrc.c
index c2c8e65..a2d6708 100644
--- a/Source/CTest/Curl/netrc.c
+++ b/Source/CTest/Curl/netrc.c
@@ -1,25 +1,25 @@
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 
 #include "setup.h"
 
@@ -78,12 +78,15 @@ int Curl_parsenetrc(char *host,
   FILE *file;
   char netrcbuffer[256];
   int retcode=1;
+
+  int specific_login = (login[0] != 0);
   
   char *home = NULL; 
   int state=NOTHING;
 
-  char state_login=0;
-  char state_password=0;
+  char state_login=0;      /* Found a login keyword */
+  char state_password=0;   /* Found a password keyword */
+  char state_our_login=0;  /* With specific_login, found *our* login name */
 
 #define NETRC DOT_CHAR "netrc"
 
@@ -116,6 +119,30 @@ int Curl_parsenetrc(char *host,
 
   sprintf(netrcbuffer, "%s%s%s", home, DIR_CHAR, NETRC);
 
+#ifdef MALLOCDEBUG
+  {
+    /* This is a hack to allow testing.
+     * If compiled with --enable-debug and CURL_DEBUG_NETRC is defined,
+     * then it's the path to a substitute .netrc for testing purposes *only* */
+
+    char *override = curl_getenv("CURL_DEBUG_NETRC");
+
+    if (override != NULL) {
+      printf("NETRC: overridden .netrc file: %s\n", home);
+
+      if (strlen(override)+1 > sizeof(netrcbuffer)) {
+        free(override);
+        if(NULL==pw)
+          free(home);
+
+        return -1;
+      }
+      strcpy(netrcbuffer, override);
+      free(override);
+    }
+  }
+#endif /* MALLOCDEBUG */
+
   file = fopen(netrcbuffer, "r");
   if(file) {
     char *tok;
@@ -123,6 +150,10 @@ int Curl_parsenetrc(char *host,
     while(fgets(netrcbuffer, sizeof(netrcbuffer), file)) {
       tok=strtok_r(netrcbuffer, " \t\n", &tok_buf);
       while(tok) {
+
+        if (login[0] && password[0])
+          goto done;
+
         switch(state) {
         case NOTHING:
           if(strequal("machine", tok)) {
@@ -149,17 +180,23 @@ int Curl_parsenetrc(char *host,
         case HOSTVALID:
           /* we are now parsing sub-keywords concerning "our" host */
           if(state_login) {
-            strncpy(login, tok, LOGINSIZE-1);
+            if (specific_login) {
+              state_our_login = strequal(login, tok);
+            }else{
+              strncpy(login, tok, LOGINSIZE-1);
 #ifdef _NETRC_DEBUG
-            printf("LOGIN: %s\n", login);
+              printf("LOGIN: %s\n", login);
 #endif
+            }
             state_login=0;
           }
           else if(state_password) {
-            strncpy(password, tok, PASSWORDSIZE-1);
+            if (state_our_login || !specific_login) {
+              strncpy(password, tok, PASSWORDSIZE-1);
 #ifdef _NETRC_DEBUG
-            printf("PASSWORD: %s\n", password);
+              printf("PASSWORD: %s\n", password);
 #endif
+            }
             state_password=0;
           }
           else if(strequal("login", tok))
@@ -169,13 +206,16 @@ int Curl_parsenetrc(char *host,
           else if(strequal("machine", tok)) {
             /* ok, there's machine here go => */
             state = HOSTFOUND;
+            state_our_login = 0;
           }
           break;
         } /* switch (state) */
+
         tok = strtok_r(NULL, " \t\n", &tok_buf);
       } /* while (tok) */
     } /* while fgets() */
 
+done:
     fclose(file);
   }
 
diff --git a/Source/CTest/Curl/netrc.h b/Source/CTest/Curl/netrc.h
index de95390..bbafb3d 100644
--- a/Source/CTest/Curl/netrc.h
+++ b/Source/CTest/Curl/netrc.h
@@ -1,28 +1,33 @@
 #ifndef __NETRC_H
 #define __NETRC_H
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 int Curl_parsenetrc(char *host,
                     char *login,
                     char *password);
+  /* Assume: password[0]=0, host[0] != 0.
+   * If login[0] = 0, search for login and password within a machine section
+   * in the netrc.
+   * If login[0] != 0, search for password within machine and login.
+   */
 #endif
diff --git a/Source/CTest/Curl/progress.c b/Source/CTest/Curl/progress.c
index 318a6d8..76fa18c 100644
--- a/Source/CTest/Curl/progress.c
+++ b/Source/CTest/Curl/progress.c
@@ -1,25 +1,25 @@
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 
 #include "setup.h"
 
@@ -45,6 +45,10 @@
 
 #include "progress.h"
 
+#define _MPRINTF_REPLACE /* use our functions only */
+#include <curl/mprintf.h>
+
+
 static void time2str(char *r, int t)
 {
   int h = (t/3600);
@@ -103,6 +107,15 @@ void Curl_pgrsDone(struct connectdata *conn)
   }
 }
 
+/* reset all times except redirect */
+void Curl_pgrsResetTimes(struct SessionHandle *data)
+{
+  data->progress.t_nslookup = 0.0;
+  data->progress.t_connect = 0.0;
+  data->progress.t_pretransfer = 0.0;
+  data->progress.t_starttransfer = 0.0;
+}
+
 void Curl_pgrsTime(struct SessionHandle *data, timerid timer)
 {
   switch(timer) {
@@ -134,6 +147,10 @@ void Curl_pgrsTime(struct SessionHandle *data, timerid timer)
   case TIMER_POSTRANSFER:
     /* this is the normal end-of-transfer thing */
     break;
+  case TIMER_REDIRECT:
+    data->progress.t_redirect =
+      (double)Curl_tvdiff(Curl_tvnow(), data->progress.start)/1000.0;
+    break;
   }
 }
 
@@ -327,8 +344,8 @@ int Curl_pgrsUpdate(struct connectdata *conn)
   /* If we have a total estimate, we can display that and the expected
      time left */
   if(total_estimate) {
-    time2str(time_left, total_estimate-(int) data->progress.timespent); 
-    time2str(time_total, total_estimate);
+    time2str(time_left, (int)(total_estimate - data->progress.timespent)); 
+    time2str(time_total, (int)total_estimate);
   }
   else {
     /* otherwise we blank those times */
@@ -336,7 +353,7 @@ int Curl_pgrsUpdate(struct connectdata *conn)
     strcpy(time_total, "--:--:--");
   }
   /* The time spent so far is always known */
-  time2str(time_current, data->progress.timespent);
+  time2str(time_current, (int)data->progress.timespent);
 
   /* Get the total amount of data expected to get transfered */
   total_expected_transfer = 
diff --git a/Source/CTest/Curl/progress.h b/Source/CTest/Curl/progress.h
index 2d45984..51994cb 100644
--- a/Source/CTest/Curl/progress.h
+++ b/Source/CTest/Curl/progress.h
@@ -1,27 +1,27 @@
 #ifndef __PROGRESS_H
 #define __PROGRESS_H
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 
 #include "timeval.h"
 
@@ -34,6 +34,7 @@ typedef enum {
   TIMER_STARTTRANSFER,
   TIMER_POSTRANSFER,
   TIMER_STARTSINGLE,
+  TIMER_REDIRECT,
   TIMER_LAST /* must be last */
 } timerid;
   
@@ -44,6 +45,7 @@ void Curl_pgrsSetUploadSize(struct SessionHandle *data, double size);
 void Curl_pgrsSetDownloadCounter(struct SessionHandle *data, double size);
 void Curl_pgrsSetUploadCounter(struct SessionHandle *data, double size);
 int Curl_pgrsUpdate(struct connectdata *);
+void Curl_pgrsResetTimes(struct SessionHandle *data);
 void Curl_pgrsTime(struct SessionHandle *data, timerid timer);
 
 
diff --git a/Source/CTest/Curl/security.c b/Source/CTest/Curl/security.c
index 9e2cc2e..aa11a8f 100644
--- a/Source/CTest/Curl/security.c
+++ b/Source/CTest/Curl/security.c
@@ -40,6 +40,7 @@
 
 #include "setup.h"
 
+#ifndef CURL_DISABLE_FTP
 #ifdef KRB4
 
 #define _MPRINTF_REPLACE /* we want curl-functions instead of native ones */
@@ -552,6 +553,7 @@ Curl_sec_end(struct connectdata *conn)
 }
 
 #endif /* KRB4 */
+#endif /* CURL_DISABLE_FTP */
 
 /*
  * local variables:
diff --git a/Source/CTest/Curl/security.h b/Source/CTest/Curl/security.h
index cd8d235..3bbb78f 100644
--- a/Source/CTest/Curl/security.h
+++ b/Source/CTest/Curl/security.h
@@ -1,27 +1,27 @@
 #ifndef __SECURITY_H
 #define __SECURITY_H
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 
 /* this is a re-write */
 
diff --git a/Source/CTest/Curl/sendf.c b/Source/CTest/Curl/sendf.c
index 7f203ee..6ebe014 100644
--- a/Source/CTest/Curl/sendf.c
+++ b/Source/CTest/Curl/sendf.c
@@ -1,25 +1,25 @@
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2002, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 
 #include "setup.h"
 
@@ -62,18 +62,18 @@
 /* returns last node in linked list */
 static struct curl_slist *slist_get_last(struct curl_slist *list)
 {
-        struct curl_slist       *item;
-
-        /* if caller passed us a NULL, return now */
-        if (!list)
-                return NULL;
-
-        /* loop through to find the last item */
-        item = list;
-        while (item->next) {
-                item = item->next;
-        }
-        return item;
+  struct curl_slist     *item;
+
+  /* if caller passed us a NULL, return now */
+  if (!list)
+    return NULL;
+
+  /* loop through to find the last item */
+  item = list;
+  while (item->next) {
+    item = item->next;
+  }
+  return item;
 }
 
 /* append a struct to the linked list. It always retunrs the address of the
@@ -84,61 +84,61 @@ static struct curl_slist *slist_get_last(struct curl_slist *list)
 struct curl_slist *curl_slist_append(struct curl_slist *list,
                                      const char *data)
 {
-        struct curl_slist       *last;
-        struct curl_slist       *new_item;
-
-        new_item = (struct curl_slist *) malloc(sizeof(struct curl_slist));
-        if (new_item) {
-                new_item->next = NULL;
-                new_item->data = strdup(data);
-        }
-        else {
-                fprintf(stderr, "Cannot allocate memory for QUOTE list.\n");
-                return NULL;
-        }
-
-        if (list) {
-                last = slist_get_last(list);
-                last->next = new_item;
-                return list;
-        }
-
-        /* if this is the first item, then new_item *is* the list */
-        return new_item;
+  struct curl_slist     *last;
+  struct curl_slist     *new_item;
+
+  new_item = (struct curl_slist *) malloc(sizeof(struct curl_slist));
+  if (new_item) {
+    new_item->next = NULL;
+    new_item->data = strdup(data);
+  }
+  if (new_item == NULL || new_item->data == NULL) {
+    fprintf(stderr, "Cannot allocate memory for QUOTE list.\n");
+    return NULL;
+  }
+
+  if (list) {
+    last = slist_get_last(list);
+    last->next = new_item;
+    return list;
+  }
+
+  /* if this is the first item, then new_item *is* the list */
+  return new_item;
 }
 
 /* be nice and clean up resources */
 void curl_slist_free_all(struct curl_slist *list)
 {
-        struct curl_slist       *next;
-        struct curl_slist       *item;
+  struct curl_slist     *next;
+  struct curl_slist     *item;
 
-        if (!list)
-                return;
+  if (!list)
+    return;
 
-        item = list;
-        do {
-                next = item->next;
+  item = list;
+  do {
+    next = item->next;
                 
-                if (item->data) {
-                        free(item->data);
-                }
-                free(item);
-                item = next;
-        } while (next);
+    if (item->data) {
+      free(item->data);
+    }
+    free(item);
+    item = next;
+  } while (next);
 }
 
-
 /* Curl_infof() is for info message along the way */
 
 void Curl_infof(struct SessionHandle *data, const char *fmt, ...)
 {
   va_list ap;
   if(data->set.verbose) {
+    char print_buffer[1024 + 1];
     va_start(ap, fmt);
-    fputs("* ", data->set.err);
-    vfprintf(data->set.err, fmt, ap);
+    vsnprintf(print_buffer, 1024, fmt, ap);
     va_end(ap);
+    Curl_debug(data, CURLINFO_TEXT, print_buffer, strlen(print_buffer));
   }
 }
 
@@ -153,6 +153,10 @@ void Curl_failf(struct SessionHandle *data, const char *fmt, ...)
   if(data->set.errorbuffer && !data->state.errorbuf) {
     vsnprintf(data->set.errorbuffer, CURL_ERROR_SIZE, fmt, ap);
     data->state.errorbuf = TRUE; /* wrote error string */
+
+    if(data->set.verbose)
+      Curl_debug(data, CURLINFO_TEXT, data->set.errorbuffer,
+                 strlen(data->set.errorbuffer));
   }
   va_end(ap);
 }
@@ -163,23 +167,45 @@ CURLcode Curl_sendf(int sockfd, struct connectdata *conn,
 {
   struct SessionHandle *data = conn->data;
   ssize_t bytes_written;
-  CURLcode result;
+  ssize_t write_len;
+  CURLcode res;
   char *s;
+  char *sptr;
   va_list ap;
   va_start(ap, fmt);
   s = vaprintf(fmt, ap); /* returns an allocated string */
   va_end(ap);
   if(!s)
-    return 0; /* failure */
-  if(data->set.verbose)
-    fprintf(data->set.err, "> %s", s);
+    return CURLE_OUT_OF_MEMORY; /* failure */
 
-  /* Write the buffer to the socket */
-  result = Curl_write(conn, sockfd, s, strlen(s), &bytes_written);
+  bytes_written=0;
+  write_len = strlen(s);
+  sptr = s;
+
+  do {
+    /* Write the buffer to the socket */
+    res = Curl_write(conn, sockfd, sptr, write_len, &bytes_written);
+
+    if(CURLE_OK != res)
+      break;
+
+    if(data->set.verbose)
+      Curl_debug(data, CURLINFO_DATA_OUT, sptr, bytes_written);
+
+    if(bytes_written != write_len) {
+      /* if not all was written at once, we must advance the pointer, decrease
+         the size left and try again! */
+      write_len -= bytes_written;
+      sptr += bytes_written;
+    }
+    else
+      break;
+
+  } while(1);
 
   free(s); /* free the output string */
 
-  return result;
+  return res;
 }
 
 /*
@@ -212,7 +238,7 @@ CURLcode Curl_write(struct connectdata *conn, int sockfd,
       }
       /* a true error */
       failf(conn->data, "SSL_write() return error %d\n", err);
-      return CURLE_WRITE_ERROR;
+      return CURLE_SEND_ERROR;
     }
     bytes_written = rc;
   }
@@ -244,7 +270,7 @@ CURLcode Curl_write(struct connectdata *conn, int sockfd,
 #endif
 
   *written = bytes_written;
-  return (-1 != bytes_written)?CURLE_OK:CURLE_WRITE_ERROR;
+  return (-1 != bytes_written)?CURLE_OK:CURLE_SEND_ERROR;
 }
 
 /* client_write() sends data to the write callback(s)
@@ -325,6 +351,9 @@ int Curl_read(struct connectdata *conn,
       case SSL_ERROR_WANT_WRITE:
         /* if there's data pending, then we re-invoke SSL_read() */
         break;
+      default:
+        failf(conn->data, "SSL read error: %d", err);
+        return CURLE_RECV_ERROR;
       }
     } while(loop);
     if(loop && SSL_pending(conn->ssl.handle))
@@ -355,6 +384,29 @@ int Curl_read(struct connectdata *conn,
   return CURLE_OK;
 }
 
+/* return 0 on success */
+int Curl_debug(struct SessionHandle *data, curl_infotype type,
+               char *ptr, size_t size)
+{
+  static const char * const s_infotype[CURLINFO_END] = {
+    "* ", "< ", "> ", "{ ", "} " };
+
+  if(data->set.fdebug)
+    return (*data->set.fdebug)(data, type, ptr, size,
+                               data->set.debugdata);
+
+  switch(type) {
+  case CURLINFO_TEXT:
+  case CURLINFO_HEADER_OUT:
+    fwrite(s_infotype[type], 2, 1, data->set.err);
+    fwrite(ptr, size, 1, data->set.err);
+    break;
+  default: /* nada */
+    break;
+  }
+  return 0;
+}
+
 
 /*
  * local variables:
diff --git a/Source/CTest/Curl/sendf.h b/Source/CTest/Curl/sendf.h
index 6724810..665a4c8 100644
--- a/Source/CTest/Curl/sendf.h
+++ b/Source/CTest/Curl/sendf.h
@@ -1,27 +1,27 @@
 #ifndef __SENDF_H
 #define __SENDF_H
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 
 CURLcode Curl_sendf(int fd, struct connectdata *, const char *fmt, ...);
 void Curl_infof(struct SessionHandle *, const char *fmt, ...);
@@ -53,4 +53,9 @@ CURLcode Curl_write(struct connectdata *conn, int sockfd,
                     void *mem, size_t len,
                     ssize_t *written);
 
+/* the function used to output verbose information */
+int Curl_debug(struct SessionHandle *handle, curl_infotype type,
+               char *data, size_t size);
+
+
 #endif
diff --git a/Source/CTest/Curl/setup.h b/Source/CTest/Curl/setup.h
index b18bae5..783fb83 100644
--- a/Source/CTest/Curl/setup.h
+++ b/Source/CTest/Curl/setup.h
@@ -1,29 +1,39 @@
 #ifndef __SETUP_H
 #define __SETUP_H
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
-
-
+ ***************************************************************************/
+
+/* MN 06/07/02 */
+/* #define HTTP_ONLY
+*/
+#ifdef HTTP_ONLY
+#define CURL_DISABLE_FTP
+#define CURL_DISABLE_LDAP
+#define CURL_DISABLE_TELNET
+#define CURL_DISABLE_DICT
+#define CURL_DISABLE_FILE
+#define CURL_DISABLE_GOPHER
+#endif
 
 #if !defined(WIN32) && defined(_WIN32)
 /* This _might_ be a good Borland fix. Please report whether this works or
diff --git a/Source/CTest/Curl/speedcheck.c b/Source/CTest/Curl/speedcheck.c
index dbd2e87..5b4d018 100644
--- a/Source/CTest/Curl/speedcheck.c
+++ b/Source/CTest/Curl/speedcheck.c
@@ -1,25 +1,25 @@
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 
 #include "setup.h"
 
diff --git a/Source/CTest/Curl/speedcheck.h b/Source/CTest/Curl/speedcheck.h
index 08eca0d..e5397d2 100644
--- a/Source/CTest/Curl/speedcheck.h
+++ b/Source/CTest/Curl/speedcheck.h
@@ -1,27 +1,27 @@
 #ifndef __SPEEDCHECK_H
 #define __SPEEDCHECK_H
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 
 #include "setup.h"
 
diff --git a/Source/CTest/Curl/ssluse.c b/Source/CTest/Curl/ssluse.c
index 74cdca1..d3162f7 100644
--- a/Source/CTest/Curl/ssluse.c
+++ b/Source/CTest/Curl/ssluse.c
@@ -1,25 +1,25 @@
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 
 /*
  * The original SSL code for curl was written by
@@ -55,6 +55,15 @@
 #undef HAVE_USERDATA_IN_PWD_CALLBACK
 #endif
 
+#if OPENSSL_VERSION_NUMBER >= 0x00907001L
+/* ENGINE_load_private_key() takes four arguments */
+#define HAVE_ENGINE_LOAD_FOUR_ARGS
+#else
+/* ENGINE_load_private_key() takes three arguments */
+#undef HAVE_ENGINE_LOAD_FOUR_ARGS
+#endif
+
+
 #ifndef HAVE_USERDATA_IN_PWD_CALLBACK
 static char global_passwd[64];
 #endif
@@ -223,30 +232,22 @@ int cert_stuff(struct connectdata *conn,
       SSL_CTX_set_default_passwd_cb(conn->ssl.ctx, passwd_callback);
     }
 
-#if 0
-    if (SSL_CTX_use_certificate_file(conn->ssl.ctx,
-                                     cert_file,
-                                     SSL_FILETYPE_PEM) != 1) {
-      failf(data, "unable to set certificate file (wrong password?)");
-      return(0);
-    }
-    if (key_file == NULL)
-      key_file=cert_file;
-
-    if (SSL_CTX_use_PrivateKey_file(conn->ssl.ctx,
-                                    key_file,
-                                    SSL_FILETYPE_PEM) != 1) {
-      failf(data, "unable to set public key file");
-      return(0);
-    }
-#else
-    /* The '#ifdef 0' section above was removed on 17-dec-2001 */
-
     file_type = do_file_type(cert_type);
 
     switch(file_type) {
     case SSL_FILETYPE_PEM:
+      /* SSL_CTX_use_certificate_chain_file() only works on PEM files */
+      if (SSL_CTX_use_certificate_chain_file(conn->ssl.ctx,
+                                             cert_file) != 1) {
+        failf(data, "unable to set certificate file (wrong password?)");
+        return 0;
+      }
+      break;
+
     case SSL_FILETYPE_ASN1:
+      /* SSL_CTX_use_certificate_file() works with either PEM or ASN1, but
+         we use the case above for PEM so this can only be performed with
+         ASN1 files. */
       if (SSL_CTX_use_certificate_file(conn->ssl.ctx,
                                        cert_file,
                                        file_type) != 1) {
@@ -283,11 +284,17 @@ int cert_stuff(struct connectdata *conn,
       {                         /* XXXX still needs some work */
         EVP_PKEY *priv_key = NULL;
         if (conn && conn->data && conn->data->engine) {
+#ifdef HAVE_ENGINE_LOAD_FOUR_ARGS
+          UI_METHOD *ui_method = UI_OpenSSL();
+#endif
           if (!key_file || !key_file[0]) {
             failf(data, "no key set to load from crypto engine\n");
             return 0;
           }
           priv_key = ENGINE_load_private_key(conn->data->engine,key_file,
+#ifdef HAVE_ENGINE_LOAD_FOUR_ARGS
+                                             ui_method,
+#endif
                                              data->set.key_passwd);
           if (!priv_key) {
             failf(data, "failed to load private key from crypto engine\n");
@@ -315,8 +322,6 @@ int cert_stuff(struct connectdata *conn,
       return 0;
     }
 
-#endif
-    
     ssl=SSL_new(conn->ssl.ctx);
     x509=SSL_get_certificate(ssl);
     
@@ -717,7 +722,7 @@ Curl_SSLConnect(struct connectdata *conn)
                     data->set.key,
                     data->set.key_type)) {
       /* failf() is already done in cert_stuff() */
-      return CURLE_SSL_CONNECT_ERROR;
+      return CURLE_SSL_CERTPROBLEM;
     }
   }
 
@@ -725,7 +730,7 @@ Curl_SSLConnect(struct connectdata *conn)
     if (!SSL_CTX_set_cipher_list(conn->ssl.ctx,
                                  data->set.ssl.cipher_list)) {
       failf(data, "failed setting cipher list");
-      return CURLE_SSL_CONNECT_ERROR;
+      return CURLE_SSL_CIPHER;
     }
   }
 
@@ -734,11 +739,12 @@ Curl_SSLConnect(struct connectdata *conn)
                        SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT|
                        SSL_VERIFY_CLIENT_ONCE,
                        cert_verify_callback);
-    if (!SSL_CTX_load_verify_locations(conn->ssl.ctx,
+    if ((data->set.ssl.CAfile || data->set.ssl.CApath) &&
+        !SSL_CTX_load_verify_locations(conn->ssl.ctx,
                                        data->set.ssl.CAfile,
                                        data->set.ssl.CApath)) {
       failf(data,"error setting cerficate verify locations");
-      return CURLE_SSL_CONNECT_ERROR;
+      return CURLE_SSL_CACERT;
     }
   }
   else
diff --git a/Source/CTest/Curl/ssluse.h b/Source/CTest/Curl/ssluse.h
index e8115f0..b8526a3 100644
--- a/Source/CTest/Curl/ssluse.h
+++ b/Source/CTest/Curl/ssluse.h
@@ -1,27 +1,27 @@
 #ifndef __SSLUSE_H
 #define __SSLUSE_H
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 #include "urldata.h"
 CURLcode Curl_SSLConnect(struct connectdata *conn);
 
diff --git a/Source/CTest/Curl/strequal.c b/Source/CTest/Curl/strequal.c
index 07bc16b..500e749 100644
--- a/Source/CTest/Curl/strequal.c
+++ b/Source/CTest/Curl/strequal.c
@@ -1,25 +1,25 @@
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 
 #include "setup.h"
 
diff --git a/Source/CTest/Curl/strequal.h b/Source/CTest/Curl/strequal.h
index e376db9..e63dc21 100644
--- a/Source/CTest/Curl/strequal.h
+++ b/Source/CTest/Curl/strequal.h
@@ -1,27 +1,27 @@
 #ifndef __STREQUAL_H
 #define __STREQUAL_H
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 
 /*
  * These two actually are public functions.
@@ -32,6 +32,10 @@ int curl_strnequal(const char *first, const char *second, size_t max);
 #define strequal(a,b) curl_strequal(a,b)
 #define strnequal(a,b,c) curl_strnequal(a,b,c)
 
+/* checkprefix() is a shorter version of the above, used when the first
+   argument is zero-byte terminated */
+#define checkprefix(a,b)    strnequal(a,b,strlen(a))
+
 #ifndef HAVE_STRLCAT
 #define strlcat(x,y,z) Curl_strlcat(x,y,z)
 size_t Curl_strlcat(char *dst, const char *src, size_t siz);
diff --git a/Source/CTest/Curl/strtok.c b/Source/CTest/Curl/strtok.c
index e7724d9..42ac1d8 100644
--- a/Source/CTest/Curl/strtok.c
+++ b/Source/CTest/Curl/strtok.c
@@ -1,25 +1,25 @@
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 
 #include "setup.h"
 
diff --git a/Source/CTest/Curl/strtok.h b/Source/CTest/Curl/strtok.h
index 6e7e167..242319a 100644
--- a/Source/CTest/Curl/strtok.h
+++ b/Source/CTest/Curl/strtok.h
@@ -1,25 +1,25 @@
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 
 #ifndef _CURL_STRTOK_R_H
 #define _CURL_STRTOK_R_H
diff --git a/Source/CTest/Curl/telnet.c b/Source/CTest/Curl/telnet.c
index 29c2110..42a1780 100644
--- a/Source/CTest/Curl/telnet.c
+++ b/Source/CTest/Curl/telnet.c
@@ -1,28 +1,29 @@
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 
 #include "setup.h"
 
+#ifndef CURL_DISABLE_TELNET
 /* -- WIN32 approved -- */
 #include <stdio.h>
 #include <string.h>
@@ -1049,6 +1050,7 @@ CURLcode Curl_telnet(struct connectdata *conn)
   char *buf = data->state.buffer;
   ssize_t nread;
   struct TELNET *tn;
+  struct timeval now;           /* current time */
 
   code = init_telnet(conn);
   if(code)
@@ -1148,9 +1150,13 @@ CURLcode Curl_telnet(struct connectdata *conn)
   keepfd = readfd;
 
   while (keepon) {
+    struct timeval interval;
+
     readfd = keepfd;            /* set this every lap in the loop */
+    interval.tv_sec = 1;
+    interval.tv_usec = 0;
 
-    switch (select (sockfd + 1, &readfd, NULL, NULL, NULL)) {
+    switch (select (sockfd + 1, &readfd, NULL, NULL, &interval)) {
     case -1:                    /* error, stop reading */
       keepon = FALSE;
       continue;
@@ -1198,10 +1204,20 @@ CURLcode Curl_telnet(struct connectdata *conn)
         }
       }
     }
+    if(data->set.timeout) {
+      now = Curl_tvnow();
+      if(Curl_tvdiff(now, conn->created)/1000 >= data->set.timeout) {
+        failf(data, "Time-out");
+        code = CURLE_OPERATION_TIMEOUTED;
+        keepon = FALSE;
+      }
+    }
   }
 #endif
   /* mark this as "no further transfer wanted" */
-  return Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+  Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+
+  return code;
 }
 
 /*
@@ -1211,3 +1227,4 @@ CURLcode Curl_telnet(struct connectdata *conn)
  * vim600: fdm=marker
  * vim: et sw=2 ts=2 sts=2 tw=78
  */
+#endif
diff --git a/Source/CTest/Curl/telnet.h b/Source/CTest/Curl/telnet.h
index e576d1d..a985517 100644
--- a/Source/CTest/Curl/telnet.h
+++ b/Source/CTest/Curl/telnet.h
@@ -1,29 +1,30 @@
 #ifndef __TELNET_H
 #define __TELNET_H
 
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
+#ifndef CURL_DISABLE_TELNET
 CURLcode Curl_telnet(struct connectdata *conn);
 CURLcode Curl_telnet_done(struct connectdata *conn);
-
+#endif
 #endif
diff --git a/Source/CTest/Curl/timeval.c b/Source/CTest/Curl/timeval.c
index cd44613..7ed6051 100644
--- a/Source/CTest/Curl/timeval.c
+++ b/Source/CTest/Curl/timeval.c
@@ -1,25 +1,25 @@
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 
 #ifdef WIN32
 #include <windows.h>
@@ -32,22 +32,40 @@
 int
 gettimeofday (struct timeval *tp, void *nothing)
 {
- SYSTEMTIME st;
- time_t tt;
- struct tm tmtm;
- /* mktime converts local to UTC */
- GetLocalTime (&st);
- tmtm.tm_sec = st.wSecond;
- tmtm.tm_min = st.wMinute;
- tmtm.tm_hour = st.wHour;
- tmtm.tm_mday = st.wDay;
- tmtm.tm_mon = st.wMonth - 1;
- tmtm.tm_year = st.wYear - 1900;
- tmtm.tm_isdst = -1;
- tt = mktime (&tmtm);
- tp->tv_sec = tt;
- tp->tv_usec = st.wMilliseconds * 1000;
- return 1;
+#ifdef WITHOUT_MM_LIB
+  SYSTEMTIME st;
+  time_t tt;
+  struct tm tmtm;
+  /* mktime converts local to UTC */
+  GetLocalTime (&st);
+  tmtm.tm_sec = st.wSecond;
+  tmtm.tm_min = st.wMinute;
+  tmtm.tm_hour = st.wHour;
+  tmtm.tm_mday = st.wDay;
+  tmtm.tm_mon = st.wMonth - 1;
+  tmtm.tm_year = st.wYear - 1900;
+  tmtm.tm_isdst = -1;
+  tt = mktime (&tmtm);
+  tp->tv_sec = tt;
+  tp->tv_usec = st.wMilliseconds * 1000;
+#else
+  /**
+   ** The earlier time calculations using GetLocalTime
+   ** had a time resolution of 10ms.The timeGetTime, part
+   ** of multimedia apis offer a better time resolution
+   ** of 1ms.Need to link against winmm.lib for this
+   **/
+  unsigned long Ticks = 0;
+  unsigned long Sec =0;
+  unsigned long Usec = 0;
+  Ticks = timeGetTime();
+
+  Sec = Ticks/1000;
+  Usec = (Ticks - (Sec*1000))*1000;
+  tp->tv_sec = Sec;
+  tp->tv_usec = Usec;
+#endif
+  return 1;
 }
 #define HAVE_GETTIMEOFDAY
 #endif
diff --git a/Source/CTest/Curl/timeval.h b/Source/CTest/Curl/timeval.h
index c8ce593..b5ef901 100644
--- a/Source/CTest/Curl/timeval.h
+++ b/Source/CTest/Curl/timeval.h
@@ -1,27 +1,27 @@
 #ifndef __TIMEVAL_H
 #define __TIMEVAL_H
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 
 #include "setup.h"
 
diff --git a/Source/CTest/Curl/transfer.c b/Source/CTest/Curl/transfer.c
index e4c1599..5e4e4fb 100644
--- a/Source/CTest/Curl/transfer.c
+++ b/Source/CTest/Curl/transfer.c
@@ -1,25 +1,25 @@
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 
 #include "setup.h"
 
@@ -82,6 +82,8 @@
 #include <curl/types.h>
 #include "netrc.h"
 
+#include "content_encoding.h"   /* content encoding support. 08/27/02 jhrg */
+
 #include "hostip.h"
 #include "transfer.h"
 #include "sendf.h"
@@ -168,6 +170,10 @@ compareheader(char *headerline, /* line to check */
   return FALSE; /* no match */
 }
 
+/* We keep this static and global since this is read-only and NEVER
+   changed. It should just remain a blanked-out timeout value. */
+static struct timeval notimeout={0,0};
+
 CURLcode Curl_readwrite(struct connectdata *conn,
                         bool *done)
 {
@@ -176,14 +182,49 @@ CURLcode Curl_readwrite(struct connectdata *conn,
   int result;
   ssize_t nread; /* number of bytes read */
   int didwhat=0;
+  
+  /* These two are used only if no other select() or _fdset() have been
+     invoked before this. This typicly happens if you use the multi interface
+     and call curl_multi_perform() without calling curl_multi_fdset()
+     first. */
+  fd_set extrareadfd;
+  fd_set extrawritefd;
+
+  fd_set *readfdp = k->readfdp;
+  fd_set *writefdp = k->writefdp;
+  
+  if((k->keepon & KEEP_READ) && !readfdp) {
+    /* reading is requested, but no socket descriptor pointer was set */
+    FD_ZERO(&extrareadfd);
+    FD_SET(conn->sockfd, &extrareadfd);
+    readfdp = &extrareadfd;
+
+    /* no write, no exceptions, no timeout */
+    select(conn->sockfd+1, readfdp, NULL, NULL, &notimeout);
+  }
+  if((k->keepon & KEEP_WRITE) && !writefdp) {
+    /* writing is requested, but no socket descriptor pointer was set */
+    FD_ZERO(&extrawritefd);
+    FD_SET(conn->writesockfd, &extrawritefd);
+    writefdp = &extrawritefd;
+
+    /* no read, no exceptions, no timeout */
+    select(conn->writesockfd+1, NULL, writefdp, NULL, &notimeout);
+  }
 
   do {
+    /* If we still have reading to do, we check if we have a readable
+       socket. Sometimes the reafdp is NULL, it no fd_set was done using
+       the multi interface and then we can do nothing but to attempt a
+       read to be sure. */
     if((k->keepon & KEEP_READ) &&
-       FD_ISSET(conn->sockfd, &k->readfd)) {
+       (FD_ISSET(conn->sockfd, readfdp))) {
 
       /* read! */
       result = Curl_read(conn, conn->sockfd, k->buf,
-                         BUFSIZE -1, &nread);
+                         data->set.buffer_size?
+                         data->set.buffer_size:BUFSIZE -1,
+                         &nread);
 
       if(0>result)
         break; /* get out of loop */
@@ -215,6 +256,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
          headers at the moment or not. */          
       if (k->header) {
         /* we are in parse-the-header-mode */
+        bool stop_reading = FALSE;
 
         /* header line within buffer loop */
         do {
@@ -226,35 +268,43 @@ CURLcode Curl_readwrite(struct connectdata *conn,
           k->end_ptr = strchr (k->str_start, '\n');
               
           if (!k->end_ptr) {
-            /* no more complete header lines within buffer */
-            /* copy what is remaining into headerbuff */
-            int str_length = (int)strlen(k->str);
+            /* Not a complete header line within buffer, append the data to
+               the end of the headerbuff. */
 
-            /*
-             * We enlarge the header buffer if it seems to be too
-             * smallish
-             */
-            if (k->hbuflen + (int)str_length >=
-                data->state.headersize) {
+            if (k->hbuflen + nread >= data->state.headersize) {
+              /* We enlarge the header buffer as it is too small */
               char *newbuff;
-              long newsize=MAX((k->hbuflen+str_length)*3/2,
+              long newsize=MAX((k->hbuflen+nread)*3/2,
                                data->state.headersize*2);
               hbufp_index = k->hbufp - data->state.headerbuff;
               newbuff = (char *)realloc(data->state.headerbuff, newsize);
               if(!newbuff) {
                 failf (data, "Failed to alloc memory for big header!");
-                return CURLE_READ_ERROR;
+                return CURLE_OUT_OF_MEMORY;
               }
               data->state.headersize=newsize;
               data->state.headerbuff = newbuff;
               k->hbufp = data->state.headerbuff + hbufp_index;
             }
-            strcpy (k->hbufp, k->str);
-            k->hbufp += strlen (k->str);
-            k->hbuflen += strlen (k->str);
+            memcpy(k->hbufp, k->str, nread);
+            k->hbufp += nread;
+            k->hbuflen += nread;
+            if (!k->headerline && (k->hbuflen>5)) {
+              /* make a first check that this looks like a HTTP header */
+              if(!checkprefix("HTTP/", data->state.headerbuff)) {
+                /* this is not the beginning of a HTTP first header line */
+                k->header = FALSE;
+                k->badheader = HEADER_ALLBAD;
+                break;
+              }
+            }
+
             break;              /* read more and try again */
           }
 
+          /* decrease the size of the remaining buffer */
+          nread -= (k->end_ptr - k->str)+1; 
+
           k->str = k->end_ptr + 1; /* move past new line */
 
           /*
@@ -273,7 +323,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
             newbuff = (char *)realloc(data->state.headerbuff, newsize);
             if(!newbuff) {
               failf (data, "Failed to alloc memory for big header!");
-              return CURLE_READ_ERROR;
+              return CURLE_OUT_OF_MEMORY;
             }
             data->state.headersize= newsize;
             data->state.headerbuff = newbuff;
@@ -292,7 +342,19 @@ CURLcode Curl_readwrite(struct connectdata *conn,
            * We now have a FULL header line that p points to
            *****/
 
+          if(!k->headerline) {
+            /* the first read header */
+            if((k->hbuflen>5) &&
+               !checkprefix("HTTP/", data->state.headerbuff)) {
+              /* this is not the beginning of a HTTP first header line */
+              k->header = FALSE;
+              k->badheader = HEADER_PARTHEADER;
+              break;
+            }
+          }
+
           if (('\n' == *k->p) || ('\r' == *k->p)) {
+            int headerlen;
             /* Zero-length header line means end of headers! */
 
             if ('\r' == *k->p)
@@ -327,7 +389,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
                * we got: "417 Expectation Failed" this means:
                * we have made a HTTP call and our Expect Header
                * seems to cause a problem => abort the write operations
-               * (or prevent them from starting
+               * (or prevent them from starting).
                */
               k->write_after_100_header = FALSE;
               k->keepon &= ~KEEP_WRITE;
@@ -340,14 +402,16 @@ CURLcode Curl_readwrite(struct connectdata *conn,
             if (data->set.http_include_header)
               k->writetype |= CLIENTWRITE_BODY;
 
+            headerlen = k->p - data->state.headerbuff;
+
             result = Curl_client_write(data, k->writetype,
                                        data->state.headerbuff,
-                                       k->p - data->state.headerbuff);
+                                       headerlen);
             if(result)
               return result;
 
-            data->info.header_size += k->p - data->state.headerbuff;
-            conn->headerbytecount += k->p - data->state.headerbuff;
+            data->info.header_size += headerlen;
+            conn->headerbytecount += headerlen;
 
             if(!k->header) {
               /*
@@ -356,8 +420,6 @@ CURLcode Curl_readwrite(struct connectdata *conn,
                * If we requested a "no body", this is a good time to get
                * out and return home.
                */
-              bool stop_reading = FALSE;
-
               if(data->set.no_body)
                 stop_reading = TRUE;
               else if(!conn->bits.close) {
@@ -367,22 +429,16 @@ CURLcode Curl_readwrite(struct connectdata *conn,
                    reading! */
                 if(-1 != conn->size)
                   conn->maxdownload = conn->size;
-
-                /* If max download size is *zero* (nothing) we already
-                   have nothing and can safely return ok now! */
-                if(0 == conn->maxdownload)
-                  stop_reading = TRUE;
-                    
-                /* What to do if the size is *not* known? */
               }
-
+              /* If max download size is *zero* (nothing) we already
+                 have nothing and can safely return ok now! */
+              if(0 == conn->maxdownload)
+                stop_reading = TRUE;
+                    
               if(stop_reading) {
                 /* we make sure that this socket isn't read more now */
                 k->keepon &= ~KEEP_READ;
                 FD_ZERO(&k->rkeepfd);
-                /* for a progress meter/info update before going away */
-                Curl_pgrsUpdate(conn);
-                return CURLE_OK;
               }
 
               break;            /* exit header line loop */
@@ -451,6 +507,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
                  * NOT contain a message-body, and thus is always terminated
                  * by the first empty line after the header fields.  */
                 conn->size=0;
+                conn->maxdownload=0;
                 break;
               default:
                 /* nothing */
@@ -458,22 +515,23 @@ CURLcode Curl_readwrite(struct connectdata *conn,
               }
             }
             else {
-              k->header = FALSE;        /* this is not a header line */
+              k->header = FALSE;   /* this is not a header line */
               break;
             }
           }
+
           /* check for Content-Length: header lines to get size */
-          if (strnequal("Content-Length:", k->p, 15) &&
+          if (checkprefix("Content-Length:", k->p) &&
               sscanf (k->p+15, " %ld", &k->contentlength)) {
             conn->size = k->contentlength;
             Curl_pgrsSetDownloadSize(data, k->contentlength);
-          }
+            }
           /* check for Content-Type: header lines to get the mime-type */
-          else if (strnequal("Content-Type:", k->p, 13)) {
+          else if (checkprefix("Content-Type:", k->p)) {
             char *start;
             char *end;
             int len;
-
+              
             /* Find the first non-space letter */
             for(start=k->p+14;
                 *start && isspace((int)*start);
@@ -539,7 +597,35 @@ CURLcode Curl_readwrite(struct connectdata *conn,
             /* init our chunky engine */
             Curl_httpchunk_init(conn);
           }
-          else if (strnequal("Content-Range:", k->p, 14)) {
+          else if (checkprefix("Content-Encoding:", k->p) &&
+                   data->set.encoding) {
+            /*
+             * Process Content-Encoding. Look for the values: identity, gzip,
+             * defalte, compress, x-gzip and x-compress. x-gzip and
+             * x-compress are the same as gzip and compress. (Sec 3.5 RFC
+             * 2616). zlib cannot handle compress, and gzip is not currently
+             * implemented. However, errors are handled further down when the
+             * response body is processed 08/27/02 jhrg */
+            char *start;
+
+            /* Find the first non-space letter */
+            for(start=k->p+17;
+                *start && isspace((int)*start);
+                start++);
+
+            /* Record the content-encoding for later use. 08/27/02 jhrg */
+            if (checkprefix("identity", start))
+              k->content_encoding = IDENTITY;
+            else if (checkprefix("deflate", start))
+              k->content_encoding = DEFLATE;
+            else if (checkprefix("gzip", start) 
+                     || checkprefix("x-gzip", start))
+              k->content_encoding = GZIP;
+            else if (checkprefix("compress", start) 
+                     || checkprefix("x-compress", start))
+              k->content_encoding = COMPRESS;
+          }
+          else if (checkprefix("Content-Range:", k->p)) {
             if (sscanf (k->p+14, " bytes %d-", &k->offset) ||
                 sscanf (k->p+14, " bytes: %d-", &k->offset)) {
               /* This second format was added August 1st 2000 by Igor
@@ -552,11 +638,10 @@ CURLcode Curl_readwrite(struct connectdata *conn,
             }
           }
           else if(data->cookies &&
-                  strnequal("Set-Cookie:", k->p, 11)) {
-            Curl_cookie_add(data->cookies, TRUE, k->p+12, conn->name);
+                  checkprefix("Set-Cookie:", k->p)) {
+            Curl_cookie_add(data->cookies, TRUE, k->p+11, conn->name);
           }
-          else if(strnequal("Last-Modified:", k->p,
-                            strlen("Last-Modified:")) &&
+          else if(checkprefix("Last-Modified:", k->p) &&
                   (data->set.timecondition || data->set.get_filetime) ) {
             time_t secs=time(NULL);
             k->timeofdoc = curl_getdate(k->p+strlen("Last-Modified:"),
@@ -566,7 +651,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
           }
           else if ((k->httpcode >= 300 && k->httpcode < 400) &&
                    (data->set.http_follow_location) &&
-                   strnequal("Location:", k->p, 9)) {
+                   checkprefix("Location:", k->p)) {
             /* this is the URL that the server advices us to get instead */
             char *ptr;
             char *start=k->p;
@@ -584,9 +669,11 @@ CURLcode Curl_readwrite(struct connectdata *conn,
             while(*ptr && !isspace((int)*ptr))
               ptr++;
             backup = *ptr; /* store the ending letter */
-            *ptr = '\0';   /* zero terminate */
-            conn->newurl = strdup(start); /* clone string */
-            *ptr = backup; /* restore ending letter */
+            if(ptr != start) {
+              *ptr = '\0';   /* zero terminate */
+              conn->newurl = strdup(start); /* clone string */
+              *ptr = backup; /* restore ending letter */
+            }
           }
 
           /*
@@ -597,6 +684,10 @@ CURLcode Curl_readwrite(struct connectdata *conn,
           if (data->set.http_include_header)
             k->writetype |= CLIENTWRITE_BODY;
 
+          if(data->set.verbose)
+            Curl_debug(data, CURLINFO_HEADER_IN,
+                       k->p, k->hbuflen);
+
           result = Curl_client_write(data, k->writetype, k->p,
                                      k->hbuflen);
           if(result)
@@ -609,20 +700,16 @@ CURLcode Curl_readwrite(struct connectdata *conn,
           k->hbufp = data->state.headerbuff;
           k->hbuflen = 0;
         }
-        while (*k->str); /* header line within buffer */
+        while (!stop_reading && *k->str); /* header line within buffer */
+
+        if(stop_reading)
+          /* We've stopped dealing with input, get out of the do-while loop */
+          break;
 
         /* We might have reached the end of the header part here, but
            there might be a non-header part left in the end of the read
            buffer. */
 
-        if (!k->header) {
-          /* the next token and forward is not part of
-             the header! */
-
-          /* we subtract the remaining header size from the buffer */
-          nread -= (k->str - k->buf);
-        }
-
       }                 /* end if header mode */
 
       /* This is not an 'else if' since it may be a rest from the header
@@ -638,8 +725,9 @@ CURLcode Curl_readwrite(struct connectdata *conn,
             if (conn->newurl) {
               /* abort after the headers if "follow Location" is set */
               infof (data, "Follow to new URL: %s\n", conn->newurl);
-                k->keepon &= ~KEEP_READ;
-                FD_ZERO(&k->rkeepfd);
+              k->keepon &= ~KEEP_READ;
+              FD_ZERO(&k->rkeepfd);
+              *done = TRUE;
               return CURLE_OK;
             }
             else if (conn->resume_from &&
@@ -664,6 +752,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
                   if(k->timeofdoc < data->set.timevalue) {
                     infof(data,
                           "The requested document is not new enough\n");
+                    *done = TRUE;
                     return CURLE_OK;
                   }
                   break;
@@ -671,6 +760,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
                   if(k->timeofdoc > data->set.timevalue) {
                     infof(data,
                           "The requested document is not old enough\n");
+                    *done = TRUE;
                     return CURLE_OK;
                   }
                   break;
@@ -682,6 +772,18 @@ CURLcode Curl_readwrite(struct connectdata *conn,
         } /* this is the first time we write a body part */
         k->bodywrites++;
 
+        /* pass data to the debug function before it gets "dechunked" */
+        if(data->set.verbose) {
+          if(k->badheader) {
+            Curl_debug(data, CURLINFO_DATA_IN, data->state.headerbuff,
+                       k->hbuflen);
+            if(k->badheader == HEADER_PARTHEADER)
+              Curl_debug(data, CURLINFO_DATA_IN, k->str, nread);
+          }
+          else
+            Curl_debug(data, CURLINFO_DATA_IN, k->str, nread);
+        }
+
         if(conn->bits.chunk) {
           /*
            * Bless me father for I have sinned. Here comes a chunked
@@ -693,8 +795,12 @@ CURLcode Curl_readwrite(struct connectdata *conn,
             Curl_httpchunk_read(conn, k->str, nread, &nread);
 
           if(CHUNKE_OK < res) {
-            failf(data, "Receeived problem in the chunky parser");
-            return CURLE_READ_ERROR;
+            if(CHUNKE_WRITE_ERROR == res) {
+              failf(data, "Failed writing data");
+              return CURLE_WRITE_ERROR;
+            }
+            failf(data, "Received problem in the chunky parser");
+            return CURLE_RECV_ERROR;
           }
           else if(CHUNKE_STOP == res) {
             /* we're done reading chunks! */
@@ -722,10 +828,51 @@ CURLcode Curl_readwrite(struct connectdata *conn,
 
         Curl_pgrsSetDownloadCounter(data, (double)k->bytecount);
             
-        if(!conn->bits.chunk && nread) {
+        if(!conn->bits.chunk && (nread || k->badheader)) {
           /* If this is chunky transfer, it was already written */
-          result = Curl_client_write(data, CLIENTWRITE_BODY, k->str,
-                                     nread);
+
+          if(k->badheader) {
+            /* we parsed a piece of data wrongly assuming it was a header
+               and now we output it as body instead */
+            result = Curl_client_write(data, CLIENTWRITE_BODY,
+                                       data->state.headerbuff,
+                                       k->hbuflen);
+          }
+          if(k->badheader < HEADER_ALLBAD) {
+            /* This switch handles various content encodings. If there's an
+               error here, be sure to check over the almost identical code in
+               http_chunk.c. 08/29/02 jhrg */
+#ifdef HAVE_LIBZ
+            switch (k->content_encoding) {
+            case IDENTITY:
+#endif
+              /* This is the default when the server sends no
+                 Content-Encoding header. See Curl_readwrite_init; the
+                 memset() call initializes k->content_encoding to zero.
+                 08/28/02 jhrg */
+              result = Curl_client_write(data, CLIENTWRITE_BODY, k->str, 
+                                         nread);
+#ifdef HAVE_LIBZ
+              break;
+
+            case DEFLATE: 
+              /* Assume CLIENTWRITE_BODY; headers are not encoded. */
+              result = Curl_unencode_deflate_write(data, k, nread);
+              break;
+
+            case GZIP:          /* FIXME 08/27/02 jhrg */
+            case COMPRESS:
+            default:
+              failf (data, "Unrecognized content encoding type. "
+                     "libcurl understands `identity' and `deflate' "
+                     "content encodings.");
+              result = CURLE_BAD_CONTENT_ENCODING;
+              break;
+            }
+#endif
+          }
+          k->badheader = HEADER_NORMAL; /* taken care of now */
+
           if(result)
             return result;
         }
@@ -733,8 +880,12 @@ CURLcode Curl_readwrite(struct connectdata *conn,
       } /* if (! header and data to read ) */
     } /* if( read from socket ) */
 
+    /* If we still have writing to do, we check if we have a writable
+       socket. Sometimes the writefdp is NULL, it no fd_set was done using
+       the multi interface and then we can do nothing but to attempt a
+       write to be sure. */
     if((k->keepon & KEEP_WRITE) &&
-       FD_ISSET(conn->writesockfd, &k->writefd)) {
+       (FD_ISSET(conn->writesockfd, writefdp)) ) {
       /* write */
 
       int i, si;
@@ -748,11 +899,46 @@ CURLcode Curl_readwrite(struct connectdata *conn,
       /* only read more data if there's no upload data already
          present in the upload buffer */
       if(0 == conn->upload_present) {
+        size_t buffersize = BUFSIZE;
         /* init the "upload from here" pointer */
         conn->upload_fromhere = k->uploadbuf;
 
-        nread = data->set.fread(conn->upload_fromhere, 1,
-                                BUFSIZE, data->set.in);
+        if(!k->upload_done) {
+
+          if(conn->bits.upload_chunky) {
+            /* if chunked Transfer-Encoding */
+            buffersize -= (8 + 2 + 2);   /* 32bit hex + CRLF + CRLF */
+            conn->upload_fromhere += 10; /* 32bit hex + CRLF */
+          }
+
+          nread = data->set.fread(conn->upload_fromhere, 1,
+                                  buffersize, data->set.in);
+          
+          if(conn->bits.upload_chunky) {
+            /* if chunked Transfer-Encoding */
+            char hexbuffer[9];
+            int hexlen = snprintf(hexbuffer, sizeof(hexbuffer),
+                                  "%x\r\n", nread);
+            /* move buffer pointer */
+            conn->upload_fromhere -= hexlen;
+            nread += hexlen;
+
+            /* copy the prefix to the buffer */
+            memcpy(conn->upload_fromhere, hexbuffer, hexlen);
+            if(nread>0) {
+              /* append CRLF to the data */
+              memcpy(conn->upload_fromhere +
+                     nread, "\r\n", 2);
+              nread+=2;
+            }
+            else {
+              /* mark this as done once this chunk is transfered */
+              k->upload_done = TRUE;
+            }
+          }
+        }
+        else
+          nread = 0; /* we're done uploading/reading */
 
         /* the signed int typecase of nread of for systems that has
            unsigned size_t */
@@ -769,16 +955,24 @@ CURLcode Curl_readwrite(struct connectdata *conn,
         /* convert LF to CRLF if so asked */
         if (data->set.crlf) {
           for(i = 0, si = 0; i < nread; i++, si++) {
-            if (k->buf[i] == 0x0a) {
+            if (conn->upload_fromhere[i] == 0x0a) {
               data->state.scratch[si++] = 0x0d;
               data->state.scratch[si] = 0x0a;
             }
-            else {
-              data->state.scratch[si] = k->uploadbuf[i];
-            }
+            else
+              data->state.scratch[si] = conn->upload_fromhere[i];
+          }
+          if(si != nread) {
+            /* only perform the special operation if we really did replace
+               anything */
+            nread = si;
+
+            /* upload from the new (replaced) buffer instead */
+            conn->upload_fromhere = data->state.scratch;
+
+            /* set the new amount too */
+            conn->upload_present = nread;
           }
-          nread = si;
-          k->buf = data->state.scratch; /* point to the new buffer */
         }
       }
       else {
@@ -804,14 +998,23 @@ CURLcode Curl_readwrite(struct connectdata *conn,
            is to happen */
         conn->upload_fromhere += bytes_written;
       }
-      else if(data->set.crlf)
-        k->buf = data->state.buffer; /* put it back on the buffer */
       else {
         /* we've uploaded that buffer now */
         conn->upload_fromhere = k->uploadbuf;
         conn->upload_present = 0; /* no more bytes left */
+
+        if(k->upload_done) {
+          /* switch off writing, we're done! */
+          k->keepon &= ~KEEP_WRITE; /* we're done writing */
+          FD_ZERO(&k->wkeepfd);
+        }
       }
 
+      if(data->set.verbose)
+        Curl_debug(data, CURLINFO_DATA_OUT, conn->upload_fromhere,
+                   bytes_written);
+      
+
       k->writebytecount += bytes_written;
       Curl_pgrsSetUploadCounter(data, (double)k->writebytecount);
 
@@ -887,13 +1090,14 @@ CURLcode Curl_readwrite_init(struct connectdata *conn)
   struct SessionHandle *data = conn->data;
   struct Curl_transfer_keeper *k = &conn->keep;
 
+  /* NB: the content encoding software depends on this initialization of
+     Curl_transfer_keeper. 08/28/02 jhrg */
   memset(k, 0, sizeof(struct Curl_transfer_keeper));
 
   k->start = Curl_tvnow(); /* start time */
   k->now = k->start;   /* current time is now */
   k->header = TRUE; /* assume header */
   k->httpversion = -1; /* unknown at this point */
-  k->conn = (struct connectdata *)conn; /* store the connection */
 
   data = conn->data; /* there's the root struct */
   k->buf = data->state.buffer;
@@ -905,13 +1109,16 @@ CURLcode Curl_readwrite_init(struct connectdata *conn)
   Curl_pgrsTime(data, TIMER_PRETRANSFER);
   Curl_speedinit(data);
 
-  if (!conn->getheader) {
+  Curl_pgrsSetUploadCounter(data, 0);
+  Curl_pgrsSetDownloadCounter(data, 0);
+
+  if (!conn->bits.getheader) {
     k->header = FALSE;
     if(conn->size > 0)
       Curl_pgrsSetDownloadSize(data, conn->size);
   }
   /* we want header and/or body, if neither then don't do this! */
-  if(conn->getheader || !data->set.no_body) {
+  if(conn->bits.getheader || !data->set.no_body) {
 
     FD_ZERO (&k->readfd);               /* clear it */
     if(conn->sockfd != -1) {
@@ -950,11 +1157,13 @@ void Curl_single_fdset(struct connectdata *conn,
   if(conn->keep.keepon & KEEP_READ) {
     FD_SET(conn->sockfd, read_fd_set);
     *max_fd = conn->sockfd;
+    conn->keep.readfdp = read_fd_set; /* store the address of the set */
   }
   if(conn->keep.keepon & KEEP_WRITE) {
     FD_SET(conn->writesockfd, write_fd_set);
     if(conn->writesockfd > *max_fd)
       *max_fd = conn->writesockfd;
+    conn->keep.writefdp = write_fd_set; /* store the address of the set */
   }
   /* we don't use exceptions, only touch that one to prevent compiler
      warnings! */
@@ -991,9 +1200,12 @@ Transfer(struct connectdata *conn)
     return CURLE_OK;
 
   /* we want header and/or body, if neither then don't do this! */
-  if(!conn->getheader && data->set.no_body)
+  if(!conn->bits.getheader && data->set.no_body)
     return CURLE_OK;
 
+  k->writefdp = &k->writefd; /* store the address of the set */
+  k->readfdp = &k->readfd;   /* store the address of the set */
+
   while (!done) {
     struct timeval interval;
     k->readfd = k->rkeepfd;  /* set these every lap in the loop */
@@ -1001,8 +1213,7 @@ Transfer(struct connectdata *conn)
     interval.tv_sec = 1;
     interval.tv_usec = 0;
 
-    switch (select (k->maxfd, &k->readfd, &k->writefd, NULL,
-                    &interval)) {
+    switch (select (k->maxfd, k->readfdp, k->writefdp, NULL, &interval)) {
     case -1: /* select() error, stop reading */
 #ifdef EINTR
       /* The EINTR is not serious, and it seems you might get this more
@@ -1047,6 +1258,22 @@ CURLcode Curl_pretransfer(struct SessionHandle *data)
   data->state.this_is_a_follow = FALSE; /* reset this */
   data->state.errorbuf = FALSE; /* no error has occurred */
 
+  /* If there was a list of cookie files to read and we haven't done it before,
+     do it now! */
+  if(data->change.cookielist) {
+    struct curl_slist *list = data->change.cookielist;
+    while(list) {
+      data->cookies = Curl_cookie_init(list->data,
+                                       data->cookies,
+                                       data->set.cookiesession);
+      list = list->next;
+    }
+    curl_slist_free_all(data->change.cookielist); /* clean up list */
+    data->change.cookielist = NULL; /* don't do this again! */
+  }
+
+
+
  /* Allow data->set.use_port to set which port to use. This needs to be
   * disabled for example when we follow Location: headers to URLs using
   * different ports! */
@@ -1056,7 +1283,8 @@ CURLcode Curl_pretransfer(struct SessionHandle *data)
   /*************************************************************
    * Tell signal handler to ignore SIGPIPE
    *************************************************************/
-  data->state.prev_signal = signal(SIGPIPE, SIG_IGN);
+  if(!data->set.no_signal)
+    data->state.prev_signal = signal(SIGPIPE, SIG_IGN);
 #endif  
 
   Curl_initinfo(data); /* reset session-specific information "variables" */
@@ -1069,12 +1297,245 @@ CURLcode Curl_posttransfer(struct SessionHandle *data)
 {
 #if defined(HAVE_SIGNAL) && defined(SIGPIPE)
   /* restore the signal handler for SIGPIPE before we get back */
-  signal(SIGPIPE, data->state.prev_signal);
+  if(!data->set.no_signal)
+    signal(SIGPIPE, data->state.prev_signal);
 #endif  
 
   return CURLE_OK;
 }
 
+CURLcode Curl_follow(struct SessionHandle *data,
+                     char *newurl) /* this 'newurl' is the Location: string,
+                                      and it must be malloc()ed before passed
+                                      here */
+{
+  /* Location: redirect */
+  char prot[16]; /* URL protocol string storage */
+  char letter;   /* used for a silly sscanf */
+  
+  if (data->set.maxredirs &&
+      (data->set.followlocation >= data->set.maxredirs)) {
+    failf(data,"Maximum (%d) redirects followed", data->set.maxredirs);
+    return CURLE_TOO_MANY_REDIRECTS;
+  }
+
+  /* mark the next request as a followed location: */
+  data->state.this_is_a_follow = TRUE;
+
+  data->set.followlocation++; /* count location-followers */
+
+  if(data->set.http_auto_referer) {
+    /* We are asked to automatically set the previous URL as the
+       referer when we get the next URL. We pick the ->url field,
+       which may or may not be 100% correct */
+
+    if(data->change.referer_alloc)
+      /* If we already have an allocated referer, free this first */
+      free(data->change.referer);
+
+    data->change.referer = strdup(data->change.url);
+    data->change.referer_alloc = TRUE; /* yes, free this later */
+  }
+
+  if(2 != sscanf(newurl, "%15[^?&/:]://%c", prot, &letter)) {
+    /***
+     *DANG* this is an RFC 2068 violation. The URL is supposed
+     to be absolute and this doesn't seem to be that!
+     ***
+     Instead, we have to TRY to append this new path to the old URL
+     to the right of the host part. Oh crap, this is doomed to cause
+     problems in the future...
+    */
+    char *protsep;
+    char *pathsep;
+    char *newest;
+
+    char *useurl = newurl;
+
+    /* we must make our own copy of the URL to play with, as it may
+       point to read-only data */
+    char *url_clone=strdup(data->change.url);
+
+    if(!url_clone)
+      return CURLE_OUT_OF_MEMORY; /* skip out of this NOW */
+
+    /* protsep points to the start of the host name */
+    protsep=strstr(url_clone, "//");
+    if(!protsep)
+      protsep=url_clone;
+    else
+      protsep+=2; /* pass the slashes */
+
+    if('/' != newurl[0]) {
+      int level=0;
+
+      /* First we need to find out if there's a ?-letter in the URL,
+         and cut it and the right-side of that off */
+      pathsep = strrchr(protsep, '?');
+      if(pathsep)
+        *pathsep=0;
+      
+      /* we have a relative path to append to the last slash if
+         there's one available */
+      pathsep = strrchr(protsep, '/');
+      if(pathsep)
+        *pathsep=0;
+
+      /* Check if there's any slash after the host name, and if so,
+         remember that position instead */
+      pathsep = strchr(protsep, '/');
+      if(pathsep)
+        protsep = pathsep+1;
+      else
+        protsep = NULL;
+
+      /* now deal with one "./" or any amount of "../" in the newurl
+         and act accordingly */
+
+      if((useurl[0] == '.') && (useurl[1] == '/'))
+        useurl+=2; /* just skip the "./" */
+            
+      while((useurl[0] == '.') &&
+            (useurl[1] == '.') &&
+            (useurl[2] == '/')) {
+        level++; 
+        useurl+=3; /* pass the "../" */
+      }
+
+      if(protsep) {
+        while(level--) {
+          /* cut off one more level from the right of the original URL */
+          pathsep = strrchr(protsep, '/');
+          if(pathsep)
+            *pathsep=0;
+          else {
+            *protsep=0;
+            break;
+          }
+        }
+      }
+    }
+    else {
+      /* We got a new absolute path for this server, cut off from the
+         first slash */
+      pathsep = strchr(protsep, '/');
+      if(pathsep)
+        *pathsep=0;
+    }
+
+    newest=(char *)malloc( strlen(url_clone) +
+                           1 + /* possible slash */
+                           strlen(useurl) + 1/* zero byte */);
+    
+    if(!newest)
+      return CURLE_OUT_OF_MEMORY; /* go out from this */
+
+    sprintf(newest, "%s%s%s", url_clone,
+            (('/' == useurl[0]) || (protsep && !*protsep))?"":"/",
+            useurl);
+    free(newurl); /* newurl is the allocated pointer */
+    free(url_clone);
+    newurl = newest;
+  }
+  else
+    /* This is an absolute URL, don't allow the custom port number */
+    data->state.allow_port = FALSE;
+
+  if(data->change.url_alloc)
+    free(data->change.url);
+  else
+    data->change.url_alloc = TRUE; /* the URL is allocated */
+      
+  /* TBD: set the URL with curl_setopt() */
+  data->change.url = newurl;
+  newurl = NULL; /* don't free! */
+
+  infof(data, "Follows Location: to new URL: '%s'\n", data->change.url);
+
+  /*
+   * We get here when the HTTP code is 300-399. We need to perform
+   * differently based on exactly what return code there was.
+   * Discussed on the curl mailing list and posted about on the 26th
+   * of January 2001.
+   */
+  switch(data->info.httpcode) {
+  case 300: /* Multiple Choices */
+  case 306: /* Not used */
+  case 307: /* Temporary Redirect */
+  default:  /* for all unknown ones */
+    /* These are explicitly mention since I've checked RFC2616 and they
+     * seem to be OK to POST to.
+     */
+    break;
+  case 301: /* Moved Permanently */
+    /* (quote from RFC2616, section 10.3.2):
+     * 
+     *  Note: When automatically redirecting a POST request after
+     *  receiving a 301 status code, some existing HTTP/1.0 user agents
+     *  will erroneously change it into a GET request.
+     *
+     * ----
+     * Warning: Because most of importants user agents do this clear
+     * RFC2616 violation, many webservers expect this misbehavior. So
+     * these servers often answers to a POST request with an error page.
+     * To be sure that libcurl gets the page that most user agents
+     * would get, libcurl has to force GET:
+     */
+    if( data->set.httpreq == HTTPREQ_POST
+        || data->set.httpreq == HTTPREQ_POST_FORM) {
+      infof(data,
+            "Violate RFC 2616/10.3.2 and switch from POST to GET\n");
+      data->set.httpreq = HTTPREQ_GET;
+    }
+    break;
+  case 302: /* Found */
+    /* (From 10.3.3)
+       
+    Note: RFC 1945 and RFC 2068 specify that the client is not allowed
+    to change the method on the redirected request.  However, most
+    existing user agent implementations treat 302 as if it were a 303
+    response, performing a GET on the Location field-value regardless
+    of the original request method. The status codes 303 and 307 have
+    been added for servers that wish to make unambiguously clear which
+    kind of reaction is expected of the client.
+    
+    (From 10.3.4)
+    
+    Note: Many pre-HTTP/1.1 user agents do not understand the 303
+    status. When interoperability with such clients is a concern, the
+    302 status code may be used instead, since most user agents react
+    to a 302 response as described here for 303.             
+    */
+  case 303: /* See Other */
+    /* Disable both types of POSTs, since doing a second POST when
+     * following isn't what anyone would want! */
+    if(data->set.httpreq != HTTPREQ_GET) {
+      data->set.httpreq = HTTPREQ_GET; /* enforce GET request */
+      infof(data, "Disables POST, goes with %s\n",
+            data->set.no_body?"HEAD":"GET");
+    }
+    break;
+  case 304: /* Not Modified */
+    /* 304 means we did a conditional request and it was "Not modified".
+     * We shouldn't get any Location: header in this response!
+     */
+    break;
+  case 305: /* Use Proxy */
+    /* (quote from RFC2616, section 10.3.6):
+     * "The requested resource MUST be accessed through the proxy given
+     * by the Location field. The Location field gives the URI of the
+     * proxy.  The recipient is expected to repeat this single request
+     * via the proxy. 305 responses MUST only be generated by origin
+     * servers."
+     */
+    break;
+  }
+  Curl_pgrsTime(data, TIMER_REDIRECT);
+  Curl_pgrsResetTimes(data);
+
+  return CURLE_OK;
+}
+
 CURLcode Curl_perform(struct SessionHandle *data)
 {
   CURLcode res;
@@ -1082,15 +1543,17 @@ CURLcode Curl_perform(struct SessionHandle *data)
   struct connectdata *conn=NULL;
   char *newurl = NULL; /* possibly a new URL to follow to! */
 
+  data->state.used_interface = Curl_if_easy;
+
   res = Curl_pretransfer(data);
   if(res)
     return res;
 
   /*
-   * It is important that there is NO 'return' from this function any any
-   * other place than falling down the bottom! This is because we have cleanup
-   * stuff that must be done before we get back, and that is only performed
-   * after this do-while loop.
+   * It is important that there is NO 'return' from this function at any other
+   * place than falling down to the end of the function! This is because we
+   * have cleanup stuff that must be done before we get back, and that is only
+   * performed after this do-while loop.
    */
 
   do {
@@ -1116,12 +1579,20 @@ CURLcode Curl_perform(struct SessionHandle *data)
            * may be free()ed in the Curl_done() function.
            */
           newurl = conn->newurl?strdup(conn->newurl):NULL;
-        else
+        else {
           /* The transfer phase returned error, we mark the connection to get
            * closed to prevent being re-used. This is becasue we can't
            * possibly know if the connection is in a good shape or not now. */
           conn->bits.close = TRUE;
 
+          if(-1 !=conn->secondarysocket) {
+            /* if we failed anywhere, we must clean up the secondary socket if
+               it was used */
+            sclose(conn->secondarysocket);
+            conn->secondarysocket=-1;
+          }
+        }
+
         /* Always run Curl_done(), even if some of the previous calls
            failed, but return the previous (original) error code */
         res2 = Curl_done(conn);
@@ -1136,172 +1607,11 @@ CURLcode Curl_perform(struct SessionHandle *data)
        */
 
       if((res == CURLE_OK) && newurl) {
-        /* Location: redirect
- 
-           This is assumed to happen for HTTP(S) only!
-        */
-        char prot[16]; /* URL protocol string storage */
-        char letter;   /* used for a silly sscanf */
-
-        if (data->set.maxredirs && (data->set.followlocation >= data->set.maxredirs)) {
-          failf(data,"Maximum (%d) redirects followed", data->set.maxredirs);
-          res=CURLE_TOO_MANY_REDIRECTS;
-          break;
-        }
-
-        /* mark the next request as a followed location: */
-        data->state.this_is_a_follow = TRUE;
-
-        data->set.followlocation++; /* count location-followers */
-
-        if(data->set.http_auto_referer) {
-          /* We are asked to automatically set the previous URL as the
-             referer when we get the next URL. We pick the ->url field,
-             which may or may not be 100% correct */
-
-          if(data->change.referer_alloc)
-            /* If we already have an allocated referer, free this first */
-            free(data->change.referer);
-
-          data->change.referer = strdup(data->change.url);
-          data->change.referer_alloc = TRUE; /* yes, free this later */
-        }
-
-        if(2 != sscanf(newurl, "%15[^?&/:]://%c", prot, &letter)) {
-          /***
-           *DANG* this is an RFC 2068 violation. The URL is supposed
-           to be absolute and this doesn't seem to be that!
-           ***
-           Instead, we have to TRY to append this new path to the old URL
-           to the right of the host part. Oh crap, this is doomed to cause
-           problems in the future...
-          */
-          char *protsep;
-          char *pathsep;
-          char *newest;
-
-          /* we must make our own copy of the URL to play with, as it may
-             point to read-only data */
-          char *url_clone=strdup(data->change.url);
-
-          if(!url_clone) {
-            res = CURLE_OUT_OF_MEMORY;
-            break; /* skip out of this loop NOW */
-          }
-
-          /* protsep points to the start of the host name */
-          protsep=strstr(url_clone, "//");
-          if(!protsep)
-            protsep=url_clone;
-          else
-            protsep+=2; /* pass the slashes */
-
-          if('/' != newurl[0]) {
-            /* First we need to find out if there's a ?-letter in the URL,
-               and cut it and the right-side of that off */
-            pathsep = strrchr(protsep, '?');
-            if(pathsep)
-              *pathsep=0;
-
-            /* we have a relative path to append to the last slash if
-               there's one available */
-            pathsep = strrchr(protsep, '/');
-            if(pathsep)
-              *pathsep=0;
-          }
-          else {
-            /* We got a new absolute path for this server, cut off from the
-               first slash */
-            pathsep = strchr(protsep, '/');
-            if(pathsep)
-              *pathsep=0;
-          }
-
-          newest=(char *)malloc( strlen(url_clone) +
-                                 1 + /* possible slash */
-                                 strlen(newurl) + 1/* zero byte */);
-
-          if(!newest) {
-            res = CURLE_OUT_OF_MEMORY;
-            break; /* go go go out from this loop */
-          }
-          sprintf(newest, "%s%s%s", url_clone, ('/' == newurl[0])?"":"/",
-                  newurl);
-          free(newurl);
-          free(url_clone);
-          newurl = newest;
-        }
-        else
-          /* This is an absolute URL, don't allow the custom port number */
-          data->state.allow_port = FALSE;
-
-        if(data->change.url_alloc)
-          free(data->change.url);
-        else
-          data->change.url_alloc = TRUE; /* the URL is allocated */
-      
-        /* TBD: set the URL with curl_setopt() */
-        data->change.url = newurl;
-        newurl = NULL; /* don't free! */
-
-        infof(data, "Follows Location: to new URL: '%s'\n", data->change.url);
-
-        /*
-         * We get here when the HTTP code is 300-399. We need to perform
-         * differently based on exactly what return code there was.
-         * Discussed on the curl mailing list and posted about on the 26th
-         * of January 2001.
-         */
-        switch(data->info.httpcode) {
-        case 300: /* Multiple Choices */
-        case 301: /* Moved Permanently */
-        case 306: /* Not used */
-        case 307: /* Temporary Redirect */
-        default:  /* for all unknown ones */
-          /* These are explicitly mention since I've checked RFC2616 and they
-           * seem to be OK to POST to.
-           */
-          break;
-        case 302: /* Found */
-          /* (From 10.3.3)
-
-            Note: RFC 1945 and RFC 2068 specify that the client is not allowed
-            to change the method on the redirected request.  However, most
-            existing user agent implementations treat 302 as if it were a 303
-            response, performing a GET on the Location field-value regardless
-            of the original request method. The status codes 303 and 307 have
-            been added for servers that wish to make unambiguously clear which
-            kind of reaction is expected of the client.
-
-            (From 10.3.4)
-
-            Note: Many pre-HTTP/1.1 user agents do not understand the 303
-            status. When interoperability with such clients is a concern, the
-            302 status code may be used instead, since most user agents react
-            to a 302 response as described here for 303.             
-          */
-        case 303: /* See Other */
-          /* Disable both types of POSTs, since doing a second POST when
-           * following isn't what anyone would want! */
-          data->set.httpreq = HTTPREQ_GET; /* enforce GET request */
-          infof(data, "Disables POST, goes with GET\n");
-          break;
-        case 304: /* Not Modified */
-          /* 304 means we did a conditional request and it was "Not modified".
-           * We shouldn't get any Location: header in this response!
-           */
-          break;
-        case 305: /* Use Proxy */
-          /* (quote from RFC2616, section 10.3.6):
-           * "The requested resource MUST be accessed through the proxy given
-           * by the Location field. The Location field gives the URI of the
-           * proxy.  The recipient is expected to repeat this single request
-           * via the proxy. 305 responses MUST only be generated by origin
-           * servers."
-           */
-          break;
+        res = Curl_follow(data, newurl);
+        if(CURLE_OK == res) {
+          newurl = NULL;
+          continue;
         }
-        continue;
       }
     }
     break; /* it only reaches here when this shouldn't loop */
@@ -1339,7 +1649,7 @@ Curl_Transfer(struct connectdata *c_conn, /* connection data */
   /* now copy all input parameters */
   conn->sockfd = sockfd;
   conn->size = size;
-  conn->getheader = getheader;
+  conn->bits.getheader = getheader;
   conn->bytecountp = bytecountp;
   conn->writesockfd = writesockfd;
   conn->writebytecountp = writebytecountp;
diff --git a/Source/CTest/Curl/transfer.h b/Source/CTest/Curl/transfer.h
index ee6c93d..cc15343 100644
--- a/Source/CTest/Curl/transfer.h
+++ b/Source/CTest/Curl/transfer.h
@@ -1,32 +1,31 @@
 #ifndef __TRANSFER_H
 #define __TRANSFER_H
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 CURLcode Curl_perform(struct SessionHandle *data);
-
 CURLcode Curl_pretransfer(struct SessionHandle *data);
 CURLcode Curl_posttransfer(struct SessionHandle *data);
-
+CURLcode Curl_follow(struct SessionHandle *data, char *newurl);
 CURLcode Curl_readwrite(struct connectdata *conn, bool *done);
 void Curl_single_fdset(struct connectdata *conn, 
                        fd_set *read_fd_set,
diff --git a/Source/CTest/Curl/url.c b/Source/CTest/Curl/url.c
index d830fb6..3216fd6 100644
--- a/Source/CTest/Curl/url.c
+++ b/Source/CTest/Curl/url.c
@@ -1,25 +1,25 @@
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 
 /* -- WIN32 approved -- */
 
@@ -72,6 +72,10 @@
 #include <inet.h>
 #endif
 
+#ifdef HAVE_SETJMP_H
+#include <setjmp.h>
+#endif
+
 #ifndef HAVE_SELECT
 #error "We can't compile without select() support!"
 #endif
@@ -107,6 +111,7 @@
 #include "ldap.h"
 #include "url.h"
 #include "connect.h"
+#include "ca-bundle.h"
 
 #include <curl/types.h>
 
@@ -120,6 +125,7 @@
 #ifdef KRB4
 #include "security.h"
 #endif
+
 /* The last #include file should be: */
 #ifdef MALLOCDEBUG
 #include "memdebug.h"
@@ -138,11 +144,17 @@ static unsigned int ConnectionStore(struct SessionHandle *data,
 #ifndef RETSIGTYPE
 #define RETSIGTYPE void
 #endif
+#ifdef HAVE_SIGSETJMP
+extern sigjmp_buf curl_jmpenv;
+#endif
 static
 RETSIGTYPE alarmfunc(int signal)
 {
   /* this is for "-ansi -Wall -pedantic" to stop complaining!   (rabe) */
   (void)signal;
+#ifdef HAVE_SIGSETJMP
+  siglongjmp(curl_jmpenv, 1);
+#endif
   return;
 }
 #endif
@@ -167,6 +179,13 @@ CURLcode Curl_close(struct SessionHandle *data)
   Curl_SSL_Close_All(data);
 #endif
 
+  /* No longer a dirty share, if it exists */
+  if (data->share)
+    data->share->dirty--;
+
+  if(data->change.cookielist) /* clean up list if any */
+    curl_slist_free_all(data->change.cookielist);
+
   if(data->state.auth_host)
     free(data->state.auth_host);
 
@@ -182,11 +201,13 @@ CURLcode Curl_close(struct SessionHandle *data)
   if(data->state.headerbuff)
     free(data->state.headerbuff);
 
+#ifndef CURL_DISABLE_HTTP
   if(data->set.cookiejar)
     /* we have a "destination" for all the cookies to get dumped to */
     Curl_cookie_output(data->cookies, data->set.cookiejar);
     
   Curl_cookie_cleanup(data->cookies);
+#endif
 
   /* free the connection cache */
   free(data->state.connects);
@@ -262,7 +283,11 @@ CURLcode Curl_open(struct SessionHandle **curl)
 
   /* Set the default size of the SSL session ID cache */
   data->set.ssl.numsessions = 5;
+
+  data->set.proxyport = 1080;
   
+  data->set.proxytype = CURLPROXY_HTTP; /* defaults to HTTP proxy */
+
   /* create an array with connection data struct pointers */
   data->state.numconnects = 5; /* hard-coded right now */
   data->state.connects = (struct connectdata **)
@@ -272,12 +297,23 @@ CURLcode Curl_open(struct SessionHandle **curl)
     free(data);
     return CURLE_OUT_OF_MEMORY;
   }
-  
+
+  /*
+   * libcurl 7.10 introduces SSL verification *by default*! This needs to be
+   * switched off unless wanted.
+   */
+  data->set.ssl.verifypeer = TRUE;
+  data->set.ssl.verifyhost = 2;
+#ifdef CURL_CA_BUNDLE
+  /* This is our prefered CA cert bundle since install time */
+  data->set.ssl.CAfile = (char *)CURL_CA_BUNDLE;
+#endif
+
+
   memset(data->state.connects, 0,
          sizeof(struct connectdata *)*data->state.numconnects);
 
   *curl = data;
-
   return CURLE_OK;
 }
 
@@ -439,7 +475,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
     /*
      * Parse the $HOME/.netrc file
      */
-    data->set.use_netrc = va_arg(param, long)?TRUE:FALSE;
+    data->set.use_netrc = va_arg(param, long);
     break;
   case CURLOPT_FOLLOWLOCATION:
     /*
@@ -493,13 +529,36 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
     data->set.ssl.version = va_arg(param, long);
     break;
 
+  case CURLOPT_COOKIESESSION:
+    /*
+     * Set this option to TRUE to start a new "cookie session". It will
+     * prevent the forthcoming read-cookies-from-file actions to accept
+     * cookies that are marked as being session cookies, as they belong to a
+     * previous session.
+     *
+     * In the original Netscape cookie spec, "session cookies" are cookies
+     * with no expire date set. RFC2109 describes the same action if no
+     * 'Max-Age' is set and RFC2965 includes the RFC2109 description and adds
+     * a 'Discard' action that can enforce the discard even for cookies that
+     * have a Max-Age.
+     *
+     * We run mostly with the original cookie spec, as hardly anyone implements
+     * anything else.
+     */
+    data->set.cookiesession = (bool)va_arg(param, long);
+    break;
+
+#ifndef CURL_DISABLE_HTTP
   case CURLOPT_COOKIEFILE:
     /*
      * Set cookie file to read and parse. Can be used multiple times.
      */
     cookiefile = (char *)va_arg(param, void *);
     if(cookiefile)
-      data->cookies = Curl_cookie_init(cookiefile, data->cookies);
+      /* append the cookie file name to the list of file names, and deal with
+         them later */
+      data->change.cookielist =
+        curl_slist_append(data->change.cookielist, cookiefile);
     break;
 
   case CURLOPT_COOKIEJAR:
@@ -512,8 +571,11 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
      * Activate the cookie parser. This may or may not already
      * have been made.
      */
-    data->cookies = Curl_cookie_init(NULL, data->cookies);
+    data->cookies = Curl_cookie_init(NULL, data->cookies,
+                                     data->set.cookiesession);
     break;
+#endif
+
   case CURLOPT_WRITEHEADER:
     /*
      * Custom pointer to pass the header write callback function
@@ -634,8 +696,9 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
     data->set.use_port = va_arg(param, long);
     break;
   case CURLOPT_POST:
-    /* Does this option serve a purpose anymore? */
-
+    /* Does this option serve a purpose anymore? Yes it does, when
+       CURLOPT_POSTFIELDS isn't used and the POST data is read off the
+       callback! */
     if(va_arg(param, long))
       data->set.httpreq = HTTPREQ_POST;
     break;
@@ -673,7 +736,13 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
     break;
   case CURLOPT_PROXY:
     /*
-     * Set proxy server:port to use as HTTP proxy
+     * Set proxy server:port to use as HTTP proxy.
+     *
+     * If the proxy is set to "" we explicitly say that we don't want to use a
+     * proxy (even though there might be environment variables saying so).
+     *
+     * Setting it to NULL, means no proxy but allows the environment variables
+     * to decide for us.
      */
     if(data->change.proxy_alloc) {
       /*
@@ -723,6 +792,13 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
      */
     data->set.useragent = va_arg(param, char *);
     break;
+  case CURLOPT_ENCODING:
+    /*
+     * String to use at the value of Accept-Encoding header. 08/28/02 jhrg
+     */
+    data->set.encoding = va_arg(param, char *);
+    break;
+
   case CURLOPT_USERPWD:
     /*
      * user:password to use in the operation
@@ -752,7 +828,11 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
      * Progress callback function
      */
     data->set.fprogress = va_arg(param, curl_progress_callback);
-    data->progress.callback = TRUE; /* no longer internal */
+    if(data->set.fprogress)
+      data->progress.callback = TRUE; /* no longer internal */
+    else
+      data->progress.callback = FALSE; /* NULL enforces internal */
+
     break;
   case CURLOPT_PROGRESSDATA:
     /*
@@ -765,6 +845,13 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
      * Password prompt callback
      */
     data->set.fpasswd = va_arg(param, curl_passwd_callback);
+    /*
+     * if the callback provided is null, reset the default callback
+     */
+    if(!data->set.fpasswd)
+    {
+      data->set.fpasswd = my_getpass;
+    }
     break;
   case CURLOPT_PASSWDDATA:
     /*
@@ -790,12 +877,30 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
      */
     data->set.set_resume_from = va_arg(param, long);
     break;
+  case CURLOPT_DEBUGFUNCTION:
+    /*
+     * stderr write callback.
+     */
+    data->set.fdebug = va_arg(param, curl_debug_callback);
+    /*
+     * if the callback provided is NULL, it'll use the default callback
+     */
+    break;
+  case CURLOPT_DEBUGDATA:
+    /*
+     * Set to a void * that should receive all error writes. This
+     * defaults to CURLOPT_STDERR for normal operations.
+     */
+    data->set.debugdata = va_arg(param, void *);
+    break;
   case CURLOPT_STDERR:
     /*
      * Set to a FILE * that should receive all error writes. This
      * defaults to stderr for normal operations.
      */
     data->set.err = va_arg(param, FILE *);
+    if(!data->set.err)
+      data->set.err = stderr;
     break;
   case CURLOPT_HEADERFUNCTION:
     /*
@@ -928,7 +1033,14 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
      * Set CA info for SSL connection. Specify file name of the CA certificate
      */
     data->set.ssl.CAfile = va_arg(param, char *);
-    data->set.ssl.CApath = NULL; /*This does not work on windows.*/
+    break;
+  case CURLOPT_CAPATH:
+    /*
+     * Set CA path info for SSL connection. Specify directory name of the CA
+     * certificates which have been prepared using openssl c_rehash utility.
+     */
+    /* This does not work on windows. */
+    data->set.ssl.CApath = va_arg(param, char *);
     break;
   case CURLOPT_TELNETOPTIONS:
     /*
@@ -936,9 +1048,49 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
      */
     data->set.telnet_options = va_arg(param, struct curl_slist *);
     break;
+
+  case CURLOPT_BUFFERSIZE:
+    /*
+     * The application kindly asks for a differently sized receive buffer.
+     * If it seems reasonable, we'll use it.
+     */
+    data->set.buffer_size = va_arg(param, long);
+
+    if(data->set.buffer_size> (BUFSIZE -1 ))
+      data->set.buffer_size = 0; /* huge internal default */
+
+    break;
+
+  case CURLOPT_NOSIGNAL:
+    /*
+     * The application asks not to set any signal() or alarm() handlers,
+     * even when using a timeout.
+     */
+    data->set.no_signal = va_arg(param, long) ? TRUE : FALSE;
+    break;
+
+  case CURLOPT_SHARE:
+    {
+      curl_share *set;
+      set = va_arg(param, curl_share *);
+      if(data->share)
+        data->share->dirty--;
+
+      data->share = set;
+      data->share->dirty++;
+    }
+    break;
+
+  case CURLOPT_PROXYTYPE:
+    /*
+     * Set proxy type. HTTP/SOCKS4/SOCKS5
+     */
+    data->set.proxytype = va_arg(param, long);
+    break;
+
   default:
     /* unknown tag and its companion, just ignore: */
-    return CURLE_READ_ERROR; /* correct this */
+    return CURLE_FAILED_INIT; /* correct this */
   }
   return CURLE_OK;
 }
@@ -993,6 +1145,8 @@ CURLcode Curl_disconnect(struct connectdata *conn)
     free(conn->allocptr.uagent);
   if(conn->allocptr.userpwd)
     free(conn->allocptr.userpwd);
+  if(conn->allocptr.accept_encoding)
+    free(conn->allocptr.accept_encoding);
   if(conn->allocptr.rangeline)
     free(conn->allocptr.rangeline);
   if(conn->allocptr.ref)
@@ -1026,7 +1180,7 @@ static bool SocketIsDead(int sock)
   FD_SET(sock,&check_set); 
 
   to.tv_sec = 0; 
-  to.tv_usec = 1; 
+  to.tv_usec = 0; 
 
   sval = select(sock + 1, &check_set, 0, 0, &to);
   if(sval == 0)
@@ -1050,6 +1204,7 @@ ConnectionExists(struct SessionHandle *data,
   struct connectdata *check;
 
   for(i=0; i< data->state.numconnects; i++) {
+    bool match = FALSE;
     /*
      * Note that if we use a HTTP proxy, we check connections to that
      * proxy and not to the actual remote server.
@@ -1070,7 +1225,6 @@ ConnectionExists(struct SessionHandle *data,
       if(strequal(needle->protostr, check->protostr) &&
          strequal(needle->name, check->name) &&
          (needle->remote_port == check->remote_port) ) {
-        bool dead;
         if(strequal(needle->protostr, "FTP")) {
           /* This is FTP, verify that we're using the same name and
              password as well */
@@ -1080,27 +1234,7 @@ ConnectionExists(struct SessionHandle *data,
             continue;
           }
         }
-        dead = SocketIsDead(check->firstsocket);
-        if(dead) {
-          /*
-           * Even though the connection seems to have passed away, we could
-           * still make an effort to get the name information, as we intend to
-           * connect to the same host again.
-           *
-           * This is now subject to discussion. What do you think?
-           */
-          infof(data, "Connection %d seems to be dead!\n", i);
-          Curl_disconnect(check); /* disconnect resources */
-          data->state.connects[i]=NULL; /* nothing here */
-
-          /* There's no need to continue search, because we only store
-             one connection for each unique set of identifiers */
-          return FALSE;
-        }
-
-        *usethis = check;
-        return TRUE; /* yes, we found one to use! */
-        
+        match = TRUE;
       }
     }
     else { /* The requested needle connection is using a proxy,
@@ -1109,9 +1243,26 @@ ConnectionExists(struct SessionHandle *data,
          strequal(needle->proxyhost, check->proxyhost) &&
          needle->port == check->port) {
         /* This is the same proxy connection, use it! */
-        *usethis = check;
-        return TRUE;
+        match = TRUE;
+      }
+    }
+
+    if(match) {
+      bool dead = SocketIsDead(check->firstsocket);
+      if(dead) {
+        /*
+         */
+        infof(data, "Connection %d seems to be dead!\n", i);
+        Curl_disconnect(check); /* disconnect resources */
+        data->state.connects[i]=NULL; /* nothing here */
+
+        /* There's no need to continue searching, because we only store
+           one connection for each unique set of identifiers */
+        return FALSE;
       }
+
+      *usethis = check;
+      return TRUE; /* yes, we found one to use! */
     }
   }
   return FALSE; /* no matching connecting exists */
@@ -1213,7 +1364,197 @@ ConnectionStore(struct SessionHandle *data,
   return i;
 }
 
-static CURLcode ConnectPlease(struct connectdata *conn)
+/*
+ * This function logs in to a SOCKS5 proxy and sends the specifies the final
+ * desitination server.
+ */
+static int handleSock5Proxy(
+    const char *proxy_name,
+    const char *proxy_password,
+    struct connectdata *conn,
+    int sock)
+{
+  unsigned char socksreq[600]; /* room for large user/pw (255 max each) */
+  int actualread;
+  int written;
+  CURLcode result;
+
+  Curl_nonblock(sock, FALSE);
+
+  socksreq[0] = 5; /* version */
+  socksreq[1] = (char)(proxy_name[0] ? 2 : 1); /* number of methods (below) */
+  socksreq[2] = 0; /* no authentication */
+  socksreq[3] = 2; /* username/password */
+
+  result = Curl_write(conn, sock, (char *)socksreq, (2 + (int)socksreq[1]),
+                      &written);
+  if ((result != CURLE_OK) || (written != (2 + (int)socksreq[1]))) {
+    failf(conn->data, "Unable to send initial SOCKS5 request.");
+    return 1;
+  }
+
+  result=Curl_read(conn, sock, (char *)socksreq, 2, &actualread);
+  if ((result != CURLE_OK) || (actualread != 2)) {
+    failf(conn->data, "Unable to receive initial SOCKS5 response.");
+    return 1;
+  }
+
+  if (socksreq[0] != 5) {
+    failf(conn->data, "Received invalid version in initial SOCKS5 response.");
+    return 1;
+  }
+  if (socksreq[1] == 0) {
+    /* Nothing to do, no authentication needed */
+    ;
+  }
+  else if (socksreq[1] == 2) {
+    /* Needs user name and password */
+    int userlen, pwlen, len;
+
+    userlen = strlen(proxy_name);
+    pwlen = strlen(proxy_password);
+
+    /*   username/password request looks like
+     * +----+------+----------+------+----------+
+     * |VER | ULEN |  UNAME   | PLEN |  PASSWD  |
+     * +----+------+----------+------+----------+
+     * | 1  |  1   | 1 to 255 |  1   | 1 to 255 |
+     * +----+------+----------+------+----------+
+     */
+    len = 0;
+    socksreq[len++] = 1;    /* username/pw subnegotiation version */
+    socksreq[len++] = (char) userlen;
+    memcpy(socksreq + len, proxy_name, (int) userlen);
+    len += userlen;
+    socksreq[len++] = (char) pwlen;
+    memcpy(socksreq + len, proxy_password, (int) pwlen);
+    len += pwlen;
+
+    result = Curl_write(conn, sock, (char *)socksreq, len, &written);
+    if ((result != CURLE_OK) || (len != written)) {
+      failf(conn->data, "Failed to send SOCKS5 sub-negotiation request.");
+      return 1;
+    }
+
+    result=Curl_read(conn, sock, (char *)socksreq, 2, &actualread);
+    if ((result != CURLE_OK) || (actualread != 2)) {
+      failf(conn->data, "Unable to receive SOCKS5 sub-negotiation response.");
+      return 1;
+    }
+
+    if ((socksreq[0] != 5) || /* version */
+        (socksreq[1] != 0)) { /* status */
+      failf(conn->data, "User was rejected by the SOCKS5 server (%d %d).",
+            socksreq[0], socksreq[1]);
+      return 1;
+    }
+
+    /* Everything is good so far, user was authenticated! */
+  }
+  else {
+    /* error */
+    if (socksreq[1] == 1) {
+      failf(conn->data,
+            "SOCKS5 GSSAPI per-message authentication is not supported.");
+      return 1;
+    }
+    else if (socksreq[1] == 255) {
+      if (proxy_name[0] == 0) {
+        failf(conn->data,
+              "No authentication method was acceptable. (It is quite likely"
+              " that the SOCKS5 server wanted a username/password, since none"
+              " was supplied to the server on this connection.)");
+      }
+      else {            
+        failf(conn->data, "No authentication method was acceptable.");
+      }
+      return 1;
+    }
+    else {
+      failf(conn->data,
+            "Undocumented SOCKS5 mode attempted to be used by server.");
+      return 1;
+    }
+  }
+
+  /* Authentication is complete, now specify destination to the proxy */
+  socksreq[0] = 5; /* version (SOCKS5) */
+  socksreq[1] = 1; /* connect */
+  socksreq[2] = 0; /* must be zero */
+  socksreq[3] = 1; /* IPv4 = 1 */
+    
+  {
+#ifndef ENABLE_IPV6
+    struct Curl_dns_entry *dns;
+    Curl_addrinfo *hp=NULL;
+    dns = Curl_resolv(conn->data, conn->hostname, conn->remote_port);
+    /*
+     * We cannot use 'hostent' as a struct that Curl_resolv() returns.  It
+     * returns a Curl_addrinfo pointer that may not always look the same.
+     */
+    if(dns)
+      hp=dns->addr;
+    if (hp && hp->h_addr_list[0]) {
+      socksreq[4] = ((char*)hp->h_addr_list[0])[0];
+      socksreq[5] = ((char*)hp->h_addr_list[0])[1];
+      socksreq[6] = ((char*)hp->h_addr_list[0])[2];
+      socksreq[7] = ((char*)hp->h_addr_list[0])[3];
+
+      Curl_resolv_unlock(dns); /* not used anymore from now on */
+    }
+    else {
+      failf(conn->data, "Failed to resolve \"%s\" for SOCKS5 connect.",
+            conn->hostname);
+      return 1;
+    }
+#else
+    failf(conn->data,
+          "%s:%d has an internal error an needs to be fixed to work",
+          __FILE__, __LINE__);
+    return 1;
+#endif
+  }
+
+  *((unsigned short*)&socksreq[8]) = htons(conn->remote_port);
+
+  {
+    const int packetsize = 10;
+
+    result = Curl_write(conn, sock, (char *)socksreq, packetsize, &written);
+    if ((result != CURLE_OK) || (written != packetsize)) {
+      failf(conn->data, "Failed to send SOCKS5 connect request.");
+      return 1;
+    }
+
+    result = Curl_read(conn, sock, (char *)socksreq, packetsize, &actualread);
+    if ((result != CURLE_OK) || (actualread != packetsize)) {
+      failf(conn->data, "Failed to receive SOCKS5 connect request ack.");
+      return 1;
+    }
+
+    if (socksreq[0] != 5) { /* version */
+      failf(conn->data,
+            "SOCKS5 reply has wrong version, version should be 5.");
+      return 1;
+    }
+    if (socksreq[1] != 0) { /* Anything besides 0 is an error */
+        failf(conn->data,
+              "Can't complete SOCKS5 connection to %d.%d.%d.%d:%d. (%d)",
+              (unsigned char)socksreq[4], (unsigned char)socksreq[5],
+              (unsigned char)socksreq[6], (unsigned char)socksreq[7],
+              (unsigned int)ntohs(*(unsigned short*)(&socksreq[8])),
+              socksreq[1]);
+        return 1;
+    }
+  }
+
+  Curl_nonblock(sock, TRUE);
+  return 0; /* Proxy was successful! */
+}
+
+static CURLcode ConnectPlease(struct connectdata *conn,
+                              struct Curl_dns_entry *hostaddr,
+                              bool *connected)
 {
   CURLcode result;
   Curl_ipconnect *addr;
@@ -1222,28 +1563,130 @@ static CURLcode ConnectPlease(struct connectdata *conn)
    * Connect to server/proxy
    *************************************************************/
   result= Curl_connecthost(conn,
-                           conn->hostaddr,
+                           hostaddr,
                            conn->port,
                            &conn->firstsocket,
-                           &addr);
+                           &addr,
+                           connected);
   if(CURLE_OK == result) {
     /* All is cool, then we store the current information from the hostaddr
        struct to the serv_addr, as it might be needed later. The address
        returned from the function above is crucial here. */
+    conn->connect_addr = hostaddr;
+
 #ifdef ENABLE_IPV6
     conn->serv_addr = addr;
 #else
     memset((char *) &conn->serv_addr, '\0', sizeof(conn->serv_addr));
     memcpy((char *)&(conn->serv_addr.sin_addr),
            (struct in_addr *)addr, sizeof(struct in_addr));
-    conn->serv_addr.sin_family = conn->hostaddr->h_addrtype;
-    conn->serv_addr.sin_port = htons(conn->port);
+    conn->serv_addr.sin_family = hostaddr->addr->h_addrtype;
+    conn->serv_addr.sin_port = htons((unsigned short)conn->port);
 #endif
+
+    if (conn->data->set.proxytype == CURLPROXY_SOCKS5) {
+      return handleSock5Proxy(conn->data->state.proxyuser,
+                              conn->data->state.proxypasswd,
+                              conn,
+                              conn->firstsocket) ?
+        CURLE_COULDNT_CONNECT : CURLE_OK;
+    }
+    else if (conn->data->set.proxytype == CURLPROXY_HTTP) {
+      /* do nothing here. handled later. */
+    }
+    else {
+      failf(conn->data, "unknown proxytype option given");
+      return CURLE_COULDNT_CONNECT; 
+    }
   }
 
   return result;
 }
 
+static void verboseconnect(struct connectdata *conn,
+                           struct Curl_dns_entry *dns)
+{
+#ifdef HAVE_INET_NTOA_R
+  char ntoa_buf[64];
+#endif
+  struct SessionHandle *data = conn->data;
+
+  /* Figure out the ip-number and display the first host name it shows: */
+#ifdef ENABLE_IPV6
+  (void)dns; /* not used in the IPv6 enabled version */
+  {
+    char hbuf[NI_MAXHOST];
+#ifdef NI_WITHSCOPEID
+    const int niflags = NI_NUMERICHOST | NI_WITHSCOPEID;
+#else
+    const int niflags = NI_NUMERICHOST;
+#endif
+    struct addrinfo *ai = conn->serv_addr;
+
+    if (getnameinfo(ai->ai_addr, ai->ai_addrlen, hbuf, sizeof(hbuf), NULL, 0,
+        niflags)) {
+      snprintf(hbuf, sizeof(hbuf), "?");
+    }
+    if (ai->ai_canonname) {
+      infof(data, "Connected to %s (%s) port %d\n", ai->ai_canonname, hbuf,
+            conn->port);
+    } else {
+      infof(data, "Connected to %s port %d\n", hbuf, conn->port);
+    }
+  }
+#else
+  {
+    Curl_addrinfo *hostaddr=dns->addr;
+    struct in_addr in;
+    (void) memcpy(&in.s_addr, &conn->serv_addr.sin_addr, sizeof (in.s_addr));
+    infof(data, "Connected to %s (%s) port %d\n",
+          hostaddr?hostaddr->h_name:"",
+#if defined(HAVE_INET_NTOA_R)
+          inet_ntoa_r(in, ntoa_buf, sizeof(ntoa_buf)),
+#else
+          inet_ntoa(in),
+#endif
+          conn->port);
+  }
+#endif
+}
+
+/*
+ * We have discovered that the TCP connection has been successful, we can now
+ * proceed with some action.
+ *
+ * If we're using the multi interface, this host address pointer is most
+ * likely NULL at this point as we can't keep the resolved info around. This
+ * may call for some reworking, like a reference counter in the struct or
+ * something. The hostaddr is not used for very much though, we have the
+ * 'serv_addr' field in the connectdata struct for most of it.
+ */
+CURLcode Curl_protocol_connect(struct connectdata *conn,
+                               struct Curl_dns_entry *hostaddr)
+{
+  struct SessionHandle *data = conn->data;
+  CURLcode result=CURLE_OK;
+  
+  Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */
+
+  if(data->set.verbose)
+    verboseconnect(conn, hostaddr);
+
+  if(conn->curl_connect) {
+    /* is there a protocol-specific connect() procedure? */
+
+    /* set start time here for timeout purposes in the
+     * connect procedure, it is later set again for the
+     * progress meter purpose */
+    conn->now = Curl_tvnow();
+
+    /* Call the protocol-specific connect function */
+    result = conn->curl_connect(conn);
+  }
+
+  return result; /* pass back status */
+}
+
 static CURLcode CreateConnection(struct SessionHandle *data,
                                  struct connectdata **in_connect)
 {
@@ -1253,18 +1696,16 @@ static CURLcode CreateConnection(struct SessionHandle *data,
   char resumerange[40]="";
   struct connectdata *conn;
   struct connectdata *conn_temp;
-  char endbracket;
   int urllen;
-#ifdef HAVE_INET_NTOA_R
-  char ntoa_buf[64];
-#endif
+  struct Curl_dns_entry *hostaddr;
 #ifdef HAVE_ALARM
-  unsigned int prev_alarm;
+  unsigned int prev_alarm=0;
 #endif
+  char endbracket;
 
 #ifdef HAVE_SIGACTION
   struct sigaction keep_sigact;   /* store the old struct here */
-  bool keep_copysig;              /* did copy it? */
+  bool keep_copysig=FALSE;        /* did copy it? */
 #else
 #ifdef HAVE_SIGNAL
   void *keep_sigact;              /* store the old handler here */
@@ -1301,16 +1742,18 @@ static CURLcode CreateConnection(struct SessionHandle *data,
   conn->firstsocket = -1;     /* no file descriptor */
   conn->secondarysocket = -1; /* no file descriptor */
   conn->connectindex = -1;    /* no index */
-  conn->bits.httpproxy = data->change.proxy?TRUE:FALSE; /* proxy-or-not */
+  conn->bits.httpproxy = (data->change.proxy && *data->change.proxy &&
+                          (data->set.proxytype == CURLPROXY_HTTP))?
+    TRUE:FALSE; /* http proxy or not */
   conn->bits.use_range = data->set.set_range?TRUE:FALSE; /* range status */
-  conn->range = data->set.set_range;               /* clone the range setting */
+  conn->range = data->set.set_range;              /* clone the range setting */
   conn->resume_from = data->set.set_resume_from;   /* inherite resume_from */
 
   /* Default protocol-independent behavior doesn't support persistant
      connections, so we set this to force-close. Protocols that support
      this need to set this to FALSE in their "curl_do" functions. */
   conn->bits.close = TRUE;
-  
+
   /* inherite initial knowledge from the data struct */
   conn->bits.user_passwd = data->set.userpwd?1:0;
   conn->bits.proxy_user_passwd = data->set.proxyuserpwd?1:0;
@@ -1321,6 +1764,20 @@ static CURLcode CreateConnection(struct SessionHandle *data,
   /* Store creation time to help future close decision making */
   conn->created = Curl_tvnow();
 
+  /* Set the start time temporary to this creation time to allow easier
+     timeout checks before the transfer has started for real. The start time
+     is later set "for real" using Curl_pgrsStartNow(). */
+  conn->data->progress.start = conn->created; 
+
+  conn->bits.upload_chunky =
+    ((conn->protocol&PROT_HTTP) &&
+     data->set.upload &&
+     (data->set.infilesize == -1) &&
+     (data->set.httpversion != CURL_HTTP_VERSION_1_0))?
+    /* HTTP, upload, unknown file size and not HTTP 1.0 */
+    TRUE:
+  /* else, no chunky upload */
+  FALSE;
 
   /***********************************************************
    * We need to allocate memory to store the path in. We get the size of the
@@ -1410,22 +1867,25 @@ static CURLcode CreateConnection(struct SessionHandle *data,
        * is based on the first letters of the server name.
        */
 
-      if(strnequal(conn->gname, "FTP", 3)) {
+      /* Note: if you add a new protocol, please update the list in
+       * lib/version.c too! */
+
+      if(checkprefix("FTP", conn->gname)) {
         strcpy(conn->protostr, "ftp");
       }
-      else if(strnequal(conn->gname, "GOPHER", 6))
+      else if(checkprefix("GOPHER", conn->gname))
         strcpy(conn->protostr, "gopher");
 #ifdef USE_SSLEAY
-      else if(strnequal(conn->gname, "HTTPS", 5))
+      else if(checkprefix("HTTPS", conn->gname))
         strcpy(conn->protostr, "https");
-      else if(strnequal(conn->gname, "FTPS", 4))
+      else if(checkprefix("FTPS", conn->gname))
         strcpy(conn->protostr, "ftps");
 #endif /* USE_SSLEAY */
-      else if(strnequal(conn->gname, "TELNET", 6))
+      else if(checkprefix("TELNET", conn->gname))
         strcpy(conn->protostr, "telnet");
-      else if (strnequal(conn->gname, "DICT", sizeof("DICT")-1))
+      else if (checkprefix("DICT", conn->gname))
         strcpy(conn->protostr, "DICT");
-      else if (strnequal(conn->gname, "LDAP", sizeof("LDAP")-1))
+      else if (checkprefix("LDAP", conn->gname))
         strcpy(conn->protostr, "LDAP");
       else {
         strcpy(conn->protostr, "http");
@@ -1437,32 +1897,12 @@ static CURLcode CreateConnection(struct SessionHandle *data,
 
   buf = data->state.buffer; /* this is our buffer */
 
-  /*************************************************************
-   * Take care of user and password authentication stuff
-   *************************************************************/
-
-  if(conn->bits.user_passwd && !data->set.use_netrc) {
-    data->state.user[0] =0;
-    data->state.passwd[0]=0;
-
-    if(*data->set.userpwd != ':') {
-      /* the name is given, get user+password */
-      sscanf(data->set.userpwd, "%127[^:]:%127[^\n]",
-             data->state.user, data->state.passwd);
-    }
-    else
-      /* no name given, get the password only */
-      sscanf(data->set.userpwd+1, "%127[^\n]", data->state.passwd);
-
-    /* check for password, if no ask for one */
-    if( !data->state.passwd[0] ) {
-      if(!data->set.fpasswd ||
-         data->set.fpasswd(data->set.passwd_client,
-                       "password:", data->state.passwd,
-                           sizeof(data->state.passwd)))
-        return CURLE_BAD_PASSWORD_ENTERED;
-    }
-  }
+  /*
+   * So if the URL was A://B/C,
+   *   conn->protostr is A
+   *   conn->gname is B
+   *   conn->path is /C
+   */
 
   /*************************************************************
    * Take care of proxy authentication stuff
@@ -1482,12 +1922,13 @@ static CURLcode CreateConnection(struct SessionHandle *data,
 
     /* check for password, if no ask for one */
     if( !data->state.proxypasswd[0] ) {
-      if(!data->set.fpasswd ||
-         data->set.fpasswd( data->set.passwd_client,
-                        "proxy password:",
-                        data->state.proxypasswd,
-                        sizeof(data->state.proxypasswd)))
+      if(data->set.fpasswd( data->set.passwd_client,
+                            "proxy password:",
+                            data->state.proxypasswd,
+                            sizeof(data->state.proxypasswd))) {
+        failf(data, "Bad password from password callback");
         return CURLE_BAD_PASSWORD_ENTERED;
+      }
     }
 
   }
@@ -1537,10 +1978,17 @@ static CURLcode CreateConnection(struct SessionHandle *data,
 
       nope=no_proxy?strtok_r(no_proxy, ", ", &no_proxy_tok_buf):NULL;
       while(nope) {
-        if(strlen(nope) <= strlen(conn->name)) {
+        unsigned int namelen;
+        char *endptr = strchr(conn->name, ':');
+        if(endptr)
+          namelen=endptr-conn->name;
+        else
+          namelen=strlen(conn->name);
+
+        if(strlen(nope) <= namelen) {
           char *checkn=
-            conn->name + strlen(conn->name) - strlen(nope);
-          if(strnequal(nope, checkn, strlen(nope))) {
+            conn->name + namelen - strlen(nope);
+          if(checkprefix(nope, checkn)) {
             /* no proxy for this host! */
             break;
           }
@@ -1622,6 +2070,7 @@ static CURLcode CreateConnection(struct SessionHandle *data,
     conn->protocol &= ~PROT_MISSING; /* switch that one off again */
   }
 
+#ifndef CURL_DISABLE_HTTP
   /************************************************************
    * RESUME on a HTTP page is a tricky business. First, let's just check that
    * 'range' isn't used, then set the range parameter and leave the resume as
@@ -1640,22 +2089,29 @@ static CURLcode CreateConnection(struct SessionHandle *data,
       conn->bits.use_range = 1; /* switch on range usage */
     }
   }
-
+#endif
   /*************************************************************
    * Setup internals depending on protocol
    *************************************************************/
 
   if (strequal(conn->protostr, "HTTP")) {
+#ifndef CURL_DISABLE_HTTP
     conn->port = (data->set.use_port && data->state.allow_port)?
       data->set.use_port:PORT_HTTP;
     conn->remote_port = PORT_HTTP;
     conn->protocol |= PROT_HTTP;
     conn->curl_do = Curl_http;
+    conn->curl_do_more = NULL;
     conn->curl_done = Curl_http_done;
     conn->curl_connect = Curl_http_connect;
+#else
+    failf(data, LIBCURL_NAME
+          " was built with HTTP disabled, http: not supported!");
+    return CURLE_UNSUPPORTED_PROTOCOL;
+#endif
   }
   else if (strequal(conn->protostr, "HTTPS")) {
-#ifdef USE_SSLEAY
+#if defined(USE_SSLEAY) && !defined(CURL_DISABLE_HTTP)
 
     conn->port = (data->set.use_port && data->state.allow_port)?
       data->set.use_port:PORT_HTTPS;
@@ -1663,6 +2119,7 @@ static CURLcode CreateConnection(struct SessionHandle *data,
     conn->protocol |= PROT_HTTP|PROT_HTTPS|PROT_SSL;
 
     conn->curl_do = Curl_http;
+    conn->curl_do_more = NULL;
     conn->curl_done = Curl_http_done;
     conn->curl_connect = Curl_http_connect;
 
@@ -1673,6 +2130,7 @@ static CURLcode CreateConnection(struct SessionHandle *data,
 #endif /* !USE_SSLEAY */
   }
   else if (strequal(conn->protostr, "GOPHER")) {
+#ifndef CURL_DISABLE_GOPHER
     conn->port = (data->set.use_port && data->state.allow_port)?
       data->set.use_port:PORT_GOPHER;
     conn->remote_port = PORT_GOPHER;
@@ -1684,10 +2142,18 @@ static CURLcode CreateConnection(struct SessionHandle *data,
       }
     conn->protocol |= PROT_GOPHER;
     conn->curl_do = Curl_http;
+    conn->curl_do_more = NULL;
     conn->curl_done = Curl_http_done;
+#else
+    failf(data, LIBCURL_NAME
+          " was built with GOPHER disabled, gopher: not supported!");
+#endif
   }
   else if(strequal(conn->protostr, "FTP") ||
           strequal(conn->protostr, "FTPS")) {
+
+/* MN 06/07/02 */
+#ifndef CURL_DISABLE_FTP
     char *type;
 
     if(strequal(conn->protostr, "FTPS")) {
@@ -1706,6 +2172,7 @@ static CURLcode CreateConnection(struct SessionHandle *data,
     conn->protocol |= PROT_FTP;
 
     if(data->change.proxy &&
+       *data->change.proxy &&
        !data->set.tunnel_thru_httpproxy) {
       /* Unless we have asked to tunnel ftp operations through the proxy, we
          switch and use HTTP operations only */
@@ -1715,11 +2182,17 @@ static CURLcode CreateConnection(struct SessionHandle *data,
         failf(data, "ftps does not work through http proxy!");
         return CURLE_UNSUPPORTED_PROTOCOL;
       }
+#ifndef CURL_DISABLE_HTTP
       conn->curl_do = Curl_http;
       conn->curl_done = Curl_http_done;
+#else
+      failf(data, "FTP over http proxy requires HTTP support built-in!");
+      return CURLE_UNSUPPORTED_PROTOCOL;
+#endif
     }
     else {
       conn->curl_do = Curl_ftp;
+      conn->curl_do_more = Curl_ftp_nextconnect;
       conn->curl_done = Curl_ftp_done;
       conn->curl_connect = Curl_ftp_connect;
       conn->curl_disconnect = Curl_ftp_disconnect;
@@ -1735,7 +2208,7 @@ static CURLcode CreateConnection(struct SessionHandle *data,
     }
     if(type) {
       char command;
-      *type=0;
+      *type=0;                     /* it was in the middle of the hostname */
       command = toupper(type[6]);
       switch(command) {
       case 'A': /* ASCII mode */
@@ -1751,8 +2224,16 @@ static CURLcode CreateConnection(struct SessionHandle *data,
         break;
       }
     }
+
+/* MN 06/07/02 */
+#else /* CURL_DISABLE_FTP */
+    failf(data, LIBCURL_NAME
+          " was built with FTP disabled, ftp/ftps: not supported!");
+    return CURLE_UNSUPPORTED_PROTOCOL;
+#endif
   }
   else if(strequal(conn->protostr, "TELNET")) {
+#ifndef CURL_DISABLE_TELNET
     /* telnet testing factory */
     conn->protocol |= PROT_TELNET;
 
@@ -1761,24 +2242,39 @@ static CURLcode CreateConnection(struct SessionHandle *data,
     conn->remote_port = PORT_TELNET;
     conn->curl_do = Curl_telnet;
     conn->curl_done = Curl_telnet_done;
+#else
+    failf(data, LIBCURL_NAME
+          " was built with TELNET disabled!");
+#endif
   }
   else if (strequal(conn->protostr, "DICT")) {
+#ifndef CURL_DISABLE_DICT
     conn->protocol |= PROT_DICT;
     conn->port = (data->set.use_port && data->state.allow_port)?
       data->set.use_port:PORT_DICT;
     conn->remote_port = PORT_DICT;
     conn->curl_do = Curl_dict;
     conn->curl_done = NULL; /* no DICT-specific done */
+#else
+    failf(data, LIBCURL_NAME
+          " was built with DICT disabled!");
+#endif
   }
   else if (strequal(conn->protostr, "LDAP")) {
+#ifndef CURL_DISABLE_LDAP
     conn->protocol |= PROT_LDAP;
     conn->port = (data->set.use_port && data->state.allow_port)?
       data->set.use_port:PORT_LDAP;
     conn->remote_port = PORT_LDAP;
     conn->curl_do = Curl_ldap;
     conn->curl_done = NULL; /* no LDAP-specific done */
+#else
+    failf(data, LIBCURL_NAME
+          " was built with LDAP disabled!");
+#endif
   }
   else if (strequal(conn->protostr, "FILE")) {
+#ifndef CURL_DISABLE_FILE
     conn->protocol |= PROT_FILE;
 
     conn->curl_do = Curl_file;
@@ -1795,6 +2291,10 @@ static CURLcode CreateConnection(struct SessionHandle *data,
     }
 
     return result;
+#else
+    failf(data, LIBCURL_NAME
+          " was built with FILE disabled!");
+#endif
   }
   else {
     /* We fell through all checks and thus we don't support the specified
@@ -1804,84 +2304,6 @@ static CURLcode CreateConnection(struct SessionHandle *data,
   }
 
   /*************************************************************
-   * .netrc scanning coming up
-   *************************************************************/
-  if(data->set.use_netrc) {
-    if(Curl_parsenetrc(conn->hostname,
-                       data->state.user,
-                       data->state.passwd)) {
-      infof(data, "Couldn't find host %s in the .netrc file, using defaults",
-            conn->hostname);
-    }
-    else
-      conn->bits.user_passwd = 1; /* enable user+password */
-
-    /* weather we failed or not, we don't know which fields that were filled
-       in anyway */
-    if(!data->state.user[0])
-      strcpy(data->state.user, CURL_DEFAULT_USER);
-    if(!data->state.passwd[0])
-      strcpy(data->state.passwd, CURL_DEFAULT_PASSWORD);
-  }
-  else if(!(conn->bits.user_passwd) &&
-          (conn->protocol & (PROT_FTP|PROT_HTTP)) ) {
-    /* This is a FTP or HTTP URL, and we haven't got the user+password in
-     * the extra parameter, we will now try to extract the possible
-     * user+password pair in a string like:
-     * ftp://user:password@ftp.my.site:8021/README */
-    char *ptr=NULL; /* assign to remove possible warnings */
-    if((ptr=strchr(conn->name, '@'))) {
-      /* there's a user+password given here, to the left of the @ */
-
-      data->state.user[0] =0;
-      data->state.passwd[0]=0;
-
-      if(*conn->name != ':') {
-        /* the name is given, get user+password */
-        sscanf(conn->name, "%127[^:@]:%127[^@]",
-               data->state.user, data->state.passwd);
-      }
-      else
-        /* no name given, get the password only */
-        sscanf(conn->name+1, "%127[^@]", data->state.passwd);
-
-      if(data->state.user[0]) {
-        char *newname=curl_unescape(data->state.user, 0);
-        if(strlen(newname) < sizeof(data->state.user)) {
-          strcpy(data->state.user, newname);
-        }
-        /* if the new name is longer than accepted, then just use
-           the unconverted name, it'll be wrong but what the heck */
-        free(newname);
-      }
-
-      /* check for password, if no ask for one */
-      if( !data->state.passwd[0] ) {
-        if(!data->set.fpasswd ||
-           data->set.fpasswd(data->set.passwd_client,
-                             "password:", data->state.passwd,
-                             sizeof(data->state.passwd)))
-          return CURLE_BAD_PASSWORD_ENTERED;
-      }
-      else {
-        /* we have a password found in the URL, decode it! */
-        char *newpasswd=curl_unescape(data->state.passwd, 0);
-        if(strlen(newpasswd) < sizeof(data->state.passwd)) {
-          strcpy(data->state.passwd, newpasswd);
-        }
-        free(newpasswd);
-      }
-
-      conn->name = ++ptr;
-      conn->bits.user_passwd=TRUE; /* enable user+password */
-    }
-    else {
-      strcpy(data->state.user, CURL_DEFAULT_USER);
-      strcpy(data->state.passwd, CURL_DEFAULT_PASSWORD);
-    }
-  }
-
-  /*************************************************************
    * Figure out the remote port number
    *
    * No matter if we use a proxy or not, we have to figure out the remote
@@ -1889,32 +2311,48 @@ static CURLcode CreateConnection(struct SessionHandle *data,
    *
    * To be able to detect port number flawlessly, we must not confuse them
    * IPv6-specified addresses in the [0::1] style. (RFC2732)
+   *
+   * The conn->name is currently [user:passwd@]host[:port] where host could
+   * be a hostname, IPv4 address or IPv6 address.
    *************************************************************/
-
   if((1 == sscanf(conn->name, "[%*39[0-9a-fA-F:.]%c", &endbracket)) &&
      (']' == endbracket)) {
-    /* This is a (IPv6-style) specified IP-address. We support _any_
-       IP within brackets to be really generic. */
-    conn->name++; /* pass the starting bracket */
+    /* this is a RFC2732-style specified IP-address */
+    conn->bits.ipv6_ip = TRUE;
 
+    conn->name++; /* pass the starting bracket */ 
+    conn->hostname++;
     tmp = strchr(conn->name, ']');
     *tmp = 0; /* zero terminate */
-
     tmp++; /* pass the ending bracket */
     if(':' != *tmp)
       tmp = NULL; /* no port number available */
   }
-  else {
-    /* traditional IPv4-style port-extracting */
-    tmp = strchr(conn->name, ':');
-  }
+  else
+    tmp = strrchr(conn->name, ':');
 
   if (tmp) {
-    *tmp++ = '\0'; /* cut off the name there */
-    conn->remote_port = atoi(tmp);
+    char *rest;
+    unsigned long port;
+
+    port=strtoul(tmp+1, &rest, 10);  /* Port number must be decimal */
+
+    if (rest != (tmp+1) && *rest == '\0') {
+      /* The colon really did have only digits after it,
+       * so it is either a port number or a mistake */
+
+      if (port > 0xffff) {   /* Single unix standard says port numbers are
+                              * 16 bits long */
+        failf(data, "Port number too large: %lu", port);
+        return CURLE_URL_MALFORMAT;
+      }
+
+      *tmp = '\0'; /* cut off the name there */
+      conn->remote_port = (unsigned short)port;
+    }
   }
 
-  if(data->change.proxy) {
+  if(data->change.proxy && *data->change.proxy) {
     /* If this is supposed to use a proxy, we need to figure out the proxy
        host name name, so that we can re-use an existing connection
        that may exist registered to the same proxy host. */
@@ -1966,6 +2404,137 @@ static CURLcode CreateConnection(struct SessionHandle *data,
   }
 
   /*************************************************************
+   * Take care of user and password authentication stuff
+   *************************************************************/
+
+  /*
+   * Inputs: data->set.userpwd   (CURLOPT_USERPWD)
+   *         data->set.fpasswd   (CURLOPT_PASSWDFUNCTION)
+   *         data->set.use_netrc (CURLOPT_NETRC)
+   *         conn->hostname
+   *         netrc file
+   *         hard-coded defaults
+   *
+   * Outputs: (almost :- all currently undefined)
+   *          conn->bits.user_passwd  - non-zero if non-default passwords exist
+   *          conn->state.user        - non-zero length if defined
+   *          conn->state.passwd      -   ditto
+   *          conn->hostname          - remove user name and password
+   */
+
+  /* At this point, we're hoping all the other special cases have
+   * been taken care of, so conn->hostname is at most
+   *    [user[:password]]@]hostname
+   *
+   * We need somewhere to put the embedded details, so do that first.
+   */
+
+  data->state.user[0] =0;   /* to make everything well-defined */
+  data->state.passwd[0]=0;
+  
+  if (conn->protocol & (PROT_FTP|PROT_HTTP)) {
+    /* This is a FTP or HTTP URL, we will now try to extract the possible
+     * user+password pair in a string like:
+     * ftp://user:password@ftp.my.site:8021/README */
+    char *ptr=strchr(conn->name, '@');
+    char *userpass = conn->name;
+    if(ptr != NULL) {
+      /* there's a user+password given here, to the left of the @ */
+
+      conn->name = conn->hostname = ++ptr;
+
+      /* So the hostname is sane.  Only bother interpreting the
+       * results if we could care.  It could still be wasted
+       * work because it might be overtaken by the programmatically
+       * set user/passwd, but doing that first adds more cases here :-(
+       */
+
+      if (data->set.use_netrc != CURL_NETRC_REQUIRED) {
+        /* We could use the one in the URL */
+
+        conn->bits.user_passwd = 1; /* enable user+password */
+
+        if(*userpass != ':') {
+          /* the name is given, get user+password */
+          sscanf(userpass, "%127[^:@]:%127[^@]",
+                 data->state.user, data->state.passwd);
+        }
+        else
+          /* no name given, get the password only */
+          sscanf(userpass, ":%127[^@]", data->state.passwd);
+
+        if(data->state.user[0]) {
+          char *newname=curl_unescape(data->state.user, 0);
+          if(strlen(newname) < sizeof(data->state.user)) {
+            strcpy(data->state.user, newname);
+          }
+          /* if the new name is longer than accepted, then just use
+             the unconverted name, it'll be wrong but what the heck */
+          free(newname);
+        }
+        if (data->state.passwd[0]) {
+          /* we have a password found in the URL, decode it! */
+          char *newpasswd=curl_unescape(data->state.passwd, 0);
+          if(strlen(newpasswd) < sizeof(data->state.passwd)) {
+            strcpy(data->state.passwd, newpasswd);
+          }
+          free(newpasswd);
+        }
+      }
+    }
+  }
+
+  /* Programmatically set password:
+   *   - always applies, if available
+   *   - takes precedence over the values we just set above
+   * so scribble it over the top.
+   * User-supplied passwords are assumed not to need unescaping.
+   *
+   * user_password is set in "inherite initial knowledge' above,
+   * so it doesn't have to be set in this block
+   */
+  if (data->set.userpwd != NULL) {
+    if(*data->set.userpwd != ':') {
+      /* the name is given, get user+password */
+      sscanf(data->set.userpwd, "%127[^:]:%127[^\n]",
+             data->state.user, data->state.passwd);
+    }
+    else
+      /* no name given, get the password only */
+      sscanf(data->set.userpwd+1, "%127[^\n]", data->state.passwd);
+  }
+
+  if (data->set.use_netrc != CURL_NETRC_IGNORED &&
+      data->state.passwd[0] == '\0' ) {  /* need passwd */
+    if(Curl_parsenetrc(conn->hostname,
+                       data->state.user,
+                       data->state.passwd)) {
+      infof(data, "Couldn't find host %s in the .netrc file, using defaults",
+            conn->hostname);
+    } else
+      conn->bits.user_passwd = 1; /* enable user+password */
+  }
+
+  /* if we have a user but no password, ask for one */
+  if(conn->bits.user_passwd &&
+     !data->state.passwd[0] ) {
+    if(data->set.fpasswd(data->set.passwd_client,
+                         "password:", data->state.passwd,
+                         sizeof(data->state.passwd)))
+      return CURLE_BAD_PASSWORD_ENTERED;
+  }
+
+  /* So we could have a password but no user; that's just too bad. */
+
+  /* If our protocol needs a password and we have none, use the defaults */
+  if ( (conn->protocol & (PROT_FTP|PROT_HTTP)) &&
+       !conn->bits.user_passwd) {
+    strcpy(data->state.user, CURL_DEFAULT_USER);
+    strcpy(data->state.passwd, CURL_DEFAULT_PASSWORD);
+    /* This is the default password, so DON'T set conn->bits.user_passwd */
+  }
+
+  /*************************************************************
    * Check the current list of connections to see if we can
    * re-use an already existing one or if we have to create a
    * new one.
@@ -1988,6 +2557,10 @@ static CURLcode CreateConnection(struct SessionHandle *data,
       free(old_conn->proxyhost);
     conn = conn_temp;        /* use this connection from now on */
 
+    /* If we speak over a proxy, we need to copy the host name too, as it
+       might be another remote host even when re-using a connection */
+    strcpy(conn->gname, old_conn->gname); /* safe strcpy() */
+
     /* we need these pointers if we speak over a proxy */
     conn->hostname = conn->gname;
     conn->name = &conn->gname[old_conn->name - old_conn->gname];
@@ -2044,7 +2617,7 @@ static CURLcode CreateConnection(struct SessionHandle *data,
   /*************************************************************
    * Set timeout if that is being used
    *************************************************************/
-  if(data->set.timeout || data->set.connecttimeout) {
+  if((data->set.timeout || data->set.connecttimeout) && !data->set.no_signal) {
     /*************************************************************
      * Set signal handler to catch SIGALRM
      * Store the old value to be able to set it back later!
@@ -2089,33 +2662,31 @@ static CURLcode CreateConnection(struct SessionHandle *data,
   /*************************************************************
    * Resolve the name of the server or proxy
    *************************************************************/
-  if(!data->change.proxy) {
+  if(conn->bits.reuse) {
+    /* re-used connection, no resolving is necessary */
+    hostaddr = NULL;
+  }
+  else if(!data->change.proxy || !*data->change.proxy) {
     /* If not connecting via a proxy, extract the port from the URL, if it is
      * there, thus overriding any defaults that might have been set above. */
     conn->port =  conn->remote_port; /* it is the same port */
 
     /* Resolve target host right on */
-    if(!conn->hostaddr) {
-      /* it might already be set if reusing a connection */
-      conn->hostaddr = Curl_resolv(data, conn->name, conn->port,
-                                   &conn->hostent_buf);
-    }
-    if(!conn->hostaddr) {
+    hostaddr = Curl_resolv(data, conn->name, conn->port);
+
+    if(!hostaddr) {
       failf(data, "Couldn't resolve host '%s'", conn->name);
       result =  CURLE_COULDNT_RESOLVE_HOST;
       /* don't return yet, we need to clean up the timeout first */
     }
   }
-  else if(!conn->hostaddr) {
-    /* This is a proxy that hasn't been resolved yet. It may be resolved
-       if we're reusing an existing connection. */
+  else {
+    /* This is a proxy that hasn't been resolved yet. */
 
     /* resolve proxy */
-    /* it might already be set if reusing a connection */
-    conn->hostaddr = Curl_resolv(data, conn->proxyhost, conn->port,
-                                 &conn->hostent_buf);
+    hostaddr = Curl_resolv(data, conn->proxyhost, conn->port);
 
-    if(!conn->hostaddr) {
+    if(!hostaddr) {
       failf(data, "Couldn't resolve proxy '%s'", conn->proxyhost);
       result = CURLE_COULDNT_RESOLVE_PROXY;
       /* don't return yet, we need to clean up the timeout first */
@@ -2123,7 +2694,7 @@ static CURLcode CreateConnection(struct SessionHandle *data,
   }
   Curl_pgrsTime(data, TIMER_NAMELOOKUP);
 #ifdef HAVE_ALARM
-  if(data->set.timeout || data->set.connecttimeout) {
+  if((data->set.timeout || data->set.connecttimeout) && !data->set.no_signal) {
 #ifdef HAVE_SIGACTION
     if(keep_copysig) {
       /* we got a struct as it looked before, now put that one back nice
@@ -2185,7 +2756,8 @@ static CURLcode CreateConnection(struct SessionHandle *data,
    * Send user-agent to HTTP proxies even if the target protocol
    * isn't HTTP.
    *************************************************************/
-  if((conn->protocol&PROT_HTTP) || data->change.proxy) {
+  if((conn->protocol&PROT_HTTP) ||
+     (data->change.proxy && *data->change.proxy)) {
     if(data->set.useragent) {
       if(conn->allocptr.uagent)
         free(conn->allocptr.uagent);
@@ -2194,68 +2766,36 @@ static CURLcode CreateConnection(struct SessionHandle *data,
     }
   }
 
-  if(-1 == conn->firstsocket) {
-    /* Connect only if not already connected! */
-    result = ConnectPlease(conn);
-    if(CURLE_OK != result)
-      return result;
-
-    if(conn->curl_connect) {
-      /* is there a connect() procedure? */
-
-      /* set start time here for timeout purposes in the
-       * connect procedure, it is later set again for the
-       * progress meter purpose */
-      conn->now = Curl_tvnow();
-
-      /* Call the protocol-specific connect function */
-      result = conn->curl_connect(conn);
-      if(result != CURLE_OK)
-        return result; /* pass back errors */
-    }
+  if(data->set.encoding) {
+    if(conn->allocptr.accept_encoding)
+      free(conn->allocptr.accept_encoding);
+    conn->allocptr.accept_encoding =
+      aprintf("Accept-Encoding: %s\015\012", data->set.encoding);
   }
 
-  Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected */
-
-  conn->now = Curl_tvnow(); /* time this *after* the connect is done */
   conn->bytecount = 0;
   conn->headerbytecount = 0;
   
-  /* Figure out the ip-number and display the first host name it shows: */
-#ifdef ENABLE_IPV6
-  {
-    char hbuf[NI_MAXHOST];
-#ifdef NI_WITHSCOPEID
-    const int niflags = NI_NUMERICHOST | NI_WITHSCOPEID;
-#else
-    const int niflags = NI_NUMERICHOST;
-#endif
-    struct addrinfo *ai = conn->serv_addr;
+  if(-1 == conn->firstsocket) {
+    bool connected;
 
-    if (getnameinfo(ai->ai_addr, ai->ai_addrlen, hbuf, sizeof(hbuf), NULL, 0,
-        niflags)) {
-      snprintf(hbuf, sizeof(hbuf), "?");
-    }
-    if (ai->ai_canonname) {
-      infof(data, "Connected to %s (%s) port %d\n", ai->ai_canonname, hbuf,
-            conn->port);
-    } else {
-      infof(data, "Connected to %s port %d\n", hbuf, conn->port);
-    }
+    /* Connect only if not already connected! */
+    result = ConnectPlease(conn, hostaddr, &connected);
+
+    if(connected)
+      result = Curl_protocol_connect(conn, hostaddr);
+
+    if(CURLE_OK != result)
+      return result;
   }
-#else
-  {
-    struct in_addr in;
-    (void) memcpy(&in.s_addr, &conn->serv_addr.sin_addr, sizeof (in.s_addr));
-    infof(data, "Connected to %s (%s)\n", conn->hostaddr->h_name,
-#if defined(HAVE_INET_NTOA_R)
-          inet_ntoa_r(in, ntoa_buf, sizeof(ntoa_buf))
-#else
-          inet_ntoa(in)
-#endif
-          );
+  else {
+    Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected already */
+    if(data->set.verbose)
+      verboseconnect(conn, hostaddr);
   }
-#endif
+
+  conn->now = Curl_tvnow(); /* time this *after* the connect is done, we
+                               set this here perhaps a second time */
 
 #ifdef __EMX__
   /* 20000330 mgs
@@ -2293,7 +2833,6 @@ CURLcode Curl_connect(struct SessionHandle *data,
   return code;
 }
 
-
 CURLcode Curl_done(struct connectdata *conn)
 {
   struct SessionHandle *data=conn->data;
@@ -2311,7 +2850,16 @@ CURLcode Curl_done(struct connectdata *conn)
     free(conn->newurl);
     conn->newurl = NULL;
   }
- 
+
+  if(conn->connect_addr)
+    Curl_resolv_unlock(conn->connect_addr); /* done with this */
+
+#if defined(MALLOCDEBUG) && defined(AGGRESIVE_TEST)
+  /* scan for DNS cache entries still marked as in use */
+  Curl_hash_apply(data->hostcache,
+                  NULL, Curl_scan_cache_used);
+#endif
+
   /* this calls the protocol-specific function pointer previously set */
   if(conn->curl_done)
     result = conn->curl_done(conn);
@@ -2341,13 +2889,15 @@ CURLcode Curl_do(struct connectdata **connp)
   struct connectdata *conn = *connp;
   struct SessionHandle *data=conn->data;
 
+  conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to use */
+
   if(conn->curl_do) {
     /* generic protocol-specific function pointer set in curl_connect() */
     result = conn->curl_do(conn);
 
     /* This was formerly done in transfer.c, but we better do it here */
     
-    if((CURLE_WRITE_ERROR == result) && conn->bits.reuse) {
+    if((CURLE_SEND_ERROR == result) && conn->bits.reuse) {
       /* This was a re-use of a connection and we got a write error in the
        * DO-phase. Then we DISCONNECT this connection and have another attempt
        * to CONNECT and then DO again! The retry cannot possibly find another
@@ -2370,6 +2920,16 @@ CURLcode Curl_do(struct connectdata **connp)
   return result;
 }
 
+CURLcode Curl_do_more(struct connectdata *conn)
+{
+  CURLcode result=CURLE_OK;
+
+  if(conn->curl_do_more)
+    result = conn->curl_do_more(conn);
+
+  return result;
+}
+
 /*
  * local variables:
  * eval: (load-file "../curl-mode.el")
diff --git a/Source/CTest/Curl/url.h b/Source/CTest/Curl/url.h
index de3c02e..2da8ade 100644
--- a/Source/CTest/Curl/url.h
+++ b/Source/CTest/Curl/url.h
@@ -1,27 +1,27 @@
 #ifndef __URL_H
 #define __URL_H
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 
 /*
  * Prototypes for library-wide functions provided by url.c
@@ -32,7 +32,9 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...);
 CURLcode Curl_close(struct SessionHandle *data); /* opposite of curl_open() */
 CURLcode Curl_connect(struct SessionHandle *, struct connectdata **);
 CURLcode Curl_do(struct connectdata **);
+CURLcode Curl_do_more(struct connectdata *);
 CURLcode Curl_done(struct connectdata *);
 CURLcode Curl_disconnect(struct connectdata *);
-
+CURLcode Curl_protocol_connect(struct connectdata *conn,
+                               struct Curl_dns_entry *dns);
 #endif
diff --git a/Source/CTest/Curl/urldata.h b/Source/CTest/Curl/urldata.h
index de318f1..c4cab1a 100644
--- a/Source/CTest/Curl/urldata.h
+++ b/Source/CTest/Curl/urldata.h
@@ -1,33 +1,31 @@
 #ifndef __URLDATA_H
 #define __URLDATA_H
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 
 /* This file is for lib internal stuff */
 
 #include "setup.h"
-#include "hostip.h"
-#include "hash.h"
 
 #define PORT_FTP 21
 #define PORT_TELNET 23
@@ -81,9 +79,15 @@
 #include <curl/curl.h>
 
 #include "http_chunks.h" /* for the structs and enum stuff */
+#include "hostip.h"
+#include "hash.h"
+
+#ifdef HAVE_ZLIB_H
+#include <zlib.h>               /* for content-encoding 08/28/02 jhrg */
+#endif
 
 /* Download buffer size, keep it fairly big for speed reasons */
-#define BUFSIZE (1024*20)
+#define BUFSIZE CURL_MAX_WRITE_SIZE
 
 /* Initial size of the buffer to store headers in, it'll be enlarged in case
    of need. */
@@ -136,14 +140,15 @@ struct ssl_config_data {
   long version;          /* what version the client wants to use */
   long certverifyresult; /* result from the certificate verification */
   long verifypeer;       /* set TRUE if this is desired */
-  long verifyhost;       /* 0: no verif, 1: check that CN exists, 2: CN must match hostname */
+  long verifyhost;       /* 0: no verify
+                            1: check that CN exists
+                            2: CN must match hostname */
   char *CApath;          /* DOES NOT WORK ON WINDOWS */
   char *CAfile;          /* cerficate to verify peer against */
   char *random_file;     /* path to file containing "random" data */
   char *egdsocket;       /* path to file containing the EGD daemon socket */
   char *cipher_list;     /* list of ciphers to use */
-
-  long numsessions;                 /* SSL session id cache size */
+  long numsessions;      /* SSL session id cache size */
 };
 
 /****************************************************************************
@@ -179,7 +184,13 @@ struct FTP {
   char *entrypath; /* the PWD reply when we logged on */
 
   char *cache;       /* data cache between getresponse()-calls */
-  size_t cache_size; /* size of cache in bytes */                    
+  size_t cache_size; /* size of cache in bytes */
+  bool dont_check;  /* Set to TRUE to prevent the final (post-transfer)
+                       file size and 226/250 status check. It should still
+                       read the line, just ignore the result. */
+  bool no_transfer; /* nothing was transfered, (possibly because a resumed
+                       transfer already was complete) */
+
 };
 
 /****************************************************************************
@@ -199,12 +210,18 @@ struct ConnectBits {
   bool httpproxy;    /* if set, this transfer is done through a http proxy */
   bool user_passwd;    /* do we use user+password for this connection? */
   bool proxy_user_passwd; /* user+password for the proxy? */
-
+  bool ipv6_ip; /* we communicate with a remove site specified with pure IPv6
+                   IP address */
   bool use_range;
   bool rangestringalloc; /* the range string is malloc()'ed */
 
-  bool resume_done; /* nothing was transfered, resumed transfer already
-                       complete */
+  bool do_more; /* this is set TRUE if the ->curl_do_more() function is
+                   supposed to be called, after ->curl_do() */
+
+  bool upload_chunky; /* set TRUE if we are doing chunked transfer-encoding
+                         on upload */
+
+  bool getheader;        /* TRUE if header parsing is wanted */
 };
 
 /*
@@ -220,6 +237,13 @@ struct Curl_transfer_keeper {
   struct timeval start;         /* transfer started at this time */
   struct timeval now;           /* current time */
   bool header;                  /* incoming data has HTTP header */
+  enum {
+    HEADER_NORMAL,      /* no bad header at all */
+    HEADER_PARTHEADER,  /* part of the chunk is a bad header, the rest is
+                           normal data */
+    HEADER_ALLBAD       /* all was believed to be header */
+  } badheader;                  /* the header was deemed bad and will be
+                                   written as body */
   int headerline;               /* counts header lines to better track the
                                    first one */
   char *hbufp;                  /* points at *end* of header line */
@@ -236,19 +260,32 @@ struct Curl_transfer_keeper {
   bool write_after_100_header;  /* should we enable the write after
                                    we received a 100-continue/timeout
                                    or directly */
+  int content_encoding;         /* What content encoding. sec 3.5, RFC2616. */
+
+#define IDENTITY 0              /* No encoding */
+#define DEFLATE 1               /* zlib delfate [RFC 1950 & 1951] */
+#define GZIP 2                  /* gzip algorithm [RFC 1952] */
+#define COMPRESS 3              /* Not handled, added for completeness */
+
+#ifdef HAVE_LIBZ
+  bool zlib_init;               /* True if zlib already initialized;
+                                   undefined if Content-Encdoing header. */
+  z_stream z;                   /* State structure for zlib. */
+#endif
 
   /* for the low speed checks: */
   time_t timeofdoc;
   long bodywrites;
   int writetype;
 
-  /* the highest fd we use + 1 */
-  struct SessionHandle *data;
-  struct connectdata *conn;
   char *buf;
   char *uploadbuf;
   int maxfd;
 
+  /* pointers to the actual descriptors we check */
+  fd_set *readfdp;
+  fd_set *writefdp;
+
   /* the file descriptors to play with */
   fd_set readfd;
   fd_set writefd;
@@ -256,6 +293,8 @@ struct Curl_transfer_keeper {
   fd_set wkeepfd;
   int keepon;
 
+  bool upload_done; /* set to TRUE when doing chunked transfer-encoding upload
+                       and we're uploading the last chunk */
 };
 
 
@@ -282,11 +321,11 @@ struct connectdata {
 #define PROT_FTPS    (1<<9)
 #define PROT_SSL     (1<<10) /* protocol requires SSL */
 
-  Curl_addrinfo *hostaddr; /* IP-protocol independent host info pointer list */
-  char *hostent_buf; /* pointer to allocated memory for name info */
+  /* the particular host we use, in two different ways */
+  struct Curl_dns_entry *connect_addr;
 
 #ifdef ENABLE_IPV6
-  struct addrinfo *serv_addr;   /* the particular host we use */
+  struct addrinfo *serv_addr;
 #else
   struct sockaddr_in serv_addr;
 #endif
@@ -324,6 +363,12 @@ struct connectdata {
   CURLcode (*curl_do)(struct connectdata *connect);
   CURLcode (*curl_done)(struct connectdata *connect);
 
+  /* If the curl_do() function is better made in two halves, this
+   * curl_do_more() function will be called afterwards, if set. For example
+   * for doing the FTP stuff after the PASV/PORT command.
+   */
+  CURLcode (*curl_do_more)(struct connectdata *connect);
+
   /* This function *MAY* be set to a protocol-dependent function that is run
    * after the connect() and everything is done, as a step in the connection.
    */ 
@@ -344,7 +389,6 @@ struct connectdata {
   /* READ stuff */
   int sockfd;            /* socket to read from or -1 */
   int size;              /* -1 if unknown at this point */
-  bool getheader;        /* TRUE if header parsing is wanted */
   long *bytecountp;      /* return number of bytes read or NULL */
           
   /* WRITE stuff */
@@ -357,6 +401,7 @@ struct connectdata {
   struct dynamically_allocated_data {
     char *proxyuserpwd; /* free later if not NULL! */
     char *uagent; /* free later if not NULL! */
+    char *accept_encoding; /* free later if not NULL! 08/28/02 jhrg */
     char *userpwd; /* free later if not NULL! */
     char *rangeline; /* free later if not NULL! */
     char *ref; /* free later if not NULL! */
@@ -410,9 +455,11 @@ struct connectdata {
       buffer, so the next read should read from where this pointer points to,
       and the 'upload_present' contains the number of bytes available at this
       position */
-  char *upload_fromhere;                                   
+  char *upload_fromhere;
 };
 
+/* The end of connectdata. 08/27/02 jhrg */
+
 /*
  * Struct to keep statistical and informational data.
  */
@@ -451,6 +498,7 @@ struct Progress {
   double t_connect;
   double t_pretransfer;
   double t_starttransfer;
+  double t_redirect;
 
   struct timeval start;
   struct timeval t_startsingle;
@@ -483,6 +531,12 @@ typedef enum {
 #define MAX_CURL_PASSWORD_LENGTH 256
 
 struct UrlState {
+  enum {
+    Curl_if_none,
+    Curl_if_easy,
+    Curl_if_multi
+  } used_interface;
+
   /* buffers to store authentication data in, as parsed from input options */
   char user[MAX_CURL_USER_LENGTH];
   char passwd[MAX_CURL_PASSWORD_LENGTH];
@@ -542,6 +596,8 @@ struct DynamicStatic {
   bool proxy_alloc; /* http proxy string is malloc()'ed */
   char *referer;    /* referer string */
   bool referer_alloc; /* referer sting is malloc()ed */
+  struct curl_slist *cookielist; /* list of cookie files set by
+                                    curl_easy_setopt(COOKIEFILE) calls */
 };
 
 /*
@@ -553,7 +609,8 @@ struct DynamicStatic {
  */
 
 struct UserDefined {
-  FILE *err;    /* the stderr writes goes here */
+  FILE *err;         /* the stderr user data goes here */
+  void *debugdata;   /* the data that will be passed to fdebug */
   char *errorbuffer; /* store failure messages in here */
   char *proxyuserpwd;  /* Proxy <user:password>, if used */
   long proxyport; /* If non-zero, use this port number by default. If the
@@ -574,6 +631,7 @@ struct UserDefined {
   bool free_referer; /* set TRUE if 'referer' points to a string we
                         allocated */
   char *useragent;   /* User-Agent string */
+  char *encoding;    /* Accept-Encoding string 08/28/02 jhrg */
   char *postfields;  /* if POST, set the fields' values here */
   size_t postfieldsize; /* if POST, this might have a size to use instead of
                            strlen(), and then the data *may* be binary (contain
@@ -584,6 +642,7 @@ struct UserDefined {
   curl_write_callback fwrite_header; /* function that stores headers */
   curl_read_callback fread;          /* function that reads the input */
   curl_progress_callback fprogress;  /* function for progress information */
+  curl_debug_callback fdebug;      /* function that write informational data */
   void *progress_client; /* pointer to pass to the progress callback */
   curl_passwd_callback fpasswd;      /* call for password */
   void *passwd_client;               /* pass to the passwd callback */
@@ -603,6 +662,7 @@ struct UserDefined {
   char *key_passwd;     /* plain text private key password */
   char *crypto_engine;  /* name of the crypto engine to use */
   char *cookiejar;      /* dump all cookies to this file */
+  bool cookiesession;   /* new cookie session? */
   bool crlf;            /* convert crlf on ftp upload(?) */
   struct curl_slist *quote;     /* after connection is established */
   struct curl_slist *postquote; /* after the transfer */
@@ -622,7 +682,10 @@ struct UserDefined {
   char *krb4_level; /* what security level */
   struct ssl_config_data ssl;  /* user defined SSL stuff */
 
+  curl_proxytype proxytype; /* what kind of proxy that is in use */
+
   int dns_cache_timeout; /* DNS cache timeout */
+  long buffer_size;      /* size of receive buffer to use */
   
 /* Here follows boolean settings that define how to behave during
    this session. They are STATIC, set by libcurl users or at least initially
@@ -645,13 +708,15 @@ struct UserDefined {
   bool no_body;
   bool set_port;
   bool upload;
-  bool use_netrc;
+  enum CURL_NETRC_OPTION
+       use_netrc;        /* defined in include/curl.h */
   bool verbose;
   bool krb4;             /* kerberos4 connection requested */
   bool reuse_forbid;     /* forbidden to be reused, close after use */
   bool reuse_fresh;      /* do not re-use an existing connection  */
   bool expect100header;  /* TRUE if we added Expect: 100-continue */
   bool ftp_use_epsv;     /* if EPSV is to be attempted or not */
+  bool no_signal;        /* do not use any signal/alarm handler */
 
   bool global_dns_cache;
 };
@@ -668,7 +733,8 @@ struct UserDefined {
  * 'struct urlstate' instead.  */
 
 struct SessionHandle {
-  curl_hash          *hostcache;
+  curl_hash *hostcache;
+  curl_share *share;           /* Share, handles global variable mutexing */
   struct UserDefined set;      /* values set by the libcurl user */
   struct DynamicStatic change; /* possibly modified userdefined data */
 
diff --git a/Source/CTest/Curl/version.c b/Source/CTest/Curl/version.c
index ecaec67..41a71bf 100644
--- a/Source/CTest/Curl/version.c
+++ b/Source/CTest/Curl/version.c
@@ -1,25 +1,25 @@
-/*****************************************************************************
+/***************************************************************************
  *                                  _   _ ____  _     
  *  Project                     ___| | | |  _ \| |    
  *                             / __| | | | |_) | |    
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2002, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * In order to be useful for every potential user, curl and libcurl are
- * dual-licensed under the MPL and the MIT/X-derivate licenses.
+ * Copyright (C) 1998 - 2002, 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 MPL or the MIT/X-derivate
- * licenses. You may pick one of these licenses.
+ * 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$
- *****************************************************************************/
+ ***************************************************************************/
 
 #include "setup.h"
 
@@ -29,14 +29,9 @@
 #include <curl/curl.h>
 #include "urldata.h"
 
-char *curl_version(void)
-{
-  static char version[200];
-  char *ptr;
-  strcpy(version, LIBCURL_NAME " " LIBCURL_VERSION );
-  ptr=strchr(version, '\0');
-
 #ifdef USE_SSLEAY
+static void getssl_version(char *ptr, long *num)
+{
 
 #if (SSLEAY_VERSION_NUMBER >= 0x905000)
   {
@@ -44,6 +39,7 @@ char *curl_version(void)
     unsigned long ssleay_value;
     sub[1]='\0';
     ssleay_value=SSLeay();
+    *num = ssleay_value;
     if(ssleay_value < 0x906000) {
       ssleay_value=SSLEAY_VERSION_NUMBER;
       sub[0]='\0';
@@ -56,7 +52,7 @@ char *curl_version(void)
         sub[0]='\0';
     }
 
-    sprintf(ptr, " (OpenSSL %lx.%lx.%lx%s)",
+    sprintf(ptr, " OpenSSL/%lx.%lx.%lx%s",
             (ssleay_value>>28)&0xf,
             (ssleay_value>>20)&0xff,
             (ssleay_value>>12)&0xff,
@@ -64,8 +60,9 @@ char *curl_version(void)
   }
 
 #else
+  *num = SSLEAY_VERSION_NUMBER;
 #if (SSLEAY_VERSION_NUMBER >= 0x900000)
-  sprintf(ptr, " (SSL %lx.%lx.%lx)",
+  sprintf(ptr, " OpenSSL/%lx.%lx.%lx",
           (SSLEAY_VERSION_NUMBER>>28)&0xff,
           (SSLEAY_VERSION_NUMBER>>20)&0xff,
           (SSLEAY_VERSION_NUMBER>>12)&0xf);
@@ -79,37 +76,128 @@ char *curl_version(void)
     else
       sub[0]='\0';
 
-    sprintf(ptr, " (SSL %x.%x.%x%s)",
+    sprintf(ptr, " SSL/%x.%x.%x%s",
             (SSLEAY_VERSION_NUMBER>>12)&0xff,
             (SSLEAY_VERSION_NUMBER>>8)&0xf,
             (SSLEAY_VERSION_NUMBER>>4)&0xf, sub);
   }
 #endif
 #endif
-  ptr=strchr(ptr, '\0');
+}
+
+#endif
+
+char *curl_version(void)
+{
+  static char version[200];
+  char *ptr;
+  long num;
+  strcpy(version, LIBCURL_NAME "/" LIBCURL_VERSION );
+  ptr=strchr(version, '\0');
+
+#ifdef USE_SSLEAY
+  getssl_version(ptr, &num);
+  ptr=strchr(version, '\0');
+#else
+  (void)num; /* no compiler warning please */
 #endif
 
-#if defined(KRB4) || defined(ENABLE_IPV6)
-  strcat(ptr, " (");
-  ptr+=2;
 #ifdef KRB4
-  sprintf(ptr, "krb4 ");
+  sprintf(ptr, " krb4");
   ptr += strlen(ptr);
 #endif
 #ifdef ENABLE_IPV6
-  sprintf(ptr, "ipv6 ");
+  sprintf(ptr, " ipv6");
   ptr += strlen(ptr);
 #endif
-  sprintf(ptr, "enabled)");
+#ifdef HAVE_LIBZ
+  sprintf(ptr, " zlib/%s", zlibVersion());
   ptr += strlen(ptr);
 #endif
 
-#ifdef USE_ZLIB
-  sprintf(ptr, " (zlib %s)", zlibVersion());
-  ptr += strlen(ptr);
+  return version;
+}
+
+/* data for curl_version_info */
+
+static const char *protocols[] = {
+#ifndef CURL_DISABLE_FTP
+  "ftp",
+#endif
+#ifndef CURL_DISABLE_GOPHER
+  "gopher",
+#endif
+#ifndef CURL_DISABLE_TELNET
+  "telnet",
+#endif
+#ifndef CURL_DISABLE_DICT
+  "dict",
+#endif
+#ifndef CURL_DISABLE_LDAP
+  "ldap",
+#endif
+#ifndef CURL_DISABLE_HTTP
+  "http",
+#endif
+#ifndef CURL_DISABLE_FILE
+  "file",
 #endif
 
-  return version;
+#ifdef USE_SSLEAY
+#ifndef CURL_DISABLE_HTTP
+  "https",
+#endif
+#ifndef CURL_DISABLE_FTP
+  "ftps",
+#endif
+#endif
+  NULL
+};
+
+static curl_version_info_data version_info = {
+  CURLVERSION_FIRST,
+  LIBCURL_VERSION,
+  LIBCURL_VERSION_NUM,
+  OS, /* as found by configure or set by hand at build-time */
+  0 /* features is 0 by default */
+#ifdef ENABLE_IPV6
+  | CURL_VERSION_IPV6
+#endif
+#ifdef KRB4
+  | CURL_VERSION_KERBEROS4
+#endif
+#ifdef USE_SSLEAY
+  | CURL_VERSION_SSL
+#endif
+#ifdef HAVE_LIBZ
+  | CURL_VERSION_LIBZ
+#endif
+  ,
+  NULL, /* ssl_version */
+  0,    /* ssl_version_num */
+  NULL, /* zlib_version */
+  protocols
+};
+
+curl_version_info_data *curl_version_info(CURLversion stamp)
+{
+#ifdef USE_SSLEAY
+  static char ssl_buffer[80];
+  long num;
+  getssl_version(ssl_buffer, &num);
+
+  version_info.ssl_version = ssl_buffer;
+  version_info.ssl_version_num = num;
+  /* SSL stuff is left zero if undefined */
+#endif
+
+#ifdef HAVE_LIBZ
+  version_info.libz_version = zlibVersion();
+  /* libz left NULL if non-existing */
+#endif
+  (void)stamp; /* avoid compiler warnings, we don't use this */
+
+  return &version_info;
 }
 
 /*
-- 
cgit v0.12