mirror of
https://gitlab.kitware.com/cmake/cmake.git
synced 2026-09-25 04:09:36 +03:00
Merge branch 'upstream-curl' into update-curl
* upstream-curl: curl 2025-11-05 (400fffa9)
This commit is contained in:
@@ -25,9 +25,9 @@
|
||||
#
|
||||
# Input variables:
|
||||
#
|
||||
# - `BROTLI_INCLUDE_DIR`: The brotli include directory.
|
||||
# - `BROTLICOMMON_LIBRARY`: Path to `brotlicommon` library.
|
||||
# - `BROTLIDEC_LIBRARY`: Path to `brotlidec` library.
|
||||
# - `BROTLI_INCLUDE_DIR`: Absolute path to brotli include directory.
|
||||
# - `BROTLICOMMON_LIBRARY`: Absolute path to `brotlicommon` library.
|
||||
# - `BROTLIDEC_LIBRARY`: Absolute path to `brotlidec` library.
|
||||
#
|
||||
# Result variables:
|
||||
#
|
||||
@@ -51,7 +51,7 @@ endif()
|
||||
|
||||
if(BROTLI_FOUND)
|
||||
set(Brotli_FOUND TRUE)
|
||||
set(BROTLI_VERSION "${BROTLI_libbrotlicommon_VERSION}")
|
||||
set(BROTLI_VERSION ${BROTLI_libbrotlicommon_VERSION})
|
||||
string(REPLACE ";" " " BROTLI_CFLAGS "${BROTLI_CFLAGS}")
|
||||
message(STATUS "Found Brotli (via pkg-config): ${BROTLI_INCLUDE_DIRS} (found version \"${BROTLI_VERSION}\")")
|
||||
else()
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
#
|
||||
# Input variables:
|
||||
#
|
||||
# - `CARES_INCLUDE_DIR`: The c-ares include directory.
|
||||
# - `CARES_LIBRARY`: Path to `cares` library.
|
||||
# - `CARES_INCLUDE_DIR`: Absolute path to c-ares include directory.
|
||||
# - `CARES_LIBRARY`: Absolute path to `cares` library.
|
||||
#
|
||||
# Result variables:
|
||||
#
|
||||
|
||||
@@ -25,12 +25,12 @@
|
||||
#
|
||||
# Input variables:
|
||||
#
|
||||
# - `GSS_ROOT_DIR`: Set this variable to the root installation of GSS. (also supported as environment)
|
||||
# - `GSS_ROOT_DIR`: Absolute path to the root installation of GSS. (also supported as environment)
|
||||
#
|
||||
# Result variables:
|
||||
#
|
||||
# - `GSS_FOUND`: System has the Heimdal library.
|
||||
# - `GSS_FLAVOUR`: "GNU", "MIT" or "Heimdal" if anything found.
|
||||
# - `GSS_FOUND`: System has a GSS library.
|
||||
# - `GSS_FLAVOUR`: "GNU" or "MIT" if anything found.
|
||||
# - `GSS_INCLUDE_DIRS`: The GSS include directories.
|
||||
# - `GSS_LIBRARIES`: The GSS library names.
|
||||
# - `GSS_LIBRARY_DIRS`: The GSS library directories.
|
||||
@@ -41,16 +41,12 @@
|
||||
|
||||
set(_gnu_modname "gss")
|
||||
set(_mit_modname "mit-krb5-gssapi")
|
||||
set(_heimdal_modname "heimdal-gssapi")
|
||||
|
||||
include(CheckIncludeFile)
|
||||
include(CheckIncludeFiles)
|
||||
include(CheckTypeSize)
|
||||
|
||||
set(_gss_root_hints
|
||||
"${GSS_ROOT_DIR}"
|
||||
"$ENV{GSS_ROOT_DIR}"
|
||||
)
|
||||
set(_gss_root_hints "${GSS_ROOT_DIR}" "$ENV{GSS_ROOT_DIR}")
|
||||
|
||||
set(_gss_CFLAGS "")
|
||||
set(_gss_LIBRARY_DIRS "")
|
||||
@@ -59,7 +55,7 @@ set(_gss_LIBRARY_DIRS "")
|
||||
if(NOT GSS_ROOT_DIR AND NOT "$ENV{GSS_ROOT_DIR}")
|
||||
if(CURL_USE_PKGCONFIG)
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_search_module(_gss ${_gnu_modname} ${_mit_modname} ${_heimdal_modname})
|
||||
pkg_search_module(_gss ${_gnu_modname} ${_mit_modname})
|
||||
list(APPEND _gss_root_hints "${_gss_PREFIX}")
|
||||
set(_gss_version "${_gss_VERSION}")
|
||||
endif()
|
||||
@@ -69,37 +65,22 @@ if(NOT GSS_ROOT_DIR AND NOT "$ENV{GSS_ROOT_DIR}")
|
||||
endif()
|
||||
|
||||
if(NOT _gss_FOUND) # Not found by pkg-config. Let us take more traditional approach.
|
||||
find_file(_gss_configure_script
|
||||
NAMES
|
||||
"krb5-config"
|
||||
HINTS
|
||||
${_gss_root_hints}
|
||||
PATH_SUFFIXES
|
||||
"bin"
|
||||
NO_CMAKE_PATH
|
||||
NO_CMAKE_ENVIRONMENT_PATH
|
||||
)
|
||||
|
||||
find_file(_gss_configure_script NAMES "krb5-config" PATH_SUFFIXES "bin" HINTS ${_gss_root_hints}
|
||||
NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH)
|
||||
# If not found in user-supplied directories, maybe system knows better
|
||||
find_file(_gss_configure_script
|
||||
NAMES
|
||||
"krb5-config"
|
||||
PATH_SUFFIXES
|
||||
"bin"
|
||||
)
|
||||
find_file(_gss_configure_script NAMES "krb5-config" PATH_SUFFIXES "bin")
|
||||
|
||||
if(_gss_configure_script)
|
||||
|
||||
set(_gss_INCLUDE_DIRS "")
|
||||
set(_gss_LIBRARIES "")
|
||||
|
||||
execute_process(
|
||||
COMMAND ${_gss_configure_script} "--cflags" "gssapi"
|
||||
execute_process(COMMAND ${_gss_configure_script} "--cflags" "gssapi"
|
||||
OUTPUT_VARIABLE _gss_cflags_raw
|
||||
RESULT_VARIABLE _gss_configure_failed
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
message(STATUS "FindGSS krb5-config --cflags: ${_gss_cflags_raw}")
|
||||
|
||||
if(NOT _gss_configure_failed) # 0 means success
|
||||
# Should also work in an odd case when multiple directories are given.
|
||||
string(STRIP "${_gss_cflags_raw}" _gss_cflags_raw)
|
||||
@@ -116,12 +97,10 @@ if(NOT _gss_FOUND) # Not found by pkg-config. Let us take more traditional appr
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
execute_process(
|
||||
COMMAND ${_gss_configure_script} "--libs" "gssapi"
|
||||
execute_process(COMMAND ${_gss_configure_script} "--libs" "gssapi"
|
||||
OUTPUT_VARIABLE _gss_lib_flags
|
||||
RESULT_VARIABLE _gss_configure_failed
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
message(STATUS "FindGSS krb5-config --libs: ${_gss_lib_flags}")
|
||||
|
||||
if(NOT _gss_configure_failed) # 0 means success
|
||||
@@ -141,157 +120,93 @@ if(NOT _gss_FOUND) # Not found by pkg-config. Let us take more traditional appr
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
execute_process(
|
||||
COMMAND ${_gss_configure_script} "--version"
|
||||
execute_process(COMMAND ${_gss_configure_script} "--version"
|
||||
OUTPUT_VARIABLE _gss_version
|
||||
RESULT_VARIABLE _gss_configure_failed
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
# Older versions may not have the "--version" parameter. In this case we just do not care.
|
||||
if(_gss_configure_failed)
|
||||
set(_gss_version 0)
|
||||
else()
|
||||
# Strip prefix string to leave the version number only
|
||||
string(REPLACE "Kerberos 5 release " "" _gss_version "${_gss_version}")
|
||||
endif()
|
||||
|
||||
execute_process(
|
||||
COMMAND ${_gss_configure_script} "--vendor"
|
||||
execute_process(COMMAND ${_gss_configure_script} "--vendor"
|
||||
OUTPUT_VARIABLE _gss_vendor
|
||||
RESULT_VARIABLE _gss_configure_failed
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
# Older versions may not have the "--vendor" parameter. In this case we just do not care.
|
||||
if(_gss_configure_failed)
|
||||
set(GSS_FLAVOUR "Heimdal") # most probably, should not really matter
|
||||
else()
|
||||
if(_gss_vendor MATCHES "H|heimdal")
|
||||
set(GSS_FLAVOUR "Heimdal")
|
||||
else()
|
||||
set(GSS_FLAVOUR "MIT")
|
||||
endif()
|
||||
if(NOT _gss_configure_failed AND NOT _gss_vendor MATCHES "Heimdal|heimdal")
|
||||
set(GSS_FLAVOUR "MIT") # assume a default, should not really matter
|
||||
endif()
|
||||
|
||||
else() # Either there is no config script or we are on a platform that does not provide one (Windows?)
|
||||
|
||||
find_path(_gss_INCLUDE_DIRS NAMES "gssapi/gssapi.h"
|
||||
HINTS
|
||||
${_gss_root_hints}
|
||||
PATH_SUFFIXES
|
||||
"include"
|
||||
"inc"
|
||||
)
|
||||
find_path(_gss_INCLUDE_DIRS NAMES "gssapi/gssapi.h" HINTS ${_gss_root_hints} PATH_SUFFIXES "include" "inc")
|
||||
|
||||
if(_gss_INCLUDE_DIRS) # We have found something
|
||||
set(_gss_libdir_suffixes "")
|
||||
|
||||
if(_gss_INCLUDE_DIRS) # jay, we have found something
|
||||
cmake_push_check_state()
|
||||
list(APPEND CMAKE_REQUIRED_INCLUDES "${_gss_INCLUDE_DIRS}")
|
||||
check_include_files("gssapi/gssapi_generic.h;gssapi/gssapi_krb5.h" _gss_have_mit_headers)
|
||||
cmake_pop_check_state()
|
||||
|
||||
if(_gss_have_mit_headers)
|
||||
set(GSS_FLAVOUR "MIT")
|
||||
else()
|
||||
# Prevent compiling the header - just check if we can include it
|
||||
list(APPEND CMAKE_REQUIRED_DEFINITIONS "-D__ROKEN_H__")
|
||||
check_include_file("roken.h" _gss_have_roken_h)
|
||||
|
||||
check_include_file("heimdal/roken.h" _gss_have_heimdal_roken_h)
|
||||
if(_gss_have_roken_h OR _gss_have_heimdal_roken_h)
|
||||
set(GSS_FLAVOUR "Heimdal")
|
||||
endif()
|
||||
endif()
|
||||
cmake_pop_check_state()
|
||||
else()
|
||||
# I am not convinced if this is the right way but this is what autotools do at the moment
|
||||
find_path(_gss_INCLUDE_DIRS NAMES "gssapi.h"
|
||||
HINTS
|
||||
${_gss_root_hints}
|
||||
PATH_SUFFIXES
|
||||
"include"
|
||||
"inc"
|
||||
)
|
||||
|
||||
if(_gss_INCLUDE_DIRS)
|
||||
set(GSS_FLAVOUR "Heimdal")
|
||||
else()
|
||||
find_path(_gss_INCLUDE_DIRS NAMES "gss.h"
|
||||
HINTS
|
||||
${_gss_root_hints}
|
||||
PATH_SUFFIXES
|
||||
"include"
|
||||
)
|
||||
|
||||
if(_gss_INCLUDE_DIRS)
|
||||
set(GSS_FLAVOUR "GNU")
|
||||
set(GSS_PC_REQUIRES "gss")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# If we have headers, check if we can link libraries
|
||||
if(GSS_FLAVOUR)
|
||||
set(_gss_libdir_suffixes "")
|
||||
set(_gss_libdir_hints ${_gss_root_hints})
|
||||
get_filename_component(_gss_calculated_potential_root "${_gss_INCLUDE_DIRS}" DIRECTORY)
|
||||
list(APPEND _gss_libdir_hints ${_gss_calculated_potential_root})
|
||||
|
||||
if(WIN32)
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
list(APPEND _gss_libdir_suffixes "lib/AMD64")
|
||||
if(GSS_FLAVOUR STREQUAL "GNU")
|
||||
set(_gss_libname "gss")
|
||||
elseif(GSS_FLAVOUR STREQUAL "MIT")
|
||||
if(WIN32)
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
list(APPEND _gss_libdir_suffixes "lib/AMD64")
|
||||
set(_gss_libname "gssapi64")
|
||||
else()
|
||||
set(_gss_libname "libgssapi")
|
||||
endif()
|
||||
else()
|
||||
list(APPEND _gss_libdir_suffixes "lib/i386")
|
||||
if(GSS_FLAVOUR STREQUAL "GNU")
|
||||
set(_gss_libname "gss")
|
||||
elseif(GSS_FLAVOUR STREQUAL "MIT")
|
||||
list(APPEND _gss_libdir_suffixes "lib/i386")
|
||||
set(_gss_libname "gssapi32")
|
||||
else()
|
||||
set(_gss_libname "libgssapi")
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
list(APPEND _gss_libdir_suffixes "lib;lib64") # those suffixes are not checked for HINTS
|
||||
if(GSS_FLAVOUR STREQUAL "GNU")
|
||||
set(_gss_libname "gss")
|
||||
elseif(GSS_FLAVOUR STREQUAL "MIT")
|
||||
set(_gss_libname "gssapi_krb5")
|
||||
else()
|
||||
set(_gss_libname "gssapi")
|
||||
list(APPEND _gss_libdir_suffixes "lib" "lib64") # those suffixes are not checked for HINTS
|
||||
set(_gss_libname "gssapi_krb5")
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
find_path(_gss_INCLUDE_DIRS NAMES "gss.h" HINTS ${_gss_root_hints} PATH_SUFFIXES "include")
|
||||
|
||||
find_library(_gss_LIBRARIES NAMES ${_gss_libname}
|
||||
HINTS
|
||||
${_gss_libdir_hints}
|
||||
PATH_SUFFIXES
|
||||
${_gss_libdir_suffixes}
|
||||
)
|
||||
if(_gss_INCLUDE_DIRS)
|
||||
set(GSS_FLAVOUR "GNU")
|
||||
set(GSS_PC_REQUIRES ${_gnu_modname})
|
||||
set(_gss_libname "gss")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# If we have headers, look up libraries
|
||||
if(GSS_FLAVOUR)
|
||||
set(_gss_libdir_hints ${_gss_root_hints})
|
||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.20)
|
||||
cmake_path(GET _gss_INCLUDE_DIRS PARENT_PATH _gss_calculated_potential_root)
|
||||
else()
|
||||
get_filename_component(_gss_calculated_potential_root "${_gss_INCLUDE_DIRS}" DIRECTORY)
|
||||
endif()
|
||||
list(APPEND _gss_libdir_hints ${_gss_calculated_potential_root})
|
||||
|
||||
find_library(_gss_LIBRARIES NAMES ${_gss_libname} HINTS ${_gss_libdir_hints} PATH_SUFFIXES ${_gss_libdir_suffixes})
|
||||
endif()
|
||||
endif()
|
||||
if(NOT GSS_FLAVOUR)
|
||||
message(FATAL_ERROR "GNU or MIT GSS is required")
|
||||
endif()
|
||||
else()
|
||||
# _gss_MODULE_NAME set since CMake 3.16
|
||||
if(_gss_MODULE_NAME STREQUAL _gnu_modname OR _gss_${_gnu_modname}_VERSION)
|
||||
# _gss_MODULE_NAME set since CMake 3.16.
|
||||
# _pkg_check_modules_pkg_name is undocumented and used as a fallback for CMake <3.16 versions.
|
||||
if(_gss_MODULE_NAME STREQUAL _gnu_modname OR _pkg_check_modules_pkg_name STREQUAL _gnu_modname)
|
||||
set(GSS_FLAVOUR "GNU")
|
||||
set(GSS_PC_REQUIRES "gss")
|
||||
if(NOT _gss_version) # for old CMake versions?
|
||||
set(_gss_version ${_gss_${_gnu_modname}_VERSION})
|
||||
endif()
|
||||
elseif(_gss_MODULE_NAME STREQUAL _mit_modname OR _gss_${_mit_modname}_VERSION)
|
||||
set(GSS_PC_REQUIRES ${_gnu_modname})
|
||||
elseif(_gss_MODULE_NAME STREQUAL _mit_modname OR _pkg_check_modules_pkg_name STREQUAL _mit_modname)
|
||||
set(GSS_FLAVOUR "MIT")
|
||||
set(GSS_PC_REQUIRES "mit-krb5-gssapi")
|
||||
if(NOT _gss_version) # for old CMake versions?
|
||||
set(_gss_version ${_gss_${_mit_modname}_VERSION})
|
||||
endif()
|
||||
set(GSS_PC_REQUIRES ${_mit_modname})
|
||||
else()
|
||||
set(GSS_FLAVOUR "Heimdal")
|
||||
set(GSS_PC_REQUIRES "heimdal-gssapi")
|
||||
if(NOT _gss_version) # for old CMake versions?
|
||||
set(_gss_version ${_gss_${_heimdal_modname}_VERSION})
|
||||
endif()
|
||||
message(FATAL_ERROR "GNU or MIT GSS is required")
|
||||
endif()
|
||||
message(STATUS "Found GSS/${GSS_FLAVOUR} (via pkg-config): ${_gss_INCLUDE_DIRS} (found version \"${_gss_version}\")")
|
||||
endif()
|
||||
@@ -304,33 +219,21 @@ set(GSS_LIBRARY_DIRS ${_gss_LIBRARY_DIRS})
|
||||
set(GSS_CFLAGS ${_gss_CFLAGS})
|
||||
set(GSS_VERSION ${_gss_version})
|
||||
|
||||
if(GSS_FLAVOUR)
|
||||
if(NOT GSS_VERSION AND GSS_FLAVOUR STREQUAL "Heimdal")
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(_heimdal_manifest_file "Heimdal.Application.amd64.manifest")
|
||||
if(NOT GSS_VERSION)
|
||||
if(GSS_FLAVOUR STREQUAL "MIT")
|
||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.24)
|
||||
cmake_host_system_information(RESULT _mit_version QUERY WINDOWS_REGISTRY
|
||||
"HKLM/SOFTWARE/MIT/Kerberos/SDK/CurrentVersion" VALUE "VersionString")
|
||||
else()
|
||||
set(_heimdal_manifest_file "Heimdal.Application.x86.manifest")
|
||||
get_filename_component(_mit_version
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\MIT\\Kerberos\\SDK\\CurrentVersion;VersionString]" NAME CACHE)
|
||||
endif()
|
||||
|
||||
if(EXISTS "${GSS_INCLUDE_DIRS}/${_heimdal_manifest_file}")
|
||||
file(STRINGS "${GSS_INCLUDE_DIRS}/${_heimdal_manifest_file}" _heimdal_version_str
|
||||
REGEX "^.*version=\"[0-9]\\.[^\"]+\".*$")
|
||||
|
||||
string(REGEX MATCH "[0-9]\\.[^\"]+" GSS_VERSION "${_heimdal_version_str}")
|
||||
endif()
|
||||
|
||||
if(NOT GSS_VERSION)
|
||||
set(GSS_VERSION "Heimdal Unknown")
|
||||
endif()
|
||||
elseif(NOT GSS_VERSION AND GSS_FLAVOUR STREQUAL "MIT")
|
||||
get_filename_component(_mit_version "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MIT\\Kerberos\\SDK\\CurrentVersion;VersionString]" NAME
|
||||
CACHE)
|
||||
if(WIN32 AND _mit_version)
|
||||
set(GSS_VERSION "${_mit_version}")
|
||||
else()
|
||||
set(GSS_VERSION "MIT Unknown")
|
||||
endif()
|
||||
elseif(NOT GSS_VERSION AND GSS_FLAVOUR STREQUAL "GNU")
|
||||
else() # GNU
|
||||
if(GSS_INCLUDE_DIRS AND EXISTS "${GSS_INCLUDE_DIRS}/gss.h")
|
||||
set(_version_regex "#[\t ]*define[\t ]+GSS_VERSION[\t ]+\"([^\"]*)\"")
|
||||
file(STRINGS "${GSS_INCLUDE_DIRS}/gss.h" _version_str REGEX "${_version_regex}")
|
||||
@@ -350,7 +253,7 @@ find_package_handle_standard_args(GSS
|
||||
VERSION_VAR
|
||||
GSS_VERSION
|
||||
FAIL_MESSAGE
|
||||
"Could NOT find GSS, try to set the path to GSS root folder in the system variable GSS_ROOT_DIR"
|
||||
"Could NOT find GSS, try to set the absolute path to GSS installation root directory in the environment variable GSS_ROOT_DIR"
|
||||
)
|
||||
|
||||
mark_as_advanced(
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
# are also available at https://curl.se/docs/copyright.html.
|
||||
#
|
||||
# You may opt to use, copy, modify, merge, publish, distribute 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.
|
||||
#
|
||||
# SPDX-License-Identifier: curl
|
||||
#
|
||||
###########################################################################
|
||||
# Find the GnuTLS library
|
||||
#
|
||||
# Input variables:
|
||||
#
|
||||
# - `GNUTLS_INCLUDE_DIR`: Absolute path to GnuTLS include directory.
|
||||
# - `GNUTLS_LIBRARY`: Absolute path to `gnutls` library.
|
||||
#
|
||||
# Result variables:
|
||||
#
|
||||
# - `GNUTLS_FOUND`: System has GnuTLS.
|
||||
# - `GNUTLS_INCLUDE_DIRS`: The GnuTLS include directories.
|
||||
# - `GNUTLS_LIBRARIES`: The GnuTLS library names.
|
||||
# - `GNUTLS_LIBRARY_DIRS`: The GnuTLS library directories.
|
||||
# - `GNUTLS_PC_REQUIRES`: The GnuTLS pkg-config packages.
|
||||
# - `GNUTLS_CFLAGS`: Required compiler flags.
|
||||
# - `GNUTLS_VERSION`: Version of GnuTLS.
|
||||
|
||||
set(GNUTLS_PC_REQUIRES "gnutls")
|
||||
|
||||
if(CURL_USE_PKGCONFIG AND
|
||||
NOT DEFINED GNUTLS_INCLUDE_DIR AND
|
||||
NOT DEFINED GNUTLS_LIBRARY)
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(GNUTLS ${GNUTLS_PC_REQUIRES})
|
||||
endif()
|
||||
|
||||
if(GNUTLS_FOUND)
|
||||
set(GnuTLS_FOUND TRUE)
|
||||
string(REPLACE ";" " " GNUTLS_CFLAGS "${GNUTLS_CFLAGS}")
|
||||
message(STATUS "Found GnuTLS (via pkg-config): ${GNUTLS_INCLUDE_DIRS} (found version \"${GNUTLS_VERSION}\")")
|
||||
else()
|
||||
find_path(GNUTLS_INCLUDE_DIR NAMES "gnutls/gnutls.h")
|
||||
find_library(GNUTLS_LIBRARY NAMES "gnutls" "libgnutls")
|
||||
|
||||
unset(GNUTLS_VERSION CACHE)
|
||||
if(GNUTLS_INCLUDE_DIR AND EXISTS "${GNUTLS_INCLUDE_DIR}/gnutls/gnutls.h")
|
||||
set(_version_regex "#[\t ]*define[\t ]+GNUTLS_VERSION[\t ]+\"([^\"]*)\"")
|
||||
file(STRINGS "${GNUTLS_INCLUDE_DIR}/gnutls/gnutls.h" _version_str REGEX "${_version_regex}")
|
||||
string(REGEX REPLACE "${_version_regex}" "\\1" _version_str "${_version_str}")
|
||||
set(GNUTLS_VERSION "${_version_str}")
|
||||
unset(_version_regex)
|
||||
unset(_version_str)
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(GnuTLS
|
||||
REQUIRED_VARS
|
||||
GNUTLS_INCLUDE_DIR
|
||||
GNUTLS_LIBRARY
|
||||
VERSION_VAR
|
||||
GNUTLS_VERSION
|
||||
)
|
||||
|
||||
if(GNUTLS_FOUND)
|
||||
set(GNUTLS_INCLUDE_DIRS ${GNUTLS_INCLUDE_DIR})
|
||||
set(GNUTLS_LIBRARIES ${GNUTLS_LIBRARY})
|
||||
endif()
|
||||
|
||||
mark_as_advanced(GNUTLS_INCLUDE_DIR GNUTLS_LIBRARY)
|
||||
endif()
|
||||
@@ -25,9 +25,9 @@
|
||||
#
|
||||
# Input variables:
|
||||
#
|
||||
# - `LDAP_INCLUDE_DIR`: The ldap include directory.
|
||||
# - `LDAP_LIBRARY`: Path to `ldap` library.
|
||||
# - `LDAP_LBER_LIBRARY`: Path to `lber` library.
|
||||
# - `LDAP_INCLUDE_DIR`: Absolute path to ldap include directory.
|
||||
# - `LDAP_LIBRARY`: Absolute path to `ldap` library.
|
||||
# - `LDAP_LBER_LIBRARY`: Absolute path to `lber` library.
|
||||
#
|
||||
# Result variables:
|
||||
#
|
||||
@@ -50,7 +50,7 @@ if(CURL_USE_PKGCONFIG AND
|
||||
endif()
|
||||
|
||||
if(LDAP_FOUND)
|
||||
set(LDAP_VERSION "${LDAP_ldap_VERSION}")
|
||||
set(LDAP_VERSION ${LDAP_ldap_VERSION})
|
||||
string(REPLACE ";" " " LDAP_CFLAGS "${LDAP_CFLAGS}")
|
||||
message(STATUS "Found LDAP (via pkg-config): ${LDAP_INCLUDE_DIRS} (found version \"${LDAP_VERSION}\")")
|
||||
else()
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
#
|
||||
# Input variables:
|
||||
#
|
||||
# - `LIBGSASL_INCLUDE_DIR`: The libgsasl include directory.
|
||||
# - `LIBGSASL_LIBRARY`: Path to `libgsasl` library.
|
||||
# - `LIBGSASL_INCLUDE_DIR`: Absolute path to libgsasl include directory.
|
||||
# - `LIBGSASL_LIBRARY`: Absolute path to `libgsasl` library.
|
||||
#
|
||||
# Result variables:
|
||||
#
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
#
|
||||
# Input variables:
|
||||
#
|
||||
# - `LIBIDN2_INCLUDE_DIR`: The libidn2 include directory.
|
||||
# - `LIBIDN2_LIBRARY`: Path to `libidn2` library.
|
||||
# - `LIBIDN2_INCLUDE_DIR`: Absolute path to libidn2 include directory.
|
||||
# - `LIBIDN2_LIBRARY`: Absolute path to `libidn2` library.
|
||||
#
|
||||
# Result variables:
|
||||
#
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
#
|
||||
# Input variables:
|
||||
#
|
||||
# - `LIBPSL_INCLUDE_DIR`: The libpsl include directory.
|
||||
# - `LIBPSL_LIBRARY`: Path to `libpsl` library.
|
||||
# - `LIBPSL_INCLUDE_DIR`: Absolute path to libpsl include directory.
|
||||
# - `LIBPSL_LIBRARY`: Absolute path to `libpsl` library.
|
||||
#
|
||||
# Result variables:
|
||||
#
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
#
|
||||
# Input variables:
|
||||
#
|
||||
# - `LIBRTMP_INCLUDE_DIR`: The librtmp include directory.
|
||||
# - `LIBRTMP_LIBRARY`: Path to `librtmp` library.
|
||||
# - `LIBRTMP_INCLUDE_DIR`: Absolute path to librtmp include directory.
|
||||
# - `LIBRTMP_LIBRARY`: Absolute path to `librtmp` library.
|
||||
#
|
||||
# Result variables:
|
||||
#
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
#
|
||||
# Input variables:
|
||||
#
|
||||
# - `LIBSSH_INCLUDE_DIR`: The libssh include directory.
|
||||
# - `LIBSSH_LIBRARY`: Path to libssh library.
|
||||
# - `LIBSSH_INCLUDE_DIR`: Absolute path to libssh include directory.
|
||||
# - `LIBSSH_LIBRARY`: Absolute path to `libssh` library.
|
||||
#
|
||||
# Result variables:
|
||||
#
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
#
|
||||
# Input variables:
|
||||
#
|
||||
# - `LIBSSH2_INCLUDE_DIR`: The libssh2 include directory.
|
||||
# - `LIBSSH2_LIBRARY`: Path to `libssh2` library.
|
||||
# - `LIBSSH2_INCLUDE_DIR`: Absolute path to libssh2 include directory.
|
||||
# - `LIBSSH2_LIBRARY`: Absolute path to `libssh2` library.
|
||||
#
|
||||
# Result variables:
|
||||
#
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
#
|
||||
# Input variables:
|
||||
#
|
||||
# - `LIBUV_INCLUDE_DIR`: The libuv include directory.
|
||||
# - `LIBUV_LIBRARY`: Path to `libuv` library.
|
||||
# - `LIBUV_INCLUDE_DIR`: Absolute path to libuv include directory.
|
||||
# - `LIBUV_LIBRARY`: Absolute path to `libuv` library.
|
||||
#
|
||||
# Result variables:
|
||||
#
|
||||
|
||||
@@ -25,10 +25,10 @@
|
||||
#
|
||||
# Input variables:
|
||||
#
|
||||
# - `MBEDTLS_INCLUDE_DIR`: The mbedTLS include directory.
|
||||
# - `MBEDTLS_LIBRARY`: Path to `mbedtls` library.
|
||||
# - `MBEDX509_LIBRARY`: Path to `mbedx509` library.
|
||||
# - `MBEDCRYPTO_LIBRARY`: Path to `mbedcrypto` library.
|
||||
# - `MBEDTLS_INCLUDE_DIR`: Absolute path to mbedTLS include directory.
|
||||
# - `MBEDTLS_LIBRARY`: Absolute path to `mbedtls` library.
|
||||
# - `MBEDX509_LIBRARY`: Absolute path to `mbedx509` library.
|
||||
# - `MBEDCRYPTO_LIBRARY`: Absolute path to `mbedcrypto` library.
|
||||
#
|
||||
# Result variables:
|
||||
#
|
||||
@@ -59,7 +59,7 @@ endif()
|
||||
|
||||
if(MBEDTLS_FOUND)
|
||||
set(MbedTLS_FOUND TRUE)
|
||||
set(MBEDTLS_VERSION "${MBEDTLS_mbedtls_VERSION}")
|
||||
set(MBEDTLS_VERSION ${MBEDTLS_mbedtls_VERSION})
|
||||
string(REPLACE ";" " " MBEDTLS_CFLAGS "${MBEDTLS_CFLAGS}")
|
||||
message(STATUS "Found MbedTLS (via pkg-config): ${MBEDTLS_INCLUDE_DIRS} (found version \"${MBEDTLS_VERSION}\")")
|
||||
else()
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
#
|
||||
# Input variables:
|
||||
#
|
||||
# - `NGHTTP2_INCLUDE_DIR`: The nghttp2 include directory.
|
||||
# - `NGHTTP2_LIBRARY`: Path to `nghttp2` library.
|
||||
# - `NGHTTP2_INCLUDE_DIR`: Absolute path to nghttp2 include directory.
|
||||
# - `NGHTTP2_LIBRARY`: Absolute path to `nghttp2` library.
|
||||
#
|
||||
# Result variables:
|
||||
#
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
#
|
||||
# Input variables:
|
||||
#
|
||||
# - `NGHTTP3_INCLUDE_DIR`: The nghttp3 include directory.
|
||||
# - `NGHTTP3_LIBRARY`: Path to `nghttp3` library.
|
||||
# - `NGHTTP3_INCLUDE_DIR`: Absolute path to nghttp3 include directory.
|
||||
# - `NGHTTP3_LIBRARY`: Absolute path to `nghttp3` library.
|
||||
#
|
||||
# Result variables:
|
||||
#
|
||||
|
||||
@@ -35,14 +35,14 @@
|
||||
#
|
||||
# Input variables:
|
||||
#
|
||||
# - `NGTCP2_INCLUDE_DIR`: The ngtcp2 include directory.
|
||||
# - `NGTCP2_LIBRARY`: Path to `ngtcp2` library.
|
||||
# - `NGTCP2_CRYPTO_BORINGSSL_LIBRARY`: Path to `ngtcp2_crypto_boringssl` library.
|
||||
# - `NGTCP2_CRYPTO_GNUTLS_LIBRARY`: Path to `ngtcp2_crypto_gnutls` library.
|
||||
# - `NGTCP2_CRYPTO_LIBRESSL_LIBRARY`: Path to `ngtcp2_crypto_libressl` library.
|
||||
# - `NGTCP2_CRYPTO_OSSL_LIBRARY`: Path to `ngtcp2_crypto_ossl` library.
|
||||
# - `NGTCP2_CRYPTO_QUICTLS_LIBRARY`: Path to `ngtcp2_crypto_quictls` library.
|
||||
# - `NGTCP2_CRYPTO_WOLFSSL_LIBRARY`: Path to `ngtcp2_crypto_wolfssl` library.
|
||||
# - `NGTCP2_INCLUDE_DIR`: Absolute path to ngtcp2 include directory.
|
||||
# - `NGTCP2_LIBRARY`: Absolute path to `ngtcp2` library.
|
||||
# - `NGTCP2_CRYPTO_BORINGSSL_LIBRARY`: Absolute path to `ngtcp2_crypto_boringssl` library.
|
||||
# - `NGTCP2_CRYPTO_GNUTLS_LIBRARY`: Absolute path to `ngtcp2_crypto_gnutls` library.
|
||||
# - `NGTCP2_CRYPTO_LIBRESSL_LIBRARY`: Absolute path to `ngtcp2_crypto_libressl` library.
|
||||
# - `NGTCP2_CRYPTO_OSSL_LIBRARY`: Absolute path to `ngtcp2_crypto_ossl` library.
|
||||
# - `NGTCP2_CRYPTO_QUICTLS_LIBRARY`: Absolute path to `ngtcp2_crypto_quictls` library.
|
||||
# - `NGTCP2_CRYPTO_WOLFSSL_LIBRARY`: Absolute path to `ngtcp2_crypto_wolfssl` library.
|
||||
#
|
||||
# Result variables:
|
||||
#
|
||||
@@ -86,7 +86,7 @@ if(CURL_USE_PKGCONFIG AND
|
||||
endif()
|
||||
|
||||
if(NGTCP2_FOUND)
|
||||
set(NGTCP2_VERSION "${NGTCP2_libngtcp2_VERSION}")
|
||||
set(NGTCP2_VERSION ${NGTCP2_libngtcp2_VERSION})
|
||||
string(REPLACE ";" " " NGTCP2_CFLAGS "${NGTCP2_CFLAGS}")
|
||||
message(STATUS "Found NGTCP2 (via pkg-config): ${NGTCP2_INCLUDE_DIRS} (found version \"${NGTCP2_VERSION}\")")
|
||||
else()
|
||||
@@ -104,7 +104,11 @@ else()
|
||||
endif()
|
||||
|
||||
if(_ngtcp2_crypto_backend)
|
||||
get_filename_component(_ngtcp2_library_dir "${NGTCP2_LIBRARY}" DIRECTORY)
|
||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.20)
|
||||
cmake_path(GET NGTCP2_LIBRARY PARENT_PATH _ngtcp2_library_dir)
|
||||
else()
|
||||
get_filename_component(_ngtcp2_library_dir "${NGTCP2_LIBRARY}" DIRECTORY)
|
||||
endif()
|
||||
find_library(${_crypto_library_upper}_LIBRARY NAMES ${_crypto_library_lower} HINTS ${_ngtcp2_library_dir})
|
||||
|
||||
if(${_crypto_library_upper}_LIBRARY)
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
#
|
||||
# Input variables:
|
||||
#
|
||||
# - `NETTLE_INCLUDE_DIR`: The nettle include directory.
|
||||
# - `NETTLE_LIBRARY`: Path to `nettle` library.
|
||||
# - `NETTLE_INCLUDE_DIR`: Absolute path to nettle include directory.
|
||||
# - `NETTLE_LIBRARY`: Absolute path to `nettle` library.
|
||||
#
|
||||
# Result variables:
|
||||
#
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
#
|
||||
# Input variables:
|
||||
#
|
||||
# - `QUICHE_INCLUDE_DIR`: The quiche include directory.
|
||||
# - `QUICHE_LIBRARY`: Path to `quiche` library.
|
||||
# - `QUICHE_INCLUDE_DIR`: Absolute path to quiche include directory.
|
||||
# - `QUICHE_LIBRARY`: Absolute path to `quiche` library.
|
||||
#
|
||||
# Result variables:
|
||||
#
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
#
|
||||
# Input variables:
|
||||
#
|
||||
# - `RUSTLS_INCLUDE_DIR`: The Rustls include directory.
|
||||
# - `RUSTLS_LIBRARY`: Path to `rustls` library.
|
||||
# - `RUSTLS_INCLUDE_DIR`: Absolute path to Rustls include directory.
|
||||
# - `RUSTLS_LIBRARY`: Absolute path to `rustls` library.
|
||||
#
|
||||
# Result variables:
|
||||
#
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
# are also available at https://curl.se/docs/copyright.html.
|
||||
#
|
||||
# You may opt to use, copy, modify, merge, publish, distribute 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.
|
||||
#
|
||||
# SPDX-License-Identifier: curl
|
||||
#
|
||||
###########################################################################
|
||||
# Find the wolfSSH library
|
||||
#
|
||||
# Input variables:
|
||||
#
|
||||
# - `WOLFSSH_INCLUDE_DIR`: The wolfSSH include directory.
|
||||
# - `WOLFSSH_LIBRARY`: Path to `wolfssh` library.
|
||||
#
|
||||
# Result variables:
|
||||
#
|
||||
# - `WOLFSSH_FOUND`: System has wolfSSH.
|
||||
# - `WOLFSSH_INCLUDE_DIRS`: The wolfSSH include directories.
|
||||
# - `WOLFSSH_LIBRARIES`: The wolfSSH library names.
|
||||
# - `WOLFSSH_VERSION`: Version of wolfSSH.
|
||||
|
||||
find_path(WOLFSSH_INCLUDE_DIR NAMES "wolfssh/ssh.h")
|
||||
find_library(WOLFSSH_LIBRARY NAMES "wolfssh" "libwolfssh")
|
||||
|
||||
unset(WOLFSSH_VERSION CACHE)
|
||||
if(WOLFSSH_INCLUDE_DIR AND EXISTS "${WOLFSSH_INCLUDE_DIR}/wolfssh/version.h")
|
||||
set(_version_regex "#[\t ]*define[\t ]+LIBWOLFSSH_VERSION_STRING[\t ]+\"([^\"]*)\"")
|
||||
file(STRINGS "${WOLFSSH_INCLUDE_DIR}/wolfssh/version.h" _version_str REGEX "${_version_regex}")
|
||||
string(REGEX REPLACE "${_version_regex}" "\\1" _version_str "${_version_str}")
|
||||
set(WOLFSSH_VERSION "${_version_str}")
|
||||
unset(_version_regex)
|
||||
unset(_version_str)
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(WolfSSH
|
||||
REQUIRED_VARS
|
||||
WOLFSSH_INCLUDE_DIR
|
||||
WOLFSSH_LIBRARY
|
||||
VERSION_VAR
|
||||
WOLFSSH_VERSION
|
||||
)
|
||||
|
||||
if(WOLFSSH_FOUND)
|
||||
set(WOLFSSH_INCLUDE_DIRS ${WOLFSSH_INCLUDE_DIR})
|
||||
set(WOLFSSH_LIBRARIES ${WOLFSSH_LIBRARY})
|
||||
endif()
|
||||
|
||||
mark_as_advanced(WOLFSSH_INCLUDE_DIR WOLFSSH_LIBRARY)
|
||||
@@ -25,8 +25,8 @@
|
||||
#
|
||||
# Input variables:
|
||||
#
|
||||
# - `WOLFSSL_INCLUDE_DIR`: The wolfSSL include directory.
|
||||
# - `WOLFSSL_LIBRARY`: Path to `wolfssl` library.
|
||||
# - `WOLFSSL_INCLUDE_DIR`: Absolute path to wolfSSL include directory.
|
||||
# - `WOLFSSL_LIBRARY`: Absolute path to `wolfssl` library.
|
||||
#
|
||||
# Result variables:
|
||||
#
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
#
|
||||
# Input variables:
|
||||
#
|
||||
# - `ZSTD_INCLUDE_DIR`: The zstd include directory.
|
||||
# - `ZSTD_LIBRARY`: Path to `zstd` library.
|
||||
# - `ZSTD_INCLUDE_DIR`: Absolute path to zstd include directory.
|
||||
# - `ZSTD_LIBRARY`: Absolute path to `zstd` library.
|
||||
#
|
||||
# Result variables:
|
||||
#
|
||||
|
||||
@@ -29,12 +29,10 @@ set(_picky_nocheck "") # not to pass to feature checks
|
||||
if(CURL_WERROR)
|
||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.24)
|
||||
set(CMAKE_COMPILE_WARNING_AS_ERROR ON)
|
||||
else()
|
||||
if(MSVC)
|
||||
list(APPEND _picky_nocheck "-WX")
|
||||
else() # llvm/clang and gcc style options
|
||||
list(APPEND _picky_nocheck "-Werror")
|
||||
endif()
|
||||
elseif(MSVC)
|
||||
list(APPEND _picky_nocheck "-WX")
|
||||
else() # llvm/clang and gcc-style options
|
||||
list(APPEND _picky_nocheck "-Werror")
|
||||
endif()
|
||||
|
||||
if((CMAKE_C_COMPILER_ID STREQUAL "GNU" AND
|
||||
@@ -47,8 +45,8 @@ endif()
|
||||
|
||||
if(APPLE AND
|
||||
(CMAKE_C_COMPILER_ID STREQUAL "Clang" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 3.6) OR
|
||||
(CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 6.3))
|
||||
list(APPEND _picky "-Werror=partial-availability") # clang 3.6 appleclang 6.3
|
||||
(CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 6.1))
|
||||
list(APPEND _picky "-Werror=partial-availability") # clang 3.6 appleclang 6.1
|
||||
endif()
|
||||
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
@@ -87,6 +85,9 @@ if(PICKY_COMPILER)
|
||||
set(_picky_detect
|
||||
)
|
||||
|
||||
# Notes: -Wno-* options should ideally be disabled at their precise cutoff versions,
|
||||
# to suppress undesired warnings in case -Weverything is passed as a custom option.
|
||||
|
||||
# Assume these options always exist with both clang and gcc.
|
||||
# Require clang 3.0 / gcc 2.95 or later.
|
||||
list(APPEND _picky_enable
|
||||
@@ -121,13 +122,14 @@ if(PICKY_COMPILER)
|
||||
-Wmissing-field-initializers # clang 2.7 gcc 4.1
|
||||
-Wmissing-noreturn # clang 2.7 gcc 4.1
|
||||
-Wno-format-nonliteral # clang 1.0 gcc 2.96 (3.0)
|
||||
-Wno-padded # clang 2.9 gcc 4.1 # Not used: We cannot change public structs
|
||||
-Wno-sign-conversion # clang 2.9 gcc 4.3
|
||||
-Wno-switch-default # clang 2.7 gcc 4.1 # Not used: Annoying to fix or silence
|
||||
-Wno-switch-enum # clang 2.7 gcc 4.1 # Not used: It basically disallows default case
|
||||
-Wno-system-headers # clang 1.0 gcc 3.0
|
||||
# -Wpadded # clang 2.9 gcc 4.1 # Not used: We cannot change public structs
|
||||
-Wold-style-definition # clang 2.7 gcc 3.4
|
||||
-Wredundant-decls # clang 2.7 gcc 4.1
|
||||
-Wstrict-prototypes # clang 1.0 gcc 3.3
|
||||
# -Wswitch-enum # clang 2.7 gcc 4.1 # Not used: It basically disallows default case
|
||||
-Wtype-limits # clang 2.7 gcc 4.3
|
||||
-Wunreachable-code # clang 2.7 gcc 4.1
|
||||
# -Wunused-macros # clang 2.7 gcc 4.1 # Not practical
|
||||
@@ -139,6 +141,8 @@ if(PICKY_COMPILER)
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
list(APPEND _picky_enable
|
||||
${_picky_common_old}
|
||||
-Wconditional-uninitialized # clang 3.0
|
||||
-Wno-used-but-marked-unused # clang 3.0 # Triggered by typecheck-gcc.h (with clang 14+)
|
||||
-Wshift-sign-overflow # clang 2.9
|
||||
-Wshorten-64-to-32 # clang 1.0
|
||||
-Wformat=2 # clang 3.0 gcc 4.8
|
||||
@@ -149,39 +153,102 @@ if(PICKY_COMPILER)
|
||||
)
|
||||
endif()
|
||||
# Enable based on compiler version
|
||||
if((CMAKE_C_COMPILER_ID STREQUAL "Clang" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 3.6) OR
|
||||
(CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 6.3))
|
||||
if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 3.1)
|
||||
list(APPEND _picky_enable
|
||||
-Wdouble-promotion # clang 3.6 gcc 4.6 appleclang 6.3
|
||||
-Wenum-conversion # clang 3.2 gcc 10.0 appleclang 4.6 g++ 11.0
|
||||
-Wno-covered-switch-default # clang 3.1 appleclang 3.1 # Annoying to fix or silence
|
||||
-Wno-disabled-macro-expansion # clang 3.1 appleclang 3.1 # Triggered by typecheck-gcc.h (with clang 14+)
|
||||
)
|
||||
if(MSVC)
|
||||
list(APPEND _picky_enable
|
||||
-Wno-format-non-iso # clang 3.1 appleclang 3.1 # 'q' length modifier is not supported by ISO C
|
||||
)
|
||||
else()
|
||||
list(APPEND _picky_enable
|
||||
-Wformat-non-iso # clang 3.1 appleclang 3.1
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
if((CMAKE_C_COMPILER_ID STREQUAL "Clang" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 3.3) OR
|
||||
(CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 5.0))
|
||||
list(APPEND _picky_enable
|
||||
-Wenum-conversion # clang 3.2 gcc 10.0 appleclang 4.2 g++ 11.0
|
||||
-Wmissing-variable-declarations # clang 3.2 appleclang 4.2
|
||||
-Wno-documentation-unknown-command # clang 3.3 appleclang 5.0
|
||||
-Wsometimes-uninitialized # clang 3.2 appleclang 4.2
|
||||
)
|
||||
endif()
|
||||
if((CMAKE_C_COMPILER_ID STREQUAL "Clang" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 3.6) OR
|
||||
(CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 6.1))
|
||||
list(APPEND _picky_enable
|
||||
-Wdouble-promotion # clang 3.6 gcc 4.6 appleclang 6.1
|
||||
-Wheader-guard # clang 3.4 appleclang 5.1
|
||||
-Wpragmas # clang 3.5 gcc 4.1 appleclang 6.0
|
||||
-Wsometimes-uninitialized # clang 3.2 appleclang 4.6
|
||||
# -Wunreachable-code-break # clang 3.5 appleclang 6.0 # Not used: Silent in "unity" builds
|
||||
-Wunused-const-variable # clang 3.4 gcc 6.0 appleclang 5.1
|
||||
)
|
||||
endif()
|
||||
if((CMAKE_C_COMPILER_ID STREQUAL "Clang" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 3.9) OR
|
||||
(CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 8.3))
|
||||
(CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 8.1))
|
||||
list(APPEND _picky_enable
|
||||
-Wcomma # clang 3.9 appleclang 8.3
|
||||
-Wmissing-variable-declarations # clang 3.2 appleclang 4.6
|
||||
-Wcomma # clang 3.9 appleclang 8.1
|
||||
)
|
||||
if(MSVC)
|
||||
list(APPEND _picky_enable
|
||||
-Wno-nonportable-system-include-path # clang 3.9 appleclang 8.1 # No truly portable solution to this
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
if((CMAKE_C_COMPILER_ID STREQUAL "Clang" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 7.0) OR
|
||||
(CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 10.3))
|
||||
(CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 11))
|
||||
list(APPEND _picky_enable
|
||||
-Wassign-enum # clang 7.0 appleclang 10.3
|
||||
-Wextra-semi-stmt # clang 7.0 appleclang 10.3
|
||||
-Wassign-enum # clang 7.0 appleclang 11.0
|
||||
-Wextra-semi-stmt # clang 7.0 appleclang 11.0
|
||||
)
|
||||
endif()
|
||||
if((CMAKE_C_COMPILER_ID STREQUAL "Clang" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 10.0) OR
|
||||
(CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 12.4))
|
||||
(CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 12))
|
||||
list(APPEND _picky_enable
|
||||
-Wimplicit-fallthrough # clang 4.0 gcc 7.0 appleclang 12.4 # We do silencing for clang 10.0 and above only
|
||||
-Wxor-used-as-pow # clang 10.0 gcc 13.0
|
||||
-Wimplicit-fallthrough # clang 4.0 gcc 7.0 appleclang 9.0 # We do silencing for clang 10.0 and above only
|
||||
-Wxor-used-as-pow # clang 10.0 gcc 13.0 appleclang 12.0
|
||||
)
|
||||
endif()
|
||||
if((CMAKE_C_COMPILER_ID STREQUAL "Clang" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 13.0) OR
|
||||
(CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 13.1))
|
||||
list(APPEND _picky_enable
|
||||
-Wcast-function-type # clang 13.0 appleclang 13.1
|
||||
-Wreserved-identifier # clang 13.0 appleclang 13.1 # Keep it before -Wno-reserved-macro-identifier
|
||||
-Wno-reserved-macro-identifier # clang 13.0 appleclang 13.1 # External macros have to be set sometimes
|
||||
)
|
||||
endif()
|
||||
if((CMAKE_C_COMPILER_ID STREQUAL "Clang" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 16.0) OR
|
||||
(CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 15.0))
|
||||
list(APPEND _picky_enable
|
||||
-Wno-unsafe-buffer-usage # clang 16.0 appleclang 15.0
|
||||
)
|
||||
endif()
|
||||
if((CMAKE_C_COMPILER_ID STREQUAL "Clang" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 16.0) OR
|
||||
(CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 16.0))
|
||||
list(APPEND _picky_enable
|
||||
-Wcast-function-type-strict # clang 16.0 appleclang 16.0
|
||||
)
|
||||
endif()
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "Clang" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 21.0)
|
||||
list(APPEND _picky_enable
|
||||
-Warray-compare # clang 20.0 gcc 12.0 appleclang ?
|
||||
-Wc++-hidden-decl # clang 21.0 appleclang ?
|
||||
-Wno-implicit-void-ptr-cast # clang 21.0 appleclang ?
|
||||
-Wtentative-definition-compat # clang 21.0 appleclang ?
|
||||
)
|
||||
if(WIN32)
|
||||
list(APPEND _picky_enable
|
||||
-Wno-c++-keyword # clang 21.0 appleclang ? # `wchar_t` triggers it on Windows
|
||||
)
|
||||
else()
|
||||
list(APPEND _picky_enable
|
||||
-Wc++-keyword # clang 21.0 appleclang ?
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
else() # gcc
|
||||
# Enable based on compiler version
|
||||
if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 4.3)
|
||||
@@ -207,7 +274,7 @@ if(PICKY_COMPILER)
|
||||
endif()
|
||||
if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 4.8)
|
||||
list(APPEND _picky_enable
|
||||
-Wdouble-promotion # clang 3.6 gcc 4.6 appleclang 6.3
|
||||
-Wdouble-promotion # clang 3.6 gcc 4.6 appleclang 6.1
|
||||
-Wformat=2 # clang 3.0 gcc 4.8
|
||||
-Wtrampolines # gcc 4.6
|
||||
)
|
||||
@@ -232,21 +299,21 @@ if(PICKY_COMPILER)
|
||||
-Walloc-zero # gcc 7.0
|
||||
-Wduplicated-branches # gcc 7.0
|
||||
-Wformat-truncation=2 # gcc 7.0
|
||||
-Wimplicit-fallthrough # clang 4.0 gcc 7.0
|
||||
-Wimplicit-fallthrough # clang 4.0 gcc 7.0 appleclang 9.0
|
||||
-Wrestrict # gcc 7.0
|
||||
)
|
||||
endif()
|
||||
if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 10.0)
|
||||
list(APPEND _picky_enable
|
||||
-Warith-conversion # gcc 10.0
|
||||
-Wenum-conversion # clang 3.2 gcc 10.0 appleclang 4.6 g++ 11.0
|
||||
-Wenum-conversion # clang 3.2 gcc 10.0 appleclang 4.2 g++ 11.0
|
||||
)
|
||||
endif()
|
||||
if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 13.0)
|
||||
list(APPEND _picky_enable
|
||||
-Warray-compare # clang 20.0 gcc 12.0
|
||||
-Warray-compare # clang 20.0 gcc 12.0 appleclang ?
|
||||
-Wenum-int-mismatch # gcc 13.0
|
||||
-Wxor-used-as-pow # clang 10.0 gcc 13.0
|
||||
-Wxor-used-as-pow # clang 10.0 gcc 13.0 appleclang 12.0
|
||||
)
|
||||
endif()
|
||||
if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 15.0)
|
||||
@@ -262,8 +329,11 @@ if(PICKY_COMPILER)
|
||||
|
||||
set(_picky_skipped "")
|
||||
foreach(_ccopt IN LISTS _picky_enable)
|
||||
string(REGEX MATCH "-W([a-z0-9-]+)" _ccmatch "${_ccopt}")
|
||||
if(_ccmatch AND CMAKE_C_FLAGS MATCHES "-Wno-${CMAKE_MATCH_1}" AND NOT _ccopt STREQUAL "-Wall" AND NOT _ccopt MATCHES "^-Wno-")
|
||||
string(REGEX MATCH "-W([a-z0-9+-]+)" _ccmatch "${_ccopt}")
|
||||
string(REPLACE "+" "\\+" _cmake_match_1 "${CMAKE_MATCH_1}") # escape '+' to make it a valid regex
|
||||
if(_ccmatch AND "${CMAKE_C_FLAGS} " MATCHES "-Wno-${_cmake_match_1} " AND
|
||||
NOT _ccopt STREQUAL "-Wall" AND
|
||||
NOT _ccopt MATCHES "^-Wno-")
|
||||
string(APPEND _picky_skipped " ${_ccopt}")
|
||||
else()
|
||||
list(APPEND _picky "${_ccopt}")
|
||||
|
||||
@@ -144,7 +144,7 @@ set(HAVE_GETRLIMIT 1)
|
||||
set(HAVE_GETSOCKNAME 1)
|
||||
set(HAVE_GETTIMEOFDAY 1)
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
set(HAVE_GLIBC_STRERROR_R 1)
|
||||
# Depends on C library.
|
||||
else()
|
||||
set(HAVE_GLIBC_STRERROR_R 0)
|
||||
endif()
|
||||
@@ -166,7 +166,7 @@ else()
|
||||
endif()
|
||||
set(HAVE_LIBGEN_H 1)
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
set(HAVE_LINUX_TCP_H 1)
|
||||
# Requires Linux kernel userspace headers. Expected with glibc. May be missing by default with MUSL.
|
||||
else()
|
||||
set(HAVE_LINUX_TCP_H 0)
|
||||
endif()
|
||||
@@ -208,7 +208,7 @@ endif()
|
||||
set(HAVE_POLL 1)
|
||||
set(HAVE_POLL_H 1)
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
set(HAVE_POSIX_STRERROR_R 0)
|
||||
# Depends on C library.
|
||||
else()
|
||||
set(HAVE_POSIX_STRERROR_R 1)
|
||||
endif()
|
||||
|
||||
@@ -191,7 +191,8 @@ if(MINGW OR MSVC)
|
||||
curl_prefill_type_size("LONG_LONG" 8)
|
||||
curl_prefill_type_size("__INT64" 8)
|
||||
curl_prefill_type_size("CURL_OFF_T" 8)
|
||||
# CURL_SOCKET_T, SIZE_T: 8 for _WIN64, 4 otherwise
|
||||
curl_prefill_type_size("CURL_SOCKET_T" ${CMAKE_SIZEOF_VOID_P})
|
||||
curl_prefill_type_size("SIZE_T" ${CMAKE_SIZEOF_VOID_P})
|
||||
# TIME_T: 8 for _WIN64 or UCRT or MSVC and not Windows CE, 4 otherwise
|
||||
# Also 4 for non-UCRT 32-bit when _USE_32BIT_TIME_T is set.
|
||||
# mingw-w64 sets _USE_32BIT_TIME_T unless __MINGW_USE_VC2005_COMPAT is explicit defined.
|
||||
@@ -200,7 +201,7 @@ if(MINGW OR MSVC)
|
||||
set(HAVE_FILE_OFFSET_BITS 0)
|
||||
curl_prefill_type_size("OFF_T" 4)
|
||||
else()
|
||||
# SSIZE_T: 8 for _WIN64, 4 otherwise
|
||||
curl_prefill_type_size("SSIZE_T" ${CMAKE_SIZEOF_VOID_P})
|
||||
set(HAVE_FILE_OFFSET_BITS 1) # mingw-w64 v3+
|
||||
curl_prefill_type_size("OFF_T" 8) # mingw-w64 v3+
|
||||
endif()
|
||||
|
||||
+106
-84
@@ -318,6 +318,13 @@ endif()
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
||||
string(APPEND _target_flags " GCC")
|
||||
endif()
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "AppleClang")
|
||||
string(APPEND _target_flags " APPLE-CLANG")
|
||||
elseif(CMAKE_C_COMPILER_ID STREQUAL "Clang" AND MSVC)
|
||||
string(APPEND _target_flags " CLANG-CL")
|
||||
elseif(CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
string(APPEND _target_flags " LLVM-CLANG")
|
||||
endif()
|
||||
if(MINGW)
|
||||
string(APPEND _target_flags " MINGW")
|
||||
endif()
|
||||
@@ -488,6 +495,26 @@ if(CURL_CLANG_TIDY)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
option(CURL_CODE_COVERAGE "Enable code coverage build options" OFF)
|
||||
if(CURL_CODE_COVERAGE)
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
||||
set(CURL_COVERAGE_MACROS "NDEBUG")
|
||||
set(CURL_COVERAGE_CFLAGS "-O0" "-g" "-fprofile-arcs")
|
||||
if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 4.1)
|
||||
list(APPEND CURL_COVERAGE_CFLAGS "--coverage")
|
||||
else()
|
||||
list(APPEND CURL_COVERAGE_CFLAGS "-ftest-coverage")
|
||||
endif()
|
||||
set(CURL_COVERAGE_LIBS "gcov")
|
||||
elseif(CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
set(CURL_COVERAGE_MACROS "NDEBUG")
|
||||
set(CURL_COVERAGE_CFLAGS "-O0" "-g" "-fprofile-instr-generate" "-fcoverage-mapping")
|
||||
set(CURL_COVERAGE_LDFLAGS "-fprofile-instr-generate" "-fcoverage-mapping")
|
||||
else()
|
||||
set(CURL_CODE_COVERAGE OFF)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# For debug libs and exes, add "-d" postfix
|
||||
if(NOT DEFINED CMAKE_DEBUG_POSTFIX)
|
||||
set(CMAKE_DEBUG_POSTFIX "-d")
|
||||
@@ -806,7 +833,7 @@ elseif(DOS)
|
||||
include_directories(SYSTEM "${WATT_ROOT}/inc")
|
||||
list(APPEND CMAKE_REQUIRED_INCLUDES "${WATT_ROOT}/inc")
|
||||
else()
|
||||
message(FATAL_ERROR "Set WATT_ROOT variable to the root installation of Watt-32.")
|
||||
message(FATAL_ERROR "Set WATT_ROOT variable to the absolute path to the root installation of Watt-32.")
|
||||
endif()
|
||||
elseif(AMIGA)
|
||||
if(AMISSL_INCLUDE_DIR AND AMISSL_STUBS_LIBRARY AND AMISSL_AUTO_LIBRARY)
|
||||
@@ -927,6 +954,26 @@ if(CURL_WINDOWS_SSPI AND NOT WINDOWS_STORE)
|
||||
set(USE_WINDOWS_SSPI ON)
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
option(USE_APPLE_SECTRUST "Use Apple OS-native certificate verification" OFF)
|
||||
if(USE_APPLE_SECTRUST)
|
||||
if(NOT CURL_USE_OPENSSL AND NOT CURL_USE_GNUTLS)
|
||||
message(FATAL_ERROR "Apple SecTrust is only supported with Openssl/GnuTLS")
|
||||
endif()
|
||||
find_library(COREFOUNDATION_FRAMEWORK NAMES "Security")
|
||||
mark_as_advanced(COREFOUNDATION_FRAMEWORK)
|
||||
if(NOT COREFOUNDATION_FRAMEWORK)
|
||||
message(FATAL_ERROR "Security framework not found")
|
||||
endif()
|
||||
list(APPEND CURL_LIBS "-framework Security")
|
||||
|
||||
set(_use_core_foundation_and_core_services ON)
|
||||
message(STATUS "Apple OS-native certificate verification enabled")
|
||||
endif()
|
||||
else()
|
||||
set(USE_APPLE_SECTRUST OFF)
|
||||
endif()
|
||||
|
||||
if(_use_core_foundation_and_core_services)
|
||||
find_library(COREFOUNDATION_FRAMEWORK NAMES "CoreFoundation")
|
||||
mark_as_advanced(COREFOUNDATION_FRAMEWORK)
|
||||
@@ -1025,6 +1072,18 @@ if(CURL_USE_MBEDTLS)
|
||||
set(_valid_default_ssl_backend TRUE)
|
||||
endif()
|
||||
set(_curl_ca_bundle_supported TRUE)
|
||||
|
||||
if(MBEDTLS_VERSION VERSION_GREATER_EQUAL 4.0.0)
|
||||
set(HAVE_MBEDTLS_DES_CRYPT_ECB 0) # pre-fill detection result
|
||||
endif()
|
||||
if(NOT DEFINED HAVE_MBEDTLS_DES_CRYPT_ECB)
|
||||
cmake_push_check_state()
|
||||
list(APPEND CMAKE_REQUIRED_INCLUDES "${MBEDTLS_INCLUDE_DIRS}")
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES "${MBEDTLS_LIBRARIES}")
|
||||
curl_required_libpaths("${MBEDTLS_LIBRARY_DIRS}")
|
||||
check_function_exists("mbedtls_des_crypt_ecb" HAVE_MBEDTLS_DES_CRYPT_ECB) # in mbedTLS <4
|
||||
cmake_pop_check_state()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CURL_USE_WOLFSSL)
|
||||
@@ -1047,27 +1106,23 @@ if(CURL_USE_WOLFSSL)
|
||||
endif()
|
||||
|
||||
if(CURL_USE_GNUTLS)
|
||||
if(CURL_USE_PKGCONFIG)
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(GNUTLS "gnutls")
|
||||
if(GNUTLS_FOUND)
|
||||
set(GNUTLS_LIBRARIES ${GNUTLS_LINK_LIBRARIES})
|
||||
string(REPLACE ";" " " GNUTLS_CFLAGS "${GNUTLS_CFLAGS}")
|
||||
if(GNUTLS_CFLAGS)
|
||||
string(APPEND CMAKE_C_FLAGS " ${GNUTLS_CFLAGS}")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
if(NOT GNUTLS_FOUND)
|
||||
find_package(GnuTLS REQUIRED)
|
||||
find_package(GnuTLS REQUIRED)
|
||||
list(APPEND CURL_LIBS ${GNUTLS_LIBRARIES})
|
||||
list(APPEND CURL_LIBDIRS ${GNUTLS_LIBRARY_DIRS})
|
||||
list(APPEND LIBCURL_PC_REQUIRES_PRIVATE ${GNUTLS_PC_REQUIRES})
|
||||
include_directories(SYSTEM ${GNUTLS_INCLUDE_DIRS})
|
||||
link_directories(${GNUTLS_LIBRARY_DIRS})
|
||||
if(GNUTLS_CFLAGS)
|
||||
string(APPEND CMAKE_C_FLAGS " ${GNUTLS_CFLAGS}")
|
||||
endif()
|
||||
|
||||
find_package(Nettle REQUIRED)
|
||||
set(_ssl_enabled ON)
|
||||
set(USE_GNUTLS ON)
|
||||
list(APPEND CURL_LIBS ${GNUTLS_LIBRARIES} ${NETTLE_LIBRARIES})
|
||||
list(APPEND CURL_LIBDIRS ${GNUTLS_LIBRARY_DIRS} ${NETTLE_LIBRARY_DIRS})
|
||||
list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "gnutls" ${NETTLE_PC_REQUIRES})
|
||||
include_directories(SYSTEM ${GNUTLS_INCLUDE_DIRS} ${NETTLE_INCLUDE_DIRS})
|
||||
list(APPEND CURL_LIBS ${NETTLE_LIBRARIES})
|
||||
list(APPEND CURL_LIBDIRS ${NETTLE_LIBRARY_DIRS})
|
||||
list(APPEND LIBCURL_PC_REQUIRES_PRIVATE ${NETTLE_PC_REQUIRES})
|
||||
include_directories(SYSTEM ${NETTLE_INCLUDE_DIRS})
|
||||
link_directories(${NETTLE_LIBRARY_DIRS})
|
||||
if(NETTLE_CFLAGS)
|
||||
string(APPEND CMAKE_C_FLAGS " ${NETTLE_CFLAGS}")
|
||||
@@ -1082,6 +1137,7 @@ if(CURL_USE_GNUTLS)
|
||||
cmake_push_check_state()
|
||||
list(APPEND CMAKE_REQUIRED_INCLUDES "${GNUTLS_INCLUDE_DIRS}")
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES "${GNUTLS_LIBRARIES}")
|
||||
curl_required_libpaths("${GNUTLS_LIBRARY_DIRS}")
|
||||
check_symbol_exists("gnutls_srp_verifier" "gnutls/gnutls.h" HAVE_GNUTLS_SRP)
|
||||
cmake_pop_check_state()
|
||||
endif()
|
||||
@@ -1244,6 +1300,9 @@ if(USE_WOLFSSL)
|
||||
endif()
|
||||
|
||||
if(USE_OPENSSL)
|
||||
if(NOT DEFINED HAVE_DES_ECB_ENCRYPT)
|
||||
curl_openssl_check_exists("DES_ecb_encrypt" "openssl/des.h" HAVE_DES_ECB_ENCRYPT)
|
||||
endif()
|
||||
if(NOT DEFINED HAVE_SSL_SET0_WBIO)
|
||||
curl_openssl_check_exists("SSL_set0_wbio" HAVE_SSL_SET0_WBIO)
|
||||
endif()
|
||||
@@ -1576,23 +1635,6 @@ if(NOT USE_LIBSSH2 AND CURL_USE_LIBSSH)
|
||||
set(USE_LIBSSH ON)
|
||||
endif()
|
||||
|
||||
# wolfSSH
|
||||
option(CURL_USE_WOLFSSH "Use wolfSSH" OFF)
|
||||
mark_as_advanced(CURL_USE_WOLFSSH)
|
||||
set(USE_WOLFSSH OFF)
|
||||
if(NOT USE_LIBSSH2 AND NOT USE_LIBSSH AND CURL_USE_WOLFSSH)
|
||||
if(USE_WOLFSSL)
|
||||
find_package(WolfSSH)
|
||||
if(WOLFSSH_FOUND)
|
||||
set(CURL_LIBS ${WOLFSSH_LIBRARIES} ${CURL_LIBS}) # keep it before TLS-crypto, compression
|
||||
include_directories(SYSTEM ${WOLFSSH_INCLUDE_DIRS})
|
||||
set(USE_WOLFSSH ON)
|
||||
endif()
|
||||
else()
|
||||
message(WARNING "wolfSSH requires wolfSSL. Skipping.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
option(CURL_USE_GSASL "Use libgsasl" OFF)
|
||||
mark_as_advanced(CURL_USE_GSASL)
|
||||
if(CURL_USE_GSASL)
|
||||
@@ -1627,38 +1669,8 @@ if(CURL_USE_GSSAPI)
|
||||
|
||||
if(GSS_FLAVOUR STREQUAL "GNU")
|
||||
set(HAVE_GSSGNU 1)
|
||||
else()
|
||||
cmake_push_check_state()
|
||||
list(APPEND CMAKE_REQUIRED_INCLUDES "${GSS_INCLUDE_DIRS}")
|
||||
|
||||
set(_include_list "")
|
||||
check_include_file("gssapi/gssapi.h" HAVE_GSSAPI_GSSAPI_H)
|
||||
if(HAVE_GSSAPI_GSSAPI_H)
|
||||
list(APPEND _include_list "gssapi/gssapi.h")
|
||||
endif()
|
||||
check_include_files("${_include_list};gssapi/gssapi_generic.h" HAVE_GSSAPI_GSSAPI_GENERIC_H)
|
||||
|
||||
if(GSS_FLAVOUR STREQUAL "MIT")
|
||||
check_include_files("${_include_list};gssapi/gssapi_krb5.h" _have_gssapi_gssapi_krb5_h)
|
||||
if(HAVE_GSSAPI_GSSAPI_GENERIC_H)
|
||||
list(APPEND _include_list "gssapi/gssapi_generic.h")
|
||||
endif()
|
||||
if(_have_gssapi_gssapi_krb5_h)
|
||||
list(APPEND _include_list "gssapi/gssapi_krb5.h")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED HAVE_GSS_C_NT_HOSTBASED_SERVICE)
|
||||
string(APPEND CMAKE_REQUIRED_FLAGS " ${GSS_CFLAGS}")
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES "${GSS_LIBRARIES}")
|
||||
curl_required_libpaths("${GSS_LIBRARY_DIRS}")
|
||||
check_symbol_exists("GSS_C_NT_HOSTBASED_SERVICE" "${_include_list}" HAVE_GSS_C_NT_HOSTBASED_SERVICE)
|
||||
endif()
|
||||
if(NOT HAVE_GSS_C_NT_HOSTBASED_SERVICE)
|
||||
set(HAVE_OLD_GSSMIT ON)
|
||||
endif()
|
||||
endif()
|
||||
unset(_include_list)
|
||||
cmake_pop_check_state()
|
||||
elseif(GSS_VERSION) # MIT
|
||||
set(CURL_KRB5_VERSION "\"${GSS_VERSION}\"")
|
||||
endif()
|
||||
else()
|
||||
message(WARNING "GSSAPI has been requested, but no supporting libraries found. Skipping.")
|
||||
@@ -1715,14 +1727,16 @@ if(0) # XXX(cmake): not needed for build within cmake
|
||||
# CA handling
|
||||
#
|
||||
if(_curl_ca_bundle_supported)
|
||||
set(_ca_opt_desc "Set 'none' to disable or 'auto' for auto-detection. Defaults to 'auto'.")
|
||||
|
||||
set(CURL_CA_BUNDLE "auto" CACHE
|
||||
STRING "Path to the CA bundle. Set 'none' to disable or 'auto' for auto-detection. Defaults to 'auto'.")
|
||||
STRING "Absolute path to the CA bundle. ${_ca_opt_desc}")
|
||||
set(CURL_CA_FALLBACK OFF CACHE
|
||||
BOOL "Use built-in CA store of OpenSSL. Defaults to OFF")
|
||||
set(CURL_CA_PATH "auto" CACHE
|
||||
STRING "Location of default CA path. Set 'none' to disable or 'auto' for auto-detection. Defaults to 'auto'.")
|
||||
STRING "Absolute path to a directory containing CA certificates stored individually. ${_ca_opt_desc}")
|
||||
set(CURL_CA_EMBED "" CACHE
|
||||
STRING "Path to the CA bundle to embed in the curl tool.")
|
||||
STRING "Absolute path to the CA bundle to embed in the curl tool.")
|
||||
|
||||
if(CURL_CA_FALLBACK AND NOT CURL_USE_OPENSSL)
|
||||
message(FATAL_ERROR "CURL_CA_FALLBACK only works with OpenSSL.")
|
||||
@@ -1734,7 +1748,7 @@ if(_curl_ca_bundle_supported)
|
||||
unset(CURL_CA_BUNDLE CACHE)
|
||||
elseif(CURL_CA_BUNDLE STREQUAL "auto")
|
||||
unset(CURL_CA_BUNDLE CACHE)
|
||||
if(NOT CMAKE_CROSSCOMPILING AND NOT WIN32)
|
||||
if(NOT CMAKE_CROSSCOMPILING AND NOT WIN32 AND NOT USE_APPLE_SECTRUST)
|
||||
set(_curl_ca_bundle_autodetect TRUE)
|
||||
endif()
|
||||
else()
|
||||
@@ -1773,8 +1787,8 @@ if(_curl_ca_bundle_supported)
|
||||
if(EXISTS "${_search_ca_bundle_path}")
|
||||
message(STATUS "Found CA bundle: ${_search_ca_bundle_path}")
|
||||
set(CURL_CA_BUNDLE "${_search_ca_bundle_path}" CACHE
|
||||
STRING "Path to the CA bundle. Set 'none' to disable or 'auto' for auto-detection. Defaults to 'auto'.")
|
||||
set(CURL_CA_BUNDLE_SET TRUE CACHE BOOL "Path to the CA bundle has been set")
|
||||
STRING "Absolute path to the CA bundle. ${_ca_opt_desc}")
|
||||
set(CURL_CA_BUNDLE_SET TRUE CACHE BOOL "Absolute path to the CA bundle has been set")
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
@@ -1787,8 +1801,8 @@ if(_curl_ca_bundle_supported)
|
||||
unset(_curl_ca_files_found)
|
||||
message(STATUS "Found CA path: ${_search_ca_path}")
|
||||
set(CURL_CA_PATH "${_search_ca_path}" CACHE
|
||||
STRING "Location of default CA path. Set 'none' to disable or 'auto' for auto-detection. Defaults to 'auto'.")
|
||||
set(CURL_CA_PATH_SET TRUE CACHE BOOL "Path to the CA bundle has been set")
|
||||
STRING "Absolute path to a directory containing CA certificates stored individually. ${_ca_opt_desc}")
|
||||
set(CURL_CA_PATH_SET TRUE CACHE BOOL "Absolute path to the CA bundle has been set")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
@@ -2186,6 +2200,9 @@ if(WIN32)
|
||||
endif()
|
||||
|
||||
list(APPEND CURL_LIBS ${CURL_NETWORK_AND_TIME_LIBS})
|
||||
if(CURL_CODE_COVERAGE)
|
||||
list(APPEND CURL_LIBS ${CURL_COVERAGE_LIBS})
|
||||
endif()
|
||||
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "MSVC") # MSVC but exclude clang-cl
|
||||
set_property(DIRECTORY APPEND PROPERTY COMPILE_OPTIONS "-MP") # Parallel compilation
|
||||
@@ -2212,9 +2229,8 @@ endif()
|
||||
# (= regenerate it).
|
||||
function(curl_transform_makefile_inc _input_file _output_file)
|
||||
file(READ ${_input_file} _makefile_inc_text)
|
||||
# cmake-lint: disable=W0106
|
||||
string(REPLACE "$(top_srcdir)" "\${PROJECT_SOURCE_DIR}" _makefile_inc_text ${_makefile_inc_text})
|
||||
string(REPLACE "$(top_builddir)" "\${PROJECT_BINARY_DIR}" _makefile_inc_text ${_makefile_inc_text})
|
||||
string(REPLACE "$(top_srcdir)" "\${PROJECT_SOURCE_DIR}" _makefile_inc_text ${_makefile_inc_text}) # cmake-lint: disable=W0106
|
||||
string(REPLACE "$(top_builddir)" "\${PROJECT_BINARY_DIR}" _makefile_inc_text ${_makefile_inc_text}) # cmake-lint: disable=W0106
|
||||
|
||||
string(REGEX REPLACE "\\\\\n" "!^!^!" _makefile_inc_text ${_makefile_inc_text})
|
||||
string(REGEX REPLACE "([a-zA-Z_][a-zA-Z0-9_]*)[\t ]*=[\t ]*([^\n]*)" "set(\\1 \\2)" _makefile_inc_text ${_makefile_inc_text})
|
||||
@@ -2298,8 +2314,8 @@ endmacro()
|
||||
# NTLM support requires crypto functions from various SSL libs.
|
||||
# These conditions must match those in lib/curl_setup.h.
|
||||
if(NOT CURL_DISABLE_NTLM AND
|
||||
(USE_OPENSSL OR
|
||||
USE_MBEDTLS OR
|
||||
((USE_OPENSSL AND HAVE_DES_ECB_ENCRYPT) OR
|
||||
(USE_MBEDTLS AND HAVE_MBEDTLS_DES_CRYPT_ECB) OR
|
||||
USE_GNUTLS OR
|
||||
USE_WIN32_CRYPTO OR
|
||||
(USE_WOLFSSL AND HAVE_WOLFSSL_DES_ECB_ENCRYPT)))
|
||||
@@ -2333,8 +2349,8 @@ curl_add_if("SMBS" NOT CURL_DISABLE_SMB AND _ssl_enabled AND
|
||||
_use_curl_ntlm_core AND (SIZEOF_CURL_OFF_T GREATER 4))
|
||||
curl_add_if("SMTP" NOT CURL_DISABLE_SMTP)
|
||||
curl_add_if("SMTPS" NOT CURL_DISABLE_SMTP AND _ssl_enabled)
|
||||
curl_add_if("SCP" USE_LIBSSH2 OR USE_LIBSSH OR USE_WOLFSSH)
|
||||
curl_add_if("SFTP" USE_LIBSSH2 OR USE_LIBSSH OR USE_WOLFSSH)
|
||||
curl_add_if("SCP" USE_LIBSSH2 OR USE_LIBSSH)
|
||||
curl_add_if("SFTP" USE_LIBSSH2 OR USE_LIBSSH)
|
||||
curl_add_if("IPFS" NOT CURL_DISABLE_IPFS)
|
||||
curl_add_if("IPNS" NOT CURL_DISABLE_IPFS)
|
||||
curl_add_if("RTSP" NOT CURL_DISABLE_RTSP)
|
||||
@@ -2394,6 +2410,7 @@ curl_add_if("HTTPSRR" _ssl_enabled AND USE_HTTPSRR)
|
||||
curl_add_if("PSL" USE_LIBPSL)
|
||||
curl_add_if("CAcert" CURL_CA_EMBED_SET)
|
||||
curl_add_if("SSLS-EXPORT" _ssl_enabled AND USE_SSLS_EXPORT)
|
||||
curl_add_if("AppleSecTrust" USE_APPLE_SECTRUST AND _ssl_enabled AND (USE_OPENSSL OR USE_GNUTLS))
|
||||
if(_items)
|
||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.13)
|
||||
list(SORT _items CASE INSENSITIVE)
|
||||
@@ -2528,8 +2545,13 @@ if(NOT CURL_DISABLE_INSTALL)
|
||||
elseif(_lib MATCHES "/")
|
||||
# This gets a bit more complex, because we want to specify the
|
||||
# directory separately, and only once per directory
|
||||
get_filename_component(_libdir ${_lib} DIRECTORY)
|
||||
get_filename_component(_libname ${_lib} NAME_WE)
|
||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.20)
|
||||
cmake_path(GET _lib PARENT_PATH _libdir)
|
||||
cmake_path(GET _lib STEM _libname)
|
||||
else()
|
||||
get_filename_component(_libdir "${_lib}" DIRECTORY)
|
||||
get_filename_component(_libname "${_lib}" NAME_WE)
|
||||
endif()
|
||||
if(_libname MATCHES "^lib")
|
||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.20)
|
||||
cmake_path(SET _libdir NORMALIZE "${_libdir}")
|
||||
|
||||
@@ -401,12 +401,12 @@ typedef int (*curl_seek_callback)(void *instream,
|
||||
#define CURL_TRAILERFUNC_ABORT 1
|
||||
|
||||
typedef size_t (*curl_read_callback)(char *buffer,
|
||||
size_t size,
|
||||
size_t nitems,
|
||||
void *instream);
|
||||
size_t size,
|
||||
size_t nitems,
|
||||
void *instream);
|
||||
|
||||
typedef int (*curl_trailer_callback)(struct curl_slist **list,
|
||||
void *userdata);
|
||||
void *userdata);
|
||||
|
||||
typedef enum {
|
||||
CURLSOCKTYPE_IPCXN, /* socket created for a specific IP connection */
|
||||
@@ -1357,7 +1357,8 @@ typedef enum {
|
||||
/* Set the krb4/5 security level, this also enables krb4/5 awareness. This
|
||||
* is a string, 'clear', 'safe', 'confidential' or 'private'. If the string
|
||||
* is set but does not match one of these, 'private' will be used. */
|
||||
CURLOPT(CURLOPT_KRBLEVEL, CURLOPTTYPE_STRINGPOINT, 63),
|
||||
CURLOPTDEPRECATED(CURLOPT_KRBLEVEL, CURLOPTTYPE_STRINGPOINT, 63,
|
||||
8.17.0, "removed"),
|
||||
|
||||
/* Set if we should verify the peer in ssl handshake, set 1 to verify. */
|
||||
CURLOPT(CURLOPT_SSL_VERIFYPEER, CURLOPTTYPE_LONG, 64),
|
||||
@@ -1952,8 +1953,7 @@ typedef enum {
|
||||
/* Pass in a bitmask of "header options" */
|
||||
CURLOPT(CURLOPT_HEADEROPT, CURLOPTTYPE_VALUES, 229),
|
||||
|
||||
/* The public key in DER form used to validate the peer public key
|
||||
this option is used only if SSL_VERIFYPEER is true */
|
||||
/* The public key used to validate the peer public key */
|
||||
CURLOPT(CURLOPT_PINNEDPUBLICKEY, CURLOPTTYPE_STRINGPOINT, 230),
|
||||
|
||||
/* Path to Unix domain socket */
|
||||
|
||||
@@ -32,12 +32,12 @@
|
||||
|
||||
/* This is the version number of the libcurl package from which this header
|
||||
file origins: */
|
||||
#define LIBCURL_VERSION "8.16.0"
|
||||
#define LIBCURL_VERSION "8.17.0"
|
||||
|
||||
/* The numeric version number is also available "in parts" by using these
|
||||
defines: */
|
||||
#define LIBCURL_VERSION_MAJOR 8
|
||||
#define LIBCURL_VERSION_MINOR 16
|
||||
#define LIBCURL_VERSION_MINOR 17
|
||||
#define LIBCURL_VERSION_PATCH 0
|
||||
/* This is the numeric version of the libcurl version number, meant for easier
|
||||
parsing and comparisons by programs. The LIBCURL_VERSION_NUM define will
|
||||
@@ -58,7 +58,7 @@
|
||||
CURL_VERSION_BITS() macro since curl's own configure script greps for it
|
||||
and needs it to contain the full number.
|
||||
*/
|
||||
#define LIBCURL_VERSION_NUM 0x081000
|
||||
#define LIBCURL_VERSION_NUM 0x081100
|
||||
|
||||
/*
|
||||
* This is the date and time when the full source package was created. The
|
||||
|
||||
@@ -398,6 +398,12 @@ typedef enum {
|
||||
/* network has changed, adjust caches/connection reuse */
|
||||
CURLOPT(CURLMOPT_NETWORK_CHANGED, CURLOPTTYPE_LONG, 17),
|
||||
|
||||
/* This is the notify callback function pointer */
|
||||
CURLOPT(CURLMOPT_NOTIFYFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 18),
|
||||
|
||||
/* This is the argument passed to the notify callback */
|
||||
CURLOPT(CURLMOPT_NOTIFYDATA, CURLOPTTYPE_OBJECTPOINT, 19),
|
||||
|
||||
CURLMOPT_LASTENTRY /* the last unused */
|
||||
} CURLMoption;
|
||||
|
||||
@@ -464,7 +470,9 @@ typedef enum {
|
||||
* be read via `curl_multi_info_read()`. */
|
||||
CURLMINFO_XFERS_DONE = 4,
|
||||
/* The total number of easy handles added to the multi handle, ever. */
|
||||
CURLMINFO_XFERS_ADDED = 5
|
||||
CURLMINFO_XFERS_ADDED = 5,
|
||||
|
||||
CURLMINFO_LASTENTRY /* the last unused */
|
||||
} CURLMinfo_offt;
|
||||
|
||||
/*
|
||||
@@ -518,6 +526,26 @@ CURL_EXTERN CURLMcode curl_multi_waitfds(CURLM *multi,
|
||||
unsigned int size,
|
||||
unsigned int *fd_count);
|
||||
|
||||
/*
|
||||
* Notifications dispatched by a multi handle, when enabled.
|
||||
*/
|
||||
#define CURLMNOTIFY_INFO_READ 0
|
||||
#define CURLMNOTIFY_EASY_DONE 1
|
||||
|
||||
/*
|
||||
* Callback to install via CURLMOPT_NOTIFYFUNCTION.
|
||||
*/
|
||||
typedef void (*curl_notify_callback)(CURLM *multi,
|
||||
unsigned int notification,
|
||||
CURL *easy,
|
||||
void *user_data);
|
||||
|
||||
CURL_EXTERN CURLMcode curl_multi_notify_disable(CURLM *multi,
|
||||
unsigned int notification);
|
||||
|
||||
CURL_EXTERN CURLMcode curl_multi_notify_enable(CURLM *multi,
|
||||
unsigned int notification);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* end of extern "C" */
|
||||
#endif
|
||||
|
||||
@@ -29,9 +29,9 @@
|
||||
/* To add a new kind of warning, add an
|
||||
* if(curlcheck_sometype_option(_curl_opt))
|
||||
* if(!curlcheck_sometype(value))
|
||||
* _curl_easy_setopt_err_sometype();
|
||||
* Wcurl_easy_setopt_err_sometype();
|
||||
* block and define curlcheck_sometype_option, curlcheck_sometype and
|
||||
* _curl_easy_setopt_err_sometype below
|
||||
* Wcurl_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
|
||||
@@ -47,113 +47,113 @@
|
||||
CURL_IGNORE_DEPRECATION( \
|
||||
if(curlcheck_long_option(option)) \
|
||||
if(!curlcheck_long(value)) \
|
||||
_curl_easy_setopt_err_long(); \
|
||||
Wcurl_easy_setopt_err_long(); \
|
||||
if(curlcheck_off_t_option(option)) \
|
||||
if(!curlcheck_off_t(value)) \
|
||||
_curl_easy_setopt_err_curl_off_t(); \
|
||||
Wcurl_easy_setopt_err_curl_off_t(); \
|
||||
if(curlcheck_string_option(option)) \
|
||||
if(!curlcheck_string(value)) \
|
||||
_curl_easy_setopt_err_string(); \
|
||||
Wcurl_easy_setopt_err_string(); \
|
||||
if((option) == CURLOPT_PRIVATE) { } \
|
||||
if(curlcheck_write_cb_option(option)) \
|
||||
if(!curlcheck_write_cb(value)) \
|
||||
_curl_easy_setopt_err_write_callback(); \
|
||||
Wcurl_easy_setopt_err_write_callback(); \
|
||||
if(curlcheck_curl_option(option)) \
|
||||
if(!curlcheck_curl(value)) \
|
||||
_curl_easy_setopt_err_curl(); \
|
||||
Wcurl_easy_setopt_err_curl(); \
|
||||
if((option) == CURLOPT_RESOLVER_START_FUNCTION) \
|
||||
if(!curlcheck_resolver_start_callback(value)) \
|
||||
_curl_easy_setopt_err_resolver_start_callback(); \
|
||||
Wcurl_easy_setopt_err_resolver_start_callback(); \
|
||||
if((option) == CURLOPT_READFUNCTION) \
|
||||
if(!curlcheck_read_cb(value)) \
|
||||
_curl_easy_setopt_err_read_cb(); \
|
||||
Wcurl_easy_setopt_err_read_cb(); \
|
||||
if((option) == CURLOPT_IOCTLFUNCTION) \
|
||||
if(!curlcheck_ioctl_cb(value)) \
|
||||
_curl_easy_setopt_err_ioctl_cb(); \
|
||||
Wcurl_easy_setopt_err_ioctl_cb(); \
|
||||
if((option) == CURLOPT_SOCKOPTFUNCTION) \
|
||||
if(!curlcheck_sockopt_cb(value)) \
|
||||
_curl_easy_setopt_err_sockopt_cb(); \
|
||||
Wcurl_easy_setopt_err_sockopt_cb(); \
|
||||
if((option) == CURLOPT_OPENSOCKETFUNCTION) \
|
||||
if(!curlcheck_opensocket_cb(value)) \
|
||||
_curl_easy_setopt_err_opensocket_cb(); \
|
||||
Wcurl_easy_setopt_err_opensocket_cb(); \
|
||||
if((option) == CURLOPT_PROGRESSFUNCTION) \
|
||||
if(!curlcheck_progress_cb(value)) \
|
||||
_curl_easy_setopt_err_progress_cb(); \
|
||||
Wcurl_easy_setopt_err_progress_cb(); \
|
||||
if((option) == CURLOPT_XFERINFOFUNCTION) \
|
||||
if(!curlcheck_xferinfo_cb(value)) \
|
||||
_curl_easy_setopt_err_xferinfo_cb(); \
|
||||
Wcurl_easy_setopt_err_xferinfo_cb(); \
|
||||
if((option) == CURLOPT_DEBUGFUNCTION) \
|
||||
if(!curlcheck_debug_cb(value)) \
|
||||
_curl_easy_setopt_err_debug_cb(); \
|
||||
Wcurl_easy_setopt_err_debug_cb(); \
|
||||
if((option) == CURLOPT_SSL_CTX_FUNCTION) \
|
||||
if(!curlcheck_ssl_ctx_cb(value)) \
|
||||
_curl_easy_setopt_err_ssl_ctx_cb(); \
|
||||
Wcurl_easy_setopt_err_ssl_ctx_cb(); \
|
||||
if(curlcheck_conv_cb_option(option)) \
|
||||
if(!curlcheck_conv_cb(value)) \
|
||||
_curl_easy_setopt_err_conv_cb(); \
|
||||
Wcurl_easy_setopt_err_conv_cb(); \
|
||||
if((option) == CURLOPT_SEEKFUNCTION) \
|
||||
if(!curlcheck_seek_cb(value)) \
|
||||
_curl_easy_setopt_err_seek_cb(); \
|
||||
Wcurl_easy_setopt_err_seek_cb(); \
|
||||
if((option) == CURLOPT_CHUNK_BGN_FUNCTION) \
|
||||
if(!curlcheck_chunk_bgn_cb(value)) \
|
||||
_curl_easy_setopt_err_chunk_bgn_cb(); \
|
||||
Wcurl_easy_setopt_err_chunk_bgn_cb(); \
|
||||
if((option) == CURLOPT_CHUNK_END_FUNCTION) \
|
||||
if(!curlcheck_chunk_end_cb(value)) \
|
||||
_curl_easy_setopt_err_chunk_end_cb(); \
|
||||
Wcurl_easy_setopt_err_chunk_end_cb(); \
|
||||
if((option) == CURLOPT_CLOSESOCKETFUNCTION) \
|
||||
if(!curlcheck_close_socket_cb(value)) \
|
||||
_curl_easy_setopt_err_close_socket_cb(); \
|
||||
Wcurl_easy_setopt_err_close_socket_cb(); \
|
||||
if((option) == CURLOPT_FNMATCH_FUNCTION) \
|
||||
if(!curlcheck_fnmatch_cb(value)) \
|
||||
_curl_easy_setopt_err_fnmatch_cb(); \
|
||||
Wcurl_easy_setopt_err_fnmatch_cb(); \
|
||||
if((option) == CURLOPT_HSTSREADFUNCTION) \
|
||||
if(!curlcheck_hstsread_cb(value)) \
|
||||
_curl_easy_setopt_err_hstsread_cb(); \
|
||||
Wcurl_easy_setopt_err_hstsread_cb(); \
|
||||
if((option) == CURLOPT_HSTSWRITEFUNCTION) \
|
||||
if(!curlcheck_hstswrite_cb(value)) \
|
||||
_curl_easy_setopt_err_hstswrite_cb(); \
|
||||
Wcurl_easy_setopt_err_hstswrite_cb(); \
|
||||
if((option) == CURLOPT_SSH_HOSTKEYFUNCTION) \
|
||||
if(!curlcheck_ssh_hostkey_cb(value)) \
|
||||
_curl_easy_setopt_err_ssh_hostkey_cb(); \
|
||||
Wcurl_easy_setopt_err_ssh_hostkey_cb(); \
|
||||
if((option) == CURLOPT_SSH_KEYFUNCTION) \
|
||||
if(!curlcheck_ssh_key_cb(value)) \
|
||||
_curl_easy_setopt_err_ssh_key_cb(); \
|
||||
Wcurl_easy_setopt_err_ssh_key_cb(); \
|
||||
if((option) == CURLOPT_INTERLEAVEFUNCTION) \
|
||||
if(!curlcheck_interleave_cb(value)) \
|
||||
_curl_easy_setopt_err_interleave_cb(); \
|
||||
Wcurl_easy_setopt_err_interleave_cb(); \
|
||||
if((option) == CURLOPT_PREREQFUNCTION) \
|
||||
if(!curlcheck_prereq_cb(value)) \
|
||||
_curl_easy_setopt_err_prereq_cb(); \
|
||||
Wcurl_easy_setopt_err_prereq_cb(); \
|
||||
if((option) == CURLOPT_TRAILERFUNCTION) \
|
||||
if(!curlcheck_trailer_cb(value)) \
|
||||
_curl_easy_setopt_err_trailer_cb(); \
|
||||
Wcurl_easy_setopt_err_trailer_cb(); \
|
||||
if(curlcheck_cb_data_option(option)) \
|
||||
if(!curlcheck_cb_data(value)) \
|
||||
_curl_easy_setopt_err_cb_data(); \
|
||||
Wcurl_easy_setopt_err_cb_data(); \
|
||||
if((option) == CURLOPT_ERRORBUFFER) \
|
||||
if(!curlcheck_error_buffer(value)) \
|
||||
_curl_easy_setopt_err_error_buffer(); \
|
||||
Wcurl_easy_setopt_err_error_buffer(); \
|
||||
if((option) == CURLOPT_CURLU) \
|
||||
if(!curlcheck_ptr((value), CURLU)) \
|
||||
_curl_easy_setopt_err_curlu(); \
|
||||
Wcurl_easy_setopt_err_curlu(); \
|
||||
if((option) == CURLOPT_STDERR) \
|
||||
if(!curlcheck_FILE(value)) \
|
||||
_curl_easy_setopt_err_FILE(); \
|
||||
Wcurl_easy_setopt_err_FILE(); \
|
||||
if(curlcheck_postfields_option(option)) \
|
||||
if(!curlcheck_postfields(value)) \
|
||||
_curl_easy_setopt_err_postfields(); \
|
||||
Wcurl_easy_setopt_err_postfields(); \
|
||||
if((option) == CURLOPT_HTTPPOST) \
|
||||
if(!curlcheck_arr((value), struct curl_httppost)) \
|
||||
_curl_easy_setopt_err_curl_httpost(); \
|
||||
Wcurl_easy_setopt_err_curl_httpost(); \
|
||||
if((option) == CURLOPT_MIMEPOST) \
|
||||
if(!curlcheck_ptr((value), curl_mime)) \
|
||||
_curl_easy_setopt_err_curl_mimepost(); \
|
||||
Wcurl_easy_setopt_err_curl_mimepost(); \
|
||||
if(curlcheck_slist_option(option)) \
|
||||
if(!curlcheck_arr((value), struct curl_slist)) \
|
||||
_curl_easy_setopt_err_curl_slist(); \
|
||||
Wcurl_easy_setopt_err_curl_slist(); \
|
||||
if((option) == CURLOPT_SHARE) \
|
||||
if(!curlcheck_ptr((value), CURLSH)) \
|
||||
_curl_easy_setopt_err_CURLSH(); \
|
||||
Wcurl_easy_setopt_err_CURLSH(); \
|
||||
) \
|
||||
} \
|
||||
curl_easy_setopt(handle, option, value); \
|
||||
@@ -166,28 +166,28 @@
|
||||
CURL_IGNORE_DEPRECATION( \
|
||||
if(curlcheck_string_info(info)) \
|
||||
if(!curlcheck_arr((arg), char *)) \
|
||||
_curl_easy_getinfo_err_string(); \
|
||||
Wcurl_easy_getinfo_err_string(); \
|
||||
if(curlcheck_long_info(info)) \
|
||||
if(!curlcheck_arr((arg), long)) \
|
||||
_curl_easy_getinfo_err_long(); \
|
||||
Wcurl_easy_getinfo_err_long(); \
|
||||
if(curlcheck_double_info(info)) \
|
||||
if(!curlcheck_arr((arg), double)) \
|
||||
_curl_easy_getinfo_err_double(); \
|
||||
Wcurl_easy_getinfo_err_double(); \
|
||||
if(curlcheck_slist_info(info)) \
|
||||
if(!curlcheck_arr((arg), struct curl_slist *)) \
|
||||
_curl_easy_getinfo_err_curl_slist(); \
|
||||
Wcurl_easy_getinfo_err_curl_slist(); \
|
||||
if(curlcheck_tlssessioninfo_info(info)) \
|
||||
if(!curlcheck_arr((arg), struct curl_tlssessioninfo *)) \
|
||||
_curl_easy_getinfo_err_curl_tlssessioninfo(); \
|
||||
Wcurl_easy_getinfo_err_curl_tlssessioninfo(); \
|
||||
if(curlcheck_certinfo_info(info)) \
|
||||
if(!curlcheck_arr((arg), struct curl_certinfo *)) \
|
||||
_curl_easy_getinfo_err_curl_certinfo(); \
|
||||
Wcurl_easy_getinfo_err_curl_certinfo(); \
|
||||
if(curlcheck_socket_info(info)) \
|
||||
if(!curlcheck_arr((arg), curl_socket_t)) \
|
||||
_curl_easy_getinfo_err_curl_socket(); \
|
||||
Wcurl_easy_getinfo_err_curl_socket(); \
|
||||
if(curlcheck_off_t_info(info)) \
|
||||
if(!curlcheck_arr((arg), curl_off_t)) \
|
||||
_curl_easy_getinfo_err_curl_off_t(); \
|
||||
Wcurl_easy_getinfo_err_curl_off_t(); \
|
||||
) \
|
||||
} \
|
||||
curl_easy_getinfo(handle, info, arg); \
|
||||
@@ -198,25 +198,28 @@
|
||||
if(__builtin_constant_p(option)) { \
|
||||
if(curlcheck_long_option(option)) \
|
||||
if(!curlcheck_long(value)) \
|
||||
_curl_multi_setopt_err_long(); \
|
||||
Wcurl_multi_setopt_err_long(); \
|
||||
if(curlcheck_off_t_option(option)) \
|
||||
if(!curlcheck_off_t(value)) \
|
||||
_curl_multi_setopt_err_curl_off_t(); \
|
||||
Wcurl_multi_setopt_err_curl_off_t(); \
|
||||
if(curlcheck_multicb_data_option(option)) \
|
||||
if(!curlcheck_cb_data(value)) \
|
||||
_curl_multi_setopt_err_cb_data(); \
|
||||
Wcurl_multi_setopt_err_cb_data(); \
|
||||
if(curlcheck_charpp_option(option)) \
|
||||
if(!curlcheck_ptrptr(value, char)) \
|
||||
_curl_multi_setopt_err_charpp(); \
|
||||
Wcurl_multi_setopt_err_charpp(); \
|
||||
if((option) == CURLMOPT_NOTIFYFUNCTION) \
|
||||
if(!curlcheck_multinotify_cb(value)) \
|
||||
Wcurl_multi_setopt_err_notifycb(); \
|
||||
if((option) == CURLMOPT_PUSHFUNCTION) \
|
||||
if(!curlcheck_multipush_cb(value)) \
|
||||
_curl_multi_setopt_err_pushcb(); \
|
||||
Wcurl_multi_setopt_err_pushcb(); \
|
||||
if((option) == CURLMOPT_SOCKETFUNCTION) \
|
||||
if(!curlcheck_multisocket_cb(value)) \
|
||||
_curl_multi_setopt_err_socketcb(); \
|
||||
Wcurl_multi_setopt_err_socketcb(); \
|
||||
if((option) == CURLMOPT_TIMERFUNCTION) \
|
||||
if(!curlcheck_multitimer_cb(value)) \
|
||||
_curl_multi_setopt_err_timercb(); \
|
||||
Wcurl_multi_setopt_err_timercb(); \
|
||||
} \
|
||||
curl_multi_setopt(handle, option, value); \
|
||||
})
|
||||
@@ -224,7 +227,8 @@
|
||||
/* evaluates to true if the option takes a data argument to pass to a
|
||||
callback */
|
||||
#define curlcheck_multicb_data_option(option) \
|
||||
((option) == CURLMOPT_PUSHDATA || \
|
||||
((option) == CURLMOPT_NOTIFYDATA || \
|
||||
(option) == CURLMOPT_PUSHDATA || \
|
||||
(option) == CURLMOPT_SOCKETDATA || \
|
||||
(option) == CURLMOPT_TIMERDATA || \
|
||||
0)
|
||||
@@ -246,17 +250,22 @@
|
||||
curlcheck_cb_compatible((expr), curl_socket_callback))
|
||||
|
||||
/* evaluates to true if expr is of type curl_push_callback */
|
||||
#define curlcheck_multipush_cb(expr) \
|
||||
(curlcheck_NULL(expr) || \
|
||||
#define curlcheck_multipush_cb(expr) \
|
||||
(curlcheck_NULL(expr) || \
|
||||
curlcheck_cb_compatible((expr), curl_push_callback))
|
||||
|
||||
/* evaluates to true if expr is of type curl_push_callback */
|
||||
#define curlcheck_multinotify_cb(expr) \
|
||||
(curlcheck_NULL(expr) || \
|
||||
curlcheck_cb_compatible((expr), curl_notify_callback))
|
||||
|
||||
/*
|
||||
* 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)
|
||||
|
||||
|
||||
/* the actual warnings, triggered by calling the _curl_easy_setopt_err*
|
||||
/* the actual warnings, triggered by calling the Wcurl_easy_setopt_err*
|
||||
* functions */
|
||||
|
||||
/* To define a new warning, use _CURL_WARNING(identifier, "message") */
|
||||
@@ -265,132 +274,134 @@
|
||||
__attribute__((__unused__)) __attribute__((__noinline__)) \
|
||||
id(void) { __asm__(""); }
|
||||
|
||||
CURLWARNING(_curl_multi_setopt_err_long,
|
||||
CURLWARNING(Wcurl_multi_setopt_err_long,
|
||||
"curl_multi_setopt expects a long argument")
|
||||
CURLWARNING(_curl_multi_setopt_err_curl_off_t,
|
||||
CURLWARNING(Wcurl_multi_setopt_err_curl_off_t,
|
||||
"curl_multi_setopt expects a curl_off_t argument")
|
||||
CURLWARNING(_curl_multi_setopt_err_cb_data,
|
||||
CURLWARNING(Wcurl_multi_setopt_err_cb_data,
|
||||
"curl_multi_setopt expects a 'void *' argument")
|
||||
CURLWARNING(_curl_multi_setopt_err_charpp,
|
||||
CURLWARNING(Wcurl_multi_setopt_err_charpp,
|
||||
"curl_multi_setopt expects a 'char **' argument")
|
||||
CURLWARNING(_curl_multi_setopt_err_pushcb,
|
||||
CURLWARNING(Wcurl_multi_setopt_err_pushcb,
|
||||
"curl_multi_setopt expects a curl_push_callback argument")
|
||||
CURLWARNING(_curl_multi_setopt_err_socketcb,
|
||||
CURLWARNING(Wcurl_multi_setopt_err_notifycb,
|
||||
"curl_multi_setopt expects a curl_notify_callback argument")
|
||||
CURLWARNING(Wcurl_multi_setopt_err_socketcb,
|
||||
"curl_multi_setopt expects a curl_socket_callback argument")
|
||||
CURLWARNING(_curl_multi_setopt_err_timercb,
|
||||
CURLWARNING(Wcurl_multi_setopt_err_timercb,
|
||||
"curl_multi_setopt expects a curl_multi_timer_callback argument")
|
||||
|
||||
CURLWARNING(_curl_easy_setopt_err_long,
|
||||
CURLWARNING(Wcurl_easy_setopt_err_long,
|
||||
"curl_easy_setopt expects a long argument")
|
||||
CURLWARNING(_curl_easy_setopt_err_curl_off_t,
|
||||
CURLWARNING(Wcurl_easy_setopt_err_curl_off_t,
|
||||
"curl_easy_setopt expects a curl_off_t argument")
|
||||
CURLWARNING(_curl_easy_setopt_err_string,
|
||||
CURLWARNING(Wcurl_easy_setopt_err_string,
|
||||
"curl_easy_setopt expects a "
|
||||
"string ('char *' or char[]) argument")
|
||||
CURLWARNING(_curl_easy_setopt_err_write_callback,
|
||||
CURLWARNING(Wcurl_easy_setopt_err_write_callback,
|
||||
"curl_easy_setopt expects a curl_write_callback argument")
|
||||
CURLWARNING(_curl_easy_setopt_err_resolver_start_callback,
|
||||
CURLWARNING(Wcurl_easy_setopt_err_resolver_start_callback,
|
||||
"curl_easy_setopt expects a "
|
||||
"curl_resolver_start_callback argument")
|
||||
CURLWARNING(_curl_easy_setopt_err_read_cb,
|
||||
CURLWARNING(Wcurl_easy_setopt_err_read_cb,
|
||||
"curl_easy_setopt expects a curl_read_callback argument")
|
||||
CURLWARNING(_curl_easy_setopt_err_ioctl_cb,
|
||||
CURLWARNING(Wcurl_easy_setopt_err_ioctl_cb,
|
||||
"curl_easy_setopt expects a curl_ioctl_callback argument")
|
||||
CURLWARNING(_curl_easy_setopt_err_sockopt_cb,
|
||||
CURLWARNING(Wcurl_easy_setopt_err_sockopt_cb,
|
||||
"curl_easy_setopt expects a curl_sockopt_callback argument")
|
||||
CURLWARNING(_curl_easy_setopt_err_opensocket_cb,
|
||||
CURLWARNING(Wcurl_easy_setopt_err_opensocket_cb,
|
||||
"curl_easy_setopt expects a "
|
||||
"curl_opensocket_callback argument")
|
||||
CURLWARNING(_curl_easy_setopt_err_progress_cb,
|
||||
CURLWARNING(Wcurl_easy_setopt_err_progress_cb,
|
||||
"curl_easy_setopt expects a curl_progress_callback argument")
|
||||
CURLWARNING(_curl_easy_setopt_err_xferinfo_cb,
|
||||
CURLWARNING(Wcurl_easy_setopt_err_xferinfo_cb,
|
||||
"curl_easy_setopt expects a curl_xferinfo_callback argument")
|
||||
CURLWARNING(_curl_easy_setopt_err_debug_cb,
|
||||
CURLWARNING(Wcurl_easy_setopt_err_debug_cb,
|
||||
"curl_easy_setopt expects a curl_debug_callback argument")
|
||||
CURLWARNING(_curl_easy_setopt_err_ssl_ctx_cb,
|
||||
CURLWARNING(Wcurl_easy_setopt_err_ssl_ctx_cb,
|
||||
"curl_easy_setopt expects a curl_ssl_ctx_callback argument")
|
||||
CURLWARNING(_curl_easy_setopt_err_conv_cb,
|
||||
CURLWARNING(Wcurl_easy_setopt_err_conv_cb,
|
||||
"curl_easy_setopt expects a curl_conv_callback argument")
|
||||
CURLWARNING(_curl_easy_setopt_err_seek_cb,
|
||||
CURLWARNING(Wcurl_easy_setopt_err_seek_cb,
|
||||
"curl_easy_setopt expects a curl_seek_callback argument")
|
||||
CURLWARNING(_curl_easy_setopt_err_cb_data,
|
||||
CURLWARNING(Wcurl_easy_setopt_err_cb_data,
|
||||
"curl_easy_setopt expects a "
|
||||
"private data pointer as argument")
|
||||
CURLWARNING(_curl_easy_setopt_err_chunk_bgn_cb,
|
||||
CURLWARNING(Wcurl_easy_setopt_err_chunk_bgn_cb,
|
||||
"curl_easy_setopt expects a curl_chunk_bgn_callback argument")
|
||||
CURLWARNING(_curl_easy_setopt_err_chunk_end_cb,
|
||||
CURLWARNING(Wcurl_easy_setopt_err_chunk_end_cb,
|
||||
"curl_easy_setopt expects a curl_chunk_end_callback argument")
|
||||
CURLWARNING(_curl_easy_setopt_err_close_socket_cb,
|
||||
CURLWARNING(Wcurl_easy_setopt_err_close_socket_cb,
|
||||
"curl_easy_setopt expects a curl_closesocket_callback argument")
|
||||
CURLWARNING(_curl_easy_setopt_err_fnmatch_cb,
|
||||
CURLWARNING(Wcurl_easy_setopt_err_fnmatch_cb,
|
||||
"curl_easy_setopt expects a curl_fnmatch_callback argument")
|
||||
CURLWARNING(_curl_easy_setopt_err_hstsread_cb,
|
||||
CURLWARNING(Wcurl_easy_setopt_err_hstsread_cb,
|
||||
"curl_easy_setopt expects a curl_hstsread_callback argument")
|
||||
CURLWARNING(_curl_easy_setopt_err_hstswrite_cb,
|
||||
CURLWARNING(Wcurl_easy_setopt_err_hstswrite_cb,
|
||||
"curl_easy_setopt expects a curl_hstswrite_callback argument")
|
||||
CURLWARNING(_curl_easy_setopt_err_ssh_key_cb,
|
||||
CURLWARNING(Wcurl_easy_setopt_err_ssh_key_cb,
|
||||
"curl_easy_setopt expects a curl_sshkeycallback argument")
|
||||
CURLWARNING(_curl_easy_setopt_err_ssh_hostkey_cb,
|
||||
CURLWARNING(Wcurl_easy_setopt_err_ssh_hostkey_cb,
|
||||
"curl_easy_setopt expects a curl_sshhostkeycallback argument")
|
||||
CURLWARNING(_curl_easy_setopt_err_interleave_cb,
|
||||
CURLWARNING(Wcurl_easy_setopt_err_interleave_cb,
|
||||
"curl_easy_setopt expects a curl_interleave_callback argument")
|
||||
CURLWARNING(_curl_easy_setopt_err_prereq_cb,
|
||||
CURLWARNING(Wcurl_easy_setopt_err_prereq_cb,
|
||||
"curl_easy_setopt expects a curl_prereq_callback argument")
|
||||
CURLWARNING(_curl_easy_setopt_err_trailer_cb,
|
||||
CURLWARNING(Wcurl_easy_setopt_err_trailer_cb,
|
||||
"curl_easy_setopt expects a curl_trailerfunc_ok argument")
|
||||
CURLWARNING(_curl_easy_setopt_err_error_buffer,
|
||||
CURLWARNING(Wcurl_easy_setopt_err_error_buffer,
|
||||
"curl_easy_setopt expects a "
|
||||
"char buffer of CURL_ERROR_SIZE as argument")
|
||||
CURLWARNING(_curl_easy_setopt_err_curlu,
|
||||
CURLWARNING(Wcurl_easy_setopt_err_curlu,
|
||||
"curl_easy_setopt expects a 'CURLU *' argument")
|
||||
CURLWARNING(_curl_easy_setopt_err_curl,
|
||||
CURLWARNING(Wcurl_easy_setopt_err_curl,
|
||||
"curl_easy_setopt expects a 'CURL *' argument")
|
||||
CURLWARNING(_curl_easy_setopt_err_FILE,
|
||||
CURLWARNING(Wcurl_easy_setopt_err_FILE,
|
||||
"curl_easy_setopt expects a 'FILE *' argument")
|
||||
CURLWARNING(_curl_easy_setopt_err_postfields,
|
||||
CURLWARNING(Wcurl_easy_setopt_err_postfields,
|
||||
"curl_easy_setopt expects a 'void *' or 'char *' argument")
|
||||
CURLWARNING(_curl_easy_setopt_err_curl_httpost,
|
||||
CURLWARNING(Wcurl_easy_setopt_err_curl_httpost,
|
||||
"curl_easy_setopt expects a 'struct curl_httppost *' "
|
||||
"argument")
|
||||
CURLWARNING(_curl_easy_setopt_err_curl_mimepost,
|
||||
CURLWARNING(Wcurl_easy_setopt_err_curl_mimepost,
|
||||
"curl_easy_setopt expects a 'curl_mime *' "
|
||||
"argument")
|
||||
CURLWARNING(_curl_easy_setopt_err_curl_slist,
|
||||
CURLWARNING(Wcurl_easy_setopt_err_curl_slist,
|
||||
"curl_easy_setopt expects a 'struct curl_slist *' argument")
|
||||
CURLWARNING(_curl_easy_setopt_err_CURLSH,
|
||||
CURLWARNING(Wcurl_easy_setopt_err_CURLSH,
|
||||
"curl_easy_setopt expects a CURLSH* argument")
|
||||
CURLWARNING(_curl_easy_getinfo_err_string,
|
||||
CURLWARNING(Wcurl_easy_getinfo_err_string,
|
||||
"curl_easy_getinfo expects a pointer to 'char *'")
|
||||
CURLWARNING(_curl_easy_getinfo_err_long,
|
||||
CURLWARNING(Wcurl_easy_getinfo_err_long,
|
||||
"curl_easy_getinfo expects a pointer to long")
|
||||
CURLWARNING(_curl_easy_getinfo_err_double,
|
||||
CURLWARNING(Wcurl_easy_getinfo_err_double,
|
||||
"curl_easy_getinfo expects a pointer to double")
|
||||
CURLWARNING(_curl_easy_getinfo_err_curl_slist,
|
||||
CURLWARNING(Wcurl_easy_getinfo_err_curl_slist,
|
||||
"curl_easy_getinfo expects a pointer to 'struct curl_slist *'")
|
||||
CURLWARNING(_curl_easy_getinfo_err_curl_tlssessioninfo,
|
||||
CURLWARNING(Wcurl_easy_getinfo_err_curl_tlssessioninfo,
|
||||
"curl_easy_getinfo expects a pointer to "
|
||||
"'struct curl_tlssessioninfo *'")
|
||||
CURLWARNING(_curl_easy_getinfo_err_curl_certinfo,
|
||||
CURLWARNING(Wcurl_easy_getinfo_err_curl_certinfo,
|
||||
"curl_easy_getinfo expects a pointer to "
|
||||
"'struct curl_certinfo *'")
|
||||
CURLWARNING(_curl_easy_getinfo_err_curl_socket,
|
||||
CURLWARNING(Wcurl_easy_getinfo_err_curl_socket,
|
||||
"curl_easy_getinfo expects a pointer to curl_socket_t")
|
||||
CURLWARNING(_curl_easy_getinfo_err_curl_off_t,
|
||||
CURLWARNING(Wcurl_easy_getinfo_err_curl_off_t,
|
||||
"curl_easy_getinfo expects a pointer to curl_off_t")
|
||||
|
||||
/* groups of curl_easy_setops options that take the same type of argument */
|
||||
|
||||
/* evaluates to true if option takes a long argument */
|
||||
#define curlcheck_long_option(option) \
|
||||
#define curlcheck_long_option(option) \
|
||||
(0 < (option) && (option) < CURLOPTTYPE_OBJECTPOINT)
|
||||
|
||||
#define curlcheck_off_t_option(option) \
|
||||
(((option) > CURLOPTTYPE_OFF_T) && ((option) < CURLOPTTYPE_BLOB))
|
||||
|
||||
/* option takes a CURL * argument */
|
||||
#define curlcheck_curl_option(option) \
|
||||
((option) == CURLOPT_STREAM_DEPENDS || \
|
||||
(option) == CURLOPT_STREAM_DEPENDS_E || \
|
||||
#define curlcheck_curl_option(option) \
|
||||
((option) == CURLOPT_STREAM_DEPENDS || \
|
||||
(option) == CURLOPT_STREAM_DEPENDS_E || \
|
||||
0)
|
||||
|
||||
/* evaluates to true if option takes a char* argument */
|
||||
@@ -673,7 +684,7 @@ CURLWARNING(_curl_easy_getinfo_err_curl_off_t,
|
||||
(curlcheck_ptr((expr), void) || \
|
||||
curlcheck_ptr((expr), FILE))
|
||||
#else /* be less strict */
|
||||
#define curlcheck_cb_data(expr) \
|
||||
#define curlcheck_cb_data(expr) \
|
||||
curlcheck_any_ptr(expr)
|
||||
#endif
|
||||
|
||||
@@ -704,60 +715,60 @@ CURLWARNING(_curl_easy_getinfo_err_curl_off_t,
|
||||
(curlcheck_NULL(expr) || \
|
||||
curlcheck_cb_compatible((expr), __typeof__(fread) *) || \
|
||||
curlcheck_cb_compatible((expr), curl_read_callback) || \
|
||||
curlcheck_cb_compatible((expr), _curl_read_callback1) || \
|
||||
curlcheck_cb_compatible((expr), _curl_read_callback2) || \
|
||||
curlcheck_cb_compatible((expr), _curl_read_callback3) || \
|
||||
curlcheck_cb_compatible((expr), _curl_read_callback4) || \
|
||||
curlcheck_cb_compatible((expr), _curl_read_callback5) || \
|
||||
curlcheck_cb_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 *);
|
||||
curlcheck_cb_compatible((expr), Wcurl_read_callback1) || \
|
||||
curlcheck_cb_compatible((expr), Wcurl_read_callback2) || \
|
||||
curlcheck_cb_compatible((expr), Wcurl_read_callback3) || \
|
||||
curlcheck_cb_compatible((expr), Wcurl_read_callback4) || \
|
||||
curlcheck_cb_compatible((expr), Wcurl_read_callback5) || \
|
||||
curlcheck_cb_compatible((expr), Wcurl_read_callback6))
|
||||
typedef size_t (*Wcurl_read_callback1)(char *, size_t, size_t, void *);
|
||||
typedef size_t (*Wcurl_read_callback2)(char *, size_t, size_t, const void *);
|
||||
typedef size_t (*Wcurl_read_callback3)(char *, size_t, size_t, FILE *);
|
||||
typedef size_t (*Wcurl_read_callback4)(void *, size_t, size_t, void *);
|
||||
typedef size_t (*Wcurl_read_callback5)(void *, size_t, size_t, const void *);
|
||||
typedef size_t (*Wcurl_read_callback6)(void *, size_t, size_t, FILE *);
|
||||
|
||||
/* evaluates to true if expr is of type curl_write_callback or "similar" */
|
||||
#define curlcheck_write_cb(expr) \
|
||||
(curlcheck_read_cb(expr) || \
|
||||
curlcheck_cb_compatible((expr), __typeof__(fwrite) *) || \
|
||||
curlcheck_cb_compatible((expr), curl_write_callback) || \
|
||||
curlcheck_cb_compatible((expr), _curl_write_callback1) || \
|
||||
curlcheck_cb_compatible((expr), _curl_write_callback2) || \
|
||||
curlcheck_cb_compatible((expr), _curl_write_callback3) || \
|
||||
curlcheck_cb_compatible((expr), _curl_write_callback4) || \
|
||||
curlcheck_cb_compatible((expr), _curl_write_callback5) || \
|
||||
curlcheck_cb_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,
|
||||
curlcheck_cb_compatible((expr), Wcurl_write_callback1) || \
|
||||
curlcheck_cb_compatible((expr), Wcurl_write_callback2) || \
|
||||
curlcheck_cb_compatible((expr), Wcurl_write_callback3) || \
|
||||
curlcheck_cb_compatible((expr), Wcurl_write_callback4) || \
|
||||
curlcheck_cb_compatible((expr), Wcurl_write_callback5) || \
|
||||
curlcheck_cb_compatible((expr), Wcurl_write_callback6))
|
||||
typedef size_t (*Wcurl_write_callback1)(const char *, size_t, size_t, void *);
|
||||
typedef size_t (*Wcurl_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,
|
||||
typedef size_t (*Wcurl_write_callback3)(const char *, size_t, size_t, FILE *);
|
||||
typedef size_t (*Wcurl_write_callback4)(const void *, size_t, size_t, void *);
|
||||
typedef size_t (*Wcurl_write_callback5)(const void *, size_t, size_t,
|
||||
const void *);
|
||||
typedef size_t (*_curl_write_callback6)(const void *, size_t, size_t, FILE *);
|
||||
typedef size_t (*Wcurl_write_callback6)(const void *, size_t, size_t, FILE *);
|
||||
|
||||
/* evaluates to true if expr is of type curl_ioctl_callback or "similar" */
|
||||
#define curlcheck_ioctl_cb(expr) \
|
||||
(curlcheck_NULL(expr) || \
|
||||
curlcheck_cb_compatible((expr), curl_ioctl_callback) || \
|
||||
curlcheck_cb_compatible((expr), _curl_ioctl_callback1) || \
|
||||
curlcheck_cb_compatible((expr), _curl_ioctl_callback2) || \
|
||||
curlcheck_cb_compatible((expr), _curl_ioctl_callback3) || \
|
||||
curlcheck_cb_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 *);
|
||||
curlcheck_cb_compatible((expr), Wcurl_ioctl_callback1) || \
|
||||
curlcheck_cb_compatible((expr), Wcurl_ioctl_callback2) || \
|
||||
curlcheck_cb_compatible((expr), Wcurl_ioctl_callback3) || \
|
||||
curlcheck_cb_compatible((expr), Wcurl_ioctl_callback4))
|
||||
typedef curlioerr (*Wcurl_ioctl_callback1)(CURL *, int, void *);
|
||||
typedef curlioerr (*Wcurl_ioctl_callback2)(CURL *, int, const void *);
|
||||
typedef curlioerr (*Wcurl_ioctl_callback3)(CURL *, curliocmd, void *);
|
||||
typedef curlioerr (*Wcurl_ioctl_callback4)(CURL *, curliocmd, const void *);
|
||||
|
||||
/* evaluates to true if expr is of type curl_sockopt_callback or "similar" */
|
||||
#define curlcheck_sockopt_cb(expr) \
|
||||
(curlcheck_NULL(expr) || \
|
||||
curlcheck_cb_compatible((expr), curl_sockopt_callback) || \
|
||||
curlcheck_cb_compatible((expr), _curl_sockopt_callback1) || \
|
||||
curlcheck_cb_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,
|
||||
curlcheck_cb_compatible((expr), Wcurl_sockopt_callback1) || \
|
||||
curlcheck_cb_compatible((expr), Wcurl_sockopt_callback2))
|
||||
typedef int (*Wcurl_sockopt_callback1)(void *, curl_socket_t, curlsocktype);
|
||||
typedef int (*Wcurl_sockopt_callback2)(const void *, curl_socket_t,
|
||||
curlsocktype);
|
||||
|
||||
/* evaluates to true if expr is of type curl_opensocket_callback or
|
||||
@@ -765,28 +776,28 @@ typedef int (*_curl_sockopt_callback2)(const void *, curl_socket_t,
|
||||
#define curlcheck_opensocket_cb(expr) \
|
||||
(curlcheck_NULL(expr) || \
|
||||
curlcheck_cb_compatible((expr), curl_opensocket_callback) || \
|
||||
curlcheck_cb_compatible((expr), _curl_opensocket_callback1) || \
|
||||
curlcheck_cb_compatible((expr), _curl_opensocket_callback2) || \
|
||||
curlcheck_cb_compatible((expr), _curl_opensocket_callback3) || \
|
||||
curlcheck_cb_compatible((expr), _curl_opensocket_callback4))
|
||||
typedef curl_socket_t (*_curl_opensocket_callback1)
|
||||
curlcheck_cb_compatible((expr), Wcurl_opensocket_callback1) || \
|
||||
curlcheck_cb_compatible((expr), Wcurl_opensocket_callback2) || \
|
||||
curlcheck_cb_compatible((expr), Wcurl_opensocket_callback3) || \
|
||||
curlcheck_cb_compatible((expr), Wcurl_opensocket_callback4))
|
||||
typedef curl_socket_t (*Wcurl_opensocket_callback1)
|
||||
(void *, curlsocktype, struct curl_sockaddr *);
|
||||
typedef curl_socket_t (*_curl_opensocket_callback2)
|
||||
typedef curl_socket_t (*Wcurl_opensocket_callback2)
|
||||
(void *, curlsocktype, const struct curl_sockaddr *);
|
||||
typedef curl_socket_t (*_curl_opensocket_callback3)
|
||||
typedef curl_socket_t (*Wcurl_opensocket_callback3)
|
||||
(const void *, curlsocktype, struct curl_sockaddr *);
|
||||
typedef curl_socket_t (*_curl_opensocket_callback4)
|
||||
typedef curl_socket_t (*Wcurl_opensocket_callback4)
|
||||
(const void *, curlsocktype, const struct curl_sockaddr *);
|
||||
|
||||
/* evaluates to true if expr is of type curl_progress_callback or "similar" */
|
||||
#define curlcheck_progress_cb(expr) \
|
||||
(curlcheck_NULL(expr) || \
|
||||
curlcheck_cb_compatible((expr), curl_progress_callback) || \
|
||||
curlcheck_cb_compatible((expr), _curl_progress_callback1) || \
|
||||
curlcheck_cb_compatible((expr), _curl_progress_callback2))
|
||||
typedef int (*_curl_progress_callback1)(void *,
|
||||
curlcheck_cb_compatible((expr), Wcurl_progress_callback1) || \
|
||||
curlcheck_cb_compatible((expr), Wcurl_progress_callback2))
|
||||
typedef int (*Wcurl_progress_callback1)(void *,
|
||||
double, double, double, double);
|
||||
typedef int (*_curl_progress_callback2)(const void *,
|
||||
typedef int (*Wcurl_progress_callback2)(const void *,
|
||||
double, double, double, double);
|
||||
|
||||
/* evaluates to true if expr is of type curl_xferinfo_callback */
|
||||
@@ -798,29 +809,29 @@ typedef int (*_curl_progress_callback2)(const void *,
|
||||
#define curlcheck_debug_cb(expr) \
|
||||
(curlcheck_NULL(expr) || \
|
||||
curlcheck_cb_compatible((expr), curl_debug_callback) || \
|
||||
curlcheck_cb_compatible((expr), _curl_debug_callback1) || \
|
||||
curlcheck_cb_compatible((expr), _curl_debug_callback2) || \
|
||||
curlcheck_cb_compatible((expr), _curl_debug_callback3) || \
|
||||
curlcheck_cb_compatible((expr), _curl_debug_callback4) || \
|
||||
curlcheck_cb_compatible((expr), _curl_debug_callback5) || \
|
||||
curlcheck_cb_compatible((expr), _curl_debug_callback6) || \
|
||||
curlcheck_cb_compatible((expr), _curl_debug_callback7) || \
|
||||
curlcheck_cb_compatible((expr), _curl_debug_callback8))
|
||||
typedef int (*_curl_debug_callback1) (CURL *,
|
||||
curlcheck_cb_compatible((expr), Wcurl_debug_callback1) || \
|
||||
curlcheck_cb_compatible((expr), Wcurl_debug_callback2) || \
|
||||
curlcheck_cb_compatible((expr), Wcurl_debug_callback3) || \
|
||||
curlcheck_cb_compatible((expr), Wcurl_debug_callback4) || \
|
||||
curlcheck_cb_compatible((expr), Wcurl_debug_callback5) || \
|
||||
curlcheck_cb_compatible((expr), Wcurl_debug_callback6) || \
|
||||
curlcheck_cb_compatible((expr), Wcurl_debug_callback7) || \
|
||||
curlcheck_cb_compatible((expr), Wcurl_debug_callback8))
|
||||
typedef int (*Wcurl_debug_callback1) (CURL *,
|
||||
curl_infotype, char *, size_t, void *);
|
||||
typedef int (*_curl_debug_callback2) (CURL *,
|
||||
typedef int (*Wcurl_debug_callback2) (CURL *,
|
||||
curl_infotype, char *, size_t, const void *);
|
||||
typedef int (*_curl_debug_callback3) (CURL *,
|
||||
typedef int (*Wcurl_debug_callback3) (CURL *,
|
||||
curl_infotype, const char *, size_t, void *);
|
||||
typedef int (*_curl_debug_callback4) (CURL *,
|
||||
typedef int (*Wcurl_debug_callback4) (CURL *,
|
||||
curl_infotype, const char *, size_t, const void *);
|
||||
typedef int (*_curl_debug_callback5) (CURL *,
|
||||
typedef int (*Wcurl_debug_callback5) (CURL *,
|
||||
curl_infotype, unsigned char *, size_t, void *);
|
||||
typedef int (*_curl_debug_callback6) (CURL *,
|
||||
typedef int (*Wcurl_debug_callback6) (CURL *,
|
||||
curl_infotype, unsigned char *, size_t, const void *);
|
||||
typedef int (*_curl_debug_callback7) (CURL *,
|
||||
typedef int (*Wcurl_debug_callback7) (CURL *,
|
||||
curl_infotype, const unsigned char *, size_t, void *);
|
||||
typedef int (*_curl_debug_callback8) (CURL *,
|
||||
typedef int (*Wcurl_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" */
|
||||
@@ -828,66 +839,66 @@ typedef int (*_curl_debug_callback8) (CURL *,
|
||||
#define curlcheck_ssl_ctx_cb(expr) \
|
||||
(curlcheck_NULL(expr) || \
|
||||
curlcheck_cb_compatible((expr), curl_ssl_ctx_callback) || \
|
||||
curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback1) || \
|
||||
curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback2) || \
|
||||
curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback3) || \
|
||||
curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback4) || \
|
||||
curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback5) || \
|
||||
curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback6) || \
|
||||
curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback7) || \
|
||||
curlcheck_cb_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 *,
|
||||
curlcheck_cb_compatible((expr), Wcurl_ssl_ctx_callback1) || \
|
||||
curlcheck_cb_compatible((expr), Wcurl_ssl_ctx_callback2) || \
|
||||
curlcheck_cb_compatible((expr), Wcurl_ssl_ctx_callback3) || \
|
||||
curlcheck_cb_compatible((expr), Wcurl_ssl_ctx_callback4) || \
|
||||
curlcheck_cb_compatible((expr), Wcurl_ssl_ctx_callback5) || \
|
||||
curlcheck_cb_compatible((expr), Wcurl_ssl_ctx_callback6) || \
|
||||
curlcheck_cb_compatible((expr), Wcurl_ssl_ctx_callback7) || \
|
||||
curlcheck_cb_compatible((expr), Wcurl_ssl_ctx_callback8))
|
||||
typedef CURLcode (*Wcurl_ssl_ctx_callback1)(CURL *, void *, void *);
|
||||
typedef CURLcode (*Wcurl_ssl_ctx_callback2)(CURL *, void *, const void *);
|
||||
typedef CURLcode (*Wcurl_ssl_ctx_callback3)(CURL *, const void *, void *);
|
||||
typedef CURLcode (*Wcurl_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 are 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 *,
|
||||
typedef CURLcode (*Wcurl_ssl_ctx_callback5)(CURL *, SSL_CTX *, void *);
|
||||
typedef CURLcode (*Wcurl_ssl_ctx_callback6)(CURL *, SSL_CTX *, const void *);
|
||||
typedef CURLcode (*Wcurl_ssl_ctx_callback7)(CURL *, const SSL_CTX *, void *);
|
||||
typedef CURLcode (*Wcurl_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;
|
||||
typedef Wcurl_ssl_ctx_callback1 Wcurl_ssl_ctx_callback5;
|
||||
typedef Wcurl_ssl_ctx_callback1 Wcurl_ssl_ctx_callback6;
|
||||
typedef Wcurl_ssl_ctx_callback1 Wcurl_ssl_ctx_callback7;
|
||||
typedef Wcurl_ssl_ctx_callback1 Wcurl_ssl_ctx_callback8;
|
||||
#endif
|
||||
|
||||
/* evaluates to true if expr is of type curl_conv_callback or "similar" */
|
||||
#define curlcheck_conv_cb(expr) \
|
||||
(curlcheck_NULL(expr) || \
|
||||
curlcheck_cb_compatible((expr), curl_conv_callback) || \
|
||||
curlcheck_cb_compatible((expr), _curl_conv_callback1) || \
|
||||
curlcheck_cb_compatible((expr), _curl_conv_callback2) || \
|
||||
curlcheck_cb_compatible((expr), _curl_conv_callback3) || \
|
||||
curlcheck_cb_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);
|
||||
curlcheck_cb_compatible((expr), Wcurl_conv_callback1) || \
|
||||
curlcheck_cb_compatible((expr), Wcurl_conv_callback2) || \
|
||||
curlcheck_cb_compatible((expr), Wcurl_conv_callback3) || \
|
||||
curlcheck_cb_compatible((expr), Wcurl_conv_callback4))
|
||||
typedef CURLcode (*Wcurl_conv_callback1)(char *, size_t length);
|
||||
typedef CURLcode (*Wcurl_conv_callback2)(const char *, size_t length);
|
||||
typedef CURLcode (*Wcurl_conv_callback3)(void *, size_t length);
|
||||
typedef CURLcode (*Wcurl_conv_callback4)(const void *, size_t length);
|
||||
|
||||
/* evaluates to true if expr is of type curl_seek_callback or "similar" */
|
||||
#define curlcheck_seek_cb(expr) \
|
||||
(curlcheck_NULL(expr) || \
|
||||
curlcheck_cb_compatible((expr), curl_seek_callback) || \
|
||||
curlcheck_cb_compatible((expr), _curl_seek_callback1) || \
|
||||
curlcheck_cb_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);
|
||||
curlcheck_cb_compatible((expr), Wcurl_seek_callback1) || \
|
||||
curlcheck_cb_compatible((expr), Wcurl_seek_callback2))
|
||||
typedef CURLcode (*Wcurl_seek_callback1)(void *, curl_off_t, int);
|
||||
typedef CURLcode (*Wcurl_seek_callback2)(const void *, curl_off_t, int);
|
||||
|
||||
/* evaluates to true if expr is of type curl_chunk_bgn_callback */
|
||||
#define curlcheck_chunk_bgn_cb(expr) \
|
||||
(curlcheck_NULL(expr) || \
|
||||
curlcheck_cb_compatible((expr), curl_chunk_bgn_callback) || \
|
||||
curlcheck_cb_compatible((expr), _curl_chunk_bgn_callback1) || \
|
||||
curlcheck_cb_compatible((expr), _curl_chunk_bgn_callback2))
|
||||
typedef long (*_curl_chunk_bgn_callback1)(struct curl_fileinfo *,
|
||||
curlcheck_cb_compatible((expr), Wcurl_chunk_bgn_callback1) || \
|
||||
curlcheck_cb_compatible((expr), Wcurl_chunk_bgn_callback2))
|
||||
typedef long (*Wcurl_chunk_bgn_callback1)(struct curl_fileinfo *,
|
||||
void *, int);
|
||||
typedef long (*_curl_chunk_bgn_callback2)(void *, void *, int);
|
||||
typedef long (*Wcurl_chunk_bgn_callback2)(void *, void *, int);
|
||||
|
||||
/* evaluates to true if expr is of type curl_chunk_end_callback */
|
||||
#define curlcheck_chunk_end_cb(expr) \
|
||||
@@ -927,11 +938,11 @@ typedef long (*_curl_chunk_bgn_callback2)(void *, void *, int);
|
||||
/* evaluates to true if expr is of type curl_interleave_callback */
|
||||
#define curlcheck_interleave_cb(expr) \
|
||||
(curlcheck_NULL(expr) || \
|
||||
curlcheck_cb_compatible((expr), _curl_interleave_callback1) || \
|
||||
curlcheck_cb_compatible((expr), _curl_interleave_callback2))
|
||||
typedef size_t (*_curl_interleave_callback1)(void *p, size_t s,
|
||||
curlcheck_cb_compatible((expr), Wcurl_interleave_callback1) || \
|
||||
curlcheck_cb_compatible((expr), Wcurl_interleave_callback2))
|
||||
typedef size_t (*Wcurl_interleave_callback1)(void *p, size_t s,
|
||||
size_t n, void *u);
|
||||
typedef size_t (*_curl_interleave_callback2)(char *p, size_t s,
|
||||
typedef size_t (*Wcurl_interleave_callback2)(char *p, size_t s,
|
||||
size_t n, void *u);
|
||||
|
||||
/* evaluates to true if expr is of type curl_prereq_callback */
|
||||
|
||||
@@ -151,7 +151,7 @@ if(SHARE_LIB_OBJECT AND CMAKE_VERSION VERSION_GREATER_EQUAL 3.12)
|
||||
set_target_properties(${LIB_OBJECT} PROPERTIES
|
||||
POSITION_INDEPENDENT_CODE ON)
|
||||
if(CURL_HIDES_PRIVATE_SYMBOLS)
|
||||
set_property(TARGET ${LIB_OBJECT} APPEND PROPERTY COMPILE_FLAGS "${CURL_CFLAG_SYMBOLS_HIDE}")
|
||||
set_property(TARGET ${LIB_OBJECT} APPEND PROPERTY COMPILE_OPTIONS "${CURL_CFLAG_SYMBOLS_HIDE}")
|
||||
set_property(TARGET ${LIB_OBJECT} APPEND PROPERTY COMPILE_DEFINITIONS "CURL_HIDDEN_SYMBOLS")
|
||||
endif()
|
||||
if(CURL_HAS_LTO)
|
||||
@@ -163,6 +163,10 @@ if(SHARE_LIB_OBJECT AND CMAKE_VERSION VERSION_GREATER_EQUAL 3.12)
|
||||
set_target_properties(${LIB_OBJECT} PROPERTIES INTERPROCEDURAL_OPTIMIZATION TRUE)
|
||||
endif()
|
||||
endif()
|
||||
if(CURL_CODE_COVERAGE)
|
||||
set_property(TARGET ${LIB_OBJECT} APPEND PROPERTY COMPILE_DEFINITIONS ${CURL_COVERAGE_MACROS})
|
||||
set_property(TARGET ${LIB_OBJECT} APPEND PROPERTY COMPILE_OPTIONS ${CURL_COVERAGE_CFLAGS})
|
||||
endif()
|
||||
|
||||
target_include_directories(${LIB_OBJECT} INTERFACE
|
||||
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
|
||||
@@ -189,7 +193,7 @@ if(BUILD_STATIC_LIBS)
|
||||
INTERFACE_COMPILE_DEFINITIONS "CURL_STATICLIB"
|
||||
INTERFACE_LINK_DIRECTORIES "${CURL_LIBDIRS}")
|
||||
if(CURL_HIDES_PRIVATE_SYMBOLS)
|
||||
set_property(TARGET ${LIB_STATIC} APPEND PROPERTY COMPILE_FLAGS "${CURL_CFLAG_SYMBOLS_HIDE}")
|
||||
set_property(TARGET ${LIB_STATIC} APPEND PROPERTY COMPILE_OPTIONS "${CURL_CFLAG_SYMBOLS_HIDE}")
|
||||
set_property(TARGET ${LIB_STATIC} APPEND PROPERTY COMPILE_DEFINITIONS "CURL_HIDDEN_SYMBOLS")
|
||||
endif()
|
||||
if(CURL_HAS_LTO)
|
||||
@@ -201,6 +205,10 @@ if(BUILD_STATIC_LIBS)
|
||||
set_target_properties(${LIB_STATIC} PROPERTIES INTERPROCEDURAL_OPTIMIZATION TRUE)
|
||||
endif()
|
||||
endif()
|
||||
if(CURL_CODE_COVERAGE)
|
||||
set_property(TARGET ${LIB_STATIC} APPEND PROPERTY COMPILE_DEFINITIONS ${CURL_COVERAGE_MACROS})
|
||||
set_property(TARGET ${LIB_STATIC} APPEND PROPERTY COMPILE_OPTIONS ${CURL_COVERAGE_CFLAGS})
|
||||
endif()
|
||||
|
||||
target_include_directories(${LIB_STATIC} INTERFACE
|
||||
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
|
||||
@@ -225,7 +233,7 @@ if(BUILD_SHARED_LIBS)
|
||||
IMPORT_PREFIX "" IMPORT_SUFFIX "${IMPORT_LIB_SUFFIX}${CMAKE_IMPORT_LIBRARY_SUFFIX}"
|
||||
POSITION_INDEPENDENT_CODE ON)
|
||||
if(CURL_HIDES_PRIVATE_SYMBOLS)
|
||||
set_property(TARGET ${LIB_SHARED} APPEND PROPERTY COMPILE_FLAGS "${CURL_CFLAG_SYMBOLS_HIDE}")
|
||||
set_property(TARGET ${LIB_SHARED} APPEND PROPERTY COMPILE_OPTIONS "${CURL_CFLAG_SYMBOLS_HIDE}")
|
||||
set_property(TARGET ${LIB_SHARED} APPEND PROPERTY COMPILE_DEFINITIONS "CURL_HIDDEN_SYMBOLS")
|
||||
endif()
|
||||
if(CURL_HAS_LTO)
|
||||
@@ -237,6 +245,15 @@ if(BUILD_SHARED_LIBS)
|
||||
set_target_properties(${LIB_SHARED} PROPERTIES INTERPROCEDURAL_OPTIMIZATION TRUE)
|
||||
endif()
|
||||
endif()
|
||||
if(CURL_CODE_COVERAGE)
|
||||
set_property(TARGET ${LIB_SHARED} APPEND PROPERTY COMPILE_DEFINITIONS ${CURL_COVERAGE_MACROS})
|
||||
set_property(TARGET ${LIB_SHARED} APPEND PROPERTY COMPILE_OPTIONS ${CURL_COVERAGE_CFLAGS})
|
||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.13)
|
||||
set_property(TARGET ${LIB_SHARED} APPEND PROPERTY LINK_OPTIONS ${CURL_COVERAGE_LDFLAGS})
|
||||
else()
|
||||
set_property(TARGET ${LIB_SHARED} APPEND PROPERTY LINK_FLAGS ${CURL_COVERAGE_LDFLAGS})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
target_include_directories(${LIB_SHARED} INTERFACE
|
||||
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
|
||||
@@ -307,9 +324,9 @@ if(BUILD_SHARED_LIBS)
|
||||
check_c_source_compiles("int main(void) { return 0; }" HAVE_VERSIONED_SYMBOLS)
|
||||
if(HAVE_VERSIONED_SYMBOLS)
|
||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.13)
|
||||
set_target_properties(${LIB_SHARED} PROPERTIES LINK_OPTIONS "${CMAKE_REQUIRED_LINK_OPTIONS}")
|
||||
set_property(TARGET ${LIB_SHARED} APPEND PROPERTY LINK_OPTIONS "${CMAKE_REQUIRED_LINK_OPTIONS}")
|
||||
else()
|
||||
set_target_properties(${LIB_SHARED} PROPERTIES LINK_FLAGS "${CMAKE_REQUIRED_LINK_OPTIONS}")
|
||||
set_property(TARGET ${LIB_SHARED} APPEND PROPERTY LINK_FLAGS "${CMAKE_REQUIRED_LINK_OPTIONS}")
|
||||
endif()
|
||||
else()
|
||||
message(WARNING "Versioned symbols requested, but not supported by the toolchain.")
|
||||
|
||||
@@ -26,10 +26,12 @@
|
||||
LIB_CURLX_CFILES = \
|
||||
curlx/base64.c \
|
||||
curlx/dynbuf.c \
|
||||
curlx/fopen.c \
|
||||
curlx/inet_ntop.c \
|
||||
curlx/inet_pton.c \
|
||||
curlx/multibyte.c \
|
||||
curlx/nonblock.c \
|
||||
curlx/strerr.c \
|
||||
curlx/strparse.c \
|
||||
curlx/timediff.c \
|
||||
curlx/timeval.c \
|
||||
@@ -43,10 +45,12 @@ LIB_CURLX_HFILES = \
|
||||
curlx/base64.h \
|
||||
curlx/curlx.h \
|
||||
curlx/dynbuf.h \
|
||||
curlx/fopen.h \
|
||||
curlx/inet_ntop.h \
|
||||
curlx/inet_pton.h \
|
||||
curlx/multibyte.h \
|
||||
curlx/nonblock.h \
|
||||
curlx/strerr.h \
|
||||
curlx/strparse.h \
|
||||
curlx/timediff.h \
|
||||
curlx/timeval.h \
|
||||
@@ -75,6 +79,7 @@ LIB_VAUTH_HFILES = \
|
||||
vauth/vauth.h
|
||||
|
||||
LIB_VTLS_CFILES = \
|
||||
vtls/apple.c \
|
||||
vtls/cipher_suite.c \
|
||||
vtls/gtls.c \
|
||||
vtls/hostcheck.c \
|
||||
@@ -92,6 +97,7 @@ LIB_VTLS_CFILES = \
|
||||
vtls/x509asn1.c
|
||||
|
||||
LIB_VTLS_HFILES = \
|
||||
vtls/apple.h \
|
||||
vtls/cipher_suite.h \
|
||||
vtls/gtls.h \
|
||||
vtls/hostcheck.h \
|
||||
@@ -127,8 +133,7 @@ LIB_VQUIC_HFILES = \
|
||||
LIB_VSSH_CFILES = \
|
||||
vssh/libssh.c \
|
||||
vssh/libssh2.c \
|
||||
vssh/curl_path.c \
|
||||
vssh/wolfssh.c
|
||||
vssh/curl_path.c
|
||||
|
||||
LIB_VSSH_HFILES = \
|
||||
vssh/curl_path.h \
|
||||
@@ -155,9 +160,9 @@ LIB_CFILES = \
|
||||
cookie.c \
|
||||
cshutdn.c \
|
||||
curl_addrinfo.c \
|
||||
curl_des.c \
|
||||
curl_endian.c \
|
||||
curl_fnmatch.c \
|
||||
curl_fopen.c \
|
||||
curl_get_line.c \
|
||||
curl_gethostname.c \
|
||||
curl_gssapi.c \
|
||||
@@ -182,7 +187,6 @@ LIB_CFILES = \
|
||||
fake_addrinfo.c \
|
||||
file.c \
|
||||
fileinfo.c \
|
||||
fopen.c \
|
||||
formdata.c \
|
||||
ftp.c \
|
||||
ftplistparser.c \
|
||||
@@ -209,7 +213,6 @@ LIB_CFILES = \
|
||||
idn.c \
|
||||
if2ip.c \
|
||||
imap.c \
|
||||
krb5.c \
|
||||
ldap.c \
|
||||
llist.c \
|
||||
macos.c \
|
||||
@@ -221,6 +224,7 @@ LIB_CFILES = \
|
||||
mqtt.c \
|
||||
multi.c \
|
||||
multi_ev.c \
|
||||
multi_ntfy.c \
|
||||
netrc.c \
|
||||
noproxy.c \
|
||||
openldap.c \
|
||||
@@ -285,14 +289,13 @@ LIB_HFILES = \
|
||||
cookie.h \
|
||||
curl_addrinfo.h \
|
||||
curl_ctype.h \
|
||||
curl_des.h \
|
||||
curl_endian.h \
|
||||
curl_fnmatch.h \
|
||||
curl_fopen.h \
|
||||
curl_get_line.h \
|
||||
curl_gethostname.h \
|
||||
curl_gssapi.h \
|
||||
curl_hmac.h \
|
||||
curl_krb5.h \
|
||||
curl_ldap.h \
|
||||
curl_md4.h \
|
||||
curl_md5.h \
|
||||
@@ -323,7 +326,6 @@ LIB_HFILES = \
|
||||
fake_addrinfo.h \
|
||||
file.h \
|
||||
fileinfo.h \
|
||||
fopen.h \
|
||||
formdata.h \
|
||||
ftp.h \
|
||||
ftplistparser.h \
|
||||
@@ -354,6 +356,7 @@ LIB_HFILES = \
|
||||
mqtt.h \
|
||||
multihandle.h \
|
||||
multi_ev.h \
|
||||
multi_ntfy.h \
|
||||
multiif.h \
|
||||
netrc.h \
|
||||
noproxy.h \
|
||||
|
||||
@@ -31,19 +31,18 @@
|
||||
#include <curl/curl.h>
|
||||
#include "urldata.h"
|
||||
#include "altsvc.h"
|
||||
#include "curl_fopen.h"
|
||||
#include "curl_get_line.h"
|
||||
#include "parsedate.h"
|
||||
#include "sendf.h"
|
||||
#include "curlx/warnless.h"
|
||||
#include "fopen.h"
|
||||
#include "rename.h"
|
||||
#include "strdup.h"
|
||||
#include "curlx/inet_pton.h"
|
||||
#include "curlx/strparse.h"
|
||||
#include "connect.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
@@ -227,18 +226,22 @@ static CURLcode altsvc_load(struct altsvcinfo *asi, const char *file)
|
||||
if(!asi->filename)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
fp = fopen(file, FOPEN_READTEXT);
|
||||
fp = curlx_fopen(file, FOPEN_READTEXT);
|
||||
if(fp) {
|
||||
bool eof = FALSE;
|
||||
struct dynbuf buf;
|
||||
curlx_dyn_init(&buf, MAX_ALTSVC_LINE);
|
||||
while(Curl_get_line(&buf, fp)) {
|
||||
const char *lineptr = curlx_dyn_ptr(&buf);
|
||||
curlx_str_passblanks(&lineptr);
|
||||
if(curlx_str_single(&lineptr, '#'))
|
||||
altsvc_add(asi, lineptr);
|
||||
}
|
||||
do {
|
||||
result = Curl_get_line(&buf, fp, &eof);
|
||||
if(!result) {
|
||||
const char *lineptr = curlx_dyn_ptr(&buf);
|
||||
curlx_str_passblanks(&lineptr);
|
||||
if(curlx_str_single(&lineptr, '#'))
|
||||
altsvc_add(asi, lineptr);
|
||||
}
|
||||
} while(!result && !eof);
|
||||
curlx_dyn_free(&buf); /* free the line buffer */
|
||||
fclose(fp);
|
||||
curlx_fclose(fp);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -270,23 +273,23 @@ static CURLcode altsvc_out(struct altsvc *as, FILE *fp)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
fprintf(fp,
|
||||
"%s %s%s%s %u "
|
||||
"%s %s%s%s %u "
|
||||
"\"%d%02d%02d "
|
||||
"%02d:%02d:%02d\" "
|
||||
"%u %u\n",
|
||||
Curl_alpnid2str(as->src.alpnid),
|
||||
src6_pre, as->src.host, src6_post,
|
||||
as->src.port,
|
||||
curl_mfprintf(fp,
|
||||
"%s %s%s%s %u "
|
||||
"%s %s%s%s %u "
|
||||
"\"%d%02d%02d "
|
||||
"%02d:%02d:%02d\" "
|
||||
"%u %u\n",
|
||||
Curl_alpnid2str(as->src.alpnid),
|
||||
src6_pre, as->src.host, src6_post,
|
||||
as->src.port,
|
||||
|
||||
Curl_alpnid2str(as->dst.alpnid),
|
||||
dst6_pre, as->dst.host, dst6_post,
|
||||
as->dst.port,
|
||||
Curl_alpnid2str(as->dst.alpnid),
|
||||
dst6_pre, as->dst.host, dst6_post,
|
||||
as->dst.port,
|
||||
|
||||
stamp.tm_year + 1900, stamp.tm_mon + 1, stamp.tm_mday,
|
||||
stamp.tm_hour, stamp.tm_min, stamp.tm_sec,
|
||||
as->persist, as->prio);
|
||||
stamp.tm_year + 1900, stamp.tm_mon + 1, stamp.tm_mday,
|
||||
stamp.tm_hour, stamp.tm_min, stamp.tm_sec,
|
||||
as->persist, as->prio);
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
@@ -391,7 +394,7 @@ CURLcode Curl_altsvc_save(struct Curl_easy *data,
|
||||
if(result)
|
||||
break;
|
||||
}
|
||||
fclose(out);
|
||||
curlx_fclose(out);
|
||||
if(!result && tempstore && Curl_rename(tempstore, file))
|
||||
result = CURLE_WRITE_ERROR;
|
||||
|
||||
|
||||
@@ -199,8 +199,9 @@ struct Library *SocketBase = NULL;
|
||||
|
||||
#ifdef __libnix__
|
||||
void __request(const char *msg);
|
||||
#define CURL_AMIGA_REQUEST(msg) __request(msg)
|
||||
#else
|
||||
# define __request(msg) Printf((const unsigned char *)(msg "\n\a"), 0)
|
||||
#define CURL_AMIGA_REQUEST(msg) Printf((const unsigned char *)(msg "\n\a"), 0)
|
||||
#endif
|
||||
|
||||
void Curl_amiga_cleanup(void)
|
||||
@@ -217,14 +218,14 @@ CURLcode Curl_amiga_init(void)
|
||||
SocketBase = OpenLibrary((const unsigned char *)"bsdsocket.library", 4);
|
||||
|
||||
if(!SocketBase) {
|
||||
__request("No TCP/IP Stack running!");
|
||||
CURL_AMIGA_REQUEST("No TCP/IP Stack running!");
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
|
||||
if(SocketBaseTags(SBTM_SETVAL(SBTC_ERRNOPTR(sizeof(errno))), (ULONG) &errno,
|
||||
SBTM_SETVAL(SBTC_LOGTAGPTR), (ULONG) "curl",
|
||||
if(SocketBaseTags(SBTM_SETVAL(SBTC_ERRNOPTR(sizeof(errno))), (ULONG)&errno,
|
||||
SBTM_SETVAL(SBTC_LOGTAGPTR), (ULONG)"curl",
|
||||
TAG_DONE)) {
|
||||
__request("SocketBaseTags ERROR");
|
||||
CURL_AMIGA_REQUEST("SocketBaseTags ERROR");
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
|
||||
|
||||
@@ -61,7 +61,6 @@
|
||||
#include "progress.h"
|
||||
#include "curlx/timediff.h"
|
||||
#include "httpsrr.h"
|
||||
#include "strdup.h"
|
||||
|
||||
#include <ares.h>
|
||||
#include <ares_version.h> /* really old c-ares did not include this by
|
||||
@@ -85,20 +84,7 @@
|
||||
#if ARES_VERSION >= 0x011000
|
||||
/* 1.16.0 or later has ares_getaddrinfo */
|
||||
#define HAVE_CARES_GETADDRINFO 1
|
||||
#endif
|
||||
|
||||
#ifdef USE_HTTPSRR
|
||||
#if ARES_VERSION < 0x011c00
|
||||
#error "requires c-ares 1.28.0 or newer for HTTPSRR"
|
||||
#endif
|
||||
#define HTTPSRR_WORKS
|
||||
#endif
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#else
|
||||
/* How long we are willing to wait for additional parallel responses after
|
||||
obtaining a "definitive" one. For old c-ares without getaddrinfo.
|
||||
|
||||
@@ -109,6 +95,18 @@
|
||||
See query_completed_cb() for an explanation of how this is used.
|
||||
*/
|
||||
#define HAPPY_EYEBALLS_DNS_TIMEOUT 5000
|
||||
#endif
|
||||
|
||||
#ifdef USE_HTTPSRR
|
||||
#if ARES_VERSION < 0x011c00
|
||||
#error "requires c-ares 1.28.0 or newer for HTTPSRR"
|
||||
#endif
|
||||
#define HTTPSRR_WORKS
|
||||
#endif
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#define CARES_TIMEOUT_PER_ATTEMPT 2000
|
||||
|
||||
@@ -303,11 +301,13 @@ CURLcode Curl_async_is_resolved(struct Curl_easy *data,
|
||||
|
||||
if(data->state.async.done) {
|
||||
*dns = data->state.async.dns;
|
||||
return CURLE_OK;
|
||||
return ares->result;
|
||||
}
|
||||
|
||||
if(Curl_ares_perform(ares->channel, 0) < 0)
|
||||
return CURLE_UNRECOVERABLE_POLL;
|
||||
if(Curl_ares_perform(ares->channel, 0) < 0) {
|
||||
result = CURLE_UNRECOVERABLE_POLL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
#ifndef HAVE_CARES_GETADDRINFO
|
||||
/* Now that we have checked for any last minute results above, see if there
|
||||
@@ -372,6 +372,9 @@ CURLcode Curl_async_is_resolved(struct Curl_easy *data,
|
||||
result, *dns ? "" : "not ");
|
||||
async_ares_cleanup(data);
|
||||
}
|
||||
|
||||
out:
|
||||
ares->result = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -513,8 +516,6 @@ static void async_ares_hostbyname_cb(void *user_data,
|
||||
(void)timeouts; /* ignored */
|
||||
|
||||
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;
|
||||
|
||||
if(ARES_SUCCESS == status) {
|
||||
@@ -729,6 +730,9 @@ struct Curl_addrinfo *Curl_async_getaddrinfo(struct Curl_easy *data,
|
||||
int *waitp)
|
||||
{
|
||||
struct async_ares_ctx *ares = &data->state.async.ares;
|
||||
#ifdef USE_HTTPSRR
|
||||
char *rrname = NULL;
|
||||
#endif
|
||||
*waitp = 0; /* default to synchronous response */
|
||||
|
||||
if(async_ares_init_lazy(data))
|
||||
@@ -741,14 +745,27 @@ struct Curl_addrinfo *Curl_async_getaddrinfo(struct Curl_easy *data,
|
||||
data->state.async.hostname = strdup(hostname);
|
||||
if(!data->state.async.hostname)
|
||||
return NULL;
|
||||
#ifdef USE_HTTPSRR
|
||||
if(port != 443) {
|
||||
rrname = curl_maprintf("_%d_.https.%s", port, hostname);
|
||||
if(!rrname) {
|
||||
free(data->state.async.hostname);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* initial status - failed */
|
||||
ares->ares_status = ARES_ENOTFOUND;
|
||||
ares->result = CURLE_OK;
|
||||
|
||||
#if ARES_VERSION >= 0x011800 /* >= v1.24.0 */
|
||||
CURL_TRC_DNS(data, "asyn-ares: servers=%s",
|
||||
ares_get_servers_csv(ares->channel));
|
||||
#if !defined(CURL_DISABLE_VERBOSE_STRINGS) && \
|
||||
ARES_VERSION >= 0x011800 /* >= v1.24.0 */
|
||||
if(CURL_TRC_DNS_is_verbose(data)) {
|
||||
char *csv = ares_get_servers_csv(ares->channel);
|
||||
CURL_TRC_DNS(data, "asyn-ares: servers=%s", csv);
|
||||
ares_free_string(csv);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CARES_GETADDRINFO
|
||||
@@ -778,7 +795,7 @@ struct Curl_addrinfo *Curl_async_getaddrinfo(struct Curl_easy *data,
|
||||
* accordingly to save a call to getservbyname in inside C-Ares
|
||||
*/
|
||||
hints.ai_flags = ARES_AI_NUMERICSERV;
|
||||
msnprintf(service, sizeof(service), "%d", port);
|
||||
curl_msnprintf(service, sizeof(service), "%d", port);
|
||||
ares->num_pending = 1;
|
||||
ares_getaddrinfo(ares->channel, data->state.async.hostname,
|
||||
service, &hints, async_ares_addrinfo_cb, data);
|
||||
@@ -790,7 +807,7 @@ struct Curl_addrinfo *Curl_async_getaddrinfo(struct Curl_easy *data,
|
||||
/* The stack seems to be IPv6-enabled */
|
||||
/* areschannel is already setup in the Curl_open() function */
|
||||
CURL_TRC_DNS(data, "asyn-ares: fire off query for A");
|
||||
ares_gethostbyname(ares->channel, hostname, PF_INET,
|
||||
ares_gethostbyname(ares->channel, data->state.async.hostname, PF_INET,
|
||||
async_ares_hostbyname_cb, data);
|
||||
CURL_TRC_DNS(data, "asyn-ares: fire off query for AAAA");
|
||||
ares->num_pending = 2;
|
||||
@@ -809,11 +826,14 @@ struct Curl_addrinfo *Curl_async_getaddrinfo(struct Curl_easy *data,
|
||||
#endif
|
||||
#ifdef USE_HTTPSRR
|
||||
{
|
||||
CURL_TRC_DNS(data, "asyn-ares: fire off query for HTTPSRR");
|
||||
CURL_TRC_DNS(data, "asyn-ares: fire off query for HTTPSRR: %s",
|
||||
rrname ? rrname : data->state.async.hostname);
|
||||
memset(&ares->hinfo, 0, sizeof(ares->hinfo));
|
||||
ares->hinfo.port = -1;
|
||||
ares->hinfo.rrname = rrname;
|
||||
ares->num_pending++; /* one more */
|
||||
ares_query_dnsrec(ares->channel, data->state.async.hostname,
|
||||
ares_query_dnsrec(ares->channel,
|
||||
rrname ? rrname : data->state.async.hostname,
|
||||
ARES_CLASS_IN, ARES_REC_TYPE_HTTPS,
|
||||
async_ares_rr_done, data, NULL);
|
||||
}
|
||||
|
||||
@@ -64,7 +64,6 @@
|
||||
#include "multiif.h"
|
||||
#include "curl_threads.h"
|
||||
#include "select.h"
|
||||
#include "strdup.h"
|
||||
|
||||
#ifdef USE_ARES
|
||||
#include <ares.h>
|
||||
@@ -73,8 +72,7 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
@@ -199,14 +197,6 @@ err_exit:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void async_thrd_cleanup(void *arg)
|
||||
{
|
||||
struct async_thrdd_addr_ctx *addr_ctx = arg;
|
||||
|
||||
Curl_thread_disable_cancel();
|
||||
addr_ctx_unlink(&addr_ctx, NULL);
|
||||
}
|
||||
|
||||
#ifdef HAVE_GETADDRINFO
|
||||
|
||||
/*
|
||||
@@ -220,15 +210,6 @@ static CURL_THREAD_RETURN_T CURL_STDCALL getaddrinfo_thread(void *arg)
|
||||
struct async_thrdd_addr_ctx *addr_ctx = arg;
|
||||
bool do_abort;
|
||||
|
||||
/* clang complains about empty statements and the pthread_cleanup* macros
|
||||
* are pretty ill defined. */
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wextra-semi-stmt"
|
||||
#endif
|
||||
|
||||
Curl_thread_push_cleanup(async_thrd_cleanup, addr_ctx);
|
||||
|
||||
Curl_mutex_acquire(&addr_ctx->mutx);
|
||||
do_abort = addr_ctx->do_abort;
|
||||
Curl_mutex_release(&addr_ctx->mutx);
|
||||
@@ -237,10 +218,7 @@ static CURL_THREAD_RETURN_T CURL_STDCALL getaddrinfo_thread(void *arg)
|
||||
char service[12];
|
||||
int rc;
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
Curl_resolve_test_delay();
|
||||
#endif
|
||||
msnprintf(service, sizeof(service), "%d", addr_ctx->port);
|
||||
curl_msnprintf(service, sizeof(service), "%d", addr_ctx->port);
|
||||
|
||||
rc = Curl_getaddrinfo_ex(addr_ctx->hostname, service,
|
||||
&addr_ctx->hints, &addr_ctx->res);
|
||||
@@ -274,11 +252,6 @@ static CURL_THREAD_RETURN_T CURL_STDCALL getaddrinfo_thread(void *arg)
|
||||
|
||||
}
|
||||
|
||||
Curl_thread_pop_cleanup();
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
addr_ctx_unlink(&addr_ctx, NULL);
|
||||
return 0;
|
||||
}
|
||||
@@ -293,24 +266,11 @@ static CURL_THREAD_RETURN_T CURL_STDCALL gethostbyname_thread(void *arg)
|
||||
struct async_thrdd_addr_ctx *addr_ctx = arg;
|
||||
bool do_abort;
|
||||
|
||||
/* clang complains about empty statements and the pthread_cleanup* macros
|
||||
* are pretty ill defined. */
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wextra-semi-stmt"
|
||||
#endif
|
||||
|
||||
Curl_thread_push_cleanup(async_thrd_cleanup, addr_ctx);
|
||||
|
||||
Curl_mutex_acquire(&addr_ctx->mutx);
|
||||
do_abort = addr_ctx->do_abort;
|
||||
Curl_mutex_release(&addr_ctx->mutx);
|
||||
|
||||
if(!do_abort) {
|
||||
#ifdef DEBUGBUILD
|
||||
Curl_resolve_test_delay();
|
||||
#endif
|
||||
|
||||
addr_ctx->res = Curl_ipv4_resolve_r(addr_ctx->hostname, addr_ctx->port);
|
||||
if(!addr_ctx->res) {
|
||||
addr_ctx->sock_error = SOCKERRNO;
|
||||
@@ -337,12 +297,7 @@ static CURL_THREAD_RETURN_T CURL_STDCALL gethostbyname_thread(void *arg)
|
||||
#endif
|
||||
}
|
||||
|
||||
Curl_thread_pop_cleanup();
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
async_thrd_cleanup(addr_ctx);
|
||||
addr_ctx_unlink(&addr_ctx, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -381,12 +336,12 @@ static void async_thrdd_destroy(struct Curl_easy *data)
|
||||
CURL_TRC_DNS(data, "async_thrdd_destroy, thread joined");
|
||||
}
|
||||
else {
|
||||
/* thread is still running. Detach the thread while mutexed, it will
|
||||
* trigger the cleanup when it releases its reference. */
|
||||
/* thread is still running. Detach it. */
|
||||
Curl_thread_destroy(&addr->thread_hnd);
|
||||
CURL_TRC_DNS(data, "async_thrdd_destroy, thread detached");
|
||||
}
|
||||
}
|
||||
/* release our reference to the shared context */
|
||||
addr_ctx_unlink(&thrdd->addr, data);
|
||||
}
|
||||
|
||||
@@ -406,12 +361,18 @@ static void async_thrdd_rr_done(void *user_data, ares_status_t status,
|
||||
thrdd->rr.result = Curl_httpsrr_from_ares(data, dnsrec, &thrdd->rr.hinfo);
|
||||
}
|
||||
|
||||
static CURLcode async_rr_start(struct Curl_easy *data)
|
||||
static CURLcode async_rr_start(struct Curl_easy *data, int port)
|
||||
{
|
||||
struct async_thrdd_ctx *thrdd = &data->state.async.thrdd;
|
||||
int status;
|
||||
char *rrname = NULL;
|
||||
|
||||
DEBUGASSERT(!thrdd->rr.channel);
|
||||
if(port != 443) {
|
||||
rrname = curl_maprintf("_%d_.https.%s", port, data->conn->host.name);
|
||||
if(!rrname)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
status = ares_init_options(&thrdd->rr.channel, NULL, 0);
|
||||
if(status != ARES_SUCCESS) {
|
||||
thrdd->rr.channel = NULL;
|
||||
@@ -428,8 +389,9 @@ static CURLcode async_rr_start(struct Curl_easy *data)
|
||||
|
||||
memset(&thrdd->rr.hinfo, 0, sizeof(thrdd->rr.hinfo));
|
||||
thrdd->rr.hinfo.port = -1;
|
||||
thrdd->rr.hinfo.rrname = rrname;
|
||||
ares_query_dnsrec(thrdd->rr.channel,
|
||||
data->conn->host.name, ARES_CLASS_IN,
|
||||
rrname ? rrname : data->conn->host.name, ARES_CLASS_IN,
|
||||
ARES_REC_TYPE_HTTPS,
|
||||
async_thrdd_rr_done, data, NULL);
|
||||
CURL_TRC_DNS(data, "Issued HTTPS-RR request for %s", data->conn->host.name);
|
||||
@@ -499,7 +461,7 @@ static bool async_thrdd_init(struct Curl_easy *data,
|
||||
}
|
||||
|
||||
#ifdef USE_HTTPSRR_ARES
|
||||
if(async_rr_start(data))
|
||||
if(async_rr_start(data, port))
|
||||
infof(data, "Failed HTTPS RR operation");
|
||||
#endif
|
||||
CURL_TRC_DNS(data, "resolve thread started for of %s:%d", hostname, port);
|
||||
@@ -532,10 +494,12 @@ static void async_thrdd_shutdown(struct Curl_easy *data)
|
||||
done = addr_ctx->thrd_done;
|
||||
Curl_mutex_release(&addr_ctx->mutx);
|
||||
|
||||
DEBUGASSERT(addr_ctx->thread_hnd != curl_thread_t_null);
|
||||
if(!done && (addr_ctx->thread_hnd != curl_thread_t_null)) {
|
||||
CURL_TRC_DNS(data, "cancelling resolve thread");
|
||||
(void)Curl_thread_cancel(&addr_ctx->thread_hnd);
|
||||
/* Wait for the thread to terminate if it is already marked done. If it is
|
||||
not done yet we cannot do anything here. We had tried pthread_cancel but
|
||||
it caused hanging and resource leaks (#18532). */
|
||||
if(done && (addr_ctx->thread_hnd != curl_thread_t_null)) {
|
||||
Curl_thread_join(&addr_ctx->thread_hnd);
|
||||
CURL_TRC_DNS(data, "async_thrdd_shutdown, thread joined");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -553,9 +517,11 @@ static CURLcode asyn_thrdd_await(struct Curl_easy *data,
|
||||
if(!entry)
|
||||
async_thrdd_shutdown(data);
|
||||
|
||||
CURL_TRC_DNS(data, "resolve, wait for thread to finish");
|
||||
if(!Curl_thread_join(&addr_ctx->thread_hnd)) {
|
||||
DEBUGASSERT(0);
|
||||
if(addr_ctx->thread_hnd != curl_thread_t_null) {
|
||||
CURL_TRC_DNS(data, "resolve, wait for thread to finish");
|
||||
if(!Curl_thread_join(&addr_ctx->thread_hnd)) {
|
||||
DEBUGASSERT(0);
|
||||
}
|
||||
}
|
||||
|
||||
if(entry)
|
||||
@@ -650,6 +616,7 @@ CURLcode Curl_async_is_resolved(struct Curl_easy *data,
|
||||
|
||||
data->state.async.done = TRUE;
|
||||
Curl_resolv_unlink(data, &data->state.async.dns);
|
||||
Curl_expire_done(data, EXPIRE_ASYNC_NAME);
|
||||
|
||||
if(thrdd->addr->res) {
|
||||
data->state.async.dns =
|
||||
|
||||
@@ -25,8 +25,7 @@
|
||||
#include "curl_setup.h"
|
||||
#include "bufq.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
|
||||
@@ -225,7 +225,7 @@ typedef CURLcode Curl_bufq_reader(void *reader_ctx,
|
||||
size_t *pnread);
|
||||
|
||||
/**
|
||||
* Read date and append it to the end of the buffer queue until the
|
||||
* Read bytes and append them to the end of the buffer queue until the
|
||||
* reader returns blocking or the queue is full. A reader returns
|
||||
* CURLE_AGAIN to indicate blocking.
|
||||
* Returns the total amount of buf read (may be 0) in `pnread` on success.
|
||||
|
||||
@@ -46,8 +46,7 @@
|
||||
#include "multiif.h"
|
||||
#include "curlx/strparse.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
|
||||
@@ -44,8 +44,7 @@
|
||||
#include "select.h"
|
||||
#include "cf-h2-proxy.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
@@ -101,8 +100,8 @@ static CURLcode tunnel_stream_init(struct Curl_cfilter *cf,
|
||||
return result;
|
||||
|
||||
ts->authority = /* host:port with IPv6 support */
|
||||
aprintf("%s%s%s:%d", ipv6_ip ? "[":"", hostname,
|
||||
ipv6_ip ? "]" : "", port);
|
||||
curl_maprintf("%s%s%s:%d", ipv6_ip ? "[":"", hostname,
|
||||
ipv6_ip ? "]" : "", port);
|
||||
if(!ts->authority)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
@@ -433,6 +432,11 @@ static int proxy_h2_process_pending_input(struct Curl_cfilter *cf,
|
||||
*err = CURLE_RECV_ERROR;
|
||||
return -1;
|
||||
}
|
||||
else if(!rv) {
|
||||
/* nghttp2 does not want to process more, but has no error. This
|
||||
* probably cannot happen, but be safe. */
|
||||
break;
|
||||
}
|
||||
Curl_bufq_skip(&ctx->inbufq, (size_t)rv);
|
||||
if(Curl_bufq_is_empty(&ctx->inbufq)) {
|
||||
CURL_TRC_CF(data, cf, "[0] all data in connection buffer processed");
|
||||
@@ -551,47 +555,47 @@ static int proxy_h2_fr_print(const nghttp2_frame *frame,
|
||||
{
|
||||
switch(frame->hd.type) {
|
||||
case NGHTTP2_DATA: {
|
||||
return msnprintf(buffer, blen,
|
||||
"FRAME[DATA, len=%d, eos=%d, padlen=%d]",
|
||||
(int)frame->hd.length,
|
||||
!!(frame->hd.flags & NGHTTP2_FLAG_END_STREAM),
|
||||
(int)frame->data.padlen);
|
||||
return curl_msnprintf(buffer, blen,
|
||||
"FRAME[DATA, len=%d, eos=%d, padlen=%d]",
|
||||
(int)frame->hd.length,
|
||||
!!(frame->hd.flags & NGHTTP2_FLAG_END_STREAM),
|
||||
(int)frame->data.padlen);
|
||||
}
|
||||
case NGHTTP2_HEADERS: {
|
||||
return msnprintf(buffer, blen,
|
||||
"FRAME[HEADERS, len=%d, hend=%d, eos=%d]",
|
||||
(int)frame->hd.length,
|
||||
!!(frame->hd.flags & NGHTTP2_FLAG_END_HEADERS),
|
||||
!!(frame->hd.flags & NGHTTP2_FLAG_END_STREAM));
|
||||
return curl_msnprintf(buffer, blen,
|
||||
"FRAME[HEADERS, len=%d, hend=%d, eos=%d]",
|
||||
(int)frame->hd.length,
|
||||
!!(frame->hd.flags & NGHTTP2_FLAG_END_HEADERS),
|
||||
!!(frame->hd.flags & NGHTTP2_FLAG_END_STREAM));
|
||||
}
|
||||
case NGHTTP2_PRIORITY: {
|
||||
return msnprintf(buffer, blen,
|
||||
"FRAME[PRIORITY, len=%d, flags=%d]",
|
||||
(int)frame->hd.length, frame->hd.flags);
|
||||
return curl_msnprintf(buffer, blen,
|
||||
"FRAME[PRIORITY, len=%d, flags=%d]",
|
||||
(int)frame->hd.length, frame->hd.flags);
|
||||
}
|
||||
case NGHTTP2_RST_STREAM: {
|
||||
return msnprintf(buffer, blen,
|
||||
"FRAME[RST_STREAM, len=%d, flags=%d, error=%u]",
|
||||
(int)frame->hd.length, frame->hd.flags,
|
||||
frame->rst_stream.error_code);
|
||||
return curl_msnprintf(buffer, blen,
|
||||
"FRAME[RST_STREAM, len=%d, flags=%d, error=%u]",
|
||||
(int)frame->hd.length, frame->hd.flags,
|
||||
frame->rst_stream.error_code);
|
||||
}
|
||||
case NGHTTP2_SETTINGS: {
|
||||
if(frame->hd.flags & NGHTTP2_FLAG_ACK) {
|
||||
return msnprintf(buffer, blen, "FRAME[SETTINGS, ack=1]");
|
||||
return curl_msnprintf(buffer, blen, "FRAME[SETTINGS, ack=1]");
|
||||
}
|
||||
return msnprintf(buffer, blen,
|
||||
"FRAME[SETTINGS, len=%d]", (int)frame->hd.length);
|
||||
return curl_msnprintf(buffer, blen,
|
||||
"FRAME[SETTINGS, len=%d]", (int)frame->hd.length);
|
||||
}
|
||||
case NGHTTP2_PUSH_PROMISE:
|
||||
return msnprintf(buffer, blen,
|
||||
"FRAME[PUSH_PROMISE, len=%d, hend=%d]",
|
||||
(int)frame->hd.length,
|
||||
!!(frame->hd.flags & NGHTTP2_FLAG_END_HEADERS));
|
||||
return curl_msnprintf(buffer, blen,
|
||||
"FRAME[PUSH_PROMISE, len=%d, hend=%d]",
|
||||
(int)frame->hd.length,
|
||||
!!(frame->hd.flags & NGHTTP2_FLAG_END_HEADERS));
|
||||
case NGHTTP2_PING:
|
||||
return msnprintf(buffer, blen,
|
||||
"FRAME[PING, len=%d, ack=%d]",
|
||||
(int)frame->hd.length,
|
||||
frame->hd.flags & NGHTTP2_FLAG_ACK);
|
||||
return curl_msnprintf(buffer, blen,
|
||||
"FRAME[PING, len=%d, ack=%d]",
|
||||
(int)frame->hd.length,
|
||||
frame->hd.flags & NGHTTP2_FLAG_ACK);
|
||||
case NGHTTP2_GOAWAY: {
|
||||
char scratch[128];
|
||||
size_t s_len = CURL_ARRAYSIZE(scratch);
|
||||
@@ -600,19 +604,20 @@ static int proxy_h2_fr_print(const nghttp2_frame *frame,
|
||||
if(len)
|
||||
memcpy(scratch, frame->goaway.opaque_data, len);
|
||||
scratch[len] = '\0';
|
||||
return msnprintf(buffer, blen, "FRAME[GOAWAY, error=%d, reason='%s', "
|
||||
"last_stream=%d]", frame->goaway.error_code,
|
||||
scratch, frame->goaway.last_stream_id);
|
||||
return curl_msnprintf(buffer, blen,
|
||||
"FRAME[GOAWAY, error=%d, reason='%s', "
|
||||
"last_stream=%d]", frame->goaway.error_code,
|
||||
scratch, frame->goaway.last_stream_id);
|
||||
}
|
||||
case NGHTTP2_WINDOW_UPDATE: {
|
||||
return msnprintf(buffer, blen,
|
||||
"FRAME[WINDOW_UPDATE, incr=%d]",
|
||||
frame->window_update.window_size_increment);
|
||||
return curl_msnprintf(buffer, blen,
|
||||
"FRAME[WINDOW_UPDATE, incr=%d]",
|
||||
frame->window_update.window_size_increment);
|
||||
}
|
||||
default:
|
||||
return msnprintf(buffer, blen, "FRAME[%d, len=%d, flags=%d]",
|
||||
frame->hd.type, (int)frame->hd.length,
|
||||
frame->hd.flags);
|
||||
return curl_msnprintf(buffer, blen, "FRAME[%d, len=%d, flags=%d]",
|
||||
frame->hd.type, (int)frame->hd.length,
|
||||
frame->hd.flags);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,8 +34,7 @@
|
||||
#include "multiif.h"
|
||||
#include "select.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
|
||||
@@ -38,8 +38,7 @@
|
||||
#include "select.h"
|
||||
#include "vquic/vquic.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
|
||||
@@ -41,9 +41,6 @@
|
||||
#ifdef HAVE_NETDB_H
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
#ifdef HAVE_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
@@ -63,8 +60,7 @@
|
||||
#include "select.h"
|
||||
#include "vquic/vquic.h" /* for quic cfilters */
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
@@ -156,12 +152,17 @@ static const struct Curl_addrinfo *cf_ai_iter_next(struct cf_ai_iter *iter)
|
||||
return iter->last;
|
||||
}
|
||||
|
||||
#ifdef USE_IPV6
|
||||
static bool cf_ai_iter_done(struct cf_ai_iter *iter)
|
||||
static bool cf_ai_iter_has_more(struct cf_ai_iter *iter)
|
||||
{
|
||||
return (iter->n >= 0) && !iter->last;
|
||||
const struct Curl_addrinfo *addr = iter->last ? iter->last->ai_next :
|
||||
((iter->n < 0) ? iter->head : NULL);
|
||||
while(addr) {
|
||||
if(addr->ai_family == iter->ai_family)
|
||||
return TRUE;
|
||||
addr = addr->ai_next;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct cf_ip_attempt {
|
||||
struct cf_ip_attempt *next;
|
||||
@@ -356,7 +357,7 @@ static CURLcode cf_ip_ballers_run(struct cf_ip_ballers *bs,
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct cf_ip_attempt *a = NULL, **panchor;
|
||||
bool do_more, more_possible;
|
||||
bool do_more;
|
||||
struct curltime now;
|
||||
timediff_t next_expire_ms;
|
||||
int i, inconclusive, ongoing;
|
||||
@@ -367,7 +368,6 @@ static CURLcode cf_ip_ballers_run(struct cf_ip_ballers *bs,
|
||||
evaluate:
|
||||
now = curlx_now();
|
||||
ongoing = inconclusive = 0;
|
||||
more_possible = TRUE;
|
||||
|
||||
/* check if a running baller connects now */
|
||||
i = -1;
|
||||
@@ -407,8 +407,14 @@ evaluate:
|
||||
do_more = TRUE;
|
||||
}
|
||||
else {
|
||||
do_more = (curlx_timediff(now, bs->last_attempt_started) >=
|
||||
bs->attempt_delay_ms);
|
||||
bool more_possible = cf_ai_iter_has_more(&bs->addr_iter);
|
||||
#ifdef USE_IPV6
|
||||
if(!more_possible)
|
||||
more_possible = cf_ai_iter_has_more(&bs->ipv6_iter);
|
||||
#endif
|
||||
do_more = more_possible &&
|
||||
(curlx_timediff(now, bs->last_attempt_started) >=
|
||||
bs->attempt_delay_ms);
|
||||
if(do_more)
|
||||
CURL_TRC_CF(data, cf, "happy eyeballs timeout expired, "
|
||||
"start next attempt");
|
||||
@@ -421,7 +427,7 @@ evaluate:
|
||||
int ai_family = 0;
|
||||
#ifdef USE_IPV6
|
||||
if((bs->last_attempt_ai_family == AF_INET) ||
|
||||
cf_ai_iter_done(&bs->addr_iter)) {
|
||||
!cf_ai_iter_has_more(&bs->addr_iter)) {
|
||||
addr = cf_ai_iter_next(&bs->ipv6_iter);
|
||||
ai_family = bs->ipv6_iter.ai_family;
|
||||
}
|
||||
@@ -454,10 +460,10 @@ evaluate:
|
||||
else if(inconclusive) {
|
||||
/* tried all addresses, no success but some where inconclusive.
|
||||
* Let's restart the inconclusive ones. */
|
||||
if(curlx_timediff(now, bs->last_attempt_started) >=
|
||||
bs->attempt_delay_ms) {
|
||||
CURL_TRC_CF(data, cf, "tried all addresses with inconclusive results"
|
||||
", restarting one");
|
||||
timediff_t since_ms = curlx_timediff(now, bs->last_attempt_started);
|
||||
timediff_t delay_ms = bs->attempt_delay_ms - since_ms;
|
||||
if(delay_ms <= 0) {
|
||||
CURL_TRC_CF(data, cf, "all attempts inconclusive, restarting one");
|
||||
i = -1;
|
||||
for(a = bs->running; a; a = a->next) {
|
||||
++i;
|
||||
@@ -472,14 +478,17 @@ evaluate:
|
||||
}
|
||||
DEBUGASSERT(0); /* should not come here */
|
||||
}
|
||||
else {
|
||||
/* let's wait some more before restarting */
|
||||
infof(data, "connect attempts inconclusive, retrying "
|
||||
"in %" FMT_TIMEDIFF_T "ms", delay_ms);
|
||||
Curl_expire(data, delay_ms, EXPIRE_HAPPY_EYEBALLS);
|
||||
}
|
||||
/* attempt timeout for restart has not expired yet */
|
||||
goto out;
|
||||
}
|
||||
else if(ongoing) {
|
||||
else if(!ongoing) {
|
||||
/* no more addresses, no inconclusive attempts */
|
||||
more_possible = FALSE;
|
||||
}
|
||||
else {
|
||||
CURL_TRC_CF(data, cf, "no more attempts to try");
|
||||
result = CURLE_COULDNT_CONNECT;
|
||||
i = 0;
|
||||
@@ -493,21 +502,34 @@ evaluate:
|
||||
|
||||
out:
|
||||
if(!result) {
|
||||
bool more_possible;
|
||||
|
||||
/* when do we need to be called again? */
|
||||
next_expire_ms = Curl_timeleft(data, &now, TRUE);
|
||||
if(more_possible) {
|
||||
timediff_t expire_ms, elapsed_ms;
|
||||
elapsed_ms = curlx_timediff(now, bs->last_attempt_started);
|
||||
expire_ms = CURLMAX(bs->attempt_delay_ms - elapsed_ms, 0);
|
||||
next_expire_ms = CURLMIN(next_expire_ms, expire_ms);
|
||||
}
|
||||
|
||||
if(next_expire_ms <= 0) {
|
||||
failf(data, "Connection timeout after %" FMT_OFF_T " ms",
|
||||
curlx_timediff(now, data->progress.t_startsingle));
|
||||
return CURLE_OPERATION_TIMEDOUT;
|
||||
}
|
||||
Curl_expire(data, next_expire_ms, EXPIRE_HAPPY_EYEBALLS);
|
||||
|
||||
more_possible = cf_ai_iter_has_more(&bs->addr_iter);
|
||||
#ifdef USE_IPV6
|
||||
if(!more_possible)
|
||||
more_possible = cf_ai_iter_has_more(&bs->ipv6_iter);
|
||||
#endif
|
||||
if(more_possible) {
|
||||
timediff_t expire_ms, elapsed_ms;
|
||||
elapsed_ms = curlx_timediff(now, bs->last_attempt_started);
|
||||
expire_ms = CURLMAX(bs->attempt_delay_ms - elapsed_ms, 0);
|
||||
next_expire_ms = CURLMIN(next_expire_ms, expire_ms);
|
||||
if(next_expire_ms <= 0) {
|
||||
CURL_TRC_CF(data, cf, "HAPPY_EYBALLS timeout due, re-evaluate");
|
||||
goto evaluate;
|
||||
}
|
||||
CURL_TRC_CF(data, cf, "next HAPPY_EYBALLS timeout in %" FMT_TIMEDIFF_T
|
||||
"ms", next_expire_ms);
|
||||
Curl_expire(data, next_expire_ms, EXPIRE_HAPPY_EYEBALLS);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -627,26 +649,36 @@ static CURLcode is_connected(struct Curl_cfilter *cf,
|
||||
|
||||
{
|
||||
const char *hostname, *proxy_name = NULL;
|
||||
int port;
|
||||
char viamsg[160];
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
if(conn->bits.socksproxy)
|
||||
proxy_name = conn->socks_proxy.host.name;
|
||||
else if(conn->bits.httpproxy)
|
||||
proxy_name = conn->http_proxy.host.name;
|
||||
#endif
|
||||
hostname = conn->bits.conn_to_host ?
|
||||
conn->conn_to_host.name : conn->host.name;
|
||||
hostname = conn->bits.conn_to_host ? conn->conn_to_host.name :
|
||||
conn->host.name;
|
||||
|
||||
if(cf->sockindex == SECONDARYSOCKET)
|
||||
port = conn->secondary_port;
|
||||
else if(cf->conn->bits.conn_to_port)
|
||||
port = conn->conn_to_port;
|
||||
#ifdef USE_UNIX_SOCKETS
|
||||
if(conn->unix_domain_socket)
|
||||
curl_msnprintf(viamsg, sizeof(viamsg), "over %s",
|
||||
conn->unix_domain_socket);
|
||||
else
|
||||
port = conn->remote_port;
|
||||
#endif
|
||||
{
|
||||
int port;
|
||||
if(cf->sockindex == SECONDARYSOCKET)
|
||||
port = conn->secondary_port;
|
||||
else if(cf->conn->bits.conn_to_port)
|
||||
port = conn->conn_to_port;
|
||||
else
|
||||
port = conn->remote_port;
|
||||
curl_msnprintf(viamsg, sizeof(viamsg), "port %u", port);
|
||||
}
|
||||
|
||||
failf(data, "Failed to connect to %s port %u %s%s%safter "
|
||||
failf(data, "Failed to connect to %s %s %s%s%safter "
|
||||
"%" FMT_TIMEDIFF_T " ms: %s",
|
||||
hostname, port,
|
||||
hostname, viamsg,
|
||||
proxy_name ? "via " : "",
|
||||
proxy_name ? proxy_name : "",
|
||||
proxy_name ? " " : "",
|
||||
|
||||
@@ -44,9 +44,6 @@
|
||||
#ifdef HAVE_NETDB_H
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
#ifdef HAVE_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
@@ -65,7 +62,6 @@
|
||||
#include "bufq.h"
|
||||
#include "sendf.h"
|
||||
#include "if2ip.h"
|
||||
#include "strerror.h"
|
||||
#include "cfilters.h"
|
||||
#include "cf-socket.h"
|
||||
#include "connect.h"
|
||||
@@ -83,10 +79,10 @@
|
||||
#include "strdup.h"
|
||||
#include "system_win32.h"
|
||||
#include "curlx/version_win32.h"
|
||||
#include "curlx/strerr.h"
|
||||
#include "curlx/strparse.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
@@ -117,7 +113,7 @@ static void tcpnodelay(struct Curl_easy *data, curl_socket_t sockfd)
|
||||
if(setsockopt(sockfd, level, TCP_NODELAY,
|
||||
(void *)&onoff, sizeof(onoff)) < 0)
|
||||
infof(data, "Could not set TCP_NODELAY: %s",
|
||||
Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
|
||||
curlx_strerror(SOCKERRNO, buffer, sizeof(buffer)));
|
||||
#else
|
||||
(void)data;
|
||||
(void)sockfd;
|
||||
@@ -139,7 +135,7 @@ static void nosigpipe(struct Curl_easy *data,
|
||||
#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
||||
char buffer[STRERROR_LEN];
|
||||
infof(data, "Could not set SO_NOSIGPIPE: %s",
|
||||
Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
|
||||
curlx_strerror(SOCKERRNO, buffer, sizeof(buffer)));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -336,12 +332,11 @@ static CURLcode sock_assign_addr(struct Curl_sockaddr_ex *dest,
|
||||
}
|
||||
dest->addrlen = (unsigned int)ai->ai_addrlen;
|
||||
|
||||
if(dest->addrlen > sizeof(struct Curl_sockaddr_storage)) {
|
||||
DEBUGASSERT(0);
|
||||
DEBUGASSERT(dest->addrlen <= sizeof(dest->curl_sa_addrbuf));
|
||||
if(dest->addrlen > sizeof(dest->curl_sa_addrbuf))
|
||||
return CURLE_TOO_LARGE;
|
||||
}
|
||||
|
||||
memcpy(&dest->curl_sa_addr, ai->ai_addr, dest->addrlen);
|
||||
memcpy(&dest->curl_sa_addrbuf, ai->ai_addr, dest->addrlen);
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
@@ -349,6 +344,8 @@ static CURLcode socket_open(struct Curl_easy *data,
|
||||
struct Curl_sockaddr_ex *addr,
|
||||
curl_socket_t *sockfd)
|
||||
{
|
||||
char errbuf[STRERROR_LEN];
|
||||
|
||||
DEBUGASSERT(data);
|
||||
DEBUGASSERT(data->conn);
|
||||
if(data->set.fopensocket) {
|
||||
@@ -369,12 +366,25 @@ static CURLcode socket_open(struct Curl_easy *data,
|
||||
}
|
||||
else {
|
||||
/* opensocket callback not set, so simply create the socket now */
|
||||
*sockfd = socket(addr->family, addr->socktype, addr->protocol);
|
||||
*sockfd = CURL_SOCKET(addr->family, addr->socktype, addr->protocol);
|
||||
}
|
||||
|
||||
if(*sockfd == CURL_SOCKET_BAD)
|
||||
if(*sockfd == CURL_SOCKET_BAD) {
|
||||
/* no socket, no connection */
|
||||
failf(data, "failed to open socket: %s",
|
||||
curlx_strerror(SOCKERRNO, errbuf, sizeof(errbuf)));
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
#ifdef HAVE_FCNTL
|
||||
if(fcntl(*sockfd, F_SETFD, FD_CLOEXEC) < 0) {
|
||||
failf(data, "fcntl set CLOEXEC: %s",
|
||||
curlx_strerror(SOCKERRNO, errbuf, sizeof(errbuf)));
|
||||
close(*sockfd);
|
||||
*sockfd = CURL_SOCKET_BAD;
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(USE_IPV6) && defined(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID)
|
||||
if(data->conn->scope_id && (addr->family == AF_INET6)) {
|
||||
@@ -453,7 +463,7 @@ int Curl_socket_close(struct Curl_easy *data, struct connectdata *conn,
|
||||
/* When you run a program that uses the Windows Sockets API, you may
|
||||
experience slow performance when you copy data to a TCP server.
|
||||
|
||||
https://support.microsoft.com/kb/823764
|
||||
https://learn.microsoft.com/troubleshoot/windows-server/networking/slow-performance-copy-data-tcp-server-sockets-api
|
||||
|
||||
Work-around: Make the Socket Send Buffer Size Larger Than the Program Send
|
||||
Buffer Size
|
||||
@@ -648,7 +658,7 @@ static CURLcode bindlocal(struct Curl_easy *data, struct connectdata *conn,
|
||||
char buffer[STRERROR_LEN];
|
||||
data->state.os_errno = error = SOCKERRNO;
|
||||
failf(data, "Couldn't bind to interface '%s' with errno %d: %s",
|
||||
iface, error, Curl_strerror(error, buffer, sizeof(buffer)));
|
||||
iface, error, curlx_strerror(error, buffer, sizeof(buffer)));
|
||||
return CURLE_INTERFACE_FAILED;
|
||||
}
|
||||
break;
|
||||
@@ -751,8 +761,8 @@ static CURLcode bindlocal(struct Curl_easy *data, struct connectdata *conn,
|
||||
char buffer[STRERROR_LEN];
|
||||
data->state.errorbuf = FALSE;
|
||||
data->state.os_errno = error = SOCKERRNO;
|
||||
failf(data, "Couldn't bind to '%s' with errno %d: %s",
|
||||
host, error, Curl_strerror(error, buffer, sizeof(buffer)));
|
||||
failf(data, "Couldn't bind to '%s' with errno %d: %s", host,
|
||||
error, curlx_strerror(error, buffer, sizeof(buffer)));
|
||||
return CURLE_INTERFACE_FAILED;
|
||||
}
|
||||
}
|
||||
@@ -790,10 +800,10 @@ static CURLcode bindlocal(struct Curl_easy *data, struct connectdata *conn,
|
||||
infof(data, "Bind to local port %d failed, trying next", port - 1);
|
||||
/* We reuse/clobber the port variable here below */
|
||||
if(sock->sa_family == AF_INET)
|
||||
si4->sin_port = ntohs(port);
|
||||
si4->sin_port = htons(port);
|
||||
#ifdef USE_IPV6
|
||||
else
|
||||
si6->sin6_port = ntohs(port);
|
||||
si6->sin6_port = htons(port);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
@@ -803,7 +813,7 @@ static CURLcode bindlocal(struct Curl_easy *data, struct connectdata *conn,
|
||||
char buffer[STRERROR_LEN];
|
||||
data->state.os_errno = error = SOCKERRNO;
|
||||
failf(data, "bind failed with errno %d: %s",
|
||||
error, Curl_strerror(error, buffer, sizeof(buffer)));
|
||||
error, curlx_strerror(error, buffer, sizeof(buffer)));
|
||||
}
|
||||
|
||||
return CURLE_INTERFACE_FAILED;
|
||||
@@ -825,8 +835,8 @@ static bool verifyconnect(curl_socket_t sockfd, int *error)
|
||||
* 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
|
||||
* In May 2004, we brought it back to offer more info back on connect
|
||||
* failures. We could reproduce the former problems with this function, but
|
||||
* could avoid them by adding this SleepEx() call below:
|
||||
*
|
||||
* "I do not have Rational Quantify, but the hint from his post was
|
||||
@@ -904,8 +914,8 @@ static CURLcode socket_connect_result(struct Curl_easy *data,
|
||||
#else
|
||||
{
|
||||
char buffer[STRERROR_LEN];
|
||||
infof(data, "Immediate connect fail for %s: %s",
|
||||
ipaddress, Curl_strerror(error, buffer, sizeof(buffer)));
|
||||
infof(data, "Immediate connect fail for %s: %s", ipaddress,
|
||||
curlx_strerror(error, buffer, sizeof(buffer)));
|
||||
}
|
||||
#endif
|
||||
data->state.os_errno = error;
|
||||
@@ -1036,10 +1046,12 @@ static void cf_socket_destroy(struct Curl_cfilter *cf, struct Curl_easy *data)
|
||||
cf->ctx = NULL;
|
||||
}
|
||||
|
||||
static CURLcode set_local_ip(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data)
|
||||
static void set_local_ip(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data)
|
||||
{
|
||||
struct cf_socket_ctx *ctx = cf->ctx;
|
||||
ctx->ip.local_ip[0] = 0;
|
||||
ctx->ip.local_port = -1;
|
||||
|
||||
#ifdef HAVE_GETSOCKNAME
|
||||
if((ctx->sock != CURL_SOCKET_BAD) &&
|
||||
@@ -1053,23 +1065,18 @@ static CURLcode set_local_ip(struct Curl_cfilter *cf,
|
||||
memset(&ssloc, 0, sizeof(ssloc));
|
||||
if(getsockname(ctx->sock, (struct sockaddr*) &ssloc, &slen)) {
|
||||
int error = SOCKERRNO;
|
||||
failf(data, "getsockname() failed with errno %d: %s",
|
||||
error, Curl_strerror(error, buffer, sizeof(buffer)));
|
||||
return CURLE_FAILED_INIT;
|
||||
infof(data, "getsockname() failed with errno %d: %s",
|
||||
error, curlx_strerror(error, buffer, sizeof(buffer)));
|
||||
}
|
||||
if(!Curl_addr2string((struct sockaddr*)&ssloc, slen,
|
||||
ctx->ip.local_ip, &ctx->ip.local_port)) {
|
||||
failf(data, "ssloc inet_ntop() failed with errno %d: %s",
|
||||
errno, Curl_strerror(errno, buffer, sizeof(buffer)));
|
||||
return CURLE_FAILED_INIT;
|
||||
else if(!Curl_addr2string((struct sockaddr*)&ssloc, slen,
|
||||
ctx->ip.local_ip, &ctx->ip.local_port)) {
|
||||
infof(data, "ssloc inet_ntop() failed with errno %d: %s",
|
||||
errno, curlx_strerror(errno, buffer, sizeof(buffer)));
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)data;
|
||||
ctx->ip.local_ip[0] = 0;
|
||||
ctx->ip.local_port = -1;
|
||||
#endif
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode set_remote_ip(struct Curl_cfilter *cf,
|
||||
@@ -1086,7 +1093,7 @@ static CURLcode set_remote_ip(struct Curl_cfilter *cf,
|
||||
ctx->error = errno;
|
||||
/* malformed address or bug in inet_ntop, try next address */
|
||||
failf(data, "curl_sa_addr inet_ntop() failed with errno %d: %s",
|
||||
errno, Curl_strerror(errno, buffer, sizeof(buffer)));
|
||||
errno, curlx_strerror(errno, buffer, sizeof(buffer)));
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
return CURLE_OK;
|
||||
@@ -1332,7 +1339,8 @@ static CURLcode cf_tcp_connect(struct Curl_cfilter *cf,
|
||||
rc = SOCKET_WRITABLE(ctx->sock, 0);
|
||||
|
||||
if(rc == 0) { /* no connection yet */
|
||||
CURL_TRC_CF(data, cf, "not connected yet");
|
||||
CURL_TRC_CF(data, cf, "not connected yet on fd=%" FMT_SOCKET_T,
|
||||
ctx->sock);
|
||||
return CURLE_OK;
|
||||
}
|
||||
else if(rc == CURL_CSELECT_OUT || cf->conn->bits.tcp_fastopen) {
|
||||
@@ -1342,7 +1350,7 @@ static CURLcode cf_tcp_connect(struct Curl_cfilter *cf,
|
||||
set_local_ip(cf, data);
|
||||
*done = TRUE;
|
||||
cf->connected = TRUE;
|
||||
CURL_TRC_CF(data, cf, "connected");
|
||||
CURL_TRC_CF(data, cf, "connected on fd=%" FMT_SOCKET_T, ctx->sock);
|
||||
return CURLE_OK;
|
||||
}
|
||||
}
|
||||
@@ -1363,7 +1371,7 @@ out:
|
||||
infof(data, "connect to %s port %u from %s port %d failed: %s",
|
||||
ctx->ip.remote_ip, ctx->ip.remote_port,
|
||||
ctx->ip.local_ip, ctx->ip.local_port,
|
||||
Curl_strerror(ctx->error, buffer, sizeof(buffer)));
|
||||
curlx_strerror(ctx->error, buffer, sizeof(buffer)));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -1501,7 +1509,7 @@ static CURLcode cf_socket_send(struct Curl_cfilter *cf, struct Curl_easy *data,
|
||||
else {
|
||||
char buffer[STRERROR_LEN];
|
||||
failf(data, "Send failure: %s",
|
||||
Curl_strerror(sockerr, buffer, sizeof(buffer)));
|
||||
curlx_strerror(sockerr, buffer, sizeof(buffer)));
|
||||
data->state.os_errno = sockerr;
|
||||
result = CURLE_SEND_ERROR;
|
||||
}
|
||||
@@ -1569,7 +1577,7 @@ static CURLcode cf_socket_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
|
||||
else {
|
||||
char buffer[STRERROR_LEN];
|
||||
failf(data, "Recv failure: %s",
|
||||
Curl_strerror(sockerr, buffer, sizeof(buffer)));
|
||||
curlx_strerror(sockerr, buffer, sizeof(buffer)));
|
||||
data->state.os_errno = sockerr;
|
||||
result = CURLE_RECV_ERROR;
|
||||
}
|
||||
@@ -1764,6 +1772,11 @@ CURLcode Curl_cf_tcp_create(struct Curl_cfilter **pcf,
|
||||
(void)data;
|
||||
(void)conn;
|
||||
DEBUGASSERT(transport == TRNSPRT_TCP);
|
||||
if(!ai) {
|
||||
result = CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ctx = calloc(1, sizeof(*ctx));
|
||||
if(!ctx) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
@@ -1860,6 +1873,7 @@ static CURLcode cf_udp_connect(struct Curl_cfilter *cf,
|
||||
*done = TRUE;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
*done = FALSE;
|
||||
if(ctx->sock == CURL_SOCKET_BAD) {
|
||||
result = cf_socket_open(cf, data);
|
||||
@@ -1876,10 +1890,6 @@ static CURLcode cf_udp_connect(struct Curl_cfilter *cf,
|
||||
FMT_SOCKET_T " (%s:%d)",
|
||||
ctx->sock, ctx->ip.local_ip, ctx->ip.local_port);
|
||||
}
|
||||
else {
|
||||
CURL_TRC_CF(data, cf, "cf_udp_connect(), opened socket=%"
|
||||
FMT_SOCKET_T " (unconnected)", ctx->sock);
|
||||
}
|
||||
*done = TRUE;
|
||||
cf->connected = TRUE;
|
||||
}
|
||||
@@ -2040,13 +2050,13 @@ static void cf_tcp_set_accepted_remote_ip(struct Curl_cfilter *cf,
|
||||
if(getpeername(ctx->sock, (struct sockaddr*) &ssrem, &plen)) {
|
||||
int error = SOCKERRNO;
|
||||
failf(data, "getpeername() failed with errno %d: %s",
|
||||
error, Curl_strerror(error, buffer, sizeof(buffer)));
|
||||
error, curlx_strerror(error, buffer, sizeof(buffer)));
|
||||
return;
|
||||
}
|
||||
if(!Curl_addr2string((struct sockaddr*)&ssrem, plen,
|
||||
ctx->ip.remote_ip, &ctx->ip.remote_port)) {
|
||||
failf(data, "ssrem inet_ntop() failed with errno %d: %s",
|
||||
errno, Curl_strerror(errno, buffer, sizeof(buffer)));
|
||||
errno, curlx_strerror(errno, buffer, sizeof(buffer)));
|
||||
return;
|
||||
}
|
||||
#else
|
||||
@@ -2061,6 +2071,7 @@ static CURLcode cf_tcp_accept_connect(struct Curl_cfilter *cf,
|
||||
bool *done)
|
||||
{
|
||||
struct cf_socket_ctx *ctx = cf->ctx;
|
||||
char errbuf[STRERROR_LEN];
|
||||
#ifdef USE_IPV6
|
||||
struct Curl_sockaddr_storage add;
|
||||
#else
|
||||
@@ -2079,6 +2090,7 @@ static CURLcode cf_tcp_accept_connect(struct Curl_cfilter *cf,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
*done = FALSE;
|
||||
timeout_ms = cf_tcp_accept_timeleft(cf, data);
|
||||
if(timeout_ms < 0) {
|
||||
/* if a timeout was already reached, bail out */
|
||||
@@ -2106,29 +2118,33 @@ static CURLcode cf_tcp_accept_connect(struct Curl_cfilter *cf,
|
||||
|
||||
if(!incoming) {
|
||||
CURL_TRC_CF(data, cf, "nothing heard from the server yet");
|
||||
*done = FALSE;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
if(!getsockname(ctx->sock, (struct sockaddr *) &add, &size)) {
|
||||
size = sizeof(add);
|
||||
size = sizeof(add);
|
||||
#ifdef HAVE_ACCEPT4
|
||||
s_accepted = accept4(ctx->sock, (struct sockaddr *) &add, &size,
|
||||
SOCK_NONBLOCK | SOCK_CLOEXEC);
|
||||
s_accepted = CURL_ACCEPT4(ctx->sock, (struct sockaddr *) &add, &size,
|
||||
SOCK_NONBLOCK | SOCK_CLOEXEC);
|
||||
#else
|
||||
s_accepted = CURL_ACCEPT(ctx->sock, (struct sockaddr *) &add, &size);
|
||||
s_accepted = CURL_ACCEPT(ctx->sock, (struct sockaddr *) &add, &size);
|
||||
#endif
|
||||
}
|
||||
|
||||
if(CURL_SOCKET_BAD == s_accepted) {
|
||||
failf(data, "Error accept()ing server connect");
|
||||
return CURLE_FTP_PORT_FAILED;
|
||||
failf(data, "Error accept()ing server connect: %s",
|
||||
curlx_strerror(SOCKERRNO, errbuf, sizeof(errbuf)));
|
||||
return CURLE_FTP_ACCEPT_FAILED;
|
||||
}
|
||||
#if !defined(HAVE_ACCEPT4) && defined(HAVE_FCNTL)
|
||||
if((fcntl(s_accepted, F_SETFD, FD_CLOEXEC) < 0) ||
|
||||
(curlx_nonblock(s_accepted, TRUE) < 0)) {
|
||||
failf(data, "fcntl set CLOEXEC/NONBLOCK: %s",
|
||||
curlx_strerror(SOCKERRNO, errbuf, sizeof(errbuf)));
|
||||
Curl_socket_close(data, cf->conn, s_accepted);
|
||||
return CURLE_FTP_ACCEPT_FAILED;
|
||||
}
|
||||
|
||||
infof(data, "Connection accepted from server");
|
||||
#ifndef HAVE_ACCEPT4
|
||||
(void)curlx_nonblock(s_accepted, TRUE); /* enable non-blocking */
|
||||
#endif
|
||||
infof(data, "Connection accepted from server");
|
||||
|
||||
/* Replace any filter on SECONDARY with one listening on this socket */
|
||||
ctx->listening = FALSE;
|
||||
ctx->accepted = TRUE;
|
||||
|
||||
@@ -48,11 +48,12 @@ struct Curl_sockaddr_ex {
|
||||
int protocol;
|
||||
unsigned int addrlen;
|
||||
union {
|
||||
struct sockaddr addr;
|
||||
struct Curl_sockaddr_storage buff;
|
||||
} _sa_ex_u;
|
||||
struct sockaddr sa;
|
||||
struct Curl_sockaddr_storage buf;
|
||||
} addr;
|
||||
};
|
||||
#define curl_sa_addr _sa_ex_u.addr
|
||||
#define curl_sa_addr addr.sa
|
||||
#define curl_sa_addrbuf addr.buf
|
||||
|
||||
/*
|
||||
* Parse interface option, and return the interface name and the host part.
|
||||
@@ -80,7 +81,7 @@ int Curl_socket_close(struct Curl_easy *data, struct connectdata *conn,
|
||||
/* When you run a program that uses the Windows Sockets API, you may
|
||||
experience slow performance when you copy data to a TCP server.
|
||||
|
||||
https://support.microsoft.com/kb/823764
|
||||
https://learn.microsoft.com/troubleshoot/windows-server/networking/slow-performance-copy-data-tcp-server-sockets-api
|
||||
|
||||
Work-around: Make the Socket Send Buffer Size Larger Than the Program Send
|
||||
Buffer Size
|
||||
@@ -157,7 +158,7 @@ CURLcode Curl_cf_socket_peek(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
curl_socket_t *psock,
|
||||
const struct Curl_sockaddr_ex **paddr,
|
||||
struct ip_quadruple *pip);
|
||||
struct ip_quadruple *pip) WARN_UNUSED_RESULT;
|
||||
|
||||
extern struct Curl_cftype Curl_cft_tcp;
|
||||
extern struct Curl_cftype Curl_cft_udp;
|
||||
|
||||
@@ -37,8 +37,7 @@
|
||||
#include "curlx/warnless.h"
|
||||
#include "curlx/strparse.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
@@ -383,29 +382,26 @@ void Curl_conn_cf_insert_after(struct Curl_cfilter *cf_at,
|
||||
*pnext = tail;
|
||||
}
|
||||
|
||||
bool Curl_conn_cf_discard_sub(struct Curl_cfilter *cf,
|
||||
struct Curl_cfilter *discard,
|
||||
struct Curl_easy *data,
|
||||
bool destroy_always)
|
||||
bool Curl_conn_cf_discard(struct Curl_cfilter **pcf,
|
||||
struct Curl_easy *data)
|
||||
{
|
||||
struct Curl_cfilter **pprev = &cf->next;
|
||||
struct Curl_cfilter *cf = pcf ? *pcf : NULL;
|
||||
bool found = FALSE;
|
||||
|
||||
/* remove from sub-chain and destroy */
|
||||
DEBUGASSERT(cf);
|
||||
while(*pprev) {
|
||||
if(*pprev == cf) {
|
||||
*pprev = discard->next;
|
||||
discard->next = NULL;
|
||||
found = TRUE;
|
||||
break;
|
||||
if(cf) {
|
||||
if(cf->conn) {
|
||||
/* unlink if present in connection filter chain */
|
||||
struct Curl_cfilter **pprev = &cf->conn->cfilter[cf->sockindex];
|
||||
while(*pprev) {
|
||||
if(*pprev == *pcf) {
|
||||
*pprev = (*pcf)->next;
|
||||
cf->next = NULL;
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
pprev = &((*pprev)->next);
|
||||
}
|
||||
}
|
||||
pprev = &((*pprev)->next);
|
||||
}
|
||||
if(found || destroy_always) {
|
||||
discard->next = NULL;
|
||||
discard->cft->destroy(discard, data);
|
||||
free(discard);
|
||||
Curl_conn_cf_discard_chain(pcf, data);
|
||||
}
|
||||
return found;
|
||||
}
|
||||
@@ -546,8 +542,9 @@ CURLcode Curl_conn_connect(struct Curl_easy *data,
|
||||
Curl_pollfds_reset(&cpfds);
|
||||
/* In general, we want to send after connect, wait on that. */
|
||||
if(sockfd != CURL_SOCKET_BAD)
|
||||
Curl_pollset_set_out_only(data, &ps, sockfd);
|
||||
result = Curl_conn_adjust_pollset(data, data->conn, &ps);
|
||||
result = Curl_pollset_set_out_only(data, &ps, sockfd);
|
||||
if(!result)
|
||||
result = Curl_conn_adjust_pollset(data, data->conn, &ps);
|
||||
if(result)
|
||||
goto out;
|
||||
result = Curl_pollfds_add_ps(&cpfds, &ps);
|
||||
@@ -936,13 +933,14 @@ Curl_conn_get_remote_addr(struct Curl_easy *data, int sockindex)
|
||||
|
||||
void Curl_conn_forget_socket(struct Curl_easy *data, int sockindex)
|
||||
{
|
||||
if(data->conn && CONN_SOCK_IDX_VALID(sockindex)) {
|
||||
struct Curl_cfilter *cf = data->conn->cfilter[sockindex];
|
||||
struct connectdata *conn = data->conn;
|
||||
if(conn && CONN_SOCK_IDX_VALID(sockindex)) {
|
||||
struct Curl_cfilter *cf = conn->cfilter[sockindex];
|
||||
if(cf)
|
||||
(void)Curl_conn_cf_cntrl(cf, data, TRUE,
|
||||
CF_CTRL_FORGET_SOCKET, 0, NULL);
|
||||
fake_sclose(data->conn->sock[sockindex]);
|
||||
data->conn->sock[sockindex] = CURL_SOCKET_BAD;
|
||||
fake_sclose(conn->sock[sockindex]);
|
||||
conn->sock[sockindex] = CURL_SOCKET_BAD;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -969,13 +967,6 @@ CURLcode Curl_conn_ev_data_setup(struct Curl_easy *data)
|
||||
CF_CTRL_DATA_SETUP, 0, NULL);
|
||||
}
|
||||
|
||||
CURLcode Curl_conn_ev_data_idle(struct Curl_easy *data)
|
||||
{
|
||||
return cf_cntrl_all(data->conn, data, FALSE,
|
||||
CF_CTRL_DATA_IDLE, 0, NULL);
|
||||
}
|
||||
|
||||
|
||||
CURLcode Curl_conn_flush(struct Curl_easy *data, int sockindex)
|
||||
{
|
||||
if(!CONN_SOCK_IDX_VALID(sockindex))
|
||||
|
||||
@@ -118,7 +118,7 @@ typedef CURLcode Curl_cft_conn_keep_alive(struct Curl_cfilter *cf,
|
||||
*/
|
||||
/* data event arg1 arg2 return */
|
||||
#define CF_CTRL_DATA_SETUP 4 /* 0 NULL first fail */
|
||||
#define CF_CTRL_DATA_IDLE 5 /* 0 NULL first fail */
|
||||
/* unused now 5 */
|
||||
#define CF_CTRL_DATA_PAUSE 6 /* on/off NULL first fail */
|
||||
#define CF_CTRL_DATA_DONE 7 /* premature NULL ignored */
|
||||
#define CF_CTRL_DATA_DONE_SEND 8 /* 0 NULL ignored */
|
||||
@@ -297,16 +297,12 @@ void Curl_conn_cf_insert_after(struct Curl_cfilter *cf_at,
|
||||
struct Curl_cfilter *cf_new);
|
||||
|
||||
/**
|
||||
* Discard, e.g. remove and destroy `discard` iff
|
||||
* it still is in the filter chain below `cf`. If `discard`
|
||||
* is no longer found beneath `cf` return FALSE.
|
||||
* if `destroy_always` is TRUE, will call `discard`s destroy
|
||||
* function and free it even if not found in the subchain.
|
||||
* Extract filter `*pcf` from its connection filter chain.
|
||||
* Destroy `*pcf`, even if it was not part of the chain and NULL it.
|
||||
* Returns TRUE of cf has been part of chain.
|
||||
*/
|
||||
bool Curl_conn_cf_discard_sub(struct Curl_cfilter *cf,
|
||||
struct Curl_cfilter *discard,
|
||||
struct Curl_easy *data,
|
||||
bool destroy_always);
|
||||
bool Curl_conn_cf_discard(struct Curl_cfilter **pcf,
|
||||
struct Curl_easy *data);
|
||||
|
||||
/**
|
||||
* Discard all cfilters starting with `*pcf` and clearing it afterwards.
|
||||
@@ -517,7 +513,7 @@ CURLcode Curl_cf_send(struct Curl_easy *data, int sockindex,
|
||||
|
||||
/**
|
||||
* Receive bytes from connection filter `cf` into `bufq`.
|
||||
* Convenience wrappter around `Curl_bufq_sipn()`,
|
||||
* Convenience wrapper around `Curl_bufq_sipn()`,
|
||||
* so users do not have to implement a callback.
|
||||
*/
|
||||
CURLcode Curl_cf_recv_bufq(struct Curl_cfilter *cf,
|
||||
@@ -543,12 +539,6 @@ CURLcode Curl_cf_send_bufq(struct Curl_cfilter *cf,
|
||||
*/
|
||||
CURLcode Curl_conn_ev_data_setup(struct Curl_easy *data);
|
||||
|
||||
/**
|
||||
* Notify connection filters that now would be a good time to
|
||||
* perform any idle, e.g. time related, actions.
|
||||
*/
|
||||
CURLcode Curl_conn_ev_data_idle(struct Curl_easy *data);
|
||||
|
||||
/**
|
||||
* Notify connection filters that the transfer represented by `data`
|
||||
* is done with sending data (e.g. has uploaded everything).
|
||||
|
||||
@@ -45,8 +45,7 @@
|
||||
#include "curlx/strparse.h"
|
||||
#include "uint-table.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
@@ -79,7 +78,7 @@
|
||||
struct cpool_bundle {
|
||||
struct Curl_llist conns; /* connections in the bundle */
|
||||
size_t dest_len; /* total length of destination, including NUL */
|
||||
char *dest[1]; /* destination of bundle, allocated to keep dest_len bytes */
|
||||
char dest[1]; /* destination of bundle, allocated to keep dest_len bytes */
|
||||
};
|
||||
|
||||
|
||||
@@ -91,13 +90,13 @@ static void cpool_discard_conn(struct cpool *cpool,
|
||||
static struct cpool_bundle *cpool_bundle_create(const char *dest)
|
||||
{
|
||||
struct cpool_bundle *bundle;
|
||||
size_t dest_len = strlen(dest);
|
||||
size_t dest_len = strlen(dest) + 1;
|
||||
|
||||
bundle = calloc(1, sizeof(*bundle) + dest_len);
|
||||
bundle = calloc(1, sizeof(*bundle) + dest_len - 1);
|
||||
if(!bundle)
|
||||
return NULL;
|
||||
Curl_llist_init(&bundle->conns, NULL);
|
||||
bundle->dest_len = dest_len + 1;
|
||||
bundle->dest_len = dest_len;
|
||||
memcpy(bundle->dest, dest, bundle->dest_len);
|
||||
return bundle;
|
||||
}
|
||||
@@ -320,7 +319,7 @@ static struct connectdata *cpool_get_oldest_idle(struct cpool *cpool)
|
||||
struct connectdata *oldest_idle = NULL;
|
||||
struct cpool_bundle *bundle;
|
||||
struct curltime now;
|
||||
timediff_t highscore =- 1;
|
||||
timediff_t highscore = -1;
|
||||
timediff_t score;
|
||||
|
||||
now = curlx_now();
|
||||
@@ -532,12 +531,19 @@ static bool cpool_foreach(struct Curl_easy *data,
|
||||
bool Curl_cpool_conn_now_idle(struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
unsigned int maxconnects = !data->multi->maxconnects ?
|
||||
(Curl_multi_xfers_running(data->multi) * 4) : data->multi->maxconnects;
|
||||
unsigned int maxconnects;
|
||||
struct connectdata *oldest_idle = NULL;
|
||||
struct cpool *cpool = cpool_get_instance(data);
|
||||
bool kept = TRUE;
|
||||
|
||||
if(!data->multi->maxconnects) {
|
||||
unsigned int running = Curl_multi_xfers_running(data->multi);
|
||||
maxconnects = (running <= UINT_MAX / 4) ? running * 4 : UINT_MAX;
|
||||
}
|
||||
else {
|
||||
maxconnects = data->multi->maxconnects;
|
||||
}
|
||||
|
||||
conn->lastused = curlx_now(); /* it was used up until now */
|
||||
if(cpool && maxconnects) {
|
||||
/* may be called form a callback already under lock */
|
||||
@@ -895,7 +901,7 @@ void Curl_cpool_print(struct cpool *cpool)
|
||||
if(!cpool)
|
||||
return;
|
||||
|
||||
fprintf(stderr, "=Bundle cache=\n");
|
||||
curl_mfprintf(stderr, "=Bundle cache=\n");
|
||||
|
||||
Curl_hash_start_iterate(cpool->dest2bundle, &iter);
|
||||
|
||||
@@ -906,15 +912,15 @@ void Curl_cpool_print(struct cpool *cpool)
|
||||
|
||||
bundle = he->ptr;
|
||||
|
||||
fprintf(stderr, "%s -", he->key);
|
||||
curl_mfprintf(stderr, "%s -", he->key);
|
||||
curr = Curl_llist_head(bundle->conns);
|
||||
while(curr) {
|
||||
conn = Curl_node_elem(curr);
|
||||
|
||||
fprintf(stderr, " [%p %d]", (void *)conn, conn->refcount);
|
||||
curl_mfprintf(stderr, " [%p %d]", (void *)conn, conn->refcount);
|
||||
curr = Curl_node_next(curr);
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
curl_mfprintf(stderr, "\n");
|
||||
|
||||
he = Curl_hash_next_element(&iter);
|
||||
}
|
||||
|
||||
@@ -41,9 +41,6 @@
|
||||
#ifdef HAVE_NETDB_H
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
#ifdef HAVE_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
@@ -78,8 +75,7 @@
|
||||
#include "http_proxy.h"
|
||||
#include "socks.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
@@ -127,7 +123,7 @@ timediff_t Curl_timeleft(struct Curl_easy *data,
|
||||
before the connect timeout expires and we must acknowledge whichever
|
||||
timeout that is reached first. The total timeout is set per entire
|
||||
operation, while the connect timeout is set per connect. */
|
||||
if(data->set.timeout <= 0 && !duringconnect)
|
||||
if((!data->set.timeout || data->set.connect_only) && !duringconnect)
|
||||
return 0; /* no timeout in place or checked, return "no limit" */
|
||||
|
||||
if(!nowp) {
|
||||
@@ -135,9 +131,9 @@ timediff_t Curl_timeleft(struct Curl_easy *data,
|
||||
nowp = &now;
|
||||
}
|
||||
|
||||
if(data->set.timeout > 0) {
|
||||
if(data->set.timeout) {
|
||||
timeleft_ms = data->set.timeout -
|
||||
curlx_timediff(*nowp, data->progress.t_startop);
|
||||
curlx_timediff(*nowp, data->progress.t_startop);
|
||||
if(!timeleft_ms)
|
||||
timeleft_ms = -1; /* 0 is "no limit", fake 1 ms expiry */
|
||||
if(!duringconnect)
|
||||
@@ -162,20 +158,21 @@ void Curl_shutdown_start(struct Curl_easy *data, int sockindex,
|
||||
int timeout_ms, struct curltime *nowp)
|
||||
{
|
||||
struct curltime now;
|
||||
struct connectdata *conn = data->conn;
|
||||
|
||||
DEBUGASSERT(data->conn);
|
||||
DEBUGASSERT(conn);
|
||||
if(!nowp) {
|
||||
now = curlx_now();
|
||||
nowp = &now;
|
||||
}
|
||||
data->conn->shutdown.start[sockindex] = *nowp;
|
||||
data->conn->shutdown.timeout_ms = (timeout_ms > 0) ?
|
||||
conn->shutdown.start[sockindex] = *nowp;
|
||||
conn->shutdown.timeout_ms = (timeout_ms > 0) ?
|
||||
(timediff_t)timeout_ms :
|
||||
((data->set.shutdowntimeout > 0) ?
|
||||
data->set.shutdowntimeout : DEFAULT_SHUTDOWN_TIMEOUT_MS);
|
||||
/* Set a timer, unless we operate on the admin handle */
|
||||
if(data->mid && (data->conn->shutdown.timeout_ms > 0))
|
||||
Curl_expire_ex(data, nowp, data->conn->shutdown.timeout_ms,
|
||||
if(data->mid)
|
||||
Curl_expire_ex(data, nowp, conn->shutdown.timeout_ms,
|
||||
EXPIRE_SHUTDOWN);
|
||||
}
|
||||
|
||||
@@ -270,7 +267,7 @@ bool Curl_addr2string(struct sockaddr *sa, curl_socklen_t salen,
|
||||
case AF_UNIX:
|
||||
if(salen > (curl_socklen_t)sizeof(CURL_SA_FAMILY_T)) {
|
||||
su = (struct sockaddr_un*)sa;
|
||||
msnprintf(addr, MAX_IPADR_LEN, "%s", su->sun_path);
|
||||
curl_msnprintf(addr, MAX_IPADR_LEN, "%s", su->sun_path);
|
||||
}
|
||||
else
|
||||
addr[0] = 0; /* socket with no name */
|
||||
@@ -621,3 +618,13 @@ out:
|
||||
Curl_resolv_unlink(data, &data->state.dns[sockindex]);
|
||||
return result;
|
||||
}
|
||||
|
||||
void Curl_conn_set_multiplex(struct connectdata *conn)
|
||||
{
|
||||
if(!conn->bits.multiplex) {
|
||||
conn->bits.multiplex = TRUE;
|
||||
if(conn->attached_multi) {
|
||||
Curl_multi_connchanged(conn->attached_multi);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,6 +123,9 @@ CURLcode Curl_conn_setup(struct Curl_easy *data,
|
||||
struct Curl_dns_entry *dns,
|
||||
int ssl_mode);
|
||||
|
||||
/* Set conn to allow multiplexing. */
|
||||
void Curl_conn_set_multiplex(struct connectdata *conn);
|
||||
|
||||
extern struct Curl_cftype Curl_cft_setup;
|
||||
|
||||
#endif /* HEADER_CURL_CONNECT_H */
|
||||
|
||||
@@ -51,10 +51,8 @@
|
||||
#include "sendf.h"
|
||||
#include "http.h"
|
||||
#include "content_encoding.h"
|
||||
#include "strdup.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
|
||||
@@ -80,17 +80,16 @@ Example set of cookies:
|
||||
#include "slist.h"
|
||||
#include "share.h"
|
||||
#include "strcase.h"
|
||||
#include "curl_fopen.h"
|
||||
#include "curl_get_line.h"
|
||||
#include "curl_memrchr.h"
|
||||
#include "parsedate.h"
|
||||
#include "rename.h"
|
||||
#include "fopen.h"
|
||||
#include "strdup.h"
|
||||
#include "llist.h"
|
||||
#include "curlx/strparse.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
@@ -751,7 +750,6 @@ parse_cookie_header(struct Curl_easy *data,
|
||||
if(!co->name)
|
||||
return CERR_BAD;
|
||||
|
||||
data->req.setcookies++;
|
||||
return CERR_OK;
|
||||
}
|
||||
|
||||
@@ -1141,6 +1139,9 @@ Curl_cookie_add(struct Curl_easy *data,
|
||||
if(co->expires && (co->expires < ci->next_expiration))
|
||||
ci->next_expiration = co->expires;
|
||||
|
||||
if(httpheader)
|
||||
data->req.setcookies++;
|
||||
|
||||
return co;
|
||||
fail:
|
||||
freecookie(co);
|
||||
@@ -1195,7 +1196,7 @@ struct CookieInfo *Curl_cookie_init(struct Curl_easy *data,
|
||||
if(!strcmp(file, "-"))
|
||||
fp = stdin;
|
||||
else {
|
||||
fp = fopen(file, "rb");
|
||||
fp = curlx_fopen(file, "rb");
|
||||
if(!fp)
|
||||
infof(data, "WARNING: failed to open cookie file \"%s\"", file);
|
||||
else
|
||||
@@ -1206,19 +1207,27 @@ struct CookieInfo *Curl_cookie_init(struct Curl_easy *data,
|
||||
ci->running = FALSE; /* this is not running, this is init */
|
||||
if(fp) {
|
||||
struct dynbuf buf;
|
||||
bool eof = FALSE;
|
||||
CURLcode result;
|
||||
curlx_dyn_init(&buf, MAX_COOKIE_LINE);
|
||||
while(Curl_get_line(&buf, fp)) {
|
||||
const char *lineptr = curlx_dyn_ptr(&buf);
|
||||
bool headerline = FALSE;
|
||||
if(checkprefix("Set-Cookie:", lineptr)) {
|
||||
/* This is a cookie line, get it! */
|
||||
lineptr += 11;
|
||||
headerline = TRUE;
|
||||
curlx_str_passblanks(&lineptr);
|
||||
}
|
||||
do {
|
||||
result = Curl_get_line(&buf, fp, &eof);
|
||||
if(!result) {
|
||||
const char *lineptr = curlx_dyn_ptr(&buf);
|
||||
bool headerline = FALSE;
|
||||
if(checkprefix("Set-Cookie:", lineptr)) {
|
||||
/* This is a cookie line, get it! */
|
||||
lineptr += 11;
|
||||
headerline = TRUE;
|
||||
curlx_str_passblanks(&lineptr);
|
||||
}
|
||||
|
||||
Curl_cookie_add(data, ci, headerline, TRUE, lineptr, NULL, NULL, TRUE);
|
||||
}
|
||||
(void)Curl_cookie_add(data, ci, headerline, TRUE, lineptr, NULL,
|
||||
NULL, TRUE);
|
||||
/* File reading cookie failures are not propagated back to the
|
||||
caller because there is no way to do that */
|
||||
}
|
||||
} while(!result && !eof);
|
||||
curlx_dyn_free(&buf); /* free the line buffer */
|
||||
|
||||
/*
|
||||
@@ -1228,7 +1237,7 @@ struct CookieInfo *Curl_cookie_init(struct Curl_easy *data,
|
||||
remove_expired(ci);
|
||||
|
||||
if(handle)
|
||||
fclose(handle);
|
||||
curlx_fclose(handle);
|
||||
}
|
||||
data->state.cookie_engine = TRUE;
|
||||
}
|
||||
@@ -1479,7 +1488,7 @@ void Curl_cookie_cleanup(struct CookieInfo *ci)
|
||||
*/
|
||||
static char *get_netscape_format(const struct Cookie *co)
|
||||
{
|
||||
return aprintf(
|
||||
return curl_maprintf(
|
||||
"%s" /* httponly preamble */
|
||||
"%s%s\t" /* domain */
|
||||
"%s\t" /* tailmatch */
|
||||
@@ -1575,7 +1584,7 @@ static CURLcode cookie_output(struct Curl_easy *data,
|
||||
error = CURLE_OUT_OF_MEMORY;
|
||||
goto error;
|
||||
}
|
||||
fprintf(out, "%s\n", format_ptr);
|
||||
curl_mfprintf(out, "%s\n", format_ptr);
|
||||
free(format_ptr);
|
||||
}
|
||||
|
||||
@@ -1583,10 +1592,9 @@ static CURLcode cookie_output(struct Curl_easy *data,
|
||||
}
|
||||
|
||||
if(!use_stdout) {
|
||||
fclose(out);
|
||||
curlx_fclose(out);
|
||||
out = NULL;
|
||||
if(tempstore && Curl_rename(tempstore, filename)) {
|
||||
unlink(tempstore);
|
||||
error = CURLE_WRITE_ERROR;
|
||||
goto error;
|
||||
}
|
||||
@@ -1602,8 +1610,11 @@ static CURLcode cookie_output(struct Curl_easy *data,
|
||||
|
||||
error:
|
||||
if(out && !use_stdout)
|
||||
fclose(out);
|
||||
free(tempstore);
|
||||
curlx_fclose(out);
|
||||
if(tempstore) {
|
||||
unlink(tempstore);
|
||||
free(tempstore);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -1658,18 +1669,18 @@ void Curl_flush_cookies(struct Curl_easy *data, bool cleanup)
|
||||
{
|
||||
CURLcode res;
|
||||
|
||||
if(data->set.str[STRING_COOKIEJAR]) {
|
||||
Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
|
||||
|
||||
Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
|
||||
/* only save the cookie file if a transfer was started (data->state.url is
|
||||
set), as otherwise the cookies were not completely initialized and there
|
||||
might be cookie files that weren't loaded so saving the file is the wrong
|
||||
thing. */
|
||||
if(data->set.str[STRING_COOKIEJAR] && data->state.url) {
|
||||
/* if we have a destination file for all the cookies to get dumped to */
|
||||
res = cookie_output(data, data->cookies, data->set.str[STRING_COOKIEJAR]);
|
||||
if(res)
|
||||
infof(data, "WARNING: failed to save cookies in %s: %s",
|
||||
data->set.str[STRING_COOKIEJAR], curl_easy_strerror(res));
|
||||
}
|
||||
else {
|
||||
Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
|
||||
}
|
||||
|
||||
if(cleanup && (!data->share || (data->cookies != data->share->cookies))) {
|
||||
Curl_cookie_cleanup(data->cookies);
|
||||
|
||||
@@ -42,8 +42,7 @@
|
||||
#include "select.h"
|
||||
#include "curlx/strparse.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
|
||||
@@ -53,8 +53,8 @@
|
||||
#include "fake_addrinfo.h"
|
||||
#include "curlx/inet_pton.h"
|
||||
#include "curlx/warnless.h"
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
@@ -507,9 +507,11 @@ curl_dbg_freeaddrinfo(struct addrinfo *freethis,
|
||||
if(env)
|
||||
r_freeaddrinfo(freethis);
|
||||
else
|
||||
/* !checksrc! disable BANNEDFUNC 1 */
|
||||
freeaddrinfo(freethis);
|
||||
}
|
||||
#else
|
||||
/* !checksrc! disable BANNEDFUNC 1 */
|
||||
freeaddrinfo(freethis);
|
||||
#endif
|
||||
}
|
||||
@@ -540,8 +542,10 @@ curl_dbg_getaddrinfo(const char *hostname,
|
||||
if(env)
|
||||
res = r_getaddrinfo(hostname, service, hints, result);
|
||||
else
|
||||
/* !checksrc! disable BANNEDFUNC 1 */
|
||||
res = getaddrinfo(hostname, service, hints, result);
|
||||
#else
|
||||
/* !checksrc! disable BANNEDFUNC 1 */
|
||||
int res = getaddrinfo(hostname, service, hints, result);
|
||||
#endif
|
||||
if(res == 0)
|
||||
|
||||
@@ -141,7 +141,7 @@
|
||||
/* disables SMTP */
|
||||
#cmakedefine CURL_DISABLE_SMTP 1
|
||||
|
||||
/* disabled WebSockets */
|
||||
/* disabled WebSocket */
|
||||
#cmakedefine CURL_DISABLE_WEBSOCKETS 1
|
||||
|
||||
/* disables use of socketpair for curl_multi_poll */
|
||||
@@ -308,15 +308,12 @@
|
||||
/* 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
|
||||
|
||||
/* if you have the GNU gssapi libraries */
|
||||
#cmakedefine HAVE_GSSGNU 1
|
||||
|
||||
/* MIT Kerberos version */
|
||||
#cmakedefine CURL_KRB5_VERSION ${CURL_KRB5_VERSION}
|
||||
|
||||
/* Define to 1 if you have the <ifaddrs.h> header file. */
|
||||
#cmakedefine HAVE_IFADDRS_H 1
|
||||
|
||||
@@ -416,9 +413,6 @@
|
||||
/* Define to 1 if you have the <net/if.h> header file. */
|
||||
#cmakedefine HAVE_NET_IF_H 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 `pipe' function. */
|
||||
#cmakedefine HAVE_PIPE 1
|
||||
|
||||
@@ -688,6 +682,9 @@ ${SIZEOF_TIME_T_CODE}
|
||||
/* if mbedTLS is enabled */
|
||||
#cmakedefine USE_MBEDTLS 1
|
||||
|
||||
/* if mbedTLS <4 has the mbedtls_des_crypt_ecb function. */
|
||||
#cmakedefine HAVE_MBEDTLS_DES_CRYPT_ECB 1
|
||||
|
||||
/* if Rustls is enabled */
|
||||
#cmakedefine USE_RUSTLS 1
|
||||
|
||||
@@ -715,9 +712,6 @@ ${SIZEOF_TIME_T_CODE}
|
||||
/* if libssh2 is in use */
|
||||
#cmakedefine USE_LIBSSH2 1
|
||||
|
||||
/* if wolfssh is in use */
|
||||
#cmakedefine USE_WOLFSSH 1
|
||||
|
||||
/* if libpsl is in use */
|
||||
#cmakedefine USE_LIBPSL 1
|
||||
|
||||
@@ -807,6 +801,9 @@ ${SIZEOF_TIME_T_CODE}
|
||||
/* to enable Apple IDN */
|
||||
#cmakedefine USE_APPLE_IDN 1
|
||||
|
||||
/* to enable Apple OS-native certificate verification */
|
||||
#cmakedefine USE_APPLE_SECTRUST 1
|
||||
|
||||
/* Define to 1 if OpenSSL has the SSL_CTX_set_srp_username function. */
|
||||
#cmakedefine HAVE_OPENSSL_SRP 1
|
||||
|
||||
@@ -823,7 +820,10 @@ ${SIZEOF_TIME_T_CODE}
|
||||
#cmakedefine USE_ECH 1
|
||||
|
||||
/* Define to 1 if you have the wolfSSL_CTX_GenerateEchConfig function. */
|
||||
#cmakedefine HAVE_WOLFSSL_CTX_GENERATEECHCONFIG
|
||||
#cmakedefine HAVE_WOLFSSL_CTX_GENERATEECHCONFIG 1
|
||||
|
||||
/* Define to 1 if you have the SSL_set1_ech_config_list function. */
|
||||
#cmakedefine HAVE_SSL_SET1_ECH_CONFIG_LIST
|
||||
#cmakedefine HAVE_SSL_SET1_ECH_CONFIG_LIST 1
|
||||
|
||||
/* Define to 1 if OpenSSL has the DES_ecb_encrypt function. */
|
||||
#cmakedefine HAVE_DES_ECB_ENCRYPT 1
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) Steve Holme, <steve_holme@hotmail.com>.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute 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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if defined(USE_CURL_NTLM_CORE) && \
|
||||
(defined(USE_GNUTLS) || \
|
||||
defined(USE_OS400CRYPTO) || \
|
||||
defined(USE_WIN32_CRYPTO))
|
||||
|
||||
#include "curl_des.h"
|
||||
|
||||
/*
|
||||
* Curl_des_set_odd_parity()
|
||||
*
|
||||
* This is used to apply odd parity to the given byte array. It is typically
|
||||
* used by when a cryptography engine does not have its own version.
|
||||
*
|
||||
* The function is a port of the Java based oddParity() function over at:
|
||||
*
|
||||
* https://davenport.sourceforge.net/ntlm.html
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* bytes [in/out] - The data whose parity bits are to be adjusted for
|
||||
* odd parity.
|
||||
* len [out] - The length of the data.
|
||||
*/
|
||||
void Curl_des_set_odd_parity(unsigned char *bytes, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for(i = 0; i < len; i++) {
|
||||
unsigned char b = bytes[i];
|
||||
|
||||
bool needs_parity = (((b >> 7) ^ (b >> 6) ^ (b >> 5) ^
|
||||
(b >> 4) ^ (b >> 3) ^ (b >> 2) ^
|
||||
(b >> 1)) & 0x01) == 0;
|
||||
|
||||
if(needs_parity)
|
||||
bytes[i] |= 0x01;
|
||||
else
|
||||
bytes[i] &= 0xfe;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -27,15 +27,11 @@
|
||||
#if !defined(CURL_DISABLE_COOKIES) || !defined(CURL_DISABLE_ALTSVC) || \
|
||||
!defined(CURL_DISABLE_HSTS)
|
||||
|
||||
#ifdef HAVE_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#include "urldata.h"
|
||||
#include "rand.h"
|
||||
#include "fopen.h"
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_fopen.h"
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
@@ -102,11 +98,12 @@ CURLcode Curl_fopen(struct Curl_easy *data, const char *filename,
|
||||
char *dir = NULL;
|
||||
*tempname = NULL;
|
||||
|
||||
*fh = fopen(filename, FOPEN_WRITETEXT);
|
||||
*fh = curlx_fopen(filename, FOPEN_WRITETEXT);
|
||||
if(!*fh)
|
||||
goto fail;
|
||||
if(
|
||||
#ifdef UNDER_CE
|
||||
/* !checksrc! disable BANNEDFUNC 1 */
|
||||
stat(filename, &sb) == -1
|
||||
#else
|
||||
fstat(fileno(*fh), &sb) == -1
|
||||
@@ -114,7 +111,7 @@ CURLcode Curl_fopen(struct Curl_easy *data, const char *filename,
|
||||
|| !S_ISREG(sb.st_mode)) {
|
||||
return CURLE_OK;
|
||||
}
|
||||
fclose(*fh);
|
||||
curlx_fclose(*fh);
|
||||
*fh = NULL;
|
||||
|
||||
result = Curl_rand_alnum(data, randbuf, sizeof(randbuf));
|
||||
@@ -125,7 +122,7 @@ CURLcode Curl_fopen(struct Curl_easy *data, const char *filename,
|
||||
if(dir) {
|
||||
/* The temp filename should not end up too long for the target file
|
||||
system */
|
||||
tempstore = aprintf("%s%s.tmp", dir, randbuf);
|
||||
tempstore = curl_maprintf("%s%s.tmp", dir, randbuf);
|
||||
free(dir);
|
||||
}
|
||||
|
||||
@@ -137,14 +134,16 @@ CURLcode Curl_fopen(struct Curl_easy *data, const char *filename,
|
||||
result = CURLE_WRITE_ERROR;
|
||||
#if (defined(ANDROID) || defined(__ANDROID__)) && \
|
||||
(defined(__i386__) || defined(__arm__))
|
||||
fd = open(tempstore, O_WRONLY | O_CREAT | O_EXCL, (mode_t)(0600|sb.st_mode));
|
||||
fd = curlx_open(tempstore, O_WRONLY | O_CREAT | O_EXCL,
|
||||
(mode_t)(0600 | sb.st_mode));
|
||||
#else
|
||||
fd = open(tempstore, O_WRONLY | O_CREAT | O_EXCL, 0600|sb.st_mode);
|
||||
fd = curlx_open(tempstore, O_WRONLY | O_CREAT | O_EXCL,
|
||||
0600 | sb.st_mode);
|
||||
#endif
|
||||
if(fd == -1)
|
||||
goto fail;
|
||||
|
||||
*fh = fdopen(fd, FOPEN_WRITETEXT);
|
||||
*fh = curlx_fdopen(fd, FOPEN_WRITETEXT);
|
||||
if(!*fh)
|
||||
goto fail;
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curlx/fopen.h"
|
||||
|
||||
CURLcode Curl_fopen(struct Curl_easy *data, const char *filename,
|
||||
FILE **fh, char **tempname);
|
||||
|
||||
@@ -32,63 +32,43 @@
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
static int appendnl(struct dynbuf *buf)
|
||||
{
|
||||
CURLcode result = curlx_dyn_addn(buf, "\n", 1);
|
||||
if(result)
|
||||
/* too long line or out of memory */
|
||||
return 0; /* error */
|
||||
return 1; /* all good */
|
||||
}
|
||||
#define appendnl(b) \
|
||||
curlx_dyn_addn(buf, "\n", 1)
|
||||
|
||||
/*
|
||||
* Curl_get_line() makes sure to only return complete whole lines that end
|
||||
* newlines.
|
||||
* Curl_get_line() returns only complete whole lines that end with newline.
|
||||
* When 'eof' is set TRUE, the last line has been read.
|
||||
*/
|
||||
int Curl_get_line(struct dynbuf *buf, FILE *input)
|
||||
CURLcode Curl_get_line(struct dynbuf *buf, FILE *input, bool *eof)
|
||||
{
|
||||
CURLcode result;
|
||||
char buffer[128];
|
||||
curlx_dyn_reset(buf);
|
||||
while(1) {
|
||||
char *b = fgets(buffer, sizeof(buffer), input);
|
||||
size_t rlen;
|
||||
char *b = fgets(buffer, sizeof(buffer), input);
|
||||
|
||||
if(b) {
|
||||
rlen = strlen(b);
|
||||
|
||||
if(!rlen)
|
||||
break;
|
||||
*eof = feof(input);
|
||||
|
||||
rlen = b ? strlen(b) : 0;
|
||||
if(rlen) {
|
||||
result = curlx_dyn_addn(buf, b, rlen);
|
||||
if(result)
|
||||
/* too long line or out of memory */
|
||||
return 0; /* error */
|
||||
|
||||
else if(b[rlen-1] == '\n')
|
||||
/* end of the line */
|
||||
return 1; /* all good */
|
||||
|
||||
else if(feof(input))
|
||||
/* append a newline */
|
||||
return appendnl(buf);
|
||||
}
|
||||
else {
|
||||
rlen = curlx_dyn_len(buf);
|
||||
if(rlen) {
|
||||
b = curlx_dyn_ptr(buf);
|
||||
|
||||
if(b[rlen-1] != '\n')
|
||||
/* append a newline */
|
||||
return appendnl(buf);
|
||||
|
||||
return 1; /* all good */
|
||||
}
|
||||
else
|
||||
break;
|
||||
return result;
|
||||
}
|
||||
/* now check the full line */
|
||||
rlen = curlx_dyn_len(buf);
|
||||
b = curlx_dyn_ptr(buf);
|
||||
if(rlen && (b[rlen-1] == '\n'))
|
||||
/* LF at end of the line */
|
||||
return CURLE_OK; /* all good */
|
||||
if(*eof)
|
||||
/* append a newline */
|
||||
return appendnl(buf);
|
||||
/* otherwise get next line to append */
|
||||
}
|
||||
return 0;
|
||||
/* UNREACHABLE */
|
||||
}
|
||||
|
||||
#endif /* if not disabled */
|
||||
|
||||
@@ -27,6 +27,6 @@
|
||||
#include "curlx/dynbuf.h"
|
||||
|
||||
/* Curl_get_line() returns complete lines that end with a newline. */
|
||||
int Curl_get_line(struct dynbuf *buf, FILE *input);
|
||||
CURLcode Curl_get_line(struct dynbuf *buf, FILE *input, bool *eof);
|
||||
|
||||
#endif /* HEADER_CURL_GET_LINE_H */
|
||||
|
||||
@@ -29,8 +29,29 @@
|
||||
#include "curl_gssapi.h"
|
||||
#include "sendf.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#ifdef DEBUGBUILD
|
||||
#if defined(HAVE_GSSGNU) || !defined(_WIN32)
|
||||
/* To avoid memdebug macro replacement, wrap the name in parentheses to call
|
||||
the original version. It is freed via the GSS API gss_release_buffer(). */
|
||||
#define Curl_gss_alloc (malloc)
|
||||
#define Curl_gss_free (free)
|
||||
#define CURL_GSS_STUB
|
||||
/* For correctness this would be required for all platforms, not only Windows,
|
||||
but, as of v1.22.1, MIT Kerberos uses a special allocator only for Windows,
|
||||
and the availability of 'gssapi/gssapi_alloc.h' is difficult to detect,
|
||||
because GSS headers are not versioned, and there is also no other macro to
|
||||
indicate 1.18+ vs. previous versions. On Windows we can use 'GSS_S_BAD_MIC'.
|
||||
*/
|
||||
#elif defined(_WIN32) && defined(GSS_S_BAD_MIC) /* MIT Kerberos 1.15+ */
|
||||
/* MIT Kerberos 1.10+ (Windows), 1.18+ (all platforms), missing from GNU GSS */
|
||||
#include <gssapi/gssapi_alloc.h>
|
||||
#define Curl_gss_alloc gssalloc_malloc
|
||||
#define Curl_gss_free gssalloc_free
|
||||
#define CURL_GSS_STUB
|
||||
#endif
|
||||
#endif /* DEBUGBUILD */
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
@@ -52,7 +73,7 @@ gss_OID_desc Curl_krb5_mech_oid CURL_ALIGN8 = {
|
||||
9, CURL_UNCONST("\x2a\x86\x48\x86\xf7\x12\x01\x02\x02")
|
||||
};
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
#ifdef CURL_GSS_STUB
|
||||
enum min_err_code {
|
||||
STUB_GSS_OK = 0,
|
||||
STUB_GSS_NO_MEMORY,
|
||||
@@ -213,9 +234,7 @@ stub_gss_init_sec_context(OM_uint32 *min,
|
||||
ctx->flags = req_flags;
|
||||
}
|
||||
|
||||
/* To avoid memdebug macro replacement, wrap the name in parentheses to call
|
||||
the original version. It is freed via the GSS API gss_release_buffer(). */
|
||||
token = (malloc)(length);
|
||||
token = Curl_gss_alloc(length);
|
||||
if(!token) {
|
||||
free(ctx);
|
||||
*min = STUB_GSS_NO_MEMORY;
|
||||
@@ -230,29 +249,30 @@ stub_gss_init_sec_context(OM_uint32 *min,
|
||||
major_status = gss_display_name(&minor_status, target_name,
|
||||
&target_desc, &name_type);
|
||||
if(GSS_ERROR(major_status)) {
|
||||
(free)(token);
|
||||
Curl_gss_free(token);
|
||||
free(ctx);
|
||||
*min = STUB_GSS_NO_MEMORY;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
if(strlen(creds) + target_desc.length + 5 >= sizeof(ctx->creds)) {
|
||||
(free)(token);
|
||||
Curl_gss_free(token);
|
||||
free(ctx);
|
||||
*min = STUB_GSS_NO_MEMORY;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
/* Token format: creds:target:type:padding */
|
||||
used = msnprintf(token, length, "%s:%.*s:%d:", creds,
|
||||
(int)target_desc.length, (const char *)target_desc.value,
|
||||
ctx->sent);
|
||||
used = curl_msnprintf(token, length, "%s:%.*s:%d:", creds,
|
||||
(int)target_desc.length,
|
||||
(const char *)target_desc.value,
|
||||
ctx->sent);
|
||||
|
||||
gss_release_buffer(&minor_status, &target_desc);
|
||||
}
|
||||
|
||||
if(used >= length) {
|
||||
(free)(token);
|
||||
Curl_gss_free(token);
|
||||
free(ctx);
|
||||
*min = STUB_GSS_NO_MEMORY;
|
||||
return GSS_S_FAILURE;
|
||||
@@ -294,7 +314,7 @@ stub_gss_delete_sec_context(OM_uint32 *min,
|
||||
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
#endif /* DEBUGBUILD */
|
||||
#endif /* CURL_GSS_STUB */
|
||||
|
||||
OM_uint32 Curl_gss_init_sec_context(struct Curl_easy *data,
|
||||
OM_uint32 *minor_status,
|
||||
@@ -313,7 +333,7 @@ OM_uint32 Curl_gss_init_sec_context(struct Curl_easy *data,
|
||||
req_flags |= GSS_C_MUTUAL_FLAG;
|
||||
|
||||
if(data->set.gssapi_delegation & CURLGSSAPI_DELEGATION_POLICY_FLAG) {
|
||||
#ifdef GSS_C_DELEG_POLICY_FLAG
|
||||
#ifdef GSS_C_DELEG_POLICY_FLAG /* MIT Kerberos 1.8+, missing from GNU GSS */
|
||||
req_flags |= GSS_C_DELEG_POLICY_FLAG;
|
||||
#else
|
||||
infof(data, "WARNING: support for CURLGSSAPI_DELEGATION_POLICY_FLAG not "
|
||||
@@ -324,7 +344,7 @@ OM_uint32 Curl_gss_init_sec_context(struct Curl_easy *data,
|
||||
if(data->set.gssapi_delegation & CURLGSSAPI_DELEGATION_FLAG)
|
||||
req_flags |= GSS_C_DELEG_FLAG;
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
#ifdef CURL_GSS_STUB
|
||||
if(getenv("CURL_STUB_GSS_CREDS"))
|
||||
return stub_gss_init_sec_context(minor_status,
|
||||
GSS_C_NO_CREDENTIAL, /* cred_handle */
|
||||
@@ -339,7 +359,7 @@ OM_uint32 Curl_gss_init_sec_context(struct Curl_easy *data,
|
||||
output_token,
|
||||
ret_flags,
|
||||
NULL /* time_rec */);
|
||||
#endif /* DEBUGBUILD */
|
||||
#endif /* CURL_GSS_STUB */
|
||||
|
||||
return gss_init_sec_context(minor_status,
|
||||
GSS_C_NO_CREDENTIAL, /* cred_handle */
|
||||
@@ -360,12 +380,12 @@ OM_uint32 Curl_gss_delete_sec_context(OM_uint32 *min,
|
||||
gss_ctx_id_t *context,
|
||||
gss_buffer_t output_token)
|
||||
{
|
||||
#ifdef DEBUGBUILD
|
||||
#ifdef CURL_GSS_STUB
|
||||
if(getenv("CURL_STUB_GSS_CREDS"))
|
||||
return stub_gss_delete_sec_context(min,
|
||||
(struct stub_gss_ctx_id_t_desc **)context,
|
||||
output_token);
|
||||
#endif /* DEBUGBUILD */
|
||||
#endif /* CURL_GSS_STUB */
|
||||
|
||||
return gss_delete_sec_context(min, context, output_token);
|
||||
}
|
||||
@@ -387,9 +407,9 @@ static size_t display_gss_error(OM_uint32 status, int type,
|
||||
&status_string);
|
||||
if(maj_stat == GSS_S_COMPLETE && status_string.length > 0) {
|
||||
if(GSS_LOG_BUFFER_LEN > len + status_string.length + 3) {
|
||||
len += msnprintf(buf + len, GSS_LOG_BUFFER_LEN - len,
|
||||
"%.*s. ", (int)status_string.length,
|
||||
(char *)status_string.value);
|
||||
len += curl_msnprintf(buf + len, GSS_LOG_BUFFER_LEN - len,
|
||||
"%.*s. ", (int)status_string.length,
|
||||
(char *)status_string.value);
|
||||
}
|
||||
}
|
||||
gss_release_buffer(&min_stat, &status_string);
|
||||
|
||||
@@ -28,6 +28,11 @@
|
||||
#include "urldata.h"
|
||||
|
||||
#ifdef HAVE_GSSAPI
|
||||
|
||||
#ifdef GSS_C_CHANNEL_BOUND_FLAG /* MIT Kerberos 1.19+, missing from GNU GSS */
|
||||
#define CURL_GSSAPI_HAS_CHANNEL_BINDING
|
||||
#endif
|
||||
|
||||
extern gss_OID_desc Curl_spnego_mech_oid;
|
||||
extern gss_OID_desc Curl_krb5_mech_oid;
|
||||
|
||||
@@ -51,12 +56,6 @@ OM_uint32 Curl_gss_delete_sec_context(OM_uint32 *min,
|
||||
void Curl_gss_log_error(struct Curl_easy *data, const char *prefix,
|
||||
OM_uint32 major, OM_uint32 minor);
|
||||
|
||||
/* Provide some definitions missing in old headers */
|
||||
#ifdef HAVE_OLD_GSSMIT
|
||||
#define GSS_C_NT_HOSTBASED_SERVICE gss_nt_service_name
|
||||
#define NCOMPAT 1
|
||||
#endif
|
||||
|
||||
/* Define our privacy and integrity protection values */
|
||||
#define GSSAUTH_P_NONE 1
|
||||
#define GSSAUTH_P_INTEGRITY 2
|
||||
|
||||
@@ -29,27 +29,9 @@
|
||||
#undef calloc
|
||||
#undef realloc
|
||||
#undef free
|
||||
#undef send
|
||||
#undef recv
|
||||
|
||||
#ifdef _WIN32
|
||||
#undef _tcsdup
|
||||
#undef Curl_tcsdup
|
||||
#endif
|
||||
|
||||
#undef socket
|
||||
#ifdef HAVE_ACCEPT4
|
||||
#undef accept4
|
||||
#endif
|
||||
#ifdef HAVE_SOCKETPAIR
|
||||
#undef socketpair
|
||||
#endif
|
||||
|
||||
#undef fopen
|
||||
#ifdef CURL_FOPEN
|
||||
#define fopen(fname, mode) CURL_FOPEN(fname, mode)
|
||||
#endif
|
||||
#undef fdopen
|
||||
#undef fclose
|
||||
|
||||
#undef HEADER_CURL_MEMORY_H
|
||||
#undef HEADER_CURL_MEMDEBUG_H
|
||||
|
||||
@@ -77,11 +77,11 @@
|
||||
#define free(ptr) Curl_cfree(ptr)
|
||||
|
||||
#ifdef _WIN32
|
||||
#undef _tcsdup
|
||||
#undef Curl_tcsdup
|
||||
#ifdef UNICODE
|
||||
#define _tcsdup(ptr) Curl_wcsdup(ptr)
|
||||
#define Curl_tcsdup(ptr) Curl_wcsdup(ptr)
|
||||
#else
|
||||
#define _tcsdup(ptr) Curl_cstrdup(ptr)
|
||||
#define Curl_tcsdup(ptr) Curl_cstrdup(ptr)
|
||||
#endif
|
||||
#endif /* _WIN32 */
|
||||
|
||||
|
||||
@@ -38,10 +38,9 @@
|
||||
1. USE_OPENSSL
|
||||
2. USE_WOLFSSL
|
||||
3. USE_GNUTLS
|
||||
4. -
|
||||
5. USE_MBEDTLS
|
||||
6. USE_OS400CRYPTO
|
||||
7. USE_WIN32_CRYPTO
|
||||
4. USE_MBEDTLS
|
||||
5. USE_OS400CRYPTO
|
||||
6. USE_WIN32_CRYPTO
|
||||
|
||||
This ensures that:
|
||||
- the same SSL branch gets activated throughout this source
|
||||
@@ -51,23 +50,25 @@
|
||||
in NTLM type-3 messages.
|
||||
*/
|
||||
|
||||
#ifdef USE_OPENSSL
|
||||
#include <openssl/opensslconf.h>
|
||||
#if !defined(OPENSSL_NO_DES) && !defined(OPENSSL_NO_DEPRECATED_3_0)
|
||||
#define USE_OPENSSL_DES
|
||||
#endif
|
||||
#elif defined(USE_WOLFSSL)
|
||||
#include <wolfssl/options.h>
|
||||
#ifndef NO_DES3
|
||||
#define USE_OPENSSL_DES
|
||||
#endif
|
||||
#ifdef USE_MBEDTLS
|
||||
#include <mbedtls/version.h>
|
||||
#if MBEDTLS_VERSION_NUMBER < 0x03020000
|
||||
#error "mbedTLS 3.2.0 or later required"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(USE_OPENSSL) && defined(HAVE_DES_ECB_ENCRYPT)
|
||||
#define USE_OPENSSL_DES
|
||||
#elif defined(USE_WOLFSSL) && defined(HAVE_WOLFSSL_DES_ECB_ENCRYPT)
|
||||
#define USE_OPENSSL_DES
|
||||
#elif defined(USE_MBEDTLS) && defined(HAVE_MBEDTLS_DES_CRYPT_ECB)
|
||||
#define USE_MBEDTLS_DES
|
||||
#endif
|
||||
|
||||
#ifdef USE_OPENSSL_DES
|
||||
|
||||
#ifdef USE_OPENSSL
|
||||
# include <openssl/des.h>
|
||||
# include <openssl/md5.h>
|
||||
# include <openssl/ssl.h>
|
||||
# include <openssl/rand.h>
|
||||
# ifdef OPENSSL_IS_AWSLC /* for versions 1.2.0 to 1.30.1 */
|
||||
@@ -75,8 +76,8 @@
|
||||
# endif
|
||||
# define DESKEY(x) &x
|
||||
#else
|
||||
# include <wolfssl/options.h>
|
||||
# include <wolfssl/openssl/des.h>
|
||||
# include <wolfssl/openssl/md5.h>
|
||||
# include <wolfssl/openssl/ssl.h>
|
||||
# include <wolfssl/openssl/rand.h>
|
||||
# ifdef OPENSSL_COEXIST
|
||||
@@ -96,18 +97,20 @@
|
||||
#elif defined(USE_GNUTLS)
|
||||
|
||||
# include <nettle/des.h>
|
||||
# define USE_CURL_DES_SET_ODD_PARITY
|
||||
|
||||
#elif defined(USE_MBEDTLS)
|
||||
#elif defined(USE_MBEDTLS_DES)
|
||||
|
||||
# include <mbedtls/des.h>
|
||||
|
||||
#elif defined(USE_OS400CRYPTO)
|
||||
# include "cipher.mih" /* mih/cipher */
|
||||
# define USE_CURL_DES_SET_ODD_PARITY
|
||||
#elif defined(USE_WIN32_CRYPTO)
|
||||
# include <wincrypt.h>
|
||||
# define USE_CURL_DES_SET_ODD_PARITY
|
||||
#else
|
||||
# error "cannot compile NTLM support without a crypto library with DES."
|
||||
# define CURL_NTLM_NOT_SUPPORTED
|
||||
#endif
|
||||
|
||||
#include "urldata.h"
|
||||
@@ -117,14 +120,50 @@
|
||||
#include "curl_hmac.h"
|
||||
#include "curlx/warnless.h"
|
||||
#include "curl_endian.h"
|
||||
#include "curl_des.h"
|
||||
#include "curl_md4.h"
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#ifndef CURL_NTLM_NOT_SUPPORTED
|
||||
#ifdef USE_CURL_DES_SET_ODD_PARITY
|
||||
/*
|
||||
* curl_des_set_odd_parity()
|
||||
*
|
||||
* Copyright (C) Steve Holme, <steve_holme@hotmail.com>
|
||||
*
|
||||
* This is used to apply odd parity to the given byte array. It is typically
|
||||
* used by when a cryptography engine does not have its own version.
|
||||
*
|
||||
* The function is a port of the Java based oddParity() function over at:
|
||||
*
|
||||
* https://davenport.sourceforge.net/ntlm.html
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* bytes [in/out] - The data whose parity bits are to be adjusted for
|
||||
* odd parity.
|
||||
* len [out] - The length of the data.
|
||||
*/
|
||||
static void curl_des_set_odd_parity(unsigned char *bytes, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for(i = 0; i < len; i++) {
|
||||
unsigned char b = bytes[i];
|
||||
|
||||
bool needs_parity = (((b >> 7) ^ (b >> 6) ^ (b >> 5) ^
|
||||
(b >> 4) ^ (b >> 3) ^ (b >> 2) ^
|
||||
(b >> 1)) & 0x01) == 0;
|
||||
|
||||
if(needs_parity)
|
||||
bytes[i] |= 0x01;
|
||||
else
|
||||
bytes[i] &= 0xfe;
|
||||
}
|
||||
}
|
||||
#endif /* USE_CURL_DES_SET_ODD_PARITY */
|
||||
|
||||
/*
|
||||
* Turns a 56-bit key into being 64-bit wide.
|
||||
*/
|
||||
@@ -139,7 +178,6 @@ static void extend_key_56_to_64(const unsigned char *key_56, char *key)
|
||||
key[6] = (char)(((key_56[5] << 2) & 0xFF) | (key_56[6] >> 6));
|
||||
key[7] = (char) ((key_56[6] << 1) & 0xFF);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_OPENSSL_DES
|
||||
/*
|
||||
@@ -172,13 +210,13 @@ static void setup_des_key(const unsigned char *key_56,
|
||||
extend_key_56_to_64(key_56, key);
|
||||
|
||||
/* Set the key parity to odd */
|
||||
Curl_des_set_odd_parity((unsigned char *) key, sizeof(key));
|
||||
curl_des_set_odd_parity((unsigned char *) key, sizeof(key));
|
||||
|
||||
/* Set the key */
|
||||
des_set_key(des, (const uint8_t *) key);
|
||||
}
|
||||
|
||||
#elif defined(USE_MBEDTLS)
|
||||
#elif defined(USE_MBEDTLS_DES)
|
||||
|
||||
static bool encrypt_des(const unsigned char *in, unsigned char *out,
|
||||
const unsigned char *key_56)
|
||||
@@ -214,7 +252,7 @@ static bool encrypt_des(const unsigned char *in, unsigned char *out,
|
||||
extend_key_56_to_64(key_56, ctl.Crypto_Key);
|
||||
|
||||
/* Set the key parity to odd */
|
||||
Curl_des_set_odd_parity((unsigned char *) ctl.Crypto_Key, ctl.Data_Len);
|
||||
curl_des_set_odd_parity((unsigned char *) ctl.Crypto_Key, ctl.Data_Len);
|
||||
|
||||
/* Perform the encryption */
|
||||
_CIPHER((_SPCPTR *) &out, &ctl, (_SPCPTR *) &in);
|
||||
@@ -252,7 +290,7 @@ static bool encrypt_des(const unsigned char *in, unsigned char *out,
|
||||
extend_key_56_to_64(key_56, blob.key);
|
||||
|
||||
/* Set the key parity to odd */
|
||||
Curl_des_set_odd_parity((unsigned char *) blob.key, sizeof(blob.key));
|
||||
curl_des_set_odd_parity((unsigned char *) blob.key, sizeof(blob.key));
|
||||
|
||||
/* Import the key */
|
||||
if(!CryptImportKey(hprov, (BYTE *) &blob, sizeof(blob), 0, 0, &hkey)) {
|
||||
@@ -305,7 +343,7 @@ void Curl_ntlm_core_lm_resp(const unsigned char *keys,
|
||||
des_encrypt(&des, 8, results + 8, plaintext);
|
||||
setup_des_key(keys + 14, &des);
|
||||
des_encrypt(&des, 8, results + 16, plaintext);
|
||||
#elif defined(USE_MBEDTLS) || defined(USE_OS400CRYPTO) || \
|
||||
#elif defined(USE_MBEDTLS_DES) || defined(USE_OS400CRYPTO) || \
|
||||
defined(USE_WIN32_CRYPTO)
|
||||
encrypt_des(plaintext, results, keys);
|
||||
encrypt_des(plaintext, results + 8, keys + 7);
|
||||
@@ -324,11 +362,9 @@ CURLcode Curl_ntlm_core_mk_lm_hash(const char *password,
|
||||
unsigned char *lmbuffer /* 21 bytes */)
|
||||
{
|
||||
unsigned char pw[14];
|
||||
#ifndef CURL_NTLM_NOT_SUPPORTED
|
||||
static const unsigned char magic[] = {
|
||||
0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 /* i.e. KGS!@#$% */
|
||||
};
|
||||
#endif
|
||||
size_t len = CURLMIN(strlen(password), 14);
|
||||
|
||||
Curl_strntoupper((char *)pw, password, len);
|
||||
@@ -353,7 +389,7 @@ CURLcode Curl_ntlm_core_mk_lm_hash(const char *password,
|
||||
des_encrypt(&des, 8, lmbuffer, magic);
|
||||
setup_des_key(pw + 7, &des);
|
||||
des_encrypt(&des, 8, lmbuffer + 8, magic);
|
||||
#elif defined(USE_MBEDTLS) || defined(USE_OS400CRYPTO) || \
|
||||
#elif defined(USE_MBEDTLS_DES) || defined(USE_OS400CRYPTO) || \
|
||||
defined(USE_WIN32_CRYPTO)
|
||||
encrypt_des(magic, lmbuffer, pw);
|
||||
encrypt_des(magic, lmbuffer + 8, pw + 7);
|
||||
@@ -567,14 +603,15 @@ CURLcode Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash,
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
/* Create the BLOB structure */
|
||||
msnprintf((char *)ptr + HMAC_MD5_LENGTH, NTLMv2_BLOB_LEN,
|
||||
"%c%c%c%c" /* NTLMv2_BLOB_SIGNATURE */
|
||||
"%c%c%c%c" /* Reserved = 0 */
|
||||
"%c%c%c%c%c%c%c%c", /* Timestamp */
|
||||
NTLMv2_BLOB_SIGNATURE[0], NTLMv2_BLOB_SIGNATURE[1],
|
||||
NTLMv2_BLOB_SIGNATURE[2], NTLMv2_BLOB_SIGNATURE[3],
|
||||
0, 0, 0, 0,
|
||||
LONGQUARTET(tw.dwLowDateTime), LONGQUARTET(tw.dwHighDateTime));
|
||||
curl_msnprintf((char *)ptr + HMAC_MD5_LENGTH, NTLMv2_BLOB_LEN,
|
||||
"%c%c%c%c" /* NTLMv2_BLOB_SIGNATURE */
|
||||
"%c%c%c%c" /* Reserved = 0 */
|
||||
"%c%c%c%c%c%c%c%c", /* Timestamp */
|
||||
NTLMv2_BLOB_SIGNATURE[0], NTLMv2_BLOB_SIGNATURE[1],
|
||||
NTLMv2_BLOB_SIGNATURE[2], NTLMv2_BLOB_SIGNATURE[3],
|
||||
0, 0, 0, 0,
|
||||
LONGQUARTET(tw.dwLowDateTime),
|
||||
LONGQUARTET(tw.dwHighDateTime));
|
||||
|
||||
memcpy(ptr + 32, challenge_client, 8);
|
||||
if(ntlm->target_info_len)
|
||||
|
||||
@@ -24,8 +24,6 @@
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
#define MERR_OK 0
|
||||
#define MERR_MEM 1
|
||||
#define MERR_TOO_LARGE 2
|
||||
@@ -36,29 +34,4 @@ extern const unsigned char Curl_ldigits[];
|
||||
/* Upper-case digits. */
|
||||
extern const unsigned char Curl_udigits[];
|
||||
|
||||
#ifdef BUILDING_LIBCURL
|
||||
|
||||
/*
|
||||
* This header should be included by ALL code in libcurl that uses any
|
||||
* *rintf() functions.
|
||||
*/
|
||||
|
||||
# undef printf
|
||||
# undef fprintf
|
||||
# undef msnprintf
|
||||
# undef vprintf
|
||||
# undef vfprintf
|
||||
# undef mvsnprintf
|
||||
# undef aprintf
|
||||
# undef vaprintf
|
||||
# define printf curl_mprintf
|
||||
# define fprintf curl_mfprintf
|
||||
# define msnprintf curl_msnprintf
|
||||
# define vprintf curl_mvprintf
|
||||
# define vfprintf curl_mvfprintf
|
||||
# define mvsnprintf curl_mvsnprintf
|
||||
# define aprintf curl_maprintf
|
||||
# define vaprintf curl_mvaprintf
|
||||
|
||||
#endif /* BUILDING_LIBCURL */
|
||||
#endif /* HEADER_CURL_PRINTF_H */
|
||||
|
||||
@@ -37,8 +37,7 @@
|
||||
#include <curl/curl.h>
|
||||
#include <librtmp/rtmp.h>
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
@@ -386,9 +385,9 @@ void Curl_rtmp_version(char *version, size_t len)
|
||||
else
|
||||
suff[0] = '\0';
|
||||
|
||||
msnprintf(version, len, "librtmp/%d.%d%s",
|
||||
RTMP_LIB_VERSION >> 16, (RTMP_LIB_VERSION >> 8) & 0xff,
|
||||
suff);
|
||||
curl_msnprintf(version, len, "librtmp/%d.%d%s",
|
||||
RTMP_LIB_VERSION >> 16, (RTMP_LIB_VERSION >> 8) & 0xff,
|
||||
suff);
|
||||
}
|
||||
|
||||
#endif /* USE_LIBRTMP */
|
||||
|
||||
@@ -43,7 +43,6 @@
|
||||
#include "urldata.h"
|
||||
|
||||
#include "curlx/base64.h"
|
||||
#include "curl_md5.h"
|
||||
#include "vauth/vauth.h"
|
||||
#include "cfilters.h"
|
||||
#include "vtls/vtls.h"
|
||||
@@ -51,8 +50,8 @@
|
||||
#include "curl_sasl.h"
|
||||
#include "curlx/warnless.h"
|
||||
#include "sendf.h"
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
@@ -812,7 +811,9 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data,
|
||||
|
||||
case SASL_CANCEL:
|
||||
/* Remove the offending mechanism from the supported list */
|
||||
sasl->authmechs ^= sasl->authused;
|
||||
sasl->authmechs &= (unsigned short)~sasl->authused;
|
||||
sasl->authused = SASL_AUTH_NONE;
|
||||
sasl->curmech = NULL;
|
||||
|
||||
/* Start an alternative SASL authentication */
|
||||
return Curl_sasl_start(sasl, data, sasl->force_ir, progress);
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
fail. Fixed in 14.2.0_1. Disable the workaround if the fix is detected. */
|
||||
#if defined(__APPLE__) && !defined(__clang__) && defined(__GNUC__) && \
|
||||
defined(__has_attribute)
|
||||
# if !defined(__has_feature)
|
||||
# if !defined(__has_feature) /* Keep this PP check separate from others */
|
||||
# define availability curl_pp_attribute_disabled
|
||||
# elif !__has_feature(attribute_availability)
|
||||
# define availability curl_pp_attribute_disabled
|
||||
@@ -521,15 +521,6 @@
|
||||
# endif
|
||||
# define LSEEK_ERROR (long)-1
|
||||
# endif
|
||||
# ifndef UNDER_CE
|
||||
int curlx_win32_stat(const char *path, struct_stat *buffer);
|
||||
int curlx_win32_open(const char *filename, int oflag, ...);
|
||||
FILE *curlx_win32_fopen(const char *filename, const char *mode);
|
||||
# define stat(fname, stp) curlx_win32_stat(fname, stp)
|
||||
# define open curlx_win32_open
|
||||
# define CURL_FOPEN(fname, mode) curlx_win32_fopen(fname, mode)
|
||||
# define fopen(fname, mode) CURL_FOPEN(fname, mode)
|
||||
# endif
|
||||
#elif defined(__DJGPP__)
|
||||
/* Requires DJGPP 2.04 */
|
||||
# include <unistd.h>
|
||||
@@ -780,8 +771,9 @@
|
||||
|
||||
/* Single point where USE_NTLM definition might be defined */
|
||||
#ifndef CURL_DISABLE_NTLM
|
||||
# if defined(USE_OPENSSL) || defined(USE_MBEDTLS) || \
|
||||
# if (defined(USE_OPENSSL) && defined(HAVE_DES_ECB_ENCRYPT)) || \
|
||||
defined(USE_GNUTLS) || \
|
||||
(defined(USE_MBEDTLS) && defined(HAVE_MBEDTLS_DES_CRYPT_ECB)) || \
|
||||
defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO) || \
|
||||
(defined(USE_WOLFSSL) && defined(HAVE_WOLFSSL_DES_ECB_ENCRYPT))
|
||||
# define USE_CURL_NTLM_CORE
|
||||
@@ -791,7 +783,7 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(USE_LIBSSH2) || defined(USE_LIBSSH) || defined(USE_WOLFSSH)
|
||||
#if defined(USE_LIBSSH2) || defined(USE_LIBSSH)
|
||||
#define USE_SSH
|
||||
#endif
|
||||
|
||||
@@ -974,6 +966,10 @@ endings either CRLF or LF so 't' is appropriate.
|
||||
|
||||
#define CURL_ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
|
||||
|
||||
/* Buffer size for error messages retrieved via
|
||||
curlx_strerror() and Curl_sspi_strerror() */
|
||||
#define STRERROR_LEN 256
|
||||
|
||||
#ifndef CURL_DID_MEMORY_FUNC_TYPEDEFS /* only if not already done */
|
||||
/*
|
||||
* The following memory function replacement typedef's are COPIED from
|
||||
@@ -1003,6 +999,8 @@ extern curl_calloc_callback Curl_ccalloc;
|
||||
#define Curl_safefree(ptr) \
|
||||
do { free((ptr)); (ptr) = NULL;} while(0)
|
||||
|
||||
#include <curl/curl.h> /* for CURL_EXTERN, mprintf.h */
|
||||
|
||||
#ifdef CURLDEBUG
|
||||
#ifdef __clang__
|
||||
# define ALLOC_FUNC __attribute__((__malloc__))
|
||||
@@ -1027,8 +1025,6 @@ extern curl_calloc_callback Curl_ccalloc;
|
||||
# define ALLOC_SIZE2(n, s)
|
||||
#endif
|
||||
|
||||
#include <curl/curl.h> /* for CURL_EXTERN */
|
||||
|
||||
extern FILE *curl_dbg_logfile;
|
||||
|
||||
/* memory functions */
|
||||
@@ -1098,9 +1094,21 @@ CURL_EXTERN ALLOC_FUNC
|
||||
curl_dbg_getaddrinfo(host, serv, hint, res, __LINE__, __FILE__)
|
||||
#define CURL_FREEADDRINFO(data) \
|
||||
curl_dbg_freeaddrinfo(data, __LINE__, __FILE__)
|
||||
|
||||
#define CURL_SOCKET(domain,type,protocol) \
|
||||
curl_dbg_socket((int)domain, type, protocol, __LINE__, __FILE__)
|
||||
#ifdef HAVE_SOCKETPAIR
|
||||
#define CURL_SOCKETPAIR(domain,type,protocol,socket_vector) \
|
||||
curl_dbg_socketpair((int)domain, type, protocol, socket_vector, \
|
||||
__LINE__, __FILE__)
|
||||
#endif
|
||||
#define CURL_ACCEPT(sock,addr,len) \
|
||||
curl_dbg_accept(sock, addr, len, __LINE__, __FILE__)
|
||||
#ifdef HAVE_ACCEPT4
|
||||
#define CURL_ACCEPT4(sock,addr,len,flags) \
|
||||
curl_dbg_accept4(sock, addr, len, flags, __LINE__, __FILE__)
|
||||
#endif
|
||||
#define CURL_SEND(a,b,c,d) curl_dbg_send(a,b,c,d, __LINE__, __FILE__)
|
||||
#define CURL_RECV(a,b,c,d) curl_dbg_recv(a,b,c,d, __LINE__, __FILE__)
|
||||
|
||||
#else /* !CURLDEBUG */
|
||||
|
||||
@@ -1109,8 +1117,16 @@ CURL_EXTERN ALLOC_FUNC
|
||||
|
||||
#define CURL_GETADDRINFO getaddrinfo
|
||||
#define CURL_FREEADDRINFO freeaddrinfo
|
||||
|
||||
#define CURL_SOCKET socket
|
||||
#ifdef HAVE_SOCKETPAIR
|
||||
#define CURL_SOCKETPAIR socketpair
|
||||
#endif
|
||||
#define CURL_ACCEPT accept
|
||||
#ifdef HAVE_ACCEPT4
|
||||
#define CURL_ACCEPT4 accept4
|
||||
#endif
|
||||
#define CURL_SEND send
|
||||
#define CURL_RECV recv
|
||||
|
||||
#endif /* CURLDEBUG */
|
||||
|
||||
|
||||
@@ -138,7 +138,7 @@ CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp,
|
||||
}
|
||||
|
||||
/* Setup the identity's user and length */
|
||||
dup_user.tchar_ptr = _tcsdup(user.tchar_ptr);
|
||||
dup_user.tchar_ptr = Curl_tcsdup(user.tchar_ptr);
|
||||
if(!dup_user.tchar_ptr) {
|
||||
curlx_unicodefree(useranddomain.tchar_ptr);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
@@ -165,7 +165,7 @@ CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp,
|
||||
passwd.tchar_ptr = curlx_convert_UTF8_to_tchar(passwdp);
|
||||
if(!passwd.tchar_ptr)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
dup_passwd.tchar_ptr = _tcsdup(passwd.tchar_ptr);
|
||||
dup_passwd.tchar_ptr = Curl_tcsdup(passwd.tchar_ptr);
|
||||
if(!dup_passwd.tchar_ptr) {
|
||||
curlx_unicodefree(passwd.tchar_ptr);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
@@ -26,12 +26,8 @@
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#ifdef USE_THREADS_POSIX
|
||||
# ifdef HAVE_PTHREAD_H
|
||||
# include <pthread.h>
|
||||
# endif
|
||||
#elif defined(USE_THREADS_WIN32)
|
||||
# include <process.h>
|
||||
#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
#include "curl_threads.h"
|
||||
@@ -64,14 +60,18 @@ curl_thread_t Curl_thread_create(CURL_THREAD_RETURN_T
|
||||
{
|
||||
curl_thread_t t = malloc(sizeof(pthread_t));
|
||||
struct Curl_actual_call *ac = malloc(sizeof(struct Curl_actual_call));
|
||||
int rc;
|
||||
if(!(ac && t))
|
||||
goto err;
|
||||
|
||||
ac->func = func;
|
||||
ac->arg = arg;
|
||||
|
||||
if(pthread_create(t, NULL, curl_thread_create_thunk, ac) != 0)
|
||||
rc = pthread_create(t, NULL, curl_thread_create_thunk, ac);
|
||||
if(rc) {
|
||||
CURL_SETERRNO(rc);
|
||||
goto err;
|
||||
}
|
||||
|
||||
return t;
|
||||
|
||||
@@ -100,61 +100,19 @@ int Curl_thread_join(curl_thread_t *hnd)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* do not use pthread_cancel if:
|
||||
* - pthread_cancel seems to be absent
|
||||
* - on FreeBSD, as we see hangers in CI testing
|
||||
* - this is a -fsanitize=thread build
|
||||
* (clang sanitizer reports false positive when functions to not return)
|
||||
*/
|
||||
#if defined(PTHREAD_CANCEL_ENABLE) && !defined(__FreeBSD__)
|
||||
#if defined(__has_feature)
|
||||
# if !__has_feature(thread_sanitizer)
|
||||
#define USE_PTHREAD_CANCEL
|
||||
# endif
|
||||
#else /* __has_feature */
|
||||
#define USE_PTHREAD_CANCEL
|
||||
#endif /* !__has_feature */
|
||||
#endif /* PTHREAD_CANCEL_ENABLE && !__FreeBSD__ */
|
||||
|
||||
int Curl_thread_cancel(curl_thread_t *hnd)
|
||||
{
|
||||
(void)hnd;
|
||||
if(*hnd != curl_thread_t_null)
|
||||
#ifdef USE_PTHREAD_CANCEL
|
||||
return pthread_cancel(**hnd);
|
||||
#else
|
||||
return 1; /* not supported */
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#elif defined(USE_THREADS_WIN32)
|
||||
|
||||
curl_thread_t Curl_thread_create(CURL_THREAD_RETURN_T
|
||||
(CURL_STDCALL *func) (void *), void *arg)
|
||||
{
|
||||
#if defined(CURL_WINDOWS_UWP) || defined(UNDER_CE)
|
||||
typedef HANDLE curl_win_thread_handle_t;
|
||||
#else
|
||||
typedef uintptr_t curl_win_thread_handle_t;
|
||||
#endif
|
||||
curl_thread_t t;
|
||||
curl_win_thread_handle_t thread_handle;
|
||||
#if defined(CURL_WINDOWS_UWP) || defined(UNDER_CE)
|
||||
thread_handle = CreateThread(NULL, 0, func, arg, 0, NULL);
|
||||
#else
|
||||
thread_handle = _beginthreadex(NULL, 0, func, arg, 0, NULL);
|
||||
#endif
|
||||
t = (curl_thread_t)thread_handle;
|
||||
if((t == 0) || (t == LongToHandle(-1L))) {
|
||||
#ifdef UNDER_CE
|
||||
curl_thread_t t = CreateThread(NULL, 0, func, arg, 0, NULL);
|
||||
if(!t) {
|
||||
DWORD gle = GetLastError();
|
||||
/* !checksrc! disable ERRNOVAR 1 */
|
||||
int err = (gle == ERROR_ACCESS_DENIED ||
|
||||
gle == ERROR_NOT_ENOUGH_MEMORY) ?
|
||||
EACCES : EINVAL;
|
||||
CURL_SETERRNO(err);
|
||||
#endif
|
||||
return curl_thread_t_null;
|
||||
}
|
||||
return t;
|
||||
@@ -170,7 +128,7 @@ void Curl_thread_destroy(curl_thread_t *hnd)
|
||||
|
||||
int Curl_thread_join(curl_thread_t *hnd)
|
||||
{
|
||||
#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < _WIN32_WINNT_VISTA)
|
||||
#ifdef UNDER_CE
|
||||
int ret = (WaitForSingleObject(*hnd, INFINITE) == WAIT_OBJECT_0);
|
||||
#else
|
||||
int ret = (WaitForSingleObjectEx(*hnd, INFINITE, FALSE) == WAIT_OBJECT_0);
|
||||
@@ -178,16 +136,7 @@ int Curl_thread_join(curl_thread_t *hnd)
|
||||
|
||||
Curl_thread_destroy(hnd);
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int Curl_thread_cancel(curl_thread_t *hnd)
|
||||
{
|
||||
if(*hnd != curl_thread_t_null) {
|
||||
return 1; /* not supported */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* USE_THREADS_* */
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "curl_setup.h"
|
||||
|
||||
#ifdef USE_THREADS_POSIX
|
||||
# define CURL_THREAD_RETURN_T unsigned int
|
||||
# define CURL_STDCALL
|
||||
# define curl_mutex_t pthread_mutex_t
|
||||
# define curl_thread_t pthread_t *
|
||||
@@ -35,7 +36,8 @@
|
||||
# define Curl_mutex_release(m) pthread_mutex_unlock(m)
|
||||
# define Curl_mutex_destroy(m) pthread_mutex_destroy(m)
|
||||
#elif defined(USE_THREADS_WIN32)
|
||||
# define CURL_STDCALL __stdcall
|
||||
# define CURL_THREAD_RETURN_T DWORD
|
||||
# define CURL_STDCALL WINAPI
|
||||
# define curl_mutex_t CRITICAL_SECTION
|
||||
# define curl_thread_t HANDLE
|
||||
# define curl_thread_t_null (HANDLE)0
|
||||
@@ -47,14 +49,6 @@
|
||||
# define Curl_mutex_acquire(m) EnterCriticalSection(m)
|
||||
# define Curl_mutex_release(m) LeaveCriticalSection(m)
|
||||
# define Curl_mutex_destroy(m) DeleteCriticalSection(m)
|
||||
#else
|
||||
# define CURL_STDCALL
|
||||
#endif
|
||||
|
||||
#if defined(CURL_WINDOWS_UWP) || defined(UNDER_CE)
|
||||
#define CURL_THREAD_RETURN_T DWORD
|
||||
#else
|
||||
#define CURL_THREAD_RETURN_T unsigned int
|
||||
#endif
|
||||
|
||||
#if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32)
|
||||
@@ -66,22 +60,6 @@ void Curl_thread_destroy(curl_thread_t *hnd);
|
||||
|
||||
int Curl_thread_join(curl_thread_t *hnd);
|
||||
|
||||
int Curl_thread_cancel(curl_thread_t *hnd);
|
||||
|
||||
#if defined(USE_THREADS_POSIX) && defined(PTHREAD_CANCEL_ENABLE)
|
||||
#define Curl_thread_push_cleanup(a,b) pthread_cleanup_push(a,b)
|
||||
#define Curl_thread_pop_cleanup() pthread_cleanup_pop(0)
|
||||
#define Curl_thread_enable_cancel() \
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL)
|
||||
#define Curl_thread_disable_cancel() \
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL)
|
||||
#else
|
||||
#define Curl_thread_push_cleanup(a,b) ((void)a,(void)b)
|
||||
#define Curl_thread_pop_cleanup() Curl_nop_stmt
|
||||
#define Curl_thread_enable_cancel() Curl_nop_stmt
|
||||
#define Curl_thread_disable_cancel() Curl_nop_stmt
|
||||
#endif
|
||||
|
||||
#endif /* USE_THREADS_POSIX || USE_THREADS_WIN32 */
|
||||
|
||||
#endif /* HEADER_CURL_THREADS_H */
|
||||
|
||||
@@ -47,8 +47,7 @@
|
||||
#include "vtls/vtls.h"
|
||||
#include "vquic/vquic.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
@@ -102,14 +101,14 @@ static size_t trc_print_ids(struct Curl_easy *data, char *buf, size_t maxlen)
|
||||
data->conn->connection_id : data->state.recent_conn_id;
|
||||
if(data->id >= 0) {
|
||||
if(cid >= 0)
|
||||
return msnprintf(buf, maxlen, CURL_TRC_FMT_IDSDC, data->id, cid);
|
||||
return curl_msnprintf(buf, maxlen, CURL_TRC_FMT_IDSDC, data->id, cid);
|
||||
else
|
||||
return msnprintf(buf, maxlen, CURL_TRC_FMT_IDSD, data->id);
|
||||
return curl_msnprintf(buf, maxlen, CURL_TRC_FMT_IDSD, data->id);
|
||||
}
|
||||
else if(cid >= 0)
|
||||
return msnprintf(buf, maxlen, CURL_TRC_FMT_IDSC, cid);
|
||||
return curl_msnprintf(buf, maxlen, CURL_TRC_FMT_IDSC, cid);
|
||||
else {
|
||||
return msnprintf(buf, maxlen, "[x-x] ");
|
||||
return curl_msnprintf(buf, maxlen, "[x-x] ");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,8 +142,8 @@ void Curl_debug(struct Curl_easy *data, curl_infotype type,
|
||||
|
||||
if(CURL_TRC_IDS(data) && (size < TRC_LINE_MAX)) {
|
||||
len = trc_print_ids(data, buf, TRC_LINE_MAX);
|
||||
len += msnprintf(buf + len, TRC_LINE_MAX - len, "%.*s",
|
||||
(int)size, ptr);
|
||||
len += curl_msnprintf(buf + len, TRC_LINE_MAX - len, "%.*s",
|
||||
(int)size, ptr);
|
||||
len = trc_end_buf(buf, len, TRC_LINE_MAX, FALSE);
|
||||
Curl_set_in_callback(data, TRUE);
|
||||
(void)(*data->set.fdebug)(data, type, buf, len, data->set.debugdata);
|
||||
@@ -189,7 +188,7 @@ void Curl_failf(struct Curl_easy *data, const char *fmt, ...)
|
||||
size_t len;
|
||||
char error[CURL_ERROR_SIZE + 2];
|
||||
va_start(ap, fmt);
|
||||
len = mvsnprintf(error, CURL_ERROR_SIZE, fmt, ap);
|
||||
len = curl_mvsnprintf(error, CURL_ERROR_SIZE, fmt, ap);
|
||||
|
||||
if(data->set.errorbuffer && !data->state.errorbuf) {
|
||||
strcpy(data->set.errorbuffer, error);
|
||||
@@ -220,15 +219,15 @@ static void trc_infof(struct Curl_easy *data,
|
||||
if(CURL_TRC_IDS(data))
|
||||
len += trc_print_ids(data, buf + len, TRC_LINE_MAX - len);
|
||||
if(feat)
|
||||
len += msnprintf(buf + len, TRC_LINE_MAX - len, "[%s] ", feat->name);
|
||||
len += curl_msnprintf(buf + len, TRC_LINE_MAX - len, "[%s] ", feat->name);
|
||||
if(opt_id) {
|
||||
if(opt_id_idx > 0)
|
||||
len += msnprintf(buf + len, TRC_LINE_MAX - len, "[%s-%d] ",
|
||||
opt_id, opt_id_idx);
|
||||
len += curl_msnprintf(buf + len, TRC_LINE_MAX - len, "[%s-%d] ",
|
||||
opt_id, opt_id_idx);
|
||||
else
|
||||
len += msnprintf(buf + len, TRC_LINE_MAX - len, "[%s] ", opt_id);
|
||||
len += curl_msnprintf(buf + len, TRC_LINE_MAX - len, "[%s] ", opt_id);
|
||||
}
|
||||
len += mvsnprintf(buf + len, TRC_LINE_MAX - len, fmt, ap);
|
||||
len += curl_mvsnprintf(buf + len, TRC_LINE_MAX - len, fmt, ap);
|
||||
len = trc_end_buf(buf, len, TRC_LINE_MAX, TRUE);
|
||||
trc_write(data, CURLINFO_TEXT, buf, len);
|
||||
}
|
||||
@@ -272,6 +271,10 @@ struct curl_trc_feat Curl_trc_feat_dns = {
|
||||
"DNS",
|
||||
CURL_LOG_LVL_NONE,
|
||||
};
|
||||
struct curl_trc_feat Curl_trc_feat_timer = {
|
||||
"TIMER",
|
||||
CURL_LOG_LVL_NONE,
|
||||
};
|
||||
|
||||
static const char * const Curl_trc_timer_names[]={
|
||||
"100_TIMEOUT",
|
||||
@@ -291,24 +294,37 @@ static const char * const Curl_trc_timer_names[]={
|
||||
"SHUTDOWN",
|
||||
};
|
||||
|
||||
const char *Curl_trc_timer_name(int tid)
|
||||
static const char *trc_timer_name(int tid)
|
||||
{
|
||||
if((tid >= 0) && ((size_t)tid < CURL_ARRAYSIZE(Curl_trc_timer_names)))
|
||||
return Curl_trc_timer_names[(size_t)tid];
|
||||
return "UNKNOWN?";
|
||||
}
|
||||
|
||||
void Curl_trc_multi_timeouts(struct Curl_easy *data)
|
||||
void Curl_trc_timer(struct Curl_easy *data, int tid, const char *fmt, ...)
|
||||
{
|
||||
struct Curl_llist_node *e = Curl_llist_head(&data->state.timeoutlist);
|
||||
if(e) {
|
||||
struct curltime now = curlx_now();
|
||||
while(e) {
|
||||
struct time_node *n = Curl_node_elem(e);
|
||||
e = Curl_node_next(e);
|
||||
CURL_TRC_M(data, "[TIMEOUT] %s expires in %" FMT_TIMEDIFF_T "ns",
|
||||
CURL_TIMER_NAME(n->eid),
|
||||
curlx_timediff_us(n->time, now));
|
||||
DEBUGASSERT(!strchr(fmt, '\n'));
|
||||
if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_timer)) {
|
||||
const char *tname = trc_timer_name(tid);
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
trc_infof(data, &Curl_trc_feat_timer, tname, 0, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
|
||||
void Curl_trc_easy_timers(struct Curl_easy *data)
|
||||
{
|
||||
if(CURL_TRC_TIMER_is_verbose(data)) {
|
||||
struct Curl_llist_node *e = Curl_llist_head(&data->state.timeoutlist);
|
||||
if(e) {
|
||||
struct curltime now = curlx_now();
|
||||
while(e) {
|
||||
struct time_node *n = Curl_node_elem(e);
|
||||
e = Curl_node_next(e);
|
||||
CURL_TRC_TIMER(data, n->eid, "expires in %" FMT_TIMEDIFF_T "ns",
|
||||
curlx_timediff_us(n->time, now));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -476,6 +492,7 @@ static struct trc_feat_def trc_feats[] = {
|
||||
{ &Curl_trc_feat_read, TRC_CT_NONE },
|
||||
{ &Curl_trc_feat_write, TRC_CT_NONE },
|
||||
{ &Curl_trc_feat_dns, TRC_CT_NETWORK },
|
||||
{ &Curl_trc_feat_timer, TRC_CT_NETWORK },
|
||||
#ifndef CURL_DISABLE_FTP
|
||||
{ &Curl_trc_feat_ftp, TRC_CT_PROTOCOL },
|
||||
#endif
|
||||
@@ -640,8 +657,6 @@ void Curl_trc_cf_infof(struct Curl_easy *data, const struct Curl_cfilter *cf,
|
||||
(void)data; (void)cf; (void)fmt;
|
||||
}
|
||||
|
||||
struct curl_trc_feat;
|
||||
|
||||
void Curl_trc_multi(struct Curl_easy *data, const char *fmt, ...)
|
||||
{
|
||||
(void)data; (void)fmt;
|
||||
@@ -657,6 +672,11 @@ void Curl_trc_dns(struct Curl_easy *data, const char *fmt, ...)
|
||||
(void)data; (void)fmt;
|
||||
}
|
||||
|
||||
void Curl_trc_timer(struct Curl_easy *data, int tid, const char *fmt, ...)
|
||||
{
|
||||
(void)data; (void)tid; (void)fmt;
|
||||
}
|
||||
|
||||
void Curl_trc_read(struct Curl_easy *data, const char *fmt, ...)
|
||||
{
|
||||
(void)data; (void)fmt;
|
||||
|
||||
@@ -86,7 +86,7 @@ void Curl_trc_multi(struct Curl_easy *data,
|
||||
const char *fmt, ...) CURL_PRINTF(2, 3);
|
||||
const char *Curl_trc_mstate_name(int state);
|
||||
const char *Curl_trc_timer_name(int tid);
|
||||
void Curl_trc_multi_timeouts(struct Curl_easy *data);
|
||||
void Curl_trc_easy_timers(struct Curl_easy *data);
|
||||
|
||||
void Curl_trc_write(struct Curl_easy *data,
|
||||
const char *fmt, ...) CURL_PRINTF(2, 3);
|
||||
@@ -94,6 +94,13 @@ void Curl_trc_read(struct Curl_easy *data,
|
||||
const char *fmt, ...) CURL_PRINTF(2, 3);
|
||||
void Curl_trc_dns(struct Curl_easy *data,
|
||||
const char *fmt, ...) CURL_PRINTF(2, 3);
|
||||
void Curl_trc_timer(struct Curl_easy *data, int tid,
|
||||
const char *fmt, ...) CURL_PRINTF(3, 4);
|
||||
|
||||
struct curl_trc_feat {
|
||||
const char *name;
|
||||
int log_level;
|
||||
};
|
||||
|
||||
#ifndef CURL_DISABLE_FTP
|
||||
extern struct curl_trc_feat Curl_trc_feat_ftp;
|
||||
@@ -118,6 +125,10 @@ void Curl_trc_ws(struct Curl_easy *data,
|
||||
|
||||
#define CURL_TRC_M_is_verbose(data) \
|
||||
Curl_trc_ft_is_verbose(data, &Curl_trc_feat_multi)
|
||||
#define CURL_TRC_DNS_is_verbose(data) \
|
||||
Curl_trc_ft_is_verbose(data, &Curl_trc_feat_dns)
|
||||
#define CURL_TRC_TIMER_is_verbose(data) \
|
||||
Curl_trc_ft_is_verbose(data, &Curl_trc_feat_timer)
|
||||
|
||||
#if defined(CURL_HAVE_C99) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||
#define infof(data, ...) \
|
||||
@@ -136,8 +147,11 @@ void Curl_trc_ws(struct Curl_easy *data,
|
||||
do { if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_read)) \
|
||||
Curl_trc_read(data, __VA_ARGS__); } while(0)
|
||||
#define CURL_TRC_DNS(data, ...) \
|
||||
do { if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_dns)) \
|
||||
do { if(CURL_TRC_DNS_is_verbose(data)) \
|
||||
Curl_trc_dns(data, __VA_ARGS__); } while(0)
|
||||
#define CURL_TRC_TIMER(data, tid, ...) \
|
||||
do { if(CURL_TRC_TIMER_is_verbose(data)) \
|
||||
Curl_trc_timer(data, tid, __VA_ARGS__); } while(0)
|
||||
|
||||
#ifndef CURL_DISABLE_FTP
|
||||
#define CURL_TRC_FTP(data, ...) \
|
||||
@@ -168,6 +182,7 @@ void Curl_trc_ws(struct Curl_easy *data,
|
||||
#define CURL_TRC_WRITE Curl_trc_write
|
||||
#define CURL_TRC_READ Curl_trc_read
|
||||
#define CURL_TRC_DNS Curl_trc_dns
|
||||
#define CURL_TRC_TIMER Curl_trc_timer
|
||||
|
||||
#ifndef CURL_DISABLE_FTP
|
||||
#define CURL_TRC_FTP Curl_trc_ftp
|
||||
@@ -184,11 +199,6 @@ void Curl_trc_ws(struct Curl_easy *data,
|
||||
|
||||
#endif /* !CURL_HAVE_C99 */
|
||||
|
||||
struct curl_trc_feat {
|
||||
const char *name;
|
||||
int log_level;
|
||||
};
|
||||
|
||||
#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
||||
/* informational messages enabled */
|
||||
|
||||
@@ -196,6 +206,7 @@ extern struct curl_trc_feat Curl_trc_feat_multi;
|
||||
extern struct curl_trc_feat Curl_trc_feat_read;
|
||||
extern struct curl_trc_feat Curl_trc_feat_write;
|
||||
extern struct curl_trc_feat Curl_trc_feat_dns;
|
||||
extern struct curl_trc_feat Curl_trc_feat_timer;
|
||||
|
||||
#define Curl_trc_is_verbose(data) \
|
||||
((data) && (data)->set.verbose && \
|
||||
@@ -208,10 +219,9 @@ extern struct curl_trc_feat Curl_trc_feat_dns;
|
||||
(Curl_trc_is_verbose(data) && \
|
||||
(ft)->log_level >= CURL_LOG_LVL_INFO)
|
||||
#define CURL_MSTATE_NAME(s) Curl_trc_mstate_name((int)(s))
|
||||
#define CURL_TIMER_NAME(t) Curl_trc_timer_name((int)(t))
|
||||
#define CURL_TRC_M_TIMEOUTS(data) \
|
||||
do { if(CURL_TRC_M_is_verbose(data)) \
|
||||
Curl_trc_multi_timeouts(data); } while(0)
|
||||
#define CURL_TRC_EASY_TIMERS(data) \
|
||||
do { if(CURL_TRC_TIMER_is_verbose(data)) \
|
||||
Curl_trc_easy_timers(data); } while(0)
|
||||
|
||||
#else /* CURL_DISABLE_VERBOSE_STRINGS */
|
||||
/* All informational messages are not compiled in for size savings */
|
||||
@@ -220,8 +230,7 @@ extern struct curl_trc_feat Curl_trc_feat_dns;
|
||||
#define Curl_trc_cf_is_verbose(x,y) (FALSE)
|
||||
#define Curl_trc_ft_is_verbose(x,y) (FALSE)
|
||||
#define CURL_MSTATE_NAME(x) ((void)(x), "-")
|
||||
#define CURL_TIMER_NAME(x) ((void)(x), "-")
|
||||
#define CURL_TRC_M_TIMEOUTS(x) Curl_nop_stmt
|
||||
#define CURL_TRC_EASY_TIMERS(x) Curl_nop_stmt
|
||||
|
||||
#endif /* !CURL_DISABLE_VERBOSE_STRINGS */
|
||||
|
||||
|
||||
@@ -182,12 +182,12 @@ static CURLcode base64_encode(const char *table64,
|
||||
*outlen = 0;
|
||||
|
||||
if(!insize)
|
||||
insize = strlen(inputbuff);
|
||||
return CURLE_OK;
|
||||
|
||||
#if SIZEOF_SIZE_T == 4
|
||||
if(insize > UINT_MAX/4)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
#endif
|
||||
/* safety precaution */
|
||||
DEBUGASSERT(insize <= CURL_MAX_BASE64_INPUT);
|
||||
if(insize > CURL_MAX_BASE64_INPUT)
|
||||
return CURLE_TOO_LARGE;
|
||||
|
||||
base64data = output = malloc((insize + 2) / 3 * 4 + 1);
|
||||
if(!output)
|
||||
@@ -240,8 +240,6 @@ static CURLcode base64_encode(const char *table64,
|
||||
* encoded data. Size of encoded data is returned in variable pointed by
|
||||
* outlen.
|
||||
*
|
||||
* Input length of 0 indicates input buffer holds a null-terminated string.
|
||||
*
|
||||
* Returns CURLE_OK on success, otherwise specific error code. Function
|
||||
* output shall not be considered valid unless CURLE_OK is returned.
|
||||
*
|
||||
|
||||
@@ -33,4 +33,8 @@ CURLcode curlx_base64_decode(const char *src,
|
||||
|
||||
extern const char Curl_base64encdec[];
|
||||
|
||||
/* maximum input length acceptable to base64 encode, here to catch and prevent
|
||||
mistakes */
|
||||
#define CURL_MAX_BASE64_INPUT 16000000
|
||||
|
||||
#endif /* HEADER_CURL_BASE64_H */
|
||||
|
||||
@@ -58,12 +58,18 @@
|
||||
#include "version_win32.h"
|
||||
/* provides curlx_verify_windows_version() */
|
||||
|
||||
#include "strerr.h"
|
||||
/* The curlx_strerror() function */
|
||||
|
||||
#include "strparse.h"
|
||||
/* The curlx_str_* parsing functions */
|
||||
|
||||
#include "dynbuf.h"
|
||||
/* The curlx_dyn_* functions */
|
||||
|
||||
#include "fopen.h"
|
||||
/* The curlx_f* functions */
|
||||
|
||||
#include "base64.h"
|
||||
#include "timeval.h"
|
||||
#include "timediff.h"
|
||||
|
||||
@@ -0,0 +1,324 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute 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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
* This file is 'mem-include-scan' clean, which means its memory allocations
|
||||
* are not tracked by the curl memory tracker memdebug, so they must not use
|
||||
* `CURLDEBUG` macro replacements in memdebug.h for free, malloc, etc. To avoid
|
||||
* these macro replacements, wrap the names in parentheses to call the original
|
||||
* versions: `ptr = (malloc)(123)`, `(free)(ptr)`, etc.
|
||||
*/
|
||||
|
||||
#include "../curl_setup.h"
|
||||
|
||||
#include "fopen.h"
|
||||
|
||||
int curlx_fseek(void *stream, curl_off_t offset, int whence)
|
||||
{
|
||||
#if defined(_WIN32) && defined(USE_WIN32_LARGE_FILES)
|
||||
return _fseeki64(stream, (__int64)offset, whence);
|
||||
#elif defined(HAVE_FSEEKO) && defined(HAVE_DECL_FSEEKO)
|
||||
return fseeko(stream, (off_t)offset, whence);
|
||||
#else
|
||||
if(offset > LONG_MAX)
|
||||
return -1;
|
||||
return fseek(stream, (long)offset, whence);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(_WIN32) && !defined(UNDER_CE)
|
||||
|
||||
#include "multibyte.h"
|
||||
|
||||
/* declare GetFullPathNameW for mingw-w64 UWP builds targeting old windows */
|
||||
#if defined(CURL_WINDOWS_UWP) && defined(__MINGW32__) && \
|
||||
(_WIN32_WINNT < _WIN32_WINNT_WIN10)
|
||||
WINBASEAPI DWORD WINAPI GetFullPathNameW(LPCWSTR, DWORD, LPWSTR, LPWSTR *);
|
||||
#endif
|
||||
|
||||
/* Fix excessive paths (paths that exceed MAX_PATH length of 260).
|
||||
*
|
||||
* This is a helper function to fix paths that would exceed the MAX_PATH
|
||||
* limitation check done by Windows APIs. It does so by normalizing the passed
|
||||
* in filename or path 'in' to its full canonical path, and if that path is
|
||||
* longer than MAX_PATH then setting 'out' to "\\?\" prefix + that full path.
|
||||
*
|
||||
* For example 'in' filename255chars in current directory C:\foo\bar is
|
||||
* fixed as \\?\C:\foo\bar\filename255chars for 'out' which will tell Windows
|
||||
* it is ok to access that filename even though the actual full path is longer
|
||||
* than 260 chars.
|
||||
*
|
||||
* For non-Unicode builds this function may fail sometimes because only the
|
||||
* Unicode versions of some Windows API functions can access paths longer than
|
||||
* MAX_PATH, for example GetFullPathNameW which is used in this function. When
|
||||
* the full path is then converted from Unicode to multibyte that fails if any
|
||||
* directories in the path contain characters not in the current codepage.
|
||||
*/
|
||||
static bool fix_excessive_path(const TCHAR *in, TCHAR **out)
|
||||
{
|
||||
size_t needed, count;
|
||||
const wchar_t *in_w;
|
||||
wchar_t *fbuf = NULL;
|
||||
|
||||
/* MS documented "approximate" limit for the maximum path length */
|
||||
const size_t max_path_len = 32767;
|
||||
|
||||
#ifndef _UNICODE
|
||||
wchar_t *ibuf = NULL;
|
||||
char *obuf = NULL;
|
||||
#endif
|
||||
|
||||
*out = NULL;
|
||||
|
||||
/* skip paths already normalized */
|
||||
if(!_tcsncmp(in, _T("\\\\?\\"), 4))
|
||||
goto cleanup;
|
||||
|
||||
#ifndef _UNICODE
|
||||
/* convert multibyte input to unicode */
|
||||
needed = mbstowcs(NULL, in, 0);
|
||||
if(needed == (size_t)-1 || needed >= max_path_len)
|
||||
goto cleanup;
|
||||
++needed; /* for NUL */
|
||||
ibuf = (malloc)(needed * sizeof(wchar_t));
|
||||
if(!ibuf)
|
||||
goto cleanup;
|
||||
count = mbstowcs(ibuf, in, needed);
|
||||
if(count == (size_t)-1 || count >= needed)
|
||||
goto cleanup;
|
||||
in_w = ibuf;
|
||||
#else
|
||||
in_w = in;
|
||||
#endif
|
||||
|
||||
/* GetFullPathNameW returns the normalized full path in unicode. It converts
|
||||
forward slashes to backslashes, processes .. to remove directory segments,
|
||||
etc. Unlike GetFullPathNameA it can process paths that exceed MAX_PATH. */
|
||||
needed = (size_t)GetFullPathNameW(in_w, 0, NULL, NULL);
|
||||
if(!needed || needed > max_path_len)
|
||||
goto cleanup;
|
||||
/* skip paths that are not excessive and do not need modification */
|
||||
if(needed <= MAX_PATH)
|
||||
goto cleanup;
|
||||
fbuf = (malloc)(needed * sizeof(wchar_t));
|
||||
if(!fbuf)
|
||||
goto cleanup;
|
||||
count = (size_t)GetFullPathNameW(in_w, (DWORD)needed, fbuf, NULL);
|
||||
if(!count || count >= needed)
|
||||
goto cleanup;
|
||||
|
||||
/* prepend \\?\ or \\?\UNC\ to the excessively long path.
|
||||
*
|
||||
* c:\longpath ---> \\?\c:\longpath
|
||||
* \\.\c:\longpath ---> \\?\c:\longpath
|
||||
* \\?\c:\longpath ---> \\?\c:\longpath (unchanged)
|
||||
* \\server\c$\longpath ---> \\?\UNC\server\c$\longpath
|
||||
*
|
||||
* https://learn.microsoft.com/dotnet/standard/io/file-path-formats
|
||||
*/
|
||||
if(!wcsncmp(fbuf, L"\\\\?\\", 4))
|
||||
; /* do nothing */
|
||||
else if(!wcsncmp(fbuf, L"\\\\.\\", 4))
|
||||
fbuf[2] = '?';
|
||||
else if(!wcsncmp(fbuf, L"\\\\.", 3) || !wcsncmp(fbuf, L"\\\\?", 3)) {
|
||||
/* Unexpected, not UNC. The formatting doc doesn't allow this AFAICT. */
|
||||
goto cleanup;
|
||||
}
|
||||
else {
|
||||
wchar_t *temp;
|
||||
|
||||
if(!wcsncmp(fbuf, L"\\\\", 2)) {
|
||||
/* "\\?\UNC\" + full path without "\\" + null */
|
||||
needed = 8 + (count - 2) + 1;
|
||||
if(needed > max_path_len)
|
||||
goto cleanup;
|
||||
|
||||
temp = (malloc)(needed * sizeof(wchar_t));
|
||||
if(!temp)
|
||||
goto cleanup;
|
||||
|
||||
wcsncpy(temp, L"\\\\?\\UNC\\", 8);
|
||||
wcscpy(temp + 8, fbuf + 2);
|
||||
}
|
||||
else {
|
||||
/* "\\?\" + full path + null */
|
||||
needed = 4 + count + 1;
|
||||
if(needed > max_path_len)
|
||||
goto cleanup;
|
||||
|
||||
temp = (malloc)(needed * sizeof(wchar_t));
|
||||
if(!temp)
|
||||
goto cleanup;
|
||||
|
||||
wcsncpy(temp, L"\\\\?\\", 4);
|
||||
wcscpy(temp + 4, fbuf);
|
||||
}
|
||||
|
||||
(free)(fbuf);
|
||||
fbuf = temp;
|
||||
}
|
||||
|
||||
#ifndef _UNICODE
|
||||
/* convert unicode full path to multibyte output */
|
||||
needed = wcstombs(NULL, fbuf, 0);
|
||||
if(needed == (size_t)-1 || needed >= max_path_len)
|
||||
goto cleanup;
|
||||
++needed; /* for NUL */
|
||||
obuf = (malloc)(needed);
|
||||
if(!obuf)
|
||||
goto cleanup;
|
||||
count = wcstombs(obuf, fbuf, needed);
|
||||
if(count == (size_t)-1 || count >= needed)
|
||||
goto cleanup;
|
||||
*out = obuf;
|
||||
obuf = NULL;
|
||||
#else
|
||||
*out = fbuf;
|
||||
fbuf = NULL;
|
||||
#endif
|
||||
|
||||
cleanup:
|
||||
(free)(fbuf);
|
||||
#ifndef _UNICODE
|
||||
(free)(ibuf);
|
||||
(free)(obuf);
|
||||
#endif
|
||||
return *out ? true : false;
|
||||
}
|
||||
|
||||
int curlx_win32_open(const char *filename, int oflag, ...)
|
||||
{
|
||||
int pmode = 0;
|
||||
int result = -1;
|
||||
TCHAR *fixed = NULL;
|
||||
const TCHAR *target = NULL;
|
||||
|
||||
#ifdef _UNICODE
|
||||
wchar_t *filename_w = curlx_convert_UTF8_to_wchar(filename);
|
||||
#endif
|
||||
|
||||
va_list param;
|
||||
va_start(param, oflag);
|
||||
if(oflag & O_CREAT)
|
||||
pmode = va_arg(param, int);
|
||||
va_end(param);
|
||||
|
||||
#ifdef _UNICODE
|
||||
if(filename_w) {
|
||||
if(fix_excessive_path(filename_w, &fixed))
|
||||
target = fixed;
|
||||
else
|
||||
target = filename_w;
|
||||
result = _wopen(target, oflag, pmode);
|
||||
curlx_unicodefree(filename_w);
|
||||
}
|
||||
else
|
||||
/* !checksrc! disable ERRNOVAR 1 */
|
||||
CURL_SETERRNO(EINVAL);
|
||||
#else
|
||||
if(fix_excessive_path(filename, &fixed))
|
||||
target = fixed;
|
||||
else
|
||||
target = filename;
|
||||
result = _open(target, oflag, pmode);
|
||||
#endif
|
||||
|
||||
(free)(fixed);
|
||||
return result;
|
||||
}
|
||||
|
||||
FILE *curlx_win32_fopen(const char *filename, const char *mode)
|
||||
{
|
||||
FILE *result = NULL;
|
||||
TCHAR *fixed = NULL;
|
||||
const TCHAR *target = NULL;
|
||||
|
||||
#ifdef _UNICODE
|
||||
wchar_t *filename_w = curlx_convert_UTF8_to_wchar(filename);
|
||||
wchar_t *mode_w = curlx_convert_UTF8_to_wchar(mode);
|
||||
if(filename_w && mode_w) {
|
||||
if(fix_excessive_path(filename_w, &fixed))
|
||||
target = fixed;
|
||||
else
|
||||
target = filename_w;
|
||||
result = _wfopen(target, mode_w);
|
||||
}
|
||||
else
|
||||
/* !checksrc! disable ERRNOVAR 1 */
|
||||
CURL_SETERRNO(EINVAL);
|
||||
curlx_unicodefree(filename_w);
|
||||
curlx_unicodefree(mode_w);
|
||||
#else
|
||||
if(fix_excessive_path(filename, &fixed))
|
||||
target = fixed;
|
||||
else
|
||||
target = filename;
|
||||
/* !checksrc! disable BANNEDFUNC 1 */
|
||||
result = fopen(target, mode);
|
||||
#endif
|
||||
|
||||
(free)(fixed);
|
||||
return result;
|
||||
}
|
||||
|
||||
int curlx_win32_stat(const char *path, struct_stat *buffer)
|
||||
{
|
||||
int result = -1;
|
||||
TCHAR *fixed = NULL;
|
||||
const TCHAR *target = NULL;
|
||||
|
||||
#ifdef _UNICODE
|
||||
wchar_t *path_w = curlx_convert_UTF8_to_wchar(path);
|
||||
if(path_w) {
|
||||
if(fix_excessive_path(path_w, &fixed))
|
||||
target = fixed;
|
||||
else
|
||||
target = path_w;
|
||||
#ifndef USE_WIN32_LARGE_FILES
|
||||
result = _wstat(target, buffer);
|
||||
#else
|
||||
result = _wstati64(target, buffer);
|
||||
#endif
|
||||
curlx_unicodefree(path_w);
|
||||
}
|
||||
else
|
||||
/* !checksrc! disable ERRNOVAR 1 */
|
||||
CURL_SETERRNO(EINVAL);
|
||||
#else
|
||||
if(fix_excessive_path(path, &fixed))
|
||||
target = fixed;
|
||||
else
|
||||
target = path;
|
||||
#ifndef USE_WIN32_LARGE_FILES
|
||||
result = _stat(target, buffer);
|
||||
#else
|
||||
result = _stati64(target, buffer);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
(free)(fixed);
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* _WIN32 && !UNDER_CE */
|
||||
@@ -0,0 +1,60 @@
|
||||
#ifndef HEADER_CURLX_FOPEN_H
|
||||
#define HEADER_CURLX_FOPEN_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute 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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "../curl_setup.h"
|
||||
|
||||
#include "multibyte.h"
|
||||
|
||||
#ifdef HAVE_FCNTL_H
|
||||
#include <fcntl.h> /* for open() and attributes */
|
||||
#endif
|
||||
|
||||
int curlx_fseek(void *stream, curl_off_t offset, int whence);
|
||||
|
||||
#if defined(_WIN32) && !defined(UNDER_CE)
|
||||
FILE *curlx_win32_fopen(const char *filename, const char *mode);
|
||||
int curlx_win32_stat(const char *path, struct_stat *buffer);
|
||||
int curlx_win32_open(const char *filename, int oflag, ...);
|
||||
#define CURLX_FOPEN_LOW(fname, mode) curlx_win32_fopen(fname, mode)
|
||||
#define curlx_stat(fname, stp) curlx_win32_stat(fname, stp)
|
||||
#define curlx_open curlx_win32_open
|
||||
#else
|
||||
#define CURLX_FOPEN_LOW fopen
|
||||
#define curlx_stat(fname, stp) stat(fname, stp)
|
||||
#define curlx_open open
|
||||
#endif
|
||||
|
||||
#ifdef CURLDEBUG
|
||||
#define curlx_fopen(file,mode) curl_dbg_fopen(file,mode,__LINE__,__FILE__)
|
||||
#define curlx_fdopen(file,mode) curl_dbg_fdopen(file,mode,__LINE__,__FILE__)
|
||||
#define curlx_fclose(file) curl_dbg_fclose(file,__LINE__,__FILE__)
|
||||
#else
|
||||
#define curlx_fopen CURLX_FOPEN_LOW
|
||||
#define curlx_fdopen fdopen
|
||||
#define curlx_fclose fclose
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURLX_FOPEN_H */
|
||||
@@ -16,9 +16,6 @@
|
||||
*
|
||||
* SPDX-License-Identifier: ISC
|
||||
*/
|
||||
/*
|
||||
* Original code by Paul Vixie. "curlified" by Gisle Vanem.
|
||||
*/
|
||||
|
||||
#include "../curl_setup.h"
|
||||
|
||||
|
||||
@@ -84,277 +84,4 @@ char *curlx_convert_wchar_to_UTF8(const wchar_t *str_w)
|
||||
return str_utf8;
|
||||
}
|
||||
|
||||
#ifndef UNDER_CE
|
||||
|
||||
/* declare GetFullPathNameW for mingw-w64 UWP builds targeting old windows */
|
||||
#if defined(CURL_WINDOWS_UWP) && defined(__MINGW32__) && \
|
||||
(_WIN32_WINNT < _WIN32_WINNT_WIN10)
|
||||
WINBASEAPI DWORD WINAPI GetFullPathNameW(LPCWSTR, DWORD, LPWSTR, LPWSTR *);
|
||||
#endif
|
||||
|
||||
/* Fix excessive paths (paths that exceed MAX_PATH length of 260).
|
||||
*
|
||||
* This is a helper function to fix paths that would exceed the MAX_PATH
|
||||
* limitation check done by Windows APIs. It does so by normalizing the passed
|
||||
* in filename or path 'in' to its full canonical path, and if that path is
|
||||
* longer than MAX_PATH then setting 'out' to "\\?\" prefix + that full path.
|
||||
*
|
||||
* For example 'in' filename255chars in current directory C:\foo\bar is
|
||||
* fixed as \\?\C:\foo\bar\filename255chars for 'out' which will tell Windows
|
||||
* it is ok to access that filename even though the actual full path is longer
|
||||
* than 260 chars.
|
||||
*
|
||||
* For non-Unicode builds this function may fail sometimes because only the
|
||||
* Unicode versions of some Windows API functions can access paths longer than
|
||||
* MAX_PATH, for example GetFullPathNameW which is used in this function. When
|
||||
* the full path is then converted from Unicode to multibyte that fails if any
|
||||
* directories in the path contain characters not in the current codepage.
|
||||
*/
|
||||
static bool fix_excessive_path(const TCHAR *in, TCHAR **out)
|
||||
{
|
||||
size_t needed, count;
|
||||
const wchar_t *in_w;
|
||||
wchar_t *fbuf = NULL;
|
||||
|
||||
/* MS documented "approximate" limit for the maximum path length */
|
||||
const size_t max_path_len = 32767;
|
||||
|
||||
#ifndef _UNICODE
|
||||
wchar_t *ibuf = NULL;
|
||||
char *obuf = NULL;
|
||||
#endif
|
||||
|
||||
*out = NULL;
|
||||
|
||||
/* skip paths already normalized */
|
||||
if(!_tcsncmp(in, _T("\\\\?\\"), 4))
|
||||
goto cleanup;
|
||||
|
||||
#ifndef _UNICODE
|
||||
/* convert multibyte input to unicode */
|
||||
needed = mbstowcs(NULL, in, 0);
|
||||
if(needed == (size_t)-1 || needed >= max_path_len)
|
||||
goto cleanup;
|
||||
++needed; /* for NUL */
|
||||
ibuf = (malloc)(needed * sizeof(wchar_t));
|
||||
if(!ibuf)
|
||||
goto cleanup;
|
||||
count = mbstowcs(ibuf, in, needed);
|
||||
if(count == (size_t)-1 || count >= needed)
|
||||
goto cleanup;
|
||||
in_w = ibuf;
|
||||
#else
|
||||
in_w = in;
|
||||
#endif
|
||||
|
||||
/* GetFullPathNameW returns the normalized full path in unicode. It converts
|
||||
forward slashes to backslashes, processes .. to remove directory segments,
|
||||
etc. Unlike GetFullPathNameA it can process paths that exceed MAX_PATH. */
|
||||
needed = (size_t)GetFullPathNameW(in_w, 0, NULL, NULL);
|
||||
if(!needed || needed > max_path_len)
|
||||
goto cleanup;
|
||||
/* skip paths that are not excessive and do not need modification */
|
||||
if(needed <= MAX_PATH)
|
||||
goto cleanup;
|
||||
fbuf = (malloc)(needed * sizeof(wchar_t));
|
||||
if(!fbuf)
|
||||
goto cleanup;
|
||||
count = (size_t)GetFullPathNameW(in_w, (DWORD)needed, fbuf, NULL);
|
||||
if(!count || count >= needed)
|
||||
goto cleanup;
|
||||
|
||||
/* prepend \\?\ or \\?\UNC\ to the excessively long path.
|
||||
*
|
||||
* c:\longpath ---> \\?\c:\longpath
|
||||
* \\.\c:\longpath ---> \\?\c:\longpath
|
||||
* \\?\c:\longpath ---> \\?\c:\longpath (unchanged)
|
||||
* \\server\c$\longpath ---> \\?\UNC\server\c$\longpath
|
||||
*
|
||||
* https://learn.microsoft.com/en-us/dotnet/standard/io/file-path-formats
|
||||
*/
|
||||
if(!wcsncmp(fbuf, L"\\\\?\\", 4))
|
||||
; /* do nothing */
|
||||
else if(!wcsncmp(fbuf, L"\\\\.\\", 4))
|
||||
fbuf[2] = '?';
|
||||
else if(!wcsncmp(fbuf, L"\\\\.", 3) || !wcsncmp(fbuf, L"\\\\?", 3)) {
|
||||
/* Unexpected, not UNC. The formatting doc doesn't allow this AFAICT. */
|
||||
goto cleanup;
|
||||
}
|
||||
else {
|
||||
wchar_t *temp;
|
||||
|
||||
if(!wcsncmp(fbuf, L"\\\\", 2)) {
|
||||
/* "\\?\UNC\" + full path without "\\" + null */
|
||||
needed = 8 + (count - 2) + 1;
|
||||
if(needed > max_path_len)
|
||||
goto cleanup;
|
||||
|
||||
temp = (malloc)(needed * sizeof(wchar_t));
|
||||
if(!temp)
|
||||
goto cleanup;
|
||||
|
||||
wcsncpy(temp, L"\\\\?\\UNC\\", 8);
|
||||
wcscpy(temp + 8, fbuf + 2);
|
||||
}
|
||||
else {
|
||||
/* "\\?\" + full path + null */
|
||||
needed = 4 + count + 1;
|
||||
if(needed > max_path_len)
|
||||
goto cleanup;
|
||||
|
||||
temp = (malloc)(needed * sizeof(wchar_t));
|
||||
if(!temp)
|
||||
goto cleanup;
|
||||
|
||||
wcsncpy(temp, L"\\\\?\\", 4);
|
||||
wcscpy(temp + 4, fbuf);
|
||||
}
|
||||
|
||||
(free)(fbuf);
|
||||
fbuf = temp;
|
||||
}
|
||||
|
||||
#ifndef _UNICODE
|
||||
/* convert unicode full path to multibyte output */
|
||||
needed = wcstombs(NULL, fbuf, 0);
|
||||
if(needed == (size_t)-1 || needed >= max_path_len)
|
||||
goto cleanup;
|
||||
++needed; /* for NUL */
|
||||
obuf = (malloc)(needed);
|
||||
if(!obuf)
|
||||
goto cleanup;
|
||||
count = wcstombs(obuf, fbuf, needed);
|
||||
if(count == (size_t)-1 || count >= needed)
|
||||
goto cleanup;
|
||||
*out = obuf;
|
||||
obuf = NULL;
|
||||
#else
|
||||
*out = fbuf;
|
||||
fbuf = NULL;
|
||||
#endif
|
||||
|
||||
cleanup:
|
||||
(free)(fbuf);
|
||||
#ifndef _UNICODE
|
||||
(free)(ibuf);
|
||||
(free)(obuf);
|
||||
#endif
|
||||
return *out ? true : false;
|
||||
}
|
||||
|
||||
int curlx_win32_open(const char *filename, int oflag, ...)
|
||||
{
|
||||
int pmode = 0;
|
||||
int result = -1;
|
||||
TCHAR *fixed = NULL;
|
||||
const TCHAR *target = NULL;
|
||||
|
||||
#ifdef _UNICODE
|
||||
wchar_t *filename_w = curlx_convert_UTF8_to_wchar(filename);
|
||||
#endif
|
||||
|
||||
va_list param;
|
||||
va_start(param, oflag);
|
||||
if(oflag & O_CREAT)
|
||||
pmode = va_arg(param, int);
|
||||
va_end(param);
|
||||
|
||||
#ifdef _UNICODE
|
||||
if(filename_w) {
|
||||
if(fix_excessive_path(filename_w, &fixed))
|
||||
target = fixed;
|
||||
else
|
||||
target = filename_w;
|
||||
result = _wopen(target, oflag, pmode);
|
||||
curlx_unicodefree(filename_w);
|
||||
}
|
||||
else
|
||||
/* !checksrc! disable ERRNOVAR 1 */
|
||||
CURL_SETERRNO(EINVAL);
|
||||
#else
|
||||
if(fix_excessive_path(filename, &fixed))
|
||||
target = fixed;
|
||||
else
|
||||
target = filename;
|
||||
result = _open(target, oflag, pmode);
|
||||
#endif
|
||||
|
||||
(free)(fixed);
|
||||
return result;
|
||||
}
|
||||
|
||||
FILE *curlx_win32_fopen(const char *filename, const char *mode)
|
||||
{
|
||||
FILE *result = NULL;
|
||||
TCHAR *fixed = NULL;
|
||||
const TCHAR *target = NULL;
|
||||
|
||||
#ifdef _UNICODE
|
||||
wchar_t *filename_w = curlx_convert_UTF8_to_wchar(filename);
|
||||
wchar_t *mode_w = curlx_convert_UTF8_to_wchar(mode);
|
||||
if(filename_w && mode_w) {
|
||||
if(fix_excessive_path(filename_w, &fixed))
|
||||
target = fixed;
|
||||
else
|
||||
target = filename_w;
|
||||
result = _wfopen(target, mode_w);
|
||||
}
|
||||
else
|
||||
/* !checksrc! disable ERRNOVAR 1 */
|
||||
CURL_SETERRNO(EINVAL);
|
||||
curlx_unicodefree(filename_w);
|
||||
curlx_unicodefree(mode_w);
|
||||
#else
|
||||
if(fix_excessive_path(filename, &fixed))
|
||||
target = fixed;
|
||||
else
|
||||
target = filename;
|
||||
result = (fopen)(target, mode);
|
||||
#endif
|
||||
|
||||
(free)(fixed);
|
||||
return result;
|
||||
}
|
||||
|
||||
int curlx_win32_stat(const char *path, struct_stat *buffer)
|
||||
{
|
||||
int result = -1;
|
||||
TCHAR *fixed = NULL;
|
||||
const TCHAR *target = NULL;
|
||||
|
||||
#ifdef _UNICODE
|
||||
wchar_t *path_w = curlx_convert_UTF8_to_wchar(path);
|
||||
if(path_w) {
|
||||
if(fix_excessive_path(path_w, &fixed))
|
||||
target = fixed;
|
||||
else
|
||||
target = path_w;
|
||||
#ifndef USE_WIN32_LARGE_FILES
|
||||
result = _wstat(target, buffer);
|
||||
#else
|
||||
result = _wstati64(target, buffer);
|
||||
#endif
|
||||
curlx_unicodefree(path_w);
|
||||
}
|
||||
else
|
||||
/* !checksrc! disable ERRNOVAR 1 */
|
||||
CURL_SETERRNO(EINVAL);
|
||||
#else
|
||||
if(fix_excessive_path(path, &fixed))
|
||||
target = fixed;
|
||||
else
|
||||
target = path;
|
||||
#ifndef USE_WIN32_LARGE_FILES
|
||||
result = _stat(target, buffer);
|
||||
#else
|
||||
result = _stati64(target, buffer);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
(free)(fixed);
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* UNDER_CE */
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
||||
@@ -0,0 +1,361 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute 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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "../curl_setup.h"
|
||||
|
||||
#ifdef HAVE_STRERROR_R
|
||||
# if (!defined(HAVE_POSIX_STRERROR_R) && \
|
||||
!defined(HAVE_GLIBC_STRERROR_R)) || \
|
||||
(defined(HAVE_POSIX_STRERROR_R) && defined(HAVE_GLIBC_STRERROR_R))
|
||||
# error "strerror_r MUST be either POSIX, glibc style"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#ifndef WITHOUT_LIBCURL
|
||||
#include <curl/mprintf.h>
|
||||
#define SNPRINTF curl_msnprintf
|
||||
#else
|
||||
/* when built for the test servers */
|
||||
|
||||
/* adjust for old MSVC */
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1900)
|
||||
#define SNPRINTF _snprintf
|
||||
#else
|
||||
#define SNPRINTF snprintf
|
||||
#endif
|
||||
#endif /* !WITHOUT_LIBCURL */
|
||||
|
||||
#include "winapi.h"
|
||||
#include "strerr.h"
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "../curl_memory.h"
|
||||
#include "../memdebug.h"
|
||||
|
||||
#ifdef USE_WINSOCK
|
||||
/* This is a helper function for curlx_strerror that converts Winsock error
|
||||
* codes (WSAGetLastError) to error messages.
|
||||
* Returns NULL if no error message was found for error code.
|
||||
*/
|
||||
static const char *
|
||||
get_winsock_error(int err, char *buf, size_t len)
|
||||
{
|
||||
#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
||||
const char *p;
|
||||
size_t alen;
|
||||
#endif
|
||||
|
||||
if(!len)
|
||||
return NULL;
|
||||
|
||||
*buf = '\0';
|
||||
|
||||
#ifdef CURL_DISABLE_VERBOSE_STRINGS
|
||||
(void)err;
|
||||
return NULL;
|
||||
#else
|
||||
switch(err) {
|
||||
case WSAEINTR:
|
||||
p = "Call interrupted";
|
||||
break;
|
||||
case WSAEBADF:
|
||||
p = "Bad file";
|
||||
break;
|
||||
case WSAEACCES:
|
||||
p = "Bad access";
|
||||
break;
|
||||
case WSAEFAULT:
|
||||
p = "Bad argument";
|
||||
break;
|
||||
case WSAEINVAL:
|
||||
p = "Invalid arguments";
|
||||
break;
|
||||
case WSAEMFILE:
|
||||
p = "Out of file descriptors";
|
||||
break;
|
||||
case WSAEWOULDBLOCK:
|
||||
p = "Call would block";
|
||||
break;
|
||||
case WSAEINPROGRESS:
|
||||
case WSAEALREADY:
|
||||
p = "Blocking call in progress";
|
||||
break;
|
||||
case WSAENOTSOCK:
|
||||
p = "Descriptor is not a socket";
|
||||
break;
|
||||
case WSAEDESTADDRREQ:
|
||||
p = "Need destination address";
|
||||
break;
|
||||
case WSAEMSGSIZE:
|
||||
p = "Bad message size";
|
||||
break;
|
||||
case WSAEPROTOTYPE:
|
||||
p = "Bad protocol";
|
||||
break;
|
||||
case WSAENOPROTOOPT:
|
||||
p = "Protocol option is unsupported";
|
||||
break;
|
||||
case WSAEPROTONOSUPPORT:
|
||||
p = "Protocol is unsupported";
|
||||
break;
|
||||
case WSAESOCKTNOSUPPORT:
|
||||
p = "Socket is unsupported";
|
||||
break;
|
||||
case WSAEOPNOTSUPP:
|
||||
p = "Operation not supported";
|
||||
break;
|
||||
case WSAEAFNOSUPPORT:
|
||||
p = "Address family not supported";
|
||||
break;
|
||||
case WSAEPFNOSUPPORT:
|
||||
p = "Protocol family not supported";
|
||||
break;
|
||||
case WSAEADDRINUSE:
|
||||
p = "Address already in use";
|
||||
break;
|
||||
case WSAEADDRNOTAVAIL:
|
||||
p = "Address not available";
|
||||
break;
|
||||
case WSAENETDOWN:
|
||||
p = "Network down";
|
||||
break;
|
||||
case WSAENETUNREACH:
|
||||
p = "Network unreachable";
|
||||
break;
|
||||
case WSAENETRESET:
|
||||
p = "Network has been reset";
|
||||
break;
|
||||
case WSAECONNABORTED:
|
||||
p = "Connection was aborted";
|
||||
break;
|
||||
case WSAECONNRESET:
|
||||
p = "Connection was reset";
|
||||
break;
|
||||
case WSAENOBUFS:
|
||||
p = "No buffer space";
|
||||
break;
|
||||
case WSAEISCONN:
|
||||
p = "Socket is already connected";
|
||||
break;
|
||||
case WSAENOTCONN:
|
||||
p = "Socket is not connected";
|
||||
break;
|
||||
case WSAESHUTDOWN:
|
||||
p = "Socket has been shut down";
|
||||
break;
|
||||
case WSAETOOMANYREFS:
|
||||
p = "Too many references";
|
||||
break;
|
||||
case WSAETIMEDOUT:
|
||||
p = "Timed out";
|
||||
break;
|
||||
case WSAECONNREFUSED:
|
||||
p = "Connection refused";
|
||||
break;
|
||||
case WSAELOOP:
|
||||
p = "Loop??";
|
||||
break;
|
||||
case WSAENAMETOOLONG:
|
||||
p = "Name too long";
|
||||
break;
|
||||
case WSAEHOSTDOWN:
|
||||
p = "Host down";
|
||||
break;
|
||||
case WSAEHOSTUNREACH:
|
||||
p = "Host unreachable";
|
||||
break;
|
||||
case WSAENOTEMPTY:
|
||||
p = "Not empty";
|
||||
break;
|
||||
case WSAEPROCLIM:
|
||||
p = "Process limit reached";
|
||||
break;
|
||||
case WSAEUSERS:
|
||||
p = "Too many users";
|
||||
break;
|
||||
case WSAEDQUOT:
|
||||
p = "Bad quota";
|
||||
break;
|
||||
case WSAESTALE:
|
||||
p = "Something is stale";
|
||||
break;
|
||||
case WSAEREMOTE:
|
||||
p = "Remote error";
|
||||
break;
|
||||
case WSAEDISCON:
|
||||
p = "Disconnected";
|
||||
break;
|
||||
/* Extended Winsock errors */
|
||||
case WSASYSNOTREADY:
|
||||
p = "Winsock library is not ready";
|
||||
break;
|
||||
case WSANOTINITIALISED:
|
||||
p = "Winsock library not initialised";
|
||||
break;
|
||||
case WSAVERNOTSUPPORTED:
|
||||
p = "Winsock version not supported";
|
||||
break;
|
||||
|
||||
/* getXbyY() errors (already handled in herrmsg):
|
||||
* Authoritative Answer: Host not found */
|
||||
case WSAHOST_NOT_FOUND:
|
||||
p = "Host not found";
|
||||
break;
|
||||
|
||||
/* Non-Authoritative: Host not found, or SERVERFAIL */
|
||||
case WSATRY_AGAIN:
|
||||
p = "Host not found, try again";
|
||||
break;
|
||||
|
||||
/* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
|
||||
case WSANO_RECOVERY:
|
||||
p = "Unrecoverable error in call to nameserver";
|
||||
break;
|
||||
|
||||
/* Valid name, no data record of requested type */
|
||||
case WSANO_DATA:
|
||||
p = "No data record of requested type";
|
||||
break;
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
alen = strlen(p);
|
||||
if(alen < len)
|
||||
strcpy(buf, p);
|
||||
return buf;
|
||||
#endif
|
||||
}
|
||||
#endif /* USE_WINSOCK */
|
||||
|
||||
/*
|
||||
* Our thread-safe and smart strerror() replacement.
|
||||
*
|
||||
* The 'err' argument passed in to this function MUST be a true errno number
|
||||
* as reported on this system. We do no range checking on the number before
|
||||
* we pass it to the "number-to-message" conversion function and there might
|
||||
* be systems that do not do proper range checking in there themselves.
|
||||
*
|
||||
* We do not do range checking (on systems other than Windows) since there is
|
||||
* no good reliable and portable way to do it.
|
||||
*
|
||||
* On Windows different types of error codes overlap. This function has an
|
||||
* order of preference when trying to match error codes:
|
||||
* CRT (errno), Winsock (WSAGetLastError), Windows API (GetLastError).
|
||||
*
|
||||
* It may be more correct to call one of the variant functions instead:
|
||||
* Call Curl_sspi_strerror if the error code is definitely Windows SSPI.
|
||||
* Call curlx_winapi_strerror if the error code is definitely Windows API.
|
||||
*/
|
||||
const char *curlx_strerror(int err, char *buf, size_t buflen)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
DWORD old_win_err = GetLastError();
|
||||
#endif
|
||||
int old_errno = errno;
|
||||
char *p;
|
||||
|
||||
if(!buflen)
|
||||
return NULL;
|
||||
|
||||
#ifndef _WIN32
|
||||
DEBUGASSERT(err >= 0);
|
||||
#endif
|
||||
|
||||
*buf = '\0';
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifndef UNDER_CE
|
||||
/* 'sys_nerr' is the maximum errno number, it is not widely portable */
|
||||
if(err >= 0 && err < sys_nerr)
|
||||
SNPRINTF(buf, buflen, "%s", sys_errlist[err]);
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if(
|
||||
#ifdef USE_WINSOCK
|
||||
!get_winsock_error(err, buf, buflen) &&
|
||||
#endif
|
||||
!curlx_get_winapi_error((DWORD)err, buf, buflen))
|
||||
SNPRINTF(buf, buflen, "Unknown error %d (%#x)", err, err);
|
||||
}
|
||||
#else /* !_WIN32 */
|
||||
|
||||
#if defined(HAVE_STRERROR_R) && defined(HAVE_POSIX_STRERROR_R)
|
||||
/*
|
||||
* The POSIX-style strerror_r() may set errno to ERANGE if insufficient
|
||||
* storage is supplied via 'strerrbuf' and 'buflen' to hold the generated
|
||||
* message string, or EINVAL if 'errnum' is not a valid error number.
|
||||
*/
|
||||
if(strerror_r(err, buf, buflen) &&
|
||||
buflen > sizeof("Unknown error ") + 20) {
|
||||
if(buf[0] == '\0')
|
||||
SNPRINTF(buf, buflen, "Unknown error %d", err);
|
||||
}
|
||||
#elif defined(HAVE_STRERROR_R) && defined(HAVE_GLIBC_STRERROR_R)
|
||||
/*
|
||||
* The glibc-style strerror_r() only *might* use the buffer we pass to
|
||||
* the function, but it always returns the error message as a pointer,
|
||||
* so we must copy that string unconditionally (if non-NULL).
|
||||
*/
|
||||
{
|
||||
char buffer[256];
|
||||
char *msg = strerror_r(err, buffer, sizeof(buffer));
|
||||
if(msg && buflen > 1)
|
||||
SNPRINTF(buf, buflen, "%s", msg);
|
||||
else if(buflen > sizeof("Unknown error ") + 20)
|
||||
SNPRINTF(buf, buflen, "Unknown error %d", err);
|
||||
}
|
||||
#else
|
||||
{
|
||||
/* !checksrc! disable BANNEDFUNC 1 */
|
||||
const char *msg = strerror(err);
|
||||
if(msg && buflen > 1)
|
||||
SNPRINTF(buf, buflen, "%s", msg);
|
||||
else if(buflen > sizeof("Unknown error ") + 20)
|
||||
SNPRINTF(buf, buflen, "Unknown error %d", err);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
||||
/* strip trailing '\r\n' or '\n'. */
|
||||
p = strrchr(buf, '\n');
|
||||
if(p && (p - buf) >= 2)
|
||||
*p = '\0';
|
||||
p = strrchr(buf, '\r');
|
||||
if(p && (p - buf) >= 1)
|
||||
*p = '\0';
|
||||
|
||||
if(errno != old_errno)
|
||||
CURL_SETERRNO(old_errno);
|
||||
|
||||
#ifdef _WIN32
|
||||
if(old_win_err != GetLastError())
|
||||
SetLastError(old_win_err);
|
||||
#endif
|
||||
|
||||
return buf;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef HEADER_CURL_DES_H
|
||||
#define HEADER_CURL_DES_H
|
||||
#ifndef HEADER_CURL_STRERR_H
|
||||
#define HEADER_CURL_STRERR_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) Steve Holme, <steve_holme@hotmail.com>.
|
||||
* Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -24,16 +24,6 @@
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
const char *curlx_strerror(int err, char *buf, size_t buflen);
|
||||
|
||||
#if defined(USE_CURL_NTLM_CORE) && \
|
||||
(defined(USE_GNUTLS) || \
|
||||
defined(USE_OS400CRYPTO) || \
|
||||
defined(USE_WIN32_CRYPTO))
|
||||
|
||||
/* Applies odd parity to the given byte array */
|
||||
void Curl_des_set_odd_parity(unsigned char *bytes, size_t length);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_DES_H */
|
||||
#endif /* HEADER_CURL_STRERR_H */
|
||||
@@ -134,8 +134,15 @@ bool curlx_verify_windows_version(const unsigned int majorVersion,
|
||||
static bool onetime = TRUE; /* safe because first call is during init */
|
||||
|
||||
if(onetime) {
|
||||
#if defined(__clang__) && __clang_major__ >= 16
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wcast-function-type-strict"
|
||||
#endif
|
||||
pRtlVerifyVersionInfo = CURLX_FUNCTION_CAST(RTLVERIFYVERSIONINFO_FN,
|
||||
(GetProcAddress(GetModuleHandleA("ntdll"), "RtlVerifyVersionInfo")));
|
||||
GetProcAddress(GetModuleHandleA("ntdll"), "RtlVerifyVersionInfo"));
|
||||
#if defined(__clang__) && __clang_major__ >= 16
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
onetime = FALSE;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,12 +25,12 @@
|
||||
|
||||
/*
|
||||
* curlx_winapi_strerror:
|
||||
* Variant of Curl_strerror if the error code is definitely Windows API.
|
||||
* Variant of curlx_strerror if the error code is definitely Windows API.
|
||||
*/
|
||||
#ifdef _WIN32
|
||||
#include "winapi.h"
|
||||
|
||||
#ifdef BUILDING_LIBCURL
|
||||
#ifndef WITHOUT_LIBCURL
|
||||
#include <curl/mprintf.h>
|
||||
#define SNPRINTF curl_msnprintf
|
||||
#else
|
||||
@@ -38,19 +38,17 @@
|
||||
|
||||
/* adjust for old MSVC */
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1900)
|
||||
# define SNPRINTF _snprintf
|
||||
#define SNPRINTF _snprintf
|
||||
#else
|
||||
#define SNPRINTF snprintf
|
||||
#endif
|
||||
#endif /* !WITHOUT_LIBCURL */
|
||||
|
||||
#endif /* !BUILDING_LIBCURL */
|
||||
|
||||
#ifdef _WIN32
|
||||
/* This is a helper function for Curl_strerror that converts Windows API error
|
||||
/* This is a helper function for curlx_strerror that converts Windows API error
|
||||
* codes (GetLastError) to error messages.
|
||||
* Returns NULL if no error message was found for error code.
|
||||
*/
|
||||
const char *curlx_get_winapi_error(int err, char *buf, size_t buflen)
|
||||
const char *curlx_get_winapi_error(DWORD err, char *buf, size_t buflen)
|
||||
{
|
||||
char *p;
|
||||
wchar_t wbuf[256];
|
||||
@@ -66,7 +64,7 @@ const char *curlx_get_winapi_error(int err, char *buf, size_t buflen)
|
||||
expect the local codepage (eg fprintf, failf, infof).
|
||||
FormatMessageW -> wcstombs is used for Windows CE compatibility. */
|
||||
if(FormatMessageW((FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS), NULL, (DWORD)err,
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS), NULL, err,
|
||||
LANG_NEUTRAL, wbuf, CURL_ARRAYSIZE(wbuf), NULL)) {
|
||||
size_t written = wcstombs(buf, wbuf, buflen - 1);
|
||||
if(written != (size_t)-1)
|
||||
@@ -86,13 +84,10 @@ const char *curlx_get_winapi_error(int err, char *buf, size_t buflen)
|
||||
|
||||
return *buf ? buf : NULL;
|
||||
}
|
||||
#endif /* _WIN32 */
|
||||
|
||||
const char *curlx_winapi_strerror(DWORD err, char *buf, size_t buflen)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
DWORD old_win_err = GetLastError();
|
||||
#endif
|
||||
int old_errno = errno;
|
||||
|
||||
if(!buflen)
|
||||
@@ -101,14 +96,14 @@ const char *curlx_winapi_strerror(DWORD err, char *buf, size_t buflen)
|
||||
*buf = '\0';
|
||||
|
||||
#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
||||
if(!curlx_get_winapi_error((int)err, buf, buflen)) {
|
||||
if(!curlx_get_winapi_error(err, buf, buflen)) {
|
||||
#if defined(__GNUC__) && __GNUC__ >= 7
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic warning "-Wformat-truncation=1"
|
||||
#endif
|
||||
/* some GCC compilers cause false positive warnings if we allow this
|
||||
warning */
|
||||
SNPRINTF(buf, buflen, "Unknown error %lu (0x%08lX)", err, err);
|
||||
SNPRINTF(buf, buflen, "Unknown error %lu (0x%08lx)", err, err);
|
||||
#if defined(__GNUC__) && __GNUC__ >= 7
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
@@ -125,10 +120,8 @@ const char *curlx_winapi_strerror(DWORD err, char *buf, size_t buflen)
|
||||
if(errno != old_errno)
|
||||
CURL_SETERRNO(old_errno);
|
||||
|
||||
#ifdef _WIN32
|
||||
if(old_win_err != GetLastError())
|
||||
SetLastError(old_win_err);
|
||||
#endif
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
#ifdef _WIN32
|
||||
#define WINAPI_ERROR_LEN 100
|
||||
const char *curlx_get_winapi_error(int err, char *buf, size_t buflen);
|
||||
const char *curlx_get_winapi_error(DWORD err, char *buf, size_t buflen);
|
||||
const char *curlx_winapi_strerror(DWORD err, char *buf, size_t buflen);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -35,8 +35,7 @@
|
||||
#include "cw-out.h"
|
||||
#include "cw-pause.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
@@ -303,6 +302,7 @@ static CURLcode cw_out_buf_flush(struct cw_out_ctx *ctx,
|
||||
&consumed);
|
||||
if(result && (result != CURLE_AGAIN))
|
||||
return result;
|
||||
result = CURLE_OK;
|
||||
|
||||
if(consumed) {
|
||||
if(consumed == curlx_dyn_len(&cwbuf->b)) {
|
||||
@@ -404,7 +404,7 @@ static CURLcode cw_out_do_write(struct cw_out_ctx *ctx,
|
||||
/* still have buffered data, append and flush */
|
||||
result = cw_out_append(ctx, data, otype, buf, blen);
|
||||
if(result)
|
||||
return result;
|
||||
goto out;
|
||||
result = cw_out_flush_chain(ctx, data, &ctx->buf, flush_all);
|
||||
if(result)
|
||||
goto out;
|
||||
|
||||
@@ -34,8 +34,7 @@
|
||||
#include "sendf.h"
|
||||
#include "cw-pause.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
|
||||
@@ -59,9 +59,9 @@
|
||||
#include "escape.h"
|
||||
#include "progress.h"
|
||||
#include "dict.h"
|
||||
#include "curl_printf.h"
|
||||
|
||||
/* The last 2 #include files should be: */
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
|
||||
@@ -144,7 +144,7 @@ static CURLcode sendf(struct Curl_easy *data, const char *fmt, ...)
|
||||
char *sptr;
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
s = vaprintf(fmt, ap); /* returns an allocated string */
|
||||
s = curl_mvaprintf(fmt, ap); /* returns an allocated string */
|
||||
va_end(ap);
|
||||
if(!s)
|
||||
return CURLE_OUT_OF_MEMORY; /* failure */
|
||||
|
||||
@@ -28,8 +28,7 @@
|
||||
#include <openssl/crypto.h>
|
||||
#endif
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
|
||||
+28
-25
@@ -41,8 +41,7 @@
|
||||
#include "escape.h"
|
||||
#include "urlapi-int.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
@@ -377,6 +376,9 @@ static CURLcode doh_probe_run(struct Curl_easy *data,
|
||||
options should be added to check doh proxy insecure separately,
|
||||
CURLOPT_DOH_PROXY_SSL_VERIFYHOST and CURLOPT_DOH_PROXY_SSL_VERIFYPEER.
|
||||
*/
|
||||
doh->set.ssl.custom_cafile = data->set.ssl.custom_cafile;
|
||||
doh->set.ssl.custom_capath = data->set.ssl.custom_capath;
|
||||
doh->set.ssl.custom_cablob = data->set.ssl.custom_cablob;
|
||||
if(data->set.str[STRING_SSL_CAFILE]) {
|
||||
ERROR_CHECK_SETOPT(CURLOPT_CAINFO,
|
||||
data->set.str[STRING_SSL_CAFILE]);
|
||||
@@ -456,6 +458,7 @@ struct Curl_addrinfo *Curl_doh(struct Curl_easy *data,
|
||||
|
||||
DEBUGASSERT(conn);
|
||||
DEBUGASSERT(!data->state.async.doh);
|
||||
DEBUGASSERT(hostname && hostname[0]);
|
||||
if(data->state.async.doh)
|
||||
Curl_doh_cleanup(data);
|
||||
|
||||
@@ -510,7 +513,7 @@ struct Curl_addrinfo *Curl_doh(struct Curl_easy *data,
|
||||
/* Only use HTTPS RR for HTTP(S) transfers */
|
||||
char *qname = NULL;
|
||||
if(port != PORT_HTTPS) {
|
||||
qname = aprintf("_%d._https.%s", port, hostname);
|
||||
qname = curl_maprintf("_%d._https.%s", port, hostname);
|
||||
if(!qname)
|
||||
goto error;
|
||||
}
|
||||
@@ -759,7 +762,7 @@ UNITTEST DOHcode doh_resp_decode(const unsigned char *doh,
|
||||
|
||||
ancount = doh_get16bit(doh, 6);
|
||||
while(ancount) {
|
||||
unsigned short class;
|
||||
unsigned short dnsclass;
|
||||
unsigned int ttl;
|
||||
|
||||
rc = doh_skipqname(doh, dohlen, &index);
|
||||
@@ -779,8 +782,8 @@ UNITTEST DOHcode doh_resp_decode(const unsigned char *doh,
|
||||
|
||||
if(dohlen < (index + 2))
|
||||
return DOH_DNS_OUT_OF_RANGE;
|
||||
class = doh_get16bit(doh, index);
|
||||
if(DNS_CLASS_IN != class)
|
||||
dnsclass = doh_get16bit(doh, index);
|
||||
if(DNS_CLASS_IN != dnsclass)
|
||||
return DOH_DNS_UNEXPECTED_CLASS; /* unsupported */
|
||||
index += 2;
|
||||
|
||||
@@ -816,7 +819,7 @@ UNITTEST DOHcode doh_resp_decode(const unsigned char *doh,
|
||||
if(dohlen < (index + 8))
|
||||
return DOH_DNS_OUT_OF_RANGE;
|
||||
|
||||
index += 2 + 2 + 4; /* type, class and ttl */
|
||||
index += 2 + 2 + 4; /* type, dnsclass and ttl */
|
||||
|
||||
if(dohlen < (index + 2))
|
||||
return DOH_DNS_OUT_OF_RANGE;
|
||||
@@ -838,7 +841,7 @@ UNITTEST DOHcode doh_resp_decode(const unsigned char *doh,
|
||||
if(dohlen < (index + 8))
|
||||
return DOH_DNS_OUT_OF_RANGE;
|
||||
|
||||
index += 2 + 2 + 4; /* type, class and ttl */
|
||||
index += 2 + 2 + 4; /* type, dnsclass and ttl */
|
||||
|
||||
if(dohlen < (index + 2))
|
||||
return DOH_DNS_OUT_OF_RANGE;
|
||||
@@ -887,8 +890,9 @@ static void doh_show(struct Curl_easy *data,
|
||||
len = sizeof(buffer) - len;
|
||||
for(j = 0; j < 16; j += 2) {
|
||||
size_t l;
|
||||
msnprintf(ptr, len, "%s%02x%02x", j ? ":" : "", d->addr[i].ip.v6[j],
|
||||
d->addr[i].ip.v6[j + 1]);
|
||||
curl_msnprintf(ptr, len, "%s%02x%02x", j ? ":" : "",
|
||||
d->addr[i].ip.v6[j],
|
||||
d->addr[i].ip.v6[j + 1]);
|
||||
l = strlen(ptr);
|
||||
len -= l;
|
||||
ptr += l;
|
||||
@@ -1062,7 +1066,7 @@ UNITTEST void de_cleanup(struct dohentry *d)
|
||||
* @return is 1 for success, error otherwise
|
||||
*
|
||||
* The encoding here is defined in
|
||||
* https://tools.ietf.org/html/rfc1035#section-3.1
|
||||
* https://datatracker.ietf.org/doc/html/rfc1035#section-3.1
|
||||
*
|
||||
* The input buffer pointer will be modified so it points to
|
||||
* just after the end of the DNS name encoding on output. (And
|
||||
@@ -1215,8 +1219,9 @@ UNITTEST void doh_print_httpsrr(struct Curl_easy *data,
|
||||
CURLcode Curl_doh_is_resolved(struct Curl_easy *data,
|
||||
struct Curl_dns_entry **dnsp)
|
||||
{
|
||||
CURLcode result;
|
||||
CURLcode result = CURLE_OK;
|
||||
struct doh_probes *dohp = data->state.async.doh;
|
||||
struct dohentry de;
|
||||
*dnsp = NULL; /* defaults to no response */
|
||||
if(!dohp)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
@@ -1229,7 +1234,6 @@ CURLcode Curl_doh_is_resolved(struct Curl_easy *data,
|
||||
}
|
||||
else if(!dohp->pending) {
|
||||
DOHcode rc[DOH_SLOT_COUNT];
|
||||
struct dohentry de;
|
||||
int slot;
|
||||
|
||||
/* Clear any result the might still be there */
|
||||
@@ -1261,17 +1265,14 @@ CURLcode Curl_doh_is_resolved(struct Curl_easy *data,
|
||||
struct Curl_dns_entry *dns;
|
||||
struct Curl_addrinfo *ai;
|
||||
|
||||
|
||||
if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_dns)) {
|
||||
CURL_TRC_DNS(data, "hostname: %s", dohp->host);
|
||||
doh_show(data, &de);
|
||||
}
|
||||
|
||||
result = doh2ai(&de, dohp->host, dohp->port, &ai);
|
||||
if(result) {
|
||||
de_cleanup(&de);
|
||||
return result;
|
||||
}
|
||||
if(result)
|
||||
goto error;
|
||||
|
||||
/* we got a response, create a dns entry. */
|
||||
dns = Curl_dnscache_mk_entry(data, ai, dohp->host, 0, dohp->port, FALSE);
|
||||
@@ -1284,7 +1285,8 @@ CURLcode Curl_doh_is_resolved(struct Curl_easy *data,
|
||||
de.https_rrs->len, &hrr);
|
||||
if(result) {
|
||||
infof(data, "Failed to decode HTTPS RR");
|
||||
return result;
|
||||
Curl_resolv_unlink(data, &dns);
|
||||
goto error;
|
||||
}
|
||||
infof(data, "Some HTTPS RR to process");
|
||||
# ifdef DEBUGBUILD
|
||||
@@ -1302,14 +1304,15 @@ CURLcode Curl_doh_is_resolved(struct Curl_easy *data,
|
||||
|
||||
/* All done */
|
||||
data->state.async.done = TRUE;
|
||||
de_cleanup(&de);
|
||||
Curl_doh_cleanup(data);
|
||||
return result;
|
||||
|
||||
} /* !dohp->pending */
|
||||
else
|
||||
/* wait for pending DoH transactions to complete */
|
||||
return CURLE_OK;
|
||||
|
||||
/* else wait for pending DoH transactions to complete */
|
||||
return CURLE_OK;
|
||||
error:
|
||||
de_cleanup(&de);
|
||||
Curl_doh_cleanup(data);
|
||||
return result;
|
||||
}
|
||||
|
||||
void Curl_doh_close(struct Curl_easy *data)
|
||||
|
||||
@@ -26,12 +26,12 @@
|
||||
#include "dynhds.h"
|
||||
#include "strcase.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#ifdef USE_NGHTTP2
|
||||
#include <stdint.h>
|
||||
#include <nghttp2/nghttp2.h>
|
||||
#endif /* USE_NGHTTP2 */
|
||||
#include "curl_printf.h"
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
|
||||
+28
-25
@@ -80,8 +80,7 @@
|
||||
|
||||
#include "easy_lock.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
@@ -157,42 +156,42 @@ static CURLcode global_init(long flags, bool memoryfuncs)
|
||||
}
|
||||
|
||||
if(Curl_trc_init()) {
|
||||
DEBUGF(fprintf(stderr, "Error: Curl_trc_init failed\n"));
|
||||
DEBUGF(curl_mfprintf(stderr, "Error: Curl_trc_init failed\n"));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if(!Curl_ssl_init()) {
|
||||
DEBUGF(fprintf(stderr, "Error: Curl_ssl_init failed\n"));
|
||||
DEBUGF(curl_mfprintf(stderr, "Error: Curl_ssl_init failed\n"));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if(!Curl_vquic_init()) {
|
||||
DEBUGF(fprintf(stderr, "Error: Curl_vquic_init failed\n"));
|
||||
DEBUGF(curl_mfprintf(stderr, "Error: Curl_vquic_init failed\n"));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if(Curl_win32_init(flags)) {
|
||||
DEBUGF(fprintf(stderr, "Error: win32_init failed\n"));
|
||||
DEBUGF(curl_mfprintf(stderr, "Error: win32_init failed\n"));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if(Curl_amiga_init()) {
|
||||
DEBUGF(fprintf(stderr, "Error: Curl_amiga_init failed\n"));
|
||||
DEBUGF(curl_mfprintf(stderr, "Error: Curl_amiga_init failed\n"));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if(Curl_macos_init()) {
|
||||
DEBUGF(fprintf(stderr, "Error: Curl_macos_init failed\n"));
|
||||
DEBUGF(curl_mfprintf(stderr, "Error: Curl_macos_init failed\n"));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if(Curl_async_global_init()) {
|
||||
DEBUGF(fprintf(stderr, "Error: resolver_global_init failed\n"));
|
||||
DEBUGF(curl_mfprintf(stderr, "Error: resolver_global_init failed\n"));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if(Curl_ssh_init()) {
|
||||
DEBUGF(fprintf(stderr, "Error: Curl_ssh_init failed\n"));
|
||||
DEBUGF(curl_mfprintf(stderr, "Error: Curl_ssh_init failed\n"));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@@ -361,7 +360,7 @@ CURL *curl_easy_init(void)
|
||||
result = global_init(CURL_GLOBAL_DEFAULT, TRUE);
|
||||
if(result) {
|
||||
/* something in the global init failed, return nothing */
|
||||
DEBUGF(fprintf(stderr, "Error: curl_global_init failed\n"));
|
||||
DEBUGF(curl_mfprintf(stderr, "Error: curl_global_init failed\n"));
|
||||
global_init_unlock();
|
||||
return NULL;
|
||||
}
|
||||
@@ -371,7 +370,7 @@ CURL *curl_easy_init(void)
|
||||
/* We use curl_open() with undefined URL so far */
|
||||
result = Curl_open(&data);
|
||||
if(result) {
|
||||
DEBUGF(fprintf(stderr, "Error: Curl_open failed\n"));
|
||||
DEBUGF(curl_mfprintf(stderr, "Error: Curl_open failed\n"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -407,7 +406,7 @@ static int events_timer(CURLM *multi, /* multi handle */
|
||||
struct events *ev = userp;
|
||||
(void)multi;
|
||||
#if DEBUG_EV_POLL
|
||||
fprintf(stderr, "events_timer: set timeout %ldms\n", timeout_ms);
|
||||
curl_mfprintf(stderr, "events_timer: set timeout %ldms\n", timeout_ms);
|
||||
#endif
|
||||
ev->ms = timeout_ms;
|
||||
ev->msbump = TRUE;
|
||||
@@ -559,7 +558,7 @@ static unsigned int populate_fds(struct pollfd *fds, struct events *ev)
|
||||
f->events = m->socket.events;
|
||||
f->revents = 0;
|
||||
#if DEBUG_EV_POLL
|
||||
fprintf(stderr, "poll() %d check socket %d\n", numfds, f->fd);
|
||||
curl_mfprintf(stderr, "poll() %d check socket %d\n", numfds, f->fd);
|
||||
#endif
|
||||
f++;
|
||||
numfds++;
|
||||
@@ -579,19 +578,19 @@ static CURLcode poll_fds(struct events *ev,
|
||||
if(numfds) {
|
||||
/* wait for activity or timeout */
|
||||
#if DEBUG_EV_POLL
|
||||
fprintf(stderr, "poll(numfds=%u, timeout=%ldms)\n", numfds, ev->ms);
|
||||
curl_mfprintf(stderr, "poll(numfds=%u, timeout=%ldms)\n", numfds, ev->ms);
|
||||
#endif
|
||||
*pollrc = Curl_poll(fds, numfds, ev->ms);
|
||||
#if DEBUG_EV_POLL
|
||||
fprintf(stderr, "poll(numfds=%u, timeout=%ldms) -> %d\n",
|
||||
numfds, ev->ms, *pollrc);
|
||||
curl_mfprintf(stderr, "poll(numfds=%u, timeout=%ldms) -> %d\n",
|
||||
numfds, ev->ms, *pollrc);
|
||||
#endif
|
||||
if(*pollrc < 0)
|
||||
return CURLE_UNRECOVERABLE_POLL;
|
||||
}
|
||||
else {
|
||||
#if DEBUG_EV_POLL
|
||||
fprintf(stderr, "poll, but no fds, wait timeout=%ldms\n", ev->ms);
|
||||
curl_mfprintf(stderr, "poll, but no fds, wait timeout=%ldms\n", ev->ms);
|
||||
#endif
|
||||
*pollrc = 0;
|
||||
if(ev->ms > 0)
|
||||
@@ -629,7 +628,7 @@ static CURLcode wait_or_timeout(struct Curl_multi *multi, struct events *ev)
|
||||
if(!pollrc) {
|
||||
/* timeout! */
|
||||
ev->ms = 0;
|
||||
/* fprintf(stderr, "call curl_multi_socket_action(TIMEOUT)\n"); */
|
||||
/* curl_mfprintf(stderr, "call curl_multi_socket_action(TIMEOUT)\n"); */
|
||||
mcode = curl_multi_socket_action(multi, CURL_SOCKET_TIMEOUT, 0,
|
||||
&ev->running_handles);
|
||||
}
|
||||
@@ -658,8 +657,8 @@ static CURLcode wait_or_timeout(struct Curl_multi *multi, struct events *ev)
|
||||
timediff_t timediff = curlx_timediff(curlx_now(), before);
|
||||
if(timediff > 0) {
|
||||
#if DEBUG_EV_POLL
|
||||
fprintf(stderr, "poll timeout %ldms not updated, decrease by "
|
||||
"time spent %ldms\n", ev->ms, (long)timediff);
|
||||
curl_mfprintf(stderr, "poll timeout %ldms not updated, decrease by "
|
||||
"time spent %ldms\n", ev->ms, (long)timediff);
|
||||
#endif
|
||||
if(timediff > ev->ms)
|
||||
ev->ms = 0;
|
||||
@@ -877,12 +876,16 @@ void curl_easy_cleanup(CURL *ptr)
|
||||
* information from a performed transfer and similar.
|
||||
*/
|
||||
#undef curl_easy_getinfo
|
||||
CURLcode curl_easy_getinfo(CURL *data, CURLINFO info, ...)
|
||||
CURLcode curl_easy_getinfo(CURL *easy, CURLINFO info, ...)
|
||||
{
|
||||
struct Curl_easy *data = easy;
|
||||
va_list arg;
|
||||
void *paramp;
|
||||
CURLcode result;
|
||||
|
||||
if(!GOOD_EASY_HANDLE(data))
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
|
||||
va_start(arg, info);
|
||||
paramp = va_arg(arg, void *);
|
||||
|
||||
@@ -1106,7 +1109,7 @@ void curl_easy_reset(CURL *d)
|
||||
/* zero out UserDefined data: */
|
||||
Curl_freeset(data);
|
||||
memset(&data->set, 0, sizeof(struct UserDefined));
|
||||
(void)Curl_init_userdefined(data);
|
||||
Curl_init_userdefined(data);
|
||||
|
||||
/* zero out Progress data: */
|
||||
memset(&data->progress, 0, sizeof(struct Progress));
|
||||
@@ -1116,7 +1119,6 @@ void curl_easy_reset(CURL *d)
|
||||
|
||||
data->progress.hide = TRUE;
|
||||
data->state.current_speed = -1; /* init to negative == impossible */
|
||||
data->state.retrycount = 0; /* reset the retry counter */
|
||||
data->state.recent_conn_id = -1; /* clear remembered connection id */
|
||||
|
||||
/* zero out authentication data: */
|
||||
@@ -1163,7 +1165,8 @@ CURLcode curl_easy_pause(CURL *d, int action)
|
||||
send_paused = Curl_xfer_send_is_paused(data);
|
||||
send_paused_new = (action & CURLPAUSE_SEND);
|
||||
|
||||
if(send_paused != send_paused_new) {
|
||||
if((send_paused != send_paused_new) ||
|
||||
(send_paused_new != Curl_creader_is_paused(data))) {
|
||||
changed = TRUE;
|
||||
result = Curl_1st_err(result, Curl_xfer_pause_send(data, send_paused_new));
|
||||
}
|
||||
|
||||
@@ -45,20 +45,18 @@
|
||||
#define curl_simple_lock atomic_int
|
||||
#define CURL_SIMPLE_LOCK_INIT 0
|
||||
|
||||
/* a clang-thing */
|
||||
#ifndef __has_builtin
|
||||
#define __has_builtin(x) 0
|
||||
#endif
|
||||
|
||||
#ifndef __INTEL_COMPILER
|
||||
/* The Intel compiler tries to look like GCC *and* clang *and* lies in its
|
||||
__has_builtin() function, so override it. */
|
||||
|
||||
/* if GCC on i386/x86_64 or if the built-in is present */
|
||||
#if ( (defined(__GNUC__) && !defined(__clang__)) && \
|
||||
(defined(__i386__) || defined(__x86_64__))) || \
|
||||
__has_builtin(__builtin_ia32_pause)
|
||||
#if (defined(__GNUC__) && !defined(__clang__)) && \
|
||||
(defined(__i386__) || defined(__x86_64__))
|
||||
#define HAVE_BUILTIN_IA32_PAUSE
|
||||
#elif defined(__has_builtin) /* Keep this PP check separate from others */
|
||||
#if __has_builtin(__builtin_ia32_pause)
|
||||
#define HAVE_BUILTIN_IA32_PAUSE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -34,11 +34,10 @@ struct Curl_easy;
|
||||
#include "urldata.h"
|
||||
#include "curlx/warnless.h"
|
||||
#include "escape.h"
|
||||
#include "strdup.h"
|
||||
#include "curlx/strparse.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
|
||||
@@ -31,8 +31,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <ares.h>
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
@@ -178,7 +177,7 @@ int r_getaddrinfo(const char *node,
|
||||
if(env) {
|
||||
rc = ares_set_servers_ports_csv(channel, env);
|
||||
if(rc) {
|
||||
fprintf(stderr, "ares_set_servers_ports_csv failed: %d", rc);
|
||||
curl_mfprintf(stderr, "ares_set_servers_ports_csv failed: %d", rc);
|
||||
/* Cleanup */
|
||||
ares_destroy(channel);
|
||||
return EAI_MEMORY; /* we can't run */
|
||||
|
||||
+20
-24
@@ -46,10 +46,6 @@
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
@@ -65,15 +61,15 @@
|
||||
#include "escape.h"
|
||||
#include "file.h"
|
||||
#include "speedcheck.h"
|
||||
#include "getinfo.h"
|
||||
#include "multiif.h"
|
||||
#include "transfer.h"
|
||||
#include "url.h"
|
||||
#include "parsedate.h" /* for the week day and month names */
|
||||
#include "curlx/fopen.h"
|
||||
#include "curlx/warnless.h"
|
||||
#include "curl_range.h"
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
@@ -237,7 +233,7 @@ static CURLcode file_connect(struct Curl_easy *data, bool *done)
|
||||
return CURLE_URL_MALFORMAT;
|
||||
}
|
||||
|
||||
fd = open(actual_path, O_RDONLY|CURL_O_BINARY);
|
||||
fd = curlx_open(actual_path, O_RDONLY | CURL_O_BINARY);
|
||||
file->path = actual_path;
|
||||
#else
|
||||
if(memchr(real_path, 0, real_path_len)) {
|
||||
@@ -261,16 +257,16 @@ static CURLcode file_connect(struct Curl_easy *data, bool *done)
|
||||
extern int __unix_path_semantics;
|
||||
if(strchr(real_path + 1, ':')) {
|
||||
/* Amiga absolute path */
|
||||
fd = open(real_path + 1, O_RDONLY);
|
||||
fd = curlx_open(real_path + 1, O_RDONLY);
|
||||
file->path++;
|
||||
}
|
||||
else if(__unix_path_semantics) {
|
||||
/* -lunix fallback */
|
||||
fd = open(real_path, O_RDONLY);
|
||||
fd = curlx_open(real_path, O_RDONLY);
|
||||
}
|
||||
}
|
||||
#else
|
||||
fd = open(real_path, O_RDONLY);
|
||||
fd = curlx_open(real_path, O_RDONLY);
|
||||
file->path = real_path;
|
||||
#endif
|
||||
#endif
|
||||
@@ -349,9 +345,9 @@ static CURLcode file_upload(struct Curl_easy *data,
|
||||
|
||||
#if (defined(ANDROID) || defined(__ANDROID__)) && \
|
||||
(defined(__i386__) || defined(__arm__))
|
||||
fd = open(file->path, mode, (mode_t)data->set.new_file_perms);
|
||||
fd = curlx_open(file->path, mode, (mode_t)data->set.new_file_perms);
|
||||
#else
|
||||
fd = open(file->path, mode, data->set.new_file_perms);
|
||||
fd = curlx_open(file->path, mode, data->set.new_file_perms);
|
||||
#endif
|
||||
if(fd < 0) {
|
||||
failf(data, "cannot open %s for writing", file->path);
|
||||
@@ -491,8 +487,8 @@ static CURLcode file_do(struct Curl_easy *data, bool *done)
|
||||
static const char accept_ranges[]= { "Accept-ranges: bytes\r\n" };
|
||||
if(expected_size >= 0) {
|
||||
headerlen =
|
||||
msnprintf(header, sizeof(header), "Content-Length: %" FMT_OFF_T "\r\n",
|
||||
expected_size);
|
||||
curl_msnprintf(header, sizeof(header),
|
||||
"Content-Length: %" FMT_OFF_T "\r\n", expected_size);
|
||||
result = Curl_client_write(data, CLIENTWRITE_HEADER, header, headerlen);
|
||||
if(result)
|
||||
return result;
|
||||
@@ -510,15 +506,15 @@ static CURLcode file_do(struct Curl_easy *data, bool *done)
|
||||
|
||||
/* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
|
||||
headerlen =
|
||||
msnprintf(header, sizeof(header),
|
||||
"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);
|
||||
curl_msnprintf(header, sizeof(header),
|
||||
"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(data, CLIENTWRITE_HEADER, header, headerlen);
|
||||
if(!result)
|
||||
/* end of headers */
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
|
||||
#ifndef CURL_DISABLE_FTP
|
||||
|
||||
#include "strdup.h"
|
||||
#include "fileinfo.h"
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
|
||||
@@ -37,9 +37,10 @@ struct Curl_easy;
|
||||
#include "sendf.h"
|
||||
#include "strdup.h"
|
||||
#include "rand.h"
|
||||
#include "curlx/fopen.h"
|
||||
#include "curlx/warnless.h"
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
@@ -771,20 +772,6 @@ static CURLcode setname(curl_mimepart *part, const char *name, size_t len)
|
||||
return res;
|
||||
}
|
||||
|
||||
/* wrap call to fseeko so it matches the calling convention of callback */
|
||||
static int fseeko_wrapper(void *stream, curl_off_t offset, int whence)
|
||||
{
|
||||
#if defined(_WIN32) && defined(USE_WIN32_LARGE_FILES)
|
||||
return _fseeki64(stream, (__int64)offset, whence);
|
||||
#elif defined(HAVE_FSEEKO) && defined(HAVE_DECL_FSEEKO)
|
||||
return fseeko(stream, (off_t)offset, whence);
|
||||
#else
|
||||
if(offset > LONG_MAX)
|
||||
return -1;
|
||||
return fseek(stream, (long)offset, whence);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_getformdata() converts a linked list of "meta data" into a mime
|
||||
* structure. The input list is in 'post', while the output is stored in
|
||||
@@ -868,10 +855,17 @@ CURLcode Curl_getformdata(CURL *data,
|
||||
particular, freopen(stdin) by the caller is not guaranteed
|
||||
to result as expected. This feature has been kept for backward
|
||||
compatibility: use of "-" pseudo filename should be avoided. */
|
||||
#if defined(__clang__) && __clang_major__ >= 16
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wcast-function-type-strict"
|
||||
#endif
|
||||
result = curl_mime_data_cb(part, (curl_off_t) -1,
|
||||
(curl_read_callback) fread,
|
||||
fseeko_wrapper,
|
||||
curlx_fseek,
|
||||
NULL, (void *) stdin);
|
||||
#if defined(__clang__) && __clang_major__ >= 16
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
}
|
||||
else
|
||||
result = curl_mime_filedata(part, file->contents);
|
||||
|
||||
+191
-227
@@ -53,13 +53,11 @@
|
||||
#include "fileinfo.h"
|
||||
#include "ftplistparser.h"
|
||||
#include "curl_range.h"
|
||||
#include "curl_krb5.h"
|
||||
#include "strcase.h"
|
||||
#include "vtls/vtls.h"
|
||||
#include "cfilters.h"
|
||||
#include "cf-socket.h"
|
||||
#include "connect.h"
|
||||
#include "strerror.h"
|
||||
#include "curlx/inet_ntop.h"
|
||||
#include "curlx/inet_pton.h"
|
||||
#include "select.h"
|
||||
@@ -72,9 +70,10 @@
|
||||
#include "http_proxy.h"
|
||||
#include "socks.h"
|
||||
#include "strdup.h"
|
||||
#include "curlx/strerr.h"
|
||||
#include "curlx/strparse.h"
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
@@ -142,11 +141,11 @@ static const char * const ftp_state_names[]={
|
||||
#endif /* !CURL_DISABLE_VERBOSE_STRINGS */
|
||||
|
||||
/* This is the ONLY way to change FTP state! */
|
||||
static void _ftp_state(struct Curl_easy *data,
|
||||
struct ftp_conn *ftpc,
|
||||
ftpstate newstate
|
||||
static void ftp_state_low(struct Curl_easy *data,
|
||||
struct ftp_conn *ftpc,
|
||||
ftpstate newstate
|
||||
#ifdef DEBUGBUILD
|
||||
, int lineno
|
||||
, int lineno
|
||||
#endif
|
||||
)
|
||||
{
|
||||
@@ -172,9 +171,9 @@ static void _ftp_state(struct Curl_easy *data,
|
||||
|
||||
/* Local API functions */
|
||||
#ifndef DEBUGBUILD
|
||||
#define ftp_state(x,y,z) _ftp_state(x,y,z)
|
||||
#define ftp_state(x,y,z) ftp_state_low(x,y,z)
|
||||
#else /* !DEBUGBUILD */
|
||||
#define ftp_state(x,y,z) _ftp_state(x,y,z,__LINE__)
|
||||
#define ftp_state(x,y,z) ftp_state_low(x,y,z,__LINE__)
|
||||
#endif /* DEBUGBUILD */
|
||||
|
||||
static CURLcode ftp_sendquote(struct Curl_easy *data,
|
||||
@@ -272,7 +271,7 @@ const struct Curl_handler Curl_handler_ftp = {
|
||||
CURLPROTO_FTP, /* family */
|
||||
PROTOPT_DUAL | PROTOPT_CLOSEACTION | PROTOPT_NEEDSPWD |
|
||||
PROTOPT_NOURLQUERY | PROTOPT_PROXY_AS_HTTP |
|
||||
PROTOPT_WILDCARD /* flags */
|
||||
PROTOPT_WILDCARD | PROTOPT_SSL_REUSE /* flags */
|
||||
};
|
||||
|
||||
|
||||
@@ -335,7 +334,6 @@ static void freedirs(struct ftp_conn *ftpc)
|
||||
ftpc->dirdepth = 0;
|
||||
Curl_safefree(ftpc->rawpath);
|
||||
ftpc->file = NULL;
|
||||
Curl_safefree(ftpc->newhost);
|
||||
}
|
||||
|
||||
#ifdef CURL_PREFER_LF_LINEENDS
|
||||
@@ -430,6 +428,10 @@ static const struct Curl_cwtype ftp_cw_lc = {
|
||||
};
|
||||
|
||||
#endif /* CURL_PREFER_LF_LINEENDS */
|
||||
|
||||
static CURLcode getftpresponse(struct Curl_easy *data, ssize_t *nread,
|
||||
int *ftpcode);
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* ftp_check_ctrl_on_data_wait()
|
||||
@@ -446,11 +448,14 @@ static CURLcode ftp_check_ctrl_on_data_wait(struct Curl_easy *data,
|
||||
bool response = FALSE;
|
||||
|
||||
/* First check whether there is a cached response from server */
|
||||
if(curlx_dyn_len(&pp->recvbuf) && (*curlx_dyn_ptr(&pp->recvbuf) > '3')) {
|
||||
/* Data connection could not be established, let's return */
|
||||
infof(data, "There is negative response in cache while serv connect");
|
||||
(void)Curl_GetFTPResponse(data, &nread, &ftpcode);
|
||||
return CURLE_FTP_ACCEPT_FAILED;
|
||||
if(curlx_dyn_len(&pp->recvbuf)) {
|
||||
const char *l = curlx_dyn_ptr(&pp->recvbuf);
|
||||
if(!ISDIGIT(*l) || (*l > '3')) {
|
||||
/* Data connection could not be established, let's return */
|
||||
infof(data, "There is negative response in cache while serv connect");
|
||||
(void)getftpresponse(data, &nread, &ftpcode);
|
||||
return CURLE_FTP_ACCEPT_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
if(pp->overflow)
|
||||
@@ -476,13 +481,14 @@ static CURLcode ftp_check_ctrl_on_data_wait(struct Curl_easy *data,
|
||||
infof(data, "Ctrl conn has data while waiting for data conn");
|
||||
if(pp->overflow > 3) {
|
||||
const char *r = curlx_dyn_ptr(&pp->recvbuf);
|
||||
size_t len = curlx_dyn_len(&pp->recvbuf);
|
||||
|
||||
DEBUGASSERT((pp->overflow + pp->nfinal) <=
|
||||
curlx_dyn_len(&pp->recvbuf));
|
||||
DEBUGASSERT((pp->overflow + pp->nfinal) <= curlx_dyn_len(&pp->recvbuf));
|
||||
/* move over the most recently handled response line */
|
||||
r += pp->nfinal;
|
||||
len -= pp->nfinal;
|
||||
|
||||
if(LASTLINE(r)) {
|
||||
if((len > 3) && LASTLINE(r)) {
|
||||
curl_off_t status;
|
||||
if(!curlx_str_number(&r, &status, 999) && (status == 226)) {
|
||||
/* funny timing situation where we get the final message on the
|
||||
@@ -495,7 +501,7 @@ static CURLcode ftp_check_ctrl_on_data_wait(struct Curl_easy *data,
|
||||
}
|
||||
}
|
||||
|
||||
(void)Curl_GetFTPResponse(data, &nread, &ftpcode);
|
||||
(void)getftpresponse(data, &nread, &ftpcode);
|
||||
|
||||
infof(data, "FTP code: %03d", ftpcode);
|
||||
|
||||
@@ -527,7 +533,7 @@ static CURLcode ftp_initiate_transfer(struct Curl_easy *data,
|
||||
if(result || !connected)
|
||||
return result;
|
||||
|
||||
if(ftpc->state_saved == FTP_STOR) {
|
||||
if(data->state.upload) {
|
||||
/* When we know we are uploading a specified file, we can get the file
|
||||
size prior to the actual upload. */
|
||||
Curl_pgrsSetUploadSize(data, data->state.infilesize);
|
||||
@@ -542,7 +548,7 @@ static CURLcode ftp_initiate_transfer(struct Curl_easy *data,
|
||||
}
|
||||
else {
|
||||
/* FTP download, shutdown, do not ignore errors */
|
||||
Curl_xfer_setup_recv(data, SECONDARYSOCKET, ftpc->retr_size_saved);
|
||||
Curl_xfer_setup_recv(data, SECONDARYSOCKET, data->req.size);
|
||||
Curl_xfer_set_shutdown(data, TRUE, FALSE);
|
||||
}
|
||||
|
||||
@@ -577,28 +583,6 @@ static CURLcode ftp_readresp(struct Curl_easy *data,
|
||||
int code;
|
||||
CURLcode result = Curl_pp_readresp(data, sockindex, pp, &code, size);
|
||||
DEBUGASSERT(ftpcodep);
|
||||
#ifdef HAVE_GSSAPI
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
char * const buf = curlx_dyn_ptr(&ftpc->pp.recvbuf);
|
||||
|
||||
/* handle the security-oriented responses 6xx ***/
|
||||
switch(code) {
|
||||
case 631:
|
||||
code = Curl_sec_read_msg(data, conn, buf, PROT_SAFE);
|
||||
break;
|
||||
case 632:
|
||||
code = Curl_sec_read_msg(data, conn, buf, PROT_PRIVATE);
|
||||
break;
|
||||
case 633:
|
||||
code = Curl_sec_read_msg(data, conn, buf, PROT_CONFIDENTIAL);
|
||||
break;
|
||||
default:
|
||||
/* normal ftp stuff we pass through! */
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* store the latest code for later retrieval, except during shutdown */
|
||||
if(!ftpc->shutdown)
|
||||
@@ -625,14 +609,14 @@ static CURLcode ftp_readresp(struct Curl_easy *data,
|
||||
/* --- parse FTP server responses --- */
|
||||
|
||||
/*
|
||||
* Curl_GetFTPResponse() is a BLOCKING function to read the full response
|
||||
* from a server after a command.
|
||||
* getftpresponse() is a BLOCKING function to read the full response from a
|
||||
* server after a command.
|
||||
*
|
||||
*/
|
||||
|
||||
CURLcode Curl_GetFTPResponse(struct Curl_easy *data,
|
||||
ssize_t *nreadp, /* return number of bytes read */
|
||||
int *ftpcodep) /* return the ftp-code */
|
||||
static CURLcode getftpresponse(struct Curl_easy *data,
|
||||
ssize_t *nreadp, /* return number of bytes
|
||||
read */
|
||||
int *ftpcodep) /* return the ftp-code */
|
||||
{
|
||||
/*
|
||||
* We cannot read just one byte per read() and then go back to select() as
|
||||
@@ -650,7 +634,7 @@ CURLcode Curl_GetFTPResponse(struct Curl_easy *data,
|
||||
int cache_skip = 0;
|
||||
DEBUGASSERT(ftpcodep);
|
||||
|
||||
CURL_TRC_FTP(data, "getFTPResponse start");
|
||||
CURL_TRC_FTP(data, "getftpresponse start");
|
||||
*nreadp = 0;
|
||||
*ftpcodep = 0; /* 0 for errors */
|
||||
|
||||
@@ -733,7 +717,7 @@ CURLcode Curl_GetFTPResponse(struct Curl_easy *data,
|
||||
} /* while there is buffer left and loop is requested */
|
||||
|
||||
pp->pending_resp = FALSE;
|
||||
CURL_TRC_FTP(data, "getFTPResponse -> result=%d, nread=%zd, ftpcode=%d",
|
||||
CURL_TRC_FTP(data, "getftpresponse -> result=%d, nread=%zd, ftpcode=%d",
|
||||
result, *nreadp, *ftpcodep);
|
||||
|
||||
return result;
|
||||
@@ -1026,7 +1010,7 @@ static CURLcode ftp_state_use_port(struct Curl_easy *data,
|
||||
sslen = sizeof(ss);
|
||||
if(getsockname(conn->sock[FIRSTSOCKET], sa, &sslen)) {
|
||||
failf(data, "getsockname() failed: %s",
|
||||
Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
|
||||
curlx_strerror(SOCKERRNO, buffer, sizeof(buffer)));
|
||||
goto out;
|
||||
}
|
||||
switch(sa->sa_family) {
|
||||
@@ -1073,7 +1057,7 @@ static CURLcode ftp_state_use_port(struct Curl_easy *data,
|
||||
}
|
||||
if(!ai) {
|
||||
failf(data, "socket failure: %s",
|
||||
Curl_strerror(error, buffer, sizeof(buffer)));
|
||||
curlx_strerror(error, buffer, sizeof(buffer)));
|
||||
goto out;
|
||||
}
|
||||
CURL_TRC_FTP(data, "[%s] ftp_state_use_port(), opened socket",
|
||||
@@ -1100,12 +1084,12 @@ static CURLcode ftp_state_use_port(struct Curl_easy *data,
|
||||
* the control connection instead and restart the port loop
|
||||
*/
|
||||
infof(data, "bind(port=%hu) on non-local address failed: %s", port,
|
||||
Curl_strerror(error, buffer, sizeof(buffer)));
|
||||
curlx_strerror(error, buffer, sizeof(buffer)));
|
||||
|
||||
sslen = sizeof(ss);
|
||||
if(getsockname(conn->sock[FIRSTSOCKET], sa, &sslen)) {
|
||||
failf(data, "getsockname() failed: %s",
|
||||
Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
|
||||
curlx_strerror(SOCKERRNO, buffer, sizeof(buffer)));
|
||||
goto out;
|
||||
}
|
||||
port = port_min;
|
||||
@@ -1114,28 +1098,30 @@ static CURLcode ftp_state_use_port(struct Curl_easy *data,
|
||||
}
|
||||
if(error != SOCKEADDRINUSE && error != SOCKEACCES) {
|
||||
failf(data, "bind(port=%hu) failed: %s", port,
|
||||
Curl_strerror(error, buffer, sizeof(buffer)));
|
||||
curlx_strerror(error, buffer, sizeof(buffer)));
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
||||
/* check if port is the maximum value here, because it might be 0xffff and
|
||||
then the increment below will wrap the 16 bit counter */
|
||||
if(port == port_max) {
|
||||
/* maybe all ports were in use already */
|
||||
failf(data, "bind() failed, ran out of ports");
|
||||
goto out;
|
||||
}
|
||||
port++;
|
||||
}
|
||||
|
||||
/* maybe all ports were in use already */
|
||||
if(port > port_max) {
|
||||
failf(data, "bind() failed, we ran out of ports");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* get the name again after the bind() so that we can extract the
|
||||
port number it uses now */
|
||||
sslen = sizeof(ss);
|
||||
if(getsockname(portsock, sa, &sslen)) {
|
||||
failf(data, "getsockname() failed: %s",
|
||||
Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
|
||||
curlx_strerror(SOCKERRNO, buffer, sizeof(buffer)));
|
||||
goto out;
|
||||
}
|
||||
CURL_TRC_FTP(data, "[%s] ftp_state_use_port(), socket bound to port %d",
|
||||
@@ -1145,7 +1131,7 @@ static CURLcode ftp_state_use_port(struct Curl_easy *data,
|
||||
|
||||
if(listen(portsock, 1)) {
|
||||
failf(data, "socket failure: %s",
|
||||
Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
|
||||
curlx_strerror(SOCKERRNO, buffer, sizeof(buffer)));
|
||||
goto out;
|
||||
}
|
||||
CURL_TRC_FTP(data, "[%s] ftp_state_use_port(), listening on %d",
|
||||
@@ -1222,7 +1208,7 @@ static CURLcode ftp_state_use_port(struct Curl_easy *data,
|
||||
source++;
|
||||
}
|
||||
*dest = 0;
|
||||
msnprintf(dest, 20, ",%d,%d", (int)(port >> 8), (int)(port & 0xff));
|
||||
curl_msnprintf(dest, 20, ",%d,%d", (int)(port >> 8), (int)(port & 0xff));
|
||||
|
||||
result = Curl_pp_sendf(data, &ftpc->pp, "%s %s", mode[fcmd], target);
|
||||
if(result) {
|
||||
@@ -1435,12 +1421,12 @@ static CURLcode ftp_state_list(struct Curl_easy *data,
|
||||
}
|
||||
}
|
||||
|
||||
cmd = aprintf("%s%s%.*s",
|
||||
data->set.str[STRING_CUSTOMREQUEST] ?
|
||||
data->set.str[STRING_CUSTOMREQUEST] :
|
||||
(data->state.list_only ? "NLST" : "LIST"),
|
||||
lstArg ? " " : "",
|
||||
lstArglen, lstArg ? lstArg : "");
|
||||
cmd = curl_maprintf("%s%s%.*s",
|
||||
data->set.str[STRING_CUSTOMREQUEST] ?
|
||||
data->set.str[STRING_CUSTOMREQUEST] :
|
||||
(data->state.list_only ? "NLST" : "LIST"),
|
||||
lstArg ? " " : "",
|
||||
lstArglen, lstArg ? lstArg : "");
|
||||
|
||||
if(!cmd)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
@@ -1784,11 +1770,12 @@ static CURLcode ftp_epsv_disable(struct Curl_easy *data,
|
||||
}
|
||||
|
||||
|
||||
static char *control_address_dup(struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
static CURLcode ftp_control_addr_dup(struct Curl_easy *data,
|
||||
char **newhostp)
|
||||
{
|
||||
struct ip_quadruple ipquad;
|
||||
bool is_ipv6;
|
||||
struct connectdata *conn = data->conn;
|
||||
struct ip_quadruple ipquad;
|
||||
bool is_ipv6;
|
||||
|
||||
/* Returns the control connection IP address.
|
||||
If a proxy tunnel is used, returns the original hostname instead, because
|
||||
@@ -1796,11 +1783,19 @@ static char *control_address_dup(struct Curl_easy *data,
|
||||
not the ftp host. */
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
if(conn->bits.tunnel_proxy || conn->bits.socksproxy)
|
||||
return strdup(conn->host.name);
|
||||
*newhostp = strdup(conn->host.name);
|
||||
else
|
||||
#endif
|
||||
if(!Curl_conn_get_ip_info(data, conn, FIRSTSOCKET, &is_ipv6, &ipquad))
|
||||
return strdup(ipquad.remote_ip);
|
||||
return NULL;
|
||||
if(!Curl_conn_get_ip_info(data, conn, FIRSTSOCKET, &is_ipv6, &ipquad) &&
|
||||
*ipquad.remote_ip)
|
||||
*newhostp = strdup(ipquad.remote_ip);
|
||||
else {
|
||||
/* failed to get the remote_ip of the DATA connection */
|
||||
failf(data, "unable to get peername of DATA connection");
|
||||
*newhostp = NULL;
|
||||
return CURLE_FTP_CANT_GET_HOST;
|
||||
}
|
||||
return *newhostp ? CURLE_OK : CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
static bool match_pasv_6nums(const char *p,
|
||||
@@ -1830,12 +1825,11 @@ static CURLcode ftp_state_pasv_resp(struct Curl_easy *data,
|
||||
struct Curl_dns_entry *dns = NULL;
|
||||
unsigned short connectport; /* the local port connect() should use! */
|
||||
struct pingpong *pp = &ftpc->pp;
|
||||
char *newhost = NULL;
|
||||
unsigned short newport = 0;
|
||||
char *str =
|
||||
curlx_dyn_ptr(&pp->recvbuf) + 4; /* start on the first letter */
|
||||
|
||||
/* if we come here again, make sure the former name is cleared */
|
||||
Curl_safefree(ftpc->newhost);
|
||||
|
||||
if((ftpc->count1 == 0) &&
|
||||
(ftpcode == 229)) {
|
||||
/* positive EPSV response */
|
||||
@@ -1852,10 +1846,10 @@ static CURLcode ftp_state_pasv_resp(struct Curl_easy *data,
|
||||
failf(data, "Illegal port number in EPSV reply");
|
||||
return CURLE_FTP_WEIRD_PASV_REPLY;
|
||||
}
|
||||
ftpc->newport = (unsigned short)num;
|
||||
ftpc->newhost = control_address_dup(data, conn);
|
||||
if(!ftpc->newhost)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
newport = (unsigned short)num;
|
||||
result = ftp_control_addr_dup(data, &newhost);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
else
|
||||
ptr = NULL;
|
||||
@@ -1897,15 +1891,17 @@ static CURLcode ftp_state_pasv_resp(struct Curl_easy *data,
|
||||
infof(data, "Skip %u.%u.%u.%u for data connection, reuse %s instead",
|
||||
ip[0], ip[1], ip[2], ip[3],
|
||||
conn->host.name);
|
||||
ftpc->newhost = control_address_dup(data, conn);
|
||||
result = ftp_control_addr_dup(data, &newhost);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
else
|
||||
ftpc->newhost = aprintf("%u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]);
|
||||
newhost = curl_maprintf("%u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]);
|
||||
|
||||
if(!ftpc->newhost)
|
||||
if(!newhost)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
ftpc->newport = (unsigned short)(((ip[4] << 8) + ip[5]) & 0xffff);
|
||||
newport = (unsigned short)(((ip[4] << 8) + ip[5]) & 0xffff);
|
||||
}
|
||||
else if(ftpc->count1 == 0) {
|
||||
/* EPSV failed, move on to PASV */
|
||||
@@ -1929,7 +1925,7 @@ static CURLcode ftp_state_pasv_resp(struct Curl_easy *data,
|
||||
result = Curl_conn_get_ip_info(data, data->conn, FIRSTSOCKET,
|
||||
&is_ipv6, &ipquad);
|
||||
if(result)
|
||||
return result;
|
||||
goto error;
|
||||
|
||||
(void)Curl_resolv_blocking(data, host_name, ipquad.remote_port,
|
||||
is_ipv6 ? CURL_IPRESOLVE_V6 : CURL_IPRESOLVE_V4,
|
||||
@@ -1939,31 +1935,31 @@ static CURLcode ftp_state_pasv_resp(struct Curl_easy *data,
|
||||
|
||||
if(!dns) {
|
||||
failf(data, "cannot resolve proxy host %s:%hu", host_name, connectport);
|
||||
return CURLE_COULDNT_RESOLVE_PROXY;
|
||||
result = CURLE_COULDNT_RESOLVE_PROXY;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* normal, direct, ftp connection */
|
||||
DEBUGASSERT(ftpc->newhost);
|
||||
DEBUGASSERT(newhost);
|
||||
|
||||
/* postponed address resolution in case of tcp fastopen */
|
||||
if(conn->bits.tcp_fastopen && !conn->bits.reuse && !ftpc->newhost[0]) {
|
||||
free(ftpc->newhost);
|
||||
ftpc->newhost = control_address_dup(data, conn);
|
||||
if(!ftpc->newhost)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
if(conn->bits.tcp_fastopen && !conn->bits.reuse && !newhost[0]) {
|
||||
free(newhost);
|
||||
result = ftp_control_addr_dup(data, &newhost);
|
||||
if(result)
|
||||
goto error;
|
||||
}
|
||||
|
||||
(void)Curl_resolv_blocking(data, ftpc->newhost, ftpc->newport,
|
||||
conn->ip_version, &dns);
|
||||
connectport = ftpc->newport; /* we connect to the remote port */
|
||||
(void)Curl_resolv_blocking(data, newhost, newport, conn->ip_version, &dns);
|
||||
connectport = newport; /* we connect to the remote port */
|
||||
|
||||
if(!dns) {
|
||||
failf(data, "cannot resolve new host %s:%hu",
|
||||
ftpc->newhost, connectport);
|
||||
return CURLE_FTP_CANT_GET_HOST;
|
||||
failf(data, "cannot resolve new host %s:%hu", newhost, connectport);
|
||||
result = CURLE_FTP_CANT_GET_HOST;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1972,10 +1968,12 @@ static CURLcode ftp_state_pasv_resp(struct Curl_easy *data,
|
||||
CURL_CF_SSL_ENABLE : CURL_CF_SSL_DISABLE);
|
||||
|
||||
if(result) {
|
||||
if(ftpc->count1 == 0 && ftpcode == 229)
|
||||
if(ftpc->count1 == 0 && ftpcode == 229) {
|
||||
free(newhost);
|
||||
return ftp_epsv_disable(data, ftpc, conn);
|
||||
}
|
||||
|
||||
return result;
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
||||
@@ -1987,17 +1985,21 @@ static CURLcode ftp_state_pasv_resp(struct Curl_easy *data,
|
||||
|
||||
if(data->set.verbose)
|
||||
/* this just dumps information about this second connection */
|
||||
ftp_pasv_verbose(data, dns->addr, ftpc->newhost, connectport);
|
||||
ftp_pasv_verbose(data, dns->addr, newhost, connectport);
|
||||
|
||||
free(conn->secondaryhostname);
|
||||
conn->secondary_port = ftpc->newport;
|
||||
conn->secondaryhostname = strdup(ftpc->newhost);
|
||||
if(!conn->secondaryhostname)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
conn->secondary_port = newport;
|
||||
conn->secondaryhostname = strdup(newhost);
|
||||
if(!conn->secondaryhostname) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto error;
|
||||
}
|
||||
|
||||
conn->bits.do_more = TRUE;
|
||||
ftp_state(data, ftpc, FTP_STOP); /* this phase is completed */
|
||||
|
||||
error:
|
||||
free(newhost);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -2106,9 +2108,9 @@ static CURLcode ftp_state_mdtm_resp(struct Curl_easy *data,
|
||||
if(ftp_213_date(resp, &year, &month, &day, &hour, &minute, &second)) {
|
||||
/* we have a time, reformat it */
|
||||
char timebuf[24];
|
||||
msnprintf(timebuf, sizeof(timebuf),
|
||||
"%04d%02d%02d %02d:%02d:%02d GMT",
|
||||
year, month, day, hour, minute, second);
|
||||
curl_msnprintf(timebuf, sizeof(timebuf),
|
||||
"%04d%02d%02d %02d:%02d:%02d GMT",
|
||||
year, month, day, hour, minute, second);
|
||||
/* now, convert this into a time() value: */
|
||||
if(!Curl_getdate_capped(timebuf, &data->info.filetime))
|
||||
showtime = TRUE;
|
||||
@@ -2141,15 +2143,16 @@ static CURLcode ftp_state_mdtm_resp(struct Curl_easy *data,
|
||||
|
||||
/* format: "Tue, 15 Nov 1994 12:45:26" */
|
||||
headerbuflen =
|
||||
msnprintf(headerbuf, sizeof(headerbuf),
|
||||
"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);
|
||||
curl_msnprintf(headerbuf, sizeof(headerbuf),
|
||||
"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 = client_write_header(data, headerbuf, headerbuflen);
|
||||
if(result)
|
||||
return result;
|
||||
@@ -2336,7 +2339,7 @@ static CURLcode ftp_state_size_resp(struct Curl_easy *data,
|
||||
for all the digits at the end of the response and parse only those as a
|
||||
number. */
|
||||
char *start = &buf[4];
|
||||
const char *fdigit = memchr(start, '\r', len);
|
||||
const char *fdigit = memchr(start, '\r', len - 4);
|
||||
if(fdigit) {
|
||||
fdigit--;
|
||||
if(*fdigit == '\n')
|
||||
@@ -2362,8 +2365,9 @@ static CURLcode ftp_state_size_resp(struct Curl_easy *data,
|
||||
#ifdef CURL_FTP_HTTPSTYLE_HEAD
|
||||
if(filesize != -1) {
|
||||
char clbuf[128];
|
||||
int clbuflen = msnprintf(clbuf, sizeof(clbuf),
|
||||
"Content-Length: %" FMT_OFF_T "\r\n", filesize);
|
||||
int clbuflen = curl_msnprintf(clbuf, sizeof(clbuf),
|
||||
"Content-Length: %" FMT_OFF_T "\r\n",
|
||||
filesize);
|
||||
result = client_write_header(data, clbuf, clbuflen);
|
||||
if(result)
|
||||
return result;
|
||||
@@ -2424,19 +2428,16 @@ static CURLcode ftp_state_rest_resp(struct Curl_easy *data,
|
||||
|
||||
static CURLcode ftp_state_stor_resp(struct Curl_easy *data,
|
||||
struct ftp_conn *ftpc,
|
||||
int ftpcode, ftpstate instate)
|
||||
int ftpcode)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
if(ftpcode >= 400) {
|
||||
failf(data, "Failed FTP upload: %0d", ftpcode);
|
||||
ftp_state(data, ftpc, FTP_STOP);
|
||||
/* oops, we never close the sockets! */
|
||||
return CURLE_UPLOAD_FAILED;
|
||||
}
|
||||
|
||||
ftpc->state_saved = instate;
|
||||
|
||||
/* PORT means we are now awaiting the server to connect to us. */
|
||||
if(data->set.ftp_use_port) {
|
||||
bool connected;
|
||||
@@ -2485,7 +2486,7 @@ static CURLcode ftp_state_get_resp(struct Curl_easy *data,
|
||||
E:
|
||||
125 Data connection already open; Transfer starting. */
|
||||
|
||||
curl_off_t size = -1; /* default unknown size */
|
||||
data->req.size = -1; /* default unknown size */
|
||||
|
||||
|
||||
/*
|
||||
@@ -2508,49 +2509,35 @@ static CURLcode ftp_state_get_resp(struct Curl_easy *data,
|
||||
* those cases only confuses us.
|
||||
*
|
||||
* Example D above makes this parsing a little tricky */
|
||||
const char *bytes;
|
||||
char *buf = curlx_dyn_ptr(&ftpc->pp.recvbuf);
|
||||
bytes = strstr(buf, " bytes");
|
||||
if(bytes) {
|
||||
long in = (long)(--bytes-buf);
|
||||
/* this is a hint there is size information in there! ;-) */
|
||||
while(--in) {
|
||||
/* scan for the left parenthesis and break there */
|
||||
if('(' == *bytes)
|
||||
break;
|
||||
/* skip only digits */
|
||||
if(!ISDIGIT(*bytes)) {
|
||||
bytes = NULL;
|
||||
size_t len = curlx_dyn_len(&ftpc->pp.recvbuf);
|
||||
if(len >= 7) { /* "1 bytes" is 7 characters */
|
||||
size_t i;
|
||||
for(i = 0; i < len - 7; i++) {
|
||||
curl_off_t what;
|
||||
char *buf = curlx_dyn_ptr(&ftpc->pp.recvbuf);
|
||||
const char *c = &buf[i];
|
||||
if(!curlx_str_number(&c, &what, CURL_OFF_T_MAX) &&
|
||||
!curlx_str_single(&c, ' ') &&
|
||||
!strncmp(c, "bytes", 5)) {
|
||||
data->req.size = what;
|
||||
break;
|
||||
}
|
||||
/* one more estep backwards */
|
||||
bytes--;
|
||||
}
|
||||
/* if we have nothing but digits: */
|
||||
if(bytes) {
|
||||
++bytes;
|
||||
/* get the number! */
|
||||
if(curlx_str_number(&bytes, &size, CURL_OFF_T_MAX))
|
||||
size = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(ftp->downloadsize > -1)
|
||||
size = ftp->downloadsize;
|
||||
data->req.size = ftp->downloadsize;
|
||||
|
||||
if(size > data->req.maxdownload && data->req.maxdownload > 0)
|
||||
size = data->req.size = data->req.maxdownload;
|
||||
if(data->req.size > data->req.maxdownload && data->req.maxdownload > 0)
|
||||
data->req.size = data->req.maxdownload;
|
||||
else if((instate != FTP_LIST) && (data->state.prefer_ascii))
|
||||
size = -1; /* kludge for servers that understate ASCII mode file size */
|
||||
data->req.size = -1; /* for servers that understate ASCII mode file
|
||||
size */
|
||||
|
||||
infof(data, "Maxdownload = %" FMT_OFF_T, data->req.maxdownload);
|
||||
|
||||
if(instate != FTP_LIST)
|
||||
infof(data, "Getting file with size: %" FMT_OFF_T, size);
|
||||
|
||||
/* FTP download: */
|
||||
ftpc->state_saved = instate;
|
||||
ftpc->retr_size_saved = size;
|
||||
infof(data, "Getting file with size: %" FMT_OFF_T, data->req.size);
|
||||
|
||||
if(data->set.ftp_use_port) {
|
||||
bool connected;
|
||||
@@ -2629,7 +2616,7 @@ static CURLcode ftp_state_user_resp(struct Curl_easy *data,
|
||||
/* 331 Password required for ...
|
||||
(the server requires to send the user's password too) */
|
||||
result = Curl_pp_sendf(data, &ftpc->pp, "PASS %s",
|
||||
data->conn->passwd ? data->conn->passwd : "");
|
||||
data->conn->passwd);
|
||||
if(!result)
|
||||
ftp_state(data, ftpc, FTP_PASS);
|
||||
}
|
||||
@@ -2812,25 +2799,6 @@ static CURLcode ftp_wait_resp(struct Curl_easy *data,
|
||||
return CURLE_WEIRD_SERVER_REPLY;
|
||||
}
|
||||
|
||||
/* We have received a 220 response fine, now we proceed. */
|
||||
#ifdef HAVE_GSSAPI
|
||||
if(data->set.krb) {
|
||||
/* If not anonymous login, try a secure login. Note that this
|
||||
procedure is still BLOCKING. */
|
||||
|
||||
Curl_sec_request_prot(conn, "private");
|
||||
/* We set private first as default, in case the line below fails to
|
||||
set a valid level */
|
||||
Curl_sec_request_prot(conn, data->set.str[STRING_KRB_LEVEL]);
|
||||
|
||||
if(Curl_sec_login(data, conn)) {
|
||||
failf(data, "secure login failed");
|
||||
return CURLE_WEIRD_SERVER_REPLY;
|
||||
}
|
||||
infof(data, "Authentication successful");
|
||||
}
|
||||
#endif
|
||||
|
||||
if(data->set.use_ssl && !conn->bits.ftp_use_control_ssl) {
|
||||
/* We do not have an SSL/TLS control connection yet, but FTPS is
|
||||
requested. Try an FTPS connection now */
|
||||
@@ -3169,7 +3137,7 @@ static CURLcode ftp_pp_statemachine(struct Curl_easy *data,
|
||||
break;
|
||||
|
||||
case FTP_STOR:
|
||||
result = ftp_state_stor_resp(data, ftpc, ftpcode, ftpc->state);
|
||||
result = ftp_state_stor_resp(data, ftpc, ftpcode);
|
||||
break;
|
||||
|
||||
case FTP_QUIT:
|
||||
@@ -3396,14 +3364,8 @@ static CURLcode ftp_done(struct Curl_easy *data, CURLcode status,
|
||||
* data has been transferred. This happens when doing through NATs etc that
|
||||
* abandon old silent connections.
|
||||
*/
|
||||
timediff_t old_time = pp->response_time;
|
||||
|
||||
pp->response_time = 60*1000; /* give it only a minute for now */
|
||||
pp->response = curlx_now(); /* timeout relative now */
|
||||
|
||||
result = Curl_GetFTPResponse(data, &nread, &ftpcode);
|
||||
|
||||
pp->response_time = old_time; /* set this back to previous value */
|
||||
result = getftpresponse(data, &nread, &ftpcode);
|
||||
|
||||
if(!nread && (CURLE_OPERATION_TIMEDOUT == result)) {
|
||||
failf(data, "control connection looks dead");
|
||||
@@ -3494,7 +3456,6 @@ static CURLcode ftp_done(struct Curl_easy *data, CURLcode status,
|
||||
*
|
||||
* BLOCKING
|
||||
*/
|
||||
|
||||
static
|
||||
CURLcode ftp_sendquote(struct Curl_easy *data,
|
||||
struct ftp_conn *ftpc,
|
||||
@@ -3525,7 +3486,7 @@ CURLcode ftp_sendquote(struct Curl_easy *data,
|
||||
result = Curl_pp_sendf(data, &ftpc->pp, "%s", cmd);
|
||||
if(!result) {
|
||||
pp->response = curlx_now(); /* timeout relative now */
|
||||
result = Curl_GetFTPResponse(data, &nread, &ftpcode);
|
||||
result = getftpresponse(data, &nread, &ftpcode);
|
||||
}
|
||||
if(result)
|
||||
return result;
|
||||
@@ -3617,7 +3578,6 @@ ftp_pasv_verbose(struct Curl_easy *data,
|
||||
* (which basically is only for when PASV is being sent to retry a failed
|
||||
* EPSV).
|
||||
*/
|
||||
|
||||
static CURLcode ftp_do_more(struct Curl_easy *data, int *completep)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
@@ -3632,6 +3592,9 @@ static CURLcode ftp_do_more(struct Curl_easy *data, int *completep)
|
||||
|
||||
if(!ftpc || !ftp)
|
||||
return CURLE_FAILED_INIT;
|
||||
|
||||
*completep = 0; /* default to stay in the state */
|
||||
|
||||
/* if the second connection has been set up, try to connect it fully
|
||||
* to the remote host. This may not complete at this time, for several
|
||||
* reasons:
|
||||
@@ -3650,7 +3613,6 @@ static CURLcode ftp_do_more(struct Curl_easy *data, int *completep)
|
||||
/* this is a EPSV connect failing, try PASV instead */
|
||||
return ftp_epsv_disable(data, ftpc, conn);
|
||||
}
|
||||
*completep = (int)complete;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -3781,7 +3743,6 @@ static CURLcode ftp_do_more(struct Curl_easy *data, int *completep)
|
||||
* This is the actual DO function for FTP. Get a file/directory according to
|
||||
* the options previously setup.
|
||||
*/
|
||||
|
||||
static
|
||||
CURLcode ftp_perform(struct Curl_easy *data,
|
||||
struct ftp_conn *ftpc,
|
||||
@@ -3972,7 +3933,7 @@ static CURLcode wc_statemach(struct Curl_easy *data,
|
||||
struct Curl_llist_node *head = Curl_llist_head(&wildcard->filelist);
|
||||
struct curl_fileinfo *finfo = Curl_node_elem(head);
|
||||
|
||||
char *tmp_path = aprintf("%s%s", wildcard->path, finfo->filename);
|
||||
char *tmp_path = curl_maprintf("%s%s", wildcard->path, finfo->filename);
|
||||
if(!tmp_path)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
@@ -4198,6 +4159,8 @@ static size_t numof_slashes(const char *str)
|
||||
return num;
|
||||
}
|
||||
|
||||
#define FTP_MAX_DIR_DEPTH 1000
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* ftp_parse_url_path()
|
||||
@@ -4271,7 +4234,7 @@ CURLcode ftp_parse_url_path(struct Curl_easy *data,
|
||||
/* number of entries to allocate for the 'dirs' array */
|
||||
size_t dirAlloc = numof_slashes(rawPath);
|
||||
|
||||
if(dirAlloc >= 1000)
|
||||
if(dirAlloc >= FTP_MAX_DIR_DEPTH)
|
||||
/* suspiciously deep dir hierarchy */
|
||||
return CURLE_URL_MALFORMAT;
|
||||
|
||||
@@ -4464,10 +4427,38 @@ static void ftp_conn_dtor(void *key, size_t klen, void *entry)
|
||||
free(ftpc);
|
||||
}
|
||||
|
||||
static void type_url_check(struct Curl_easy *data, struct FTP *ftp)
|
||||
{
|
||||
size_t len = strlen(ftp->path);
|
||||
/* FTP URLs support an extension like ";type=<typecode>" that
|
||||
* we will try to get now! */
|
||||
if((len >= 7) && !memcmp(&ftp->path[len - 7], ";type=", 6)) {
|
||||
char *type = &ftp->path[len - 7];
|
||||
char command = Curl_raw_toupper(type[6]);
|
||||
|
||||
*type = 0; /* cut it off */
|
||||
|
||||
switch(command) {
|
||||
case 'A': /* ASCII mode */
|
||||
data->state.prefer_ascii = TRUE;
|
||||
break;
|
||||
|
||||
case 'D': /* directory mode */
|
||||
data->state.list_only = TRUE;
|
||||
break;
|
||||
|
||||
case 'I': /* binary mode */
|
||||
default:
|
||||
/* switch off ASCII */
|
||||
data->state.prefer_ascii = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static CURLcode ftp_setup_connection(struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
char *type;
|
||||
struct FTP *ftp;
|
||||
CURLcode result = CURLE_OK;
|
||||
struct ftp_conn *ftpc;
|
||||
@@ -4502,34 +4493,7 @@ static CURLcode ftp_setup_connection(struct Curl_easy *data,
|
||||
|
||||
ftp->path = &data->state.up.path[1]; /* do not include the initial slash */
|
||||
|
||||
/* FTP URLs support an extension like ";type=<typecode>" that
|
||||
* we will try to get now! */
|
||||
type = strstr(ftp->path, ";type=");
|
||||
|
||||
if(!type)
|
||||
type = strstr(conn->host.rawalloc, ";type=");
|
||||
|
||||
if(type) {
|
||||
char command;
|
||||
*type = 0; /* it was in the middle of the hostname */
|
||||
command = Curl_raw_toupper(type[6]);
|
||||
|
||||
switch(command) {
|
||||
case 'A': /* ASCII mode */
|
||||
data->state.prefer_ascii = TRUE;
|
||||
break;
|
||||
|
||||
case 'D': /* directory mode */
|
||||
data->state.list_only = TRUE;
|
||||
break;
|
||||
|
||||
case 'I': /* binary mode */
|
||||
default:
|
||||
/* switch off ASCII */
|
||||
data->state.prefer_ascii = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
type_url_check(data, ftp);
|
||||
|
||||
/* get some initial data into the ftp struct */
|
||||
ftp->transfer = PPTRANSFER_BODY;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user