summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Source/CTest/Curl/CMakeLists.txt19
-rw-r--r--Source/CTest/Curl/arpa_telnet.h20
-rw-r--r--Source/CTest/Curl/base64.c16
-rw-r--r--Source/CTest/Curl/base64.h16
-rw-r--r--Source/CTest/Curl/ca-bundle.h31
-rw-r--r--Source/CTest/Curl/config.h.in545
-rw-r--r--Source/CTest/Curl/connect.c195
-rw-r--r--Source/CTest/Curl/connect.h27
-rw-r--r--Source/CTest/Curl/content_encoding.c122
-rw-r--r--Source/CTest/Curl/content_encoding.h34
-rw-r--r--Source/CTest/Curl/cookie.c106
-rw-r--r--Source/CTest/Curl/cookie.h23
-rw-r--r--Source/CTest/Curl/curl/curl.h351
-rw-r--r--Source/CTest/Curl/curl/easy.h16
-rw-r--r--Source/CTest/Curl/curl/stdcheaders.h16
-rw-r--r--Source/CTest/Curl/curl/types.h16
-rw-r--r--Source/CTest/Curl/dict.c16
-rw-r--r--Source/CTest/Curl/dict.h19
-rw-r--r--Source/CTest/Curl/easy.c23
-rw-r--r--Source/CTest/Curl/escape.c40
-rw-r--r--Source/CTest/Curl/escape.h16
-rw-r--r--Source/CTest/Curl/file.c36
-rw-r--r--Source/CTest/Curl/file.h18
-rw-r--r--Source/CTest/Curl/formdata.c427
-rw-r--r--Source/CTest/Curl/formdata.h29
-rw-r--r--Source/CTest/Curl/ftp.c520
-rw-r--r--Source/CTest/Curl/ftp.h24
-rw-r--r--Source/CTest/Curl/getenv.c16
-rw-r--r--Source/CTest/Curl/getinfo.c34
-rw-r--r--Source/CTest/Curl/getinfo.h16
-rw-r--r--Source/CTest/Curl/getpass.c56
-rw-r--r--Source/CTest/Curl/getpass.h16
-rw-r--r--Source/CTest/Curl/hash.c311
-rw-r--r--Source/CTest/Curl/hash.h77
-rw-r--r--Source/CTest/Curl/hostip.c396
-rw-r--r--Source/CTest/Curl/hostip.h53
-rw-r--r--Source/CTest/Curl/http.c197
-rw-r--r--Source/CTest/Curl/http.h20
-rw-r--r--Source/CTest/Curl/http_chunks.c47
-rw-r--r--Source/CTest/Curl/http_chunks.h17
-rw-r--r--Source/CTest/Curl/if2ip.c16
-rw-r--r--Source/CTest/Curl/if2ip.h16
-rw-r--r--Source/CTest/Curl/krb4.c6
-rw-r--r--Source/CTest/Curl/krb4.h16
-rw-r--r--Source/CTest/Curl/ldap.c20
-rw-r--r--Source/CTest/Curl/ldap.h19
-rw-r--r--Source/CTest/Curl/llist.c42
-rw-r--r--Source/CTest/Curl/llist.h32
-rw-r--r--Source/CTest/Curl/memdebug.c30
-rw-r--r--Source/CTest/Curl/memdebug.h23
-rw-r--r--Source/CTest/Curl/mprintf.c21
-rw-r--r--Source/CTest/Curl/multi.c297
-rw-r--r--Source/CTest/Curl/netrc.c68
-rw-r--r--Source/CTest/Curl/netrc.h21
-rw-r--r--Source/CTest/Curl/progress.c39
-rw-r--r--Source/CTest/Curl/progress.h18
-rw-r--r--Source/CTest/Curl/security.c2
-rw-r--r--Source/CTest/Curl/security.h16
-rw-r--r--Source/CTest/Curl/sendf.c184
-rw-r--r--Source/CTest/Curl/sendf.h21
-rw-r--r--Source/CTest/Curl/setup.h30
-rw-r--r--Source/CTest/Curl/speedcheck.c16
-rw-r--r--Source/CTest/Curl/speedcheck.h16
-rw-r--r--Source/CTest/Curl/ssluse.c72
-rw-r--r--Source/CTest/Curl/ssluse.h16
-rw-r--r--Source/CTest/Curl/strequal.c16
-rw-r--r--Source/CTest/Curl/strequal.h20
-rw-r--r--Source/CTest/Curl/strtok.c16
-rw-r--r--Source/CTest/Curl/strtok.h16
-rw-r--r--Source/CTest/Curl/telnet.c37
-rw-r--r--Source/CTest/Curl/telnet.h19
-rw-r--r--Source/CTest/Curl/timeval.c66
-rw-r--r--Source/CTest/Curl/timeval.h16
-rw-r--r--Source/CTest/Curl/transfer.c834
-rw-r--r--Source/CTest/Curl/transfer.h19
-rw-r--r--Source/CTest/Curl/url.c1092
-rw-r--r--Source/CTest/Curl/url.h20
-rw-r--r--Source/CTest/Curl/urldata.h124
-rw-r--r--Source/CTest/Curl/version.c146
79 files changed, 5044 insertions, 2431 deletions
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;
}
/*