New version of libcurl

This commit is contained in:
Andy Cedilnik 2003-01-09 23:26:37 -05:00
parent 382d0d4474
commit 3ad91bf9d3
79 changed files with 5040 additions and 2427 deletions

View File

@ -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)

View File

@ -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

View File

@ -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
*

View File

@ -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

View File

@ -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 */

View File

@ -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 if you have the <alloca.h> header file. */
#cmakedefine HAVE_ALLOCA_H ${HAVE_ALLOCA_H}
/* Define to 1 if you have the <alloca.h> header file. */
#cmakedefine HAVE_ALLOCA_H ${HAVE_ALLOCA_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 <arpa/inet.h> header file. */
#cmakedefine HAVE_ARPA_INET_H ${HAVE_ARPA_INET_H}
/* Define if you have the `closesocket' function. */
#cmakedefine HAVE_CLOSESOCKET ${HAVE_CLOSESOCKET}
/* Define to 1 if you have the `closesocket' function. */
#cmakedefine HAVE_CLOSESOCKET ${HAVE_CLOSESOCKET}
/* Define if you have the <crypto.h> header file. */
#cmakedefine HAVE_CRYPTO_H ${HAVE_CRYPTO_H}
/* Define to 1 if you have the <crypto.h> header file. */
#cmakedefine HAVE_CRYPTO_H ${HAVE_CRYPTO_H}
/* Define if you have the <des.h> header file. */
#cmakedefine HAVE_DES_H ${HAVE_DES_H}
/* Define to 1 if you have the <des.h> header file. */
#cmakedefine HAVE_DES_H ${HAVE_DES_H}
/* Define if you have the <dlfcn.h> header file. */
#cmakedefine HAVE_DLFCN_H ${HAVE_DLFCN_H}
/* to disable NON-BLOCKING connections */
#cmakedefine HAVE_DISABLED_NONBLOCKING ${HAVE_DISABLED_NONBLOCKING}
/* Define if you have the `dlopen' function. */
#cmakedefine HAVE_DLOPEN ${HAVE_DLOPEN}
/* Define to 1 if you have the <dlfcn.h> header file. */
#cmakedefine HAVE_DLFCN_H ${HAVE_DLFCN_H}
/* Define if you have the <err.h> header file. */
#cmakedefine HAVE_ERR_H ${HAVE_ERR_H}
/* Define to 1 if you have the `dlopen' function. */
#cmakedefine HAVE_DLOPEN ${HAVE_DLOPEN}
/* Define if you have the <fcntl.h> header file. */
#cmakedefine HAVE_FCNTL_H ${HAVE_FCNTL_H}
/* Define to 1 if you have the <err.h> header file. */
#cmakedefine HAVE_ERR_H ${HAVE_ERR_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 if you have the <malloc.h> header file. */
#cmakedefine HAVE_MALLOC_H ${HAVE_MALLOC_H}
/* Define to 1 if you have the `localtime_r' function. */
#cmakedefine HAVE_LOCALTIME_R ${HAVE_LOCALTIME_R}
/* Define if you have the <memory.h> header file. */
#cmakedefine HAVE_MEMORY_H ${HAVE_MEMORY_H}
/* Define to 1 if you have the <malloc.h> header file. */
#cmakedefine HAVE_MALLOC_H ${HAVE_MALLOC_H}
/* Define if you have the <netdb.h> header file. */
#cmakedefine HAVE_NETDB_H ${HAVE_NETDB_H}
/* Define to 1 if you have the <memory.h> header file. */
#cmakedefine HAVE_MEMORY_H ${HAVE_MEMORY_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 <netdb.h> header file. */
#cmakedefine HAVE_NETDB_H ${HAVE_NETDB_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 <netinet/if_ether.h> header file. */
#cmakedefine HAVE_NETINET_IF_ETHER_H ${HAVE_NETINET_IF_ETHER_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 <netinet/in.h> header file. */
#cmakedefine HAVE_NETINET_IN_H ${HAVE_NETINET_IN_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 <net/if.h> header file. */
#cmakedefine HAVE_NET_IF_H ${HAVE_NET_IF_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/crypto.h> header file. */
#cmakedefine HAVE_OPENSSL_CRYPTO_H ${HAVE_OPENSSL_CRYPTO_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 <openssl/engine.h> header file. */
#cmakedefine HAVE_OPENSSL_ENGINE_H ${HAVE_OPENSSL_ENGINE_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 <openssl/err.h> header file. */
#cmakedefine HAVE_OPENSSL_ERR_H ${HAVE_OPENSSL_ERR_H}
/* 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 <openssl/pem.h> header file. */
#cmakedefine HAVE_OPENSSL_PEM_H ${HAVE_OPENSSL_PEM_H}
/* 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 <openssl/rsa.h> header file. */
#cmakedefine HAVE_OPENSSL_RSA_H ${HAVE_OPENSSL_RSA_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 <openssl/ssl.h> header file. */
#cmakedefine HAVE_OPENSSL_SSL_H ${HAVE_OPENSSL_SSL_H}
/* Define if you have the <pem.h> header file. */
#cmakedefine HAVE_PEM_H ${HAVE_PEM_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 `perror' function. */
#cmakedefine HAVE_PERROR ${HAVE_PERROR}
/* Define to 1 if you have the <pem.h> header file. */
#cmakedefine HAVE_PEM_H ${HAVE_PEM_H}
/* Define if you have the <pwd.h> header file. */
#cmakedefine HAVE_PWD_H ${HAVE_PWD_H}
/* Define to 1 if you have the `perror' function. */
#cmakedefine HAVE_PERROR ${HAVE_PERROR}
/* Define if you have the `RAND_egd' function. */
#cmakedefine HAVE_RAND_EGD ${HAVE_RAND_EGD}
/* Define to 1 if you have the `poll' function. */
#cmakedefine HAVE_POLL ${HAVE_POLL}
/* Define if you have the `RAND_screen' function. */
#cmakedefine HAVE_RAND_SCREEN ${HAVE_RAND_SCREEN}
/* Define to 1 if you have the <pwd.h> header file. */
#cmakedefine HAVE_PWD_H ${HAVE_PWD_H}
/* Define if you have the `RAND_status' function. */
#cmakedefine HAVE_RAND_STATUS ${HAVE_RAND_STATUS}
/* Define to 1 if you have the `RAND_egd' function. */
#cmakedefine HAVE_RAND_EGD ${HAVE_RAND_EGD}
/* Define if you have the <rsa.h> header file. */
#cmakedefine HAVE_RSA_H ${HAVE_RSA_H}
/* Define to 1 if you have the `RAND_screen' function. */
#cmakedefine HAVE_RAND_SCREEN ${HAVE_RAND_SCREEN}
/* Define if you have the `select' function. */
#cmakedefine HAVE_SELECT ${HAVE_SELECT}
/* Define to 1 if you have the `RAND_status' function. */
#cmakedefine HAVE_RAND_STATUS ${HAVE_RAND_STATUS}
/* Define if you have the `setvbuf' function. */
#cmakedefine HAVE_SETVBUF ${HAVE_SETVBUF}
/* Define to 1 if you have the <rsa.h> header file. */
#cmakedefine HAVE_RSA_H ${HAVE_RSA_H}
/* Define if you have the <sgtty.h> header file. */
#cmakedefine HAVE_SGTTY_H ${HAVE_SGTTY_H}
/* Define to 1 if you have the `select' function. */
#cmakedefine HAVE_SELECT ${HAVE_SELECT}
/* Define if you have the `sigaction' function. */
#cmakedefine HAVE_SIGACTION ${HAVE_SIGACTION}
/* Define to 1 if you have the <setjmp.h> header file. */
#cmakedefine HAVE_SETJMP_H ${HAVE_SETJMP_H}
/* Define if you have the `signal' function. */
#cmakedefine HAVE_SIGNAL ${HAVE_SIGNAL}
/* Define to 1 if you have the `setvbuf' function. */
#cmakedefine HAVE_SETVBUF ${HAVE_SETVBUF}
/* Define if you have the `socket' function. */
#cmakedefine HAVE_SOCKET ${HAVE_SOCKET}
/* Define to 1 if you have the <sgtty.h> header file. */
#cmakedefine HAVE_SGTTY_H ${HAVE_SGTTY_H}
/* Define if you have the <ssl.h> header file. */
#cmakedefine HAVE_SSL_H ${HAVE_SSL_H}
/* Define to 1 if you have the `sigaction' function. */
#cmakedefine HAVE_SIGACTION ${HAVE_SIGACTION}
/* Define if you have the <stdint.h> header file. */
#cmakedefine HAVE_STDINT_H ${HAVE_STDINT_H}
/* Define to 1 if you have the `signal' function. */
#cmakedefine HAVE_SIGNAL ${HAVE_SIGNAL}
/* Define if you have the <stdlib.h> header file. */
#cmakedefine HAVE_STDLIB_H ${HAVE_STDLIB_H}
/* If you have sigsetjmp */
#cmakedefine HAVE_SIGSETJMP ${HAVE_SIGSETJMP}
/* Define if you have the `strcasecmp' function. */
#cmakedefine HAVE_STRCASECMP ${HAVE_STRCASECMP}
/* Define to 1 if you have the `socket' function. */
#cmakedefine HAVE_SOCKET ${HAVE_SOCKET}
/* Define if you have the `strcmpi' function. */
#cmakedefine HAVE_STRCMPI ${HAVE_STRCMPI}
/* Define to 1 if you have the <ssl.h> header file. */
#cmakedefine HAVE_SSL_H ${HAVE_SSL_H}
/* Define if you have the `strdup' function. */
#cmakedefine HAVE_STRDUP ${HAVE_STRDUP}
/* Define to 1 if you have the <stdint.h> header file. */
#cmakedefine HAVE_STDINT_H ${HAVE_STDINT_H}
/* Define if you have the `strftime' function. */
#cmakedefine HAVE_STRFTIME ${HAVE_STRFTIME}
/* Define to 1 if you have the <stdlib.h> header file. */
#cmakedefine HAVE_STDLIB_H ${HAVE_STDLIB_H}
/* Define if you have the `stricmp' function. */
#cmakedefine HAVE_STRICMP ${HAVE_STRICMP}
/* Define to 1 if you have the `strcasecmp' function. */
#cmakedefine HAVE_STRCASECMP ${HAVE_STRCASECMP}
/* Define if you have the <strings.h> header file. */
#cmakedefine HAVE_STRINGS_H ${HAVE_STRINGS_H}
/* Define to 1 if you have the `strcmpi' function. */
#cmakedefine HAVE_STRCMPI ${HAVE_STRCMPI}
/* Define if you have the <string.h> header file. */
#cmakedefine HAVE_STRING_H ${HAVE_STRING_H}
/* Define to 1 if you have the `strdup' function. */
#cmakedefine HAVE_STRDUP ${HAVE_STRDUP}
/* Define if you have the `strlcat' function. */
#cmakedefine HAVE_STRLCAT ${HAVE_STRLCAT}
/* Define to 1 if you have the `strftime' function. */
#cmakedefine HAVE_STRFTIME ${HAVE_STRFTIME}
/* Define if you have the `strlcpy' function. */
#cmakedefine HAVE_STRLCPY ${HAVE_STRLCPY}
/* Define to 1 if you have the `stricmp' function. */
#cmakedefine HAVE_STRICMP ${HAVE_STRICMP}
/* Define if you have the `strstr' function. */
#cmakedefine HAVE_STRSTR ${HAVE_STRSTR}
/* Define to 1 if you have the <strings.h> header file. */
#cmakedefine HAVE_STRINGS_H ${HAVE_STRINGS_H}
/* Define if you have the `strtok_r' function. */
#cmakedefine HAVE_STRTOK_R ${HAVE_STRTOK_R}
/* Define to 1 if you have the <string.h> header file. */
#cmakedefine HAVE_STRING_H ${HAVE_STRING_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 `strlcat' function. */
#cmakedefine HAVE_STRLCAT ${HAVE_STRLCAT}
/* 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 `strlcpy' function. */
#cmakedefine HAVE_STRLCPY ${HAVE_STRLCPY}
/* 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 `strstr' function. */
#cmakedefine HAVE_STRSTR ${HAVE_STRSTR}
/* 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 `strtok_r' function. */
#cmakedefine HAVE_STRTOK_R ${HAVE_STRTOK_R}
/* 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/param.h> header file. */
#cmakedefine HAVE_SYS_PARAM_H ${HAVE_SYS_PARAM_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/poll.h> header file. */
#cmakedefine HAVE_SYS_POLL_H ${HAVE_SYS_POLL_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/select.h> header file. */
#cmakedefine HAVE_SYS_SELECT_H ${HAVE_SYS_SELECT_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 <sys/socket.h> header file. */
#cmakedefine HAVE_SYS_SOCKET_H ${HAVE_SYS_SOCKET_H}
/* Define if you have the `tcgetattr' function. */
#cmakedefine HAVE_TCGETATTR ${HAVE_TCGETATTR}
/* 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 `tcsetattr' function. */
#cmakedefine HAVE_TCSETATTR ${HAVE_TCSETATTR}
/* 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 <termios.h> header file. */
#cmakedefine HAVE_TERMIOS_H ${HAVE_TERMIOS_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 <termio.h> header file. */
#cmakedefine HAVE_TERMIO_H ${HAVE_TERMIO_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 <time.h> header file. */
#cmakedefine HAVE_TIME_H ${HAVE_TIME_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 `uname' function. */
#cmakedefine HAVE_UNAME ${HAVE_UNAME}
/* Define to 1 if you have the `tcgetattr' function. */
#cmakedefine HAVE_TCGETATTR ${HAVE_TCGETATTR}
/* Define if you have the <unistd.h> header file. */
#cmakedefine HAVE_UNISTD_H ${HAVE_UNISTD_H}
/* Define to 1 if you have the `tcsetattr' function. */
#cmakedefine HAVE_TCSETATTR ${HAVE_TCSETATTR}
/* Define if you have the `utime' function. */
#cmakedefine HAVE_UTIME ${HAVE_UTIME}
/* Define to 1 if you have the <termios.h> header file. */
#cmakedefine HAVE_TERMIOS_H ${HAVE_TERMIOS_H}
/* Define if you have the <utime.h> header file. */
#cmakedefine HAVE_UTIME_H ${HAVE_UTIME_H}
/* Define to 1 if you have the <termio.h> header file. */
#cmakedefine HAVE_TERMIO_H ${HAVE_TERMIO_H}
/* Define if you have the <winsock.h> header file. */
#cmakedefine HAVE_WINSOCK_H ${HAVE_WINSOCK_H}
/* Define to 1 if you have the <time.h> header file. */
#cmakedefine HAVE_TIME_H ${HAVE_TIME_H}
/* Define if you have the <x509.h> header file. */
#cmakedefine HAVE_X509_H ${HAVE_X509_H}
/* Define to 1 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 to 1 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 to 1 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}
/* 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. */

View File

@ -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)
@ -329,6 +342,72 @@ int socketerror(int sockfd)
return err;
}
/*
* 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
@ -336,15 +415,17 @@ int socketerror(int sockfd)
*/
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 */

View File

@ -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

View File

@ -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
*/

View File

@ -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
*/

View File

@ -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")

View File

@ -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 *);

View File

@ -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

View File

@ -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

View File

@ -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>

View File

@ -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;

View File

@ -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"

View File

@ -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

View File

@ -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) {

View File

@ -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")

View File

@ -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. */

View File

@ -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

View File

@ -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

View File

@ -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;
}
/* CMC: Added support for buffer uploads */
case CURLFORM_BUFFER:
{
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
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:
{
const char *contenttype = NULL;
if (array_state)
contenttype = array_value;
else
contenttype = va_arg(params, const char *);
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")

View File

@ -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,

View File

@ -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().
memset(hostent_buf, 0, sizeof(struct hostent));
... as must be struct hostent_data Craig Markwardt 19 Sep 2002. */
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;
}
/***********************************************************************
/*
* Curl_ftp_nextconnect()
*
* ftp_perform()
*
* 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;
}
@ -1988,6 +1901,128 @@ CURLcode ftp_perform(struct connectdata *conn)
return CURLE_OK;
}
/***********************************************************************
*
* 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()
@ -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);
retcode = ftp_perform(conn, &connected);
/* clean up here, success or error doesn't matter */
if(ftp->file)
free(ftp->file);
if(ftp->dir)
free(ftp->dir);
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 */

View File

@ -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

View File

@ -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"

View File

@ -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;

View File

@ -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);

View File

@ -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 */

View File

@ -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. */

View File

@ -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;
char *end = (char *) key + key_length;
unsigned long h = 5381;
while (p < end) {
h = (h << 4) + *p++;
if ((g = (h & 0xF0000000))) {
h = h ^ (g >> 24);
h = h ^ g;
}
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; \
}
#define MIN(a, b) (a > b ? b : a)
/* {{{ static int _hash_key_compare (char *, size_t, char *, size_t)
*/
static int
curl_hash_key_compare(curl_hash_key *key1, curl_hash_key *key2)
_hash_key_compare (char *key1, size_t key1_len, char *key2, size_t key2_len)
{
if (key1->type == CURL_HASH_KEY_IS_NUM) {
if (key2->type == CURL_HASH_KEY_IS_STRING)
return 0;
if (key1->value.num == key2->value.num)
return 1;
} else {
if (key2->type == CURL_HASH_KEY_IS_NUM)
return 0;
if (memcmp(key1->value.str.val, key2->value.str.val,
MIN(key1->value.str.len, key2->value.str.len)) == 0)
return 1;
if (key1_len == key2_len &&
*key1 == *key2 &&
memcmp(key1, key2, key1_len) == 0) {
return 1;
}
return 0;
}
/* }}} */
int
curl_hash_add_or_update(curl_hash *h, char *str_key, unsigned int str_key_len,
unsigned long num_key, const void *p)
/* {{{ 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)
{
curl_hash_element *e;
curl_hash_key tmp;
curl_llist *l;
curl_llist_element *le;
int slot;
*e = (curl_hash_element *) malloc(sizeof(curl_hash_element));
(*e)->key = strdup(key);
(*e)->key_len = key_len;
(*e)->ptr = (void *) p;
return 0;
}
/* }}} */
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;
#define find_slot(__h, __k, __k_len) (_hash_str(__k, __k_len) % (__h)->slots)
#define FETCH_LIST \
curl_llist *l = h->table[find_slot(h, key, key_len)]
/* {{{ int curl_hash_add (curl_hash *, char *, size_t, const void *)
*/
int
Curl_hash_add (curl_hash *h, char *key, size_t key_len, const void *p)
{
curl_hash_element *he;
curl_llist_element *le;
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;
FETCH_LIST;
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);
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;
curl_hash_element *he;
FETCH_LIST;
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;
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;
}
/* }}} */
/* {{{ 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);
}
}
size_t
curl_hash_count(curl_hash *h)
/* {{{ 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:

View File

@ -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
*/

View File

@ -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;
}
/* Macro to save redundant free'ing of entry_id */
#define _hostcache_return(__v) \
{ \
free(entry_id); \
return (__v); \
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;
}
Curl_addrinfo *Curl_resolv(struct SessionHandle *data,
char *hostname,
int port,
char **bufp)
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(dns) \
{ \
free(entry_id); \
return dns; \
}
#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;
char *bufp;
/* 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);
#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);
}
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);
/* Create a new cache entry */
p = (struct curl_dns_cache_entry *) malloc(sizeof(struct curl_dns_cache_entry));
if (!p) {
_hostcache_return(NULL);
}
dns->timestamp = now;
dns->inuse++; /* mark entry as in-use */
#ifdef MALLOCDEBUG
dns->entry_id = entry_id;
#endif
p->addr = Curl_getaddrinfo(data, hostname, port, bufp);
if (!p->addr) {
free(p);
_hostcache_return(NULL);
}
p->timestamp = now;
/* Remove outdated and unused entries from the hostcache */
hostcache_prune(data->hostcache,
data->set.dns_cache_timeout,
now);
/* Save it in our host cache */
curl_hash_update(data->hostcache, entry_id, entry_len+1, (const void *) p);
_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;
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 = (struct hostent*)buf;
h->h_addr_list = (char**)(buf + sizeof(*h));
addrentry = (struct in_addr*)(h->h_addr_list + 2);
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);

View File

@ -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);

View File

@ -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 */
break;
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! */
}
case HTTPREQ_POST:
/* this is the simple POST, using x-www-form-urlencoded style */
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)) );
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) );
if(!checkheaders(data, "Content-Type:"))
add_bufferf(req_buffer,
"Content-Type: application/x-www-form-urlencoded\r\n");
if(!checkheaders(data, "Content-Type:"))
add_bufferf(req_buffer,
"Content-Type: application/x-www-form-urlencoded\r\n");
/* 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 );
}
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
add_buffer(req_buffer, "\r\n", 2);
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
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

View File

@ -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

View File

@ -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 */

View File

@ -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;

View File

@ -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"

View File

@ -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__)

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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);

View File

@ -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)

View File

@ -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);

View File

@ -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__)

View File

@ -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)

View File

@ -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:

View File

@ -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);
}

View File

@ -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

View File

@ -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 =

View File

@ -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);

View File

@ -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:

View File

@ -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 */

View File

@ -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;
struct curl_slist *item;
/* if caller passed us a NULL, return now */
if (!list)
return NULL;
/* 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;
/* 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;
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;
}
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 (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;
/* 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:

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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"

View File

@ -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

View File

@ -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);

View File

@ -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"

View File

@ -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);

View File

@ -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"

View File

@ -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

View File

@ -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) {
readfd = keepfd; /* set this every lap in the loop */
struct timeval interval;
switch (select (sockfd + 1, &readfd, NULL, NULL, NULL)) {
readfd = keepfd; /* set this every lap in the loop */
interval.tv_sec = 1;
interval.tv_usec = 0;
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

View File

@ -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

View File

@ -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

View File

@ -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"

File diff suppressed because it is too large Load Diff

View File

@ -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,

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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 */

View File

@ -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,39 +76,130 @@ 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)");
ptr += strlen(ptr);
#endif
#ifdef USE_ZLIB
sprintf(ptr, " (zlib %s)", zlibVersion());
#ifdef HAVE_LIBZ
sprintf(ptr, " zlib/%s", zlibVersion());
ptr += strlen(ptr);
#endif
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
#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;
}
/*
* local variables:
* eval: (load-file "../curl-mode.el")