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) PROJECT(LIBCURL C)
SET(PACKAGE "curl") SET(PACKAGE "curl")
SET(VERSION "7.9.5") SET(VERSION "7.10.2")
SET(PACKAGE_TARNAME " ")
SET(OPERATING_SYSTEM ${CMAKE_SYSTEM_NAME}) SET(OPERATING_SYSTEM ${CMAKE_SYSTEM_NAME})
SET(CMAKE_C_FLAGS "${CMAKE_ANSI_CFLAGS} ${CMAKE_C_FLAGS}") SET(CMAKE_C_FLAGS "${CMAKE_ANSI_CFLAGS} ${CMAKE_C_FLAGS}")
@ -52,6 +53,7 @@ SET(libCurl_SRCS
llist.c llist.c
hash.c hash.c
multi.c multi.c
content_encoding.c
) )
IF(WIN32) IF(WIN32)
@ -86,6 +88,11 @@ IF(HAVE_LIBWS2_32)
SET(CURL_LIBS ${CURL_LIBS} ws2_32) SET(CURL_LIBS ${CURL_LIBS} ws2_32)
ENDIF(HAVE_LIBWS2_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}) SET(CMAKE_REQUIRED_LIBRARIES ${CURL_LIBS})
CHECK_INCLUDE_FILE("sys/types.h" HAVE_SYS_TYPES_H) 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("malloc.h" HAVE_MALLOC_H)
CHECK_INCLUDE_FILE("memory.h" HAVE_MEMORY_H) CHECK_INCLUDE_FILE("memory.h" HAVE_MEMORY_H)
CHECK_INCLUDE_FILE("netdb.h" HAVE_NETDB_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("netinet/in.h" HAVE_NETINET_IN_H)
CHECK_INCLUDE_FILE("sys/socket.h" HAVE_SYS_SOCKET_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("sockio.h" HAVE_SOCKIO_H)
CHECK_INCLUDE_FILE("sys/sockio.h" HAVE_SYS_SOCKIO_H) CHECK_INCLUDE_FILE("sys/sockio.h" HAVE_SYS_SOCKIO_H)
CHECK_INCLUDE_FILE("x509.h" HAVE_X509_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(ssize_t SIZEOF_SSIZE_T)
CHECK_TYPE_SIZE("long double" SIZEOF_LONG_DOUBLE) 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(vprintf HAVE_VPRINTF)
CHECK_FUNCTION_EXISTS(socket HAVE_SOCKET) CHECK_FUNCTION_EXISTS(socket HAVE_SOCKET)
CHECK_FUNCTION_EXISTS(poll HAVE_POLL)
CHECK_FUNCTION_EXISTS(select HAVE_SELECT) CHECK_FUNCTION_EXISTS(select HAVE_SELECT)
CHECK_FUNCTION_EXISTS(strdup HAVE_STRDUP) CHECK_FUNCTION_EXISTS(strdup HAVE_STRDUP)
CHECK_FUNCTION_EXISTS(strstr HAVE_STRSTR) 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(setvbuf HAVE_SETVBUF)
CHECK_FUNCTION_EXISTS(sigaction HAVE_SIGACTION) CHECK_FUNCTION_EXISTS(sigaction HAVE_SIGACTION)
CHECK_FUNCTION_EXISTS(signal HAVE_SIGNAL) 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(getpass_r HAVE_GETPASS_R)
CHECK_FUNCTION_EXISTS(strlcat HAVE_STRLCAT) CHECK_FUNCTION_EXISTS(strlcat HAVE_STRLCAT)
CHECK_FUNCTION_EXISTS(getpwuid HAVE_GETPWUID) CHECK_FUNCTION_EXISTS(getpwuid HAVE_GETPWUID)

View File

@ -1,28 +1,28 @@
#ifndef __ARPA_TELNET_H #ifndef __ARPA_TELNET_H
#define __ARPA_TELNET_H #define __ARPA_TELNET_H
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
#ifndef CURL_DISABLE_TELNET
/* /*
* Telnet option defines. Add more here if in need. * 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) && \ #define TELCMD_OK(x) ( ((unsigned int)(x) >= TELCMD_MINIMUM) && \
((unsigned int)(x) <= TELCMD_MAXIMUM) ) ((unsigned int)(x) <= TELCMD_MAXIMUM) )
#define TELCMD(x) telnetcmds[(x)-TELCMD_MINIMUM] #define TELCMD(x) telnetcmds[(x)-TELCMD_MINIMUM]
#endif
#endif #endif

View File

@ -1,25 +1,25 @@
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2001, Andrew Francis and Daniel Stenberg * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
/* Base64 encoding/decoding /* Base64 encoding/decoding
* *

View File

@ -1,27 +1,27 @@
#ifndef __BASE64_H #ifndef __BASE64_H
#define __BASE64_H #define __BASE64_H
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
int Curl_base64_encode(const void *data, int size, char **str); int Curl_base64_encode(const void *data, int size, char **str);
int Curl_base64_decode(const char *str, void *data); int Curl_base64_decode(const char *str, void *data);
#endif #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! */ /* Name of this package! */
#define PACKAGE "${PACKAGE}" #cmakedefine PACKAGE "${PACKAGE}"
/* Version number of this archive. */ /* Version number of this archive. */
#define VERSION "${VERSION}" #cmakedefine VERSION "${VERSION}"
/* Define if you have the getpass function. */ /* Define if you have the getpass function. */
#cmakedefine HAVE_GETPASS ${HAVE_GETPASS} #cmakedefine HAVE_GETPASS ${HAVE_GETPASS}
/* Define cpu-machine-OS */ /* Define cpu-machine-OS */
#define OS "${OPERATING_SYSTEM}" #define OS "${OPERATING_SYSTEM}"
/* Define if you have the gethostbyaddr_r() function with 5 arguments */ /* 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 */ /* 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 */ /* 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 */ /* 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 */ /* 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 */ /* 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. */ /* Define if you have the inet_ntoa_r function declared. */
#cmakedefine HAVE_INET_NTOA_R_DECL ${HAVE_INET_NTOA_R_DECL} #cmakedefine HAVE_INET_NTOA_R_DECL ${HAVE_INET_NTOA_R_DECL}
@ -36,342 +36,433 @@
#cmakedefine HAVE_GETSERVBYNAME ${HAVE_GETSERVBYNAME} #cmakedefine HAVE_GETSERVBYNAME ${HAVE_GETSERVBYNAME}
/* Define if you need the _REENTRANT define for some functions */ /* 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) */ /* Define if you have the Kerberos4 libraries (including -ldes) */
#cmakedefine KRB4 ${KRB4} #cmakedefine KRB4 ${KRB4}
/* Define if you want to enable IPv6 support */ /* 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 */ /* 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 */ /* 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 */ /* Define this as a suitable file to read random data from */
#cmakedefine RANDOM_FILE "${RANDOM_FILE}" #cmakedefine RANDOM_FILE "${RANDOM_FILE}"
/* Define this to your Entropy Gathering Daemon socket pathname */ /* 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 */ /* 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 */ /* Define the one correct non-blocking socket method below */
#cmakedefine HAVE_FIONBIO ${HAVE_FIONBIO} #cmakedefine HAVE_FIONBIO ${HAVE_FIONBIO}
#cmakedefine HAVE_IOCTLSOCKET ${HAVE_IOCTLSOCKET} #cmakedefine HAVE_IOCTLSOCKET ${HAVE_IOCTLSOCKET}
#cmakedefine HAVE_IOCTLSOCKET_CASE ${HAVE_IOCTLSOCKET_CASE} #cmakedefine HAVE_IOCTLSOCKET_CASE ${HAVE_IOCTLSOCKET_CASE}
#cmakedefine HAVE_O_NONBLOCK ${HAVE_O_NONBLOCK} #cmakedefine HAVE_O_NONBLOCK ${HAVE_O_NONBLOCK}
#cmakedefine HAVE_DISABLED_NONBLOCKING ${HAVE_DISABLED_NONBLOCKING} #cmakedefine HAVE_DISABLED_NONBLOCKING ${HAVE_DISABLED_NONBLOCKING}
/* Define this to 'int' if in_addr_t is not an available typedefed type */ /* 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 */ /* 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 */ /* 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. */ /* Define to 1 if you have the <alloca.h> header file. */
#cmakedefine HAVE_ALLOCA_H ${HAVE_ALLOCA_H} #cmakedefine HAVE_ALLOCA_H ${HAVE_ALLOCA_H}
/* Define if you have the <arpa/inet.h> header file. */ /* Define to 1 if you have the <arpa/inet.h> header file. */
#cmakedefine HAVE_ARPA_INET_H ${HAVE_ARPA_INET_H} #cmakedefine HAVE_ARPA_INET_H ${HAVE_ARPA_INET_H}
/* Define if you have the `closesocket' function. */ /* Define to 1 if you have the `closesocket' function. */
#cmakedefine HAVE_CLOSESOCKET ${HAVE_CLOSESOCKET} #cmakedefine HAVE_CLOSESOCKET ${HAVE_CLOSESOCKET}
/* Define if you have the <crypto.h> header file. */ /* Define to 1 if you have the <crypto.h> header file. */
#cmakedefine HAVE_CRYPTO_H ${HAVE_CRYPTO_H} #cmakedefine HAVE_CRYPTO_H ${HAVE_CRYPTO_H}
/* Define if you have the <des.h> header file. */ /* Define to 1 if you have the <des.h> header file. */
#cmakedefine HAVE_DES_H ${HAVE_DES_H} #cmakedefine HAVE_DES_H ${HAVE_DES_H}
/* Define if you have the <dlfcn.h> header file. */ /* to disable NON-BLOCKING connections */
#cmakedefine HAVE_DLFCN_H ${HAVE_DLFCN_H} #cmakedefine HAVE_DISABLED_NONBLOCKING ${HAVE_DISABLED_NONBLOCKING}
/* Define if you have the `dlopen' function. */ /* Define to 1 if you have the <dlfcn.h> header file. */
#cmakedefine HAVE_DLOPEN ${HAVE_DLOPEN} #cmakedefine HAVE_DLFCN_H ${HAVE_DLFCN_H}
/* Define if you have the <err.h> header file. */ /* Define to 1 if you have the `dlopen' function. */
#cmakedefine HAVE_ERR_H ${HAVE_ERR_H} #cmakedefine HAVE_DLOPEN ${HAVE_DLOPEN}
/* Define if you have the <fcntl.h> header file. */ /* Define to 1 if you have the <err.h> header file. */
#cmakedefine HAVE_FCNTL_H ${HAVE_FCNTL_H} #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 */ /* Define if getaddrinfo exists and works */
#cmakedefine HAVE_GETADDRINFO ${HAVE_GETADDRINFO} #cmakedefine HAVE_GETADDRINFO ${HAVE_GETADDRINFO}
/* Define if you have the `geteuid' function. */ /* Define to 1 if you have the `geteuid' function. */
#cmakedefine HAVE_GETEUID ${HAVE_GETEUID} #cmakedefine HAVE_GETEUID ${HAVE_GETEUID}
/* Define if you have the `gethostbyaddr' function. */ /* Define to 1 if you have the `gethostbyaddr' function. */
#cmakedefine HAVE_GETHOSTBYADDR ${HAVE_GETHOSTBYADDR} #cmakedefine HAVE_GETHOSTBYADDR ${HAVE_GETHOSTBYADDR}
/* Define if you have the `gethostbyaddr_r' function. */ /* Define to 1 if you have the `gethostbyaddr_r' function. */
#cmakedefine HAVE_GETHOSTBYADDR_R ${HAVE_GETHOSTBYADDR_R} #cmakedefine HAVE_GETHOSTBYADDR_R ${HAVE_GETHOSTBYADDR_R}
/* Define if you have the `gethostbyname_r' function. */ /* Define to 1 if you have the `gethostbyname_r' function. */
#cmakedefine HAVE_GETHOSTBYNAME_R ${HAVE_GETHOSTBYNAME_R} #cmakedefine HAVE_GETHOSTBYNAME_R ${HAVE_GETHOSTBYNAME_R}
/* Define if you have the `gethostname' function. */ /* Define to 1 if you have the `getpass_r' function. */
#cmakedefine HAVE_GETHOSTNAME ${HAVE_GETHOSTNAME} #cmakedefine HAVE_GETPASS_R ${HAVE_GETPASS_R}
/* Define if you have the `getpass_r' function. */ /* Define to 1 if you have the `getpwuid' function. */
#cmakedefine HAVE_GETPASS_R ${HAVE_GETPASS_R} #cmakedefine HAVE_GETPWUID ${HAVE_GETPWUID}
/* Define if you have the `getpwuid' function. */ /* Define to 1 if you have the `gettimeofday' function. */
#cmakedefine HAVE_GETPWUID ${HAVE_GETPWUID} #cmakedefine HAVE_GETTIMEOFDAY ${HAVE_GETTIMEOFDAY}
/* Define if you have the `gettimeofday' function. */ /* Define to 1 if you have the `gmtime_r' function. */
#cmakedefine HAVE_GETTIMEOFDAY ${HAVE_GETTIMEOFDAY} #cmakedefine HAVE_GMTIME_R ${HAVE_GMTIME_R}
/* Define if you have the `gmtime_r' function. */ /* Define to 1 if you have the `inet_addr' function. */
#cmakedefine HAVE_GMTIME_R ${HAVE_GMTIME_R} #cmakedefine HAVE_INET_ADDR ${HAVE_INET_ADDR}
/* Define if you have the `inet_addr' function. */ /* Define to 1 if you have the `inet_ntoa' function. */
#cmakedefine HAVE_INET_ADDR ${HAVE_INET_ADDR} #cmakedefine HAVE_INET_NTOA ${HAVE_INET_NTOA}
/* Define if you have the `inet_ntoa' function. */ /* Define to 1 if you have the `inet_ntoa_r' function. */
#cmakedefine HAVE_INET_NTOA ${HAVE_INET_NTOA} #cmakedefine HAVE_INET_NTOA_R ${HAVE_INET_NTOA_R}
/* Define if you have the `inet_ntoa_r' function. */ /* Define to 1 if you have the <inttypes.h> header file. */
#cmakedefine HAVE_INET_NTOA_R ${HAVE_INET_NTOA_R} #cmakedefine HAVE_INTTYPES_H ${HAVE_INTTYPES_H}
/* Define if you have the <inttypes.h> header file. */ /* Define to 1 if you have the <io.h> header file. */
#cmakedefine HAVE_INTTYPES_H ${HAVE_INTTYPES_H} #cmakedefine HAVE_IO_H ${HAVE_IO_H}
/* Define if you have the <io.h> header file. */ /* Define to 1 if you have the `krb_get_our_ip_for_realm' function. */
#cmakedefine HAVE_IO_H ${HAVE_IO_H} #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. */ /* Define to 1 if you have the <krb.h> header file. */
#cmakedefine HAVE_KRB_GET_OUR_IP_FOR_REALM ${HAVE_KRB_GET_OUR_IP_FOR_REALM} #cmakedefine HAVE_KRB_H ${HAVE_KRB_H}
/* Define if you have the <krb.h> header file. */
#cmakedefine HAVE_KRB_H ${HAVE_KRB_H}
/* Define if you have the `crypto' library (-lcrypto). */ /* Define to 1 if you have the `crypto' library (-lcrypto). */
#cmakedefine HAVE_LIBCRYPTO ${HAVE_LIBCRYPTO} #cmakedefine HAVE_LIBCRYPTO ${HAVE_LIBCRYPTO}
/* Define if you have the `dl' library (-ldl). */ /* Define to 1 if you have the `dl' library (-ldl). */
#cmakedefine HAVE_LIBDL ${HAVE_LIBDL} #cmakedefine HAVE_LIBDL ${HAVE_LIBDL}
/* Define if you have the `nsl' library (-lnsl). */ /* Define to 1 if you have the `nsl' library (-lnsl). */
#cmakedefine HAVE_LIBNSL ${HAVE_LIBNSL} #cmakedefine HAVE_LIBNSL ${HAVE_LIBNSL}
/* Define if you have the `resolv' library (-lresolv). */ /* Define to 1 if you have the `resolv' library (-lresolv). */
#cmakedefine HAVE_LIBRESOLV ${HAVE_LIBRESOLV} #cmakedefine HAVE_LIBRESOLV ${HAVE_LIBRESOLV}
/* Define if you have the `resolve' library (-lresolve). */ /* Define to 1 if you have the `resolve' library (-lresolve). */
#cmakedefine HAVE_LIBRESOLVE ${HAVE_LIBRESOLVE} #cmakedefine HAVE_LIBRESOLVE ${HAVE_LIBRESOLVE}
/* Define if you have the `socket' library (-lsocket). */ /* Define to 1 if you have the `socket' library (-lsocket). */
#cmakedefine HAVE_LIBSOCKET ${HAVE_LIBSOCKET} #cmakedefine HAVE_LIBSOCKET ${HAVE_LIBSOCKET}
/* Define if you have the `ssl' library (-lssl). */ /* Define to 1 if you have the `ssl' library (-lssl). */
#cmakedefine HAVE_LIBSSL ${HAVE_LIBSSL} #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} #cmakedefine HAVE_LIBUCB ${HAVE_LIBUCB}
/* Define if you have the `localtime_r' function. */ /* If zlib is available */
#cmakedefine HAVE_LOCALTIME_R ${HAVE_LOCALTIME_R} #cmakedefine HAVE_LIBZ ${HAVE_LIBZ}
/* Define if you have the <malloc.h> header file. */ /* Define to 1 if you have the `localtime_r' function. */
#cmakedefine HAVE_MALLOC_H ${HAVE_MALLOC_H} #cmakedefine HAVE_LOCALTIME_R ${HAVE_LOCALTIME_R}
/* Define if you have the <memory.h> header file. */ /* Define to 1 if you have the <malloc.h> header file. */
#cmakedefine HAVE_MEMORY_H ${HAVE_MEMORY_H} #cmakedefine HAVE_MALLOC_H ${HAVE_MALLOC_H}
/* Define if you have the <netdb.h> header file. */ /* Define to 1 if you have the <memory.h> header file. */
#cmakedefine HAVE_NETDB_H ${HAVE_NETDB_H} #cmakedefine HAVE_MEMORY_H ${HAVE_MEMORY_H}
/* Define if you have the <netinet/if_ether.h> header file. */ /* Define to 1 if you have the <netdb.h> header file. */
#cmakedefine HAVE_NETINET_IF_ETHER_H ${HAVE_NETINET_IF_ETHER_H} #cmakedefine HAVE_NETDB_H ${HAVE_NETDB_H}
/* Define if you have the <netinet/in.h> header file. */ /* Define to 1 if you have the <netinet/if_ether.h> header file. */
#cmakedefine HAVE_NETINET_IN_H ${HAVE_NETINET_IN_H} #cmakedefine HAVE_NETINET_IF_ETHER_H ${HAVE_NETINET_IF_ETHER_H}
/* Define if you have the <net/if.h> header file. */ /* Define to 1 if you have the <netinet/in.h> header file. */
#cmakedefine HAVE_NET_IF_H ${HAVE_NET_IF_H} #cmakedefine HAVE_NETINET_IN_H ${HAVE_NETINET_IN_H}
/* Define if you have the <openssl/crypto.h> header file. */ /* Define to 1 if you have the <net/if.h> header file. */
#cmakedefine HAVE_OPENSSL_CRYPTO_H ${HAVE_OPENSSL_CRYPTO_H} #cmakedefine HAVE_NET_IF_H ${HAVE_NET_IF_H}
/* Define if you have the <openssl/engine.h> header file. */ /* Define to 1 if you have the <openssl/crypto.h> header file. */
#cmakedefine HAVE_OPENSSL_ENGINE_H ${HAVE_OPENSSL_ENGINE_H} #cmakedefine HAVE_OPENSSL_CRYPTO_H ${HAVE_OPENSSL_CRYPTO_H}
/* Define if you have the <openssl/err.h> header file. */ /* Define to 1 if you have the <openssl/engine.h> header file. */
#cmakedefine HAVE_OPENSSL_ERR_H ${HAVE_OPENSSL_ERR_H} #cmakedefine HAVE_OPENSSL_ENGINE_H ${HAVE_OPENSSL_ENGINE_H}
/* Define if you have the <openssl/pem.h> header file. */ /* Define to 1 if you have the <openssl/err.h> header file. */
#cmakedefine HAVE_OPENSSL_PEM_H ${HAVE_OPENSSL_PEM_H} #cmakedefine HAVE_OPENSSL_ERR_H ${HAVE_OPENSSL_ERR_H}
/* Define if you have the <openssl/rsa.h> header file. */ /* Define to 1 if you have the <openssl/pem.h> header file. */
#cmakedefine HAVE_OPENSSL_RSA_H ${HAVE_OPENSSL_RSA_H} #cmakedefine HAVE_OPENSSL_PEM_H ${HAVE_OPENSSL_PEM_H}
/* Define if you have the <openssl/ssl.h> header file. */ /* Define to 1 if you have the <openssl/rsa.h> header file. */
#cmakedefine HAVE_OPENSSL_SSL_H ${HAVE_OPENSSL_SSL_H} #cmakedefine HAVE_OPENSSL_RSA_H ${HAVE_OPENSSL_RSA_H}
/* Define if you have the <openssl/x509.h> header file. */ /* Define to 1 if you have the <openssl/ssl.h> header file. */
#cmakedefine HAVE_OPENSSL_X509_H ${HAVE_OPENSSL_X509_H} #cmakedefine HAVE_OPENSSL_SSL_H ${HAVE_OPENSSL_SSL_H}
/* Define if you have the <pem.h> header file. */ /* Define to 1 if you have the <openssl/x509.h> header file. */
#cmakedefine HAVE_PEM_H ${HAVE_PEM_H} #cmakedefine HAVE_OPENSSL_X509_H ${HAVE_OPENSSL_X509_H}
/* Define if you have the `perror' function. */ /* Define to 1 if you have the <pem.h> header file. */
#cmakedefine HAVE_PERROR ${HAVE_PERROR} #cmakedefine HAVE_PEM_H ${HAVE_PEM_H}
/* Define if you have the <pwd.h> header file. */ /* Define to 1 if you have the `perror' function. */
#cmakedefine HAVE_PWD_H ${HAVE_PWD_H} #cmakedefine HAVE_PERROR ${HAVE_PERROR}
/* Define if you have the `RAND_egd' function. */ /* Define to 1 if you have the `poll' function. */
#cmakedefine HAVE_RAND_EGD ${HAVE_RAND_EGD} #cmakedefine HAVE_POLL ${HAVE_POLL}
/* Define if you have the `RAND_screen' function. */ /* Define to 1 if you have the <pwd.h> header file. */
#cmakedefine HAVE_RAND_SCREEN ${HAVE_RAND_SCREEN} #cmakedefine HAVE_PWD_H ${HAVE_PWD_H}
/* Define if you have the `RAND_status' function. */ /* Define to 1 if you have the `RAND_egd' function. */
#cmakedefine HAVE_RAND_STATUS ${HAVE_RAND_STATUS} #cmakedefine HAVE_RAND_EGD ${HAVE_RAND_EGD}
/* Define if you have the <rsa.h> header file. */ /* Define to 1 if you have the `RAND_screen' function. */
#cmakedefine HAVE_RSA_H ${HAVE_RSA_H} #cmakedefine HAVE_RAND_SCREEN ${HAVE_RAND_SCREEN}
/* Define if you have the `select' function. */ /* Define to 1 if you have the `RAND_status' function. */
#cmakedefine HAVE_SELECT ${HAVE_SELECT} #cmakedefine HAVE_RAND_STATUS ${HAVE_RAND_STATUS}
/* Define if you have the `setvbuf' function. */ /* Define to 1 if you have the <rsa.h> header file. */
#cmakedefine HAVE_SETVBUF ${HAVE_SETVBUF} #cmakedefine HAVE_RSA_H ${HAVE_RSA_H}
/* Define if you have the <sgtty.h> header file. */ /* Define to 1 if you have the `select' function. */
#cmakedefine HAVE_SGTTY_H ${HAVE_SGTTY_H} #cmakedefine HAVE_SELECT ${HAVE_SELECT}
/* Define if you have the `sigaction' function. */ /* Define to 1 if you have the <setjmp.h> header file. */
#cmakedefine HAVE_SIGACTION ${HAVE_SIGACTION} #cmakedefine HAVE_SETJMP_H ${HAVE_SETJMP_H}
/* Define if you have the `signal' function. */ /* Define to 1 if you have the `setvbuf' function. */
#cmakedefine HAVE_SIGNAL ${HAVE_SIGNAL} #cmakedefine HAVE_SETVBUF ${HAVE_SETVBUF}
/* Define if you have the `socket' function. */ /* Define to 1 if you have the <sgtty.h> header file. */
#cmakedefine HAVE_SOCKET ${HAVE_SOCKET} #cmakedefine HAVE_SGTTY_H ${HAVE_SGTTY_H}
/* Define if you have the <ssl.h> header file. */ /* Define to 1 if you have the `sigaction' function. */
#cmakedefine HAVE_SSL_H ${HAVE_SSL_H} #cmakedefine HAVE_SIGACTION ${HAVE_SIGACTION}
/* Define if you have the <stdint.h> header file. */ /* Define to 1 if you have the `signal' function. */
#cmakedefine HAVE_STDINT_H ${HAVE_STDINT_H} #cmakedefine HAVE_SIGNAL ${HAVE_SIGNAL}
/* Define if you have the <stdlib.h> header file. */ /* If you have sigsetjmp */
#cmakedefine HAVE_STDLIB_H ${HAVE_STDLIB_H} #cmakedefine HAVE_SIGSETJMP ${HAVE_SIGSETJMP}
/* Define if you have the `strcasecmp' function. */ /* Define to 1 if you have the `socket' function. */
#cmakedefine HAVE_STRCASECMP ${HAVE_STRCASECMP} #cmakedefine HAVE_SOCKET ${HAVE_SOCKET}
/* Define if you have the `strcmpi' function. */ /* Define to 1 if you have the <ssl.h> header file. */
#cmakedefine HAVE_STRCMPI ${HAVE_STRCMPI} #cmakedefine HAVE_SSL_H ${HAVE_SSL_H}
/* Define if you have the `strdup' function. */ /* Define to 1 if you have the <stdint.h> header file. */
#cmakedefine HAVE_STRDUP ${HAVE_STRDUP} #cmakedefine HAVE_STDINT_H ${HAVE_STDINT_H}
/* Define if you have the `strftime' function. */ /* Define to 1 if you have the <stdlib.h> header file. */
#cmakedefine HAVE_STRFTIME ${HAVE_STRFTIME} #cmakedefine HAVE_STDLIB_H ${HAVE_STDLIB_H}
/* Define if you have the `stricmp' function. */ /* Define to 1 if you have the `strcasecmp' function. */
#cmakedefine HAVE_STRICMP ${HAVE_STRICMP} #cmakedefine HAVE_STRCASECMP ${HAVE_STRCASECMP}
/* Define if you have the <strings.h> header file. */ /* Define to 1 if you have the `strcmpi' function. */
#cmakedefine HAVE_STRINGS_H ${HAVE_STRINGS_H} #cmakedefine HAVE_STRCMPI ${HAVE_STRCMPI}
/* Define if you have the <string.h> header file. */ /* Define to 1 if you have the `strdup' function. */
#cmakedefine HAVE_STRING_H ${HAVE_STRING_H} #cmakedefine HAVE_STRDUP ${HAVE_STRDUP}
/* Define if you have the `strlcat' function. */ /* Define to 1 if you have the `strftime' function. */
#cmakedefine HAVE_STRLCAT ${HAVE_STRLCAT} #cmakedefine HAVE_STRFTIME ${HAVE_STRFTIME}
/* Define if you have the `strlcpy' function. */ /* Define to 1 if you have the `stricmp' function. */
#cmakedefine HAVE_STRLCPY ${HAVE_STRLCPY} #cmakedefine HAVE_STRICMP ${HAVE_STRICMP}
/* Define if you have the `strstr' function. */ /* Define to 1 if you have the <strings.h> header file. */
#cmakedefine HAVE_STRSTR ${HAVE_STRSTR} #cmakedefine HAVE_STRINGS_H ${HAVE_STRINGS_H}
/* Define if you have the `strtok_r' function. */ /* Define to 1 if you have the <string.h> header file. */
#cmakedefine HAVE_STRTOK_R ${HAVE_STRTOK_R} #cmakedefine HAVE_STRING_H ${HAVE_STRING_H}
/* Define if you have the <sys/param.h> header file. */ /* Define to 1 if you have the `strlcat' function. */
#cmakedefine HAVE_SYS_PARAM_H ${HAVE_SYS_PARAM_H} #cmakedefine HAVE_STRLCAT ${HAVE_STRLCAT}
/* Define if you have the <sys/select.h> header file. */ /* Define to 1 if you have the `strlcpy' function. */
#cmakedefine HAVE_SYS_SELECT_H ${HAVE_SYS_SELECT_H} #cmakedefine HAVE_STRLCPY ${HAVE_STRLCPY}
/* Define if you have the <sys/socket.h> header file. */ /* Define to 1 if you have the `strstr' function. */
#cmakedefine HAVE_SYS_SOCKET_H ${HAVE_SYS_SOCKET_H} #cmakedefine HAVE_STRSTR ${HAVE_STRSTR}
/* Define if you have the <sys/sockio.h> header file. */ /* Define to 1 if you have the `strtok_r' function. */
#cmakedefine HAVE_SYS_SOCKIO_H ${HAVE_SYS_SOCKIO_H} #cmakedefine HAVE_STRTOK_R ${HAVE_STRTOK_R}
/* Define if you have the <sys/stat.h> header file. */ /* Define to 1 if you have the <sys/param.h> header file. */
#cmakedefine HAVE_SYS_STAT_H ${HAVE_SYS_STAT_H} #cmakedefine HAVE_SYS_PARAM_H ${HAVE_SYS_PARAM_H}
/* Define if you have the <sys/time.h> header file. */ /* Define to 1 if you have the <sys/poll.h> header file. */
#cmakedefine HAVE_SYS_TIME_H ${HAVE_SYS_TIME_H} #cmakedefine HAVE_SYS_POLL_H ${HAVE_SYS_POLL_H}
/* Define if you have the <sys/types.h> header file. */ /* Define to 1 if you have the <sys/select.h> header file. */
#cmakedefine HAVE_SYS_TYPES_H ${HAVE_SYS_TYPES_H} #cmakedefine HAVE_SYS_SELECT_H ${HAVE_SYS_SELECT_H}
/* Define if you have the <sys/utime.h> header file. */ /* Define to 1 if you have the <sys/socket.h> header file. */
#cmakedefine HAVE_SYS_UTIME_H ${HAVE_SYS_UTIME_H} #cmakedefine HAVE_SYS_SOCKET_H ${HAVE_SYS_SOCKET_H}
/* Define if you have the `tcgetattr' function. */ /* Define to 1 if you have the <sys/sockio.h> header file. */
#cmakedefine HAVE_TCGETATTR ${HAVE_TCGETATTR} #cmakedefine HAVE_SYS_SOCKIO_H ${HAVE_SYS_SOCKIO_H}
/* Define if you have the `tcsetattr' function. */ /* Define to 1 if you have the <sys/stat.h> header file. */
#cmakedefine HAVE_TCSETATTR ${HAVE_TCSETATTR} #cmakedefine HAVE_SYS_STAT_H ${HAVE_SYS_STAT_H}
/* Define if you have the <termios.h> header file. */ /* Define to 1 if you have the <sys/time.h> header file. */
#cmakedefine HAVE_TERMIOS_H ${HAVE_TERMIOS_H} #cmakedefine HAVE_SYS_TIME_H ${HAVE_SYS_TIME_H}
/* Define if you have the <termio.h> header file. */ /* Define to 1 if you have the <sys/types.h> header file. */
#cmakedefine HAVE_TERMIO_H ${HAVE_TERMIO_H} #cmakedefine HAVE_SYS_TYPES_H ${HAVE_SYS_TYPES_H}
/* Define if you have the <time.h> header file. */ /* Define to 1 if you have the <sys/utime.h> header file. */
#cmakedefine HAVE_TIME_H ${HAVE_TIME_H} #cmakedefine HAVE_SYS_UTIME_H ${HAVE_SYS_UTIME_H}
/* Define if you have the `uname' function. */ /* Define to 1 if you have the `tcgetattr' function. */
#cmakedefine HAVE_UNAME ${HAVE_UNAME} #cmakedefine HAVE_TCGETATTR ${HAVE_TCGETATTR}
/* Define if you have the <unistd.h> header file. */ /* Define to 1 if you have the `tcsetattr' function. */
#cmakedefine HAVE_UNISTD_H ${HAVE_UNISTD_H} #cmakedefine HAVE_TCSETATTR ${HAVE_TCSETATTR}
/* Define if you have the `utime' function. */ /* Define to 1 if you have the <termios.h> header file. */
#cmakedefine HAVE_UTIME ${HAVE_UTIME} #cmakedefine HAVE_TERMIOS_H ${HAVE_TERMIOS_H}
/* Define if you have the <utime.h> header file. */ /* Define to 1 if you have the <termio.h> header file. */
#cmakedefine HAVE_UTIME_H ${HAVE_UTIME_H} #cmakedefine HAVE_TERMIO_H ${HAVE_TERMIO_H}
/* Define if you have the <winsock.h> header file. */ /* Define to 1 if you have the <time.h> header file. */
#cmakedefine HAVE_WINSOCK_H ${HAVE_WINSOCK_H} #cmakedefine HAVE_TIME_H ${HAVE_TIME_H}
/* Define if you have the <x509.h> header file. */ /* Define to 1 if you have the `uname' function. */
#cmakedefine HAVE_X509_H ${HAVE_X509_H} #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 */ /* 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'). */ /* 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. */ /* Define to 1 if you have the ANSI C header files. */
#cmakedefine STDC_HEADERS ${STDC_HEADERS} #cmakedefine STDC_HEADERS ${STDC_HEADERS}
/* Define if you can safely include both <sys/time.h> and <time.h>. */ /* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#cmakedefine TIME_WITH_SYS_TIME ${TIME_WITH_SYS_TIME} #cmakedefine TIME_WITH_SYS_TIME ${TIME_WITH_SYS_TIME}
/* Version number of package */ /* 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. System headers sometimes define this.
We just want to avoid a redefinition error message. */ We just want to avoid a redefinition error message. */
#ifndef _ALL_SOURCE #ifndef _ALL_SOURCE
@ -379,22 +470,22 @@
#endif #endif
/* Number of bits in a file offset, on hosts where this is settable. */ /* 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. */ /* 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. */ /* 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 */ /* 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. */ /* 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 */ /* 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. */ /* Define to `int' if <sys/types.h> does not define. */
#cmakedefine ssize_t ${ssize_t} #cmakedefine ssize_t ${ssize_t}
@ -402,7 +493,7 @@
/* Define if you don't have vprintf but do have _doprnt. */ /* Define if you don't have vprintf but do have _doprnt. */
#cmakedefine HAVE_DOPRNT ${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} #cmakedefine HAVE_VPRINTF ${HAVE_VPRINTF}
/* The number of bytes in a long double. */ /* The number of bytes in a long double. */

View File

@ -1,25 +1,25 @@
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
#include "setup.h" #include "setup.h"
@ -185,7 +185,6 @@ int waitconnect(int sockfd, /* socket */
return 0; return 0;
} }
#ifndef ENABLE_IPV6
static CURLcode bindlocal(struct connectdata *conn, static CURLcode bindlocal(struct connectdata *conn,
int sockfd) int sockfd)
{ {
@ -207,22 +206,28 @@ static CURLcode bindlocal(struct connectdata *conn,
*************************************************************/ *************************************************************/
if (strlen(data->set.device)<255) { if (strlen(data->set.device)<255) {
struct sockaddr_in sa; struct sockaddr_in sa;
struct hostent *h=NULL; struct Curl_dns_entry *h=NULL;
char *hostdataptr=NULL;
size_t size; size_t size;
char myhost[256] = ""; char myhost[256] = "";
in_addr_t in; in_addr_t in;
if(Curl_if2ip(data->set.device, myhost, sizeof(myhost))) { 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 { else {
if(strlen(data->set.device)>1) { if(strlen(data->set.device)>1) {
h = Curl_resolv(data, data->set.device, 0, &hostdataptr); /*
} * This was not an interface, resolve the name as a host name
if(h) { * or IP number
/* we know data->set.device is shorter than the myhost array */ */
strcpy(myhost, data->set.device); 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 (INADDR_NONE != in) {
if ( h ) { 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)); memset((char *)&sa, 0, sizeof(sa));
memcpy((char *)&sa.sin_addr, #ifdef ENABLE_IPV6
h->h_addr, memcpy((char *)&sa.sin_addr, addr->ai_addr, addr->ai_addrlen);
h->h_length); sa.sin_family = addr->ai_family;
#else
memcpy((char *)&sa.sin_addr, addr->h_addr, addr->h_length);
sa.sin_family = AF_INET; sa.sin_family = AF_INET;
#endif
sa.sin_addr.s_addr = in; sa.sin_addr.s_addr = in;
sa.sin_port = 0; /* get any port */ sa.sin_port = 0; /* get any port */
@ -314,7 +327,7 @@ static CURLcode bindlocal(struct connectdata *conn,
return CURLE_HTTP_PORT_FAILED; return CURLE_HTTP_PORT_FAILED;
} }
#endif /* end of ipv4-specific section */
static static
int socketerror(int sockfd) int socketerror(int sockfd)
@ -329,6 +342,72 @@ int socketerror(int sockfd)
return err; 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. * 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 * 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 */ 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 port, /* connect to this */
int *sockconn, /* the connected socket */ 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; struct SessionHandle *data = conn->data;
int rc; int rc;
int sockfd=-1; int sockfd=-1;
int aliasindex=0; int aliasindex=0;
char *hostname;
struct timeval after; struct timeval after;
struct timeval before = Curl_tvnow(); struct timeval before = Curl_tvnow();
@ -353,6 +434,9 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
* Figure out what maximum time we have left * Figure out what maximum time we have left
*************************************************************/ *************************************************************/
long timeout_ms=300000; /* milliseconds, default to five minutes */ long timeout_ms=300000; /* milliseconds, default to five minutes */
*connected = FALSE; /* default to not connected */
if(data->set.timeout || data->set.connecttimeout) { if(data->set.timeout || data->set.connecttimeout) {
double has_passed; 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 #ifdef ENABLE_IPV6
/* /*
* Connecting with IPv6 support is so much easier and cleanly done * 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; struct addrinfo *ai;
port =0; /* prevent compiler warning */ 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); sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
if (sockfd < 0) if (sockfd < 0)
continue; 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 */ /* set socket non-blocking */
Curl_nonblock(sockfd, TRUE); Curl_nonblock(sockfd, TRUE);
@ -417,17 +516,21 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
case EAGAIN: case EAGAIN:
#endif #endif
case EINTR: case EINTR:
/* asynchronous connect, wait for connect or timeout */ /* 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); rc = waitconnect(sockfd, timeout_ms);
break; break;
case ECONNREFUSED: /* no one listening */ case ECONNREFUSED: /* no one listening */
default: default:
/* unknown error, fallthrough and try another address! */ /* unknown error, fallthrough and try another address! */
failf(data, "Failed to connect"); failf(data, "Failed connect to %s: %d", hostname, error);
break; break;
} }
} }
if(0 == rc) { if(0 == rc) {
/* we might be connected, if the socket says it is OK! Ask it! */ /* we might be connected, if the socket says it is OK! Ask it! */
int err; int err;
@ -435,10 +538,17 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
err = socketerror(sockfd); err = socketerror(sockfd);
if ((0 == err) || (EISCONN == err)) { if ((0 == err) || (EISCONN == err)) {
/* we are connected, awesome! */ /* we are connected, awesome! */
*connected = TRUE; /* this is truly a connect */
break; break;
} }
failf(data, "socket error: %d", err);
/* we are _not_ connected, it was a false alert, continue please */ /* 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 */ /* connect failed or timed out */
sclose(sockfd); sclose(sockfd);
@ -454,10 +564,8 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
before = after; before = after;
continue; continue;
} }
if (sockfd < 0) { if (sockfd < 0)
failf(data, "connect() failed");
return CURLE_COULDNT_CONNECT; return CURLE_COULDNT_CONNECT;
}
/* leave the socket in non-blocking mode */ /* leave the socket in non-blocking mode */
@ -468,7 +576,7 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
/* /*
* Connecting with IPv4-only support * 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 /* If there is no addresses in the address list, then we return
error right away */ error right away */
failf(data, "no address available"); 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 /* This is the loop that attempts to connect to all IP-addresses we
know for the given host. One by one. */ know for the given host. One by one. */
for(rc=-1, aliasindex=0; 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++) { aliasindex++) {
struct sockaddr_in serv_addr; struct sockaddr_in serv_addr;
/* do this nasty work to do the connect */ /* do this nasty work to do the connect */
memset((char *) &serv_addr, '\0', sizeof(serv_addr)); memset((char *) &serv_addr, '\0', sizeof(serv_addr));
memcpy((char *)&(serv_addr.sin_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)); sizeof(struct in_addr));
serv_addr.sin_family = remotehost->h_addrtype; serv_addr.sin_family = remotehost->addr->h_addrtype;
serv_addr.sin_port = htons(port); serv_addr.sin_port = htons((unsigned short)port);
rc = connect(sockfd, (struct sockaddr *)&serv_addr, rc = connect(sockfd, (struct sockaddr *)&serv_addr,
sizeof(serv_addr)); sizeof(serv_addr));
@ -523,13 +631,17 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
*/ */
case EAGAIN: case EAGAIN:
#endif #endif
/* asynchronous connect, wait for connect or timeout */ /* 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); rc = waitconnect(sockfd, timeout_ms);
break; break;
default: default:
/* unknown error, fallthrough and try another address! */ /* 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; break;
} }
} }
@ -538,6 +650,7 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
int err = socketerror(sockfd); int err = socketerror(sockfd);
if ((0 == err) || (EISCONN == err)) { if ((0 == err) || (EISCONN == err)) {
/* we are connected, awesome! */ /* we are connected, awesome! */
*connected = TRUE; /* this is a true connect */
break; break;
} }
/* nope, not connected for real */ /* nope, not connected for real */
@ -545,6 +658,12 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
} }
if(0 != rc) { 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 */ /* get a new timeout for next attempt */
after = Curl_tvnow(); after = Curl_tvnow();
timeout_ms -= Curl_tvdiff(after, before); timeout_ms -= Curl_tvdiff(after, before);
@ -561,7 +680,7 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
/* no good connect was made */ /* no good connect was made */
sclose(sockfd); sclose(sockfd);
*sockconn = -1; *sockconn = -1;
failf(data, "Couldn't connect to host"); failf(data, "Connect failed");
return CURLE_COULDNT_CONNECT; return CURLE_COULDNT_CONNECT;
} }
@ -569,7 +688,7 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
if(addr) if(addr)
/* this is the address we've connected to */ /* 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 #endif
/* allow NULL-pointers to get passed in */ /* allow NULL-pointers to get passed in */

View File

@ -1,35 +1,40 @@
#ifndef __CONNECT_H #ifndef __CONNECT_H
#define __CONNECT_H #define __CONNECT_H
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
int Curl_nonblock(int socket, /* operate on this */ int Curl_nonblock(int socket, /* operate on this */
int nonblock /* TRUE or FALSE */); int nonblock /* TRUE or FALSE */);
CURLcode Curl_is_connected(struct connectdata *conn,
int sockfd,
bool *connected);
CURLcode Curl_connecthost(struct connectdata *conn, 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 port, /* connect to this port number */
int *sockconn, /* not set if error is returned */ int *sockconn, /* not set if error is returned */
Curl_ipconnect **addr /* the one we used */ Curl_ipconnect **addr, /* the one we used */
); /* index we used */ bool *connected /* truly connected? */
);
#endif #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 ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2002, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
/*** /***
@ -79,6 +79,8 @@ Example set of cookies:
#include "setup.h" #include "setup.h"
#ifndef CURL_DISABLE_HTTP
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
@ -93,6 +95,21 @@ Example set of cookies:
#include "memdebug.h" #include "memdebug.h"
#endif #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() * Curl_cookie_add()
@ -104,7 +121,7 @@ Example set of cookies:
struct Cookie * struct Cookie *
Curl_cookie_add(struct CookieInfo *c, Curl_cookie_add(struct CookieInfo *c,
bool httpheader, /* TRUE if HTTP header-style line */ 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 */ char *domain) /* default domain */
{ {
struct Cookie *clist; struct Cookie *clist;
@ -129,6 +146,10 @@ Curl_cookie_add(struct CookieInfo *c,
/* This line was read off a HTTP-header */ /* This line was read off a HTTP-header */
char *sep; char *sep;
semiptr=strchr(lineptr, ';'); /* first, find a semicolon */ semiptr=strchr(lineptr, ';'); /* first, find a semicolon */
while(*lineptr && isspace((int)*lineptr))
lineptr++;
ptr = lineptr; ptr = lineptr;
do { do {
/* we have a <what>=<this> pair or a 'secure' word here */ /* we have a <what>=<this> pair or a 'secure' word here */
@ -145,6 +166,8 @@ Curl_cookie_add(struct CookieInfo *c,
name, what)) { name, what)) {
/* this is a <name>=<what> pair */ /* this is a <name>=<what> pair */
char *whatptr;
/* Strip off trailing whitespace from the 'what' */ /* Strip off trailing whitespace from the 'what' */
int len=strlen(what); int len=strlen(what);
while(len && isspace((int)what[len-1])) { while(len && isspace((int)what[len-1])) {
@ -152,15 +175,21 @@ Curl_cookie_add(struct CookieInfo *c,
len--; len--;
} }
/* Skip leading whitespace from the 'what' */
whatptr=what;
while(isspace((int)*whatptr)) {
whatptr++;
}
if(strequal("path", name)) { if(strequal("path", name)) {
co->path=strdup(what); co->path=strdup(whatptr);
} }
else if(strequal("domain", name)) { else if(strequal("domain", name)) {
co->domain=strdup(what); co->domain=strdup(whatptr);
co->field1= (what[0]=='.')?2:1; co->field1= (whatptr[0]=='.')?2:1;
} }
else if(strequal("version", name)) { else if(strequal("version", name)) {
co->version=strdup(what); co->version=strdup(whatptr);
} }
else if(strequal("max-age", name)) { else if(strequal("max-age", name)) {
/* Defined in RFC2109: /* Defined in RFC2109:
@ -172,17 +201,17 @@ Curl_cookie_add(struct CookieInfo *c,
cookie should be discarded immediately. cookie should be discarded immediately.
*/ */
co->maxage = strdup(what); co->maxage = strdup(whatptr);
co->expires = co->expires =
atoi((*co->maxage=='\"')?&co->maxage[1]:&co->maxage[0]) + now; atoi((*co->maxage=='\"')?&co->maxage[1]:&co->maxage[0]) + now;
} }
else if(strequal("expires", name)) { else if(strequal("expires", name)) {
co->expirestr=strdup(what); co->expirestr=strdup(whatptr);
co->expires = curl_getdate(what, &now); co->expires = curl_getdate(what, &now);
} }
else if(!co->name) { else if(!co->name) {
co->name = strdup(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 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) { if(7 != fields) {
/* we did not find the sufficient number of fields to recognize this /* we did not find the sufficient number of fields to recognize this
as a valid line, abort and go home */ as a valid line, abort and go home */
free_cookiemess(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);
return NULL; 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; co->livecookie = c->running;
/* now, we have parsed the incoming line, we must now check if this /* 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 */ /* the names are identical */
if(clist->domain && co->domain) { 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; replace_old=TRUE;
} }
else if(!clist->domain && !co->domain) 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 * Inits a cookie struct to read data from a local file. This is always
* called before any cookies are set. File may be NULL. * 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]; char line[MAX_COOKIE_LINE];
struct CookieInfo *c; struct CookieInfo *c;
@ -477,11 +513,13 @@ struct CookieInfo *Curl_cookie_init(char *file, struct CookieInfo *inc)
else else
fp = file?fopen(file, "r"):NULL; fp = file?fopen(file, "r"):NULL;
c->newsession = newsession; /* new session? */
if(fp) { if(fp) {
char *lineptr; char *lineptr;
bool headerline; bool headerline;
while(fgets(line, MAX_COOKIE_LINE, fp)) { 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! */ /* This is a cookie line, get it! */
lineptr=&line[11]; lineptr=&line[11];
headerline=TRUE; headerline=TRUE;
@ -499,7 +537,7 @@ struct CookieInfo *Curl_cookie_init(char *file, struct CookieInfo *inc)
fclose(fp); fclose(fp);
} }
c->running = TRUE; /* now, we're running */ c->running = TRUE; /* now, we're running */
return c; 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 /* now check the left part of the path with the cookies path
requirement */ requirement */
if(!co->path || if(!co->path ||
strnequal(path, co->path, strlen(co->path))) { checkprefix(co->path, path) ) {
/* and now, we know this is a match and we should create an /* and now, we know this is a match and we should create an
entry for the return-linked-list */ entry for the return-linked-list */
@ -729,6 +767,8 @@ int main(int argc, char **argv)
#endif #endif
#endif /* CURL_DISABLE_HTTP */
/* /*
* local variables: * local variables:
* eval: (load-file "../curl-mode.el") * eval: (load-file "../curl-mode.el")

View File

@ -1,27 +1,27 @@
#ifndef __COOKIE_H #ifndef __COOKIE_H
#define __COOKIE_H #define __COOKIE_H
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
#include <stdio.h> #include <stdio.h>
#ifdef WIN32 #ifdef WIN32
@ -55,9 +55,10 @@ struct CookieInfo {
/* linked list of cookies we know of */ /* linked list of cookies we know of */
struct Cookie *cookies; struct Cookie *cookies;
char *filename; /* file we read from/write to */ char *filename; /* file we read from/write to */
bool running; /* state info, for cookie adding information */ bool running; /* state info, for cookie adding information */
long numcookies; /* number of cookies in the "jar" */ 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 */ /* 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, struct Cookie *Curl_cookie_add(struct CookieInfo *, bool header, char *line,
char *domain); 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); struct Cookie *Curl_cookie_getlist(struct CookieInfo *, char *, char *, bool);
void Curl_cookie_freelist(struct Cookie *); void Curl_cookie_freelist(struct Cookie *);
void Curl_cookie_cleanup(struct CookieInfo *); void Curl_cookie_cleanup(struct CookieInfo *);

View File

@ -1,27 +1,27 @@
#ifndef __CURL_CURL_H #ifndef __CURL_CURL_H
#define __CURL_CURL_H #define __CURL_CURL_H
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2002, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
#include <stdio.h> #include <stdio.h>
/* The include stuff here is mainly for time_t! */ /* The include stuff here is mainly for time_t! */
@ -49,22 +49,31 @@
#define FALSE 0 #define FALSE 0
#endif #endif
#include <curl/types.h> #include "types.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
struct HttpPost { /* stupid #define trick to preserve functionality with older code, but
struct HttpPost *next; /* next entry in the list */ 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 */ char *name; /* pointer to allocated name */
long namelength; /* length of name length */ long namelength; /* length of name length */
char *contents; /* pointer to allocated data contents */ char *contents; /* pointer to allocated data contents */
long contentslength; /* length of contents field */ 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 */ char *contenttype; /* Content-Type */
struct curl_slist* contentheader; /* list of extra headers for this form */ struct curl_slist* contentheader; /* list of extra headers for this form */
struct HttpPost *more; /* if one field name has more than one file, this struct curl_httppost *more; /* if one field name has more than one file, this
link should link to following files */ link should link to following files */
long flags; /* as defined below */ long flags; /* as defined below */
#define HTTPPOST_FILENAME (1<<0) /* specified content is a file name */ #define HTTPPOST_FILENAME (1<<0) /* specified content is a file name */
#define HTTPPOST_READFILE (1<<1) /* 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 */ do not free in formfree */
#define HTTPPOST_PTRCONTENTS (1<<3) /* contents is only stored pointer #define HTTPPOST_PTRCONTENTS (1<<3) /* contents is only stored pointer
do not free in formfree */ 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, typedef int (*curl_progress_callback)(void *clientp,
@ -80,6 +96,8 @@ typedef int (*curl_progress_callback)(void *clientp,
double ultotal, double ultotal,
double ulnow); double ulnow);
#define CURL_MAX_WRITE_SIZE 20480
typedef size_t (*curl_write_callback)(char *buffer, typedef size_t (*curl_write_callback)(char *buffer,
size_t size, size_t size,
size_t nitems, size_t nitems,
@ -95,6 +113,23 @@ typedef int (*curl_passwd_callback)(void *clientp,
char *buffer, char *buffer,
int buflen); 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 /* All possible error codes from all sorts of curl functions. Future versions
may return other values, stay prepared. may return other values, stay prepared.
@ -139,7 +174,7 @@ typedef enum {
CURLE_HTTP_RANGE_ERROR, /* 33 - RANGE "command" didn't work */ CURLE_HTTP_RANGE_ERROR, /* 33 - RANGE "command" didn't work */
CURLE_HTTP_POST_ERROR, /* 34 */ CURLE_HTTP_POST_ERROR, /* 34 */
CURLE_SSL_CONNECT_ERROR, /* 35 - wrong when connecting with SSL */ 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_FILE_COULDNT_READ_FILE, /* 37 */
CURLE_LDAP_CANNOT_BIND, /* 38 */ CURLE_LDAP_CANNOT_BIND, /* 38 */
CURLE_LDAP_SEARCH_FAILED, /* 39 */ CURLE_LDAP_SEARCH_FAILED, /* 39 */
@ -157,11 +192,28 @@ typedef enum {
CURLE_SSL_PEER_CERTIFICATE, /* 51 - peer's certificate wasn't ok */ CURLE_SSL_PEER_CERTIFICATE, /* 51 - peer's certificate wasn't ok */
CURLE_GOT_NOTHING, /* 52 - when this is a specific error */ CURLE_GOT_NOTHING, /* 52 - when this is a specific error */
CURLE_SSL_ENGINE_NOTFOUND, /* 53 - SSL crypto engine not found */ 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! */ CURL_LAST /* never use! */
} CURLcode; } 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 /* 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 is no longer used by libcurl but is instead #defined here only to not
make programs break */ make programs break */
@ -169,22 +221,47 @@ typedef enum {
/* This is just to make older programs not break: */ /* This is just to make older programs not break: */
#define CURLE_FTP_PARTIAL_FILE CURLE_PARTIAL_FILE #define CURLE_FTP_PARTIAL_FILE CURLE_PARTIAL_FILE
#define CURLE_FTP_BAD_DOWNLOAD_RESUME CURLE_BAD_DOWNLOAD_RESUME
#define CURL_ERROR_SIZE 256 #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>, /* name is uppercase CURLOPT_<name>,
type is one of the defined CURLOPTTYPE_<type> type is one of the defined CURLOPTTYPE_<type>
number is unique identifier */ number is unique identifier */
#ifdef CINIT #ifdef CINIT
#undef CINIT #undef CINIT
#endif #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 #ifdef CURL_ISOCPP
but 32 */ #define CINIT(name,type,number) CURLOPT_ ## name = CURLOPTTYPE_ ## type + number
#define CURLOPTTYPE_LONG 0 #else
#define CURLOPTTYPE_OBJECTPOINT 10000 /* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */
#define CURLOPTTYPE_FUNCTIONPOINT 20000 #define LONG CURLOPTTYPE_LONG
#define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT
#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT
#define CINIT(name,type,number) CURLOPT_/**/name = type + number
#endif
typedef enum { typedef enum {
CINIT(NOTHING, LONG, 0), /********* the first one is unused ************/ 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(FTPLISTONLY, LONG, 48), /* Use NLST when listing ftp dir */
CINIT(FTPAPPEND, LONG, 50), /* Append instead of overwrite on upload! */ 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! */ CINIT(FOLLOWLOCATION, LONG, 52), /* use Location: Luke! */
/* This FTPASCII name is now obsolete, to be removed, use the TRANSFERTEXT /* 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)*/ /* send linked-list of pre-transfer QUOTE commands (Wesley Laxton)*/
CINIT(PREQUOTE, OBJECTPOINT, 93), 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; } 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. */ /* These enums are for use with the CURLOPT_HTTP_VERSION option. */
enum { enum {
CURL_HTTP_VERSION_NONE, /* setting this means we don't care, and that we'd 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 */ 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 { enum {
CURL_SSLVERSION_DEFAULT, CURL_SSLVERSION_DEFAULT,
CURL_SSLVERSION_TLSv1, CURL_SSLVERSION_TLSv1,
@ -522,15 +654,26 @@ enum {
typedef enum { typedef enum {
TIMECOND_NONE, CURL_TIMECOND_NONE,
TIMECOND_IFMODSINCE, CURL_TIMECOND_IFMODSINCE,
TIMECOND_IFUNMODSINCE, CURL_TIMECOND_IFUNMODSINCE,
TIMECOND_LASTMOD, CURL_TIMECOND_LASTMOD,
TIMECOND_LAST CURL_TIMECOND_LAST
} curl_TimeCond; } 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__ #ifdef __BEOS__
#include <support/SupportDefs.h> #include <support/SupportDefs.h>
#endif #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 strequal(a,b) curl_strequal(a,b)
#define strnequal(a,b,c) curl_strnequal(a,b,c) #define strnequal(a,b,c) curl_strnequal(a,b,c)
/* external form function */ /* DEPRECATED function to build formdata */
int curl_formparse(char *string, int curl_formparse(char *, struct curl_httppost **,
struct HttpPost **httppost, struct curl_httppost **_post);
struct HttpPost **last_post);
/* name is uppercase CURLFORM_<name> */ /* name is uppercase CURLFORM_<name> */
#ifdef CFINIT #ifdef CFINIT
#undef CFINIT #undef CFINIT
#endif #endif
#ifdef CURL_ISOCPP
#define CFINIT(name) CURLFORM_ ## name #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 { typedef enum {
CFINIT(NOTHING), /********* the first one is unused ************/ CFINIT(NOTHING), /********* the first one is unused ************/
@ -571,29 +719,65 @@ typedef enum {
CFINIT(CONTENTSLENGTH), CFINIT(CONTENTSLENGTH),
CFINIT(FILECONTENT), CFINIT(FILECONTENT),
CFINIT(ARRAY), CFINIT(ARRAY),
CFINIT(ARRAY_START), /* below are the options allowed within a array */ CFINIT(OBSOLETE),
CFINIT(FILE), CFINIT(FILE),
CFINIT(BUFFER),
CFINIT(BUFFERPTR),
CFINIT(BUFFERLENGTH),
CFINIT(CONTENTTYPE), CFINIT(CONTENTTYPE),
CFINIT(CONTENTHEADER), CFINIT(CONTENTHEADER),
CFINIT(FILENAME),
CFINIT(END), CFINIT(END),
CFINIT(ARRAY_END), /* up are the options allowed within a array */ CFINIT(OBSOLETE2),
CURLFORM_LASTENTRY /* the last unusued */ CURLFORM_LASTENTRY /* the last unusued */
} CURLformoption; } CURLformoption;
#undef CFINIT /* done */
/* structure to be used as parameter for CURLFORM_ARRAY */ /* structure to be used as parameter for CURLFORM_ARRAY */
struct curl_forms { struct curl_forms {
CURLformoption option; CURLformoption option;
const char *value; const char *value;
}; };
/* new external form function */ /* use this for multipart formpost building */
int curl_formadd(struct HttpPost **httppost, /* Returns code for curl_formadd()
struct HttpPost **last_post, *
* 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: */ /* 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 /* Unix and Win32 getenv function call, this returns a malloc()'ed string that
MUST be free()ed after usage is complete. */ MUST be free()ed after usage is complete. */
@ -606,6 +790,9 @@ char *curl_version(void);
* allocated string or NULL if an error occurred. */ * allocated string or NULL if an error occurred. */
char *curl_escape(const char *string, int length); char *curl_escape(const char *string, int length);
char *curl_unescape(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 /* curl_global_init() should be invoked exactly once for each application that
uses libcurl */ uses libcurl */
@ -616,8 +803,8 @@ CURLcode curl_global_init(long flags);
void curl_global_cleanup(void); void curl_global_cleanup(void);
/* This is the version number */ /* This is the version number */
#define LIBCURL_VERSION "7.9.5" #define LIBCURL_VERSION "7.10.2"
#define LIBCURL_VERSION_NUM 0x070905 #define LIBCURL_VERSION_NUM 0x070a02
/* linked-list structure for the CURLOPT_QUOTE option (and other) */ /* linked-list structure for the CURLOPT_QUOTE option (and other) */
struct curl_slist { struct curl_slist {
@ -671,14 +858,18 @@ typedef enum {
CURLINFO_CONTENT_TYPE = CURLINFO_STRING + 18, CURLINFO_CONTENT_TYPE = CURLINFO_STRING + 18,
CURLINFO_REDIRECT_TIME = CURLINFO_DOUBLE + 19,
CURLINFO_REDIRECT_COUNT = CURLINFO_LONG + 20,
/* Fill in new entries here! */ /* Fill in new entries here! */
CURLINFO_LASTONE = 19 CURLINFO_LASTONE = 21
} CURLINFO; } CURLINFO;
/* unfortunately, the easy.h include file needs the options and info stuff /* unfortunately, the easy.h and multi.h include files need options and info
before it can be included! */ stuff before they can be included! */
#include <curl/easy.h> /* nothing in curl is fun without the easy stuff */ #include "easy.h" /* nothing in curl is fun without the easy stuff */
#include "multi.h"
typedef enum { typedef enum {
CURLCLOSEPOLICY_NONE, /* first, never use this */ CURLCLOSEPOLICY_NONE, /* first, never use this */
@ -698,6 +889,78 @@ typedef enum {
#define CURL_GLOBAL_NOTHING 0 #define CURL_GLOBAL_NOTHING 0
#define CURL_GLOBAL_DEFAULT CURL_GLOBAL_ALL #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 #ifdef __cplusplus
} }
#endif #endif

View File

@ -1,27 +1,27 @@
#ifndef __CURL_EASY_H #ifndef __CURL_EASY_H
#define __CURL_EASY_H #define __CURL_EASY_H
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif

View File

@ -1,27 +1,27 @@
#ifndef __STDC_HEADERS_H #ifndef __STDC_HEADERS_H
#define __STDC_HEADERS_H #define __STDC_HEADERS_H
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
#ifdef HAVE_SYS_TYPES_H #ifdef HAVE_SYS_TYPES_H
#include <sys/types.h> #include <sys/types.h>

View File

@ -1,27 +1,27 @@
#ifndef __CURL_TYPES_H #ifndef __CURL_TYPES_H
#define __CURL_TYPES_H #define __CURL_TYPES_H
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
typedef void CURL; typedef void CURL;
typedef void CURLconnect; typedef void CURLconnect;

View File

@ -1,25 +1,25 @@
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
#include "setup.h" #include "setup.h"

View File

@ -1,29 +1,30 @@
#ifndef __DICT_H #ifndef __DICT_H
#define __DICT_H #define __DICT_H
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
#ifndef CURL_DISABLE_DICT
CURLcode Curl_dict(struct connectdata *conn); CURLcode Curl_dict(struct connectdata *conn);
CURLcode Curl_dict_done(struct connectdata *conn); CURLcode Curl_dict_done(struct connectdata *conn);
#endif
#endif #endif

View File

@ -1,25 +1,25 @@
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
#include "setup.h" #include "setup.h"
@ -238,7 +238,7 @@ CURLcode curl_easy_perform(CURL *curl)
data->hostcache = Curl_global_host_cache_get(); data->hostcache = Curl_global_host_cache_get();
} }
else { 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; struct SessionHandle *data = (struct SessionHandle *)curl;
if (!Curl_global_host_cache_use(data)) { if (!Curl_global_host_cache_use(data)) {
curl_hash_destroy(data->hostcache); Curl_hash_destroy(data->hostcache);
} }
Curl_close(data); Curl_close(data);
} }
@ -312,7 +312,8 @@ CURL *curl_easy_duphandle(CURL *incurl)
/* If cookies are enabled in the parent handle, we enable them /* If cookies are enabled in the parent handle, we enable them
in the clone as well! */ in the clone as well! */
outcurl->cookies = Curl_cookie_init(data->cookies->filename, outcurl->cookies = Curl_cookie_init(data->cookies->filename,
outcurl->cookies); outcurl->cookies,
data->set.cookiesession);
/* duplicate all values in 'change' */ /* duplicate all values in 'change' */
if(data->change.url) { if(data->change.url) {

View File

@ -1,25 +1,25 @@
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
/* Escape and unescape URL encoding in strings. The functions return a new /* Escape and unescape URL encoding in strings. The functions return a new
* allocated string or NULL if an error occurred. */ * allocated string or NULL if an error occurred. */
@ -48,11 +48,9 @@ char *curl_escape(const char *string, int length)
length = alloc-1; length = alloc-1;
while(length--) { while(length--) {
in = *string; in = *string;
if(' ' == in) if(!(in >= 'a' && in <= 'z') &&
ns[index++] = '+'; !(in >= 'A' && in <= 'Z') &&
else if(!(in >= 'a' && in <= 'z') && !(in >= '0' && in <= '9')) {
!(in >= 'A' && in <= 'Z') &&
!(in >= '0' && in <= '9')) {
/* encode it */ /* encode it */
newlen += 2; /* the size grows with two, since this'll become a %XX */ newlen += 2; /* the size grows with two, since this'll become a %XX */
if(newlen > alloc) { if(newlen > alloc) {
@ -82,19 +80,10 @@ char *curl_unescape(const char *string, int length)
unsigned char in; unsigned char in;
int index=0; int index=0;
unsigned int hex; 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) { while(--alloc > 0) {
in = *string; in = *string;
if(querypart && ('+' == in)) if('%' == in) {
in = ' ';
else if(!querypart && ('?' == in)) {
/* we have "walked in" to the query part */
querypart=TRUE;
}
else if('%' == in) {
/* encoded part */ /* encoded part */
if(sscanf(string+1, "%02X", &hex)) { if(sscanf(string+1, "%02X", &hex)) {
in = hex; in = hex;
@ -111,6 +100,11 @@ char *curl_unescape(const char *string, int length)
} }
void curl_free(void *p)
{
free(p);
}
/* /*
* local variables: * local variables:
* eval: (load-file "../curl-mode.el") * eval: (load-file "../curl-mode.el")

View File

@ -1,28 +1,28 @@
#ifndef __ESCAPE_H #ifndef __ESCAPE_H
#define __ESCAPE_H #define __ESCAPE_H
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
/* Escape and unescape URL encoding in strings. The functions return a new /* Escape and unescape URL encoding in strings. The functions return a new
* allocated string or NULL if an error occurred. */ * allocated string or NULL if an error occurred. */

View File

@ -1,28 +1,29 @@
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
#include "setup.h" #include "setup.h"
#ifndef CURL_DISABLE_FILE
/* -- WIN32 approved -- */ /* -- WIN32 approved -- */
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -140,7 +141,7 @@ CURLcode Curl_file(struct connectdata *conn)
*/ */
CURLcode res = CURLE_OK; CURLcode res = CURLE_OK;
struct stat statbuf; struct stat statbuf;
ssize_t expected_size=-1; double expected_size=-1;
ssize_t nread; ssize_t nread;
struct SessionHandle *data = conn->data; struct SessionHandle *data = conn->data;
char *buf = data->state.buffer; char *buf = data->state.buffer;
@ -155,9 +156,19 @@ CURLcode Curl_file(struct connectdata *conn)
/*VMS?? -- This only works reliable for STREAMLF files */ /*VMS?? -- This only works reliable for STREAMLF files */
if( -1 != fstat(fd, &statbuf)) { if( -1 != fstat(fd, &statbuf)) {
/* we could stat it, then read out the size */ /* 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 /* The following is a shortcut implementation of file reading
this is both more efficient than the former call to download() and this is both more efficient than the former call to download() and
it avoids problems with select() and recv() on file descriptors it avoids problems with select() and recv() on file descriptors
@ -165,6 +176,10 @@ CURLcode Curl_file(struct connectdata *conn)
if(expected_size != -1) if(expected_size != -1)
Curl_pgrsSetDownloadSize(data, expected_size); 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) { while (res == CURLE_OK) {
nread = read(fd, buf, BUFSIZE-1); nread = read(fd, buf, BUFSIZE-1);
@ -204,3 +219,4 @@ CURLcode Curl_file(struct connectdata *conn)
* vim600: fdm=marker * vim600: fdm=marker
* vim: et sw=2 ts=2 sts=2 tw=78 * vim: et sw=2 ts=2 sts=2 tw=78
*/ */
#endif

View File

@ -1,28 +1,30 @@
#ifndef __FILE_H #ifndef __FILE_H
#define __FILE_H #define __FILE_H
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
#ifndef CURL_DISABLE_FILE
CURLcode Curl_file(struct connectdata *conn); CURLcode Curl_file(struct connectdata *conn);
CURLcode Curl_file_connect(struct connectdata *conn); CURLcode Curl_file_connect(struct connectdata *conn);
#endif #endif
#endif

View File

@ -1,25 +1,25 @@
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
/* /*
Debug the form generator stand-alone by compiling this source file with: 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" #include "setup.h"
#ifndef CURL_DISABLE_HTTP
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -171,8 +173,8 @@ static void GetStr(char **string,
static static
int FormParse(char *input, int FormParse(char *input,
struct HttpPost **httppost, struct curl_httppost **httppost,
struct HttpPost **last_post) struct curl_httppost **last_post)
{ {
/* nextarg MUST be a string in the format 'name=contents' and we'll /* nextarg MUST be a string in the format 'name=contents' and we'll
build a linked list with the info */ build a linked list with the info */
@ -186,8 +188,8 @@ int FormParse(char *input,
char *prevtype = NULL; char *prevtype = NULL;
char *sep; char *sep;
char *sep2; char *sep2;
struct HttpPost *post; struct curl_httppost *post;
struct HttpPost *subpost; /* a sub-node */ struct curl_httppost *subpost; /* a sub-node */
unsigned int i; unsigned int i;
/* Preallocate contents to the length of input to make sure we don't /* 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 /* For the first file name, we allocate and initiate the main list
node */ node */
post = (struct HttpPost *)malloc(sizeof(struct HttpPost)); post = (struct curl_httppost *)malloc(sizeof(struct curl_httppost));
if(post) { if(post) {
memset(post, 0, sizeof(struct HttpPost)); memset(post, 0, sizeof(struct curl_httppost));
GetStr(&post->name, name); /* get the name */ GetStr(&post->name, name); /* get the name */
GetStr(&post->contents, contp); /* get the contents */ GetStr(&post->contents, contp); /* get the contents */
post->contentslength = 0; post->contentslength = 0;
@ -320,9 +322,10 @@ int FormParse(char *input,
else { else {
/* we add a file name to the previously allocated node, known as /* we add a file name to the previously allocated node, known as
'post' now */ 'post' now */
subpost =(struct HttpPost *)malloc(sizeof(struct HttpPost)); subpost =(struct curl_httppost *)
malloc(sizeof(struct curl_httppost));
if(subpost) { if(subpost) {
memset(subpost, 0, sizeof(struct HttpPost)); memset(subpost, 0, sizeof(struct curl_httppost));
GetStr(&subpost->name, name); /* get the name */ GetStr(&subpost->name, name); /* get the name */
GetStr(&subpost->contents, contp); /* get the contents */ GetStr(&subpost->contents, contp); /* get the contents */
subpost->contentslength = 0; subpost->contentslength = 0;
@ -342,9 +345,9 @@ int FormParse(char *input,
} while(sep && *sep); /* loop if there's another file name */ } while(sep && *sep); /* loop if there's another file name */
} }
else { else {
post = (struct HttpPost *)malloc(sizeof(struct HttpPost)); post = (struct curl_httppost *)malloc(sizeof(struct curl_httppost));
if(post) { if(post) {
memset(post, 0, sizeof(struct HttpPost)); memset(post, 0, sizeof(struct curl_httppost));
GetStr(&post->name, name); /* get the name */ GetStr(&post->name, name); /* get the name */
if( contp[0]=='<' ) { if( contp[0]=='<' ) {
GetStr(&post->contents, contp+1); /* get the contents */ GetStr(&post->contents, contp+1); /* get the contents */
@ -378,8 +381,8 @@ int FormParse(char *input,
} }
int curl_formparse(char *input, int curl_formparse(char *input,
struct HttpPost **httppost, struct curl_httppost **httppost,
struct HttpPost **last_post) struct curl_httppost **last_post)
{ {
return FormParse(input, 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. * Returns newly allocated HttpPost on success and NULL if malloc failed.
* *
***************************************************************************/ ***************************************************************************/
static struct HttpPost * AddHttpPost(char * name, static struct curl_httppost *
long namelength, AddHttpPost(char * name, long namelength,
char * value, char * value, long contentslength,
long contentslength,
char *contenttype, /* CMC: Added support for buffer uploads */
long flags, char * buffer, long bufferlength,
struct curl_slist* contentHeader,
struct HttpPost *parent_post, char *contenttype,
struct HttpPost **httppost, long flags,
struct HttpPost **last_post) struct curl_slist* contentHeader,
char *showfilename,
struct curl_httppost *parent_post,
struct curl_httppost **httppost,
struct curl_httppost **last_post)
{ {
struct HttpPost *post; struct curl_httppost *post;
post = (struct HttpPost *)malloc(sizeof(struct HttpPost)); post = (struct curl_httppost *)malloc(sizeof(struct curl_httppost));
if(post) { if(post) {
memset(post, 0, sizeof(struct HttpPost)); memset(post, 0, sizeof(struct curl_httppost));
post->name = name; post->name = name;
post->namelength = name?(namelength?namelength:(long)strlen(name)):0; post->namelength = name?(namelength?namelength:(long)strlen(name)):0;
post->contents = value; post->contents = value;
post->contentslength = contentslength; post->contentslength = contentslength;
/* CMC: Added support for buffer uploads */
post->buffer = buffer;
post->bufferlength = bufferlength;
post->contenttype = contenttype; post->contenttype = contenttype;
post->contentheader = contentHeader; post->contentheader = contentHeader;
post->showfilename = showfilename;
post->flags = flags; post->flags = flags;
} }
else else
@ -600,44 +613,31 @@ static int AllocAndCopy (char **buffer, int buffer_length)
* CURLFORM_FILE, "filename1", CURLFORM_FILE, "filename2", CURLFORM_END); * CURLFORM_FILE, "filename1", CURLFORM_FILE, "filename2", CURLFORM_END);
* *
* Returns: * Returns:
* FORMADD_OK on success * CURL_FORMADD_OK on success
* FORMADD_MEMORY if the FormInfo allocation fails * CURL_FORMADD_MEMORY if the FormInfo allocation fails
* FORMADD_OPTION_TWICE if one option is given twice for one Form * CURL_FORMADD_OPTION_TWICE if one option is given twice for one Form
* FORMADD_NULL if a null pointer was given for a char * CURL_FORMADD_NULL if a null pointer was given for a char
* FORMADD_MEMORY if the allocation of a FormInfo struct failed * CURL_FORMADD_MEMORY if the allocation of a FormInfo struct failed
* FORMADD_UNKNOWN_OPTION if an unknown option was used * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used
* FORMADD_INCOMPLETE if the some FormInfo is not complete (or an error) * CURL_FORMADD_INCOMPLETE if the some FormInfo is not complete (or an error)
* FORMADD_MEMORY if a HttpPost struct cannot be allocated * CURL_FORMADD_MEMORY if a HttpPost struct cannot be allocated
* FORMADD_MEMORY if some allocation for string copying failed. * CURL_FORMADD_MEMORY if some allocation for string copying failed.
* FORMADD_ILLEGAL_ARRAY if an illegal option is used in an array * 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 static
FORMcode FormAdd(struct HttpPost **httppost, CURLFORMcode FormAdd(struct curl_httppost **httppost,
struct HttpPost **last_post, struct curl_httppost **last_post,
va_list params) va_list params)
{ {
FormInfo *first_form, *current_form, *form; FormInfo *first_form, *current_form, *form;
FORMcode return_value = FORMADD_OK; CURLFORMcode return_value = CURL_FORMADD_OK;
const char *prevtype = NULL; const char *prevtype = NULL;
struct HttpPost *post = NULL; struct curl_httppost *post = NULL;
CURLformoption option; CURLformoption option;
struct curl_forms *forms = NULL; 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 /* 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 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; current_form = first_form;
} }
else else
return FORMADD_MEMORY; return CURL_FORMADD_MEMORY;
/* /*
* Loop through all the options set. * Loop through all the options set.
@ -661,14 +661,14 @@ FORMcode FormAdd(struct HttpPost **httppost,
while (1) { while (1) {
/* break if we have an error to report */ /* break if we have an error to report */
if (return_value != FORMADD_OK) if (return_value != CURL_FORMADD_OK)
break; break;
/* first see if we have more parts of the array param */ /* first see if we have more parts of the array param */
if ( array_state ) { if ( array_state ) {
/* get the upcoming option from the given array */ /* get the upcoming option from the given array */
option = forms->option; option = forms->option;
array_value = forms->value; array_value = (char *)forms->value;
forms++; /* advance this to next entry */ forms++; /* advance this to next entry */
if (CURLFORM_END == option) { if (CURLFORM_END == option) {
@ -676,16 +676,6 @@ FORMcode FormAdd(struct HttpPost **httppost,
array_state = FALSE; array_state = FALSE;
continue; 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 { else {
/* This is not array-state, get next option */ /* This is not array-state, get next option */
@ -696,11 +686,16 @@ FORMcode FormAdd(struct HttpPost **httppost,
switch (option) { switch (option) {
case CURLFORM_ARRAY: case CURLFORM_ARRAY:
forms = va_arg(params, struct curl_forms *); if(array_state)
if (forms) /* we don't support an array from within an array */
array_state = TRUE; return_value = CURL_FORMADD_ILLEGAL_ARRAY;
else else {
return_value = FORMADD_NULL; forms = va_arg(params, struct curl_forms *);
if (forms)
array_state = TRUE;
else
return_value = CURL_FORMADD_NULL;
}
break; break;
/* /*
@ -710,20 +705,22 @@ FORMcode FormAdd(struct HttpPost **httppost,
current_form->flags |= HTTPPOST_PTRNAME; /* fall through */ current_form->flags |= HTTPPOST_PTRNAME; /* fall through */
case CURLFORM_COPYNAME: case CURLFORM_COPYNAME:
if (current_form->name) if (current_form->name)
return_value = FORMADD_OPTION_TWICE; return_value = CURL_FORMADD_OPTION_TWICE;
else { else {
char *name = va_arg(params, char *); char *name = array_state?
array_value:va_arg(params, char *);
if (name) if (name)
current_form->name = name; /* store for the moment */ current_form->name = name; /* store for the moment */
else else
return_value = FORMADD_NULL; return_value = CURL_FORMADD_NULL;
} }
break; break;
case CURLFORM_NAMELENGTH: case CURLFORM_NAMELENGTH:
if (current_form->namelength) if (current_form->namelength)
return_value = FORMADD_OPTION_TWICE; return_value = CURL_FORMADD_OPTION_TWICE;
else else
current_form->namelength = va_arg(params, long); current_form->namelength =
array_state?(long)array_value:va_arg(params, long);
break; break;
/* /*
@ -733,117 +730,179 @@ FORMcode FormAdd(struct HttpPost **httppost,
current_form->flags |= HTTPPOST_PTRCONTENTS; /* fall through */ current_form->flags |= HTTPPOST_PTRCONTENTS; /* fall through */
case CURLFORM_COPYCONTENTS: case CURLFORM_COPYCONTENTS:
if (current_form->value) if (current_form->value)
return_value = FORMADD_OPTION_TWICE; return_value = CURL_FORMADD_OPTION_TWICE;
else { else {
char *value = va_arg(params, char *); char *value =
array_state?array_value:va_arg(params, char *);
if (value) if (value)
current_form->value = value; /* store for the moment */ current_form->value = value; /* store for the moment */
else else
return_value = FORMADD_NULL; return_value = CURL_FORMADD_NULL;
} }
break; break;
case CURLFORM_CONTENTSLENGTH: case CURLFORM_CONTENTSLENGTH:
if (current_form->contentslength) if (current_form->contentslength)
return_value = FORMADD_OPTION_TWICE; return_value = CURL_FORMADD_OPTION_TWICE;
else else
current_form->contentslength = va_arg(params, long); current_form->contentslength =
array_state?(long)array_value:va_arg(params, long);
break; break;
/* Get contents from a given file name */ /* Get contents from a given file name */
case CURLFORM_FILECONTENT: case CURLFORM_FILECONTENT:
if (current_form->flags != 0) if (current_form->flags != 0)
return_value = FORMADD_OPTION_TWICE; return_value = CURL_FORMADD_OPTION_TWICE;
else { else {
char *filename = va_arg(params, char *); char *filename = array_state?
array_value:va_arg(params, char *);
if (filename) { if (filename) {
current_form->value = strdup(filename); current_form->value = strdup(filename);
current_form->flags |= HTTPPOST_READFILE; current_form->flags |= HTTPPOST_READFILE;
} }
else else
return_value = FORMADD_NULL; return_value = CURL_FORMADD_NULL;
} }
break; break;
/* We upload a file */ /* We upload a file */
case CURLFORM_FILE: case CURLFORM_FILE:
{ {
const char *filename = NULL; char *filename = array_state?array_value:
if (array_state) va_arg(params, char *);
filename = array_value;
else
filename = va_arg(params, const char *);
if (current_form->value) { if (current_form->value) {
if (current_form->flags & HTTPPOST_FILENAME) { if (current_form->flags & HTTPPOST_FILENAME) {
if (filename) { if (filename) {
if (!(current_form = AddFormInfo(strdup(filename), if (!(current_form = AddFormInfo(strdup(filename),
NULL, current_form))) NULL, current_form)))
return_value = FORMADD_MEMORY; return_value = CURL_FORMADD_MEMORY;
} }
else else
return_value = FORMADD_NULL; return_value = CURL_FORMADD_NULL;
} }
else else
return_value = FORMADD_OPTION_TWICE; return_value = CURL_FORMADD_OPTION_TWICE;
} }
else { else {
if (filename) if (filename)
current_form->value = strdup(filename); current_form->value = strdup(filename);
else else
return_value = FORMADD_NULL; return_value = CURL_FORMADD_NULL;
current_form->flags |= HTTPPOST_FILENAME; current_form->flags |= HTTPPOST_FILENAME;
} }
break; 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: case CURLFORM_CONTENTTYPE:
{ {
const char *contenttype = NULL; char *contenttype =
if (array_state) array_state?array_value:va_arg(params, char *);
contenttype = array_value;
else
contenttype = va_arg(params, const char *);
if (current_form->contenttype) { if (current_form->contenttype) {
if (current_form->flags & HTTPPOST_FILENAME) { if (current_form->flags & HTTPPOST_FILENAME) {
if (contenttype) { if (contenttype) {
if (!(current_form = AddFormInfo(NULL, if (!(current_form = AddFormInfo(NULL,
strdup(contenttype), strdup(contenttype),
current_form))) current_form)))
return_value = FORMADD_MEMORY; return_value = CURL_FORMADD_MEMORY;
} }
else else
return_value = FORMADD_NULL; return_value = CURL_FORMADD_NULL;
} }
else else
return_value = FORMADD_OPTION_TWICE; return_value = CURL_FORMADD_OPTION_TWICE;
} }
else { else {
if (contenttype) if (contenttype)
current_form->contenttype = strdup(contenttype); current_form->contenttype = strdup(contenttype);
else else
return_value = FORMADD_NULL; return_value = CURL_FORMADD_NULL;
} }
break; break;
} }
case CURLFORM_CONTENTHEADER: case CURLFORM_CONTENTHEADER:
{ {
struct curl_slist* list = NULL; /* this "cast increases required alignment of target type" but
if( array_state ) we consider it OK anyway */
list = (struct curl_slist*)array_value; struct curl_slist* list = array_state?
else (struct curl_slist*)array_value:
list = va_arg(params,struct curl_slist*); va_arg(params, struct curl_slist*);
if( current_form->contentheader ) if( current_form->contentheader )
return_value = FORMADD_OPTION_TWICE; return_value = CURL_FORMADD_OPTION_TWICE;
else else
current_form->contentheader = list; current_form->contentheader = list;
break; 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: 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 /* go through the list, check for copleteness and if everything is
* alright add the HttpPost item otherwise set return_value accordingly */ * 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_FILENAME) && ( (form->flags & HTTPPOST_FILENAME) &&
(form->flags & HTTPPOST_PTRCONTENTS) ) || (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_READFILE) &&
(form->flags & HTTPPOST_PTRCONTENTS) ) (form->flags & HTTPPOST_PTRCONTENTS) )
) { ) {
return_value = FORMADD_INCOMPLETE; return_value = CURL_FORMADD_INCOMPLETE;
break; break;
} }
else { else {
if ( (form->flags & HTTPPOST_FILENAME) && if ( ((form->flags & HTTPPOST_FILENAME) ||
(form->flags & HTTPPOST_BUFFER)) &&
!form->contenttype ) { !form->contenttype ) {
/* our contenttype is missing */ /* our contenttype is missing */
form->contenttype form->contenttype
@ -873,28 +939,36 @@ FORMcode FormAdd(struct HttpPost **httppost,
(form == first_form) ) { (form == first_form) ) {
/* copy name (without strdup; possibly contains null characters) */ /* copy name (without strdup; possibly contains null characters) */
if (AllocAndCopy(&form->name, form->namelength)) { if (AllocAndCopy(&form->name, form->namelength)) {
return_value = FORMADD_MEMORY; return_value = CURL_FORMADD_MEMORY;
break; break;
} }
} }
if ( !(form->flags & HTTPPOST_FILENAME) && if ( !(form->flags & HTTPPOST_FILENAME) &&
!(form->flags & HTTPPOST_READFILE) && !(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) */ /* copy value (without strdup; possibly contains null characters) */
if (AllocAndCopy(&form->value, form->contentslength)) { if (AllocAndCopy(&form->value, form->contentslength)) {
return_value = FORMADD_MEMORY; return_value = CURL_FORMADD_MEMORY;
break; break;
} }
} }
post = AddHttpPost(form->name, form->namelength, post = AddHttpPost(form->name, form->namelength,
form->value, form->contentslength, form->value, form->contentslength,
/* CMC: Added support for buffer uploads */
form->buffer, form->bufferlength,
form->contenttype, form->flags, form->contenttype, form->flags,
form->contentheader, form->contentheader, form->showfilename,
post, httppost, post, httppost,
last_post); last_post);
if(!post) if(!post)
return_value = FORMADD_MEMORY; return_value = CURL_FORMADD_MEMORY;
if (form->contenttype) if (form->contenttype)
prevtype = form->contenttype; prevtype = form->contenttype;
@ -915,12 +989,12 @@ FORMcode FormAdd(struct HttpPost **httppost,
return return_value; return return_value;
} }
int curl_formadd(struct HttpPost **httppost, CURLFORMcode curl_formadd(struct curl_httppost **httppost,
struct HttpPost **last_post, struct curl_httppost **last_post,
...) ...)
{ {
va_list arg; va_list arg;
int result; CURLFORMcode result;
va_start(arg, last_post); va_start(arg, last_post);
result = FormAdd(httppost, last_post, arg); result = FormAdd(httppost, last_post, arg);
va_end(arg); va_end(arg);
@ -975,8 +1049,8 @@ char *Curl_FormBoundary(void)
the same form won't be identical */ the same form won't be identical */
int i; int i;
static char table64[]= static char table62[]=
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
retstring = (char *)malloc(BOUNDARY_LENGTH); retstring = (char *)malloc(BOUNDARY_LENGTH);
@ -988,7 +1062,7 @@ char *Curl_FormBoundary(void)
strcpy(retstring, "curl"); /* bonus commercials 8*) */ strcpy(retstring, "curl"); /* bonus commercials 8*) */
for(i=4; i<(BOUNDARY_LENGTH-1); i++) { 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 */ 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 */ /* 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) if(!form)
/* no form to free, just get out of this */ /* 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 */ free(form->contents); /* free the contents */
if(form->contenttype) if(form->contenttype)
free(form->contenttype); /* free the content type */ free(form->contenttype); /* free the content type */
if(form->showfilename)
free(form->showfilename); /* free the faked file name */
free(form); /* free the struct */ free(form); /* free the struct */
} while((form=next)); /* continue */ } while((form=next)); /* continue */
} }
struct FormData *Curl_getFormData(struct HttpPost *post, CURLcode Curl_getFormData(struct FormData **finalform,
int *sizep) struct curl_httppost *post,
int *sizep)
{ {
struct FormData *form = NULL; struct FormData *form = NULL;
struct FormData *firstform; struct FormData *firstform;
struct curl_httppost *file;
struct HttpPost *file; CURLcode result = CURLE_OK;
int size =0; int size =0;
char *boundary; char *boundary;
char *fileboundary=NULL; char *fileboundary=NULL;
struct curl_slist* curList; struct curl_slist* curList;
*finalform=NULL; /* default form is empty */
if(!post) if(!post)
return NULL; /* no input => no output! */ return result; /* no input => no output! */
boundary = Curl_FormBoundary(); boundary = Curl_FormBoundary();
@ -1093,16 +1171,29 @@ struct FormData *Curl_getFormData(struct HttpPost *post,
file = post; file = post;
do { 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(post->more) {
/* if multiple-file */ /* if multiple-file */
size += AddFormDataf(&form, size += AddFormDataf(&form,
"\r\n--%s\r\nContent-Disposition: attachment; filename=\"%s\"", "\r\n--%s\r\nContent-Disposition: "
fileboundary, file->contents); "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, size += AddFormDataf(&form,
"; filename=\"%s\"", "; filename=\"%s\"",
post->contents); (post->showfilename?post->showfilename:
post->contents));
} }
if(file->contenttype) { if(file->contenttype) {
@ -1127,7 +1218,7 @@ struct FormData *Curl_getFormData(struct HttpPost *post,
*/ */
if(file->contenttype && if(file->contenttype &&
!strnequal("text/", file->contenttype, 5)) { !checkprefix("text/", file->contenttype)) {
/* this is not a text content, mention our binary encoding */ /* this is not a text content, mention our binary encoding */
size += AddFormData(&form, "\r\nContent-Transfer-Encoding: binary", 0); 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: fileread = strequal("-", file->contents)?stdin:
/* binary read for win32 crap */ /* binary read for win32 crap */
/*VMS??*/ fopen(file->contents, "rb"); /* ONLY ALLOWS FOR STREAM FILES ON VMS */ /*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?? 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?? For implied CC, every record needs to have a \n appended & 1 added to SIZE */
if(fileread) { if(fileread) {
while((nread = fread(buffer, 1, 1024, fileread))) { while((nread = fread(buffer, 1, 1024, fileread)))
size += AddFormData(&form, size += AddFormData(&form, buffer, nread);
buffer,
nread);
}
if(fileread != stdin) if(fileread != stdin)
fclose(fileread); fclose(fileread);
} }
else { else {
#if 0
/* File wasn't found, add a nothing field! */ /* File wasn't found, add a nothing field! */
size += AddFormData(&form, "", 0); 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 */ /* include the contents we got */
size += AddFormData(&form, post->contents, post->contentslength); size += AddFormData(&form, post->contents, post->contentslength);
} }
@ -1187,7 +1288,9 @@ struct FormData *Curl_getFormData(struct HttpPost *post,
free(boundary); free(boundary);
return firstform; *finalform=firstform;
return result;
} }
int Curl_FormInit(struct Form *form, struct FormData *formdata ) int Curl_FormInit(struct Form *form, struct FormData *formdata )
@ -1294,8 +1397,8 @@ int Curl_FormReadOneLine(char *buffer,
#ifdef _FORM_DEBUG #ifdef _FORM_DEBUG
int FormAddTest(const char * errormsg, int FormAddTest(const char * errormsg,
struct HttpPost **httppost, struct curl_httppost **httppost,
struct HttpPost **last_post, struct curl_httppost **last_post,
...) ...)
{ {
int result; int result;
@ -1341,8 +1444,8 @@ int main()
int size; int size;
int nread; int nread;
char buffer[4096]; char buffer[4096];
struct HttpPost *httppost=NULL; struct curl_httppost *httppost=NULL;
struct HttpPost *last_post=NULL; struct curl_httppost *last_post=NULL;
struct curl_forms forms[4]; struct curl_forms forms[4];
struct FormData *form; struct FormData *form;
@ -1451,9 +1554,9 @@ int main(int argc, char **argv)
#endif #endif
int i; int i;
char *nextarg; char *nextarg;
struct HttpPost *httppost=NULL; struct curl_httppost *httppost=NULL;
struct HttpPost *last_post=NULL; struct curl_httppost *last_post=NULL;
struct HttpPost *post; struct curl_httppost *post;
int size; int size;
int nread; int nread;
char buffer[4096]; char buffer[4096];
@ -1492,6 +1595,8 @@ int main(int argc, char **argv)
#endif #endif
#endif /* CURL_DISABLE_HTTP */
/* /*
* local variables: * local variables:
* eval: (load-file "../curl-mode.el") * eval: (load-file "../curl-mode.el")

View File

@ -1,28 +1,28 @@
#ifndef __FORMDATA_H #ifndef __FORMDATA_H
#define __FORMDATA_H #define __FORMDATA_H
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
/* plain and simple linked list with lines to send */ /* plain and simple linked list with lines to send */
struct FormData { struct FormData {
struct FormData *next; struct FormData *next;
@ -44,14 +44,23 @@ typedef struct FormInfo {
long contentslength; long contentslength;
char *contenttype; char *contenttype;
long flags; 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 curl_slist* contentheader;
struct FormInfo *more; struct FormInfo *more;
} FormInfo; } FormInfo;
int Curl_FormInit(struct Form *form, struct FormData *formdata ); int Curl_FormInit(struct Form *form, struct FormData *formdata );
struct FormData *Curl_getFormData(struct HttpPost *post, CURLcode
int *size); Curl_getFormData(struct FormData **,
struct HttpPost *post,
int *size);
/* fread() emulation */ /* fread() emulation */
int Curl_FormReader(char *buffer, int Curl_FormReader(char *buffer,

View File

@ -1,28 +1,29 @@
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
#include "setup.h" #include "setup.h"
#ifndef CURL_DISABLE_FTP
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
@ -210,16 +211,6 @@ int Curl_GetFTPResponse(char *buf,
if (ftpcode) if (ftpcode)
*ftpcode = 0; /* 0 for errors */ *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_ZERO (&readfd); /* clear it */
FD_SET (sockfd, &readfd); /* read socket */ FD_SET (sockfd, &readfd); /* read socket */
@ -235,11 +226,22 @@ int Curl_GetFTPResponse(char *buf,
keepon=TRUE; keepon=TRUE;
while((nread<BUFSIZE) && (keepon && !error)) { while((nread<BUFSIZE) && (keepon && !error)) {
readfd = rkeepfd; /* set every lap */ /* check and reset timeout value every lap */
interval.tv_sec = timeout; if(data->set.timeout) {
interval.tv_usec = 0; /* 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)) { switch (select (sockfd+1, &readfd, NULL, NULL, &interval)) {
case -1: /* select() error, stop reading */ case -1: /* select() error, stop reading */
error = SELECT_ERROR; error = SELECT_ERROR;
@ -253,6 +255,7 @@ int Curl_GetFTPResponse(char *buf,
error = SELECT_OK; error = SELECT_OK;
break; break;
} }
}
if(SELECT_OK == error) { if(SELECT_OK == error) {
/* /*
* This code previously didn't use the kerberos sec_read() code * This code previously didn't use the kerberos sec_read() code
@ -301,11 +304,8 @@ int Curl_GetFTPResponse(char *buf,
CURLcode result; CURLcode result;
/* output debug output if that is requested */ /* output debug output if that is requested */
if(data->set.verbose) { if(data->set.verbose)
fputs("< ", data->set.err); Curl_debug(data, CURLINFO_HEADER_IN, line_start, perline);
fwrite(line_start, perline, 1, data->set.err);
/* no need to output LF here, it is part of the data */
}
/* /*
* We pass all response-lines to the callback function registered * 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 */ 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 * Curl_ftp_connect() should do everything that is to be considered a part of
* support for that functionality with IPv6, this function can go in again. * 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) CURLcode Curl_ftp_connect(struct connectdata *conn)
{ {
/* this is FTP and no proxy */ /* this is FTP and no proxy */
@ -622,8 +599,10 @@ CURLcode Curl_ftp_done(struct connectdata *conn)
CURLcode result=CURLE_OK; CURLcode result=CURLE_OK;
if(data->set.upload) { if(data->set.upload) {
if((-1 != data->set.infilesize) && (data->set.infilesize != *ftp->bytecountp)) { if((-1 != data->set.infilesize) &&
failf(data, "Wrote only partial file (%d out of %d bytes)", (data->set.infilesize != *ftp->bytecountp) &&
!data->set.crlf) {
failf(data, "Uploaded unaligned file size (%d out of %d bytes)",
*ftp->bytecountp, data->set.infilesize); *ftp->bytecountp, data->set.infilesize);
return CURLE_PARTIAL_FILE; 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); failf(data, "Received only partial file: %d bytes", *ftp->bytecountp);
return CURLE_PARTIAL_FILE; return CURLE_PARTIAL_FILE;
} }
else if(!conn->bits.resume_done && else if(!ftp->dont_check &&
!data->set.no_body && !*ftp->bytecountp &&
(0 == *ftp->bytecountp)) { (conn->size>0)) {
/* We consider this an error, but there's no true FTP error received /* 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. 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 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); sclose(conn->secondarysocket);
conn->secondarysocket = -1; conn->secondarysocket = -1;
if(!data->set.no_body && !conn->bits.resume_done) { if(!ftp->no_transfer) {
/* now let's see what the server says about the transfer we /* now let's see what the server says about the transfer we just
just performed: */ performed: */
nread = Curl_GetFTPResponse(buf, conn, &ftpcode); nread = Curl_GetFTPResponse(buf, conn, &ftpcode);
if(nread < 0) if(nread < 0)
return CURLE_OPERATION_TIMEOUTED; return CURLE_OPERATION_TIMEOUTED;
/* 226 Transfer complete, 250 Requested file action okay, completed. */ if(!ftp->dont_check) {
if((ftpcode != 226) && (ftpcode != 250)) { /* 226 Transfer complete, 250 Requested file action okay, completed. */
failf(data, "server did not report OK, got %d", ftpcode); if((ftpcode != 226) && (ftpcode != 250)) {
return CURLE_FTP_WRITE_ERROR; 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? */ /* Send any post-transfer QUOTE strings? */
if(!result && data->set.postquote) if(!result && data->set.postquote)
@ -728,8 +711,7 @@ CURLcode ftp_cwd(struct connectdata *conn, char *path)
CURLcode result; CURLcode result;
FTPSENDF(conn, "CWD %s", path); FTPSENDF(conn, "CWD %s", path);
nread = Curl_GetFTPResponse( nread = Curl_GetFTPResponse(conn->data->state.buffer, conn, &ftpcode);
conn->data->state.buffer, conn, &ftpcode);
if (nread < 0) if (nread < 0)
return CURLE_OPERATION_TIMEOUTED; return CURLE_OPERATION_TIMEOUTED;
@ -898,15 +880,19 @@ ftp_pasv_verbose(struct connectdata *conn,
/* Bjorn Reese (November 28 2001): /* Bjorn Reese (November 28 2001):
The Tru64 man page on gethostbyaddr_r() says that The Tru64 man page on gethostbyaddr_r() says that
the hostent struct must be filled with zeroes before the call to 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, if(gethostbyaddr_r((char *) &address,
sizeof(address), AF_INET, sizeof(address), AF_INET,
(struct hostent *)hostent_buf, (struct hostent *)hostent_buf,
hostent_buf + sizeof(*answer))) (struct hostent_data *)(hostent_buf + sizeof(*answer))))
answer=NULL; answer=NULL;
else
answer=(struct hostent *)hostent_buf;
# endif # endif
# ifdef HAVE_GETHOSTBYADDR_R_7 # ifdef HAVE_GETHOSTBYADDR_R_7
@ -914,7 +900,7 @@ ftp_pasv_verbose(struct connectdata *conn,
answer = gethostbyaddr_r((char *) &address, sizeof(address), AF_INET, answer = gethostbyaddr_r((char *) &address, sizeof(address), AF_INET,
(struct hostent *)bigbuf, (struct hostent *)bigbuf,
hostent_buf + sizeof(*answer), hostent_buf + sizeof(*answer),
sizeof(hostent_buf) - sizeof(*answer), sizeof(bigbuf) - sizeof(*answer),
&h_errnop); &h_errnop);
# endif # endif
# ifdef HAVE_GETHOSTBYADDR_R_8 # ifdef HAVE_GETHOSTBYADDR_R_8
@ -922,7 +908,7 @@ ftp_pasv_verbose(struct connectdata *conn,
if(gethostbyaddr_r((char *) &address, sizeof(address), AF_INET, if(gethostbyaddr_r((char *) &address, sizeof(address), AF_INET,
(struct hostent *)hostent_buf, (struct hostent *)hostent_buf,
hostent_buf + sizeof(*answer), hostent_buf + sizeof(*answer),
sizeof(hostent_buf) - sizeof(*answer), sizeof(bigbuf) - sizeof(*answer),
&answer, &answer,
&h_errnop)) &h_errnop))
answer=NULL; /* error */ answer=NULL; /* error */
@ -1013,7 +999,6 @@ CURLcode ftp_use_port(struct connectdata *conn)
#endif #endif
unsigned char *ap; unsigned char *ap;
unsigned char *pp; unsigned char *pp;
int alen, plen;
char portmsgbuf[4096], tmp[4096]; char portmsgbuf[4096], tmp[4096];
const char *mode[] = { "EPRT", "LPRT", "PORT", NULL }; const char *mode[] = { "EPRT", "LPRT", "PORT", NULL };
@ -1064,18 +1049,19 @@ CURLcode ftp_use_port(struct connectdata *conn)
} }
freeaddrinfo(res); freeaddrinfo(res);
if (portsock < 0) { if (portsock < 0) {
failf(data, strerror(errno)); failf(data, "%s", strerror(errno));
return CURLE_FTP_PORT_FAILED; return CURLE_FTP_PORT_FAILED;
} }
sslen = sizeof(ss); sslen = sizeof(ss);
if (getsockname(portsock, sa, &sslen) < 0) { if (getsockname(portsock, sa, &sslen) < 0) {
failf(data, strerror(errno)); failf(data, "%s", strerror(errno));
return CURLE_FTP_PORT_FAILED; return CURLE_FTP_PORT_FAILED;
} }
for (modep = (char **)mode; modep && *modep; modep++) { for (modep = (char **)mode; modep && *modep; modep++) {
int lprtaf, eprtaf; int lprtaf, eprtaf;
int alen=0, plen=0;
switch (sa->sa_family) { switch (sa->sa_family) {
case AF_INET: case AF_INET:
@ -1197,30 +1183,42 @@ CURLcode ftp_use_port(struct connectdata *conn)
* *
*/ */
struct sockaddr_in sa; struct sockaddr_in sa;
struct hostent *h=NULL; struct Curl_dns_entry *h=NULL;
char *hostdataptr=NULL;
unsigned short porttouse; unsigned short porttouse;
char myhost[256] = ""; char myhost[256] = "";
bool sa_filled_in = FALSE;
if(data->set.ftpport) { if(data->set.ftpport) {
if(Curl_if2ip(data->set.ftpport, myhost, sizeof(myhost))) { if(Curl_if2ip(data->set.ftpport, myhost, sizeof(myhost))) {
h = Curl_resolv(data, myhost, 0, &hostdataptr); h = Curl_resolv(data, myhost, 0);
} }
else { else {
int len = strlen(data->set.ftpport); int len = strlen(data->set.ftpport);
if(len>1) if(len>1)
h = Curl_resolv(data, data->set.ftpport, 0, &hostdataptr); h = Curl_resolv(data, data->set.ftpport, 0);
if(h) if(h)
strcpy(myhost, data->set.ftpport); /* buffer overflow risk */ strcpy(myhost, data->set.ftpport); /* buffer overflow risk */
} }
} }
if(! *myhost) { if(! *myhost) {
char *tmp_host = getmyhost(myhost, sizeof(myhost)); /* pick a suitable default here */
h=Curl_resolv(data, tmp_host, 0, &hostdataptr);
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 ) { if( (portsock = socket(AF_INET, SOCK_STREAM, 0)) >= 0 ) {
int size; int size;
@ -1229,12 +1227,15 @@ CURLcode ftp_use_port(struct connectdata *conn)
we fail before the true secondary stuff is made */ we fail before the true secondary stuff is made */
conn->secondarysocket = portsock; conn->secondarysocket = portsock;
memset((char *)&sa, 0, sizeof(sa)); if(!sa_filled_in) {
memcpy((char *)&sa.sin_addr, memset((char *)&sa, 0, sizeof(sa));
h->h_addr, memcpy((char *)&sa.sin_addr,
h->h_length); h->addr->h_addr,
sa.sin_family = AF_INET; h->addr->h_length);
sa.sin_addr.s_addr = INADDR_ANY; sa.sin_family = AF_INET;
sa.sin_addr.s_addr = INADDR_ANY;
}
sa.sin_port = 0; sa.sin_port = 0;
size = sizeof(sa); size = sizeof(sa);
@ -1252,19 +1253,16 @@ CURLcode ftp_use_port(struct connectdata *conn)
if ( listen(portsock, 1) < 0 ) { if ( listen(portsock, 1) < 0 ) {
failf(data, "listen(2) failed on socket"); failf(data, "listen(2) failed on socket");
free(hostdataptr);
return CURLE_FTP_PORT_FAILED; return CURLE_FTP_PORT_FAILED;
} }
} }
else { else {
failf(data, "bind(2) failed on socket"); failf(data, "bind(2) failed on socket");
free(hostdataptr);
return CURLE_FTP_PORT_FAILED; return CURLE_FTP_PORT_FAILED;
} }
} }
else { else {
failf(data, "socket(2) failed (%s)"); failf(data, "socket(2) failed (%s)");
free(hostdataptr);
return CURLE_FTP_PORT_FAILED; return CURLE_FTP_PORT_FAILED;
} }
} }
@ -1278,7 +1276,10 @@ CURLcode ftp_use_port(struct connectdata *conn)
#endif #endif
struct in_addr in; struct in_addr in;
unsigned short ip[5]; 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 #ifdef HAVE_INET_NTOA_R
/* ignore the return code from inet_ntoa_r() as it is int or /* ignore the return code from inet_ntoa_r() as it is int or
char * depending on system */ char * depending on system */
@ -1289,6 +1290,9 @@ CURLcode ftp_use_port(struct connectdata *conn)
sscanf( inet_ntoa(in), "%hu.%hu.%hu.%hu", sscanf( inet_ntoa(in), "%hu.%hu.%hu.%hu",
&ip[0], &ip[1], &ip[2], &ip[3]); &ip[0], &ip[1], &ip[2], &ip[3]);
#endif #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", result=Curl_ftpsendf(conn, "PORT %d,%d,%d,%d,%d,%d",
ip[0], ip[1], ip[2], ip[3], ip[0], ip[1], ip[2], ip[3],
porttouse >> 8, porttouse >> 8,
@ -1320,14 +1324,15 @@ CURLcode ftp_use_port(struct connectdata *conn)
*/ */
static static
CURLcode ftp_use_pasv(struct connectdata *conn) CURLcode ftp_use_pasv(struct connectdata *conn,
bool *connected)
{ {
struct SessionHandle *data = conn->data; struct SessionHandle *data = conn->data;
ssize_t nread; ssize_t nread;
char *buf = data->state.buffer; /* this is our buffer */ char *buf = data->state.buffer; /* this is our buffer */
int ftpcode; /* receive FTP response codes in this */ int ftpcode; /* receive FTP response codes in this */
CURLcode result; CURLcode result;
Curl_addrinfo *addr=NULL; struct Curl_dns_entry *addr=NULL;
Curl_ipconnect *conninfo; Curl_ipconnect *conninfo;
/* /*
@ -1358,8 +1363,7 @@ CURLcode ftp_use_pasv(struct connectdata *conn)
#endif #endif
int modeoff; int modeoff;
unsigned short connectport; /* the local port connect() should use! */ unsigned short connectport; /* the local port connect() should use! */
unsigned short newport; /* remote port, not necessary the local one */ unsigned short newport=0; /* remote port, not necessary the local one */
char *hostdataptr=NULL;
/* newhost must be able to hold a full IP-style address in ASCII, which /* newhost must be able to hold a full IP-style address in ASCII, which
in the IPv6 case means 5*8-1 = 39 letters */ 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); for (modeoff = (data->set.ftp_use_epsv?0:1);
mode[modeoff]; modeoff++) { mode[modeoff]; modeoff++) {
result = Curl_ftpsendf(conn, mode[modeoff]); result = Curl_ftpsendf(conn, "%s", mode[modeoff]);
if(result) if(result)
return result; return result;
nread = Curl_GetFTPResponse(buf, conn, &ftpcode); nread = Curl_GetFTPResponse(buf, conn, &ftpcode);
@ -1449,18 +1453,21 @@ CURLcode ftp_use_pasv(struct connectdata *conn)
if(data->change.proxy) { if(data->change.proxy) {
/* /*
* This is a tunnel through a http proxy and we need to connect to the * 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 * proxy again here.
* previous lookup. *
* 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 = connectport =
(unsigned short)conn->port; /* we connect to the proxy's port */ (unsigned short)conn->port; /* we connect to the proxy's port */
} }
else { else {
/* normal, direct, ftp connection */ /* normal, direct, ftp connection */
addr = Curl_resolv(data, newhostp, newport, &hostdataptr); addr = Curl_resolv(data, newhostp, newport);
if(!addr) { 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; return CURLE_FTP_CANT_GET_HOST;
} }
connectport = newport; /* we connect to the remote port */ connectport = newport; /* we connect to the remote port */
@ -1470,12 +1477,21 @@ CURLcode ftp_use_pasv(struct connectdata *conn)
addr, addr,
connectport, connectport,
&conn->secondarysocket, &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) && if((CURLE_OK == result) &&
data->set.verbose) data->set.verbose)
/* this just dumps information about this second connection */ /* 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) if(CURLE_OK != result)
return result; return result;
@ -1483,7 +1499,7 @@ CURLcode ftp_use_pasv(struct connectdata *conn)
if (data->set.tunnel_thru_httpproxy) { if (data->set.tunnel_thru_httpproxy) {
/* We want "seamless" FTP operations through HTTP proxy tunnel */ /* We want "seamless" FTP operations through HTTP proxy tunnel */
result = Curl_ConnectHTTPProxyTunnel(conn, conn->secondarysocket, result = Curl_ConnectHTTPProxyTunnel(conn, conn->secondarysocket,
newhost, newport); newhostp, newport);
if(CURLE_OK != result) if(CURLE_OK != result)
return result; return result;
} }
@ -1491,125 +1507,24 @@ CURLcode ftp_use_pasv(struct connectdata *conn)
return CURLE_OK; return CURLE_OK;
} }
/*********************************************************************** /*
* Curl_ftp_nextconnect()
* *
* ftp_perform() * This function shall be called when the second FTP connection has been
* * established and is confirmed connected.
* This is the actual DO function for FTP. Get a file/directory according to
* the options previously setup.
*/ */
static CURLcode Curl_ftp_nextconnect(struct connectdata *conn)
CURLcode ftp_perform(struct connectdata *conn)
{ {
/* this is FTP and no proxy */
ssize_t nread;
CURLcode result;
struct SessionHandle *data=conn->data; struct SessionHandle *data=conn->data;
char *buf = data->state.buffer; /* this is our buffer */ 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() */ /* the ftp struct is already inited in ftp_connect() */
struct FTP *ftp = conn->proto.ftp; struct FTP *ftp = conn->proto.ftp;
long *bytecountp = ftp->bytecountp; 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) { if(data->set.upload) {
@ -1688,10 +1603,9 @@ CURLcode ftp_perform(struct connectdata *conn)
/* no data to transfer */ /* no data to transfer */
result=Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL); result=Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
/* Set resume done so that we won't get any error in /* Set no_transfer so that we won't get any error in
* Curl_ftp_done() because we didn't transfer the amount of bytes * Curl_ftp_done() because we didn't transfer anything! */
* that the local file file obviously is */ ftp->no_transfer = TRUE;
conn->bits.resume_done = TRUE;
return CURLE_OK; 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", infof(data, "range-download from %d to %d, totally %d bytes\n",
from, to, totalsize); from, to, totalsize);
ftp->dont_check = TRUE; /* dont check for successful transfer */
} }
if((data->set.ftp_list_only) || !ftp->file) { 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); result=Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
infof(data, "File already completely downloaded\n"); infof(data, "File already completely downloaded\n");
/* Set resume done so that we won't get any error in Curl_ftp_done() /* Set no_transfer so that we won't get any error in Curl_ftp_done()
* because we didn't transfer the amount of bytes that the remote * because we didn't transfer the any file */
* file obviously is */ ftp->no_transfer = TRUE;
conn->bits.resume_done = TRUE;
return CURLE_OK; return CURLE_OK;
} }
@ -1988,6 +1901,128 @@ CURLcode ftp_perform(struct connectdata *conn)
return CURLE_OK; 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() * Curl_ftp()
@ -2000,6 +2035,7 @@ CURLcode ftp_perform(struct connectdata *conn)
CURLcode Curl_ftp(struct connectdata *conn) CURLcode Curl_ftp(struct connectdata *conn)
{ {
CURLcode retcode; CURLcode retcode;
bool connected;
struct SessionHandle *data = conn->data; struct SessionHandle *data = conn->data;
struct FTP *ftp; struct FTP *ftp;
@ -2046,15 +2082,15 @@ CURLcode Curl_ftp(struct connectdata *conn)
else else
ftp->dir = NULL; ftp->dir = NULL;
retcode = ftp_perform(conn); retcode = ftp_perform(conn, &connected);
/* clean up here, success or error doesn't matter */ if(CURLE_OK == retcode) {
if(ftp->file) if(connected)
free(ftp->file); retcode = Curl_ftp_nextconnect(conn);
if(ftp->dir) else
free(ftp->dir); /* since we didn't connect now, we want do_more to get called */
conn->bits.do_more = TRUE;
ftp->file = ftp->dir = NULL; /* zero */ }
return retcode; return retcode;
} }
@ -2081,10 +2117,7 @@ CURLcode Curl_ftpsendf(struct connectdata *conn,
va_start(ap, fmt); va_start(ap, fmt);
vsnprintf(s, 250, fmt, ap); vsnprintf(s, 250, fmt, ap);
va_end(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 */ strcat(s, "\r\n"); /* append a trailing CRLF */
bytes_written=0; bytes_written=0;
@ -2097,6 +2130,9 @@ CURLcode Curl_ftpsendf(struct connectdata *conn,
if(CURLE_OK != res) if(CURLE_OK != res)
break; break;
if(conn->data->set.verbose)
Curl_debug(conn->data, CURLINFO_HEADER_OUT, sptr, bytes_written);
if(bytes_written != write_len) { if(bytes_written != write_len) {
write_len -= bytes_written; write_len -= bytes_written;
sptr += bytes_written; sptr += bytes_written;
@ -2125,6 +2161,12 @@ CURLcode Curl_ftp_disconnect(struct connectdata *conn)
free(ftp->entrypath); free(ftp->entrypath);
if(ftp->cache) if(ftp->cache)
free(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; return CURLE_OK;
} }
@ -2136,3 +2178,5 @@ CURLcode Curl_ftp_disconnect(struct connectdata *conn)
* vim600: fdm=marker * vim600: fdm=marker
* vim: et sw=2 ts=2 sts=2 tw=78 * vim: et sw=2 ts=2 sts=2 tw=78
*/ */
#endif /* CURL_DISABLE_FTP */

View File

@ -1,37 +1,37 @@
#ifndef __FTP_H #ifndef __FTP_H
#define __FTP_H #define __FTP_H
/***************************************************************************
/*****************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
#ifndef CURL_DISABLE_FTP
CURLcode Curl_ftp(struct connectdata *conn); CURLcode Curl_ftp(struct connectdata *conn);
CURLcode Curl_ftp_done(struct connectdata *conn); CURLcode Curl_ftp_done(struct connectdata *conn);
CURLcode Curl_ftp_connect(struct connectdata *conn); CURLcode Curl_ftp_connect(struct connectdata *conn);
CURLcode Curl_ftp_disconnect(struct connectdata *conn); CURLcode Curl_ftp_disconnect(struct connectdata *conn);
CURLcode Curl_ftpsendf(struct connectdata *, const char *fmt, ...); CURLcode Curl_ftpsendf(struct connectdata *, const char *fmt, ...);
/* The kerberos stuff needs this: */
int Curl_GetFTPResponse(char *buf, struct connectdata *conn, int Curl_GetFTPResponse(char *buf, struct connectdata *conn,
int *ftpcode); int *ftpcode);
CURLcode Curl_ftp_nextconnect(struct connectdata *conn);
#endif
#endif #endif

View File

@ -1,25 +1,25 @@
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
#include "setup.h" #include "setup.h"

View File

@ -1,25 +1,25 @@
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
#include "setup.h" #include "setup.h"
@ -35,6 +35,11 @@
#include <stdlib.h> #include <stdlib.h>
#endif #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 * This is supposed to be called in the beginning of a permform() session
* and should reset all session-info variables * and should reset all session-info variables
@ -49,6 +54,7 @@ CURLcode Curl_initinfo(struct SessionHandle *data)
pro->t_pretransfer = 0; pro->t_pretransfer = 0;
pro->t_starttransfer = 0; pro->t_starttransfer = 0;
pro->timespent = 0; pro->timespent = 0;
pro->t_redirect = 0;
info->httpcode = 0; info->httpcode = 0;
info->httpversion=0; info->httpversion=0;
@ -66,9 +72,9 @@ CURLcode Curl_initinfo(struct SessionHandle *data)
CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...) CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...)
{ {
va_list arg; va_list arg;
long *param_longp; long *param_longp=NULL;
double *param_doublep; double *param_doublep=NULL;
char **param_charp; char **param_charp=NULL;
va_start(arg, info); va_start(arg, info);
switch(info&CURLINFO_TYPEMASK) { switch(info&CURLINFO_TYPEMASK) {
@ -143,6 +149,12 @@ CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...)
case CURLINFO_CONTENT_LENGTH_UPLOAD: case CURLINFO_CONTENT_LENGTH_UPLOAD:
*param_doublep = data->progress.size_ul; *param_doublep = data->progress.size_ul;
break; 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: case CURLINFO_CONTENT_TYPE:
*param_charp = data->info.contenttype; *param_charp = data->info.contenttype;
break; break;

View File

@ -1,27 +1,27 @@
#ifndef __GETINFO_H #ifndef __GETINFO_H
#define __GETINFO_H #define __GETINFO_H
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...); CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...);
CURLcode Curl_initinfo(struct SessionHandle *data); 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: * 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" #include "memdebug.h"
#endif #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) char *getpass_r(const char *prompt, char *buffer, size_t buflen)
{ {
FILE *infp; FILE *infp;
char infp_fclose = 0;
FILE *outfp; FILE *outfp;
RETSIGTYPE (*sigint)(); RETSIGTYPE (*sigint)();
#ifndef __EMX__ #ifndef __EMX__
@ -127,41 +123,30 @@ char *getpass_r(const char *prompt, char *buffer, size_t buflen)
sigtstp = signal(SIGTSTP, SIG_IGN); sigtstp = signal(SIGTSTP, SIG_IGN);
#endif #endif
if( (infp=fopen("/dev/tty", "r")) == NULL ) infp=fopen("/dev/tty", "r");
{ if( NULL == infp )
infp = stdin; infp = stdin;
} else
if( (outfp=fopen("/dev/tty", "w")) == NULL ) infp_fclose = 1;
{
outfp = stderr; outfp = stderr;
}
infd = fileno(infp); infd = fileno(infp);
outfd = fileno(outfp); outfd = fileno(outfp);
/* dissable echo */ /* dissable echo */
#ifdef HAVE_TERMIOS_H #ifdef HAVE_TERMIOS_H
if(tcgetattr(outfd, &orig) != 0) tcgetattr(outfd, &orig);
{
; /*perror("tcgetattr");*/
}
noecho = orig; noecho = orig;
noecho.c_lflag &= ~ECHO; noecho.c_lflag &= ~ECHO;
if(tcsetattr(outfd, TCSANOW, &noecho) != 0) tcsetattr(outfd, TCSANOW, &noecho);
{
; /*perror("tcgetattr");*/
}
#else #else
# ifdef HAVE_TERMIO_H # ifdef HAVE_TERMIO_H
if(ioctl(outfd, TCGETA, &orig) != 0) ioctl(outfd, TCGETA, &orig);
{
; /*perror("ioctl");*/
}
noecho = orig; noecho = orig;
noecho.c_lflag &= ~ECHO; noecho.c_lflag &= ~ECHO;
if(ioctl(outfd, TCSETA, &noecho) != 0) ioctl(outfd, TCSETA, &noecho);
{
; /*perror("ioctl");*/
}
# else # else
# endif # endif
#endif #endif
@ -187,16 +172,10 @@ char *getpass_r(const char *prompt, char *buffer, size_t buflen)
* user types more than buflen * user types more than buflen
*/ */
#ifdef HAVE_TERMIOS_H #ifdef HAVE_TERMIOS_H
if(tcsetattr(outfd, TCSAFLUSH, &orig) != 0) tcsetattr(outfd, TCSAFLUSH, &orig);
{
; /*perror("tcgetattr");*/
}
#else #else
# ifdef HAVE_TERMIO_H # ifdef HAVE_TERMIO_H
if(ioctl(outfd, TCSETA, &orig) != 0) ioctl(outfd, TCSETA, &orig);
{
; /*perror("ioctl");*/
}
# else # else
# endif # endif
#endif #endif
@ -206,6 +185,9 @@ char *getpass_r(const char *prompt, char *buffer, size_t buflen)
signal(SIGTSTP, sigtstp); signal(SIGTSTP, sigtstp);
#endif #endif
if(infp_fclose)
fclose(infp);
return buffer; /* we always return success */ return buffer; /* we always return success */
} }
#endif /* VMS */ #endif /* VMS */

View File

@ -1,27 +1,27 @@
#ifndef __GETPASS_H #ifndef __GETPASS_H
#define __GETPASS_H #define __GETPASS_H
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
#ifndef HAVE_GETPASS_R #ifndef HAVE_GETPASS_R
/* If there's a system-provided function named like this, we trust it is /* If there's a system-provided function named like this, we trust it is
also found in one of the standard headers. */ also found in one of the standard headers. */

View File

@ -1,30 +1,31 @@
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2002, Daniel Stenberg, <daniel@haxx.se>, et al * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
#include "setup.h" #include "setup.h"
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include "hash.h" #include "hash.h"
#include "llist.h" #include "llist.h"
@ -34,55 +35,45 @@
#endif #endif
static unsigned long /* {{{ static unsigned long _hash_str (const char *, size_t)
curl_hash_str(const char *key, unsigned int key_length) */
static unsigned long
_hash_str (const char *key, size_t key_length)
{ {
register unsigned long h = 0; char *end = (char *) key + key_length;
register unsigned long g; unsigned long h = 5381;
register char *p = (char *) key;
register char *end = (char *) key + key_length;
while (p < end) { while (key < end) {
h = (h << 4) + *p++; h += h << 5;
if ((g = (h & 0xF0000000))) { h ^= (unsigned long) *key++;
h = h ^ (g >> 24);
h = h ^ g;
}
} }
return h; return h;
} }
/* }}} */
static unsigned long /* {{{ static void _hash_element_dtor (void *, void *)
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 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 *) user;
curl_hash *h = (curl_hash *) u; curl_hash_element *e = (curl_hash_element *) element;
if (e->key.type == CURL_HASH_KEY_IS_STRING) { if (e->key) {
free(e->key.value.str.val); free(e->key);
} }
h->dtor(e->ptr); h->dtor(e->ptr);
free(e); free(e);
e = NULL;
} }
/* }}} */
/* {{{ void curl_hash_init (curl_hash *, int, curl_hash_dtor)
*/
void 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; int i;
@ -91,116 +82,110 @@ curl_hash_init(curl_hash *h, int slots, curl_hash_dtor dtor)
h->slots = slots; h->slots = slots;
h->table = (curl_llist **) malloc(slots * sizeof(curl_llist *)); h->table = (curl_llist **) malloc(slots * sizeof(curl_llist *));
for (i = 0; i < h->slots; ++i) { for (i = 0; i < slots; ++i) {
h->table[i] = curl_llist_alloc((curl_llist_dtor) hash_element_dtor); 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 *
curl_hash_alloc(int slots, curl_hash_dtor dtor) Curl_hash_alloc (int slots, curl_hash_dtor dtor)
{ {
curl_hash *h; curl_hash *h;
h = (curl_hash *)malloc(sizeof(curl_hash)); h = (curl_hash *) malloc(sizeof(curl_hash));
if(NULL == h) if (NULL == h)
return NULL; return NULL;
curl_hash_init(h, slots, dtor); Curl_hash_init(h, slots, dtor);
return h; return h;
} }
/* }}} */
#define FIND_SLOT(__h, __s_key, __s_key_len, __n_key) \ /* {{{ static int _hash_key_compare (char *, size_t, char *, size_t)
((__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 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 (key1_len == key2_len &&
if (key2->type == CURL_HASH_KEY_IS_STRING) *key1 == *key2 &&
return 0; memcmp(key1, key2, key1_len) == 0) {
return 1;
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;
} }
return 0; return 0;
} }
/* }}} */
int /* {{{ static int _mk_hash_element (curl_hash_element **, char *, size_t, const void *)
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 **e, char *key, size_t key_len, const void *p)
{ {
curl_hash_element *e; *e = (curl_hash_element *) malloc(sizeof(curl_hash_element));
curl_hash_key tmp; (*e)->key = strdup(key);
curl_llist *l; (*e)->key_len = key_len;
curl_llist_element *le; (*e)->ptr = (void *) p;
int slot; return 0;
}
/* }}} */
slot = FIND_SLOT(h, str_key, str_key_len, num_key); #define find_slot(__h, __k, __k_len) (_hash_str(__k, __k_len) % (__h)->slots)
l = h->table[slot];
KEY_CREATE(&tmp, str_key, str_key_len, num_key, 0); #define FETCH_LIST \
for (le = CURL_LLIST_HEAD(l); le != NULL; le = CURL_LLIST_NEXT(le)) { curl_llist *l = h->table[find_slot(h, key, key_len)]
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); /* {{{ int curl_hash_add (curl_hash *, char *, size_t, const void *)
to_update->ptr = (void *) p; */
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; return 1;
} }
} }
e = (curl_hash_element *) malloc(sizeof(curl_hash_element)); if (_mk_hash_element(&he, key, key_len, p) != 0)
KEY_CREATE(&e->key, str_key, str_key_len, num_key, 1); return 0;
e->ptr = (void *) p;
if (curl_llist_insert_next(l, CURL_LLIST_TAIL(l), e)) { if (Curl_llist_insert_next(l, CURL_LLIST_TAIL(l), he)) {
++h->size; ++h->size;
return 1; return 1;
} else {
return 0;
} }
return 0;
} }
/* }}} */
/* {{{ int curl_hash_delete (curl_hash *, char *, size_t)
*/
int int
curl_hash_extended_delete(curl_hash *h, char *str_key, unsigned int str_key_len, Curl_hash_delete(curl_hash *h, char *key, size_t key_len)
unsigned long num_key)
{ {
curl_llist *l; curl_hash_element *he;
curl_llist_element *le; curl_llist_element *le;
curl_hash_key tmp; FETCH_LIST;
int slot;
slot = FIND_SLOT(h, str_key, str_key_len, num_key); for (le = CURL_LLIST_HEAD(l);
l = h->table[slot]; le != NULL;
le = CURL_LLIST_NEXT(le)) {
KEY_CREATE(&tmp, str_key, str_key_len, num_key, 0); he = CURL_LLIST_VALP(le);
for (le = CURL_LLIST_HEAD(l); le != NULL; le = CURL_LLIST_NEXT(le)) { if (_hash_key_compare(he->key, he->key_len, key, key_len)) {
if (curl_hash_key_compare(&tmp, &((curl_hash_element *) CURL_LLIST_VALP(le))->key)) { Curl_llist_remove(l, le, (void *) h);
curl_llist_remove(l, le, (void *) h);
--h->size; --h->size;
return 1; return 1;
} }
@ -208,73 +193,111 @@ curl_hash_extended_delete(curl_hash *h, char *str_key, unsigned int str_key_len,
return 0; return 0;
} }
/* }}} */
int /* {{{ int curl_hash_pick (curl_hash *, char *, size_t, void **)
curl_hash_extended_find(curl_hash *h, char *str_key, unsigned int str_key_len, */
unsigned long num_key, void **p) void *
Curl_hash_pick(curl_hash *h, char *key, size_t key_len)
{ {
curl_llist *l;
curl_llist_element *le; curl_llist_element *le;
curl_hash_key tmp; curl_hash_element *he;
int slot; FETCH_LIST;
slot = FIND_SLOT(h, str_key, str_key_len, num_key); for (le = CURL_LLIST_HEAD(l);
l = h->table[slot]; le != NULL;
le = CURL_LLIST_NEXT(le)) {
KEY_CREATE(&tmp, str_key, str_key_len, num_key, 0); he = CURL_LLIST_VALP(le);
for (le = CURL_LLIST_HEAD(l); le != NULL; le = CURL_LLIST_NEXT(le)) { if (_hash_key_compare(he->key, he->key_len, key, key_len)) {
if (curl_hash_key_compare(&tmp, &((curl_hash_element *) CURL_LLIST_VALP(le))->key)) { return he->ptr;
*p = ((curl_hash_element *) CURL_LLIST_VALP(le))->ptr;
return 1;
} }
} }
return 0; return NULL;
} }
/* }}} */
/* {{{ void curl_hash_apply (curl_hash *, void *, void (*)(void *, curl_hash_element *))
*/
void 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; curl_llist_element *le;
int i; int i;
for (i = 0; i < h->slots; ++i) { for (i = 0; i < h->slots; ++i) {
for (le = CURL_LLIST_HEAD(h->table[i]); le != NULL; le = CURL_LLIST_NEXT(le)) { for (le = CURL_LLIST_HEAD(h->table[i]);
cb(user, (curl_hash_element *) CURL_LLIST_VALP(le)); 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 void
curl_hash_clean(curl_hash *h) Curl_hash_clean(curl_hash *h)
{ {
int i; int i;
for (i = 0; i < h->slots; ++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); 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 /* {{{ int curl_hash_count (curl_hash *)
curl_hash_count(curl_hash *h) */
int
Curl_hash_count(curl_hash *h)
{ {
return h->size; return h->size;
} }
/* }}} */
/* {{{ void curl_hash_destroy (curl_hash *)
*/
void void
curl_hash_destroy(curl_hash *h) Curl_hash_destroy(curl_hash *h)
{ {
if (!h) { if (!h)
return; return;
}
curl_hash_clean(h); Curl_hash_clean(h);
free(h); free(h);
h = NULL;
} }
/* }}} */
/* /*
* local variables: * local variables:

View File

@ -1,27 +1,27 @@
#ifndef __HASH_H #ifndef __HASH_H
#define __HASH_H #define __HASH_H
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
#include "setup.h" #include "setup.h"
@ -29,9 +29,6 @@
#include "llist.h" #include "llist.h"
#define CURL_HASH_KEY_IS_STRING 0
#define CURL_HASH_KEY_IS_NUM 1
typedef void (*curl_hash_dtor)(void *); typedef void (*curl_hash_dtor)(void *);
typedef struct _curl_hash { typedef struct _curl_hash {
@ -41,45 +38,31 @@ typedef struct _curl_hash {
size_t size; size_t size;
} curl_hash; } 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 { typedef struct _curl_hash_element {
curl_hash_key key; void *ptr;
void *ptr; char *key;
size_t key_len;
} curl_hash_element; } curl_hash_element;
void curl_hash_init(curl_hash *h, int slots, curl_hash_dtor dtor); void Curl_hash_init(curl_hash *, int, curl_hash_dtor);
curl_hash *curl_hash_alloc(int slots, curl_hash_dtor dtor); curl_hash *Curl_hash_alloc(int, curl_hash_dtor);
int curl_hash_add_or_update(curl_hash *h, char *str_key, unsigned int str_key_len, int Curl_hash_add(curl_hash *, char *, size_t, const void *);
unsigned long num_key, const void *p); int Curl_hash_delete(curl_hash *h, char *key, size_t key_len);
int curl_hash_extended_delete(curl_hash *h, char *str_key, unsigned int str_key_len, void *Curl_hash_pick(curl_hash *, char *, size_t);
unsigned long num_key); void Curl_hash_apply(curl_hash *h, void *user,
int curl_hash_extended_find(curl_hash *h, char *str_key, unsigned int str_key_len, void (*cb)(void *user, void *ptr));
unsigned long num_key, void **p); int Curl_hash_count(curl_hash *h);
void curl_hash_apply(curl_hash *h, void *user, void (*cb)(void *, curl_hash_element *)); void Curl_hash_clean(curl_hash *h);
size_t curl_hash_count(curl_hash *h); void Curl_hash_clean_with_criterium(curl_hash *h, void *user, int (*comp)(void *, void *));
void curl_hash_clean(curl_hash *h); void Curl_hash_destroy(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
#endif #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 ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
#include "setup.h" #include "setup.h"
@ -56,6 +56,10 @@
#endif #endif
#endif #endif
#ifdef HAVE_SETJMP_H
#include <setjmp.h>
#endif
#include "urldata.h" #include "urldata.h"
#include "sendf.h" #include "sendf.h"
#include "hostip.h" #include "hostip.h"
@ -76,10 +80,15 @@
static curl_hash hostname_cache; static curl_hash hostname_cache;
static int host_cache_initialized; 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) void Curl_global_host_cache_init(void)
{ {
if (!host_cache_initialized) { if (!host_cache_initialized) {
curl_hash_init(&hostname_cache, 7, Curl_freeaddrinfo); Curl_hash_init(&hostname_cache, 7, Curl_freeaddrinfo);
host_cache_initialized = 1; host_cache_initialized = 1;
} }
} }
@ -92,16 +101,11 @@ curl_hash *Curl_global_host_cache_get(void)
void Curl_global_host_cache_dtor(void) void Curl_global_host_cache_dtor(void)
{ {
if (host_cache_initialized) { if (host_cache_initialized) {
curl_hash_clean(&hostname_cache); Curl_hash_clean(&hostname_cache);
host_cache_initialized = 0; 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 */ /* count the number of characters that an integer takes up */
static int _num_chars(int i) static int _num_chars(int i)
{ {
@ -125,7 +129,7 @@ static int _num_chars(int i)
/* Create a hostcache id */ /* Create a hostcache id */
static char * 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; char *id = NULL;
@ -152,70 +156,132 @@ _create_hostcache_id(char *server, int port, ssize_t *entry_len)
return id; return id;
} }
/* Macro to save redundant free'ing of entry_id */ struct hostcache_prune_data {
#define _hostcache_return(__v) \ int cache_timeout;
{ \ int now;
free(entry_id); \ };
return (__v); \
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, static void
char *hostname, hostcache_prune(curl_hash *hostcache, int cache_timeout, int now)
int port, {
char **bufp) 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; char *entry_id = NULL;
struct curl_dns_cache_entry *p = NULL; struct Curl_dns_entry *dns = NULL;
ssize_t entry_len; ssize_t entry_len;
time_t now; time_t now;
char *bufp;
/* If the host cache timeout is 0, we don't do DNS cach'ing #ifdef HAVE_SIGSETJMP
so fall through */ /* this allows us to time-out from the name resolver, as the timeout
if (data->set.dns_cache_timeout == 0) { will generate a signal and we will siglongjmp() from that here */
return Curl_getaddrinfo(data, hostname, port, bufp); 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 */ /* Create an entry id, based upon the hostname and port */
entry_len = strlen(hostname); entry_len = strlen(hostname);
entry_id = _create_hostcache_id(hostname, port, &entry_len); entry_id = create_hostcache_id(hostname, port, &entry_len);
/* If we can't create the entry id, don't cache, just fall-through /* If we can't create the entry id, fail */
to the plain Curl_getaddrinfo() */ if (!entry_id)
if (!entry_id) { return NULL;
return Curl_getaddrinfo(data, hostname, port, bufp);
}
time(&now);
/* See if its already in our dns cache */ /* See if its already in our dns cache */
if (entry_id && curl_hash_find(data->hostcache, entry_id, entry_len+1, (void **) &p)) { dns = Curl_hash_pick(data->hostcache, entry_id, entry_len+1);
/* Do we need to check for a cache timeout? */
if (data->set.dns_cache_timeout != -1) { if (!dns) {
/* Return if the entry has not timed out */ Curl_addrinfo *addr = my_getaddrinfo(data, hostname, port, &bufp);
if ((now - p->timestamp) < data->set.dns_cache_timeout) {
_hostcache_return(p->addr); 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 */ dns->timestamp = now;
p = (struct curl_dns_cache_entry *) malloc(sizeof(struct curl_dns_cache_entry)); dns->inuse++; /* mark entry as in-use */
if (!p) { #ifdef MALLOCDEBUG
_hostcache_return(NULL); dns->entry_id = entry_id;
} #endif
p->addr = Curl_getaddrinfo(data, hostname, port, bufp); /* Remove outdated and unused entries from the hostcache */
if (!p->addr) { hostcache_prune(data->hostcache,
free(p); data->set.dns_cache_timeout,
_hostcache_return(NULL); now);
}
p->timestamp = now;
/* Save it in our host cache */ HOSTCACHE_RETURN(dns);
curl_hash_update(data->hostcache, entry_id, entry_len+1, (const void *) p);
_hostcache_return(p->addr);
} }
/* /*
@ -225,7 +291,7 @@ Curl_addrinfo *Curl_resolv(struct SessionHandle *data,
*/ */
void Curl_freeaddrinfo(void *freethis) 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 #ifdef ENABLE_IPV6
freeaddrinfo(p->addr); 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 * memory we need to free after use. That meory *MUST* be freed with
* Curl_freeaddrinfo(), nothing else. * Curl_freeaddrinfo(), nothing else.
*/ */
Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data, static Curl_addrinfo *my_getaddrinfo(struct SessionHandle *data,
char *hostname, char *hostname,
int port, int port,
char **bufp) char **bufp)
{ {
struct addrinfo hints, *res; struct addrinfo hints, *res;
int error; int error;
char sbuf[NI_MAXSERV]; 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)); memset(&hints, 0, sizeof(hints));
hints.ai_family = PF_INET; hints.ai_family = pf;
hints.ai_socktype = SOCK_STREAM; hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_CANONNAME; hints.ai_flags = AI_CANONNAME;
snprintf(sbuf, sizeof(sbuf), "%d", port); snprintf(sbuf, sizeof(sbuf), "%d", port);
error = getaddrinfo(hostname, sbuf, &hints, &res); error = getaddrinfo(hostname, sbuf, &hints, &res);
if (error) { if (error) {
infof(data, "getaddrinfo(3) failed for %s\n", hostname); infof(data, "getaddrinfo(3) failed for %s:%d\n", hostname, port);
return NULL; return NULL;
} }
*bufp=(char *)res; /* make it point to the result struct */ *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 */ #else /* following code is IPv4-only */
#ifndef HAVE_GETHOSTBYNAME_R #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 * 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! * copy). Make absolutely sure the destination buffer is big enough!
* *
* Keith McGuigan * Keith McGuigan
* 10/3/2001 */ * 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; struct hostent* copy;
int i; int i;
char* str; char *str;
int len; int len;
bufptr = buf; bufptr = *buf;
copy = (struct hostent*)bufptr; copy = (struct hostent*)bufptr;
bufptr += sizeof(struct hostent); bufptr += sizeof(struct hostent);
@ -334,10 +416,12 @@ static struct hostent* pack_hostent(char* buf, struct hostent* orig)
bufptr += len; bufptr += len;
/* we align on even 64bit boundaries for safety */ /* 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! */ /* 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 */ /* Figure out how many aliases there are */
for (i = 0; orig->h_aliases[i] != NULL; ++i); 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; copy->h_length = orig->h_length;
/* align it for (at least) 32bit accesses */ /* align it for (at least) 32bit accesses */
bufptr = (char *)MEMALIGN(bufptr); bufptr = MEMALIGN(bufptr);
copy->h_addr_list = (char**)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; 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; return copy;
} }
#endif #endif
@ -405,18 +501,34 @@ static char *MakeIP(unsigned long num,char *addr, int addr_len)
return (addr); 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 #ifndef INADDR_NONE
#define INADDR_NONE (in_addr_t) ~0 #define INADDR_NONE (in_addr_t) ~0
#endif #endif
Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data, static void hostcache_fixoffset(struct hostent *h, int offset)
char *hostname, {
int port, int i=0;
char **bufp) 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; struct hostent *h = NULL;
in_addr_t in; 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 * everything. OSF1 is known to require at least 8872 bytes. The buffer
* required for storing all possible aliases and IP numbers is according to * required for storing all possible aliases and IP numbers is according to
* Stevens' Unix Network Programming 2nd editor, p. 304: 8192 bytes! */ * 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 */ port=0; /* unused in IPv4 code */
ret = 0; /* to prevent the compiler warning */ ret = 0; /* to prevent the compiler warning */
if ( (in=inet_addr(hostname)) != INADDR_NONE ) { if ( (in=inet_addr(hostname)) != INADDR_NONE ) {
struct in_addr *addrentry; 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 = &buf->hostentry;
h->h_addr_list = (char**)(buf + sizeof(*h)); h->h_addr_list = &buf->h_addr_list[0];
addrentry = (struct in_addr*)(h->h_addr_list + 2); addrentry = &buf->addrentry;
addrentry->s_addr = in; addrentry->s_addr = in;
h->h_addr_list[0] = (char*)addrentry; h->h_addr_list[0] = (char*)addrentry;
h->h_addr_list[1] = NULL; h->h_addr_list[1] = NULL;
h->h_addrtype = AF_INET; h->h_addrtype = AF_INET;
h->h_length = sizeof(*addrentry); h->h_length = sizeof(*addrentry);
h->h_name = *(h->h_addr_list) + h->h_length; h->h_name = &buf->h_name[0];
/* bad one h->h_name = (char*)(h->h_addr_list + h->h_length); */ MakeIP(ntohl(in), h->h_name, sizeof(buf->h_name));
MakeIP(ntohl(in),h->h_name, CURL_NAMELOOKUP_SIZE - (long)(h->h_name) + (long)buf);
} }
#if defined(HAVE_GETHOSTBYNAME_R) #if defined(HAVE_GETHOSTBYNAME_R)
else { else {
int h_errnop; 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_ /* Workaround for gethostbyname_r bug in qnx nto. It is also _required_
for some of these functions. */ for some of these functions. */
memset(buf, 0, CURL_NAMELOOKUP_SIZE); memset(buf, 0, CURL_NAMELOOKUP_SIZE);
#ifdef HAVE_GETHOSTBYNAME_R_5 #ifdef HAVE_GETHOSTBYNAME_R_5
/* Solaris, IRIX and more */ /* Solaris, IRIX and more */
if ((h = gethostbyname_r(hostname, (void)res; /* prevent compiler warning */
(struct hostent *)buf, while(!h) {
(char *)buf + sizeof(struct hostent), h = gethostbyname_r(hostname,
CURL_NAMELOOKUP_SIZE - sizeof(struct hostent), (struct hostent *)buf,
&h_errnop)) == NULL ) (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 #endif
#ifdef HAVE_GETHOSTBYNAME_R_6 #ifdef HAVE_GETHOSTBYNAME_R_6
/* Linux */ /* Linux */
if( gethostbyname_r(hostname, do {
(struct hostent *)buf, res=gethostbyname_r(hostname,
(char *)buf + sizeof(struct hostent), (struct hostent *)buf,
CURL_NAMELOOKUP_SIZE - sizeof(struct hostent), (char *)buf + sizeof(struct hostent),
&h, /* DIFFERENCE */ step_size - sizeof(struct hostent),
&h_errnop)) &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 #endif
#ifdef HAVE_GETHOSTBYNAME_R_3 #ifdef HAVE_GETHOSTBYNAME_R_3
/* AIX, Digital Unix, HPUX 10, more? */ /* AIX, Digital Unix, HPUX 10, more? */
@ -484,8 +661,8 @@ Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data,
* size dilemma. */ * size dilemma. */
ret = gethostbyname_r(hostname, ret = gethostbyname_r(hostname,
(struct hostent *)buf, (struct hostent *)buf,
(struct hostent_data *)(buf + sizeof(struct hostent))); (struct hostent_data *)((char *)buf + sizeof(struct hostent)));
else else
ret = -1; /* failure, too smallish buffer size */ ret = -1; /* failure, too smallish buffer size */
@ -504,14 +681,17 @@ Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data,
else { else {
if ((h = gethostbyname(hostname)) == NULL ) { if ((h = gethostbyname(hostname)) == NULL ) {
infof(data, "gethostbyname(2) failed for %s\n", hostname); infof(data, "gethostbyname(2) failed for %s\n", hostname);
free(buf);
*bufp=NULL; *bufp=NULL;
} }
else else
{
char *buf=(char *)malloc(CURL_NAMELOOKUP_SIZE);
/* we make a copy of the hostent right now, right here, as the /* 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 static one we got a pointer to might get removed when we don't
want/expect that */ want/expect that */
h = pack_hostent((char *)buf, h); h = pack_hostent(&buf, h);
*bufp=(char *)buf;
}
#endif #endif
} }
return (h); return (h);

View File

@ -1,28 +1,29 @@
#ifndef __HOSTIP_H #ifndef __HOSTIP_H
#define __HOSTIP_H #define __HOSTIP_H
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
#include "setup.h"
#include "hash.h" #include "hash.h"
struct addrinfo; 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) #define Curl_global_host_cache_use(__p) ((__p)->set.global_dns_cache)
Curl_addrinfo *Curl_resolv(struct SessionHandle *data, struct Curl_dns_entry {
char *hostname, Curl_addrinfo *addr;
int port, time_t timestamp;
char **bufp); 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 */ /* free name info */
void Curl_freeaddrinfo(void *freethis); void Curl_freeaddrinfo(void *freethis);

View File

@ -1,28 +1,29 @@
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
#include "setup.h" #include "setup.h"
#ifndef CURL_DISABLE_HTTP
/* -- WIN32 approved -- */ /* -- WIN32 approved -- */
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -133,12 +134,6 @@ CURLcode add_buffer_send(int sockfd, struct connectdata *conn, send_buffer *in,
char *ptr; char *ptr;
int size; 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 /* 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 */ 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) if(CURLE_OK != res)
break; break;
if(conn->data->set.verbose)
/* this data _may_ contain binary stuff */
Curl_debug(conn->data, CURLINFO_HEADER_OUT, ptr, amount);
if(amount != size) { if(amount != size) {
size -= amount; size -= amount;
ptr += amount; ptr += amount;
@ -163,7 +162,7 @@ CURLcode add_buffer_send(int sockfd, struct connectdata *conn, send_buffer *in,
free(in->buffer); free(in->buffer);
free(in); free(in);
*bytes_written = amount; *bytes_written += amount;
return res; return res;
} }
@ -364,11 +363,8 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
the line isn't really terminated until the LF comes */ the line isn't really terminated until the LF comes */
/* output debug output if that is requested */ /* output debug output if that is requested */
if(data->set.verbose) { if(data->set.verbose)
fputs("< ", data->set.err); Curl_debug(data, CURLINFO_DATA_IN, line_start, perline);
fwrite(line_start, perline, 1, data->set.err);
/* no need to output LF here, it is part of the data */
}
if('\r' == line_start[0]) { if('\r' == line_start[0]) {
/* end of headers */ /* end of headers */
@ -392,7 +388,7 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
} /* while there's buffer left and loop is requested */ } /* while there's buffer left and loop is requested */
if(error) if(error)
return CURLE_READ_ERROR; return CURLE_RECV_ERROR;
if(200 != httperror) { if(200 != httperror) {
if(407 == httperror) if(407 == httperror)
@ -400,7 +396,7 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
failf(data, "Proxy requires authorization!"); failf(data, "Proxy requires authorization!");
else else
failf(data, "Received error code %d from proxy", httperror); 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"); 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 * has occured, can we start talking SSL
*/ */
if(data->change.proxy && if(conn->bits.httpproxy &&
((conn->protocol & PROT_HTTPS) || data->set.tunnel_thru_httpproxy)) { ((conn->protocol & PROT_HTTPS) || data->set.tunnel_thru_httpproxy)) {
/* either HTTPS over proxy, OR explicitly asked for a tunnel */ /* 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) CURLcode Curl_http_done(struct connectdata *conn)
{ {
struct SessionHandle *data; struct SessionHandle *data;
long *bytecount = &conn->bytecount;
struct HTTP *http; struct HTTP *http;
data=conn->data; data=conn->data;
http=conn->proto.http; http=conn->proto.http;
if(HTTPREQ_POST_FORM == data->set.httpreq) { 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 */ Curl_formclean(http->sendit); /* Now free that whole lot */
data->set.fread = http->storefread; /* restore */ data->set.fread = http->storefread; /* restore */
data->set.in = http->in; /* restore */ data->set.in = http->in; /* restore */
} }
else if(HTTPREQ_PUT == data->set.httpreq) { else if(HTTPREQ_PUT == data->set.httpreq)
*bytecount = http->readbytecount + http->writebytecount; conn->bytecount = http->readbytecount + http->writebytecount;
}
if(0 == (http->readbytecount + conn->headerbytecount)) { if(0 == (http->readbytecount + conn->headerbytecount)) {
/* nothing was read from the HTTP server, this can't be right /* 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 */ struct Cookie *co=NULL; /* no cookies from start */
char *ppath = conn->ppath; /* three previous function arguments */ char *ppath = conn->ppath; /* three previous function arguments */
char *host = conn->name; char *host = conn->name;
long *bytecount = &conn->bytecount; const char *te = ""; /* tranfer-encoding */
if(!conn->proto.http) { if(!conn->proto.http) {
/* Only allocate this struct if we don't already have it! */ /* 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); 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) { if(data->cookies) {
co = Curl_cookie_getlist(data->cookies, co = Curl_cookie_getlist(data->cookies,
host, ppath, 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 && !data->set.tunnel_thru_httpproxy &&
!(conn->protocol&PROT_HTTPS)) { !(conn->protocol&PROT_HTTPS)) {
/* The path sent to the proxy is in fact the entire URL */ /* 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) { if(HTTPREQ_POST_FORM == data->set.httpreq) {
/* we must build the whole darned post sequence first, so that we have /* 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 */ 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:")) { if(!checkheaders(data, "Host:")) {
@ -579,13 +587,22 @@ CURLcode Curl_http(struct connectdata *conn)
if(conn->allocptr.host) if(conn->allocptr.host)
free(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)) || if(((conn->protocol&PROT_HTTPS) && (conn->remote_port == PORT_HTTPS)) ||
(!(conn->protocol&PROT_HTTPS) && (conn->remote_port == PORT_HTTP)) ) (!(conn->protocol&PROT_HTTPS) && (conn->remote_port == PORT_HTTP)) )
/* If (HTTPS on port 443) OR (non-HTTPS on port 80) then don't include /* If (HTTPS on port 443) OR (non-HTTPS on port 80) then don't include
the port number in the host string */ 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 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); conn->remote_port);
} }
@ -661,6 +678,9 @@ CURLcode Curl_http(struct connectdata *conn)
*/ */
if((data->set.httpreq == HTTPREQ_GET) && if((data->set.httpreq == HTTPREQ_GET) &&
!checkheaders(data, "Range:")) { !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); conn->allocptr.rangeline = aprintf("Range: bytes=%s\r\n", conn->range);
} }
else if((data->set.httpreq != HTTPREQ_GET) && else if((data->set.httpreq != HTTPREQ_GET) &&
@ -705,7 +725,9 @@ CURLcode Curl_http(struct connectdata *conn)
"%s" /* host */ "%s" /* host */
"%s" /* pragma */ "%s" /* pragma */
"%s" /* accept */ "%s" /* accept */
"%s", /* referer */ "%s" /* accept-encoding */
"%s" /* referer */
"%s",/* transfer-encoding */
data->set.customrequest?data->set.customrequest: data->set.customrequest?data->set.customrequest:
(data->set.no_body?"HEAD": (data->set.no_body?"HEAD":
@ -725,7 +747,10 @@ CURLcode Curl_http(struct connectdata *conn)
(conn->allocptr.host?conn->allocptr.host:""), /* Host: host */ (conn->allocptr.host?conn->allocptr.host:""), /* Host: host */
http->p_pragma?http->p_pragma:"", http->p_pragma?http->p_pragma:"",
http->p_accept?http->p_accept:"", 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) { if(co) {
@ -780,16 +805,16 @@ CURLcode Curl_http(struct connectdata *conn)
strcpy(buf, "no strftime() support"); strcpy(buf, "no strftime() support");
#endif #endif
switch(data->set.timecondition) { switch(data->set.timecondition) {
case TIMECOND_IFMODSINCE: case CURL_TIMECOND_IFMODSINCE:
default: default:
add_bufferf(req_buffer, add_bufferf(req_buffer,
"If-Modified-Since: %s\r\n", buf); "If-Modified-Since: %s\r\n", buf);
break; break;
case TIMECOND_IFUNMODSINCE: case CURL_TIMECOND_IFUNMODSINCE:
add_bufferf(req_buffer, add_bufferf(req_buffer,
"If-Unmodified-Since: %s\r\n", buf); "If-Unmodified-Since: %s\r\n", buf);
break; break;
case TIMECOND_LASTMOD: case CURL_TIMECOND_LASTMOD:
add_bufferf(req_buffer, add_bufferf(req_buffer,
"Last-Modified: %s\r\n", buf); "Last-Modified: %s\r\n", buf);
break; break;
@ -814,7 +839,9 @@ CURLcode Curl_http(struct connectdata *conn)
headers = headers->next; 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)) { if(Curl_FormInit(&http->form, http->sendit)) {
failf(data, "Internal HTTP POST error!"); failf(data, "Internal HTTP POST error!");
return CURLE_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 */ Curl_formclean(http->sendit); /* free that whole lot */
return result; return result;
} }
} break;
else if(HTTPREQ_PUT == data->set.httpreq) {
/* Let's PUT the data to the server! */ case HTTPREQ_PUT: /* Let's PUT the data to the server! */
if(data->set.infilesize>0) { if(data->set.infilesize>0) {
add_bufferf(req_buffer, add_bufferf(req_buffer,
@ -911,51 +938,53 @@ CURLcode Curl_http(struct connectdata *conn)
&http->writebytecount); &http->writebytecount);
if(result) if(result)
return result; return result;
break;
}
else {
if(HTTPREQ_POST == data->set.httpreq) {
/* this is the simple POST, using x-www-form-urlencoded style */
if(!data->set.postfields) { case HTTPREQ_POST:
/* /* this is the simple POST, using x-www-form-urlencoded style */
* 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! */
}
if(!checkheaders(data, "Content-Length:")) if(!checkheaders(data, "Content-Length:"))
/* we allow replacing this header, although it isn't very wise to /* we allow replacing this header, although it isn't very wise to
actually set your own */ actually set your own */
add_bufferf(req_buffer, add_bufferf(req_buffer,
"Content-Length: %d\r\n", "Content-Length: %d\r\n",
(data->set.postfieldsize?data->set.postfieldsize: data->set.postfieldsize?
strlen(data->set.postfields)) ); data->set.postfieldsize:
(data->set.postfields?strlen(data->set.postfields):0) );
if(!checkheaders(data, "Content-Type:")) if(!checkheaders(data, "Content-Type:"))
add_bufferf(req_buffer, add_bufferf(req_buffer,
"Content-Type: application/x-www-form-urlencoded\r\n"); "Content-Type: application/x-www-form-urlencoded\r\n");
/* and here comes the actual data */ add_buffer(req_buffer, "\r\n", 2);
if(data->set.postfieldsize) {
add_buffer(req_buffer, "\r\n", 2); /* and here comes the actual data */
add_buffer(req_buffer, data->set.postfields, if(data->set.postfieldsize && data->set.postfields) {
data->set.postfieldsize); add_buffer(req_buffer, data->set.postfields,
} data->set.postfieldsize);
else {
add_bufferf(req_buffer,
"\r\n"
"%s",
data->set.postfields );
}
} }
else else if(data->set.postfields)
add_buffer(req_buffer, "\r\n", 2); 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 */ /* issue the request */
result = add_buffer_send(conn->firstsocket, conn, req_buffer, result = add_buffer_send(conn->firstsocket, conn, req_buffer,
&data->info.request_size); &data->info.request_size);
@ -964,7 +993,8 @@ CURLcode Curl_http(struct connectdata *conn)
failf(data, "Failed sending HTTP request"); failf(data, "Failed sending HTTP request");
else else
/* HTTP GET/HEAD download: */ /* 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 */ -1, NULL); /* nothing to upload */
} }
if(result) if(result)
@ -983,3 +1013,4 @@ CURLcode Curl_http(struct connectdata *conn)
* vim600: fdm=marker * vim600: fdm=marker
* vim: et sw=2 ts=2 sts=2 tw=78 * vim: et sw=2 ts=2 sts=2 tw=78
*/ */
#endif

View File

@ -1,29 +1,29 @@
#ifndef __HTTP_H #ifndef __HTTP_H
#define __HTTP_H #define __HTTP_H
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
#ifndef CURL_DISABLE_HTTP
/* ftp can use this as well */ /* ftp can use this as well */
CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn, CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
int tunnelsocket, int tunnelsocket,
@ -38,5 +38,5 @@ CURLcode Curl_http_connect(struct connectdata *conn);
void Curl_httpchunk_init(struct connectdata *conn); void Curl_httpchunk_init(struct connectdata *conn);
CHUNKcode Curl_httpchunk_read(struct connectdata *conn, char *datap, CHUNKcode Curl_httpchunk_read(struct connectdata *conn, char *datap,
ssize_t length, ssize_t *wrote); ssize_t length, ssize_t *wrote);
#endif
#endif #endif

View File

@ -1,27 +1,28 @@
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
#include "setup.h" #include "setup.h"
#ifndef CURL_DISABLE_HTTP
/* -- WIN32 approved -- */ /* -- WIN32 approved -- */
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -32,6 +33,8 @@
#include "urldata.h" /* it includes http_chunks.h */ #include "urldata.h" /* it includes http_chunks.h */
#include "sendf.h" /* for the client write stuff */ #include "sendf.h" /* for the client write stuff */
#include "content_encoding.h" /* 08/29/02 jhrg */
#define _MPRINTF_REPLACE /* use our functions only */ #define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h> #include <curl/mprintf.h>
@ -171,7 +174,32 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
piece = (ch->datasize >= length)?length:ch->datasize; piece = (ch->datasize >= length)?length:ch->datasize;
/* Write the data portion available */ /* 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) if(result)
return CHUNKE_WRITE_ERROR; return CHUNKE_WRITE_ERROR;
*wrote += piece; *wrote += piece;
@ -228,3 +256,4 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
* vim600: fdm=marker * vim600: fdm=marker
* vim: et sw=2 ts=2 sts=2 tw=78 * vim: et sw=2 ts=2 sts=2 tw=78
*/ */
#endif /* CURL_DISABLE_HTTP */

View File

@ -1,27 +1,27 @@
#ifndef __HTTP_CHUNKS_H #ifndef __HTTP_CHUNKS_H
#define __HTTP_CHUNKS_H #define __HTTP_CHUNKS_H
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
/* /*
* The longest possible hexadecimal number we support in a chunked transfer. * The longest possible hexadecimal number we support in a chunked transfer.
* Weird enough, RFC2616 doesn't set a maximum size! Since we use strtoul() * Weird enough, RFC2616 doesn't set a maximum size! Since we use strtoul()
@ -73,6 +73,7 @@ typedef enum {
CHUNKE_BAD_CHUNK, CHUNKE_BAD_CHUNK,
CHUNKE_WRITE_ERROR, CHUNKE_WRITE_ERROR,
CHUNKE_STATE_ERROR, CHUNKE_STATE_ERROR,
CHUNKE_BAD_ENCODING,
CHUNKE_LAST CHUNKE_LAST
} CHUNKcode; } CHUNKcode;

View File

@ -1,25 +1,25 @@
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
#include "setup.h" #include "setup.h"

View File

@ -1,27 +1,27 @@
#ifndef __IF2IP_H #ifndef __IF2IP_H
#define __IF2IP_H #define __IF2IP_H
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
#include "setup.h" #include "setup.h"
#if ! defined(WIN32) && ! defined(__BEOS__) && !defined(__CYGWIN32__) #if ! defined(WIN32) && ! defined(__BEOS__) && !defined(__CYGWIN32__)

View File

@ -40,6 +40,7 @@
#include "setup.h" #include "setup.h"
#ifndef CURL_DISABLE_FTP
#ifdef KRB4 #ifdef KRB4
#include "security.h" #include "security.h"
@ -197,7 +198,7 @@ krb4_auth(void *app_data, struct connectdata *conn)
int checksum; int checksum;
u_int32_t cs; u_int32_t cs;
struct krb4_data *d = app_data; struct krb4_data *d = app_data;
char *host = conn->hostaddr->h_name; char *host = conn->hostname;
ssize_t nread; ssize_t nread;
int l = sizeof(conn->local_addr); int l = sizeof(conn->local_addr);
struct SessionHandle *data = conn->data; struct SessionHandle *data = conn->data;
@ -362,7 +363,7 @@ void Curl_krb_kauth(struct connectdata *conn)
if (strcmp ((char*)tktcopy.dat + 8, if (strcmp ((char*)tktcopy.dat + 8,
KRB_TICKET_GRANTING_TICKET) != 0) { KRB_TICKET_GRANTING_TICKET) != 0) {
afs_string_to_key (passwd, afs_string_to_key (passwd,
krb_realmofhost(conn->hostaddr->h_name), krb_realmofhost(conn->hostname),
&key); &key);
des_key_sched (&key, schedule); des_key_sched (&key, schedule);
des_pcbc_encrypt((des_cblock*)tkt.dat, (des_cblock*)tktcopy.dat, 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 /* KRB4 */
#endif /* CURL_DISABLE_FTP */
/* /*
* local variables: * local variables:

View File

@ -1,27 +1,27 @@
#ifndef __KRB4_H #ifndef __KRB4_H
#define __KRB4_H #define __KRB4_H
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
void Curl_krb_kauth(struct connectdata *conn); void Curl_krb_kauth(struct connectdata *conn);
#endif #endif

View File

@ -1,28 +1,29 @@
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
#include "setup.h" #include "setup.h"
#ifndef CURL_DISABLE_LDAP
/* -- WIN32 approved -- */ /* -- WIN32 approved -- */
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -147,7 +148,7 @@ CURLcode Curl_ldap(struct connectdata *conn)
int ldaptext; int ldaptext;
struct SessionHandle *data=conn->data; struct SessionHandle *data=conn->data;
infof(data, "LDAP: %s %s\n", data->change.url); infof(data, "LDAP: %s\n", data->change.url);
DynaOpen(); DynaOpen();
if (libldap == NULL) { if (libldap == NULL) {
@ -229,3 +230,4 @@ CURLcode Curl_ldap(struct connectdata *conn)
* vim600: fdm=marker * vim600: fdm=marker
* vim: et sw=2 ts=2 sts=2 tw=78 * vim: et sw=2 ts=2 sts=2 tw=78
*/ */
#endif

View File

@ -1,29 +1,30 @@
#ifndef __LDAP_H #ifndef __LDAP_H
#define __LDAP_H #define __LDAP_H
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
#ifndef CURL_DISABLE_LDAP
CURLcode Curl_ldap(struct connectdata *conn); CURLcode Curl_ldap(struct connectdata *conn);
CURLcode Curl_ldap_done(struct connectdata *conn); CURLcode Curl_ldap_done(struct connectdata *conn);
#endif
#endif /* __LDAP_H */ #endif /* __LDAP_H */

View File

@ -1,25 +1,25 @@
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2002, Daniel Stenberg, <daniel@haxx.se>, et al * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
#include "setup.h" #include "setup.h"
@ -33,7 +33,7 @@
#include "memdebug.h" #include "memdebug.h"
#endif #endif
void 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->size = 0;
l->dtor = dtor; l->dtor = dtor;
@ -42,7 +42,7 @@ curl_llist_init(curl_llist *l, curl_llist_dtor dtor)
} }
curl_llist * curl_llist *
curl_llist_alloc(curl_llist_dtor dtor) Curl_llist_alloc(curl_llist_dtor dtor)
{ {
curl_llist *list; curl_llist *list;
@ -50,13 +50,13 @@ curl_llist_alloc(curl_llist_dtor dtor)
if(NULL == list) if(NULL == list)
return NULL; return NULL;
curl_llist_init(list, dtor); Curl_llist_init(list, dtor);
return list; return list;
} }
int 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; curl_llist_element *ne;
@ -84,7 +84,7 @@ curl_llist_insert_next(curl_llist *list, curl_llist_element *e, const void *p)
} }
int 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; curl_llist_element *ne;
@ -111,7 +111,7 @@ curl_llist_insert_prev(curl_llist *list, curl_llist_element *e, const void *p)
} }
int 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) if (e == NULL || list->size == 0)
return 1; return 1;
@ -139,28 +139,28 @@ curl_llist_remove(curl_llist *list, curl_llist_element *e, void *user)
} }
int 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 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 size_t
curl_llist_count(curl_llist *list) Curl_llist_count(curl_llist *list)
{ {
return list->size; return list->size;
} }
void void
curl_llist_destroy(curl_llist *list, void *user) Curl_llist_destroy(curl_llist *list, void *user)
{ {
while (list->size > 0) { while (list->size > 0) {
curl_llist_remove(list, CURL_LLIST_TAIL(list), user); Curl_llist_remove(list, CURL_LLIST_TAIL(list), user);
} }
free(list); free(list);

View File

@ -1,27 +1,27 @@
#ifndef __LLIST_H #ifndef __LLIST_H
#define __LLIST_H #define __LLIST_H
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
#include "setup.h" #include "setup.h"
#include <stddef.h> #include <stddef.h>
@ -44,14 +44,14 @@ typedef struct _curl_llist {
size_t size; size_t size;
} curl_llist; } curl_llist;
void curl_llist_init(curl_llist *, curl_llist_dtor); void Curl_llist_init(curl_llist *, curl_llist_dtor);
curl_llist *curl_llist_alloc(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_next(curl_llist *, curl_llist_element *, const void *);
int curl_llist_insert_prev(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(curl_llist *, curl_llist_element *, void *);
int curl_llist_remove_next(curl_llist *, curl_llist_element *, void *); int Curl_llist_remove_next(curl_llist *, curl_llist_element *, void *);
size_t curl_llist_count(curl_llist *); size_t Curl_llist_count(curl_llist *);
void curl_llist_destroy(curl_llist *, void *); void Curl_llist_destroy(curl_llist *, void *);
#define CURL_LLIST_HEAD(__l) ((__l)->head) #define CURL_LLIST_HEAD(__l) ((__l)->head)
#define CURL_LLIST_TAIL(__l) ((__l)->tail) #define CURL_LLIST_TAIL(__l) ((__l)->tail)

View File

@ -1,26 +1,26 @@
#ifdef MALLOCDEBUG #ifdef MALLOCDEBUG
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
#include "setup.h" #include "setup.h"
@ -49,7 +49,9 @@
struct memdebug { struct memdebug {
int size; 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 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) if(logfile)
fprintf(logfile, "FILE %s:%d fclose(%p)\n", fprintf(logfile, "FILE %s:%d fclose(%p)\n",
source, line, file); source, line, file);

View File

@ -1,4 +1,26 @@
#ifdef MALLOCDEBUG #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" #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); int curl_fclose(FILE *file, int line, const char *source);
/* Set this symbol on the command-line, recompile all lib-sources */ /* Set this symbol on the command-line, recompile all lib-sources */
#undef strdup
#define strdup(ptr) curl_dostrdup(ptr, __LINE__, __FILE__) #define strdup(ptr) curl_dostrdup(ptr, __LINE__, __FILE__)
#define malloc(size) curl_domalloc(size, __LINE__, __FILE__) #define malloc(size) curl_domalloc(size, __LINE__, __FILE__)
#define realloc(ptr,size) curl_dorealloc(ptr, 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++; infop->len++;
return output; /* fputc() returns like this on success */ return output; /* fputc() returns like this on success */
} }
char *curl_maprintf(const char *format, ...) char *curl_maprintf(const char *format, ...)
@ -1044,12 +1043,17 @@ char *curl_maprintf(const char *format, ...)
va_start(ap_save, format); va_start(ap_save, format);
retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save); retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save);
va_end(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 */ info.buffer[info.len] = 0; /* we terminate this with a zero byte */
return info.buffer; return info.buffer;
} }
else else
return NULL; return strdup("");
} }
char *curl_mvaprintf(const char *format, va_list ap_save) 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; info.alloc = 0;
retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save); retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save);
info.buffer[info.len] = 0; /* we terminate this with a zero byte */ if(-1 == retcode) {
if(info.len) { if(info.alloc)
free(info.buffer);
return NULL;
}
if(info.alloc) {
info.buffer[info.len] = 0; /* we terminate this with a zero byte */ info.buffer[info.len] = 0; /* we terminate this with a zero byte */
return info.buffer; return info.buffer;
} }
else else
return NULL; return strdup("");
} }
static int storebuffer(int output, FILE *data) static int storebuffer(int output, FILE *data)

View File

@ -1,36 +1,40 @@
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
#include "setup.h" #include "setup.h"
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <curl/curl.h> #include <curl/curl.h>
#include "multi.h" /* will become <curl/multi.h> soon */
#include "urldata.h" #include "urldata.h"
#include "transfer.h" #include "transfer.h"
#include "url.h" #include "url.h"
#include "connect.h"
/* The last #include file should be: */
#ifdef MALLOCDEBUG
#include "memdebug.h"
#endif
struct Curl_message { struct Curl_message {
/* the 'CURLMsg' is the part that is visible to the external user */ /* the 'CURLMsg' is the part that is visible to the external user */
@ -40,11 +44,13 @@ struct Curl_message {
typedef enum { typedef enum {
CURLM_STATE_INIT, CURLM_STATE_INIT,
CURLM_STATE_CONNECT, CURLM_STATE_CONNECT, /* connect has been sent off */
CURLM_STATE_DO, CURLM_STATE_WAITCONNECT, /* we're awaiting the connect to finalize */
CURLM_STATE_PERFORM, CURLM_STATE_DO, /* send off the request (part 1) */
CURLM_STATE_DONE, CURLM_STATE_DO_MORE, /* send off the request (part 2) */
CURLM_STATE_COMPLETED, 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 */ CURLM_STATE_LAST /* not a true state, never use this */
} CURLMstate; } CURLMstate;
@ -59,6 +65,13 @@ struct Curl_one_easy {
CURLMstate state; /* the handle's state */ CURLMstate state; /* the handle's state */
CURLcode result; /* previous result */ 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. */ /* This is the amount of entries in the linked list above. */
int num_easy; int num_easy;
/* this is a linked list of posted messages */ int num_msgs; /* total amount of messages in the easy handles */
struct Curl_message *msgs;
/* amount of messages in the queue */
int num_msgs;
/* Hostname cache */ /* Hostname cache */
curl_hash *hostcache; 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 /* 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. */ 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 */ /* make the previous node point to our next */
if(easy->prev) if(easy->prev)
easy->prev->next = easy->next; easy->prev->next = easy->next;
@ -180,6 +194,8 @@ CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
/* NOTE NOTE NOTE /* NOTE NOTE NOTE
We do not touch the easy handle here! */ We do not touch the easy handle here! */
if (easy->msg)
free(easy->msg);
free(easy); free(easy);
multi->num_easy--; /* one less to care about now */ multi->num_easy--; /* one less to care about now */
@ -211,6 +227,32 @@ CURLMcode curl_multi_fdset(CURLM *multi_handle,
switch(easy->state) { switch(easy->state) {
default: default:
break; 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: case CURLM_STATE_PERFORM:
/* This should have a set of file descriptors for us to set. */ /* This should have a set of file descriptors for us to set. */
/* after the transfer is done, go DONE */ /* 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; struct Curl_one_easy *easy;
bool done; bool done;
CURLMcode result=CURLM_OK; CURLMcode result=CURLM_OK;
struct Curl_message *msg = NULL;
bool connected;
*running_handles = 0; /* bump this once for every living handle */ *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; easy=multi->easy.next;
while(easy) { while(easy) {
#ifdef MALLOCDEBUG
fprintf(stderr, "HANDLE %p: State: %x\n",
(char *)easy, easy->state);
#endif
switch(easy->state) { switch(easy->state) {
case CURLM_STATE_INIT: case CURLM_STATE_INIT:
/* init this transfer. */ /* init this transfer. */
easy->result=Curl_pretransfer(easy->easy_handle); easy->result=Curl_pretransfer(easy->easy_handle);
if(CURLE_OK == easy->result) { if(CURLE_OK == easy->result) {
/* after init, go CONNECT */ /* after init, go CONNECT */
easy->state = CURLM_STATE_CONNECT; easy->state = CURLM_STATE_CONNECT;
result = CURLM_CALL_MULTI_PERFORM; result = CURLM_CALL_MULTI_PERFORM;
easy->easy_handle->state.used_interface = Curl_if_multi;
} }
break; break;
case CURLM_STATE_CONNECT: case CURLM_STATE_CONNECT:
@ -261,7 +314,7 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
} }
else { else {
if (multi->hostcache == NULL) { 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; 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. */ /* Connect. We get a connection identifier filled in. */
easy->result = Curl_connect(easy->easy_handle, &easy->easy_conn); 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) { if(CURLE_OK == easy->result) {
easy->state = CURLM_STATE_DO; easy->state = CURLM_STATE_WAITCONNECT;
result = CURLM_CALL_MULTI_PERFORM; result = CURLM_CALL_MULTI_PERFORM;
} }
break; 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: case CURLM_STATE_DO:
/* Do the fetch or put request */ /* Do the fetch or put request */
easy->result = Curl_do(&easy->easy_conn); easy->result = Curl_do(&easy->easy_conn);
/* after do, go PERFORM */
if(CURLE_OK == easy->result) { 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; easy->state = CURLM_STATE_PERFORM;
result = CURLM_CALL_MULTI_PERFORM; result = CURLM_CALL_MULTI_PERFORM;
} }
} }
break; break;
case CURLM_STATE_PERFORM: case CURLM_STATE_PERFORM:
/* read/write data if it is ready to do so */ /* read/write data if it is ready to do so */
easy->result = Curl_readwrite(easy->easy_conn, &done); 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 */ /* after the transfer is done, go DONE */
if(TRUE == done) { else if(TRUE == done) {
/* call this even if the readwrite function returned error */ /* call this even if the readwrite function returned error */
easy->result = Curl_posttransfer(easy->easy_handle); Curl_posttransfer(easy->easy_handle);
easy->state = CURLM_STATE_DONE;
result = CURLM_CALL_MULTI_PERFORM; /* 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; break;
case CURLM_STATE_DONE: case CURLM_STATE_DONE:
/* post-transfer command */ /* post-transfer command */
easy->result = Curl_done(easy->easy_conn); easy->result = Curl_done(easy->easy_conn);
/* after we have DONE what we're supposed to do, go COMPLETED */
if(CURLE_OK == easy->result) /* after we have DONE what we're supposed to do, go COMPLETED, and
easy->state = CURLM_STATE_COMPLETED; it doesn't matter what the Curl_done() returned! */
easy->state = CURLM_STATE_COMPLETED;
break; break;
case CURLM_STATE_COMPLETED: case CURLM_STATE_COMPLETED:
/* this is a completed transfer, it is likely to still be connected */ /* 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; return CURLM_INTERNAL_ERROR;
} }
if((CURLM_STATE_COMPLETED != easy->state) && if(CURLM_STATE_COMPLETED != easy->state) {
(CURLE_OK != easy->result)) { if(CURLE_OK != easy->result)
/* /*
* If an error was returned, and we aren't in completed now, * If an error was returned, and we aren't in completed state now,
* then we go to completed and consider this transfer aborted. * then we go to completed and consider this transfer aborted. */
*/ easy->state = CURLM_STATE_COMPLETED;
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 */ easy = easy->next; /* operate on next handle */
} }
return result; return result;
} }
CURLMcode curl_multi_cleanup(CURLM *multi_handle) CURLMcode curl_multi_cleanup(CURLM *multi_handle)
{ {
struct Curl_multi *multi=(struct Curl_multi *)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)) { if(GOOD_MULTI_HANDLE(multi)) {
multi->type = 0; /* not good anymore */ multi->type = 0; /* not good anymore */
curl_hash_destroy(multi->hostcache); Curl_hash_destroy(multi->hostcache);
/* remove all easy handles */ /* 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); free(multi);
@ -350,7 +529,35 @@ CURLMcode curl_multi_cleanup(CURLM *multi_handle)
return CURLM_BAD_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: * local variables:

View File

@ -1,25 +1,25 @@
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
#include "setup.h" #include "setup.h"
@ -78,12 +78,15 @@ int Curl_parsenetrc(char *host,
FILE *file; FILE *file;
char netrcbuffer[256]; char netrcbuffer[256];
int retcode=1; int retcode=1;
int specific_login = (login[0] != 0);
char *home = NULL; char *home = NULL;
int state=NOTHING; int state=NOTHING;
char state_login=0; char state_login=0; /* Found a login keyword */
char state_password=0; 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" #define NETRC DOT_CHAR "netrc"
@ -116,6 +119,30 @@ int Curl_parsenetrc(char *host,
sprintf(netrcbuffer, "%s%s%s", home, DIR_CHAR, NETRC); 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"); file = fopen(netrcbuffer, "r");
if(file) { if(file) {
char *tok; char *tok;
@ -123,6 +150,10 @@ int Curl_parsenetrc(char *host,
while(fgets(netrcbuffer, sizeof(netrcbuffer), file)) { while(fgets(netrcbuffer, sizeof(netrcbuffer), file)) {
tok=strtok_r(netrcbuffer, " \t\n", &tok_buf); tok=strtok_r(netrcbuffer, " \t\n", &tok_buf);
while(tok) { while(tok) {
if (login[0] && password[0])
goto done;
switch(state) { switch(state) {
case NOTHING: case NOTHING:
if(strequal("machine", tok)) { if(strequal("machine", tok)) {
@ -149,17 +180,23 @@ int Curl_parsenetrc(char *host,
case HOSTVALID: case HOSTVALID:
/* we are now parsing sub-keywords concerning "our" host */ /* we are now parsing sub-keywords concerning "our" host */
if(state_login) { 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 #ifdef _NETRC_DEBUG
printf("LOGIN: %s\n", login); printf("LOGIN: %s\n", login);
#endif #endif
}
state_login=0; state_login=0;
} }
else if(state_password) { else if(state_password) {
strncpy(password, tok, PASSWORDSIZE-1); if (state_our_login || !specific_login) {
strncpy(password, tok, PASSWORDSIZE-1);
#ifdef _NETRC_DEBUG #ifdef _NETRC_DEBUG
printf("PASSWORD: %s\n", password); printf("PASSWORD: %s\n", password);
#endif #endif
}
state_password=0; state_password=0;
} }
else if(strequal("login", tok)) else if(strequal("login", tok))
@ -169,13 +206,16 @@ int Curl_parsenetrc(char *host,
else if(strequal("machine", tok)) { else if(strequal("machine", tok)) {
/* ok, there's machine here go => */ /* ok, there's machine here go => */
state = HOSTFOUND; state = HOSTFOUND;
state_our_login = 0;
} }
break; break;
} /* switch (state) */ } /* switch (state) */
tok = strtok_r(NULL, " \t\n", &tok_buf); tok = strtok_r(NULL, " \t\n", &tok_buf);
} /* while (tok) */ } /* while (tok) */
} /* while fgets() */ } /* while fgets() */
done:
fclose(file); fclose(file);
} }

View File

@ -1,28 +1,33 @@
#ifndef __NETRC_H #ifndef __NETRC_H
#define __NETRC_H #define __NETRC_H
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
int Curl_parsenetrc(char *host, int Curl_parsenetrc(char *host,
char *login, char *login,
char *password); 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 #endif

View File

@ -1,25 +1,25 @@
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
#include "setup.h" #include "setup.h"
@ -45,6 +45,10 @@
#include "progress.h" #include "progress.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
static void time2str(char *r, int t) static void time2str(char *r, int t)
{ {
int h = (t/3600); 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) void Curl_pgrsTime(struct SessionHandle *data, timerid timer)
{ {
switch(timer) { switch(timer) {
@ -134,6 +147,10 @@ void Curl_pgrsTime(struct SessionHandle *data, timerid timer)
case TIMER_POSTRANSFER: case TIMER_POSTRANSFER:
/* this is the normal end-of-transfer thing */ /* this is the normal end-of-transfer thing */
break; 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 /* If we have a total estimate, we can display that and the expected
time left */ time left */
if(total_estimate) { if(total_estimate) {
time2str(time_left, total_estimate-(int) data->progress.timespent); time2str(time_left, (int)(total_estimate - data->progress.timespent));
time2str(time_total, total_estimate); time2str(time_total, (int)total_estimate);
} }
else { else {
/* otherwise we blank those times */ /* otherwise we blank those times */
@ -336,7 +353,7 @@ int Curl_pgrsUpdate(struct connectdata *conn)
strcpy(time_total, "--:--:--"); strcpy(time_total, "--:--:--");
} }
/* The time spent so far is always known */ /* 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 */ /* Get the total amount of data expected to get transfered */
total_expected_transfer = total_expected_transfer =

View File

@ -1,27 +1,27 @@
#ifndef __PROGRESS_H #ifndef __PROGRESS_H
#define __PROGRESS_H #define __PROGRESS_H
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
#include "timeval.h" #include "timeval.h"
@ -34,6 +34,7 @@ typedef enum {
TIMER_STARTTRANSFER, TIMER_STARTTRANSFER,
TIMER_POSTRANSFER, TIMER_POSTRANSFER,
TIMER_STARTSINGLE, TIMER_STARTSINGLE,
TIMER_REDIRECT,
TIMER_LAST /* must be last */ TIMER_LAST /* must be last */
} timerid; } timerid;
@ -44,6 +45,7 @@ void Curl_pgrsSetUploadSize(struct SessionHandle *data, double size);
void Curl_pgrsSetDownloadCounter(struct SessionHandle *data, double size); void Curl_pgrsSetDownloadCounter(struct SessionHandle *data, double size);
void Curl_pgrsSetUploadCounter(struct SessionHandle *data, double size); void Curl_pgrsSetUploadCounter(struct SessionHandle *data, double size);
int Curl_pgrsUpdate(struct connectdata *); int Curl_pgrsUpdate(struct connectdata *);
void Curl_pgrsResetTimes(struct SessionHandle *data);
void Curl_pgrsTime(struct SessionHandle *data, timerid timer); void Curl_pgrsTime(struct SessionHandle *data, timerid timer);

View File

@ -40,6 +40,7 @@
#include "setup.h" #include "setup.h"
#ifndef CURL_DISABLE_FTP
#ifdef KRB4 #ifdef KRB4
#define _MPRINTF_REPLACE /* we want curl-functions instead of native ones */ #define _MPRINTF_REPLACE /* we want curl-functions instead of native ones */
@ -552,6 +553,7 @@ Curl_sec_end(struct connectdata *conn)
} }
#endif /* KRB4 */ #endif /* KRB4 */
#endif /* CURL_DISABLE_FTP */
/* /*
* local variables: * local variables:

View File

@ -1,27 +1,27 @@
#ifndef __SECURITY_H #ifndef __SECURITY_H
#define __SECURITY_H #define __SECURITY_H
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
/* this is a re-write */ /* this is a re-write */

View File

@ -1,25 +1,25 @@
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2002, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
#include "setup.h" #include "setup.h"
@ -62,18 +62,18 @@
/* returns last node in linked list */ /* returns last node in linked list */
static struct curl_slist *slist_get_last(struct curl_slist *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 caller passed us a NULL, return now */
if (!list) if (!list)
return NULL; return NULL;
/* loop through to find the last item */ /* loop through to find the last item */
item = list; item = list;
while (item->next) { while (item->next) {
item = item->next; item = item->next;
} }
return item; return item;
} }
/* append a struct to the linked list. It always retunrs the address of the /* 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, struct curl_slist *curl_slist_append(struct curl_slist *list,
const char *data) const char *data)
{ {
struct curl_slist *last; struct curl_slist *last;
struct curl_slist *new_item; struct curl_slist *new_item;
new_item = (struct curl_slist *) malloc(sizeof(struct curl_slist)); new_item = (struct curl_slist *) malloc(sizeof(struct curl_slist));
if (new_item) { if (new_item) {
new_item->next = NULL; new_item->next = NULL;
new_item->data = strdup(data); new_item->data = strdup(data);
} }
else { if (new_item == NULL || new_item->data == NULL) {
fprintf(stderr, "Cannot allocate memory for QUOTE list.\n"); fprintf(stderr, "Cannot allocate memory for QUOTE list.\n");
return NULL; return NULL;
} }
if (list) { if (list) {
last = slist_get_last(list); last = slist_get_last(list);
last->next = new_item; last->next = new_item;
return list; return list;
} }
/* if this is the first item, then new_item *is* the list */ /* if this is the first item, then new_item *is* the list */
return new_item; return new_item;
} }
/* be nice and clean up resources */ /* be nice and clean up resources */
void curl_slist_free_all(struct curl_slist *list) void curl_slist_free_all(struct curl_slist *list)
{ {
struct curl_slist *next; struct curl_slist *next;
struct curl_slist *item; struct curl_slist *item;
if (!list) if (!list)
return; return;
item = list; item = list;
do { do {
next = item->next; next = item->next;
if (item->data) { if (item->data) {
free(item->data); free(item->data);
} }
free(item); free(item);
item = next; item = next;
} while (next); } while (next);
} }
/* Curl_infof() is for info message along the way */ /* Curl_infof() is for info message along the way */
void Curl_infof(struct SessionHandle *data, const char *fmt, ...) void Curl_infof(struct SessionHandle *data, const char *fmt, ...)
{ {
va_list ap; va_list ap;
if(data->set.verbose) { if(data->set.verbose) {
char print_buffer[1024 + 1];
va_start(ap, fmt); va_start(ap, fmt);
fputs("* ", data->set.err); vsnprintf(print_buffer, 1024, fmt, ap);
vfprintf(data->set.err, fmt, ap);
va_end(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) { if(data->set.errorbuffer && !data->state.errorbuf) {
vsnprintf(data->set.errorbuffer, CURL_ERROR_SIZE, fmt, ap); vsnprintf(data->set.errorbuffer, CURL_ERROR_SIZE, fmt, ap);
data->state.errorbuf = TRUE; /* wrote error string */ 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); va_end(ap);
} }
@ -163,23 +167,45 @@ CURLcode Curl_sendf(int sockfd, struct connectdata *conn,
{ {
struct SessionHandle *data = conn->data; struct SessionHandle *data = conn->data;
ssize_t bytes_written; ssize_t bytes_written;
CURLcode result; ssize_t write_len;
CURLcode res;
char *s; char *s;
char *sptr;
va_list ap; va_list ap;
va_start(ap, fmt); va_start(ap, fmt);
s = vaprintf(fmt, ap); /* returns an allocated string */ s = vaprintf(fmt, ap); /* returns an allocated string */
va_end(ap); va_end(ap);
if(!s) if(!s)
return 0; /* failure */ return CURLE_OUT_OF_MEMORY; /* failure */
if(data->set.verbose)
fprintf(data->set.err, "> %s", s);
/* Write the buffer to the socket */ bytes_written=0;
result = Curl_write(conn, sockfd, s, strlen(s), &bytes_written); 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 */ 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 */ /* a true error */
failf(conn->data, "SSL_write() return error %d\n", err); failf(conn->data, "SSL_write() return error %d\n", err);
return CURLE_WRITE_ERROR; return CURLE_SEND_ERROR;
} }
bytes_written = rc; bytes_written = rc;
} }
@ -244,7 +270,7 @@ CURLcode Curl_write(struct connectdata *conn, int sockfd,
#endif #endif
*written = bytes_written; *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) /* client_write() sends data to the write callback(s)
@ -325,6 +351,9 @@ int Curl_read(struct connectdata *conn,
case SSL_ERROR_WANT_WRITE: case SSL_ERROR_WANT_WRITE:
/* if there's data pending, then we re-invoke SSL_read() */ /* if there's data pending, then we re-invoke SSL_read() */
break; break;
default:
failf(conn->data, "SSL read error: %d", err);
return CURLE_RECV_ERROR;
} }
} while(loop); } while(loop);
if(loop && SSL_pending(conn->ssl.handle)) if(loop && SSL_pending(conn->ssl.handle))
@ -355,6 +384,29 @@ int Curl_read(struct connectdata *conn,
return CURLE_OK; 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: * local variables:

View File

@ -1,27 +1,27 @@
#ifndef __SENDF_H #ifndef __SENDF_H
#define __SENDF_H #define __SENDF_H
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
CURLcode Curl_sendf(int fd, struct connectdata *, const char *fmt, ...); CURLcode Curl_sendf(int fd, struct connectdata *, const char *fmt, ...);
void Curl_infof(struct SessionHandle *, 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, void *mem, size_t len,
ssize_t *written); 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 #endif

View File

@ -1,29 +1,39 @@
#ifndef __SETUP_H #ifndef __SETUP_H
#define __SETUP_H #define __SETUP_H
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $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) #if !defined(WIN32) && defined(_WIN32)
/* This _might_ be a good Borland fix. Please report whether this works or /* This _might_ be a good Borland fix. Please report whether this works or

View File

@ -1,25 +1,25 @@
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
#include "setup.h" #include "setup.h"

View File

@ -1,27 +1,27 @@
#ifndef __SPEEDCHECK_H #ifndef __SPEEDCHECK_H
#define __SPEEDCHECK_H #define __SPEEDCHECK_H
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
#include "setup.h" #include "setup.h"

View File

@ -1,25 +1,25 @@
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
/* /*
* The original SSL code for curl was written by * The original SSL code for curl was written by
@ -55,6 +55,15 @@
#undef HAVE_USERDATA_IN_PWD_CALLBACK #undef HAVE_USERDATA_IN_PWD_CALLBACK
#endif #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 #ifndef HAVE_USERDATA_IN_PWD_CALLBACK
static char global_passwd[64]; static char global_passwd[64];
#endif #endif
@ -223,30 +232,22 @@ int cert_stuff(struct connectdata *conn,
SSL_CTX_set_default_passwd_cb(conn->ssl.ctx, passwd_callback); 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); file_type = do_file_type(cert_type);
switch(file_type) { switch(file_type) {
case SSL_FILETYPE_PEM: 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: 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, if (SSL_CTX_use_certificate_file(conn->ssl.ctx,
cert_file, cert_file,
file_type) != 1) { file_type) != 1) {
@ -283,11 +284,17 @@ int cert_stuff(struct connectdata *conn,
{ /* XXXX still needs some work */ { /* XXXX still needs some work */
EVP_PKEY *priv_key = NULL; EVP_PKEY *priv_key = NULL;
if (conn && conn->data && conn->data->engine) { 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]) { if (!key_file || !key_file[0]) {
failf(data, "no key set to load from crypto engine\n"); failf(data, "no key set to load from crypto engine\n");
return 0; return 0;
} }
priv_key = ENGINE_load_private_key(conn->data->engine,key_file, priv_key = ENGINE_load_private_key(conn->data->engine,key_file,
#ifdef HAVE_ENGINE_LOAD_FOUR_ARGS
ui_method,
#endif
data->set.key_passwd); data->set.key_passwd);
if (!priv_key) { if (!priv_key) {
failf(data, "failed to load private key from crypto engine\n"); failf(data, "failed to load private key from crypto engine\n");
@ -315,8 +322,6 @@ int cert_stuff(struct connectdata *conn,
return 0; return 0;
} }
#endif
ssl=SSL_new(conn->ssl.ctx); ssl=SSL_new(conn->ssl.ctx);
x509=SSL_get_certificate(ssl); x509=SSL_get_certificate(ssl);
@ -717,7 +722,7 @@ Curl_SSLConnect(struct connectdata *conn)
data->set.key, data->set.key,
data->set.key_type)) { data->set.key_type)) {
/* failf() is already done in cert_stuff() */ /* 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, if (!SSL_CTX_set_cipher_list(conn->ssl.ctx,
data->set.ssl.cipher_list)) { data->set.ssl.cipher_list)) {
failf(data, "failed setting 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_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT|
SSL_VERIFY_CLIENT_ONCE, SSL_VERIFY_CLIENT_ONCE,
cert_verify_callback); 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.CAfile,
data->set.ssl.CApath)) { data->set.ssl.CApath)) {
failf(data,"error setting cerficate verify locations"); failf(data,"error setting cerficate verify locations");
return CURLE_SSL_CONNECT_ERROR; return CURLE_SSL_CACERT;
} }
} }
else else

View File

@ -1,27 +1,27 @@
#ifndef __SSLUSE_H #ifndef __SSLUSE_H
#define __SSLUSE_H #define __SSLUSE_H
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
#include "urldata.h" #include "urldata.h"
CURLcode Curl_SSLConnect(struct connectdata *conn); CURLcode Curl_SSLConnect(struct connectdata *conn);

View File

@ -1,25 +1,25 @@
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
#include "setup.h" #include "setup.h"

View File

@ -1,27 +1,27 @@
#ifndef __STREQUAL_H #ifndef __STREQUAL_H
#define __STREQUAL_H #define __STREQUAL_H
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
/* /*
* These two actually are public functions. * 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 strequal(a,b) curl_strequal(a,b)
#define strnequal(a,b,c) curl_strnequal(a,b,c) #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 #ifndef HAVE_STRLCAT
#define strlcat(x,y,z) Curl_strlcat(x,y,z) #define strlcat(x,y,z) Curl_strlcat(x,y,z)
size_t Curl_strlcat(char *dst, const char *src, size_t siz); size_t Curl_strlcat(char *dst, const char *src, size_t siz);

View File

@ -1,25 +1,25 @@
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
#include "setup.h" #include "setup.h"

View File

@ -1,25 +1,25 @@
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
#ifndef _CURL_STRTOK_R_H #ifndef _CURL_STRTOK_R_H
#define _CURL_STRTOK_R_H #define _CURL_STRTOK_R_H

View File

@ -1,28 +1,29 @@
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
#include "setup.h" #include "setup.h"
#ifndef CURL_DISABLE_TELNET
/* -- WIN32 approved -- */ /* -- WIN32 approved -- */
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -1049,6 +1050,7 @@ CURLcode Curl_telnet(struct connectdata *conn)
char *buf = data->state.buffer; char *buf = data->state.buffer;
ssize_t nread; ssize_t nread;
struct TELNET *tn; struct TELNET *tn;
struct timeval now; /* current time */
code = init_telnet(conn); code = init_telnet(conn);
if(code) if(code)
@ -1148,9 +1150,13 @@ CURLcode Curl_telnet(struct connectdata *conn)
keepfd = readfd; keepfd = readfd;
while (keepon) { 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 */ case -1: /* error, stop reading */
keepon = FALSE; keepon = FALSE;
continue; 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 #endif
/* mark this as "no further transfer wanted" */ /* 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 * vim600: fdm=marker
* vim: et sw=2 ts=2 sts=2 tw=78 * vim: et sw=2 ts=2 sts=2 tw=78
*/ */
#endif

View File

@ -1,29 +1,30 @@
#ifndef __TELNET_H #ifndef __TELNET_H
#define __TELNET_H #define __TELNET_H
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
#ifndef CURL_DISABLE_TELNET
CURLcode Curl_telnet(struct connectdata *conn); CURLcode Curl_telnet(struct connectdata *conn);
CURLcode Curl_telnet_done(struct connectdata *conn); CURLcode Curl_telnet_done(struct connectdata *conn);
#endif
#endif #endif

View File

@ -1,25 +1,25 @@
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
#ifdef WIN32 #ifdef WIN32
#include <windows.h> #include <windows.h>
@ -32,22 +32,40 @@
int int
gettimeofday (struct timeval *tp, void *nothing) gettimeofday (struct timeval *tp, void *nothing)
{ {
SYSTEMTIME st; #ifdef WITHOUT_MM_LIB
time_t tt; SYSTEMTIME st;
struct tm tmtm; time_t tt;
/* mktime converts local to UTC */ struct tm tmtm;
GetLocalTime (&st); /* mktime converts local to UTC */
tmtm.tm_sec = st.wSecond; GetLocalTime (&st);
tmtm.tm_min = st.wMinute; tmtm.tm_sec = st.wSecond;
tmtm.tm_hour = st.wHour; tmtm.tm_min = st.wMinute;
tmtm.tm_mday = st.wDay; tmtm.tm_hour = st.wHour;
tmtm.tm_mon = st.wMonth - 1; tmtm.tm_mday = st.wDay;
tmtm.tm_year = st.wYear - 1900; tmtm.tm_mon = st.wMonth - 1;
tmtm.tm_isdst = -1; tmtm.tm_year = st.wYear - 1900;
tt = mktime (&tmtm); tmtm.tm_isdst = -1;
tp->tv_sec = tt; tt = mktime (&tmtm);
tp->tv_usec = st.wMilliseconds * 1000; tp->tv_sec = tt;
return 1; 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 #define HAVE_GETTIMEOFDAY
#endif #endif

View File

@ -1,27 +1,27 @@
#ifndef __TIMEVAL_H #ifndef __TIMEVAL_H
#define __TIMEVAL_H #define __TIMEVAL_H
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
#include "setup.h" #include "setup.h"

File diff suppressed because it is too large Load Diff

View File

@ -1,32 +1,31 @@
#ifndef __TRANSFER_H #ifndef __TRANSFER_H
#define __TRANSFER_H #define __TRANSFER_H
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
CURLcode Curl_perform(struct SessionHandle *data); CURLcode Curl_perform(struct SessionHandle *data);
CURLcode Curl_pretransfer(struct SessionHandle *data); CURLcode Curl_pretransfer(struct SessionHandle *data);
CURLcode Curl_posttransfer(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); CURLcode Curl_readwrite(struct connectdata *conn, bool *done);
void Curl_single_fdset(struct connectdata *conn, void Curl_single_fdset(struct connectdata *conn,
fd_set *read_fd_set, fd_set *read_fd_set,

File diff suppressed because it is too large Load Diff

View File

@ -1,27 +1,27 @@
#ifndef __URL_H #ifndef __URL_H
#define __URL_H #define __URL_H
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
/* /*
* Prototypes for library-wide functions provided by url.c * 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_close(struct SessionHandle *data); /* opposite of curl_open() */
CURLcode Curl_connect(struct SessionHandle *, struct connectdata **); CURLcode Curl_connect(struct SessionHandle *, struct connectdata **);
CURLcode Curl_do(struct connectdata **); CURLcode Curl_do(struct connectdata **);
CURLcode Curl_do_more(struct connectdata *);
CURLcode Curl_done(struct connectdata *); CURLcode Curl_done(struct connectdata *);
CURLcode Curl_disconnect(struct connectdata *); CURLcode Curl_disconnect(struct connectdata *);
CURLcode Curl_protocol_connect(struct connectdata *conn,
struct Curl_dns_entry *dns);
#endif #endif

View File

@ -1,33 +1,31 @@
#ifndef __URLDATA_H #ifndef __URLDATA_H
#define __URLDATA_H #define __URLDATA_H
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
/* This file is for lib internal stuff */ /* This file is for lib internal stuff */
#include "setup.h" #include "setup.h"
#include "hostip.h"
#include "hash.h"
#define PORT_FTP 21 #define PORT_FTP 21
#define PORT_TELNET 23 #define PORT_TELNET 23
@ -81,9 +79,15 @@
#include <curl/curl.h> #include <curl/curl.h>
#include "http_chunks.h" /* for the structs and enum stuff */ #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 */ /* 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 /* Initial size of the buffer to store headers in, it'll be enlarged in case
of need. */ of need. */
@ -136,14 +140,15 @@ struct ssl_config_data {
long version; /* what version the client wants to use */ long version; /* what version the client wants to use */
long certverifyresult; /* result from the certificate verification */ long certverifyresult; /* result from the certificate verification */
long verifypeer; /* set TRUE if this is desired */ 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 *CApath; /* DOES NOT WORK ON WINDOWS */
char *CAfile; /* cerficate to verify peer against */ char *CAfile; /* cerficate to verify peer against */
char *random_file; /* path to file containing "random" data */ char *random_file; /* path to file containing "random" data */
char *egdsocket; /* path to file containing the EGD daemon socket */ char *egdsocket; /* path to file containing the EGD daemon socket */
char *cipher_list; /* list of ciphers to use */ 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 *entrypath; /* the PWD reply when we logged on */
char *cache; /* data cache between getresponse()-calls */ 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 httpproxy; /* if set, this transfer is done through a http proxy */
bool user_passwd; /* do we use user+password for this connection? */ bool user_passwd; /* do we use user+password for this connection? */
bool proxy_user_passwd; /* user+password for the proxy? */ 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 use_range;
bool rangestringalloc; /* the range string is malloc()'ed */ bool rangestringalloc; /* the range string is malloc()'ed */
bool resume_done; /* nothing was transfered, resumed transfer already bool do_more; /* this is set TRUE if the ->curl_do_more() function is
complete */ 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 start; /* transfer started at this time */
struct timeval now; /* current time */ struct timeval now; /* current time */
bool header; /* incoming data has HTTP header */ 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 int headerline; /* counts header lines to better track the
first one */ first one */
char *hbufp; /* points at *end* of header line */ 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 bool write_after_100_header; /* should we enable the write after
we received a 100-continue/timeout we received a 100-continue/timeout
or directly */ 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: */ /* for the low speed checks: */
time_t timeofdoc; time_t timeofdoc;
long bodywrites; long bodywrites;
int writetype; int writetype;
/* the highest fd we use + 1 */
struct SessionHandle *data;
struct connectdata *conn;
char *buf; char *buf;
char *uploadbuf; char *uploadbuf;
int maxfd; int maxfd;
/* pointers to the actual descriptors we check */
fd_set *readfdp;
fd_set *writefdp;
/* the file descriptors to play with */ /* the file descriptors to play with */
fd_set readfd; fd_set readfd;
fd_set writefd; fd_set writefd;
@ -256,6 +293,8 @@ struct Curl_transfer_keeper {
fd_set wkeepfd; fd_set wkeepfd;
int keepon; 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_FTPS (1<<9)
#define PROT_SSL (1<<10) /* protocol requires SSL */ #define PROT_SSL (1<<10) /* protocol requires SSL */
Curl_addrinfo *hostaddr; /* IP-protocol independent host info pointer list */ /* the particular host we use, in two different ways */
char *hostent_buf; /* pointer to allocated memory for name info */ struct Curl_dns_entry *connect_addr;
#ifdef ENABLE_IPV6 #ifdef ENABLE_IPV6
struct addrinfo *serv_addr; /* the particular host we use */ struct addrinfo *serv_addr;
#else #else
struct sockaddr_in serv_addr; struct sockaddr_in serv_addr;
#endif #endif
@ -324,6 +363,12 @@ struct connectdata {
CURLcode (*curl_do)(struct connectdata *connect); CURLcode (*curl_do)(struct connectdata *connect);
CURLcode (*curl_done)(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 /* 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. * after the connect() and everything is done, as a step in the connection.
*/ */
@ -344,7 +389,6 @@ struct connectdata {
/* READ stuff */ /* READ stuff */
int sockfd; /* socket to read from or -1 */ int sockfd; /* socket to read from or -1 */
int size; /* -1 if unknown at this point */ 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 */ long *bytecountp; /* return number of bytes read or NULL */
/* WRITE stuff */ /* WRITE stuff */
@ -357,6 +401,7 @@ struct connectdata {
struct dynamically_allocated_data { struct dynamically_allocated_data {
char *proxyuserpwd; /* free later if not NULL! */ char *proxyuserpwd; /* free later if not NULL! */
char *uagent; /* 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 *userpwd; /* free later if not NULL! */
char *rangeline; /* free later if not NULL! */ char *rangeline; /* free later if not NULL! */
char *ref; /* 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, 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 and the 'upload_present' contains the number of bytes available at this
position */ position */
char *upload_fromhere; char *upload_fromhere;
}; };
/* The end of connectdata. 08/27/02 jhrg */
/* /*
* Struct to keep statistical and informational data. * Struct to keep statistical and informational data.
*/ */
@ -451,6 +498,7 @@ struct Progress {
double t_connect; double t_connect;
double t_pretransfer; double t_pretransfer;
double t_starttransfer; double t_starttransfer;
double t_redirect;
struct timeval start; struct timeval start;
struct timeval t_startsingle; struct timeval t_startsingle;
@ -483,6 +531,12 @@ typedef enum {
#define MAX_CURL_PASSWORD_LENGTH 256 #define MAX_CURL_PASSWORD_LENGTH 256
struct UrlState { 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 */ /* buffers to store authentication data in, as parsed from input options */
char user[MAX_CURL_USER_LENGTH]; char user[MAX_CURL_USER_LENGTH];
char passwd[MAX_CURL_PASSWORD_LENGTH]; char passwd[MAX_CURL_PASSWORD_LENGTH];
@ -542,6 +596,8 @@ struct DynamicStatic {
bool proxy_alloc; /* http proxy string is malloc()'ed */ bool proxy_alloc; /* http proxy string is malloc()'ed */
char *referer; /* referer string */ char *referer; /* referer string */
bool referer_alloc; /* referer sting is malloc()ed */ 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 { 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 *errorbuffer; /* store failure messages in here */
char *proxyuserpwd; /* Proxy <user:password>, if used */ char *proxyuserpwd; /* Proxy <user:password>, if used */
long proxyport; /* If non-zero, use this port number by default. If the 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 bool free_referer; /* set TRUE if 'referer' points to a string we
allocated */ allocated */
char *useragent; /* User-Agent string */ char *useragent; /* User-Agent string */
char *encoding; /* Accept-Encoding string 08/28/02 jhrg */
char *postfields; /* if POST, set the fields' values here */ char *postfields; /* if POST, set the fields' values here */
size_t postfieldsize; /* if POST, this might have a size to use instead of size_t postfieldsize; /* if POST, this might have a size to use instead of
strlen(), and then the data *may* be binary (contain 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_write_callback fwrite_header; /* function that stores headers */
curl_read_callback fread; /* function that reads the input */ curl_read_callback fread; /* function that reads the input */
curl_progress_callback fprogress; /* function for progress information */ 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 */ void *progress_client; /* pointer to pass to the progress callback */
curl_passwd_callback fpasswd; /* call for password */ curl_passwd_callback fpasswd; /* call for password */
void *passwd_client; /* pass to the passwd callback */ void *passwd_client; /* pass to the passwd callback */
@ -603,6 +662,7 @@ struct UserDefined {
char *key_passwd; /* plain text private key password */ char *key_passwd; /* plain text private key password */
char *crypto_engine; /* name of the crypto engine to use */ char *crypto_engine; /* name of the crypto engine to use */
char *cookiejar; /* dump all cookies to this file */ char *cookiejar; /* dump all cookies to this file */
bool cookiesession; /* new cookie session? */
bool crlf; /* convert crlf on ftp upload(?) */ bool crlf; /* convert crlf on ftp upload(?) */
struct curl_slist *quote; /* after connection is established */ struct curl_slist *quote; /* after connection is established */
struct curl_slist *postquote; /* after the transfer */ struct curl_slist *postquote; /* after the transfer */
@ -622,7 +682,10 @@ struct UserDefined {
char *krb4_level; /* what security level */ char *krb4_level; /* what security level */
struct ssl_config_data ssl; /* user defined SSL stuff */ 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 */ 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 /* Here follows boolean settings that define how to behave during
this session. They are STATIC, set by libcurl users or at least initially this session. They are STATIC, set by libcurl users or at least initially
@ -645,13 +708,15 @@ struct UserDefined {
bool no_body; bool no_body;
bool set_port; bool set_port;
bool upload; bool upload;
bool use_netrc; enum CURL_NETRC_OPTION
use_netrc; /* defined in include/curl.h */
bool verbose; bool verbose;
bool krb4; /* kerberos4 connection requested */ bool krb4; /* kerberos4 connection requested */
bool reuse_forbid; /* forbidden to be reused, close after use */ bool reuse_forbid; /* forbidden to be reused, close after use */
bool reuse_fresh; /* do not re-use an existing connection */ bool reuse_fresh; /* do not re-use an existing connection */
bool expect100header; /* TRUE if we added Expect: 100-continue */ bool expect100header; /* TRUE if we added Expect: 100-continue */
bool ftp_use_epsv; /* if EPSV is to be attempted or not */ 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; bool global_dns_cache;
}; };
@ -668,7 +733,8 @@ struct UserDefined {
* 'struct urlstate' instead. */ * 'struct urlstate' instead. */
struct SessionHandle { 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 UserDefined set; /* values set by the libcurl user */
struct DynamicStatic change; /* possibly modified userdefined data */ struct DynamicStatic change; /* possibly modified userdefined data */

View File

@ -1,25 +1,25 @@
/***************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2002, Daniel Stenberg, <daniel@haxx.se>, et al. * 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.
* *
* 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 * 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 * 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 * furnished to do so, under the terms of the COPYING file.
* licenses. You may pick one of these licenses.
* *
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. * KIND, either express or implied.
* *
* $Id$ * $Id$
*****************************************************************************/ ***************************************************************************/
#include "setup.h" #include "setup.h"
@ -29,14 +29,9 @@
#include <curl/curl.h> #include <curl/curl.h>
#include "urldata.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 #ifdef USE_SSLEAY
static void getssl_version(char *ptr, long *num)
{
#if (SSLEAY_VERSION_NUMBER >= 0x905000) #if (SSLEAY_VERSION_NUMBER >= 0x905000)
{ {
@ -44,6 +39,7 @@ char *curl_version(void)
unsigned long ssleay_value; unsigned long ssleay_value;
sub[1]='\0'; sub[1]='\0';
ssleay_value=SSLeay(); ssleay_value=SSLeay();
*num = ssleay_value;
if(ssleay_value < 0x906000) { if(ssleay_value < 0x906000) {
ssleay_value=SSLEAY_VERSION_NUMBER; ssleay_value=SSLEAY_VERSION_NUMBER;
sub[0]='\0'; sub[0]='\0';
@ -56,7 +52,7 @@ char *curl_version(void)
sub[0]='\0'; sub[0]='\0';
} }
sprintf(ptr, " (OpenSSL %lx.%lx.%lx%s)", sprintf(ptr, " OpenSSL/%lx.%lx.%lx%s",
(ssleay_value>>28)&0xf, (ssleay_value>>28)&0xf,
(ssleay_value>>20)&0xff, (ssleay_value>>20)&0xff,
(ssleay_value>>12)&0xff, (ssleay_value>>12)&0xff,
@ -64,8 +60,9 @@ char *curl_version(void)
} }
#else #else
*num = SSLEAY_VERSION_NUMBER;
#if (SSLEAY_VERSION_NUMBER >= 0x900000) #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>>28)&0xff,
(SSLEAY_VERSION_NUMBER>>20)&0xff, (SSLEAY_VERSION_NUMBER>>20)&0xff,
(SSLEAY_VERSION_NUMBER>>12)&0xf); (SSLEAY_VERSION_NUMBER>>12)&0xf);
@ -79,39 +76,130 @@ char *curl_version(void)
else else
sub[0]='\0'; 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>>12)&0xff,
(SSLEAY_VERSION_NUMBER>>8)&0xf, (SSLEAY_VERSION_NUMBER>>8)&0xf,
(SSLEAY_VERSION_NUMBER>>4)&0xf, sub); (SSLEAY_VERSION_NUMBER>>4)&0xf, sub);
} }
#endif #endif
#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 #endif
#if defined(KRB4) || defined(ENABLE_IPV6)
strcat(ptr, " (");
ptr+=2;
#ifdef KRB4 #ifdef KRB4
sprintf(ptr, "krb4 "); sprintf(ptr, " krb4");
ptr += strlen(ptr); ptr += strlen(ptr);
#endif #endif
#ifdef ENABLE_IPV6 #ifdef ENABLE_IPV6
sprintf(ptr, "ipv6 "); sprintf(ptr, " ipv6");
ptr += strlen(ptr); ptr += strlen(ptr);
#endif #endif
sprintf(ptr, "enabled)"); #ifdef HAVE_LIBZ
ptr += strlen(ptr); sprintf(ptr, " zlib/%s", zlibVersion());
#endif
#ifdef USE_ZLIB
sprintf(ptr, " (zlib %s)", zlibVersion());
ptr += strlen(ptr); ptr += strlen(ptr);
#endif #endif
return version; 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: * local variables:
* eval: (load-file "../curl-mode.el") * eval: (load-file "../curl-mode.el")