Merge topic 'update-curl'

c02c747b Tests: Update expected CTestTestFailedSubmit output
a427ed0c curl: Skip sanity check that triggers Clang warning
17b24d55 curl: Disable warnings to avoid changing 3rd party code
4c3bd340 curl: Skip check for inet_pton on Windows
54cb23c6 curl: Restore installation of OpenSSL DLLs
c50f0327 curl: Restore CURL_CA_BUNDLE option
681693c9 curl: Restore CMake-specific zlib selection code
10d80b68 curl: Restore CMake-specific test and install code
19593042 curl: Configure build to work within CMake
cf54aebb curl: Fix curl.h inclusion of curlbuild.h from CMake sources
c17e3207 curl: Use arch-aware CHECK_TYPE_SIZE results
1f7cb7e2 curl: Fix detection of headers with dependencies
b18c9044 curl: Drop inclusion of .rc file for static lib
860f0a2d curl: Select file APIs on Windows
5a3b55ed curl: Do not use 'dl' on HP-UX
59242702 curl: Simplify if() conditions on check result variables
...
This commit is contained in:
Brad King 2014-11-10 10:43:10 -05:00 committed by CMake Topic Stage
commit 75f3a282b7
325 changed files with 94693 additions and 42433 deletions

View File

@ -271,10 +271,7 @@ macro (CMAKE_BUILD_UTILITIES)
set(CURL_SPECIAL_ZLIB_H ${CMAKE_ZLIB_HEADER})
set(CURL_SPECIAL_LIBZ_INCLUDES ${CMAKE_ZLIB_INCLUDES})
set(CURL_SPECIAL_LIBZ ${CMAKE_ZLIB_LIBRARIES})
option(CMAKE_BUILD_CURL_SHARED "Should curl be built shared" FALSE)
if(NOT CMAKE_BUILD_CURL_SHARED)
add_definitions(-DCURL_STATICLIB)
endif()
set(CMAKE_CURL_INCLUDES)
set(CMAKE_CURL_LIBRARIES cmcurl)
if(CMAKE_TESTS_CDASH_SERVER)

View File

@ -2726,6 +2726,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release
set(regex "${regex}([Cc]ould *n.t resolve host")
set(regex "${regex}|[Cc]ould *n.t connect to host")
set(regex "${regex}|Failed *t*o* connect to")
set(regex "${regex}|Connection timed out after [0-9]+ milliseconds")
set(regex "${regex}|Empty reply from server")
set(regex "${regex}|The requested URL returned error")
set(regex "${regex}|libcurl was built with SSL disabled. https: not supported)")

View File

@ -17,7 +17,7 @@
#ifdef CMAKE_USE_SYSTEM_CURL
# include <curl/curl.h>
#else
# include <cmcurl/curl/curl.h>
# include <cmcurl/include/curl/curl.h>
#endif
#endif

1
Utilities/cmcurl/.gitattributes vendored Normal file
View File

@ -0,0 +1 @@
* -whitespace

View File

@ -12,42 +12,39 @@
# CMAKE_REQUIRED_INCLUDES = list of include directories
# CMAKE_REQUIRED_LIBRARIES = list of libraries to link
MACRO(CURL_CHECK_C_SOURCE_COMPILES SOURCE VAR)
IF(NOT DEFINED ${VAR} OR ${VAR} MATCHES "UNKNOWN")
SET(message "${VAR}")
macro(CURL_CHECK_C_SOURCE_COMPILES SOURCE VAR)
if(NOT DEFINED "${VAR}")
set(message "${VAR}")
# If the number of arguments is greater than 2 (SOURCE VAR)
IF(${ARGC} GREATER 2)
if(${ARGC} GREATER 2)
# then add the third argument as a message
SET(message "${ARGV2} (${VAR})")
ENDIF(${ARGC} GREATER 2)
SET(MACRO_CHECK_FUNCTION_DEFINITIONS
set(message "${ARGV2} (${VAR})")
endif()
set(MACRO_CHECK_FUNCTION_DEFINITIONS
"-D${VAR} ${CMAKE_REQUIRED_FLAGS}")
IF(CMAKE_REQUIRED_LIBRARIES)
SET(CURL_CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES
if(CMAKE_REQUIRED_LIBRARIES)
set(CURL_CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES
"-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}")
ELSE(CMAKE_REQUIRED_LIBRARIES)
SET(CURL_CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES)
ENDIF(CMAKE_REQUIRED_LIBRARIES)
IF(CMAKE_REQUIRED_INCLUDES)
SET(CURL_CHECK_C_SOURCE_COMPILES_ADD_INCLUDES
endif()
if(CMAKE_REQUIRED_INCLUDES)
set(CURL_CHECK_C_SOURCE_COMPILES_ADD_INCLUDES
"-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
ELSE(CMAKE_REQUIRED_INCLUDES)
SET(CURL_CHECK_C_SOURCE_COMPILES_ADD_INCLUDES)
ENDIF(CMAKE_REQUIRED_INCLUDES)
SET(src "")
FOREACH(def ${EXTRA_DEFINES})
SET(src "${src}#define ${def} 1\n")
ENDFOREACH(def)
FOREACH(inc ${HEADER_INCLUDES})
SET(src "${src}#include <${inc}>\n")
ENDFOREACH(inc)
endif()
set(src "")
foreach(def ${EXTRA_DEFINES})
set(src "${src}#define ${def} 1\n")
endforeach(def)
foreach(inc ${HEADER_INCLUDES})
set(src "${src}#include <${inc}>\n")
endforeach(inc)
SET(src "${src}\nint main() { ${SOURCE} ; return 0; }")
SET(CMAKE_CONFIGURABLE_FILE_CONTENT "${src}")
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/CMake/CMakeConfigurableFile.in
"${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c")
MESSAGE(STATUS "Performing Test ${message}")
TRY_COMPILE(${VAR}
set(src "${src}\nint main() { ${SOURCE} ; return 0; }")
set(CMAKE_CONFIGURABLE_FILE_CONTENT "${src}")
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/CMake/CMakeConfigurableFile.in
"${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c"
IMMEDIATE)
message(STATUS "Performing Test ${message}")
try_compile(${VAR}
${CMAKE_BINARY_DIR}
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c
COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
@ -55,20 +52,20 @@ MACRO(CURL_CHECK_C_SOURCE_COMPILES SOURCE VAR)
"${CURL_CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES}"
"${CURL_CHECK_C_SOURCE_COMPILES_ADD_INCLUDES}"
OUTPUT_VARIABLE OUTPUT)
IF(${VAR})
SET(${VAR} 1 CACHE INTERNAL "Test ${message}")
MESSAGE(STATUS "Performing Test ${message} - Success")
FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
if(${VAR})
set(${VAR} 1 CACHE INTERNAL "Test ${message}")
message(STATUS "Performing Test ${message} - Success")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Performing C SOURCE FILE Test ${message} succeded with the following output:\n"
"${OUTPUT}\n"
"Source file was:\n${src}\n")
ELSE(${VAR})
MESSAGE(STATUS "Performing Test ${message} - Failed")
SET(${VAR} "" CACHE INTERNAL "Test ${message}")
FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
else()
message(STATUS "Performing Test ${message} - Failed")
set(${VAR} "" CACHE INTERNAL "Test ${message}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Performing C SOURCE FILE Test ${message} failed with the following output:\n"
"${OUTPUT}\n"
"Source file was:\n${src}\n")
ENDIF(${VAR})
ENDIF()
ENDMACRO(CURL_CHECK_C_SOURCE_COMPILES)
endif()
endif()
endmacro()

View File

@ -12,42 +12,43 @@
# CMAKE_REQUIRED_INCLUDES = list of include directories
# CMAKE_REQUIRED_LIBRARIES = list of libraries to link
MACRO(CURL_CHECK_C_SOURCE_RUNS SOURCE VAR)
IF("${VAR}" MATCHES "^${VAR}$" OR "${VAR}" MATCHES "UNKNOWN")
SET(message "${VAR}")
macro(CURL_CHECK_C_SOURCE_RUNS SOURCE VAR)
if(NOT DEFINED "${VAR}")
set(message "${VAR}")
# If the number of arguments is greater than 2 (SOURCE VAR)
IF(${ARGC} GREATER 2)
if(${ARGC} GREATER 2)
# then add the third argument as a message
SET(message "${ARGV2} (${VAR})")
ENDIF(${ARGC} GREATER 2)
SET(MACRO_CHECK_FUNCTION_DEFINITIONS
set(message "${ARGV2} (${VAR})")
endif(${ARGC} GREATER 2)
set(MACRO_CHECK_FUNCTION_DEFINITIONS
"-D${VAR} ${CMAKE_REQUIRED_FLAGS}")
IF(CMAKE_REQUIRED_LIBRARIES)
SET(CURL_CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES
if(CMAKE_REQUIRED_LIBRARIES)
set(CURL_CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES
"-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}")
ELSE(CMAKE_REQUIRED_LIBRARIES)
SET(CURL_CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES)
ENDIF(CMAKE_REQUIRED_LIBRARIES)
IF(CMAKE_REQUIRED_INCLUDES)
SET(CURL_CHECK_C_SOURCE_COMPILES_ADD_INCLUDES
else(CMAKE_REQUIRED_LIBRARIES)
set(CURL_CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES)
endif(CMAKE_REQUIRED_LIBRARIES)
if(CMAKE_REQUIRED_INCLUDES)
set(CURL_CHECK_C_SOURCE_COMPILES_ADD_INCLUDES
"-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
ELSE(CMAKE_REQUIRED_INCLUDES)
SET(CURL_CHECK_C_SOURCE_COMPILES_ADD_INCLUDES)
ENDIF(CMAKE_REQUIRED_INCLUDES)
SET(src "")
FOREACH(def ${EXTRA_DEFINES})
SET(src "${src}#define ${def} 1\n")
ENDFOREACH(def)
FOREACH(inc ${HEADER_INCLUDES})
SET(src "${src}#include <${inc}>\n")
ENDFOREACH(inc)
else(CMAKE_REQUIRED_INCLUDES)
set(CURL_CHECK_C_SOURCE_COMPILES_ADD_INCLUDES)
endif(CMAKE_REQUIRED_INCLUDES)
set(src "")
foreach(def ${EXTRA_DEFINES})
set(src "${src}#define ${def} 1\n")
endforeach(def)
foreach(inc ${HEADER_INCLUDES})
set(src "${src}#include <${inc}>\n")
endforeach(inc)
SET(src "${src}\nint main() { ${SOURCE} ; return 0; }")
SET(CMAKE_CONFIGURABLE_FILE_CONTENT "${src}")
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/CMake/CMakeConfigurableFile.in
"${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c")
MESSAGE(STATUS "Performing Test ${message}")
TRY_RUN(${VAR} ${VAR}_COMPILED
set(src "${src}\nint main() { ${SOURCE} ; return 0; }")
set(CMAKE_CONFIGURABLE_FILE_CONTENT "${src}")
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/CMake/CMakeConfigurableFile.in
"${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c"
IMMEDIATE)
message(STATUS "Performing Test ${message}")
try_run(${VAR} ${VAR}_COMPILED
${CMAKE_BINARY_DIR}
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c
COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
@ -56,27 +57,27 @@ MACRO(CURL_CHECK_C_SOURCE_RUNS SOURCE VAR)
"${CURL_CHECK_C_SOURCE_COMPILES_ADD_INCLUDES}"
OUTPUT_VARIABLE OUTPUT)
# if it did not compile make the return value fail code of 1
IF(NOT ${VAR}_COMPILED)
SET(${VAR} 1)
ENDIF(NOT ${VAR}_COMPILED)
if(NOT ${VAR}_COMPILED)
set(${VAR} 1)
endif(NOT ${VAR}_COMPILED)
# if the return value was 0 then it worked
SET(result_var ${${VAR}})
IF("${result_var}" EQUAL 0)
SET(${VAR} 1 CACHE INTERNAL "Test ${message}")
MESSAGE(STATUS "Performing Test ${message} - Success")
FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
set(result_var ${${VAR}})
if("${result_var}" EQUAL 0)
set(${VAR} 1 CACHE INTERNAL "Test ${message}")
message(STATUS "Performing Test ${message} - Success")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Performing C SOURCE FILE Test ${message} succeded with the following output:\n"
"${OUTPUT}\n"
"Return value: ${${VAR}}\n"
"Source file was:\n${src}\n")
ELSE("${result_var}" EQUAL 0)
MESSAGE(STATUS "Performing Test ${message} - Failed")
SET(${VAR} "" CACHE INTERNAL "Test ${message}")
FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
else("${result_var}" EQUAL 0)
message(STATUS "Performing Test ${message} - Failed")
set(${VAR} "" CACHE INTERNAL "Test ${message}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Performing C SOURCE FILE Test ${message} failed with the following output:\n"
"${OUTPUT}\n"
"Return value: ${result_var}\n"
"Source file was:\n${src}\n")
ENDIF("${result_var}" EQUAL 0)
ENDIF("${VAR}" MATCHES "^${VAR}$" OR "${VAR}" MATCHES "UNKNOWN")
ENDMACRO(CURL_CHECK_C_SOURCE_RUNS)
endif("${result_var}" EQUAL 0)
endif()
endmacro(CURL_CHECK_C_SOURCE_RUNS)

View File

@ -1,3 +1,24 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute 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.
*
***************************************************************************/
#ifdef TIME_WITH_SYS_TIME
/* Time with sys/time test */
@ -16,33 +37,36 @@ return 0;
#endif
#ifdef HAVE_O_NONBLOCK
#ifdef HAVE_FCNTL_O_NONBLOCK
/* headers for FCNTL_O_NONBLOCK test */
#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(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)
#if (defined(_AIX) || defined(__xlC__)) && !defined(_AIX41)
# 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);
int
main ()
{
/* O_NONBLOCK source test */
int flags = 0;
if(0 != fcntl(0, F_SETFL, flags | O_NONBLOCK))
return 1;
return 0;
}
#endif
@ -339,6 +363,24 @@ if (sizeof (in_addr_t))
return 0;
}
#endif
#ifdef HAVE_BOOL_T
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_STDBOOL_H
#include <stdbool.h>
#endif
int
main ()
{
if (sizeof (bool *) )
return 0;
;
return 0;
}
#endif
#ifdef STDC_HEADERS
#include <stdlib.h>
#include <stdarg.h>
@ -432,7 +474,20 @@ int main(void) {
int main () { ; return 0; }
#endif
#ifdef HAVE_IOCTLSOCKET
/* includes start */
#ifdef HAVE_WINDOWS_H
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif
# include <windows.h>
# ifdef HAVE_WINSOCK2_H
# include <winsock2.h>
# else
# ifdef HAVE_WINSOCK_H
# include <winsock.h>
# endif
# endif
#endif
int
main ()
@ -447,51 +502,181 @@ main ()
}
#endif
#ifdef HAVE_IOCTLSOCKET_CASE
#ifdef HAVE_IOCTLSOCKET_CAMEL
/* includes start */
#ifdef HAVE_WINDOWS_H
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif
# include <windows.h>
# ifdef HAVE_WINSOCK2_H
# include <winsock2.h>
# else
# ifdef HAVE_WINSOCK_H
# include <winsock.h>
# endif
# endif
#endif
int
main ()
{
/* IoctlSocket source code */
int socket;
int flags = IoctlSocket(socket, FIONBIO, (long)1);
if(0 != IoctlSocket(0, 0, 0))
return 1;
;
return 0;
}
#endif
#ifdef HAVE_FIONBIO
/* headers for FIONBIO test */
#include <unistd.h>
#include <stropts.h>
#ifdef HAVE_IOCTLSOCKET_CAMEL_FIONBIO
/* includes start */
#ifdef HAVE_WINDOWS_H
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif
# include <windows.h>
# ifdef HAVE_WINSOCK2_H
# include <winsock2.h>
# else
# ifdef HAVE_WINSOCK_H
# include <winsock.h>
# endif
# endif
#endif
int
main ()
{
/* FIONBIO source test (old-style unix) */
int socket;
int flags = ioctl(socket, FIONBIO, &flags);
/* IoctlSocket source code */
long flags = 0;
if(0 != ioctlsocket(0, FIONBIO, &flags))
return 1;
;
return 0;
}
#endif
#ifdef HAVE_IOCTLSOCKET_FIONBIO
/* includes start */
#ifdef HAVE_WINDOWS_H
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif
# include <windows.h>
# ifdef HAVE_WINSOCK2_H
# include <winsock2.h>
# else
# ifdef HAVE_WINSOCK_H
# include <winsock.h>
# endif
# endif
#endif
int
main ()
{
int flags = 0;
if(0 != ioctlsocket(0, FIONBIO, &flags))
return 1;
;
return 0;
}
#endif
#ifdef HAVE_SO_NONBLOCK
/* headers for SO_NONBLOCK test (BeOS) */
#ifdef HAVE_IOCTL_FIONBIO
/* headers for FIONBIO test */
/* includes start */
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#include <fcntl.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#ifdef HAVE_SYS_IOCTL_H
# include <sys/ioctl.h>
#endif
#ifdef HAVE_STROPTS_H
# include <stropts.h>
#endif
int main()
int
main ()
{
/* SO_NONBLOCK source code */
long b = 1;
int socket;
int flags = setsockopt(socket, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
int flags = 0;
if(0 != ioctl(0, FIONBIO, &flags))
return 1;
;
return 0;
}
#endif
#ifdef HAVE_IOCTL_SIOCGIFADDR
/* headers for FIONBIO test */
/* includes start */
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#ifdef HAVE_SYS_IOCTL_H
# include <sys/ioctl.h>
#endif
#ifdef HAVE_STROPTS_H
# include <stropts.h>
#endif
#include <net/if.h>
int
main ()
{
struct ifreq ifr;
if(0 != ioctl(0, SIOCGIFADDR, &ifr))
return 1;
;
return 0;
}
#endif
#ifdef HAVE_SETSOCKOPT_SO_NONBLOCK
/* includes start */
#ifdef HAVE_WINDOWS_H
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif
# include <windows.h>
# ifdef HAVE_WINSOCK2_H
# include <winsock2.h>
# else
# ifdef HAVE_WINSOCK_H
# include <winsock.h>
# endif
# endif
#endif
/* includes start */
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
/* includes end */
int
main ()
{
if(0 != setsockopt(0, SOL_SOCKET, SO_NONBLOCK, 0, 0))
return 1;
;
return 0;
}
#endif

View File

@ -0,0 +1,42 @@
# - Find c-ares
# Find the c-ares includes and library
# This module defines
# CARES_INCLUDE_DIR, where to find ares.h, etc.
# CARES_LIBRARIES, the libraries needed to use c-ares.
# CARES_FOUND, If false, do not try to use c-ares.
# also defined, but not for general use are
# CARES_LIBRARY, where to find the c-ares library.
FIND_PATH(CARES_INCLUDE_DIR ares.h
/usr/local/include
/usr/include
)
SET(CARES_NAMES ${CARES_NAMES} cares)
FIND_LIBRARY(CARES_LIBRARY
NAMES ${CARES_NAMES}
PATHS /usr/lib /usr/local/lib
)
IF (CARES_LIBRARY AND CARES_INCLUDE_DIR)
SET(CARES_LIBRARIES ${CARES_LIBRARY})
SET(CARES_FOUND "YES")
ELSE (CARES_LIBRARY AND CARES_INCLUDE_DIR)
SET(CARES_FOUND "NO")
ENDIF (CARES_LIBRARY AND CARES_INCLUDE_DIR)
IF (CARES_FOUND)
IF (NOT CARES_FIND_QUIETLY)
MESSAGE(STATUS "Found c-ares: ${CARES_LIBRARIES}")
ENDIF (NOT CARES_FIND_QUIETLY)
ELSE (CARES_FOUND)
IF (CARES_FIND_REQUIRED)
MESSAGE(FATAL_ERROR "Could not find c-ares library")
ENDIF (CARES_FIND_REQUIRED)
ENDIF (CARES_FOUND)
MARK_AS_ADVANCED(
CARES_LIBRARY
CARES_INCLUDE_DIR
)

View File

@ -0,0 +1,35 @@
# - Try to find the libssh2 library
# Once done this will define
#
# LIBSSH2_FOUND - system has the libssh2 library
# LIBSSH2_INCLUDE_DIR - the libssh2 include directory
# LIBSSH2_LIBRARY - the libssh2 library name
if (LIBSSH2_INCLUDE_DIR AND LIBSSH2_LIBRARY)
set(LibSSH2_FIND_QUIETLY TRUE)
endif (LIBSSH2_INCLUDE_DIR AND LIBSSH2_LIBRARY)
FIND_PATH(LIBSSH2_INCLUDE_DIR libssh2.h
)
FIND_LIBRARY(LIBSSH2_LIBRARY NAMES ssh2
)
if(LIBSSH2_INCLUDE_DIR)
file(STRINGS "${LIBSSH2_INCLUDE_DIR}/libssh2.h" libssh2_version_str REGEX "^#define[\t ]+LIBSSH2_VERSION_NUM[\t ]+0x[0-9][0-9][0-9][0-9][0-9][0-9].*")
string(REGEX REPLACE "^.*LIBSSH2_VERSION_NUM[\t ]+0x([0-9][0-9]).*$" "\\1" LIBSSH2_VERSION_MAJOR "${libssh2_version_str}")
string(REGEX REPLACE "^.*LIBSSH2_VERSION_NUM[\t ]+0x[0-9][0-9]([0-9][0-9]).*$" "\\1" LIBSSH2_VERSION_MINOR "${libssh2_version_str}")
string(REGEX REPLACE "^.*LIBSSH2_VERSION_NUM[\t ]+0x[0-9][0-9][0-9][0-9]([0-9][0-9]).*$" "\\1" LIBSSH2_VERSION_PATCH "${libssh2_version_str}")
string(REGEX REPLACE "^0(.+)" "\\1" LIBSSH2_VERSION_MAJOR "${LIBSSH2_VERSION_MAJOR}")
string(REGEX REPLACE "^0(.+)" "\\1" LIBSSH2_VERSION_MINOR "${LIBSSH2_VERSION_MINOR}")
string(REGEX REPLACE "^0(.+)" "\\1" LIBSSH2_VERSION_PATCH "${LIBSSH2_VERSION_PATCH}")
set(LIBSSH2_VERSION "${LIBSSH2_VERSION_MAJOR}.${LIBSSH2_VERSION_MINOR}.${LIBSSH2_VERSION_PATCH}")
endif(LIBSSH2_INCLUDE_DIR)
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibSSH2 DEFAULT_MSG LIBSSH2_INCLUDE_DIR LIBSSH2_LIBRARY )
MARK_AS_ADVANCED(LIBSSH2_INCLUDE_DIR LIBSSH2_LIBRARY LIBSSH2_VERSION_MAJOR LIBSSH2_VERSION_MINOR LIBSSH2_VERSION_PATCH LIBSSH2_VERSION)

View File

@ -0,0 +1,89 @@
#File defines convenience macros for available feature testing
# This macro checks if the symbol exists in the library and if it
# does, it prepends library to the list.
macro(CHECK_LIBRARY_EXISTS_CONCAT LIBRARY SYMBOL VARIABLE)
check_library_exists("${LIBRARY};${CURL_LIBS}" ${SYMBOL} "${CMAKE_LIBRARY_PATH}"
${VARIABLE})
if(${VARIABLE})
set(CURL_LIBS ${LIBRARY} ${CURL_LIBS})
endif(${VARIABLE})
endmacro(CHECK_LIBRARY_EXISTS_CONCAT)
# 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})
set(CURL_TEST_DEFINES "${CURL_TEST_DEFINES} -D${VARIABLE}")
endif(${VARIABLE})
endmacro(CHECK_INCLUDE_FILE_CONCAT)
# For other curl specific tests, use this macro.
macro(CURL_INTERNAL_TEST CURL_TEST)
if(NOT DEFINED "${CURL_TEST}")
set(MACRO_CHECK_FUNCTION_DEFINITIONS
"-D${CURL_TEST} ${CURL_TEST_DEFINES} ${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}
${CMAKE_CURRENT_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")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Performing Curl Test ${CURL_TEST} passed with the following output:\n"
"${OUTPUT}\n")
else(${CURL_TEST})
message(STATUS "Performing Curl Test ${CURL_TEST} - Failed")
set(${CURL_TEST} "" CACHE INTERNAL "Curl test ${FUNCTION}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Performing Curl Test ${CURL_TEST} failed with the following output:\n"
"${OUTPUT}\n")
endif(${CURL_TEST})
endif()
endmacro(CURL_INTERNAL_TEST)
macro(CURL_INTERNAL_TEST_RUN CURL_TEST)
if(NOT DEFINED "${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}
${CMAKE_CURRENT_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}${CMAKE_FILES_DIRECTORY}/CMakeError.log"
"Performing Curl Test ${CURL_TEST} failed with the following output:\n"
"${OUTPUT}")
if(${CURL_TEST}_COMPILE)
file(APPEND
"${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log"
"There was a problem running this test\n")
endif(${CURL_TEST}_COMPILE)
file(APPEND "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log"
"\n\n")
endif(${CURL_TEST}_COMPILE AND NOT ${CURL_TEST})
endif()
endmacro(CURL_INTERNAL_TEST_RUN)

View File

@ -1,50 +1,53 @@
INCLUDE(CurlCheckCSourceCompiles)
SET(EXTRA_DEFINES "__unused1\n#undef inline\n#define __unused2")
SET(HEADER_INCLUDES)
SET(headers_hack)
include(CurlCheckCSourceCompiles)
set(EXTRA_DEFINES "__unused1\n#undef inline\n#define __unused2")
set(HEADER_INCLUDES)
set(headers_hack)
MACRO(add_header_include check header)
IF(${check})
SET(headers_hack
macro(add_header_include check header)
if(${check})
set(headers_hack
"${headers_hack}\n#include <${header}>")
#SET(HEADER_INCLUDES
# ${HEADER_INCLUDES}
# "${header}")
ENDIF(${check})
ENDMACRO(add_header_include)
endif(${check})
endmacro(add_header_include)
SET(signature_call_conv)
IF(HAVE_WINDOWS_H)
set(signature_call_conv)
if(HAVE_WINDOWS_H)
add_header_include(HAVE_WINDOWS_H "windows.h")
add_header_include(HAVE_WINSOCK2_H "winsock2.h")
add_header_include(HAVE_WINSOCK_H "winsock.h")
SET(EXTRA_DEFINES ${EXTRA_DEFINES}
set(EXTRA_DEFINES ${EXTRA_DEFINES}
"__unused7\n#ifndef WIN32_LEAN_AND_MEAN\n#define WIN32_LEAN_AND_MEAN\n#endif\n#define __unused3")
SET(signature_call_conv "PASCAL")
ELSE(HAVE_WINDOWS_H)
set(signature_call_conv "PASCAL")
if(HAVE_LIBWS2_32)
set(CMAKE_REQUIRED_LIBRARIES ws2_32)
endif()
else(HAVE_WINDOWS_H)
add_header_include(HAVE_SYS_TYPES_H "sys/types.h")
add_header_include(HAVE_SYS_SOCKET_H "sys/socket.h")
ENDIF(HAVE_WINDOWS_H)
endif(HAVE_WINDOWS_H)
SET(EXTRA_DEFINES_BACKUP "${EXTRA_DEFINES}")
SET(EXTRA_DEFINES "${EXTRA_DEFINES_BACKUP}\n${headers_hack}\n${extern_line}\n#define __unused5")
CURL_CHECK_C_SOURCE_COMPILES("recv(0, 0, 0, 0)" curl_cv_recv)
IF(curl_cv_recv)
set(EXTRA_DEFINES_BACKUP "${EXTRA_DEFINES}")
set(EXTRA_DEFINES "${EXTRA_DEFINES_BACKUP}\n${headers_hack}\n${extern_line}\n#define __unused5")
curl_check_c_source_compiles("recv(0, 0, 0, 0)" curl_cv_recv)
if(curl_cv_recv)
# AC_CACHE_CHECK([types of arguments and return type for recv],
#[curl_cv_func_recv_args], [
#SET(curl_cv_func_recv_args "unknown")
#for recv_retv in 'int' 'ssize_t'; do
IF(NOT DEFINED curl_cv_func_recv_args OR "${curl_cv_func_recv_args}" STREQUAL "unknown")
FOREACH(recv_retv "int" "ssize_t" )
FOREACH(recv_arg1 "int" "ssize_t" "SOCKET")
FOREACH(recv_arg2 "void *" "char *")
FOREACH(recv_arg3 "size_t" "int" "socklen_t" "unsigned int")
FOREACH(recv_arg4 "int" "unsigned int")
IF(NOT curl_cv_func_recv_done)
SET(curl_cv_func_recv_test "UNKNOWN")
SET(extern_line "extern ${recv_retv} ${signature_call_conv} recv(${recv_arg1}, ${recv_arg2}, ${recv_arg3}, ${recv_arg4})\;")
SET(EXTRA_DEFINES "${EXTRA_DEFINES_BACKUP}\n${headers_hack}\n${extern_line}\n#define __unused5")
CURL_CHECK_C_SOURCE_COMPILES("
if(NOT DEFINED curl_cv_func_recv_args OR "${curl_cv_func_recv_args}" STREQUAL "unknown")
foreach(recv_retv "int" "ssize_t" )
foreach(recv_arg1 "int" "ssize_t" "SOCKET")
foreach(recv_arg2 "void *" "char *")
foreach(recv_arg3 "size_t" "int" "socklen_t" "unsigned int")
foreach(recv_arg4 "int" "unsigned int")
if(NOT curl_cv_func_recv_done)
unset(curl_cv_func_recv_test CACHE)
set(extern_line "extern ${recv_retv} ${signature_call_conv} recv(${recv_arg1}, ${recv_arg2}, ${recv_arg3}, ${recv_arg4})\;")
set(EXTRA_DEFINES "${EXTRA_DEFINES_BACKUP}\n${headers_hack}\n${extern_line}\n#define __unused5")
curl_check_c_source_compiles("
${recv_arg1} s=0;
${recv_arg2} buf=0;
${recv_arg3} len=0;
@ -52,62 +55,62 @@ IF(curl_cv_recv)
${recv_retv} res = recv(s, buf, len, flags)"
curl_cv_func_recv_test
"${recv_retv} recv(${recv_arg1}, ${recv_arg2}, ${recv_arg3}, ${recv_arg4})")
IF(curl_cv_func_recv_test)
SET(curl_cv_func_recv_args
if(curl_cv_func_recv_test)
set(curl_cv_func_recv_args
"${recv_arg1},${recv_arg2},${recv_arg3},${recv_arg4},${recv_retv}")
SET(RECV_TYPE_ARG1 "${recv_arg1}")
SET(RECV_TYPE_ARG2 "${recv_arg2}")
SET(RECV_TYPE_ARG3 "${recv_arg3}")
SET(RECV_TYPE_ARG4 "${recv_arg4}")
SET(RECV_TYPE_RETV "${recv_retv}")
SET(HAVE_RECV 1)
SET(curl_cv_func_recv_done 1)
ENDIF(curl_cv_func_recv_test)
ENDIF(NOT curl_cv_func_recv_done)
ENDFOREACH(recv_arg4)
ENDFOREACH(recv_arg3)
ENDFOREACH(recv_arg2)
ENDFOREACH(recv_arg1)
ENDFOREACH(recv_retv)
ELSE(NOT DEFINED curl_cv_func_recv_args OR "${curl_cv_func_recv_args}" STREQUAL "unknown")
STRING(REGEX REPLACE "^([^,]*),[^,]*,[^,]*,[^,]*,[^,]*$" "\\1" RECV_TYPE_ARG1 "${curl_cv_func_recv_args}")
STRING(REGEX REPLACE "^[^,]*,([^,]*),[^,]*,[^,]*,[^,]*$" "\\1" RECV_TYPE_ARG2 "${curl_cv_func_recv_args}")
STRING(REGEX REPLACE "^[^,]*,[^,]*,([^,]*),[^,]*,[^,]*$" "\\1" RECV_TYPE_ARG3 "${curl_cv_func_recv_args}")
STRING(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,([^,]*),[^,]*$" "\\1" RECV_TYPE_ARG4 "${curl_cv_func_recv_args}")
STRING(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,[^,]*,([^,]*)$" "\\1" RECV_TYPE_RETV "${curl_cv_func_recv_args}")
set(RECV_TYPE_ARG1 "${recv_arg1}")
set(RECV_TYPE_ARG2 "${recv_arg2}")
set(RECV_TYPE_ARG3 "${recv_arg3}")
set(RECV_TYPE_ARG4 "${recv_arg4}")
set(RECV_TYPE_RETV "${recv_retv}")
set(HAVE_RECV 1)
set(curl_cv_func_recv_done 1)
endif(curl_cv_func_recv_test)
endif(NOT curl_cv_func_recv_done)
endforeach(recv_arg4)
endforeach(recv_arg3)
endforeach(recv_arg2)
endforeach(recv_arg1)
endforeach(recv_retv)
else(NOT DEFINED curl_cv_func_recv_args OR "${curl_cv_func_recv_args}" STREQUAL "unknown")
string(REGEX REPLACE "^([^,]*),[^,]*,[^,]*,[^,]*,[^,]*$" "\\1" RECV_TYPE_ARG1 "${curl_cv_func_recv_args}")
string(REGEX REPLACE "^[^,]*,([^,]*),[^,]*,[^,]*,[^,]*$" "\\1" RECV_TYPE_ARG2 "${curl_cv_func_recv_args}")
string(REGEX REPLACE "^[^,]*,[^,]*,([^,]*),[^,]*,[^,]*$" "\\1" RECV_TYPE_ARG3 "${curl_cv_func_recv_args}")
string(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,([^,]*),[^,]*$" "\\1" RECV_TYPE_ARG4 "${curl_cv_func_recv_args}")
string(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,[^,]*,([^,]*)$" "\\1" RECV_TYPE_RETV "${curl_cv_func_recv_args}")
#MESSAGE("RECV_TYPE_ARG1 ${RECV_TYPE_ARG1}")
#MESSAGE("RECV_TYPE_ARG2 ${RECV_TYPE_ARG2}")
#MESSAGE("RECV_TYPE_ARG3 ${RECV_TYPE_ARG3}")
#MESSAGE("RECV_TYPE_ARG4 ${RECV_TYPE_ARG4}")
#MESSAGE("RECV_TYPE_RETV ${RECV_TYPE_RETV}")
ENDIF(NOT DEFINED curl_cv_func_recv_args OR "${curl_cv_func_recv_args}" STREQUAL "unknown")
endif(NOT DEFINED curl_cv_func_recv_args OR "${curl_cv_func_recv_args}" STREQUAL "unknown")
IF("${curl_cv_func_recv_args}" STREQUAL "unknown")
MESSAGE(FATAL_ERROR "Cannot find proper types to use for recv args")
ENDIF("${curl_cv_func_recv_args}" STREQUAL "unknown")
ELSE(curl_cv_recv)
MESSAGE(FATAL_ERROR "Unable to link function recv")
ENDIF(curl_cv_recv)
SET(curl_cv_func_recv_args "${curl_cv_func_recv_args}" CACHE INTERNAL "Arguments for recv")
SET(HAVE_RECV 1)
if("${curl_cv_func_recv_args}" STREQUAL "unknown")
message(FATAL_ERROR "Cannot find proper types to use for recv args")
endif("${curl_cv_func_recv_args}" STREQUAL "unknown")
else(curl_cv_recv)
message(FATAL_ERROR "Unable to link function recv")
endif(curl_cv_recv)
set(curl_cv_func_recv_args "${curl_cv_func_recv_args}" CACHE INTERNAL "Arguments for recv")
set(HAVE_RECV 1)
CURL_CHECK_C_SOURCE_COMPILES("send(0, 0, 0, 0)" curl_cv_send)
IF(curl_cv_send)
curl_check_c_source_compiles("send(0, 0, 0, 0)" curl_cv_send)
if(curl_cv_send)
# AC_CACHE_CHECK([types of arguments and return type for send],
#[curl_cv_func_send_args], [
#SET(curl_cv_func_send_args "unknown")
#for send_retv in 'int' 'ssize_t'; do
IF(NOT DEFINED curl_cv_func_send_args OR "${curl_cv_func_send_args}" STREQUAL "unknown")
FOREACH(send_retv "int" "ssize_t" )
FOREACH(send_arg1 "int" "ssize_t" "SOCKET")
FOREACH(send_arg2 "const void *" "void *" "char *" "const char *")
FOREACH(send_arg3 "size_t" "int" "socklen_t" "unsigned int")
FOREACH(send_arg4 "int" "unsigned int")
IF(NOT curl_cv_func_send_done)
SET(curl_cv_func_send_test "UNKNOWN")
SET(extern_line "extern ${send_retv} ${signature_call_conv} send(${send_arg1}, ${send_arg2}, ${send_arg3}, ${send_arg4})\;")
SET(EXTRA_DEFINES "${EXTRA_DEFINES_BACKUP}\n${headers_hack}\n${extern_line}\n#define __unused5")
CURL_CHECK_C_SOURCE_COMPILES("
if(NOT DEFINED curl_cv_func_send_args OR "${curl_cv_func_send_args}" STREQUAL "unknown")
foreach(send_retv "int" "ssize_t" )
foreach(send_arg1 "int" "ssize_t" "SOCKET")
foreach(send_arg2 "const void *" "void *" "char *" "const char *")
foreach(send_arg3 "size_t" "int" "socklen_t" "unsigned int")
foreach(send_arg4 "int" "unsigned int")
if(NOT curl_cv_func_send_done)
unset(curl_cv_func_send_test CACHE)
set(extern_line "extern ${send_retv} ${signature_call_conv} send(${send_arg1}, ${send_arg2}, ${send_arg3}, ${send_arg4})\;")
set(EXTRA_DEFINES "${EXTRA_DEFINES_BACKUP}\n${headers_hack}\n${extern_line}\n#define __unused5")
curl_check_c_source_compiles("
${send_arg1} s=0;
${send_arg2} buf=0;
${send_arg3} len=0;
@ -115,128 +118,136 @@ IF(curl_cv_send)
${send_retv} res = send(s, buf, len, flags)"
curl_cv_func_send_test
"${send_retv} send(${send_arg1}, ${send_arg2}, ${send_arg3}, ${send_arg4})")
IF(curl_cv_func_send_test)
if(curl_cv_func_send_test)
#MESSAGE("Found arguments: ${curl_cv_func_send_test}")
STRING(REGEX REPLACE "(const) .*" "\\1" send_qual_arg2 "${send_arg2}")
STRING(REGEX REPLACE "const (.*)" "\\1" send_arg2 "${send_arg2}")
SET(curl_cv_func_send_args
string(REGEX REPLACE "(const) .*" "\\1" send_qual_arg2 "${send_arg2}")
string(REGEX REPLACE "const (.*)" "\\1" send_arg2 "${send_arg2}")
set(curl_cv_func_send_args
"${send_arg1},${send_arg2},${send_arg3},${send_arg4},${send_retv},${send_qual_arg2}")
SET(SEND_TYPE_ARG1 "${send_arg1}")
SET(SEND_TYPE_ARG2 "${send_arg2}")
SET(SEND_TYPE_ARG3 "${send_arg3}")
SET(SEND_TYPE_ARG4 "${send_arg4}")
SET(SEND_TYPE_RETV "${send_retv}")
SET(HAVE_SEND 1)
SET(curl_cv_func_send_done 1)
ENDIF(curl_cv_func_send_test)
ENDIF(NOT curl_cv_func_send_done)
ENDFOREACH(send_arg4)
ENDFOREACH(send_arg3)
ENDFOREACH(send_arg2)
ENDFOREACH(send_arg1)
ENDFOREACH(send_retv)
ELSE(NOT DEFINED curl_cv_func_send_args OR "${curl_cv_func_send_args}" STREQUAL "unknown")
STRING(REGEX REPLACE "^([^,]*),[^,]*,[^,]*,[^,]*,[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG1 "${curl_cv_func_send_args}")
STRING(REGEX REPLACE "^[^,]*,([^,]*),[^,]*,[^,]*,[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG2 "${curl_cv_func_send_args}")
STRING(REGEX REPLACE "^[^,]*,[^,]*,([^,]*),[^,]*,[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG3 "${curl_cv_func_send_args}")
STRING(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,([^,]*),[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG4 "${curl_cv_func_send_args}")
STRING(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,[^,]*,([^,]*),[^,]*$" "\\1" SEND_TYPE_RETV "${curl_cv_func_send_args}")
STRING(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,([^,]*)$" "\\1" SEND_QUAL_ARG2 "${curl_cv_func_send_args}")
set(SEND_TYPE_ARG1 "${send_arg1}")
set(SEND_TYPE_ARG2 "${send_arg2}")
set(SEND_TYPE_ARG3 "${send_arg3}")
set(SEND_TYPE_ARG4 "${send_arg4}")
set(SEND_TYPE_RETV "${send_retv}")
set(HAVE_SEND 1)
set(curl_cv_func_send_done 1)
endif(curl_cv_func_send_test)
endif(NOT curl_cv_func_send_done)
endforeach(send_arg4)
endforeach(send_arg3)
endforeach(send_arg2)
endforeach(send_arg1)
endforeach(send_retv)
else(NOT DEFINED curl_cv_func_send_args OR "${curl_cv_func_send_args}" STREQUAL "unknown")
string(REGEX REPLACE "^([^,]*),[^,]*,[^,]*,[^,]*,[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG1 "${curl_cv_func_send_args}")
string(REGEX REPLACE "^[^,]*,([^,]*),[^,]*,[^,]*,[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG2 "${curl_cv_func_send_args}")
string(REGEX REPLACE "^[^,]*,[^,]*,([^,]*),[^,]*,[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG3 "${curl_cv_func_send_args}")
string(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,([^,]*),[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG4 "${curl_cv_func_send_args}")
string(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,[^,]*,([^,]*),[^,]*$" "\\1" SEND_TYPE_RETV "${curl_cv_func_send_args}")
string(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,([^,]*)$" "\\1" SEND_QUAL_ARG2 "${curl_cv_func_send_args}")
#MESSAGE("SEND_TYPE_ARG1 ${SEND_TYPE_ARG1}")
#MESSAGE("SEND_TYPE_ARG2 ${SEND_TYPE_ARG2}")
#MESSAGE("SEND_TYPE_ARG3 ${SEND_TYPE_ARG3}")
#MESSAGE("SEND_TYPE_ARG4 ${SEND_TYPE_ARG4}")
#MESSAGE("SEND_TYPE_RETV ${SEND_TYPE_RETV}")
#MESSAGE("SEND_QUAL_ARG2 ${SEND_QUAL_ARG2}")
ENDIF(NOT DEFINED curl_cv_func_send_args OR "${curl_cv_func_send_args}" STREQUAL "unknown")
endif(NOT DEFINED curl_cv_func_send_args OR "${curl_cv_func_send_args}" STREQUAL "unknown")
IF("${curl_cv_func_send_args}" STREQUAL "unknown")
MESSAGE(FATAL_ERROR "Cannot find proper types to use for send args")
ENDIF("${curl_cv_func_send_args}" STREQUAL "unknown")
SET(SEND_QUAL_ARG2 "const")
ELSE(curl_cv_send)
MESSAGE(FATAL_ERROR "Unable to link function send")
ENDIF(curl_cv_send)
SET(curl_cv_func_send_args "${curl_cv_func_send_args}" CACHE INTERNAL "Arguments for send")
SET(HAVE_SEND 1)
if("${curl_cv_func_send_args}" STREQUAL "unknown")
message(FATAL_ERROR "Cannot find proper types to use for send args")
endif("${curl_cv_func_send_args}" STREQUAL "unknown")
set(SEND_QUAL_ARG2 "const")
else(curl_cv_send)
message(FATAL_ERROR "Unable to link function send")
endif(curl_cv_send)
set(curl_cv_func_send_args "${curl_cv_func_send_args}" CACHE INTERNAL "Arguments for send")
set(HAVE_SEND 1)
SET(EXTRA_DEFINES "${EXTRA_DEFINES}\n${headers_hack}\n#define __unused5")
CURL_CHECK_C_SOURCE_COMPILES("int flag = MSG_NOSIGNAL" HAVE_MSG_NOSIGNAL)
set(EXTRA_DEFINES "${EXTRA_DEFINES}\n${headers_hack}\n#define __unused5")
curl_check_c_source_compiles("int flag = MSG_NOSIGNAL" HAVE_MSG_NOSIGNAL)
SET(EXTRA_DEFINES "__unused1\n#undef inline\n#define __unused2")
SET(HEADER_INCLUDES)
SET(headers_hack)
set(EXTRA_DEFINES "__unused1\n#undef inline\n#define __unused2")
set(HEADER_INCLUDES)
set(headers_hack)
MACRO(add_header_include check header)
IF(${check})
SET(headers_hack
macro(add_header_include check header)
if(${check})
set(headers_hack
"${headers_hack}\n#include <${header}>")
#SET(HEADER_INCLUDES
# ${HEADER_INCLUDES}
# "${header}")
ENDIF(${check})
ENDMACRO(add_header_include header)
endif(${check})
endmacro(add_header_include header)
IF(HAVE_WINDOWS_H)
SET(EXTRA_DEFINES ${EXTRA_DEFINES}
if(HAVE_WINDOWS_H)
set(EXTRA_DEFINES ${EXTRA_DEFINES}
"__unused7\n#ifndef WIN32_LEAN_AND_MEAN\n#define WIN32_LEAN_AND_MEAN\n#endif\n#define __unused3")
add_header_include(HAVE_WINDOWS_H "windows.h")
add_header_include(HAVE_WINSOCK2_H "winsock2.h")
add_header_include(HAVE_WINSOCK_H "winsock.h")
ELSE(HAVE_WINDOWS_H)
else(HAVE_WINDOWS_H)
add_header_include(HAVE_SYS_TYPES_H "sys/types.h")
add_header_include(HAVE_SYS_TIME_H "sys/time.h")
add_header_include(TIME_WITH_SYS_TIME "time.h")
add_header_include(HAVE_TIME_H "time.h")
ENDIF(HAVE_WINDOWS_H)
SET(EXTRA_DEFINES "${EXTRA_DEFINES}\n${headers_hack}\n#define __unused5")
CURL_CHECK_C_SOURCE_COMPILES("struct timeval ts;\nts.tv_sec = 0;\nts.tv_usec = 0" HAVE_STRUCT_TIMEVAL)
endif(HAVE_WINDOWS_H)
set(EXTRA_DEFINES "${EXTRA_DEFINES}\n${headers_hack}\n#define __unused5")
curl_check_c_source_compiles("struct timeval ts;\nts.tv_sec = 0;\nts.tv_usec = 0" HAVE_STRUCT_TIMEVAL)
SET(HAVE_SIG_ATOMIC_T 1)
SET(EXTRA_DEFINES)
SET(HEADER_INCLUDES)
IF(HAVE_SIGNAL_H)
SET(HEADER_INCLUDES "signal.h")
SET(CMAKE_EXTRA_INCLUDE_FILES "signal.h")
ENDIF(HAVE_SIGNAL_H)
CHECK_TYPE_SIZE("sig_atomic_t" SIZEOF_SIG_ATOMIC_T)
IF(HAVE_SIZEOF_SIG_ATOMIC_T)
CURL_CHECK_C_SOURCE_COMPILES("static volatile sig_atomic_t dummy = 0" HAVE_SIG_ATOMIC_T_NOT_VOLATILE)
IF(NOT HAVE_SIG_ATOMIC_T_NOT_VOLATILE)
SET(HAVE_SIG_ATOMIC_T_VOLATILE 1)
ENDIF(NOT HAVE_SIG_ATOMIC_T_NOT_VOLATILE)
ENDIF(HAVE_SIZEOF_SIG_ATOMIC_T)
include(CurlCheckCSourceRuns)
set(EXTRA_DEFINES)
set(HEADER_INCLUDES)
if(HAVE_SYS_POLL_H)
set(HEADER_INCLUDES "sys/poll.h")
endif(HAVE_SYS_POLL_H)
curl_check_c_source_runs("return poll((void *)0, 0, 10 /*ms*/)" HAVE_POLL_FINE)
SET(CHECK_TYPE_SIZE_PREINCLUDE
set(HAVE_SIG_ATOMIC_T 1)
set(EXTRA_DEFINES)
set(HEADER_INCLUDES)
if(HAVE_SIGNAL_H)
set(HEADER_INCLUDES "signal.h")
set(CMAKE_EXTRA_INCLUDE_FILES "signal.h")
endif(HAVE_SIGNAL_H)
check_type_size("sig_atomic_t" SIZEOF_SIG_ATOMIC_T)
if(HAVE_SIZEOF_SIG_ATOMIC_T)
curl_check_c_source_compiles("static volatile sig_atomic_t dummy = 0" HAVE_SIG_ATOMIC_T_NOT_VOLATILE)
if(NOT HAVE_SIG_ATOMIC_T_NOT_VOLATILE)
set(HAVE_SIG_ATOMIC_T_VOLATILE 1)
endif(NOT HAVE_SIG_ATOMIC_T_NOT_VOLATILE)
endif(HAVE_SIZEOF_SIG_ATOMIC_T)
set(CHECK_TYPE_SIZE_PREINCLUDE
"#undef inline")
IF(HAVE_WINDOWS_H)
SET(CHECK_TYPE_SIZE_PREINCLUDE "${CHECK_TYPE_SIZE_PREINCLUDE}
if(HAVE_WINDOWS_H)
set(CHECK_TYPE_SIZE_PREINCLUDE "${CHECK_TYPE_SIZE_PREINCLUDE}
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>")
IF(HAVE_WINSOCK2_H)
SET(CHECK_TYPE_SIZE_PREINCLUDE "${CHECK_TYPE_SIZE_PREINCLUDE}\n#include <winsock2.h>")
ENDIF(HAVE_WINSOCK2_H)
ELSE(HAVE_WINDOWS_H)
IF(HAVE_SYS_SOCKET_H)
SET(CMAKE_EXTRA_INCLUDE_FILES ${CMAKE_EXTRA_INCLUDE_FILES}
if(HAVE_WINSOCK2_H)
set(CHECK_TYPE_SIZE_PREINCLUDE "${CHECK_TYPE_SIZE_PREINCLUDE}\n#include <winsock2.h>")
endif(HAVE_WINSOCK2_H)
else(HAVE_WINDOWS_H)
if(HAVE_SYS_SOCKET_H)
set(CMAKE_EXTRA_INCLUDE_FILES ${CMAKE_EXTRA_INCLUDE_FILES}
"sys/socket.h")
ENDIF(HAVE_SYS_SOCKET_H)
IF(HAVE_NETINET_IN_H)
SET(CMAKE_EXTRA_INCLUDE_FILES ${CMAKE_EXTRA_INCLUDE_FILES}
endif(HAVE_SYS_SOCKET_H)
if(HAVE_NETINET_IN_H)
set(CMAKE_EXTRA_INCLUDE_FILES ${CMAKE_EXTRA_INCLUDE_FILES}
"netinet/in.h")
ENDIF(HAVE_NETINET_IN_H)
IF(HAVE_ARPA_INET_H)
SET(CMAKE_EXTRA_INCLUDE_FILES ${CMAKE_EXTRA_INCLUDE_FILES}
endif(HAVE_NETINET_IN_H)
if(HAVE_ARPA_INET_H)
set(CMAKE_EXTRA_INCLUDE_FILES ${CMAKE_EXTRA_INCLUDE_FILES}
"arpa/inet.h")
ENDIF(HAVE_ARPA_INET_H)
ENDIF(HAVE_WINDOWS_H)
endif(HAVE_ARPA_INET_H)
endif(HAVE_WINDOWS_H)
CHECK_TYPE_SIZE("struct sockaddr_storage" SIZEOF_STRUCT_SOCKADDR_STORAGE)
IF(HAVE_SIZEOF_STRUCT_SOCKADDR_STORAGE)
SET(HAVE_STRUCT_SOCKADDR_STORAGE 1)
ENDIF(HAVE_SIZEOF_STRUCT_SOCKADDR_STORAGE)
check_type_size("struct sockaddr_storage" SIZEOF_STRUCT_SOCKADDR_STORAGE)
if(HAVE_SIZEOF_STRUCT_SOCKADDR_STORAGE)
set(HAVE_STRUCT_SOCKADDR_STORAGE 1)
endif(HAVE_SIZEOF_STRUCT_SOCKADDR_STORAGE)

View File

@ -0,0 +1,122 @@
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_PROCESS_H 1)
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_X509_H 0)
set(HAVE_ZLIB_H 0)
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_INET_NTOA_R_DECL 0)
set(HAVE_INET_NTOA_R_DECL_REENTRANT 0)
if(ENABLE_IPV6)
set(HAVE_GETADDRINFO 1)
else()
set(HAVE_GETADDRINFO 0)
endif()
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)

View File

@ -0,0 +1,31 @@
# File containing various utilities
# Converts a CMake list to a string containing elements separated by spaces
function(TO_LIST_SPACES _LIST_NAME OUTPUT_VAR)
set(NEW_LIST_SPACE)
foreach(ITEM ${${_LIST_NAME}})
set(NEW_LIST_SPACE "${NEW_LIST_SPACE} ${ITEM}")
endforeach()
string(STRIP ${NEW_LIST_SPACE} NEW_LIST_SPACE)
set(${OUTPUT_VAR} "${NEW_LIST_SPACE}" PARENT_SCOPE)
endfunction()
# Appends a lis of item to a string which is a space-separated list, if they don't already exist.
function(LIST_SPACES_APPEND_ONCE LIST_NAME)
string(REPLACE " " ";" _LIST ${${LIST_NAME}})
list(APPEND _LIST ${ARGN})
list(REMOVE_DUPLICATES _LIST)
to_list_spaces(_LIST NEW_LIST_SPACE)
set(${LIST_NAME} "${NEW_LIST_SPACE}" PARENT_SCOPE)
endfunction()
# Convinience function that does the same as LIST(FIND ...) but with a TRUE/FALSE return value.
# Ex: IN_STR_LIST(MY_LIST "Searched item" WAS_FOUND)
function(IN_STR_LIST LIST_NAME ITEM_SEARCHED RETVAL)
list(FIND ${LIST_NAME} ${ITEM_SEARCHED} FIND_POS)
if(${FIND_POS} EQUAL -1)
set(${RETVAL} FALSE PARENT_SCOPE)
else()
set(${RETVAL} TRUE PARENT_SCOPE)
endif()
endfunction()

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
COPYRIGHT AND PERMISSION NOTICE
Copyright (c) 1996 - 2009, Daniel Stenberg, <daniel@haxx.se>.
Copyright (c) 1996 - 2014, Daniel Stenberg, <daniel@haxx.se>.
All rights reserved.

View File

@ -1,120 +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_PROCESS_H 1)
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_X509_H 0)
SET(HAVE_ZLIB_H 0)
SET(HAVE_SIZEOF_LONG_DOUBLE 1)
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_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_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)

View File

@ -1,483 +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 `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 */

View File

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

View File

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

View File

@ -1,84 +0,0 @@
/*****************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* $Id$
*/
#include "curl/curl.h"
#include "curl/types.h"
#include "curl/easy.h"
#include "setup.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;
}

View File

@ -1,64 +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;
(void)argc; (void)argv;
/* 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;
}

View File

@ -1,93 +0,0 @@
/*****************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* $Id$
*/
#include "curl/curl.h"
#include "setup.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;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,80 +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);
fclose(headerfile);
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);
fclose(bodyfile);
/* cleanup curl stuff */
curl_easy_cleanup(curl_handle);
return 0;
}

View File

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

View File

@ -1,120 +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();
if (headerfile)
fclose(headerfile);
return 0;
}

View File

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

View File

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

View File

@ -1,366 +0,0 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute 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 "urldata.h" /* for the SessionHandle definition */
#include "easyif.h" /* for Curl_convert_... prototypes */
#include "base64.h"
#include "memory.h"
/* include memdebug.h last */
#include "memdebug.h"
/* ---- Base64 Encoding/Decoding Table --- */
static const char table64[]=
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static void decodeQuantum(unsigned char *dest, const char *src)
{
unsigned int x = 0;
int i;
char *found;
for(i = 0; i < 4; i++) {
if((found = strchr(table64, src[i])))
x = (x << 6) + (unsigned int)(found - table64);
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 and return an allocated memory in
* the *outptr. Returns the length of the decoded data.
*/
size_t Curl_base64_decode(const char *src, unsigned char **outptr)
{
int length = 0;
int equalsTerm = 0;
int i;
int numQuantums;
unsigned char lastQuantum[3];
size_t rawlen=0;
unsigned char *newstr;
*outptr = NULL;
while((src[length] != '=') && src[length])
length++;
/* A maximum of two = padding characters is allowed */
if(src[length] == '=') {
equalsTerm++;
if(src[length+equalsTerm] == '=')
equalsTerm++;
}
numQuantums = (length + equalsTerm) / 4;
/* Don't allocate a buffer if the decoded length is 0 */
if (numQuantums <= 0)
return 0;
rawlen = (numQuantums * 3) - equalsTerm;
/* The buffer must be large enough to make room for the last quantum
(which may be partially thrown out) and the zero terminator. */
newstr = malloc(rawlen+4);
if(!newstr)
return 0;
*outptr = newstr;
/* Decode all but the last quantum (which may not decode to a
multiple of 3 bytes) */
for(i = 0; i < numQuantums - 1; i++) {
decodeQuantum((unsigned char *)newstr, src);
newstr += 3; src += 4;
}
/* This final decode may actually read slightly past the end of the buffer
if the input string is missing pad bytes. This will almost always be
harmless. */
decodeQuantum(lastQuantum, src);
for(i = 0; i < 3 - equalsTerm; i++)
newstr[i] = lastQuantum[i];
newstr[i] = 0; /* zero terminate */
return rawlen;
}
/*
* 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(struct SessionHandle *data,
const char *inp, size_t insize, char **outptr)
{
unsigned char ibuf[3];
unsigned char obuf[4];
int i;
int inputparts;
char *output;
char *base64data;
#ifdef CURL_DOES_CONVERSIONS
char *convbuf;
#endif
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;
#ifdef CURL_DOES_CONVERSIONS
/*
* The base64 data needs to be created using the network encoding
* not the host encoding. And we can't change the actual input
* so we copy it to a buffer, translate it, and use that instead.
*/
if(data) {
convbuf = (char*)malloc(insize);
if(!convbuf) {
return 0;
}
memcpy(convbuf, indata, insize);
if(CURLE_OK != Curl_convert_to_network(data, convbuf, insize)) {
free(convbuf);
return 0;
}
indata = convbuf; /* switch to the converted buffer */
}
#else
(void)data;
#endif
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] = (unsigned char) ((ibuf[0] & 0xFC) >> 2);
obuf[1] = (unsigned char) (((ibuf[0] & 0x03) << 4) | \
((ibuf[1] & 0xF0) >> 4));
obuf[2] = (unsigned char) (((ibuf[1] & 0x0F) << 2) | \
((ibuf[2] & 0xC0) >> 6));
obuf[3] = (unsigned char) (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 */
#ifdef CURL_DOES_CONVERSIONS
if(data)
free(convbuf);
#endif
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;
struct SessionHandle *handle = NULL;
#ifdef CURL_DOES_CONVERSIONS
/* get a Curl handle so Curl_base64_encode can translate properly */
handle = curl_easy_init();
if(handle == NULL) {
fprintf(stderr, "Error: curl_easy_init failed\n");
return 0;
}
#endif
data = (unsigned char *)suck(&dataLen);
base64Len = Curl_base64_encode(handle, data, dataLen, &base64);
fprintf(stderr, "%d\n", base64Len);
fprintf(stdout, "%s\n", base64);
free(base64); free(data);
#ifdef CURL_DOES_CONVERSIONS
curl_easy_cleanup(handle);
#endif
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;
#ifdef CURL_DOES_CONVERSIONS
/* get a Curl handle so main can translate properly */
struct SessionHandle *handle = curl_easy_init();
if(handle == NULL) {
fprintf(stderr, "Error: curl_easy_init failed\n");
return 0;
}
#endif
base64 = (char *)suck(&base64Len);
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) {
#ifdef CURL_DOES_CONVERSIONS
if(CURLE_OK !=
Curl_convert_from_network(handle, &data[i+j], (size_t)1))
data[i+j] = '.';
#endif /* CURL_DOES_CONVERSIONS */
printf("%c", ISGRAPH(data[i+j])?data[i+j]:'.');
} else
break;
puts("");
}
#ifdef CURL_DOES_CONVERSIONS
curl_easy_cleanup(handle);
#endif
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

View File

@ -1 +0,0 @@
/* ca bundle path set in here*/

View File

@ -1,720 +0,0 @@
/* lib/config.h.in. Generated from configure.ac by autoheader. */
/* when building libcurl itself */
#cmakedefine BUILDING_LIBCURL ${BUILDING_LIBCURL}
/* to disable cookies support */
#cmakedefine CURL_DISABLE_COOKIES ${CURL_DISABLE_COOKIES}
/* to disable cryptographic authentication */
#cmakedefine CURL_DISABLE_CRYPTO_AUTH ${CURL_DISABLE_CRYPTO_AUTH}
/* 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 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}
/* to disable TFTP */
#cmakedefine CURL_DISABLE_TFTP ${CURL_DISABLE_TFTP}
/* to disable verbose strings */
#cmakedefine CURL_DISABLE_VERBOSE_STRINGS ${CURL_DISABLE_VERBOSE_STRINGS}
/* to make a symbol visible */
#cmakedefine CURL_EXTERN_SYMBOL ${CURL_EXTERN_SYMBOL}
/* to enable hidden symbols */
#cmakedefine CURL_HIDDEN_SYMBOLS ${CURL_HIDDEN_SYMBOLS}
/* when not building a shared library */
#cmakedefine CURL_STATICLIB ${CURL_STATICLIB}
/* Set to explicitly specify we don't want to use thread-safe functions */
#cmakedefine DISABLED_THREADSAFE ${DISABLED_THREADSAFE}
/* lber dynamic library file */
#cmakedefine DL_LBER_FILE ${DL_LBER_FILE}
/* ldap dynamic library file */
#cmakedefine DL_LDAP_FILE ${DL_LDAP_FILE}
/* 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 the type qualifier of arg 1 for getnameinfo. */
#cmakedefine GETNAMEINFO_QUAL_ARG1 ${GETNAMEINFO_QUAL_ARG1}
/* Define to the type of arg 1 for getnameinfo. */
#cmakedefine GETNAMEINFO_TYPE_ARG1 ${GETNAMEINFO_TYPE_ARG1}
/* Define to the type of arg 2 for getnameinfo. */
#cmakedefine GETNAMEINFO_TYPE_ARG2 ${GETNAMEINFO_TYPE_ARG2}
/* Define to the type of args 4 and 6 for getnameinfo. */
#cmakedefine GETNAMEINFO_TYPE_ARG46 ${GETNAMEINFO_TYPE_ARG46}
/* Define to the type of arg 7 for getnameinfo. */
#cmakedefine GETNAMEINFO_TYPE_ARG7 ${GETNAMEINFO_TYPE_ARG7}
/* 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 <arpa/tftp.h> header file. */
#cmakedefine HAVE_ARPA_TFTP_H ${HAVE_ARPA_TFTP_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 `basename' function. */
#cmakedefine HAVE_BASENAME ${HAVE_BASENAME}
/* 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 `ENGINE_load_builtin_engines' function. */
#cmakedefine HAVE_ENGINE_LOAD_BUILTIN_ENGINES ${HAVE_ENGINE_LOAD_BUILTIN_ENGINES}
/* Define to 1 if you have the <errno.h> header file. */
#cmakedefine HAVE_ERRNO_H ${HAVE_ERRNO_H}
/* Define to 1 if you have the <err.h> header file. */
#cmakedefine HAVE_ERR_H ${HAVE_ERR_H}
/* Define to 1 if you have the <fcntl.h> header file. */
#cmakedefine HAVE_FCNTL_H ${HAVE_FCNTL_H}
/* use FIONBIO for non-blocking sockets */
#cmakedefine HAVE_FIONBIO ${HAVE_FIONBIO}
/* Define to 1 if you have the `fork' function. */
#cmakedefine HAVE_FORK ${HAVE_FORK}
/* Define to 1 if you have the `ftruncate' function. */
#cmakedefine HAVE_FTRUNCATE ${HAVE_FTRUNCATE}
/* 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 getnameinfo function. */
#cmakedefine HAVE_GETNAMEINFO ${HAVE_GETNAMEINFO}
/* Define to 1 if you have the `getpass_r' function. */
#cmakedefine HAVE_GETPASS_R ${HAVE_GETPASS_R}
/* Define to 1 if you have the `getprotobyname' function. */
#cmakedefine HAVE_GETPROTOBYNAME ${HAVE_GETPROTOBYNAME}
/* Define to 1 if you have the `getpwuid' function. */
#cmakedefine HAVE_GETPWUID ${HAVE_GETPWUID}
/* Define to 1 if you have the `getrlimit' function. */
#cmakedefine HAVE_GETRLIMIT ${HAVE_GETRLIMIT}
/* Define to 1 if you have the `gettimeofday' function. */
#cmakedefine HAVE_GETTIMEOFDAY ${HAVE_GETTIMEOFDAY}
/* Define to 1 if you have the `gmtime_r' function. */
#cmakedefine HAVE_GMTIME_R ${HAVE_GMTIME_R}
/* if you have the gssapi libraries */
#cmakedefine HAVE_GSSAPI ${HAVE_GSSAPI}
/* if you have the GNU gssapi libraries */
#cmakedefine HAVE_GSSGNU ${HAVE_GSSGNU}
/* 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 `idna_strerror' function. */
#cmakedefine HAVE_IDNA_STRERROR ${HAVE_IDNA_STRERROR}
/* 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 `dl' library (-ldl). */
#cmakedefine HAVE_LIBDL ${HAVE_LIBDL}
/* Define to 1 if you have the <libgen.h> header file. */
#cmakedefine HAVE_LIBGEN_H ${HAVE_LIBGEN_H}
/* 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 `ssh2' library (-lssh2). */
#cmakedefine HAVE_LIBSSH2 ${HAVE_LIBSSH2}
/* Define to 1 if you have the <libssh2.h> header file. */
#cmakedefine HAVE_LIBSSH2_H ${HAVE_LIBSSH2_H}
/* 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}
/* if your compiler supports LL */
#cmakedefine HAVE_LL ${HAVE_LL}
/* Define to 1 if you have the <locale.h> header file. */
#cmakedefine HAVE_LOCALE_H ${HAVE_LOCALE_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 MSG_NOSIGNAL flag. */
#cmakedefine HAVE_MSG_NOSIGNAL ${HAVE_MSG_NOSIGNAL}
/* 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 to 1 if NI_WITHSCOPEID exists and works. */
#cmakedefine HAVE_NI_WITHSCOPEID ${HAVE_NI_WITHSCOPEID}
/* Defined if no inet_pton() prototype available */
#cmakedefine HAVE_NO_INET_PTON_PROTO ${HAVE_NO_INET_PTON_PROTO}
/* 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/pkcs12.h> header file. */
#cmakedefine HAVE_OPENSSL_PKCS12_H ${HAVE_OPENSSL_PKCS12_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 `pipe' function. */
#cmakedefine HAVE_PIPE ${HAVE_PIPE}
/* Define to 1 if you have the `poll' function. */
#cmakedefine HAVE_POLL ${HAVE_POLL}
/* Define to 1 if you have the <process.h> header file. */
#cmakedefine HAVE_PROCESS_H ${HAVE_PROCESS_H}
/* 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 recv function. */
#cmakedefine HAVE_RECV ${HAVE_RECV}
/* 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 send function. */
#cmakedefine HAVE_SEND ${HAVE_SEND}
/* 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 `setlocale' function. */
#cmakedefine HAVE_SETLOCALE ${HAVE_SETLOCALE}
/* Define to 1 if you have the `setrlimit' function. */
#cmakedefine HAVE_SETRLIMIT ${HAVE_SETRLIMIT}
/* 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}
/* Define to 1 if you have the <signal.h> header file. */
#cmakedefine HAVE_SIGNAL_H ${HAVE_SIGNAL_H}
/* If you have sigsetjmp */
#cmakedefine HAVE_SIGSETJMP ${HAVE_SIGSETJMP}
/* Define to 1 if sig_atomic_t is an available typedef. */
#cmakedefine HAVE_SIG_ATOMIC_T ${HAVE_SIG_ATOMIC_T}
/* Define to 1 if sig_atomic_t is already defined as volatile. */
#cmakedefine HAVE_SIG_ATOMIC_T_VOLATILE ${HAVE_SIG_ATOMIC_T_VOLATILE}
/* 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 <stdio.h> header file. */
#cmakedefine HAVE_STDIO_H ${HAVE_STDIO_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 `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 `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}
/* if struct sockaddr_storage is defined */
#cmakedefine HAVE_STRUCT_SOCKADDR_STORAGE ${HAVE_STRUCT_SOCKADDR_STORAGE}
/* Define to 1 if you have the timeval struct. */
#cmakedefine HAVE_STRUCT_TIMEVAL ${HAVE_STRUCT_TIMEVAL}
/* Define to 1 if you have the <sys/filio.h> header file. */
#cmakedefine HAVE_SYS_FILIO_H ${HAVE_SYS_FILIO_H}
/* 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/resource.h> header file. */
#cmakedefine HAVE_SYS_RESOURCE_H ${HAVE_SYS_RESOURCE_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 <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 <tld.h> header file. */
#cmakedefine HAVE_TLD_H ${HAVE_TLD_H}
/* Define to 1 if you have the `tld_strerror' function. */
#cmakedefine HAVE_TLD_STRERROR ${HAVE_TLD_STRERROR}
/* 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 windows.h header file. */
#cmakedefine HAVE_WINDOWS_H ${HAVE_WINDOWS_H}
/* Define to 1 if you have the winsock2.h header file. */
#cmakedefine HAVE_WINSOCK2_H ${HAVE_WINSOCK2_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 ws2tcpip.h header file. */
#cmakedefine HAVE_WS2TCPIP_H ${HAVE_WS2TCPIP_H}
/* Define to 1 if you have the <x509.h> header file. */
#cmakedefine HAVE_X509_H ${HAVE_X509_H}
/* if you have the zlib.h header file */
#cmakedefine HAVE_ZLIB_H ${HAVE_ZLIB_H}
/* If you lack a fine basename() prototype */
#cmakedefine NEED_BASENAME_PROTO ${NEED_BASENAME_PROTO}
/* Define to 1 if you need the malloc.h header file even with stdlib.h */
#cmakedefine NEED_MALLOC_H ${NEED_MALLOC_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 to the type of arg 1 for recv. */
#cmakedefine RECV_TYPE_ARG1 ${RECV_TYPE_ARG1}
/* Define to the type of arg 2 for recv. */
#cmakedefine RECV_TYPE_ARG2 ${RECV_TYPE_ARG2}
/* Define to the type of arg 3 for recv. */
#cmakedefine RECV_TYPE_ARG3 ${RECV_TYPE_ARG3}
/* Define to the type of arg 4 for recv. */
#cmakedefine RECV_TYPE_ARG4 ${RECV_TYPE_ARG4}
/* Define to the function return type for recv. */
#cmakedefine RECV_TYPE_RETV ${RECV_TYPE_RETV}
/* 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}
/* Define to the type qualifier of arg 2 for send. */
#cmakedefine SEND_QUAL_ARG2 ${SEND_QUAL_ARG2}
/* Define to the type of arg 1 for send. */
#cmakedefine SEND_TYPE_ARG1 ${SEND_TYPE_ARG1}
/* Define to the type of arg 2 for send. */
#cmakedefine SEND_TYPE_ARG2 ${SEND_TYPE_ARG2}
/* Define to the type of arg 3 for send. */
#cmakedefine SEND_TYPE_ARG3 ${SEND_TYPE_ARG3}
/* Define to the type of arg 4 for send. */
#cmakedefine SEND_TYPE_ARG4 ${SEND_TYPE_ARG4}
/* Define to the function return type for send. */
#cmakedefine SEND_TYPE_RETV ${SEND_TYPE_RETV}
/* The size of `curl_off_t', as computed by sizeof. */
@SIZEOF_CURL_OFF_T_CODE@
/* The size of `long', as computed by sizeof. */
@SIZEOF_LONG_CODE@
/* The size of `long long', as computed by sizeof. */
@SIZEOF_LONG_LONG_CODE@
/* The size of `__int64', as computed by sizeof. */
@SIZEOF___INT64_CODE@
/* The size of `size_t', as computed by sizeof. */
@SIZEOF_SIZE_T_CODE@
/* The size of `ssize_t', as computed by sizeof. */
@SIZEOF_SSIZE_T_CODE@
/* The size of `time_t', as computed by sizeof. */
@SIZEOF_TIME_T_CODE@
/* 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 GnuTLS is enabled */
#cmakedefine USE_GNUTLS ${USE_GNUTLS}
/* if libSSH2 is in use */
#cmakedefine USE_LIBSSH2 ${USE_LIBSSH2}
/* If you want to build curl with the built-in manual */
#cmakedefine USE_MANUAL ${USE_MANUAL}
/* if OpenSSL is in use */
#cmakedefine USE_OPENSSL ${USE_OPENSSL}
/* if SSL is enabled */
#cmakedefine USE_SSLEAY ${USE_SSLEAY}
/* to enable SSPI support */
#cmakedefine USE_WINDOWS_SSPI ${USE_WINDOWS_SSPI}
/* Version number of package */
#cmakedefine VERSION "${VERSION}"
/* Define to avoid automatic inclusion of winsock.h */
#cmakedefine WIN32_LEAN_AND_MEAN ${WIN32_LEAN_AND_MEAN}
/* 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 this if you need it to compile thread-safe code */
#cmakedefine _THREAD_SAFE ${_THREAD_SAFE}
/* 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 int' 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 */
#ifndef SIZEOF_SSIZE_T
# if SIZEOF_LONG == SIZEOF_SIZE_T
typedef long ssize_t;
# elif SIZEOF_LONG_LONG == SIZEOF_SIZE_T
typedef long long ssize_t;
# elif SIZEOF___INT64 == SIZEOF_SIZE_T
typedef __int64 ssize_t;
# else
typedef int ssize_t;
# endif
#endif
/* Special handling of zlib library */
#cmakedefine CURL_SPECIAL_ZLIB_H "${CURL_SPECIAL_ZLIB_H}"

View File

@ -1,905 +0,0 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute 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 */
#ifdef HAVE_SYS_TIME_H
#include <sys/time.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> /* <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 USE_WINSOCK
#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 "memory.h"
#include "select.h"
#include "url.h" /* for Curl_safefree() */
#include "multiif.h"
#include "sockaddr.h" /* required for Curl_sockaddr_storage */
#include "inet_ntop.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,
const Curl_addrinfo *ai, /* start connecting to this */
long timeout_ms,
bool *connected);
/*
* Curl_sockerrno() returns the *socket-related* errno (or equivalent) on this
* platform to hide platform specific for the function that calls this.
*/
int Curl_sockerrno(void)
{
#ifdef USE_WINSOCK
return (int)WSAGetLastError();
#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
#define SETBLOCK 0
#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));
#undef SETBLOCK
#define SETBLOCK 1
#endif
#if defined(HAVE_FIONBIO) && (SETBLOCK == 0)
/* older unix versions */
int flags;
flags = nonblock;
return ioctl(sockfd, FIONBIO, &flags);
#undef SETBLOCK
#define SETBLOCK 2
#endif
#if defined(HAVE_IOCTLSOCKET) && (SETBLOCK == 0)
/* Windows? */
unsigned long flags;
flags = nonblock;
return ioctlsocket(sockfd, FIONBIO, &flags);
#undef SETBLOCK
#define SETBLOCK 3
#endif
#if defined(HAVE_IOCTLSOCKET_CASE) && (SETBLOCK == 0)
/* presumably for Amiga */
return IoctlSocket(sockfd, FIONBIO, (long)nonblock);
#undef SETBLOCK
#define SETBLOCK 4
#endif
#if defined(HAVE_SO_NONBLOCK) && (SETBLOCK == 0)
/* BeOS */
long b = nonblock ? 1 : 0;
return setsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
#undef SETBLOCK
#define SETBLOCK 5
#endif
#ifdef HAVE_DISABLED_NONBLOCKING
return 0; /* returns success */
#undef SETBLOCK
#define SETBLOCK 6
#endif
#if (SETBLOCK == 0)
#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)
{
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. */
(void)verifyconnect(sockfd, NULL);
#endif
/* now select() until we get connect or timeout */
rc = Curl_select(CURL_SOCKET_BAD, sockfd, (int)timeout_msec);
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(rc & CSELECT_ERR)
/* error condition caught */
return WAITCONN_FDSET_ERROR;
/* we have a connect! */
return WAITCONN_CONNECTED;
}
static CURLcode bindlocal(struct connectdata *conn,
curl_socket_t sockfd)
{
struct SessionHandle *data = conn->data;
struct sockaddr_in me;
struct sockaddr *sock = NULL; /* bind to this address */
socklen_t socksize; /* size of the data sock points to */
unsigned short port = data->set.localport; /* use this port number, 0 for
"random" */
/* how many port numbers to try to bind to, increasing one at a time */
int portnum = data->set.localportrange;
/*************************************************************
* Select device to bind socket to
*************************************************************/
if (data->set.device && (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;
Curl_resolv_unlock(data, h);
}
}
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) {
if(in == CURL_INADDR_NONE)
/* convert the resolved address, sizeof myhost >= INET_ADDRSTRLEN */
Curl_inet_ntop(h->addr->ai_addr->sa_family,
&((struct sockaddr_in*)h->addr->ai_addr)->sin_addr,
myhost, sizeof myhost);
else
/* we know data->set.device is shorter than the myhost array */
strcpy(myhost, data->set.device);
Curl_resolv_unlock(data, h);
}
}
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, "Bind local address 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_sockerrno())); */
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) {
failf(data,"couldn't find my own IP address (%s)", myhost);
return CURLE_HTTP_PORT_FAILED;
} /* end of inet_addr */
if ( h ) {
Curl_addrinfo *addr = h->addr;
sock = addr->ai_addr;
socksize = addr->ai_addrlen;
}
else
return CURLE_HTTP_PORT_FAILED;
}
else if(port) {
/* if a local port number is requested but no local IP, extract the
address from the socket */
memset(&me, 0, sizeof(struct sockaddr));
me.sin_family = AF_INET;
me.sin_addr.s_addr = INADDR_ANY;
sock = (struct sockaddr *)&me;
socksize = sizeof(struct sockaddr);
}
else
/* no local kind of binding was requested */
return CURLE_OK;
do {
/* Set port number to bind to, 0 makes the system pick one */
if(sock->sa_family == AF_INET)
((struct sockaddr_in *)sock)->sin_port = htons(port);
#ifdef ENABLE_IPV6
else
((struct sockaddr_in6 *)sock)->sin6_port = htons(port);
#endif
if( bind(sockfd, sock, socksize) >= 0) {
/* we succeeded to bind */
struct Curl_sockaddr_storage add;
socklen_t size;
size = sizeof(add);
if(getsockname(sockfd, (struct sockaddr *) &add, &size) < 0) {
failf(data, "getsockname() failed");
return CURLE_HTTP_PORT_FAILED;
}
/* We re-use/clobber the port variable here below */
if(((struct sockaddr *)&add)->sa_family == AF_INET)
port = ntohs(((struct sockaddr_in *)&add)->sin_port);
#ifdef ENABLE_IPV6
else
port = ntohs(((struct sockaddr_in6 *)&add)->sin6_port);
#endif
infof(data, "Local port: %d\n", port);
return CURLE_OK;
}
if(--portnum > 0) {
infof(data, "Bind to local port %d failed, trying next\n", port);
port++; /* try next port */
}
else
break;
} while(1);
data->state.os_errno = Curl_sockerrno();
failf(data, "bind failure: %s",
Curl_strerror(conn, data->state.os_errno));
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 = TRUE;
#ifdef SO_ERROR
int err = 0;
socklen_t errSize = sizeof(err);
#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."
*/
#ifdef _WIN32_WCE
Sleep(0);
#else
SleepEx(0, FALSE);
#endif
#endif
if( -1 == getsockopt(sockfd, SOL_SOCKET, SO_ERROR,
(void *)&err, &errSize))
err = Curl_sockerrno();
#ifdef _WIN32_WCE
/* Always returns this error, bug in CE? */
if(WSAENOPROTOOPT==err)
err=0;
#endif
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_sockerrno();
#endif
return rc;
}
CURLcode Curl_store_ip_addr(struct connectdata *conn)
{
char addrbuf[256];
Curl_printable_address(conn->ip_addr, addrbuf, sizeof(addrbuf));
/* save the string */
Curl_safefree(conn->ip_addr_str);
conn->ip_addr_str = strdup(addrbuf);
if(!conn->ip_addr_str)
return CURLE_OUT_OF_MEMORY; /* FAIL */
#ifdef PF_INET6
if(conn->ip_addr->ai_family == PF_INET6)
conn->bits.ipv6 = TRUE;
#endif
return CURLE_OK;
}
/* 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;
/* first close the failed socket */
sclose(conn->sock[sockindex]);
conn->sock[sockindex] = CURL_SOCKET_BAD;
*connected = FALSE;
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;
Curl_store_ip_addr(conn);
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 allow_total = 0;
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.t_startsingle);
/* subtract the most strict timeout of the ones */
if(data->set.timeout && data->set.connecttimeout) {
if (data->set.timeout < data->set.connecttimeout)
allow_total = allow = data->set.timeout*1000;
else
allow = data->set.connecttimeout*1000;
}
else if(data->set.timeout) {
allow_total = 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! */
Curl_expire(data, allow_total);
*connected = TRUE;
return CURLE_OK;
}
Curl_expire(data, allow);
/* check for connect without timeout as we want to return immediately */
rc = waitconnect(sockfd, 0);
if(WAITCONN_CONNECTED == rc) {
int error;
if (verifyconnect(sockfd, &error)) {
/* we are connected, awesome! */
*connected = TRUE;
return CURLE_OK;
}
/* nope, not connected for real */
data->state.os_errno = error;
infof(data, "Connection failed\n");
if(trynextip(conn, sockindex, connected)) {
code = CURLE_COULDNT_CONNECT;
}
}
else if(WAITCONN_TIMEOUT != rc) {
int error = 0;
/* nope, not connected */
if (WAITCONN_FDSET_ERROR == rc) {
(void)verifyconnect(sockfd, &error);
data->state.os_errno = error;
infof(data, "%s\n",Curl_strerror(conn,error));
}
else
infof(data, "Connection failed\n");
if(trynextip(conn, sockindex, connected)) {
error = Curl_sockerrno();
data->state.os_errno = error;
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;
int proto = IPPROTO_TCP;
#ifdef HAVE_GETPROTOBYNAME
struct protoent *pe = getprotobyname("tcp");
if (pe)
proto = pe->p_proto;
#endif
if(setsockopt(sockfd, proto, TCP_NODELAY, (void *)&onoff,
sizeof(onoff)) < 0)
infof(data, "Could not set TCP_NODELAY: %s\n",
Curl_strerror(conn, Curl_sockerrno()));
else
infof(data,"TCP_NODELAY set\n");
#else
(void)conn;
(void)sockfd;
#endif
}
#ifdef SO_NOSIGPIPE
/* The preferred method on Mac OS X (10.2 and later) to prevent SIGPIPEs when
sending data to a dead peer (instead of relying on the 4th argument to send
being MSG_NOSIGNAL). Possibly also existing and in use on other BSD
systems? */
static void nosigpipe(struct connectdata *conn,
curl_socket_t sockfd)
{
struct SessionHandle *data= conn->data;
int onoff = 1;
if(setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&onoff,
sizeof(onoff)) < 0)
infof(data, "Could not set SO_NOSIGPIPE: %s\n",
Curl_strerror(conn, Curl_sockerrno()));
}
#else
#define nosigpipe(x,y)
#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,
const Curl_addrinfo *ai,
long timeout_ms,
bool *connected)
{
char addr_buf[128];
int rc;
int error;
bool isconnected;
struct SessionHandle *data = conn->data;
curl_socket_t sockfd;
CURLcode res;
sockfd = socket(ai->ai_family, conn->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);
nosigpipe(conn, sockfd);
if(data->set.fsockopt) {
/* activate callback for setting socket options */
error = data->set.fsockopt(data->set.sockopt_client,
sockfd,
CURLSOCKTYPE_IPCXN);
if (error) {
sclose(sockfd); /* close the socket and bail out */
return CURL_SOCKET_BAD;
}
}
/* possibly bind the local end to an IP, interface or port */
res = bindlocal(conn, sockfd);
if(res) {
sclose(sockfd); /* close socket and bail out */
return CURL_SOCKET_BAD;
}
/* set socket non-blocking */
Curl_nonblock(sockfd, TRUE);
/* Connect TCP sockets, bind UDP */
if(conn->socktype == SOCK_STREAM)
rc = connect(sockfd, ai->ai_addr, ai->ai_addrlen);
else
rc = 0;
if(-1 == rc) {
error = Curl_sockerrno();
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));
data->state.os_errno = 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;
}
isconnected = verifyconnect(sockfd, &error);
if(!rc && isconnected) {
/* 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 {
data->state.os_errno = error;
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 */
const 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.t_startsingle);
#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;
}
}
Curl_expire(data, timeout_ms);
/* 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 = 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;
failf(data, "couldn't connect to host");
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 */
data->info.numconnects++; /* to track the number of connections made */
return CURLE_OK;
}

View File

@ -1 +0,0 @@
/* not used */

View File

@ -1,895 +0,0 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute 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
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#include <errno.h>
#include "strequal.h"
#ifdef WIN32
#include <time.h>
#include <io.h>
#else
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#include <netinet/in.h>
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#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 /* WIN32 ... */
#include "urldata.h"
#include <curl/curl.h>
#include "transfer.h"
#include "sslgen.h"
#include "url.h"
#include "getinfo.h"
#include "hostip.h"
#include "share.h"
#include "strdup.h"
#include "memory.h"
#include "progress.h"
#include "easyif.h"
#include "sendf.h" /* for failf function prototype */
#include <ca-bundle.h>
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
#include <iconv.h>
/* set default codesets for iconv */
#ifndef CURL_ICONV_CODESET_OF_NETWORK
#define CURL_ICONV_CODESET_OF_NETWORK "ISO8859-1"
#endif
#ifndef CURL_ICONV_CODESET_FOR_UTF8
#define CURL_ICONV_CODESET_FOR_UTF8 "UTF-8"
#endif
#define ICONV_ERROR (size_t)-1
#endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */
/* The last #include file should be: */
#include "memdebug.h"
#ifdef USE_WINSOCK
/* 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;
#if defined(ENABLE_IPV6) && (USE_WINSOCK < 2)
Error IPV6_requires_winsock2
#endif
wVersionRequested = MAKEWORD(USE_WINSOCK, USE_WINSOCK);
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;
static long init_flags;
/*
* strdup (and other memory functions) is redefined in complicated
* ways, but at this point it must be defined as the system-supplied strdup
* so the callback pointer is initialized correctly.
*/
#if defined(_WIN32_WCE)
#define system_strdup _strdup
#elif !defined(HAVE_STRDUP)
#define system_strdup curlx_strdup
#else
#define system_strdup strdup
#endif
/*
* 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)system_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)system_strdup;
Curl_ccalloc = (curl_calloc_callback)calloc;
if (flags & CURL_GLOBAL_SSL)
if (!Curl_ssl_init())
return CURLE_FAILED_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
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 = CURLE_OK;
/* 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;
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
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.
*/
CURLcode curl_easy_setopt(CURL *curl, CURLoption tag, ...)
{
va_list arg;
struct SessionHandle *data = curl;
CURLcode ret;
if(!curl)
return CURLE_BAD_FUNCTION_ARGUMENT;
va_start(arg, tag);
ret = Curl_setopt(data, tag, arg);
va_end(arg);
return ret;
}
#ifdef CURL_MULTIEASY
/***************************************************************************
* This function is still only for testing purposes. It makes a great way
* to run the full test suite on the multi interface instead of the easy one.
***************************************************************************
*
* The *new* curl_easy_perform() is the external interface that performs a
* transfer previously setup.
*
* Wrapper-function that: creates a multi handle, adds the easy handle to it,
* runs curl_multi_perform() until the transfer is done, then detaches the
* easy handle, destroys the multi handle and returns the easy handle's return
* code. This will make everything internally use and assume multi interface.
*/
CURLcode curl_easy_perform(CURL *easy)
{
CURLM *multi;
CURLMcode mcode;
CURLcode code = CURLE_OK;
int still_running;
struct timeval timeout;
int rc;
CURLMsg *msg;
fd_set fdread;
fd_set fdwrite;
fd_set fdexcep;
int maxfd;
if(!easy)
return CURLE_BAD_FUNCTION_ARGUMENT;
multi = curl_multi_init();
if(!multi)
return CURLE_OUT_OF_MEMORY;
mcode = curl_multi_add_handle(multi, easy);
if(mcode) {
curl_multi_cleanup(multi);
return CURLE_FAILED_INIT;
}
/* we start some action by calling perform right away */
do {
while(CURLM_CALL_MULTI_PERFORM ==
curl_multi_perform(multi, &still_running));
if(!still_running)
break;
FD_ZERO(&fdread);
FD_ZERO(&fdwrite);
FD_ZERO(&fdexcep);
/* timeout once per second */
timeout.tv_sec = 1;
timeout.tv_usec = 0;
/* get file descriptors from the transfers */
curl_multi_fdset(multi, &fdread, &fdwrite, &fdexcep, &maxfd);
rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
if(rc == -1)
/* select error */
break;
/* timeout or data to send/receive => loop! */
} while(still_running);
msg = curl_multi_info_read(multi, &rc);
if(msg)
code = msg->data.result;
mcode = curl_multi_remove_handle(multi, easy);
/* what to do if it fails? */
mcode = curl_multi_cleanup(multi);
/* what to do if it fails? */
return code;
}
#else
/*
* 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->dns.hostcachetype != HCACHE_GLOBAL)) {
if (data->dns.hostcachetype == HCACHE_PRIVATE)
Curl_hash_destroy(data->dns.hostcache);
data->dns.hostcache = Curl_global_host_cache_get();
data->dns.hostcachetype = HCACHE_GLOBAL;
}
if (!data->dns.hostcache) {
data->dns.hostcachetype = HCACHE_PRIVATE;
data->dns.hostcache = Curl_mk_dnscache();
if(!data->dns.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;
}
}
if(!data->state.connc) {
/* oops, no connection cache, make one up */
data->state.connc = Curl_mk_connc(CONNCACHE_PRIVATE, -1);
if(!data->state.connc)
return CURLE_OUT_OF_MEMORY;
}
return Curl_perform(data);
}
#endif
/*
* 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;
Curl_close(data);
}
/*
* Store a pointed to the multi handle within the easy handle's data struct.
*/
void Curl_easy_addmulti(struct SessionHandle *data,
void *multi)
{
data->multi = multi;
}
void Curl_easy_initHandleData(struct SessionHandle *data)
{
memset(&data->reqdata, 0, sizeof(struct HandleData));
data->reqdata.maxdownload = -1;
}
/*
* 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;
if(data->state.used_interface == Curl_if_multi)
outcurl->state.connc = data->state.connc;
else
outcurl->state.connc = Curl_mk_connc(CONNCACHE_PRIVATE, -1);
if(!outcurl->state.connc)
break;
outcurl->state.lastconnect = -1;
outcurl->progress.flags = data->progress.flags;
outcurl->progress.callback = data->progress.callback;
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
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.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
#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
outcurl->inbound_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
CURL_ICONV_CODESET_OF_NETWORK);
outcurl->outbound_cd = iconv_open(CURL_ICONV_CODESET_OF_NETWORK,
CURL_ICONV_CODESET_OF_HOST);
outcurl->utf8_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
CURL_ICONV_CODESET_FOR_UTF8);
#endif
Curl_easy_initHandleData(outcurl);
outcurl->magic = CURLEASY_MAGIC_NUMBER;
fail = FALSE; /* we reach this point and thus we are OK */
} while(0);
if(fail) {
if(outcurl) {
if(outcurl->state.connc->type == CONNCACHE_PRIVATE)
Curl_rm_connc(outcurl->state.connc);
if(outcurl->state.headerbuff)
free(outcurl->state.headerbuff);
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;
Curl_safefree(data->reqdata.pathbuffer);
data->reqdata.pathbuffer=NULL;
Curl_safefree(data->reqdata.proto.generic);
data->reqdata.proto.generic=NULL;
/* zero out UserDefined data: */
memset(&data->set, 0, sizeof(struct UserDefined));
/* zero out Progress data: */
memset(&data->progress, 0, sizeof(struct Progress));
/* init Handle data */
Curl_easy_initHandleData(data);
/* 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->set.postfieldsize = -1;
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 */
/*
* 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 preferred CA cert bundle since install time */
data->set.ssl.CAfile = (char *)CURL_CA_BUNDLE;
#endif
data->set.ssh_auth_types = CURLSSH_AUTH_DEFAULT; /* defaults to any auth
type */
}
#ifdef CURL_DOES_CONVERSIONS
/*
* Curl_convert_to_network() is an internal function
* for performing ASCII conversions on non-ASCII platforms.
*/
CURLcode Curl_convert_to_network(struct SessionHandle *data,
char *buffer, size_t length)
{
CURLcode rc;
if(data->set.convtonetwork) {
/* use translation callback */
rc = data->set.convtonetwork(buffer, length);
if(rc != CURLE_OK) {
failf(data,
"CURLOPT_CONV_TO_NETWORK_FUNCTION callback returned %i: %s",
rc, curl_easy_strerror(rc));
}
return(rc);
} else {
#ifdef HAVE_ICONV
/* do the translation ourselves */
char *input_ptr, *output_ptr;
size_t in_bytes, out_bytes, rc;
/* open an iconv conversion descriptor if necessary */
if(data->outbound_cd == (iconv_t)-1) {
data->outbound_cd = iconv_open(CURL_ICONV_CODESET_OF_NETWORK,
CURL_ICONV_CODESET_OF_HOST);
if(data->outbound_cd == (iconv_t)-1) {
failf(data,
"The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
CURL_ICONV_CODESET_OF_NETWORK,
CURL_ICONV_CODESET_OF_HOST,
errno, strerror(errno));
return CURLE_CONV_FAILED;
}
}
/* call iconv */
input_ptr = output_ptr = buffer;
in_bytes = out_bytes = length;
rc = iconv(data->outbound_cd, (const char**)&input_ptr, &in_bytes,
&output_ptr, &out_bytes);
if ((rc == ICONV_ERROR) || (in_bytes != 0)) {
failf(data,
"The Curl_convert_to_network iconv call failed with errno %i: %s",
errno, strerror(errno));
return CURLE_CONV_FAILED;
}
#else
failf(data, "CURLOPT_CONV_TO_NETWORK_FUNCTION callback required");
return CURLE_CONV_REQD;
#endif /* HAVE_ICONV */
}
return CURLE_OK;
}
/*
* Curl_convert_from_network() is an internal function
* for performing ASCII conversions on non-ASCII platforms.
*/
CURLcode Curl_convert_from_network(struct SessionHandle *data,
char *buffer, size_t length)
{
CURLcode rc;
if(data->set.convfromnetwork) {
/* use translation callback */
rc = data->set.convfromnetwork(buffer, length);
if(rc != CURLE_OK) {
failf(data,
"CURLOPT_CONV_FROM_NETWORK_FUNCTION callback returned %i: %s",
rc, curl_easy_strerror(rc));
}
return(rc);
} else {
#ifdef HAVE_ICONV
/* do the translation ourselves */
char *input_ptr, *output_ptr;
size_t in_bytes, out_bytes, rc;
/* open an iconv conversion descriptor if necessary */
if(data->inbound_cd == (iconv_t)-1) {
data->inbound_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
CURL_ICONV_CODESET_OF_NETWORK);
if(data->inbound_cd == (iconv_t)-1) {
failf(data,
"The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
CURL_ICONV_CODESET_OF_HOST,
CURL_ICONV_CODESET_OF_NETWORK,
errno, strerror(errno));
return CURLE_CONV_FAILED;
}
}
/* call iconv */
input_ptr = output_ptr = buffer;
in_bytes = out_bytes = length;
rc = iconv(data->inbound_cd, (const char **)&input_ptr, &in_bytes,
&output_ptr, &out_bytes);
if ((rc == ICONV_ERROR) || (in_bytes != 0)) {
failf(data,
"The Curl_convert_from_network iconv call failed with errno %i: %s",
errno, strerror(errno));
return CURLE_CONV_FAILED;
}
#else
failf(data, "CURLOPT_CONV_FROM_NETWORK_FUNCTION callback required");
return CURLE_CONV_REQD;
#endif /* HAVE_ICONV */
}
return CURLE_OK;
}
/*
* Curl_convert_from_utf8() is an internal function
* for performing UTF-8 conversions on non-ASCII platforms.
*/
CURLcode Curl_convert_from_utf8(struct SessionHandle *data,
char *buffer, size_t length)
{
CURLcode rc;
if(data->set.convfromutf8) {
/* use translation callback */
rc = data->set.convfromutf8(buffer, length);
if(rc != CURLE_OK) {
failf(data,
"CURLOPT_CONV_FROM_UTF8_FUNCTION callback returned %i: %s",
rc, curl_easy_strerror(rc));
}
return(rc);
} else {
#ifdef HAVE_ICONV
/* do the translation ourselves */
char *input_ptr, *output_ptr;
size_t in_bytes, out_bytes, rc;
/* open an iconv conversion descriptor if necessary */
if(data->utf8_cd == (iconv_t)-1) {
data->utf8_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
CURL_ICONV_CODESET_FOR_UTF8);
if(data->utf8_cd == (iconv_t)-1) {
failf(data,
"The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
CURL_ICONV_CODESET_OF_HOST,
CURL_ICONV_CODESET_FOR_UTF8,
errno, strerror(errno));
return CURLE_CONV_FAILED;
}
}
/* call iconv */
input_ptr = output_ptr = buffer;
in_bytes = out_bytes = length;
rc = iconv(data->utf8_cd, (const char**)&input_ptr, &in_bytes,
&output_ptr, &out_bytes);
if ((rc == ICONV_ERROR) || (in_bytes != 0)) {
failf(data,
"The Curl_convert_from_utf8 iconv call failed with errno %i: %s",
errno, strerror(errno));
return CURLE_CONV_FAILED;
}
if (output_ptr < input_ptr) {
/* null terminate the now shorter output string */
*output_ptr = 0x00;
}
#else
failf(data, "CURLOPT_CONV_FROM_UTF8_FUNCTION callback required");
return CURLE_CONV_REQD;
#endif /* HAVE_ICONV */
}
return CURLE_OK;
}
#endif /* CURL_DOES_CONVERSIONS */

View File

@ -1,407 +0,0 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute 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>
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef WIN32
#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
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#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_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 "memory.h"
#include "parsedate.h" /* for the week day and month names */
#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_easy_unescape(conn->data, conn->data->reqdata.path, 0, NULL);
struct FILEPROTO *file;
int fd;
#if defined(WIN32) || defined(MSDOS) || 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;
}
if (conn->data->reqdata.proto.file) {
free(conn->data->reqdata.proto.file);
}
conn->data->reqdata.proto.file = file;
#if defined(WIN32) || defined(MSDOS) || 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 DOS, 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 */
file->fd = fd;
if(!conn->data->set.upload && (fd == -1)) {
failf(conn->data, "Couldn't open file %s", conn->data->reqdata.path);
Curl_file_done(conn, CURLE_FILE_COULDNT_READ_FILE, FALSE);
return CURLE_FILE_COULDNT_READ_FILE;
}
return CURLE_OK;
}
CURLcode Curl_file_done(struct connectdata *conn,
CURLcode status, bool premature)
{
struct FILEPROTO *file = conn->data->reqdata.proto.file;
(void)status; /* not used */
(void)premature; /* not used */
Curl_safefree(file->freepath);
if(file->fd != -1)
close(file->fd);
return CURLE_OK;
}
#if defined(WIN32) || defined(MSDOS) || defined(__EMX__)
#define DIRSEP '\\'
#else
#define DIRSEP '/'
#endif
static CURLcode file_upload(struct connectdata *conn)
{
struct FILEPROTO *file = conn->data->reqdata.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->data->reqdata.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)
break;
if (readcount <= 0) /* fix questionable compare error. curlvms */
break;
nread = (size_t)readcount;
/* 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, bool *done)
{
/* 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; /* struct_stat instead of struct stat just to allow the
Windows version to have a different struct without
having to redefine the simple word 'stat' */
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();
*done = TRUE; /* unconditionally */
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->data->reqdata.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(conn, CLIENTWRITE_BOTH, buf, 0);
if(result)
return result;
result = Curl_client_write(conn, CLIENTWRITE_BOTH,
(char *)"Accept-ranges: bytes\r\n", 0);
if(result)
return result;
if(fstated) {
struct tm *tm;
time_t clock = (time_t)statbuf.st_mtime;
#ifdef HAVE_GMTIME_R
struct tm buffer;
tm = (struct tm *)gmtime_r(&clock, &buffer);
#else
tm = gmtime(&clock);
#endif
/* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
snprintf(buf, BUFSIZE-1,
"Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n",
Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
tm->tm_mday,
Curl_month[tm->tm_mon],
tm->tm_year + 1900,
tm->tm_hour,
tm->tm_min,
tm->tm_sec);
result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0);
}
return result;
}
if (data->reqdata.resume_from <= expected_size)
expected_size -= data->reqdata.resume_from;
else {
failf(data, "failed to resume file:// transfer");
return CURLE_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(data->reqdata.resume_from) {
if(data->reqdata.resume_from !=
lseek(fd, data->reqdata.resume_from, SEEK_SET))
return CURLE_BAD_DOWNLOAD_RESUME;
}
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(conn, 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;
return res;
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,43 +0,0 @@
#ifndef __FTP_H
#define __FTP_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute 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, bool *done);
CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode, bool premature);
CURLcode Curl_ftp_connect(struct connectdata *conn, bool *done);
CURLcode Curl_ftp_disconnect(struct connectdata *conn);
CURLcode Curl_ftpsendf(struct connectdata *, const char *fmt, ...);
CURLcode Curl_nbftpsendf(struct connectdata *, const char *fmt, ...);
CURLcode Curl_GetFTPResponse(ssize_t *nread, struct connectdata *conn,
int *ftpcode);
CURLcode Curl_ftp_nextconnect(struct connectdata *conn);
CURLcode Curl_ftp_multi_statemach(struct connectdata *conn, bool *done);
int Curl_ftp_getsock(struct connectdata *conn,
curl_socket_t *socks,
int numsocks);
CURLcode Curl_ftp_doing(struct connectdata *conn,
bool *dophase_done);
#endif /* CURL_DISABLE_FTP */
#endif /* __FTP_H */

View File

@ -1,234 +0,0 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute 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 "memory.h"
#include "sslgen.h"
/* Make this the last #include */
#include "memdebug.h"
/*
* This is supposed to be called in the beginning of a perform() 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;
info->numconnects = 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;
struct curl_slist **param_slistp=NULL;
char buf;
if(!data)
return CURLE_BAD_FUNCTION_ARGUMENT;
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;
case CURLINFO_SLIST:
param_slistp = va_arg(arg, struct curl_slist **);
if(NULL == param_slistp)
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_data;
break;
case CURLINFO_HTTPAUTH_AVAIL:
*param_longp = data->info.httpauthavail;
break;
case CURLINFO_PROXYAUTH_AVAIL:
*param_longp = data->info.proxyauthavail;
break;
case CURLINFO_OS_ERRNO:
*param_longp = data->state.os_errno;
break;
case CURLINFO_NUM_CONNECTS:
*param_longp = data->info.numconnects;
break;
case CURLINFO_SSL_ENGINES:
*param_slistp = Curl_ssl_engines_list(data);
break;
case CURLINFO_COOKIELIST:
*param_slistp = Curl_cookie_list(data);
break;
case CURLINFO_FTP_ENTRY_PATH:
/* Return the entrypath string from the most recent connection.
This pointer was copied from the connectdata structure by FTP.
The actual string may be free()ed by subsequent libcurl calls so
it must be copied to a safer area before the next libcurl call.
Callers must never free it themselves. */
*param_charp = data->state.most_recent_ftp_entrypath;
break;
case CURLINFO_LASTSOCKET:
if((data->state.lastconnect != -1) &&
(data->state.connc->connects[data->state.lastconnect] != NULL)) {
struct connectdata *c = data->state.connc->connects
[data->state.lastconnect];
*param_longp = c->sock[FIRSTSOCKET];
/* we have a socket connected, let's determine if the server shut down */
/* determine if ssl */
if(c->ssl[FIRSTSOCKET].use) {
/* use the SSL context */
if (!Curl_ssl_check_cxn(c))
*param_longp = -1; /* FIN received */
}
/* Minix 3.1 doesn't support any flags on recv; just assume socket is OK */
#ifdef MSG_PEEK
else {
/* use the socket */
if(recv((RECV_TYPE_ARG1)c->sock[FIRSTSOCKET], (RECV_TYPE_ARG2)&buf,
(RECV_TYPE_ARG3)1, (RECV_TYPE_ARG4)MSG_PEEK) == 0) {
*param_longp = -1; /* FIN received */
}
}
#endif
}
else
*param_longp = -1;
break;
default:
return CURLE_BAD_FUNCTION_ARGUMENT;
}
return CURLE_OK;
}

View File

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

View File

@ -1,640 +0,0 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute 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$
***************************************************************************/
/*
* Source file for all GnuTLS-specific code for the TLS/SSL layer. No code
* but sslgen.c should ever call or use these functions.
*
* Note: don't use the GnuTLS' *_t variable type names in this source code,
* since they were not present in 1.0.X.
*/
#include "setup.h"
#ifdef USE_GNUTLS
#include <gnutls/gnutls.h>
#include <gnutls/x509.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 "gtls.h"
#include "sslgen.h"
#include "parsedate.h"
#include "connect.h" /* for the connect timeout */
#include "select.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
#include "memory.h"
/* The last #include file should be: */
#include "memdebug.h"
/* Enable GnuTLS debugging by defining GTLSDEBUG */
/*#define GTLSDEBUG */
#ifdef GTLSDEBUG
static void tls_log_func(int level, const char *str)
{
fprintf(stderr, "|<%d>| %s", level, str);
}
#endif
/*
* Custom push and pull callback functions used by GNU TLS to read and write
* to the socket. These functions are simple wrappers to send() and recv()
* (although here using the sread/swrite macros as defined by setup_once.h).
* We use custom functions rather than the GNU TLS defaults because it allows
* us to get specific about the fourth "flags" argument, and to use arbitrary
* private data with gnutls_transport_set_ptr if we wish.
*/
static ssize_t Curl_gtls_push(void *s, const void *buf, size_t len)
{
return swrite(s, buf, len);
}
static ssize_t Curl_gtls_pull(void *s, void *buf, size_t len)
{
return sread(s, buf, len);
}
/* Global GnuTLS init, called from Curl_ssl_init() */
int Curl_gtls_init(void)
{
gnutls_global_init();
#ifdef GTLSDEBUG
gnutls_global_set_log_function(tls_log_func);
gnutls_global_set_log_level(2);
#endif
return 1;
}
int Curl_gtls_cleanup(void)
{
gnutls_global_deinit();
return 1;
}
static void showtime(struct SessionHandle *data,
const char *text,
time_t stamp)
{
struct tm *tm;
#ifdef HAVE_GMTIME_R
struct tm buffer;
tm = (struct tm *)gmtime_r(&stamp, &buffer);
#else
tm = gmtime(&stamp);
#endif
snprintf(data->state.buffer,
BUFSIZE,
"\t %s: %s, %02d %s %4d %02d:%02d:%02d GMT\n",
text,
Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
tm->tm_mday,
Curl_month[tm->tm_mon],
tm->tm_year + 1900,
tm->tm_hour,
tm->tm_min,
tm->tm_sec);
infof(data, "%s", data->state.buffer);
}
/* this function does a BLOCKING SSL/TLS (re-)handshake */
static CURLcode handshake(struct connectdata *conn,
gnutls_session session,
int sockindex,
bool duringconnect)
{
struct SessionHandle *data = conn->data;
int rc;
do {
rc = gnutls_handshake(session);
if((rc == GNUTLS_E_AGAIN) || (rc == GNUTLS_E_INTERRUPTED)) {
long timeout_ms = DEFAULT_CONNECT_TIMEOUT;
long has_passed;
if(duringconnect && data->set.connecttimeout)
timeout_ms = data->set.connecttimeout*1000;
if(data->set.timeout) {
/* get the strictest timeout of the ones converted to milliseconds */
if((data->set.timeout*1000) < timeout_ms)
timeout_ms = data->set.timeout*1000;
}
/* Evaluate in milliseconds how much time that has passed */
has_passed = Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle);
/* 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;
}
rc = Curl_select(conn->sock[sockindex],
conn->sock[sockindex], (int)timeout_ms);
if(rc > 0)
/* reabable or writable, go loop*/
continue;
else if(0 == rc) {
/* timeout */
failf(data, "SSL connection timeout");
return CURLE_OPERATION_TIMEDOUT;
}
else {
/* anything that gets here is fatally bad */
failf(data, "select on SSL socket, errno: %d", Curl_sockerrno());
return CURLE_SSL_CONNECT_ERROR;
}
}
else
break;
} while(1);
if (rc < 0) {
failf(data, "gnutls_handshake() failed: %s", gnutls_strerror(rc));
return CURLE_SSL_CONNECT_ERROR;
}
return CURLE_OK;
}
static gnutls_x509_crt_fmt do_file_type(const char *type)
{
if(!type || !type[0])
return GNUTLS_X509_FMT_PEM;
if(curl_strequal(type, "PEM"))
return GNUTLS_X509_FMT_PEM;
if(curl_strequal(type, "DER"))
return GNUTLS_X509_FMT_DER;
return -1;
}
/*
* This function is called after the TCP connect has completed. Setup the TLS
* layer and do all necessary magic.
*/
CURLcode
Curl_gtls_connect(struct connectdata *conn,
int sockindex)
{
const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 };
struct SessionHandle *data = conn->data;
gnutls_session session;
int rc;
unsigned int cert_list_size;
const gnutls_datum *chainp;
unsigned int verify_status;
gnutls_x509_crt x509_cert;
char certbuf[256]; /* big enough? */
size_t size;
unsigned int algo;
unsigned int bits;
time_t clock;
const char *ptr;
void *ssl_sessionid;
size_t ssl_idsize;
/* GnuTLS only supports TLSv1 (and SSLv3?) */
if(data->set.ssl.version == CURL_SSLVERSION_SSLv2) {
failf(data, "GnuTLS does not support SSLv2");
return CURLE_SSL_CONNECT_ERROR;
}
/* allocate a cred struct */
rc = gnutls_certificate_allocate_credentials(&conn->ssl[sockindex].cred);
if(rc < 0) {
failf(data, "gnutls_cert_all_cred() failed: %s", gnutls_strerror(rc));
return CURLE_SSL_CONNECT_ERROR;
}
if(data->set.ssl.CAfile) {
/* set the trusted CA cert bundle file */
gnutls_certificate_set_verify_flags(conn->ssl[sockindex].cred,
GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT);
rc = gnutls_certificate_set_x509_trust_file(conn->ssl[sockindex].cred,
data->set.ssl.CAfile,
GNUTLS_X509_FMT_PEM);
if(rc < 0) {
infof(data, "error reading ca cert file %s (%s)\n",
data->set.ssl.CAfile, gnutls_strerror(rc));
if (data->set.ssl.verifypeer)
return CURLE_SSL_CACERT_BADFILE;
}
else
infof(data, "found %d certificates in %s\n",
rc, data->set.ssl.CAfile);
}
/* Initialize TLS session as a client */
rc = gnutls_init(&conn->ssl[sockindex].session, GNUTLS_CLIENT);
if(rc) {
failf(data, "gnutls_init() failed: %d", rc);
return CURLE_SSL_CONNECT_ERROR;
}
/* convenient assign */
session = conn->ssl[sockindex].session;
/* Use default priorities */
rc = gnutls_set_default_priority(session);
if(rc < 0)
return CURLE_SSL_CONNECT_ERROR;
/* Sets the priority on the certificate types supported by gnutls. Priority
is higher for types specified before others. After specifying the types
you want, you must append a 0. */
rc = gnutls_certificate_type_set_priority(session, cert_type_priority);
if(rc < 0)
return CURLE_SSL_CONNECT_ERROR;
if(data->set.cert) {
if( gnutls_certificate_set_x509_key_file(
conn->ssl[sockindex].cred, data->set.cert,
data->set.key != 0 ? data->set.key : data->set.cert,
do_file_type(data->set.cert_type) ) ) {
failf(data, "error reading X.509 key or certificate file");
return CURLE_SSL_CONNECT_ERROR;
}
}
/* put the credentials to the current session */
rc = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE,
conn->ssl[sockindex].cred);
/* set the connection handle (file descriptor for the socket) */
gnutls_transport_set_ptr(session,
(gnutls_transport_ptr)conn->sock[sockindex]);
/* register callback functions to send and receive data. */
gnutls_transport_set_push_function(session, Curl_gtls_push);
gnutls_transport_set_pull_function(session, Curl_gtls_pull);
/* lowat must be set to zero when using custom push and pull functions. */
gnutls_transport_set_lowat(session, 0);
/* This might be a reconnect, so we check for a session ID in the cache
to speed up things */
if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, &ssl_idsize)) {
/* we got a session id, use it! */
gnutls_session_set_data(session, ssl_sessionid, ssl_idsize);
/* Informational message */
infof (data, "SSL re-using session ID\n");
}
rc = handshake(conn, session, sockindex, TRUE);
if(rc)
/* handshake() sets its own error message with failf() */
return rc;
/* This function will return the peer's raw certificate (chain) as sent by
the peer. These certificates are in raw format (DER encoded for
X.509). In case of a X.509 then a certificate list may be present. The
first certificate in the list is the peer's certificate, following the
issuer's certificate, then the issuer's issuer etc. */
chainp = gnutls_certificate_get_peers(session, &cert_list_size);
if(!chainp) {
if(data->set.ssl.verifyhost) {
failf(data, "failed to get server cert");
return CURLE_SSL_PEER_CERTIFICATE;
}
infof(data, "\t common name: WARNING couldn't obtain\n");
}
/* This function will try to verify the peer's certificate and return its
status (trusted, invalid etc.). The value of status should be one or more
of the gnutls_certificate_status_t enumerated elements bitwise or'd. To
avoid denial of service attacks some default upper limits regarding the
certificate key size and chain size are set. To override them use
gnutls_certificate_set_verify_limits(). */
rc = gnutls_certificate_verify_peers2(session, &verify_status);
if (rc < 0) {
failf(data, "server cert verify failed: %d", rc);
return CURLE_SSL_CONNECT_ERROR;
}
/* verify_status is a bitmask of gnutls_certificate_status bits */
if(verify_status & GNUTLS_CERT_INVALID) {
if (data->set.ssl.verifypeer) {
failf(data, "server certificate verification failed. CAfile: %s",
data->set.ssl.CAfile?data->set.ssl.CAfile:"none");
return CURLE_SSL_CACERT;
}
else
infof(data, "\t server certificate verification FAILED\n");
}
else
infof(data, "\t server certificate verification OK\n");
/* initialize an X.509 certificate structure. */
gnutls_x509_crt_init(&x509_cert);
/* convert the given DER or PEM encoded Certificate to the native
gnutls_x509_crt_t format */
gnutls_x509_crt_import(x509_cert, chainp, GNUTLS_X509_FMT_DER);
size=sizeof(certbuf);
rc = gnutls_x509_crt_get_dn_by_oid(x509_cert, GNUTLS_OID_X520_COMMON_NAME,
0, /* the first and only one */
FALSE,
certbuf,
&size);
if(rc) {
infof(data, "error fetching CN from cert:%s\n",
gnutls_strerror(rc));
}
/* This function will check if the given certificate's subject matches the
given hostname. This is a basic implementation of the matching described
in RFC2818 (HTTPS), which takes into account wildcards, and the subject
alternative name PKIX extension. Returns non zero on success, and zero on
failure. */
rc = gnutls_x509_crt_check_hostname(x509_cert, conn->host.name);
if(!rc) {
if (data->set.ssl.verifyhost > 1) {
failf(data, "SSL: certificate subject name (%s) does not match "
"target host name '%s'", certbuf, conn->host.dispname);
gnutls_x509_crt_deinit(x509_cert);
return CURLE_SSL_PEER_CERTIFICATE;
}
else
infof(data, "\t common name: %s (does not match '%s')\n",
certbuf, conn->host.dispname);
}
else
infof(data, "\t common name: %s (matched)\n", certbuf);
/* Show:
- ciphers used
- subject
- start date
- expire date
- common name
- issuer
*/
/* public key algorithm's parameters */
algo = gnutls_x509_crt_get_pk_algorithm(x509_cert, &bits);
infof(data, "\t certificate public key: %s\n",
gnutls_pk_algorithm_get_name(algo));
/* version of the X.509 certificate. */
infof(data, "\t certificate version: #%d\n",
gnutls_x509_crt_get_version(x509_cert));
size = sizeof(certbuf);
gnutls_x509_crt_get_dn(x509_cert, certbuf, &size);
infof(data, "\t subject: %s\n", certbuf);
clock = gnutls_x509_crt_get_activation_time(x509_cert);
showtime(data, "start date", clock);
clock = gnutls_x509_crt_get_expiration_time(x509_cert);
showtime(data, "expire date", clock);
size = sizeof(certbuf);
gnutls_x509_crt_get_issuer_dn(x509_cert, certbuf, &size);
infof(data, "\t issuer: %s\n", certbuf);
gnutls_x509_crt_deinit(x509_cert);
/* compression algorithm (if any) */
ptr = gnutls_compression_get_name(gnutls_compression_get(session));
/* the *_get_name() says "NULL" if GNUTLS_COMP_NULL is returned */
infof(data, "\t compression: %s\n", ptr);
/* the name of the cipher used. ie 3DES. */
ptr = gnutls_cipher_get_name(gnutls_cipher_get(session));
infof(data, "\t cipher: %s\n", ptr);
/* the MAC algorithms name. ie SHA1 */
ptr = gnutls_mac_get_name(gnutls_mac_get(session));
infof(data, "\t MAC: %s\n", ptr);
if(!ssl_sessionid) {
/* this session was not previously in the cache, add it now */
/* get the session ID data size */
gnutls_session_get_data(session, NULL, &ssl_idsize);
ssl_sessionid = malloc(ssl_idsize); /* get a buffer for it */
if(ssl_sessionid) {
/* extract session ID to the allocated buffer */
gnutls_session_get_data(session, ssl_sessionid, &ssl_idsize);
/* store this session id */
return Curl_ssl_addsessionid(conn, ssl_sessionid, ssl_idsize);
}
}
return CURLE_OK;
}
/* return number of sent (non-SSL) bytes */
ssize_t Curl_gtls_send(struct connectdata *conn,
int sockindex,
void *mem,
size_t len)
{
ssize_t rc = gnutls_record_send(conn->ssl[sockindex].session, mem, len);
if(rc < 0 ) {
if(rc == GNUTLS_E_AGAIN)
return 0; /* EWOULDBLOCK equivalent */
rc = -1; /* generic error code for send failure */
}
return rc;
}
void Curl_gtls_close_all(struct SessionHandle *data)
{
/* FIX: make the OpenSSL code more generic and use parts of it here */
(void)data;
}
static void close_one(struct connectdata *conn,
int index)
{
if(conn->ssl[index].session) {
gnutls_bye(conn->ssl[index].session, GNUTLS_SHUT_RDWR);
gnutls_deinit(conn->ssl[index].session);
}
gnutls_certificate_free_credentials(conn->ssl[index].cred);
}
void Curl_gtls_close(struct connectdata *conn)
{
if(conn->ssl[0].use)
close_one(conn, 0);
if(conn->ssl[1].use)
close_one(conn, 1);
}
/*
* This function is called to shut down the SSL layer but keep the
* socket open (CCC - Clear Command Channel)
*/
int Curl_gtls_shutdown(struct connectdata *conn, int sockindex)
{
int result;
int retval = 0;
struct SessionHandle *data = conn->data;
int done = 0;
ssize_t nread;
char buf[120];
/* This has only been tested on the proftpd server, and the mod_tls code
sends a close notify alert without waiting for a close notify alert in
response. Thus we wait for a close notify alert from the server, but
we do not send one. Let's hope other servers do the same... */
if(conn->ssl[sockindex].session) {
while(!done) {
int what = Curl_select(conn->sock[sockindex],
CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
if(what > 0) {
/* Something to read, let's do it and hope that it is the close
notify alert from the server */
result = gnutls_record_recv(conn->ssl[sockindex].session,
buf, sizeof(buf));
switch(result) {
case 0:
/* This is the expected response. There was no data but only
the close notify alert */
done = 1;
break;
case GNUTLS_E_AGAIN:
case GNUTLS_E_INTERRUPTED:
infof(data, "GNUTLS_E_AGAIN || GNUTLS_E_INTERRUPTED\n");
break;
default:
retval = -1;
done = 1;
break;
}
}
else if(0 == what) {
/* timeout */
failf(data, "SSL shutdown timeout");
done = 1;
break;
}
else {
/* anything that gets here is fatally bad */
failf(data, "select on SSL socket, errno: %d", Curl_sockerrno());
retval = -1;
done = 1;
}
}
gnutls_deinit(conn->ssl[sockindex].session);
}
gnutls_certificate_free_credentials(conn->ssl[sockindex].cred);
conn->ssl[sockindex].session = NULL;
conn->ssl[sockindex].use = FALSE;
return retval;
}
/*
* If the read would block we return -1 and set 'wouldblock' to TRUE.
* Otherwise we return the amount of data read. Other errors should return -1
* and set 'wouldblock' to FALSE.
*/
ssize_t Curl_gtls_recv(struct connectdata *conn, /* connection data */
int num, /* socketindex */
char *buf, /* store read data here */
size_t buffersize, /* max amount to read */
bool *wouldblock)
{
ssize_t ret;
ret = gnutls_record_recv(conn->ssl[num].session, buf, buffersize);
if((ret == GNUTLS_E_AGAIN) || (ret == GNUTLS_E_INTERRUPTED)) {
*wouldblock = TRUE;
return -1;
}
if(ret == GNUTLS_E_REHANDSHAKE) {
/* BLOCKING call, this is bad but a work-around for now. Fixing this "the
proper way" takes a whole lot of work. */
CURLcode rc = handshake(conn, conn->ssl[num].session, num, FALSE);
if(rc)
/* handshake() writes error message on its own */
return rc;
*wouldblock = TRUE; /* then return as if this was a wouldblock */
return -1;
}
*wouldblock = FALSE;
if (!ret) {
failf(conn->data, "Peer closed the TLS connection");
return -1;
}
if (ret < 0) {
failf(conn->data, "GnuTLS recv error (%d): %s",
(int)ret, gnutls_strerror(ret));
return -1;
}
return ret;
}
void Curl_gtls_session_free(void *ptr)
{
free(ptr);
}
size_t Curl_gtls_version(char *buffer, size_t size)
{
return snprintf(buffer, size, " GnuTLS/%s", gnutls_check_version(NULL));
}
#endif /* USE_GNUTLS */

View File

@ -1,46 +0,0 @@
#ifndef __GTLS_H
#define __GTLS_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute 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_gtls_init(void);
int Curl_gtls_cleanup(void);
CURLcode Curl_gtls_connect(struct connectdata *conn, int sockindex);
/* tell GnuTLS to close down all open information regarding connections (and
thus session ID caching etc) */
void Curl_gtls_close_all(struct SessionHandle *data);
void Curl_gtls_close(struct connectdata *conn); /* close a SSL connection */
/* return number of sent (non-SSL) bytes */
ssize_t Curl_gtls_send(struct connectdata *conn, int sockindex,
void *mem, size_t len);
ssize_t Curl_gtls_recv(struct connectdata *conn, /* connection data */
int num, /* socketindex */
char *buf, /* store read data here */
size_t buffersize, /* max amount to read */
bool *wouldblock);
void Curl_gtls_session_free(void *ptr);
size_t Curl_gtls_version(char *buffer, size_t size);
int Curl_gtls_shutdown(struct connectdata *conn, int sockindex);
#endif

View File

@ -1,315 +0,0 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute 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 "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)
{
struct curl_hash *h = (struct curl_hash *) user;
struct curl_hash_element *e = (struct 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(struct curl_hash *h, int slots, curl_hash_dtor dtor)
{
int i;
h->dtor = dtor;
h->size = 0;
h->slots = slots;
h->table = (struct curl_llist **) malloc(slots * sizeof(struct 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 */
}
struct curl_hash *
Curl_hash_alloc(int slots, curl_hash_dtor dtor)
{
struct curl_hash *h;
h = (struct curl_hash *) malloc(sizeof(struct 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 struct curl_hash_element *
mk_hash_element(char *key, size_t key_len, const void *p)
{
struct curl_hash_element *he =
(struct curl_hash_element *) malloc(sizeof(struct curl_hash_element));
if(he) {
char *dup = malloc(key_len);
if(dup) {
/* copy the key */
memcpy(dup, key, key_len);
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(struct curl_hash *h, char *key, size_t key_len, void *p)
{
struct curl_hash_element *he;
struct curl_llist_element *le;
struct curl_llist *l = FETCH_LIST(h, key, key_len);
for (le = l->head; le; le = le->next) {
he = (struct 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 */
}
/* remove the identified hash entry, returns non-zero on failure */
int Curl_hash_delete(struct curl_hash *h, char *key, size_t key_len)
{
struct curl_llist_element *le;
struct curl_hash_element *he;
struct 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)) {
Curl_llist_remove(l, le, (void *) h);
return 0;
}
}
return 1;
}
void *
Curl_hash_pick(struct curl_hash *h, char *key, size_t key_len)
{
struct curl_llist_element *le;
struct curl_hash_element *he;
struct 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))
{
struct 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(struct 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(struct curl_hash *h, void *user,
int (*comp)(void *, void *))
{
struct curl_llist_element *le;
struct curl_llist_element *lnext;
struct 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) {
struct 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(struct curl_hash *h)
{
if (!h)
return;
Curl_hash_clean(h);
free(h);
}
#if 0 /* useful function for debugging hashes and their contents */
void Curl_hash_print(struct curl_hash *h,
void (*func)(void *))
{
int i;
struct curl_llist_element *le;
struct curl_llist *list;
struct curl_hash_element *he;
if (!h)
return;
fprintf(stderr, "=Hash dump=\n");
for (i = 0; i < h->slots; i++) {
list = h->table[i];
le = list->head; /* get first list entry */
if(le) {
fprintf(stderr, "index %d:", i);
while(le) {
he = le->ptr;
if(func)
func(he->ptr);
else
fprintf(stderr, " [%p]", he->ptr);
le = le->next;
}
fprintf(stderr, "\n");
}
}
}
#endif

View File

@ -1,61 +0,0 @@
#ifndef __HASH_H
#define __HASH_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute 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 *);
struct curl_hash {
struct curl_llist **table;
curl_hash_dtor dtor;
int slots;
size_t size;
};
struct curl_hash_element {
void *ptr;
char *key;
size_t key_len;
};
int Curl_hash_init(struct curl_hash *, int, curl_hash_dtor);
struct curl_hash *Curl_hash_alloc(int, curl_hash_dtor);
void *Curl_hash_add(struct curl_hash *, char *, size_t, void *);
int Curl_hash_delete(struct curl_hash *h, char *key, size_t key_len);
void *Curl_hash_pick(struct curl_hash *, char *, size_t);
void Curl_hash_apply(struct curl_hash *h, void *user,
void (*cb)(void *user, void *ptr));
int Curl_hash_count(struct curl_hash *h);
void Curl_hash_clean(struct curl_hash *h);
void Curl_hash_clean_with_criterium(struct curl_hash *h, void *user,
int (*comp)(void *, void *));
void Curl_hash_destroy(struct curl_hash *h);
#endif

View File

@ -1,307 +0,0 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute 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>
#ifdef NEED_MALLOC_H
#include <malloc.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_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
#ifdef HAVE_SETJMP_H
#include <setjmp.h>
#endif
#ifdef HAVE_PROCESS_H
#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 "multiif.h"
#include "connect.h" /* for the Curl_sockerrno() proto */
#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 "memory.h"
/* The last #include file should be: */
#include "memdebug.h"
/***********************************************************************
* Only for ares-enabled builds
**********************************************************************/
#ifdef CURLRES_ARES
/*
* Curl_resolv_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!
*/
int Curl_resolv_getsock(struct connectdata *conn,
curl_socket_t *socks,
int numsocks)
{
struct timeval maxtime;
struct timeval timeout;
int max = ares_getsock(conn->data->state.areschannel,
(int *)socks, numsocks);
maxtime.tv_sec = CURL_TIMEOUT_RESOLVE;
maxtime.tv_usec = 0;
ares_timeout(conn->data->state.areschannel, &maxtime, &timeout);
Curl_expire(conn->data,
(timeout.tv_sec * 1000) + (timeout.tv_usec/1000) );
return max;
}
/*
* 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 && Curl_sockerrno() != 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 */
conn->bits.close = TRUE;
}
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,
const 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,
(ares_host_callback)Curl_addrinfo4_callback, conn);
*waitp = TRUE; /* please wait for the response */
}
return NULL; /* no struct yet */
}
#endif /* CURLRES_ARES */

View File

@ -1,636 +0,0 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute 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>
#ifdef NEED_MALLOC_H
#include <malloc.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_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
#ifdef HAVE_SETJMP_H
#include <setjmp.h>
#endif
#ifdef HAVE_PROCESS_H
#include <process.h>
#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 "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. 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 struct 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
*/
struct 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++)
; /* empty loop */
return i;
}
/*
* 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)
{
const void *ip4 = &((const struct sockaddr_in*)ip->ai_addr)->sin_addr;
int af = ip->ai_family;
#ifdef CURLRES_IPV6
const void *ip6 = &((const struct sockaddr_in6*)ip->ai_addr)->sin6_addr;
#else
const void *ip6 = NULL;
#endif
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(const 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(struct 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) || !data->dns.hostcache)
/* cache forever means never prune, and NULL hostcache means
we can't do it */
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->dns.hostcache,
data->set.dns_cache_timeout,
now);
if(data->share)
Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
}
static int
remove_entry_if_stale(struct SessionHandle *data, struct Curl_dns_entry *dns)
{
struct hostcache_prune_data user;
if( !dns || (data->set.dns_cache_timeout == -1) || !data->dns.hostcache)
/* cache forever means never prune, and NULL hostcache means
we can't do it */
return 0;
time(&user.now);
user.cache_timeout = data->set.dns_cache_timeout;
if ( !hostcache_timestamp_remove(&user,dns) )
return 0;
/* ok, we do need to clear the cache. although we need to remove just a
single entry we clean the entire hash, as no explicit delete function
is provided */
if(data->share)
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
Curl_hash_clean_with_criterium(data->dns.hostcache,
(void *) &user,
hostcache_timestamp_remove);
if(data->share)
Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
return 1;
}
#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,
const 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 *) calloc(sizeof(struct Curl_dns_entry), 1);
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->dns.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,
const char *hostname,
int port,
struct Curl_dns_entry **entry)
{
char *entry_id = NULL;
struct Curl_dns_entry *dns = NULL;
size_t entry_len;
int wait;
struct SessionHandle *data = conn->data;
CURLcode result;
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) {
if (sigsetjmp(curl_jmpenv, 1)) {
/* this is coming from a siglongjmp() */
failf(data, "name lookup timed out");
return CURLRESOLV_ERROR;
}
}
#endif
/* 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->dns.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);
/* See whether the returned entry is stale. Deliberately done after the
locked block */
if ( remove_entry_if_stale(data,dns) )
dns = NULL; /* the memory deallocation is being handled by the hash */
rc = CURLRESOLV_ERROR; /* default to failure */
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 {
if(data->share)
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
dns->inuse++; /* we use it! */
if(data->share)
Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
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.
*/
struct 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(const void *org, int port)
{
const struct hostent *orig = org;
return Curl_he2ai(orig, port);
}
#endif /* CURLRES_ADDRINFO_COPY */
/***********************************************************************
* Only for plain-ipv4 and c-ares builds
**********************************************************************/
#if defined(CURLRES_IPV4) || defined(CURLRES_ARES)
/*
* 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;
}
}
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, const 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;
#ifdef _CRAY
/* On UNICOS, s_addr is a bit field and for some reason assigning to it
* doesn't work. There must be a better fix than this ugly hack.
*/
memcpy(addrentry, &num, SIZEOF_in_addr);
#else
addrentry->s_addr = num;
#endif
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;
}
#endif

View File

@ -1,138 +0,0 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute 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>
#ifdef NEED_MALLOC_H
#include <malloc.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_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
#ifdef HAVE_SETJMP_H
#include <setjmp.h>
#endif
#ifdef HAVE_PROCESS_H
#include <process.h>
#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 "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
*/
int Curl_resolv_getsock(struct connectdata *conn,
curl_socket_t *sock,
int numsocks)
{
(void)conn;
(void)sock;
(void)numsocks;
return 0; /* no bits since we don't use any socks */
}
#endif /* truly sync */

View File

@ -1,840 +0,0 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute 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>
#ifdef NEED_MALLOC_H
#include <malloc.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_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
#ifdef HAVE_SETJMP_H
#include <setjmp.h>
#endif
#ifdef HAVE_PROCESS_H
#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 "multiif.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
#include "inet_ntop.h"
#include "memory.h"
/* The last #include file should be: */
#include "memdebug.h"
#if defined(_MSC_VER) && defined(CURL_NO__BEGINTHREADEX)
#pragma message ("No _beginthreadex() available in this RTL")
#endif
/***********************************************************************
* 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_resolv_fdset() */
HANDLE mutex_waiting; /* marks that we are still waiting for a resolve */
HANDLE event_resolved; /* marks that the thread obtained the information */
HANDLE event_thread_started; /* marks that the thread has initialized and
started */
HANDLE mutex_terminate; /* serializes access to flag_terminate */
HANDLE event_terminate; /* flag for thread to terminate instead of calling
callbacks */
#ifdef CURLRES_IPV6
struct addrinfo hints;
#endif
};
/* Data for synchronization between resolver thread and its parent */
struct thread_sync_data {
HANDLE mutex_waiting; /* thread_data.mutex_waiting duplicate */
HANDLE mutex_terminate; /* thread_data.mutex_terminate duplicate */
HANDLE event_terminate; /* thread_data.event_terminate duplicate */
char * hostname; /* hostname to resolve, Curl_async.hostname
duplicate */
};
/* Destroy resolver thread synchronization data */
static
void destroy_thread_sync_data(struct thread_sync_data * tsd)
{
if (tsd->hostname) {
free(tsd->hostname);
tsd->hostname = NULL;
}
if (tsd->event_terminate) {
CloseHandle(tsd->event_terminate);
tsd->event_terminate = NULL;
}
if (tsd->mutex_terminate) {
CloseHandle(tsd->mutex_terminate);
tsd->mutex_terminate = NULL;
}
if (tsd->mutex_waiting) {
CloseHandle(tsd->mutex_waiting);
tsd->mutex_waiting = NULL;
}
}
/* Initialize resolver thread synchronization data */
static
BOOL init_thread_sync_data(struct thread_data * td,
char * hostname,
struct thread_sync_data * tsd)
{
HANDLE curr_proc = GetCurrentProcess();
memset(tsd, 0, sizeof(*tsd));
if (!DuplicateHandle(curr_proc, td->mutex_waiting,
curr_proc, &tsd->mutex_waiting, 0, FALSE,
DUPLICATE_SAME_ACCESS)) {
/* failed to duplicate the mutex, no point in continuing */
destroy_thread_sync_data(tsd);
return FALSE;
}
if (!DuplicateHandle(curr_proc, td->mutex_terminate,
curr_proc, &tsd->mutex_terminate, 0, FALSE,
DUPLICATE_SAME_ACCESS)) {
/* failed to duplicate the mutex, no point in continuing */
destroy_thread_sync_data(tsd);
return FALSE;
}
if (!DuplicateHandle(curr_proc, td->event_terminate,
curr_proc, &tsd->event_terminate, 0, FALSE,
DUPLICATE_SAME_ACCESS)) {
/* failed to duplicate the event, no point in continuing */
destroy_thread_sync_data(tsd);
return FALSE;
}
/* Copying hostname string because original can be destroyed by parent
* thread during gethostbyname execution.
*/
tsd->hostname = strdup(hostname);
if (!tsd->hostname) {
/* Memory allocation failed */
destroy_thread_sync_data(tsd);
return FALSE;
}
return TRUE;
}
/* acquire resolver thread synchronization */
static
BOOL acquire_thread_sync(struct thread_sync_data * tsd)
{
/* is the thread initiator still waiting for us ? */
if (WaitForSingleObject(tsd->mutex_waiting, 0) == WAIT_TIMEOUT) {
/* yes, it is */
/* Waiting access to event_terminate */
if (WaitForSingleObject(tsd->mutex_terminate, INFINITE) != WAIT_OBJECT_0) {
/* Something went wrong - now just ignoring */
}
else {
if (WaitForSingleObject(tsd->event_terminate, 0) != WAIT_TIMEOUT) {
/* Parent thread signaled us to terminate.
* This means that all data in conn->async is now destroyed
* and we cannot use it.
*/
}
else {
return TRUE;
}
}
}
return FALSE;
}
/* release resolver thread synchronization */
static
void release_thread_sync(struct thread_sync_data * tsd)
{
ReleaseMutex(tsd->mutex_terminate);
}
#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 = 0;
/* Duplicate the passed mutex and event handles.
* This allows us to use it even after the container gets destroyed
* due to a resolver timeout.
*/
struct thread_sync_data tsd = { 0,0,0,NULL };
if (!init_thread_sync_data(td, conn->async.hostname, &tsd)) {
/* thread synchronization data initialization failed */
return (unsigned)-1;
}
WSASetLastError (conn->async.status = NO_DATA); /* pending status */
/* Signaling that we have initialized all copies of data and handles we
need */
SetEvent(td->event_thread_started);
he = gethostbyname (tsd.hostname);
/* is parent thread waiting for us and are we able to access conn members? */
if (acquire_thread_sync(&tsd)) {
/* Mark that we have obtained the information, and that we are calling
* back with it. */
SetEvent(td->event_resolved);
if (he) {
rc = Curl_addrinfo4_callback(conn, CURL_ASYNC_SUCCESS, he);
}
else {
rc = Curl_addrinfo4_callback(conn, (int)WSAGetLastError(), NULL);
}
TRACE(("Winsock-error %d, addr %s\n", conn->async.status,
he ? inet_ntoa(*(struct in_addr*)he->h_addr) : "unknown"));
release_thread_sync(&tsd);
}
/* clean up */
destroy_thread_sync_data(&tsd);
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;
struct addrinfo hints = td->hints;
/* Duplicate the passed mutex handle.
* This allows us to use it even after the container gets destroyed
* due to a resolver timeout.
*/
struct thread_sync_data tsd = { 0,0,0,NULL };
if (!init_thread_sync_data(td, conn->async.hostname, &tsd)) {
/* thread synchronization data initialization failed */
return -1;
}
itoa(conn->async.port, service, 10);
WSASetLastError(conn->async.status = NO_DATA); /* pending status */
/* Signaling that we have initialized all copies of data and handles we
need */
SetEvent(td->event_thread_started);
rc = getaddrinfo(tsd.hostname, service, &hints, &res);
/* is parent thread waiting for us and are we able to access conn members? */
if (acquire_thread_sync(&tsd)) {
/* Mark that we have obtained the information, and that we are calling
back with it. */
SetEvent(td->event_resolved);
if (rc == 0) {
#ifdef DEBUG_THREADING_GETADDRINFO
dump_addrinfo (conn, res);
#endif
rc = Curl_addrinfo6_callback(conn, CURL_ASYNC_SUCCESS, res);
}
else {
rc = Curl_addrinfo6_callback(conn, (int)WSAGetLastError(), NULL);
TRACE(("Winsock-error %d, no address\n", conn->async.status));
}
release_thread_sync(&tsd);
}
/* clean up */
destroy_thread_sync_data(&tsd);
return (rc);
/* An implicit _endthreadex() here */
}
#endif
/*
* Curl_destroy_thread_data() cleans up async resolver data and thread handle.
* Complementary of ares_destroy.
*/
void Curl_destroy_thread_data (struct Curl_async *async)
{
if (async->hostname)
free(async->hostname);
if (async->os_specific) {
struct thread_data *td = (struct thread_data*) async->os_specific;
curl_socket_t sock = td->dummy_sock;
if (td->mutex_terminate && td->event_terminate) {
/* Signaling resolver thread to terminate */
if (WaitForSingleObject(td->mutex_terminate, INFINITE) == WAIT_OBJECT_0) {
SetEvent(td->event_terminate);
ReleaseMutex(td->mutex_terminate);
}
else {
/* Something went wrong - just ignoring it */
}
}
if (td->mutex_terminate)
CloseHandle(td->mutex_terminate);
if (td->event_terminate)
CloseHandle(td->event_terminate);
if (td->event_thread_started)
CloseHandle(td->event_thread_started);
if (sock != CURL_SOCKET_BAD)
sclose(sock);
/* destroy the synchronization objects */
if (td->mutex_waiting)
CloseHandle(td->mutex_waiting);
td->mutex_waiting = NULL;
if (td->event_resolved)
CloseHandle(td->event_resolved);
if (td->thread_hnd)
CloseHandle(td->thread_hnd);
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);
HANDLE thread_and_event[2] = {0};
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;
/* Create the mutex used to inform the resolver thread that we're
* still waiting, and take initial ownership.
*/
td->mutex_waiting = CreateMutex(NULL, TRUE, NULL);
if (td->mutex_waiting == NULL) {
Curl_destroy_thread_data(&conn->async);
SetLastError(EAGAIN);
return FALSE;
}
/* Create the event that the thread uses to inform us that it's
* done resolving. Do not signal it.
*/
td->event_resolved = CreateEvent(NULL, TRUE, FALSE, NULL);
if (td->event_resolved == NULL) {
Curl_destroy_thread_data(&conn->async);
SetLastError(EAGAIN);
return FALSE;
}
/* Create the mutex used to serialize access to event_terminated
* between us and resolver thread.
*/
td->mutex_terminate = CreateMutex(NULL, FALSE, NULL);
if (td->mutex_terminate == NULL) {
Curl_destroy_thread_data(&conn->async);
SetLastError(EAGAIN);
return FALSE;
}
/* Create the event used to signal thread that it should terminate.
*/
td->event_terminate = CreateEvent(NULL, TRUE, FALSE, NULL);
if (td->event_terminate == NULL) {
Curl_destroy_thread_data(&conn->async);
SetLastError(EAGAIN);
return FALSE;
}
/* Create the event used by thread to inform it has initialized its own data.
*/
td->event_thread_started = CreateEvent(NULL, TRUE, FALSE, NULL);
if (td->event_thread_started == NULL) {
Curl_destroy_thread_data(&conn->async);
SetLastError(EAGAIN);
return FALSE;
}
#ifdef _WIN32_WCE
td->thread_hnd = (HANDLE) CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE) THREAD_FUNC,
conn, 0, &td->thread_id);
#else
td->thread_hnd = (HANDLE) _beginthreadex(NULL, 0, THREAD_FUNC,
conn, 0, &td->thread_id);
#endif
#ifdef CURLRES_IPV6
curlassert(hints);
td->hints = *hints;
#else
(void) hints;
#endif
if (!td->thread_hnd) {
#ifdef _WIN32_WCE
TRACE(("CreateThread() failed; %s\n", Curl_strerror(conn,GetLastError())));
#else
SetLastError(errno);
TRACE(("_beginthreadex() failed; %s\n", Curl_strerror(conn,errno)));
#endif
Curl_destroy_thread_data(&conn->async);
return FALSE;
}
/* Waiting until the thread will initialize its data or it will exit due errors.
*/
thread_and_event[0] = td->thread_hnd;
thread_and_event[1] = td->event_thread_started;
if (WaitForMultipleObjects(sizeof(thread_and_event) /
sizeof(thread_and_event[0]),
(const HANDLE*)thread_and_event, FALSE,
INFINITE) == WAIT_FAILED) {
/* The resolver thread has been created,
* most probably it works now - ignoring this "minor" error
*/
}
/* This socket is only to keep Curl_resolv_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();
/* wait for the thread to resolve the name */
status = WaitForSingleObject(td->event_resolved, 1000UL*timeout);
/* mark that we are now done waiting */
ReleaseMutex(td->mutex_waiting);
/* close our handle to the mutex, no point in hanging on to it */
CloseHandle(td->mutex_waiting);
td->mutex_waiting = NULL;
/* close the event handle, it's useless now */
CloseHandle(td->event_resolved);
td->event_resolved = NULL;
/* has the resolver thread succeeded in resolving our query ? */
if (status == WAIT_OBJECT_0) {
/* wait for the thread to exit, it's in the callback sequence */
if (WaitForSingleObject(td->thread_hnd, 5000) == WAIT_TIMEOUT) {
TerminateThread(td->thread_hnd, 0);
conn->async.done = TRUE;
td->thread_status = (DWORD)-1;
TRACE(("%s() thread stuck?!, ", THREAD_NAME));
}
else {
/* 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));
if(entry)
*entry = conn->async.dns;
rc = CURLE_OK;
if (!conn->async.dns) {
/* a name was not resolved */
if (td->thread_status == CURLE_OUT_OF_MEMORY) {
rc = CURLE_OUT_OF_MEMORY;
failf(data, "Could not resolve host: %s", curl_easy_strerror(rc));
}
else if(conn->async.done) {
if(conn->bits.httpproxy) {
failf(data, "Could not resolve proxy: %s; %s",
conn->proxy.dispname, Curl_strerror(conn, conn->async.status));
rc = CURLE_COULDNT_RESOLVE_PROXY;
}
else {
failf(data, "Could not resolve host: %s; %s",
conn->host.name, Curl_strerror(conn, conn->async.status));
rc = CURLE_COULDNT_RESOLVE_HOST;
}
}
else 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
rc = CURLE_OPERATION_TIMEDOUT;
}
Curl_destroy_thread_data(&conn->async);
if(!conn->async.dns)
conn->bits.close = TRUE;
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 */
Curl_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));
}
return CURLE_OK;
}
int Curl_resolv_getsock(struct connectdata *conn,
curl_socket_t *socks,
int numsocks)
{
const struct thread_data *td =
(const struct thread_data *) conn->async.os_specific;
if (td && td->dummy_sock != CURL_SOCKET_BAD) {
if(numsocks) {
/* return one socket waiting for writable, even though this is just
a dummy */
socks[0] = td->dummy_sock;
return GETSOCK_WRITESOCK(0);
}
}
return 0;
}
#ifdef CURLRES_IPV4
/*
* Curl_getaddrinfo() - for Windows threading without ENABLE_IPV6.
*/
Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
const char *hostname,
int port,
int *waitp)
{
struct hostent *h = NULL;
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; %s\n",
hostname, Curl_strerror(conn,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,
const 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 = conn->socktype;
#if 0 /* removed nov 8 2005 before 7.15.1 */
hints.ai_flags = AI_CANONNAME;
#endif
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; %s\n",
hostname, Curl_strerror(conn,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 */

File diff suppressed because it is too large Load Diff

View File

@ -1,85 +0,0 @@
#ifndef __HTTP_H
#define __HTTP_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute 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_proxyCONNECT(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, bool *done);
CURLcode Curl_http_done(struct connectdata *, CURLcode, bool premature);
CURLcode Curl_http_connect(struct connectdata *conn, bool *done);
CURLcode Curl_https_connecting(struct connectdata *conn, bool *done);
int Curl_https_getsock(struct connectdata *conn,
curl_socket_t *socks,
int numsocks);
/* 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 */
/* MAX_INITIAL_POST_SIZE indicates the number of bytes that will make the POST
data get included in the initial data chunk sent to the server. If the
data is larger than this, it will automatically get split up in multiple
system calls.
This value used to be fairly big (100K), but we must take into account that
if the server rejects the POST due for authentication reasons, this data
will always be uncondtionally sent and thus it may not be larger than can
always be afforded to send twice.
It must not be greater than 64K to work on VMS.
*/
#ifndef MAX_INITIAL_POST_SIZE
#define MAX_INITIAL_POST_SIZE (64*1024)
#endif
#ifndef TINY_INITIAL_POST_SIZE
#define TINY_INITIAL_POST_SIZE 1024
#endif
#endif
#endif

View File

@ -1,327 +0,0 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute 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 "urldata.h"
#include "sendf.h"
#include "strequal.h"
#include "base64.h"
#include "http_negotiate.h"
#include "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, "%s", 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(*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(*header))
header++;
len = strlen(header);
if (len > 0) {
int rawlen = Curl_base64_decode(header, (unsigned char **)&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 succeeded\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 succeeded\n");
}
}
#endif
len = Curl_base64_encode(conn->data,
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

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -1,134 +0,0 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute 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
#include "if2ip.h"
/*
* This test can probably be simplified to #if defined(SIOCGIFADDR) and
* moved after the following includes.
*/
#if !defined(WIN32) && !defined(__BEOS__) && !defined(__CYGWIN__) && \
!defined(__riscos__) && !defined(__INTERIX) && !defined(NETWARE) && \
!defined(_AMIGASF) && !defined(__minix)
#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
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif
#ifdef HAVE_SYS_SOCKIO_H
#include <sys/sockio.h>
#endif
#ifdef VMS
#include <inet.h>
#endif
#include "inet_ntop.h"
#include "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;
struct sockaddr_in *s = (struct sockaddr_in *)&req.ifr_dstaddr;
memcpy(&in, &s->sin_addr, sizeof(in));
ip = (char *) Curl_inet_ntop(s->sin_family, &in, buf, buf_size);
}
sclose(dummy);
}
return ip;
}
/* -- end of if2ip() -- */
#else
char *Curl_if2ip(const char *interf, char *buf, int buf_size)
{
(void) interf;
(void) buf;
(void) buf_size;
return NULL;
}
#endif

View File

@ -0,0 +1,218 @@
#ifndef __CURL_CURLBUILD_H
#define __CURL_CURLBUILD_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute 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.
*
***************************************************************************/
/* ================================================================ */
/* NOTES FOR CONFIGURE CAPABLE SYSTEMS */
/* ================================================================ */
/*
* NOTE 1:
* -------
*
* Nothing in this file is intended to be modified or adjusted by the
* curl library user nor by the curl library builder.
*
* If you think that something actually needs to be changed, adjusted
* or fixed in this file, then, report it on the libcurl development
* mailing list: http://cool.haxx.se/mailman/listinfo/curl-library/
*
* This header file shall only export symbols which are 'curl' or 'CURL'
* prefixed, otherwise public name space would be polluted.
*
* NOTE 2:
* -------
*
* Right now you might be staring at file include/curl/curlbuild.h.in or
* at file include/curl/curlbuild.h, this is due to the following reason:
*
* On systems capable of running the configure script, the configure process
* will overwrite the distributed include/curl/curlbuild.h file with one that
* is suitable and specific to the library being configured and built, which
* is generated from the include/curl/curlbuild.h.in template file.
*
*/
/* ================================================================ */
/* DEFINITION OF THESE SYMBOLS SHALL NOT TAKE PLACE ANYWHERE ELSE */
/* ================================================================ */
#ifdef CURL_SIZEOF_LONG
#error "CURL_SIZEOF_LONG shall not be defined except in curlbuild.h"
Error Compilation_aborted_CURL_SIZEOF_LONG_already_defined
#endif
#ifdef CURL_TYPEOF_CURL_SOCKLEN_T
#error "CURL_TYPEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h"
Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_already_defined
#endif
#ifdef CURL_SIZEOF_CURL_SOCKLEN_T
#error "CURL_SIZEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h"
Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_already_defined
#endif
#ifdef CURL_TYPEOF_CURL_OFF_T
#error "CURL_TYPEOF_CURL_OFF_T shall not be defined except in curlbuild.h"
Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_already_defined
#endif
#ifdef CURL_FORMAT_CURL_OFF_T
#error "CURL_FORMAT_CURL_OFF_T shall not be defined except in curlbuild.h"
Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_already_defined
#endif
#ifdef CURL_FORMAT_CURL_OFF_TU
#error "CURL_FORMAT_CURL_OFF_TU shall not be defined except in curlbuild.h"
Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_already_defined
#endif
#ifdef CURL_FORMAT_OFF_T
#error "CURL_FORMAT_OFF_T shall not be defined except in curlbuild.h"
Error Compilation_aborted_CURL_FORMAT_OFF_T_already_defined
#endif
#ifdef CURL_SIZEOF_CURL_OFF_T
#error "CURL_SIZEOF_CURL_OFF_T shall not be defined except in curlbuild.h"
Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_already_defined
#endif
#ifdef CURL_SUFFIX_CURL_OFF_T
#error "CURL_SUFFIX_CURL_OFF_T shall not be defined except in curlbuild.h"
Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_already_defined
#endif
#ifdef CURL_SUFFIX_CURL_OFF_TU
#error "CURL_SUFFIX_CURL_OFF_TU shall not be defined except in curlbuild.h"
Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_already_defined
#endif
/* ================================================================ */
/* EXTERNAL INTERFACE SETTINGS FOR CONFIGURE CAPABLE SYSTEMS ONLY */
/* ================================================================ */
/* Configure process defines this to 1 when it finds out that system */
/* header file ws2tcpip.h must be included by the external interface. */
#cmakedefine CURL_PULL_WS2TCPIP_H
#ifdef CURL_PULL_WS2TCPIP_H
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif
# include <windows.h>
# include <winsock2.h>
# include <ws2tcpip.h>
#endif
/* Configure process defines this to 1 when it finds out that system */
/* header file sys/types.h must be included by the external interface. */
#cmakedefine CURL_PULL_SYS_TYPES_H
#ifdef CURL_PULL_SYS_TYPES_H
# include <sys/types.h>
#endif
/* Configure process defines this to 1 when it finds out that system */
/* header file stdint.h must be included by the external interface. */
#cmakedefine CURL_PULL_STDINT_H
#ifdef CURL_PULL_STDINT_H
# include <stdint.h>
#endif
/* Configure process defines this to 1 when it finds out that system */
/* header file inttypes.h must be included by the external interface. */
#cmakedefine CURL_PULL_INTTYPES_H
#ifdef CURL_PULL_INTTYPES_H
# include <inttypes.h>
#endif
/* Configure process defines this to 1 when it finds out that system */
/* header file sys/socket.h must be included by the external interface. */
#cmakedefine CURL_PULL_SYS_SOCKET_H
#ifdef CURL_PULL_SYS_SOCKET_H
# include <sys/socket.h>
#endif
/* Configure process defines this to 1 when it finds out that system */
/* header file sys/poll.h must be included by the external interface. */
#cmakedefine CURL_PULL_SYS_POLL_H
#ifdef CURL_PULL_SYS_POLL_H
# include <sys/poll.h>
#endif
/* The size of `int', as computed by sizeof. */
@CURL_SIZEOF_INT_CODE@
/* The size of `long', as computed by sizeof. */
@CURL_SIZEOF_LONG_CODE@
/* The size of `long long', as computed by sizeof. */
@CURL_SIZEOF_LONG_LONG_CODE@
/* The size of `ssize_t', as computed by sizeof. */
@CURL_SIZEOF_SSIZE_T_CODE@
#define CURL_HAVE_SOCKLEN_T @CURL_HAVE_SOCKLEN_T@
#if CURL_HAVE_SOCKLEN_T
/* Integral data type used for curl_socklen_t. */
#define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
/* The size of `curl_socklen_t', as computed by sizeof. */
@CURL_SIZEOF_CURL_SOCKLEN_T_CODE@
#else
# define CURL_TYPEOF_CURL_SOCKLEN_T int
# define CURL_SIZEOF_CURL_SOCKLEN_T CURL_SIZEOF_INT
#endif
/* Data type definition of curl_socklen_t. */
typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t;
#if CURL_SIZEOF_LONG == 8
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_SIZEOF_CURL_OFF_T 8
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_FORMAT_OFF_T "%ld"
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
#elif CURL_SIZEOF_LONG_LONG == 8
# define CURL_TYPEOF_CURL_OFF_T long long
# define CURL_SIZEOF_CURL_OFF_T 8
# define CURL_FORMAT_CURL_OFF_T "lld"
# define CURL_FORMAT_CURL_OFF_TU "llu"
# define CURL_FORMAT_OFF_T "%lld"
# define CURL_SUFFIX_CURL_OFF_T LL
# define CURL_SUFFIX_CURL_OFF_TU ULL
#else
# define CURL_TYPEOF_CURL_OFF_T ssize_t
# define CURL_SIZEOF_CURL_OFF_T CURL_SIZEOF_SSIZE_T
/* TODO: need adjustment here. */
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_FORMAT_OFF_T "%ld"
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
#endif
/* Data type definition of curl_off_t. */
typedef CURL_TYPEOF_CURL_OFF_T curl_off_t;
#endif /* __CURL_CURLBUILD_H */

View File

@ -0,0 +1,262 @@
#ifndef __CURL_CURLRULES_H
#define __CURL_CURLRULES_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute 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.
*
***************************************************************************/
/* ================================================================ */
/* COMPILE TIME SANITY CHECKS */
/* ================================================================ */
/*
* NOTE 1:
* -------
*
* All checks done in this file are intentionally placed in a public
* header file which is pulled by curl/curl.h when an application is
* being built using an already built libcurl library. Additionally
* this file is also included and used when building the library.
*
* If compilation fails on this file it is certainly sure that the
* problem is elsewhere. It could be a problem in the curlbuild.h
* header file, or simply that you are using different compilation
* settings than those used to build the library.
*
* Nothing in this file is intended to be modified or adjusted by the
* curl library user nor by the curl library builder.
*
* Do not deactivate any check, these are done to make sure that the
* library is properly built and used.
*
* You can find further help on the libcurl development mailing list:
* http://cool.haxx.se/mailman/listinfo/curl-library/
*
* NOTE 2
* ------
*
* Some of the following compile time checks are based on the fact
* that the dimension of a constant array can not be a negative one.
* In this way if the compile time verification fails, the compilation
* will fail issuing an error. The error description wording is compiler
* dependent but it will be quite similar to one of the following:
*
* "negative subscript or subscript is too large"
* "array must have at least one element"
* "-1 is an illegal array size"
* "size of array is negative"
*
* If you are building an application which tries to use an already
* built libcurl library and you are getting this kind of errors on
* this file, it is a clear indication that there is a mismatch between
* how the library was built and how you are trying to use it for your
* application. Your already compiled or binary library provider is the
* only one who can give you the details you need to properly use it.
*/
/*
* Verify that some macros are actually defined.
*/
#ifndef CURL_SIZEOF_LONG
# error "CURL_SIZEOF_LONG definition is missing!"
Error Compilation_aborted_CURL_SIZEOF_LONG_is_missing
#endif
#ifndef CURL_TYPEOF_CURL_SOCKLEN_T
# error "CURL_TYPEOF_CURL_SOCKLEN_T definition is missing!"
Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_is_missing
#endif
#ifndef CURL_SIZEOF_CURL_SOCKLEN_T
# error "CURL_SIZEOF_CURL_SOCKLEN_T definition is missing!"
Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_is_missing
#endif
#ifndef CURL_TYPEOF_CURL_OFF_T
# error "CURL_TYPEOF_CURL_OFF_T definition is missing!"
Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_is_missing
#endif
#ifndef CURL_FORMAT_CURL_OFF_T
# error "CURL_FORMAT_CURL_OFF_T definition is missing!"
Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_is_missing
#endif
#ifndef CURL_FORMAT_CURL_OFF_TU
# error "CURL_FORMAT_CURL_OFF_TU definition is missing!"
Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_is_missing
#endif
#ifndef CURL_FORMAT_OFF_T
# error "CURL_FORMAT_OFF_T definition is missing!"
Error Compilation_aborted_CURL_FORMAT_OFF_T_is_missing
#endif
#ifndef CURL_SIZEOF_CURL_OFF_T
# error "CURL_SIZEOF_CURL_OFF_T definition is missing!"
Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_is_missing
#endif
#ifndef CURL_SUFFIX_CURL_OFF_T
# error "CURL_SUFFIX_CURL_OFF_T definition is missing!"
Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_is_missing
#endif
#ifndef CURL_SUFFIX_CURL_OFF_TU
# error "CURL_SUFFIX_CURL_OFF_TU definition is missing!"
Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_is_missing
#endif
/*
* Macros private to this header file.
*/
#define CurlchkszEQ(t, s) sizeof(t) == s ? 1 : -1
#define CurlchkszGE(t1, t2) sizeof(t1) >= sizeof(t2) ? 1 : -1
/*
* Verify that the size previously defined and expected for long
* is the same as the one reported by sizeof() at compile time.
*/
typedef char
__curl_rule_01__
[CurlchkszEQ(long, CURL_SIZEOF_LONG)];
/*
* Verify that the size previously defined and expected for
* curl_off_t is actually the the same as the one reported
* by sizeof() at compile time.
*/
typedef char
__curl_rule_02__
[CurlchkszEQ(curl_off_t, CURL_SIZEOF_CURL_OFF_T)];
/*
* Verify at compile time that the size of curl_off_t as reported
* by sizeof() is greater or equal than the one reported for long
* for the current compilation.
*/
typedef char
__curl_rule_03__
[CurlchkszGE(curl_off_t, long)];
/*
* Verify that the size previously defined and expected for
* curl_socklen_t is actually the the same as the one reported
* by sizeof() at compile time.
*/
typedef char
__curl_rule_04__
[CurlchkszEQ(curl_socklen_t, CURL_SIZEOF_CURL_SOCKLEN_T)];
/*
* Verify at compile time that the size of curl_socklen_t as reported
* by sizeof() is greater or equal than the one reported for int for
* the current compilation.
*/
typedef char
__curl_rule_05__
[CurlchkszGE(curl_socklen_t, int)];
/* ================================================================ */
/* EXTERNALLY AND INTERNALLY VISIBLE DEFINITIONS */
/* ================================================================ */
/*
* CURL_ISOCPP and CURL_OFF_T_C definitions are done here in order to allow
* these to be visible and exported by the external libcurl interface API,
* while also making them visible to the library internals, simply including
* curl_setup.h, without actually needing to include curl.h internally.
* If some day this section would grow big enough, all this should be moved
* to its own header file.
*/
/*
* Figure out if we can use the ## preprocessor 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.
*/
#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) || \
defined(__HP_aCC) || defined(__BORLANDC__) || defined(__LCC__) || \
defined(__POCC__) || defined(__SALFORDC__) || defined(__HIGHC__) || \
defined(__ILEC400__)
/* 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
/*
* Macros for minimum-width signed and unsigned curl_off_t integer constants.
*/
#if defined(__BORLANDC__) && (__BORLANDC__ == 0x0551)
# define __CURL_OFF_T_C_HLPR2(x) x
# define __CURL_OFF_T_C_HLPR1(x) __CURL_OFF_T_C_HLPR2(x)
# define CURL_OFF_T_C(Val) __CURL_OFF_T_C_HLPR1(Val) ## \
__CURL_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_T)
# define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HLPR1(Val) ## \
__CURL_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_TU)
#else
# ifdef CURL_ISOCPP
# define __CURL_OFF_T_C_HLPR2(Val,Suffix) Val ## Suffix
# else
# define __CURL_OFF_T_C_HLPR2(Val,Suffix) Val/**/Suffix
# endif
# define __CURL_OFF_T_C_HLPR1(Val,Suffix) __CURL_OFF_T_C_HLPR2(Val,Suffix)
# define CURL_OFF_T_C(Val) __CURL_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_T)
# define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_TU)
#endif
/*
* Get rid of macros private to this header file.
*/
#undef CurlchkszEQ
#undef CurlchkszGE
/*
* Get rid of macros not intended to exist beyond this point.
*/
#undef CURL_PULL_WS2TCPIP_H
#undef CURL_PULL_SYS_TYPES_H
#undef CURL_PULL_SYS_SOCKET_H
#undef CURL_PULL_SYS_POLL_H
#undef CURL_PULL_STDINT_H
#undef CURL_PULL_INTTYPES_H
#undef CURL_TYPEOF_CURL_SOCKLEN_T
#undef CURL_TYPEOF_CURL_OFF_T
#ifdef CURL_NO_OLDIES
#undef CURL_FORMAT_OFF_T /* not required since 7.19.0 - obsoleted in 7.20.0 */
#endif
#endif /* __CURL_CURLRULES_H */

View File

@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@ -20,21 +20,23 @@
* 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 global package copyright */
#define LIBCURL_COPYRIGHT "1996 - 2014 Daniel Stenberg, <daniel@haxx.se>."
/* This is the version number of the libcurl package from which this header
file origins: */
#define LIBCURL_VERSION "7.16.1"
#define LIBCURL_VERSION "7.38.0"
/* The numeric version number is also available "in parts" by using these
defines: */
#define LIBCURL_VERSION_MAJOR 7
#define LIBCURL_VERSION_MINOR 16
#define LIBCURL_VERSION_PATCH 1
#define LIBCURL_VERSION_MINOR 38
#define LIBCURL_VERSION_PATCH 0
/* This is the numeric version of the libcurl version number, meant for easier
parsing and comparions by programs. The LIBCURL_VERSION_NUM define will
@ -51,6 +53,17 @@
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 0x071001
#define LIBCURL_VERSION_NUM 0x072600
/*
* This is the date and time when the full source package was created. The
* timestamp is not stored in git, as the timestamp is properly set in the
* tarballs by the maketgz script.
*
* The format of the date should follow this template:
*
* "Mon Feb 12 11:35:33 UTC 2007"
*/
#define LIBCURL_TIMESTAMP "DEV"
#endif /* __CURL_CURLVER_H */

View File

@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@ -20,7 +20,6 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* $Id$
***************************************************************************/
#ifdef __cplusplus
extern "C" {
@ -54,8 +53,8 @@ CURL_EXTERN CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...);
*
* 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
* options, internal state info and things like persistent connections cannot
* be transferred. 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.
*/
@ -74,6 +73,28 @@ CURL_EXTERN CURL* curl_easy_duphandle(CURL *curl);
*/
CURL_EXTERN void curl_easy_reset(CURL *curl);
/*
* NAME curl_easy_recv()
*
* DESCRIPTION
*
* Receives data from the connected socket. Use after successful
* curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
*/
CURL_EXTERN CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen,
size_t *n);
/*
* NAME curl_easy_send()
*
* DESCRIPTION
*
* Sends data over the connected socket. Use after successful
* curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
*/
CURL_EXTERN CURLcode curl_easy_send(CURL *curl, const void *buffer,
size_t buflen, size_t *n);
#ifdef __cplusplus
}
#endif

View File

@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@ -20,7 +20,6 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* $Id$
***************************************************************************/
#include <stdarg.h>
@ -35,11 +34,13 @@ extern "C" {
CURL_EXTERN int curl_mprintf(const char *format, ...);
CURL_EXTERN int curl_mfprintf(FILE *fd, const char *format, ...);
CURL_EXTERN int curl_msprintf(char *buffer, const char *format, ...);
CURL_EXTERN int curl_msnprintf(char *buffer, size_t maxlength, const char *format, ...);
CURL_EXTERN int curl_msnprintf(char *buffer, size_t maxlength,
const char *format, ...);
CURL_EXTERN int curl_mvprintf(const char *format, va_list args);
CURL_EXTERN int curl_mvfprintf(FILE *fd, const char *format, va_list args);
CURL_EXTERN int curl_mvsprintf(char *buffer, const char *format, va_list args);
CURL_EXTERN int curl_mvsnprintf(char *buffer, size_t maxlength, const char *format, va_list args);
CURL_EXTERN int curl_mvsnprintf(char *buffer, size_t maxlength,
const char *format, va_list args);
CURL_EXTERN char *curl_maprintf(const char *format, ...);
CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args);
@ -57,7 +58,7 @@ CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args);
# define printf curl_mprintf
# define fprintf curl_mfprintf
#ifdef CURLDEBUG
/* When built with CURLDEBUG we define away the sprintf() functions since we
/* When built with CURLDEBUG we define away the sprintf functions since we
don't want internal code to be using them */
# define sprintf sprintf_was_used
# define vsprintf vsprintf_was_used

View File

@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@ -20,7 +20,6 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* $Id$
***************************************************************************/
/*
This is an "external" header file. Don't give away any internals here!
@ -65,6 +64,8 @@ typedef enum {
CURLM_INTERNAL_ERROR, /* this is a libcurl bug */
CURLM_BAD_SOCKET, /* the passed in socket argument did not match */
CURLM_UNKNOWN_OPTION, /* curl_multi_setopt() with unsupported option */
CURLM_ADDED_ALREADY, /* an easy handle already added to a multi handle was
attempted to get added - again */
CURLM_LAST
} CURLMcode;
@ -90,6 +91,19 @@ struct CURLMsg {
};
typedef struct CURLMsg CURLMsg;
/* Based on poll(2) structure and values.
* We don't use pollfd and POLL* constants explicitly
* to cover platforms without poll(). */
#define CURL_WAIT_POLLIN 0x0001
#define CURL_WAIT_POLLPRI 0x0002
#define CURL_WAIT_POLLOUT 0x0004
struct curl_waitfd {
curl_socket_t fd;
short events;
short revents; /* not supported yet */
};
/*
* Name: curl_multi_init()
*
@ -134,6 +148,20 @@ CURL_EXTERN CURLMcode curl_multi_fdset(CURLM *multi_handle,
fd_set *exc_fd_set,
int *max_fd);
/*
* Name: curl_multi_wait()
*
* Desc: Poll on all fds within a CURLM set as well as any
* additional fds passed to the function.
*
* Returns: CURLMcode type, general multi error code.
*/
CURL_EXTERN CURLMcode curl_multi_wait(CURLM *multi_handle,
struct curl_waitfd extra_fds[],
unsigned int extra_nfds,
int timeout_ms,
int *ret);
/*
* Name: curl_multi_perform()
*
@ -224,6 +252,10 @@ CURL_EXTERN const char *curl_multi_strerror(CURLMcode);
#define CURL_SOCKET_TIMEOUT CURL_SOCKET_BAD
#define CURL_CSELECT_IN 0x01
#define CURL_CSELECT_OUT 0x02
#define CURL_CSELECT_ERR 0x04
typedef int (*curl_socket_callback)(CURL *easy, /* easy handle */
curl_socket_t s, /* socket */
int what, /* see above */
@ -249,9 +281,21 @@ typedef int (*curl_multi_timer_callback)(CURLM *multi, /* multi handle */
CURL_EXTERN CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s,
int *running_handles);
CURL_EXTERN CURLMcode curl_multi_socket_action(CURLM *multi_handle,
curl_socket_t s,
int ev_bitmask,
int *running_handles);
CURL_EXTERN CURLMcode curl_multi_socket_all(CURLM *multi_handle,
int *running_handles);
#ifndef CURL_ALLOW_OLD_MULTI_SOCKET
/* This macro below was added in 7.16.3 to push users who recompile to use
the new curl_multi_socket_action() instead of the old curl_multi_socket()
*/
#define curl_multi_socket(x,y,z) curl_multi_socket_action(x,y,0,z)
#endif
/*
* Name: curl_multi_timeout()
*
@ -267,7 +311,7 @@ CURL_EXTERN CURLMcode curl_multi_timeout(CURLM *multi_handle,
#undef CINIT /* re-using the same name as in curl.h */
#ifdef CURL_ISOCPP
#define CINIT(name,type,number) CURLMOPT_ ## name = CURLOPTTYPE_ ## type + number
#define CINIT(name,type,num) CURLMOPT_ ## name = CURLOPTTYPE_ ## type + num
#else
/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */
#define LONG CURLOPTTYPE_LONG
@ -293,6 +337,34 @@ typedef enum {
/* This is the argument passed to the timer callback */
CINIT(TIMERDATA, OBJECTPOINT, 5),
/* maximum number of entries in the connection cache */
CINIT(MAXCONNECTS, LONG, 6),
/* maximum number of (pipelining) connections to one host */
CINIT(MAX_HOST_CONNECTIONS, LONG, 7),
/* maximum number of requests in a pipeline */
CINIT(MAX_PIPELINE_LENGTH, LONG, 8),
/* a connection with a content-length longer than this
will not be considered for pipelining */
CINIT(CONTENT_LENGTH_PENALTY_SIZE, OFF_T, 9),
/* a connection with a chunk length longer than this
will not be considered for pipelining */
CINIT(CHUNK_LENGTH_PENALTY_SIZE, OFF_T, 10),
/* a list of site names(+port) that are blacklisted from
pipelining */
CINIT(PIPELINING_SITE_BL, OBJECTPOINT, 11),
/* a list of server types that are blacklisted from
pipelining */
CINIT(PIPELINING_SERVER_BL, OBJECTPOINT, 12),
/* maximum number of open connections in total */
CINIT(MAX_TOTAL_CONNECTIONS, LONG, 13),
CURLMOPT_LASTENTRY /* the last unused */
} CURLMoption;

View File

@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@ -20,7 +20,6 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* $Id$
***************************************************************************/
#include <sys/types.h>
@ -31,4 +30,4 @@ 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
#endif /* __STDC_HEADERS_H */

View File

@ -0,0 +1,610 @@
#ifndef __CURL_TYPECHECK_GCC_H
#define __CURL_TYPECHECK_GCC_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute 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.
*
***************************************************************************/
/* wraps curl_easy_setopt() with typechecking */
/* To add a new kind of warning, add an
* if(_curl_is_sometype_option(_curl_opt))
* if(!_curl_is_sometype(value))
* _curl_easy_setopt_err_sometype();
* block and define _curl_is_sometype_option, _curl_is_sometype and
* _curl_easy_setopt_err_sometype below
*
* NOTE: We use two nested 'if' statements here instead of the && operator, in
* order to work around gcc bug #32061. It affects only gcc 4.3.x/4.4.x
* when compiling with -Wlogical-op.
*
* To add an option that uses the same type as an existing option, you'll just
* need to extend the appropriate _curl_*_option macro
*/
#define curl_easy_setopt(handle, option, value) \
__extension__ ({ \
__typeof__ (option) _curl_opt = option; \
if(__builtin_constant_p(_curl_opt)) { \
if(_curl_is_long_option(_curl_opt)) \
if(!_curl_is_long(value)) \
_curl_easy_setopt_err_long(); \
if(_curl_is_off_t_option(_curl_opt)) \
if(!_curl_is_off_t(value)) \
_curl_easy_setopt_err_curl_off_t(); \
if(_curl_is_string_option(_curl_opt)) \
if(!_curl_is_string(value)) \
_curl_easy_setopt_err_string(); \
if(_curl_is_write_cb_option(_curl_opt)) \
if(!_curl_is_write_cb(value)) \
_curl_easy_setopt_err_write_callback(); \
if((_curl_opt) == CURLOPT_READFUNCTION) \
if(!_curl_is_read_cb(value)) \
_curl_easy_setopt_err_read_cb(); \
if((_curl_opt) == CURLOPT_IOCTLFUNCTION) \
if(!_curl_is_ioctl_cb(value)) \
_curl_easy_setopt_err_ioctl_cb(); \
if((_curl_opt) == CURLOPT_SOCKOPTFUNCTION) \
if(!_curl_is_sockopt_cb(value)) \
_curl_easy_setopt_err_sockopt_cb(); \
if((_curl_opt) == CURLOPT_OPENSOCKETFUNCTION) \
if(!_curl_is_opensocket_cb(value)) \
_curl_easy_setopt_err_opensocket_cb(); \
if((_curl_opt) == CURLOPT_PROGRESSFUNCTION) \
if(!_curl_is_progress_cb(value)) \
_curl_easy_setopt_err_progress_cb(); \
if((_curl_opt) == CURLOPT_DEBUGFUNCTION) \
if(!_curl_is_debug_cb(value)) \
_curl_easy_setopt_err_debug_cb(); \
if((_curl_opt) == CURLOPT_SSL_CTX_FUNCTION) \
if(!_curl_is_ssl_ctx_cb(value)) \
_curl_easy_setopt_err_ssl_ctx_cb(); \
if(_curl_is_conv_cb_option(_curl_opt)) \
if(!_curl_is_conv_cb(value)) \
_curl_easy_setopt_err_conv_cb(); \
if((_curl_opt) == CURLOPT_SEEKFUNCTION) \
if(!_curl_is_seek_cb(value)) \
_curl_easy_setopt_err_seek_cb(); \
if(_curl_is_cb_data_option(_curl_opt)) \
if(!_curl_is_cb_data(value)) \
_curl_easy_setopt_err_cb_data(); \
if((_curl_opt) == CURLOPT_ERRORBUFFER) \
if(!_curl_is_error_buffer(value)) \
_curl_easy_setopt_err_error_buffer(); \
if((_curl_opt) == CURLOPT_STDERR) \
if(!_curl_is_FILE(value)) \
_curl_easy_setopt_err_FILE(); \
if(_curl_is_postfields_option(_curl_opt)) \
if(!_curl_is_postfields(value)) \
_curl_easy_setopt_err_postfields(); \
if((_curl_opt) == CURLOPT_HTTPPOST) \
if(!_curl_is_arr((value), struct curl_httppost)) \
_curl_easy_setopt_err_curl_httpost(); \
if(_curl_is_slist_option(_curl_opt)) \
if(!_curl_is_arr((value), struct curl_slist)) \
_curl_easy_setopt_err_curl_slist(); \
if((_curl_opt) == CURLOPT_SHARE) \
if(!_curl_is_ptr((value), CURLSH)) \
_curl_easy_setopt_err_CURLSH(); \
} \
curl_easy_setopt(handle, _curl_opt, value); \
})
/* wraps curl_easy_getinfo() with typechecking */
/* FIXME: don't allow const pointers */
#define curl_easy_getinfo(handle, info, arg) \
__extension__ ({ \
__typeof__ (info) _curl_info = info; \
if(__builtin_constant_p(_curl_info)) { \
if(_curl_is_string_info(_curl_info)) \
if(!_curl_is_arr((arg), char *)) \
_curl_easy_getinfo_err_string(); \
if(_curl_is_long_info(_curl_info)) \
if(!_curl_is_arr((arg), long)) \
_curl_easy_getinfo_err_long(); \
if(_curl_is_double_info(_curl_info)) \
if(!_curl_is_arr((arg), double)) \
_curl_easy_getinfo_err_double(); \
if(_curl_is_slist_info(_curl_info)) \
if(!_curl_is_arr((arg), struct curl_slist *)) \
_curl_easy_getinfo_err_curl_slist(); \
} \
curl_easy_getinfo(handle, _curl_info, arg); \
})
/* TODO: typechecking for curl_share_setopt() and curl_multi_setopt(),
* for now just make sure that the functions are called with three
* arguments
*/
#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param)
#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param)
/* the actual warnings, triggered by calling the _curl_easy_setopt_err*
* functions */
/* To define a new warning, use _CURL_WARNING(identifier, "message") */
#define _CURL_WARNING(id, message) \
static void __attribute__((__warning__(message))) \
__attribute__((__unused__)) __attribute__((__noinline__)) \
id(void) { __asm__(""); }
_CURL_WARNING(_curl_easy_setopt_err_long,
"curl_easy_setopt expects a long argument for this option")
_CURL_WARNING(_curl_easy_setopt_err_curl_off_t,
"curl_easy_setopt expects a curl_off_t argument for this option")
_CURL_WARNING(_curl_easy_setopt_err_string,
"curl_easy_setopt expects a "
"string (char* or char[]) argument for this option"
)
_CURL_WARNING(_curl_easy_setopt_err_write_callback,
"curl_easy_setopt expects a curl_write_callback argument for this option")
_CURL_WARNING(_curl_easy_setopt_err_read_cb,
"curl_easy_setopt expects a curl_read_callback argument for this option")
_CURL_WARNING(_curl_easy_setopt_err_ioctl_cb,
"curl_easy_setopt expects a curl_ioctl_callback argument for this option")
_CURL_WARNING(_curl_easy_setopt_err_sockopt_cb,
"curl_easy_setopt expects a curl_sockopt_callback argument for this option")
_CURL_WARNING(_curl_easy_setopt_err_opensocket_cb,
"curl_easy_setopt expects a "
"curl_opensocket_callback argument for this option"
)
_CURL_WARNING(_curl_easy_setopt_err_progress_cb,
"curl_easy_setopt expects a curl_progress_callback argument for this option")
_CURL_WARNING(_curl_easy_setopt_err_debug_cb,
"curl_easy_setopt expects a curl_debug_callback argument for this option")
_CURL_WARNING(_curl_easy_setopt_err_ssl_ctx_cb,
"curl_easy_setopt expects a curl_ssl_ctx_callback argument for this option")
_CURL_WARNING(_curl_easy_setopt_err_conv_cb,
"curl_easy_setopt expects a curl_conv_callback argument for this option")
_CURL_WARNING(_curl_easy_setopt_err_seek_cb,
"curl_easy_setopt expects a curl_seek_callback argument for this option")
_CURL_WARNING(_curl_easy_setopt_err_cb_data,
"curl_easy_setopt expects a "
"private data pointer as argument for this option")
_CURL_WARNING(_curl_easy_setopt_err_error_buffer,
"curl_easy_setopt expects a "
"char buffer of CURL_ERROR_SIZE as argument for this option")
_CURL_WARNING(_curl_easy_setopt_err_FILE,
"curl_easy_setopt expects a FILE* argument for this option")
_CURL_WARNING(_curl_easy_setopt_err_postfields,
"curl_easy_setopt expects a void* or char* argument for this option")
_CURL_WARNING(_curl_easy_setopt_err_curl_httpost,
"curl_easy_setopt expects a struct curl_httppost* argument for this option")
_CURL_WARNING(_curl_easy_setopt_err_curl_slist,
"curl_easy_setopt expects a struct curl_slist* argument for this option")
_CURL_WARNING(_curl_easy_setopt_err_CURLSH,
"curl_easy_setopt expects a CURLSH* argument for this option")
_CURL_WARNING(_curl_easy_getinfo_err_string,
"curl_easy_getinfo expects a pointer to char * for this info")
_CURL_WARNING(_curl_easy_getinfo_err_long,
"curl_easy_getinfo expects a pointer to long for this info")
_CURL_WARNING(_curl_easy_getinfo_err_double,
"curl_easy_getinfo expects a pointer to double for this info")
_CURL_WARNING(_curl_easy_getinfo_err_curl_slist,
"curl_easy_getinfo expects a pointer to struct curl_slist * for this info")
/* groups of curl_easy_setops options that take the same type of argument */
/* To add a new option to one of the groups, just add
* (option) == CURLOPT_SOMETHING
* to the or-expression. If the option takes a long or curl_off_t, you don't
* have to do anything
*/
/* evaluates to true if option takes a long argument */
#define _curl_is_long_option(option) \
(0 < (option) && (option) < CURLOPTTYPE_OBJECTPOINT)
#define _curl_is_off_t_option(option) \
((option) > CURLOPTTYPE_OFF_T)
/* evaluates to true if option takes a char* argument */
#define _curl_is_string_option(option) \
((option) == CURLOPT_URL || \
(option) == CURLOPT_PROXY || \
(option) == CURLOPT_INTERFACE || \
(option) == CURLOPT_NETRC_FILE || \
(option) == CURLOPT_USERPWD || \
(option) == CURLOPT_USERNAME || \
(option) == CURLOPT_PASSWORD || \
(option) == CURLOPT_PROXYUSERPWD || \
(option) == CURLOPT_PROXYUSERNAME || \
(option) == CURLOPT_PROXYPASSWORD || \
(option) == CURLOPT_NOPROXY || \
(option) == CURLOPT_ACCEPT_ENCODING || \
(option) == CURLOPT_REFERER || \
(option) == CURLOPT_USERAGENT || \
(option) == CURLOPT_COOKIE || \
(option) == CURLOPT_COOKIEFILE || \
(option) == CURLOPT_COOKIEJAR || \
(option) == CURLOPT_COOKIELIST || \
(option) == CURLOPT_FTPPORT || \
(option) == CURLOPT_FTP_ALTERNATIVE_TO_USER || \
(option) == CURLOPT_FTP_ACCOUNT || \
(option) == CURLOPT_RANGE || \
(option) == CURLOPT_CUSTOMREQUEST || \
(option) == CURLOPT_SSLCERT || \
(option) == CURLOPT_SSLCERTTYPE || \
(option) == CURLOPT_SSLKEY || \
(option) == CURLOPT_SSLKEYTYPE || \
(option) == CURLOPT_KEYPASSWD || \
(option) == CURLOPT_SSLENGINE || \
(option) == CURLOPT_CAINFO || \
(option) == CURLOPT_CAPATH || \
(option) == CURLOPT_RANDOM_FILE || \
(option) == CURLOPT_EGDSOCKET || \
(option) == CURLOPT_SSL_CIPHER_LIST || \
(option) == CURLOPT_KRBLEVEL || \
(option) == CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 || \
(option) == CURLOPT_SSH_PUBLIC_KEYFILE || \
(option) == CURLOPT_SSH_PRIVATE_KEYFILE || \
(option) == CURLOPT_CRLFILE || \
(option) == CURLOPT_ISSUERCERT || \
(option) == CURLOPT_SOCKS5_GSSAPI_SERVICE || \
(option) == CURLOPT_SSH_KNOWNHOSTS || \
(option) == CURLOPT_MAIL_FROM || \
(option) == CURLOPT_RTSP_SESSION_ID || \
(option) == CURLOPT_RTSP_STREAM_URI || \
(option) == CURLOPT_RTSP_TRANSPORT || \
(option) == CURLOPT_XOAUTH2_BEARER || \
(option) == CURLOPT_DNS_SERVERS || \
(option) == CURLOPT_DNS_INTERFACE || \
(option) == CURLOPT_DNS_LOCAL_IP4 || \
(option) == CURLOPT_DNS_LOCAL_IP6 || \
(option) == CURLOPT_LOGIN_OPTIONS || \
0)
/* evaluates to true if option takes a curl_write_callback argument */
#define _curl_is_write_cb_option(option) \
((option) == CURLOPT_HEADERFUNCTION || \
(option) == CURLOPT_WRITEFUNCTION)
/* evaluates to true if option takes a curl_conv_callback argument */
#define _curl_is_conv_cb_option(option) \
((option) == CURLOPT_CONV_TO_NETWORK_FUNCTION || \
(option) == CURLOPT_CONV_FROM_NETWORK_FUNCTION || \
(option) == CURLOPT_CONV_FROM_UTF8_FUNCTION)
/* evaluates to true if option takes a data argument to pass to a callback */
#define _curl_is_cb_data_option(option) \
((option) == CURLOPT_WRITEDATA || \
(option) == CURLOPT_READDATA || \
(option) == CURLOPT_IOCTLDATA || \
(option) == CURLOPT_SOCKOPTDATA || \
(option) == CURLOPT_OPENSOCKETDATA || \
(option) == CURLOPT_PROGRESSDATA || \
(option) == CURLOPT_HEADERDATA || \
(option) == CURLOPT_DEBUGDATA || \
(option) == CURLOPT_SSL_CTX_DATA || \
(option) == CURLOPT_SEEKDATA || \
(option) == CURLOPT_PRIVATE || \
(option) == CURLOPT_SSH_KEYDATA || \
(option) == CURLOPT_INTERLEAVEDATA || \
(option) == CURLOPT_CHUNK_DATA || \
(option) == CURLOPT_FNMATCH_DATA || \
0)
/* evaluates to true if option takes a POST data argument (void* or char*) */
#define _curl_is_postfields_option(option) \
((option) == CURLOPT_POSTFIELDS || \
(option) == CURLOPT_COPYPOSTFIELDS || \
0)
/* evaluates to true if option takes a struct curl_slist * argument */
#define _curl_is_slist_option(option) \
((option) == CURLOPT_HTTPHEADER || \
(option) == CURLOPT_HTTP200ALIASES || \
(option) == CURLOPT_QUOTE || \
(option) == CURLOPT_POSTQUOTE || \
(option) == CURLOPT_PREQUOTE || \
(option) == CURLOPT_TELNETOPTIONS || \
(option) == CURLOPT_MAIL_RCPT || \
0)
/* groups of curl_easy_getinfo infos that take the same type of argument */
/* evaluates to true if info expects a pointer to char * argument */
#define _curl_is_string_info(info) \
(CURLINFO_STRING < (info) && (info) < CURLINFO_LONG)
/* evaluates to true if info expects a pointer to long argument */
#define _curl_is_long_info(info) \
(CURLINFO_LONG < (info) && (info) < CURLINFO_DOUBLE)
/* evaluates to true if info expects a pointer to double argument */
#define _curl_is_double_info(info) \
(CURLINFO_DOUBLE < (info) && (info) < CURLINFO_SLIST)
/* true if info expects a pointer to struct curl_slist * argument */
#define _curl_is_slist_info(info) \
(CURLINFO_SLIST < (info))
/* typecheck helpers -- check whether given expression has requested type*/
/* For pointers, you can use the _curl_is_ptr/_curl_is_arr macros,
* otherwise define a new macro. Search for __builtin_types_compatible_p
* in the GCC manual.
* NOTE: these macros MUST NOT EVALUATE their arguments! The argument is
* the actual expression passed to the curl_easy_setopt macro. This
* means that you can only apply the sizeof and __typeof__ operators, no
* == or whatsoever.
*/
/* XXX: should evaluate to true iff expr is a pointer */
#define _curl_is_any_ptr(expr) \
(sizeof(expr) == sizeof(void*))
/* evaluates to true if expr is NULL */
/* XXX: must not evaluate expr, so this check is not accurate */
#define _curl_is_NULL(expr) \
(__builtin_types_compatible_p(__typeof__(expr), __typeof__(NULL)))
/* evaluates to true if expr is type*, const type* or NULL */
#define _curl_is_ptr(expr, type) \
(_curl_is_NULL(expr) || \
__builtin_types_compatible_p(__typeof__(expr), type *) || \
__builtin_types_compatible_p(__typeof__(expr), const type *))
/* evaluates to true if expr is one of type[], type*, NULL or const type* */
#define _curl_is_arr(expr, type) \
(_curl_is_ptr((expr), type) || \
__builtin_types_compatible_p(__typeof__(expr), type []))
/* evaluates to true if expr is a string */
#define _curl_is_string(expr) \
(_curl_is_arr((expr), char) || \
_curl_is_arr((expr), signed char) || \
_curl_is_arr((expr), unsigned char))
/* evaluates to true if expr is a long (no matter the signedness)
* XXX: for now, int is also accepted (and therefore short and char, which
* are promoted to int when passed to a variadic function) */
#define _curl_is_long(expr) \
(__builtin_types_compatible_p(__typeof__(expr), long) || \
__builtin_types_compatible_p(__typeof__(expr), signed long) || \
__builtin_types_compatible_p(__typeof__(expr), unsigned long) || \
__builtin_types_compatible_p(__typeof__(expr), int) || \
__builtin_types_compatible_p(__typeof__(expr), signed int) || \
__builtin_types_compatible_p(__typeof__(expr), unsigned int) || \
__builtin_types_compatible_p(__typeof__(expr), short) || \
__builtin_types_compatible_p(__typeof__(expr), signed short) || \
__builtin_types_compatible_p(__typeof__(expr), unsigned short) || \
__builtin_types_compatible_p(__typeof__(expr), char) || \
__builtin_types_compatible_p(__typeof__(expr), signed char) || \
__builtin_types_compatible_p(__typeof__(expr), unsigned char))
/* evaluates to true if expr is of type curl_off_t */
#define _curl_is_off_t(expr) \
(__builtin_types_compatible_p(__typeof__(expr), curl_off_t))
/* evaluates to true if expr is abuffer suitable for CURLOPT_ERRORBUFFER */
/* XXX: also check size of an char[] array? */
#define _curl_is_error_buffer(expr) \
(_curl_is_NULL(expr) || \
__builtin_types_compatible_p(__typeof__(expr), char *) || \
__builtin_types_compatible_p(__typeof__(expr), char[]))
/* evaluates to true if expr is of type (const) void* or (const) FILE* */
#if 0
#define _curl_is_cb_data(expr) \
(_curl_is_ptr((expr), void) || \
_curl_is_ptr((expr), FILE))
#else /* be less strict */
#define _curl_is_cb_data(expr) \
_curl_is_any_ptr(expr)
#endif
/* evaluates to true if expr is of type FILE* */
#define _curl_is_FILE(expr) \
(__builtin_types_compatible_p(__typeof__(expr), FILE *))
/* evaluates to true if expr can be passed as POST data (void* or char*) */
#define _curl_is_postfields(expr) \
(_curl_is_ptr((expr), void) || \
_curl_is_arr((expr), char))
/* FIXME: the whole callback checking is messy...
* The idea is to tolerate char vs. void and const vs. not const
* pointers in arguments at least
*/
/* helper: __builtin_types_compatible_p distinguishes between functions and
* function pointers, hide it */
#define _curl_callback_compatible(func, type) \
(__builtin_types_compatible_p(__typeof__(func), type) || \
__builtin_types_compatible_p(__typeof__(func), type*))
/* evaluates to true if expr is of type curl_read_callback or "similar" */
#define _curl_is_read_cb(expr) \
(_curl_is_NULL(expr) || \
__builtin_types_compatible_p(__typeof__(expr), __typeof__(fread)) || \
__builtin_types_compatible_p(__typeof__(expr), curl_read_callback) || \
_curl_callback_compatible((expr), _curl_read_callback1) || \
_curl_callback_compatible((expr), _curl_read_callback2) || \
_curl_callback_compatible((expr), _curl_read_callback3) || \
_curl_callback_compatible((expr), _curl_read_callback4) || \
_curl_callback_compatible((expr), _curl_read_callback5) || \
_curl_callback_compatible((expr), _curl_read_callback6))
typedef size_t (_curl_read_callback1)(char *, size_t, size_t, void*);
typedef size_t (_curl_read_callback2)(char *, size_t, size_t, const void*);
typedef size_t (_curl_read_callback3)(char *, size_t, size_t, FILE*);
typedef size_t (_curl_read_callback4)(void *, size_t, size_t, void*);
typedef size_t (_curl_read_callback5)(void *, size_t, size_t, const void*);
typedef size_t (_curl_read_callback6)(void *, size_t, size_t, FILE*);
/* evaluates to true if expr is of type curl_write_callback or "similar" */
#define _curl_is_write_cb(expr) \
(_curl_is_read_cb(expr) || \
__builtin_types_compatible_p(__typeof__(expr), __typeof__(fwrite)) || \
__builtin_types_compatible_p(__typeof__(expr), curl_write_callback) || \
_curl_callback_compatible((expr), _curl_write_callback1) || \
_curl_callback_compatible((expr), _curl_write_callback2) || \
_curl_callback_compatible((expr), _curl_write_callback3) || \
_curl_callback_compatible((expr), _curl_write_callback4) || \
_curl_callback_compatible((expr), _curl_write_callback5) || \
_curl_callback_compatible((expr), _curl_write_callback6))
typedef size_t (_curl_write_callback1)(const char *, size_t, size_t, void*);
typedef size_t (_curl_write_callback2)(const char *, size_t, size_t,
const void*);
typedef size_t (_curl_write_callback3)(const char *, size_t, size_t, FILE*);
typedef size_t (_curl_write_callback4)(const void *, size_t, size_t, void*);
typedef size_t (_curl_write_callback5)(const void *, size_t, size_t,
const void*);
typedef size_t (_curl_write_callback6)(const void *, size_t, size_t, FILE*);
/* evaluates to true if expr is of type curl_ioctl_callback or "similar" */
#define _curl_is_ioctl_cb(expr) \
(_curl_is_NULL(expr) || \
__builtin_types_compatible_p(__typeof__(expr), curl_ioctl_callback) || \
_curl_callback_compatible((expr), _curl_ioctl_callback1) || \
_curl_callback_compatible((expr), _curl_ioctl_callback2) || \
_curl_callback_compatible((expr), _curl_ioctl_callback3) || \
_curl_callback_compatible((expr), _curl_ioctl_callback4))
typedef curlioerr (_curl_ioctl_callback1)(CURL *, int, void*);
typedef curlioerr (_curl_ioctl_callback2)(CURL *, int, const void*);
typedef curlioerr (_curl_ioctl_callback3)(CURL *, curliocmd, void*);
typedef curlioerr (_curl_ioctl_callback4)(CURL *, curliocmd, const void*);
/* evaluates to true if expr is of type curl_sockopt_callback or "similar" */
#define _curl_is_sockopt_cb(expr) \
(_curl_is_NULL(expr) || \
__builtin_types_compatible_p(__typeof__(expr), curl_sockopt_callback) || \
_curl_callback_compatible((expr), _curl_sockopt_callback1) || \
_curl_callback_compatible((expr), _curl_sockopt_callback2))
typedef int (_curl_sockopt_callback1)(void *, curl_socket_t, curlsocktype);
typedef int (_curl_sockopt_callback2)(const void *, curl_socket_t,
curlsocktype);
/* evaluates to true if expr is of type curl_opensocket_callback or
"similar" */
#define _curl_is_opensocket_cb(expr) \
(_curl_is_NULL(expr) || \
__builtin_types_compatible_p(__typeof__(expr), curl_opensocket_callback) ||\
_curl_callback_compatible((expr), _curl_opensocket_callback1) || \
_curl_callback_compatible((expr), _curl_opensocket_callback2) || \
_curl_callback_compatible((expr), _curl_opensocket_callback3) || \
_curl_callback_compatible((expr), _curl_opensocket_callback4))
typedef curl_socket_t (_curl_opensocket_callback1)
(void *, curlsocktype, struct curl_sockaddr *);
typedef curl_socket_t (_curl_opensocket_callback2)
(void *, curlsocktype, const struct curl_sockaddr *);
typedef curl_socket_t (_curl_opensocket_callback3)
(const void *, curlsocktype, struct curl_sockaddr *);
typedef curl_socket_t (_curl_opensocket_callback4)
(const void *, curlsocktype, const struct curl_sockaddr *);
/* evaluates to true if expr is of type curl_progress_callback or "similar" */
#define _curl_is_progress_cb(expr) \
(_curl_is_NULL(expr) || \
__builtin_types_compatible_p(__typeof__(expr), curl_progress_callback) || \
_curl_callback_compatible((expr), _curl_progress_callback1) || \
_curl_callback_compatible((expr), _curl_progress_callback2))
typedef int (_curl_progress_callback1)(void *,
double, double, double, double);
typedef int (_curl_progress_callback2)(const void *,
double, double, double, double);
/* evaluates to true if expr is of type curl_debug_callback or "similar" */
#define _curl_is_debug_cb(expr) \
(_curl_is_NULL(expr) || \
__builtin_types_compatible_p(__typeof__(expr), curl_debug_callback) || \
_curl_callback_compatible((expr), _curl_debug_callback1) || \
_curl_callback_compatible((expr), _curl_debug_callback2) || \
_curl_callback_compatible((expr), _curl_debug_callback3) || \
_curl_callback_compatible((expr), _curl_debug_callback4) || \
_curl_callback_compatible((expr), _curl_debug_callback5) || \
_curl_callback_compatible((expr), _curl_debug_callback6) || \
_curl_callback_compatible((expr), _curl_debug_callback7) || \
_curl_callback_compatible((expr), _curl_debug_callback8))
typedef int (_curl_debug_callback1) (CURL *,
curl_infotype, char *, size_t, void *);
typedef int (_curl_debug_callback2) (CURL *,
curl_infotype, char *, size_t, const void *);
typedef int (_curl_debug_callback3) (CURL *,
curl_infotype, const char *, size_t, void *);
typedef int (_curl_debug_callback4) (CURL *,
curl_infotype, const char *, size_t, const void *);
typedef int (_curl_debug_callback5) (CURL *,
curl_infotype, unsigned char *, size_t, void *);
typedef int (_curl_debug_callback6) (CURL *,
curl_infotype, unsigned char *, size_t, const void *);
typedef int (_curl_debug_callback7) (CURL *,
curl_infotype, const unsigned char *, size_t, void *);
typedef int (_curl_debug_callback8) (CURL *,
curl_infotype, const unsigned char *, size_t, const void *);
/* evaluates to true if expr is of type curl_ssl_ctx_callback or "similar" */
/* this is getting even messier... */
#define _curl_is_ssl_ctx_cb(expr) \
(_curl_is_NULL(expr) || \
__builtin_types_compatible_p(__typeof__(expr), curl_ssl_ctx_callback) || \
_curl_callback_compatible((expr), _curl_ssl_ctx_callback1) || \
_curl_callback_compatible((expr), _curl_ssl_ctx_callback2) || \
_curl_callback_compatible((expr), _curl_ssl_ctx_callback3) || \
_curl_callback_compatible((expr), _curl_ssl_ctx_callback4) || \
_curl_callback_compatible((expr), _curl_ssl_ctx_callback5) || \
_curl_callback_compatible((expr), _curl_ssl_ctx_callback6) || \
_curl_callback_compatible((expr), _curl_ssl_ctx_callback7) || \
_curl_callback_compatible((expr), _curl_ssl_ctx_callback8))
typedef CURLcode (_curl_ssl_ctx_callback1)(CURL *, void *, void *);
typedef CURLcode (_curl_ssl_ctx_callback2)(CURL *, void *, const void *);
typedef CURLcode (_curl_ssl_ctx_callback3)(CURL *, const void *, void *);
typedef CURLcode (_curl_ssl_ctx_callback4)(CURL *, const void *, const void *);
#ifdef HEADER_SSL_H
/* hack: if we included OpenSSL's ssl.h, we know about SSL_CTX
* this will of course break if we're included before OpenSSL headers...
*/
typedef CURLcode (_curl_ssl_ctx_callback5)(CURL *, SSL_CTX, void *);
typedef CURLcode (_curl_ssl_ctx_callback6)(CURL *, SSL_CTX, const void *);
typedef CURLcode (_curl_ssl_ctx_callback7)(CURL *, const SSL_CTX, void *);
typedef CURLcode (_curl_ssl_ctx_callback8)(CURL *, const SSL_CTX,
const void *);
#else
typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback5;
typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback6;
typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback7;
typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback8;
#endif
/* evaluates to true if expr is of type curl_conv_callback or "similar" */
#define _curl_is_conv_cb(expr) \
(_curl_is_NULL(expr) || \
__builtin_types_compatible_p(__typeof__(expr), curl_conv_callback) || \
_curl_callback_compatible((expr), _curl_conv_callback1) || \
_curl_callback_compatible((expr), _curl_conv_callback2) || \
_curl_callback_compatible((expr), _curl_conv_callback3) || \
_curl_callback_compatible((expr), _curl_conv_callback4))
typedef CURLcode (*_curl_conv_callback1)(char *, size_t length);
typedef CURLcode (*_curl_conv_callback2)(const char *, size_t length);
typedef CURLcode (*_curl_conv_callback3)(void *, size_t length);
typedef CURLcode (*_curl_conv_callback4)(const void *, size_t length);
/* evaluates to true if expr is of type curl_seek_callback or "similar" */
#define _curl_is_seek_cb(expr) \
(_curl_is_NULL(expr) || \
__builtin_types_compatible_p(__typeof__(expr), curl_seek_callback) || \
_curl_callback_compatible((expr), _curl_seek_callback1) || \
_curl_callback_compatible((expr), _curl_seek_callback2))
typedef CURLcode (*_curl_seek_callback1)(void *, curl_off_t, int);
typedef CURLcode (*_curl_seek_callback2)(const void *, curl_off_t, int);
#endif /* __CURL_TYPECHECK_GCC_H */

View File

@ -1,425 +0,0 @@
/* This source code was modified by Martin Hedenfalk <mhe@stacken.kth.se> for
* use in Curl. Martin's latest changes were done 2000-09-18.
*
* It has since been patched away like a madman by Daniel Stenberg to make it
* better applied to curl conditions, and to make it not use globals, pollute
* name space and more.
*
* Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* Copyright (c) 2004 - 2007 Daniel Stenberg
* 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.
*
* $Id$
*/
#include "setup.h"
#ifndef CURL_DISABLE_FTP
#ifdef HAVE_KRB4
#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 "urldata.h"
#include "base64.h"
#include "ftp.h"
#include "sendf.h"
#include "krb4.h"
#include "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;
unsigned char *ptr;
size_t 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) {
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)
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
infof(data, "Using NAT IP address (%s) for kerberos 4\n", ip);
localaddr->sin_addr = natAddr;
}
}
}
#endif
if(Curl_base64_encode(conn->data, (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, &ptr);
if(len > sizeof(adat.dat)-1) {
free(ptr);
len=0;
}
if(!len || !ptr) {
Curl_failf(data, "Failed to decode base64 from server");
return AUTH_ERROR;
}
memcpy((char *)adat.dat, ptr, len);
free(ptr);
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];
size_t tmp;
ssize_t nread;
int save;
CURLcode result;
unsigned char *ptr;
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, &ptr);
if(tmp >= sizeof(tkt.dat)) {
free(ptr);
tmp=0;
}
if(!tmp || !ptr) {
Curl_failf(conn->data, "Failed to decode base64 in reply.\n");
Curl_set_command_prot(conn, save);
return CURLE_FTP_WEIRD_SERVER_REPLY;
}
memcpy((char *)tkt.dat, ptr, tmp);
free(ptr);
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(conn->data, (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 */

View File

@ -1,702 +0,0 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute 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>
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef NEED_MALLOC_H
#include <malloc.h>
#endif
#include <errno.h>
#if defined(WIN32)
# 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 "memory.h"
#include "base64.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 (cl -Gr). Watcom
* uses fastcall by default.
*/
#if !defined(WIN32) && !defined(__cdecl)
#define __cdecl
#endif
#ifndef LDAP_SIZELIMIT_EXCEEDED
#define LDAP_SIZELIMIT_EXCEEDED 4
#endif
#ifndef LDAP_VERSION2
#define LDAP_VERSION2 2
#endif
#ifndef LDAP_VERSION3
#define LDAP_VERSION3 3
#endif
#ifndef LDAP_OPT_PROTOCOL_VERSION
#define LDAP_OPT_PROTOCOL_VERSION 0x0011
#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
/*
* We use this ZERO_NULL to avoid picky compiler warnings,
* when assigning a NULL pointer to a function pointer var.
*/
#define ZERO_NULL 0
typedef void * (*dynafunc)(void *input);
/***********************************************************************
*/
#if defined(HAVE_DLOPEN) || defined(HAVE_LIBDL) || defined(WIN32)
static void *libldap = NULL;
#if defined(DL_LBER_FILE)
static void *liblber = NULL;
#endif
#endif
struct bv {
unsigned long bv_len;
char *bv_val;
};
static int DynaOpen(const char **mod_name)
{
#if defined(HAVE_DLOPEN) || defined(HAVE_LIBDL)
if (libldap == NULL) {
/*
* libldap.so can normally resolve its dependency on liblber.so
* automatically, but in broken installation it does not so
* handle it here by opening liblber.so as global.
*/
#ifdef DL_LBER_FILE
*mod_name = DL_LBER_FILE;
liblber = dlopen(*mod_name, DLOPEN_MODE);
if (!liblber)
return 0;
#endif
/* Assume loading libldap.so will fail if loading of liblber.so failed
*/
*mod_name = DL_LDAP_FILE;
libldap = dlopen(*mod_name, RTLD_LAZY);
}
return (libldap != NULL);
#elif defined(WIN32)
*mod_name = DL_LDAP_FILE;
if (!libldap)
libldap = (void*)LoadLibrary(*mod_name);
return (libldap != NULL);
#else
*mod_name = "";
return (0);
#endif
}
static void DynaClose(void)
{
#if defined(HAVE_DLOPEN) || defined(HAVE_LIBDL)
if (libldap) {
dlclose(libldap);
libldap=NULL;
}
#ifdef DL_LBER_FILE
if (liblber) {
dlclose(liblber);
liblber=NULL;
}
#endif
#elif defined(WIN32)
if (libldap) {
FreeLibrary ((HMODULE)libldap);
libldap = NULL;
}
#endif
}
static dynafunc DynaGetFunction(const char *name)
{
dynafunc func = (dynafunc)ZERO_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);
}
#else
(void) 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, bool *done)
{
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 *);
void **(__cdecl *ldap_get_values_len)(void *, void *, const char *);
void (__cdecl *ldap_value_free_len)(void **);
void (__cdecl *ldap_memfree)(void *);
void (__cdecl *ber_free)(void *, int);
int (__cdecl *ldap_set_option)(void *, int, void *);
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;
int ldap_proto;
char *val_b64;
size_t val_b64_sz;
*done = TRUE; /* unconditionally */
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 *(__cdecl *)(char *, int), ldap_init);
DYNA_GET_FUNCTION(int (__cdecl *)(void *, char *, char *),
ldap_simple_bind_s);
DYNA_GET_FUNCTION(int (__cdecl *)(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 (__cdecl *)(void *, char *, int, char *, char **, int,
void **), ldap_search_s);
DYNA_GET_FUNCTION(void *(__cdecl *)(void *, void *), ldap_first_entry);
DYNA_GET_FUNCTION(void *(__cdecl *)(void *, void *), ldap_next_entry);
DYNA_GET_FUNCTION(char *(__cdecl *)(int), ldap_err2string);
DYNA_GET_FUNCTION(char *(__cdecl *)(void *, void *), ldap_get_dn);
DYNA_GET_FUNCTION(char *(__cdecl *)(void *, void *, void **),
ldap_first_attribute);
DYNA_GET_FUNCTION(char *(__cdecl *)(void *, void *, void *),
ldap_next_attribute);
DYNA_GET_FUNCTION(void **(__cdecl *)(void *, void *, const char *),
ldap_get_values_len);
DYNA_GET_FUNCTION(void (__cdecl *)(void **), ldap_value_free_len);
DYNA_GET_FUNCTION(void (__cdecl *)(void *), ldap_memfree);
DYNA_GET_FUNCTION(void (__cdecl *)(void *, int), ber_free);
DYNA_GET_FUNCTION(int (__cdecl *)(void *, int, void *), ldap_set_option);
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;
}
ldap_proto = LDAP_VERSION3;
(*ldap_set_option)(server, LDAP_OPT_PROTOCOL_VERSION, &ldap_proto);
rc = (*ldap_simple_bind_s)(server,
conn->bits.user_passwd ? conn->user : NULL,
conn->bits.user_passwd ? conn->passwd : NULL);
if (rc != 0) {
ldap_proto = LDAP_VERSION2;
(*ldap_set_option)(server, LDAP_OPT_PROTOCOL_VERSION, &ldap_proto);
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(conn, CLIENTWRITE_BODY, (char *)"DN: ", 4);
Curl_client_write(conn, CLIENTWRITE_BODY, (char *)dn, 0);
Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
for (attribute = (*ldap_first_attribute)(server, entryIterator, &ber);
attribute;
attribute = (*ldap_next_attribute)(server, entryIterator, ber))
{
struct bv **vals = (struct bv **)
(*ldap_get_values_len)(server, entryIterator, attribute);
if (vals != NULL)
{
for (i = 0; (vals[i] != NULL); i++)
{
Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\t", 1);
Curl_client_write(conn, CLIENTWRITE_BODY, (char *) attribute, 0);
Curl_client_write(conn, CLIENTWRITE_BODY, (char *)": ", 2);
if ((strlen(attribute) > 7) &&
(strcmp(";binary",
(char *)attribute +
(strlen((char *)attribute) - 7)) == 0)) {
/* Binary attribute, encode to base64. */
val_b64_sz = Curl_base64_encode(conn->data,
vals[i]->bv_val,
vals[i]->bv_len,
&val_b64);
if (val_b64_sz > 0) {
Curl_client_write(conn, CLIENTWRITE_BODY, val_b64, val_b64_sz);
free(val_b64);
}
} else
Curl_client_write(conn, CLIENTWRITE_BODY, vals[i]->bv_val,
vals[i]->bv_len);
Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0);
}
/* Free memory used to store values */
(*ldap_value_free_len)((void **)vals);
}
Curl_client_write(conn, 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_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
conn->bits.close = TRUE;
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 (void *data, LDAPURLDesc *ludp)
{
int i;
if (ludp->lud_filter) {
ludp->lud_filter = curl_easy_unescape(data, ludp->lud_filter, 0, NULL);
if (!ludp->lud_filter)
return (FALSE);
}
for (i = 0; ludp->lud_attrs && ludp->lud_attrs[i]; i++) {
ludp->lud_attrs[i] = curl_easy_unescape(data, ludp->lud_attrs[i], 0, NULL);
if (!ludp->lud_attrs[i])
return (FALSE);
}
for (i = 0; ludp->lud_exts && ludp->lud_exts[i]; i++) {
ludp->lud_exts[i] = curl_easy_unescape(data, ludp->lud_exts[i], 0, NULL);
if (!ludp->lud_exts[i])
return (FALSE);
}
if (ludp->lud_dn) {
char *dn = ludp->lud_dn;
char *new_dn = curl_easy_unescape(data, dn, 0, NULL);
free(dn);
ludp->lud_dn = new_dn;
if (!new_dn)
return (FALSE);
}
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->data->reqdata.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->data ||
!conn->data->reqdata.path ||
conn->data->reqdata.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->data->reqdata.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(conn->data, 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 */

View File

@ -0,0 +1,147 @@
set(LIB_NAME cmcurl)
configure_file(${CURL_SOURCE_DIR}/include/curl/curlbuild.h.cmake
${CURL_BINARY_DIR}/include/curl/curlbuild.h)
configure_file(curl_config.h.cmake
${CMAKE_CURRENT_BINARY_DIR}/curl_config.h)
transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake")
include(${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake)
list(APPEND HHEADERS
${CMAKE_CURRENT_BINARY_DIR}/curl_config.h
${CURL_BINARY_DIR}/include/curl/curlbuild.h
)
if(MSVC AND NOT CURL_STATICLIB)
list(APPEND CSOURCES libcurl.rc)
endif()
# SET(CSOURCES
# # memdebug.c -not used
# # nwlib.c - Not used
# # strtok.c - specify later
# # strtoofft.c - specify later
# )
# # if we have Kerberos 4, right now this is never on
# #OPTION(CURL_KRB4 "Use Kerberos 4" OFF)
# IF(CURL_KRB4)
# SET(CSOURCES ${CSOURCES}
# 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(CSOURCES ${CSOURCES}
# memdebug.c
# )
# ENDIF(CURL_MALLOC_DEBUG)
# # only build compat strtoofft if we need to
# IF(NOT HAVE_STRTOLL AND NOT HAVE__STRTOI64)
# SET(CSOURCES ${CSOURCES}
# strtoofft.c
# )
# ENDIF(NOT HAVE_STRTOLL AND NOT HAVE__STRTOI64)
if(HAVE_FEATURES_H)
set_source_files_properties(
cookie.c
easy.c
formdata.c
getenv.c
nonblock.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)
# The rest of the build
include_directories(${CMAKE_CURRENT_BINARY_DIR}/../include)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../include)
include_directories(${CMAKE_CURRENT_BINARY_DIR}/..)
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
include_directories(${CMAKE_CURRENT_BINARY_DIR})
if(CURL_USE_ARES)
include_directories(${CARES_INCLUDE_DIR})
endif()
if(CURL_STATICLIB)
# Static lib
set(CURL_USER_DEFINED_DYNAMIC_OR_STATIC STATIC)
else()
# DLL / so dynamic lib
set(CURL_USER_DEFINED_DYNAMIC_OR_STATIC SHARED)
endif()
# For windows we want to install OPENSSL_LIBRARIES dlls
# and also copy them into the build tree so that testing
# can find them.
if(CMAKE_USE_OPENSSL AND OPENSSL_FOUND AND WIN32)
find_file(CMAKE_EAY_DLL NAME libeay32.dll HINTS ${OPENSSL_INCLUDE_DIR}/..)
find_file(CMAKE_SSL_DLL NAME ssleay32.dll HINTS ${OPENSSL_INCLUDE_DIR}/..)
mark_as_advanced(CMAKE_EAY_DLL CMAKE_SSL_DLL)
if(CMAKE_SSL_DLL AND CMAKE_EAY_DLL)
set(CMAKE_CURL_SSL_DLLS ${CMake_BIN_DIR}/${CMAKE_CFG_INTDIR}/libeay32.dll
${CMake_BIN_DIR}/${CMAKE_CFG_INTDIR}/ssleay32.dll)
add_custom_command(OUTPUT
${CMake_BIN_DIR}/${CMAKE_CFG_INTDIR}/libeay32.dll
DEPENDS ${CMAKE_EAY_DLL}
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_EAY_DLL}
${CMake_BIN_DIR}/${CMAKE_CFG_INTDIR}/libeay32.dll)
add_custom_command(OUTPUT
${CMake_BIN_DIR}/${CMAKE_CFG_INTDIR}/ssleay32.dll
DEPENDS ${CMAKE_SSL_DLL}
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SSL_DLL}
${CMake_BIN_DIR}/${CMAKE_CFG_INTDIR}/ssleay32.dll)
install(PROGRAMS ${CMAKE_EAY_DLL} ${CMAKE_SSL_DLL} DESTINATION bin)
endif()
endif()
add_library(
${LIB_NAME}
${CURL_USER_DEFINED_DYNAMIC_OR_STATIC}
${HHEADERS} ${CSOURCES}
${CMAKE_CURL_SSL_DLLS}
)
target_link_libraries(${LIB_NAME} ${CURL_LIBS})
if(0) # This code not needed for building within CMake.
if(WIN32)
add_definitions( -D_USRDLL )
endif()
endif()
set_target_properties(${LIB_NAME} PROPERTIES COMPILE_DEFINITIONS BUILDING_LIBCURL)
setup_curl_dependencies(${LIB_NAME})
if(0) # This code not needed for building within CMake.
# Remove the "lib" prefix since the library is already named "libcurl".
set_target_properties(${LIB_NAME} PROPERTIES PREFIX "")
set_target_properties(${LIB_NAME} PROPERTIES IMPORT_PREFIX "")
if(WIN32)
if(NOT CURL_STATICLIB)
# Add "_imp" as a suffix before the extension to avoid conflicting with the statically linked "libcurl.lib"
set_target_properties(${LIB_NAME} PROPERTIES IMPORT_SUFFIX "_imp.lib")
endif()
endif()
install(TARGETS ${LIB_NAME} DESTINATION lib)
endif()

View File

@ -0,0 +1,71 @@
#***************************************************************************
# _ _ ____ _
# Project ___| | | | _ \| |
# / __| | | | |_) | |
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
# are also available at http://curl.haxx.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute 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.
#
###########################################################################
LIB_VTLS_CFILES = vtls/openssl.c vtls/gtls.c vtls/vtls.c vtls/nss.c \
vtls/qssl.c vtls/polarssl.c vtls/polarssl_threadlock.c vtls/axtls.c \
vtls/cyassl.c vtls/curl_schannel.c vtls/curl_darwinssl.c vtls/gskit.c
LIB_VTLS_HFILES = vtls/qssl.h vtls/openssl.h vtls/vtls.h vtls/gtls.h \
vtls/nssg.h vtls/polarssl.h vtls/polarssl_threadlock.h vtls/axtls.h \
vtls/cyassl.h vtls/curl_schannel.h vtls/curl_darwinssl.h vtls/gskit.h
LIB_CFILES = file.c timeval.c base64.c hostip.c progress.c formdata.c \
cookie.c http.c sendf.c ftp.c url.c dict.c if2ip.c speedcheck.c \
ldap.c version.c getenv.c escape.c mprintf.c telnet.c netrc.c \
getinfo.c transfer.c strequal.c easy.c security.c curl_fnmatch.c \
fileinfo.c ftplistparser.c wildcard.c krb5.c memdebug.c http_chunks.c \
strtok.c connect.c llist.c hash.c multi.c content_encoding.c share.c \
http_digest.c md4.c md5.c http_negotiate.c inet_pton.c strtoofft.c \
strerror.c amigaos.c hostasyn.c hostip4.c hostip6.c hostsyn.c \
inet_ntop.c parsedate.c select.c tftp.c splay.c strdup.c socks.c \
ssh.c rawstr.c curl_addrinfo.c socks_gssapi.c socks_sspi.c \
curl_sspi.c slist.c nonblock.c curl_memrchr.c imap.c pop3.c smtp.c \
pingpong.c rtsp.c curl_threads.c warnless.c hmac.c curl_rtmp.c \
openldap.c curl_gethostname.c gopher.c idn_win32.c \
http_negotiate_sspi.c http_proxy.c non-ascii.c asyn-ares.c \
asyn-thread.c curl_gssapi.c curl_ntlm.c curl_ntlm_wb.c \
curl_ntlm_core.c curl_ntlm_msgs.c curl_sasl.c curl_multibyte.c \
hostcheck.c bundles.c conncache.c pipeline.c dotdot.c x509asn1.c \
http2.c curl_sasl_sspi.c
LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h \
formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h if2ip.h \
speedcheck.h urldata.h curl_ldap.h escape.h telnet.h getinfo.h \
strequal.h curl_sec.h memdebug.h http_chunks.h curl_fnmatch.h \
wildcard.h fileinfo.h ftplistparser.h strtok.h connect.h llist.h \
hash.h content_encoding.h share.h curl_md4.h curl_md5.h http_digest.h \
http_negotiate.h inet_pton.h amigaos.h strtoofft.h strerror.h \
inet_ntop.h curlx.h curl_memory.h curl_setup.h transfer.h select.h \
easyif.h multiif.h parsedate.h tftp.h sockaddr.h splay.h strdup.h \
socks.h ssh.h curl_base64.h rawstr.h curl_addrinfo.h curl_sspi.h \
slist.h nonblock.h curl_memrchr.h imap.h pop3.h smtp.h pingpong.h \
rtsp.h curl_threads.h warnless.h curl_hmac.h curl_rtmp.h \
curl_gethostname.h gopher.h http_proxy.h non-ascii.h asyn.h \
curl_ntlm.h curl_gssapi.h curl_ntlm_wb.h curl_ntlm_core.h \
curl_ntlm_msgs.h curl_sasl.h curl_multibyte.h hostcheck.h bundles.h \
conncache.h curl_setup_once.h multihandle.h setup-vms.h pipeline.h \
dotdot.h x509asn1.h http2.h sigpipe.h
LIB_RCFILES = libcurl.rc
CSOURCES = $(LIB_CFILES) $(LIB_VTLS_CFILES)
HHEADERS = $(LIB_HFILES) $(LIB_VTLS_HFILES)

View File

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@ -18,12 +18,16 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* $Id$
***************************************************************************/
#include "amigaos.h"
#include "curl_setup.h"
#if defined(__AMIGA__) && !defined(__ixemul__)
#include <amitcp/socketbasetags.h>
#include "amigaos.h"
struct Library *SocketBase = NULL;
extern int errno, h_errno;
@ -34,7 +38,7 @@ void __request(const char *msg);
# define __request( msg ) Printf( msg "\n\a")
#endif
void amiga_cleanup()
void Curl_amiga_cleanup()
{
if(SocketBase) {
CloseLibrary(SocketBase);
@ -42,7 +46,7 @@ void amiga_cleanup()
}
}
BOOL amiga_init()
bool Curl_amiga_init()
{
if(!SocketBase)
SocketBase = OpenLibrary("bsdsocket.library", 4);
@ -52,23 +56,22 @@ BOOL amiga_init()
return FALSE;
}
if(SocketBaseTags(
SBTM_SETVAL(SBTC_ERRNOPTR(sizeof(errno))), (ULONG) &errno,
// SBTM_SETVAL(SBTC_HERRNOLONGPTR), (ULONG) &h_errno,
if(SocketBaseTags(SBTM_SETVAL(SBTC_ERRNOPTR(sizeof(errno))), (ULONG) &errno,
SBTM_SETVAL(SBTC_LOGTAGPTR), (ULONG) "cURL",
TAG_DONE)) {
__request("SocketBaseTags ERROR");
return FALSE;
}
#ifndef __libnix__
atexit(amiga_cleanup);
atexit(Curl_amiga_cleanup);
#endif
return TRUE;
}
#ifdef __libnix__
ADD2EXIT(amiga_cleanup,-50);
ADD2EXIT(Curl_amiga_cleanup,-50);
#endif
#endif /* __AMIGA__ && ! __ixemul__ */

View File

@ -1,5 +1,5 @@
#ifndef __SOCKADDR_H
#define __SOCKADDR_H
#ifndef HEADER_CURL_AMIGAOS_H
#define HEADER_CURL_AMIGAOS_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@ -20,19 +20,20 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* $Id$
***************************************************************************/
#include "curl_setup.h"
#include "setup.h"
#if defined(__AMIGA__) && !defined(__ixemul__)
bool Curl_amiga_init();
void Curl_amiga_cleanup();
#ifdef HAVE_STRUCT_SOCKADDR_STORAGE
struct Curl_sockaddr_storage {
struct sockaddr_storage buffer;
};
#else
struct Curl_sockaddr_storage {
char buffer[256]; /* this should be big enough to fit a lot */
};
#define Curl_amiga_init() 1
#define Curl_amiga_cleanup() Curl_nop_stmt
#endif
#endif /* __SOCKADDR_H */
#endif /* HEADER_CURL_AMIGAOS_H */

View File

@ -1,5 +1,5 @@
#ifndef __ARPA_TELNET_H
#define __ARPA_TELNET_H
#ifndef HEADER_CURL_ARPA_TELNET_H
#define HEADER_CURL_ARPA_TELNET_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@ -20,16 +20,17 @@
* 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_ECHO 1 /* just echo! */
#define CURL_TELOPT_SGA 3 /* Suppress Go Ahead */
#define CURL_TELOPT_EXOPL 255 /* EXtended OPtions List */
#define CURL_TELOPT_TTYPE 24 /* Terminal TYPE */
#define CURL_TELOPT_NAWS 31 /* Negotiate About Window Size */
#define CURL_TELOPT_XDISPLOC 35 /* X DISPlay LOCation */
#define CURL_TELOPT_NEW_ENVIRON 39 /* NEW ENVIRONment variables */
@ -97,5 +98,7 @@ static const char * const telnetcmds[]=
#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
#endif /* CURL_DISABLE_TELNET */
#endif /* HEADER_CURL_ARPA_TELNET_H */

View File

@ -0,0 +1,694 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute 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 "curl_setup.h"
#ifdef HAVE_LIMITS_H
#include <limits.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 __VMS
#include <in.h>
#include <inet.h>
#endif
#ifdef HAVE_PROCESS_H
#include <process.h>
#endif
#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
#undef in_addr_t
#define in_addr_t unsigned long
#endif
/***********************************************************************
* Only for ares-enabled builds
* And only for functions that fulfill the asynch resolver backend API
* as defined in asyn.h, nothing else belongs in this file!
**********************************************************************/
#ifdef CURLRES_ARES
#include "urldata.h"
#include "sendf.h"
#include "hostip.h"
#include "hash.h"
#include "share.h"
#include "strerror.h"
#include "url.h"
#include "multiif.h"
#include "inet_pton.h"
#include "connect.h"
#include "select.h"
#include "progress.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
# if defined(CURL_STATICLIB) && !defined(CARES_STATICLIB) && \
(defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__))
# define CARES_STATICLIB
# endif
# include <ares.h>
# include <ares_version.h> /* really old c-ares didn't include this by
itself */
#if ARES_VERSION >= 0x010500
/* c-ares 1.5.0 or later, the callback proto is modified */
#define HAVE_CARES_CALLBACK_TIMEOUTS 1
#endif
#include "curl_memory.h"
/* The last #include file should be: */
#include "memdebug.h"
struct ResolverResults {
int num_pending; /* number of ares_gethostbyname() requests */
Curl_addrinfo *temp_ai; /* intermediary result while fetching c-ares parts */
int last_status;
};
/*
* Curl_resolver_global_init() - the generic low-level asynchronous name
* resolve API. Called from curl_global_init() to initialize global resolver
* environment. Initializes ares library.
*/
int Curl_resolver_global_init(void)
{
#ifdef CARES_HAVE_ARES_LIBRARY_INIT
if(ares_library_init(ARES_LIB_INIT_ALL)) {
return CURLE_FAILED_INIT;
}
#endif
return CURLE_OK;
}
/*
* Curl_resolver_global_cleanup()
*
* Called from curl_global_cleanup() to destroy global resolver environment.
* Deinitializes ares library.
*/
void Curl_resolver_global_cleanup(void)
{
#ifdef CARES_HAVE_ARES_LIBRARY_CLEANUP
ares_library_cleanup();
#endif
}
/*
* Curl_resolver_init()
*
* Called from curl_easy_init() -> Curl_open() to initialize resolver
* URL-state specific environment ('resolver' member of the UrlState
* structure). Fills the passed pointer by the initialized ares_channel.
*/
CURLcode Curl_resolver_init(void **resolver)
{
int status = ares_init((ares_channel*)resolver);
if(status != ARES_SUCCESS) {
if(status == ARES_ENOMEM)
return CURLE_OUT_OF_MEMORY;
else
return CURLE_FAILED_INIT;
}
return CURLE_OK;
/* make sure that all other returns from this function should destroy the
ares channel before returning error! */
}
/*
* Curl_resolver_cleanup()
*
* Called from curl_easy_cleanup() -> Curl_close() to cleanup resolver
* URL-state specific environment ('resolver' member of the UrlState
* structure). Destroys the ares channel.
*/
void Curl_resolver_cleanup(void *resolver)
{
ares_destroy((ares_channel)resolver);
}
/*
* Curl_resolver_duphandle()
*
* Called from curl_easy_duphandle() to duplicate resolver URL-state specific
* environment ('resolver' member of the UrlState structure). Duplicates the
* 'from' ares channel and passes the resulting channel to the 'to' pointer.
*/
int Curl_resolver_duphandle(void **to, void *from)
{
/* Clone the ares channel for the new handle */
if(ARES_SUCCESS != ares_dup((ares_channel*)to,(ares_channel)from))
return CURLE_FAILED_INIT;
return CURLE_OK;
}
static void destroy_async_data (struct Curl_async *async);
/*
* Cancel all possibly still on-going resolves for this connection.
*/
void Curl_resolver_cancel(struct connectdata *conn)
{
if(conn && conn->data && conn->data->state.resolver)
ares_cancel((ares_channel)conn->data->state.resolver);
destroy_async_data(&conn->async);
}
/*
* destroy_async_data() cleans up async resolver data.
*/
static void destroy_async_data (struct Curl_async *async)
{
if(async->hostname)
free(async->hostname);
if(async->os_specific) {
struct ResolverResults *res = (struct ResolverResults *)async->os_specific;
if(res) {
if(res->temp_ai) {
Curl_freeaddrinfo(res->temp_ai);
res->temp_ai = NULL;
}
free(res);
}
async->os_specific = NULL;
}
async->hostname = NULL;
}
/*
* Curl_resolver_getsock() 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: sockets-in-use-bitmap
*/
int Curl_resolver_getsock(struct connectdata *conn,
curl_socket_t *socks,
int numsocks)
{
struct timeval maxtime;
struct timeval timebuf;
struct timeval *timeout;
long milli;
int max = ares_getsock((ares_channel)conn->data->state.resolver,
(ares_socket_t *)socks, numsocks);
maxtime.tv_sec = CURL_TIMEOUT_RESOLVE;
maxtime.tv_usec = 0;
timeout = ares_timeout((ares_channel)conn->data->state.resolver, &maxtime,
&timebuf);
milli = (timeout->tv_sec * 1000) + (timeout->tv_usec/1000);
if(milli == 0)
milli += 10;
Curl_expire_latest(conn->data, milli);
return max;
}
/*
* waitperform()
*
* 1) Ask ares what sockets it currently plays with, then
* 2) wait for the timeout period to check for action on ares' sockets.
* 3) tell ares to act on all the sockets marked as "with action"
*
* return number of sockets it worked on
*/
static int waitperform(struct connectdata *conn, int timeout_ms)
{
struct SessionHandle *data = conn->data;
int nfds;
int bitmask;
ares_socket_t socks[ARES_GETSOCK_MAXNUM];
struct pollfd pfd[ARES_GETSOCK_MAXNUM];
int i;
int num = 0;
bitmask = ares_getsock((ares_channel)data->state.resolver, socks,
ARES_GETSOCK_MAXNUM);
for(i=0; i < ARES_GETSOCK_MAXNUM; i++) {
pfd[i].events = 0;
pfd[i].revents = 0;
if(ARES_GETSOCK_READABLE(bitmask, i)) {
pfd[i].fd = socks[i];
pfd[i].events |= POLLRDNORM|POLLIN;
}
if(ARES_GETSOCK_WRITABLE(bitmask, i)) {
pfd[i].fd = socks[i];
pfd[i].events |= POLLWRNORM|POLLOUT;
}
if(pfd[i].events != 0)
num++;
else
break;
}
if(num)
nfds = Curl_poll(pfd, num, timeout_ms);
else
nfds = 0;
if(!nfds)
/* Call ares_process() unconditonally here, even if we simply timed out
above, as otherwise the ares name resolve won't timeout! */
ares_process_fd((ares_channel)data->state.resolver, ARES_SOCKET_BAD,
ARES_SOCKET_BAD);
else {
/* move through the descriptors and ask for processing on them */
for(i=0; i < num; i++)
ares_process_fd((ares_channel)data->state.resolver,
pfd[i].revents & (POLLRDNORM|POLLIN)?
pfd[i].fd:ARES_SOCKET_BAD,
pfd[i].revents & (POLLWRNORM|POLLOUT)?
pfd[i].fd:ARES_SOCKET_BAD);
}
return nfds;
}
/*
* Curl_resolver_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_resolver_is_resolved(struct connectdata *conn,
struct Curl_dns_entry **dns)
{
struct SessionHandle *data = conn->data;
struct ResolverResults *res = (struct ResolverResults *)
conn->async.os_specific;
CURLcode rc = CURLE_OK;
*dns = NULL;
waitperform(conn, 0);
if(res && !res->num_pending) {
(void)Curl_addrinfo_callback(conn, res->last_status, res->temp_ai);
/* temp_ai ownership is moved to the connection, so we need not free-up
them */
res->temp_ai = NULL;
if(!conn->async.dns) {
failf(data, "Could not resolve: %s (%s)",
conn->async.hostname, ares_strerror(conn->async.status));
rc = conn->bits.proxy?CURLE_COULDNT_RESOLVE_PROXY:
CURLE_COULDNT_RESOLVE_HOST;
}
else
*dns = conn->async.dns;
destroy_async_data(&conn->async);
}
return rc;
}
/*
* Curl_resolver_wait_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_resolver_wait_resolv(struct connectdata *conn,
struct Curl_dns_entry **entry)
{
CURLcode rc=CURLE_OK;
struct SessionHandle *data = conn->data;
long timeout;
struct timeval now = Curl_tvnow();
struct Curl_dns_entry *temp_entry;
timeout = Curl_timeleft(data, &now, TRUE);
if(!timeout)
timeout = CURL_TIMEOUT_RESOLVE * 1000; /* default name resolve timeout */
/* Wait for the name resolve query to complete. */
for(;;) {
struct timeval *tvp, tv, store;
long timediff;
int itimeout;
int timeout_ms;
itimeout = (timeout > (long)INT_MAX) ? INT_MAX : (int)timeout;
store.tv_sec = itimeout/1000;
store.tv_usec = (itimeout%1000)*1000;
tvp = ares_timeout((ares_channel)data->state.resolver, &store, &tv);
/* use the timeout period ares returned to us above if less than one
second is left, otherwise just use 1000ms to make sure the progress
callback gets called frequent enough */
if(!tvp->tv_sec)
timeout_ms = (int)(tvp->tv_usec/1000);
else
timeout_ms = 1000;
waitperform(conn, timeout_ms);
Curl_resolver_is_resolved(conn,&temp_entry);
if(conn->async.done)
break;
if(Curl_pgrsUpdate(conn)) {
rc = CURLE_ABORTED_BY_CALLBACK;
timeout = -1; /* trigger the cancel below */
}
else {
struct timeval now2 = Curl_tvnow();
timediff = Curl_tvdiff(now2, now); /* spent time */
timeout -= timediff?timediff:1; /* always deduct at least 1 */
now = now2; /* for next loop */
}
if(timeout < 0) {
/* our timeout, so we cancel the ares operation */
ares_cancel((ares_channel)data->state.resolver);
break;
}
}
/* Operation complete, if the lookup was successful we now have the entry
in the cache. */
if(entry)
*entry = conn->async.dns;
if(rc)
/* close the connection, since we can't return failure here without
cleaning up this connection properly.
TODO: remove this action from here, it is not a name resolver decision.
*/
connclose(conn, "c-ares resolve failed");
return rc;
}
/* Connects results to the list */
static void compound_results(struct ResolverResults *res,
Curl_addrinfo *ai)
{
Curl_addrinfo *ai_tail;
if(!ai)
return;
ai_tail = ai;
while(ai_tail->ai_next)
ai_tail = ai_tail->ai_next;
/* Add the new results to the list of old results. */
ai_tail->ai_next = res->temp_ai;
res->temp_ai = ai;
}
/*
* ares_query_completed_cb() is the callback that ares will call when
* the host query initiated by ares_gethostbyname() from Curl_getaddrinfo(),
* when using ares, is completed either successfully or with failure.
*/
static void query_completed_cb(void *arg, /* (struct connectdata *) */
int status,
#ifdef HAVE_CARES_CALLBACK_TIMEOUTS
int timeouts,
#endif
struct hostent *hostent)
{
struct connectdata *conn = (struct connectdata *)arg;
struct ResolverResults *res;
#ifdef HAVE_CARES_CALLBACK_TIMEOUTS
(void)timeouts; /* ignored */
#endif
if(ARES_EDESTRUCTION == status)
/* when this ares handle is getting destroyed, the 'arg' pointer may not
be valid so only defer it when we know the 'status' says its fine! */
return;
res = (struct ResolverResults *)conn->async.os_specific;
res->num_pending--;
if(CURL_ASYNC_SUCCESS == status) {
Curl_addrinfo *ai = Curl_he2ai(hostent, conn->async.port);
if(ai) {
compound_results(res, ai);
}
}
/* A successful result overwrites any previous error */
if(res->last_status != ARES_SUCCESS)
res->last_status = status;
}
/*
* Curl_resolver_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_resolver_getaddrinfo(struct connectdata *conn,
const char *hostname,
int port,
int *waitp)
{
char *bufp;
struct SessionHandle *data = conn->data;
struct in_addr in;
int family = PF_INET;
#ifdef ENABLE_IPV6 /* CURLRES_IPV6 */
struct in6_addr in6;
#endif /* CURLRES_IPV6 */
*waitp = 0; /* default to synchronous response */
/* First check if this is an IPv4 address string */
if(Curl_inet_pton(AF_INET, hostname, &in) > 0) {
/* This is a dotted IP address 123.123.123.123-style */
return Curl_ip2addr(AF_INET, &in, hostname, port);
}
#ifdef ENABLE_IPV6 /* CURLRES_IPV6 */
/* Otherwise, check if this is an IPv6 address string */
if(Curl_inet_pton (AF_INET6, hostname, &in6) > 0)
/* This must be an IPv6 address literal. */
return Curl_ip2addr(AF_INET6, &in6, hostname, port);
switch(conn->ip_version) {
default:
#if ARES_VERSION >= 0x010601
family = PF_UNSPEC; /* supported by c-ares since 1.6.1, so for older
c-ares versions this just falls through and defaults
to PF_INET */
break;
#endif
case CURL_IPRESOLVE_V4:
family = PF_INET;
break;
case CURL_IPRESOLVE_V6:
family = PF_INET6;
break;
}
#endif /* CURLRES_IPV6 */
bufp = strdup(hostname);
if(bufp) {
struct ResolverResults *res = NULL;
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 */
res = calloc(sizeof(struct ResolverResults),1);
if(!res) {
Curl_safefree(conn->async.hostname);
conn->async.hostname = NULL;
return NULL;
}
conn->async.os_specific = res;
/* initial status - failed */
res->last_status = ARES_ENOTFOUND;
#ifdef ENABLE_IPV6 /* CURLRES_IPV6 */
if(family == PF_UNSPEC) {
if(Curl_ipv6works()) {
res->num_pending = 2;
/* areschannel is already setup in the Curl_open() function */
ares_gethostbyname((ares_channel)data->state.resolver, hostname,
PF_INET, query_completed_cb, conn);
ares_gethostbyname((ares_channel)data->state.resolver, hostname,
PF_INET6, query_completed_cb, conn);
}
else {
res->num_pending = 1;
/* areschannel is already setup in the Curl_open() function */
ares_gethostbyname((ares_channel)data->state.resolver, hostname,
PF_INET, query_completed_cb, conn);
}
}
else
#endif /* CURLRES_IPV6 */
{
res->num_pending = 1;
/* areschannel is already setup in the Curl_open() function */
ares_gethostbyname((ares_channel)data->state.resolver, hostname, family,
query_completed_cb, conn);
}
*waitp = 1; /* expect asynchronous response */
}
return NULL; /* no struct yet */
}
CURLcode Curl_set_dns_servers(struct SessionHandle *data,
char *servers)
{
CURLcode result = CURLE_NOT_BUILT_IN;
int ares_result;
/* If server is NULL or empty, this would purge all DNS servers
* from ares library, which will cause any and all queries to fail.
* So, just return OK if none are configured and don't actually make
* any changes to c-ares. This lets c-ares use it's defaults, which
* it gets from the OS (for instance from /etc/resolv.conf on Linux).
*/
if(!(servers && servers[0]))
return CURLE_OK;
#if (ARES_VERSION >= 0x010704)
ares_result = ares_set_servers_csv(data->state.resolver, servers);
switch(ares_result) {
case ARES_SUCCESS:
result = CURLE_OK;
break;
case ARES_ENOMEM:
result = CURLE_OUT_OF_MEMORY;
break;
case ARES_ENOTINITIALIZED:
case ARES_ENODATA:
case ARES_EBADSTR:
default:
result = CURLE_BAD_FUNCTION_ARGUMENT;
break;
}
#else /* too old c-ares version! */
(void)data;
(void)(ares_result);
#endif
return result;
}
CURLcode Curl_set_dns_interface(struct SessionHandle *data,
const char *interf)
{
#if (ARES_VERSION >= 0x010704)
if(!interf)
interf = "";
ares_set_local_dev((ares_channel)data->state.resolver, interf);
return CURLE_OK;
#else /* c-ares version too old! */
(void)data;
(void)interf;
return CURLE_NOT_BUILT_IN;
#endif
}
CURLcode Curl_set_dns_local_ip4(struct SessionHandle *data,
const char *local_ip4)
{
#if (ARES_VERSION >= 0x010704)
struct in_addr a4;
if((!local_ip4) || (local_ip4[0] == 0)) {
a4.s_addr = 0; /* disabled: do not bind to a specific address */
}
else {
if(Curl_inet_pton(AF_INET, local_ip4, &a4) != 1) {
return CURLE_BAD_FUNCTION_ARGUMENT;
}
}
ares_set_local_ip4((ares_channel)data->state.resolver, ntohl(a4.s_addr));
return CURLE_OK;
#else /* c-ares version too old! */
(void)data;
(void)local_ip4;
return CURLE_NOT_BUILT_IN;
#endif
}
CURLcode Curl_set_dns_local_ip6(struct SessionHandle *data,
const char *local_ip6)
{
#if (ARES_VERSION >= 0x010704) && defined(ENABLE_IPV6)
unsigned char a6[INET6_ADDRSTRLEN];
if((!local_ip6) || (local_ip6[0] == 0)) {
/* disabled: do not bind to a specific address */
memset(a6, 0, sizeof(a6));
}
else {
if(Curl_inet_pton(AF_INET6, local_ip6, a6) != 1) {
return CURLE_BAD_FUNCTION_ARGUMENT;
}
}
ares_set_local_ip6((ares_channel)data->state.resolver, a6);
return CURLE_OK;
#else /* c-ares version too old! */
(void)data;
(void)local_ip6;
return CURLE_NOT_BUILT_IN;
#endif
}
#endif /* CURLRES_ARES */

View File

@ -0,0 +1,701 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute 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 "curl_setup.h"
#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 __VMS
#include <in.h>
#include <inet.h>
#endif
#if defined(USE_THREADS_POSIX)
# ifdef HAVE_PTHREAD_H
# include <pthread.h>
# endif
#elif defined(USE_THREADS_WIN32)
# ifdef HAVE_PROCESS_H
# include <process.h>
# endif
#endif
#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
#undef in_addr_t
#define in_addr_t unsigned long
#endif
#ifdef HAVE_GETADDRINFO
# define RESOLVER_ENOMEM EAI_MEMORY
#else
# define RESOLVER_ENOMEM ENOMEM
#endif
#include "urldata.h"
#include "sendf.h"
#include "hostip.h"
#include "hash.h"
#include "share.h"
#include "strerror.h"
#include "url.h"
#include "multiif.h"
#include "inet_pton.h"
#include "inet_ntop.h"
#include "curl_threads.h"
#include "connect.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
#include "curl_memory.h"
/* The last #include file should be: */
#include "memdebug.h"
/***********************************************************************
* Only for threaded name resolves builds
**********************************************************************/
#ifdef CURLRES_THREADED
/*
* Curl_resolver_global_init()
* Called from curl_global_init() to initialize global resolver environment.
* Does nothing here.
*/
int Curl_resolver_global_init(void)
{
return CURLE_OK;
}
/*
* Curl_resolver_global_cleanup()
* Called from curl_global_cleanup() to destroy global resolver environment.
* Does nothing here.
*/
void Curl_resolver_global_cleanup(void)
{
}
/*
* Curl_resolver_init()
* Called from curl_easy_init() -> Curl_open() to initialize resolver
* URL-state specific environment ('resolver' member of the UrlState
* structure). Does nothing here.
*/
CURLcode Curl_resolver_init(void **resolver)
{
(void)resolver;
return CURLE_OK;
}
/*
* Curl_resolver_cleanup()
* Called from curl_easy_cleanup() -> Curl_close() to cleanup resolver
* URL-state specific environment ('resolver' member of the UrlState
* structure). Does nothing here.
*/
void Curl_resolver_cleanup(void *resolver)
{
(void)resolver;
}
/*
* Curl_resolver_duphandle()
* Called from curl_easy_duphandle() to duplicate resolver URL state-specific
* environment ('resolver' member of the UrlState structure). Does nothing
* here.
*/
int Curl_resolver_duphandle(void **to, void *from)
{
(void)to;
(void)from;
return CURLE_OK;
}
static void destroy_async_data(struct Curl_async *);
/*
* Cancel all possibly still on-going resolves for this connection.
*/
void Curl_resolver_cancel(struct connectdata *conn)
{
destroy_async_data(&conn->async);
}
/* This function is used to init a threaded resolve */
static bool init_resolve_thread(struct connectdata *conn,
const char *hostname, int port,
const struct addrinfo *hints);
/* Data for synchronization between resolver thread and its parent */
struct thread_sync_data {
curl_mutex_t * mtx;
int done;
char * hostname; /* hostname to resolve, Curl_async.hostname
duplicate */
int port;
int sock_error;
Curl_addrinfo *res;
#ifdef HAVE_GETADDRINFO
struct addrinfo hints;
#endif
struct thread_data *td; /* for thread-self cleanup */
};
struct thread_data {
curl_thread_t thread_hnd;
unsigned int poll_interval;
long interval_end;
struct thread_sync_data tsd;
};
static struct thread_sync_data *conn_thread_sync_data(struct connectdata *conn)
{
return &(((struct thread_data *)conn->async.os_specific)->tsd);
}
#define CONN_THREAD_SYNC_DATA(conn) &(((conn)->async.os_specific)->tsd);
/* Destroy resolver thread synchronization data */
static
void destroy_thread_sync_data(struct thread_sync_data * tsd)
{
if(tsd->mtx) {
Curl_mutex_destroy(tsd->mtx);
free(tsd->mtx);
}
if(tsd->hostname)
free(tsd->hostname);
if(tsd->res)
Curl_freeaddrinfo(tsd->res);
memset(tsd,0,sizeof(*tsd));
}
/* Initialize resolver thread synchronization data */
static
int init_thread_sync_data(struct thread_data * td,
const char * hostname,
int port,
const struct addrinfo *hints)
{
struct thread_sync_data *tsd = &td->tsd;
memset(tsd, 0, sizeof(*tsd));
tsd->td = td;
tsd->port = port;
#ifdef HAVE_GETADDRINFO
DEBUGASSERT(hints);
tsd->hints = *hints;
#else
(void) hints;
#endif
tsd->mtx = malloc(sizeof(curl_mutex_t));
if(tsd->mtx == NULL)
goto err_exit;
Curl_mutex_init(tsd->mtx);
tsd->sock_error = CURL_ASYNC_SUCCESS;
/* Copying hostname string because original can be destroyed by parent
* thread during gethostbyname execution.
*/
tsd->hostname = strdup(hostname);
if(!tsd->hostname)
goto err_exit;
return 1;
err_exit:
/* Memory allocation failed */
destroy_thread_sync_data(tsd);
return 0;
}
static int getaddrinfo_complete(struct connectdata *conn)
{
struct thread_sync_data *tsd = conn_thread_sync_data(conn);
int rc;
rc = Curl_addrinfo_callback(conn, tsd->sock_error, tsd->res);
/* The tsd->res structure has been copied to async.dns and perhaps the DNS
cache. Set our copy to NULL so destroy_thread_sync_data doesn't free it.
*/
tsd->res = NULL;
return rc;
}
#ifdef HAVE_GETADDRINFO
/*
* getaddrinfo_thread() resolves a name and then exits.
*
* For builds without ARES, but with ENABLE_IPV6, create a resolver thread
* and wait on it.
*/
static unsigned int CURL_STDCALL getaddrinfo_thread (void *arg)
{
struct thread_sync_data *tsd = (struct thread_sync_data*)arg;
struct thread_data *td = tsd->td;
char service[12];
int rc;
snprintf(service, sizeof(service), "%d", tsd->port);
rc = Curl_getaddrinfo_ex(tsd->hostname, service, &tsd->hints, &tsd->res);
if(rc != 0) {
tsd->sock_error = SOCKERRNO?SOCKERRNO:rc;
if(tsd->sock_error == 0)
tsd->sock_error = RESOLVER_ENOMEM;
}
Curl_mutex_acquire(tsd->mtx);
if(tsd->done) {
/* too late, gotta clean up the mess */
Curl_mutex_release(tsd->mtx);
destroy_thread_sync_data(tsd);
free(td);
}
else {
tsd->done = 1;
Curl_mutex_release(tsd->mtx);
}
return 0;
}
#else /* HAVE_GETADDRINFO */
/*
* gethostbyname_thread() resolves a name and then exits.
*/
static unsigned int CURL_STDCALL gethostbyname_thread (void *arg)
{
struct thread_sync_data *tsd = (struct thread_sync_data *)arg;
struct thread_data *td = tsd->td;
tsd->res = Curl_ipv4_resolve_r(tsd->hostname, tsd->port);
if(!tsd->res) {
tsd->sock_error = SOCKERRNO;
if(tsd->sock_error == 0)
tsd->sock_error = RESOLVER_ENOMEM;
}
Curl_mutex_acquire(tsd->mtx);
if(tsd->done) {
/* too late, gotta clean up the mess */
Curl_mutex_release(tsd->mtx);
destroy_thread_sync_data(tsd);
free(td);
}
else {
tsd->done = 1;
Curl_mutex_release(tsd->mtx);
}
return 0;
}
#endif /* HAVE_GETADDRINFO */
/*
* destroy_async_data() cleans up async resolver data and thread handle.
*/
static void destroy_async_data (struct Curl_async *async)
{
if(async->os_specific) {
struct thread_data *td = (struct thread_data*) async->os_specific;
int done;
/*
* if the thread is still blocking in the resolve syscall, detach it and
* let the thread do the cleanup...
*/
Curl_mutex_acquire(td->tsd.mtx);
done = td->tsd.done;
td->tsd.done = 1;
Curl_mutex_release(td->tsd.mtx);
if(!done) {
Curl_thread_destroy(td->thread_hnd);
}
else {
if(td->thread_hnd != curl_thread_t_null)
Curl_thread_join(&td->thread_hnd);
destroy_thread_sync_data(&td->tsd);
free(async->os_specific);
}
}
async->os_specific = NULL;
if(async->hostname)
free(async->hostname);
async->hostname = 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 struct addrinfo *hints)
{
struct thread_data *td = calloc(1, sizeof(struct thread_data));
int err = RESOLVER_ENOMEM;
conn->async.os_specific = (void*) td;
if(!td)
goto err_exit;
conn->async.port = port;
conn->async.done = FALSE;
conn->async.status = 0;
conn->async.dns = NULL;
td->thread_hnd = curl_thread_t_null;
if(!init_thread_sync_data(td, hostname, port, hints))
goto err_exit;
Curl_safefree(conn->async.hostname);
conn->async.hostname = strdup(hostname);
if(!conn->async.hostname)
goto err_exit;
#ifdef HAVE_GETADDRINFO
td->thread_hnd = Curl_thread_create(getaddrinfo_thread, &td->tsd);
#else
td->thread_hnd = Curl_thread_create(gethostbyname_thread, &td->tsd);
#endif
if(!td->thread_hnd) {
#ifndef _WIN32_WCE
err = errno;
#endif
goto err_exit;
}
return TRUE;
err_exit:
destroy_async_data(&conn->async);
SET_ERRNO(err);
return FALSE;
}
/*
* resolver_error() calls failf() with the appropriate message after a resolve
* error
*/
static CURLcode resolver_error(struct connectdata *conn)
{
const char *host_or_proxy;
CURLcode rc;
if(conn->bits.httpproxy) {
host_or_proxy = "proxy";
rc = CURLE_COULDNT_RESOLVE_PROXY;
}
else {
host_or_proxy = "host";
rc = CURLE_COULDNT_RESOLVE_HOST;
}
failf(conn->data, "Could not resolve %s: %s", host_or_proxy,
conn->async.hostname);
return rc;
}
/*
* Curl_resolver_wait_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_resolver_wait_resolv(struct connectdata *conn,
struct Curl_dns_entry **entry)
{
struct thread_data *td = (struct thread_data*) conn->async.os_specific;
CURLcode rc = CURLE_OK;
DEBUGASSERT(conn && td);
/* wait for the thread to resolve the name */
if(Curl_thread_join(&td->thread_hnd))
rc = getaddrinfo_complete(conn);
else
DEBUGASSERT(0);
conn->async.done = TRUE;
if(entry)
*entry = conn->async.dns;
if(!conn->async.dns)
/* a name was not resolved, report error */
rc = resolver_error(conn);
destroy_async_data(&conn->async);
if(!conn->async.dns)
connclose(conn, "asynch resolve failed");
return (rc);
}
/*
* Curl_resolver_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_resolver_is_resolved(struct connectdata *conn,
struct Curl_dns_entry **entry)
{
struct SessionHandle *data = conn->data;
struct thread_data *td = (struct thread_data*) conn->async.os_specific;
int done = 0;
*entry = NULL;
if(!td) {
DEBUGASSERT(td);
return CURLE_COULDNT_RESOLVE_HOST;
}
Curl_mutex_acquire(td->tsd.mtx);
done = td->tsd.done;
Curl_mutex_release(td->tsd.mtx);
if(done) {
getaddrinfo_complete(conn);
if(!conn->async.dns) {
CURLcode rc = resolver_error(conn);
destroy_async_data(&conn->async);
return rc;
}
destroy_async_data(&conn->async);
*entry = conn->async.dns;
}
else {
/* poll for name lookup done with exponential backoff up to 250ms */
long elapsed = Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle);
if(elapsed < 0)
elapsed = 0;
if(td->poll_interval == 0)
/* Start at 1ms poll interval */
td->poll_interval = 1;
else if(elapsed >= td->interval_end)
/* Back-off exponentially if last interval expired */
td->poll_interval *= 2;
if(td->poll_interval > 250)
td->poll_interval = 250;
td->interval_end = elapsed + td->poll_interval;
Curl_expire_latest(conn->data, td->poll_interval);
}
return CURLE_OK;
}
int Curl_resolver_getsock(struct connectdata *conn,
curl_socket_t *socks,
int numsocks)
{
(void)conn;
(void)socks;
(void)numsocks;
return 0;
}
#ifndef HAVE_GETADDRINFO
/*
* Curl_getaddrinfo() - for platforms without getaddrinfo
*/
Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
const char *hostname,
int port,
int *waitp)
{
struct in_addr in;
*waitp = 0; /* default to synchronous response */
if(Curl_inet_pton(AF_INET, hostname, &in) > 0)
/* This is a dotted IP address 123.123.123.123-style */
return Curl_ip2addr(AF_INET, &in, hostname, port);
/* fire up a new resolver thread! */
if(init_resolve_thread(conn, hostname, port, NULL)) {
*waitp = 1; /* expect asynchronous response */
return NULL;
}
/* fall-back to blocking version */
return Curl_ipv4_resolve_r(hostname, port);
}
#else /* !HAVE_GETADDRINFO */
/*
* Curl_resolver_getaddrinfo() - for getaddrinfo
*/
Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
const char *hostname,
int port,
int *waitp)
{
struct addrinfo hints;
struct in_addr in;
Curl_addrinfo *res;
int error;
char sbuf[12];
int pf = PF_INET;
#ifdef CURLRES_IPV6
struct in6_addr in6;
#endif /* CURLRES_IPV6 */
*waitp = 0; /* default to synchronous response */
/* First check if this is an IPv4 address string */
if(Curl_inet_pton(AF_INET, hostname, &in) > 0)
/* This is a dotted IP address 123.123.123.123-style */
return Curl_ip2addr(AF_INET, &in, hostname, port);
#ifdef CURLRES_IPV6
/* check if this is an IPv6 address string */
if(Curl_inet_pton (AF_INET6, hostname, &in6) > 0)
/* This is an IPv6 address literal */
return Curl_ip2addr(AF_INET6, &in6, hostname, port);
/*
* Check if a limited name resolve has been requested.
*/
switch(conn->ip_version) {
case CURL_IPRESOLVE_V4:
pf = PF_INET;
break;
case CURL_IPRESOLVE_V6:
pf = PF_INET6;
break;
default:
pf = PF_UNSPEC;
break;
}
if((pf != PF_INET) && !Curl_ipv6works())
/* the stack seems to be a non-ipv6 one */
pf = PF_INET;
#endif /* CURLRES_IPV6 */
memset(&hints, 0, sizeof(hints));
hints.ai_family = pf;
hints.ai_socktype = conn->socktype;
snprintf(sbuf, sizeof(sbuf), "%d", port);
/* fire up a new resolver thread! */
if(init_resolve_thread(conn, hostname, port, &hints)) {
*waitp = 1; /* expect asynchronous response */
return NULL;
}
/* fall-back to blocking version */
infof(conn->data, "init_resolve_thread() failed for %s; %s\n",
hostname, Curl_strerror(conn, ERRNO));
error = Curl_getaddrinfo_ex(hostname, sbuf, &hints, &res);
if(error) {
infof(conn->data, "getaddrinfo() failed for %s:%d; %s\n",
hostname, port, Curl_strerror(conn, SOCKERRNO));
return NULL;
}
return res;
}
#endif /* !HAVE_GETADDRINFO */
CURLcode Curl_set_dns_servers(struct SessionHandle *data,
char *servers)
{
(void)data;
(void)servers;
return CURLE_NOT_BUILT_IN;
}
CURLcode Curl_set_dns_interface(struct SessionHandle *data,
const char *interf)
{
(void)data;
(void)interf;
return CURLE_NOT_BUILT_IN;
}
CURLcode Curl_set_dns_local_ip4(struct SessionHandle *data,
const char *local_ip4)
{
(void)data;
(void)local_ip4;
return CURLE_NOT_BUILT_IN;
}
CURLcode Curl_set_dns_local_ip6(struct SessionHandle *data,
const char *local_ip6)
{
(void)data;
(void)local_ip6;
return CURLE_NOT_BUILT_IN;
}
#endif /* CURLRES_THREADED */

168
Utilities/cmcurl/lib/asyn.h Normal file
View File

@ -0,0 +1,168 @@
#ifndef HEADER_CURL_ASYN_H
#define HEADER_CURL_ASYN_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute 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 "curl_setup.h"
#include "curl_addrinfo.h"
struct addrinfo;
struct hostent;
struct SessionHandle;
struct connectdata;
struct Curl_dns_entry;
/*
* This header defines all functions in the internal asynch resolver interface.
* All asynch resolvers need to provide these functions.
* asyn-ares.c and asyn-thread.c are the current implementations of asynch
* resolver backends.
*/
/*
* Curl_resolver_global_init()
*
* Called from curl_global_init() to initialize global resolver environment.
* Returning anything else than CURLE_OK fails curl_global_init().
*/
int Curl_resolver_global_init(void);
/*
* Curl_resolver_global_cleanup()
* Called from curl_global_cleanup() to destroy global resolver environment.
*/
void Curl_resolver_global_cleanup(void);
/*
* Curl_resolver_init()
* Called from curl_easy_init() -> Curl_open() to initialize resolver
* URL-state specific environment ('resolver' member of the UrlState
* structure). Should fill the passed pointer by the initialized handler.
* Returning anything else than CURLE_OK fails curl_easy_init() with the
* correspondent code.
*/
CURLcode Curl_resolver_init(void **resolver);
/*
* Curl_resolver_cleanup()
* Called from curl_easy_cleanup() -> Curl_close() to cleanup resolver
* URL-state specific environment ('resolver' member of the UrlState
* structure). Should destroy the handler and free all resources connected to
* it.
*/
void Curl_resolver_cleanup(void *resolver);
/*
* Curl_resolver_duphandle()
* Called from curl_easy_duphandle() to duplicate resolver URL-state specific
* environment ('resolver' member of the UrlState structure). Should
* duplicate the 'from' handle and pass the resulting handle to the 'to'
* pointer. Returning anything else than CURLE_OK causes failed
* curl_easy_duphandle() call.
*/
int Curl_resolver_duphandle(void **to, void *from);
/*
* Curl_resolver_cancel().
*
* It is called from inside other functions to cancel currently performing
* resolver request. Should also free any temporary resources allocated to
* perform a request.
*/
void Curl_resolver_cancel(struct connectdata *conn);
/* Curl_resolver_getsock()
*
* This function is called from the multi_getsock() function. 'sock' is a
* pointer to an array to hold the file descriptors, with 'numsock' being the
* size of that array (in number of entries). This function is supposed to
* return bitmask indicating what file descriptors (referring to array indexes
* in the 'sock' array) to wait for, read/write.
*/
int Curl_resolver_getsock(struct connectdata *conn, curl_socket_t *sock,
int numsocks);
/*
* Curl_resolver_is_resolved()
*
* 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_resolver_is_resolved(struct connectdata *conn,
struct Curl_dns_entry **dns);
/*
* Curl_resolver_wait_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_resolver_wait_resolv(struct connectdata *conn,
struct Curl_dns_entry **dnsentry);
/*
* Curl_resolver_getaddrinfo() - when using this resolver
*
* 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.
*
* Each resolver backend must of course make sure to return data in the
* correct format to comply with this.
*/
Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
const char *hostname,
int port,
int *waitp);
#ifndef CURLRES_ASYNCH
/* convert these functions if an asynch resolver isn't used */
#define Curl_resolver_cancel(x) Curl_nop_stmt
#define Curl_resolver_is_resolved(x,y) CURLE_COULDNT_RESOLVE_HOST
#define Curl_resolver_wait_resolv(x,y) CURLE_COULDNT_RESOLVE_HOST
#define Curl_resolver_getsock(x,y,z) 0
#define Curl_resolver_duphandle(x,y) CURLE_OK
#define Curl_resolver_init(x) CURLE_OK
#define Curl_resolver_global_init() CURLE_OK
#define Curl_resolver_global_cleanup() Curl_nop_stmt
#define Curl_resolver_cleanup(x) Curl_nop_stmt
#endif
#ifdef CURLRES_ASYNCH
#define Curl_resolver_asynch() 1
#else
#define Curl_resolver_asynch() 0
#endif
/********** end of generic resolver interface functions *****************/
#endif /* HEADER_CURL_ASYN_H */

View File

@ -0,0 +1,314 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute 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.
*
***************************************************************************/
/* Base64 encoding/decoding */
#include "curl_setup.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
#include "urldata.h" /* for the SessionHandle definition */
#include "warnless.h"
#include "curl_base64.h"
#include "curl_memory.h"
#include "non-ascii.h"
/* include memdebug.h last */
#include "memdebug.h"
/* ---- Base64 Encoding/Decoding Table --- */
static const char base64[]=
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
/* The Base 64 encoding with an URL and filename safe alphabet, RFC 4648
section 5 */
static const char base64url[]=
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
static size_t decodeQuantum(unsigned char *dest, const char *src)
{
size_t padding = 0;
const char *s, *p;
unsigned long i, v, x = 0;
for(i = 0, s = src; i < 4; i++, s++) {
v = 0;
if(*s == '=') {
x = (x << 6);
padding++;
}
else {
p = base64;
while(*p && (*p != *s)) {
v++;
p++;
}
if(*p == *s)
x = (x << 6) + v;
else
return 0;
}
}
if(padding < 1)
dest[2] = curlx_ultouc(x & 0xFFUL);
x >>= 8;
if(padding < 2)
dest[1] = curlx_ultouc(x & 0xFFUL);
x >>= 8;
dest[0] = curlx_ultouc(x & 0xFFUL);
return 3 - padding;
}
/*
* Curl_base64_decode()
*
* Given a base64 NUL-terminated string at src, decode it and return a
* pointer in *outptr to a newly allocated memory area holding decoded
* data. Size of decoded data is returned in variable pointed by outlen.
*
* Returns CURLE_OK on success, otherwise specific error code. Function
* output shall not be considered valid unless CURLE_OK is returned.
*
* When decoded data length is 0, returns NULL in *outptr.
*
* @unittest: 1302
*/
CURLcode Curl_base64_decode(const char *src,
unsigned char **outptr, size_t *outlen)
{
size_t srclen = 0;
size_t length = 0;
size_t padding = 0;
size_t i;
size_t result;
size_t numQuantums;
size_t rawlen = 0;
unsigned char *pos;
unsigned char *newstr;
*outptr = NULL;
*outlen = 0;
srclen = strlen(src);
/* Check the length of the input string is valid */
if(!srclen || srclen % 4)
return CURLE_BAD_CONTENT_ENCODING;
/* Find the position of any = padding characters */
while((src[length] != '=') && src[length])
length++;
/* A maximum of two = padding characters is allowed */
if(src[length] == '=') {
padding++;
if(src[length + 1] == '=')
padding++;
}
/* Check the = padding characters weren't part way through the input */
if(length + padding != srclen)
return CURLE_BAD_CONTENT_ENCODING;
/* Calculate the number of quantums */
numQuantums = srclen / 4;
/* Calculate the size of the decoded string */
rawlen = (numQuantums * 3) - padding;
/* Allocate our buffer including room for a zero terminator */
newstr = malloc(rawlen + 1);
if(!newstr)
return CURLE_OUT_OF_MEMORY;
pos = newstr;
/* Decode the quantums */
for(i = 0; i < numQuantums; i++) {
result = decodeQuantum(pos, src);
if(!result) {
Curl_safefree(newstr);
return CURLE_BAD_CONTENT_ENCODING;
}
pos += result;
src += 4;
}
/* Zero terminate */
*pos = '\0';
/* Return the decoded data */
*outptr = newstr;
*outlen = rawlen;
return CURLE_OK;
}
static CURLcode base64_encode(const char *table64,
struct SessionHandle *data,
const char *inputbuff, size_t insize,
char **outptr, size_t *outlen)
{
CURLcode error;
unsigned char ibuf[3];
unsigned char obuf[4];
int i;
int inputparts;
char *output;
char *base64data;
char *convbuf = NULL;
const char *indata = inputbuff;
*outptr = NULL;
*outlen = 0;
if(0 == insize)
insize = strlen(indata);
base64data = output = malloc(insize*4/3+4);
if(NULL == output)
return CURLE_OUT_OF_MEMORY;
/*
* The base64 data needs to be created using the network encoding
* not the host encoding. And we can't change the actual input
* so we copy it to a buffer, translate it, and use that instead.
*/
error = Curl_convert_clone(data, indata, insize, &convbuf);
if(error) {
free(output);
return error;
}
if(convbuf)
indata = (char *)convbuf;
while(insize > 0) {
for(i = inputparts = 0; i < 3; i++) {
if(insize > 0) {
inputparts++;
ibuf[i] = (unsigned char) *indata;
indata++;
insize--;
}
else
ibuf[i] = 0;
}
obuf[0] = (unsigned char) ((ibuf[0] & 0xFC) >> 2);
obuf[1] = (unsigned char) (((ibuf[0] & 0x03) << 4) | \
((ibuf[1] & 0xF0) >> 4));
obuf[2] = (unsigned char) (((ibuf[1] & 0x0F) << 2) | \
((ibuf[2] & 0xC0) >> 6));
obuf[3] = (unsigned char) (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; /* return pointer to new data, allocated memory */
if(convbuf)
free(convbuf);
*outlen = strlen(base64data); /* return the length of the new data */
return CURLE_OK;
}
/*
* Curl_base64_encode()
*
* Given a pointer to an input buffer and an input size, encode it and
* return a pointer in *outptr to a newly allocated memory area holding
* encoded data. Size of encoded data is returned in variable pointed by
* outlen.
*
* Input length of 0 indicates input buffer holds a NUL-terminated string.
*
* Returns CURLE_OK on success, otherwise specific error code. Function
* output shall not be considered valid unless CURLE_OK is returned.
*
* When encoded data length is 0, returns NULL in *outptr.
*
* @unittest: 1302
*/
CURLcode Curl_base64_encode(struct SessionHandle *data,
const char *inputbuff, size_t insize,
char **outptr, size_t *outlen)
{
return base64_encode(base64, data, inputbuff, insize, outptr, outlen);
}
/*
* Curl_base64url_encode()
*
* Given a pointer to an input buffer and an input size, encode it and
* return a pointer in *outptr to a newly allocated memory area holding
* encoded data. Size of encoded data is returned in variable pointed by
* outlen.
*
* Input length of 0 indicates input buffer holds a NUL-terminated string.
*
* Returns CURLE_OK on success, otherwise specific error code. Function
* output shall not be considered valid unless CURLE_OK is returned.
*
* When encoded data length is 0, returns NULL in *outptr.
*
* @unittest: 1302
*/
CURLcode Curl_base64url_encode(struct SessionHandle *data,
const char *inputbuff, size_t insize,
char **outptr, size_t *outlen)
{
return base64_encode(base64url, data, inputbuff, insize, outptr, outlen);
}
/* ---- End of Base64 Encoding ---- */

View File

@ -0,0 +1,110 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2012, Linus Nielsen Feltzing, <linus@haxx.se>
* Copyright (C) 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute 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 "curl_setup.h"
#include <curl/curl.h>
#include "urldata.h"
#include "url.h"
#include "progress.h"
#include "multiif.h"
#include "bundles.h"
#include "sendf.h"
#include "rawstr.h"
#include "curl_memory.h"
/* The last #include file should be: */
#include "memdebug.h"
static void conn_llist_dtor(void *user, void *element)
{
struct connectdata *data = element;
(void)user;
data->bundle = NULL;
}
CURLcode Curl_bundle_create(struct SessionHandle *data,
struct connectbundle **cb_ptr)
{
(void)data;
DEBUGASSERT(*cb_ptr == NULL);
*cb_ptr = malloc(sizeof(struct connectbundle));
if(!*cb_ptr)
return CURLE_OUT_OF_MEMORY;
(*cb_ptr)->num_connections = 0;
(*cb_ptr)->server_supports_pipelining = FALSE;
(*cb_ptr)->conn_list = Curl_llist_alloc((curl_llist_dtor) conn_llist_dtor);
if(!(*cb_ptr)->conn_list) {
Curl_safefree(*cb_ptr);
return CURLE_OUT_OF_MEMORY;
}
return CURLE_OK;
}
void Curl_bundle_destroy(struct connectbundle *cb_ptr)
{
if(!cb_ptr)
return;
if(cb_ptr->conn_list) {
Curl_llist_destroy(cb_ptr->conn_list, NULL);
cb_ptr->conn_list = NULL;
}
Curl_safefree(cb_ptr);
}
/* Add a connection to a bundle */
CURLcode Curl_bundle_add_conn(struct connectbundle *cb_ptr,
struct connectdata *conn)
{
if(!Curl_llist_insert_next(cb_ptr->conn_list, cb_ptr->conn_list->tail, conn))
return CURLE_OUT_OF_MEMORY;
conn->bundle = cb_ptr;
cb_ptr->num_connections++;
return CURLE_OK;
}
/* Remove a connection from a bundle */
int Curl_bundle_remove_conn(struct connectbundle *cb_ptr,
struct connectdata *conn)
{
struct curl_llist_element *curr;
curr = cb_ptr->conn_list->head;
while(curr) {
if(curr->ptr == conn) {
Curl_llist_remove(cb_ptr->conn_list, curr, NULL);
cb_ptr->num_connections--;
conn->bundle = NULL;
return 1; /* we removed a handle */
}
curr = curr->next;
}
return 0;
}

View File

@ -1,5 +1,5 @@
#ifndef __SELECT_H
#define __SELECT_H
#ifndef HEADER_CURL_BUNDLES_H
#define HEADER_CURL_BUNDLES_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 2012, Linus Nielsen Feltzing, <linus@haxx.se>
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@ -20,41 +20,26 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* $Id$
***************************************************************************/
#ifdef HAVE_SYS_POLL_H
#include <sys/poll.h>
#else
#ifndef POLLIN
#define POLLIN 0x01
#define POLLPRI 0x02
#define POLLOUT 0x04
#define POLLERR 0x08
#define POLLHUP 0x10
#define POLLNVAL 0x20
struct pollfd
{
curl_socket_t fd;
short events;
short revents;
struct connectbundle {
bool server_supports_pipelining; /* TRUE if server supports pipelining,
set after first response */
size_t num_connections; /* Number of connections in the bundle */
struct curl_llist *conn_list; /* The connectdata members of the bundle */
};
#endif
#endif
CURLcode Curl_bundle_create(struct SessionHandle *data,
struct connectbundle **cb_ptr);
#define CSELECT_IN 0x01
#define CSELECT_OUT 0x02
#define CSELECT_ERR 0x04
void Curl_bundle_destroy(struct connectbundle *cb_ptr);
int Curl_select(curl_socket_t readfd, curl_socket_t writefd, int timeout_ms);
CURLcode Curl_bundle_add_conn(struct connectbundle *cb_ptr,
struct connectdata *conn);
int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms);
int Curl_bundle_remove_conn(struct connectbundle *cb_ptr,
struct connectdata *conn);
#ifdef TPF
int tpf_select_libcurl(int maxfds, fd_set* reads, fd_set* writes,
fd_set* excepts, struct timeval* tv);
#endif
#endif
#endif /* HEADER_CURL_BUNDLES_H */

View File

@ -0,0 +1,283 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2012, Linus Nielsen Feltzing, <linus@haxx.se>
* Copyright (C) 2012 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute 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 "curl_setup.h"
#include <curl/curl.h>
#include "urldata.h"
#include "url.h"
#include "progress.h"
#include "multiif.h"
#include "sendf.h"
#include "rawstr.h"
#include "bundles.h"
#include "conncache.h"
#include "curl_memory.h"
/* The last #include file should be: */
#include "memdebug.h"
static void free_bundle_hash_entry(void *freethis)
{
struct connectbundle *b = (struct connectbundle *) freethis;
Curl_bundle_destroy(b);
}
struct conncache *Curl_conncache_init(int size)
{
struct conncache *connc;
connc = calloc(1, sizeof(struct conncache));
if(!connc)
return NULL;
connc->hash = Curl_hash_alloc(size, Curl_hash_str,
Curl_str_key_compare, free_bundle_hash_entry);
if(!connc->hash) {
free(connc);
return NULL;
}
return connc;
}
void Curl_conncache_destroy(struct conncache *connc)
{
if(connc) {
Curl_hash_destroy(connc->hash);
connc->hash = NULL;
free(connc);
}
}
struct connectbundle *Curl_conncache_find_bundle(struct conncache *connc,
char *hostname)
{
struct connectbundle *bundle = NULL;
if(connc)
bundle = Curl_hash_pick(connc->hash, hostname, strlen(hostname)+1);
return bundle;
}
static bool conncache_add_bundle(struct conncache *connc,
char *hostname,
struct connectbundle *bundle)
{
void *p;
p = Curl_hash_add(connc->hash, hostname, strlen(hostname)+1, bundle);
return p?TRUE:FALSE;
}
static void conncache_remove_bundle(struct conncache *connc,
struct connectbundle *bundle)
{
struct curl_hash_iterator iter;
struct curl_hash_element *he;
if(!connc)
return;
Curl_hash_start_iterate(connc->hash, &iter);
he = Curl_hash_next_element(&iter);
while(he) {
if(he->ptr == bundle) {
/* The bundle is destroyed by the hash destructor function,
free_bundle_hash_entry() */
Curl_hash_delete(connc->hash, he->key, he->key_len);
return;
}
he = Curl_hash_next_element(&iter);
}
}
CURLcode Curl_conncache_add_conn(struct conncache *connc,
struct connectdata *conn)
{
CURLcode result;
struct connectbundle *bundle;
struct connectbundle *new_bundle = NULL;
struct SessionHandle *data = conn->data;
bundle = Curl_conncache_find_bundle(data->state.conn_cache,
conn->host.name);
if(!bundle) {
result = Curl_bundle_create(data, &new_bundle);
if(result != CURLE_OK)
return result;
if(!conncache_add_bundle(data->state.conn_cache,
conn->host.name, new_bundle)) {
Curl_bundle_destroy(new_bundle);
return CURLE_OUT_OF_MEMORY;
}
bundle = new_bundle;
}
result = Curl_bundle_add_conn(bundle, conn);
if(result != CURLE_OK) {
if(new_bundle)
conncache_remove_bundle(data->state.conn_cache, new_bundle);
return result;
}
conn->connection_id = connc->next_connection_id++;
connc->num_connections++;
return CURLE_OK;
}
void Curl_conncache_remove_conn(struct conncache *connc,
struct connectdata *conn)
{
struct connectbundle *bundle = conn->bundle;
/* The bundle pointer can be NULL, since this function can be called
due to a failed connection attempt, before being added to a bundle */
if(bundle) {
Curl_bundle_remove_conn(bundle, conn);
if(bundle->num_connections == 0) {
conncache_remove_bundle(connc, bundle);
}
if(connc) {
connc->num_connections--;
DEBUGF(infof(conn->data, "The cache now contains %d members\n",
connc->num_connections));
}
}
}
/* This function iterates the entire connection cache and calls the
function func() with the connection pointer as the first argument
and the supplied 'param' argument as the other,
Return 0 from func() to continue the loop, return 1 to abort it.
*/
void Curl_conncache_foreach(struct conncache *connc,
void *param,
int (*func)(struct connectdata *conn, void *param))
{
struct curl_hash_iterator iter;
struct curl_llist_element *curr;
struct curl_hash_element *he;
if(!connc)
return;
Curl_hash_start_iterate(connc->hash, &iter);
he = Curl_hash_next_element(&iter);
while(he) {
struct connectbundle *bundle;
struct connectdata *conn;
bundle = he->ptr;
he = Curl_hash_next_element(&iter);
curr = bundle->conn_list->head;
while(curr) {
/* Yes, we need to update curr before calling func(), because func()
might decide to remove the connection */
conn = curr->ptr;
curr = curr->next;
if(1 == func(conn, param))
return;
}
}
}
/* Return the first connection found in the cache. Used when closing all
connections */
struct connectdata *
Curl_conncache_find_first_connection(struct conncache *connc)
{
struct curl_hash_iterator iter;
struct curl_llist_element *curr;
struct curl_hash_element *he;
struct connectbundle *bundle;
Curl_hash_start_iterate(connc->hash, &iter);
he = Curl_hash_next_element(&iter);
while(he) {
bundle = he->ptr;
curr = bundle->conn_list->head;
if(curr) {
return curr->ptr;
}
he = Curl_hash_next_element(&iter);
}
return NULL;
}
#if 0
/* Useful for debugging the connection cache */
void Curl_conncache_print(struct conncache *connc)
{
struct curl_hash_iterator iter;
struct curl_llist_element *curr;
struct curl_hash_element *he;
if(!connc)
return;
fprintf(stderr, "=Bundle cache=\n");
Curl_hash_start_iterate(connc->hash, &iter);
he = Curl_hash_next_element(&iter);
while(he) {
struct connectbundle *bundle;
struct connectdata *conn;
bundle = he->ptr;
fprintf(stderr, "%s -", he->key);
curr = bundle->conn_list->head;
while(curr) {
conn = curr->ptr;
fprintf(stderr, " [%p %d]", (void *)conn, conn->inuse);
curr = curr->next;
}
fprintf(stderr, "\n");
he = Curl_hash_next_element(&iter);
}
}
#endif

View File

@ -0,0 +1,55 @@
#ifndef HEADER_CURL_CONNCACHE_H
#define HEADER_CURL_CONNCACHE_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2012 - 2014, Linus Nielsen Feltzing, <linus@haxx.se>
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute 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.
*
***************************************************************************/
struct conncache {
struct curl_hash *hash;
size_t num_connections;
long next_connection_id;
struct timeval last_cleanup;
};
struct conncache *Curl_conncache_init(int size);
void Curl_conncache_destroy(struct conncache *connc);
struct connectbundle *Curl_conncache_find_bundle(struct conncache *connc,
char *hostname);
CURLcode Curl_conncache_add_conn(struct conncache *connc,
struct connectdata *conn);
void Curl_conncache_remove_conn(struct conncache *connc,
struct connectdata *conn);
void Curl_conncache_foreach(struct conncache *connc,
void *param,
int (*func)(struct connectdata *conn,
void *param));
struct connectdata *
Curl_conncache_find_first_connection(struct conncache *connc);
void Curl_conncache_print(struct conncache *connc);
#endif /* HEADER_CURL_CONNCACHE_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,122 @@
#ifndef HEADER_CURL_CONNECT_H
#define HEADER_CURL_CONNECT_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute 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 "curl_setup.h"
#include "nonblock.h" /* for curlx_nonblock(), formerly Curl_nonblock() */
#include "sockaddr.h"
CURLcode Curl_is_connected(struct connectdata *conn,
int sockindex,
bool *connected);
CURLcode Curl_connecthost(struct connectdata *conn,
const struct Curl_dns_entry *host);
/* generic function that returns how much time there's left to run, according
to the timeouts set */
long Curl_timeleft(struct SessionHandle *data,
struct timeval *nowp,
bool duringconnect);
#define DEFAULT_CONNECT_TIMEOUT 300000 /* milliseconds == five minutes */
#define HAPPY_EYEBALLS_TIMEOUT 200 /* milliseconds to wait between
ipv4/ipv6 connection attempts */
/*
* Used to extract socket and connectdata struct for the most recent
* transfer on the given SessionHandle.
*
* The returned socket will be CURL_SOCKET_BAD in case of failure!
*/
curl_socket_t Curl_getconnectinfo(struct SessionHandle *data,
struct connectdata **connp);
#ifdef USE_WINSOCK
/* When you run a program that uses the Windows Sockets API, you may
experience slow performance when you copy data to a TCP server.
http://support.microsoft.com/kb/823764
Work-around: Make the Socket Send Buffer Size Larger Than the Program Send
Buffer Size
*/
void Curl_sndbufset(curl_socket_t sockfd);
#else
#define Curl_sndbufset(y) Curl_nop_stmt
#endif
void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd);
void Curl_persistconninfo(struct connectdata *conn);
int Curl_closesocket(struct connectdata *conn, curl_socket_t sock);
/*
* The Curl_sockaddr_ex structure is basically libcurl's external API
* curl_sockaddr structure with enough space available to directly hold any
* protocol-specific address structures. The variable declared here will be
* used to pass / receive data to/from the fopensocket callback if this has
* been set, before that, it is initialized from parameters.
*/
struct Curl_sockaddr_ex {
int family;
int socktype;
int protocol;
unsigned int addrlen;
union {
struct sockaddr addr;
struct Curl_sockaddr_storage buff;
} _sa_ex_u;
};
#define sa_addr _sa_ex_u.addr
/*
* Create a socket based on info from 'conn' and 'ai'.
*
* Fill in 'addr' and 'sockfd' accordingly if OK is returned. If the open
* socket callback is set, used that!
*
*/
CURLcode Curl_socket(struct connectdata *conn,
const Curl_addrinfo *ai,
struct Curl_sockaddr_ex *addr,
curl_socket_t *sockfd);
#ifdef CURLDEBUG
/*
* Curl_connclose() sets the bit.close bit to TRUE with an explanation.
* Nothing else.
*/
void Curl_conncontrol(struct connectdata *conn,
bool closeit,
const char *reason);
#define connclose(x,y) Curl_conncontrol(x,TRUE, y)
#define connkeep(x,y) Curl_conncontrol(x, FALSE, y)
#else /* if !CURLDEBUG */
#define connclose(x,y) (x)->bits.close = TRUE
#define connkeep(x,y) (x)->bits.close = FALSE
#endif
#endif /* HEADER_CURL_CONNECT_H */

View File

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@ -18,21 +18,17 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* $Id$
***************************************************************************/
#include "setup.h"
#include "curl_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 "memory.h"
#include "curl_memory.h"
#include "memdebug.h"
@ -40,7 +36,7 @@
(doing so will reduce code size slightly). */
#define OLD_ZLIB_SUPPORT 1
#define DSIZ 0x10000 /* buffer size for decompressed data */
#define DSIZ CURL_MAX_WRITE_SIZE /* buffer size for decompressed data */
#define GZIP_MAGIC_0 0x1f
#define GZIP_MAGIC_1 0x8b
@ -53,13 +49,20 @@
#define COMMENT 0x10 /* bit 4 set: file comment present */
#define RESERVED 0xE0 /* bits 5..7: reserved */
enum zlibState {
ZLIB_UNINIT, /* uninitialized */
ZLIB_INIT, /* initialized */
ZLIB_GZIP_HEADER, /* reading gzip header */
ZLIB_GZIP_INFLATING, /* inflating gzip stream */
ZLIB_INIT_GZIP /* initialized in transparent gzip mode */
};
static voidpf
zalloc_cb(voidpf opaque, unsigned int items, unsigned int size)
{
(void) opaque;
/* not a typo, keep it calloc() */
return (voidpf) calloc(items, size);
}
static void
zfree_cb(voidpf opaque, voidpf ptr)
{
(void) opaque;
free(ptr);
}
static CURLcode
process_zlib_error(struct connectdata *conn, z_stream *z)
@ -76,7 +79,7 @@ process_zlib_error(struct connectdata *conn, z_stream *z)
}
static CURLcode
exit_zlib(z_stream *z, bool *zlib_init, CURLcode result)
exit_zlib(z_stream *z, zlibInitState *zlib_init, CURLcode result)
{
inflateEnd(z);
*zlib_init = ZLIB_UNINIT;
@ -85,7 +88,7 @@ exit_zlib(z_stream *z, bool *zlib_init, CURLcode result)
static CURLcode
inflate_stream(struct connectdata *conn,
struct Curl_transfer_keeper *k)
struct SingleRequest *k)
{
int allow_restart = 1;
z_stream *z = &k->z; /* zlib state structure */
@ -97,7 +100,7 @@ inflate_stream(struct connectdata *conn,
/* Dynamically allocate a buffer for decompression because it's uncommonly
large to hold on the stack */
decomp = (char*)malloc(DSIZ);
decomp = malloc(DSIZ);
if(decomp == NULL) {
return exit_zlib(z, &k->zlib_init, CURLE_OUT_OF_MEMORY);
}
@ -112,7 +115,7 @@ inflate_stream(struct connectdata *conn,
status = inflate(z, Z_SYNC_FLUSH);
if(status == Z_OK || status == Z_STREAM_END) {
allow_restart = 0;
if(DSIZ - z->avail_out) {
if((DSIZ - z->avail_out) && (!k->ignorebody)) {
result = Curl_client_write(conn, CLIENTWRITE_BODY, decomp,
DSIZ - z->avail_out);
/* if !CURLE_OK, clean up, return */
@ -132,7 +135,9 @@ inflate_stream(struct connectdata *conn,
}
/* Done with these bytes, exit */
if (status == Z_OK && z->avail_in == 0) {
/* status is always Z_OK at this point! */
if(z->avail_in == 0) {
free(decomp);
return result;
}
@ -141,9 +146,10 @@ inflate_stream(struct connectdata *conn,
/* some servers seem to not generate zlib headers, so this is an attempt
to fix and continue anyway */
inflateReset(z);
(void) inflateEnd(z); /* don't care about the return code */
if(inflateInit2(z, -MAX_WBITS) != Z_OK) {
return process_zlib_error(conn, z);
free(decomp);
return exit_zlib(z, &k->zlib_init, process_zlib_error(conn, z));
}
z->next_in = orig_in;
z->avail_in = nread;
@ -160,18 +166,17 @@ inflate_stream(struct connectdata *conn,
CURLcode
Curl_unencode_deflate_write(struct connectdata *conn,
struct Curl_transfer_keeper *k,
struct SingleRequest *k,
ssize_t nread)
{
z_stream *z = &k->z; /* zlib state structure */
/* Initialize zlib? */
if(k->zlib_init == ZLIB_UNINIT) {
z->zalloc = (alloc_func)Z_NULL;
z->zfree = (free_func)Z_NULL;
z->opaque = 0;
z->next_in = NULL;
z->avail_in = 0;
memset(z, 0, sizeof(z_stream));
z->zalloc = (alloc_func)zalloc_cb;
z->zfree = (free_func)zfree_cb;
if(inflateInit(z) != Z_OK)
return process_zlib_error(conn, z);
k->zlib_init = ZLIB_INIT;
@ -255,7 +260,6 @@ static enum {
/* Skip over the NUL */
--len;
++data;
}
if(flags & HEAD_CRC) {
@ -263,7 +267,6 @@ static enum {
return GZIP_UNDERFLOW;
len -= 2;
data += 2;
}
*headerlen = totallen - len;
@ -273,18 +276,16 @@ static enum {
CURLcode
Curl_unencode_gzip_write(struct connectdata *conn,
struct Curl_transfer_keeper *k,
struct SingleRequest *k,
ssize_t nread)
{
z_stream *z = &k->z; /* zlib state structure */
/* Initialize zlib? */
if(k->zlib_init == ZLIB_UNINIT) {
z->zalloc = (alloc_func)Z_NULL;
z->zfree = (free_func)Z_NULL;
z->opaque = 0;
z->next_in = NULL;
z->avail_in = 0;
memset(z, 0, sizeof(z_stream));
z->zalloc = (alloc_func)zalloc_cb;
z->zfree = (free_func)zfree_cb;
if(strcmp(zlibVersion(), "1.2.0.4") >= 0) {
/* zlib ver. >= 1.2.0.4 supports transparent gzip decompressing */
@ -292,8 +293,8 @@ Curl_unencode_gzip_write(struct connectdata *conn,
return process_zlib_error(conn, z);
}
k->zlib_init = ZLIB_INIT_GZIP; /* Transparent gzip decompress state */
} else {
}
else {
/* we must parse the gzip header ourselves */
if(inflateInit2(z, -MAX_WBITS) != Z_OK) {
return process_zlib_error(conn, z);
@ -372,7 +373,7 @@ Curl_unencode_gzip_write(struct connectdata *conn,
ssize_t hlen;
unsigned char *oldblock = z->next_in;
z->avail_in += nread;
z->avail_in += (uInt)nread;
z->next_in = realloc(z->next_in, z->avail_in);
if(z->next_in == NULL) {
free(oldblock);
@ -421,4 +422,14 @@ Curl_unencode_gzip_write(struct connectdata *conn,
return inflate_stream(conn, k);
#endif
}
void Curl_unencode_cleanup(struct connectdata *conn)
{
struct SessionHandle *data = conn->data;
struct SingleRequest *k = &data->req;
z_stream *z = &k->z;
if(k->zlib_init != ZLIB_UNINIT)
(void) exit_zlib(z, &k->zlib_init, CURLE_OK);
}
#endif /* HAVE_LIBZ */

View File

@ -1,3 +1,5 @@
#ifndef HEADER_CURL_CONTENT_ENCODING_H
#define HEADER_CURL_CONTENT_ENCODING_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
@ -5,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@ -18,24 +20,29 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* $Id$
***************************************************************************/
#include "setup.h"
#include "curl_setup.h"
/*
* Comma-separated list all supported Content-Encodings ('identity' is implied)
*/
#ifdef HAVE_LIBZ
#define ALL_CONTENT_ENCODINGS "deflate, gzip"
/* force a cleanup */
void Curl_unencode_cleanup(struct connectdata *conn);
#else
#define ALL_CONTENT_ENCODINGS "identity"
#define Curl_unencode_cleanup(x) Curl_nop_stmt
#endif
CURLcode Curl_unencode_deflate_write(struct connectdata *conn,
struct Curl_transfer_keeper *k,
struct SingleRequest *req,
ssize_t nread);
CURLcode
Curl_unencode_gzip_write(struct connectdata *conn,
struct Curl_transfer_keeper *k,
struct SingleRequest *k,
ssize_t nread);
#endif /* HEADER_CURL_CONTENT_ENCODING_H */

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
#ifndef __COOKIE_H
#define __COOKIE_H
#ifndef HEADER_CURL_COOKIE_H
#define HEADER_CURL_COOKIE_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@ -20,17 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* $Id$
***************************************************************************/
#include <stdio.h>
#if defined(WIN32)
#include <time.h>
#else
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#endif
#include "curl_setup.h"
#include <curl/curl.h>
@ -38,7 +29,8 @@ struct Cookie {
struct Cookie *next; /* next in the chain */
char *name; /* <this> = value */
char *value; /* name = <this> */
char *path; /* path = <this> */
char *path; /* path = <this> which is in Set-Cookie: */
char *spath; /* sanitized cookie path */
char *domain; /* domain = <this> */
curl_off_t expires; /* expires = <this> */
char *expirestr; /* the plain text version */
@ -50,6 +42,7 @@ struct Cookie {
bool secure; /* whether the 'secure' keyword was used */
bool livecookie; /* updated from a server, not a stored file */
bool httponly; /* true if the httponly directive is present */
};
struct CookieInfo {
@ -84,24 +77,28 @@ struct SessionHandle;
*/
struct Cookie *Curl_cookie_add(struct SessionHandle *data,
struct CookieInfo *, bool header, char *line,
char *domain, char *path);
struct CookieInfo *, bool header, char *lineptr,
const char *domain, const 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 *);
struct Cookie *Curl_cookie_getlist(struct CookieInfo *, const char *,
const char *, bool);
void Curl_cookie_freelist(struct Cookie *cookies, bool cookiestoo);
void Curl_cookie_clearall(struct CookieInfo *cookies);
void Curl_cookie_clearsess(struct CookieInfo *cookies);
void Curl_cookie_cleanup(struct CookieInfo *);
int Curl_cookie_output(struct CookieInfo *, char *);
#if defined(CURL_DISABLE_HTTP) || defined(CURL_DISABLE_COOKIES)
#define Curl_cookie_list(x) NULL
#define Curl_cookie_loadfiles(x) do { } while (0)
#define Curl_cookie_loadfiles(x) Curl_nop_stmt
#define Curl_cookie_init(x,y,z,w) NULL
#define Curl_cookie_cleanup(x) Curl_nop_stmt
#define Curl_flush_cookies(x,y) Curl_nop_stmt
#else
void Curl_flush_cookies(struct SessionHandle *data, int cleanup);
void Curl_cookie_cleanup(struct CookieInfo *);
struct CookieInfo *Curl_cookie_init(struct SessionHandle *data,
const char *, struct CookieInfo *, bool);
struct curl_slist *Curl_cookie_list(struct SessionHandle *data);
void Curl_cookie_loadfiles(struct SessionHandle *data);
#endif
#endif
#endif /* HEADER_CURL_COOKIE_H */

View File

@ -0,0 +1,527 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute 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 "curl_setup.h"
#include <curl/curl.h>
#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 __VMS
# include <in.h>
# include <inet.h>
#endif
#if defined(NETWARE) && defined(__NOVELL_LIBC__)
# undef in_addr_t
# define in_addr_t unsigned long
#endif
#include "curl_addrinfo.h"
#include "inet_pton.h"
#include "warnless.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
#include "curl_memory.h"
/* The last #include file should be: */
#include "memdebug.h"
/*
* Curl_freeaddrinfo()
*
* This is used to free a linked list of Curl_addrinfo structs along
* with all its associated allocated storage. This function should be
* called once for each successful call to Curl_getaddrinfo_ex() or to
* any function call which actually allocates a Curl_addrinfo struct.
*/
#if defined(__INTEL_COMPILER) && (__INTEL_COMPILER == 910) && \
defined(__OPTIMIZE__) && defined(__unix__) && defined(__i386__)
/* workaround icc 9.1 optimizer issue */
# define vqualifier volatile
#else
# define vqualifier
#endif
void
Curl_freeaddrinfo(Curl_addrinfo *cahead)
{
Curl_addrinfo *vqualifier canext;
Curl_addrinfo *ca;
for(ca = cahead; ca != NULL; ca = canext) {
if(ca->ai_addr)
free(ca->ai_addr);
if(ca->ai_canonname)
free(ca->ai_canonname);
canext = ca->ai_next;
free(ca);
}
}
#ifdef HAVE_GETADDRINFO
/*
* Curl_getaddrinfo_ex()
*
* This is a wrapper function around system's getaddrinfo(), with
* the only difference that instead of returning a linked list of
* addrinfo structs this one returns a linked list of Curl_addrinfo
* ones. The memory allocated by this function *MUST* be free'd with
* Curl_freeaddrinfo(). For each successful call to this function
* there must be an associated call later to Curl_freeaddrinfo().
*
* There should be no single call to system's getaddrinfo() in the
* whole library, any such call should be 'routed' through this one.
*/
int
Curl_getaddrinfo_ex(const char *nodename,
const char *servname,
const struct addrinfo *hints,
Curl_addrinfo **result)
{
const struct addrinfo *ai;
struct addrinfo *aihead;
Curl_addrinfo *cafirst = NULL;
Curl_addrinfo *calast = NULL;
Curl_addrinfo *ca;
size_t ss_size;
int error;
*result = NULL; /* assume failure */
error = getaddrinfo(nodename, servname, hints, &aihead);
if(error)
return error;
/* traverse the addrinfo list */
for(ai = aihead; ai != NULL; ai = ai->ai_next) {
/* ignore elements with unsupported address family, */
/* settle family-specific sockaddr structure size. */
if(ai->ai_family == AF_INET)
ss_size = sizeof(struct sockaddr_in);
#ifdef ENABLE_IPV6
else if(ai->ai_family == AF_INET6)
ss_size = sizeof(struct sockaddr_in6);
#endif
else
continue;
/* ignore elements without required address info */
if((ai->ai_addr == NULL) || !(ai->ai_addrlen > 0))
continue;
/* ignore elements with bogus address size */
if((size_t)ai->ai_addrlen < ss_size)
continue;
if((ca = malloc(sizeof(Curl_addrinfo))) == NULL) {
error = EAI_MEMORY;
break;
}
/* copy each structure member individually, member ordering, */
/* size, or padding might be different for each platform. */
ca->ai_flags = ai->ai_flags;
ca->ai_family = ai->ai_family;
ca->ai_socktype = ai->ai_socktype;
ca->ai_protocol = ai->ai_protocol;
ca->ai_addrlen = (curl_socklen_t)ss_size;
ca->ai_addr = NULL;
ca->ai_canonname = NULL;
ca->ai_next = NULL;
if((ca->ai_addr = malloc(ss_size)) == NULL) {
error = EAI_MEMORY;
free(ca);
break;
}
memcpy(ca->ai_addr, ai->ai_addr, ss_size);
if(ai->ai_canonname != NULL) {
if((ca->ai_canonname = strdup(ai->ai_canonname)) == NULL) {
error = EAI_MEMORY;
free(ca->ai_addr);
free(ca);
break;
}
}
/* if the return list is empty, this becomes the first element */
if(!cafirst)
cafirst = ca;
/* add this element last in the return list */
if(calast)
calast->ai_next = ca;
calast = ca;
}
/* destroy the addrinfo list */
if(aihead)
freeaddrinfo(aihead);
/* if we failed, also destroy the Curl_addrinfo list */
if(error) {
Curl_freeaddrinfo(cafirst);
cafirst = NULL;
}
else if(!cafirst) {
#ifdef EAI_NONAME
/* rfc3493 conformant */
error = EAI_NONAME;
#else
/* rfc3493 obsoleted */
error = EAI_NODATA;
#endif
#ifdef USE_WINSOCK
SET_SOCKERRNO(error);
#endif
}
*result = cafirst;
/* This is not a CURLcode */
return error;
}
#endif /* HAVE_GETADDRINFO */
/*
* Curl_he2ai()
*
* This function returns a pointer to the first element of a newly allocated
* Curl_addrinfo struct linked list filled with the data of a given hostent.
* Curl_addrinfo is meant to work like the addrinfo struct does for a IPv6
* stack, but usable also for IPv4, all hosts and environments.
*
* The memory allocated by this function *MUST* be free'd later on calling
* Curl_freeaddrinfo(). For each successful call to this function there
* must be an associated call later to Curl_freeaddrinfo().
*
* Curl_addrinfo defined in "lib/curl_addrinfo.h"
*
* struct Curl_addrinfo {
* int ai_flags;
* int ai_family;
* int ai_socktype;
* int ai_protocol;
* curl_socklen_t ai_addrlen; * Follow rfc3493 struct addrinfo *
* char *ai_canonname;
* struct sockaddr *ai_addr;
* struct Curl_addrinfo *ai_next;
* };
* typedef struct Curl_addrinfo Curl_addrinfo;
*
* hostent defined in <netdb.h>
*
* struct hostent {
* char *h_name;
* char **h_aliases;
* int h_addrtype;
* int h_length;
* char **h_addr_list;
* };
*
* for backward compatibility:
*
* #define h_addr h_addr_list[0]
*/
Curl_addrinfo *
Curl_he2ai(const struct hostent *he, int port)
{
Curl_addrinfo *ai;
Curl_addrinfo *prevai = NULL;
Curl_addrinfo *firstai = NULL;
struct sockaddr_in *addr;
#ifdef ENABLE_IPV6
struct sockaddr_in6 *addr6;
#endif
CURLcode result = CURLE_OK;
int i;
char *curr;
if(!he)
/* no input == no output! */
return NULL;
DEBUGASSERT((he->h_name != NULL) && (he->h_addr_list != NULL));
for(i=0; (curr = he->h_addr_list[i]) != NULL; i++) {
size_t ss_size;
#ifdef ENABLE_IPV6
if(he->h_addrtype == AF_INET6)
ss_size = sizeof (struct sockaddr_in6);
else
#endif
ss_size = sizeof (struct sockaddr_in);
if((ai = calloc(1, sizeof(Curl_addrinfo))) == NULL) {
result = CURLE_OUT_OF_MEMORY;
break;
}
if((ai->ai_canonname = strdup(he->h_name)) == NULL) {
result = CURLE_OUT_OF_MEMORY;
free(ai);
break;
}
if((ai->ai_addr = calloc(1, ss_size)) == NULL) {
result = CURLE_OUT_OF_MEMORY;
free(ai->ai_canonname);
free(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 = he->h_addrtype;
/* we return all names as STREAM, so when using this address for TFTP
the type must be ignored and conn->socktype be used instead! */
ai->ai_socktype = SOCK_STREAM;
ai->ai_addrlen = (curl_socklen_t)ss_size;
/* leave the rest of the struct filled with zero */
switch (ai->ai_family) {
case AF_INET:
addr = (void *)ai->ai_addr; /* storage area for this info */
memcpy(&addr->sin_addr, curr, sizeof(struct in_addr));
addr->sin_family = (unsigned short)(he->h_addrtype);
addr->sin_port = htons((unsigned short)port);
break;
#ifdef ENABLE_IPV6
case AF_INET6:
addr6 = (void *)ai->ai_addr; /* storage area for this info */
memcpy(&addr6->sin6_addr, curr, sizeof(struct in6_addr));
addr6->sin6_family = (unsigned short)(he->h_addrtype);
addr6->sin6_port = htons((unsigned short)port);
break;
#endif
}
prevai = ai;
}
if(result != CURLE_OK) {
Curl_freeaddrinfo(firstai);
firstai = NULL;
}
return firstai;
}
struct namebuff {
struct hostent hostentry;
union {
struct in_addr ina4;
#ifdef ENABLE_IPV6
struct in6_addr ina6;
#endif
} addrentry;
char *h_addr_list[2];
};
/*
* Curl_ip2addr()
*
* This function takes an internet address, in binary form, as input parameter
* along with its address family and the string version of the address, and it
* returns a Curl_addrinfo chain filled in correctly with information for the
* given address/host
*/
Curl_addrinfo *
Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port)
{
Curl_addrinfo *ai;
#if defined(__VMS) && \
defined(__INITIAL_POINTER_SIZE) && (__INITIAL_POINTER_SIZE == 64)
#pragma pointer_size save
#pragma pointer_size short
#pragma message disable PTRMISMATCH
#endif
struct hostent *h;
struct namebuff *buf;
char *addrentry;
char *hoststr;
size_t addrsize;
DEBUGASSERT(inaddr && hostname);
buf = malloc(sizeof(struct namebuff));
if(!buf)
return NULL;
hoststr = strdup(hostname);
if(!hoststr) {
free(buf);
return NULL;
}
switch(af) {
case AF_INET:
addrsize = sizeof(struct in_addr);
addrentry = (void *)&buf->addrentry.ina4;
memcpy(addrentry, inaddr, sizeof(struct in_addr));
break;
#ifdef ENABLE_IPV6
case AF_INET6:
addrsize = sizeof(struct in6_addr);
addrentry = (void *)&buf->addrentry.ina6;
memcpy(addrentry, inaddr, sizeof(struct in6_addr));
break;
#endif
default:
free(hoststr);
free(buf);
return NULL;
}
h = &buf->hostentry;
h->h_name = hoststr;
h->h_aliases = NULL;
h->h_addrtype = (short)af;
h->h_length = (short)addrsize;
h->h_addr_list = &buf->h_addr_list[0];
h->h_addr_list[0] = addrentry;
h->h_addr_list[1] = NULL; /* terminate list of entries */
#if defined(__VMS) && \
defined(__INITIAL_POINTER_SIZE) && (__INITIAL_POINTER_SIZE == 64)
#pragma pointer_size restore
#pragma message enable PTRMISMATCH
#endif
ai = Curl_he2ai(h, port);
free(hoststr);
free(buf);
return ai;
}
/*
* Given an IPv4 or IPv6 dotted string address, this converts it to a proper
* allocated Curl_addrinfo struct and returns it.
*/
Curl_addrinfo *Curl_str2addr(char *address, int port)
{
struct in_addr in;
if(Curl_inet_pton(AF_INET, address, &in) > 0)
/* This is a dotted IP address 123.123.123.123-style */
return Curl_ip2addr(AF_INET, &in, address, port);
#ifdef ENABLE_IPV6
else {
struct in6_addr in6;
if(Curl_inet_pton(AF_INET6, address, &in6) > 0)
/* This is a dotted IPv6 address ::1-style */
return Curl_ip2addr(AF_INET6, &in6, address, port);
}
#endif
return NULL; /* bad input format */
}
#if defined(CURLDEBUG) && defined(HAVE_FREEADDRINFO)
/*
* curl_dofreeaddrinfo()
*
* This is 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 want to include in memdebug.c
*/
void
curl_dofreeaddrinfo(struct addrinfo *freethis,
int line, const char *source)
{
(freeaddrinfo)(freethis);
curl_memlog("ADDR %s:%d freeaddrinfo(%p)\n",
source, line, (void *)freethis);
}
#endif /* defined(CURLDEBUG) && defined(HAVE_FREEADDRINFO) */
#if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO)
/*
* curl_dogetaddrinfo()
*
* This is 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 want to include in memdebug.c
*/
int
curl_dogetaddrinfo(const char *hostname,
const char *service,
const struct addrinfo *hints,
struct addrinfo **result,
int line, const char *source)
{
int res=(getaddrinfo)(hostname, service, hints, result);
if(0 == res)
/* success */
curl_memlog("ADDR %s:%d getaddrinfo() = %p\n",
source, line, (void *)*result);
else
curl_memlog("ADDR %s:%d getaddrinfo() failed\n",
source, line);
return res;
}
#endif /* defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) */

View File

@ -0,0 +1,97 @@
#ifndef HEADER_CURL_ADDRINFO_H
#define HEADER_CURL_ADDRINFO_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute 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 "curl_setup.h"
#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 __VMS
# include <in.h>
# include <inet.h>
# include <stdlib.h>
#endif
/*
* Curl_addrinfo is our internal struct definition that we use to allow
* consistent internal handling of this data. We use this even when the
* system provides an addrinfo structure definition. And we use this for
* all sorts of IPv4 and IPV6 builds.
*/
struct Curl_addrinfo {
int ai_flags;
int ai_family;
int ai_socktype;
int ai_protocol;
curl_socklen_t ai_addrlen; /* Follow rfc3493 struct addrinfo */
char *ai_canonname;
struct sockaddr *ai_addr;
struct Curl_addrinfo *ai_next;
};
typedef struct Curl_addrinfo Curl_addrinfo;
void
Curl_freeaddrinfo(Curl_addrinfo *cahead);
#ifdef HAVE_GETADDRINFO
int
Curl_getaddrinfo_ex(const char *nodename,
const char *servname,
const struct addrinfo *hints,
Curl_addrinfo **result);
#endif
Curl_addrinfo *
Curl_he2ai(const struct hostent *he, int port);
Curl_addrinfo *
Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port);
Curl_addrinfo *Curl_str2addr(char *dotted, int port);
#if defined(CURLDEBUG) && defined(HAVE_FREEADDRINFO)
void
curl_dofreeaddrinfo(struct addrinfo *freethis,
int line, const char *source);
#endif
#if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO)
int
curl_dogetaddrinfo(const char *hostname,
const char *service,
const struct addrinfo *hints,
struct addrinfo **result,
int line, const char *source);
#endif
#endif /* HEADER_CURL_ADDRINFO_H */

View File

@ -0,0 +1,35 @@
#ifndef HEADER_CURL_BASE64_H
#define HEADER_CURL_BASE64_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute 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.
*
***************************************************************************/
CURLcode Curl_base64_encode(struct SessionHandle *data,
const char *inputbuff, size_t insize,
char **outptr, size_t *outlen);
CURLcode Curl_base64url_encode(struct SessionHandle *data,
const char *inputbuff, size_t insize,
char **outptr, size_t *outlen);
CURLcode Curl_base64_decode(const char *src,
unsigned char **outptr, size_t *outlen);
#endif /* HEADER_CURL_BASE64_H */

View File

@ -0,0 +1,961 @@
/* lib/curl_config.h.in. Generated somehow by cmake. */
/* when building libcurl itself */
#cmakedefine BUILDING_LIBCURL 1
/* Location of default ca bundle */
#cmakedefine CURL_CA_BUNDLE ${CURL_CA_BUNDLE}
/* Location of default ca path */
#cmakedefine CURL_CA_PATH ${CURL_CA_PATH}
/* to disable cookies support */
#cmakedefine CURL_DISABLE_COOKIES 1
/* to disable cryptographic authentication */
#cmakedefine CURL_DISABLE_CRYPTO_AUTH 1
/* to disable DICT */
#cmakedefine CURL_DISABLE_DICT 1
/* to disable FILE */
#cmakedefine CURL_DISABLE_FILE 1
/* to disable FTP */
#cmakedefine CURL_DISABLE_FTP 1
/* to disable HTTP */
#cmakedefine CURL_DISABLE_HTTP 1
/* to disable LDAP */
#cmakedefine CURL_DISABLE_LDAP 1
/* to disable LDAPS */
#cmakedefine CURL_DISABLE_LDAPS 1
/* to disable proxies */
#cmakedefine CURL_DISABLE_PROXY 1
/* to disable TELNET */
#cmakedefine CURL_DISABLE_TELNET 1
/* to disable TFTP */
#cmakedefine CURL_DISABLE_TFTP 1
/* to disable verbose strings */
#cmakedefine CURL_DISABLE_VERBOSE_STRINGS 1
/* to make a symbol visible */
#cmakedefine CURL_EXTERN_SYMBOL 1
/* Ensure using CURL_EXTERN_SYMBOL is possible */
#ifndef CURL_EXTERN_SYMBOL
#define CURL_EXTERN_SYMBOL
#endif
/* Use Windows LDAP implementation */
#cmakedefine CURL_LDAP_WIN 1
/* when not building a shared library */
#cmakedefine CURL_STATICLIB 1
/* Set to explicitly specify we don't want to use thread-safe functions */
#cmakedefine DISABLED_THREADSAFE 1
/* your Entropy Gathering Daemon socket pathname */
#cmakedefine EGD_SOCKET ${EGD_SOCKET}
/* Define if you want to enable IPv6 support */
#cmakedefine ENABLE_IPV6 1
/* Define to the type qualifier of arg 1 for getnameinfo. */
#cmakedefine GETNAMEINFO_QUAL_ARG1 ${GETNAMEINFO_QUAL_ARG1}
/* Define to the type of arg 1 for getnameinfo. */
#cmakedefine GETNAMEINFO_TYPE_ARG1 ${GETNAMEINFO_TYPE_ARG1}
/* Define to the type of arg 2 for getnameinfo. */
#cmakedefine GETNAMEINFO_TYPE_ARG2 ${GETNAMEINFO_TYPE_ARG2}
/* Define to the type of args 4 and 6 for getnameinfo. */
#cmakedefine GETNAMEINFO_TYPE_ARG46 ${GETNAMEINFO_TYPE_ARG46}
/* Define to the type of arg 7 for getnameinfo. */
#cmakedefine GETNAMEINFO_TYPE_ARG7 ${GETNAMEINFO_TYPE_ARG7}
/* Specifies the number of arguments to getservbyport_r */
#cmakedefine GETSERVBYPORT_R_ARGS ${GETSERVBYPORT_R_ARGS}
/* Specifies the size of the buffer to pass to getservbyport_r */
#cmakedefine GETSERVBYPORT_R_BUFSIZE ${GETSERVBYPORT_R_BUFSIZE}
/* Define to 1 if you have the alarm function. */
#cmakedefine HAVE_ALARM 1
/* Define to 1 if you have the <alloca.h> header file. */
#cmakedefine HAVE_ALLOCA_H 1
/* Define to 1 if you have the <arpa/inet.h> header file. */
#cmakedefine HAVE_ARPA_INET_H 1
/* Define to 1 if you have the <arpa/tftp.h> header file. */
#cmakedefine HAVE_ARPA_TFTP_H 1
/* Define to 1 if you have the <assert.h> header file. */
#cmakedefine HAVE_ASSERT_H 1
/* Define to 1 if you have the `basename' function. */
#cmakedefine HAVE_BASENAME 1
/* Define to 1 if bool is an available type. */
#cmakedefine HAVE_BOOL_T 1
/* Define to 1 if you have the clock_gettime function and monotonic timer. */
#cmakedefine HAVE_CLOCK_GETTIME_MONOTONIC 1
/* Define to 1 if you have the `closesocket' function. */
#cmakedefine HAVE_CLOSESOCKET 1
/* Define to 1 if you have the `CRYPTO_cleanup_all_ex_data' function. */
#cmakedefine HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 1
/* Define to 1 if you have the <crypto.h> header file. */
#cmakedefine HAVE_CRYPTO_H 1
/* Define to 1 if you have the <des.h> header file. */
#cmakedefine HAVE_DES_H 1
/* Define to 1 if you have the <dlfcn.h> header file. */
#cmakedefine HAVE_DLFCN_H 1
/* Define to 1 if you have the `ENGINE_load_builtin_engines' function. */
#cmakedefine HAVE_ENGINE_LOAD_BUILTIN_ENGINES 1
/* Define to 1 if you have the <errno.h> header file. */
#cmakedefine HAVE_ERRNO_H 1
/* Define to 1 if you have the <err.h> header file. */
#cmakedefine HAVE_ERR_H 1
/* Define to 1 if you have the fcntl function. */
#cmakedefine HAVE_FCNTL 1
/* Define to 1 if you have the <fcntl.h> header file. */
#cmakedefine HAVE_FCNTL_H 1
/* Define to 1 if you have a working fcntl O_NONBLOCK function. */
#cmakedefine HAVE_FCNTL_O_NONBLOCK 1
/* Define to 1 if you have the fdopen function. */
#cmakedefine HAVE_FDOPEN 1
/* Define to 1 if you have the `fork' function. */
#cmakedefine HAVE_FORK 1
/* Define to 1 if you have the freeaddrinfo function. */
#cmakedefine HAVE_FREEADDRINFO 1
/* Define to 1 if you have the freeifaddrs function. */
#cmakedefine HAVE_FREEIFADDRS 1
/* Define to 1 if you have the ftruncate function. */
#cmakedefine HAVE_FTRUNCATE 1
/* Define to 1 if you have a working getaddrinfo function. */
#cmakedefine HAVE_GETADDRINFO 1
/* Define to 1 if you have the `geteuid' function. */
#cmakedefine HAVE_GETEUID 1
/* Define to 1 if you have the gethostbyaddr function. */
#cmakedefine HAVE_GETHOSTBYADDR 1
/* Define to 1 if you have the gethostbyaddr_r function. */
#cmakedefine HAVE_GETHOSTBYADDR_R 1
/* gethostbyaddr_r() takes 5 args */
#cmakedefine HAVE_GETHOSTBYADDR_R_5 1
/* gethostbyaddr_r() takes 7 args */
#cmakedefine HAVE_GETHOSTBYADDR_R_7 1
/* gethostbyaddr_r() takes 8 args */
#cmakedefine HAVE_GETHOSTBYADDR_R_8 1
/* Define to 1 if you have the gethostbyname function. */
#cmakedefine HAVE_GETHOSTBYNAME 1
/* Define to 1 if you have the gethostbyname_r function. */
#cmakedefine HAVE_GETHOSTBYNAME_R 1
/* gethostbyname_r() takes 3 args */
#cmakedefine HAVE_GETHOSTBYNAME_R_3 1
/* gethostbyname_r() takes 5 args */
#cmakedefine HAVE_GETHOSTBYNAME_R_5 1
/* gethostbyname_r() takes 6 args */
#cmakedefine HAVE_GETHOSTBYNAME_R_6 1
/* Define to 1 if you have the gethostname function. */
#cmakedefine HAVE_GETHOSTNAME 1
/* Define to 1 if you have a working getifaddrs function. */
#cmakedefine HAVE_GETIFADDRS 1
/* Define to 1 if you have the getnameinfo function. */
#cmakedefine HAVE_GETNAMEINFO 1
/* Define to 1 if you have the `getpass_r' function. */
#cmakedefine HAVE_GETPASS_R 1
/* Define to 1 if you have the `getppid' function. */
#cmakedefine HAVE_GETPPID 1
/* Define to 1 if you have the `getprotobyname' function. */
#cmakedefine HAVE_GETPROTOBYNAME 1
/* Define to 1 if you have the `getpwuid' function. */
#cmakedefine HAVE_GETPWUID 1
/* Define to 1 if you have the `getrlimit' function. */
#cmakedefine HAVE_GETRLIMIT 1
/* Define to 1 if you have the getservbyport_r function. */
#cmakedefine HAVE_GETSERVBYPORT_R 1
/* Define to 1 if you have the `gettimeofday' function. */
#cmakedefine HAVE_GETTIMEOFDAY 1
/* Define to 1 if you have a working glibc-style strerror_r function. */
#cmakedefine HAVE_GLIBC_STRERROR_R 1
/* Define to 1 if you have a working gmtime_r function. */
#cmakedefine HAVE_GMTIME_R 1
/* if you have the gssapi libraries */
#cmakedefine HAVE_GSSAPI 1
/* Define to 1 if you have the <gssapi/gssapi_generic.h> header file. */
#cmakedefine HAVE_GSSAPI_GSSAPI_GENERIC_H 1
/* Define to 1 if you have the <gssapi/gssapi.h> header file. */
#cmakedefine HAVE_GSSAPI_GSSAPI_H 1
/* Define to 1 if you have the <gssapi/gssapi_krb5.h> header file. */
#cmakedefine HAVE_GSSAPI_GSSAPI_KRB5_H 1
/* if you have the GNU gssapi libraries */
#cmakedefine HAVE_GSSGNU 1
/* if you have the Heimdal gssapi libraries */
#cmakedefine HAVE_GSSHEIMDAL 1
/* if you have the MIT gssapi libraries */
#cmakedefine HAVE_GSSMIT 1
/* Define to 1 if you have the `idna_strerror' function. */
#cmakedefine HAVE_IDNA_STRERROR 1
/* Define to 1 if you have the `idn_free' function. */
#cmakedefine HAVE_IDN_FREE 1
/* Define to 1 if you have the <idn-free.h> header file. */
#cmakedefine HAVE_IDN_FREE_H 1
/* Define to 1 if you have the <ifaddrs.h> header file. */
#cmakedefine HAVE_IFADDRS_H 1
/* Define to 1 if you have the `inet_addr' function. */
#cmakedefine HAVE_INET_ADDR 1
/* Define to 1 if you have the inet_ntoa_r function. */
#cmakedefine HAVE_INET_NTOA_R 1
/* inet_ntoa_r() takes 2 args */
#cmakedefine HAVE_INET_NTOA_R_2 1
/* inet_ntoa_r() takes 3 args */
#cmakedefine HAVE_INET_NTOA_R_3 1
/* Define to 1 if you have a IPv6 capable working inet_ntop function. */
#cmakedefine HAVE_INET_NTOP 1
/* Define to 1 if you have a IPv6 capable working inet_pton function. */
#cmakedefine HAVE_INET_PTON 1
/* Define to 1 if you have the <inttypes.h> header file. */
#cmakedefine HAVE_INTTYPES_H 1
/* Define to 1 if you have the ioctl function. */
#cmakedefine HAVE_IOCTL 1
/* Define to 1 if you have the ioctlsocket function. */
#cmakedefine HAVE_IOCTLSOCKET 1
/* Define to 1 if you have the IoctlSocket camel case function. */
#cmakedefine HAVE_IOCTLSOCKET_CAMEL 1
/* Define to 1 if you have a working IoctlSocket camel case FIONBIO function.
*/
#cmakedefine HAVE_IOCTLSOCKET_CAMEL_FIONBIO 1
/* Define to 1 if you have a working ioctlsocket FIONBIO function. */
#cmakedefine HAVE_IOCTLSOCKET_FIONBIO 1
/* Define to 1 if you have a working ioctl FIONBIO function. */
#cmakedefine HAVE_IOCTL_FIONBIO 1
/* Define to 1 if you have a working ioctl SIOCGIFADDR function. */
#cmakedefine HAVE_IOCTL_SIOCGIFADDR 1
/* Define to 1 if you have the <io.h> header file. */
#cmakedefine HAVE_IO_H 1
/* if you have the Kerberos4 libraries (including -ldes) */
#cmakedefine HAVE_KRB4 1
/* Define to 1 if you have the `krb_get_our_ip_for_realm' function. */
#cmakedefine HAVE_KRB_GET_OUR_IP_FOR_REALM 1
/* Define to 1 if you have the <krb.h> header file. */
#cmakedefine HAVE_KRB_H 1
/* Define to 1 if you have the lber.h header file. */
#cmakedefine HAVE_LBER_H 1
/* Define to 1 if you have the ldapssl.h header file. */
#cmakedefine HAVE_LDAPSSL_H 1
/* Define to 1 if you have the ldap.h header file. */
#cmakedefine HAVE_LDAP_H 1
/* Use LDAPS implementation */
#cmakedefine HAVE_LDAP_SSL 1
/* Define to 1 if you have the ldap_ssl.h header file. */
#cmakedefine HAVE_LDAP_SSL_H 1
/* Define to 1 if you have the `ldap_url_parse' function. */
#cmakedefine HAVE_LDAP_URL_PARSE 1
/* Define to 1 if you have the <libgen.h> header file. */
#cmakedefine HAVE_LIBGEN_H 1
/* Define to 1 if you have the `idn' library (-lidn). */
#cmakedefine HAVE_LIBIDN 1
/* Define to 1 if you have the `resolv' library (-lresolv). */
#cmakedefine HAVE_LIBRESOLV 1
/* Define to 1 if you have the `resolve' library (-lresolve). */
#cmakedefine HAVE_LIBRESOLVE 1
/* Define to 1 if you have the `socket' library (-lsocket). */
#cmakedefine HAVE_LIBSOCKET 1
/* Define to 1 if you have the `ssh2' library (-lssh2). */
#cmakedefine HAVE_LIBSSH2 1
/* Define to 1 if libssh2 provides `libssh2_version'. */
#cmakedefine HAVE_LIBSSH2_VERSION 1
/* Define to 1 if libssh2 provides `libssh2_init'. */
#cmakedefine HAVE_LIBSSH2_INIT 1
/* Define to 1 if libssh2 provides `libssh2_exit'. */
#cmakedefine HAVE_LIBSSH2_EXIT 1
/* Define to 1 if libssh2 provides `libssh2_scp_send64'. */
#cmakedefine HAVE_LIBSSH2_SCP_SEND64 1
/* Define to 1 if libssh2 provides `libssh2_session_handshake'. */
#cmakedefine HAVE_LIBSSH2_SESSION_HANDSHAKE 1
/* Define to 1 if you have the <libssh2.h> header file. */
#cmakedefine HAVE_LIBSSH2_H 1
/* Define to 1 if you have the `ssl' library (-lssl). */
#cmakedefine HAVE_LIBSSL 1
/* if zlib is available */
#cmakedefine HAVE_LIBZ 1
/* Define to 1 if you have the <limits.h> header file. */
#cmakedefine HAVE_LIMITS_H 1
/* if your compiler supports LL */
#cmakedefine HAVE_LL 1
/* Define to 1 if you have the <locale.h> header file. */
#cmakedefine HAVE_LOCALE_H 1
/* Define to 1 if you have a working localtime_r function. */
#cmakedefine HAVE_LOCALTIME_R 1
/* Define to 1 if the compiler supports the 'long long' data type. */
#cmakedefine HAVE_LONGLONG 1
/* Define to 1 if you have the malloc.h header file. */
#cmakedefine HAVE_MALLOC_H 1
/* Define to 1 if you have the <memory.h> header file. */
#cmakedefine HAVE_MEMORY_H 1
/* Define to 1 if you have the MSG_NOSIGNAL flag. */
#cmakedefine HAVE_MSG_NOSIGNAL 1
/* Define to 1 if you have the <netdb.h> header file. */
#cmakedefine HAVE_NETDB_H 1
/* Define to 1 if you have the <netinet/in.h> header file. */
#cmakedefine HAVE_NETINET_IN_H 1
/* Define to 1 if you have the <netinet/tcp.h> header file. */
#cmakedefine HAVE_NETINET_TCP_H 1
/* Define to 1 if you have the <net/if.h> header file. */
#cmakedefine HAVE_NET_IF_H 1
/* Define to 1 if NI_WITHSCOPEID exists and works. */
#cmakedefine HAVE_NI_WITHSCOPEID 1
/* if you have an old MIT gssapi library, lacking GSS_C_NT_HOSTBASED_SERVICE */
#cmakedefine HAVE_OLD_GSSMIT 1
/* Define to 1 if you have the <openssl/crypto.h> header file. */
#cmakedefine HAVE_OPENSSL_CRYPTO_H 1
/* Define to 1 if you have the <openssl/engine.h> header file. */
#cmakedefine HAVE_OPENSSL_ENGINE_H 1
/* Define to 1 if you have the <openssl/err.h> header file. */
#cmakedefine HAVE_OPENSSL_ERR_H 1
/* Define to 1 if you have the <openssl/pem.h> header file. */
#cmakedefine HAVE_OPENSSL_PEM_H 1
/* Define to 1 if you have the <openssl/pkcs12.h> header file. */
#cmakedefine HAVE_OPENSSL_PKCS12_H 1
/* Define to 1 if you have the <openssl/rsa.h> header file. */
#cmakedefine HAVE_OPENSSL_RSA_H 1
/* Define to 1 if you have the <openssl/ssl.h> header file. */
#cmakedefine HAVE_OPENSSL_SSL_H 1
/* Define to 1 if you have the <openssl/x509.h> header file. */
#cmakedefine HAVE_OPENSSL_X509_H 1
/* Define to 1 if you have the <pem.h> header file. */
#cmakedefine HAVE_PEM_H 1
/* Define to 1 if you have the `perror' function. */
#cmakedefine HAVE_PERROR 1
/* Define to 1 if you have the `pipe' function. */
#cmakedefine HAVE_PIPE 1
/* Define to 1 if you have a working poll function. */
#cmakedefine HAVE_POLL 1
/* If you have a fine poll */
#cmakedefine HAVE_POLL_FINE 1
/* Define to 1 if you have the <poll.h> header file. */
#cmakedefine HAVE_POLL_H 1
/* Define to 1 if you have a working POSIX-style strerror_r function. */
#cmakedefine HAVE_POSIX_STRERROR_R 1
/* Define to 1 if you have the <pwd.h> header file. */
#cmakedefine HAVE_PWD_H 1
/* Define to 1 if you have the `RAND_egd' function. */
#cmakedefine HAVE_RAND_EGD 1
/* Define to 1 if you have the `RAND_screen' function. */
#cmakedefine HAVE_RAND_SCREEN 1
/* Define to 1 if you have the `RAND_status' function. */
#cmakedefine HAVE_RAND_STATUS 1
/* Define to 1 if you have the recv function. */
#cmakedefine HAVE_RECV 1
/* Define to 1 if you have the recvfrom function. */
#cmakedefine HAVE_RECVFROM 1
/* Define to 1 if you have the <rsa.h> header file. */
#cmakedefine HAVE_RSA_H 1
/* Define to 1 if you have the select function. */
#cmakedefine HAVE_SELECT 1
/* Define to 1 if you have the send function. */
#cmakedefine HAVE_SEND 1
/* Define to 1 if you have the <setjmp.h> header file. */
#cmakedefine HAVE_SETJMP_H 1
/* Define to 1 if you have the `setlocale' function. */
#cmakedefine HAVE_SETLOCALE 1
/* Define to 1 if you have the `setmode' function. */
#cmakedefine HAVE_SETMODE 1
/* Define to 1 if you have the `setrlimit' function. */
#cmakedefine HAVE_SETRLIMIT 1
/* Define to 1 if you have the setsockopt function. */
#cmakedefine HAVE_SETSOCKOPT 1
/* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */
#cmakedefine HAVE_SETSOCKOPT_SO_NONBLOCK 1
/* Define to 1 if you have the <sgtty.h> header file. */
#cmakedefine HAVE_SGTTY_H 1
/* Define to 1 if you have the sigaction function. */
#cmakedefine HAVE_SIGACTION 1
/* Define to 1 if you have the siginterrupt function. */
#cmakedefine HAVE_SIGINTERRUPT 1
/* Define to 1 if you have the signal function. */
#cmakedefine HAVE_SIGNAL 1
/* Define to 1 if you have the <signal.h> header file. */
#cmakedefine HAVE_SIGNAL_H 1
/* Define to 1 if you have the sigsetjmp function or macro. */
#cmakedefine HAVE_SIGSETJMP 1
/* Define to 1 if sig_atomic_t is an available typedef. */
#cmakedefine HAVE_SIG_ATOMIC_T 1
/* Define to 1 if sig_atomic_t is already defined as volatile. */
#cmakedefine HAVE_SIG_ATOMIC_T_VOLATILE 1
/* Define to 1 if struct sockaddr_in6 has the sin6_scope_id member */
#cmakedefine HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1
/* Define to 1 if you have the `socket' function. */
#cmakedefine HAVE_SOCKET 1
/* Define to 1 if you have the `SSL_get_shutdown' function. */
#cmakedefine HAVE_SSL_GET_SHUTDOWN 1
/* Define to 1 if you have the <ssl.h> header file. */
#cmakedefine HAVE_SSL_H 1
/* Define to 1 if you have the <stdbool.h> header file. */
#cmakedefine HAVE_STDBOOL_H 1
/* Define to 1 if you have the <stdint.h> header file. */
#cmakedefine HAVE_STDINT_H 1
/* Define to 1 if you have the <stdio.h> header file. */
#cmakedefine HAVE_STDIO_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#cmakedefine HAVE_STDLIB_H 1
/* Define to 1 if you have the strcasecmp function. */
#cmakedefine HAVE_STRCASECMP 1
/* Define to 1 if you have the strcasestr function. */
#cmakedefine HAVE_STRCASESTR 1
/* Define to 1 if you have the strcmpi function. */
#cmakedefine HAVE_STRCMPI 1
/* Define to 1 if you have the strdup function. */
#cmakedefine HAVE_STRDUP 1
/* Define to 1 if you have the strerror_r function. */
#cmakedefine HAVE_STRERROR_R 1
/* Define to 1 if you have the stricmp function. */
#cmakedefine HAVE_STRICMP 1
/* Define to 1 if you have the <strings.h> header file. */
#cmakedefine HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#cmakedefine HAVE_STRING_H 1
/* Define to 1 if you have the strlcat function. */
#cmakedefine HAVE_STRLCAT 1
/* Define to 1 if you have the `strlcpy' function. */
#cmakedefine HAVE_STRLCPY 1
/* Define to 1 if you have the strncasecmp function. */
#cmakedefine HAVE_STRNCASECMP 1
/* Define to 1 if you have the strncmpi function. */
#cmakedefine HAVE_STRNCMPI 1
/* Define to 1 if you have the strnicmp function. */
#cmakedefine HAVE_STRNICMP 1
/* Define to 1 if you have the <stropts.h> header file. */
#cmakedefine HAVE_STROPTS_H 1
/* Define to 1 if you have the strstr function. */
#cmakedefine HAVE_STRSTR 1
/* Define to 1 if you have the strtok_r function. */
#cmakedefine HAVE_STRTOK_R 1
/* Define to 1 if you have the strtoll function. */
#cmakedefine HAVE_STRTOLL 1
/* if struct sockaddr_storage is defined */
#cmakedefine HAVE_STRUCT_SOCKADDR_STORAGE 1
/* Define to 1 if you have the timeval struct. */
#cmakedefine HAVE_STRUCT_TIMEVAL 1
/* Define to 1 if you have the <sys/filio.h> header file. */
#cmakedefine HAVE_SYS_FILIO_H 1
/* Define to 1 if you have the <sys/ioctl.h> header file. */
#cmakedefine HAVE_SYS_IOCTL_H 1
/* Define to 1 if you have the <sys/param.h> header file. */
#cmakedefine HAVE_SYS_PARAM_H 1
/* Define to 1 if you have the <sys/poll.h> header file. */
#cmakedefine HAVE_SYS_POLL_H 1
/* Define to 1 if you have the <sys/resource.h> header file. */
#cmakedefine HAVE_SYS_RESOURCE_H 1
/* Define to 1 if you have the <sys/select.h> header file. */
#cmakedefine HAVE_SYS_SELECT_H 1
/* Define to 1 if you have the <sys/socket.h> header file. */
#cmakedefine HAVE_SYS_SOCKET_H 1
/* Define to 1 if you have the <sys/sockio.h> header file. */
#cmakedefine HAVE_SYS_SOCKIO_H 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#cmakedefine HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/time.h> header file. */
#cmakedefine HAVE_SYS_TIME_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#cmakedefine HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <sys/uio.h> header file. */
#cmakedefine HAVE_SYS_UIO_H 1
/* Define to 1 if you have the <sys/un.h> header file. */
#cmakedefine HAVE_SYS_UN_H 1
/* Define to 1 if you have the <sys/utime.h> header file. */
#cmakedefine HAVE_SYS_UTIME_H 1
/* Define to 1 if you have the <termios.h> header file. */
#cmakedefine HAVE_TERMIOS_H 1
/* Define to 1 if you have the <termio.h> header file. */
#cmakedefine HAVE_TERMIO_H 1
/* Define to 1 if you have the <time.h> header file. */
#cmakedefine HAVE_TIME_H 1
/* Define to 1 if you have the <tld.h> header file. */
#cmakedefine HAVE_TLD_H 1
/* Define to 1 if you have the `tld_strerror' function. */
#cmakedefine HAVE_TLD_STRERROR 1
/* Define to 1 if you have the `uname' function. */
#cmakedefine HAVE_UNAME 1
/* Define to 1 if you have the <unistd.h> header file. */
#cmakedefine HAVE_UNISTD_H 1
/* Define to 1 if you have the `utime' function. */
#cmakedefine HAVE_UTIME 1
/* Define to 1 if you have the <utime.h> header file. */
#cmakedefine HAVE_UTIME_H 1
/* Define to 1 if compiler supports C99 variadic macro style. */
#cmakedefine HAVE_VARIADIC_MACROS_C99 1
/* Define to 1 if compiler supports old gcc variadic macro style. */
#cmakedefine HAVE_VARIADIC_MACROS_GCC 1
/* Define to 1 if you have the winber.h header file. */
#cmakedefine HAVE_WINBER_H 1
/* Define to 1 if you have the windows.h header file. */
#cmakedefine HAVE_WINDOWS_H 1
/* Define to 1 if you have the winldap.h header file. */
#cmakedefine HAVE_WINLDAP_H 1
/* Define to 1 if you have the winsock2.h header file. */
#cmakedefine HAVE_WINSOCK2_H 1
/* Define to 1 if you have the winsock.h header file. */
#cmakedefine HAVE_WINSOCK_H 1
/* Define this symbol if your OS supports changing the contents of argv */
#cmakedefine HAVE_WRITABLE_ARGV 1
/* Define to 1 if you have the writev function. */
#cmakedefine HAVE_WRITEV 1
/* Define to 1 if you have the ws2tcpip.h header file. */
#cmakedefine HAVE_WS2TCPIP_H 1
/* Define to 1 if you have the <x509.h> header file. */
#cmakedefine HAVE_X509_H 1
/* Define if you have the <process.h> header file. */
#cmakedefine HAVE_PROCESS_H 1
/* if you have the zlib.h header file */
#cmakedefine HAVE_ZLIB_H 1
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#cmakedefine LT_OBJDIR ${LT_OBJDIR}
/* If you lack a fine basename() prototype */
#cmakedefine NEED_BASENAME_PROTO 1
/* Define to 1 if you need the lber.h header file even with ldap.h */
#cmakedefine NEED_LBER_H 1
/* Define to 1 if you need the malloc.h header file even with stdlib.h */
#cmakedefine NEED_MALLOC_H 1
/* Define to 1 if _REENTRANT preprocessor symbol must be defined. */
#cmakedefine NEED_REENTRANT 1
/* cpu-machine-OS */
#cmakedefine OS ${OS}
/* 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 to the type of arg 1 for recvfrom. */
#cmakedefine RECVFROM_TYPE_ARG1 ${RECVFROM_TYPE_ARG1}
/* Define to the type pointed by arg 2 for recvfrom. */
#cmakedefine RECVFROM_TYPE_ARG2 ${RECVFROM_TYPE_ARG2}
/* Define to 1 if the type pointed by arg 2 for recvfrom is void. */
#cmakedefine RECVFROM_TYPE_ARG2_IS_VOID 1
/* Define to the type of arg 3 for recvfrom. */
#cmakedefine RECVFROM_TYPE_ARG3 ${RECVFROM_TYPE_ARG3}
/* Define to the type of arg 4 for recvfrom. */
#cmakedefine RECVFROM_TYPE_ARG4 ${RECVFROM_TYPE_ARG4}
/* Define to the type pointed by arg 5 for recvfrom. */
#cmakedefine RECVFROM_TYPE_ARG5 ${RECVFROM_TYPE_ARG5}
/* Define to 1 if the type pointed by arg 5 for recvfrom is void. */
#cmakedefine RECVFROM_TYPE_ARG5_IS_VOID 1
/* Define to the type pointed by arg 6 for recvfrom. */
#cmakedefine RECVFROM_TYPE_ARG6 ${RECVFROM_TYPE_ARG6}
/* Define to 1 if the type pointed by arg 6 for recvfrom is void. */
#cmakedefine RECVFROM_TYPE_ARG6_IS_VOID 1
/* Define to the function return type for recvfrom. */
#cmakedefine RECVFROM_TYPE_RETV ${RECVFROM_TYPE_RETV}
/* Define to the type of arg 1 for recv. */
#cmakedefine RECV_TYPE_ARG1 ${RECV_TYPE_ARG1}
/* Define to the type of arg 2 for recv. */
#cmakedefine RECV_TYPE_ARG2 ${RECV_TYPE_ARG2}
/* Define to the type of arg 3 for recv. */
#cmakedefine RECV_TYPE_ARG3 ${RECV_TYPE_ARG3}
/* Define to the type of arg 4 for recv. */
#cmakedefine RECV_TYPE_ARG4 ${RECV_TYPE_ARG4}
/* Define to the function return type for recv. */
#cmakedefine RECV_TYPE_RETV ${RECV_TYPE_RETV}
/* Define as the return type of signal handlers (`int' or `void'). */
#cmakedefine RETSIGTYPE ${RETSIGTYPE}
/* Define to the type qualifier of arg 5 for select. */
#cmakedefine SELECT_QUAL_ARG5 ${SELECT_QUAL_ARG5}
/* 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}
/* Define to the function return type for select. */
#cmakedefine SELECT_TYPE_RETV ${SELECT_TYPE_RETV}
/* Define to the type qualifier of arg 2 for send. */
#cmakedefine SEND_QUAL_ARG2 ${SEND_QUAL_ARG2}
/* Define to the type of arg 1 for send. */
#cmakedefine SEND_TYPE_ARG1 ${SEND_TYPE_ARG1}
/* Define to the type of arg 2 for send. */
#cmakedefine SEND_TYPE_ARG2 ${SEND_TYPE_ARG2}
/* Define to the type of arg 3 for send. */
#cmakedefine SEND_TYPE_ARG3 ${SEND_TYPE_ARG3}
/* Define to the type of arg 4 for send. */
#cmakedefine SEND_TYPE_ARG4 ${SEND_TYPE_ARG4}
/* Define to the function return type for send. */
#cmakedefine SEND_TYPE_RETV ${SEND_TYPE_RETV}
/* The size of `int', as computed by sizeof. */
@SIZEOF_INT_CODE@
/* The size of `short', as computed by sizeof. */
@SIZEOF_SHORT_CODE@
/* The size of `long', as computed by sizeof. */
@SIZEOF_LONG_CODE@
/* The size of `off_t', as computed by sizeof. */
@SIZEOF_OFF_T_CODE@
/* The size of `size_t', as computed by sizeof. */
@SIZEOF_SIZE_T_CODE@
/* The size of `ssize_t', as computed by sizeof. */
@SIZEOF_SSIZE_T_CODE@
/* The size of `time_t', as computed by sizeof. */
@SIZEOF_TIME_T_CODE@
/* Define to 1 if you have the ANSI C header files. */
#cmakedefine STDC_HEADERS 1
/* Define to the type of arg 3 for strerror_r. */
#cmakedefine STRERROR_R_TYPE_ARG3 ${STRERROR_R_TYPE_ARG3}
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#cmakedefine TIME_WITH_SYS_TIME 1
/* Define if you want to enable c-ares support */
#cmakedefine USE_ARES 1
/* Define to disable non-blocking sockets. */
#cmakedefine USE_BLOCKING_SOCKETS 1
/* if GnuTLS is enabled */
#cmakedefine USE_GNUTLS 1
/* if PolarSSL is enabled */
#cmakedefine USE_POLARSSL 1
/* if libSSH2 is in use */
#cmakedefine USE_LIBSSH2 1
/* If you want to build curl with the built-in manual */
#cmakedefine USE_MANUAL 1
/* if NSS is enabled */
#cmakedefine USE_NSS 1
/* if you want to use OpenLDAP code instead of legacy ldap implementation */
#cmakedefine USE_OPENLDAP 1
/* if OpenSSL is in use */
#cmakedefine USE_OPENSSL 1
/* if SSL is enabled */
#cmakedefine USE_SSLEAY 1
/* to enable SSPI support */
#cmakedefine USE_WINDOWS_SSPI 1
/* Define to 1 if using yaSSL in OpenSSL compatibility mode. */
#cmakedefine USE_YASSLEMUL 1
/* Version number of package */
#cmakedefine VERSION ${VERSION}
/* Define to avoid automatic inclusion of winsock.h */
#cmakedefine WIN32_LEAN_AND_MEAN 1
/* Define to 1 if OS is AIX. */
#ifndef _ALL_SOURCE
# undef _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 this if you need it to compile thread-safe code */
#cmakedefine _THREAD_SAFE ${_THREAD_SAFE}
/* Define to empty if `const' does not conform to ANSI C. */
#cmakedefine const ${const}
/* Type to use in place of in_addr_t when system does not provide it. */
#cmakedefine in_addr_t ${in_addr_t}
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
#undef inline
#endif
/* Define to `unsigned int' if <sys/types.h> does not define. */
#cmakedefine size_t ${size_t}
/* the signed version of size_t */
#ifndef SIZEOF_SSIZE_T
# if SIZEOF_LONG == SIZEOF_SIZE_T
typedef long ssize_t;
# elif SIZEOF_LONG_LONG == SIZEOF_SIZE_T
typedef long long ssize_t;
# elif SIZEOF___INT64 == SIZEOF_SIZE_T
typedef __int64 ssize_t;
# else
typedef int ssize_t;
# endif
#endif

View File

@ -0,0 +1,427 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute 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 "curl_setup.h"
#include "curl_fnmatch.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
#include "curl_memory.h"
/* The last #include file should be: */
#include "memdebug.h"
#define CURLFNM_CHARSET_LEN (sizeof(char) * 256)
#define CURLFNM_CHSET_SIZE (CURLFNM_CHARSET_LEN + 15)
#define CURLFNM_NEGATE CURLFNM_CHARSET_LEN
#define CURLFNM_ALNUM (CURLFNM_CHARSET_LEN + 1)
#define CURLFNM_DIGIT (CURLFNM_CHARSET_LEN + 2)
#define CURLFNM_XDIGIT (CURLFNM_CHARSET_LEN + 3)
#define CURLFNM_ALPHA (CURLFNM_CHARSET_LEN + 4)
#define CURLFNM_PRINT (CURLFNM_CHARSET_LEN + 5)
#define CURLFNM_BLANK (CURLFNM_CHARSET_LEN + 6)
#define CURLFNM_LOWER (CURLFNM_CHARSET_LEN + 7)
#define CURLFNM_GRAPH (CURLFNM_CHARSET_LEN + 8)
#define CURLFNM_SPACE (CURLFNM_CHARSET_LEN + 9)
#define CURLFNM_UPPER (CURLFNM_CHARSET_LEN + 10)
typedef enum {
CURLFNM_LOOP_DEFAULT = 0,
CURLFNM_LOOP_BACKSLASH
} loop_state;
typedef enum {
CURLFNM_SCHS_DEFAULT = 0,
CURLFNM_SCHS_MAYRANGE,
CURLFNM_SCHS_MAYRANGE2,
CURLFNM_SCHS_RIGHTBR,
CURLFNM_SCHS_RIGHTBRLEFTBR
} setcharset_state;
typedef enum {
CURLFNM_PKW_INIT = 0,
CURLFNM_PKW_DDOT
} parsekey_state;
#define SETCHARSET_OK 1
#define SETCHARSET_FAIL 0
static int parsekeyword(unsigned char **pattern, unsigned char *charset)
{
parsekey_state state = CURLFNM_PKW_INIT;
#define KEYLEN 10
char keyword[KEYLEN] = { 0 };
int found = FALSE;
int i;
unsigned char *p = *pattern;
for(i = 0; !found; i++) {
char c = *p++;
if(i >= KEYLEN)
return SETCHARSET_FAIL;
switch(state) {
case CURLFNM_PKW_INIT:
if(ISALPHA(c) && ISLOWER(c))
keyword[i] = c;
else if(c == ':')
state = CURLFNM_PKW_DDOT;
else
return 0;
break;
case CURLFNM_PKW_DDOT:
if(c == ']')
found = TRUE;
else
return SETCHARSET_FAIL;
}
}
#undef KEYLEN
*pattern = p; /* move caller's pattern pointer */
if(strcmp(keyword, "digit") == 0)
charset[CURLFNM_DIGIT] = 1;
else if(strcmp(keyword, "alnum") == 0)
charset[CURLFNM_ALNUM] = 1;
else if(strcmp(keyword, "alpha") == 0)
charset[CURLFNM_ALPHA] = 1;
else if(strcmp(keyword, "xdigit") == 0)
charset[CURLFNM_XDIGIT] = 1;
else if(strcmp(keyword, "print") == 0)
charset[CURLFNM_PRINT] = 1;
else if(strcmp(keyword, "graph") == 0)
charset[CURLFNM_GRAPH] = 1;
else if(strcmp(keyword, "space") == 0)
charset[CURLFNM_SPACE] = 1;
else if(strcmp(keyword, "blank") == 0)
charset[CURLFNM_BLANK] = 1;
else if(strcmp(keyword, "upper") == 0)
charset[CURLFNM_UPPER] = 1;
else if(strcmp(keyword, "lower") == 0)
charset[CURLFNM_LOWER] = 1;
else
return SETCHARSET_FAIL;
return SETCHARSET_OK;
}
/* returns 1 (true) if pattern is OK, 0 if is bad ("p" is pattern pointer) */
static int setcharset(unsigned char **p, unsigned char *charset)
{
setcharset_state state = CURLFNM_SCHS_DEFAULT;
unsigned char rangestart = 0;
unsigned char lastchar = 0;
bool something_found = FALSE;
unsigned char c;
for(;;) {
c = **p;
switch(state) {
case CURLFNM_SCHS_DEFAULT:
if(ISALNUM(c)) { /* ASCII value */
rangestart = c;
charset[c] = 1;
(*p)++;
state = CURLFNM_SCHS_MAYRANGE;
something_found = TRUE;
}
else if(c == ']') {
if(something_found)
return SETCHARSET_OK;
else
something_found = TRUE;
state = CURLFNM_SCHS_RIGHTBR;
charset[c] = 1;
(*p)++;
}
else if(c == '[') {
char c2 = *((*p)+1);
if(c2 == ':') { /* there has to be a keyword */
(*p) += 2;
if(parsekeyword(p, charset)) {
state = CURLFNM_SCHS_DEFAULT;
}
else
return SETCHARSET_FAIL;
}
else {
charset[c] = 1;
(*p)++;
}
something_found = TRUE;
}
else if(c == '?' || c == '*') {
something_found = TRUE;
charset[c] = 1;
(*p)++;
}
else if(c == '^' || c == '!') {
if(!something_found) {
if(charset[CURLFNM_NEGATE]) {
charset[c] = 1;
something_found = TRUE;
}
else
charset[CURLFNM_NEGATE] = 1; /* negate charset */
}
else
charset[c] = 1;
(*p)++;
}
else if(c == '\\') {
c = *(++(*p));
if(ISPRINT((c))) {
something_found = TRUE;
state = CURLFNM_SCHS_MAYRANGE;
charset[c] = 1;
rangestart = c;
(*p)++;
}
else
return SETCHARSET_FAIL;
}
else if(c == '\0') {
return SETCHARSET_FAIL;
}
else {
charset[c] = 1;
(*p)++;
something_found = TRUE;
}
break;
case CURLFNM_SCHS_MAYRANGE:
if(c == '-') {
charset[c] = 1;
(*p)++;
lastchar = '-';
state = CURLFNM_SCHS_MAYRANGE2;
}
else if(c == '[') {
state = CURLFNM_SCHS_DEFAULT;
}
else if(ISALNUM(c)) {
charset[c] = 1;
(*p)++;
}
else if(c == '\\') {
c = *(++(*p));
if(ISPRINT(c)) {
charset[c] = 1;
(*p)++;
}
else
return SETCHARSET_FAIL;
}
else if(c == ']') {
return SETCHARSET_OK;
}
else
return SETCHARSET_FAIL;
break;
case CURLFNM_SCHS_MAYRANGE2:
if(c == '\\') {
c = *(++(*p));
if(!ISPRINT(c))
return SETCHARSET_FAIL;
}
if(c == ']') {
return SETCHARSET_OK;
}
else if(c == '\\') {
c = *(++(*p));
if(ISPRINT(c)) {
charset[c] = 1;
state = CURLFNM_SCHS_DEFAULT;
(*p)++;
}
else
return SETCHARSET_FAIL;
}
if(c >= rangestart) {
if((ISLOWER(c) && ISLOWER(rangestart)) ||
(ISDIGIT(c) && ISDIGIT(rangestart)) ||
(ISUPPER(c) && ISUPPER(rangestart))) {
charset[lastchar] = 0;
rangestart++;
while(rangestart++ <= c)
charset[rangestart-1] = 1;
(*p)++;
state = CURLFNM_SCHS_DEFAULT;
}
else
return SETCHARSET_FAIL;
}
break;
case CURLFNM_SCHS_RIGHTBR:
if(c == '[') {
state = CURLFNM_SCHS_RIGHTBRLEFTBR;
charset[c] = 1;
(*p)++;
}
else if(c == ']') {
return SETCHARSET_OK;
}
else if(c == '\0') {
return SETCHARSET_FAIL;
}
else if(ISPRINT(c)) {
charset[c] = 1;
(*p)++;
state = CURLFNM_SCHS_DEFAULT;
}
else
/* used 'goto fail' instead of 'return SETCHARSET_FAIL' to avoid a
* nonsense warning 'statement not reached' at end of the fnc when
* compiling on Solaris */
goto fail;
break;
case CURLFNM_SCHS_RIGHTBRLEFTBR:
if(c == ']') {
return SETCHARSET_OK;
}
else {
state = CURLFNM_SCHS_DEFAULT;
charset[c] = 1;
(*p)++;
}
break;
}
}
fail:
return SETCHARSET_FAIL;
}
static int loop(const unsigned char *pattern, const unsigned char *string)
{
loop_state state = CURLFNM_LOOP_DEFAULT;
unsigned char *p = (unsigned char *)pattern;
unsigned char *s = (unsigned char *)string;
unsigned char charset[CURLFNM_CHSET_SIZE] = { 0 };
int rc = 0;
for(;;) {
switch(state) {
case CURLFNM_LOOP_DEFAULT:
if(*p == '*') {
while(*(p+1) == '*') /* eliminate multiple stars */
p++;
if(*s == '\0' && *(p+1) == '\0')
return CURL_FNMATCH_MATCH;
rc = loop(p + 1, s); /* *.txt matches .txt <=> .txt matches .txt */
if(rc == CURL_FNMATCH_MATCH)
return CURL_FNMATCH_MATCH;
if(*s) /* let the star eat up one character */
s++;
else
return CURL_FNMATCH_NOMATCH;
}
else if(*p == '?') {
if(ISPRINT(*s)) {
s++;
p++;
}
else if(*s == '\0')
return CURL_FNMATCH_NOMATCH;
else
return CURL_FNMATCH_FAIL; /* cannot deal with other character */
}
else if(*p == '\0') {
if(*s == '\0')
return CURL_FNMATCH_MATCH;
else
return CURL_FNMATCH_NOMATCH;
}
else if(*p == '\\') {
state = CURLFNM_LOOP_BACKSLASH;
p++;
}
else if(*p == '[') {
unsigned char *pp = p+1; /* cannot handle with pointer to register */
if(setcharset(&pp, charset)) {
int found = FALSE;
if(charset[(unsigned int)*s])
found = TRUE;
else if(charset[CURLFNM_ALNUM])
found = ISALNUM(*s);
else if(charset[CURLFNM_ALPHA])
found = ISALPHA(*s);
else if(charset[CURLFNM_DIGIT])
found = ISDIGIT(*s);
else if(charset[CURLFNM_XDIGIT])
found = ISXDIGIT(*s);
else if(charset[CURLFNM_PRINT])
found = ISPRINT(*s);
else if(charset[CURLFNM_SPACE])
found = ISSPACE(*s);
else if(charset[CURLFNM_UPPER])
found = ISUPPER(*s);
else if(charset[CURLFNM_LOWER])
found = ISLOWER(*s);
else if(charset[CURLFNM_BLANK])
found = ISBLANK(*s);
else if(charset[CURLFNM_GRAPH])
found = ISGRAPH(*s);
if(charset[CURLFNM_NEGATE])
found = !found;
if(found) {
p = pp+1;
s++;
memset(charset, 0, CURLFNM_CHSET_SIZE);
}
else
return CURL_FNMATCH_NOMATCH;
}
else
return CURL_FNMATCH_FAIL;
}
else {
if(*p++ != *s++)
return CURL_FNMATCH_NOMATCH;
}
break;
case CURLFNM_LOOP_BACKSLASH:
if(ISPRINT(*p)) {
if(*p++ == *s++)
state = CURLFNM_LOOP_DEFAULT;
else
return CURL_FNMATCH_NOMATCH;
}
else
return CURL_FNMATCH_FAIL;
break;
}
}
}
/*
* @unittest: 1307
*/
int Curl_fnmatch(void *ptr, const char *pattern, const char *string)
{
(void)ptr; /* the argument is specified by the curl_fnmatch_callback
prototype, but not used by Curl_fnmatch() */
if(!pattern || !string) {
return CURL_FNMATCH_FAIL;
}
return loop((unsigned char *)pattern, (unsigned char *)string);
}

View File

@ -1,5 +1,5 @@
#ifndef __EASYIF_H
#define __EASYIF_H
#ifndef HEADER_CURL_FNMATCH_H
#define HEADER_CURL_FNMATCH_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@ -20,21 +20,25 @@
* 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 easy.c
#define CURL_FNMATCH_MATCH 0
#define CURL_FNMATCH_NOMATCH 1
#define CURL_FNMATCH_FAIL 2
/* default pattern matching function
* =================================
* Implemented with recursive backtracking, if you want to use Curl_fnmatch,
* please note that there is not implemented UTF/UNICODE support.
*
* Implemented features:
* '?' notation, does not match UTF characters
* '*' can also work with UTF string
* [a-zA-Z0-9] enumeration support
*
* keywords: alnum, digit, xdigit, alpha, print, blank, lower, graph, space
* and upper (use as "[[:alnum:]]")
*/
void Curl_easy_addmulti(struct SessionHandle *data, void *multi);
int Curl_fnmatch(void *ptr, const char *pattern, const char *string);
void Curl_easy_initHandleData(struct SessionHandle *data);
CURLcode Curl_convert_to_network(struct SessionHandle *data,
char *buffer, size_t length);
CURLcode Curl_convert_from_network(struct SessionHandle *data,
char *buffer, size_t length);
CURLcode Curl_convert_from_utf8(struct SessionHandle *data,
char *buffer, size_t length);
#endif /* __EASYIF_H */
#endif /* HEADER_CURL_FNMATCH_H */

View File

@ -0,0 +1,100 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute 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 "curl_setup.h"
#include "curl_gethostname.h"
/*
* Curl_gethostname() is a wrapper around gethostname() which allows
* overriding the host name that the function would normally return.
* This capability is used by the test suite to verify exact matching
* of NTLM authentication, which exercises libcurl's MD4 and DES code
* as well as by the SMTP module when a hostname is not provided.
*
* For libcurl debug enabled builds host name overriding takes place
* when environment variable CURL_GETHOSTNAME is set, using the value
* held by the variable to override returned host name.
*
* Note: The function always returns the un-qualified hostname rather
* than being provider dependent.
*
* For libcurl shared library release builds the test suite preloads
* another shared library named libhostname using the LD_PRELOAD
* mechanism which intercepts, and might override, the gethostname()
* function call. In this case a given platform must support the
* LD_PRELOAD mechanism and additionally have environment variable
* CURL_GETHOSTNAME set in order to override the returned host name.
*
* For libcurl static library release builds no overriding takes place.
*/
int Curl_gethostname(char *name, GETHOSTNAME_TYPE_ARG2 namelen) {
#ifndef HAVE_GETHOSTNAME
/* Allow compilation and return failure when unavailable */
(void) name;
(void) namelen;
return -1;
#else
int err;
char* dot;
#ifdef DEBUGBUILD
/* Override host name when environment variable CURL_GETHOSTNAME is set */
const char *force_hostname = getenv("CURL_GETHOSTNAME");
if(force_hostname) {
strncpy(name, force_hostname, namelen);
err = 0;
}
else {
name[0] = '\0';
err = gethostname(name, namelen);
}
#else /* DEBUGBUILD */
/* The call to system's gethostname() might get intercepted by the
libhostname library when libcurl is built as a non-debug shared
library when running the test suite. */
name[0] = '\0';
err = gethostname(name, namelen);
#endif
name[namelen - 1] = '\0';
if(err)
return err;
/* Truncate domain, leave only machine name */
dot = strchr(name, '.');
if(dot)
*dot = '\0';
return 0;
#endif
}

View File

@ -0,0 +1,31 @@
#ifndef HEADER_CURL_GETHOSTNAME_H
#define HEADER_CURL_GETHOSTNAME_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute 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.
*
***************************************************************************/
/* Hostname buffer size */
#define HOSTNAME_MAX 1024
/* This returns the local machine's un-qualified hostname */
int Curl_gethostname(char *name, GETHOSTNAME_TYPE_ARG2 namelen);
#endif /* HEADER_CURL_GETHOSTNAME_H */

View File

@ -0,0 +1,75 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2011 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute 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 "curl_setup.h"
#ifdef HAVE_GSSAPI
#include "curl_gssapi.h"
#include "sendf.h"
static const char spnego_oid_bytes[] = "\x2b\x06\x01\x05\x05\x02";
gss_OID_desc Curl_spnego_mech_oid = { 6, &spnego_oid_bytes };
static const char krb5_oid_bytes[] = "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02";
gss_OID_desc Curl_krb5_mech_oid = { 9, &krb5_oid_bytes };
OM_uint32 Curl_gss_init_sec_context(
struct SessionHandle *data,
OM_uint32 *minor_status,
gss_ctx_id_t *context,
gss_name_t target_name,
gss_OID mech_type,
gss_channel_bindings_t input_chan_bindings,
gss_buffer_t input_token,
gss_buffer_t output_token,
OM_uint32 *ret_flags)
{
OM_uint32 req_flags = GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG;
if(data->set.gssapi_delegation & CURLGSSAPI_DELEGATION_POLICY_FLAG) {
#ifdef GSS_C_DELEG_POLICY_FLAG
req_flags |= GSS_C_DELEG_POLICY_FLAG;
#else
infof(data, "warning: support for CURLGSSAPI_DELEGATION_POLICY_FLAG not "
"compiled in\n");
#endif
}
if(data->set.gssapi_delegation & CURLGSSAPI_DELEGATION_FLAG)
req_flags |= GSS_C_DELEG_FLAG;
return gss_init_sec_context(minor_status,
GSS_C_NO_CREDENTIAL, /* cred_handle */
context,
target_name,
mech_type,
req_flags,
0, /* time_req */
input_chan_bindings,
input_token,
NULL, /* actual_mech_type */
output_token,
ret_flags,
NULL /* time_rec */);
}
#endif /* HAVE_GSSAPI */

View File

@ -1,5 +1,5 @@
#ifndef __CONNECT_H
#define __CONNECT_H
#ifndef HEADER_CURL_GSSAPI_H
#define HEADER_CURL_GSSAPI_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@ -20,27 +20,41 @@
* 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 */);
#include "curl_setup.h"
#include "urldata.h"
CURLcode Curl_is_connected(struct connectdata *conn,
int sockindex,
bool *connected);
CURLcode Curl_connecthost(struct connectdata *conn,
const 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_sockerrno(void);
CURLcode Curl_store_ip_addr(struct connectdata *conn);
#define DEFAULT_CONNECT_TIMEOUT 300000 /* milliseconds == five minutes */
#ifdef HAVE_GSSAPI
#ifdef HAVE_GSSGNU
# include <gss.h>
#elif defined HAVE_GSSMIT
/* MIT style */
# include <gssapi/gssapi.h>
# include <gssapi/gssapi_generic.h>
# include <gssapi/gssapi_krb5.h>
#else
/* Heimdal-style */
# include <gssapi.h>
#endif
extern gss_OID_desc Curl_spnego_mech_oid;
extern gss_OID_desc Curl_krb5_mech_oid;
/* Common method for using GSS-API */
OM_uint32 Curl_gss_init_sec_context(
struct SessionHandle *data,
OM_uint32 *minor_status,
gss_ctx_id_t *context,
gss_name_t target_name,
gss_OID mech_type,
gss_channel_bindings_t input_chan_bindings,
gss_buffer_t input_token,
gss_buffer_t output_token,
OM_uint32 *ret_flags);
#endif /* HAVE_GSSAPI */
#endif /* HEADER_CURL_GSSAPI_H */

View File

@ -0,0 +1,67 @@
#ifndef HEADER_CURL_HMAC_H
#define HEADER_CURL_HMAC_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute 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.
*
***************************************************************************/
#ifndef CURL_DISABLE_CRYPTO_AUTH
typedef void (* HMAC_hinit_func)(void * context);
typedef void (* HMAC_hupdate_func)(void * context,
const unsigned char * data,
unsigned int len);
typedef void (* HMAC_hfinal_func)(unsigned char * result, void * context);
/* Per-hash function HMAC parameters. */
typedef struct {
HMAC_hinit_func hmac_hinit; /* Initialize context procedure. */
HMAC_hupdate_func hmac_hupdate; /* Update context with data. */
HMAC_hfinal_func hmac_hfinal; /* Get final result procedure. */
unsigned int hmac_ctxtsize; /* Context structure size. */
unsigned int hmac_maxkeylen; /* Maximum key length (bytes). */
unsigned int hmac_resultlen; /* Result length (bytes). */
} HMAC_params;
/* HMAC computation context. */
typedef struct {
const HMAC_params * hmac_hash; /* Hash function definition. */
void * hmac_hashctxt1; /* Hash function context 1. */
void * hmac_hashctxt2; /* Hash function context 2. */
} HMAC_context;
/* Prototypes. */
HMAC_context * Curl_HMAC_init(const HMAC_params * hashparams,
const unsigned char * key,
unsigned int keylen);
int Curl_HMAC_update(HMAC_context * context,
const unsigned char * data,
unsigned int len);
int Curl_HMAC_final(HMAC_context * context, unsigned char * result);
#endif
#endif /* HEADER_CURL_HMAC_H */

Some files were not shown because too many files have changed in this diff Show More