diff options
author | Alexander Neundorf <neundorf@kde.org> | 2007-08-09 18:26:10 (GMT) |
---|---|---|
committer | Alexander Neundorf <neundorf@kde.org> | 2007-08-09 18:26:10 (GMT) |
commit | 9bd32386c266c906c1a4c02964dfa68292c4ab12 (patch) | |
tree | 25084262740f6fad05068d4b8d0367180dfeead4 /Source | |
parent | 4b92b89664086e3b5e38e53b325aa88e0b42a6d4 (diff) | |
download | CMake-9bd32386c266c906c1a4c02964dfa68292c4ab12.zip CMake-9bd32386c266c906c1a4c02964dfa68292c4ab12.tar.gz CMake-9bd32386c266c906c1a4c02964dfa68292c4ab12.tar.bz2 |
COMP: this copy of curl is unused, the one in Utilities/cmcurl/ is used
Alex
Diffstat (limited to 'Source')
138 files changed, 2 insertions, 42831 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index fe54ef8..1ca897c 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -257,7 +257,7 @@ INCLUDE_DIRECTORIES( # # Sources for CTestLib # -SET(CMTEST_SRCS cmCTest.cxx +SET(CTEST_SRCS cmCTest.cxx CTest/cmCTestBuildAndTestHandler.cxx CTest/cmCTestBuildCommand.cxx CTest/cmCTestBuildHandler.cxx @@ -284,7 +284,7 @@ SET(CMTEST_SRCS cmCTest.cxx ) # Build CTestLib -ADD_LIBRARY(CTestLib ${CMTEST_SRCS}) +ADD_LIBRARY(CTestLib ${CTEST_SRCS}) TARGET_LINK_LIBRARIES(CTestLib CMakeLib ${CMAKE_CURL_LIBRARIES} ${CMAKE_XMLRPC_LIBRARIES}) # diff --git a/Source/CTest/CMakeLists.txt b/Source/CTest/CMakeLists.txt deleted file mode 100644 index 278263e..0000000 --- a/Source/CTest/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -# Ignore this CMake lists diff --git a/Source/CTest/Curl/.NoDartCoverage b/Source/CTest/Curl/.NoDartCoverage deleted file mode 100644 index 3c99729..0000000 --- a/Source/CTest/Curl/.NoDartCoverage +++ /dev/null @@ -1 +0,0 @@ -# do not do coverage in this directory diff --git a/Source/CTest/Curl/CMake/CheckTypeSize.c.in b/Source/CTest/Curl/CMake/CheckTypeSize.c.in deleted file mode 100644 index 822d9c5..0000000 --- a/Source/CTest/Curl/CMake/CheckTypeSize.c.in +++ /dev/null @@ -1,34 +0,0 @@ -#ifdef CHECK_TYPE_SIZE_TYPE - -@CHECK_TYPE_SIZE_PREINCLUDE@ - -#ifdef HAVE_SYS_TYPES_H -# include <sys/types.h> -#endif /* HAVE_SYS_TYPES_H */ - -#ifdef HAVE_STDINT_H -# include <stdint.h> -#endif /* HAVE_STDINT_H */ - -#ifdef HAVE_STDDEF_H -# include <stddef.h> -#endif /* HAVE_STDDEF_H */ - -@CHECK_TYPE_SIZE_PREMAIN@ - -#ifdef __CLASSIC_C__ -int main(){ - int ac; - char*av[]; -#else -int main(int ac, char*av[]){ -#endif - if(ac > 1000){return *av[0];} - return sizeof(CHECK_TYPE_SIZE_TYPE); -} - -#else /* CHECK_TYPE_SIZE_TYPE */ - -# error "CHECK_TYPE_SIZE_TYPE has to specify the type" - -#endif /* CHECK_TYPE_SIZE_TYPE */ diff --git a/Source/CTest/Curl/CMake/CheckTypeSize.cmake b/Source/CTest/Curl/CMake/CheckTypeSize.cmake deleted file mode 100644 index 0f7ad52..0000000 --- a/Source/CTest/Curl/CMake/CheckTypeSize.cmake +++ /dev/null @@ -1,53 +0,0 @@ -# -# Check if the type exists and determine size of type. if the type -# exists, the size will be stored to the variable. -# -# CHECK_TYPE_SIZE - macro which checks the size of type -# VARIABLE - variable to store size if the type exists. -# HAVE_${VARIABLE} - does the variable exists or not -# - -MACRO(CHECK_TYPE_SIZE TYPE VARIABLE) - SET(CMAKE_ALLOW_UNKNOWN_VARIABLE_READ_ACCESS 1) - IF(NOT DEFINED ${VARIABLE}) - IF("HAVE_${VARIABLE}" MATCHES "^HAVE_${VARIABLE}$") - SET(MACRO_CHECK_TYPE_SIZE_FLAGS - "-DCHECK_TYPE_SIZE_TYPE=\"${TYPE}\" ${CMAKE_REQUIRED_FLAGS}") - FOREACH(def HAVE_SYS_TYPES_H HAVE_STDINT_H HAVE_STDDEF_H) - IF("${def}") - SET(MACRO_CHECK_TYPE_SIZE_FLAGS - "${MACRO_CHECK_TYPE_SIZE_FLAGS} -D${def}") - ENDIF("${def}") - ENDFOREACH(def) - SET(CHECK_TYPE_SIZE_PREMAIN) - FOREACH(def ${CMAKE_EXTRA_INCLUDE_FILES}) - SET(CHECK_TYPE_SIZE_PREMAIN "${CHECK_TYPE_SIZE_PREMAIN}#include \"${def}\"\n") - ENDFOREACH(def) - CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/CMake/CheckTypeSize.c.in" - "${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/CheckTypeSize.c" @ONLY) - FILE(READ "${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/CheckTypeSize.c" - CHECK_TYPE_SIZE_FILE_CONTENT) - MESSAGE(STATUS "Check size of ${TYPE}") - IF(CMAKE_REQUIRED_LIBRARIES) - SET(CHECK_TYPE_SIZE_ADD_LIBRARIES - "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}") - ENDIF(CMAKE_REQUIRED_LIBRARIES) - TRY_RUN(${VARIABLE} HAVE_${VARIABLE} - ${CMAKE_BINARY_DIR} - "${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/CheckTypeSize.c" - CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_TYPE_SIZE_FLAGS} - "${CHECK_TYPE_SIZE_ADD_LIBRARIES}" - OUTPUT_VARIABLE OUTPUT) - IF(HAVE_${VARIABLE}) - MESSAGE(STATUS "Check size of ${TYPE} - done") - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeOutput.log - "Determining size of ${TYPE} passed with the following output:\n${OUTPUT}\n\n") - ELSE(HAVE_${VARIABLE}) - MESSAGE(STATUS "Check size of ${TYPE} - failed") - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeError.log - "Determining size of ${TYPE} failed with the following output:\n${OUTPUT}\nCheckTypeSize.c:\n${CHECK_TYPE_SIZE_FILE_CONTENT}\n\n") - ENDIF(HAVE_${VARIABLE}) - ENDIF("HAVE_${VARIABLE}" MATCHES "^HAVE_${VARIABLE}$") - ENDIF(NOT DEFINED ${VARIABLE}) - SET(CMAKE_ALLOW_UNKNOWN_VARIABLE_READ_ACCESS ) -ENDMACRO(CHECK_TYPE_SIZE) diff --git a/Source/CTest/Curl/CMake/CurlTests.c b/Source/CTest/Curl/CMake/CurlTests.c deleted file mode 100644 index 61278ea..0000000 --- a/Source/CTest/Curl/CMake/CurlTests.c +++ /dev/null @@ -1,535 +0,0 @@ -#ifdef TIME_WITH_SYS_TIME -/* Time with sys/time test */ - -#include <sys/types.h> -#include <sys/time.h> -#include <time.h> - -int -main () -{ -if ((struct tm *) 0) -return 0; - ; - return 0; -} - -#endif - -#ifdef HAVE_O_NONBLOCK - -#include <sys/types.h> -#include <unistd.h> -#include <fcntl.h> - -int -main () -{ - /* try to compile O_NONBLOCK */ - -#if defined(sun) || defined(__sun__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) -# if defined(__SVR4) || defined(__srv4__) -# define PLATFORM_SOLARIS -# else -# define PLATFORM_SUNOS4 -# endif -#endif -#if (defined(_AIX) || defined(__xlC__)) && !defined(_AIX4) -# define PLATFORM_AIX_V3 -#endif - -#if defined(PLATFORM_SUNOS4) || defined(PLATFORM_AIX_V3) || defined(__BEOS__) -#error "O_NONBLOCK does not work on this platform" -#endif - int socket; - int flags = fcntl(socket, F_SETFL, flags | O_NONBLOCK); - return 0; -} -#endif - -#ifdef HAVE_GETHOSTBYADDR_R_5 -#include <sys/types.h> -#include <netdb.h> -int -main () -{ - -char * address; -int length; -int type; -struct hostent h; -struct hostent_data hdata; -int rc; -#ifndef gethostbyaddr_r - (void)gethostbyaddr_r; -#endif -rc = gethostbyaddr_r(address, length, type, &h, &hdata); - ; - return 0; -} -#endif -#ifdef HAVE_GETHOSTBYADDR_R_5_REENTRANT -#define _REENTRANT -#include <sys/types.h> -#include <netdb.h> -int -main () -{ - -char * address; -int length;q -int type; -struct hostent h; -struct hostent_data hdata; -int rc; -#ifndef gethostbyaddr_r - (void)gethostbyaddr_r; -#endif -rc = gethostbyaddr_r(address, length, type, &h, &hdata); - ; - return 0; -} -#endif -#ifdef HAVE_GETHOSTBYADDR_R_7 -#include <sys/types.h> -#include <netdb.h> -int -main () -{ - -char * address; -int length; -int type; -struct hostent h; -char buffer[8192]; -int h_errnop; -struct hostent * hp; - -#ifndef gethostbyaddr_r - (void)gethostbyaddr_r; -#endif -hp = gethostbyaddr_r(address, length, type, &h, - buffer, 8192, &h_errnop); - ; - return 0; -} -#endif -#ifdef HAVE_GETHOSTBYADDR_R_7_REENTRANT -#define _REENTRANT -#include <sys/types.h> -#include <netdb.h> -int -main () -{ - -char * address; -int length; -int type; -struct hostent h; -char buffer[8192]; -int h_errnop; -struct hostent * hp; - -#ifndef gethostbyaddr_r - (void)gethostbyaddr_r; -#endif -hp = gethostbyaddr_r(address, length, type, &h, - buffer, 8192, &h_errnop); - ; - return 0; -} -#endif -#ifdef HAVE_GETHOSTBYADDR_R_8 -#include <sys/types.h> -#include <netdb.h> -int -main () -{ - -char * address; -int length; -int type; -struct hostent h; -char buffer[8192]; -int h_errnop; -struct hostent * hp; -int rc; - -#ifndef gethostbyaddr_r - (void)gethostbyaddr_r; -#endif -rc = gethostbyaddr_r(address, length, type, &h, - buffer, 8192, &hp, &h_errnop); - ; - return 0; -} -#endif -#ifdef HAVE_GETHOSTBYADDR_R_8_REENTRANT -#define _REENTRANT -#include <sys/types.h> -#include <netdb.h> -int -main () -{ - -char * address; -int length; -int type; -struct hostent h; -char buffer[8192]; -int h_errnop; -struct hostent * hp; -int rc; - -#ifndef gethostbyaddr_r - (void)gethostbyaddr_r; -#endif -rc = gethostbyaddr_r(address, length, type, &h, - buffer, 8192, &hp, &h_errnop); - ; - return 0; -} -#endif -#ifdef HAVE_GETHOSTBYNAME_R_3 -#include <string.h> -#include <sys/types.h> -#include <netdb.h> -#undef NULL -#define NULL (void *)0 - -int -main () -{ - -struct hostent_data data; -#ifndef gethostbyname_r - (void)gethostbyname_r; -#endif -gethostbyname_r(NULL, NULL, NULL); - ; - return 0; -} -#endif -#ifdef HAVE_GETHOSTBYNAME_R_3_REENTRANT -#define _REENTRANT -#include <string.h> -#include <sys/types.h> -#include <netdb.h> -#undef NULL -#define NULL (void *)0 - -int -main () -{ - -struct hostent_data data; -#ifndef gethostbyname_r - (void)gethostbyname_r; -#endif -gethostbyname_r(NULL, NULL, NULL); - ; - return 0; -} -#endif -#ifdef HAVE_GETHOSTBYNAME_R_5 -#include <sys/types.h> -#include <netinet/in.h> -#include <netdb.h> -#undef NULL -#define NULL (void *)0 - -int -main () -{ -#ifndef gethostbyname_r - (void)gethostbyname_r; -#endif -gethostbyname_r(NULL, NULL, NULL, 0, NULL); - ; - return 0; -} -#endif -#ifdef HAVE_GETHOSTBYNAME_R_5_REENTRANT -#define _REENTRANT -#include <sys/types.h> -#include <netdb.h> -#undef NULL -#define NULL (void *)0 - -int -main () -{ - -#ifndef gethostbyname_r - (void)gethostbyname_r; -#endif -gethostbyname_r(NULL, NULL, NULL, 0, NULL); - ; - return 0; -} -#endif -#ifdef HAVE_GETHOSTBYNAME_R_6 -#include <sys/types.h> -#include <netdb.h> -#undef NULL -#define NULL (void *)0 - -int -main () -{ - -#ifndef gethostbyname_r - (void)gethostbyname_r; -#endif -gethostbyname_r(NULL, NULL, NULL, 0, NULL, NULL); - ; - return 0; -} -#endif -#ifdef HAVE_GETHOSTBYNAME_R_6_REENTRANT -#define _REENTRANT -#include <sys/types.h> -#include <netdb.h> -#undef NULL -#define NULL (void *)0 - -int -main () -{ - -#ifndef gethostbyname_r - (void)gethostbyname_r; -#endif -gethostbyname_r(NULL, NULL, NULL, 0, NULL, NULL); - ; - return 0; -} -#endif -#ifdef HAVE_SOCKLEN_T -#include <sys/types.h> -#include <sys/socket.h> - -int -main () -{ -if ((socklen_t *) 0) - return 0; -if (sizeof (socklen_t)) - return 0; - ; - return 0; -} -#endif -#ifdef HAVE_IN_ADDR_T -#include <sys/types.h> -#include <sys/socket.h> -#include <arpa/inet.h> - -int -main () -{ -if ((in_addr_t *) 0) - return 0; -if (sizeof (in_addr_t)) - return 0; - ; - return 0; -} -#endif -#ifdef STDC_HEADERS -#include <stdlib.h> -#include <stdarg.h> -#include <string.h> -#include <float.h> -int main() { return 0; } -#endif -#ifdef RETSIGTYPE_TEST -#include <sys/types.h> -#include <signal.h> -#ifdef signal -# undef signal -#endif -#ifdef __cplusplus -extern "C" void (*signal (int, void (*)(int)))(int); -#else -void (*signal ()) (); -#endif - -int -main () -{ - return 0; -} -#endif -#ifdef HAVE_INET_NTOA_R_DECL -#include <arpa/inet.h> - -typedef void (*func_type)(); - -int main() -{ -#ifndef inet_ntoa_r - func_type func; - func = (func_type)inet_ntoa_r; -#endif - return 0; -} -#endif -#ifdef HAVE_INET_NTOA_R_DECL_REENTRANT -#define _REENTRANT -#include <arpa/inet.h> - -typedef void (*func_type)(); - -int main() -{ -#ifndef inet_ntoa_r - func_type func; - func = (func_type)&inet_ntoa_r; -#endif - return 0; -} -#endif -#ifdef HAVE_GETADDRINFO -#include <netdb.h> -#include <sys/types.h> -#include <sys/socket.h> - -int main(void) { - struct addrinfo hints, *ai; - int error; - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; -#ifndef getaddrinfo - (void)getaddrinfo; -#endif - error = getaddrinfo("127.0.0.1", "8080", &hints, &ai); - if (error) { - return 1; - } - return 0; -} -#endif -#ifdef HAVE_FILE_OFFSET_BITS -#ifdef _FILE_OFFSET_BITS -#undef _FILE_OFFSET_BITS -#endif -#define _FILE_OFFSET_BITS 64 -#include <sys/types.h> - /* Check that off_t can represent 2**63 - 1 correctly. - We can't simply define LARGE_OFF_T to be 9223372036854775807, - since some C++ compilers masquerading as C compilers - incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) - int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 - && LARGE_OFF_T % 2147483647 == 1) - ? 1 : -1]; -int main () { ; return 0; } -#endif -#ifdef HAVE_IOCTLSOCKET -#include <windows.h> - -int -main () -{ - -/* ioctlsocket source code */ - int socket; - unsigned long flags = ioctlsocket(socket, FIONBIO, &flags); - - ; - return 0; -} - -#endif -#ifdef HAVE_IOCTLSOCKET_CASE -#include <windows.h> - -int -main () -{ - -/* IoctlSocket source code */ - int socket; - int flags = IoctlSocket(socket, FIONBIO, (long)1); - - ; - return 0; -} -#endif -#ifdef HAVE_FIONBIO -/* headers for FIONBIO test */ -#include <unistd.h> -#include <stropts.h> - -int -main () -{ - -/* FIONBIO source test (old-style unix) */ - int socket; - int flags = ioctl(socket, FIONBIO, &flags); - - ; - return 0; -} -#endif -#ifdef HAVE_SO_NONBLOCK - -/* headers for SO_NONBLOCK test (BeOS) */ -#include <sys/types.h> -#include <unistd.h> -#include <fcntl.h> - -int main() -{ -/* SO_NONBLOCK source code */ - long b = 1; - int socket; - int flags = setsockopt(socket, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b)); - return 0; -} -#endif -#ifdef HAVE_GLIBC_STRERROR_R -#include <string.h> -#include <errno.h> -int -main () { - char buffer[1024]; /* big enough to play with */ - char *string = - strerror_r(EACCES, buffer, sizeof(buffer)); - /* this should've returned a string */ - if(!string || !string[0]) - return 99; - return 0; -} -#endif -#ifdef HAVE_POSIX_STRERROR_R -#include <string.h> -#include <errno.h> -int -main () { - char buffer[1024]; /* big enough to play with */ - int error = - strerror_r(EACCES, buffer, sizeof(buffer)); - /* This should've returned zero, and written an error string in the - buffer.*/ - if(!buffer[0] || error) - return 99; - return 0; -} -#endif -#ifdef HAVE_LONG_LONG_CONSTANT -int main() -{ - long long c = 0x8000000000000000LL; - long long k = 0x7FFFFFFFFFFFFFFFLL; - if ( c == 0x8000000000000000LL && c != k ) - { - return 0; - } - return 1; -} -#endif diff --git a/Source/CTest/Curl/CMakeLists.txt b/Source/CTest/Curl/CMakeLists.txt deleted file mode 100644 index b61087b..0000000 --- a/Source/CTest/Curl/CMakeLists.txt +++ /dev/null @@ -1,586 +0,0 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.0) -PROJECT(LIBCURL C) - -INCLUDE_REGULAR_EXPRESSION("^.*\\.h$") - -# Setup package meta-data -SET(PACKAGE "curl") -SET(VERSION "7.12.1") -SET(PACKAGE_TARNAME "curl") -SET(PACKAGE_BUGREPORT " ") -SET(PACKAGE_NAME "curl") -SET(PACKAGE_VERSION "-") -SET(PACKAGE_STRING "curl-") -SET(PACKAGE_BUGREPORT "a suitable curl mailing list => http://curl.haxx.se/mail/") -SET(OPERATING_SYSTEM "${CMAKE_SYSTEM_NAME}") - -# We need ansi c-flags, especially on HP -SET(CMAKE_C_FLAGS "${CMAKE_ANSI_CFLAGS} ${CMAKE_C_FLAGS}") -SET(CMAKE_REQUIRED_FLAGS ${CMAKE_ANSI_CFLAGS}) - -# If we are on AIX, do the _ALL_SOURCE magic -IF(${CMAKE_SYSTEM_NAME} MATCHES AIX) - SET(_ALL_SOURCE 1) -ENDIF(${CMAKE_SYSTEM_NAME} MATCHES AIX) - -# Include all the necessary files for macros -SET(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake") -INCLUDE (CheckFunctionExists) -INCLUDE (CheckIncludeFile) -INCLUDE (CheckIncludeFiles) -INCLUDE (CheckLibraryExists) -INCLUDE (CheckSymbolExists) -INCLUDE (CheckTypeSize) - -SET(libCurl_SRCS - base64.c - connect.c - content_encoding.c - cookie.c - dict.c - easy.c - escape.c - file.c - formdata.c - ftp.c - getdate.c - getenv.c - getinfo.c - hash.c - hostares.c - hostasyn.c - hostip.c - hostip4.c - hostip6.c - hostsyn.c - hostthre.c - http.c - http_chunks.c - http_digest.c - http_negotiate.c - http_ntlm.c - if2ip.c - inet_ntop.c - inet_pton.c - krb4.c - llist.c - md5.c - memdebug.c - mprintf.c - multi.c - netrc.c - progress.c - sendf.c - share.c - speedcheck.c - ssluse.c - strequal.c - strerror.c - telnet.c - timeval.c - transfer.c - url.c - version.c - ) - -SET(CURL_DISABLE_LDAP 1) -IF(NOT CURL_DISABLE_LDAP) - SET(libCurl_SRCS - ${libCurl_SRCS} - ldap.c - ) -ENDIF(NOT CURL_DISABLE_LDAP) - -# if we have Kerberos 4, right now this is never on -#OPTION(CURL_KRB4 "Use Kerberos 4" OFF) -IF(CURL_KRB4) - SET(libCurl_SRCS ${libCurl_SRCS} - krb4.c - security.c - ) -ENDIF(CURL_KRB4) - -#OPTION(CURL_MALLOC_DEBUG "Debug mallocs in Curl" OFF) -MARK_AS_ADVANCED(CURL_MALLOC_DEBUG) -IF(CURL_MALLOC_DEBUG) - SET(libCurl_SRCS ${libCurl_SRCS} - memdebug.c - ) -ENDIF(CURL_MALLOC_DEBUG) - -# On windows preload settings -IF(WIN32) - INCLUDE(${LIBCURL_SOURCE_DIR}/Platforms/WindowsCache.cmake) -ENDIF(WIN32) - -# This macro checks if the symbol exists in the library and if it -# does, it appends library to the list. -SET(CURL_LIBS "") -MACRO(CHECK_LIBRARY_EXISTS_CONCAT LIBRARY SYMBOL VARIABLE) - CHECK_LIBRARY_EXISTS("${LIBRARY};${CURL_LIBS}" ${SYMBOL} "" - ${VARIABLE}) - IF(${VARIABLE}) - SET(CURL_LIBS ${CURL_LIBS} ${LIBRARY}) - ENDIF(${VARIABLE}) -ENDMACRO(CHECK_LIBRARY_EXISTS_CONCAT) - -# Check for all needed libraries -CHECK_LIBRARY_EXISTS_CONCAT("dl" dlopen HAVE_LIBDL) -CHECK_LIBRARY_EXISTS_CONCAT("ucb" gethostname HAVE_LIBUCB) -CHECK_LIBRARY_EXISTS_CONCAT("socket" connect HAVE_LIBSOCKET) -CHECK_LIBRARY_EXISTS("c" gethostbyname "" NOT_NEED_LIBNSL) - -IF(NOT NOT_NEED_LIBNSL) - CHECK_LIBRARY_EXISTS_CONCAT("nsl" gethostbyname HAVE_LIBNSL) -ENDIF(NOT NOT_NEED_LIBNSL) - -CHECK_LIBRARY_EXISTS_CONCAT("ws2_32" getch HAVE_LIBWS2_32) -CHECK_LIBRARY_EXISTS_CONCAT("winmm" getch HAVE_LIBWINMM) -IF(NOT CURL_SPECIAL_LIBZ) - CHECK_LIBRARY_EXISTS_CONCAT("z" inflateEnd HAVE_LIBZ) -ENDIF(NOT CURL_SPECIAL_LIBZ) - -#OPTION(CMAKE_USE_OPENSSL "Use OpenSSL code. Experimental" OFF) -MARK_AS_ADVANCED(CMAKE_USE_OPENSSL) -IF(CMAKE_USE_OPENSSL) - CHECK_LIBRARY_EXISTS_CONCAT("crypto" CRYPTO_lock HAVE_LIBCRYPTO) - CHECK_LIBRARY_EXISTS_CONCAT("ssl" SSL_connect HAVE_LIBSSL) -ENDIF(CMAKE_USE_OPENSSL) - -# Check for symbol dlopen (same as HAVE_LIBDL) -CHECK_LIBRARY_EXISTS("${CURL_LIBS}" dlopen "" HAVE_DLOPEN) - -# For other tests to use the same libraries -SET(CMAKE_REQUIRED_LIBRARIES ${CURL_LIBS}) - -IF(CURL_SPECIAL_LIBZ) - SET(CURL_LIBS ${CURL_LIBS} "${CURL_SPECIAL_LIBZ}") - INCLUDE_DIRECTORIES(${CURL_SPECIAL_LIBZ_INCLUDES}) - SET(HAVE_LIBZ 0) - SET(HAVE_ZLIB_H 0) -ENDIF(CURL_SPECIAL_LIBZ) - - -# If we have features.h, then do the _BSD_SOURCE magic -CHECK_INCLUDE_FILE("features.h" HAVE_FEATURES_H) -IF(HAVE_FEATURES_H) - SET_SOURCE_FILES_PROPERTIES( - cookie.c - easy.c - formdata.c - getenv.c - hash.c - http.c - if2ip.c - mprintf.c - multi.c - sendf.c - telnet.c - transfer.c - url.c - COMPILE_FLAGS -D_BSD_SOURCE) -ENDIF(HAVE_FEATURES_H) - -# Check if header file exists and add it to the list. -MACRO(CHECK_INCLUDE_FILE_CONCAT FILE VARIABLE) - CHECK_INCLUDE_FILES("${CURL_INCLUDES};${FILE}" ${VARIABLE}) - IF(${VARIABLE}) - SET(CURL_INCLUDES ${CURL_INCLUDES} ${FILE}) - ENDIF(${VARIABLE}) -ENDMACRO(CHECK_INCLUDE_FILE_CONCAT) - -# Check for header files -CHECK_INCLUDE_FILE_CONCAT("stdio.h" HAVE_STDIO_H) -CHECK_INCLUDE_FILE_CONCAT("stddef.h" HAVE_STDDEF_H) -CHECK_INCLUDE_FILE_CONCAT("sys/types.h" HAVE_SYS_TYPES_H) -CHECK_INCLUDE_FILE_CONCAT("inttypes.h" HAVE_INTTYPES_H) -CHECK_INCLUDE_FILE_CONCAT("alloca.h" HAVE_ALLOCA_H) -CHECK_INCLUDE_FILE_CONCAT("arpa/inet.h" HAVE_ARPA_INET_H) -CHECK_INCLUDE_FILE_CONCAT("dlfcn.h" HAVE_DLFCN_H) -CHECK_INCLUDE_FILE_CONCAT("fcntl.h" HAVE_FCNTL_H) -CHECK_INCLUDE_FILE_CONCAT("malloc.h" HAVE_MALLOC_H) -CHECK_INCLUDE_FILE_CONCAT("memory.h" HAVE_MEMORY_H) -CHECK_INCLUDE_FILE_CONCAT("netdb.h" HAVE_NETDB_H) -CHECK_INCLUDE_FILE_CONCAT("sys/poll.h" HAVE_SYS_POLL_H) -CHECK_INCLUDE_FILE_CONCAT("assert.h" HAVE_ASSERT_H) -CHECK_INCLUDE_FILE_CONCAT("limits.h" HAVE_LIMITS_H) - -IF(CMAKE_USE_OPENSSL) - CHECK_INCLUDE_FILE_CONCAT("openssl/x509.h" HAVE_OPENSSL_X509_H) - CHECK_INCLUDE_FILE_CONCAT("openssl/engine.h" HAVE_OPENSSL_ENGINE_H) - CHECK_INCLUDE_FILE_CONCAT("openssl/rsa.h" HAVE_OPENSSL_RSA_H) - CHECK_INCLUDE_FILE_CONCAT("openssl/crypto.h" HAVE_OPENSSL_CRYPTO_H) - CHECK_INCLUDE_FILE_CONCAT("openssl/pem.h" HAVE_OPENSSL_PEM_H) - CHECK_INCLUDE_FILE_CONCAT("openssl/ssl.h" HAVE_OPENSSL_SSL_H) - CHECK_INCLUDE_FILE_CONCAT("openssl/err.h" HAVE_OPENSSL_ERR_H) - CHECK_INCLUDE_FILE_CONCAT("openssl/rand.h" HAVE_OPENSSL_RAND_H) -ENDIF(CMAKE_USE_OPENSSL) - -IF(NOT CURL_SPECIAL_LIBZ) - CHECK_INCLUDE_FILE_CONCAT("zlib.h" HAVE_ZLIB_H) -ENDIF(NOT CURL_SPECIAL_LIBZ) -CHECK_INCLUDE_FILE_CONCAT("sys/socket.h" HAVE_SYS_SOCKET_H) -CHECK_INCLUDE_FILE_CONCAT("netinet/in.h" HAVE_NETINET_IN_H) -CHECK_INCLUDE_FILE_CONCAT("net/if.h" HAVE_NET_IF_H) -CHECK_INCLUDE_FILE_CONCAT("netinet/if_ether.h" - HAVE_NETINET_IF_ETHER_H) -CHECK_INCLUDE_FILE_CONCAT("netinet/tcp.h" - HAVE_NETINET_TCP_H) -CHECK_INCLUDE_FILE_CONCAT("sys/select.h" HAVE_SYS_SELECT_H) -CHECK_INCLUDE_FILE_CONCAT("utime.h" HAVE_UTIME_H) -CHECK_INCLUDE_FILE_CONCAT("netinet/in.h" HAVE_NETINET_IN_H) -CHECK_INCLUDE_FILE_CONCAT("pwd.h" HAVE_PWD_H) -CHECK_INCLUDE_FILE_CONCAT("sgtty.h" HAVE_SGTTY_H) -CHECK_INCLUDE_FILE_CONCAT("stdint.h" HAVE_STDINT_H) -CHECK_INCLUDE_FILE_CONCAT("stdlib.h" HAVE_STDLIB_H) -CHECK_INCLUDE_FILE_CONCAT("string.h" HAVE_STRING_H) -CHECK_INCLUDE_FILE_CONCAT("strings.h" HAVE_STRINGS_H) -CHECK_INCLUDE_FILE_CONCAT("sys/param.h" HAVE_SYS_PARAM_H) -CHECK_INCLUDE_FILE_CONCAT("sys/stat.h" HAVE_SYS_STAT_H) -CHECK_INCLUDE_FILE_CONCAT("sys/time.h" HAVE_SYS_TIME_H) -CHECK_INCLUDE_FILE_CONCAT("termios.h" HAVE_TERMIOS_H) -CHECK_INCLUDE_FILE_CONCAT("termio.h" HAVE_TERMIO_H) -CHECK_INCLUDE_FILE_CONCAT("io.h" HAVE_IO_H) -CHECK_INCLUDE_FILE_CONCAT("time.h" HAVE_TIME_H) -CHECK_INCLUDE_FILE_CONCAT("unistd.h" HAVE_UNISTD_H) -CHECK_INCLUDE_FILE_CONCAT("sys/utime.h" HAVE_SYS_UTIME_H) -CHECK_INCLUDE_FILE_CONCAT("winsock.h" HAVE_WINSOCK_H) -CHECK_INCLUDE_FILE_CONCAT("sockio.h" HAVE_SOCKIO_H) -CHECK_INCLUDE_FILE_CONCAT("sys/sockio.h" HAVE_SYS_SOCKIO_H) -CHECK_INCLUDE_FILE_CONCAT("x509.h" HAVE_X509_H) -CHECK_INCLUDE_FILE_CONCAT("setjmp.h" HAVE_SETJMP_H) -CHECK_INCLUDE_FILE_CONCAT("signal.h" HAVE_SIGNAL_H) -CHECK_INCLUDE_FILE_CONCAT("sys/ioctl.h" HAVE_SYS_IOCTL_H) -CHECK_INCLUDE_FILE_CONCAT("sys/utsname.h" HAVE_SYS_UTSNAME_H) - -CHECK_TYPE_SIZE(size_t SIZEOF_SIZE_T) -CHECK_TYPE_SIZE(ssize_t SIZEOF_SSIZE_T) -CHECK_TYPE_SIZE("long long" SIZEOF_LONG_LONG) -CHECK_TYPE_SIZE("long double" SIZEOF_LONG_DOUBLE) -IF(NOT HAVE_SIZEOF_SSIZE_T) - SET(ssize_t int) -ENDIF(NOT HAVE_SIZEOF_SSIZE_T) -IF(HAVE_SIZEOF_LONG_LONG) - SET(HAVE_LONGLONG 1) -ENDIF(HAVE_SIZEOF_LONG_LONG) - -FIND_FILE(RANDOM_FILE urandom /dev) -MARK_AS_ADVANCED(RANDOM_FILE) - -# Check for some functions that are used -CHECK_SYMBOL_EXISTS(socket "${CURL_INCLUDES}" HAVE_SOCKET) -CHECK_SYMBOL_EXISTS(poll "${CURL_INCLUDES}" HAVE_POLL) -CHECK_SYMBOL_EXISTS(select "${CURL_INCLUDES}" HAVE_SELECT) -CHECK_SYMBOL_EXISTS(strdup "${CURL_INCLUDES}" HAVE_STRDUP) -CHECK_SYMBOL_EXISTS(strstr "${CURL_INCLUDES}" HAVE_STRSTR) -CHECK_SYMBOL_EXISTS(strtok_r "${CURL_INCLUDES}" HAVE_STRTOK_R) -CHECK_SYMBOL_EXISTS(strftime "${CURL_INCLUDES}" HAVE_STRFTIME) -CHECK_SYMBOL_EXISTS(uname "${CURL_INCLUDES}" HAVE_UNAME) -CHECK_SYMBOL_EXISTS(strcasecmp "${CURL_INCLUDES}" HAVE_STRCASECMP) -CHECK_SYMBOL_EXISTS(stricmp "${CURL_INCLUDES}" HAVE_STRICMP) -CHECK_SYMBOL_EXISTS(strcmpi "${CURL_INCLUDES}" HAVE_STRCMPI) -CHECK_SYMBOL_EXISTS(strncmpi "${CURL_INCLUDES}" HAVE_STRNCMPI) -IF(NOT HAVE_STRNCMPI) - SET(HAVE_STRCMPI) -ENDIF(NOT HAVE_STRNCMPI) -CHECK_SYMBOL_EXISTS(gethostbyaddr "${CURL_INCLUDES}" HAVE_GETHOSTBYADDR) -CHECK_SYMBOL_EXISTS(gettimeofday "${CURL_INCLUDES}" HAVE_GETTIMEOFDAY) -CHECK_SYMBOL_EXISTS(inet_addr "${CURL_INCLUDES}" HAVE_INET_ADDR) -CHECK_SYMBOL_EXISTS(inet_pton "${CURL_INCLUDES}" HAVE_INET_PTON) -CHECK_SYMBOL_EXISTS(inet_ntoa "${CURL_INCLUDES}" HAVE_INET_NTOA) -CHECK_SYMBOL_EXISTS(inet_ntoa_r "${CURL_INCLUDES}" HAVE_INET_NTOA_R) -CHECK_SYMBOL_EXISTS(tcsetattr "${CURL_INCLUDES}" HAVE_TCSETATTR) -CHECK_SYMBOL_EXISTS(tcgetattr "${CURL_INCLUDES}" HAVE_TCGETATTR) -CHECK_SYMBOL_EXISTS(perror "${CURL_INCLUDES}" HAVE_PERROR) -CHECK_SYMBOL_EXISTS(closesocket "${CURL_INCLUDES}" HAVE_CLOSESOCKET) -CHECK_SYMBOL_EXISTS(setvbuf "${CURL_INCLUDES}" HAVE_SETVBUF) -CHECK_SYMBOL_EXISTS(sigsetjmp "${CURL_INCLUDES}" HAVE_SIGSETJMP) -CHECK_SYMBOL_EXISTS(getpass_r "${CURL_INCLUDES}" HAVE_GETPASS_R) -CHECK_SYMBOL_EXISTS(strlcat "${CURL_INCLUDES}" HAVE_STRLCAT) -CHECK_SYMBOL_EXISTS(getpwuid "${CURL_INCLUDES}" HAVE_GETPWUID) -CHECK_SYMBOL_EXISTS(geteuid "${CURL_INCLUDES}" HAVE_GETEUID) -CHECK_SYMBOL_EXISTS(utime "${CURL_INCLUDES}" HAVE_UTIME) -IF(CMAKE_USE_OPENSSL) - CHECK_SYMBOL_EXISTS(RAND_status "${CURL_INCLUDES}" HAVE_RAND_STATUS) - CHECK_SYMBOL_EXISTS(RAND_screen "${CURL_INCLUDES}" HAVE_RAND_SCREEN) - CHECK_SYMBOL_EXISTS(RAND_egd "${CURL_INCLUDES}" HAVE_RAND_EGD) - CHECK_SYMBOL_EXISTS(CRYPTO_cleanup_all_ex_data "${CURL_INCLUDES}" - HAVE_CRYPTO_CLEANUP_ALL_EX_DATA) -ENDIF(CMAKE_USE_OPENSSL) -CHECK_SYMBOL_EXISTS(gmtime_r "${CURL_INCLUDES}" HAVE_GMTIME_R) -CHECK_SYMBOL_EXISTS(localtime_r "${CURL_INCLUDES}" HAVE_LOCALTIME_R) - -CHECK_SYMBOL_EXISTS(gethostbyname "${CURL_INCLUDES}" HAVE_GETHOSTBYNAME) -CHECK_SYMBOL_EXISTS(gethostbyname_r "${CURL_INCLUDES}" HAVE_GETHOSTBYNAME_R) -CHECK_SYMBOL_EXISTS(gethostbyaddr_r "${CURL_INCLUDES}" HAVE_GETHOSTBYADDR_R) - -CHECK_SYMBOL_EXISTS(signal "${CURL_INCLUDES}" HAVE_SIGNAL_FUNC) -CHECK_SYMBOL_EXISTS(SIGALRM "${CURL_INCLUDES}" HAVE_SIGNAL_MACRO) -IF(HAVE_SIGNAL_FUNC AND HAVE_SIGNAL_MACRO) - SET(HAVE_SIGNAL 1) -ENDIF(HAVE_SIGNAL_FUNC AND HAVE_SIGNAL_MACRO) -CHECK_SYMBOL_EXISTS(uname "${CURL_INCLUDES}" HAVE_UNAME) -CHECK_SYMBOL_EXISTS(strtoll "${CURL_INCLUDES}" HAVE_STRTOLL) -CHECK_SYMBOL_EXISTS(_strtoi64 "${CURL_INCLUDES}" HAVE__STRTOI64) -CHECK_SYMBOL_EXISTS(strerror_r "${CURL_INCLUDES}" HAVE_STRERROR_R) -CHECK_SYMBOL_EXISTS(siginterrupt "${CURL_INCLUDES}" HAVE_SIGINTERRUPT) -CHECK_SYMBOL_EXISTS(perror "${CURL_INCLUDES}" HAVE_PERROR) - -# only build compat strtok if we need to -IF (NOT HAVE_STRTOK_R) - SET(libCurl_SRCS ${libCurl_SRCS} - strtok.c - ) -ENDIF (NOT HAVE_STRTOK_R) -IF(NOT HAVE_STRTOLL AND NOT HAVE__STRTOI64) - SET(libCurl_SRCS ${libCurl_SRCS} - strtoofft.c - ) -ENDIF(NOT HAVE_STRTOLL AND NOT HAVE__STRTOI64) - -# sigaction and sigsetjmp are special. Use special mechanism for -# detecting those, but only if previous attempt failed. -IF(HAVE_SIGNAL_H) - CHECK_SYMBOL_EXISTS(sigaction "signal.h" HAVE_SIGACTION) -ENDIF(HAVE_SIGNAL_H) - -IF(NOT HAVE_SIGSETJMP) - IF(HAVE_SETJMP_H) - CHECK_SYMBOL_EXISTS(sigsetjmp "setjmp.h" HAVE_MACRO_SIGSETJMP) - IF(HAVE_MACRO_SIGSETJMP) - SET(HAVE_SIGSETJMP 1) - ENDIF(HAVE_MACRO_SIGSETJMP) - ENDIF(HAVE_SETJMP_H) -ENDIF(NOT HAVE_SIGSETJMP) - -# For other curl specific tests, use this macro. -MACRO(CURL_INTERNAL_TEST CURL_TEST) - IF("${CURL_TEST}" MATCHES "^${CURL_TEST}$") - SET(MACRO_CHECK_FUNCTION_DEFINITIONS - "-D${CURL_TEST} ${CMAKE_REQUIRED_FLAGS}") - IF(CMAKE_REQUIRED_LIBRARIES) - SET(CURL_TEST_ADD_LIBRARIES - "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}") - ENDIF(CMAKE_REQUIRED_LIBRARIES) - - MESSAGE(STATUS "Performing Curl Test ${CURL_TEST}") - TRY_COMPILE(${CURL_TEST} - ${CMAKE_BINARY_DIR} - ${LIBCURL_SOURCE_DIR}/CMake/CurlTests.c - CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS} - "${CURL_TEST_ADD_LIBRARIES}" - OUTPUT_VARIABLE OUTPUT) - IF(${CURL_TEST}) - SET(${CURL_TEST} 1 CACHE INTERNAL "Curl test ${FUNCTION}") - MESSAGE(STATUS "Performing Curl Test ${CURL_TEST} - Success") - ELSE(${CURL_TEST}) - MESSAGE(STATUS "Performing Curl Test ${CURL_TEST} - Failed") - SET(${CURL_TEST} "" CACHE INTERNAL "Curl test ${FUNCTION}") - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeError.log - "Performing Curl Test ${CURL_TEST} failed with the following output:\n" - "${OUTPUT}\n") - ENDIF(${CURL_TEST}) - ENDIF("${CURL_TEST}" MATCHES "^${CURL_TEST}$") -ENDMACRO(CURL_INTERNAL_TEST) -MACRO(CURL_INTERNAL_TEST_RUN CURL_TEST) - IF("${CURL_TEST}_COMPILE" MATCHES "^${CURL_TEST}_COMPILE$") - SET(MACRO_CHECK_FUNCTION_DEFINITIONS - "-D${CURL_TEST} ${CMAKE_REQUIRED_FLAGS}") - IF(CMAKE_REQUIRED_LIBRARIES) - SET(CURL_TEST_ADD_LIBRARIES - "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}") - ENDIF(CMAKE_REQUIRED_LIBRARIES) - - MESSAGE(STATUS "Performing Curl Test ${CURL_TEST}") - TRY_RUN(${CURL_TEST} ${CURL_TEST}_COMPILE - ${CMAKE_BINARY_DIR} - ${LIBCURL_SOURCE_DIR}/CMake/CurlTests.c - CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS} - "${CURL_TEST_ADD_LIBRARIES}" - OUTPUT_VARIABLE OUTPUT) - IF(${CURL_TEST}_COMPILE AND NOT ${CURL_TEST}) - SET(${CURL_TEST} 1 CACHE INTERNAL "Curl test ${FUNCTION}") - MESSAGE(STATUS "Performing Curl Test ${CURL_TEST} - Success") - ELSE(${CURL_TEST}_COMPILE AND NOT ${CURL_TEST}) - MESSAGE(STATUS "Performing Curl Test ${CURL_TEST} - Failed") - SET(${CURL_TEST} "" CACHE INTERNAL "Curl test ${FUNCTION}") - FILE(APPEND "${CMAKE_BINARY_DIR}/CMakeError.log" - "Performing Curl Test ${CURL_TEST} failed with the following output:\n" - "${OUTPUT}") - IF(${CURL_TEST}_COMPILE) - FILE(APPEND "${CMAKE_BINARY_DIR}/CMakeError.log" - "There was a running problem of this test\n") - ENDIF(${CURL_TEST}_COMPILE) - FILE(APPEND "${CMAKE_BINARY_DIR}/CMakeError.log" - "\n\n") - ENDIF(${CURL_TEST}_COMPILE AND NOT ${CURL_TEST}) - ENDIF("${CURL_TEST}_COMPILE" MATCHES "^${CURL_TEST}_COMPILE$") -ENDMACRO(CURL_INTERNAL_TEST_RUN) - -# Do curl specific tests -#OPTION(CURL_HAVE_DISABLED_NONBLOCKING "Disable non-blocking socket detection" OFF) -SET(CURL_NONBLOCKING_TESTS) -IF(NOT CURL_HAVE_DISABLED_NONBLOCKING) - SET(CURL_NONBLOCKING_TESTS - HAVE_FIONBIO - HAVE_IOCTLSOCKET - HAVE_IOCTLSOCKET_CASE - HAVE_O_NONBLOCK - HAVE_SO_NONBLOCK - ) -ENDIF(NOT CURL_HAVE_DISABLED_NONBLOCKING) -FOREACH(CURL_TEST - ${CURL_NONBLOCKING_TESTS} - TIME_WITH_SYS_TIME - HAVE_O_NONBLOCKHAVE_GETHOSTBYADDR_R_5 - HAVE_GETHOSTBYADDR_R_7 - HAVE_GETHOSTBYADDR_R_8 - HAVE_GETHOSTBYADDR_R_5_REENTRANT - HAVE_GETHOSTBYADDR_R_7_REENTRANT - HAVE_GETHOSTBYADDR_R_8_REENTRANT - HAVE_GETHOSTBYNAME_R_3 - HAVE_GETHOSTBYNAME_R_5 - HAVE_GETHOSTBYNAME_R_6 - HAVE_GETHOSTBYNAME_R_3_REENTRANT - HAVE_GETHOSTBYNAME_R_5_REENTRANT - HAVE_GETHOSTBYNAME_R_6_REENTRANT - HAVE_SOCKLEN_T - HAVE_IN_ADDR_T - STDC_HEADERS - RETSIGTYPE_TEST - HAVE_INET_NTOA_R_DECL - HAVE_INET_NTOA_R_DECL_REENTRANT - HAVE_GETADDRINFO - HAVE_FILE_OFFSET_BITS - ) - CURL_INTERNAL_TEST(${CURL_TEST}) -ENDFOREACH(CURL_TEST) -IF(HAVE_FILE_OFFSET_BITS) - SET(_FILE_OFFSET_BITS 64) -ENDIF(HAVE_FILE_OFFSET_BITS) - -FOREACH(CURL_TEST - HAVE_GLIBC_STRERROR_R - HAVE_POSIX_STRERROR_R - HAVE_LONG_LONG_CONSTANT - ) - CURL_INTERNAL_TEST_RUN(${CURL_TEST}) -ENDFOREACH(CURL_TEST) - -# Check for reentrant -FOREACH(CURL_TEST - HAVE_GETHOSTBYADDR_R_5 - HAVE_GETHOSTBYADDR_R_7 - HAVE_GETHOSTBYADDR_R_8 - HAVE_GETHOSTBYNAME_R_3 - HAVE_GETHOSTBYNAME_R_5 - HAVE_GETHOSTBYNAME_R_6 - HAVE_INET_NTOA_R_DECL_REENTRANT) - IF(NOT ${CURL_TEST}) - IF(${CURL_TEST}_REENTRANT) - SET(NEED_REENTRANT 1) - ENDIF(${CURL_TEST}_REENTRANT) - ENDIF(NOT ${CURL_TEST}) -ENDFOREACH(CURL_TEST) - -IF(NEED_REENTRANT) - FOREACH(CURL_TEST - HAVE_GETHOSTBYADDR_R_5 - HAVE_GETHOSTBYADDR_R_7 - HAVE_GETHOSTBYADDR_R_8 - HAVE_GETHOSTBYNAME_R_3 - HAVE_GETHOSTBYNAME_R_5 - HAVE_GETHOSTBYNAME_R_6) - SET(${CURL_TEST} 0) - IF(${CURL_TEST}_REENTRANT) - SET(${CURL_TEST} 1) - ENDIF(${CURL_TEST}_REENTRANT) - ENDFOREACH(CURL_TEST) -ENDIF(NEED_REENTRANT) - -IF(HAVE_INET_NTOA_R_DECL_REENTRANT) - SET(HAVE_INET_NTOA_R_DECL 1) - SET(NEED_REENTRANT 1) -ENDIF(HAVE_INET_NTOA_R_DECL_REENTRANT) - -# Some other minor tests - -IF(NOT HAVE_SOCKLEN_T) - SET(socklen_t "int") -ENDIF(NOT HAVE_SOCKLEN_T) - -IF(NOT HAVE_IN_ADDR_T) - SET(in_addr_t "unsigned long") -ENDIF(NOT HAVE_IN_ADDR_T) - -# Fix libz / zlib.h - -IF(NOT CURL_SPECIAL_LIBZ) - IF(NOT HAVE_LIBZ) - SET(HAVE_ZLIB_H 0) - ENDIF(NOT HAVE_LIBZ) - - IF(NOT HAVE_ZLIB_H) - SET(HAVE_LIBZ 0) - ENDIF(NOT HAVE_ZLIB_H) -ENDIF(NOT CURL_SPECIAL_LIBZ) - -IF(_FILE_OFFSET_BITS) - SET(_FILE_OFFSET_BITS 64) -ENDIF(_FILE_OFFSET_BITS) -SET(CMAKE_REQUIRED_FLAGS "-D_FILE_OFFSET_BITS=64") -SET(CMAKE_EXTRA_INCLUDE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/curl/curl.h") -CHECK_TYPE_SIZE("curl_off_t" SIZEOF_CURL_OFF_T) -SET(CMAKE_EXTRA_INCLUDE_FILES) -SET(CMAKE_REQUIRED_FLAGS) - - -# Check for nonblocking -SET(HAVE_DISABLED_NONBLOCKING 1) -IF(HAVE_FIONBIO OR - HAVE_IOCTLSOCKET OR - HAVE_IOCTLSOCKET_CASE OR - HAVE_O_NONBLOCK) - SET(HAVE_DISABLED_NONBLOCKING) -ENDIF(HAVE_FIONBIO OR - HAVE_IOCTLSOCKET OR - HAVE_IOCTLSOCKET_CASE OR - HAVE_O_NONBLOCK) - -IF(RETSIGTYPE_TEST) - SET(RETSIGTYPE void) -ELSE(RETSIGTYPE_TEST) - SET(RETSIGTYPE int) -ENDIF(RETSIGTYPE_TEST) - -IF(CMAKE_COMPILER_IS_GNUCC AND APPLE) - # The Mac version of GCC warns about use of long double. Disable it. - GET_SOURCE_FILE_PROPERTY(MPRINTF_COMPILE_FLAGS mprintf.c COMPILE_FLAGS) - IF(MPRINTF_COMPILE_FLAGS) - SET(MPRINTF_COMPILE_FLAGS "${MPRINTF_COMPILE_FLAGS} -Wno-long-double") - ELSE(MPRINTF_COMPILE_FLAGS) - SET(MPRINTF_COMPILE_FLAGS "-Wno-long-double") - ENDIF(MPRINTF_COMPILE_FLAGS) - SET_SOURCE_FILES_PROPERTIES(mprintf.c PROPERTIES - COMPILE_FLAGS ${MPRINTF_COMPILE_FLAGS}) -ENDIF(CMAKE_COMPILER_IS_GNUCC AND APPLE) - -# The rest of the build - -INCLUDE_DIRECTORIES(${LIBCURL_SOURCE_DIR}) -INCLUDE_DIRECTORIES(${LIBCURL_BINARY_DIR}) -ADD_DEFINITIONS(-DHAVE_CONFIG_H) -CONFIGURE_FILE(${LIBCURL_SOURCE_DIR}/config.h.in - ${LIBCURL_BINARY_DIR}/config.h) - -ADD_LIBRARY(Curl ${libCurl_SRCS}) -TARGET_LINK_LIBRARIES(Curl ${CURL_LIBS}) - -OPTION(CURL_TESTING "Do libCurl testing" OFF) -IF(CURL_TESTING) - SUBDIRS(Testing) -ENDIF(CURL_TESTING) - -ADD_EXECUTABLE(LIBCURL Testing/curltest.c) -TARGET_LINK_LIBRARIES(LIBCURL Curl) -ADD_TEST(curl "${EXECUTABLE_OUTPUT_PATH}/LIBCURL") diff --git a/Source/CTest/Curl/Platforms/WindowsCache.cmake b/Source/CTest/Curl/Platforms/WindowsCache.cmake deleted file mode 100644 index 1a84b37..0000000 --- a/Source/CTest/Curl/Platforms/WindowsCache.cmake +++ /dev/null @@ -1,123 +0,0 @@ -IF(NOT UNIX) - IF(WIN32) - SET(HAVE_LIBDL 0) - SET(HAVE_LIBUCB 0) - SET(HAVE_LIBSOCKET 0) - SET(NOT_NEED_LIBNSL 0) - SET(HAVE_LIBNSL 0) - SET(HAVE_LIBZ 0) - SET(HAVE_LIBCRYPTO 0) - - SET(HAVE_DLOPEN 0) - - SET(HAVE_ALLOCA_H 0) - SET(HAVE_ARPA_INET_H 0) - SET(HAVE_DLFCN_H 0) - SET(HAVE_FCNTL_H 1) - SET(HAVE_FEATURES_H 0) - SET(HAVE_INTTYPES_H 0) - SET(HAVE_IO_H 1) - SET(HAVE_MALLOC_H 1) - SET(HAVE_MEMORY_H 1) - SET(HAVE_NETDB_H 0) - SET(HAVE_NETINET_IF_ETHER_H 0) - SET(HAVE_NETINET_IN_H 0) - SET(HAVE_NET_IF_H 0) - SET(HAVE_PWD_H 0) - SET(HAVE_SETJMP_H 1) - SET(HAVE_SGTTY_H 0) - SET(HAVE_SIGNAL_H 1) - SET(HAVE_SOCKIO_H 0) - SET(HAVE_STDINT_H 0) - SET(HAVE_STDLIB_H 1) - SET(HAVE_STRINGS_H 0) - SET(HAVE_STRING_H 1) - SET(HAVE_SYS_PARAM_H 0) - SET(HAVE_SYS_POLL_H 0) - SET(HAVE_SYS_SELECT_H 0) - SET(HAVE_SYS_SOCKET_H 0) - SET(HAVE_SYS_SOCKIO_H 0) - SET(HAVE_SYS_STAT_H 1) - SET(HAVE_SYS_TIME_H 0) - SET(HAVE_SYS_TYPES_H 1) - SET(HAVE_SYS_UTIME_H 1) - SET(HAVE_TERMIOS_H 0) - SET(HAVE_TERMIO_H 0) - SET(HAVE_TIME_H 1) - SET(HAVE_UNISTD_H 0) - SET(HAVE_UTIME_H 0) - SET(HAVE_WINSOCK_H 1) - SET(HAVE_X509_H 0) - SET(HAVE_ZLIB_H 0) - - SET(HAVE_SIZEOF_LONG_DOUBLE 1) - SET(HAVE_SIZEOF_SSIZE_T 0) - SET(SIZEOF_LONG_DOUBLE 8) - - SET(HAVE_SOCKET 1) - SET(HAVE_POLL 0) - SET(HAVE_SELECT 1) - SET(HAVE_STRDUP 1) - SET(HAVE_STRSTR 1) - SET(HAVE_STRTOK_R 0) - SET(HAVE_STRFTIME 1) - SET(HAVE_UNAME 0) - SET(HAVE_STRCASECMP 0) - SET(HAVE_STRICMP 1) - SET(HAVE_STRCMPI 1) - SET(HAVE_GETHOSTBYADDR 1) - SET(HAVE_GETTIMEOFDAY 0) - SET(HAVE_INET_ADDR 1) - SET(HAVE_INET_NTOA 1) - SET(HAVE_INET_NTOA_R 0) - SET(HAVE_TCGETATTR 0) - SET(HAVE_TCSETATTR 0) - SET(HAVE_PERROR 1) - SET(HAVE_CLOSESOCKET 1) - SET(HAVE_SETVBUF 0) - SET(HAVE_SIGSETJMP 0) - SET(HAVE_GETPASS_R 0) - SET(HAVE_STRLCAT 0) - SET(HAVE_GETPWUID 0) - SET(HAVE_GETEUID 0) - SET(HAVE_UTIME 1) - SET(HAVE_RAND_EGD 0) - SET(HAVE_RAND_SCREEN 0) - SET(HAVE_RAND_STATUS 0) - SET(HAVE_GMTIME_R 0) - SET(HAVE_LOCALTIME_R 0) - SET(HAVE_GETHOSTBYADDR_R 0) - SET(HAVE_GETHOSTBYNAME_R 0) - SET(HAVE_SIGNAL_FUNC 1) - SET(HAVE_SIGNAL_MACRO 0) - - SET(HAVE_GETHOSTBYADDR_R_5 0) - SET(HAVE_GETHOSTBYADDR_R_5_REENTRANT 0) - SET(HAVE_GETHOSTBYADDR_R_7 0) - SET(HAVE_GETHOSTBYADDR_R_7_REENTRANT 0) - SET(HAVE_GETHOSTBYADDR_R_8 0) - SET(HAVE_GETHOSTBYADDR_R_8_REENTRANT 0) - SET(HAVE_GETHOSTBYNAME_R_3 0) - SET(HAVE_GETHOSTBYNAME_R_3_REENTRANT 0) - SET(HAVE_GETHOSTBYNAME_R_5 0) - SET(HAVE_GETHOSTBYNAME_R_5_REENTRANT 0) - SET(HAVE_GETHOSTBYNAME_R_6 0) - SET(HAVE_GETHOSTBYNAME_R_6_REENTRANT 0) - - SET(TIME_WITH_SYS_TIME 0) - SET(HAVE_O_NONBLOCK 0) - SET(HAVE_IN_ADDR_T 0) - SET(HAVE_SOCKLEN_T 0) - SET(HAVE_INET_NTOA_R_DECL 0) - SET(HAVE_INET_NTOA_R_DECL_REENTRANT 0) - SET(HAVE_GETADDRINFO 0) - SET(STDC_HEADERS 1) - SET(RETSIGTYPE_TEST 1) - - SET(HAVE_SIGACTION 0) - SET(HAVE_MACRO_SIGSETJMP 0) - ELSE(WIN32) - MESSAGE("This file should be included on Windows platform only") - ENDIF(WIN32) -ENDIF(NOT UNIX) - diff --git a/Source/CTest/Curl/Platforms/config-aix.h b/Source/CTest/Curl/Platforms/config-aix.h deleted file mode 100644 index 86d1093..0000000 --- a/Source/CTest/Curl/Platforms/config-aix.h +++ /dev/null @@ -1,486 +0,0 @@ -/* lib/config.h. Generated by configure. */ -/* lib/config.h.in. Generated from configure.in by autoheader. */ -/* Name of this package! */ -#define PACKAGE "curl" - -/* Version number of this archive. */ -#define VERSION "7.10.2" - -/* Define if you have the getpass function. */ -/* #undef HAVE_GETPASS */ - -/* Define cpu-machine-OS */ -#define OS "powerpc-ibm-aix5.1.0.0" - -/* Define if you have the gethostbyaddr_r() function with 5 arguments */ -#define HAVE_GETHOSTBYADDR_R_5 1 - -/* Define if you have the gethostbyaddr_r() function with 7 arguments */ -/* #undef HAVE_GETHOSTBYADDR_R_7 */ - -/* Define if you have the gethostbyaddr_r() function with 8 arguments */ -/* #undef HAVE_GETHOSTBYADDR_R_8 */ - -/* Define if you have the gethostbyname_r() function with 3 arguments */ -#define HAVE_GETHOSTBYNAME_R_3 1 - -/* Define if you have the gethostbyname_r() function with 5 arguments */ -/* #undef HAVE_GETHOSTBYNAME_R_5 */ - -/* Define if you have the gethostbyname_r() function with 6 arguments */ -/* #undef HAVE_GETHOSTBYNAME_R_6 */ - -/* Define if you have the inet_ntoa_r function declared. */ -/* #undef HAVE_INET_NTOA_R_DECL */ - -/* Define if you need the _REENTRANT define for some functions */ -/* #undef NEED_REENTRANT */ - -/* Define if you have the Kerberos4 libraries (including -ldes) */ -/* #undef KRB4 */ - -/* Define if you want to enable IPv6 support */ -#define ENABLE_IPV6 1 - -/* Define this to 'int' if ssize_t is not an available typedefed type */ -/* #undef ssize_t */ - -/* Define this to 'int' if socklen_t is not an available typedefed type */ -/* #undef socklen_t */ - -/* Define this as a suitable file to read random data from */ -/* #undef RANDOM_FILE */ - -/* Define this to your Entropy Gathering Daemon socket pathname */ -/* #undef EGD_SOCKET */ - -/* Define if you have a working OpenSSL installation */ -/* #undef OPENSSL_ENABLED */ - -/* Define the one correct non-blocking socket method below */ -/* #undef HAVE_FIONBIO */ -/* #undef HAVE_IOCTLSOCKET */ -/* #undef HAVE_IOCTLSOCKET_CASE */ -/* #undef HAVE_O_NONBLOCK */ -#define HAVE_DISABLED_NONBLOCKING 1 - -/* Define this to 'int' if in_addr_t is not an available typedefed type */ -/* #undef in_addr_t */ - -/* Define to disable DICT */ -/* #undef CURL_DISABLE_DICT */ - -/* Define to disable FILE */ -/* #undef CURL_DISABLE_FILE */ - -/* Define to disable FTP */ -/* #undef CURL_DISABLE_FTP */ - -/* Define to disable GOPHER */ -/* #undef CURL_DISABLE_GOPHER */ - -/* Define to disable HTTP */ -/* #undef CURL_DISABLE_HTTP */ - -/* Define to disable LDAP */ -/* #undef CURL_DISABLE_LDAP */ - -/* Define to disable TELNET */ -/* #undef CURL_DISABLE_TELNET */ - -/* Define if you have zlib present */ -#define HAVE_LIBZ 1 - -/* CA bundle full path name */ -#define CURL_CA_BUNDLE "/usr/local/share/curl/curl-ca-bundle.crt" - -/* to disable FILE */ -/* #undef CURL_DISABLE_FILE */ - -/* to disable FTP */ -/* #undef CURL_DISABLE_FTP */ - -/* to disable GOPHER */ -/* #undef CURL_DISABLE_GOPHER */ - -/* to disable HTTP */ -/* #undef CURL_DISABLE_HTTP */ - -/* to disable LDAP */ -/* #undef CURL_DISABLE_LDAP */ - -/* to disable TELNET */ -/* #undef CURL_DISABLE_TELNET */ - -/* Set to explicitly specify we don't want to use thread-safe functions */ -/* #undef DISABLED_THREADSAFE */ - -/* your Entropy Gathering Daemon socket pathname */ -/* #undef EGD_SOCKET */ - -/* Define if you want to enable IPv6 support */ -#define ENABLE_IPV6 1 - -/* Define to 1 if you have the <alloca.h> header file. */ -#define HAVE_ALLOCA_H 1 - -/* Define to 1 if you have the <arpa/inet.h> header file. */ -#define HAVE_ARPA_INET_H 1 - -/* Define to 1 if you have the `closesocket' function. */ -/* #undef HAVE_CLOSESOCKET */ - -/* Define to 1 if you have the <crypto.h> header file. */ -/* #undef HAVE_CRYPTO_H */ - -/* Define to 1 if you have the <des.h> header file. */ -/* #undef HAVE_DES_H */ - -/* to disable NON-BLOCKING connections */ -#define HAVE_DISABLED_NONBLOCKING 1 - -/* Define to 1 if you have the <dlfcn.h> header file. */ -#define HAVE_DLFCN_H 1 - -/* Define to 1 if you have the `dlopen' function. */ -#define HAVE_DLOPEN 1 - -/* Define to 1 if you have the <err.h> header file. */ -/* #undef HAVE_ERR_H */ - -/* Define to 1 if you have the <fcntl.h> header file. */ -#define HAVE_FCNTL_H 1 - -/* Define if getaddrinfo exists and works */ -#define HAVE_GETADDRINFO 1 - -/* Define to 1 if you have the `geteuid' function. */ -#define HAVE_GETEUID 1 - -/* Define to 1 if you have the `gethostbyaddr' function. */ -#define HAVE_GETHOSTBYADDR 1 - -/* Define to 1 if you have the `gethostbyaddr_r' function. */ -#define HAVE_GETHOSTBYADDR_R 1 - -/* Define to 1 if you have the `gethostbyname_r' function. */ -#define HAVE_GETHOSTBYNAME_R 1 - -/* Define to 1 if you have the `getpass_r' function. */ -/* #undef HAVE_GETPASS_R */ - -/* Define to 1 if you have the `getpwuid' function. */ -#define HAVE_GETPWUID 1 - -/* Define to 1 if you have the `gettimeofday' function. */ -#define HAVE_GETTIMEOFDAY 1 - -/* Define to 1 if you have the `gmtime_r' function. */ -#define HAVE_GMTIME_R 1 - -/* Define to 1 if you have the `inet_addr' function. */ -#define HAVE_INET_ADDR 1 - -/* Define to 1 if you have the `inet_ntoa' function. */ -#define HAVE_INET_NTOA 1 - -/* Define to 1 if you have the `inet_ntoa_r' function. */ -#define HAVE_INET_NTOA_R 1 - -/* Define to 1 if you have the <inttypes.h> header file. */ -#define HAVE_INTTYPES_H 1 - -/* Define to 1 if you have the <io.h> header file. */ -/* #undef HAVE_IO_H */ - -/* Define to 1 if you have the `krb_get_our_ip_for_realm' function. */ -/* #undef HAVE_KRB_GET_OUR_IP_FOR_REALM */ - -/* Define to 1 if you have the <krb.h> header file. */ -/* #undef HAVE_KRB_H */ - -/* Define to 1 if you have the `crypto' library (-lcrypto). */ -/* #undef HAVE_LIBCRYPTO */ - -/* Define to 1 if you have the `dl' library (-ldl). */ -/* #undef HAVE_LIBDL */ - -/* Define to 1 if you have the `nsl' library (-lnsl). */ -/* #undef HAVE_LIBNSL */ - -/* Define to 1 if you have the `resolv' library (-lresolv). */ -/* #undef HAVE_LIBRESOLV */ - -/* Define to 1 if you have the `resolve' library (-lresolve). */ -/* #undef HAVE_LIBRESOLVE */ - -/* Define to 1 if you have the `socket' library (-lsocket). */ -/* #undef HAVE_LIBSOCKET */ - -/* Define to 1 if you have the `ssl' library (-lssl). */ -/* #undef HAVE_LIBSSL */ - -/* If zlib is available */ -#define HAVE_LIBZ 1 - -/* Define to 1 if you have the `localtime_r' function. */ -#define HAVE_LOCALTIME_R 1 - -/* Define to 1 if you have the <malloc.h> header file. */ -#define HAVE_MALLOC_H 1 - -/* Define to 1 if you have the <memory.h> header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 if you have the <netdb.h> header file. */ -#define HAVE_NETDB_H 1 - -/* Define to 1 if you have the <netinet/if_ether.h> header file. */ -#define HAVE_NETINET_IF_ETHER_H 1 - -/* Define to 1 if you have the <netinet/in.h> header file. */ -#define HAVE_NETINET_IN_H 1 - -/* Define to 1 if you have the <net/if.h> header file. */ -#define HAVE_NET_IF_H 1 - -/* Define to 1 if you have the <openssl/crypto.h> header file. */ -/* #undef HAVE_OPENSSL_CRYPTO_H */ - -/* Define to 1 if you have the <openssl/engine.h> header file. */ -/* #undef HAVE_OPENSSL_ENGINE_H */ - -/* Define to 1 if you have the <openssl/err.h> header file. */ -/* #undef HAVE_OPENSSL_ERR_H */ - -/* Define to 1 if you have the <openssl/pem.h> header file. */ -/* #undef HAVE_OPENSSL_PEM_H */ - -/* Define to 1 if you have the <openssl/rsa.h> header file. */ -/* #undef HAVE_OPENSSL_RSA_H */ - -/* Define to 1 if you have the <openssl/ssl.h> header file. */ -/* #undef HAVE_OPENSSL_SSL_H */ - -/* Define to 1 if you have the <openssl/x509.h> header file. */ -/* #undef HAVE_OPENSSL_X509_H */ - -/* Define to 1 if you have the <pem.h> header file. */ -/* #undef HAVE_PEM_H */ - -/* Define to 1 if you have the `perror' function. */ -#define HAVE_PERROR 1 - -/* Define to 1 if you have the `poll' function. */ -#define HAVE_POLL 1 - -/* Define to 1 if you have the <pwd.h> header file. */ -#define HAVE_PWD_H 1 - -/* Define to 1 if you have the `RAND_egd' function. */ -/* #undef HAVE_RAND_EGD */ - -/* Define to 1 if you have the `RAND_screen' function. */ -/* #undef HAVE_RAND_SCREEN */ - -/* Define to 1 if you have the `RAND_status' function. */ -/* #undef HAVE_RAND_STATUS */ - -/* Define to 1 if you have the <rsa.h> header file. */ -/* #undef HAVE_RSA_H */ - -/* Define to 1 if you have the `select' function. */ -#define HAVE_SELECT 1 - -/* Define to 1 if you have the <setjmp.h> header file. */ -#define HAVE_SETJMP_H 1 - -/* Define to 1 if you have the `setvbuf' function. */ -#define HAVE_SETVBUF 1 - -/* Define to 1 if you have the <sgtty.h> header file. */ -#define HAVE_SGTTY_H 1 - -/* Define to 1 if you have the `sigaction' function. */ -#define HAVE_SIGACTION 1 - -/* Define to 1 if you have the `signal' function. */ -#define HAVE_SIGNAL 1 - -/* If you have sigsetjmp */ -#define HAVE_SIGSETJMP 1 - -/* Define to 1 if you have the `socket' function. */ -#define HAVE_SOCKET 1 - -/* Define to 1 if you have the <ssl.h> header file. */ -/* #undef HAVE_SSL_H */ - -/* Define to 1 if you have the <stdint.h> header file. */ -/* #undef HAVE_STDINT_H */ - -/* Define to 1 if you have the <stdlib.h> header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the `strcasecmp' function. */ -#define HAVE_STRCASECMP 1 - -/* Define to 1 if you have the `strcmpi' function. */ -/* #undef HAVE_STRCMPI */ - -/* Define to 1 if you have the `strdup' function. */ -#define HAVE_STRDUP 1 - -/* Define to 1 if you have the `strftime' function. */ -#define HAVE_STRFTIME 1 - -/* Define to 1 if you have the `stricmp' function. */ -/* #undef HAVE_STRICMP */ - -/* Define to 1 if you have the <strings.h> header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the <string.h> header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the `strlcat' function. */ -/* #undef HAVE_STRLCAT */ - -/* Define to 1 if you have the `strlcpy' function. */ -/* #undef HAVE_STRLCPY */ - -/* Define to 1 if you have the `strstr' function. */ -#define HAVE_STRSTR 1 - -/* Define to 1 if you have the `strtok_r' function. */ -#define HAVE_STRTOK_R 1 - -/* Define to 1 if you have the <sys/param.h> header file. */ -#define HAVE_SYS_PARAM_H 1 - -/* Define to 1 if you have the <sys/poll.h> header file. */ -#define HAVE_SYS_POLL_H 1 - -/* Define to 1 if you have the <sys/select.h> header file. */ -#define HAVE_SYS_SELECT_H 1 - -/* Define to 1 if you have the <sys/socket.h> header file. */ -#define HAVE_SYS_SOCKET_H 1 - -/* Define to 1 if you have the <sys/sockio.h> header file. */ -/* #undef HAVE_SYS_SOCKIO_H */ - -/* Define to 1 if you have the <sys/stat.h> header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the <sys/time.h> header file. */ -#define HAVE_SYS_TIME_H 1 - -/* Define to 1 if you have the <sys/types.h> header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the <sys/utime.h> header file. */ -/* #undef HAVE_SYS_UTIME_H */ - -/* Define to 1 if you have the `tcgetattr' function. */ -#define HAVE_TCGETATTR 1 - -/* Define to 1 if you have the `tcsetattr' function. */ -#define HAVE_TCSETATTR 1 - -/* Define to 1 if you have the <termios.h> header file. */ -#define HAVE_TERMIOS_H 1 - -/* Define to 1 if you have the <termio.h> header file. */ -#define HAVE_TERMIO_H 1 - -/* Define to 1 if you have the <time.h> header file. */ -#define HAVE_TIME_H 1 - -/* Define to 1 if you have the `uname' function. */ -#define HAVE_UNAME 1 - -/* Define to 1 if you have the <unistd.h> header file. */ -#define HAVE_UNISTD_H 1 - -/* Define to 1 if you have the `utime' function. */ -#define HAVE_UTIME 1 - -/* Define to 1 if you have the <utime.h> header file. */ -#define HAVE_UTIME_H 1 - -/* Define to 1 if you have the <winsock.h> header file. */ -/* #undef HAVE_WINSOCK_H */ - -/* Define to 1 if you have the <x509.h> header file. */ -/* #undef HAVE_X509_H */ - -/* if you have the zlib.h header file */ -/* #undef HAVE_ZLIB_H */ - -/* if you have the Kerberos4 libraries (including -ldes) */ -/* #undef KRB4 */ - -/* cpu-machine-OS */ -#define OS "powerpc-ibm-aix5.1.0.0" - -/* Name of package */ -#define PACKAGE "curl" - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "" - -/* a suitable file to read random data from */ -/* #undef RANDOM_FILE */ - -/* Define as the return type of signal handlers (`int' or `void'). */ -#define RETSIGTYPE void - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */ -#define TIME_WITH_SYS_TIME 1 - -/* Version number of package */ -#define VERSION "7.10.2" - -/* Define to 1 if on AIX 3. - System headers sometimes define this. - We just want to avoid a redefinition error message. */ -#ifndef _ALL_SOURCE -# define _ALL_SOURCE 1 -#endif - -/* Number of bits in a file offset, on hosts where this is settable. */ -/* #undef _FILE_OFFSET_BITS */ - -/* Define for large files, on AIX-style hosts. */ -#define _LARGE_FILES 1 - -/* Define to empty if `const' does not conform to ANSI C. */ -/* #undef const */ - -/* type to use in place of in_addr_t if not defined */ -/* #undef in_addr_t */ - -/* Define to `unsigned' if <sys/types.h> does not define. */ -/* #undef size_t */ - -/* type to use in place of socklen_t if not defined */ -/* #undef socklen_t */ - -/* Define to `int' if <sys/types.h> does not define. */ -/* #undef ssize_t */ diff --git a/Source/CTest/Curl/Testing/CMakeLists.txt b/Source/CTest/Curl/Testing/CMakeLists.txt deleted file mode 100644 index 214410f..0000000 --- a/Source/CTest/Curl/Testing/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -SET(CURL_TESTS - ftpget - ftpgetresp - ftpupload - getinmemory - persistant - sepheaders - simple - ) - -CONFIGURE_FILE(${LIBCURL_SOURCE_DIR}/Testing/testconfig.h.in - ${LIBCURL_BINARY_DIR}/Testing/testconfig.h) - -INCLUDE_DIRECTORIES(${LIBCURL_BINARY_DIR}/Testing) - -FOREACH(TEST ${CURL_TESTS}) - ADD_EXECUTABLE(${TEST} ${TEST}.c) - TARGET_LINK_LIBRARIES(${TEST} cmcurl) -ENDFOREACH(TEST) diff --git a/Source/CTest/Curl/Testing/curlgtk.c b/Source/CTest/Curl/Testing/curlgtk.c deleted file mode 100644 index 7c9ce2a..0000000 --- a/Source/CTest/Curl/Testing/curlgtk.c +++ /dev/null @@ -1,95 +0,0 @@ -/***************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * $Id$ - */ -/* Copyright (c) 2000 David Odin (aka DindinX) for MandrakeSoft */ -/* an attempt to use the curl library in concert with a gtk-threaded application */ - -#include <stdio.h> -#include <gtk/gtk.h> - -#include <curl/curl.h> -#include <curl/types.h> /* new for v7 */ -#include <curl/easy.h> /* new for v7 */ - -#include <pthread.h> - -GtkWidget *Bar; - -size_t my_read_func(void *ptr, size_t size, size_t nmemb, FILE *stream) -{ - return fread(ptr, size, nmemb, stream); -} - -int my_progress_func(GtkWidget *Bar, int t, int d) -{ -/* printf("%d / %d (%g %%)\n", d, t, d*100.0/t);*/ - gdk_threads_enter(); - gtk_progress_set_value(GTK_PROGRESS(Bar), d*100.0/t); - gdk_threads_leave(); - return 0; -} - -void *curl_thread(void *ptr) -{ - CURL *curl; - CURLcode res; - FILE *outfile; - gchar *url = ptr; - - curl = curl_easy_init(); - if(curl) - { - outfile = fopen("/tmp/test.curl", "w"); - - curl_easy_setopt(curl, CURLOPT_URL, url); - curl_easy_setopt(curl, CURLOPT_FILE, outfile); - curl_easy_setopt(curl, CURLOPT_READFUNCTION, my_read_func); - curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, my_progress_func); - curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, Bar); - - res = curl_easy_perform(curl); - - fclose(outfile); - /* always cleanup */ - curl_easy_cleanup(curl); - } - return NULL; -} - -int main(int argc, char **argv) -{ - GtkWidget *Window, *Frame, *Frame2; - GtkAdjustment *adj; - pthread_t curl_tid; - - /* Init thread */ - g_thread_init(NULL); - - gtk_init(&argc, &argv); - Window = gtk_window_new(GTK_WINDOW_TOPLEVEL); - Frame = gtk_frame_new(NULL); - gtk_frame_set_shadow_type(GTK_FRAME(Frame), GTK_SHADOW_OUT); - gtk_container_add(GTK_CONTAINER(Window), Frame); - Frame2 = gtk_frame_new(NULL); - gtk_frame_set_shadow_type(GTK_FRAME(Frame2), GTK_SHADOW_IN); - gtk_container_add(GTK_CONTAINER(Frame), Frame2); - gtk_container_set_border_width(GTK_CONTAINER(Frame2), 5); - adj = (GtkAdjustment*)gtk_adjustment_new(0, 0, 100, 0, 0, 0); - Bar = gtk_progress_bar_new_with_adjustment(adj); - gtk_container_add(GTK_CONTAINER(Frame2), Bar); - gtk_widget_show_all(Window); - - pthread_create(&curl_tid, NULL, curl_thread, argv[1]); - - gdk_threads_enter(); - gtk_main(); - gdk_threads_leave(); - return 0; -} - diff --git a/Source/CTest/Curl/Testing/curltest.c b/Source/CTest/Curl/Testing/curltest.c deleted file mode 100644 index c21774a..0000000 --- a/Source/CTest/Curl/Testing/curltest.c +++ /dev/null @@ -1,143 +0,0 @@ -/* Prevent warnings on Visual Studio */ -struct _RPC_ASYNC_STATE; - -#include "curl/curl.h" -#include <stdlib.h> -#include <string.h> - -int GetFtpFile(void) -{ - int retVal = 0; - CURL *curl; - CURLcode res; - curl = curl_easy_init(); - if(curl) - { - /* Get curl 7.9.2 from sunet.se's FTP site: */ - curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); - curl_easy_setopt(curl, CURLOPT_HEADER, 1); - curl_easy_setopt(curl, CURLOPT_URL, - "ftp://public.kitware.com/pub/cmake/cygwin/setup.hint"); - res = curl_easy_perform(curl); - if ( res != 0 ) - { - printf("Error fetching: ftp://public.kitware.com/pub/cmake/cygwin/setup.hint\n"); - retVal = 1; - } - - /* always cleanup */ - curl_easy_cleanup(curl); - } - else - { - printf("Cannot create curl object\n"); - retVal = 1; - } - return retVal; -} - -int GetWebFile(void) -{ - int retVal = 0; - CURL *curl; - CURLcode res; - - char proxy[1024]; - int proxy_type = 0; - - if ( getenv("HTTP_PROXY") ) - { - proxy_type = 1; - if (getenv("HTTP_PROXY_PORT") ) - { - sprintf(proxy, "%s:%s", getenv("HTTP_PROXY"), getenv("HTTP_PROXY_PORT")); - } - else - { - sprintf(proxy, "%s", getenv("HTTP_PROXY")); - } - if ( getenv("HTTP_PROXY_TYPE") ) - { - /* HTTP/SOCKS4/SOCKS5 */ - if ( strcmp(getenv("HTTP_PROXY_TYPE"), "HTTP") == 0 ) - { - proxy_type = 1; - } - else if ( strcmp(getenv("HTTP_PROXY_TYPE"), "SOCKS4") == 0 ) - { - proxy_type = 2; - } - else if ( strcmp(getenv("HTTP_PROXY_TYPE"), "SOCKS5") == 0 ) - { - proxy_type = 3; - } - } - } - - curl = curl_easy_init(); - if(curl) - { - curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); - curl_easy_setopt(curl, CURLOPT_HEADER, 1); - - /* Using proxy */ - if ( proxy_type > 0 ) - { - curl_easy_setopt(curl, CURLOPT_PROXY, proxy); - switch (proxy_type) - { - case 2: - curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS4); - break; - case 3: - curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5); - break; - default: - curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_HTTP); - } - } - - /* get the first document */ - curl_easy_setopt(curl, CURLOPT_URL, "http://www.cmake.org/page1.html"); - res = curl_easy_perform(curl); - if ( res != 0 ) - { - printf("Error fetching: http://www.cmake.org/page1.html\n"); - retVal = 1; - } - - /* get another document from the same server using the same - connection */ - /* - curl_easy_setopt(curl, CURLOPT_URL, "http://www.cmake.org/page2.html"); - res = curl_easy_perform(curl); - if ( res != 0 ) - { - printf("Error fetching: http://www.cmake.org/page2.html\n"); - retVal = 1; - } - */ - - /* always cleanup */ - curl_easy_cleanup(curl); - } - else - { - printf("Cannot create curl object\n"); - retVal = 1; - } - - return retVal; -} - -int main(/*int argc, char **argv*/) -{ - int retVal = 0; - curl_global_init(CURL_GLOBAL_DEFAULT); - retVal += GetWebFile(); - - /* Do not check the output of FTP socks5 cannot handle FTP yet */ - GetFtpFile(); - curl_global_cleanup(); - return retVal; -} diff --git a/Source/CTest/Curl/Testing/ftpget.c b/Source/CTest/Curl/Testing/ftpget.c deleted file mode 100644 index db3edfb..0000000 --- a/Source/CTest/Curl/Testing/ftpget.c +++ /dev/null @@ -1,83 +0,0 @@ -/***************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * $Id$ - */ - -#include "curl/curl.h" -#include "curl/types.h" -#include "curl/easy.h" - -#include "testconfig.h" - -/* - * This is an example showing how to get a single file from an FTP server. - * It delays the actual destination file creation until the first write - * callback so that it won't create an empty file in case the remote file - * doesn't exist or something else fails. - */ - -struct FtpFile { - char *filename; - FILE *stream; -}; - -int my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream) -{ - struct FtpFile *out=(struct FtpFile *)stream; - if(out && !out->stream) { - /* open file for writing */ - out->stream=fopen(out->filename, "wb"); - if(!out->stream) - return -1; /* failure, can't open file to write */ - } - return fwrite(buffer, size, nmemb, out->stream); -} - - -int main(void) -{ - CURL *curl; - CURLcode res; - struct FtpFile ftpfile={ - LIBCURL_BINARY_DIR "/Testing/ftpget-download.txt", /* name to store the file as if succesful */ - NULL - }; - - curl_global_init(CURL_GLOBAL_DEFAULT); - - curl = curl_easy_init(); - if(curl) { - /* Get curl 7.9.2 from sunet.se's FTP site: */ - curl_easy_setopt(curl, CURLOPT_URL, - "ftp://public.kitware.com/pub/cmake/cygwin/setup.hint"); - /* Define our callback to get called when there's data to be written */ - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite); - /* Set a pointer to our struct to pass to the callback */ - curl_easy_setopt(curl, CURLOPT_FILE, &ftpfile); - - /* Switch on full protocol/debug output */ - curl_easy_setopt(curl, CURLOPT_VERBOSE, TRUE); - - res = curl_easy_perform(curl); - - /* always cleanup */ - curl_easy_cleanup(curl); - - if(CURLE_OK != res) { - /* we failed */ - fprintf(stderr, "curl told us %d\n", res); - } - } - - if(ftpfile.stream) - fclose(ftpfile.stream); /* close the local file */ - - curl_global_cleanup(); - - return 0; -} diff --git a/Source/CTest/Curl/Testing/ftpgetresp.c b/Source/CTest/Curl/Testing/ftpgetresp.c deleted file mode 100644 index d3f5d42..0000000 --- a/Source/CTest/Curl/Testing/ftpgetresp.c +++ /dev/null @@ -1,63 +0,0 @@ -/***************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * $Id$ - */ - -#include "curl/curl.h" -#include "curl/types.h" -#include "curl/easy.h" - -#include "testconfig.h" - -/* - * Similar to ftpget.c but this also stores the received response-lines - * in a separate file using our own callback! - * - * This functionality was introduced in libcurl 7.9.3. - */ - -size_t -write_response(void *ptr, size_t size, size_t nmemb, void *data) -{ - FILE *writehere = (FILE *)data; - return fwrite(ptr, size, nmemb, writehere); -} - -int main(int argc, char **argv) -{ - CURL *curl; - CURLcode res; - FILE *ftpfile; - FILE *respfile; - - /* local file name to store the file as */ - ftpfile = fopen(LIBCURL_BINARY_DIR "/Testing/ftpgetresp-list.txt", "wb"); /* b is binary, needed on win32 */ - - /* local file name to store the FTP server's response lines in */ - respfile = fopen(LIBCURL_BINARY_DIR "/Testing/ftpgetresp-responses.txt", "wb"); /* b is binary, needed on win32 */ - - curl_global_init(CURL_GLOBAL_DEFAULT); - - curl = curl_easy_init(); - if(curl) { - /* Get a file listing from sunet */ - curl_easy_setopt(curl, CURLOPT_URL, "ftp://public.kitware.com/"); - curl_easy_setopt(curl, CURLOPT_FILE, ftpfile); - curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, write_response); - curl_easy_setopt(curl, CURLOPT_WRITEHEADER, respfile); - res = curl_easy_perform(curl); - - /* always cleanup */ - curl_easy_cleanup(curl); - } - - fclose(ftpfile); /* close the local file */ - fclose(respfile); /* close the response file */ - - return 0; -} diff --git a/Source/CTest/Curl/Testing/ftpupload.c b/Source/CTest/Curl/Testing/ftpupload.c deleted file mode 100644 index bca0a56..0000000 --- a/Source/CTest/Curl/Testing/ftpupload.c +++ /dev/null @@ -1,92 +0,0 @@ -/***************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * $Id$ - */ - -#include "curl/curl.h" - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> - -#include "testconfig.h" - -/* - * This example shows an FTP upload, with a rename of the file just after - * a successful upload. - * - * Example based on source code provided by Erick Nuwendam. Thanks! - */ - -#define LOCAL_FILE LIBCURL_SOURCE_DIR "/Testing/ftpupload.c" -#define UPLOAD_FILE_AS "while-uploading.txt" -#define REMOTE_URL "ftp://public.kitware.com/incoming/" UPLOAD_FILE_AS -#define RENAME_FILE_TO "renamed-and-fine.txt" - -int main(int argc, char **argv) -{ - CURL *curl; - CURLcode res; - FILE *ftpfile; - FILE * hd_src ; - int hd ; - struct stat file_info; - - struct curl_slist *headerlist=NULL; - char buf_1 [] = "RNFR " UPLOAD_FILE_AS; - char buf_2 [] = "RNTO " RENAME_FILE_TO; - - /* get the file size of the local file */ - hd = open(LOCAL_FILE, O_RDONLY) ; - fstat(hd, &file_info); - close(hd) ; - - /* get a FILE * of the same file, could also be made with - fdopen() from the previous descriptor, but hey this is just - an example! */ - hd_src = fopen(LOCAL_FILE, "rb"); - - /* In windows, this will init the winsock stuff */ - curl_global_init(CURL_GLOBAL_ALL); - - /* get a curl handle */ - curl = curl_easy_init(); - if(curl) { - /* build a list of commands to pass to libcurl */ - headerlist = curl_slist_append(headerlist, buf_1); - headerlist = curl_slist_append(headerlist, buf_2); - - /* enable uploading */ - curl_easy_setopt(curl, CURLOPT_UPLOAD, TRUE) ; - - /* specify target */ - curl_easy_setopt(curl,CURLOPT_URL, REMOTE_URL); - - /* pass in that last of FTP commands to run after the transfer */ - curl_easy_setopt(curl, CURLOPT_POSTQUOTE, headerlist); - - /* now specify which file to upload */ - curl_easy_setopt(curl, CURLOPT_INFILE, hd_src); - - /* and give the size of the upload (optional) */ - curl_easy_setopt(curl, CURLOPT_INFILESIZE, (long)file_info.st_size); - - /* Now run off and do what you've been told! */ - res = curl_easy_perform(curl); - - /* clean up the FTP commands list */ - curl_slist_free_all (headerlist); - - /* always cleanup */ - curl_easy_cleanup(curl); - } - fclose(hd_src); /* close the local file */ - - curl_global_cleanup(); - return 0; -} diff --git a/Source/CTest/Curl/Testing/getinmemory.c b/Source/CTest/Curl/Testing/getinmemory.c deleted file mode 100644 index a8872da..0000000 --- a/Source/CTest/Curl/Testing/getinmemory.c +++ /dev/null @@ -1,83 +0,0 @@ -/***************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * $Id$ - * - * Example source code to show how the callback function can be used to - * download data into a chunk of memory instead of storing it in a file. - * - * This exact source code has not been verified to work. - */ - -/* to make this work under windows, use the win32-functions from the - win32socket.c file as well */ - -#include "curl/curl.h" -#include "curl/types.h" -#include "curl/easy.h" - -struct MemoryStruct { - char *memory; - size_t size; -}; - -size_t -WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data) -{ - register int realsize = size * nmemb; - struct MemoryStruct *mem = (struct MemoryStruct *)data; - - mem->memory = (char *)realloc(mem->memory, mem->size + realsize + 1); - if (mem->memory) { - memcpy(&(mem->memory[mem->size]), ptr, realsize); - mem->size += realsize; - mem->memory[mem->size] = 0; - } - return realsize; -} - -int main(int argc, char **argv) -{ - CURL *curl_handle; - - struct MemoryStruct chunk; - - chunk.memory=NULL; /* we expect realloc(NULL, size) to work */ - chunk.size = 0; /* no data at this point */ - - curl_global_init(CURL_GLOBAL_DEFAULT); - - /* init the curl session */ - curl_handle = curl_easy_init(); - - /* specify URL to get */ - curl_easy_setopt(curl_handle, CURLOPT_URL, "http://www.cmake.org/HTML/Index.html"); - - /* send all data to this function */ - curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); - - /* we pass our 'chunk' struct to the callback function */ - curl_easy_setopt(curl_handle, CURLOPT_FILE, (void *)&chunk); - - /* get it! */ - curl_easy_perform(curl_handle); - - /* cleanup curl stuff */ - curl_easy_cleanup(curl_handle); - - /* - * Now, our chunk.memory points to a memory block that is chunk.size - * bytes big and contains the remote file. - * - * Do something nice with it! - */ - - /* For example display it... */ - write(1, chunk.memory, chunk.size); - - return 0; -} diff --git a/Source/CTest/Curl/Testing/http-post.c b/Source/CTest/Curl/Testing/http-post.c deleted file mode 100644 index 1b4154f..0000000 --- a/Source/CTest/Curl/Testing/http-post.c +++ /dev/null @@ -1,35 +0,0 @@ -/***************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * $Id$ - */ - -#include <stdio.h> -#include <curl/curl.h> - -int main(void) -{ - CURL *curl; - CURLcode res; - - curl = curl_easy_init(); - if(curl) { - /* First set the URL that is about to receive our POST. This URL can - just as well be a https:// URL if that is what should receive the - data. */ - curl_easy_setopt(curl, CURLOPT_URL, "http://postit.example.com/moo.cgi"); - /* Now specify the POST data */ - curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "name=daniel&project=curl"); - - /* Perform the request, res will get the return code */ - res = curl_easy_perform(curl); - - /* always cleanup */ - curl_easy_cleanup(curl); - } - return 0; -} diff --git a/Source/CTest/Curl/Testing/httpput.c b/Source/CTest/Curl/Testing/httpput.c deleted file mode 100644 index 78275c4..0000000 --- a/Source/CTest/Curl/Testing/httpput.c +++ /dev/null @@ -1,100 +0,0 @@ -/***************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * $Id$ - */ - -#include <stdio.h> -#include <fcntl.h> -#include <sys/stat.h> - -#include <curl/curl.h> - -/* - * This example shows a HTTP PUT operation. PUTs a file given as a command - * line argument to the URL also given on the command line. - * - * This example also uses its own read callback. - */ - -size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream) -{ - size_t retcode; - - /* in real-world cases, this would probably get this data differently - as this fread() stuff is exactly what the library already would do - by default internally */ - retcode = fread(ptr, size, nmemb, stream); - - fprintf(stderr, "*** We read %d bytes from file\n", retcode); - - return retcode; -} - -int main(int argc, char **argv) -{ - CURL *curl; - CURLcode res; - FILE *ftpfile; - FILE * hd_src ; - int hd ; - struct stat file_info; - - char *file; - char *url; - - if(argc < 3) - return 1; - - file= argv[1]; - url = argv[2]; - - /* get the file size of the local file */ - hd = open(file, O_RDONLY) ; - fstat(hd, &file_info); - close(hd) ; - - /* get a FILE * of the same file, could also be made with - fdopen() from the previous descriptor, but hey this is just - an example! */ - hd_src = fopen(file, "rb"); - - /* In windows, this will init the winsock stuff */ - curl_global_init(CURL_GLOBAL_ALL); - - /* get a curl handle */ - curl = curl_easy_init(); - if(curl) { - /* we want to use our own read function */ - curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback); - - /* enable uploading */ - curl_easy_setopt(curl, CURLOPT_UPLOAD, TRUE) ; - - /* HTTP PUT please */ - curl_easy_setopt(curl, CURLOPT_PUT, TRUE); - - /* specify target */ - curl_easy_setopt(curl,CURLOPT_URL, url); - - /* now specify which file to upload */ - curl_easy_setopt(curl, CURLOPT_INFILE, hd_src); - - /* and give the size of the upload (optional) */ - curl_easy_setopt(curl, CURLOPT_INFILESIZE, file_info.st_size); - - /* Now run off and do what you've been told! */ - res = curl_easy_perform(curl); - - /* always cleanup */ - curl_easy_cleanup(curl); - } - fclose(hd_src); /* close the local file */ - - curl_global_cleanup(); - return 0; -} diff --git a/Source/CTest/Curl/Testing/multithread.c b/Source/CTest/Curl/Testing/multithread.c deleted file mode 100644 index c3936ef..0000000 --- a/Source/CTest/Curl/Testing/multithread.c +++ /dev/null @@ -1,70 +0,0 @@ -/***************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * $Id$ - */ - -/* A multi-threaded example that uses pthreads extensively to fetch - * X remote files at once */ - -#include <stdio.h> -#include <pthread.h> -#include <curl/curl.h> - -/* silly list of test-URLs */ -char *urls[]= { - "http://curl.haxx.se/", - "ftp://cool.haxx.se/", - "http://www.contactor.se/", - "www.haxx.se" -}; - -void *pull_one_url(void *url) -{ - CURL *curl; - - curl = curl_easy_init(); - - curl_easy_setopt(curl, CURLOPT_URL, url); - curl_easy_perform(curl); - - curl_easy_cleanup(curl); - - return NULL; -} - - -/* - int pthread_create(pthread_t *new_thread_ID, - const pthread_attr_t *attr, - void * (*start_func)(void *), void *arg); -*/ - -int main(int argc, char **argv) -{ - pthread_t tid[4]; - int i; - int error; - for(i=0; i< 4; i++) { - error = pthread_create(&tid[i], - NULL, /* default attributes please */ - pull_one_url, - urls[i]); - if(0 != error) - fprintf(stderr, "Couldn't run thread number %d, errno %d\n", i, error); - else - fprintf(stderr, "Thread %d, gets %s\n", i, urls[i]); - } - - /* now wait for all threads to terminate */ - for(i=0; i< 4; i++) { - error = pthread_join(tid[i], NULL); - fprintf(stderr, "Thread %d terminated\n", i); - } - - return 0; -} diff --git a/Source/CTest/Curl/Testing/persistant.c b/Source/CTest/Curl/Testing/persistant.c deleted file mode 100644 index 8534703..0000000 --- a/Source/CTest/Curl/Testing/persistant.c +++ /dev/null @@ -1,53 +0,0 @@ -/***************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * $Id$ - */ - -#include <stdio.h> - -#include "curl/curl.h" - -/* to make this work under windows, use the win32-functions from the - docs/examples/win32socket.c file as well */ - -/* This example REQUIRES libcurl 7.7 or later */ -#if (LIBCURL_VERSION_NUM < 0x070700) -#error Too old libcurl version, upgrade or stay away. -#endif - -int main(int argc, char **argv) -{ - CURL *curl; - CURLcode res; - -#ifdef MALLOCDEBUG - /* this sends all memory debug messages to a specified logfile */ - curl_memdebug("memdump"); -#endif - - curl_global_init(CURL_GLOBAL_DEFAULT); - curl = curl_easy_init(); - if(curl) { - curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); - curl_easy_setopt(curl, CURLOPT_HEADER, 1); - - /* get the first document */ - curl_easy_setopt(curl, CURLOPT_URL, "http://www.cmake.org/"); - res = curl_easy_perform(curl); - - /* get another document from the same server using the same - connection */ - curl_easy_setopt(curl, CURLOPT_URL, "http://www.cmake.org/HTML/Index.html"); - res = curl_easy_perform(curl); - - /* always cleanup */ - curl_easy_cleanup(curl); - } - - return 0; -} diff --git a/Source/CTest/Curl/Testing/postit2.c b/Source/CTest/Curl/Testing/postit2.c deleted file mode 100644 index 9b7cda0..0000000 --- a/Source/CTest/Curl/Testing/postit2.c +++ /dev/null @@ -1,92 +0,0 @@ -/***************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * $Id$ - * - * Example code that uploads a file name 'foo' to a remote script that accepts - * "HTML form based" (as described in RFC1738) uploads using HTTP POST. - * - * The imaginary form we'll fill in looks like: - * - * <form method="post" enctype="multipart/form-data" action="examplepost.cgi"> - * Enter file: <input type="file" name="sendfile" size="40"> - * Enter file name: <input type="text" name="filename" size="30"> - * <input type="submit" value="send" name="submit"> - * </form> - * - * This exact source code has not been verified to work. - */ - -/* to make this work under windows, use the win32-functions from the - win32socket.c file as well */ - -#include <stdio.h> -#include <string.h> - -#include <curl/curl.h> -#include <curl/types.h> -#include <curl/easy.h> - -#if LIBCURL_VERSION_NUM < 0x070900 -#error "curl_formadd() is not introduced until libcurl 7.9 and later" -#endif - -int main(int argc, char *argv[]) -{ - CURL *curl; - CURLcode res; - - struct HttpPost *formpost=NULL; - struct HttpPost *lastptr=NULL; - struct curl_slist *headerlist=NULL; - char buf[] = "Expect:"; - - /* Fill in the file upload field */ - curl_formadd(&formpost, - &lastptr, - CURLFORM_COPYNAME, "sendfile", - CURLFORM_FILE, "postit2.c", - CURLFORM_END); - - /* Fill in the filename field */ - curl_formadd(&formpost, - &lastptr, - CURLFORM_COPYNAME, "filename", - CURLFORM_COPYCONTENTS, "postit2.c", - CURLFORM_END); - - - /* Fill in the submit field too, even if this is rarely needed */ - curl_formadd(&formpost, - &lastptr, - CURLFORM_COPYNAME, "submit", - CURLFORM_COPYCONTENTS, "send", - CURLFORM_END); - - curl = curl_easy_init(); - /* initalize custom header list (stating that Expect: 100-continue is not - wanted */ - headerlist = curl_slist_append(headerlist, buf); - if(curl) { - /* what URL that receives this POST */ - curl_easy_setopt(curl, CURLOPT_URL, "http://curl.haxx.se/examplepost.cgi"); - if ( (argc == 2) && (!strcmp(argv[1], "noexpectheader")) ) - /* only disable 100-continue header if explicitly requested */ - curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist); - curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost); - res = curl_easy_perform(curl); - - /* always cleanup */ - curl_easy_cleanup(curl); - - /* then cleanup the formpost chain */ - curl_formfree(formpost); - /* free slist */ - curl_slist_free_all (headerlist); - } - return 0; -} diff --git a/Source/CTest/Curl/Testing/sepheaders.c b/Source/CTest/Curl/Testing/sepheaders.c deleted file mode 100644 index e3ea7be..0000000 --- a/Source/CTest/Curl/Testing/sepheaders.c +++ /dev/null @@ -1,78 +0,0 @@ -/***************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * $Id$ - */ - -/* to make this work under windows, use the win32-functions from the - win32socket.c file as well */ - -#include "curl/curl.h" -#include "curl/types.h" -#include "curl/easy.h" - -#include "testconfig.h" - -size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream) -{ - int written = fwrite(ptr, size, nmemb, (FILE *)stream); - return written; -} - -int main(int argc, char **argv) -{ - CURL *curl_handle; - char *headerfilename = LIBCURL_BINARY_DIR "/Testing/sepheaders-head.out"; - FILE *headerfile; - char *bodyfilename = LIBCURL_BINARY_DIR "/Testing/sepheaders-body.out"; - FILE *bodyfile; - - curl_global_init(CURL_GLOBAL_DEFAULT); - /* init the curl session */ - curl_handle = curl_easy_init(); - - /* set URL to get */ - curl_easy_setopt(curl_handle, CURLOPT_URL, "http://www.cmake.org/HTML/Index.html"); - - /* no progress meter please */ - curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 1); - - /* shut up completely */ - curl_easy_setopt(curl_handle, CURLOPT_MUTE, 1); - - /* send all data to this function */ - curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_data); - - /* open the files */ - headerfile = fopen(headerfilename,"w"); - if (headerfile == NULL) { - curl_easy_cleanup(curl_handle); - return -1; - } - bodyfile = fopen(bodyfilename,"w"); - if (bodyfile == NULL) { - curl_easy_cleanup(curl_handle); - return -1; - } - - /* we want the headers to this file handle */ - curl_easy_setopt(curl_handle, CURLOPT_WRITEHEADER ,headerfile); - - /* we want the body to this file handle */ - curl_easy_setopt(curl_handle, CURLOPT_FILE ,bodyfile); - - /* get it! */ - curl_easy_perform(curl_handle); - - /* close the header file */ - fclose(headerfile); - - /* cleanup curl stuff */ - curl_easy_cleanup(curl_handle); - - return 0; -} diff --git a/Source/CTest/Curl/Testing/simple.c b/Source/CTest/Curl/Testing/simple.c deleted file mode 100644 index 6dd6050..0000000 --- a/Source/CTest/Curl/Testing/simple.c +++ /dev/null @@ -1,28 +0,0 @@ -/***************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * $Id$ - */ - -#include "curl/curl.h" - -int main(void) -{ - CURL *curl; - CURLcode res; - - curl_global_init(CURL_GLOBAL_DEFAULT); - curl = curl_easy_init(); - if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "http://www.cmake.org/HTML/Index.html"); - res = curl_easy_perform(curl); - - /* always cleanup */ - curl_easy_cleanup(curl); - } - return 0; -} diff --git a/Source/CTest/Curl/Testing/simplessl.c b/Source/CTest/Curl/Testing/simplessl.c deleted file mode 100644 index 9a53603..0000000 --- a/Source/CTest/Curl/Testing/simplessl.c +++ /dev/null @@ -1,118 +0,0 @@ -/***************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * $Id$ - */ - -#include <stdio.h> - -#include <curl/curl.h> -#include <curl/types.h> -#include <curl/easy.h> - - -/* some requirements for this to work: - 1. set pCertFile to the file with the client certificate - 2. if the key is passphrase protected, set pPassphrase to the - passphrase you use - 3. if you are using a crypto engine: - 3.1. set a #define USE_ENGINE - 3.2. set pEngine to the name of the crypto engine you use - 3.3. set pKeyName to the key identifier you want to use - 4. if you don't use a crypto engine: - 4.1. set pKeyName to the file name of your client key - 4.2. if the format of the key file is DER, set pKeyType to "DER" - - !! verify of the server certificate is not implemented here !! - - **** This example only works with libcurl 7.9.3 and later! **** - -*/ - -int main(int argc, char **argv) -{ - CURL *curl; - CURLcode res; - FILE *headerfile; - - const char *pCertFile = "testcert.pem"; - const char *pCACertFile="cacert.pem" - - const char *pKeyName; - const char *pKeyType; - - const char *pEngine; - -#if USE_ENGINE - pKeyName = "rsa_test"; - pKeyType = "ENG"; - pEngine = "chil"; /* for nChiper HSM... */ -#else - pKeyName = "testkey.pem"; - pKeyType = "PEM"; - pEngine = NULL; -#endif - - const char *pPassphrase = NULL; - - headerfile = fopen("dumpit", "w"); - - curl_global_init(CURL_GLOBAL_DEFAULT); - - curl = curl_easy_init(); - if(curl) { - /* what call to write: */ - curl_easy_setopt(curl, CURLOPT_URL, "HTTPS://curl.haxx.se"); - curl_easy_setopt(curl, CURLOPT_WRITEHEADER, headerfile); - - while(1) /* do some ugly short cut... */ - { - if (pEngine) /* use crypto engine */ - { - if (curl_easy_setopt(curl, CURLOPT_SSLENGINE,pEngine) != CURLE_OK) - { /* load the crypto engine */ - fprintf(stderr,"can't set crypto engine\n"); - break; - } - if (curl_easy_setopt(curl, CURLOPT_SSLENGINE_DEFAULT,1) != CURLE_OK) - { /* set the crypto engine as default */ - /* only needed for the first time you load - a engine in a curl object... */ - fprintf(stderr,"can't set crypto engine as default\n"); - break; - } - } - /* cert is stored PEM coded in file... */ - /* since PEM is default, we needn't set it for PEM */ - curl_easy_setopt(curl,CURLOPT_SSLCERTTYPE,"PEM"); - /* set the cert for client authentication */ - curl_easy_setopt(curl,CURLOPT_SSLCERT,pCertFile); - /* sorry, for engine we must set the passphrase - (if the key has one...) */ - if (pPassphrase) - curl_easy_setopt(curl,CURLOPT_SSLKEYPASSWD,pPassphrase); - /* if we use a key stored in a crypto engine, - we must set the key type to "ENG" */ - curl_easy_setopt(curl,CURLOPT_SSLKEYTYPE,pKeyType); - /* set the private key (file or ID in engine) */ - curl_easy_setopt(curl,CURLOPT_SSLKEY,pKeyName); - /* set the file with the certs vaildating the server */ - curl_easy_setopt(curl,CURLOPT_CAINFO,pCACertFile); - /* disconnect if we can't validate server's cert */ - curl_easy_setopt(curl,CURLOPT_SSL_VERIFYPEER,1); - - res = curl_easy_perform(curl); - break; /* we are done... */ - } - /* always cleanup */ - curl_easy_cleanup(curl); - } - - curl_global_cleanup(); - - return 0; -} diff --git a/Source/CTest/Curl/Testing/testconfig.h.in b/Source/CTest/Curl/Testing/testconfig.h.in deleted file mode 100644 index faab462..0000000 --- a/Source/CTest/Curl/Testing/testconfig.h.in +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __testconfig_h__ -#define __testconfig_h__ - -#define LIBCURL_SOURCE_DIR "${LIBCURL_SOURCE_DIR}" -#define LIBCURL_BINARY_DIR "${LIBCURL_BINARY_DIR}" - -#endif /* __testconfig_h__ */ diff --git a/Source/CTest/Curl/Testing/win32sockets.c b/Source/CTest/Curl/Testing/win32sockets.c deleted file mode 100644 index 5f791c8..0000000 --- a/Source/CTest/Curl/Testing/win32sockets.c +++ /dev/null @@ -1,49 +0,0 @@ - -/* - * Note: This is only required if you use curl 7.8 or lower, later - * versions provide an option to curl_global_init() that does the - * win32 initialization for you. - */ - -/* - * These are example functions doing socket init that Windows - * require. If you don't use windows, you can safely ignore this crap. - */ - -#include <windows.h> - -void win32_cleanup(void) -{ - WSACleanup(); -} - -int win32_init(void) -{ - WORD wVersionRequested; - WSADATA wsaData; - int err; - wVersionRequested = MAKEWORD(1, 1); - - err = WSAStartup(wVersionRequested, &wsaData); - - if (err != 0) - /* Tell the user that we couldn't find a useable */ - /* winsock.dll. */ - return 1; - - /* Confirm that the Windows Sockets DLL supports 1.1.*/ - /* Note that if the DLL supports versions greater */ - /* than 1.1 in addition to 1.1, it will still return */ - /* 1.1 in wVersion since that is the version we */ - /* requested. */ - - if ( LOBYTE( wsaData.wVersion ) != 1 || - HIBYTE( wsaData.wVersion ) != 1 ) { - /* Tell the user that we couldn't find a useable */ - - /* winsock.dll. */ - WSACleanup(); - return 1; - } - return 0; /* 0 is ok */ -} diff --git a/Source/CTest/Curl/amigaos.c b/Source/CTest/Curl/amigaos.c deleted file mode 100644 index 16a7d5e..0000000 --- a/Source/CTest/Curl/amigaos.c +++ /dev/null @@ -1,49 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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 "amigaos.h" -#include <stdio.h> /* for stderr */ - -struct Library *SocketBase = NULL; - -void amiga_cleanup() -{ - if(SocketBase) - CloseLibrary(SocketBase); - - SocketBase = NULL; -} - -BOOL amiga_init() -{ - if(!SocketBase) - SocketBase = OpenLibrary("bsdsocket.library", 4); - - if(!SocketBase) { - fprintf(stderr, "No TCP/IP Stack running!\n\a"); - return FALSE; - } - - atexit(amiga_cleanup); - return TRUE; -} diff --git a/Source/CTest/Curl/amigaos.h b/Source/CTest/Curl/amigaos.h deleted file mode 100644 index 0196eec..0000000 --- a/Source/CTest/Curl/amigaos.h +++ /dev/null @@ -1,52 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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$ - ***************************************************************************/ - -#ifndef LIBCURL_AMIGAOS_H -#define LIBCURL_AMIGAOS_H - -#ifndef __ixemul__ - -#include <exec/types.h> -#include <exec/execbase.h> - -#include <proto/exec.h> -#include <proto/dos.h> - -#include <bsdsocket.h> - -#include "config-amigaos.h" - -#define select(args...) WaitSelect( args, NULL) -#define inet_ntoa(x) Inet_NtoA( x ## .s_addr) -#define ioctl(a,b,c,d) IoctlSocket( (LONG)a, (ULONG)b, (char*)c) -#define _AMIGASF 1 - -extern void amiga_cleanup(); -extern BOOL amiga_init(); - -#else /* __ixemul__ */ - -#warning compiling with ixemul... - -#endif /* __ixemul__ */ -#endif /* LIBCURL_AMIGAOS_H */ diff --git a/Source/CTest/Curl/arpa_telnet.h b/Source/CTest/Curl/arpa_telnet.h deleted file mode 100644 index 5359ff1..0000000 --- a/Source/CTest/Curl/arpa_telnet.h +++ /dev/null @@ -1,101 +0,0 @@ -#ifndef __ARPA_TELNET_H -#define __ARPA_TELNET_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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$ - ***************************************************************************/ -#ifndef CURL_DISABLE_TELNET -/* - * Telnet option defines. Add more here if in need. - */ -#define CURL_TELOPT_BINARY 0 /* binary 8bit data */ -#define CURL_TELOPT_SGA 3 /* Supress Go Ahead */ -#define CURL_TELOPT_EXOPL 255 /* EXtended OPtions List */ -#define CURL_TELOPT_TTYPE 24 /* Terminal TYPE */ -#define CURL_TELOPT_XDISPLOC 35 /* X DISPlay LOCation */ - -#define CURL_TELOPT_NEW_ENVIRON 39 /* NEW ENVIRONment variables */ -#define CURL_NEW_ENV_VAR 0 -#define CURL_NEW_ENV_VALUE 1 - -/* - * The telnet options represented as strings - */ -static const char *telnetoptions[]= -{ - "BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD", - "NAME", "STATUS", "TIMING MARK", "RCTE", - "NAOL", "NAOP", "NAOCRD", "NAOHTS", - "NAOHTD", "NAOFFD", "NAOVTS", "NAOVTD", - "NAOLFD", "EXTEND ASCII", "LOGOUT", "BYTE MACRO", - "DE TERMINAL", "SUPDUP", "SUPDUP OUTPUT", "SEND LOCATION", - "TERM TYPE", "END OF RECORD", "TACACS UID", "OUTPUT MARKING", - "TTYLOC", "3270 REGIME", "X3 PAD", "NAWS", - "TERM SPEED", "LFLOW", "LINEMODE", "XDISPLOC", - "OLD-ENVIRON", "AUTHENTICATION", "ENCRYPT", "NEW-ENVIRON" -}; - -#define CURL_TELOPT_MAXIMUM CURL_TELOPT_NEW_ENVIRON - -#define CURL_TELOPT_OK(x) ((x) <= CURL_TELOPT_MAXIMUM) -#define CURL_TELOPT(x) telnetoptions[x] - -#define CURL_NTELOPTS 40 - -/* - * First some defines - */ -#define CURL_xEOF 236 /* End Of File */ -#define CURL_SE 240 /* Sub negotiation End */ -#define CURL_NOP 241 /* No OPeration */ -#define CURL_DM 242 /* Data Mark */ -#define CURL_GA 249 /* Go Ahead, reverse the line */ -#define CURL_SB 250 /* SuBnegotiation */ -#define CURL_WILL 251 /* Our side WILL use this option */ -#define CURL_WONT 252 /* Our side WON'T use this option */ -#define CURL_DO 253 /* DO use this option! */ -#define CURL_DONT 254 /* DON'T use this option! */ -#define CURL_IAC 255 /* Interpret As Command */ - -/* - * Then those numbers represented as strings: - */ -static const char *telnetcmds[]= -{ - "EOF", "SUSP", "ABORT", "EOR", "SE", - "NOP", "DMARK", "BRK", "IP", "AO", - "AYT", "EC", "EL", "GA", "SB", - "WILL", "WONT", "DO", "DONT", "IAC" -}; - -#define CURL_TELCMD_MINIMUM CURL_xEOF /* the first one */ -#define CURL_TELCMD_MAXIMUM CURL_IAC /* surprise, 255 is the last one! ;-) */ - -#define CURL_TELQUAL_IS 0 -#define CURL_TELQUAL_SEND 1 -#define CURL_TELQUAL_INFO 2 -#define CURL_TELQUAL_NAME 3 - -#define CURL_TELCMD_OK(x) ( ((unsigned int)(x) >= CURL_TELCMD_MINIMUM) && \ - ((unsigned int)(x) <= CURL_TELCMD_MAXIMUM) ) -#define CURL_TELCMD(x) telnetcmds[(x)-CURL_TELCMD_MINIMUM] -#endif -#endif diff --git a/Source/CTest/Curl/base64.c b/Source/CTest/Curl/base64.c deleted file mode 100644 index 7f8ae86..0000000 --- a/Source/CTest/Curl/base64.c +++ /dev/null @@ -1,288 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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$ - ***************************************************************************/ - -/* Base64 encoding/decoding - * - * Test harnesses down the bottom - compile with -DTEST_ENCODE for - * a program that will read in raw data from stdin and write out - * a base64-encoded version to stdout, and the length returned by the - * encoding function to stderr. Compile with -DTEST_DECODE for a program that - * will go the other way. - * - * This code will break if int is smaller than 32 bits - */ - -#include "setup.h" - -#include <stdlib.h> -#include <string.h> - -#define _MPRINTF_REPLACE /* use our functions only */ -#include <curl/mprintf.h> - -#include "base64.h" -#include "curl_memory.h" - -/* include memdebug.h last */ -#include "memdebug.h" - - -static void decodeQuantum(unsigned char *dest, const char *src) -{ - unsigned int x = 0; - int i; - for(i = 0; i < 4; i++) { - if(src[i] >= 'A' && src[i] <= 'Z') - x = (x << 6) + (unsigned int)(src[i] - 'A' + 0); - else if(src[i] >= 'a' && src[i] <= 'z') - x = (x << 6) + (unsigned int)(src[i] - 'a' + 26); - else if(src[i] >= '0' && src[i] <= '9') - x = (x << 6) + (unsigned int)(src[i] - '0' + 52); - else if(src[i] == '+') - x = (x << 6) + 62; - else if(src[i] == '/') - x = (x << 6) + 63; - else if(src[i] == '=') - x = (x << 6); - } - - dest[2] = (unsigned char)(x & 255); - x >>= 8; - dest[1] = (unsigned char)(x & 255); - x >>= 8; - dest[0] = (unsigned char)(x & 255); -} - -/* - * Curl_base64_decode() - * - * Given a base64 string at src, decode it into the memory pointed to by - * dest. Returns the length of the decoded data. - */ -size_t Curl_base64_decode(const char *src, char *dest) -{ - int length = 0; - int equalsTerm = 0; - int i; - int numQuantums; - unsigned char lastQuantum[3]; - size_t rawlen; - - while((src[length] != '=') && src[length]) - length++; - while(src[length+equalsTerm] == '=') - equalsTerm++; - - numQuantums = (length + equalsTerm) / 4; - - rawlen = (numQuantums * 3) - equalsTerm; - - for(i = 0; i < numQuantums - 1; i++) { - decodeQuantum((unsigned char *)dest, src); - dest += 3; src += 4; - } - - decodeQuantum(lastQuantum, src); - for(i = 0; i < 3 - equalsTerm; i++) - dest[i] = lastQuantum[i]; - - return rawlen; -} - -/* ---- Base64 Encoding --- */ -static char table64[]= - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -/* - * Curl_base64_encode() - * - * Returns the length of the newly created base64 string. The third argument - * is a pointer to an allocated area holding the base64 data. If something - * went wrong, -1 is returned. - * - */ -size_t Curl_base64_encode(const char *inp, size_t insize, char **outptr) -{ - unsigned char ibuf[3]; - unsigned char obuf[4]; - int i; - int inputparts; - char *output; - char *base64data; - - char *indata = (char *)inp; - - *outptr = NULL; /* set to NULL in case of failure before we reach the end */ - - if(0 == insize) - insize = strlen(indata); - - base64data = output = (char*)malloc(insize*4/3+4); - if(NULL == output) - return 0; - - while(insize > 0) { - for (i = inputparts = 0; i < 3; i++) { - if(insize > 0) { - inputparts++; - ibuf[i] = *indata; - indata++; - insize--; - } - else - ibuf[i] = 0; - } - - obuf [0] = (ibuf [0] & 0xFC) >> 2; - obuf [1] = ((ibuf [0] & 0x03) << 4) | ((ibuf [1] & 0xF0) >> 4); - obuf [2] = ((ibuf [1] & 0x0F) << 2) | ((ibuf [2] & 0xC0) >> 6); - obuf [3] = ibuf [2] & 0x3F; - - switch(inputparts) { - case 1: /* only one byte read */ - snprintf(output, 5, "%c%c==", - table64[obuf[0]], - table64[obuf[1]]); - break; - case 2: /* two bytes read */ - snprintf(output, 5, "%c%c%c=", - table64[obuf[0]], - table64[obuf[1]], - table64[obuf[2]]); - break; - default: - snprintf(output, 5, "%c%c%c%c", - table64[obuf[0]], - table64[obuf[1]], - table64[obuf[2]], - table64[obuf[3]] ); - break; - } - output += 4; - } - *output=0; - *outptr = base64data; /* make it return the actual data memory */ - - return strlen(base64data); /* return the length of the new data */ -} -/* ---- End of Base64 Encoding ---- */ - -/************* TEST HARNESS STUFF ****************/ - - -#ifdef TEST_ENCODE -/* encoding test harness. Read in standard input and write out the length - * returned by Curl_base64_encode, followed by the base64'd data itself - */ -#include <stdio.h> - -#define TEST_NEED_SUCK -void *suck(int *); - -int main(int argc, char **argv, char **envp) -{ - char *base64; - size_t base64Len; - unsigned char *data; - int dataLen; - - data = (unsigned char *)suck(&dataLen); - base64Len = Curl_base64_encode(data, dataLen, &base64); - - fprintf(stderr, "%d\n", base64Len); - fprintf(stdout, "%s", base64); - - free(base64); free(data); - return 0; -} -#endif - -#ifdef TEST_DECODE -/* decoding test harness. Read in a base64 string from stdin and write out the - * length returned by Curl_base64_decode, followed by the decoded data itself - * - * gcc -DTEST_DECODE base64.c -o base64 mprintf.o memdebug.o - */ -#include <stdio.h> - -#define TEST_NEED_SUCK -void *suck(int *); - -int main(int argc, char **argv, char **envp) -{ - char *base64; - int base64Len; - unsigned char *data; - int dataLen; - int i, j; - - base64 = (char *)suck(&base64Len); - data = (unsigned char *)malloc(base64Len * 3/4 + 8); - dataLen = Curl_base64_decode(base64, data); - - fprintf(stderr, "%d\n", dataLen); - - for(i=0; i < dataLen; i+=0x10) { - printf("0x%02x: ", i); - for(j=0; j < 0x10; j++) - if((j+i) < dataLen) - printf("%02x ", data[i+j]); - else - printf(" "); - - printf(" | "); - - for(j=0; j < 0x10; j++) - if((j+i) < dataLen) - printf("%c", isgraph(data[i+j])?data[i+j]:'.'); - else - break; - puts(""); - } - - free(base64); free(data); - return 0; -} -#endif - -#ifdef TEST_NEED_SUCK -/* this function 'sucks' in as much as possible from stdin */ -void *suck(int *lenptr) -{ - int cursize = 8192; - unsigned char *buf = NULL; - int lastread; - int len = 0; - - do { - cursize *= 2; - buf = (unsigned char *)realloc(buf, cursize); - memset(buf + len, 0, cursize - len); - lastread = fread(buf + len, 1, cursize - len, stdin); - len += lastread; - } while(!feof(stdin)); - - lenptr[0] = len; - return (void *)buf; -} -#endif diff --git a/Source/CTest/Curl/base64.h b/Source/CTest/Curl/base64.h deleted file mode 100644 index 307148e..0000000 --- a/Source/CTest/Curl/base64.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef __BASE64_H -#define __BASE64_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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$ - ***************************************************************************/ -size_t Curl_base64_encode(const char *input, size_t size, char **str); -size_t Curl_base64_decode(const char *source, char *dest); -#endif diff --git a/Source/CTest/Curl/ca-bundle.h b/Source/CTest/Curl/ca-bundle.h deleted file mode 100644 index 12390bc..0000000 --- a/Source/CTest/Curl/ca-bundle.h +++ /dev/null @@ -1 +0,0 @@ -/* ca bundle path set in here*/ diff --git a/Source/CTest/Curl/config.h.in b/Source/CTest/Curl/config.h.in deleted file mode 100644 index 1086027..0000000 --- a/Source/CTest/Curl/config.h.in +++ /dev/null @@ -1,512 +0,0 @@ -/* lib/config.h.in. Generated from configure.in by autoheader. */ - -/* to disable DICT */ -#cmakedefine CURL_DISABLE_DICT ${CURL_DISABLE_DICT} - -/* to disable FILE */ -#cmakedefine CURL_DISABLE_FILE ${CURL_DISABLE_FILE} - -/* to disable FTP */ -#cmakedefine CURL_DISABLE_FTP ${CURL_DISABLE_FTP} - -/* to disable GOPHER */ -#cmakedefine CURL_DISABLE_GOPHER ${CURL_DISABLE_GOPHER} - -/* to disable HTTP */ -#cmakedefine CURL_DISABLE_HTTP ${CURL_DISABLE_HTTP} - -/* to disable LDAP */ -#cmakedefine CURL_DISABLE_LDAP ${CURL_DISABLE_LDAP} - -/* to disable TELNET */ -#cmakedefine CURL_DISABLE_TELNET ${CURL_DISABLE_TELNET} - -/* Set to explicitly specify we don't want to use thread-safe functions */ -#cmakedefine DISABLED_THREADSAFE ${DISABLED_THREADSAFE} - -/* your Entropy Gathering Daemon socket pathname */ -#cmakedefine EGD_SOCKET ${EGD_SOCKET} - -/* Define if you want to enable IPv6 support */ -#cmakedefine ENABLE_IPV6 ${ENABLE_IPV6} - -/* Define to 1 if you have the <alloca.h> header file. */ -#cmakedefine HAVE_ALLOCA_H ${HAVE_ALLOCA_H} - -/* Define to 1 if you have the <arpa/inet.h> header file. */ -#cmakedefine HAVE_ARPA_INET_H ${HAVE_ARPA_INET_H} - -/* Define to 1 if you have the <assert.h> header file. */ -#cmakedefine HAVE_ASSERT_H ${HAVE_ASSERT_H} - -/* Define to 1 if you have the `closesocket' function. */ -#cmakedefine HAVE_CLOSESOCKET ${HAVE_CLOSESOCKET} - -/* Define to 1 if you have the `CRYPTO_cleanup_all_ex_data' function. */ -#cmakedefine HAVE_CRYPTO_CLEANUP_ALL_EX_DATA ${HAVE_CRYPTO_CLEANUP_ALL_EX_DATA} - -/* Define to 1 if you have the <crypto.h> header file. */ -#cmakedefine HAVE_CRYPTO_H ${HAVE_CRYPTO_H} - -/* Define to 1 if you have the <des.h> header file. */ -#cmakedefine HAVE_DES_H ${HAVE_DES_H} - -/* disabled non-blocking sockets */ -#cmakedefine HAVE_DISABLED_NONBLOCKING ${HAVE_DISABLED_NONBLOCKING} - -/* Define to 1 if you have the <dlfcn.h> header file. */ -#cmakedefine HAVE_DLFCN_H ${HAVE_DLFCN_H} - -/* Define to 1 if you have the `dlopen' function. */ -#cmakedefine HAVE_DLOPEN ${HAVE_DLOPEN} - -/* Define to 1 if you have the <err.h> header file. */ -#cmakedefine HAVE_ERR_H ${HAVE_ERR_H} - -/* Define to 1 if you have the <fcntl.h> header file. */ -#cmakedefine HAVE_FCNTL_H ${HAVE_FCNTL_H} - -/* use FIONBIO for non-blocking sockets */ -#cmakedefine HAVE_FIONBIO ${HAVE_FIONBIO} - -/* Define if getaddrinfo exists and works */ -#cmakedefine HAVE_GETADDRINFO ${HAVE_GETADDRINFO} - -/* Define to 1 if you have the `geteuid' function. */ -#cmakedefine HAVE_GETEUID ${HAVE_GETEUID} - -/* Define to 1 if you have the `gethostbyaddr' function. */ -#cmakedefine HAVE_GETHOSTBYADDR ${HAVE_GETHOSTBYADDR} - -/* If you have gethostbyname */ -#cmakedefine HAVE_GETHOSTBYNAME ${HAVE_GETHOSTBYNAME} - -/* Define to 1 if you have the `gethostbyname_r' function. */ -#cmakedefine HAVE_GETHOSTBYNAME_R ${HAVE_GETHOSTBYNAME_R} - -/* gethostbyname_r() takes 3 args */ -#cmakedefine HAVE_GETHOSTBYNAME_R_3 ${HAVE_GETHOSTBYNAME_R_3} - -/* gethostbyname_r() takes 5 args */ -#cmakedefine HAVE_GETHOSTBYNAME_R_5 ${HAVE_GETHOSTBYNAME_R_5} - -/* gethostbyname_r() takes 6 args */ -#cmakedefine HAVE_GETHOSTBYNAME_R_6 ${HAVE_GETHOSTBYNAME_R_6} - -/* Define to 1 if you have the `getpass_r' function. */ -#cmakedefine HAVE_GETPASS_R ${HAVE_GETPASS_R} - -/* Define to 1 if you have the `getpwuid' function. */ -#cmakedefine HAVE_GETPWUID ${HAVE_GETPWUID} - -/* Define to 1 if you have the `gettimeofday' function. */ -#cmakedefine HAVE_GETTIMEOFDAY ${HAVE_GETTIMEOFDAY} - -/* we have a glibc-style strerror_r() */ -#cmakedefine HAVE_GLIBC_STRERROR_R ${HAVE_GLIBC_STRERROR_R} - -/* Define to 1 if you have the `gmtime_r' function. */ -#cmakedefine HAVE_GMTIME_R ${HAVE_GMTIME_R} - -/* if you have the gssapi libraries */ -#cmakedefine HAVE_GSSAPI ${HAVE_GSSAPI} - -/* if you have the Heimdal gssapi libraries */ -#cmakedefine HAVE_GSSHEIMDAL ${HAVE_GSSHEIMDAL} - -/* if you have the MIT gssapi libraries */ -#cmakedefine HAVE_GSSMIT ${HAVE_GSSMIT} - -/* Define to 1 if you have the `idn_free' function. */ -#cmakedefine HAVE_IDN_FREE ${HAVE_IDN_FREE} - -/* Define to 1 if you have the <idn-free.h> header file. */ -#cmakedefine HAVE_IDN_FREE_H ${HAVE_IDN_FREE_H} - -/* Define to 1 if you have the `inet_addr' function. */ -#cmakedefine HAVE_INET_ADDR ${HAVE_INET_ADDR} - -/* Define to 1 if you have the `inet_ntoa' function. */ -#cmakedefine HAVE_INET_NTOA ${HAVE_INET_NTOA} - -/* Define to 1 if you have the `inet_ntoa_r' function. */ -#cmakedefine HAVE_INET_NTOA_R ${HAVE_INET_NTOA_R} - -/* inet_ntoa_r() is declared */ -#cmakedefine HAVE_INET_NTOA_R_DECL ${HAVE_INET_NTOA_R_DECL} - -/* Define to 1 if you have the `inet_pton' function. */ -#cmakedefine HAVE_INET_PTON ${HAVE_INET_PTON} - -/* Define to 1 if you have the <inttypes.h> header file. */ -#cmakedefine HAVE_INTTYPES_H ${HAVE_INTTYPES_H} - -/* use ioctlsocket() for non-blocking sockets */ -#cmakedefine HAVE_IOCTLSOCKET ${HAVE_IOCTLSOCKET} - -/* use Ioctlsocket() for non-blocking sockets */ -#cmakedefine HAVE_IOCTLSOCKET_CASE ${HAVE_IOCTLSOCKET_CASE} - -/* Define to 1 if you have the <io.h> header file. */ -#cmakedefine HAVE_IO_H ${HAVE_IO_H} - -/* if you have the Kerberos4 libraries (including -ldes) */ -#cmakedefine HAVE_KRB4 ${HAVE_KRB4} - -/* Define to 1 if you have the `krb_get_our_ip_for_realm' function. */ -#cmakedefine HAVE_KRB_GET_OUR_IP_FOR_REALM ${HAVE_KRB_GET_OUR_IP_FOR_REALM} - -/* Define to 1 if you have the <krb.h> header file. */ -#cmakedefine HAVE_KRB_H ${HAVE_KRB_H} - -/* Define to 1 if you have the `crypto' library (-lcrypto). */ -#cmakedefine HAVE_LIBCRYPTO ${HAVE_LIBCRYPTO} - -/* Define to 1 if you have the `dl' library (-ldl). */ -#cmakedefine HAVE_LIBDL ${HAVE_LIBDL} - -/* Define to 1 if you have the `idn' library (-lidn). */ -#cmakedefine HAVE_LIBIDN ${HAVE_LIBIDN} - -/* Define to 1 if you have the `resolv' library (-lresolv). */ -#cmakedefine HAVE_LIBRESOLV ${HAVE_LIBRESOLV} - -/* Define to 1 if you have the `resolve' library (-lresolve). */ -#cmakedefine HAVE_LIBRESOLVE ${HAVE_LIBRESOLVE} - -/* Define to 1 if you have the `socket' library (-lsocket). */ -#cmakedefine HAVE_LIBSOCKET ${HAVE_LIBSOCKET} - -/* Define to 1 if you have the `ssl' library (-lssl). */ -#cmakedefine HAVE_LIBSSL ${HAVE_LIBSSL} - -/* if zlib is available */ -#cmakedefine HAVE_LIBZ ${HAVE_LIBZ} - -/* Define to 1 if you have the <limits.h> header file. */ -#cmakedefine HAVE_LIMITS_H ${HAVE_LIMITS_H} - -/* Define to 1 if you have the `localtime_r' function. */ -#cmakedefine HAVE_LOCALTIME_R ${HAVE_LOCALTIME_R} - -/* if your compiler supports 'long long' */ -#cmakedefine HAVE_LONGLONG ${HAVE_LONGLONG} - -/* Define to 1 if you have the <malloc.h> header file. */ -#cmakedefine HAVE_MALLOC_H ${HAVE_MALLOC_H} - -/* Define to 1 if you have the <memory.h> header file. */ -#cmakedefine HAVE_MEMORY_H ${HAVE_MEMORY_H} - -/* Define to 1 if you have the <netdb.h> header file. */ -#cmakedefine HAVE_NETDB_H ${HAVE_NETDB_H} - -/* Define to 1 if you have the <netinet/in.h> header file. */ -#cmakedefine HAVE_NETINET_IN_H ${HAVE_NETINET_IN_H} - -/* Define to 1 if you have the <netinet/tcp.h> header file. */ -#cmakedefine HAVE_NETINET_TCP_H ${HAVE_NETINET_TCP_H} - -/* Define to 1 if you have the <net/if.h> header file. */ -#cmakedefine HAVE_NET_IF_H ${HAVE_NET_IF_H} - -/* Define if NI_WITHSCOPEID exists and works */ -#cmakedefine HAVE_NI_WITHSCOPEID ${HAVE_NI_WITHSCOPEID} - -/* we have no strerror_r() proto */ -#cmakedefine HAVE_NO_STRERROR_R_DECL ${HAVE_NO_STRERROR_R_DECL} - -/* Define to 1 if you have the <openssl/crypto.h> header file. */ -#cmakedefine HAVE_OPENSSL_CRYPTO_H ${HAVE_OPENSSL_CRYPTO_H} - -/* Define to 1 if you have the <openssl/engine.h> header file. */ -#cmakedefine HAVE_OPENSSL_ENGINE_H ${HAVE_OPENSSL_ENGINE_H} - -/* Define to 1 if you have the <openssl/err.h> header file. */ -#cmakedefine HAVE_OPENSSL_ERR_H ${HAVE_OPENSSL_ERR_H} - -/* Define to 1 if you have the <openssl/pem.h> header file. */ -#cmakedefine HAVE_OPENSSL_PEM_H ${HAVE_OPENSSL_PEM_H} - -/* Define to 1 if you have the <openssl/rsa.h> header file. */ -#cmakedefine HAVE_OPENSSL_RSA_H ${HAVE_OPENSSL_RSA_H} - -/* Define to 1 if you have the <openssl/ssl.h> header file. */ -#cmakedefine HAVE_OPENSSL_SSL_H ${HAVE_OPENSSL_SSL_H} - -/* Define to 1 if you have the <openssl/x509.h> header file. */ -#cmakedefine HAVE_OPENSSL_X509_H ${HAVE_OPENSSL_X509_H} - -/* use O_NONBLOCK for non-blocking sockets */ -#cmakedefine HAVE_O_NONBLOCK ${HAVE_O_NONBLOCK} - -/* Define to 1 if you have the <pem.h> header file. */ -#cmakedefine HAVE_PEM_H ${HAVE_PEM_H} - -/* Define to 1 if you have the `perror' function. */ -#cmakedefine HAVE_PERROR ${HAVE_PERROR} - -/* Define to 1 if you have the `poll' function. */ -#cmakedefine HAVE_POLL ${HAVE_POLL} - -/* If you have a fine poll */ -#cmakedefine HAVE_POLL_FINE ${HAVE_POLL_FINE} - -/* we have a POSIX-style strerror_r() */ -#cmakedefine HAVE_POSIX_STRERROR_R ${HAVE_POSIX_STRERROR_R} - -/* Define to 1 if you have the <pwd.h> header file. */ -#cmakedefine HAVE_PWD_H ${HAVE_PWD_H} - -/* Define to 1 if you have the `RAND_egd' function. */ -#cmakedefine HAVE_RAND_EGD ${HAVE_RAND_EGD} - -/* Define to 1 if you have the `RAND_screen' function. */ -#cmakedefine HAVE_RAND_SCREEN ${HAVE_RAND_SCREEN} - -/* Define to 1 if you have the `RAND_status' function. */ -#cmakedefine HAVE_RAND_STATUS ${HAVE_RAND_STATUS} - -/* Define to 1 if you have the <rsa.h> header file. */ -#cmakedefine HAVE_RSA_H ${HAVE_RSA_H} - -/* Define to 1 if you have the `select' function. */ -#cmakedefine HAVE_SELECT ${HAVE_SELECT} - -/* Define to 1 if you have the <setjmp.h> header file. */ -#cmakedefine HAVE_SETJMP_H ${HAVE_SETJMP_H} - -/* Define to 1 if you have the <sgtty.h> header file. */ -#cmakedefine HAVE_SGTTY_H ${HAVE_SGTTY_H} - -/* Define to 1 if you have the `sigaction' function. */ -#cmakedefine HAVE_SIGACTION ${HAVE_SIGACTION} - -/* Define to 1 if you have the `siginterrupt' function. */ -#cmakedefine HAVE_SIGINTERRUPT ${HAVE_SIGINTERRUPT} - -/* Define to 1 if you have the `signal' function. */ -#cmakedefine HAVE_SIGNAL ${HAVE_SIGNAL} - -/* If you have sigsetjmp */ -#cmakedefine HAVE_SIGSETJMP ${HAVE_SIGSETJMP} - -/* Define to 1 if you have the `socket' function. */ -#cmakedefine HAVE_SOCKET ${HAVE_SOCKET} - -/* use SO_NONBLOCK for non-blocking sockets */ -#cmakedefine HAVE_SO_NONBLOCK ${HAVE_SO_NONBLOCK} - -/* Define this if you have the SPNEGO library fbopenssl */ -#cmakedefine HAVE_SPNEGO ${HAVE_SPNEGO} - -/* Define to 1 if you have the <ssl.h> header file. */ -#cmakedefine HAVE_SSL_H ${HAVE_SSL_H} - -/* Define to 1 if you have the <stdint.h> header file. */ -#cmakedefine HAVE_STDINT_H ${HAVE_STDINT_H} - -/* Define to 1 if you have the <stdlib.h> header file. */ -#cmakedefine HAVE_STDLIB_H ${HAVE_STDLIB_H} - -/* Define to 1 if you have the `strcasecmp' function. */ -#cmakedefine HAVE_STRCASECMP ${HAVE_STRCASECMP} - -/* Define to 1 if you have the `strcmpi' function. */ -#cmakedefine HAVE_STRCMPI ${HAVE_STRCMPI} - -/* Define to 1 if you have the `strdup' function. */ -#cmakedefine HAVE_STRDUP ${HAVE_STRDUP} - -/* Define to 1 if you have the `strerror_r' function. */ -#cmakedefine HAVE_STRERROR_R ${HAVE_STRERROR_R} - -/* Define to 1 if you have the `strftime' function. */ -#cmakedefine HAVE_STRFTIME ${HAVE_STRFTIME} - -/* Define to 1 if you have the `stricmp' function. */ -#cmakedefine HAVE_STRICMP ${HAVE_STRICMP} - -/* Define to 1 if you have the <strings.h> header file. */ -#cmakedefine HAVE_STRINGS_H ${HAVE_STRINGS_H} - -/* Define to 1 if you have the <string.h> header file. */ -#cmakedefine HAVE_STRING_H ${HAVE_STRING_H} - -/* Define to 1 if you have the `strlcat' function. */ -#cmakedefine HAVE_STRLCAT ${HAVE_STRLCAT} - -/* Define to 1 if you have the `strlcpy' function. */ -#cmakedefine HAVE_STRLCPY ${HAVE_STRLCPY} - -/* Define to 1 if you have the `strstr' function. */ -#cmakedefine HAVE_STRSTR ${HAVE_STRSTR} - -/* Define to 1 if you have the `strtok_r' function. */ -#cmakedefine HAVE_STRTOK_R ${HAVE_STRTOK_R} - -/* Define to 1 if you have the `strtoll' function. */ -#cmakedefine HAVE_STRTOLL ${HAVE_STRTOLL} - -/* Define to 1 if you have the <sys/ioctl.h> header file. */ -#cmakedefine HAVE_SYS_IOCTL_H ${HAVE_SYS_IOCTL_H} - -/* Define to 1 if you have the <sys/param.h> header file. */ -#cmakedefine HAVE_SYS_PARAM_H ${HAVE_SYS_PARAM_H} - -/* Define to 1 if you have the <sys/poll.h> header file. */ -#cmakedefine HAVE_SYS_POLL_H ${HAVE_SYS_POLL_H} - -/* Define to 1 if you have the <sys/select.h> header file. */ -#cmakedefine HAVE_SYS_SELECT_H ${HAVE_SYS_SELECT_H} - -/* Define to 1 if you have the <sys/socket.h> header file. */ -#cmakedefine HAVE_SYS_SOCKET_H ${HAVE_SYS_SOCKET_H} - -/* Define to 1 if you have the <sys/sockio.h> header file. */ -#cmakedefine HAVE_SYS_SOCKIO_H ${HAVE_SYS_SOCKIO_H} - -/* Define to 1 if you have the <sys/stat.h> header file. */ -#cmakedefine HAVE_SYS_STAT_H ${HAVE_SYS_STAT_H} - -/* Define to 1 if you have the <sys/time.h> header file. */ -#cmakedefine HAVE_SYS_TIME_H ${HAVE_SYS_TIME_H} - -/* Define to 1 if you have the <sys/types.h> header file. */ -#cmakedefine HAVE_SYS_TYPES_H ${HAVE_SYS_TYPES_H} - -/* Define to 1 if you have the <sys/utime.h> header file. */ -#cmakedefine HAVE_SYS_UTIME_H ${HAVE_SYS_UTIME_H} - -/* Define to 1 if you have the `tcgetattr' function. */ -#cmakedefine HAVE_TCGETATTR ${HAVE_TCGETATTR} - -/* Define to 1 if you have the `tcsetattr' function. */ -#cmakedefine HAVE_TCSETATTR ${HAVE_TCSETATTR} - -/* Define to 1 if you have the <termios.h> header file. */ -#cmakedefine HAVE_TERMIOS_H ${HAVE_TERMIOS_H} - -/* Define to 1 if you have the <termio.h> header file. */ -#cmakedefine HAVE_TERMIO_H ${HAVE_TERMIO_H} - -/* Define to 1 if you have the <time.h> header file. */ -#cmakedefine HAVE_TIME_H ${HAVE_TIME_H} - -/* Define to 1 if you have the `uname' function. */ -#cmakedefine HAVE_UNAME ${HAVE_UNAME} - -/* Define to 1 if you have the <unistd.h> header file. */ -#cmakedefine HAVE_UNISTD_H ${HAVE_UNISTD_H} - -/* Define to 1 if you have the `utime' function. */ -#cmakedefine HAVE_UTIME ${HAVE_UTIME} - -/* Define to 1 if you have the <utime.h> header file. */ -#cmakedefine HAVE_UTIME_H ${HAVE_UTIME_H} - -/* Define to 1 if you have the <winsock.h> header file. */ -#cmakedefine HAVE_WINSOCK_H ${HAVE_WINSOCK_H} - -/* Define this symbol if your OS supports changing the contents of argv */ -#cmakedefine HAVE_WRITABLE_ARGV ${HAVE_WRITABLE_ARGV} - -/* 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} - -/* need REENTRANT defined */ -#cmakedefine NEED_REENTRANT ${NEED_REENTRANT} - -/* cpu-machine-OS */ -#define OS "${OPERATING_SYSTEM}" - -/* Name of package */ -#cmakedefine PACKAGE "${PACKAGE}" - -/* Define to the address where bug reports for this package should be sent. */ -#cmakedefine PACKAGE_BUGREPORT "${PACKAGE_BUGREPORT}" - -/* Define to the full name of this package. */ -#cmakedefine PACKAGE_NAME "${PACKAGE_NAME}" - -/* Define to the full name and version of this package. */ -#cmakedefine PACKAGE_STRING "${PACKAGE_STRING}" - -/* Define to the one symbol short name of this package. */ -#cmakedefine PACKAGE_TARNAME "${PACKAGE_TARNAME}" - -/* Define to the version of this package. */ -#cmakedefine PACKAGE_VERSION "${PACKAGE_VERSION}" - -/* a suitable file to read random data from */ -#cmakedefine RANDOM_FILE "${RANDOM_FILE}" - -/* Define as the return type of signal handlers (`int' or `void'). */ -#cmakedefine RETSIGTYPE ${RETSIGTYPE} - -/* Define to the type of arg 1 for `select'. */ -#cmakedefine SELECT_TYPE_ARG1 ${SELECT_TYPE_ARG1} - -/* Define to the type of args 2, 3 and 4 for `select'. */ -#cmakedefine SELECT_TYPE_ARG234 ${SELECT_TYPE_ARG234} - -/* Define to the type of arg 5 for `select'. */ -#cmakedefine SELECT_TYPE_ARG5 ${SELECT_TYPE_ARG5} - -/* The size of a `curl_off_t', as computed by sizeof. */ -#cmakedefine SIZEOF_CURL_OFF_T ${SIZEOF_CURL_OFF_T} - -/* The size of a `size_t', as computed by sizeof. */ -#cmakedefine SIZEOF_SIZE_T ${SIZEOF_SIZE_T} - -/* Define to 1 if you have the ANSI C header files. */ -#cmakedefine STDC_HEADERS ${STDC_HEADERS} - -/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */ -#cmakedefine TIME_WITH_SYS_TIME ${TIME_WITH_SYS_TIME} - -/* Define if you want to enable ares support */ -#cmakedefine USE_ARES ${USE_ARES} - -/* If you want to build curl with the built-in manual */ -#cmakedefine USE_MANUAL ${USE_MANUAL} - -/* Version number of package */ -#cmakedefine VERSION "${VERSION}" - -/* Define to 1 if on AIX 3. - System headers sometimes define this. - We just want to avoid a redefinition error message. */ -#ifndef _ALL_SOURCE -#cmakedefine _ALL_SOURCE ${_ALL_SOURCE} -#endif - -/* Number of bits in a file offset, on hosts where this is settable. */ -#cmakedefine _FILE_OFFSET_BITS ${_FILE_OFFSET_BITS} - -/* Define for large files, on AIX-style hosts. */ -#cmakedefine _LARGE_FILES ${_LARGE_FILES} - -/* Define to empty if `const' does not conform to ANSI C. */ -#cmakedefine const ${const} - -/* type to use in place of in_addr_t if not defined */ -#cmakedefine in_addr_t ${in_addr_t} - -/* Define to `unsigned' if <sys/types.h> does not define. */ -#cmakedefine size_t ${size_t} - -/* type to use in place of socklen_t if not defined */ -#cmakedefine socklen_t ${socklen_t} - -/* the signed version of size_t */ -#cmakedefine ssize_t ${ssize_t} - -/* define if the compiler supports number 0x3627676LL */ -#cmakedefine HAVE_LONG_LONG_CONSTANT ${HAVE_LONG_LONG_CONSTANT} - -/* Special handling of zlib library */ -#cmakedefine CURL_SPECIAL_ZLIB_H "${CURL_SPECIAL_ZLIB_H}" diff --git a/Source/CTest/Curl/connect.c b/Source/CTest/Curl/connect.c deleted file mode 100644 index c107354..0000000 --- a/Source/CTest/Curl/connect.c +++ /dev/null @@ -1,788 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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" - -#ifndef WIN32 -/* headers for non-win32 */ -#include <sys/time.h> -#ifdef HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif -#ifdef HAVE_SYS_SOCKET_H -#include <sys/socket.h> -#endif -#ifdef HAVE_NETINET_IN_H -#include <netinet/in.h> /* <netinet/tcp.h> may need it */ -#endif -#ifdef HAVE_NETINET_TCP_H -#include <netinet/tcp.h> /* for TCP_NODELAY */ -#endif -#ifdef HAVE_SYS_IOCTL_H -#include <sys/ioctl.h> -#endif -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif -#ifdef HAVE_NETDB_H -#include <netdb.h> -#endif -#ifdef HAVE_FCNTL_H -#include <fcntl.h> -#endif -#ifdef HAVE_NETINET_IN_H -#include <netinet/in.h> -#endif -#ifdef HAVE_ARPA_INET_H -#include <arpa/inet.h> -#endif -#ifdef HAVE_STDLIB_H -#include <stdlib.h> /* required for free() prototype, without it, this crashes - on macos 68K */ -#endif -#if (defined(HAVE_FIONBIO) && defined(__NOVELL_LIBC__)) -#include <sys/filio.h> -#endif -#if (defined(NETWARE) && defined(__NOVELL_LIBC__)) -#undef in_addr_t -#define in_addr_t unsigned long -#endif -#ifdef VMS -#include <in.h> -#include <inet.h> -#endif - -#endif -#include <stdio.h> -#include <errno.h> -#include <string.h> - -#ifndef TRUE -#define TRUE 1 -#define FALSE 0 -#endif - -#ifdef WIN32 -#include <windows.h> -#define EINPROGRESS WSAEINPROGRESS -#define EWOULDBLOCK WSAEWOULDBLOCK -#define EISCONN WSAEISCONN -#define ENOTSOCK WSAENOTSOCK -#define ECONNREFUSED WSAECONNREFUSED -#endif - -#include "urldata.h" -#include "sendf.h" -#include "if2ip.h" -#include "strerror.h" -#include "connect.h" -#include "curl_memory.h" - -/* The last #include file should be: */ -#include "memdebug.h" - -static bool verifyconnect(curl_socket_t sockfd, int *error); - -static curl_socket_t -singleipconnect(struct connectdata *conn, - Curl_addrinfo *ai, /* start connecting to this */ - long timeout_ms, - bool *connected); - -/* - * Curl_ourerrno() returns the errno (or equivalent) on this platform to - * hide platform specific for the function that calls this. - */ -int Curl_ourerrno(void) -{ -#ifdef WIN32 - return (int)GetLastError(); -#else - return errno; -#endif -} - -/* - * Curl_nonblock() set the given socket to either blocking or non-blocking - * mode based on the 'nonblock' boolean argument. This function is highly - * portable. - */ -int Curl_nonblock(curl_socket_t sockfd, /* operate on this */ - int nonblock /* TRUE or FALSE */) -{ -#undef SETBLOCK -#ifdef HAVE_O_NONBLOCK - { - /* most recent unix versions */ - int flags; - - flags = fcntl(sockfd, F_GETFL, 0); - if (TRUE == nonblock) - return fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); - else - return fcntl(sockfd, F_SETFL, flags & (~O_NONBLOCK)); - } -#define SETBLOCK 1 -#endif - -#ifdef HAVE_FIONBIO - { - /* older unix versions */ - int flags; - - flags = nonblock; - return ioctl(sockfd, FIONBIO, &flags); - } -#ifdef SETBLOCK -# undef SETBLOCK -#endif -#define SETBLOCK 2 -#endif - -#ifdef HAVE_IOCTLSOCKET - /* Windows? */ - unsigned long flags; - flags = nonblock; - return ioctlsocket(sockfd, FIONBIO, &flags); -#define SETBLOCK 3 -#endif - -#ifdef HAVE_IOCTLSOCKET_CASE - /* presumably for Amiga */ - return IoctlSocket(sockfd, FIONBIO, (long)nonblock); -#ifdef SETBLOCK -# undef SETBLOCK -#endif -#define SETBLOCK 4 -#endif - -#ifdef HAVE_SO_NONBLOCK - /* BeOS */ - long b = nonblock ? 1 : 0; - return setsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b)); -#ifdef SETBLOCK -# undef SETBLOCK -#endif -#define SETBLOCK 5 -#endif - -#ifdef HAVE_DISABLED_NONBLOCKING - (void)nonblock; - (void)sockfd; - return 0; /* returns success */ -#ifdef SETBLOCK -# undef SETBLOCK -#endif -#define SETBLOCK 6 -#endif - -#ifndef SETBLOCK -#error "no non-blocking method was found/used/set" -#endif -} - -/* - * waitconnect() waits for a TCP connect on the given socket for the specified - * number if milliseconds. It returns: - * 0 fine connect - * -1 select() error - * 1 select() timeout - * 2 select() returned with an error condition fd_set - */ - -#define WAITCONN_CONNECTED 0 -#define WAITCONN_SELECT_ERROR -1 -#define WAITCONN_TIMEOUT 1 -#define WAITCONN_FDSET_ERROR 2 - -static -int waitconnect(curl_socket_t sockfd, /* socket */ - long timeout_msec) -{ - fd_set fd; - fd_set errfd; - struct timeval interval; - int rc; -#ifdef mpeix - /* Call this function once now, and ignore the results. We do this to - "clear" the error state on the socket so that we can later read it - reliably. This is reported necessary on the MPE/iX operating system. */ - verifyconnect(sockfd, NULL); -#endif - - /* now select() until we get connect or timeout */ - FD_ZERO(&fd); - FD_SET(sockfd, &fd); - - FD_ZERO(&errfd); - FD_SET(sockfd, &errfd); - - interval.tv_sec = (int)(timeout_msec/1000); - timeout_msec -= interval.tv_sec*1000; - - interval.tv_usec = timeout_msec*1000; - - rc = select(sockfd+1, NULL, &fd, &errfd, &interval); - if(-1 == rc) - /* error, no connect here, try next */ - return WAITCONN_SELECT_ERROR; - - else if(0 == rc) - /* timeout, no connect today */ - return WAITCONN_TIMEOUT; - - if(FD_ISSET(sockfd, &errfd)) - /* error condition caught */ - return WAITCONN_FDSET_ERROR; - - /* we have a connect! */ - return WAITCONN_CONNECTED; -} - -static CURLcode bindlocal(struct connectdata *conn, - curl_socket_t sockfd) -{ -#ifdef HAVE_INET_NTOA - bool bindworked = FALSE; - struct SessionHandle *data = conn->data; - - /************************************************************* - * Select device to bind socket to - *************************************************************/ - if (strlen(data->set.device)<255) { - struct Curl_dns_entry *h=NULL; - char myhost[256] = ""; - in_addr_t in; - int rc; - bool was_iface = FALSE; - - /* First check if the given name is an IP address */ - in=inet_addr(data->set.device); - - if((in == CURL_INADDR_NONE) && - Curl_if2ip(data->set.device, myhost, sizeof(myhost))) { - /* - * We now have the numerical IPv4-style x.y.z.w in the 'myhost' buffer - */ - rc = Curl_resolv(conn, myhost, 0, &h); - if(rc == CURLRESOLV_PENDING) - (void)Curl_wait_for_resolv(conn, &h); - - if(h) - was_iface = TRUE; - } - - if(!was_iface) { - /* - * This was not an interface, resolve the name as a host name - * or IP number - */ - rc = Curl_resolv(conn, data->set.device, 0, &h); - if(rc == CURLRESOLV_PENDING) - (void)Curl_wait_for_resolv(conn, &h); - - if(h) - /* we know data->set.device is shorter than the myhost array */ - strcpy(myhost, data->set.device); - } - - if(! *myhost) { - /* need to fix this - h=Curl_gethost(data, - getmyhost(*myhost,sizeof(myhost)), - hostent_buf, - sizeof(hostent_buf)); - */ - failf(data, "Couldn't bind to '%s'", data->set.device); - return CURLE_HTTP_PORT_FAILED; - } - - infof(data, "We bind local end to %s\n", myhost); - -#ifdef SO_BINDTODEVICE - /* I am not sure any other OSs than Linux that provide this feature, and - * at the least I cannot test. --Ben - * - * This feature allows one to tightly bind the local socket to a - * particular interface. This will force even requests to other local - * interfaces to go out the external interface. - * - */ - if (was_iface) { - /* Only bind to the interface when specified as interface, not just as a - * hostname or ip address. - */ - if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, - data->set.device, strlen(data->set.device)+1) != 0) { - /* printf("Failed to BINDTODEVICE, socket: %d device: %s error: %s\n", - sockfd, data->set.device, Curl_strerror(Curl_ourerrno())); */ - infof(data, "SO_BINDTODEVICE %s failed\n", - data->set.device); - /* This is typically "errno 1, error: Operation not permitted" if - you're not running as root or another suitable privileged user */ - } - } -#endif - - in=inet_addr(myhost); - if (CURL_INADDR_NONE != in) { - - if ( h ) { - Curl_addrinfo *addr = h->addr; - - Curl_resolv_unlock(data, h); - /* we don't need it anymore after this function has returned */ - - if( bind(sockfd, addr->ai_addr, (socklen_t)addr->ai_addrlen) >= 0) { - /* we succeeded to bind */ -#ifdef ENABLE_IPV6 - struct sockaddr_in6 add; -#else - struct sockaddr_in add; -#endif - -#ifdef __hpux - int gsize = sizeof(add); -#else - socklen_t gsize = sizeof(add); -#endif - bindworked = TRUE; - - if(getsockname(sockfd, (struct sockaddr *) &add, - &gsize)<0) { - failf(data, "getsockname() failed"); - return CURLE_HTTP_PORT_FAILED; - } - } - - if(!bindworked) { - failf(data, "%s", Curl_strerror(conn, Curl_ourerrno())); - return CURLE_HTTP_PORT_FAILED; - } - - } /* end of if h */ - else { - failf(data,"could't find my own IP address (%s)", myhost); - return CURLE_HTTP_PORT_FAILED; - } - } /* end of inet_addr */ - - else { - failf(data, "could't find my own IP address (%s)", myhost); - return CURLE_HTTP_PORT_FAILED; - } - - return CURLE_OK; - - } /* end of device selection support */ -#endif /* end of HAVE_INET_NTOA */ - - return CURLE_HTTP_PORT_FAILED; -} - -/* - * verifyconnect() returns TRUE if the connect really has happened. - */ -static bool verifyconnect(curl_socket_t sockfd, int *error) -{ - bool rc; -#ifdef SO_ERROR - int err = 0; -#ifdef __hpux - int errSize = sizeof(err); -#else - socklen_t errSize = sizeof(err); -#endif - - -#ifdef WIN32 - /* - * In October 2003 we effectively nullified this function on Windows due to - * problems with it using all CPU in multi-threaded cases. - * - * In May 2004, we bring it back to offer more info back on connect failures. - * Gisle Vanem could reproduce the former problems with this function, but - * could avoid them by adding this SleepEx() call below: - * - * "I don't have Rational Quantify, but the hint from his post was - * ntdll::NtRemoveIoCompletion(). So I'd assume the SleepEx (or maybe - * just Sleep(0) would be enough?) would release whatever - * mutex/critical-section the ntdll call is waiting on. - * - * Someone got to verify this on Win-NT 4.0, 2000." - */ - SleepEx(0, FALSE); -#endif - - if( -1 == getsockopt(sockfd, SOL_SOCKET, SO_ERROR, - (void *)&err, &errSize)) - err = Curl_ourerrno(); - - if ((0 == err) || (EISCONN == err)) - /* we are connected, awesome! */ - rc = TRUE; - else - /* This wasn't a successful connect */ - rc = FALSE; - if (error) - *error = err; -#else - (void)sockfd; - if (error) - *error = Curl_ourerrno(); -#endif - return rc; -} - -/* Used within the multi interface. Try next IP address, return TRUE if no - more address exists */ -static bool trynextip(struct connectdata *conn, - int sockindex, - bool *connected) -{ - curl_socket_t sockfd; - Curl_addrinfo *ai; - - if(sockindex != FIRSTSOCKET) - return TRUE; /* no next */ - - /* try the next address */ - ai = conn->ip_addr->ai_next; - - while (ai) { - sockfd = singleipconnect(conn, ai, 0L, connected); - if(sockfd != CURL_SOCKET_BAD) { - /* store the new socket descriptor */ - conn->sock[sockindex] = sockfd; - conn->ip_addr = ai; - return FALSE; - } - ai = ai->ai_next; - } - return TRUE; -} - -/* - * Curl_is_connected() is used from the multi interface to check if the - * firstsocket has connected. - */ - -CURLcode Curl_is_connected(struct connectdata *conn, - int sockindex, - bool *connected) -{ - int rc; - struct SessionHandle *data = conn->data; - CURLcode code = CURLE_OK; - curl_socket_t sockfd = conn->sock[sockindex]; - long allow = DEFAULT_CONNECT_TIMEOUT; - long has_passed; - - curlassert(sockindex >= FIRSTSOCKET && sockindex <= SECONDARYSOCKET); - - *connected = FALSE; /* a very negative world view is best */ - - /* Evaluate in milliseconds how much time that has passed */ - 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) - allow = data->set.timeout*1000; - else - allow = data->set.connecttimeout*1000; - } - else if(data->set.timeout) { - allow = data->set.timeout*1000; - } - else if(data->set.connecttimeout) { - allow = data->set.connecttimeout*1000; - } - - if(has_passed > allow ) { - /* time-out, bail out, go home */ - failf(data, "Connection time-out after %ld ms", has_passed); - return CURLE_OPERATION_TIMEOUTED; - } - if(conn->bits.tcpconnect) { - /* we are connected already! */ - *connected = TRUE; - return CURLE_OK; - } - - /* check for connect without timeout as we want to return immediately */ - rc = waitconnect(sockfd, 0); - - if(WAITCONN_CONNECTED == rc) { - if (verifyconnect(sockfd, NULL)) { - /* we are connected, awesome! */ - *connected = TRUE; - return CURLE_OK; - } - /* nope, not connected for real */ - infof(data, "Connection failed\n"); - if(trynextip(conn, sockindex, connected)) { - code = CURLE_COULDNT_CONNECT; - } - } - else if(WAITCONN_TIMEOUT != rc) { - /* nope, not connected */ - infof(data, "Connection failed\n"); - if(trynextip(conn, sockindex, connected)) { - int error = Curl_ourerrno(); - failf(data, "Failed connect to %s:%d; %s", - conn->host.name, conn->port, Curl_strerror(conn,error)); - code = CURLE_COULDNT_CONNECT; - } - } - /* - * If the connection failed here, we should attempt to connect to the "next - * address" for the given host. - */ - - return code; -} - -static void tcpnodelay(struct connectdata *conn, - curl_socket_t sockfd) -{ -#ifdef TCP_NODELAY - struct SessionHandle *data= conn->data; - socklen_t onoff = (socklen_t) data->set.tcp_nodelay; - if(setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (void *)&onoff, - sizeof(onoff)) < 0) - infof(data, "Could not set TCP_NODELAY: %s\n", - Curl_strerror(conn, Curl_ourerrno())); - else - infof(data,"TCP_NODELAY set\n"); -#else - (void)conn; - (void)sockfd; -#endif -} - -/* singleipconnect() connects to the given IP only, and it may return without - having connected if used from the multi interface. */ -static curl_socket_t -singleipconnect(struct connectdata *conn, - Curl_addrinfo *ai, - long timeout_ms, - bool *connected) -{ - char addr_buf[128]; - int rc; - int error; - bool conected; - struct SessionHandle *data = conn->data; - curl_socket_t sockfd = socket(ai->ai_family, ai->ai_socktype, - ai->ai_protocol); - if (sockfd == CURL_SOCKET_BAD) - return CURL_SOCKET_BAD; - - *connected = FALSE; /* default is not connected */ - - Curl_printable_address(ai, addr_buf, sizeof(addr_buf)); - infof(data, " Trying %s... ", addr_buf); - - if(data->set.tcp_nodelay) - tcpnodelay(conn, sockfd); - - if(conn->data->set.device) { - /* user selected to bind the outgoing socket to a specified "device" - before doing connect */ - CURLcode res = bindlocal(conn, sockfd); - if(res) - return res; - } - - /* set socket non-blocking */ - Curl_nonblock(sockfd, TRUE); - - rc = connect(sockfd, ai->ai_addr, ai->ai_addrlen); - - if(-1 == rc) { - error = Curl_ourerrno(); - - switch (error) { - case EINPROGRESS: - case EWOULDBLOCK: -#if defined(EAGAIN) && EAGAIN != EWOULDBLOCK - /* On some platforms EAGAIN and EWOULDBLOCK are the - * same value, and on others they are different, hence - * the odd #if - */ - case EAGAIN: -#endif - rc = waitconnect(sockfd, timeout_ms); - break; - default: - /* unknown error, fallthrough and try another address! */ - failf(data, "Failed to connect to %s: %s", - addr_buf, Curl_strerror(conn,error)); - break; - } - } - - /* The 'WAITCONN_TIMEOUT == rc' comes from the waitconnect(), and not from - connect(). We can be sure of this since connect() cannot return 1. */ - if((WAITCONN_TIMEOUT == rc) && - (data->state.used_interface == Curl_if_multi)) { - /* Timeout when running the multi interface */ - return sockfd; - } - - conected = verifyconnect(sockfd, &error); - - if(!rc && conected) { - /* we are connected, awesome! */ - *connected = TRUE; /* this is a true connect */ - infof(data, "connected\n"); - return sockfd; - } - else if(WAITCONN_TIMEOUT == rc) - infof(data, "Timeout\n"); - else - infof(data, "%s\n", Curl_strerror(conn, error)); - - /* connect failed or timed out */ - sclose(sockfd); - - return CURL_SOCKET_BAD; -} - -/* - * TCP connect to the given host with timeout, proxy or remote doesn't matter. - * There might be more than one IP address to try out. Fill in the passed - * pointer with the connected socket. - */ - -CURLcode Curl_connecthost(struct connectdata *conn, /* context */ - struct Curl_dns_entry *remotehost, /* use this one */ - curl_socket_t *sockconn, /* the connected socket */ - Curl_addrinfo **addr, /* the one we used */ - bool *connected) /* really connected? */ -{ - struct SessionHandle *data = conn->data; - curl_socket_t sockfd = CURL_SOCKET_BAD; - int aliasindex; - int num_addr; - Curl_addrinfo *ai; - Curl_addrinfo *curr_addr; - - struct timeval after; - struct timeval before = Curl_tvnow(); - - /************************************************************* - * Figure out what maximum time we have left - *************************************************************/ - long timeout_ms= DEFAULT_CONNECT_TIMEOUT; - long timeout_per_addr; - - *connected = FALSE; /* default to not connected */ - - if(data->set.timeout || data->set.connecttimeout) { - long has_passed; - - /* Evaluate in milliseconds how much time that has passed */ - has_passed = Curl_tvdiff(Curl_tvnow(), data->progress.start); - -#ifndef min -#define min(a, b) ((a) < (b) ? (a) : (b)) -#endif - - /* get the most strict timeout of the ones converted to milliseconds */ - if(data->set.timeout && data->set.connecttimeout) { - if (data->set.timeout < data->set.connecttimeout) - timeout_ms = data->set.timeout*1000; - else - timeout_ms = data->set.connecttimeout*1000; - } - else if(data->set.timeout) - timeout_ms = data->set.timeout*1000; - else - timeout_ms = data->set.connecttimeout*1000; - - /* subtract the passed time */ - timeout_ms -= has_passed; - - if(timeout_ms < 0) { - /* a precaution, no need to continue if time already is up */ - failf(data, "Connection time-out"); - return CURLE_OPERATION_TIMEOUTED; - } - } - - /* Max time for each address */ - num_addr = Curl_num_addresses(remotehost->addr); - timeout_per_addr = timeout_ms / num_addr; - - ai = remotehost->addr; - - /* Below is the loop that attempts to connect to all IP-addresses we - * know for the given host. One by one until one IP succeeds. - */ - - if(data->state.used_interface == Curl_if_multi) - /* don't hang when doing multi */ - timeout_per_addr = timeout_ms = 0; - - /* - * Connecting with a Curl_addrinfo chain - */ - for (curr_addr = ai, aliasindex=0; curr_addr; - curr_addr = curr_addr->ai_next, aliasindex++) { - - /* start connecting to the IP curr_addr points to */ - sockfd = singleipconnect(conn, curr_addr, timeout_per_addr, connected); - - if(sockfd != CURL_SOCKET_BAD) - break; - - /* get a new timeout for next attempt */ - after = Curl_tvnow(); - timeout_ms -= Curl_tvdiff(after, before); - if(timeout_ms < 0) { - failf(data, "connect() timed out!"); - return CURLE_OPERATION_TIMEOUTED; - } - before = after; - } /* end of connect-to-each-address loop */ - - if (sockfd == CURL_SOCKET_BAD) { - /* no good connect was made */ - *sockconn = CURL_SOCKET_BAD; - return CURLE_COULDNT_CONNECT; - } - - /* leave the socket in non-blocking mode */ - - /* store the address we use */ - if(addr) - *addr = curr_addr; - - /* allow NULL-pointers to get passed in */ - if(sockconn) - *sockconn = sockfd; /* the socket descriptor we've connected */ - - return CURLE_OK; -} diff --git a/Source/CTest/Curl/connect.h b/Source/CTest/Curl/connect.h deleted file mode 100644 index d39495c..0000000 --- a/Source/CTest/Curl/connect.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef __CONNECT_H -#define __CONNECT_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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$ - ***************************************************************************/ - -int Curl_nonblock(curl_socket_t sockfd, /* operate on this */ - int nonblock /* TRUE or FALSE */); - -CURLcode Curl_is_connected(struct connectdata *conn, - int sockindex, - bool *connected); - -CURLcode Curl_connecthost(struct connectdata *conn, - struct Curl_dns_entry *host, /* connect to this */ - curl_socket_t *sockconn, /* not set if error */ - Curl_addrinfo **addr, /* the one we used */ - bool *connected /* truly connected? */ - ); - -int Curl_ourerrno(void); - -#define DEFAULT_CONNECT_TIMEOUT 300000 /* milliseconds == five minutes */ - -#endif diff --git a/Source/CTest/Curl/content_encoding.c b/Source/CTest/Curl/content_encoding.c deleted file mode 100644 index b8c68bd..0000000 --- a/Source/CTest/Curl/content_encoding.c +++ /dev/null @@ -1,363 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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 <stdlib.h> -#include <string.h> - -#include "urldata.h" -#include <curl/curl.h> -#include "sendf.h" -#include "content_encoding.h" -#include "curl_memory.h" - -#include "memdebug.h" - -#define DSIZ 0x10000 /* buffer size for decompressed data */ - -#define GZIP_MAGIC_0 0x1f -#define GZIP_MAGIC_1 0x8b - -/* gzip flag byte */ -#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ -#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */ -#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ -#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ -#define COMMENT 0x10 /* bit 4 set: file comment present */ -#define RESERVED 0xE0 /* bits 5..7: reserved */ - -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 */ - CURLcode result = CURLE_OK; /* 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; - z->next_in = NULL; - z->avail_in = 0; - if (inflateInit(z) != Z_OK) - return process_zlib_error(data, z); - k->zlib_init = 1; - } - - /* Set the compressed input when this function is called */ - z->next_in = (Bytef *)k->str; - z->avail_in = (uInt)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) { - if (DSIZ - z->avail_out) { - 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)); - } - } -} - -/* Skip over the gzip header */ -static enum { - GZIP_OK, - GZIP_BAD, - GZIP_UNDERFLOW -} check_gzip_header(unsigned char const *data, ssize_t len, ssize_t *headerlen) -{ - int method, flags; - const ssize_t totallen = len; - - /* The shortest header is 10 bytes */ - if (len < 10) - return GZIP_UNDERFLOW; - - if ((data[0] != GZIP_MAGIC_0) || (data[1] != GZIP_MAGIC_1)) - return GZIP_BAD; - - method = data[2]; - flags = data[3]; - - if (method != Z_DEFLATED || (flags & RESERVED) != 0) { - /* Can't handle this compression method or unknown flag */ - return GZIP_BAD; - } - - /* Skip over time, xflags, OS code and all previous bytes */ - len -= 10; - data += 10; - - if (flags & EXTRA_FIELD) { - ssize_t extra_len; - - if (len < 2) - return GZIP_UNDERFLOW; - - extra_len = (data[1] << 8) | data[0]; - - if (len < (extra_len+2)) - return GZIP_UNDERFLOW; - - len -= (extra_len + 2); - } - - if (flags & ORIG_NAME) { - /* Skip over NUL-terminated file name */ - while (len && *data) { - --len; - ++data; - } - if (!len || *data) - return GZIP_UNDERFLOW; - - /* Skip over the NUL */ - --len; - ++data; - } - - if (flags & COMMENT) { - /* Skip over NUL-terminated comment */ - while (len && *data) { - --len; - ++data; - } - if (!len || *data) - return GZIP_UNDERFLOW; - - /* Skip over the NUL */ - --len; - ++data; - } - - if (flags & HEAD_CRC) { - if (len < 2) - return GZIP_UNDERFLOW; - - len -= 2; - data += 2; - } - - *headerlen = totallen - len; - return GZIP_OK; -} - -CURLcode -Curl_unencode_gzip_write(struct SessionHandle *data, - struct Curl_transfer_keeper *k, - ssize_t nread) -{ - int status; /* zlib status */ - CURLcode result = CURLE_OK; /* 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; - z->next_in = NULL; - z->avail_in = 0; - if (inflateInit2(z, -MAX_WBITS) != Z_OK) - return process_zlib_error(data, z); - k->zlib_init = 1; /* Initial call state */ - } - - /* This next mess is to get around the potential case where there isn't - * enough data passed in to skip over the gzip header. If that happens, we - * malloc a block and copy what we have then wait for the next call. If - * there still isn't enough (this is definitely a worst-case scenario), we - * make the block bigger, copy the next part in and keep waiting. - */ - - /* Skip over gzip header? */ - if (k->zlib_init == 1) { - /* Initial call state */ - ssize_t hlen; - - switch (check_gzip_header((unsigned char *)k->str, nread, &hlen)) { - case GZIP_OK: - z->next_in = (Bytef *)k->str + hlen; - z->avail_in = (uInt)(nread - hlen); - k->zlib_init = 3; /* Inflating stream state */ - break; - - case GZIP_UNDERFLOW: - /* We need more data so we can find the end of the gzip header. It's - * possible that the memory block we malloc here will never be freed if - * the transfer abruptly aborts after this point. Since it's unlikely - * that circumstances will be right for this code path to be followed in - * the first place, and it's even more unlikely for a transfer to fail - * immediately afterwards, it should seldom be a problem. - */ - z->avail_in = (uInt)nread; - z->next_in = malloc(z->avail_in); - if (z->next_in == NULL) { - return exit_zlib(z, &k->zlib_init, CURLE_OUT_OF_MEMORY); - } - memcpy(z->next_in, k->str, z->avail_in); - k->zlib_init = 2; /* Need more gzip header data state */ - /* We don't have any data to inflate yet */ - return CURLE_OK; - - case GZIP_BAD: - default: - return exit_zlib(z, &k->zlib_init, process_zlib_error(data, z)); - } - - } - else if (k->zlib_init == 2) { - /* Need more gzip header data state */ - ssize_t hlen; - unsigned char *oldblock = z->next_in; - - z->avail_in += nread; - z->next_in = realloc(z->next_in, z->avail_in); - if (z->next_in == NULL) { - free(oldblock); - return exit_zlib(z, &k->zlib_init, CURLE_OUT_OF_MEMORY); - } - /* Append the new block of data to the previous one */ - memcpy(z->next_in + z->avail_in - nread, k->str, nread); - - switch (check_gzip_header(z->next_in, z->avail_in, &hlen)) { - case GZIP_OK: - /* This is the zlib stream data */ - free(z->next_in); - /* Don't point into the malloced block since we just freed it */ - z->next_in = (Bytef *)k->str + hlen + nread - z->avail_in; - z->avail_in = (uInt)(z->avail_in - hlen); - k->zlib_init = 3; /* Inflating stream state */ - break; - - case GZIP_UNDERFLOW: - /* We still don't have any data to inflate! */ - return CURLE_OK; - - case GZIP_BAD: - default: - free(z->next_in); - return exit_zlib(z, &k->zlib_init, process_zlib_error(data, z)); - } - - } - else { - /* Inflating stream state */ - z->next_in = (Bytef *)k->str; - z->avail_in = (uInt)nread; - } - - if (z->avail_in == 0) { - /* We don't have any data to inflate; wait until next time */ - return CURLE_OK; - } - - /* 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) { - if(DSIZ - z->avail_out) { - 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 */ - /* We should really check the gzip CRC here */ - 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 */ diff --git a/Source/CTest/Curl/content_encoding.h b/Source/CTest/Curl/content_encoding.h deleted file mode 100644 index a65dbd2..0000000 --- a/Source/CTest/Curl/content_encoding.h +++ /dev/null @@ -1,41 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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" - -/* - * Comma-separated list all supported Content-Encodings ('identity' is implied) - */ -#ifdef HAVE_LIBZ -#define ALL_CONTENT_ENCODINGS "deflate, gzip" -#else -#define ALL_CONTENT_ENCODINGS "identity" -#endif - -CURLcode Curl_unencode_deflate_write(struct SessionHandle *data, - struct Curl_transfer_keeper *k, - ssize_t nread); - -CURLcode -Curl_unencode_gzip_write(struct SessionHandle *data, - struct Curl_transfer_keeper *k, - ssize_t nread); diff --git a/Source/CTest/Curl/cookie.c b/Source/CTest/Curl/cookie.c deleted file mode 100644 index 3ba5627..0000000 --- a/Source/CTest/Curl/cookie.c +++ /dev/null @@ -1,879 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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$ - ***************************************************************************/ - -/*** - - -RECEIVING COOKIE INFORMATION -============================ - -struct CookieInfo *cookie_init(char *file); - - Inits a cookie struct to store data in a local file. This is always - called before any cookies are set. - -int cookies_set(struct CookieInfo *cookie, char *cookie_line); - - The 'cookie_line' parameter is a full "Set-cookie:" line as - received from a server. - - The function need to replace previously stored lines that this new - line superceeds. - - It may remove lines that are expired. - - It should return an indication of success/error. - - -SENDING COOKIE INFORMATION -========================== - -struct Cookies *cookie_getlist(struct CookieInfo *cookie, - char *host, char *path, bool secure); - - For a given host and path, return a linked list of cookies that - the client should send to the server if used now. The secure - boolean informs the cookie if a secure connection is achieved or - not. - - It shall only return cookies that haven't expired. - - -Example set of cookies: - - Set-cookie: PRODUCTINFO=webxpress; domain=.fidelity.com; path=/; secure - Set-cookie: PERSONALIZE=none;expires=Monday, 13-Jun-1988 03:04:55 GMT; - domain=.fidelity.com; path=/ftgw; secure - Set-cookie: FidHist=none;expires=Monday, 13-Jun-1988 03:04:55 GMT; - domain=.fidelity.com; path=/; secure - Set-cookie: FidOrder=none;expires=Monday, 13-Jun-1988 03:04:55 GMT; - domain=.fidelity.com; path=/; secure - Set-cookie: DisPend=none;expires=Monday, 13-Jun-1988 03:04:55 GMT; - domain=.fidelity.com; path=/; secure - Set-cookie: FidDis=none;expires=Monday, 13-Jun-1988 03:04:55 GMT; - domain=.fidelity.com; path=/; secure - Set-cookie: - Session_Key@6791a9e0-901a-11d0-a1c8-9b012c88aa77=none;expires=Monday, - 13-Jun-1988 03:04:55 GMT; domain=.fidelity.com; path=/; secure -****/ - - -#include "setup.h" - -#ifndef CURL_DISABLE_HTTP - -#include <stdlib.h> -#include <string.h> -#include <ctype.h> - -#include "urldata.h" -#include "cookie.h" -#include "getdate.h" -#include "strequal.h" -#include "strtok.h" -#include "sendf.h" -#include "curl_memory.h" - -/* The last #include file should be: */ -#ifdef CURLDEBUG -#include "memdebug.h" -#endif - -static void freecookie(struct Cookie *co) -{ - if(co->expirestr) - free(co->expirestr); - 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); -} - -static bool tailmatch(const char *little, const char *bigone) -{ - size_t littlelen = strlen(little); - size_t biglen = strlen(bigone); - - if(littlelen > biglen) - return FALSE; - - return (bool)strequal(little, bigone+biglen-littlelen); -} - -/**************************************************************************** - * - * Curl_cookie_add() - * - * Add a single cookie line to the cookie keeping object. - * - ***************************************************************************/ - -struct Cookie * -Curl_cookie_add(struct SessionHandle *data, - /* The 'data' pointer here may be NULL at times, and thus - must only be used very carefully for things that can deal - with data being NULL. Such as infof() and similar */ - - struct CookieInfo *c, - bool httpheader, /* TRUE if HTTP header-style line */ - char *lineptr, /* first character of the line */ - char *domain, /* default domain */ - char *path) /* full path used when this cookie is set, - used to get default path for the cookie - unless set */ -{ - struct Cookie *clist; - char *what; - char name[MAX_NAME]; - char *ptr; - char *semiptr; - struct Cookie *co; - struct Cookie *lastc=NULL; - time_t now = time(NULL); - bool replace_old; - bool badcookie = FALSE; /* cookies are good by default. mmmmm yummy */ - - /* First, alloc and init a new struct for it */ - co = (struct Cookie *)calloc(sizeof(struct Cookie), 1); - if(!co) - return NULL; /* bail out if we're this low on memory */ - - if(httpheader) { - /* This line was read off a HTTP-header */ - char *sep; - - what = malloc(MAX_COOKIE_LINE); - if(!what) { - free(co); - return NULL; - } - - semiptr=strchr(lineptr, ';'); /* first, find a semicolon */ - - while(*lineptr && isspace((int)*lineptr)) - lineptr++; - - ptr = lineptr; - do { - /* we have a <what>=<this> pair or a 'secure' word here */ - sep = strchr(ptr, '='); - if(sep && (!semiptr || (semiptr>sep)) ) { - /* - * There is a = sign and if there was a semicolon too, which make sure - * that the semicolon comes _after_ the equal sign. - */ - - name[0]=what[0]=0; /* init the buffers */ - if(1 <= sscanf(ptr, "%" MAX_NAME_TXT "[^;=]=%" - MAX_COOKIE_LINE_TXT "[^;\r\n]", - name, what)) { - /* this is a <name>=<what> pair */ - - char *whatptr; - - /* Strip off trailing whitespace from the 'what' */ - size_t len=strlen(what); - while(len && isspace((int)what[len-1])) { - what[len-1]=0; - len--; - } - - /* Skip leading whitespace from the 'what' */ - whatptr=what; - while(isspace((int)*whatptr)) { - whatptr++; - } - - if(strequal("path", name)) { - co->path=strdup(whatptr); - if(!co->path) { - badcookie = TRUE; /* out of memory bad */ - break; - } - } - else if(strequal("domain", name)) { - /* note that this name may or may not have a preceeding dot, but - we don't care about that, we treat the names the same anyway */ - - const char *domptr=whatptr; - int dotcount=1; - - /* Count the dots, we need to make sure that there are enough - of them. */ - - if('.' == whatptr[0]) - /* don't count the initial dot, assume it */ - domptr++; - - do { - domptr = strchr(domptr, '.'); - if(domptr) { - domptr++; - dotcount++; - } - } while(domptr); - - /* The original Netscape cookie spec defined that this domain name - MUST have three dots (or two if one of the seven holy TLDs), - but it seems that these kinds of cookies are in use "out there" - so we cannot be that strict. I've therefore lowered the check - to not allow less than two dots. */ - - if(dotcount < 2) { - /* Received and skipped a cookie with a domain using too few - dots. */ - badcookie=TRUE; /* mark this as a bad cookie */ - infof(data, "skipped cookie with illegal dotcount domain: %s\n", - whatptr); - } - else { - /* Now, we make sure that our host is within the given domain, - or the given domain is not valid and thus cannot be set. */ - - if('.' == whatptr[0]) - whatptr++; /* ignore preceeding dot */ - - if(!domain || tailmatch(whatptr, domain)) { - const char *tailptr=whatptr; - if(tailptr[0] == '.') - tailptr++; - co->domain=strdup(tailptr); /* don't prefix w/dots - internally */ - if(!co->domain) { - badcookie = TRUE; - break; - } - co->tailmatch=TRUE; /* we always do that if the domain name was - given */ - } - else { - /* we did not get a tailmatch and then the attempted set domain - is not a domain to which the current host belongs. Mark as - bad. */ - badcookie=TRUE; - infof(data, "skipped cookie with bad tailmatch domain: %s\n", - whatptr); - } - } - } - else if(strequal("version", name)) { - co->version=strdup(whatptr); - if(!co->version) { - badcookie = TRUE; - break; - } - } - else if(strequal("max-age", name)) { - /* Defined in RFC2109: - - Optional. The Max-Age attribute defines the lifetime of the - cookie, in seconds. The delta-seconds value is a decimal non- - negative integer. After delta-seconds seconds elapse, the - client should discard the cookie. A value of zero means the - cookie should be discarded immediately. - - */ - co->maxage = strdup(whatptr); - if(!co->maxage) { - badcookie = TRUE; - break; - } - co->expires = - atoi((*co->maxage=='\"')?&co->maxage[1]:&co->maxage[0]) + now; - } - else if(strequal("expires", name)) { - co->expirestr=strdup(whatptr); - if(!co->expirestr) { - badcookie = TRUE; - break; - } - co->expires = curl_getdate(what, &now); - } - else if(!co->name) { - co->name = strdup(name); - co->value = strdup(whatptr); - if(!co->name || !co->value) { - badcookie = TRUE; - break; - } - } - /* - else this is the second (or more) name we don't know - about! */ - } - else { - /* this is an "illegal" <what>=<this> pair */ - } - } - else { - if(sscanf(ptr, "%" MAX_COOKIE_LINE_TXT "[^;\r\n]", - what)) { - if(strequal("secure", what)) - co->secure = TRUE; - /* else, - unsupported keyword without assign! */ - - } - } - if(!semiptr || !*semiptr) { - /* we already know there are no more cookies */ - semiptr = NULL; - continue; - } - - ptr=semiptr+1; - while(ptr && *ptr && isspace((int)*ptr)) - ptr++; - semiptr=strchr(ptr, ';'); /* now, find the next semicolon */ - - if(!semiptr && *ptr) - /* There are no more semicolons, but there's a final name=value pair - coming up */ - semiptr=strchr(ptr, '\0'); - } while(semiptr); - - if(!badcookie && !co->domain) { - if(domain) { - /* no domain was given in the header line, set the default */ - co->domain=strdup(domain); - if(!co->domain) - badcookie = TRUE; - } - } - - if(!badcookie && !co->path && path) { - /* no path was given in the header line, set the default */ - char *endslash = strrchr(path, '/'); - if(endslash) { - size_t pathlen = endslash-path+1; /* include the ending slash */ - co->path=malloc(pathlen+1); /* one extra for the zero byte */ - if(co->path) { - memcpy(co->path, path, pathlen); - co->path[pathlen]=0; /* zero terminate */ - } - else - badcookie = TRUE; - } - } - - free(what); - - if(badcookie || !co->name) { - /* we didn't get a cookie name or a bad one, - this is an illegal line, bail out */ - freecookie(co); - return NULL; - } - - } - else { - /* This line is NOT a HTTP header style line, we do offer support for - reading the odd netscape cookies-file format here */ - char *firstptr; - char *tok_buf; - int fields; - - if(lineptr[0]=='#') { - /* don't even try the comments */ - free(co); - return NULL; - } - /* strip off the possible end-of-line characters */ - ptr=strchr(lineptr, '\r'); - if(ptr) - *ptr=0; /* clear it */ - ptr=strchr(lineptr, '\n'); - if(ptr) - *ptr=0; /* clear it */ - - firstptr=strtok_r(lineptr, "\t", &tok_buf); /* tokenize it on the TAB */ - - /* Here's a quick check to eliminate normal HTTP-headers from this */ - if(!firstptr || strchr(firstptr, ':')) { - free(co); - return NULL; - } - - /* Now loop through the fields and init the struct we already have - allocated */ - for(ptr=firstptr, fields=0; ptr && !badcookie; - ptr=strtok_r(NULL, "\t", &tok_buf), fields++) { - switch(fields) { - case 0: - if(ptr[0]=='.') /* skip preceeding dots */ - ptr++; - co->domain = strdup(ptr); - if(!co->domain) - badcookie = TRUE; - break; - case 1: - /* This field got its explanation on the 23rd of May 2001 by - Andrés García: - - flag: A TRUE/FALSE value indicating if all machines within a given - domain can access the variable. This value is set automatically by - the browser, depending on the value you set for the domain. - - As far as I can see, it is set to true when the cookie says - .domain.com and to false when the domain is complete www.domain.com - */ - co->tailmatch=(bool)strequal(ptr, "TRUE"); /* store information */ - break; - case 2: - /* It turns out, that sometimes the file format allows the path - field to remain not filled in, we try to detect this and work - around it! Andrés García made us aware of this... */ - if (strcmp("TRUE", ptr) && strcmp("FALSE", ptr)) { - /* only if the path doesn't look like a boolean option! */ - co->path = strdup(ptr); - if(!co->path) - badcookie = TRUE; - break; - } - /* this doesn't look like a path, make one up! */ - co->path = strdup("/"); - if(!co->path) - badcookie = TRUE; - fields++; /* add a field and fall down to secure */ - /* FALLTHROUGH */ - case 3: - co->secure = (bool)strequal(ptr, "TRUE"); - break; - case 4: - co->expires = atoi(ptr); - break; - case 5: - co->name = strdup(ptr); - if(!co->name) - badcookie = TRUE; - break; - case 6: - co->value = strdup(ptr); - if(!co->value) - badcookie = TRUE; - break; - } - } - if(6 == fields) { - /* we got a cookie with blank contents, fix it */ - co->value = strdup(""); - if(!co->value) - badcookie = TRUE; - else - fields++; - } - - if(!badcookie && (7 != fields)) - /* we did not find the sufficient number of fields */ - badcookie = TRUE; - - if(badcookie) { - freecookie(co); - return NULL; - } - - } - - if(!c->running && /* read from a file */ - c->newsession && /* clean session cookies */ - !co->expires) { /* this is a session cookie since it doesn't expire! */ - freecookie(co); - return NULL; - } - - co->livecookie = c->running; - - /* now, we have parsed the incoming line, we must now check if this - superceeds an already existing cookie, which it may if the previous have - the same domain and path as this */ - - clist = c->cookies; - replace_old = FALSE; - while(clist) { - if(strequal(clist->name, co->name)) { - /* the names are identical */ - - if(clist->domain && co->domain) { - if(strequal(clist->domain, co->domain)) - /* The domains are identical */ - replace_old=TRUE; - } - else if(!clist->domain && !co->domain) - replace_old = TRUE; - - if(replace_old) { - /* the domains were identical */ - - if(clist->path && co->path) { - if(strequal(clist->path, co->path)) { - replace_old = TRUE; - } - else - replace_old = FALSE; - } - else if(!clist->path && !co->path) - replace_old = TRUE; - else - replace_old = FALSE; - - } - - if(replace_old && !co->livecookie && clist->livecookie) { - /* Both cookies matched fine, except that the already present - cookie is "live", which means it was set from a header, while - the new one isn't "live" and thus only read from a file. We let - live cookies stay alive */ - - /* Free the newcomer and get out of here! */ - freecookie(co); - return NULL; - } - - if(replace_old) { - co->next = clist->next; /* get the next-pointer first */ - - /* then free all the old pointers */ - if(clist->name) - free(clist->name); - if(clist->value) - free(clist->value); - if(clist->domain) - free(clist->domain); - if(clist->path) - free(clist->path); - if(clist->expirestr) - free(clist->expirestr); - - if(clist->version) - free(clist->version); - if(clist->maxage) - free(clist->maxage); - - *clist = *co; /* then store all the new data */ - - free(co); /* free the newly alloced memory */ - co = clist; /* point to the previous struct instead */ - - /* We have replaced a cookie, now skip the rest of the list but - make sure the 'lastc' pointer is properly set */ - do { - lastc = clist; - clist = clist->next; - } while(clist); - break; - } - } - lastc = clist; - clist = clist->next; - } - - if(c->running) - /* Only show this when NOT reading the cookies from a file */ - infof(data, "%s cookie %s=\"%s\" for domain %s, path %s, expire %d\n", - replace_old?"Replaced":"Added", co->name, co->value, - co->domain, co->path, co->expires); - - if(!replace_old) { - /* then make the last item point on this new one */ - if(lastc) - lastc->next = co; - else - c->cookies = co; - } - - c->numcookies++; /* one more cookie in the jar */ - return co; -} - -/***************************************************************************** - * - * Curl_cookie_init() - * - * Inits a cookie struct to read data from a local file. This is always - * called before any cookies are set. File may be NULL. - * - * If 'newsession' is TRUE, discard all "session cookies" on read from file. - * - ****************************************************************************/ -struct CookieInfo *Curl_cookie_init(struct SessionHandle *data, - char *file, - struct CookieInfo *inc, - bool newsession) -{ - struct CookieInfo *c; - FILE *fp; - bool fromfile=TRUE; - - if(NULL == inc) { - /* we didn't get a struct, create one */ - c = (struct CookieInfo *)calloc(1, sizeof(struct CookieInfo)); - if(!c) - return NULL; /* failed to get memory */ - c->filename = strdup(file?file:"none"); /* copy the name just in case */ - } - else { - /* we got an already existing one, use that */ - c = inc; - } - c->running = FALSE; /* this is not running, this is init */ - - if(file && strequal(file, "-")) { - fp = stdin; - fromfile=FALSE; - } - else - fp = file?fopen(file, "r"):NULL; - - c->newsession = newsession; /* new session? */ - - if(fp) { - char *lineptr; - bool headerline; - - char *line = (char *)malloc(MAX_COOKIE_LINE); - if(line) { - while(fgets(line, MAX_COOKIE_LINE, fp)) { - if(checkprefix("Set-Cookie:", line)) { - /* This is a cookie line, get it! */ - lineptr=&line[11]; - headerline=TRUE; - } - else { - lineptr=line; - headerline=FALSE; - } - while(*lineptr && isspace((int)*lineptr)) - lineptr++; - - Curl_cookie_add(data, c, headerline, lineptr, NULL, NULL); - } - free(line); /* free the line buffer */ - } - if(fromfile) - fclose(fp); - } - - c->running = TRUE; /* now, we're running */ - - return c; -} - -/***************************************************************************** - * - * Curl_cookie_getlist() - * - * For a given host and path, return a linked list of cookies that the - * client should send to the server if used now. The secure boolean informs - * the cookie if a secure connection is achieved or not. - * - * It shall only return cookies that haven't expired. - * - ****************************************************************************/ - -struct Cookie *Curl_cookie_getlist(struct CookieInfo *c, - char *host, char *path, bool secure) -{ - struct Cookie *newco; - struct Cookie *co; - time_t now = time(NULL); - struct Cookie *mainco=NULL; - - if(!c || !c->cookies) - return NULL; /* no cookie struct or no cookies in the struct */ - - co = c->cookies; - - while(co) { - /* only process this cookie if it is not expired or had no expire - date AND that if the cookie requires we're secure we must only - continue if we are! */ - if( (co->expires<=0 || (co->expires> now)) && - (co->secure?secure:TRUE) ) { - - /* now check if the domain is correct */ - if(!co->domain || - (co->tailmatch && tailmatch(co->domain, host)) || - (!co->tailmatch && strequal(host, co->domain)) ) { - /* the right part of the host matches the domain stuff in the - cookie data */ - - /* now check the left part of the path with the cookies path - requirement */ - if(!co->path || - checkprefix(co->path, path) ) { - - /* and now, we know this is a match and we should create an - entry for the return-linked-list */ - - newco = (struct Cookie *)malloc(sizeof(struct Cookie)); - if(newco) { - /* first, copy the whole source cookie: */ - memcpy(newco, co, sizeof(struct Cookie)); - - /* then modify our next */ - newco->next = mainco; - - /* point the main to us */ - mainco = newco; - } - else { - /* failure, clear up the allocated chain and return NULL */ - while(mainco) { - co = mainco->next; - free(mainco); - mainco = co; - } - - return NULL; - } - } - } - } - co = co->next; - } - - return mainco; /* return the new list */ -} - - -/***************************************************************************** - * - * Curl_cookie_freelist() - * - * Free a list of cookies previously returned by Curl_cookie_getlist(); - * - ****************************************************************************/ - -void Curl_cookie_freelist(struct Cookie *co) -{ - struct Cookie *next; - if(co) { - while(co) { - next = co->next; - free(co); /* we only free the struct since the "members" are all - just copied! */ - co = next; - } - } -} - -/***************************************************************************** - * - * Curl_cookie_cleanup() - * - * Free a "cookie object" previous created with cookie_init(). - * - ****************************************************************************/ -void Curl_cookie_cleanup(struct CookieInfo *c) -{ - struct Cookie *co; - struct Cookie *next; - if(c) { - if(c->filename) - free(c->filename); - co = c->cookies; - - while(co) { - next = co->next; - freecookie(co); - co = next; - } - free(c); /* free the base struct as well */ - } -} - -/* - * Curl_cookie_output() - * - * Writes all internally known cookies to the specified file. Specify - * "-" as file name to write to stdout. - * - * The function returns non-zero on write failure. - */ -int Curl_cookie_output(struct CookieInfo *c, char *dumphere) -{ - struct Cookie *co; - FILE *out; - bool use_stdout=FALSE; - - if((NULL == c) || (0 == c->numcookies)) - /* If there are no known cookies, we don't write or even create any - destination file */ - return 0; - - if(strequal("-", dumphere)) { - /* use stdout */ - out = stdout; - use_stdout=TRUE; - } - else { - out = fopen(dumphere, "w"); - if(!out) - return 1; /* failure */ - } - - if(c) { - fputs("# Netscape HTTP Cookie File\n" - "# http://www.netscape.com/newsref/std/cookie_spec.html\n" - "# This file was generated by libcurl! Edit at your own risk.\n\n", - out); - co = c->cookies; - - while(co) { - fprintf(out, - "%s%s\t" /* domain */ - "%s\t" /* tailmatch */ - "%s\t" /* path */ - "%s\t" /* secure */ - "%u\t" /* expires */ - "%s\t" /* name */ - "%s\n", /* value */ - - /* Make sure all domains are prefixed with a dot if they allow - tailmatching. This is Mozilla-style. */ - (co->tailmatch && co->domain && co->domain[0] != '.')? ".":"", - co->domain?co->domain:"unknown", - co->tailmatch?"TRUE":"FALSE", - co->path?co->path:"/", - co->secure?"TRUE":"FALSE", - (unsigned int)co->expires, - co->name, - co->value?co->value:""); - - co=co->next; - } - } - - if(!use_stdout) - fclose(out); - - return 0; -} - -#endif /* CURL_DISABLE_HTTP */ diff --git a/Source/CTest/Curl/cookie.h b/Source/CTest/Curl/cookie.h deleted file mode 100644 index 6f8e8e5..0000000 --- a/Source/CTest/Curl/cookie.h +++ /dev/null @@ -1,95 +0,0 @@ -#ifndef __COOKIE_H -#define __COOKIE_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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 <stdio.h> -#ifdef WIN32 -#include <time.h> -#else -#include <sys/time.h> -#endif - -#include <curl/curl.h> - -struct Cookie { - struct Cookie *next; /* next in the chain */ - char *name; /* <this> = value */ - char *value; /* name = <this> */ - char *path; /* path = <this> */ - char *domain; /* domain = <this> */ - long expires; /* expires = <this> */ - char *expirestr; /* the plain text version */ - bool tailmatch; /* weather we do tail-matchning of the domain name */ - - /* RFC 2109 keywords. Version=1 means 2109-compliant cookie sending */ - char *version; /* Version = <value> */ - char *maxage; /* Max-Age = <value> */ - - bool secure; /* whether the 'secure' keyword was used */ - bool livecookie; /* updated from a server, not a stored file */ -}; - -struct CookieInfo { - /* linked list of cookies we know of */ - struct Cookie *cookies; - - char *filename; /* file we read from/write to */ - bool running; /* state info, for cookie adding information */ - 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. RFC 2109 - section 6.3 says: - - "at least 4096 bytes per cookie (as measured by the size of the characters - that comprise the cookie non-terminal in the syntax description of the - Set-Cookie header)" - -*/ -#define MAX_COOKIE_LINE 5000 -#define MAX_COOKIE_LINE_TXT "4999" - -/* This is the maximum length of a cookie name we deal with: */ -#define MAX_NAME 1024 -#define MAX_NAME_TXT "1023" - -struct SessionHandle; -/* - * Add a cookie to the internal list of cookies. The domain and path arguments - * are only used if the header boolean is TRUE. - */ - -struct Cookie *Curl_cookie_add(struct SessionHandle *data, - struct CookieInfo *, bool header, char *line, - char *domain, char *path); - -struct CookieInfo *Curl_cookie_init(struct SessionHandle *data, - char *, struct CookieInfo *, bool); -struct Cookie *Curl_cookie_getlist(struct CookieInfo *, char *, char *, bool); -void Curl_cookie_freelist(struct Cookie *); -void Curl_cookie_cleanup(struct CookieInfo *); -int Curl_cookie_output(struct CookieInfo *, char *); - -#endif diff --git a/Source/CTest/Curl/curl.copyright b/Source/CTest/Curl/curl.copyright deleted file mode 100644 index 16ea773..0000000 --- a/Source/CTest/Curl/curl.copyright +++ /dev/null @@ -1,25 +0,0 @@ -This package was cmakified by Andy Cedilnik <andy . cedilnik @ kitware.com> - -It was downloaded from http://curl.haxx.se - -COPYRIGHT AND PERMISSION NOTICE - -Copyright (c) 1996 - 2004, Daniel Stenberg, <daniel@haxx.se>. - -All rights reserved. - -Permission to use, copy, modify, and distribute this software for any purpose -with or without fee is hereby granted, provided that the above copyright -notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN -NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE -OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall not -be used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization of the copyright holder. diff --git a/Source/CTest/Curl/curl/curl.h b/Source/CTest/Curl/curl/curl.h deleted file mode 100644 index 96c8fcc..0000000 --- a/Source/CTest/Curl/curl/curl.h +++ /dev/null @@ -1,1340 +0,0 @@ -#ifndef __CURL_CURL_H -#define __CURL_CURL_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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$ - ***************************************************************************/ - -/* If you have problems, all libcurl docs and details are found here: - http://curl.haxx.se/libcurl/ -*/ - -#include "curlver.h" /* the libcurl version defines */ - -#include <stdio.h> -#include <limits.h> - -/* The include stuff here below is mainly for time_t! */ -#ifdef vms -# include <types.h> -# include <time.h> -#else -# include <sys/types.h> -# include <time.h> -#endif /* defined (vms) */ - -typedef void CURL; - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * We want the typedef curl_off_t setup for large file support on all - * platforms. We also provide a CURL_FORMAT_OFF_T define to use in *printf - * format strings when outputting a variable of type curl_off_t. - */ -#if defined(_MSC_VER) || defined(__LCC__) -/* MSVC */ - typedef signed __int64 curl_off_t; -#define CURL_FORMAT_OFF_T "%I64d" -#else /* _MSC_VER || __LCC__ */ -#if (defined(__GNUC__) && defined(WIN32)) || defined(__WATCOMC__) -/* gcc on windows or Watcom */ - typedef long long curl_off_t; -#define CURL_FORMAT_OFF_T "%I64d" -#else /* GCC or Watcom on Windows */ - -/* "normal" POSIX approach, do note that this does not necessarily mean that - the type is >32 bits, see the SIZEOF_CURL_OFF_T define for that! */ - typedef off_t curl_off_t; - -/* Check a range of defines to detect large file support. On Linux it seems - none of these are set by default, so if you don't explicitly switches on - large file support, this define will be made for "small file" support. */ -#ifndef _FILE_OFFSET_BITS -#define _FILE_OFFSET_BITS 0 /* to prevent warnings in the check below */ -#define UNDEF_FILE_OFFSET_BITS -#endif -#ifndef FILESIZEBITS -#define FILESIZEBITS 0 /* to prevent warnings in the check below */ -#define UNDEF_FILESIZEBITS -#endif - -#if defined(_LARGE_FILES) || (_FILE_OFFSET_BITS > 32) || (FILESIZEBITS > 32) \ - || defined(_LARGEFILE_SOURCE) || defined(_LARGEFILE64_SOURCE) - /* For now, we assume at least one of these to be set for large files to - work! */ -#define CURL_FORMAT_OFF_T "%lld" -#else /* LARGE_FILE support */ -#define CURL_FORMAT_OFF_T "%ld" -#endif -#endif /* GCC or Watcom on Windows */ -#endif /* _MSC_VER || __LCC__ */ - -#ifdef UNDEF_FILE_OFFSET_BITS -/* this was defined above for our checks, undefine it again */ -#undef _FILE_OFFSET_BITS -#endif - -#ifdef UNDEF_FILESIZEBITS -/* this was defined above for our checks, undefine it again */ -#undef FILESIZEBITS -#endif - -struct curl_httppost { - struct curl_httppost *next; /* next entry in the list */ - char *name; /* pointer to allocated name */ - long namelength; /* length of name length */ - char *contents; /* pointer to allocated data contents */ - long contentslength; /* length of contents field */ - char *buffer; /* pointer to allocated buffer contents */ - long bufferlength; /* length of buffer field */ - char *contenttype; /* Content-Type */ - struct curl_slist* contentheader; /* list of extra headers for this form */ - struct curl_httppost *more; /* if one field name has more than one - file, this link should link to following - files */ - long flags; /* as defined below */ -#define HTTPPOST_FILENAME (1<<0) /* specified content is a file name */ -#define HTTPPOST_READFILE (1<<1) /* specified content is a file name */ -#define HTTPPOST_PTRNAME (1<<2) /* name is only stored pointer - do not free in formfree */ -#define HTTPPOST_PTRCONTENTS (1<<3) /* contents is only stored pointer - do not free in formfree */ -#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, - double dltotal, - double dlnow, - double ultotal, - double ulnow); - - /* Tests have proven that 20K is a very bad buffer size for uploads on - Windows, while 16K for some odd reason performed a lot better. */ -#define CURL_MAX_WRITE_SIZE 16384 - -typedef size_t (*curl_write_callback)(char *buffer, - size_t size, - size_t nitems, - void *outstream); - -/* This is a brand new return code for the read callback that will signal - the caller to immediately abort the current transfer. */ -#define CURL_READFUNC_ABORT 0x10000000 -typedef size_t (*curl_read_callback)(char *buffer, - size_t size, - size_t nitems, - void *instream); - - /* not used since 7.10.8, will be removed in a future release */ -typedef int (*curl_passwd_callback)(void *clientp, - const char *prompt, - char *buffer, - int buflen); - -/* - * The following typedef's are signatures of malloc, free, realloc, strdup and - * calloc respectively. Function pointers of these types can be passed to the - * curl_global_init_mem() function to set user defined memory management - * callback routines. - */ -typedef void *(*curl_malloc_callback)(size_t size); -typedef void (*curl_free_callback)(void *ptr); -typedef void *(*curl_realloc_callback)(void *ptr, size_t size); -typedef char *(*curl_strdup_callback)(const char *str); -typedef void *(*curl_calloc_callback)(size_t nmemb, size_t size); - -/* 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_SSL_DATA_IN, /* 5 */ - CURLINFO_SSL_DATA_OUT, /* 6 */ - 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 *userptr); /* whatever the user please */ - -/* All possible error codes from all sorts of curl functions. Future versions - may return other values, stay prepared. - - Always add new return codes last. Never *EVER* remove any. The return - codes must remain the same! - */ - -typedef enum { - CURLE_OK = 0, - CURLE_UNSUPPORTED_PROTOCOL, /* 1 */ - CURLE_FAILED_INIT, /* 2 */ - CURLE_URL_MALFORMAT, /* 3 */ - CURLE_URL_MALFORMAT_USER, /* 4 (NOT USED) */ - CURLE_COULDNT_RESOLVE_PROXY, /* 5 */ - CURLE_COULDNT_RESOLVE_HOST, /* 6 */ - CURLE_COULDNT_CONNECT, /* 7 */ - CURLE_FTP_WEIRD_SERVER_REPLY, /* 8 */ - CURLE_FTP_ACCESS_DENIED, /* 9 */ - CURLE_FTP_USER_PASSWORD_INCORRECT, /* 10 */ - CURLE_FTP_WEIRD_PASS_REPLY, /* 11 */ - CURLE_FTP_WEIRD_USER_REPLY, /* 12 */ - CURLE_FTP_WEIRD_PASV_REPLY, /* 13 */ - CURLE_FTP_WEIRD_227_FORMAT, /* 14 */ - CURLE_FTP_CANT_GET_HOST, /* 15 */ - CURLE_FTP_CANT_RECONNECT, /* 16 */ - CURLE_FTP_COULDNT_SET_BINARY, /* 17 */ - CURLE_PARTIAL_FILE, /* 18 */ - CURLE_FTP_COULDNT_RETR_FILE, /* 19 */ - CURLE_FTP_WRITE_ERROR, /* 20 */ - CURLE_FTP_QUOTE_ERROR, /* 21 */ - CURLE_HTTP_RETURNED_ERROR, /* 22 */ - CURLE_WRITE_ERROR, /* 23 */ - CURLE_MALFORMAT_USER, /* 24 - NOT USED */ - CURLE_FTP_COULDNT_STOR_FILE, /* 25 - failed FTP upload */ - CURLE_READ_ERROR, /* 26 - could open/read from file */ - CURLE_OUT_OF_MEMORY, /* 27 */ - CURLE_OPERATION_TIMEOUTED, /* 28 - the timeout time was reached */ - CURLE_FTP_COULDNT_SET_ASCII, /* 29 - TYPE A failed */ - CURLE_FTP_PORT_FAILED, /* 30 - FTP PORT operation failed */ - CURLE_FTP_COULDNT_USE_REST, /* 31 - the REST command failed */ - CURLE_FTP_COULDNT_GET_SIZE, /* 32 - the SIZE command failed */ - CURLE_HTTP_RANGE_ERROR, /* 33 - RANGE "command" didn't work */ - CURLE_HTTP_POST_ERROR, /* 34 */ - CURLE_SSL_CONNECT_ERROR, /* 35 - wrong when connecting with SSL */ - CURLE_BAD_DOWNLOAD_RESUME, /* 36 - couldn't resume download */ - CURLE_FILE_COULDNT_READ_FILE, /* 37 */ - CURLE_LDAP_CANNOT_BIND, /* 38 */ - CURLE_LDAP_SEARCH_FAILED, /* 39 */ - CURLE_LIBRARY_NOT_FOUND, /* 40 */ - CURLE_FUNCTION_NOT_FOUND, /* 41 */ - CURLE_ABORTED_BY_CALLBACK, /* 42 */ - CURLE_BAD_FUNCTION_ARGUMENT, /* 43 */ - CURLE_BAD_CALLING_ORDER, /* 44 - NOT USED */ - CURLE_INTERFACE_FAILED, /* 45 - CURLOPT_INTERFACE failed */ - CURLE_BAD_PASSWORD_ENTERED, /* 46 - NOT USED */ - CURLE_TOO_MANY_REDIRECTS , /* 47 - catch endless re-direct loops */ - CURLE_UNKNOWN_TELNET_OPTION, /* 48 - User specified an unknown option */ - CURLE_TELNET_OPTION_SYNTAX , /* 49 - Malformed telnet option */ - CURLE_OBSOLETE, /* 50 - NOT USED */ - CURLE_SSL_PEER_CERTIFICATE, /* 51 - peer's certificate wasn't ok */ - CURLE_GOT_NOTHING, /* 52 - when this is a specific error */ - CURLE_SSL_ENGINE_NOTFOUND, /* 53 - SSL crypto engine not found */ - CURLE_SSL_ENGINE_SETFAILED, /* 54 - can not set SSL crypto engine as - default */ - CURLE_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 */ - CURLE_LDAP_INVALID_URL, /* 62 - Invalid LDAP URL */ - CURLE_FILESIZE_EXCEEDED, /* 63 - Maximum file size exceeded */ - CURLE_FTP_SSL_FAILED, /* 64 - Requested FTP SSL level failed */ - - CURL_LAST /* never use! */ -} CURLcode; - -typedef CURLcode (*curl_ssl_ctx_callback)(CURL *curl, /* easy handle */ - void *ssl_ctx, /* actually an - OpenSSL SSL_CTX */ - void *userptr); - -/* Make a spelling correction for the operation timed-out define */ -#define CURLE_OPERATION_TIMEDOUT CURLE_OPERATION_TIMEOUTED - -/* backwards compatibility with older names */ -#define CURLE_HTTP_NOT_FOUND CURLE_HTTP_RETURNED_ERROR -#define CURLE_HTTP_PORT_FAILED CURLE_INTERFACE_FAILED - -typedef enum { - CURLPROXY_HTTP = 0, - CURLPROXY_SOCKS4 = 4, - CURLPROXY_SOCKS5 = 5 -} curl_proxytype; - -#define CURLAUTH_NONE 0 /* nothing */ -#define CURLAUTH_BASIC (1<<0) /* Basic (default) */ -#define CURLAUTH_DIGEST (1<<1) /* Digest */ -#define CURLAUTH_GSSNEGOTIATE (1<<2) /* GSS-Negotiate */ -#define CURLAUTH_NTLM (1<<3) /* NTLM */ -#define CURLAUTH_ANY ~0 /* all types set */ -#define CURLAUTH_ANYSAFE (~CURLAUTH_BASIC) - -/* this was the error code 50 in 7.7.3 and a few earlier versions, this - is no longer used by libcurl but is instead #defined here only to not - make programs break */ -#define CURLE_ALREADY_COMPLETE 99999 - -/* This is just to make older programs not break: */ -#define CURLE_FTP_PARTIAL_FILE CURLE_PARTIAL_FILE -#define CURLE_FTP_BAD_DOWNLOAD_RESUME CURLE_BAD_DOWNLOAD_RESUME - -#define CURL_ERROR_SIZE 256 - -typedef enum { - CURLFTPSSL_NONE, /* do not attempt to use SSL */ - CURLFTPSSL_TRY, /* try using SSL, proceed anyway otherwise */ - CURLFTPSSL_CONTROL, /* SSL for the control connection or fail */ - CURLFTPSSL_ALL, /* SSL for all communication or fail */ - CURLFTPSSL_LAST /* not an option, never use */ -} curl_ftpssl; - -/* 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 -#define CURLOPTTYPE_OFF_T 30000 - -/* name is uppercase CURLOPT_<name>, - type is one of the defined CURLOPTTYPE_<type> - number is unique identifier */ -#ifdef CINIT -#undef CINIT -#endif -/* - * 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__) || defined(__LCC__) - /* 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 - -#ifdef CURL_ISOCPP -#define CINIT(name,type,number) CURLOPT_ ## name = CURLOPTTYPE_ ## type + number -#else -/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ -#define LONG CURLOPTTYPE_LONG -#define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT -#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT -#define OFF_T CURLOPTTYPE_OFF_T -#define CINIT(name,type,number) CURLOPT_/**/name = type + number -#endif - -/* - * This macro-mania below setups the CURLOPT_[what] enum, to be used with - * curl_easy_setopt(). The first argument in the CINIT() macro is the [what] - * word. - */ - -typedef enum { - /* This is the FILE * or void * the regular output should be written to. */ - CINIT(FILE, OBJECTPOINT, 1), - - /* The full URL to get/put */ - CINIT(URL, OBJECTPOINT, 2), - - /* Port number to connect to, if other than default. */ - CINIT(PORT, LONG, 3), - - /* Name of proxy to use. */ - CINIT(PROXY, OBJECTPOINT, 4), - - /* "name:password" to use when fetching. */ - CINIT(USERPWD, OBJECTPOINT, 5), - - /* "name:password" to use with proxy. */ - CINIT(PROXYUSERPWD, OBJECTPOINT, 6), - - /* Range to get, specified as an ASCII string. */ - CINIT(RANGE, OBJECTPOINT, 7), - - /* not used */ - - /* Specified file stream to upload from (use as input): */ - CINIT(INFILE, OBJECTPOINT, 9), - - /* Buffer to receive error messages in, must be at least CURL_ERROR_SIZE - * bytes big. If this is not used, error messages go to stderr instead: */ - CINIT(ERRORBUFFER, OBJECTPOINT, 10), - - /* Function that will be called to store the output (instead of fwrite). The - * parameters will use fwrite() syntax, make sure to follow them. */ - CINIT(WRITEFUNCTION, FUNCTIONPOINT, 11), - - /* Function that will be called to read the input (instead of fread). The - * parameters will use fread() syntax, make sure to follow them. */ - CINIT(READFUNCTION, FUNCTIONPOINT, 12), - - /* Time-out the read operation after this amount of seconds */ - CINIT(TIMEOUT, LONG, 13), - - /* If the CURLOPT_INFILE is used, this can be used to inform libcurl about - * how large the file being sent really is. That allows better error - * checking and better verifies that the upload was succcessful. -1 means - * unknown size. - * - * For large file support, there is also a _LARGE version of the key - * which takes an off_t type, allowing platforms with larger off_t - * sizes to handle larger files. See below for INFILESIZE_LARGE. - */ - CINIT(INFILESIZE, LONG, 14), - - /* POST input fields. */ - CINIT(POSTFIELDS, OBJECTPOINT, 15), - - /* Set the referer page (needed by some CGIs) */ - CINIT(REFERER, OBJECTPOINT, 16), - - /* Set the FTP PORT string (interface name, named or numerical IP address) - Use i.e '-' to use default address. */ - CINIT(FTPPORT, OBJECTPOINT, 17), - - /* Set the User-Agent string (examined by some CGIs) */ - CINIT(USERAGENT, OBJECTPOINT, 18), - - /* If the download receives less than "low speed limit" bytes/second - * during "low speed time" seconds, the operations is aborted. - * You could i.e if you have a pretty high speed connection, abort if - * it is less than 2000 bytes/sec during 20 seconds. - */ - - /* Set the "low speed limit" */ - CINIT(LOW_SPEED_LIMIT, LONG , 19), - - /* Set the "low speed time" */ - CINIT(LOW_SPEED_TIME, LONG, 20), - - /* Set the continuation offset. - * - * Note there is also a _LARGE version of this key which uses - * off_t types, allowing for large file offsets on platforms which - * use larger-than-32-bit off_t's. Look below for RESUME_FROM_LARGE. - */ - CINIT(RESUME_FROM, LONG, 21), - - /* Set cookie in request: */ - CINIT(COOKIE, OBJECTPOINT, 22), - - /* This points to a linked list of headers, struct curl_slist kind */ - CINIT(HTTPHEADER, OBJECTPOINT, 23), - - /* This points to a linked list of post entries, struct HttpPost */ - CINIT(HTTPPOST, OBJECTPOINT, 24), - - /* name of the file keeping your private SSL-certificate */ - CINIT(SSLCERT, OBJECTPOINT, 25), - - /* password for the SSL-private key, keep this for compatibility */ - CINIT(SSLCERTPASSWD, OBJECTPOINT, 26), - /* password for the SSL private key */ - CINIT(SSLKEYPASSWD, OBJECTPOINT, 26), - - /* send TYPE parameter? */ - CINIT(CRLF, LONG, 27), - - /* send linked-list of QUOTE commands */ - CINIT(QUOTE, OBJECTPOINT, 28), - - /* send FILE * or void * to store headers to, if you use a callback it - is simply passed to the callback unmodified */ - CINIT(WRITEHEADER, OBJECTPOINT, 29), - - /* point to a file to read the initial cookies from, also enables - "cookie awareness" */ - CINIT(COOKIEFILE, OBJECTPOINT, 31), - - /* What version to specifly try to use. - See CURL_SSLVERSION defines below. */ - CINIT(SSLVERSION, LONG, 32), - - /* What kind of HTTP time condition to use, see defines */ - CINIT(TIMECONDITION, LONG, 33), - - /* Time to use with the above condition. Specified in number of seconds - since 1 Jan 1970 */ - CINIT(TIMEVALUE, LONG, 34), - - /* 35 = OBSOLETE */ - - /* Custom request, for customizing the get command like - HTTP: DELETE, TRACE and others - FTP: to use a different list command - */ - CINIT(CUSTOMREQUEST, OBJECTPOINT, 36), - - /* HTTP request, for odd commands like DELETE, TRACE and others */ - CINIT(STDERR, OBJECTPOINT, 37), - - /* 38 is not used */ - - /* send linked-list of post-transfer QUOTE commands */ - CINIT(POSTQUOTE, OBJECTPOINT, 39), - - /* Pass a pointer to string of the output using full variable-replacement - as described elsewhere. */ - CINIT(WRITEINFO, OBJECTPOINT, 40), - - CINIT(VERBOSE, LONG, 41), /* talk a lot */ - CINIT(HEADER, LONG, 42), /* throw the header out too */ - CINIT(NOPROGRESS, LONG, 43), /* shut off the progress meter */ - CINIT(NOBODY, LONG, 44), /* use HEAD to get http document */ - CINIT(FAILONERROR, LONG, 45), /* no output on http error codes >= 300 */ - CINIT(UPLOAD, LONG, 46), /* this is an upload */ - CINIT(POST, LONG, 47), /* HTTP POST method */ - CINIT(FTPLISTONLY, LONG, 48), /* Use NLST when listing ftp dir */ - - CINIT(FTPAPPEND, LONG, 50), /* Append instead of overwrite on upload! */ - - /* 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(TRANSFERTEXT, LONG, 53), /* transfer data in text/ASCII format */ - CINIT(PUT, LONG, 54), /* HTTP PUT */ - - /* 55 = OBSOLETE */ - - /* Function that will be called instead of the internal progress display - * function. This function should be defined as the curl_progress_callback - * prototype defines. */ - CINIT(PROGRESSFUNCTION, FUNCTIONPOINT, 56), - - /* Data passed to the progress callback */ - CINIT(PROGRESSDATA, OBJECTPOINT, 57), - - /* We want the referer field set automatically when following locations */ - CINIT(AUTOREFERER, LONG, 58), - - /* Port of the proxy, can be set in the proxy string as well with: - "[host]:[port]" */ - CINIT(PROXYPORT, LONG, 59), - - /* size of the POST input data, if strlen() is not good to use */ - CINIT(POSTFIELDSIZE, LONG, 60), - - /* tunnel non-http operations through a HTTP proxy */ - CINIT(HTTPPROXYTUNNEL, LONG, 61), - - /* Set the interface string to use as outgoing network interface */ - CINIT(INTERFACE, OBJECTPOINT, 62), - - /* Set the krb4 security level, this also enables krb4 awareness. This is a - * string, 'clear', 'safe', 'confidential' or 'private'. If the string is - * set but doesn't match one of these, 'private' will be used. */ - CINIT(KRB4LEVEL, OBJECTPOINT, 63), - - /* Set if we should verify the peer in ssl handshake, set 1 to verify. */ - CINIT(SSL_VERIFYPEER, LONG, 64), - - /* The CApath or CAfile used to validate the peer certificate - this option is used only if SSL_VERIFYPEER is true */ - CINIT(CAINFO, OBJECTPOINT, 65), - - /* 66 = OBSOLETE */ - /* 67 = OBSOLETE */ - - /* Maximum number of http redirects to follow */ - CINIT(MAXREDIRS, LONG, 68), - - /* Pass a long set to 1 to get the date of the requested document (if - possible)! Pass a zero to shut it off. */ - CINIT(FILETIME, LONG, 69), - - /* This points to a linked list of telnet options */ - CINIT(TELNETOPTIONS, OBJECTPOINT, 70), - - /* Max amount of cached alive connections */ - CINIT(MAXCONNECTS, LONG, 71), - - /* What policy to use when closing connections when the cache is filled - up */ - CINIT(CLOSEPOLICY, LONG, 72), - - /* 73 = OBSOLETE */ - - /* Set to explicitly use a new connection for the upcoming transfer. - Do not use this unless you're absolutely sure of this, as it makes the - operation slower and is less friendly for the network. */ - CINIT(FRESH_CONNECT, LONG, 74), - - /* Set to explicitly forbid the upcoming transfer's connection to be re-used - when done. Do not use this unless you're absolutely sure of this, as it - makes the operation slower and is less friendly for the network. */ - CINIT(FORBID_REUSE, LONG, 75), - - /* Set to a file name that contains random data for libcurl to use to - seed the random engine when doing SSL connects. */ - CINIT(RANDOM_FILE, OBJECTPOINT, 76), - - /* Set to the Entropy Gathering Daemon socket pathname */ - CINIT(EGDSOCKET, OBJECTPOINT, 77), - - /* Time-out connect operations after this amount of seconds, if connects - are OK within this time, then fine... This only aborts the connect - phase. [Only works on unix-style/SIGALRM operating systems] */ - CINIT(CONNECTTIMEOUT, LONG, 78), - - /* Function that will be called to store headers (instead of fwrite). The - * parameters will use fwrite() syntax, make sure to follow them. */ - CINIT(HEADERFUNCTION, FUNCTIONPOINT, 79), - - /* Set this to force the HTTP request to get back to GET. Only really usable - if POST, PUT or a custom request have been used first. - */ - CINIT(HTTPGET, LONG, 80), - - /* Set if we should verify the Common name from the peer certificate in ssl - * handshake, set 1 to check existence, 2 to ensure that it matches the - * provided hostname. */ - CINIT(SSL_VERIFYHOST, LONG, 81), - - /* Specify which file name to write all known cookies in after completed - operation. Set file name to "-" (dash) to make it go to stdout. */ - CINIT(COOKIEJAR, OBJECTPOINT, 82), - - /* Specify which SSL ciphers to use */ - CINIT(SSL_CIPHER_LIST, OBJECTPOINT, 83), - - /* Specify which HTTP version to use! This must be set to one of the - CURL_HTTP_VERSION* enums set below. */ - CINIT(HTTP_VERSION, LONG, 84), - - /* Specificly switch on or off the FTP engine's use of the EPSV command. By - default, that one will always be attempted before the more traditional - PASV command. */ - CINIT(FTP_USE_EPSV, LONG, 85), - - /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") */ - CINIT(SSLCERTTYPE, OBJECTPOINT, 86), - - /* name of the file keeping your private SSL-key */ - CINIT(SSLKEY, OBJECTPOINT, 87), - - /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") */ - CINIT(SSLKEYTYPE, OBJECTPOINT, 88), - - /* crypto engine for the SSL-sub system */ - CINIT(SSLENGINE, OBJECTPOINT, 89), - - /* set the crypto engine for the SSL-sub system as default - the param has no meaning... - */ - CINIT(SSLENGINE_DEFAULT, LONG, 90), - - /* Non-zero value means to use the global dns cache */ - CINIT(DNS_USE_GLOBAL_CACHE, LONG, 91), /* To become OBSOLETE soon */ - - /* DNS cache timeout */ - CINIT(DNS_CACHE_TIMEOUT, LONG, 92), - - /* send linked-list of pre-transfer QUOTE commands (Wesley Laxton)*/ - CINIT(PREQUOTE, OBJECTPOINT, 93), - - /* set the debug function */ - CINIT(DEBUGFUNCTION, FUNCTIONPOINT, 94), - - /* set the data for the debug function */ - CINIT(DEBUGDATA, OBJECTPOINT, 95), - - /* mark this as start of a cookie session */ - CINIT(COOKIESESSION, LONG, 96), - - /* The CApath directory used to validate the peer certificate - this option is used only if SSL_VERIFYPEER is true */ - CINIT(CAPATH, OBJECTPOINT, 97), - - /* Instruct libcurl to use a smaller receive buffer */ - CINIT(BUFFERSIZE, LONG, 98), - - /* Instruct libcurl to not use any signal/alarm handlers, even when using - timeouts. This option is useful for multi-threaded applications. - See libcurl-the-guide for more background information. */ - CINIT(NOSIGNAL, LONG, 99), - - /* 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), - - /* Set pointer to private data */ - CINIT(PRIVATE, OBJECTPOINT, 103), - - /* Set aliases for HTTP 200 in the HTTP Response header */ - CINIT(HTTP200ALIASES, OBJECTPOINT, 104), - - /* Continue to send authentication (user+password) when following locations, - even when hostname changed. This can potentionally send off the name - and password to whatever host the server decides. */ - CINIT(UNRESTRICTED_AUTH, LONG, 105), - - /* Specificly switch on or off the FTP engine's use of the EPRT command ( it - also disables the LPRT attempt). By default, those ones will always be - attempted before the good old traditional PORT command. */ - CINIT(FTP_USE_EPRT, LONG, 106), - - /* Set this to a bitmask value to enable the particular authentications - methods you like. Use this in combination with CURLOPT_USERPWD. - Note that setting multiple bits may cause extra network round-trips. */ - CINIT(HTTPAUTH, LONG, 107), - - /* Set the ssl context callback function, currently only for OpenSSL ssl_ctx - in second argument. The function must be matching the - curl_ssl_ctx_callback proto. */ - CINIT(SSL_CTX_FUNCTION, FUNCTIONPOINT, 108), - - /* Set the userdata for the ssl context callback function's third - argument */ - CINIT(SSL_CTX_DATA, OBJECTPOINT, 109), - - /* FTP Option that causes missing dirs to be created on the remote server */ - CINIT(FTP_CREATE_MISSING_DIRS, LONG, 110), - - /* Set this to a bitmask value to enable the particular authentications - methods you like. Use this in combination with CURLOPT_PROXYUSERPWD. - Note that setting multiple bits may cause extra network round-trips. */ - CINIT(PROXYAUTH, LONG, 111), - - /* FTP option that changes the timeout, in seconds, associated with - getting a response. This is different from transfer timeout time and - essentially places a demand on the FTP server to acknowledge commands - in a timely manner. */ - CINIT(FTP_RESPONSE_TIMEOUT, LONG , 112), - - /* Set this option to one of the CURL_IPRESOLVE_* defines (see below) to - tell libcurl to resolve names to those IP versions only. This only has - affect on systems with support for more than one, i.e IPv4 _and_ IPv6. */ - CINIT(IPRESOLVE, LONG, 113), - - /* Set this option to limit the size of a file that will be downloaded from - an HTTP or FTP server. - - Note there is also _LARGE version which adds large file support for - platforms which have larger off_t sizes. See MAXFILESIZE_LARGE below. */ - CINIT(MAXFILESIZE, LONG, 114), - - /* See the comment for INFILESIZE above, but in short, specifies - * the size of the file being uploaded. -1 means unknown. - */ - CINIT(INFILESIZE_LARGE, OFF_T, 115), - - /* Sets the continuation offset. There is also a LONG version of this; - * look above for RESUME_FROM. - */ - CINIT(RESUME_FROM_LARGE, OFF_T, 116), - - /* Sets the maximum size of data that will be downloaded from - * an HTTP or FTP server. See MAXFILESIZE above for the LONG version. - */ - CINIT(MAXFILESIZE_LARGE, OFF_T, 117), - - /* Set this option to the file name of your .netrc file you want libcurl - to parse (using the CURLOPT_NETRC option). If not set, libcurl will do - a poor attempt to find the user's home directory and check for a .netrc - file in there. */ - CINIT(NETRC_FILE, OBJECTPOINT, 118), - - /* Enable SSL/TLS for FTP, pick one of: - CURLFTPSSL_TRY - try using SSL, proceed anyway otherwise - CURLFTPSSL_CONTROL - SSL for the control connection or fail - CURLFTPSSL_ALL - SSL for all communication or fail - */ - CINIT(FTP_SSL, LONG, 119), - - /* The _LARGE version of the standard POSTFIELDSIZE option */ - CINIT(POSTFIELDSIZE_LARGE, OFF_T, 120), - - /* Enable/disable the TCP Nagle algorithm */ - CINIT(TCP_NODELAY, LONG, 121), - - /* When doing 3rd party transfer, set the source host name with this */ - CINIT(SOURCE_HOST, OBJECTPOINT, 122), - - /* When doing 3rd party transfer, set the source user and password with - this */ - CINIT(SOURCE_USERPWD, OBJECTPOINT, 123), - - /* When doing 3rd party transfer, set the source file path with this */ - CINIT(SOURCE_PATH, OBJECTPOINT, 124), - - /* When doing 3rd party transfer, set the source server's port number - with this */ - CINIT(SOURCE_PORT, LONG, 125), - - /* When doing 3rd party transfer, decide which server that should get the - PASV command (and the other gets the PORT). - 0 (default) - The target host issues PASV. - 1 - The source host issues PASV */ - CINIT(PASV_HOST, LONG, 126), - - /* When doing 3rd party transfer, set the source pre-quote linked list - of commands with this */ - CINIT(SOURCE_PREQUOTE, OBJECTPOINT, 127), - - /* When doing 3rd party transfer, set the source post-quote linked list - of commands with this */ - CINIT(SOURCE_POSTQUOTE, OBJECTPOINT, 128), - - CURLOPT_LASTENTRY /* the last unused */ -} CURLoption; - - /* Below here follows defines for the CURLOPT_IPRESOLVE option. If a host - name resolves addresses using more than one IP protocol version, this - option might be handy to force libcurl to use a specific IP version. */ -#define CURL_IPRESOLVE_WHATEVER 0 /* default, resolves addresses to all IP - versions that your system allows */ -#define CURL_IPRESOLVE_V4 1 /* resolve to ipv4 addresses */ -#define CURL_IPRESOLVE_V6 2 /* resolve to ipv6 addresses */ - - /* three convenient "aliases" that follow the name scheme better */ -#define CURLOPT_WRITEDATA CURLOPT_FILE -#define CURLOPT_READDATA CURLOPT_INFILE -#define CURLOPT_HEADERDATA CURLOPT_WRITEHEADER - -#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all - the obsolete stuff removed! */ -#define CURLOPT_HTTPREQUEST -1 -#define CURLOPT_FTPASCII CURLOPT_TRANSFERTEXT -#define CURLOPT_MUTE -2 -#define CURLOPT_PASSWDFUNCTION -3 -#define CURLOPT_PASSWDDATA -4 -#define CURLOPT_CLOSEFUNCTION -5 - -#else -/* This is set if CURL_NO_OLDIES is defined at compile-time */ -#undef CURLOPT_DNS_USE_GLOBAL_CACHE /* soon obsolete */ -#endif - - - /* These enums are for use with the CURLOPT_HTTP_VERSION option. */ -enum { - CURL_HTTP_VERSION_NONE, /* setting this means we don't care, and that we'd - like the library to choose the best possible - for us! */ - CURL_HTTP_VERSION_1_0, /* please use HTTP 1.0 in the request */ - CURL_HTTP_VERSION_1_1, /* please use HTTP 1.1 in the request */ - - CURL_HTTP_VERSION_LAST /* *ILLEGAL* http version */ -}; - - /* These enums are for use with the CURLOPT_NETRC option. */ -enum CURL_NETRC_OPTION { - CURL_NETRC_IGNORED, /* The .netrc will never be read. - * This is the default. */ - CURL_NETRC_OPTIONAL, /* A user:password in the URL will be preferred - * to one in the .netrc. */ - CURL_NETRC_REQUIRED, /* A user:password in the URL will be ignored. - * Unless one is set programmatically, the .netrc - * will be queried. */ - CURL_NETRC_LAST -}; - -enum { - CURL_SSLVERSION_DEFAULT, - CURL_SSLVERSION_TLSv1, - CURL_SSLVERSION_SSLv2, - CURL_SSLVERSION_SSLv3, - - CURL_SSLVERSION_LAST /* never use, keep last */ -}; - - -typedef enum { - CURL_TIMECOND_NONE, - - CURL_TIMECOND_IFMODSINCE, - CURL_TIMECOND_IFUNMODSINCE, - CURL_TIMECOND_LASTMOD, - - CURL_TIMECOND_LAST -} curl_TimeCond; - -#ifdef __BEOS__ -#include <support/SupportDefs.h> -#endif - - -/* curl_strequal() and curl_strnequal() are subject for removal in a future - libcurl, see lib/README.curlx for details */ -extern int (curl_strequal)(const char *s1, const char *s2); -extern int (curl_strnequal)(const char *s1, const char *s2, size_t n); - -/* name is uppercase CURLFORM_<name> */ -#ifdef CFINIT -#undef CFINIT -#endif - -#ifdef CURL_ISOCPP -#define CFINIT(name) CURLFORM_ ## name -#else -/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ -#define CFINIT(name) CURLFORM_/**/name -#endif - -typedef enum { - CFINIT(NOTHING), /********* the first one is unused ************/ - - /* */ - CFINIT(COPYNAME), - CFINIT(PTRNAME), - CFINIT(NAMELENGTH), - CFINIT(COPYCONTENTS), - CFINIT(PTRCONTENTS), - CFINIT(CONTENTSLENGTH), - CFINIT(FILECONTENT), - CFINIT(ARRAY), - CFINIT(OBSOLETE), - CFINIT(FILE), - - CFINIT(BUFFER), - CFINIT(BUFFERPTR), - CFINIT(BUFFERLENGTH), - - CFINIT(CONTENTTYPE), - CFINIT(CONTENTHEADER), - CFINIT(FILENAME), - CFINIT(END), - CFINIT(OBSOLETE2), - - CURLFORM_LASTENTRY /* the last unusued */ -} CURLformoption; - -#undef CFINIT /* done */ - -/* structure to be used as parameter for CURLFORM_ARRAY */ -struct curl_forms { - CURLformoption option; - const char *value; -}; - -/* use this for multipart formpost building */ -/* Returns code for curl_formadd() - * - * Returns: - * CURL_FORMADD_OK on success - * CURL_FORMADD_MEMORY if the FormInfo allocation fails - * CURL_FORMADD_OPTION_TWICE if one option is given twice for one Form - * CURL_FORMADD_NULL if a null pointer was given for a char - * CURL_FORMADD_MEMORY if the allocation of a FormInfo struct failed - * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used - * CURL_FORMADD_INCOMPLETE if the some FormInfo is not complete (or error) - * CURL_FORMADD_MEMORY if a HttpPost struct cannot be allocated - * CURL_FORMADD_MEMORY if some allocation for string copying failed. - * CURL_FORMADD_ILLEGAL_ARRAY if an illegal option is used in an array - * - ***************************************************************************/ -typedef enum { - CURL_FORMADD_OK, /* first, no error */ - - CURL_FORMADD_MEMORY, - CURL_FORMADD_OPTION_TWICE, - CURL_FORMADD_NULL, - CURL_FORMADD_UNKNOWN_OPTION, - CURL_FORMADD_INCOMPLETE, - CURL_FORMADD_ILLEGAL_ARRAY, - CURL_FORMADD_DISABLED, /* libcurl was built with this disabled */ - - CURL_FORMADD_LAST /* last */ -} CURLFORMcode; - -/* - * NAME curl_formadd() - * - * DESCRIPTION - * - * Pretty advanved function for building multi-part formposts. Each invoke - * adds one part that together construct a full post. Then use - * CURLOPT_HTTPPOST to send it off to libcurl. - */ -CURLFORMcode curl_formadd(struct curl_httppost **httppost, - struct curl_httppost **last_post, - ...); - -/* - * NAME curl_formfree() - * - * DESCRIPTION - * - * Free a multipart formpost previously built with curl_formadd(). - */ -void curl_formfree(struct curl_httppost *form); - -/* - * NAME curl_getenv() - * - * DESCRIPTION - * - * Returns a malloc()'ed string that MUST be curl_free()ed after usage is - * complete. DEPRECATED - see lib/README.curlx - */ -char *curl_getenv(const char *variable); - -/* - * NAME curl_version() - * - * DESCRIPTION - * - * Returns a static ascii string of the libcurl version. - */ -char *curl_version(void); - -/* - * NAME curl_escape() - * - * DESCRIPTION - * - * Escapes URL strings (converts all letters consider illegal in URLs to their - * %XX versions). This function returns a new allocated string or NULL if an - * error occurred. - */ -char *curl_escape(const char *string, int length); - -/* - * NAME curl_unescape() - * - * DESCRIPTION - * - * Unescapes URL encoding in strings (converts all %XX codes to their 8bit - * versions). This function returns a new allocated string or NULL if an error - * occurred. - */ -char *curl_unescape(const char *string, int length); - -/* - * NAME curl_free() - * - * DESCRIPTION - * - * Provided for de-allocation in the same translation unit that did the - * allocation. Added in libcurl 7.10 - */ -void curl_free(void *p); - -/* - * NAME curl_global_init() - * - * DESCRIPTION - * - * curl_global_init() should be invoked exactly once for each application that - * uses libcurl - */ -CURLcode curl_global_init(long flags); - -/* - * NAME curl_global_init_mem() - * - * DESCRIPTION - * - * curl_global_init() or curl_global_init_mem() should be invoked exactly once - * for each application that uses libcurl. This function can be used to - * initialize libcurl and set user defined memory management callback - * functions. Users can implement memory management routines to check for - * memory leaks, check for mis-use of the curl library etc. User registered - * callback routines with be invoked by this library instead of the system - * memory management routines like malloc, free etc. - */ -CURLcode curl_global_init_mem(long flags, - curl_malloc_callback m, - curl_free_callback f, - curl_realloc_callback r, - curl_strdup_callback s, - curl_calloc_callback c); - -/* - * NAME curl_global_cleanup() - * - * DESCRIPTION - * - * curl_global_cleanup() should be invoked exactly once for each application - * that uses libcurl - */ -void curl_global_cleanup(void); - -/* linked-list structure for the CURLOPT_QUOTE option (and other) */ -struct curl_slist { - char *data; - struct curl_slist *next; -}; - -/* - * NAME curl_slist_append() - * - * DESCRIPTION - * - * Appends a string to a linked list. If no list exists, it will be created - * first. Returns the new list, after appending. - */ -struct curl_slist *curl_slist_append(struct curl_slist *, const char *); - -/* - * NAME curl_slist_free_all() - * - * DESCRIPTION - * - * free a previously built curl_slist. - */ -void curl_slist_free_all(struct curl_slist *); - -/* - * NAME curl_getdate() - * - * DESCRIPTION - * - * Returns the time, in seconds since 1 Jan 1970 of the time string given in - * the first argument. The time argument in the second parameter is for cases - * where the specified time is relative now, like 'two weeks' or 'tomorrow' - * etc. - */ -time_t curl_getdate(const char *p, const time_t *now); - -#define CURLINFO_STRING 0x100000 -#define CURLINFO_LONG 0x200000 -#define CURLINFO_DOUBLE 0x300000 -#define CURLINFO_MASK 0x0fffff -#define CURLINFO_TYPEMASK 0xf00000 - -typedef enum { - CURLINFO_NONE, /* first, never use this */ - CURLINFO_EFFECTIVE_URL = CURLINFO_STRING + 1, - CURLINFO_RESPONSE_CODE = CURLINFO_LONG + 2, - CURLINFO_TOTAL_TIME = CURLINFO_DOUBLE + 3, - CURLINFO_NAMELOOKUP_TIME = CURLINFO_DOUBLE + 4, - CURLINFO_CONNECT_TIME = CURLINFO_DOUBLE + 5, - CURLINFO_PRETRANSFER_TIME = CURLINFO_DOUBLE + 6, - CURLINFO_SIZE_UPLOAD = CURLINFO_DOUBLE + 7, - CURLINFO_SIZE_DOWNLOAD = CURLINFO_DOUBLE + 8, - CURLINFO_SPEED_DOWNLOAD = CURLINFO_DOUBLE + 9, - CURLINFO_SPEED_UPLOAD = CURLINFO_DOUBLE + 10, - CURLINFO_HEADER_SIZE = CURLINFO_LONG + 11, - CURLINFO_REQUEST_SIZE = CURLINFO_LONG + 12, - CURLINFO_SSL_VERIFYRESULT = CURLINFO_LONG + 13, - CURLINFO_FILETIME = CURLINFO_LONG + 14, - CURLINFO_CONTENT_LENGTH_DOWNLOAD = CURLINFO_DOUBLE + 15, - CURLINFO_CONTENT_LENGTH_UPLOAD = CURLINFO_DOUBLE + 16, - CURLINFO_STARTTRANSFER_TIME = CURLINFO_DOUBLE + 17, - CURLINFO_CONTENT_TYPE = CURLINFO_STRING + 18, - CURLINFO_REDIRECT_TIME = CURLINFO_DOUBLE + 19, - CURLINFO_REDIRECT_COUNT = CURLINFO_LONG + 20, - CURLINFO_PRIVATE = CURLINFO_STRING + 21, - CURLINFO_HTTP_CONNECTCODE = CURLINFO_LONG + 22, - CURLINFO_HTTPAUTH_AVAIL = CURLINFO_LONG + 23, - CURLINFO_PROXYAUTH_AVAIL = CURLINFO_LONG + 24, - /* Fill in new entries below here! */ - - CURLINFO_LASTONE = 23 -} CURLINFO; - -/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as - CURLINFO_HTTP_CODE */ -#define CURLINFO_HTTP_CODE CURLINFO_RESPONSE_CODE - -typedef enum { - CURLCLOSEPOLICY_NONE, /* first, never use this */ - - CURLCLOSEPOLICY_OLDEST, - CURLCLOSEPOLICY_LEAST_RECENTLY_USED, - CURLCLOSEPOLICY_LEAST_TRAFFIC, - CURLCLOSEPOLICY_SLOWEST, - CURLCLOSEPOLICY_CALLBACK, - - CURLCLOSEPOLICY_LAST /* last, never use this */ -} curl_closepolicy; - -#define CURL_GLOBAL_SSL (1<<0) -#define CURL_GLOBAL_WIN32 (1<<1) -#define CURL_GLOBAL_ALL (CURL_GLOBAL_SSL|CURL_GLOBAL_WIN32) -#define CURL_GLOBAL_NOTHING 0 -#define CURL_GLOBAL_DEFAULT CURL_GLOBAL_ALL - - -/***************************************************************************** - * Setup defines, protos etc for the sharing stuff. - */ - -/* Different data locks for a single share */ -typedef enum { - CURL_LOCK_DATA_NONE = 0, - /* CURL_LOCK_DATA_SHARE is used internaly to say that - * the locking is just made to change the internal state of the share - * itself. - */ - CURL_LOCK_DATA_SHARE, - CURL_LOCK_DATA_COOKIE, - CURL_LOCK_DATA_DNS, - CURL_LOCK_DATA_SSL_SESSION, - CURL_LOCK_DATA_CONNECT, - CURL_LOCK_DATA_LAST -} curl_lock_data; - -/* Different lock access types */ -typedef enum { - CURL_LOCK_ACCESS_NONE = 0, /* unspecified action */ - CURL_LOCK_ACCESS_SHARED = 1, /* for read perhaps */ - CURL_LOCK_ACCESS_SINGLE = 2, /* for write perhaps */ - CURL_LOCK_ACCESS_LAST /* never use */ -} curl_lock_access; - -typedef void (*curl_lock_function)(CURL *handle, - curl_lock_data data, - curl_lock_access locktype, - void *userptr); -typedef void (*curl_unlock_function)(CURL *handle, - curl_lock_data data, - void *userptr); - -typedef void CURLSH; - -typedef enum { - CURLSHE_OK, /* all is fine */ - CURLSHE_BAD_OPTION, /* 1 */ - CURLSHE_IN_USE, /* 2 */ - CURLSHE_INVALID, /* 3 */ - CURLSHE_NOMEM, /* out of memory */ - CURLSHE_LAST /* never use */ -} CURLSHcode; - -typedef enum { - CURLSHOPT_NONE, /* don't use */ - CURLSHOPT_SHARE, /* specify a data type to share */ - CURLSHOPT_UNSHARE, /* specify shich data type to stop sharing */ - CURLSHOPT_LOCKFUNC, /* pass in a 'curl_lock_function' pointer */ - CURLSHOPT_UNLOCKFUNC, /* pass in a 'curl_unlock_function' pointer */ - CURLSHOPT_USERDATA, /* pass in a user data pointer used in the lock/unlock - callback functions */ - CURLSHOPT_LAST /* never use */ -} CURLSHoption; - -CURLSH *curl_share_init(void); -CURLSHcode curl_share_setopt(CURLSH *, CURLSHoption option, ...); -CURLSHcode curl_share_cleanup(CURLSH *); - -/**************************************************************************** - * Structures for querying information about the curl library at runtime. - */ - -typedef enum { - CURLVERSION_FIRST, - CURLVERSION_SECOND, - CURLVERSION_THIRD, - 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_THIRD - -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; - - /* The fields below this were added in CURLVERSION_SECOND */ - const char *ares; - int ares_num; - - /* This field was aded in CURLVERSION_THIRD */ - const char *libidn; -} curl_version_info_data; - -#define CURL_VERSION_IPV6 (1<<0) /* IPv6-enabled */ -#define CURL_VERSION_KERBEROS4 (1<<1) /* kerberos auth is supported */ -#define CURL_VERSION_SSL (1<<2) /* SSL options are present */ -#define CURL_VERSION_LIBZ (1<<3) /* libz features are present */ -#define CURL_VERSION_NTLM (1<<4) /* NTLM auth is supported */ -#define CURL_VERSION_GSSNEGOTIATE (1<<5) /* Negotiate auth support */ -#define CURL_VERSION_DEBUG (1<<6) /* built with debug capabilities */ -#define CURL_VERSION_ASYNCHDNS (1<<7) /* asynchronous dns resolves */ -#define CURL_VERSION_SPNEGO (1<<8) /* SPNEGO auth */ -#define CURL_VERSION_LARGEFILE (1<<9) /* supports files bigger than 2GB */ -#define CURL_VERSION_IDN (1<<10) /* International Domain Names support */ - -/* - * NAME curl_version_info() - * - * DESCRIPTION - * - * This function returns a pointer to a static copy of the version info - * struct. See above. - */ -curl_version_info_data *curl_version_info(CURLversion); - -/* - * NAME curl_easy_strerror() - * - * DESCRIPTION - * - * The curl_easy_strerror function may be used to turn a CURLcode value - * into the equivalent human readable error string. This is useful - * for printing meaningful error messages. - */ -const char *curl_easy_strerror(CURLcode); - -/* - * NAME curl_share_strerror() - * - * DESCRIPTION - * - * The curl_share_strerror function may be used to turn a CURLSHcode value - * into the equivalent human readable error string. This is useful - * for printing meaningful error messages. - */ -const char *curl_share_strerror(CURLSHcode); - -#ifdef __cplusplus -} -#endif - -/* unfortunately, the easy.h and multi.h include files need options and info - stuff before they can be included! */ -#include "easy.h" /* nothing in curl is fun without the easy stuff */ -#include "multi.h" - -#endif /* __CURL_CURL_H */ diff --git a/Source/CTest/Curl/curl/curlver.h b/Source/CTest/Curl/curl/curlver.h deleted file mode 100644 index ef0a4c5..0000000 --- a/Source/CTest/Curl/curl/curlver.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef __CURL_CURLVER_H -#define __CURL_CURLVER_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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$ - ***************************************************************************/ - -/* This header file contains nothing but libcurl version info, generated by - a script at release-time. This was made its own header file in 7.11.2 */ - -/* This is the version number of the libcurl package from which this header - file origins: */ -#define LIBCURL_VERSION "7.12.1" - -/* This is the numeric version of the libcurl version number, meant for easier - parsing and comparions by programs. The LIBCURL_VERSION_NUM define will - always follow this syntax: - - 0xXXYYZZ - - Where XX, YY and ZZ are the main version, release and patch numbers in - hexadecimal. All three numbers are always represented using two digits. 1.2 - would appear as "0x010200" while version 9.11.7 appears as "0x090b07". - - This 6-digit hexadecimal number does not show pre-release number, and it is - always a greater number in a more recent release. It makes comparisons with - greater than and less than work. -*/ -#define LIBCURL_VERSION_NUM 0x70C01 - -/* The numeric version number is also available "in parts" by using these - defines: */ -#define LIBCURL_VERSION_MAJOR 7 -#define LIBCURL_VERSION_MINOR 12 -#define LIBCURL_VERSION_PATCH 1 - -#endif /* __CURL_CURLVER_H */ diff --git a/Source/CTest/Curl/curl/easy.h b/Source/CTest/Curl/curl/easy.h deleted file mode 100644 index 336e542..0000000 --- a/Source/CTest/Curl/curl/easy.h +++ /dev/null @@ -1,81 +0,0 @@ -#ifndef __CURL_EASY_H -#define __CURL_EASY_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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$ - ***************************************************************************/ -#ifdef __cplusplus -extern "C" { -#endif - -CURL *curl_easy_init(void); -CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...); -CURLcode curl_easy_perform(CURL *curl); -void curl_easy_cleanup(CURL *curl); - -/* - * NAME curl_easy_getinfo() - * - * DESCRIPTION - * - * Request internal information from the curl session with this function. The - * third argument MUST be a pointer to a long, a pointer to a char * or a - * pointer to a double (as the documentation describes elsewhere). The data - * pointed to will be filled in accordingly and can be relied upon only if the - * function returns CURLE_OK. This function is intended to get used *AFTER* a - * performed transfer, all results from this function are undefined until the - * transfer is completed. - */ -CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...); - - -/* - * NAME curl_easy_duphandle() - * - * DESCRIPTION - * - * Creates a new curl session handle with the same options set for the handle - * passed in. Duplicating a handle could only be a matter of cloning data and - * options, internal state info and things like persistant connections cannot - * be transfered. It is useful in multithreaded applications when you can run - * curl_easy_duphandle() for each new thread to avoid a series of identical - * curl_easy_setopt() invokes in every thread. - */ -CURL* curl_easy_duphandle(CURL *curl); - -/* - * NAME curl_easy_reset() - * - * DESCRIPTION - * - * Re-initializes a CURL handle to the default values. This puts back the - * handle to the same state as it was in when it was just created. - * - * It does keep: live connections, the Session ID cache, the DNS cache and the - * cookies. - */ -void curl_easy_reset(CURL *curl); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/Source/CTest/Curl/curl/mprintf.h b/Source/CTest/Curl/curl/mprintf.h deleted file mode 100644 index 65dc114..0000000 --- a/Source/CTest/Curl/curl/mprintf.h +++ /dev/null @@ -1,54 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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$ - ***************************************************************************/ - -#ifndef H_MPRINTF -#define H_MPRINTF - -#include <stdarg.h> -#include <stdio.h> /* needed for FILE */ - -int curl_mprintf(const char *format, ...); -int curl_mfprintf(FILE *fd, const char *format, ...); -int curl_msprintf(char *buffer, const char *format, ...); -int curl_msnprintf(char *buffer, size_t maxlength, const char *format, ...); -int curl_mvprintf(const char *format, va_list args); -int curl_mvfprintf(FILE *fd, const char *format, va_list args); -int curl_mvsprintf(char *buffer, const char *format, va_list args); -int curl_mvsnprintf(char *buffer, size_t maxlength, const char *format, va_list args); -char *curl_maprintf(const char *format, ...); -char *curl_mvaprintf(const char *format, va_list args); - -#ifdef _MPRINTF_REPLACE -# define printf curl_mprintf -# define fprintf curl_mfprintf -# define sprintf curl_msprintf -# define snprintf curl_msnprintf -# define vprintf curl_mvprintf -# define vfprintf curl_mvfprintf -# define vsprintf curl_mvsprintf -# define vsnprintf curl_mvsnprintf -# define aprintf curl_maprintf -# define vaprintf curl_mvaprintf -#endif - -#endif /* H_MPRINTF */ diff --git a/Source/CTest/Curl/curl/multi.h b/Source/CTest/Curl/curl/multi.h deleted file mode 100644 index 3a867ab..0000000 --- a/Source/CTest/Curl/curl/multi.h +++ /dev/null @@ -1,221 +0,0 @@ -#ifndef __CURL_MULTI_H -#define __CURL_MULTI_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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$ - ***************************************************************************/ -/* - This is meant to be the "external" header file. Don't give away any - internals here! - - This document presents a mixture of ideas from at least: - - Daniel Stenberg - - Steve Dekorte - - Sterling Hughes - - Ben Greear - - ------------------------------------------- - GOALS - - o Enable a "pull" interface. The application that uses libcurl decides where - and when to ask libcurl to get/send data. - - o Enable multiple simultaneous transfers in the same thread without making it - complicated for the application. - - o Enable the application to select() on its own file descriptors and curl's - file descriptors simultaneous easily. - -*/ -#if defined(_WIN32) && !defined(WIN32) -/* Chris Lewis mentioned that he doesn't get WIN32 defined, only _WIN32 so we - make this adjustment to catch this. */ -#define WIN32 1 -#endif - -#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__) -#include <winsock2.h> -#else - -/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish - libc5-based Linux systems. Only include it on system that are known to - require it! */ -#if defined(_AIX) || defined(NETWARE) -#include <sys/select.h> -#endif - -#include <sys/socket.h> -#include <sys/time.h> -#include <sys/types.h> -#endif - -#include "curl.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void CURLM; - -typedef enum { - CURLM_CALL_MULTI_PERFORM=-1, /* please call curl_multi_perform() soon */ - CURLM_OK, - CURLM_BAD_HANDLE, /* the passed-in handle is not a valid CURLM handle */ - CURLM_BAD_EASY_HANDLE, /* an easy handle was not good/valid */ - CURLM_OUT_OF_MEMORY, /* if you ever get this, you're in deep sh*t */ - CURLM_INTERNAL_ERROR, /* this is a libcurl bug */ - CURLM_LAST -} CURLMcode; - -typedef enum { - CURLMSG_NONE, /* first, not used */ - CURLMSG_DONE, /* This easy handle has completed. 'result' contains - the CURLcode of the transfer */ - CURLMSG_LAST /* last, not used */ -} CURLMSG; - -struct CURLMsg { - CURLMSG msg; /* what this message means */ - CURL *easy_handle; /* the handle it concerns */ - union { - void *whatever; /* message-specific data */ - CURLcode result; /* return code for transfer */ - } data; -}; -typedef struct CURLMsg CURLMsg; - -/* - * Name: curl_multi_init() - * - * Desc: inititalize multi-style curl usage - * Returns: a new CURLM handle to use in all 'curl_multi' functions. - */ -CURLM *curl_multi_init(void); - -/* - * Name: curl_multi_add_handle() - * - * Desc: add a standard curl handle to the multi stack - * Returns: CURLMcode type, general multi error code. - */ -CURLMcode curl_multi_add_handle(CURLM *multi_handle, - CURL *curl_handle); - - /* - * Name: curl_multi_remove_handle() - * - * Desc: removes a curl handle from the multi stack again - * Returns: CURLMcode type, general multi error code. - */ -CURLMcode curl_multi_remove_handle(CURLM *multi_handle, - CURL *curl_handle); - - /* - * Name: curl_multi_fdset() - * - * Desc: Ask curl for its fd_set sets. The app can use these to select() or - * poll() on. We want curl_multi_perform() called as soon as one of - * them are ready. - * Returns: CURLMcode type, general multi error code. - */ -CURLMcode curl_multi_fdset(CURLM *multi_handle, - fd_set *read_fd_set, - fd_set *write_fd_set, - fd_set *exc_fd_set, - int *max_fd); - - /* - * Name: curl_multi_perform() - * - * Desc: When the app thinks there's data available for curl it calls this - * function to read/write whatever there is right now. This returns - * as soon as the reads and writes are done. This function does not - * require that there actually is data available for reading or that - * data can be written, it can be called just in case. It returns - * the number of handles that still transfer data in the second - * argument's integer-pointer. - * - * Returns: CURLMcode type, general multi error code. *NOTE* that this only - * returns errors etc regarding the whole multi stack. There might - * still have occurred problems on invidual transfers even when this - * returns OK. - */ -CURLMcode curl_multi_perform(CURLM *multi_handle, - int *running_handles); - - /* - * Name: curl_multi_cleanup() - * - * Desc: Cleans up and removes a whole multi stack. It does not free or - * touch any individual easy handles in any way. We need to define - * in what state those handles will be if this function is called - * in the middle of a transfer. - * Returns: CURLMcode type, general multi error code. - */ -CURLMcode curl_multi_cleanup(CURLM *multi_handle); - -/* - * Name: curl_multi_info_read() - * - * Desc: Ask the multi handle if there's any messages/informationals from - * the individual transfers. Messages include informationals such as - * error code from the transfer or just the fact that a transfer is - * completed. More details on these should be written down as well. - * - * Repeated calls to this function will return a new struct each - * time, until a special "end of msgs" struct is returned as a signal - * that there is no more to get at this point. - * - * The data the returned pointer points to will not survive calling - * curl_multi_cleanup(). - * - * The 'CURLMsg' struct is meant to be very simple and only contain - * very basic informations. If more involved information is wanted, - * we will provide the particular "transfer handle" in that struct - * and that should/could/would be used in subsequent - * curl_easy_getinfo() calls (or similar). The point being that we - * must never expose complex structs to applications, as then we'll - * undoubtably get backwards compatibility problems in the future. - * - * Returns: A pointer to a filled-in struct, or NULL if it failed or ran out - * of structs. It also writes the number of messages left in the - * queue (after this read) in the integer the second argument points - * to. - */ -CURLMsg *curl_multi_info_read(CURLM *multi_handle, - int *msgs_in_queue); - -/* - * NAME curl_multi_strerror() - * - * DESCRIPTION - * - * The curl_multi_strerror function may be used to turn a CURLMcode value - * into the equivalent human readable error string. This is useful - * for printing meaningful error messages. - */ -const char *curl_multi_strerror(CURLMcode); - -#ifdef __cplusplus -} /* end of extern "C" */ -#endif - -#endif diff --git a/Source/CTest/Curl/curl/stdcheaders.h b/Source/CTest/Curl/curl/stdcheaders.h deleted file mode 100644 index 11c1e2f..0000000 --- a/Source/CTest/Curl/curl/stdcheaders.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef __STDC_HEADERS_H -#define __STDC_HEADERS_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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 <sys/types.h> - -size_t fread (void *, size_t, size_t, FILE *); -size_t fwrite (const void *, size_t, size_t, FILE *); - -int strcasecmp(const char *, const char *); -int strncasecmp(const char *, const char *, size_t); - -#endif diff --git a/Source/CTest/Curl/curl/types.h b/Source/CTest/Curl/curl/types.h deleted file mode 100644 index d37d6ae..0000000 --- a/Source/CTest/Curl/curl/types.h +++ /dev/null @@ -1 +0,0 @@ -/* not used */ diff --git a/Source/CTest/Curl/curl_memory.h b/Source/CTest/Curl/curl_memory.h deleted file mode 100644 index 4e32a67..0000000 --- a/Source/CTest/Curl/curl_memory.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef _CURL_MEMORY_H -#define _CURL_MEMORY_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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 <curl/curl.h> /* for the typedefs */ - -extern curl_malloc_callback Curl_cmalloc; -extern curl_free_callback Curl_cfree; -extern curl_realloc_callback Curl_crealloc; -extern curl_strdup_callback Curl_cstrdup; -extern curl_calloc_callback Curl_ccalloc; - -#ifndef CURLDEBUG -/* Only do this define-mania if we're not using the memdebug system, as that - has preference on this magic. */ -#undef strdup -#define strdup(ptr) Curl_cstrdup(ptr) -#undef malloc -#define malloc(size) Curl_cmalloc(size) -#undef calloc -#define calloc(nbelem,size) Curl_ccalloc(nbelem, size) -#undef realloc -#define realloc(ptr,size) Curl_crealloc(ptr, size) -#undef free -#define free(ptr) Curl_cfree(ptr) - -#endif - -#endif /* _CURL_MEMORY_H */ diff --git a/Source/CTest/Curl/curlx.h b/Source/CTest/Curl/curlx.h deleted file mode 100644 index 0dd9a09..0000000 --- a/Source/CTest/Curl/curlx.h +++ /dev/null @@ -1,95 +0,0 @@ -#ifndef __CURLX_H -#define __CURLX_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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$ - ***************************************************************************/ - -/* - * Defines protos and includes all header files that provide the curlx_* - * functions. The curlx_* functions are not part of the libcurl API, but are - * stand-alone functions whose sources can be built and linked by apps if need - * be. - */ - -#include <curl/mprintf.h> -/* this is still a public header file that provides the curl_mprintf() - functions while they still are offered publicly. They will be made library- - private one day */ - -#include "strequal.h" -/* "strequal.h" provides the strequal protos */ - -#include "strtoofft.h" -/* "strtoofft.h" provides this function: curlx_strtoofft(), returns a - curl_off_t number from a given string. -*/ - -#include "timeval.h" -/* - "timeval.h" sets up a 'struct timeval' even for platforms that otherwise - don't have one and has protos for these functions: - - curlx_tvnow() - curlx_tvdiff() - curlx_tvdiff_secs() -*/ - -/* Now setup curlx_ * names for the functions that are to become curlx_ and - be removed from a future libcurl official API: - curlx_getenv - curlx_mprintf (and its variations) - curlx_strequal - curlx_strnequal - -*/ - -#define curlx_getenv curl_getenv -#define curlx_strequal curl_strequal -#define curlx_strnequal curl_strnequal -#define curlx_mvsnprintf curl_mvsnprintf -#define curlx_msnprintf curl_msnprintf -#define curlx_maprintf curl_maprintf -#define curlx_mvaprintf curl_mvaprintf -#define curlx_msprintf curl_msprintf -#define curlx_mprintf curl_mprintf -#define curlx_mfprintf curl_mfprintf -#define curlx_mvsprintf curl_mvsprintf -#define curlx_mvprintf curl_mvprintf -#define curlx_mvfprintf curl_mvfprintf - -#ifdef ENABLE_CURLX_PRINTF -/* If this define is set, we define all "standard" printf() functions to use - the curlx_* version instead. It makes the source code transparant and - easier to understand/patch. */ -# define printf curlx_mprintf -# define fprintf curlx_mfprintf -# define sprintf curlx_msprintf -# define snprintf curlx_msnprintf -# define vprintf curlx_mvprintf -# define vfprintf curlx_mvfprintf -# define vsprintf curlx_mvsprintf -# define vsnprintf curlx_mvsnprintf -# define aprintf curlx_maprintf -# define vaprintf curlx_mvaprintf -#endif /* ENABLE_CURLX_PRINTF */ - -#endif /* __CURLX_H */ diff --git a/Source/CTest/Curl/dict.c b/Source/CTest/Curl/dict.c deleted file mode 100644 index 06cb6b6..0000000 --- a/Source/CTest/Curl/dict.c +++ /dev/null @@ -1,221 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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" - -/* -- WIN32 approved -- */ -#include <stdio.h> -#include <string.h> -#include <stdarg.h> -#include <stdlib.h> -#include <ctype.h> -#include <sys/types.h> -#include <sys/stat.h> - -#include <errno.h> - -#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__) -#include <time.h> -#include <io.h> -#else -#ifdef HAVE_SYS_SOCKET_H -#include <sys/socket.h> -#endif -#include <netinet/in.h> -#include <sys/time.h> -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif -#include <netdb.h> -#ifdef HAVE_ARPA_INET_H -#include <arpa/inet.h> -#endif -#ifdef HAVE_NET_IF_H -#include <net/if.h> -#endif -#include <sys/ioctl.h> -#include <signal.h> - -#ifdef HAVE_SYS_PARAM_H -#include <sys/param.h> -#endif - -#ifdef HAVE_SYS_SELECT_H -#include <sys/select.h> -#endif - - -#endif - -#include "urldata.h" -#include <curl/curl.h> -#include "transfer.h" -#include "sendf.h" - -#include "progress.h" -#include "strequal.h" -#include "dict.h" - -#define _MPRINTF_REPLACE /* use our functions only */ -#include <curl/mprintf.h> - -CURLcode Curl_dict(struct connectdata *conn) -{ - char *word; - char *ppath; - char *database = NULL; - char *strategy = NULL; - char *nthdef = NULL; /* This is not part of the protocol, but required - by RFC 2229 */ - CURLcode result; - struct SessionHandle *data=conn->data; - curl_socket_t sockfd = conn->sock[FIRSTSOCKET]; - - char *path = conn->path; - curl_off_t *bytecount = &conn->bytecount; - - if(conn->bits.user_passwd) { - /* AUTH is missing */ - } - - if (strnequal(path, DICT_MATCH, sizeof(DICT_MATCH)-1) || - strnequal(path, DICT_MATCH2, sizeof(DICT_MATCH2)-1) || - strnequal(path, DICT_MATCH3, sizeof(DICT_MATCH3)-1)) { - - word = strchr(path, ':'); - if (word) { - word++; - database = strchr(word, ':'); - if (database) { - *database++ = (char)0; - strategy = strchr(database, ':'); - if (strategy) { - *strategy++ = (char)0; - nthdef = strchr(strategy, ':'); - if (nthdef) { - *nthdef++ = (char)0; - } - } - } - } - - if ((word == NULL) || (*word == (char)0)) { - failf(data, "lookup word is missing"); - } - if ((database == NULL) || (*database == (char)0)) { - database = (char *)"!"; - } - if ((strategy == NULL) || (*strategy == (char)0)) { - strategy = (char *)"."; - } - - result = Curl_sendf(sockfd, conn, - "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\n" - "MATCH " - "%s " /* database */ - "%s " /* strategy */ - "%s\n" /* word */ - "QUIT\n", - - database, - strategy, - word - ); - if(result) - failf(data, "Failed sending DICT request"); - else - result = Curl_Transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount, - -1, NULL); /* no upload */ - if(result) - return result; - } - else if (strnequal(path, DICT_DEFINE, sizeof(DICT_DEFINE)-1) || - strnequal(path, DICT_DEFINE2, sizeof(DICT_DEFINE2)-1) || - strnequal(path, DICT_DEFINE3, sizeof(DICT_DEFINE3)-1)) { - - word = strchr(path, ':'); - if (word) { - word++; - database = strchr(word, ':'); - if (database) { - *database++ = (char)0; - nthdef = strchr(database, ':'); - if (nthdef) { - *nthdef++ = (char)0; - } - } - } - - if ((word == NULL) || (*word == (char)0)) { - failf(data, "lookup word is missing"); - } - if ((database == NULL) || (*database == (char)0)) { - database = (char *)"!"; - } - - result = Curl_sendf(sockfd, conn, - "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\n" - "DEFINE " - "%s " /* database */ - "%s\n" /* word */ - "QUIT\n", - database, - word); - if(result) - failf(data, "Failed sending DICT request"); - else - result = Curl_Transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount, - -1, NULL); /* no upload */ - - if(result) - return result; - - } - else { - - ppath = strchr(path, '/'); - if (ppath) { - int i; - - ppath++; - for (i = 0; ppath[i]; i++) { - if (ppath[i] == ':') - ppath[i] = ' '; - } - result = Curl_sendf(sockfd, conn, - "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\n" - "%s\n" - "QUIT\n", ppath); - if(result) - failf(data, "Failed sending DICT request"); - else - result = Curl_Transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount, - -1, NULL); - if(result) - return result; - } - } - (void)nthdef; - - return CURLE_OK; -} diff --git a/Source/CTest/Curl/dict.h b/Source/CTest/Curl/dict.h deleted file mode 100644 index 4301f01..0000000 --- a/Source/CTest/Curl/dict.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef __DICT_H -#define __DICT_H - -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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$ - ***************************************************************************/ -#ifndef CURL_DISABLE_DICT -CURLcode Curl_dict(struct connectdata *conn); -CURLcode Curl_dict_done(struct connectdata *conn); -#endif -#endif diff --git a/Source/CTest/Curl/easy.c b/Source/CTest/Curl/easy.c deleted file mode 100644 index fb116fd..0000000 --- a/Source/CTest/Curl/easy.c +++ /dev/null @@ -1,583 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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" - -/* -- WIN32 approved -- */ -#include <stdio.h> -#include <string.h> -#include <stdarg.h> -#include <stdlib.h> -#include <ctype.h> -#include <sys/types.h> -#include <sys/stat.h> - -#include <errno.h> - -#include "strequal.h" - -#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__) -#include <time.h> -#include <io.h> -#else -#ifdef HAVE_SYS_SOCKET_H -#include <sys/socket.h> -#endif -#include <netinet/in.h> -#include <sys/time.h> -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif -#include <netdb.h> -#ifdef HAVE_ARPA_INET_H -#include <arpa/inet.h> -#endif -#ifdef HAVE_NET_IF_H -#include <net/if.h> -#endif -#include <sys/ioctl.h> -#include <signal.h> - -#ifdef HAVE_SYS_PARAM_H -#include <sys/param.h> -#endif - -#ifdef HAVE_SYS_SELECT_H -#include <sys/select.h> -#endif - -#endif /* WIN32 ... */ - -#include "urldata.h" -#include <curl/curl.h> -#include "transfer.h" -#include "ssluse.h" -#include "url.h" -#include "getinfo.h" -#include "hostip.h" -#include "share.h" -#include "curl_memory.h" - -#define _MPRINTF_REPLACE /* use our functions only */ -#include <curl/mprintf.h> - -/* The last #include file should be: */ -#include "memdebug.h" - -#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__) -/* win32_cleanup() is for win32 socket cleanup functionality, the opposite - of win32_init() */ -static void win32_cleanup(void) -{ - WSACleanup(); -} - -/* win32_init() performs win32 socket initialization to properly setup the - stack to allow networking */ -static CURLcode win32_init(void) -{ - WORD wVersionRequested; - WSADATA wsaData; - int err; - -#ifdef ENABLE_IPV6 - wVersionRequested = MAKEWORD(2, 0); -#else - wVersionRequested = MAKEWORD(1, 1); -#endif - - err = WSAStartup(wVersionRequested, &wsaData); - - if (err != 0) - /* Tell the user that we couldn't find a useable */ - /* winsock.dll. */ - return CURLE_FAILED_INIT; - - /* Confirm that the Windows Sockets DLL supports what we need.*/ - /* Note that if the DLL supports versions greater */ - /* than wVersionRequested, it will still return */ - /* wVersionRequested in wVersion. wHighVersion contains the */ - /* highest supported version. */ - - if ( LOBYTE( wsaData.wVersion ) != LOBYTE(wVersionRequested) || - HIBYTE( wsaData.wVersion ) != HIBYTE(wVersionRequested) ) { - /* Tell the user that we couldn't find a useable */ - - /* winsock.dll. */ - WSACleanup(); - return CURLE_FAILED_INIT; - } - /* The Windows Sockets DLL is acceptable. Proceed. */ - return CURLE_OK; -} - -#else -/* These functions exist merely to prevent compiler warnings */ -static CURLcode win32_init(void) { return CURLE_OK; } -static void win32_cleanup(void) { } -#endif - -#ifdef USE_LIBIDN -/* - * Initialise use of IDNA library. - * It falls back to ASCII if $CHARSET isn't defined. This doesn't work for - * idna_to_ascii_lz(). - */ -static void idna_init (void) -{ -#ifdef WIN32 - char buf[60]; - UINT cp = GetACP(); - - if (!getenv("CHARSET") && cp > 0) { - snprintf(buf, sizeof(buf), "CHARSET=cp%u", cp); - putenv(buf); - } -#else - /* to do? */ -#endif -} -#endif /* USE_LIBIDN */ - -/* true globals -- for curl_global_init() and curl_global_cleanup() */ -static unsigned int initialized = 0; -static long init_flags = 0; - -/* - * If a memory-using function (like curl_getenv) is used before - * curl_global_init() is called, we need to have these pointers set already. - */ -curl_malloc_callback Curl_cmalloc = (curl_malloc_callback)malloc; -curl_free_callback Curl_cfree = (curl_free_callback)free; -curl_realloc_callback Curl_crealloc = (curl_realloc_callback)realloc; -curl_strdup_callback Curl_cstrdup = (curl_strdup_callback)strdup; -curl_calloc_callback Curl_ccalloc = (curl_calloc_callback)calloc; - -/** - * curl_global_init() globally initializes cURL given a bitwise set of the - * different features of what to initialize. - */ -CURLcode curl_global_init(long flags) -{ - if (initialized) - return CURLE_OK; - - /* Setup the default memory functions here (again) */ - Curl_cmalloc = (curl_malloc_callback)malloc; - Curl_cfree = (curl_free_callback)free; - Curl_crealloc = (curl_realloc_callback)realloc; - Curl_cstrdup = (curl_strdup_callback)strdup; - Curl_ccalloc = (curl_calloc_callback)calloc; - - if (flags & CURL_GLOBAL_SSL) - Curl_SSL_init(); - - if (flags & CURL_GLOBAL_WIN32) - if (win32_init() != CURLE_OK) - return CURLE_FAILED_INIT; - -#ifdef _AMIGASF - if(!amiga_init()) - return CURLE_FAILED_INIT; -#endif - -#ifdef USE_LIBIDN - idna_init(); -#endif - - initialized = 1; - init_flags = flags; - - return CURLE_OK; -} - -/* - * curl_global_init_mem() globally initializes cURL and also registers the - * user provided callback routines. - */ -CURLcode curl_global_init_mem(long flags, curl_malloc_callback m, - curl_free_callback f, curl_realloc_callback r, - curl_strdup_callback s, curl_calloc_callback c) -{ - CURLcode code; - - /* Invalid input, return immediately */ - if (!m || !f || !r || !s || !c) - return CURLE_FAILED_INIT; - - /* Already initialized, don't do it again */ - if ( initialized ) - return CURLE_OK; - - /* Call the actual init function first */ - code = curl_global_init(flags); - if (code == CURLE_OK) { - Curl_cmalloc = m; - Curl_cfree = f; - Curl_cstrdup = s; - Curl_crealloc = r; - Curl_ccalloc = c; - } - - return code; -} - -/** - * curl_global_cleanup() globally cleanups cURL, uses the value of - * "init_flags" to determine what needs to be cleaned up and what doesn't. - */ -void curl_global_cleanup(void) -{ - if (!initialized) - return; - - Curl_global_host_cache_dtor(); - - if (init_flags & CURL_GLOBAL_SSL) - Curl_SSL_cleanup(); - - if (init_flags & CURL_GLOBAL_WIN32) - win32_cleanup(); - -#ifdef _AMIGASF - amiga_cleanup(); -#endif - - initialized = 0; - init_flags = 0; -} - -/* - * curl_easy_init() is the external interface to alloc, setup and init an - * easy handle that is returned. If anything goes wrong, NULL is returned. - */ -CURL *curl_easy_init(void) -{ - CURLcode res; - struct SessionHandle *data; - - /* Make sure we inited the global SSL stuff */ - if (!initialized) { - res = curl_global_init(CURL_GLOBAL_DEFAULT); - if(res) - /* something in the global init failed, return nothing */ - return NULL; - } - - /* We use curl_open() with undefined URL so far */ - res = Curl_open(&data); - if(res != CURLE_OK) - return NULL; - - return data; -} - -/* - * curl_easy_setopt() is the external interface for setting options on an - * easy handle. - */ -typedef int (*func_T)(void); -CURLcode curl_easy_setopt(CURL *curl, CURLoption tag, ...) -{ - va_list arg; - func_T param_func; - long param_long; - void *param_obj; - curl_off_t param_offset; - struct SessionHandle *data = curl; - CURLcode ret; - - if(!curl) - return CURLE_BAD_FUNCTION_ARGUMENT; - - va_start(arg, tag); - - /* PORTING NOTE: - Object pointers can't necessarily be casted to function pointers and - therefore we need to know what type it is and read the correct type - at once. This should also correct problems with different sizes of - the types. - */ - - if(tag < CURLOPTTYPE_OBJECTPOINT) { - /* This is a LONG type */ - param_long = va_arg(arg, long); - ret = Curl_setopt(data, tag, param_long); - } - else if(tag < CURLOPTTYPE_FUNCTIONPOINT) { - /* This is a object pointer type */ - param_obj = va_arg(arg, void *); - ret = Curl_setopt(data, tag, param_obj); - } - else if(tag < CURLOPTTYPE_OFF_T) { - /* This is a function pointer type */ - param_func = va_arg(arg, func_T ); - ret = Curl_setopt(data, tag, param_func); - } - else { - /* This is a curl_off_t type */ - param_offset = va_arg(arg, curl_off_t); - ret = Curl_setopt(data, tag, param_offset); - } - - va_end(arg); - return ret; -} - -/* - * curl_easy_perform() is the external interface that performs a transfer - * previously setup. - */ -CURLcode curl_easy_perform(CURL *curl) -{ - struct SessionHandle *data = (struct SessionHandle *)curl; - - if(!data) - return CURLE_BAD_FUNCTION_ARGUMENT; - - if ( ! (data->share && data->share->hostcache) ) { - - if (Curl_global_host_cache_use(data) && - data->hostcache != Curl_global_host_cache_get()) { - if (data->hostcache) - Curl_hash_destroy(data->hostcache); - data->hostcache = Curl_global_host_cache_get(); - } - - if (!data->hostcache) { - data->hostcache = Curl_mk_dnscache(); - - if(!data->hostcache) - /* While we possibly could survive and do good without a host cache, - the fact that creating it failed indicates that things are truly - screwed up and we should bail out! */ - return CURLE_OUT_OF_MEMORY; - } - - } - - return Curl_perform(data); -} - -/* - * curl_easy_cleanup() is the external interface to cleaning/freeing the given - * easy handle. - */ -void curl_easy_cleanup(CURL *curl) -{ - struct SessionHandle *data = (struct SessionHandle *)curl; - - if(!data) - return; - - if ( ! (data->share && data->share->hostcache) ) { - if ( !Curl_global_host_cache_use(data)) { - Curl_hash_destroy(data->hostcache); - } - } - Curl_close(data); -} - -/* - * curl_easy_getinfo() is an external interface that allows an app to retrieve - * information from a performed transfer and similar. - */ -CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...) -{ - va_list arg; - void *paramp; - struct SessionHandle *data = (struct SessionHandle *)curl; - - va_start(arg, info); - paramp = va_arg(arg, void *); - - return Curl_getinfo(data, info, paramp); -} - -/* - * curl_easy_duphandle() is an external interface to allow duplication of a - * given input easy handle. The returned handle will be a new working handle - * with all options set exactly as the input source handle. - */ -CURL *curl_easy_duphandle(CURL *incurl) -{ - bool fail = TRUE; - struct SessionHandle *data=(struct SessionHandle *)incurl; - - struct SessionHandle *outcurl = (struct SessionHandle *) - calloc(sizeof(struct SessionHandle), 1); - - if(NULL == outcurl) - return NULL; /* failure */ - - do { - - /* - * We setup a few buffers we need. We should probably make them - * get setup on-demand in the code, as that would probably decrease - * the likeliness of us forgetting to init a buffer here in the future. - */ - outcurl->state.headerbuff=(char*)malloc(HEADERSIZE); - if(!outcurl->state.headerbuff) { - break; - } - outcurl->state.headersize=HEADERSIZE; - - /* copy all userdefined values */ - outcurl->set = data->set; - outcurl->state.numconnects = data->state.numconnects; - outcurl->state.connects = (struct connectdata **) - malloc(sizeof(struct connectdata *) * outcurl->state.numconnects); - - if(!outcurl->state.connects) { - break; - } - - memset(outcurl->state.connects, 0, - sizeof(struct connectdata *)*outcurl->state.numconnects); - - outcurl->progress.flags = data->progress.flags; - outcurl->progress.callback = data->progress.callback; - -#ifndef CURL_DISABLE_HTTP - if(data->cookies) { - /* If cookies are enabled in the parent handle, we enable them - in the clone as well! */ - outcurl->cookies = Curl_cookie_init(data, - data->cookies->filename, - outcurl->cookies, - data->set.cookiesession); - if(!outcurl->cookies) { - break; - } - } -#endif /* CURL_DISABLE_HTTP */ - - /* duplicate all values in 'change' */ - if(data->change.url) { - outcurl->change.url = strdup(data->change.url); - if(!outcurl->change.url) - break; - outcurl->change.url_alloc = TRUE; - } - if(data->change.proxy) { - outcurl->change.proxy = strdup(data->change.proxy); - if(!outcurl->change.proxy) - break; - outcurl->change.proxy_alloc = TRUE; - } - if(data->change.referer) { - outcurl->change.referer = strdup(data->change.referer); - if(!outcurl->change.referer) - break; - outcurl->change.referer_alloc = TRUE; - } - -#ifdef USE_ARES - /* If we use ares, we setup a new ares channel for the new handle */ - if(ARES_SUCCESS != ares_init(&outcurl->state.areschannel)) - break; -#endif - - fail = FALSE; /* we reach this point and thus we are OK */ - - } while(0); - - if(fail) { - if(outcurl) { - if(outcurl->state.connects) - free(outcurl->state.connects); - if(outcurl->state.headerbuff) - free(outcurl->state.headerbuff); - if(outcurl->change.proxy) - free(outcurl->change.proxy); - if(outcurl->change.url) - free(outcurl->change.url); - if(outcurl->change.referer) - free(outcurl->change.referer); - free(outcurl); /* free the memory again */ - outcurl = NULL; - } - } - - return outcurl; -} - -/* - * curl_easy_reset() is an external interface that allows an app to re- - * initialize a session handle to the default values. - */ -void curl_easy_reset(CURL *curl) -{ - struct SessionHandle *data = (struct SessionHandle *)curl; - - /* zero out UserDefined data: */ - memset(&data->set, 0, sizeof(struct UserDefined)); - - /* zero out Progress data: */ - memset(&data->progress, 0, sizeof(struct Progress)); - - /* The remainder of these calls have been taken from Curl_open() */ - - data->set.out = stdout; /* default output to stdout */ - data->set.in = stdin; /* default input from stdin */ - data->set.err = stderr; /* default stderr to stderr */ - - /* use fwrite as default function to store output */ - data->set.fwrite = (curl_write_callback)fwrite; - - /* use fread as default function to read input */ - data->set.fread = (curl_read_callback)fread; - - data->set.infilesize = -1; /* we don't know any size */ - - data->state.current_speed = -1; /* init to negative == impossible */ - - data->set.httpreq = HTTPREQ_GET; /* Default HTTP request */ - data->set.ftp_use_epsv = TRUE; /* FTP defaults to EPSV operations */ - data->set.ftp_use_eprt = TRUE; /* FTP defaults to EPRT operations */ - - data->set.dns_cache_timeout = 60; /* Timeout every 60 seconds by default */ - - /* make libcurl quiet by default: */ - data->set.hide_progress = TRUE; /* CURLOPT_NOPROGRESS changes these */ - - /* Set the default size of the SSL session ID cache */ - data->set.ssl.numsessions = 5; - - data->set.proxyport = 1080; - data->set.proxytype = CURLPROXY_HTTP; /* defaults to HTTP proxy */ - data->set.httpauth = CURLAUTH_BASIC; /* defaults to basic */ - data->set.proxyauth = CURLAUTH_BASIC; /* defaults to basic */ - - /* - * libcurl 7.10 introduced SSL verification *by default*! This needs to be - * switched off unless wanted. - */ - data->set.ssl.verifypeer = TRUE; - data->set.ssl.verifyhost = 2; -#ifdef CURL_CA_BUNDLE - /* This is our prefered CA cert bundle since install time */ - data->set.ssl.CAfile = (char *)CURL_CA_BUNDLE; -#endif -} diff --git a/Source/CTest/Curl/escape.c b/Source/CTest/Curl/escape.c deleted file mode 100644 index 2b9a883..0000000 --- a/Source/CTest/Curl/escape.c +++ /dev/null @@ -1,135 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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$ - ***************************************************************************/ - -/* Escape and unescape URL encoding in strings. The functions return a new - * allocated string or NULL if an error occurred. */ - -#include "setup.h" -#include <ctype.h> -#include <curl/curl.h> - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include "curl_memory.h" - -#define _MPRINTF_REPLACE /* use our functions only */ -#include <curl/mprintf.h> - -/* The last #include file should be: */ -#include "memdebug.h" - -char *curl_escape(const char *string, int inlength) -{ - size_t alloc = (inlength?(size_t)inlength:strlen(string))+1; - char *ns; - char *testing_ptr; - unsigned char in; - size_t newlen = alloc; - int strindex=0; - size_t length; - - ns = malloc(alloc); - if(!ns) - return NULL; - - length = alloc-1; - while(length--) { - in = *string; - if(!(in >= 'a' && in <= 'z') && - !(in >= 'A' && in <= 'Z') && - !(in >= '0' && in <= '9')) { - /* encode it */ - newlen += 2; /* the size grows with two, since this'll become a %XX */ - if(newlen > alloc) { - alloc *= 2; - testing_ptr = realloc(ns, alloc); - if(!testing_ptr) { - free( ns ); - return NULL; - } - else { - ns = testing_ptr; - } - } - snprintf(&ns[strindex], 4, "%%%02X", in); - - strindex+=3; - } - else { - /* just copy this */ - ns[strindex++]=in; - } - string++; - } - ns[strindex]=0; /* terminate it */ - return ns; -} - -#define ishex(in) ((in >= 'a' && in <= 'f') || \ - (in >= 'A' && in <= 'F') || \ - (in >= '0' && in <= '9')) - -char *curl_unescape(const char *string, int length) -{ - int alloc = (length?length:(int)strlen(string))+1; - char *ns = malloc(alloc); - unsigned char in; - int strindex=0; - long hex; - - if( !ns ) - return NULL; - - while(--alloc > 0) { - in = *string; - if(('%' == in) && ishex(string[1]) && ishex(string[2])) { - /* this is two hexadecimal digits following a '%' */ - char hexstr[3]; - char *ptr; - hexstr[0] = string[1]; - hexstr[1] = string[2]; - hexstr[2] = 0; - - hex = strtol(hexstr, &ptr, 16); - - in = (unsigned char)hex; /* this long is never bigger than 255 anyway */ - string+=2; - alloc-=2; - } - - ns[strindex++] = in; - string++; - } - ns[strindex]=0; /* terminate it */ - return ns; -} - -/* For operating systems/environments that use different malloc/free - ssystems for the app and for this library, we provide a free that uses - the library's memory system */ -void curl_free(void *p) -{ - if(p) - free(p); -} diff --git a/Source/CTest/Curl/escape.h b/Source/CTest/Curl/escape.h deleted file mode 100644 index 4d29236..0000000 --- a/Source/CTest/Curl/escape.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef __ESCAPE_H -#define __ESCAPE_H - -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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$ - ***************************************************************************/ -/* Escape and unescape URL encoding in strings. The functions return a new - * allocated string or NULL if an error occurred. */ - -char *curl_escape(const char *string, int length); -char *curl_unescape(const char *string, int length); - -#endif diff --git a/Source/CTest/Curl/file.c b/Source/CTest/Curl/file.c deleted file mode 100644 index cd4366c..0000000 --- a/Source/CTest/Curl/file.c +++ /dev/null @@ -1,390 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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" - -#ifndef CURL_DISABLE_FILE -/* -- WIN32 approved -- */ -#include <stdio.h> -#include <string.h> -#include <stdarg.h> -#include <stdlib.h> -#include <ctype.h> -#include <sys/types.h> -#include <sys/stat.h> - -#include <errno.h> - -#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__) -#include <time.h> -#include <io.h> -#include <fcntl.h> -#else -#ifdef HAVE_SYS_SOCKET_H -#include <sys/socket.h> -#endif -#ifdef HAVE_NETINET_IN_H -#include <netinet/in.h> -#endif -#include <sys/time.h> -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif -#ifdef HAVE_NETDB_H -#include <netdb.h> -#endif -#ifdef HAVE_ARPA_INET_H -#include <arpa/inet.h> -#endif -#ifdef HAVE_NET_IF_H -#include <net/if.h> -#endif -#include <sys/ioctl.h> -#include <signal.h> - -#ifdef HAVE_SYS_PARAM_H -#include <sys/param.h> -#endif - -#ifdef HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif -#ifdef HAVE_FCNTL_H -#include <fcntl.h> -#endif - -#endif - -#include "urldata.h" -#include <curl/curl.h> -#include "progress.h" -#include "sendf.h" -#include "escape.h" -#include "file.h" -#include "speedcheck.h" -#include "getinfo.h" -#include "transfer.h" -#include "url.h" -#include "curl_memory.h" - -#define _MPRINTF_REPLACE /* use our functions only */ -#include <curl/mprintf.h> - -/* The last #include file should be: */ -#include "memdebug.h" - -/* - * Curl_file_connect() gets called from Curl_protocol_connect() to allow us to - * do protocol-specific actions at connect-time. We emulate a - * connect-then-transfer protocol and "connect" to the file here - */ -CURLcode Curl_file_connect(struct connectdata *conn) -{ - char *real_path = curl_unescape(conn->path, 0); - struct FILEPROTO *file; - int fd; -#if defined(WIN32) || defined(__EMX__) - int i; - char *actual_path; -#endif - - if(!real_path) - return CURLE_OUT_OF_MEMORY; - - file = (struct FILEPROTO *)calloc(sizeof(struct FILEPROTO), 1); - if(!file) { - free(real_path); - return CURLE_OUT_OF_MEMORY; - } - - conn->proto.file = file; - -#if defined(WIN32) || defined(__EMX__) - /* If the first character is a slash, and there's - something that looks like a drive at the beginning of - the path, skip the slash. If we remove the initial - slash in all cases, paths without drive letters end up - relative to the current directory which isn't how - browsers work. - - Some browsers accept | instead of : as the drive letter - separator, so we do too. - - On other platforms, we need the slash to indicate an - absolute pathname. On Windows, absolute paths start - with a drive letter. - */ - actual_path = real_path; - if ((actual_path[0] == '/') && - actual_path[1] && - (actual_path[2] == ':' || actual_path[2] == '|')) - { - actual_path[2] = ':'; - actual_path++; - } - - /* change path separators from '/' to '\\' for Windows and OS/2 */ - for (i=0; actual_path[i] != '\0'; ++i) - if (actual_path[i] == '/') - actual_path[i] = '\\'; - - fd = open(actual_path, O_RDONLY | O_BINARY); /* no CR/LF translation! */ - file->path = actual_path; -#else - fd = open(real_path, O_RDONLY); - file->path = real_path; -#endif - file->freepath = real_path; /* free this when done */ - - if(!conn->data->set.upload && (fd == -1)) { - failf(conn->data, "Couldn't open file %s", conn->path); - Curl_file_done(conn, CURLE_FILE_COULDNT_READ_FILE); - return CURLE_FILE_COULDNT_READ_FILE; - } - file->fd = fd; - - return CURLE_OK; -} - -#if defined(WIN32) && (SIZEOF_CURL_OFF_T > 4) -#define lseek(x,y,z) _lseeki64(x, y, z) -#endif - -CURLcode Curl_file_done(struct connectdata *conn, - CURLcode status) -{ - struct FILEPROTO *file = conn->proto.file; - (void)status; /* not used */ - Curl_safefree(file->freepath); - - return CURLE_OK; -} - -#if defined(WIN32) || defined(__EMX__) -#define DIRSEP '\\' -#else -#define DIRSEP '/' -#endif - -static CURLcode file_upload(struct connectdata *conn) -{ - struct FILEPROTO *file = conn->proto.file; - char *dir = strchr(file->path, DIRSEP); - FILE *fp; - CURLcode res=CURLE_OK; - struct SessionHandle *data = conn->data; - char *buf = data->state.buffer; - size_t nread; - size_t nwrite; - curl_off_t bytecount = 0; - struct timeval now = Curl_tvnow(); - - /* - * Since FILE: doesn't do the full init, we need to provide some extra - * assignments here. - */ - conn->fread = data->set.fread; - conn->fread_in = data->set.in; - conn->upload_fromhere = buf; - - if(!dir) - return CURLE_FILE_COULDNT_READ_FILE; /* fix: better error code */ - - if(!dir[1]) - return CURLE_FILE_COULDNT_READ_FILE; /* fix: better error code */ - - fp = fopen(file->path, "wb"); - if(!fp) { - failf(data, "Can't open %s for writing", file->path); - return CURLE_WRITE_ERROR; - } - - if(-1 != data->set.infilesize) - /* known size of data to "upload" */ - Curl_pgrsSetUploadSize(data, data->set.infilesize); - - while (res == CURLE_OK) { - int readcount; - res = Curl_fillreadbuffer(conn, BUFSIZE, &readcount); - if(res) - return res; - - nread = (size_t)readcount; - - if (nread <= 0) - break; - - /* write the data to the target */ - nwrite = fwrite(buf, 1, nread, fp); - if(nwrite != nread) { - res = CURLE_SEND_ERROR; - break; - } - - bytecount += nread; - - Curl_pgrsSetUploadCounter(data, bytecount); - - if(Curl_pgrsUpdate(conn)) - res = CURLE_ABORTED_BY_CALLBACK; - else - res = Curl_speedcheck(data, now); - } - if(!res && Curl_pgrsUpdate(conn)) - res = CURLE_ABORTED_BY_CALLBACK; - - fclose(fp); - - return res; -} - -/* - * Curl_file() is the protocol-specific function for the do-phase, separated - * from the connect-phase above. Other protocols merely setup the transfer in - * the do-phase, to have it done in the main transfer loop but since some - * platforms we support don't allow select()ing etc on file handles (as - * opposed to sockets) we instead perform the whole do-operation in this - * function. - */ -CURLcode Curl_file(struct connectdata *conn) -{ - /* This implementation ignores the host name in conformance with - RFC 1738. Only local files (reachable via the standard file system) - are supported. This means that files on remotely mounted directories - (via NFS, Samba, NT sharing) can be accessed through a file:// URL - */ - CURLcode res = CURLE_OK; - struct stat statbuf; - curl_off_t expected_size=0; - bool fstated=FALSE; - ssize_t nread; - struct SessionHandle *data = conn->data; - char *buf = data->state.buffer; - curl_off_t bytecount = 0; - int fd; - struct timeval now = Curl_tvnow(); - - Curl_readwrite_init(conn); - Curl_initinfo(data); - Curl_pgrsStartNow(data); - - if(data->set.upload) - return file_upload(conn); - - /* get the fd from the connection phase */ - fd = conn->proto.file->fd; - - /* VMS: This only works reliable for STREAMLF files */ - if( -1 != fstat(fd, &statbuf)) { - /* we could stat it, then read out the size */ - expected_size = statbuf.st_size; - fstated = TRUE; - } - - /* If we have selected NOBODY and HEADER, it means that we only want file - information. Which for FILE can't be much more than the file size and - date. */ - if(conn->bits.no_body && data->set.include_header && fstated) { - CURLcode result; - snprintf(buf, sizeof(data->state.buffer), - "Content-Length: %" FORMAT_OFF_T "\r\n", expected_size); - result = Curl_client_write(data, CLIENTWRITE_BOTH, buf, 0); - if(result) - return result; - - result = Curl_client_write(data, CLIENTWRITE_BOTH, - (char *)"Accept-ranges: bytes\r\n", 0); - if(result) - return result; - -#ifdef HAVE_STRFTIME - if(fstated) { - struct tm *tm; - time_t cuClock = (time_t)statbuf.st_mtime; -#ifdef HAVE_GMTIME_R - struct tm buffer; - tm = (struct tm *)gmtime_r(&cuClock, &buffer); -#else - tm = gmtime(&cuClock); -#endif - /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */ - strftime(buf, BUFSIZE-1, "Last-Modified: %a, %d %b %Y %H:%M:%S GMT\r\n", - tm); - result = Curl_client_write(data, CLIENTWRITE_BOTH, buf, 0); - } -#endif - return result; - } - - /* 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 (fstated && (expected_size == 0)) - return CURLE_OK; - - /* The following is a shortcut implementation of file reading - this is both more efficient than the former call to download() and - it avoids problems with select() and recv() on file descriptors - in Winsock */ - if(fstated) - Curl_pgrsSetDownloadSize(data, expected_size); - - if(conn->resume_from) - lseek(fd, conn->resume_from, SEEK_SET); - - Curl_pgrsTime(data, TIMER_STARTTRANSFER); - - while (res == CURLE_OK) { - nread = read(fd, buf, BUFSIZE-1); - - if ( nread > 0) - buf[nread] = 0; - - if (nread <= 0) - break; - - bytecount += nread; - - res = Curl_client_write(data, CLIENTWRITE_BODY, buf, nread); - if(res) - return res; - - Curl_pgrsSetDownloadCounter(data, bytecount); - - if(Curl_pgrsUpdate(conn)) - res = CURLE_ABORTED_BY_CALLBACK; - else - res = Curl_speedcheck(data, now); - } - if(Curl_pgrsUpdate(conn)) - res = CURLE_ABORTED_BY_CALLBACK; - - close(fd); - - return res; -} -#endif diff --git a/Source/CTest/Curl/file.h b/Source/CTest/Curl/file.h deleted file mode 100644 index 689b8ae..0000000 --- a/Source/CTest/Curl/file.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef __FILE_H -#define __FILE_H - -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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$ - ***************************************************************************/ -#ifndef CURL_DISABLE_FILE -CURLcode Curl_file(struct connectdata *); -CURLcode Curl_file_done(struct connectdata *, CURLcode); -CURLcode Curl_file_connect(struct connectdata *); -#endif -#endif diff --git a/Source/CTest/Curl/formdata.c b/Source/CTest/Curl/formdata.c deleted file mode 100644 index 5abff6e..0000000 --- a/Source/CTest/Curl/formdata.c +++ /dev/null @@ -1,1484 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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$ - ***************************************************************************/ - -/* - Debug the form generator stand-alone by compiling this source file with: - - gcc -DHAVE_CONFIG_H -I../ -g -D_FORM_DEBUG -o formdata -I../include formdata.c strequal.c - - run the 'formdata' executable the output should end with: - All Tests seem to have worked ... - and the following parts should be there: - -Content-Disposition: form-data; name="simple_COPYCONTENTS" -value for simple COPYCONTENTS - -Content-Disposition: form-data; name="COPYCONTENTS_+_CONTENTTYPE" -Content-Type: image/gif -value for COPYCONTENTS + CONTENTTYPE - -Content-Disposition: form-data; name="PRNAME_+_NAMELENGTH_+_COPYNAME_+_CONTENTSLENGTH" -vlue for PTRNAME + NAMELENGTH + COPYNAME + CONTENTSLENGTH -(or you might see P^@RNAME and v^@lue at the start) - -Content-Disposition: form-data; name="simple_PTRCONTENTS" -value for simple PTRCONTENTS - -Content-Disposition: form-data; name="PTRCONTENTS_+_CONTENTSLENGTH" -vlue for PTRCONTENTS + CONTENTSLENGTH -(or you might see v^@lue at the start) - -Content-Disposition: form-data; name="PTRCONTENTS_+_CONTENTSLENGTH_+_CONTENTTYPE" -Content-Type: text/plain -vlue for PTRCOTNENTS + CONTENTSLENGTH + CONTENTTYPE -(or you might see v^@lue at the start) - -Content-Disposition: form-data; name="FILE1_+_CONTENTTYPE"; filename="inet_ntoa_r.h" -Content-Type: text/html -... - -Content-Disposition: form-data; name="FILE1_+_FILE2" -Content-Type: multipart/mixed, boundary=curlz1s0dkticx49MV1KGcYP5cvfSsz -... -Content-Disposition: attachment; filename="inet_ntoa_r.h" -Content-Type: text/plain -... -Content-Disposition: attachment; filename="Makefile.b32.resp" -Content-Type: text/plain -... - -Content-Disposition: form-data; name="FILE1_+_FILE2_+_FILE3" -Content-Type: multipart/mixed, boundary=curlirkYPmPwu6FrJ1vJ1u1BmtIufh1 -... -Content-Disposition: attachment; filename="inet_ntoa_r.h" -Content-Type: text/plain -... -Content-Disposition: attachment; filename="Makefile.b32.resp" -Content-Type: text/plain -... -Content-Disposition: attachment; filename="inet_ntoa_r.h" -Content-Type: text/plain -... - - -Content-Disposition: form-data; name="ARRAY: FILE1_+_FILE2_+_FILE3" -Content-Type: multipart/mixed, boundary=curlirkYPmPwu6FrJ1vJ1u1BmtIufh1 -... -Content-Disposition: attachment; filename="inet_ntoa_r.h" -Content-Type: text/plain -... -Content-Disposition: attachment; filename="Makefile.b32.resp" -Content-Type: text/plain -... -Content-Disposition: attachment; filename="inet_ntoa_r.h" -Content-Type: text/plain -... - -Content-Disposition: form-data; name="FILECONTENT" -... - - */ - -#include "setup.h" -#include <curl/curl.h> - -/* Length of the random boundary string. */ -#define BOUNDARY_LENGTH 40 - -#ifndef CURL_DISABLE_HTTP - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdarg.h> -#include <time.h> -#include <sys/stat.h> -#include "formdata.h" -#include "strequal.h" -#include "curl_memory.h" - -#define _MPRINTF_REPLACE /* use our functions only */ -#include <curl/mprintf.h> - -/* The last #include file should be: */ -#include "memdebug.h" - -/* What kind of Content-Type to use on un-specified files with unrecognized - extensions. */ -#define HTTPPOST_CONTENTTYPE_DEFAULT "application/octet-stream" - -#define FORM_FILE_SEPARATOR ',' -#define FORM_TYPE_SEPARATOR ';' - -/*************************************************************************** - * - * AddHttpPost() - * - * Adds a HttpPost structure to the list, if parent_post is given becomes - * a subpost of parent_post instead of a direct list element. - * - * Returns newly allocated HttpPost on success and NULL if malloc failed. - * - ***************************************************************************/ -static struct curl_httppost * -AddHttpPost(char * name, size_t namelength, - char * value, size_t contentslength, - char * buffer, size_t bufferlength, - char *contenttype, - long flags, - struct curl_slist* contentHeader, - char *showfilename, - struct curl_httppost *parent_post, - struct curl_httppost **httppost, - struct curl_httppost **last_post) -{ - struct curl_httppost *post; - post = (struct curl_httppost *)calloc(sizeof(struct curl_httppost), 1); - if(post) { - post->name = name; - post->namelength = (long)(name?(namelength?namelength:strlen(name)):0); - post->contents = value; - post->contentslength = (long)contentslength; - post->buffer = buffer; - post->bufferlength = (long)bufferlength; - post->contenttype = contenttype; - post->contentheader = contentHeader; - post->showfilename = showfilename; - post->flags = flags; - } - else - return NULL; - - if (parent_post) { - /* now, point our 'more' to the original 'more' */ - post->more = parent_post->more; - - /* then move the original 'more' to point to ourselves */ - parent_post->more = post; - } - else { - /* make the previous point to this */ - if(*last_post) - (*last_post)->next = post; - else - (*httppost) = post; - - (*last_post) = post; - } - return post; -} - -/*************************************************************************** - * - * AddFormInfo() - * - * Adds a FormInfo structure to the list presented by parent_form_info. - * - * Returns newly allocated FormInfo on success and NULL if malloc failed/ - * parent_form_info is NULL. - * - ***************************************************************************/ -static FormInfo * AddFormInfo(char *value, - char *contenttype, - FormInfo *parent_form_info) -{ - FormInfo *form_info; - form_info = (FormInfo *)malloc(sizeof(FormInfo)); - if(form_info) { - memset(form_info, 0, sizeof(FormInfo)); - if (value) - form_info->value = value; - if (contenttype) - form_info->contenttype = contenttype; - form_info->flags = HTTPPOST_FILENAME; - } - else - return NULL; - - if (parent_form_info) { - /* now, point our 'more' to the original 'more' */ - form_info->more = parent_form_info->more; - - /* then move the original 'more' to point to ourselves */ - parent_form_info->more = form_info; - } - else - return NULL; - - return form_info; -} - -/*************************************************************************** - * - * ContentTypeForFilename() - * - * Provides content type for filename if one of the known types (else - * (either the prevtype or the default is returned). - * - * Returns some valid contenttype for filename. - * - ***************************************************************************/ -static const char * ContentTypeForFilename (const char *filename, - const char *prevtype) -{ - const char *contenttype; - unsigned int i; - /* - * No type was specified, we scan through a few well-known - * extensions and pick the first we match! - */ - struct ContentType { - const char *extension; - const char *type; - }; - static struct ContentType ctts[]={ - {".gif", "image/gif"}, - {".jpg", "image/jpeg"}, - {".jpeg", "image/jpeg"}, - {".txt", "text/plain"}, - {".html", "text/html"} - }; - - if(prevtype) - /* default to the previously set/used! */ - contenttype = prevtype; - else - /* It seems RFC1867 defines no Content-Type to default to - text/plain so we don't actually need to set this: */ - contenttype = HTTPPOST_CONTENTTYPE_DEFAULT; - - for(i=0; i<sizeof(ctts)/sizeof(ctts[0]); i++) { - if(strlen(filename) >= strlen(ctts[i].extension)) { - if(strequal(filename + - strlen(filename) - strlen(ctts[i].extension), - ctts[i].extension)) { - contenttype = ctts[i].type; - break; - } - } - } - /* we have a contenttype by now */ - return contenttype; -} - -/*************************************************************************** - * - * memdup() - * - * Copies the 'source' data to a newly allocated buffer buffer (that is - * returned). Uses buffer_length if not null, else uses strlen to determine - * the length of the buffer to be copied - * - * Returns the new pointer or NULL on failure. - * - ***************************************************************************/ -static char *memdup(const char *src, size_t buffer_length) -{ - size_t length; - bool add = FALSE; - char *buffer; - - if (buffer_length) - length = buffer_length; - else { - length = strlen(src); - add = TRUE; - } - buffer = (char*)malloc(length+add); - if (!buffer) - return NULL; /* fail */ - - memcpy(buffer, src, length); - - /* if length unknown do null termination */ - if (add) - buffer[length] = '\0'; - - return buffer; -} - -/*************************************************************************** - * - * FormAdd() - * - * Stores a formpost parameter and builds the appropriate linked list. - * - * Has two principal functionalities: using files and byte arrays as - * post parts. Byte arrays are either copied or just the pointer is stored - * (as the user requests) while for files only the filename and not the - * content is stored. - * - * While you may have only one byte array for each name, multiple filenames - * are allowed (and because of this feature CURLFORM_END is needed after - * using CURLFORM_FILE). - * - * Examples: - * - * Simple name/value pair with copied contents: - * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name", - * CURLFORM_COPYCONTENTS, "value", CURLFORM_END); - * - * name/value pair where only the content pointer is remembered: - * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name", - * CURLFORM_PTRCONTENTS, ptr, CURLFORM_CONTENTSLENGTH, 10, CURLFORM_END); - * (if CURLFORM_CONTENTSLENGTH is missing strlen () is used) - * - * storing a filename (CONTENTTYPE is optional!): - * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name", - * CURLFORM_FILE, "filename1", CURLFORM_CONTENTTYPE, "plain/text", - * CURLFORM_END); - * - * storing multiple filenames: - * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name", - * CURLFORM_FILE, "filename1", CURLFORM_FILE, "filename2", CURLFORM_END); - * - * 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 an error) - * CURL_FORMADD_MEMORY if a HttpPost struct cannot be allocated - * CURL_FORMADD_MEMORY if some allocation for string copying failed. - * CURL_FORMADD_ILLEGAL_ARRAY if an illegal option is used in an array - * - ***************************************************************************/ - -static -CURLFORMcode FormAdd(struct curl_httppost **httppost, - struct curl_httppost **last_post, - va_list params) -{ - FormInfo *first_form, *current_form, *form = NULL; - CURLFORMcode return_value = CURL_FORMADD_OK; - const char *prevtype = NULL; - struct curl_httppost *post; - CURLformoption option; - struct curl_forms *forms = NULL; - char *array_value=NULL; /* value read from an array */ - - /* This is a state variable, that if TRUE means that we're parsing an - array that we got passed to us. If FALSE we're parsing the input - va_list arguments. */ - bool array_state = FALSE; - - /* - * We need to allocate the first struct to fill in. - */ - first_form = (FormInfo *)calloc(sizeof(struct FormInfo), 1); - if(!first_form) - return CURL_FORMADD_MEMORY; - - current_form = first_form; - - /* - * Loop through all the options set. Break if we have an error to report. - */ - while (return_value == CURL_FORMADD_OK) { - - /* first see if we have more parts of the array param */ - if ( array_state ) { - /* get the upcoming option from the given array */ - option = forms->option; - array_value = (char *)forms->value; - - forms++; /* advance this to next entry */ - if (CURLFORM_END == option) { - /* end of array state */ - array_state = FALSE; - continue; - } - } - else { - /* This is not array-state, get next option */ - option = va_arg(params, CURLformoption); - if (CURLFORM_END == option) - break; - } - - switch (option) { - case CURLFORM_ARRAY: - if(array_state) - /* we don't support an array from within an array */ - return_value = CURL_FORMADD_ILLEGAL_ARRAY; - else { - forms = va_arg(params, struct curl_forms *); - if (forms) - array_state = TRUE; - else - return_value = CURL_FORMADD_NULL; - } - break; - - /* - * Set the Name property. - */ - case CURLFORM_PTRNAME: - current_form->flags |= HTTPPOST_PTRNAME; /* fall through */ - case CURLFORM_COPYNAME: - if (current_form->name) - return_value = CURL_FORMADD_OPTION_TWICE; - else { - char *name = array_state? - array_value:va_arg(params, char *); - if (name) - current_form->name = name; /* store for the moment */ - else - return_value = CURL_FORMADD_NULL; - } - break; - case CURLFORM_NAMELENGTH: - if (current_form->namelength) - return_value = CURL_FORMADD_OPTION_TWICE; - else - current_form->namelength = - array_state?(long)array_value:va_arg(params, long); - break; - - /* - * Set the contents property. - */ - case CURLFORM_PTRCONTENTS: - current_form->flags |= HTTPPOST_PTRCONTENTS; /* fall through */ - case CURLFORM_COPYCONTENTS: - if (current_form->value) - return_value = CURL_FORMADD_OPTION_TWICE; - else { - char *value = - array_state?array_value:va_arg(params, char *); - if (value) - current_form->value = value; /* store for the moment */ - else - return_value = CURL_FORMADD_NULL; - } - break; - case CURLFORM_CONTENTSLENGTH: - if (current_form->contentslength) - return_value = CURL_FORMADD_OPTION_TWICE; - else - current_form->contentslength = - array_state?(long)array_value:va_arg(params, long); - break; - - /* Get contents from a given file name */ - case CURLFORM_FILECONTENT: - if (current_form->flags != 0) - return_value = CURL_FORMADD_OPTION_TWICE; - else { - char *filename = array_state? - array_value:va_arg(params, char *); - if (filename) { - current_form->value = strdup(filename); - if(!current_form->value) - return_value = CURL_FORMADD_MEMORY; - else { - current_form->flags |= HTTPPOST_READFILE; - current_form->value_alloc = TRUE; - } - } - else - return_value = CURL_FORMADD_NULL; - } - break; - - /* We upload a file */ - case CURLFORM_FILE: - { - char *filename = array_state?array_value: - va_arg(params, char *); - - if (current_form->value) { - if (current_form->flags & HTTPPOST_FILENAME) { - if (filename) { - if (!(current_form = AddFormInfo(strdup(filename), - NULL, current_form))) - return_value = CURL_FORMADD_MEMORY; - } - else - return_value = CURL_FORMADD_NULL; - } - else - return_value = CURL_FORMADD_OPTION_TWICE; - } - else { - if (filename) { - current_form->value = strdup(filename); - if(!current_form->value) - return_value = CURL_FORMADD_MEMORY; - else { - current_form->flags |= HTTPPOST_FILENAME; - current_form->value_alloc = TRUE; - } - } - else - return_value = CURL_FORMADD_NULL; - } - break; - } - - 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); - if(!current_form->value) - return_value = CURL_FORMADD_MEMORY; - } - else - return_value = CURL_FORMADD_NULL; - current_form->flags |= HTTPPOST_BUFFER; - } - break; - } - - 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; - - case CURLFORM_BUFFERLENGTH: - if (current_form->bufferlength) - return_value = CURL_FORMADD_OPTION_TWICE; - else - current_form->bufferlength = - array_state?(long)array_value:va_arg(params, long); - break; - - case CURLFORM_CONTENTTYPE: - { - char *contenttype = - array_state?array_value:va_arg(params, char *); - if (current_form->contenttype) { - if (current_form->flags & HTTPPOST_FILENAME) { - if (contenttype) { - if (!(current_form = AddFormInfo(NULL, - strdup(contenttype), - current_form))) - return_value = CURL_FORMADD_MEMORY; - } - else - return_value = CURL_FORMADD_NULL; - } - else - return_value = CURL_FORMADD_OPTION_TWICE; - } - else { - if (contenttype) { - current_form->contenttype = strdup(contenttype); - if(!current_form->contenttype) - return_value = CURL_FORMADD_MEMORY; - else - current_form->contenttype_alloc = TRUE; - } - else - return_value = CURL_FORMADD_NULL; - } - break; - } - case CURLFORM_CONTENTHEADER: - { - /* this "cast increases required alignment of target type" but - we consider it OK anyway */ - struct curl_slist* list = 0; - if ( array_state ) - { - memcpy(&list, &array_value, sizeof(struct curl_slist*)); - } - else - { - list = va_arg(params, struct curl_slist*); - } - - if( current_form->contentheader ) - return_value = CURL_FORMADD_OPTION_TWICE; - else - current_form->contentheader = list; - - break; - } - case CURLFORM_FILENAME: - { - char *filename = array_state?array_value: - va_arg(params, char *); - if( current_form->showfilename ) - return_value = CURL_FORMADD_OPTION_TWICE; - else { - current_form->showfilename = strdup(filename); - if(!current_form->showfilename) - return_value = CURL_FORMADD_MEMORY; - else - current_form->showfilename_alloc = TRUE; - } - break; - } - default: - return_value = CURL_FORMADD_UNKNOWN_OPTION; - } - } - - if(CURL_FORMADD_OK == return_value) { - /* go through the list, check for copleteness and if everything is - * alright add the HttpPost item otherwise set return_value accordingly */ - - post = NULL; - for(form = first_form; - form != NULL; - form = form->more) { - if ( ((!form->name || !form->value) && !post) || - ( (form->contentslength) && - (form->flags & HTTPPOST_FILENAME) ) || - ( (form->flags & HTTPPOST_FILENAME) && - (form->flags & HTTPPOST_PTRCONTENTS) ) || - - ( (!form->buffer) && - (form->flags & HTTPPOST_BUFFER) && - (form->flags & HTTPPOST_PTRBUFFER) ) || - - ( (form->flags & HTTPPOST_READFILE) && - (form->flags & HTTPPOST_PTRCONTENTS) ) - ) { - return_value = CURL_FORMADD_INCOMPLETE; - break; - } - else { - if ( ((form->flags & HTTPPOST_FILENAME) || - (form->flags & HTTPPOST_BUFFER)) && - !form->contenttype ) { - /* our contenttype is missing */ - form->contenttype - = strdup(ContentTypeForFilename(form->value, prevtype)); - if(!form->contenttype) { - return_value = CURL_FORMADD_MEMORY; - break; - } - form->contenttype_alloc = TRUE; - } - if ( !(form->flags & HTTPPOST_PTRNAME) && - (form == first_form) ) { - /* copy name (without strdup; possibly contains null characters) */ - form->name = memdup(form->name, form->namelength); - if (!form->name) { - return_value = CURL_FORMADD_MEMORY; - break; - } - form->name_alloc = TRUE; - } - if ( !(form->flags & HTTPPOST_FILENAME) && - !(form->flags & HTTPPOST_READFILE) && - !(form->flags & HTTPPOST_PTRCONTENTS) && - !(form->flags & HTTPPOST_PTRBUFFER) ) { - /* copy value (without strdup; possibly contains null characters) */ - form->value = memdup(form->value, form->contentslength); - if (!form->value) { - return_value = CURL_FORMADD_MEMORY; - break; - } - form->value_alloc = TRUE; - } - post = AddHttpPost(form->name, form->namelength, - form->value, form->contentslength, - form->buffer, form->bufferlength, - form->contenttype, form->flags, - form->contentheader, form->showfilename, - post, httppost, - last_post); - - if(!post) { - return_value = CURL_FORMADD_MEMORY; - break; - } - - if (form->contenttype) - prevtype = form->contenttype; - } - } - } - - if(return_value) { - /* we return on error, free possibly allocated fields */ - if(!form) - form = current_form; - if(form) { - if(form->name_alloc) - free(form->name); - if(form->value_alloc) - free(form->value); - if(form->contenttype_alloc) - free(form->contenttype); - if(form->showfilename_alloc) - free(form->showfilename); - } - } - - /* always delete the allocated memory before returning */ - form = first_form; - while (form != NULL) { - FormInfo *delete_form; - - delete_form = form; - form = form->more; - free (delete_form); - } - - return return_value; -} - -/* - * curl_formadd() is a public API to add a section to the multipart formpost. - */ - -CURLFORMcode curl_formadd(struct curl_httppost **httppost, - struct curl_httppost **last_post, - ...) -{ - va_list arg; - CURLFORMcode result; - va_start(arg, last_post); - result = FormAdd(httppost, last_post, arg); - va_end(arg); - return result; -} - -/* - * AddFormData() adds a chunk of data to the FormData linked list. - * - * size is incremented by the chunk length, unless it is NULL - */ -static CURLcode AddFormData(struct FormData **formp, - enum formtype type, - const void *line, - size_t length, - curl_off_t *size) -{ - struct FormData *newform = (struct FormData *) - malloc(sizeof(struct FormData)); - if (!newform) - return CURLE_OUT_OF_MEMORY; - newform->next = NULL; - - /* we make it easier for plain strings: */ - if(!length) - length = strlen((char *)line); - - newform->line = (char *)malloc(length+1); - if (!newform->line) { - free(newform); - return CURLE_OUT_OF_MEMORY; - } - memcpy(newform->line, line, length); - newform->length = length; - newform->line[length]=0; /* zero terminate for easier debugging */ - newform->type = type; - - if(*formp) { - (*formp)->next = newform; - *formp = newform; - } - else - *formp = newform; - - if (size) { - if(type == FORM_DATA) - *size += length; - else { - /* Since this is a file to be uploaded here, add the size of the actual - file */ - if(!strequal("-", newform->line)) { - struct stat file; - if(!stat(newform->line, &file)) { - *size += file.st_size; - } - } - } - } - return CURLE_OK; -} - -/* - * AddFormDataf() adds printf()-style formatted data to the formdata chain. - */ - -static CURLcode AddFormDataf(struct FormData **formp, - curl_off_t *size, - const char *fmt, ...) -{ - char s[4096]; - va_list ap; - va_start(ap, fmt); - vsnprintf(s, sizeof(s), fmt, ap); - va_end(ap); - - return AddFormData(formp, FORM_DATA, s, 0, size); -} - -/* - * Curl_formclean() is used from http.c, this cleans a built FormData linked - * list - */ -void Curl_formclean(struct FormData *form) -{ - struct FormData *next; - - if(!form) - return; - - do { - next=form->next; /* the following form line */ - free(form->line); /* free the line */ - free(form); /* free the struct */ - - } while((form=next)); /* continue */ -} - -/* - * curl_formfree() is an external function to free up a whole form post - * chain - */ -void curl_formfree(struct curl_httppost *form) -{ - struct curl_httppost *next; - - if(!form) - /* no form to free, just get out of this */ - return; - - do { - next=form->next; /* the following form line */ - - /* recurse to sub-contents */ - if(form->more) - curl_formfree(form->more); - - if( !(form->flags & HTTPPOST_PTRNAME) && form->name) - free(form->name); /* free the name */ - if( !(form->flags & HTTPPOST_PTRCONTENTS) && form->contents) - free(form->contents); /* free the contents */ - if(form->contenttype) - free(form->contenttype); /* free the content type */ - if(form->showfilename) - free(form->showfilename); /* free the faked file name */ - free(form); /* free the struct */ - - } while((form=next)); /* continue */ -} - -/* - * Curl_getFormData() converts a linked list of "meta data" into a complete - * (possibly huge) multipart formdata. The input list is in 'post', while the - * output resulting linked lists gets stored in '*finalform'. *sizep will get - * the total size of the whole POST. - */ - -CURLcode Curl_getFormData(struct FormData **finalform, - struct curl_httppost *post, - curl_off_t *sizep) -{ - struct FormData *form = NULL; - struct FormData *firstform; - struct curl_httppost *file; - CURLcode result = CURLE_OK; - - curl_off_t size=0; /* support potentially ENORMOUS formposts */ - char *boundary; - char *fileboundary=NULL; - struct curl_slist* curList; - - *finalform=NULL; /* default form is empty */ - - if(!post) - return result; /* no input => no output! */ - - boundary = Curl_FormBoundary(); - if(!boundary) - return CURLE_OUT_OF_MEMORY; - - /* Make the first line of the output */ - result = AddFormDataf(&form, NULL, - "Content-Type: multipart/form-data;" - " boundary=%s\r\n", - boundary); - if (result) { - free(boundary); - return result; - } - /* we DO NOT include that line in the total size of the POST, since it'll be - part of the header! */ - - firstform = form; - - do { - - if(size) { - result = AddFormDataf(&form, &size, "\r\n"); - if (result) - break; - } - - /* boundary */ - result = AddFormDataf(&form, &size, "--%s\r\n", boundary); - if (result) - break; - - result = AddFormDataf(&form, &size, - "Content-Disposition: form-data; name=\""); - if (result) - break; - - result = AddFormData(&form, FORM_DATA, post->name, post->namelength, - &size); - if (result) - break; - - result = AddFormDataf(&form, &size, "\""); - if (result) - break; - - if(post->more) { - /* If used, this is a link to more file names, we must then do - the magic to include several files with the same field name */ - - fileboundary = Curl_FormBoundary(); - - result = AddFormDataf(&form, &size, - "\r\nContent-Type: multipart/mixed," - " boundary=%s\r\n", - fileboundary); - if (result) - break; - } - - file = post; - - do { - - /* If 'showfilename' is set, that is a faked name passed on to us - to use to in the formpost. If that is not set, the actually used - local file name should be added. */ - - if(post->more) { - /* if multiple-file */ - result = AddFormDataf(&form, &size, - "\r\n--%s\r\nContent-Disposition: " - "attachment; filename=\"%s\"", - fileboundary, - (file->showfilename?file->showfilename: - file->contents)); - if (result) - break; - } - else if((post->flags & HTTPPOST_FILENAME) || - (post->flags & HTTPPOST_BUFFER)) { - - result = AddFormDataf(&form, &size, - "; filename=\"%s\"", - (post->showfilename?post->showfilename: - post->contents)); - if (result) - break; - } - - if(file->contenttype) { - /* we have a specified type */ - result = AddFormDataf(&form, &size, - "\r\nContent-Type: %s", - file->contenttype); - if (result) - break; - } - - curList = file->contentheader; - while( curList ) { - /* Process the additional headers specified for this form */ - result = AddFormDataf( &form, &size, "\r\n%s", curList->data ); - if (result) - break; - curList = curList->next; - } - if (result) { - Curl_formclean(firstform); - free(boundary); - return result; - } - -#if 0 - /* The header Content-Transfer-Encoding: seems to confuse some receivers - * (like the built-in PHP engine). While I can't see any reason why it - * should, I can just as well skip this to the benefit of the users who - * are using such confused receivers. - */ - - if(file->contenttype && - !checkprefix("text/", file->contenttype)) { - /* this is not a text content, mention our binary encoding */ - size += AddFormData(&form, "\r\nContent-Transfer-Encoding: binary", 0); - } -#endif - - result = AddFormDataf(&form, &size, "\r\n\r\n"); - if (result) - break; - - if((post->flags & HTTPPOST_FILENAME) || - (post->flags & HTTPPOST_READFILE)) { - /* we should include the contents from the specified file */ - FILE *fileread; - - fileread = strequal("-", file->contents)? - stdin:fopen(file->contents, "rb"); /* binary read for win32 */ - - /* - * VMS: This only allows for stream files on VMS. Stream files are - * OK, as are FIXED & VAR files WITHOUT implied CC For implied CC, - * every record needs to have a \n appended & 1 added to SIZE - */ - - if(fileread) { - if(fileread != stdin) { - /* close the file again */ - fclose(fileread); - /* add the file name only - for later reading from this */ - result = AddFormData(&form, FORM_FILE, file->contents, 0, &size); - } - else { - /* When uploading from stdin, we can't know the size of the file, - * thus must read the full file as before. We *could* use chunked - * transfer-encoding, but that only works for HTTP 1.1 and we - * can't be sure we work with such a server. - */ - size_t nread; - char buffer[512]; - while((nread = fread(buffer, 1, sizeof(buffer), fileread))) { - result = AddFormData(&form, FORM_DATA, buffer, nread, &size); - if (result) - break; - } - } - - if (result) { - Curl_formclean(firstform); - free(boundary); - return result; - } - - } - else { - Curl_formclean(firstform); - free(boundary); - *finalform = NULL; - return CURLE_READ_ERROR; - } - - } - else if (post->flags & HTTPPOST_BUFFER) { - /* include contents of buffer */ - result = AddFormData(&form, FORM_DATA, post->buffer, - post->bufferlength, &size); - if (result) - break; - } - - else { - /* include the contents we got */ - result = AddFormData(&form, FORM_DATA, post->contents, - post->contentslength, &size); - if (result) - break; - } - } while((file = file->more)); /* for each specified file for this field */ - if (result) { - Curl_formclean(firstform); - free(boundary); - return result; - } - - if(post->more) { - /* this was a multiple-file inclusion, make a termination file - boundary: */ - result = AddFormDataf(&form, &size, - "\r\n--%s--", - fileboundary); - free(fileboundary); - if (result) - break; - } - - } while((post=post->next)); /* for each field */ - if (result) { - Curl_formclean(firstform); - free(boundary); - return result; - } - - /* end-boundary for everything */ - result = AddFormDataf(&form, &size, - "\r\n--%s--\r\n", - boundary); - if (result) { - Curl_formclean(firstform); - free(boundary); - return result; - } - - *sizep = size; - - free(boundary); - - *finalform=firstform; - - return result; -} - -/* - * Curl_FormInit() inits the struct 'form' points to with the 'formdata' - * and resets the 'sent' counter. - */ -int Curl_FormInit(struct Form *form, struct FormData *formdata ) -{ - if(!formdata) - return 1; /* error */ - - form->data = formdata; - form->sent = 0; - form->fp = NULL; - - return 0; -} - -static size_t readfromfile(struct Form *form, char *buffer, size_t size) -{ - size_t nread; - if(!form->fp) { - /* this file hasn't yet been opened */ - form->fp = fopen(form->data->line, "rb"); /* b is for binary */ - if(!form->fp) - return -1; /* failure */ - } - nread = fread(buffer, 1, size, form->fp); - - if(nread != size) { - /* this is the last chunk form the file, move on */ - fclose(form->fp); - form->fp = NULL; - form->data = form->data->next; - } - - return nread; -} - -/* - * Curl_FormReader() is the fread() emulation function that will be used to - * deliver the formdata to the transfer loop and then sent away to the peer. - */ -size_t Curl_FormReader(char *buffer, - size_t size, - size_t nitems, - FILE *mydata) -{ - struct Form *form; - size_t wantedsize; - size_t gotsize = 0; - - form=(struct Form *)mydata; - - wantedsize = size * nitems; - - if(!form->data) - return 0; /* nothing, error, empty */ - - if(form->data->type == FORM_FILE) - return readfromfile(form, buffer, wantedsize); - - do { - - if( (form->data->length - form->sent ) > wantedsize - gotsize) { - - memcpy(buffer + gotsize , form->data->line + form->sent, - wantedsize - gotsize); - - form->sent += wantedsize-gotsize; - - return wantedsize; - } - - memcpy(buffer+gotsize, - form->data->line + form->sent, - (form->data->length - form->sent) ); - gotsize += form->data->length - form->sent; - - form->sent = 0; - - form->data = form->data->next; /* advance */ - - } while(form->data && (form->data->type == FORM_DATA)); - /* If we got an empty line and we have more data, we proceed to the next - line immediately to avoid returning zero before we've reached the end. - This is the bug reported November 22 1999 on curl 6.3. (Daniel) */ - - return gotsize; -} - -/* - * Curl_formpostheader() returns the first line of the formpost, the - * request-header part (which is not part of the request-body like the rest of - * the post). - */ -char *Curl_formpostheader(void *formp, size_t *len) -{ - char *header; - struct Form *form=(struct Form *)formp; - - if(!form->data) - return 0; /* nothing, ERROR! */ - - header = form->data->line; - *len = form->data->length; - - form->data = form->data->next; /* advance */ - - return header; -} - - -#ifdef _FORM_DEBUG -int FormAddTest(const char * errormsg, - struct curl_httppost **httppost, - struct curl_httppost **last_post, - ...) -{ - int result; - va_list arg; - va_start(arg, last_post); - if ((result = FormAdd(httppost, last_post, arg))) - fprintf (stderr, "ERROR doing FormAdd ret: %d action: %s\n", result, - errormsg); - va_end(arg); - return result; -} - - -int main() -{ - char name1[] = "simple_COPYCONTENTS"; - char name2[] = "COPYCONTENTS_+_CONTENTTYPE"; - char name3[] = "PTRNAME_+_NAMELENGTH_+_COPYNAME_+_CONTENTSLENGTH"; - char name4[] = "simple_PTRCONTENTS"; - char name5[] = "PTRCONTENTS_+_CONTENTSLENGTH"; - char name6[] = "PTRCONTENTS_+_CONTENTSLENGTH_+_CONTENTTYPE"; - char name7[] = "FILE1_+_CONTENTTYPE"; - char name8[] = "FILE1_+_FILE2"; - char name9[] = "FILE1_+_FILE2_+_FILE3"; - char name10[] = "ARRAY: FILE1_+_FILE2_+_FILE3"; - char name11[] = "FILECONTENT"; - char value1[] = "value for simple COPYCONTENTS"; - char value2[] = "value for COPYCONTENTS + CONTENTTYPE"; - char value3[] = "value for PTRNAME + NAMELENGTH + COPYNAME + CONTENTSLENGTH"; - char value4[] = "value for simple PTRCONTENTS"; - char value5[] = "value for PTRCONTENTS + CONTENTSLENGTH"; - char value6[] = "value for PTRCOTNENTS + CONTENTSLENGTH + CONTENTTYPE"; - char value7[] = "inet_ntoa_r.h"; - char value8[] = "Makefile.b32.resp"; - char type2[] = "image/gif"; - char type6[] = "text/plain"; - char type7[] = "text/html"; - int name3length = strlen(name3); - int value3length = strlen(value3); - int value5length = strlen(value4); - int value6length = strlen(value5); - int errors = 0; - int size; - size_t nread; - char buffer[4096]; - struct curl_httppost *httppost=NULL; - struct curl_httppost *last_post=NULL; - struct curl_forms forms[4]; - - struct FormData *form; - struct Form formread; - - if (FormAddTest("simple COPYCONTENTS test", &httppost, &last_post, - CURLFORM_COPYNAME, name1, CURLFORM_COPYCONTENTS, value1, - CURLFORM_END)) - ++errors; - if (FormAddTest("COPYCONTENTS + CONTENTTYPE test", &httppost, &last_post, - CURLFORM_COPYNAME, name2, CURLFORM_COPYCONTENTS, value2, - CURLFORM_CONTENTTYPE, type2, CURLFORM_END)) - ++errors; - /* make null character at start to check that contentslength works - correctly */ - name3[1] = '\0'; - value3[1] = '\0'; - if (FormAddTest("PTRNAME + NAMELENGTH + COPYNAME + CONTENTSLENGTH test", - &httppost, &last_post, - CURLFORM_PTRNAME, name3, CURLFORM_COPYCONTENTS, value3, - CURLFORM_CONTENTSLENGTH, value3length, - CURLFORM_NAMELENGTH, name3length, CURLFORM_END)) - ++errors; - if (FormAddTest("simple PTRCONTENTS test", &httppost, &last_post, - CURLFORM_COPYNAME, name4, CURLFORM_PTRCONTENTS, value4, - CURLFORM_END)) - ++errors; - /* make null character at start to check that contentslength works - correctly */ - value5[1] = '\0'; - if (FormAddTest("PTRCONTENTS + CONTENTSLENGTH test", &httppost, &last_post, - CURLFORM_COPYNAME, name5, CURLFORM_PTRCONTENTS, value5, - CURLFORM_CONTENTSLENGTH, value5length, CURLFORM_END)) - ++errors; - /* make null character at start to check that contentslength works - correctly */ - value6[1] = '\0'; - if (FormAddTest("PTRCONTENTS + CONTENTSLENGTH + CONTENTTYPE test", - &httppost, &last_post, - CURLFORM_COPYNAME, name6, CURLFORM_PTRCONTENTS, value6, - CURLFORM_CONTENTSLENGTH, value6length, - CURLFORM_CONTENTTYPE, type6, CURLFORM_END)) - ++errors; - if (FormAddTest("FILE + CONTENTTYPE test", &httppost, &last_post, - CURLFORM_COPYNAME, name7, CURLFORM_FILE, value7, - CURLFORM_CONTENTTYPE, type7, CURLFORM_END)) - ++errors; - if (FormAddTest("FILE1 + FILE2 test", &httppost, &last_post, - CURLFORM_COPYNAME, name8, CURLFORM_FILE, value7, - CURLFORM_FILE, value8, CURLFORM_END)) - ++errors; - if (FormAddTest("FILE1 + FILE2 + FILE3 test", &httppost, &last_post, - CURLFORM_COPYNAME, name9, CURLFORM_FILE, value7, - CURLFORM_FILE, value8, CURLFORM_FILE, value7, CURLFORM_END)) - ++errors; - forms[0].option = CURLFORM_FILE; - forms[0].value = value7; - forms[1].option = CURLFORM_FILE; - forms[1].value = value8; - forms[2].option = CURLFORM_FILE; - forms[2].value = value7; - forms[3].option = CURLFORM_END; - if (FormAddTest("FILE1 + FILE2 + FILE3 ARRAY test", &httppost, &last_post, - CURLFORM_COPYNAME, name10, CURLFORM_ARRAY, forms, - CURLFORM_END)) - ++errors; - if (FormAddTest("FILECONTENT test", &httppost, &last_post, - CURLFORM_COPYNAME, name11, CURLFORM_FILECONTENT, value7, - CURLFORM_END)) - ++errors; - - form=Curl_getFormData(httppost, &size); - - Curl_FormInit(&formread, form); - - do { - nread = Curl_FormReader(buffer, 1, sizeof(buffer), - (FILE *)&formread); - - if(-1 == nread) - break; - fwrite(buffer, nread, 1, stdout); - } while(1); - - fprintf(stdout, "size: %d\n", size); - if (errors) - fprintf(stdout, "\n==> %d Test(s) failed!\n", errors); - else - fprintf(stdout, "\nAll Tests seem to have worked (please check output)\n"); - - return 0; -} - -#endif - -#else /* CURL_DISABLE_HTTP */ -CURLFORMcode curl_formadd(struct curl_httppost **httppost, - struct curl_httppost **last_post, - ...) -{ - (void)httppost; - (void)last_post; - return CURL_FORMADD_DISABLED; -} - -void curl_formfree(struct curl_httppost *form) -{ - (void)form; - /* does nothing HTTP is disabled */ -} - -#endif /* CURL_DISABLE_HTTP */ - -/* - * Curl_FormBoundary() creates a suitable boundary string and returns an - * allocated one. This is also used by SSL-code so it must be present even - * if HTTP is disabled! - */ -char *Curl_FormBoundary(void) -{ - char *retstring; - static int randomizer=0; /* this is just so that two boundaries within - the same form won't be identical */ - size_t i; - - static char table16[]="abcdef0123456789"; - - retstring = (char *)malloc(BOUNDARY_LENGTH+1); - - if(!retstring) - return NULL; /* failed */ - - srand(time(NULL)+randomizer++); /* seed */ - - strcpy(retstring, "----------------------------"); - - for(i=strlen(retstring); i<BOUNDARY_LENGTH; i++) - retstring[i] = table16[rand()%16]; - - /* 28 dashes and 12 hexadecimal digits makes 12^16 (184884258895036416) - combinations */ - retstring[BOUNDARY_LENGTH]=0; /* zero terminate */ - - return retstring; -} diff --git a/Source/CTest/Curl/formdata.h b/Source/CTest/Curl/formdata.h deleted file mode 100644 index c6a78cd..0000000 --- a/Source/CTest/Curl/formdata.h +++ /dev/null @@ -1,92 +0,0 @@ -#ifndef __FORMDATA_H -#define __FORMDATA_H - -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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$ - ***************************************************************************/ - -enum formtype { - FORM_DATA, /* regular data */ - FORM_FILE /* 'line' points to a file name we should read from */ -}; - -/* plain and simple linked list with lines to send */ -struct FormData { - struct FormData *next; - enum formtype type; - char *line; - size_t length; -}; - -struct Form { - struct FormData *data; /* current form line to send */ - size_t sent; /* number of bytes of the current line that has - already been sent in a previous invoke */ - FILE *fp; /* file to read from */ -}; - -/* used by FormAdd for temporary storage */ -typedef struct FormInfo { - char *name; - bool name_alloc; - size_t namelength; - char *value; - bool value_alloc; - size_t contentslength; - char *contenttype; - bool contenttype_alloc; - long flags; - char *buffer; /* pointer to existing buffer used for file upload */ - size_t bufferlength; - char *showfilename; /* The file name to show. If not set, the actual - file name will be used */ - bool showfilename_alloc; - struct curl_slist* contentheader; - struct FormInfo *more; -} FormInfo; - -int Curl_FormInit(struct Form *form, struct FormData *formdata ); - -CURLcode -Curl_getFormData(struct FormData **, - struct curl_httppost *post, - curl_off_t *size); - -/* fread() emulation */ -size_t Curl_FormReader(char *buffer, - size_t size, - size_t nitems, - FILE *mydata); - -/* - * Curl_formpostheader() returns the first line of the formpost, the - * request-header part (which is not part of the request-body like the rest of - * the post). - */ -char *Curl_formpostheader(void *formp, size_t *len); - -char *Curl_FormBoundary(void); - -void Curl_formclean(struct FormData *); - -#endif - diff --git a/Source/CTest/Curl/ftp.c b/Source/CTest/Curl/ftp.c deleted file mode 100644 index 2501412..0000000 --- a/Source/CTest/Curl/ftp.c +++ /dev/null @@ -1,2774 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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" - -#ifndef CURL_DISABLE_FTP -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <stdarg.h> -#include <ctype.h> -#include <errno.h> - -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif -#ifdef HAVE_SYS_SELECT_H -#include <sys/select.h> -#endif - -#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__) - -#else /* some kind of unix */ -#ifdef HAVE_SYS_SOCKET_H -#include <sys/socket.h> -#endif -#include <sys/types.h> -#ifdef HAVE_NETINET_IN_H -#include <netinet/in.h> -#endif -#ifdef HAVE_ARPA_INET_H -#include <arpa/inet.h> -#endif -#include <sys/utsname.h> -#ifdef HAVE_NETDB_H -#include <netdb.h> -#endif -#ifdef VMS -#include <in.h> -#include <inet.h> -#endif -#endif - -#if defined(WIN32) && defined(__GNUC__) || defined(__MINGW32__) -#include <errno.h> -#endif - -#if (defined(NETWARE) && defined(__NOVELL_LIBC__)) -#undef in_addr_t -#define in_addr_t unsigned long -#endif - -#include <curl/curl.h> -#include "urldata.h" -#include "sendf.h" - -#include "if2ip.h" -#include "hostip.h" -#include "progress.h" -#include "transfer.h" -#include "escape.h" -#include "http.h" /* for HTTP proxy tunnel stuff */ -#include "ftp.h" - -#ifdef HAVE_KRB4 -#include "security.h" -#include "krb4.h" -#endif - -#include "strtoofft.h" -#include "strequal.h" -#include "ssluse.h" -#include "connect.h" -#include "strerror.h" -#include "curl_memory.h" -#include "inet_ntop.h" - -#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL) -#include "inet_ntoa_r.h" -#endif - -#define _MPRINTF_REPLACE /* use our functions only */ -#include <curl/mprintf.h> - -/* The last #include file should be: */ -#ifdef CURLDEBUG -#include "memdebug.h" -#endif - -#ifdef HAVE_NI_WITHSCOPEID -#define NIFLAGS NI_NUMERICHOST | NI_NUMERICSERV | NI_WITHSCOPEID -#else -#define NIFLAGS NI_NUMERICHOST | NI_NUMERICSERV -#endif - -/* Local API functions */ -static CURLcode ftp_sendquote(struct connectdata *conn, - struct curl_slist *quote); -static CURLcode ftp_cwd(struct connectdata *conn, char *path); -static CURLcode ftp_mkd(struct connectdata *conn, char *path); -static CURLcode ftp_cwd_and_mkd(struct connectdata *conn, char *path); -static CURLcode ftp_quit(struct connectdata *conn); -static CURLcode ftp_3rdparty_pretransfer(struct connectdata *conn); -static CURLcode ftp_3rdparty_transfer(struct connectdata *conn); -static CURLcode ftp_regular_transfer(struct connectdata *conn); -static CURLcode ftp_3rdparty(struct connectdata *conn); - -/* easy-to-use macro: */ -#define FTPSENDF(x,y,z) if((result = Curl_ftpsendf(x,y,z))) return result - -static void freedirs(struct FTP *ftp) -{ - int i; - if(ftp->dirs) { - for (i=0; i < ftp->dirdepth; i++){ - if(ftp->dirs[i]) { - free(ftp->dirs[i]); - ftp->dirs[i]=NULL; - } - } - free(ftp->dirs); - ftp->dirs = NULL; - } - if(ftp->file) { - free(ftp->file); - ftp->file = NULL; - } -} - -/*********************************************************************** - * - * AllowServerConnect() - * - * When we've issue the PORT command, we have told the server to connect - * to us. This function will sit and wait here until the server has - * connected. - * - */ -static CURLcode AllowServerConnect(struct connectdata *conn) -{ - fd_set rdset; - struct timeval dt; - struct SessionHandle *data = conn->data; - curl_socket_t sock = conn->sock[SECONDARYSOCKET]; - struct timeval now = Curl_tvnow(); - long timespent = Curl_tvdiff(Curl_tvnow(), now)/1000; - long timeout = data->set.connecttimeout?data->set.connecttimeout: - (data->set.timeout?data->set.timeout: 0); - - FD_ZERO(&rdset); - - FD_SET(sock, &rdset); - - if(timeout) { - timeout -= timespent; - if(timeout<=0) { - failf(data, "Timed out before server could connect to us"); - return CURLE_OPERATION_TIMEDOUT; - } - } - - /* we give the server 60 seconds to connect to us, or a custom timeout */ - dt.tv_sec = (int)(timeout?timeout:60); - dt.tv_usec = 0; - - switch (select(sock+1, &rdset, NULL, NULL, &dt)) { - case -1: /* error */ - /* let's die here */ - failf(data, "Error while waiting for server connect"); - return CURLE_FTP_PORT_FAILED; - case 0: /* timeout */ - /* let's die here */ - failf(data, "Timeout while waiting for server connect"); - return CURLE_FTP_PORT_FAILED; - default: - /* we have received data here */ - { - curl_socket_t s; -#ifdef __hpux - int size = sizeof(struct sockaddr_in); -#else - socklen_t size = sizeof(struct sockaddr_in); -#endif - struct sockaddr_in add; - - getsockname(sock, (struct sockaddr *) &add, &size); - s=accept(sock, (struct sockaddr *) &add, &size); - - sclose(sock); /* close the first socket */ - - if (CURL_SOCKET_BAD == s) { - /* DIE! */ - failf(data, "Error accept()ing server connect"); - return CURLE_FTP_PORT_FAILED; - } - infof(data, "Connection accepted from server\n"); - - conn->sock[SECONDARYSOCKET] = s; - Curl_nonblock(s, TRUE); /* enable non-blocking */ - } - break; - } - - return CURLE_OK; -} - - -/* --- parse FTP server responses --- */ - -/* - * Curl_GetFTPResponse() is supposed to be invoked after each command sent to - * a remote FTP server. This function will wait and read all lines of the - * response and extract the relevant return code for the invoking function. - */ - -CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */ - struct connectdata *conn, - int *ftpcode) /* return the ftp-code */ -{ - /* Brand new implementation. - * We cannot read just one byte per read() and then go back to select() - * as it seems that the OpenSSL read() stuff doesn't grok that properly. - * - * Alas, read as much as possible, split up into lines, use the ending - * line in a response or continue reading. */ - - curl_socket_t sockfd = conn->sock[FIRSTSOCKET]; - int perline; /* count bytes per line */ - bool keepon=TRUE; - ssize_t gotbytes; - char *ptr; - long timeout; /* timeout in seconds */ - struct timeval interval; - fd_set rkeepfd; - fd_set readfd; - struct SessionHandle *data = conn->data; - char *line_start; - int code=0; /* default ftp "error code" to return */ - char *buf = data->state.buffer; - CURLcode result = CURLE_OK; - struct FTP *ftp = conn->proto.ftp; - struct timeval now = Curl_tvnow(); - - if (ftpcode) - *ftpcode = 0; /* 0 for errors */ - - FD_ZERO (&readfd); /* clear it */ - FD_SET (sockfd, &readfd); /* read socket */ - - /* get this in a backup variable to be able to restore it on each lap in the - select() loop */ - rkeepfd = readfd; - - ptr=buf; - line_start = buf; - - *nreadp=0; - perline=0; - - while((*nreadp<BUFSIZE) && (keepon && !result)) { - /* check and reset timeout value every lap */ - if(data->set.ftp_response_timeout ) - /* if CURLOPT_FTP_RESPONSE_TIMEOUT is set, use that to determine - remaining time. Also, use "now" as opposed to "conn->now" - because ftp_response_timeout is only supposed to govern - the response for any given ftp response, not for the time - from connect to the given ftp response. */ - timeout = data->set.ftp_response_timeout - /* timeout time */ - Curl_tvdiff(Curl_tvnow(), now)/1000; /* spent time */ - else 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 */ - else - /* Even without a requested timeout, we only wait response_time - seconds for the full response to arrive before we bail out */ - timeout = ftp->response_time - - Curl_tvdiff(Curl_tvnow(), now)/1000; /* spent time */ - - if(timeout <=0 ) { - failf(data, "FTP response timeout"); - return CURLE_OPERATION_TIMEDOUT; /* already too little time */ - } - - if(!ftp->cache) { - readfd = rkeepfd; /* set every lap */ - interval.tv_sec = 1; /* use 1 second timeout intervals */ - interval.tv_usec = 0; - - switch (select (sockfd+1, &readfd, NULL, NULL, &interval)) { - case -1: /* select() error, stop reading */ - result = CURLE_RECV_ERROR; - failf(data, "FTP response aborted due to select() error: %d", errno); - break; - case 0: /* timeout */ - if(Curl_pgrsUpdate(conn)) - return CURLE_ABORTED_BY_CALLBACK; - continue; /* just continue in our loop for the timeout duration */ - - default: - break; - } - } - if(CURLE_OK == result) { - /* - * This code previously didn't use the kerberos sec_read() code - * to read, but when we use Curl_read() it may do so. Do confirm - * that this is still ok and then remove this comment! - */ - if(ftp->cache) { - /* we had data in the "cache", copy that instead of doing an actual - * read - * - * Dave Meyer, December 2003: - * ftp->cache_size is cast to int here. This should be safe, - * because it would have been populated with something of size - * int to begin with, even though its datatype may be larger - * than an int. - */ - memcpy(ptr, ftp->cache, (int)ftp->cache_size); - gotbytes = (int)ftp->cache_size; - free(ftp->cache); /* free the cache */ - ftp->cache = NULL; /* clear the pointer */ - ftp->cache_size = 0; /* zero the size just in case */ - } - else { - int res = Curl_read(conn, sockfd, ptr, BUFSIZE-*nreadp, &gotbytes); - if(res < 0) - /* EWOULDBLOCK */ - continue; /* go looping again */ - - if(CURLE_OK != res) - keepon = FALSE; - } - - if(!keepon) - ; - else if(gotbytes <= 0) { - keepon = FALSE; - result = CURLE_RECV_ERROR; - failf(data, "FTP response reading failed"); - } - else { - /* we got a whole chunk of data, which can be anything from one - * byte to a set of lines and possible just a piece of the last - * line */ - int i; - - conn->headerbytecount += gotbytes; - - *nreadp += gotbytes; - for(i = 0; i < gotbytes; ptr++, i++) { - perline++; - if(*ptr=='\n') { - /* a newline is CRLF in ftp-talk, so the CR is ignored as - the line isn't really terminated until the LF comes */ - - /* output debug output if that is requested */ - if(data->set.verbose) - Curl_debug(data, CURLINFO_HEADER_IN, line_start, perline, conn->host.dispname); - - /* - * We pass all response-lines to the callback function registered - * for "headers". The response lines can be seen as a kind of - * headers. - */ - result = Curl_client_write(data, CLIENTWRITE_HEADER, - line_start, perline); - if(result) - return result; - -#define lastline(line) (isdigit((int)line[0]) && isdigit((int)line[1]) && \ - isdigit((int)line[2]) && (' ' == line[3])) - - if(perline>3 && lastline(line_start)) { - /* This is the end of the last line, copy the last - * line to the start of the buffer and zero terminate, - * for old times sake (and krb4)! */ - char *meow; - int n; - for(meow=line_start, n=0; meow<ptr; meow++, n++) - buf[n] = *meow; - *meow=0; /* zero terminate */ - keepon=FALSE; - line_start = ptr+1; /* advance pointer */ - i++; /* skip this before getting out */ - break; - } - perline=0; /* line starts over here */ - line_start = ptr+1; - } - } - if(!keepon && (i != gotbytes)) { - /* We found the end of the response lines, but we didn't parse the - full chunk of data we have read from the server. We therefore - need to store the rest of the data to be checked on the next - invoke as it may actually contain another end of response - already! Cleverly figured out by Eric Lavigne in December - 2001. */ - ftp->cache_size = gotbytes - i; - ftp->cache = (char *)malloc((int)ftp->cache_size); - if(ftp->cache) - memcpy(ftp->cache, line_start, (int)ftp->cache_size); - else - return CURLE_OUT_OF_MEMORY; /**BANG**/ - } - } /* there was data */ - } /* if(no error) */ - } /* while there's buffer left and loop is requested */ - - if(!result) - code = atoi(buf); - -#ifdef HAVE_KRB4 - /* handle the security-oriented responses 6xx ***/ - /* FIXME: some errorchecking perhaps... ***/ - switch(code) { - case 631: - Curl_sec_read_msg(conn, buf, prot_safe); - break; - case 632: - Curl_sec_read_msg(conn, buf, prot_private); - break; - case 633: - Curl_sec_read_msg(conn, buf, prot_confidential); - break; - default: - /* normal ftp stuff we pass through! */ - break; - } -#endif - - if(ftpcode) - *ftpcode=code; /* return the initial number like this */ - - /* store the latest code for later retrieval */ - conn->data->info.httpcode=code; - - return result; -} - -static const char *ftpauth[]= { - "SSL", "TLS", NULL -}; - -/* - * Curl_ftp_connect() should do everything that is to be considered a part of - * the connection phase. - */ -CURLcode Curl_ftp_connect(struct connectdata *conn) -{ - /* this is FTP and no proxy */ - ssize_t nread; - struct SessionHandle *data=conn->data; - char *buf = data->state.buffer; /* this is our buffer */ - struct FTP *ftp; - CURLcode result; - int ftpcode, try; - - ftp = (struct FTP *)malloc(sizeof(struct FTP)); - if(!ftp) - return CURLE_OUT_OF_MEMORY; - - memset(ftp, 0, sizeof(struct FTP)); - conn->proto.ftp = ftp; - - /* We always support persistant connections on ftp */ - conn->bits.close = FALSE; - - /* get some initial data into the ftp struct */ - ftp->bytecountp = &conn->bytecount; - - /* no need to duplicate them, this connectdata struct won't change */ - ftp->user = conn->user; - ftp->passwd = conn->passwd; - ftp->response_time = 3600; /* set default response time-out */ - -#ifndef CURL_DISABLE_HTTP - if (conn->bits.tunnel_proxy) { - /* We want "seamless" FTP operations through HTTP proxy tunnel */ - result = Curl_ConnectHTTPProxyTunnel(conn, FIRSTSOCKET, - conn->host.name, conn->remote_port); - if(CURLE_OK != result) - return result; - } -#endif /* CURL_DISABLE_HTTP */ - - if(conn->protocol & PROT_FTPS) { - /* FTPS is simply ftp with SSL for the control channel */ - /* now, perform the SSL initialization for this socket */ - result = Curl_SSLConnect(conn, FIRSTSOCKET); - if(result) - return result; - } - - /* The first thing we do is wait for the "220*" line: */ - result = Curl_GetFTPResponse(&nread, conn, &ftpcode); - if(result) - return result; - - if(ftpcode != 220) { - failf(data, "This doesn't seem like a nice ftp-server response"); - return CURLE_FTP_WEIRD_SERVER_REPLY; - } - -#ifdef HAVE_KRB4 - /* if not anonymous login, try a secure login */ - if(data->set.krb4) { - - /* request data protection level (default is 'clear') */ - Curl_sec_request_prot(conn, "private"); - - /* We set private first as default, in case the line below fails to - set a valid level */ - Curl_sec_request_prot(conn, data->set.krb4_level); - - if(Curl_sec_login(conn) != 0) - infof(data, "Logging in with password in cleartext!\n"); - else - infof(data, "Authentication successful\n"); - } -#endif - - if(data->set.ftp_ssl && !conn->ssl[FIRSTSOCKET].use) { - /* we don't have a SSL/TLS connection, try a FTPS connection now */ - - for (try = 0; ftpauth[try]; try++) { - - FTPSENDF(conn, "AUTH %s", ftpauth[try]); - - result = Curl_GetFTPResponse(&nread, conn, &ftpcode); - - if(result) - return result; - - /* RFC2228 (page 5) says: - * - * If the server is willing to accept the named security mechanism, and - * does not require any security data, it must respond with reply code - * 234/334. - */ - - if((ftpcode == 234) || (ftpcode == 334)) { - result = Curl_SSLConnect(conn, FIRSTSOCKET); - if(result) - return result; - conn->protocol |= PROT_FTPS; - conn->ssl[SECONDARYSOCKET].use = FALSE; /* clear-text data */ - break; - } - } - } - - /* send USER */ - FTPSENDF(conn, "USER %s", ftp->user?ftp->user:""); - - /* wait for feedback */ - result = Curl_GetFTPResponse(&nread, conn, &ftpcode); - if(result) - return result; - - if(ftpcode == 530) { - /* 530 User ... access denied - (the server denies to log the specified user) */ - failf(data, "Access denied: %s", &buf[4]); - return CURLE_FTP_ACCESS_DENIED; - } - else if(ftpcode == 331) { - /* 331 Password required for ... - (the server requires to send the user's password too) */ - FTPSENDF(conn, "PASS %s", ftp->passwd?ftp->passwd:""); - result = Curl_GetFTPResponse(&nread, conn, &ftpcode); - if(result) - return result; - - if(ftpcode == 530) { - /* 530 Login incorrect. - (the username and/or the password are incorrect) */ - failf(data, "the username and/or the password are incorrect"); - return CURLE_FTP_USER_PASSWORD_INCORRECT; - } - else if(ftpcode == 230) { - /* 230 User ... logged in. - (user successfully logged in) */ - - infof(data, "We have successfully logged in\n"); - } - else { - failf(data, "Odd return code after PASS"); - return CURLE_FTP_WEIRD_PASS_REPLY; - } - } - else if(buf[0] == '2') { - /* 230 User ... logged in. - (the user logged in without password) */ - infof(data, "We have successfully logged in\n"); - if (conn->ssl[FIRSTSOCKET].use) { -#ifdef HAVE_KRB4 - /* We are logged in with Kerberos, now set the requested protection - * level - */ - if(conn->sec_complete) - Curl_sec_set_protection_level(conn); - - /* We may need to issue a KAUTH here to have access to the files - * do it if user supplied a password - */ - if(conn->passwd && *conn->passwd) { - result = Curl_krb_kauth(conn); - if(result) - return result; - } -#endif - } - } - else { - failf(data, "Odd return code after USER"); - return CURLE_FTP_WEIRD_USER_REPLY; - } - - if(conn->ssl[FIRSTSOCKET].use) { - /* PBSZ = PROTECTION BUFFER SIZE. - - The 'draft-murray-auth-ftp-ssl' (draft 12, page 7) says: - - Specifically, the PROT command MUST be preceded by a PBSZ command - and a PBSZ command MUST be preceded by a successful security data - exchange (the TLS negotiation in this case) - - ... (and on page 8): - - Thus the PBSZ command must still be issued, but must have a parameter - of '0' to indicate that no buffering is taking place and the data - connection should not be encapsulated. - */ - FTPSENDF(conn, "PBSZ %d", 0); - result = Curl_GetFTPResponse(&nread, conn, &ftpcode); - if(result) - return result; - - /* For TLS, the data connection can have one of two security levels. - - 1)Clear (requested by 'PROT C') - - 2)Private (requested by 'PROT P') - */ - if(!conn->ssl[SECONDARYSOCKET].use) { - FTPSENDF(conn, "PROT %c", 'P'); - result = Curl_GetFTPResponse(&nread, conn, &ftpcode); - if(result) - return result; - - if(ftpcode == 200) - /* We have enabled SSL for the data connection! */ - conn->ssl[SECONDARYSOCKET].use = TRUE; - - /* FTP servers typically responds with 500 if they decide to reject - our 'P' request */ - } - } - - /* send PWD to discover our entry point */ - FTPSENDF(conn, "PWD", NULL); - - /* wait for feedback */ - result = Curl_GetFTPResponse(&nread, conn, &ftpcode); - if(result) - return result; - - if(ftpcode == 257) { - char *dir = (char *)malloc(nread+1); - char *store=dir; - char *ptr=&buf[4]; /* start on the first letter */ - - if(!dir) - return CURLE_OUT_OF_MEMORY; - - /* Reply format is like - 257<space>"<directory-name>"<space><commentary> and the RFC959 says - - The directory name can contain any character; embedded double-quotes - should be escaped by double-quotes (the "quote-doubling" convention). - */ - if('\"' == *ptr) { - /* it started good */ - ptr++; - while(ptr && *ptr) { - if('\"' == *ptr) { - if('\"' == ptr[1]) { - /* "quote-doubling" */ - *store = ptr[1]; - ptr++; - } - else { - /* end of path */ - *store = '\0'; /* zero terminate */ - break; /* get out of this loop */ - } - } - else - *store = *ptr; - store++; - ptr++; - } - ftp->entrypath =dir; /* remember this */ - infof(data, "Entry path is '%s'\n", ftp->entrypath); - } - else { - /* couldn't get the path */ - free(dir); - infof(data, "Failed to figure out path\n"); - } - - } - else { - /* We couldn't read the PWD response! */ - } - - return CURLE_OK; -} - -/*********************************************************************** - * - * Curl_ftp_done() - * - * The DONE function. This does what needs to be done after a single DO has - * performed. - * - * Input argument is already checked for validity. - */ -CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode status) -{ - struct SessionHandle *data = conn->data; - struct FTP *ftp = conn->proto.ftp; - ssize_t nread; - int ftpcode; - CURLcode result=CURLE_OK; - - bool was_ctl_valid = ftp->ctl_valid; - - /* free the dir tree and file parts */ - freedirs(ftp); - - ftp->ctl_valid = FALSE; - - if(data->set.upload) { - if((-1 != data->set.infilesize) && - (data->set.infilesize != *ftp->bytecountp) && - !data->set.crlf) { - failf(data, "Uploaded unaligned file size (%" FORMAT_OFF_T - " out of %" FORMAT_OFF_T " bytes)", - *ftp->bytecountp, data->set.infilesize); - conn->bits.close = TRUE; /* close this connection since we don't - know what state this error leaves us in */ - return CURLE_PARTIAL_FILE; - } - } - else { - if((-1 != conn->size) && (conn->size != *ftp->bytecountp) && - (conn->maxdownload != *ftp->bytecountp)) { - failf(data, "Received only partial file: %" FORMAT_OFF_T " bytes", - *ftp->bytecountp); - conn->bits.close = TRUE; /* close this connection since we don't - know what state this error leaves us in */ - return CURLE_PARTIAL_FILE; - } - else if(!ftp->dont_check && - !*ftp->bytecountp && - (conn->size>0)) { - /* We consider this an error, but there's no true FTP error received - why we need to continue to "read out" the server response too. - We don't want to leave a "waiting" server reply if we'll get told - to make a second request on this same connection! */ - failf(data, "No data was received!"); - result = CURLE_FTP_COULDNT_RETR_FILE; - } - } - - switch(status) { - case CURLE_BAD_DOWNLOAD_RESUME: - case CURLE_FTP_WEIRD_PASV_REPLY: - case CURLE_FTP_PORT_FAILED: - case CURLE_FTP_COULDNT_SET_BINARY: - case CURLE_FTP_COULDNT_RETR_FILE: - case CURLE_FTP_ACCESS_DENIED: - /* the connection stays alive fine even though this happened */ - /* fall-through */ - case CURLE_OK: /* doesn't affect the control connection's status */ - ftp->ctl_valid = was_ctl_valid; - break; - default: /* by default, an error means the control connection is - wedged and should not be used anymore */ - ftp->ctl_valid = FALSE; - break; - } - -#ifdef HAVE_KRB4 - Curl_sec_fflush_fd(conn, conn->sock[SECONDARYSOCKET]); -#endif - /* shut down the socket to inform the server we're done */ - sclose(conn->sock[SECONDARYSOCKET]); - conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; - - if(!ftp->no_transfer && !status) { - /* Let's see what the server says about the transfer we just performed, - * but lower the timeout as sometimes this connection has died while the - * data has been transfered. This happens when doing through NATs etc that - * abandon old silent connections. - */ - ftp->response_time = 60; /* give it only a minute for now */ - - result = Curl_GetFTPResponse(&nread, conn, &ftpcode); - - ftp->response_time = 3600; /* set this back to one hour waits */ - - if(!nread && (CURLE_OPERATION_TIMEDOUT == result)) { - failf(data, "control connection looks dead"); - return result; - } - - if(result) - return result; - - if(!ftp->dont_check) { - /* 226 Transfer complete, 250 Requested file action okay, completed. */ - if((ftpcode != 226) && (ftpcode != 250)) { - failf(data, "server did not report OK, got %d", ftpcode); - return CURLE_FTP_WRITE_ERROR; - } - } - } - - /* clear these for next connection */ - ftp->no_transfer = FALSE; - ftp->dont_check = FALSE; - - if (!result && conn->sec_conn) { /* 3rd party transfer */ - /* "done" with the secondary connection */ - result = Curl_ftp_done(conn->sec_conn, status); - } - - /* Send any post-transfer QUOTE strings? */ - if(!status && !result && data->set.postquote) - result = ftp_sendquote(conn, data->set.postquote); - - return result; -} - -/*********************************************************************** - * - * ftp_sendquote() - * - * Where a 'quote' means a list of custom commands to send to the server. - * The quote list is passed as an argument. - */ - -static -CURLcode ftp_sendquote(struct connectdata *conn, struct curl_slist *quote) -{ - struct curl_slist *item; - ssize_t nread; - int ftpcode; - CURLcode result; - - item = quote; - while (item) { - if (item->data) { - FTPSENDF(conn, "%s", item->data); - - result = Curl_GetFTPResponse(&nread, conn, &ftpcode); - if (result) - return result; - - if (ftpcode >= 400) { - failf(conn->data, "QUOT string not accepted: %s", item->data); - return CURLE_FTP_QUOTE_ERROR; - } - } - - item = item->next; - } - - return CURLE_OK; -} - -/*********************************************************************** - * - * ftp_getfiletime() - * - * Get the timestamp of the given file. - */ -static -CURLcode ftp_getfiletime(struct connectdata *conn, char *file) -{ - CURLcode result; - int ftpcode; /* for ftp status */ - ssize_t nread; - char *buf = conn->data->state.buffer; - - /* we have requested to get the modified-time of the file, this is yet - again a grey area as the MDTM is not kosher RFC959 */ - FTPSENDF(conn, "MDTM %s", file); - - result = Curl_GetFTPResponse(&nread, conn, &ftpcode); - if(result) - return result; - - switch(ftpcode) { - case 213: - { - /* we got a time. Format should be: "YYYYMMDDHHMMSS[.sss]" where the - last .sss part is optional and means fractions of a second */ - int year, month, day, hour, minute, second; - if(6 == sscanf(buf+4, "%04d%02d%02d%02d%02d%02d", - &year, &month, &day, &hour, &minute, &second)) { - /* we have a time, reformat it */ - time_t secs=time(NULL); - snprintf(buf, sizeof(conn->data->state.buffer), - "%04d%02d%02d %02d:%02d:%02d GMT", - year, month, day, hour, minute, second); - /* now, convert this into a time() value: */ - conn->data->info.filetime = curl_getdate(buf, &secs); - } - } - break; - default: - infof(conn->data, "unsupported MDTM reply format\n"); - break; - case 550: /* "No such file or directory" */ - failf(conn->data, "Given file does not exist"); - result = CURLE_FTP_COULDNT_RETR_FILE; - break; - } - return result; -} - -/*********************************************************************** - * - * ftp_transfertype() - * - * Set transfer type. We only deal with ASCII or BINARY so this function - * sets one of them. - */ -static CURLcode ftp_transfertype(struct connectdata *conn, - bool ascii) -{ - struct SessionHandle *data = conn->data; - int ftpcode; - ssize_t nread; - CURLcode result; - - FTPSENDF(conn, "TYPE %s", ascii?"A":"I"); - - result = Curl_GetFTPResponse(&nread, conn, &ftpcode); - if(result) - return result; - - if(ftpcode != 200) { - failf(data, "Couldn't set %s mode", - ascii?"ASCII":"binary"); - return ascii? CURLE_FTP_COULDNT_SET_ASCII:CURLE_FTP_COULDNT_SET_BINARY; - } - - return CURLE_OK; -} - -/*********************************************************************** - * - * ftp_getsize() - * - * Returns the file size (in bytes) of the given remote file. - */ - -static -CURLcode ftp_getsize(struct connectdata *conn, char *file, - curl_off_t *size) -{ - struct SessionHandle *data = conn->data; - int ftpcode; - ssize_t nread; - char *buf=data->state.buffer; - CURLcode result; - - FTPSENDF(conn, "SIZE %s", file); - result = Curl_GetFTPResponse(&nread, conn, &ftpcode); - if(result) - return result; - - if(ftpcode == 213) { - /* get the size from the ascii string: */ - *size = curlx_strtoofft(buf+4, NULL, 0); - } - else - return CURLE_FTP_COULDNT_GET_SIZE; - - return CURLE_OK; -} - -/*************************************************************************** - * - * ftp_pasv_verbose() - * - * This function only outputs some informationals about this second connection - * when we've issued a PASV command before and thus we have connected to a - * possibly new IP address. - * - */ -static void -ftp_pasv_verbose(struct connectdata *conn, - Curl_addrinfo *ai, - char *newhost, /* ascii version */ - int port) -{ - char buf[256]; - Curl_printable_address(ai, buf, sizeof(buf)); - infof(conn->data, "Connecting to %s (%s) port %d\n", newhost, buf, port); -} - -/*********************************************************************** - * - * ftp_use_port() - * - * Send the proper PORT command. PORT is the ftp client's way of telling the - * server that *WE* open a port that we listen on an awaits the server to - * connect to. This is the opposite of PASV. - */ - -static -CURLcode ftp_use_port(struct connectdata *conn) -{ - struct SessionHandle *data=conn->data; - curl_socket_t portsock; - ssize_t nread; - int ftpcode; /* receive FTP response codes in this */ - CURLcode result; - -#ifdef ENABLE_IPV6 - /****************************************************************** - * - * Here's a piece of IPv6-specific code coming up - * - */ - - struct addrinfo hints, *res, *ai; - struct sockaddr_storage ss; - socklen_t sslen; - char hbuf[NI_MAXHOST]; - - struct sockaddr *sa=(struct sockaddr *)&ss; - unsigned char *ap; - unsigned char *pp; - char portmsgbuf[1024], tmp[1024]; - - const char *mode[] = { "EPRT", "LPRT", "PORT", NULL }; - char **modep; - int rc; - int error; - - /* - * we should use Curl_if2ip? given pickiness of recent ftpd, - * I believe we should use the same address as the control connection. - */ - sslen = sizeof(ss); - rc = getsockname(conn->sock[FIRSTSOCKET], (struct sockaddr *)&ss, &sslen); - if(rc < 0) { - failf(data, "getsockname() returned %d\n", rc); - return CURLE_FTP_PORT_FAILED; - } - - rc = getnameinfo((struct sockaddr *)&ss, sslen, hbuf, sizeof(hbuf), NULL, 0, - NIFLAGS); - if(rc) { - failf(data, "getnameinfo() returned %d\n", rc); - return CURLE_FTP_PORT_FAILED; - } - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = sa->sa_family; - /*hints.ai_family = ss.ss_family; - this way can be used if sockaddr_storage is properly defined, as glibc - 2.1.X doesn't do*/ - hints.ai_socktype = SOCK_STREAM; - hints.ai_flags = AI_PASSIVE; - - rc = getaddrinfo(hbuf, NULL, &hints, &res); - if(rc) { - failf(data, "getaddrinfo() returned %d\n", rc); - return CURLE_FTP_PORT_FAILED; - } - - portsock = CURL_SOCKET_BAD; - error = 0; - for (ai = res; ai; ai = ai->ai_next) { - /* - * Workaround for AIX5 getaddrinfo() problem (it doesn't set ai_socktype): - */ - if (ai->ai_socktype == 0) - ai->ai_socktype = hints.ai_socktype; - - portsock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); - if (portsock == CURL_SOCKET_BAD) { - error = Curl_ourerrno(); - continue; - } - - if (bind(portsock, ai->ai_addr, ai->ai_addrlen) < 0) { - error = Curl_ourerrno(); - sclose(portsock); - portsock = CURL_SOCKET_BAD; - continue; - } - - if (listen(portsock, 1) < 0) { - error = Curl_ourerrno(); - sclose(portsock); - portsock = CURL_SOCKET_BAD; - continue; - } - - break; - } - freeaddrinfo(res); - if (portsock == CURL_SOCKET_BAD) { - failf(data, "%s", Curl_strerror(conn,error)); - return CURLE_FTP_PORT_FAILED; - } - - sslen = sizeof(ss); - if (getsockname(portsock, sa, &sslen) < 0) { - failf(data, "%s", Curl_strerror(conn,Curl_ourerrno())); - return CURLE_FTP_PORT_FAILED; - } - - for (modep = (char **)(data->set.ftp_use_eprt?&mode[0]:&mode[2]); - modep && *modep; modep++) { - int lprtaf, eprtaf; - int alen=0, plen=0; - - switch (sa->sa_family) { - case AF_INET: - ap = (unsigned char *)&((struct sockaddr_in *)&ss)->sin_addr; - alen = sizeof(((struct sockaddr_in *)&ss)->sin_addr); - pp = (unsigned char *)&((struct sockaddr_in *)&ss)->sin_port; - plen = sizeof(((struct sockaddr_in *)&ss)->sin_port); - lprtaf = 4; - eprtaf = 1; - break; - case AF_INET6: - ap = (unsigned char *)&((struct sockaddr_in6 *)&ss)->sin6_addr; - alen = sizeof(((struct sockaddr_in6 *)&ss)->sin6_addr); - pp = (unsigned char *)&((struct sockaddr_in6 *)&ss)->sin6_port; - plen = sizeof(((struct sockaddr_in6 *)&ss)->sin6_port); - lprtaf = 6; - eprtaf = 2; - break; - default: - ap = pp = NULL; - lprtaf = eprtaf = -1; - break; - } - - if (strcmp(*modep, "EPRT") == 0) { - if (eprtaf < 0) - continue; - if (getnameinfo((struct sockaddr *)&ss, sslen, - portmsgbuf, sizeof(portmsgbuf), tmp, sizeof(tmp), - NIFLAGS)) - continue; - - /* do not transmit IPv6 scope identifier to the wire */ - if (sa->sa_family == AF_INET6) { - char *q = strchr(portmsgbuf, '%'); - if (q) - *q = '\0'; - } - - result = Curl_ftpsendf(conn, "%s |%d|%s|%s|", *modep, eprtaf, - portmsgbuf, tmp); - if(result) - return result; - } - else if (strcmp(*modep, "LPRT") == 0 || - strcmp(*modep, "PORT") == 0) { - int i; - - if (strcmp(*modep, "LPRT") == 0 && lprtaf < 0) - continue; - if (strcmp(*modep, "PORT") == 0 && sa->sa_family != AF_INET) - continue; - - portmsgbuf[0] = '\0'; - if (strcmp(*modep, "LPRT") == 0) { - snprintf(tmp, sizeof(tmp), "%d,%d", lprtaf, alen); - if (strlcat(portmsgbuf, tmp, sizeof(portmsgbuf)) >= - sizeof(portmsgbuf)) { - continue; - } - } - - for (i = 0; i < alen; i++) { - if (portmsgbuf[0]) - snprintf(tmp, sizeof(tmp), ",%u", ap[i]); - else - snprintf(tmp, sizeof(tmp), "%u", ap[i]); - - if (strlcat(portmsgbuf, tmp, sizeof(portmsgbuf)) >= - sizeof(portmsgbuf)) { - continue; - } - } - - if (strcmp(*modep, "LPRT") == 0) { - snprintf(tmp, sizeof(tmp), ",%d", plen); - - if (strlcat(portmsgbuf, tmp, sizeof(portmsgbuf)) >= sizeof(portmsgbuf)) - continue; - } - - for (i = 0; i < plen; i++) { - snprintf(tmp, sizeof(tmp), ",%u", pp[i]); - - if (strlcat(portmsgbuf, tmp, sizeof(portmsgbuf)) >= - sizeof(portmsgbuf)) { - continue; - } - } - - result = Curl_ftpsendf(conn, "%s %s", *modep, portmsgbuf); - if(result) - return result; - } - - result = Curl_GetFTPResponse(&nread, conn, &ftpcode); - if(result) - return result; - - if (ftpcode != 200) { - continue; - } - else - break; - } - - if (!*modep) { - sclose(portsock); - failf(data, "PORT command attempts failed"); - return CURLE_FTP_PORT_FAILED; - } - /* we set the secondary socket variable to this for now, it - is only so that the cleanup function will close it in case - we fail before the true secondary stuff is made */ - conn->sock[SECONDARYSOCKET] = portsock; - -#else - /****************************************************************** - * - * Here's a piece of IPv4-specific code coming up - * - */ - struct sockaddr_in sa; - unsigned short porttouse; - char myhost[256] = ""; - bool sa_filled_in = FALSE; - Curl_addrinfo *addr = NULL; - unsigned short ip[4]; - - if(data->set.ftpport) { - in_addr_t in; - - /* First check if the given name is an IP address */ - in=inet_addr(data->set.ftpport); - - if(in != CURL_INADDR_NONE) - /* this is an IPv4 address */ - addr = Curl_ip2addr(in, data->set.ftpport, 0); - else { - if(Curl_if2ip(data->set.ftpport, myhost, sizeof(myhost))) { - /* The interface to IP conversion provided a dotted address */ - in=inet_addr(myhost); - addr = Curl_ip2addr(in, myhost, 0); - } - else if(strlen(data->set.ftpport)> 1) { - /* might be a host name! */ - struct Curl_dns_entry *h=NULL; - int rc = Curl_resolv(conn, myhost, 0, &h); - if(rc == CURLRESOLV_PENDING) - rc = Curl_wait_for_resolv(conn, &h); - (void)rc; - if(h) { - addr = h->addr; - /* when we return from this function, we can forget about this entry - to we can unlock it now already */ - Curl_resolv_unlock(data, h); - } /* (h) */ - } /* strlen */ - } /* CURL_INADDR_NONE */ - } /* data->set.ftpport */ - - if(!addr) { - /* pick a suitable default here */ - -#ifdef __hpux - int sslen; -#else - socklen_t sslen; -#endif - - sslen = sizeof(sa); - if (getsockname(conn->sock[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 */ - } - - if (addr || sa_filled_in) { - portsock = socket(AF_INET, SOCK_STREAM, 0); - if(CURL_SOCKET_BAD != portsock) { - socklen_t size; - - /* we set the secondary socket variable to this for now, it - is only so that the cleanup function will close it in case - we fail before the true secondary stuff is made */ - conn->sock[SECONDARYSOCKET] = portsock; - - if(!sa_filled_in) { - memcpy(&sa, addr->ai_addr, sizeof(sa)); - sa.sin_addr.s_addr = INADDR_ANY; - } - - sa.sin_port = 0; - size = sizeof(sa); - - if(bind(portsock, (struct sockaddr *)&sa, size) >= 0) { - /* we succeeded to bind */ - struct sockaddr_in add; -#ifdef __hpux - int socksize = sizeof(add); -#else - socklen_t socksize = sizeof(add); -#endif - - if(getsockname(portsock, (struct sockaddr *) &add, - &socksize)<0) { - failf(data, "getsockname() failed"); - return CURLE_FTP_PORT_FAILED; - } - porttouse = ntohs(add.sin_port); - - if ( listen(portsock, 1) < 0 ) { - failf(data, "listen(2) failed on socket"); - return CURLE_FTP_PORT_FAILED; - } - } - else { - failf(data, "bind(2) failed on socket"); - return CURLE_FTP_PORT_FAILED; - } - } - else { - failf(data, "socket(2) failed (%s)"); - return CURLE_FTP_PORT_FAILED; - } - } - else { - failf(data, "could't find IP address to use"); - return CURLE_FTP_PORT_FAILED; - } - - if(sa_filled_in) - Curl_inet_ntop(AF_INET, &((struct sockaddr_in *)&sa)->sin_addr, - myhost, sizeof(myhost)); - else - Curl_printable_address(addr, myhost, sizeof(myhost)); - - if(4 == sscanf(myhost, "%hu.%hu.%hu.%hu", - &ip[0], &ip[1], &ip[2], &ip[3])) { - - infof(data, "Telling server to connect to %d.%d.%d.%d:%d\n", - ip[0], ip[1], ip[2], ip[3], porttouse); - - result=Curl_ftpsendf(conn, "PORT %d,%d,%d,%d,%d,%d", - ip[0], ip[1], ip[2], ip[3], - porttouse >> 8, - porttouse & 255); - if(result) - return result; - - } - else - return CURLE_FTP_PORT_FAILED; - - Curl_freeaddrinfo(addr); - - result = Curl_GetFTPResponse(&nread, conn, &ftpcode); - if(result) - return result; - - if(ftpcode != 200) { - failf(data, "Server does not grok PORT, try without it!"); - return CURLE_FTP_PORT_FAILED; - } -#endif /* end of ipv4-specific code */ - - return CURLE_OK; -} - -/*********************************************************************** - * - * ftp_use_pasv() - * - * Send the PASV command. PASV is the ftp client's way of asking the server to - * open a second port that we can connect to (for the data transfer). This is - * the opposite of PORT. - */ - -static -CURLcode ftp_use_pasv(struct connectdata *conn, - bool *connected) -{ - struct SessionHandle *data = conn->data; - ssize_t nread; - char *buf = data->state.buffer; /* this is our buffer */ - int ftpcode; /* receive FTP response codes in this */ - CURLcode result; - struct Curl_dns_entry *addr=NULL; - Curl_addrinfo *conninfo; - int rc; - - /* - Here's the excecutive summary on what to do: - - PASV is RFC959, expect: - 227 Entering Passive Mode (a1,a2,a3,a4,p1,p2) - - LPSV is RFC1639, expect: - 228 Entering Long Passive Mode (4,4,a1,a2,a3,a4,2,p1,p2) - - EPSV is RFC2428, expect: - 229 Entering Extended Passive Mode (|||port|) - - */ - - const char *mode[] = { "EPSV", "PASV", NULL }; - int results[] = { 229, 227, 0 }; - int modeoff; - unsigned short connectport; /* the local port connect() should use! */ - unsigned short newport=0; /* remote port, not necessary the local one */ - - /* newhost must be able to hold a full IP-style address in ASCII, which - in the IPv6 case means 5*8-1 = 39 letters */ - char newhost[48]; - char *newhostp=NULL; - - for (modeoff = (data->set.ftp_use_epsv?0:1); - mode[modeoff]; modeoff++) { - result = Curl_ftpsendf(conn, "%s", mode[modeoff]); - if(result) - return result; - result = Curl_GetFTPResponse(&nread, conn, &ftpcode); - if(result) - return result; - if (ftpcode == results[modeoff]) - break; - } - - if (!mode[modeoff]) { - failf(data, "Odd return code after PASV"); - return CURLE_FTP_WEIRD_PASV_REPLY; - } - else if (227 == results[modeoff]) { - int ip[4]; - int port[2]; - char *str=buf; - - /* - * New 227-parser June 3rd 1999. - * It now scans for a sequence of six comma-separated numbers and - * will take them as IP+port indicators. - * - * Found reply-strings include: - * "227 Entering Passive Mode (127,0,0,1,4,51)" - * "227 Data transfer will passively listen to 127,0,0,1,4,51" - * "227 Entering passive mode. 127,0,0,1,4,51" - */ - - while(*str) { - if (6 == sscanf(str, "%d,%d,%d,%d,%d,%d", - &ip[0], &ip[1], &ip[2], &ip[3], - &port[0], &port[1])) - break; - str++; - } - - if(!*str) { - failf(data, "Couldn't interpret this 227-reply: %s", buf); - return CURLE_FTP_WEIRD_227_FORMAT; - } - - snprintf(newhost, sizeof(newhost), - "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]); - newhostp = newhost; - newport = (port[0]<<8) + port[1]; - } - else if (229 == results[modeoff]) { - char *ptr = strchr(buf, '('); - if(ptr) { - unsigned int num; - char separator[4]; - ptr++; - if(5 == sscanf(ptr, "%c%c%c%u%c", - &separator[0], - &separator[1], - &separator[2], - &num, - &separator[3])) { - char sep1 = separator[0]; - int i; - - /* The four separators should be identical, or else this is an oddly - formatted reply and we bail out immediately. */ - for(i=1; i<4; i++) { - if(separator[i] != sep1) { - ptr=NULL; /* set to NULL to signal error */ - break; - } - } - if(ptr) { - newport = num; - - /* we should use the same host we already are connected to */ - newhostp = conn->host.name; - } - } - else - ptr=NULL; - } - if(!ptr) { - failf(data, "Weirdly formatted EPSV reply"); - return CURLE_FTP_WEIRD_PASV_REPLY; - } - } - else - return CURLE_FTP_CANT_RECONNECT; - - if(data->change.proxy && *data->change.proxy) { - /* - * This is a tunnel through a http proxy and we need to connect to the - * proxy again here. - * - * We don't want to rely on a former host lookup that might've expired - * now, instead we remake the lookup here and now! - */ - rc = Curl_resolv(conn, conn->proxy.name, (int)conn->port, &addr); - if(rc == CURLRESOLV_PENDING) - rc = Curl_wait_for_resolv(conn, &addr); - - connectport = - (unsigned short)conn->port; /* we connect to the proxy's port */ - - } - else { - /* normal, direct, ftp connection */ - rc = Curl_resolv(conn, newhostp, newport, &addr); - if(rc == CURLRESOLV_PENDING) - rc = Curl_wait_for_resolv(conn, &addr); - - if(!addr) { - failf(data, "Can't resolve new host %s:%d", newhostp, newport); - return CURLE_FTP_CANT_GET_HOST; - } - connectport = newport; /* we connect to the remote port */ - } - - result = Curl_connecthost(conn, - addr, - &conn->sock[SECONDARYSOCKET], - &conninfo, - connected); - - Curl_resolv_unlock(data, addr); /* we're done using this address */ - - if(result) - return result; - - /* - * 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(data->set.verbose) - /* this just dumps information about this second connection */ - ftp_pasv_verbose(conn, conninfo, newhostp, connectport); - -#ifndef CURL_DISABLE_HTTP - if(conn->bits.tunnel_proxy) { - /* We want "seamless" FTP operations through HTTP proxy tunnel */ - result = Curl_ConnectHTTPProxyTunnel(conn, SECONDARYSOCKET, - newhostp, newport); - if(CURLE_OK != result) - return result; - } -#endif /* CURL_DISABLE_HTTP */ - - (void)rc; - return CURLE_OK; -} - -/* - * Curl_ftp_nextconnect() - * - * This function shall be called when the second FTP connection has been - * established and is confirmed connected. - */ - -CURLcode Curl_ftp_nextconnect(struct connectdata *conn) -{ - struct SessionHandle *data=conn->data; - char *buf = data->state.buffer; /* this is our buffer */ - CURLcode result; - ssize_t nread; - int ftpcode; /* for ftp status */ - - /* the ftp struct is already inited in Curl_ftp_connect() */ - struct FTP *ftp = conn->proto.ftp; - curl_off_t *bytecountp = ftp->bytecountp; - - if(data->set.upload) { - - /* Set type to binary (unless specified ASCII) */ - result = ftp_transfertype(conn, data->set.ftp_ascii); - if(result) - return result; - - /* Send any PREQUOTE strings after transfer type is set? (Wesley Laxton)*/ - if(data->set.prequote) { - if ((result = ftp_sendquote(conn, data->set.prequote)) != CURLE_OK) - return result; - } - - if(conn->resume_from) { - /* we're about to continue the uploading of a file */ - /* 1. get already existing file's size. We use the SIZE - command for this which may not exist in the server! - The SIZE command is not in RFC959. */ - - /* 2. This used to set REST. But since we can do append, we - don't another ftp command. We just skip the source file - offset and then we APPEND the rest on the file instead */ - - /* 3. pass file-size number of bytes in the source file */ - /* 4. lower the infilesize counter */ - /* => transfer as usual */ - - if(conn->resume_from < 0 ) { - /* we could've got a specified offset from the command line, - but now we know we didn't */ - curl_off_t gottensize; - - if(CURLE_OK != ftp_getsize(conn, ftp->file, &gottensize)) { - failf(data, "Couldn't get remote file size"); - return CURLE_FTP_COULDNT_GET_SIZE; - } - conn->resume_from = gottensize; - } - - if(conn->resume_from) { - /* do we still game? */ - curl_off_t passed=0; - /* enable append instead */ - data->set.ftp_append = 1; - - /* Now, let's read off the proper amount of bytes from the - input. If we knew it was a proper file we could've just - fseek()ed but we only have a stream here */ - do { - curl_off_t readthisamountnow = (conn->resume_from - passed); - curl_off_t actuallyread; - - if(readthisamountnow > BUFSIZE) - readthisamountnow = BUFSIZE; - - actuallyread = (curl_off_t) - conn->fread(data->state.buffer, 1, (size_t)readthisamountnow, - conn->fread_in); - - passed += actuallyread; - if(actuallyread != readthisamountnow) { - failf(data, "Could only read %" FORMAT_OFF_T - " bytes from the input", passed); - return CURLE_FTP_COULDNT_USE_REST; - } - } - while(passed != conn->resume_from); - - /* now, decrease the size of the read */ - if(data->set.infilesize>0) { - data->set.infilesize -= conn->resume_from; - - if(data->set.infilesize <= 0) { - infof(data, "File already completely uploaded\n"); - - /* no data to transfer */ - result=Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL); - (void)result; - - /* Set no_transfer so that we won't get any error in - * Curl_ftp_done() because we didn't transfer anything! */ - ftp->no_transfer = TRUE; - - return CURLE_OK; - } - } - /* we've passed, proceed as normal */ - } - } - - /* Send everything on data->state.in to the socket */ - if(data->set.ftp_append) { - /* we append onto the file instead of rewriting it */ - FTPSENDF(conn, "APPE %s", ftp->file); - } - else { - FTPSENDF(conn, "STOR %s", ftp->file); - } - - result = Curl_GetFTPResponse(&nread, conn, &ftpcode); - if(result) - return result; - - if(ftpcode>=400) { - failf(data, "Failed FTP upload:%s", buf+3); - /* oops, we never close the sockets! */ - return CURLE_FTP_COULDNT_STOR_FILE; - } - - if(data->set.ftp_use_port) { - /* PORT means we are now awaiting the server to connect to us. */ - result = AllowServerConnect(conn); - if( result ) - return result; - } - - if(conn->ssl[SECONDARYSOCKET].use) { - /* since we only have a plaintext TCP connection here, we must now - do the TLS stuff */ - infof(data, "Doing the SSL/TLS handshake on the data stream\n"); - result = Curl_SSLConnect(conn, SECONDARYSOCKET); - if(result) - return result; - } - - *bytecountp=0; - - /* When we know we're uploading a specified file, we can get the file - size prior to the actual upload. */ - - Curl_pgrsSetUploadSize(data, data->set.infilesize); - - result = Curl_Transfer(conn, -1, -1, FALSE, NULL, /* no download */ - SECONDARYSOCKET, bytecountp); - if(result) - return result; - - } - else if(!conn->bits.no_body) { - /* Retrieve file or directory */ - bool dirlist=FALSE; - curl_off_t downloadsize=-1; - - if(conn->bits.use_range && conn->range) { - curl_off_t from, to; - curl_off_t totalsize; - char *ptr; - char *ptr2; - - from=curlx_strtoofft(conn->range, &ptr, 0); - while(ptr && *ptr && (isspace((int)*ptr) || (*ptr=='-'))) - ptr++; - to=curlx_strtoofft(ptr, &ptr2, 0); - if(ptr == ptr2) { - /* we didn't get any digit */ - to=-1; - } - if((-1 == to) && (from>=0)) { - /* X - */ - conn->resume_from = from; - infof(data, "FTP RANGE %" FORMAT_OFF_T " to end of file\n", from); - } - else if(from < 0) { - /* -Y */ - totalsize = -from; - conn->maxdownload = -from; - conn->resume_from = from; - infof(data, "FTP RANGE the last %" FORMAT_OFF_T " bytes\n", totalsize); - } - else { - /* X-Y */ - totalsize = to-from; - conn->maxdownload = totalsize+1; /* include the last mentioned byte */ - conn->resume_from = from; - infof(data, "FTP RANGE from %" FORMAT_OFF_T - " getting %" FORMAT_OFF_T " bytes\n", from, conn->maxdownload); - } - infof(data, "range-download from %" FORMAT_OFF_T - " to %" FORMAT_OFF_T ", totally %" FORMAT_OFF_T " bytes\n", - from, to, conn->maxdownload); - ftp->dont_check = TRUE; /* dont check for successful transfer */ - } - - if((data->set.ftp_list_only) || !ftp->file) { - /* The specified path ends with a slash, and therefore we think this - is a directory that is requested, use LIST. But before that we - need to set ASCII transfer mode. */ - dirlist = TRUE; - - /* Set type to ASCII */ - result = ftp_transfertype(conn, TRUE /* ASCII enforced */); - if(result) - return result; - - /* if this output is to be machine-parsed, the NLST command will be - better used since the LIST command output is not specified or - standard in any way */ - - FTPSENDF(conn, "%s", - data->set.customrequest?data->set.customrequest: - (data->set.ftp_list_only?"NLST":"LIST")); - } - else { - curl_off_t foundsize; - - /* Set type to binary (unless specified ASCII) */ - result = ftp_transfertype(conn, data->set.ftp_ascii); - if(result) - return result; - - /* Send any PREQUOTE strings after transfer type is set? */ - if(data->set.prequote) { - if ((result = ftp_sendquote(conn, data->set.prequote)) != CURLE_OK) - return result; - } - - /* Attempt to get the size, it'll be useful in some cases: for resumed - downloads and when talking to servers that don't give away the size - in the RETR response line. */ - result = ftp_getsize(conn, ftp->file, &foundsize); - if(CURLE_OK == result) { - if (data->set.max_filesize && foundsize > data->set.max_filesize) { - failf(data, "Maximum file size exceeded"); - return CURLE_FILESIZE_EXCEEDED; - } - downloadsize = foundsize; - } - - if(conn->resume_from) { - - /* Daniel: (August 4, 1999) - * - * We start with trying to use the SIZE command to figure out the size - * of the file we're gonna get. If we can get the size, this is by far - * the best way to know if we're trying to resume beyond the EOF. - * - * Daniel, November 28, 2001. We *always* get the size on downloads - * now, so it is done before this even when not doing resumes. I saved - * the comment above for nostalgical reasons! ;-) - */ - if(CURLE_OK != result) { - infof(data, "ftp server doesn't support SIZE\n"); - /* We couldn't get the size and therefore we can't know if there - really is a part of the file left to get, although the server - will just close the connection when we start the connection so it - won't cause us any harm, just not make us exit as nicely. */ - } - else { - /* We got a file size report, so we check that there actually is a - part of the file left to get, or else we go home. */ - if(conn->resume_from< 0) { - /* We're supposed to download the last abs(from) bytes */ - if(foundsize < -conn->resume_from) { - failf(data, "Offset (%" FORMAT_OFF_T - ") was beyond file size (%" FORMAT_OFF_T ")", - conn->resume_from, foundsize); - return CURLE_FTP_BAD_DOWNLOAD_RESUME; - } - /* convert to size to download */ - downloadsize = -conn->resume_from; - /* download from where? */ - conn->resume_from = foundsize - downloadsize; - } - else { - if(foundsize < conn->resume_from) { - failf(data, "Offset (%" FORMAT_OFF_T - ") was beyond file size (%" FORMAT_OFF_T ")", - conn->resume_from, foundsize); - return CURLE_FTP_BAD_DOWNLOAD_RESUME; - } - /* Now store the number of bytes we are expected to download */ - downloadsize = foundsize-conn->resume_from; - } - } - - if (downloadsize == 0) { - /* no data to transfer */ - result=Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL); - (void)result; - infof(data, "File already completely downloaded\n"); - - /* Set no_transfer so that we won't get any error in Curl_ftp_done() - * because we didn't transfer the any file */ - ftp->no_transfer = TRUE; - return CURLE_OK; - } - - /* Set resume file transfer offset */ - infof(data, "Instructs server to resume from offset %" FORMAT_OFF_T - "\n", - conn->resume_from); - - FTPSENDF(conn, "REST %" FORMAT_OFF_T, conn->resume_from); - - result = Curl_GetFTPResponse(&nread, conn, &ftpcode); - if(result) - return result; - - if(ftpcode != 350) { - failf(data, "Couldn't use REST: %s", buf+4); - return CURLE_FTP_COULDNT_USE_REST; - } - } - - FTPSENDF(conn, "RETR %s", ftp->file); - } - - result = Curl_GetFTPResponse(&nread, conn, &ftpcode); - if(result) - return result; - - if((ftpcode == 150) || (ftpcode == 125)) { - - /* - A; - 150 Opening BINARY mode data connection for /etc/passwd (2241 - bytes). (ok, the file is being transfered) - - B: - 150 Opening ASCII mode data connection for /bin/ls - - C: - 150 ASCII data connection for /bin/ls (137.167.104.91,37445) (0 bytes). - - D: - 150 Opening ASCII mode data connection for /linux/fisk/kpanelrc (0.0.0.0,0) (545 bytes). - - E: - 125 Data connection already open; Transfer starting. */ - - curl_off_t size=-1; /* default unknown size */ - - - /* - * It appears that there are FTP-servers that return size 0 for files - * when SIZE is used on the file while being in BINARY mode. To work - * around that (stupid) behavior, we attempt to parse the RETR response - * even if the SIZE returned size zero. - * - * Debugging help from Salvatore Sorrentino on February 26, 2003. - */ - - if(!dirlist && - !data->set.ftp_ascii && - (downloadsize < 1)) { - /* - * It seems directory listings either don't show the size or very - * often uses size 0 anyway. ASCII transfers may very well turn out - * that the transfered amount of data is not the same as this line - * tells, why using this number in those cases only confuses us. - * - * Example D above makes this parsing a little tricky */ - char *bytes; - bytes=strstr(buf, " bytes"); - if(bytes--) { - long in=bytes-buf; - /* this is a hint there is size information in there! ;-) */ - while(--in) { - /* scan for the parenthesis and break there */ - if('(' == *bytes) - break; - /* if only skip digits, or else we're in deep trouble */ - if(!isdigit((int)*bytes)) { - bytes=NULL; - break; - } - /* one more estep backwards */ - bytes--; - } - /* only if we have nothing but digits: */ - if(bytes++) { - /* get the number! */ - size = curlx_strtoofft(bytes, NULL, 0); - } - - } - } - else if(downloadsize > -1) - size = downloadsize; - - if(data->set.ftp_use_port) { - result = AllowServerConnect(conn); - if( result ) - return result; - } - - if(conn->ssl[SECONDARYSOCKET].use) { - /* since we only have a plaintext TCP connection here, we must now - do the TLS stuff */ - infof(data, "Doing the SSL/TLS handshake on the data stream\n"); - result = Curl_SSLConnect(conn, SECONDARYSOCKET); - if(result) - return result; - } - - if(size > conn->maxdownload && conn->maxdownload > 0) - size = conn->size = conn->maxdownload; - - infof(data, "Getting file with size: %" FORMAT_OFF_T "\n", size); - - /* FTP download: */ - result=Curl_Transfer(conn, SECONDARYSOCKET, size, FALSE, - bytecountp, - -1, NULL); /* no upload here */ - if(result) - return result; - } - else { - if(dirlist && (ftpcode == 450)) { - /* simply no matching files */ - ftp->no_transfer = TRUE; /* don't think we should download anything */ - } - else { - failf(data, "%s", buf+4); - return CURLE_FTP_COULDNT_RETR_FILE; - } - } - - } - /* end of transfer */ - - 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 Curl_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_and_mkd(conn, ftp->entrypath)) != CURLE_OK) - return result; - } - - { - int i; /* counter for loop */ - for (i=0; i < ftp->dirdepth; i++) { - /* RFC 1738 says empty components should be respected too, but - that is plain stupid since CWD can't be used with an empty argument */ - if ((result = ftp_cwd_and_mkd(conn, ftp->dirs[i])) != CURLE_OK) - return result; - } - } - - /* Requested time of file or time-depended transfer? */ - if((data->set.get_filetime || data->set.timecondition) && - ftp->file) { - result = ftp_getfiletime(conn, ftp->file); - switch( result ) - { - case CURLE_FTP_COULDNT_RETR_FILE: - case CURLE_OK: - if(data->set.timecondition) { - if((data->info.filetime > 0) && (data->set.timevalue > 0)) { - switch(data->set.timecondition) { - case CURL_TIMECOND_IFMODSINCE: - default: - if(data->info.filetime < data->set.timevalue) { - infof(data, "The requested document is not new enough\n"); - ftp->no_transfer = TRUE; /* mark this to not transfer data */ - return CURLE_OK; - } - break; - case CURL_TIMECOND_IFUNMODSINCE: - if(data->info.filetime > data->set.timevalue) { - infof(data, "The requested document is not old enough\n"); - ftp->no_transfer = TRUE; /* mark this to not transfer data */ - return CURLE_OK; - } - break; - } /* switch */ - } - else { - infof(data, "Skipping time comparison\n"); - } - } - break; - default: - return result; - } /* switch */ - } - - /* 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(conn->bits.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! */ - curl_off_t filesize; - ssize_t nread; - int ftpcode; - - 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) { - snprintf(buf, sizeof(data->state.buffer), - "Content-Length: %" FORMAT_OFF_T "\r\n", filesize); - result = Curl_client_write(data, CLIENTWRITE_BOTH, buf, 0); - if(result) - return result; - } - - /* Determine if server can respond to REST command and therefore - whether it can do a range */ - FTPSENDF(conn, "REST 0", NULL); - result = Curl_GetFTPResponse(&nread, conn, &ftpcode); - - if ((CURLE_OK == result) && (ftpcode == 350)) { - result = Curl_client_write(data, CLIENTWRITE_BOTH, - (char *)"Accept-ranges: bytes\r\n", 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>=0) ) { - struct tm *tm; - time_t cuClock = (time_t)data->info.filetime; -#ifdef HAVE_GMTIME_R - struct tm buffer; - tm = (struct tm *)gmtime_r(&cuClock, &buffer); -#else - tm = gmtime(&cuClock); -#endif - /* format: "Tue, 15 Nov 1994 12:45:26" */ - strftime(buf, BUFSIZE-1, "Last-Modified: %a, %d %b %Y %H:%M:%S GMT\r\n", - tm); - result = Curl_client_write(data, CLIENTWRITE_BOTH, buf, 0); - if(result) - return result; - } -#endif - - return CURLE_OK; - } - - if(conn->bits.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(CURLE_OK == result && *connected) - infof(data, "Connected the data stream with PASV!\n"); - } - - return result; -} - -/*********************************************************************** - * - * Curl_ftp() - * - * This function is registered as 'curl_do' function. It decodes the path - * parts etc as a wrapper to the actual DO function (ftp_perform). - * - * The input argument is already checked for validity. - */ -CURLcode Curl_ftp(struct connectdata *conn) -{ - CURLcode retcode; - - if (conn->sec_conn) /* 3rd party transfer */ - retcode = ftp_3rdparty(conn); - else - retcode = ftp_regular_transfer(conn); - - return retcode; -} - -/*********************************************************************** - * - * Curl_ftpsendf() - * - * Sends the formated string as a ftp command to a ftp server - * - * NOTE: we build the command in a fixed-length buffer, which sets length - * restrictions on the command! - */ -CURLcode Curl_ftpsendf(struct connectdata *conn, - const char *fmt, ...) -{ - ssize_t bytes_written; - char s[256]; - size_t write_len; - char *sptr=s; - CURLcode res; - - va_list ap; - va_start(ap, fmt); - vsnprintf(s, 250, fmt, ap); - va_end(ap); - - strcat(s, "\r\n"); /* append a trailing CRLF */ - - bytes_written=0; - write_len = strlen(s); - - while(1) { - res = Curl_write(conn, conn->sock[FIRSTSOCKET], sptr, write_len, - &bytes_written); - - if(CURLE_OK != res) - break; - - if(conn->data->set.verbose) - Curl_debug(conn->data, CURLINFO_HEADER_OUT, sptr, bytes_written, conn->host.dispname); - - if(bytes_written != (ssize_t)write_len) { - write_len -= bytes_written; - sptr += bytes_written; - } - else - break; - } - - return res; -} - -/*********************************************************************** - * - * ftp_quit() - * - * This should be called before calling sclose() on an ftp control connection - * (not data connections). We should then wait for the response from the - * server before returning. The calling code should then try to close the - * connection. - * - */ -static CURLcode ftp_quit(struct connectdata *conn) -{ - ssize_t nread; - int ftpcode; - CURLcode ret = CURLE_OK; - - if(conn->proto.ftp->ctl_valid) { - ret = Curl_ftpsendf(conn, "%s", "QUIT"); - if(CURLE_OK == ret) - ret = Curl_GetFTPResponse(&nread, conn, &ftpcode); - } - - return ret; -} - -/*********************************************************************** - * - * Curl_ftp_disconnect() - * - * Disconnect from an FTP server. Cleanup protocol-specific per-connection - * resources - */ -CURLcode Curl_ftp_disconnect(struct connectdata *conn) -{ - struct FTP *ftp= conn->proto.ftp; - - /* We cannot send quit unconditionally. If this connection is stale or - bad in any way, sending quit and waiting around here will make the - disconnect wait in vain and cause more problems than we need to. - - ftp_quit() will check the state of ftp->ctl_valid. If it's ok it - will try to send the QUIT command, otherwise it will just return. - */ - - /* The FTP session may or may not have been allocated/setup at this point! */ - if(ftp) { - (void)ftp_quit(conn); /* ignore errors on the QUIT */ - - if(ftp->entrypath) - free(ftp->entrypath); - if(ftp->cache) { - free(ftp->cache); - ftp->cache = NULL; - } - freedirs(ftp); - } - return CURLE_OK; -} - -/*********************************************************************** - * - * ftp_mkd() - * - * Makes a directory on the FTP server. - * - * Calls failf() - */ -static CURLcode ftp_mkd(struct connectdata *conn, char *path) -{ - CURLcode result; - int ftpcode; /* for ftp status */ - ssize_t nread; - - /* Create a directory on the remote server */ - FTPSENDF(conn, "MKD %s", path); - - result = Curl_GetFTPResponse(&nread, conn, &ftpcode); - if(result) - return result; - - switch(ftpcode) { - case 257: - /* success! */ - infof( conn->data , "Created remote directory %s\n" , path ); - break; - case 550: - failf(conn->data, "Permission denied to make directory %s", path); - result = CURLE_FTP_ACCESS_DENIED; - break; - default: - failf(conn->data, "unrecognized MKD response: %d", ftpcode ); - result = CURLE_FTP_ACCESS_DENIED; - break; - } - return result; -} - -/*********************************************************************** - * - * ftp_cwd() - * - * Send 'CWD' to the remote server to Change Working Directory. It is the ftp - * version of the unix 'cd' command. This function is only called from the - * ftp_cwd_and_mkd() function these days. - * - * This function does NOT call failf(). - */ -static -CURLcode ftp_cwd(struct connectdata *conn, char *path) -{ - ssize_t nread; - int ftpcode; - CURLcode result; - - FTPSENDF(conn, "CWD %s", path); - result = Curl_GetFTPResponse(&nread, conn, &ftpcode); - if (!result) { - /* According to RFC959, CWD is supposed to return 250 on success, but - there seem to be non-compliant FTP servers out there that return 200, - so we accept any '2xy' code here. */ - if (ftpcode/100 != 2) - result = CURLE_FTP_ACCESS_DENIED; - } - - return result; -} - -/*********************************************************************** - * - * ftp_cwd_and_mkd() - * - * Change to the given directory. If the directory is not present, and we - * have been told to allow it, then create the directory and cd to it. - * - */ -static CURLcode ftp_cwd_and_mkd(struct connectdata *conn, char *path) -{ - CURLcode result; - - result = ftp_cwd(conn, path); - if (result) { - if(conn->data->set.ftp_create_missing_dirs) { - result = ftp_mkd(conn, path); - if (result) - /* ftp_mkd() calls failf() itself */ - return result; - result = ftp_cwd(conn, path); - } - if(result) - failf(conn->data, "Couldn't cd to %s", path); - } - return result; -} - - - -/*********************************************************************** - * - * ftp_3rdparty_pretransfer() - * - * Preparation for 3rd party transfer. - * - */ -static CURLcode ftp_3rdparty_pretransfer(struct connectdata *conn) -{ - CURLcode result; - struct SessionHandle *data = conn->data; - struct connectdata *sec_conn = conn->sec_conn; - - /* sets transfer type */ - result = ftp_transfertype(conn, data->set.ftp_ascii); - if (result) - return result; - - result = ftp_transfertype(sec_conn, data->set.ftp_ascii); - if (result) - return result; - - /* Send any PREQUOTE strings after transfer type is set? */ - if (data->set.source_prequote) { - /* sends command(s) to source server before file transfer */ - result = ftp_sendquote(sec_conn, data->set.source_prequote); - } - if (!result && data->set.prequote) - result = ftp_sendquote(conn, data->set.prequote); - - return result; -} - - - -/*********************************************************************** - * - * ftp_3rdparty_transfer() - * - * Performs 3rd party transfer. - * - */ -static CURLcode ftp_3rdparty_transfer(struct connectdata *conn) -{ - CURLcode result; - ssize_t nread; - int ftpcode, ip[4], port[2]; - struct SessionHandle *data = conn->data; - struct connectdata *sec_conn = conn->sec_conn; - char *buf = data->state.buffer; /* this is our buffer */ - char *str = buf; - char pasv_port[50]; - const char *stor_cmd; - struct connectdata *pasv_conn; - struct connectdata *port_conn; - - if (data->set.pasvHost == CURL_TARGET_PASV) { - pasv_conn = conn; - port_conn = sec_conn; - } - else { - pasv_conn = sec_conn; - port_conn = conn; - } - - /* sets the passive mode */ - FTPSENDF(pasv_conn, "%s", "PASV"); - result = Curl_GetFTPResponse(&nread, pasv_conn, &ftpcode); - if (result) return result; - if (ftpcode != 227) { - failf(data, "Odd return code after PASV:%s", buf + 3); - return CURLE_FTP_WEIRD_PASV_REPLY; - } - - while (*str) { - if (6 == sscanf(str, "%d,%d,%d,%d,%d,%d", - &ip[0], &ip[1], &ip[2], &ip[3], &port[0], &port[1])) - break; - str++; - } - - if (!*str) { - failf(pasv_conn->data, "Couldn't interpret this 227-reply: %s", buf); - return CURLE_FTP_WEIRD_227_FORMAT; - } - - snprintf(pasv_port, sizeof(pasv_port), "%d,%d,%d,%d,%d,%d", ip[0], ip[1], - ip[2], ip[3], port[0], port[1]); - - /* sets data connection between remote hosts */ - FTPSENDF(port_conn, "PORT %s", pasv_port); - result = Curl_GetFTPResponse(&nread, port_conn, &ftpcode); - if (result) - return result; - - if (ftpcode != 200) { - failf(data, "PORT command attempts failed:%s", buf + 3); - return CURLE_FTP_PORT_FAILED; - } - - /* we might append onto the file instead of overwriting it */ - stor_cmd = data->set.ftp_append?"APPE":"STOR"; - - /* transfers file between remote hosts */ - FTPSENDF(sec_conn, "RETR %s", data->set.source_path); - - if(data->set.pasvHost == CURL_TARGET_PASV) { - - result = Curl_GetFTPResponse(&nread, sec_conn, &ftpcode); - if (result) - return result; - - if (ftpcode != 150) { - failf(data, "Failed RETR: %s", buf + 4); - return CURLE_FTP_COULDNT_RETR_FILE; - } - - result = Curl_ftpsendf(conn, "%s %s", stor_cmd, conn->path); - if(CURLE_OK == result) - result = Curl_GetFTPResponse(&nread, conn, &ftpcode); - if (result) - return result; - - if (ftpcode != 150) { - failf(data, "Failed FTP upload: %s", buf + 4); - return CURLE_FTP_COULDNT_STOR_FILE; - } - - } - else { - - result = Curl_ftpsendf(conn, "%s %s", stor_cmd, conn->path); - if(CURLE_OK == result) - result = Curl_GetFTPResponse(&nread, sec_conn, &ftpcode); - if (result) - return result; - - if (ftpcode != 150) { - failf(data, "Failed FTP upload: %s", buf + 4); - return CURLE_FTP_COULDNT_STOR_FILE; - } - - result = Curl_GetFTPResponse(&nread, conn, &ftpcode); - if (result) - return result; - - if (ftpcode != 150) { - failf(data, "Failed FTP upload: %s", buf + 4); - return CURLE_FTP_COULDNT_STOR_FILE; - } - } - - return CURLE_OK; -} - - - -/*********************************************************************** - * - * ftp_regular_transfer() - * - * The input argument is already checked for validity. - * Performs a regular transfer between local and remote hosts. - * - * ftp->ctl_valid starts out as FALSE, and gets set to TRUE if we reach the - * Curl_ftp_done() function without finding any major problem. - */ -static -CURLcode ftp_regular_transfer(struct connectdata *conn) -{ - CURLcode retcode=CURLE_OK; - bool connected=0; - struct SessionHandle *data = conn->data; - struct FTP *ftp; - - char *slash_pos; /* position of the first '/' char in curpos */ - char *cur_pos=conn->path; /* current position in ppath. point at the begin - of next path component */ - - /* the ftp struct is already inited in ftp_connect() */ - ftp = conn->proto.ftp; - ftp->ctl_valid = FALSE; - conn->size = -1; /* make sure this is unknown at this point */ - - Curl_pgrsSetUploadCounter(data, 0); - Curl_pgrsSetDownloadCounter(data, 0); - Curl_pgrsSetUploadSize(data, 0); - Curl_pgrsSetDownloadSize(data, 0); - - ftp->dirdepth = 0; - ftp->diralloc = 5; /* default dir depth to allocate */ - ftp->dirs = (char **)malloc(ftp->diralloc * sizeof(ftp->dirs[0])); - if(!ftp->dirs) - return CURLE_OUT_OF_MEMORY; - ftp->dirs[0] = NULL; /* to start with */ - - /* parse the URL path into separate path components */ - while((slash_pos=strchr(cur_pos, '/'))) { - /* 1 or 0 to indicate absolute directory */ - bool absolute_dir = (cur_pos - conn->path > 0) && (ftp->dirdepth == 0); - - /* seek out the next path component */ - if (slash_pos-cur_pos) { - /* we skip empty path components, like "x//y" since the FTP command CWD - requires a parameter and a non-existant parameter a) doesn't work on - many servers and b) has no effect on the others. */ - int len = (int)(slash_pos - cur_pos + absolute_dir); - ftp->dirs[ftp->dirdepth] = curl_unescape(cur_pos - absolute_dir, len); - - if (!ftp->dirs[ftp->dirdepth]) { /* run out of memory ... */ - failf(data, "no memory"); - freedirs(ftp); - return CURLE_OUT_OF_MEMORY; - } - } - else { - cur_pos = slash_pos + 1; /* jump to the rest of the string */ - continue; - } - - if(!retcode) { - cur_pos = slash_pos + 1; /* jump to the rest of the string */ - if(++ftp->dirdepth >= ftp->diralloc) { - /* enlarge array */ - char **bigger; - ftp->diralloc *= 2; /* double the size each time */ - bigger = realloc(ftp->dirs, ftp->diralloc * sizeof(ftp->dirs[0])); - if(!bigger) { - freedirs(ftp); - return CURLE_OUT_OF_MEMORY; - } - ftp->dirs = (char **)bigger; - } - } - } - - ftp->file = cur_pos; /* the rest is the file name */ - - if(*ftp->file) { - ftp->file = curl_unescape(ftp->file, 0); - if(NULL == ftp->file) { - freedirs(ftp); - failf(data, "no memory"); - return CURLE_OUT_OF_MEMORY; - } - } - else - ftp->file=NULL; /* instead of point to a zero byte, we make it a NULL - pointer */ - - retcode = ftp_perform(conn, &connected); - - if(CURLE_OK == retcode) { - if(connected) - retcode = Curl_ftp_nextconnect(conn); - - if(retcode && (conn->sock[SECONDARYSOCKET] != CURL_SOCKET_BAD)) { - /* Failure detected, close the second socket if it was created already */ - sclose(conn->sock[SECONDARYSOCKET]); - conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; - } - - if(ftp->no_transfer) - /* no data to transfer */ - retcode=Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL); - else if(!connected) - /* since we didn't connect now, we want do_more to get called */ - conn->bits.do_more = TRUE; - } - else - freedirs(ftp); - - ftp->ctl_valid = TRUE; /* seems good */ - - return retcode; -} - - - -/*********************************************************************** - * - * ftp_3rdparty() - * - * The input argument is already checked for validity. - * Performs a 3rd party transfer between two remote hosts. - */ -static CURLcode ftp_3rdparty(struct connectdata *conn) -{ - CURLcode retcode; - - conn->proto.ftp->ctl_valid = conn->sec_conn->proto.ftp->ctl_valid = TRUE; - conn->size = conn->sec_conn->size = -1; - - retcode = ftp_3rdparty_pretransfer(conn); - if (!retcode) - retcode = ftp_3rdparty_transfer(conn); - - return retcode; -} - -#endif /* CURL_DISABLE_FTP */ diff --git a/Source/CTest/Curl/ftp.h b/Source/CTest/Curl/ftp.h deleted file mode 100644 index dc7cf79..0000000 --- a/Source/CTest/Curl/ftp.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef __FTP_H -#define __FTP_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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$ - ***************************************************************************/ - -#ifndef CURL_DISABLE_FTP -CURLcode Curl_ftp(struct connectdata *conn); -CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode); -CURLcode Curl_ftp_connect(struct connectdata *conn); -CURLcode Curl_ftp_disconnect(struct connectdata *conn); -CURLcode Curl_ftpsendf(struct connectdata *, const char *fmt, ...); -CURLcode Curl_GetFTPResponse(ssize_t *nread, struct connectdata *conn, - int *ftpcode); -CURLcode Curl_ftp_nextconnect(struct connectdata *conn); -#endif - -#endif diff --git a/Source/CTest/Curl/getdate.c b/Source/CTest/Curl/getdate.c deleted file mode 100644 index 6aca48e..0000000 --- a/Source/CTest/Curl/getdate.c +++ /dev/null @@ -1,2471 +0,0 @@ -/* A Bison parser, made by GNU Bison 1.875a. */ - -/* Skeleton parser for Yacc-like parsing with Bison, - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* As a special exception, when this file is copied by Bison into a - Bison output file, you may use that output file without restriction. - This special exception was added by the Free Software Foundation - in version 1.24 of Bison. */ - -/* Written by Richard Stallman by simplifying the original so called - ``semantic'' parser. */ - -/* All symbols defined below should begin with yy or YY, to avoid - infringing on user name space. This should be done even for local - variables, as they might otherwise be expanded by user macros. - There are some unavoidable exceptions within include files to - define necessary library symbols; they are noted "INFRINGES ON - USER NAME SPACE" below. */ - -/* Identify Bison output. */ -#define YYBISON 1 - -/* Skeleton name. */ -#define YYSKELETON_NAME "yacc.c" - -/* Pure parsers. */ -#define YYPURE 1 - -/* Using locations. */ -#define YYLSP_NEEDED 0 - - - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - tAGO = 258, - tDAY = 259, - tDAY_UNIT = 260, - tDAYZONE = 261, - tDST = 262, - tHOUR_UNIT = 263, - tID = 264, - tMERIDIAN = 265, - tMINUTE_UNIT = 266, - tMONTH = 267, - tMONTH_UNIT = 268, - tSEC_UNIT = 269, - tSNUMBER = 270, - tUNUMBER = 271, - tYEAR_UNIT = 272, - tZONE = 273 - }; -#endif -#define tAGO 258 -#define tDAY 259 -#define tDAY_UNIT 260 -#define tDAYZONE 261 -#define tDST 262 -#define tHOUR_UNIT 263 -#define tID 264 -#define tMERIDIAN 265 -#define tMINUTE_UNIT 266 -#define tMONTH 267 -#define tMONTH_UNIT 268 -#define tSEC_UNIT 269 -#define tSNUMBER 270 -#define tUNUMBER 271 -#define tYEAR_UNIT 272 -#define tZONE 273 - - - - -/* Copy the first part of user declarations. */ -#line 1 "getdate.y" - -/* -** Originally written by Steven M. Bellovin <smb@research.att.com> while -** at the University of North Carolina at Chapel Hill. Later tweaked by -** a couple of people on Usenet. Completely overhauled by Rich $alz -** <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990. -** -** This code has been modified since it was included in curl, to make it -** thread-safe and to make compilers complain less about it. -** -** This code is in the public domain and has no copyright. -*/ - -#include "setup.h" - -# ifdef HAVE_ALLOCA_H -# include <alloca.h> -# endif - -# ifdef HAVE_TIME_H -# include <time.h> -# endif - -#ifndef YYDEBUG - /* to satisfy gcc -Wundef, we set this to 0 */ -#define YYDEBUG 0 -#endif - -#ifndef YYSTACK_USE_ALLOCA - /* to satisfy gcc -Wundef, we set this to 0 */ -#define YYSTACK_USE_ALLOCA 0 -#endif - -/* Since the code of getdate.y is not included in the Emacs executable - itself, there is no need to #define static in this file. Even if - the code were included in the Emacs executable, it probably - wouldn't do any harm to #undef it here; this will only cause - problems if we try to write to a static variable, which I don't - think this code needs to do. */ -#ifdef emacs -# undef static -#endif - -#ifdef __APPLE__ -#include <sys/types.h> -#include <sys/malloc.h> -#else - -#endif -#include <string.h> -#include <stdio.h> -#include <ctype.h> - -#if HAVE_STDLIB_H -# include <stdlib.h> /* for `free'; used by Bison 1.27 */ -#else - -#ifdef HAVE_MALLOC_H -#include <malloc.h> -#endif - -#endif - -#if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII)) -# define IN_CTYPE_DOMAIN(c) 1 -#else -# define IN_CTYPE_DOMAIN(c) isascii(c) -#endif - -#define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace (c)) -#define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha (c)) -#define ISUPPER(c) (IN_CTYPE_DOMAIN (c) && isupper (c)) -#define ISDIGIT_LOCALE(c) (IN_CTYPE_DOMAIN (c) && isdigit (c)) - -/* ISDIGIT differs from ISDIGIT_LOCALE, as follows: - - Its arg may be any int or unsigned int; it need not be an unsigned char. - - It's guaranteed to evaluate its argument exactly once. - - It's typically faster. - Posix 1003.2-1992 section 2.5.2.1 page 50 lines 1556-1558 says that - only '0' through '9' are digits. Prefer ISDIGIT to ISDIGIT_LOCALE unless - it's important to use the locale's definition of `digit' even when the - host does not conform to Posix. */ -#define ISDIGIT(c) ((unsigned) (c) - '0' <= 9) - -#if defined (STDC_HEADERS) || defined (USG) -# include <string.h> -#endif - -#include "curl_memory.h" -/* The last #include file should be: */ -#include "memdebug.h" - -#ifndef YYMAXDEPTH -#define YYMAXDEPTH 0 -#endif - -#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) -# define __attribute__(x) -#endif - -#ifndef ATTRIBUTE_UNUSED -# define ATTRIBUTE_UNUSED __attribute__ ((__unused__)) -#endif - -/* Some old versions of bison generate parsers that use bcopy. - That loses on systems that don't provide the function, so we have - to redefine it here. */ -#if !defined (HAVE_BCOPY) && defined (HAVE_MEMCPY) && !defined (bcopy) -# define bcopy(from, to, len) memcpy ((to), (from), (len)) -#endif - -/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc), - as well as gratuitiously global symbol names, so we can have multiple - yacc generated parsers in the same program. Note that these are only - the variables produced by yacc. If other parser generators (bison, - byacc, etc) produce additional global names that conflict at link time, - then those parser generators need to be fixed instead of adding those - names to this list. */ - -#define yymaxdepth Curl_gd_maxdepth -#define yyparse Curl_gd_parse -#define yylex Curl_gd_lex -#define yyerror Curl_gd_error -#define yylval Curl_gd_lval -#define yychar Curl_gd_char -#define yydebug Curl_gd_debug -#define yypact Curl_gd_pact -#define yyr1 Curl_gd_r1 -#define yyr2 Curl_gd_r2 -#define yydef Curl_gd_def -#define yychk Curl_gd_chk -#define yypgo Curl_gd_pgo -#define yyact Curl_gd_act -#define yyexca Curl_gd_exca -#define yyerrflag Curl_gd_errflag -#define yynerrs Curl_gd_nerrs -#define yyps Curl_gd_ps -#define yypv Curl_gd_pv -#define yys Curl_gd_s -#define yy_yys Curl_gd_yys -#define yystate Curl_gd_state -#define yytmp Curl_gd_tmp -#define yyv Curl_gd_v -#define yy_yyv Curl_gd_yyv -#define yyval Curl_gd_val -#define yylloc Curl_gd_lloc -#define yyreds Curl_gd_reds /* With YYDEBUG defined */ -#define yytoks Curl_gd_toks /* With YYDEBUG defined */ -#define yylhs Curl_gd_yylhs -#define yylen Curl_gd_yylen -#define yydefred Curl_gd_yydefred -#define yydgoto Curl_gd_yydgoto -#define yysindex Curl_gd_yysindex -#define yyrindex Curl_gd_yyrindex -#define yygindex Curl_gd_yygindex -#define yytable Curl_gd_yytable -#define yycheck Curl_gd_yycheck - -#define EPOCH 1970 -#define HOUR(x) ((x) * 60) - -#define MAX_BUFF_LEN 128 /* size of buffer to read the date into */ - -/* -** An entry in the lexical lookup table. -*/ -typedef struct _TABLE { - const char *name; - int type; - int value; -} TABLE; - - -/* -** Meridian: am, pm, or 24-hour style. -*/ -typedef enum _MERIDIAN { - MERam, MERpm, MER24 -} MERIDIAN; - -/* parse results and input string */ -typedef struct _CURL_CONTEXT { - const char *yyInput; - int yyDayOrdinal; - int yyDayNumber; - int yyHaveDate; - int yyHaveDay; - int yyHaveRel; - int yyHaveTime; - int yyHaveZone; - int yyTimezone; - int yyDay; - int yyHour; - int yyMinutes; - int yyMonth; - int yySeconds; - int yyYear; - MERIDIAN yyMeridian; - int yyRelDay; - int yyRelHour; - int yyRelMinutes; - int yyRelMonth; - int yyRelSeconds; - int yyRelYear; -} CURL_CONTEXT; - -/* enable use of extra argument to yyparse and yylex which can be used to pass -** in a user defined value (CURL_CONTEXT struct in our case) -*/ -#define YYPARSE_PARAM cookie -#define YYLEX_PARAM cookie -#define context ((CURL_CONTEXT *) cookie) - - -/* Enabling traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif - -/* Enabling verbose error messages. */ -#ifdef YYERROR_VERBOSE -# undef YYERROR_VERBOSE -# define YYERROR_VERBOSE 1 -#else -# define YYERROR_VERBOSE 0 -#endif - -#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) -#line 223 "getdate.y" -typedef union YYSTYPE { - int Number; - enum _MERIDIAN Meridian; -} YYSTYPE; -/* Line 191 of yacc.c. */ -#line 331 "y.tab.c" -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -# define YYSTYPE_IS_TRIVIAL 1 -#endif - - - -/* Copy the second part of user declarations. */ -#line 228 "getdate.y" - -static int yylex (YYSTYPE *yylval, void *cookie); -static int yyerror (const char *s); - - -/* Line 214 of yacc.c. */ -#line 347 "y.tab.c" - -#if ! defined (yyoverflow) || YYERROR_VERBOSE - -/* The parser invokes alloca or malloc; define the necessary symbols. */ - -# if YYSTACK_USE_ALLOCA -# define YYSTACK_ALLOC alloca -# else -# ifndef YYSTACK_USE_ALLOCA -# if defined (alloca) || defined (_ALLOCA_H) -# define YYSTACK_ALLOC alloca -# else -# ifdef __GNUC__ -# define YYSTACK_ALLOC __builtin_alloca -# endif -# endif -# endif -# endif - -# ifdef YYSTACK_ALLOC - /* Pacify GCC's `empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) -# else -# if defined (__STDC__) || defined (__cplusplus) -# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# endif -# define YYSTACK_ALLOC malloc -# define YYSTACK_FREE free -# endif -#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ - - -#if (! defined (yyoverflow) \ - && (! defined (__cplusplus) \ - || (YYSTYPE_IS_TRIVIAL))) - -/* A type that is properly aligned for any stack member. */ -union yyalloc -{ - short yyss; - YYSTYPE yyvs; - }; - -/* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) - -/* The size of an array large to enough to hold all stacks, each with - N elements. */ -# define YYSTACK_BYTES(N) \ - ((N) * (sizeof (short) + sizeof (YYSTYPE)) \ - + YYSTACK_GAP_MAXIMUM) - -/* Copy COUNT objects from FROM to TO. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if 1 < __GNUC__ -# define YYCOPY(To, From, Count) \ - __builtin_memcpy (To, From, (Count) * sizeof (*(From))) -# else -# define YYCOPY(To, From, Count) \ - do \ - { \ - register YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (To)[yyi] = (From)[yyi]; \ - } \ - while (0) -# endif -# endif - -/* Relocate STACK from its old location to the new one. The - local variables YYSIZE and YYSTACKSIZE give the old and new number of - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ -# define YYSTACK_RELOCATE(Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack, Stack, yysize); \ - Stack = &yyptr->Stack; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - (void)yyptr; \ - } \ - while (0) - -#endif - -#if defined (__STDC__) || defined (__cplusplus) - typedef signed char yysigned_char; -#else - typedef short yysigned_char; -#endif - -/* YYFINAL -- State number of the termination state. */ -#define YYFINAL 2 -/* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 50 - -/* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 22 -/* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 11 -/* YYNRULES -- Number of rules. */ -#define YYNRULES 51 -/* YYNRULES -- Number of states. */ -#define YYNSTATES 61 - -/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ -#define YYUNDEFTOK 2 -#define YYMAXUTOK 273 - -#define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) - -/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ -static const unsigned char yytranslate[] = -{ - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 20, 2, 2, 21, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 19, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18 -}; - -#if YYDEBUG -/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in - YYRHS. */ -static const unsigned char yyprhs[] = -{ - 0, 0, 3, 4, 7, 9, 11, 13, 15, 17, - 19, 22, 27, 32, 39, 46, 48, 50, 53, 55, - 58, 61, 65, 71, 75, 79, 82, 87, 90, 94, - 97, 99, 102, 105, 107, 110, 113, 115, 118, 121, - 123, 126, 129, 131, 134, 137, 139, 142, 145, 147, - 149, 150 -}; - -/* YYRHS -- A `-1'-separated list of the rules' RHS. */ -static const yysigned_char yyrhs[] = -{ - 23, 0, -1, -1, 23, 24, -1, 25, -1, 26, - -1, 28, -1, 27, -1, 29, -1, 31, -1, 16, - 10, -1, 16, 19, 16, 32, -1, 16, 19, 16, - 15, -1, 16, 19, 16, 19, 16, 32, -1, 16, - 19, 16, 19, 16, 15, -1, 18, -1, 6, -1, - 18, 7, -1, 4, -1, 4, 20, -1, 16, 4, - -1, 16, 21, 16, -1, 16, 21, 16, 21, 16, - -1, 16, 15, 15, -1, 16, 12, 15, -1, 12, - 16, -1, 12, 16, 20, 16, -1, 16, 12, -1, - 16, 12, 16, -1, 30, 3, -1, 30, -1, 16, - 17, -1, 15, 17, -1, 17, -1, 16, 13, -1, - 15, 13, -1, 13, -1, 16, 5, -1, 15, 5, - -1, 5, -1, 16, 8, -1, 15, 8, -1, 8, - -1, 16, 11, -1, 15, 11, -1, 11, -1, 16, - 14, -1, 15, 14, -1, 14, -1, 16, -1, -1, - 10, -1 -}; - -/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -static const unsigned short yyrline[] = -{ - 0, 244, 244, 245, 248, 251, 254, 257, 260, 263, - 266, 272, 278, 287, 293, 305, 308, 312, 317, 321, - 325, 331, 335, 353, 359, 365, 369, 374, 378, 385, - 393, 396, 399, 402, 405, 408, 411, 414, 417, 420, - 423, 426, 429, 432, 435, 438, 441, 444, 447, 452, - 487, 490 -}; -#endif - -#if YYDEBUG || YYERROR_VERBOSE -/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. - First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -static const char *const yytname[] = -{ - "$end", "error", "$undefined", "tAGO", "tDAY", "tDAY_UNIT", "tDAYZONE", - "tDST", "tHOUR_UNIT", "tID", "tMERIDIAN", "tMINUTE_UNIT", "tMONTH", - "tMONTH_UNIT", "tSEC_UNIT", "tSNUMBER", "tUNUMBER", "tYEAR_UNIT", - "tZONE", "':'", "','", "'/'", "$accept", "spec", "item", "time", "zone", - "day", "date", "rel", "relunit", "number", "o_merid", 0 -}; -#endif - -# ifdef YYPRINT -/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to - token YYLEX-NUM. */ -static const unsigned short yytoknum[] = -{ - 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272, 273, 58, - 44, 47 -}; -# endif - -/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const unsigned char yyr1[] = -{ - 0, 22, 23, 23, 24, 24, 24, 24, 24, 24, - 25, 25, 25, 25, 25, 26, 26, 26, 27, 27, - 27, 28, 28, 28, 28, 28, 28, 28, 28, 29, - 29, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 31, - 32, 32 -}; - -/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -static const unsigned char yyr2[] = -{ - 0, 2, 0, 2, 1, 1, 1, 1, 1, 1, - 2, 4, 4, 6, 6, 1, 1, 2, 1, 2, - 2, 3, 5, 3, 3, 2, 4, 2, 3, 2, - 1, 2, 2, 1, 2, 2, 1, 2, 2, 1, - 2, 2, 1, 2, 2, 1, 2, 2, 1, 1, - 0, 1 -}; - -/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state - STATE-NUM when YYTABLE doesn't specify something else to do. Zero - means the default is an error. */ -static const unsigned char yydefact[] = -{ - 2, 0, 1, 18, 39, 16, 42, 45, 0, 36, - 48, 0, 49, 33, 15, 3, 4, 5, 7, 6, - 8, 30, 9, 19, 25, 38, 41, 44, 35, 47, - 32, 20, 37, 40, 10, 43, 27, 34, 46, 0, - 31, 0, 0, 17, 29, 0, 24, 28, 23, 50, - 21, 26, 51, 12, 0, 11, 0, 50, 22, 14, - 13 -}; - -/* YYDEFGOTO[NTERM-NUM]. */ -static const yysigned_char yydefgoto[] = -{ - -1, 1, 15, 16, 17, 18, 19, 20, 21, 22, - 55 -}; - -/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ -#define YYPACT_NINF -20 -static const yysigned_char yypact[] = -{ - -20, 0, -20, -19, -20, -20, -20, -20, -13, -20, - -20, 30, 15, -20, 14, -20, -20, -20, -20, -20, - -20, 19, -20, -20, 4, -20, -20, -20, -20, -20, - -20, -20, -20, -20, -20, -20, -6, -20, -20, 16, - -20, 17, 23, -20, -20, 24, -20, -20, -20, 27, - 28, -20, -20, -20, 29, -20, 32, -8, -20, -20, - -20 -}; - -/* YYPGOTO[NTERM-NUM]. */ -static const yysigned_char yypgoto[] = -{ - -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, - -7 -}; - -/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule which - number is the opposite. If zero, do what YYDEFACT says. - If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -1 -static const unsigned char yytable[] = -{ - 2, 23, 52, 24, 3, 4, 5, 59, 6, 46, - 47, 7, 8, 9, 10, 11, 12, 13, 14, 31, - 32, 43, 44, 33, 45, 34, 35, 36, 37, 38, - 39, 48, 40, 49, 41, 25, 42, 52, 26, 50, - 51, 27, 53, 28, 29, 57, 54, 30, 58, 56, - 60 -}; - -static const unsigned char yycheck[] = -{ - 0, 20, 10, 16, 4, 5, 6, 15, 8, 15, - 16, 11, 12, 13, 14, 15, 16, 17, 18, 4, - 5, 7, 3, 8, 20, 10, 11, 12, 13, 14, - 15, 15, 17, 16, 19, 5, 21, 10, 8, 16, - 16, 11, 15, 13, 14, 16, 19, 17, 16, 21, - 57 -}; - -/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ -static const unsigned char yystos[] = -{ - 0, 23, 0, 4, 5, 6, 8, 11, 12, 13, - 14, 15, 16, 17, 18, 24, 25, 26, 27, 28, - 29, 30, 31, 20, 16, 5, 8, 11, 13, 14, - 17, 4, 5, 8, 10, 11, 12, 13, 14, 15, - 17, 19, 21, 7, 3, 20, 15, 16, 15, 16, - 16, 16, 10, 15, 19, 32, 21, 16, 16, 15, - 32 -}; - -#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) -# define YYSIZE_T __SIZE_TYPE__ -#endif -#if ! defined (YYSIZE_T) && defined (size_t) -# define YYSIZE_T size_t -#endif -#if ! defined (YYSIZE_T) -# if defined (__STDC__) || defined (__cplusplus) -# include <stddef.h> /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# endif -#endif -#if ! defined (YYSIZE_T) -# define YYSIZE_T unsigned int -#endif - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) -#define YYEOF 0 - -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrlab1 - - -/* Like YYERROR except do call yyerror. This remains here temporarily - to ease the transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. */ - -#define YYFAIL goto yyerrlab - -#define YYRECOVERING() (!!yyerrstatus) - -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY && yylen == 1) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - yytoken = YYTRANSLATE (yychar); \ - YYPOPSTACK; \ - goto yybackup; \ - } \ - else \ - { \ - yyerror ("syntax error: cannot back up");\ - YYERROR; \ - } \ -while (0) - -#define YYTERROR 1 -#define YYERRCODE 256 - -/* YYLLOC_DEFAULT -- Compute the default location (before the actions - are run). */ - -#ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - Current.first_line = Rhs[1].first_line; \ - Current.first_column = Rhs[1].first_column; \ - Current.last_line = Rhs[N].last_line; \ - Current.last_column = Rhs[N].last_column; -#endif - -/* YYLEX -- calling `yylex' with the right arguments. */ - -#ifdef YYLEX_PARAM -# define YYLEX yylex (&yylval, YYLEX_PARAM) -#else -# define YYLEX yylex (&yylval) -#endif - -/* Enable debugging if requested. */ -#if YYDEBUG - -# ifndef YYFPRINTF -# include <stdio.h> /* INFRINGES ON USER NAME SPACE */ -# define YYFPRINTF fprintf -# endif - -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (0) - -# define YYDSYMPRINT(Args) \ -do { \ - if (yydebug) \ - yysymprint Args; \ -} while (0) - -# define YYDSYMPRINTF(Title, Token, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yysymprint (stderr, \ - Token, Value); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (0) - -/*------------------------------------------------------------------. -| yy_stack_print -- Print the state stack from its BOTTOM up to its | -| TOP (cinluded). | -`------------------------------------------------------------------*/ - -#if defined (__STDC__) || defined (__cplusplus) -static void -yy_stack_print (short *bottom, short *top) -#else -static void -yy_stack_print (bottom, top) - short *bottom; - short *top; -#endif -{ - YYFPRINTF (stderr, "Stack now"); - for (/* Nothing. */; bottom <= top; ++bottom) - YYFPRINTF (stderr, " %d", *bottom); - YYFPRINTF (stderr, "\n"); -} - -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (0) - - -/*------------------------------------------------. -| Report that the YYRULE is going to be reduced. | -`------------------------------------------------*/ - -#if defined (__STDC__) || defined (__cplusplus) -static void -yy_reduce_print (int yyrule) -#else -static void -yy_reduce_print (yyrule) - int yyrule; -#endif -{ - int yyi; - unsigned int yylineno = yyrline[yyrule]; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ", - yyrule - 1, yylineno); - /* Print the symbols being reduced, and their result. */ - for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++) - YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]); - YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]); -} - -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (Rule); \ -} while (0) - -/* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -int yydebug; -#else /* !YYDEBUG */ -# define YYDPRINTF(Args) -# define YYDSYMPRINT(Args) -# define YYDSYMPRINTF(Title, Token, Value, Location) -# define YY_STACK_PRINT(Bottom, Top) -# define YY_REDUCE_PRINT(Rule) -#endif /* !YYDEBUG */ - - -/* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH -# define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only - if the built-in stack extension method is used). - - Do not make this value too large; the results are undefined if - SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH) - evaluated with infinite-precision integer arithmetic. */ - -#if YYMAXDEPTH == 0 -# undef YYMAXDEPTH -#endif - -#ifndef YYMAXDEPTH -# define YYMAXDEPTH 10000 -#endif - - - -#if YYERROR_VERBOSE - -# ifndef yystrlen -# if defined (__GLIBC__) && defined (_STRING_H) -# define yystrlen strlen -# else -/* Return the length of YYSTR. */ -static YYSIZE_T -# if defined (__STDC__) || defined (__cplusplus) -yystrlen (const char *yystr) -# else -yystrlen (yystr) - const char *yystr; -# endif -{ - register const char *yys = yystr; - - while (*yys++ != '\0') - continue; - - return yys - yystr - 1; -} -# endif -# endif - -# ifndef yystpcpy -# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) -# define yystpcpy stpcpy -# else -/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in - YYDEST. */ -static char * -# if defined (__STDC__) || defined (__cplusplus) -yystpcpy (char *yydest, const char *yysrc) -# else -yystpcpy (yydest, yysrc) - char *yydest; - const char *yysrc; -# endif -{ - register char *yyd = yydest; - register const char *yys = yysrc; - - while ((*yyd++ = *yys++) != '\0') - continue; - - return yyd - 1; -} -# endif -# endif - -#endif /* !YYERROR_VERBOSE */ - - - -#if YYDEBUG -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -#if defined (__STDC__) || defined (__cplusplus) -static void -yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep) -#else -static void -yysymprint (yyoutput, yytype, yyvaluep) - FILE *yyoutput; - int yytype; - YYSTYPE *yyvaluep; -#endif -{ - /* Pacify ``unused variable'' warnings. */ - (void) yyvaluep; - - if (yytype < YYNTOKENS) - { - YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); -# ifdef YYPRINT - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -# endif - } - else - YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); - - switch (yytype) - { - default: - break; - } - YYFPRINTF (yyoutput, ")"); -} - -#endif /* ! YYDEBUG */ -/*-----------------------------------------------. -| Release the memory associated to this symbol. | -`-----------------------------------------------*/ - -#if defined (__STDC__) || defined (__cplusplus) -static void -yydestruct (int yytype, YYSTYPE *yyvaluep) -#else -static void -yydestruct (yytype, yyvaluep) - int yytype; - YYSTYPE *yyvaluep; -#endif -{ - /* Pacify ``unused variable'' warnings. */ - (void) yyvaluep; - - switch (yytype) - { - - default: - break; - } -} - - -/* Prevent warnings from -Wmissing-prototypes. */ - -#ifdef YYPARSE_PARAM -# if defined (__STDC__) || defined (__cplusplus) -int yyparse (void *YYPARSE_PARAM); -# else -int yyparse (); -# endif -#else /* ! YYPARSE_PARAM */ -#if defined (__STDC__) || defined (__cplusplus) -int yyparse (void); -#else -int yyparse (); -#endif -#endif /* ! YYPARSE_PARAM */ - - - - - - -/*----------. -| yyparse. | -`----------*/ - -#ifdef YYPARSE_PARAM -# if defined (__STDC__) || defined (__cplusplus) -int yyparse (void *YYPARSE_PARAM) -# else -int yyparse (YYPARSE_PARAM) - void *YYPARSE_PARAM; -# endif -#else /* ! YYPARSE_PARAM */ -#if defined (__STDC__) || defined (__cplusplus) -int -yyparse (void) -#else -int -yyparse () - -#endif -#endif -{ - /* The lookahead symbol. */ -int yychar; - -/* The semantic value of the lookahead symbol. */ -YYSTYPE yylval; - -/* Number of syntax errors so far. */ -int yynerrs; - - register int yystate; - register int yyn; - int yyresult; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - /* Lookahead token as an internal (translated) token number. */ - int yytoken = 0; - - /* Three stacks and their tools: - `yyss': related to states, - `yyvs': related to semantic values, - `yyls': related to locations. - - Refer to the stacks thru separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - - /* The state stack. */ - short yyssa[YYINITDEPTH]; - short *yyss = yyssa; - register short *yyssp; - - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs = yyvsa; - register YYSTYPE *yyvsp; - - - -#define YYPOPSTACK (yyvsp--, yyssp--) - - YYSIZE_T yystacksize = YYINITDEPTH; - - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; - - - /* When reducing, the number of symbols on the RHS of the reduced - rule. */ - int yylen; - - YYDPRINTF ((stderr, "Starting parse\n")); - - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - - /* Initialize stack pointers. - Waste one element of value and location stack - so that they stay on the same level as the state stack. - The wasted elements are never initialized. */ - - yyssp = yyss; - yyvsp = yyvs; - - goto yysetstate; - -/*------------------------------------------------------------. -| yynewstate -- Push a new state, which is found in yystate. | -`------------------------------------------------------------*/ - yynewstate: - /* In all cases, when you get here, the value and location stacks - have just been pushed. so pushing a state here evens the stacks. - */ - yyssp++; - - yysetstate: - *yyssp = yystate; - - if (yyss + yystacksize - 1 <= yyssp) - { - /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = yyssp - yyss + 1; - -#ifdef yyoverflow - { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - YYSTYPE *yyvs1 = yyvs; - short *yyss1 = yyss; - - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow ("parser stack overflow", - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - - &yystacksize); - - yyss = yyss1; - yyvs = yyvs1; - } -#else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyoverflowlab; -# else - /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) - goto yyoverflowlab; - yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; - - { - short *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyoverflowlab; - YYSTACK_RELOCATE (yyss); - YYSTACK_RELOCATE (yyvs); - -# undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); - } -# endif -#endif /* no yyoverflow */ - - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1; - - - YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); - - if (yyss + yystacksize - 1 <= yyssp) - YYABORT; - } - - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); - - goto yybackup; - -/*-----------. -| yybackup. | -`-----------*/ -yybackup: - -/* Do appropriate processing given the current state. */ -/* Read a lookahead token if we need one and don't already have one. */ -/* yyresume: */ - - /* First try to decide what to do without reference to lookahead token. */ - - yyn = yypact[yystate]; - if (yyn == YYPACT_NINF) - goto yydefault; - - /* Not known => get a lookahead token if don't already have one. */ - - /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ - if (yychar == YYEMPTY) - { - YYDPRINTF ((stderr, "Reading a token: ")); - yychar = YYLEX; - } - - if (yychar <= YYEOF) - { - yychar = yytoken = YYEOF; - YYDPRINTF ((stderr, "Now at end of input.\n")); - } - else - { - yytoken = YYTRANSLATE (yychar); - YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc); - } - - /* If the proper action on seeing token YYTOKEN is to reduce or to - detect an error, take that action. */ - yyn += yytoken; - if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) - goto yydefault; - yyn = yytable[yyn]; - if (yyn <= 0) - { - if (yyn == 0 || yyn == YYTABLE_NINF) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - - if (yyn == YYFINAL) - YYACCEPT; - - /* Shift the lookahead token. */ - YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken])); - - /* Discard the token being shifted unless it is eof. */ - if (yychar != YYEOF) - yychar = YYEMPTY; - - *++yyvsp = yylval; - - - /* Count tokens shifted since error; after three, turn off error - status. */ - if (yyerrstatus) - yyerrstatus--; - - yystate = yyn; - goto yynewstate; - - -/*-----------------------------------------------------------. -| yydefault -- do the default action for the current state. | -`-----------------------------------------------------------*/ -yydefault: - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - goto yyreduce; - - -/*-----------------------------. -| yyreduce -- Do a reduction. | -`-----------------------------*/ -yyreduce: - /* yyn is the number of a rule to reduce with. */ - yylen = yyr2[yyn]; - - /* If YYLEN is nonzero, implement the default value of the action: - `$$ = $1'. - - Otherwise, the following line sets YYVAL to garbage. - This behavior is undocumented and Bison - users should not rely upon it. Assigning to YYVAL - unconditionally makes the parser a bit smaller, and it avoids a - GCC warning that YYVAL may be used uninitialized. */ - yyval = yyvsp[1-yylen]; - - - YY_REDUCE_PRINT (yyn); - switch (yyn) - { - case 4: -#line 248 "getdate.y" - { - context->yyHaveTime++; - } - break; - - case 5: -#line 251 "getdate.y" - { - context->yyHaveZone++; - } - break; - - case 6: -#line 254 "getdate.y" - { - context->yyHaveDate++; - } - break; - - case 7: -#line 257 "getdate.y" - { - context->yyHaveDay++; - } - break; - - case 8: -#line 260 "getdate.y" - { - context->yyHaveRel++; - } - break; - - case 10: -#line 266 "getdate.y" - { - context->yyHour = yyvsp[-1].Number; - context->yyMinutes = 0; - context->yySeconds = 0; - context->yyMeridian = yyvsp[0].Meridian; - } - break; - - case 11: -#line 272 "getdate.y" - { - context->yyHour = yyvsp[-3].Number; - context->yyMinutes = yyvsp[-1].Number; - context->yySeconds = 0; - context->yyMeridian = yyvsp[0].Meridian; - } - break; - - case 12: -#line 278 "getdate.y" - { - context->yyHour = yyvsp[-3].Number; - context->yyMinutes = yyvsp[-1].Number; - context->yyMeridian = MER24; - context->yyHaveZone++; - context->yyTimezone = (yyvsp[0].Number < 0 - ? -yyvsp[0].Number % 100 + (-yyvsp[0].Number / 100) * 60 - : - (yyvsp[0].Number % 100 + (yyvsp[0].Number / 100) * 60)); - } - break; - - case 13: -#line 287 "getdate.y" - { - context->yyHour = yyvsp[-5].Number; - context->yyMinutes = yyvsp[-3].Number; - context->yySeconds = yyvsp[-1].Number; - context->yyMeridian = yyvsp[0].Meridian; - } - break; - - case 14: -#line 293 "getdate.y" - { - context->yyHour = yyvsp[-5].Number; - context->yyMinutes = yyvsp[-3].Number; - context->yySeconds = yyvsp[-1].Number; - context->yyMeridian = MER24; - context->yyHaveZone++; - context->yyTimezone = (yyvsp[0].Number < 0 - ? -yyvsp[0].Number % 100 + (-yyvsp[0].Number / 100) * 60 - : - (yyvsp[0].Number % 100 + (yyvsp[0].Number / 100) * 60)); - } - break; - - case 15: -#line 305 "getdate.y" - { - context->yyTimezone = yyvsp[0].Number; - } - break; - - case 16: -#line 308 "getdate.y" - { - context->yyTimezone = yyvsp[0].Number - 60; - } - break; - - case 17: -#line 312 "getdate.y" - { - context->yyTimezone = yyvsp[-1].Number - 60; - } - break; - - case 18: -#line 317 "getdate.y" - { - context->yyDayOrdinal = 1; - context->yyDayNumber = yyvsp[0].Number; - } - break; - - case 19: -#line 321 "getdate.y" - { - context->yyDayOrdinal = 1; - context->yyDayNumber = yyvsp[-1].Number; - } - break; - - case 20: -#line 325 "getdate.y" - { - context->yyDayOrdinal = yyvsp[-1].Number; - context->yyDayNumber = yyvsp[0].Number; - } - break; - - case 21: -#line 331 "getdate.y" - { - context->yyMonth = yyvsp[-2].Number; - context->yyDay = yyvsp[0].Number; - } - break; - - case 22: -#line 335 "getdate.y" - { - /* Interpret as YYYY/MM/DD if $1 >= 1000, otherwise as MM/DD/YY. - The goal in recognizing YYYY/MM/DD is solely to support legacy - machine-generated dates like those in an RCS log listing. If - you want portability, use the ISO 8601 format. */ - if (yyvsp[-4].Number >= 1000) - { - context->yyYear = yyvsp[-4].Number; - context->yyMonth = yyvsp[-2].Number; - context->yyDay = yyvsp[0].Number; - } - else - { - context->yyMonth = yyvsp[-4].Number; - context->yyDay = yyvsp[-2].Number; - context->yyYear = yyvsp[0].Number; - } - } - break; - - case 23: -#line 353 "getdate.y" - { - /* ISO 8601 format. yyyy-mm-dd. */ - context->yyYear = yyvsp[-2].Number; - context->yyMonth = -yyvsp[-1].Number; - context->yyDay = -yyvsp[0].Number; - } - break; - - case 24: -#line 359 "getdate.y" - { - /* e.g. 17-JUN-1992. */ - context->yyDay = yyvsp[-2].Number; - context->yyMonth = yyvsp[-1].Number; - context->yyYear = -yyvsp[0].Number; - } - break; - - case 25: -#line 365 "getdate.y" - { - context->yyMonth = yyvsp[-1].Number; - context->yyDay = yyvsp[0].Number; - } - break; - - case 26: -#line 369 "getdate.y" - { - context->yyMonth = yyvsp[-3].Number; - context->yyDay = yyvsp[-2].Number; - context->yyYear = yyvsp[0].Number; - } - break; - - case 27: -#line 374 "getdate.y" - { - context->yyMonth = yyvsp[0].Number; - context->yyDay = yyvsp[-1].Number; - } - break; - - case 28: -#line 378 "getdate.y" - { - context->yyMonth = yyvsp[-1].Number; - context->yyDay = yyvsp[-2].Number; - context->yyYear = yyvsp[0].Number; - } - break; - - case 29: -#line 385 "getdate.y" - { - context->yyRelSeconds = -context->yyRelSeconds; - context->yyRelMinutes = -context->yyRelMinutes; - context->yyRelHour = -context->yyRelHour; - context->yyRelDay = -context->yyRelDay; - context->yyRelMonth = -context->yyRelMonth; - context->yyRelYear = -context->yyRelYear; - } - break; - - case 31: -#line 396 "getdate.y" - { - context->yyRelYear += yyvsp[-1].Number * yyvsp[0].Number; - } - break; - - case 32: -#line 399 "getdate.y" - { - context->yyRelYear += yyvsp[-1].Number * yyvsp[0].Number; - } - break; - - case 33: -#line 402 "getdate.y" - { - context->yyRelYear += yyvsp[0].Number; - } - break; - - case 34: -#line 405 "getdate.y" - { - context->yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number; - } - break; - - case 35: -#line 408 "getdate.y" - { - context->yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number; - } - break; - - case 36: -#line 411 "getdate.y" - { - context->yyRelMonth += yyvsp[0].Number; - } - break; - - case 37: -#line 414 "getdate.y" - { - context->yyRelDay += yyvsp[-1].Number * yyvsp[0].Number; - } - break; - - case 38: -#line 417 "getdate.y" - { - context->yyRelDay += yyvsp[-1].Number * yyvsp[0].Number; - } - break; - - case 39: -#line 420 "getdate.y" - { - context->yyRelDay += yyvsp[0].Number; - } - break; - - case 40: -#line 423 "getdate.y" - { - context->yyRelHour += yyvsp[-1].Number * yyvsp[0].Number; - } - break; - - case 41: -#line 426 "getdate.y" - { - context->yyRelHour += yyvsp[-1].Number * yyvsp[0].Number; - } - break; - - case 42: -#line 429 "getdate.y" - { - context->yyRelHour += yyvsp[0].Number; - } - break; - - case 43: -#line 432 "getdate.y" - { - context->yyRelMinutes += yyvsp[-1].Number * yyvsp[0].Number; - } - break; - - case 44: -#line 435 "getdate.y" - { - context->yyRelMinutes += yyvsp[-1].Number * yyvsp[0].Number; - } - break; - - case 45: -#line 438 "getdate.y" - { - context->yyRelMinutes += yyvsp[0].Number; - } - break; - - case 46: -#line 441 "getdate.y" - { - context->yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number; - } - break; - - case 47: -#line 444 "getdate.y" - { - context->yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number; - } - break; - - case 48: -#line 447 "getdate.y" - { - context->yyRelSeconds += yyvsp[0].Number; - } - break; - - case 49: -#line 453 "getdate.y" - { - if (context->yyHaveTime && context->yyHaveDate && - !context->yyHaveRel) - context->yyYear = yyvsp[0].Number; - else - { - if (yyvsp[0].Number>10000) - { - context->yyHaveDate++; - context->yyDay= (yyvsp[0].Number)%100; - context->yyMonth= (yyvsp[0].Number/100)%100; - context->yyYear = yyvsp[0].Number/10000; - } - else - { - context->yyHaveTime++; - if (yyvsp[0].Number < 100) - { - context->yyHour = yyvsp[0].Number; - context->yyMinutes = 0; - } - else - { - context->yyHour = yyvsp[0].Number / 100; - context->yyMinutes = yyvsp[0].Number % 100; - } - context->yySeconds = 0; - context->yyMeridian = MER24; - } - } - } - break; - - case 50: -#line 487 "getdate.y" - { - yyval.Meridian = MER24; - } - break; - - case 51: -#line 491 "getdate.y" - { - yyval.Meridian = yyvsp[0].Meridian; - } - break; - - - } - -/* Line 999 of yacc.c. */ -#line 1688 "y.tab.c" - - yyvsp -= yylen; - yyssp -= yylen; - - - YY_STACK_PRINT (yyss, yyssp); - - *++yyvsp = yyval; - - - /* Now `shift' the result of the reduction. Determine what state - that goes to, based on the state we popped back to and the rule - number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; - if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTOKENS]; - - goto yynewstate; - - -/*------------------------------------. -| yyerrlab -- here on detecting error | -`------------------------------------*/ -yyerrlab: - /* If not already recovering from an error, report this error. */ - if (!yyerrstatus) - { - ++yynerrs; -#if YYERROR_VERBOSE - yyn = yypact[yystate]; - - if (YYPACT_NINF < yyn && yyn < YYLAST) - { - YYSIZE_T yysize = 0; - int yytype = YYTRANSLATE (yychar); - char *yymsg; - int yyx, yycount; - - yycount = 0; - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. */ - for (yyx = yyn < 0 ? -yyn : 0; - yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) - yysize += yystrlen (yytname[yyx]) + 15, yycount++; - yysize += yystrlen ("syntax error, unexpected ") + 1; - yysize += yystrlen (yytname[yytype]); - yymsg = (char *) YYSTACK_ALLOC (yysize); - if (yymsg != 0) - { - char *yyp = yystpcpy (yymsg, "syntax error, unexpected "); - yyp = yystpcpy (yyp, yytname[yytype]); - - if (yycount < 5) - { - yycount = 0; - for (yyx = yyn < 0 ? -yyn : 0; - yyx < (int) (sizeof (yytname) / sizeof (char *)); - yyx++) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) - { - const char *yyq = ! yycount ? ", expecting " : " or "; - yyp = yystpcpy (yyp, yyq); - yyp = yystpcpy (yyp, yytname[yyx]); - yycount++; - } - } - yyerror (yymsg); - YYSTACK_FREE (yymsg); - } - else - yyerror ("syntax error; also virtual memory exhausted"); - } - else -#endif /* YYERROR_VERBOSE */ - yyerror ("syntax error"); - } - (void)yynerrs; - - - - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse lookahead token after an - error, discard it. */ - - /* Return failure if at end of input. */ - if (yychar == YYEOF) - { - /* Pop the error token. */ - YYPOPSTACK; - /* Pop the rest of the stack. */ - while (yyss < yyssp) - { - YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); - yydestruct (yystos[*yyssp], yyvsp); - YYPOPSTACK; - } - YYABORT; - } - - YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc); - yydestruct (yytoken, &yylval); - yychar = YYEMPTY; - - } - - /* Else will try to reuse lookahead token after shifting the error - token. */ - goto yyerrlab1; - - -/*----------------------------------------------------. -| yyerrlab1 -- error raised explicitly by an action. | -`----------------------------------------------------*/ -yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ - - for (;;) - { - yyn = yypact[yystate]; - if (yyn != YYPACT_NINF) - { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } - - /* Pop the current state because it cannot handle the error token. */ - if (yyssp == yyss) - YYABORT; - - YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); - yydestruct (yystos[yystate], yyvsp); - yyvsp--; - yystate = *--yyssp; - - YY_STACK_PRINT (yyss, yyssp); - } - - if (yyn == YYFINAL) - YYACCEPT; - - YYDPRINTF ((stderr, "Shifting error token, ")); - - *++yyvsp = yylval; - - - yystate = yyn; - goto yynewstate; - - -/*-------------------------------------. -| yyacceptlab -- YYACCEPT comes here. | -`-------------------------------------*/ -yyacceptlab: - yyresult = 0; - goto yyreturn; - -/*-----------------------------------. -| yyabortlab -- YYABORT comes here. | -`-----------------------------------*/ -yyabortlab: - yyresult = 1; - goto yyreturn; - -#ifndef yyoverflow -/*----------------------------------------------. -| yyoverflowlab -- parser overflow comes here. | -`----------------------------------------------*/ -yyoverflowlab: - yyerror ("parser stack overflow"); - yyresult = 2; - /* Fall through. */ -#endif - -yyreturn: -#ifndef yyoverflow - if (yyss != yyssa) - YYSTACK_FREE (yyss); -#endif - return yyresult; -} - - -#line 496 "getdate.y" - - -/* Include this file down here because bison inserts code above which - may define-away `const'. We want the prototype for get_date to have - the same signature as the function definition does. */ -#include "getdate.h" - -#ifndef WIN32 /* the windows dudes don't need these, does anyone really? */ -extern struct tm *gmtime (const time_t *); -extern struct tm *localtime (const time_t *); -extern time_t mktime (struct tm *); -#endif - -/* Month and day table. */ -static TABLE const MonthDayTable[] = { - { "january", tMONTH, 1 }, - { "february", tMONTH, 2 }, - { "march", tMONTH, 3 }, - { "april", tMONTH, 4 }, - { "may", tMONTH, 5 }, - { "june", tMONTH, 6 }, - { "july", tMONTH, 7 }, - { "august", tMONTH, 8 }, - { "september", tMONTH, 9 }, - { "sept", tMONTH, 9 }, - { "october", tMONTH, 10 }, - { "november", tMONTH, 11 }, - { "december", tMONTH, 12 }, - { "sunday", tDAY, 0 }, - { "monday", tDAY, 1 }, - { "tuesday", tDAY, 2 }, - { "tues", tDAY, 2 }, - { "wednesday", tDAY, 3 }, - { "wednes", tDAY, 3 }, - { "thursday", tDAY, 4 }, - { "thur", tDAY, 4 }, - { "thurs", tDAY, 4 }, - { "friday", tDAY, 5 }, - { "saturday", tDAY, 6 }, - { NULL, 0, 0 } -}; - -/* Time units table. */ -static TABLE const UnitsTable[] = { - { "year", tYEAR_UNIT, 1 }, - { "month", tMONTH_UNIT, 1 }, - { "fortnight", tDAY_UNIT, 14 }, - { "week", tDAY_UNIT, 7 }, - { "day", tDAY_UNIT, 1 }, - { "hour", tHOUR_UNIT, 1 }, - { "minute", tMINUTE_UNIT, 1 }, - { "min", tMINUTE_UNIT, 1 }, - { "second", tSEC_UNIT, 1 }, - { "sec", tSEC_UNIT, 1 }, - { NULL, 0, 0 } -}; - -/* Assorted relative-time words. */ -static TABLE const OtherTable[] = { - { "tomorrow", tMINUTE_UNIT, 1 * 24 * 60 }, - { "yesterday", tMINUTE_UNIT, -1 * 24 * 60 }, - { "today", tMINUTE_UNIT, 0 }, - { "now", tMINUTE_UNIT, 0 }, - { "last", tUNUMBER, -1 }, - { "this", tMINUTE_UNIT, 0 }, - { "next", tUNUMBER, 1 }, - { "first", tUNUMBER, 1 }, -/* { "second", tUNUMBER, 2 }, */ - { "third", tUNUMBER, 3 }, - { "fourth", tUNUMBER, 4 }, - { "fifth", tUNUMBER, 5 }, - { "sixth", tUNUMBER, 6 }, - { "seventh", tUNUMBER, 7 }, - { "eighth", tUNUMBER, 8 }, - { "ninth", tUNUMBER, 9 }, - { "tenth", tUNUMBER, 10 }, - { "eleventh", tUNUMBER, 11 }, - { "twelfth", tUNUMBER, 12 }, - { "ago", tAGO, 1 }, - { NULL, 0, 0 } -}; - -/* The timezone table. */ -static TABLE const TimezoneTable[] = { - { "gmt", tZONE, HOUR ( 0) }, /* Greenwich Mean */ - { "ut", tZONE, HOUR ( 0) }, /* Universal (Coordinated) */ - { "utc", tZONE, HOUR ( 0) }, - { "wet", tZONE, HOUR ( 0) }, /* Western European */ - { "bst", tDAYZONE, HOUR ( 0) }, /* British Summer */ - { "wat", tZONE, HOUR ( 1) }, /* West Africa */ - { "at", tZONE, HOUR ( 2) }, /* Azores */ -#if 0 - /* For completeness. BST is also British Summer, and GST is - * also Guam Standard. */ - { "bst", tZONE, HOUR ( 3) }, /* Brazil Standard */ - { "gst", tZONE, HOUR ( 3) }, /* Greenland Standard */ -#endif -#if 0 - { "nft", tZONE, HOUR (3.5) }, /* Newfoundland */ - { "nst", tZONE, HOUR (3.5) }, /* Newfoundland Standard */ - { "ndt", tDAYZONE, HOUR (3.5) }, /* Newfoundland Daylight */ -#endif - { "ast", tZONE, HOUR ( 4) }, /* Atlantic Standard */ - { "adt", tDAYZONE, HOUR ( 4) }, /* Atlantic Daylight */ - { "est", tZONE, HOUR ( 5) }, /* Eastern Standard */ - { "edt", tDAYZONE, HOUR ( 5) }, /* Eastern Daylight */ - { "cst", tZONE, HOUR ( 6) }, /* Central Standard */ - { "cdt", tDAYZONE, HOUR ( 6) }, /* Central Daylight */ - { "mst", tZONE, HOUR ( 7) }, /* Mountain Standard */ - { "mdt", tDAYZONE, HOUR ( 7) }, /* Mountain Daylight */ - { "pst", tZONE, HOUR ( 8) }, /* Pacific Standard */ - { "pdt", tDAYZONE, HOUR ( 8) }, /* Pacific Daylight */ - { "yst", tZONE, HOUR ( 9) }, /* Yukon Standard */ - { "ydt", tDAYZONE, HOUR ( 9) }, /* Yukon Daylight */ - { "hst", tZONE, HOUR (10) }, /* Hawaii Standard */ - { "hdt", tDAYZONE, HOUR (10) }, /* Hawaii Daylight */ - { "cat", tZONE, HOUR (10) }, /* Central Alaska */ - { "ahst", tZONE, HOUR (10) }, /* Alaska-Hawaii Standard */ - { "nt", tZONE, HOUR (11) }, /* Nome */ - { "idlw", tZONE, HOUR (12) }, /* International Date Line West */ - { "cet", tZONE, -HOUR (1) }, /* Central European */ - { "met", tZONE, -HOUR (1) }, /* Middle European */ - { "mewt", tZONE, -HOUR (1) }, /* Middle European Winter */ - { "mest", tDAYZONE, -HOUR (1) }, /* Middle European Summer */ - { "mesz", tDAYZONE, -HOUR (1) }, /* Middle European Summer */ - { "swt", tZONE, -HOUR (1) }, /* Swedish Winter */ - { "sst", tDAYZONE, -HOUR (1) }, /* Swedish Summer */ - { "fwt", tZONE, -HOUR (1) }, /* French Winter */ - { "fst", tDAYZONE, -HOUR (1) }, /* French Summer */ - { "eet", tZONE, -HOUR (2) }, /* Eastern Europe, USSR Zone 1 */ - { "bt", tZONE, -HOUR (3) }, /* Baghdad, USSR Zone 2 */ -#if 0 - { "it", tZONE, -HOUR (3.5) },/* Iran */ -#endif - { "zp4", tZONE, -HOUR (4) }, /* USSR Zone 3 */ - { "zp5", tZONE, -HOUR (5) }, /* USSR Zone 4 */ -#if 0 - { "ist", tZONE, -HOUR (5.5) },/* Indian Standard */ -#endif - { "zp6", tZONE, -HOUR (6) }, /* USSR Zone 5 */ -#if 0 - /* For completeness. NST is also Newfoundland Standard, and SST is - * also Swedish Summer. */ - { "nst", tZONE, -HOUR (6.5) },/* North Sumatra */ - { "sst", tZONE, -HOUR (7) }, /* South Sumatra, USSR Zone 6 */ -#endif /* 0 */ - { "wast", tZONE, -HOUR (7) }, /* West Australian Standard */ - { "wadt", tDAYZONE, -HOUR (7) }, /* West Australian Daylight */ -#if 0 - { "jt", tZONE, -HOUR (7.5) },/* Java (3pm in Cronusland!) */ -#endif - { "cct", tZONE, -HOUR (8) }, /* China Coast, USSR Zone 7 */ - { "jst", tZONE, -HOUR (9) }, /* Japan Standard, USSR Zone 8 */ -#if 0 - { "cast", tZONE, -HOUR (9.5) },/* Central Australian Standard */ - { "cadt", tDAYZONE, -HOUR (9.5) },/* Central Australian Daylight */ -#endif - { "east", tZONE, -HOUR (10) }, /* Eastern Australian Standard */ - { "eadt", tDAYZONE, -HOUR (10) }, /* Eastern Australian Daylight */ - { "gst", tZONE, -HOUR (10) }, /* Guam Standard, USSR Zone 9 */ - { "nzt", tZONE, -HOUR (12) }, /* New Zealand */ - { "nzst", tZONE, -HOUR (12) }, /* New Zealand Standard */ - { "nzdt", tDAYZONE, -HOUR (12) }, /* New Zealand Daylight */ - { "idle", tZONE, -HOUR (12) }, /* International Date Line East */ - { NULL, 0, 0 } -}; - -/* Military timezone table. */ -static TABLE const MilitaryTable[] = { - { "a", tZONE, HOUR ( 1) }, - { "b", tZONE, HOUR ( 2) }, - { "c", tZONE, HOUR ( 3) }, - { "d", tZONE, HOUR ( 4) }, - { "e", tZONE, HOUR ( 5) }, - { "f", tZONE, HOUR ( 6) }, - { "g", tZONE, HOUR ( 7) }, - { "h", tZONE, HOUR ( 8) }, - { "i", tZONE, HOUR ( 9) }, - { "k", tZONE, HOUR ( 10) }, - { "l", tZONE, HOUR ( 11) }, - { "m", tZONE, HOUR ( 12) }, - { "n", tZONE, HOUR (- 1) }, - { "o", tZONE, HOUR (- 2) }, - { "p", tZONE, HOUR (- 3) }, - { "q", tZONE, HOUR (- 4) }, - { "r", tZONE, HOUR (- 5) }, - { "s", tZONE, HOUR (- 6) }, - { "t", tZONE, HOUR (- 7) }, - { "u", tZONE, HOUR (- 8) }, - { "v", tZONE, HOUR (- 9) }, - { "w", tZONE, HOUR (-10) }, - { "x", tZONE, HOUR (-11) }, - { "y", tZONE, HOUR (-12) }, - { "z", tZONE, HOUR ( 0) }, - { NULL, 0, 0 } -}; - - - - -/* ARGSUSED */ -static int -yyerror (const char *s ATTRIBUTE_UNUSED) -{ - return 0; -} - -static int -ToHour (int Hours, MERIDIAN Meridian) -{ - switch (Meridian) - { - case MER24: - if (Hours < 0 || Hours > 23) - return -1; - return Hours; - case MERam: - if (Hours < 1 || Hours > 12) - return -1; - if (Hours == 12) - Hours = 0; - return Hours; - case MERpm: - if (Hours < 1 || Hours > 12) - return -1; - if (Hours == 12) - Hours = 0; - return Hours + 12; - default: - break; /* used to do abort() here */ - } - /* NOTREACHED - but make gcc happy! */ - return -1; -} - -static int -ToYear (int Year) -{ - if (Year < 0) - Year = -Year; - - /* XPG4 suggests that years 00-68 map to 2000-2068, and - years 69-99 map to 1969-1999. */ - if (Year < 69) - Year += 2000; - else if (Year < 100) - Year += 1900; - - return Year; -} - -static int -LookupWord (YYSTYPE *yylval, char *buff) -{ - char *p; - char *q; - const TABLE *tp; - size_t i; - int abbrev; - - /* Make it lowercase. */ - for (p = buff; *p; p++) - if (ISUPPER ((unsigned char) *p)) - *p = tolower ((int)*p); - - if (strcmp (buff, "am") == 0 || strcmp (buff, "a.m.") == 0) - { - yylval->Meridian = MERam; - return tMERIDIAN; - } - if (strcmp (buff, "pm") == 0 || strcmp (buff, "p.m.") == 0) - { - yylval->Meridian = MERpm; - return tMERIDIAN; - } - - /* See if we have an abbreviation for a month. */ - if (strlen (buff) == 3) - abbrev = 1; - else if (strlen (buff) == 4 && buff[3] == '.') - { - abbrev = 1; - buff[3] = '\0'; - } - else - abbrev = 0; - - for (tp = MonthDayTable; tp->name; tp++) - { - if (abbrev) - { - if (strncmp (buff, tp->name, 3) == 0) - { - yylval->Number = tp->value; - return tp->type; - } - } - else if (strcmp (buff, tp->name) == 0) - { - yylval->Number = tp->value; - return tp->type; - } - } - - for (tp = TimezoneTable; tp->name; tp++) - if (strcmp (buff, tp->name) == 0) - { - yylval->Number = tp->value; - return tp->type; - } - - if (strcmp (buff, "dst") == 0) - return tDST; - - for (tp = UnitsTable; tp->name; tp++) - if (strcmp (buff, tp->name) == 0) - { - yylval->Number = tp->value; - return tp->type; - } - - /* Strip off any plural and try the units table again. */ - i = strlen (buff) - 1; - if (buff[i] == 's') - { - buff[i] = '\0'; - for (tp = UnitsTable; tp->name; tp++) - if (strcmp (buff, tp->name) == 0) - { - yylval->Number = tp->value; - return tp->type; - } - buff[i] = 's'; /* Put back for "this" in OtherTable. */ - } - - for (tp = OtherTable; tp->name; tp++) - if (strcmp (buff, tp->name) == 0) - { - yylval->Number = tp->value; - return tp->type; - } - - /* Military timezones. */ - if (buff[1] == '\0' && ISALPHA ((unsigned char) *buff)) - { - for (tp = MilitaryTable; tp->name; tp++) - if (strcmp (buff, tp->name) == 0) - { - yylval->Number = tp->value; - return tp->type; - } - } - - /* Drop out any periods and try the timezone table again. */ - for (i = 0, p = q = buff; *q; q++) - if (*q != '.') - *p++ = *q; - else - i++; - *p = '\0'; - if (i) - for (tp = TimezoneTable; tp->name; tp++) - if (strcmp (buff, tp->name) == 0) - { - yylval->Number = tp->value; - return tp->type; - } - - return tID; -} - -static int -yylex (YYSTYPE *yylval, void *cookie) -{ - register unsigned char c; - register char *p; - char buff[20]; - int Count; - int sign; - - for (;;) - { - while (ISSPACE ((unsigned char) *context->yyInput)) - context->yyInput++; - - if (ISDIGIT (c = *context->yyInput) || c == '-' || c == '+') - { - if (c == '-' || c == '+') - { - sign = c == '-' ? -1 : 1; - if (!ISDIGIT (*++context->yyInput)) - /* skip the '-' sign */ - continue; - } - else - sign = 0; - for (yylval->Number = 0; ISDIGIT (c = *context->yyInput++);) - yylval->Number = 10 * yylval->Number + c - '0'; - context->yyInput--; - if (sign < 0) - yylval->Number = -yylval->Number; - return sign ? tSNUMBER : tUNUMBER; - } - if (ISALPHA (c)) - { - for (p = buff; (c = *context->yyInput++, ISALPHA (c)) || c == '.';) - if (p < &buff[sizeof buff - 1]) - *p++ = c; - *p = '\0'; - context->yyInput--; - return LookupWord (yylval, buff); - } - if (c != '(') - return *context->yyInput++; - Count = 0; - do - { - c = *context->yyInput++; - if (c == '\0') - return c; - if (c == '(') - Count++; - else if (c == ')') - Count--; - } - while (Count > 0); - } -} - -#define TM_YEAR_ORIGIN 1900 - -/* Yield A - B, measured in seconds. */ -static long -difftm (struct tm *a, struct tm *b) -{ - int ay = a->tm_year + (TM_YEAR_ORIGIN - 1); - int by = b->tm_year + (TM_YEAR_ORIGIN - 1); - long days = ( - /* difference in day of year */ - a->tm_yday - b->tm_yday - /* + intervening leap days */ - + ((ay >> 2) - (by >> 2)) - - (ay / 100 - by / 100) - + ((ay / 100 >> 2) - (by / 100 >> 2)) - /* + difference in years * 365 */ - + (long) (ay - by) * 365 - ); - return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour)) - + (a->tm_min - b->tm_min)) - + (a->tm_sec - b->tm_sec)); -} - -time_t -curl_getdate (const char *p, const time_t *now) -{ - struct tm tm, tm0, *tmp; - time_t Start; - CURL_CONTEXT cookie; -#ifdef HAVE_LOCALTIME_R - struct tm keeptime; -#endif - cookie.yyInput = p; - Start = now ? *now : time ((time_t *) NULL); -#ifdef HAVE_LOCALTIME_R - tmp = (struct tm *)localtime_r(&Start, &keeptime); -#else - tmp = localtime (&Start); -#endif - if (!tmp) - return -1; - cookie.yyYear = tmp->tm_year + TM_YEAR_ORIGIN; - cookie.yyMonth = tmp->tm_mon + 1; - cookie.yyDay = tmp->tm_mday; - cookie.yyHour = tmp->tm_hour; - cookie.yyMinutes = tmp->tm_min; - cookie.yySeconds = tmp->tm_sec; - tm.tm_isdst = tmp->tm_isdst; - cookie.yyMeridian = MER24; - cookie.yyRelSeconds = 0; - cookie.yyRelMinutes = 0; - cookie.yyRelHour = 0; - cookie.yyRelDay = 0; - cookie.yyRelMonth = 0; - cookie.yyRelYear = 0; - cookie.yyHaveDate = 0; - cookie.yyHaveDay = 0; - cookie.yyHaveRel = 0; - cookie.yyHaveTime = 0; - cookie.yyHaveZone = 0; - - if (yyparse ((void*)&cookie) - || cookie.yyHaveTime > 1 || cookie.yyHaveZone > 1 || - cookie.yyHaveDate > 1 || cookie.yyHaveDay > 1) - return -1; - - tm.tm_year = ToYear (cookie.yyYear) - TM_YEAR_ORIGIN + cookie.yyRelYear; - tm.tm_mon = cookie.yyMonth - 1 + cookie.yyRelMonth; - tm.tm_mday = cookie.yyDay + cookie.yyRelDay; - if (cookie.yyHaveTime || - (cookie.yyHaveRel && !cookie.yyHaveDate && !cookie.yyHaveDay)) - { - tm.tm_hour = ToHour (cookie.yyHour, cookie.yyMeridian); - if (tm.tm_hour < 0) - return -1; - tm.tm_min = cookie.yyMinutes; - tm.tm_sec = cookie.yySeconds; - } - else - { - tm.tm_hour = tm.tm_min = tm.tm_sec = 0; - } - tm.tm_hour += cookie.yyRelHour; - tm.tm_min += cookie.yyRelMinutes; - tm.tm_sec += cookie.yyRelSeconds; - - /* Let mktime deduce tm_isdst if we have an absolute timestamp, - or if the relative timestamp mentions days, months, or years. */ - if (cookie.yyHaveDate | cookie.yyHaveDay | cookie.yyHaveTime | - cookie.yyRelDay | cookie.yyRelMonth | cookie.yyRelYear) - tm.tm_isdst = -1; - - tm0 = tm; - - Start = mktime (&tm); - - if (Start == (time_t) -1) - { - - /* Guard against falsely reporting errors near the time_t boundaries - when parsing times in other time zones. For example, if the min - time_t value is 1970-01-01 00:00:00 UTC and we are 8 hours ahead - of UTC, then the min localtime value is 1970-01-01 08:00:00; if - we apply mktime to 1970-01-01 00:00:00 we will get an error, so - we apply mktime to 1970-01-02 08:00:00 instead and adjust the time - zone by 24 hours to compensate. This algorithm assumes that - there is no DST transition within a day of the time_t boundaries. */ - if (cookie.yyHaveZone) - { - tm = tm0; - if (tm.tm_year <= EPOCH - TM_YEAR_ORIGIN) - { - tm.tm_mday++; - cookie.yyTimezone -= 24 * 60; - } - else - { - tm.tm_mday--; - cookie.yyTimezone += 24 * 60; - } - Start = mktime (&tm); - } - - if (Start == (time_t) -1) - return Start; - } - - if (cookie.yyHaveDay && !cookie.yyHaveDate) - { - tm.tm_mday += ((cookie.yyDayNumber - tm.tm_wday + 7) % 7 - + 7 * (cookie.yyDayOrdinal - (0 < cookie.yyDayOrdinal))); - Start = mktime (&tm); - if (Start == (time_t) -1) - return Start; - } - - if (cookie.yyHaveZone) - { - long delta; - struct tm *gmt; -#ifdef HAVE_GMTIME_R - /* thread-safe version */ - struct tm keeptime2; - gmt = (struct tm *)gmtime_r(&Start, &keeptime2); -#else - gmt = gmtime(&Start); -#endif - if (!gmt) - return -1; - delta = cookie.yyTimezone * 60L + difftm (&tm, gmt); - if ((Start + delta < Start) != (delta < 0)) - return -1; /* time_t overflow */ - Start += delta; - } - - return Start; -} - - diff --git a/Source/CTest/Curl/getdate.h b/Source/CTest/Curl/getdate.h deleted file mode 100644 index 85650e3..0000000 --- a/Source/CTest/Curl/getdate.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -** Originally written by Steven M. Bellovin <smb@research.att.com> while -** at the University of North Carolina at Chapel Hill. Later tweaked by -** a couple of people on Usenet. Completely overhauled by Rich $alz -** <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990. -** -** This code is in the public domain and has no copyright. -*/ - -# include "setup.h" - -#ifndef PARAMS -# if defined PROTOTYPES || (defined __STDC__ && __STDC__) -# define PARAMS(Args) Args -# else -# define PARAMS(Args) () -# endif -#endif - -#ifdef vms -# include <types.h> -# include <time.h> -#else -# include <sys/types.h> -# if TIME_WITH_SYS_TIME -# include <sys/time.h> -# include <time.h> -# else -# if HAVE_SYS_TIME_H -# include <sys/time.h> -# else -# include <time.h> -# endif -# endif -#endif /* defined (vms) */ - -time_t curl_getdate PARAMS ((const char *p, const time_t *now)); diff --git a/Source/CTest/Curl/getenv.c b/Source/CTest/Curl/getenv.c deleted file mode 100644 index 302db2e..0000000 --- a/Source/CTest/Curl/getenv.c +++ /dev/null @@ -1,70 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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 <stdio.h> -#include <stdlib.h> -#include <string.h> - -#ifdef WIN32 -#include <windows.h> -#endif - -#ifdef VMS -#include <unixlib.h> -#endif - -#include <curl/curl.h> -#include "curl_memory.h" - -#include "memdebug.h" - -static -char *GetEnv(const char *variable) -{ -#ifdef WIN32 - /* This shit requires windows.h (HUGE) to be included */ - char env[MAX_PATH]; /* MAX_PATH is from windef.h */ - char *temp = getenv(variable); - env[0] = '\0'; - if (temp != NULL) - ExpandEnvironmentStrings(temp, env, sizeof(env)); -#else -#ifdef VMS - char *env = getenv(variable); - if (env && strcmp("HOME",variable) == 0) { - env = decc$translate_vms(env); - } -#else - /* no length control */ - char *env = getenv(variable); -#endif -#endif - return (env && env[0])?strdup(env):NULL; -} - -char *curl_getenv(const char *v) -{ - return GetEnv(v); -} diff --git a/Source/CTest/Curl/getinfo.c b/Source/CTest/Curl/getinfo.c deleted file mode 100644 index 7316d3a..0000000 --- a/Source/CTest/Curl/getinfo.c +++ /dev/null @@ -1,174 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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 <curl/curl.h> - -#include "urldata.h" -#include "getinfo.h" - -#include <stdio.h> -#include <string.h> -#include <stdarg.h> -#include <stdlib.h> -#include "curl_memory.h" - -/* Make this the last #include */ -#include "memdebug.h" - -/* - * This is supposed to be called in the beginning of a permform() session - * and should reset all session-info variables - */ -CURLcode Curl_initinfo(struct SessionHandle *data) -{ - struct Progress *pro = &data->progress; - struct PureInfo *info =&data->info; - - pro->t_nslookup = 0; - pro->t_connect = 0; - pro->t_pretransfer = 0; - pro->t_starttransfer = 0; - pro->timespent = 0; - pro->t_redirect = 0; - - info->httpcode = 0; - info->httpversion=0; - info->filetime=-1; /* -1 is an illegal time and thus means unknown */ - - if (info->contenttype) - free(info->contenttype); - info->contenttype = NULL; - - info->header_size = 0; - info->request_size = 0; - return CURLE_OK; -} - -CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...) -{ - va_list arg; - long *param_longp=NULL; - double *param_doublep=NULL; - char **param_charp=NULL; - va_start(arg, info); - - switch(info&CURLINFO_TYPEMASK) { - default: - return CURLE_BAD_FUNCTION_ARGUMENT; - case CURLINFO_STRING: - param_charp = va_arg(arg, char **); - if(NULL == param_charp) - return CURLE_BAD_FUNCTION_ARGUMENT; - break; - case CURLINFO_LONG: - param_longp = va_arg(arg, long *); - if(NULL == param_longp) - return CURLE_BAD_FUNCTION_ARGUMENT; - break; - case CURLINFO_DOUBLE: - param_doublep = va_arg(arg, double *); - if(NULL == param_doublep) - return CURLE_BAD_FUNCTION_ARGUMENT; - break; - } - - switch(info) { - case CURLINFO_EFFECTIVE_URL: - *param_charp = data->change.url?data->change.url:(char *)""; - break; - case CURLINFO_RESPONSE_CODE: - *param_longp = data->info.httpcode; - break; - case CURLINFO_HTTP_CONNECTCODE: - *param_longp = data->info.httpproxycode; - break; - case CURLINFO_FILETIME: - *param_longp = data->info.filetime; - break; - case CURLINFO_HEADER_SIZE: - *param_longp = data->info.header_size; - break; - case CURLINFO_REQUEST_SIZE: - *param_longp = data->info.request_size; - break; - case CURLINFO_TOTAL_TIME: - *param_doublep = data->progress.timespent; - break; - case CURLINFO_NAMELOOKUP_TIME: - *param_doublep = data->progress.t_nslookup; - break; - case CURLINFO_CONNECT_TIME: - *param_doublep = data->progress.t_connect; - break; - case CURLINFO_PRETRANSFER_TIME: - *param_doublep = data->progress.t_pretransfer; - break; - case CURLINFO_STARTTRANSFER_TIME: - *param_doublep = data->progress.t_starttransfer; - break; - case CURLINFO_SIZE_UPLOAD: - *param_doublep = (double)data->progress.uploaded; - break; - case CURLINFO_SIZE_DOWNLOAD: - *param_doublep = (double)data->progress.downloaded; - break; - case CURLINFO_SPEED_DOWNLOAD: - *param_doublep = (double)data->progress.dlspeed; - break; - case CURLINFO_SPEED_UPLOAD: - *param_doublep = (double)data->progress.ulspeed; - break; - case CURLINFO_SSL_VERIFYRESULT: - *param_longp = data->set.ssl.certverifyresult; - break; - case CURLINFO_CONTENT_LENGTH_DOWNLOAD: - *param_doublep = (double)data->progress.size_dl; - break; - case CURLINFO_CONTENT_LENGTH_UPLOAD: - *param_doublep = (double)data->progress.size_ul; - break; - case CURLINFO_REDIRECT_TIME: - *param_doublep = data->progress.t_redirect; - break; - case CURLINFO_REDIRECT_COUNT: - *param_longp = data->set.followlocation; - break; - case CURLINFO_CONTENT_TYPE: - *param_charp = data->info.contenttype; - break; - case CURLINFO_PRIVATE: - *param_charp = data->set.private; - break; - case CURLINFO_HTTPAUTH_AVAIL: - *param_longp = data->info.httpauthavail; - break; - case CURLINFO_PROXYAUTH_AVAIL: - *param_longp = data->info.proxyauthavail; - break; - default: - return CURLE_BAD_FUNCTION_ARGUMENT; - } - return CURLE_OK; -} diff --git a/Source/CTest/Curl/getinfo.h b/Source/CTest/Curl/getinfo.h deleted file mode 100644 index 2fe1b5c..0000000 --- a/Source/CTest/Curl/getinfo.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef __GETINFO_H -#define __GETINFO_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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_getinfo(struct SessionHandle *data, CURLINFO info, ...); -CURLcode Curl_initinfo(struct SessionHandle *data); - -#endif diff --git a/Source/CTest/Curl/hash.c b/Source/CTest/Curl/hash.c deleted file mode 100644 index 614d692..0000000 --- a/Source/CTest/Curl/hash.c +++ /dev/null @@ -1,267 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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 <string.h> -#include <stdlib.h> - -#include "hash.h" -#include "llist.h" -#include "curl_memory.h" - -/* this must be the last include file */ -#include "memdebug.h" - -static unsigned long -hash_str(const char *key, size_t key_length) -{ - char *end = (char *) key + key_length; - unsigned long h = 5381; - - while (key < end) { - h += h << 5; - h ^= (unsigned long) *key++; - } - - return h; -} - -static void -hash_element_dtor(void *user, void *element) -{ - curl_hash *h = (curl_hash *) user; - curl_hash_element *e = (curl_hash_element *) element; - - if (e->key) { - free(e->key); - } - - h->dtor(e->ptr); - - free(e); -} - -/* return 1 on error, 0 is fine */ -int -Curl_hash_init(curl_hash *h, int slots, curl_hash_dtor dtor) -{ - int i; - - h->dtor = dtor; - h->size = 0; - h->slots = slots; - - h->table = (curl_llist **) malloc(slots * sizeof(curl_llist *)); - if(h->table) { - for (i = 0; i < slots; ++i) { - h->table[i] = Curl_llist_alloc((curl_llist_dtor) hash_element_dtor); - if(!h->table[i]) { - while(i--) - Curl_llist_destroy(h->table[i], NULL); - free(h->table); - return 1; /* failure */ - } - } - return 0; /* fine */ - } - else - return 1; /* failure */ -} - -curl_hash * -Curl_hash_alloc(int slots, curl_hash_dtor dtor) -{ - curl_hash *h; - - h = (curl_hash *) malloc(sizeof(curl_hash)); - if (h) { - if(Curl_hash_init(h, slots, dtor)) { - /* failure */ - free(h); - h = NULL; - } - } - - return h; -} - -static int -hash_key_compare(char *key1, size_t key1_len, char *key2, size_t key2_len) -{ - if (key1_len == key2_len && - *key1 == *key2 && - memcmp(key1, key2, key1_len) == 0) { - return 1; - } - - return 0; -} - -static curl_hash_element * -mk_hash_element(char *key, size_t key_len, const void *p) -{ - curl_hash_element *he = - (curl_hash_element *) malloc(sizeof(curl_hash_element)); - - if(he) { - char *dup = strdup(key); - if(dup) { - he->key = dup; - he->key_len = key_len; - he->ptr = (void *) p; - } - else { - /* failed to duplicate the key, free memory and fail */ - free(he); - he = NULL; - } - } - return he; -} - -#define find_slot(__h, __k, __k_len) (hash_str(__k, __k_len) % (__h)->slots) - -#define FETCH_LIST(x,y,z) x->table[find_slot(x, y, z)] - -/* Return the data in the hash. If there already was a match in the hash, - that data is returned. */ -void * -Curl_hash_add(curl_hash *h, char *key, size_t key_len, void *p) -{ - curl_hash_element *he; - curl_llist_element *le; - curl_llist *l = FETCH_LIST(h, key, key_len); - - for (le = l->head; le; le = le->next) { - he = (curl_hash_element *) le->ptr; - if (hash_key_compare(he->key, he->key_len, key, key_len)) { - h->dtor(p); /* remove the NEW entry */ - return he->ptr; /* return the EXISTING entry */ - } - } - - he = mk_hash_element(key, key_len, p); - if (he) { - if(Curl_llist_insert_next(l, l->tail, he)) { - ++h->size; - return p; /* return the new entry */ - } - /* - * Couldn't insert it, destroy the 'he' element and the key again. We - * don't call hash_element_dtor() since that would also call the - * "destructor" for the actual data 'p'. When we fail, we shall not touch - * that data. - */ - free(he->key); - free(he); - } - - return NULL; /* failure */ -} - -void * -Curl_hash_pick(curl_hash *h, char *key, size_t key_len) -{ - curl_llist_element *le; - curl_hash_element *he; - curl_llist *l = FETCH_LIST(h, key, key_len); - - for (le = l->head; - le; - le = le->next) { - he = le->ptr; - if (hash_key_compare(he->key, he->key_len, key, key_len)) { - return he->ptr; - } - } - - return NULL; -} - -#if defined(CURLDEBUG) && defined(AGGRESIVE_TEST) -void -Curl_hash_apply(curl_hash *h, void *user, - void (*cb)(void *user, void *ptr)) -{ - curl_llist_element *le; - int i; - - for (i = 0; i < h->slots; ++i) { - for (le = (h->table[i])->head; - le; - le = le->next) { - curl_hash_element *el = le->ptr; - cb(user, el->ptr); - } - } -} -#endif - -void -Curl_hash_clean(curl_hash *h) -{ - int i; - - for (i = 0; i < h->slots; ++i) { - Curl_llist_destroy(h->table[i], (void *) h); - } - - free(h->table); -} - -void -Curl_hash_clean_with_criterium(curl_hash *h, void *user, - int (*comp)(void *, void *)) -{ - curl_llist_element *le; - curl_llist_element *lnext; - curl_llist *list; - int i; - - for (i = 0; i < h->slots; ++i) { - list = h->table[i]; - le = list->head; /* get first list entry */ - while(le) { - curl_hash_element *he = le->ptr; - lnext = le->next; - /* ask the callback function if we shall remove this entry or not */ - if (comp(user, he->ptr)) { - Curl_llist_remove(list, le, (void *) h); - --h->size; /* one less entry in the hash now */ - } - le = lnext; - } - } -} - -void -Curl_hash_destroy(curl_hash *h) -{ - if (!h) - return; - - Curl_hash_clean(h); - free(h); -} - diff --git a/Source/CTest/Curl/hash.h b/Source/CTest/Curl/hash.h deleted file mode 100644 index 7814674..0000000 --- a/Source/CTest/Curl/hash.h +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef __HASH_H -#define __HASH_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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 <stddef.h> - -#include "llist.h" - -typedef void (*curl_hash_dtor)(void *); - -typedef struct _curl_hash { - curl_llist **table; - curl_hash_dtor dtor; - int slots; - size_t size; -} curl_hash; - -typedef struct _curl_hash_element { - void *ptr; - char *key; - size_t key_len; -} curl_hash_element; - - -int Curl_hash_init(curl_hash *, int, curl_hash_dtor); -curl_hash *Curl_hash_alloc(int, curl_hash_dtor); -void *Curl_hash_add(curl_hash *, char *, size_t, void *); -int Curl_hash_delete(curl_hash *h, char *key, size_t key_len); -void *Curl_hash_pick(curl_hash *, char *, size_t); -void Curl_hash_apply(curl_hash *h, void *user, - void (*cb)(void *user, void *ptr)); -int Curl_hash_count(curl_hash *h); -void Curl_hash_clean(curl_hash *h); -void Curl_hash_clean_with_criterium(curl_hash *h, void *user, int (*comp)(void *, void *)); -void Curl_hash_destroy(curl_hash *h); - -#endif diff --git a/Source/CTest/Curl/hostares.c b/Source/CTest/Curl/hostares.c deleted file mode 100644 index 197f540..0000000 --- a/Source/CTest/Curl/hostares.c +++ /dev/null @@ -1,301 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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 <string.h> -#include <errno.h> - -#define _REENTRANT - -#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__) -#include <malloc.h> -#else -#ifdef HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif -#ifdef HAVE_SYS_SOCKET_H -#include <sys/socket.h> -#endif -#ifdef HAVE_NETINET_IN_H -#include <netinet/in.h> -#endif -#ifdef HAVE_NETDB_H -#include <netdb.h> -#endif -#ifdef HAVE_ARPA_INET_H -#include <arpa/inet.h> -#endif -#ifdef HAVE_STDLIB_H -#include <stdlib.h> /* required for free() prototypes */ -#endif -#ifdef HAVE_UNISTD_H -#include <unistd.h> /* for the close() proto */ -#endif -#ifdef VMS -#include <in.h> -#include <inet.h> -#include <stdlib.h> -#endif -#endif - -#ifdef HAVE_SETJMP_H -#include <setjmp.h> -#endif - -#ifdef WIN32 -#include <process.h> -#endif - -#if (defined(NETWARE) && defined(__NOVELL_LIBC__)) -#undef in_addr_t -#define in_addr_t unsigned long -#endif - -#include "urldata.h" -#include "sendf.h" -#include "hostip.h" -#include "hash.h" -#include "share.h" -#include "strerror.h" -#include "url.h" - -#define _MPRINTF_REPLACE /* use our functions only */ -#include <curl/mprintf.h> - -#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL) -#include "inet_ntoa_r.h" -#endif - -#include "curl_memory.h" - -/* The last #include file should be: */ -#include "memdebug.h" - -/*********************************************************************** - * Only for ares-enabled builds - **********************************************************************/ - -#ifdef CURLRES_ARES - -/* - * Curl_fdset() is called when someone from the outside world (using - * curl_multi_fdset()) wants to get our fd_set setup and we're talking with - * ares. The caller must make sure that this function is only called when we - * have a working ares channel. - * - * Returns: CURLE_OK always! - */ - -CURLcode Curl_fdset(struct connectdata *conn, - fd_set *read_fd_set, - fd_set *write_fd_set, - int *max_fdp) - -{ - int max = ares_fds(conn->data->state.areschannel, - read_fd_set, write_fd_set); - *max_fdp = max; - - return CURLE_OK; -} - -/* - * Curl_is_resolved() is called repeatedly to check if a previous name resolve - * request has completed. It should also make sure to time-out if the - * operation seems to take too long. - * - * Returns normal CURLcode errors. - */ -CURLcode Curl_is_resolved(struct connectdata *conn, - struct Curl_dns_entry **dns) -{ - fd_set read_fds, write_fds; - struct timeval tv={0,0}; - struct SessionHandle *data = conn->data; - int nfds; - - FD_ZERO(&read_fds); - FD_ZERO(&write_fds); - - nfds = ares_fds(data->state.areschannel, &read_fds, &write_fds); - - (void)select(nfds, &read_fds, &write_fds, NULL, - (struct timeval *)&tv); - - /* Call ares_process() unconditonally here, even if we simply timed out - above, as otherwise the ares name resolve won't timeout! */ - ares_process(data->state.areschannel, &read_fds, &write_fds); - - *dns = NULL; - - if(conn->async.done) { - /* we're done, kill the ares handle */ - if(!conn->async.dns) { - failf(data, "Could not resolve host: %s (%s)", conn->host.dispname, - ares_strerror(conn->async.status)); - return CURLE_COULDNT_RESOLVE_HOST; - } - *dns = conn->async.dns; - } - - return CURLE_OK; -} - -/* - * Curl_wait_for_resolv() waits for a resolve to finish. This function should - * be avoided since using this risk getting the multi interface to "hang". - * - * If 'entry' is non-NULL, make it point to the resolved dns entry - * - * Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved, and - * CURLE_OPERATION_TIMEDOUT if a time-out occurred. - */ -CURLcode Curl_wait_for_resolv(struct connectdata *conn, - struct Curl_dns_entry **entry) -{ - CURLcode rc=CURLE_OK; - struct SessionHandle *data = conn->data; - long timeout = CURL_TIMEOUT_RESOLVE; /* default name resolve timeout */ - - /* now, see if there's a connect timeout or a regular timeout to - use instead of the default one */ - if(conn->data->set.connecttimeout) - timeout = conn->data->set.connecttimeout; - else if(conn->data->set.timeout) - timeout = conn->data->set.timeout; - - /* We convert the number of seconds into number of milliseconds here: */ - if(timeout < 2147483) - /* maximum amount of seconds that can be multiplied with 1000 and - still fit within 31 bits */ - timeout *= 1000; - else - timeout = 0x7fffffff; /* ridiculous amount of time anyway */ - - /* Wait for the name resolve query to complete. */ - while (1) { - int nfds=0; - fd_set read_fds, write_fds; - struct timeval *tvp, tv, store; - int count; - struct timeval now = Curl_tvnow(); - long timediff; - - store.tv_sec = (int)timeout/1000; - store.tv_usec = (timeout%1000)*1000; - - FD_ZERO(&read_fds); - FD_ZERO(&write_fds); - nfds = ares_fds(data->state.areschannel, &read_fds, &write_fds); - if (nfds == 0) - /* no file descriptors means we're done waiting */ - break; - tvp = ares_timeout(data->state.areschannel, &store, &tv); - count = select(nfds, &read_fds, &write_fds, NULL, tvp); - if (count < 0 && errno != EINVAL) - break; - - ares_process(data->state.areschannel, &read_fds, &write_fds); - - timediff = Curl_tvdiff(Curl_tvnow(), now); /* spent time */ - timeout -= timediff?timediff:1; /* always deduct at least 1 */ - if (timeout < 0) { - /* our timeout, so we cancel the ares operation */ - ares_cancel(data->state.areschannel); - break; - } - } - - /* Operation complete, if the lookup was successful we now have the entry - in the cache. */ - - if(entry) - *entry = conn->async.dns; - - if(!conn->async.dns) { - /* a name was not resolved */ - if((timeout < 0) || (conn->async.status == ARES_ETIMEOUT)) { - failf(data, "Resolving host timed out: %s", conn->host.dispname); - rc = CURLE_OPERATION_TIMEDOUT; - } - else if(conn->async.done) { - failf(data, "Could not resolve host: %s (%s)", conn->host.dispname, - ares_strerror(conn->async.status)); - rc = CURLE_COULDNT_RESOLVE_HOST; - } - else - rc = CURLE_OPERATION_TIMEDOUT; - - /* close the connection, since we can't return failure here without - cleaning up this connection properly */ - Curl_disconnect(conn); - } - - return rc; -} - -/* - * Curl_getaddrinfo() - when using ares - * - * Returns name information about the given hostname and port number. If - * successful, the 'hostent' is returned and the forth argument will point to - * memory we need to free after use. That memory *MUST* be freed with - * Curl_freeaddrinfo(), nothing else. - */ -Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn, - char *hostname, - int port, - int *waitp) -{ - char *bufp; - struct SessionHandle *data = conn->data; - in_addr_t in = inet_addr(hostname); - - *waitp = FALSE; - - if (in != CURL_INADDR_NONE) { - /* This is a dotted IP address 123.123.123.123-style */ - return Curl_ip2addr(in, hostname, port); - } - - bufp = strdup(hostname); - - if(bufp) { - Curl_safefree(conn->async.hostname); - conn->async.hostname = bufp; - conn->async.port = port; - conn->async.done = FALSE; /* not done */ - conn->async.status = 0; /* clear */ - conn->async.dns = NULL; /* clear */ - - /* areschannel is already setup in the Curl_open() function */ - ares_gethostbyname(data->state.areschannel, hostname, PF_INET, - Curl_addrinfo4_callback, conn); - - *waitp = TRUE; /* please wait for the response */ - } - return NULL; /* no struct yet */ -} - -#endif /* CURLRES_ARES */ diff --git a/Source/CTest/Curl/hostasyn.c b/Source/CTest/Curl/hostasyn.c deleted file mode 100644 index b3c9dfa..0000000 --- a/Source/CTest/Curl/hostasyn.c +++ /dev/null @@ -1,170 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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 <string.h> -#include <errno.h> - -#define _REENTRANT - -#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__) -#include <malloc.h> -#else -#ifdef HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif -#ifdef HAVE_SYS_SOCKET_H -#include <sys/socket.h> -#endif -#ifdef HAVE_NETINET_IN_H -#include <netinet/in.h> -#endif -#ifdef HAVE_NETDB_H -#include <netdb.h> -#endif -#ifdef HAVE_ARPA_INET_H -#include <arpa/inet.h> -#endif -#ifdef HAVE_STDLIB_H -#include <stdlib.h> /* required for free() prototypes */ -#endif -#ifdef HAVE_UNISTD_H -#include <unistd.h> /* for the close() proto */ -#endif -#ifdef VMS -#include <in.h> -#include <inet.h> -#include <stdlib.h> -#endif -#endif - -#ifdef HAVE_SETJMP_H -#include <setjmp.h> -#endif - -#ifdef WIN32 -#include <process.h> -#endif - -#if (defined(NETWARE) && defined(__NOVELL_LIBC__)) -#undef in_addr_t -#define in_addr_t unsigned long -#endif - -#include "urldata.h" -#include "sendf.h" -#include "hostip.h" -#include "hash.h" -#include "share.h" -#include "strerror.h" -#include "url.h" - -#define _MPRINTF_REPLACE /* use our functions only */ -#include <curl/mprintf.h> - -#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL) -#include "inet_ntoa_r.h" -#endif - -#include "curl_memory.h" -/* The last #include file should be: */ -#include "memdebug.h" - -/*********************************************************************** - * Only for builds using asynchronous name resolves - **********************************************************************/ -#ifdef CURLRES_ASYNCH -/* - * addrinfo_callback() gets called by ares, gethostbyname_thread() or - * getaddrinfo_thread() when we got the name resolved (or not!). - * - * If the status argument is CURL_ASYNC_SUCCESS, we might need to copy the - * address field since it might be freed when this function returns. This - * operation stores the resolved data in the DNS cache. - * - * NOTE: for IPv6 operations, Curl_addrinfo_copy() returns the same - * pointer it is given as argument! - * - * The storage operation locks and unlocks the DNS cache. - */ -static void addrinfo_callback(void *arg, /* "struct connectdata *" */ - int status, - void *addr) -{ - struct connectdata *conn = (struct connectdata *)arg; - struct Curl_dns_entry *dns = NULL; - - conn->async.done = TRUE; - conn->async.status = status; - - if(CURL_ASYNC_SUCCESS == status) { - - /* - * IPv4: Curl_addrinfo_copy() copies the address and returns an allocated - * version. - * - * IPv6: Curl_addrinfo_copy() returns the input pointer! - */ - Curl_addrinfo *ai = Curl_addrinfo_copy(addr, conn->async.port); - if(ai) { - struct SessionHandle *data = conn->data; - - if(data->share) - Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE); - - dns = Curl_cache_addr(data, ai, - conn->async.hostname, - conn->async.port); - if(!dns) - /* failed to store, cleanup and return error */ - Curl_freeaddrinfo(ai); - - if(data->share) - Curl_share_unlock(data, CURL_LOCK_DATA_DNS); - } - } - - conn->async.dns = dns; - - /* ipv4: The input hostent struct will be freed by ares when we return from - this function */ -} - -void Curl_addrinfo4_callback(void *arg, /* "struct connectdata *" */ - int status, - struct hostent *hostent) -{ - addrinfo_callback(arg, status, hostent); -} - -#ifdef CURLRES_IPV6 -void Curl_addrinfo6_callback(void *arg, /* "struct connectdata *" */ - int status, - struct addrinfo *ai) -{ - addrinfo_callback(arg, status, ai); -} -#endif - -#endif /* CURLRES_ASYNC */ diff --git a/Source/CTest/Curl/hostip.c b/Source/CTest/Curl/hostip.c deleted file mode 100644 index 43ade26..0000000 --- a/Source/CTest/Curl/hostip.c +++ /dev/null @@ -1,540 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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 <string.h> -#include <errno.h> - -#define _REENTRANT - -#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__) -#include <malloc.h> -#else -#ifdef HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif -#ifdef HAVE_SYS_SOCKET_H -#include <sys/socket.h> -#endif -#ifdef HAVE_NETINET_IN_H -#include <netinet/in.h> -#endif -#ifdef HAVE_NETDB_H -#include <netdb.h> -#endif -#ifdef HAVE_ARPA_INET_H -#include <arpa/inet.h> -#endif -#ifdef HAVE_STDLIB_H -#include <stdlib.h> /* required for free() prototypes */ -#endif -#ifdef HAVE_UNISTD_H -#include <unistd.h> /* for the close() proto */ -#endif -#ifdef VMS -#include <in.h> -#include <inet.h> -#include <stdlib.h> -#endif -#endif - -#ifdef HAVE_SETJMP_H -#include <setjmp.h> -#endif - -#ifdef WIN32 -#include <process.h> -#endif - -#if (defined(NETWARE) && defined(__NOVELL_LIBC__)) -#undef in_addr_t -#define in_addr_t unsigned long -#endif - -#include "urldata.h" -#include "sendf.h" -#include "hostip.h" -#include "hash.h" -#include "share.h" -#include "strerror.h" -#include "url.h" -#include "inet_ntop.h" - -#define _MPRINTF_REPLACE /* use our functions only */ -#include <curl/mprintf.h> - -#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL) -#include "inet_ntoa_r.h" -#endif - -#include "curl_memory.h" -/* The last #include file should be: */ -#include "memdebug.h" - -/* - * hostip.c explained - * ================== - * - * The main COMPILE-TIME DEFINES to keep in mind when reading the host*.c - * source file are these: - * - * CURLRES_IPV6 - this host has getaddrinfo() and family, and thus we use - * that. The host may not be able to resolve IPv6, but we don't really have to - * take that into account. Hosts that aren't IPv6-enabled have CURLRES_IPV4 - * defined. - * - * CURLRES_ARES - is defined if libcurl is built to use c-ares for - * asynchronous name resolves. It cannot have ENABLE_IPV6 defined at the same - * time, as c-ares has no ipv6 support. This can be Windows or *nix. - * - * CURLRES_THREADED - is defined if libcurl is built to run under (native) - * Windows, and then the name resolve will be done in a new thread, and the - * supported API will be the same as for ares-builds. - * - * If any of the two previous are defined, CURLRES_ASYNCH is defined too. If - * libcurl is not built to use an asynchronous resolver, CURLRES_SYNCH is - * defined. - * - * The host*.c sources files are split up like this: - * - * hostip.c - method-independent resolver functions and utility functions - * hostasyn.c - functions for asynchronous name resolves - * hostsyn.c - functions for synchronous name resolves - * hostares.c - functions for ares-using name resolves - * hostthre.c - functions for threaded name resolves - * hostip4.c - ipv4-specific functions - * hostip6.c - ipv6-specific functions - * - * The hostip.h is the united header file for all this. It defines the - * CURLRES_* defines based on the config*.h and setup.h defines. - */ - -/* These two symbols are for the global DNS cache */ -static curl_hash hostname_cache; -static int host_cache_initialized; - -static void freednsentry(void *freethis); - -/* - * Curl_global_host_cache_init() initializes and sets up a global DNS cache. - * Global DNS cache is general badness. Do not use. This will be removed in - * a future version. Use the share interface instead! - */ -void Curl_global_host_cache_init(void) -{ - if (!host_cache_initialized) { - Curl_hash_init(&hostname_cache, 7, freednsentry); - host_cache_initialized = 1; - } -} - -/* - * Return a pointer to the global cache - */ -curl_hash *Curl_global_host_cache_get(void) -{ - return &hostname_cache; -} - -/* - * Destroy and cleanup the global DNS cache - */ -void Curl_global_host_cache_dtor(void) -{ - if (host_cache_initialized) { - Curl_hash_clean(&hostname_cache); - host_cache_initialized = 0; - } -} - -/* - * Return # of adresses in a Curl_addrinfo struct - */ -int Curl_num_addresses(const Curl_addrinfo *addr) -{ - int i; - for (i = 0; addr; addr = addr->ai_next, i++); - return i; -} - -#define GET_SIN_ADDR_FROM_CURL_ADDRINFO(ai_addr, si, sin, sinaddr, ip) \ - { \ - union { \ - struct si* vsi; \ - struct sin* vsin;\ - } vi; \ - vi.vsi = ai_addr; \ - ip = &(vi.vsin->sinaddr); \ - } - -/* - * Curl_printable_address() returns a printable version of the 1st address - * given in the 'ip' argument. The result will be stored in the buf that is - * bufsize bytes big. - * - * If the conversion fails, it returns NULL. - */ -const char *Curl_printable_address(const Curl_addrinfo *ip, - char *buf, size_t bufsize) -{ - int af = ip->ai_family; - const void *ip4; -#ifdef CURLRES_IPV6 - const void *ip6; - GET_SIN_ADDR_FROM_CURL_ADDRINFO(ip->ai_addr, sockaddr, sockaddr_in6, - sin6_addr, ip6); -#else - const void *ip6 = NULL; -#endif - GET_SIN_ADDR_FROM_CURL_ADDRINFO(ip->ai_addr, sockaddr, sockaddr_in, - sin_addr, ip4); - - return Curl_inet_ntop(af, af == AF_INET ? ip4 : ip6, buf, bufsize); -} - -/* - * Return a hostcache id string for the providing host + port, to be used by - * the DNS caching. - */ -static char * -create_hostcache_id(char *server, int port) -{ - /* create and return the new allocated entry */ - return aprintf("%s:%d", server, port); -} - -struct hostcache_prune_data { - int cache_timeout; - time_t now; -}; - -/* - * This function is set as a callback to be called for every entry in the DNS - * cache when we want to prune old unused entries. - * - * Returning non-zero means remove the entry, return 0 to keep it in the - * cache. - */ -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; -} - -/* - * Prune the DNS cache. This assumes that a lock has already been taken. - */ -static void -hostcache_prune(curl_hash *hostcache, int cache_timeout, time_t now) -{ - struct hostcache_prune_data user; - - user.cache_timeout = cache_timeout; - user.now = now; - - Curl_hash_clean_with_criterium(hostcache, - (void *) &user, - hostcache_timestamp_remove); -} - -/* - * Library-wide function for pruning the DNS cache. This function takes and - * returns the appropriate locks. - */ -void Curl_hostcache_prune(struct SessionHandle *data) -{ - time_t now; - - if(data->set.dns_cache_timeout == -1) - /* cache forever means never prune! */ - return; - - if(data->share) - Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE); - - time(&now); - - /* Remove outdated and unused entries from the hostcache */ - hostcache_prune(data->hostcache, - data->set.dns_cache_timeout, - now); - - if(data->share) - Curl_share_unlock(data, CURL_LOCK_DATA_DNS); -} - -#ifdef HAVE_SIGSETJMP -/* Beware this is a global and unique instance. This is used to store the - return address that we can jump back to from inside a signal handler. This - is not thread-safe stuff. */ -sigjmp_buf curl_jmpenv; -#endif - - -/* - * Curl_cache_addr() stores a 'Curl_addrinfo' struct in the DNS cache. - * - * When calling Curl_resolv() has resulted in a response with a returned - * address, we call this function to store the information in the dns - * cache etc - * - * Returns the Curl_dns_entry entry pointer or NULL if the storage failed. - */ -struct Curl_dns_entry * -Curl_cache_addr(struct SessionHandle *data, - Curl_addrinfo *addr, - char *hostname, - int port) -{ - char *entry_id; - size_t entry_len; - struct Curl_dns_entry *dns; - struct Curl_dns_entry *dns2; - time_t now; - - /* Create an entry id, based upon the hostname and port */ - entry_id = create_hostcache_id(hostname, port); - /* If we can't create the entry id, fail */ - if (!entry_id) - return NULL; - entry_len = strlen(entry_id); - - /* Create a new cache entry */ - dns = (struct Curl_dns_entry *) malloc(sizeof(struct Curl_dns_entry)); - if (!dns) { - free(entry_id); - return NULL; - } - - dns->inuse = 0; /* init to not used */ - dns->addr = addr; /* this is the address(es) */ - - /* Store the resolved data in our DNS cache. This function may return a - pointer to an existing struct already present in the hash, and it may - return the same argument we pass in. Make no assumptions. */ - dns2 = Curl_hash_add(data->hostcache, entry_id, entry_len+1, (void *)dns); - if(!dns2) { - /* Major badness, run away. */ - free(dns); - free(entry_id); - return NULL; - } - time(&now); - dns = dns2; - - dns->timestamp = now; /* used now */ - dns->inuse++; /* mark entry as in-use */ - - /* free the allocated entry_id again */ - free(entry_id); - - return dns; -} - -/* - * Curl_resolv() is the main name resolve function within libcurl. It resolves - * a name and returns a pointer to the entry in the 'entry' argument (if one - * is provided). This function might return immediately if we're using asynch - * resolves. See the return codes. - * - * The cache entry we return will get its 'inuse' counter increased when this - * function is used. You MUST call Curl_resolv_unlock() later (when you're - * done using this struct) to decrease the counter again. - * - * Return codes: - * - * CURLRESOLV_ERROR (-1) = error, no pointer - * CURLRESOLV_RESOLVED (0) = OK, pointer provided - * CURLRESOLV_PENDING (1) = waiting for response, no pointer - */ - -int Curl_resolv(struct connectdata *conn, - char *hostname, - int port, - struct Curl_dns_entry **entry) -{ - char *entry_id; - struct Curl_dns_entry *dns = NULL; - size_t entry_len; - int wait; - struct SessionHandle *data = conn->data; - CURLcode result; - - /* default to failure */ - int rc; - *entry = NULL; - -#ifdef HAVE_SIGSETJMP - /* this allows us to time-out from the name resolver, as the timeout - will generate a signal and we will siglongjmp() from that here */ - if(!data->set.no_signal && sigsetjmp(curl_jmpenv, 1)) { - /* this is coming from a siglongjmp() */ - failf(data, "name lookup timed out"); - return CURLRESOLV_ERROR; - } -#endif - rc = CURLRESOLV_ERROR; - - /* Create an entry id, based upon the hostname and port */ - entry_id = create_hostcache_id(hostname, port); - /* If we can't create the entry id, fail */ - if (!entry_id) - return CURLRESOLV_ERROR; - - entry_len = strlen(entry_id); - - if(data->share) - Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE); - - /* See if its already in our dns cache */ - dns = Curl_hash_pick(data->hostcache, entry_id, entry_len+1); - - if(data->share) - Curl_share_unlock(data, CURL_LOCK_DATA_DNS); - - /* free the allocated entry_id again */ - free(entry_id); - - if (!dns) { - /* The entry was not in the cache. Resolve it to IP address */ - - Curl_addrinfo *addr; - - /* Check what IP specifics the app has requested and if we can provide it. - * If not, bail out. */ - if(!Curl_ipvalid(data)) - return CURLRESOLV_ERROR; - - /* If Curl_getaddrinfo() returns NULL, 'wait' might be set to a non-zero - value indicating that we need to wait for the response to the resolve - call */ - addr = Curl_getaddrinfo(conn, hostname, port, &wait); - - if (!addr) { - if(wait) { - /* the response to our resolve call will come asynchronously at - a later time, good or bad */ - /* First, check that we haven't received the info by now */ - result = Curl_is_resolved(conn, &dns); - if(result) /* error detected */ - return CURLRESOLV_ERROR; - if(dns) - rc = CURLRESOLV_RESOLVED; /* pointer provided */ - else - rc = CURLRESOLV_PENDING; /* no info yet */ - } - } - else { - if(data->share) - Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE); - - /* we got a response, store it in the cache */ - dns = Curl_cache_addr(data, addr, hostname, port); - - if(data->share) - Curl_share_unlock(data, CURL_LOCK_DATA_DNS); - - if(!dns) - /* returned failure, bail out nicely */ - Curl_freeaddrinfo(addr); - else - rc = CURLRESOLV_RESOLVED; - } - } - else { - dns->inuse++; /* we use it! */ - rc = CURLRESOLV_RESOLVED; - } - - *entry = dns; - - return rc; -} - -/* - * Curl_resolv_unlock() unlocks the given cached DNS entry. When this has been - * made, the struct may be destroyed due to pruning. It is important that only - * one unlock is made for each Curl_resolv() call. - */ -void Curl_resolv_unlock(struct SessionHandle *data, struct Curl_dns_entry *dns) -{ - curlassert(dns && (dns->inuse>0)); - - if(data->share) - Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE); - - dns->inuse--; - - if(data->share) - Curl_share_unlock(data, CURL_LOCK_DATA_DNS); -} - -/* - * File-internal: free a cache dns entry. - */ -static void freednsentry(void *freethis) -{ - struct Curl_dns_entry *p = (struct Curl_dns_entry *) freethis; - - Curl_freeaddrinfo(p->addr); - - free(p); -} - -/* - * Curl_mk_dnscache() creates a new DNS cache and returns the handle for it. - */ -curl_hash *Curl_mk_dnscache(void) -{ - return Curl_hash_alloc(7, freednsentry); -} - -#ifdef CURLRES_ADDRINFO_COPY - -/* align on even 64bit boundaries */ -#define MEMALIGN(x) ((x)+(8-(((unsigned long)(x))&0x7))) - -/* - * Curl_addrinfo_copy() performs a "deep" copy of a hostent into a buffer and - * returns a pointer to the malloc()ed copy. You need to call free() on the - * returned buffer when you're done with it. - */ -Curl_addrinfo *Curl_addrinfo_copy(void *org, int port) -{ - struct hostent *orig = org; - - return Curl_he2ai(orig, port); -} -#endif /* CURLRES_ADDRINFO_COPY */ diff --git a/Source/CTest/Curl/hostip.h b/Source/CTest/Curl/hostip.h deleted file mode 100644 index 545fec0..0000000 --- a/Source/CTest/Curl/hostip.h +++ /dev/null @@ -1,255 +0,0 @@ -#ifndef __HOSTIP_H -#define __HOSTIP_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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 "hash.h" - -#ifdef HAVE_NETDB_H -#include <netdb.h> -#endif - -/* - * Setup comfortable CURLRES_* defines to use in the host*.c sources. - */ - -#ifdef USE_ARES -#define CURLRES_ASYNCH -#define CURLRES_ARES -#endif - -#ifdef USE_THREADING_GETHOSTBYNAME -#define CURLRES_ASYNCH -#define CURLRES_THREADED -#endif - -#ifdef USE_THREADING_GETADDRINFO -#define CURLRES_ASYNCH -#define CURLRES_THREADED -#endif - -#ifdef ENABLE_IPV6 -#define CURLRES_IPV6 -#else -#define CURLRES_IPV4 -#endif - -#ifdef CURLRES_IPV4 -#if !defined(HAVE_GETHOSTBYNAME_R) || defined(CURLRES_ASYNCH) -/* If built for ipv4 and missing gethostbyname_r(), or if using async name - resolve, we need the Curl_addrinfo_copy() function (which itself needs the - Curl_hostent_relocate() function)) */ -#define CURLRES_ADDRINFO_COPY -#endif -#endif /* IPv4-only */ - -#ifndef CURLRES_ASYNCH -#define CURLRES_SYNCH -#endif - -#ifndef USE_LIBIDN -#define CURLRES_IDN -#endif - -/* Allocate enough memory to hold the full name information structs and - * everything. OSF1 is known to require at least 8872 bytes. The buffer - * required for storing all possible aliases and IP numbers is according to - * Stevens' Unix Network Programming 2nd edition, p. 304: 8192 bytes! - */ -#define CURL_HOSTENT_SIZE 9000 - -#define CURL_TIMEOUT_RESOLVE 300 /* when using asynch methods, we allow this - many seconds for a name resolve */ - -#ifdef CURLRES_ARES -#define CURL_ASYNC_SUCCESS ARES_SUCCESS -#else -#define CURL_ASYNC_SUCCESS CURLE_OK -#endif - -/* - * Curl_addrinfo MUST be used for all name resolved info. - */ -#ifdef CURLRES_IPV6 -typedef struct addrinfo Curl_addrinfo; -#else -/* OK, so some ipv4-only include tree probably have the addrinfo struct, but - to work even on those that don't, we provide our own look-alike! */ -struct Curl_addrinfo { - int ai_flags; - int ai_family; - int ai_socktype; - int ai_protocol; - size_t ai_addrlen; - struct sockaddr *ai_addr; - char *ai_canonname; - struct Curl_addrinfo *ai_next; -}; -typedef struct Curl_addrinfo Curl_addrinfo; -#endif - -struct addrinfo; -struct SessionHandle; -struct connectdata; - -void Curl_global_host_cache_init(void); -void Curl_global_host_cache_dtor(void); -curl_hash *Curl_global_host_cache_get(void); - -#define Curl_global_host_cache_use(__p) ((__p)->set.global_dns_cache) - -struct Curl_dns_entry { - Curl_addrinfo *addr; - time_t timestamp; - long inuse; /* use-counter, make very sure you decrease this - when you're done using the address you received */ -}; - -/* - * 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! - */ -/* return codes */ -#define CURLRESOLV_ERROR -1 -#define CURLRESOLV_RESOLVED 0 -#define CURLRESOLV_PENDING 1 -int Curl_resolv(struct connectdata *conn, char *hostname, - int port, struct Curl_dns_entry **dnsentry); - -/* - * Curl_ipvalid() checks what CURL_IPRESOLVE_* requirements that might've - * been set and returns TRUE if they are OK. - */ -bool Curl_ipvalid(struct SessionHandle *data); - -/* - * Curl_getaddrinfo() is the generic low-level name resolve API within this - * source file. There are several versions of this function - for different - * name resolve layers (selected at build-time). They all take this same set - * of arguments - */ -Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn, - char *hostname, - int port, - int *waitp); - -CURLcode Curl_is_resolved(struct connectdata *conn, - struct Curl_dns_entry **dns); -CURLcode Curl_wait_for_resolv(struct connectdata *conn, - struct Curl_dns_entry **dnsentry); - -/* Curl_fdset() is a generic function that exists in multiple versions - depending on what name resolve technology we've built to use. The function - is called from the curl_multi_fdset() function */ -CURLcode Curl_fdset(struct connectdata *conn, - fd_set *read_fd_set, - fd_set *write_fd_set, - int *max_fdp); -/* unlock a previously resolved dns entry */ -void Curl_resolv_unlock(struct SessionHandle *data, struct Curl_dns_entry *dns); - -/* for debugging purposes only: */ -void Curl_scan_cache_used(void *user, void *ptr); - -/* free name info */ -void Curl_freeaddrinfo(Curl_addrinfo *freeaddr); - -/* make a new dns cache and return the handle */ -curl_hash *Curl_mk_dnscache(void); - -/* prune old entries from the DNS cache */ -void Curl_hostcache_prune(struct SessionHandle *data); - -/* Return # of adresses in a Curl_addrinfo struct */ -int Curl_num_addresses (const Curl_addrinfo *addr); - -#ifdef CURLDEBUG -void curl_dofreeaddrinfo(struct addrinfo *freethis, - int line, const char *source); -int curl_dogetaddrinfo(char *hostname, char *service, - struct addrinfo *hints, - struct addrinfo **result, - int line, const char *source); -int curl_dogetnameinfo(const struct sockaddr *sa, socklen_t salen, - char *host, size_t hostlen, - char *serv, size_t servlen, int flags, - int line, const char *source); -#endif - -/* This is the callback function that is used when we build with asynch - resolve, ipv4 */ -void Curl_addrinfo4_callback(void *arg, - int status, - struct hostent *hostent); -/* This is the callback function that is used when we build with asynch - resolve, ipv6 */ -void Curl_addrinfo6_callback(void *arg, - int status, - struct addrinfo *ai); - - -/* [ipv4 only] Creates a Curl_addrinfo struct from a numerical-only IP - address */ -Curl_addrinfo *Curl_ip2addr(in_addr_t num, char *hostname, int port); - -/* [ipv4 only] Curl_he2ai() converts a struct hostent to a Curl_addrinfo chain - and returns it */ -Curl_addrinfo *Curl_he2ai(struct hostent *, int port); - -/* relocate a hostent struct */ -void Curl_hostent_relocate(struct hostent *h, long offset); - -/* Clone a Curl_addrinfo struct, works protocol independently */ -Curl_addrinfo *Curl_addrinfo_copy(void *orig, int port); - -/* - * Curl_printable_address() returns a printable version of the 1st address - * given in the 'ip' argument. The result will be stored in the buf that is - * bufsize bytes big. - */ -const char *Curl_printable_address(const Curl_addrinfo *ip, - char *buf, size_t bufsize); - -/* - * Curl_cache_addr() stores a 'Curl_addrinfo' struct in the DNS cache. - * - * Returns the Curl_dns_entry entry pointer or NULL if the storage failed. - */ -struct Curl_dns_entry * -Curl_cache_addr(struct SessionHandle *data, Curl_addrinfo *addr, - char *hostname, int port); - -#ifndef INADDR_NONE -#define CURL_INADDR_NONE (in_addr_t) ~0 -#else -#define CURL_INADDR_NONE INADDR_NONE -#endif - - - - -#endif diff --git a/Source/CTest/Curl/hostip4.c b/Source/CTest/Curl/hostip4.c deleted file mode 100644 index 1b4c3c1..0000000 --- a/Source/CTest/Curl/hostip4.c +++ /dev/null @@ -1,456 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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 <string.h> -#include <errno.h> - -#define _REENTRANT - -#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__) -#include <malloc.h> -#else -#ifdef HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif -#ifdef HAVE_SYS_SOCKET_H -#include <sys/socket.h> -#endif -#ifdef HAVE_NETINET_IN_H -#include <netinet/in.h> -#endif -#ifdef HAVE_NETDB_H -#include <netdb.h> -#endif -#ifdef HAVE_ARPA_INET_H -#include <arpa/inet.h> -#endif -#ifdef HAVE_STDLIB_H -#include <stdlib.h> /* required for free() prototypes */ -#endif -#ifdef HAVE_UNISTD_H -#include <unistd.h> /* for the close() proto */ -#endif -#ifdef VMS -#include <in.h> -#include <inet.h> -#include <stdlib.h> -#endif -#endif - -#ifdef HAVE_SETJMP_H -#include <setjmp.h> -#endif - -#ifdef WIN32 -#include <process.h> -#endif - -#if (defined(NETWARE) && defined(__NOVELL_LIBC__)) -#undef in_addr_t -#define in_addr_t unsigned long -#endif - -#include "urldata.h" -#include "sendf.h" -#include "hostip.h" -#include "hash.h" -#include "share.h" -#include "strerror.h" -#include "url.h" - -#define _MPRINTF_REPLACE /* use our functions only */ -#include <curl/mprintf.h> - -#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL) -#include "inet_ntoa_r.h" -#endif - -#include "curl_memory.h" -/* The last #include file should be: */ -#include "memdebug.h" - -/*********************************************************************** - * Only for plain-ipv4 builds - **********************************************************************/ -#ifdef CURLRES_IPV4 /* plain ipv4 code coming up */ - -/* - * This is a function for freeing name information in a protocol independent - * way. - */ -void Curl_freeaddrinfo(Curl_addrinfo *ai) -{ - Curl_addrinfo *next; - - /* walk over the list and free all entries */ - while(ai) { - next = ai->ai_next; - free(ai); - ai = next; - } -} - -/* - * Curl_ipvalid() checks what CURL_IPRESOLVE_* requirements that might've - * been set and returns TRUE if they are OK. - */ -bool Curl_ipvalid(struct SessionHandle *data) -{ - if(data->set.ip_version == CURL_IPRESOLVE_V6) - /* an ipv6 address was requested and we can't get/use one */ - return FALSE; - - return TRUE; /* OK, proceed */ -} - -struct namebuf { - struct hostent hostentry; - char *h_addr_list[2]; - struct in_addr addrentry; - char h_name[16]; /* 123.123.123.123 = 15 letters is maximum */ -}; - -/* - * Curl_ip2addr() takes a 32bit ipv4 internet address as input parameter - * together with a pointer to the string version of the address, and it - * returns a Curl_addrinfo chain filled in correctly with information for this - * address/host. - * - * The input parameters ARE NOT checked for validity but they are expected - * to have been checked already when this is called. - */ -Curl_addrinfo *Curl_ip2addr(in_addr_t num, char *hostname, int port) -{ - Curl_addrinfo *ai; - struct hostent *h; - struct in_addr *addrentry; - struct namebuf buffer; - struct namebuf *buf = &buffer; - - h = &buf->hostentry; - h->h_addr_list = &buf->h_addr_list[0]; - addrentry = &buf->addrentry; - addrentry->s_addr = num; - h->h_addr_list[0] = (char*)addrentry; - h->h_addr_list[1] = NULL; - h->h_addrtype = AF_INET; - h->h_length = sizeof(*addrentry); - h->h_name = &buf->h_name[0]; - h->h_aliases = NULL; - - /* Now store the dotted version of the address */ - snprintf((char*)(h->h_name), 16, "%s", hostname); - - ai = Curl_he2ai(h, port); - - return ai; -} - -#ifdef CURLRES_SYNCH /* the functions below are for synchronous resolves */ - -/* - * Curl_getaddrinfo() - the ipv4 synchronous version. - * - * 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. - * - * gethostbyname_r() is the thread-safe version of the gethostbyname() - * function. When we build for plain IPv4, we attempt to use this - * function. There are _three_ different gethostbyname_r() versions, and we - * detect which one this platform supports in the configure script and set up - * the HAVE_GETHOSTBYNAME_R_3, HAVE_GETHOSTBYNAME_R_5 or - * HAVE_GETHOSTBYNAME_R_6 defines accordingly. Note that HAVE_GETADDRBYNAME - * has the corresponding rules. This is primarily on *nix. Note that some unix - * flavours have thread-safe versions of the plain gethostbyname() etc. - * - */ -Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn, - char *hostname, - int port, - int *waitp) -{ - Curl_addrinfo *ai = NULL; - struct hostent *h = NULL; - in_addr_t in; - struct SessionHandle *data = conn->data; - struct hostent *buf = NULL; - - (void)port; /* unused in IPv4 code */ - - *waitp = 0; /* don't wait, we act synchronously */ - - in=inet_addr(hostname); - if (in != CURL_INADDR_NONE) { - /* This is a dotted IP address 123.123.123.123-style */ - return Curl_ip2addr(in, hostname, port); - } - -#if defined(HAVE_GETHOSTBYNAME_R) - /* - * gethostbyname_r() is the preferred resolve function for many platforms. - * Since there are three different versions of it, the following code is - * somewhat #ifdef-ridden. - */ - else { - int h_errnop; - int res=ERANGE; - - buf = (struct hostent *)calloc(CURL_HOSTENT_SIZE, 1); - if(!buf) - return NULL; /* major failure */ - /* - * The clearing of the buffer is a workaround for a gethostbyname_r bug in - * qnx nto and it is also _required_ for some of these functions on some - * platforms. - */ - -#ifdef HAVE_GETHOSTBYNAME_R_5 - /* Solaris, IRIX and more */ - (void)res; /* prevent compiler warning */ - h = gethostbyname_r(hostname, - (struct hostent *)buf, - (char *)buf + sizeof(struct hostent), - CURL_HOSTENT_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) { - ; - } - else -#endif /* HAVE_GETHOSTBYNAME_R_5 */ -#ifdef HAVE_GETHOSTBYNAME_R_6 - /* Linux */ - - res=gethostbyname_r(hostname, - (struct hostent *)buf, - (char *)buf + sizeof(struct hostent), - CURL_HOSTENT_SIZE - sizeof(struct hostent), - &h, /* DIFFERENCE */ - &h_errnop); - /* Redhat 8, using glibc 2.2.93 changed the behavior. Now all of a - * sudden this function returns EAGAIN if the given buffer size is too - * small. Previous versions are known to return ERANGE for the same - * problem. - * - * This wouldn't be such a big problem if older versions wouldn't - * sometimes return EAGAIN on a common failure case. Alas, we can't - * assume that EAGAIN *or* ERANGE means ERANGE for any given version of - * glibc. - * - * For now, we do that and thus we may call the function repeatedly and - * fail for older glibc versions that return EAGAIN, until we run out of - * buffer size (step_size grows beyond CURL_HOSTENT_SIZE). - * - * If anyone has a better fix, please tell us! - * - * ------------------------------------------------------------------- - * - * On October 23rd 2003, Dan C dug up more details on the mysteries of - * gethostbyname_r() in glibc: - * - * In glibc 2.2.5 the interface is different (this has also been - * discovered in glibc 2.1.1-6 as shipped by Redhat 6). What I can't - * explain, is that tests performed on glibc 2.2.4-34 and 2.2.4-32 - * (shipped/upgraded by Redhat 7.2) don't show this behavior! - * - * In this "buggy" version, the return code is -1 on error and 'errno' - * is set to the ERANGE or EAGAIN code. Note that 'errno' is not a - * thread-safe variable. - */ - - if(!h) /* failure */ -#endif/* HAVE_GETHOSTBYNAME_R_6 */ -#ifdef HAVE_GETHOSTBYNAME_R_3 - /* AIX, Digital Unix/Tru64, HPUX 10, more? */ - - /* For AIX 4.3 or later, we don't use gethostbyname_r() at all, because of - * the plain fact that it does not return unique full buffers on each - * call, but instead several of the pointers in the hostent structs will - * point to the same actual data! This have the unfortunate down-side that - * our caching system breaks down horribly. Luckily for us though, AIX 4.3 - * and more recent versions have a "completely thread-safe"[*] libc where - * all the data is stored in thread-specific memory areas making calls to - * the plain old gethostbyname() work fine even for multi-threaded - * programs. - * - * This AIX 4.3 or later detection is all made in the configure script. - * - * Troels Walsted Hansen helped us work this out on March 3rd, 2003. - * - * [*] = much later we've found out that it isn't at all "completely - * thread-safe", but at least the gethostbyname() function is. - */ - - if(CURL_HOSTENT_SIZE >= - (sizeof(struct hostent)+sizeof(struct hostent_data))) { - - /* August 22nd, 2000: Albert Chin-A-Young brought an updated version - * that should work! September 20: Richard Prescott worked on the buffer - * size dilemma. - */ - - res = gethostbyname_r(hostname, - (struct hostent *)buf, - (struct hostent_data *)((char *)buf + - sizeof(struct hostent))); - h_errnop= errno; /* we don't deal with this, but set it anyway */ - } - else - res = -1; /* failure, too smallish buffer size */ - - if(!res) { /* success */ - - h = buf; /* result expected in h */ - - /* This is the worst kind of the different gethostbyname_r() interfaces. - * Since we don't know how big buffer this particular lookup required, - * we can't realloc down the huge alloc without doing closer analysis of - * the returned data. Thus, we always use CURL_HOSTENT_SIZE for every - * name lookup. Fixing this would require an extra malloc() and then - * calling Curl_addrinfo_copy() that subsequent realloc()s down the new - * memory area to the actually used amount. - */ - } - else -#endif /* HAVE_GETHOSTBYNAME_R_3 */ - { - infof(data, "gethostbyname_r(2) failed for %s\n", hostname); - h = NULL; /* set return code to NULL */ - free(buf); - } -#else /* HAVE_GETHOSTBYNAME_R */ - /* - * Here is code for platforms that don't have gethostbyname_r() or for - * which the gethostbyname() is the preferred() function. - */ - else { - h = gethostbyname(hostname); - if (!h) - infof(data, "gethostbyname(2) failed for %s\n", hostname); -#endif /*HAVE_GETHOSTBYNAME_R */ - } - - if(h) { - ai = Curl_he2ai(h, port); - - if (buf) /* used a *_r() function */ - free(buf); - } - - return ai; -} - -#endif /* CURLRES_SYNCH */ - -/* - * Curl_he2ai() translates from a hostent struct to a Curl_addrinfo struct. - * The Curl_addrinfo is meant to work like the addrinfo struct does for IPv6 - * stacks, but for all hosts and environments. - -struct Curl_addrinfo { - int ai_flags; - int ai_family; - int ai_socktype; - int ai_protocol; - size_t ai_addrlen; - struct sockaddr *ai_addr; - char *ai_canonname; - struct addrinfo *ai_next; -}; - -struct hostent { - char *h_name; * official name of host * - char **h_aliases; * alias list * - int h_addrtype; * host address type * - int h_length; * length of address * - char **h_addr_list; * list of addresses * -} -#define h_addr h_addr_list[0] * for backward compatibility * - -*/ - -Curl_addrinfo *Curl_he2ai(struct hostent *he, int port) -{ - Curl_addrinfo *ai; - Curl_addrinfo *prevai = NULL; - Curl_addrinfo *firstai = NULL; - int i; - - union { - struct in_addr *addr; - char* list; - } curr; - union { - struct sockaddr_in* addr_in; - struct sockaddr* addr; - } address; - - if(!he) - /* no input == no output! */ - return NULL; - - for(i=0; (curr.list = he->h_addr_list[i]); i++) { - - ai = calloc(1, sizeof(Curl_addrinfo) + sizeof(struct sockaddr_in)); - - if(!ai) - break; - - if(!firstai) - /* store the pointer we want to return from this function */ - firstai = ai; - - if(prevai) - /* make the previous entry point to this */ - prevai->ai_next = ai; - - ai->ai_family = AF_INET; /* we only support this */ - ai->ai_socktype = SOCK_STREAM; /* we only support this */ - ai->ai_addrlen = sizeof(struct sockaddr_in); - /* make the ai_addr point to the address immediately following this struct - and use that area to store the address */ - ai->ai_addr = (struct sockaddr *) (ai + 1); - - /* leave the rest of the struct filled with zero */ - - address.addr = ai->ai_addr; /* storage area for this info */ - - memcpy((char *)&(address.addr_in->sin_addr), curr.addr, sizeof(struct in_addr)); - address.addr_in->sin_family = he->h_addrtype; - address.addr_in->sin_port = htons((unsigned short)port); - - prevai = ai; - } - return firstai; -} - -#endif /* CURLRES_IPV4 */ diff --git a/Source/CTest/Curl/hostip6.c b/Source/CTest/Curl/hostip6.c deleted file mode 100644 index 6717c00..0000000 --- a/Source/CTest/Curl/hostip6.c +++ /dev/null @@ -1,263 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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 <string.h> -#include <errno.h> - -#define _REENTRANT - -#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__) -#include <malloc.h> -#else -#ifdef HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif -#ifdef HAVE_SYS_SOCKET_H -#include <sys/socket.h> -#endif -#ifdef HAVE_NETINET_IN_H -#include <netinet/in.h> -#endif -#ifdef HAVE_NETDB_H -#include <netdb.h> -#endif -#ifdef HAVE_ARPA_INET_H -#include <arpa/inet.h> -#endif -#ifdef HAVE_STDLIB_H -#include <stdlib.h> /* required for free() prototypes */ -#endif -#ifdef HAVE_UNISTD_H -#include <unistd.h> /* for the close() proto */ -#endif -#ifdef VMS -#include <in.h> -#include <inet.h> -#include <stdlib.h> -#endif -#endif - -#ifdef HAVE_SETJMP_H -#include <setjmp.h> -#endif - -#ifdef WIN32 -#include <process.h> -#endif - -#if (defined(NETWARE) && defined(__NOVELL_LIBC__)) -#undef in_addr_t -#define in_addr_t unsigned long -#endif - -#include "urldata.h" -#include "sendf.h" -#include "hostip.h" -#include "hash.h" -#include "share.h" -#include "strerror.h" -#include "url.h" - -#define _MPRINTF_REPLACE /* use our functions only */ -#include <curl/mprintf.h> - -#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL) -#include "inet_ntoa_r.h" -#endif - -#include "curl_memory.h" -/* The last #include file should be: */ -#include "memdebug.h" - -/*********************************************************************** - * Only for ipv6-enabled builds - **********************************************************************/ -#ifdef CURLRES_IPV6 -/* - * This is a wrapper function for freeing name information in a protocol - * independent way. This takes care of using the appropriate underlaying - * function. - */ -void Curl_freeaddrinfo(Curl_addrinfo *p) -{ - freeaddrinfo(p); -} - -#ifdef CURLRES_ASYNCH -/* - * Curl_addrinfo_copy() is used by the asynch callback to copy a given - * address. But this is an ipv6 build and then we don't copy the address, we - * just return the same pointer! - */ -Curl_addrinfo *Curl_addrinfo_copy(void *source, int port) -{ - (void) port; - return source; -} -#endif - -#ifdef CURLDEBUG -/* These are strictly for memory tracing and are using the same style as the - * family otherwise present in memdebug.c. I put these ones here since they - * require a bunch of structs I didn't wanna include in memdebug.c - */ -int curl_dogetaddrinfo(char *hostname, char *service, - struct addrinfo *hints, - struct addrinfo **result, - int line, const char *source) -{ - int res=(getaddrinfo)(hostname, service, hints, result); - if(0 == res) { - /* success */ - if(logfile) - fprintf(logfile, "ADDR %s:%d getaddrinfo() = %p\n", - source, line, (void *)*result); - } - else { - if(logfile) - fprintf(logfile, "ADDR %s:%d getaddrinfo() failed\n", - source, line); - } - return res; -} - -int curl_dogetnameinfo(const struct sockaddr *sa, socklen_t salen, - char *host, size_t hostlen, - char *serv, size_t servlen, int flags, - int line, const char *source) -{ - int res=(getnameinfo)(sa, salen, host, hostlen, serv, servlen, flags); - if(0 == res) { - /* success */ - if(logfile) - fprintf(logfile, "GETNAME %s:%d getnameinfo()\n", - source, line); - } - else { - if(logfile) - fprintf(logfile, "GETNAME %s:%d getnameinfo() failed = %d\n", - source, line, res); - } - return res; -} - -void curl_dofreeaddrinfo(struct addrinfo *freethis, - int line, const char *source) -{ - (freeaddrinfo)(freethis); - if(logfile) - fprintf(logfile, "ADDR %s:%d freeaddrinfo(%p)\n", - source, line, (void *)freethis); -} - -#endif - -/* - * Curl_ipvalid() checks what CURL_IPRESOLVE_* requirements that might've - * been set and returns TRUE if they are OK. - */ -bool Curl_ipvalid(struct SessionHandle *data) -{ - if(data->set.ip_version == CURL_IPRESOLVE_V6) { - /* see if we have an IPv6 stack */ - curl_socket_t s = socket(PF_INET6, SOCK_DGRAM, 0); - if (s == CURL_SOCKET_BAD) - /* an ipv6 address was requested and we can't get/use one */ - return FALSE; - sclose(s); - } - return TRUE; -} - -#ifndef USE_THREADING_GETADDRINFO -/* - * Curl_getaddrinfo() when built ipv6-enabled (non-threading version). - * - * Returns name information about the given hostname and port number. If - * successful, the 'addrinfo' is returned and the forth argument will point to - * memory we need to free after use. That memory *MUST* be freed with - * Curl_freeaddrinfo(), nothing else. - */ -Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn, - char *hostname, - int port, - int *waitp) -{ - struct addrinfo hints, *res; - int error; - char sbuf[NI_MAXSERV]; - curl_socket_t s; - int pf; - struct SessionHandle *data = conn->data; - - *waitp=0; /* don't wait, we have the response now */ - - /* 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); - - /* - * Check if a more limited name resolve has been requested. - */ - switch(data->set.ip_version) { - case CURL_IPRESOLVE_V4: - pf = PF_INET; - break; - case CURL_IPRESOLVE_V6: - pf = PF_INET6; - break; - default: - pf = PF_UNSPEC; - break; - } - } - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = pf; - hints.ai_socktype = SOCK_STREAM; - hints.ai_flags = AI_CANONNAME; - snprintf(sbuf, sizeof(sbuf), "%d", port); - error = getaddrinfo(hostname, sbuf, &hints, &res); - if (error) { - infof(data, "getaddrinfo(3) failed for %s:%d\n", hostname, port); - return NULL; - } - - return res; -} -#endif /* USE_THREADING_GETADDRINFO */ -#endif /* ipv6 */ - diff --git a/Source/CTest/Curl/hostsyn.c b/Source/CTest/Curl/hostsyn.c deleted file mode 100644 index 786f9d9..0000000 --- a/Source/CTest/Curl/hostsyn.c +++ /dev/null @@ -1,149 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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 <string.h> -#include <errno.h> - -#define _REENTRANT - -#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__) -#include <malloc.h> -#else -#ifdef HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif -#ifdef HAVE_SYS_SOCKET_H -#include <sys/socket.h> -#endif -#ifdef HAVE_NETINET_IN_H -#include <netinet/in.h> -#endif -#ifdef HAVE_NETDB_H -#include <netdb.h> -#endif -#ifdef HAVE_ARPA_INET_H -#include <arpa/inet.h> -#endif -#ifdef HAVE_STDLIB_H -#include <stdlib.h> /* required for free() prototypes */ -#endif -#ifdef HAVE_UNISTD_H -#include <unistd.h> /* for the close() proto */ -#endif -#ifdef VMS -#include <in.h> -#include <inet.h> -#include <stdlib.h> -#endif -#endif - -#ifdef HAVE_SETJMP_H -#include <setjmp.h> -#endif - -#ifdef WIN32 -#include <process.h> -#endif - -#if (defined(NETWARE) && defined(__NOVELL_LIBC__)) -#undef in_addr_t -#define in_addr_t unsigned long -#endif - -#include "urldata.h" -#include "sendf.h" -#include "hostip.h" -#include "hash.h" -#include "share.h" -#include "strerror.h" -#include "url.h" - -#define _MPRINTF_REPLACE /* use our functions only */ -#include <curl/mprintf.h> - -#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL) -#include "inet_ntoa_r.h" -#endif - -#include "curl_memory.h" -/* The last #include file should be: */ -#include "memdebug.h" - -/*********************************************************************** - * Only for builds using synchronous name resolves - **********************************************************************/ -#ifdef CURLRES_SYNCH - -/* - * Curl_wait_for_resolv() for synch-builds. Curl_resolv() can never return - * wait==TRUE, so this function will never be called. If it still gets called, - * we return failure at once. - * - * We provide this function only to allow multi.c to remain unaware if we are - * doing asynch resolves or not. - */ -CURLcode Curl_wait_for_resolv(struct connectdata *conn, - struct Curl_dns_entry **entry) -{ - (void)conn; - *entry=NULL; - return CURLE_COULDNT_RESOLVE_HOST; -} - -/* - * This function will never be called when synch-built. If it still gets - * called, we return failure at once. - * - * We provide this function only to allow multi.c to remain unaware if we are - * doing asynch resolves or not. - */ -CURLcode Curl_is_resolved(struct connectdata *conn, - struct Curl_dns_entry **dns) -{ - (void)conn; - *dns = NULL; - - return CURLE_COULDNT_RESOLVE_HOST; -} - -/* - * We just return OK, this function is never actually used for synch builds. - * It is present here to keep #ifdefs out from multi.c - */ - -CURLcode Curl_fdset(struct connectdata *conn, - fd_set *read_fd_set, - fd_set *write_fd_set, - int *max_fdp) -{ - (void)conn; - (void)read_fd_set; - (void)write_fd_set; - (void)max_fdp; - - return CURLE_OK; -} - -#endif /* truly sync */ diff --git a/Source/CTest/Curl/hostthre.c b/Source/CTest/Curl/hostthre.c deleted file mode 100644 index 4f56ccb..0000000 --- a/Source/CTest/Curl/hostthre.c +++ /dev/null @@ -1,551 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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 <string.h> -#include <errno.h> - -#define _REENTRANT - -#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__) -#include <malloc.h> -#else -#ifdef HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif -#ifdef HAVE_SYS_SOCKET_H -#include <sys/socket.h> -#endif -#ifdef HAVE_NETINET_IN_H -#include <netinet/in.h> -#endif -#ifdef HAVE_NETDB_H -#include <netdb.h> -#endif -#ifdef HAVE_ARPA_INET_H -#include <arpa/inet.h> -#endif -#ifdef HAVE_STDLIB_H -#include <stdlib.h> /* required for free() prototypes */ -#endif -#ifdef HAVE_UNISTD_H -#include <unistd.h> /* for the close() proto */ -#endif -#ifdef VMS -#include <in.h> -#include <inet.h> -#include <stdlib.h> -#endif -#endif - -#ifdef HAVE_SETJMP_H -#include <setjmp.h> -#endif - -#ifdef WIN32 -#include <process.h> -#endif - -#if (defined(NETWARE) && defined(__NOVELL_LIBC__)) -#undef in_addr_t -#define in_addr_t unsigned long -#endif - -#include "urldata.h" -#include "sendf.h" -#include "hostip.h" -#include "hash.h" -#include "share.h" -#include "strerror.h" -#include "url.h" - -#define _MPRINTF_REPLACE /* use our functions only */ -#include <curl/mprintf.h> - -#include "inet_ntop.h" - -#include "curl_memory.h" -/* The last #include file should be: */ -#include "memdebug.h" - -/*********************************************************************** - * Only for Windows threaded name resolves builds - **********************************************************************/ -#ifdef CURLRES_THREADED - -/* This function is used to init a threaded resolve */ -static bool init_resolve_thread(struct connectdata *conn, - const char *hostname, int port, - const Curl_addrinfo *hints); - -#ifdef CURLRES_IPV4 - #define THREAD_FUNC gethostbyname_thread - #define THREAD_NAME "gethostbyname_thread" -#else - #define THREAD_FUNC getaddrinfo_thread - #define THREAD_NAME "getaddrinfo_thread" -#endif - -#if defined(DEBUG_THREADING_GETHOSTBYNAME) || \ - defined(DEBUG_THREADING_GETADDRINFO) -/* If this is defined, provide tracing */ -#define TRACE(args) \ - do { trace_it("%u: ", __LINE__); trace_it args; } while (0) - -static void trace_it (const char *fmt, ...) -{ - static int do_trace = -1; - va_list args; - - if (do_trace == -1) { - const char *env = getenv("CURL_TRACE"); - do_trace = (env && atoi(env) > 0); - } - if (!do_trace) - return; - va_start (args, fmt); - vfprintf (stderr, fmt, args); - fflush (stderr); - va_end (args); -} -#else -#define TRACE(x) -#endif - -#ifdef DEBUG_THREADING_GETADDRINFO -static void dump_addrinfo (struct connectdata *conn, const struct addrinfo *ai) -{ - TRACE(("dump_addrinfo:\n")); - for ( ; ai; ai = ai->ai_next) { - char buf [INET6_ADDRSTRLEN]; - - trace_it(" fam %2d, CNAME %s, ", - ai->ai_family, ai->ai_canonname ? ai->ai_canonname : "<none>"); - if (Curl_printable_address(ai, buf, sizeof(buf))) - trace_it("%s\n", buf); - else - trace_it("failed; %s\n", Curl_strerror(conn,WSAGetLastError())); - } -} -#endif - -struct thread_data { - HANDLE thread_hnd; - unsigned thread_id; - DWORD thread_status; - curl_socket_t dummy_sock; /* dummy for Curl_fdset() */ - FILE *stderr_file; -#ifdef CURLRES_IPV6 - struct addrinfo hints; -#endif -}; - -#if defined(CURLRES_IPV4) -/* - * gethostbyname_thread() resolves a name, calls the Curl_addrinfo4_callback - * and then exits. - * - * For builds without ARES/ENABLE_IPV6, create a resolver thread and wait on - * it. - */ -static unsigned __stdcall gethostbyname_thread (void *arg) -{ - struct connectdata *conn = (struct connectdata*) arg; - struct thread_data *td = (struct thread_data*) conn->async.os_specific; - struct hostent *he; - int rc; - - /* Sharing the same _iob[] element with our parent thread should - * hopefully make printouts synchronised. I'm not sure it works - * with a static runtime lib (MSVC's libc.lib). - */ - *stderr = *td->stderr_file; - - WSASetLastError (conn->async.status = NO_DATA); /* pending status */ - he = gethostbyname (conn->async.hostname); - if (he) { - Curl_addrinfo4_callback(conn, CURL_ASYNC_SUCCESS, he); - rc = 1; - } - else { - Curl_addrinfo4_callback(conn, (int)WSAGetLastError(), NULL); - rc = 0; - } - TRACE(("Winsock-error %d, addr %s\n", conn->async.status, - he ? inet_ntoa(*(struct in_addr*)he->h_addr) : "unknown")); - return (rc); - /* An implicit _endthreadex() here */ -} - -#elif defined(CURLRES_IPV6) - -/* - * getaddrinfo_thread() resolves a name, calls Curl_addrinfo6_callback and then - * exits. - * - * For builds without ARES, but with ENABLE_IPV6, create a resolver thread - * and wait on it. - */ -static unsigned __stdcall getaddrinfo_thread (void *arg) -{ - struct connectdata *conn = (struct connectdata*) arg; - struct thread_data *td = (struct thread_data*) conn->async.os_specific; - struct addrinfo *res; - char service [NI_MAXSERV]; - int rc; - - *stderr = *td->stderr_file; - - itoa(conn->async.port, service, 10); - - WSASetLastError(conn->async.status = NO_DATA); /* pending status */ - - rc = getaddrinfo(conn->async.hostname, service, &td->hints, &res); - - if (rc == 0) { -#ifdef DEBUG_THREADING_GETADDRINFO - dump_addrinfo (conn, res); -#endif - Curl_addrinfo6_callback(conn, CURL_ASYNC_SUCCESS, res); - } - else { - Curl_addrinfo6_callback(conn, (int)WSAGetLastError(), NULL); - TRACE(("Winsock-error %d, no address\n", conn->async.status)); - } - return (rc); - /* An implicit _endthreadex() here */ -} -#endif - -/* - * destroy_thread_data() cleans up async resolver data. - * Complementary of ares_destroy. - */ -static void destroy_thread_data (struct Curl_async *async) -{ - if (async->hostname) - free(async->hostname); - - if (async->os_specific) { - curl_socket_t sock = ((const struct thread_data*)async->os_specific)->dummy_sock; - - if (sock != CURL_SOCKET_BAD) - sclose(sock); - free(async->os_specific); - } - async->hostname = NULL; - async->os_specific = NULL; -} - -/* - * init_resolve_thread() starts a new thread that performs the actual - * resolve. This function returns before the resolve is done. - * - * Returns FALSE in case of failure, otherwise TRUE. - */ -static bool init_resolve_thread (struct connectdata *conn, - const char *hostname, int port, - const Curl_addrinfo *hints) -{ - struct thread_data *td = calloc(sizeof(*td), 1); - - if (!td) { - SetLastError(ENOMEM); - return FALSE; - } - - Curl_safefree(conn->async.hostname); - conn->async.hostname = strdup(hostname); - if (!conn->async.hostname) { - free(td); - SetLastError(ENOMEM); - return FALSE; - } - - conn->async.port = port; - conn->async.done = FALSE; - conn->async.status = 0; - conn->async.dns = NULL; - conn->async.os_specific = (void*) td; - - td->dummy_sock = CURL_SOCKET_BAD; - td->stderr_file = stderr; - td->thread_hnd = (HANDLE) _beginthreadex(NULL, 0, THREAD_FUNC, - conn, 0, &td->thread_id); -#ifdef CURLRES_IPV6 - curlassert(hints); - td->hints = *hints; -#else - (void) hints; -#endif - - if (!td->thread_hnd) { - SetLastError(errno); - TRACE(("_beginthreadex() failed; %s\n", Curl_strerror(conn,errno))); - destroy_thread_data(&conn->async); - return FALSE; - } - /* This socket is only to keep Curl_fdset() and select() happy; should never - * become signalled for read/write since it's unbound but Windows needs - * atleast 1 socket in select(). - */ - td->dummy_sock = socket(AF_INET, SOCK_DGRAM, 0); - return TRUE; -} - - -/* - * Curl_wait_for_resolv() waits for a resolve to finish. This function should - * be avoided since using this risk getting the multi interface to "hang". - * - * If 'entry' is non-NULL, make it point to the resolved dns entry - * - * This is the version for resolves-in-a-thread. - */ -CURLcode Curl_wait_for_resolv(struct connectdata *conn, - struct Curl_dns_entry **entry) -{ - struct thread_data *td = (struct thread_data*) conn->async.os_specific; - struct SessionHandle *data = conn->data; - long timeout; - DWORD status, ticks; - CURLcode rc; - - curlassert (conn && td); - - /* now, see if there's a connect timeout or a regular timeout to - use instead of the default one */ - timeout = - conn->data->set.connecttimeout ? conn->data->set.connecttimeout : - conn->data->set.timeout ? conn->data->set.timeout : - CURL_TIMEOUT_RESOLVE; /* default name resolve timeout */ - ticks = GetTickCount(); - (void)ticks; - - status = WaitForSingleObject(td->thread_hnd, 1000UL*timeout); - if (status == WAIT_OBJECT_0 || status == WAIT_ABANDONED) { - /* Thread finished before timeout; propagate Winsock error to this thread. - * 'conn->async.done = TRUE' is set in Curl_addrinfo4/6_callback(). - */ - WSASetLastError(conn->async.status); - GetExitCodeThread(td->thread_hnd, &td->thread_status); - TRACE(("%s() status %lu, thread retval %lu, ", - THREAD_NAME, status, td->thread_status)); - } - else { - conn->async.done = TRUE; - td->thread_status = (DWORD)-1; - TRACE(("%s() timeout, ", THREAD_NAME)); - } - - TRACE(("elapsed %lu ms\n", GetTickCount()-ticks)); - - CloseHandle(td->thread_hnd); - - if(entry) - *entry = conn->async.dns; - - rc = CURLE_OK; - - if (!conn->async.dns) { - /* a name was not resolved */ - if (td->thread_status == (DWORD)-1 || conn->async.status == NO_DATA) { - failf(data, "Resolving host timed out: %s", conn->host.name); - rc = CURLE_OPERATION_TIMEDOUT; - } - else if(conn->async.done) { - failf(data, "Could not resolve host: %s; %s", - conn->host.name, Curl_strerror(conn,conn->async.status)); - rc = CURLE_COULDNT_RESOLVE_HOST; - } - else - rc = CURLE_OPERATION_TIMEDOUT; - } - - destroy_thread_data(&conn->async); - - if(CURLE_OK != rc) - /* close the connection, since we must not return failure from here - without cleaning up this connection properly */ - Curl_disconnect(conn); - - return (rc); -} - -/* - * Curl_is_resolved() is called repeatedly to check if a previous name resolve - * request has completed. It should also make sure to time-out if the - * operation seems to take too long. - */ -CURLcode Curl_is_resolved(struct connectdata *conn, - struct Curl_dns_entry **entry) -{ - *entry = NULL; - - if (conn->async.done) { - /* we're done */ - destroy_thread_data(&conn->async); - if (!conn->async.dns) { - TRACE(("Curl_is_resolved(): CURLE_COULDNT_RESOLVE_HOST\n")); - return CURLE_COULDNT_RESOLVE_HOST; - } - *entry = conn->async.dns; - TRACE(("resolved okay, dns %p\n", *entry)); - } - else - TRACE(("not yet\n")); - return CURLE_OK; -} - -CURLcode Curl_fdset(struct connectdata *conn, - fd_set *read_fd_set, - fd_set *write_fd_set, - int *max_fdp) -{ - const struct thread_data *td = - (const struct thread_data *) conn->async.os_specific; - - if (td && td->dummy_sock != CURL_SOCKET_BAD) { - FD_SET(td->dummy_sock,write_fd_set); - *max_fdp = td->dummy_sock; - } - (void) read_fd_set; - return CURLE_OK; -} - -#ifdef CURLRES_IPV4 -/* - * Curl_getaddrinfo() - for Windows threading without ENABLE_IPV6. - */ -Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn, - char *hostname, - int port, - int *waitp) -{ - struct hostent *h; - struct SessionHandle *data = conn->data; - in_addr_t in; - - *waitp = 0; /* don't wait, we act synchronously */ - - in = inet_addr(hostname); - if (in != CURL_INADDR_NONE) - /* This is a dotted IP address 123.123.123.123-style */ - return Curl_ip2addr(in, hostname, port); - - /* fire up a new resolver thread! */ - if (init_resolve_thread(conn, hostname, port, NULL)) { - *waitp = TRUE; /* please wait for the response */ - return NULL; - } - - /* fall-back to blocking version */ - infof(data, "init_resolve_thread() failed for %s; code %lu\n", - hostname, GetLastError()); - - h = gethostbyname(hostname); - if (!h) { - infof(data, "gethostbyname(2) failed for %s:%d; %s\n", - hostname, port, Curl_strerror(conn,WSAGetLastError())); - return NULL; - } - return Curl_he2ai(h, port); -} -#endif /* CURLRES_IPV4 */ - -#ifdef CURLRES_IPV6 -/* - * Curl_getaddrinfo() - for Windows threading IPv6 enabled - */ -Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn, - char *hostname, - int port, - int *waitp) -{ - struct addrinfo hints, *res; - int error; - char sbuf[NI_MAXSERV]; - curl_socket_t s; - int pf; - struct SessionHandle *data = conn->data; - - *waitp = FALSE; /* default to synch response */ - - /* see if we have an IPv6 stack */ - s = socket(PF_INET6, SOCK_DGRAM, 0); - if (s == CURL_SOCKET_BAD) { - /* 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); - - /* - * Check if a more limited name resolve has been requested. - */ - switch(data->set.ip_version) { - case CURL_IPRESOLVE_V4: - pf = PF_INET; - break; - case CURL_IPRESOLVE_V6: - pf = PF_INET6; - break; - default: - pf = PF_UNSPEC; - break; - } - } - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = pf; - hints.ai_socktype = SOCK_STREAM; - hints.ai_flags = AI_CANONNAME; - itoa(port, sbuf, 10); - - /* fire up a new resolver thread! */ - if (init_resolve_thread(conn, hostname, port, &hints)) { - *waitp = TRUE; /* please wait for the response */ - return NULL; - } - - /* fall-back to blocking version */ - infof(data, "init_resolve_thread() failed for %s; code %lu\n", - hostname, GetLastError()); - - error = getaddrinfo(hostname, sbuf, &hints, &res); - if (error) { - infof(data, "getaddrinfo() failed for %s:%d; %s\n", - hostname, port, Curl_strerror(conn,WSAGetLastError())); - return NULL; - } - return res; -} -#endif /* CURLRES_IPV6 */ -#endif /* CURLRES_THREADED */ diff --git a/Source/CTest/Curl/http.c b/Source/CTest/Curl/http.c deleted file mode 100644 index 7cf543b..0000000 --- a/Source/CTest/Curl/http.c +++ /dev/null @@ -1,1996 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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" - -#ifndef CURL_DISABLE_HTTP -/* -- WIN32 approved -- */ -#include <stdio.h> -#include <string.h> -#include <stdarg.h> -#include <stdlib.h> -#include <ctype.h> -#include <sys/types.h> -#include <sys/stat.h> - -#include <errno.h> - -#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__) -#include <time.h> -#include <io.h> -#else -#ifdef HAVE_SYS_SOCKET_H -#include <sys/socket.h> -#endif -#ifdef HAVE_NETINET_IN_H -#include <netinet/in.h> -#endif -#include <sys/time.h> - -#ifdef HAVE_TIME_H -#ifdef TIME_WITH_SYS_TIME -#include <time.h> -#endif -#endif - -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif -#include <netdb.h> -#ifdef HAVE_ARPA_INET_H -#include <arpa/inet.h> -#endif -#ifdef HAVE_NET_IF_H -#include <net/if.h> -#endif -#include <sys/ioctl.h> -#include <signal.h> - -#ifdef HAVE_SYS_PARAM_H -#include <sys/param.h> -#endif - -#ifdef HAVE_SYS_SELECT_H -#include <sys/select.h> -#endif - -#endif - -#include "urldata.h" -#include <curl/curl.h> -#include "transfer.h" -#include "sendf.h" -#include "formdata.h" -#include "progress.h" -#include "base64.h" -#include "cookie.h" -#include "strequal.h" -#include "ssluse.h" -#include "http_digest.h" -#include "http_ntlm.h" -#include "http_negotiate.h" -#include "url.h" -#include "share.h" -#include "hostip.h" -#include "http.h" -#include "curl_memory.h" - -#define _MPRINTF_REPLACE /* use our functions only */ -#include <curl/mprintf.h> - -/* The last #include file should be: */ -#include "memdebug.h" - -/* - * checkheaders() checks the linked list of custom HTTP headers for a - * particular header (prefix). - * - * Returns a pointer to the first matching header or NULL if none matched. - */ -static char *checkheaders(struct SessionHandle *data, const char *thisheader) -{ - struct curl_slist *head; - size_t thislen = strlen(thisheader); - - for(head = data->set.headers; head; head=head->next) { - if(strnequal(head->data, thisheader, thislen)) - return head->data; - } - return NULL; -} - -/* - * Curl_output_basic() sets up an Authorization: header (or the proxy version) - * for HTTP Basic authentication. - * - * Returns CURLcode. - */ -static CURLcode Curl_output_basic(struct connectdata *conn, bool proxy) -{ - char *authorization; - struct SessionHandle *data=conn->data; - char **userp; - char *user; - char *pwd; - - if(proxy) { - userp = &conn->allocptr.proxyuserpwd; - user = conn->proxyuser; - pwd = conn->proxypasswd; - } - else { - userp = &conn->allocptr.userpwd; - user = conn->user; - pwd = conn->passwd; - } - - snprintf(data->state.buffer, sizeof(data->state.buffer), "%s:%s", user, pwd); - if(Curl_base64_encode(data->state.buffer, - strlen(data->state.buffer), - &authorization) > 0) { - if(*userp) - free(*userp); - *userp = aprintf( "%sAuthorization: Basic %s\015\012", - proxy?"Proxy-":"", - authorization); - free(authorization); - } - else - return CURLE_OUT_OF_MEMORY; - return CURLE_OK; -} - -/* pickoneauth() selects the most favourable authentication method from the - * ones available and the ones we want. - * - * return TRUE if one was picked - */ -static bool pickoneauth(struct auth *pick) -{ - bool picked; - /* only deal with authentication we want */ - long avail = pick->avail & pick->want; - picked = TRUE; - - /* The order of these checks is highly relevant, as this will be the order - of preference in case of the existance of multiple accepted types. */ - if(avail & CURLAUTH_GSSNEGOTIATE) - pick->picked = CURLAUTH_GSSNEGOTIATE; - else if(avail & CURLAUTH_DIGEST) - pick->picked = CURLAUTH_DIGEST; - else if(avail & CURLAUTH_NTLM) - pick->picked = CURLAUTH_NTLM; - else if(avail & CURLAUTH_BASIC) - pick->picked = CURLAUTH_BASIC; - else { - pick->picked = CURLAUTH_PICKNONE; /* we select to use nothing */ - picked = FALSE; - } - pick->avail = CURLAUTH_NONE; /* clear it here */ - - return picked; -} - -/* - * Curl_http_auth_act() gets called when a all HTTP headers have been received - * and it checks what authentication methods that are available and decides - * which one (if any) to use. It will set 'newurl' if an auth metod was - * picked. - */ - -CURLcode Curl_http_auth_act(struct connectdata *conn) -{ - struct SessionHandle *data = conn->data; - bool pickhost = FALSE; - bool pickproxy = FALSE; - CURLcode code = CURLE_OK; - - if(data->state.authproblem) - return data->set.http_fail_on_error?CURLE_HTTP_RETURNED_ERROR:CURLE_OK; - - if(conn->bits.user_passwd && - ((conn->keep.httpcode == 401) || - (conn->bits.authprobe && conn->keep.httpcode < 300))) { - pickhost = pickoneauth(&data->state.authhost); - if(!pickhost) - data->state.authproblem = TRUE; - } - if(conn->bits.proxy_user_passwd && - ((conn->keep.httpcode == 407) || - (conn->bits.authprobe && conn->keep.httpcode < 300))) { - pickproxy = pickoneauth(&data->state.authproxy); - if(!pickproxy) - data->state.authproblem = TRUE; - } - - if(pickhost || pickproxy) - conn->newurl = strdup(data->change.url); /* clone URL */ - - else if((conn->keep.httpcode < 300) && - (!data->state.authhost.done) && - conn->bits.authprobe) { - /* no (known) authentication available, - authentication is not "done" yet and - no authentication seems to be required and - we didn't try HEAD or GET */ - if((data->set.httpreq != HTTPREQ_GET) && - (data->set.httpreq != HTTPREQ_HEAD)) { - conn->newurl = strdup(data->change.url); /* clone URL */ - data->state.authhost.done = TRUE; - } - } - if (Curl_http_should_fail(conn)) { - failf (data, "The requested URL returned error: %d", - conn->keep.httpcode); - code = CURLE_HTTP_RETURNED_ERROR; - } - - return code; -} - -/** - * Curl_http_output_auth() setups the authentication headers for the - * host/proxy and the correct authentication - * method. conn->data->state.authdone is set to TRUE when authentication is - * done. - * - * @param conn all information about the current connection - * @param request pointer to the request keyword - * @param path pointer to the requested path - * @param proxytunnel boolean if this is the request setting up a "proxy - * tunnel" - * - * @returns CURLcode - */ -static CURLcode -Curl_http_output_auth(struct connectdata *conn, - char *request, - char *path, - bool proxytunnel) /* TRUE if this is the request setting - up the proxy tunnel */ -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - char *auth=NULL; - - curlassert(data); - - if((conn->bits.httpproxy && conn->bits.proxy_user_passwd) || - conn->bits.user_passwd) - /* continue please */ ; - else { - data->state.authhost.done = TRUE; - data->state.authproxy.done = TRUE; - return CURLE_OK; /* no authentication with no user or password */ - } - - if(data->state.authhost.want && !data->state.authhost.picked) - /* The app has selected one or more methods, but none has been picked - so far by a server round-trip. Then we set the picked one to the - want one, and if this is one single bit it'll be used instantly. */ - data->state.authhost.picked = data->state.authhost.want; - - if(data->state.authproxy.want && !data->state.authproxy.picked) - /* The app has selected one or more methods, but none has been picked so - far by a proxy round-trip. Then we set the picked one to the want one, - and if this is one single bit it'll be used instantly. */ - data->state.authproxy.picked = data->state.authproxy.want; - - /* To prevent the user+password to get sent to other than the original - host due to a location-follow, we do some weirdo checks here */ - if(!data->state.this_is_a_follow || - !data->state.auth_host || - curl_strequal(data->state.auth_host, conn->host.name) || - data->set.http_disable_hostname_check_before_authentication) { - - /* Send proxy authentication header if needed */ - if (conn->bits.httpproxy && - (conn->bits.tunnel_proxy == proxytunnel)) { -#ifdef USE_SSLEAY - if(data->state.authproxy.want == CURLAUTH_NTLM) { - auth=(char *)"NTLM"; - result = Curl_output_ntlm(conn, TRUE); - if(result) - return result; - } - else -#endif - if(data->state.authproxy.want == CURLAUTH_BASIC) { - /* Basic */ - if(conn->bits.proxy_user_passwd && - !checkheaders(data, "Proxy-authorization:")) { - auth=(char *)"Basic"; - result = Curl_output_basic(conn, TRUE); - if(result) - return result; - } - data->state.authproxy.done = TRUE; - } - else if(data->state.authproxy.want == CURLAUTH_DIGEST) { - auth=(char *)"Digest"; - result = Curl_output_digest(conn, - TRUE, /* proxy */ - (unsigned char *)request, - (unsigned char *)path); - if(result) - return result; - } - - infof(data, "Proxy auth using %s with user '%s'\n", - auth, conn->proxyuser?conn->proxyuser:""); - } - else - /* we have no proxy so let's pretend we're done authenticating - with it */ - data->state.authproxy.done = TRUE; - - /* Send web authentication header if needed */ - { - auth = NULL; -#ifdef HAVE_GSSAPI - if((data->state.authhost.want == CURLAUTH_GSSNEGOTIATE) && - data->state.negotiate.context && - !GSS_ERROR(data->state.negotiate.status)) { - auth=(char *)"GSS-Negotiate"; - result = Curl_output_negotiate(conn); - if (result) - return result; - data->state.authhost.done = TRUE; - } - else -#endif -#ifdef USE_SSLEAY - if(data->state.authhost.picked == CURLAUTH_NTLM) { - auth=(char *)"NTLM"; - result = Curl_output_ntlm(conn, FALSE); - if(result) - return result; - } - else -#endif - { - if(data->state.authhost.picked == CURLAUTH_DIGEST) { - auth=(char *)"Digest"; - result = Curl_output_digest(conn, - FALSE, /* not a proxy */ - (unsigned char *)request, - (unsigned char *)path); - if(result) - return result; - } - else if(data->state.authhost.picked == CURLAUTH_BASIC) { - if(conn->bits.user_passwd && - !checkheaders(data, "Authorization:")) { - auth=(char *)"Basic"; - result = Curl_output_basic(conn, FALSE); - if(result) - return result; - } - /* basic is always ready */ - data->state.authhost.done = TRUE; - } - } - if(auth) - infof(data, "Server auth using %s with user '%s'\n", - auth, conn->user); - } - } - else - data->state.authhost.done = TRUE; - - return result; -} - - -/* - * Curl_http_input_auth() deals with Proxy-Authenticate: and WWW-Authenticate: - * headers. They are dealt with both in the transfer.c main loop and in the - * proxy CONNECT loop. - */ - -CURLcode Curl_http_input_auth(struct connectdata *conn, - int httpcode, - char *header) /* the first non-space */ -{ - /* - * This resource requires authentication - */ - struct SessionHandle *data = conn->data; - - long *availp; - char *start; - struct auth *authp; - - if (httpcode == 407) { - start = header+strlen("Proxy-authenticate:"); - availp = &data->info.proxyauthavail; - authp = &data->state.authproxy; - } - else { - start = header+strlen("WWW-Authenticate:"); - availp = &data->info.httpauthavail; - authp = &data->state.authhost; - } - - /* pass all white spaces */ - while(*start && isspace((int)*start)) - start++; - - /* - * Here we check if we want the specific single authentiction (using ==) and - * if we do, we initiate usage of it. - * - * If the provided authentication is wanted as one out of several accepted - * types (using &), we OR this authenticaion type to the authavail - * variable. - */ - -#ifdef HAVE_GSSAPI - if (checkprefix("GSS-Negotiate", start) || - checkprefix("Negotiate", start)) { - *availp |= CURLAUTH_GSSNEGOTIATE; - authp->avail |= CURLAUTH_GSSNEGOTIATE; - if(authp->picked == CURLAUTH_GSSNEGOTIATE) { - /* if exactly this is wanted, go */ - int neg = Curl_input_negotiate(conn, start); - if (neg == 0) { - conn->newurl = strdup(data->change.url); - data->state.authproblem = (conn->newurl == NULL); - } - else { - infof(data, "Authentication problem. Ignoring this.\n"); - data->state.authproblem = TRUE; - } - } - } - else -#endif -#ifdef USE_SSLEAY - /* NTLM support requires the SSL crypto libs */ - if(checkprefix("NTLM", start)) { - *availp |= CURLAUTH_NTLM; - authp->avail |= CURLAUTH_NTLM; - if(authp->picked == CURLAUTH_NTLM) { - /* NTLM authentication is picked and activated */ - CURLntlm ntlm = - Curl_input_ntlm(conn, (bool)(httpcode == 407), start); - - if(CURLNTLM_BAD != ntlm) - data->state.authproblem = FALSE; - else { - infof(data, "Authentication problem. Ignoring this.\n"); - data->state.authproblem = TRUE; - } - } - } - else -#endif - if(checkprefix("Digest", start)) { - CURLdigest dig; - *availp |= CURLAUTH_DIGEST; - authp->avail |= CURLAUTH_DIGEST; - - /* We call this function on input Digest headers even if Digest - * authentication isn't activated yet, as we need to store the - * incoming data from this header in case we are gonna use Digest. */ - dig = Curl_input_digest(conn, (bool)(httpcode == 407), start); - - if(CURLDIGEST_FINE != dig) { - infof(data, "Authentication problem. Ignoring this.\n"); - data->state.authproblem = TRUE; - } - } - else if(checkprefix("Basic", start)) { - *availp |= CURLAUTH_BASIC; - authp->avail |= CURLAUTH_BASIC; - if(authp->picked == CURLAUTH_BASIC) { - /* We asked for Basic authentication but got a 40X back - anyway, which basicly means our name+password isn't - valid. */ - authp->avail = CURLAUTH_NONE; - infof(data, "Authentication problem. Ignoring this.\n"); - data->state.authproblem = TRUE; - } - } - - return CURLE_OK; -} - -/** - * Curl_http_should_fail() determines whether an HTTP response has gotten us - * into an error state or not. - * - * @param conn all information about the current connection - * - * @retval 0 communications should continue - * - * @retval 1 communications should not continue - */ -int Curl_http_should_fail(struct connectdata *conn) -{ - struct SessionHandle *data; - struct Curl_transfer_keeper *k; - - curlassert(conn); - data = conn->data; - curlassert(data); - - /* - ** For readability - */ - k = &conn->keep; - - /* - ** If we haven't been asked to fail on error, - ** don't fail. - */ - if (!data->set.http_fail_on_error) - return 0; - - /* - ** Any code < 400 is never terminal. - */ - if (k->httpcode < 400) - return 0; - - /* - ** Any code >= 400 that's not 401 or 407 is always - ** a terminal error - */ - if ((k->httpcode != 401) && - (k->httpcode != 407)) - return 1; - - /* - ** All we have left to deal with is 401 and 407 - */ - curlassert((k->httpcode == 401) || (k->httpcode == 407)); - - /* - ** Examine the current authentication state to see if this - ** is an error. The idea is for this function to get - ** called after processing all the headers in a response - ** message. So, if we've been to asked to authenticate a - ** particular stage, and we've done it, we're OK. But, if - ** we're already completely authenticated, it's not OK to - ** get another 401 or 407. - ** - ** It is possible for authentication to go stale such that - ** the client needs to reauthenticate. Once that info is - ** available, use it here. - */ -#if 0 /* set to 1 when debugging this functionality */ - infof(data,"%s: authstage = %d\n",__FUNCTION__,data->state.authstage); - infof(data,"%s: authwant = 0x%08x\n",__FUNCTION__,data->state.authwant); - infof(data,"%s: authavail = 0x%08x\n",__FUNCTION__,data->state.authavail); - infof(data,"%s: httpcode = %d\n",__FUNCTION__,k->httpcode); - infof(data,"%s: authdone = %d\n",__FUNCTION__,data->state.authdone); - infof(data,"%s: newurl = %s\n",__FUNCTION__,conn->newurl ? conn->newurl : "(null)"); - infof(data,"%s: authproblem = %d\n",__FUNCTION__,data->state.authproblem); -#endif - - /* - ** Either we're not authenticating, or we're supposed to - ** be authenticating something else. This is an error. - */ - if((k->httpcode == 401) && !conn->bits.user_passwd) - return TRUE; - if((k->httpcode == 407) && !conn->bits.proxy_user_passwd) - return TRUE; - - return data->state.authproblem; -} - -/* - * readmoredata() is a "fread() emulation" to provide POST and/or request - * data. It is used when a huge POST is to be made and the entire chunk wasn't - * sent in the first send(). This function will then be called from the - * transfer.c loop when more data is to be sent to the peer. - * - * Returns the amount of bytes it filled the buffer with. - */ -static size_t readmoredata(char *buffer, - size_t size, - size_t nitems, - void *userp) -{ - struct connectdata *conn = (struct connectdata *)userp; - struct HTTP *http = conn->proto.http; - size_t fullsize = size * nitems; - - if(0 == http->postsize) - /* nothing to return */ - return 0; - - /* make sure that a HTTP request is never sent away chunked! */ - conn->bits.forbidchunk= (http->sending == HTTPSEND_REQUEST)?TRUE:FALSE; - - if(http->postsize <= (curl_off_t)fullsize) { - memcpy(buffer, http->postdata, (size_t)http->postsize); - fullsize = (size_t)http->postsize; - - if(http->backup.postsize) { - /* move backup data into focus and continue on that */ - http->postdata = http->backup.postdata; - http->postsize = http->backup.postsize; - conn->fread = http->backup.fread; - conn->fread_in = http->backup.fread_in; - - http->sending++; /* move one step up */ - - http->backup.postsize=0; - } - else - http->postsize = 0; - - return fullsize; - } - - memcpy(buffer, http->postdata, fullsize); - http->postdata += fullsize; - http->postsize -= fullsize; - - return fullsize; -} - -/* ------------------------------------------------------------------------- */ -/* - * The add_buffer series of functions are used to build one large memory chunk - * from repeated function invokes. Used so that the entire HTTP request can - * be sent in one go. - */ - -struct send_buffer { - char *buffer; - size_t size_max; - size_t size_used; -}; -typedef struct send_buffer send_buffer; - -static CURLcode - add_buffer(send_buffer *in, const void *inptr, size_t size); - -/* - * add_buffer_init() sets up and returns a fine buffer struct - */ -static -send_buffer *add_buffer_init(void) -{ - send_buffer *blonk; - blonk=(send_buffer *)malloc(sizeof(send_buffer)); - if(blonk) { - memset(blonk, 0, sizeof(send_buffer)); - return blonk; - } - return NULL; /* failed, go home */ -} - -/* - * add_buffer_send() sends a buffer and frees all associated memory. - * - * Returns CURLcode - */ -static -CURLcode add_buffer_send(send_buffer *in, - struct connectdata *conn, - long *bytes_written) /* add the number of sent - bytes to this counter */ -{ - ssize_t amount; - CURLcode res; - char *ptr; - size_t size; - struct HTTP *http = conn->proto.http; - size_t sendsize; - curl_socket_t sockfd = conn->sock[FIRSTSOCKET]; - - /* 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 */ - - ptr = in->buffer; - size = in->size_used; - - if(conn->protocol & PROT_HTTPS) { - /* We never send more than CURL_MAX_WRITE_SIZE bytes in one single chunk - when we speak HTTPS, as if only a fraction of it is sent now, this data - needs to fit into the normal read-callback buffer later on and that - buffer is using this size. - */ - - sendsize= (size > CURL_MAX_WRITE_SIZE)?CURL_MAX_WRITE_SIZE:size; - - /* OpenSSL is very picky and we must send the SAME buffer pointer to the - library when we attempt to re-send this buffer. Sending the same data - is not enough, we must use the exact same address. For this reason, we - must copy the data to the uploadbuffer first, since that is the buffer - we will be using if this send is retried later. - */ - memcpy(conn->data->state.uploadbuffer, ptr, sendsize); - ptr = conn->data->state.uploadbuffer; - } - else - sendsize = size; - - res = Curl_write(conn, sockfd, ptr, sendsize, &amount); - - if(CURLE_OK == res) { - - if(conn->data->set.verbose) - /* this data _may_ contain binary stuff */ - Curl_debug(conn->data, CURLINFO_HEADER_OUT, ptr, amount, - conn->host.dispname); - - *bytes_written += amount; - - if((size_t)amount != size) { - /* The whole request could not be sent in one system call. We must queue - it up and send it later when we get the chance. We must not loop here - and wait until it might work again. */ - - size -= amount; - - ptr = in->buffer + amount; - - /* backup the currently set pointers */ - http->backup.fread = conn->fread; - http->backup.fread_in = conn->fread_in; - http->backup.postdata = http->postdata; - http->backup.postsize = http->postsize; - - /* set the new pointers for the request-sending */ - conn->fread = (curl_read_callback)readmoredata; - conn->fread_in = (void *)conn; - http->postdata = ptr; - http->postsize = (curl_off_t)size; - - http->send_buffer = in; - http->sending = HTTPSEND_REQUEST; - - return CURLE_OK; - } - http->sending = HTTPSEND_BODY; - /* the full buffer was sent, clean up and return */ - } - if(in->buffer) - free(in->buffer); - free(in); - - return res; -} - - -/* - * add_bufferf() add the formatted input to the buffer. - */ -static -CURLcode add_bufferf(send_buffer *in, const char *fmt, ...) -{ - char *s; - va_list ap; - va_start(ap, fmt); - s = vaprintf(fmt, ap); /* this allocs a new string to append */ - va_end(ap); - - if(s) { - CURLcode result = add_buffer(in, s, strlen(s)); - free(s); - if(CURLE_OK == result) - return CURLE_OK; - } - /* If we failed, we cleanup the whole buffer and return error */ - if(in->buffer) - free(in->buffer); - free(in); - return CURLE_OUT_OF_MEMORY; -} - -/* - * add_buffer() appends a memory chunk to the existing buffer - */ -static -CURLcode add_buffer(send_buffer *in, const void *inptr, size_t size) -{ - char *new_rb; - size_t new_size; - - if(!in->buffer || - ((in->size_used + size) > (in->size_max - 1))) { - new_size = (in->size_used+size)*2; - if(in->buffer) - /* we have a buffer, enlarge the existing one */ - new_rb = (char *)realloc(in->buffer, new_size); - else - /* create a new buffer */ - new_rb = (char *)malloc(new_size); - - if(!new_rb) - return CURLE_OUT_OF_MEMORY; - - in->buffer = new_rb; - in->size_max = new_size; - } - memcpy(&in->buffer[in->size_used], inptr, size); - - in->size_used += size; - - return CURLE_OK; -} - -/* end of the add_buffer functions */ -/* ------------------------------------------------------------------------- */ - -/* - * Curl_compareheader() - * - * Returns TRUE if 'headerline' contains the 'header' with given 'content'. - * Pass headers WITH the colon. - */ -bool -Curl_compareheader(char *headerline, /* line to check */ - const char *header, /* header keyword _with_ colon */ - const char *content) /* content string to find */ -{ - /* RFC2616, section 4.2 says: "Each header field consists of a name followed - * by a colon (":") and the field value. Field names are case-insensitive. - * The field value MAY be preceded by any amount of LWS, though a single SP - * is preferred." */ - - size_t hlen = strlen(header); - size_t clen; - size_t len; - char *start; - char *end; - - if(!strnequal(headerline, header, hlen)) - return FALSE; /* doesn't start with header */ - - /* pass the header */ - start = &headerline[hlen]; - - /* pass all white spaces */ - while(*start && isspace((int)*start)) - start++; - - /* find the end of the header line */ - end = strchr(start, '\r'); /* lines end with CRLF */ - if(!end) { - /* in case there's a non-standard compliant line here */ - end = strchr(start, '\n'); - - if(!end) - /* hm, there's no line ending here, use the zero byte! */ - end = strchr(start, '\0'); - } - - len = end-start; /* length of the content part of the input line */ - clen = strlen(content); /* length of the word to find */ - - /* find the content string in the rest of the line */ - for(;len>=clen;len--, start++) { - if(strnequal(start, content, clen)) - return TRUE; /* match! */ - } - - return FALSE; /* no match */ -} - -/* - * ConnectHTTPProxyTunnel() requires that we're connected to a HTTP proxy. This - * function will issue the necessary commands to get a seamless tunnel through - * this proxy. After that, the socket can be used just as a normal socket. - */ - -CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn, - int sockindex, - char *hostname, - int remote_port) -{ - int subversion=0; - struct SessionHandle *data=conn->data; - struct Curl_transfer_keeper *k = &conn->keep; - CURLcode result; - int res; - - size_t nread; /* total size read */ - int perline; /* count bytes per line */ - bool keepon=TRUE; - ssize_t gotbytes; - char *ptr; - long timeout; /* default timeout in seconds */ - struct timeval interval; - fd_set rkeepfd; - fd_set readfd; - char *line_start; - char *host_port; - curl_socket_t tunnelsocket = conn->sock[sockindex]; - -#define SELECT_OK 0 -#define SELECT_ERROR 1 -#define SELECT_TIMEOUT 2 - int error = SELECT_OK; - - infof(data, "Establish HTTP proxy tunnel to %s:%d\n", hostname, remote_port); - - do { - if(conn->newurl) { - /* This only happens if we've looped here due to authentication reasons, - and we don't really use the newly cloned URL here then. Just free() - it. */ - free(conn->newurl); - conn->newurl = NULL; - } - - host_port = aprintf("%s:%d", hostname, remote_port); - if(!host_port) - return CURLE_OUT_OF_MEMORY; - - /* Setup the proxy-authorization header, if any */ - result = Curl_http_output_auth(conn, (char *)"CONNECT", host_port, TRUE); - if(CURLE_OK == result) { - - /* OK, now send the connect request to the proxy */ - result = - Curl_sendf(tunnelsocket, conn, - "CONNECT %s:%d HTTP/1.0\015\012" - "%s" - "%s" - "\r\n", - hostname, remote_port, - conn->bits.proxy_user_passwd? - conn->allocptr.proxyuserpwd:"", - data->set.useragent?conn->allocptr.uagent:"" - ); - if(result) - failf(data, "Failed sending CONNECT to proxy"); - } - free(host_port); - if(result) - return result; - - FD_ZERO (&readfd); /* clear it */ - FD_SET (tunnelsocket, &readfd); /* read socket */ - - /* get this in a backup variable to be able to restore it on each lap in - the select() loop */ - rkeepfd = readfd; - - ptr=data->state.buffer; - line_start = ptr; - - nread=0; - perline=0; - - while((nread<BUFSIZE) && (keepon && !error)) { - readfd = rkeepfd; /* set every lap */ - interval.tv_sec = 1; /* timeout each second and check the timeout */ - interval.tv_usec = 0; - - 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, "Proxy connection aborted due to timeout"); - error = SELECT_TIMEOUT; /* already too little time */ - break; - } - } - - switch (select (tunnelsocket+1, &readfd, NULL, NULL, &interval)) { - case -1: /* select() error, stop reading */ - error = SELECT_ERROR; - failf(data, "Proxy CONNECT aborted due to select() error"); - break; - case 0: /* timeout */ - break; - default: - /* - * This code previously didn't use the kerberos sec_read() code - * to read, but when we use Curl_read() it may do so. Do confirm - * that this is still ok and then remove this comment! - */ - res= Curl_read(conn, tunnelsocket, ptr, BUFSIZE-nread, &gotbytes); - if(res< 0) - /* EWOULDBLOCK */ - continue; /* go loop yourself */ - else if(res) - keepon = FALSE; - else if(gotbytes <= 0) { - keepon = FALSE; - error = SELECT_ERROR; - failf(data, "Proxy CONNECT aborted"); - } - else { - /* - * We got a whole chunk of data, which can be anything from one byte - * to a set of lines and possibly just a piece of the last line. - * - * TODO: To make this code work less error-prone, we need to make - * sure that we read and create full lines before we compare them, - * as there is really nothing that stops the proxy from delivering - * the response lines in multiple parts, each part consisting of - * only a little piece of the line(s). */ - int i; - - nread += gotbytes; - for(i = 0; i < gotbytes; ptr++, i++) { - perline++; /* amount of bytes in this line so far */ - if(*ptr=='\n') { - char letter; - int writetype; - - /* output debug output if that is requested */ - if(data->set.verbose) - Curl_debug(data, CURLINFO_HEADER_IN, line_start, perline, - conn->host.dispname); - - /* send the header to the callback */ - writetype = CLIENTWRITE_HEADER; - if(data->set.include_header) - writetype |= CLIENTWRITE_BODY; - - result = Curl_client_write(data, writetype, line_start, perline); - if(result) - return result; - - /* Newlines are CRLF, so the CR is ignored as the line isn't - really terminated until the LF comes. Treat a following CR - as end-of-headers as well.*/ - - if(('\r' == line_start[0]) || - ('\n' == line_start[0])) { - /* end of response-headers from the proxy */ - keepon=FALSE; - break; /* breaks out of for-loop, not switch() */ - } - - /* keep a backup of the position we are about to blank */ - letter = line_start[perline]; - line_start[perline]=0; /* zero terminate the buffer */ - if((checkprefix("WWW-Authenticate:", line_start) && - (401 == k->httpcode)) || - (checkprefix("Proxy-authenticate:", line_start) && - (407 == k->httpcode))) { - result = Curl_http_input_auth(conn, k->httpcode, line_start); - if(result) - return result; - } - else if(2 == sscanf(line_start, "HTTP/1.%d %d", - &subversion, - &k->httpcode)) { - /* store the HTTP code from the proxy */ - data->info.httpproxycode = k->httpcode; - } - /* put back the letter we blanked out before */ - line_start[perline]= letter; - - perline=0; /* line starts over here */ - line_start = ptr+1; /* this skips the zero byte we wrote */ - } - } - } - break; - } /* switch */ - } /* while there's buffer left and loop is requested */ - - if(error) - return CURLE_RECV_ERROR; - - if(data->info.httpproxycode != 200) - /* Deal with the possibly already received authenticate - headers. 'newurl' is set to a new URL if we must loop. */ - Curl_http_auth_act(conn); - - } while(conn->newurl); - - if(200 != k->httpcode) { - failf(data, "Received HTTP code %d from proxy after CONNECT", - k->httpcode); - return CURLE_RECV_ERROR; - } - - /* If a proxy-authorization header was used for the proxy, then we should - make sure that it isn't accidentally used for the document request - after we've connected. So let's free and clear it here. */ - Curl_safefree(conn->allocptr.proxyuserpwd); - conn->allocptr.proxyuserpwd = NULL; - - data->state.authproxy.done = TRUE; - - infof (data, "Proxy replied OK to CONNECT request\n"); - return CURLE_OK; -} - -/* - * Curl_http_connect() performs HTTP stuff to do at connect-time, called from - * the generic Curl_connect(). - */ -CURLcode Curl_http_connect(struct connectdata *conn) -{ - struct SessionHandle *data; - CURLcode result; - - data=conn->data; - - /* If we are not using a proxy and we want a secure connection, perform SSL - * initialization & connection now. If using a proxy with https, then we - * must tell the proxy to CONNECT to the host we want to talk to. Only - * after the connect has occured, can we start talking SSL - */ - - if(conn->bits.tunnel_proxy) { - - /* either SSL over proxy, or explicitly asked for */ - result = Curl_ConnectHTTPProxyTunnel(conn, FIRSTSOCKET, - conn->host.name, - conn->remote_port); - if(CURLE_OK != result) - return result; - } - - if(conn->protocol & PROT_HTTPS) { - /* now, perform the SSL initialization for this socket */ - result = Curl_SSLConnect(conn, FIRSTSOCKET); - if(result) - return result; - } - - if(conn->bits.user_passwd && !data->state.this_is_a_follow) { - /* Authorization: is requested, this is not a followed location, get the - original host name */ - if (data->state.auth_host) - /* Free to avoid leaking memory on multiple requests*/ - free(data->state.auth_host); - - data->state.auth_host = strdup(conn->host.name); - } - - return CURLE_OK; -} - -/* - * Curl_http_done() gets called from Curl_done() after a single HTTP request - * has been performed. - */ - -CURLcode Curl_http_done(struct connectdata *conn, - CURLcode status) -{ - struct SessionHandle *data; - struct HTTP *http; - (void)status; /* no use for us */ - - data=conn->data; - http=conn->proto.http; - - /* set the proper values (possibly modified on POST) */ - conn->fread = data->set.fread; /* restore */ - conn->fread_in = data->set.in; /* restore */ - - if (http == NULL) - return CURLE_OK; - - if(http->send_buffer) { - send_buffer *buff = http->send_buffer; - - free(buff->buffer); - free(buff); - http->send_buffer = NULL; /* cleaer the pointer */ - } - - if(HTTPREQ_POST_FORM == data->set.httpreq) { - conn->bytecount = http->readbytecount + http->writebytecount; - - Curl_formclean(http->sendit); /* Now free that whole lot */ - } - else if(HTTPREQ_PUT == data->set.httpreq) - conn->bytecount = http->readbytecount + http->writebytecount; - - if(!conn->bits.retry && - ((http->readbytecount + - conn->headerbytecount - - conn->deductheadercount)) <= 0) { - /* If this connection isn't simply closed to be retried, AND nothing was - read from the HTTP server (that counts), this can't be right so we - return an error here */ - failf(data, "Empty reply from server"); - return CURLE_GOT_NOTHING; - } - - return CURLE_OK; -} - -/* - * Curl_http() gets called from the generic Curl_do() function when a HTTP - * request is to be performed. This creates and sends a properly constructed - * HTTP request. - */ -CURLcode Curl_http(struct connectdata *conn) -{ - struct SessionHandle *data=conn->data; - char *buf = data->state.buffer; /* this is a short cut to the buffer */ - CURLcode result; - struct HTTP *http; - char *ppath = conn->path; - char *host = conn->host.name; - const char *te = ""; /* tranfer-encoding */ - char *ptr; - char *request; - Curl_HttpReq httpreq = data->set.httpreq; - char *addcookies = NULL; - - if(!conn->proto.http) { - /* Only allocate this struct if we don't already have it! */ - - http = (struct HTTP *)malloc(sizeof(struct HTTP)); - if(!http) - return CURLE_OUT_OF_MEMORY; - memset(http, 0, sizeof(struct HTTP)); - conn->proto.http = http; - } - else - http = conn->proto.http; - - /* We default to persistant connections */ - conn->bits.close = FALSE; - - if ( (conn->protocol&(PROT_HTTP|PROT_FTP)) && - data->set.upload) { - httpreq = HTTPREQ_PUT; - } - - /* Now set the 'request' pointer to the proper request string */ - if(data->set.customrequest) - request = data->set.customrequest; - else { - if(conn->bits.no_body) - request = (char *)"HEAD"; - else { - curlassert((httpreq > HTTPREQ_NONE) && (httpreq < HTTPREQ_LAST)); - switch(httpreq) { - case HTTPREQ_POST: - case HTTPREQ_POST_FORM: - request = (char *)"POST"; - break; - case HTTPREQ_PUT: - request = (char *)"PUT"; - break; - default: /* this should never happen */ - case HTTPREQ_GET: - request = (char *)"GET"; - break; - case HTTPREQ_HEAD: - request = (char *)"HEAD"; - break; - } - } - } - - /* The User-Agent string might have been allocated in url.c already, because - it might have been used in the proxy connect, but if we have got a header - with the user-agent string specified, we erase the previously made string - here. */ - if(checkheaders(data, "User-Agent:") && conn->allocptr.uagent) { - free(conn->allocptr.uagent); - conn->allocptr.uagent=NULL; - } - - /* setup the authentication headers */ - result = Curl_http_output_auth(conn, request, ppath, FALSE); - if(result) - return result; - - if((!data->state.authhost.done || !data->state.authproxy.done ) && - (httpreq != HTTPREQ_GET)) { - /* Until we are authenticated, we switch over to HEAD. Unless its a GET - we want to do. The explanation for this is rather long and boring, but - the point is that it can't be done otherwise without risking having to - send the POST or PUT data multiple times. */ - httpreq = HTTPREQ_HEAD; - request = (char *)"HEAD"; - conn->bits.no_body = TRUE; - conn->bits.authprobe = TRUE; /* this is a request done to probe for - authentication methods */ - } - else - conn->bits.authprobe = FALSE; - - Curl_safefree(conn->allocptr.ref); - if(data->change.referer && !checkheaders(data, "Referer:")) - conn->allocptr.ref = aprintf("Referer: %s\015\012", data->change.referer); - else - conn->allocptr.ref = NULL; - - if(data->set.cookie && !checkheaders(data, "Cookie:")) - addcookies = data->set.cookie; - - if(!conn->bits.upload_chunky && (httpreq != HTTPREQ_GET)) { - /* not a chunky transfer yet, but data is to be sent */ - ptr = checkheaders(data, "Transfer-Encoding:"); - if(ptr) { - /* Some kind of TE is requested, check if 'chunked' is chosen */ - conn->bits.upload_chunky = - Curl_compareheader(ptr, "Transfer-Encoding:", "chunked"); - te = ""; - } - } - else if(conn->bits.upload_chunky) { - /* RFC2616 section 4.4: - Messages MUST NOT include both a Content-Length header field and a - non-identity transfer-coding. If the message does include a non- - identity transfer-coding, the Content-Length MUST be ignored. */ - - if(!checkheaders(data, "Transfer-Encoding:")) { - te = "Transfer-Encoding: chunked\r\n"; - } - else { - te = ""; - conn->bits.upload_chunky = FALSE; /* transfer-encoding was disabled, - so don't chunkify this! */ - } - } - - Curl_safefree(conn->allocptr.host); - - ptr = checkheaders(data, "Host:"); - if(ptr && !data->state.this_is_a_follow) { - /* If we have a given custom Host: header, we extract the host name in - order to possibly use it for cookie reasons later on. We only allow the - custom Host: header if this is NOT a redirect, as setting Host: in the - redirected request is being out on thin ice. */ - char *start = ptr+strlen("Host:"); - while(*start && isspace((int)*start )) - start++; - ptr = start; /* start host-scanning here */ - - /* scan through the string to find the end (space or colon) */ - while(*ptr && !isspace((int)*ptr) && !(':'==*ptr)) - ptr++; - - if(ptr != start) { - size_t len=ptr-start; - conn->allocptr.cookiehost = malloc(len+1); - if(!conn->allocptr.cookiehost) - return CURLE_OUT_OF_MEMORY; - memcpy(conn->allocptr.cookiehost, start, len); - conn->allocptr.cookiehost[len]=0; - } - - conn->allocptr.host = NULL; - } - else { - /* When building Host: headers, we must put the host name within - [brackets] if the host name is a plain IPv6-address. RFC2732-style. */ - - if(((conn->protocol&PROT_HTTPS) && (conn->remote_port == PORT_HTTPS)) || - (!(conn->protocol&PROT_HTTPS) && (conn->remote_port == PORT_HTTP)) ) - /* If (HTTPS on port 443) OR (non-HTTPS on port 80) then don't include - the port number in the host string */ - conn->allocptr.host = aprintf("Host: %s%s%s\r\n", - conn->bits.ipv6_ip?"[":"", - host, - conn->bits.ipv6_ip?"]":""); - else - conn->allocptr.host = aprintf("Host: %s%s%s:%d\r\n", - conn->bits.ipv6_ip?"[":"", - host, - conn->bits.ipv6_ip?"]":"", - conn->remote_port); - - if(!conn->allocptr.host) - /* without Host: we can't make a nice request */ - return CURLE_OUT_OF_MEMORY; - } - - if (conn->bits.httpproxy && !conn->bits.tunnel_proxy) { - /* Using a proxy but does not tunnel through it */ - - /* The path sent to the proxy is in fact the entire URL. But if the remote - host is a IDN-name, we must make sure that the request we produce only - uses the encoded host name! */ - if(conn->host.dispname != conn->host.name) { - char *url = data->change.url; - char *iPtr = strstr(url, conn->host.dispname); - if(iPtr) { - /* This is where the display name starts in the URL, now replace this - part with the encoded name. TODO: This method of replacing the host - name is rather crude as I believe there's a slight risk that the - user has entered a user name or password that contain the host name - string. */ - size_t currlen = strlen(conn->host.dispname); - size_t newlen = strlen(conn->host.name); - size_t urllen = strlen(url); - - char *newurl; - - newurl = malloc(urllen + newlen - currlen + 1); - if(newurl) { - /* copy the part before the host name */ - memcpy(newurl, url, iPtr - url); - /* append the new host name instead of the old */ - memcpy(newurl + (iPtr - url), conn->host.name, newlen); - /* append the piece after the host name */ - memcpy(newurl + newlen + (iPtr - url), - iPtr + currlen, /* copy the trailing zero byte too */ - urllen - (iPtr-url) - currlen + 1); - if(data->change.url_alloc) - free(data->change.url); - data->change.url = newurl; - data->change.url_alloc = TRUE; - } - else - return CURLE_OUT_OF_MEMORY; - } - } - ppath = data->change.url; - } - if(HTTPREQ_POST_FORM == httpreq) { - /* we must build the whole darned post sequence first, so that we have - a size of the whole shebang before we start to send it */ - 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, "Pragma:")) - http->p_pragma = "Pragma: no-cache\r\n"; - - if(!checkheaders(data, "Accept:")) - http->p_accept = "Accept: */*\r\n"; - - if(( (HTTPREQ_POST == httpreq) || - (HTTPREQ_POST_FORM == httpreq) || - (HTTPREQ_PUT == httpreq) ) && - conn->resume_from) { - /********************************************************************** - * Resuming upload in HTTP means that we PUT or POST and that we have - * got a resume_from value set. The resume value has already created - * a Range: header that will be passed along. We need to "fast forward" - * the file the given number of bytes and decrease the assume upload - * file size before we continue this venture in the dark lands of HTTP. - *********************************************************************/ - - if(conn->resume_from < 0 ) { - /* - * This is meant to get the size of the present remote-file by itself. - * We don't support this now. Bail out! - */ - conn->resume_from = 0; - } - - if(conn->resume_from) { - /* do we still game? */ - curl_off_t passed=0; - - /* Now, let's read off the proper amount of bytes from the - input. If we knew it was a proper file we could've just - fseek()ed but we only have a stream here */ - do { - size_t readthisamountnow = (size_t)(conn->resume_from - passed); - size_t actuallyread; - - if(readthisamountnow > BUFSIZE) - readthisamountnow = BUFSIZE; - - actuallyread = - data->set.fread(data->state.buffer, 1, (size_t)readthisamountnow, - data->set.in); - - passed += actuallyread; - if(actuallyread != readthisamountnow) { - failf(data, "Could only read %" FORMAT_OFF_T - " bytes from the input", - passed); - return CURLE_READ_ERROR; - } - } while(passed != conn->resume_from); /* loop until done */ - - /* now, decrease the size of the read */ - if(data->set.infilesize>0) { - data->set.infilesize -= conn->resume_from; - - if(data->set.infilesize <= 0) { - failf(data, "File already completely uploaded"); - return CURLE_PARTIAL_FILE; - } - } - /* we've passed, proceed as normal */ - } - } - if(conn->bits.use_range) { - /* - * A range is selected. We use different headers whether we're downloading - * or uploading and we always let customized headers override our internal - * ones if any such are specified. - */ - if((httpreq == HTTPREQ_GET) && - !checkheaders(data, "Range:")) { - /* if a line like this was already allocated, free the previous one */ - if(conn->allocptr.rangeline) - free(conn->allocptr.rangeline); - conn->allocptr.rangeline = aprintf("Range: bytes=%s\r\n", conn->range); - } - else if((httpreq != HTTPREQ_GET) && - !checkheaders(data, "Content-Range:")) { - - if(conn->resume_from) { - /* This is because "resume" was selected */ - curl_off_t total_expected_size= - conn->resume_from + data->set.infilesize; - conn->allocptr.rangeline = - aprintf("Content-Range: bytes %s%" FORMAT_OFF_T - "/%" FORMAT_OFF_T "\r\n", - conn->range, total_expected_size-1, - total_expected_size); - } - else { - /* Range was selected and then we just pass the incoming range and - append total size */ - conn->allocptr.rangeline = - aprintf("Content-Range: bytes %s/%" FORMAT_OFF_T "\r\n", - conn->range, data->set.infilesize); - } - } - } - - { - /* Use 1.1 unless the use specificly asked for 1.0 */ - const char *httpstring= - data->set.httpversion==CURL_HTTP_VERSION_1_0?"1.0":"1.1"; - - send_buffer *req_buffer; - struct curl_slist *headers=data->set.headers; - curl_off_t postsize; /* off_t type to be able to hold a large file size */ - - /* initialize a dynamic send-buffer */ - req_buffer = add_buffer_init(); - - if(!req_buffer) - return CURLE_OUT_OF_MEMORY; - - /* add the main request stuff */ - result = - add_bufferf(req_buffer, - "%s " /* GET/HEAD/POST/PUT */ - "%s HTTP/%s\r\n" /* path + HTTP version */ - "%s" /* proxyuserpwd */ - "%s" /* userpwd */ - "%s" /* range */ - "%s" /* user agent */ - "%s" /* host */ - "%s" /* pragma */ - "%s" /* accept */ - "%s" /* accept-encoding */ - "%s" /* referer */ - "%s",/* transfer-encoding */ - - request, - ppath, - httpstring, - conn->allocptr.proxyuserpwd? - conn->allocptr.proxyuserpwd:"", - conn->allocptr.userpwd?conn->allocptr.userpwd:"", - (conn->bits.use_range && conn->allocptr.rangeline)? - conn->allocptr.rangeline:"", - (data->set.useragent && *data->set.useragent && conn->allocptr.uagent)? - conn->allocptr.uagent:"", - (conn->allocptr.host?conn->allocptr.host:""), /* Host: host */ - http->p_pragma?http->p_pragma:"", - http->p_accept?http->p_accept:"", - (data->set.encoding && *data->set.encoding && conn->allocptr.accept_encoding)? - conn->allocptr.accept_encoding:"", - (data->change.referer && conn->allocptr.ref)?conn->allocptr.ref:"" /* Referer: <data> */, - te - ); - - if(result) - return result; - - if(data->cookies || addcookies) { - struct Cookie *co=NULL; /* no cookies from start */ - int count=0; - - if(data->cookies) { - Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); - co = Curl_cookie_getlist(data->cookies, - conn->allocptr.cookiehost? - conn->allocptr.cookiehost:host, ppath, - (bool)(conn->protocol&PROT_HTTPS?TRUE:FALSE)); - Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); - } - if(co) { - struct Cookie *store=co; - /* now loop through all cookies that matched */ - while(co) { - if(co->value) { - if(0 == count) { - result = add_bufferf(req_buffer, "Cookie: "); - if(result) - break; - } - result = add_bufferf(req_buffer, - "%s%s=%s", count?"; ":"", - co->name, co->value); - if(result) - break; - count++; - } - co = co->next; /* next cookie please */ - } - Curl_cookie_freelist(store); /* free the cookie list */ - } - if(addcookies && (CURLE_OK == result)) { - if(!count) - result = add_bufferf(req_buffer, "Cookie: "); - if(CURLE_OK == result) { - result = add_bufferf(req_buffer, "%s%s", - count?"; ":"", - addcookies); - count++; - } - } - if(count && (CURLE_OK == result)) - result = add_buffer(req_buffer, "\r\n", 2); - - if(result) - return result; - } - - if(data->set.timecondition) { - struct tm *thistime; - - /* Phil Karn (Fri, 13 Apr 2001) pointed out that the If-Modified-Since - * header family should have their times set in GMT as RFC2616 defines: - * "All HTTP date/time stamps MUST be represented in Greenwich Mean Time - * (GMT), without exception. For the purposes of HTTP, GMT is exactly - * equal to UTC (Coordinated Universal Time)." (see page 20 of RFC2616). - */ - -#ifdef HAVE_GMTIME_R - /* thread-safe version */ - struct tm keeptime; - thistime = (struct tm *)gmtime_r(&data->set.timevalue, &keeptime); -#else - thistime = gmtime(&data->set.timevalue); -#endif - -#ifdef HAVE_STRFTIME - /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */ - strftime(buf, BUFSIZE-1, "%a, %d %b %Y %H:%M:%S GMT", thistime); -#else - /* TODO: Right, we *could* write a replacement here */ - strcpy(buf, "no strftime() support"); -#endif - switch(data->set.timecondition) { - case CURL_TIMECOND_IFMODSINCE: - default: - result = add_bufferf(req_buffer, - "If-Modified-Since: %s\r\n", buf); - break; - case CURL_TIMECOND_IFUNMODSINCE: - result = add_bufferf(req_buffer, - "If-Unmodified-Since: %s\r\n", buf); - break; - case CURL_TIMECOND_LASTMOD: - result = add_bufferf(req_buffer, - "Last-Modified: %s\r\n", buf); - break; - } - if(result) - return result; - } - - while(headers) { - ptr = strchr(headers->data, ':'); - if(ptr) { - /* we require a colon for this to be a true header */ - - ptr++; /* pass the colon */ - while(*ptr && isspace((int)*ptr)) - ptr++; - - if(*ptr) { - /* only send this if the contents was non-blank */ - - result = add_bufferf(req_buffer, "%s\r\n", headers->data); - if(result) - return result; - } - } - headers = headers->next; - } - - http->postdata = NULL; /* nothing to post at this point */ - Curl_pgrsSetUploadSize(data, 0); /* upload size is 0 atm */ - - /* If 'authdone' is FALSE, we must not set the write socket index to the - Curl_transfer() call below, as we're not ready to actually upload any - data yet. */ - - switch(httpreq) { - - case HTTPREQ_POST_FORM: - if(Curl_FormInit(&http->form, http->sendit)) { - failf(data, "Internal HTTP POST error!"); - return CURLE_HTTP_POST_ERROR; - } - - /* set the read function to read from the generated form data */ - conn->fread = (curl_read_callback)Curl_FormReader; - conn->fread_in = &http->form; - - http->sending = HTTPSEND_BODY; - - if(!conn->bits.upload_chunky) { - /* only add Content-Length if not uploading chunked */ - result = add_bufferf(req_buffer, - "Content-Length: %" FORMAT_OFF_T "\r\n", - http->postsize); - if(result) - return result; - } - - if(!checkheaders(data, "Expect:")) { - /* if not disabled explicitly we add a Expect: 100-continue - to the headers which actually speeds up post operations (as - there is one packet coming back from the web server) */ - result = add_bufferf(req_buffer, - "Expect: 100-continue\r\n"); - if(result) - return result; - data->set.expect100header = TRUE; - } - - if(!checkheaders(data, "Content-Type:")) { - /* Get Content-Type: line from Curl_formpostheader. - - The Content-Type header line also contains the MIME boundary - string etc why disabling this header is likely to not make things - work, but we support disabling it anyway. - */ - char *contentType; - size_t linelength=0; - contentType = Curl_formpostheader((void *)&http->form, - &linelength); - if(!contentType) { - failf(data, "Could not get Content-Type header line!"); - return CURLE_HTTP_POST_ERROR; - } - result = add_buffer(req_buffer, contentType, linelength); - if(result) - return result; - } - - /* make the request end in a true CRLF */ - result = add_buffer(req_buffer, "\r\n", 2); - if(result) - return result; - - /* set upload size to the progress meter */ - Curl_pgrsSetUploadSize(data, http->postsize); - - /* fire away the whole request to the server */ - result = add_buffer_send(req_buffer, conn, - &data->info.request_size); - if(result) - failf(data, "Failed sending POST request"); - else - /* setup variables for the upcoming transfer */ - result = Curl_Transfer(conn, FIRSTSOCKET, -1, TRUE, - &http->readbytecount, - FIRSTSOCKET, - &http->writebytecount); - if(result) { - Curl_formclean(http->sendit); /* free that whole lot */ - return result; - } - break; - - case HTTPREQ_PUT: /* Let's PUT the data to the server! */ - - if((data->set.infilesize>0) && !conn->bits.upload_chunky) { - /* only add Content-Length if not uploading chunked */ - result = add_bufferf(req_buffer, - "Content-Length: %" FORMAT_OFF_T "\r\n", /* size */ - data->set.infilesize ); - if(result) - return result; - } - - if(!checkheaders(data, "Expect:")) { - /* if not disabled explicitly we add a Expect: 100-continue - to the headers which actually speeds up post operations (as - there is one packet coming back from the web server) */ - result = add_bufferf(req_buffer, - "Expect: 100-continue\r\n"); - if(result) - return result; - data->set.expect100header = TRUE; - } - - result = add_buffer(req_buffer, "\r\n", 2); /* end of headers */ - if(result) - return result; - - /* set the upload size to the progress meter */ - Curl_pgrsSetUploadSize(data, data->set.infilesize); - - /* this sends the buffer and frees all the buffer resources */ - result = add_buffer_send(req_buffer, conn, - &data->info.request_size); - if(result) - failf(data, "Failed sending POST request"); - else - /* prepare for transfer */ - result = Curl_Transfer(conn, FIRSTSOCKET, -1, TRUE, - &http->readbytecount, - FIRSTSOCKET, - &http->writebytecount); - if(result) - return result; - break; - - case HTTPREQ_POST: - /* this is the simple POST, using x-www-form-urlencoded style */ - - /* store the size of the postfields */ - postsize = data->set.postfieldsize? - data->set.postfieldsize: - (data->set.postfields?(curl_off_t)strlen(data->set.postfields):0); - - if(!conn->bits.upload_chunky) { - /* We only set Content-Length and allow a custom Content-Length if - we don't upload data chunked, as RFC2616 forbids us to set both - kinds of headers (Transfer-Encoding: chunked and Content-Length) */ - - if(!checkheaders(data, "Content-Length:")) { - /* we allow replacing this header, although it isn't very wise to - actually set your own */ - result = add_bufferf(req_buffer, - "Content-Length: %" FORMAT_OFF_T"\r\n", - postsize); - if(result) - return result; - } - } - - if(!checkheaders(data, "Content-Type:")) { - result = add_bufferf(req_buffer, - "Content-Type: application/x-www-form-urlencoded\r\n"); - if(result) - return result; - } - - if(data->set.postfields) { - - if((data->state.authhost.done || data->state.authproxy.done ) - && (postsize < (100*1024))) { - /* If we're not done with the authentication phase, we don't expect - to actually send off any data yet. Hence, we delay the sending of - the body until we receive that friendly 100-continue response */ - - /* The post data is less than 100K, then append it to the header. - This limit is no magic limit but only set to prevent really huge - POSTs to get the data duplicated with malloc() and family. */ - - result = add_buffer(req_buffer, "\r\n", 2); /* end of headers! */ - if(result) - return result; - - if(!conn->bits.upload_chunky) { - /* We're not sending it 'chunked', append it to the request - already now to reduce the number if send() calls */ - result = add_buffer(req_buffer, data->set.postfields, - (size_t)postsize); - } - else { - /* Append the POST data chunky-style */ - result = add_bufferf(req_buffer, "%x\r\n", (int)postsize); - if(CURLE_OK == result) - result = add_buffer(req_buffer, data->set.postfields, - (size_t)postsize); - if(CURLE_OK == result) - result = add_buffer(req_buffer, - "\r\n0\r\n\r\n", 7); /* end of a chunked - transfer stream */ - } - if(result) - return result; - } - else { - /* A huge POST coming up, do data separate from the request */ - http->postsize = postsize; - http->postdata = data->set.postfields; - - http->sending = HTTPSEND_BODY; - - conn->fread = (curl_read_callback)readmoredata; - conn->fread_in = (void *)conn; - - /* set the upload size to the progress meter */ - Curl_pgrsSetUploadSize(data, http->postsize); - - if(!checkheaders(data, "Expect:")) { - /* if not disabled explicitly we add a Expect: 100-continue to the - headers which actually speeds up post operations (as there is - one packet coming back from the web server) */ - add_bufferf(req_buffer, - "Expect: 100-continue\r\n"); - data->set.expect100header = TRUE; - } - - add_buffer(req_buffer, "\r\n", 2); /* end of headers! */ - } - } - else { - add_buffer(req_buffer, "\r\n", 2); /* end of headers! */ - - /* set the upload size to the progress meter */ - Curl_pgrsSetUploadSize(data, data->set.infilesize); - - /* set the pointer to mark that we will send the post body using - the read callback */ - http->postdata = (char *)&http->postdata; - } - /* issue the request */ - result = add_buffer_send(req_buffer, conn, - &data->info.request_size); - - if(result) - failf(data, "Failed sending HTTP POST request"); - else - result = - Curl_Transfer(conn, FIRSTSOCKET, -1, TRUE, - &http->readbytecount, - http->postdata?FIRSTSOCKET:-1, - http->postdata?&http->writebytecount:NULL); - break; - - default: - add_buffer(req_buffer, "\r\n", 2); - - /* issue the request */ - result = add_buffer_send(req_buffer, conn, - &data->info.request_size); - - if(result) - failf(data, "Failed sending HTTP request"); - else - /* HTTP GET/HEAD download: */ - result = Curl_Transfer(conn, FIRSTSOCKET, -1, TRUE, - &http->readbytecount, - http->postdata?FIRSTSOCKET:-1, - http->postdata?&http->writebytecount:NULL); - } - if(result) - return result; - } - - return CURLE_OK; -} -#endif diff --git a/Source/CTest/Curl/http.h b/Source/CTest/Curl/http.h deleted file mode 100644 index 80c1807..0000000 --- a/Source/CTest/Curl/http.h +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef __HTTP_H -#define __HTTP_H - -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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$ - ***************************************************************************/ -#ifndef CURL_DISABLE_HTTP -bool Curl_compareheader(char *headerline, /* line to check */ - const char *header, /* header keyword _with_ colon */ - const char *content); /* content string to find */ - -/* ftp can use this as well */ -CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn, - int tunnelsocket, - char *hostname, int remote_port); - -/* protocol-specific functions set up to be called by the main engine */ -CURLcode Curl_http(struct connectdata *conn); -CURLcode Curl_http_done(struct connectdata *, CURLcode); -CURLcode Curl_http_connect(struct connectdata *conn); - -/* The following functions are defined in http_chunks.c */ -void Curl_httpchunk_init(struct connectdata *conn); -CHUNKcode Curl_httpchunk_read(struct connectdata *conn, char *datap, - ssize_t length, ssize_t *wrote); - -/* These functions are in http.c */ -void Curl_http_auth_stage(struct SessionHandle *data, int stage); -CURLcode Curl_http_input_auth(struct connectdata *conn, - int httpcode, char *header); -CURLcode Curl_http_auth_act(struct connectdata *conn); - -int Curl_http_should_fail(struct connectdata *conn); - -/* If only the PICKNONE bit is set, there has been a round-trip and we - selected to use no auth at all. Ie, we actively select no auth, as opposed - to not having one selected. The other CURLAUTH_* defines are present in the - public curl/curl.h header. */ -#define CURLAUTH_PICKNONE (1<<30) /* don't use auth */ - -#endif -#endif diff --git a/Source/CTest/Curl/http_chunks.c b/Source/CTest/Curl/http_chunks.c deleted file mode 100644 index 02fdfc5..0000000 --- a/Source/CTest/Curl/http_chunks.c +++ /dev/null @@ -1,264 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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" - -#ifndef CURL_DISABLE_HTTP -/* -- WIN32 approved -- */ -#include <stdio.h> -#include <string.h> -#include <stdarg.h> -#include <stdlib.h> -#include <ctype.h> - -#include "urldata.h" /* it includes http_chunks.h */ -#include "sendf.h" /* for the client write stuff */ - -#include "content_encoding.h" -#include "http.h" -#include "curl_memory.h" - -#define _MPRINTF_REPLACE /* use our functions only */ -#include <curl/mprintf.h> - -/* The last #include file should be: */ -#include "memdebug.h" - -/* - * Chunk format (simplified): - * - * <HEX SIZE>[ chunk extension ] CRLF - * <DATA> CRLF - * - * Highlights from RFC2616 section 3.6 say: - - The chunked encoding modifies the body of a message in order to - transfer it as a series of chunks, each with its own size indicator, - followed by an OPTIONAL trailer containing entity-header fields. This - allows dynamically produced content to be transferred along with the - information necessary for the recipient to verify that it has - received the full message. - - Chunked-Body = *chunk - last-chunk - trailer - CRLF - - chunk = chunk-size [ chunk-extension ] CRLF - chunk-data CRLF - chunk-size = 1*HEX - last-chunk = 1*("0") [ chunk-extension ] CRLF - - chunk-extension= *( ";" chunk-ext-name [ "=" chunk-ext-val ] ) - chunk-ext-name = token - chunk-ext-val = token | quoted-string - chunk-data = chunk-size(OCTET) - trailer = *(entity-header CRLF) - - The chunk-size field is a string of hex digits indicating the size of - the chunk. The chunked encoding is ended by any chunk whose size is - zero, followed by the trailer, which is terminated by an empty line. - - */ - - -void Curl_httpchunk_init(struct connectdata *conn) -{ - struct Curl_chunker *chunk = &conn->proto.http->chunk; - chunk->hexindex=0; /* start at 0 */ - chunk->dataleft=0; /* no data left yet! */ - chunk->state = CHUNK_HEX; /* we get hex first! */ -} - -/* - * chunk_read() returns a OK for normal operations, or a positive return code - * for errors. STOP means this sequence of chunks is complete. The 'wrote' - * argument is set to tell the caller how many bytes we actually passed to the - * client (for byte-counting and whatever). - * - * The states and the state-machine is further explained in the header file. - */ -CHUNKcode Curl_httpchunk_read(struct connectdata *conn, - char *datap, - ssize_t datalen, - ssize_t *wrotep) -{ - CURLcode result=CURLE_OK; - struct Curl_chunker *ch = &conn->proto.http->chunk; - struct Curl_transfer_keeper *k = &conn->keep; - size_t piece; - size_t length = (size_t)datalen; - size_t *wrote = (size_t *)wrotep; - - *wrote = 0; /* nothing's written yet */ - - while(length) { - switch(ch->state) { - case CHUNK_HEX: - if(isxdigit((int)*datap)) { - if(ch->hexindex < MAXNUM_SIZE) { - ch->hexbuffer[ch->hexindex] = *datap; - datap++; - length--; - ch->hexindex++; - } - else { - return CHUNKE_TOO_LONG_HEX; /* longer hex than we support */ - } - } - else { - if(0 == ch->hexindex) { - /* This is illegal data, we received junk where we expected - a hexadecimal digit. */ - return CHUNKE_ILLEGAL_HEX; - } - /* length and datap are unmodified */ - ch->hexbuffer[ch->hexindex]=0; - ch->datasize=strtoul(ch->hexbuffer, NULL, 16); - ch->state = CHUNK_POSTHEX; - } - break; - - case CHUNK_POSTHEX: - /* In this state, we're waiting for CRLF to arrive. We support - this to allow so called chunk-extensions to show up here - before the CRLF comes. */ - if(*datap == '\r') - ch->state = CHUNK_CR; - length--; - datap++; - break; - - case CHUNK_CR: - /* waiting for the LF */ - if(*datap == '\n') { - /* we're now expecting data to come, unless size was zero! */ - if(0 == ch->datasize) { - ch->state = CHUNK_STOP; /* stop reading! */ - if(1 == length) { - /* This was the final byte, return right now */ - return CHUNKE_STOP; - } - } - else - ch->state = CHUNK_DATA; - } - else - /* previously we got a fake CR, go back to CR waiting! */ - ch->state = CHUNK_CR; - datap++; - length--; - break; - - case CHUNK_DATA: - /* we get pure and fine data - - We expect another 'datasize' of data. We have 'length' right now, - it can be more or less than 'datasize'. Get the smallest piece. - */ - piece = (ch->datasize >= length)?length:ch->datasize; - - /* Write the data portion available */ -#ifdef HAVE_LIBZ - switch (conn->keep.content_encoding) { - case IDENTITY: -#endif - if(!k->ignorebody) - result = Curl_client_write(conn->data, CLIENTWRITE_BODY, datap, - piece); -#ifdef HAVE_LIBZ - break; - - case DEFLATE: - /* update conn->keep.str to point to the chunk data. */ - conn->keep.str = datap; - result = Curl_unencode_deflate_write(conn->data, &conn->keep, - (ssize_t)piece); - break; - - case GZIP: - /* update conn->keep.str to point to the chunk data. */ - conn->keep.str = datap; - result = Curl_unencode_gzip_write(conn->data, &conn->keep, - (ssize_t)piece); - break; - - case COMPRESS: - default: - failf (conn->data, - "Unrecognized content encoding type. " - "libcurl understands `identity', `deflate' and `gzip' " - "content encodings."); - return CHUNKE_BAD_ENCODING; - } -#endif - - if(result) - return CHUNKE_WRITE_ERROR; - - *wrote += piece; - - ch->datasize -= piece; /* decrease amount left to expect */ - datap += piece; /* move read pointer forward */ - length -= piece; /* decrease space left in this round */ - - if(0 == ch->datasize) - /* end of data this round, we now expect a trailing CRLF */ - ch->state = CHUNK_POSTCR; - break; - - case CHUNK_POSTCR: - if(*datap == '\r') { - ch->state = CHUNK_POSTLF; - datap++; - length--; - } - else - return CHUNKE_BAD_CHUNK; - break; - - case CHUNK_POSTLF: - if(*datap == '\n') { - /* - * The last one before we go back to hex state and start all - * over. - */ - Curl_httpchunk_init(conn); - datap++; - length--; - } - else - return CHUNKE_BAD_CHUNK; - break; - - case CHUNK_STOP: - /* If we arrive here, there is data left in the end of the buffer - even if there's no more chunks to read */ - ch->dataleft = length; - return CHUNKE_STOP; /* return stop */ - default: - return CHUNKE_STATE_ERROR; - } - } - return CHUNKE_OK; -} -#endif /* CURL_DISABLE_HTTP */ diff --git a/Source/CTest/Curl/http_chunks.h b/Source/CTest/Curl/http_chunks.h deleted file mode 100644 index 26b79de..0000000 --- a/Source/CTest/Curl/http_chunks.h +++ /dev/null @@ -1,88 +0,0 @@ -#ifndef __HTTP_CHUNKS_H -#define __HTTP_CHUNKS_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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$ - ***************************************************************************/ -/* - * The longest possible hexadecimal number we support in a chunked transfer. - * Weird enough, RFC2616 doesn't set a maximum size! Since we use strtoul() - * to convert it, we "only" support 2^32 bytes chunk data. - */ -#define MAXNUM_SIZE 16 - -typedef enum { - CHUNK_FIRST, /* never use */ - - /* In this we await and buffer all hexadecimal digits until we get one - that isn't a hexadecimal digit. When done, we go POSTHEX */ - CHUNK_HEX, - - /* We have received the hexadecimal digit and we eat all characters until - we get a CRLF pair. When we see a CR we go to the CR state. */ - CHUNK_POSTHEX, - - /* A single CR has been found and we should get a LF right away in this - state or we go back to POSTHEX. When LF is received, we go to DATA. - If the size given was zero, we set state to STOP and return. */ - CHUNK_CR, - - /* We eat the amount of data specified. When done, we move on to the - POST_CR state. */ - CHUNK_DATA, - - /* POSTCR should get a CR and nothing else, then move to POSTLF */ - CHUNK_POSTCR, - - /* POSTLF should get a LF and nothing else, then move back to HEX as - the CRLF combination marks the end of a chunk */ - CHUNK_POSTLF, - - /* This is mainly used to really mark that we're out of the game. - NOTE: that there's a 'dataleft' field in the struct that will tell how - many bytes that were not passed to the client in the end of the last - buffer! */ - CHUNK_STOP, - - CHUNK_LAST /* never use */ -} ChunkyState; - -typedef enum { - CHUNKE_STOP = -1, - CHUNKE_OK = 0, - CHUNKE_TOO_LONG_HEX = 1, - CHUNKE_ILLEGAL_HEX, - CHUNKE_BAD_CHUNK, - CHUNKE_WRITE_ERROR, - CHUNKE_STATE_ERROR, - CHUNKE_BAD_ENCODING, - CHUNKE_LAST -} CHUNKcode; - -struct Curl_chunker { - char hexbuffer[ MAXNUM_SIZE + 1]; - int hexindex; - ChunkyState state; - size_t datasize; - size_t dataleft; /* untouched data amount at the end of the last buffer */ -}; - -#endif diff --git a/Source/CTest/Curl/http_digest.c b/Source/CTest/Curl/http_digest.c deleted file mode 100644 index b997ccb..0000000 --- a/Source/CTest/Curl/http_digest.c +++ /dev/null @@ -1,482 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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" - -#ifndef CURL_DISABLE_HTTP -/* -- WIN32 approved -- */ -#include <stdio.h> -#include <string.h> -#include <stdarg.h> -#include <stdlib.h> -#include <ctype.h> - -#include "urldata.h" -#include "sendf.h" -#include "strequal.h" -#include "base64.h" -#include "md5.h" -#include "http_digest.h" -#include "strtok.h" -#include "url.h" /* for Curl_safefree() */ -#include "curl_memory.h" - -#define _MPRINTF_REPLACE /* use our functions only */ -#include <curl/mprintf.h> - -/* The last #include file should be: */ -#include "memdebug.h" - -/* Test example headers: - -WWW-Authenticate: Digest realm="testrealm", nonce="1053604598" -Proxy-Authenticate: Digest realm="testrealm", nonce="1053604598" - -*/ - -CURLdigest Curl_input_digest(struct connectdata *conn, - bool proxy, - char *header) /* rest of the *-authenticate: - header */ -{ - bool more = TRUE; - char *token; - char *tmp; - bool foundAuth = FALSE; - bool foundAuthInt = FALSE; - struct SessionHandle *data=conn->data; - bool before = FALSE; /* got a nonce before */ - struct digestdata *d; - - if(proxy) { - d = &data->state.proxydigest; - } - else { - d = &data->state.digest; - } - - /* skip initial whitespaces */ - while(*header && isspace((int)*header)) - header++; - - if(checkprefix("Digest", header)) { - header += strlen("Digest"); - - /* If we already have received a nonce, keep that in mind */ - if(d->nonce) - before = TRUE; - - /* clear off any former leftovers and init to defaults */ - Curl_digest_cleanup_one(d); - - while(more) { - char value[32]; - char content[128]; - size_t totlen; - - while(*header && isspace((int)*header)) - header++; - - /* how big can these strings be? */ - if((2 == sscanf(header, "%31[^=]=\"%127[^\"]\"", - value, content)) || - /* try the same scan but without quotes around the content but don't - include the possibly trailing comma */ - (2 == sscanf(header, "%31[^=]=%127[^,]", - value, content)) ) { - if(strequal(value, "nonce")) { - d->nonce = strdup(content); - if(!d->nonce) - return CURLDIGEST_NOMEM; - } - else if(strequal(value, "stale")) { - if(strequal(content, "true")) { - d->stale = TRUE; - d->nc = 1; /* we make a new nonce now */ - } - } - else if(strequal(value, "realm")) { - d->realm = strdup(content); - if(!d->realm) - return CURLDIGEST_NOMEM; - } - else if(strequal(value, "opaque")) { - d->opaque = strdup(content); - if(!d->opaque) - return CURLDIGEST_NOMEM; - } - else if(strequal(value, "qop")) { - char *tok_buf; - /* tokenize the list and choose auth if possible, use a temporary - clone of the buffer since strtok_r() ruins it */ - tmp = strdup(content); - if(!tmp) - return CURLDIGEST_NOMEM; - token = strtok_r(tmp, ",", &tok_buf); - while (token != NULL) { - if (strequal(token, "auth")) { - foundAuth = TRUE; - } - else if (strequal(token, "auth-int")) { - foundAuthInt = TRUE; - } - token = strtok_r(NULL, ",", &tok_buf); - } - free(tmp); - /*select only auth o auth-int. Otherwise, ignore*/ - if (foundAuth) { - d->qop = strdup("auth"); - if(!d->qop) - return CURLDIGEST_NOMEM; - } - else if (foundAuthInt) { - d->qop = strdup("auth-int"); - if(!d->qop) - return CURLDIGEST_NOMEM; - } - } - else if(strequal(value, "algorithm")) { - d->algorithm = strdup(content); - if(!d->algorithm) - return CURLDIGEST_NOMEM; - if(strequal(content, "MD5-sess")) - d->algo = CURLDIGESTALGO_MD5SESS; - else if(strequal(content, "MD5")) - d->algo = CURLDIGESTALGO_MD5; - else - return CURLDIGEST_BADALGO; - } - else { - /* unknown specifier, ignore it! */ - } - totlen = strlen(value)+strlen(content)+1; - - if(header[strlen(value)+1] == '\"') - /* the contents were within quotes, then add 2 for them to the - length */ - totlen += 2; - } - else - break; /* we're done here */ - - header += totlen; - if(',' == *header) - /* allow the list to be comma-separated */ - header++; - } - /* We had a nonce since before, and we got another one now without - 'stale=true'. This means we provided bad credentials in the previous - request */ - if(before && !d->stale) - return CURLDIGEST_BAD; - - /* We got this header without a nonce, that's a bad Digest line! */ - if(!d->nonce) - return CURLDIGEST_BAD; - } - else - /* else not a digest, get out */ - return CURLDIGEST_NONE; - - return CURLDIGEST_FINE; -} - -/* convert md5 chunk to RFC2617 (section 3.1.3) -suitable ascii string*/ -static void md5_to_ascii(unsigned char *source, /* 16 bytes */ - unsigned char *dest) /* 33 bytes */ -{ - int i; - for(i=0; i<16; i++) - snprintf((char *)&dest[i*2], 3, "%02x", source[i]); -} - -CURLcode Curl_output_digest(struct connectdata *conn, - bool proxy, - unsigned char *request, - unsigned char *uripath) -{ - /* We have a Digest setup for this, use it! Now, to get all the details for - this sorted out, I must urge you dear friend to read up on the RFC2617 - section 3.2.2, */ - unsigned char md5buf[16]; /* 16 bytes/128 bits */ - unsigned char request_digest[33]; - unsigned char *md5this; - unsigned char *ha1; - unsigned char ha2[33];/* 32 digits and 1 zero byte */ - char cnoncebuf[7]; - char *cnonce; - char *tmp; - struct timeval now; - - char **allocuserpwd; - char *userp; - char *passwdp; - struct auth *authp; - - struct SessionHandle *data = conn->data; - struct digestdata *d; - - if(proxy) { - d = &data->state.proxydigest; - allocuserpwd = &conn->allocptr.proxyuserpwd; - userp = conn->proxyuser; - passwdp = conn->proxypasswd; - authp = &data->state.authproxy; - } - else { - d = &data->state.digest; - allocuserpwd = &conn->allocptr.userpwd; - userp = conn->user; - passwdp = conn->passwd; - authp = &data->state.authhost; - } - - /* not set means empty */ - if(!userp) - userp=(char *)""; - - if(!passwdp) - passwdp=(char *)""; - - if(!d->nonce) { - authp->done = FALSE; - return CURLE_OK; - } - authp->done = TRUE; - - if(!d->nc) - d->nc = 1; - - if(!d->cnonce) { - /* Generate a cnonce */ - now = Curl_tvnow(); - snprintf(cnoncebuf, sizeof(cnoncebuf), "%06ld", now.tv_sec); - if(Curl_base64_encode(cnoncebuf, strlen(cnoncebuf), &cnonce)) - d->cnonce = cnonce; - else - return CURLE_OUT_OF_MEMORY; - } - - /* - if the algorithm is "MD5" or unspecified (which then defaults to MD5): - - A1 = unq(username-value) ":" unq(realm-value) ":" passwd - - if the algorithm is "MD5-sess" then: - - A1 = H( unq(username-value) ":" unq(realm-value) ":" passwd ) - ":" unq(nonce-value) ":" unq(cnonce-value) - */ - - md5this = (unsigned char *) - aprintf("%s:%s:%s", userp, d->realm, passwdp); - if(!md5this) - return CURLE_OUT_OF_MEMORY; - Curl_md5it(md5buf, md5this); - free(md5this); /* free this again */ - - ha1 = (unsigned char *)malloc(33); /* 32 digits and 1 zero byte */ - if(!ha1) - return CURLE_OUT_OF_MEMORY; - - md5_to_ascii(md5buf, ha1); - - if(d->algo == CURLDIGESTALGO_MD5SESS) { - /* nonce and cnonce are OUTSIDE the hash */ - tmp = aprintf("%s:%s:%s", ha1, d->nonce, d->cnonce); - free(ha1); - if(!tmp) - return CURLE_OUT_OF_MEMORY; - ha1 = (unsigned char *)tmp; - } - - /* - If the "qop" directive's value is "auth" or is unspecified, then A2 is: - - A2 = Method ":" digest-uri-value - - If the "qop" value is "auth-int", then A2 is: - - A2 = Method ":" digest-uri-value ":" H(entity-body) - - (The "Method" value is the HTTP request method as specified in section - 5.1.1 of RFC 2616) - */ - - md5this = (unsigned char *)aprintf("%s:%s", request, uripath); - if(!md5this) { - free(ha1); - return CURLE_OUT_OF_MEMORY; - } - - if (d->qop && strequal(d->qop, "auth-int")) { - /* We don't support auth-int at the moment. I can't see a easy way to get - entity-body here */ - /* TODO: Append H(entity-body)*/ - } - Curl_md5it(md5buf, md5this); - free(md5this); /* free this again */ - md5_to_ascii(md5buf, ha2); - - if (d->qop) { - md5this = (unsigned char *)aprintf("%s:%s:%08x:%s:%s:%s", - ha1, - d->nonce, - d->nc, - d->cnonce, - d->qop, - ha2); - } - else { - md5this = (unsigned char *)aprintf("%s:%s:%s", - ha1, - d->nonce, - ha2); - } - free(ha1); - if(!md5this) - return CURLE_OUT_OF_MEMORY; - - Curl_md5it(md5buf, md5this); - free(md5this); /* free this again */ - md5_to_ascii(md5buf, request_digest); - - /* for test case 64 (snooped from a Mozilla 1.3a request) - - Authorization: Digest username="testuser", realm="testrealm", \ - nonce="1053604145", uri="/64", response="c55f7f30d83d774a3d2dcacf725abaca" - */ - - Curl_safefree(*allocuserpwd); - - if (d->qop) { - *allocuserpwd = - aprintf( "%sAuthorization: Digest " - "username=\"%s\", " - "realm=\"%s\", " - "nonce=\"%s\", " - "uri=\"%s\", " - "cnonce=\"%s\", " - "nc=%08x, " - "qop=\"%s\", " - "response=\"%s\"", - proxy?"Proxy-":"", - userp, - d->realm, - d->nonce, - uripath, /* this is the PATH part of the URL */ - d->cnonce, - d->nc, - d->qop, - request_digest); - - if(strequal(d->qop, "auth")) - d->nc++; /* The nc (from RFC) has to be a 8 hex digit number 0 padded - which tells to the server how many times you are using the - same nonce in the qop=auth mode. */ - } - else { - *allocuserpwd = - aprintf( "%sAuthorization: Digest " - "username=\"%s\", " - "realm=\"%s\", " - "nonce=\"%s\", " - "uri=\"%s\", " - "response=\"%s\"", - proxy?"Proxy-":"", - userp, - d->realm, - d->nonce, - uripath, /* this is the PATH part of the URL */ - request_digest); - } - if(!*allocuserpwd) - return CURLE_OUT_OF_MEMORY; - - /* Add optional fields */ - if(d->opaque) { - /* append opaque */ - tmp = aprintf("%s, opaque=\"%s\"", *allocuserpwd, d->opaque); - if(!tmp) - return CURLE_OUT_OF_MEMORY; - free(*allocuserpwd); - *allocuserpwd = tmp; - } - - if(d->algorithm) { - /* append algorithm */ - tmp = aprintf("%s, algorithm=\"%s\"", *allocuserpwd, d->algorithm); - if(!tmp) - return CURLE_OUT_OF_MEMORY; - free(*allocuserpwd); - *allocuserpwd = tmp; - } - - /* append CRLF to the userpwd header */ - tmp = (char*) realloc(*allocuserpwd, strlen(*allocuserpwd) + 3 + 1); - if(!tmp) - return CURLE_OUT_OF_MEMORY; - strcat(tmp, "\r\n"); - *allocuserpwd = tmp; - - return CURLE_OK; -} - -void Curl_digest_cleanup_one(struct digestdata *d) -{ - if(d->nonce) - free(d->nonce); - d->nonce = NULL; - - if(d->cnonce) - free(d->cnonce); - d->cnonce = NULL; - - if(d->realm) - free(d->realm); - d->realm = NULL; - - if(d->opaque) - free(d->opaque); - d->opaque = NULL; - - if(d->qop) - free(d->qop); - d->qop = NULL; - - if(d->algorithm) - free(d->algorithm); - d->algorithm = NULL; - - d->nc = 0; - d->algo = CURLDIGESTALGO_MD5; /* default algorithm */ - d->stale = FALSE; /* default means normal, not stale */ -} - - -void Curl_digest_cleanup(struct SessionHandle *data) -{ - Curl_digest_cleanup_one(&data->state.digest); - Curl_digest_cleanup_one(&data->state.proxydigest); -} - -#endif diff --git a/Source/CTest/Curl/http_digest.h b/Source/CTest/Curl/http_digest.h deleted file mode 100644 index b4fca06..0000000 --- a/Source/CTest/Curl/http_digest.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef __HTTP_DIGEST_H -#define __HTTP_DIGEST_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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$ - ***************************************************************************/ - -typedef enum { - CURLDIGEST_NONE, /* not a digest */ - CURLDIGEST_BAD, /* a digest, but one we don't like */ - CURLDIGEST_BADALGO, /* unsupported algorithm requested */ - CURLDIGEST_NOMEM, - CURLDIGEST_FINE, /* a digest we act on */ - - CURLDIGEST_LAST /* last entry in this enum, don't use */ -} CURLdigest; - -enum { - CURLDIGESTALGO_MD5, - CURLDIGESTALGO_MD5SESS -}; - -/* this is for digest header input */ -CURLdigest Curl_input_digest(struct connectdata *conn, - bool proxy, char *header); - -/* this is for creating digest header output */ -CURLcode Curl_output_digest(struct connectdata *conn, - bool proxy, - unsigned char *request, - unsigned char *uripath); -void Curl_digest_cleanup(struct SessionHandle *data); -void Curl_digest_cleanup_one(struct digestdata *dig); - -#endif diff --git a/Source/CTest/Curl/http_negotiate.c b/Source/CTest/Curl/http_negotiate.c deleted file mode 100644 index 62a23f1..0000000 --- a/Source/CTest/Curl/http_negotiate.c +++ /dev/null @@ -1,332 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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_GSSAPI -#ifdef HAVE_GSSMIT -#define GSS_C_NT_HOSTBASED_SERVICE gss_nt_service_name -#endif - -#ifndef CURL_DISABLE_HTTP - /* -- WIN32 approved -- */ -#include <stdio.h> -#include <string.h> -#include <stdarg.h> -#include <stdlib.h> -#include <ctype.h> -#include <errno.h> - -#include "urldata.h" -#include "sendf.h" -#include "strequal.h" -#include "base64.h" -#include "http_negotiate.h" -#include "curl_memory.h" - -#define _MPRINTF_REPLACE /* use our functions only */ -#include <curl/mprintf.h> - -/* The last #include file should be: */ -#include "memdebug.h" - -static int -get_gss_name(struct connectdata *conn, gss_name_t *server) -{ - struct negotiatedata *neg_ctx = &conn->data->state.negotiate; - OM_uint32 major_status, minor_status; - gss_buffer_desc token = GSS_C_EMPTY_BUFFER; - char name[2048]; - const char* service; - - /* GSSAPI implementation by Globus (known as GSI) requires the name to be - of form "<service>/<fqdn>" instead of <service>@<fqdn> (ie. slash instead - of at-sign). Also GSI servers are often identified as 'host' not 'khttp'. - Change following lines if you want to use GSI */ - - /* IIS uses the <service>@<fqdn> form but uses 'http' as the service name */ - - if (neg_ctx->gss) - service = "KHTTP"; - else - service = "HTTP"; - - token.length = strlen(service) + 1 + strlen(conn->host.name) + 1; - if (token.length + 1 > sizeof(name)) - return EMSGSIZE; - - snprintf(name, sizeof(name), "%s@%s", service, conn->host.name); - - token.value = (void *) name; - major_status = gss_import_name(&minor_status, - &token, - GSS_C_NT_HOSTBASED_SERVICE, - server); - - return GSS_ERROR(major_status) ? -1 : 0; -} - -static void -log_gss_error(struct connectdata *conn, OM_uint32 error_status, char *prefix) -{ - OM_uint32 maj_stat, min_stat; - OM_uint32 msg_ctx = 0; - gss_buffer_desc status_string; - char buf[1024]; - size_t len; - - snprintf(buf, sizeof(buf), "%s", prefix); - len = strlen(buf); - do { - maj_stat = gss_display_status (&min_stat, - error_status, - GSS_C_MECH_CODE, - GSS_C_NO_OID, - &msg_ctx, - &status_string); - if (sizeof(buf) > len + status_string.length + 1) { - snprintf(buf + len, sizeof(buf) - len, - ": %s", (char*) status_string.value); - len += status_string.length; - } - gss_release_buffer(&min_stat, &status_string); - } while (!GSS_ERROR(maj_stat) && msg_ctx != 0); - - infof(conn->data, buf); -} - -int Curl_input_negotiate(struct connectdata *conn, char *header) -{ - struct negotiatedata *neg_ctx = &conn->data->state.negotiate; - OM_uint32 major_status, minor_status, minor_status2; - gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER; - gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER; - int ret; - size_t len; - bool gss; - const char* protocol; - - while(*header && isspace((int)*header)) - header++; - if(checkprefix("GSS-Negotiate", header)) { - protocol = "GSS-Negotiate"; - gss = TRUE; - } - else if (checkprefix("Negotiate", header)) { - protocol = "Negotiate"; - gss = FALSE; - } - else - return -1; - - if (neg_ctx->context) { - if (neg_ctx->gss != gss) { - return -1; - } - } - else { - neg_ctx->protocol = protocol; - neg_ctx->gss = gss; - } - - if (neg_ctx->context && neg_ctx->status == GSS_S_COMPLETE) { - /* We finished succesfully our part of authentication, but server - * rejected it (since we're again here). Exit with an error since we - * can't invent anything better */ - Curl_cleanup_negotiate(conn->data); - return -1; - } - - if (neg_ctx->server_name == NULL && - (ret = get_gss_name(conn, &neg_ctx->server_name))) - return ret; - - header += strlen(neg_ctx->protocol); - while(*header && isspace((int)*header)) - header++; - - len = strlen(header); - if (len > 0) { - int rawlen; - input_token.length = (len+3)/4 * 3; - input_token.value = malloc(input_token.length); - if (input_token.value == NULL) - return ENOMEM; - rawlen = Curl_base64_decode(header, input_token.value); - if (rawlen < 0) - return -1; - input_token.length = rawlen; - -#ifdef HAVE_SPNEGO /* Handle SPNEGO */ - if (checkprefix("Negotiate", header)) { - ASN1_OBJECT * object = NULL; - int rc = 1; - unsigned char * spnegoToken = NULL; - size_t spnegoTokenLength = 0; - unsigned char * mechToken = NULL; - size_t mechTokenLength = 0; - - spnegoToken = malloc(input_token.length); - if (input_token.value == NULL) - return ENOMEM; - spnegoTokenLength = input_token.length; - - object = OBJ_txt2obj ("1.2.840.113554.1.2.2", 1); - if (!parseSpnegoTargetToken(spnegoToken, - spnegoTokenLength, - NULL, - NULL, - &mechToken, - &mechTokenLength, - NULL, - NULL)) { - free(spnegoToken); - spnegoToken = NULL; - infof(conn->data, "Parse SPNEGO Target Token failed\n"); - } - else { - free(input_token.value); - input_token.value = NULL; - input_token.value = malloc(mechTokenLength); - memcpy(input_token.value, mechToken,mechTokenLength); - input_token.length = mechTokenLength; - free(mechToken); - mechToken = NULL; - infof(conn->data, "Parse SPNEGO Target Token succeded\n"); - } - } -#endif - } - - major_status = gss_init_sec_context(&minor_status, - GSS_C_NO_CREDENTIAL, - &neg_ctx->context, - neg_ctx->server_name, - GSS_C_NO_OID, - GSS_C_DELEG_FLAG, - 0, - GSS_C_NO_CHANNEL_BINDINGS, - &input_token, - NULL, - &output_token, - NULL, - NULL); - if (input_token.length > 0) - gss_release_buffer(&minor_status2, &input_token); - neg_ctx->status = major_status; - if (GSS_ERROR(major_status)) { - /* Curl_cleanup_negotiate(conn->data) ??? */ - log_gss_error(conn, minor_status, - (char *)"gss_init_sec_context() failed: "); - return -1; - } - - if (output_token.length == 0) { - return -1; - } - - neg_ctx->output_token = output_token; - /* conn->bits.close = FALSE; */ - - return 0; -} - - -CURLcode Curl_output_negotiate(struct connectdata *conn) -{ - struct negotiatedata *neg_ctx = &conn->data->state.negotiate; - OM_uint32 minor_status; - char *encoded = NULL; - int len; - -#ifdef HAVE_SPNEGO /* Handle SPNEGO */ - if (checkprefix("Negotiate",neg_ctx->protocol)) { - ASN1_OBJECT * object = NULL; - int rc = 1; - unsigned char * spnegoToken = NULL; - size_t spnegoTokenLength = 0; - unsigned char * responseToken = NULL; - size_t responseTokenLength = 0; - - responseToken = malloc(neg_ctx->output_token.length); - if ( responseToken == NULL) - return CURLE_OUT_OF_MEMORY; - memcpy(responseToken, neg_ctx->output_token.value, - neg_ctx->output_token.length); - responseTokenLength = neg_ctx->output_token.length; - - object=OBJ_txt2obj ("1.2.840.113554.1.2.2", 1); - if (!makeSpnegoInitialToken (object, - responseToken, - responseTokenLength, - &spnegoToken, - &spnegoTokenLength)) { - free(responseToken); - responseToken = NULL; - infof(conn->data, "Make SPNEGO Initial Token failed\n"); - } - else { - free(neg_ctx->output_token.value); - responseToken = NULL; - neg_ctx->output_token.value = malloc(spnegoTokenLength); - memcpy(neg_ctx->output_token.value, spnegoToken,spnegoTokenLength); - neg_ctx->output_token.length = spnegoTokenLength; - free(spnegoToken); - spnegoToken = NULL; - infof(conn->data, "Make SPNEGO Initial Token succeded\n"); - } - } -#endif - len = Curl_base64_encode(neg_ctx->output_token.value, - neg_ctx->output_token.length, - &encoded); - - if (len < 0) - return CURLE_OUT_OF_MEMORY; - - conn->allocptr.userpwd = - aprintf("Authorization: %s %s\r\n", neg_ctx->protocol, encoded); - free(encoded); - gss_release_buffer(&minor_status, &neg_ctx->output_token); - return (conn->allocptr.userpwd == NULL) ? CURLE_OUT_OF_MEMORY : CURLE_OK; -} - -void Curl_cleanup_negotiate(struct SessionHandle *data) -{ - OM_uint32 minor_status; - struct negotiatedata *neg_ctx = &data->state.negotiate; - - if (neg_ctx->context != GSS_C_NO_CONTEXT) - gss_delete_sec_context(&minor_status, &neg_ctx->context, GSS_C_NO_BUFFER); - - if (neg_ctx->output_token.length != 0) - gss_release_buffer(&minor_status, &neg_ctx->output_token); - - if (neg_ctx->server_name != GSS_C_NO_NAME) - gss_release_name(&minor_status, &neg_ctx->server_name); - - memset(neg_ctx, 0, sizeof(*neg_ctx)); -} - - -#endif -#endif diff --git a/Source/CTest/Curl/http_negotiate.h b/Source/CTest/Curl/http_negotiate.h deleted file mode 100644 index ce0d083..0000000 --- a/Source/CTest/Curl/http_negotiate.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef __HTTP_NEGOTIATE_H -#define __HTTP_NEGOTIATE_H - -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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$ - ***************************************************************************/ - -#ifdef HAVE_GSSAPI - -/* this is for Negotiate header input */ -int Curl_input_negotiate(struct connectdata *conn, char *header); - -/* this is for creating Negotiate header output */ -CURLcode Curl_output_negotiate(struct connectdata *conn); - -void Curl_cleanup_negotiate(struct SessionHandle *data); - -#endif - -#endif diff --git a/Source/CTest/Curl/http_ntlm.c b/Source/CTest/Curl/http_ntlm.c deleted file mode 100644 index fe0b653..0000000 --- a/Source/CTest/Curl/http_ntlm.c +++ /dev/null @@ -1,585 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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" - -/* NTLM details: - - http://davenport.sourceforge.net/ntlm.html - http://www.innovation.ch/java/ntlm.html - -*/ - -#ifndef CURL_DISABLE_HTTP -#ifdef USE_SSLEAY -/* We need OpenSSL for the crypto lib to provide us with MD4 and DES */ - -/* -- WIN32 approved -- */ -#include <stdio.h> -#include <string.h> -#include <stdarg.h> -#include <stdlib.h> -#include <ctype.h> - -#include "urldata.h" -#include "sendf.h" -#include "strequal.h" -#include "base64.h" -#include "http_ntlm.h" -#include "url.h" -#include "curl_memory.h" - -#define _MPRINTF_REPLACE /* use our functions only */ -#include <curl/mprintf.h> - -#include <openssl/des.h> -#include <openssl/md4.h> -#include <openssl/ssl.h> - -#if OPENSSL_VERSION_NUMBER < 0x00907001L -#define DES_key_schedule des_key_schedule -#define DES_cblock des_cblock -#define DES_set_odd_parity des_set_odd_parity -#define DES_set_key des_set_key -#define DES_ecb_encrypt des_ecb_encrypt - -/* This is how things were done in the old days */ -#define DESKEY(x) x -#define DESKEYARG(x) x -#else -/* Modern version */ -#define DESKEYARG(x) *x -#define DESKEY(x) &x -#endif - -/* The last #include file should be: */ -#include "memdebug.h" - -/* Define this to make the type-3 message include the NT response message */ -#define USE_NTRESPONSES 1 - -/* - (*) = A "security buffer" is a triplet consisting of two shorts and one - long: - - 1. a 'short' containing the length of the buffer in bytes - 2. a 'short' containing the allocated space for the buffer in bytes - 3. a 'long' containing the offset to the start of the buffer from the - beginning of the NTLM message, in bytes. -*/ - - -CURLntlm Curl_input_ntlm(struct connectdata *conn, - bool proxy, /* if proxy or not */ - char *header) /* rest of the www-authenticate: - header */ -{ - /* point to the correct struct with this */ - struct ntlmdata *ntlm; - - ntlm = proxy?&conn->proxyntlm:&conn->ntlm; - - /* skip initial whitespaces */ - while(*header && isspace((int)*header)) - header++; - - if(checkprefix("NTLM", header)) { - unsigned char buffer[256]; - header += strlen("NTLM"); - - while(*header && isspace((int)*header)) - header++; - - if(*header) { - /* We got a type-2 message here: - - Index Description Content - 0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP" - (0x4e544c4d53535000) - 8 NTLM Message Type long (0x02000000) - 12 Target Name security buffer(*) - 20 Flags long - 24 Challenge 8 bytes - (32) Context (optional) 8 bytes (two consecutive longs) - (40) Target Information (optional) security buffer(*) - 32 (48) start of data block - */ - - size_t size = Curl_base64_decode(header, (char *)buffer); - - ntlm->state = NTLMSTATE_TYPE2; /* we got a type-2 */ - - if(size >= 48) - /* the nonce of interest is index [24 .. 31], 8 bytes */ - memcpy(ntlm->nonce, &buffer[24], 8); - - /* at index decimal 20, there's a 32bit NTLM flag field */ - - } - else { - if(ntlm->state >= NTLMSTATE_TYPE1) - return CURLNTLM_BAD; - - ntlm->state = NTLMSTATE_TYPE1; /* we should sent away a type-1 */ - } - } - return CURLNTLM_FINE; -} - -/* - * Turns a 56 bit key into the 64 bit, odd parity key and sets the key. The - * key schedule ks is also set. - */ -static void setup_des_key(unsigned char *key_56, - DES_key_schedule DESKEYARG(ks)) -{ - DES_cblock key; - - key[0] = key_56[0]; - key[1] = ((key_56[0] << 7) & 0xFF) | (key_56[1] >> 1); - key[2] = ((key_56[1] << 6) & 0xFF) | (key_56[2] >> 2); - key[3] = ((key_56[2] << 5) & 0xFF) | (key_56[3] >> 3); - key[4] = ((key_56[3] << 4) & 0xFF) | (key_56[4] >> 4); - key[5] = ((key_56[4] << 3) & 0xFF) | (key_56[5] >> 5); - key[6] = ((key_56[5] << 2) & 0xFF) | (key_56[6] >> 6); - key[7] = (key_56[6] << 1) & 0xFF; - - DES_set_odd_parity(&key); - DES_set_key(&key, ks); -} - - /* - * takes a 21 byte array and treats it as 3 56-bit DES keys. The - * 8 byte plaintext is encrypted with each key and the resulting 24 - * bytes are stored in the results array. - */ -static void calc_resp(unsigned char *keys, - unsigned char *plaintext, - unsigned char *results) -{ - DES_key_schedule ks; - - setup_des_key(keys, DESKEY(ks)); - DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) results, - DESKEY(ks), DES_ENCRYPT); - - setup_des_key(keys+7, DESKEY(ks)); - DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results+8), - DESKEY(ks), DES_ENCRYPT); - - setup_des_key(keys+14, DESKEY(ks)); - DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results+16), - DESKEY(ks), DES_ENCRYPT); -} - -/* - * Set up lanmanager and nt hashed passwords - */ -static void mkhash(char *password, - unsigned char *nonce, /* 8 bytes */ - unsigned char *lmresp /* must fit 0x18 bytes */ -#ifdef USE_NTRESPONSES - , unsigned char *ntresp /* must fit 0x18 bytes */ -#endif - ) -{ - unsigned char lmbuffer[21]; -#ifdef USE_NTRESPONSES - unsigned char ntbuffer[21]; -#endif - unsigned char *pw; - static const unsigned char magic[] = { - 0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 - }; - unsigned int i; - size_t len = strlen(password); - - /* make it fit at least 14 bytes */ - pw = malloc(len<7?14:len*2); - if(!pw) - return; /* this will lead to a badly generated package */ - - if (len > 14) - len = 14; - - for (i=0; i<len; i++) - pw[i] = toupper(password[i]); - - for (; i<14; i++) - pw[i] = 0; - - { - /* create LanManager hashed password */ - DES_key_schedule ks; - - setup_des_key(pw, DESKEY(ks)); - DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)lmbuffer, - DESKEY(ks), DES_ENCRYPT); - - setup_des_key(pw+7, DESKEY(ks)); - DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)(lmbuffer+8), - DESKEY(ks), DES_ENCRYPT); - - memset(lmbuffer+16, 0, 5); - } - /* create LM responses */ - calc_resp(lmbuffer, nonce, lmresp); - -#ifdef USE_NTRESPONSES - { - /* create NT hashed password */ - MD4_CTX MD4; - - len = strlen(password); - - for (i=0; i<len; i++) { - pw[2*i] = password[i]; - pw[2*i+1] = 0; - } - - MD4_Init(&MD4); - MD4_Update(&MD4, pw, 2*len); - MD4_Final(ntbuffer, &MD4); - - memset(ntbuffer+16, 0, 8); - } - - calc_resp(ntbuffer, nonce, ntresp); -#endif - - free(pw); -} - -#define SHORTPAIR(x) ((x) & 0xff), ((x) >> 8) -#define LONGQUARTET(x) ((x) & 0xff), (((x) >> 8)&0xff), \ - (((x) >>16)&0xff), ((x)>>24) - -/* this is for creating ntlm header output */ -CURLcode Curl_output_ntlm(struct connectdata *conn, - bool proxy) -{ - const char *domain=""; /* empty */ - const char *host=""; /* empty */ - int domlen=(int)strlen(domain); - int hostlen = (int)strlen(host); - int hostoff; /* host name offset */ - int domoff; /* domain name offset */ - size_t size; - char *base64=NULL; - unsigned char ntlmbuf[256]; /* enough, unless the host/domain is very long */ - - /* point to the address of the pointer that holds the string to sent to the - server, which is for a plain host or for a HTTP proxy */ - char **allocuserpwd; - - /* point to the name and password for this */ - char *userp; - char *passwdp; - /* point to the correct struct with this */ - struct ntlmdata *ntlm; - struct auth *authp; - - curlassert(conn); - curlassert(conn->data); - - if(proxy) { - allocuserpwd = &conn->allocptr.proxyuserpwd; - userp = conn->proxyuser; - passwdp = conn->proxypasswd; - ntlm = &conn->proxyntlm; - authp = &conn->data->state.authproxy; - } - else { - allocuserpwd = &conn->allocptr.userpwd; - userp = conn->user; - passwdp = conn->passwd; - ntlm = &conn->ntlm; - authp = &conn->data->state.authhost; - } - authp->done = FALSE; - - /* not set means empty */ - if(!userp) - userp=(char *)""; - - if(!passwdp) - passwdp=(char *)""; - - switch(ntlm->state) { - case NTLMSTATE_TYPE1: - default: /* for the weird cases we (re)start here */ - hostoff = 32; - domoff = hostoff + hostlen; - - /* Create and send a type-1 message: - - Index Description Content - 0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP" - (0x4e544c4d53535000) - 8 NTLM Message Type long (0x01000000) - 12 Flags long - 16 Supplied Domain security buffer(*) - 24 Supplied Workstation security buffer(*) - 32 start of data block - - */ - - snprintf((char *)ntlmbuf, sizeof(ntlmbuf), "NTLMSSP%c" - "\x01%c%c%c" /* 32-bit type = 1 */ - "%c%c%c%c" /* 32-bit NTLM flag field */ - "%c%c" /* domain length */ - "%c%c" /* domain allocated space */ - "%c%c" /* domain name offset */ - "%c%c" /* 2 zeroes */ - "%c%c" /* host length */ - "%c%c" /* host allocated space */ - "%c%c" /* host name offset */ - "%c%c" /* 2 zeroes */ - "%s" /* host name */ - "%s", /* domain string */ - 0, /* trailing zero */ - 0,0,0, /* part of type-1 long */ - - LONGQUARTET( - NTLMFLAG_NEGOTIATE_OEM| /* 2 */ - NTLMFLAG_NEGOTIATE_NTLM_KEY /* 200 */ - /* equals 0x0202 */ - ), - SHORTPAIR(domlen), - SHORTPAIR(domlen), - SHORTPAIR(domoff), - 0,0, - SHORTPAIR(hostlen), - SHORTPAIR(hostlen), - SHORTPAIR(hostoff), - 0,0, - host, domain); - - /* initial packet length */ - size = 32 + hostlen + domlen; - - /* now keeper of the base64 encoded package size */ - size = Curl_base64_encode((char *)ntlmbuf, size, &base64); - - if(size >0 ) { - Curl_safefree(*allocuserpwd); - *allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n", - proxy?"Proxy-":"", - base64); - free(base64); - } - else - return CURLE_OUT_OF_MEMORY; /* FIX TODO */ - - break; - - case NTLMSTATE_TYPE2: - /* We received the type-2 already, create a type-3 message: - - Index Description Content - 0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP" - (0x4e544c4d53535000) - 8 NTLM Message Type long (0x03000000) - 12 LM/LMv2 Response security buffer(*) - 20 NTLM/NTLMv2 Response security buffer(*) - 28 Domain Name security buffer(*) - 36 User Name security buffer(*) - 44 Workstation Name security buffer(*) - (52) Session Key (optional) security buffer(*) - (60) Flags (optional) long - 52 (64) start of data block - - */ - - { - int lmrespoff; - int ntrespoff; - int useroff; - unsigned char lmresp[0x18]; /* fixed-size */ -#ifdef USE_NTRESPONSES - unsigned char ntresp[0x18]; /* fixed-size */ -#endif - const char *user; - int userlen; - - user = strchr(userp, '\\'); - if(!user) - user = strchr(userp, '/'); - - if (user) { - domain = userp; - domlen = (int)(user - domain); - user++; - } - else - user = userp; - userlen = (int)strlen(user); - - mkhash(passwdp, &ntlm->nonce[0], lmresp -#ifdef USE_NTRESPONSES - , ntresp -#endif - ); - - domoff = 64; /* always */ - useroff = domoff + domlen; - hostoff = useroff + userlen; - lmrespoff = hostoff + hostlen; - ntrespoff = lmrespoff + 0x18; - - /* Create the big type-3 message binary blob */ - size = snprintf((char *)ntlmbuf, sizeof(ntlmbuf), - "NTLMSSP%c" - "\x03%c%c%c" /* type-3, 32 bits */ - - "%c%c%c%c" /* LanManager length + allocated space */ - "%c%c" /* LanManager offset */ - "%c%c" /* 2 zeroes */ - - "%c%c" /* NT-response length */ - "%c%c" /* NT-response allocated space */ - "%c%c" /* NT-response offset */ - "%c%c" /* 2 zeroes */ - - "%c%c" /* domain length */ - "%c%c" /* domain allocated space */ - "%c%c" /* domain name offset */ - "%c%c" /* 2 zeroes */ - - "%c%c" /* user length */ - "%c%c" /* user allocated space */ - "%c%c" /* user offset */ - "%c%c" /* 2 zeroes */ - - "%c%c" /* host length */ - "%c%c" /* host allocated space */ - "%c%c" /* host offset */ - "%c%c%c%c%c%c" /* 6 zeroes */ - - "\xff\xff" /* message length */ - "%c%c" /* 2 zeroes */ - - "\x01\x82" /* flags */ - "%c%c" /* 2 zeroes */ - - /* domain string */ - /* user string */ - /* host string */ - /* LanManager response */ - /* NT response */ - , - 0, /* zero termination */ - 0,0,0, /* type-3 long, the 24 upper bits */ - - SHORTPAIR(0x18), /* LanManager response length, twice */ - SHORTPAIR(0x18), - SHORTPAIR(lmrespoff), - 0x0, 0x0, - -#ifdef USE_NTRESPONSES - SHORTPAIR(0x18), /* NT-response length, twice */ - SHORTPAIR(0x18), -#else - 0x0, 0x0, - 0x0, 0x0, -#endif - SHORTPAIR(ntrespoff), - 0x0, 0x0, - - SHORTPAIR(domlen), - SHORTPAIR(domlen), - SHORTPAIR(domoff), - 0x0, 0x0, - - SHORTPAIR(userlen), - SHORTPAIR(userlen), - SHORTPAIR(useroff), - 0x0, 0x0, - - SHORTPAIR(hostlen), - SHORTPAIR(hostlen), - SHORTPAIR(hostoff), - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - 0x0, 0x0, - - 0x0, 0x0); - - /* size is now 64 */ - size=64; - ntlmbuf[62]=ntlmbuf[63]=0; - - memcpy(&ntlmbuf[size], domain, domlen); - size += domlen; - - memcpy(&ntlmbuf[size], user, userlen); - size += userlen; - - /* we append the binary hashes to the end of the blob */ - if(size < ((int)sizeof(ntlmbuf) - 0x18)) { - memcpy(&ntlmbuf[size], lmresp, 0x18); - size += 0x18; - } - -#ifdef USE_NTRESPONSES - if(size < ((int)sizeof(ntlmbuf) - 0x18)) { - memcpy(&ntlmbuf[size], ntresp, 0x18); - size += 0x18; - } -#endif - - ntlmbuf[56] = (unsigned char)(size & 0xff); - ntlmbuf[57] = (unsigned char)(size >> 8); - - /* convert the binary blob into base64 */ - size = Curl_base64_encode((char *)ntlmbuf, size, &base64); - - if(size >0 ) { - Curl_safefree(*allocuserpwd); - *allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n", - proxy?"Proxy-":"", - base64); - free(base64); - } - else - return CURLE_OUT_OF_MEMORY; /* FIX TODO */ - - ntlm->state = NTLMSTATE_TYPE3; /* we sent a type-3 */ - authp->done = TRUE; - } - break; - - case NTLMSTATE_TYPE3: - /* connection is already authenticated, - * don't send a header in future requests */ - if(*allocuserpwd) { - free(*allocuserpwd); - *allocuserpwd=NULL; - } - authp->done = TRUE; - break; - } - - return CURLE_OK; -} -#endif /* USE_SSLEAY */ -#endif /* !CURL_DISABLE_HTTP */ diff --git a/Source/CTest/Curl/http_ntlm.h b/Source/CTest/Curl/http_ntlm.h deleted file mode 100644 index 4386a1c..0000000 --- a/Source/CTest/Curl/http_ntlm.h +++ /dev/null @@ -1,143 +0,0 @@ -#ifndef __HTTP_NTLM_H -#define __HTTP_NTLM_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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$ - ***************************************************************************/ - -typedef enum { - CURLNTLM_NONE, /* not a ntlm */ - CURLNTLM_BAD, /* an ntlm, but one we don't like */ - CURLNTLM_FIRST, /* the first 401-reply we got with NTLM */ - CURLNTLM_FINE, /* an ntlm we act on */ - - CURLNTLM_LAST /* last entry in this enum, don't use */ -} CURLntlm; - -/* this is for ntlm header input */ -CURLntlm Curl_input_ntlm(struct connectdata *conn, bool proxy, char *header); - -/* this is for creating ntlm header output */ -CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy); - -void Curl_ntlm_cleanup(struct SessionHandle *data); - - -/* Flag bits definitions based on http://davenport.sourceforge.net/ntlm.html */ - -#define NTLMFLAG_NEGOTIATE_UNICODE (1<<0) -/* Indicates that Unicode strings are supported for use in security buffer - data. */ - -#define NTLMFLAG_NEGOTIATE_OEM (1<<1) -/* Indicates that OEM strings are supported for use in security buffer data. */ - -#define NTLMFLAG_REQUEST_TARGET (1<<2) -/* Requests that the server's authentication realm be included in the Type 2 - message. */ - -/* unknown (1<<3) */ -#define NTLMFLAG_NEGOTIATE_SIGN (1<<4) -/* Specifies that authenticated communication between the client and server - should carry a digital signature (message integrity). */ - -#define NTLMFLAG_NEGOTIATE_SEAL (1<<5) -/* Specifies that authenticated communication between the client and server - should be encrypted (message confidentiality). */ - -#define NTLMFLAG_NEGOTIATE_DATAGRAM_STYLE (1<<6) -/* unknown purpose */ - -#define NTLMFLAG_NEGOTIATE_LM_KEY (1<<7) -/* Indicates that the LAN Manager session key should be used for signing and - sealing authenticated communications. */ - -#define NTLMFLAG_NEGOTIATE_NETWARE (1<<8) -/* unknown purpose */ - -#define NTLMFLAG_NEGOTIATE_NTLM_KEY (1<<9) -/* Indicates that NTLM authentication is being used. */ - -/* unknown (1<<10) */ -/* unknown (1<<11) */ - -#define NTLMFLAG_NEGOTIATE_DOMAIN_SUPPLIED (1<<12) -/* Sent by the client in the Type 1 message to indicate that a desired - authentication realm is included in the message. */ - -#define NTLMFLAG_NEGOTIATE_WORKSTATION_SUPPLIED (1<<13) -/* Sent by the client in the Type 1 message to indicate that the client - workstation's name is included in the message. */ - -#define NTLMFLAG_NEGOTIATE_LOCAL_CALL (1<<14) -/* Sent by the server to indicate that the server and client are on the same - machine. Implies that the client may use a pre-established local security - context rather than responding to the challenge. */ - -#define NTLMFLAG_NEGOTIATE_ALWAYS_SIGN (1<<15) -/* Indicates that authenticated communication between the client and server - should be signed with a "dummy" signature. */ - -#define NTLMFLAG_TARGET_TYPE_DOMAIN (1<<16) -/* Sent by the server in the Type 2 message to indicate that the target - authentication realm is a domain. */ - -#define NTLMFLAG_TARGET_TYPE_SERVER (1<<17) -/* Sent by the server in the Type 2 message to indicate that the target - authentication realm is a server. */ - -#define NTLMFLAG_TARGET_TYPE_SHARE (1<<18) -/* Sent by the server in the Type 2 message to indicate that the target - authentication realm is a share. Presumably, this is for share-level - authentication. Usage is unclear. */ - -#define NTLMFLAG_NEGOTIATE_NTLM2_KEY (1<<19) -/* Indicates that the NTLM2 signing and sealing scheme should be used for - protecting authenticated communications. */ - -#define NTLMFLAG_REQUEST_INIT_RESPONSE (1<<20) -/* unknown purpose */ - -#define NTLMFLAG_REQUEST_ACCEPT_RESPONSE (1<<21) -/* unknown purpose */ - -#define NTLMFLAG_REQUEST_NONNT_SESSION_KEY (1<<22) -/* unknown purpose */ - -#define NTLMFLAG_NEGOTIATE_TARGET_INFO (1<<23) -/* Sent by the server in the Type 2 message to indicate that it is including a - Target Information block in the message. */ - -/* unknown (1<24) */ -/* unknown (1<25) */ -/* unknown (1<26) */ -/* unknown (1<27) */ -/* unknown (1<28) */ - -#define NTLMFLAG_NEGOTIATE_128 (1<<29) -/* Indicates that 128-bit encryption is supported. */ - -#define NTLMFLAG_NEGOTIATE_KEY_EXCHANGE (1<<30) -/* unknown purpose */ - -#define NTLMFLAG_NEGOTIATE_56 (1<<31) -/* Indicates that 56-bit encryption is supported. */ -#endif diff --git a/Source/CTest/Curl/if2ip.c b/Source/CTest/Curl/if2ip.c deleted file mode 100644 index 8bccc94..0000000 --- a/Source/CTest/Curl/if2ip.c +++ /dev/null @@ -1,142 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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 <stdio.h> -#include <stdlib.h> -#include <string.h> - -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -#if !defined(WIN32) && !defined(__BEOS__) && !defined(__CYGWIN32__) && \ - !defined(__riscos__) && !defined(__INTERIX) && !defined(NETWARE) - -#ifdef HAVE_SYS_SOCKET_H -#include <sys/socket.h> -#endif -#ifdef HAVE_NETINET_IN_H -#include <netinet/in.h> -#endif -#ifdef HAVE_ARPA_INET_H -#include <arpa/inet.h> -#endif - -#ifdef HAVE_SYS_TIME_H -/* This must be before net/if.h for AIX 3.2 to enjoy life */ -#include <sys/time.h> -#endif -#ifdef HAVE_NET_IF_H -#include <net/if.h> -#endif -#ifdef HAVE_SYS_IOCTL_H -#include <sys/ioctl.h> -#endif - -/* -- if2ip() -- */ -#ifdef HAVE_NETDB_H -#include <netdb.h> -#endif - -#ifdef HAVE_SYS_SOCKIO_H -#include <sys/sockio.h> -#endif - -#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL) -#include "inet_ntoa_r.h" -#endif - -#ifdef VMS -#include <inet.h> -#endif - -#include "if2ip.h" -#include "curl_memory.h" - -/* The last #include file should be: */ -#include "memdebug.h" - -#define SYS_ERROR -1 - -char *Curl_if2ip(const char *interface, char *buf, int buf_size) -{ - int dummy; - char *ip=NULL; - - if(!interface) - return NULL; - - dummy = socket(AF_INET, SOCK_STREAM, 0); - if (SYS_ERROR == dummy) { - return NULL; - } - else { - struct ifreq req; - size_t len = strlen(interface); - memset(&req, 0, sizeof(req)); - if(len >= sizeof(req.ifr_name)) - return NULL; /* this can't be a fine interface name */ - memcpy(req.ifr_name, interface, len+1); - req.ifr_addr.sa_family = AF_INET; -#ifdef IOCTL_3_ARGS - if (SYS_ERROR == ioctl(dummy, SIOCGIFADDR, &req)) { -#else - if (SYS_ERROR == ioctl(dummy, SIOCGIFADDR, &req, sizeof(req))) { -#endif - sclose(dummy); - return NULL; - } - else { - struct in_addr in; - - union { - struct sockaddr_in *sin; - struct sockaddr *s; - } soadd; - - soadd.s = &req.ifr_dstaddr; - memcpy(&in, &(soadd.sin->sin_addr.s_addr), sizeof(in)); -#if defined(HAVE_INET_NTOA_R) - ip = inet_ntoa_r(in,buf,buf_size); -#else - ip = strncpy(buf,inet_ntoa(in),buf_size); - ip[buf_size - 1] = 0; -#endif - } - sclose(dummy); - } - return ip; -} - -/* -- end of if2ip() -- */ -#else -char *Curl_if2ip(const char *interface, char *buf, int buf_size) -{ - (void) interface; - (void) buf; - (void) buf_size; - return NULL; -} -#endif diff --git a/Source/CTest/Curl/if2ip.h b/Source/CTest/Curl/if2ip.h deleted file mode 100644 index 45a1805..0000000 --- a/Source/CTest/Curl/if2ip.h +++ /dev/null @@ -1,69 +0,0 @@ -#ifndef __IF2IP_H -#define __IF2IP_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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" - -#if !defined(WIN32) && !defined(__BEOS__) && !defined(__CYGWIN32__) && \ - !defined(__riscos__) && !defined(__INTERIX) -extern char *Curl_if2ip(const char *interface, char *buf, int buf_size); -#else -#define Curl_if2ip(a,b,c) NULL -#endif -#ifdef __INTERIX -/* Nedelcho Stanev's work-around for SFU 3.0 */ -struct ifreq { -#define IFNAMSIZ 16 -#define IFHWADDRLEN 6 - union { - char ifrn_name[IFNAMSIZ]; /* if name, e.g. "en0" */ - } ifr_ifrn; - - union { - struct sockaddr ifru_addr; - struct sockaddr ifru_broadaddr; - struct sockaddr ifru_netmask; - struct sockaddr ifru_hwaddr; - short ifru_flags; - int ifru_metric; - int ifru_mtu; - } ifr_ifru; -}; - -/* This define was added by Daniel to avoid an extra #ifdef INTERIX in the - C code. */ -#define ifr_dstaddr ifr_addr - -#define ifr_name ifr_ifrn.ifrn_name /* interface name */ -#define ifr_addr ifr_ifru.ifru_addr /* address */ -#define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */ -#define ifr_netmask ifr_ifru.ifru_netmask /* interface net mask */ -#define ifr_flags ifr_ifru.ifru_flags /* flags */ -#define ifr_hwaddr ifr_ifru.ifru_hwaddr /* MAC address */ -#define ifr_metric ifr_ifru.ifru_metric /* metric */ -#define ifr_mtu ifr_ifru.ifru_mtu /* mtu */ - -#define SIOCGIFADDR _IOW('s', 102, struct ifreq) /* Get if addr */ -#endif /* interix */ - -#endif diff --git a/Source/CTest/Curl/inet_ntoa_r.h b/Source/CTest/Curl/inet_ntoa_r.h deleted file mode 100644 index 7959c49..0000000 --- a/Source/CTest/Curl/inet_ntoa_r.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef __INET_NTOA_R_H -#define __INET_NTOA_R_H -/* - * My solaris 5.6 system running gcc 2.8.1 does *not* have this prototype - * in any system include file! Isn't that weird? - */ -char *inet_ntoa_r(const struct in_addr in, char *buffer, int buflen); - -#endif diff --git a/Source/CTest/Curl/inet_ntop.c b/Source/CTest/Curl/inet_ntop.c deleted file mode 100644 index 6809a92..0000000 --- a/Source/CTest/Curl/inet_ntop.c +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Original code by Paul Vixie. "curlified" by Gisle Vanem. - */ - -#include "setup.h" - -#ifndef HAVE_INET_NTOP - -#ifdef HAVE_SYS_PARAM_H -#include <sys/param.h> -#endif -#ifdef HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif -#ifdef HAVE_SYS_SOCKET_H -#include <sys/socket.h> -#endif -#ifdef HAVE_NETINET_IN_H -#include <netinet/in.h> -#endif -#ifdef HAVE_ARPA_INET_H -#include <arpa/inet.h> -#endif -#include <string.h> -#include <errno.h> - -#define _MPRINTF_REPLACE /* use our functions only */ -#include <curl/mprintf.h> - -#include "inet_ntop.h" - -#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL) -/* this platform has a inet_ntoa_r() function, but no proto declared anywhere - so we include our own proto to make compilers happy */ -#include "inet_ntoa_r.h" -#endif - -#define IN6ADDRSZ 16 -#define INADDRSZ 4 -#define INT16SZ 2 - -#ifdef WIN32 -#define EAFNOSUPPORT WSAEAFNOSUPPORT -#define SET_ERRNO(e) WSASetLastError(errno = (e)) -#else -#define SET_ERRNO(e) errno = e -#endif - -/* - * Format an IPv4 address, more or less like inet_ntoa(). - * - * Returns `dst' (as a const) - * Note: - * - uses no statics - * - takes a u_char* not an in_addr as input - */ -static const char *inet_ntop4 (const u_char *src, char *dst, size_t size) -{ -#ifdef HAVE_INET_NTOA_R - return inet_ntoa_r(*(struct in_addr*)src, dst, size); -#else - union { - const u_char* uch; - const struct in_addr* iad; - } srcaddr; - const char *addr; - srcaddr.uch = src; - addr = inet_ntoa(*srcaddr.iad); - - if (strlen(addr) >= size) - { - SET_ERRNO(ENOSPC); - return (NULL); - } - return strcpy(dst, addr); -#endif -} - -#ifdef ENABLE_IPV6 -/* - * Convert IPv6 binary address into presentation (printable) format. - */ -static const char *inet_ntop6 (const u_char *src, char *dst, size_t size) -{ - /* - * Note that int32_t and int16_t need only be "at least" large enough - * to contain a value of the specified size. On some systems, like - * Crays, there is no such thing as an integer variable with 16 bits. - * Keep this in mind if you think this function should have been coded - * to use pointer overlays. All the world's not a VAX. - */ - char tmp [sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")]; - char *tp; - struct { - long base; - long len; - } best, cur; - u_long words [IN6ADDRSZ / INT16SZ]; - int i; - - /* Preprocess: - * Copy the input (bytewise) array into a wordwise array. - * Find the longest run of 0x00's in src[] for :: shorthanding. - */ - memset(words, 0, sizeof(words)); - for (i = 0; i < IN6ADDRSZ; i++) - words[i/2] |= (src[i] << ((1 - (i % 2)) << 3)); - - best.base = -1; - cur.base = -1; - for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) - { - if (words[i] == 0) - { - if (cur.base == -1) - cur.base = i, cur.len = 1; - else - cur.len++; - } - else if (cur.base != -1) - { - if (best.base == -1 || cur.len > best.len) - best = cur; - cur.base = -1; - } - } - if ((cur.base != -1) && (best.base == -1 || cur.len > best.len)) - best = cur; - if (best.base != -1 && best.len < 2) - best.base = -1; - - /* Format the result. - */ - tp = tmp; - for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) - { - /* Are we inside the best run of 0x00's? - */ - if (best.base != -1 && i >= best.base && i < (best.base + best.len)) - { - if (i == best.base) - *tp++ = ':'; - continue; - } - - /* Are we following an initial run of 0x00s or any real hex? - */ - if (i != 0) - *tp++ = ':'; - - /* Is this address an encapsulated IPv4? - */ - if (i == 6 && best.base == 0 && - (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) - { - if (!inet_ntop4(src+12, tp, sizeof(tmp) - (tp - tmp))) - { - SET_ERRNO(ENOSPC); - return (NULL); - } - tp += strlen(tp); - break; - } - tp += snprintf(tp, 5, "%lx", words[i]); - } - - /* Was it a trailing run of 0x00's? - */ - if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) - *tp++ = ':'; - *tp++ = '\0'; - - /* Check for overflow, copy, and we're done. - */ - if ((size_t)(tp - tmp) > size) - { - SET_ERRNO(ENOSPC); - return (NULL); - } - return strcpy (dst, tmp); -} -#endif /* ENABLE_IPV6 */ - -/* - * Convert a network format address to presentation format. - * - * Returns pointer to presentation format address (`dst'), - * Returns NULL on error (see errno). - */ -const char *Curl_inet_ntop(int af, const void *src, char *buf, size_t size) -{ - switch (af) { - case AF_INET: - return inet_ntop4((const u_char*)src, buf, size); -#ifdef ENABLE_IPV6 - case AF_INET6: - return inet_ntop6((const u_char*)src, buf, size); -#endif - default: - SET_ERRNO(EAFNOSUPPORT); - return NULL; - } -} -#endif /* HAVE_INET_NTOP */ diff --git a/Source/CTest/Curl/inet_ntop.h b/Source/CTest/Curl/inet_ntop.h deleted file mode 100644 index 5948a12..0000000 --- a/Source/CTest/Curl/inet_ntop.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef __INET_NTOP_H -#define __INET_NTOP_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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_INET_NTOP -#define Curl_inet_ntop(af,addr,buf,size) inet_ntop(af,addr,buf,size) -#ifdef HAVE_ARPA_INET_H -#include <arpa/inet.h> -#endif -#else -const char *Curl_inet_ntop(int af, const void *addr, char *buf, size_t size); -#endif - -#endif /* __INET_NTOP_H */ diff --git a/Source/CTest/Curl/inet_pton.c b/Source/CTest/Curl/inet_pton.c deleted file mode 100644 index 5e8e9b3..0000000 --- a/Source/CTest/Curl/inet_pton.c +++ /dev/null @@ -1,240 +0,0 @@ -/* This is from the BIND 4.9.4 release, modified to compile by itself */ - -/* Copyright (c) 1996 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -#include "setup.h" - -#ifndef HAVE_INET_PTON - -#ifdef HAVE_SYS_PARAM_H -#include <sys/param.h> -#endif -#ifdef HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif -#ifdef HAVE_SYS_SOCKET_H -#include <sys/socket.h> -#endif -#ifdef HAVE_NETINET_IN_H -#include <netinet/in.h> -#endif -#ifdef HAVE_ARPA_INET_H -#include <arpa/inet.h> -#endif -#include <string.h> -#include <errno.h> - -#include "inet_pton.h" - -#define IN6ADDRSZ 16 -#define INADDRSZ 4 -#define INT16SZ 2 - -#ifdef WIN32 -#define EAFNOSUPPORT WSAEAFNOSUPPORT -#endif - -/* - * WARNING: Don't even consider trying to compile this on a system where - * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. - */ - -static int inet_pton4(const char *src, unsigned char *dst); -#ifdef ENABLE_IPV6 -static int inet_pton6(const char *src, unsigned char *dst); -#endif - -/* int - * inet_pton(af, src, dst) - * convert from presentation format (which usually means ASCII printable) - * to network format (which is usually some kind of binary format). - * return: - * 1 if the address was valid for the specified address family - * 0 if the address wasn't valid (`dst' is untouched in this case) - * -1 if some other error occurred (`dst' is untouched in this case, too) - * author: - * Paul Vixie, 1996. - */ -int -Curl_inet_pton(int af, const char *src, void *dst) -{ - switch (af) { - case AF_INET: - return (inet_pton4(src, dst)); -#ifdef ENABLE_IPV6 -#ifndef AF_INET6 -#define AF_INET6 AF_MAX+1 /* just to let this compile */ -#endif - case AF_INET6: - return (inet_pton6(src, dst)); -#endif - default: - errno = EAFNOSUPPORT; - return (-1); - } - /* NOTREACHED */ -} - -/* int - * inet_pton4(src, dst) - * like inet_aton() but without all the hexadecimal and shorthand. - * return: - * 1 if `src' is a valid dotted quad, else 0. - * notice: - * does not touch `dst' unless it's returning 1. - * author: - * Paul Vixie, 1996. - */ -static int -inet_pton4(const char *src, unsigned char *dst) -{ - static const char digits[] = "0123456789"; - int saw_digit, octets, ch; - unsigned char tmp[INADDRSZ], *tp; - - saw_digit = 0; - octets = 0; - *(tp = tmp) = 0; - while ((ch = *src++) != '\0') { - const char *pch; - - if ((pch = strchr(digits, ch)) != NULL) { - u_int new = *tp * 10 + (pch - digits); - - if (new > 255) - return (0); - *tp = new; - if (! saw_digit) { - if (++octets > 4) - return (0); - saw_digit = 1; - } - } else if (ch == '.' && saw_digit) { - if (octets == 4) - return (0); - *++tp = 0; - saw_digit = 0; - } else - return (0); - } - if (octets < 4) - return (0); - /* bcopy(tmp, dst, INADDRSZ); */ - memcpy(dst, tmp, INADDRSZ); - return (1); -} - -#ifdef ENABLE_IPV6 -/* int - * inet_pton6(src, dst) - * convert presentation level address to network order binary form. - * return: - * 1 if `src' is a valid [RFC1884 2.2] address, else 0. - * notice: - * (1) does not touch `dst' unless it's returning 1. - * (2) :: in a full address is silently ignored. - * credit: - * inspired by Mark Andrews. - * author: - * Paul Vixie, 1996. - */ -static int -inet_pton6(const char *src, unsigned char *dst) -{ - static const char xdigits_l[] = "0123456789abcdef", - xdigits_u[] = "0123456789ABCDEF"; - unsigned char tmp[IN6ADDRSZ], *tp, *endp, *colonp; - const char *xdigits, *curtok; - int ch, saw_xdigit; - u_int val; - - memset((tp = tmp), 0, IN6ADDRSZ); - endp = tp + IN6ADDRSZ; - colonp = NULL; - /* Leading :: requires some special handling. */ - if (*src == ':') - if (*++src != ':') - return (0); - curtok = src; - saw_xdigit = 0; - val = 0; - while ((ch = *src++) != '\0') { - const char *pch; - - if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL) - pch = strchr((xdigits = xdigits_u), ch); - if (pch != NULL) { - val <<= 4; - val |= (pch - xdigits); - if (val > 0xffff) - return (0); - saw_xdigit = 1; - continue; - } - if (ch == ':') { - curtok = src; - if (!saw_xdigit) { - if (colonp) - return (0); - colonp = tp; - continue; - } - if (tp + INT16SZ > endp) - return (0); - *tp++ = (unsigned char) (val >> 8) & 0xff; - *tp++ = (unsigned char) val & 0xff; - saw_xdigit = 0; - val = 0; - continue; - } - if (ch == '.' && ((tp + INADDRSZ) <= endp) && - inet_pton4(curtok, tp) > 0) { - tp += INADDRSZ; - saw_xdigit = 0; - break; /* '\0' was seen by inet_pton4(). */ - } - return (0); - } - if (saw_xdigit) { - if (tp + INT16SZ > endp) - return (0); - *tp++ = (unsigned char) (val >> 8) & 0xff; - *tp++ = (unsigned char) val & 0xff; - } - if (colonp != NULL) { - /* - * Since some memmove()'s erroneously fail to handle - * overlapping regions, we'll do the shift by hand. - */ - const int n = tp - colonp; - int i; - - for (i = 1; i <= n; i++) { - endp[- i] = colonp[n - i]; - colonp[n - i] = 0; - } - tp = endp; - } - if (tp != endp) - return (0); - /* bcopy(tmp, dst, IN6ADDRSZ); */ - memcpy(dst, tmp, IN6ADDRSZ); - return (1); -} -#endif /* ENABLE_IPV6 */ - -#endif /* HAVE_INET_PTON */ diff --git a/Source/CTest/Curl/inet_pton.h b/Source/CTest/Curl/inet_pton.h deleted file mode 100644 index b0a70d4..0000000 --- a/Source/CTest/Curl/inet_pton.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef __INET_PTON_H -#define __INET_PTON_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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_INET_PTON -#define Curl_inet_pton(x,y,z) inet_pton(x,y,z) -#ifdef HAVE_ARPA_INET_H -#include <arpa/inet.h> -#endif -#else -int Curl_inet_pton(int, const char *, void *); -#endif - -#endif /* __INET_PTON_H */ diff --git a/Source/CTest/Curl/krb4.c b/Source/CTest/Curl/krb4.c deleted file mode 100644 index 50467e3..0000000 --- a/Source/CTest/Curl/krb4.c +++ /dev/null @@ -1,408 +0,0 @@ -/* This source code was modified by Martin Hedenfalk <mhe@stacken.kth.se> for - * use in Curl. His latest changes were done 2000-09-18. - * - * It has since been patched away like a madman by Daniel Stenberg - * <daniel@haxx.se> to make it better applied to curl conditions, and to make - * it not use globals, pollute name space and more. This source code awaits a - * rewrite to work around the paragraph 2 in the BSD licenses as explained - * below. - * - * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. */ - -#include "setup.h" - -#ifndef CURL_DISABLE_FTP -#ifdef HAVE_KRB4 - -#include "security.h" -#include "base64.h" -#include <stdlib.h> -#ifdef HAVE_NETDB_H -#include <netdb.h> -#endif -#include <string.h> -#include <krb.h> -#include <des.h> - -#ifdef HAVE_UNISTD_H -#include <unistd.h> /* for getpid() */ -#endif - -#include "ftp.h" -#include "sendf.h" -#include "krb4.h" -#include "curl_memory.h" - -#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL) -#include "inet_ntoa_r.h" -#endif - -/* The last #include file should be: */ -#include "memdebug.h" - -#define LOCAL_ADDR (&conn->local_addr) -#define REMOTE_ADDR conn->ip_addr->ai_addr -#define myctladdr LOCAL_ADDR -#define hisctladdr REMOTE_ADDR - -struct krb4_data { - des_cblock key; - des_key_schedule schedule; - char name[ANAME_SZ]; - char instance[INST_SZ]; - char realm[REALM_SZ]; -}; - -#ifndef HAVE_STRLCPY -/* if it ever goes non-static, make it Curl_ prefixed! */ -static size_t -strlcpy (char *dst, const char *src, size_t dst_sz) -{ - size_t n; - char *p; - - for (p = dst, n = 0; - n + 1 < dst_sz && *src != '\0'; - ++p, ++src, ++n) - *p = *src; - *p = '\0'; - if (*src == '\0') - return n; - else - return n + strlen (src); -} -#else -size_t strlcpy (char *dst, const char *src, size_t dst_sz); -#endif - -static int -krb4_check_prot(void *app_data, int level) -{ - app_data = NULL; /* prevent compiler warning */ - if(level == prot_confidential) - return -1; - return 0; -} - -static int -krb4_decode(void *app_data, void *buf, int len, int level, - struct connectdata *conn) -{ - MSG_DAT m; - int e; - struct krb4_data *d = app_data; - - if(level == prot_safe) - e = krb_rd_safe(buf, len, &d->key, - (struct sockaddr_in *)REMOTE_ADDR, - (struct sockaddr_in *)LOCAL_ADDR, &m); - else - e = krb_rd_priv(buf, len, d->schedule, &d->key, - (struct sockaddr_in *)REMOTE_ADDR, - (struct sockaddr_in *)LOCAL_ADDR, &m); - if(e) { - struct SessionHandle *data = conn->data; - infof(data, "krb4_decode: %s\n", krb_get_err_text(e)); - return -1; - } - memmove(buf, m.app_data, m.app_length); - return m.app_length; -} - -static int -krb4_overhead(void *app_data, int level, int len) -{ - /* no arguments are used, just init them to prevent compiler warnings */ - app_data = NULL; - level = 0; - len = 0; - return 31; -} - -static int -krb4_encode(void *app_data, void *from, int length, int level, void **to, - struct connectdata *conn) -{ - struct krb4_data *d = app_data; - *to = malloc(length + 31); - if(level == prot_safe) - return krb_mk_safe(from, *to, length, &d->key, - (struct sockaddr_in *)LOCAL_ADDR, - (struct sockaddr_in *)REMOTE_ADDR); - else if(level == prot_private) - return krb_mk_priv(from, *to, length, d->schedule, &d->key, - (struct sockaddr_in *)LOCAL_ADDR, - (struct sockaddr_in *)REMOTE_ADDR); - else - return -1; -} - -static int -mk_auth(struct krb4_data *d, KTEXT adat, - const char *service, char *host, int checksum) -{ - int ret; - CREDENTIALS cred; - char sname[SNAME_SZ], inst[INST_SZ], realm[REALM_SZ]; - - strlcpy(sname, service, sizeof(sname)); - strlcpy(inst, krb_get_phost(host), sizeof(inst)); - strlcpy(realm, krb_realmofhost(host), sizeof(realm)); - ret = krb_mk_req(adat, sname, inst, realm, checksum); - if(ret) - return ret; - strlcpy(sname, service, sizeof(sname)); - strlcpy(inst, krb_get_phost(host), sizeof(inst)); - strlcpy(realm, krb_realmofhost(host), sizeof(realm)); - ret = krb_get_cred(sname, inst, realm, &cred); - memmove(&d->key, &cred.session, sizeof(des_cblock)); - des_key_sched(&d->key, d->schedule); - memset(&cred, 0, sizeof(cred)); - return ret; -} - -#ifdef HAVE_KRB_GET_OUR_IP_FOR_REALM -int krb_get_our_ip_for_realm(char *, struct in_addr *); -#endif - -static int -krb4_auth(void *app_data, struct connectdata *conn) -{ - int ret; - char *p; - int len; - KTEXT_ST adat; - MSG_DAT msg_data; - int checksum; - u_int32_t cs; - struct krb4_data *d = app_data; - char *host = conn->host.name; - ssize_t nread; - int l = sizeof(conn->local_addr); - struct SessionHandle *data = conn->data; - CURLcode result; - - if(getsockname(conn->sock[FIRSTSOCKET], - (struct sockaddr *)LOCAL_ADDR, &l) < 0) - perror("getsockname()"); - - checksum = getpid(); - ret = mk_auth(d, &adat, "ftp", host, checksum); - if(ret == KDC_PR_UNKNOWN) - ret = mk_auth(d, &adat, "rcmd", host, checksum); - if(ret) { - Curl_infof(data, "%s\n", krb_get_err_text(ret)); - return AUTH_CONTINUE; - } - -#ifdef HAVE_KRB_GET_OUR_IP_FOR_REALM - if (krb_get_config_bool("nat_in_use")) { - struct sockaddr_in *localaddr = (struct sockaddr_in *)LOCAL_ADDR; - struct in_addr natAddr; - - if (krb_get_our_ip_for_realm(krb_realmofhost(host), - &natAddr) != KSUCCESS - && krb_get_our_ip_for_realm(NULL, &natAddr) != KSUCCESS) - Curl_infof(data, "Can't get address for realm %s\n", - krb_realmofhost(host)); - else { - if (natAddr.s_addr != localaddr->sin_addr.s_addr) { -#ifdef HAVE_INET_NTOA_R - char ntoa_buf[64]; - char *ip = (char *)inet_ntoa_r(natAddr, ntoa_buf, sizeof(ntoa_buf)); -#else - char *ip = (char *)inet_ntoa(natAddr); -#endif - Curl_infof(data, "Using NAT IP address (%s) for kerberos 4\n", ip); - localaddr->sin_addr = natAddr; - } - } - } -#endif - - if(Curl_base64_encode((char *)adat.dat, adat.length, &p) < 1) { - Curl_failf(data, "Out of memory base64-encoding"); - return AUTH_CONTINUE; - } - - result = Curl_ftpsendf(conn, "ADAT %s", p); - - free(p); - - if(result) - return -2; - - if(Curl_GetFTPResponse(&nread, conn, NULL)) - return -1; - - if(data->state.buffer[0] != '2'){ - Curl_failf(data, "Server didn't accept auth data"); - return AUTH_ERROR; - } - - p = strstr(data->state.buffer, "ADAT="); - if(!p) { - Curl_failf(data, "Remote host didn't send adat reply"); - return AUTH_ERROR; - } - p += 5; - len = Curl_base64_decode(p, (char *)adat.dat); - if(len < 0) { - Curl_failf(data, "Failed to decode base64 from server"); - return AUTH_ERROR; - } - adat.length = len; - ret = krb_rd_safe(adat.dat, adat.length, &d->key, - (struct sockaddr_in *)hisctladdr, - (struct sockaddr_in *)myctladdr, &msg_data); - if(ret) { - Curl_failf(data, "Error reading reply from server: %s", - krb_get_err_text(ret)); - return AUTH_ERROR; - } - krb_get_int(msg_data.app_data, &cs, 4, 0); - if(cs - checksum != 1) { - Curl_failf(data, "Bad checksum returned from server"); - return AUTH_ERROR; - } - return AUTH_OK; -} - -struct Curl_sec_client_mech Curl_krb4_client_mech = { - "KERBEROS_V4", - sizeof(struct krb4_data), - NULL, /* init */ - krb4_auth, - NULL, /* end */ - krb4_check_prot, - krb4_overhead, - krb4_encode, - krb4_decode -}; - -CURLcode Curl_krb_kauth(struct connectdata *conn) -{ - des_cblock key; - des_key_schedule schedule; - KTEXT_ST tkt, tktcopy; - char *name; - char *p; - char passwd[100]; - int tmp; - ssize_t nread; - int save; - CURLcode result; - - save = Curl_set_command_prot(conn, prot_private); - - result = Curl_ftpsendf(conn, "SITE KAUTH %s", conn->user); - - if(result) - return result; - - result = Curl_GetFTPResponse(&nread, conn, NULL); - if(result) - return result; - - if(conn->data->state.buffer[0] != '3'){ - Curl_set_command_prot(conn, save); - return CURLE_FTP_WEIRD_SERVER_REPLY; - } - - p = strstr(conn->data->state.buffer, "T="); - if(!p) { - Curl_failf(conn->data, "Bad reply from server"); - Curl_set_command_prot(conn, save); - return CURLE_FTP_WEIRD_SERVER_REPLY; - } - - p += 2; - tmp = Curl_base64_decode(p, (char *)tkt.dat); - if(tmp < 0) { - Curl_failf(conn->data, "Failed to decode base64 in reply.\n"); - Curl_set_command_prot(conn, save); - return CURLE_FTP_WEIRD_SERVER_REPLY; - } - tkt.length = tmp; - tktcopy.length = tkt.length; - - p = strstr(conn->data->state.buffer, "P="); - if(!p) { - Curl_failf(conn->data, "Bad reply from server"); - Curl_set_command_prot(conn, save); - return CURLE_FTP_WEIRD_SERVER_REPLY; - } - name = p + 2; - for(; *p && *p != ' ' && *p != '\r' && *p != '\n'; p++); - *p = 0; - - des_string_to_key (conn->passwd, &key); - des_key_sched(&key, schedule); - - des_pcbc_encrypt((void *)tkt.dat, (void *)tktcopy.dat, - tkt.length, - schedule, &key, DES_DECRYPT); - if (strcmp ((char*)tktcopy.dat + 8, - KRB_TICKET_GRANTING_TICKET) != 0) { - afs_string_to_key(passwd, - krb_realmofhost(conn->host.name), - &key); - des_key_sched(&key, schedule); - des_pcbc_encrypt((void *)tkt.dat, (void *)tktcopy.dat, - tkt.length, - schedule, &key, DES_DECRYPT); - } - memset(key, 0, sizeof(key)); - memset(schedule, 0, sizeof(schedule)); - memset(passwd, 0, sizeof(passwd)); - if(Curl_base64_encode((char *)tktcopy.dat, tktcopy.length, &p) < 1) { - failf(conn->data, "Out of memory base64-encoding."); - Curl_set_command_prot(conn, save); - return CURLE_OUT_OF_MEMORY; - } - memset (tktcopy.dat, 0, tktcopy.length); - - result = Curl_ftpsendf(conn, "SITE KAUTH %s %s", name, p); - free(p); - if(result) - return result; - - result = Curl_GetFTPResponse(&nread, conn, NULL); - if(result) - return result; - Curl_set_command_prot(conn, save); - - return CURLE_OK; -} - -#endif /* HAVE_KRB4 */ -#endif /* CURL_DISABLE_FTP */ diff --git a/Source/CTest/Curl/krb4.h b/Source/CTest/Curl/krb4.h deleted file mode 100644 index cded35b..0000000 --- a/Source/CTest/Curl/krb4.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef __KRB4_H -#define __KRB4_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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_krb_kauth(struct connectdata *conn); - -#endif diff --git a/Source/CTest/Curl/ldap.c b/Source/CTest/Curl/ldap.c deleted file mode 100644 index 62e5b26..0000000 --- a/Source/CTest/Curl/ldap.c +++ /dev/null @@ -1,625 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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" - -#ifndef CURL_DISABLE_LDAP -/* -- WIN32 approved -- */ -#include <stdio.h> -#include <string.h> -#include <stdarg.h> -#include <stdlib.h> -#include <ctype.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <errno.h> - -#if defined(WIN32) -# include <windows.h> -# include <malloc.h> -# include <WinLdap.h> -#endif - -#ifdef HAVE_UNISTD_H -# include <unistd.h> -#endif - -#ifdef HAVE_DLFCN_H -# include <dlfcn.h> -#endif - -#include "urldata.h" -#include <curl/curl.h> -#include "sendf.h" -#include "escape.h" -#include "transfer.h" -#include "strequal.h" -#include "strtok.h" -#include "ldap.h" -#include "curl_memory.h" - -#define _MPRINTF_REPLACE /* use our functions only */ -#include <curl/mprintf.h> - -#include "memdebug.h" - -/* WLdap32.dll functions are *not* stdcall. Must call these via __cdecl - * pointers in case libcurl was compiled as fastcall (-Gr). - */ -#if !defined(WIN32) && !defined(__cdecl) -#define __cdecl -#endif - -#ifndef LDAP_SIZELIMIT_EXCEEDED -#define LDAP_SIZELIMIT_EXCEEDED 4 -#endif - -#define DLOPEN_MODE RTLD_LAZY /*! assume all dlopen() implementations have - this */ - -#if defined(RTLD_LAZY_GLOBAL) /* It turns out some systems use this: */ -# undef DLOPEN_MODE -# define DLOPEN_MODE RTLD_LAZY_GLOBAL -#elif defined(RTLD_GLOBAL) -# undef DLOPEN_MODE -# define DLOPEN_MODE (RTLD_LAZY | RTLD_GLOBAL) -#endif - -#define DYNA_GET_FUNCTION(type, fnc) do { \ - (fnc) = (type)DynaGetFunction(#fnc); \ - if ((fnc) == NULL) \ - return CURLE_FUNCTION_NOT_FOUND; \ - } while (0) - -/*! CygWin etc. configure could set these, but we don't want it. - * Must use WLdap32.dll code. - */ -#if defined(WIN32) -#undef HAVE_DLOPEN -#undef HAVE_LIBDL -#endif - -typedef void * (*dynafunc)(void *input); - -/*********************************************************************** - */ -static void *libldap = NULL; -#ifndef WIN32 -static void *liblber = NULL; -#endif - -static int DynaOpen(const char **mod_name) -{ -#if defined(HAVE_DLOPEN) || defined(HAVE_LIBDL) - if (libldap == NULL) { - /* - * libldap.so should be able to resolve its dependency on - * liblber.so automatically, but since it does not we will - * handle it here by opening liblber.so as global. - */ - *mod_name = "liblber.so"; - liblber = dlopen(*mod_name, DLOPEN_MODE); - - /* Assume loading libldap.so will fail if loading of liblber.so failed - */ - if (liblber) { - *mod_name = "libldap.so"; - libldap = dlopen(*mod_name, RTLD_LAZY); - } - } - return (libldap != NULL && liblber != NULL); - -#elif defined(WIN32) - *mod_name = "wldap32.dll"; - if (!libldap) - libldap = (void*)LoadLibrary(*mod_name); - return (libldap != NULL); - -#else - return (0); -#endif -} - -static void DynaClose(void) -{ -#if defined(HAVE_DLOPEN) || defined(HAVE_LIBDL) - if (libldap) { - dlclose(libldap); - libldap=NULL; - } - if (liblber) { - dlclose(liblber); - liblber=NULL; - } -#elif defined(WIN32) - if (libldap) { - FreeLibrary ((HMODULE)libldap); - libldap = NULL; - } -#endif -} - -static dynafunc DynaGetFunction(const char *name) -{ - dynafunc func = (dynafunc)NULL; - -#if defined(HAVE_DLOPEN) || defined(HAVE_LIBDL) - if (libldap) { - /* This typecast magic below was brought by Joe Halpin. In ISO C, you - * cannot typecast a data pointer to a function pointer, but that's - * exactly what we need to do here to avoid compiler warnings on picky - * compilers! */ - *(void**) (&func) = dlsym(libldap, name); - } -#elif defined(WIN32) - if (libldap) { - func = (dynafunc)GetProcAddress((HINSTANCE)libldap, name); - } -#endif - return func; -} - -/*********************************************************************** - */ -typedef struct ldap_url_desc { - struct ldap_url_desc *lud_next; - char *lud_scheme; - char *lud_host; - int lud_port; - char *lud_dn; - char **lud_attrs; - int lud_scope; - char *lud_filter; - char **lud_exts; - int lud_crit_exts; -} LDAPURLDesc; - -#ifdef WIN32 -static int _ldap_url_parse (const struct connectdata *conn, - LDAPURLDesc **ludp); -static void _ldap_free_urldesc (LDAPURLDesc *ludp); - -static void (*ldap_free_urldesc)(LDAPURLDesc *) = _ldap_free_urldesc; -#endif - -#ifdef DEBUG_LDAP - #define LDAP_TRACE(x) do { \ - _ldap_trace ("%u: ", __LINE__); \ - _ldap_trace x; \ - } while (0) - - static void _ldap_trace (const char *fmt, ...); -#else - #define LDAP_TRACE(x) ((void)0) -#endif - - -CURLcode Curl_ldap(struct connectdata *conn) -{ - CURLcode status = CURLE_OK; - int rc = 0; -#ifndef WIN32 - int (*ldap_url_parse)(char *, LDAPURLDesc **); - void (*ldap_free_urldesc)(void *); -#endif - void *(__cdecl *ldap_init)(char *, int); - int (__cdecl *ldap_simple_bind_s)(void *, char *, char *); - int (__cdecl *ldap_unbind_s)(void *); - int (__cdecl *ldap_search_s)(void *, char *, int, char *, char **, - int, void **); - void *(__cdecl *ldap_first_entry)(void *, void *); - void *(__cdecl *ldap_next_entry)(void *, void *); - char *(__cdecl *ldap_err2string)(int); - char *(__cdecl *ldap_get_dn)(void *, void *); - char *(__cdecl *ldap_first_attribute)(void *, void *, void **); - char *(__cdecl *ldap_next_attribute)(void *, void *, void *); - char **(__cdecl *ldap_get_values)(void *, void *, const char *); - void (__cdecl *ldap_value_free)(char **); - void (__cdecl *ldap_memfree)(void *); - void (__cdecl *ber_free)(void *, int); - - void *server; - LDAPURLDesc *ludp = NULL; - const char *mod_name; - void *result; - void *entryIterator; /*! type should be 'LDAPMessage *' */ - int num = 0; - struct SessionHandle *data=conn->data; - - infof(data, "LDAP local: %s\n", data->change.url); - - if (!DynaOpen(&mod_name)) { - failf(data, "The %s LDAP library/libraries couldn't be opened", mod_name); - return CURLE_LIBRARY_NOT_FOUND; - } - - /* The types are needed because ANSI C distinguishes between - * pointer-to-object (data) and pointer-to-function. - */ - DYNA_GET_FUNCTION(void *(*)(char *, int), ldap_init); - DYNA_GET_FUNCTION(int (*)(void *, char *, char *), ldap_simple_bind_s); - DYNA_GET_FUNCTION(int (*)(void *), ldap_unbind_s); -#ifndef WIN32 - DYNA_GET_FUNCTION(int (*)(char *, LDAPURLDesc **), ldap_url_parse); - DYNA_GET_FUNCTION(void (*)(void *), ldap_free_urldesc); -#endif - DYNA_GET_FUNCTION(int (*)(void *, char *, int, char *, char **, int, - void **), ldap_search_s); - DYNA_GET_FUNCTION(void *(*)(void *, void *), ldap_first_entry); - DYNA_GET_FUNCTION(void *(*)(void *, void *), ldap_next_entry); - DYNA_GET_FUNCTION(char *(*)(int), ldap_err2string); - DYNA_GET_FUNCTION(char *(*)(void *, void *), ldap_get_dn); - DYNA_GET_FUNCTION(char *(*)(void *, void *, void **), ldap_first_attribute); - DYNA_GET_FUNCTION(char *(*)(void *, void *, void *), ldap_next_attribute); - DYNA_GET_FUNCTION(char **(*)(void *, void *, const char *), ldap_get_values); - DYNA_GET_FUNCTION(void (*)(char **), ldap_value_free); - DYNA_GET_FUNCTION(void (*)(void *), ldap_memfree); - DYNA_GET_FUNCTION(void (*)(void *, int), ber_free); - - server = (*ldap_init)(conn->host.name, (int)conn->port); - if (server == NULL) { - failf(data, "LDAP local: Cannot connect to %s:%d", - conn->host.name, conn->port); - status = CURLE_COULDNT_CONNECT; - goto quit; - } - - rc = (*ldap_simple_bind_s)(server, - conn->bits.user_passwd ? conn->user : NULL, - conn->bits.user_passwd ? conn->passwd : NULL); - if (rc != 0) { - failf(data, "LDAP local: %s", (*ldap_err2string)(rc)); - status = CURLE_LDAP_CANNOT_BIND; - goto quit; - } - -#ifdef WIN32 - rc = _ldap_url_parse(conn, &ludp); -#else - rc = (*ldap_url_parse)(data->change.url, &ludp); -#endif - - if (rc != 0) { - failf(data, "LDAP local: %s", (*ldap_err2string)(rc)); - status = CURLE_LDAP_INVALID_URL; - goto quit; - } - - rc = (*ldap_search_s)(server, ludp->lud_dn, ludp->lud_scope, - ludp->lud_filter, ludp->lud_attrs, 0, &result); - - if (rc != 0 && rc != LDAP_SIZELIMIT_EXCEEDED) { - failf(data, "LDAP remote: %s", (*ldap_err2string)(rc)); - status = CURLE_LDAP_SEARCH_FAILED; - goto quit; - } - - for(num = 0, entryIterator = (*ldap_first_entry)(server, result); - entryIterator; - entryIterator = (*ldap_next_entry)(server, entryIterator), num++) - { - void *ber = NULL; /*! is really 'BerElement **' */ - void *attribute; /*! suspicious that this isn't 'const' */ - char *dn = (*ldap_get_dn)(server, entryIterator); - int i; - - Curl_client_write(data, CLIENTWRITE_BODY, (char *)"DN: ", 4); - Curl_client_write(data, CLIENTWRITE_BODY, (char *)dn, 0); - Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 1); - - for (attribute = (*ldap_first_attribute)(server, entryIterator, &ber); - attribute; - attribute = (*ldap_next_attribute)(server, entryIterator, ber)) - { - char **vals = (*ldap_get_values)(server, entryIterator, attribute); - - if (vals != NULL) - { - for (i = 0; (vals[i] != NULL); i++) - { - Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\t", 1); - Curl_client_write(data, CLIENTWRITE_BODY, (char*) attribute, 0); - Curl_client_write(data, CLIENTWRITE_BODY, (char *)": ", 2); - Curl_client_write(data, CLIENTWRITE_BODY, vals[i], 0); - Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 0); - } - - /* Free memory used to store values */ - (*ldap_value_free)(vals); - } - Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 1); - - (*ldap_memfree)(attribute); - (*ldap_memfree)(dn); - } - if (ber) - (*ber_free)(ber, 0); - } - -quit: - LDAP_TRACE (("Received %d entries\n", num)); - if (rc == LDAP_SIZELIMIT_EXCEEDED) - infof(data, "There are more than %d entries\n", num); - if (ludp) - (*ldap_free_urldesc)(ludp); - if (server) - (*ldap_unbind_s)(server); - - DynaClose(); - - /* no data to transfer */ - Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL); - - return status; -} - -#ifdef DEBUG_LDAP -static void _ldap_trace (const char *fmt, ...) -{ - static int do_trace = -1; - va_list args; - - if (do_trace == -1) { - const char *env = getenv("CURL_TRACE"); - do_trace = (env && atoi(env) > 0); - } - if (!do_trace) - return; - - va_start (args, fmt); - vfprintf (stderr, fmt, args); - va_end (args); -} -#endif - -#ifdef WIN32 -/* - * Return scope-value for a scope-string. - */ -static int str2scope (const char *p) -{ - if (!stricmp(p, "one")) - return LDAP_SCOPE_ONELEVEL; - if (!stricmp(p, "onetree")) - return LDAP_SCOPE_ONELEVEL; - if (!stricmp(p, "base")) - return LDAP_SCOPE_BASE; - if (!stricmp(p, "sub")) - return LDAP_SCOPE_SUBTREE; - if (!stricmp( p, "subtree")) - return LDAP_SCOPE_SUBTREE; - return (-1); -} - -/* - * Split 'str' into strings separated by commas. - * Note: res[] points into 'str'. - */ -static char **split_str (char *str) -{ - char **res, *lasts, *s; - int i; - - for (i = 2, s = strchr(str,','); s; i++) - s = strchr(++s,','); - - res = calloc(i, sizeof(char*)); - if (!res) - return NULL; - - for (i = 0, s = strtok_r(str, ",", &lasts); s; - s = strtok_r(NULL, ",", &lasts), i++) - res[i] = s; - return res; -} - -/* - * Unescape the LDAP-URL components - */ -static bool unescape_elements (LDAPURLDesc *ludp) -{ - int i; - - if (ludp->lud_filter) { - ludp->lud_filter = curl_unescape(ludp->lud_filter, 0); - if (!ludp->lud_filter) - return (FALSE); - } - - for (i = 0; ludp->lud_attrs && ludp->lud_attrs[i]; i++) { - ludp->lud_attrs[i] = curl_unescape(ludp->lud_attrs[i], 0); - if (!ludp->lud_attrs[i]) - return (FALSE); - } - - for (i = 0; ludp->lud_exts && ludp->lud_exts[i]; i++) { - ludp->lud_exts[i] = curl_unescape(ludp->lud_exts[i], 0); - if (!ludp->lud_exts[i]) - return (FALSE); - } - - if (ludp->lud_dn) { - char *dn = ludp->lud_dn; - char *new_dn = curl_unescape(dn, 0); - - free(dn); - if (!new_dn) - return (FALSE); - ludp->lud_dn = new_dn; - } - return (TRUE); -} - -/* - * Break apart the pieces of an LDAP URL. - * Syntax: - * ldap://<hostname>:<port>/<base_dn>?<attributes>?<scope>?<filter>?<ext> - * - * <hostname> already known from 'conn->host.name'. - * <port> already known from 'conn->remote_port'. - * extract the rest from 'conn->path+1'. All fields are optional. e.g. - * ldap://<hostname>:<port>/?<attributes>?<scope>?<filter> yields ludp->lud_dn = "". - * - * Ref. http://developer.netscape.com/docs/manuals/dirsdk/csdk30/url.htm#2831915 - */ -static int _ldap_url_parse2 (const struct connectdata *conn, LDAPURLDesc *ludp) -{ - char *p, *q; - int i; - - if (!conn->path || conn->path[0] != '/' || - !checkprefix(conn->protostr, conn->data->change.url)) - return LDAP_INVALID_SYNTAX; - - ludp->lud_scope = LDAP_SCOPE_BASE; - ludp->lud_port = conn->remote_port; - ludp->lud_host = conn->host.name; - - /* parse DN (Distinguished Name). - */ - ludp->lud_dn = strdup(conn->path+1); - if (!ludp->lud_dn) - return LDAP_NO_MEMORY; - - p = strchr(ludp->lud_dn, '?'); - LDAP_TRACE (("DN '%.*s'\n", p ? (size_t)(p-ludp->lud_dn) : strlen(ludp->lud_dn), - ludp->lud_dn)); - - if (!p) - goto success; - - *p++ = '\0'; - - /* parse attributes. skip "??". - */ - q = strchr(p, '?'); - if (q) - *q++ = '\0'; - - if (*p && *p != '?') { - ludp->lud_attrs = split_str(p); - if (!ludp->lud_attrs) - return LDAP_NO_MEMORY; - - for (i = 0; ludp->lud_attrs[i]; i++) - LDAP_TRACE (("attr[%d] '%s'\n", i, ludp->lud_attrs[i])); - } - - p = q; - if (!p) - goto success; - - /* parse scope. skip "??" - */ - q = strchr(p, '?'); - if (q) - *q++ = '\0'; - - if (*p && *p != '?') { - ludp->lud_scope = str2scope(p); - if (ludp->lud_scope == -1) - return LDAP_INVALID_SYNTAX; - LDAP_TRACE (("scope %d\n", ludp->lud_scope)); - } - - p = q; - if (!p) - goto success; - - /* parse filter - */ - q = strchr(p, '?'); - if (q) - *q++ = '\0'; - if (!*p) - return LDAP_INVALID_SYNTAX; - - ludp->lud_filter = p; - LDAP_TRACE (("filter '%s'\n", ludp->lud_filter)); - - p = q; - if (!p) - goto success; - - /* parse extensions - */ - ludp->lud_exts = split_str(p); - if (!ludp->lud_exts) - return LDAP_NO_MEMORY; - - for (i = 0; ludp->lud_exts[i]; i++) - LDAP_TRACE (("exts[%d] '%s'\n", i, ludp->lud_exts[i])); - -success: - if (!unescape_elements(ludp)) - return LDAP_NO_MEMORY; - return LDAP_SUCCESS; -} - -static int _ldap_url_parse (const struct connectdata *conn, - LDAPURLDesc **ludpp) -{ - LDAPURLDesc *ludp = calloc(sizeof(*ludp), 1); - int rc; - - *ludpp = NULL; - if (!ludp) - return LDAP_NO_MEMORY; - - rc = _ldap_url_parse2 (conn, ludp); - if (rc != LDAP_SUCCESS) { - _ldap_free_urldesc(ludp); - ludp = NULL; - } - *ludpp = ludp; - return (rc); -} - -static void _ldap_free_urldesc (LDAPURLDesc *ludp) -{ - int i; - - if (!ludp) - return; - - if (ludp->lud_dn) - free(ludp->lud_dn); - - if (ludp->lud_filter) - free(ludp->lud_filter); - - if (ludp->lud_attrs) { - for (i = 0; ludp->lud_attrs[i]; i++) - free(ludp->lud_attrs[i]); - free(ludp->lud_attrs); - } - - if (ludp->lud_exts) { - for (i = 0; ludp->lud_exts[i]; i++) - free(ludp->lud_exts[i]); - free(ludp->lud_exts); - } - free (ludp); -} -#endif /* WIN32 */ -#endif /* CURL_DISABLE_LDAP */ diff --git a/Source/CTest/Curl/ldap.h b/Source/CTest/Curl/ldap.h deleted file mode 100644 index b95cf74..0000000 --- a/Source/CTest/Curl/ldap.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef __LDAP_H -#define __LDAP_H - -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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$ - ***************************************************************************/ -#ifndef CURL_DISABLE_LDAP -CURLcode Curl_ldap(struct connectdata *conn); -#endif -#endif /* __LDAP_H */ diff --git a/Source/CTest/Curl/llist.c b/Source/CTest/Curl/llist.c deleted file mode 100644 index 90ac1c8..0000000 --- a/Source/CTest/Curl/llist.c +++ /dev/null @@ -1,130 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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 <string.h> -#include <stdlib.h> - -#include "llist.h" -#include "curl_memory.h" - -/* this must be the last include file */ -#include "memdebug.h" - -void -Curl_llist_init(curl_llist *l, curl_llist_dtor dtor) -{ - l->size = 0; - l->dtor = dtor; - l->head = NULL; - l->tail = NULL; -} - -curl_llist * -Curl_llist_alloc(curl_llist_dtor dtor) -{ - curl_llist *list; - - list = (curl_llist *)malloc(sizeof(curl_llist)); - if(NULL == list) - return NULL; - - Curl_llist_init(list, dtor); - - return list; -} - -/* - * Curl_llist_insert_next() returns 1 on success and 0 on failure. - */ -int -Curl_llist_insert_next(curl_llist *list, curl_llist_element *e, const void *p) -{ - curl_llist_element *ne = - (curl_llist_element *) malloc(sizeof(curl_llist_element)); - if(!ne) - return 0; - - ne->ptr = (void *) p; - if (list->size == 0) { - list->head = ne; - list->head->prev = NULL; - list->head->next = NULL; - list->tail = ne; - } - else { - ne->next = e->next; - ne->prev = e; - if (e->next) { - e->next->prev = ne; - } - else { - list->tail = ne; - } - e->next = ne; - } - - ++list->size; - - return 1; -} - -int -Curl_llist_remove(curl_llist *list, curl_llist_element *e, void *user) -{ - if (e == NULL || list->size == 0) - return 1; - - if (e == list->head) { - list->head = e->next; - - if (list->head == NULL) - list->tail = NULL; - else - e->next->prev = NULL; - } else { - e->prev->next = e->next; - if (!e->next) - list->tail = e->prev; - else - e->next->prev = e->prev; - } - - list->dtor(user, e->ptr); - free(e); - --list->size; - - return 1; -} - -void -Curl_llist_destroy(curl_llist *list, void *user) -{ - if(list) { - while (list->size > 0) - Curl_llist_remove(list, list->tail, user); - - free(list); - } -} diff --git a/Source/CTest/Curl/llist.h b/Source/CTest/Curl/llist.h deleted file mode 100644 index 4f76513..0000000 --- a/Source/CTest/Curl/llist.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef __LLIST_H -#define __LLIST_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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 <stddef.h> - -typedef void (*curl_llist_dtor)(void *, void *); - -typedef struct _curl_llist_element { - void *ptr; - - struct _curl_llist_element *prev; - struct _curl_llist_element *next; -} curl_llist_element; - -typedef struct _curl_llist { - curl_llist_element *head; - curl_llist_element *tail; - - curl_llist_dtor dtor; - - size_t size; -} curl_llist; - -void Curl_llist_init(curl_llist *, curl_llist_dtor); -curl_llist *Curl_llist_alloc(curl_llist_dtor); -int Curl_llist_insert_next(curl_llist *, curl_llist_element *, const void *); -int Curl_llist_insert_prev(curl_llist *, curl_llist_element *, const void *); -int Curl_llist_remove(curl_llist *, curl_llist_element *, void *); -int Curl_llist_remove_next(curl_llist *, curl_llist_element *, void *); -size_t Curl_llist_count(curl_llist *); -void Curl_llist_destroy(curl_llist *, void *); - -#endif diff --git a/Source/CTest/Curl/md5.c b/Source/CTest/Curl/md5.c deleted file mode 100644 index 269726b..0000000 --- a/Source/CTest/Curl/md5.c +++ /dev/null @@ -1,348 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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" - -#ifndef USE_SSLEAY -/* This code segment is only used if OpenSSL is not provided, as if it is - we use the MD5-function provided there instead. No good duplicating - code! */ - -/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All -rights reserved. - -License to copy and use this software is granted provided that it -is identified as the "RSA Data Security, Inc. MD5 Message-Digest -Algorithm" in all material mentioning or referencing this software -or this function. - -License is also granted to make and use derivative works provided -that such works are identified as "derived from the RSA Data -Security, Inc. MD5 Message-Digest Algorithm" in all material -mentioning or referencing the derived work. - -RSA Data Security, Inc. makes no representations concerning either -the merchantability of this software or the suitability of this -software for any particular purpose. It is provided "as is" -without express or implied warranty of any kind. - -These notices must be retained in any copies of any part of this -documentation and/or software. - */ - -#include <string.h> - -/* UINT4 defines a four byte word */ -typedef unsigned int UINT4; - -/* MD5 context. */ -struct md5_ctx { - UINT4 state[4]; /* state (ABCD) */ - UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */ - unsigned char buffer[64]; /* input buffer */ -}; - -typedef struct md5_ctx MD5_CTX; - -static void MD5_Init(struct md5_ctx *); -static void MD5_Update(struct md5_ctx *, unsigned char *, unsigned int); -static void MD5_Final(unsigned char [16], struct md5_ctx *); - -/* Constants for MD5Transform routine. - */ - -#define S11 7 -#define S12 12 -#define S13 17 -#define S14 22 -#define S21 5 -#define S22 9 -#define S23 14 -#define S24 20 -#define S31 4 -#define S32 11 -#define S33 16 -#define S34 23 -#define S41 6 -#define S42 10 -#define S43 15 -#define S44 21 - -static void MD5Transform(UINT4 [4], unsigned char [64]); -static void Encode(unsigned char *, UINT4 *, unsigned int); -static void Decode(UINT4 *, unsigned char *, unsigned int); - -static unsigned char PADDING[64] = { - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -/* F, G, H and I are basic MD5 functions. - */ -#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) -#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) -#define H(x, y, z) ((x) ^ (y) ^ (z)) -#define I(x, y, z) ((y) ^ ((x) | (~z))) - -/* ROTATE_LEFT rotates x left n bits. - */ -#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) - -/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. -Rotation is separate from addition to prevent recomputation. - */ -#define FF(a, b, c, d, x, s, ac) { \ - (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define GG(a, b, c, d, x, s, ac) { \ - (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define HH(a, b, c, d, x, s, ac) { \ - (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define II(a, b, c, d, x, s, ac) { \ - (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } - -/* MD5 initialization. Begins an MD5 operation, writing a new context. - */ -static void MD5_Init(struct md5_ctx *context) -{ - context->count[0] = context->count[1] = 0; - /* Load magic initialization constants. */ - context->state[0] = 0x67452301; - context->state[1] = 0xefcdab89; - context->state[2] = 0x98badcfe; - context->state[3] = 0x10325476; -} - -/* MD5 block update operation. Continues an MD5 message-digest - operation, processing another message block, and updating the - context. - */ -static void MD5_Update (struct md5_ctx *context, /* context */ - unsigned char *input, /* input block */ - unsigned int inputLen)/* length of input block */ -{ - unsigned int i, bufindex, partLen; - - /* Compute number of bytes mod 64 */ - bufindex = (unsigned int)((context->count[0] >> 3) & 0x3F); - - /* Update number of bits */ - if ((context->count[0] += ((UINT4)inputLen << 3)) - < ((UINT4)inputLen << 3)) - context->count[1]++; - context->count[1] += ((UINT4)inputLen >> 29); - - partLen = 64 - bufindex; - - /* Transform as many times as possible. */ - if (inputLen >= partLen) { - memcpy((void *)&context->buffer[bufindex], (void *)input, partLen); - MD5Transform(context->state, context->buffer); - - for (i = partLen; i + 63 < inputLen; i += 64) - MD5Transform(context->state, &input[i]); - - bufindex = 0; - } - else - i = 0; - - /* Buffer remaining input */ - memcpy((void *)&context->buffer[bufindex], (void *)&input[i], inputLen-i); -} - -/* MD5 finalization. Ends an MD5 message-digest operation, writing the - the message digest and zeroizing the context. -*/ -static void MD5_Final(unsigned char digest[16], /* message digest */ - struct md5_ctx *context) /* context */ -{ - unsigned char bits[8]; - unsigned int count, padLen; - - /* Save number of bits */ - Encode (bits, context->count, 8); - - /* Pad out to 56 mod 64. */ - count = (unsigned int)((context->count[0] >> 3) & 0x3f); - padLen = (count < 56) ? (56 - count) : (120 - count); - MD5_Update (context, PADDING, padLen); - - /* Append length (before padding) */ - MD5_Update (context, bits, 8); - - /* Store state in digest */ - Encode (digest, context->state, 16); - - /* Zeroize sensitive information. */ - memset ((void *)context, 0, sizeof (*context)); -} - -/* MD5 basic transformation. Transforms state based on block. */ -static void MD5Transform(UINT4 state[4], - unsigned char block[64]) -{ - UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; - - Decode (x, block, 64); - - /* Round 1 */ - FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ - FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ - FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ - FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ - FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ - FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ - FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ - FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ - FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ - FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ - FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ - FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ - FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ - FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ - FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ - FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ - - /* Round 2 */ - GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ - GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ - GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ - GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ - GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ - GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ - GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ - GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ - GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ - GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ - GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ - GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ - GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ - GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ - GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ - GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ - - /* Round 3 */ - HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ - HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ - HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ - HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ - HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ - HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ - HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ - HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ - HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ - HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ - HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ - HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ - HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ - HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ - HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ - HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ - - /* Round 4 */ - II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ - II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ - II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ - II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ - II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ - II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ - II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ - II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ - II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ - II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ - II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ - II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ - II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ - II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ - II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ - II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ - - state[0] += a; - state[1] += b; - state[2] += c; - state[3] += d; - - /* Zeroize sensitive information. */ - memset((void *)x, 0, sizeof (x)); -} - -/* Encodes input (UINT4) into output (unsigned char). Assumes len is - a multiple of 4. - */ -static void Encode (unsigned char *output, - UINT4 *input, - unsigned int len) -{ - unsigned int i, j; - - for (i = 0, j = 0; j < len; i++, j += 4) { - output[j] = (unsigned char)(input[i] & 0xff); - output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); - output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); - output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); - } -} - -/* Decodes input (unsigned char) into output (UINT4). Assumes len is - a multiple of 4. -*/ -static void Decode (UINT4 *output, - unsigned char *input, - unsigned int len) -{ - unsigned int i, j; - - for (i = 0, j = 0; j < len; i++, j += 4) - output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) | - (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24); -} - -#else -/* If OpenSSL is present */ -#include <openssl/md5.h> -#include <string.h> -#endif - -#include "md5.h" - -void Curl_md5it(unsigned char *outbuffer, /* 16 bytes */ - unsigned char *input) -{ - MD5_CTX ctx; - MD5_Init(&ctx); - MD5_Update(&ctx, input, strlen((char *)input)); - MD5_Final(outbuffer, &ctx); -} diff --git a/Source/CTest/Curl/md5.h b/Source/CTest/Curl/md5.h deleted file mode 100644 index 12b3a5e..0000000 --- a/Source/CTest/Curl/md5.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef __MD5_H -#define __MD5_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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$ - ***************************************************************************/ - -void Curl_md5it(unsigned char *output, - unsigned char *input); - -#endif diff --git a/Source/CTest/Curl/memdebug.c b/Source/CTest/Curl/memdebug.c deleted file mode 100644 index 799fe7c..0000000 --- a/Source/CTest/Curl/memdebug.c +++ /dev/null @@ -1,293 +0,0 @@ -#ifdef CURLDEBUG -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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 <curl/curl.h> - -#ifdef HAVE_SYS_SOCKET_H -#include <sys/socket.h> -#endif - -#define _MPRINTF_REPLACE -#include <curl/mprintf.h> -#include "urldata.h" -#include <stdio.h> -#include <string.h> -#include <stdlib.h> - -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -#define MEMDEBUG_NODEFINES /* don't redefine the standard functions */ -#include "curl_memory.h" -#include "memdebug.h" - -struct memdebug { - size_t size; - double mem[1]; - /* I'm hoping this is the thing with the strictest alignment - * requirements. That also means we waste some space :-( */ -}; - -/* - * Note that these debug functions are very simple and they are meant to - * remain so. For advanced analysis, record a log file and write perl scripts - * to analyze them! - * - * Don't use these with multithreaded test programs! - */ - -#define logfile curl_debuglogfile -FILE *curl_debuglogfile; -static bool memlimit; /* enable memory limit */ -static long memsize; /* set number of mallocs allowed */ - -/* this sets the log file name */ -void curl_memdebug(const char *logname) -{ - if(logname) - logfile = fopen(logname, "w"); - else - logfile = stderr; -} - -/* This function sets the number of malloc() calls that should return - successfully! */ -void curl_memlimit(long limit) -{ - memlimit = TRUE; - memsize = limit; -} - -/* returns TRUE if this isn't allowed! */ -static bool countcheck(const char *func, int line, const char *source) -{ - /* if source is NULL, then the call is made internally and this check - should not be made */ - if(memlimit && source) { - if(!memsize) { - if(logfile && source) - fprintf(logfile, "LIMIT %s:%d %s reached memlimit\n", - source, line, func); - if(source) - fprintf(stderr, "LIMIT %s:%d %s reached memlimit\n", - source, line, func); - return TRUE; /* RETURN ERROR! */ - } - else - memsize--; /* countdown */ - - /* log the countdown */ - if(logfile && source) - fprintf(logfile, "LIMIT %s:%d %ld ALLOCS left\n", - source, line, memsize); - - } - - return FALSE; /* allow this */ -} - -void *curl_domalloc(size_t wantedsize, int line, const char *source) -{ - struct memdebug *mem; - size_t size; - - if(countcheck("malloc", line, source)) - return NULL; - - /* alloc at least 64 bytes */ - size = sizeof(struct memdebug)+wantedsize; - - mem=(struct memdebug *)(Curl_cmalloc)(size); - if(mem) { - /* fill memory with junk */ - memset(mem->mem, 0xA5, wantedsize); - mem->size = wantedsize; - } - - if(logfile && source) - fprintf(logfile, "MEM %s:%d malloc(%zd) = %p\n", - source, line, wantedsize, mem ? mem->mem : 0); - return (mem ? mem->mem : NULL); -} - -void *curl_docalloc(size_t wanted_elements, size_t wanted_size, - int line, const char *source) -{ - struct memdebug *mem; - size_t size, user_size; - - if(countcheck("calloc", line, source)) - return NULL; - - /* alloc at least 64 bytes */ - user_size = wanted_size * wanted_elements; - size = sizeof(struct memdebug) + user_size; - - mem = (struct memdebug *)(Curl_cmalloc)(size); - if(mem) { - /* fill memory with zeroes */ - memset(mem->mem, 0, user_size); - mem->size = user_size; - } - - if(logfile && source) - fprintf(logfile, "MEM %s:%d calloc(%u,%u) = %p\n", - source, line, wanted_elements, wanted_size, mem ? mem->mem : 0); - return (mem ? mem->mem : NULL); -} - -char *curl_dostrdup(const char *str, int line, const char *source) -{ - char *mem; - size_t len; - - curlassert(str != NULL); - - if(countcheck("strdup", line, source)) - return NULL; - - len=strlen(str)+1; - - mem=curl_domalloc(len, 0, NULL); /* NULL prevents logging */ - if (mem) - memcpy(mem, str, len); - - if(logfile) - fprintf(logfile, "MEM %s:%d strdup(%p) (%zd) = %p\n", - source, line, str, len, mem); - - return mem; -} - -/* We provide a realloc() that accepts a NULL as pointer, which then - performs a malloc(). In order to work with ares. */ -void *curl_dorealloc(void *ptr, size_t wantedsize, - int line, const char *source) -{ - struct memdebug *mem=NULL; - - size_t size = sizeof(struct memdebug)+wantedsize; - - if(countcheck("realloc", line, source)) - return NULL; - - if(ptr) - mem = (struct memdebug *)((char *)ptr - offsetof(struct memdebug, mem)); - - mem=(struct memdebug *)(Curl_crealloc)(mem, size); - if(logfile) - fprintf(logfile, "MEM %s:%d realloc(0x%x, %zd) = %p\n", - source, line, ptr, wantedsize, mem?mem->mem:NULL); - - if(mem) { - mem->size = wantedsize; - return mem->mem; - } - - return NULL; -} - -void curl_dofree(void *ptr, int line, const char *source) -{ - struct memdebug *mem; - - curlassert(ptr != NULL); - - mem = (struct memdebug *)((char *)ptr - offsetof(struct memdebug, mem)); - - /* destroy */ - memset(mem->mem, 0x13, mem->size); - - /* free for real */ - (Curl_cfree)(mem); - - if(logfile) - fprintf(logfile, "MEM %s:%d free(%p)\n", source, line, ptr); -} - -int curl_socket(int domain, int type, int protocol, int line, - const char *source) -{ - int sockfd=(socket)(domain, type, protocol); - if(logfile && (sockfd!=-1)) - fprintf(logfile, "FD %s:%d socket() = %d\n", - source, line, sockfd); - return sockfd; -} - -int curl_accept(int s, void *saddr, void *saddrlen, - int line, const char *source) -{ - struct sockaddr *addr = (struct sockaddr *)saddr; - socklen_t *addrlen = (socklen_t *)saddrlen; - int sockfd=(accept)(s, addr, addrlen); - if(logfile) - fprintf(logfile, "FD %s:%d accept() = %d\n", - source, line, sockfd); - return sockfd; -} - -/* this is our own defined way to close sockets on *ALL* platforms */ -int curl_sclose(int sockfd, int line, const char *source) -{ - int res=sclose(sockfd); - if(logfile) - fprintf(logfile, "FD %s:%d sclose(%d)\n", - source, line, sockfd); - return res; -} - -FILE *curl_fopen(const char *file, const char *mode, - int line, const char *source) -{ - FILE *res=(fopen)(file, mode); - if(logfile) - fprintf(logfile, "FILE %s:%d fopen(\"%s\",\"%s\") = %p\n", - source, line, file, mode, res); - return res; -} - -int curl_fclose(FILE *file, int line, const char *source) -{ - int res; - - curlassert(file != NULL); - - res=(fclose)(file); - if(logfile) - fprintf(logfile, "FILE %s:%d fclose(%p)\n", - source, line, file); - return res; -} -#else -#ifdef VMS -int VOID_VAR_MEMDEBUG; -#else -/* we provide a fake do-nothing function here to avoid compiler warnings */ -void curl_memdebug(void) {} -#endif /* VMS */ -#endif /* CURLDEBUG */ diff --git a/Source/CTest/Curl/memdebug.h b/Source/CTest/Curl/memdebug.h deleted file mode 100644 index 42574cf..0000000 --- a/Source/CTest/Curl/memdebug.h +++ /dev/null @@ -1,108 +0,0 @@ -#ifdef CURLDEBUG -#ifndef _CURL_MEDEBUG_H -#define _CURL_MEDEBUG_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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$ - ***************************************************************************/ - -/* - * CAUTION: this header is designed to work when included by the app-side - * as well as the library. Do not mix with library internals! - */ - -#include "setup.h" - -#ifdef HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif - -#ifdef HAVE_SYS_SOCKET_H -#include <sys/socket.h> -#endif -#include <stdio.h> -#ifdef HAVE_MEMORY_H -#include <memory.h> -#endif - -#define logfile curl_debuglogfile - -extern FILE *logfile; - -/* memory functions */ -void *curl_domalloc(size_t size, int line, const char *source); -void *curl_docalloc(size_t elements, size_t size, int line, const char *source); -void *curl_dorealloc(void *ptr, size_t size, int line, const char *source); -void curl_dofree(void *ptr, int line, const char *source); -char *curl_dostrdup(const char *str, int line, const char *source); -void curl_memdebug(const char *logname); -void curl_memlimit(long limit); - -/* file descriptor manipulators */ -int curl_socket(int domain, int type, int protocol, int line , const char *); -int curl_sclose(int sockfd, int, const char *source); -int curl_accept(int s, void *addr, void *addrlen, - int line, const char *source); - -/* FILE functions */ -FILE *curl_fopen(const char *file, const char *mode, int line, - const char *source); -int curl_fclose(FILE *file, int line, const char *source); - -#ifndef MEMDEBUG_NODEFINES - -/* Set this symbol on the command-line, recompile all lib-sources */ -#undef strdup -#define strdup(ptr) curl_dostrdup(ptr, __LINE__, __FILE__) -#define malloc(size) curl_domalloc(size, __LINE__, __FILE__) -#define calloc(nbelem,size) curl_docalloc(nbelem, size, __LINE__, __FILE__) -#define realloc(ptr,size) curl_dorealloc(ptr, size, __LINE__, __FILE__) -#define free(ptr) curl_dofree(ptr, __LINE__, __FILE__) - -#define socket(domain,type,protocol)\ - curl_socket(domain,type,protocol,__LINE__,__FILE__) -#undef accept /* for those with accept as a macro */ -#define accept(sock,addr,len)\ - curl_accept(sock,addr,len,__LINE__,__FILE__) - -#define getaddrinfo(host,serv,hint,res) \ - curl_dogetaddrinfo(host,serv,hint,res,__LINE__,__FILE__) -#define getnameinfo(sa,salen,host,hostlen,serv,servlen,flags) \ - curl_dogetnameinfo(sa,salen,host,hostlen,serv,servlen,flags, __LINE__, \ - __FILE__) -#define freeaddrinfo(data) \ - curl_dofreeaddrinfo(data,__LINE__,__FILE__) - -/* sclose is probably already defined, redefine it! */ -#undef sclose -#define sclose(sockfd) curl_sclose(sockfd,__LINE__,__FILE__) -/* ares-adjusted define: */ -#undef closesocket -#define closesocket(sockfd) curl_sclose(sockfd,__LINE__,__FILE__) - -#undef fopen -#define fopen(file,mode) curl_fopen(file,mode,__LINE__,__FILE__) -#define fclose(file) curl_fclose(file,__LINE__,__FILE__) - -#endif /* MEMDEBUG_NODEFINES */ - -#endif /* _CURL_MEDEBUG_H */ -#endif /* CURLDEBUG */ diff --git a/Source/CTest/Curl/mprintf.c b/Source/CTest/Curl/mprintf.c deleted file mode 100644 index d620fcd..0000000 --- a/Source/CTest/Curl/mprintf.c +++ /dev/null @@ -1,1219 +0,0 @@ -/**************************************************************************** - * - * $Id$ - * - ************************************************************************* - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND - * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. - * - * Purpose: - * A merge of Bjorn Reese's format() function and Daniel's dsprintf() - * 1.0. A full blooded printf() clone with full support for <num>$ - * everywhere (parameters, widths and precisions) including variabled - * sized parameters (like doubles, long longs, long doubles and even - * void * in 64-bit architectures). - * - * Current restrictions: - * - Max 128 parameters - * - No 'long double' support. - * - * If you ever want truly portable and good *printf() clones, the project that - * took on from here is named 'Trio' and you find more details on the trio web - * page at http://daniel.haxx.se/trio/ - */ - - -#include "setup.h" -#include <sys/types.h> -#include <stdio.h> -#include <stdlib.h> -#include <stdarg.h> -#include <ctype.h> -#include <string.h> - -#include <curl/mprintf.h> - -#ifndef SIZEOF_LONG_DOUBLE -#define SIZEOF_LONG_DOUBLE 0 -#endif - -#ifndef SIZEOF_SIZE_T -/* default to 4 bytes for size_t unless defined in the config.h */ -#define SIZEOF_SIZE_T 4 -#endif - -#ifdef DPRINTF_DEBUG -#define HAVE_LONGLONG -#define LONG_LONG long long -#define ENABLE_64BIT -#endif - -#include "curl_memory.h" -/* The last #include file should be: */ -#include "memdebug.h" - -#define BUFFSIZE 256 /* buffer for long-to-str and float-to-str calcs */ -#define MAX_PARAMETERS 128 /* lame static limit */ - -#undef TRUE -#undef FALSE -#undef BOOL -#ifdef __cplusplus -# define TRUE true -# define FALSE false -# define BOOL bool -#else -# define TRUE ((char)(1 == 1)) -# define FALSE ((char)(0 == 1)) -# define BOOL char -#endif - - -/* Lower-case digits. */ -static const char lower_digits[] = "0123456789abcdefghijklmnopqrstuvwxyz"; - -/* Upper-case digits. */ -static const char upper_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - -#define OUTCHAR(x) \ - do{ \ - if(stream((unsigned char)(x), (FILE *)data) != -1) \ - done++; \ - else \ - return done; /* return immediately on failure */ \ - } while(0) - -/* Data type to read from the arglist */ -typedef enum { - FORMAT_UNKNOWN = 0, - FORMAT_STRING, - FORMAT_PTR, - FORMAT_INT, - FORMAT_INTPTR, - FORMAT_LONG, - FORMAT_LONGLONG, - FORMAT_DOUBLE, - FORMAT_LONGDOUBLE, - FORMAT_WIDTH /* For internal use */ -} FormatType; - -/* convertion and display flags */ -enum { - FLAGS_NEW = 0, - FLAGS_SPACE = 1<<0, - FLAGS_SHOWSIGN = 1<<1, - FLAGS_LEFT = 1<<2, - FLAGS_ALT = 1<<3, - FLAGS_SHORT = 1<<4, - FLAGS_LONG = 1<<5, - FLAGS_LONGLONG = 1<<6, - FLAGS_LONGDOUBLE = 1<<7, - FLAGS_PAD_NIL = 1<<8, - FLAGS_UNSIGNED = 1<<9, - FLAGS_OCTAL = 1<<10, - FLAGS_HEX = 1<<11, - FLAGS_UPPER = 1<<12, - FLAGS_WIDTH = 1<<13, /* '*' or '*<num>$' used */ - FLAGS_WIDTHPARAM = 1<<14, /* width PARAMETER was specified */ - FLAGS_PREC = 1<<15, /* precision was specified */ - FLAGS_PRECPARAM = 1<<16, /* precision PARAMETER was specified */ - FLAGS_CHAR = 1<<17, /* %c story */ - FLAGS_FLOATE = 1<<18, /* %e or %E */ - FLAGS_FLOATG = 1<<19 /* %g or %G */ -}; - -typedef struct { - FormatType type; - int flags; - long width; /* width OR width parameter number */ - long precision; /* precision OR precision parameter number */ - union { - char *str; - void *ptr; - long num; -#ifdef ENABLE_64BIT - LONG_LONG lnum; -#endif - double dnum; - } data; -} va_stack_t; - -struct nsprintf { - char *buffer; - size_t length; - size_t max; -}; - -struct asprintf { - char *buffer; /* allocated buffer */ - size_t len; /* length of string */ - size_t alloc; /* length of alloc */ - bool fail; /* TRUE if an alloc has failed and thus the output is not - the complete data */ -}; - -int curl_msprintf(char *buffer, const char *format, ...); - -static long dprintf_DollarString(char *input, char **end) -{ - int number=0; - while(isdigit((int)*input)) { - number *= 10; - number += *input-'0'; - input++; - } - if(number && ('$'==*input++)) { - *end = input; - return number; - } - return 0; -} - -static BOOL dprintf_IsQualifierNoDollar(char c) -{ - switch (c) { - case '-': case '+': case ' ': case '#': case '.': - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - case 'h': case 'l': case 'L': case 'z': case 'q': - case '*': case 'O': - return TRUE; - default: - return FALSE; - } -} - -#ifdef DPRINTF_DEBUG2 -int dprintf_Pass1Report(va_stack_t *vto, int max) -{ - int i; - char buffer[128]; - int bit; - int flags; - - for(i=0; i<max; i++) { - char *type; - switch(vto[i].type) { - case FORMAT_UNKNOWN: - type = "unknown"; - break; - case FORMAT_STRING: - type ="string"; - break; - case FORMAT_PTR: - type ="pointer"; - break; - case FORMAT_INT: - type = "int"; - break; - case FORMAT_LONG: - type = "long"; - break; - case FORMAT_LONGLONG: - type = "long long"; - break; - case FORMAT_DOUBLE: - type = "double"; - break; - case FORMAT_LONGDOUBLE: - type = "long double"; - break; - } - - - buffer[0]=0; - - for(bit=0; bit<31; bit++) { - flags = vto[i].flags & (1<<bit); - - if(flags & FLAGS_SPACE) - strcat(buffer, "space "); - else if(flags & FLAGS_SHOWSIGN) - strcat(buffer, "plus "); - else if(flags & FLAGS_LEFT) - strcat(buffer, "left "); - else if(flags & FLAGS_ALT) - strcat(buffer, "alt "); - else if(flags & FLAGS_SHORT) - strcat(buffer, "short "); - else if(flags & FLAGS_LONG) - strcat(buffer, "long "); - else if(flags & FLAGS_LONGLONG) - strcat(buffer, "longlong "); - else if(flags & FLAGS_LONGDOUBLE) - strcat(buffer, "longdouble "); - else if(flags & FLAGS_PAD_NIL) - strcat(buffer, "padnil "); - else if(flags & FLAGS_UNSIGNED) - strcat(buffer, "unsigned "); - else if(flags & FLAGS_OCTAL) - strcat(buffer, "octal "); - else if(flags & FLAGS_HEX) - strcat(buffer, "hex "); - else if(flags & FLAGS_UPPER) - strcat(buffer, "upper "); - else if(flags & FLAGS_WIDTH) - strcat(buffer, "width "); - else if(flags & FLAGS_WIDTHPARAM) - strcat(buffer, "widthparam "); - else if(flags & FLAGS_PREC) - strcat(buffer, "precision "); - else if(flags & FLAGS_PRECPARAM) - strcat(buffer, "precparam "); - else if(flags & FLAGS_CHAR) - strcat(buffer, "char "); - else if(flags & FLAGS_FLOATE) - strcat(buffer, "floate "); - else if(flags & FLAGS_FLOATG) - strcat(buffer, "floatg "); - } - printf("REPORT: %d. %s [%s]\n", i, type, buffer); - - } - - -} -#endif - -/****************************************************************** - * - * Pass 1: - * Create an index with the type of each parameter entry and its - * value (may vary in size) - * - ******************************************************************/ - -static long dprintf_Pass1(char *format, va_stack_t *vto, char **endpos, - va_list arglist) -{ - char *fmt = format; - int param_num = 0; - long this_param; - long width; - long precision; - int flags; - long max_param=0; - long i; - - while (*fmt) { - if (*fmt++ == '%') { - if (*fmt == '%') { - fmt++; - continue; /* while */ - } - - flags = FLAGS_NEW; - - /* Handle the positional case (N$) */ - - param_num++; - - this_param = dprintf_DollarString(fmt, &fmt); - if (0 == this_param) - /* we got no positional, get the next counter */ - this_param = param_num; - - if (this_param > max_param) - max_param = this_param; - - /* - * The parameter with number 'i' should be used. Next, we need - * to get SIZE and TYPE of the parameter. Add the information - * to our array. - */ - - width = 0; - precision = 0; - - /* Handle the flags */ - - while (dprintf_IsQualifierNoDollar(*fmt)) { - switch (*fmt++) { - case ' ': - flags |= FLAGS_SPACE; - break; - case '+': - flags |= FLAGS_SHOWSIGN; - break; - case '-': - flags |= FLAGS_LEFT; - flags &= ~FLAGS_PAD_NIL; - break; - case '#': - flags |= FLAGS_ALT; - break; - case '.': - flags |= FLAGS_PREC; - if ('*' == *fmt) { - /* The precision is picked from a specified parameter */ - - flags |= FLAGS_PRECPARAM; - fmt++; - param_num++; - - i = dprintf_DollarString(fmt, &fmt); - if (i) - precision = i; - else - precision = param_num; - - if (precision > max_param) - max_param = precision; - } - else { - flags |= FLAGS_PREC; - precision = strtol(fmt, &fmt, 10); - } - break; - case 'h': - flags |= FLAGS_SHORT; - break; - case 'l': - if (flags & FLAGS_LONG) - flags |= FLAGS_LONGLONG; - else - flags |= FLAGS_LONG; - break; - case 'L': - flags |= FLAGS_LONGDOUBLE; - break; - case 'q': - flags |= FLAGS_LONGLONG; - break; - case 'z': - /* the code below generates a warning if -Wunreachable-code is - used */ -#if SIZEOF_SIZE_T>4 - flags |= FLAGS_LONGLONG; -#else - flags |= FLAGS_LONG; -#endif - break; - case 'O': -#if SIZEOF_CURL_OFF_T > 4 - flags |= FLAGS_LONGLONG; -#else - flags |= FLAGS_LONG; -#endif - break; - case '0': - if (!(flags & FLAGS_LEFT)) - flags |= FLAGS_PAD_NIL; - /* FALLTHROUGH */ - case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - flags |= FLAGS_WIDTH; - width = strtol(fmt-1, &fmt, 10); - break; - case '*': /* Special case */ - flags |= FLAGS_WIDTHPARAM; - param_num++; - - i = dprintf_DollarString(fmt, &fmt); - if(i) - width = i; - else - width = param_num; - if(width > max_param) - max_param=width; - break; - default: - break; - } - } /* switch */ - - /* Handle the specifier */ - - i = this_param - 1; - - switch (*fmt) { - case 'S': - flags |= FLAGS_ALT; - /* FALLTHROUGH */ - case 's': - vto[i].type = FORMAT_STRING; - break; - case 'n': - vto[i].type = FORMAT_INTPTR; - break; - case 'p': - vto[i].type = FORMAT_PTR; - break; - case 'd': case 'i': - vto[i].type = FORMAT_INT; - break; - case 'u': - vto[i].type = FORMAT_INT; - flags |= FLAGS_UNSIGNED; - break; - case 'o': - vto[i].type = FORMAT_INT; - flags |= FLAGS_OCTAL; - break; - case 'x': - vto[i].type = FORMAT_INT; - flags |= FLAGS_HEX; - break; - case 'X': - vto[i].type = FORMAT_INT; - flags |= FLAGS_HEX|FLAGS_UPPER; - break; - case 'c': - vto[i].type = FORMAT_INT; - flags |= FLAGS_CHAR; - break; - case 'f': - vto[i].type = FORMAT_DOUBLE; - break; - case 'e': - vto[i].type = FORMAT_DOUBLE; - flags |= FLAGS_FLOATE; - break; - case 'E': - vto[i].type = FORMAT_DOUBLE; - flags |= FLAGS_FLOATE|FLAGS_UPPER; - break; - case 'g': - vto[i].type = FORMAT_DOUBLE; - flags |= FLAGS_FLOATG; - break; - case 'G': - vto[i].type = FORMAT_DOUBLE; - flags |= FLAGS_FLOATG|FLAGS_UPPER; - break; - default: - vto[i].type = FORMAT_UNKNOWN; - break; - } /* switch */ - - vto[i].flags = flags; - vto[i].width = width; - vto[i].precision = precision; - - if (flags & FLAGS_WIDTHPARAM) { - /* we have the width specified from a parameter, so we make that - parameter's info setup properly */ - vto[i].width = width - 1; - i = width - 1; - vto[i].type = FORMAT_WIDTH; - vto[i].flags = FLAGS_NEW; - vto[i].precision = vto[i].width = 0; /* can't use width or precision - of width! */ - } - if (flags & FLAGS_PRECPARAM) { - /* we have the precision specified from a parameter, so we make that - parameter's info setup properly */ - vto[i].precision = precision - 1; - i = precision - 1; - vto[i].type = FORMAT_WIDTH; - vto[i].flags = FLAGS_NEW; - vto[i].precision = vto[i].width = 0; /* can't use width or precision - of width! */ - } - *endpos++ = fmt + 1; /* end of this sequence */ - } - } - -#ifdef DPRINTF_DEBUG2 - dprintf_Pass1Report(vto, max_param); -#endif - - /* Read the arg list parameters into our data list */ - for (i=0; i<max_param; i++) { - if ((i + 1 < max_param) && (vto[i + 1].type == FORMAT_WIDTH)) - { - /* Width/precision arguments must be read before the main argument - * they are attached to - */ - vto[i + 1].data.num = va_arg(arglist, int); - } - - switch (vto[i].type) - { - case FORMAT_STRING: - vto[i].data.str = va_arg(arglist, char *); - break; - - case FORMAT_INTPTR: - case FORMAT_UNKNOWN: - case FORMAT_PTR: - vto[i].data.ptr = va_arg(arglist, void *); - break; - - case FORMAT_INT: -#ifdef ENABLE_64BIT - if(vto[i].flags & FLAGS_LONGLONG) - vto[i].data.lnum = va_arg(arglist, LONG_LONG); - else -#endif - if(vto[i].flags & FLAGS_LONG) - vto[i].data.num = va_arg(arglist, long); - else - vto[i].data.num = va_arg(arglist, int); - break; - - case FORMAT_DOUBLE: - vto[i].data.dnum = va_arg(arglist, double); - break; - - case FORMAT_WIDTH: - /* Argument has been read. Silently convert it into an integer - * for later use - */ - vto[i].type = FORMAT_INT; - break; - - default: - break; - } - } - - return max_param; - -} - -static int dprintf_formatf( - void *data, /* untouched by format(), just sent to the stream() function in - the second argument */ - /* function pointer called for each output character */ - int (*stream)(int, FILE *), - const char *format, /* %-formatted string */ - va_list ap_save) /* list of parameters */ -{ - /* Base-36 digits for numbers. */ - const char *digits = lower_digits; - - /* Pointer into the format string. */ - char *f; - - /* Number of characters written. */ - int done = 0; - - long param; /* current parameter to read */ - long param_num=0; /* parameter counter */ - - va_stack_t vto[MAX_PARAMETERS]; - char *endpos[MAX_PARAMETERS]; - char **end; - - char work[BUFFSIZE]; - - va_stack_t *p; - - /* Do the actual %-code parsing */ - dprintf_Pass1((char *)format, vto, endpos, ap_save); - - end = &endpos[0]; /* the initial end-position from the list dprintf_Pass1() - created for us */ - - f = (char *)format; - while (*f != '\0') { - /* Format spec modifiers. */ - char alt; - - /* Width of a field. */ - long width; - - /* Precision of a field. */ - long prec; - - /* Decimal integer is negative. */ - char is_neg; - - /* Base of a number to be written. */ - long base; - - /* Integral values to be written. */ -#ifdef ENABLE_64BIT - unsigned LONG_LONG num; -#else - unsigned long num; -#endif - long signed_num; - - if (*f != '%') { - /* This isn't a format spec, so write everything out until the next one - OR end of string is reached. */ - do { - OUTCHAR(*f); - } while(*++f && ('%' != *f)); - continue; - } - - ++f; - - /* Check for "%%". Note that although the ANSI standard lists - '%' as a conversion specifier, it says "The complete format - specification shall be `%%'," so we can avoid all the width - and precision processing. */ - if (*f == '%') { - ++f; - OUTCHAR('%'); - continue; - } - - /* If this is a positional parameter, the position must follow imediately - after the %, thus create a %<num>$ sequence */ - param=dprintf_DollarString(f, &f); - - if(!param) - param = param_num; - else - --param; - - param_num++; /* increase this always to allow "%2$s %1$s %s" and then the - third %s will pick the 3rd argument */ - - p = &vto[param]; - - /* pick up the specified width */ - if(p->flags & FLAGS_WIDTHPARAM) - width = vto[p->width].data.num; - else - width = p->width; - - /* pick up the specified precision */ - if(p->flags & FLAGS_PRECPARAM) - prec = vto[p->precision].data.num; - else if(p->flags & FLAGS_PREC) - prec = p->precision; - else - prec = -1; - - alt = (p->flags & FLAGS_ALT)?TRUE:FALSE; - - switch (p->type) { - case FORMAT_INT: - num = p->data.num; - if(p->flags & FLAGS_CHAR) { - /* Character. */ - if (!(p->flags & FLAGS_LEFT)) - while (--width > 0) - OUTCHAR(' '); - OUTCHAR((char) num); - if (p->flags & FLAGS_LEFT) - while (--width > 0) - OUTCHAR(' '); - break; - } - if(p->flags & FLAGS_UNSIGNED) { - /* Decimal unsigned integer. */ - base = 10; - goto unsigned_number; - } - if(p->flags & FLAGS_OCTAL) { - /* Octal unsigned integer. */ - base = 8; - goto unsigned_number; - } - if(p->flags & FLAGS_HEX) { - /* Hexadecimal unsigned integer. */ - - digits = (p->flags & FLAGS_UPPER)? upper_digits : lower_digits; - base = 16; - goto unsigned_number; - } - - /* Decimal integer. */ - base = 10; - -#ifdef ENABLE_64BIT - if(p->flags & FLAGS_LONGLONG) { - /* long long */ - is_neg = p->data.lnum < 0; - num = is_neg ? (- p->data.lnum) : p->data.lnum; - } - else -#endif - { - signed_num = (long) num; - is_neg = signed_num < 0; - num = is_neg ? (- signed_num) : signed_num; - } - goto number; - - unsigned_number: - /* Unsigned number of base BASE. */ - is_neg = 0; - - number: - /* Number of base BASE. */ - { - char *workend = &work[sizeof(work) - 1]; - char *w; - - /* Supply a default precision if none was given. */ - if (prec == -1) - prec = 1; - - /* Put the number in WORK. */ - w = workend; - while (num > 0) { - *w-- = digits[num % base]; - num /= base; - } - width -= workend - w; - prec -= workend - w; - - if (alt && base == 8 && prec <= 0) { - *w-- = '0'; - --width; - } - - if (prec > 0) { - width -= prec; - while (prec-- > 0) - *w-- = '0'; - } - - if (alt && base == 16) - width -= 2; - - if (is_neg || (p->flags & FLAGS_SHOWSIGN) || (p->flags & FLAGS_SPACE)) - --width; - - if (!(p->flags & FLAGS_LEFT) && !(p->flags & FLAGS_PAD_NIL)) - while (width-- > 0) - OUTCHAR(' '); - - if (is_neg) - OUTCHAR('-'); - else if (p->flags & FLAGS_SHOWSIGN) - OUTCHAR('+'); - else if (p->flags & FLAGS_SPACE) - OUTCHAR(' '); - - if (alt && base == 16) { - OUTCHAR('0'); - if(p->flags & FLAGS_UPPER) - OUTCHAR('X'); - else - OUTCHAR('x'); - } - - if (!(p->flags & FLAGS_LEFT) && (p->flags & FLAGS_PAD_NIL)) - while (width-- > 0) - OUTCHAR('0'); - - /* Write the number. */ - while (++w <= workend) { - OUTCHAR(*w); - } - - if (p->flags & FLAGS_LEFT) - while (width-- > 0) - OUTCHAR(' '); - } - break; - - case FORMAT_STRING: - /* String. */ - { - static char null[] = "(nil)"; - char *str; - size_t len; - - str = (char *) p->data.str; - if ( str == NULL) { - /* Write null[] if there's space. */ - if (prec == -1 || prec >= (long) sizeof(null) - 1) { - str = null; - len = sizeof(null) - 1; - /* Disable quotes around (nil) */ - p->flags &= (~FLAGS_ALT); - } - else { - str = (char *)""; - len = 0; - } - } - else - len = strlen(str); - - if (prec != -1 && (size_t) prec < len) - len = prec; - width -= len; - - if (p->flags & FLAGS_ALT) - OUTCHAR('"'); - - if (!(p->flags&FLAGS_LEFT)) - while (width-- > 0) - OUTCHAR(' '); - - while (len-- > 0) - OUTCHAR(*str++); - if (p->flags&FLAGS_LEFT) - while (width-- > 0) - OUTCHAR(' '); - - if (p->flags & FLAGS_ALT) - OUTCHAR('"'); - } - break; - - case FORMAT_PTR: - /* Generic pointer. */ - { - void *ptr; - ptr = (void *) p->data.ptr; - if (ptr != NULL) { - /* If the pointer is not NULL, write it as a %#x spec. */ - base = 16; - digits = (p->flags & FLAGS_UPPER)? upper_digits : lower_digits; - alt = 1; - num = (unsigned long) ptr; - is_neg = 0; - goto number; - } - else { - /* Write "(nil)" for a nil pointer. */ - static char strnil[] = "(nil)"; - char *point; - - width -= sizeof(strnil) - 1; - if (p->flags & FLAGS_LEFT) - while (width-- > 0) - OUTCHAR(' '); - for (point = strnil; *point != '\0'; ++point) - OUTCHAR(*point); - if (! (p->flags & FLAGS_LEFT)) - while (width-- > 0) - OUTCHAR(' '); - } - } - break; - - case FORMAT_DOUBLE: - { - char formatbuf[32]="%"; - char *fptr; - size_t left = sizeof(formatbuf)-strlen(formatbuf); - int len; - - width = -1; - if (p->flags & FLAGS_WIDTH) - width = p->width; - else if (p->flags & FLAGS_WIDTHPARAM) - width = vto[p->width].data.num; - - prec = -1; - if (p->flags & FLAGS_PREC) - prec = p->precision; - else if (p->flags & FLAGS_PRECPARAM) - prec = vto[p->precision].data.num; - - if (p->flags & FLAGS_LEFT) - strcat(formatbuf, "-"); - if (p->flags & FLAGS_SHOWSIGN) - strcat(formatbuf, "+"); - if (p->flags & FLAGS_SPACE) - strcat(formatbuf, " "); - if (p->flags & FLAGS_ALT) - strcat(formatbuf, "#"); - - fptr=&formatbuf[strlen(formatbuf)]; - - if(width >= 0) { - /* RECURSIVE USAGE */ - len = curl_msnprintf(fptr, left, "%ld", width); - fptr += len; - left -= len; - } - if(prec >= 0) { - /* RECURSIVE USAGE */ - len = curl_msnprintf(fptr, left, ".%ld", prec); - fptr += len; - left -= len; - } - (void)left; - if (p->flags & FLAGS_LONG) - *fptr++ = 'l'; - - if (p->flags & FLAGS_FLOATE) - *fptr++ = p->flags&FLAGS_UPPER ? 'E':'e'; - else if (p->flags & FLAGS_FLOATG) - *fptr++ = p->flags & FLAGS_UPPER ? 'G' : 'g'; - else - *fptr++ = 'f'; - - *fptr = 0; /* and a final zero termination */ - - /* NOTE NOTE NOTE!! Not all sprintf() implementations returns number - of output characters */ - (sprintf)(work, formatbuf, p->data.dnum); - - for(fptr=work; *fptr; fptr++) - OUTCHAR(*fptr); - } - break; - - case FORMAT_INTPTR: - /* Answer the count of characters written. */ -#ifdef ENABLE_64BIT - if (p->flags & FLAGS_LONGLONG) - *(LONG_LONG *) p->data.ptr = (LONG_LONG)done; - else -#endif - if (p->flags & FLAGS_LONG) - *(long *) p->data.ptr = (long)done; - else if (!(p->flags & FLAGS_SHORT)) - *(int *) p->data.ptr = (int)done; - else - *(short *) p->data.ptr = (short)done; - break; - - default: - break; - } - f = *end++; /* goto end of %-code */ - - } - return done; -} - -/* fputc() look-alike */ -static int addbyter(int output, FILE *data) -{ - struct nsprintf *infop=(struct nsprintf *)data; - unsigned char outc = (unsigned char)output; - - if(infop->length < infop->max) { - /* only do this if we haven't reached max length yet */ - infop->buffer[0] = outc; /* store */ - infop->buffer++; /* increase pointer */ - infop->length++; /* we are now one byte larger */ - return outc; /* fputc() returns like this on success */ - } - return -1; -} - -int curl_mvsnprintf(char *buffer, size_t maxlength, const char *format, - va_list ap_save) -{ - int retcode; - struct nsprintf info; - - info.buffer = buffer; - info.length = 0; - info.max = maxlength; - - retcode = dprintf_formatf(&info, addbyter, format, ap_save); - if(info.max) { - /* we terminate this with a zero byte */ - if(info.max == info.length) - /* we're at maximum, scrap the last letter */ - info.buffer[-1] = 0; - else - info.buffer[0] = 0; - } - return retcode; -} - -int curl_msnprintf(char *buffer, size_t maxlength, const char *format, ...) -{ - int retcode; - va_list ap_save; /* argument pointer */ - va_start(ap_save, format); - retcode = curl_mvsnprintf(buffer, maxlength, format, ap_save); - va_end(ap_save); - return retcode; -} - -/* fputc() look-alike */ -static int alloc_addbyter(int output, FILE *data) -{ - struct asprintf *infop=(struct asprintf *)data; - unsigned char outc = (unsigned char)output; - - if(!infop->buffer) { - infop->buffer=(char *)malloc(32); - if(!infop->buffer) { - infop->fail = TRUE; - return -1; /* fail */ - } - infop->alloc = 32; - infop->len =0; - } - else if(infop->len+1 >= infop->alloc) { - char *newptr; - - newptr = (char *)realloc(infop->buffer, infop->alloc*2); - - if(!newptr) { - infop->fail = TRUE; - return -1; - } - infop->buffer = newptr; - infop->alloc *= 2; - } - - infop->buffer[ infop->len ] = outc; - - infop->len++; - - return outc; /* fputc() returns like this on success */ -} - -char *curl_maprintf(const char *format, ...) -{ - va_list ap_save; /* argument pointer */ - int retcode; - struct asprintf info; - - info.buffer = NULL; - info.len = 0; - info.alloc = 0; - info.fail = FALSE; - - va_start(ap_save, format); - retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save); - va_end(ap_save); - if((-1 == retcode) || info.fail) { - if(info.alloc) - free(info.buffer); - return NULL; - } - if(info.alloc) { - info.buffer[info.len] = 0; /* we terminate this with a zero byte */ - return info.buffer; - } - else - return strdup(""); -} - -char *curl_mvaprintf(const char *format, va_list ap_save) -{ - int retcode; - struct asprintf info; - - info.buffer = NULL; - info.len = 0; - info.alloc = 0; - info.fail = FALSE; - - retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save); - if((-1 == retcode) || info.fail) { - if(info.alloc) - free(info.buffer); - return NULL; - } - - if(info.alloc) { - info.buffer[info.len] = 0; /* we terminate this with a zero byte */ - return info.buffer; - } - else - return strdup(""); -} - -static int storebuffer(int output, FILE *data) -{ - char **buffer = (char **)data; - unsigned char outc = (unsigned char)output; - **buffer = outc; - (*buffer)++; - return outc; /* act like fputc() ! */ -} - -int curl_msprintf(char *buffer, const char *format, ...) -{ - va_list ap_save; /* argument pointer */ - int retcode; - va_start(ap_save, format); - retcode = dprintf_formatf(&buffer, storebuffer, format, ap_save); - va_end(ap_save); - *buffer=0; /* we terminate this with a zero byte */ - return retcode; -} - -#ifndef WIN32 /* not needed on win32 */ -extern int fputc(int, FILE *); -#endif - -int curl_mprintf(const char *format, ...) -{ - int retcode; - va_list ap_save; /* argument pointer */ - va_start(ap_save, format); - retcode = dprintf_formatf(stdout, fputc, format, ap_save); - va_end(ap_save); - return retcode; -} - -int curl_mfprintf(FILE *whereto, const char *format, ...) -{ - int retcode; - va_list ap_save; /* argument pointer */ - va_start(ap_save, format); - retcode = dprintf_formatf(whereto, fputc, format, ap_save); - va_end(ap_save); - return retcode; -} - -int curl_mvsprintf(char *buffer, const char *format, va_list ap_save) -{ - int retcode; - retcode = dprintf_formatf(&buffer, storebuffer, format, ap_save); - *buffer=0; /* we terminate this with a zero byte */ - return retcode; -} - -int curl_mvprintf(const char *format, va_list ap_save) -{ - return dprintf_formatf(stdout, fputc, format, ap_save); -} - -int curl_mvfprintf(FILE *whereto, const char *format, va_list ap_save) -{ - return dprintf_formatf(whereto, fputc, format, ap_save); -} - -#ifdef DPRINTF_DEBUG -int main() -{ - char buffer[129]; - char *ptr; -#ifdef ENABLE_64BIT - long long one=99; - long long two=100; - long long test = 0x1000000000LL; - curl_mprintf("%lld %lld %lld\n", one, two, test); -#endif - - curl_mprintf("%3d %5d\n", 10, 1998); - - ptr=curl_maprintf("test this then baby %s%s%s%s%s%s %d %d %d loser baby get a hit in yer face now!", "", "pretty long string pretty long string pretty long string pretty long string pretty long string", "/", "/", "/", "pretty long string", 1998, 1999, 2001); - - puts(ptr); - - memset(ptr, 55, strlen(ptr)+1); - - free(ptr); - -#if 1 - curl_mprintf(buffer, "%s %s %d", "daniel", "stenberg", 19988); - puts(buffer); - - curl_mfprintf(stderr, "%s %#08x\n", "dummy", 65); - - printf("%s %#08x\n", "dummy", 65); - { - double tryout = 3.14156592; - curl_mprintf(buffer, "%.2g %G %f %e %E", tryout, tryout, tryout, tryout, tryout); - puts(buffer); - printf("%.2g %G %f %e %E\n", tryout, tryout, tryout, tryout, tryout); - } -#endif - - return 0; -} - -#endif diff --git a/Source/CTest/Curl/multi.c b/Source/CTest/Curl/multi.c deleted file mode 100644 index a604af8..0000000 --- a/Source/CTest/Curl/multi.c +++ /dev/null @@ -1,648 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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 <stdlib.h> -#include <string.h> - -#ifdef HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif -#ifdef HAVE_SYS_SOCKET_H -#include <sys/socket.h> -#endif -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -#include <curl/curl.h> - -#include "urldata.h" -#include "transfer.h" -#include "url.h" -#include "connect.h" -#include "progress.h" -#include "curl_memory.h" - -/* The last #include file should be: */ -#include "memdebug.h" - -struct Curl_message { - /* the 'CURLMsg' is the part that is visible to the external user */ - struct CURLMsg extmsg; - struct Curl_message *next; -}; - -typedef enum { - CURLM_STATE_INIT, - CURLM_STATE_CONNECT, /* resolve/connect has been sent off */ - CURLM_STATE_WAITRESOLVE, /* we're awaiting the resolve to finalize */ - CURLM_STATE_WAITCONNECT, /* we're awaiting the connect to finalize */ - CURLM_STATE_DO, /* send off the request (part 1) */ - CURLM_STATE_DO_MORE, /* send off the request (part 2) */ - CURLM_STATE_PERFORM, /* transfer data */ - CURLM_STATE_DONE, /* post data transfer operation */ - CURLM_STATE_COMPLETED, /* operation complete */ - - CURLM_STATE_LAST /* not a true state, never use this */ -} CURLMstate; - -struct Curl_one_easy { - /* first, two fields for the linked list of these */ - struct Curl_one_easy *next; - struct Curl_one_easy *prev; - - struct SessionHandle *easy_handle; /* the easy handle for this unit */ - struct connectdata *easy_conn; /* the "unit's" connection */ - - CURLMstate state; /* the handle's state */ - CURLcode result; /* previous result */ - - struct Curl_message *msg; /* A pointer to one single posted message. - Cleanup should be done on this pointer NOT on - the linked list in Curl_multi. This message - will be deleted when this handle is removed - from the multi-handle */ - int msg_num; /* number of messages left in 'msg' to return */ -}; - - -#define CURL_MULTI_HANDLE 0x000bab1e - -#define GOOD_MULTI_HANDLE(x) ((x)&&(((struct Curl_multi *)x)->type == CURL_MULTI_HANDLE)) -#define GOOD_EASY_HANDLE(x) (x) - -/* This is the struct known as CURLM on the outside */ -struct Curl_multi { - /* First a simple identifier to easier detect if a user mix up - this multi handle with an easy handle. Set this to CURL_MULTI_HANDLE. */ - long type; - - /* We have a linked list with easy handles */ - struct Curl_one_easy easy; - /* This is the amount of entries in the linked list above. */ - int num_easy; - - int num_msgs; /* total amount of messages in the easy handles */ - - /* Hostname cache */ - curl_hash *hostcache; -}; - - -CURLM *curl_multi_init(void) -{ - struct Curl_multi *multi; - - multi = (void *)malloc(sizeof(struct Curl_multi)); - - if(multi) { - memset(multi, 0, sizeof(struct Curl_multi)); - multi->type = CURL_MULTI_HANDLE; - } - else - return NULL; - - multi->hostcache = Curl_mk_dnscache(); - if(!multi->hostcache) { - /* failure, free mem and bail out */ - free(multi); - multi = NULL; - } - return (CURLM *) multi; -} - -CURLMcode curl_multi_add_handle(CURLM *multi_handle, - CURL *easy_handle) -{ - struct Curl_multi *multi=(struct Curl_multi *)multi_handle; - struct Curl_one_easy *easy; - - /* First, make some basic checks that the CURLM handle is a good handle */ - if(!GOOD_MULTI_HANDLE(multi)) - return CURLM_BAD_HANDLE; - - /* Verify that we got a somewhat good easy handle too */ - if(!GOOD_EASY_HANDLE(easy_handle)) - return CURLM_BAD_EASY_HANDLE; - - /* Now, time to add an easy handle to the multi stack */ - easy = (struct Curl_one_easy *)malloc(sizeof(struct Curl_one_easy)); - if(!easy) - return CURLM_OUT_OF_MEMORY; - - /* clean it all first (just to be sure) */ - memset(easy, 0, sizeof(struct Curl_one_easy)); - - /* set the easy handle */ - easy->easy_handle = easy_handle; - easy->state = CURLM_STATE_INIT; - - /* for multi interface connections, we share DNS cache automaticly */ - easy->easy_handle->hostcache = multi->hostcache; - - /* We add this new entry first in the list. We make our 'next' point to the - previous next and our 'prev' point back to the 'first' struct */ - easy->next = multi->easy.next; - easy->prev = &multi->easy; - - /* make 'easy' the first node in the chain */ - multi->easy.next = easy; - - /* if there was a next node, make sure its 'prev' pointer links back to - the new node */ - if(easy->next) - easy->next->prev = easy; - - /* increase the node-counter */ - multi->num_easy++; - - return CURLM_CALL_MULTI_PERFORM; -} - -CURLMcode curl_multi_remove_handle(CURLM *multi_handle, - CURL *curl_handle) -{ - struct Curl_multi *multi=(struct Curl_multi *)multi_handle; - struct Curl_one_easy *easy; - - /* First, make some basic checks that the CURLM handle is a good handle */ - if(!GOOD_MULTI_HANDLE(multi)) - return CURLM_BAD_HANDLE; - - /* Verify that we got a somewhat good easy handle too */ - if(!GOOD_EASY_HANDLE(curl_handle)) - return CURLM_BAD_EASY_HANDLE; - - /* scan through the list and remove the 'curl_handle' */ - easy = multi->easy.next; - while(easy) { - if(easy->easy_handle == (struct SessionHandle *)curl_handle) - break; - easy=easy->next; - } - if(easy) { - /* If the 'state' is not INIT or COMPLETED, we might need to do something - nice to put the easy_handle in a good known state when this returns. */ - - /* clear out the usage of the shared DNS cache */ - easy->easy_handle->hostcache = NULL; - - /* make the previous node point to our next */ - if(easy->prev) - easy->prev->next = easy->next; - /* make our next point to our previous node */ - if(easy->next) - easy->next->prev = easy->prev; - - /* NOTE NOTE NOTE - We do not touch the easy handle here! */ - if (easy->msg) - free(easy->msg); - free(easy); - - multi->num_easy--; /* one less to care about now */ - - return CURLM_OK; - } - else - return CURLM_BAD_EASY_HANDLE; /* twasn't found */ -} - -CURLMcode curl_multi_fdset(CURLM *multi_handle, - fd_set *read_fd_set, fd_set *write_fd_set, - fd_set *exc_fd_set, int *max_fd) -{ - /* Scan through all the easy handles to get the file descriptors set. - Some easy handles may not have connected to the remote host yet, - and then we must make sure that is done. */ - struct Curl_multi *multi=(struct Curl_multi *)multi_handle; - struct Curl_one_easy *easy; - int this_max_fd=-1; - - if(!GOOD_MULTI_HANDLE(multi)) - return CURLM_BAD_HANDLE; - - *max_fd = -1; /* so far none! */ - - easy=multi->easy.next; - while(easy) { - switch(easy->state) { - default: - break; - case CURLM_STATE_WAITRESOLVE: - /* waiting for a resolve to complete */ - Curl_fdset(easy->easy_conn, read_fd_set, write_fd_set, &this_max_fd); - if(this_max_fd > *max_fd) - *max_fd = this_max_fd; - 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; - curl_socket_t sockfd; - - if(CURLM_STATE_WAITCONNECT == easy->state) { - sockfd = conn->sock[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->sock[SECONDARYSOCKET]; - FD_SET(sockfd, write_fd_set); - } - - if((int)sockfd > *max_fd) - *max_fd = (int)sockfd; - } - break; - case CURLM_STATE_PERFORM: - /* This should have a set of file descriptors for us to set. */ - /* after the transfer is done, go DONE */ - - Curl_single_fdset(easy->easy_conn, - read_fd_set, write_fd_set, - exc_fd_set, &this_max_fd); - - /* remember the maximum file descriptor */ - if(this_max_fd > *max_fd) - *max_fd = this_max_fd; - - break; - } - easy = easy->next; /* check next handle */ - } - - return CURLM_OK; -} - -CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles) -{ - struct Curl_multi *multi=(struct Curl_multi *)multi_handle; - struct Curl_one_easy *easy; - bool done; - CURLMcode result=CURLM_OK; - struct Curl_message *msg; - bool connected; - bool async; - - *running_handles = 0; /* bump this once for every living handle */ - - if(!GOOD_MULTI_HANDLE(multi)) - return CURLM_BAD_HANDLE; - - easy=multi->easy.next; - while(easy) { -#if 0 - fprintf(stderr, "HANDLE %p: State: %x\n", - (char *)easy, easy->state); -#endif - do { - if (CURLM_STATE_WAITCONNECT <= easy->state && - easy->state <= CURLM_STATE_DO && - easy->easy_handle->change.url_changed) { - char *gotourl; - Curl_posttransfer(easy->easy_handle); - - easy->result = Curl_done(&easy->easy_conn, CURLE_OK); - if(CURLE_OK == easy->result) { - gotourl = strdup(easy->easy_handle->change.url); - if(gotourl) { - easy->easy_handle->change.url_changed = FALSE; - easy->result = Curl_follow(easy->easy_handle, gotourl); - if(CURLE_OK == easy->result) - easy->state = CURLM_STATE_CONNECT; - else - free(gotourl); - } - else { - easy->result = CURLE_OUT_OF_MEMORY; - easy->state = CURLM_STATE_COMPLETED; - break; - } - } - } - - easy->easy_handle->change.url_changed = FALSE; - - switch(easy->state) { - case CURLM_STATE_INIT: - /* init this transfer. */ - easy->result=Curl_pretransfer(easy->easy_handle); - - if(CURLE_OK == easy->result) { - /* after init, go CONNECT */ - easy->state = CURLM_STATE_CONNECT; - result = CURLM_CALL_MULTI_PERFORM; - - easy->easy_handle->state.used_interface = Curl_if_multi; - } - break; - - case CURLM_STATE_CONNECT: - /* Connect. We get a connection identifier filled in. */ - Curl_pgrsTime(easy->easy_handle, TIMER_STARTSINGLE); - easy->result = Curl_connect(easy->easy_handle, &easy->easy_conn, - &async); - - if(CURLE_OK == easy->result) { - if(async) - /* We're now waiting for an asynchronous name lookup */ - easy->state = CURLM_STATE_WAITRESOLVE; - else { - /* after the connect has been sent off, go WAITCONNECT */ - easy->state = CURLM_STATE_WAITCONNECT; - result = CURLM_CALL_MULTI_PERFORM; - } - } - break; - - case CURLM_STATE_WAITRESOLVE: - /* awaiting an asynch name resolve to complete */ - { - struct Curl_dns_entry *dns = NULL; - - /* check if we have the name resolved by now */ - easy->result = Curl_is_resolved(easy->easy_conn, &dns); - - if(dns) { - /* Perform the next step in the connection phase, and then move on - to the WAITCONNECT state */ - easy->result = Curl_async_resolved(easy->easy_conn); - - if(CURLE_OK != easy->result) - /* if Curl_async_resolved() returns failure, the connection struct - is already freed and gone */ - easy->easy_conn = NULL; /* no more connection */ - - easy->state = CURLM_STATE_WAITCONNECT; - } - - if(CURLE_OK != easy->result) { - /* failure detected */ - Curl_disconnect(easy->easy_conn); /* disconnect properly */ - easy->easy_conn = NULL; /* no more connection */ - break; - } - } - break; - - case CURLM_STATE_WAITCONNECT: - /* awaiting a completion of an asynch connect */ - easy->result = Curl_is_connected(easy->easy_conn, FIRSTSOCKET, - &connected); - if(connected) - easy->result = Curl_protocol_connect(easy->easy_conn); - - if(CURLE_OK != easy->result) { - /* failure detected */ - Curl_disconnect(easy->easy_conn); /* close the connection */ - easy->easy_conn = NULL; /* no more connection */ - break; - } - - if(connected) { - /* after the connect has completed, go DO */ - easy->state = CURLM_STATE_DO; - result = CURLM_CALL_MULTI_PERFORM; - } - break; - - case CURLM_STATE_DO: - /* Do the fetch or put request */ - easy->result = Curl_do(&easy->easy_conn); - if(CURLE_OK == easy->result) { - - /* 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, SECONDARYSOCKET, - &connected); - if(connected) { - /* - * When we are connected, DO MORE and then go PERFORM - */ - easy->result = Curl_do_more(easy->easy_conn); - - if(CURLE_OK == easy->result) - easy->result = Curl_readwrite_init(easy->easy_conn); - - if(CURLE_OK == easy->result) { - easy->state = CURLM_STATE_PERFORM; - result = CURLM_CALL_MULTI_PERFORM; - } - } - break; - - case CURLM_STATE_PERFORM: - /* read/write data if it is ready to do so */ - easy->result = Curl_readwrite(easy->easy_conn, &done); - - 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(CURL_SOCKET_BAD != easy->easy_conn->sock[SECONDARYSOCKET]) { - /* if we failed anywhere, we must clean up the secondary socket if - it was used */ - sclose(easy->easy_conn->sock[SECONDARYSOCKET]); - easy->easy_conn->sock[SECONDARYSOCKET]=-1; - } - Curl_posttransfer(easy->easy_handle); - Curl_done(&easy->easy_conn, easy->result); - } - - /* after the transfer is done, go DONE */ - else if(TRUE == done) { - - /* call this even if the readwrite function returned error */ - Curl_posttransfer(easy->easy_handle); - - /* When we follow redirects, must to go back to the CONNECT state */ - if(easy->easy_conn->newurl) { - char *newurl = easy->easy_conn->newurl; - easy->easy_conn->newurl = NULL; - easy->result = Curl_done(&easy->easy_conn, CURLE_OK); - if(easy->result == CURLE_OK) - easy->result = Curl_follow(easy->easy_handle, newurl); - if(CURLE_OK == easy->result) { - easy->state = CURLM_STATE_CONNECT; - result = CURLM_CALL_MULTI_PERFORM; - } - } - else { - easy->state = CURLM_STATE_DONE; - result = CURLM_CALL_MULTI_PERFORM; - } - } - break; - case CURLM_STATE_DONE: - /* post-transfer command */ - easy->result = Curl_done(&easy->easy_conn, CURLE_OK); - - /* after we have DONE what we're supposed to do, go COMPLETED, and - it doesn't matter what the Curl_done() returned! */ - easy->state = CURLM_STATE_COMPLETED; - break; - - case CURLM_STATE_COMPLETED: - /* this is a completed transfer, it is likely to still be connected */ - - /* This node should be delinked from the list now and we should post - an information message that we are complete. */ - break; - default: - return CURLM_INTERNAL_ERROR; - } - - if(CURLM_STATE_COMPLETED != easy->state) { - if(CURLE_OK != easy->result) { - /* - * If an error was returned, and we aren't in completed state now, - * then we go to completed and consider this transfer aborted. */ - easy->state = CURLM_STATE_COMPLETED; - } - else - /* this one still lives! */ - (*running_handles)++; - } - - } while (easy->easy_handle->change.url_changed); - - 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 */ - } - - easy = easy->next; /* operate on next handle */ - } - - return result; -} - -CURLMcode curl_multi_cleanup(CURLM *multi_handle) -{ - struct Curl_multi *multi=(struct Curl_multi *)multi_handle; - struct Curl_one_easy *easy; - struct Curl_one_easy *nexteasy; - - if(GOOD_MULTI_HANDLE(multi)) { - multi->type = 0; /* not good anymore */ - Curl_hash_destroy(multi->hostcache); - - /* 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); - - return CURLM_OK; - } - else - return CURLM_BAD_HANDLE; -} - -CURLMsg *curl_multi_info_read(CURLM *multi_handle, int *msgs_in_queue) -{ - struct Curl_multi *multi=(struct Curl_multi *)multi_handle; - - *msgs_in_queue = 0; /* default to none */ - - 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; -} diff --git a/Source/CTest/Curl/netrc.c b/Source/CTest/Curl/netrc.c deleted file mode 100644 index 770bfb5..0000000 --- a/Source/CTest/Curl/netrc.c +++ /dev/null @@ -1,247 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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 <stdio.h> -#include <stdlib.h> -#include <string.h> - -#ifdef HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif -#ifdef HAVE_PWD_H -#include <pwd.h> -#endif -#ifdef VMS -#include <unixlib.h> -#endif - -#include <curl/curl.h> -#include "netrc.h" - -#include "strequal.h" -#include "strtok.h" -#include "curl_memory.h" - -#define _MPRINTF_REPLACE /* use our functions only */ -#include <curl/mprintf.h> - -/* The last #include file should be: */ -#include "memdebug.h" - -/* Debug this single source file with: - 'make netrc' then run './netrc'! - - Oh, make sure you have a .netrc file too ;-) - */ - -/* Get user and password from .netrc when given a machine name */ - -enum { - NOTHING, - HOSTFOUND, /* the 'machine' keyword was found */ - HOSTCOMPLETE, /* the machine name following the keyword was found too */ - HOSTVALID, /* this is "our" machine! */ - - HOSTEND /* LAST enum */ -}; - -/* make sure we have room for at least this size: */ -#define LOGINSIZE 64 -#define PASSWORDSIZE 64 - -/* returns -1 on failure, 0 if the host is found, 1 is the host isn't found */ -int Curl_parsenetrc(char *host, - char *login, - char *password, - char *netrcfile) -{ - FILE *file; - int retcode=1; - int specific_login = (login[0] != 0); - char *home = NULL; - bool home_alloc = FALSE; - bool netrc_alloc = FALSE; - int state=NOTHING; - - char state_login=0; /* Found a login keyword */ - char state_password=0; /* Found a password keyword */ - int state_our_login=FALSE; /* With specific_login, found *our* login name */ - -#define NETRC DOT_CHAR "netrc" - -#ifdef CURLDEBUG - { - /* 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) { - printf("NETRC: overridden " NETRC " file: %s\n", home); - netrcfile = override; - netrc_alloc = TRUE; - } - } -#endif /* CURLDEBUG */ - if(!netrcfile) { - home = curl_getenv("HOME"); /* portable environment reader */ - if(home) { - home_alloc = TRUE; -#if defined(HAVE_GETPWUID) && defined(HAVE_GETEUID) - } - else { - struct passwd *pw; - pw= getpwuid(geteuid()); - if (pw) { -#ifdef VMS - home = decc$translate_vms(pw->pw_dir); -#else - home = pw->pw_dir; -#endif - } -#endif - } - - if(!home) - return -1; - - netrcfile = curl_maprintf("%s%s%s", home, DIR_CHAR, NETRC); - if(!netrcfile) { - if(home_alloc) - free(home); - return -1; - } - netrc_alloc = TRUE; - } - - file = fopen(netrcfile, "r"); - if(file) { - char *tok; - char *tok_buf; - bool done=FALSE; - char netrcbuffer[256]; - - while(!done && fgets(netrcbuffer, sizeof(netrcbuffer), file)) { - tok=strtok_r(netrcbuffer, " \t\n", &tok_buf); - while(!done && tok) { - - if (login[0] && password[0]) { - done=TRUE; - break; - } - - switch(state) { - case NOTHING: - if(strequal("machine", tok)) { - /* the next tok is the machine name, this is in itself the - delimiter that starts the stuff entered for this machine, - after this we need to search for 'login' and - 'password'. */ - state=HOSTFOUND; - } - break; - case HOSTFOUND: - if(strequal(host, tok)) { - /* and yes, this is our host! */ - state=HOSTVALID; -#ifdef _NETRC_DEBUG - printf("HOST: %s\n", tok); -#endif - retcode=0; /* we did find our host */ - } - else - /* not our host */ - state=NOTHING; - break; - case HOSTVALID: - /* we are now parsing sub-keywords concerning "our" host */ - if(state_login) { - if (specific_login) { - state_our_login = strequal(login, tok); - } - else { - strncpy(login, tok, LOGINSIZE-1); -#ifdef _NETRC_DEBUG - printf("LOGIN: %s\n", login); -#endif - } - state_login=0; - } - else if(state_password) { - if (state_our_login || !specific_login) { - strncpy(password, tok, PASSWORDSIZE-1); -#ifdef _NETRC_DEBUG - printf("PASSWORD: %s\n", password); -#endif - } - state_password=0; - } - else if(strequal("login", tok)) - state_login=1; - else if(strequal("password", tok)) - state_password=1; - else if(strequal("machine", tok)) { - /* ok, there's machine here go => */ - state = HOSTFOUND; - state_our_login = FALSE; - } - break; - } /* switch (state) */ - - tok = strtok_r(NULL, " \t\n", &tok_buf); - } /* while (tok) */ - } /* while fgets() */ - - fclose(file); - } - - if(home_alloc) - free(home); - if(netrc_alloc) - free(netrcfile); - - return retcode; -} - -#ifdef _NETRC_DEBUG -int main(int argc, char **argv) -{ - char login[64]=""; - char password[64]=""; - - if(argc<2) - return -1; - - if(0 == ParseNetrc(argv[1], login, password)) { - printf("HOST: %s LOGIN: %s PASSWORD: %s\n", - argv[1], login, password); - } -} - -#endif diff --git a/Source/CTest/Curl/netrc.h b/Source/CTest/Curl/netrc.h deleted file mode 100644 index 939c552..0000000 --- a/Source/CTest/Curl/netrc.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef __NETRC_H -#define __NETRC_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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$ - ***************************************************************************/ -int Curl_parsenetrc(char *host, - char *login, - char *password, - char *filename); - /* Assume: password[0]=0, host[0] != 0. - * If login[0] = 0, search for login and password within a machine section - * in the netrc. - * If login[0] != 0, search for password within machine and login. - */ -#endif diff --git a/Source/CTest/Curl/nwlib.c b/Source/CTest/Curl/nwlib.c deleted file mode 100644 index a999dfd..0000000 --- a/Source/CTest/Curl/nwlib.c +++ /dev/null @@ -1,300 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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 <errno.h> -#include <string.h> -#include <stdlib.h> -#include <library.h> -#include <netware.h> -#include <screen.h> -#include <nks/thread.h> -#include <nks/synch.h> - -#include "curl_memory.h" -#include "memdebug.h" - -typedef struct -{ - int _errno; - void *twentybytes; -} libthreaddata_t; - -typedef struct -{ - int x; - int y; - int z; - void *tenbytes; - NXKey_t perthreadkey; /* if -1, no key obtained... */ - NXMutex_t *lock; -} libdata_t; - -int gLibId = -1; -void *gLibHandle = (void *) NULL; -rtag_t gAllocTag = (rtag_t) NULL; -NXMutex_t *gLibLock = (NXMutex_t *) NULL; - -/* internal library function prototypes... */ -int DisposeLibraryData ( void * ); -void DisposeThreadData ( void * ); -int GetOrSetUpData ( int id, libdata_t **data, libthreaddata_t **threaddata ); - - -int _NonAppStart( void *NLMHandle, - void *errorScreen, - const char *cmdLine, - const char *loadDirPath, - size_t uninitializedDataLength, - void *NLMFileHandle, - int (*readRoutineP)( int conn, - void *fileHandle, size_t offset, - size_t nbytes, - size_t *bytesRead, - void *buffer ), - size_t customDataOffset, - size_t customDataSize, - int messageCount, - const char **messages ) -{ - NX_LOCK_INFO_ALLOC(liblock, "Per-Application Data Lock", 0); - -#ifndef __GNUC__ -#pragma unused(cmdLine) -#pragma unused(loadDirPath) -#pragma unused(uninitializedDataLength) -#pragma unused(NLMFileHandle) -#pragma unused(readRoutineP) -#pragma unused(customDataOffset) -#pragma unused(customDataSize) -#pragma unused(messageCount) -#pragma unused(messages) -#endif - -/* -** Here we process our command line, post errors (to the error screen), -** perform initializations and anything else we need to do before being able -** to accept calls into us. If we succeed, we return non-zero and the NetWare -** Loader will leave us up, otherwise we fail to load and get dumped. -*/ - gAllocTag = AllocateResourceTag(NLMHandle, - "<library-name> memory allocations", - AllocSignature); - - if (!gAllocTag) { - OutputToScreen(errorScreen, "Unable to allocate resource tag for " - "library memory allocations.\n"); - return -1; - } - - gLibId = register_library(DisposeLibraryData); - - if (gLibId < -1) { - OutputToScreen(errorScreen, "Unable to register library with kernel.\n"); - return -1; - } - - gLibHandle = NLMHandle; - - gLibLock = NXMutexAlloc(0, 0, &liblock); - - if (!gLibLock) { - OutputToScreen(errorScreen, "Unable to allocate library data lock.\n"); - return -1; - } - - return 0; -} - -/* -** Here we clean up any resources we allocated. Resource tags is a big part -** of what we created, but NetWare doesn't ask us to free those. -*/ -void _NonAppStop( void ) -{ - (void) unregister_library(gLibId); - NXMutexFree(gLibLock); -} - -/* -** This function cannot be the first in the file for if the file is linked -** first, then the check-unload function's offset will be nlmname.nlm+0 -** which is how to tell that there isn't one. When the check function is -** first in the linked objects, it is ambiguous. For this reason, we will -** put it inside this file after the stop function. -** -** Here we check to see if it's alright to ourselves to be unloaded. If not, -** we return a non-zero value. Right now, there isn't any reason not to allow -** it. -*/ -int _NonAppCheckUnload( void ) -{ - return 0; -} - -int GetOrSetUpData(int id, libdata_t **appData, - libthreaddata_t **threadData ) -{ - int err; - libdata_t *app_data; - libthreaddata_t *thread_data; - NXKey_t key; - NX_LOCK_INFO_ALLOC(liblock, "Application Data Lock", 0); - - err = 0; - thread_data = (libthreaddata_t *) NULL; - -/* -** Attempt to get our data for the application calling us. This is where we -** store whatever application-specific information we need to carry in support -** of calling applications. -*/ - app_data = (libdata_t *) get_app_data(id); - - if (!app_data) { -/* -** This application hasn't called us before; set up application AND per-thread -** data. Of course, just in case a thread from this same application is calling -** us simultaneously, we better lock our application data-creation mutex. We -** also need to recheck for data after we acquire the lock because WE might be -** that other thread that was too late to create the data and the first thread -** in will have created it. -*/ - NXLock(gLibLock); - - if (!(app_data = (libdata_t *) get_app_data(id))) { - app_data = (libdata_t *) malloc(sizeof(libdata_t)); - - if (app_data) { - memset(app_data, 0, sizeof(libdata_t)); - - app_data->tenbytes = malloc(10); - app_data->lock = NXMutexAlloc(0, 0, &liblock); - - if (!app_data->tenbytes || !app_data->lock) { - if (app_data->lock) - NXMutexFree(app_data->lock); - - free(app_data); - app_data = (libdata_t *) NULL; - err = ENOMEM; - } - - if (app_data) { -/* -** Here we burn in the application data that we were trying to get by calling -** get_app_data(). Next time we call the first function, we'll get this data -** we're just now setting. We also go on here to establish the per-thread data -** for the calling thread, something we'll have to do on each application -** thread the first time it calls us. -*/ - err = set_app_data(gLibId, app_data); - - if (err) { - free(app_data); - app_data = (libdata_t *) NULL; - err = ENOMEM; - } - else { - /* create key for thread-specific data... */ - err = NXKeyCreate(DisposeThreadData, (void *) NULL, &key); - - if (err) /* (no more keys left?) */ - key = -1; - - app_data->perthreadkey = key; - } - } - } - } - - NXUnlock(gLibLock); - } - - if (app_data) { - key = app_data->perthreadkey; - - if (key != -1 /* couldn't create a key? no thread data */ - && !(err = NXKeyGetValue(key, (void **) &thread_data)) - && !thread_data) { -/* -** Allocate the per-thread data for the calling thread. Regardless of whether -** there was already application data or not, this may be the first call by a -** a new thread. The fact that we allocation 20 bytes on a pointer is not very -** important, this just helps to demonstrate that we can have arbitrarily -** complex per-thread data. -*/ - thread_data = (libthreaddata_t *) malloc(sizeof(libthreaddata_t)); - - if (thread_data) { - thread_data->_errno = 0; - thread_data->twentybytes = malloc(20); - - if (!thread_data->twentybytes) { - free(thread_data); - thread_data = (libthreaddata_t *) NULL; - err = ENOMEM; - } - - if ((err = NXKeySetValue(key, thread_data))) { - free(thread_data->twentybytes); - free(thread_data); - thread_data = (libthreaddata_t *) NULL; - } - } - } - } - - if (appData) - *appData = app_data; - - if (threadData) - *threadData = thread_data; - - return err; -} - -int DisposeLibraryData( void *data) -{ - if (data) { - void *tenbytes = ((libdata_t *) data)->tenbytes; - - if (tenbytes) - free(tenbytes); - - free(data); - } - - return 0; -} - -void DisposeThreadData(void *data) -{ - if (data) { - void *twentybytes = ((libthreaddata_t *) data)->twentybytes; - - if (twentybytes) - free(twentybytes); - - free(data); - } -} diff --git a/Source/CTest/Curl/progress.c b/Source/CTest/Curl/progress.c deleted file mode 100644 index 36be56e..0000000 --- a/Source/CTest/Curl/progress.c +++ /dev/null @@ -1,426 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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 <string.h> -#include <time.h> - -#if defined(__EMX__) -#include <stdlib.h> -#endif - -#include <curl/curl.h> -#include "urldata.h" -#include "sendf.h" -#include "progress.h" - -#define _MPRINTF_REPLACE /* use our functions only */ -#include <curl/mprintf.h> - -/* Provide a string that is 2 + 1 + 2 + 1 + 2 = 8 letters long (plus the zero - byte) */ -static void time2str(char *r, long t) -{ - long h; - if(!t) { - strcpy(r, "--:--:--"); - return; - } - h = (t/3600); - if(h <= 99) { - long m = (t-(h*3600))/60; - long s = (t-(h*3600)-(m*60)); - snprintf(r, 9, "%2ld:%02ld:%02ld",h,m,s); - } - else { - /* this equals to more than 99 hours, switch to a more suitable output - format to fit within the limits. */ - if(h/24 <= 999) - snprintf(r, 9, "%3ldd %02ldh", h/24, h-(h/24)*24); - else - snprintf(r, 9, "%7ldd", h/24); - } -} - -/* The point of this function would be to return a string of the input data, - but never longer than 5 columns (+ one zero byte). - Add suffix k, M, G when suitable... */ -static char *max5data(curl_off_t bytes, char *max5) -{ -#define ONE_KILOBYTE 1024 -#define ONE_MEGABYTE (1024* ONE_KILOBYTE) -#define ONE_GIGABYTE (1024* ONE_MEGABYTE) -#define ONE_TERRABYTE ((curl_off_t)1024* ONE_GIGABYTE) -#define ONE_PETABYTE ((curl_off_t)1024* ONE_TERRABYTE) - - if(bytes < 100000) { - snprintf(max5, 6, "%5" FORMAT_OFF_T, bytes); - } - else if(bytes < (10000*ONE_KILOBYTE)) { - snprintf(max5, 6, "%4" FORMAT_OFF_T "k", (curl_off_t)(bytes/ONE_KILOBYTE)); - } - else if(bytes < (100*ONE_MEGABYTE)) { - /* 'XX.XM' is good as long as we're less than 100 megs */ - snprintf(max5, 6, "%2d.%0dM", - (int)(bytes/ONE_MEGABYTE), - (int)(bytes%ONE_MEGABYTE)/(ONE_MEGABYTE/10) ); - } -#if SIZEOF_CURL_OFF_T > 4 - else if(bytes < ( (curl_off_t)10000*ONE_MEGABYTE)) - /* 'XXXXM' is good until we're at 10000MB or above */ - snprintf(max5, 6, "%4" FORMAT_OFF_T "M", (curl_off_t)(bytes/ONE_MEGABYTE)); - - else if(bytes < (curl_off_t)100*ONE_GIGABYTE) - /* 10000 MB - 100 GB, we show it as XX.XG */ - snprintf(max5, 6, "%2d.%0dG", - (int)(bytes/ONE_GIGABYTE), - (int)(bytes%ONE_GIGABYTE)/(ONE_GIGABYTE/10) ); - - else if(bytes < (curl_off_t)10000 * ONE_GIGABYTE) - /* up to 10000GB, display without decimal: XXXXG */ - snprintf(max5, 6, "%4dG", (int)(bytes/ONE_GIGABYTE)); - - else if(bytes < (curl_off_t)10000 * ONE_TERRABYTE) - /* up to 10000TB, display without decimal: XXXXT */ - snprintf(max5, 6, "%4dT", (int)(bytes/ONE_TERRABYTE)); - else { - /* up to 10000PB, display without decimal: XXXXP */ - snprintf(max5, 6, "%4dP", (int)(bytes/ONE_PETABYTE)); - - /* 16384 petabytes (16 exabytes) is maximum a 64 bit number can hold, - but this type is signed so 8192PB will be max.*/ - } - -#else - else - snprintf(max5, 6, "%4" FORMAT_OFF_T "M", (curl_off_t)(bytes/ONE_MEGABYTE)); -#endif - - return max5; -} - -/* - - New proposed interface, 9th of February 2000: - - pgrsStartNow() - sets start time - pgrsSetDownloadSize(x) - known expected download size - pgrsSetUploadSize(x) - known expected upload size - pgrsSetDownloadCounter() - amount of data currently downloaded - pgrsSetUploadCounter() - amount of data currently uploaded - pgrsUpdate() - show progress - pgrsDone() - transfer complete - -*/ - -void Curl_pgrsDone(struct connectdata *conn) -{ - struct SessionHandle *data = conn->data; - data->progress.lastshow=0; - Curl_pgrsUpdate(conn); /* the final (forced) update */ - if(!(data->progress.flags & PGRS_HIDE) && - !data->progress.callback) - /* only output if we don't use a progress callback and we're not hidden */ - fprintf(data->set.err, "\n"); -} - -/* reset all times except redirect */ -void Curl_pgrsResetTimes(struct SessionHandle *data) -{ - data->progress.t_nslookup = 0.0; - data->progress.t_connect = 0.0; - data->progress.t_pretransfer = 0.0; - data->progress.t_starttransfer = 0.0; -} - -void Curl_pgrsTime(struct SessionHandle *data, timerid timer) -{ - switch(timer) { - default: - case TIMER_NONE: - /* mistake filter */ - break; - case TIMER_STARTSINGLE: - /* This is set at the start of a single fetch */ - data->progress.t_startsingle = Curl_tvnow(); - break; - - case TIMER_NAMELOOKUP: - data->progress.t_nslookup = - Curl_tvdiff_secs(Curl_tvnow(), data->progress.t_startsingle); - break; - case TIMER_CONNECT: - data->progress.t_connect = - Curl_tvdiff_secs(Curl_tvnow(), data->progress.t_startsingle); - break; - case TIMER_PRETRANSFER: - data->progress.t_pretransfer = - Curl_tvdiff_secs(Curl_tvnow(), data->progress.t_startsingle); - break; - case TIMER_STARTTRANSFER: - data->progress.t_starttransfer = - Curl_tvdiff_secs(Curl_tvnow(), data->progress.t_startsingle); - break; - case TIMER_POSTRANSFER: - /* this is the normal end-of-transfer thing */ - break; - case TIMER_REDIRECT: - data->progress.t_redirect = - Curl_tvdiff_secs(Curl_tvnow(), data->progress.start); - break; - } -} - -void Curl_pgrsStartNow(struct SessionHandle *data) -{ - data->progress.speeder_c = 0; /* reset the progress meter display */ - data->progress.start = Curl_tvnow(); -} - -void Curl_pgrsSetDownloadCounter(struct SessionHandle *data, curl_off_t size) -{ - data->progress.downloaded = size; -} - -void Curl_pgrsSetUploadCounter(struct SessionHandle *data, curl_off_t size) -{ - data->progress.uploaded = size; -} - -void Curl_pgrsSetDownloadSize(struct SessionHandle *data, curl_off_t size) -{ - data->progress.size_dl = size; - if(size > 0) - data->progress.flags |= PGRS_DL_SIZE_KNOWN; - else - data->progress.flags &= ~PGRS_DL_SIZE_KNOWN; -} - -void Curl_pgrsSetUploadSize(struct SessionHandle *data, curl_off_t size) -{ - data->progress.size_ul = size; - if(size > 0) - data->progress.flags |= PGRS_UL_SIZE_KNOWN; - else - data->progress.flags &= ~PGRS_UL_SIZE_KNOWN; -} - -int Curl_pgrsUpdate(struct connectdata *conn) -{ - struct timeval now; - int result; - char max5[6][10]; - int dlpercen=0; - int ulpercen=0; - int total_percen=0; - curl_off_t total_transfer; - curl_off_t total_expected_transfer; - long timespent; - struct SessionHandle *data = conn->data; - int nowindex = data->progress.speeder_c% CURR_TIME; - int checkindex; - int countindex; /* amount of seconds stored in the speeder array */ - char time_left[10]; - char time_total[10]; - char time_spent[10]; - long ulestimate=0; - long dlestimate=0; - long total_estimate; - - if(data->progress.flags & PGRS_HIDE) - ; /* We do enter this function even if we don't wanna see anything, since - this is were lots of the calculations are being made that will be used - even when not displayed! */ - else if(!(data->progress.flags & PGRS_HEADERS_OUT)) { - if (!data->progress.callback) { - if(conn->resume_from) - fprintf(data->set.err, - "** Resuming transfer from byte position %" FORMAT_OFF_T - "\n", - conn->resume_from); - fprintf(data->set.err, - " %% Total %% Received %% Xferd Average Speed Time Time Time Current\n" - " Dload Upload Total Spent Left Speed\n"); - } - data->progress.flags |= PGRS_HEADERS_OUT; /* headers are shown */ - } - - now = Curl_tvnow(); /* what time is it */ - - /* The time spent so far (from the start) */ - data->progress.timespent = Curl_tvdiff_secs(now, data->progress.start); - timespent = (long)data->progress.timespent; - - /* The average download speed this far */ - data->progress.dlspeed = (curl_off_t) - ((double)data->progress.downloaded/ - (data->progress.timespent>0?data->progress.timespent:1)); - - /* The average upload speed this far */ - data->progress.ulspeed = (curl_off_t) - ((double)data->progress.uploaded/ - (data->progress.timespent>0?data->progress.timespent:1)); - - if(data->progress.lastshow == Curl_tvlong(now)) - return 0; /* never update this more than once a second if the end isn't - reached */ - data->progress.lastshow = now.tv_sec; - - /* Let's do the "current speed" thing, which should use the fastest - of the dl/ul speeds. Store the fasted speed at entry 'nowindex'. */ - data->progress.speeder[ nowindex ] = - data->progress.downloaded>data->progress.uploaded? - data->progress.downloaded:data->progress.uploaded; - - /* remember the exact time for this moment */ - data->progress.speeder_time [ nowindex ] = now; - - /* advance our speeder_c counter, which is increased every time we get - here and we expect it to never wrap as 2^32 is a lot of seconds! */ - data->progress.speeder_c++; - - /* figure out how many index entries of data we have stored in our speeder - array. With N_ENTRIES filled in, we have about N_ENTRIES-1 seconds of - transfer. Imagine, after one second we have filled in two entries, - after two seconds we've filled in three entries etc. */ - countindex = ((data->progress.speeder_c>=CURR_TIME)? - CURR_TIME:data->progress.speeder_c) - 1; - - /* first of all, we don't do this if there's no counted seconds yet */ - if(countindex) { - long span_ms; - - /* Get the index position to compare with the 'nowindex' position. - Get the oldest entry possible. While we have less than CURR_TIME - entries, the first entry will remain the oldest. */ - checkindex = (data->progress.speeder_c>=CURR_TIME)? - data->progress.speeder_c%CURR_TIME:0; - - /* Figure out the exact time for the time span */ - span_ms = Curl_tvdiff(now, - data->progress.speeder_time[checkindex]); - if(0 == span_ms) - span_ms=1; /* at least one millisecond MUST have passed */ - - /* Calculate the average speed the last 'span_ms' milliseconds */ - { - curl_off_t amount = data->progress.speeder[nowindex]- - data->progress.speeder[checkindex]; - - if(amount > 0xffffffff/1000) - /* the 'amount' value is bigger than would fit in 32 bits if - multiplied with 1000, so we use the double math for this */ - data->progress.current_speed = (curl_off_t) - ((double)amount/((double)span_ms/1000.0)); - else - /* the 'amount' value is small enough to fit within 32 bits even - when multiplied with 1000 */ - data->progress.current_speed = amount*1000/span_ms; - } - } - else - /* the first second we use the main average */ - data->progress.current_speed = - (data->progress.ulspeed>data->progress.dlspeed)? - data->progress.ulspeed:data->progress.dlspeed; - - if(data->progress.flags & PGRS_HIDE) - return 0; - - else if(data->set.fprogress) { - /* There's a callback set, so we call that instead of writing - anything ourselves. This really is the way to go. */ - result= data->set.fprogress(data->set.progress_client, - (double)data->progress.size_dl, - (double)data->progress.downloaded, - (double)data->progress.size_ul, - (double)data->progress.uploaded); - if(result) - failf(data, "Callback aborted"); - return result; - } - - /* Figure out the estimated time of arrival for the upload */ - if((data->progress.flags & PGRS_UL_SIZE_KNOWN) && - (data->progress.ulspeed>0) && - (data->progress.size_ul > 100) ) { - ulestimate = (long)(data->progress.size_ul / data->progress.ulspeed); - ulpercen = (int)(100*(data->progress.uploaded/100) / - (data->progress.size_ul/100) ); - } - - /* ... and the download */ - if((data->progress.flags & PGRS_DL_SIZE_KNOWN) && - (data->progress.dlspeed>0) && - (data->progress.size_dl>100)) { - dlestimate = (long)(data->progress.size_dl / data->progress.dlspeed); - dlpercen = (int)(100*(data->progress.downloaded/100) / - (data->progress.size_dl/100)); - } - - /* Now figure out which of them that is slower and use for the for - total estimate! */ - total_estimate = ulestimate>dlestimate?ulestimate:dlestimate; - - /* create the three time strings */ - time2str(time_left, total_estimate > 0?(total_estimate - timespent):0); - time2str(time_total, total_estimate); - time2str(time_spent, timespent); - - /* Get the total amount of data expected to get transfered */ - total_expected_transfer = - (data->progress.flags & PGRS_UL_SIZE_KNOWN? - data->progress.size_ul:data->progress.uploaded)+ - (data->progress.flags & PGRS_DL_SIZE_KNOWN? - data->progress.size_dl:data->progress.downloaded); - - /* We have transfered this much so far */ - total_transfer = data->progress.downloaded + data->progress.uploaded; - - /* Get the percentage of data transfered so far */ - if(total_expected_transfer > 100) - total_percen=(int)(100*(total_transfer/100) / - (total_expected_transfer/100) ); - - fprintf(data->set.err, - "\r%3d %s %3d %s %3d %s %s %s %s %s %s %s", - total_percen, /* 3 letters */ /* total % */ - max5data(total_expected_transfer, max5[2]), /* total size */ - dlpercen, /* 3 letters */ /* rcvd % */ - max5data(data->progress.downloaded, max5[0]), /* rcvd size */ - ulpercen, /* 3 letters */ /* xfer % */ - max5data(data->progress.uploaded, max5[1]), /* xfer size */ - max5data(data->progress.dlspeed, max5[3]), /* avrg dl speed */ - max5data(data->progress.ulspeed, max5[4]), /* avrg ul speed */ - time_total, /* 8 letters */ /* total time */ - time_spent, /* 8 letters */ /* time spent */ - time_left, /* 8 letters */ /* time left */ - max5data(data->progress.current_speed, max5[5]) /* current speed */ - ); - - /* we flush the output stream to make it appear as soon as possible */ - fflush(data->set.err); - - return 0; -} diff --git a/Source/CTest/Curl/progress.h b/Source/CTest/Curl/progress.h deleted file mode 100644 index dcfcaf7..0000000 --- a/Source/CTest/Curl/progress.h +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef __PROGRESS_H -#define __PROGRESS_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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 "timeval.h" - - -typedef enum { - TIMER_NONE, - TIMER_NAMELOOKUP, - TIMER_CONNECT, - TIMER_PRETRANSFER, - TIMER_STARTTRANSFER, - TIMER_POSTRANSFER, - TIMER_STARTSINGLE, - TIMER_REDIRECT, - TIMER_LAST /* must be last */ -} timerid; - -void Curl_pgrsDone(struct connectdata *); -void Curl_pgrsStartNow(struct SessionHandle *data); -void Curl_pgrsSetDownloadSize(struct SessionHandle *data, curl_off_t size); -void Curl_pgrsSetUploadSize(struct SessionHandle *data, curl_off_t size); -void Curl_pgrsSetDownloadCounter(struct SessionHandle *data, curl_off_t size); -void Curl_pgrsSetUploadCounter(struct SessionHandle *data, curl_off_t size); -int Curl_pgrsUpdate(struct connectdata *); -void Curl_pgrsResetTimes(struct SessionHandle *data); -void Curl_pgrsTime(struct SessionHandle *data, timerid timer); - - -/* Don't show progress for sizes smaller than: */ -#define LEAST_SIZE_PROGRESS BUFSIZE - -#define PROGRESS_DOWNLOAD (1<<0) -#define PROGRESS_UPLOAD (1<<1) -#define PROGRESS_DOWN_AND_UP (PROGRESS_UPLOAD | PROGRESS_DOWNLOAD) - -#define PGRS_SHOW_DL (1<<0) -#define PGRS_SHOW_UL (1<<1) -#define PGRS_DONE_DL (1<<2) -#define PGRS_DONE_UL (1<<3) -#define PGRS_HIDE (1<<4) -#define PGRS_UL_SIZE_KNOWN (1<<5) -#define PGRS_DL_SIZE_KNOWN (1<<6) - -#define PGRS_HEADERS_OUT (1<<7) /* set when the headers have been written */ - - -#endif /* __PROGRESS_H */ diff --git a/Source/CTest/Curl/security.c b/Source/CTest/Curl/security.c deleted file mode 100644 index 861f953..0000000 --- a/Source/CTest/Curl/security.c +++ /dev/null @@ -1,483 +0,0 @@ -/* This source code was modified by Martin Hedenfalk <mhe@stacken.kth.se> for - * use in Curl. His latest changes were done 2000-09-18. - * - * It has since been patched and modified a lot by Daniel Stenberg - * <daniel@haxx.se> to make it better applied to curl conditions, and to make - * it not use globals, pollute name space and more. This source code awaits a - * rewrite to work around the paragraph 2 in the BSD licenses as explained - * below. - * - * Copyright (c) 1998, 1999 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. */ - -#include "setup.h" - -#ifndef CURL_DISABLE_FTP -#ifdef HAVE_KRB4 - -#define _MPRINTF_REPLACE /* we want curl-functions instead of native ones */ -#include <curl/mprintf.h> - -#include "security.h" -#include <stdlib.h> -#include <string.h> -#include <netdb.h> - -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -#include "base64.h" -#include "sendf.h" -#include "ftp.h" -#include "curl_memory.h" - -/* The last #include file should be: */ -#include "memdebug.h" - -#define min(a, b) ((a) < (b) ? (a) : (b)) - -static struct { - enum protection_level level; - const char *name; -} level_names[] = { - { prot_clear, "clear" }, - { prot_safe, "safe" }, - { prot_confidential, "confidential" }, - { prot_private, "private" } -}; - -static enum protection_level -name_to_level(const char *name) -{ - int i; - for(i = 0; i < (int)sizeof(level_names)/(int)sizeof(level_names[0]); i++) - if(!strncasecmp(level_names[i].name, name, strlen(name))) - return level_names[i].level; - return (enum protection_level)-1; -} - -static struct Curl_sec_client_mech *mechs[] = { -#ifdef KRB5 - /* not supported */ -#endif -#ifdef HAVE_KRB4 - &Curl_krb4_client_mech, -#endif - NULL -}; - -int -Curl_sec_getc(struct connectdata *conn, FILE *F) -{ - if(conn->sec_complete && conn->data_prot) { - char c; - if(Curl_sec_read(conn, fileno(F), &c, 1) <= 0) - return EOF; - return c; - } - else - return getc(F); -} - -static int -block_read(int fd, void *buf, size_t len) -{ - unsigned char *p = buf; - int b; - while(len) { - b = read(fd, p, len); - if (b == 0) - return 0; - else if (b < 0) - return -1; - len -= b; - p += b; - } - return p - (unsigned char*)buf; -} - -static int -block_write(int fd, void *buf, size_t len) -{ - unsigned char *p = buf; - int b; - while(len) { - b = write(fd, p, len); - if(b < 0) - return -1; - len -= b; - p += b; - } - return p - (unsigned char*)buf; -} - -static int -sec_get_data(struct connectdata *conn, - int fd, struct krb4buffer *buf) -{ - int len; - int b; - - b = block_read(fd, &len, sizeof(len)); - if (b == 0) - return 0; - else if (b < 0) - return -1; - len = ntohl(len); - buf->data = realloc(buf->data, len); - b = block_read(fd, buf->data, len); - if (b == 0) - return 0; - else if (b < 0) - return -1; - buf->size = (conn->mech->decode)(conn->app_data, buf->data, len, - conn->data_prot, conn); - buf->index = 0; - return 0; -} - -static size_t -buffer_read(struct krb4buffer *buf, void *data, size_t len) -{ - len = min(len, buf->size - buf->index); - memcpy(data, (char*)buf->data + buf->index, len); - buf->index += len; - return len; -} - -static size_t -buffer_write(struct krb4buffer *buf, void *data, size_t len) -{ - if(buf->index + len > buf->size) { - void *tmp; - if(buf->data == NULL) - tmp = malloc(1024); - else - tmp = realloc(buf->data, buf->index + len); - if(tmp == NULL) - return -1; - buf->data = tmp; - buf->size = buf->index + len; - } - memcpy((char*)buf->data + buf->index, data, len); - buf->index += len; - return len; -} - -int -Curl_sec_read(struct connectdata *conn, int fd, void *buffer, int length) -{ - size_t len; - int rx = 0; - - if(conn->sec_complete == 0 || conn->data_prot == 0) - return read(fd, buffer, length); - - if(conn->in_buffer.eof_flag){ - conn->in_buffer.eof_flag = 0; - return 0; - } - - len = buffer_read(&conn->in_buffer, buffer, length); - length -= len; - rx += len; - buffer = (char*)buffer + len; - - while(length) { - if(sec_get_data(conn, fd, &conn->in_buffer) < 0) - return -1; - if(conn->in_buffer.size == 0) { - if(rx) - conn->in_buffer.eof_flag = 1; - return rx; - } - len = buffer_read(&conn->in_buffer, buffer, length); - length -= len; - rx += len; - buffer = (char*)buffer + len; - } - return rx; -} - -static int -sec_send(struct connectdata *conn, int fd, char *from, int length) -{ - int bytes; - void *buf; - bytes = (conn->mech->encode)(conn->app_data, from, length, conn->data_prot, - &buf, conn); - bytes = htonl(bytes); - block_write(fd, &bytes, sizeof(bytes)); - block_write(fd, buf, ntohl(bytes)); - free(buf); - return length; -} - -int -Curl_sec_fflush_fd(struct connectdata *conn, int fd) -{ - if(conn->data_prot != prot_clear) { - if(conn->out_buffer.index > 0){ - Curl_sec_write(conn, fd, - conn->out_buffer.data, conn->out_buffer.index); - conn->out_buffer.index = 0; - } - sec_send(conn, fd, NULL, 0); - } - return 0; -} - -int -Curl_sec_write(struct connectdata *conn, int fd, char *buffer, int length) -{ - int len = conn->buffer_size; - int tx = 0; - - if(conn->data_prot == prot_clear) - return write(fd, buffer, length); - - len -= (conn->mech->overhead)(conn->app_data, conn->data_prot, len); - while(length){ - if(length < len) - len = length; - sec_send(conn, fd, buffer, len); - length -= len; - buffer += len; - tx += len; - } - return tx; -} - -int -Curl_sec_putc(struct connectdata *conn, int c, FILE *F) -{ - char ch = c; - if(conn->data_prot == prot_clear) - return putc(c, F); - - buffer_write(&conn->out_buffer, &ch, 1); - if(c == '\n' || conn->out_buffer.index >= 1024 /* XXX */) { - Curl_sec_write(conn, fileno(F), conn->out_buffer.data, - conn->out_buffer.index); - conn->out_buffer.index = 0; - } - return c; -} - -int -Curl_sec_read_msg(struct connectdata *conn, char *s, int level) -{ - int len; - char *buf; - int code; - - buf = malloc(strlen(s)); - len = Curl_base64_decode(s + 4, buf); /* XXX */ - - len = (conn->mech->decode)(conn->app_data, buf, len, level, conn); - if(len < 0) { - free(buf); - return -1; - } - - buf[len] = '\0'; - - if(buf[3] == '-') - code = 0; - else - sscanf(buf, "%d", &code); - if(buf[len-1] == '\n') - buf[len-1] = '\0'; - strcpy(s, buf); - free(buf); - return code; -} - -enum protection_level -Curl_set_command_prot(struct connectdata *conn, enum protection_level level) -{ - enum protection_level old = conn->command_prot; - conn->command_prot = level; - return old; -} - -static int -sec_prot_internal(struct connectdata *conn, int level) -{ - char *p; - unsigned int s = 1048576; - ssize_t nread; - - if(!conn->sec_complete){ - infof(conn->data, "No security data exchange has taken place.\n"); - return -1; - } - - if(level){ - int code; - if(Curl_ftpsendf(conn, "PBSZ %u", s)) - return -1; - - if(Curl_GetFTPResponse(&nread, conn, &code)) - return -1; - - if(code/100 != '2'){ - failf(conn->data, "Failed to set protection buffer size."); - return -1; - } - conn->buffer_size = s; - - p = strstr(conn->data->state.buffer, "PBSZ="); - if(p) - sscanf(p, "PBSZ=%u", &s); - if(s < conn->buffer_size) - conn->buffer_size = s; - } - - if(Curl_ftpsendf(conn, "PROT %c", level["CSEP"])) - return -1; - - if(Curl_GetFTPResponse(&nread, conn, NULL)) - return -1; - - if(conn->data->state.buffer[0] != '2'){ - failf(conn->data, "Failed to set protection level."); - return -1; - } - - conn->data_prot = (enum protection_level)level; - return 0; -} - -void -Curl_sec_set_protection_level(struct connectdata *conn) -{ - if(conn->sec_complete && conn->data_prot != conn->request_data_prot) - sec_prot_internal(conn, conn->request_data_prot); -} - - -int -Curl_sec_request_prot(struct connectdata *conn, const char *level) -{ - int l = name_to_level(level); - if(l == -1) - return -1; - conn->request_data_prot = (enum protection_level)l; - return 0; -} - -int -Curl_sec_login(struct connectdata *conn) -{ - int ret; - struct Curl_sec_client_mech **m; - ssize_t nread; - struct SessionHandle *data=conn->data; - int ftpcode; - - for(m = mechs; *m && (*m)->name; m++) { - void *tmp; - - tmp = realloc(conn->app_data, (*m)->size); - if (tmp == NULL) { - failf (data, "realloc %u failed", (*m)->size); - return -1; - } - conn->app_data = tmp; - - if((*m)->init && (*(*m)->init)(conn->app_data) != 0) { - infof(data, "Skipping %s...\n", (*m)->name); - continue; - } - infof(data, "Trying %s...\n", (*m)->name); - - if(Curl_ftpsendf(conn, "AUTH %s", (*m)->name)) - return -1; - - if(Curl_GetFTPResponse(&nread, conn, &ftpcode)) - return -1; - - if(conn->data->state.buffer[0] != '3'){ - switch(ftpcode) { - case 504: - infof(data, - "%s is not supported by the server.\n", (*m)->name); - break; - case 534: - infof(data, "%s rejected as security mechanism.\n", (*m)->name); - break; - default: - if(conn->data->state.buffer[0] == '5') { - infof(data, "The server doesn't support the FTP " - "security extensions.\n"); - return -1; - } - break; - } - continue; - } - - ret = (*(*m)->auth)(conn->app_data, conn); - - if(ret == AUTH_CONTINUE) - continue; - else if(ret != AUTH_OK){ - /* mechanism is supposed to output error string */ - return -1; - } - conn->mech = *m; - conn->sec_complete = 1; - conn->command_prot = prot_safe; - break; - } - - return *m == NULL; -} - -void -Curl_sec_end(struct connectdata *conn) -{ - if (conn->mech != NULL) { - if(conn->mech->end) - (conn->mech->end)(conn->app_data); - memset(conn->app_data, 0, conn->mech->size); - free(conn->app_data); - conn->app_data = NULL; - } - conn->sec_complete = 0; - conn->data_prot = (enum protection_level)0; - conn->mech=NULL; -} - -#endif /* HAVE_KRB4 */ -#endif /* CURL_DISABLE_FTP */ diff --git a/Source/CTest/Curl/security.h b/Source/CTest/Curl/security.h deleted file mode 100644 index 5213ba5..0000000 --- a/Source/CTest/Curl/security.h +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef __SECURITY_H -#define __SECURITY_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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$ - ***************************************************************************/ - -/* this is a re-write */ - -#include <stdarg.h> -#include "urldata.h" /* for struct connectdata * */ - -struct Curl_sec_client_mech { - const char *name; - size_t size; - int (*init)(void *); - int (*auth)(void *, struct connectdata *); - void (*end)(void *); - int (*check_prot)(void *, int); - int (*overhead)(void *, int, int); - int (*encode)(void *, void*, int, int, void**, struct connectdata *); - int (*decode)(void *, void*, int, int, struct connectdata *); -}; - - -#define AUTH_OK 0 -#define AUTH_CONTINUE 1 -#define AUTH_ERROR 2 - -extern struct Curl_sec_client_mech Curl_krb4_client_mech; - -int Curl_sec_fflush_fd(struct connectdata *conn, int fd); -int Curl_sec_fprintf (struct connectdata *, FILE *, const char *, ...); -int Curl_sec_getc (struct connectdata *conn, FILE *); -int Curl_sec_putc (struct connectdata *conn, int, FILE *); -int Curl_sec_read (struct connectdata *conn, int, void *, int); -int Curl_sec_read_msg (struct connectdata *conn, char *, int); - -int Curl_sec_vfprintf(struct connectdata *, FILE *, const char *, va_list); -int Curl_sec_fprintf2(struct connectdata *conn, FILE *f, const char *fmt, ...); -int Curl_sec_vfprintf2(struct connectdata *conn, FILE *, const char *, va_list); -int Curl_sec_write (struct connectdata *conn, int, char *, int); - -void Curl_sec_end (struct connectdata *); -int Curl_sec_login (struct connectdata *); -void Curl_sec_prot (int, char **); -int Curl_sec_request_prot (struct connectdata *conn, const char *level); -void Curl_sec_set_protection_level(struct connectdata *conn); -void Curl_sec_status (void); - -enum protection_level Curl_set_command_prot(struct connectdata *, - enum protection_level); - -#endif diff --git a/Source/CTest/Curl/sendf.c b/Source/CTest/Curl/sendf.c deleted file mode 100644 index fae2ff3..0000000 --- a/Source/CTest/Curl/sendf.c +++ /dev/null @@ -1,496 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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 <stdio.h> -#include <stdarg.h> -#include <stdlib.h> -#include <errno.h> - -#ifdef HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif - -#ifdef HAVE_SYS_SOCKET_H -#include <sys/socket.h> /* required for send() & recv() prototypes */ -#endif - -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -#include <curl/curl.h> -#include "urldata.h" -#include "sendf.h" -#include "connect.h" /* for the Curl_ourerrno() proto */ - -#define _MPRINTF_REPLACE /* use the internal *printf() functions */ -#include <curl/mprintf.h> - -#ifdef HAVE_KRB4 -#include "security.h" -#endif -#include <string.h> -#include "curl_memory.h" -/* The last #include file should be: */ -#include "memdebug.h" - -/* returns last node in linked list */ -static struct curl_slist *slist_get_last(struct curl_slist *list) -{ - struct curl_slist *item; - - /* if caller passed us a NULL, return now */ - if (!list) - return NULL; - - /* loop through to find the last item */ - item = list; - while (item->next) { - item = item->next; - } - return item; -} - -/* - * curl_slist_append() appends a string to the linked list. It always retunrs - * the address of the first record, so that you can sure this function as an - * initialization function as well as an append function. If you find this - * bothersome, then simply create a separate _init function and call it - * appropriately from within the proram. - */ -struct curl_slist *curl_slist_append(struct curl_slist *list, - const char *data) -{ - struct curl_slist *last; - struct curl_slist *new_item; - - new_item = (struct curl_slist *) malloc(sizeof(struct curl_slist)); - if (new_item) { - char *cuDup = strdup(data); - if(cuDup) { - new_item->next = NULL; - new_item->data = cuDup; - } - else { - free(new_item); - return NULL; - } - } - else - return NULL; - - if (list) { - last = slist_get_last(list); - last->next = new_item; - return list; - } - - /* if this is the first item, then new_item *is* the list */ - return new_item; -} - -/* be nice and clean up resources */ -void curl_slist_free_all(struct curl_slist *list) -{ - struct curl_slist *next; - struct curl_slist *item; - - if (!list) - return; - - item = list; - do { - next = item->next; - - if (item->data) { - free(item->data); - } - free(item); - item = next; - } while (next); -} - -/* Curl_infof() is for info message along the way */ - -void Curl_infof(struct SessionHandle *data, const char *fmt, ...) -{ - if(data && data->set.verbose) { - va_list ap; - char print_buffer[1024 + 1]; - va_start(ap, fmt); - vsnprintf(print_buffer, 1024, fmt, ap); - va_end(ap); - Curl_debug(data, CURLINFO_TEXT, print_buffer, strlen(print_buffer), NULL); - } -} - -/* Curl_failf() is for messages stating why we failed. - * The message SHALL NOT include any LF or CR. - */ - -void Curl_failf(struct SessionHandle *data, const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - if(data->set.errorbuffer && !data->state.errorbuf) { - vsnprintf(data->set.errorbuffer, CURL_ERROR_SIZE, fmt, ap); - data->state.errorbuf = TRUE; /* wrote error string */ - - if(data->set.verbose) { - size_t len = strlen(data->set.errorbuffer); - bool doneit=FALSE; - if(len < CURL_ERROR_SIZE - 1) { - doneit = TRUE; - data->set.errorbuffer[len] = '\n'; - data->set.errorbuffer[++len] = '\0'; - } - Curl_debug(data, CURLINFO_TEXT, data->set.errorbuffer, len, NULL); - if(doneit) - /* cut off the newline again */ - data->set.errorbuffer[--len]=0; - } - } - va_end(ap); -} - -/* Curl_sendf() sends formated data to the server */ -CURLcode Curl_sendf(curl_socket_t sockfd, struct connectdata *conn, - const char *fmt, ...) -{ - struct SessionHandle *data = conn->data; - ssize_t bytes_written; - size_t write_len; - CURLcode res; - char *s; - char *sptr; - va_list ap; - va_start(ap, fmt); - s = vaprintf(fmt, ap); /* returns an allocated string */ - va_end(ap); - if(!s) - return CURLE_OUT_OF_MEMORY; /* failure */ - - bytes_written=0; - write_len = strlen(s); - sptr = s; - - while (1) { - /* 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, - conn->host.dispname); - - if((size_t)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; - } - - free(s); /* free the output string */ - - return res; -} - -/* - * Curl_write() is an internal write function that sends plain (binary) data - * to the server. Works with plain sockets, SSL or kerberos. - */ -CURLcode Curl_write(struct connectdata *conn, - curl_socket_t sockfd, - void *mem, - size_t len, - ssize_t *written) -{ - ssize_t bytes_written; - CURLcode retcode; - -#ifdef USE_SSLEAY - /* Set 'num' to 0 or 1, depending on which socket that has been sent here. - If it is the second socket, we set num to 1. Otherwise to 0. This lets - us use the correct ssl handle. */ - int num = (sockfd == conn->sock[SECONDARYSOCKET]); - /* SSL_write() is said to return 'int' while write() and send() returns - 'size_t' */ - if (conn->ssl[num].use) { - int err; - char error_buffer[120]; /* OpenSSL documents that this must be at least - 120 bytes long. */ - unsigned long sslerror; - int rc = SSL_write(conn->ssl[num].handle, mem, (int)len); - - if(rc < 0) { - err = SSL_get_error(conn->ssl[num].handle, rc); - - switch(err) { - case SSL_ERROR_WANT_READ: - case SSL_ERROR_WANT_WRITE: - /* The operation did not complete; the same TLS/SSL I/O function - should be called again later. This is basicly an EWOULDBLOCK - equivalent. */ - *written = 0; - return CURLE_OK; - case SSL_ERROR_SYSCALL: - failf(conn->data, "SSL_write() returned SYSCALL, errno = %d\n", - Curl_ourerrno()); - return CURLE_SEND_ERROR; - case SSL_ERROR_SSL: - /* A failure in the SSL library occurred, usually a protocol error. - The OpenSSL error queue contains more information on the error. */ - sslerror = ERR_get_error(); - failf(conn->data, "SSL_write() error: %s\n", - ERR_error_string(sslerror, error_buffer)); - return CURLE_SEND_ERROR; - } - /* a true error */ - failf(conn->data, "SSL_write() return error %d\n", err); - return CURLE_SEND_ERROR; - } - bytes_written = rc; - } - else { -#else - (void)conn; -#endif -#ifdef HAVE_KRB4 - if(conn->sec_complete) { - bytes_written = Curl_sec_write(conn, sockfd, mem, len); - } - else -#endif /* HAVE_KRB4 */ - { - bytes_written = (ssize_t)swrite(sockfd, mem, len); - } - if(-1 == bytes_written) { - int err = Curl_ourerrno(); - - if( -#ifdef WSAEWOULDBLOCK - /* This is how Windows does it */ - (WSAEWOULDBLOCK == err) -#else - /* As pointed out by Christophe Demory on March 11 2003, errno - may be EWOULDBLOCK or on some systems EAGAIN when it returned - due to its inability to send off data without blocking. We - therefor treat both error codes the same here */ - (EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err) -#endif - ) - /* this is just a case of EWOULDBLOCK */ - bytes_written=0; - } -#ifdef USE_SSLEAY - } -#endif - - *written = bytes_written; - retcode = (-1 != bytes_written)?CURLE_OK:CURLE_SEND_ERROR; - - return retcode; -} - -/* client_write() sends data to the write callback(s) - - The bit pattern defines to what "streams" to write to. Body and/or header. - The defines are in sendf.h of course. - */ -CURLcode Curl_client_write(struct SessionHandle *data, - int type, - char *ptr, - size_t len) -{ - size_t wrote; - - if(0 == len) - len = strlen(ptr); - - if(type & CLIENTWRITE_BODY) { - wrote = data->set.fwrite(ptr, 1, len, data->set.out); - if(wrote != len) { - failf (data, "Failed writing body"); - return CURLE_WRITE_ERROR; - } - } - if((type & CLIENTWRITE_HEADER) && - (data->set.fwrite_header || data->set.writeheader) ) { - /* - * Write headers to the same callback or to the especially setup - * header callback function (added after version 7.7.1). - */ - curl_write_callback writeit= - data->set.fwrite_header?data->set.fwrite_header:data->set.fwrite; - - wrote = writeit(ptr, 1, len, data->set.writeheader); - if(wrote != len) { - failf (data, "Failed writing header"); - return CURLE_WRITE_ERROR; - } - } - - return CURLE_OK; -} - -/* - * Internal read-from-socket function. This is meant to deal with plain - * sockets, SSL sockets and kerberos sockets. - * - * If the read would block (EWOULDBLOCK) we return -1. Otherwise we return - * a regular CURLcode value. - */ -int Curl_read(struct connectdata *conn, /* connection data */ - curl_socket_t sockfd, /* read from this socket */ - char *buf, /* store read data here */ - size_t buffersize, /* max amount to read */ - ssize_t *n) /* amount bytes read */ -{ - ssize_t nread; -#ifdef USE_SSLEAY - /* Set 'num' to 0 or 1, depending on which socket that has been sent here. - If it is the second socket, we set num to 1. Otherwise to 0. This lets - us use the correct ssl handle. */ - int num = (sockfd == conn->sock[SECONDARYSOCKET]); - - *n=0; /* reset amount to zero */ - - if (conn->ssl[num].use) { - nread = (ssize_t)SSL_read(conn->ssl[num].handle, buf, (int)buffersize); - - if(nread < 0) { - /* failed SSL_read */ - int err = SSL_get_error(conn->ssl[num].handle, (int)nread); - - switch(err) { - case SSL_ERROR_NONE: /* this is not an error */ - case SSL_ERROR_ZERO_RETURN: /* no more data */ - break; - case SSL_ERROR_WANT_READ: - case SSL_ERROR_WANT_WRITE: - /* there's data pending, re-invoke SSL_read() */ - return -1; /* basicly EWOULDBLOCK */ - default: - /* openssl/ssl.h says "look at error stack/return value/errno" */ - { - char error_buffer[120]; /* OpenSSL documents that this must be at - least 120 bytes long. */ - unsigned long sslerror = ERR_get_error(); - failf(conn->data, "SSL read: %s, errno %d", - ERR_error_string(sslerror, error_buffer), - Curl_ourerrno() ); - } - return CURLE_RECV_ERROR; - } - } - } - else { -#else - (void)conn; -#endif - *n=0; /* reset amount to zero */ -#ifdef HAVE_KRB4 - if(conn->sec_complete) - nread = Curl_sec_read(conn, sockfd, buf, buffersize); - else -#endif - nread = sread(sockfd, buf, buffersize); - - if(-1 == nread) { - int err = Curl_ourerrno(); -#ifdef WIN32 - if(WSAEWOULDBLOCK == err) -#else - if((EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err)) -#endif - return -1; - } - -#ifdef USE_SSLEAY - } -#endif /* USE_SSLEAY */ - *n = nread; - return CURLE_OK; -} - -/* return 0 on success */ -static int showit(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: - case CURLINFO_HEADER_IN: - fwrite(s_infotype[type], 2, 1, data->set.err); - fwrite(ptr, size, 1, data->set.err); - break; - default: /* nada */ - break; - } - return 0; -} - -int Curl_debug(struct SessionHandle *data, curl_infotype type, - char *ptr, size_t size, char *host) -{ - int rc; - if(data->set.printhost && host) { - char buffer[160]; - const char *t=NULL; - switch (type) { - case CURLINFO_HEADER_IN: - case CURLINFO_DATA_IN: - t = "from"; - break; - case CURLINFO_HEADER_OUT: - case CURLINFO_DATA_OUT: - t = "to"; - break; - default: - break; - } - - if(t) { - snprintf(buffer, sizeof(buffer), "[Data %s %s]", t, host); - rc = showit(data, CURLINFO_TEXT, buffer, strlen(buffer)); - if(rc) - return rc; - } - } - rc = showit(data, type, ptr, size); - return rc; -} diff --git a/Source/CTest/Curl/sendf.h b/Source/CTest/Curl/sendf.h deleted file mode 100644 index bdd3a79..0000000 --- a/Source/CTest/Curl/sendf.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef __SENDF_H -#define __SENDF_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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_sendf(curl_socket_t sockfd, struct connectdata *, - const char *fmt, ...); -void Curl_infof(struct SessionHandle *, const char *fmt, ...); -void Curl_failf(struct SessionHandle *, const char *fmt, ...); - -#define infof Curl_infof -#define failf Curl_failf - -#define CLIENTWRITE_BODY 1 -#define CLIENTWRITE_HEADER 2 -#define CLIENTWRITE_BOTH (CLIENTWRITE_BODY|CLIENTWRITE_HEADER) - -CURLcode Curl_client_write(struct SessionHandle *data, int type, char *ptr, - size_t len); - -/* internal read-function, does plain socket, SSL and krb4 */ -int Curl_read(struct connectdata *conn, curl_socket_t sockfd, - char *buf, size_t buffersize, - ssize_t *n); -/* internal write-function, does plain socket, SSL and krb4 */ -CURLcode Curl_write(struct connectdata *conn, - curl_socket_t sockfd, - void *mem, size_t len, - ssize_t *written); - -/* the function used to output verbose information */ -int Curl_debug(struct SessionHandle *handle, curl_infotype type, - char *data, size_t size, char *host); - - -#endif diff --git a/Source/CTest/Curl/setup.h b/Source/CTest/Curl/setup.h deleted file mode 100644 index fff6974..0000000 --- a/Source/CTest/Curl/setup.h +++ /dev/null @@ -1,294 +0,0 @@ -#ifndef __SETUP_H -#define __SETUP_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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$ - ***************************************************************************/ - -#ifdef HTTP_ONLY -#define CURL_DISABLE_FTP -#define CURL_DISABLE_LDAP -#define CURL_DISABLE_TELNET -#define CURL_DISABLE_DICT -#define CURL_DISABLE_FILE -#define CURL_DISABLE_GOPHER -#endif - -#if !defined(WIN32) && defined(__WIN32__) -/* This should be a good Borland fix. Alexander J. Oss told us! */ -#define WIN32 -#endif - -#ifdef HAVE_CONFIG_H -#include "config.h" /* the configure script results */ -#else -#ifdef WIN32 -/* hand-modified win32 config.h! */ -#include "config-win32.h" -#endif -#endif - -#ifdef macintosh -/* hand-modified MacOS config.h! */ -#include "config-mac.h" -#endif -#ifdef AMIGA -/* hand-modified AmigaOS config.h! */ -#include "amigaos.h" -#endif - -#ifndef TRUE -#define TRUE 1 -#endif -#ifndef FALSE -#define FALSE 0 -#endif - -#if !defined(__cplusplus) && !defined(__BEOS__) -typedef unsigned char bool; -#define typedef_bool -#endif - -#ifdef HAVE_LONGLONG -#define LONG_LONG long long -#define ENABLE_64BIT -#else -#ifdef _MSC_VER -#define LONG_LONG __int64 -#define ENABLE_64BIT -#endif -#endif /* HAVE_LONGLONG */ - -#ifndef SIZEOF_CURL_OFF_T -/* If we don't know the size here, we assume a conservative size: 4. When - building libcurl, the actual size of this variable should be define in the - config*.h file. */ -#define SIZEOF_CURL_OFF_T 4 -#endif - -/* We set up our internal prefered (CURL_)FORMAT_OFF_T here */ -#if SIZEOF_CURL_OFF_T > 4 -#define FORMAT_OFF_T "lld" -#else -#define FORMAT_OFF_T "ld" -#endif - -#ifdef NEED_REENTRANT -/* Solaris machines needs _REENTRANT set for a few function prototypes and - things to appear in the #include files. We need to #define it before all - #include files */ -#define _REENTRANT -#endif - -#include <stdio.h> -#ifdef HAVE_ASSERT_H -#include <assert.h> -#endif -#include <errno.h> - -#ifdef __TANDEM /* for nsr-tandem-nsk systems */ -#include <floss.h> -#endif - -#if defined(HAVE_X509_H) && defined(HAVE_SSL_H) && defined(HAVE_RSA_H) && \ -defined(HAVE_PEM_H) && defined(HAVE_ERR_H) && defined(HAVE_CRYPTO_H) && \ -defined(HAVE_LIBSSL) && defined(HAVE_LIBCRYPTO) - /* the six important includes files all exist and so do both libs, - defined SSLeay usage */ -#define USE_SSLEAY 1 -#endif -#if defined(HAVE_OPENSSL_X509_H) && defined(HAVE_OPENSSL_SSL_H) && \ -defined(HAVE_OPENSSL_RSA_H) && defined(HAVE_OPENSSL_PEM_H) && \ -defined(HAVE_OPENSSL_ERR_H) && defined(HAVE_OPENSSL_CRYPTO_H) && \ -defined(HAVE_LIBSSL) && defined(HAVE_LIBCRYPTO) - /* the six important includes files all exist and so do both libs, - defined SSLeay usage */ -#define USE_SSLEAY 1 -#define USE_OPENSSL 1 -#endif - -#ifndef STDC_HEADERS /* no standard C headers! */ -#include <curl/stdcheaders.h> -#endif - -#if defined(CURLDEBUG) && defined(HAVE_ASSERT_H) -#define curlassert(x) assert(x) -#else -/* does nothing without CURLDEBUG defined */ -#define curlassert(x) -#endif - -#ifdef MSG_NOSIGNAL -/* If we have the MSG_NOSIGNAL define, we make sure to use that in the forth - argument to send() and recv() */ -#define SEND_4TH_ARG MSG_NOSIGNAL -#define HAVE_MSG_NOSIGNAL 1 /* we have MSG_NOSIGNAL */ -#else -#define SEND_4TH_ARG 0 -#endif - - -/* Below we define four functions. They should - 1. close a socket - 2. read from a socket - 3. write to a socket - - 4. set the SIGALRM signal timeout - 5. set dir/file naming defines - */ - -#ifdef WIN32 - -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN /* Prevent including <winsock*.h> in <windows.h> */ -#endif - -#if (defined(ENABLE_IPV6) || defined(CURLDEBUG)) && defined(_MSC_VER) && \ - (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0500) -/* - * Needed to pull in the real getaddrinfo() and not the inline version - * in <wspiAPI.H> which doesn't support IPv6 (IPv4 only). <wspiAPI.H> is - * included from <ws2tcpip.h> for <= 0x0500 SDKs. - */ -#undef _WIN32_WINNT -#define _WIN32_WINNT 0x0501 -#endif - -#include <winsock2.h> /* required by telnet.c */ - -#if defined(ENABLE_IPV6) || defined(USE_SSLEAY) -#include <ws2tcpip.h> -#endif - -#if !defined(__GNUC__) || defined(__MINGW32__) -#define sclose(x) closesocket(x) -#define sread(x,y,z) recv(x,y,z, SEND_4TH_ARG) -#define swrite(x,y,z) (size_t)send(x,y,z, SEND_4TH_ARG) -#undef HAVE_ALARM -#else - /* gcc-for-win is still good :) */ -#define sclose(x) close(x) -#define sread(x,y,z) recv(x,y,z, SEND_4TH_ARG) -#define swrite(x,y,z) send(x,y,z, SEND_4TH_ARG) -#define HAVE_ALARM -#endif - -#define DIR_CHAR "\\" -#define DOT_CHAR "_" - -#else - -#ifdef DJGPP -#define sclose(x) close_s(x) -#define sread(x,y,z) read_s(x,y,z) -#define swrite(x,y,z) write_s(x,y,z) -#define select(n,r,w,x,t) select_s(n,r,w,x,t) -#define ioctl(x,y,z) ioctlsocket(x,y,(char *)(z)) -#define IOCTL_3_ARGS -#include <tcp.h> -#ifdef word -#undef word -#endif - -#else - -#ifdef __BEOS__ -#define sclose(x) closesocket(x) -#define sread(x,y,z) (ssize_t)recv(x,y,z, SEND_4TH_ARG) -#define swrite(x,y,z) (ssize_t)send(x,y,z, SEND_4TH_ARG) -#else -#define sclose(x) close(x) -#define sread(x,y,z) recv(x,y,z, SEND_4TH_ARG) -#define swrite(x,y,z) send(x,y,z, SEND_4TH_ARG) -#endif - -#define HAVE_ALARM - -#endif - -#ifdef _AMIGASF -#undef HAVE_ALARM -#undef sclose -#define sclose(x) CloseSocket(x) -#endif - -#define DIR_CHAR "/" -#define DOT_CHAR "." - -#ifdef DJGPP -#undef DOT_CHAR -#define DOT_CHAR "_" -#endif - -#ifndef fileno /* sunos 4 have this as a macro! */ -int fileno( FILE *stream); -#endif - -#endif - -/* now typedef our socket type */ -#ifdef WIN32 -typedef SOCKET curl_socket_t; -#define CURL_SOCKET_BAD INVALID_SOCKET -#else -typedef int curl_socket_t; -#define CURL_SOCKET_BAD -1 -#endif - -#if defined(ENABLE_IPV6) && defined(USE_ARES) -#error "ares does not yet support IPv6. Disable IPv6 or ares and rebuild" -#endif - -#if defined(WIN32) && !defined(__CYGWIN__) && !defined(USE_ARES) && \ - !defined(__LCC__) /* lcc-win32 doesn't have _beginthreadex() */ -#ifdef ENABLE_IPV6 -#define USE_THREADING_GETADDRINFO -#else -#define USE_THREADING_GETHOSTBYNAME /* Cygwin uses alarm() function */ -#endif -#endif - -#ifdef mpeix -#define IOCTL_3_ARGS -#endif - -#ifndef ECONNRESET -#ifdef WSAECONNRESET -#define ECONNRESET WSAECONNRESET -#else -/* This will effectively prevent the code from working in this particular - aspect, but it still compile fine! */ -#define ECONNRESET 10000 -#endif -#endif - -#ifdef NETWARE -#undef HAVE_ALARM -#endif - -#ifdef HAVE_LIBIDN -/* This could benefit from additional checks that some of the used/important - header files are present as well before we define the USE_* define. */ -#define USE_LIBIDN -#define LIBIDN_REQUIRED_VERSION "0.4.1" -#endif - -#endif /* __CONFIG_H */ diff --git a/Source/CTest/Curl/share.c b/Source/CTest/Curl/share.c deleted file mode 100644 index 1022d97..0000000 --- a/Source/CTest/Curl/share.c +++ /dev/null @@ -1,219 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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 <stdarg.h> -#include <stdlib.h> -#include <string.h> -#include <curl/curl.h> -#include "urldata.h" -#include "share.h" -#include "curl_memory.h" - -/* The last #include file should be: */ -#include "memdebug.h" - -CURLSH * -curl_share_init(void) -{ - struct Curl_share *share = - (struct Curl_share *)malloc(sizeof(struct Curl_share)); - if (share) { - memset (share, 0, sizeof(struct Curl_share)); - share->specifier |= (1<<CURL_LOCK_DATA_SHARE); - } - - return share; -} - -CURLSHcode -curl_share_setopt(CURLSH *sh, CURLSHoption option, ...) -{ - struct Curl_share *share = (struct Curl_share *)sh; - va_list param; - int type; - curl_lock_function lockfunc; - curl_unlock_function unlockfunc; - void *ptr; - - if (share->dirty) - /* don't allow setting options while one or more handles are already - using this share */ - return CURLSHE_IN_USE; - - va_start(param, option); - - switch(option) { - case CURLSHOPT_SHARE: - /* this is a type this share will share */ - type = va_arg(param, int); - share->specifier |= (1<<type); - switch( type ) { - case CURL_LOCK_DATA_DNS: - if (!share->hostcache) { - share->hostcache = Curl_mk_dnscache(); - if(!share->hostcache) - return CURLSHE_NOMEM; - } - break; - -#ifndef CURL_DISABLE_HTTP - case CURL_LOCK_DATA_COOKIE: - if (!share->cookies) { - share->cookies = Curl_cookie_init(NULL, NULL, NULL, TRUE ); - if(!share->cookies) - return CURLSHE_NOMEM; - } - break; -#endif /* CURL_DISABLE_HTTP */ - - case CURL_LOCK_DATA_SSL_SESSION: /* not supported (yet) */ - case CURL_LOCK_DATA_CONNECT: /* not supported (yet) */ - - default: - return CURLSHE_BAD_OPTION; - } - break; - - case CURLSHOPT_UNSHARE: - /* this is a type this share will no longer share */ - type = va_arg(param, int); - share->specifier &= ~(1<<type); - switch( type ) - { - case CURL_LOCK_DATA_DNS: - if (share->hostcache) { - Curl_hash_destroy(share->hostcache); - share->hostcache = NULL; - } - break; - -#ifndef CURL_DISABLE_HTTP - case CURL_LOCK_DATA_COOKIE: - if (share->cookies) { - Curl_cookie_cleanup(share->cookies); - share->cookies = NULL; - } - break; -#endif /* CURL_DISABLE_HTTP */ - - case CURL_LOCK_DATA_SSL_SESSION: - break; - - case CURL_LOCK_DATA_CONNECT: - break; - - default: - return CURLSHE_BAD_OPTION; - } - break; - - case CURLSHOPT_LOCKFUNC: - lockfunc = va_arg(param, curl_lock_function); - share->lockfunc = lockfunc; - break; - - case CURLSHOPT_UNLOCKFUNC: - unlockfunc = va_arg(param, curl_unlock_function); - share->unlockfunc = unlockfunc; - break; - - case CURLSHOPT_USERDATA: - ptr = va_arg(param, void *); - share->clientdata = ptr; - break; - - default: - return CURLSHE_BAD_OPTION; - } - - return CURLSHE_OK; -} - -CURLSHcode -curl_share_cleanup(CURLSH *sh) -{ - struct Curl_share *share = (struct Curl_share *)sh; - - if (share == NULL) - return CURLSHE_INVALID; - - if(share->lockfunc) - share->lockfunc(NULL, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE, - share->clientdata); - - if (share->dirty) { - if(share->unlockfunc) - share->unlockfunc(NULL, CURL_LOCK_DATA_SHARE, share->clientdata); - return CURLSHE_IN_USE; - } - - if(share->hostcache) - Curl_hash_destroy(share->hostcache); - -#ifndef CURL_DISABLE_HTTP - if(share->cookies) - Curl_cookie_cleanup(share->cookies); -#endif /* CURL_DISABLE_HTTP */ - - if(share->unlockfunc) - share->unlockfunc(NULL, CURL_LOCK_DATA_SHARE, share->clientdata); - free(share); - - return CURLSHE_OK; -} - - -CURLSHcode -Curl_share_lock(struct SessionHandle *data, curl_lock_data type, - curl_lock_access accesstype) -{ - struct Curl_share *share = data->share; - - if (share == NULL) - return CURLSHE_INVALID; - - if(share->specifier & (1<<type)) { - if(share->lockfunc) /* only call this if set! */ - share->lockfunc(data, type, accesstype, share->clientdata); - } - /* else if we don't share this, pretend successful lock */ - - return CURLSHE_OK; -} - -CURLSHcode -Curl_share_unlock(struct SessionHandle *data, curl_lock_data type) -{ - struct Curl_share *share = data->share; - - if (share == NULL) - return CURLSHE_INVALID; - - if(share->specifier & (1<<type)) { - if(share->unlockfunc) /* only call this if set! */ - share->unlockfunc (data, type, share->clientdata); - } - - return CURLSHE_OK; -} diff --git a/Source/CTest/Curl/share.h b/Source/CTest/Curl/share.h deleted file mode 100644 index 5c85c80..0000000 --- a/Source/CTest/Curl/share.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef __CURL_SHARE_H -#define __CURL_SHARE_H - -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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 <curl/curl.h> -#include "cookie.h" - -/* this struct is libcurl-private, don't export details */ -struct Curl_share { - unsigned int specifier; - volatile unsigned int dirty; - - curl_lock_function lockfunc; - curl_unlock_function unlockfunc; - void *clientdata; - - curl_hash *hostcache; - struct CookieInfo *cookies; -}; - -CURLSHcode Curl_share_lock ( - struct SessionHandle *, - curl_lock_data, - curl_lock_access - ); - -CURLSHcode Curl_share_unlock ( - struct SessionHandle *, - curl_lock_data - ); - -#endif /* __CURL_SHARE_H */ diff --git a/Source/CTest/Curl/speedcheck.c b/Source/CTest/Curl/speedcheck.c deleted file mode 100644 index 33a8e5d..0000000 --- a/Source/CTest/Curl/speedcheck.c +++ /dev/null @@ -1,67 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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 <stdio.h> -#include <string.h> - -#include <curl/curl.h> -#include "urldata.h" -#include "sendf.h" -#include "speedcheck.h" - -void Curl_speedinit(struct SessionHandle *data) -{ - memset(&data->state.keeps_speed, 0, sizeof(struct timeval)); -} - -CURLcode Curl_speedcheck(struct SessionHandle *data, - struct timeval now) -{ - if((data->progress.current_speed >= 0) && - data->set.low_speed_time && - (Curl_tvlong(data->state.keeps_speed) != 0) && - (data->progress.current_speed < data->set.low_speed_limit)) { - - /* We are now below the "low speed limit". If we are below it - for "low speed time" seconds we consider that enough reason - to abort the download. */ - - if( (Curl_tvdiff(now, data->state.keeps_speed)/1000) > - data->set.low_speed_time) { - /* we have been this slow for long enough, now die */ - failf(data, - "Operation too slow. " - "Less than %d bytes/sec transfered the last %d seconds", - data->set.low_speed_limit, - data->set.low_speed_time); - return CURLE_OPERATION_TIMEOUTED; - } - } - else { - /* we keep up the required speed all right */ - data->state.keeps_speed = now; - } - return CURLE_OK; -} diff --git a/Source/CTest/Curl/speedcheck.h b/Source/CTest/Curl/speedcheck.h deleted file mode 100644 index 62475f6..0000000 --- a/Source/CTest/Curl/speedcheck.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef __SPEEDCHECK_H -#define __SPEEDCHECK_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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 "timeval.h" - -void Curl_speedinit(struct SessionHandle *data); -CURLcode Curl_speedcheck(struct SessionHandle *data, - struct timeval now); - -#endif diff --git a/Source/CTest/Curl/ssluse.c b/Source/CTest/Curl/ssluse.c deleted file mode 100644 index 04d1c94..0000000 --- a/Source/CTest/Curl/ssluse.c +++ /dev/null @@ -1,1487 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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$ - ***************************************************************************/ - -/* - * The original SSL code for curl was written by - * Linas Vepstas <linas@linas.org> and Sampo Kellomaki <sampo@iki.fi> - */ - -#include "setup.h" - -#include <string.h> -#include <stdlib.h> -#include <ctype.h> -#ifdef HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif -#ifdef HAVE_SYS_SOCKET_H -#include <sys/socket.h> -#endif - -#include "urldata.h" -#include "sendf.h" -#include "formdata.h" /* for the boundary function */ -#include "url.h" /* for the ssl config check function */ -#include "inet_pton.h" -#include "ssluse.h" -#include "connect.h" /* Curl_ourerrno() proto */ -#include "strequal.h" - -#define _MPRINTF_REPLACE /* use the internal *printf() functions */ -#include <curl/mprintf.h> - -#ifdef USE_SSLEAY -#include <openssl/rand.h> -#include <openssl/x509v3.h> - -#include "curl_memory.h" - -/* The last #include file should be: */ -#include "memdebug.h" - -#ifndef min -#define min(a, b) ((a) < (b) ? (a) : (b)) -#endif - -#if OPENSSL_VERSION_NUMBER >= 0x0090581fL -#define HAVE_SSL_GET1_SESSION 1 -#else -#undef HAVE_SSL_GET1_SESSION -#endif - -#if OPENSSL_VERSION_NUMBER >= 0x00904100L -#define HAVE_USERDATA_IN_PWD_CALLBACK 1 -#else -#undef HAVE_USERDATA_IN_PWD_CALLBACK -#endif - -#if OPENSSL_VERSION_NUMBER >= 0x00907001L -/* ENGINE_load_private_key() takes four arguments */ -#define HAVE_ENGINE_LOAD_FOUR_ARGS -#else -/* ENGINE_load_private_key() takes three arguments */ -#undef HAVE_ENGINE_LOAD_FOUR_ARGS -#endif - -#if OPENSSL_VERSION_NUMBER >= 0x00906001L -#define HAVE_ERR_ERROR_STRING_N 1 -#endif - - -#ifndef HAVE_USERDATA_IN_PWD_CALLBACK -static char global_passwd[64]; -#endif - -static int passwd_callback(char *buf, int num, int verify -#if HAVE_USERDATA_IN_PWD_CALLBACK - /* This was introduced in 0.9.4, we can set this - using SSL_CTX_set_default_passwd_cb_userdata() - */ - , void *global_passwd -#endif - ) -{ - if(verify) - fprintf(stderr, "%s\n", buf); - else { - if(num > (int)strlen((char *)global_passwd)) { - strcpy(buf, global_passwd); - return (int)strlen(buf); - } - } - return 0; -} - -/* - * rand_enough() is a function that returns TRUE if we have seeded the random - * engine properly. We use some preprocessor magic to provide a seed_enough() - * macro to use, just to prevent a compiler warning on this function if we - * pass in an argument that is never used. - */ - -#ifdef HAVE_RAND_STATUS -#define seed_enough(x) rand_enough() -static bool rand_enough(void) -{ - return RAND_status()?TRUE:FALSE; -} -#else -#define seed_enough(x) rand_enough(x) -static bool rand_enough(int nread) -{ - /* this is a very silly decision to make */ - return (nread > 500)?TRUE:FALSE; -} -#endif - -static -int random_the_seed(struct SessionHandle *data) -{ - char *buf = data->state.buffer; /* point to the big buffer */ - int nread=0; - - /* Q: should we add support for a random file name as a libcurl option? - A: Yes, it is here */ - -#ifndef RANDOM_FILE - /* if RANDOM_FILE isn't defined, we only perform this if an option tells - us to! */ - if(data->set.ssl.random_file) -#define RANDOM_FILE "" /* doesn't matter won't be used */ -#endif - { - /* let the option override the define */ - nread += RAND_load_file((data->set.ssl.random_file? - data->set.ssl.random_file:RANDOM_FILE), - 16384); - if(seed_enough(nread)) - return nread; - } - -#if defined(HAVE_RAND_EGD) - /* only available in OpenSSL 0.9.5 and later */ - /* EGD_SOCKET is set at configure time or not at all */ -#ifndef EGD_SOCKET - /* If we don't have the define set, we only do this if the egd-option - is set */ - if(data->set.ssl.egdsocket) -#define EGD_SOCKET "" /* doesn't matter won't be used */ -#endif - { - /* If there's an option and a define, the option overrides the - define */ - int ret = RAND_egd(data->set.ssl.egdsocket? - data->set.ssl.egdsocket:EGD_SOCKET); - if(-1 != ret) { - nread += ret; - if(seed_enough(nread)) - return nread; - } - } -#endif - - /* If we get here, it means we need to seed the PRNG using a "silly" - approach! */ -#ifdef HAVE_RAND_SCREEN - /* This one gets a random value by reading the currently shown screen */ - RAND_screen(); - nread = 100; /* just a value */ -#else - { - int len; - char *area; - - /* Changed call to RAND_seed to use the underlying RAND_add implementation - * directly. Do this in a loop, with the amount of additional entropy - * being dependent upon the algorithm used by Curl_FormBoundary(): N bytes - * of a 7-bit ascii set. -- Richard Gorton, March 11 2003. - */ - - do { - area = Curl_FormBoundary(); - if(!area) - return 3; /* out of memory */ - - len = (int)strlen(area); - RAND_add(area, len, (len >> 1)); - - free(area); /* now remove the random junk */ - } while (!RAND_status()); - } -#endif - - /* generates a default path for the random seed file */ - buf[0]=0; /* blank it first */ - RAND_file_name(buf, BUFSIZE); - if(buf[0]) { - /* we got a file name to try */ - nread += RAND_load_file(buf, 16384); - if(seed_enough(nread)) - return nread; - } - - infof(data, "libcurl is now using a weak random seed!\n"); - return nread; -} - -#ifndef SSL_FILETYPE_ENGINE -#define SSL_FILETYPE_ENGINE 42 -#endif -static int do_file_type(const char *type) -{ - if(!type || !type[0]) - return SSL_FILETYPE_PEM; - if(curl_strequal(type, "PEM")) - return SSL_FILETYPE_PEM; - if(curl_strequal(type, "DER")) - return SSL_FILETYPE_ASN1; - if(curl_strequal(type, "ENG")) - return SSL_FILETYPE_ENGINE; - return -1; -} - -static -int cert_stuff(struct connectdata *conn, - SSL_CTX* ctx, - char *cert_file, - const char *cert_type, - char *key_file, - const char *key_type) -{ - struct SessionHandle *data = conn->data; - int file_type; - - if(cert_file != NULL) { - SSL *ssl; - X509 *x509; - - if(data->set.key_passwd) { -#ifndef HAVE_USERDATA_IN_PWD_CALLBACK - /* - * If password has been given, we store that in the global - * area (*shudder*) for a while: - */ - size_t len = strlen(data->set.key_passwd); - if(len < sizeof(global_passwd)) - memcpy(global_passwd, data->set.key_passwd, len+1); -#else - /* - * We set the password in the callback userdata - */ - SSL_CTX_set_default_passwd_cb_userdata(ctx, - data->set.key_passwd); -#endif - /* Set passwd callback: */ - SSL_CTX_set_default_passwd_cb(ctx, passwd_callback); - } - - file_type = do_file_type(cert_type); - - switch(file_type) { - case SSL_FILETYPE_PEM: - /* SSL_CTX_use_certificate_chain_file() only works on PEM files */ - if(SSL_CTX_use_certificate_chain_file(ctx, - cert_file) != 1) { - failf(data, "unable to set certificate file (wrong password?)"); - return 0; - } - break; - - case SSL_FILETYPE_ASN1: - /* SSL_CTX_use_certificate_file() works with either PEM or ASN1, but - we use the case above for PEM so this can only be performed with - ASN1 files. */ - if(SSL_CTX_use_certificate_file(ctx, - cert_file, - file_type) != 1) { - failf(data, "unable to set certificate file (wrong password?)"); - return 0; - } - break; - case SSL_FILETYPE_ENGINE: - failf(data, "file type ENG for certificate not implemented"); - return 0; - - default: - failf(data, "not supported file type '%s' for certificate", cert_type); - return 0; - } - - file_type = do_file_type(key_type); - - switch(file_type) { - case SSL_FILETYPE_PEM: - if(key_file == NULL) - /* cert & key can only be in PEM case in the same file */ - key_file=cert_file; - case SSL_FILETYPE_ASN1: - if(SSL_CTX_use_PrivateKey_file(ctx, key_file, file_type) != 1) { - failf(data, "unable to set private key file: '%s' type %s\n", - key_file, key_type?key_type:"PEM"); - return 0; - } - break; - case SSL_FILETYPE_ENGINE: -#ifdef HAVE_OPENSSL_ENGINE_H - { /* XXXX still needs some work */ - EVP_PKEY *priv_key = NULL; - if(conn && conn->data && conn->data->engine) { -#ifdef HAVE_ENGINE_LOAD_FOUR_ARGS - UI_METHOD *ui_method = UI_OpenSSL(); -#endif - if(!key_file || !key_file[0]) { - failf(data, "no key set to load from crypto engine\n"); - return 0; - } - /* the typecast below was added to please mingw32 */ - priv_key = (EVP_PKEY *) - ENGINE_load_private_key(conn->data->engine,key_file, -#ifdef HAVE_ENGINE_LOAD_FOUR_ARGS - ui_method, -#endif - data->set.key_passwd); - if(!priv_key) { - failf(data, "failed to load private key from crypto engine\n"); - return 0; - } - if(SSL_CTX_use_PrivateKey(ctx, priv_key) != 1) { - failf(data, "unable to set private key\n"); - EVP_PKEY_free(priv_key); - return 0; - } - EVP_PKEY_free(priv_key); /* we don't need the handle any more... */ - } - else { - failf(data, "crypto engine not set, can't load private key\n"); - return 0; - } - } - break; -#else - failf(data, "file type ENG for private key not supported\n"); - return 0; -#endif - default: - failf(data, "not supported file type for private key\n"); - return 0; - } - - ssl=SSL_new(ctx); - x509=SSL_get_certificate(ssl); - - /* This version was provided by Evan Jordan and is supposed to not - leak memory as the previous version: */ - if(x509 != NULL) { - EVP_PKEY *pktmp = X509_get_pubkey(x509); - EVP_PKEY_copy_parameters(pktmp,SSL_get_privatekey(ssl)); - EVP_PKEY_free(pktmp); - } - - SSL_free(ssl); - - /* If we are using DSA, we can copy the parameters from - * the private key */ - - - /* Now we know that a key and cert have been set against - * the SSL context */ - if(!SSL_CTX_check_private_key(ctx)) { - failf(data, "Private key does not match the certificate public key"); - return(0); - } -#ifndef HAVE_USERDATA_IN_PWD_CALLBACK - /* erase it now */ - memset(global_passwd, 0, sizeof(global_passwd)); -#endif - } - return(1); -} - -static -int cert_verify_callback(int ok, X509_STORE_CTX *ctx) -{ - X509 *err_cert; - char buf[256]; - - err_cert=X509_STORE_CTX_get_current_cert(ctx); - X509_NAME_oneline(X509_get_subject_name(err_cert), buf, sizeof(buf)); - return ok; -} - -/* "global" init done? */ -static int init_ssl=0; - -/* we have the "SSL is seeded" boolean global for the application to - prevent multiple time-consuming seedings in vain */ -static bool ssl_seeded = FALSE; -#endif /* USE_SSLEAY */ - -/* Global init */ -void Curl_SSL_init(void) -{ -#ifdef USE_SSLEAY - /* make sure this is only done once */ - if(0 != init_ssl) - return; - - init_ssl++; /* never again */ - -#ifdef HAVE_ENGINE_LOAD_BUILTIN_ENGINES - ENGINE_load_builtin_engines(); -#endif - - /* Lets get nice error messages */ - SSL_load_error_strings(); - - /* Setup all the global SSL stuff */ - SSLeay_add_ssl_algorithms(); -#else - /* SSL disabled, do nothing */ -#endif -} - -/* Global cleanup */ -void Curl_SSL_cleanup(void) -{ -#ifdef USE_SSLEAY - if(init_ssl) { - /* only cleanup if we did a previous init */ - - /* Free the SSL error strings */ - ERR_free_strings(); - - /* EVP_cleanup() removes all ciphers and digests from the - table. */ - EVP_cleanup(); - -#ifdef HAVE_ENGINE_cleanup - ENGINE_cleanup(); -#endif - -#ifdef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA - /* this function was not present in 0.9.6b, but was added sometimes - later */ - CRYPTO_cleanup_all_ex_data(); -#endif - - init_ssl=0; /* not inited any more */ - } -#else - /* SSL disabled, do nothing */ -#endif -} - -#ifndef USE_SSLEAY -void Curl_SSL_Close(struct connectdata *conn) -{ - (void)conn; -} -#endif - -#ifdef USE_SSLEAY - -/* - * This function is called when an SSL connection is closed. - */ -void Curl_SSL_Close(struct connectdata *conn) -{ - if(conn->ssl[FIRSTSOCKET].use) { - int i; - /* - ERR_remove_state() frees the error queue associated with - thread pid. If pid == 0, the current thread will have its - error queue removed. - - Since error queue data structures are allocated - automatically for new threads, they must be freed when - threads are terminated in oder to avoid memory leaks. - */ - ERR_remove_state(0); - - for(i=0; i<2; i++) { - struct ssl_connect_data *connssl = &conn->ssl[i]; - - if(connssl->handle) { - (void)SSL_shutdown(connssl->handle); - SSL_set_connect_state(connssl->handle); - - SSL_free (connssl->handle); - connssl->handle = NULL; - } - if(connssl->ctx) { - SSL_CTX_free (connssl->ctx); - connssl->ctx = NULL; - } - connssl->use = FALSE; /* get back to ordinary socket usage */ - } - } -} - - -/* - * This sets up a session cache to the specified size. - */ -CURLcode Curl_SSL_InitSessions(struct SessionHandle *data, long amount) -{ - struct curl_ssl_session *session; - - if(data->state.session) - /* this is just a precaution to prevent multiple inits */ - return CURLE_OK; - - session = (struct curl_ssl_session *) - malloc(amount * sizeof(struct curl_ssl_session)); - if(!session) - return CURLE_OUT_OF_MEMORY; - - /* "blank out" the newly allocated memory */ - memset(session, 0, amount * sizeof(struct curl_ssl_session)); - - /* store the info in the SSL section */ - data->set.ssl.numsessions = amount; - data->state.session = session; - data->state.sessionage = 1; /* this is brand new */ - - return CURLE_OK; -} - -/* - * Check if there's a session ID for the given connection in the cache, - * and if there's one suitable, it is returned. - */ -static int Get_SSL_Session(struct connectdata *conn, - SSL_SESSION **ssl_sessionid) -{ - struct curl_ssl_session *check; - struct SessionHandle *data = conn->data; - long i; - - for(i=0; i< data->set.ssl.numsessions; i++) { - check = &data->state.session[i]; - if(!check->sessionid) - /* not session ID means blank entry */ - continue; - if(curl_strequal(conn->host.name, check->name) && - (conn->remote_port == check->remote_port) && - Curl_ssl_config_matches(&conn->ssl_config, &check->ssl_config)) { - /* yes, we have a session ID! */ - data->state.sessionage++; /* increase general age */ - check->age = data->state.sessionage; /* set this as used in this age */ - *ssl_sessionid = check->sessionid; - return FALSE; - } - } - *ssl_sessionid = (SSL_SESSION *)NULL; - return TRUE; -} - -/* - * Kill a single session ID entry in the cache. - */ -static int Kill_Single_Session(struct curl_ssl_session *session) -{ - if(session->sessionid) { - /* defensive check */ - - /* free the ID */ - SSL_SESSION_free(session->sessionid); - session->sessionid=NULL; - session->age = 0; /* fresh */ - - Curl_free_ssl_config(&session->ssl_config); - - Curl_safefree(session->name); - session->name = NULL; /* no name */ - - return 0; /* ok */ - } - else - return 1; -} - -/* - * This function is called when the 'data' struct is going away. Close - * down everything and free all resources! - */ -int Curl_SSL_Close_All(struct SessionHandle *data) -{ - int i; - - if(data->state.session) { - for(i=0; i< data->set.ssl.numsessions; i++) - /* the single-killer function handles empty table slots */ - Kill_Single_Session(&data->state.session[i]); - - /* free the cache data */ - free(data->state.session); - } -#ifdef HAVE_OPENSSL_ENGINE_H - if(data->engine) - { - ENGINE_free(data->engine); - data->engine = NULL; - } -#endif - return 0; -} - -/* - * Extract the session id and store it in the session cache. - */ -static int Store_SSL_Session(struct connectdata *conn, - struct ssl_connect_data *ssl) -{ - SSL_SESSION *ssl_sessionid; - int i; - struct SessionHandle *data=conn->data; /* the mother of all structs */ - struct curl_ssl_session *store = &data->state.session[0]; - long oldest_age=data->state.session[0].age; /* zero if unused */ - char *clone_host; - - clone_host = strdup(conn->host.name); - if(!clone_host) - return -1; /* bail out */ - - /* ask OpenSSL, say please */ - -#ifdef HAVE_SSL_GET1_SESSION - ssl_sessionid = SSL_get1_session(ssl->handle); - - /* SSL_get1_session() will increment the reference - count and the session will stay in memory until explicitly freed with - SSL_SESSION_free(3), regardless of its state. - This function was introduced in openssl 0.9.5a. */ -#else - ssl_sessionid = SSL_get_session(ssl->handle); - - /* if SSL_get1_session() is unavailable, use SSL_get_session(). - This is an inferior option because the session can be flushed - at any time by openssl. It is included only so curl compiles - under versions of openssl < 0.9.5a. - - WARNING: How curl behaves if it's session is flushed is - untested. - */ -#endif - - /* Now we should add the session ID and the host name to the cache, (remove - the oldest if necessary) */ - - /* find an empty slot for us, or find the oldest */ - for(i=1; (i<data->set.ssl.numsessions) && - data->state.session[i].sessionid; i++) { - if(data->state.session[i].age < oldest_age) { - oldest_age = data->state.session[i].age; - store = &data->state.session[i]; - } - } - if(i == data->set.ssl.numsessions) - /* cache is full, we must "kill" the oldest entry! */ - Kill_Single_Session(store); - else - store = &data->state.session[i]; /* use this slot */ - - /* now init the session struct wisely */ - store->sessionid = ssl_sessionid; - store->age = data->state.sessionage; /* set current age */ - store->name = clone_host; /* clone host name */ - store->remote_port = conn->remote_port; /* port number */ - - Curl_clone_ssl_config(&conn->ssl_config, &store->ssl_config); - - return 0; -} - -static int Curl_ASN1_UTCTIME_output(struct connectdata *conn, - const char *prefix, - ASN1_UTCTIME *tm) -{ - char *asn1_string; - int gmt=FALSE; - int i; - int year=0,month=0,day=0,hour=0,minute=0,second=0; - struct SessionHandle *data = conn->data; - - if(!data->set.verbose) - return 0; - - i=tm->length; - asn1_string=(char *)tm->data; - - if(i < 10) - return 1; - if(asn1_string[i-1] == 'Z') - gmt=TRUE; - for (i=0; i<10; i++) - if((asn1_string[i] > '9') || (asn1_string[i] < '0')) - return 2; - - year= (asn1_string[0]-'0')*10+(asn1_string[1]-'0'); - if(year < 50) - year+=100; - - month= (asn1_string[2]-'0')*10+(asn1_string[3]-'0'); - if((month > 12) || (month < 1)) - return 3; - - day= (asn1_string[4]-'0')*10+(asn1_string[5]-'0'); - hour= (asn1_string[6]-'0')*10+(asn1_string[7]-'0'); - minute= (asn1_string[8]-'0')*10+(asn1_string[9]-'0'); - - if((asn1_string[10] >= '0') && (asn1_string[10] <= '9') && - (asn1_string[11] >= '0') && (asn1_string[11] <= '9')) - second= (asn1_string[10]-'0')*10+(asn1_string[11]-'0'); - - infof(data, - "%s%04d-%02d-%02d %02d:%02d:%02d %s\n", - prefix, year+1900, month, day, hour, minute, second, (gmt?"GMT":"")); - - return 0; -} - -#endif - -/* ====================================================== */ -#ifdef USE_SSLEAY - -/* - * Match a hostname against a wildcard pattern. - * E.g. - * "foo.host.com" matches "*.host.com". - * - * We are a bit more liberal than RFC2818 describes in that we - * accept multiple "*" in pattern (similar to what some other browsers do). - * E.g. - * "abc.def.domain.com" should strickly not match "*.domain.com", but we - * don't consider "." to be important in CERT checking. - */ -#define HOST_NOMATCH 0 -#define HOST_MATCH 1 - -static int hostmatch(const char *hostname, const char *pattern) -{ - while (1) { - int c = *pattern++; - - if (c == '\0') - return (*hostname ? HOST_NOMATCH : HOST_MATCH); - - if (c == '*') { - c = *pattern; - if (c == '\0') /* "*\0" matches anything remaining */ - return HOST_MATCH; - - while (*hostname) { - /* The only recursive function in libcurl! */ - if (hostmatch(hostname++,pattern) == HOST_MATCH) - return HOST_MATCH; - } - return HOST_NOMATCH; - } - - if (toupper(c) != toupper(*hostname++)) - return HOST_NOMATCH; - } -} - -static int -cert_hostcheck(const char *match_pattern, const char *hostname) -{ - if (!match_pattern || !*match_pattern || - !hostname || !*hostname) /* sanity check */ - return 0; - - if(curl_strequal(hostname,match_pattern)) /* trivial case */ - return 1; - - if (hostmatch(hostname,match_pattern) == HOST_MATCH) - return 1; - return 0; -} - -/* Quote from RFC2818 section 3.1 "Server Identity" - - If a subjectAltName extension of type dNSName is present, that MUST - be used as the identity. Otherwise, the (most specific) Common Name - field in the Subject field of the certificate MUST be used. Although - the use of the Common Name is existing practice, it is deprecated and - Certification Authorities are encouraged to use the dNSName instead. - - Matching is performed using the matching rules specified by - [RFC2459]. If more than one identity of a given type is present in - the certificate (e.g., more than one dNSName name, a match in any one - of the set is considered acceptable.) Names may contain the wildcard - character * which is considered to match any single domain name - component or component fragment. E.g., *.a.com matches foo.a.com but - not bar.foo.a.com. f*.com matches foo.com but not bar.com. - - In some cases, the URI is specified as an IP address rather than a - hostname. In this case, the iPAddress subjectAltName must be present - in the certificate and must exactly match the IP in the URI. - -*/ -static CURLcode verifyhost(struct connectdata *conn, - X509 *server_cert) -{ - bool matched = FALSE; /* no alternative match yet */ - int target = GEN_DNS; /* target type, GEN_DNS or GEN_IPADD */ - int addrlen = 0; - struct SessionHandle *data = conn->data; - STACK_OF(GENERAL_NAME) *altnames; -#ifdef ENABLE_IPV6 - struct in6_addr addr; -#else - struct in_addr addr; -#endif - -#ifdef ENABLE_IPV6 - if(conn->bits.ipv6_ip && - Curl_inet_pton(AF_INET6, conn->host.name, &addr)) { - target = GEN_IPADD; - addrlen = sizeof(struct in6_addr); - } - else -#endif - if(Curl_inet_pton(AF_INET, conn->host.name, &addr)) { - target = GEN_IPADD; - addrlen = sizeof(struct in_addr); - } - - /* get a "list" of alternative names */ - altnames = X509_get_ext_d2i(server_cert, NID_subject_alt_name, NULL, NULL); - - if(altnames) { - int numalts; - int i; - - /* get amount of alternatives, RFC2459 claims there MUST be at least - one, but we don't depend on it... */ - numalts = sk_GENERAL_NAME_num(altnames); - - /* loop through all alternatives while none has matched */ - for (i=0; (i<numalts) && !matched; i++) { - /* get a handle to alternative name number i */ - const GENERAL_NAME *check = sk_GENERAL_NAME_value(altnames, i); - - /* only check alternatives of the same type the target is */ - if(check->type == target) { - /* get data and length */ - const char *altptr = (char *)ASN1_STRING_data(check->d.ia5); - int altlen; - - switch(target) { - case GEN_DNS: /* name/pattern comparison */ - /* The OpenSSL man page explicitly says: "In general it cannot be - assumed that the data returned by ASN1_STRING_data() is null - terminated or does not contain embedded nulls." But also that - "The actual format of the data will depend on the actual string - type itself: for example for and IA5String the data will be ASCII" - - Gisle researched the OpenSSL sources: - "I checked the 0.9.6 and 0.9.8 sources before my patch and - it always 0-terminates an IA5String." - */ - if (cert_hostcheck(altptr, conn->host.name)) - matched = TRUE; - break; - - case GEN_IPADD: /* IP address comparison */ - /* compare alternative IP address if the data chunk is the same size - our server IP address is */ - altlen = ASN1_STRING_length(check->d.ia5); - if((altlen == addrlen) && !memcmp(altptr, &addr, altlen)) - matched = TRUE; - break; - } - } - } - GENERAL_NAMES_free(altnames); - } - - if(matched) - /* an alternative name matched the server hostname */ - infof(data, "\t subjectAltName: %s matched\n", conn->host.dispname); - else { - /* we have to look to the last occurence of a commonName in the - distinguished one to get the most significant one. */ - int j,i=-1 ; - -/* The following is done because of a bug in 0.9.6b */ - - unsigned char *nulstr = (unsigned char *)""; - unsigned char *peer_CN = nulstr; - - X509_NAME *name = X509_get_subject_name(server_cert) ; - if (name) - while ((j=X509_NAME_get_index_by_NID(name,NID_commonName,i))>=0) - i=j; - - /* we have the name entry and we will now convert this to a string - that we can use for comparison. Doing this we support BMPstring, - UTF8 etc. */ - - if (i>=0) { - ASN1_STRING *tmp = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name,i)); - - /* In OpenSSL 0.9.7d and earlier, ASN1_STRING_to_UTF8 fails if the input - is already UTF-8 encoded. We check for this case and copy the raw - string manually to avoid the problem. This code can be made - conditional in the future when OpenSSL has been fixed. Work-around - brought by Alexis S. L. Carvalho. */ - if (tmp && ASN1_STRING_type(tmp) == V_ASN1_UTF8STRING) { - j = ASN1_STRING_length(tmp); - if (j >= 0) { - peer_CN = OPENSSL_malloc(j+1); - if (peer_CN) { - memcpy(peer_CN, ASN1_STRING_data(tmp), j); - peer_CN[j] = '\0'; - } - } - } - else /* not a UTF8 name */ - j = ASN1_STRING_to_UTF8(&peer_CN, tmp); - } - - if (peer_CN == nulstr) - peer_CN = NULL; - - if (!peer_CN) { - if(data->set.ssl.verifyhost > 1) { - failf(data, - "SSL: unable to obtain common name from peer certificate"); - return CURLE_SSL_PEER_CERTIFICATE; - } - else { - /* Consider verifyhost == 1 as an "OK" for a missing CN field, but we - output a note about the situation */ - infof(data, "\t common name: WARNING couldn't obtain\n"); - } - } - else if(!cert_hostcheck((const char *)peer_CN, conn->host.name)) { - if(data->set.ssl.verifyhost > 1) { - failf(data, "SSL: certificate subject name '%s' does not match " - "target host name '%s'", peer_CN, conn->host.dispname); - OPENSSL_free(peer_CN); - return CURLE_SSL_PEER_CERTIFICATE ; - } - else - infof(data, "\t common name: %s (does not match '%s')\n", - peer_CN, conn->host.dispname); - } - else { - infof(data, "\t common name: %s (matched)\n", peer_CN); - OPENSSL_free(peer_CN); - } - } - return CURLE_OK; -} -#endif - -/* The SSL_CTRL_SET_MSG_CALLBACK doesn't exist in ancient OpenSSL versions - and thus this cannot be done there. */ -#ifdef SSL_CTRL_SET_MSG_CALLBACK - -static const char *ssl_msg_type(int ssl_ver, int msg) -{ - if (ssl_ver == SSL2_VERSION_MAJOR) { - switch (msg) { - case SSL2_MT_ERROR: - return "Error"; - case SSL2_MT_CLIENT_HELLO: - return "Client hello"; - case SSL2_MT_CLIENT_MASTER_KEY: - return "Client key"; - case SSL2_MT_CLIENT_FINISHED: - return "Client finished"; - case SSL2_MT_SERVER_HELLO: - return "Server hello"; - case SSL2_MT_SERVER_VERIFY: - return "Server verify"; - case SSL2_MT_SERVER_FINISHED: - return "Server finished"; - case SSL2_MT_REQUEST_CERTIFICATE: - return "Request CERT"; - case SSL2_MT_CLIENT_CERTIFICATE: - return "Client CERT"; - } - } - else if (ssl_ver == SSL3_VERSION_MAJOR) { - switch (msg) { - case SSL3_MT_HELLO_REQUEST: - return "Hello request"; - case SSL3_MT_CLIENT_HELLO: - return "Client hello"; - case SSL3_MT_SERVER_HELLO: - return "Server hello"; - case SSL3_MT_CERTIFICATE: - return "CERT"; - case SSL3_MT_SERVER_KEY_EXCHANGE: - return "Server key exchange"; - case SSL3_MT_CLIENT_KEY_EXCHANGE: - return "Client key exchange"; - case SSL3_MT_CERTIFICATE_REQUEST: - return "Request CERT"; - case SSL3_MT_SERVER_DONE: - return "Server finished"; - case SSL3_MT_CERTIFICATE_VERIFY: - return "CERT verify"; - case SSL3_MT_FINISHED: - return "Finished"; - } - } - return "Unknown"; -} - -static const char *tls_rt_type(int type) -{ - return ( - type == SSL3_RT_CHANGE_CIPHER_SPEC ? "TLS change cipher, " : - type == SSL3_RT_ALERT ? "TLS alert, " : - type == SSL3_RT_HANDSHAKE ? "TLS handshake, " : - type == SSL3_RT_APPLICATION_DATA ? "TLS app data, " : - "TLS Unknown, "); -} - - -/* - * Our callback from the SSL/TLS layers. - */ -static void ssl_tls_trace(int direction, int ssl_ver, int content_type, - const void *buf, size_t len, const SSL *ssl, - struct connectdata *conn) -{ - struct SessionHandle *data = conn->data; - const char *msg_name, *tls_rt_name; - char ssl_buf[1024]; - int ver, msg_type, txt_len; - - if (!conn || !conn->data || !conn->data->set.fdebug || - (direction != 0 && direction != 1)) - return; - - data = conn->data; - ssl_ver >>= 8; - ver = (ssl_ver == SSL2_VERSION_MAJOR ? '2' : - ssl_ver == SSL3_VERSION_MAJOR ? '3' : '?'); - - /* SSLv2 doesn't seem to have TLS record-type headers, so OpenSSL - * always pass-up content-type as 0. But the interesting message-type - * is at 'buf[0]'. - */ - if (ssl_ver == SSL3_VERSION_MAJOR && content_type != 0) - tls_rt_name = tls_rt_type(content_type); - else - tls_rt_name = ""; - - msg_type = *(char*)buf; - msg_name = ssl_msg_type(ssl_ver, msg_type); - - txt_len = 1 + snprintf(ssl_buf, sizeof(ssl_buf), "SSLv%c, %s%s (%d):\n", - ver, tls_rt_name, msg_name, msg_type); - Curl_debug(data, CURLINFO_TEXT, ssl_buf, txt_len, NULL); - - Curl_debug(data, (direction == 1) ? CURLINFO_SSL_DATA_OUT : - CURLINFO_SSL_DATA_IN, (char *)buf, len, NULL); - (void) ssl; -} -#endif - -/* ====================================================== */ -CURLcode -Curl_SSLConnect(struct connectdata *conn, - int sockindex) -{ - CURLcode retcode = CURLE_OK; - -#ifdef USE_SSLEAY - struct SessionHandle *data = conn->data; - int err; - long lerr; - int what; - char * str; - SSL_METHOD *req_method; - SSL_SESSION *ssl_sessionid=NULL; - ASN1_TIME *certdate; - curl_socket_t sockfd = conn->sock[sockindex]; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - - /* mark this is being ssl enabled from here on out. */ - connssl->use = TRUE; - - if(!ssl_seeded || data->set.ssl.random_file || data->set.ssl.egdsocket) { - /* Make funny stuff to get random input */ - random_the_seed(data); - - ssl_seeded = TRUE; - } - - /* check to see if we've been told to use an explicit SSL/TLS version */ - switch(data->set.ssl.version) { - default: - case CURL_SSLVERSION_DEFAULT: - /* we try to figure out version */ - req_method = SSLv23_client_method(); - break; - case CURL_SSLVERSION_TLSv1: - req_method = TLSv1_client_method(); - break; - case CURL_SSLVERSION_SSLv2: - req_method = SSLv2_client_method(); - break; - case CURL_SSLVERSION_SSLv3: - req_method = SSLv3_client_method(); - break; - } - - connssl->ctx = SSL_CTX_new(req_method); - - if(!connssl->ctx) { - failf(data, "SSL: couldn't create a context!"); - return CURLE_OUT_OF_MEMORY; - } - -#ifdef SSL_CTRL_SET_MSG_CALLBACK - if (data->set.fdebug) { - SSL_CTX_callback_ctrl(connssl->ctx, SSL_CTRL_SET_MSG_CALLBACK, - ssl_tls_trace); - SSL_CTX_ctrl(connssl->ctx, SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, conn); - } -#endif - - /* OpenSSL contains code to work-around lots of bugs and flaws in various - SSL-implementations. SSL_CTX_set_options() is used to enabled those - work-arounds. The man page for this option states that SSL_OP_ALL enables - ll the work-arounds and that "It is usually safe to use SSL_OP_ALL to - enable the bug workaround options if compatibility with somewhat broken - implementations is desired." - - */ - SSL_CTX_set_options(connssl->ctx, SSL_OP_ALL); - -#if 0 - /* - * Not sure it's needed to tell SSL_connect() that socket is - * non-blocking. It doesn't seem to care, but just return with - * SSL_ERROR_WANT_x. - */ - if (data->state.used_interface == Curl_if_multi) - SSL_CTX_ctrl(connssl->ctx, BIO_C_SET_NBIO, 1, NULL); -#endif - - if(data->set.cert) { - if(!cert_stuff(conn, - connssl->ctx, - data->set.cert, - data->set.cert_type, - data->set.key, - data->set.key_type)) { - /* failf() is already done in cert_stuff() */ - return CURLE_SSL_CERTPROBLEM; - } - } - - if(data->set.ssl.cipher_list) { - if(!SSL_CTX_set_cipher_list(connssl->ctx, - data->set.ssl.cipher_list)) { - failf(data, "failed setting cipher list"); - return CURLE_SSL_CIPHER; - } - } - - if (data->set.ssl.CAfile || data->set.ssl.CApath) { - /* tell SSL where to find CA certificates that are used to verify - the servers certificate. */ - if (!SSL_CTX_load_verify_locations(connssl->ctx, data->set.ssl.CAfile, - data->set.ssl.CApath)) { - if (data->set.ssl.verifypeer) { - /* Fail if we insist on successfully verifying the server. */ - failf(data,"error setting certificate verify locations:\n" - " CAfile: %s\n CApath: %s\n", - data->set.ssl.CAfile ? data->set.ssl.CAfile : "none", - data->set.ssl.CApath ? data->set.ssl.CApath : "none"); - return CURLE_SSL_CACERT; - } - else { - /* Just continue with a warning if no strict certificate verification - is required. */ - infof(data, "error setting certificate verify locations," - " continuing anyway:\n"); - } - } - else { - /* Everything is fine. */ - infof(data, "successfully set certificate verify locations:\n"); - } - infof(data, - " CAfile: %s\n" - " CApath: %s\n", - data->set.ssl.CAfile ? data->set.ssl.CAfile : "none", - data->set.ssl.CApath ? data->set.ssl.CApath : "none"); - } - /* SSL always tries to verify the peer, this only says whether it should - * fail to connect if the verification fails, or if it should continue - * anyway. In the latter case the result of the verification is checked with - * SSL_get_verify_result() below. */ - SSL_CTX_set_verify(connssl->ctx, - data->set.ssl.verifypeer?SSL_VERIFY_PEER:SSL_VERIFY_NONE, - cert_verify_callback); - - /* give application a chance to interfere with SSL set up. */ - if(data->set.ssl.fsslctx) { - retcode = (*data->set.ssl.fsslctx)(data, connssl->ctx, - data->set.ssl.fsslctxp); - if(retcode) { - failf(data,"error signaled by ssl ctx callback"); - return retcode; - } - } - - /* Lets make an SSL structure */ - connssl->handle = SSL_new(connssl->ctx); - SSL_set_connect_state(connssl->handle); - - connssl->server_cert = 0x0; - - if(!conn->bits.reuse) { - /* We're not re-using a connection, check if there's a cached ID we - can/should use here! */ - if(!Get_SSL_Session(conn, &ssl_sessionid)) { - /* we got a session id, use it! */ - SSL_set_session(connssl->handle, ssl_sessionid); - /* Informational message */ - infof (data, "SSL re-using session ID\n"); - } - } - - /* pass the raw socket into the SSL layers */ - SSL_set_fd(connssl->handle, sockfd); - - while(1) { - fd_set writefd; - fd_set readfd; - struct timeval interval; - long timeout_ms; - - /* Find out if any timeout is set. If not, use 300 seconds. - Otherwise, figure out the most strict timeout of the two possible one - and then how much time that has elapsed to know how much time we - allow for the connect call */ - if(data->set.timeout || data->set.connecttimeout) { - long has_passed; - - /* Evaluate in milliseconds how much time that has passed */ - has_passed = Curl_tvdiff(Curl_tvnow(), data->progress.start); - - /* get the most strict timeout of the ones converted to milliseconds */ - if(data->set.timeout && - (data->set.timeout>data->set.connecttimeout)) - timeout_ms = data->set.timeout*1000; - else - timeout_ms = data->set.connecttimeout*1000; - - /* subtract the passed time */ - timeout_ms -= has_passed; - - if(timeout_ms < 0) { - /* a precaution, no need to continue if time already is up */ - failf(data, "SSL connection timeout"); - return CURLE_OPERATION_TIMEOUTED; - } - } - else - /* no particular time-out has been set */ - timeout_ms= DEFAULT_CONNECT_TIMEOUT; - - - FD_ZERO(&writefd); - FD_ZERO(&readfd); - - err = SSL_connect(connssl->handle); - - /* 1 is fine - 0 is "not successful but was shut down controlled" - <0 is "handshake was not successful, because a fatal error occurred" */ - if(1 != err) { - int detail = SSL_get_error(connssl->handle, err); - - if(SSL_ERROR_WANT_READ == detail) - FD_SET(sockfd, &readfd); - else if(SSL_ERROR_WANT_WRITE == detail) - FD_SET(sockfd, &writefd); - else { - /* untreated error */ - unsigned long errdetail; - char error_buffer[120]; /* OpenSSL documents that this must be at least - 120 bytes long. */ - CURLcode rc; - const char *cert_problem = NULL; - - errdetail = ERR_get_error(); /* Gets the earliest error code from the - thread's error queue and removes the - entry. */ - - switch(errdetail) { - case 0x1407E086: - /* 1407E086: - SSL routines: - SSL2_SET_CERTIFICATE: - certificate verify failed */ - /* fall-through */ - case 0x14090086: - /* 14090086: - SSL routines: - SSL3_GET_SERVER_CERTIFICATE: - certificate verify failed */ - cert_problem = "SSL certificate problem, verify that the CA cert is" - " OK. Details:\n"; - rc = CURLE_SSL_CACERT; - break; - default: - rc = CURLE_SSL_CONNECT_ERROR; - break; - } - - /* detail is already set to the SSL error above */ - - /* If we e.g. use SSLv2 request-method and the server doesn't like us - * (RST connection etc.), OpenSSL gives no explanation whatsoever and - * the SO_ERROR is also lost. - */ - if (CURLE_SSL_CONNECT_ERROR == rc && errdetail == 0) { - failf(data, "Unknown SSL protocol error in connection to %s:%d ", - conn->host.name, conn->port); - return rc; - } - /* Could be a CERT problem */ - -#ifdef HAVE_ERR_ERROR_STRING_N - /* OpenSSL 0.9.6 and later has a function named - ERRO_error_string_n() that takes the size of the buffer as a - third argument */ - ERR_error_string_n(errdetail, error_buffer, sizeof(error_buffer)); -#else - ERR_error_string(errdetail, error_buffer); -#endif - failf(data, "%s%s", cert_problem ? cert_problem : "", error_buffer); - return rc; - } - } - else - /* we have been connected fine, get out of the connect loop */ - break; - - interval.tv_sec = (int)(timeout_ms/1000); - timeout_ms -= interval.tv_sec*1000; - - interval.tv_usec = timeout_ms*1000; - - while(1) { - what = select(sockfd+1, &readfd, &writefd, NULL, &interval); - if(what > 0) - /* reabable or writable, go loop in the outer loop */ - break; - else if(0 == what) { - /* timeout */ - failf(data, "SSL connection timeout"); - return CURLE_OPERATION_TIMEDOUT; - } - else { -#if !defined(WIN32) && defined(EINTR) - /* For platforms without EINTR all errnos are bad */ - if (errno == EINTR) - continue; /* retry the select() */ -#endif - /* anything other than the unimportant EINTR is fatally bad */ - failf(data, "select on SSL socket, errno: %d", Curl_ourerrno()); - return CURLE_SSL_CONNECT_ERROR; - } - } /* while()-loop for the select() */ - } /* while()-loop for the SSL_connect() */ - - /* Informational message */ - infof (data, "SSL connection using %s\n", - SSL_get_cipher(connssl->handle)); - - if(!ssl_sessionid) { - /* Since this is not a cached session ID, then we want to stach this one - in the cache! */ - Store_SSL_Session(conn, connssl); - } - - - /* Get server's certificate (note: beware of dynamic allocation) - opt */ - /* major serious hack alert -- we should check certificates - * to authenticate the server; otherwise we risk man-in-the-middle - * attack - */ - - connssl->server_cert = SSL_get_peer_certificate(connssl->handle); - if(!connssl->server_cert) { - failf(data, "SSL: couldn't get peer certificate!"); - return CURLE_SSL_PEER_CERTIFICATE; - } - infof (data, "Server certificate:\n"); - - str = X509_NAME_oneline(X509_get_subject_name(connssl->server_cert), - NULL, 0); - if(!str) { - failf(data, "SSL: couldn't get X509-subject!"); - X509_free(connssl->server_cert); - return CURLE_SSL_CONNECT_ERROR; - } - infof(data, "\t subject: %s\n", str); - CRYPTO_free(str); - - certdate = X509_get_notBefore(connssl->server_cert); - Curl_ASN1_UTCTIME_output(conn, "\t start date: ", certdate); - - certdate = X509_get_notAfter(connssl->server_cert); - Curl_ASN1_UTCTIME_output(conn, "\t expire date: ", certdate); - - if(data->set.ssl.verifyhost) { - retcode = verifyhost(conn, connssl->server_cert); - if(retcode) { - X509_free(connssl->server_cert); - return retcode; - } - } - - str = X509_NAME_oneline(X509_get_issuer_name(connssl->server_cert), - NULL, 0); - if(!str) { - failf(data, "SSL: couldn't get X509-issuer name!"); - retcode = CURLE_SSL_CONNECT_ERROR; - } - else { - infof(data, "\t issuer: %s\n", str); - CRYPTO_free(str); - - /* We could do all sorts of certificate verification stuff here before - deallocating the certificate. */ - - lerr = data->set.ssl.certverifyresult= - SSL_get_verify_result(connssl->handle); - if(data->set.ssl.certverifyresult != X509_V_OK) { - if(data->set.ssl.verifypeer) { - /* We probably never reach this, because SSL_connect() will fail - and we return earlyer if verifypeer is set? */ - failf(data, "SSL certificate verify result: %s (%ld)", - X509_verify_cert_error_string(lerr), lerr); - retcode = CURLE_SSL_PEER_CERTIFICATE; - } - else - infof(data, "SSL certificate verify result: %s (%ld)," - " continuing anyway.\n", - X509_verify_cert_error_string(err), lerr); - } - else - infof(data, "SSL certificate verify ok.\n"); - } - - X509_free(connssl->server_cert); -#else /* USE_SSLEAY */ - (void)conn; - (void)sockindex; -#endif - return retcode; -} diff --git a/Source/CTest/Curl/ssluse.h b/Source/CTest/Curl/ssluse.h deleted file mode 100644 index 886d2ca..0000000 --- a/Source/CTest/Curl/ssluse.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef __SSLUSE_H -#define __SSLUSE_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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 "urldata.h" -CURLcode Curl_SSLConnect(struct connectdata *conn, int sockindex); - -void Curl_SSL_init(void); /* Global SSL init */ -void Curl_SSL_cleanup(void); /* Global SSL cleanup */ - -/* init the SSL session ID cache */ -CURLcode Curl_SSL_InitSessions(struct SessionHandle *, long); -void Curl_SSL_Close(struct connectdata *conn); /* close a SSL connection */ - -/* tell the SSL stuff to close down all open information regarding - connections (and thus session ID caching etc) */ -int Curl_SSL_Close_All(struct SessionHandle *data); -#endif diff --git a/Source/CTest/Curl/strequal.c b/Source/CTest/Curl/strequal.c deleted file mode 100644 index 66e2e4f..0000000 --- a/Source/CTest/Curl/strequal.c +++ /dev/null @@ -1,140 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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 <string.h> -#include <ctype.h> - -#include "strequal.h" - -#ifdef HAVE_STRCASECMP -/* this is for "-ansi -Wall -pedantic" to stop complaining! */ -extern int (strcasecmp)(const char *s1, const char *s2); -extern int (strncasecmp)(const char *s1, const char *s2, size_t n); -#endif - -int curl_strequal(const char *first, const char *second) -{ -#if defined(HAVE_STRCASECMP) - return !(strcasecmp)(first, second); -#elif defined(HAVE_STRICMP) - return !(stricmp)(first, second); -#elif defined(HAVE_STRCMPI) - return !(strcmpi)(first, second); -#else - while (*first && *second) { - if (toupper(*first) != toupper(*second)) { - break; - } - first++; - second++; - } - return toupper(*first) == toupper(*second); -#endif -} - -int curl_strnequal(const char *first, const char *second, size_t max) -{ -#if defined(HAVE_STRCASECMP) - return !strncasecmp(first, second, max); -#elif defined(HAVE_STRICMP) - return !strnicmp(first, second, max); -#elif defined(HAVE_STRCMPI) - return !strncmpi(first, second, max); -#else - while (*first && *second && max) { - if (toupper(*first) != toupper(*second)) { - break; - } - max--; - first++; - second++; - } - if(0 == max) - return 1; /* they are equal this far */ - - return toupper(*first) == toupper(*second); -#endif -} - -/* - * Curl_strcasestr() finds the first occurrence of the substring needle in the - * string haystack. The terminating `\0' characters are not compared. The - * matching is done CASE INSENSITIVE, which thus is the difference between - * this and strstr(). - */ -char *Curl_strcasestr(const char *haystack, const char *needle) -{ - size_t nlen = strlen(needle); - size_t hlen = strlen(haystack); - - while(hlen-- >= nlen) { - if(curl_strnequal(haystack, needle, nlen)) - return (char *)haystack; - haystack++; - } - return NULL; -} - -#ifndef HAVE_STRLCAT -/* - * The strlcat() function appends the NUL-terminated string src to the end - * of dst. It will append at most size - strlen(dst) - 1 bytes, NUL-termi- - * nating the result. - * - * The strlcpy() and strlcat() functions return the total length of the - * string they tried to create. For strlcpy() that means the length of src. - * For strlcat() that means the initial length of dst plus the length of - * src. While this may seem somewhat confusing it was done to make trunca- - * tion detection simple. - * - * - */ -size_t Curl_strlcat(char *dst, const char *src, size_t siz) -{ - char *d = dst; - const char *s = src; - size_t n = siz; - size_t dlen; - - /* Find the end of dst and adjust bytes left but don't go past end */ - while (n-- != 0 && *d != '\0') - d++; - dlen = d - dst; - n = siz - dlen; - - if (n == 0) - return(dlen + strlen(s)); - while (*s != '\0') { - if (n != 1) { - *d++ = *s; - n--; - } - s++; - } - *d = '\0'; - - return(dlen + (s - src)); /* count does not include NUL */ -} -#endif diff --git a/Source/CTest/Curl/strequal.h b/Source/CTest/Curl/strequal.h deleted file mode 100644 index 5865211..0000000 --- a/Source/CTest/Curl/strequal.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef __STREQUAL_H -#define __STREQUAL_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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$ - ***************************************************************************/ - -/* - * These two actually are public functions. - */ -int curl_strequal(const char *first, const char *second); -int curl_strnequal(const char *first, const char *second, size_t max); - -#define strequal(a,b) curl_strequal(a,b) -#define strnequal(a,b,c) curl_strnequal(a,b,c) - -/* checkprefix() is a shorter version of the above, used when the first - argument is zero-byte terminated */ -#define checkprefix(a,b) strnequal(a,b,strlen(a)) - -/* case insensitive strstr() */ -char *Curl_strcasestr(const char *haystack, const char *needle); - -#ifndef HAVE_STRLCAT -#define strlcat(x,y,z) Curl_strlcat(x,y,z) -size_t Curl_strlcat(char *dst, const char *src, size_t siz); -#endif - -#endif diff --git a/Source/CTest/Curl/strerror.c b/Source/CTest/Curl/strerror.c deleted file mode 100644 index ea5bcd8..0000000 --- a/Source/CTest/Curl/strerror.c +++ /dev/null @@ -1,569 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2004, 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. - * - ***************************************************************************/ - -#include "setup.h" - -#include <curl/curl.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> - -#include "strerror.h" - -#define _MPRINTF_REPLACE /* use our functions only */ -#include <curl/mprintf.h> - -#ifdef HAVE_NO_STRERROR_R_DECL -#ifdef HAVE_POSIX_STRERROR_R -/* seen on AIX 5100-02 gcc 2.9 */ -extern int strerror_r(int errnum, char *strerrbuf, size_t buflen); -#else -extern char *strerror_r(int errnum, char *buf, size_t buflen); -#endif -#endif - -const char * -curl_easy_strerror(CURLcode error) -{ - switch (error) { - case CURLE_OK: - return "no error"; - - case CURLE_UNSUPPORTED_PROTOCOL: - return "unsupported protocol"; - - case CURLE_FAILED_INIT: - return "failed init"; - - case CURLE_URL_MALFORMAT: - return "URL using bad/illegal format or missing URL"; - - case CURLE_COULDNT_RESOLVE_PROXY: - return "couldnt resolve proxy"; - - case CURLE_COULDNT_RESOLVE_HOST: - return "couldnt resolve host"; - - case CURLE_COULDNT_CONNECT: - return "couldn't connect"; - - case CURLE_FTP_WEIRD_SERVER_REPLY: - return "FTP: weird server reply"; - - case CURLE_FTP_ACCESS_DENIED: - return "FTP: access denied"; - - case CURLE_FTP_USER_PASSWORD_INCORRECT: - return "FTP: user and/or password incorrect"; - - case CURLE_FTP_WEIRD_PASS_REPLY: - return "FTP: unknown PASS reply"; - - case CURLE_FTP_WEIRD_USER_REPLY: - return "FTP: unknown USER reply"; - - case CURLE_FTP_WEIRD_PASV_REPLY: - return "FTP: unknown PASV reply"; - - case CURLE_FTP_WEIRD_227_FORMAT: - return "FTP: unknown 227 response format"; - - case CURLE_FTP_CANT_GET_HOST: - return "FTP: can't figure out the host in the PASV response"; - - case CURLE_FTP_CANT_RECONNECT: - return "FTP: can't connect to server the response code is unknown"; - - case CURLE_FTP_COULDNT_SET_BINARY: - return "FTP: couldn't set binary mode"; - - case CURLE_PARTIAL_FILE: - return "Transferred a partial file"; - - case CURLE_FTP_COULDNT_RETR_FILE: - return "FTP: couldn't retrieve (RETR failed) the specified file"; - - case CURLE_FTP_WRITE_ERROR: - return "FTP: the post-transfer acknowledge response was not OK"; - - case CURLE_FTP_QUOTE_ERROR: - return "FTP: a quote command returned error"; - - case CURLE_HTTP_RETURNED_ERROR: - return "HTTP response code said error"; - - case CURLE_WRITE_ERROR: - return "failed writing received data to disk/application"; - - case CURLE_FTP_COULDNT_STOR_FILE: - return "failed FTP upload (the STOR command)"; - - case CURLE_READ_ERROR: - return "failed to open/read local data from file/application"; - - case CURLE_OUT_OF_MEMORY: - return "out of memory"; - - case CURLE_OPERATION_TIMEOUTED: - return "a timeout was reached"; - - case CURLE_FTP_COULDNT_SET_ASCII: - return "FTP could not set ASCII mode (TYPE A)"; - - case CURLE_FTP_PORT_FAILED: - return "FTP command PORT failed"; - - case CURLE_FTP_COULDNT_USE_REST: - return "FTP command REST failed"; - - case CURLE_FTP_COULDNT_GET_SIZE: - return "FTP command SIZE failed"; - - case CURLE_HTTP_RANGE_ERROR: - return "a range was requested but the server did not deliver it"; - - case CURLE_HTTP_POST_ERROR: - return "internal problem setting up the POST"; - - case CURLE_SSL_CONNECT_ERROR: - return "SSL connect error"; - - case CURLE_FTP_BAD_DOWNLOAD_RESUME: - return "couldn't resume FTP download"; - - case CURLE_FILE_COULDNT_READ_FILE: - return "couldn't read a file:// file"; - - case CURLE_LDAP_CANNOT_BIND: - return "LDAP: cannot bind"; - - case CURLE_LDAP_SEARCH_FAILED: - return "LDAP: search failed"; - - case CURLE_LIBRARY_NOT_FOUND: - return "a required shared library was not found"; - - case CURLE_FUNCTION_NOT_FOUND: - return "a required function in the shared library was not found"; - - case CURLE_ABORTED_BY_CALLBACK: - return "the operation was aborted by an application callback"; - - case CURLE_BAD_FUNCTION_ARGUMENT: - return "a libcurl function was given a bad argument"; - - case CURLE_INTERFACE_FAILED: - return "failed binding local connection end"; - - case CURLE_TOO_MANY_REDIRECTS : - return "number of redirects hit maximum amount"; - - case CURLE_UNKNOWN_TELNET_OPTION: - return "User specified an unknown option"; - - case CURLE_TELNET_OPTION_SYNTAX : - return "Malformed telnet option"; - - case CURLE_SSL_PEER_CERTIFICATE: - return "SSL peer certificate was not ok"; - - case CURLE_GOT_NOTHING: - return "server returned nothing (no headers, no data)"; - - case CURLE_SSL_ENGINE_NOTFOUND: - return "SSL crypto engine not found"; - - case CURLE_SSL_ENGINE_SETFAILED: - return "can not set SSL crypto engine as default"; - - case CURLE_SEND_ERROR: - return "failed sending data to the peer"; - - case CURLE_RECV_ERROR: - return "failure when receiving data from the peer"; - - case CURLE_SHARE_IN_USE: - return "share is already in use"; - - case CURLE_SSL_CERTPROBLEM: - return "problem with the local SSL certificate"; - - case CURLE_SSL_CIPHER: - return "couldn't use specified SSL cipher"; - - case CURLE_SSL_CACERT: - return "problem with the SSL CA cert (path? access rights?)"; - - case CURLE_BAD_CONTENT_ENCODING: - return "Unrecognized HTTP Content-Encoding"; - - case CURLE_LDAP_INVALID_URL: - return "Invalid LDAP URL"; - - case CURLE_FILESIZE_EXCEEDED: - return "Maximum file size exceeded"; - - case CURLE_FTP_SSL_FAILED: - return "Requested FTP SSL level failed"; - - case CURLE_URL_MALFORMAT_USER: /* not used by current libcurl */ - case CURLE_MALFORMAT_USER: /* not used by current libcurl */ - case CURLE_BAD_CALLING_ORDER: /* not used by current libcurl */ - case CURLE_BAD_PASSWORD_ENTERED:/* not used by current libcurl */ - case CURLE_OBSOLETE: /* not used by current libcurl */ - case CURL_LAST: - break; - } - /* - * By using a switch, gcc -Wall will complain about enum values - * which do not appear, helping keep this function up-to-date. - * By using gcc -Wall -Werror, you can't forget. - * - * A table would not have the same benefit. Most compilers will - * generate code very similar to a table in any case, so there - * is little performance gain from a table. And something is broken - * for the user's application, anyways, so does it matter how fast - * it _doesn't_ work? - * - * The line number for the error will be near this comment, which - * is why it is here, and not at the start of the switch. - */ - return "unknown error"; -} - -const char * -curl_multi_strerror(CURLMcode error) -{ - switch (error) { - case CURLM_CALL_MULTI_PERFORM: - return "please call curl_multi_perform() soon"; - - case CURLM_OK: - return "no error"; - - case CURLM_BAD_HANDLE: - return "invalid multi handle"; - - case CURLM_BAD_EASY_HANDLE: - return "invalid easy handle"; - - case CURLM_OUT_OF_MEMORY: - return "out of memory"; - - case CURLM_INTERNAL_ERROR: - return "internal error"; - - case CURLM_LAST: - break; - } - - return "unknown error"; -} - -const char * -curl_share_strerror(CURLSHcode error) -{ - switch (error) { - case CURLSHE_OK: - return "no error"; - - case CURLSHE_BAD_OPTION: - return "unknown share option"; - - case CURLSHE_IN_USE: - return "share currently in use"; - - case CURLSHE_INVALID: - return "invalid share handle"; - - case CURLSHE_NOMEM: - return "out of memory"; - - case CURLSHE_LAST: - break; - } - - return "CURLSH unknown"; -} - -#if defined(WIN32) && !defined(__CYGWIN__) - -/* This function handles most / all (?) Winsock errors cURL is able to produce. - */ -static const char * -get_winsock_error (int err, char *buf, size_t len) -{ - char *p; - - switch (err) { - case WSAEINTR: - p = "Call interrupted."; - break; - case WSAEBADF: - p = "Bad file"; - break; - case WSAEACCES: - p = "Bad access"; - break; - case WSAEFAULT: - p = "Bad argument"; - break; - case WSAEINVAL: - p = "Invalid arguments"; - break; - case WSAEMFILE: - p = "Out of file descriptors"; - break; - case WSAEWOULDBLOCK: - p = "Call would block"; - break; - case WSAEINPROGRESS: - case WSAEALREADY: - p = "Blocking call in progress"; - break; - case WSAENOTSOCK: - p = "Descriptor is not a socket."; - break; - case WSAEDESTADDRREQ: - p = "Need destination address"; - break; - case WSAEMSGSIZE: - p = "Bad message size"; - break; - case WSAEPROTOTYPE: - p = "Bad protocol"; - break; - case WSAENOPROTOOPT: - p = "Protocol option is unsupported"; - break; - case WSAEPROTONOSUPPORT: - p = "Protocol is unsupported"; - break; - case WSAESOCKTNOSUPPORT: - p = "Socket is unsupported"; - break; - case WSAEOPNOTSUPP: - p = "Operation not supported"; - break; - case WSAEAFNOSUPPORT: - p = "Address family not supported"; - break; - case WSAEPFNOSUPPORT: - p = "Protocol family not supported"; - break; - case WSAEADDRINUSE: - p = "Address already in use"; - break; - case WSAEADDRNOTAVAIL: - p = "Address not available"; - break; - case WSAENETDOWN: - p = "Network down"; - break; - case WSAENETUNREACH: - p = "Network unreachable"; - break; - case WSAENETRESET: - p = "Network has been reset"; - break; - case WSAECONNABORTED: - p = "Connection was aborted"; - break; - case WSAECONNRESET: - p = "Connection was reset"; - break; - case WSAENOBUFS: - p = "No buffer space"; - break; - case WSAEISCONN: - p = "Socket is already connected"; - break; - case WSAENOTCONN: - p = "Socket is not connected"; - break; - case WSAESHUTDOWN: - p = "Socket has been shut down"; - break; - case WSAETOOMANYREFS: - p = "Too many references"; - break; - case WSAETIMEDOUT: - p = "Timed out"; - break; - case WSAECONNREFUSED: - p = "Connection refused"; - break; - case WSAELOOP: - p = "Loop??"; - break; - case WSAENAMETOOLONG: - p = "Name too long"; - break; - case WSAEHOSTDOWN: - p = "Host down"; - break; - case WSAEHOSTUNREACH: - p = "Host unreachable"; - break; - case WSAENOTEMPTY: - p = "Not empty"; - break; - case WSAEPROCLIM: - p = "Process limit reached"; - break; - case WSAEUSERS: - p = "Too many users"; - break; - case WSAEDQUOT: - p = "Bad quota"; - break; - case WSAESTALE: - p = "Something is stale"; - break; - case WSAEREMOTE: - p = "Remote error"; - break; - case WSAEDISCON: - p = "Disconnected"; - break; - - /* Extended Winsock errors */ - case WSASYSNOTREADY: - p = "Winsock library is not ready"; - break; - case WSANOTINITIALISED: - p = "Winsock library not initalised"; - break; - case WSAVERNOTSUPPORTED: - p = "Winsock version not supported."; - break; - - /* getXbyY() errors (already handled in herrmsg): - * Authoritative Answer: Host not found */ - case WSAHOST_NOT_FOUND: - p = "Host not found"; - break; - - /* Non-Authoritative: Host not found, or SERVERFAIL */ - case WSATRY_AGAIN: - p = "Host not found, try again"; - break; - - /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */ - case WSANO_RECOVERY: - p = "Unrecoverable error in call to nameserver"; - break; - - /* Valid name, no data record of requested type */ - case WSANO_DATA: - p = "No data record of requested type"; - break; - - default: - return NULL; - } - strncpy (buf, p, len); - buf [len-1] = '\0'; - return buf; -} -#endif /* WIN32 && !__CYGWIN__ */ - -/* - * Our thread-safe and smart strerror() replacement. - * - * The 'err' argument passed in to this function MUST be a true errno number - * as reported on this system. We do no range checking on the number before - * we pass it to the "number-to-message" convertion function and there might - * be systems that don't do proper range checking in there themselves. - * - * We don't do range checking (on systems other than Windows) since there is - * no good reliable and portable way to do it. - */ -const char *Curl_strerror(struct connectdata *conn, int err) -{ - char *buf, *p; - size_t max; - - curlassert(conn); - curlassert(err >= 0); - - buf = conn->syserr_buf; - max = sizeof(conn->syserr_buf)-1; - *buf = '\0'; - -#if defined(WIN32) && !defined(__CYGWIN__) - /* 'sys_nerr' is the maximum errno number, it is not widely portable */ - if (err >= 0 && err < sys_nerr) - strncpy(buf, strerror(err), max); - else { - if (!get_winsock_error (err, buf, max) && - !FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, - LANG_NEUTRAL, buf, max, NULL)) - snprintf(buf, max, "Unknown error %d (%#x)", err, err); - } -#else /* not native Windows coming up */ - - /* These should be atomic and hopefully thread-safe */ -#ifdef HAVE_STRERROR_R - /* There are two different APIs for strerror_r(). The POSIX and the GLIBC - versions. */ -#ifdef HAVE_POSIX_STRERROR_R - strerror_r(err, buf, max); - /* this may set errno to ERANGE if insufficient storage was supplied via - 'strerrbuf' and 'buflen' to contain the generated message string, or - EINVAL if the value of 'errnum' is not a valid error number.*/ -#else - { - /* HAVE_GLIBC_STRERROR_R */ - char buffer[256]; - char *msg = strerror_r(err, buffer, sizeof(buffer)); - /* this version of strerror_r() only *might* use the buffer we pass to - the function, but it always returns the error message as a pointer, - so we must copy that string unconditionally */ - if ( !msg ) - { - msg = "Unknown System Error"; - } - strncpy(buf, msg, max); - } -#endif /* end of HAVE_GLIBC_STRERROR_R */ -#else /* HAVE_STRERROR_R */ - { - char *msg = strerror(err); - if ( !msg ) - { - msg = "Unknown System Error"; - } - strncpy(buf, msg, max); - } -#endif /* end of HAVE_STRERROR_R */ -#endif /* end of ! Windows */ - - buf[max] = '\0'; /* make sure the string is zero terminated */ - - /* strip trailing '\r\n' or '\n'. */ - if ((p = strrchr(buf,'\n')) != NULL && (p - buf) >= 2) - *p = '\0'; - if ((p = strrchr(buf,'\r')) != NULL && (p - buf) >= 1) - *p = '\0'; - return buf; -} diff --git a/Source/CTest/Curl/strerror.h b/Source/CTest/Curl/strerror.h deleted file mode 100644 index 7d68723..0000000 --- a/Source/CTest/Curl/strerror.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef __CURL_STRERROR_H -#define __CURL_STRERROR_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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 "urldata.h" - -const char *Curl_strerror (struct connectdata *conn, int err); - -#endif diff --git a/Source/CTest/Curl/strtok.c b/Source/CTest/Curl/strtok.c deleted file mode 100644 index 630e4e0..0000000 --- a/Source/CTest/Curl/strtok.c +++ /dev/null @@ -1,68 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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" - -#ifndef HAVE_STRTOK_R -#include <stddef.h> -#include <string.h> - -#include "strtok.h" - -char * -Curl_strtok_r(char *ptr, const char *sep, char **end) -{ - if (!ptr) - /* we got NULL input so then we get our last position instead */ - ptr = *end; - - /* pass all letters that are including in the separator string */ - while (*ptr && strchr(sep, *ptr)) - ++ptr; - - if (*ptr) { - /* so this is where the next piece of string starts */ - char *start = ptr; - - /* set the end pointer to the first byte after the start */ - *end = start + 1; - - /* scan through the string to find where it ends, it ends on a - null byte or a character that exists in the separator string */ - while (**end && !strchr(sep, **end)) - ++*end; - - if (**end) { - /* the end is not a null byte */ - **end = '\0'; /* zero terminate it! */ - ++*end; /* advance the last pointer to beyond the null byte */ - } - - return start; /* return the position where the string starts */ - } - - /* we ended up on a null byte, there are no more strings to find! */ - return NULL; -} - -#endif /* this was only compiled if strtok_r wasn't present */ diff --git a/Source/CTest/Curl/strtok.h b/Source/CTest/Curl/strtok.h deleted file mode 100644 index cf9fac8..0000000 --- a/Source/CTest/Curl/strtok.h +++ /dev/null @@ -1,38 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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$ - ***************************************************************************/ - -#ifndef _CURL_STRTOK_R_H -#define _CURL_STRTOK_R_H - -#include "setup.h" -#include <stddef.h> - -#ifndef HAVE_STRTOK_R -char *Curl_strtok_r(char *s, const char *delim, char **last); -#define strtok_r Curl_strtok_r -#else -#include <string.h> -#endif - -#endif - diff --git a/Source/CTest/Curl/strtoofft.c b/Source/CTest/Curl/strtoofft.c deleted file mode 100644 index e2b02c4..0000000 --- a/Source/CTest/Curl/strtoofft.c +++ /dev/null @@ -1,164 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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 "strtoofft.h" - -#ifdef NEED_CURL_STRTOLL -#include <stdlib.h> -#include <ctype.h> -#include <errno.h> - -static int get_char(char c, int base); - -/** - * Emulated version of the strtoll function. This extracts a long long - * value from the given input string and returns it. - */ -curl_off_t -curlx_strtoll(const char *nptr, char **endptr, int base) -{ - char *end; - int is_negative = 0; - int overflow; - int i; - curl_off_t value = 0; - curl_off_t newval; - - /* Skip leading whitespace. */ - end = (char *)nptr; - while (isspace((int)end[0])) { - end++; - } - - /* Handle the sign, if any. */ - if (end[0] == '-') { - is_negative = 1; - end++; - } - else if (end[0] == '+') { - end++; - } - else if (end[0] == '\0') { - /* We had nothing but perhaps some whitespace -- there was no number. */ - if (endptr) { - *endptr = end; - } - return 0; - } - - /* Handle special beginnings, if present and allowed. */ - if (end[0] == '0' && end[1] == 'x') { - if (base == 16 || base == 0) { - end += 2; - base = 16; - } - } - else if (end[0] == '0') { - if (base == 8 || base == 0) { - end++; - base = 8; - } - } - - /* Matching strtol, if the base is 0 and it doesn't look like - * the number is octal or hex, we assume it's base 10. - */ - if (base == 0) { - base = 10; - } - - /* Loop handling digits. */ - value = 0; - overflow = 0; - for (i = get_char(end[0], base); - i != -1; - end++, i = get_char(end[0], base)) { - newval = base * value + i; - if (newval < value) { - /* We've overflowed. */ - overflow = 1; - break; - } - else - value = newval; - } - - if (!overflow) { - if (is_negative) { - /* Fix the sign. */ - value *= -1; - } - } - else { -#ifdef HAVE_LONG_LONG_CONSTANT - if (is_negative) - value = 0x8000000000000000LL; - else - value = 0x7FFFFFFFFFFFFFFFLL; -#else - if (is_negative) - value = 0x8000000000000000L; - else - value = 0x7FFFFFFFFFFFFFFFL; -#endif - - errno = ERANGE; - } - - if (endptr) - *endptr = end; - - return value; -} - -/** - * Returns the value of c in the given base, or -1 if c cannot - * be interpreted properly in that base (i.e., is out of range, - * is a null, etc.). - * - * @param c the character to interpret according to base - * @param base the base in which to interpret c - * - * @return the value of c in base, or -1 if c isn't in range - */ -static int get_char(char c, int base) -{ - int value = -1; - if (c <= '9' && c >= '0') { - value = c - '0'; - } - else if (c <= 'Z' && c >= 'A') { - value = c - 'A' + 10; - } - else if (c <= 'z' && c >= 'a') { - value = c - 'a' + 10; - } - - if (value >= base) { - value = -1; - } - - return value; -} -#endif /* Only present if we need strtoll, but don't have it. */ diff --git a/Source/CTest/Curl/strtoofft.h b/Source/CTest/Curl/strtoofft.h deleted file mode 100644 index 4c5d265..0000000 --- a/Source/CTest/Curl/strtoofft.h +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef _CURL_STRTOOFFT_H -#define _CURL_STRTOOFFT_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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$ - ***************************************************************************/ - -/* - * CAUTION: this header is designed to work when included by the app-side - * as well as the library. Do not mix with library internals! - */ - -#include "setup.h" -#include <stddef.h> -#include <curl/curl.h> /* for the curl_off_t type */ - -/* Determine what type of file offset conversion handling we wish to use. For - * systems with a 32-bit curl_off_t type, we should use strtol. For systems - * with a 64-bit curl_off_t type, we should use strtoll if it exists, and if - * not, should try to emulate its functionality. At any rate, we define - * 'strtoofft' such that it can be used to work with curl_off_t's regardless. - */ -#if SIZEOF_CURL_OFF_T > 4 -#if HAVE_STRTOLL -#define curlx_strtoofft strtoll -#else /* HAVE_STRTOLL */ - -/* For MSVC7 we can use _strtoi64() which seems to be a strtoll() clone */ -#if defined(_MSC_VER) && (_MSC_VER >= 1300) -#define curlx_strtoofft _strtoi64 -#else /* MSVC7 or later */ -curl_off_t curlx_strtoll(const char *nptr, char **endptr, int base); -#define curlx_strtoofft curlx_strtoll -#define NEED_CURL_STRTOLL -#endif /* MSVC7 or later */ - -#endif /* HAVE_STRTOLL */ -#else /* SIZEOF_CURL_OFF_T > 4 */ -/* simply use strtol() to get 32bit numbers */ -#define curlx_strtoofft strtol -#endif - -#endif - diff --git a/Source/CTest/Curl/telnet.c b/Source/CTest/Curl/telnet.c deleted file mode 100644 index 98a1adf..0000000 --- a/Source/CTest/Curl/telnet.c +++ /dev/null @@ -1,1389 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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" - -#ifndef CURL_DISABLE_TELNET -/* -- WIN32 approved -- */ -#include <stdio.h> -#include <string.h> -#include <stdarg.h> -#include <stdlib.h> -#include <ctype.h> -#include <sys/types.h> -#include <sys/stat.h> - -#include <errno.h> - -#if defined(WIN32) -#include <time.h> -#include <io.h> -#else -#ifdef HAVE_SYS_SOCKET_H -#include <sys/socket.h> -#endif -#include <netinet/in.h> -#include <sys/time.h> -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif -#include <netdb.h> -#ifdef HAVE_ARPA_INET_H -#include <arpa/inet.h> -#endif -#ifdef HAVE_NET_IF_H -#include <net/if.h> -#endif -#include <sys/ioctl.h> -#include <signal.h> - -#ifdef HAVE_SYS_PARAM_H -#include <sys/param.h> -#endif - -#ifdef HAVE_SYS_SELECT_H -#include <sys/select.h> -#endif - - -#endif - -#include "urldata.h" -#include <curl/curl.h> -#include "transfer.h" -#include "sendf.h" -#include "telnet.h" - -#define _MPRINTF_REPLACE /* use our functions only */ -#include <curl/mprintf.h> - -#define TELOPTS -#define TELCMDS - -#include "arpa_telnet.h" -#include "curl_memory.h" - -/* The last #include file should be: */ -#include "memdebug.h" - -#define SUBBUFSIZE 512 - -#define CURL_SB_CLEAR(x) x->subpointer = x->subbuffer; -#define CURL_SB_TERM(x) { x->subend = x->subpointer; CURL_SB_CLEAR(x); } -#define CURL_SB_ACCUM(x,c) \ - if (x->subpointer < (x->subbuffer+sizeof x->subbuffer)) { \ - *x->subpointer++ = (c); \ - } - -#define CURL_SB_GET(x) ((*x->subpointer++)&0xff) -#define CURL_SB_PEEK(x) ((*x->subpointer)&0xff) -#define CURL_SB_EOF(x) (x->subpointer >= x->subend) -#define CURL_SB_LEN(x) (x->subend - x->subpointer) - -#ifdef WIN32 -typedef FARPROC WSOCK2_FUNC; -static CURLcode check_wsock2 ( struct SessionHandle *data ); -#endif - -static -void telrcv(struct connectdata *, - unsigned char *inbuf, /* Data received from socket */ - ssize_t count); /* Number of bytes received */ - -static void printoption(struct SessionHandle *data, - const char *direction, - int cmd, int option); - -static void negotiate(struct connectdata *); -static void send_negotiation(struct connectdata *, int cmd, int option); -static void set_local_option(struct connectdata *, int cmd, int option); -static void set_remote_option(struct connectdata *, int cmd, int option); - -static void printsub(struct SessionHandle *data, - int direction, unsigned char *pointer, - size_t length); -static void suboption(struct connectdata *); - -/* For negotiation compliant to RFC 1143 */ -#define CURL_NO 0 -#define CURL_YES 1 -#define CURL_WANTYES 2 -#define CURL_WANTNO 3 - -#define CURL_EMPTY 0 -#define CURL_OPPOSITE 1 - -/* - * Telnet receiver states for fsm - */ -typedef enum -{ - CURL_TS_DATA = 0, - CURL_TS_IAC, - CURL_TS_WILL, - CURL_TS_WONT, - CURL_TS_DO, - CURL_TS_DONT, - CURL_TS_CR, - CURL_TS_SB, /* sub-option collection */ - CURL_TS_SE /* looking for sub-option end */ -} TelnetReceive; - -struct TELNET { - int please_negotiate; - int already_negotiated; - int us[256]; - int usq[256]; - int us_preferred[256]; - int him[256]; - int himq[256]; - int him_preferred[256]; - char subopt_ttype[32]; /* Set with suboption TTYPE */ - char subopt_xdisploc[128]; /* Set with suboption XDISPLOC */ - struct curl_slist *telnet_vars; /* Environment variables */ - - /* suboptions */ - char subbuffer[SUBBUFSIZE]; - char *subpointer, *subend; /* buffer for sub-options */ - - TelnetReceive telrcv_state; -}; - -#ifdef WIN32 -static CURLcode -check_wsock2 ( struct SessionHandle *data ) -{ - int err; - WORD wVersionRequested; - WSADATA wsaData; - - curlassert(data); - - /* telnet requires at least WinSock 2.0 so ask for it. */ - wVersionRequested = MAKEWORD(2, 0); - - err = WSAStartup(wVersionRequested, &wsaData); - - /* We must've called this once already, so this call */ - /* should always succeed. But, just in case... */ - if (err != 0) { - failf(data,"WSAStartup failed (%d)",err); - return CURLE_FAILED_INIT; - } - - /* We have to have a WSACleanup call for every successful */ - /* WSAStartup call. */ - WSACleanup(); - - /* Check that our version is supported */ - if (LOBYTE(wsaData.wVersion) != LOBYTE(wVersionRequested) || - HIBYTE(wsaData.wVersion) != HIBYTE(wVersionRequested)) { - /* Our version isn't supported */ - failf(data,"insufficient winsock version to support " - "telnet"); - return CURLE_FAILED_INIT; - } - - /* Our version is supported */ - return CURLE_OK; -} -#endif -static -CURLcode init_telnet(struct connectdata *conn) -{ - struct TELNET *tn; - - tn = (struct TELNET *)calloc(1, sizeof(struct TELNET)); - if(!tn) - return CURLE_OUT_OF_MEMORY; - - conn->proto.telnet = (void *)tn; /* make us known */ - - tn->telrcv_state = CURL_TS_DATA; - - /* Init suboptions */ - CURL_SB_CLEAR(tn); - - /* Set the options we want by default */ - tn->us_preferred[CURL_TELOPT_BINARY] = CURL_YES; - tn->us_preferred[CURL_TELOPT_SGA] = CURL_YES; - tn->him_preferred[CURL_TELOPT_BINARY] = CURL_YES; - tn->him_preferred[CURL_TELOPT_SGA] = CURL_YES; - - return CURLE_OK; -} - -static void negotiate(struct connectdata *conn) -{ - int i; - struct TELNET *tn = (struct TELNET *)conn->proto.telnet; - - for(i = 0;i < CURL_NTELOPTS;i++) - { - if(tn->us_preferred[i] == CURL_YES) - set_local_option(conn, i, CURL_YES); - - if(tn->him_preferred[i] == CURL_YES) - set_remote_option(conn, i, CURL_YES); - } -} - -static void printoption(struct SessionHandle *data, - const char *direction, int cmd, int option) -{ - const char *fmt; - const char *opt; - - if (data->set.verbose) - { - if (cmd == CURL_IAC) - { - if (CURL_TELCMD_OK(option)) - Curl_infof(data, "%s IAC %s\n", direction, CURL_TELCMD(option)); - else - Curl_infof(data, "%s IAC %d\n", direction, option); - } - else - { - fmt = (cmd == CURL_WILL) ? "WILL" : (cmd == CURL_WONT) ? "WONT" : - (cmd == CURL_DO) ? "DO" : (cmd == CURL_DONT) ? "DONT" : 0; - if (fmt) - { - if (CURL_TELOPT_OK(option)) - opt = CURL_TELOPT(option); - else if (option == CURL_TELOPT_EXOPL) - opt = "EXOPL"; - else - opt = NULL; - - if(opt) - Curl_infof(data, "%s %s %s\n", direction, fmt, opt); - else - Curl_infof(data, "%s %s %d\n", direction, fmt, option); - } - else - Curl_infof(data, "%s %d %d\n", direction, cmd, option); - } - } -} - -static void send_negotiation(struct connectdata *conn, int cmd, int option) -{ - unsigned char buf[3]; - - buf[0] = CURL_IAC; - buf[1] = cmd; - buf[2] = option; - - (void)swrite(conn->sock[FIRSTSOCKET], buf, 3); - - printoption(conn->data, "SENT", cmd, option); -} - -static -void set_remote_option(struct connectdata *conn, int option, int newstate) -{ - struct TELNET *tn = (struct TELNET *)conn->proto.telnet; - if(newstate == CURL_YES) - { - switch(tn->him[option]) - { - case CURL_NO: - tn->him[option] = CURL_WANTYES; - send_negotiation(conn, CURL_DO, option); - break; - - case CURL_YES: - /* Already enabled */ - break; - - case CURL_WANTNO: - switch(tn->himq[option]) - { - case CURL_EMPTY: - /* Already negotiating for CURL_YES, queue the request */ - tn->himq[option] = CURL_OPPOSITE; - break; - case CURL_OPPOSITE: - /* Error: already queued an enable request */ - break; - } - break; - - case CURL_WANTYES: - switch(tn->himq[option]) - { - case CURL_EMPTY: - /* Error: already negotiating for enable */ - break; - case CURL_OPPOSITE: - tn->himq[option] = CURL_EMPTY; - break; - } - break; - } - } - else /* NO */ - { - switch(tn->him[option]) - { - case CURL_NO: - /* Already disabled */ - break; - - case CURL_YES: - tn->him[option] = CURL_WANTNO; - send_negotiation(conn, CURL_DONT, option); - break; - - case CURL_WANTNO: - switch(tn->himq[option]) - { - case CURL_EMPTY: - /* Already negotiating for NO */ - break; - case CURL_OPPOSITE: - tn->himq[option] = CURL_EMPTY; - break; - } - break; - - case CURL_WANTYES: - switch(tn->himq[option]) - { - case CURL_EMPTY: - tn->himq[option] = CURL_OPPOSITE; - break; - case CURL_OPPOSITE: - break; - } - break; - } - } -} - -static -void rec_will(struct connectdata *conn, int option) -{ - struct TELNET *tn = (struct TELNET *)conn->proto.telnet; - switch(tn->him[option]) - { - case CURL_NO: - if(tn->him_preferred[option] == CURL_YES) - { - tn->him[option] = CURL_YES; - send_negotiation(conn, CURL_DO, option); - } - else - { - send_negotiation(conn, CURL_DONT, option); - } - break; - - case CURL_YES: - /* Already enabled */ - break; - - case CURL_WANTNO: - switch(tn->himq[option]) - { - case CURL_EMPTY: - /* Error: DONT answered by WILL */ - tn->him[option] = CURL_NO; - break; - case CURL_OPPOSITE: - /* Error: DONT answered by WILL */ - tn->him[option] = CURL_YES; - tn->himq[option] = CURL_EMPTY; - break; - } - break; - - case CURL_WANTYES: - switch(tn->himq[option]) - { - case CURL_EMPTY: - tn->him[option] = CURL_YES; - break; - case CURL_OPPOSITE: - tn->him[option] = CURL_WANTNO; - tn->himq[option] = CURL_EMPTY; - send_negotiation(conn, CURL_DONT, option); - break; - } - break; - } -} - -static -void rec_wont(struct connectdata *conn, int option) -{ - struct TELNET *tn = (struct TELNET *)conn->proto.telnet; - switch(tn->him[option]) - { - case CURL_NO: - /* Already disabled */ - break; - - case CURL_YES: - tn->him[option] = CURL_NO; - send_negotiation(conn, CURL_DONT, option); - break; - - case CURL_WANTNO: - switch(tn->himq[option]) - { - case CURL_EMPTY: - tn->him[option] = CURL_NO; - break; - - case CURL_OPPOSITE: - tn->him[option] = CURL_WANTYES; - tn->himq[option] = CURL_EMPTY; - send_negotiation(conn, CURL_DO, option); - break; - } - break; - - case CURL_WANTYES: - switch(tn->himq[option]) - { - case CURL_EMPTY: - tn->him[option] = CURL_NO; - break; - case CURL_OPPOSITE: - tn->him[option] = CURL_NO; - tn->himq[option] = CURL_EMPTY; - break; - } - break; - } -} - -static void -set_local_option(struct connectdata *conn, int option, int newstate) -{ - struct TELNET *tn = (struct TELNET *)conn->proto.telnet; - if(newstate == CURL_YES) - { - switch(tn->us[option]) - { - case CURL_NO: - tn->us[option] = CURL_WANTYES; - send_negotiation(conn, CURL_WILL, option); - break; - - case CURL_YES: - /* Already enabled */ - break; - - case CURL_WANTNO: - switch(tn->usq[option]) - { - case CURL_EMPTY: - /* Already negotiating for CURL_YES, queue the request */ - tn->usq[option] = CURL_OPPOSITE; - break; - case CURL_OPPOSITE: - /* Error: already queued an enable request */ - break; - } - break; - - case CURL_WANTYES: - switch(tn->usq[option]) - { - case CURL_EMPTY: - /* Error: already negotiating for enable */ - break; - case CURL_OPPOSITE: - tn->usq[option] = CURL_EMPTY; - break; - } - break; - } - } - else /* NO */ - { - switch(tn->us[option]) - { - case CURL_NO: - /* Already disabled */ - break; - - case CURL_YES: - tn->us[option] = CURL_WANTNO; - send_negotiation(conn, CURL_WONT, option); - break; - - case CURL_WANTNO: - switch(tn->usq[option]) - { - case CURL_EMPTY: - /* Already negotiating for NO */ - break; - case CURL_OPPOSITE: - tn->usq[option] = CURL_EMPTY; - break; - } - break; - - case CURL_WANTYES: - switch(tn->usq[option]) - { - case CURL_EMPTY: - tn->usq[option] = CURL_OPPOSITE; - break; - case CURL_OPPOSITE: - break; - } - break; - } - } -} - -static -void rec_do(struct connectdata *conn, int option) -{ - struct TELNET *tn = (struct TELNET *)conn->proto.telnet; - switch(tn->us[option]) - { - case CURL_NO: - if(tn->us_preferred[option] == CURL_YES) - { - tn->us[option] = CURL_YES; - send_negotiation(conn, CURL_WILL, option); - } - else - { - send_negotiation(conn, CURL_WONT, option); - } - break; - - case CURL_YES: - /* Already enabled */ - break; - - case CURL_WANTNO: - switch(tn->usq[option]) - { - case CURL_EMPTY: - /* Error: DONT answered by WILL */ - tn->us[option] = CURL_NO; - break; - case CURL_OPPOSITE: - /* Error: DONT answered by WILL */ - tn->us[option] = CURL_YES; - tn->usq[option] = CURL_EMPTY; - break; - } - break; - - case CURL_WANTYES: - switch(tn->usq[option]) - { - case CURL_EMPTY: - tn->us[option] = CURL_YES; - break; - case CURL_OPPOSITE: - tn->us[option] = CURL_WANTNO; - tn->himq[option] = CURL_EMPTY; - send_negotiation(conn, CURL_WONT, option); - break; - } - break; - } -} - -static -void rec_dont(struct connectdata *conn, int option) -{ - struct TELNET *tn = (struct TELNET *)conn->proto.telnet; - switch(tn->us[option]) - { - case CURL_NO: - /* Already disabled */ - break; - - case CURL_YES: - tn->us[option] = CURL_NO; - send_negotiation(conn, CURL_WONT, option); - break; - - case CURL_WANTNO: - switch(tn->usq[option]) - { - case CURL_EMPTY: - tn->us[option] = CURL_NO; - break; - - case CURL_OPPOSITE: - tn->us[option] = CURL_WANTYES; - tn->usq[option] = CURL_EMPTY; - send_negotiation(conn, CURL_WILL, option); - break; - } - break; - - case CURL_WANTYES: - switch(tn->usq[option]) - { - case CURL_EMPTY: - tn->us[option] = CURL_NO; - break; - case CURL_OPPOSITE: - tn->us[option] = CURL_NO; - tn->usq[option] = CURL_EMPTY; - break; - } - break; - } -} - - -static void printsub(struct SessionHandle *data, - int direction, /* '<' or '>' */ - unsigned char *pointer, /* where suboption data is */ - size_t length) /* length of suboption data */ -{ - unsigned int i = 0; - - if (data->set.verbose) - { - if (direction) - { - Curl_infof(data, "%s IAC SB ", (direction == '<')? "RCVD":"SENT"); - if (length >= 3) - { - int j; - - i = pointer[length-2]; - j = pointer[length-1]; - - if (i != CURL_IAC || j != CURL_SE) - { - Curl_infof(data, "(terminated by "); - if (CURL_TELOPT_OK(i)) - Curl_infof(data, "%s ", CURL_TELOPT(i)); - else if (CURL_TELCMD_OK(i)) - Curl_infof(data, "%s ", CURL_TELCMD(i)); - else - Curl_infof(data, "%d ", i); - if (CURL_TELOPT_OK(j)) - Curl_infof(data, "%s", CURL_TELOPT(j)); - else if (CURL_TELCMD_OK(j)) - Curl_infof(data, "%s", CURL_TELCMD(j)); - else - Curl_infof(data, "%d", j); - Curl_infof(data, ", not IAC SE!) "); - } - } - length -= 2; - } - if (length < 1) - { - Curl_infof(data, "(Empty suboption?)"); - return; - } - - if (CURL_TELOPT_OK(pointer[0])) { - switch(pointer[0]) { - case CURL_TELOPT_TTYPE: - case CURL_TELOPT_XDISPLOC: - case CURL_TELOPT_NEW_ENVIRON: - Curl_infof(data, "%s", CURL_TELOPT(pointer[0])); - break; - default: - Curl_infof(data, "%s (unsupported)", CURL_TELOPT(pointer[0])); - break; - } - } - else - Curl_infof(data, "%d (unknown)", pointer[i]); - - switch(pointer[1]) { - case CURL_TELQUAL_IS: - Curl_infof(data, " IS"); - break; - case CURL_TELQUAL_SEND: - Curl_infof(data, " SEND"); - break; - case CURL_TELQUAL_INFO: - Curl_infof(data, " INFO/REPLY"); - break; - case CURL_TELQUAL_NAME: - Curl_infof(data, " NAME"); - break; - } - - switch(pointer[0]) { - case CURL_TELOPT_TTYPE: - case CURL_TELOPT_XDISPLOC: - pointer[length] = 0; - Curl_infof(data, " \"%s\"", &pointer[2]); - break; - case CURL_TELOPT_NEW_ENVIRON: - if(pointer[1] == CURL_TELQUAL_IS) { - Curl_infof(data, " "); - for(i = 3;i < length;i++) { - switch(pointer[i]) { - case CURL_NEW_ENV_VAR: - Curl_infof(data, ", "); - break; - case CURL_NEW_ENV_VALUE: - Curl_infof(data, " = "); - break; - default: - Curl_infof(data, "%c", pointer[i]); - break; - } - } - } - break; - default: - for (i = 2; i < length; i++) - Curl_infof(data, " %.2x", pointer[i]); - break; - } - - if (direction) - { - Curl_infof(data, "\n"); - } - } -} - -static CURLcode check_telnet_options(struct connectdata *conn) -{ - struct curl_slist *head; - char option_keyword[128]; - char option_arg[256]; - char *buf; - struct SessionHandle *data = conn->data; - struct TELNET *tn = (struct TELNET *)conn->proto.telnet; - - /* Add the user name as an environment variable if it - was given on the command line */ - if(conn->bits.user_passwd) - { - snprintf(option_arg, sizeof(option_arg), "USER,%s", conn->user); - tn->telnet_vars = curl_slist_append(tn->telnet_vars, option_arg); - - tn->us_preferred[CURL_TELOPT_NEW_ENVIRON] = CURL_YES; - } - - for(head = data->set.telnet_options; head; head=head->next) { - if(sscanf(head->data, "%127[^= ]%*[ =]%255s", - option_keyword, option_arg) == 2) { - - /* Terminal type */ - if(curl_strequal(option_keyword, "TTYPE")) { - strncpy(tn->subopt_ttype, option_arg, 31); - tn->subopt_ttype[31] = 0; /* String termination */ - tn->us_preferred[CURL_TELOPT_TTYPE] = CURL_YES; - continue; - } - - /* Display variable */ - if(curl_strequal(option_keyword, "XDISPLOC")) { - strncpy(tn->subopt_xdisploc, option_arg, 127); - tn->subopt_xdisploc[127] = 0; /* String termination */ - tn->us_preferred[CURL_TELOPT_XDISPLOC] = CURL_YES; - continue; - } - - /* Environment variable */ - if(curl_strequal(option_keyword, "NEW_ENV")) { - buf = strdup(option_arg); - if(!buf) - return CURLE_OUT_OF_MEMORY; - tn->telnet_vars = curl_slist_append(tn->telnet_vars, buf); - tn->us_preferred[CURL_TELOPT_NEW_ENVIRON] = CURL_YES; - continue; - } - - failf(data, "Unknown telnet option %s", head->data); - return CURLE_UNKNOWN_TELNET_OPTION; - } else { - failf(data, "Syntax error in telnet option: %s", head->data); - return CURLE_TELNET_OPTION_SYNTAX; - } - } - - return CURLE_OK; -} - -/* - * suboption() - * - * Look at the sub-option buffer, and try to be helpful to the other - * side. - */ - -static void suboption(struct connectdata *conn) -{ - struct curl_slist *v; - unsigned char temp[2048]; - size_t len; - size_t tmplen; - char varname[128]; - char varval[128]; - struct SessionHandle *data = conn->data; - struct TELNET *tn = (struct TELNET *)conn->proto.telnet; - - printsub(data, '<', (unsigned char *)tn->subbuffer, CURL_SB_LEN(tn)+2); - switch (CURL_SB_GET(tn)) { - case CURL_TELOPT_TTYPE: - len = strlen(tn->subopt_ttype) + 4 + 2; - snprintf((char *)temp, sizeof(temp), - "%c%c%c%c%s%c%c", CURL_IAC, CURL_SB, CURL_TELOPT_TTYPE, - CURL_TELQUAL_IS, tn->subopt_ttype, CURL_IAC, CURL_SE); - (void)swrite(conn->sock[FIRSTSOCKET], temp, len); - printsub(data, '>', &temp[2], len-2); - break; - case CURL_TELOPT_XDISPLOC: - len = strlen(tn->subopt_xdisploc) + 4 + 2; - snprintf((char *)temp, sizeof(temp), - "%c%c%c%c%s%c%c", CURL_IAC, CURL_SB, CURL_TELOPT_XDISPLOC, - CURL_TELQUAL_IS, tn->subopt_xdisploc, CURL_IAC, CURL_SE); - (void)swrite(conn->sock[FIRSTSOCKET], temp, len); - printsub(data, '>', &temp[2], len-2); - break; - case CURL_TELOPT_NEW_ENVIRON: - snprintf((char *)temp, sizeof(temp), - "%c%c%c%c", CURL_IAC, CURL_SB, CURL_TELOPT_NEW_ENVIRON, - CURL_TELQUAL_IS); - len = 4; - - for(v = tn->telnet_vars;v;v = v->next) { - tmplen = (strlen(v->data) + 1); - /* Add the variable only if it fits */ - if(len + tmplen < (int)sizeof(temp)-6) { - sscanf(v->data, "%127[^,],%127s", varname, varval); - snprintf((char *)&temp[len], sizeof(temp) - len, - "%c%s%c%s", CURL_NEW_ENV_VAR, varname, - CURL_NEW_ENV_VALUE, varval); - len += tmplen; - } - } - snprintf((char *)&temp[len], sizeof(temp) - len, - "%c%c", CURL_IAC, CURL_SE); - len += 2; - (void)swrite(conn->sock[FIRSTSOCKET], temp, len); - printsub(data, '>', &temp[2], len-2); - break; - } - return; -} - -static -void telrcv(struct connectdata *conn, - unsigned char *inbuf, /* Data received from socket */ - ssize_t count) /* Number of bytes received */ -{ - unsigned char c; - int in = 0; - struct SessionHandle *data = conn->data; - struct TELNET *tn = (struct TELNET *)conn->proto.telnet; - - while(count--) - { - c = inbuf[in++]; - - switch (tn->telrcv_state) - { - case CURL_TS_CR: - tn->telrcv_state = CURL_TS_DATA; - if (c == '\0') - { - break; /* Ignore \0 after CR */ - } - - Curl_client_write(data, CLIENTWRITE_BODY, (char *)&c, 1); - continue; - - case CURL_TS_DATA: - if (c == CURL_IAC) - { - tn->telrcv_state = CURL_TS_IAC; - break; - } - else if(c == '\r') - { - tn->telrcv_state = CURL_TS_CR; - } - - Curl_client_write(data, CLIENTWRITE_BODY, (char *)&c, 1); - continue; - - case CURL_TS_IAC: - process_iac: - switch (c) - { - case CURL_WILL: - tn->telrcv_state = CURL_TS_WILL; - continue; - case CURL_WONT: - tn->telrcv_state = CURL_TS_WONT; - continue; - case CURL_DO: - tn->telrcv_state = CURL_TS_DO; - continue; - case CURL_DONT: - tn->telrcv_state = CURL_TS_DONT; - continue; - case CURL_SB: - CURL_SB_CLEAR(tn); - tn->telrcv_state = CURL_TS_SB; - continue; - case CURL_IAC: - Curl_client_write(data, CLIENTWRITE_BODY, (char *)&c, 1); - break; - case CURL_DM: - case CURL_NOP: - case CURL_GA: - default: - printoption(data, "RCVD", CURL_IAC, c); - break; - } - tn->telrcv_state = CURL_TS_DATA; - continue; - - case CURL_TS_WILL: - printoption(data, "RCVD", CURL_WILL, c); - tn->please_negotiate = 1; - rec_will(conn, c); - tn->telrcv_state = CURL_TS_DATA; - continue; - - case CURL_TS_WONT: - printoption(data, "RCVD", CURL_WONT, c); - tn->please_negotiate = 1; - rec_wont(conn, c); - tn->telrcv_state = CURL_TS_DATA; - continue; - - case CURL_TS_DO: - printoption(data, "RCVD", CURL_DO, c); - tn->please_negotiate = 1; - rec_do(conn, c); - tn->telrcv_state = CURL_TS_DATA; - continue; - - case CURL_TS_DONT: - printoption(data, "RCVD", CURL_DONT, c); - tn->please_negotiate = 1; - rec_dont(conn, c); - tn->telrcv_state = CURL_TS_DATA; - continue; - - case CURL_TS_SB: - if (c == CURL_IAC) - { - tn->telrcv_state = CURL_TS_SE; - } - else - { - CURL_SB_ACCUM(tn,c); - } - continue; - - case CURL_TS_SE: - if (c != CURL_SE) - { - if (c != CURL_IAC) - { - /* - * This is an error. We only expect to get - * "IAC IAC" or "IAC SE". Several things may - * have happend. An IAC was not doubled, the - * IAC SE was left off, or another option got - * inserted into the suboption are all possibilities. - * If we assume that the IAC was not doubled, - * and really the IAC SE was left off, we could - * get into an infinate loop here. So, instead, - * we terminate the suboption, and process the - * partial suboption if we can. - */ - CURL_SB_ACCUM(tn, (unsigned char)CURL_IAC); - CURL_SB_ACCUM(tn, c); - tn->subpointer -= 2; - CURL_SB_TERM(tn); - - printoption(data, "In SUBOPTION processing, RCVD", CURL_IAC, c); - suboption(conn); /* handle sub-option */ - tn->telrcv_state = CURL_TS_IAC; - goto process_iac; - } - CURL_SB_ACCUM(tn,c); - tn->telrcv_state = CURL_TS_SB; - } - else - { - CURL_SB_ACCUM(tn, (unsigned char)CURL_IAC); - CURL_SB_ACCUM(tn, (unsigned char)CURL_SE); - tn->subpointer -= 2; - CURL_SB_TERM(tn); - suboption(conn); /* handle sub-option */ - tn->telrcv_state = CURL_TS_DATA; - } - break; - } - } -} - -CURLcode Curl_telnet_done(struct connectdata *conn, CURLcode status) -{ - struct TELNET *tn = (struct TELNET *)conn->proto.telnet; - (void)status; /* unused */ - - curl_slist_free_all(tn->telnet_vars); - - free(conn->proto.telnet); - conn->proto.telnet = NULL; - - return CURLE_OK; -} - -CURLcode Curl_telnet(struct connectdata *conn) -{ - CURLcode code; - struct SessionHandle *data = conn->data; - curl_socket_t sockfd = conn->sock[FIRSTSOCKET]; -#ifdef WIN32 - HMODULE wsock2; - WSOCK2_FUNC close_event_func; - WSOCK2_FUNC create_event_func; - WSOCK2_FUNC event_select_func; - WSOCK2_FUNC enum_netevents_func; - WSAEVENT event_handle; - WSANETWORKEVENTS events; - HANDLE stdin_handle; - HANDLE objs[2]; - DWORD obj_count; - DWORD wait_timeout; - DWORD waitret; - DWORD readfile_read; -#else - fd_set readfd; - fd_set keepfd; -#endif - ssize_t nread; - bool keepon = TRUE; - char *buf = data->state.buffer; - struct TELNET *tn; - - code = init_telnet(conn); - if(code) - return code; - - tn = (struct TELNET *)conn->proto.telnet; - - code = check_telnet_options(conn); - if(code) - return code; - -#ifdef WIN32 - /* - ** This functionality only works with WinSock >= 2.0. So, - ** make sure have it. - */ - code = check_wsock2(data); - if (code) - return code; - - /* OK, so we have WinSock 2.0. We need to dynamically */ - /* load ws2_32.dll and get the function pointers we need. */ - wsock2 = LoadLibrary("WS2_32.DLL"); - if (wsock2 == NULL) { - failf(data,"failed to load WS2_32.DLL (%d)",GetLastError()); - return CURLE_FAILED_INIT; - } - - /* Grab a pointer to WSACreateEvent */ - create_event_func = GetProcAddress(wsock2,"WSACreateEvent"); - if (create_event_func == NULL) { - failf(data,"failed to find WSACreateEvent function (%d)", - GetLastError()); - FreeLibrary(wsock2); - return CURLE_FAILED_INIT; - } - - /* And WSACloseEvent */ - close_event_func = GetProcAddress(wsock2,"WSACloseEvent"); - if (create_event_func == NULL) { - failf(data,"failed to find WSACloseEvent function (%d)", - GetLastError()); - FreeLibrary(wsock2); - return CURLE_FAILED_INIT; - } - - /* And WSAEventSelect */ - event_select_func = GetProcAddress(wsock2,"WSAEventSelect"); - if (event_select_func == NULL) { - failf(data,"failed to find WSAEventSelect function (%d)", - GetLastError()); - FreeLibrary(wsock2); - return CURLE_FAILED_INIT; - } - - /* And WSAEnumNetworkEvents */ - enum_netevents_func = GetProcAddress(wsock2,"WSAEnumNetworkEvents"); - if (enum_netevents_func == NULL) { - failf(data,"failed to find WSAEnumNetworkEvents function (%d)", - GetLastError()); - FreeLibrary(wsock2); - return CURLE_FAILED_INIT; - } - - /* We want to wait for both stdin and the socket. Since - ** the select() function in winsock only works on sockets - ** we have to use the WaitForMultipleObjects() call. - */ - - /* First, create a sockets event object */ - event_handle = (WSAEVENT)create_event_func(); - if (event_handle == WSA_INVALID_EVENT) { - failf(data,"WSACreateEvent failed (%d)",WSAGetLastError()); - FreeLibrary(wsock2); - return CURLE_FAILED_INIT; - } - - /* The get the Windows file handle for stdin */ - stdin_handle = GetStdHandle(STD_INPUT_HANDLE); - - /* Create the list of objects to wait for */ - objs[0] = event_handle; - objs[1] = stdin_handle; - - /* Tell winsock what events we want to listen to */ - if(event_select_func(sockfd, event_handle, FD_READ|FD_CLOSE) == SOCKET_ERROR) { - close_event_func(event_handle); - FreeLibrary(wsock2); - return 0; - } - - /* If stdin_handle is a pipe, use PeekNamedPipe() method to check it, - else use the old WaitForMultipleObjects() way */ - if(GetFileType(stdin_handle) == FILE_TYPE_PIPE) { - /* Don't wait for stdin_handle, just wait for event_handle */ - obj_count = 1; - /* Check stdin_handle per 100 milliseconds */ - wait_timeout = 100; - } else { - obj_count = 2; - wait_timeout = INFINITE; - } - - /* Keep on listening and act on events */ - while(keepon) { - waitret = WaitForMultipleObjects(obj_count, objs, FALSE, wait_timeout); - switch(waitret) { - case WAIT_TIMEOUT: - { - unsigned char outbuf[2]; - int out_count; - ssize_t bytes_written; - char *buffer = buf; - - for(;;) { - if(!PeekNamedPipe(stdin_handle, NULL, 0, NULL, &readfile_read, NULL)) { - keepon = FALSE; - break; - } - nread = readfile_read; - - if(!nread) - break; - - if(!ReadFile(stdin_handle, buf, sizeof(data->state.buffer), - &readfile_read, NULL)) { - keepon = FALSE; - break; - } - nread = readfile_read; - - while(nread--) { - outbuf[0] = *buffer++; - out_count = 1; - if(outbuf[0] == CURL_IAC) - outbuf[out_count++] = CURL_IAC; - - Curl_write(conn, conn->sock[FIRSTSOCKET], outbuf, - out_count, &bytes_written); - } - } - } - break; - - case WAIT_OBJECT_0 + 1: - { - unsigned char outbuf[2]; - int out_count; - ssize_t bytes_written; - char *buffer = buf; - - if(!ReadFile(stdin_handle, buf, sizeof(data->state.buffer), - &readfile_read, NULL)) { - keepon = FALSE; - break; - } - nread = readfile_read; - - while(nread--) { - outbuf[0] = *buffer++; - out_count = 1; - if(outbuf[0] == CURL_IAC) - outbuf[out_count++] = CURL_IAC; - - Curl_write(conn, conn->sock[FIRSTSOCKET], outbuf, - out_count, &bytes_written); - } - } - break; - - case WAIT_OBJECT_0: - if(enum_netevents_func(sockfd, event_handle, &events) - != SOCKET_ERROR) { - if(events.lNetworkEvents & FD_READ) { - /* This reallu OUGHT to check its return code. */ - (void)Curl_read(conn, sockfd, buf, BUFSIZE - 1, &nread); - - telrcv(conn, (unsigned char *)buf, nread); - - fflush(stdout); - - /* Negotiate if the peer has started negotiating, - otherwise don't. We don't want to speak telnet with - non-telnet servers, like POP or SMTP. */ - if(tn->please_negotiate && !tn->already_negotiated) { - negotiate(conn); - tn->already_negotiated = 1; - } - } - - if(events.lNetworkEvents & FD_CLOSE) { - keepon = FALSE; - } - } - break; - } - } - - /* We called WSACreateEvent, so call WSACloseEvent */ - if (close_event_func(event_handle) == FALSE) { - infof(data,"WSACloseEvent failed (%d)",WSAGetLastError()); - } - - /* "Forget" pointers into the library we're about to free */ - create_event_func = NULL; - close_event_func = NULL; - event_select_func = NULL; - enum_netevents_func = NULL; - (void)create_event_func; - (void)close_event_func; - (void)event_select_func; - (void)enum_netevents_func; - - /* We called LoadLibrary, so call FreeLibrary */ - if (!FreeLibrary(wsock2)) - infof(data,"FreeLibrary(wsock2) failed (%d)",GetLastError()); -#else - FD_ZERO (&readfd); /* clear it */ - FD_SET (sockfd, &readfd); - FD_SET (0, &readfd); - - keepfd = readfd; - - while (keepon) { - struct timeval interval; - - readfd = keepfd; /* set this every lap in the loop */ - interval.tv_sec = 1; - interval.tv_usec = 0; - - switch (select (sockfd + 1, &readfd, NULL, NULL, &interval)) { - case -1: /* error, stop reading */ - keepon = FALSE; - continue; - case 0: /* timeout */ - break; - default: /* read! */ - if(FD_ISSET(0, &readfd)) { /* read from stdin */ - unsigned char outbuf[2]; - int out_count = 0; - ssize_t bytes_written; - char *buffer = buf; - - nread = read(0, buf, 255); - - while(nread--) { - outbuf[0] = *buffer++; - out_count = 1; - if(outbuf[0] == CURL_IAC) - outbuf[out_count++] = CURL_IAC; - - Curl_write(conn, conn->sock[FIRSTSOCKET], outbuf, - out_count, &bytes_written); - } - } - - if(FD_ISSET(sockfd, &readfd)) { - /* This OUGHT to check the return code... */ - (void)Curl_read(conn, sockfd, buf, BUFSIZE - 1, &nread); - - /* if we receive 0 or less here, the server closed the connection and - we bail out from this! */ - if (nread <= 0) { - keepon = FALSE; - break; - } - - telrcv(conn, (unsigned char *)buf, nread); - - /* Negotiate if the peer has started negotiating, - otherwise don't. We don't want to speak telnet with - non-telnet servers, like POP or SMTP. */ - if(tn->please_negotiate && !tn->already_negotiated) { - negotiate(conn); - tn->already_negotiated = 1; - } - } - } - if(data->set.timeout) { - struct timeval now; /* current time */ - now = Curl_tvnow(); - if(Curl_tvdiff(now, conn->created)/1000 >= data->set.timeout) { - failf(data, "Time-out"); - code = CURLE_OPERATION_TIMEOUTED; - keepon = FALSE; - } - } - } -#endif - /* mark this as "no further transfer wanted" */ - Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL); - - return code; -} -#endif diff --git a/Source/CTest/Curl/telnet.h b/Source/CTest/Curl/telnet.h deleted file mode 100644 index 86dd99b..0000000 --- a/Source/CTest/Curl/telnet.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef __TELNET_H -#define __TELNET_H - -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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$ - ***************************************************************************/ -#ifndef CURL_DISABLE_TELNET -CURLcode Curl_telnet(struct connectdata *conn); -CURLcode Curl_telnet_done(struct connectdata *conn, CURLcode); -#endif -#endif diff --git a/Source/CTest/Curl/timeval.c b/Source/CTest/Curl/timeval.c deleted file mode 100644 index 499fba5..0000000 --- a/Source/CTest/Curl/timeval.c +++ /dev/null @@ -1,116 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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 "timeval.h" - -#ifndef HAVE_GETTIMEOFDAY - -#ifdef WIN32 -#include <mmsystem.h> - -static int gettimeofday(struct timeval *tp, void *nothing) -{ -#ifdef WITHOUT_MM_LIB - SYSTEMTIME st; - time_t tt; - struct tm tmtm; - /* mktime converts local to UTC */ - GetLocalTime (&st); - tmtm.tm_sec = st.wSecond; - tmtm.tm_min = st.wMinute; - tmtm.tm_hour = st.wHour; - tmtm.tm_mday = st.wDay; - tmtm.tm_mon = st.wMonth - 1; - tmtm.tm_year = st.wYear - 1900; - tmtm.tm_isdst = -1; - tt = mktime (&tmtm); - tp->tv_sec = tt; - tp->tv_usec = st.wMilliseconds * 1000; -#else - /** - ** The earlier time calculations using GetLocalTime - ** had a time resolution of 10ms.The timeGetTime, part - ** of multimedia apis offer a better time resolution - ** of 1ms.Need to link against winmm.lib for this - **/ - unsigned long Ticks; - unsigned long Sec; - unsigned long Usec; - Ticks = timeGetTime(); - - Sec = Ticks/1000; - Usec = (Ticks - (Sec*1000))*1000; - tp->tv_sec = Sec; - tp->tv_usec = Usec; -#endif /* WITHOUT_MM_LIB */ - (void)nothing; - return 0; -} -#else /* WIN32 */ -/* non-win32 version of Curl_gettimeofday() */ -static int gettimeofday(struct timeval *tp, void *nothing) -{ - (void)nothing; /* we don't support specific time-zones */ - tp->tv_sec = (long)time(NULL); - tp->tv_usec = 0; - return 0; -} -#endif /* WIN32 */ -#endif /* HAVE_GETTIMEOFDAY */ - -/* Return the current time in a timeval struct */ -struct timeval curlx_tvnow(void) -{ - struct timeval now; - (void)gettimeofday(&now, NULL); - return now; -} - -/* - * Make sure that the first argument is the more recent time, as otherwise - * we'll get a weird negative time-diff back... - * - * Returns: the time difference in number of milliseconds. - */ -long curlx_tvdiff(struct timeval newer, struct timeval older) -{ - return (newer.tv_sec-older.tv_sec)*1000+ - (newer.tv_usec-older.tv_usec)/1000; -} - -/* - * Same as curlx_tvdiff but with full usec resolution. - * - * Returns: the time difference in seconds with subsecond resolution. - */ -double curlx_tvdiff_secs(struct timeval newer, struct timeval older) -{ - return (double)(newer.tv_sec-older.tv_sec)+ - (double)(newer.tv_usec-older.tv_usec)/1000000.0; -} - -/* return the number of seconds in the given input timeval struct */ -long Curl_tvlong(struct timeval t1) -{ - return t1.tv_sec; -} diff --git a/Source/CTest/Curl/timeval.h b/Source/CTest/Curl/timeval.h deleted file mode 100644 index 67b885a..0000000 --- a/Source/CTest/Curl/timeval.h +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef __TIMEVAL_H -#define __TIMEVAL_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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$ - ***************************************************************************/ - -/* - * CAUTION: this header is designed to work when included by the app-side - * as well as the library. Do not mix with library internals! - */ - -#include "setup.h" - -#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__) -#include <time.h> -#else -#include <sys/time.h> -#endif - -#ifndef HAVE_GETTIMEOFDAY -#if !defined(_WINSOCKAPI_) && !defined(__MINGW32__) && !defined(_AMIGASF) && \ - !defined(__LCC__) -struct timeval { - long tv_sec; - long tv_usec; -}; -#endif -#endif - -struct timeval curlx_tvnow(void); - -/* - * Make sure that the first argument (t1) is the more recent time and t2 is - * the older time, as otherwise you get a weird negative time-diff back... - * - * Returns: the time difference in number of milliseconds. - */ -long curlx_tvdiff(struct timeval t1, struct timeval t2); - -/* - * Same as curlx_tvdiff but with full usec resolution. - * - * Returns: the time difference in seconds with subsecond resolution. - */ -double curlx_tvdiff_secs(struct timeval t1, struct timeval t2); - -long Curl_tvlong(struct timeval t1); - -/* These two defines below exist to provide the older API for library - internals only. */ -#define Curl_tvnow() curlx_tvnow() -#define Curl_tvdiff(x,y) curlx_tvdiff(x,y) -#define Curl_tvdiff_secs(x,y) curlx_tvdiff_secs(x,y) - -#endif diff --git a/Source/CTest/Curl/transfer.c b/Source/CTest/Curl/transfer.c deleted file mode 100644 index 4a108cc..0000000 --- a/Source/CTest/Curl/transfer.c +++ /dev/null @@ -1,2191 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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" - -/* -- WIN32 approved -- */ -#include <stdio.h> -#include <string.h> -#include <stdarg.h> -#include <stdlib.h> -#include <ctype.h> -#ifdef HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif -#include <sys/stat.h> - -#include <errno.h> - -#include "strtoofft.h" -#include "strequal.h" - -#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__) -#include <time.h> -#include <io.h> -#else -#ifdef HAVE_SYS_SOCKET_H -#include <sys/socket.h> -#endif -#ifdef HAVE_NETINET_IN_H -#include <netinet/in.h> -#endif -#include <sys/time.h> -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif -#include <netdb.h> -#ifdef HAVE_ARPA_INET_H -#include <arpa/inet.h> -#endif -#ifdef HAVE_NET_IF_H -#include <net/if.h> -#endif -#ifdef HAVE_SYS_IOCTL_H -#include <sys/ioctl.h> -#endif -#include <signal.h> - -#ifdef HAVE_SYS_PARAM_H -#include <sys/param.h> -#endif - -#ifdef HAVE_SYS_SELECT_H -#include <sys/select.h> -#endif - -#ifndef HAVE_SELECT -#error "We can't compile without select() support!" -#endif -#ifndef HAVE_SOCKET -#error "We can't compile without socket() support!" -#endif - -#endif - -#include "urldata.h" -#include <curl/curl.h> -#include "netrc.h" - -#include "content_encoding.h" -#include "hostip.h" -#include "transfer.h" -#include "sendf.h" -#include "speedcheck.h" -#include "progress.h" -#include "getdate.h" -#include "http.h" -#include "url.h" -#include "getinfo.h" -#include "ssluse.h" -#include "http_digest.h" -#include "http_ntlm.h" -#include "http_negotiate.h" -#include "share.h" -#include "curl_memory.h" - -#define _MPRINTF_REPLACE /* use our functions only */ -#include <curl/mprintf.h> - -/* The last #include file should be: */ -#include "memdebug.h" - -#define CURL_TIMEOUT_EXPECT_100 1000 /* counting ms here */ - -enum { - KEEP_NONE, - KEEP_READ, - KEEP_WRITE -}; - -/* We keep this static and global since this is read-only and NEVER - changed. It should just remain a blanked-out timeout value. */ -static struct timeval notimeout={0,0}; - -/* - * This function will call the read callback to fill our buffer with data - * to upload. - */ -CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp) -{ - struct SessionHandle *data = conn->data; - size_t buffersize = (size_t)bytes; - int nread; - - if(conn->bits.upload_chunky) { - /* if chunked Transfer-Encoding */ - buffersize -= (8 + 2 + 2); /* 32bit hex + CRLF + CRLF */ - conn->upload_fromhere += 10; /* 32bit hex + CRLF */ - } - - /* this function returns a size_t, so we typecast to int to prevent warnings - with picky compilers */ - nread = (int)conn->fread(conn->upload_fromhere, 1, - buffersize, conn->fread_in); - - if(nread == CURL_READFUNC_ABORT) { - failf(data, "operation aborted by callback\n"); - return CURLE_ABORTED_BY_CALLBACK; - } - - if(!conn->bits.forbidchunk && conn->bits.upload_chunky) { - /* if chunked Transfer-Encoding */ - char hexbuffer[11]; - int hexlen = snprintf(hexbuffer, sizeof(hexbuffer), - "%x\r\n", nread); - /* move buffer pointer */ - conn->upload_fromhere -= hexlen; - nread += hexlen; - - /* copy the prefix to the buffer */ - memcpy(conn->upload_fromhere, hexbuffer, hexlen); - - /* always append CRLF to the data */ - memcpy(conn->upload_fromhere + nread, "\r\n", 2); - - if((nread - hexlen) == 0) { - /* mark this as done once this chunk is transfered */ - conn->keep.upload_done = TRUE; - } - - nread+=2; /* for the added CRLF */ - } - - *nreadp = nread; - - return CURLE_OK; -} - -/* - * checkhttpprefix() - * - * Returns TRUE if member of the list matches prefix of string - */ -static bool -checkhttpprefix(struct SessionHandle *data, - const char *s) -{ - struct curl_slist *head = data->set.http200aliases; - - while (head) { - if (checkprefix(head->data, s)) - return TRUE; - head = head->next; - } - - if(checkprefix("HTTP/", s)) - return TRUE; - - return FALSE; -} - - -/* - * Curl_readwrite() is the low-level function to be called when data is to - * be read and written to/from the connection. - */ -CURLcode Curl_readwrite(struct connectdata *conn, - bool *done) -{ - struct Curl_transfer_keeper *k = &conn->keep; - struct SessionHandle *data = conn->data; - CURLcode result; - ssize_t nread; /* number of bytes read */ - int didwhat=0; - - /* These two are used only if no other select() or _fdset() have been - invoked before this. This typicly happens if you use the multi interface - and call curl_multi_perform() without calling curl_multi_fdset() - first. */ - fd_set extrareadfd; - fd_set extrawritefd; - - fd_set *readfdp = k->readfdp; - fd_set *writefdp = k->writefdp; - curl_off_t contentlength; - - if((k->keepon & KEEP_READ) && !readfdp) { - /* reading is requested, but no socket descriptor pointer was set */ - FD_ZERO(&extrareadfd); - FD_SET(conn->sockfd, &extrareadfd); - readfdp = &extrareadfd; - - /* no write, no exceptions, no timeout */ - select(conn->sockfd+1, readfdp, NULL, NULL, ¬imeout); - } - if((k->keepon & KEEP_WRITE) && !writefdp) { - /* writing is requested, but no socket descriptor pointer was set */ - FD_ZERO(&extrawritefd); - FD_SET(conn->writesockfd, &extrawritefd); - writefdp = &extrawritefd; - - /* no read, no exceptions, no timeout */ - select(conn->writesockfd+1, NULL, writefdp, NULL, ¬imeout); - } - - do { - /* If we still have reading to do, we check if we have a readable - socket. Sometimes the reafdp is NULL, if no fd_set was done using - the multi interface and then we can do nothing but to attempt a - read to be sure. */ - if((k->keepon & KEEP_READ) && - (!readfdp || FD_ISSET(conn->sockfd, readfdp))) { - - bool readdone = TRUE; - - /* This is where we loop until we have read everything there is to - read or we get a EWOULDBLOCK */ - do { - size_t buffersize = data->set.buffer_size? - data->set.buffer_size:BUFSIZE -1; - - /* receive data from the network! */ - int readrc = Curl_read(conn, conn->sockfd, k->buf, buffersize, &nread); - - /* subzero, this would've blocked */ - if(0>readrc) - break; /* get out of loop */ - - /* get the CURLcode from the int */ - result = (CURLcode)readrc; - - if(result>0) - return result; - - if ((k->bytecount == 0) && (k->writebytecount == 0)) { - Curl_pgrsTime(data, TIMER_STARTTRANSFER); - if(k->wait100_after_headers) - /* set time stamp to compare with when waiting for the 100 */ - k->start100 = Curl_tvnow(); - } - - didwhat |= KEEP_READ; - - /* NULL terminate, allowing string ops to be used */ - if (0 < nread) - k->buf[nread] = 0; - - /* if we receive 0 or less here, the server closed the connection and - we bail out from this! */ - else if (0 >= nread) { - k->keepon &= ~KEEP_READ; - FD_ZERO(&k->rkeepfd); - readdone = TRUE; - break; - } - - /* Default buffer to use when we write the buffer, it may be changed - in the flow below before the actual storing is done. */ - k->str = k->buf; - - /* Since this is a two-state thing, we check if we are parsing - headers at the moment or not. */ - if (k->header) { - /* we are in parse-the-header-mode */ - bool stop_reading = FALSE; - - /* header line within buffer loop */ - do { - size_t hbufp_index; - size_t rest_length; - size_t full_length; - int writetype; - - /* str_start is start of line within buf */ - k->str_start = k->str; - - k->end_ptr = strchr (k->str_start, '\n'); - - if (!k->end_ptr) { - /* Not a complete header line within buffer, append the data to - the end of the headerbuff. */ - - if (k->hbuflen + nread >= data->state.headersize) { - /* We enlarge the header buffer as it is too small */ - char *newbuff; - size_t newsize=CURLMAX((k->hbuflen+nread)*3/2, - data->state.headersize*2); - hbufp_index = k->hbufp - data->state.headerbuff; - newbuff = (char *)realloc(data->state.headerbuff, newsize); - if(!newbuff) { - failf (data, "Failed to alloc memory for big header!"); - return CURLE_OUT_OF_MEMORY; - } - data->state.headersize=newsize; - data->state.headerbuff = newbuff; - k->hbufp = data->state.headerbuff + hbufp_index; - } - memcpy(k->hbufp, k->str, nread); - k->hbufp += nread; - k->hbuflen += nread; - if (!k->headerline && (k->hbuflen>5)) { - /* make a first check that this looks like a HTTP header */ - if(!checkhttpprefix(data, data->state.headerbuff)) { - /* this is not the beginning of a HTTP first header line */ - k->header = FALSE; - k->badheader = HEADER_ALLBAD; - break; - } - } - - break; /* read more and try again */ - } - - /* decrease the size of the remaining (supposed) header line */ - rest_length = (k->end_ptr - k->str)+1; - nread -= rest_length; - - k->str = k->end_ptr + 1; /* move past new line */ - - full_length = k->str - k->str_start; - - /* - * We're about to copy a chunk of data to the end of the - * already received header. We make sure that the full string - * fit in the allocated header buffer, or else we enlarge - * it. - */ - if (k->hbuflen + full_length >= - data->state.headersize) { - char *newbuff; - size_t newsize=CURLMAX((k->hbuflen+full_length)*3/2, - data->state.headersize*2); - hbufp_index = k->hbufp - data->state.headerbuff; - newbuff = (char *)realloc(data->state.headerbuff, newsize); - if(!newbuff) { - failf (data, "Failed to alloc memory for big header!"); - return CURLE_OUT_OF_MEMORY; - } - data->state.headersize= newsize; - data->state.headerbuff = newbuff; - k->hbufp = data->state.headerbuff + hbufp_index; - } - - /* copy to end of line */ - strncpy (k->hbufp, k->str_start, full_length); - k->hbufp += full_length; - k->hbuflen += full_length; - *k->hbufp = 0; - k->end_ptr = k->hbufp; - - k->p = data->state.headerbuff; - - /**** - * We now have a FULL header line that p points to - *****/ - - if(!k->headerline) { - /* the first read header */ - if((k->hbuflen>5) && - !checkhttpprefix(data, data->state.headerbuff)) { - /* this is not the beginning of a HTTP first header line */ - k->header = FALSE; - if(nread) - /* since there's more, this is a partial bad header */ - k->badheader = HEADER_PARTHEADER; - else { - /* this was all we read so its all a bad header */ - k->badheader = HEADER_ALLBAD; - nread = (ssize_t)rest_length; - } - break; - } - } - - if (('\n' == *k->p) || ('\r' == *k->p)) { - size_t headerlen; - /* Zero-length header line means end of headers! */ - - if ('\r' == *k->p) - k->p++; /* pass the \r byte */ - if ('\n' == *k->p) - k->p++; /* pass the \n byte */ - - if(100 == k->httpcode) { - /* - * We have made a HTTP PUT or POST and this is 1.1-lingo - * that tells us that the server is OK with this and ready - * to receive the data. - * However, we'll get more headers now so we must get - * back into the header-parsing state! - */ - k->header = TRUE; - k->headerline = 0; /* restart the header line counter */ - /* if we did wait for this do enable write now! */ - if (k->write_after_100_header) { - - k->write_after_100_header = FALSE; - FD_SET (conn->writesockfd, &k->writefd); /* write */ - k->keepon |= KEEP_WRITE; - k->wkeepfd = k->writefd; - } - } - else - k->header = FALSE; /* no more header to parse! */ - - if (417 == k->httpcode) { - /* - * we got: "417 Expectation Failed" this means: - * we have made a HTTP call and our Expect Header - * seems to cause a problem => abort the write operations - * (or prevent them from starting). - */ - k->write_after_100_header = FALSE; - k->keepon &= ~KEEP_WRITE; - FD_ZERO(&k->wkeepfd); - } - -#ifndef CURL_DISABLE_HTTP - /* - * When all the headers have been parsed, see if we should give - * up and return an error. - */ - if (Curl_http_should_fail(conn)) { - failf (data, "The requested URL returned error: %d", - k->httpcode); - return CURLE_HTTP_RETURNED_ERROR; - } -#endif /* CURL_DISABLE_HTTP */ - - /* now, only output this if the header AND body are requested: - */ - writetype = CLIENTWRITE_HEADER; - if (data->set.include_header) - writetype |= CLIENTWRITE_BODY; - - headerlen = k->p - data->state.headerbuff; - - result = Curl_client_write(data, writetype, - data->state.headerbuff, - headerlen); - if(result) - return result; - - data->info.header_size += headerlen; - conn->headerbytecount += headerlen; - - conn->deductheadercount = - (100 == k->httpcode)?conn->headerbytecount:0; - - if (conn->resume_from && - !k->content_range && - (data->set.httpreq==HTTPREQ_GET)) { - if(k->httpcode == 416) { - /* "Requested Range Not Satisfiable" */ - stop_reading = TRUE; - } - else { - /* we wanted to resume a download, although the server - * doesn't seem to support this and we did this with a GET - * (if it wasn't a GET we did a POST or PUT resume) */ - failf (data, "HTTP server doesn't seem to support " - "byte ranges. Cannot resume."); - return CURLE_HTTP_RANGE_ERROR; - } - } -#ifndef CURL_DISABLE_HTTP - if(!stop_reading) { - /* Curl_http_auth_act() checks what authentication methods - * that are available and decides which one (if any) to - * use. It will set 'newurl' if an auth metod was picked. */ - result = Curl_http_auth_act(conn); - - if(result) - return result; - } -#endif /* CURL_DISABLE_HTTP */ - - if(!k->header) { - /* - * really end-of-headers. - * - * If we requested a "no body", this is a good time to get - * out and return home. - */ - if(conn->bits.no_body) - stop_reading = TRUE; - else { - /* If we know the expected size of this document, we set the - maximum download size to the size of the expected - document or else, we won't know when to stop reading! - - Note that we set the download maximum even if we read a - "Connection: close" header, to make sure that - "Content-Length: 0" still prevents us from attempting to - read the (missing) response-body. - */ - /* According to RFC2616 section 4.4, we MUST ignore - Content-Length: headers if we are now receiving data - using chunked Transfer-Encoding. - */ - if(conn->bits.chunk) - conn->size=-1; - - } - if(-1 != conn->size) { - /* We do this operation even if no_body is true, since this - data might be retrieved later with curl_easy_getinfo() - and its CURLINFO_CONTENT_LENGTH_DOWNLOAD option. */ - - Curl_pgrsSetDownloadSize(data, conn->size); - conn->maxdownload = conn->size; - } - /* If max download size is *zero* (nothing) we already - have nothing and can safely return ok now! */ - if(0 == conn->maxdownload) - stop_reading = TRUE; - - if(stop_reading) { - /* we make sure that this socket isn't read more now */ - k->keepon &= ~KEEP_READ; - FD_ZERO(&k->rkeepfd); - } - - break; /* exit header line loop */ - } - - /* We continue reading headers, so reset the line-based - header parsing variables hbufp && hbuflen */ - k->hbufp = data->state.headerbuff; - k->hbuflen = 0; - continue; - } - - /* - * Checks for special headers coming up. - */ - - if (!k->headerline++) { - /* This is the first header, it MUST be the error code line - or else we consiser this to be the body right away! */ - int httpversion_major; - int nc=sscanf(k->p, " HTTP/%d.%d %3d", - &httpversion_major, - &k->httpversion, - &k->httpcode); - if (nc==3) { - k->httpversion += 10 * httpversion_major; - } - else { - /* this is the real world, not a Nirvana - NCSA 1.5.x returns this crap when asked for HTTP/1.1 - */ - nc=sscanf(k->p, " HTTP %3d", &k->httpcode); - k->httpversion = 10; - - /* If user has set option HTTP200ALIASES, - compare header line against list of aliases - */ - if (!nc) { - if (checkhttpprefix(data, k->p)) { - nc = 1; - k->httpcode = 200; - k->httpversion = - (data->set.httpversion==CURL_HTTP_VERSION_1_0)? 10 : 11; - } - } - } - - if (nc) { - data->info.httpcode = k->httpcode; - data->info.httpversion = k->httpversion; - - /* - * This code executes as part of processing the header. As a - * result, it's not totally clear how to interpret the - * response code yet as that depends on what other headers may - * be present. 401 and 407 may be errors, but may be OK - * depending on how authentication is working. Other codes - * are definitely errors, so give up here. - */ - if (data->set.http_fail_on_error && - (k->httpcode >= 400) && - (k->httpcode != 401) && - (k->httpcode != 407)) { - /* serious error, go home! */ - failf (data, "The requested URL returned error: %d", - k->httpcode); - return CURLE_HTTP_RETURNED_ERROR; - } - - if(k->httpversion == 10) - /* Default action for HTTP/1.0 must be to close, unless - we get one of those fancy headers that tell us the - server keeps it open for us! */ - conn->bits.close = TRUE; - - switch(k->httpcode) { - case 204: - /* (quote from RFC2616, section 10.2.5): The server has - * fulfilled the request but does not need to return an - * entity-body ... The 204 response MUST NOT include a - * message-body, and thus is always terminated by the first - * empty line after the header fields. */ - /* FALLTHROUGH */ - case 416: /* Requested Range Not Satisfiable, it has the - Content-Length: set as the "real" document but no - actual response is sent. */ - case 304: - /* (quote from RFC2616, section 10.3.5): The 304 response - * MUST NOT contain a message-body, and thus is always - * terminated by the first empty line after the header - * fields. */ - conn->size=0; - conn->maxdownload=0; - break; - default: - /* nothing */ - break; - } - } - else { - k->header = FALSE; /* this is not a header line */ - break; - } - } - - /* Check for Content-Length: header lines to get size. Ignore - the header completely if we get a 416 response as then we're - resuming a document that we don't get, and this header contains - info about the true size of the document we didn't get now. */ - if ((k->httpcode != 416) && - checkprefix("Content-Length:", k->p)) { - contentlength = curlx_strtoofft(k->p+15, NULL, 10); - if (data->set.max_filesize && - contentlength > data->set.max_filesize) { - failf(data, "Maximum file size exceeded"); - return CURLE_FILESIZE_EXCEEDED; - } - if(contentlength >= 0) - conn->size = contentlength; - else { - /* Negative Content-Length is really odd, and we know it - happens for example when older Apache servers send large - files */ - conn->bits.close = TRUE; - infof(data, "Negative content-length: %" FORMAT_OFF_T - ", closing after transfer\n", contentlength); - } - } - /* check for Content-Type: header lines to get the mime-type */ - else if (checkprefix("Content-Type:", k->p)) { - char *start; - char *end; - size_t len; - - /* Find the first non-space letter */ - for(start=k->p+13; - *start && isspace((int)*start); - start++); - - end = strchr(start, '\r'); - if(!end) - end = strchr(start, '\n'); - - if(end) { - /* skip all trailing space letters */ - for(; isspace((int)*end) && (end > start); end--); - - /* get length of the type */ - len = end-start+1; - - /* allocate memory of a cloned copy */ - Curl_safefree(data->info.contenttype); - - data->info.contenttype = malloc(len + 1); - if (NULL == data->info.contenttype) - return CURLE_OUT_OF_MEMORY; - - /* copy the content-type string */ - memcpy(data->info.contenttype, start, len); - data->info.contenttype[len] = 0; /* zero terminate */ - } - } -#ifndef CURL_DISABLE_HTTP - else if((k->httpversion == 10) && - conn->bits.httpproxy && - Curl_compareheader(k->p, - "Proxy-Connection:", "keep-alive")) { - /* - * When a HTTP/1.0 reply comes when using a proxy, the - * 'Proxy-Connection: keep-alive' line tells us the - * connection will be kept alive for our pleasure. - * Default action for 1.0 is to close. - */ - conn->bits.close = FALSE; /* don't close when done */ - infof(data, "HTTP/1.0 proxy connection set to keep alive!\n"); - } - else if((k->httpversion == 10) && - Curl_compareheader(k->p, "Connection:", "keep-alive")) { - /* - * A HTTP/1.0 reply with the 'Connection: keep-alive' line - * tells us the connection will be kept alive for our - * pleasure. Default action for 1.0 is to close. - * - * [RFC2068, section 19.7.1] */ - conn->bits.close = FALSE; /* don't close when done */ - infof(data, "HTTP/1.0 connection set to keep alive!\n"); - } - else if (Curl_compareheader(k->p, "Connection:", "close")) { - /* - * [RFC 2616, section 8.1.2.1] - * "Connection: close" is HTTP/1.1 language and means that - * the connection will close when this request has been - * served. - */ - conn->bits.close = TRUE; /* close when done */ - } - else if (Curl_compareheader(k->p, - "Transfer-Encoding:", "chunked")) { - /* - * [RFC 2616, section 3.6.1] A 'chunked' transfer encoding - * means that the server will send a series of "chunks". Each - * chunk starts with line with info (including size of the - * coming block) (terminated with CRLF), then a block of data - * with the previously mentioned size. There can be any amount - * of chunks, and a chunk-data set to zero signals the - * end-of-chunks. */ - conn->bits.chunk = TRUE; /* chunks coming our way */ - - /* init our chunky engine */ - Curl_httpchunk_init(conn); - } - else if (checkprefix("Content-Encoding:", k->p) && - data->set.encoding) { - /* - * Process Content-Encoding. Look for the values: identity, - * gzip, deflate, compress, x-gzip and x-compress. x-gzip and - * x-compress are the same as gzip and compress. (Sec 3.5 RFC - * 2616). zlib cannot handle compress. However, errors are - * handled further down when the response body is processed - */ - char *start; - - /* Find the first non-space letter */ - for(start=k->p+17; - *start && isspace((int)*start); - start++); - - /* Record the content-encoding for later use */ - if (checkprefix("identity", start)) - k->content_encoding = IDENTITY; - else if (checkprefix("deflate", start)) - k->content_encoding = DEFLATE; - else if (checkprefix("gzip", start) - || checkprefix("x-gzip", start)) - k->content_encoding = GZIP; - else if (checkprefix("compress", start) - || checkprefix("x-compress", start)) - k->content_encoding = COMPRESS; - } - else if (Curl_compareheader(k->p, "Content-Range:", "bytes")) { - /* Content-Range: bytes [num]- - Content-Range: bytes: [num]- - - The second format was added August 1st 2000 by Igor - Khristophorov since Sun's webserver JavaWebServer/1.1.1 - obviously sends the header this way! :-( */ - - char *ptr = strstr(k->p, "bytes"); - ptr+=5; - - if(*ptr == ':') - /* stupid colon skip */ - ptr++; - - k->offset = curlx_strtoofft(ptr, NULL, 10); - - if (conn->resume_from == k->offset) - /* we asked for a resume and we got it */ - k->content_range = TRUE; - } - else if(data->cookies && - checkprefix("Set-Cookie:", k->p)) { - Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, - CURL_LOCK_ACCESS_SINGLE); - Curl_cookie_add(data, - data->cookies, TRUE, k->p+11, - /* If there is a custom-set Host: name, use it - here, or else use real peer host name. */ - conn->allocptr.cookiehost? - conn->allocptr.cookiehost:conn->host.name, - conn->path); - Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); - } - else if(checkprefix("Last-Modified:", k->p) && - (data->set.timecondition || data->set.get_filetime) ) { - time_t secs=time(NULL); - k->timeofdoc = curl_getdate(k->p+strlen("Last-Modified:"), - &secs); - if(data->set.get_filetime) - data->info.filetime = k->timeofdoc; - } - else if((checkprefix("WWW-Authenticate:", k->p) && - (401 == k->httpcode)) || - (checkprefix("Proxy-authenticate:", k->p) && - (407 == k->httpcode))) { - result = Curl_http_input_auth(conn, k->httpcode, k->p); - if(result) - return result; - } - else if ((k->httpcode >= 300 && k->httpcode < 400) && - checkprefix("Location:", k->p)) { - if(data->set.http_follow_location) { - /* this is the URL that the server advices us to get instead */ - char *ptr; - char *start=k->p; - char backup; - - start += 9; /* pass "Location:" */ - - /* Skip spaces and tabs. We do this to support multiple - white spaces after the "Location:" keyword. */ - while(*start && isspace((int)*start )) - start++; - - /* Scan through the string from the end to find the last - non-space. k->end_ptr points to the actual terminating zero - letter, move pointer one letter back and start from - there. This logic strips off trailing whitespace, but keeps - any embedded whitespace. */ - ptr = k->end_ptr-1; - while((ptr>=start) && isspace((int)*ptr)) - ptr--; - ptr++; - - backup = *ptr; /* store the ending letter */ - if(ptr != start) { - *ptr = '\0'; /* zero terminate */ - conn->newurl = strdup(start); /* clone string */ - *ptr = backup; /* restore ending letter */ - if(!conn->newurl) - return CURLE_OUT_OF_MEMORY; - } - } - } -#endif /* CURL_DISABLE_HTTP */ - - /* - * End of header-checks. Write them to the client. - */ - - writetype = CLIENTWRITE_HEADER; - if (data->set.include_header) - writetype |= CLIENTWRITE_BODY; - - if(data->set.verbose) - Curl_debug(data, CURLINFO_HEADER_IN, - k->p, k->hbuflen, conn->host.dispname); - - result = Curl_client_write(data, writetype, k->p, k->hbuflen); - if(result) - return result; - - data->info.header_size += k->hbuflen; - conn->headerbytecount += k->hbuflen; - - /* reset hbufp pointer && hbuflen */ - k->hbufp = data->state.headerbuff; - k->hbuflen = 0; - } - while (!stop_reading && *k->str); /* header line within buffer */ - - if(stop_reading) - /* We've stopped dealing with input, get out of the do-while loop */ - break; - - /* We might have reached the end of the header part here, but - there might be a non-header part left in the end of the read - buffer. */ - - } /* end if header mode */ - - /* This is not an 'else if' since it may be a rest from the header - parsing, where the beginning of the buffer is headers and the end - is non-headers. */ - if (k->str && !k->header && (nread > 0)) { - - if(0 == k->bodywrites) { - /* These checks are only made the first time we are about to - write a piece of the body */ - if(conn->protocol&PROT_HTTP) { - /* HTTP-only checks */ - - if (conn->newurl) { - if(conn->bits.close) { - /* Abort after the headers if "follow Location" is set - and we're set to close anyway. */ - k->keepon &= ~KEEP_READ; - FD_ZERO(&k->rkeepfd); - *done = TRUE; - return CURLE_OK; - } - /* We have a new url to load, but since we want to be able - to re-use this connection properly, we read the full - response in "ignore more" */ - k->ignorebody = TRUE; - infof(data, "Ignoring the response-body\n"); - } - if(data->set.timecondition && !conn->range) { - /* A time condition has been set AND no ranges have been - requested. This seems to be what chapter 13.3.4 of - RFC 2616 defines to be the correct action for a - HTTP/1.1 client */ - if((k->timeofdoc > 0) && (data->set.timevalue > 0)) { - switch(data->set.timecondition) { - case CURL_TIMECOND_IFMODSINCE: - default: - if(k->timeofdoc < data->set.timevalue) { - infof(data, - "The requested document is not new enough\n"); - *done = TRUE; - return CURLE_OK; - } - break; - case CURL_TIMECOND_IFUNMODSINCE: - if(k->timeofdoc > data->set.timevalue) { - infof(data, - "The requested document is not old enough\n"); - *done = TRUE; - return CURLE_OK; - } - break; - } /* switch */ - } /* two valid time strings */ - } /* we have a time condition */ - - } /* this is HTTP */ - } /* this is the first time we write a body part */ - k->bodywrites++; - - /* pass data to the debug function before it gets "dechunked" */ - if(data->set.verbose) { - if(k->badheader) { - Curl_debug(data, CURLINFO_DATA_IN, data->state.headerbuff, - k->hbuflen, conn->host.dispname); - if(k->badheader == HEADER_PARTHEADER) - Curl_debug(data, CURLINFO_DATA_IN, k->str, nread, - conn->host.dispname); - } - else - Curl_debug(data, CURLINFO_DATA_IN, k->str, nread, - conn->host.dispname); - } - -#ifndef CURL_DISABLE_HTTP - if(conn->bits.chunk) { - /* - * Bless me father for I have sinned. Here comes a chunked - * transfer flying and we need to decode this properly. While - * the name says read, this function both reads and writes away - * the data. The returned 'nread' holds the number of actual - * data it wrote to the client. */ - CHUNKcode res = - Curl_httpchunk_read(conn, k->str, nread, &nread); - - if(CHUNKE_OK < res) { - if(CHUNKE_WRITE_ERROR == res) { - failf(data, "Failed writing data"); - return CURLE_WRITE_ERROR; - } - failf(data, "Received problem %d in the chunky parser", res); - return CURLE_RECV_ERROR; - } - else if(CHUNKE_STOP == res) { - /* we're done reading chunks! */ - k->keepon &= ~KEEP_READ; /* read no more */ - FD_ZERO(&k->rkeepfd); - - /* There are now possibly N number of bytes at the end of the - str buffer that weren't written to the client, but we don't - care about them right now. */ - } - /* If it returned OK, we just keep going */ - } -#endif /* CURL_DISABLE_HTTP */ - - if((-1 != conn->maxdownload) && - (k->bytecount + nread >= conn->maxdownload)) { - nread = (ssize_t) (conn->maxdownload - k->bytecount); - if(nread < 0 ) /* this should be unusual */ - nread = 0; - - k->keepon &= ~KEEP_READ; /* we're done reading */ - FD_ZERO(&k->rkeepfd); - } - - k->bytecount += nread; - - Curl_pgrsSetDownloadCounter(data, k->bytecount); - - if(!conn->bits.chunk && (nread || k->badheader)) { - /* If this is chunky transfer, it was already written */ - - if(k->badheader && !k->ignorebody) { - /* we parsed a piece of data wrongly assuming it was a header - and now we output it as body instead */ - result = Curl_client_write(data, CLIENTWRITE_BODY, - data->state.headerbuff, - k->hbuflen); - } - if(k->badheader < HEADER_ALLBAD) { - /* This switch handles various content encodings. If there's an - error here, be sure to check over the almost identical code - in http_chunks.c. - Make sure that ALL_CONTENT_ENCODINGS contains all the - encodings handled here. */ -#ifdef HAVE_LIBZ - switch (k->content_encoding) { - case IDENTITY: -#endif - /* This is the default when the server sends no - Content-Encoding header. See Curl_readwrite_init; the - memset() call initializes k->content_encoding to zero. */ - if(!k->ignorebody) - result = Curl_client_write(data, CLIENTWRITE_BODY, k->str, - nread); -#ifdef HAVE_LIBZ - break; - - case DEFLATE: - /* Assume CLIENTWRITE_BODY; headers are not encoded. */ - result = Curl_unencode_deflate_write(data, k, nread); - break; - - case GZIP: - /* Assume CLIENTWRITE_BODY; headers are not encoded. */ - result = Curl_unencode_gzip_write(data, k, nread); - break; - - case COMPRESS: - default: - failf (data, "Unrecognized content encoding type. " - "libcurl understands `identity', `deflate' and `gzip' " - "content encodings."); - result = CURLE_BAD_CONTENT_ENCODING; - break; - } -#endif - } - k->badheader = HEADER_NORMAL; /* taken care of now */ - - if(result) - return result; - } - - } /* if (! header and data to read ) */ - - } while(!readdone); - - } /* if( read from socket ) */ - - /* If we still have writing to do, we check if we have a writable - socket. Sometimes the writefdp is NULL, if no fd_set was done using - the multi interface and then we can do nothing but to attempt a - write to be sure. */ - if((k->keepon & KEEP_WRITE) && - (!writefdp || FD_ISSET(conn->writesockfd, writefdp)) ) { - /* write */ - - int i, si; - ssize_t bytes_written; - bool writedone=TRUE; - - if ((k->bytecount == 0) && (k->writebytecount == 0)) - Curl_pgrsTime(data, TIMER_STARTTRANSFER); - - didwhat |= KEEP_WRITE; - - /* - * We loop here to do the READ and SEND loop until we run out of - * data to send or until we get EWOULDBLOCK back - */ - do { - - /* only read more data if there's no upload data already - present in the upload buffer */ - if(0 == conn->upload_present) { - /* init the "upload from here" pointer */ - conn->upload_fromhere = k->uploadbuf; - - if(!k->upload_done) { - /* HTTP pollution, this should be written nicer to become more - protocol agnostic. */ - int fillcount; - - if(k->wait100_after_headers && - (conn->proto.http->sending == HTTPSEND_BODY)) { - /* If this call is to send body data, we must take some action: - We have sent off the full HTTP 1.1 request, and we shall now - go into the Expect: 100 state and await such a header */ - k->wait100_after_headers = FALSE; /* headers sent */ - k->write_after_100_header = TRUE; /* wait for the header */ - FD_ZERO (&k->writefd); /* clear it */ - k->wkeepfd = k->writefd; /* set the keeper variable */ - k->keepon &= ~KEEP_WRITE; /* disable writing */ - k->start100 = Curl_tvnow(); /* timeout count starts now */ - didwhat &= ~KEEP_WRITE; /* we didn't write anything actually */ - break; - } - - result = Curl_fillreadbuffer(conn, BUFSIZE, &fillcount); - if(result) - return result; - - nread = (ssize_t)fillcount; - } - else - nread = 0; /* we're done uploading/reading */ - - /* the signed int typecase of nread of for systems that has - unsigned size_t */ - if (nread<=0) { - /* done */ - k->keepon &= ~KEEP_WRITE; /* we're done writing */ - FD_ZERO(&k->wkeepfd); - writedone = TRUE; - (void)writedone; - break; - } - - /* store number of bytes available for upload */ - conn->upload_present = nread; - - /* convert LF to CRLF if so asked */ - if (data->set.crlf) { - if(data->state.scratch == NULL) - data->state.scratch = malloc(2*BUFSIZE); - if(data->state.scratch == NULL) { - failf (data, "Failed to alloc scratch buffer!"); - return CURLE_OUT_OF_MEMORY; - } - for(i = 0, si = 0; i < nread; i++, si++) { - if (conn->upload_fromhere[i] == 0x0a) { - data->state.scratch[si++] = 0x0d; - data->state.scratch[si] = 0x0a; - } - else - data->state.scratch[si] = conn->upload_fromhere[i]; - } - if(si != nread) { - /* only perform the special operation if we really did replace - anything */ - nread = si; - - /* upload from the new (replaced) buffer instead */ - conn->upload_fromhere = data->state.scratch; - - /* set the new amount too */ - conn->upload_present = nread; - } - } - } - else { - /* We have a partial buffer left from a previous "round". Use - that instead of reading more data */ - } - - /* write to socket (send away data) */ - result = Curl_write(conn, - conn->writesockfd, /* socket to send to */ - conn->upload_fromhere, /* buffer pointer */ - conn->upload_present, /* buffer size */ - &bytes_written); /* actually send away */ - if(result) - return result; - - if(data->set.verbose) - /* show the data before we change the pointer upload_fromhere */ - Curl_debug(data, CURLINFO_DATA_OUT, conn->upload_fromhere, - bytes_written, conn->host.dispname); - - if(conn->upload_present != bytes_written) { - /* we only wrote a part of the buffer (if anything), deal with it! */ - - /* store the amount of bytes left in the buffer to write */ - conn->upload_present -= bytes_written; - - /* advance the pointer where to find the buffer when the next send - is to happen */ - conn->upload_fromhere += bytes_written; - - writedone = TRUE; /* we are done, stop the loop */ - } - else { - /* we've uploaded that buffer now */ - conn->upload_fromhere = k->uploadbuf; - conn->upload_present = 0; /* no more bytes left */ - - if(k->upload_done) { - /* switch off writing, we're done! */ - k->keepon &= ~KEEP_WRITE; /* we're done writing */ - FD_ZERO(&k->wkeepfd); - writedone = TRUE; - } - } - - k->writebytecount += bytes_written; - Curl_pgrsSetUploadCounter(data, k->writebytecount); - - } while(!writedone); /* loop until we're done writing! */ - - } - - } while(0); /* just to break out from! */ - - k->now = Curl_tvnow(); - if(didwhat) { - /* Update read/write counters */ - if(conn->bytecountp) - *conn->bytecountp = k->bytecount; /* read count */ - if(conn->writebytecountp) - *conn->writebytecountp = k->writebytecount; /* write count */ - } - else { - /* no read no write, this is a timeout? */ - if (k->write_after_100_header) { - /* This should allow some time for the header to arrive, but only a - very short time as otherwise it'll be too much wasted times too - often. */ - - /* Quoting RFC2616, section "8.2.3 Use of the 100 (Continue) Status": - - Therefore, when a client sends this header field to an origin server - (possibly via a proxy) from which it has never seen a 100 (Continue) - status, the client SHOULD NOT wait for an indefinite period before - sending the request body. - - */ - - long ms = Curl_tvdiff(k->now, k->start100); - if(ms > CURL_TIMEOUT_EXPECT_100) { - /* we've waited long enough, continue anyway */ - k->write_after_100_header = FALSE; - FD_SET (conn->writesockfd, &k->writefd); /* write socket */ - k->keepon |= KEEP_WRITE; - k->wkeepfd = k->writefd; - } - } - } - - if(Curl_pgrsUpdate(conn)) - result = CURLE_ABORTED_BY_CALLBACK; - else - result = Curl_speedcheck(data, k->now); - if (result) - return result; - - if (data->set.timeout && - ((Curl_tvdiff(k->now, k->start)/1000) >= data->set.timeout)) { - failf(data, "Operation timed out with %" FORMAT_OFF_T - " out of %" FORMAT_OFF_T " bytes received", - k->bytecount, conn->size); - return CURLE_OPERATION_TIMEOUTED; - } - - if(!k->keepon) { - /* - * The transfer has been performed. Just make some general checks before - * returning. - */ - - if(!(conn->bits.no_body) && (conn->size != -1) && - (k->bytecount != conn->size) && - !conn->newurl) { - failf(data, "transfer closed with %" FORMAT_OFF_T - " bytes remaining to read", - conn->size - k->bytecount); - return CURLE_PARTIAL_FILE; - } - else if(conn->bits.chunk && conn->proto.http->chunk.datasize) { - failf(data, "transfer closed with at least %d bytes remaining", - conn->proto.http->chunk.datasize); - return CURLE_PARTIAL_FILE; - } - if(Curl_pgrsUpdate(conn)) - return CURLE_ABORTED_BY_CALLBACK; - } - - /* Now update the "done" boolean we return */ - *done = !k->keepon; - - return CURLE_OK; -} - - -/* - * Curl_readwrite_init() inits the readwrite session. - */ - -CURLcode Curl_readwrite_init(struct connectdata *conn) -{ - struct SessionHandle *data; - struct Curl_transfer_keeper *k = &conn->keep; - - /* NB: the content encoding software depends on this initialization of - Curl_transfer_keeper. */ - memset(k, 0, sizeof(struct Curl_transfer_keeper)); - - k->start = Curl_tvnow(); /* start time */ - k->now = k->start; /* current time is now */ - k->header = TRUE; /* assume header */ - k->httpversion = -1; /* unknown at this point */ - - data = conn->data; /* there's the root struct */ - k->buf = data->state.buffer; - k->uploadbuf = data->state.uploadbuffer; - k->maxfd = (conn->sockfd>conn->writesockfd? - conn->sockfd:conn->writesockfd)+1; - k->hbufp = data->state.headerbuff; - k->ignorebody=FALSE; - - Curl_pgrsTime(data, TIMER_PRETRANSFER); - Curl_speedinit(data); - - Curl_pgrsSetUploadCounter(data, 0); - Curl_pgrsSetDownloadCounter(data, 0); - - if (!conn->bits.getheader) { - k->header = FALSE; - if(conn->size > 0) - Curl_pgrsSetDownloadSize(data, conn->size); - } - /* we want header and/or body, if neither then don't do this! */ - if(conn->bits.getheader || !conn->bits.no_body) { - - FD_ZERO (&k->readfd); /* clear it */ - if(conn->sockfd != CURL_SOCKET_BAD) { - FD_SET (conn->sockfd, &k->readfd); /* read socket */ - k->keepon |= KEEP_READ; - } - - FD_ZERO (&k->writefd); /* clear it */ - if(conn->writesockfd != CURL_SOCKET_BAD) { - /* HTTP 1.1 magic: - - Even if we require a 100-return code before uploading data, we might - need to write data before that since the REQUEST may not have been - finished sent off just yet. - - Thus, we must check if the request has been sent before we set the - state info where we wait for the 100-return code - */ - if (data->set.expect100header && - (conn->proto.http->sending == HTTPSEND_BODY)) { - /* wait with write until we either got 100-continue or a timeout */ - k->write_after_100_header = TRUE; - k->start100 = k->start; - } - else { - if(data->set.expect100header) - /* when we've sent off the rest of the headers, we must await a - 100-continue */ - k->wait100_after_headers = TRUE; - FD_SET (conn->writesockfd, &k->writefd); /* write socket */ - k->keepon |= KEEP_WRITE; - } - } - - /* get these in backup variables to be able to restore them on each lap in - the select() loop */ - k->rkeepfd = k->readfd; - k->wkeepfd = k->writefd; - - } - - return CURLE_OK; -} - -/* - * Curl_single_fdset() gets called by the multi interface code when the app - * has requested to get the fd_sets for the current connection. This function - * will then be called once for every connection that the multi interface - * keeps track of. This function will only be called for connections that are - * in the proper state to have this information available. - */ -void Curl_single_fdset(struct connectdata *conn, - fd_set *read_fd_set, - fd_set *write_fd_set, - fd_set *exc_fd_set, - int *max_fd) -{ - *max_fd = -1; /* init */ - if(conn->keep.keepon & KEEP_READ) { - FD_SET(conn->sockfd, read_fd_set); - *max_fd = conn->sockfd; - conn->keep.readfdp = read_fd_set; /* store the address of the set */ - } - if(conn->keep.keepon & KEEP_WRITE) { - FD_SET(conn->writesockfd, write_fd_set); - - /* since sockets are curl_socket_t nowadays, we typecast it to int here - to compare it nicely */ - if((int)conn->writesockfd > *max_fd) - *max_fd = conn->writesockfd; - conn->keep.writefdp = write_fd_set; /* store the address of the set */ - } - /* we don't use exceptions, only touch that one to prevent compiler - warnings! */ - *exc_fd_set = *exc_fd_set; -} - - -/* - * Transfer() - * - * This function is what performs the actual transfer. It is capable of - * doing both ways simultaneously. - * The transfer must already have been setup by a call to Curl_Transfer(). - * - * Note that headers are created in a preallocated buffer of a default size. - * That buffer can be enlarged on demand, but it is never shrunken again. - * - * Parts of this function was once written by the friendly Mark Butler - * <butlerm@xmission.com>. - */ - -static CURLcode -Transfer(struct connectdata *conn) -{ - CURLcode result; - struct Curl_transfer_keeper *k = &conn->keep; - bool done=FALSE; - - if(!(conn->protocol & PROT_FILE)) - /* Only do this if we are not transferring FILE:, since the file: treatment - is different*/ - Curl_readwrite_init(conn); - - if((conn->sockfd == CURL_SOCKET_BAD) && - (conn->writesockfd == CURL_SOCKET_BAD)) - /* nothing to read, nothing to write, we're already OK! */ - return CURLE_OK; - - /* we want header and/or body, if neither then don't do this! */ - if(!conn->bits.getheader && conn->bits.no_body) - return CURLE_OK; - - k->writefdp = &k->writefd; /* store the address of the set */ - k->readfdp = &k->readfd; /* store the address of the set */ - - while (!done) { - struct timeval interval; - k->readfd = k->rkeepfd; /* set these every lap in the loop */ - k->writefd = k->wkeepfd; - interval.tv_sec = 1; - interval.tv_usec = 0; - - switch (select (k->maxfd, k->readfdp, k->writefdp, NULL, &interval)) { - case -1: /* select() error, stop reading */ -#ifdef EINTR - /* The EINTR is not serious, and it seems you might get this more - ofen when using the lib in a multi-threaded environment! */ - if(errno == EINTR) - ; - else -#endif - done = TRUE; /* no more read or write */ - continue; - case 0: /* timeout */ - default: /* readable descriptors */ - result = Curl_readwrite(conn, &done); - break; - } - if(result) - return result; - - /* "done" signals to us if the transfer(s) are ready */ - } - - return CURLE_OK; -} - -/* - * Curl_pretransfer() is called immediately before a transfer starts. - */ -CURLcode Curl_pretransfer(struct SessionHandle *data) -{ - if(!data->change.url) - /* we can't do anything wihout URL */ - return CURLE_URL_MALFORMAT; - -#ifdef USE_SSLEAY - { - /* Init the SSL session ID cache here. We do it here since we want to do - it after the *_setopt() calls (that could change the size of the cache) - but before any transfer takes place. */ - CURLcode res = Curl_SSL_InitSessions(data, data->set.ssl.numsessions); - if(res) - return res; - } -#endif - - data->set.followlocation=0; /* reset the location-follow counter */ - data->state.this_is_a_follow = FALSE; /* reset this */ - data->state.errorbuf = FALSE; /* no error has occurred */ - - data->state.authproblem = FALSE; - data->state.authhost.want = data->set.httpauth; - data->state.authproxy.want = data->set.proxyauth; - -#ifndef CURL_DISABLE_HTTP - /* If there was a list of cookie files to read and we haven't done it before, - do it now! */ - if(data->change.cookielist) { - struct curl_slist *list = data->change.cookielist; - Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); - while(list) { - data->cookies = Curl_cookie_init(data, - list->data, - data->cookies, - data->set.cookiesession); - list = list->next; - } - Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); - curl_slist_free_all(data->change.cookielist); /* clean up list */ - data->change.cookielist = NULL; /* don't do this again! */ - } -#endif /* CURL_DISABLE_HTTP */ - - - /* Allow data->set.use_port to set which port to use. This needs to be - * disabled for example when we follow Location: headers to URLs using - * different ports! */ - data->state.allow_port = TRUE; - -#if defined(HAVE_SIGNAL) && defined(SIGPIPE) && !defined(HAVE_MSG_NOSIGNAL) - /************************************************************* - * Tell signal handler to ignore SIGPIPE - *************************************************************/ - if(!data->set.no_signal) - data->state.prev_signal = signal(SIGPIPE, SIG_IGN); -#endif - - Curl_initinfo(data); /* reset session-specific information "variables" */ - Curl_pgrsStartNow(data); - - return CURLE_OK; -} - -/* - * Curl_posttransfer() is called immediately after a transfer ends - */ -CURLcode Curl_posttransfer(struct SessionHandle *data) -{ -#if defined(HAVE_SIGNAL) && defined(SIGPIPE) && !defined(HAVE_MSG_NOSIGNAL) - /* restore the signal handler for SIGPIPE before we get back */ - if(!data->set.no_signal) - signal(SIGPIPE, data->state.prev_signal); -#else - (void)data; /* unused parameter */ -#endif - - return CURLE_OK; -} - -/* - * strlen_url() returns the length of the given URL if the spaces within the - * URL were properly URL encoded. - */ -static int strlen_url(char *url) -{ - char *ptr; - int newlen=0; - bool left=TRUE; /* left side of the ? */ - - for(ptr=url; *ptr; ptr++) { - switch(*ptr) { - case '?': - left=FALSE; - default: - newlen++; - break; - case ' ': - if(left) - newlen+=3; - else - newlen++; - break; - } - } - return newlen; -} - -/* strcpy_url() copies a url to a output buffer and URL-encodes the spaces in - * the source URL accordingly. - */ -static void strcpy_url(char *output, char *url) -{ - /* we must add this with whitespace-replacing */ - bool left=TRUE; - char *iptr; - char *optr = output; - for(iptr = url; /* read from here */ - *iptr; /* until zero byte */ - iptr++) { - switch(*iptr) { - case '?': - left=FALSE; - default: - *optr++=*iptr; - break; - case ' ': - if(left) { - *optr++='%'; /* add a '%' */ - *optr++='2'; /* add a '2' */ - *optr++='0'; /* add a '0' */ - } - else - *optr++='+'; /* add a '+' here */ - break; - } - } - *optr=0; /* zero terminate output buffer */ - -} - -/* - * Curl_follow() handles the URL redirect magic. Pass in the 'newurl' string - * as given by the remote server and set up the new URL to request. - */ -CURLcode Curl_follow(struct SessionHandle *data, - char *newurl) /* this 'newurl' is the Location: string, - and it must be malloc()ed before passed - here */ -{ - /* Location: redirect */ - char prot[16]; /* URL protocol string storage */ - char letter; /* used for a silly sscanf */ - size_t newlen; - char *newest; - - if (data->set.maxredirs && - (data->set.followlocation >= data->set.maxredirs)) { - failf(data,"Maximum (%d) redirects followed", data->set.maxredirs); - return CURLE_TOO_MANY_REDIRECTS; - } - - /* mark the next request as a followed location: */ - data->state.this_is_a_follow = TRUE; - - data->set.followlocation++; /* count location-followers */ - - if(data->set.http_auto_referer) { - /* We are asked to automatically set the previous URL as the - referer when we get the next URL. We pick the ->url field, - which may or may not be 100% correct */ - - if(data->change.referer_alloc) - /* If we already have an allocated referer, free this first */ - free(data->change.referer); - - data->change.referer = strdup(data->change.url); - data->change.referer_alloc = TRUE; /* yes, free this later */ - } - - if(2 != sscanf(newurl, "%15[^?&/:]://%c", prot, &letter)) { - /*** - *DANG* this is an RFC 2068 violation. The URL is supposed - to be absolute and this doesn't seem to be that! - *** - Instead, we have to TRY to append this new path to the old URL - to the right of the host part. Oh crap, this is doomed to cause - problems in the future... - */ - char *protsep; - char *pathsep; - - char *useurl = newurl; - size_t urllen; - - /* we must make our own copy of the URL to play with, as it may - point to read-only data */ - char *url_clone=strdup(data->change.url); - - if(!url_clone) - return CURLE_OUT_OF_MEMORY; /* skip out of this NOW */ - - /* protsep points to the start of the host name */ - protsep=strstr(url_clone, "//"); - if(!protsep) - protsep=url_clone; - else - protsep+=2; /* pass the slashes */ - - if('/' != newurl[0]) { - int level=0; - - /* First we need to find out if there's a ?-letter in the URL, - and cut it and the right-side of that off */ - pathsep = strrchr(protsep, '?'); - if(pathsep) - *pathsep=0; - - /* we have a relative path to append to the last slash if - there's one available */ - pathsep = strrchr(protsep, '/'); - if(pathsep) - *pathsep=0; - - /* Check if there's any slash after the host name, and if so, - remember that position instead */ - pathsep = strchr(protsep, '/'); - if(pathsep) - protsep = pathsep+1; - else - protsep = NULL; - - /* now deal with one "./" or any amount of "../" in the newurl - and act accordingly */ - - if((useurl[0] == '.') && (useurl[1] == '/')) - useurl+=2; /* just skip the "./" */ - - while((useurl[0] == '.') && - (useurl[1] == '.') && - (useurl[2] == '/')) { - level++; - useurl+=3; /* pass the "../" */ - } - - if(protsep) { - while(level--) { - /* cut off one more level from the right of the original URL */ - pathsep = strrchr(protsep, '/'); - if(pathsep) - *pathsep=0; - else { - *protsep=0; - break; - } - } - } - } - else { - /* We got a new absolute path for this server, cut off from the - first slash */ - pathsep = strchr(protsep, '/'); - if(pathsep) - *pathsep=0; - else { - /* There was no slash. Now, since we might be operating on a badly - formatted URL, such as "http://www.url.com?id=2380" which doesn't - use a slash separator as it is supposed to, we need to check for a - ?-letter as well! */ - pathsep = strchr(protsep, '?'); - if(pathsep) - *pathsep=0; - } - } - - /* If the new part contains a space, this is a mighty stupid redirect - but we still make an effort to do "right". To the left of a '?' - letter we replace each space with %20 while it is replaced with '+' - on the right side of the '?' letter. - */ - newlen = strlen_url(useurl); - - urllen = strlen(url_clone); - - newest=(char *)malloc( urllen + 1 + /* possible slash */ - newlen + 1 /* zero byte */); - - if(!newest) { - free(url_clone); /* don't leak this */ - return CURLE_OUT_OF_MEMORY; /* go out from this */ - } - - /* copy over the root url part */ - memcpy(newest, url_clone, urllen); - - /* check if we need to append a slash */ - if(('/' == useurl[0]) || (protsep && !*protsep)) - ; - else - newest[urllen++]='/'; - - /* then append the new piece on the right side */ - strcpy_url(&newest[urllen], useurl); - - free(newurl); /* newurl is the allocated pointer */ - free(url_clone); - newurl = newest; - } - else { - /* This is an absolute URL, don't allow the custom port number */ - data->state.allow_port = FALSE; - - if(strchr(newurl, ' ')) { - /* This new URL contains at least one space, this is a mighty stupid - redirect but we still make an effort to do "right". */ - newlen = strlen_url(newurl); - - newest = malloc(newlen+1); /* get memory for this */ - if(newest) { - strcpy_url(newest, newurl); /* create a space-free URL */ - - free(newurl); /* that was no good */ - newurl = newest; /* use this instead now */ - } - } - - } - - if(data->change.url_alloc) - free(data->change.url); - else - data->change.url_alloc = TRUE; /* the URL is allocated */ - - data->change.url = newurl; - newurl = NULL; /* don't free! */ - (void)newurl; - - infof(data, "Issue another request to this URL: '%s'\n", data->change.url); - - /* - * We get here when the HTTP code is 300-399 (and 401). We need to perform - * differently based on exactly what return code there was. - * - * News from 7.10.6: we can also get here on a 401 or 407, in case we act on - * a HTTP (proxy-) authentication scheme other than Basic. - */ - switch(data->info.httpcode) { - /* 401 - Act on a www-authentication, we keep on moving and do the - Authorization: XXXX header in the HTTP request code snippet */ - /* 407 - Act on a proxy-authentication, we keep on moving and do the - Proxy-Authorization: XXXX header in the HTTP request code snippet */ - /* 300 - Multiple Choices */ - /* 306 - Not used */ - /* 307 - Temporary Redirect */ - default: /* for all above (and the unknown ones) */ - /* Some codes are explicitly mentioned since I've checked RFC2616 and they - * seem to be OK to POST to. - */ - break; - case 301: /* Moved Permanently */ - /* (quote from RFC2616, section 10.3.2): - * - * Note: When automatically redirecting a POST request after receiving a - * 301 status code, some existing HTTP/1.0 user agents will erroneously - * change it into a GET request. - * - * ---- - * - * Warning: Because most of importants user agents do this obvious RFC2616 - * violation, many webservers expect this misbehavior. So these servers - * often answers to a POST request with an error page. To be sure that - * libcurl gets the page that most user agents would get, libcurl has to - * force GET: - */ - if( data->set.httpreq == HTTPREQ_POST - || data->set.httpreq == HTTPREQ_POST_FORM) { - infof(data, - "Violate RFC 2616/10.3.2 and switch from POST to GET\n"); - data->set.httpreq = HTTPREQ_GET; - } - break; - case 302: /* Found */ - /* (From 10.3.3) - - Note: RFC 1945 and RFC 2068 specify that the client is not allowed - to change the method on the redirected request. However, most - existing user agent implementations treat 302 as if it were a 303 - response, performing a GET on the Location field-value regardless - of the original request method. The status codes 303 and 307 have - been added for servers that wish to make unambiguously clear which - kind of reaction is expected of the client. - - (From 10.3.4) - - Note: Many pre-HTTP/1.1 user agents do not understand the 303 - status. When interoperability with such clients is a concern, the - 302 status code may be used instead, since most user agents react - to a 302 response as described here for 303. - */ - case 303: /* See Other */ - /* Disable both types of POSTs, since doing a second POST when - * following isn't what anyone would want! */ - if(data->set.httpreq != HTTPREQ_GET) { - data->set.httpreq = HTTPREQ_GET; /* enforce GET request */ - infof(data, "Disables POST, goes with %s\n", - data->set.opt_no_body?"HEAD":"GET"); - } - break; - case 304: /* Not Modified */ - /* 304 means we did a conditional request and it was "Not modified". - * We shouldn't get any Location: header in this response! - */ - break; - case 305: /* Use Proxy */ - /* (quote from RFC2616, section 10.3.6): - * "The requested resource MUST be accessed through the proxy given - * by the Location field. The Location field gives the URI of the - * proxy. The recipient is expected to repeat this single request - * via the proxy. 305 responses MUST only be generated by origin - * servers." - */ - break; - } - Curl_pgrsTime(data, TIMER_REDIRECT); - Curl_pgrsResetTimes(data); - - return CURLE_OK; -} - -static CURLcode -Curl_connect_host(struct SessionHandle *data, - struct connectdata **conn) -{ - CURLcode res; - int urlchanged; - - do { - bool async; - Curl_pgrsTime(data, TIMER_STARTSINGLE); - data->change.url_changed = FALSE; - res = Curl_connect(data, conn, &async); - - if((CURLE_OK == res) && async) { - /* Now, if async is TRUE here, we need to wait for the name - to resolve */ - res = Curl_wait_for_resolv(*conn, NULL); - if(CURLE_OK == res) - /* Resolved, continue with the connection */ - res = Curl_async_resolved(*conn); - } - if(res) - break; - - /* If a callback (or something) has altered the URL we should use within - the Curl_connect(), we detect it here and act as if we are redirected - to the new URL */ - urlchanged = data->change.url_changed; - if ((CURLE_OK == res) && urlchanged) { - res = Curl_done(conn, res); - if(CURLE_OK == res) { - char *gotourl = strdup(data->change.url); - res = Curl_follow(data, gotourl); - if(res) - free(gotourl); - } - } - } while (urlchanged && res == CURLE_OK); - - return res; -} - - - -/* - * Curl_perform() is the internal high-level function that gets called by the - * external curl_easy_perform() function. It inits, performs and cleans up a - * single file transfer. - */ -CURLcode Curl_perform(struct SessionHandle *data) -{ - CURLcode res; - CURLcode res2; - struct connectdata *conn=NULL; - char *newurl = NULL; /* possibly a new URL to follow to! */ - - data->state.used_interface = Curl_if_easy; - - res = Curl_pretransfer(data); - if(res) - return res; - - /* - * It is important that there is NO 'return' from this function at any other - * place than falling down to the end of the function! This is because we - * have cleanup stuff that must be done before we get back, and that is only - * performed after this do-while loop. - */ - - do { - res = Curl_connect_host(data, &conn); /* primary connection */ - - if(res == CURLE_OK) { - if (data->set.source_host) /* 3rd party transfer */ - res = Curl_pretransfersec(conn); - else - conn->sec_conn = NULL; - } - - if(res == CURLE_OK) { - - res = Curl_do(&conn); - - /* for non 3rd party transfer only */ - if(res == CURLE_OK && !data->set.source_host) { - res = Transfer(conn); /* now fetch that URL please */ - if(res == CURLE_OK) { - - if((conn->keep.bytecount+conn->headerbytecount == 0) && - conn->bits.reuse) { - /* We got no data and we attempted to re-use a connection. This - might happen if the connection was left alive when we were done - using it before, but that was closed when we wanted to read - from it again. Bad luck. Retry the same request on a fresh - connect! */ - infof(data, "Connection died, retrying a fresh connect\n"); - newurl = strdup(conn->data->change.url); - - conn->bits.close = TRUE; /* close this connection */ - conn->bits.retry = TRUE; /* mark this as a connection we're about - to retry. Marking it this way should - prevent i.e HTTP transfers to return - error just because nothing has been - transfered! */ - } - else - /* - * We must duplicate the new URL here as the connection data - * may be free()ed in the Curl_done() function. - */ - newurl = conn->newurl?strdup(conn->newurl):NULL; - } - else { - /* The transfer phase returned error, we mark the connection to get - * closed to prevent being re-used. This is becasue we can't - * possibly know if the connection is in a good shape or not now. */ - conn->bits.close = TRUE; - - if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET]) { - /* if we failed anywhere, we must clean up the secondary socket if - it was used */ - sclose(conn->sock[SECONDARYSOCKET]); - conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; - } - } - - /* Always run Curl_done(), even if some of the previous calls - failed, but return the previous (original) error code */ - res2 = Curl_done(&conn, res); - - if(CURLE_OK == res) - res = res2; - } - else - /* Curl_do() failed, clean up left-overs in the done-call */ - res2 = Curl_done(&conn, res); - - (void)res2; - - /* - * Important: 'conn' cannot be used here, since it may have been closed - * in 'Curl_done' or other functions. - */ - - if((res == CURLE_OK) && newurl) { - res = Curl_follow(data, newurl); - if(CURLE_OK == res) { - newurl = NULL; - continue; - } - } - } - break; /* it only reaches here when this shouldn't loop */ - - } while(1); /* loop if Location: */ - - if(newurl) - free(newurl); - - /* run post-transfer uncondionally, but don't clobber the return code if - we already have an error code recorder */ - res2 = Curl_posttransfer(data); - if(!res && res2) - res = res2; - - return res; -} - -/* - * Curl_Transfer() is called to setup some basic properties for the upcoming - * transfer. - */ -CURLcode -Curl_Transfer(struct connectdata *c_conn, /* connection data */ - int sockindex, /* socket index to read from or -1 */ - curl_off_t size, /* -1 if unknown at this point */ - bool getheader, /* TRUE if header parsing is wanted */ - curl_off_t *bytecountp, /* return number of bytes read or NULL */ - int writesockindex, /* socket index to write to, it may very - well be the same we read from. -1 - disables */ - curl_off_t *writecountp /* return number of bytes written or - NULL */ - ) -{ - struct connectdata *conn = (struct connectdata *)c_conn; - if(!conn) - return CURLE_BAD_FUNCTION_ARGUMENT; - - curlassert((sockindex <= 1) && (sockindex >= -1)); - - /* now copy all input parameters */ - conn->sockfd = sockindex==-1? - CURL_SOCKET_BAD:conn->sock[sockindex]; - conn->size = size; - conn->bits.getheader = getheader; - conn->bytecountp = bytecountp; - conn->writesockfd = writesockindex==-1? - CURL_SOCKET_BAD:conn->sock[writesockindex]; - conn->writebytecountp = writecountp; - - return CURLE_OK; - -} - -/* - * Curl_pretransfersec() prepares the secondary connection (used for 3rd party - * FTP transfers). - */ -CURLcode Curl_pretransfersec(struct connectdata *conn) -{ - CURLcode status; - struct SessionHandle *data = conn->data; - struct connectdata *sec_conn = NULL; /* secondary connection */ - - /* update data with source host options */ - char *url = aprintf( "%s://%s/", conn->protostr, data->set.source_host); - - if(!url) - return CURLE_OUT_OF_MEMORY; - - if(data->change.url_alloc) - free(data->change.url); - - data->change.url_alloc = TRUE; - data->change.url = url; - data->set.ftpport = data->set.source_port; - data->set.userpwd = data->set.source_userpwd; - - /* secondary connection */ - status = Curl_connect_host(data, &sec_conn); - if(CURLE_OK == status) { - sec_conn->data = data; - conn->sec_conn = sec_conn; - } - - return status; -} diff --git a/Source/CTest/Curl/transfer.h b/Source/CTest/Curl/transfer.h deleted file mode 100644 index 1b7eb82..0000000 --- a/Source/CTest/Curl/transfer.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef __TRANSFER_H -#define __TRANSFER_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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_perform(struct SessionHandle *data); -CURLcode Curl_pretransfer(struct SessionHandle *data); -CURLcode Curl_pretransfersec(struct connectdata *conn); -CURLcode Curl_posttransfer(struct SessionHandle *data); -CURLcode Curl_follow(struct SessionHandle *data, char *newurl); -CURLcode Curl_readwrite(struct connectdata *conn, bool *done); -void Curl_single_fdset(struct connectdata *conn, - fd_set *read_fd_set, - fd_set *write_fd_set, - fd_set *exc_fd_set, - int *max_fd); -CURLcode Curl_readwrite_init(struct connectdata *conn); - -CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp); - -/* This sets up a forthcoming transfer */ -CURLcode -Curl_Transfer (struct connectdata *data, - int sockindex, /* socket index to read from or -1 */ - curl_off_t size, /* -1 if unknown at this point */ - bool getheader, /* TRUE if header parsing is wanted */ - curl_off_t *bytecountp, /* return number of bytes read */ - int writesockindex, /* socket index to write to, it may - very well be the same we read from. - -1 disables */ - curl_off_t *writecountp /* return number of bytes written */ -); -#endif diff --git a/Source/CTest/Curl/url.c b/Source/CTest/Curl/url.c deleted file mode 100644 index b532e20..0000000 --- a/Source/CTest/Curl/url.c +++ /dev/null @@ -1,3686 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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$ - ***************************************************************************/ - -/* -- WIN32 approved -- */ - -#include "setup.h" - -#include <stdio.h> -#include <string.h> -#include <stdarg.h> -#include <stdlib.h> -#include <ctype.h> -#include <sys/types.h> -#include <sys/stat.h> - -#include <errno.h> - -#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__) -#include <time.h> -#include <io.h> -#else -#ifdef HAVE_SYS_SOCKET_H -#include <sys/socket.h> -#endif -#include <netinet/in.h> -#include <sys/time.h> -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif -#include <netdb.h> -#ifdef HAVE_ARPA_INET_H -#include <arpa/inet.h> -#endif -#ifdef HAVE_NET_IF_H -#include <net/if.h> -#endif -#include <sys/ioctl.h> -#include <signal.h> - -#ifdef HAVE_SYS_PARAM_H -#include <sys/param.h> -#endif - -#ifdef HAVE_SYS_SELECT_H -#include <sys/select.h> -#endif - -#ifdef VMS -#include <in.h> -#include <inet.h> -#endif - -#ifdef HAVE_SETJMP_H -#include <setjmp.h> -#endif - -#ifndef HAVE_SELECT -#error "We can't compile without select() support!" -#endif -#ifndef HAVE_SOCKET -#error "We can't compile without socket() support!" -#endif - - -#endif - -#ifdef USE_LIBIDN -#include <idna.h> -#include <stringprep.h> -#ifdef HAVE_IDN_FREE_H -#include <idn-free.h> -#else -void idn_free (void *ptr); /* prototype from idn-free.h, not provided by - libidn 0.4.5's make install! */ -#endif -#ifndef HAVE_IDN_FREE -/* if idn_free() was not found in this version of libidn, use plain free() - instead */ -#define idn_free(x) (free)(x) -#endif -#endif - -#ifdef HAVE_OPENSSL_ENGINE_H -#include <openssl/engine.h> -#endif -#include "urldata.h" -#include "netrc.h" - -#include "formdata.h" -#include "base64.h" -#include "ssluse.h" -#include "hostip.h" -#include "if2ip.h" -#include "transfer.h" -#include "sendf.h" -#include "progress.h" -#include "cookie.h" -#include "strequal.h" -#include "escape.h" -#include "strtok.h" -#include "share.h" -#include "content_encoding.h" -#include "http_digest.h" -#include "http_negotiate.h" - -/* And now for the protocols */ -#include "ftp.h" -#include "dict.h" -#include "telnet.h" -#include "http.h" -#include "file.h" -#include "ldap.h" -#include "url.h" -#include "connect.h" -#include "inet_ntop.h" -#include <ca-bundle.h> - -#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL) -#include "inet_ntoa_r.h" -#endif - -#define _MPRINTF_REPLACE /* use our functions only */ -#include <curl/mprintf.h> - -#ifdef HAVE_KRB4 -#include "security.h" -#endif -#include "curl_memory.h" - -/* The last #include file should be: */ -#include "memdebug.h" - -/* Local static prototypes */ -static long ConnectionKillOne(struct SessionHandle *data); -static bool ConnectionExists(struct SessionHandle *data, - struct connectdata *needle, - struct connectdata **usethis); -static long ConnectionStore(struct SessionHandle *data, - struct connectdata *conn); -static bool safe_strequal(char* str1, char* str2); - -#ifndef USE_ARES -/* not for Win32, unless it is cygwin - not for ares builds */ -#if !defined(WIN32) || defined(__CYGWIN32__) - -#ifndef RETSIGTYPE -#define RETSIGTYPE void -#endif -#ifdef HAVE_SIGSETJMP -extern sigjmp_buf curl_jmpenv; -#endif -static -RETSIGTYPE alarmfunc(int sig) -{ - /* this is for "-ansi -Wall -pedantic" to stop complaining! (rabe) */ - (void)sig; -#ifdef HAVE_SIGSETJMP - siglongjmp(curl_jmpenv, 1); -#endif - return; -} -#endif -#endif /* USE_ARES */ - -void Curl_safefree(void *ptr) -{ - if(ptr) - free(ptr); -} - -/* - * This is the internal function curl_easy_cleanup() calls. This should - * cleanup and free all resources associated with this sessionhandle. - * - * NOTE: if we ever add something that attempts to write to a socket or - * similar here, we must ignore SIGPIPE first. It is currently only done - * when curl_easy_perform() is invoked. - */ - -CURLcode Curl_close(struct SessionHandle *data) -{ - /* Loop through all open connections and kill them one by one */ - while(-1 != ConnectionKillOne(data)); - -#ifdef USE_SSLEAY - /* Close down all open SSL info and sessions */ - Curl_SSL_Close_All(data); -#endif - - if(data->change.cookielist) /* clean up list if any */ - curl_slist_free_all(data->change.cookielist); - - Curl_safefree(data->state.auth_host); - Curl_safefree(data->state.scratch); - - if(data->change.proxy_alloc) - free(data->change.proxy); - - if(data->change.referer_alloc) - free(data->change.referer); - - if(data->change.url_alloc) - free(data->change.url); - - Curl_safefree(data->state.headerbuff); - -#ifndef CURL_DISABLE_HTTP - Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); - if(data->set.cookiejar) { - /* we have a "destination" for all the cookies to get dumped to */ - if(Curl_cookie_output(data->cookies, data->set.cookiejar)) - infof(data, "WARNING: failed to save cookies in %s\n", - data->set.cookiejar); - } - - if( !data->share || (data->cookies != data->share->cookies) ) { - Curl_cookie_cleanup(data->cookies); - } - Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); - - Curl_digest_cleanup(data); -#endif - - /* free the connection cache */ - free(data->state.connects); - - Curl_safefree(data->info.contenttype); - -#ifdef USE_ARES - /* this destroys the channel and we cannot use it anymore after this */ - ares_destroy(data->state.areschannel); -#endif - - /* No longer a dirty share, if it exists */ - if (data->share) - data->share->dirty--; - - free(data); - return CURLE_OK; -} - -/** - * Curl_open() - * - * @param curl is a pointer to a sessionhandle pointer that gets set by this - * function. - * @return CURLcode - */ - -CURLcode Curl_open(struct SessionHandle **curl) -{ - CURLcode res = CURLE_OK; - struct SessionHandle *data; - /* Very simple start-up: alloc the struct, init it with zeroes and return */ - data = (struct SessionHandle *)calloc(1, sizeof(struct SessionHandle)); - if(!data) - /* this is a very serious error */ - return CURLE_OUT_OF_MEMORY; - -#ifdef USE_ARES - if(ARES_SUCCESS != ares_init(&data->state.areschannel)) { - free(data); - return CURLE_FAILED_INIT; - } - /* make sure that all other returns from this function should destroy the - ares channel before returning error! */ -#endif - - /* We do some initial setup here, all those fields that can't be just 0 */ - - data->state.headerbuff=(char*)malloc(HEADERSIZE); - if(!data->state.headerbuff) - res = CURLE_OUT_OF_MEMORY; - else { - data->state.headersize=HEADERSIZE; - - data->set.out = stdout; /* default output to stdout */ - data->set.in = stdin; /* default input from stdin */ - data->set.err = stderr; /* default stderr to stderr */ - - /* use fwrite as default function to store output */ - data->set.fwrite = (curl_write_callback)fwrite; - - /* use fread as default function to read input */ - data->set.fread = (curl_read_callback)fread; - - data->set.infilesize = -1; /* we don't know any size */ - - data->state.current_speed = -1; /* init to negative == impossible */ - - data->set.httpreq = HTTPREQ_GET; /* Default HTTP request */ - data->set.ftp_use_epsv = TRUE; /* FTP defaults to EPSV operations */ - data->set.ftp_use_eprt = TRUE; /* FTP defaults to EPRT operations */ - - data->set.dns_cache_timeout = 60; /* Timeout every 60 seconds by default */ - - /* make libcurl quiet by default: */ - data->set.hide_progress = TRUE; /* CURLOPT_NOPROGRESS changes these */ - data->progress.flags |= PGRS_HIDE; - - /* Set the default size of the SSL session ID cache */ - data->set.ssl.numsessions = 5; - - data->set.proxyport = 1080; - data->set.proxytype = CURLPROXY_HTTP; /* defaults to HTTP proxy */ - data->set.httpauth = CURLAUTH_BASIC; /* defaults to basic */ - data->set.proxyauth = CURLAUTH_BASIC; /* defaults to basic */ - - /* create an array with connection data struct pointers */ - data->state.numconnects = 5; /* hard-coded right now */ - data->state.connects = (struct connectdata **) - malloc(sizeof(struct connectdata *) * data->state.numconnects); - - if(!data->state.connects) - res = CURLE_OUT_OF_MEMORY; - else - memset(data->state.connects, 0, - sizeof(struct connectdata *)*data->state.numconnects); - - /* - * libcurl 7.10 introduced SSL verification *by default*! This needs to be - * switched off unless wanted. - */ - data->set.ssl.verifypeer = TRUE; - data->set.ssl.verifyhost = 2; -#ifdef CURL_CA_BUNDLE - /* This is our prefered CA cert bundle since install time */ - data->set.ssl.CAfile = (char *)CURL_CA_BUNDLE; -#endif - } - - if(res) { -#ifdef USE_ARES - ares_destroy(data->state.areschannel); -#endif - if(data->state.headerbuff) - free(data->state.headerbuff); - free(data); - data = NULL; - } - - *curl = data; - return CURLE_OK; -} - -CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) -{ - va_list param; - char *cookiefile; - - va_start(param, option); - - switch(option) { - case CURLOPT_DNS_CACHE_TIMEOUT: - data->set.dns_cache_timeout = va_arg(param, int); - break; - case CURLOPT_DNS_USE_GLOBAL_CACHE: - { - int use_cache = va_arg(param, int); - if (use_cache) { - Curl_global_host_cache_init(); - } - - data->set.global_dns_cache = use_cache; - } - break; - case CURLOPT_SSL_CIPHER_LIST: - /* set a list of cipher we want to use in the SSL connection */ - data->set.ssl.cipher_list = va_arg(param, char *); - break; - - case CURLOPT_RANDOM_FILE: - /* - * This is the path name to a file that contains random data to seed - * the random SSL stuff with. The file is only used for reading. - */ - data->set.ssl.random_file = va_arg(param, char *); - break; - case CURLOPT_EGDSOCKET: - /* - * The Entropy Gathering Daemon socket pathname - */ - data->set.ssl.egdsocket = va_arg(param, char *); - break; - case CURLOPT_MAXCONNECTS: - /* - * Set the absolute number of maximum simultaneous alive connection that - * libcurl is allowed to have. - */ - { - long newconnects= va_arg(param, long); - struct connectdata **newptr; - long i; - - if(newconnects < data->state.numconnects) { - /* Since this number is *decreased* from the existing number, we must - close the possibly open connections that live on the indexes that - are being removed! */ - for(i=newconnects; i< data->state.numconnects; i++) - Curl_disconnect(data->state.connects[i]); - } - if(newconnects) { - newptr= (struct connectdata **) - realloc(data->state.connects, - sizeof(struct connectdata *) * newconnects); - if(!newptr) - /* we closed a few connections in vain, but so what? */ - return CURLE_OUT_OF_MEMORY; - - /* nullify the newly added pointers */ - for(i=data->state.numconnects; i<newconnects; i++) { - newptr[i] = NULL; - } - - data->state.connects = newptr; - data->state.numconnects = newconnects; - } - else { - /* zero makes NO cache at all */ - if(data->state.connects) - free(data->state.connects); - data->state.connects=NULL; - data->state.numconnects=0; - } - } - break; - case CURLOPT_FORBID_REUSE: - /* - * When this transfer is done, it must not be left to be reused by a - * subsequent transfer but shall be closed immediately. - */ - data->set.reuse_forbid = va_arg(param, long)?TRUE:FALSE; - break; - case CURLOPT_FRESH_CONNECT: - /* - * This transfer shall not use a previously cached connection but - * should be made with a fresh new connect! - */ - data->set.reuse_fresh = va_arg(param, long)?TRUE:FALSE; - break; - case CURLOPT_VERBOSE: - /* - * Verbose means infof() calls that give a lot of information about - * the connection and transfer procedures as well as internal choices. - */ - data->set.verbose = va_arg(param, long)?TRUE:FALSE; - break; - case CURLOPT_HEADER: - /* - * Set to include the header in the general data output stream. - */ - data->set.include_header = va_arg(param, long)?TRUE:FALSE; - break; - case CURLOPT_NOPROGRESS: - /* - * Shut off the internal supported progress meter - */ - data->set.hide_progress = va_arg(param, long)?TRUE:FALSE; - if(data->set.hide_progress) - data->progress.flags |= PGRS_HIDE; - else - data->progress.flags &= ~PGRS_HIDE; - break; - case CURLOPT_NOBODY: - /* - * Do not include the body part in the output data stream. - */ - data->set.opt_no_body = va_arg(param, long)?TRUE:FALSE; - if(data->set.opt_no_body) - /* in HTTP lingo, this means using the HEAD request */ - data->set.httpreq = HTTPREQ_HEAD; - break; - case CURLOPT_FAILONERROR: - /* - * Don't output the >=300 error code HTML-page, but instead only - * return error. - */ - data->set.http_fail_on_error = va_arg(param, long)?TRUE:FALSE; - break; - case CURLOPT_UPLOAD: - case CURLOPT_PUT: - /* - * We want to sent data to the remote host. If this is HTTP, that equals - * using the PUT request. - */ - data->set.upload = va_arg(param, long)?TRUE:FALSE; - if(data->set.upload) - /* If this is HTTP, PUT is what's needed to "upload" */ - data->set.httpreq = HTTPREQ_PUT; - break; - case CURLOPT_FILETIME: - /* - * Try to get the file time of the remote document. The time will - * later (possibly) become available using curl_easy_getinfo(). - */ - data->set.get_filetime = va_arg(param, long)?TRUE:FALSE; - break; - case CURLOPT_FTP_CREATE_MISSING_DIRS: - /* - * An FTP option that modifies an upload to create missing directories on - * the server. - */ - data->set.ftp_create_missing_dirs = va_arg( param , long )?TRUE:FALSE; - break; - case CURLOPT_FTP_RESPONSE_TIMEOUT: - /* - * An FTP option that specifies how quickly an FTP response must be - * obtained before it is considered failure. - */ - data->set.ftp_response_timeout = va_arg( param , long ); - break; - case CURLOPT_FTPLISTONLY: - /* - * An FTP option that changes the command to one that asks for a list - * only, no file info details. - */ - data->set.ftp_list_only = va_arg(param, long)?TRUE:FALSE; - break; - case CURLOPT_FTPAPPEND: - /* - * We want to upload and append to an existing (FTP) file. - */ - data->set.ftp_append = va_arg(param, long)?TRUE:FALSE; - break; - case CURLOPT_NETRC: - /* - * Parse the $HOME/.netrc file - */ - data->set.use_netrc = (enum CURL_NETRC_OPTION)va_arg(param, long); - break; - case CURLOPT_NETRC_FILE: - /* - * Use this file instead of the $HOME/.netrc file - */ - data->set.netrc_file = va_arg(param, char *); - break; - case CURLOPT_TRANSFERTEXT: - /* - * This option was previously named 'FTPASCII'. Renamed to work with - * more protocols than merely FTP. - * - * Transfer using ASCII (instead of BINARY). - */ - data->set.ftp_ascii = va_arg(param, long)?TRUE:FALSE; - break; - case CURLOPT_TIMECONDITION: - /* - * Set HTTP time condition. This must be one of the defines in the - * curl/curl.h header file. - */ - data->set.timecondition = (curl_TimeCond)va_arg(param, long); - break; - case CURLOPT_TIMEVALUE: - /* - * This is the value to compare with the remote document with the - * method set with CURLOPT_TIMECONDITION - */ - data->set.timevalue = (time_t)va_arg(param, long); - break; - case CURLOPT_SSLVERSION: - /* - * Set explicit SSL version to try to connect with, as some SSL - * implementations are lame. - */ - data->set.ssl.version = va_arg(param, long); - break; - -#ifndef CURL_DISABLE_HTTP - case CURLOPT_AUTOREFERER: - /* - * Switch on automatic referer that gets set if curl follows locations. - */ - data->set.http_auto_referer = va_arg(param, long)?1:0; - break; - - case CURLOPT_ENCODING: - /* - * String to use at the value of Accept-Encoding header. - * - * If the encoding is set to "" we use an Accept-Encoding header that - * encompasses all the encodings we support. - * If the encoding is set to NULL we don't send an Accept-Encoding header - * and ignore an received Content-Encoding header. - * - */ - data->set.encoding = va_arg(param, char *); - if(data->set.encoding && !*data->set.encoding) - data->set.encoding = (char*)ALL_CONTENT_ENCODINGS; - break; - - case CURLOPT_FOLLOWLOCATION: - /* - * Follow Location: header hints on a HTTP-server. - */ - data->set.http_follow_location = va_arg(param, long)?TRUE:FALSE; - break; - - case CURLOPT_UNRESTRICTED_AUTH: - /* - * Send authentication (user+password) when following locations, even when - * hostname changed. - */ - data->set.http_disable_hostname_check_before_authentication = - va_arg(param, long)?TRUE:FALSE; - break; - - case CURLOPT_MAXREDIRS: - /* - * The maximum amount of hops you allow curl to follow Location: - * headers. This should mostly be used to detect never-ending loops. - */ - data->set.maxredirs = va_arg(param, long); - break; - - case CURLOPT_POST: - /* Does this option serve a purpose anymore? Yes it does, when - CURLOPT_POSTFIELDS isn't used and the POST data is read off the - callback! */ - if(va_arg(param, long)) - data->set.httpreq = HTTPREQ_POST; - break; - - case CURLOPT_POSTFIELDS: - /* - * A string with POST data. Makes curl HTTP POST. - */ - data->set.postfields = va_arg(param, char *); - if(data->set.postfields) - data->set.httpreq = HTTPREQ_POST; - break; - - case CURLOPT_POSTFIELDSIZE: - /* - * The size of the POSTFIELD data to prevent libcurl to do strlen() to - * figure it out. Enables binary posts. - */ - data->set.postfieldsize = va_arg(param, long); - break; - - case CURLOPT_POSTFIELDSIZE_LARGE: - /* - * The size of the POSTFIELD data to prevent libcurl to do strlen() to - * figure it out. Enables binary posts. - */ - data->set.postfieldsize = va_arg(param, curl_off_t); - break; - - case CURLOPT_HTTPPOST: - /* - * Set to make us do HTTP POST - */ - data->set.httppost = va_arg(param, struct curl_httppost *); - if(data->set.httppost) - data->set.httpreq = HTTPREQ_POST_FORM; - break; - - case CURLOPT_REFERER: - /* - * String to set in the HTTP Referer: field. - */ - if(data->change.referer_alloc) { - free(data->change.referer); - data->change.referer_alloc = FALSE; - } - data->set.set_referer = va_arg(param, char *); - data->change.referer = data->set.set_referer; - break; - - case CURLOPT_USERAGENT: - /* - * String to use in the HTTP User-Agent field - */ - data->set.useragent = va_arg(param, char *); - break; - - case CURLOPT_HTTPHEADER: - /* - * Set a list with HTTP headers to use (or replace internals with) - */ - data->set.headers = va_arg(param, struct curl_slist *); - break; - - case CURLOPT_HTTP200ALIASES: - /* - * Set a list of aliases for HTTP 200 in response header - */ - data->set.http200aliases = va_arg(param, struct curl_slist *); - break; - - case CURLOPT_COOKIE: - /* - * Cookie string to send to the remote server in the request. - */ - data->set.cookie = va_arg(param, char *); - break; - - case CURLOPT_COOKIEFILE: - /* - * Set cookie file to read and parse. Can be used multiple times. - */ - cookiefile = (char *)va_arg(param, void *); - if(cookiefile) { - struct curl_slist *cl; - /* append the cookie file name to the list of file names, and deal with - them later */ - cl = curl_slist_append(data->change.cookielist, cookiefile); - - if(!cl) - return CURLE_OUT_OF_MEMORY; - - data->change.cookielist = cl; - } - break; - - case CURLOPT_COOKIEJAR: - /* - * Set cookie file name to dump all cookies to when we're done. - */ - data->set.cookiejar = (char *)va_arg(param, void *); - - /* - * Activate the cookie parser. This may or may not already - * have been made. - */ - data->cookies = Curl_cookie_init(data, NULL, data->cookies, - data->set.cookiesession); - break; - - case CURLOPT_COOKIESESSION: - /* - * Set this option to TRUE to start a new "cookie session". It will - * prevent the forthcoming read-cookies-from-file actions to accept - * cookies that are marked as being session cookies, as they belong to a - * previous session. - * - * In the original Netscape cookie spec, "session cookies" are cookies - * with no expire date set. RFC2109 describes the same action if no - * 'Max-Age' is set and RFC2965 includes the RFC2109 description and adds - * a 'Discard' action that can enforce the discard even for cookies that - * have a Max-Age. - * - * We run mostly with the original cookie spec, as hardly anyone implements - * anything else. - */ - data->set.cookiesession = (bool)va_arg(param, long); - break; - - case CURLOPT_HTTPGET: - /* - * Set to force us do HTTP GET - */ - if(va_arg(param, long)) { - data->set.httpreq = HTTPREQ_GET; - data->set.upload = FALSE; /* switch off upload */ - } - break; - - case CURLOPT_HTTP_VERSION: - /* - * This sets a requested HTTP version to be used. The value is one of - * the listed enums in curl/curl.h. - */ - data->set.httpversion = va_arg(param, long); - break; - - case CURLOPT_HTTPPROXYTUNNEL: - /* - * Tunnel operations through the proxy instead of normal proxy use - */ - data->set.tunnel_thru_httpproxy = va_arg(param, long)?TRUE:FALSE; - break; - - case CURLOPT_CUSTOMREQUEST: - /* - * Set a custom string to use as request - */ - data->set.customrequest = va_arg(param, char *); - - /* we don't set - data->set.httpreq = HTTPREQ_CUSTOM; - here, we continue as if we were using the already set type - and this just changes the actual request keyword */ - break; - - case CURLOPT_PROXY: - /* - * Set proxy server:port to use as HTTP proxy. - * - * If the proxy is set to "" we explicitly say that we don't want to use a - * proxy (even though there might be environment variables saying so). - * - * Setting it to NULL, means no proxy but allows the environment variables - * to decide for us. - */ - if(data->change.proxy_alloc) { - /* - * The already set string is allocated, free that first - */ - data->change.proxy_alloc=FALSE;; - free(data->change.proxy); - } - data->set.set_proxy = va_arg(param, char *); - data->change.proxy = data->set.set_proxy; - break; - - case CURLOPT_PROXYPORT: - /* - * Explicitly set HTTP proxy port number. - */ - data->set.proxyport = va_arg(param, long); - break; - - case CURLOPT_HTTPAUTH: - /* - * Set HTTP Authentication type BITMASK. - */ - { - long auth = va_arg(param, long); - /* switch off bits we can't support */ -#ifndef USE_SSLEAY - auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */ -#endif -#ifndef HAVE_GSSAPI - auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI */ -#endif - if(!auth) - return CURLE_FAILED_INIT; /* no supported types left! */ - - data->set.httpauth = auth; - } - break; - - case CURLOPT_PROXYAUTH: - /* - * Set HTTP Authentication type BITMASK. - */ - { - long auth = va_arg(param, long); - /* switch off bits we can't support */ -#ifndef USE_SSLEAY - auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */ -#endif -#ifndef HAVE_GSSAPI - auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI */ -#endif - if(!auth) - return CURLE_FAILED_INIT; /* no supported types left! */ - - data->set.proxyauth = auth; - } - break; -#endif /* CURL_DISABLE_HTTP */ - - case CURLOPT_WRITEHEADER: - /* - * Custom pointer to pass the header write callback function - */ - data->set.writeheader = (void *)va_arg(param, void *); - break; - case CURLOPT_ERRORBUFFER: - /* - * Error buffer provided by the caller to get the human readable - * error string in. - */ - data->set.errorbuffer = va_arg(param, char *); - break; - case CURLOPT_FILE: - /* - * FILE pointer to write to or include in the data write callback - */ - data->set.out = va_arg(param, FILE *); - break; - case CURLOPT_FTPPORT: - /* - * Use FTP PORT, this also specifies which IP address to use - */ - data->set.ftpport = va_arg(param, char *); - data->set.ftp_use_port = data->set.ftpport?1:0; - break; - - case CURLOPT_FTP_USE_EPRT: - data->set.ftp_use_eprt = va_arg(param, long)?TRUE:FALSE; - break; - - case CURLOPT_FTP_USE_EPSV: - data->set.ftp_use_epsv = va_arg(param, long)?TRUE:FALSE; - break; - - case CURLOPT_INFILE: - /* - * FILE pointer to read the file to be uploaded from. Or possibly - * used as argument to the read callback. - */ - data->set.in = va_arg(param, FILE *); - break; - case CURLOPT_INFILESIZE: - /* - * If known, this should inform curl about the file size of the - * to-be-uploaded file. - */ - data->set.infilesize = va_arg(param, long); - break; - case CURLOPT_INFILESIZE_LARGE: - /* - * If known, this should inform curl about the file size of the - * to-be-uploaded file. - */ - data->set.infilesize = va_arg(param, curl_off_t); - break; - case CURLOPT_LOW_SPEED_LIMIT: - /* - * The low speed limit that if transfers are below this for - * CURLOPT_LOW_SPEED_TIME, the transfer is aborted. - */ - data->set.low_speed_limit=va_arg(param, long); - break; - case CURLOPT_LOW_SPEED_TIME: - /* - * The low speed time that if transfers are below the set - * CURLOPT_LOW_SPEED_LIMIT during this time, the transfer is aborted. - */ - data->set.low_speed_time=va_arg(param, long); - break; - case CURLOPT_URL: - /* - * The URL to fetch. - */ - if(data->change.url_alloc) { - /* the already set URL is allocated, free it first! */ - free(data->change.url); - data->change.url_alloc=FALSE; - } - data->set.set_url = va_arg(param, char *); - data->change.url = data->set.set_url; - data->change.url_changed = TRUE; - break; - case CURLOPT_PORT: - /* - * The port number to use when getting the URL - */ - data->set.use_port = va_arg(param, long); - break; - case CURLOPT_TIMEOUT: - /* - * The maximum time you allow curl to use for a single transfer - * operation. - */ - data->set.timeout = va_arg(param, long); - break; - case CURLOPT_CONNECTTIMEOUT: - /* - * The maximum time you allow curl to use to connect. - */ - data->set.connecttimeout = va_arg(param, long); - break; - - case CURLOPT_USERPWD: - /* - * user:password to use in the operation - */ - data->set.userpwd = va_arg(param, char *); - break; - case CURLOPT_POSTQUOTE: - /* - * List of RAW FTP commands to use after a transfer - */ - data->set.postquote = va_arg(param, struct curl_slist *); - break; - case CURLOPT_PREQUOTE: - /* - * List of RAW FTP commands to use prior to RETR (Wesley Laxton) - */ - data->set.prequote = va_arg(param, struct curl_slist *); - break; - case CURLOPT_QUOTE: - /* - * List of RAW FTP commands to use before a transfer - */ - data->set.quote = va_arg(param, struct curl_slist *); - break; - case CURLOPT_PROGRESSFUNCTION: - /* - * Progress callback function - */ - data->set.fprogress = va_arg(param, curl_progress_callback); - if(data->set.fprogress) - data->progress.callback = TRUE; /* no longer internal */ - else - data->progress.callback = FALSE; /* NULL enforces internal */ - - break; - case CURLOPT_PROGRESSDATA: - /* - * Custom client data to pass to the progress callback - */ - data->set.progress_client = va_arg(param, void *); - break; - case CURLOPT_PROXYUSERPWD: - /* - * user:password needed to use the proxy - */ - data->set.proxyuserpwd = va_arg(param, char *); - break; - case CURLOPT_RANGE: - /* - * What range of the file you want to transfer - */ - data->set.set_range = va_arg(param, char *); - break; - case CURLOPT_RESUME_FROM: - /* - * Resume transfer at the give file position - */ - data->set.set_resume_from = va_arg(param, long); - break; - case CURLOPT_RESUME_FROM_LARGE: - /* - * Resume transfer at the give file position - */ - data->set.set_resume_from = va_arg(param, curl_off_t); - break; - case CURLOPT_DEBUGFUNCTION: - /* - * stderr write callback. - */ - data->set.fdebug = va_arg(param, curl_debug_callback); - /* - * if the callback provided is NULL, it'll use the default callback - */ - break; - case CURLOPT_DEBUGDATA: - /* - * Set to a void * that should receive all error writes. This - * defaults to CURLOPT_STDERR for normal operations. - */ - data->set.debugdata = va_arg(param, void *); - break; - case CURLOPT_STDERR: - /* - * Set to a FILE * that should receive all error writes. This - * defaults to stderr for normal operations. - */ - data->set.err = va_arg(param, FILE *); - if(!data->set.err) - data->set.err = stderr; - break; - case CURLOPT_HEADERFUNCTION: - /* - * Set header write callback - */ - data->set.fwrite_header = va_arg(param, curl_write_callback); - break; - case CURLOPT_WRITEFUNCTION: - /* - * Set data write callback - */ - data->set.fwrite = va_arg(param, curl_write_callback); - if(!data->set.fwrite) - /* When set to NULL, reset to our internal default function */ - data->set.fwrite = (curl_write_callback)fwrite; - break; - case CURLOPT_READFUNCTION: - /* - * Read data callback - */ - data->set.fread = va_arg(param, curl_read_callback); - if(!data->set.fread) - /* When set to NULL, reset to our internal default function */ - data->set.fread = (curl_read_callback)fread; - break; - case CURLOPT_SSLCERT: - /* - * String that holds file name of the SSL certificate to use - */ - data->set.cert = va_arg(param, char *); - break; - case CURLOPT_SSLCERTTYPE: - /* - * String that holds file type of the SSL certificate to use - */ - data->set.cert_type = va_arg(param, char *); - break; - case CURLOPT_SSLKEY: - /* - * String that holds file name of the SSL certificate to use - */ - data->set.key = va_arg(param, char *); - break; - case CURLOPT_SSLKEYTYPE: - /* - * String that holds file type of the SSL certificate to use - */ - data->set.key_type = va_arg(param, char *); - break; - case CURLOPT_SSLKEYPASSWD: - /* - * String that holds the SSL private key password. - */ - data->set.key_passwd = va_arg(param, char *); - break; - case CURLOPT_SSLENGINE: - /* - * String that holds the SSL crypto engine. - */ -#ifdef HAVE_OPENSSL_ENGINE_H - { - const char *cpTemp = va_arg(param, char *); - ENGINE *e; - if (cpTemp && cpTemp[0]) { - e = ENGINE_by_id(cpTemp); - if (e) { - if (data->engine) { - ENGINE_free(data->engine); - } - data->engine = e; - } - else { - failf(data, "SSL Engine '%s' not found", cpTemp); - return CURLE_SSL_ENGINE_NOTFOUND; - } - } - } - break; -#else - return CURLE_SSL_ENGINE_NOTFOUND; -#endif - case CURLOPT_SSLENGINE_DEFAULT: - /* - * flag to set engine as default. - */ -#ifdef HAVE_OPENSSL_ENGINE_H - if (data->engine) { - if (ENGINE_set_default(data->engine, ENGINE_METHOD_ALL) > 0) { -#ifdef DEBUG - fprintf(stderr,"set default crypto engine\n"); -#endif - } - else { -#ifdef DEBUG - failf(data, "set default crypto engine failed"); -#endif - return CURLE_SSL_ENGINE_SETFAILED; - } - } -#endif - break; - case CURLOPT_CRLF: - /* - * Kludgy option to enable CRLF convertions. Subject for removal. - */ - data->set.crlf = va_arg(param, long)?TRUE:FALSE; - break; - case CURLOPT_INTERFACE: - /* - * Set what interface to bind to when performing an operation and thus - * what from-IP your connection will use. - */ - data->set.device = va_arg(param, char *); - break; - case CURLOPT_KRB4LEVEL: - /* - * A string that defines the krb4 security level. - */ - data->set.krb4_level = va_arg(param, char *); - data->set.krb4=data->set.krb4_level?TRUE:FALSE; - break; - case CURLOPT_SSL_VERIFYPEER: - /* - * Enable peer SSL verifying. - */ - data->set.ssl.verifypeer = va_arg(param, long); - break; - case CURLOPT_SSL_VERIFYHOST: - /* - * Enable verification of the CN contained in the peer certificate - */ - data->set.ssl.verifyhost = va_arg(param, long); - break; - case CURLOPT_SSL_CTX_FUNCTION: - /* - * Set a SSL_CTX callback - */ - data->set.ssl.fsslctx = va_arg(param, curl_ssl_ctx_callback); - break; - case CURLOPT_SSL_CTX_DATA: - /* - * Set a SSL_CTX callback parameter pointer - */ - data->set.ssl.fsslctxp = va_arg(param, void *); - break; - case CURLOPT_CAINFO: - /* - * Set CA info for SSL connection. Specify file name of the CA certificate - */ - data->set.ssl.CAfile = va_arg(param, char *); - break; - case CURLOPT_CAPATH: - /* - * Set CA path info for SSL connection. Specify directory name of the CA - * certificates which have been prepared using openssl c_rehash utility. - */ - /* This does not work on windows. */ - data->set.ssl.CApath = va_arg(param, char *); - break; - case CURLOPT_TELNETOPTIONS: - /* - * Set a linked list of telnet options - */ - data->set.telnet_options = va_arg(param, struct curl_slist *); - break; - - case CURLOPT_BUFFERSIZE: - /* - * The application kindly asks for a differently sized receive buffer. - * If it seems reasonable, we'll use it. - */ - data->set.buffer_size = va_arg(param, long); - - if((data->set.buffer_size> (BUFSIZE -1 )) || - (data->set.buffer_size < 1)) - data->set.buffer_size = 0; /* huge internal default */ - - break; - - case CURLOPT_NOSIGNAL: - /* - * The application asks not to set any signal() or alarm() handlers, - * even when using a timeout. - */ - data->set.no_signal = va_arg(param, long) ? TRUE : FALSE; - break; - - case CURLOPT_SHARE: - { - struct Curl_share *set; - set = va_arg(param, struct Curl_share *); - - /* disconnect from old share, if any */ - if(data->share) { - Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE); - - if(data->share->hostcache == data->hostcache) - data->hostcache = NULL; - - if(data->share->cookies == data->cookies) - data->cookies = NULL; - - data->share->dirty--; - - Curl_share_unlock(data, CURL_LOCK_DATA_SHARE); - data->share = NULL; - } - - /* use new share if it set */ - data->share = set; - if(data->share) { - - Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE); - - data->share->dirty++; - - if(data->share->hostcache) { - /* use shared host cache, first free own one if any */ - if(data->hostcache) - Curl_hash_destroy(data->hostcache); - - data->hostcache = data->share->hostcache; - } -#ifndef CURL_DISABLE_HTTP - if(data->share->cookies) { - /* use shared cookie list, first free own one if any */ - if (data->cookies) - Curl_cookie_cleanup(data->cookies); - data->cookies = data->share->cookies; - } -#endif /* CURL_DISABLE_HTTP */ - Curl_share_unlock(data, CURL_LOCK_DATA_SHARE); - - } -#ifndef CURL_DISABLE_HTTP - /* check cookie list is set */ - if(!data->cookies) - data->cookies = Curl_cookie_init(data, NULL, NULL, TRUE ); -#endif /* CURL_DISABLE_HTTP */ - /* check for host cache not needed, - * it will be done by curl_easy_perform */ - } - break; - - case CURLOPT_PROXYTYPE: - /* - * Set proxy type. HTTP/SOCKS4/SOCKS5 - */ - data->set.proxytype = (curl_proxytype)va_arg(param, long); - break; - - case CURLOPT_PRIVATE: - /* - * Set private data pointer. - */ - data->set.private = va_arg(param, char *); - break; - - case CURLOPT_MAXFILESIZE: - /* - * Set the maximum size of a file to download. - */ - data->set.max_filesize = va_arg(param, long); - break; - - case CURLOPT_FTP_SSL: - /* - * Make FTP transfers attempt to use SSL/TLS. - */ - data->set.ftp_ssl = (curl_ftpssl)va_arg(param, long); - break; - - case CURLOPT_IPRESOLVE: - data->set.ip_version = va_arg(param, long); - break; - - case CURLOPT_MAXFILESIZE_LARGE: - /* - * Set the maximum size of a file to download. - */ - data->set.max_filesize = va_arg(param, curl_off_t); - break; - - case CURLOPT_TCP_NODELAY: - /* - * Enable or disable TCP_NODELAY, which will disable/enable the Nagle - * algorithm - */ - data->set.tcp_nodelay = (bool)va_arg(param, long); - break; - - /*********** 3rd party transfer options ***********/ - case CURLOPT_SOURCE_HOST: - /* - * Use SOURCE HOST - */ - data->set.source_host = va_arg(param, char *); - data->set.printhost = (data->set.source_host != NULL); - break; - - case CURLOPT_SOURCE_PORT: - /* - * Use SOURCE PORT - */ - data->set.source_port = va_arg(param, char *); - break; - - case CURLOPT_SOURCE_USERPWD: - /* - * Use SOURCE USER[:PASSWORD] - */ - data->set.source_userpwd = va_arg(param, char *); - break; - - case CURLOPT_SOURCE_PATH: - /* - * Use SOURCE PATH - */ - data->set.source_path = va_arg(param, char *); - break; - - case CURLOPT_PASV_HOST: - /* - * Indicates whether source or target host is passive - */ - data->set.pasvHost = va_arg(param, long)?CURL_SOURCE_PASV:CURL_TARGET_PASV; - break; - - case CURLOPT_SOURCE_PREQUOTE: - /* - * List of RAW FTP commands to use before a transfer on the source host - */ - data->set.source_prequote = va_arg(param, struct curl_slist *); - break; - - case CURLOPT_SOURCE_POSTQUOTE: - /* - * List of RAW FTP commands to use after a transfer on the source host - */ - data->set.source_postquote = va_arg(param, struct curl_slist *); - break; - - default: - /* unknown tag and its companion, just ignore: */ - return CURLE_FAILED_INIT; /* correct this */ - } - return CURLE_OK; -} - -CURLcode Curl_disconnect(struct connectdata *conn) -{ - struct SessionHandle *data; - if(!conn) - return CURLE_OK; /* this is closed and fine already */ - - data = conn->data; - - /* - * The range string is usually freed in curl_done(), but we might - * get here *instead* if we fail prematurely. Thus we need to be able - * to free this resource here as well. - */ - if(conn->bits.rangestringalloc) { - free(conn->range); - conn->bits.rangestringalloc = FALSE; - } - - if((conn->ntlm.state != NTLMSTATE_NONE) || - (conn->proxyntlm.state != NTLMSTATE_NONE)) { - /* Authentication data is a mix of connection-related and sessionhandle- - related stuff. NTLM is connection-related so when we close the shop - we shall forget. */ - data->state.authhost.done = FALSE; - data->state.authhost.picked = - data->state.authhost.want; - - data->state.authproxy.done = FALSE; - data->state.authproxy.picked = - data->state.authhost.want; - - data->state.authproblem = FALSE; - } - - if(conn->curl_disconnect) - /* This is set if protocol-specific cleanups should be made */ - conn->curl_disconnect(conn); - - if(-1 != conn->connectindex) { - /* unlink ourselves! */ - infof(data, "Closing connection #%ld\n", conn->connectindex); - data->state.connects[conn->connectindex] = NULL; - } - - Curl_safefree(conn->proto.generic); - Curl_safefree(conn->newurl); - Curl_safefree(conn->pathbuffer); /* the URL path buffer */ - - Curl_safefree(conn->host.rawalloc); /* host name buffer */ - Curl_safefree(conn->proxy.rawalloc); /* proxy name buffer */ -#ifdef USE_LIBIDN - if(conn->host.encalloc) - idn_free(conn->host.encalloc); /* encoded host name buffer, must be freed - with idn_free() since this was allocated - by libidn */ - if(conn->proxy.encalloc) - idn_free(conn->proxy.encalloc); /* encoded proxy name buffer, must be - freed with idn_free() since this was - allocated by libidn */ -#endif - Curl_SSL_Close(conn); - - /* close possibly still open sockets */ - if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET]) - sclose(conn->sock[SECONDARYSOCKET]); - if(CURL_SOCKET_BAD != conn->sock[FIRSTSOCKET]) - sclose(conn->sock[FIRSTSOCKET]); - - Curl_safefree(conn->user); - Curl_safefree(conn->passwd); - Curl_safefree(conn->proxyuser); - Curl_safefree(conn->proxypasswd); - Curl_safefree(conn->allocptr.proxyuserpwd); - Curl_safefree(conn->allocptr.uagent); - Curl_safefree(conn->allocptr.userpwd); - Curl_safefree(conn->allocptr.accept_encoding); - Curl_safefree(conn->allocptr.rangeline); - Curl_safefree(conn->allocptr.ref); - Curl_safefree(conn->allocptr.host); - Curl_safefree(conn->allocptr.cookiehost); - -#if defined(USE_ARES) || defined(USE_THREADING_GETHOSTBYNAME) || \ - defined(USE_THREADING_GETADDRINFO) - /* possible left-overs from the async name resolve */ - Curl_safefree(conn->async.hostname); - Curl_safefree(conn->async.os_specific); -#endif - - Curl_free_ssl_config(&conn->ssl_config); - - free(conn); /* free all the connection oriented data */ - - return CURLE_OK; -} - -/* - * This function should return TRUE if the socket is to be assumed to - * be dead. Most commonly this happens when the server has closed the - * connection due to inactivity. - */ -static bool SocketIsDead(curl_socket_t sock) -{ - int sval; - bool ret_val = TRUE; - fd_set check_set; - struct timeval to; - - FD_ZERO(&check_set); - FD_SET(sock, &check_set); - - to.tv_sec = 0; - to.tv_usec = 0; - - sval = select(sock + 1, &check_set, 0, 0, &to); - if(sval == 0) - /* timeout */ - ret_val = FALSE; - - return ret_val; -} - -/* - * Given one filled in connection struct (named needle), this function should - * detect if there already is one that have all the significant details - * exactly the same and thus should be used instead. - */ -static bool -ConnectionExists(struct SessionHandle *data, - struct connectdata *needle, - struct connectdata **usethis) -{ - long i; - struct connectdata *check; - - for(i=0; i< data->state.numconnects; i++) { - bool match = FALSE; - /* - * Note that if we use a HTTP proxy, we check connections to that - * proxy and not to the actual remote server. - */ - check = data->state.connects[i]; - if(!check) - /* NULL pointer means not filled-in entry */ - continue; - - if((needle->protocol&PROT_SSL) != (check->protocol&PROT_SSL)) - /* don't do mixed SSL and non-SSL connections */ - continue; - - if(!needle->bits.httpproxy || needle->protocol&PROT_SSL) { - /* The requested connection does not use a HTTP proxy or it - uses SSL. */ - - if(!(needle->protocol&PROT_SSL) && check->bits.httpproxy) - /* we don't do SSL but the cached connection has a proxy, - then don't match this */ - continue; - - if(strequal(needle->protostr, check->protostr) && - strequal(needle->host.name, check->host.name) && - (needle->remote_port == check->remote_port) ) { - if(needle->protocol & PROT_SSL) { - /* This is SSL, verify that we're using the same - ssl options as well */ - if(!Curl_ssl_config_matches(&needle->ssl_config, - &check->ssl_config)) { - continue; - } - } - if((needle->protocol & PROT_FTP) || - ((needle->protocol & PROT_HTTP) && - (needle->data->state.authhost.want==CURLAUTH_NTLM))) { - /* This is FTP or HTTP+NTLM, verify that we're using the same name - and password as well */ - if(!strequal(needle->user, check->user) || - !strequal(needle->passwd, check->passwd)) { - /* one of them was different */ - continue; - } - } - match = TRUE; - } - } - else { /* The requested needle connection is using a proxy, - is the checked one using the same? */ - if(check->bits.httpproxy && - strequal(needle->proxy.name, check->proxy.name) && - needle->port == check->port) { - /* This is the same proxy connection, use it! */ - match = TRUE; - } - } - - if(match) { - bool dead = SocketIsDead(check->sock[FIRSTSOCKET]); - if(dead) { - /* - */ - infof(data, "Connection %d seems to be dead!\n", i); - Curl_disconnect(check); /* disconnect resources */ - data->state.connects[i]=NULL; /* nothing here */ - - /* There's no need to continue searching, because we only store - one connection for each unique set of identifiers */ - return FALSE; - } - - *usethis = check; - return TRUE; /* yes, we found one to use! */ - } - } - return FALSE; /* no matching connecting exists */ -} - -/* - * This function frees/closes a connection in the connection cache. This - * should take the previously set policy into account when deciding which - * of the connections to kill. - */ -static long -ConnectionKillOne(struct SessionHandle *data) -{ - long i; - struct connectdata *conn; - long highscore=-1; - long connindex=-1; - long score; - struct timeval now; - - now = Curl_tvnow(); - - for(i=0; i< data->state.numconnects; i++) { - conn = data->state.connects[i]; - - if(!conn) - continue; - - /* - * By using the set policy, we score each connection. - */ - switch(data->set.closepolicy) { - case CURLCLOSEPOLICY_LEAST_RECENTLY_USED: - default: - /* - * Set higher score for the age passed since the connection - * was used. - */ - score = Curl_tvdiff(now, conn->now); - break; - case CURLCLOSEPOLICY_OLDEST: - /* - * Set higher score for the age passed since the connection - * was created. - */ - score = Curl_tvdiff(now, conn->created); - break; - } - - if(score > highscore) { - highscore = score; - connindex = i; - } - } - if(connindex >= 0) { - - /* the winner gets the honour of being disconnected */ - (void) Curl_disconnect(data->state.connects[connindex]); - - /* clean the array entry */ - data->state.connects[connindex] = NULL; - } - - return connindex; /* return the available index or -1 */ -} - -/* - * The given input connection struct pointer is to be stored. If the "cache" - * is already full, we must clean out the most suitable using the previously - * set policy. - * - * The given connection should be unique. That must've been checked prior to - * this call. - */ -static long -ConnectionStore(struct SessionHandle *data, - struct connectdata *conn) -{ - long i; - for(i=0; i< data->state.numconnects; i++) { - if(!data->state.connects[i]) - break; - } - if(i == data->state.numconnects) { - /* there was no room available, kill one */ - i = ConnectionKillOne(data); - infof(data, "Connection (#%d) was killed to make room\n", i); - } - - if(-1 != i) { - /* only do this if a true index was returned, if -1 was returned there - is no room in the cache for an unknown reason and we cannot store - this there. */ - data->state.connects[i] = conn; /* fill in this */ - conn->connectindex = i; /* make the child know where the pointer to this - particular data is stored */ - } - return i; -} - -/* - * This function logs in to a SOCKS5 proxy and sends the specifies the final - * desitination server. - */ -static int handleSock5Proxy(const char *proxy_name, - const char *proxy_password, - struct connectdata *conn) -{ - /* - According to the RFC1928, section "6. Replies". This is what a SOCK5 - replies: - - +----+-----+-------+------+----------+----------+ - |VER | REP | RSV | ATYP | BND.ADDR | BND.PORT | - +----+-----+-------+------+----------+----------+ - | 1 | 1 | X'00' | 1 | Variable | 2 | - +----+-----+-------+------+----------+----------+ - - Where: - - o VER protocol version: X'05' - o REP Reply field: - o X'00' succeeded - */ - - unsigned char socksreq[600]; /* room for large user/pw (255 max each) */ - ssize_t actualread; - ssize_t written; - int result; - CURLcode code; - int sock = conn->sock[FIRSTSOCKET]; - - Curl_nonblock(sock, FALSE); - - socksreq[0] = 5; /* version */ - socksreq[1] = (char)(proxy_name ? 2 : 1); /* number of methods (below) */ - socksreq[2] = 0; /* no authentication */ - socksreq[3] = 2; /* username/password */ - - code = Curl_write(conn, sock, (char *)socksreq, (2 + (int)socksreq[1]), - &written); - if ((code != CURLE_OK) || (written != (2 + (int)socksreq[1]))) { - failf(conn->data, "Unable to send initial SOCKS5 request."); - return 1; - } - - result=Curl_read(conn, sock, (char *)socksreq, 2, &actualread); - if ((result != CURLE_OK) || (actualread != 2)) { - failf(conn->data, "Unable to receive initial SOCKS5 response."); - return 1; - } - - if (socksreq[0] != 5) { - failf(conn->data, "Received invalid version in initial SOCKS5 response."); - return 1; - } - if (socksreq[1] == 0) { - /* Nothing to do, no authentication needed */ - ; - } - else if (socksreq[1] == 2) { - /* Needs user name and password */ - int userlen, pwlen, len; - - userlen = (int)strlen(proxy_name); - pwlen = proxy_password?(int)strlen(proxy_password):0; - - /* username/password request looks like - * +----+------+----------+------+----------+ - * |VER | ULEN | UNAME | PLEN | PASSWD | - * +----+------+----------+------+----------+ - * | 1 | 1 | 1 to 255 | 1 | 1 to 255 | - * +----+------+----------+------+----------+ - */ - len = 0; - socksreq[len++] = 1; /* username/pw subnegotiation version */ - socksreq[len++] = (char) userlen; - memcpy(socksreq + len, proxy_name, (int) userlen); - len += userlen; - socksreq[len++] = (char) pwlen; - memcpy(socksreq + len, proxy_password, (int) pwlen); - len += pwlen; - - code = Curl_write(conn, sock, (char *)socksreq, len, &written); - if ((code != CURLE_OK) || (len != written)) { - failf(conn->data, "Failed to send SOCKS5 sub-negotiation request."); - return 1; - } - - result=Curl_read(conn, sock, (char *)socksreq, 2, &actualread); - if ((result != CURLE_OK) || (actualread != 2)) { - failf(conn->data, "Unable to receive SOCKS5 sub-negotiation response."); - return 1; - } - - if ((socksreq[0] != 5) || /* version */ - (socksreq[1] != 0)) { /* status */ - failf(conn->data, "User was rejected by the SOCKS5 server (%d %d).", - socksreq[0], socksreq[1]); - return 1; - } - - /* Everything is good so far, user was authenticated! */ - } - else { - /* error */ - if (socksreq[1] == 1) { - failf(conn->data, - "SOCKS5 GSSAPI per-message authentication is not supported."); - return 1; - } - else if (socksreq[1] == 255) { - if (proxy_name[0] == 0) { - failf(conn->data, - "No authentication method was acceptable. (It is quite likely" - " that the SOCKS5 server wanted a username/password, since none" - " was supplied to the server on this connection.)"); - } - else { - failf(conn->data, "No authentication method was acceptable."); - } - return 1; - } - else { - failf(conn->data, - "Undocumented SOCKS5 mode attempted to be used by server."); - return 1; - } - } - - /* Authentication is complete, now specify destination to the proxy */ - socksreq[0] = 5; /* version (SOCKS5) */ - socksreq[1] = 1; /* connect */ - socksreq[2] = 0; /* must be zero */ - socksreq[3] = 1; /* IPv4 = 1 */ - - { - struct Curl_dns_entry *dns; - Curl_addrinfo *hp=NULL; - int rc = Curl_resolv(conn, conn->host.name, (int)conn->remote_port, &dns); - - if(rc == CURLRESOLV_ERROR) - return 1; - - if(rc == CURLRESOLV_PENDING) - /* this requires that we're in "wait for resolve" state */ - rc = Curl_wait_for_resolv(conn, &dns); - (void)rc; - - /* - * We cannot use 'hostent' as a struct that Curl_resolv() returns. It - * returns a Curl_addrinfo pointer that may not always look the same. - */ - if(dns) - hp=dns->addr; - if (hp) { - char buf[64]; - unsigned short ip[4]; - Curl_printable_address(hp, buf, sizeof(buf)); - - if(4 == sscanf( buf, "%hu.%hu.%hu.%hu", - &ip[0], &ip[1], &ip[2], &ip[3])) { - socksreq[4] = (unsigned char)ip[0]; - socksreq[5] = (unsigned char)ip[1]; - socksreq[6] = (unsigned char)ip[2]; - socksreq[7] = (unsigned char)ip[3]; - } - else - hp = NULL; /* fail! */ - - Curl_resolv_unlock(conn->data, dns); /* not used anymore from now on */ - } - if(!hp) { - failf(conn->data, "Failed to resolve \"%s\" for SOCKS5 connect.", - conn->host.name); - return 1; - } - } - - { - unsigned short s = htons(conn->remote_port); - memcpy(socksreq+8, &s, sizeof(unsigned short)); - } - - { - const int packetsize = 10; - - code = Curl_write(conn, sock, (char *)socksreq, packetsize, &written); - if ((code != CURLE_OK) || (written != packetsize)) { - failf(conn->data, "Failed to send SOCKS5 connect request."); - return 1; - } - - result = Curl_read(conn, sock, (char *)socksreq, packetsize, &actualread); - if ((result != CURLE_OK) || (actualread != packetsize)) { - failf(conn->data, "Failed to receive SOCKS5 connect request ack."); - return 1; - } - - if (socksreq[0] != 5) { /* version */ - failf(conn->data, - "SOCKS5 reply has wrong version, version should be 5."); - return 1; - } - if (socksreq[1] != 0) { /* Anything besides 0 is an error */ - unsigned short sh; - memcpy(&sh, socksreq+8, sizeof(unsigned short)); - - failf(conn->data, - "Can't complete SOCKS5 connection to %d.%d.%d.%d:%d. (%d)", - (unsigned char)socksreq[4], (unsigned char)socksreq[5], - (unsigned char)socksreq[6], (unsigned char)socksreq[7], - (unsigned int)ntohs(sh), - socksreq[1]); - return 1; - } - } - - Curl_nonblock(sock, TRUE); - return 0; /* Proxy was successful! */ -} - -static CURLcode ConnectPlease(struct connectdata *conn, - struct Curl_dns_entry *hostaddr, - bool *connected) -{ - CURLcode result; - Curl_addrinfo *addr; - struct SessionHandle *data = conn->data; - char *hostname = data->change.proxy?conn->proxy.name:conn->host.name; - - infof(data, "About to connect() to %s port %d\n", - hostname, conn->port); - - /************************************************************* - * Connect to server/proxy - *************************************************************/ - result= Curl_connecthost(conn, - hostaddr, - &conn->sock[FIRSTSOCKET], - &addr, - connected); - if(CURLE_OK == result) { - /* All is cool, then we store the current information */ - conn->dns_entry = hostaddr; - conn->ip_addr = addr; - - if (conn->data->set.proxytype == CURLPROXY_SOCKS5) { - return handleSock5Proxy(conn->proxyuser, - conn->proxypasswd, - conn) ? - CURLE_COULDNT_CONNECT : CURLE_OK; - } - else if (conn->data->set.proxytype == CURLPROXY_HTTP) { - /* do nothing here. handled later. */ - } - else { - failf(conn->data, "unknown proxytype option given"); - return CURLE_COULDNT_CONNECT; - } - } - - return result; -} - -/* - * verboseconnect() displays verbose information after a connect - */ -static void verboseconnect(struct connectdata *conn) -{ - struct SessionHandle *data = conn->data; - char addrbuf[256]; - - /* Get a printable version of the network address. */ - Curl_printable_address(conn->ip_addr, addrbuf, sizeof(addrbuf)); - infof(data, "Connected to %s (%s) port %d\n", - conn->bits.httpproxy ? conn->proxy.dispname : conn->host.dispname, - addrbuf[0] ? addrbuf : "??", conn->port); -} - -/* - * We have discovered that the TCP connection has been successful, we can now - * proceed with some action. - * - * If we're using the multi interface, this host address pointer is most - * likely NULL at this point as we can't keep the resolved info around. This - * may call for some reworking, like a reference counter in the struct or - * something. - */ -CURLcode Curl_protocol_connect(struct connectdata *conn) -{ - struct SessionHandle *data = conn->data; - CURLcode result=CURLE_OK; - - if(conn->bits.tcpconnect) - /* We already are connected, get back. This may happen when the connect - worked fine in the first call, like when we connect to a local server - or proxy. */ - return CURLE_OK; - - Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */ - - if(data->set.verbose) - verboseconnect(conn); - - if(conn->curl_connect) { - /* is there a protocol-specific connect() procedure? */ - - /* set start time here for timeout purposes in the - * connect procedure, it is later set again for the - * progress meter purpose */ - conn->now = Curl_tvnow(); - - /* Call the protocol-specific connect function */ - result = conn->curl_connect(conn); - } - - return result; /* pass back status */ -} - -/* - * Helpers for IDNA convertions. - */ -#ifdef USE_LIBIDN -static bool is_ASCII_name (const char *hostname) -{ - const unsigned char *ch = (const unsigned char*)hostname; - - while (*ch) { - if (*ch++ & 0x80) - return FALSE; - } - return TRUE; -} -#endif - -static void fix_hostname(struct connectdata *conn, struct hostname *host) -{ - /* set the name we use to display the host name */ - host->dispname = host->name; - -#ifdef USE_LIBIDN - /************************************************************* - * Check name for non-ASCII and convert hostname to ACE form. - *************************************************************/ - if (!is_ASCII_name(host->name) && - stringprep_check_version(LIBIDN_REQUIRED_VERSION)) { - char *ace_hostname = NULL; - struct SessionHandle *data = conn->data; - int rc = idna_to_ascii_lz(host->name, &ace_hostname, 0); - infof (data, "Input domain encoded as `%s'\n", - stringprep_locale_charset ()); - if (rc != IDNA_SUCCESS) - infof(data, "Failed to convert %s to ACE; IDNA error %d\n", - host->name, rc); - else { - host->encalloc = ace_hostname; - /* change the name pointer to point to the encoded hostname */ - host->name = host->encalloc; - } - } -#else - (void)conn; /* never used */ -#endif -} - - -/** - * CreateConnection() sets up a new connectdata struct, or re-uses an already - * existing one, and resolves host name. - * - * if this function returns CURLE_OK and *async is set to TRUE, the resolve - * response will be coming asynchronously. If *async is FALSE, the name is - * already resolved. - * - * @param data The sessionhandle pointer - * @param in_connect is set to the next connection data pointer - * @param addr is set to the new dns entry for this connection - * @param async is set TRUE/FALSE depending on the nature of this lookup - * @return CURLcode - * @see SetupConnection() - */ - -static CURLcode CreateConnection(struct SessionHandle *data, - struct connectdata **in_connect, - struct Curl_dns_entry **addr, - bool *async) -{ - char *tmp; - CURLcode result=CURLE_OK; - struct connectdata *conn; - struct connectdata *conn_temp; - size_t urllen; - struct Curl_dns_entry *hostaddr; -#if defined(HAVE_ALARM) && !defined(USE_ARES) - unsigned int prev_alarm=0; -#endif - char endbracket; - char user[MAX_CURL_USER_LENGTH]; - char passwd[MAX_CURL_PASSWORD_LENGTH]; - int rc; - bool reuse; - -#ifndef USE_ARES -#ifdef SIGALRM -#ifdef HAVE_SIGACTION - struct sigaction keep_sigact; /* store the old struct here */ - bool keep_copysig=FALSE; /* did copy it? */ -#else -#ifdef HAVE_SIGNAL - void *keep_sigact; /* store the old handler here */ -#endif /* HAVE_SIGNAL */ -#endif /* HAVE_SIGACTION */ -#endif /* SIGALRM */ -#endif /* USE_ARES */ - - *addr = NULL; /* nothing yet */ - *async = FALSE; - - /************************************************************* - * Check input data - *************************************************************/ - - if(!data->change.url) - return CURLE_URL_MALFORMAT; - - /* First, split up the current URL in parts so that we can use the - parts for checking against the already present connections. In order - to not have to modify everything at once, we allocate a temporary - connection data struct and fill in for comparison purposes. */ - - conn = (struct connectdata *)malloc(sizeof(struct connectdata)); - if(!conn) { - *in_connect = NULL; /* clear the pointer */ - return CURLE_OUT_OF_MEMORY; - } - /* We must set the return variable as soon as possible, so that our - parent can cleanup any possible allocs we may have done before - any failure */ - *in_connect = conn; - - /* we have to init the struct */ - memset(conn, 0, sizeof(struct connectdata)); - - /* and we setup a few fields in case we end up actually using this struct */ - conn->data = data; /* remember our daddy */ - conn->sock[FIRSTSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */ - conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */ - conn->connectindex = -1; /* no index */ - conn->bits.httpproxy = (data->change.proxy && *data->change.proxy && - (data->set.proxytype == CURLPROXY_HTTP))? - TRUE:FALSE; /* http proxy or not */ - - /* Default protocol-independent behavior doesn't support persistant - connections, so we set this to force-close. Protocols that support - this need to set this to FALSE in their "curl_do" functions. */ - conn->bits.close = TRUE; - - /* maxdownload must be -1 on init, as 0 is a valid value! */ - conn->maxdownload = -1; /* might have been used previously! */ - - /* Store creation time to help future close decision making */ - conn->created = Curl_tvnow(); - - conn->bits.use_range = data->set.set_range?TRUE:FALSE; /* range status */ - conn->range = data->set.set_range; /* clone the range setting */ - conn->resume_from = data->set.set_resume_from; /* inherite resume_from */ - - /* Set the start time temporary to this creation time to allow easier - timeout checks before the transfer has started for real. The start time - is later set "for real" using Curl_pgrsStartNow(). */ - conn->data->progress.start = conn->created; - - conn->bits.user_passwd = data->set.userpwd?1:0; - conn->bits.proxy_user_passwd = data->set.proxyuserpwd?1:0; - conn->bits.no_body = data->set.opt_no_body; - conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy; - - /* This initing continues below, see the comment "Continue connectdata - * initialization here" */ - - /*********************************************************** - * We need to allocate memory to store the path in. We get the size of the - * full URL to be sure, and we need to make it at least 256 bytes since - * other parts of the code will rely on this fact - ***********************************************************/ -#define LEAST_PATH_ALLOC 256 - urllen=strlen(data->change.url); - if(urllen < LEAST_PATH_ALLOC) - urllen=LEAST_PATH_ALLOC; - - conn->pathbuffer=(char *)malloc(urllen); - if(NULL == conn->pathbuffer) - return CURLE_OUT_OF_MEMORY; /* really bad error */ - conn->path = conn->pathbuffer; - - conn->host.rawalloc=(char *)malloc(urllen); - if(NULL == conn->host.rawalloc) - return CURLE_OUT_OF_MEMORY; - conn->host.name = conn->host.rawalloc; - - /************************************************************* - * Parse the URL. - * - * We need to parse the url even when using the proxy, because we will need - * the hostname and port in case we are trying to SSL connect through the - * proxy -- and we don't know if we will need to use SSL until we parse the - * url ... - ************************************************************/ - if((2 == sscanf(data->change.url, "%15[^:]:%[^\n]", - conn->protostr, - conn->path)) && strequal(conn->protostr, "file")) { - if(conn->path[0] == '/' && conn->path[1] == '/') { - /* Allow omitted hostname (e.g. file:/<path>). This is not strictly - * speaking a valid file: URL by RFC 1738, but treating file:/<path> as - * file://localhost/<path> is similar to how other schemes treat missing - * hostnames. See RFC 1808. */ - - /* This cannot be done with strcpy() in a portable manner, since the - memory areas overlap! */ - memmove(conn->path, conn->path + 2, strlen(conn->path + 2)+1); - } - /* - * we deal with file://<host>/<path> differently since it supports no - * hostname other than "localhost" and "127.0.0.1", which is unique among - * the URL protocols specified in RFC 1738 - */ - if(conn->path[0] != '/') { - /* the URL included a host name, we ignore host names in file:// URLs - as the standards don't define what to do with them */ - char *ptr=strchr(conn->path, '/'); - if(ptr) { - /* there was a slash present - - RFC1738 (section 3.1, page 5) says: - - The rest of the locator consists of data specific to the scheme, - and is known as the "url-path". It supplies the details of how the - specified resource can be accessed. Note that the "/" between the - host (or port) and the url-path is NOT part of the url-path. - - As most agents use file://localhost/foo to get '/foo' although the - slash preceeding foo is a separator and not a slash for the path, - a URL as file://localhost//foo must be valid as well, to refer to - the same file with an absolute path. - */ - - if(ptr[1] && ('/' == ptr[1])) - /* if there was two slashes, we skip the first one as that is then - used truly as a separator */ - ptr++; - - /* This cannot be made with strcpy, as the memory chunks overlap! */ - memmove(conn->path, ptr, strlen(ptr)+1); - } - } - - strcpy(conn->protostr, "file"); /* store protocol string lowercase */ - } - else { - /* Set default path */ - strcpy(conn->path, "/"); - - /* We need to search for '/' OR '?' - whichever comes first after host - * name but before the path. We need to change that to handle things like - * http://example.com?param= (notice the missing '/'). Later we'll insert - * that missing slash at the beginning of the path. - */ - if (2 > sscanf(data->change.url, - "%15[^\n:]://%[^\n/?]%[^\n]", - conn->protostr, - conn->host.name, conn->path)) { - - /* - * The URL was badly formatted, let's try the browser-style _without_ - * protocol specified like 'http://'. - */ - if((1 > sscanf(data->change.url, "%[^\n/?]%[^\n]", - conn->host.name, conn->path)) ) { - /* - * We couldn't even get this format. - */ - failf(data, "<url> malformed"); - return CURLE_URL_MALFORMAT; - } - - /* - * Since there was no protocol part specified, we guess what protocol it - * is based on the first letters of the server name. - */ - - /* Note: if you add a new protocol, please update the list in - * lib/version.c too! */ - - if(checkprefix("GOPHER", conn->host.name)) - strcpy(conn->protostr, "gopher"); -#ifdef USE_SSLEAY - else if(checkprefix("HTTPS", conn->host.name)) - strcpy(conn->protostr, "https"); - else if(checkprefix("FTPS", conn->host.name)) - strcpy(conn->protostr, "ftps"); -#endif /* USE_SSLEAY */ - else if(checkprefix("FTP", conn->host.name)) - strcpy(conn->protostr, "ftp"); - else if(checkprefix("TELNET", conn->host.name)) - strcpy(conn->protostr, "telnet"); - else if (checkprefix("DICT", conn->host.name)) - strcpy(conn->protostr, "DICT"); - else if (checkprefix("LDAP", conn->host.name)) - strcpy(conn->protostr, "LDAP"); - else { - strcpy(conn->protostr, "http"); - } - - conn->protocol |= PROT_MISSING; /* not given in URL */ - } - } - - /* If the URL is malformatted (missing a '/' after hostname before path) we - * insert a slash here. The only letter except '/' we accept to start a path - * is '?'. - */ - if(conn->path[0] == '?') { - /* We need this function to deal with overlapping memory areas. We know - that the memory area 'path' points to is 'urllen' bytes big and that - is bigger than the path. Use +1 to move the zero byte too. */ - memmove(&conn->path[1], conn->path, strlen(conn->path)+1); - conn->path[0] = '/'; - } - - /* - * So if the URL was A://B/C, - * conn->protostr is A - * conn->host.name is B - * conn->path is /C - */ - - /************************************************************* - * Take care of proxy authentication stuff - *************************************************************/ - if(conn->bits.proxy_user_passwd) { - char proxyuser[MAX_CURL_USER_LENGTH]=""; - char proxypasswd[MAX_CURL_PASSWORD_LENGTH]=""; - - sscanf(data->set.proxyuserpwd, - "%" MAX_CURL_USER_LENGTH_TXT "[^:]:" - "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^\n]", - proxyuser, proxypasswd); - - conn->proxyuser = strdup(proxyuser); - if(!conn->proxyuser) - return CURLE_OUT_OF_MEMORY; - - conn->proxypasswd = strdup(proxypasswd); - if(!conn->proxypasswd) - return CURLE_OUT_OF_MEMORY; - } - - /************************************************************* - * Detect what (if any) proxy to use - *************************************************************/ - if(!data->change.proxy) { - /* If proxy was not specified, we check for default proxy environment - * variables, to enable i.e Lynx compliance: - * - * http_proxy=http://some.server.dom:port/ - * https_proxy=http://some.server.dom:port/ - * ftp_proxy=http://some.server.dom:port/ - * gopher_proxy=http://some.server.dom:port/ - * no_proxy=domain1.dom,host.domain2.dom - * (a comma-separated list of hosts which should - * not be proxied, or an asterisk to override - * all proxy variables) - * all_proxy=http://some.server.dom:port/ - * (seems to exist for the CERN www lib. Probably - * the first to check for.) - * - * For compatibility, the all-uppercase versions of these variables are - * checked if the lowercase versions don't exist. - */ - char *no_proxy; - char *no_proxy_tok_buf; - char *proxy=NULL; - char proxy_env[128]; - (void)proxy; - - no_proxy=curl_getenv("no_proxy"); - if(!no_proxy) - no_proxy=curl_getenv("NO_PROXY"); - - if(!no_proxy || !strequal("*", no_proxy)) { - /* NO_PROXY wasn't specified or it wasn't just an asterisk */ - char *nope; - - nope=no_proxy?strtok_r(no_proxy, ", ", &no_proxy_tok_buf):NULL; - while(nope) { - size_t namelen; - char *endptr = strchr(conn->host.name, ':'); - if(endptr) - namelen=endptr-conn->host.name; - else - namelen=strlen(conn->host.name); - - if(strlen(nope) <= namelen) { - char *checkn= - conn->host.name + namelen - strlen(nope); - if(checkprefix(nope, checkn)) { - /* no proxy for this host! */ - break; - } - } - nope=strtok_r(NULL, ", ", &no_proxy_tok_buf); - } - if(!nope) { - /* It was not listed as without proxy */ - char *protop = conn->protostr; - char *envp = proxy_env; - char *prox; - - /* Now, build <protocol>_proxy and check for such a one to use */ - while(*protop) - *envp++ = tolower((int)*protop++); - - /* append _proxy */ - strcpy(envp, "_proxy"); - - /* read the protocol proxy: */ - prox=curl_getenv(proxy_env); - - /* - * We don't try the uppercase version of HTTP_PROXY because of - * security reasons: - * - * When curl is used in a webserver application - * environment (cgi or php), this environment variable can - * be controlled by the web server user by setting the - * http header 'Proxy:' to some value. - * - * This can cause 'internal' http/ftp requests to be - * arbitrarily redirected by any external attacker. - */ - if(!prox && !strequal("http_proxy", proxy_env)) { - /* There was no lowercase variable, try the uppercase version: */ - for(envp = proxy_env; *envp; envp++) - *envp = toupper((int)*envp); - prox=curl_getenv(proxy_env); - } - - if(prox && *prox) { /* don't count "" strings */ - proxy = prox; /* use this */ - } - else { - proxy = curl_getenv("all_proxy"); /* default proxy to use */ - if(!proxy) - proxy=curl_getenv("ALL_PROXY"); - } - - if(proxy && *proxy) { - /* we have a proxy here to set */ - char *ptr; - char proxyuser[MAX_CURL_USER_LENGTH]; - char proxypasswd[MAX_CURL_PASSWORD_LENGTH]; - - char *fineptr; - - /* skip the possible protocol piece */ - ptr=strstr(proxy, "://"); - if(ptr) - ptr += 3; - else - ptr = proxy; - - fineptr = ptr; - - /* check for an @-letter */ - ptr = strchr(ptr, '@'); - if(ptr && (2 == sscanf(fineptr, - "%" MAX_CURL_USER_LENGTH_TXT"[^:]:" - "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]", - proxyuser, proxypasswd))) { - CURLcode res = CURLE_OK; - - /* found user and password, rip them out */ - Curl_safefree(conn->proxyuser); - conn->proxyuser = strdup(proxyuser); - - if(!conn->proxyuser) - res = CURLE_OUT_OF_MEMORY; - else { - Curl_safefree(conn->proxypasswd); - conn->proxypasswd = strdup(proxypasswd); - - if(!conn->proxypasswd) - res = CURLE_OUT_OF_MEMORY; - } - - if(CURLE_OK == res) { - conn->bits.proxy_user_passwd = TRUE; /* enable it */ - ptr = strdup(ptr+1); /* the right side of the @-letter */ - - if(ptr) { - free(proxy); /* free the former proxy string */ - proxy = ptr; /* now use this instead */ - } - else - res = CURLE_OUT_OF_MEMORY; - } - - if(res) { - free(proxy); /* free the allocated proxy string */ - return res; - } - } - - data->change.proxy = proxy; - data->change.proxy_alloc=TRUE; /* this needs to be freed later */ - conn->bits.httpproxy = TRUE; - } - } /* if (!nope) - it wasn't specified non-proxy */ - } /* NO_PROXY wasn't specified or '*' */ - if(no_proxy) - free(no_proxy); - } /* if not using proxy */ - - /************************************************************* - * No protocol part in URL was used, add it! - *************************************************************/ - if(conn->protocol&PROT_MISSING) { - /* We're guessing prefixes here and if we're told to use a proxy or if - we're gonna follow a Location: later or... then we need the protocol - part added so that we have a valid URL. */ - char *reurl; - - reurl = aprintf("%s://%s", conn->protostr, data->change.url); - - if(!reurl) - return CURLE_OUT_OF_MEMORY; - - data->change.url = reurl; - data->change.url_alloc = TRUE; /* free this later */ - conn->protocol &= ~PROT_MISSING; /* switch that one off again */ - } - -#ifndef CURL_DISABLE_HTTP - /************************************************************ - * RESUME on a HTTP page is a tricky business. First, let's just check that - * 'range' isn't used, then set the range parameter and leave the resume as - * it is to inform about this situation for later use. We will then - * "attempt" to resume, and if we're talking to a HTTP/1.1 (or later) - * server, we will get the document resumed. If we talk to a HTTP/1.0 - * server, we just fail since we can't rewind the file writing from within - * this function. - ***********************************************************/ - if(conn->resume_from) { - if(!conn->bits.use_range) { - /* if it already was in use, we just skip this */ - conn->range = aprintf("%" FORMAT_OFF_T "-", conn->resume_from); - if(!conn->range) - return CURLE_OUT_OF_MEMORY; - conn->bits.rangestringalloc = TRUE; /* mark as allocated */ - conn->bits.use_range = 1; /* switch on range usage */ - } - } -#endif - /************************************************************* - * Setup internals depending on protocol - *************************************************************/ - - if (strequal(conn->protostr, "HTTP")) { -#ifndef CURL_DISABLE_HTTP - conn->port = (data->set.use_port && data->state.allow_port)? - data->set.use_port:PORT_HTTP; - conn->remote_port = PORT_HTTP; - conn->protocol |= PROT_HTTP; - conn->curl_do = Curl_http; - conn->curl_do_more = NULL; - conn->curl_done = Curl_http_done; - conn->curl_connect = Curl_http_connect; -#else - failf(data, LIBCURL_NAME - " was built with HTTP disabled, http: not supported!"); - return CURLE_UNSUPPORTED_PROTOCOL; -#endif - } - else if (strequal(conn->protostr, "HTTPS")) { -#if defined(USE_SSLEAY) && !defined(CURL_DISABLE_HTTP) - - conn->port = (data->set.use_port && data->state.allow_port)? - data->set.use_port:PORT_HTTPS; - conn->remote_port = PORT_HTTPS; - conn->protocol |= PROT_HTTP|PROT_HTTPS|PROT_SSL; - - conn->curl_do = Curl_http; - conn->curl_do_more = NULL; - conn->curl_done = Curl_http_done; - conn->curl_connect = Curl_http_connect; - -#else /* USE_SSLEAY */ - failf(data, LIBCURL_NAME - " was built with SSL disabled, https: not supported!"); - return CURLE_UNSUPPORTED_PROTOCOL; -#endif /* !USE_SSLEAY */ - } - else if (strequal(conn->protostr, "GOPHER")) { -#ifndef CURL_DISABLE_GOPHER - conn->port = (data->set.use_port && data->state.allow_port)? - data->set.use_port:PORT_GOPHER; - conn->remote_port = PORT_GOPHER; - /* Skip /<item-type>/ in path if present */ - if (isdigit((int)conn->path[1])) { - conn->path = strchr(&conn->path[1], '/'); - if (conn->path == NULL) - conn->path = conn->pathbuffer; - } - conn->protocol |= PROT_GOPHER; - conn->curl_do = Curl_http; - conn->curl_do_more = NULL; - conn->curl_done = Curl_http_done; -#else - failf(data, LIBCURL_NAME - " was built with GOPHER disabled, gopher: not supported!"); -#endif - } - else if(strequal(conn->protostr, "FTP") || - strequal(conn->protostr, "FTPS")) { - -#ifndef CURL_DISABLE_FTP - char *type; - int port = PORT_FTP; - - if(strequal(conn->protostr, "FTPS")) { -#ifdef USE_SSLEAY - conn->protocol |= PROT_FTPS|PROT_SSL; - conn->ssl[SECONDARYSOCKET].use = TRUE; /* send data securely */ - port = PORT_FTPS; -#else - failf(data, LIBCURL_NAME - " was built with SSL disabled, ftps: not supported!"); - return CURLE_UNSUPPORTED_PROTOCOL; -#endif /* !USE_SSLEAY */ - } - - conn->port = (data->set.use_port && data->state.allow_port)? - data->set.use_port:port; - conn->remote_port = port; - conn->protocol |= PROT_FTP; - - if(data->change.proxy && - *data->change.proxy && - !data->set.tunnel_thru_httpproxy) { - /* Unless we have asked to tunnel ftp operations through the proxy, we - switch and use HTTP operations only */ - if(conn->protocol & PROT_FTPS) { - /* FTPS is a hacked protocol and does not work through your - ordinary http proxy! */ - failf(data, "ftps does not work through http proxy!"); - return CURLE_UNSUPPORTED_PROTOCOL; - } -#ifndef CURL_DISABLE_HTTP - conn->curl_do = Curl_http; - conn->curl_done = Curl_http_done; -#else - failf(data, "FTP over http proxy requires HTTP support built-in!"); - return CURLE_UNSUPPORTED_PROTOCOL; -#endif - } - else { - conn->curl_do = Curl_ftp; - conn->curl_do_more = Curl_ftp_nextconnect; - conn->curl_done = Curl_ftp_done; - conn->curl_connect = Curl_ftp_connect; - conn->curl_disconnect = Curl_ftp_disconnect; - } - - conn->path++; /* don't include the initial slash */ - - /* FTP URLs support an extension like ";type=<typecode>" that - * we'll try to get now! */ - type=strstr(conn->path, ";type="); - if(!type) { - type=strstr(conn->host.rawalloc, ";type="); - } - if(type) { - char command; - *type=0; /* it was in the middle of the hostname */ - command = toupper((int)type[6]); - switch(command) { - case 'A': /* ASCII mode */ - data->set.ftp_ascii = 1; - break; - case 'D': /* directory mode */ - data->set.ftp_list_only = 1; - break; - case 'I': /* binary mode */ - default: - /* switch off ASCII */ - data->set.ftp_ascii = 0; - break; - } - } -#else /* CURL_DISABLE_FTP */ - failf(data, LIBCURL_NAME - " was built with FTP disabled, ftp/ftps: not supported!"); - return CURLE_UNSUPPORTED_PROTOCOL; -#endif - } - else if(strequal(conn->protostr, "TELNET")) { -#ifndef CURL_DISABLE_TELNET - /* telnet testing factory */ - conn->protocol |= PROT_TELNET; - - conn->port = (data->set.use_port && data->state.allow_port)? - data->set.use_port: PORT_TELNET; - conn->remote_port = PORT_TELNET; - conn->curl_do = Curl_telnet; - conn->curl_done = Curl_telnet_done; -#else - failf(data, LIBCURL_NAME - " was built with TELNET disabled!"); -#endif - } - else if (strequal(conn->protostr, "DICT")) { -#ifndef CURL_DISABLE_DICT - conn->protocol |= PROT_DICT; - conn->port = (data->set.use_port && data->state.allow_port)? - data->set.use_port:PORT_DICT; - conn->remote_port = PORT_DICT; - conn->curl_do = Curl_dict; - conn->curl_done = NULL; /* no DICT-specific done */ -#else - failf(data, LIBCURL_NAME - " was built with DICT disabled!"); -#endif - } - else if (strequal(conn->protostr, "LDAP")) { -#ifndef CURL_DISABLE_LDAP - conn->protocol |= PROT_LDAP; - conn->port = (data->set.use_port && data->state.allow_port)? - data->set.use_port:PORT_LDAP; - conn->remote_port = PORT_LDAP; - conn->curl_do = Curl_ldap; - conn->curl_done = NULL; /* no LDAP-specific done */ -#else - failf(data, LIBCURL_NAME - " was built with LDAP disabled!"); -#endif - } - else if (strequal(conn->protostr, "FILE")) { -#ifndef CURL_DISABLE_FILE - conn->protocol |= PROT_FILE; - - conn->curl_do = Curl_file; - conn->curl_done = Curl_file_done; - - /* anyway, this is supposed to be the connect function so we better - at least check that the file is present here! */ - result = Curl_file_connect(conn); - - /* Setup a "faked" transfer that'll do nothing */ - if(CURLE_OK == result) { - conn->bits.tcpconnect = TRUE; /* we are "connected */ - result = Curl_Transfer(conn, -1, -1, FALSE, NULL, /* no download */ - -1, NULL); /* no upload */ - } - - return result; -#else - failf(data, LIBCURL_NAME - " was built with FILE disabled!"); -#endif - } - else { - /* We fell through all checks and thus we don't support the specified - protocol */ - failf(data, "Unsupported protocol: %s", conn->protostr); - return CURLE_UNSUPPORTED_PROTOCOL; - } - - /************************************************************* - * Figure out the remote port number - * - * No matter if we use a proxy or not, we have to figure out the remote - * port number of various reasons. - * - * To be able to detect port number flawlessly, we must not confuse them - * IPv6-specified addresses in the [0::1] style. (RFC2732) - * - * The conn->host.name is currently [user:passwd@]host[:port] where host - * could be a hostname, IPv4 address or IPv6 address. - *************************************************************/ - if((1 == sscanf(conn->host.name, "[%*39[0-9a-fA-F:.]%c", &endbracket)) && - (']' == endbracket)) { - /* this is a RFC2732-style specified IP-address */ - conn->bits.ipv6_ip = TRUE; - - conn->host.name++; /* pass the starting bracket */ - tmp = strchr(conn->host.name, ']'); - *tmp = 0; /* zero terminate */ - tmp++; /* pass the ending bracket */ - if(':' != *tmp) - tmp = NULL; /* no port number available */ - } - else - tmp = strrchr(conn->host.name, ':'); - - if (tmp) { - char *rest; - unsigned long port; - - port=strtoul(tmp+1, &rest, 10); /* Port number must be decimal */ - - if (rest != (tmp+1) && *rest == '\0') { - /* The colon really did have only digits after it, - * so it is either a port number or a mistake */ - - if (port > 0xffff) { /* Single unix standard says port numbers are - * 16 bits long */ - failf(data, "Port number too large: %lu", port); - return CURLE_URL_MALFORMAT; - } - - *tmp = '\0'; /* cut off the name there */ - conn->remote_port = (unsigned short)port; - } - } - - if(data->change.proxy && *data->change.proxy) { - /* If this is supposed to use a proxy, we need to figure out the proxy - host name name, so that we can re-use an existing connection - that may exist registered to the same proxy host. */ - - char *prox_portno; - char *endofprot; - - /* We need to make a duplicate of the proxy so that we can modify the - string safely. */ - char *proxydup=strdup(data->change.proxy); - - /* We use 'proxyptr' to point to the proxy name from now on... */ - char *proxyptr=proxydup; - - if(NULL == proxydup) { - failf(data, "memory shortage"); - return CURLE_OUT_OF_MEMORY; - } - - /* Daniel Dec 10, 1998: - We do the proxy host string parsing here. We want the host name and the - port name. Accept a protocol:// prefix, even though it should just be - ignored. */ - - /* 1. skip the protocol part if present */ - endofprot=strstr(proxyptr, "://"); - if(endofprot) { - proxyptr = endofprot+3; - } - - /* allow user to specify proxy.server.com:1080 if desired */ - prox_portno = strchr (proxyptr, ':'); - if (prox_portno) { - *prox_portno = 0x0; /* cut off number from host name */ - prox_portno ++; - /* now set the local port number */ - conn->port = atoi(prox_portno); - } - else if(data->set.proxyport) { - /* None given in the proxy string, then get the default one if it is - given */ - conn->port = data->set.proxyport; - } - - /* now, clone the cleaned proxy host name */ - conn->proxy.rawalloc = strdup(proxyptr); - conn->proxy.name = conn->proxy.rawalloc; - - free(proxydup); /* free the duplicate pointer and not the modified */ - if(!conn->proxy.rawalloc) - return CURLE_OUT_OF_MEMORY; - } - - /************************************************************* - * If the protcol is using SSL and HTTP proxy is used, we set - * the tunnel_proxy bit. - *************************************************************/ - if((conn->protocol&PROT_SSL) && conn->bits.httpproxy) - conn->bits.tunnel_proxy = TRUE; - - /************************************************************* - * Take care of user and password authentication stuff - *************************************************************/ - - /* - * Inputs: data->set.userpwd (CURLOPT_USERPWD) - * data->set.fpasswd (CURLOPT_PASSWDFUNCTION) - * data->set.use_netrc (CURLOPT_NETRC) - * conn->host.name - * netrc file - * hard-coded defaults - * - * Outputs: (almost :- all currently undefined) - * conn->bits.user_passwd - non-zero if non-default passwords exist - * conn->user - non-zero length if defined - * conn->passwd - ditto - * conn->host.name - remove user name and password - */ - - /* At this point, we're hoping all the other special cases have - * been taken care of, so conn->host.name is at most - * [user[:password]]@]hostname - * - * We need somewhere to put the embedded details, so do that first. - */ - - user[0] =0; /* to make everything well-defined */ - passwd[0]=0; - - if (conn->protocol & (PROT_FTP|PROT_HTTP)) { - /* This is a FTP or HTTP URL, we will now try to extract the possible - * user+password pair in a string like: - * ftp://user:password@ftp.my.site:8021/README */ - char *ptr=strchr(conn->host.name, '@'); - char *userpass = conn->host.name; - if(ptr != NULL) { - /* there's a user+password given here, to the left of the @ */ - - conn->host.name = ++ptr; - - /* So the hostname is sane. Only bother interpreting the - * results if we could care. It could still be wasted - * work because it might be overtaken by the programmatically - * set user/passwd, but doing that first adds more cases here :-( - */ - - if (data->set.use_netrc != CURL_NETRC_REQUIRED) { - /* We could use the one in the URL */ - - conn->bits.user_passwd = 1; /* enable user+password */ - - if(*userpass != ':') { - /* the name is given, get user+password */ - sscanf(userpass, "%127[^:@]:%127[^@]", - user, passwd); - } - else - /* no name given, get the password only */ - sscanf(userpass, ":%127[^@]", passwd); - - if(user[0]) { - char *newname=curl_unescape(user, 0); - if(!newname) - return CURLE_OUT_OF_MEMORY; - if(strlen(newname) < sizeof(user)) - strcpy(user, newname); - - /* if the new name is longer than accepted, then just use - the unconverted name, it'll be wrong but what the heck */ - free(newname); - } - if (passwd[0]) { - /* we have a password found in the URL, decode it! */ - char *newpasswd=curl_unescape(passwd, 0); - if(!newpasswd) - return CURLE_OUT_OF_MEMORY; - if(strlen(newpasswd) < sizeof(passwd)) - strcpy(passwd, newpasswd); - - free(newpasswd); - } - } - } - } - - /* Programmatically set password: - * - always applies, if available - * - takes precedence over the values we just set above - * so scribble it over the top. - * User-supplied passwords are assumed not to need unescaping. - * - * user_password is set in "inherite initial knowledge' above, - * so it doesn't have to be set in this block - */ - if (data->set.userpwd != NULL) { - /* the name is given, get user+password */ - sscanf(data->set.userpwd, - "%" MAX_CURL_USER_LENGTH_TXT "[^:]:" - "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^\n]", - user, passwd); - } - - if (data->set.use_netrc != CURL_NETRC_IGNORED) { - if(Curl_parsenetrc(conn->host.name, - user, passwd, - data->set.netrc_file)) { - infof(data, "Couldn't find host %s in the .netrc file, using defaults\n", - conn->host.name); - } - else - conn->bits.user_passwd = 1; /* enable user+password */ - } - - /* If our protocol needs a password and we have none, use the defaults */ - if ( (conn->protocol & PROT_FTP) && - !conn->bits.user_passwd) { - - conn->user = strdup(CURL_DEFAULT_USER); - conn->passwd = strdup(CURL_DEFAULT_PASSWORD); - /* This is the default password, so DON'T set conn->bits.user_passwd */ - } - else { - /* store user + password, zero-length if not set */ - conn->user = strdup(user); - conn->passwd = strdup(passwd); - } - if(!conn->user || !conn->passwd) - return CURLE_OUT_OF_MEMORY; - - /************************************************************* - * Check the current list of connections to see if we can - * re-use an already existing one or if we have to create a - * new one. - *************************************************************/ - - /* get a cloned copy of the SSL config situation stored in the - connection struct */ - if(!Curl_clone_ssl_config(&data->set.ssl, &conn->ssl_config)) - return CURLE_OUT_OF_MEMORY; - - /* reuse_fresh is TRUE if we are told to use a new connection by force, but - we only acknowledge this option if this is not a re-used connection - already (which happens due to follow-location or during a HTTP - authentication phase). */ - if(data->set.reuse_fresh && !data->state.this_is_a_follow) - reuse = FALSE; - else - reuse = ConnectionExists(data, conn, &conn_temp); - - if(reuse) { - /* - * We already have a connection for this, we got the former connection - * in the conn_temp variable and thus we need to cleanup the one we - * just allocated before we can move along and use the previously - * existing one. - */ - struct connectdata *old_conn = conn; - - if(old_conn->proxy.rawalloc) - free(old_conn->proxy.rawalloc); - - /* free the SSL config struct from this connection struct as this was - allocated in vain and is targeted for destruction */ - Curl_free_ssl_config(&conn->ssl_config); - - conn = conn_temp; /* use this connection from now on */ - - /* get the user+password information from the old_conn struct since it may - * be new for this request even when we re-use an existing connection */ - conn->bits.user_passwd = old_conn->bits.user_passwd; - conn->bits.proxy_user_passwd = old_conn->bits.proxy_user_passwd; - - /* host can change, when doing keepalive with a proxy ! */ - if (conn->bits.httpproxy) { - free(conn->host.rawalloc); - conn->host=old_conn->host; - } - - /* get the newly set value, not the old one */ - conn->bits.no_body = old_conn->bits.no_body; - - if (!conn->bits.httpproxy) - free(old_conn->host.rawalloc); /* free the newly allocated name buffer */ - - free(conn->pathbuffer); /* free the newly allocated path pointer */ - conn->pathbuffer = old_conn->pathbuffer; /* use the old one */ - conn->path = old_conn->path; - - /* re-use init */ - conn->bits.reuse = TRUE; /* yes, we're re-using here */ - conn->bits.chunk = FALSE; /* always assume not chunked unless told - otherwise */ - conn->maxdownload = -1; /* might have been used previously! */ - - Curl_safefree(old_conn->user); - Curl_safefree(old_conn->passwd); - Curl_safefree(old_conn->proxyuser); - Curl_safefree(old_conn->proxypasswd); - - if(old_conn->bits.rangestringalloc) - free(old_conn->range); - - free(old_conn); /* we don't need this anymore */ - - /* - * If we're doing a resumed transfer, we need to setup our stuff - * properly. - */ - conn->resume_from = data->set.set_resume_from; - if (conn->resume_from) { - if (conn->bits.rangestringalloc == TRUE) - free(conn->range); - conn->range = aprintf("%" FORMAT_OFF_T "-", conn->resume_from); - if(!conn->range) - return CURLE_OUT_OF_MEMORY; - - /* tell ourselves to fetch this range */ - conn->bits.use_range = TRUE; /* enable range download */ - conn->bits.rangestringalloc = TRUE; /* mark range string allocated */ - } - else if (data->set.set_range) { - /* There is a range, but is not a resume, useful for random ftp access */ - conn->range = strdup(data->set.set_range); - if(!conn->range) - return CURLE_OUT_OF_MEMORY; - conn->bits.rangestringalloc = TRUE; /* mark range string allocated */ - conn->bits.use_range = TRUE; /* enable range download */ - } - else - conn->bits.use_range = FALSE; /* disable range download */ - - *in_connect = conn; /* return this instead! */ - - infof(data, "Re-using existing connection! (#%ld) with host %s\n", - conn->connectindex, - conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname); - } - else { - /* - * This is a brand new connection, so let's store it in the connection - * cache of ours! - */ - ConnectionStore(data, conn); - } - - /* Continue connectdata initialization here. - * - * Inherit the proper values from the urldata struct AFTER we have arranged - * the persistant conncetion stuff */ - conn->fread = data->set.fread; - conn->fread_in = data->set.in; - - conn->bits.upload_chunky = - ((conn->protocol&PROT_HTTP) && - data->set.upload && - (data->set.infilesize == -1) && - (data->set.httpversion != CURL_HTTP_VERSION_1_0))? - /* HTTP, upload, unknown file size and not HTTP 1.0 */ - TRUE: - /* else, no chunky upload */ - FALSE; - -#ifndef USE_ARES - /************************************************************* - * Set timeout if that is being used, and we're not using an asynchronous - * name resolve. - *************************************************************/ - if((data->set.timeout || data->set.connecttimeout) && !data->set.no_signal) { - /************************************************************* - * Set signal handler to catch SIGALRM - * Store the old value to be able to set it back later! - *************************************************************/ - -#ifdef SIGALRM -#ifdef HAVE_SIGACTION - struct sigaction sigact; - sigaction(SIGALRM, NULL, &sigact); - keep_sigact = sigact; - keep_copysig = TRUE; /* yes, we have a copy */ - sigact.sa_handler = alarmfunc; -#ifdef SA_RESTART - /* HPUX doesn't have SA_RESTART but defaults to that behaviour! */ - sigact.sa_flags &= ~SA_RESTART; -#endif - /* now set the new struct */ - sigaction(SIGALRM, &sigact, NULL); -#else /* HAVE_SIGACTION */ - /* no sigaction(), revert to the much lamer signal() */ -#ifdef HAVE_SIGNAL - keep_sigact = signal(SIGALRM, alarmfunc); -#endif -#endif /* HAVE_SIGACTION */ - - /* We set the timeout on the name resolving phase first, separately from - * the download/upload part to allow a maximum time on everything. This is - * a signal-based timeout, why it won't work and shouldn't be used in - * multi-threaded environments. */ - -#ifdef HAVE_ALARM - /* alarm() makes a signal get sent when the timeout fires off, and that - will abort system calls */ - prev_alarm = alarm(data->set.connecttimeout? - data->set.connecttimeout: - data->set.timeout); - /* We can expect the conn->created time to be "now", as that was just - recently set in the beginning of this function and nothing slow - has been done since then until now. */ -#endif -#endif /* SIGALRM */ - } -#endif /* USE_ARES */ - - /************************************************************* - * Resolve the name of the server or proxy - *************************************************************/ - if(conn->bits.reuse) { - /* re-used connection, no resolving is necessary */ - hostaddr = NULL; - conn->dns_entry = NULL; /* we don't connect now so we don't have any fresh - dns entry struct to point to */ - - if (conn->bits.httpproxy) - fix_hostname(conn, &conn->host); - } - else { - /* this is a fresh connect */ - - /* set a pointer to the hostname we display */ - fix_hostname(conn, &conn->host); - - if(!data->change.proxy || !*data->change.proxy) { - /* If not connecting via a proxy, extract the port from the URL, if it is - * there, thus overriding any defaults that might have been set above. */ - conn->port = conn->remote_port; /* it is the same port */ - - /* Resolve target host right on */ - rc = Curl_resolv(conn, conn->host.name, (int)conn->port, &hostaddr); - if(rc == CURLRESOLV_PENDING) - *async = TRUE; - - else if(!hostaddr) { - failf(data, "Couldn't resolve host '%s'", conn->host.dispname); - result = CURLE_COULDNT_RESOLVE_HOST; - /* don't return yet, we need to clean up the timeout first */ - } - } - else { - /* This is a proxy that hasn't been resolved yet. */ - - /* IDN-fix the proxy name */ - fix_hostname(conn, &conn->proxy); - - /* resolve proxy */ - rc = Curl_resolv(conn, conn->proxy.name, (int)conn->port, &hostaddr); - - if(rc == CURLRESOLV_PENDING) - *async = TRUE; - - else if(!hostaddr) { - failf(data, "Couldn't resolve proxy '%s'", conn->proxy.dispname); - result = CURLE_COULDNT_RESOLVE_PROXY; - /* don't return yet, we need to clean up the timeout first */ - } - } - } - *addr = hostaddr; - -#if defined(HAVE_ALARM) && defined(SIGALRM) && !defined(USE_ARES) - if((data->set.timeout || data->set.connecttimeout) && !data->set.no_signal) { -#ifdef HAVE_SIGACTION - if(keep_copysig) { - /* we got a struct as it looked before, now put that one back nice - and clean */ - sigaction(SIGALRM, &keep_sigact, NULL); /* put it back */ - } -#else -#ifdef HAVE_SIGNAL - /* restore the previous SIGALRM handler */ - signal(SIGALRM, keep_sigact); -#endif -#endif /* HAVE_SIGACTION */ - - /* switch back the alarm() to either zero or to what it was before minus - the time we spent until now! */ - if(prev_alarm) { - /* there was an alarm() set before us, now put it back */ - unsigned long elapsed_ms = Curl_tvdiff(Curl_tvnow(), conn->created); - unsigned long alarm_set; - - /* the alarm period is counted in even number of seconds */ - alarm_set = prev_alarm - elapsed_ms/1000; - - if(!alarm_set || - ((alarm_set >= 0x80000000) && (prev_alarm < 0x80000000)) ) { - /* if the alarm time-left reached zero or turned "negative" (counted - with unsigned values), we should fire off a SIGALRM here, but we - won't, and zero would be to switch it off so we never set it to - less than 1! */ - alarm(1); - result = CURLE_OPERATION_TIMEOUTED; - failf(data, "Previous alarm fired off!"); - } - else - alarm((unsigned int)alarm_set); - } - else - alarm(0); /* just shut it off */ - } -#endif - - return result; -} - -/* SetupConnection() should be called after the name resolve initiated in - * CreateConnection() is all done. - */ - -static CURLcode SetupConnection(struct connectdata *conn, - struct Curl_dns_entry *hostaddr) -{ - struct SessionHandle *data = conn->data; - CURLcode result=CURLE_OK; - - Curl_pgrsTime(data, TIMER_NAMELOOKUP); - - if(conn->protocol & PROT_FILE) - /* There's nothing in this function to setup if we're only doing - a file:// transfer */ - return result; - - /************************************************************* - * Send user-agent to HTTP proxies even if the target protocol - * isn't HTTP. - *************************************************************/ - if((conn->protocol&PROT_HTTP) || - (data->change.proxy && *data->change.proxy)) { - if(data->set.useragent) { - Curl_safefree(conn->allocptr.uagent); - conn->allocptr.uagent = - aprintf("User-Agent: %s\015\012", data->set.useragent); - if(!conn->allocptr.uagent) - return CURLE_OUT_OF_MEMORY; - } - } - - if(data->set.encoding) { - Curl_safefree(conn->allocptr.accept_encoding); - conn->allocptr.accept_encoding = - aprintf("Accept-Encoding: %s\015\012", data->set.encoding); - if(!conn->allocptr.accept_encoding) - return CURLE_OUT_OF_MEMORY; - } - - conn->bytecount = 0; - conn->headerbytecount = 0; - - if(CURL_SOCKET_BAD == conn->sock[FIRSTSOCKET]) { - bool connected; - - /* Connect only if not already connected! */ - result = ConnectPlease(conn, hostaddr, &connected); - - if(connected) { - result = Curl_protocol_connect(conn); - if(CURLE_OK == result) - conn->bits.tcpconnect = TRUE; - } - else - conn->bits.tcpconnect = FALSE; - - - if(CURLE_OK != result) - return result; - } - else { - Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected already */ - conn->bits.tcpconnect = TRUE; - if(data->set.verbose) - verboseconnect(conn); - } - - conn->now = Curl_tvnow(); /* time this *after* the connect is done, we - set this here perhaps a second time */ - -#ifdef __EMX__ - /* 20000330 mgs - * the check is quite a hack... - * we're calling _fsetmode to fix the problem with fwrite converting newline - * characters (you get mangled text files, and corrupted binary files when - * you download to stdout and redirect it to a file). */ - - if ((data->set.out)->_handle == NULL) { - _fsetmode(stdout, "b"); - } -#endif - - return CURLE_OK; -} - -CURLcode Curl_connect(struct SessionHandle *data, - struct connectdata **in_connect, - bool *asyncp) -{ - CURLcode code; - struct Curl_dns_entry *dns; - - *asyncp = FALSE; /* assume synchronous resolves by default */ - - /* call the stuff that needs to be called */ - code = CreateConnection(data, in_connect, &dns, asyncp); - - if(CURLE_OK == code) { - /* no error */ - if(dns || !*asyncp) - /* If an address is available it means that we already have the name - resolved, OR it isn't async. - If so => continue connecting from here */ - code = SetupConnection(*in_connect, dns); - /* else - response will be received and treated async wise */ - } - - if(CURLE_OK != code) { - /* We're not allowed to return failure with memory left allocated - in the connectdata struct, free those here */ - if(*in_connect) { - Curl_disconnect(*in_connect); /* close the connection */ - *in_connect = NULL; /* return a NULL */ - } - } - - return code; -} - -/* Call this function after Curl_connect() has returned async=TRUE and - then a successful name resolve has been received */ -CURLcode Curl_async_resolved(struct connectdata *conn) -{ -#if defined(USE_ARES) || defined(USE_THREADING_GETHOSTBYNAME) || \ - defined(USE_THREADING_GETADDRINFO) - CURLcode code = SetupConnection(conn, conn->async.dns); - - if(code) - /* We're not allowed to return failure with memory left allocated - in the connectdata struct, free those here */ - Curl_disconnect(conn); /* close the connection */ - - return code; -#else - (void)conn; - return CURLE_OK; -#endif -} - - -CURLcode Curl_done(struct connectdata **connp, - CURLcode status) /* an error if this is called after an - error was detected */ -{ - CURLcode result; - struct connectdata *conn = *connp; - struct SessionHandle *data=conn->data; - - /* cleanups done even if the connection is re-used */ - - if(conn->bits.rangestringalloc) { - free(conn->range); - conn->bits.rangestringalloc = FALSE; - } - - /* Cleanup possible redirect junk */ - if(conn->newurl) { - free(conn->newurl); - conn->newurl = NULL; - } - - if(conn->dns_entry) - Curl_resolv_unlock(conn->data, conn->dns_entry); /* done with this */ - -#if defined(CURLDEBUG) && defined(AGGRESIVE_TEST) - /* scan for DNS cache entries still marked as in use */ - Curl_hash_apply(data->hostcache, - NULL, Curl_scan_cache_used); -#endif - - Curl_hostcache_prune(data); /* kill old DNS cache entries */ - - /* this calls the protocol-specific function pointer previously set */ - if(conn->curl_done) - result = conn->curl_done(conn, status); - else - result = CURLE_OK; - - Curl_pgrsDone(conn); /* done with the operation */ - - /* if data->set.reuse_forbid is TRUE, it means the libcurl client has - forced us to close this no matter what we think. - - if conn->bits.close is TRUE, it means that the connection should be - closed in spite of all our efforts to be nice, due to protocol - restrictions in our or the server's end */ - if(data->set.reuse_forbid || conn->bits.close) { - CURLcode res2; - res2 = Curl_disconnect(conn); /* close the connection */ - - *connp = NULL; /* to make the caller of this function better detect that - this was actually killed here */ - - /* If we had an error already, make sure we return that one. But - if we got a new error, return that. */ - if(!result && res2) - result = res2; - } - else - infof(data, "Connection #%ld to host %s left intact\n", - conn->connectindex, - conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname); - - return result; -} - -CURLcode Curl_do(struct connectdata **connp) -{ - CURLcode result=CURLE_OK; - struct connectdata *conn = *connp; - struct SessionHandle *data=conn->data; - - conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to use */ - - if(conn->curl_do) { - /* generic protocol-specific function pointer set in curl_connect() */ - result = conn->curl_do(conn); - - /* This was formerly done in transfer.c, but we better do it here */ - - if((CURLE_SEND_ERROR == result) && conn->bits.reuse) { - /* This was a re-use of a connection and we got a write error in the - * DO-phase. Then we DISCONNECT this connection and have another attempt - * to CONNECT and then DO again! The retry cannot possibly find another - * connection to re-use, since we only keep one possible connection for - * each. */ - - infof(data, "Re-used connection seems dead, get a new one\n"); - - conn->bits.close = TRUE; /* enforce close of this connection */ - result = Curl_done(&conn, result); /* we are so done with this */ - - /* conn may no longer be a good pointer */ - - if(CURLE_OK == result) { - bool async; - /* Now, redo the connect and get a new connection */ - result = Curl_connect(data, connp, &async); - if(CURLE_OK == result) { - /* We have connected or sent away a name resolve query fine */ - - conn = *connp; /* setup conn to again point to something nice */ - if(async) { - /* Now, if async is TRUE here, we need to wait for the name - to resolve */ - result = Curl_wait_for_resolv(conn, NULL); - if(result) - return result; - - /* Resolved, continue with the connection */ - result = Curl_async_resolved(conn); - if(result) - return result; - } - - /* ... finally back to actually retry the DO phase */ - result = conn->curl_do(conn); - } - } - } - } - return result; -} - -CURLcode Curl_do_more(struct connectdata *conn) -{ - CURLcode result=CURLE_OK; - - if(conn->curl_do_more) - result = conn->curl_do_more(conn); - - return result; -} - -static bool safe_strequal(char* str1, char* str2) -{ - if(str1 && str2) - /* both pointers point to something then compare them */ - return strequal(str1, str2); - else - /* if both pointers are NULL then treat them as equal */ - return (!str1 && !str2); -} - -bool -Curl_ssl_config_matches(struct ssl_config_data* data, - struct ssl_config_data* needle) -{ - if((data->version == needle->version) && - (data->verifypeer == needle->verifypeer) && - (data->verifyhost == needle->verifyhost) && - safe_strequal(data->CApath, needle->CApath) && - safe_strequal(data->CAfile, needle->CAfile) && - safe_strequal(data->random_file, needle->random_file) && - safe_strequal(data->egdsocket, needle->egdsocket) && - safe_strequal(data->cipher_list, needle->cipher_list)) - return TRUE; - - return FALSE; -} - -bool -Curl_clone_ssl_config(struct ssl_config_data *source, - struct ssl_config_data *dest) -{ - dest->verifyhost = source->verifyhost; - dest->verifypeer = source->verifypeer; - dest->version = source->version; - - if(source->CAfile) { - dest->CAfile = strdup(source->CAfile); - if(!dest->CAfile) - return FALSE; - } - - if(source->CApath) { - dest->CApath = strdup(source->CApath); - if(!dest->CApath) - return FALSE; - } - - if(source->cipher_list) { - dest->cipher_list = strdup(source->cipher_list); - if(!dest->cipher_list) - return FALSE; - } - - if(source->egdsocket) { - dest->egdsocket = strdup(source->egdsocket); - if(!dest->egdsocket) - return FALSE; - } - - if(source->random_file) { - dest->random_file = strdup(source->random_file); - if(!dest->random_file) - return FALSE; - } - - return TRUE; -} - -void Curl_free_ssl_config(struct ssl_config_data* sslc) -{ - if(sslc->CAfile) - free(sslc->CAfile); - - if(sslc->CApath) - free(sslc->CApath); - - if(sslc->cipher_list) - free(sslc->cipher_list); - - if(sslc->egdsocket) - free(sslc->egdsocket); - - if(sslc->random_file) - free(sslc->random_file); -} - diff --git a/Source/CTest/Curl/url.h b/Source/CTest/Curl/url.h deleted file mode 100644 index 8fd4795..0000000 --- a/Source/CTest/Curl/url.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef __URL_H -#define __URL_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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$ - ***************************************************************************/ - -/* - * Prototypes for library-wide functions provided by url.c - */ - -CURLcode Curl_open(struct SessionHandle **curl); -CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...); -CURLcode Curl_close(struct SessionHandle *data); /* opposite of curl_open() */ -CURLcode Curl_connect(struct SessionHandle *, struct connectdata **, - bool *async); -CURLcode Curl_async_resolved(struct connectdata *conn); -CURLcode Curl_do(struct connectdata **); -CURLcode Curl_do_more(struct connectdata *); -CURLcode Curl_done(struct connectdata **, CURLcode); -CURLcode Curl_disconnect(struct connectdata *); -CURLcode Curl_protocol_connect(struct connectdata *conn); -bool Curl_ssl_config_matches(struct ssl_config_data* data, - struct ssl_config_data* needle); -bool Curl_clone_ssl_config(struct ssl_config_data* source, - struct ssl_config_data* dest); -void Curl_free_ssl_config(struct ssl_config_data* sslc); -void Curl_safefree(void *ptr); -#endif diff --git a/Source/CTest/Curl/urldata.h b/Source/CTest/Curl/urldata.h deleted file mode 100644 index 07aff9b..0000000 --- a/Source/CTest/Curl/urldata.h +++ /dev/null @@ -1,962 +0,0 @@ -#ifndef __URLDATA_H -#define __URLDATA_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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$ - ***************************************************************************/ - -/* This file is for lib internal stuff */ - -#include "setup.h" - -#define PORT_FTP 21 -#define PORT_FTPS 990 -#define PORT_TELNET 23 -#define PORT_GOPHER 70 -#define PORT_HTTP 80 -#define PORT_HTTPS 443 -#define PORT_DICT 2628 -#define PORT_LDAP 389 - -#define DICT_MATCH "/MATCH:" -#define DICT_MATCH2 "/M:" -#define DICT_MATCH3 "/FIND:" -#define DICT_DEFINE "/DEFINE:" -#define DICT_DEFINE2 "/D:" -#define DICT_DEFINE3 "/LOOKUP:" - -#define CURL_DEFAULT_USER "anonymous" -#define CURL_DEFAULT_PASSWORD "curl_by_daniel@haxx.se" - -#include "cookie.h" -#include "formdata.h" - -#ifdef USE_SSLEAY -/* SSLeay stuff usually in /usr/local/ssl/include */ -#ifdef USE_OPENSSL -#include "openssl/rsa.h" -#include "openssl/crypto.h" -#include "openssl/x509.h" -#include "openssl/pem.h" -#include "openssl/ssl.h" -#include "openssl/err.h" -#ifdef HAVE_OPENSSL_ENGINE_H -#include <openssl/engine.h> -#endif -#else -#include "rsa.h" -#include "crypto.h" -#include "x509.h" -#include "pem.h" -#include "ssl.h" -#include "err.h" -#endif -#endif - -#ifdef HAVE_NETINET_IN_H -#include <netinet/in.h> -#endif - -#include "timeval.h" - -#ifdef HAVE_ZLIB_H -#include <zlib.h> /* for content-encoding */ -#endif - -#ifdef CURL_SPECIAL_ZLIB_H -#include CURL_SPECIAL_ZLIB_H -#endif - -#ifdef USE_ARES -#include <ares.h> -#endif - -#include <curl/curl.h> - -#include "http_chunks.h" /* for the structs and enum stuff */ -#include "hostip.h" -#include "hash.h" - -#ifdef HAVE_GSSAPI -#ifdef HAVE_GSSMIT -#include <gssapi/gssapi.h> -#include <gssapi/gssapi_generic.h> -#else -#include <gssapi.h> -#endif -#endif - -/* Download buffer size, keep it fairly big for speed reasons */ -#define BUFSIZE CURL_MAX_WRITE_SIZE - -/* Initial size of the buffer to store headers in, it'll be enlarged in case - of need. */ -#define HEADERSIZE 256 - -/* Just a convenience macro to get the larger value out of two given. - We prefix with CURL to prevent name collisions. */ -#define CURLMAX(x,y) ((x)>(y)?(x):(y)) - -#ifdef HAVE_KRB4 -/* Types needed for krb4-ftp connections */ -struct krb4buffer { - void *data; - size_t size; - size_t index; - int eof_flag; -}; -enum protection_level { - prot_clear, - prot_safe, - prot_confidential, - prot_private -}; -#endif - -/* struct for data related to each SSL connection */ -struct ssl_connect_data { - bool use; /* use ssl encrypted communications TRUE/FALSE */ -#ifdef USE_SSLEAY - /* these ones requires specific SSL-types */ - SSL_CTX* ctx; - SSL* handle; - X509* server_cert; -#endif /* USE_SSLEAY */ -}; - -struct ssl_config_data { - long version; /* what version the client wants to use */ - long certverifyresult; /* result from the certificate verification */ - long verifypeer; /* set TRUE if this is desired */ - long verifyhost; /* 0: no verify - 1: check that CN exists - 2: CN must match hostname */ - char *CApath; /* DOES NOT WORK ON WINDOWS */ - char *CAfile; /* cerficate to verify peer against */ - char *random_file; /* path to file containing "random" data */ - char *egdsocket; /* path to file containing the EGD daemon socket */ - char *cipher_list; /* list of ciphers to use */ - long numsessions; /* SSL session id cache size */ - curl_ssl_ctx_callback fsslctx; /* function to initialize ssl ctx */ - void *fsslctxp; /*parameter for call back */ -}; - -/* information stored about one single SSL session */ -struct curl_ssl_session { - char *name; /* host name for which this ID was used */ - void *sessionid; /* as returned from the SSL layer */ - long age; /* just a number, the higher the more recent */ - unsigned short remote_port; /* remote port to connect to */ - struct ssl_config_data ssl_config; /* setup for this session */ -}; - -/* Struct used for Digest challenge-response authentication */ -struct digestdata { - char *nonce; - char *cnonce; - char *realm; - int algo; - bool stale; /* set true for re-negotiation */ - char *opaque; - char *qop; - char *algorithm; - int nc; /* nounce count */ -}; - -typedef enum { - NTLMSTATE_NONE, - NTLMSTATE_TYPE1, - NTLMSTATE_TYPE2, - NTLMSTATE_TYPE3, - NTLMSTATE_LAST -} curlntlm; - -/* for 3rd party transfers to decide which side that issues PASV */ -typedef enum { - CURL_TARGET_PASV, - CURL_SOURCE_PASV -} curl_pasv_side; - -/* Struct used for NTLM challenge-response authentication */ -struct ntlmdata { - curlntlm state; - unsigned char nonce[8]; -}; - -#ifdef HAVE_GSSAPI -struct negotiatedata { - bool gss; /* Whether we're processing GSS-Negotiate or Negotiate */ - const char* protocol; /* "GSS-Negotiate" or "Negotiate" */ - OM_uint32 status; - gss_ctx_id_t context; - gss_name_t server_name; - gss_buffer_desc output_token; -}; -#endif - -/**************************************************************************** - * HTTP unique setup - ***************************************************************************/ -struct HTTP { - struct FormData *sendit; - curl_off_t postsize; /* off_t to handle large file sizes */ - char *postdata; - - const char *p_pragma; /* Pragma: string */ - const char *p_accept; /* Accept: string */ - curl_off_t readbytecount; - curl_off_t writebytecount; - - /* For FORM posting */ - struct Form form; - struct Curl_chunker chunk; - - struct back { - curl_read_callback fread; /* backup storage for fread pointer */ - void *fread_in; /* backup storage for fread_in pointer */ - char *postdata; - curl_off_t postsize; - } backup; - - enum { - HTTPSEND_NADA, /* init */ - HTTPSEND_REQUEST, /* sending a request */ - HTTPSEND_BODY, /* sending body */ - HTTPSEND_LAST /* never use this */ - } sending; - - void *send_buffer; /* used if the request couldn't be sent in one chunk, - points to an allocated send_buffer struct */ -}; - -/**************************************************************************** - * FTP unique setup - ***************************************************************************/ -struct FTP { - curl_off_t *bytecountp; - char *user; /* user name string */ - char *passwd; /* password string */ - char *urlpath; /* the originally given path part of the URL */ - char **dirs; /* realloc()ed array for path components */ - int dirdepth; /* number of entries used in the 'dirs' array */ - int diralloc; /* number of entries allocated for the 'dirs' array */ - char *file; /* decoded file */ - - char *entrypath; /* the PWD reply when we logged on */ - - char *cache; /* data cache between getresponse()-calls */ - curl_off_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) */ - long response_time; /* When no timeout is given, this is the amount of - seconds we await for an FTP response. Initialized - in Curl_ftp_connect() */ - bool ctl_valid; /* Tells Curl_ftp_quit() whether or not to do - anything. If the connection has timed out or - been closed, this should be FALSE when it gets - to Curl_ftp_quit() */ -}; - -/**************************************************************************** - * FILE unique setup - ***************************************************************************/ -struct FILEPROTO { - char *path; /* the path we operate on */ - char *freepath; /* pointer to the allocated block we must free, this might - differ from the 'path' pointer */ - int fd; /* open file descriptor to read from! */ -}; - -/* - * Boolean values that concerns this connection. - */ -struct ConnectBits { - bool close; /* if set, we close the connection after this request */ - bool reuse; /* if set, this is a re-used connection */ - bool chunk; /* if set, this is a chunked transfer-encoding */ - bool httpproxy; /* if set, this transfer is done through a http proxy */ - bool user_passwd; /* do we use user+password for this connection? */ - bool proxy_user_passwd; /* user+password for the proxy? */ - bool ipv6_ip; /* we communicate with a remove site specified with pure IPv6 - IP address */ - bool use_range; - bool rangestringalloc; /* the range string is malloc()'ed */ - - bool do_more; /* this is set TRUE if the ->curl_do_more() function is - supposed to be called, after ->curl_do() */ - - bool upload_chunky; /* set TRUE if we are doing chunked transfer-encoding - on upload */ - bool getheader; /* TRUE if header parsing is wanted */ - - bool forbidchunk; /* used only to explicitly forbid chunk-upload for - specific upload buffers. See readmoredata() in - http.c for details. */ - bool tcpconnect; /* the tcp stream (or simimlar) is connected, this - is set the first time on the first connect function - call */ - bool retry; /* this connection is about to get closed and then - re-attempted at another connection. */ - bool no_body; /* CURLOPT_NO_BODY (or similar) was set */ - bool tunnel_proxy; /* if CONNECT is used to "tunnel" through the proxy. - This is implicit when SSL-protocols are used through - proxies, but can also be enabled explicitly by - apps */ - bool authprobe; /* set TRUE when this transfer is done to probe for auth - types, as when asking for "any" type when speaking - HTTP */ -}; - -struct hostname { - char *rawalloc; /* allocated "raw" version of the name */ - char *encalloc; /* allocated IDN-encoded version of the name */ - char *name; /* name to use internally, might be encoded, might be raw */ - char *dispname; /* name to display, as 'name' might be encoded */ -}; - -/* - * This struct is all the previously local variables from Curl_perform() moved - * to struct to allow the function to return and get re-invoked better without - * losing state. - */ - -struct Curl_transfer_keeper { - curl_off_t bytecount; /* total number of bytes read */ - curl_off_t writebytecount; /* number of bytes written */ - struct timeval start; /* transfer started at this time */ - struct timeval now; /* current time */ - bool header; /* incoming data has HTTP header */ - enum { - HEADER_NORMAL, /* no bad header at all */ - HEADER_PARTHEADER, /* part of the chunk is a bad header, the rest - is normal data */ - HEADER_ALLBAD /* all was believed to be header */ - } badheader; /* the header was deemed bad and will be - written as body */ - int headerline; /* counts header lines to better track the - first one */ - char *hbufp; /* points at *end* of header line */ - size_t hbuflen; - char *str; /* within buf */ - char *str_start; /* within buf */ - char *end_ptr; /* within buf */ - char *p; /* within headerbuff */ - bool content_range; /* set TRUE if Content-Range: was found */ - curl_off_t offset; /* possible resume offset read from the - Content-Range: header */ - int httpcode; /* error code from the 'HTTP/1.? XXX' line */ - int httpversion; /* the HTTP version*10 */ - struct timeval start100; /* time stamp to wait for the 100 code from */ - bool write_after_100_header; /* TRUE = we enable the write after we - received a 100-continue/timeout or - FALSE = directly */ - bool wait100_after_headers; /* TRUE = after the request-headers have been - sent off properly, we go into the wait100 - state, FALSE = don't */ - 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-Encoding header. */ - z_stream z; /* State structure for zlib. */ -#endif - - time_t timeofdoc; - long bodywrites; - - char *buf; - char *uploadbuf; - curl_socket_t maxfd; - - /* pointers to the actual descriptors we check */ - fd_set *readfdp; - fd_set *writefdp; - - /* the file descriptors to play with */ - fd_set readfd; - fd_set writefd; - fd_set rkeepfd; - fd_set wkeepfd; - int keepon; - - bool upload_done; /* set to TRUE when doing chunked transfer-encoding upload - and we're uploading the last chunk */ - - bool ignorebody; /* we read a response-body but we ignore it! */ -}; - -#if defined(USE_ARES) || defined(USE_THREADING_GETHOSTBYNAME) || \ - defined(USE_THREADING_GETADDRINFO) -struct Curl_async { - char *hostname; - int port; - struct Curl_dns_entry *dns; - bool done; /* set TRUE when the lookup is complete */ - int status; /* if done is TRUE, this is the status from the callback */ - void *os_specific; /* 'struct thread_data' for Windows */ -}; -#endif - -#define FIRSTSOCKET 0 -#define SECONDARYSOCKET 1 - -/* - * The connectdata struct contains all fields and variables that should be - * unique for an entire connection. - */ -struct connectdata { - /**** Fields set when inited and not modified again */ - struct SessionHandle *data; /* link to the root CURL struct */ - long connectindex; /* what index in the connects index this particular - struct has */ - - long protocol; /* PROT_* flags concerning the protocol set */ -#define PROT_MISSING (1<<0) -#define PROT_GOPHER (1<<1) -#define PROT_HTTP (1<<2) -#define PROT_HTTPS (1<<3) -#define PROT_FTP (1<<4) -#define PROT_TELNET (1<<5) -#define PROT_DICT (1<<6) -#define PROT_LDAP (1<<7) -#define PROT_FILE (1<<8) -#define PROT_FTPS (1<<9) -#define PROT_SSL (1<<10) /* protocol requires SSL */ - - /* the particular host we use, in two different ways */ - struct Curl_dns_entry *dns_entry; - Curl_addrinfo *ip_addr; /* the particular IP we connected to */ - - char protostr[16]; /* store the protocol string in this buffer */ - - struct hostname host; - struct hostname proxy; - - char *pathbuffer;/* allocated buffer to store the URL's path part in */ - char *path; /* path to use, points to somewhere within the pathbuffer - area */ - long port; /* which port to use locally */ - unsigned short remote_port; /* what remote port to connect to, - not the proxy port! */ - curl_off_t bytecount; - long headerbytecount; /* only count received headers */ - long deductheadercount; /* this amount of bytes doesn't count when we check - if anything has been transfered at the end of - a connection. We use this counter to make only - a 100 reply (without a following second response - code) result in a CURLE_GOT_NOTHING error code */ - - char *range; /* range, if used. See README for detailed specification on - this syntax. */ - curl_off_t resume_from; /* continue [ftp] transfer from here */ - - char *user; /* user name string, allocated */ - char *passwd; /* password string, allocated */ - - char *proxyuser; /* proxy user name string, allocated */ - char *proxypasswd; /* proxy password string, allocated */ - - struct timeval now; /* "current" time */ - struct timeval created; /* creation time */ - curl_socket_t sock[2]; /* two sockets, the second is used for the data - transfer when doing FTP */ - curl_off_t maxdownload; /* in bytes, the maximum amount of data to fetch, 0 - means unlimited */ - - struct ssl_connect_data ssl[2]; /* this is for ssl-stuff */ - struct ssl_config_data ssl_config; - - struct ConnectBits bits; /* various state-flags for this connection */ - - /* These two functions MUST be set by the curl_connect() function to be - be protocol dependent */ - CURLcode (*curl_do)(struct connectdata *); - CURLcode (*curl_done)(struct connectdata *, CURLcode); - - /* 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 *); - - /* 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. - */ - CURLcode (*curl_connect)(struct connectdata *); - - /* This function *MAY* be set to a protocol-dependent function that is run - * by the curl_disconnect(), as a step in the disconnection. - */ - CURLcode (*curl_disconnect)(struct connectdata *); - - /* This function *MAY* be set to a protocol-dependent function that is run - * in the curl_close() function if protocol-specific cleanups are required. - */ - CURLcode (*curl_close)(struct connectdata *); - - /**** curl_get() phase fields */ - - /* READ stuff */ - curl_socket_t sockfd; /* socket to read from or CURL_SOCKET_BAD */ - curl_off_t size; /* -1 if unknown at this point */ - curl_off_t *bytecountp; /* return number of bytes read or NULL */ - - /* WRITE stuff */ - curl_socket_t writesockfd; /* socket to write to, it may very - well be the same we read from. - CURL_SOCKET_BAD disables */ - curl_off_t *writebytecountp; /* return number of bytes written or NULL */ - - /** Dynamicly allocated strings, may need to be freed before this **/ - /** struct is killed. **/ - struct dynamically_allocated_data { - char *proxyuserpwd; /* free later if not NULL! */ - char *uagent; /* free later if not NULL! */ - char *accept_encoding; /* free later if not NULL! */ - char *userpwd; /* free later if not NULL! */ - char *rangeline; /* free later if not NULL! */ - char *ref; /* free later if not NULL! */ - char *host; /* free later if not NULL */ - char *cookiehost; /* free later if not NULL */ - } allocptr; - - char *newurl; /* This can only be set if a Location: was in the - document headers */ - -#ifdef HAVE_KRB4 - enum protection_level command_prot; - enum protection_level data_prot; - enum protection_level request_data_prot; - - size_t buffer_size; - - struct krb4buffer in_buffer, out_buffer; - int sec_complete; - void *app_data; - - struct Curl_sec_client_mech *mech; - struct sockaddr_in local_addr; - -#endif - - /*************** Request - specific items ************/ - /* previously this was in the urldata struct */ - union { - struct HTTP *http; - struct HTTP *gopher; /* alias, just for the sake of being more readable */ - struct HTTP *https; /* alias, just for the sake of being more readable */ - struct FTP *ftp; - struct FILEPROTO *file; - void *telnet; /* private for telnet.c-eyes only */ - void *generic; - } proto; - - /* This struct is inited when needed */ - struct Curl_transfer_keeper keep; - - /* 'upload_present' is used to keep a byte counter of how much data there is - still left in the buffer, aimed for upload. */ - ssize_t upload_present; - - /* 'upload_fromhere' is used as a read-pointer when we uploaded parts of a - buffer, so the next read should read from where this pointer points to, - and the 'upload_present' contains the number of bytes available at this - position */ - char *upload_fromhere; - - curl_read_callback fread; /* function that reads the input */ - void *fread_in; /* pointer to pass to the fread() above */ - - struct ntlmdata ntlm; /* NTLM differs from other authentication schemes - because it authenticates connections, not - single requests! */ - struct ntlmdata proxyntlm; /* NTLM data for proxy */ - - char syserr_buf [256]; /* buffer for Curl_strerror() */ - -#if defined(USE_ARES) || defined(USE_THREADING_GETHOSTBYNAME) || \ - defined(USE_THREADING_GETADDRINFO) - /* data used for the asynch name resolve callback */ - struct Curl_async async; -#endif - struct connectdata *sec_conn; /* secondary connection for 3rd party - transfer */ -}; - -/* The end of connectdata. */ - -/* - * Struct to keep statistical and informational data. - */ -struct PureInfo { - int httpcode; /* Recent HTTP or FTP response code */ - int httpproxycode; - int httpversion; - long filetime; /* If requested, this is might get set. Set to -1 if the time - was unretrievable. We cannot have this of type time_t, - since time_t is unsigned on several platforms such as - OpenVMS. */ - long header_size; /* size of read header(s) in bytes */ - long request_size; /* the amount of bytes sent in the request(s) */ - - long proxyauthavail; - long httpauthavail; - - char *contenttype; /* the content type of the object */ -}; - - -struct Progress { - long lastshow; /* time() of the last displayed progress meter or NULL to - force redraw at next call */ - curl_off_t size_dl; /* total expected size */ - curl_off_t size_ul; /* total expected size */ - curl_off_t downloaded; /* transfered so far */ - curl_off_t uploaded; /* transfered so far */ - - curl_off_t current_speed; /* uses the currently fastest transfer */ - - bool callback; /* set when progress callback is used */ - int width; /* screen width at download start */ - int flags; /* see progress.h */ - - double timespent; - - curl_off_t dlspeed; - curl_off_t ulspeed; - - double t_nslookup; - double t_connect; - double t_pretransfer; - double t_starttransfer; - double t_redirect; - - struct timeval start; - struct timeval t_startsingle; -#define CURR_TIME (5+1) /* 6 entries for 5 seconds */ - - curl_off_t speeder[ CURR_TIME ]; - struct timeval speeder_time[ CURR_TIME ]; - int speeder_c; -}; - -typedef enum { - HTTPREQ_NONE, /* first in list */ - HTTPREQ_GET, - HTTPREQ_POST, - HTTPREQ_POST_FORM, /* we make a difference internally */ - HTTPREQ_PUT, - HTTPREQ_HEAD, - HTTPREQ_CUSTOM, - HTTPREQ_LAST /* last in list */ -} Curl_HttpReq; - -/* - * Values that are generated, temporary or calculated internally for a - * "session handle" must be defined within the 'struct urlstate'. This struct - * will be used within the SessionHandle struct. When the 'SessionHandle' - * struct is cloned, this data MUST NOT be copied. - * - * Remember that any "state" information goes globally for the curl handle. - * Session-data MUST be put in the connectdata struct and here. */ -#define MAX_CURL_USER_LENGTH 256 -#define MAX_CURL_PASSWORD_LENGTH 256 -#define MAX_CURL_USER_LENGTH_TXT "255" -#define MAX_CURL_PASSWORD_LENGTH_TXT "255" - -struct auth { - long want; /* Bitmask set to the authentication methods wanted by the app - (with CURLOPT_HTTPAUTH or CURLOPT_PROXYAUTH). */ - long picked; - long avail; /* bitmask for what the server reports to support for this - resource */ - bool done; /* TRUE when the auth phase is done and ready to do the *actual* - request */ -}; - -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 */ - struct timeval keeps_speed; /* for the progress meter really */ - - /* 'connects' will be an allocated array with pointers. If the pointer is - set, it holds an allocated connection. */ - struct connectdata **connects; - long numconnects; /* size of the 'connects' array */ - - char *headerbuff; /* allocated buffer to store headers in */ - size_t headersize; /* size of the allocation */ - - char buffer[BUFSIZE+1]; /* download buffer */ - char uploadbuffer[BUFSIZE+1]; /* upload buffer */ - curl_off_t current_speed; /* the ProgressShow() funcion sets this, - bytes / second */ - bool this_is_a_follow; /* this is a followed Location: request */ - - char *auth_host; /* if set, this should be the host name that we will - sent authorization to, no else. Used to make Location: - following not keep sending user+password... This is - strdup() data. - */ - - struct curl_ssl_session *session; /* array of 'numsessions' size */ - long sessionage; /* number of the most recent session */ - - char *scratch; /* huge buffer[BUFSIZE*2] when doing upload CRLF replacing */ - bool errorbuf; /* Set to TRUE if the error buffer is already filled in. - This must be set to FALSE every time _easy_perform() is - called. */ - -#ifdef HAVE_SIGNAL - /* storage for the previous bag^H^H^HSIGPIPE signal handler :-) */ - void (*prev_signal)(int sig); -#endif - bool allow_port; /* Is set.use_port allowed to take effect or not. This - is always set TRUE when curl_easy_perform() is called. */ - - struct digestdata digest; - struct digestdata proxydigest; - -#ifdef HAVE_GSSAPI - struct negotiatedata negotiate; -#endif - - struct auth authhost; - struct auth authproxy; - - bool authproblem; /* TRUE if there's some problem authenticating */ -#ifdef USE_ARES - ares_channel areschannel; /* for name resolves */ -#endif -}; - - -/* - * This 'DynamicStatic' struct defines dynamic states that actually change - * values in the 'UserDefined' area, which MUST be taken into consideration - * if the UserDefined struct is cloned or similar. You can probably just - * copy these, but each one indicate a special action on other data. - */ - -struct DynamicStatic { - char *url; /* work URL, copied from UserDefined */ - bool url_alloc; /* URL string is malloc()'ed */ - bool url_changed; /* set on CURL_OPT_URL, used to detect if the URL was - changed after the connect phase, as we allow callback - to change it and if so, we reconnect to use the new - URL instead */ - char *proxy; /* work proxy, copied from UserDefined */ - bool proxy_alloc; /* http proxy string is malloc()'ed */ - char *referer; /* referer string */ - bool referer_alloc; /* referer sting is malloc()ed */ - struct curl_slist *cookielist; /* list of cookie files set by - curl_easy_setopt(COOKIEFILE) calls */ -}; - -/* - * This 'UserDefined' struct must only contain data that is set once to go - * for many (perhaps) independent connections. Values that are generated or - * calculated internally for the "session handle" MUST be defined within the - * 'struct urlstate' instead. The only exceptions MUST note the changes in - * the 'DynamicStatic' struct. - */ - -struct UserDefined { - FILE *err; /* the stderr user data goes here */ - void *debugdata; /* the data that will be passed to fdebug */ - char *errorbuffer; /* store failure messages in here */ - char *proxyuserpwd; /* Proxy <user:password>, if used */ - long proxyport; /* If non-zero, use this port number by default. If the - proxy string features a ":[port]" that one will override - this. */ - void *out; /* the fetched file goes here */ - void *in; /* the uploaded file is read from here */ - void *writeheader; /* write the header to this is non-NULL */ - char *set_url; /* what original URL to work on */ - char *set_proxy; /* proxy to use */ - long use_port; /* which port to use (when not using default) */ - char *userpwd; /* <user:password>, if used */ - long httpauth; /* what kind of HTTP authentication to use (bitmask) */ - long proxyauth; /* what kind of proxy authentication to use (bitmask) */ - char *set_range; /* range, if used. See README for detailed specification - on this syntax. */ - long followlocation; /* as in HTTP Location: */ - long maxredirs; /* maximum no. of http(s) redirects to follow */ - char *set_referer; /* custom string */ - bool free_referer; /* set TRUE if 'referer' points to a string we - allocated */ - char *useragent; /* User-Agent string */ - char *encoding; /* Accept-Encoding string */ - char *postfields; /* if POST, set the fields' values here */ - curl_off_t postfieldsize; /* if POST, this might have a size to use instead - of strlen(), and then the data *may* be binary - (contain zero bytes) */ - char *ftpport; /* port to send with the FTP PORT command */ - char *device; /* network interface to use */ - curl_write_callback fwrite; /* function that stores the output */ - curl_write_callback fwrite_header; /* function that stores headers */ - curl_read_callback fread; /* function that reads the input */ - curl_progress_callback fprogress; /* function for progress information */ - curl_debug_callback fdebug; /* function that write informational data */ - void *progress_client; /* pointer to pass to the progress callback */ - long timeout; /* in seconds, 0 means no timeout */ - long connecttimeout; /* in seconds, 0 means no timeout */ - long ftp_response_timeout; /* in seconds, 0 means no timeout */ - curl_off_t infilesize; /* size of file to upload, -1 means unknown */ - long low_speed_limit; /* bytes/second */ - long low_speed_time; /* number of seconds */ - curl_off_t set_resume_from; /* continue [ftp] transfer from here */ - char *cookie; /* HTTP cookie string to send */ - struct curl_slist *headers; /* linked list of extra headers */ - struct curl_httppost *httppost; /* linked list of POST data */ - char *cert; /* certificate */ - char *cert_type; /* format for certificate (default: PEM) */ - char *key; /* private key */ - char *key_type; /* format for private key (default: PEM) */ - char *key_passwd; /* plain text private key password */ - char *crypto_engine; /* name of the crypto engine to use */ - char *cookiejar; /* dump all cookies to this file */ - bool cookiesession; /* new cookie session? */ - bool crlf; /* convert crlf on ftp upload(?) */ - struct curl_slist *quote; /* after connection is established */ - struct curl_slist *postquote; /* after the transfer */ - struct curl_slist *prequote; /* before the transfer, after type */ - struct curl_slist *source_prequote; /* in 3rd party transfer mode - before - the transfer on source host */ - struct curl_slist *source_postquote; /* in 3rd party transfer mode - after - the transfer on source host */ - struct curl_slist *telnet_options; /* linked list of telnet options */ - curl_TimeCond timecondition; /* kind of time/date comparison */ - time_t timevalue; /* what time to compare with */ - curl_closepolicy closepolicy; /* connection cache close concept */ - Curl_HttpReq httpreq; /* what kind of HTTP request (if any) is this */ - char *customrequest; /* HTTP/FTP request to use */ - long httpversion; /* when non-zero, a specific HTTP version requested to - be used in the library's request(s) */ - char *auth_host; /* if set, this is the allocated string to the host name - * to which to send the authorization data to, and no other - * host (which location-following otherwise could lead to) - */ - char *krb4_level; /* what security level */ - struct ssl_config_data ssl; /* user defined SSL stuff */ - - curl_proxytype proxytype; /* what kind of proxy that is in use */ - - int dns_cache_timeout; /* DNS cache timeout */ - long buffer_size; /* size of receive buffer to use */ - - char *private; /* Private data */ - - struct curl_slist *http200aliases; /* linked list of aliases for http200 */ - - long ip_version; - - curl_off_t max_filesize; /* Maximum file size to download */ - - char *source_host; /* for 3rd party transfer */ - char *source_port; /* for 3rd party transfer */ - char *source_userpwd; /* for 3rd party transfer */ - char *source_path; /* for 3rd party transfer */ - curl_pasv_side pasvHost; /* for 3rd party transfer indicates passive host */ - -/* Here follows boolean settings that define how to behave during - this session. They are STATIC, set by libcurl users or at least initially - and they don't change during operations. */ - - bool printhost; /* printing host name in debug info */ - bool get_filetime; - bool tunnel_thru_httpproxy; - bool ftp_append; - bool ftp_ascii; - bool ftp_list_only; - bool ftp_create_missing_dirs; - bool ftp_use_port; - bool hide_progress; - bool http_fail_on_error; - bool http_follow_location; - bool http_disable_hostname_check_before_authentication; - bool include_header; /* include received protocol headers in data output */ - bool http_set_referer; - bool http_auto_referer; /* set "correct" referer when following location: */ - bool opt_no_body; /* as set with CURLOPT_NO_BODY */ - bool set_port; - bool upload; - enum CURL_NETRC_OPTION - use_netrc; /* defined in include/curl.h */ - char *netrc_file; /* if not NULL, use this instead of trying to find - $HOME/.netrc */ - bool verbose; - bool krb4; /* kerberos4 connection requested */ - bool reuse_forbid; /* forbidden to be reused, close after use */ - bool reuse_fresh; /* do not re-use an existing connection */ - bool expect100header; /* TRUE if we added Expect: 100-continue */ - bool ftp_use_epsv; /* if EPSV is to be attempted or not */ - bool ftp_use_eprt; /* if EPRT is to be attempted or not */ - curl_ftpssl ftp_ssl; /* if AUTH TLS is to be attempted etc */ - bool no_signal; /* do not use any signal/alarm handler */ - bool global_dns_cache; /* subject for future removal */ - bool tcp_nodelay; /* whether to enable TCP_NODELAY or not */ - -}; - -/* - * In August 2001, this struct was redesigned and is since stricter than - * before. The 'connectdata' struct MUST have all the connection oriented - * stuff as we may now have several simultaneous connections and connection - * structs in memory. - * - * From now on, the 'SessionHandle' must only contain data that is set once to - * go for many (perhaps) independent connections. Values that are generated or - * calculated internally for the "session handle" must be defined within the - * 'struct urlstate' instead. */ - -struct SessionHandle { - curl_hash *hostcache; - struct Curl_share *share; /* Share, handles global variable mutexing */ - struct UserDefined set; /* values set by the libcurl user */ - struct DynamicStatic change; /* possibly modified userdefined data */ - - struct CookieInfo *cookies; /* the cookies, read from files and servers */ - struct Progress progress; /* for all the progress meter data */ - struct UrlState state; /* struct for fields used for state info and - other dynamic purposes */ - struct PureInfo info; /* stats, reports and info data */ -#if defined(USE_SSLEAY) && defined(HAVE_OPENSSL_ENGINE_H) - ENGINE* engine; -#endif /* USE_SSLEAY */ -}; - -#define LIBCURL_NAME "libcurl" - -#endif diff --git a/Source/CTest/Curl/version.c b/Source/CTest/Curl/version.c deleted file mode 100644 index 4af298b..0000000 --- a/Source/CTest/Curl/version.c +++ /dev/null @@ -1,261 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2004, 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 <string.h> -#include <stdio.h> - -#include <curl/curl.h> -#include "urldata.h" - -#define _MPRINTF_REPLACE /* use the internal *printf() functions */ -#include <curl/mprintf.h> - -#ifdef USE_ARES -#include <ares_version.h> -#endif - -#ifdef USE_LIBIDN -#include <stringprep.h> -#endif - -#ifdef USE_SSLEAY -static int getssl_version(char *ptr, size_t left, long *num) -{ - -#if (SSLEAY_VERSION_NUMBER >= 0x905000) - { - char sub[2]; - unsigned long ssleay_value; - sub[1]='\0'; - ssleay_value=SSLeay(); - *num = (long)ssleay_value; - if(ssleay_value < 0x906000) { - ssleay_value=SSLEAY_VERSION_NUMBER; - sub[0]='\0'; - } - else { - if(ssleay_value&0xff0) { - sub[0]=(char)((ssleay_value>>4)&0xff) + 'a' -1; - } - else - sub[0]='\0'; - } - - return snprintf(ptr, left, " OpenSSL/%lx.%lx.%lx%s", - (ssleay_value>>28)&0xf, - (ssleay_value>>20)&0xff, - (ssleay_value>>12)&0xff, - sub); - } - -#else - *num = SSLEAY_VERSION_NUMBER; -#if (SSLEAY_VERSION_NUMBER >= 0x900000) - return snprintf(ptr, left, " OpenSSL/%lx.%lx.%lx", - (SSLEAY_VERSION_NUMBER>>28)&0xff, - (SSLEAY_VERSION_NUMBER>>20)&0xff, - (SSLEAY_VERSION_NUMBER>>12)&0xf); -#else - { - char sub[2]; - sub[1]='\0'; - if(SSLEAY_VERSION_NUMBER&0x0f) { - sub[0]=(SSLEAY_VERSION_NUMBER&0x0f) + 'a' -1; - } - else - sub[0]='\0'; - - return snprintf(ptr, left, " SSL/%x.%x.%x%s", - (SSLEAY_VERSION_NUMBER>>12)&0xff, - (SSLEAY_VERSION_NUMBER>>8)&0xf, - (SSLEAY_VERSION_NUMBER>>4)&0xf, sub); - } -#endif -#endif -} - -#endif - -char *curl_version(void) -{ - static char version[200]; - char *ptr=version; - /* to prevent compier warnings, we only declare len if we have code - that uses it */ -#if defined(USE_SSLEAY) || defined(HAVE_LIBZ) || defined(USE_ARES) || \ - defined(USE_LIBIDN) - int len; -#endif - size_t left = sizeof(version); - strcpy(ptr, LIBCURL_NAME "/" LIBCURL_VERSION ); - ptr=strchr(ptr, '\0'); - left -= strlen(ptr); - (void)left; - -#ifdef USE_SSLEAY - { - long num; - len = getssl_version(ptr, left, &num); - left -= len; - ptr += len; - } -#endif - -#ifdef HAVE_LIBZ - len = snprintf(ptr, left, " zlib/%s", zlibVersion()); - left -= len; - ptr += len; -#endif -#ifdef USE_ARES - /* this function is only present in c-ares, not in the original ares */ - len = snprintf(ptr, left, " c-ares/%s", ares_version(NULL)); - left -= len; - ptr += len; -#endif -#ifdef USE_LIBIDN - if(stringprep_check_version(LIBIDN_REQUIRED_VERSION)) { - len = snprintf(ptr, left, " libidn/%s", stringprep_check_version(NULL)); - left -= len; - ptr += len; - } -#endif - - return version; -} - -/* data for curl_version_info */ - -static const char *protocols[] = { -#ifndef CURL_DISABLE_FTP - "ftp", -#endif -#ifndef CURL_DISABLE_GOPHER - "gopher", -#endif -#ifndef CURL_DISABLE_TELNET - "telnet", -#endif -#ifndef CURL_DISABLE_DICT - "dict", -#endif -#ifndef CURL_DISABLE_LDAP - "ldap", -#endif -#ifndef CURL_DISABLE_HTTP - "http", -#endif -#ifndef CURL_DISABLE_FILE - "file", -#endif - -#ifdef USE_SSLEAY -#ifndef CURL_DISABLE_HTTP - "https", -#endif -#ifndef CURL_DISABLE_FTP - "ftps", -#endif -#endif - NULL -}; - -static curl_version_info_data version_info = { - CURLVERSION_NOW, - 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 HAVE_KRB4 - | CURL_VERSION_KERBEROS4 -#endif -#ifdef USE_SSLEAY - | CURL_VERSION_SSL - | CURL_VERSION_NTLM /* since this requires OpenSSL */ -#endif -#ifdef HAVE_LIBZ - | CURL_VERSION_LIBZ -#endif -#ifdef HAVE_GSSAPI - | CURL_VERSION_GSSNEGOTIATE -#endif -#ifdef CURLDEBUG - | CURL_VERSION_DEBUG -#endif -#ifdef USE_ARES - | CURL_VERSION_ASYNCHDNS -#endif -#ifdef HAVE_SPNEGO - | CURL_VERSION_SPNEGO -#endif -#if defined(ENABLE_64BIT) && (SIZEOF_CURL_OFF_T > 4) - | CURL_VERSION_LARGEFILE -#endif - , - NULL, /* ssl_version */ - 0, /* ssl_version_num */ - NULL, /* zlib_version */ - protocols, - NULL, /* c-ares version */ - 0, /* c-ares version numerical */ - NULL, /* libidn version */ -}; - -curl_version_info_data *curl_version_info(CURLversion stamp) -{ -#ifdef USE_SSLEAY - static char ssl_buffer[80]; - long num; - getssl_version(ssl_buffer, sizeof(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 -#ifdef USE_ARES - { - int aresnum; - version_info.ares = ares_version(&aresnum); - version_info.ares_num = aresnum; - } -#endif -#ifdef USE_LIBIDN - /* This returns a version string if we use the given version or later, - otherwise it returns NULL */ - version_info.libidn = stringprep_check_version(LIBIDN_REQUIRED_VERSION); - if(version_info.libidn) - version_info.features |= CURL_VERSION_IDN; -#endif - (void)stamp; /* avoid compiler warnings, we don't use this */ - - return &version_info; -} |