mirror of
https://github.com/cmclark00/retro-imager.git
synced 2025-05-18 16:05:21 +01:00
Move source files to /src
This commit is contained in:
parent
4daff1ba79
commit
033ff07abf
2685 changed files with 9 additions and 7 deletions
3
src/.gitignore
vendored
Normal file
3
src/.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
|
||||
dependencies/libarchive-3.4.2/build/pkgconfig/libarchive.pc
|
||||
CMakeLists.txt.user
|
292
src/CMakeLists.txt
Normal file
292
src/CMakeLists.txt
Normal file
|
@ -0,0 +1,292 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
# Copyright (C) 2020 Raspberry Pi Ltd
|
||||
|
||||
cmake_minimum_required(VERSION 3.9.4)
|
||||
if (APPLE)
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.13" CACHE STRING "" FORCE)
|
||||
endif()
|
||||
|
||||
project(rpi-imager LANGUAGES CXX C)
|
||||
set(IMAGER_VERSION_MAJOR 1)
|
||||
set(IMAGER_VERSION_MINOR 7)
|
||||
set(IMAGER_VERSION_STR "${IMAGER_VERSION_MAJOR}.${IMAGER_VERSION_MINOR}.1")
|
||||
set(IMAGER_VERSION_CSV "${IMAGER_VERSION_MAJOR},${IMAGER_VERSION_MINOR},1,0")
|
||||
add_definitions(-DIMAGER_VERSION_STR="${IMAGER_VERSION_STR}")
|
||||
add_definitions(-DIMAGER_VERSION_CSV=${IMAGER_VERSION_CSV})
|
||||
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
|
||||
# Adding headers explicity so they are displayed in Qt Creator
|
||||
set(HEADERS config.h imagewriter.h networkaccessmanagerfactory.h nan.h drivelistitem.h drivelistmodel.h drivelistmodelpollthread.h driveformatthread.h powersaveblocker.h cli.h
|
||||
downloadthread.h downloadextractthread.h localfileextractthread.h downloadstatstelemetry.h dependencies/mountutils/src/mountutils.hpp dependencies/sha256crypt/sha256crypt.h)
|
||||
|
||||
# Add dependencies
|
||||
if (APPLE)
|
||||
set_source_files_properties("icons/rpi-imager.icns" PROPERTIES MACOSX_PACKAGE_LOCATION "Resources")
|
||||
set(DEPENDENCIES acceleratedcryptographichash.cpp mac/macfile.cpp mac/macfile.h dependencies/mountutils/src/darwin/functions.cpp
|
||||
dependencies/drivelist/src/darwin/list.mm dependencies/drivelist/src/darwin/REDiskList.m icons/rpi-imager.icns)
|
||||
enable_language(OBJC C)
|
||||
elseif (UNIX)
|
||||
set(DEPENDENCIES acceleratedcryptographichash.cpp dependencies/mountutils/src/linux/functions.cpp linux/linuxdrivelist.cpp)
|
||||
find_package(Qt5DBus)
|
||||
if(Qt5DBus_FOUND)
|
||||
set(DEPENDENCIES ${DEPENDENCIES} linux/udisks2api.cpp linux/udisks2api.h)
|
||||
set(EXTRALIBS Qt5::DBus)
|
||||
message("udisks2 support enabled")
|
||||
else()
|
||||
message("DBUS not found. Disabling udisks2 support")
|
||||
endif()
|
||||
find_package(ZLIB)
|
||||
if(ZLIB_FOUND)
|
||||
set(EXTRALIBS ${EXTRALIBS} ZLIB::ZLIB)
|
||||
endif()
|
||||
find_package(LibLZMA)
|
||||
if(LIBLZMA_FOUND)
|
||||
set(EXTRALIBS ${EXTRALIBS} LibLZMA::LibLZMA)
|
||||
endif()
|
||||
elseif (WIN32)
|
||||
set(DEPENDENCIES acceleratedcryptographichash.cpp dependencies/mountutils/src/windows/functions.cpp dependencies/drivelist/src/windows/list.cpp
|
||||
windows/winfile.cpp windows/winfile.h
|
||||
windows/rpi-imager.rc)
|
||||
find_package(Qt5WinExtras REQUIRED)
|
||||
set(EXTRALIBS setupapi wlanapi Qt5::WinExtras)
|
||||
endif()
|
||||
|
||||
include_directories(BEFORE .)
|
||||
|
||||
# Test if we need libatomic
|
||||
include(CheckCXXSourceCompiles)
|
||||
check_cxx_source_compiles("
|
||||
#include <atomic>
|
||||
#include <stdint.h>
|
||||
int main() {
|
||||
std::atomic<int64_t> x;
|
||||
x = 1;
|
||||
return (int) x;
|
||||
}"
|
||||
atomicbuiltin)
|
||||
|
||||
if (NOT atomicbuiltin)
|
||||
find_library(ATOMIC_LIBRARY NAMES atomic libatomic.so.1)
|
||||
if (NOT ATOMIC_LIBRARY)
|
||||
message( FATAL_ERROR "Missing libatomic while architecture does need it" )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(SOURCES "main.cpp" "imagewriter.cpp" "networkaccessmanagerfactory.cpp"
|
||||
"drivelistitem.cpp" "drivelistmodel.cpp" "drivelistmodelpollthread.cpp" "downloadthread.cpp" "downloadextractthread.cpp"
|
||||
"driveformatthread.cpp" "localfileextractthread.cpp" "powersaveblocker.cpp" "downloadstatstelemetry.cpp" "qml.qrc" "dependencies/sha256crypt/sha256crypt.c" "cli.cpp")
|
||||
|
||||
find_package(Qt5 COMPONENTS Core Quick LinguistTools Svg OPTIONAL_COMPONENTS Widgets)
|
||||
if (Qt5Widgets_FOUND)
|
||||
set(EXTRALIBS ${EXTRALIBS} Qt5::Widgets)
|
||||
endif()
|
||||
|
||||
#qt5_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} i18n/rpi-imager_en.ts i18n/rpi-imager_nl.ts i18n/rpi-imager_zh.ts i18n/rpi-imager_tr.ts i18n/rpi-imager_fr.ts i18n/rpi-imager_de.ts i18n/rpi-imager_sk.ts i18n/rpi-imager_it.ts i18n/rpi-imager_ca.ts i18n/rpi-imager_sl.ts)
|
||||
qt5_add_translation(QM_FILES i18n/rpi-imager_en.ts i18n/rpi-imager_nl.ts i18n/rpi-imager_zh.ts i18n/rpi-imager_tr.ts i18n/rpi-imager_fr.ts i18n/rpi-imager_de.ts i18n/rpi-imager_sk.ts i18n/rpi-imager_it.ts i18n/rpi-imager_ca.ts i18n/rpi-imager_sl.ts)
|
||||
configure_file(i18n/translations.qrc "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY)
|
||||
set(SOURCES ${SOURCES} ${CMAKE_CURRENT_BINARY_DIR}/translations.qrc ${QM_FILES})
|
||||
|
||||
if (WIN32)
|
||||
# Adding WIN32 prevents a console window being opened on Windows
|
||||
add_executable(${PROJECT_NAME} WIN32 ${SOURCES} ${HEADERS} ${DEPENDENCIES})
|
||||
else()
|
||||
add_executable(${PROJECT_NAME} ${SOURCES} ${HEADERS} ${DEPENDENCIES})
|
||||
endif()
|
||||
|
||||
# Enable link time optimization if available
|
||||
include(CheckIPOSupported)
|
||||
check_ipo_supported(RESULT iposupported OUTPUT ipoerror)
|
||||
|
||||
if(iposupported)
|
||||
message("Enabled LTO")
|
||||
set_property(TARGET ${PROJECT_NAME} PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
|
||||
else()
|
||||
message(STATUS "LTO not supported: <${ipoerror}>")
|
||||
endif()
|
||||
|
||||
# Because dependencies are typically not available by default on Windows, build bundled code
|
||||
if (WIN32)
|
||||
# Target Windows 7 (needed for drivelist module)
|
||||
add_definitions(-DWINVER=0x0601 -D_WIN32_WINNT=0x0601)
|
||||
|
||||
find_package(OpenSSL REQUIRED)
|
||||
|
||||
# Bundled zlib
|
||||
add_subdirectory(dependencies/zlib-1.2.11)
|
||||
set(ZLIB_LIBRARY zlibstatic)
|
||||
set(ZLIB_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/dependencies/zlib-1.2.11)
|
||||
|
||||
# Bundled libcurl
|
||||
set(CMAKE_CURL_INCLUDES)
|
||||
set(CURL_LIBRARIES cmcurl)
|
||||
add_subdirectory(dependencies/cmcurl)
|
||||
set(CURL_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/dependencies/cmcurl/include)
|
||||
|
||||
# Bundled liblzma
|
||||
add_subdirectory(dependencies/cmliblzma)
|
||||
set(LIBLZMA_HAS_AUTO_DECODER 1)
|
||||
set(LIBLZMA_HAS_EASY_ENCODER 1)
|
||||
set(LIBLZMA_HAS_LZMA_PRESET 1)
|
||||
set(LIBLZMA_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/dependencies/cmliblzma/liblzma/api)
|
||||
set(LIBLZMA_LIBRARY cmliblzma)
|
||||
|
||||
# Bundled zstd
|
||||
set(ZSTD_BUILD_PROGRAMS OFF)
|
||||
set(ZSTD_BUILD_SHARED OFF)
|
||||
add_subdirectory(dependencies/zstd-1.5.0/build/cmake)
|
||||
set(ZSTD_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/dependencies/zstd-1.5.0/lib)
|
||||
set(ZSTD_LIBRARY libzstd_static)
|
||||
|
||||
# Bundled libarchive
|
||||
set(ENABLE_TEST OFF CACHE BOOL "")
|
||||
set(ENABLE_TAR OFF CACHE BOOL "")
|
||||
set(ENABLE_CPIO OFF CACHE BOOL "")
|
||||
set(ENABLE_CAT OFF CACHE BOOL "")
|
||||
add_subdirectory(dependencies/libarchive-3.5.2)
|
||||
set(LibArchive_LIBRARIES archive_static)
|
||||
set(LibArchive_INCLUDE_DIR dependencies/libarchive-3.5.2/libarchive)
|
||||
|
||||
# Bundled fat32format
|
||||
add_subdirectory(dependencies/fat32format)
|
||||
add_dependencies(${PROJECT_NAME} fat32format)
|
||||
|
||||
# Strip debug symbols
|
||||
add_custom_command(TARGET ${PROJECT_NAME}
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_STRIP} "${CMAKE_BINARY_DIR}/${PROJECT_NAME}.exe")
|
||||
|
||||
# Code signing
|
||||
find_program(SIGNTOOL "signtool.exe" PATHS "c:/Program Files (x86)/Microsoft SDKs/ClickOnce/SignTool")
|
||||
if (NOT SIGNTOOL)
|
||||
message(FATAL_ERROR "Unable to locate signtool.exe used for code signing")
|
||||
endif()
|
||||
|
||||
add_custom_command(TARGET ${PROJECT_NAME}
|
||||
POST_BUILD
|
||||
COMMAND "${SIGNTOOL}" sign /tr http://timestamp.digicert.com /td sha256 /fd sha256 /a "${CMAKE_BINARY_DIR}/${PROJECT_NAME}.exe")
|
||||
|
||||
add_custom_command(TARGET ${PROJECT_NAME}
|
||||
POST_BUILD
|
||||
COMMAND "${SIGNTOOL}" sign /tr http://timestamp.digicert.com /td sha256 /fd sha256 /a "${CMAKE_BINARY_DIR}/dependencies/fat32format/fat32format.exe")
|
||||
|
||||
# Windeploy
|
||||
find_program(WINDEPLOYQT "windeployqt.exe" PATHS "${Qt5_DIR}/../../../bin")
|
||||
if (NOT WINDEPLOYQT)
|
||||
message(FATAL_ERROR "Unable to locate windeployqt.exe")
|
||||
endif()
|
||||
|
||||
file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/deploy")
|
||||
|
||||
add_custom_command(TARGET ${PROJECT_NAME}
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
"${CMAKE_BINARY_DIR}/${PROJECT_NAME}.exe" "${CMAKE_BINARY_DIR}/dependencies/fat32format/fat32format.exe"
|
||||
"${CMAKE_SOURCE_DIR}/license.txt" "${CMAKE_SOURCE_DIR}/windows/rpi-imager-cli.cmd"
|
||||
"${CMAKE_BINARY_DIR}/deploy")
|
||||
|
||||
add_custom_command(TARGET ${PROJECT_NAME}
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
"${Qt5_DIR}/../../../bin/libssl-1_1.dll" "${Qt5_DIR}/../../../bin/libcrypto-1_1.dll"
|
||||
"${CMAKE_BINARY_DIR}/deploy")
|
||||
|
||||
configure_file(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/windows/rpi-imager.nsi.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/rpi-imager.nsi"
|
||||
@ONLY)
|
||||
|
||||
add_custom_command(TARGET ${PROJECT_NAME}
|
||||
POST_BUILD
|
||||
COMMAND "${WINDEPLOYQT}" --no-translations --no-webkit2 --no-opengl-sw --angle --qmldir "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_BINARY_DIR}/deploy/rpi-imager.exe")
|
||||
|
||||
# Remove excess files
|
||||
add_custom_command(TARGET ${PROJECT_NAME}
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E remove
|
||||
"${CMAKE_BINARY_DIR}/deploy/imageformats/qtiff.dll"
|
||||
"${CMAKE_BINARY_DIR}/deploy/imageformats/qwebp.dll"
|
||||
"${CMAKE_BINARY_DIR}/deploy/imageformats/qgif.dll")
|
||||
|
||||
elseif(APPLE)
|
||||
find_package(ZLIB REQUIRED)
|
||||
find_package(CURL REQUIRED)
|
||||
|
||||
# Bundled liblzma
|
||||
add_subdirectory(dependencies/cmliblzma)
|
||||
set(LIBLZMA_HAS_AUTO_DECODER 1)
|
||||
set(LIBLZMA_HAS_EASY_ENCODER 1)
|
||||
set(LIBLZMA_HAS_LZMA_PRESET 1)
|
||||
set(LIBLZMA_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/dependencies/cmliblzma/liblzma/api)
|
||||
set(LIBLZMA_LIBRARY cmliblzma)
|
||||
|
||||
# Bundled zstd
|
||||
set(ZSTD_BUILD_PROGRAMS OFF)
|
||||
set(ZSTD_BUILD_SHARED OFF)
|
||||
add_subdirectory(dependencies/zstd-1.5.0/build/cmake)
|
||||
set(ZSTD_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/dependencies/zstd-1.5.0/lib)
|
||||
set(ZSTD_LIBRARY libzstd_static)
|
||||
|
||||
# Bundled libarchive
|
||||
set(ENABLE_TEST OFF CACHE BOOL "")
|
||||
set(ENABLE_TAR OFF CACHE BOOL "")
|
||||
set(ENABLE_CPIO OFF CACHE BOOL "")
|
||||
set(ENABLE_CAT OFF CACHE BOOL "")
|
||||
add_subdirectory(dependencies/libarchive-3.5.2)
|
||||
set(LibArchive_LIBRARIES archive_static)
|
||||
set(LibArchive_INCLUDE_DIR dependencies/libarchive-3.5.2/libarchive)
|
||||
|
||||
find_library(Cocoa Cocoa)
|
||||
find_library(CoreFoundation CoreFoundation)
|
||||
find_library(DiskArbitration DiskArbitration)
|
||||
find_library(Security Security)
|
||||
set(EXTRALIBS ${EXTRALIBS} ${CoreFoundation} ${DiskArbitration} ${Security} ${Cocoa})
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES MACOSX_BUNDLE YES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/mac/Info.plist.in)
|
||||
|
||||
find_program(MACDEPLOYQT "macdeployqt" PATHS "${Qt5_DIR}/../../../bin")
|
||||
if (NOT MACDEPLOYQT)
|
||||
message(FATAL_ERROR "Unable to locate macdeployqt")
|
||||
endif()
|
||||
|
||||
add_custom_command(TARGET ${PROJECT_NAME}
|
||||
POST_BUILD
|
||||
COMMAND "${MACDEPLOYQT}" "${CMAKE_BINARY_DIR}/${PROJECT_NAME}.app" -qmldir="${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
|
||||
else()
|
||||
find_package(CURL 7.32.0 REQUIRED)
|
||||
find_package(LibArchive 3.2.0 REQUIRED)
|
||||
find_package(OpenSSL REQUIRED)
|
||||
if (NOT CMAKE_CROSSCOMPILING)
|
||||
find_program(LSBLK "lsblk")
|
||||
if (NOT LSBLK)
|
||||
message(FATAL_ERROR "Unable to locate lsblk (used for disk enumeration)")
|
||||
endif()
|
||||
|
||||
execute_process(COMMAND "${LSBLK}" "--json" RESULT_VARIABLE ret)
|
||||
if (ret EQUAL "1")
|
||||
message(FATAL_ERROR "util-linux package too old. lsblk does not support --json (used for disk enumeration)")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
configure_file(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/linux/rpi-imager.metainfo.xml.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/rpi-imager.metainfo.xml"
|
||||
@ONLY)
|
||||
|
||||
install(TARGETS rpi-imager DESTINATION bin)
|
||||
install(FILES icons/rpi-imager.png DESTINATION share/icons/hicolor/128x128/apps)
|
||||
install(FILES linux/rpi-imager.desktop DESTINATION share/applications)
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/rpi-imager.metainfo.xml" DESTINATION share/metainfo)
|
||||
endif()
|
||||
|
||||
get_target_property(QT_TARGET_TYPE Qt5::Core TYPE)
|
||||
if(${QT_TARGET_TYPE} STREQUAL "STATIC_LIBRARY")
|
||||
find_package(Qt5QmlImportScanner REQUIRED)
|
||||
qt5_import_qml_plugins(${PROJECT_NAME})
|
||||
qt5_import_plugins(${PROJECT_NAME} INCLUDE Qt5::QSvgPlugin)
|
||||
endif()
|
||||
|
||||
include_directories(${CURL_INCLUDE_DIR} ${LibArchive_INCLUDE_DIR} ${OPENSSL_INCLUDE_DIR})
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Core Qt5::Quick Qt5::Svg ${CURL_LIBRARIES} ${LibArchive_LIBRARIES} ${OPENSSL_LIBRARIES} ${ATOMIC_LIBRARY} ${EXTRALIBS})
|
149
src/MsgPopup.qml
Normal file
149
src/MsgPopup.qml
Normal file
|
@ -0,0 +1,149 @@
|
|||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright (C) 2020 Raspberry Pi Ltd
|
||||
*/
|
||||
|
||||
import QtQuick 2.9
|
||||
import QtQuick.Controls 2.2
|
||||
import QtQuick.Layouts 1.0
|
||||
import QtQuick.Controls.Material 2.2
|
||||
import "qmlcomponents"
|
||||
|
||||
Popup {
|
||||
id: msgpopup
|
||||
x: 75
|
||||
y: (parent.height-height)/2
|
||||
width: parent.width-150
|
||||
height: msgpopupbody.implicitHeight+150
|
||||
padding: 0
|
||||
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
|
||||
|
||||
property alias title: msgpopupheader.text
|
||||
property alias text: msgpopupbody.text
|
||||
property bool continueButton: true
|
||||
property bool quitButton: false
|
||||
property bool yesButton: false
|
||||
property bool noButton: false
|
||||
signal yes()
|
||||
signal no()
|
||||
|
||||
// background of title
|
||||
Rectangle {
|
||||
color: "#f5f5f5"
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
height: 35
|
||||
width: parent.width
|
||||
}
|
||||
// line under title
|
||||
Rectangle {
|
||||
color: "#afafaf"
|
||||
width: parent.width
|
||||
y: 35
|
||||
implicitHeight: 1
|
||||
}
|
||||
|
||||
Text {
|
||||
id: msgx
|
||||
text: "X"
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
anchors.rightMargin: 25
|
||||
anchors.topMargin: 10
|
||||
font.family: roboto.name
|
||||
font.bold: true
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
msgpopup.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
spacing: 20
|
||||
anchors.fill: parent
|
||||
|
||||
Text {
|
||||
id: msgpopupheader
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 10
|
||||
font.family: roboto.name
|
||||
font.bold: true
|
||||
}
|
||||
|
||||
Text {
|
||||
id: msgpopupbody
|
||||
font.pointSize: 12
|
||||
wrapMode: Text.Wrap
|
||||
textFormat: Text.StyledText
|
||||
font.family: roboto.name
|
||||
Layout.maximumWidth: msgpopup.width-50
|
||||
Layout.fillHeight: true
|
||||
Layout.leftMargin: 25
|
||||
Layout.topMargin: 25
|
||||
Accessible.name: text.replace(/<\/?[^>]+(>|$)/g, "")
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.alignment: Qt.AlignCenter | Qt.AlignBottom
|
||||
Layout.bottomMargin: 10
|
||||
spacing: 20
|
||||
|
||||
ImButton {
|
||||
text: qsTr("NO")
|
||||
onClicked: {
|
||||
msgpopup.close()
|
||||
msgpopup.no()
|
||||
}
|
||||
visible: msgpopup.noButton
|
||||
Material.foreground: activeFocus ? "#d1dcfb" : "#ffffff"
|
||||
Material.background: "#c51a4a"
|
||||
}
|
||||
|
||||
ImButton {
|
||||
text: qsTr("YES")
|
||||
onClicked: {
|
||||
msgpopup.close()
|
||||
msgpopup.yes()
|
||||
}
|
||||
visible: msgpopup.yesButton
|
||||
Material.foreground: activeFocus ? "#d1dcfb" : "#ffffff"
|
||||
Material.background: "#c51a4a"
|
||||
}
|
||||
|
||||
ImButton {
|
||||
text: qsTr("CONTINUE")
|
||||
onClicked: {
|
||||
msgpopup.close()
|
||||
}
|
||||
visible: msgpopup.continueButton
|
||||
Material.foreground: activeFocus ? "#d1dcfb" : "#ffffff"
|
||||
Material.background: "#c51a4a"
|
||||
}
|
||||
|
||||
ImButton {
|
||||
text: qsTr("QUIT")
|
||||
onClicked: {
|
||||
Qt.quit()
|
||||
}
|
||||
font.family: roboto.name
|
||||
visible: msgpopup.quitButton
|
||||
Material.foreground: activeFocus ? "#d1dcfb" : "#ffffff"
|
||||
Material.background: "#c51a4a"
|
||||
}
|
||||
|
||||
Text { text: " " }
|
||||
}
|
||||
}
|
||||
|
||||
function openPopup() {
|
||||
open()
|
||||
// trigger screen reader to speak out message
|
||||
msgpopupbody.forceActiveFocus()
|
||||
}
|
||||
}
|
831
src/OptionsPopup.qml
Normal file
831
src/OptionsPopup.qml
Normal file
|
@ -0,0 +1,831 @@
|
|||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright (C) 2021 Raspberry Pi Ltd
|
||||
*/
|
||||
|
||||
import QtQuick 2.9
|
||||
import QtQuick.Controls 2.2
|
||||
import QtQuick.Layouts 1.0
|
||||
import QtQuick.Controls.Material 2.2
|
||||
import "qmlcomponents"
|
||||
|
||||
Popup {
|
||||
id: popup
|
||||
//x: 62
|
||||
x: (parent.width-width)/2
|
||||
y: 10
|
||||
//width: parent.width-125
|
||||
width: popupbody.implicitWidth+60
|
||||
height: parent.height-20
|
||||
padding: 0
|
||||
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
|
||||
property bool initialized: false
|
||||
property bool hasSavedSettings: false
|
||||
property string config
|
||||
property string cmdline
|
||||
property string firstrun
|
||||
property string cloudinit
|
||||
property string cloudinitrun
|
||||
property string cloudinitwrite
|
||||
property string cloudinitnetwork
|
||||
|
||||
// background of title
|
||||
Rectangle {
|
||||
color: "#f5f5f5"
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
height: 35
|
||||
width: parent.width
|
||||
}
|
||||
// line under title
|
||||
Rectangle {
|
||||
color: "#afafaf"
|
||||
width: parent.width
|
||||
y: 35
|
||||
implicitHeight: 1
|
||||
}
|
||||
|
||||
Text {
|
||||
id: msgx
|
||||
text: "X"
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
anchors.rightMargin: 25
|
||||
anchors.topMargin: 10
|
||||
font.family: roboto.name
|
||||
font.bold: true
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
popup.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
spacing: 20
|
||||
anchors.fill: parent
|
||||
|
||||
Text {
|
||||
id: popupheader
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 10
|
||||
font.family: roboto.name
|
||||
font.bold: true
|
||||
text: qsTr("Advanced options")
|
||||
}
|
||||
|
||||
ScrollView {
|
||||
id: popupbody
|
||||
font.family: roboto.name
|
||||
//Layout.maximumWidth: popup.width-30
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
Layout.leftMargin: 25
|
||||
Layout.topMargin: 10
|
||||
clip: true
|
||||
ScrollBar.vertical.policy: ScrollBar.AlwaysOn
|
||||
|
||||
ColumnLayout {
|
||||
|
||||
GroupBox {
|
||||
title: qsTr("Image customization options")
|
||||
label: RowLayout {
|
||||
Label {
|
||||
text: parent.parent.title
|
||||
}
|
||||
ComboBox {
|
||||
id: comboSaveSettings
|
||||
model: {
|
||||
[qsTr("for this session only"),
|
||||
qsTr("to always use")]
|
||||
}
|
||||
Layout.minimumWidth: 250
|
||||
Layout.maximumHeight: 40
|
||||
enabled: !imageWriter.isEmbeddedMode()
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
spacing: -10
|
||||
|
||||
ImCheckBox {
|
||||
id: chkOverscan
|
||||
text: qsTr("Disable overscan")
|
||||
}
|
||||
RowLayout {
|
||||
ImCheckBox {
|
||||
id: chkHostname
|
||||
text: qsTr("Set hostname:")
|
||||
onCheckedChanged: {
|
||||
if (checked) {
|
||||
fieldHostname.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
}
|
||||
TextField {
|
||||
id: fieldHostname
|
||||
enabled: chkHostname.checked
|
||||
text: "raspberrypi"
|
||||
}
|
||||
Text {
|
||||
text : ".local"
|
||||
color: chkHostname.checked ? "black" : "grey"
|
||||
}
|
||||
}
|
||||
ImCheckBox {
|
||||
id: chkSSH
|
||||
text: qsTr("Enable SSH")
|
||||
onCheckedChanged: {
|
||||
if (checked) {
|
||||
if (!radioPasswordAuthentication.checked && !radioPubKeyAuthentication.checked) {
|
||||
radioPasswordAuthentication.checked = true
|
||||
}
|
||||
if (radioPasswordAuthentication.checked) {
|
||||
chkSetUser.checked = true
|
||||
if (!fieldUserPassword.length) {
|
||||
fieldUserPassword.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ColumnLayout {
|
||||
enabled: chkSSH.checked
|
||||
Layout.leftMargin: 40
|
||||
spacing: -10
|
||||
|
||||
ImRadioButton {
|
||||
id: radioPasswordAuthentication
|
||||
text: qsTr("Use password authentication")
|
||||
onCheckedChanged: {
|
||||
if (checked) {
|
||||
chkSetUser.checked = true
|
||||
fieldUserPassword.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
}
|
||||
ImRadioButton {
|
||||
id: radioPubKeyAuthentication
|
||||
text: qsTr("Allow public-key authentication only")
|
||||
onCheckedChanged: {
|
||||
if (checked) {
|
||||
if (chkSetUser.checked && fieldUserName.text == "pi" && fieldUserPassword.text.length == 0) {
|
||||
chkSetUser.checked = false
|
||||
}
|
||||
fieldPublicKey.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
}
|
||||
GridLayout {
|
||||
Layout.leftMargin: 40
|
||||
columns: 2
|
||||
columnSpacing: 10
|
||||
rowSpacing: -5
|
||||
enabled: radioPubKeyAuthentication.checked
|
||||
|
||||
Text {
|
||||
text: qsTr("Set authorized_keys for '%1':").arg(fieldUserName.text)
|
||||
color: parent.enabled ? "black" : "grey"
|
||||
}
|
||||
TextField {
|
||||
id: fieldPublicKey
|
||||
Layout.minimumWidth: 200
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImCheckBox {
|
||||
id: chkSetUser
|
||||
text: qsTr("Set username and password")
|
||||
onCheckedChanged: {
|
||||
if (!checked && chkSSH.checked && radioPasswordAuthentication.checked) {
|
||||
checked = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
enabled: chkSetUser.checked
|
||||
Layout.leftMargin: 40
|
||||
spacing: -5
|
||||
|
||||
GridLayout {
|
||||
columns: 2
|
||||
columnSpacing: 10
|
||||
rowSpacing: -5
|
||||
|
||||
Text {
|
||||
text: qsTr("Username:")
|
||||
color: parent.enabled ? (fieldUserName.indicateError ? "red" : "black") : "grey"
|
||||
}
|
||||
TextField {
|
||||
id: fieldUserName
|
||||
text: "pi"
|
||||
Layout.minimumWidth: 200
|
||||
property bool indicateError: false
|
||||
|
||||
onTextEdited: {
|
||||
indicateError = false
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
text: qsTr("Password:")
|
||||
color: parent.enabled ? (fieldUserPassword.indicateError ? "red" : "black") : "grey"
|
||||
}
|
||||
TextField {
|
||||
id: fieldUserPassword
|
||||
echoMode: TextInput.Password
|
||||
Layout.minimumWidth: 200
|
||||
property bool alreadyCrypted: false
|
||||
property bool indicateError: false
|
||||
|
||||
onTextEdited: {
|
||||
if (alreadyCrypted) {
|
||||
/* User is trying to edit saved
|
||||
(crypted) password, clear field */
|
||||
alreadyCrypted = false
|
||||
clear()
|
||||
}
|
||||
if (indicateError) {
|
||||
indicateError = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImCheckBox {
|
||||
id: chkWifi
|
||||
text: qsTr("Configure wifi")
|
||||
onCheckedChanged: {
|
||||
if (checked) {
|
||||
if (!fieldWifiSSID.length) {
|
||||
fieldWifiSSID.forceActiveFocus()
|
||||
} else if (!fieldWifiPassword.length) {
|
||||
fieldWifiPassword.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
GridLayout {
|
||||
enabled: chkWifi.checked
|
||||
Layout.leftMargin: 40
|
||||
columns: 2
|
||||
columnSpacing: 10
|
||||
rowSpacing: -5
|
||||
|
||||
Text {
|
||||
text: qsTr("SSID:")
|
||||
color: parent.enabled ? (fieldWifiSSID.indicateError ? "red" : "black") : "grey"
|
||||
}
|
||||
TextField {
|
||||
id: fieldWifiSSID
|
||||
Layout.minimumWidth: 200
|
||||
property bool indicateError: false
|
||||
onTextEdited: {
|
||||
indicateError = false
|
||||
}
|
||||
}
|
||||
|
||||
ImCheckBox {
|
||||
id: chkWifiSSIDHidden
|
||||
Layout.columnSpan: 2
|
||||
text: qsTr("Hidden SSID")
|
||||
checked: false
|
||||
}
|
||||
|
||||
Text {
|
||||
text: qsTr("Password:")
|
||||
color: parent.enabled ? (fieldWifiPassword.indicateError ? "red" : "black") : "grey"
|
||||
}
|
||||
TextField {
|
||||
id: fieldWifiPassword
|
||||
Layout.minimumWidth: 200
|
||||
echoMode: chkShowPassword.checked ? TextInput.Normal : TextInput.Password
|
||||
property bool indicateError: false
|
||||
onTextEdited: {
|
||||
indicateError = false
|
||||
}
|
||||
}
|
||||
|
||||
ImCheckBox {
|
||||
id: chkShowPassword
|
||||
Layout.columnSpan: 2
|
||||
text: qsTr("Show password")
|
||||
checked: true
|
||||
}
|
||||
|
||||
Text {
|
||||
text: qsTr("Wifi country:")
|
||||
color: parent.enabled ? "black" : "grey"
|
||||
}
|
||||
ComboBox {
|
||||
id: fieldWifiCountry
|
||||
editable: true
|
||||
}
|
||||
}
|
||||
|
||||
ImCheckBox {
|
||||
id: chkLocale
|
||||
text: qsTr("Set locale settings")
|
||||
}
|
||||
GridLayout {
|
||||
enabled: chkLocale.checked
|
||||
Layout.leftMargin: 40
|
||||
columns: 2
|
||||
columnSpacing: 10
|
||||
rowSpacing: -5
|
||||
|
||||
Text {
|
||||
text: qsTr("Time zone:")
|
||||
color: parent.enabled ? "black" : "grey"
|
||||
}
|
||||
ComboBox {
|
||||
id: fieldTimezone
|
||||
editable: true
|
||||
Layout.minimumWidth: 200
|
||||
}
|
||||
|
||||
Text {
|
||||
text: qsTr("Keyboard layout:")
|
||||
color: parent.enabled ? "black" : "grey"
|
||||
}
|
||||
ComboBox {
|
||||
id: fieldKeyboardLayout
|
||||
editable: true
|
||||
Layout.minimumWidth: 200
|
||||
}
|
||||
ImCheckBox {
|
||||
id: chkSkipFirstUse
|
||||
text: qsTr("Skip first-run wizard")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GroupBox {
|
||||
title: qsTr("Persistent settings")
|
||||
Layout.fillWidth: true
|
||||
|
||||
ColumnLayout {
|
||||
spacing: -10
|
||||
|
||||
ImCheckBox {
|
||||
id: chkBeep
|
||||
text: qsTr("Play sound when finished")
|
||||
}
|
||||
ImCheckBox {
|
||||
id: chkEject
|
||||
text: qsTr("Eject media when finished")
|
||||
}
|
||||
ImCheckBox {
|
||||
id: chkTelemtry
|
||||
text: qsTr("Enable telemetry")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.alignment: Qt.AlignCenter | Qt.AlignBottom
|
||||
Layout.bottomMargin: 10
|
||||
spacing: 20
|
||||
|
||||
ImButton {
|
||||
text: qsTr("SAVE")
|
||||
onClicked: {
|
||||
if (chkSetUser.checked && fieldUserPassword.text.length == 0)
|
||||
{
|
||||
fieldUserPassword.indicateError = true
|
||||
fieldUserPassword.forceActiveFocus()
|
||||
return
|
||||
}
|
||||
if (chkSetUser.checked && fieldUserName.text.length == 0)
|
||||
{
|
||||
fieldUserName.indicateError = true
|
||||
fieldUserName.forceActiveFocus()
|
||||
return
|
||||
}
|
||||
|
||||
if (chkWifi.checked)
|
||||
{
|
||||
if (fieldWifiPassword.text.length < 8 || fieldWifiPassword.text.length > 64)
|
||||
{
|
||||
fieldWifiPassword.indicateError = true
|
||||
fieldWifiPassword.forceActiveFocus()
|
||||
}
|
||||
if (fieldWifiSSID.text.length == 0)
|
||||
{
|
||||
fieldWifiSSID.indicateError = true
|
||||
fieldWifiSSID.forceActiveFocus()
|
||||
}
|
||||
if (fieldWifiSSID.indicateError || fieldWifiPassword.indicateError)
|
||||
{
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
applySettings()
|
||||
saveSettings()
|
||||
popup.close()
|
||||
}
|
||||
Material.foreground: activeFocus ? "#d1dcfb" : "#ffffff"
|
||||
Material.background: "#c51a4a"
|
||||
}
|
||||
|
||||
Text { text: " " }
|
||||
}
|
||||
}
|
||||
|
||||
function initialize() {
|
||||
chkBeep.checked = imageWriter.getBoolSetting("beep")
|
||||
chkTelemtry.checked = imageWriter.getBoolSetting("telemetry")
|
||||
chkEject.checked = imageWriter.getBoolSetting("eject")
|
||||
var settings = imageWriter.getSavedCustomizationSettings()
|
||||
fieldTimezone.model = imageWriter.getTimezoneList()
|
||||
fieldPublicKey.text = imageWriter.getDefaultPubKey()
|
||||
fieldWifiCountry.model = imageWriter.getCountryList()
|
||||
fieldKeyboardLayout.model = imageWriter.getKeymapLayoutList()
|
||||
|
||||
if (Object.keys(settings).length) {
|
||||
comboSaveSettings.currentIndex = 1
|
||||
hasSavedSettings = true
|
||||
}
|
||||
if ('disableOverscan' in settings) {
|
||||
chkOverscan.checked = true
|
||||
}
|
||||
if ('hostname' in settings) {
|
||||
fieldHostname.text = settings.hostname
|
||||
chkHostname.checked = true
|
||||
}
|
||||
if ('sshAuthorizedKeys' in settings) {
|
||||
fieldPublicKey.text = settings.sshAuthorizedKeys
|
||||
radioPubKeyAuthentication.checked = true
|
||||
chkSSH.checked = true
|
||||
}
|
||||
|
||||
if ('sshUserPassword' in settings) {
|
||||
fieldUserPassword.text = settings.sshUserPassword
|
||||
fieldUserPassword.alreadyCrypted = true
|
||||
chkSetUser.checked = true
|
||||
/* Older imager versions did not have a sshEnabled setting.
|
||||
Assume it is true if it does not exists and sshUserPassword is set */
|
||||
if (!('sshEnabled' in settings) || settings.sshEnabled === "true" || settings.sshEnabled === true) {
|
||||
chkSSH.checked = true
|
||||
radioPasswordAuthentication.checked = true
|
||||
}
|
||||
}
|
||||
if ('sshUserName' in settings) {
|
||||
fieldUserName.text = settings.sshUserName
|
||||
chkSetUser.checked = true
|
||||
}
|
||||
if ('wifiSSID' in settings) {
|
||||
fieldWifiSSID.text = settings.wifiSSID
|
||||
if ('wifiSSIDHidden' in settings && settings.wifiSSIDHidden) {
|
||||
chkWifiSSIDHidden.checked = true
|
||||
}
|
||||
chkShowPassword.checked = false
|
||||
fieldWifiPassword.text = settings.wifiPassword
|
||||
fieldWifiCountry.currentIndex = fieldWifiCountry.find(settings.wifiCountry)
|
||||
if (fieldWifiCountry.currentIndex == -1) {
|
||||
fieldWifiCountry.editText = settings.wifiCountry
|
||||
}
|
||||
chkWifi.checked = true
|
||||
} else {
|
||||
fieldWifiCountry.currentIndex = fieldWifiCountry.find("GB")
|
||||
fieldWifiSSID.text = imageWriter.getSSID()
|
||||
if (fieldWifiSSID.text.length) {
|
||||
fieldWifiPassword.text = imageWriter.getPSK(fieldWifiSSID.text)
|
||||
if (fieldWifiPassword.text.length) {
|
||||
chkShowPassword.checked = false
|
||||
if (Qt.platform.os == "osx") {
|
||||
/* User indicated wifi must be prefilled */
|
||||
chkWifi.checked = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var tz;
|
||||
if ('timezone' in settings) {
|
||||
chkLocale.checked = true
|
||||
tz = settings.timezone
|
||||
} else {
|
||||
tz = imageWriter.getTimezone()
|
||||
}
|
||||
var tzidx = fieldTimezone.find(tz)
|
||||
if (tzidx === -1) {
|
||||
fieldTimezone.editText = tz
|
||||
} else {
|
||||
fieldTimezone.currentIndex = tzidx
|
||||
}
|
||||
if ('keyboardLayout' in settings) {
|
||||
fieldKeyboardLayout.currentIndex = fieldKeyboardLayout.find(settings.keyboardLayout)
|
||||
if (fieldKeyboardLayout.currentIndex == -1) {
|
||||
fieldKeyboardLayout.editText = settings.keyboardLayout
|
||||
}
|
||||
} else {
|
||||
if (imageWriter.isEmbeddedMode())
|
||||
{
|
||||
fieldKeyboardLayout.currentIndex = fieldKeyboardLayout.find(imageWriter.getCurrentKeyboard())
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Lacking an easy cross-platform to fetch keyboard layout
|
||||
from host system, just default to "gb" for people in
|
||||
UK time zone for now, and "us" for everyone else */
|
||||
if (tz == "Europe/London") {
|
||||
fieldKeyboardLayout.currentIndex = fieldKeyboardLayout.find("gb")
|
||||
} else {
|
||||
fieldKeyboardLayout.currentIndex = fieldKeyboardLayout.find("us")
|
||||
}
|
||||
}
|
||||
}
|
||||
if ('skipFirstUse' in settings) {
|
||||
chkSkipFirstUse.checked = true
|
||||
}
|
||||
|
||||
initialized = true
|
||||
}
|
||||
|
||||
function openPopup() {
|
||||
if (!initialized) {
|
||||
initialize()
|
||||
}
|
||||
|
||||
open()
|
||||
popupbody.forceActiveFocus()
|
||||
}
|
||||
|
||||
function addCmdline(s) {
|
||||
cmdline += " "+s
|
||||
}
|
||||
function addConfig(s) {
|
||||
config += s+"\n"
|
||||
}
|
||||
function addFirstRun(s) {
|
||||
firstrun += s+"\n"
|
||||
}
|
||||
function escapeshellarg(arg) {
|
||||
return "'"+arg.replace(/'/g, "\\'")+"'"
|
||||
}
|
||||
function addCloudInit(s) {
|
||||
cloudinit += s+"\n"
|
||||
}
|
||||
function addCloudInitWriteFile(name, content, perms) {
|
||||
cloudinitwrite += "- encoding: b64\n"
|
||||
cloudinitwrite += " content: "+Qt.btoa(content)+"\n"
|
||||
cloudinitwrite += " owner: root:root\n"
|
||||
cloudinitwrite += " path: "+name+"\n"
|
||||
cloudinitwrite += " permissions: '"+perms+"'\n"
|
||||
}
|
||||
function addCloudInitRun(cmd) {
|
||||
cloudinitrun += "- "+cmd+"\n"
|
||||
}
|
||||
|
||||
function applySettings()
|
||||
{
|
||||
cmdline = ""
|
||||
config = ""
|
||||
firstrun = ""
|
||||
cloudinit = ""
|
||||
cloudinitrun = ""
|
||||
cloudinitwrite = ""
|
||||
cloudinitnetwork = ""
|
||||
|
||||
if (chkOverscan.checked) {
|
||||
addConfig("disable_overscan=1")
|
||||
}
|
||||
if (chkHostname.checked && fieldHostname.length) {
|
||||
addFirstRun("CURRENT_HOSTNAME=`cat /etc/hostname | tr -d \" \\t\\n\\r\"`")
|
||||
addFirstRun("echo "+fieldHostname.text+" >/etc/hostname")
|
||||
addFirstRun("sed -i \"s/127.0.1.1.*$CURRENT_HOSTNAME/127.0.1.1\\t"+fieldHostname.text+"/g\" /etc/hosts")
|
||||
|
||||
addCloudInit("hostname: "+fieldHostname.text)
|
||||
addCloudInit("manage_etc_hosts: true")
|
||||
addCloudInit("packages:")
|
||||
addCloudInit("- avahi-daemon")
|
||||
/* Disable date/time checks in apt as NTP may not have synchronized yet when installing packages */
|
||||
addCloudInit("apt:")
|
||||
addCloudInit(" conf: |")
|
||||
addCloudInit(" Acquire {")
|
||||
addCloudInit(" Check-Date \"false\";")
|
||||
addCloudInit(" };")
|
||||
addCloudInit("")
|
||||
}
|
||||
|
||||
if (chkSSH.checked || chkSetUser.checked) {
|
||||
// First user may not be called 'pi' on all distributions, so look username up
|
||||
addFirstRun("FIRSTUSER=`getent passwd 1000 | cut -d: -f1`");
|
||||
addFirstRun("FIRSTUSERHOME=`getent passwd 1000 | cut -d: -f6`")
|
||||
|
||||
addCloudInit("users:")
|
||||
addCloudInit("- name: "+fieldUserName.text)
|
||||
addCloudInit(" groups: users,adm,dialout,audio,netdev,video,plugdev,cdrom,games,input,gpio,spi,i2c,render,sudo")
|
||||
addCloudInit(" shell: /bin/bash")
|
||||
|
||||
var cryptedPassword;
|
||||
if (chkSetUser.checked) {
|
||||
cryptedPassword = fieldUserPassword.alreadyCrypted ? fieldUserPassword.text : imageWriter.crypt(fieldUserPassword.text)
|
||||
addCloudInit(" lock_passwd: false")
|
||||
addCloudInit(" passwd: "+cryptedPassword)
|
||||
}
|
||||
|
||||
if (chkSSH.checked && radioPubKeyAuthentication.checked) {
|
||||
var pubkey = fieldPublicKey.text
|
||||
var pubkeyArr = pubkey.split("\n")
|
||||
|
||||
if (pubkey.length) {
|
||||
addFirstRun("install -o \"$FIRSTUSER\" -m 700 -d \"$FIRSTUSERHOME/.ssh\"")
|
||||
addFirstRun("install -o \"$FIRSTUSER\" -m 600 <(printf \""+pubkey.replace(/\n/g, "\\n")+"\") \"$FIRSTUSERHOME/.ssh/authorized_keys\"")
|
||||
}
|
||||
addFirstRun("echo 'PasswordAuthentication no' >>/etc/ssh/sshd_config")
|
||||
|
||||
if (!chkSetUser.checked) {
|
||||
addCloudInit(" lock_passwd: true")
|
||||
}
|
||||
addCloudInit(" ssh_authorized_keys:")
|
||||
for (var i=0; i<pubkeyArr.length; i++) {
|
||||
var pk = pubkeyArr[i].trim();
|
||||
if (pk) {
|
||||
addCloudInit(" - "+pk)
|
||||
}
|
||||
}
|
||||
addCloudInit(" sudo: ALL=(ALL) NOPASSWD:ALL")
|
||||
}
|
||||
addCloudInit("")
|
||||
|
||||
if (chkSSH.checked && radioPasswordAuthentication.checked) {
|
||||
addCloudInit("ssh_pwauth: true")
|
||||
}
|
||||
|
||||
if (chkSetUser.checked) {
|
||||
/* Rename first ("pi") user if a different desired username was specified */
|
||||
addFirstRun("if [ -f /usr/lib/userconf-pi/userconf ]; then")
|
||||
addFirstRun(" /usr/lib/userconf-pi/userconf "+escapeshellarg(fieldUserName.text)+" "+escapeshellarg(cryptedPassword))
|
||||
addFirstRun("else")
|
||||
addFirstRun(" echo \"$FIRSTUSER:\""+escapeshellarg(cryptedPassword)+" | chpasswd -e")
|
||||
addFirstRun(" if [ \"$FIRSTUSER\" != \""+fieldUserName.text+"\" ]; then")
|
||||
addFirstRun(" usermod -l \""+fieldUserName.text+"\" \"$FIRSTUSER\"")
|
||||
addFirstRun(" usermod -m -d \"/home/"+fieldUserName.text+"\" \""+fieldUserName.text+"\"")
|
||||
addFirstRun(" groupmod -n \""+fieldUserName.text+"\" \"$FIRSTUSER\"")
|
||||
addFirstRun(" if grep -q \"^autologin-user=\" /etc/lightdm/lightdm.conf ; then")
|
||||
addFirstRun(" sed /etc/lightdm/lightdm.conf -i -e \"s/^autologin-user=.*/autologin-user="+fieldUserName.text+"/\"")
|
||||
addFirstRun(" fi")
|
||||
addFirstRun(" if [ -f /etc/systemd/system/getty@tty1.service.d/autologin.conf ]; then")
|
||||
addFirstRun(" sed /etc/systemd/system/getty@tty1.service.d/autologin.conf -i -e \"s/$FIRSTUSER/"+fieldUserName.text+"/\"")
|
||||
addFirstRun(" fi")
|
||||
addFirstRun(" if [ -f /etc/sudoers.d/010_pi-nopasswd ]; then")
|
||||
addFirstRun(" sed -i \"s/^$FIRSTUSER /"+fieldUserName.text+" /\" /etc/sudoers.d/010_pi-nopasswd")
|
||||
addFirstRun(" fi")
|
||||
addFirstRun(" fi")
|
||||
addFirstRun("fi")
|
||||
}
|
||||
|
||||
if (chkSSH.checked) {
|
||||
addFirstRun("systemctl enable ssh")
|
||||
}
|
||||
addCloudInit("")
|
||||
}
|
||||
if (chkWifi.checked) {
|
||||
var wpaconfig = "country="+fieldWifiCountry.editText+"\n"
|
||||
wpaconfig += "ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev\n"
|
||||
wpaconfig += "ap_scan=1\n\n"
|
||||
wpaconfig += "update_config=1\n"
|
||||
wpaconfig += "network={\n"
|
||||
if (chkWifiSSIDHidden.checked) {
|
||||
wpaconfig += "\tscan_ssid=1\n"
|
||||
}
|
||||
wpaconfig += "\tssid=\""+fieldWifiSSID.text+"\"\n"
|
||||
var cryptedPsk = fieldWifiPassword.text.length == 64 ? fieldWifiPassword.text : imageWriter.pbkdf2(fieldWifiPassword.text, fieldWifiSSID.text)
|
||||
wpaconfig += "\tpsk="+cryptedPsk+"\n"
|
||||
wpaconfig += "}\n"
|
||||
|
||||
addFirstRun("cat >/etc/wpa_supplicant/wpa_supplicant.conf <<'WPAEOF'")
|
||||
addFirstRun(wpaconfig)
|
||||
addFirstRun("WPAEOF")
|
||||
addFirstRun("chmod 600 /etc/wpa_supplicant/wpa_supplicant.conf")
|
||||
addFirstRun("rfkill unblock wifi")
|
||||
addFirstRun("for filename in /var/lib/systemd/rfkill/*:wlan ; do")
|
||||
addFirstRun(" echo 0 > $filename")
|
||||
addFirstRun("done")
|
||||
|
||||
cloudinitnetwork = "version: 2\n"
|
||||
cloudinitnetwork += "wifis:\n"
|
||||
cloudinitnetwork += " renderer: networkd\n"
|
||||
cloudinitnetwork += " wlan0:\n"
|
||||
cloudinitnetwork += " dhcp4: true\n"
|
||||
cloudinitnetwork += " optional: true\n"
|
||||
cloudinitnetwork += " access-points:\n"
|
||||
cloudinitnetwork += " \""+fieldWifiSSID.text+"\":\n"
|
||||
cloudinitnetwork += " password: \""+cryptedPsk+"\"\n"
|
||||
if (chkWifiSSIDHidden.checked) {
|
||||
cloudinitnetwork += " hidden: true\n"
|
||||
}
|
||||
|
||||
/* FIXME: setting wifi country code broken on Ubuntu
|
||||
For unknown reasons udev does not trigger setregdomain automatically and as a result
|
||||
our setting in /etc/default/crda is being ignored by Ubuntu. */
|
||||
addCloudInitRun("sed -i 's/^\s*REGDOMAIN=\S*/REGDOMAIN="+fieldWifiCountry.editText+"/' /etc/default/crda || true")
|
||||
}
|
||||
if (chkLocale.checked) {
|
||||
if (chkSkipFirstUse.checked) {
|
||||
addFirstRun("rm -f /etc/xdg/autostart/piwiz.desktop")
|
||||
addCloudInitRun("rm -f /etc/xdg/autostart/piwiz.desktop")
|
||||
}
|
||||
|
||||
var kbdconfig = "XKBMODEL=\"pc105\"\n"
|
||||
kbdconfig += "XKBLAYOUT=\""+fieldKeyboardLayout.editText+"\"\n"
|
||||
kbdconfig += "XKBVARIANT=\"\"\n"
|
||||
kbdconfig += "XKBOPTIONS=\"\"\n"
|
||||
|
||||
addFirstRun("rm -f /etc/localtime")
|
||||
addFirstRun("echo \""+fieldTimezone.editText+"\" >/etc/timezone")
|
||||
addFirstRun("dpkg-reconfigure -f noninteractive tzdata")
|
||||
addFirstRun("cat >/etc/default/keyboard <<'KBEOF'")
|
||||
addFirstRun(kbdconfig)
|
||||
addFirstRun("KBEOF")
|
||||
addFirstRun("dpkg-reconfigure -f noninteractive keyboard-configuration")
|
||||
|
||||
addCloudInit("timezone: "+fieldTimezone.editText)
|
||||
addCloudInitRun("localectl set-x11-keymap \""+fieldKeyboardLayout.editText+"\" pc105")
|
||||
addCloudInitRun("setupcon -k --force || true")
|
||||
}
|
||||
|
||||
if (firstrun.length) {
|
||||
firstrun = "#!/bin/bash\n\n"+"set +e\n\n"+firstrun
|
||||
addFirstRun("rm -f /boot/firstrun.sh")
|
||||
addFirstRun("sed -i 's| systemd.run.*||g' /boot/cmdline.txt")
|
||||
addFirstRun("exit 0")
|
||||
/* using systemd.run_success_action=none does not seem to have desired effect
|
||||
systemd then stays at "reached target kernel command line", so use reboot instead */
|
||||
//addCmdline("systemd.run=/boot/firstrun.sh systemd.run_success_action=reboot systemd.unit=kernel-command-line.target")
|
||||
// cmdline changing moved to DownloadThread::_customizeImage()
|
||||
}
|
||||
|
||||
if (cloudinitwrite !== "") {
|
||||
addCloudInit("write_files:\n"+cloudinitwrite+"\n")
|
||||
}
|
||||
|
||||
if (cloudinitrun !== "") {
|
||||
addCloudInit("runcmd:\n"+cloudinitrun+"\n")
|
||||
}
|
||||
|
||||
imageWriter.setImageCustomization(config, cmdline, firstrun, cloudinit, cloudinitnetwork)
|
||||
}
|
||||
|
||||
function saveSettings()
|
||||
{
|
||||
if (comboSaveSettings.currentIndex == 1) {
|
||||
hasSavedSettings = true
|
||||
var settings = { };
|
||||
if (chkOverscan.checked) {
|
||||
settings.disableOverscan = true
|
||||
}
|
||||
if (chkHostname.checked && fieldHostname.length) {
|
||||
settings.hostname = fieldHostname.text
|
||||
}
|
||||
if (chkSetUser.checked) {
|
||||
settings.sshUserName = fieldUserName.text
|
||||
settings.sshUserPassword = fieldUserPassword.alreadyCrypted ? fieldUserPassword.text : imageWriter.crypt(fieldUserPassword.text)
|
||||
}
|
||||
|
||||
settings.sshEnabled = chkSSH.checked
|
||||
if (chkSSH.checked && radioPubKeyAuthentication.checked) {
|
||||
settings.sshAuthorizedKeys = fieldPublicKey.text
|
||||
}
|
||||
if (chkWifi.checked) {
|
||||
settings.wifiSSID = fieldWifiSSID.text
|
||||
if (chkWifiSSIDHidden.checked) {
|
||||
settings.wifiSSIDHidden = true
|
||||
}
|
||||
settings.wifiPassword = fieldWifiPassword.text.length == 64 ? fieldWifiPassword.text : imageWriter.pbkdf2(fieldWifiPassword.text, fieldWifiSSID.text)
|
||||
settings.wifiCountry = fieldWifiCountry.editText
|
||||
}
|
||||
if (chkLocale.checked) {
|
||||
settings.timezone = fieldTimezone.editText
|
||||
settings.keyboardLayout = fieldKeyboardLayout.editText
|
||||
if (chkSkipFirstUse.checked) {
|
||||
settings.skipFirstUse = true
|
||||
}
|
||||
}
|
||||
|
||||
imageWriter.setSavedCustomizationSettings(settings)
|
||||
|
||||
} else if (hasSavedSettings) {
|
||||
imageWriter.clearSavedCustomizationSettings()
|
||||
hasSavedSettings = false
|
||||
}
|
||||
|
||||
imageWriter.setSetting("beep", chkBeep.checked)
|
||||
imageWriter.setSetting("eject", chkEject.checked)
|
||||
imageWriter.setSetting("telemetry", chkTelemtry.checked)
|
||||
}
|
||||
}
|
133
src/UseSavedSettingsPopup.qml
Normal file
133
src/UseSavedSettingsPopup.qml
Normal file
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright (C) 2021 Raspberry Pi Ltd
|
||||
*/
|
||||
|
||||
import QtQuick 2.9
|
||||
import QtQuick.Controls 2.2
|
||||
import QtQuick.Layouts 1.0
|
||||
import QtQuick.Controls.Material 2.2
|
||||
import "qmlcomponents"
|
||||
|
||||
Popup {
|
||||
id: msgpopup
|
||||
x: 75
|
||||
y: (parent.height-height)/2
|
||||
width: parent.width-150
|
||||
height: msgpopupbody.implicitHeight+150
|
||||
padding: 0
|
||||
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
|
||||
|
||||
signal yes()
|
||||
signal no()
|
||||
signal editSettings()
|
||||
|
||||
// background of title
|
||||
Rectangle {
|
||||
color: "#f5f5f5"
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
height: 35
|
||||
width: parent.width
|
||||
}
|
||||
// line under title
|
||||
Rectangle {
|
||||
color: "#afafaf"
|
||||
width: parent.width
|
||||
y: 35
|
||||
implicitHeight: 1
|
||||
}
|
||||
|
||||
Text {
|
||||
id: msgx
|
||||
text: "X"
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
anchors.rightMargin: 25
|
||||
anchors.topMargin: 10
|
||||
font.family: roboto.name
|
||||
font.bold: true
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
msgpopup.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
spacing: 20
|
||||
anchors.fill: parent
|
||||
|
||||
Text {
|
||||
id: msgpopupheader
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 10
|
||||
font.family: roboto.name
|
||||
font.bold: true
|
||||
text: qsTr("Warning: advanced settings set")
|
||||
}
|
||||
|
||||
Text {
|
||||
id: msgpopupbody
|
||||
font.pointSize: 12
|
||||
wrapMode: Text.Wrap
|
||||
textFormat: Text.StyledText
|
||||
font.family: roboto.name
|
||||
Layout.maximumWidth: msgpopup.width-50
|
||||
Layout.fillHeight: true
|
||||
Layout.leftMargin: 25
|
||||
Layout.topMargin: 25
|
||||
Accessible.name: text.replace(/<\/?[^>]+(>|$)/g, "")
|
||||
text: qsTr("Would you like to apply the image customization settings saved earlier?")
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.alignment: Qt.AlignCenter | Qt.AlignBottom
|
||||
Layout.bottomMargin: 10
|
||||
spacing: 20
|
||||
|
||||
ImButton {
|
||||
text: qsTr("NO, CLEAR SETTINGS")
|
||||
onClicked: {
|
||||
msgpopup.close()
|
||||
msgpopup.no()
|
||||
}
|
||||
Material.foreground: activeFocus ? "#d1dcfb" : "#ffffff"
|
||||
Material.background: "#c51a4a"
|
||||
}
|
||||
|
||||
ImButton {
|
||||
text: qsTr("YES")
|
||||
onClicked: {
|
||||
msgpopup.close()
|
||||
msgpopup.yes()
|
||||
}
|
||||
Material.foreground: activeFocus ? "#d1dcfb" : "#ffffff"
|
||||
Material.background: "#c51a4a"
|
||||
}
|
||||
|
||||
ImButton {
|
||||
text: qsTr("EDIT SETTINGS")
|
||||
onClicked: {
|
||||
msgpopup.close()
|
||||
msgpopup.editSettings()
|
||||
}
|
||||
Material.foreground: activeFocus ? "#d1dcfb" : "#ffffff"
|
||||
Material.background: "#c51a4a"
|
||||
}
|
||||
|
||||
Text { text: " " }
|
||||
}
|
||||
}
|
||||
|
||||
function openPopup() {
|
||||
open()
|
||||
// trigger screen reader to speak out message
|
||||
msgpopupbody.forceActiveFocus()
|
||||
}
|
||||
}
|
37
src/acceleratedcryptographichash.cpp
Normal file
37
src/acceleratedcryptographichash.cpp
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Use OpenSSL for hashing as their code is more optimized than Qt's
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright (C) 2020 Raspberry Pi Ltd
|
||||
*/
|
||||
|
||||
#include "acceleratedcryptographichash.h"
|
||||
|
||||
AcceleratedCryptographicHash::AcceleratedCryptographicHash(QCryptographicHash::Algorithm method)
|
||||
{
|
||||
if (method != QCryptographicHash::Sha256)
|
||||
throw std::runtime_error("Only sha256 implemented");
|
||||
|
||||
SHA256_Init(&_sha256);
|
||||
}
|
||||
|
||||
AcceleratedCryptographicHash::~AcceleratedCryptographicHash()
|
||||
{
|
||||
}
|
||||
|
||||
void AcceleratedCryptographicHash::addData(const char *data, int length)
|
||||
{
|
||||
SHA256_Update(&_sha256, data, length);
|
||||
}
|
||||
|
||||
void AcceleratedCryptographicHash::addData(const QByteArray &data)
|
||||
{
|
||||
addData(data.constData(), data.size());
|
||||
}
|
||||
|
||||
QByteArray AcceleratedCryptographicHash::result()
|
||||
{
|
||||
unsigned char binhash[SHA256_DIGEST_LENGTH];
|
||||
SHA256_Final(binhash, &_sha256);
|
||||
return QByteArray((char *) binhash, sizeof binhash);
|
||||
}
|
35
src/acceleratedcryptographichash.h
Normal file
35
src/acceleratedcryptographichash.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
#ifndef ACCELERATEDCRYPTOGRAPHICHASH_H
|
||||
#define ACCELERATEDCRYPTOGRAPHICHASH_H
|
||||
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright (C) 2020 Raspberry Pi Ltd
|
||||
*/
|
||||
|
||||
#include <QCryptographicHash>
|
||||
|
||||
#ifdef Q_OS_DARWIN
|
||||
#include <CommonCrypto/CommonDigest.h>
|
||||
#define SHA256_CTX CC_SHA256_CTX
|
||||
#define SHA256_DIGEST_LENGTH CC_SHA256_DIGEST_LENGTH
|
||||
#define SHA256_Init CC_SHA256_Init
|
||||
#define SHA256_Update CC_SHA256_Update
|
||||
#define SHA256_Final CC_SHA256_Final
|
||||
#else
|
||||
#include "openssl/sha.h"
|
||||
#endif
|
||||
|
||||
class AcceleratedCryptographicHash
|
||||
{
|
||||
public:
|
||||
explicit AcceleratedCryptographicHash(QCryptographicHash::Algorithm method);
|
||||
virtual ~AcceleratedCryptographicHash();
|
||||
void addData(const char *data, int length);
|
||||
void addData(const QByteArray &data);
|
||||
QByteArray result();
|
||||
|
||||
protected:
|
||||
SHA256_CTX _sha256;
|
||||
};
|
||||
|
||||
#endif // ACCELERATEDCRYPTOGRAPHICHASH_H
|
224
src/cli.cpp
Normal file
224
src/cli.cpp
Normal file
|
@ -0,0 +1,224 @@
|
|||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright (C) 2020 Raspberry Pi Ltd
|
||||
*/
|
||||
|
||||
#include "cli.h"
|
||||
#include "imagewriter.h"
|
||||
#include <iostream>
|
||||
#include <QCoreApplication>
|
||||
#include <QCommandLineParser>
|
||||
#include <QFileInfo>
|
||||
#include "drivelistmodel.h"
|
||||
#include "dependencies/drivelist/src/drivelist.hpp"
|
||||
|
||||
/* Message handler to discard qDebug() output if using cli (unless --debug is set) */
|
||||
static void devnullMsgHandler(QtMsgType, const QMessageLogContext &, const QString &)
|
||||
{
|
||||
}
|
||||
|
||||
Cli::Cli(int &argc, char *argv[]) : QObject(nullptr)
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
/* Allocate console on Windows (only needed if compiled as GUI program) */
|
||||
if (::AttachConsole(ATTACH_PARENT_PROCESS) || ::AllocConsole())
|
||||
{
|
||||
freopen("CONOUT$", "w", stdout);
|
||||
freopen("CONOUT$", "w", stderr);
|
||||
std::ios::sync_with_stdio();
|
||||
}
|
||||
#endif
|
||||
_app = new QCoreApplication(argc, argv);
|
||||
_app->setOrganizationName("Raspberry Pi");
|
||||
_app->setOrganizationDomain("raspberrypi.org");
|
||||
_app->setApplicationName("Imager");
|
||||
_imageWriter = new ImageWriter;
|
||||
connect(_imageWriter, &ImageWriter::success, this, &Cli::onSuccess);
|
||||
connect(_imageWriter, &ImageWriter::error, this, &Cli::onError);
|
||||
connect(_imageWriter, &ImageWriter::preparationStatusUpdate, this, &Cli::onPreparationStatusUpdate);
|
||||
connect(_imageWriter, &ImageWriter::downloadProgress, this, &Cli::onDownloadProgress);
|
||||
connect(_imageWriter, &ImageWriter::verifyProgress, this, &Cli::onVerifyProgress);
|
||||
}
|
||||
|
||||
Cli::~Cli()
|
||||
{
|
||||
delete _imageWriter;
|
||||
delete _app;
|
||||
}
|
||||
|
||||
int Cli::main()
|
||||
{
|
||||
QCommandLineParser parser;
|
||||
QCommandLineOption cli("cli");
|
||||
parser.addOption(cli);
|
||||
QCommandLineOption disableVerify("disable-verify", "Disable verification");
|
||||
parser.addOption(disableVerify);
|
||||
QCommandLineOption writeSystemDrive("enable-writing-system-drives", "Only use this if you know what you are doing");
|
||||
parser.addOption(writeSystemDrive);
|
||||
QCommandLineOption sha256Option("sha256", "Expected hash", "sha256", "");
|
||||
parser.addOption(sha256Option);
|
||||
QCommandLineOption debugOption("debug", "Output debug messages to console");
|
||||
parser.addOption(debugOption);
|
||||
QCommandLineOption quietOption("quiet", "Only write to console on error");
|
||||
parser.addOption(quietOption);
|
||||
|
||||
parser.addPositionalArgument("src", "Image file/URL");
|
||||
parser.addPositionalArgument("dst", "Destination device");
|
||||
parser.process(*_app);
|
||||
|
||||
const QStringList args = parser.positionalArguments();
|
||||
if (args.count() != 2)
|
||||
{
|
||||
std::cerr << "Usage: --cli [--disable-verify] [--sha256 <expected hash>] [--debug] [--quiet] <image file to write> <destination drive device>" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!parser.isSet(debugOption))
|
||||
{
|
||||
qInstallMessageHandler(devnullMsgHandler);
|
||||
}
|
||||
_quiet = parser.isSet(quietOption);
|
||||
|
||||
if (args[0].startsWith("http:", Qt::CaseInsensitive) || args[0].startsWith("https:", Qt::CaseInsensitive))
|
||||
{
|
||||
_imageWriter->setSrc(args[0], 0, 0, parser.value(sha256Option).toLatin1() );
|
||||
}
|
||||
else
|
||||
{
|
||||
QFileInfo fi(args[0]);
|
||||
|
||||
if (fi.isFile())
|
||||
{
|
||||
_imageWriter->setSrc(QUrl::fromLocalFile(args[0]), fi.size(), 0, parser.value(sha256Option).toLatin1() );
|
||||
}
|
||||
else if (!fi.exists())
|
||||
{
|
||||
std::cerr << "Error: source file does not exists" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Error: source is not a regular file" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (parser.isSet(writeSystemDrive))
|
||||
{
|
||||
std::cerr << "WARNING: writing to system drives is enabled." << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
DriveListModel dlm;
|
||||
dlm.processDriveList(Drivelist::ListStorageDevices() );
|
||||
bool foundDrive = false;
|
||||
int numDrives = dlm.rowCount( QModelIndex() );
|
||||
|
||||
for (int i = 0; i < numDrives; i++)
|
||||
{
|
||||
if (dlm.index(i, 0).data(dlm.deviceRole) == args[1])
|
||||
{
|
||||
foundDrive = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundDrive)
|
||||
{
|
||||
std::cerr << "Destination drive is not in list of removable volumes. Choose one of the following:" << std::endl << std::endl;
|
||||
|
||||
for (int i = 0; i < numDrives; i++)
|
||||
{
|
||||
QModelIndex idx = dlm.index(i, 0);
|
||||
QByteArray line = idx.data(dlm.deviceRole).toByteArray()+" ("+idx.data(dlm.descriptionRole).toByteArray()+")";
|
||||
|
||||
std::cerr << line.constData() << std::endl;
|
||||
}
|
||||
|
||||
std::cerr << std::endl << "Or use --enable-writing-system-drives to overrule." << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
_imageWriter->setDst(args[1]);
|
||||
_imageWriter->setVerifyEnabled(!parser.isSet(disableVerify));
|
||||
|
||||
/* Run startWrite() in event loop (otherwise calling _app->exit() on error does not work) */
|
||||
QTimer::singleShot(1, _imageWriter, &ImageWriter::startWrite);
|
||||
return _app->exec();
|
||||
}
|
||||
|
||||
void Cli::onSuccess()
|
||||
{
|
||||
if (!_quiet)
|
||||
{
|
||||
_clearLine();
|
||||
std::cerr << "Write successful." << std::endl;
|
||||
}
|
||||
_app->exit(0);
|
||||
}
|
||||
|
||||
void Cli::_clearLine()
|
||||
{
|
||||
/* Properly clearing line requires platform specific code.
|
||||
Just write some spaces for now, and return to beginning of line. */
|
||||
std::cerr << " \r";
|
||||
}
|
||||
|
||||
void Cli::onError(QVariant msg)
|
||||
{
|
||||
QByteArray m = msg.toByteArray();
|
||||
|
||||
if (!_quiet)
|
||||
{
|
||||
_clearLine();
|
||||
}
|
||||
std::cerr << "Error: " << m.constData() << std::endl;
|
||||
_app->exit(1);
|
||||
}
|
||||
|
||||
void Cli::onDownloadProgress(QVariant dlnow, QVariant dltotal)
|
||||
{
|
||||
_printProgress("Writing", dlnow, dltotal);
|
||||
}
|
||||
|
||||
void Cli::onVerifyProgress(QVariant now, QVariant total)
|
||||
{
|
||||
_printProgress("Verifying", now, total);
|
||||
}
|
||||
|
||||
void Cli::onPreparationStatusUpdate(QVariant msg)
|
||||
{
|
||||
if (!_quiet)
|
||||
{
|
||||
QByteArray ascii = QByteArray(" ")+msg.toByteArray()+"\r";
|
||||
_clearLine();
|
||||
std::cerr << ascii.constData();
|
||||
}
|
||||
}
|
||||
|
||||
void Cli::_printProgress(const QByteArray &msg, QVariant now, QVariant total)
|
||||
{
|
||||
if (_quiet)
|
||||
return;
|
||||
|
||||
float n = now.toFloat();
|
||||
float t = total.toFloat();
|
||||
|
||||
if (t)
|
||||
{
|
||||
int percent = n/t*100;
|
||||
if (percent != _lastPercent || msg != _lastMsg)
|
||||
{
|
||||
QByteArray txt = QByteArray(" ")+msg+": ["+QByteArray(percent/5, '-')+'>'+QByteArray(20-percent/5, ' ')+"] "+QByteArray::number(percent)+" %\r";
|
||||
std::cerr << txt.constData();
|
||||
_lastPercent = percent;
|
||||
_lastMsg = msg;
|
||||
}
|
||||
}
|
||||
else if (msg != _lastMsg)
|
||||
{
|
||||
std::cerr << msg.constData() << "\r";
|
||||
_lastMsg = msg;
|
||||
}
|
||||
}
|
39
src/cli.h
Normal file
39
src/cli.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
#ifndef CLI_H
|
||||
#define CLI_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QVariant>
|
||||
|
||||
class ImageWriter;
|
||||
class QCoreApplication;
|
||||
|
||||
class Cli : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit Cli(int &argc, char *argv[]);
|
||||
virtual ~Cli();
|
||||
int main();
|
||||
|
||||
protected:
|
||||
QCoreApplication *_app;
|
||||
ImageWriter *_imageWriter;
|
||||
int _lastPercent;
|
||||
QByteArray _lastMsg;
|
||||
bool _quiet;
|
||||
|
||||
void _printProgress(const QByteArray &msg, QVariant now, QVariant total);
|
||||
void _clearLine();
|
||||
|
||||
protected slots:
|
||||
void onSuccess();
|
||||
void onError(QVariant msg);
|
||||
void onDownloadProgress(QVariant dlnow, QVariant dltotal);
|
||||
void onVerifyProgress(QVariant now, QVariant total);
|
||||
void onPreparationStatusUpdate(QVariant msg);
|
||||
|
||||
signals:
|
||||
|
||||
};
|
||||
|
||||
#endif // CLI_H
|
44
src/config.h
Normal file
44
src/config.h
Normal file
|
@ -0,0 +1,44 @@
|
|||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright (C) 2020 Raspberry Pi Ltd
|
||||
*/
|
||||
|
||||
|
||||
/* Repository URL */
|
||||
#define OSLIST_URL "https://downloads.raspberrypi.org/os_list_imagingutility_v3.json"
|
||||
|
||||
/* Time synchronization URL (only used on eglfs QPA platform, URL must be HTTP) */
|
||||
#define TIME_URL "http://downloads.raspberrypi.org/os_list_imagingutility_v3.json?time_synchronization"
|
||||
|
||||
/* Phone home the name of images downloaded for image popularity ranking */
|
||||
#define TELEMETRY_URL "https://rpi-imager-stats.raspberrypi.com/downloads"
|
||||
#define TELEMETRY_ENABLED_DEFAULT true
|
||||
|
||||
/* Hash algorithm for verifying (uncompressed image) checksum */
|
||||
#define OSLIST_HASH_ALGORITHM QCryptographicHash::Sha256
|
||||
|
||||
/* Hide system drives from list */
|
||||
#define DRIVELIST_FILTER_SYSTEM_DRIVES true
|
||||
|
||||
/* Update progressbar every 0.1 second */
|
||||
#define PROGRESS_UPDATE_INTERVAL 100
|
||||
|
||||
/* Block size used for writes (currently used when using .zip images only) */
|
||||
#define IMAGEWRITER_BLOCKSIZE 1*1024*1024
|
||||
|
||||
/* Block size used with uncompressed images */
|
||||
#define IMAGEWRITER_UNCOMPRESSED_BLOCKSIZE 128*1024
|
||||
|
||||
/* Block size used when reading during verify stage */
|
||||
#define IMAGEWRITER_VERIFY_BLOCKSIZE 128*1024
|
||||
|
||||
/* Enable caching */
|
||||
#define IMAGEWRITER_ENABLE_CACHE_DEFAULT true
|
||||
|
||||
/* Do not cache if it would bring free disk space under 5 GB */
|
||||
#define IMAGEWRITER_MINIMAL_SPACE_FOR_CACHING 5*1024*1024*1024ll
|
||||
|
||||
#endif // CONFIG_H
|
249
src/countries.txt
Normal file
249
src/countries.txt
Normal file
|
@ -0,0 +1,249 @@
|
|||
AD
|
||||
AE
|
||||
AF
|
||||
AG
|
||||
AI
|
||||
AL
|
||||
AM
|
||||
AO
|
||||
AQ
|
||||
AR
|
||||
AS
|
||||
AT
|
||||
AU
|
||||
AW
|
||||
AX
|
||||
AZ
|
||||
BA
|
||||
BB
|
||||
BD
|
||||
BE
|
||||
BF
|
||||
BG
|
||||
BH
|
||||
BI
|
||||
BJ
|
||||
BL
|
||||
BM
|
||||
BN
|
||||
BO
|
||||
BQ
|
||||
BR
|
||||
BS
|
||||
BT
|
||||
BV
|
||||
BW
|
||||
BY
|
||||
BZ
|
||||
CA
|
||||
CC
|
||||
CD
|
||||
CF
|
||||
CG
|
||||
CH
|
||||
CI
|
||||
CK
|
||||
CL
|
||||
CM
|
||||
CN
|
||||
CO
|
||||
CR
|
||||
CU
|
||||
CV
|
||||
CW
|
||||
CX
|
||||
CY
|
||||
CZ
|
||||
DE
|
||||
DJ
|
||||
DK
|
||||
DM
|
||||
DO
|
||||
DZ
|
||||
EC
|
||||
EE
|
||||
EG
|
||||
EH
|
||||
ER
|
||||
ES
|
||||
ET
|
||||
FI
|
||||
FJ
|
||||
FK
|
||||
FM
|
||||
FO
|
||||
FR
|
||||
GA
|
||||
GB
|
||||
GD
|
||||
GE
|
||||
GF
|
||||
GG
|
||||
GH
|
||||
GI
|
||||
GL
|
||||
GM
|
||||
GN
|
||||
GP
|
||||
GQ
|
||||
GR
|
||||
GS
|
||||
GT
|
||||
GU
|
||||
GW
|
||||
GY
|
||||
HK
|
||||
HM
|
||||
HN
|
||||
HR
|
||||
HT
|
||||
HU
|
||||
ID
|
||||
IE
|
||||
IL
|
||||
IM
|
||||
IN
|
||||
IO
|
||||
IQ
|
||||
IR
|
||||
IS
|
||||
IT
|
||||
JE
|
||||
JM
|
||||
JO
|
||||
JP
|
||||
KE
|
||||
KG
|
||||
KH
|
||||
KI
|
||||
KM
|
||||
KN
|
||||
KP
|
||||
KR
|
||||
KW
|
||||
KY
|
||||
KZ
|
||||
LA
|
||||
LB
|
||||
LC
|
||||
LI
|
||||
LK
|
||||
LR
|
||||
LS
|
||||
LT
|
||||
LU
|
||||
LV
|
||||
LY
|
||||
MA
|
||||
MC
|
||||
MD
|
||||
ME
|
||||
MF
|
||||
MG
|
||||
MH
|
||||
MK
|
||||
ML
|
||||
MM
|
||||
MN
|
||||
MO
|
||||
MP
|
||||
MQ
|
||||
MR
|
||||
MS
|
||||
MT
|
||||
MU
|
||||
MV
|
||||
MW
|
||||
MX
|
||||
MY
|
||||
MZ
|
||||
NA
|
||||
NC
|
||||
NE
|
||||
NF
|
||||
NG
|
||||
NI
|
||||
NL
|
||||
NO
|
||||
NP
|
||||
NR
|
||||
NU
|
||||
NZ
|
||||
OM
|
||||
PA
|
||||
PE
|
||||
PF
|
||||
PG
|
||||
PH
|
||||
PK
|
||||
PL
|
||||
PM
|
||||
PN
|
||||
PR
|
||||
PS
|
||||
PT
|
||||
PW
|
||||
PY
|
||||
QA
|
||||
RE
|
||||
RO
|
||||
RS
|
||||
RU
|
||||
RW
|
||||
SA
|
||||
SB
|
||||
SC
|
||||
SD
|
||||
SE
|
||||
SG
|
||||
SH
|
||||
SI
|
||||
SJ
|
||||
SK
|
||||
SL
|
||||
SM
|
||||
SN
|
||||
SO
|
||||
SR
|
||||
SS
|
||||
ST
|
||||
SV
|
||||
SX
|
||||
SY
|
||||
SZ
|
||||
TC
|
||||
TD
|
||||
TF
|
||||
TG
|
||||
TH
|
||||
TJ
|
||||
TK
|
||||
TL
|
||||
TM
|
||||
TN
|
||||
TO
|
||||
TR
|
||||
TT
|
||||
TV
|
||||
TW
|
||||
TZ
|
||||
UA
|
||||
UG
|
||||
UM
|
||||
US
|
||||
UY
|
||||
UZ
|
||||
VA
|
||||
VC
|
||||
VE
|
||||
VG
|
||||
VI
|
||||
VN
|
||||
VU
|
||||
WF
|
||||
WS
|
||||
YE
|
||||
YT
|
||||
ZA
|
||||
ZM
|
||||
ZW
|
1
src/dependencies/cmcurl/CMake/CMakeConfigurableFile.in
Normal file
1
src/dependencies/cmcurl/CMake/CMakeConfigurableFile.in
Normal file
|
@ -0,0 +1 @@
|
|||
@CMAKE_CONFIGURABLE_FILE_CONTENT@
|
61
src/dependencies/cmcurl/CMake/CurlSymbolHiding.cmake
Normal file
61
src/dependencies/cmcurl/CMake/CurlSymbolHiding.cmake
Normal file
|
@ -0,0 +1,61 @@
|
|||
include(CheckCSourceCompiles)
|
||||
|
||||
option(CURL_HIDDEN_SYMBOLS "Set to ON to hide libcurl internal symbols (=hide all symbols that aren't officially external)." ON)
|
||||
mark_as_advanced(CURL_HIDDEN_SYMBOLS)
|
||||
|
||||
if(CURL_HIDDEN_SYMBOLS)
|
||||
set(SUPPORTS_SYMBOL_HIDING FALSE)
|
||||
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
set(SUPPORTS_SYMBOL_HIDING TRUE)
|
||||
set(_SYMBOL_EXTERN "__attribute__ ((__visibility__ (\"default\")))")
|
||||
set(_CFLAG_SYMBOLS_HIDE "-fvisibility=hidden")
|
||||
elseif(CMAKE_COMPILER_IS_GNUCC)
|
||||
if(NOT CMAKE_VERSION VERSION_LESS 2.8.10)
|
||||
set(GCC_VERSION ${CMAKE_C_COMPILER_VERSION})
|
||||
else()
|
||||
execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion
|
||||
OUTPUT_VARIABLE GCC_VERSION)
|
||||
endif()
|
||||
if(NOT GCC_VERSION VERSION_LESS 3.4)
|
||||
# note: this is considered buggy prior to 4.0 but the autotools don't care, so let's ignore that fact
|
||||
set(SUPPORTS_SYMBOL_HIDING TRUE)
|
||||
set(_SYMBOL_EXTERN "__attribute__ ((__visibility__ (\"default\")))")
|
||||
set(_CFLAG_SYMBOLS_HIDE "-fvisibility=hidden")
|
||||
endif()
|
||||
elseif(CMAKE_C_COMPILER_ID MATCHES "SunPro" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 8.0)
|
||||
set(SUPPORTS_SYMBOL_HIDING TRUE)
|
||||
set(_SYMBOL_EXTERN "__global")
|
||||
set(_CFLAG_SYMBOLS_HIDE "-xldscope=hidden")
|
||||
elseif(CMAKE_C_COMPILER_ID MATCHES "Intel" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 9.0)
|
||||
# note: this should probably just check for version 9.1.045 but I'm not 100% sure
|
||||
# so let's to it the same way autotools do.
|
||||
set(SUPPORTS_SYMBOL_HIDING TRUE)
|
||||
set(_SYMBOL_EXTERN "__attribute__ ((__visibility__ (\"default\")))")
|
||||
set(_CFLAG_SYMBOLS_HIDE "-fvisibility=hidden")
|
||||
check_c_source_compiles("#include <stdio.h>
|
||||
int main (void) { printf(\"icc fvisibility bug test\"); return 0; }" _no_bug)
|
||||
if(NOT _no_bug)
|
||||
set(SUPPORTS_SYMBOL_HIDING FALSE)
|
||||
set(_SYMBOL_EXTERN "")
|
||||
set(_CFLAG_SYMBOLS_HIDE "")
|
||||
endif()
|
||||
elseif(MSVC)
|
||||
set(SUPPORTS_SYMBOL_HIDING TRUE)
|
||||
endif()
|
||||
|
||||
set(HIDES_CURL_PRIVATE_SYMBOLS ${SUPPORTS_SYMBOL_HIDING})
|
||||
elseif(MSVC)
|
||||
if(NOT CMAKE_VERSION VERSION_LESS 3.7)
|
||||
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE) #present since 3.4.3 but broken
|
||||
set(HIDES_CURL_PRIVATE_SYMBOLS FALSE)
|
||||
else()
|
||||
message(WARNING "Hiding private symbols regardless CURL_HIDDEN_SYMBOLS being disabled.")
|
||||
set(HIDES_CURL_PRIVATE_SYMBOLS TRUE)
|
||||
endif()
|
||||
else()
|
||||
set(HIDES_CURL_PRIVATE_SYMBOLS FALSE)
|
||||
endif()
|
||||
|
||||
set(CURL_CFLAG_SYMBOLS_HIDE ${_CFLAG_SYMBOLS_HIDE})
|
||||
set(CURL_EXTERN_SYMBOL ${_SYMBOL_EXTERN})
|
615
src/dependencies/cmcurl/CMake/CurlTests.c
Normal file
615
src/dependencies/cmcurl/CMake/CurlTests.c
Normal file
|
@ -0,0 +1,615 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
#ifdef TIME_WITH_SYS_TIME
|
||||
/* Time with sys/time test */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
if ((struct tm *) 0)
|
||||
return 0;
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FCNTL_O_NONBLOCK
|
||||
|
||||
/* headers for FCNTL_O_NONBLOCK test */
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
/* */
|
||||
#if defined(sun) || defined(__sun__) || \
|
||||
defined(__SUNPRO_C) || defined(__SUNPRO_CC)
|
||||
# if defined(__SVR4) || defined(__srv4__)
|
||||
# define PLATFORM_SOLARIS
|
||||
# else
|
||||
# define PLATFORM_SUNOS4
|
||||
# endif
|
||||
#endif
|
||||
#if (defined(_AIX) || defined(__xlC__)) && !defined(_AIX41)
|
||||
# define PLATFORM_AIX_V3
|
||||
#endif
|
||||
/* */
|
||||
#if defined(PLATFORM_SUNOS4) || defined(PLATFORM_AIX_V3) || defined(__BEOS__)
|
||||
#error "O_NONBLOCK does not work on this platform"
|
||||
#endif
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
/* O_NONBLOCK source test */
|
||||
int flags = 0;
|
||||
if(0 != fcntl(0, F_SETFL, flags | O_NONBLOCK))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* tests for gethostbyaddr_r or gethostbyname_r */
|
||||
#if defined(HAVE_GETHOSTBYADDR_R_5_REENTRANT) || \
|
||||
defined(HAVE_GETHOSTBYADDR_R_7_REENTRANT) || \
|
||||
defined(HAVE_GETHOSTBYADDR_R_8_REENTRANT) || \
|
||||
defined(HAVE_GETHOSTBYNAME_R_3_REENTRANT) || \
|
||||
defined(HAVE_GETHOSTBYNAME_R_5_REENTRANT) || \
|
||||
defined(HAVE_GETHOSTBYNAME_R_6_REENTRANT)
|
||||
# define _REENTRANT
|
||||
/* no idea whether _REENTRANT is always set, just invent a new flag */
|
||||
# define TEST_GETHOSTBYFOO_REENTRANT
|
||||
#endif
|
||||
#if defined(HAVE_GETHOSTBYADDR_R_5) || \
|
||||
defined(HAVE_GETHOSTBYADDR_R_7) || \
|
||||
defined(HAVE_GETHOSTBYADDR_R_8) || \
|
||||
defined(HAVE_GETHOSTBYNAME_R_3) || \
|
||||
defined(HAVE_GETHOSTBYNAME_R_5) || \
|
||||
defined(HAVE_GETHOSTBYNAME_R_6) || \
|
||||
defined(TEST_GETHOSTBYFOO_REENTRANT)
|
||||
#include <sys/types.h>
|
||||
#include <netdb.h>
|
||||
int main(void)
|
||||
{
|
||||
char *address = "example.com";
|
||||
int length = 0;
|
||||
int type = 0;
|
||||
struct hostent h;
|
||||
int rc = 0;
|
||||
#if defined(HAVE_GETHOSTBYADDR_R_5) || \
|
||||
defined(HAVE_GETHOSTBYADDR_R_5_REENTRANT) || \
|
||||
\
|
||||
defined(HAVE_GETHOSTBYNAME_R_3) || \
|
||||
defined(HAVE_GETHOSTBYNAME_R_3_REENTRANT)
|
||||
struct hostent_data hdata;
|
||||
#elif defined(HAVE_GETHOSTBYADDR_R_7) || \
|
||||
defined(HAVE_GETHOSTBYADDR_R_7_REENTRANT) || \
|
||||
defined(HAVE_GETHOSTBYADDR_R_8) || \
|
||||
defined(HAVE_GETHOSTBYADDR_R_8_REENTRANT) || \
|
||||
\
|
||||
defined(HAVE_GETHOSTBYNAME_R_5) || \
|
||||
defined(HAVE_GETHOSTBYNAME_R_5_REENTRANT) || \
|
||||
defined(HAVE_GETHOSTBYNAME_R_6) || \
|
||||
defined(HAVE_GETHOSTBYNAME_R_6_REENTRANT)
|
||||
char buffer[8192];
|
||||
int h_errnop;
|
||||
struct hostent *hp;
|
||||
#endif
|
||||
|
||||
#ifndef gethostbyaddr_r
|
||||
(void)gethostbyaddr_r;
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_GETHOSTBYADDR_R_5) || \
|
||||
defined(HAVE_GETHOSTBYADDR_R_5_REENTRANT)
|
||||
rc = gethostbyaddr_r(address, length, type, &h, &hdata);
|
||||
#elif defined(HAVE_GETHOSTBYADDR_R_7) || \
|
||||
defined(HAVE_GETHOSTBYADDR_R_7_REENTRANT)
|
||||
hp = gethostbyaddr_r(address, length, type, &h, buffer, 8192, &h_errnop);
|
||||
(void)hp;
|
||||
#elif defined(HAVE_GETHOSTBYADDR_R_8) || \
|
||||
defined(HAVE_GETHOSTBYADDR_R_8_REENTRANT)
|
||||
rc = gethostbyaddr_r(address, length, type, &h, buffer, 8192, &hp, &h_errnop);
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_GETHOSTBYNAME_R_3) || \
|
||||
defined(HAVE_GETHOSTBYNAME_R_3_REENTRANT)
|
||||
rc = gethostbyname_r(address, &h, &hdata);
|
||||
#elif defined(HAVE_GETHOSTBYNAME_R_5) || \
|
||||
defined(HAVE_GETHOSTBYNAME_R_5_REENTRANT)
|
||||
rc = gethostbyname_r(address, &h, buffer, 8192, &h_errnop);
|
||||
(void)hp; /* not used for test */
|
||||
#elif defined(HAVE_GETHOSTBYNAME_R_6) || \
|
||||
defined(HAVE_GETHOSTBYNAME_R_6_REENTRANT)
|
||||
rc = gethostbyname_r(address, &h, buffer, 8192, &hp, &h_errnop);
|
||||
#endif
|
||||
|
||||
(void)length;
|
||||
(void)type;
|
||||
(void)rc;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SOCKLEN_T
|
||||
#ifdef _WIN32
|
||||
#include <ws2tcpip.h>
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
int
|
||||
main ()
|
||||
{
|
||||
if ((socklen_t *) 0)
|
||||
return 0;
|
||||
if (sizeof (socklen_t))
|
||||
return 0;
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_IN_ADDR_T
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
if ((in_addr_t *) 0)
|
||||
return 0;
|
||||
if (sizeof (in_addr_t))
|
||||
return 0;
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_BOOL_T
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDBOOL_H
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
int
|
||||
main ()
|
||||
{
|
||||
if (sizeof (bool *) )
|
||||
return 0;
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef STDC_HEADERS
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <float.h>
|
||||
int main() { return 0; }
|
||||
#endif
|
||||
#ifdef RETSIGTYPE_TEST
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
#ifdef signal
|
||||
# undef signal
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
extern "C" void (*signal (int, void (*)(int)))(int);
|
||||
#else
|
||||
void (*signal ()) ();
|
||||
#endif
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_INET_NTOA_R_DECL
|
||||
#include <arpa/inet.h>
|
||||
|
||||
typedef void (*func_type)();
|
||||
|
||||
int main()
|
||||
{
|
||||
#ifndef inet_ntoa_r
|
||||
func_type func;
|
||||
func = (func_type)inet_ntoa_r;
|
||||
(void)func;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_INET_NTOA_R_DECL_REENTRANT
|
||||
#define _REENTRANT
|
||||
#include <arpa/inet.h>
|
||||
|
||||
typedef void (*func_type)();
|
||||
|
||||
int main()
|
||||
{
|
||||
#ifndef inet_ntoa_r
|
||||
func_type func;
|
||||
func = (func_type)&inet_ntoa_r;
|
||||
(void)func;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_GETADDRINFO
|
||||
#include <netdb.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
int main(void) {
|
||||
struct addrinfo hints, *ai;
|
||||
int error;
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
#ifndef getaddrinfo
|
||||
(void)getaddrinfo;
|
||||
#endif
|
||||
error = getaddrinfo("127.0.0.1", "8080", &hints, &ai);
|
||||
if (error) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_FILE_OFFSET_BITS
|
||||
#ifdef _FILE_OFFSET_BITS
|
||||
#undef _FILE_OFFSET_BITS
|
||||
#endif
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
#include <sys/types.h>
|
||||
/* Check that off_t can represent 2**63 - 1 correctly.
|
||||
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
||||
since some C++ compilers masquerading as C compilers
|
||||
incorrectly reject 9223372036854775807. */
|
||||
#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
|
||||
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
||||
&& LARGE_OFF_T % 2147483647 == 1)
|
||||
? 1 : -1];
|
||||
int main () { ; return 0; }
|
||||
#endif
|
||||
#ifdef HAVE_IOCTLSOCKET
|
||||
/* includes start */
|
||||
#ifdef HAVE_WINDOWS_H
|
||||
# ifndef WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# endif
|
||||
# include <windows.h>
|
||||
# ifdef HAVE_WINSOCK2_H
|
||||
# include <winsock2.h>
|
||||
# else
|
||||
# ifdef HAVE_WINSOCK_H
|
||||
# include <winsock.h>
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
|
||||
/* ioctlsocket source code */
|
||||
int socket;
|
||||
unsigned long flags = ioctlsocket(socket, FIONBIO, &flags);
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
#ifdef HAVE_IOCTLSOCKET_CAMEL
|
||||
/* includes start */
|
||||
#ifdef HAVE_WINDOWS_H
|
||||
# ifndef WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# endif
|
||||
# include <windows.h>
|
||||
# ifdef HAVE_WINSOCK2_H
|
||||
# include <winsock2.h>
|
||||
# else
|
||||
# ifdef HAVE_WINSOCK_H
|
||||
# include <winsock.h>
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
|
||||
/* IoctlSocket source code */
|
||||
if(0 != IoctlSocket(0, 0, 0))
|
||||
return 1;
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_IOCTLSOCKET_CAMEL_FIONBIO
|
||||
/* includes start */
|
||||
#ifdef HAVE_WINDOWS_H
|
||||
# ifndef WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# endif
|
||||
# include <windows.h>
|
||||
# ifdef HAVE_WINSOCK2_H
|
||||
# include <winsock2.h>
|
||||
# else
|
||||
# ifdef HAVE_WINSOCK_H
|
||||
# include <winsock.h>
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
|
||||
/* IoctlSocket source code */
|
||||
long flags = 0;
|
||||
if(0 != ioctlsocket(0, FIONBIO, &flags))
|
||||
return 1;
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_IOCTLSOCKET_FIONBIO
|
||||
/* includes start */
|
||||
#ifdef HAVE_WINDOWS_H
|
||||
# ifndef WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# endif
|
||||
# include <windows.h>
|
||||
# ifdef HAVE_WINSOCK2_H
|
||||
# include <winsock2.h>
|
||||
# else
|
||||
# ifdef HAVE_WINSOCK_H
|
||||
# include <winsock.h>
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
|
||||
int flags = 0;
|
||||
if(0 != ioctlsocket(0, FIONBIO, &flags))
|
||||
return 1;
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_IOCTL_FIONBIO
|
||||
/* headers for FIONBIO test */
|
||||
/* includes start */
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
# include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_IOCTL_H
|
||||
# include <sys/ioctl.h>
|
||||
#endif
|
||||
#ifdef HAVE_STROPTS_H
|
||||
# include <stropts.h>
|
||||
#endif
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
|
||||
int flags = 0;
|
||||
if(0 != ioctl(0, FIONBIO, &flags))
|
||||
return 1;
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_IOCTL_SIOCGIFADDR
|
||||
/* headers for FIONBIO test */
|
||||
/* includes start */
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
# include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_IOCTL_H
|
||||
# include <sys/ioctl.h>
|
||||
#endif
|
||||
#ifdef HAVE_STROPTS_H
|
||||
# include <stropts.h>
|
||||
#endif
|
||||
#include <net/if.h>
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
struct ifreq ifr;
|
||||
if(0 != ioctl(0, SIOCGIFADDR, &ifr))
|
||||
return 1;
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_SETSOCKOPT_SO_NONBLOCK
|
||||
/* includes start */
|
||||
#ifdef HAVE_WINDOWS_H
|
||||
# ifndef WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# endif
|
||||
# include <windows.h>
|
||||
# ifdef HAVE_WINSOCK2_H
|
||||
# include <winsock2.h>
|
||||
# else
|
||||
# ifdef HAVE_WINSOCK_H
|
||||
# include <winsock.h>
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
/* includes start */
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
# include <sys/socket.h>
|
||||
#endif
|
||||
/* includes end */
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
if(0 != setsockopt(0, SOL_SOCKET, SO_NONBLOCK, 0, 0))
|
||||
return 1;
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_GLIBC_STRERROR_R
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
void check(char c) {}
|
||||
|
||||
int
|
||||
main () {
|
||||
char buffer[1024];
|
||||
/* This will not compile if strerror_r does not return a char* */
|
||||
check(strerror_r(EACCES, buffer, sizeof(buffer))[0]);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_POSIX_STRERROR_R
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
/* float, because a pointer can't be implicitly cast to float */
|
||||
void check(float f) {}
|
||||
|
||||
int
|
||||
main () {
|
||||
char buffer[1024];
|
||||
/* This will not compile if strerror_r does not return an int */
|
||||
check(strerror_r(EACCES, buffer, sizeof(buffer)));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_FSETXATTR_6
|
||||
#include <sys/xattr.h> /* header from libc, not from libattr */
|
||||
int
|
||||
main() {
|
||||
fsetxattr(0, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_FSETXATTR_5
|
||||
#include <sys/xattr.h> /* header from libc, not from libattr */
|
||||
int
|
||||
main() {
|
||||
fsetxattr(0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_CLOCK_GETTIME_MONOTONIC
|
||||
#include <time.h>
|
||||
int
|
||||
main() {
|
||||
struct timespec ts = {0, 0};
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_BUILTIN_AVAILABLE
|
||||
int
|
||||
main() {
|
||||
if(__builtin_available(macOS 10.12, *)) {}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_VARIADIC_MACROS_C99
|
||||
#define c99_vmacro3(first, ...) fun3(first, __VA_ARGS__)
|
||||
#define c99_vmacro2(first, ...) fun2(first, __VA_ARGS__)
|
||||
|
||||
int fun3(int arg1, int arg2, int arg3);
|
||||
int fun2(int arg1, int arg2);
|
||||
|
||||
int fun3(int arg1, int arg2, int arg3) {
|
||||
return arg1 + arg2 + arg3;
|
||||
}
|
||||
int fun2(int arg1, int arg2) {
|
||||
return arg1 + arg2;
|
||||
}
|
||||
|
||||
int
|
||||
main() {
|
||||
int res3 = c99_vmacro3(1, 2, 3);
|
||||
int res2 = c99_vmacro2(1, 2);
|
||||
(void)res3;
|
||||
(void)res2;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_VARIADIC_MACROS_GCC
|
||||
#define gcc_vmacro3(first, args...) fun3(first, args)
|
||||
#define gcc_vmacro2(first, args...) fun2(first, args)
|
||||
|
||||
int fun3(int arg1, int arg2, int arg3);
|
||||
int fun2(int arg1, int arg2);
|
||||
|
||||
int fun3(int arg1, int arg2, int arg3) {
|
||||
return arg1 + arg2 + arg3;
|
||||
}
|
||||
int fun2(int arg1, int arg2) {
|
||||
return arg1 + arg2;
|
||||
}
|
||||
|
||||
int
|
||||
main() {
|
||||
int res3 = gcc_vmacro3(1, 2, 3);
|
||||
int res2 = gcc_vmacro2(1, 2);
|
||||
(void)res3;
|
||||
(void)res2;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
20
src/dependencies/cmcurl/CMake/FindBrotli.cmake
Normal file
20
src/dependencies/cmcurl/CMake/FindBrotli.cmake
Normal file
|
@ -0,0 +1,20 @@
|
|||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
find_path(BROTLI_INCLUDE_DIR "brotli/decode.h")
|
||||
|
||||
find_library(BROTLICOMMON_LIBRARY NAMES brotlicommon)
|
||||
find_library(BROTLIDEC_LIBRARY NAMES brotlidec)
|
||||
|
||||
find_package_handle_standard_args(BROTLI
|
||||
FOUND_VAR
|
||||
BROTLI_FOUND
|
||||
REQUIRED_VARS
|
||||
BROTLIDEC_LIBRARY
|
||||
BROTLICOMMON_LIBRARY
|
||||
BROTLI_INCLUDE_DIR
|
||||
FAIL_MESSAGE
|
||||
"Could NOT find BROTLI"
|
||||
)
|
||||
|
||||
set(BROTLI_INCLUDE_DIRS ${BROTLI_INCLUDE_DIR})
|
||||
set(BROTLI_LIBRARIES ${BROTLICOMMON_LIBRARY} ${BROTLIDEC_LIBRARY})
|
42
src/dependencies/cmcurl/CMake/FindCARES.cmake
Normal file
42
src/dependencies/cmcurl/CMake/FindCARES.cmake
Normal file
|
@ -0,0 +1,42 @@
|
|||
# - Find c-ares
|
||||
# Find the c-ares includes and library
|
||||
# This module defines
|
||||
# CARES_INCLUDE_DIR, where to find ares.h, etc.
|
||||
# CARES_LIBRARIES, the libraries needed to use c-ares.
|
||||
# CARES_FOUND, If false, do not try to use c-ares.
|
||||
# also defined, but not for general use are
|
||||
# CARES_LIBRARY, where to find the c-ares library.
|
||||
|
||||
find_path(CARES_INCLUDE_DIR ares.h
|
||||
/usr/local/include
|
||||
/usr/include
|
||||
)
|
||||
|
||||
set(CARES_NAMES ${CARES_NAMES} cares)
|
||||
find_library(CARES_LIBRARY
|
||||
NAMES ${CARES_NAMES}
|
||||
PATHS /usr/lib /usr/local/lib
|
||||
)
|
||||
|
||||
if(CARES_LIBRARY AND CARES_INCLUDE_DIR)
|
||||
set(CARES_LIBRARIES ${CARES_LIBRARY})
|
||||
set(CARES_FOUND "YES")
|
||||
else()
|
||||
set(CARES_FOUND "NO")
|
||||
endif()
|
||||
|
||||
|
||||
if(CARES_FOUND)
|
||||
if(NOT CARES_FIND_QUIETLY)
|
||||
message(STATUS "Found c-ares: ${CARES_LIBRARIES}")
|
||||
endif()
|
||||
else()
|
||||
if(CARES_FIND_REQUIRED)
|
||||
message(FATAL_ERROR "Could not find c-ares library")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
mark_as_advanced(
|
||||
CARES_LIBRARY
|
||||
CARES_INCLUDE_DIR
|
||||
)
|
285
src/dependencies/cmcurl/CMake/FindGSS.cmake
Normal file
285
src/dependencies/cmcurl/CMake/FindGSS.cmake
Normal file
|
@ -0,0 +1,285 @@
|
|||
# - Try to find the GSS Kerberos library
|
||||
# Once done this will define
|
||||
#
|
||||
# GSS_ROOT_DIR - Set this variable to the root installation of GSS
|
||||
#
|
||||
# Read-Only variables:
|
||||
# GSS_FOUND - system has the Heimdal library
|
||||
# GSS_FLAVOUR - "MIT" or "Heimdal" if anything found.
|
||||
# GSS_INCLUDE_DIR - the Heimdal include directory
|
||||
# GSS_LIBRARIES - The libraries needed to use GSS
|
||||
# GSS_LINK_DIRECTORIES - Directories to add to linker search path
|
||||
# GSS_LINKER_FLAGS - Additional linker flags
|
||||
# GSS_COMPILER_FLAGS - Additional compiler flags
|
||||
# GSS_VERSION - This is set to version advertised by pkg-config or read from manifest.
|
||||
# In case the library is found but no version info available it'll be set to "unknown"
|
||||
|
||||
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}"
|
||||
)
|
||||
|
||||
# try to find library using system pkg-config if user didn't specify root dir
|
||||
if(NOT GSS_ROOT_DIR AND NOT "$ENV{GSS_ROOT_DIR}")
|
||||
if(UNIX)
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_search_module(_GSS_PKG ${_MIT_MODNAME} ${_HEIMDAL_MODNAME})
|
||||
list(APPEND _GSS_ROOT_HINTS "${_GSS_PKG_PREFIX}")
|
||||
elseif(WIN32)
|
||||
list(APPEND _GSS_ROOT_HINTS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MIT\\Kerberos;InstallDir]")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT _GSS_FOUND) #not found by pkg-config. Let's 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
|
||||
)
|
||||
|
||||
# if not found in user-supplied directories, maybe system knows better
|
||||
find_file(_GSS_CONFIGURE_SCRIPT
|
||||
NAMES
|
||||
"krb5-config"
|
||||
PATH_SUFFIXES
|
||||
bin
|
||||
)
|
||||
|
||||
if(_GSS_CONFIGURE_SCRIPT)
|
||||
execute_process(
|
||||
COMMAND ${_GSS_CONFIGURE_SCRIPT} "--cflags" "gssapi"
|
||||
OUTPUT_VARIABLE _GSS_CFLAGS
|
||||
RESULT_VARIABLE _GSS_CONFIGURE_FAILED
|
||||
)
|
||||
message(STATUS "CFLAGS: ${_GSS_CFLAGS}")
|
||||
if(NOT _GSS_CONFIGURE_FAILED) # 0 means success
|
||||
# should also work in an odd case when multiple directories are given
|
||||
string(STRIP "${_GSS_CFLAGS}" _GSS_CFLAGS)
|
||||
string(REGEX REPLACE " +-I" ";" _GSS_CFLAGS "${_GSS_CFLAGS}")
|
||||
string(REGEX REPLACE " +-([^I][^ \\t;]*)" ";-\\1" _GSS_CFLAGS "${_GSS_CFLAGS}")
|
||||
|
||||
foreach(_flag ${_GSS_CFLAGS})
|
||||
if(_flag MATCHES "^-I.*")
|
||||
string(REGEX REPLACE "^-I" "" _val "${_flag}")
|
||||
list(APPEND _GSS_INCLUDE_DIR "${_val}")
|
||||
else()
|
||||
list(APPEND _GSS_COMPILER_FLAGS "${_flag}")
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
execute_process(
|
||||
COMMAND ${_GSS_CONFIGURE_SCRIPT} "--libs" "gssapi"
|
||||
OUTPUT_VARIABLE _GSS_LIB_FLAGS
|
||||
RESULT_VARIABLE _GSS_CONFIGURE_FAILED
|
||||
)
|
||||
message(STATUS "LDFLAGS: ${_GSS_LIB_FLAGS}")
|
||||
|
||||
if(NOT _GSS_CONFIGURE_FAILED) # 0 means success
|
||||
# this script gives us libraries and link directories. Blah. We have to deal with it.
|
||||
string(STRIP "${_GSS_LIB_FLAGS}" _GSS_LIB_FLAGS)
|
||||
string(REGEX REPLACE " +-(L|l)" ";-\\1" _GSS_LIB_FLAGS "${_GSS_LIB_FLAGS}")
|
||||
string(REGEX REPLACE " +-([^Ll][^ \\t;]*)" ";-\\1" _GSS_LIB_FLAGS "${_GSS_LIB_FLAGS}")
|
||||
|
||||
foreach(_flag ${_GSS_LIB_FLAGS})
|
||||
if(_flag MATCHES "^-l.*")
|
||||
string(REGEX REPLACE "^-l" "" _val "${_flag}")
|
||||
list(APPEND _GSS_LIBRARIES "${_val}")
|
||||
elseif(_flag MATCHES "^-L.*")
|
||||
string(REGEX REPLACE "^-L" "" _val "${_flag}")
|
||||
list(APPEND _GSS_LINK_DIRECTORIES "${_val}")
|
||||
else()
|
||||
list(APPEND _GSS_LINKER_FLAGS "${_flag}")
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
execute_process(
|
||||
COMMAND ${_GSS_CONFIGURE_SCRIPT} "--version"
|
||||
OUTPUT_VARIABLE _GSS_VERSION
|
||||
RESULT_VARIABLE _GSS_CONFIGURE_FAILED
|
||||
)
|
||||
|
||||
# older versions may not have the "--version" parameter. In this case we just don't care.
|
||||
if(_GSS_CONFIGURE_FAILED)
|
||||
set(_GSS_VERSION 0)
|
||||
endif()
|
||||
|
||||
execute_process(
|
||||
COMMAND ${_GSS_CONFIGURE_SCRIPT} "--vendor"
|
||||
OUTPUT_VARIABLE _GSS_VENDOR
|
||||
RESULT_VARIABLE _GSS_CONFIGURE_FAILED
|
||||
)
|
||||
|
||||
# older versions may not have the "--vendor" parameter. In this case we just don't care.
|
||||
if(_GSS_CONFIGURE_FAILED)
|
||||
set(GSS_FLAVOUR "Heimdal") # most probably, shouldn't really matter
|
||||
else()
|
||||
if(_GSS_VENDOR MATCHES ".*H|heimdal.*")
|
||||
set(GSS_FLAVOUR "Heimdal")
|
||||
else()
|
||||
set(GSS_FLAVOUR "MIT")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
else() # either there is no config script or we are on platform that doesn't provide one (Windows?)
|
||||
|
||||
find_path(_GSS_INCLUDE_DIR
|
||||
NAMES
|
||||
"gssapi/gssapi.h"
|
||||
HINTS
|
||||
${_GSS_ROOT_HINTS}
|
||||
PATH_SUFFIXES
|
||||
include
|
||||
inc
|
||||
)
|
||||
|
||||
if(_GSS_INCLUDE_DIR) #jay, we've found something
|
||||
set(CMAKE_REQUIRED_INCLUDES "${_GSS_INCLUDE_DIR}")
|
||||
check_include_files( "gssapi/gssapi_generic.h;gssapi/gssapi_krb5.h" _GSS_HAVE_MIT_HEADERS)
|
||||
|
||||
if(_GSS_HAVE_MIT_HEADERS)
|
||||
set(GSS_FLAVOUR "MIT")
|
||||
else()
|
||||
# prevent compiling the header - just check if we can include it
|
||||
set(CMAKE_REQUIRED_DEFINITIONS "${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()
|
||||
set(CMAKE_REQUIRED_DEFINITIONS "")
|
||||
endif()
|
||||
else()
|
||||
# I'm not convienced if this is the right way but this is what autotools do at the moment
|
||||
find_path(_GSS_INCLUDE_DIR
|
||||
NAMES
|
||||
"gssapi.h"
|
||||
HINTS
|
||||
${_GSS_ROOT_HINTS}
|
||||
PATH_SUFFIXES
|
||||
include
|
||||
inc
|
||||
)
|
||||
|
||||
if(_GSS_INCLUDE_DIR)
|
||||
set(GSS_FLAVOUR "Heimdal")
|
||||
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_DIR}" PATH)
|
||||
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 "MIT")
|
||||
set(_GSS_LIBNAME "gssapi64")
|
||||
else()
|
||||
set(_GSS_LIBNAME "libgssapi")
|
||||
endif()
|
||||
else()
|
||||
list(APPEND _GSS_LIBDIR_SUFFIXES "lib/i386")
|
||||
if(GSS_FLAVOUR STREQUAL "MIT")
|
||||
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 "MIT")
|
||||
set(_GSS_LIBNAME "gssapi_krb5")
|
||||
else()
|
||||
set(_GSS_LIBNAME "gssapi")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
find_library(_GSS_LIBRARIES
|
||||
NAMES
|
||||
${_GSS_LIBNAME}
|
||||
HINTS
|
||||
${_GSS_LIBDIR_HINTS}
|
||||
PATH_SUFFIXES
|
||||
${_GSS_LIBDIR_SUFFIXES}
|
||||
)
|
||||
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
if(_GSS_PKG_${_MIT_MODNAME}_VERSION)
|
||||
set(GSS_FLAVOUR "MIT")
|
||||
set(_GSS_VERSION _GSS_PKG_${_MIT_MODNAME}_VERSION)
|
||||
else()
|
||||
set(GSS_FLAVOUR "Heimdal")
|
||||
set(_GSS_VERSION _GSS_PKG_${_MIT_HEIMDAL}_VERSION)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(GSS_INCLUDE_DIR ${_GSS_INCLUDE_DIR})
|
||||
set(GSS_LIBRARIES ${_GSS_LIBRARIES})
|
||||
set(GSS_LINK_DIRECTORIES ${_GSS_LINK_DIRECTORIES})
|
||||
set(GSS_LINKER_FLAGS ${_GSS_LINKER_FLAGS})
|
||||
set(GSS_COMPILER_FLAGS ${_GSS_COMPILER_FLAGS})
|
||||
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")
|
||||
else()
|
||||
set(HEIMDAL_MANIFEST_FILE "Heimdal.Application.x86.manifest")
|
||||
endif()
|
||||
|
||||
if(EXISTS "${GSS_INCLUDE_DIR}/${HEIMDAL_MANIFEST_FILE}")
|
||||
file(STRINGS "${GSS_INCLUDE_DIR}/${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()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
set(_GSS_REQUIRED_VARS GSS_LIBRARIES GSS_FLAVOUR)
|
||||
|
||||
find_package_handle_standard_args(GSS
|
||||
REQUIRED_VARS
|
||||
${_GSS_REQUIRED_VARS}
|
||||
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"
|
||||
)
|
||||
|
||||
mark_as_advanced(GSS_INCLUDE_DIR GSS_LIBRARIES)
|
35
src/dependencies/cmcurl/CMake/FindLibSSH2.cmake
Normal file
35
src/dependencies/cmcurl/CMake/FindLibSSH2.cmake
Normal file
|
@ -0,0 +1,35 @@
|
|||
# - Try to find the libssh2 library
|
||||
# Once done this will define
|
||||
#
|
||||
# LIBSSH2_FOUND - system has the libssh2 library
|
||||
# LIBSSH2_INCLUDE_DIR - the libssh2 include directory
|
||||
# LIBSSH2_LIBRARY - the libssh2 library name
|
||||
|
||||
if(LIBSSH2_INCLUDE_DIR AND LIBSSH2_LIBRARY)
|
||||
set(LibSSH2_FIND_QUIETLY TRUE)
|
||||
endif()
|
||||
|
||||
find_path(LIBSSH2_INCLUDE_DIR libssh2.h
|
||||
)
|
||||
|
||||
find_library(LIBSSH2_LIBRARY NAMES ssh2
|
||||
)
|
||||
|
||||
if(LIBSSH2_INCLUDE_DIR)
|
||||
file(STRINGS "${LIBSSH2_INCLUDE_DIR}/libssh2.h" libssh2_version_str REGEX "^#define[\t ]+LIBSSH2_VERSION_NUM[\t ]+0x[0-9][0-9][0-9][0-9][0-9][0-9].*")
|
||||
|
||||
string(REGEX REPLACE "^.*LIBSSH2_VERSION_NUM[\t ]+0x([0-9][0-9]).*$" "\\1" LIBSSH2_VERSION_MAJOR "${libssh2_version_str}")
|
||||
string(REGEX REPLACE "^.*LIBSSH2_VERSION_NUM[\t ]+0x[0-9][0-9]([0-9][0-9]).*$" "\\1" LIBSSH2_VERSION_MINOR "${libssh2_version_str}")
|
||||
string(REGEX REPLACE "^.*LIBSSH2_VERSION_NUM[\t ]+0x[0-9][0-9][0-9][0-9]([0-9][0-9]).*$" "\\1" LIBSSH2_VERSION_PATCH "${libssh2_version_str}")
|
||||
|
||||
string(REGEX REPLACE "^0(.+)" "\\1" LIBSSH2_VERSION_MAJOR "${LIBSSH2_VERSION_MAJOR}")
|
||||
string(REGEX REPLACE "^0(.+)" "\\1" LIBSSH2_VERSION_MINOR "${LIBSSH2_VERSION_MINOR}")
|
||||
string(REGEX REPLACE "^0(.+)" "\\1" LIBSSH2_VERSION_PATCH "${LIBSSH2_VERSION_PATCH}")
|
||||
|
||||
set(LIBSSH2_VERSION "${LIBSSH2_VERSION_MAJOR}.${LIBSSH2_VERSION_MINOR}.${LIBSSH2_VERSION_PATCH}")
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(LibSSH2 DEFAULT_MSG LIBSSH2_INCLUDE_DIR LIBSSH2_LIBRARY )
|
||||
|
||||
mark_as_advanced(LIBSSH2_INCLUDE_DIR LIBSSH2_LIBRARY LIBSSH2_VERSION_MAJOR LIBSSH2_VERSION_MINOR LIBSSH2_VERSION_PATCH LIBSSH2_VERSION)
|
13
src/dependencies/cmcurl/CMake/FindMbedTLS.cmake
Normal file
13
src/dependencies/cmcurl/CMake/FindMbedTLS.cmake
Normal file
|
@ -0,0 +1,13 @@
|
|||
find_path(MBEDTLS_INCLUDE_DIRS mbedtls/ssl.h)
|
||||
|
||||
find_library(MBEDTLS_LIBRARY mbedtls)
|
||||
find_library(MBEDX509_LIBRARY mbedx509)
|
||||
find_library(MBEDCRYPTO_LIBRARY mbedcrypto)
|
||||
|
||||
set(MBEDTLS_LIBRARIES "${MBEDTLS_LIBRARY}" "${MBEDX509_LIBRARY}" "${MBEDCRYPTO_LIBRARY}")
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(MBEDTLS DEFAULT_MSG
|
||||
MBEDTLS_INCLUDE_DIRS MBEDTLS_LIBRARY MBEDX509_LIBRARY MBEDCRYPTO_LIBRARY)
|
||||
|
||||
mark_as_advanced(MBEDTLS_INCLUDE_DIRS MBEDTLS_LIBRARY MBEDX509_LIBRARY MBEDCRYPTO_LIBRARY)
|
18
src/dependencies/cmcurl/CMake/FindNGHTTP2.cmake
Normal file
18
src/dependencies/cmcurl/CMake/FindNGHTTP2.cmake
Normal file
|
@ -0,0 +1,18 @@
|
|||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
find_path(NGHTTP2_INCLUDE_DIR "nghttp2/nghttp2.h")
|
||||
|
||||
find_library(NGHTTP2_LIBRARY NAMES nghttp2)
|
||||
|
||||
find_package_handle_standard_args(NGHTTP2
|
||||
FOUND_VAR
|
||||
NGHTTP2_FOUND
|
||||
REQUIRED_VARS
|
||||
NGHTTP2_LIBRARY
|
||||
NGHTTP2_INCLUDE_DIR
|
||||
FAIL_MESSAGE
|
||||
"Could NOT find NGHTTP2"
|
||||
)
|
||||
|
||||
set(NGHTTP2_INCLUDE_DIRS ${NGHTTP2_INCLUDE_DIR})
|
||||
set(NGHTTP2_LIBRARIES ${NGHTTP2_LIBRARY})
|
88
src/dependencies/cmcurl/CMake/Macros.cmake
Normal file
88
src/dependencies/cmcurl/CMake/Macros.cmake
Normal file
|
@ -0,0 +1,88 @@
|
|||
#File defines convenience macros for available feature testing
|
||||
|
||||
# This macro checks if the symbol exists in the library and if it
|
||||
# does, it prepends library to the list. It is intended to be called
|
||||
# multiple times with a sequence of possibly dependent libraries in
|
||||
# order of least-to-most-dependent. Some libraries depend on others
|
||||
# to link correctly.
|
||||
macro(check_library_exists_concat LIBRARY SYMBOL VARIABLE)
|
||||
check_library_exists("${LIBRARY};${CURL_LIBS}" ${SYMBOL} "${CMAKE_LIBRARY_PATH}"
|
||||
${VARIABLE})
|
||||
if(${VARIABLE})
|
||||
set(CURL_LIBS ${LIBRARY} ${CURL_LIBS})
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# Check if header file exists and add it to the list.
|
||||
# This macro is intended to be called multiple times with a sequence of
|
||||
# possibly dependent header files. Some headers depend on others to be
|
||||
# compiled correctly.
|
||||
macro(check_include_file_concat FILE VARIABLE)
|
||||
check_include_files("${CURL_INCLUDES};${FILE}" ${VARIABLE})
|
||||
if(${VARIABLE})
|
||||
set(CURL_INCLUDES ${CURL_INCLUDES} ${FILE})
|
||||
set(CURL_TEST_DEFINES "${CURL_TEST_DEFINES} -D${VARIABLE}")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# For other curl specific tests, use this macro.
|
||||
macro(curl_internal_test CURL_TEST)
|
||||
if(NOT DEFINED "${CURL_TEST}")
|
||||
set(MACRO_CHECK_FUNCTION_DEFINITIONS
|
||||
"-D${CURL_TEST} ${CURL_TEST_DEFINES} ${CMAKE_REQUIRED_FLAGS}")
|
||||
if(CMAKE_REQUIRED_LIBRARIES)
|
||||
set(CURL_TEST_ADD_LIBRARIES
|
||||
"-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}")
|
||||
endif()
|
||||
|
||||
message(STATUS "Performing Curl Test ${CURL_TEST}")
|
||||
try_compile(${CURL_TEST}
|
||||
${CMAKE_BINARY_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/CMake/CurlTests.c
|
||||
CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
|
||||
"${CURL_TEST_ADD_LIBRARIES}"
|
||||
OUTPUT_VARIABLE OUTPUT)
|
||||
if(${CURL_TEST})
|
||||
set(${CURL_TEST} 1 CACHE INTERNAL "Curl test ${FUNCTION}")
|
||||
message(STATUS "Performing Curl Test ${CURL_TEST} - Success")
|
||||
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
|
||||
"Performing Curl Test ${CURL_TEST} passed with the following output:\n"
|
||||
"${OUTPUT}\n")
|
||||
else()
|
||||
message(STATUS "Performing Curl Test ${CURL_TEST} - Failed")
|
||||
set(${CURL_TEST} "" CACHE INTERNAL "Curl test ${FUNCTION}")
|
||||
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
|
||||
"Performing Curl Test ${CURL_TEST} failed with the following output:\n"
|
||||
"${OUTPUT}\n")
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(curl_nroff_check)
|
||||
find_program(NROFF NAMES gnroff nroff)
|
||||
if(NROFF)
|
||||
# Need a way to write to stdin, this will do
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/nroff-input.txt" "test")
|
||||
# Tests for a valid nroff option to generate a manpage
|
||||
foreach(_MANOPT "-man" "-mandoc")
|
||||
execute_process(COMMAND "${NROFF}" ${_MANOPT}
|
||||
OUTPUT_VARIABLE NROFF_MANOPT_OUTPUT
|
||||
INPUT_FILE "${CMAKE_CURRENT_BINARY_DIR}/nroff-input.txt"
|
||||
ERROR_QUIET)
|
||||
# Save the option if it was valid
|
||||
if(NROFF_MANOPT_OUTPUT)
|
||||
message("Found *nroff option: -- ${_MANOPT}")
|
||||
set(NROFF_MANOPT ${_MANOPT})
|
||||
set(NROFF_USEFUL ON)
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
# No need for the temporary file
|
||||
file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/nroff-input.txt")
|
||||
if(NOT NROFF_USEFUL)
|
||||
message(WARNING "Found no *nroff option to get plaintext from man pages")
|
||||
endif()
|
||||
else()
|
||||
message(WARNING "Found no *nroff program")
|
||||
endif()
|
||||
endmacro()
|
264
src/dependencies/cmcurl/CMake/OtherTests.cmake
Normal file
264
src/dependencies/cmcurl/CMake/OtherTests.cmake
Normal file
|
@ -0,0 +1,264 @@
|
|||
include(CheckCSourceCompiles)
|
||||
# The begin of the sources (macros and includes)
|
||||
set(_source_epilogue "#undef inline")
|
||||
|
||||
macro(add_header_include check header)
|
||||
if(${check})
|
||||
set(_source_epilogue "${_source_epilogue}\n#include <${header}>")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
set(signature_call_conv)
|
||||
if(HAVE_WINDOWS_H)
|
||||
add_header_include(HAVE_WINSOCK2_H "winsock2.h")
|
||||
add_header_include(HAVE_WINDOWS_H "windows.h")
|
||||
add_header_include(HAVE_WINSOCK_H "winsock.h")
|
||||
set(_source_epilogue
|
||||
"${_source_epilogue}\n#ifndef WIN32_LEAN_AND_MEAN\n#define WIN32_LEAN_AND_MEAN\n#endif")
|
||||
set(signature_call_conv "PASCAL")
|
||||
if(HAVE_LIBWS2_32)
|
||||
set(CMAKE_REQUIRED_LIBRARIES ws2_32)
|
||||
endif()
|
||||
else()
|
||||
add_header_include(HAVE_SYS_TYPES_H "sys/types.h")
|
||||
add_header_include(HAVE_SYS_SOCKET_H "sys/socket.h")
|
||||
endif()
|
||||
|
||||
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
|
||||
|
||||
check_c_source_compiles("${_source_epilogue}
|
||||
int main(void) {
|
||||
recv(0, 0, 0, 0);
|
||||
return 0;
|
||||
}" curl_cv_recv)
|
||||
if(curl_cv_recv)
|
||||
if(NOT DEFINED curl_cv_func_recv_args OR "${curl_cv_func_recv_args}" STREQUAL "unknown")
|
||||
foreach(recv_retv "int" "ssize_t" )
|
||||
foreach(recv_arg1 "SOCKET" "int" )
|
||||
foreach(recv_arg2 "char *" "void *" )
|
||||
foreach(recv_arg3 "int" "size_t" "socklen_t" "unsigned int")
|
||||
foreach(recv_arg4 "int" "unsigned int")
|
||||
if(NOT curl_cv_func_recv_done)
|
||||
unset(curl_cv_func_recv_test CACHE)
|
||||
check_c_source_compiles("
|
||||
${_source_epilogue}
|
||||
extern ${recv_retv} ${signature_call_conv}
|
||||
recv(${recv_arg1}, ${recv_arg2}, ${recv_arg3}, ${recv_arg4});
|
||||
int main(void) {
|
||||
${recv_arg1} s=0;
|
||||
${recv_arg2} buf=0;
|
||||
${recv_arg3} len=0;
|
||||
${recv_arg4} flags=0;
|
||||
${recv_retv} res = recv(s, buf, len, flags);
|
||||
(void) res;
|
||||
return 0;
|
||||
}"
|
||||
curl_cv_func_recv_test)
|
||||
message(STATUS
|
||||
"Tested: ${recv_retv} recv(${recv_arg1}, ${recv_arg2}, ${recv_arg3}, ${recv_arg4})")
|
||||
if(curl_cv_func_recv_test)
|
||||
set(curl_cv_func_recv_args
|
||||
"${recv_arg1},${recv_arg2},${recv_arg3},${recv_arg4},${recv_retv}")
|
||||
set(RECV_TYPE_ARG1 "${recv_arg1}")
|
||||
set(RECV_TYPE_ARG2 "${recv_arg2}")
|
||||
set(RECV_TYPE_ARG3 "${recv_arg3}")
|
||||
set(RECV_TYPE_ARG4 "${recv_arg4}")
|
||||
set(RECV_TYPE_RETV "${recv_retv}")
|
||||
set(HAVE_RECV 1)
|
||||
set(curl_cv_func_recv_done 1)
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
endforeach()
|
||||
endforeach()
|
||||
endforeach()
|
||||
endforeach()
|
||||
else()
|
||||
string(REGEX REPLACE "^([^,]*),[^,]*,[^,]*,[^,]*,[^,]*$" "\\1" RECV_TYPE_ARG1 "${curl_cv_func_recv_args}")
|
||||
string(REGEX REPLACE "^[^,]*,([^,]*),[^,]*,[^,]*,[^,]*$" "\\1" RECV_TYPE_ARG2 "${curl_cv_func_recv_args}")
|
||||
string(REGEX REPLACE "^[^,]*,[^,]*,([^,]*),[^,]*,[^,]*$" "\\1" RECV_TYPE_ARG3 "${curl_cv_func_recv_args}")
|
||||
string(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,([^,]*),[^,]*$" "\\1" RECV_TYPE_ARG4 "${curl_cv_func_recv_args}")
|
||||
string(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,[^,]*,([^,]*)$" "\\1" RECV_TYPE_RETV "${curl_cv_func_recv_args}")
|
||||
endif()
|
||||
|
||||
if("${curl_cv_func_recv_args}" STREQUAL "unknown")
|
||||
message(FATAL_ERROR "Cannot find proper types to use for recv args")
|
||||
endif()
|
||||
else()
|
||||
message(FATAL_ERROR "Unable to link function recv")
|
||||
endif()
|
||||
set(curl_cv_func_recv_args "${curl_cv_func_recv_args}" CACHE INTERNAL "Arguments for recv")
|
||||
set(HAVE_RECV 1)
|
||||
|
||||
check_c_source_compiles("${_source_epilogue}
|
||||
int main(void) {
|
||||
send(0, 0, 0, 0);
|
||||
return 0;
|
||||
}" curl_cv_send)
|
||||
if(curl_cv_send)
|
||||
if(NOT DEFINED curl_cv_func_send_args OR "${curl_cv_func_send_args}" STREQUAL "unknown")
|
||||
foreach(send_retv "int" "ssize_t" )
|
||||
foreach(send_arg1 "SOCKET" "int" "ssize_t" )
|
||||
foreach(send_arg2 "const char *" "const void *" "void *" "char *")
|
||||
foreach(send_arg3 "int" "size_t" "socklen_t" "unsigned int")
|
||||
foreach(send_arg4 "int" "unsigned int")
|
||||
if(NOT curl_cv_func_send_done)
|
||||
unset(curl_cv_func_send_test CACHE)
|
||||
check_c_source_compiles("
|
||||
${_source_epilogue}
|
||||
extern ${send_retv} ${signature_call_conv}
|
||||
send(${send_arg1}, ${send_arg2}, ${send_arg3}, ${send_arg4});
|
||||
int main(void) {
|
||||
${send_arg1} s=0;
|
||||
${send_arg2} buf=0;
|
||||
${send_arg3} len=0;
|
||||
${send_arg4} flags=0;
|
||||
${send_retv} res = send(s, buf, len, flags);
|
||||
(void) res;
|
||||
return 0;
|
||||
}"
|
||||
curl_cv_func_send_test)
|
||||
message(STATUS
|
||||
"Tested: ${send_retv} send(${send_arg1}, ${send_arg2}, ${send_arg3}, ${send_arg4})")
|
||||
if(curl_cv_func_send_test)
|
||||
string(REGEX REPLACE "(const) .*" "\\1" send_qual_arg2 "${send_arg2}")
|
||||
string(REGEX REPLACE "const (.*)" "\\1" send_arg2 "${send_arg2}")
|
||||
set(curl_cv_func_send_args
|
||||
"${send_arg1},${send_arg2},${send_arg3},${send_arg4},${send_retv},${send_qual_arg2}")
|
||||
set(SEND_TYPE_ARG1 "${send_arg1}")
|
||||
set(SEND_TYPE_ARG2 "${send_arg2}")
|
||||
set(SEND_TYPE_ARG3 "${send_arg3}")
|
||||
set(SEND_TYPE_ARG4 "${send_arg4}")
|
||||
set(SEND_TYPE_RETV "${send_retv}")
|
||||
set(HAVE_SEND 1)
|
||||
set(curl_cv_func_send_done 1)
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
endforeach()
|
||||
endforeach()
|
||||
endforeach()
|
||||
endforeach()
|
||||
else()
|
||||
string(REGEX REPLACE "^([^,]*),[^,]*,[^,]*,[^,]*,[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG1 "${curl_cv_func_send_args}")
|
||||
string(REGEX REPLACE "^[^,]*,([^,]*),[^,]*,[^,]*,[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG2 "${curl_cv_func_send_args}")
|
||||
string(REGEX REPLACE "^[^,]*,[^,]*,([^,]*),[^,]*,[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG3 "${curl_cv_func_send_args}")
|
||||
string(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,([^,]*),[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG4 "${curl_cv_func_send_args}")
|
||||
string(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,[^,]*,([^,]*),[^,]*$" "\\1" SEND_TYPE_RETV "${curl_cv_func_send_args}")
|
||||
string(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,([^,]*)$" "\\1" SEND_QUAL_ARG2 "${curl_cv_func_send_args}")
|
||||
endif()
|
||||
|
||||
if("${curl_cv_func_send_args}" STREQUAL "unknown")
|
||||
message(FATAL_ERROR "Cannot find proper types to use for send args")
|
||||
endif()
|
||||
set(SEND_QUAL_ARG2 "const")
|
||||
else()
|
||||
message(FATAL_ERROR "Unable to link function send")
|
||||
endif()
|
||||
set(curl_cv_func_send_args "${curl_cv_func_send_args}" CACHE INTERNAL "Arguments for send")
|
||||
set(HAVE_SEND 1)
|
||||
|
||||
check_c_source_compiles("${_source_epilogue}
|
||||
int main(void) {
|
||||
int flag = MSG_NOSIGNAL;
|
||||
(void)flag;
|
||||
return 0;
|
||||
}" HAVE_MSG_NOSIGNAL)
|
||||
|
||||
if(NOT HAVE_WINDOWS_H)
|
||||
add_header_include(HAVE_SYS_TIME_H "sys/time.h")
|
||||
add_header_include(TIME_WITH_SYS_TIME "time.h")
|
||||
add_header_include(HAVE_TIME_H "time.h")
|
||||
endif()
|
||||
check_c_source_compiles("${_source_epilogue}
|
||||
int main(void) {
|
||||
struct timeval ts;
|
||||
ts.tv_sec = 0;
|
||||
ts.tv_usec = 0;
|
||||
(void)ts;
|
||||
return 0;
|
||||
}" HAVE_STRUCT_TIMEVAL)
|
||||
|
||||
set(HAVE_SIG_ATOMIC_T 1)
|
||||
set(CMAKE_REQUIRED_FLAGS)
|
||||
if(HAVE_SIGNAL_H)
|
||||
set(CMAKE_REQUIRED_FLAGS "-DHAVE_SIGNAL_H")
|
||||
set(CMAKE_EXTRA_INCLUDE_FILES "signal.h")
|
||||
endif()
|
||||
check_type_size("sig_atomic_t" SIZEOF_SIG_ATOMIC_T)
|
||||
if(HAVE_SIZEOF_SIG_ATOMIC_T)
|
||||
check_c_source_compiles("
|
||||
#ifdef HAVE_SIGNAL_H
|
||||
# include <signal.h>
|
||||
#endif
|
||||
int main(void) {
|
||||
static volatile sig_atomic_t dummy = 0;
|
||||
(void)dummy;
|
||||
return 0;
|
||||
}" HAVE_SIG_ATOMIC_T_NOT_VOLATILE)
|
||||
if(NOT HAVE_SIG_ATOMIC_T_NOT_VOLATILE)
|
||||
set(HAVE_SIG_ATOMIC_T_VOLATILE 1)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(HAVE_WINDOWS_H)
|
||||
set(CMAKE_EXTRA_INCLUDE_FILES winsock2.h)
|
||||
else()
|
||||
set(CMAKE_EXTRA_INCLUDE_FILES)
|
||||
if(HAVE_SYS_SOCKET_H)
|
||||
set(CMAKE_EXTRA_INCLUDE_FILES sys/socket.h)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
check_type_size("struct sockaddr_storage" SIZEOF_STRUCT_SOCKADDR_STORAGE)
|
||||
if(HAVE_SIZEOF_STRUCT_SOCKADDR_STORAGE)
|
||||
set(HAVE_STRUCT_SOCKADDR_STORAGE 1)
|
||||
endif()
|
||||
|
||||
unset(CMAKE_TRY_COMPILE_TARGET_TYPE)
|
||||
|
||||
if(NOT DEFINED CMAKE_TOOLCHAIN_FILE)
|
||||
# if not cross-compilation...
|
||||
include(CheckCSourceRuns)
|
||||
set(CMAKE_REQUIRED_FLAGS "")
|
||||
if(HAVE_SYS_POLL_H)
|
||||
set(CMAKE_REQUIRED_FLAGS "-DHAVE_SYS_POLL_H")
|
||||
elseif(HAVE_POLL_H)
|
||||
set(CMAKE_REQUIRED_FLAGS "-DHAVE_POLL_H")
|
||||
endif()
|
||||
check_c_source_runs("
|
||||
#include <stdlib.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#ifdef HAVE_SYS_POLL_H
|
||||
# include <sys/poll.h>
|
||||
#elif HAVE_POLL_H
|
||||
# include <poll.h>
|
||||
#endif
|
||||
|
||||
int main(void)
|
||||
{
|
||||
if(0 != poll(0, 0, 10)) {
|
||||
return 1; /* fail */
|
||||
}
|
||||
else {
|
||||
/* detect the 10.12 poll() breakage */
|
||||
struct timeval before, after;
|
||||
int rc;
|
||||
size_t us;
|
||||
|
||||
gettimeofday(&before, NULL);
|
||||
rc = poll(NULL, 0, 500);
|
||||
gettimeofday(&after, NULL);
|
||||
|
||||
us = (after.tv_sec - before.tv_sec) * 1000000 +
|
||||
(after.tv_usec - before.tv_usec);
|
||||
|
||||
if(us < 400000) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}" HAVE_POLL_FINE)
|
||||
endif()
|
||||
|
121
src/dependencies/cmcurl/CMake/Platforms/WindowsCache.cmake
Normal file
121
src/dependencies/cmcurl/CMake/Platforms/WindowsCache.cmake
Normal file
|
@ -0,0 +1,121 @@
|
|||
if(NOT UNIX)
|
||||
if(WIN32)
|
||||
set(HAVE_LIBDL 0)
|
||||
set(HAVE_LIBUCB 0)
|
||||
set(HAVE_LIBSOCKET 0)
|
||||
set(NOT_NEED_LIBNSL 0)
|
||||
set(HAVE_LIBNSL 0)
|
||||
set(HAVE_GETHOSTNAME 1)
|
||||
set(HAVE_LIBZ 0)
|
||||
set(HAVE_LIBCRYPTO 0)
|
||||
|
||||
set(HAVE_DLOPEN 0)
|
||||
|
||||
set(HAVE_ALLOCA_H 0)
|
||||
set(HAVE_ARPA_INET_H 0)
|
||||
set(HAVE_DLFCN_H 0)
|
||||
set(HAVE_FCNTL_H 1)
|
||||
set(HAVE_INTTYPES_H 0)
|
||||
set(HAVE_IO_H 1)
|
||||
set(HAVE_MALLOC_H 1)
|
||||
set(HAVE_MEMORY_H 1)
|
||||
set(HAVE_NETDB_H 0)
|
||||
set(HAVE_NETINET_IF_ETHER_H 0)
|
||||
set(HAVE_NETINET_IN_H 0)
|
||||
set(HAVE_NET_IF_H 0)
|
||||
set(HAVE_PROCESS_H 1)
|
||||
set(HAVE_PWD_H 0)
|
||||
set(HAVE_SETJMP_H 1)
|
||||
set(HAVE_SGTTY_H 0)
|
||||
set(HAVE_SIGNAL_H 1)
|
||||
set(HAVE_SOCKIO_H 0)
|
||||
set(HAVE_STDINT_H 0)
|
||||
set(HAVE_STDLIB_H 1)
|
||||
set(HAVE_STRINGS_H 0)
|
||||
set(HAVE_STRING_H 1)
|
||||
set(HAVE_SYS_PARAM_H 0)
|
||||
set(HAVE_SYS_POLL_H 0)
|
||||
set(HAVE_SYS_SELECT_H 0)
|
||||
set(HAVE_SYS_SOCKET_H 0)
|
||||
set(HAVE_SYS_SOCKIO_H 0)
|
||||
set(HAVE_SYS_STAT_H 1)
|
||||
set(HAVE_SYS_TIME_H 0)
|
||||
set(HAVE_SYS_TYPES_H 1)
|
||||
set(HAVE_SYS_UTIME_H 1)
|
||||
set(HAVE_TERMIOS_H 0)
|
||||
set(HAVE_TERMIO_H 0)
|
||||
set(HAVE_TIME_H 1)
|
||||
set(HAVE_UNISTD_H 0)
|
||||
set(HAVE_UTIME_H 0)
|
||||
set(HAVE_X509_H 0)
|
||||
set(HAVE_ZLIB_H 0)
|
||||
|
||||
set(HAVE_SOCKET 1)
|
||||
set(HAVE_POLL 0)
|
||||
set(HAVE_SELECT 1)
|
||||
set(HAVE_STRDUP 1)
|
||||
set(HAVE_STRSTR 1)
|
||||
set(HAVE_STRTOK_R 0)
|
||||
set(HAVE_STRFTIME 1)
|
||||
set(HAVE_UNAME 0)
|
||||
set(HAVE_STRCASECMP 0)
|
||||
set(HAVE_STRICMP 1)
|
||||
set(HAVE_STRCMPI 1)
|
||||
set(HAVE_GETHOSTBYADDR 1)
|
||||
set(HAVE_GETTIMEOFDAY 0)
|
||||
set(HAVE_INET_ADDR 1)
|
||||
set(HAVE_INET_NTOA 1)
|
||||
set(HAVE_INET_NTOA_R 0)
|
||||
set(HAVE_TCGETATTR 0)
|
||||
set(HAVE_TCSETATTR 0)
|
||||
set(HAVE_PERROR 1)
|
||||
set(HAVE_CLOSESOCKET 1)
|
||||
set(HAVE_SETVBUF 0)
|
||||
set(HAVE_SIGSETJMP 0)
|
||||
set(HAVE_GETPASS_R 0)
|
||||
set(HAVE_STRLCAT 0)
|
||||
set(HAVE_GETPWUID 0)
|
||||
set(HAVE_GETEUID 0)
|
||||
set(HAVE_UTIME 1)
|
||||
set(HAVE_RAND_EGD 0)
|
||||
set(HAVE_RAND_SCREEN 0)
|
||||
set(HAVE_RAND_STATUS 0)
|
||||
set(HAVE_GMTIME_R 0)
|
||||
set(HAVE_LOCALTIME_R 0)
|
||||
set(HAVE_GETHOSTBYADDR_R 0)
|
||||
set(HAVE_GETHOSTBYNAME_R 0)
|
||||
set(HAVE_SIGNAL_FUNC 1)
|
||||
set(HAVE_SIGNAL_MACRO 0)
|
||||
|
||||
set(HAVE_GETHOSTBYADDR_R_5 0)
|
||||
set(HAVE_GETHOSTBYADDR_R_5_REENTRANT 0)
|
||||
set(HAVE_GETHOSTBYADDR_R_7 0)
|
||||
set(HAVE_GETHOSTBYADDR_R_7_REENTRANT 0)
|
||||
set(HAVE_GETHOSTBYADDR_R_8 0)
|
||||
set(HAVE_GETHOSTBYADDR_R_8_REENTRANT 0)
|
||||
set(HAVE_GETHOSTBYNAME_R_3 0)
|
||||
set(HAVE_GETHOSTBYNAME_R_3_REENTRANT 0)
|
||||
set(HAVE_GETHOSTBYNAME_R_5 0)
|
||||
set(HAVE_GETHOSTBYNAME_R_5_REENTRANT 0)
|
||||
set(HAVE_GETHOSTBYNAME_R_6 0)
|
||||
set(HAVE_GETHOSTBYNAME_R_6_REENTRANT 0)
|
||||
|
||||
set(TIME_WITH_SYS_TIME 0)
|
||||
set(HAVE_O_NONBLOCK 0)
|
||||
set(HAVE_IN_ADDR_T 0)
|
||||
set(HAVE_INET_NTOA_R_DECL 0)
|
||||
set(HAVE_INET_NTOA_R_DECL_REENTRANT 0)
|
||||
if(ENABLE_IPV6)
|
||||
set(HAVE_GETADDRINFO 1)
|
||||
else()
|
||||
set(HAVE_GETADDRINFO 0)
|
||||
endif()
|
||||
set(STDC_HEADERS 1)
|
||||
set(RETSIGTYPE_TEST 1)
|
||||
|
||||
set(HAVE_SIGACTION 0)
|
||||
set(HAVE_MACRO_SIGSETJMP 0)
|
||||
else()
|
||||
message("This file should be included on Windows platform only")
|
||||
endif()
|
||||
endif()
|
13
src/dependencies/cmcurl/CMake/Utilities.cmake
Normal file
13
src/dependencies/cmcurl/CMake/Utilities.cmake
Normal file
|
@ -0,0 +1,13 @@
|
|||
# File containing various utilities
|
||||
|
||||
# Returns a list of arguments that evaluate to true
|
||||
function(count_true output_count_var)
|
||||
set(lst)
|
||||
foreach(option_var IN LISTS ARGN)
|
||||
if(${option_var})
|
||||
list(APPEND lst ${option_var})
|
||||
endif()
|
||||
endforeach()
|
||||
list(LENGTH lst lst_len)
|
||||
set(${output_count_var} ${lst_len} PARENT_SCOPE)
|
||||
endfunction()
|
26
src/dependencies/cmcurl/CMake/cmake_uninstall.cmake.in
Normal file
26
src/dependencies/cmcurl/CMake/cmake_uninstall.cmake.in
Normal file
|
@ -0,0 +1,26 @@
|
|||
if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
|
||||
message(FATAL_ERROR "Cannot find install manifest: @CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_INSTALL_PREFIX)
|
||||
set(CMAKE_INSTALL_PREFIX "@CMAKE_INSTALL_PREFIX@")
|
||||
endif()
|
||||
message(${CMAKE_INSTALL_PREFIX})
|
||||
|
||||
file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
|
||||
string(REGEX REPLACE "\n" ";" files "${files}")
|
||||
foreach(file ${files})
|
||||
message(STATUS "Uninstalling $ENV{DESTDIR}${file}")
|
||||
if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
|
||||
exec_program(
|
||||
"@CMAKE_COMMAND@" ARGS "-E rm -f \"$ENV{DESTDIR}${file}\""
|
||||
OUTPUT_VARIABLE rm_out
|
||||
RETURN_VALUE rm_retval
|
||||
)
|
||||
if(NOT "${rm_retval}" STREQUAL 0)
|
||||
message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}")
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
|
||||
endif()
|
||||
endforeach()
|
12
src/dependencies/cmcurl/CMake/curl-config.cmake.in
Normal file
12
src/dependencies/cmcurl/CMake/curl-config.cmake.in
Normal file
|
@ -0,0 +1,12 @@
|
|||
@PACKAGE_INIT@
|
||||
|
||||
include(CMakeFindDependencyMacro)
|
||||
if(@USE_OPENSSL@)
|
||||
find_dependency(OpenSSL @OPENSSL_VERSION_MAJOR@)
|
||||
endif()
|
||||
if(@USE_ZLIB@)
|
||||
find_dependency(ZLIB @ZLIB_VERSION_MAJOR@)
|
||||
endif()
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/@TARGETS_EXPORT_NAME@.cmake")
|
||||
check_required_components("@PROJECT_NAME@")
|
1502
src/dependencies/cmcurl/CMakeLists.txt
Normal file
1502
src/dependencies/cmcurl/CMakeLists.txt
Normal file
File diff suppressed because it is too large
Load diff
22
src/dependencies/cmcurl/COPYING
Normal file
22
src/dependencies/cmcurl/COPYING
Normal file
|
@ -0,0 +1,22 @@
|
|||
COPYRIGHT AND PERMISSION NOTICE
|
||||
|
||||
Copyright (c) 1996 - 2019, Daniel Stenberg, <daniel@haxx.se>, and many
|
||||
contributors, see the THANKS file.
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Permission to use, copy, modify, and distribute this software for any purpose
|
||||
with or without fee is hereby granted, provided that the above copyright
|
||||
notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN
|
||||
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
||||
OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of a copyright holder shall not
|
||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization of the copyright holder.
|
81
src/dependencies/cmcurl/curltest.c
Normal file
81
src/dependencies/cmcurl/curltest.c
Normal file
|
@ -0,0 +1,81 @@
|
|||
#include "curl/curl.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
int test_curl(const char* url)
|
||||
{
|
||||
CURL* curl;
|
||||
CURLcode r;
|
||||
char proxy[1024];
|
||||
int proxy_type = 0;
|
||||
|
||||
if (getenv("HTTP_PROXY")) {
|
||||
proxy_type = 1;
|
||||
if (getenv("HTTP_PROXY_PORT")) {
|
||||
sprintf(proxy, "%s:%s", getenv("HTTP_PROXY"), getenv("HTTP_PROXY_PORT"));
|
||||
} else {
|
||||
sprintf(proxy, "%s", getenv("HTTP_PROXY"));
|
||||
}
|
||||
if (getenv("HTTP_PROXY_TYPE")) {
|
||||
/* HTTP/SOCKS4/SOCKS5 */
|
||||
if (strcmp(getenv("HTTP_PROXY_TYPE"), "HTTP") == 0) {
|
||||
proxy_type = 1;
|
||||
} else if (strcmp(getenv("HTTP_PROXY_TYPE"), "SOCKS4") == 0) {
|
||||
proxy_type = 2;
|
||||
} else if (strcmp(getenv("HTTP_PROXY_TYPE"), "SOCKS5") == 0) {
|
||||
proxy_type = 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
curl = curl_easy_init();
|
||||
if (!curl) {
|
||||
fprintf(stderr, "curl_easy_init failed\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
|
||||
curl_easy_setopt(curl, CURLOPT_HEADER, 1);
|
||||
|
||||
if (proxy_type > 0) {
|
||||
curl_easy_setopt(curl, CURLOPT_PROXY, proxy);
|
||||
switch (proxy_type) {
|
||||
case 2:
|
||||
curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS4);
|
||||
break;
|
||||
case 3:
|
||||
curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
|
||||
break;
|
||||
default:
|
||||
curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
|
||||
}
|
||||
}
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, url);
|
||||
r = curl_easy_perform(curl);
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
if (r != CURLE_OK) {
|
||||
fprintf(stderr, "error: fetching '%s' failed: %s\n", url,
|
||||
curl_easy_strerror(r));
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, const char* argv[])
|
||||
{
|
||||
int r;
|
||||
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||
if (argc == 2) {
|
||||
r = test_curl(argv[1]);
|
||||
} else {
|
||||
fprintf(stderr, "error: no URL given as first argument\n");
|
||||
r = 1;
|
||||
}
|
||||
curl_global_cleanup();
|
||||
return r;
|
||||
}
|
2869
src/dependencies/cmcurl/include/curl/curl.h
Normal file
2869
src/dependencies/cmcurl/include/curl/curl.h
Normal file
File diff suppressed because it is too large
Load diff
77
src/dependencies/cmcurl/include/curl/curlver.h
Normal file
77
src/dependencies/cmcurl/include/curl/curlver.h
Normal file
|
@ -0,0 +1,77 @@
|
|||
#ifndef __CURL_CURLVER_H
|
||||
#define __CURL_CURLVER_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* This header file contains nothing but libcurl version info, generated by
|
||||
a script at release-time. This was made its own header file in 7.11.2 */
|
||||
|
||||
/* This is the global package copyright */
|
||||
#define LIBCURL_COPYRIGHT "1996 - 2019 Daniel Stenberg, <daniel@haxx.se>."
|
||||
|
||||
/* This is the version number of the libcurl package from which this header
|
||||
file origins: */
|
||||
#define LIBCURL_VERSION "7.65.0"
|
||||
|
||||
/* The numeric version number is also available "in parts" by using these
|
||||
defines: */
|
||||
#define LIBCURL_VERSION_MAJOR 7
|
||||
#define LIBCURL_VERSION_MINOR 65
|
||||
#define LIBCURL_VERSION_PATCH 0
|
||||
|
||||
/* This is the numeric version of the libcurl version number, meant for easier
|
||||
parsing and comparions by programs. The LIBCURL_VERSION_NUM define will
|
||||
always follow this syntax:
|
||||
|
||||
0xXXYYZZ
|
||||
|
||||
Where XX, YY and ZZ are the main version, release and patch numbers in
|
||||
hexadecimal (using 8 bits each). All three numbers are always represented
|
||||
using two digits. 1.2 would appear as "0x010200" while version 9.11.7
|
||||
appears as "0x090b07".
|
||||
|
||||
This 6-digit (24 bits) hexadecimal number does not show pre-release number,
|
||||
and it is always a greater number in a more recent release. It makes
|
||||
comparisons with greater than and less than work.
|
||||
|
||||
Note: This define is the full hex number and _does not_ use the
|
||||
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 0x074100
|
||||
|
||||
/*
|
||||
* This is the date and time when the full source package was created. The
|
||||
* timestamp is not stored in git, as the timestamp is properly set in the
|
||||
* tarballs by the maketgz script.
|
||||
*
|
||||
* The format of the date follows this template:
|
||||
*
|
||||
* "2007-11-23"
|
||||
*/
|
||||
#define LIBCURL_TIMESTAMP "[unreleased]"
|
||||
|
||||
#define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|(z))
|
||||
#define CURL_AT_LEAST_VERSION(x,y,z) \
|
||||
(LIBCURL_VERSION_NUM >= CURL_VERSION_BITS(x, y, z))
|
||||
|
||||
#endif /* __CURL_CURLVER_H */
|
112
src/dependencies/cmcurl/include/curl/easy.h
Normal file
112
src/dependencies/cmcurl/include/curl/easy.h
Normal file
|
@ -0,0 +1,112 @@
|
|||
#ifndef __CURL_EASY_H
|
||||
#define __CURL_EASY_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
CURL_EXTERN CURL *curl_easy_init(void);
|
||||
CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...);
|
||||
CURL_EXTERN CURLcode curl_easy_perform(CURL *curl);
|
||||
CURL_EXTERN void curl_easy_cleanup(CURL *curl);
|
||||
|
||||
/*
|
||||
* NAME curl_easy_getinfo()
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* Request internal information from the curl session with this function. The
|
||||
* third argument MUST be a pointer to a long, a pointer to a char * or a
|
||||
* pointer to a double (as the documentation describes elsewhere). The data
|
||||
* pointed to will be filled in accordingly and can be relied upon only if the
|
||||
* function returns CURLE_OK. This function is intended to get used *AFTER* a
|
||||
* performed transfer, all results from this function are undefined until the
|
||||
* transfer is completed.
|
||||
*/
|
||||
CURL_EXTERN CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...);
|
||||
|
||||
|
||||
/*
|
||||
* NAME curl_easy_duphandle()
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* Creates a new curl session handle with the same options set for the handle
|
||||
* passed in. Duplicating a handle could only be a matter of cloning data and
|
||||
* options, internal state info and things like persistent connections cannot
|
||||
* be transferred. It is useful in multithreaded applications when you can run
|
||||
* curl_easy_duphandle() for each new thread to avoid a series of identical
|
||||
* curl_easy_setopt() invokes in every thread.
|
||||
*/
|
||||
CURL_EXTERN CURL *curl_easy_duphandle(CURL *curl);
|
||||
|
||||
/*
|
||||
* NAME curl_easy_reset()
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* Re-initializes a CURL handle to the default values. This puts back the
|
||||
* handle to the same state as it was in when it was just created.
|
||||
*
|
||||
* It does keep: live connections, the Session ID cache, the DNS cache and the
|
||||
* cookies.
|
||||
*/
|
||||
CURL_EXTERN void curl_easy_reset(CURL *curl);
|
||||
|
||||
/*
|
||||
* NAME curl_easy_recv()
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* Receives data from the connected socket. Use after successful
|
||||
* curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
|
||||
*/
|
||||
CURL_EXTERN CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen,
|
||||
size_t *n);
|
||||
|
||||
/*
|
||||
* NAME curl_easy_send()
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* Sends data over the connected socket. Use after successful
|
||||
* curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
|
||||
*/
|
||||
CURL_EXTERN CURLcode curl_easy_send(CURL *curl, const void *buffer,
|
||||
size_t buflen, size_t *n);
|
||||
|
||||
|
||||
/*
|
||||
* NAME curl_easy_upkeep()
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* Performs connection upkeep for the given session handle.
|
||||
*/
|
||||
CURL_EXTERN CURLcode curl_easy_upkeep(CURL *curl);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
50
src/dependencies/cmcurl/include/curl/mprintf.h
Normal file
50
src/dependencies/cmcurl/include/curl/mprintf.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
#ifndef __CURL_MPRINTF_H
|
||||
#define __CURL_MPRINTF_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h> /* needed for FILE */
|
||||
#include "curl.h" /* for CURL_EXTERN */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
CURL_EXTERN int curl_mprintf(const char *format, ...);
|
||||
CURL_EXTERN int curl_mfprintf(FILE *fd, const char *format, ...);
|
||||
CURL_EXTERN int curl_msprintf(char *buffer, const char *format, ...);
|
||||
CURL_EXTERN int curl_msnprintf(char *buffer, size_t maxlength,
|
||||
const char *format, ...);
|
||||
CURL_EXTERN int curl_mvprintf(const char *format, va_list args);
|
||||
CURL_EXTERN int curl_mvfprintf(FILE *fd, const char *format, va_list args);
|
||||
CURL_EXTERN int curl_mvsprintf(char *buffer, const char *format, va_list args);
|
||||
CURL_EXTERN int curl_mvsnprintf(char *buffer, size_t maxlength,
|
||||
const char *format, va_list args);
|
||||
CURL_EXTERN char *curl_maprintf(const char *format, ...);
|
||||
CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __CURL_MPRINTF_H */
|
441
src/dependencies/cmcurl/include/curl/multi.h
Normal file
441
src/dependencies/cmcurl/include/curl/multi.h
Normal file
|
@ -0,0 +1,441 @@
|
|||
#ifndef __CURL_MULTI_H
|
||||
#define __CURL_MULTI_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2017, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
/*
|
||||
This is an "external" header file. Don't give away any internals here!
|
||||
|
||||
GOALS
|
||||
|
||||
o Enable a "pull" interface. The application that uses libcurl decides where
|
||||
and when to ask libcurl to get/send data.
|
||||
|
||||
o Enable multiple simultaneous transfers in the same thread without making it
|
||||
complicated for the application.
|
||||
|
||||
o Enable the application to select() on its own file descriptors and curl's
|
||||
file descriptors simultaneous easily.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* This header file should not really need to include "curl.h" since curl.h
|
||||
* itself includes this file and we expect user applications to do #include
|
||||
* <curl/curl.h> without the need for especially including multi.h.
|
||||
*
|
||||
* For some reason we added this include here at one point, and rather than to
|
||||
* break existing (wrongly written) libcurl applications, we leave it as-is
|
||||
* but with this warning attached.
|
||||
*/
|
||||
#include "curl.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(BUILDING_LIBCURL) || defined(CURL_STRICTER)
|
||||
typedef struct Curl_multi CURLM;
|
||||
#else
|
||||
typedef void CURLM;
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
CURLM_CALL_MULTI_PERFORM = -1, /* please call curl_multi_perform() or
|
||||
curl_multi_socket*() soon */
|
||||
CURLM_OK,
|
||||
CURLM_BAD_HANDLE, /* the passed-in handle is not a valid CURLM handle */
|
||||
CURLM_BAD_EASY_HANDLE, /* an easy handle was not good/valid */
|
||||
CURLM_OUT_OF_MEMORY, /* if you ever get this, you're in deep sh*t */
|
||||
CURLM_INTERNAL_ERROR, /* this is a libcurl bug */
|
||||
CURLM_BAD_SOCKET, /* the passed in socket argument did not match */
|
||||
CURLM_UNKNOWN_OPTION, /* curl_multi_setopt() with unsupported option */
|
||||
CURLM_ADDED_ALREADY, /* an easy handle already added to a multi handle was
|
||||
attempted to get added - again */
|
||||
CURLM_RECURSIVE_API_CALL, /* an api function was called from inside a
|
||||
callback */
|
||||
CURLM_LAST
|
||||
} CURLMcode;
|
||||
|
||||
/* just to make code nicer when using curl_multi_socket() you can now check
|
||||
for CURLM_CALL_MULTI_SOCKET too in the same style it works for
|
||||
curl_multi_perform() and CURLM_CALL_MULTI_PERFORM */
|
||||
#define CURLM_CALL_MULTI_SOCKET CURLM_CALL_MULTI_PERFORM
|
||||
|
||||
/* bitmask bits for CURLMOPT_PIPELINING */
|
||||
#define CURLPIPE_NOTHING 0L
|
||||
#define CURLPIPE_HTTP1 1L
|
||||
#define CURLPIPE_MULTIPLEX 2L
|
||||
|
||||
typedef enum {
|
||||
CURLMSG_NONE, /* first, not used */
|
||||
CURLMSG_DONE, /* This easy handle has completed. 'result' contains
|
||||
the CURLcode of the transfer */
|
||||
CURLMSG_LAST /* last, not used */
|
||||
} CURLMSG;
|
||||
|
||||
struct CURLMsg {
|
||||
CURLMSG msg; /* what this message means */
|
||||
CURL *easy_handle; /* the handle it concerns */
|
||||
union {
|
||||
void *whatever; /* message-specific data */
|
||||
CURLcode result; /* return code for transfer */
|
||||
} data;
|
||||
};
|
||||
typedef struct CURLMsg CURLMsg;
|
||||
|
||||
/* Based on poll(2) structure and values.
|
||||
* We don't use pollfd and POLL* constants explicitly
|
||||
* to cover platforms without poll(). */
|
||||
#define CURL_WAIT_POLLIN 0x0001
|
||||
#define CURL_WAIT_POLLPRI 0x0002
|
||||
#define CURL_WAIT_POLLOUT 0x0004
|
||||
|
||||
struct curl_waitfd {
|
||||
curl_socket_t fd;
|
||||
short events;
|
||||
short revents; /* not supported yet */
|
||||
};
|
||||
|
||||
/*
|
||||
* Name: curl_multi_init()
|
||||
*
|
||||
* Desc: inititalize multi-style curl usage
|
||||
*
|
||||
* Returns: a new CURLM handle to use in all 'curl_multi' functions.
|
||||
*/
|
||||
CURL_EXTERN CURLM *curl_multi_init(void);
|
||||
|
||||
/*
|
||||
* Name: curl_multi_add_handle()
|
||||
*
|
||||
* Desc: add a standard curl handle to the multi stack
|
||||
*
|
||||
* Returns: CURLMcode type, general multi error code.
|
||||
*/
|
||||
CURL_EXTERN CURLMcode curl_multi_add_handle(CURLM *multi_handle,
|
||||
CURL *curl_handle);
|
||||
|
||||
/*
|
||||
* Name: curl_multi_remove_handle()
|
||||
*
|
||||
* Desc: removes a curl handle from the multi stack again
|
||||
*
|
||||
* Returns: CURLMcode type, general multi error code.
|
||||
*/
|
||||
CURL_EXTERN CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
|
||||
CURL *curl_handle);
|
||||
|
||||
/*
|
||||
* Name: curl_multi_fdset()
|
||||
*
|
||||
* Desc: Ask curl for its fd_set sets. The app can use these to select() or
|
||||
* poll() on. We want curl_multi_perform() called as soon as one of
|
||||
* them are ready.
|
||||
*
|
||||
* Returns: CURLMcode type, general multi error code.
|
||||
*/
|
||||
CURL_EXTERN CURLMcode curl_multi_fdset(CURLM *multi_handle,
|
||||
fd_set *read_fd_set,
|
||||
fd_set *write_fd_set,
|
||||
fd_set *exc_fd_set,
|
||||
int *max_fd);
|
||||
|
||||
/*
|
||||
* Name: curl_multi_wait()
|
||||
*
|
||||
* Desc: Poll on all fds within a CURLM set as well as any
|
||||
* additional fds passed to the function.
|
||||
*
|
||||
* Returns: CURLMcode type, general multi error code.
|
||||
*/
|
||||
CURL_EXTERN CURLMcode curl_multi_wait(CURLM *multi_handle,
|
||||
struct curl_waitfd extra_fds[],
|
||||
unsigned int extra_nfds,
|
||||
int timeout_ms,
|
||||
int *ret);
|
||||
|
||||
/*
|
||||
* Name: curl_multi_perform()
|
||||
*
|
||||
* Desc: When the app thinks there's data available for curl it calls this
|
||||
* function to read/write whatever there is right now. This returns
|
||||
* as soon as the reads and writes are done. This function does not
|
||||
* require that there actually is data available for reading or that
|
||||
* data can be written, it can be called just in case. It returns
|
||||
* the number of handles that still transfer data in the second
|
||||
* argument's integer-pointer.
|
||||
*
|
||||
* Returns: CURLMcode type, general multi error code. *NOTE* that this only
|
||||
* returns errors etc regarding the whole multi stack. There might
|
||||
* still have occurred problems on individual transfers even when
|
||||
* this returns OK.
|
||||
*/
|
||||
CURL_EXTERN CURLMcode curl_multi_perform(CURLM *multi_handle,
|
||||
int *running_handles);
|
||||
|
||||
/*
|
||||
* Name: curl_multi_cleanup()
|
||||
*
|
||||
* Desc: Cleans up and removes a whole multi stack. It does not free or
|
||||
* touch any individual easy handles in any way. We need to define
|
||||
* in what state those handles will be if this function is called
|
||||
* in the middle of a transfer.
|
||||
*
|
||||
* Returns: CURLMcode type, general multi error code.
|
||||
*/
|
||||
CURL_EXTERN CURLMcode curl_multi_cleanup(CURLM *multi_handle);
|
||||
|
||||
/*
|
||||
* Name: curl_multi_info_read()
|
||||
*
|
||||
* Desc: Ask the multi handle if there's any messages/informationals from
|
||||
* the individual transfers. Messages include informationals such as
|
||||
* error code from the transfer or just the fact that a transfer is
|
||||
* completed. More details on these should be written down as well.
|
||||
*
|
||||
* Repeated calls to this function will return a new struct each
|
||||
* time, until a special "end of msgs" struct is returned as a signal
|
||||
* that there is no more to get at this point.
|
||||
*
|
||||
* The data the returned pointer points to will not survive calling
|
||||
* curl_multi_cleanup().
|
||||
*
|
||||
* The 'CURLMsg' struct is meant to be very simple and only contain
|
||||
* very basic information. If more involved information is wanted,
|
||||
* we will provide the particular "transfer handle" in that struct
|
||||
* and that should/could/would be used in subsequent
|
||||
* curl_easy_getinfo() calls (or similar). The point being that we
|
||||
* must never expose complex structs to applications, as then we'll
|
||||
* undoubtably get backwards compatibility problems in the future.
|
||||
*
|
||||
* Returns: A pointer to a filled-in struct, or NULL if it failed or ran out
|
||||
* of structs. It also writes the number of messages left in the
|
||||
* queue (after this read) in the integer the second argument points
|
||||
* to.
|
||||
*/
|
||||
CURL_EXTERN CURLMsg *curl_multi_info_read(CURLM *multi_handle,
|
||||
int *msgs_in_queue);
|
||||
|
||||
/*
|
||||
* Name: curl_multi_strerror()
|
||||
*
|
||||
* Desc: The curl_multi_strerror function may be used to turn a CURLMcode
|
||||
* value into the equivalent human readable error string. This is
|
||||
* useful for printing meaningful error messages.
|
||||
*
|
||||
* Returns: A pointer to a zero-terminated error message.
|
||||
*/
|
||||
CURL_EXTERN const char *curl_multi_strerror(CURLMcode);
|
||||
|
||||
/*
|
||||
* Name: curl_multi_socket() and
|
||||
* curl_multi_socket_all()
|
||||
*
|
||||
* Desc: An alternative version of curl_multi_perform() that allows the
|
||||
* application to pass in one of the file descriptors that have been
|
||||
* detected to have "action" on them and let libcurl perform.
|
||||
* See man page for details.
|
||||
*/
|
||||
#define CURL_POLL_NONE 0
|
||||
#define CURL_POLL_IN 1
|
||||
#define CURL_POLL_OUT 2
|
||||
#define CURL_POLL_INOUT 3
|
||||
#define CURL_POLL_REMOVE 4
|
||||
|
||||
#define CURL_SOCKET_TIMEOUT CURL_SOCKET_BAD
|
||||
|
||||
#define CURL_CSELECT_IN 0x01
|
||||
#define CURL_CSELECT_OUT 0x02
|
||||
#define CURL_CSELECT_ERR 0x04
|
||||
|
||||
typedef int (*curl_socket_callback)(CURL *easy, /* easy handle */
|
||||
curl_socket_t s, /* socket */
|
||||
int what, /* see above */
|
||||
void *userp, /* private callback
|
||||
pointer */
|
||||
void *socketp); /* private socket
|
||||
pointer */
|
||||
/*
|
||||
* Name: curl_multi_timer_callback
|
||||
*
|
||||
* Desc: Called by libcurl whenever the library detects a change in the
|
||||
* maximum number of milliseconds the app is allowed to wait before
|
||||
* curl_multi_socket() or curl_multi_perform() must be called
|
||||
* (to allow libcurl's timed events to take place).
|
||||
*
|
||||
* Returns: The callback should return zero.
|
||||
*/
|
||||
typedef int (*curl_multi_timer_callback)(CURLM *multi, /* multi handle */
|
||||
long timeout_ms, /* see above */
|
||||
void *userp); /* private callback
|
||||
pointer */
|
||||
|
||||
CURL_EXTERN CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s,
|
||||
int *running_handles);
|
||||
|
||||
CURL_EXTERN CURLMcode curl_multi_socket_action(CURLM *multi_handle,
|
||||
curl_socket_t s,
|
||||
int ev_bitmask,
|
||||
int *running_handles);
|
||||
|
||||
CURL_EXTERN CURLMcode curl_multi_socket_all(CURLM *multi_handle,
|
||||
int *running_handles);
|
||||
|
||||
#ifndef CURL_ALLOW_OLD_MULTI_SOCKET
|
||||
/* This macro below was added in 7.16.3 to push users who recompile to use
|
||||
the new curl_multi_socket_action() instead of the old curl_multi_socket()
|
||||
*/
|
||||
#define curl_multi_socket(x,y,z) curl_multi_socket_action(x,y,0,z)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Name: curl_multi_timeout()
|
||||
*
|
||||
* Desc: Returns the maximum number of milliseconds the app is allowed to
|
||||
* wait before curl_multi_socket() or curl_multi_perform() must be
|
||||
* called (to allow libcurl's timed events to take place).
|
||||
*
|
||||
* Returns: CURLM error code.
|
||||
*/
|
||||
CURL_EXTERN CURLMcode curl_multi_timeout(CURLM *multi_handle,
|
||||
long *milliseconds);
|
||||
|
||||
#undef CINIT /* re-using the same name as in curl.h */
|
||||
|
||||
#ifdef CURL_ISOCPP
|
||||
#define CINIT(name,type,num) CURLMOPT_ ## name = CURLOPTTYPE_ ## type + num
|
||||
#else
|
||||
/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */
|
||||
#define LONG CURLOPTTYPE_LONG
|
||||
#define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT
|
||||
#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT
|
||||
#define OFF_T CURLOPTTYPE_OFF_T
|
||||
#define CINIT(name,type,number) CURLMOPT_/**/name = type + number
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
/* This is the socket callback function pointer */
|
||||
CINIT(SOCKETFUNCTION, FUNCTIONPOINT, 1),
|
||||
|
||||
/* This is the argument passed to the socket callback */
|
||||
CINIT(SOCKETDATA, OBJECTPOINT, 2),
|
||||
|
||||
/* set to 1 to enable pipelining for this multi handle */
|
||||
CINIT(PIPELINING, LONG, 3),
|
||||
|
||||
/* This is the timer callback function pointer */
|
||||
CINIT(TIMERFUNCTION, FUNCTIONPOINT, 4),
|
||||
|
||||
/* This is the argument passed to the timer callback */
|
||||
CINIT(TIMERDATA, OBJECTPOINT, 5),
|
||||
|
||||
/* maximum number of entries in the connection cache */
|
||||
CINIT(MAXCONNECTS, LONG, 6),
|
||||
|
||||
/* maximum number of (pipelining) connections to one host */
|
||||
CINIT(MAX_HOST_CONNECTIONS, LONG, 7),
|
||||
|
||||
/* maximum number of requests in a pipeline */
|
||||
CINIT(MAX_PIPELINE_LENGTH, LONG, 8),
|
||||
|
||||
/* a connection with a content-length longer than this
|
||||
will not be considered for pipelining */
|
||||
CINIT(CONTENT_LENGTH_PENALTY_SIZE, OFF_T, 9),
|
||||
|
||||
/* a connection with a chunk length longer than this
|
||||
will not be considered for pipelining */
|
||||
CINIT(CHUNK_LENGTH_PENALTY_SIZE, OFF_T, 10),
|
||||
|
||||
/* a list of site names(+port) that are blacklisted from
|
||||
pipelining */
|
||||
CINIT(PIPELINING_SITE_BL, OBJECTPOINT, 11),
|
||||
|
||||
/* a list of server types that are blacklisted from
|
||||
pipelining */
|
||||
CINIT(PIPELINING_SERVER_BL, OBJECTPOINT, 12),
|
||||
|
||||
/* maximum number of open connections in total */
|
||||
CINIT(MAX_TOTAL_CONNECTIONS, LONG, 13),
|
||||
|
||||
/* This is the server push callback function pointer */
|
||||
CINIT(PUSHFUNCTION, FUNCTIONPOINT, 14),
|
||||
|
||||
/* This is the argument passed to the server push callback */
|
||||
CINIT(PUSHDATA, OBJECTPOINT, 15),
|
||||
|
||||
CURLMOPT_LASTENTRY /* the last unused */
|
||||
} CURLMoption;
|
||||
|
||||
|
||||
/*
|
||||
* Name: curl_multi_setopt()
|
||||
*
|
||||
* Desc: Sets options for the multi handle.
|
||||
*
|
||||
* Returns: CURLM error code.
|
||||
*/
|
||||
CURL_EXTERN CURLMcode curl_multi_setopt(CURLM *multi_handle,
|
||||
CURLMoption option, ...);
|
||||
|
||||
|
||||
/*
|
||||
* Name: curl_multi_assign()
|
||||
*
|
||||
* Desc: This function sets an association in the multi handle between the
|
||||
* given socket and a private pointer of the application. This is
|
||||
* (only) useful for curl_multi_socket uses.
|
||||
*
|
||||
* Returns: CURLM error code.
|
||||
*/
|
||||
CURL_EXTERN CURLMcode curl_multi_assign(CURLM *multi_handle,
|
||||
curl_socket_t sockfd, void *sockp);
|
||||
|
||||
|
||||
/*
|
||||
* Name: curl_push_callback
|
||||
*
|
||||
* Desc: This callback gets called when a new stream is being pushed by the
|
||||
* server. It approves or denies the new stream.
|
||||
*
|
||||
* Returns: CURL_PUSH_OK or CURL_PUSH_DENY.
|
||||
*/
|
||||
#define CURL_PUSH_OK 0
|
||||
#define CURL_PUSH_DENY 1
|
||||
|
||||
struct curl_pushheaders; /* forward declaration only */
|
||||
|
||||
CURL_EXTERN char *curl_pushheader_bynum(struct curl_pushheaders *h,
|
||||
size_t num);
|
||||
CURL_EXTERN char *curl_pushheader_byname(struct curl_pushheaders *h,
|
||||
const char *name);
|
||||
|
||||
typedef int (*curl_push_callback)(CURL *parent,
|
||||
CURL *easy,
|
||||
size_t num_headers,
|
||||
struct curl_pushheaders *headers,
|
||||
void *userp);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* end of extern "C" */
|
||||
#endif
|
||||
|
||||
#endif
|
33
src/dependencies/cmcurl/include/curl/stdcheaders.h
Normal file
33
src/dependencies/cmcurl/include/curl/stdcheaders.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
#ifndef __STDC_HEADERS_H
|
||||
#define __STDC_HEADERS_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
size_t fread(void *, size_t, size_t, FILE *);
|
||||
size_t fwrite(const void *, size_t, size_t, FILE *);
|
||||
|
||||
int strcasecmp(const char *, const char *);
|
||||
int strncasecmp(const char *, const char *, size_t);
|
||||
|
||||
#endif /* __STDC_HEADERS_H */
|
493
src/dependencies/cmcurl/include/curl/system.h
Normal file
493
src/dependencies/cmcurl/include/curl/system.h
Normal file
|
@ -0,0 +1,493 @@
|
|||
#ifndef __CURL_SYSTEM_H
|
||||
#define __CURL_SYSTEM_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2017, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
* Try to keep one section per platform, compiler and architecture, otherwise,
|
||||
* if an existing section is reused for a different one and later on the
|
||||
* original is adjusted, probably the piggybacking one can be adversely
|
||||
* changed.
|
||||
*
|
||||
* In order to differentiate between platforms/compilers/architectures use
|
||||
* only compiler built in predefined preprocessor symbols.
|
||||
*
|
||||
* curl_off_t
|
||||
* ----------
|
||||
*
|
||||
* For any given platform/compiler curl_off_t must be typedef'ed to a 64-bit
|
||||
* wide signed integral data type. The width of this data type must remain
|
||||
* constant and independent of any possible large file support settings.
|
||||
*
|
||||
* As an exception to the above, curl_off_t shall be typedef'ed to a 32-bit
|
||||
* wide signed integral data type if there is no 64-bit type.
|
||||
*
|
||||
* As a general rule, curl_off_t shall not be mapped to off_t. This rule shall
|
||||
* only be violated if off_t is the only 64-bit data type available and the
|
||||
* size of off_t is independent of large file support settings. Keep your
|
||||
* build on the safe side avoiding an off_t gating. If you have a 64-bit
|
||||
* off_t then take for sure that another 64-bit data type exists, dig deeper
|
||||
* and you will find it.
|
||||
*
|
||||
*/
|
||||
|
||||
#if defined(__DJGPP__) || defined(__GO32__)
|
||||
# if defined(__DJGPP__) && (__DJGPP__ > 1)
|
||||
# define CURL_TYPEOF_CURL_OFF_T long long
|
||||
# define CURL_FORMAT_CURL_OFF_T "lld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "llu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T LL
|
||||
# define CURL_SUFFIX_CURL_OFF_TU ULL
|
||||
# else
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T L
|
||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
||||
# endif
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T int
|
||||
|
||||
#elif defined(__SALFORDC__)
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T L
|
||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T int
|
||||
|
||||
#elif defined(__BORLANDC__)
|
||||
# if (__BORLANDC__ < 0x520)
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T L
|
||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
||||
# else
|
||||
# define CURL_TYPEOF_CURL_OFF_T __int64
|
||||
# define CURL_FORMAT_CURL_OFF_T "I64d"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "I64u"
|
||||
# define CURL_SUFFIX_CURL_OFF_T i64
|
||||
# define CURL_SUFFIX_CURL_OFF_TU ui64
|
||||
# endif
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T int
|
||||
|
||||
#elif defined(__TURBOC__)
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T L
|
||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T int
|
||||
|
||||
#elif defined(__WATCOMC__)
|
||||
# if defined(__386__)
|
||||
# define CURL_TYPEOF_CURL_OFF_T __int64
|
||||
# define CURL_FORMAT_CURL_OFF_T "I64d"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "I64u"
|
||||
# define CURL_SUFFIX_CURL_OFF_T i64
|
||||
# define CURL_SUFFIX_CURL_OFF_TU ui64
|
||||
# else
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T L
|
||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
||||
# endif
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T int
|
||||
|
||||
#elif defined(__POCC__)
|
||||
# if (__POCC__ < 280)
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T L
|
||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
||||
# elif defined(_MSC_VER)
|
||||
# define CURL_TYPEOF_CURL_OFF_T __int64
|
||||
# define CURL_FORMAT_CURL_OFF_T "I64d"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "I64u"
|
||||
# define CURL_SUFFIX_CURL_OFF_T i64
|
||||
# define CURL_SUFFIX_CURL_OFF_TU ui64
|
||||
# else
|
||||
# define CURL_TYPEOF_CURL_OFF_T long long
|
||||
# define CURL_FORMAT_CURL_OFF_T "lld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "llu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T LL
|
||||
# define CURL_SUFFIX_CURL_OFF_TU ULL
|
||||
# endif
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T int
|
||||
|
||||
#elif defined(__LCC__)
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T L
|
||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T int
|
||||
|
||||
#elif defined(__SYMBIAN32__)
|
||||
# if defined(__EABI__) /* Treat all ARM compilers equally */
|
||||
# define CURL_TYPEOF_CURL_OFF_T long long
|
||||
# define CURL_FORMAT_CURL_OFF_T "lld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "llu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T LL
|
||||
# define CURL_SUFFIX_CURL_OFF_TU ULL
|
||||
# elif defined(__CW32__)
|
||||
# pragma longlong on
|
||||
# define CURL_TYPEOF_CURL_OFF_T long long
|
||||
# define CURL_FORMAT_CURL_OFF_T "lld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "llu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T LL
|
||||
# define CURL_SUFFIX_CURL_OFF_TU ULL
|
||||
# elif defined(__VC32__)
|
||||
# define CURL_TYPEOF_CURL_OFF_T __int64
|
||||
# define CURL_FORMAT_CURL_OFF_T "lld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "llu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T LL
|
||||
# define CURL_SUFFIX_CURL_OFF_TU ULL
|
||||
# endif
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int
|
||||
|
||||
#elif defined(__MWERKS__)
|
||||
# define CURL_TYPEOF_CURL_OFF_T long long
|
||||
# define CURL_FORMAT_CURL_OFF_T "lld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "llu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T LL
|
||||
# define CURL_SUFFIX_CURL_OFF_TU ULL
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T int
|
||||
|
||||
#elif defined(_WIN32_WCE)
|
||||
# define CURL_TYPEOF_CURL_OFF_T __int64
|
||||
# define CURL_FORMAT_CURL_OFF_T "I64d"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "I64u"
|
||||
# define CURL_SUFFIX_CURL_OFF_T i64
|
||||
# define CURL_SUFFIX_CURL_OFF_TU ui64
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T int
|
||||
|
||||
#elif defined(__MINGW32__)
|
||||
# define CURL_TYPEOF_CURL_OFF_T long long
|
||||
# define CURL_FORMAT_CURL_OFF_T "I64d"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "I64u"
|
||||
# define CURL_SUFFIX_CURL_OFF_T LL
|
||||
# define CURL_SUFFIX_CURL_OFF_TU ULL
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
|
||||
# define CURL_PULL_SYS_TYPES_H 1
|
||||
# define CURL_PULL_WS2TCPIP_H 1
|
||||
|
||||
#elif defined(__VMS)
|
||||
# if defined(__VAX)
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T L
|
||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
||||
# else
|
||||
# define CURL_TYPEOF_CURL_OFF_T long long
|
||||
# define CURL_FORMAT_CURL_OFF_T "lld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "llu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T LL
|
||||
# define CURL_SUFFIX_CURL_OFF_TU ULL
|
||||
# endif
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int
|
||||
|
||||
#elif defined(__OS400__)
|
||||
# if defined(__ILEC400__)
|
||||
# define CURL_TYPEOF_CURL_OFF_T long long
|
||||
# define CURL_FORMAT_CURL_OFF_T "lld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "llu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T LL
|
||||
# define CURL_SUFFIX_CURL_OFF_TU ULL
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
|
||||
# define CURL_PULL_SYS_TYPES_H 1
|
||||
# define CURL_PULL_SYS_SOCKET_H 1
|
||||
# endif
|
||||
|
||||
#elif defined(__MVS__)
|
||||
# if defined(__IBMC__) || defined(__IBMCPP__)
|
||||
# if defined(_ILP32)
|
||||
# elif defined(_LP64)
|
||||
# endif
|
||||
# if defined(_LONG_LONG)
|
||||
# define CURL_TYPEOF_CURL_OFF_T long long
|
||||
# define CURL_FORMAT_CURL_OFF_T "lld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "llu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T LL
|
||||
# define CURL_SUFFIX_CURL_OFF_TU ULL
|
||||
# elif defined(_LP64)
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T L
|
||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
||||
# else
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T L
|
||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
||||
# endif
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
|
||||
# define CURL_PULL_SYS_TYPES_H 1
|
||||
# define CURL_PULL_SYS_SOCKET_H 1
|
||||
# endif
|
||||
|
||||
#elif defined(__370__)
|
||||
# if defined(__IBMC__) || defined(__IBMCPP__)
|
||||
# if defined(_ILP32)
|
||||
# elif defined(_LP64)
|
||||
# endif
|
||||
# if defined(_LONG_LONG)
|
||||
# define CURL_TYPEOF_CURL_OFF_T long long
|
||||
# define CURL_FORMAT_CURL_OFF_T "lld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "llu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T LL
|
||||
# define CURL_SUFFIX_CURL_OFF_TU ULL
|
||||
# elif defined(_LP64)
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T L
|
||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
||||
# else
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T L
|
||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
||||
# endif
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
|
||||
# define CURL_PULL_SYS_TYPES_H 1
|
||||
# define CURL_PULL_SYS_SOCKET_H 1
|
||||
# endif
|
||||
|
||||
#elif defined(TPF)
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T L
|
||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T int
|
||||
|
||||
#elif defined(__TINYC__) /* also known as tcc */
|
||||
|
||||
# define CURL_TYPEOF_CURL_OFF_T long long
|
||||
# define CURL_FORMAT_CURL_OFF_T "lld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "llu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T LL
|
||||
# define CURL_SUFFIX_CURL_OFF_TU ULL
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
|
||||
# define CURL_PULL_SYS_TYPES_H 1
|
||||
# define CURL_PULL_SYS_SOCKET_H 1
|
||||
|
||||
#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) /* Oracle Solaris Studio */
|
||||
# if !defined(__LP64) && (defined(__ILP32) || \
|
||||
defined(__i386) || \
|
||||
defined(__sparcv8) || \
|
||||
defined(__sparcv8plus))
|
||||
# define CURL_TYPEOF_CURL_OFF_T long long
|
||||
# define CURL_FORMAT_CURL_OFF_T "lld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "llu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T LL
|
||||
# define CURL_SUFFIX_CURL_OFF_TU ULL
|
||||
# elif defined(__LP64) || \
|
||||
defined(__amd64) || defined(__sparcv9)
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T L
|
||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
||||
# endif
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
|
||||
# define CURL_PULL_SYS_TYPES_H 1
|
||||
# define CURL_PULL_SYS_SOCKET_H 1
|
||||
|
||||
#elif defined(__xlc__) /* IBM xlc compiler */
|
||||
# if !defined(_LP64)
|
||||
# define CURL_TYPEOF_CURL_OFF_T long long
|
||||
# define CURL_FORMAT_CURL_OFF_T "lld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "llu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T LL
|
||||
# define CURL_SUFFIX_CURL_OFF_TU ULL
|
||||
# else
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T L
|
||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
||||
# endif
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
|
||||
# define CURL_PULL_SYS_TYPES_H 1
|
||||
# define CURL_PULL_SYS_SOCKET_H 1
|
||||
|
||||
/* ===================================== */
|
||||
/* KEEP MSVC THE PENULTIMATE ENTRY */
|
||||
/* ===================================== */
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
# if (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64)
|
||||
# define CURL_TYPEOF_CURL_OFF_T __int64
|
||||
# define CURL_FORMAT_CURL_OFF_T "I64d"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "I64u"
|
||||
# define CURL_SUFFIX_CURL_OFF_T i64
|
||||
# define CURL_SUFFIX_CURL_OFF_TU ui64
|
||||
# else
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T L
|
||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
||||
# endif
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T int
|
||||
|
||||
/* ===================================== */
|
||||
/* KEEP GENERIC GCC THE LAST ENTRY */
|
||||
/* ===================================== */
|
||||
|
||||
#elif defined(__GNUC__) && !defined(_SCO_DS)
|
||||
# if !defined(__LP64__) && \
|
||||
(defined(__ILP32__) || defined(__i386__) || defined(__hppa__) || \
|
||||
defined(__ppc__) || defined(__powerpc__) || defined(__arm__) || \
|
||||
defined(__sparc__) || defined(__mips__) || defined(__sh__) || \
|
||||
defined(__XTENSA__) || \
|
||||
(defined(__SIZEOF_LONG__) && __SIZEOF_LONG__ == 4) || \
|
||||
(defined(__LONG_MAX__) && __LONG_MAX__ == 2147483647L))
|
||||
# define CURL_TYPEOF_CURL_OFF_T long long
|
||||
# define CURL_FORMAT_CURL_OFF_T "lld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "llu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T LL
|
||||
# define CURL_SUFFIX_CURL_OFF_TU ULL
|
||||
# elif defined(__LP64__) || \
|
||||
defined(__x86_64__) || defined(__ppc64__) || defined(__sparc64__) || \
|
||||
(defined(__SIZEOF_LONG__) && __SIZEOF_LONG__ == 8) || \
|
||||
(defined(__LONG_MAX__) && __LONG_MAX__ == 9223372036854775807L)
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T L
|
||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
||||
# endif
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
|
||||
# define CURL_PULL_SYS_TYPES_H 1
|
||||
# define CURL_PULL_SYS_SOCKET_H 1
|
||||
|
||||
#else
|
||||
/* generic "safe guess" on old 32 bit style */
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T L
|
||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T int
|
||||
#endif
|
||||
|
||||
#ifdef _AIX
|
||||
/* AIX needs <sys/poll.h> */
|
||||
#define CURL_PULL_SYS_POLL_H
|
||||
#endif
|
||||
|
||||
|
||||
/* CURL_PULL_WS2TCPIP_H is defined above when inclusion of header file */
|
||||
/* ws2tcpip.h is required here to properly make type definitions below. */
|
||||
#ifdef CURL_PULL_WS2TCPIP_H
|
||||
# include <winsock2.h>
|
||||
# include <windows.h>
|
||||
# include <ws2tcpip.h>
|
||||
#endif
|
||||
|
||||
/* CURL_PULL_SYS_TYPES_H is defined above when inclusion of header file */
|
||||
/* sys/types.h is required here to properly make type definitions below. */
|
||||
#ifdef CURL_PULL_SYS_TYPES_H
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
|
||||
/* CURL_PULL_SYS_SOCKET_H is defined above when inclusion of header file */
|
||||
/* sys/socket.h is required here to properly make type definitions below. */
|
||||
#ifdef CURL_PULL_SYS_SOCKET_H
|
||||
# include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
/* CURL_PULL_SYS_POLL_H is defined above when inclusion of header file */
|
||||
/* sys/poll.h is required here to properly make type definitions below. */
|
||||
#ifdef CURL_PULL_SYS_POLL_H
|
||||
# include <sys/poll.h>
|
||||
#endif
|
||||
|
||||
/* Data type definition of curl_socklen_t. */
|
||||
#ifdef CURL_TYPEOF_CURL_SOCKLEN_T
|
||||
typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t;
|
||||
#endif
|
||||
|
||||
/* Data type definition of curl_off_t. */
|
||||
|
||||
#ifdef CURL_TYPEOF_CURL_OFF_T
|
||||
typedef CURL_TYPEOF_CURL_OFF_T curl_off_t;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* CURL_ISOCPP and CURL_OFF_T_C definitions are done here in order to allow
|
||||
* these to be visible and exported by the external libcurl interface API,
|
||||
* while also making them visible to the library internals, simply including
|
||||
* curl_setup.h, without actually needing to include curl.h internally.
|
||||
* If some day this section would grow big enough, all this should be moved
|
||||
* to its own header file.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Figure out if we can use the ## preprocessor operator, which is supported
|
||||
* by ISO/ANSI C and C++. Some compilers support it without setting __STDC__
|
||||
* or __cplusplus so we need to carefully check for them too.
|
||||
*/
|
||||
|
||||
#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) || \
|
||||
defined(__HP_aCC) || defined(__BORLANDC__) || defined(__LCC__) || \
|
||||
defined(__POCC__) || defined(__SALFORDC__) || defined(__HIGHC__) || \
|
||||
defined(__ILEC400__)
|
||||
/* This compiler is believed to have an ISO compatible preprocessor */
|
||||
#define CURL_ISOCPP
|
||||
#else
|
||||
/* This compiler is believed NOT to have an ISO compatible preprocessor */
|
||||
#undef CURL_ISOCPP
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Macros for minimum-width signed and unsigned curl_off_t integer constants.
|
||||
*/
|
||||
|
||||
#if defined(__BORLANDC__) && (__BORLANDC__ == 0x0551)
|
||||
# define __CURL_OFF_T_C_HLPR2(x) x
|
||||
# define __CURL_OFF_T_C_HLPR1(x) __CURL_OFF_T_C_HLPR2(x)
|
||||
# define CURL_OFF_T_C(Val) __CURL_OFF_T_C_HLPR1(Val) ## \
|
||||
__CURL_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_T)
|
||||
# define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HLPR1(Val) ## \
|
||||
__CURL_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_TU)
|
||||
#else
|
||||
# ifdef CURL_ISOCPP
|
||||
# define __CURL_OFF_T_C_HLPR2(Val,Suffix) Val ## Suffix
|
||||
# else
|
||||
# define __CURL_OFF_T_C_HLPR2(Val,Suffix) Val/**/Suffix
|
||||
# endif
|
||||
# define __CURL_OFF_T_C_HLPR1(Val,Suffix) __CURL_OFF_T_C_HLPR2(Val,Suffix)
|
||||
# define CURL_OFF_T_C(Val) __CURL_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_T)
|
||||
# define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_TU)
|
||||
#endif
|
||||
|
||||
#endif /* __CURL_SYSTEM_H */
|
694
src/dependencies/cmcurl/include/curl/typecheck-gcc.h
Normal file
694
src/dependencies/cmcurl/include/curl/typecheck-gcc.h
Normal file
|
@ -0,0 +1,694 @@
|
|||
#ifndef __CURL_TYPECHECK_GCC_H
|
||||
#define __CURL_TYPECHECK_GCC_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* wraps curl_easy_setopt() with typechecking */
|
||||
|
||||
/* To add a new kind of warning, add an
|
||||
* if(_curl_is_sometype_option(_curl_opt))
|
||||
* if(!_curl_is_sometype(value))
|
||||
* _curl_easy_setopt_err_sometype();
|
||||
* block and define _curl_is_sometype_option, _curl_is_sometype and
|
||||
* _curl_easy_setopt_err_sometype below
|
||||
*
|
||||
* NOTE: We use two nested 'if' statements here instead of the && operator, in
|
||||
* order to work around gcc bug #32061. It affects only gcc 4.3.x/4.4.x
|
||||
* when compiling with -Wlogical-op.
|
||||
*
|
||||
* To add an option that uses the same type as an existing option, you'll just
|
||||
* need to extend the appropriate _curl_*_option macro
|
||||
*/
|
||||
#define curl_easy_setopt(handle, option, value) \
|
||||
__extension__ ({ \
|
||||
__typeof__(option) _curl_opt = option; \
|
||||
if(__builtin_constant_p(_curl_opt)) { \
|
||||
if(_curl_is_long_option(_curl_opt)) \
|
||||
if(!_curl_is_long(value)) \
|
||||
_curl_easy_setopt_err_long(); \
|
||||
if(_curl_is_off_t_option(_curl_opt)) \
|
||||
if(!_curl_is_off_t(value)) \
|
||||
_curl_easy_setopt_err_curl_off_t(); \
|
||||
if(_curl_is_string_option(_curl_opt)) \
|
||||
if(!_curl_is_string(value)) \
|
||||
_curl_easy_setopt_err_string(); \
|
||||
if(_curl_is_write_cb_option(_curl_opt)) \
|
||||
if(!_curl_is_write_cb(value)) \
|
||||
_curl_easy_setopt_err_write_callback(); \
|
||||
if((_curl_opt) == CURLOPT_RESOLVER_START_FUNCTION) \
|
||||
if(!_curl_is_resolver_start_callback(value)) \
|
||||
_curl_easy_setopt_err_resolver_start_callback(); \
|
||||
if((_curl_opt) == CURLOPT_READFUNCTION) \
|
||||
if(!_curl_is_read_cb(value)) \
|
||||
_curl_easy_setopt_err_read_cb(); \
|
||||
if((_curl_opt) == CURLOPT_IOCTLFUNCTION) \
|
||||
if(!_curl_is_ioctl_cb(value)) \
|
||||
_curl_easy_setopt_err_ioctl_cb(); \
|
||||
if((_curl_opt) == CURLOPT_SOCKOPTFUNCTION) \
|
||||
if(!_curl_is_sockopt_cb(value)) \
|
||||
_curl_easy_setopt_err_sockopt_cb(); \
|
||||
if((_curl_opt) == CURLOPT_OPENSOCKETFUNCTION) \
|
||||
if(!_curl_is_opensocket_cb(value)) \
|
||||
_curl_easy_setopt_err_opensocket_cb(); \
|
||||
if((_curl_opt) == CURLOPT_PROGRESSFUNCTION) \
|
||||
if(!_curl_is_progress_cb(value)) \
|
||||
_curl_easy_setopt_err_progress_cb(); \
|
||||
if((_curl_opt) == CURLOPT_DEBUGFUNCTION) \
|
||||
if(!_curl_is_debug_cb(value)) \
|
||||
_curl_easy_setopt_err_debug_cb(); \
|
||||
if((_curl_opt) == CURLOPT_SSL_CTX_FUNCTION) \
|
||||
if(!_curl_is_ssl_ctx_cb(value)) \
|
||||
_curl_easy_setopt_err_ssl_ctx_cb(); \
|
||||
if(_curl_is_conv_cb_option(_curl_opt)) \
|
||||
if(!_curl_is_conv_cb(value)) \
|
||||
_curl_easy_setopt_err_conv_cb(); \
|
||||
if((_curl_opt) == CURLOPT_SEEKFUNCTION) \
|
||||
if(!_curl_is_seek_cb(value)) \
|
||||
_curl_easy_setopt_err_seek_cb(); \
|
||||
if(_curl_is_cb_data_option(_curl_opt)) \
|
||||
if(!_curl_is_cb_data(value)) \
|
||||
_curl_easy_setopt_err_cb_data(); \
|
||||
if((_curl_opt) == CURLOPT_ERRORBUFFER) \
|
||||
if(!_curl_is_error_buffer(value)) \
|
||||
_curl_easy_setopt_err_error_buffer(); \
|
||||
if((_curl_opt) == CURLOPT_STDERR) \
|
||||
if(!_curl_is_FILE(value)) \
|
||||
_curl_easy_setopt_err_FILE(); \
|
||||
if(_curl_is_postfields_option(_curl_opt)) \
|
||||
if(!_curl_is_postfields(value)) \
|
||||
_curl_easy_setopt_err_postfields(); \
|
||||
if((_curl_opt) == CURLOPT_HTTPPOST) \
|
||||
if(!_curl_is_arr((value), struct curl_httppost)) \
|
||||
_curl_easy_setopt_err_curl_httpost(); \
|
||||
if((_curl_opt) == CURLOPT_MIMEPOST) \
|
||||
if(!_curl_is_ptr((value), curl_mime)) \
|
||||
_curl_easy_setopt_err_curl_mimepost(); \
|
||||
if(_curl_is_slist_option(_curl_opt)) \
|
||||
if(!_curl_is_arr((value), struct curl_slist)) \
|
||||
_curl_easy_setopt_err_curl_slist(); \
|
||||
if((_curl_opt) == CURLOPT_SHARE) \
|
||||
if(!_curl_is_ptr((value), CURLSH)) \
|
||||
_curl_easy_setopt_err_CURLSH(); \
|
||||
} \
|
||||
curl_easy_setopt(handle, _curl_opt, value); \
|
||||
})
|
||||
|
||||
/* wraps curl_easy_getinfo() with typechecking */
|
||||
#define curl_easy_getinfo(handle, info, arg) \
|
||||
__extension__ ({ \
|
||||
__typeof__(info) _curl_info = info; \
|
||||
if(__builtin_constant_p(_curl_info)) { \
|
||||
if(_curl_is_string_info(_curl_info)) \
|
||||
if(!_curl_is_arr((arg), char *)) \
|
||||
_curl_easy_getinfo_err_string(); \
|
||||
if(_curl_is_long_info(_curl_info)) \
|
||||
if(!_curl_is_arr((arg), long)) \
|
||||
_curl_easy_getinfo_err_long(); \
|
||||
if(_curl_is_double_info(_curl_info)) \
|
||||
if(!_curl_is_arr((arg), double)) \
|
||||
_curl_easy_getinfo_err_double(); \
|
||||
if(_curl_is_slist_info(_curl_info)) \
|
||||
if(!_curl_is_arr((arg), struct curl_slist *)) \
|
||||
_curl_easy_getinfo_err_curl_slist(); \
|
||||
if(_curl_is_tlssessioninfo_info(_curl_info)) \
|
||||
if(!_curl_is_arr((arg), struct curl_tlssessioninfo *)) \
|
||||
_curl_easy_getinfo_err_curl_tlssesssioninfo(); \
|
||||
if(_curl_is_certinfo_info(_curl_info)) \
|
||||
if(!_curl_is_arr((arg), struct curl_certinfo *)) \
|
||||
_curl_easy_getinfo_err_curl_certinfo(); \
|
||||
if(_curl_is_socket_info(_curl_info)) \
|
||||
if(!_curl_is_arr((arg), curl_socket_t)) \
|
||||
_curl_easy_getinfo_err_curl_socket(); \
|
||||
if(_curl_is_off_t_info(_curl_info)) \
|
||||
if(!_curl_is_arr((arg), curl_off_t)) \
|
||||
_curl_easy_getinfo_err_curl_off_t(); \
|
||||
} \
|
||||
curl_easy_getinfo(handle, _curl_info, arg); \
|
||||
})
|
||||
|
||||
/*
|
||||
* For now, just make sure that the functions are called with three arguments
|
||||
*/
|
||||
#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param)
|
||||
#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param)
|
||||
|
||||
|
||||
/* the actual warnings, triggered by calling the _curl_easy_setopt_err*
|
||||
* functions */
|
||||
|
||||
/* To define a new warning, use _CURL_WARNING(identifier, "message") */
|
||||
#define _CURL_WARNING(id, message) \
|
||||
static void __attribute__((__warning__(message))) \
|
||||
__attribute__((__unused__)) __attribute__((__noinline__)) \
|
||||
id(void) { __asm__(""); }
|
||||
|
||||
_CURL_WARNING(_curl_easy_setopt_err_long,
|
||||
"curl_easy_setopt expects a long argument for this option")
|
||||
_CURL_WARNING(_curl_easy_setopt_err_curl_off_t,
|
||||
"curl_easy_setopt expects a curl_off_t argument for this option")
|
||||
_CURL_WARNING(_curl_easy_setopt_err_string,
|
||||
"curl_easy_setopt expects a "
|
||||
"string ('char *' or char[]) argument for this option"
|
||||
)
|
||||
_CURL_WARNING(_curl_easy_setopt_err_write_callback,
|
||||
"curl_easy_setopt expects a curl_write_callback argument for this option")
|
||||
_CURL_WARNING(_curl_easy_setopt_err_resolver_start_callback,
|
||||
"curl_easy_setopt expects a "
|
||||
"curl_resolver_start_callback argument for this option"
|
||||
)
|
||||
_CURL_WARNING(_curl_easy_setopt_err_read_cb,
|
||||
"curl_easy_setopt expects a curl_read_callback argument for this option")
|
||||
_CURL_WARNING(_curl_easy_setopt_err_ioctl_cb,
|
||||
"curl_easy_setopt expects a curl_ioctl_callback argument for this option")
|
||||
_CURL_WARNING(_curl_easy_setopt_err_sockopt_cb,
|
||||
"curl_easy_setopt expects a curl_sockopt_callback argument for this option")
|
||||
_CURL_WARNING(_curl_easy_setopt_err_opensocket_cb,
|
||||
"curl_easy_setopt expects a "
|
||||
"curl_opensocket_callback argument for this option"
|
||||
)
|
||||
_CURL_WARNING(_curl_easy_setopt_err_progress_cb,
|
||||
"curl_easy_setopt expects a curl_progress_callback argument for this option")
|
||||
_CURL_WARNING(_curl_easy_setopt_err_debug_cb,
|
||||
"curl_easy_setopt expects a curl_debug_callback argument for this option")
|
||||
_CURL_WARNING(_curl_easy_setopt_err_ssl_ctx_cb,
|
||||
"curl_easy_setopt expects a curl_ssl_ctx_callback argument for this option")
|
||||
_CURL_WARNING(_curl_easy_setopt_err_conv_cb,
|
||||
"curl_easy_setopt expects a curl_conv_callback argument for this option")
|
||||
_CURL_WARNING(_curl_easy_setopt_err_seek_cb,
|
||||
"curl_easy_setopt expects a curl_seek_callback argument for this option")
|
||||
_CURL_WARNING(_curl_easy_setopt_err_cb_data,
|
||||
"curl_easy_setopt expects a "
|
||||
"private data pointer as argument for this option")
|
||||
_CURL_WARNING(_curl_easy_setopt_err_error_buffer,
|
||||
"curl_easy_setopt expects a "
|
||||
"char buffer of CURL_ERROR_SIZE as argument for this option")
|
||||
_CURL_WARNING(_curl_easy_setopt_err_FILE,
|
||||
"curl_easy_setopt expects a 'FILE *' argument for this option")
|
||||
_CURL_WARNING(_curl_easy_setopt_err_postfields,
|
||||
"curl_easy_setopt expects a 'void *' or 'char *' argument for this option")
|
||||
_CURL_WARNING(_curl_easy_setopt_err_curl_httpost,
|
||||
"curl_easy_setopt expects a 'struct curl_httppost *' "
|
||||
"argument for this option")
|
||||
_CURL_WARNING(_curl_easy_setopt_err_curl_mimepost,
|
||||
"curl_easy_setopt expects a 'curl_mime *' "
|
||||
"argument for this option")
|
||||
_CURL_WARNING(_curl_easy_setopt_err_curl_slist,
|
||||
"curl_easy_setopt expects a 'struct curl_slist *' argument for this option")
|
||||
_CURL_WARNING(_curl_easy_setopt_err_CURLSH,
|
||||
"curl_easy_setopt expects a CURLSH* argument for this option")
|
||||
|
||||
_CURL_WARNING(_curl_easy_getinfo_err_string,
|
||||
"curl_easy_getinfo expects a pointer to 'char *' for this info")
|
||||
_CURL_WARNING(_curl_easy_getinfo_err_long,
|
||||
"curl_easy_getinfo expects a pointer to long for this info")
|
||||
_CURL_WARNING(_curl_easy_getinfo_err_double,
|
||||
"curl_easy_getinfo expects a pointer to double for this info")
|
||||
_CURL_WARNING(_curl_easy_getinfo_err_curl_slist,
|
||||
"curl_easy_getinfo expects a pointer to 'struct curl_slist *' for this info")
|
||||
_CURL_WARNING(_curl_easy_getinfo_err_curl_tlssesssioninfo,
|
||||
"curl_easy_getinfo expects a pointer to "
|
||||
"'struct curl_tlssessioninfo *' for this info")
|
||||
_CURL_WARNING(_curl_easy_getinfo_err_curl_certinfo,
|
||||
"curl_easy_getinfo expects a pointer to "
|
||||
"'struct curl_certinfo *' for this info")
|
||||
_CURL_WARNING(_curl_easy_getinfo_err_curl_socket,
|
||||
"curl_easy_getinfo expects a pointer to curl_socket_t for this info")
|
||||
_CURL_WARNING(_curl_easy_getinfo_err_curl_off_t,
|
||||
"curl_easy_getinfo expects a pointer to curl_off_t for this info")
|
||||
|
||||
/* groups of curl_easy_setops options that take the same type of argument */
|
||||
|
||||
/* To add a new option to one of the groups, just add
|
||||
* (option) == CURLOPT_SOMETHING
|
||||
* to the or-expression. If the option takes a long or curl_off_t, you don't
|
||||
* have to do anything
|
||||
*/
|
||||
|
||||
/* evaluates to true if option takes a long argument */
|
||||
#define _curl_is_long_option(option) \
|
||||
(0 < (option) && (option) < CURLOPTTYPE_OBJECTPOINT)
|
||||
|
||||
#define _curl_is_off_t_option(option) \
|
||||
((option) > CURLOPTTYPE_OFF_T)
|
||||
|
||||
/* evaluates to true if option takes a char* argument */
|
||||
#define _curl_is_string_option(option) \
|
||||
((option) == CURLOPT_ABSTRACT_UNIX_SOCKET || \
|
||||
(option) == CURLOPT_ACCEPT_ENCODING || \
|
||||
(option) == CURLOPT_ALTSVC || \
|
||||
(option) == CURLOPT_CAINFO || \
|
||||
(option) == CURLOPT_CAPATH || \
|
||||
(option) == CURLOPT_COOKIE || \
|
||||
(option) == CURLOPT_COOKIEFILE || \
|
||||
(option) == CURLOPT_COOKIEJAR || \
|
||||
(option) == CURLOPT_COOKIELIST || \
|
||||
(option) == CURLOPT_CRLFILE || \
|
||||
(option) == CURLOPT_CUSTOMREQUEST || \
|
||||
(option) == CURLOPT_DEFAULT_PROTOCOL || \
|
||||
(option) == CURLOPT_DNS_INTERFACE || \
|
||||
(option) == CURLOPT_DNS_LOCAL_IP4 || \
|
||||
(option) == CURLOPT_DNS_LOCAL_IP6 || \
|
||||
(option) == CURLOPT_DNS_SERVERS || \
|
||||
(option) == CURLOPT_DOH_URL || \
|
||||
(option) == CURLOPT_EGDSOCKET || \
|
||||
(option) == CURLOPT_FTPPORT || \
|
||||
(option) == CURLOPT_FTP_ACCOUNT || \
|
||||
(option) == CURLOPT_FTP_ALTERNATIVE_TO_USER || \
|
||||
(option) == CURLOPT_INTERFACE || \
|
||||
(option) == CURLOPT_ISSUERCERT || \
|
||||
(option) == CURLOPT_KEYPASSWD || \
|
||||
(option) == CURLOPT_KRBLEVEL || \
|
||||
(option) == CURLOPT_LOGIN_OPTIONS || \
|
||||
(option) == CURLOPT_MAIL_AUTH || \
|
||||
(option) == CURLOPT_MAIL_FROM || \
|
||||
(option) == CURLOPT_NETRC_FILE || \
|
||||
(option) == CURLOPT_NOPROXY || \
|
||||
(option) == CURLOPT_PASSWORD || \
|
||||
(option) == CURLOPT_PINNEDPUBLICKEY || \
|
||||
(option) == CURLOPT_PRE_PROXY || \
|
||||
(option) == CURLOPT_PROXY || \
|
||||
(option) == CURLOPT_PROXYPASSWORD || \
|
||||
(option) == CURLOPT_PROXYUSERNAME || \
|
||||
(option) == CURLOPT_PROXYUSERPWD || \
|
||||
(option) == CURLOPT_PROXY_CAINFO || \
|
||||
(option) == CURLOPT_PROXY_CAPATH || \
|
||||
(option) == CURLOPT_PROXY_CRLFILE || \
|
||||
(option) == CURLOPT_PROXY_KEYPASSWD || \
|
||||
(option) == CURLOPT_PROXY_PINNEDPUBLICKEY || \
|
||||
(option) == CURLOPT_PROXY_SERVICE_NAME || \
|
||||
(option) == CURLOPT_PROXY_SSLCERT || \
|
||||
(option) == CURLOPT_PROXY_SSLCERTTYPE || \
|
||||
(option) == CURLOPT_PROXY_SSLKEY || \
|
||||
(option) == CURLOPT_PROXY_SSLKEYTYPE || \
|
||||
(option) == CURLOPT_PROXY_SSL_CIPHER_LIST || \
|
||||
(option) == CURLOPT_PROXY_TLSAUTH_PASSWORD || \
|
||||
(option) == CURLOPT_PROXY_TLSAUTH_USERNAME || \
|
||||
(option) == CURLOPT_PROXY_TLSAUTH_TYPE || \
|
||||
(option) == CURLOPT_RANDOM_FILE || \
|
||||
(option) == CURLOPT_RANGE || \
|
||||
(option) == CURLOPT_REFERER || \
|
||||
(option) == CURLOPT_RTSP_SESSION_ID || \
|
||||
(option) == CURLOPT_RTSP_STREAM_URI || \
|
||||
(option) == CURLOPT_RTSP_TRANSPORT || \
|
||||
(option) == CURLOPT_SERVICE_NAME || \
|
||||
(option) == CURLOPT_SOCKS5_GSSAPI_SERVICE || \
|
||||
(option) == CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 || \
|
||||
(option) == CURLOPT_SSH_KNOWNHOSTS || \
|
||||
(option) == CURLOPT_SSH_PRIVATE_KEYFILE || \
|
||||
(option) == CURLOPT_SSH_PUBLIC_KEYFILE || \
|
||||
(option) == CURLOPT_SSLCERT || \
|
||||
(option) == CURLOPT_SSLCERTTYPE || \
|
||||
(option) == CURLOPT_SSLENGINE || \
|
||||
(option) == CURLOPT_SSLKEY || \
|
||||
(option) == CURLOPT_SSLKEYTYPE || \
|
||||
(option) == CURLOPT_SSL_CIPHER_LIST || \
|
||||
(option) == CURLOPT_TLSAUTH_PASSWORD || \
|
||||
(option) == CURLOPT_TLSAUTH_TYPE || \
|
||||
(option) == CURLOPT_TLSAUTH_USERNAME || \
|
||||
(option) == CURLOPT_UNIX_SOCKET_PATH || \
|
||||
(option) == CURLOPT_URL || \
|
||||
(option) == CURLOPT_USERAGENT || \
|
||||
(option) == CURLOPT_USERNAME || \
|
||||
(option) == CURLOPT_USERPWD || \
|
||||
(option) == CURLOPT_XOAUTH2_BEARER || \
|
||||
0)
|
||||
|
||||
/* evaluates to true if option takes a curl_write_callback argument */
|
||||
#define _curl_is_write_cb_option(option) \
|
||||
((option) == CURLOPT_HEADERFUNCTION || \
|
||||
(option) == CURLOPT_WRITEFUNCTION)
|
||||
|
||||
/* evaluates to true if option takes a curl_conv_callback argument */
|
||||
#define _curl_is_conv_cb_option(option) \
|
||||
((option) == CURLOPT_CONV_TO_NETWORK_FUNCTION || \
|
||||
(option) == CURLOPT_CONV_FROM_NETWORK_FUNCTION || \
|
||||
(option) == CURLOPT_CONV_FROM_UTF8_FUNCTION)
|
||||
|
||||
/* evaluates to true if option takes a data argument to pass to a callback */
|
||||
#define _curl_is_cb_data_option(option) \
|
||||
((option) == CURLOPT_CHUNK_DATA || \
|
||||
(option) == CURLOPT_CLOSESOCKETDATA || \
|
||||
(option) == CURLOPT_DEBUGDATA || \
|
||||
(option) == CURLOPT_FNMATCH_DATA || \
|
||||
(option) == CURLOPT_HEADERDATA || \
|
||||
(option) == CURLOPT_INTERLEAVEDATA || \
|
||||
(option) == CURLOPT_IOCTLDATA || \
|
||||
(option) == CURLOPT_OPENSOCKETDATA || \
|
||||
(option) == CURLOPT_PRIVATE || \
|
||||
(option) == CURLOPT_PROGRESSDATA || \
|
||||
(option) == CURLOPT_READDATA || \
|
||||
(option) == CURLOPT_SEEKDATA || \
|
||||
(option) == CURLOPT_SOCKOPTDATA || \
|
||||
(option) == CURLOPT_SSH_KEYDATA || \
|
||||
(option) == CURLOPT_SSL_CTX_DATA || \
|
||||
(option) == CURLOPT_WRITEDATA || \
|
||||
(option) == CURLOPT_RESOLVER_START_DATA || \
|
||||
(option) == CURLOPT_CURLU || \
|
||||
0)
|
||||
|
||||
/* evaluates to true if option takes a POST data argument (void* or char*) */
|
||||
#define _curl_is_postfields_option(option) \
|
||||
((option) == CURLOPT_POSTFIELDS || \
|
||||
(option) == CURLOPT_COPYPOSTFIELDS || \
|
||||
0)
|
||||
|
||||
/* evaluates to true if option takes a struct curl_slist * argument */
|
||||
#define _curl_is_slist_option(option) \
|
||||
((option) == CURLOPT_HTTP200ALIASES || \
|
||||
(option) == CURLOPT_HTTPHEADER || \
|
||||
(option) == CURLOPT_MAIL_RCPT || \
|
||||
(option) == CURLOPT_POSTQUOTE || \
|
||||
(option) == CURLOPT_PREQUOTE || \
|
||||
(option) == CURLOPT_PROXYHEADER || \
|
||||
(option) == CURLOPT_QUOTE || \
|
||||
(option) == CURLOPT_RESOLVE || \
|
||||
(option) == CURLOPT_TELNETOPTIONS || \
|
||||
0)
|
||||
|
||||
/* groups of curl_easy_getinfo infos that take the same type of argument */
|
||||
|
||||
/* evaluates to true if info expects a pointer to char * argument */
|
||||
#define _curl_is_string_info(info) \
|
||||
(CURLINFO_STRING < (info) && (info) < CURLINFO_LONG)
|
||||
|
||||
/* evaluates to true if info expects a pointer to long argument */
|
||||
#define _curl_is_long_info(info) \
|
||||
(CURLINFO_LONG < (info) && (info) < CURLINFO_DOUBLE)
|
||||
|
||||
/* evaluates to true if info expects a pointer to double argument */
|
||||
#define _curl_is_double_info(info) \
|
||||
(CURLINFO_DOUBLE < (info) && (info) < CURLINFO_SLIST)
|
||||
|
||||
/* true if info expects a pointer to struct curl_slist * argument */
|
||||
#define _curl_is_slist_info(info) \
|
||||
(((info) == CURLINFO_SSL_ENGINES) || ((info) == CURLINFO_COOKIELIST))
|
||||
|
||||
/* true if info expects a pointer to struct curl_tlssessioninfo * argument */
|
||||
#define _curl_is_tlssessioninfo_info(info) \
|
||||
(((info) == CURLINFO_TLS_SSL_PTR) || ((info) == CURLINFO_TLS_SESSION))
|
||||
|
||||
/* true if info expects a pointer to struct curl_certinfo * argument */
|
||||
#define _curl_is_certinfo_info(info) ((info) == CURLINFO_CERTINFO)
|
||||
|
||||
/* true if info expects a pointer to struct curl_socket_t argument */
|
||||
#define _curl_is_socket_info(info) \
|
||||
(CURLINFO_SOCKET < (info) && (info) < CURLINFO_OFF_T)
|
||||
|
||||
/* true if info expects a pointer to curl_off_t argument */
|
||||
#define _curl_is_off_t_info(info) \
|
||||
(CURLINFO_OFF_T < (info))
|
||||
|
||||
|
||||
/* typecheck helpers -- check whether given expression has requested type*/
|
||||
|
||||
/* For pointers, you can use the _curl_is_ptr/_curl_is_arr macros,
|
||||
* otherwise define a new macro. Search for __builtin_types_compatible_p
|
||||
* in the GCC manual.
|
||||
* NOTE: these macros MUST NOT EVALUATE their arguments! The argument is
|
||||
* the actual expression passed to the curl_easy_setopt macro. This
|
||||
* means that you can only apply the sizeof and __typeof__ operators, no
|
||||
* == or whatsoever.
|
||||
*/
|
||||
|
||||
/* XXX: should evaluate to true if expr is a pointer */
|
||||
#define _curl_is_any_ptr(expr) \
|
||||
(sizeof(expr) == sizeof(void *))
|
||||
|
||||
/* evaluates to true if expr is NULL */
|
||||
/* XXX: must not evaluate expr, so this check is not accurate */
|
||||
#define _curl_is_NULL(expr) \
|
||||
(__builtin_types_compatible_p(__typeof__(expr), __typeof__(NULL)))
|
||||
|
||||
/* evaluates to true if expr is type*, const type* or NULL */
|
||||
#define _curl_is_ptr(expr, type) \
|
||||
(_curl_is_NULL(expr) || \
|
||||
__builtin_types_compatible_p(__typeof__(expr), type *) || \
|
||||
__builtin_types_compatible_p(__typeof__(expr), const type *))
|
||||
|
||||
/* evaluates to true if expr is one of type[], type*, NULL or const type* */
|
||||
#define _curl_is_arr(expr, type) \
|
||||
(_curl_is_ptr((expr), type) || \
|
||||
__builtin_types_compatible_p(__typeof__(expr), type []))
|
||||
|
||||
/* evaluates to true if expr is a string */
|
||||
#define _curl_is_string(expr) \
|
||||
(_curl_is_arr((expr), char) || \
|
||||
_curl_is_arr((expr), signed char) || \
|
||||
_curl_is_arr((expr), unsigned char))
|
||||
|
||||
/* evaluates to true if expr is a long (no matter the signedness)
|
||||
* XXX: for now, int is also accepted (and therefore short and char, which
|
||||
* are promoted to int when passed to a variadic function) */
|
||||
#define _curl_is_long(expr) \
|
||||
(__builtin_types_compatible_p(__typeof__(expr), long) || \
|
||||
__builtin_types_compatible_p(__typeof__(expr), signed long) || \
|
||||
__builtin_types_compatible_p(__typeof__(expr), unsigned long) || \
|
||||
__builtin_types_compatible_p(__typeof__(expr), int) || \
|
||||
__builtin_types_compatible_p(__typeof__(expr), signed int) || \
|
||||
__builtin_types_compatible_p(__typeof__(expr), unsigned int) || \
|
||||
__builtin_types_compatible_p(__typeof__(expr), short) || \
|
||||
__builtin_types_compatible_p(__typeof__(expr), signed short) || \
|
||||
__builtin_types_compatible_p(__typeof__(expr), unsigned short) || \
|
||||
__builtin_types_compatible_p(__typeof__(expr), char) || \
|
||||
__builtin_types_compatible_p(__typeof__(expr), signed char) || \
|
||||
__builtin_types_compatible_p(__typeof__(expr), unsigned char))
|
||||
|
||||
/* evaluates to true if expr is of type curl_off_t */
|
||||
#define _curl_is_off_t(expr) \
|
||||
(__builtin_types_compatible_p(__typeof__(expr), curl_off_t))
|
||||
|
||||
/* evaluates to true if expr is abuffer suitable for CURLOPT_ERRORBUFFER */
|
||||
/* XXX: also check size of an char[] array? */
|
||||
#define _curl_is_error_buffer(expr) \
|
||||
(_curl_is_NULL(expr) || \
|
||||
__builtin_types_compatible_p(__typeof__(expr), char *) || \
|
||||
__builtin_types_compatible_p(__typeof__(expr), char[]))
|
||||
|
||||
/* evaluates to true if expr is of type (const) void* or (const) FILE* */
|
||||
#if 0
|
||||
#define _curl_is_cb_data(expr) \
|
||||
(_curl_is_ptr((expr), void) || \
|
||||
_curl_is_ptr((expr), FILE))
|
||||
#else /* be less strict */
|
||||
#define _curl_is_cb_data(expr) \
|
||||
_curl_is_any_ptr(expr)
|
||||
#endif
|
||||
|
||||
/* evaluates to true if expr is of type FILE* */
|
||||
#define _curl_is_FILE(expr) \
|
||||
(_curl_is_NULL(expr) || \
|
||||
(__builtin_types_compatible_p(__typeof__(expr), FILE *)))
|
||||
|
||||
/* evaluates to true if expr can be passed as POST data (void* or char*) */
|
||||
#define _curl_is_postfields(expr) \
|
||||
(_curl_is_ptr((expr), void) || \
|
||||
_curl_is_arr((expr), char) || \
|
||||
_curl_is_arr((expr), unsigned char))
|
||||
|
||||
/* helper: __builtin_types_compatible_p distinguishes between functions and
|
||||
* function pointers, hide it */
|
||||
#define _curl_callback_compatible(func, type) \
|
||||
(__builtin_types_compatible_p(__typeof__(func), type) || \
|
||||
__builtin_types_compatible_p(__typeof__(func) *, type))
|
||||
|
||||
/* evaluates to true if expr is of type curl_resolver_start_callback */
|
||||
#define _curl_is_resolver_start_callback(expr) \
|
||||
(_curl_is_NULL(expr) || \
|
||||
_curl_callback_compatible((expr), curl_resolver_start_callback))
|
||||
|
||||
/* evaluates to true if expr is of type curl_read_callback or "similar" */
|
||||
#define _curl_is_read_cb(expr) \
|
||||
(_curl_is_NULL(expr) || \
|
||||
_curl_callback_compatible((expr), __typeof__(fread) *) || \
|
||||
_curl_callback_compatible((expr), curl_read_callback) || \
|
||||
_curl_callback_compatible((expr), _curl_read_callback1) || \
|
||||
_curl_callback_compatible((expr), _curl_read_callback2) || \
|
||||
_curl_callback_compatible((expr), _curl_read_callback3) || \
|
||||
_curl_callback_compatible((expr), _curl_read_callback4) || \
|
||||
_curl_callback_compatible((expr), _curl_read_callback5) || \
|
||||
_curl_callback_compatible((expr), _curl_read_callback6))
|
||||
typedef size_t (*_curl_read_callback1)(char *, size_t, size_t, void *);
|
||||
typedef size_t (*_curl_read_callback2)(char *, size_t, size_t, const void *);
|
||||
typedef size_t (*_curl_read_callback3)(char *, size_t, size_t, FILE *);
|
||||
typedef size_t (*_curl_read_callback4)(void *, size_t, size_t, void *);
|
||||
typedef size_t (*_curl_read_callback5)(void *, size_t, size_t, const void *);
|
||||
typedef size_t (*_curl_read_callback6)(void *, size_t, size_t, FILE *);
|
||||
|
||||
/* evaluates to true if expr is of type curl_write_callback or "similar" */
|
||||
#define _curl_is_write_cb(expr) \
|
||||
(_curl_is_read_cb(expr) || \
|
||||
_curl_callback_compatible((expr), __typeof__(fwrite) *) || \
|
||||
_curl_callback_compatible((expr), curl_write_callback) || \
|
||||
_curl_callback_compatible((expr), _curl_write_callback1) || \
|
||||
_curl_callback_compatible((expr), _curl_write_callback2) || \
|
||||
_curl_callback_compatible((expr), _curl_write_callback3) || \
|
||||
_curl_callback_compatible((expr), _curl_write_callback4) || \
|
||||
_curl_callback_compatible((expr), _curl_write_callback5) || \
|
||||
_curl_callback_compatible((expr), _curl_write_callback6))
|
||||
typedef size_t (*_curl_write_callback1)(const char *, size_t, size_t, void *);
|
||||
typedef size_t (*_curl_write_callback2)(const char *, size_t, size_t,
|
||||
const void *);
|
||||
typedef size_t (*_curl_write_callback3)(const char *, size_t, size_t, FILE *);
|
||||
typedef size_t (*_curl_write_callback4)(const void *, size_t, size_t, void *);
|
||||
typedef size_t (*_curl_write_callback5)(const void *, size_t, size_t,
|
||||
const void *);
|
||||
typedef size_t (*_curl_write_callback6)(const void *, size_t, size_t, FILE *);
|
||||
|
||||
/* evaluates to true if expr is of type curl_ioctl_callback or "similar" */
|
||||
#define _curl_is_ioctl_cb(expr) \
|
||||
(_curl_is_NULL(expr) || \
|
||||
_curl_callback_compatible((expr), curl_ioctl_callback) || \
|
||||
_curl_callback_compatible((expr), _curl_ioctl_callback1) || \
|
||||
_curl_callback_compatible((expr), _curl_ioctl_callback2) || \
|
||||
_curl_callback_compatible((expr), _curl_ioctl_callback3) || \
|
||||
_curl_callback_compatible((expr), _curl_ioctl_callback4))
|
||||
typedef curlioerr (*_curl_ioctl_callback1)(CURL *, int, void *);
|
||||
typedef curlioerr (*_curl_ioctl_callback2)(CURL *, int, const void *);
|
||||
typedef curlioerr (*_curl_ioctl_callback3)(CURL *, curliocmd, void *);
|
||||
typedef curlioerr (*_curl_ioctl_callback4)(CURL *, curliocmd, const void *);
|
||||
|
||||
/* evaluates to true if expr is of type curl_sockopt_callback or "similar" */
|
||||
#define _curl_is_sockopt_cb(expr) \
|
||||
(_curl_is_NULL(expr) || \
|
||||
_curl_callback_compatible((expr), curl_sockopt_callback) || \
|
||||
_curl_callback_compatible((expr), _curl_sockopt_callback1) || \
|
||||
_curl_callback_compatible((expr), _curl_sockopt_callback2))
|
||||
typedef int (*_curl_sockopt_callback1)(void *, curl_socket_t, curlsocktype);
|
||||
typedef int (*_curl_sockopt_callback2)(const void *, curl_socket_t,
|
||||
curlsocktype);
|
||||
|
||||
/* evaluates to true if expr is of type curl_opensocket_callback or
|
||||
"similar" */
|
||||
#define _curl_is_opensocket_cb(expr) \
|
||||
(_curl_is_NULL(expr) || \
|
||||
_curl_callback_compatible((expr), curl_opensocket_callback) || \
|
||||
_curl_callback_compatible((expr), _curl_opensocket_callback1) || \
|
||||
_curl_callback_compatible((expr), _curl_opensocket_callback2) || \
|
||||
_curl_callback_compatible((expr), _curl_opensocket_callback3) || \
|
||||
_curl_callback_compatible((expr), _curl_opensocket_callback4))
|
||||
typedef curl_socket_t (*_curl_opensocket_callback1)
|
||||
(void *, curlsocktype, struct curl_sockaddr *);
|
||||
typedef curl_socket_t (*_curl_opensocket_callback2)
|
||||
(void *, curlsocktype, const struct curl_sockaddr *);
|
||||
typedef curl_socket_t (*_curl_opensocket_callback3)
|
||||
(const void *, curlsocktype, struct curl_sockaddr *);
|
||||
typedef curl_socket_t (*_curl_opensocket_callback4)
|
||||
(const void *, curlsocktype, const struct curl_sockaddr *);
|
||||
|
||||
/* evaluates to true if expr is of type curl_progress_callback or "similar" */
|
||||
#define _curl_is_progress_cb(expr) \
|
||||
(_curl_is_NULL(expr) || \
|
||||
_curl_callback_compatible((expr), curl_progress_callback) || \
|
||||
_curl_callback_compatible((expr), _curl_progress_callback1) || \
|
||||
_curl_callback_compatible((expr), _curl_progress_callback2))
|
||||
typedef int (*_curl_progress_callback1)(void *,
|
||||
double, double, double, double);
|
||||
typedef int (*_curl_progress_callback2)(const void *,
|
||||
double, double, double, double);
|
||||
|
||||
/* evaluates to true if expr is of type curl_debug_callback or "similar" */
|
||||
#define _curl_is_debug_cb(expr) \
|
||||
(_curl_is_NULL(expr) || \
|
||||
_curl_callback_compatible((expr), curl_debug_callback) || \
|
||||
_curl_callback_compatible((expr), _curl_debug_callback1) || \
|
||||
_curl_callback_compatible((expr), _curl_debug_callback2) || \
|
||||
_curl_callback_compatible((expr), _curl_debug_callback3) || \
|
||||
_curl_callback_compatible((expr), _curl_debug_callback4) || \
|
||||
_curl_callback_compatible((expr), _curl_debug_callback5) || \
|
||||
_curl_callback_compatible((expr), _curl_debug_callback6) || \
|
||||
_curl_callback_compatible((expr), _curl_debug_callback7) || \
|
||||
_curl_callback_compatible((expr), _curl_debug_callback8))
|
||||
typedef int (*_curl_debug_callback1) (CURL *,
|
||||
curl_infotype, char *, size_t, void *);
|
||||
typedef int (*_curl_debug_callback2) (CURL *,
|
||||
curl_infotype, char *, size_t, const void *);
|
||||
typedef int (*_curl_debug_callback3) (CURL *,
|
||||
curl_infotype, const char *, size_t, void *);
|
||||
typedef int (*_curl_debug_callback4) (CURL *,
|
||||
curl_infotype, const char *, size_t, const void *);
|
||||
typedef int (*_curl_debug_callback5) (CURL *,
|
||||
curl_infotype, unsigned char *, size_t, void *);
|
||||
typedef int (*_curl_debug_callback6) (CURL *,
|
||||
curl_infotype, unsigned char *, size_t, const void *);
|
||||
typedef int (*_curl_debug_callback7) (CURL *,
|
||||
curl_infotype, const unsigned char *, size_t, void *);
|
||||
typedef int (*_curl_debug_callback8) (CURL *,
|
||||
curl_infotype, const unsigned char *, size_t, const void *);
|
||||
|
||||
/* evaluates to true if expr is of type curl_ssl_ctx_callback or "similar" */
|
||||
/* this is getting even messier... */
|
||||
#define _curl_is_ssl_ctx_cb(expr) \
|
||||
(_curl_is_NULL(expr) || \
|
||||
_curl_callback_compatible((expr), curl_ssl_ctx_callback) || \
|
||||
_curl_callback_compatible((expr), _curl_ssl_ctx_callback1) || \
|
||||
_curl_callback_compatible((expr), _curl_ssl_ctx_callback2) || \
|
||||
_curl_callback_compatible((expr), _curl_ssl_ctx_callback3) || \
|
||||
_curl_callback_compatible((expr), _curl_ssl_ctx_callback4) || \
|
||||
_curl_callback_compatible((expr), _curl_ssl_ctx_callback5) || \
|
||||
_curl_callback_compatible((expr), _curl_ssl_ctx_callback6) || \
|
||||
_curl_callback_compatible((expr), _curl_ssl_ctx_callback7) || \
|
||||
_curl_callback_compatible((expr), _curl_ssl_ctx_callback8))
|
||||
typedef CURLcode (*_curl_ssl_ctx_callback1)(CURL *, void *, void *);
|
||||
typedef CURLcode (*_curl_ssl_ctx_callback2)(CURL *, void *, const void *);
|
||||
typedef CURLcode (*_curl_ssl_ctx_callback3)(CURL *, const void *, void *);
|
||||
typedef CURLcode (*_curl_ssl_ctx_callback4)(CURL *, const void *,
|
||||
const void *);
|
||||
#ifdef HEADER_SSL_H
|
||||
/* hack: if we included OpenSSL's ssl.h, we know about SSL_CTX
|
||||
* this will of course break if we're included before OpenSSL headers...
|
||||
*/
|
||||
typedef CURLcode (*_curl_ssl_ctx_callback5)(CURL *, SSL_CTX, void *);
|
||||
typedef CURLcode (*_curl_ssl_ctx_callback6)(CURL *, SSL_CTX, const void *);
|
||||
typedef CURLcode (*_curl_ssl_ctx_callback7)(CURL *, const SSL_CTX, void *);
|
||||
typedef CURLcode (*_curl_ssl_ctx_callback8)(CURL *, const SSL_CTX,
|
||||
const void *);
|
||||
#else
|
||||
typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback5;
|
||||
typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback6;
|
||||
typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback7;
|
||||
typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback8;
|
||||
#endif
|
||||
|
||||
/* evaluates to true if expr is of type curl_conv_callback or "similar" */
|
||||
#define _curl_is_conv_cb(expr) \
|
||||
(_curl_is_NULL(expr) || \
|
||||
_curl_callback_compatible((expr), curl_conv_callback) || \
|
||||
_curl_callback_compatible((expr), _curl_conv_callback1) || \
|
||||
_curl_callback_compatible((expr), _curl_conv_callback2) || \
|
||||
_curl_callback_compatible((expr), _curl_conv_callback3) || \
|
||||
_curl_callback_compatible((expr), _curl_conv_callback4))
|
||||
typedef CURLcode (*_curl_conv_callback1)(char *, size_t length);
|
||||
typedef CURLcode (*_curl_conv_callback2)(const char *, size_t length);
|
||||
typedef CURLcode (*_curl_conv_callback3)(void *, size_t length);
|
||||
typedef CURLcode (*_curl_conv_callback4)(const void *, size_t length);
|
||||
|
||||
/* evaluates to true if expr is of type curl_seek_callback or "similar" */
|
||||
#define _curl_is_seek_cb(expr) \
|
||||
(_curl_is_NULL(expr) || \
|
||||
_curl_callback_compatible((expr), curl_seek_callback) || \
|
||||
_curl_callback_compatible((expr), _curl_seek_callback1) || \
|
||||
_curl_callback_compatible((expr), _curl_seek_callback2))
|
||||
typedef CURLcode (*_curl_seek_callback1)(void *, curl_off_t, int);
|
||||
typedef CURLcode (*_curl_seek_callback2)(const void *, curl_off_t, int);
|
||||
|
||||
|
||||
#endif /* __CURL_TYPECHECK_GCC_H */
|
123
src/dependencies/cmcurl/include/curl/urlapi.h
Normal file
123
src/dependencies/cmcurl/include/curl/urlapi.h
Normal file
|
@ -0,0 +1,123 @@
|
|||
#ifndef __CURL_URLAPI_H
|
||||
#define __CURL_URLAPI_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2018 - 2019, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* the error codes for the URL API */
|
||||
typedef enum {
|
||||
CURLUE_OK,
|
||||
CURLUE_BAD_HANDLE, /* 1 */
|
||||
CURLUE_BAD_PARTPOINTER, /* 2 */
|
||||
CURLUE_MALFORMED_INPUT, /* 3 */
|
||||
CURLUE_BAD_PORT_NUMBER, /* 4 */
|
||||
CURLUE_UNSUPPORTED_SCHEME, /* 5 */
|
||||
CURLUE_URLDECODE, /* 6 */
|
||||
CURLUE_OUT_OF_MEMORY, /* 7 */
|
||||
CURLUE_USER_NOT_ALLOWED, /* 8 */
|
||||
CURLUE_UNKNOWN_PART, /* 9 */
|
||||
CURLUE_NO_SCHEME, /* 10 */
|
||||
CURLUE_NO_USER, /* 11 */
|
||||
CURLUE_NO_PASSWORD, /* 12 */
|
||||
CURLUE_NO_OPTIONS, /* 13 */
|
||||
CURLUE_NO_HOST, /* 14 */
|
||||
CURLUE_NO_PORT, /* 15 */
|
||||
CURLUE_NO_QUERY, /* 16 */
|
||||
CURLUE_NO_FRAGMENT /* 17 */
|
||||
} CURLUcode;
|
||||
|
||||
typedef enum {
|
||||
CURLUPART_URL,
|
||||
CURLUPART_SCHEME,
|
||||
CURLUPART_USER,
|
||||
CURLUPART_PASSWORD,
|
||||
CURLUPART_OPTIONS,
|
||||
CURLUPART_HOST,
|
||||
CURLUPART_PORT,
|
||||
CURLUPART_PATH,
|
||||
CURLUPART_QUERY,
|
||||
CURLUPART_FRAGMENT,
|
||||
CURLUPART_ZONEID /* added in 7.65.0 */
|
||||
} CURLUPart;
|
||||
|
||||
#define CURLU_DEFAULT_PORT (1<<0) /* return default port number */
|
||||
#define CURLU_NO_DEFAULT_PORT (1<<1) /* act as if no port number was set,
|
||||
if the port number matches the
|
||||
default for the scheme */
|
||||
#define CURLU_DEFAULT_SCHEME (1<<2) /* return default scheme if
|
||||
missing */
|
||||
#define CURLU_NON_SUPPORT_SCHEME (1<<3) /* allow non-supported scheme */
|
||||
#define CURLU_PATH_AS_IS (1<<4) /* leave dot sequences */
|
||||
#define CURLU_DISALLOW_USER (1<<5) /* no user+password allowed */
|
||||
#define CURLU_URLDECODE (1<<6) /* URL decode on get */
|
||||
#define CURLU_URLENCODE (1<<7) /* URL encode on set */
|
||||
#define CURLU_APPENDQUERY (1<<8) /* append a form style part */
|
||||
#define CURLU_GUESS_SCHEME (1<<9) /* legacy curl-style guessing */
|
||||
|
||||
typedef struct Curl_URL CURLU;
|
||||
|
||||
/*
|
||||
* curl_url() creates a new CURLU handle and returns a pointer to it.
|
||||
* Must be freed with curl_url_cleanup().
|
||||
*/
|
||||
CURL_EXTERN CURLU *curl_url(void);
|
||||
|
||||
/*
|
||||
* curl_url_cleanup() frees the CURLU handle and related resources used for
|
||||
* the URL parsing. It will not free strings previously returned with the URL
|
||||
* API.
|
||||
*/
|
||||
CURL_EXTERN void curl_url_cleanup(CURLU *handle);
|
||||
|
||||
/*
|
||||
* curl_url_dup() duplicates a CURLU handle and returns a new copy. The new
|
||||
* handle must also be freed with curl_url_cleanup().
|
||||
*/
|
||||
CURL_EXTERN CURLU *curl_url_dup(CURLU *in);
|
||||
|
||||
/*
|
||||
* curl_url_get() extracts a specific part of the URL from a CURLU
|
||||
* handle. Returns error code. The returned pointer MUST be freed with
|
||||
* curl_free() afterwards.
|
||||
*/
|
||||
CURL_EXTERN CURLUcode curl_url_get(CURLU *handle, CURLUPart what,
|
||||
char **part, unsigned int flags);
|
||||
|
||||
/*
|
||||
* curl_url_set() sets a specific part of the URL in a CURLU handle. Returns
|
||||
* error code. The passed in string will be copied. Passing a NULL instead of
|
||||
* a part string, clears that part.
|
||||
*/
|
||||
CURL_EXTERN CURLUcode curl_url_set(CURLU *handle, CURLUPart what,
|
||||
const char *part, unsigned int flags);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* end of extern "C" */
|
||||
#endif
|
||||
|
||||
#endif
|
147
src/dependencies/cmcurl/lib/CMakeLists.txt
Normal file
147
src/dependencies/cmcurl/lib/CMakeLists.txt
Normal file
|
@ -0,0 +1,147 @@
|
|||
set(LIB_NAME cmcurl)
|
||||
|
||||
if(BUILD_SHARED_LIBS)
|
||||
set(CURL_STATICLIB NO)
|
||||
else()
|
||||
set(CURL_STATICLIB YES)
|
||||
endif()
|
||||
|
||||
# Use:
|
||||
# * CURL_STATICLIB
|
||||
configure_file(curl_config.h.cmake
|
||||
${CMAKE_CURRENT_BINARY_DIR}/curl_config.h)
|
||||
|
||||
transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake")
|
||||
include(${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake)
|
||||
|
||||
list(APPEND HHEADERS
|
||||
${CMAKE_CURRENT_BINARY_DIR}/curl_config.h
|
||||
)
|
||||
|
||||
if(MSVC AND NOT CURL_STATICLIB)
|
||||
list(APPEND CSOURCES libcurl.rc)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4127")
|
||||
endif()
|
||||
|
||||
# SET(CSOURCES
|
||||
# # memdebug.c -not used
|
||||
# # nwlib.c - Not used
|
||||
# # strtok.c - specify later
|
||||
# # strtoofft.c - specify later
|
||||
# )
|
||||
|
||||
# # if we have Kerberos 4, right now this is never on
|
||||
# #OPTION(CURL_KRB4 "Use Kerberos 4" OFF)
|
||||
# IF(CURL_KRB4)
|
||||
# SET(CSOURCES ${CSOURCES}
|
||||
# krb4.c
|
||||
# security.c
|
||||
# )
|
||||
# ENDIF(CURL_KRB4)
|
||||
|
||||
# #OPTION(CURL_MALLOC_DEBUG "Debug mallocs in Curl" OFF)
|
||||
# MARK_AS_ADVANCED(CURL_MALLOC_DEBUG)
|
||||
# IF(CURL_MALLOC_DEBUG)
|
||||
# SET(CSOURCES ${CSOURCES}
|
||||
# memdebug.c
|
||||
# )
|
||||
# ENDIF(CURL_MALLOC_DEBUG)
|
||||
|
||||
# # only build compat strtoofft if we need to
|
||||
# IF(NOT HAVE_STRTOLL AND NOT HAVE__STRTOI64)
|
||||
# SET(CSOURCES ${CSOURCES}
|
||||
# strtoofft.c
|
||||
# )
|
||||
# ENDIF(NOT HAVE_STRTOLL AND NOT HAVE__STRTOI64)
|
||||
|
||||
|
||||
# The rest of the build
|
||||
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR}/../include)
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..)
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../include)
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR}/..)
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||
if(USE_ARES)
|
||||
include_directories(${CARES_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
# For windows we want to install OPENSSL_LIBRARIES dlls
|
||||
# and also copy them into the build tree so that testing
|
||||
# can find them.
|
||||
if(CMAKE_USE_OPENSSL AND OPENSSL_FOUND AND WIN32)
|
||||
find_file(CMAKE_EAY_DLL NAME libeay32.dll HINTS ${OPENSSL_INCLUDE_DIR}/..)
|
||||
find_file(CMAKE_SSL_DLL NAME ssleay32.dll HINTS ${OPENSSL_INCLUDE_DIR}/..)
|
||||
mark_as_advanced(CMAKE_EAY_DLL CMAKE_SSL_DLL)
|
||||
if(CMAKE_SSL_DLL AND CMAKE_EAY_DLL)
|
||||
set(CMAKE_CURL_SSL_DLLS ${CMake_BIN_DIR}/${CMAKE_CFG_INTDIR}/libeay32.dll
|
||||
${CMake_BIN_DIR}/${CMAKE_CFG_INTDIR}/ssleay32.dll)
|
||||
add_custom_command(OUTPUT
|
||||
${CMake_BIN_DIR}/${CMAKE_CFG_INTDIR}/libeay32.dll
|
||||
DEPENDS ${CMAKE_EAY_DLL}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_EAY_DLL}
|
||||
${CMake_BIN_DIR}/${CMAKE_CFG_INTDIR}/libeay32.dll)
|
||||
add_custom_command(OUTPUT
|
||||
${CMake_BIN_DIR}/${CMAKE_CFG_INTDIR}/ssleay32.dll
|
||||
DEPENDS ${CMAKE_SSL_DLL}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SSL_DLL}
|
||||
${CMake_BIN_DIR}/${CMAKE_CFG_INTDIR}/ssleay32.dll)
|
||||
install(PROGRAMS ${CMAKE_EAY_DLL} ${CMAKE_SSL_DLL} DESTINATION bin)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_library(
|
||||
${LIB_NAME}
|
||||
${HHEADERS} ${CSOURCES}
|
||||
${CMAKE_CURL_SSL_DLLS}
|
||||
)
|
||||
|
||||
if(NOT BUILD_SHARED_LIBS)
|
||||
set_target_properties(${LIB_NAME} PROPERTIES INTERFACE_COMPILE_DEFINITIONS CURL_STATICLIB)
|
||||
endif()
|
||||
|
||||
target_link_libraries(${LIB_NAME} ${CURL_LIBS})
|
||||
|
||||
if(0) # This code not needed for building within CMake.
|
||||
if(WIN32)
|
||||
add_definitions(-D_USRDLL)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set_target_properties(${LIB_NAME} PROPERTIES COMPILE_DEFINITIONS BUILDING_LIBCURL)
|
||||
|
||||
if(0) # This code not needed for building within CMake.
|
||||
if(HIDES_CURL_PRIVATE_SYMBOLS)
|
||||
set_property(TARGET ${LIB_NAME} APPEND PROPERTY COMPILE_DEFINITIONS "CURL_HIDDEN_SYMBOLS")
|
||||
set_property(TARGET ${LIB_NAME} APPEND PROPERTY COMPILE_FLAGS ${CURL_CFLAG_SYMBOLS_HIDE})
|
||||
endif()
|
||||
|
||||
# Remove the "lib" prefix since the library is already named "libcurl".
|
||||
set_target_properties(${LIB_NAME} PROPERTIES PREFIX "")
|
||||
set_target_properties(${LIB_NAME} PROPERTIES IMPORT_PREFIX "")
|
||||
|
||||
if(WIN32)
|
||||
if(BUILD_SHARED_LIBS)
|
||||
# Add "_imp" as a suffix before the extension to avoid conflicting with the statically linked "libcurl.lib"
|
||||
set_target_properties(${LIB_NAME} PROPERTIES IMPORT_SUFFIX "_imp.lib")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
target_include_directories(${LIB_NAME} INTERFACE
|
||||
$<INSTALL_INTERFACE:include>
|
||||
$<BUILD_INTERFACE:${CURL_SOURCE_DIR}/include>)
|
||||
|
||||
install(TARGETS ${LIB_NAME}
|
||||
EXPORT ${TARGETS_EXPORT_NAME}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
)
|
||||
|
||||
export(TARGETS ${LIB_NAME}
|
||||
APPEND FILE ${PROJECT_BINARY_DIR}/libcurl-target.cmake
|
||||
NAMESPACE CURL::
|
||||
)
|
||||
|
||||
endif()
|
84
src/dependencies/cmcurl/lib/Makefile.inc
Normal file
84
src/dependencies/cmcurl/lib/Makefile.inc
Normal file
|
@ -0,0 +1,84 @@
|
|||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2019, 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.haxx.se/docs/copyright.html.
|
||||
#
|
||||
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
# copies of the Software, and permit persons to whom the Software is
|
||||
# furnished to do so, under the terms of the COPYING file.
|
||||
#
|
||||
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
# KIND, either express or implied.
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
LIB_VAUTH_CFILES = vauth/vauth.c vauth/cleartext.c vauth/cram.c \
|
||||
vauth/digest.c vauth/digest_sspi.c vauth/krb5_gssapi.c \
|
||||
vauth/krb5_sspi.c vauth/ntlm.c vauth/ntlm_sspi.c vauth/oauth2.c \
|
||||
vauth/spnego_gssapi.c vauth/spnego_sspi.c
|
||||
|
||||
LIB_VAUTH_HFILES = vauth/vauth.h vauth/digest.h vauth/ntlm.h
|
||||
|
||||
LIB_VTLS_CFILES = vtls/openssl.c vtls/gtls.c vtls/vtls.c vtls/nss.c \
|
||||
vtls/polarssl.c vtls/polarssl_threadlock.c \
|
||||
vtls/cyassl.c vtls/schannel.c vtls/schannel_verify.c \
|
||||
vtls/sectransp.c vtls/gskit.c vtls/mbedtls.c vtls/mesalink.c
|
||||
|
||||
LIB_VTLS_HFILES = vtls/openssl.h vtls/vtls.h vtls/gtls.h \
|
||||
vtls/nssg.h vtls/polarssl.h vtls/polarssl_threadlock.h \
|
||||
vtls/cyassl.h vtls/schannel.h vtls/sectransp.h vtls/gskit.h \
|
||||
vtls/mbedtls.h vtls/mesalink.h
|
||||
|
||||
LIB_CFILES = file.c timeval.c base64.c hostip.c progress.c formdata.c \
|
||||
cookie.c http.c sendf.c ftp.c url.c dict.c if2ip.c speedcheck.c \
|
||||
ldap.c version.c getenv.c escape.c mprintf.c telnet.c netrc.c \
|
||||
getinfo.c transfer.c strcase.c easy.c security.c curl_fnmatch.c \
|
||||
fileinfo.c ftplistparser.c wildcard.c krb5.c memdebug.c http_chunks.c \
|
||||
strtok.c connect.c llist.c hash.c multi.c content_encoding.c share.c \
|
||||
http_digest.c md4.c md5.c http_negotiate.c inet_pton.c strtoofft.c \
|
||||
strerror.c amigaos.c hostasyn.c hostip4.c hostip6.c hostsyn.c \
|
||||
inet_ntop.c parsedate.c select.c tftp.c splay.c strdup.c socks.c \
|
||||
ssh.c ssh-libssh.c curl_addrinfo.c socks_gssapi.c socks_sspi.c \
|
||||
curl_sspi.c slist.c nonblock.c curl_memrchr.c imap.c pop3.c smtp.c \
|
||||
pingpong.c rtsp.c curl_threads.c warnless.c hmac.c curl_rtmp.c \
|
||||
openldap.c curl_gethostname.c gopher.c idn_win32.c \
|
||||
http_proxy.c non-ascii.c asyn-ares.c asyn-thread.c curl_gssapi.c \
|
||||
http_ntlm.c curl_ntlm_wb.c curl_ntlm_core.c curl_sasl.c rand.c \
|
||||
curl_multibyte.c hostcheck.c conncache.c dotdot.c \
|
||||
x509asn1.c http2.c smb.c curl_endian.c curl_des.c system_win32.c \
|
||||
mime.c sha256.c setopt.c curl_path.c curl_ctype.c curl_range.c psl.c \
|
||||
doh.c urlapi.c curl_get_line.c altsvc.c
|
||||
|
||||
LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h \
|
||||
formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h if2ip.h \
|
||||
speedcheck.h urldata.h curl_ldap.h escape.h telnet.h getinfo.h \
|
||||
strcase.h curl_sec.h memdebug.h http_chunks.h curl_fnmatch.h \
|
||||
wildcard.h fileinfo.h ftplistparser.h strtok.h connect.h llist.h \
|
||||
hash.h content_encoding.h share.h curl_md4.h curl_md5.h http_digest.h \
|
||||
http_negotiate.h inet_pton.h amigaos.h strtoofft.h strerror.h \
|
||||
inet_ntop.h curlx.h curl_memory.h curl_setup.h transfer.h select.h \
|
||||
easyif.h multiif.h parsedate.h tftp.h sockaddr.h splay.h strdup.h \
|
||||
socks.h ssh.h curl_base64.h curl_addrinfo.h curl_sspi.h \
|
||||
slist.h nonblock.h curl_memrchr.h imap.h pop3.h smtp.h pingpong.h \
|
||||
rtsp.h curl_threads.h warnless.h curl_hmac.h curl_rtmp.h \
|
||||
curl_gethostname.h gopher.h http_proxy.h non-ascii.h asyn.h \
|
||||
http_ntlm.h curl_gssapi.h curl_ntlm_wb.h curl_ntlm_core.h \
|
||||
curl_sasl.h curl_multibyte.h hostcheck.h conncache.h \
|
||||
curl_setup_once.h multihandle.h setup-vms.h dotdot.h \
|
||||
x509asn1.h http2.h sigpipe.h smb.h curl_endian.h curl_des.h \
|
||||
curl_printf.h system_win32.h rand.h mime.h curl_sha256.h setopt.h \
|
||||
curl_path.h curl_ctype.h curl_range.h psl.h doh.h urlapi-int.h \
|
||||
curl_get_line.h altsvc.h
|
||||
|
||||
LIB_RCFILES = libcurl.rc
|
||||
|
||||
CSOURCES = $(LIB_CFILES) $(LIB_VAUTH_CFILES) $(LIB_VTLS_CFILES)
|
||||
HHEADERS = $(LIB_HFILES) $(LIB_VAUTH_HFILES) $(LIB_VTLS_HFILES)
|
569
src/dependencies/cmcurl/lib/altsvc.c
Normal file
569
src/dependencies/cmcurl/lib/altsvc.c
Normal file
|
@ -0,0 +1,569 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2019, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
/*
|
||||
* The Alt-Svc: header is defined in RFC 7838:
|
||||
* https://tools.ietf.org/html/rfc7838
|
||||
*/
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if !defined(CURL_DISABLE_HTTP) && defined(USE_ALTSVC)
|
||||
#include <curl/curl.h>
|
||||
#include "urldata.h"
|
||||
#include "altsvc.h"
|
||||
#include "curl_get_line.h"
|
||||
#include "strcase.h"
|
||||
#include "parsedate.h"
|
||||
#include "sendf.h"
|
||||
#include "warnless.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#define MAX_ALTSVC_LINE 4095
|
||||
#define MAX_ALTSVC_DATELENSTR "64"
|
||||
#define MAX_ALTSVC_DATELEN 64
|
||||
#define MAX_ALTSVC_HOSTLENSTR "512"
|
||||
#define MAX_ALTSVC_HOSTLEN 512
|
||||
#define MAX_ALTSVC_ALPNLENSTR "10"
|
||||
#define MAX_ALTSVC_ALPNLEN 10
|
||||
|
||||
static enum alpnid alpn2alpnid(char *name)
|
||||
{
|
||||
if(strcasecompare(name, "h1"))
|
||||
return ALPN_h1;
|
||||
if(strcasecompare(name, "h2"))
|
||||
return ALPN_h2;
|
||||
if(strcasecompare(name, "h2c"))
|
||||
return ALPN_h2c;
|
||||
if(strcasecompare(name, "h3"))
|
||||
return ALPN_h3;
|
||||
return ALPN_none; /* unknown, probably rubbish input */
|
||||
}
|
||||
|
||||
/* Given the ALPN ID, return the name */
|
||||
const char *Curl_alpnid2str(enum alpnid id)
|
||||
{
|
||||
switch(id) {
|
||||
case ALPN_h1:
|
||||
return "h1";
|
||||
case ALPN_h2:
|
||||
return "h2";
|
||||
case ALPN_h2c:
|
||||
return "h2c";
|
||||
case ALPN_h3:
|
||||
return "h3";
|
||||
default:
|
||||
return ""; /* bad */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void altsvc_free(struct altsvc *as)
|
||||
{
|
||||
free(as->srchost);
|
||||
free(as->dsthost);
|
||||
free(as);
|
||||
}
|
||||
|
||||
static struct altsvc *altsvc_createid(const char *srchost,
|
||||
const char *dsthost,
|
||||
enum alpnid srcalpnid,
|
||||
enum alpnid dstalpnid,
|
||||
unsigned int srcport,
|
||||
unsigned int dstport)
|
||||
{
|
||||
struct altsvc *as = calloc(sizeof(struct altsvc), 1);
|
||||
if(!as)
|
||||
return NULL;
|
||||
|
||||
as->srchost = strdup(srchost);
|
||||
if(!as->srchost)
|
||||
goto error;
|
||||
as->dsthost = strdup(dsthost);
|
||||
if(!as->dsthost)
|
||||
goto error;
|
||||
|
||||
as->srcalpnid = srcalpnid;
|
||||
as->dstalpnid = dstalpnid;
|
||||
as->srcport = curlx_ultous(srcport);
|
||||
as->dstport = curlx_ultous(dstport);
|
||||
|
||||
return as;
|
||||
error:
|
||||
altsvc_free(as);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct altsvc *altsvc_create(char *srchost,
|
||||
char *dsthost,
|
||||
char *srcalpn,
|
||||
char *dstalpn,
|
||||
unsigned int srcport,
|
||||
unsigned int dstport)
|
||||
{
|
||||
enum alpnid dstalpnid = alpn2alpnid(dstalpn);
|
||||
enum alpnid srcalpnid = alpn2alpnid(srcalpn);
|
||||
if(!srcalpnid || !dstalpnid)
|
||||
return NULL;
|
||||
return altsvc_createid(srchost, dsthost, srcalpnid, dstalpnid,
|
||||
srcport, dstport);
|
||||
}
|
||||
|
||||
/* only returns SERIOUS errors */
|
||||
static CURLcode altsvc_add(struct altsvcinfo *asi, char *line)
|
||||
{
|
||||
/* Example line:
|
||||
h2 example.com 443 h3 shiny.example.com 8443 "20191231 10:00:00" 1
|
||||
*/
|
||||
char srchost[MAX_ALTSVC_HOSTLEN + 1];
|
||||
char dsthost[MAX_ALTSVC_HOSTLEN + 1];
|
||||
char srcalpn[MAX_ALTSVC_ALPNLEN + 1];
|
||||
char dstalpn[MAX_ALTSVC_ALPNLEN + 1];
|
||||
char date[MAX_ALTSVC_DATELEN + 1];
|
||||
unsigned int srcport;
|
||||
unsigned int dstport;
|
||||
unsigned int prio;
|
||||
unsigned int persist;
|
||||
int rc;
|
||||
|
||||
rc = sscanf(line,
|
||||
"%" MAX_ALTSVC_ALPNLENSTR "s %" MAX_ALTSVC_HOSTLENSTR "s %u "
|
||||
"%" MAX_ALTSVC_ALPNLENSTR "s %" MAX_ALTSVC_HOSTLENSTR "s %u "
|
||||
"\"%" MAX_ALTSVC_DATELENSTR "[^\"]\" %u %u",
|
||||
srcalpn, srchost, &srcport,
|
||||
dstalpn, dsthost, &dstport,
|
||||
date, &persist, &prio);
|
||||
if(9 == rc) {
|
||||
struct altsvc *as;
|
||||
time_t expires = curl_getdate(date, NULL);
|
||||
as = altsvc_create(srchost, dsthost, srcalpn, dstalpn, srcport, dstport);
|
||||
if(as) {
|
||||
as->expires = expires;
|
||||
as->prio = prio;
|
||||
as->persist = persist ? 1 : 0;
|
||||
Curl_llist_insert_next(&asi->list, asi->list.tail, as, &as->node);
|
||||
asi->num++; /* one more entry */
|
||||
}
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Load alt-svc entries from the given file. The text based line-oriented file
|
||||
* format is documented here:
|
||||
* https://github.com/curl/curl/wiki/QUIC-implementation
|
||||
*
|
||||
* This function only returns error on major problems that prevents alt-svc
|
||||
* handling to work completely. It will ignore individual syntactical errors
|
||||
* etc.
|
||||
*/
|
||||
static CURLcode altsvc_load(struct altsvcinfo *asi, const char *file)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
char *line = NULL;
|
||||
FILE *fp = fopen(file, FOPEN_READTEXT);
|
||||
if(fp) {
|
||||
line = malloc(MAX_ALTSVC_LINE);
|
||||
if(!line)
|
||||
goto fail;
|
||||
while(Curl_get_line(line, MAX_ALTSVC_LINE, fp)) {
|
||||
char *lineptr = line;
|
||||
while(*lineptr && ISBLANK(*lineptr))
|
||||
lineptr++;
|
||||
if(*lineptr == '#')
|
||||
/* skip commented lines */
|
||||
continue;
|
||||
|
||||
altsvc_add(asi, lineptr);
|
||||
}
|
||||
free(line); /* free the line buffer */
|
||||
fclose(fp);
|
||||
}
|
||||
return result;
|
||||
|
||||
fail:
|
||||
free(line);
|
||||
fclose(fp);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write this single altsvc entry to a single output line
|
||||
*/
|
||||
|
||||
static CURLcode altsvc_out(struct altsvc *as, FILE *fp)
|
||||
{
|
||||
struct tm stamp;
|
||||
CURLcode result = Curl_gmtime(as->expires, &stamp);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
fprintf(fp,
|
||||
"%s %s %u "
|
||||
"%s %s %u "
|
||||
"\"%d%02d%02d "
|
||||
"%02d:%02d:%02d\" "
|
||||
"%u %d\n",
|
||||
Curl_alpnid2str(as->srcalpnid), as->srchost, as->srcport,
|
||||
Curl_alpnid2str(as->dstalpnid), as->dsthost, as->dstport,
|
||||
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;
|
||||
}
|
||||
|
||||
/* ---- library-wide functions below ---- */
|
||||
|
||||
/*
|
||||
* Curl_altsvc_init() creates a new altsvc cache.
|
||||
* It returns the new instance or NULL if something goes wrong.
|
||||
*/
|
||||
struct altsvcinfo *Curl_altsvc_init(void)
|
||||
{
|
||||
struct altsvcinfo *asi = calloc(sizeof(struct altsvcinfo), 1);
|
||||
if(!asi)
|
||||
return NULL;
|
||||
Curl_llist_init(&asi->list, NULL);
|
||||
|
||||
/* set default behavior */
|
||||
asi->flags = CURLALTSVC_H1
|
||||
#ifdef USE_NGHTTP2
|
||||
| CURLALTSVC_H2
|
||||
#endif
|
||||
#ifdef USE_HTTP3
|
||||
| CURLALTSVC_H3
|
||||
#endif
|
||||
;
|
||||
return asi;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_altsvc_load() loads alt-svc from file.
|
||||
*/
|
||||
CURLcode Curl_altsvc_load(struct altsvcinfo *asi, const char *file)
|
||||
{
|
||||
CURLcode result;
|
||||
DEBUGASSERT(asi);
|
||||
result = altsvc_load(asi, file);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_altsvc_ctrl() passes on the external bitmask.
|
||||
*/
|
||||
CURLcode Curl_altsvc_ctrl(struct altsvcinfo *asi, const long ctrl)
|
||||
{
|
||||
DEBUGASSERT(asi);
|
||||
if(!ctrl)
|
||||
/* unexpected */
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
asi->flags = ctrl;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_altsvc_cleanup() frees an altsvc cache instance and all associated
|
||||
* resources.
|
||||
*/
|
||||
void Curl_altsvc_cleanup(struct altsvcinfo *altsvc)
|
||||
{
|
||||
struct curl_llist_element *e;
|
||||
struct curl_llist_element *n;
|
||||
if(altsvc) {
|
||||
for(e = altsvc->list.head; e; e = n) {
|
||||
struct altsvc *as = e->ptr;
|
||||
n = e->next;
|
||||
altsvc_free(as);
|
||||
}
|
||||
free(altsvc);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_altsvc_save() writes the altsvc cache to a file.
|
||||
*/
|
||||
CURLcode Curl_altsvc_save(struct altsvcinfo *altsvc, const char *file)
|
||||
{
|
||||
struct curl_llist_element *e;
|
||||
struct curl_llist_element *n;
|
||||
CURLcode result = CURLE_OK;
|
||||
FILE *out;
|
||||
|
||||
if(!altsvc)
|
||||
/* no cache activated */
|
||||
return CURLE_OK;
|
||||
|
||||
if((altsvc->flags & CURLALTSVC_READONLYFILE) || !file[0])
|
||||
/* marked as read-only or zero length file name */
|
||||
return CURLE_OK;
|
||||
out = fopen(file, FOPEN_WRITETEXT);
|
||||
if(!out)
|
||||
return CURLE_WRITE_ERROR;
|
||||
fputs("# Your alt-svc cache. https://curl.haxx.se/docs/alt-svc.html\n"
|
||||
"# This file was generated by libcurl! Edit at your own risk.\n",
|
||||
out);
|
||||
for(e = altsvc->list.head; e; e = n) {
|
||||
struct altsvc *as = e->ptr;
|
||||
n = e->next;
|
||||
result = altsvc_out(as, out);
|
||||
if(result)
|
||||
break;
|
||||
}
|
||||
fclose(out);
|
||||
return result;
|
||||
}
|
||||
|
||||
static CURLcode getalnum(const char **ptr, char *alpnbuf, size_t buflen)
|
||||
{
|
||||
size_t len;
|
||||
const char *protop;
|
||||
const char *p = *ptr;
|
||||
while(*p && ISBLANK(*p))
|
||||
p++;
|
||||
protop = p;
|
||||
while(*p && ISALNUM(*p))
|
||||
p++;
|
||||
len = p - protop;
|
||||
|
||||
if(!len || (len >= buflen))
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
memcpy(alpnbuf, protop, len);
|
||||
alpnbuf[len] = 0;
|
||||
*ptr = p;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/* altsvc_flush() removes all alternatives for this source origin from the
|
||||
list */
|
||||
static void altsvc_flush(struct altsvcinfo *asi, enum alpnid srcalpnid,
|
||||
const char *srchost, unsigned short srcport)
|
||||
{
|
||||
struct curl_llist_element *e;
|
||||
struct curl_llist_element *n;
|
||||
for(e = asi->list.head; e; e = n) {
|
||||
struct altsvc *as = e->ptr;
|
||||
n = e->next;
|
||||
if((srcalpnid == as->srcalpnid) &&
|
||||
(srcport == as->srcport) &&
|
||||
strcasecompare(srchost, as->srchost)) {
|
||||
Curl_llist_remove(&asi->list, e, NULL);
|
||||
altsvc_free(as);
|
||||
asi->num--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
/* to play well with debug builds, we can *set* a fixed time this will
|
||||
return */
|
||||
static time_t debugtime(void *unused)
|
||||
{
|
||||
char *timestr = getenv("CURL_TIME");
|
||||
(void)unused;
|
||||
if(timestr) {
|
||||
unsigned long val = strtol(timestr, NULL, 10);
|
||||
return (time_t)val;
|
||||
}
|
||||
return time(NULL);
|
||||
}
|
||||
#define time(x) debugtime(x)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Curl_altsvc_parse() takes an incoming alt-svc response header and stores
|
||||
* the data correctly in the cache.
|
||||
*
|
||||
* 'value' points to the header *value*. That's contents to the right of the
|
||||
* header name.
|
||||
*/
|
||||
CURLcode Curl_altsvc_parse(struct Curl_easy *data,
|
||||
struct altsvcinfo *asi, const char *value,
|
||||
enum alpnid srcalpnid, const char *srchost,
|
||||
unsigned short srcport)
|
||||
{
|
||||
const char *p = value;
|
||||
size_t len;
|
||||
enum alpnid dstalpnid = srcalpnid; /* the same by default */
|
||||
char namebuf[MAX_ALTSVC_HOSTLEN] = "";
|
||||
char alpnbuf[MAX_ALTSVC_ALPNLEN] = "";
|
||||
struct altsvc *as;
|
||||
unsigned short dstport = srcport; /* the same by default */
|
||||
const char *semip;
|
||||
time_t maxage = 24 * 3600; /* default is 24 hours */
|
||||
bool persist = FALSE;
|
||||
CURLcode result = getalnum(&p, alpnbuf, sizeof(alpnbuf));
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
DEBUGASSERT(asi);
|
||||
|
||||
/* Flush all cached alternatives for this source origin, if any */
|
||||
altsvc_flush(asi, srcalpnid, srchost, srcport);
|
||||
|
||||
/* "clear" is a magic keyword */
|
||||
if(strcasecompare(alpnbuf, "clear")) {
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/* The 'ma' and 'persist' flags are annoyingly meant for all alternatives
|
||||
but are set after the list on the line. Scan for the semicolons and get
|
||||
those fields first! */
|
||||
semip = p;
|
||||
do {
|
||||
semip = strchr(semip, ';');
|
||||
if(semip) {
|
||||
char option[32];
|
||||
unsigned long num;
|
||||
char *end_ptr;
|
||||
semip++; /* pass the semicolon */
|
||||
result = getalnum(&semip, option, sizeof(option));
|
||||
if(result)
|
||||
break;
|
||||
while(*semip && ISBLANK(*semip))
|
||||
semip++;
|
||||
if(*semip != '=')
|
||||
continue;
|
||||
semip++;
|
||||
num = strtoul(semip, &end_ptr, 10);
|
||||
if(num < ULONG_MAX) {
|
||||
if(strcasecompare("ma", option))
|
||||
maxage = num;
|
||||
else if(strcasecompare("persist", option) && (num == 1))
|
||||
persist = TRUE;
|
||||
}
|
||||
semip = end_ptr;
|
||||
}
|
||||
} while(semip);
|
||||
|
||||
do {
|
||||
if(*p == '=') {
|
||||
/* [protocol]="[host][:port]" */
|
||||
dstalpnid = alpn2alpnid(alpnbuf);
|
||||
if(!dstalpnid) {
|
||||
infof(data, "Unknown alt-svc protocol \"%s\", ignoring...\n", alpnbuf);
|
||||
return CURLE_OK;
|
||||
}
|
||||
p++;
|
||||
if(*p == '\"') {
|
||||
const char *dsthost;
|
||||
p++;
|
||||
if(*p != ':') {
|
||||
/* host name starts here */
|
||||
const char *hostp = p;
|
||||
while(*p && (ISALNUM(*p) || (*p == '.') || (*p == '-')))
|
||||
p++;
|
||||
len = p - hostp;
|
||||
if(!len || (len >= MAX_ALTSVC_HOSTLEN))
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
memcpy(namebuf, hostp, len);
|
||||
namebuf[len] = 0;
|
||||
dsthost = namebuf;
|
||||
}
|
||||
else {
|
||||
/* no destination name, use source host */
|
||||
dsthost = srchost;
|
||||
}
|
||||
if(*p == ':') {
|
||||
/* a port number */
|
||||
char *end_ptr;
|
||||
unsigned long port = strtoul(++p, &end_ptr, 10);
|
||||
if(port > USHRT_MAX || end_ptr == p || *end_ptr != '\"') {
|
||||
infof(data, "Unknown alt-svc port number, ignoring...\n");
|
||||
return CURLE_OK;
|
||||
}
|
||||
p = end_ptr;
|
||||
dstport = curlx_ultous(port);
|
||||
}
|
||||
if(*p++ != '\"')
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
as = altsvc_createid(srchost, dsthost,
|
||||
srcalpnid, dstalpnid,
|
||||
srcport, dstport);
|
||||
if(as) {
|
||||
/* The expires time also needs to take the Age: value (if any) into
|
||||
account. [See RFC 7838 section 3.1] */
|
||||
as->expires = maxage + time(NULL);
|
||||
as->persist = persist;
|
||||
Curl_llist_insert_next(&asi->list, asi->list.tail, as, &as->node);
|
||||
asi->num++; /* one more entry */
|
||||
infof(data, "Added alt-svc: %s:%d over %s\n", dsthost, dstport,
|
||||
Curl_alpnid2str(dstalpnid));
|
||||
}
|
||||
}
|
||||
/* after the double quote there can be a comma if there's another
|
||||
string or a semicolon if no more */
|
||||
if(*p == ',') {
|
||||
/* comma means another alternative is presented */
|
||||
p++;
|
||||
result = getalnum(&p, alpnbuf, sizeof(alpnbuf));
|
||||
if(result)
|
||||
/* failed to parse, but since we already did at least one host we
|
||||
return OK */
|
||||
return CURLE_OK;
|
||||
}
|
||||
}
|
||||
} while(*p && (*p != ';') && (*p != '\n') && (*p != '\r'));
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return TRUE on a match
|
||||
*/
|
||||
bool Curl_altsvc_lookup(struct altsvcinfo *asi,
|
||||
enum alpnid srcalpnid, const char *srchost,
|
||||
int srcport,
|
||||
enum alpnid *dstalpnid, const char **dsthost,
|
||||
int *dstport)
|
||||
{
|
||||
struct curl_llist_element *e;
|
||||
struct curl_llist_element *n;
|
||||
time_t now = time(NULL);
|
||||
DEBUGASSERT(asi);
|
||||
DEBUGASSERT(srchost);
|
||||
DEBUGASSERT(dsthost);
|
||||
|
||||
for(e = asi->list.head; e; e = n) {
|
||||
struct altsvc *as = e->ptr;
|
||||
n = e->next;
|
||||
if(as->expires < now) {
|
||||
/* an expired entry, remove */
|
||||
altsvc_free(as);
|
||||
continue;
|
||||
}
|
||||
if((as->srcalpnid == srcalpnid) &&
|
||||
strcasecompare(as->srchost, srchost) &&
|
||||
as->srcport == srcport) {
|
||||
/* match */
|
||||
*dstalpnid = as->dstalpnid;
|
||||
*dsthost = as->dsthost;
|
||||
*dstport = as->dstport;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#endif /* CURL_DISABLE_HTTP || USE_ALTSVC */
|
77
src/dependencies/cmcurl/lib/altsvc.h
Normal file
77
src/dependencies/cmcurl/lib/altsvc.h
Normal file
|
@ -0,0 +1,77 @@
|
|||
#ifndef HEADER_CURL_ALTSVC_H
|
||||
#define HEADER_CURL_ALTSVC_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2019, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if !defined(CURL_DISABLE_HTTP) && defined(USE_ALTSVC)
|
||||
#include <curl/curl.h>
|
||||
#include "llist.h"
|
||||
|
||||
enum alpnid {
|
||||
ALPN_none,
|
||||
ALPN_h1,
|
||||
ALPN_h2,
|
||||
ALPN_h2c,
|
||||
ALPN_h3
|
||||
};
|
||||
|
||||
struct altsvc {
|
||||
char *srchost;
|
||||
char *dsthost;
|
||||
unsigned short srcport;
|
||||
unsigned short dstport;
|
||||
enum alpnid srcalpnid;
|
||||
enum alpnid dstalpnid;
|
||||
time_t expires;
|
||||
bool persist;
|
||||
int prio;
|
||||
struct curl_llist_element node;
|
||||
};
|
||||
|
||||
struct altsvcinfo {
|
||||
char *filename;
|
||||
struct curl_llist list; /* list of entries */
|
||||
size_t num; /* number of alt-svc entries */
|
||||
long flags; /* the publicly set bitmask */
|
||||
};
|
||||
|
||||
const char *Curl_alpnid2str(enum alpnid id);
|
||||
struct altsvcinfo *Curl_altsvc_init(void);
|
||||
CURLcode Curl_altsvc_load(struct altsvcinfo *asi, const char *file);
|
||||
CURLcode Curl_altsvc_save(struct altsvcinfo *asi, const char *file);
|
||||
CURLcode Curl_altsvc_ctrl(struct altsvcinfo *asi, const long ctrl);
|
||||
void Curl_altsvc_cleanup(struct altsvcinfo *altsvc);
|
||||
CURLcode Curl_altsvc_parse(struct Curl_easy *data,
|
||||
struct altsvcinfo *altsvc, const char *value,
|
||||
enum alpnid srcalpn, const char *srchost,
|
||||
unsigned short srcport);
|
||||
bool Curl_altsvc_lookup(struct altsvcinfo *asi,
|
||||
enum alpnid srcalpnid, const char *srchost,
|
||||
int srcport,
|
||||
enum alpnid *dstalpnid, const char **dsthost,
|
||||
int *dstport);
|
||||
#else
|
||||
/* disabled */
|
||||
#define Curl_altsvc_save(a,b)
|
||||
#endif /* CURL_DISABLE_HTTP || USE_ALTSVC */
|
||||
#endif /* HEADER_CURL_ALTSVC_H */
|
95
src/dependencies/cmcurl/lib/amigaos.c
Normal file
95
src/dependencies/cmcurl/lib/amigaos.c
Normal file
|
@ -0,0 +1,95 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#ifdef __AMIGA__
|
||||
# include "amigaos.h"
|
||||
# if defined(HAVE_PROTO_BSDSOCKET_H) && !defined(USE_AMISSL)
|
||||
# include <amitcp/socketbasetags.h>
|
||||
# endif
|
||||
# ifdef __libnix__
|
||||
# include <stabs.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* The last #include files should be: */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#ifdef __AMIGA__
|
||||
#if defined(HAVE_PROTO_BSDSOCKET_H) && !defined(USE_AMISSL)
|
||||
struct Library *SocketBase = NULL;
|
||||
extern int errno, h_errno;
|
||||
|
||||
#ifdef __libnix__
|
||||
void __request(const char *msg);
|
||||
#else
|
||||
# define __request(msg) Printf(msg "\n\a")
|
||||
#endif
|
||||
|
||||
void Curl_amiga_cleanup()
|
||||
{
|
||||
if(SocketBase) {
|
||||
CloseLibrary(SocketBase);
|
||||
SocketBase = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool Curl_amiga_init()
|
||||
{
|
||||
if(!SocketBase)
|
||||
SocketBase = OpenLibrary("bsdsocket.library", 4);
|
||||
|
||||
if(!SocketBase) {
|
||||
__request("No TCP/IP Stack running!");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if(SocketBaseTags(SBTM_SETVAL(SBTC_ERRNOPTR(sizeof(errno))), (ULONG) &errno,
|
||||
SBTM_SETVAL(SBTC_LOGTAGPTR), (ULONG) "curl",
|
||||
TAG_DONE)) {
|
||||
__request("SocketBaseTags ERROR");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifndef __libnix__
|
||||
atexit(Curl_amiga_cleanup);
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#ifdef __libnix__
|
||||
ADD2EXIT(Curl_amiga_cleanup, -50);
|
||||
#endif
|
||||
|
||||
#endif /* HAVE_PROTO_BSDSOCKET_H */
|
||||
|
||||
#ifdef USE_AMISSL
|
||||
void Curl_amiga_X509_free(X509 *a)
|
||||
{
|
||||
X509_free(a);
|
||||
}
|
||||
#endif /* USE_AMISSL */
|
||||
#endif /* __AMIGA__ */
|
||||
|
44
src/dependencies/cmcurl/lib/amigaos.h
Normal file
44
src/dependencies/cmcurl/lib/amigaos.h
Normal file
|
@ -0,0 +1,44 @@
|
|||
#ifndef HEADER_CURL_AMIGAOS_H
|
||||
#define HEADER_CURL_AMIGAOS_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if defined(__AMIGA__) && defined(HAVE_BSDSOCKET_H) && !defined(USE_AMISSL)
|
||||
|
||||
bool Curl_amiga_init();
|
||||
void Curl_amiga_cleanup();
|
||||
|
||||
#else
|
||||
|
||||
#define Curl_amiga_init() 1
|
||||
#define Curl_amiga_cleanup() Curl_nop_stmt
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef USE_AMISSL
|
||||
#include <openssl/x509v3.h>
|
||||
void Curl_amiga_X509_free(X509 *a);
|
||||
#endif /* USE_AMISSL */
|
||||
|
||||
#endif /* HEADER_CURL_AMIGAOS_H */
|
||||
|
108
src/dependencies/cmcurl/lib/arpa_telnet.h
Normal file
108
src/dependencies/cmcurl/lib/arpa_telnet.h
Normal file
|
@ -0,0 +1,108 @@
|
|||
#ifndef HEADER_CURL_ARPA_TELNET_H
|
||||
#define HEADER_CURL_ARPA_TELNET_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
#ifndef CURL_DISABLE_TELNET
|
||||
/*
|
||||
* Telnet option defines. Add more here if in need.
|
||||
*/
|
||||
#define CURL_TELOPT_BINARY 0 /* binary 8bit data */
|
||||
#define CURL_TELOPT_ECHO 1 /* just echo! */
|
||||
#define CURL_TELOPT_SGA 3 /* Suppress Go Ahead */
|
||||
#define CURL_TELOPT_EXOPL 255 /* EXtended OPtions List */
|
||||
#define CURL_TELOPT_TTYPE 24 /* Terminal TYPE */
|
||||
#define CURL_TELOPT_NAWS 31 /* Negotiate About Window Size */
|
||||
#define CURL_TELOPT_XDISPLOC 35 /* X DISPlay LOCation */
|
||||
|
||||
#define CURL_TELOPT_NEW_ENVIRON 39 /* NEW ENVIRONment variables */
|
||||
#define CURL_NEW_ENV_VAR 0
|
||||
#define CURL_NEW_ENV_VALUE 1
|
||||
|
||||
#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
||||
/*
|
||||
* The telnet options represented as strings
|
||||
*/
|
||||
static const char * const telnetoptions[]=
|
||||
{
|
||||
"BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD",
|
||||
"NAME", "STATUS", "TIMING MARK", "RCTE",
|
||||
"NAOL", "NAOP", "NAOCRD", "NAOHTS",
|
||||
"NAOHTD", "NAOFFD", "NAOVTS", "NAOVTD",
|
||||
"NAOLFD", "EXTEND ASCII", "LOGOUT", "BYTE MACRO",
|
||||
"DE TERMINAL", "SUPDUP", "SUPDUP OUTPUT", "SEND LOCATION",
|
||||
"TERM TYPE", "END OF RECORD", "TACACS UID", "OUTPUT MARKING",
|
||||
"TTYLOC", "3270 REGIME", "X3 PAD", "NAWS",
|
||||
"TERM SPEED", "LFLOW", "LINEMODE", "XDISPLOC",
|
||||
"OLD-ENVIRON", "AUTHENTICATION", "ENCRYPT", "NEW-ENVIRON"
|
||||
};
|
||||
#endif
|
||||
|
||||
#define CURL_TELOPT_MAXIMUM CURL_TELOPT_NEW_ENVIRON
|
||||
|
||||
#define CURL_TELOPT_OK(x) ((x) <= CURL_TELOPT_MAXIMUM)
|
||||
#define CURL_TELOPT(x) telnetoptions[x]
|
||||
|
||||
#define CURL_NTELOPTS 40
|
||||
|
||||
/*
|
||||
* First some defines
|
||||
*/
|
||||
#define CURL_xEOF 236 /* End Of File */
|
||||
#define CURL_SE 240 /* Sub negotiation End */
|
||||
#define CURL_NOP 241 /* No OPeration */
|
||||
#define CURL_DM 242 /* Data Mark */
|
||||
#define CURL_GA 249 /* Go Ahead, reverse the line */
|
||||
#define CURL_SB 250 /* SuBnegotiation */
|
||||
#define CURL_WILL 251 /* Our side WILL use this option */
|
||||
#define CURL_WONT 252 /* Our side WON'T use this option */
|
||||
#define CURL_DO 253 /* DO use this option! */
|
||||
#define CURL_DONT 254 /* DON'T use this option! */
|
||||
#define CURL_IAC 255 /* Interpret As Command */
|
||||
|
||||
#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
||||
/*
|
||||
* Then those numbers represented as strings:
|
||||
*/
|
||||
static const char * const telnetcmds[]=
|
||||
{
|
||||
"EOF", "SUSP", "ABORT", "EOR", "SE",
|
||||
"NOP", "DMARK", "BRK", "IP", "AO",
|
||||
"AYT", "EC", "EL", "GA", "SB",
|
||||
"WILL", "WONT", "DO", "DONT", "IAC"
|
||||
};
|
||||
#endif
|
||||
|
||||
#define CURL_TELCMD_MINIMUM CURL_xEOF /* the first one */
|
||||
#define CURL_TELCMD_MAXIMUM CURL_IAC /* surprise, 255 is the last one! ;-) */
|
||||
|
||||
#define CURL_TELQUAL_IS 0
|
||||
#define CURL_TELQUAL_SEND 1
|
||||
#define CURL_TELQUAL_INFO 2
|
||||
#define CURL_TELQUAL_NAME 3
|
||||
|
||||
#define CURL_TELCMD_OK(x) ( ((unsigned int)(x) >= CURL_TELCMD_MINIMUM) && \
|
||||
((unsigned int)(x) <= CURL_TELCMD_MAXIMUM) )
|
||||
#define CURL_TELCMD(x) telnetcmds[(x)-CURL_TELCMD_MINIMUM]
|
||||
|
||||
#endif /* CURL_DISABLE_TELNET */
|
||||
|
||||
#endif /* HEADER_CURL_ARPA_TELNET_H */
|
826
src/dependencies/cmcurl/lib/asyn-ares.c
Normal file
826
src/dependencies/cmcurl/lib/asyn-ares.c
Normal file
|
@ -0,0 +1,826 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
/***********************************************************************
|
||||
* Only for ares-enabled builds
|
||||
* And only for functions that fulfill the asynch resolver backend API
|
||||
* as defined in asyn.h, nothing else belongs in this file!
|
||||
**********************************************************************/
|
||||
|
||||
#ifdef CURLRES_ARES
|
||||
|
||||
#include <limits.h>
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETDB_H
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#ifdef __VMS
|
||||
#include <in.h>
|
||||
#include <inet.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PROCESS_H
|
||||
#include <process.h>
|
||||
#endif
|
||||
|
||||
#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
|
||||
#undef in_addr_t
|
||||
#define in_addr_t unsigned long
|
||||
#endif
|
||||
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
#include "hostip.h"
|
||||
#include "hash.h"
|
||||
#include "share.h"
|
||||
#include "strerror.h"
|
||||
#include "url.h"
|
||||
#include "multiif.h"
|
||||
#include "inet_pton.h"
|
||||
#include "connect.h"
|
||||
#include "select.h"
|
||||
#include "progress.h"
|
||||
|
||||
# if defined(CURL_STATICLIB) && !defined(CARES_STATICLIB) && \
|
||||
(defined(WIN32) || defined(__SYMBIAN32__))
|
||||
# define CARES_STATICLIB
|
||||
# endif
|
||||
# include <ares.h>
|
||||
# include <ares_version.h> /* really old c-ares didn't include this by
|
||||
itself */
|
||||
|
||||
#if ARES_VERSION >= 0x010500
|
||||
/* c-ares 1.5.0 or later, the callback proto is modified */
|
||||
#define HAVE_CARES_CALLBACK_TIMEOUTS 1
|
||||
#endif
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
struct ResolverResults {
|
||||
int num_pending; /* number of ares_gethostbyname() requests */
|
||||
Curl_addrinfo *temp_ai; /* intermediary result while fetching c-ares parts */
|
||||
int last_status;
|
||||
struct curltime happy_eyeballs_dns_time; /* when this timer started, or 0 */
|
||||
};
|
||||
|
||||
/* How long we are willing to wait for additional parallel responses after
|
||||
obtaining a "definitive" one.
|
||||
|
||||
This is intended to equal the c-ares default timeout. cURL always uses that
|
||||
default value. Unfortunately, c-ares doesn't expose its default timeout in
|
||||
its API, but it is officially documented as 5 seconds.
|
||||
|
||||
See query_completed_cb() for an explanation of how this is used.
|
||||
*/
|
||||
#define HAPPY_EYEBALLS_DNS_TIMEOUT 5000
|
||||
|
||||
/*
|
||||
* Curl_resolver_global_init() - the generic low-level asynchronous name
|
||||
* resolve API. Called from curl_global_init() to initialize global resolver
|
||||
* environment. Initializes ares library.
|
||||
*/
|
||||
int Curl_resolver_global_init(void)
|
||||
{
|
||||
#ifdef CARES_HAVE_ARES_LIBRARY_INIT
|
||||
if(ares_library_init(ARES_LIB_INIT_ALL)) {
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
#endif
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_resolver_global_cleanup()
|
||||
*
|
||||
* Called from curl_global_cleanup() to destroy global resolver environment.
|
||||
* Deinitializes ares library.
|
||||
*/
|
||||
void Curl_resolver_global_cleanup(void)
|
||||
{
|
||||
#ifdef CARES_HAVE_ARES_LIBRARY_CLEANUP
|
||||
ares_library_cleanup();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static void Curl_ares_sock_state_cb(void *data, ares_socket_t socket_fd,
|
||||
int readable, int writable)
|
||||
{
|
||||
struct Curl_easy *easy = data;
|
||||
if(!readable && !writable) {
|
||||
DEBUGASSERT(easy);
|
||||
Curl_multi_closed(easy, socket_fd);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_resolver_init()
|
||||
*
|
||||
* Called from curl_easy_init() -> Curl_open() to initialize resolver
|
||||
* URL-state specific environment ('resolver' member of the UrlState
|
||||
* structure). Fills the passed pointer by the initialized ares_channel.
|
||||
*/
|
||||
CURLcode Curl_resolver_init(struct Curl_easy *easy, void **resolver)
|
||||
{
|
||||
int status;
|
||||
struct ares_options options;
|
||||
int optmask = ARES_OPT_SOCK_STATE_CB;
|
||||
options.sock_state_cb = Curl_ares_sock_state_cb;
|
||||
options.sock_state_cb_data = easy;
|
||||
status = ares_init_options((ares_channel*)resolver, &options, optmask);
|
||||
if(status != ARES_SUCCESS) {
|
||||
if(status == ARES_ENOMEM)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
else
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
return CURLE_OK;
|
||||
/* make sure that all other returns from this function should destroy the
|
||||
ares channel before returning error! */
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_resolver_cleanup()
|
||||
*
|
||||
* Called from curl_easy_cleanup() -> Curl_close() to cleanup resolver
|
||||
* URL-state specific environment ('resolver' member of the UrlState
|
||||
* structure). Destroys the ares channel.
|
||||
*/
|
||||
void Curl_resolver_cleanup(void *resolver)
|
||||
{
|
||||
ares_destroy((ares_channel)resolver);
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_resolver_duphandle()
|
||||
*
|
||||
* Called from curl_easy_duphandle() to duplicate resolver URL-state specific
|
||||
* environment ('resolver' member of the UrlState structure). Duplicates the
|
||||
* 'from' ares channel and passes the resulting channel to the 'to' pointer.
|
||||
*/
|
||||
CURLcode Curl_resolver_duphandle(struct Curl_easy *easy, void **to, void *from)
|
||||
{
|
||||
(void)from;
|
||||
/*
|
||||
* it would be better to call ares_dup instead, but right now
|
||||
* it is not possible to set 'sock_state_cb_data' outside of
|
||||
* ares_init_options
|
||||
*/
|
||||
return Curl_resolver_init(easy, to);
|
||||
}
|
||||
|
||||
static void destroy_async_data(struct Curl_async *async);
|
||||
|
||||
/*
|
||||
* Cancel all possibly still on-going resolves for this connection.
|
||||
*/
|
||||
void Curl_resolver_cancel(struct connectdata *conn)
|
||||
{
|
||||
if(conn->data && conn->data->state.resolver)
|
||||
ares_cancel((ares_channel)conn->data->state.resolver);
|
||||
destroy_async_data(&conn->async);
|
||||
}
|
||||
|
||||
/*
|
||||
* We're equivalent to Curl_resolver_cancel() for the c-ares resolver. We
|
||||
* never block.
|
||||
*/
|
||||
void Curl_resolver_kill(struct connectdata *conn)
|
||||
{
|
||||
/* We don't need to check the resolver state because we can be called safely
|
||||
at any time and we always do the same thing. */
|
||||
Curl_resolver_cancel(conn);
|
||||
}
|
||||
|
||||
/*
|
||||
* destroy_async_data() cleans up async resolver data.
|
||||
*/
|
||||
static void destroy_async_data(struct Curl_async *async)
|
||||
{
|
||||
free(async->hostname);
|
||||
|
||||
if(async->os_specific) {
|
||||
struct ResolverResults *res = (struct ResolverResults *)async->os_specific;
|
||||
if(res) {
|
||||
if(res->temp_ai) {
|
||||
Curl_freeaddrinfo(res->temp_ai);
|
||||
res->temp_ai = NULL;
|
||||
}
|
||||
free(res);
|
||||
}
|
||||
async->os_specific = NULL;
|
||||
}
|
||||
|
||||
async->hostname = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_resolver_getsock() is called when someone from the outside world
|
||||
* (using curl_multi_fdset()) wants to get our fd_set setup and we're talking
|
||||
* with ares. The caller must make sure that this function is only called when
|
||||
* we have a working ares channel.
|
||||
*
|
||||
* Returns: sockets-in-use-bitmap
|
||||
*/
|
||||
|
||||
int Curl_resolver_getsock(struct connectdata *conn,
|
||||
curl_socket_t *socks,
|
||||
int numsocks)
|
||||
|
||||
{
|
||||
struct timeval maxtime;
|
||||
struct timeval timebuf;
|
||||
struct timeval *timeout;
|
||||
long milli;
|
||||
int max = ares_getsock((ares_channel)conn->data->state.resolver,
|
||||
(ares_socket_t *)socks, numsocks);
|
||||
|
||||
maxtime.tv_sec = CURL_TIMEOUT_RESOLVE;
|
||||
maxtime.tv_usec = 0;
|
||||
|
||||
timeout = ares_timeout((ares_channel)conn->data->state.resolver, &maxtime,
|
||||
&timebuf);
|
||||
milli = (timeout->tv_sec * 1000) + (timeout->tv_usec/1000);
|
||||
if(milli == 0)
|
||||
milli += 10;
|
||||
Curl_expire(conn->data, milli, EXPIRE_ASYNC_NAME);
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
/*
|
||||
* waitperform()
|
||||
*
|
||||
* 1) Ask ares what sockets it currently plays with, then
|
||||
* 2) wait for the timeout period to check for action on ares' sockets.
|
||||
* 3) tell ares to act on all the sockets marked as "with action"
|
||||
*
|
||||
* return number of sockets it worked on
|
||||
*/
|
||||
|
||||
static int waitperform(struct connectdata *conn, int timeout_ms)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
int nfds;
|
||||
int bitmask;
|
||||
ares_socket_t socks[ARES_GETSOCK_MAXNUM];
|
||||
struct pollfd pfd[ARES_GETSOCK_MAXNUM];
|
||||
int i;
|
||||
int num = 0;
|
||||
|
||||
bitmask = ares_getsock((ares_channel)data->state.resolver, socks,
|
||||
ARES_GETSOCK_MAXNUM);
|
||||
|
||||
for(i = 0; i < ARES_GETSOCK_MAXNUM; i++) {
|
||||
pfd[i].events = 0;
|
||||
pfd[i].revents = 0;
|
||||
if(ARES_GETSOCK_READABLE(bitmask, i)) {
|
||||
pfd[i].fd = socks[i];
|
||||
pfd[i].events |= POLLRDNORM|POLLIN;
|
||||
}
|
||||
if(ARES_GETSOCK_WRITABLE(bitmask, i)) {
|
||||
pfd[i].fd = socks[i];
|
||||
pfd[i].events |= POLLWRNORM|POLLOUT;
|
||||
}
|
||||
if(pfd[i].events != 0)
|
||||
num++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if(num)
|
||||
nfds = Curl_poll(pfd, num, timeout_ms);
|
||||
else
|
||||
nfds = 0;
|
||||
|
||||
if(!nfds)
|
||||
/* Call ares_process() unconditonally here, even if we simply timed out
|
||||
above, as otherwise the ares name resolve won't timeout! */
|
||||
ares_process_fd((ares_channel)data->state.resolver, ARES_SOCKET_BAD,
|
||||
ARES_SOCKET_BAD);
|
||||
else {
|
||||
/* move through the descriptors and ask for processing on them */
|
||||
for(i = 0; i < num; i++)
|
||||
ares_process_fd((ares_channel)data->state.resolver,
|
||||
(pfd[i].revents & (POLLRDNORM|POLLIN))?
|
||||
pfd[i].fd:ARES_SOCKET_BAD,
|
||||
(pfd[i].revents & (POLLWRNORM|POLLOUT))?
|
||||
pfd[i].fd:ARES_SOCKET_BAD);
|
||||
}
|
||||
return nfds;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_resolver_is_resolved() is called repeatedly to check if a previous
|
||||
* name resolve request has completed. It should also make sure to time-out if
|
||||
* the operation seems to take too long.
|
||||
*
|
||||
* Returns normal CURLcode errors.
|
||||
*/
|
||||
CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
|
||||
struct Curl_dns_entry **dns)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct ResolverResults *res = (struct ResolverResults *)
|
||||
conn->async.os_specific;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
if(dns)
|
||||
*dns = NULL;
|
||||
|
||||
waitperform(conn, 0);
|
||||
|
||||
/* Now that we've checked for any last minute results above, see if there are
|
||||
any responses still pending when the EXPIRE_HAPPY_EYEBALLS_DNS timer
|
||||
expires. */
|
||||
if(res
|
||||
&& res->num_pending
|
||||
/* This is only set to non-zero if the timer was started. */
|
||||
&& (res->happy_eyeballs_dns_time.tv_sec
|
||||
|| res->happy_eyeballs_dns_time.tv_usec)
|
||||
&& (Curl_timediff(Curl_now(), res->happy_eyeballs_dns_time)
|
||||
>= HAPPY_EYEBALLS_DNS_TIMEOUT)) {
|
||||
/* Remember that the EXPIRE_HAPPY_EYEBALLS_DNS timer is no longer
|
||||
running. */
|
||||
memset(
|
||||
&res->happy_eyeballs_dns_time, 0, sizeof(res->happy_eyeballs_dns_time));
|
||||
|
||||
/* Cancel the raw c-ares request, which will fire query_completed_cb() with
|
||||
ARES_ECANCELLED synchronously for all pending responses. This will
|
||||
leave us with res->num_pending == 0, which is perfect for the next
|
||||
block. */
|
||||
ares_cancel((ares_channel)data->state.resolver);
|
||||
DEBUGASSERT(res->num_pending == 0);
|
||||
}
|
||||
|
||||
if(res && !res->num_pending) {
|
||||
if(dns) {
|
||||
(void)Curl_addrinfo_callback(conn, res->last_status, res->temp_ai);
|
||||
/* temp_ai ownership is moved to the connection, so we need not free-up
|
||||
them */
|
||||
res->temp_ai = NULL;
|
||||
}
|
||||
if(!conn->async.dns) {
|
||||
failf(data, "Could not resolve: %s (%s)",
|
||||
conn->async.hostname, ares_strerror(conn->async.status));
|
||||
result = conn->bits.proxy?CURLE_COULDNT_RESOLVE_PROXY:
|
||||
CURLE_COULDNT_RESOLVE_HOST;
|
||||
}
|
||||
else if(dns)
|
||||
*dns = conn->async.dns;
|
||||
|
||||
destroy_async_data(&conn->async);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_resolver_wait_resolv()
|
||||
*
|
||||
* Waits for a resolve to finish. This function should be avoided since using
|
||||
* this risk getting the multi interface to "hang".
|
||||
*
|
||||
* If 'entry' is non-NULL, make it point to the resolved dns entry
|
||||
*
|
||||
* Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved,
|
||||
* CURLE_OPERATION_TIMEDOUT if a time-out occurred, or other errors.
|
||||
*/
|
||||
CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
|
||||
struct Curl_dns_entry **entry)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct Curl_easy *data = conn->data;
|
||||
timediff_t timeout;
|
||||
struct curltime now = Curl_now();
|
||||
struct Curl_dns_entry *temp_entry;
|
||||
|
||||
if(entry)
|
||||
*entry = NULL; /* clear on entry */
|
||||
|
||||
timeout = Curl_timeleft(data, &now, TRUE);
|
||||
if(timeout < 0) {
|
||||
/* already expired! */
|
||||
connclose(conn, "Timed out before name resolve started");
|
||||
return CURLE_OPERATION_TIMEDOUT;
|
||||
}
|
||||
if(!timeout)
|
||||
timeout = CURL_TIMEOUT_RESOLVE * 1000; /* default name resolve timeout */
|
||||
|
||||
/* Wait for the name resolve query to complete. */
|
||||
while(!result) {
|
||||
struct timeval *tvp, tv, store;
|
||||
int itimeout;
|
||||
int timeout_ms;
|
||||
|
||||
itimeout = (timeout > (long)INT_MAX) ? INT_MAX : (int)timeout;
|
||||
|
||||
store.tv_sec = itimeout/1000;
|
||||
store.tv_usec = (itimeout%1000)*1000;
|
||||
|
||||
tvp = ares_timeout((ares_channel)data->state.resolver, &store, &tv);
|
||||
|
||||
/* use the timeout period ares returned to us above if less than one
|
||||
second is left, otherwise just use 1000ms to make sure the progress
|
||||
callback gets called frequent enough */
|
||||
if(!tvp->tv_sec)
|
||||
timeout_ms = (int)(tvp->tv_usec/1000);
|
||||
else
|
||||
timeout_ms = 1000;
|
||||
|
||||
waitperform(conn, timeout_ms);
|
||||
result = Curl_resolver_is_resolved(conn, entry?&temp_entry:NULL);
|
||||
|
||||
if(result || conn->async.done)
|
||||
break;
|
||||
|
||||
if(Curl_pgrsUpdate(conn))
|
||||
result = CURLE_ABORTED_BY_CALLBACK;
|
||||
else {
|
||||
struct curltime now2 = Curl_now();
|
||||
timediff_t timediff = Curl_timediff(now2, now); /* spent time */
|
||||
if(timediff <= 0)
|
||||
timeout -= 1; /* always deduct at least 1 */
|
||||
else if(timediff > timeout)
|
||||
timeout = -1;
|
||||
else
|
||||
timeout -= (long)timediff;
|
||||
now = now2; /* for next loop */
|
||||
}
|
||||
if(timeout < 0)
|
||||
result = CURLE_OPERATION_TIMEDOUT;
|
||||
}
|
||||
if(result)
|
||||
/* failure, so we cancel the ares operation */
|
||||
ares_cancel((ares_channel)data->state.resolver);
|
||||
|
||||
/* Operation complete, if the lookup was successful we now have the entry
|
||||
in the cache. */
|
||||
if(entry)
|
||||
*entry = conn->async.dns;
|
||||
|
||||
if(result)
|
||||
/* close the connection, since we can't return failure here without
|
||||
cleaning up this connection properly. */
|
||||
connclose(conn, "c-ares resolve failed");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Connects results to the list */
|
||||
static void compound_results(struct ResolverResults *res,
|
||||
Curl_addrinfo *ai)
|
||||
{
|
||||
Curl_addrinfo *ai_tail;
|
||||
if(!ai)
|
||||
return;
|
||||
ai_tail = ai;
|
||||
|
||||
while(ai_tail->ai_next)
|
||||
ai_tail = ai_tail->ai_next;
|
||||
|
||||
/* Add the new results to the list of old results. */
|
||||
ai_tail->ai_next = res->temp_ai;
|
||||
res->temp_ai = ai;
|
||||
}
|
||||
|
||||
/*
|
||||
* ares_query_completed_cb() is the callback that ares will call when
|
||||
* the host query initiated by ares_gethostbyname() from Curl_getaddrinfo(),
|
||||
* when using ares, is completed either successfully or with failure.
|
||||
*/
|
||||
static void query_completed_cb(void *arg, /* (struct connectdata *) */
|
||||
int status,
|
||||
#ifdef HAVE_CARES_CALLBACK_TIMEOUTS
|
||||
int timeouts,
|
||||
#endif
|
||||
struct hostent *hostent)
|
||||
{
|
||||
struct connectdata *conn = (struct connectdata *)arg;
|
||||
struct ResolverResults *res;
|
||||
|
||||
#ifdef HAVE_CARES_CALLBACK_TIMEOUTS
|
||||
(void)timeouts; /* ignored */
|
||||
#endif
|
||||
|
||||
if(ARES_EDESTRUCTION == status)
|
||||
/* when this ares handle is getting destroyed, the 'arg' pointer may not
|
||||
be valid so only defer it when we know the 'status' says its fine! */
|
||||
return;
|
||||
|
||||
res = (struct ResolverResults *)conn->async.os_specific;
|
||||
if(res) {
|
||||
res->num_pending--;
|
||||
|
||||
if(CURL_ASYNC_SUCCESS == status) {
|
||||
Curl_addrinfo *ai = Curl_he2ai(hostent, conn->async.port);
|
||||
if(ai) {
|
||||
compound_results(res, ai);
|
||||
}
|
||||
}
|
||||
/* A successful result overwrites any previous error */
|
||||
if(res->last_status != ARES_SUCCESS)
|
||||
res->last_status = status;
|
||||
|
||||
/* If there are responses still pending, we presume they must be the
|
||||
complementary IPv4 or IPv6 lookups that we started in parallel in
|
||||
Curl_resolver_getaddrinfo() (for Happy Eyeballs). If we've got a
|
||||
"definitive" response from one of a set of parallel queries, we need to
|
||||
think about how long we're willing to wait for more responses. */
|
||||
if(res->num_pending
|
||||
/* Only these c-ares status values count as "definitive" for these
|
||||
purposes. For example, ARES_ENODATA is what we expect when there is
|
||||
no IPv6 entry for a domain name, and that's not a reason to get more
|
||||
aggressive in our timeouts for the other response. Other errors are
|
||||
either a result of bad input (which should affect all parallel
|
||||
requests), local or network conditions, non-definitive server
|
||||
responses, or us cancelling the request. */
|
||||
&& (status == ARES_SUCCESS || status == ARES_ENOTFOUND)) {
|
||||
/* Right now, there can only be up to two parallel queries, so don't
|
||||
bother handling any other cases. */
|
||||
DEBUGASSERT(res->num_pending == 1);
|
||||
|
||||
/* It's possible that one of these parallel queries could succeed
|
||||
quickly, but the other could always fail or timeout (when we're
|
||||
talking to a pool of DNS servers that can only successfully resolve
|
||||
IPv4 address, for example).
|
||||
|
||||
It's also possible that the other request could always just take
|
||||
longer because it needs more time or only the second DNS server can
|
||||
fulfill it successfully. But, to align with the philosophy of Happy
|
||||
Eyeballs, we don't want to wait _too_ long or users will think
|
||||
requests are slow when IPv6 lookups don't actually work (but IPv4 ones
|
||||
do).
|
||||
|
||||
So, now that we have a usable answer (some IPv4 addresses, some IPv6
|
||||
addresses, or "no such domain"), we start a timeout for the remaining
|
||||
pending responses. Even though it is typical that this resolved
|
||||
request came back quickly, that needn't be the case. It might be that
|
||||
this completing request didn't get a result from the first DNS server
|
||||
or even the first round of the whole DNS server pool. So it could
|
||||
already be quite some time after we issued the DNS queries in the
|
||||
first place. Without modifying c-ares, we can't know exactly where in
|
||||
its retry cycle we are. We could guess based on how much time has
|
||||
gone by, but it doesn't really matter. Happy Eyeballs tells us that,
|
||||
given usable information in hand, we simply don't want to wait "too
|
||||
much longer" after we get a result.
|
||||
|
||||
We simply wait an additional amount of time equal to the default
|
||||
c-ares query timeout. That is enough time for a typical parallel
|
||||
response to arrive without being "too long". Even on a network
|
||||
where one of the two types of queries is failing or timing out
|
||||
constantly, this will usually mean we wait a total of the default
|
||||
c-ares timeout (5 seconds) plus the round trip time for the successful
|
||||
request, which seems bearable. The downside is that c-ares might race
|
||||
with us to issue one more retry just before we give up, but it seems
|
||||
better to "waste" that request instead of trying to guess the perfect
|
||||
timeout to prevent it. After all, we don't even know where in the
|
||||
c-ares retry cycle each request is.
|
||||
*/
|
||||
res->happy_eyeballs_dns_time = Curl_now();
|
||||
Curl_expire(
|
||||
conn->data, HAPPY_EYEBALLS_DNS_TIMEOUT, EXPIRE_HAPPY_EYEBALLS_DNS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_resolver_getaddrinfo() - when using ares
|
||||
*
|
||||
* Returns name information about the given hostname and port number. If
|
||||
* successful, the 'hostent' is returned and the forth argument will point to
|
||||
* memory we need to free after use. That memory *MUST* be freed with
|
||||
* Curl_freeaddrinfo(), nothing else.
|
||||
*/
|
||||
Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
||||
const char *hostname,
|
||||
int port,
|
||||
int *waitp)
|
||||
{
|
||||
char *bufp;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct in_addr in;
|
||||
int family = PF_INET;
|
||||
#ifdef ENABLE_IPV6 /* CURLRES_IPV6 */
|
||||
struct in6_addr in6;
|
||||
#endif /* CURLRES_IPV6 */
|
||||
|
||||
*waitp = 0; /* default to synchronous response */
|
||||
|
||||
/* First check if this is an IPv4 address string */
|
||||
if(Curl_inet_pton(AF_INET, hostname, &in) > 0) {
|
||||
/* This is a dotted IP address 123.123.123.123-style */
|
||||
return Curl_ip2addr(AF_INET, &in, hostname, port);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_IPV6 /* CURLRES_IPV6 */
|
||||
/* Otherwise, check if this is an IPv6 address string */
|
||||
if(Curl_inet_pton (AF_INET6, hostname, &in6) > 0)
|
||||
/* This must be an IPv6 address literal. */
|
||||
return Curl_ip2addr(AF_INET6, &in6, hostname, port);
|
||||
|
||||
switch(conn->ip_version) {
|
||||
default:
|
||||
#if ARES_VERSION >= 0x010601
|
||||
family = PF_UNSPEC; /* supported by c-ares since 1.6.1, so for older
|
||||
c-ares versions this just falls through and defaults
|
||||
to PF_INET */
|
||||
break;
|
||||
#endif
|
||||
case CURL_IPRESOLVE_V4:
|
||||
family = PF_INET;
|
||||
break;
|
||||
case CURL_IPRESOLVE_V6:
|
||||
family = PF_INET6;
|
||||
break;
|
||||
}
|
||||
#endif /* CURLRES_IPV6 */
|
||||
|
||||
bufp = strdup(hostname);
|
||||
if(bufp) {
|
||||
struct ResolverResults *res = NULL;
|
||||
free(conn->async.hostname);
|
||||
conn->async.hostname = bufp;
|
||||
conn->async.port = port;
|
||||
conn->async.done = FALSE; /* not done */
|
||||
conn->async.status = 0; /* clear */
|
||||
conn->async.dns = NULL; /* clear */
|
||||
res = calloc(sizeof(struct ResolverResults), 1);
|
||||
if(!res) {
|
||||
free(conn->async.hostname);
|
||||
conn->async.hostname = NULL;
|
||||
return NULL;
|
||||
}
|
||||
conn->async.os_specific = res;
|
||||
|
||||
/* initial status - failed */
|
||||
res->last_status = ARES_ENOTFOUND;
|
||||
#ifdef ENABLE_IPV6 /* CURLRES_IPV6 */
|
||||
if(family == PF_UNSPEC) {
|
||||
if(Curl_ipv6works()) {
|
||||
res->num_pending = 2;
|
||||
|
||||
/* areschannel is already setup in the Curl_open() function */
|
||||
ares_gethostbyname((ares_channel)data->state.resolver, hostname,
|
||||
PF_INET, query_completed_cb, conn);
|
||||
ares_gethostbyname((ares_channel)data->state.resolver, hostname,
|
||||
PF_INET6, query_completed_cb, conn);
|
||||
}
|
||||
else {
|
||||
res->num_pending = 1;
|
||||
|
||||
/* areschannel is already setup in the Curl_open() function */
|
||||
ares_gethostbyname((ares_channel)data->state.resolver, hostname,
|
||||
PF_INET, query_completed_cb, conn);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif /* CURLRES_IPV6 */
|
||||
{
|
||||
res->num_pending = 1;
|
||||
|
||||
/* areschannel is already setup in the Curl_open() function */
|
||||
ares_gethostbyname((ares_channel)data->state.resolver, hostname, family,
|
||||
query_completed_cb, conn);
|
||||
}
|
||||
|
||||
*waitp = 1; /* expect asynchronous response */
|
||||
}
|
||||
return NULL; /* no struct yet */
|
||||
}
|
||||
|
||||
CURLcode Curl_set_dns_servers(struct Curl_easy *data,
|
||||
char *servers)
|
||||
{
|
||||
CURLcode result = CURLE_NOT_BUILT_IN;
|
||||
int ares_result;
|
||||
|
||||
/* If server is NULL or empty, this would purge all DNS servers
|
||||
* from ares library, which will cause any and all queries to fail.
|
||||
* So, just return OK if none are configured and don't actually make
|
||||
* any changes to c-ares. This lets c-ares use it's defaults, which
|
||||
* it gets from the OS (for instance from /etc/resolv.conf on Linux).
|
||||
*/
|
||||
if(!(servers && servers[0]))
|
||||
return CURLE_OK;
|
||||
|
||||
#if (ARES_VERSION >= 0x010704)
|
||||
ares_result = ares_set_servers_csv(data->state.resolver, servers);
|
||||
switch(ares_result) {
|
||||
case ARES_SUCCESS:
|
||||
result = CURLE_OK;
|
||||
break;
|
||||
case ARES_ENOMEM:
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
break;
|
||||
case ARES_ENOTINITIALIZED:
|
||||
case ARES_ENODATA:
|
||||
case ARES_EBADSTR:
|
||||
default:
|
||||
result = CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
break;
|
||||
}
|
||||
#else /* too old c-ares version! */
|
||||
(void)data;
|
||||
(void)(ares_result);
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
CURLcode Curl_set_dns_interface(struct Curl_easy *data,
|
||||
const char *interf)
|
||||
{
|
||||
#if (ARES_VERSION >= 0x010704)
|
||||
if(!interf)
|
||||
interf = "";
|
||||
|
||||
ares_set_local_dev((ares_channel)data->state.resolver, interf);
|
||||
|
||||
return CURLE_OK;
|
||||
#else /* c-ares version too old! */
|
||||
(void)data;
|
||||
(void)interf;
|
||||
return CURLE_NOT_BUILT_IN;
|
||||
#endif
|
||||
}
|
||||
|
||||
CURLcode Curl_set_dns_local_ip4(struct Curl_easy *data,
|
||||
const char *local_ip4)
|
||||
{
|
||||
#if (ARES_VERSION >= 0x010704)
|
||||
struct in_addr a4;
|
||||
|
||||
if((!local_ip4) || (local_ip4[0] == 0)) {
|
||||
a4.s_addr = 0; /* disabled: do not bind to a specific address */
|
||||
}
|
||||
else {
|
||||
if(Curl_inet_pton(AF_INET, local_ip4, &a4) != 1) {
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
}
|
||||
}
|
||||
|
||||
ares_set_local_ip4((ares_channel)data->state.resolver, ntohl(a4.s_addr));
|
||||
|
||||
return CURLE_OK;
|
||||
#else /* c-ares version too old! */
|
||||
(void)data;
|
||||
(void)local_ip4;
|
||||
return CURLE_NOT_BUILT_IN;
|
||||
#endif
|
||||
}
|
||||
|
||||
CURLcode Curl_set_dns_local_ip6(struct Curl_easy *data,
|
||||
const char *local_ip6)
|
||||
{
|
||||
#if (ARES_VERSION >= 0x010704) && defined(ENABLE_IPV6)
|
||||
unsigned char a6[INET6_ADDRSTRLEN];
|
||||
|
||||
if((!local_ip6) || (local_ip6[0] == 0)) {
|
||||
/* disabled: do not bind to a specific address */
|
||||
memset(a6, 0, sizeof(a6));
|
||||
}
|
||||
else {
|
||||
if(Curl_inet_pton(AF_INET6, local_ip6, a6) != 1) {
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
}
|
||||
}
|
||||
|
||||
ares_set_local_ip6((ares_channel)data->state.resolver, a6);
|
||||
|
||||
return CURLE_OK;
|
||||
#else /* c-ares version too old! */
|
||||
(void)data;
|
||||
(void)local_ip6;
|
||||
return CURLE_NOT_BUILT_IN;
|
||||
#endif
|
||||
}
|
||||
#endif /* CURLRES_ARES */
|
760
src/dependencies/cmcurl/lib/asyn-thread.c
Normal file
760
src/dependencies/cmcurl/lib/asyn-thread.c
Normal file
|
@ -0,0 +1,760 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
/***********************************************************************
|
||||
* Only for threaded name resolves builds
|
||||
**********************************************************************/
|
||||
#ifdef CURLRES_THREADED
|
||||
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETDB_H
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#ifdef __VMS
|
||||
#include <in.h>
|
||||
#include <inet.h>
|
||||
#endif
|
||||
|
||||
#if defined(USE_THREADS_POSIX)
|
||||
# ifdef HAVE_PTHREAD_H
|
||||
# include <pthread.h>
|
||||
# endif
|
||||
#elif defined(USE_THREADS_WIN32)
|
||||
# ifdef HAVE_PROCESS_H
|
||||
# include <process.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
|
||||
#undef in_addr_t
|
||||
#define in_addr_t unsigned long
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GETADDRINFO
|
||||
# define RESOLVER_ENOMEM EAI_MEMORY
|
||||
#else
|
||||
# define RESOLVER_ENOMEM ENOMEM
|
||||
#endif
|
||||
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
#include "hostip.h"
|
||||
#include "hash.h"
|
||||
#include "share.h"
|
||||
#include "strerror.h"
|
||||
#include "url.h"
|
||||
#include "multiif.h"
|
||||
#include "inet_pton.h"
|
||||
#include "inet_ntop.h"
|
||||
#include "curl_threads.h"
|
||||
#include "connect.h"
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
struct resdata {
|
||||
struct curltime start;
|
||||
};
|
||||
|
||||
/*
|
||||
* Curl_resolver_global_init()
|
||||
* Called from curl_global_init() to initialize global resolver environment.
|
||||
* Does nothing here.
|
||||
*/
|
||||
int Curl_resolver_global_init(void)
|
||||
{
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_resolver_global_cleanup()
|
||||
* Called from curl_global_cleanup() to destroy global resolver environment.
|
||||
* Does nothing here.
|
||||
*/
|
||||
void Curl_resolver_global_cleanup(void)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_resolver_init()
|
||||
* Called from curl_easy_init() -> Curl_open() to initialize resolver
|
||||
* URL-state specific environment ('resolver' member of the UrlState
|
||||
* structure).
|
||||
*/
|
||||
CURLcode Curl_resolver_init(struct Curl_easy *easy, void **resolver)
|
||||
{
|
||||
(void)easy;
|
||||
*resolver = calloc(1, sizeof(struct resdata));
|
||||
if(!*resolver)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_resolver_cleanup()
|
||||
* Called from curl_easy_cleanup() -> Curl_close() to cleanup resolver
|
||||
* URL-state specific environment ('resolver' member of the UrlState
|
||||
* structure).
|
||||
*/
|
||||
void Curl_resolver_cleanup(void *resolver)
|
||||
{
|
||||
free(resolver);
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_resolver_duphandle()
|
||||
* Called from curl_easy_duphandle() to duplicate resolver URL state-specific
|
||||
* environment ('resolver' member of the UrlState structure).
|
||||
*/
|
||||
CURLcode Curl_resolver_duphandle(struct Curl_easy *easy, void **to, void *from)
|
||||
{
|
||||
(void)from;
|
||||
return Curl_resolver_init(easy, to);
|
||||
}
|
||||
|
||||
static void destroy_async_data(struct Curl_async *);
|
||||
|
||||
/*
|
||||
* Cancel all possibly still on-going resolves for this connection.
|
||||
*/
|
||||
void Curl_resolver_cancel(struct connectdata *conn)
|
||||
{
|
||||
destroy_async_data(&conn->async);
|
||||
}
|
||||
|
||||
/* This function is used to init a threaded resolve */
|
||||
static bool init_resolve_thread(struct connectdata *conn,
|
||||
const char *hostname, int port,
|
||||
const struct addrinfo *hints);
|
||||
|
||||
|
||||
/* Data for synchronization between resolver thread and its parent */
|
||||
struct thread_sync_data {
|
||||
curl_mutex_t * mtx;
|
||||
int done;
|
||||
|
||||
char *hostname; /* hostname to resolve, Curl_async.hostname
|
||||
duplicate */
|
||||
int port;
|
||||
int sock_error;
|
||||
Curl_addrinfo *res;
|
||||
#ifdef HAVE_GETADDRINFO
|
||||
struct addrinfo hints;
|
||||
#endif
|
||||
struct thread_data *td; /* for thread-self cleanup */
|
||||
};
|
||||
|
||||
struct thread_data {
|
||||
curl_thread_t thread_hnd;
|
||||
unsigned int poll_interval;
|
||||
time_t interval_end;
|
||||
struct thread_sync_data tsd;
|
||||
};
|
||||
|
||||
static struct thread_sync_data *conn_thread_sync_data(struct connectdata *conn)
|
||||
{
|
||||
return &(((struct thread_data *)conn->async.os_specific)->tsd);
|
||||
}
|
||||
|
||||
/* Destroy resolver thread synchronization data */
|
||||
static
|
||||
void destroy_thread_sync_data(struct thread_sync_data * tsd)
|
||||
{
|
||||
if(tsd->mtx) {
|
||||
Curl_mutex_destroy(tsd->mtx);
|
||||
free(tsd->mtx);
|
||||
}
|
||||
|
||||
free(tsd->hostname);
|
||||
|
||||
if(tsd->res)
|
||||
Curl_freeaddrinfo(tsd->res);
|
||||
|
||||
memset(tsd, 0, sizeof(*tsd));
|
||||
}
|
||||
|
||||
/* Initialize resolver thread synchronization data */
|
||||
static
|
||||
int init_thread_sync_data(struct thread_data * td,
|
||||
const char *hostname,
|
||||
int port,
|
||||
const struct addrinfo *hints)
|
||||
{
|
||||
struct thread_sync_data *tsd = &td->tsd;
|
||||
|
||||
memset(tsd, 0, sizeof(*tsd));
|
||||
|
||||
tsd->td = td;
|
||||
tsd->port = port;
|
||||
/* Treat the request as done until the thread actually starts so any early
|
||||
* cleanup gets done properly.
|
||||
*/
|
||||
tsd->done = 1;
|
||||
#ifdef HAVE_GETADDRINFO
|
||||
DEBUGASSERT(hints);
|
||||
tsd->hints = *hints;
|
||||
#else
|
||||
(void) hints;
|
||||
#endif
|
||||
|
||||
tsd->mtx = malloc(sizeof(curl_mutex_t));
|
||||
if(tsd->mtx == NULL)
|
||||
goto err_exit;
|
||||
|
||||
Curl_mutex_init(tsd->mtx);
|
||||
|
||||
tsd->sock_error = CURL_ASYNC_SUCCESS;
|
||||
|
||||
/* Copying hostname string because original can be destroyed by parent
|
||||
* thread during gethostbyname execution.
|
||||
*/
|
||||
tsd->hostname = strdup(hostname);
|
||||
if(!tsd->hostname)
|
||||
goto err_exit;
|
||||
|
||||
return 1;
|
||||
|
||||
err_exit:
|
||||
/* Memory allocation failed */
|
||||
destroy_thread_sync_data(tsd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int getaddrinfo_complete(struct connectdata *conn)
|
||||
{
|
||||
struct thread_sync_data *tsd = conn_thread_sync_data(conn);
|
||||
int rc;
|
||||
|
||||
rc = Curl_addrinfo_callback(conn, tsd->sock_error, tsd->res);
|
||||
/* The tsd->res structure has been copied to async.dns and perhaps the DNS
|
||||
cache. Set our copy to NULL so destroy_thread_sync_data doesn't free it.
|
||||
*/
|
||||
tsd->res = NULL;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_GETADDRINFO
|
||||
|
||||
/*
|
||||
* getaddrinfo_thread() resolves a name and then exits.
|
||||
*
|
||||
* For builds without ARES, but with ENABLE_IPV6, create a resolver thread
|
||||
* and wait on it.
|
||||
*/
|
||||
static unsigned int CURL_STDCALL getaddrinfo_thread(void *arg)
|
||||
{
|
||||
struct thread_sync_data *tsd = (struct thread_sync_data*)arg;
|
||||
struct thread_data *td = tsd->td;
|
||||
char service[12];
|
||||
int rc;
|
||||
|
||||
msnprintf(service, sizeof(service), "%d", tsd->port);
|
||||
|
||||
rc = Curl_getaddrinfo_ex(tsd->hostname, service, &tsd->hints, &tsd->res);
|
||||
|
||||
if(rc != 0) {
|
||||
tsd->sock_error = SOCKERRNO?SOCKERRNO:rc;
|
||||
if(tsd->sock_error == 0)
|
||||
tsd->sock_error = RESOLVER_ENOMEM;
|
||||
}
|
||||
else {
|
||||
Curl_addrinfo_set_port(tsd->res, tsd->port);
|
||||
}
|
||||
|
||||
Curl_mutex_acquire(tsd->mtx);
|
||||
if(tsd->done) {
|
||||
/* too late, gotta clean up the mess */
|
||||
Curl_mutex_release(tsd->mtx);
|
||||
destroy_thread_sync_data(tsd);
|
||||
free(td);
|
||||
}
|
||||
else {
|
||||
tsd->done = 1;
|
||||
Curl_mutex_release(tsd->mtx);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else /* HAVE_GETADDRINFO */
|
||||
|
||||
/*
|
||||
* gethostbyname_thread() resolves a name and then exits.
|
||||
*/
|
||||
static unsigned int CURL_STDCALL gethostbyname_thread(void *arg)
|
||||
{
|
||||
struct thread_sync_data *tsd = (struct thread_sync_data *)arg;
|
||||
struct thread_data *td = tsd->td;
|
||||
|
||||
tsd->res = Curl_ipv4_resolve_r(tsd->hostname, tsd->port);
|
||||
|
||||
if(!tsd->res) {
|
||||
tsd->sock_error = SOCKERRNO;
|
||||
if(tsd->sock_error == 0)
|
||||
tsd->sock_error = RESOLVER_ENOMEM;
|
||||
}
|
||||
|
||||
Curl_mutex_acquire(tsd->mtx);
|
||||
if(tsd->done) {
|
||||
/* too late, gotta clean up the mess */
|
||||
Curl_mutex_release(tsd->mtx);
|
||||
destroy_thread_sync_data(tsd);
|
||||
free(td);
|
||||
}
|
||||
else {
|
||||
tsd->done = 1;
|
||||
Curl_mutex_release(tsd->mtx);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* HAVE_GETADDRINFO */
|
||||
|
||||
/*
|
||||
* destroy_async_data() cleans up async resolver data and thread handle.
|
||||
*/
|
||||
static void destroy_async_data(struct Curl_async *async)
|
||||
{
|
||||
if(async->os_specific) {
|
||||
struct thread_data *td = (struct thread_data*) async->os_specific;
|
||||
int done;
|
||||
|
||||
/*
|
||||
* if the thread is still blocking in the resolve syscall, detach it and
|
||||
* let the thread do the cleanup...
|
||||
*/
|
||||
Curl_mutex_acquire(td->tsd.mtx);
|
||||
done = td->tsd.done;
|
||||
td->tsd.done = 1;
|
||||
Curl_mutex_release(td->tsd.mtx);
|
||||
|
||||
if(!done) {
|
||||
Curl_thread_destroy(td->thread_hnd);
|
||||
}
|
||||
else {
|
||||
if(td->thread_hnd != curl_thread_t_null)
|
||||
Curl_thread_join(&td->thread_hnd);
|
||||
|
||||
destroy_thread_sync_data(&td->tsd);
|
||||
|
||||
free(async->os_specific);
|
||||
}
|
||||
}
|
||||
async->os_specific = NULL;
|
||||
|
||||
free(async->hostname);
|
||||
async->hostname = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* init_resolve_thread() starts a new thread that performs the actual
|
||||
* resolve. This function returns before the resolve is done.
|
||||
*
|
||||
* Returns FALSE in case of failure, otherwise TRUE.
|
||||
*/
|
||||
static bool init_resolve_thread(struct connectdata *conn,
|
||||
const char *hostname, int port,
|
||||
const struct addrinfo *hints)
|
||||
{
|
||||
struct thread_data *td = calloc(1, sizeof(struct thread_data));
|
||||
int err = ENOMEM;
|
||||
|
||||
conn->async.os_specific = (void *)td;
|
||||
if(!td)
|
||||
goto errno_exit;
|
||||
|
||||
conn->async.port = port;
|
||||
conn->async.done = FALSE;
|
||||
conn->async.status = 0;
|
||||
conn->async.dns = NULL;
|
||||
td->thread_hnd = curl_thread_t_null;
|
||||
|
||||
if(!init_thread_sync_data(td, hostname, port, hints)) {
|
||||
conn->async.os_specific = NULL;
|
||||
free(td);
|
||||
goto errno_exit;
|
||||
}
|
||||
|
||||
free(conn->async.hostname);
|
||||
conn->async.hostname = strdup(hostname);
|
||||
if(!conn->async.hostname)
|
||||
goto err_exit;
|
||||
|
||||
/* The thread will set this to 1 when complete. */
|
||||
td->tsd.done = 0;
|
||||
|
||||
#ifdef HAVE_GETADDRINFO
|
||||
td->thread_hnd = Curl_thread_create(getaddrinfo_thread, &td->tsd);
|
||||
#else
|
||||
td->thread_hnd = Curl_thread_create(gethostbyname_thread, &td->tsd);
|
||||
#endif
|
||||
|
||||
if(!td->thread_hnd) {
|
||||
/* The thread never started, so mark it as done here for proper cleanup. */
|
||||
td->tsd.done = 1;
|
||||
err = errno;
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
||||
err_exit:
|
||||
destroy_async_data(&conn->async);
|
||||
|
||||
errno_exit:
|
||||
errno = err;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* resolver_error() calls failf() with the appropriate message after a resolve
|
||||
* error
|
||||
*/
|
||||
|
||||
static CURLcode resolver_error(struct connectdata *conn)
|
||||
{
|
||||
const char *host_or_proxy;
|
||||
CURLcode result;
|
||||
|
||||
if(conn->bits.httpproxy) {
|
||||
host_or_proxy = "proxy";
|
||||
result = CURLE_COULDNT_RESOLVE_PROXY;
|
||||
}
|
||||
else {
|
||||
host_or_proxy = "host";
|
||||
result = CURLE_COULDNT_RESOLVE_HOST;
|
||||
}
|
||||
|
||||
failf(conn->data, "Could not resolve %s: %s", host_or_proxy,
|
||||
conn->async.hostname);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static CURLcode thread_wait_resolv(struct connectdata *conn,
|
||||
struct Curl_dns_entry **entry,
|
||||
bool report)
|
||||
{
|
||||
struct thread_data *td = (struct thread_data*) conn->async.os_specific;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
DEBUGASSERT(conn && td);
|
||||
DEBUGASSERT(td->thread_hnd != curl_thread_t_null);
|
||||
|
||||
/* wait for the thread to resolve the name */
|
||||
if(Curl_thread_join(&td->thread_hnd)) {
|
||||
if(entry)
|
||||
result = getaddrinfo_complete(conn);
|
||||
}
|
||||
else
|
||||
DEBUGASSERT(0);
|
||||
|
||||
conn->async.done = TRUE;
|
||||
|
||||
if(entry)
|
||||
*entry = conn->async.dns;
|
||||
|
||||
if(!conn->async.dns && report)
|
||||
/* a name was not resolved, report error */
|
||||
result = resolver_error(conn);
|
||||
|
||||
destroy_async_data(&conn->async);
|
||||
|
||||
if(!conn->async.dns && report)
|
||||
connclose(conn, "asynch resolve failed");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Until we gain a way to signal the resolver threads to stop early, we must
|
||||
* simply wait for them and ignore their results.
|
||||
*/
|
||||
void Curl_resolver_kill(struct connectdata *conn)
|
||||
{
|
||||
struct thread_data *td = (struct thread_data*) conn->async.os_specific;
|
||||
|
||||
/* If we're still resolving, we must wait for the threads to fully clean up,
|
||||
unfortunately. Otherwise, we can simply cancel to clean up any resolver
|
||||
data. */
|
||||
if(td && td->thread_hnd != curl_thread_t_null)
|
||||
(void)thread_wait_resolv(conn, NULL, FALSE);
|
||||
else
|
||||
Curl_resolver_cancel(conn);
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_resolver_wait_resolv()
|
||||
*
|
||||
* Waits for a resolve to finish. This function should be avoided since using
|
||||
* this risk getting the multi interface to "hang".
|
||||
*
|
||||
* If 'entry' is non-NULL, make it point to the resolved dns entry
|
||||
*
|
||||
* Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved,
|
||||
* CURLE_OPERATION_TIMEDOUT if a time-out occurred, or other errors.
|
||||
*
|
||||
* This is the version for resolves-in-a-thread.
|
||||
*/
|
||||
CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
|
||||
struct Curl_dns_entry **entry)
|
||||
{
|
||||
return thread_wait_resolv(conn, entry, TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_resolver_is_resolved() is called repeatedly to check if a previous
|
||||
* name resolve request has completed. It should also make sure to time-out if
|
||||
* the operation seems to take too long.
|
||||
*/
|
||||
CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
|
||||
struct Curl_dns_entry **entry)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct thread_data *td = (struct thread_data*) conn->async.os_specific;
|
||||
int done = 0;
|
||||
|
||||
*entry = NULL;
|
||||
|
||||
if(!td) {
|
||||
DEBUGASSERT(td);
|
||||
return CURLE_COULDNT_RESOLVE_HOST;
|
||||
}
|
||||
|
||||
Curl_mutex_acquire(td->tsd.mtx);
|
||||
done = td->tsd.done;
|
||||
Curl_mutex_release(td->tsd.mtx);
|
||||
|
||||
if(done) {
|
||||
getaddrinfo_complete(conn);
|
||||
|
||||
if(!conn->async.dns) {
|
||||
CURLcode result = resolver_error(conn);
|
||||
destroy_async_data(&conn->async);
|
||||
return result;
|
||||
}
|
||||
destroy_async_data(&conn->async);
|
||||
*entry = conn->async.dns;
|
||||
}
|
||||
else {
|
||||
/* poll for name lookup done with exponential backoff up to 250ms */
|
||||
timediff_t elapsed = Curl_timediff(Curl_now(),
|
||||
data->progress.t_startsingle);
|
||||
if(elapsed < 0)
|
||||
elapsed = 0;
|
||||
|
||||
if(td->poll_interval == 0)
|
||||
/* Start at 1ms poll interval */
|
||||
td->poll_interval = 1;
|
||||
else if(elapsed >= td->interval_end)
|
||||
/* Back-off exponentially if last interval expired */
|
||||
td->poll_interval *= 2;
|
||||
|
||||
if(td->poll_interval > 250)
|
||||
td->poll_interval = 250;
|
||||
|
||||
td->interval_end = elapsed + td->poll_interval;
|
||||
Curl_expire(conn->data, td->poll_interval, EXPIRE_ASYNC_NAME);
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
int Curl_resolver_getsock(struct connectdata *conn,
|
||||
curl_socket_t *socks,
|
||||
int numsocks)
|
||||
{
|
||||
time_t milli;
|
||||
timediff_t ms;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct resdata *reslv = (struct resdata *)data->state.resolver;
|
||||
(void)socks;
|
||||
(void)numsocks;
|
||||
ms = Curl_timediff(Curl_now(), reslv->start);
|
||||
if(ms < 3)
|
||||
milli = 0;
|
||||
else if(ms <= 50)
|
||||
milli = ms/3;
|
||||
else if(ms <= 250)
|
||||
milli = 50;
|
||||
else
|
||||
milli = 200;
|
||||
Curl_expire(data, milli, EXPIRE_ASYNC_NAME);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef HAVE_GETADDRINFO
|
||||
/*
|
||||
* Curl_getaddrinfo() - for platforms without getaddrinfo
|
||||
*/
|
||||
Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
||||
const char *hostname,
|
||||
int port,
|
||||
int *waitp)
|
||||
{
|
||||
struct in_addr in;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct resdata *reslv = (struct resdata *)data->state.resolver;
|
||||
|
||||
*waitp = 0; /* default to synchronous response */
|
||||
|
||||
if(Curl_inet_pton(AF_INET, hostname, &in) > 0)
|
||||
/* This is a dotted IP address 123.123.123.123-style */
|
||||
return Curl_ip2addr(AF_INET, &in, hostname, port);
|
||||
|
||||
reslv->start = Curl_now();
|
||||
|
||||
/* fire up a new resolver thread! */
|
||||
if(init_resolve_thread(conn, hostname, port, NULL)) {
|
||||
*waitp = 1; /* expect asynchronous response */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
failf(conn->data, "getaddrinfo() thread failed\n");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#else /* !HAVE_GETADDRINFO */
|
||||
|
||||
/*
|
||||
* Curl_resolver_getaddrinfo() - for getaddrinfo
|
||||
*/
|
||||
Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
||||
const char *hostname,
|
||||
int port,
|
||||
int *waitp)
|
||||
{
|
||||
struct addrinfo hints;
|
||||
char sbuf[12];
|
||||
int pf = PF_INET;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct resdata *reslv = (struct resdata *)data->state.resolver;
|
||||
|
||||
*waitp = 0; /* default to synchronous response */
|
||||
|
||||
#ifndef USE_RESOLVE_ON_IPS
|
||||
{
|
||||
struct in_addr in;
|
||||
/* First check if this is an IPv4 address string */
|
||||
if(Curl_inet_pton(AF_INET, hostname, &in) > 0)
|
||||
/* This is a dotted IP address 123.123.123.123-style */
|
||||
return Curl_ip2addr(AF_INET, &in, hostname, port);
|
||||
}
|
||||
#ifdef CURLRES_IPV6
|
||||
{
|
||||
struct in6_addr in6;
|
||||
/* check if this is an IPv6 address string */
|
||||
if(Curl_inet_pton(AF_INET6, hostname, &in6) > 0)
|
||||
/* This is an IPv6 address literal */
|
||||
return Curl_ip2addr(AF_INET6, &in6, hostname, port);
|
||||
}
|
||||
#endif /* CURLRES_IPV6 */
|
||||
#endif /* !USE_RESOLVE_ON_IPS */
|
||||
|
||||
#ifdef CURLRES_IPV6
|
||||
/*
|
||||
* Check if a limited name resolve has been requested.
|
||||
*/
|
||||
switch(conn->ip_version) {
|
||||
case CURL_IPRESOLVE_V4:
|
||||
pf = PF_INET;
|
||||
break;
|
||||
case CURL_IPRESOLVE_V6:
|
||||
pf = PF_INET6;
|
||||
break;
|
||||
default:
|
||||
pf = PF_UNSPEC;
|
||||
break;
|
||||
}
|
||||
|
||||
if((pf != PF_INET) && !Curl_ipv6works())
|
||||
/* The stack seems to be a non-IPv6 one */
|
||||
pf = PF_INET;
|
||||
#endif /* CURLRES_IPV6 */
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = pf;
|
||||
hints.ai_socktype = conn->socktype;
|
||||
|
||||
msnprintf(sbuf, sizeof(sbuf), "%d", port);
|
||||
|
||||
reslv->start = Curl_now();
|
||||
/* fire up a new resolver thread! */
|
||||
if(init_resolve_thread(conn, hostname, port, &hints)) {
|
||||
*waitp = 1; /* expect asynchronous response */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
failf(data, "getaddrinfo() thread failed to start\n");
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
#endif /* !HAVE_GETADDRINFO */
|
||||
|
||||
CURLcode Curl_set_dns_servers(struct Curl_easy *data,
|
||||
char *servers)
|
||||
{
|
||||
(void)data;
|
||||
(void)servers;
|
||||
return CURLE_NOT_BUILT_IN;
|
||||
|
||||
}
|
||||
|
||||
CURLcode Curl_set_dns_interface(struct Curl_easy *data,
|
||||
const char *interf)
|
||||
{
|
||||
(void)data;
|
||||
(void)interf;
|
||||
return CURLE_NOT_BUILT_IN;
|
||||
}
|
||||
|
||||
CURLcode Curl_set_dns_local_ip4(struct Curl_easy *data,
|
||||
const char *local_ip4)
|
||||
{
|
||||
(void)data;
|
||||
(void)local_ip4;
|
||||
return CURLE_NOT_BUILT_IN;
|
||||
}
|
||||
|
||||
CURLcode Curl_set_dns_local_ip6(struct Curl_easy *data,
|
||||
const char *local_ip6)
|
||||
{
|
||||
(void)data;
|
||||
(void)local_ip6;
|
||||
return CURLE_NOT_BUILT_IN;
|
||||
}
|
||||
|
||||
#endif /* CURLRES_THREADED */
|
184
src/dependencies/cmcurl/lib/asyn.h
Normal file
184
src/dependencies/cmcurl/lib/asyn.h
Normal file
|
@ -0,0 +1,184 @@
|
|||
#ifndef HEADER_CURL_ASYN_H
|
||||
#define HEADER_CURL_ASYN_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
#include "curl_addrinfo.h"
|
||||
|
||||
struct addrinfo;
|
||||
struct hostent;
|
||||
struct Curl_easy;
|
||||
struct connectdata;
|
||||
struct Curl_dns_entry;
|
||||
|
||||
/*
|
||||
* This header defines all functions in the internal asynch resolver interface.
|
||||
* All asynch resolvers need to provide these functions.
|
||||
* asyn-ares.c and asyn-thread.c are the current implementations of asynch
|
||||
* resolver backends.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Curl_resolver_global_init()
|
||||
*
|
||||
* Called from curl_global_init() to initialize global resolver environment.
|
||||
* Returning anything else than CURLE_OK fails curl_global_init().
|
||||
*/
|
||||
int Curl_resolver_global_init(void);
|
||||
|
||||
/*
|
||||
* Curl_resolver_global_cleanup()
|
||||
* Called from curl_global_cleanup() to destroy global resolver environment.
|
||||
*/
|
||||
void Curl_resolver_global_cleanup(void);
|
||||
|
||||
/*
|
||||
* Curl_resolver_init()
|
||||
* Called from curl_easy_init() -> Curl_open() to initialize resolver
|
||||
* URL-state specific environment ('resolver' member of the UrlState
|
||||
* structure). Should fill the passed pointer by the initialized handler.
|
||||
* Returning anything else than CURLE_OK fails curl_easy_init() with the
|
||||
* correspondent code.
|
||||
*/
|
||||
CURLcode Curl_resolver_init(struct Curl_easy *easy, void **resolver);
|
||||
|
||||
/*
|
||||
* Curl_resolver_cleanup()
|
||||
* Called from curl_easy_cleanup() -> Curl_close() to cleanup resolver
|
||||
* URL-state specific environment ('resolver' member of the UrlState
|
||||
* structure). Should destroy the handler and free all resources connected to
|
||||
* it.
|
||||
*/
|
||||
void Curl_resolver_cleanup(void *resolver);
|
||||
|
||||
/*
|
||||
* Curl_resolver_duphandle()
|
||||
* Called from curl_easy_duphandle() to duplicate resolver URL-state specific
|
||||
* environment ('resolver' member of the UrlState structure). Should
|
||||
* duplicate the 'from' handle and pass the resulting handle to the 'to'
|
||||
* pointer. Returning anything else than CURLE_OK causes failed
|
||||
* curl_easy_duphandle() call.
|
||||
*/
|
||||
CURLcode Curl_resolver_duphandle(struct Curl_easy *easy, void **to,
|
||||
void *from);
|
||||
|
||||
/*
|
||||
* Curl_resolver_cancel().
|
||||
*
|
||||
* It is called from inside other functions to cancel currently performing
|
||||
* resolver request. Should also free any temporary resources allocated to
|
||||
* perform a request. This never waits for resolver threads to complete.
|
||||
*
|
||||
* It is safe to call this when conn is in any state.
|
||||
*/
|
||||
void Curl_resolver_cancel(struct connectdata *conn);
|
||||
|
||||
/*
|
||||
* Curl_resolver_kill().
|
||||
*
|
||||
* This acts like Curl_resolver_cancel() except it will block until any threads
|
||||
* associated with the resolver are complete. This never blocks for resolvers
|
||||
* that do not use threads. This is intended to be the "last chance" function
|
||||
* that cleans up an in-progress resolver completely (before its owner is about
|
||||
* to die).
|
||||
*
|
||||
* It is safe to call this when conn is in any state.
|
||||
*/
|
||||
void Curl_resolver_kill(struct connectdata *conn);
|
||||
|
||||
/* Curl_resolver_getsock()
|
||||
*
|
||||
* This function is called from the multi_getsock() function. 'sock' is a
|
||||
* pointer to an array to hold the file descriptors, with 'numsock' being the
|
||||
* size of that array (in number of entries). This function is supposed to
|
||||
* return bitmask indicating what file descriptors (referring to array indexes
|
||||
* in the 'sock' array) to wait for, read/write.
|
||||
*/
|
||||
int Curl_resolver_getsock(struct connectdata *conn, curl_socket_t *sock,
|
||||
int numsocks);
|
||||
|
||||
/*
|
||||
* Curl_resolver_is_resolved()
|
||||
*
|
||||
* Called repeatedly to check if a previous name resolve request has
|
||||
* completed. It should also make sure to time-out if the operation seems to
|
||||
* take too long.
|
||||
*
|
||||
* Returns normal CURLcode errors.
|
||||
*/
|
||||
CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
|
||||
struct Curl_dns_entry **dns);
|
||||
|
||||
/*
|
||||
* Curl_resolver_wait_resolv()
|
||||
*
|
||||
* Waits for a resolve to finish. This function should be avoided since using
|
||||
* this risk getting the multi interface to "hang".
|
||||
*
|
||||
* If 'entry' is non-NULL, make it point to the resolved dns entry
|
||||
*
|
||||
* Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved,
|
||||
* CURLE_OPERATION_TIMEDOUT if a time-out occurred, or other errors.
|
||||
*/
|
||||
CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
|
||||
struct Curl_dns_entry **dnsentry);
|
||||
|
||||
/*
|
||||
* Curl_resolver_getaddrinfo() - when using this resolver
|
||||
*
|
||||
* Returns name information about the given hostname and port number. If
|
||||
* successful, the 'hostent' is returned and the forth argument will point to
|
||||
* memory we need to free after use. That memory *MUST* be freed with
|
||||
* Curl_freeaddrinfo(), nothing else.
|
||||
*
|
||||
* Each resolver backend must of course make sure to return data in the
|
||||
* correct format to comply with this.
|
||||
*/
|
||||
Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
||||
const char *hostname,
|
||||
int port,
|
||||
int *waitp);
|
||||
|
||||
#ifndef CURLRES_ASYNCH
|
||||
/* convert these functions if an asynch resolver isn't used */
|
||||
#define Curl_resolver_cancel(x) Curl_nop_stmt
|
||||
#define Curl_resolver_kill(x) Curl_nop_stmt
|
||||
#define Curl_resolver_is_resolved(x,y) CURLE_COULDNT_RESOLVE_HOST
|
||||
#define Curl_resolver_wait_resolv(x,y) CURLE_COULDNT_RESOLVE_HOST
|
||||
#define Curl_resolver_getsock(x,y,z) 0
|
||||
#define Curl_resolver_duphandle(x,y,z) CURLE_OK
|
||||
#define Curl_resolver_init(x,y) CURLE_OK
|
||||
#define Curl_resolver_global_init() CURLE_OK
|
||||
#define Curl_resolver_global_cleanup() Curl_nop_stmt
|
||||
#define Curl_resolver_cleanup(x) Curl_nop_stmt
|
||||
#endif
|
||||
|
||||
#ifdef CURLRES_ASYNCH
|
||||
#define Curl_resolver_asynch() 1
|
||||
#else
|
||||
#define Curl_resolver_asynch() 0
|
||||
#endif
|
||||
|
||||
|
||||
/********** end of generic resolver interface functions *****************/
|
||||
#endif /* HEADER_CURL_ASYN_H */
|
326
src/dependencies/cmcurl/lib/base64.c
Normal file
326
src/dependencies/cmcurl/lib/base64.c
Normal file
|
@ -0,0 +1,326 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* Base64 encoding/decoding */
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if !defined(CURL_DISABLE_HTTP_AUTH) || defined(USE_LIBSSH2) || \
|
||||
defined(USE_LIBSSH) || !defined(CURL_DISABLE_LDAP) || \
|
||||
!defined(CURL_DISABLE_DOH) || defined(USE_SSL)
|
||||
|
||||
#include "urldata.h" /* for the Curl_easy definition */
|
||||
#include "warnless.h"
|
||||
#include "curl_base64.h"
|
||||
#include "non-ascii.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
/* ---- Base64 Encoding/Decoding Table --- */
|
||||
static const char base64[]=
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
/* The Base 64 encoding with an URL and filename safe alphabet, RFC 4648
|
||||
section 5 */
|
||||
static const char base64url[]=
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
|
||||
|
||||
static size_t decodeQuantum(unsigned char *dest, const char *src)
|
||||
{
|
||||
size_t padding = 0;
|
||||
const char *s, *p;
|
||||
unsigned long i, x = 0;
|
||||
|
||||
for(i = 0, s = src; i < 4; i++, s++) {
|
||||
if(*s == '=') {
|
||||
x = (x << 6);
|
||||
padding++;
|
||||
}
|
||||
else {
|
||||
unsigned long v = 0;
|
||||
p = base64;
|
||||
|
||||
while(*p && (*p != *s)) {
|
||||
v++;
|
||||
p++;
|
||||
}
|
||||
|
||||
if(*p == *s)
|
||||
x = (x << 6) + v;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(padding < 1)
|
||||
dest[2] = curlx_ultouc(x & 0xFFUL);
|
||||
|
||||
x >>= 8;
|
||||
if(padding < 2)
|
||||
dest[1] = curlx_ultouc(x & 0xFFUL);
|
||||
|
||||
x >>= 8;
|
||||
dest[0] = curlx_ultouc(x & 0xFFUL);
|
||||
|
||||
return 3 - padding;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_base64_decode()
|
||||
*
|
||||
* Given a base64 NUL-terminated string at src, decode it and return a
|
||||
* pointer in *outptr to a newly allocated memory area holding decoded
|
||||
* data. Size of decoded data is returned in variable pointed by outlen.
|
||||
*
|
||||
* Returns CURLE_OK on success, otherwise specific error code. Function
|
||||
* output shall not be considered valid unless CURLE_OK is returned.
|
||||
*
|
||||
* When decoded data length is 0, returns NULL in *outptr.
|
||||
*
|
||||
* @unittest: 1302
|
||||
*/
|
||||
CURLcode Curl_base64_decode(const char *src,
|
||||
unsigned char **outptr, size_t *outlen)
|
||||
{
|
||||
size_t srclen = 0;
|
||||
size_t length = 0;
|
||||
size_t padding = 0;
|
||||
size_t i;
|
||||
size_t numQuantums;
|
||||
size_t rawlen = 0;
|
||||
unsigned char *pos;
|
||||
unsigned char *newstr;
|
||||
|
||||
*outptr = NULL;
|
||||
*outlen = 0;
|
||||
srclen = strlen(src);
|
||||
|
||||
/* Check the length of the input string is valid */
|
||||
if(!srclen || srclen % 4)
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
|
||||
/* Find the position of any = padding characters */
|
||||
while((src[length] != '=') && src[length])
|
||||
length++;
|
||||
|
||||
/* A maximum of two = padding characters is allowed */
|
||||
if(src[length] == '=') {
|
||||
padding++;
|
||||
if(src[length + 1] == '=')
|
||||
padding++;
|
||||
}
|
||||
|
||||
/* Check the = padding characters weren't part way through the input */
|
||||
if(length + padding != srclen)
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
|
||||
/* Calculate the number of quantums */
|
||||
numQuantums = srclen / 4;
|
||||
|
||||
/* Calculate the size of the decoded string */
|
||||
rawlen = (numQuantums * 3) - padding;
|
||||
|
||||
/* Allocate our buffer including room for a zero terminator */
|
||||
newstr = malloc(rawlen + 1);
|
||||
if(!newstr)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
pos = newstr;
|
||||
|
||||
/* Decode the quantums */
|
||||
for(i = 0; i < numQuantums; i++) {
|
||||
size_t result = decodeQuantum(pos, src);
|
||||
if(!result) {
|
||||
free(newstr);
|
||||
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
}
|
||||
|
||||
pos += result;
|
||||
src += 4;
|
||||
}
|
||||
|
||||
/* Zero terminate */
|
||||
*pos = '\0';
|
||||
|
||||
/* Return the decoded data */
|
||||
*outptr = newstr;
|
||||
*outlen = rawlen;
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode base64_encode(const char *table64,
|
||||
struct Curl_easy *data,
|
||||
const char *inputbuff, size_t insize,
|
||||
char **outptr, size_t *outlen)
|
||||
{
|
||||
CURLcode result;
|
||||
unsigned char ibuf[3];
|
||||
unsigned char obuf[4];
|
||||
int i;
|
||||
int inputparts;
|
||||
char *output;
|
||||
char *base64data;
|
||||
char *convbuf = NULL;
|
||||
|
||||
const char *indata = inputbuff;
|
||||
|
||||
*outptr = NULL;
|
||||
*outlen = 0;
|
||||
|
||||
if(!insize)
|
||||
insize = strlen(indata);
|
||||
|
||||
#if SIZEOF_SIZE_T == 4
|
||||
if(insize > UINT_MAX/4)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
#endif
|
||||
|
||||
base64data = output = malloc(insize * 4 / 3 + 4);
|
||||
if(!output)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
/*
|
||||
* The base64 data needs to be created using the network encoding
|
||||
* not the host encoding. And we can't change the actual input
|
||||
* so we copy it to a buffer, translate it, and use that instead.
|
||||
*/
|
||||
result = Curl_convert_clone(data, indata, insize, &convbuf);
|
||||
if(result) {
|
||||
free(output);
|
||||
return result;
|
||||
}
|
||||
|
||||
if(convbuf)
|
||||
indata = (char *)convbuf;
|
||||
|
||||
while(insize > 0) {
|
||||
for(i = inputparts = 0; i < 3; i++) {
|
||||
if(insize > 0) {
|
||||
inputparts++;
|
||||
ibuf[i] = (unsigned char) *indata;
|
||||
indata++;
|
||||
insize--;
|
||||
}
|
||||
else
|
||||
ibuf[i] = 0;
|
||||
}
|
||||
|
||||
obuf[0] = (unsigned char) ((ibuf[0] & 0xFC) >> 2);
|
||||
obuf[1] = (unsigned char) (((ibuf[0] & 0x03) << 4) | \
|
||||
((ibuf[1] & 0xF0) >> 4));
|
||||
obuf[2] = (unsigned char) (((ibuf[1] & 0x0F) << 2) | \
|
||||
((ibuf[2] & 0xC0) >> 6));
|
||||
obuf[3] = (unsigned char) (ibuf[2] & 0x3F);
|
||||
|
||||
switch(inputparts) {
|
||||
case 1: /* only one byte read */
|
||||
msnprintf(output, 5, "%c%c==",
|
||||
table64[obuf[0]],
|
||||
table64[obuf[1]]);
|
||||
break;
|
||||
|
||||
case 2: /* two bytes read */
|
||||
msnprintf(output, 5, "%c%c%c=",
|
||||
table64[obuf[0]],
|
||||
table64[obuf[1]],
|
||||
table64[obuf[2]]);
|
||||
break;
|
||||
|
||||
default:
|
||||
msnprintf(output, 5, "%c%c%c%c",
|
||||
table64[obuf[0]],
|
||||
table64[obuf[1]],
|
||||
table64[obuf[2]],
|
||||
table64[obuf[3]]);
|
||||
break;
|
||||
}
|
||||
output += 4;
|
||||
}
|
||||
|
||||
/* Zero terminate */
|
||||
*output = '\0';
|
||||
|
||||
/* Return the pointer to the new data (allocated memory) */
|
||||
*outptr = base64data;
|
||||
|
||||
free(convbuf);
|
||||
|
||||
/* Return the length of the new data */
|
||||
*outlen = strlen(base64data);
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_base64_encode()
|
||||
*
|
||||
* Given a pointer to an input buffer and an input size, encode it and
|
||||
* return a pointer in *outptr to a newly allocated memory area holding
|
||||
* encoded data. Size of encoded data is returned in variable pointed by
|
||||
* outlen.
|
||||
*
|
||||
* Input length of 0 indicates input buffer holds a NUL-terminated string.
|
||||
*
|
||||
* Returns CURLE_OK on success, otherwise specific error code. Function
|
||||
* output shall not be considered valid unless CURLE_OK is returned.
|
||||
*
|
||||
* When encoded data length is 0, returns NULL in *outptr.
|
||||
*
|
||||
* @unittest: 1302
|
||||
*/
|
||||
CURLcode Curl_base64_encode(struct Curl_easy *data,
|
||||
const char *inputbuff, size_t insize,
|
||||
char **outptr, size_t *outlen)
|
||||
{
|
||||
return base64_encode(base64, data, inputbuff, insize, outptr, outlen);
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_base64url_encode()
|
||||
*
|
||||
* Given a pointer to an input buffer and an input size, encode it and
|
||||
* return a pointer in *outptr to a newly allocated memory area holding
|
||||
* encoded data. Size of encoded data is returned in variable pointed by
|
||||
* outlen.
|
||||
*
|
||||
* Input length of 0 indicates input buffer holds a NUL-terminated string.
|
||||
*
|
||||
* Returns CURLE_OK on success, otherwise specific error code. Function
|
||||
* output shall not be considered valid unless CURLE_OK is returned.
|
||||
*
|
||||
* When encoded data length is 0, returns NULL in *outptr.
|
||||
*
|
||||
* @unittest: 1302
|
||||
*/
|
||||
CURLcode Curl_base64url_encode(struct Curl_easy *data,
|
||||
const char *inputbuff, size_t insize,
|
||||
char **outptr, size_t *outlen)
|
||||
{
|
||||
return base64_encode(base64url, data, inputbuff, insize, outptr, outlen);
|
||||
}
|
||||
|
||||
#endif /* no users so disabled */
|
631
src/dependencies/cmcurl/lib/conncache.c
Normal file
631
src/dependencies/cmcurl/lib/conncache.c
Normal file
|
@ -0,0 +1,631 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2012 - 2016, Linus Nielsen Feltzing, <linus@haxx.se>
|
||||
* Copyright (C) 2012 - 2019, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "urldata.h"
|
||||
#include "url.h"
|
||||
#include "progress.h"
|
||||
#include "multiif.h"
|
||||
#include "sendf.h"
|
||||
#include "conncache.h"
|
||||
#include "share.h"
|
||||
#include "sigpipe.h"
|
||||
#include "connect.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#ifdef CURLDEBUG
|
||||
/* the debug versions of these macros make extra certain that the lock is
|
||||
never doubly locked or unlocked */
|
||||
#define CONN_LOCK(x) if((x)->share) { \
|
||||
Curl_share_lock((x), CURL_LOCK_DATA_CONNECT, CURL_LOCK_ACCESS_SINGLE); \
|
||||
DEBUGASSERT(!(x)->state.conncache_lock); \
|
||||
(x)->state.conncache_lock = TRUE; \
|
||||
}
|
||||
|
||||
#define CONN_UNLOCK(x) if((x)->share) { \
|
||||
DEBUGASSERT((x)->state.conncache_lock); \
|
||||
(x)->state.conncache_lock = FALSE; \
|
||||
Curl_share_unlock((x), CURL_LOCK_DATA_CONNECT); \
|
||||
}
|
||||
#else
|
||||
#define CONN_LOCK(x) if((x)->share) \
|
||||
Curl_share_lock((x), CURL_LOCK_DATA_CONNECT, CURL_LOCK_ACCESS_SINGLE)
|
||||
#define CONN_UNLOCK(x) if((x)->share) \
|
||||
Curl_share_unlock((x), CURL_LOCK_DATA_CONNECT)
|
||||
#endif
|
||||
|
||||
static void conn_llist_dtor(void *user, void *element)
|
||||
{
|
||||
struct connectdata *conn = element;
|
||||
(void)user;
|
||||
conn->bundle = NULL;
|
||||
}
|
||||
|
||||
static CURLcode bundle_create(struct Curl_easy *data,
|
||||
struct connectbundle **cb_ptr)
|
||||
{
|
||||
(void)data;
|
||||
DEBUGASSERT(*cb_ptr == NULL);
|
||||
*cb_ptr = malloc(sizeof(struct connectbundle));
|
||||
if(!*cb_ptr)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
(*cb_ptr)->num_connections = 0;
|
||||
(*cb_ptr)->multiuse = BUNDLE_UNKNOWN;
|
||||
|
||||
Curl_llist_init(&(*cb_ptr)->conn_list, (curl_llist_dtor) conn_llist_dtor);
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static void bundle_destroy(struct connectbundle *cb_ptr)
|
||||
{
|
||||
if(!cb_ptr)
|
||||
return;
|
||||
|
||||
Curl_llist_destroy(&cb_ptr->conn_list, NULL);
|
||||
|
||||
free(cb_ptr);
|
||||
}
|
||||
|
||||
/* Add a connection to a bundle */
|
||||
static void bundle_add_conn(struct connectbundle *cb_ptr,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
Curl_llist_insert_next(&cb_ptr->conn_list, cb_ptr->conn_list.tail, conn,
|
||||
&conn->bundle_node);
|
||||
conn->bundle = cb_ptr;
|
||||
cb_ptr->num_connections++;
|
||||
}
|
||||
|
||||
/* Remove a connection from a bundle */
|
||||
static int bundle_remove_conn(struct connectbundle *cb_ptr,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
struct curl_llist_element *curr;
|
||||
|
||||
curr = cb_ptr->conn_list.head;
|
||||
while(curr) {
|
||||
if(curr->ptr == conn) {
|
||||
Curl_llist_remove(&cb_ptr->conn_list, curr, NULL);
|
||||
cb_ptr->num_connections--;
|
||||
conn->bundle = NULL;
|
||||
return 1; /* we removed a handle */
|
||||
}
|
||||
curr = curr->next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void free_bundle_hash_entry(void *freethis)
|
||||
{
|
||||
struct connectbundle *b = (struct connectbundle *) freethis;
|
||||
|
||||
bundle_destroy(b);
|
||||
}
|
||||
|
||||
int Curl_conncache_init(struct conncache *connc, int size)
|
||||
{
|
||||
int rc;
|
||||
|
||||
/* allocate a new easy handle to use when closing cached connections */
|
||||
connc->closure_handle = curl_easy_init();
|
||||
if(!connc->closure_handle)
|
||||
return 1; /* bad */
|
||||
|
||||
rc = Curl_hash_init(&connc->hash, size, Curl_hash_str,
|
||||
Curl_str_key_compare, free_bundle_hash_entry);
|
||||
if(rc) {
|
||||
Curl_close(connc->closure_handle);
|
||||
connc->closure_handle = NULL;
|
||||
}
|
||||
else
|
||||
connc->closure_handle->state.conn_cache = connc;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void Curl_conncache_destroy(struct conncache *connc)
|
||||
{
|
||||
if(connc)
|
||||
Curl_hash_destroy(&connc->hash);
|
||||
}
|
||||
|
||||
/* creates a key to find a bundle for this connection */
|
||||
static void hashkey(struct connectdata *conn, char *buf,
|
||||
size_t len) /* something like 128 is fine */
|
||||
{
|
||||
const char *hostname;
|
||||
|
||||
if(conn->bits.socksproxy)
|
||||
hostname = conn->socks_proxy.host.name;
|
||||
else if(conn->bits.httpproxy)
|
||||
hostname = conn->http_proxy.host.name;
|
||||
else if(conn->bits.conn_to_host)
|
||||
hostname = conn->conn_to_host.name;
|
||||
else
|
||||
hostname = conn->host.name;
|
||||
|
||||
DEBUGASSERT(len > 32);
|
||||
|
||||
/* put the number first so that the hostname gets cut off if too long */
|
||||
msnprintf(buf, len, "%ld%s", conn->port, hostname);
|
||||
}
|
||||
|
||||
void Curl_conncache_unlock(struct Curl_easy *data)
|
||||
{
|
||||
CONN_UNLOCK(data);
|
||||
}
|
||||
|
||||
/* Returns number of connections currently held in the connection cache.
|
||||
Locks/unlocks the cache itself!
|
||||
*/
|
||||
size_t Curl_conncache_size(struct Curl_easy *data)
|
||||
{
|
||||
size_t num;
|
||||
CONN_LOCK(data);
|
||||
num = data->state.conn_cache->num_conn;
|
||||
CONN_UNLOCK(data);
|
||||
return num;
|
||||
}
|
||||
|
||||
/* Returns number of connections currently held in the connections's bundle
|
||||
Locks/unlocks the cache itself!
|
||||
*/
|
||||
size_t Curl_conncache_bundle_size(struct connectdata *conn)
|
||||
{
|
||||
size_t num;
|
||||
CONN_LOCK(conn->data);
|
||||
num = conn->bundle->num_connections;
|
||||
CONN_UNLOCK(conn->data);
|
||||
return num;
|
||||
}
|
||||
|
||||
/* Look up the bundle with all the connections to the same host this
|
||||
connectdata struct is setup to use.
|
||||
|
||||
**NOTE**: When it returns, it holds the connection cache lock! */
|
||||
struct connectbundle *Curl_conncache_find_bundle(struct connectdata *conn,
|
||||
struct conncache *connc)
|
||||
{
|
||||
struct connectbundle *bundle = NULL;
|
||||
CONN_LOCK(conn->data);
|
||||
if(connc) {
|
||||
char key[128];
|
||||
hashkey(conn, key, sizeof(key));
|
||||
bundle = Curl_hash_pick(&connc->hash, key, strlen(key));
|
||||
}
|
||||
|
||||
return bundle;
|
||||
}
|
||||
|
||||
static bool conncache_add_bundle(struct conncache *connc,
|
||||
char *key,
|
||||
struct connectbundle *bundle)
|
||||
{
|
||||
void *p = Curl_hash_add(&connc->hash, key, strlen(key), bundle);
|
||||
|
||||
return p?TRUE:FALSE;
|
||||
}
|
||||
|
||||
static void conncache_remove_bundle(struct conncache *connc,
|
||||
struct connectbundle *bundle)
|
||||
{
|
||||
struct curl_hash_iterator iter;
|
||||
struct curl_hash_element *he;
|
||||
|
||||
if(!connc)
|
||||
return;
|
||||
|
||||
Curl_hash_start_iterate(&connc->hash, &iter);
|
||||
|
||||
he = Curl_hash_next_element(&iter);
|
||||
while(he) {
|
||||
if(he->ptr == bundle) {
|
||||
/* The bundle is destroyed by the hash destructor function,
|
||||
free_bundle_hash_entry() */
|
||||
Curl_hash_delete(&connc->hash, he->key, he->key_len);
|
||||
return;
|
||||
}
|
||||
|
||||
he = Curl_hash_next_element(&iter);
|
||||
}
|
||||
}
|
||||
|
||||
CURLcode Curl_conncache_add_conn(struct conncache *connc,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct connectbundle *bundle;
|
||||
struct connectbundle *new_bundle = NULL;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
/* *find_bundle() locks the connection cache */
|
||||
bundle = Curl_conncache_find_bundle(conn, data->state.conn_cache);
|
||||
if(!bundle) {
|
||||
int rc;
|
||||
char key[128];
|
||||
|
||||
result = bundle_create(data, &new_bundle);
|
||||
if(result) {
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
hashkey(conn, key, sizeof(key));
|
||||
rc = conncache_add_bundle(data->state.conn_cache, key, new_bundle);
|
||||
|
||||
if(!rc) {
|
||||
bundle_destroy(new_bundle);
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto unlock;
|
||||
}
|
||||
bundle = new_bundle;
|
||||
}
|
||||
|
||||
bundle_add_conn(bundle, conn);
|
||||
conn->connection_id = connc->next_connection_id++;
|
||||
connc->num_conn++;
|
||||
|
||||
DEBUGF(infof(conn->data, "Added connection %ld. "
|
||||
"The cache now contains %zu members\n",
|
||||
conn->connection_id, connc->num_conn));
|
||||
|
||||
unlock:
|
||||
CONN_UNLOCK(data);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Removes the connectdata object from the connection cache *and* clears the
|
||||
* ->data pointer association. Pass TRUE/FALSE in the 'lock' argument
|
||||
* depending on if the parent function already holds the lock or not.
|
||||
*/
|
||||
void Curl_conncache_remove_conn(struct Curl_easy *data,
|
||||
struct connectdata *conn, bool lock)
|
||||
{
|
||||
struct connectbundle *bundle = conn->bundle;
|
||||
struct conncache *connc = data->state.conn_cache;
|
||||
|
||||
/* The bundle pointer can be NULL, since this function can be called
|
||||
due to a failed connection attempt, before being added to a bundle */
|
||||
if(bundle) {
|
||||
if(lock) {
|
||||
CONN_LOCK(data);
|
||||
}
|
||||
bundle_remove_conn(bundle, conn);
|
||||
if(bundle->num_connections == 0)
|
||||
conncache_remove_bundle(connc, bundle);
|
||||
conn->bundle = NULL; /* removed from it */
|
||||
if(connc) {
|
||||
connc->num_conn--;
|
||||
DEBUGF(infof(data, "The cache now contains %zu members\n",
|
||||
connc->num_conn));
|
||||
}
|
||||
conn->data = NULL; /* clear the association */
|
||||
if(lock) {
|
||||
CONN_UNLOCK(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* This function iterates the entire connection cache and calls the function
|
||||
func() with the connection pointer as the first argument and the supplied
|
||||
'param' argument as the other.
|
||||
|
||||
The conncache lock is still held when the callback is called. It needs it,
|
||||
so that it can safely continue traversing the lists once the callback
|
||||
returns.
|
||||
|
||||
Returns 1 if the loop was aborted due to the callback's return code.
|
||||
|
||||
Return 0 from func() to continue the loop, return 1 to abort it.
|
||||
*/
|
||||
bool Curl_conncache_foreach(struct Curl_easy *data,
|
||||
struct conncache *connc,
|
||||
void *param,
|
||||
int (*func)(struct connectdata *conn, void *param))
|
||||
{
|
||||
struct curl_hash_iterator iter;
|
||||
struct curl_llist_element *curr;
|
||||
struct curl_hash_element *he;
|
||||
|
||||
if(!connc)
|
||||
return FALSE;
|
||||
|
||||
CONN_LOCK(data);
|
||||
Curl_hash_start_iterate(&connc->hash, &iter);
|
||||
|
||||
he = Curl_hash_next_element(&iter);
|
||||
while(he) {
|
||||
struct connectbundle *bundle;
|
||||
|
||||
bundle = he->ptr;
|
||||
he = Curl_hash_next_element(&iter);
|
||||
|
||||
curr = bundle->conn_list.head;
|
||||
while(curr) {
|
||||
/* Yes, we need to update curr before calling func(), because func()
|
||||
might decide to remove the connection */
|
||||
struct connectdata *conn = curr->ptr;
|
||||
curr = curr->next;
|
||||
|
||||
if(1 == func(conn, param)) {
|
||||
CONN_UNLOCK(data);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
CONN_UNLOCK(data);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Return the first connection found in the cache. Used when closing all
|
||||
connections.
|
||||
|
||||
NOTE: no locking is done here as this is presumably only done when cleaning
|
||||
up a cache!
|
||||
*/
|
||||
static struct connectdata *
|
||||
conncache_find_first_connection(struct conncache *connc)
|
||||
{
|
||||
struct curl_hash_iterator iter;
|
||||
struct curl_hash_element *he;
|
||||
struct connectbundle *bundle;
|
||||
|
||||
Curl_hash_start_iterate(&connc->hash, &iter);
|
||||
|
||||
he = Curl_hash_next_element(&iter);
|
||||
while(he) {
|
||||
struct curl_llist_element *curr;
|
||||
bundle = he->ptr;
|
||||
|
||||
curr = bundle->conn_list.head;
|
||||
if(curr) {
|
||||
return curr->ptr;
|
||||
}
|
||||
|
||||
he = Curl_hash_next_element(&iter);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Give ownership of a connection back to the connection cache. Might
|
||||
* disconnect the oldest existing in there to make space.
|
||||
*
|
||||
* Return TRUE if stored, FALSE if closed.
|
||||
*/
|
||||
bool Curl_conncache_return_conn(struct connectdata *conn)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
/* data->multi->maxconnects can be negative, deal with it. */
|
||||
size_t maxconnects =
|
||||
(data->multi->maxconnects < 0) ? data->multi->num_easy * 4:
|
||||
data->multi->maxconnects;
|
||||
struct connectdata *conn_candidate = NULL;
|
||||
|
||||
conn->data = NULL; /* no owner anymore */
|
||||
conn->lastused = Curl_now(); /* it was used up until now */
|
||||
if(maxconnects > 0 &&
|
||||
Curl_conncache_size(data) > maxconnects) {
|
||||
infof(data, "Connection cache is full, closing the oldest one.\n");
|
||||
|
||||
conn_candidate = Curl_conncache_extract_oldest(data);
|
||||
if(conn_candidate) {
|
||||
/* the winner gets the honour of being disconnected */
|
||||
(void)Curl_disconnect(data, conn_candidate, /* dead_connection */ FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
return (conn_candidate == conn) ? FALSE : TRUE;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* This function finds the connection in the connection bundle that has been
|
||||
* unused for the longest time.
|
||||
*
|
||||
* Does not lock the connection cache!
|
||||
*
|
||||
* Returns the pointer to the oldest idle connection, or NULL if none was
|
||||
* found.
|
||||
*/
|
||||
struct connectdata *
|
||||
Curl_conncache_extract_bundle(struct Curl_easy *data,
|
||||
struct connectbundle *bundle)
|
||||
{
|
||||
struct curl_llist_element *curr;
|
||||
timediff_t highscore = -1;
|
||||
timediff_t score;
|
||||
struct curltime now;
|
||||
struct connectdata *conn_candidate = NULL;
|
||||
struct connectdata *conn;
|
||||
|
||||
(void)data;
|
||||
|
||||
now = Curl_now();
|
||||
|
||||
curr = bundle->conn_list.head;
|
||||
while(curr) {
|
||||
conn = curr->ptr;
|
||||
|
||||
if(!CONN_INUSE(conn) && !conn->data) {
|
||||
/* Set higher score for the age passed since the connection was used */
|
||||
score = Curl_timediff(now, conn->lastused);
|
||||
|
||||
if(score > highscore) {
|
||||
highscore = score;
|
||||
conn_candidate = conn;
|
||||
}
|
||||
}
|
||||
curr = curr->next;
|
||||
}
|
||||
if(conn_candidate) {
|
||||
/* remove it to prevent another thread from nicking it */
|
||||
bundle_remove_conn(bundle, conn_candidate);
|
||||
data->state.conn_cache->num_conn--;
|
||||
DEBUGF(infof(data, "The cache now contains %zu members\n",
|
||||
data->state.conn_cache->num_conn));
|
||||
conn_candidate->data = data; /* associate! */
|
||||
}
|
||||
|
||||
return conn_candidate;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function finds the connection in the connection cache that has been
|
||||
* unused for the longest time and extracts that from the bundle.
|
||||
*
|
||||
* Returns the pointer to the connection, or NULL if none was found.
|
||||
*/
|
||||
struct connectdata *
|
||||
Curl_conncache_extract_oldest(struct Curl_easy *data)
|
||||
{
|
||||
struct conncache *connc = data->state.conn_cache;
|
||||
struct curl_hash_iterator iter;
|
||||
struct curl_llist_element *curr;
|
||||
struct curl_hash_element *he;
|
||||
timediff_t highscore =- 1;
|
||||
timediff_t score;
|
||||
struct curltime now;
|
||||
struct connectdata *conn_candidate = NULL;
|
||||
struct connectbundle *bundle;
|
||||
struct connectbundle *bundle_candidate = NULL;
|
||||
|
||||
now = Curl_now();
|
||||
|
||||
CONN_LOCK(data);
|
||||
Curl_hash_start_iterate(&connc->hash, &iter);
|
||||
|
||||
he = Curl_hash_next_element(&iter);
|
||||
while(he) {
|
||||
struct connectdata *conn;
|
||||
|
||||
bundle = he->ptr;
|
||||
|
||||
curr = bundle->conn_list.head;
|
||||
while(curr) {
|
||||
conn = curr->ptr;
|
||||
|
||||
if(!CONN_INUSE(conn) && !conn->data) {
|
||||
/* Set higher score for the age passed since the connection was used */
|
||||
score = Curl_timediff(now, conn->lastused);
|
||||
|
||||
if(score > highscore) {
|
||||
highscore = score;
|
||||
conn_candidate = conn;
|
||||
bundle_candidate = bundle;
|
||||
}
|
||||
}
|
||||
curr = curr->next;
|
||||
}
|
||||
|
||||
he = Curl_hash_next_element(&iter);
|
||||
}
|
||||
if(conn_candidate) {
|
||||
/* remove it to prevent another thread from nicking it */
|
||||
bundle_remove_conn(bundle_candidate, conn_candidate);
|
||||
connc->num_conn--;
|
||||
DEBUGF(infof(data, "The cache now contains %zu members\n",
|
||||
connc->num_conn));
|
||||
conn_candidate->data = data; /* associate! */
|
||||
}
|
||||
CONN_UNLOCK(data);
|
||||
|
||||
return conn_candidate;
|
||||
}
|
||||
|
||||
void Curl_conncache_close_all_connections(struct conncache *connc)
|
||||
{
|
||||
struct connectdata *conn;
|
||||
|
||||
conn = conncache_find_first_connection(connc);
|
||||
while(conn) {
|
||||
SIGPIPE_VARIABLE(pipe_st);
|
||||
conn->data = connc->closure_handle;
|
||||
|
||||
sigpipe_ignore(conn->data, &pipe_st);
|
||||
/* This will remove the connection from the cache */
|
||||
connclose(conn, "kill all");
|
||||
(void)Curl_disconnect(connc->closure_handle, conn, FALSE);
|
||||
sigpipe_restore(&pipe_st);
|
||||
|
||||
conn = conncache_find_first_connection(connc);
|
||||
}
|
||||
|
||||
if(connc->closure_handle) {
|
||||
SIGPIPE_VARIABLE(pipe_st);
|
||||
sigpipe_ignore(connc->closure_handle, &pipe_st);
|
||||
|
||||
Curl_hostcache_clean(connc->closure_handle,
|
||||
connc->closure_handle->dns.hostcache);
|
||||
Curl_close(connc->closure_handle);
|
||||
sigpipe_restore(&pipe_st);
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Useful for debugging the connection cache */
|
||||
void Curl_conncache_print(struct conncache *connc)
|
||||
{
|
||||
struct curl_hash_iterator iter;
|
||||
struct curl_llist_element *curr;
|
||||
struct curl_hash_element *he;
|
||||
|
||||
if(!connc)
|
||||
return;
|
||||
|
||||
fprintf(stderr, "=Bundle cache=\n");
|
||||
|
||||
Curl_hash_start_iterate(connc->hash, &iter);
|
||||
|
||||
he = Curl_hash_next_element(&iter);
|
||||
while(he) {
|
||||
struct connectbundle *bundle;
|
||||
struct connectdata *conn;
|
||||
|
||||
bundle = he->ptr;
|
||||
|
||||
fprintf(stderr, "%s -", he->key);
|
||||
curr = bundle->conn_list->head;
|
||||
while(curr) {
|
||||
conn = curr->ptr;
|
||||
|
||||
fprintf(stderr, " [%p %d]", (void *)conn, conn->inuse);
|
||||
curr = curr->next;
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
he = Curl_hash_next_element(&iter);
|
||||
}
|
||||
}
|
||||
#endif
|
86
src/dependencies/cmcurl/lib/conncache.h
Normal file
86
src/dependencies/cmcurl/lib/conncache.h
Normal file
|
@ -0,0 +1,86 @@
|
|||
#ifndef HEADER_CURL_CONNCACHE_H
|
||||
#define HEADER_CURL_CONNCACHE_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2015 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2012 - 2014, Linus Nielsen Feltzing, <linus@haxx.se>
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
* All accesses to struct fields and changing of data in the connection cache
|
||||
* and connectbundles must be done with the conncache LOCKED. The cache might
|
||||
* be shared.
|
||||
*/
|
||||
|
||||
struct conncache {
|
||||
struct curl_hash hash;
|
||||
size_t num_conn;
|
||||
long next_connection_id;
|
||||
struct curltime last_cleanup;
|
||||
/* handle used for closing cached connections */
|
||||
struct Curl_easy *closure_handle;
|
||||
};
|
||||
|
||||
#define BUNDLE_NO_MULTIUSE -1
|
||||
#define BUNDLE_UNKNOWN 0 /* initial value */
|
||||
#define BUNDLE_MULTIPLEX 2
|
||||
|
||||
struct connectbundle {
|
||||
int multiuse; /* supports multi-use */
|
||||
size_t num_connections; /* Number of connections in the bundle */
|
||||
struct curl_llist conn_list; /* The connectdata members of the bundle */
|
||||
};
|
||||
|
||||
/* returns 1 on error, 0 is fine */
|
||||
int Curl_conncache_init(struct conncache *, int size);
|
||||
void Curl_conncache_destroy(struct conncache *connc);
|
||||
|
||||
/* return the correct bundle, to a host or a proxy */
|
||||
struct connectbundle *Curl_conncache_find_bundle(struct connectdata *conn,
|
||||
struct conncache *connc);
|
||||
void Curl_conncache_unlock(struct Curl_easy *data);
|
||||
/* returns number of connections currently held in the connection cache */
|
||||
size_t Curl_conncache_size(struct Curl_easy *data);
|
||||
size_t Curl_conncache_bundle_size(struct connectdata *conn);
|
||||
|
||||
bool Curl_conncache_return_conn(struct connectdata *conn);
|
||||
CURLcode Curl_conncache_add_conn(struct conncache *connc,
|
||||
struct connectdata *conn) WARN_UNUSED_RESULT;
|
||||
void Curl_conncache_remove_conn(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
bool lock);
|
||||
bool Curl_conncache_foreach(struct Curl_easy *data,
|
||||
struct conncache *connc,
|
||||
void *param,
|
||||
int (*func)(struct connectdata *conn,
|
||||
void *param));
|
||||
|
||||
struct connectdata *
|
||||
Curl_conncache_find_first_connection(struct conncache *connc);
|
||||
|
||||
struct connectdata *
|
||||
Curl_conncache_extract_bundle(struct Curl_easy *data,
|
||||
struct connectbundle *bundle);
|
||||
struct connectdata *
|
||||
Curl_conncache_extract_oldest(struct Curl_easy *data);
|
||||
void Curl_conncache_close_all_connections(struct conncache *connc);
|
||||
void Curl_conncache_print(struct conncache *connc);
|
||||
|
||||
#endif /* HEADER_CURL_CONNCACHE_H */
|
1462
src/dependencies/cmcurl/lib/connect.c
Normal file
1462
src/dependencies/cmcurl/lib/connect.c
Normal file
File diff suppressed because it is too large
Load diff
144
src/dependencies/cmcurl/lib/connect.h
Normal file
144
src/dependencies/cmcurl/lib/connect.h
Normal file
|
@ -0,0 +1,144 @@
|
|||
#ifndef HEADER_CURL_CONNECT_H
|
||||
#define HEADER_CURL_CONNECT_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
#include "curl_setup.h"
|
||||
|
||||
#include "nonblock.h" /* for curlx_nonblock(), formerly Curl_nonblock() */
|
||||
#include "sockaddr.h"
|
||||
#include "timeval.h"
|
||||
|
||||
CURLcode Curl_is_connected(struct connectdata *conn,
|
||||
int sockindex,
|
||||
bool *connected);
|
||||
|
||||
CURLcode Curl_connecthost(struct connectdata *conn,
|
||||
const struct Curl_dns_entry *host);
|
||||
|
||||
/* generic function that returns how much time there's left to run, according
|
||||
to the timeouts set */
|
||||
timediff_t Curl_timeleft(struct Curl_easy *data,
|
||||
struct curltime *nowp,
|
||||
bool duringconnect);
|
||||
|
||||
#define DEFAULT_CONNECT_TIMEOUT 300000 /* milliseconds == five minutes */
|
||||
|
||||
/*
|
||||
* Used to extract socket and connectdata struct for the most recent
|
||||
* transfer on the given Curl_easy.
|
||||
*
|
||||
* The returned socket will be CURL_SOCKET_BAD in case of failure!
|
||||
*/
|
||||
curl_socket_t Curl_getconnectinfo(struct Curl_easy *data,
|
||||
struct connectdata **connp);
|
||||
|
||||
/*
|
||||
* Check if a connection seems to be alive.
|
||||
*/
|
||||
bool Curl_connalive(struct connectdata *conn);
|
||||
|
||||
#ifdef USE_WINSOCK
|
||||
/* When you run a program that uses the Windows Sockets API, you may
|
||||
experience slow performance when you copy data to a TCP server.
|
||||
|
||||
https://support.microsoft.com/kb/823764
|
||||
|
||||
Work-around: Make the Socket Send Buffer Size Larger Than the Program Send
|
||||
Buffer Size
|
||||
|
||||
*/
|
||||
void Curl_sndbufset(curl_socket_t sockfd);
|
||||
#else
|
||||
#define Curl_sndbufset(y) Curl_nop_stmt
|
||||
#endif
|
||||
|
||||
void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd);
|
||||
void Curl_persistconninfo(struct connectdata *conn);
|
||||
int Curl_closesocket(struct connectdata *conn, curl_socket_t sock);
|
||||
|
||||
/*
|
||||
* The Curl_sockaddr_ex structure is basically libcurl's external API
|
||||
* curl_sockaddr structure with enough space available to directly hold any
|
||||
* protocol-specific address structures. The variable declared here will be
|
||||
* used to pass / receive data to/from the fopensocket callback if this has
|
||||
* been set, before that, it is initialized from parameters.
|
||||
*/
|
||||
struct Curl_sockaddr_ex {
|
||||
int family;
|
||||
int socktype;
|
||||
int protocol;
|
||||
unsigned int addrlen;
|
||||
union {
|
||||
struct sockaddr addr;
|
||||
struct Curl_sockaddr_storage buff;
|
||||
} _sa_ex_u;
|
||||
};
|
||||
#define sa_addr _sa_ex_u.addr
|
||||
|
||||
/*
|
||||
* Create a socket based on info from 'conn' and 'ai'.
|
||||
*
|
||||
* Fill in 'addr' and 'sockfd' accordingly if OK is returned. If the open
|
||||
* socket callback is set, used that!
|
||||
*
|
||||
*/
|
||||
CURLcode Curl_socket(struct connectdata *conn,
|
||||
const Curl_addrinfo *ai,
|
||||
struct Curl_sockaddr_ex *addr,
|
||||
curl_socket_t *sockfd);
|
||||
|
||||
/*
|
||||
* Curl_conncontrol() marks the end of a connection/stream. The 'closeit'
|
||||
* argument specifies if it is the end of a connection or a stream.
|
||||
*
|
||||
* For stream-based protocols (such as HTTP/2), a stream close will not cause
|
||||
* a connection close. Other protocols will close the connection for both
|
||||
* cases.
|
||||
*
|
||||
* It sets the bit.close bit to TRUE (with an explanation for debug builds),
|
||||
* when the connection will close.
|
||||
*/
|
||||
|
||||
#define CONNCTRL_KEEP 0 /* undo a marked closure */
|
||||
#define CONNCTRL_CONNECTION 1
|
||||
#define CONNCTRL_STREAM 2
|
||||
|
||||
void Curl_conncontrol(struct connectdata *conn,
|
||||
int closeit
|
||||
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||
, const char *reason
|
||||
#endif
|
||||
);
|
||||
|
||||
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||
#define streamclose(x,y) Curl_conncontrol(x, CONNCTRL_STREAM, y)
|
||||
#define connclose(x,y) Curl_conncontrol(x, CONNCTRL_CONNECTION, y)
|
||||
#define connkeep(x,y) Curl_conncontrol(x, CONNCTRL_KEEP, y)
|
||||
#else /* if !DEBUGBUILD || CURL_DISABLE_VERBOSE_STRINGS */
|
||||
#define streamclose(x,y) Curl_conncontrol(x, CONNCTRL_STREAM)
|
||||
#define connclose(x,y) Curl_conncontrol(x, CONNCTRL_CONNECTION)
|
||||
#define connkeep(x,y) Curl_conncontrol(x, CONNCTRL_KEEP)
|
||||
#endif
|
||||
|
||||
bool Curl_conn_data_pending(struct connectdata *conn, int sockindex);
|
||||
|
||||
#endif /* HEADER_CURL_CONNECT_H */
|
1020
src/dependencies/cmcurl/lib/content_encoding.c
Normal file
1020
src/dependencies/cmcurl/lib/content_encoding.c
Normal file
File diff suppressed because it is too large
Load diff
55
src/dependencies/cmcurl/lib/content_encoding.h
Normal file
55
src/dependencies/cmcurl/lib/content_encoding.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
#ifndef HEADER_CURL_CONTENT_ENCODING_H
|
||||
#define HEADER_CURL_CONTENT_ENCODING_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2017, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
#include "curl_setup.h"
|
||||
|
||||
/* Decoding writer. */
|
||||
typedef struct contenc_writer_s contenc_writer;
|
||||
typedef struct content_encoding_s content_encoding;
|
||||
|
||||
struct contenc_writer_s {
|
||||
const content_encoding *handler; /* Encoding handler. */
|
||||
contenc_writer *downstream; /* Downstream writer. */
|
||||
void *params; /* Encoding-specific storage (variable length). */
|
||||
};
|
||||
|
||||
/* Content encoding writer. */
|
||||
struct content_encoding_s {
|
||||
const char *name; /* Encoding name. */
|
||||
const char *alias; /* Encoding name alias. */
|
||||
CURLcode (*init_writer)(struct connectdata *conn, contenc_writer *writer);
|
||||
CURLcode (*unencode_write)(struct connectdata *conn, contenc_writer *writer,
|
||||
const char *buf, size_t nbytes);
|
||||
void (*close_writer)(struct connectdata *conn, contenc_writer *writer);
|
||||
size_t paramsize;
|
||||
};
|
||||
|
||||
|
||||
CURLcode Curl_build_unencoding_stack(struct connectdata *conn,
|
||||
const char *enclist, int maybechunked);
|
||||
CURLcode Curl_unencode_write(struct connectdata *conn, contenc_writer *writer,
|
||||
const char *buf, size_t nbytes);
|
||||
void Curl_unencode_cleanup(struct connectdata *conn);
|
||||
char *Curl_all_content_encodings(void);
|
||||
|
||||
#endif /* HEADER_CURL_CONTENT_ENCODING_H */
|
1657
src/dependencies/cmcurl/lib/cookie.c
Normal file
1657
src/dependencies/cmcurl/lib/cookie.c
Normal file
File diff suppressed because it is too large
Load diff
120
src/dependencies/cmcurl/lib/cookie.h
Normal file
120
src/dependencies/cmcurl/lib/cookie.h
Normal file
|
@ -0,0 +1,120 @@
|
|||
#ifndef HEADER_CURL_COOKIE_H
|
||||
#define HEADER_CURL_COOKIE_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
#include "curl_setup.h"
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
struct Cookie {
|
||||
struct Cookie *next; /* next in the chain */
|
||||
char *name; /* <this> = value */
|
||||
char *value; /* name = <this> */
|
||||
char *path; /* path = <this> which is in Set-Cookie: */
|
||||
char *spath; /* sanitized cookie path */
|
||||
char *domain; /* domain = <this> */
|
||||
curl_off_t expires; /* expires = <this> */
|
||||
char *expirestr; /* the plain text version */
|
||||
bool tailmatch; /* whether we do tail-matching of the domain name */
|
||||
|
||||
/* RFC 2109 keywords. Version=1 means 2109-compliant cookie sending */
|
||||
char *version; /* Version = <value> */
|
||||
char *maxage; /* Max-Age = <value> */
|
||||
|
||||
bool secure; /* whether the 'secure' keyword was used */
|
||||
bool livecookie; /* updated from a server, not a stored file */
|
||||
bool httponly; /* true if the httponly directive is present */
|
||||
int creationtime; /* time when the cookie was written */
|
||||
unsigned char prefix; /* bitmap fields indicating which prefix are set */
|
||||
};
|
||||
|
||||
/*
|
||||
* Available cookie prefixes, as defined in
|
||||
* draft-ietf-httpbis-rfc6265bis-02
|
||||
*/
|
||||
#define COOKIE_PREFIX__SECURE (1<<0)
|
||||
#define COOKIE_PREFIX__HOST (1<<1)
|
||||
|
||||
#define COOKIE_HASH_SIZE 256
|
||||
|
||||
struct CookieInfo {
|
||||
/* linked list of cookies we know of */
|
||||
struct Cookie *cookies[COOKIE_HASH_SIZE];
|
||||
|
||||
char *filename; /* file we read from/write to */
|
||||
bool running; /* state info, for cookie adding information */
|
||||
long numcookies; /* number of cookies in the "jar" */
|
||||
bool newsession; /* new session, discard session cookies on load */
|
||||
int lastct; /* last creation-time used in the jar */
|
||||
};
|
||||
|
||||
/* This is the maximum line length we accept for a cookie line. RFC 2109
|
||||
section 6.3 says:
|
||||
|
||||
"at least 4096 bytes per cookie (as measured by the size of the characters
|
||||
that comprise the cookie non-terminal in the syntax description of the
|
||||
Set-Cookie header)"
|
||||
|
||||
We allow max 5000 bytes cookie header. Max 4095 bytes length per cookie
|
||||
name and value. Name + value may not exceed 4096 bytes.
|
||||
|
||||
*/
|
||||
#define MAX_COOKIE_LINE 5000
|
||||
|
||||
/* This is the maximum length of a cookie name or content we deal with: */
|
||||
#define MAX_NAME 4096
|
||||
#define MAX_NAME_TXT "4095"
|
||||
|
||||
struct Curl_easy;
|
||||
/*
|
||||
* Add a cookie to the internal list of cookies. The domain and path arguments
|
||||
* are only used if the header boolean is TRUE.
|
||||
*/
|
||||
|
||||
struct Cookie *Curl_cookie_add(struct Curl_easy *data,
|
||||
struct CookieInfo *, bool header, bool noexpiry,
|
||||
char *lineptr,
|
||||
const char *domain, const char *path,
|
||||
bool secure);
|
||||
|
||||
struct Cookie *Curl_cookie_getlist(struct CookieInfo *, const char *,
|
||||
const char *, bool);
|
||||
void Curl_cookie_freelist(struct Cookie *cookies);
|
||||
void Curl_cookie_clearall(struct CookieInfo *cookies);
|
||||
void Curl_cookie_clearsess(struct CookieInfo *cookies);
|
||||
|
||||
#if defined(CURL_DISABLE_HTTP) || defined(CURL_DISABLE_COOKIES)
|
||||
#define Curl_cookie_list(x) NULL
|
||||
#define Curl_cookie_loadfiles(x) Curl_nop_stmt
|
||||
#define Curl_cookie_init(x,y,z,w) NULL
|
||||
#define Curl_cookie_cleanup(x) Curl_nop_stmt
|
||||
#define Curl_flush_cookies(x,y) Curl_nop_stmt
|
||||
#else
|
||||
void Curl_flush_cookies(struct Curl_easy *data, int cleanup);
|
||||
void Curl_cookie_cleanup(struct CookieInfo *);
|
||||
struct CookieInfo *Curl_cookie_init(struct Curl_easy *data,
|
||||
const char *, struct CookieInfo *, bool);
|
||||
struct curl_slist *Curl_cookie_list(struct Curl_easy *data);
|
||||
void Curl_cookie_loadfiles(struct Curl_easy *data);
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_COOKIE_H */
|
624
src/dependencies/cmcurl/lib/curl_addrinfo.c
Normal file
624
src/dependencies/cmcurl/lib/curl_addrinfo.c
Normal file
|
@ -0,0 +1,624 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
# include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN6_H
|
||||
# include <netinet/in6.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETDB_H
|
||||
# include <netdb.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
# include <arpa/inet.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_UN_H
|
||||
# include <sys/un.h>
|
||||
#endif
|
||||
|
||||
#ifdef __VMS
|
||||
# include <in.h>
|
||||
# include <inet.h>
|
||||
#endif
|
||||
|
||||
#if defined(NETWARE) && defined(__NOVELL_LIBC__)
|
||||
# undef in_addr_t
|
||||
# define in_addr_t unsigned long
|
||||
#endif
|
||||
|
||||
#if defined(WIN32) && defined(USE_UNIX_SOCKETS)
|
||||
#include <afunix.h>
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "curl_addrinfo.h"
|
||||
#include "inet_pton.h"
|
||||
#include "warnless.h"
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
/*
|
||||
* Curl_freeaddrinfo()
|
||||
*
|
||||
* This is used to free a linked list of Curl_addrinfo structs along
|
||||
* with all its associated allocated storage. This function should be
|
||||
* called once for each successful call to Curl_getaddrinfo_ex() or to
|
||||
* any function call which actually allocates a Curl_addrinfo struct.
|
||||
*/
|
||||
|
||||
#if defined(__INTEL_COMPILER) && (__INTEL_COMPILER == 910) && \
|
||||
defined(__OPTIMIZE__) && defined(__unix__) && defined(__i386__)
|
||||
/* workaround icc 9.1 optimizer issue */
|
||||
# define vqualifier volatile
|
||||
#else
|
||||
# define vqualifier
|
||||
#endif
|
||||
|
||||
void
|
||||
Curl_freeaddrinfo(Curl_addrinfo *cahead)
|
||||
{
|
||||
Curl_addrinfo *vqualifier canext;
|
||||
Curl_addrinfo *ca;
|
||||
|
||||
for(ca = cahead; ca != NULL; ca = canext) {
|
||||
free(ca->ai_addr);
|
||||
free(ca->ai_canonname);
|
||||
canext = ca->ai_next;
|
||||
|
||||
free(ca);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_GETADDRINFO
|
||||
/*
|
||||
* Curl_getaddrinfo_ex()
|
||||
*
|
||||
* This is a wrapper function around system's getaddrinfo(), with
|
||||
* the only difference that instead of returning a linked list of
|
||||
* addrinfo structs this one returns a linked list of Curl_addrinfo
|
||||
* ones. The memory allocated by this function *MUST* be free'd with
|
||||
* Curl_freeaddrinfo(). For each successful call to this function
|
||||
* there must be an associated call later to Curl_freeaddrinfo().
|
||||
*
|
||||
* There should be no single call to system's getaddrinfo() in the
|
||||
* whole library, any such call should be 'routed' through this one.
|
||||
*/
|
||||
|
||||
int
|
||||
Curl_getaddrinfo_ex(const char *nodename,
|
||||
const char *servname,
|
||||
const struct addrinfo *hints,
|
||||
Curl_addrinfo **result)
|
||||
{
|
||||
const struct addrinfo *ai;
|
||||
struct addrinfo *aihead;
|
||||
Curl_addrinfo *cafirst = NULL;
|
||||
Curl_addrinfo *calast = NULL;
|
||||
Curl_addrinfo *ca;
|
||||
size_t ss_size;
|
||||
int error;
|
||||
|
||||
*result = NULL; /* assume failure */
|
||||
|
||||
error = getaddrinfo(nodename, servname, hints, &aihead);
|
||||
if(error)
|
||||
return error;
|
||||
|
||||
/* traverse the addrinfo list */
|
||||
|
||||
for(ai = aihead; ai != NULL; ai = ai->ai_next) {
|
||||
|
||||
/* ignore elements with unsupported address family, */
|
||||
/* settle family-specific sockaddr structure size. */
|
||||
if(ai->ai_family == AF_INET)
|
||||
ss_size = sizeof(struct sockaddr_in);
|
||||
#ifdef ENABLE_IPV6
|
||||
else if(ai->ai_family == AF_INET6)
|
||||
ss_size = sizeof(struct sockaddr_in6);
|
||||
#endif
|
||||
else
|
||||
continue;
|
||||
|
||||
/* ignore elements without required address info */
|
||||
if((ai->ai_addr == NULL) || !(ai->ai_addrlen > 0))
|
||||
continue;
|
||||
|
||||
/* ignore elements with bogus address size */
|
||||
if((size_t)ai->ai_addrlen < ss_size)
|
||||
continue;
|
||||
|
||||
ca = malloc(sizeof(Curl_addrinfo));
|
||||
if(!ca) {
|
||||
error = EAI_MEMORY;
|
||||
break;
|
||||
}
|
||||
|
||||
/* copy each structure member individually, member ordering, */
|
||||
/* size, or padding might be different for each platform. */
|
||||
|
||||
ca->ai_flags = ai->ai_flags;
|
||||
ca->ai_family = ai->ai_family;
|
||||
ca->ai_socktype = ai->ai_socktype;
|
||||
ca->ai_protocol = ai->ai_protocol;
|
||||
ca->ai_addrlen = (curl_socklen_t)ss_size;
|
||||
ca->ai_addr = NULL;
|
||||
ca->ai_canonname = NULL;
|
||||
ca->ai_next = NULL;
|
||||
|
||||
ca->ai_addr = malloc(ss_size);
|
||||
if(!ca->ai_addr) {
|
||||
error = EAI_MEMORY;
|
||||
free(ca);
|
||||
break;
|
||||
}
|
||||
memcpy(ca->ai_addr, ai->ai_addr, ss_size);
|
||||
|
||||
if(ai->ai_canonname != NULL) {
|
||||
ca->ai_canonname = strdup(ai->ai_canonname);
|
||||
if(!ca->ai_canonname) {
|
||||
error = EAI_MEMORY;
|
||||
free(ca->ai_addr);
|
||||
free(ca);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* if the return list is empty, this becomes the first element */
|
||||
if(!cafirst)
|
||||
cafirst = ca;
|
||||
|
||||
/* add this element last in the return list */
|
||||
if(calast)
|
||||
calast->ai_next = ca;
|
||||
calast = ca;
|
||||
|
||||
}
|
||||
|
||||
/* destroy the addrinfo list */
|
||||
if(aihead)
|
||||
freeaddrinfo(aihead);
|
||||
|
||||
/* if we failed, also destroy the Curl_addrinfo list */
|
||||
if(error) {
|
||||
Curl_freeaddrinfo(cafirst);
|
||||
cafirst = NULL;
|
||||
}
|
||||
else if(!cafirst) {
|
||||
#ifdef EAI_NONAME
|
||||
/* rfc3493 conformant */
|
||||
error = EAI_NONAME;
|
||||
#else
|
||||
/* rfc3493 obsoleted */
|
||||
error = EAI_NODATA;
|
||||
#endif
|
||||
#ifdef USE_WINSOCK
|
||||
SET_SOCKERRNO(error);
|
||||
#endif
|
||||
}
|
||||
|
||||
*result = cafirst;
|
||||
|
||||
/* This is not a CURLcode */
|
||||
return error;
|
||||
}
|
||||
#endif /* HAVE_GETADDRINFO */
|
||||
|
||||
|
||||
/*
|
||||
* Curl_he2ai()
|
||||
*
|
||||
* This function returns a pointer to the first element of a newly allocated
|
||||
* Curl_addrinfo struct linked list filled with the data of a given hostent.
|
||||
* Curl_addrinfo is meant to work like the addrinfo struct does for a IPv6
|
||||
* stack, but usable also for IPv4, all hosts and environments.
|
||||
*
|
||||
* The memory allocated by this function *MUST* be free'd later on calling
|
||||
* Curl_freeaddrinfo(). For each successful call to this function there
|
||||
* must be an associated call later to Curl_freeaddrinfo().
|
||||
*
|
||||
* Curl_addrinfo defined in "lib/curl_addrinfo.h"
|
||||
*
|
||||
* struct Curl_addrinfo {
|
||||
* int ai_flags;
|
||||
* int ai_family;
|
||||
* int ai_socktype;
|
||||
* int ai_protocol;
|
||||
* curl_socklen_t ai_addrlen; * Follow rfc3493 struct addrinfo *
|
||||
* char *ai_canonname;
|
||||
* struct sockaddr *ai_addr;
|
||||
* struct Curl_addrinfo *ai_next;
|
||||
* };
|
||||
* typedef struct Curl_addrinfo Curl_addrinfo;
|
||||
*
|
||||
* hostent defined in <netdb.h>
|
||||
*
|
||||
* struct hostent {
|
||||
* char *h_name;
|
||||
* char **h_aliases;
|
||||
* int h_addrtype;
|
||||
* int h_length;
|
||||
* char **h_addr_list;
|
||||
* };
|
||||
*
|
||||
* for backward compatibility:
|
||||
*
|
||||
* #define h_addr h_addr_list[0]
|
||||
*/
|
||||
|
||||
Curl_addrinfo *
|
||||
Curl_he2ai(const struct hostent *he, int port)
|
||||
{
|
||||
Curl_addrinfo *ai;
|
||||
Curl_addrinfo *prevai = NULL;
|
||||
Curl_addrinfo *firstai = NULL;
|
||||
struct sockaddr_in *addr;
|
||||
#ifdef ENABLE_IPV6
|
||||
struct sockaddr_in6 *addr6;
|
||||
#endif
|
||||
CURLcode result = CURLE_OK;
|
||||
int i;
|
||||
char *curr;
|
||||
|
||||
if(!he)
|
||||
/* no input == no output! */
|
||||
return NULL;
|
||||
|
||||
DEBUGASSERT((he->h_name != NULL) && (he->h_addr_list != NULL));
|
||||
|
||||
for(i = 0; (curr = he->h_addr_list[i]) != NULL; i++) {
|
||||
|
||||
size_t ss_size;
|
||||
#ifdef ENABLE_IPV6
|
||||
if(he->h_addrtype == AF_INET6)
|
||||
ss_size = sizeof(struct sockaddr_in6);
|
||||
else
|
||||
#endif
|
||||
ss_size = sizeof(struct sockaddr_in);
|
||||
|
||||
ai = calloc(1, sizeof(Curl_addrinfo));
|
||||
if(!ai) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
break;
|
||||
}
|
||||
ai->ai_canonname = strdup(he->h_name);
|
||||
if(!ai->ai_canonname) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
free(ai);
|
||||
break;
|
||||
}
|
||||
ai->ai_addr = calloc(1, ss_size);
|
||||
if(!ai->ai_addr) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
free(ai->ai_canonname);
|
||||
free(ai);
|
||||
break;
|
||||
}
|
||||
|
||||
if(!firstai)
|
||||
/* store the pointer we want to return from this function */
|
||||
firstai = ai;
|
||||
|
||||
if(prevai)
|
||||
/* make the previous entry point to this */
|
||||
prevai->ai_next = ai;
|
||||
|
||||
ai->ai_family = he->h_addrtype;
|
||||
|
||||
/* we return all names as STREAM, so when using this address for TFTP
|
||||
the type must be ignored and conn->socktype be used instead! */
|
||||
ai->ai_socktype = SOCK_STREAM;
|
||||
|
||||
ai->ai_addrlen = (curl_socklen_t)ss_size;
|
||||
|
||||
/* leave the rest of the struct filled with zero */
|
||||
|
||||
switch(ai->ai_family) {
|
||||
case AF_INET:
|
||||
addr = (void *)ai->ai_addr; /* storage area for this info */
|
||||
|
||||
memcpy(&addr->sin_addr, curr, sizeof(struct in_addr));
|
||||
addr->sin_family = (CURL_SA_FAMILY_T)(he->h_addrtype);
|
||||
addr->sin_port = htons((unsigned short)port);
|
||||
break;
|
||||
|
||||
#ifdef ENABLE_IPV6
|
||||
case AF_INET6:
|
||||
addr6 = (void *)ai->ai_addr; /* storage area for this info */
|
||||
|
||||
memcpy(&addr6->sin6_addr, curr, sizeof(struct in6_addr));
|
||||
addr6->sin6_family = (CURL_SA_FAMILY_T)(he->h_addrtype);
|
||||
addr6->sin6_port = htons((unsigned short)port);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
prevai = ai;
|
||||
}
|
||||
|
||||
if(result) {
|
||||
Curl_freeaddrinfo(firstai);
|
||||
firstai = NULL;
|
||||
}
|
||||
|
||||
return firstai;
|
||||
}
|
||||
|
||||
|
||||
struct namebuff {
|
||||
struct hostent hostentry;
|
||||
union {
|
||||
struct in_addr ina4;
|
||||
#ifdef ENABLE_IPV6
|
||||
struct in6_addr ina6;
|
||||
#endif
|
||||
} addrentry;
|
||||
char *h_addr_list[2];
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Curl_ip2addr()
|
||||
*
|
||||
* This function takes an internet address, in binary form, as input parameter
|
||||
* along with its address family and the string version of the address, and it
|
||||
* returns a Curl_addrinfo chain filled in correctly with information for the
|
||||
* given address/host
|
||||
*/
|
||||
|
||||
Curl_addrinfo *
|
||||
Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port)
|
||||
{
|
||||
Curl_addrinfo *ai;
|
||||
|
||||
#if defined(__VMS) && \
|
||||
defined(__INITIAL_POINTER_SIZE) && (__INITIAL_POINTER_SIZE == 64)
|
||||
#pragma pointer_size save
|
||||
#pragma pointer_size short
|
||||
#pragma message disable PTRMISMATCH
|
||||
#endif
|
||||
|
||||
struct hostent *h;
|
||||
struct namebuff *buf;
|
||||
char *addrentry;
|
||||
char *hoststr;
|
||||
size_t addrsize;
|
||||
|
||||
DEBUGASSERT(inaddr && hostname);
|
||||
|
||||
buf = malloc(sizeof(struct namebuff));
|
||||
if(!buf)
|
||||
return NULL;
|
||||
|
||||
hoststr = strdup(hostname);
|
||||
if(!hoststr) {
|
||||
free(buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch(af) {
|
||||
case AF_INET:
|
||||
addrsize = sizeof(struct in_addr);
|
||||
addrentry = (void *)&buf->addrentry.ina4;
|
||||
memcpy(addrentry, inaddr, sizeof(struct in_addr));
|
||||
break;
|
||||
#ifdef ENABLE_IPV6
|
||||
case AF_INET6:
|
||||
addrsize = sizeof(struct in6_addr);
|
||||
addrentry = (void *)&buf->addrentry.ina6;
|
||||
memcpy(addrentry, inaddr, sizeof(struct in6_addr));
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
free(hoststr);
|
||||
free(buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
h = &buf->hostentry;
|
||||
h->h_name = hoststr;
|
||||
h->h_aliases = NULL;
|
||||
h->h_addrtype = (short)af;
|
||||
h->h_length = (short)addrsize;
|
||||
h->h_addr_list = &buf->h_addr_list[0];
|
||||
h->h_addr_list[0] = addrentry;
|
||||
h->h_addr_list[1] = NULL; /* terminate list of entries */
|
||||
|
||||
#if defined(__VMS) && \
|
||||
defined(__INITIAL_POINTER_SIZE) && (__INITIAL_POINTER_SIZE == 64)
|
||||
#pragma pointer_size restore
|
||||
#pragma message enable PTRMISMATCH
|
||||
#endif
|
||||
|
||||
ai = Curl_he2ai(h, port);
|
||||
|
||||
free(hoststr);
|
||||
free(buf);
|
||||
|
||||
return ai;
|
||||
}
|
||||
|
||||
/*
|
||||
* Given an IPv4 or IPv6 dotted string address, this converts it to a proper
|
||||
* allocated Curl_addrinfo struct and returns it.
|
||||
*/
|
||||
Curl_addrinfo *Curl_str2addr(char *address, int port)
|
||||
{
|
||||
struct in_addr in;
|
||||
if(Curl_inet_pton(AF_INET, address, &in) > 0)
|
||||
/* This is a dotted IP address 123.123.123.123-style */
|
||||
return Curl_ip2addr(AF_INET, &in, address, port);
|
||||
#ifdef ENABLE_IPV6
|
||||
{
|
||||
struct in6_addr in6;
|
||||
if(Curl_inet_pton(AF_INET6, address, &in6) > 0)
|
||||
/* This is a dotted IPv6 address ::1-style */
|
||||
return Curl_ip2addr(AF_INET6, &in6, address, port);
|
||||
}
|
||||
#endif
|
||||
return NULL; /* bad input format */
|
||||
}
|
||||
|
||||
#ifdef USE_UNIX_SOCKETS
|
||||
/**
|
||||
* Given a path to a Unix domain socket, return a newly allocated Curl_addrinfo
|
||||
* struct initialized with this path.
|
||||
* Set '*longpath' to TRUE if the error is a too long path.
|
||||
*/
|
||||
Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath, bool abstract)
|
||||
{
|
||||
Curl_addrinfo *ai;
|
||||
struct sockaddr_un *sa_un;
|
||||
size_t path_len;
|
||||
|
||||
*longpath = FALSE;
|
||||
|
||||
ai = calloc(1, sizeof(Curl_addrinfo));
|
||||
if(!ai)
|
||||
return NULL;
|
||||
ai->ai_addr = calloc(1, sizeof(struct sockaddr_un));
|
||||
if(!ai->ai_addr) {
|
||||
free(ai);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sa_un = (void *) ai->ai_addr;
|
||||
sa_un->sun_family = AF_UNIX;
|
||||
|
||||
/* sun_path must be able to store the NUL-terminated path */
|
||||
path_len = strlen(path) + 1;
|
||||
if(path_len > sizeof(sa_un->sun_path)) {
|
||||
free(ai->ai_addr);
|
||||
free(ai);
|
||||
*longpath = TRUE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ai->ai_family = AF_UNIX;
|
||||
ai->ai_socktype = SOCK_STREAM; /* assume reliable transport for HTTP */
|
||||
ai->ai_addrlen = (curl_socklen_t)
|
||||
((offsetof(struct sockaddr_un, sun_path) + path_len) & 0x7FFFFFFF);
|
||||
|
||||
/* Abstract Unix domain socket have NULL prefix instead of suffix */
|
||||
if(abstract)
|
||||
memcpy(sa_un->sun_path + 1, path, path_len - 1);
|
||||
else
|
||||
memcpy(sa_un->sun_path, path, path_len); /* copy NUL byte */
|
||||
|
||||
return ai;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) && \
|
||||
defined(HAVE_FREEADDRINFO)
|
||||
/*
|
||||
* curl_dbg_freeaddrinfo()
|
||||
*
|
||||
* This is strictly for memory tracing and are using the same style as the
|
||||
* family otherwise present in memdebug.c. I put these ones here since they
|
||||
* require a bunch of structs I didn't want to include in memdebug.c
|
||||
*/
|
||||
|
||||
void
|
||||
curl_dbg_freeaddrinfo(struct addrinfo *freethis,
|
||||
int line, const char *source)
|
||||
{
|
||||
curl_dbg_log("ADDR %s:%d freeaddrinfo(%p)\n",
|
||||
source, line, (void *)freethis);
|
||||
#ifdef USE_LWIPSOCK
|
||||
lwip_freeaddrinfo(freethis);
|
||||
#else
|
||||
(freeaddrinfo)(freethis);
|
||||
#endif
|
||||
}
|
||||
#endif /* defined(CURLDEBUG) && defined(HAVE_FREEADDRINFO) */
|
||||
|
||||
|
||||
#if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO)
|
||||
/*
|
||||
* curl_dbg_getaddrinfo()
|
||||
*
|
||||
* This is strictly for memory tracing and are using the same style as the
|
||||
* family otherwise present in memdebug.c. I put these ones here since they
|
||||
* require a bunch of structs I didn't want to include in memdebug.c
|
||||
*/
|
||||
|
||||
int
|
||||
curl_dbg_getaddrinfo(const char *hostname,
|
||||
const char *service,
|
||||
const struct addrinfo *hints,
|
||||
struct addrinfo **result,
|
||||
int line, const char *source)
|
||||
{
|
||||
#ifdef USE_LWIPSOCK
|
||||
int res = lwip_getaddrinfo(hostname, service, hints, result);
|
||||
#else
|
||||
int res = (getaddrinfo)(hostname, service, hints, result);
|
||||
#endif
|
||||
if(0 == res)
|
||||
/* success */
|
||||
curl_dbg_log("ADDR %s:%d getaddrinfo() = %p\n",
|
||||
source, line, (void *)*result);
|
||||
else
|
||||
curl_dbg_log("ADDR %s:%d getaddrinfo() failed\n",
|
||||
source, line);
|
||||
return res;
|
||||
}
|
||||
#endif /* defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) */
|
||||
|
||||
#if defined(HAVE_GETADDRINFO) && defined(USE_RESOLVE_ON_IPS)
|
||||
/*
|
||||
* Work-arounds the sin6_port is always zero bug on iOS 9.3.2 and Mac OS X
|
||||
* 10.11.5.
|
||||
*/
|
||||
void Curl_addrinfo_set_port(Curl_addrinfo *addrinfo, int port)
|
||||
{
|
||||
Curl_addrinfo *ca;
|
||||
struct sockaddr_in *addr;
|
||||
#ifdef ENABLE_IPV6
|
||||
struct sockaddr_in6 *addr6;
|
||||
#endif
|
||||
for(ca = addrinfo; ca != NULL; ca = ca->ai_next) {
|
||||
switch(ca->ai_family) {
|
||||
case AF_INET:
|
||||
addr = (void *)ca->ai_addr; /* storage area for this info */
|
||||
addr->sin_port = htons((unsigned short)port);
|
||||
break;
|
||||
|
||||
#ifdef ENABLE_IPV6
|
||||
case AF_INET6:
|
||||
addr6 = (void *)ca->ai_addr; /* storage area for this info */
|
||||
addr6->sin6_port = htons((unsigned short)port);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
107
src/dependencies/cmcurl/lib/curl_addrinfo.h
Normal file
107
src/dependencies/cmcurl/lib/curl_addrinfo.h
Normal file
|
@ -0,0 +1,107 @@
|
|||
#ifndef HEADER_CURL_ADDRINFO_H
|
||||
#define HEADER_CURL_ADDRINFO_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
# include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETDB_H
|
||||
# include <netdb.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
# include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#ifdef __VMS
|
||||
# include <in.h>
|
||||
# include <inet.h>
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Curl_addrinfo is our internal struct definition that we use to allow
|
||||
* consistent internal handling of this data. We use this even when the
|
||||
* system provides an addrinfo structure definition. And we use this for
|
||||
* all sorts of IPv4 and IPV6 builds.
|
||||
*/
|
||||
|
||||
struct Curl_addrinfo {
|
||||
int ai_flags;
|
||||
int ai_family;
|
||||
int ai_socktype;
|
||||
int ai_protocol;
|
||||
curl_socklen_t ai_addrlen; /* Follow rfc3493 struct addrinfo */
|
||||
char *ai_canonname;
|
||||
struct sockaddr *ai_addr;
|
||||
struct Curl_addrinfo *ai_next;
|
||||
};
|
||||
typedef struct Curl_addrinfo Curl_addrinfo;
|
||||
|
||||
void
|
||||
Curl_freeaddrinfo(Curl_addrinfo *cahead);
|
||||
|
||||
#ifdef HAVE_GETADDRINFO
|
||||
int
|
||||
Curl_getaddrinfo_ex(const char *nodename,
|
||||
const char *servname,
|
||||
const struct addrinfo *hints,
|
||||
Curl_addrinfo **result);
|
||||
#endif
|
||||
|
||||
Curl_addrinfo *
|
||||
Curl_he2ai(const struct hostent *he, int port);
|
||||
|
||||
Curl_addrinfo *
|
||||
Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port);
|
||||
|
||||
Curl_addrinfo *Curl_str2addr(char *dotted, int port);
|
||||
|
||||
#ifdef USE_UNIX_SOCKETS
|
||||
Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath, bool abstract);
|
||||
#endif
|
||||
|
||||
#if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) && \
|
||||
defined(HAVE_FREEADDRINFO)
|
||||
void
|
||||
curl_dbg_freeaddrinfo(struct addrinfo *freethis, int line, const char *source);
|
||||
#endif
|
||||
|
||||
#if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO)
|
||||
int
|
||||
curl_dbg_getaddrinfo(const char *hostname, const char *service,
|
||||
const struct addrinfo *hints, struct addrinfo **result,
|
||||
int line, const char *source);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GETADDRINFO
|
||||
#ifdef USE_RESOLVE_ON_IPS
|
||||
void Curl_addrinfo_set_port(Curl_addrinfo *addrinfo, int port);
|
||||
#else
|
||||
#define Curl_addrinfo_set_port(x,y)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_ADDRINFO_H */
|
35
src/dependencies/cmcurl/lib/curl_base64.h
Normal file
35
src/dependencies/cmcurl/lib/curl_base64.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
#ifndef HEADER_CURL_BASE64_H
|
||||
#define HEADER_CURL_BASE64_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
CURLcode Curl_base64_encode(struct Curl_easy *data,
|
||||
const char *inputbuff, size_t insize,
|
||||
char **outptr, size_t *outlen);
|
||||
CURLcode Curl_base64url_encode(struct Curl_easy *data,
|
||||
const char *inputbuff, size_t insize,
|
||||
char **outptr, size_t *outlen);
|
||||
|
||||
CURLcode Curl_base64_decode(const char *src,
|
||||
unsigned char **outptr, size_t *outlen);
|
||||
|
||||
#endif /* HEADER_CURL_BASE64_H */
|
1024
src/dependencies/cmcurl/lib/curl_config.h.cmake
Normal file
1024
src/dependencies/cmcurl/lib/curl_config.h.cmake
Normal file
File diff suppressed because it is too large
Load diff
133
src/dependencies/cmcurl/lib/curl_ctype.c
Normal file
133
src/dependencies/cmcurl/lib/curl_ctype.c
Normal file
|
@ -0,0 +1,133 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#ifndef CURL_DOES_CONVERSIONS
|
||||
|
||||
#undef _U
|
||||
#define _U (1<<0) /* upper case */
|
||||
#undef _L
|
||||
#define _L (1<<1) /* lower case */
|
||||
#undef _N
|
||||
#define _N (1<<2) /* decimal numerical digit */
|
||||
#undef _S
|
||||
#define _S (1<<3) /* space */
|
||||
#undef _P
|
||||
#define _P (1<<4) /* punctuation */
|
||||
#undef _C
|
||||
#define _C (1<<5) /* control */
|
||||
#undef _X
|
||||
#define _X (1<<6) /* hexadecimal letter */
|
||||
#undef _B
|
||||
#define _B (1<<7) /* blank */
|
||||
|
||||
static const unsigned char ascii[128] = {
|
||||
_C, _C, _C, _C, _C, _C, _C, _C,
|
||||
_C, _C|_S, _C|_S, _C|_S, _C|_S, _C|_S, _C, _C,
|
||||
_C, _C, _C, _C, _C, _C, _C, _C,
|
||||
_C, _C, _C, _C, _C, _C, _C, _C,
|
||||
_S|_B, _P, _P, _P, _P, _P, _P, _P,
|
||||
_P, _P, _P, _P, _P, _P, _P, _P,
|
||||
_N, _N, _N, _N, _N, _N, _N, _N,
|
||||
_N, _N, _P, _P, _P, _P, _P, _P,
|
||||
_P, _U|_X, _U|_X, _U|_X, _U|_X, _U|_X, _U|_X, _U,
|
||||
_U, _U, _U, _U, _U, _U, _U, _U,
|
||||
_U, _U, _U, _U, _U, _U, _U, _U,
|
||||
_U, _U, _U, _P, _P, _P, _P, _P,
|
||||
_P, _L|_X, _L|_X, _L|_X, _L|_X, _L|_X, _L|_X, _L,
|
||||
_L, _L, _L, _L, _L, _L, _L, _L,
|
||||
_L, _L, _L, _L, _L, _L, _L, _L,
|
||||
_L, _L, _L, _P, _P, _P, _P, _C
|
||||
};
|
||||
|
||||
int Curl_isspace(int c)
|
||||
{
|
||||
if((c < 0) || (c >= 0x80))
|
||||
return FALSE;
|
||||
return (ascii[c] & _S);
|
||||
}
|
||||
|
||||
int Curl_isdigit(int c)
|
||||
{
|
||||
if((c < 0) || (c >= 0x80))
|
||||
return FALSE;
|
||||
return (ascii[c] & _N);
|
||||
}
|
||||
|
||||
int Curl_isalnum(int c)
|
||||
{
|
||||
if((c < 0) || (c >= 0x80))
|
||||
return FALSE;
|
||||
return (ascii[c] & (_N|_U|_L));
|
||||
}
|
||||
|
||||
int Curl_isxdigit(int c)
|
||||
{
|
||||
if((c < 0) || (c >= 0x80))
|
||||
return FALSE;
|
||||
return (ascii[c] & (_N|_X));
|
||||
}
|
||||
|
||||
int Curl_isgraph(int c)
|
||||
{
|
||||
if((c < 0) || (c >= 0x80) || (c == ' '))
|
||||
return FALSE;
|
||||
return (ascii[c] & (_N|_X|_U|_L|_P|_S));
|
||||
}
|
||||
|
||||
int Curl_isprint(int c)
|
||||
{
|
||||
if((c < 0) || (c >= 0x80))
|
||||
return FALSE;
|
||||
return (ascii[c] & (_N|_X|_U|_L|_P|_S));
|
||||
}
|
||||
|
||||
int Curl_isalpha(int c)
|
||||
{
|
||||
if((c < 0) || (c >= 0x80))
|
||||
return FALSE;
|
||||
return (ascii[c] & (_U|_L));
|
||||
}
|
||||
|
||||
int Curl_isupper(int c)
|
||||
{
|
||||
if((c < 0) || (c >= 0x80))
|
||||
return FALSE;
|
||||
return (ascii[c] & (_U));
|
||||
}
|
||||
|
||||
int Curl_islower(int c)
|
||||
{
|
||||
if((c < 0) || (c >= 0x80))
|
||||
return FALSE;
|
||||
return (ascii[c] & (_L));
|
||||
}
|
||||
|
||||
int Curl_iscntrl(int c)
|
||||
{
|
||||
if((c < 0) || (c >= 0x80))
|
||||
return FALSE;
|
||||
return (ascii[c] & (_C));
|
||||
}
|
||||
|
||||
#endif /* !CURL_DOES_CONVERSIONS */
|
81
src/dependencies/cmcurl/lib/curl_ctype.h
Normal file
81
src/dependencies/cmcurl/lib/curl_ctype.h
Normal file
|
@ -0,0 +1,81 @@
|
|||
#ifndef HEADER_CURL_CTYPE_H
|
||||
#define HEADER_CURL_CTYPE_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
|
||||
/*
|
||||
* Uppercase macro versions of ANSI/ISO is*() functions/macros which
|
||||
* avoid negative number inputs with argument byte codes > 127.
|
||||
*
|
||||
* For non-ASCII platforms the C library character classification routines
|
||||
* are used despite being locale-dependent, because this is better than
|
||||
* not to work at all.
|
||||
*/
|
||||
#include <ctype.h>
|
||||
|
||||
#define ISSPACE(x) (isspace((int) ((unsigned char)x)))
|
||||
#define ISDIGIT(x) (isdigit((int) ((unsigned char)x)))
|
||||
#define ISALNUM(x) (isalnum((int) ((unsigned char)x)))
|
||||
#define ISXDIGIT(x) (isxdigit((int) ((unsigned char)x)))
|
||||
#define ISGRAPH(x) (isgraph((int) ((unsigned char)x)))
|
||||
#define ISALPHA(x) (isalpha((int) ((unsigned char)x)))
|
||||
#define ISPRINT(x) (isprint((int) ((unsigned char)x)))
|
||||
#define ISUPPER(x) (isupper((int) ((unsigned char)x)))
|
||||
#define ISLOWER(x) (islower((int) ((unsigned char)x)))
|
||||
#define ISCNTRL(x) (iscntrl((int) ((unsigned char)x)))
|
||||
#define ISASCII(x) (isascii((int) ((unsigned char)x)))
|
||||
|
||||
#else
|
||||
|
||||
int Curl_isspace(int c);
|
||||
int Curl_isdigit(int c);
|
||||
int Curl_isalnum(int c);
|
||||
int Curl_isxdigit(int c);
|
||||
int Curl_isgraph(int c);
|
||||
int Curl_isprint(int c);
|
||||
int Curl_isalpha(int c);
|
||||
int Curl_isupper(int c);
|
||||
int Curl_islower(int c);
|
||||
int Curl_iscntrl(int c);
|
||||
|
||||
#define ISSPACE(x) (Curl_isspace((int) ((unsigned char)x)))
|
||||
#define ISDIGIT(x) (Curl_isdigit((int) ((unsigned char)x)))
|
||||
#define ISALNUM(x) (Curl_isalnum((int) ((unsigned char)x)))
|
||||
#define ISXDIGIT(x) (Curl_isxdigit((int) ((unsigned char)x)))
|
||||
#define ISGRAPH(x) (Curl_isgraph((int) ((unsigned char)x)))
|
||||
#define ISALPHA(x) (Curl_isalpha((int) ((unsigned char)x)))
|
||||
#define ISPRINT(x) (Curl_isprint((int) ((unsigned char)x)))
|
||||
#define ISUPPER(x) (Curl_isupper((int) ((unsigned char)x)))
|
||||
#define ISLOWER(x) (Curl_islower((int) ((unsigned char)x)))
|
||||
#define ISCNTRL(x) (Curl_iscntrl((int) ((unsigned char)x)))
|
||||
#define ISASCII(x) (((x) >= 0) && ((x) <= 0x80))
|
||||
|
||||
#endif
|
||||
|
||||
#define ISBLANK(x) (int)((((unsigned char)x) == ' ') || \
|
||||
(((unsigned char)x) == '\t'))
|
||||
|
||||
#endif /* HEADER_CURL_CTYPE_H */
|
63
src/dependencies/cmcurl/lib/curl_des.c
Normal file
63
src/dependencies/cmcurl/lib/curl_des.c
Normal file
|
@ -0,0 +1,63 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2015, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if defined(USE_NTLM) && !defined(USE_OPENSSL)
|
||||
|
||||
#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 engines doesn't have it's own version.
|
||||
*
|
||||
* The function is a port of the Java based oddParity() function over at:
|
||||
*
|
||||
* https://davenport.sourceforge.io/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 /* USE_NTLM && !USE_OPENSSL */
|
34
src/dependencies/cmcurl/lib/curl_des.h
Normal file
34
src/dependencies/cmcurl/lib/curl_des.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
#ifndef HEADER_CURL_DES_H
|
||||
#define HEADER_CURL_DES_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2015, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if defined(USE_NTLM) && !defined(USE_OPENSSL)
|
||||
|
||||
/* Applies odd parity to the given byte array */
|
||||
void Curl_des_set_odd_parity(unsigned char *bytes, size_t length);
|
||||
|
||||
#endif /* USE_NTLM && !USE_OPENSSL */
|
||||
|
||||
#endif /* HEADER_CURL_DES_H */
|
124
src/dependencies/cmcurl/lib/curl_endian.c
Normal file
124
src/dependencies/cmcurl/lib/curl_endian.c
Normal file
|
@ -0,0 +1,124 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#include "curl_endian.h"
|
||||
|
||||
/*
|
||||
* Curl_read16_le()
|
||||
*
|
||||
* This function converts a 16-bit integer from the little endian format, as
|
||||
* used in the incoming package to whatever endian format we're using
|
||||
* natively.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* buf [in] - A pointer to a 2 byte buffer.
|
||||
*
|
||||
* Returns the integer.
|
||||
*/
|
||||
unsigned short Curl_read16_le(const unsigned char *buf)
|
||||
{
|
||||
return (unsigned short)(((unsigned short)buf[0]) |
|
||||
((unsigned short)buf[1] << 8));
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_read32_le()
|
||||
*
|
||||
* This function converts a 32-bit integer from the little endian format, as
|
||||
* used in the incoming package to whatever endian format we're using
|
||||
* natively.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* buf [in] - A pointer to a 4 byte buffer.
|
||||
*
|
||||
* Returns the integer.
|
||||
*/
|
||||
unsigned int Curl_read32_le(const unsigned char *buf)
|
||||
{
|
||||
return ((unsigned int)buf[0]) | ((unsigned int)buf[1] << 8) |
|
||||
((unsigned int)buf[2] << 16) | ((unsigned int)buf[3] << 24);
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_read16_be()
|
||||
*
|
||||
* This function converts a 16-bit integer from the big endian format, as
|
||||
* used in the incoming package to whatever endian format we're using
|
||||
* natively.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* buf [in] - A pointer to a 2 byte buffer.
|
||||
*
|
||||
* Returns the integer.
|
||||
*/
|
||||
unsigned short Curl_read16_be(const unsigned char *buf)
|
||||
{
|
||||
return (unsigned short)(((unsigned short)buf[0] << 8) |
|
||||
((unsigned short)buf[1]));
|
||||
}
|
||||
|
||||
/*
|
||||
* write32_le()
|
||||
*
|
||||
* This function converts a 32-bit integer from the native endian format,
|
||||
* to little endian format ready for sending down the wire.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* value [in] - The 32-bit integer value.
|
||||
* buffer [in] - A pointer to the output buffer.
|
||||
*/
|
||||
static void write32_le(const int value, unsigned char *buffer)
|
||||
{
|
||||
buffer[0] = (char)(value & 0x000000FF);
|
||||
buffer[1] = (char)((value & 0x0000FF00) >> 8);
|
||||
buffer[2] = (char)((value & 0x00FF0000) >> 16);
|
||||
buffer[3] = (char)((value & 0xFF000000) >> 24);
|
||||
}
|
||||
|
||||
#if (CURL_SIZEOF_CURL_OFF_T > 4)
|
||||
/*
|
||||
* Curl_write64_le()
|
||||
*
|
||||
* This function converts a 64-bit integer from the native endian format,
|
||||
* to little endian format ready for sending down the wire.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* value [in] - The 64-bit integer value.
|
||||
* buffer [in] - A pointer to the output buffer.
|
||||
*/
|
||||
#if defined(HAVE_LONGLONG)
|
||||
void Curl_write64_le(const long long value, unsigned char *buffer)
|
||||
#else
|
||||
void Curl_write64_le(const __int64 value, unsigned char *buffer)
|
||||
#endif
|
||||
{
|
||||
write32_le((int)value, buffer);
|
||||
write32_le((int)(value >> 32), buffer + 4);
|
||||
}
|
||||
#endif /* CURL_SIZEOF_CURL_OFF_T > 4 */
|
46
src/dependencies/cmcurl/lib/curl_endian.h
Normal file
46
src/dependencies/cmcurl/lib/curl_endian.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
#ifndef HEADER_CURL_ENDIAN_H
|
||||
#define HEADER_CURL_ENDIAN_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2017, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* Converts a 16-bit integer from little endian */
|
||||
unsigned short Curl_read16_le(const unsigned char *buf);
|
||||
|
||||
/* Converts a 32-bit integer from little endian */
|
||||
unsigned int Curl_read32_le(const unsigned char *buf);
|
||||
|
||||
/* Converts a 16-bit integer from big endian */
|
||||
unsigned short Curl_read16_be(const unsigned char *buf);
|
||||
|
||||
/* Converts a 32-bit integer to little endian */
|
||||
void Curl_write32_le(const int value, unsigned char *buffer);
|
||||
|
||||
#if (CURL_SIZEOF_CURL_OFF_T > 4)
|
||||
/* Converts a 64-bit integer to little endian */
|
||||
#if defined(HAVE_LONGLONG)
|
||||
void Curl_write64_le(const long long value, unsigned char *buffer);
|
||||
#else
|
||||
void Curl_write64_le(const __int64 value, unsigned char *buffer);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_ENDIAN_H */
|
389
src/dependencies/cmcurl/lib/curl_fnmatch.c
Normal file
389
src/dependencies/cmcurl/lib/curl_fnmatch.c
Normal file
|
@ -0,0 +1,389 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
#ifndef CURL_DISABLE_FTP
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "curl_fnmatch.h"
|
||||
#include "curl_memory.h"
|
||||
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
#ifndef HAVE_FNMATCH
|
||||
|
||||
#define CURLFNM_CHARSET_LEN (sizeof(char) * 256)
|
||||
#define CURLFNM_CHSET_SIZE (CURLFNM_CHARSET_LEN + 15)
|
||||
|
||||
#define CURLFNM_NEGATE CURLFNM_CHARSET_LEN
|
||||
|
||||
#define CURLFNM_ALNUM (CURLFNM_CHARSET_LEN + 1)
|
||||
#define CURLFNM_DIGIT (CURLFNM_CHARSET_LEN + 2)
|
||||
#define CURLFNM_XDIGIT (CURLFNM_CHARSET_LEN + 3)
|
||||
#define CURLFNM_ALPHA (CURLFNM_CHARSET_LEN + 4)
|
||||
#define CURLFNM_PRINT (CURLFNM_CHARSET_LEN + 5)
|
||||
#define CURLFNM_BLANK (CURLFNM_CHARSET_LEN + 6)
|
||||
#define CURLFNM_LOWER (CURLFNM_CHARSET_LEN + 7)
|
||||
#define CURLFNM_GRAPH (CURLFNM_CHARSET_LEN + 8)
|
||||
#define CURLFNM_SPACE (CURLFNM_CHARSET_LEN + 9)
|
||||
#define CURLFNM_UPPER (CURLFNM_CHARSET_LEN + 10)
|
||||
|
||||
typedef enum {
|
||||
CURLFNM_SCHS_DEFAULT = 0,
|
||||
CURLFNM_SCHS_RIGHTBR,
|
||||
CURLFNM_SCHS_RIGHTBRLEFTBR
|
||||
} setcharset_state;
|
||||
|
||||
typedef enum {
|
||||
CURLFNM_PKW_INIT = 0,
|
||||
CURLFNM_PKW_DDOT
|
||||
} parsekey_state;
|
||||
|
||||
typedef enum {
|
||||
CCLASS_OTHER = 0,
|
||||
CCLASS_DIGIT,
|
||||
CCLASS_UPPER,
|
||||
CCLASS_LOWER
|
||||
} char_class;
|
||||
|
||||
#define SETCHARSET_OK 1
|
||||
#define SETCHARSET_FAIL 0
|
||||
|
||||
static int parsekeyword(unsigned char **pattern, unsigned char *charset)
|
||||
{
|
||||
parsekey_state state = CURLFNM_PKW_INIT;
|
||||
#define KEYLEN 10
|
||||
char keyword[KEYLEN] = { 0 };
|
||||
int found = FALSE;
|
||||
int i;
|
||||
unsigned char *p = *pattern;
|
||||
for(i = 0; !found; i++) {
|
||||
char c = *p++;
|
||||
if(i >= KEYLEN)
|
||||
return SETCHARSET_FAIL;
|
||||
switch(state) {
|
||||
case CURLFNM_PKW_INIT:
|
||||
if(ISLOWER(c))
|
||||
keyword[i] = c;
|
||||
else if(c == ':')
|
||||
state = CURLFNM_PKW_DDOT;
|
||||
else
|
||||
return SETCHARSET_FAIL;
|
||||
break;
|
||||
case CURLFNM_PKW_DDOT:
|
||||
if(c == ']')
|
||||
found = TRUE;
|
||||
else
|
||||
return SETCHARSET_FAIL;
|
||||
}
|
||||
}
|
||||
#undef KEYLEN
|
||||
|
||||
*pattern = p; /* move caller's pattern pointer */
|
||||
if(strcmp(keyword, "digit") == 0)
|
||||
charset[CURLFNM_DIGIT] = 1;
|
||||
else if(strcmp(keyword, "alnum") == 0)
|
||||
charset[CURLFNM_ALNUM] = 1;
|
||||
else if(strcmp(keyword, "alpha") == 0)
|
||||
charset[CURLFNM_ALPHA] = 1;
|
||||
else if(strcmp(keyword, "xdigit") == 0)
|
||||
charset[CURLFNM_XDIGIT] = 1;
|
||||
else if(strcmp(keyword, "print") == 0)
|
||||
charset[CURLFNM_PRINT] = 1;
|
||||
else if(strcmp(keyword, "graph") == 0)
|
||||
charset[CURLFNM_GRAPH] = 1;
|
||||
else if(strcmp(keyword, "space") == 0)
|
||||
charset[CURLFNM_SPACE] = 1;
|
||||
else if(strcmp(keyword, "blank") == 0)
|
||||
charset[CURLFNM_BLANK] = 1;
|
||||
else if(strcmp(keyword, "upper") == 0)
|
||||
charset[CURLFNM_UPPER] = 1;
|
||||
else if(strcmp(keyword, "lower") == 0)
|
||||
charset[CURLFNM_LOWER] = 1;
|
||||
else
|
||||
return SETCHARSET_FAIL;
|
||||
return SETCHARSET_OK;
|
||||
}
|
||||
|
||||
/* Return the character class. */
|
||||
static char_class charclass(unsigned char c)
|
||||
{
|
||||
if(ISUPPER(c))
|
||||
return CCLASS_UPPER;
|
||||
if(ISLOWER(c))
|
||||
return CCLASS_LOWER;
|
||||
if(ISDIGIT(c))
|
||||
return CCLASS_DIGIT;
|
||||
return CCLASS_OTHER;
|
||||
}
|
||||
|
||||
/* Include a character or a range in set. */
|
||||
static void setcharorrange(unsigned char **pp, unsigned char *charset)
|
||||
{
|
||||
unsigned char *p = (*pp)++;
|
||||
unsigned char c = *p++;
|
||||
|
||||
charset[c] = 1;
|
||||
if(ISALNUM(c) && *p++ == '-') {
|
||||
char_class cc = charclass(c);
|
||||
unsigned char endrange = *p++;
|
||||
|
||||
if(endrange == '\\')
|
||||
endrange = *p++;
|
||||
if(endrange >= c && charclass(endrange) == cc) {
|
||||
while(c++ != endrange)
|
||||
if(charclass(c) == cc) /* Chars in class may be not consecutive. */
|
||||
charset[c] = 1;
|
||||
*pp = p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* returns 1 (true) if pattern is OK, 0 if is bad ("p" is pattern pointer) */
|
||||
static int setcharset(unsigned char **p, unsigned char *charset)
|
||||
{
|
||||
setcharset_state state = CURLFNM_SCHS_DEFAULT;
|
||||
bool something_found = FALSE;
|
||||
unsigned char c;
|
||||
|
||||
memset(charset, 0, CURLFNM_CHSET_SIZE);
|
||||
for(;;) {
|
||||
c = **p;
|
||||
if(!c)
|
||||
return SETCHARSET_FAIL;
|
||||
|
||||
switch(state) {
|
||||
case CURLFNM_SCHS_DEFAULT:
|
||||
if(c == ']') {
|
||||
if(something_found)
|
||||
return SETCHARSET_OK;
|
||||
something_found = TRUE;
|
||||
state = CURLFNM_SCHS_RIGHTBR;
|
||||
charset[c] = 1;
|
||||
(*p)++;
|
||||
}
|
||||
else if(c == '[') {
|
||||
unsigned char *pp = *p + 1;
|
||||
|
||||
if(*pp++ == ':' && parsekeyword(&pp, charset))
|
||||
*p = pp;
|
||||
else {
|
||||
charset[c] = 1;
|
||||
(*p)++;
|
||||
}
|
||||
something_found = TRUE;
|
||||
}
|
||||
else if(c == '^' || c == '!') {
|
||||
if(!something_found) {
|
||||
if(charset[CURLFNM_NEGATE]) {
|
||||
charset[c] = 1;
|
||||
something_found = TRUE;
|
||||
}
|
||||
else
|
||||
charset[CURLFNM_NEGATE] = 1; /* negate charset */
|
||||
}
|
||||
else
|
||||
charset[c] = 1;
|
||||
(*p)++;
|
||||
}
|
||||
else if(c == '\\') {
|
||||
c = *(++(*p));
|
||||
if(c)
|
||||
setcharorrange(p, charset);
|
||||
else
|
||||
charset['\\'] = 1;
|
||||
something_found = TRUE;
|
||||
}
|
||||
else {
|
||||
setcharorrange(p, charset);
|
||||
something_found = TRUE;
|
||||
}
|
||||
break;
|
||||
case CURLFNM_SCHS_RIGHTBR:
|
||||
if(c == '[') {
|
||||
state = CURLFNM_SCHS_RIGHTBRLEFTBR;
|
||||
charset[c] = 1;
|
||||
(*p)++;
|
||||
}
|
||||
else if(c == ']') {
|
||||
return SETCHARSET_OK;
|
||||
}
|
||||
else if(ISPRINT(c)) {
|
||||
charset[c] = 1;
|
||||
(*p)++;
|
||||
state = CURLFNM_SCHS_DEFAULT;
|
||||
}
|
||||
else
|
||||
/* used 'goto fail' instead of 'return SETCHARSET_FAIL' to avoid a
|
||||
* nonsense warning 'statement not reached' at end of the fnc when
|
||||
* compiling on Solaris */
|
||||
goto fail;
|
||||
break;
|
||||
case CURLFNM_SCHS_RIGHTBRLEFTBR:
|
||||
if(c == ']')
|
||||
return SETCHARSET_OK;
|
||||
state = CURLFNM_SCHS_DEFAULT;
|
||||
charset[c] = 1;
|
||||
(*p)++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
fail:
|
||||
return SETCHARSET_FAIL;
|
||||
}
|
||||
|
||||
static int loop(const unsigned char *pattern, const unsigned char *string,
|
||||
int maxstars)
|
||||
{
|
||||
unsigned char *p = (unsigned char *)pattern;
|
||||
unsigned char *s = (unsigned char *)string;
|
||||
unsigned char charset[CURLFNM_CHSET_SIZE] = { 0 };
|
||||
|
||||
for(;;) {
|
||||
unsigned char *pp;
|
||||
|
||||
switch(*p) {
|
||||
case '*':
|
||||
if(!maxstars)
|
||||
return CURL_FNMATCH_NOMATCH;
|
||||
/* Regroup consecutive stars and question marks. This can be done because
|
||||
'*?*?*' can be expressed as '??*'. */
|
||||
for(;;) {
|
||||
if(*++p == '\0')
|
||||
return CURL_FNMATCH_MATCH;
|
||||
if(*p == '?') {
|
||||
if(!*s++)
|
||||
return CURL_FNMATCH_NOMATCH;
|
||||
}
|
||||
else if(*p != '*')
|
||||
break;
|
||||
}
|
||||
/* Skip string characters until we find a match with pattern suffix. */
|
||||
for(maxstars--; *s; s++) {
|
||||
if(loop(p, s, maxstars) == CURL_FNMATCH_MATCH)
|
||||
return CURL_FNMATCH_MATCH;
|
||||
}
|
||||
return CURL_FNMATCH_NOMATCH;
|
||||
case '?':
|
||||
if(!*s)
|
||||
return CURL_FNMATCH_NOMATCH;
|
||||
s++;
|
||||
p++;
|
||||
break;
|
||||
case '\0':
|
||||
return *s? CURL_FNMATCH_NOMATCH: CURL_FNMATCH_MATCH;
|
||||
case '\\':
|
||||
if(p[1])
|
||||
p++;
|
||||
if(*s++ != *p++)
|
||||
return CURL_FNMATCH_NOMATCH;
|
||||
break;
|
||||
case '[':
|
||||
pp = p + 1; /* Copy in case of syntax error in set. */
|
||||
if(setcharset(&pp, charset)) {
|
||||
int found = FALSE;
|
||||
if(!*s)
|
||||
return CURL_FNMATCH_NOMATCH;
|
||||
if(charset[(unsigned int)*s])
|
||||
found = TRUE;
|
||||
else if(charset[CURLFNM_ALNUM])
|
||||
found = ISALNUM(*s);
|
||||
else if(charset[CURLFNM_ALPHA])
|
||||
found = ISALPHA(*s);
|
||||
else if(charset[CURLFNM_DIGIT])
|
||||
found = ISDIGIT(*s);
|
||||
else if(charset[CURLFNM_XDIGIT])
|
||||
found = ISXDIGIT(*s);
|
||||
else if(charset[CURLFNM_PRINT])
|
||||
found = ISPRINT(*s);
|
||||
else if(charset[CURLFNM_SPACE])
|
||||
found = ISSPACE(*s);
|
||||
else if(charset[CURLFNM_UPPER])
|
||||
found = ISUPPER(*s);
|
||||
else if(charset[CURLFNM_LOWER])
|
||||
found = ISLOWER(*s);
|
||||
else if(charset[CURLFNM_BLANK])
|
||||
found = ISBLANK(*s);
|
||||
else if(charset[CURLFNM_GRAPH])
|
||||
found = ISGRAPH(*s);
|
||||
|
||||
if(charset[CURLFNM_NEGATE])
|
||||
found = !found;
|
||||
|
||||
if(!found)
|
||||
return CURL_FNMATCH_NOMATCH;
|
||||
p = pp + 1;
|
||||
s++;
|
||||
break;
|
||||
}
|
||||
/* Syntax error in set; mismatch! */
|
||||
return CURL_FNMATCH_NOMATCH;
|
||||
|
||||
default:
|
||||
if(*p++ != *s++)
|
||||
return CURL_FNMATCH_NOMATCH;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @unittest: 1307
|
||||
*/
|
||||
int Curl_fnmatch(void *ptr, const char *pattern, const char *string)
|
||||
{
|
||||
(void)ptr; /* the argument is specified by the curl_fnmatch_callback
|
||||
prototype, but not used by Curl_fnmatch() */
|
||||
if(!pattern || !string) {
|
||||
return CURL_FNMATCH_FAIL;
|
||||
}
|
||||
return loop((unsigned char *)pattern, (unsigned char *)string, 2);
|
||||
}
|
||||
#else
|
||||
#include <fnmatch.h>
|
||||
/*
|
||||
* @unittest: 1307
|
||||
*/
|
||||
int Curl_fnmatch(void *ptr, const char *pattern, const char *string)
|
||||
{
|
||||
int rc;
|
||||
(void)ptr; /* the argument is specified by the curl_fnmatch_callback
|
||||
prototype, but not used by Curl_fnmatch() */
|
||||
if(!pattern || !string) {
|
||||
return CURL_FNMATCH_FAIL;
|
||||
}
|
||||
rc = fnmatch(pattern, string, 0);
|
||||
switch(rc) {
|
||||
case 0:
|
||||
return CURL_FNMATCH_MATCH;
|
||||
case FNM_NOMATCH:
|
||||
return CURL_FNMATCH_NOMATCH;
|
||||
default:
|
||||
return CURL_FNMATCH_FAIL;
|
||||
}
|
||||
/* not reached */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* if FTP is disabled */
|
44
src/dependencies/cmcurl/lib/curl_fnmatch.h
Normal file
44
src/dependencies/cmcurl/lib/curl_fnmatch.h
Normal file
|
@ -0,0 +1,44 @@
|
|||
#ifndef HEADER_CURL_FNMATCH_H
|
||||
#define HEADER_CURL_FNMATCH_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#define CURL_FNMATCH_MATCH 0
|
||||
#define CURL_FNMATCH_NOMATCH 1
|
||||
#define CURL_FNMATCH_FAIL 2
|
||||
|
||||
/* default pattern matching function
|
||||
* =================================
|
||||
* Implemented with recursive backtracking, if you want to use Curl_fnmatch,
|
||||
* please note that there is not implemented UTF/UNICODE support.
|
||||
*
|
||||
* Implemented features:
|
||||
* '?' notation, does not match UTF characters
|
||||
* '*' can also work with UTF string
|
||||
* [a-zA-Z0-9] enumeration support
|
||||
*
|
||||
* keywords: alnum, digit, xdigit, alpha, print, blank, lower, graph, space
|
||||
* and upper (use as "[[:alnum:]]")
|
||||
*/
|
||||
int Curl_fnmatch(void *ptr, const char *pattern, const char *string);
|
||||
|
||||
#endif /* HEADER_CURL_FNMATCH_H */
|
55
src/dependencies/cmcurl/lib/curl_get_line.c
Normal file
55
src/dependencies/cmcurl/lib/curl_get_line.c
Normal file
|
@ -0,0 +1,55 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#include "curl_get_line.h"
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
/*
|
||||
* get_line() makes sure to only return complete whole lines that fit in 'len'
|
||||
* bytes and end with a newline.
|
||||
*/
|
||||
char *Curl_get_line(char *buf, int len, FILE *input)
|
||||
{
|
||||
bool partial = FALSE;
|
||||
while(1) {
|
||||
char *b = fgets(buf, len, input);
|
||||
if(b) {
|
||||
size_t rlen = strlen(b);
|
||||
if(rlen && (b[rlen-1] == '\n')) {
|
||||
if(partial) {
|
||||
partial = FALSE;
|
||||
continue;
|
||||
}
|
||||
return b;
|
||||
}
|
||||
/* read a partial, discard the next piece that ends with newline */
|
||||
partial = TRUE;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
29
src/dependencies/cmcurl/lib/curl_get_line.h
Normal file
29
src/dependencies/cmcurl/lib/curl_get_line.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
#ifndef HEADER_CURL_GET_LINE_H
|
||||
#define HEADER_CURL_GET_LINE_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* get_line() makes sure to only return complete whole lines that fit in 'len'
|
||||
* bytes and end with a newline. */
|
||||
char *Curl_get_line(char *buf, int len, FILE *input);
|
||||
|
||||
#endif /* HEADER_CURL_GET_LINE_H */
|
100
src/dependencies/cmcurl/lib/curl_gethostname.c
Normal file
100
src/dependencies/cmcurl/lib/curl_gethostname.c
Normal file
|
@ -0,0 +1,100 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#include "curl_gethostname.h"
|
||||
|
||||
/*
|
||||
* Curl_gethostname() is a wrapper around gethostname() which allows
|
||||
* overriding the host name that the function would normally return.
|
||||
* This capability is used by the test suite to verify exact matching
|
||||
* of NTLM authentication, which exercises libcurl's MD4 and DES code
|
||||
* as well as by the SMTP module when a hostname is not provided.
|
||||
*
|
||||
* For libcurl debug enabled builds host name overriding takes place
|
||||
* when environment variable CURL_GETHOSTNAME is set, using the value
|
||||
* held by the variable to override returned host name.
|
||||
*
|
||||
* Note: The function always returns the un-qualified hostname rather
|
||||
* than being provider dependent.
|
||||
*
|
||||
* For libcurl shared library release builds the test suite preloads
|
||||
* another shared library named libhostname using the LD_PRELOAD
|
||||
* mechanism which intercepts, and might override, the gethostname()
|
||||
* function call. In this case a given platform must support the
|
||||
* LD_PRELOAD mechanism and additionally have environment variable
|
||||
* CURL_GETHOSTNAME set in order to override the returned host name.
|
||||
*
|
||||
* For libcurl static library release builds no overriding takes place.
|
||||
*/
|
||||
|
||||
int Curl_gethostname(char *name, GETHOSTNAME_TYPE_ARG2 namelen)
|
||||
{
|
||||
#ifndef HAVE_GETHOSTNAME
|
||||
|
||||
/* Allow compilation and return failure when unavailable */
|
||||
(void) name;
|
||||
(void) namelen;
|
||||
return -1;
|
||||
|
||||
#else
|
||||
int err;
|
||||
char *dot;
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
|
||||
/* Override host name when environment variable CURL_GETHOSTNAME is set */
|
||||
const char *force_hostname = getenv("CURL_GETHOSTNAME");
|
||||
if(force_hostname) {
|
||||
strncpy(name, force_hostname, namelen);
|
||||
err = 0;
|
||||
}
|
||||
else {
|
||||
name[0] = '\0';
|
||||
err = gethostname(name, namelen);
|
||||
}
|
||||
|
||||
#else /* DEBUGBUILD */
|
||||
|
||||
/* The call to system's gethostname() might get intercepted by the
|
||||
libhostname library when libcurl is built as a non-debug shared
|
||||
library when running the test suite. */
|
||||
name[0] = '\0';
|
||||
err = gethostname(name, namelen);
|
||||
|
||||
#endif
|
||||
|
||||
name[namelen - 1] = '\0';
|
||||
|
||||
if(err)
|
||||
return err;
|
||||
|
||||
/* Truncate domain, leave only machine name */
|
||||
dot = strchr(name, '.');
|
||||
if(dot)
|
||||
*dot = '\0';
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
}
|
31
src/dependencies/cmcurl/lib/curl_gethostname.h
Normal file
31
src/dependencies/cmcurl/lib/curl_gethostname.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
#ifndef HEADER_CURL_GETHOSTNAME_H
|
||||
#define HEADER_CURL_GETHOSTNAME_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* Hostname buffer size */
|
||||
#define HOSTNAME_MAX 1024
|
||||
|
||||
/* This returns the local machine's un-qualified hostname */
|
||||
int Curl_gethostname(char *name, GETHOSTNAME_TYPE_ARG2 namelen);
|
||||
|
||||
#endif /* HEADER_CURL_GETHOSTNAME_H */
|
136
src/dependencies/cmcurl/lib/curl_gssapi.c
Normal file
136
src/dependencies/cmcurl/lib/curl_gssapi.c
Normal file
|
@ -0,0 +1,136 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2011 - 2018, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#ifdef HAVE_GSSAPI
|
||||
|
||||
#include "curl_gssapi.h"
|
||||
#include "sendf.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
static char spnego_oid_bytes[] = "\x2b\x06\x01\x05\x05\x02";
|
||||
gss_OID_desc Curl_spnego_mech_oid = { 6, &spnego_oid_bytes };
|
||||
static char krb5_oid_bytes[] = "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02";
|
||||
gss_OID_desc Curl_krb5_mech_oid = { 9, &krb5_oid_bytes };
|
||||
|
||||
OM_uint32 Curl_gss_init_sec_context(
|
||||
struct Curl_easy *data,
|
||||
OM_uint32 *minor_status,
|
||||
gss_ctx_id_t *context,
|
||||
gss_name_t target_name,
|
||||
gss_OID mech_type,
|
||||
gss_channel_bindings_t input_chan_bindings,
|
||||
gss_buffer_t input_token,
|
||||
gss_buffer_t output_token,
|
||||
const bool mutual_auth,
|
||||
OM_uint32 *ret_flags)
|
||||
{
|
||||
OM_uint32 req_flags = GSS_C_REPLAY_FLAG;
|
||||
|
||||
if(mutual_auth)
|
||||
req_flags |= GSS_C_MUTUAL_FLAG;
|
||||
|
||||
if(data->set.gssapi_delegation & CURLGSSAPI_DELEGATION_POLICY_FLAG) {
|
||||
#ifdef GSS_C_DELEG_POLICY_FLAG
|
||||
req_flags |= GSS_C_DELEG_POLICY_FLAG;
|
||||
#else
|
||||
infof(data, "warning: support for CURLGSSAPI_DELEGATION_POLICY_FLAG not "
|
||||
"compiled in\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
if(data->set.gssapi_delegation & CURLGSSAPI_DELEGATION_FLAG)
|
||||
req_flags |= GSS_C_DELEG_FLAG;
|
||||
|
||||
return gss_init_sec_context(minor_status,
|
||||
GSS_C_NO_CREDENTIAL, /* cred_handle */
|
||||
context,
|
||||
target_name,
|
||||
mech_type,
|
||||
req_flags,
|
||||
0, /* time_req */
|
||||
input_chan_bindings,
|
||||
input_token,
|
||||
NULL, /* actual_mech_type */
|
||||
output_token,
|
||||
ret_flags,
|
||||
NULL /* time_rec */);
|
||||
}
|
||||
|
||||
#define GSS_LOG_BUFFER_LEN 1024
|
||||
static size_t display_gss_error(OM_uint32 status, int type,
|
||||
char *buf, size_t len) {
|
||||
OM_uint32 maj_stat;
|
||||
OM_uint32 min_stat;
|
||||
OM_uint32 msg_ctx = 0;
|
||||
gss_buffer_desc status_string;
|
||||
|
||||
do {
|
||||
maj_stat = gss_display_status(&min_stat,
|
||||
status,
|
||||
type,
|
||||
GSS_C_NO_OID,
|
||||
&msg_ctx,
|
||||
&status_string);
|
||||
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);
|
||||
}
|
||||
gss_release_buffer(&min_stat, &status_string);
|
||||
} while(!GSS_ERROR(maj_stat) && msg_ctx != 0);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_gss_log_error()
|
||||
*
|
||||
* This is used to log a GSS-API error status.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* data [in] - The session handle.
|
||||
* prefix [in] - The prefix of the log message.
|
||||
* major [in] - The major status code.
|
||||
* minor [in] - The minor status code.
|
||||
*/
|
||||
void Curl_gss_log_error(struct Curl_easy *data, const char *prefix,
|
||||
OM_uint32 major, OM_uint32 minor)
|
||||
{
|
||||
char buf[GSS_LOG_BUFFER_LEN];
|
||||
size_t len = 0;
|
||||
|
||||
if(major != GSS_S_FAILURE)
|
||||
len = display_gss_error(major, GSS_C_GSS_CODE, buf, len);
|
||||
|
||||
display_gss_error(minor, GSS_C_MECH_CODE, buf, len);
|
||||
|
||||
infof(data, "%s%s\n", prefix, buf);
|
||||
}
|
||||
|
||||
#endif /* HAVE_GSSAPI */
|
61
src/dependencies/cmcurl/lib/curl_gssapi.h
Normal file
61
src/dependencies/cmcurl/lib/curl_gssapi.h
Normal file
|
@ -0,0 +1,61 @@
|
|||
#ifndef HEADER_CURL_GSSAPI_H
|
||||
#define HEADER_CURL_GSSAPI_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2011 - 2019, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
#include "urldata.h"
|
||||
|
||||
#ifdef HAVE_GSSAPI
|
||||
extern gss_OID_desc Curl_spnego_mech_oid;
|
||||
extern gss_OID_desc Curl_krb5_mech_oid;
|
||||
|
||||
/* Common method for using GSS-API */
|
||||
OM_uint32 Curl_gss_init_sec_context(
|
||||
struct Curl_easy *data,
|
||||
OM_uint32 *minor_status,
|
||||
gss_ctx_id_t *context,
|
||||
gss_name_t target_name,
|
||||
gss_OID mech_type,
|
||||
gss_channel_bindings_t input_chan_bindings,
|
||||
gss_buffer_t input_token,
|
||||
gss_buffer_t output_token,
|
||||
const bool mutual_auth,
|
||||
OM_uint32 *ret_flags);
|
||||
|
||||
/* Helper to log a GSS-API error status */
|
||||
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
|
||||
#define GSSAUTH_P_PRIVACY 4
|
||||
|
||||
#endif /* HAVE_GSSAPI */
|
||||
#endif /* HEADER_CURL_GSSAPI_H */
|
67
src/dependencies/cmcurl/lib/curl_hmac.h
Normal file
67
src/dependencies/cmcurl/lib/curl_hmac.h
Normal file
|
@ -0,0 +1,67 @@
|
|||
#ifndef HEADER_CURL_HMAC_H
|
||||
#define HEADER_CURL_HMAC_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef CURL_DISABLE_CRYPTO_AUTH
|
||||
|
||||
typedef void (* HMAC_hinit_func)(void *context);
|
||||
typedef void (* HMAC_hupdate_func)(void *context,
|
||||
const unsigned char *data,
|
||||
unsigned int len);
|
||||
typedef void (* HMAC_hfinal_func)(unsigned char *result, void *context);
|
||||
|
||||
|
||||
/* Per-hash function HMAC parameters. */
|
||||
|
||||
typedef struct {
|
||||
HMAC_hinit_func hmac_hinit; /* Initialize context procedure. */
|
||||
HMAC_hupdate_func hmac_hupdate; /* Update context with data. */
|
||||
HMAC_hfinal_func hmac_hfinal; /* Get final result procedure. */
|
||||
unsigned int hmac_ctxtsize; /* Context structure size. */
|
||||
unsigned int hmac_maxkeylen; /* Maximum key length (bytes). */
|
||||
unsigned int hmac_resultlen; /* Result length (bytes). */
|
||||
} HMAC_params;
|
||||
|
||||
|
||||
/* HMAC computation context. */
|
||||
|
||||
typedef struct {
|
||||
const HMAC_params *hmac_hash; /* Hash function definition. */
|
||||
void *hmac_hashctxt1; /* Hash function context 1. */
|
||||
void *hmac_hashctxt2; /* Hash function context 2. */
|
||||
} HMAC_context;
|
||||
|
||||
|
||||
/* Prototypes. */
|
||||
|
||||
HMAC_context * Curl_HMAC_init(const HMAC_params *hashparams,
|
||||
const unsigned char *key,
|
||||
unsigned int keylen);
|
||||
int Curl_HMAC_update(HMAC_context *context,
|
||||
const unsigned char *data,
|
||||
unsigned int len);
|
||||
int Curl_HMAC_final(HMAC_context *context, unsigned char *result);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_HMAC_H */
|
34
src/dependencies/cmcurl/lib/curl_ldap.h
Normal file
34
src/dependencies/cmcurl/lib/curl_ldap.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
#ifndef HEADER_CURL_LDAP_H
|
||||
#define HEADER_CURL_LDAP_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
#ifndef CURL_DISABLE_LDAP
|
||||
extern const struct Curl_handler Curl_handler_ldap;
|
||||
|
||||
#if !defined(CURL_DISABLE_LDAPS) && \
|
||||
((defined(USE_OPENLDAP) && defined(USE_SSL)) || \
|
||||
(!defined(USE_OPENLDAP) && defined(HAVE_LDAP_SSL)))
|
||||
extern const struct Curl_handler Curl_handler_ldaps;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif /* HEADER_CURL_LDAP_H */
|
37
src/dependencies/cmcurl/lib/curl_md4.h
Normal file
37
src/dependencies/cmcurl/lib/curl_md4.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
#ifndef HEADER_CURL_MD4_H
|
||||
#define HEADER_CURL_MD4_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if defined(USE_NSS) || defined(USE_OS400CRYPTO) || \
|
||||
(defined(USE_OPENSSL) && defined(OPENSSL_NO_MD4)) || \
|
||||
(defined(USE_MBEDTLS) && !defined(MBEDTLS_MD4_C))
|
||||
|
||||
void Curl_md4it(unsigned char *output, const unsigned char *input, size_t len);
|
||||
|
||||
#endif /* defined(USE_NSS) || defined(USE_OS400CRYPTO) ||
|
||||
(defined(USE_OPENSSL) && defined(OPENSSL_NO_MD4)) ||
|
||||
(defined(USE_MBEDTLS) && !defined(MBEDTLS_MD4_C)) */
|
||||
|
||||
#endif /* HEADER_CURL_MD4_H */
|
63
src/dependencies/cmcurl/lib/curl_md5.h
Normal file
63
src/dependencies/cmcurl/lib/curl_md5.h
Normal file
|
@ -0,0 +1,63 @@
|
|||
#ifndef HEADER_CURL_MD5_H
|
||||
#define HEADER_CURL_MD5_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef CURL_DISABLE_CRYPTO_AUTH
|
||||
#include "curl_hmac.h"
|
||||
|
||||
#define MD5_DIGEST_LEN 16
|
||||
|
||||
typedef void (* Curl_MD5_init_func)(void *context);
|
||||
typedef void (* Curl_MD5_update_func)(void *context,
|
||||
const unsigned char *data,
|
||||
unsigned int len);
|
||||
typedef void (* Curl_MD5_final_func)(unsigned char *result, void *context);
|
||||
|
||||
typedef struct {
|
||||
Curl_MD5_init_func md5_init_func; /* Initialize context procedure */
|
||||
Curl_MD5_update_func md5_update_func; /* Update context with data */
|
||||
Curl_MD5_final_func md5_final_func; /* Get final result procedure */
|
||||
unsigned int md5_ctxtsize; /* Context structure size */
|
||||
unsigned int md5_resultlen; /* Result length (bytes) */
|
||||
} MD5_params;
|
||||
|
||||
typedef struct {
|
||||
const MD5_params *md5_hash; /* Hash function definition */
|
||||
void *md5_hashctx; /* Hash function context */
|
||||
} MD5_context;
|
||||
|
||||
extern const MD5_params Curl_DIGEST_MD5[1];
|
||||
extern const HMAC_params Curl_HMAC_MD5[1];
|
||||
|
||||
void Curl_md5it(unsigned char *output,
|
||||
const unsigned char *input);
|
||||
|
||||
MD5_context * Curl_MD5_init(const MD5_params *md5params);
|
||||
CURLcode Curl_MD5_update(MD5_context *context,
|
||||
const unsigned char *data,
|
||||
unsigned int len);
|
||||
CURLcode Curl_MD5_final(MD5_context *context, unsigned char *result);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_MD5_H */
|
156
src/dependencies/cmcurl/lib/curl_memory.h
Normal file
156
src/dependencies/cmcurl/lib/curl_memory.h
Normal file
|
@ -0,0 +1,156 @@
|
|||
#ifndef HEADER_CURL_MEMORY_H
|
||||
#define HEADER_CURL_MEMORY_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
* Nasty internal details ahead...
|
||||
*
|
||||
* File curl_memory.h must be included by _all_ *.c source files
|
||||
* that use memory related functions strdup, malloc, calloc, realloc
|
||||
* or free, and given source file is used to build libcurl library.
|
||||
* It should be included immediately before memdebug.h as the last files
|
||||
* included to avoid undesired interaction with other memory function
|
||||
* headers in dependent libraries.
|
||||
*
|
||||
* There is nearly no exception to above rule. All libcurl source
|
||||
* files in 'lib' subdirectory as well as those living deep inside
|
||||
* 'packages' subdirectories and linked together in order to build
|
||||
* libcurl library shall follow it.
|
||||
*
|
||||
* File lib/strdup.c is an exception, given that it provides a strdup
|
||||
* clone implementation while using malloc. Extra care needed inside
|
||||
* this one.
|
||||
*
|
||||
* The need for curl_memory.h inclusion is due to libcurl's feature
|
||||
* of allowing library user to provide memory replacement functions,
|
||||
* memory callbacks, at runtime with curl_global_init_mem()
|
||||
*
|
||||
* Any *.c source file used to build libcurl library that does not
|
||||
* include curl_memory.h and uses any memory function of the five
|
||||
* mentioned above will compile without any indication, but it will
|
||||
* trigger weird memory related issues at runtime.
|
||||
*
|
||||
* OTOH some source files from 'lib' subdirectory may additionally be
|
||||
* used directly as source code when using some curlx_ functions by
|
||||
* third party programs that don't even use libcurl at all. When using
|
||||
* these source files in this way it is necessary these are compiled
|
||||
* with CURLX_NO_MEMORY_CALLBACKS defined, in order to ensure that no
|
||||
* attempt of calling libcurl's memory callbacks is done from code
|
||||
* which can not use this machinery.
|
||||
*
|
||||
* Notice that libcurl's 'memory tracking' system works chaining into
|
||||
* the memory callback machinery. This implies that when compiling
|
||||
* 'lib' source files with CURLX_NO_MEMORY_CALLBACKS defined this file
|
||||
* disengages usage of libcurl's 'memory tracking' system, defining
|
||||
* MEMDEBUG_NODEFINES and overriding CURLDEBUG purpose.
|
||||
*
|
||||
* CURLX_NO_MEMORY_CALLBACKS takes precedence over CURLDEBUG. This is
|
||||
* done in order to allow building a 'memory tracking' enabled libcurl
|
||||
* and at the same time allow building programs which do not use it.
|
||||
*
|
||||
* Programs and libraries in 'tests' subdirectories have specific
|
||||
* purposes and needs, and as such each one will use whatever fits
|
||||
* best, depending additionally whether it links with libcurl or not.
|
||||
*
|
||||
* Caveat emptor. Proper curlx_* separation is a work in progress
|
||||
* the same as CURLX_NO_MEMORY_CALLBACKS usage, some adjustments may
|
||||
* still be required. IOW don't use them yet, there are sharp edges.
|
||||
*/
|
||||
|
||||
#ifdef HEADER_CURL_MEMDEBUG_H
|
||||
#error "Header memdebug.h shall not be included before curl_memory.h"
|
||||
#endif
|
||||
|
||||
#ifndef CURLX_NO_MEMORY_CALLBACKS
|
||||
|
||||
#ifndef CURL_DID_MEMORY_FUNC_TYPEDEFS /* only if not already done */
|
||||
/*
|
||||
* The following memory function replacement typedef's are COPIED from
|
||||
* curl/curl.h and MUST match the originals. We copy them to avoid having to
|
||||
* include curl/curl.h here. We avoid that include since it includes stdio.h
|
||||
* and other headers that may get messed up with defines done here.
|
||||
*/
|
||||
typedef void *(*curl_malloc_callback)(size_t size);
|
||||
typedef void (*curl_free_callback)(void *ptr);
|
||||
typedef void *(*curl_realloc_callback)(void *ptr, size_t size);
|
||||
typedef char *(*curl_strdup_callback)(const char *str);
|
||||
typedef void *(*curl_calloc_callback)(size_t nmemb, size_t size);
|
||||
#define CURL_DID_MEMORY_FUNC_TYPEDEFS
|
||||
#endif
|
||||
|
||||
extern curl_malloc_callback Curl_cmalloc;
|
||||
extern curl_free_callback Curl_cfree;
|
||||
extern curl_realloc_callback Curl_crealloc;
|
||||
extern curl_strdup_callback Curl_cstrdup;
|
||||
extern curl_calloc_callback Curl_ccalloc;
|
||||
#if defined(WIN32) && defined(UNICODE)
|
||||
extern curl_wcsdup_callback Curl_cwcsdup;
|
||||
#endif
|
||||
|
||||
#ifndef CURLDEBUG
|
||||
|
||||
/*
|
||||
* libcurl's 'memory tracking' system defines strdup, malloc, calloc,
|
||||
* realloc and free, along with others, in memdebug.h in a different
|
||||
* way although still using memory callbacks forward declared above.
|
||||
* When using the 'memory tracking' system (CURLDEBUG defined) we do
|
||||
* not define here the five memory functions given that definitions
|
||||
* from memdebug.h are the ones that shall be used.
|
||||
*/
|
||||
|
||||
#undef strdup
|
||||
#define strdup(ptr) Curl_cstrdup(ptr)
|
||||
#undef malloc
|
||||
#define malloc(size) Curl_cmalloc(size)
|
||||
#undef calloc
|
||||
#define calloc(nbelem,size) Curl_ccalloc(nbelem, size)
|
||||
#undef realloc
|
||||
#define realloc(ptr,size) Curl_crealloc(ptr, size)
|
||||
#undef free
|
||||
#define free(ptr) Curl_cfree(ptr)
|
||||
|
||||
#ifdef WIN32
|
||||
# ifdef UNICODE
|
||||
# undef wcsdup
|
||||
# define wcsdup(ptr) Curl_cwcsdup(ptr)
|
||||
# undef _wcsdup
|
||||
# define _wcsdup(ptr) Curl_cwcsdup(ptr)
|
||||
# undef _tcsdup
|
||||
# define _tcsdup(ptr) Curl_cwcsdup(ptr)
|
||||
# else
|
||||
# undef _tcsdup
|
||||
# define _tcsdup(ptr) Curl_cstrdup(ptr)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif /* CURLDEBUG */
|
||||
|
||||
#else /* CURLX_NO_MEMORY_CALLBACKS */
|
||||
|
||||
#ifndef MEMDEBUG_NODEFINES
|
||||
#define MEMDEBUG_NODEFINES
|
||||
#endif
|
||||
|
||||
#endif /* CURLX_NO_MEMORY_CALLBACKS */
|
||||
|
||||
#endif /* HEADER_CURL_MEMORY_H */
|
62
src/dependencies/cmcurl/lib/curl_memrchr.c
Normal file
62
src/dependencies/cmcurl/lib/curl_memrchr.c
Normal file
|
@ -0,0 +1,62 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "curl_memrchr.h"
|
||||
#include "curl_memory.h"
|
||||
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
#ifndef HAVE_MEMRCHR
|
||||
|
||||
/*
|
||||
* Curl_memrchr()
|
||||
*
|
||||
* Our memrchr() function clone for systems which lack this function. The
|
||||
* memrchr() function is like the memchr() function, except that it searches
|
||||
* backwards from the end of the n bytes pointed to by s instead of forward
|
||||
* from the beginning.
|
||||
*/
|
||||
|
||||
void *
|
||||
Curl_memrchr(const void *s, int c, size_t n)
|
||||
{
|
||||
if(n > 0) {
|
||||
const unsigned char *p = s;
|
||||
const unsigned char *q = s;
|
||||
|
||||
p += n - 1;
|
||||
|
||||
while(p >= q) {
|
||||
if(*p == (unsigned char)c)
|
||||
return (void *)p;
|
||||
p--;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif /* HAVE_MEMRCHR */
|
44
src/dependencies/cmcurl/lib/curl_memrchr.h
Normal file
44
src/dependencies/cmcurl/lib/curl_memrchr.h
Normal file
|
@ -0,0 +1,44 @@
|
|||
#ifndef HEADER_CURL_MEMRCHR_H
|
||||
#define HEADER_CURL_MEMRCHR_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#ifdef HAVE_MEMRCHR
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif
|
||||
|
||||
#else /* HAVE_MEMRCHR */
|
||||
|
||||
void *Curl_memrchr(const void *s, int c, size_t n);
|
||||
|
||||
#define memrchr(x,y,z) Curl_memrchr((x),(y),(z))
|
||||
|
||||
#endif /* HAVE_MEMRCHR */
|
||||
|
||||
#endif /* HEADER_CURL_MEMRCHR_H */
|
84
src/dependencies/cmcurl/lib/curl_multibyte.c
Normal file
84
src/dependencies/cmcurl/lib/curl_multibyte.c
Normal file
|
@ -0,0 +1,84 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#if defined(USE_WIN32_IDN) || ((defined(USE_WINDOWS_SSPI) || \
|
||||
defined(USE_WIN32_LDAP)) && defined(UNICODE))
|
||||
|
||||
/*
|
||||
* MultiByte conversions using Windows kernel32 library.
|
||||
*/
|
||||
|
||||
#include "curl_multibyte.h"
|
||||
#include "curl_memory.h"
|
||||
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
wchar_t *Curl_convert_UTF8_to_wchar(const char *str_utf8)
|
||||
{
|
||||
wchar_t *str_w = NULL;
|
||||
|
||||
if(str_utf8) {
|
||||
int str_w_len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS,
|
||||
str_utf8, -1, NULL, 0);
|
||||
if(str_w_len > 0) {
|
||||
str_w = malloc(str_w_len * sizeof(wchar_t));
|
||||
if(str_w) {
|
||||
if(MultiByteToWideChar(CP_UTF8, 0, str_utf8, -1, str_w,
|
||||
str_w_len) == 0) {
|
||||
free(str_w);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return str_w;
|
||||
}
|
||||
|
||||
char *Curl_convert_wchar_to_UTF8(const wchar_t *str_w)
|
||||
{
|
||||
char *str_utf8 = NULL;
|
||||
|
||||
if(str_w) {
|
||||
int bytes = WideCharToMultiByte(CP_UTF8, 0, str_w, -1,
|
||||
NULL, 0, NULL, NULL);
|
||||
if(bytes > 0) {
|
||||
str_utf8 = malloc(bytes);
|
||||
if(str_utf8) {
|
||||
if(WideCharToMultiByte(CP_UTF8, 0, str_w, -1, str_utf8, bytes,
|
||||
NULL, NULL) == 0) {
|
||||
free(str_utf8);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return str_utf8;
|
||||
}
|
||||
|
||||
#endif /* USE_WIN32_IDN || ((USE_WINDOWS_SSPI || USE_WIN32_LDAP) && UNICODE) */
|
92
src/dependencies/cmcurl/lib/curl_multibyte.h
Normal file
92
src/dependencies/cmcurl/lib/curl_multibyte.h
Normal file
|
@ -0,0 +1,92 @@
|
|||
#ifndef HEADER_CURL_MULTIBYTE_H
|
||||
#define HEADER_CURL_MULTIBYTE_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if defined(USE_WIN32_IDN) || ((defined(USE_WINDOWS_SSPI) || \
|
||||
defined(USE_WIN32_LDAP)) && defined(UNICODE))
|
||||
|
||||
/*
|
||||
* MultiByte conversions using Windows kernel32 library.
|
||||
*/
|
||||
|
||||
wchar_t *Curl_convert_UTF8_to_wchar(const char *str_utf8);
|
||||
char *Curl_convert_wchar_to_UTF8(const wchar_t *str_w);
|
||||
|
||||
#endif /* USE_WIN32_IDN || ((USE_WINDOWS_SSPI || USE_WIN32_LDAP) && UNICODE) */
|
||||
|
||||
|
||||
#if defined(USE_WIN32_IDN) || defined(USE_WINDOWS_SSPI) || \
|
||||
defined(USE_WIN32_LDAP)
|
||||
|
||||
/*
|
||||
* Macros Curl_convert_UTF8_to_tchar(), Curl_convert_tchar_to_UTF8()
|
||||
* and Curl_unicodefree() main purpose is to minimize the number of
|
||||
* preprocessor conditional directives needed by code using these
|
||||
* to differentiate UNICODE from non-UNICODE builds.
|
||||
*
|
||||
* When building with UNICODE defined, this two macros
|
||||
* Curl_convert_UTF8_to_tchar() and Curl_convert_tchar_to_UTF8()
|
||||
* return a pointer to a newly allocated memory area holding result.
|
||||
* When the result is no longer needed, allocated memory is intended
|
||||
* to be free'ed with Curl_unicodefree().
|
||||
*
|
||||
* When building without UNICODE defined, this macros
|
||||
* Curl_convert_UTF8_to_tchar() and Curl_convert_tchar_to_UTF8()
|
||||
* return the pointer received as argument. Curl_unicodefree() does
|
||||
* no actual free'ing of this pointer it is simply set to NULL.
|
||||
*/
|
||||
|
||||
#ifdef UNICODE
|
||||
|
||||
#define Curl_convert_UTF8_to_tchar(ptr) Curl_convert_UTF8_to_wchar((ptr))
|
||||
#define Curl_convert_tchar_to_UTF8(ptr) Curl_convert_wchar_to_UTF8((ptr))
|
||||
#define Curl_unicodefree(ptr) \
|
||||
do {if((ptr)) {free((ptr)); (ptr) = NULL;}} WHILE_FALSE
|
||||
|
||||
typedef union {
|
||||
unsigned short *tchar_ptr;
|
||||
const unsigned short *const_tchar_ptr;
|
||||
unsigned short *tbyte_ptr;
|
||||
const unsigned short *const_tbyte_ptr;
|
||||
} xcharp_u;
|
||||
|
||||
#else
|
||||
|
||||
#define Curl_convert_UTF8_to_tchar(ptr) (ptr)
|
||||
#define Curl_convert_tchar_to_UTF8(ptr) (ptr)
|
||||
#define Curl_unicodefree(ptr) \
|
||||
do {(ptr) = NULL;} WHILE_FALSE
|
||||
|
||||
typedef union {
|
||||
char *tchar_ptr;
|
||||
const char *const_tchar_ptr;
|
||||
unsigned char *tbyte_ptr;
|
||||
const unsigned char *const_tbyte_ptr;
|
||||
} xcharp_u;
|
||||
|
||||
#endif /* UNICODE */
|
||||
|
||||
#endif /* USE_WIN32_IDN || USE_WINDOWS_SSPI || USE_WIN32_LDAP */
|
||||
|
||||
#endif /* HEADER_CURL_MULTIBYTE_H */
|
824
src/dependencies/cmcurl/lib/curl_ntlm_core.c
Normal file
824
src/dependencies/cmcurl/lib/curl_ntlm_core.c
Normal file
|
@ -0,0 +1,824 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if defined(USE_NTLM)
|
||||
|
||||
/*
|
||||
* NTLM details:
|
||||
*
|
||||
* https://davenport.sourceforge.io/ntlm.html
|
||||
* https://www.innovation.ch/java/ntlm.html
|
||||
*/
|
||||
|
||||
/* Please keep the SSL backend-specific #if branches in this order:
|
||||
|
||||
1. USE_OPENSSL
|
||||
2. USE_GNUTLS_NETTLE
|
||||
3. USE_GNUTLS
|
||||
4. USE_NSS
|
||||
5. USE_MBEDTLS
|
||||
6. USE_SECTRANSP
|
||||
7. USE_OS400CRYPTO
|
||||
8. USE_WIN32_CRYPTO
|
||||
|
||||
This ensures that:
|
||||
- the same SSL branch gets activated throughout this source
|
||||
file even if multiple backends are enabled at the same time.
|
||||
- OpenSSL and NSS have higher priority than Windows Crypt, due
|
||||
to issues with the latter supporting NTLM2Session responses
|
||||
in NTLM type-3 messages.
|
||||
*/
|
||||
|
||||
#if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO)
|
||||
|
||||
#ifdef USE_OPENSSL
|
||||
|
||||
# include <openssl/des.h>
|
||||
# ifndef OPENSSL_NO_MD4
|
||||
# include <openssl/md4.h>
|
||||
# else
|
||||
# include "curl_md4.h"
|
||||
# endif
|
||||
# include <openssl/md5.h>
|
||||
# include <openssl/ssl.h>
|
||||
# include <openssl/rand.h>
|
||||
# if (OPENSSL_VERSION_NUMBER < 0x00907001L)
|
||||
# define DES_key_schedule des_key_schedule
|
||||
# define DES_cblock des_cblock
|
||||
# define DES_set_odd_parity des_set_odd_parity
|
||||
# define DES_set_key des_set_key
|
||||
# define DES_ecb_encrypt des_ecb_encrypt
|
||||
# define DESKEY(x) x
|
||||
# define DESKEYARG(x) x
|
||||
# else
|
||||
# define DESKEYARG(x) *x
|
||||
# define DESKEY(x) &x
|
||||
# endif
|
||||
|
||||
#elif defined(USE_GNUTLS_NETTLE)
|
||||
|
||||
# include <nettle/des.h>
|
||||
# include <nettle/md4.h>
|
||||
|
||||
#elif defined(USE_GNUTLS)
|
||||
|
||||
# include <gcrypt.h>
|
||||
# define MD5_DIGEST_LENGTH 16
|
||||
# define MD4_DIGEST_LENGTH 16
|
||||
|
||||
#elif defined(USE_NSS)
|
||||
|
||||
# include <nss.h>
|
||||
# include <pk11pub.h>
|
||||
# include <hasht.h>
|
||||
# include "curl_md4.h"
|
||||
# define MD5_DIGEST_LENGTH MD5_LENGTH
|
||||
|
||||
#elif defined(USE_MBEDTLS)
|
||||
|
||||
# include <mbedtls/des.h>
|
||||
# include <mbedtls/md4.h>
|
||||
# if !defined(MBEDTLS_MD4_C)
|
||||
# include "curl_md4.h"
|
||||
# endif
|
||||
|
||||
#elif defined(USE_SECTRANSP)
|
||||
|
||||
# include <CommonCrypto/CommonCryptor.h>
|
||||
# include <CommonCrypto/CommonDigest.h>
|
||||
|
||||
#elif defined(USE_OS400CRYPTO)
|
||||
# include "cipher.mih" /* mih/cipher */
|
||||
# include "curl_md4.h"
|
||||
#elif defined(USE_WIN32_CRYPTO)
|
||||
# include <wincrypt.h>
|
||||
#else
|
||||
# error "Can't compile NTLM support without a crypto library."
|
||||
#endif
|
||||
|
||||
#include "urldata.h"
|
||||
#include "non-ascii.h"
|
||||
#include "strcase.h"
|
||||
#include "curl_ntlm_core.h"
|
||||
#include "curl_md5.h"
|
||||
#include "curl_hmac.h"
|
||||
#include "warnless.h"
|
||||
#include "curl_endian.h"
|
||||
#include "curl_des.h"
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#define NTLM_HMAC_MD5_LEN (16)
|
||||
#define NTLMv2_BLOB_SIGNATURE "\x01\x01\x00\x00"
|
||||
#define NTLMv2_BLOB_LEN (44 -16 + ntlm->target_info_len + 4)
|
||||
|
||||
/*
|
||||
* Turns a 56-bit key into being 64-bit wide.
|
||||
*/
|
||||
static void extend_key_56_to_64(const unsigned char *key_56, char *key)
|
||||
{
|
||||
key[0] = key_56[0];
|
||||
key[1] = (unsigned char)(((key_56[0] << 7) & 0xFF) | (key_56[1] >> 1));
|
||||
key[2] = (unsigned char)(((key_56[1] << 6) & 0xFF) | (key_56[2] >> 2));
|
||||
key[3] = (unsigned char)(((key_56[2] << 5) & 0xFF) | (key_56[3] >> 3));
|
||||
key[4] = (unsigned char)(((key_56[3] << 4) & 0xFF) | (key_56[4] >> 4));
|
||||
key[5] = (unsigned char)(((key_56[4] << 3) & 0xFF) | (key_56[5] >> 5));
|
||||
key[6] = (unsigned char)(((key_56[5] << 2) & 0xFF) | (key_56[6] >> 6));
|
||||
key[7] = (unsigned char) ((key_56[6] << 1) & 0xFF);
|
||||
}
|
||||
|
||||
#ifdef USE_OPENSSL
|
||||
/*
|
||||
* Turns a 56 bit key into the 64 bit, odd parity key and sets the key. The
|
||||
* key schedule ks is also set.
|
||||
*/
|
||||
static void setup_des_key(const unsigned char *key_56,
|
||||
DES_key_schedule DESKEYARG(ks))
|
||||
{
|
||||
DES_cblock key;
|
||||
|
||||
/* Expand the 56-bit key to 64-bits */
|
||||
extend_key_56_to_64(key_56, (char *) &key);
|
||||
|
||||
/* Set the key parity to odd */
|
||||
DES_set_odd_parity(&key);
|
||||
|
||||
/* Set the key */
|
||||
DES_set_key(&key, ks);
|
||||
}
|
||||
|
||||
#elif defined(USE_GNUTLS_NETTLE)
|
||||
|
||||
static void setup_des_key(const unsigned char *key_56,
|
||||
struct des_ctx *des)
|
||||
{
|
||||
char key[8];
|
||||
|
||||
/* Expand the 56-bit key to 64-bits */
|
||||
extend_key_56_to_64(key_56, key);
|
||||
|
||||
/* Set the key parity to odd */
|
||||
Curl_des_set_odd_parity((unsigned char *) key, sizeof(key));
|
||||
|
||||
/* Set the key */
|
||||
des_set_key(des, (const uint8_t *) key);
|
||||
}
|
||||
|
||||
#elif defined(USE_GNUTLS)
|
||||
|
||||
/*
|
||||
* Turns a 56 bit key into the 64 bit, odd parity key and sets the key.
|
||||
*/
|
||||
static void setup_des_key(const unsigned char *key_56,
|
||||
gcry_cipher_hd_t *des)
|
||||
{
|
||||
char key[8];
|
||||
|
||||
/* Expand the 56-bit key to 64-bits */
|
||||
extend_key_56_to_64(key_56, key);
|
||||
|
||||
/* Set the key parity to odd */
|
||||
Curl_des_set_odd_parity((unsigned char *) key, sizeof(key));
|
||||
|
||||
/* Set the key */
|
||||
gcry_cipher_setkey(*des, key, sizeof(key));
|
||||
}
|
||||
|
||||
#elif defined(USE_NSS)
|
||||
|
||||
/*
|
||||
* Expands a 56 bit key KEY_56 to 64 bit and encrypts 64 bit of data, using
|
||||
* the expanded key. The caller is responsible for giving 64 bit of valid
|
||||
* data is IN and (at least) 64 bit large buffer as OUT.
|
||||
*/
|
||||
static bool encrypt_des(const unsigned char *in, unsigned char *out,
|
||||
const unsigned char *key_56)
|
||||
{
|
||||
const CK_MECHANISM_TYPE mech = CKM_DES_ECB; /* DES cipher in ECB mode */
|
||||
PK11SlotInfo *slot = NULL;
|
||||
char key[8]; /* expanded 64 bit key */
|
||||
SECItem key_item;
|
||||
PK11SymKey *symkey = NULL;
|
||||
SECItem *param = NULL;
|
||||
PK11Context *ctx = NULL;
|
||||
int out_len; /* not used, required by NSS */
|
||||
bool rv = FALSE;
|
||||
|
||||
/* use internal slot for DES encryption (requires NSS to be initialized) */
|
||||
slot = PK11_GetInternalKeySlot();
|
||||
if(!slot)
|
||||
return FALSE;
|
||||
|
||||
/* Expand the 56-bit key to 64-bits */
|
||||
extend_key_56_to_64(key_56, key);
|
||||
|
||||
/* Set the key parity to odd */
|
||||
Curl_des_set_odd_parity((unsigned char *) key, sizeof(key));
|
||||
|
||||
/* Import the key */
|
||||
key_item.data = (unsigned char *)key;
|
||||
key_item.len = sizeof(key);
|
||||
symkey = PK11_ImportSymKey(slot, mech, PK11_OriginUnwrap, CKA_ENCRYPT,
|
||||
&key_item, NULL);
|
||||
if(!symkey)
|
||||
goto fail;
|
||||
|
||||
/* Create the DES encryption context */
|
||||
param = PK11_ParamFromIV(mech, /* no IV in ECB mode */ NULL);
|
||||
if(!param)
|
||||
goto fail;
|
||||
ctx = PK11_CreateContextBySymKey(mech, CKA_ENCRYPT, symkey, param);
|
||||
if(!ctx)
|
||||
goto fail;
|
||||
|
||||
/* Perform the encryption */
|
||||
if(SECSuccess == PK11_CipherOp(ctx, out, &out_len, /* outbuflen */ 8,
|
||||
(unsigned char *)in, /* inbuflen */ 8)
|
||||
&& SECSuccess == PK11_Finalize(ctx))
|
||||
rv = /* all OK */ TRUE;
|
||||
|
||||
fail:
|
||||
/* cleanup */
|
||||
if(ctx)
|
||||
PK11_DestroyContext(ctx, PR_TRUE);
|
||||
if(symkey)
|
||||
PK11_FreeSymKey(symkey);
|
||||
if(param)
|
||||
SECITEM_FreeItem(param, PR_TRUE);
|
||||
PK11_FreeSlot(slot);
|
||||
return rv;
|
||||
}
|
||||
|
||||
#elif defined(USE_MBEDTLS)
|
||||
|
||||
static bool encrypt_des(const unsigned char *in, unsigned char *out,
|
||||
const unsigned char *key_56)
|
||||
{
|
||||
mbedtls_des_context ctx;
|
||||
char key[8];
|
||||
|
||||
/* Expand the 56-bit key to 64-bits */
|
||||
extend_key_56_to_64(key_56, key);
|
||||
|
||||
/* Set the key parity to odd */
|
||||
mbedtls_des_key_set_parity((unsigned char *) key);
|
||||
|
||||
/* Perform the encryption */
|
||||
mbedtls_des_init(&ctx);
|
||||
mbedtls_des_setkey_enc(&ctx, (unsigned char *) key);
|
||||
return mbedtls_des_crypt_ecb(&ctx, in, out) == 0;
|
||||
}
|
||||
|
||||
#elif defined(USE_SECTRANSP)
|
||||
|
||||
static bool encrypt_des(const unsigned char *in, unsigned char *out,
|
||||
const unsigned char *key_56)
|
||||
{
|
||||
char key[8];
|
||||
size_t out_len;
|
||||
CCCryptorStatus err;
|
||||
|
||||
/* Expand the 56-bit key to 64-bits */
|
||||
extend_key_56_to_64(key_56, key);
|
||||
|
||||
/* Set the key parity to odd */
|
||||
Curl_des_set_odd_parity((unsigned char *) key, sizeof(key));
|
||||
|
||||
/* Perform the encryption */
|
||||
err = CCCrypt(kCCEncrypt, kCCAlgorithmDES, kCCOptionECBMode, key,
|
||||
kCCKeySizeDES, NULL, in, 8 /* inbuflen */, out,
|
||||
8 /* outbuflen */, &out_len);
|
||||
|
||||
return err == kCCSuccess;
|
||||
}
|
||||
|
||||
#elif defined(USE_OS400CRYPTO)
|
||||
|
||||
static bool encrypt_des(const unsigned char *in, unsigned char *out,
|
||||
const unsigned char *key_56)
|
||||
{
|
||||
char key[8];
|
||||
_CIPHER_Control_T ctl;
|
||||
|
||||
/* Setup the cipher control structure */
|
||||
ctl.Func_ID = ENCRYPT_ONLY;
|
||||
ctl.Data_Len = sizeof(key);
|
||||
|
||||
/* Expand the 56-bit key to 64-bits */
|
||||
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);
|
||||
|
||||
/* Perform the encryption */
|
||||
_CIPHER((_SPCPTR *) &out, &ctl, (_SPCPTR *) &in);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#elif defined(USE_WIN32_CRYPTO)
|
||||
|
||||
static bool encrypt_des(const unsigned char *in, unsigned char *out,
|
||||
const unsigned char *key_56)
|
||||
{
|
||||
HCRYPTPROV hprov;
|
||||
HCRYPTKEY hkey;
|
||||
struct {
|
||||
BLOBHEADER hdr;
|
||||
unsigned int len;
|
||||
char key[8];
|
||||
} blob;
|
||||
DWORD len = 8;
|
||||
|
||||
/* Acquire the crypto provider */
|
||||
if(!CryptAcquireContext(&hprov, NULL, NULL, PROV_RSA_FULL,
|
||||
CRYPT_VERIFYCONTEXT))
|
||||
return FALSE;
|
||||
|
||||
/* Setup the key blob structure */
|
||||
memset(&blob, 0, sizeof(blob));
|
||||
blob.hdr.bType = PLAINTEXTKEYBLOB;
|
||||
blob.hdr.bVersion = 2;
|
||||
blob.hdr.aiKeyAlg = CALG_DES;
|
||||
blob.len = sizeof(blob.key);
|
||||
|
||||
/* Expand the 56-bit key to 64-bits */
|
||||
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));
|
||||
|
||||
/* Import the key */
|
||||
if(!CryptImportKey(hprov, (BYTE *) &blob, sizeof(blob), 0, 0, &hkey)) {
|
||||
CryptReleaseContext(hprov, 0);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
memcpy(out, in, 8);
|
||||
|
||||
/* Perform the encryption */
|
||||
CryptEncrypt(hkey, 0, FALSE, 0, out, &len, len);
|
||||
|
||||
CryptDestroyKey(hkey);
|
||||
CryptReleaseContext(hprov, 0);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#endif /* defined(USE_WIN32_CRYPTO) */
|
||||
|
||||
/*
|
||||
* takes a 21 byte array and treats it as 3 56-bit DES keys. The
|
||||
* 8 byte plaintext is encrypted with each key and the resulting 24
|
||||
* bytes are stored in the results array.
|
||||
*/
|
||||
void Curl_ntlm_core_lm_resp(const unsigned char *keys,
|
||||
const unsigned char *plaintext,
|
||||
unsigned char *results)
|
||||
{
|
||||
#ifdef USE_OPENSSL
|
||||
DES_key_schedule ks;
|
||||
|
||||
setup_des_key(keys, DESKEY(ks));
|
||||
DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) results,
|
||||
DESKEY(ks), DES_ENCRYPT);
|
||||
|
||||
setup_des_key(keys + 7, DESKEY(ks));
|
||||
DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results + 8),
|
||||
DESKEY(ks), DES_ENCRYPT);
|
||||
|
||||
setup_des_key(keys + 14, DESKEY(ks));
|
||||
DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results + 16),
|
||||
DESKEY(ks), DES_ENCRYPT);
|
||||
#elif defined(USE_GNUTLS_NETTLE)
|
||||
struct des_ctx des;
|
||||
setup_des_key(keys, &des);
|
||||
des_encrypt(&des, 8, results, plaintext);
|
||||
setup_des_key(keys + 7, &des);
|
||||
des_encrypt(&des, 8, results + 8, plaintext);
|
||||
setup_des_key(keys + 14, &des);
|
||||
des_encrypt(&des, 8, results + 16, plaintext);
|
||||
#elif defined(USE_GNUTLS)
|
||||
gcry_cipher_hd_t des;
|
||||
|
||||
gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
|
||||
setup_des_key(keys, &des);
|
||||
gcry_cipher_encrypt(des, results, 8, plaintext, 8);
|
||||
gcry_cipher_close(des);
|
||||
|
||||
gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
|
||||
setup_des_key(keys + 7, &des);
|
||||
gcry_cipher_encrypt(des, results + 8, 8, plaintext, 8);
|
||||
gcry_cipher_close(des);
|
||||
|
||||
gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
|
||||
setup_des_key(keys + 14, &des);
|
||||
gcry_cipher_encrypt(des, results + 16, 8, plaintext, 8);
|
||||
gcry_cipher_close(des);
|
||||
#elif defined(USE_NSS) || defined(USE_MBEDTLS) || defined(USE_SECTRANSP) \
|
||||
|| defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO)
|
||||
encrypt_des(plaintext, results, keys);
|
||||
encrypt_des(plaintext, results + 8, keys + 7);
|
||||
encrypt_des(plaintext, results + 16, keys + 14);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up lanmanager hashed password
|
||||
*/
|
||||
CURLcode Curl_ntlm_core_mk_lm_hash(struct Curl_easy *data,
|
||||
const char *password,
|
||||
unsigned char *lmbuffer /* 21 bytes */)
|
||||
{
|
||||
CURLcode result;
|
||||
unsigned char pw[14];
|
||||
static const unsigned char magic[] = {
|
||||
0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 /* i.e. KGS!@#$% */
|
||||
};
|
||||
size_t len = CURLMIN(strlen(password), 14);
|
||||
|
||||
Curl_strntoupper((char *)pw, password, len);
|
||||
memset(&pw[len], 0, 14 - len);
|
||||
|
||||
/*
|
||||
* The LanManager hashed password needs to be created using the
|
||||
* password in the network encoding not the host encoding.
|
||||
*/
|
||||
result = Curl_convert_to_network(data, (char *)pw, 14);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
{
|
||||
/* Create LanManager hashed password. */
|
||||
|
||||
#ifdef USE_OPENSSL
|
||||
DES_key_schedule ks;
|
||||
|
||||
setup_des_key(pw, DESKEY(ks));
|
||||
DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)lmbuffer,
|
||||
DESKEY(ks), DES_ENCRYPT);
|
||||
|
||||
setup_des_key(pw + 7, DESKEY(ks));
|
||||
DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)(lmbuffer + 8),
|
||||
DESKEY(ks), DES_ENCRYPT);
|
||||
#elif defined(USE_GNUTLS_NETTLE)
|
||||
struct des_ctx des;
|
||||
setup_des_key(pw, &des);
|
||||
des_encrypt(&des, 8, lmbuffer, magic);
|
||||
setup_des_key(pw + 7, &des);
|
||||
des_encrypt(&des, 8, lmbuffer + 8, magic);
|
||||
#elif defined(USE_GNUTLS)
|
||||
gcry_cipher_hd_t des;
|
||||
|
||||
gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
|
||||
setup_des_key(pw, &des);
|
||||
gcry_cipher_encrypt(des, lmbuffer, 8, magic, 8);
|
||||
gcry_cipher_close(des);
|
||||
|
||||
gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
|
||||
setup_des_key(pw + 7, &des);
|
||||
gcry_cipher_encrypt(des, lmbuffer + 8, 8, magic, 8);
|
||||
gcry_cipher_close(des);
|
||||
#elif defined(USE_NSS) || defined(USE_MBEDTLS) || defined(USE_SECTRANSP) \
|
||||
|| defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO)
|
||||
encrypt_des(magic, lmbuffer, pw);
|
||||
encrypt_des(magic, lmbuffer + 8, pw + 7);
|
||||
#endif
|
||||
|
||||
memset(lmbuffer + 16, 0, 21 - 16);
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
#ifdef USE_NTRESPONSES
|
||||
static void ascii_to_unicode_le(unsigned char *dest, const char *src,
|
||||
size_t srclen)
|
||||
{
|
||||
size_t i;
|
||||
for(i = 0; i < srclen; i++) {
|
||||
dest[2 * i] = (unsigned char)src[i];
|
||||
dest[2 * i + 1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(USE_NTLM_V2) && !defined(USE_WINDOWS_SSPI)
|
||||
|
||||
static void ascii_uppercase_to_unicode_le(unsigned char *dest,
|
||||
const char *src, size_t srclen)
|
||||
{
|
||||
size_t i;
|
||||
for(i = 0; i < srclen; i++) {
|
||||
dest[2 * i] = (unsigned char)(Curl_raw_toupper(src[i]));
|
||||
dest[2 * i + 1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* USE_NTLM_V2 && !USE_WINDOWS_SSPI */
|
||||
|
||||
/*
|
||||
* Set up nt hashed passwords
|
||||
* @unittest: 1600
|
||||
*/
|
||||
CURLcode Curl_ntlm_core_mk_nt_hash(struct Curl_easy *data,
|
||||
const char *password,
|
||||
unsigned char *ntbuffer /* 21 bytes */)
|
||||
{
|
||||
size_t len = strlen(password);
|
||||
unsigned char *pw;
|
||||
CURLcode result;
|
||||
if(len > SIZE_T_MAX/2) /* avoid integer overflow */
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
pw = len ? malloc(len * 2) : strdup("");
|
||||
if(!pw)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
ascii_to_unicode_le(pw, password, len);
|
||||
|
||||
/*
|
||||
* The NT hashed password needs to be created using the password in the
|
||||
* network encoding not the host encoding.
|
||||
*/
|
||||
result = Curl_convert_to_network(data, (char *)pw, len * 2);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
{
|
||||
/* Create NT hashed password. */
|
||||
#ifdef USE_OPENSSL
|
||||
#if !defined(OPENSSL_NO_MD4)
|
||||
MD4_CTX MD4pw;
|
||||
MD4_Init(&MD4pw);
|
||||
MD4_Update(&MD4pw, pw, 2 * len);
|
||||
MD4_Final(ntbuffer, &MD4pw);
|
||||
#else
|
||||
Curl_md4it(ntbuffer, pw, 2 * len);
|
||||
#endif
|
||||
#elif defined(USE_GNUTLS_NETTLE)
|
||||
struct md4_ctx MD4pw;
|
||||
md4_init(&MD4pw);
|
||||
md4_update(&MD4pw, (unsigned int)(2 * len), pw);
|
||||
md4_digest(&MD4pw, MD4_DIGEST_SIZE, ntbuffer);
|
||||
#elif defined(USE_GNUTLS)
|
||||
gcry_md_hd_t MD4pw;
|
||||
gcry_md_open(&MD4pw, GCRY_MD_MD4, 0);
|
||||
gcry_md_write(MD4pw, pw, 2 * len);
|
||||
memcpy(ntbuffer, gcry_md_read(MD4pw, 0), MD4_DIGEST_LENGTH);
|
||||
gcry_md_close(MD4pw);
|
||||
#elif defined(USE_NSS)
|
||||
Curl_md4it(ntbuffer, pw, 2 * len);
|
||||
#elif defined(USE_MBEDTLS)
|
||||
#if defined(MBEDTLS_MD4_C)
|
||||
mbedtls_md4(pw, 2 * len, ntbuffer);
|
||||
#else
|
||||
Curl_md4it(ntbuffer, pw, 2 * len);
|
||||
#endif
|
||||
#elif defined(USE_SECTRANSP)
|
||||
(void)CC_MD4(pw, (CC_LONG)(2 * len), ntbuffer);
|
||||
#elif defined(USE_OS400CRYPTO)
|
||||
Curl_md4it(ntbuffer, pw, 2 * len);
|
||||
#elif defined(USE_WIN32_CRYPTO)
|
||||
HCRYPTPROV hprov;
|
||||
if(CryptAcquireContext(&hprov, NULL, NULL, PROV_RSA_FULL,
|
||||
CRYPT_VERIFYCONTEXT)) {
|
||||
HCRYPTHASH hhash;
|
||||
if(CryptCreateHash(hprov, CALG_MD4, 0, 0, &hhash)) {
|
||||
DWORD length = 16;
|
||||
CryptHashData(hhash, pw, (unsigned int)len * 2, 0);
|
||||
CryptGetHashParam(hhash, HP_HASHVAL, ntbuffer, &length, 0);
|
||||
CryptDestroyHash(hhash);
|
||||
}
|
||||
CryptReleaseContext(hprov, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
memset(ntbuffer + 16, 0, 21 - 16);
|
||||
}
|
||||
|
||||
free(pw);
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
#if defined(USE_NTLM_V2) && !defined(USE_WINDOWS_SSPI)
|
||||
|
||||
/* This returns the HMAC MD5 digest */
|
||||
static CURLcode hmac_md5(const unsigned char *key, unsigned int keylen,
|
||||
const unsigned char *data, unsigned int datalen,
|
||||
unsigned char *output)
|
||||
{
|
||||
HMAC_context *ctxt = Curl_HMAC_init(Curl_HMAC_MD5, key, keylen);
|
||||
|
||||
if(!ctxt)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
/* Update the digest with the given challenge */
|
||||
Curl_HMAC_update(ctxt, data, datalen);
|
||||
|
||||
/* Finalise the digest */
|
||||
Curl_HMAC_final(ctxt, output);
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/* This creates the NTLMv2 hash by using NTLM hash as the key and Unicode
|
||||
* (uppercase UserName + Domain) as the data
|
||||
*/
|
||||
CURLcode Curl_ntlm_core_mk_ntlmv2_hash(const char *user, size_t userlen,
|
||||
const char *domain, size_t domlen,
|
||||
unsigned char *ntlmhash,
|
||||
unsigned char *ntlmv2hash)
|
||||
{
|
||||
/* Unicode representation */
|
||||
size_t identity_len;
|
||||
unsigned char *identity;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
/* we do the length checks below separately to avoid integer overflow risk
|
||||
on extreme data lengths */
|
||||
if((userlen > SIZE_T_MAX/2) ||
|
||||
(domlen > SIZE_T_MAX/2) ||
|
||||
((userlen + domlen) > SIZE_T_MAX/2))
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
identity_len = (userlen + domlen) * 2;
|
||||
identity = malloc(identity_len);
|
||||
|
||||
if(!identity)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
ascii_uppercase_to_unicode_le(identity, user, userlen);
|
||||
ascii_to_unicode_le(identity + (userlen << 1), domain, domlen);
|
||||
|
||||
result = hmac_md5(ntlmhash, 16, identity, curlx_uztoui(identity_len),
|
||||
ntlmv2hash);
|
||||
free(identity);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_ntlm_core_mk_ntlmv2_resp()
|
||||
*
|
||||
* This creates the NTLMv2 response as set in the ntlm type-3 message.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* ntlmv2hash [in] - The ntlmv2 hash (16 bytes)
|
||||
* challenge_client [in] - The client nonce (8 bytes)
|
||||
* ntlm [in] - The ntlm data struct being used to read TargetInfo
|
||||
and Server challenge received in the type-2 message
|
||||
* ntresp [out] - The address where a pointer to newly allocated
|
||||
* memory holding the NTLMv2 response.
|
||||
* ntresp_len [out] - The length of the output message.
|
||||
*
|
||||
* Returns CURLE_OK on success.
|
||||
*/
|
||||
CURLcode Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash,
|
||||
unsigned char *challenge_client,
|
||||
struct ntlmdata *ntlm,
|
||||
unsigned char **ntresp,
|
||||
unsigned int *ntresp_len)
|
||||
{
|
||||
/* NTLMv2 response structure :
|
||||
------------------------------------------------------------------------------
|
||||
0 HMAC MD5 16 bytes
|
||||
------BLOB--------------------------------------------------------------------
|
||||
16 Signature 0x01010000
|
||||
20 Reserved long (0x00000000)
|
||||
24 Timestamp LE, 64-bit signed value representing the number of
|
||||
tenths of a microsecond since January 1, 1601.
|
||||
32 Client Nonce 8 bytes
|
||||
40 Unknown 4 bytes
|
||||
44 Target Info N bytes (from the type-2 message)
|
||||
44+N Unknown 4 bytes
|
||||
------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
unsigned int len = 0;
|
||||
unsigned char *ptr = NULL;
|
||||
unsigned char hmac_output[NTLM_HMAC_MD5_LEN];
|
||||
curl_off_t tw;
|
||||
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
#if CURL_SIZEOF_CURL_OFF_T < 8
|
||||
#error "this section needs 64bit support to work"
|
||||
#endif
|
||||
|
||||
/* Calculate the timestamp */
|
||||
#ifdef DEBUGBUILD
|
||||
char *force_timestamp = getenv("CURL_FORCETIME");
|
||||
if(force_timestamp)
|
||||
tw = CURL_OFF_T_C(11644473600) * 10000000;
|
||||
else
|
||||
#endif
|
||||
tw = ((curl_off_t)time(NULL) + CURL_OFF_T_C(11644473600)) * 10000000;
|
||||
|
||||
/* Calculate the response len */
|
||||
len = NTLM_HMAC_MD5_LEN + NTLMv2_BLOB_LEN;
|
||||
|
||||
/* Allocate the response */
|
||||
ptr = calloc(1, len);
|
||||
if(!ptr)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
/* Create the BLOB structure */
|
||||
msnprintf((char *)ptr + NTLM_HMAC_MD5_LEN, NTLMv2_BLOB_LEN,
|
||||
"%c%c%c%c" /* NTLMv2_BLOB_SIGNATURE */
|
||||
"%c%c%c%c", /* Reserved = 0 */
|
||||
NTLMv2_BLOB_SIGNATURE[0], NTLMv2_BLOB_SIGNATURE[1],
|
||||
NTLMv2_BLOB_SIGNATURE[2], NTLMv2_BLOB_SIGNATURE[3],
|
||||
0, 0, 0, 0);
|
||||
|
||||
Curl_write64_le(tw, ptr + 24);
|
||||
memcpy(ptr + 32, challenge_client, 8);
|
||||
memcpy(ptr + 44, ntlm->target_info, ntlm->target_info_len);
|
||||
|
||||
/* Concatenate the Type 2 challenge with the BLOB and do HMAC MD5 */
|
||||
memcpy(ptr + 8, &ntlm->nonce[0], 8);
|
||||
result = hmac_md5(ntlmv2hash, NTLM_HMAC_MD5_LEN, ptr + 8,
|
||||
NTLMv2_BLOB_LEN + 8, hmac_output);
|
||||
if(result) {
|
||||
free(ptr);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Concatenate the HMAC MD5 output with the BLOB */
|
||||
memcpy(ptr, hmac_output, NTLM_HMAC_MD5_LEN);
|
||||
|
||||
/* Return the response */
|
||||
*ntresp = ptr;
|
||||
*ntresp_len = len;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_ntlm_core_mk_lmv2_resp()
|
||||
*
|
||||
* This creates the LMv2 response as used in the ntlm type-3 message.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* ntlmv2hash [in] - The ntlmv2 hash (16 bytes)
|
||||
* challenge_client [in] - The client nonce (8 bytes)
|
||||
* challenge_client [in] - The server challenge (8 bytes)
|
||||
* lmresp [out] - The LMv2 response (24 bytes)
|
||||
*
|
||||
* Returns CURLE_OK on success.
|
||||
*/
|
||||
CURLcode Curl_ntlm_core_mk_lmv2_resp(unsigned char *ntlmv2hash,
|
||||
unsigned char *challenge_client,
|
||||
unsigned char *challenge_server,
|
||||
unsigned char *lmresp)
|
||||
{
|
||||
unsigned char data[16];
|
||||
unsigned char hmac_output[16];
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
memcpy(&data[0], challenge_server, 8);
|
||||
memcpy(&data[8], challenge_client, 8);
|
||||
|
||||
result = hmac_md5(ntlmv2hash, 16, &data[0], 16, hmac_output);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
/* Concatenate the HMAC MD5 output with the client nonce */
|
||||
memcpy(lmresp, hmac_output, 16);
|
||||
memcpy(lmresp + 16, challenge_client, 8);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* USE_NTLM_V2 && !USE_WINDOWS_SSPI */
|
||||
|
||||
#endif /* USE_NTRESPONSES */
|
||||
|
||||
#endif /* !USE_WINDOWS_SSPI || USE_WIN32_CRYPTO */
|
||||
|
||||
#endif /* USE_NTLM */
|
105
src/dependencies/cmcurl/lib/curl_ntlm_core.h
Normal file
105
src/dependencies/cmcurl/lib/curl_ntlm_core.h
Normal file
|
@ -0,0 +1,105 @@
|
|||
#ifndef HEADER_CURL_NTLM_CORE_H
|
||||
#define HEADER_CURL_NTLM_CORE_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if defined(USE_NTLM)
|
||||
|
||||
/* If NSS is the first available SSL backend (see order in curl_ntlm_core.c)
|
||||
then it must be initialized to be used by NTLM. */
|
||||
#if !defined(USE_OPENSSL) && \
|
||||
!defined(USE_GNUTLS_NETTLE) && \
|
||||
!defined(USE_GNUTLS) && \
|
||||
defined(USE_NSS)
|
||||
#define NTLM_NEEDS_NSS_INIT
|
||||
#endif
|
||||
|
||||
#if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO)
|
||||
|
||||
#ifdef USE_OPENSSL
|
||||
# include <openssl/ssl.h>
|
||||
#endif
|
||||
|
||||
/* Define USE_NTRESPONSES in order to make the type-3 message include
|
||||
* the NT response message. */
|
||||
#define USE_NTRESPONSES
|
||||
|
||||
/* Define USE_NTLM2SESSION in order to make the type-3 message include the
|
||||
NTLM2Session response message, requires USE_NTRESPONSES defined to 1 and a
|
||||
Crypto engine that we have curl_ssl_md5sum() for. */
|
||||
#if defined(USE_NTRESPONSES) && !defined(USE_WIN32_CRYPTO)
|
||||
#define USE_NTLM2SESSION
|
||||
#endif
|
||||
|
||||
/* Define USE_NTLM_V2 in order to allow the type-3 message to include the
|
||||
LMv2 and NTLMv2 response messages, requires USE_NTRESPONSES defined to 1
|
||||
and support for 64-bit integers. */
|
||||
#if defined(USE_NTRESPONSES) && (CURL_SIZEOF_CURL_OFF_T > 4)
|
||||
#define USE_NTLM_V2
|
||||
#endif
|
||||
|
||||
void Curl_ntlm_core_lm_resp(const unsigned char *keys,
|
||||
const unsigned char *plaintext,
|
||||
unsigned char *results);
|
||||
|
||||
CURLcode Curl_ntlm_core_mk_lm_hash(struct Curl_easy *data,
|
||||
const char *password,
|
||||
unsigned char *lmbuffer /* 21 bytes */);
|
||||
|
||||
#ifdef USE_NTRESPONSES
|
||||
CURLcode Curl_ntlm_core_mk_nt_hash(struct Curl_easy *data,
|
||||
const char *password,
|
||||
unsigned char *ntbuffer /* 21 bytes */);
|
||||
|
||||
#if defined(USE_NTLM_V2) && !defined(USE_WINDOWS_SSPI)
|
||||
|
||||
CURLcode Curl_hmac_md5(const unsigned char *key, unsigned int keylen,
|
||||
const unsigned char *data, unsigned int datalen,
|
||||
unsigned char *output);
|
||||
|
||||
CURLcode Curl_ntlm_core_mk_ntlmv2_hash(const char *user, size_t userlen,
|
||||
const char *domain, size_t domlen,
|
||||
unsigned char *ntlmhash,
|
||||
unsigned char *ntlmv2hash);
|
||||
|
||||
CURLcode Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash,
|
||||
unsigned char *challenge_client,
|
||||
struct ntlmdata *ntlm,
|
||||
unsigned char **ntresp,
|
||||
unsigned int *ntresp_len);
|
||||
|
||||
CURLcode Curl_ntlm_core_mk_lmv2_resp(unsigned char *ntlmv2hash,
|
||||
unsigned char *challenge_client,
|
||||
unsigned char *challenge_server,
|
||||
unsigned char *lmresp);
|
||||
|
||||
#endif /* USE_NTLM_V2 && !USE_WINDOWS_SSPI */
|
||||
|
||||
#endif /* USE_NTRESPONSES */
|
||||
|
||||
#endif /* !USE_WINDOWS_SSPI || USE_WIN32_CRYPTO */
|
||||
|
||||
#endif /* USE_NTLM */
|
||||
|
||||
#endif /* HEADER_CURL_NTLM_CORE_H */
|
489
src/dependencies/cmcurl/lib/curl_ntlm_wb.c
Normal file
489
src/dependencies/cmcurl/lib/curl_ntlm_wb.c
Normal file
|
@ -0,0 +1,489 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \
|
||||
defined(NTLM_WB_ENABLED)
|
||||
|
||||
/*
|
||||
* NTLM details:
|
||||
*
|
||||
* https://davenport.sourceforge.io/ntlm.html
|
||||
* https://www.innovation.ch/java/ntlm.html
|
||||
*/
|
||||
|
||||
#define DEBUG_ME 0
|
||||
|
||||
#ifdef HAVE_SYS_WAIT_H
|
||||
#include <sys/wait.h>
|
||||
#endif
|
||||
#ifdef HAVE_SIGNAL_H
|
||||
#include <signal.h>
|
||||
#endif
|
||||
#ifdef HAVE_PWD_H
|
||||
#include <pwd.h>
|
||||
#endif
|
||||
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
#include "select.h"
|
||||
#include "vauth/ntlm.h"
|
||||
#include "curl_ntlm_core.h"
|
||||
#include "curl_ntlm_wb.h"
|
||||
#include "url.h"
|
||||
#include "strerror.h"
|
||||
#include "strdup.h"
|
||||
#include "strcase.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#if DEBUG_ME
|
||||
# define DEBUG_OUT(x) x
|
||||
#else
|
||||
# define DEBUG_OUT(x) Curl_nop_stmt
|
||||
#endif
|
||||
|
||||
/* Portable 'sclose_nolog' used only in child process instead of 'sclose'
|
||||
to avoid fooling the socket leak detector */
|
||||
#if defined(HAVE_CLOSESOCKET)
|
||||
# define sclose_nolog(x) closesocket((x))
|
||||
#elif defined(HAVE_CLOSESOCKET_CAMEL)
|
||||
# define sclose_nolog(x) CloseSocket((x))
|
||||
#else
|
||||
# define sclose_nolog(x) close((x))
|
||||
#endif
|
||||
|
||||
void Curl_http_auth_cleanup_ntlm_wb(struct connectdata *conn)
|
||||
{
|
||||
if(conn->ntlm_auth_hlpr_socket != CURL_SOCKET_BAD) {
|
||||
sclose(conn->ntlm_auth_hlpr_socket);
|
||||
conn->ntlm_auth_hlpr_socket = CURL_SOCKET_BAD;
|
||||
}
|
||||
|
||||
if(conn->ntlm_auth_hlpr_pid) {
|
||||
int i;
|
||||
for(i = 0; i < 4; i++) {
|
||||
pid_t ret = waitpid(conn->ntlm_auth_hlpr_pid, NULL, WNOHANG);
|
||||
if(ret == conn->ntlm_auth_hlpr_pid || errno == ECHILD)
|
||||
break;
|
||||
switch(i) {
|
||||
case 0:
|
||||
kill(conn->ntlm_auth_hlpr_pid, SIGTERM);
|
||||
break;
|
||||
case 1:
|
||||
/* Give the process another moment to shut down cleanly before
|
||||
bringing down the axe */
|
||||
Curl_wait_ms(1);
|
||||
break;
|
||||
case 2:
|
||||
kill(conn->ntlm_auth_hlpr_pid, SIGKILL);
|
||||
break;
|
||||
case 3:
|
||||
break;
|
||||
}
|
||||
}
|
||||
conn->ntlm_auth_hlpr_pid = 0;
|
||||
}
|
||||
|
||||
free(conn->challenge_header);
|
||||
conn->challenge_header = NULL;
|
||||
free(conn->response_header);
|
||||
conn->response_header = NULL;
|
||||
}
|
||||
|
||||
static CURLcode ntlm_wb_init(struct connectdata *conn, const char *userp)
|
||||
{
|
||||
curl_socket_t sockfds[2];
|
||||
pid_t child_pid;
|
||||
const char *username;
|
||||
char *slash, *domain = NULL;
|
||||
const char *ntlm_auth = NULL;
|
||||
char *ntlm_auth_alloc = NULL;
|
||||
#if defined(HAVE_GETPWUID_R) && defined(HAVE_GETEUID)
|
||||
struct passwd pw, *pw_res;
|
||||
char pwbuf[1024];
|
||||
#endif
|
||||
char buffer[STRERROR_LEN];
|
||||
|
||||
/* Return if communication with ntlm_auth already set up */
|
||||
if(conn->ntlm_auth_hlpr_socket != CURL_SOCKET_BAD ||
|
||||
conn->ntlm_auth_hlpr_pid)
|
||||
return CURLE_OK;
|
||||
|
||||
username = userp;
|
||||
/* The real ntlm_auth really doesn't like being invoked with an
|
||||
empty username. It won't make inferences for itself, and expects
|
||||
the client to do so (mostly because it's really designed for
|
||||
servers like squid to use for auth, and client support is an
|
||||
afterthought for it). So try hard to provide a suitable username
|
||||
if we don't already have one. But if we can't, provide the
|
||||
empty one anyway. Perhaps they have an implementation of the
|
||||
ntlm_auth helper which *doesn't* need it so we might as well try */
|
||||
if(!username || !username[0]) {
|
||||
username = getenv("NTLMUSER");
|
||||
if(!username || !username[0])
|
||||
username = getenv("LOGNAME");
|
||||
if(!username || !username[0])
|
||||
username = getenv("USER");
|
||||
#if defined(HAVE_GETPWUID_R) && defined(HAVE_GETEUID)
|
||||
if((!username || !username[0]) &&
|
||||
!getpwuid_r(geteuid(), &pw, pwbuf, sizeof(pwbuf), &pw_res) &&
|
||||
pw_res) {
|
||||
username = pw.pw_name;
|
||||
}
|
||||
#endif
|
||||
if(!username || !username[0])
|
||||
username = userp;
|
||||
}
|
||||
slash = strpbrk(username, "\\/");
|
||||
if(slash) {
|
||||
domain = strdup(username);
|
||||
if(!domain)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
slash = domain + (slash - username);
|
||||
*slash = '\0';
|
||||
username = username + (slash - domain) + 1;
|
||||
}
|
||||
|
||||
/* For testing purposes, when DEBUGBUILD is defined and environment
|
||||
variable CURL_NTLM_WB_FILE is set a fake_ntlm is used to perform
|
||||
NTLM challenge/response which only accepts commands and output
|
||||
strings pre-written in test case definitions */
|
||||
#ifdef DEBUGBUILD
|
||||
ntlm_auth_alloc = curl_getenv("CURL_NTLM_WB_FILE");
|
||||
if(ntlm_auth_alloc)
|
||||
ntlm_auth = ntlm_auth_alloc;
|
||||
else
|
||||
#endif
|
||||
ntlm_auth = NTLM_WB_FILE;
|
||||
|
||||
if(access(ntlm_auth, X_OK) != 0) {
|
||||
failf(conn->data, "Could not access ntlm_auth: %s errno %d: %s",
|
||||
ntlm_auth, errno, Curl_strerror(errno, buffer, sizeof(buffer)));
|
||||
goto done;
|
||||
}
|
||||
|
||||
if(socketpair(AF_UNIX, SOCK_STREAM, 0, sockfds)) {
|
||||
failf(conn->data, "Could not open socket pair. errno %d: %s",
|
||||
errno, Curl_strerror(errno, buffer, sizeof(buffer)));
|
||||
goto done;
|
||||
}
|
||||
|
||||
child_pid = fork();
|
||||
if(child_pid == -1) {
|
||||
sclose(sockfds[0]);
|
||||
sclose(sockfds[1]);
|
||||
failf(conn->data, "Could not fork. errno %d: %s",
|
||||
errno, Curl_strerror(errno, buffer, sizeof(buffer)));
|
||||
goto done;
|
||||
}
|
||||
else if(!child_pid) {
|
||||
/*
|
||||
* child process
|
||||
*/
|
||||
|
||||
/* Don't use sclose in the child since it fools the socket leak detector */
|
||||
sclose_nolog(sockfds[0]);
|
||||
if(dup2(sockfds[1], STDIN_FILENO) == -1) {
|
||||
failf(conn->data, "Could not redirect child stdin. errno %d: %s",
|
||||
errno, Curl_strerror(errno, buffer, sizeof(buffer)));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if(dup2(sockfds[1], STDOUT_FILENO) == -1) {
|
||||
failf(conn->data, "Could not redirect child stdout. errno %d: %s",
|
||||
errno, Curl_strerror(errno, buffer, sizeof(buffer)));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if(domain)
|
||||
execl(ntlm_auth, ntlm_auth,
|
||||
"--helper-protocol", "ntlmssp-client-1",
|
||||
"--use-cached-creds",
|
||||
"--username", username,
|
||||
"--domain", domain,
|
||||
NULL);
|
||||
else
|
||||
execl(ntlm_auth, ntlm_auth,
|
||||
"--helper-protocol", "ntlmssp-client-1",
|
||||
"--use-cached-creds",
|
||||
"--username", username,
|
||||
NULL);
|
||||
|
||||
sclose_nolog(sockfds[1]);
|
||||
failf(conn->data, "Could not execl(). errno %d: %s",
|
||||
errno, Curl_strerror(errno, buffer, sizeof(buffer)));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
sclose(sockfds[1]);
|
||||
conn->ntlm_auth_hlpr_socket = sockfds[0];
|
||||
conn->ntlm_auth_hlpr_pid = child_pid;
|
||||
free(domain);
|
||||
free(ntlm_auth_alloc);
|
||||
return CURLE_OK;
|
||||
|
||||
done:
|
||||
free(domain);
|
||||
free(ntlm_auth_alloc);
|
||||
return CURLE_REMOTE_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
/* if larger than this, something is seriously wrong */
|
||||
#define MAX_NTLM_WB_RESPONSE 100000
|
||||
|
||||
static CURLcode ntlm_wb_response(struct connectdata *conn,
|
||||
const char *input, curlntlm state)
|
||||
{
|
||||
char *buf = malloc(NTLM_BUFSIZE);
|
||||
size_t len_in = strlen(input), len_out = 0;
|
||||
|
||||
if(!buf)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
while(len_in > 0) {
|
||||
ssize_t written = swrite(conn->ntlm_auth_hlpr_socket, input, len_in);
|
||||
if(written == -1) {
|
||||
/* Interrupted by a signal, retry it */
|
||||
if(errno == EINTR)
|
||||
continue;
|
||||
/* write failed if other errors happen */
|
||||
goto done;
|
||||
}
|
||||
input += written;
|
||||
len_in -= written;
|
||||
}
|
||||
/* Read one line */
|
||||
while(1) {
|
||||
ssize_t size;
|
||||
char *newbuf;
|
||||
|
||||
size = sread(conn->ntlm_auth_hlpr_socket, buf + len_out, NTLM_BUFSIZE);
|
||||
if(size == -1) {
|
||||
if(errno == EINTR)
|
||||
continue;
|
||||
goto done;
|
||||
}
|
||||
else if(size == 0)
|
||||
goto done;
|
||||
|
||||
len_out += size;
|
||||
if(buf[len_out - 1] == '\n') {
|
||||
buf[len_out - 1] = '\0';
|
||||
break;
|
||||
}
|
||||
|
||||
if(len_out > MAX_NTLM_WB_RESPONSE) {
|
||||
failf(conn->data, "too large ntlm_wb response!");
|
||||
free(buf);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
newbuf = Curl_saferealloc(buf, len_out + NTLM_BUFSIZE);
|
||||
if(!newbuf)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
buf = newbuf;
|
||||
}
|
||||
|
||||
/* Samba/winbind installed but not configured */
|
||||
if(state == NTLMSTATE_TYPE1 &&
|
||||
len_out == 3 &&
|
||||
buf[0] == 'P' && buf[1] == 'W')
|
||||
goto done;
|
||||
/* invalid response */
|
||||
if(len_out < 4)
|
||||
goto done;
|
||||
if(state == NTLMSTATE_TYPE1 &&
|
||||
(buf[0]!='Y' || buf[1]!='R' || buf[2]!=' '))
|
||||
goto done;
|
||||
if(state == NTLMSTATE_TYPE2 &&
|
||||
(buf[0]!='K' || buf[1]!='K' || buf[2]!=' ') &&
|
||||
(buf[0]!='A' || buf[1]!='F' || buf[2]!=' '))
|
||||
goto done;
|
||||
|
||||
conn->response_header = aprintf("NTLM %.*s", len_out - 4, buf + 3);
|
||||
free(buf);
|
||||
if(!conn->response_header)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
return CURLE_OK;
|
||||
done:
|
||||
free(buf);
|
||||
return CURLE_REMOTE_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
CURLcode Curl_input_ntlm_wb(struct connectdata *conn,
|
||||
bool proxy,
|
||||
const char *header)
|
||||
{
|
||||
curlntlm *state = proxy ? &conn->proxy_ntlm_state : &conn->http_ntlm_state;
|
||||
|
||||
if(!checkprefix("NTLM", header))
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
|
||||
header += strlen("NTLM");
|
||||
while(*header && ISSPACE(*header))
|
||||
header++;
|
||||
|
||||
if(*header) {
|
||||
conn->challenge_header = strdup(header);
|
||||
if(!conn->challenge_header)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
*state = NTLMSTATE_TYPE2; /* We got a type-2 message */
|
||||
}
|
||||
else {
|
||||
if(*state == NTLMSTATE_LAST) {
|
||||
infof(conn->data, "NTLM auth restarted\n");
|
||||
Curl_http_auth_cleanup_ntlm_wb(conn);
|
||||
}
|
||||
else if(*state == NTLMSTATE_TYPE3) {
|
||||
infof(conn->data, "NTLM handshake rejected\n");
|
||||
Curl_http_auth_cleanup_ntlm_wb(conn);
|
||||
*state = NTLMSTATE_NONE;
|
||||
return CURLE_REMOTE_ACCESS_DENIED;
|
||||
}
|
||||
else if(*state >= NTLMSTATE_TYPE1) {
|
||||
infof(conn->data, "NTLM handshake failure (internal error)\n");
|
||||
return CURLE_REMOTE_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
*state = NTLMSTATE_TYPE1; /* We should send away a type-1 */
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is for creating ntlm header output by delegating challenge/response
|
||||
* to Samba's winbind daemon helper ntlm_auth.
|
||||
*/
|
||||
CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
|
||||
bool proxy)
|
||||
{
|
||||
/* point to the address of the pointer that holds the string to send to the
|
||||
server, which is for a plain host or for a HTTP proxy */
|
||||
char **allocuserpwd;
|
||||
/* point to the name and password for this */
|
||||
const char *userp;
|
||||
curlntlm *state;
|
||||
struct auth *authp;
|
||||
|
||||
CURLcode res = CURLE_OK;
|
||||
char *input;
|
||||
|
||||
DEBUGASSERT(conn);
|
||||
DEBUGASSERT(conn->data);
|
||||
|
||||
if(proxy) {
|
||||
allocuserpwd = &conn->allocptr.proxyuserpwd;
|
||||
userp = conn->http_proxy.user;
|
||||
state = &conn->proxy_ntlm_state;
|
||||
authp = &conn->data->state.authproxy;
|
||||
}
|
||||
else {
|
||||
allocuserpwd = &conn->allocptr.userpwd;
|
||||
userp = conn->user;
|
||||
state = &conn->http_ntlm_state;
|
||||
authp = &conn->data->state.authhost;
|
||||
}
|
||||
authp->done = FALSE;
|
||||
|
||||
/* not set means empty */
|
||||
if(!userp)
|
||||
userp = "";
|
||||
|
||||
switch(*state) {
|
||||
case NTLMSTATE_TYPE1:
|
||||
default:
|
||||
/* Use Samba's 'winbind' daemon to support NTLM authentication,
|
||||
* by delegating the NTLM challenge/response protocol to a helper
|
||||
* in ntlm_auth.
|
||||
* http://devel.squid-cache.org/ntlm/squid_helper_protocol.html
|
||||
* https://www.samba.org/samba/docs/man/manpages-3/winbindd.8.html
|
||||
* https://www.samba.org/samba/docs/man/manpages-3/ntlm_auth.1.html
|
||||
* Preprocessor symbol 'NTLM_WB_ENABLED' is defined when this
|
||||
* feature is enabled and 'NTLM_WB_FILE' symbol holds absolute
|
||||
* filename of ntlm_auth helper.
|
||||
* If NTLM authentication using winbind fails, go back to original
|
||||
* request handling process.
|
||||
*/
|
||||
/* Create communication with ntlm_auth */
|
||||
res = ntlm_wb_init(conn, userp);
|
||||
if(res)
|
||||
return res;
|
||||
res = ntlm_wb_response(conn, "YR\n", *state);
|
||||
if(res)
|
||||
return res;
|
||||
|
||||
free(*allocuserpwd);
|
||||
*allocuserpwd = aprintf("%sAuthorization: %s\r\n",
|
||||
proxy ? "Proxy-" : "",
|
||||
conn->response_header);
|
||||
DEBUG_OUT(fprintf(stderr, "**** Header %s\n ", *allocuserpwd));
|
||||
free(conn->response_header);
|
||||
if(!*allocuserpwd)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
conn->response_header = NULL;
|
||||
break;
|
||||
|
||||
case NTLMSTATE_TYPE2:
|
||||
input = aprintf("TT %s\n", conn->challenge_header);
|
||||
if(!input)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
res = ntlm_wb_response(conn, input, *state);
|
||||
free(input);
|
||||
input = NULL;
|
||||
if(res)
|
||||
return res;
|
||||
|
||||
free(*allocuserpwd);
|
||||
*allocuserpwd = aprintf("%sAuthorization: %s\r\n",
|
||||
proxy ? "Proxy-" : "",
|
||||
conn->response_header);
|
||||
DEBUG_OUT(fprintf(stderr, "**** %s\n ", *allocuserpwd));
|
||||
*state = NTLMSTATE_TYPE3; /* we sent a type-3 */
|
||||
authp->done = TRUE;
|
||||
Curl_http_auth_cleanup_ntlm_wb(conn);
|
||||
if(!*allocuserpwd)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
break;
|
||||
|
||||
case NTLMSTATE_TYPE3:
|
||||
/* connection is already authenticated,
|
||||
* don't send a header in future requests */
|
||||
*state = NTLMSTATE_LAST;
|
||||
/* FALLTHROUGH */
|
||||
case NTLMSTATE_LAST:
|
||||
Curl_safefree(*allocuserpwd);
|
||||
authp->done = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
#endif /* !CURL_DISABLE_HTTP && USE_NTLM && NTLM_WB_ENABLED */
|
41
src/dependencies/cmcurl/lib/curl_ntlm_wb.h
Normal file
41
src/dependencies/cmcurl/lib/curl_ntlm_wb.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
#ifndef HEADER_CURL_NTLM_WB_H
|
||||
#define HEADER_CURL_NTLM_WB_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \
|
||||
defined(NTLM_WB_ENABLED)
|
||||
|
||||
/* this is for ntlm header input */
|
||||
CURLcode Curl_input_ntlm_wb(struct connectdata *conn, bool proxy,
|
||||
const char *header);
|
||||
|
||||
/* this is for creating ntlm header output */
|
||||
CURLcode Curl_output_ntlm_wb(struct connectdata *conn, bool proxy);
|
||||
|
||||
void Curl_http_auth_cleanup_ntlm_wb(struct connectdata *conn);
|
||||
|
||||
#endif /* !CURL_DISABLE_HTTP && USE_NTLM && NTLM_WB_ENABLED */
|
||||
|
||||
#endif /* HEADER_CURL_NTLM_WB_H */
|
199
src/dependencies/cmcurl/lib/curl_path.c
Normal file
199
src/dependencies/cmcurl/lib/curl_path.c
Normal file
|
@ -0,0 +1,199 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if defined(USE_SSH)
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include "curl_memory.h"
|
||||
#include "curl_path.h"
|
||||
#include "escape.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
/* figure out the path to work with in this particular request */
|
||||
CURLcode Curl_getworkingpath(struct connectdata *conn,
|
||||
char *homedir, /* when SFTP is used */
|
||||
char **path) /* returns the allocated
|
||||
real path to work with */
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
char *real_path = NULL;
|
||||
char *working_path;
|
||||
size_t working_path_len;
|
||||
CURLcode result =
|
||||
Curl_urldecode(data, data->state.up.path, 0, &working_path,
|
||||
&working_path_len, FALSE);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
/* Check for /~/, indicating relative to the user's home directory */
|
||||
if(conn->handler->protocol & CURLPROTO_SCP) {
|
||||
real_path = malloc(working_path_len + 1);
|
||||
if(real_path == NULL) {
|
||||
free(working_path);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
if((working_path_len > 3) && (!memcmp(working_path, "/~/", 3)))
|
||||
/* It is referenced to the home directory, so strip the leading '/~/' */
|
||||
memcpy(real_path, working_path + 3, 4 + working_path_len-3);
|
||||
else
|
||||
memcpy(real_path, working_path, 1 + working_path_len);
|
||||
}
|
||||
else if(conn->handler->protocol & CURLPROTO_SFTP) {
|
||||
if((working_path_len > 1) && (working_path[1] == '~')) {
|
||||
size_t homelen = strlen(homedir);
|
||||
real_path = malloc(homelen + working_path_len + 1);
|
||||
if(real_path == NULL) {
|
||||
free(working_path);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
/* It is referenced to the home directory, so strip the
|
||||
leading '/' */
|
||||
memcpy(real_path, homedir, homelen);
|
||||
real_path[homelen] = '/';
|
||||
real_path[homelen + 1] = '\0';
|
||||
if(working_path_len > 3) {
|
||||
memcpy(real_path + homelen + 1, working_path + 3,
|
||||
1 + working_path_len -3);
|
||||
}
|
||||
}
|
||||
else {
|
||||
real_path = malloc(working_path_len + 1);
|
||||
if(real_path == NULL) {
|
||||
free(working_path);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
memcpy(real_path, working_path, 1 + working_path_len);
|
||||
}
|
||||
}
|
||||
|
||||
free(working_path);
|
||||
|
||||
/* store the pointer for the caller to receive */
|
||||
*path = real_path;
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/* The get_pathname() function is being borrowed from OpenSSH sftp.c
|
||||
version 4.6p1. */
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
CURLcode Curl_get_pathname(const char **cpp, char **path, char *homedir)
|
||||
{
|
||||
const char *cp = *cpp, *end;
|
||||
char quot;
|
||||
unsigned int i, j;
|
||||
size_t fullPathLength, pathLength;
|
||||
bool relativePath = false;
|
||||
static const char WHITESPACE[] = " \t\r\n";
|
||||
|
||||
if(!*cp) {
|
||||
*cpp = NULL;
|
||||
*path = NULL;
|
||||
return CURLE_QUOTE_ERROR;
|
||||
}
|
||||
/* Ignore leading whitespace */
|
||||
cp += strspn(cp, WHITESPACE);
|
||||
/* Allocate enough space for home directory and filename + separator */
|
||||
fullPathLength = strlen(cp) + strlen(homedir) + 2;
|
||||
*path = malloc(fullPathLength);
|
||||
if(*path == NULL)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
/* Check for quoted filenames */
|
||||
if(*cp == '\"' || *cp == '\'') {
|
||||
quot = *cp++;
|
||||
|
||||
/* Search for terminating quote, unescape some chars */
|
||||
for(i = j = 0; i <= strlen(cp); i++) {
|
||||
if(cp[i] == quot) { /* Found quote */
|
||||
i++;
|
||||
(*path)[j] = '\0';
|
||||
break;
|
||||
}
|
||||
if(cp[i] == '\0') { /* End of string */
|
||||
/*error("Unterminated quote");*/
|
||||
goto fail;
|
||||
}
|
||||
if(cp[i] == '\\') { /* Escaped characters */
|
||||
i++;
|
||||
if(cp[i] != '\'' && cp[i] != '\"' &&
|
||||
cp[i] != '\\') {
|
||||
/*error("Bad escaped character '\\%c'",
|
||||
cp[i]);*/
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
(*path)[j++] = cp[i];
|
||||
}
|
||||
|
||||
if(j == 0) {
|
||||
/*error("Empty quotes");*/
|
||||
goto fail;
|
||||
}
|
||||
*cpp = cp + i + strspn(cp + i, WHITESPACE);
|
||||
}
|
||||
else {
|
||||
/* Read to end of filename - either to white space or terminator */
|
||||
end = strpbrk(cp, WHITESPACE);
|
||||
if(end == NULL)
|
||||
end = strchr(cp, '\0');
|
||||
/* return pointer to second parameter if it exists */
|
||||
*cpp = end + strspn(end, WHITESPACE);
|
||||
pathLength = 0;
|
||||
relativePath = (cp[0] == '/' && cp[1] == '~' && cp[2] == '/');
|
||||
/* Handling for relative path - prepend home directory */
|
||||
if(relativePath) {
|
||||
strcpy(*path, homedir);
|
||||
pathLength = strlen(homedir);
|
||||
(*path)[pathLength++] = '/';
|
||||
(*path)[pathLength] = '\0';
|
||||
cp += 3;
|
||||
}
|
||||
/* Copy path name up until first "white space" */
|
||||
memcpy(&(*path)[pathLength], cp, (int)(end - cp));
|
||||
pathLength += (int)(end - cp);
|
||||
(*path)[pathLength] = '\0';
|
||||
}
|
||||
return CURLE_OK;
|
||||
|
||||
fail:
|
||||
Curl_safefree(*path);
|
||||
return CURLE_QUOTE_ERROR;
|
||||
}
|
||||
|
||||
#endif /* if SSH is used */
|
47
src/dependencies/cmcurl/lib/curl_path.h
Normal file
47
src/dependencies/cmcurl/lib/curl_path.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
#ifndef HEADER_CURL_PATH_H
|
||||
#define HEADER_CURL_PATH_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
#include <curl/curl.h>
|
||||
#include "urldata.h"
|
||||
|
||||
#ifdef WIN32
|
||||
# undef PATH_MAX
|
||||
# define PATH_MAX MAX_PATH
|
||||
# ifndef R_OK
|
||||
# define R_OK 4
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX 1024 /* just an extra precaution since there are systems that
|
||||
have their definition hidden well */
|
||||
#endif
|
||||
|
||||
CURLcode Curl_getworkingpath(struct connectdata *conn,
|
||||
char *homedir,
|
||||
char **path);
|
||||
|
||||
CURLcode Curl_get_pathname(const char **cpp, char **path, char *homedir);
|
||||
#endif /* HEADER_CURL_PATH_H */
|
48
src/dependencies/cmcurl/lib/curl_printf.h
Normal file
48
src/dependencies/cmcurl/lib/curl_printf.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
#ifndef HEADER_CURL_PRINTF_H
|
||||
#define HEADER_CURL_PRINTF_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
* This header should be included by ALL code in libcurl that uses any
|
||||
* *rintf() functions.
|
||||
*/
|
||||
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
# undef printf
|
||||
# undef fprintf
|
||||
# undef msnprintf
|
||||
# undef vprintf
|
||||
# undef vfprintf
|
||||
# undef vsnprintf
|
||||
# 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 /* HEADER_CURL_PRINTF_H */
|
95
src/dependencies/cmcurl/lib/curl_range.c
Normal file
95
src/dependencies/cmcurl/lib/curl_range.c
Normal file
|
@ -0,0 +1,95 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
#include <curl/curl.h>
|
||||
#include "curl_range.h"
|
||||
#include "sendf.h"
|
||||
#include "strtoofft.h"
|
||||
|
||||
/* Only include this function if one or more of FTP, FILE are enabled. */
|
||||
#if !defined(CURL_DISABLE_FTP) || !defined(CURL_DISABLE_FILE)
|
||||
|
||||
/*
|
||||
Check if this is a range download, and if so, set the internal variables
|
||||
properly.
|
||||
*/
|
||||
CURLcode Curl_range(struct connectdata *conn)
|
||||
{
|
||||
curl_off_t from, to;
|
||||
char *ptr;
|
||||
char *ptr2;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
if(data->state.use_range && data->state.range) {
|
||||
CURLofft from_t;
|
||||
CURLofft to_t;
|
||||
from_t = curlx_strtoofft(data->state.range, &ptr, 0, &from);
|
||||
if(from_t == CURL_OFFT_FLOW)
|
||||
return CURLE_RANGE_ERROR;
|
||||
while(*ptr && (ISSPACE(*ptr) || (*ptr == '-')))
|
||||
ptr++;
|
||||
to_t = curlx_strtoofft(ptr, &ptr2, 0, &to);
|
||||
if(to_t == CURL_OFFT_FLOW)
|
||||
return CURLE_RANGE_ERROR;
|
||||
if((to_t == CURL_OFFT_INVAL) && !from_t) {
|
||||
/* X - */
|
||||
data->state.resume_from = from;
|
||||
DEBUGF(infof(data, "RANGE %" CURL_FORMAT_CURL_OFF_T " to end of file\n",
|
||||
from));
|
||||
}
|
||||
else if((from_t == CURL_OFFT_INVAL) && !to_t) {
|
||||
/* -Y */
|
||||
data->req.maxdownload = to;
|
||||
data->state.resume_from = -to;
|
||||
DEBUGF(infof(data, "RANGE the last %" CURL_FORMAT_CURL_OFF_T " bytes\n",
|
||||
to));
|
||||
}
|
||||
else {
|
||||
/* X-Y */
|
||||
curl_off_t totalsize;
|
||||
|
||||
/* Ensure the range is sensible - to should follow from. */
|
||||
if(from > to)
|
||||
return CURLE_RANGE_ERROR;
|
||||
|
||||
totalsize = to - from;
|
||||
if(totalsize == CURL_OFF_T_MAX)
|
||||
return CURLE_RANGE_ERROR;
|
||||
|
||||
data->req.maxdownload = totalsize + 1; /* include last byte */
|
||||
data->state.resume_from = from;
|
||||
DEBUGF(infof(data, "RANGE from %" CURL_FORMAT_CURL_OFF_T
|
||||
" getting %" CURL_FORMAT_CURL_OFF_T " bytes\n",
|
||||
from, data->req.maxdownload));
|
||||
}
|
||||
DEBUGF(infof(data, "range-download from %" CURL_FORMAT_CURL_OFF_T
|
||||
" to %" CURL_FORMAT_CURL_OFF_T ", totally %"
|
||||
CURL_FORMAT_CURL_OFF_T " bytes\n",
|
||||
from, to, data->req.maxdownload));
|
||||
}
|
||||
else
|
||||
data->req.maxdownload = -1;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
#endif
|
30
src/dependencies/cmcurl/lib/curl_range.h
Normal file
30
src/dependencies/cmcurl/lib/curl_range.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
#ifndef HEADER_CURL_RANGE_H
|
||||
#define HEADER_CURL_RANGE_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
#include "urldata.h"
|
||||
|
||||
CURLcode Curl_range(struct connectdata *conn);
|
||||
|
||||
#endif /* HEADER_CURL_RANGE_H */
|
316
src/dependencies/cmcurl/lib/curl_rtmp.c
Normal file
316
src/dependencies/cmcurl/lib/curl_rtmp.c
Normal file
|
@ -0,0 +1,316 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2012 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2010, Howard Chu, <hyc@highlandsun.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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#ifdef USE_LIBRTMP
|
||||
|
||||
#include "curl_rtmp.h"
|
||||
#include "urldata.h"
|
||||
#include "nonblock.h" /* for curlx_nonblock */
|
||||
#include "progress.h" /* for Curl_pgrsSetUploadSize */
|
||||
#include "transfer.h"
|
||||
#include "warnless.h"
|
||||
#include <curl/curl.h>
|
||||
#include <librtmp/rtmp.h>
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
#if defined(WIN32) && !defined(USE_LWIPSOCK)
|
||||
#define setsockopt(a,b,c,d,e) (setsockopt)(a,b,c,(const char *)d,(int)e)
|
||||
#define SET_RCVTIMEO(tv,s) int tv = s*1000
|
||||
#elif defined(LWIP_SO_SNDRCVTIMEO_NONSTANDARD)
|
||||
#define SET_RCVTIMEO(tv,s) int tv = s*1000
|
||||
#else
|
||||
#define SET_RCVTIMEO(tv,s) struct timeval tv = {s,0}
|
||||
#endif
|
||||
|
||||
#define DEF_BUFTIME (2*60*60*1000) /* 2 hours */
|
||||
|
||||
static CURLcode rtmp_setup_connection(struct connectdata *conn);
|
||||
static CURLcode rtmp_do(struct connectdata *conn, bool *done);
|
||||
static CURLcode rtmp_done(struct connectdata *conn, CURLcode, bool premature);
|
||||
static CURLcode rtmp_connect(struct connectdata *conn, bool *done);
|
||||
static CURLcode rtmp_disconnect(struct connectdata *conn, bool dead);
|
||||
|
||||
static Curl_recv rtmp_recv;
|
||||
static Curl_send rtmp_send;
|
||||
|
||||
/*
|
||||
* RTMP protocol handler.h, based on https://rtmpdump.mplayerhq.hu
|
||||
*/
|
||||
|
||||
const struct Curl_handler Curl_handler_rtmp = {
|
||||
"RTMP", /* scheme */
|
||||
rtmp_setup_connection, /* setup_connection */
|
||||
rtmp_do, /* do_it */
|
||||
rtmp_done, /* done */
|
||||
ZERO_NULL, /* do_more */
|
||||
rtmp_connect, /* connect_it */
|
||||
ZERO_NULL, /* connecting */
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
rtmp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
ZERO_NULL, /* connection_check */
|
||||
PORT_RTMP, /* defport */
|
||||
CURLPROTO_RTMP, /* protocol */
|
||||
PROTOPT_NONE /* flags*/
|
||||
};
|
||||
|
||||
const struct Curl_handler Curl_handler_rtmpt = {
|
||||
"RTMPT", /* scheme */
|
||||
rtmp_setup_connection, /* setup_connection */
|
||||
rtmp_do, /* do_it */
|
||||
rtmp_done, /* done */
|
||||
ZERO_NULL, /* do_more */
|
||||
rtmp_connect, /* connect_it */
|
||||
ZERO_NULL, /* connecting */
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
rtmp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
ZERO_NULL, /* connection_check */
|
||||
PORT_RTMPT, /* defport */
|
||||
CURLPROTO_RTMPT, /* protocol */
|
||||
PROTOPT_NONE /* flags*/
|
||||
};
|
||||
|
||||
const struct Curl_handler Curl_handler_rtmpe = {
|
||||
"RTMPE", /* scheme */
|
||||
rtmp_setup_connection, /* setup_connection */
|
||||
rtmp_do, /* do_it */
|
||||
rtmp_done, /* done */
|
||||
ZERO_NULL, /* do_more */
|
||||
rtmp_connect, /* connect_it */
|
||||
ZERO_NULL, /* connecting */
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
rtmp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
ZERO_NULL, /* connection_check */
|
||||
PORT_RTMP, /* defport */
|
||||
CURLPROTO_RTMPE, /* protocol */
|
||||
PROTOPT_NONE /* flags*/
|
||||
};
|
||||
|
||||
const struct Curl_handler Curl_handler_rtmpte = {
|
||||
"RTMPTE", /* scheme */
|
||||
rtmp_setup_connection, /* setup_connection */
|
||||
rtmp_do, /* do_it */
|
||||
rtmp_done, /* done */
|
||||
ZERO_NULL, /* do_more */
|
||||
rtmp_connect, /* connect_it */
|
||||
ZERO_NULL, /* connecting */
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
rtmp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
ZERO_NULL, /* connection_check */
|
||||
PORT_RTMPT, /* defport */
|
||||
CURLPROTO_RTMPTE, /* protocol */
|
||||
PROTOPT_NONE /* flags*/
|
||||
};
|
||||
|
||||
const struct Curl_handler Curl_handler_rtmps = {
|
||||
"RTMPS", /* scheme */
|
||||
rtmp_setup_connection, /* setup_connection */
|
||||
rtmp_do, /* do_it */
|
||||
rtmp_done, /* done */
|
||||
ZERO_NULL, /* do_more */
|
||||
rtmp_connect, /* connect_it */
|
||||
ZERO_NULL, /* connecting */
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
rtmp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
ZERO_NULL, /* connection_check */
|
||||
PORT_RTMPS, /* defport */
|
||||
CURLPROTO_RTMPS, /* protocol */
|
||||
PROTOPT_NONE /* flags*/
|
||||
};
|
||||
|
||||
const struct Curl_handler Curl_handler_rtmpts = {
|
||||
"RTMPTS", /* scheme */
|
||||
rtmp_setup_connection, /* setup_connection */
|
||||
rtmp_do, /* do_it */
|
||||
rtmp_done, /* done */
|
||||
ZERO_NULL, /* do_more */
|
||||
rtmp_connect, /* connect_it */
|
||||
ZERO_NULL, /* connecting */
|
||||
ZERO_NULL, /* doing */
|
||||
ZERO_NULL, /* proto_getsock */
|
||||
ZERO_NULL, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ZERO_NULL, /* perform_getsock */
|
||||
rtmp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
ZERO_NULL, /* connection_check */
|
||||
PORT_RTMPS, /* defport */
|
||||
CURLPROTO_RTMPTS, /* protocol */
|
||||
PROTOPT_NONE /* flags*/
|
||||
};
|
||||
|
||||
static CURLcode rtmp_setup_connection(struct connectdata *conn)
|
||||
{
|
||||
RTMP *r = RTMP_Alloc();
|
||||
if(!r)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
RTMP_Init(r);
|
||||
RTMP_SetBufferMS(r, DEF_BUFTIME);
|
||||
if(!RTMP_SetupURL(r, conn->data->change.url)) {
|
||||
RTMP_Free(r);
|
||||
return CURLE_URL_MALFORMAT;
|
||||
}
|
||||
conn->proto.generic = r;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode rtmp_connect(struct connectdata *conn, bool *done)
|
||||
{
|
||||
RTMP *r = conn->proto.generic;
|
||||
SET_RCVTIMEO(tv, 10);
|
||||
|
||||
r->m_sb.sb_socket = (int)conn->sock[FIRSTSOCKET];
|
||||
|
||||
/* We have to know if it's a write before we send the
|
||||
* connect request packet
|
||||
*/
|
||||
if(conn->data->set.upload)
|
||||
r->Link.protocol |= RTMP_FEATURE_WRITE;
|
||||
|
||||
/* For plain streams, use the buffer toggle trick to keep data flowing */
|
||||
if(!(r->Link.lFlags & RTMP_LF_LIVE) &&
|
||||
!(r->Link.protocol & RTMP_FEATURE_HTTP))
|
||||
r->Link.lFlags |= RTMP_LF_BUFX;
|
||||
|
||||
(void)curlx_nonblock(r->m_sb.sb_socket, FALSE);
|
||||
setsockopt(r->m_sb.sb_socket, SOL_SOCKET, SO_RCVTIMEO,
|
||||
(char *)&tv, sizeof(tv));
|
||||
|
||||
if(!RTMP_Connect1(r, NULL))
|
||||
return CURLE_FAILED_INIT;
|
||||
|
||||
/* Clients must send a periodic BytesReceived report to the server */
|
||||
r->m_bSendCounter = true;
|
||||
|
||||
*done = TRUE;
|
||||
conn->recv[FIRSTSOCKET] = rtmp_recv;
|
||||
conn->send[FIRSTSOCKET] = rtmp_send;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode rtmp_do(struct connectdata *conn, bool *done)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
RTMP *r = conn->proto.generic;
|
||||
|
||||
if(!RTMP_ConnectStream(r, 0))
|
||||
return CURLE_FAILED_INIT;
|
||||
|
||||
if(conn->data->set.upload) {
|
||||
Curl_pgrsSetUploadSize(data, data->state.infilesize);
|
||||
Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET);
|
||||
}
|
||||
else
|
||||
Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1);
|
||||
*done = TRUE;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode rtmp_done(struct connectdata *conn, CURLcode status,
|
||||
bool premature)
|
||||
{
|
||||
(void)conn; /* unused */
|
||||
(void)status; /* unused */
|
||||
(void)premature; /* unused */
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode rtmp_disconnect(struct connectdata *conn,
|
||||
bool dead_connection)
|
||||
{
|
||||
RTMP *r = conn->proto.generic;
|
||||
(void)dead_connection;
|
||||
if(r) {
|
||||
conn->proto.generic = NULL;
|
||||
RTMP_Close(r);
|
||||
RTMP_Free(r);
|
||||
}
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static ssize_t rtmp_recv(struct connectdata *conn, int sockindex, char *buf,
|
||||
size_t len, CURLcode *err)
|
||||
{
|
||||
RTMP *r = conn->proto.generic;
|
||||
ssize_t nread;
|
||||
|
||||
(void)sockindex; /* unused */
|
||||
|
||||
nread = RTMP_Read(r, buf, curlx_uztosi(len));
|
||||
if(nread < 0) {
|
||||
if(r->m_read.status == RTMP_READ_COMPLETE ||
|
||||
r->m_read.status == RTMP_READ_EOF) {
|
||||
conn->data->req.size = conn->data->req.bytecount;
|
||||
nread = 0;
|
||||
}
|
||||
else
|
||||
*err = CURLE_RECV_ERROR;
|
||||
}
|
||||
return nread;
|
||||
}
|
||||
|
||||
static ssize_t rtmp_send(struct connectdata *conn, int sockindex,
|
||||
const void *buf, size_t len, CURLcode *err)
|
||||
{
|
||||
RTMP *r = conn->proto.generic;
|
||||
ssize_t num;
|
||||
|
||||
(void)sockindex; /* unused */
|
||||
|
||||
num = RTMP_Write(r, (char *)buf, curlx_uztosi(len));
|
||||
if(num < 0)
|
||||
*err = CURLE_SEND_ERROR;
|
||||
|
||||
return num;
|
||||
}
|
||||
#endif /* USE_LIBRTMP */
|
33
src/dependencies/cmcurl/lib/curl_rtmp.h
Normal file
33
src/dependencies/cmcurl/lib/curl_rtmp.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
#ifndef HEADER_CURL_RTMP_H
|
||||
#define HEADER_CURL_RTMP_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2010, Howard Chu, <hyc@highlandsun.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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
#ifdef USE_LIBRTMP
|
||||
extern const struct Curl_handler Curl_handler_rtmp;
|
||||
extern const struct Curl_handler Curl_handler_rtmpt;
|
||||
extern const struct Curl_handler Curl_handler_rtmpe;
|
||||
extern const struct Curl_handler Curl_handler_rtmpte;
|
||||
extern const struct Curl_handler Curl_handler_rtmps;
|
||||
extern const struct Curl_handler Curl_handler_rtmpts;
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_RTMP_H */
|
629
src/dependencies/cmcurl/lib/curl_sasl.c
Normal file
629
src/dependencies/cmcurl/lib/curl_sasl.c
Normal file
|
@ -0,0 +1,629 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2012 - 2019, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
* RFC2195 CRAM-MD5 authentication
|
||||
* RFC2617 Basic and Digest Access Authentication
|
||||
* RFC2831 DIGEST-MD5 authentication
|
||||
* RFC4422 Simple Authentication and Security Layer (SASL)
|
||||
* RFC4616 PLAIN authentication
|
||||
* RFC6749 OAuth 2.0 Authorization Framework
|
||||
* RFC7628 A Set of SASL Mechanisms for OAuth
|
||||
* Draft LOGIN SASL Mechanism <draft-murchison-sasl-login-00.txt>
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if !defined(CURL_DISABLE_IMAP) || !defined(CURL_DISABLE_SMTP) || \
|
||||
!defined(CURL_DISABLE_POP3)
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include "urldata.h"
|
||||
|
||||
#include "curl_base64.h"
|
||||
#include "curl_md5.h"
|
||||
#include "vauth/vauth.h"
|
||||
#include "vtls/vtls.h"
|
||||
#include "curl_hmac.h"
|
||||
#include "curl_sasl.h"
|
||||
#include "warnless.h"
|
||||
#include "strtok.h"
|
||||
#include "sendf.h"
|
||||
#include "non-ascii.h" /* included for Curl_convert_... prototypes */
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
/* Supported mechanisms */
|
||||
static const struct {
|
||||
const char *name; /* Name */
|
||||
size_t len; /* Name length */
|
||||
unsigned int bit; /* Flag bit */
|
||||
} mechtable[] = {
|
||||
{ "LOGIN", 5, SASL_MECH_LOGIN },
|
||||
{ "PLAIN", 5, SASL_MECH_PLAIN },
|
||||
{ "CRAM-MD5", 8, SASL_MECH_CRAM_MD5 },
|
||||
{ "DIGEST-MD5", 10, SASL_MECH_DIGEST_MD5 },
|
||||
{ "GSSAPI", 6, SASL_MECH_GSSAPI },
|
||||
{ "EXTERNAL", 8, SASL_MECH_EXTERNAL },
|
||||
{ "NTLM", 4, SASL_MECH_NTLM },
|
||||
{ "XOAUTH2", 7, SASL_MECH_XOAUTH2 },
|
||||
{ "OAUTHBEARER", 11, SASL_MECH_OAUTHBEARER },
|
||||
{ ZERO_NULL, 0, 0 }
|
||||
};
|
||||
|
||||
/*
|
||||
* Curl_sasl_cleanup()
|
||||
*
|
||||
* This is used to cleanup any libraries or curl modules used by the sasl
|
||||
* functions.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* conn [in] - The connection data.
|
||||
* authused [in] - The authentication mechanism used.
|
||||
*/
|
||||
void Curl_sasl_cleanup(struct connectdata *conn, unsigned int authused)
|
||||
{
|
||||
#if defined(USE_KERBEROS5)
|
||||
/* Cleanup the gssapi structure */
|
||||
if(authused == SASL_MECH_GSSAPI) {
|
||||
Curl_auth_cleanup_gssapi(&conn->krb5);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(USE_NTLM)
|
||||
/* Cleanup the NTLM structure */
|
||||
if(authused == SASL_MECH_NTLM) {
|
||||
Curl_auth_cleanup_ntlm(&conn->ntlm);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(USE_KERBEROS5) && !defined(USE_NTLM)
|
||||
/* Reserved for future use */
|
||||
(void)conn;
|
||||
(void)authused;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_sasl_decode_mech()
|
||||
*
|
||||
* Convert a SASL mechanism name into a token.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* ptr [in] - The mechanism string.
|
||||
* maxlen [in] - Maximum mechanism string length.
|
||||
* len [out] - If not NULL, effective name length.
|
||||
*
|
||||
* Returns the SASL mechanism token or 0 if no match.
|
||||
*/
|
||||
unsigned int Curl_sasl_decode_mech(const char *ptr, size_t maxlen, size_t *len)
|
||||
{
|
||||
unsigned int i;
|
||||
char c;
|
||||
|
||||
for(i = 0; mechtable[i].name; i++) {
|
||||
if(maxlen >= mechtable[i].len &&
|
||||
!memcmp(ptr, mechtable[i].name, mechtable[i].len)) {
|
||||
if(len)
|
||||
*len = mechtable[i].len;
|
||||
|
||||
if(maxlen == mechtable[i].len)
|
||||
return mechtable[i].bit;
|
||||
|
||||
c = ptr[mechtable[i].len];
|
||||
if(!ISUPPER(c) && !ISDIGIT(c) && c != '-' && c != '_')
|
||||
return mechtable[i].bit;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_sasl_parse_url_auth_option()
|
||||
*
|
||||
* Parse the URL login options.
|
||||
*/
|
||||
CURLcode Curl_sasl_parse_url_auth_option(struct SASL *sasl,
|
||||
const char *value, size_t len)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
size_t mechlen;
|
||||
|
||||
if(!len)
|
||||
return CURLE_URL_MALFORMAT;
|
||||
|
||||
if(sasl->resetprefs) {
|
||||
sasl->resetprefs = FALSE;
|
||||
sasl->prefmech = SASL_AUTH_NONE;
|
||||
}
|
||||
|
||||
if(!strncmp(value, "*", len))
|
||||
sasl->prefmech = SASL_AUTH_DEFAULT;
|
||||
else {
|
||||
unsigned int mechbit = Curl_sasl_decode_mech(value, len, &mechlen);
|
||||
if(mechbit && mechlen == len)
|
||||
sasl->prefmech |= mechbit;
|
||||
else
|
||||
result = CURLE_URL_MALFORMAT;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_sasl_init()
|
||||
*
|
||||
* Initializes the SASL structure.
|
||||
*/
|
||||
void Curl_sasl_init(struct SASL *sasl, const struct SASLproto *params)
|
||||
{
|
||||
sasl->params = params; /* Set protocol dependent parameters */
|
||||
sasl->state = SASL_STOP; /* Not yet running */
|
||||
sasl->authmechs = SASL_AUTH_NONE; /* No known authentication mechanism yet */
|
||||
sasl->prefmech = SASL_AUTH_DEFAULT; /* Prefer all mechanisms */
|
||||
sasl->authused = SASL_AUTH_NONE; /* No the authentication mechanism used */
|
||||
sasl->resetprefs = TRUE; /* Reset prefmech upon AUTH parsing. */
|
||||
sasl->mutual_auth = FALSE; /* No mutual authentication (GSSAPI only) */
|
||||
sasl->force_ir = FALSE; /* Respect external option */
|
||||
}
|
||||
|
||||
/*
|
||||
* state()
|
||||
*
|
||||
* This is the ONLY way to change SASL state!
|
||||
*/
|
||||
static void state(struct SASL *sasl, struct connectdata *conn,
|
||||
saslstate newstate)
|
||||
{
|
||||
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||
/* for debug purposes */
|
||||
static const char * const names[]={
|
||||
"STOP",
|
||||
"PLAIN",
|
||||
"LOGIN",
|
||||
"LOGIN_PASSWD",
|
||||
"EXTERNAL",
|
||||
"CRAMMD5",
|
||||
"DIGESTMD5",
|
||||
"DIGESTMD5_RESP",
|
||||
"NTLM",
|
||||
"NTLM_TYPE2MSG",
|
||||
"GSSAPI",
|
||||
"GSSAPI_TOKEN",
|
||||
"GSSAPI_NO_DATA",
|
||||
"OAUTH2",
|
||||
"OAUTH2_RESP",
|
||||
"CANCEL",
|
||||
"FINAL",
|
||||
/* LAST */
|
||||
};
|
||||
|
||||
if(sasl->state != newstate)
|
||||
infof(conn->data, "SASL %p state change from %s to %s\n",
|
||||
(void *)sasl, names[sasl->state], names[newstate]);
|
||||
#else
|
||||
(void) conn;
|
||||
#endif
|
||||
|
||||
sasl->state = newstate;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_sasl_can_authenticate()
|
||||
*
|
||||
* Check if we have enough auth data and capabilities to authenticate.
|
||||
*/
|
||||
bool Curl_sasl_can_authenticate(struct SASL *sasl, struct connectdata *conn)
|
||||
{
|
||||
/* Have credentials been provided? */
|
||||
if(conn->bits.user_passwd)
|
||||
return TRUE;
|
||||
|
||||
/* EXTERNAL can authenticate without a user name and/or password */
|
||||
if(sasl->authmechs & sasl->prefmech & SASL_MECH_EXTERNAL)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_sasl_start()
|
||||
*
|
||||
* Calculate the required login details for SASL authentication.
|
||||
*/
|
||||
CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn,
|
||||
bool force_ir, saslprogress *progress)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct Curl_easy *data = conn->data;
|
||||
unsigned int enabledmechs;
|
||||
const char *mech = NULL;
|
||||
char *resp = NULL;
|
||||
size_t len = 0;
|
||||
saslstate state1 = SASL_STOP;
|
||||
saslstate state2 = SASL_FINAL;
|
||||
const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
|
||||
conn->host.name;
|
||||
const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
|
||||
#if defined(USE_KERBEROS5) || defined(USE_NTLM)
|
||||
const char *service = data->set.str[STRING_SERVICE_NAME] ?
|
||||
data->set.str[STRING_SERVICE_NAME] :
|
||||
sasl->params->service;
|
||||
#endif
|
||||
|
||||
sasl->force_ir = force_ir; /* Latch for future use */
|
||||
sasl->authused = 0; /* No mechanism used yet */
|
||||
enabledmechs = sasl->authmechs & sasl->prefmech;
|
||||
*progress = SASL_IDLE;
|
||||
|
||||
/* Calculate the supported authentication mechanism, by decreasing order of
|
||||
security, as well as the initial response where appropriate */
|
||||
if((enabledmechs & SASL_MECH_EXTERNAL) && !conn->passwd[0]) {
|
||||
mech = SASL_MECH_STRING_EXTERNAL;
|
||||
state1 = SASL_EXTERNAL;
|
||||
sasl->authused = SASL_MECH_EXTERNAL;
|
||||
|
||||
if(force_ir || data->set.sasl_ir)
|
||||
result = Curl_auth_create_external_message(data, conn->user, &resp,
|
||||
&len);
|
||||
}
|
||||
else if(conn->bits.user_passwd) {
|
||||
#if defined(USE_KERBEROS5)
|
||||
if((enabledmechs & SASL_MECH_GSSAPI) && Curl_auth_is_gssapi_supported() &&
|
||||
Curl_auth_user_contains_domain(conn->user)) {
|
||||
sasl->mutual_auth = FALSE;
|
||||
mech = SASL_MECH_STRING_GSSAPI;
|
||||
state1 = SASL_GSSAPI;
|
||||
state2 = SASL_GSSAPI_TOKEN;
|
||||
sasl->authused = SASL_MECH_GSSAPI;
|
||||
|
||||
if(force_ir || data->set.sasl_ir)
|
||||
result = Curl_auth_create_gssapi_user_message(data, conn->user,
|
||||
conn->passwd,
|
||||
service,
|
||||
data->conn->host.name,
|
||||
sasl->mutual_auth,
|
||||
NULL, &conn->krb5,
|
||||
&resp, &len);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifndef CURL_DISABLE_CRYPTO_AUTH
|
||||
if((enabledmechs & SASL_MECH_DIGEST_MD5) &&
|
||||
Curl_auth_is_digest_supported()) {
|
||||
mech = SASL_MECH_STRING_DIGEST_MD5;
|
||||
state1 = SASL_DIGESTMD5;
|
||||
sasl->authused = SASL_MECH_DIGEST_MD5;
|
||||
}
|
||||
else if(enabledmechs & SASL_MECH_CRAM_MD5) {
|
||||
mech = SASL_MECH_STRING_CRAM_MD5;
|
||||
state1 = SASL_CRAMMD5;
|
||||
sasl->authused = SASL_MECH_CRAM_MD5;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifdef USE_NTLM
|
||||
if((enabledmechs & SASL_MECH_NTLM) && Curl_auth_is_ntlm_supported()) {
|
||||
mech = SASL_MECH_STRING_NTLM;
|
||||
state1 = SASL_NTLM;
|
||||
state2 = SASL_NTLM_TYPE2MSG;
|
||||
sasl->authused = SASL_MECH_NTLM;
|
||||
|
||||
if(force_ir || data->set.sasl_ir)
|
||||
result = Curl_auth_create_ntlm_type1_message(data,
|
||||
conn->user, conn->passwd,
|
||||
service,
|
||||
hostname,
|
||||
&conn->ntlm, &resp,
|
||||
&len);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if((enabledmechs & SASL_MECH_OAUTHBEARER) && conn->oauth_bearer) {
|
||||
mech = SASL_MECH_STRING_OAUTHBEARER;
|
||||
state1 = SASL_OAUTH2;
|
||||
state2 = SASL_OAUTH2_RESP;
|
||||
sasl->authused = SASL_MECH_OAUTHBEARER;
|
||||
|
||||
if(force_ir || data->set.sasl_ir)
|
||||
result = Curl_auth_create_oauth_bearer_message(data, conn->user,
|
||||
hostname,
|
||||
port,
|
||||
conn->oauth_bearer,
|
||||
&resp, &len);
|
||||
}
|
||||
else if((enabledmechs & SASL_MECH_XOAUTH2) && conn->oauth_bearer) {
|
||||
mech = SASL_MECH_STRING_XOAUTH2;
|
||||
state1 = SASL_OAUTH2;
|
||||
sasl->authused = SASL_MECH_XOAUTH2;
|
||||
|
||||
if(force_ir || data->set.sasl_ir)
|
||||
result = Curl_auth_create_xoauth_bearer_message(data, conn->user,
|
||||
conn->oauth_bearer,
|
||||
&resp, &len);
|
||||
}
|
||||
else if(enabledmechs & SASL_MECH_PLAIN) {
|
||||
mech = SASL_MECH_STRING_PLAIN;
|
||||
state1 = SASL_PLAIN;
|
||||
sasl->authused = SASL_MECH_PLAIN;
|
||||
|
||||
if(force_ir || data->set.sasl_ir)
|
||||
result = Curl_auth_create_plain_message(data, NULL, conn->user,
|
||||
conn->passwd, &resp, &len);
|
||||
}
|
||||
else if(enabledmechs & SASL_MECH_LOGIN) {
|
||||
mech = SASL_MECH_STRING_LOGIN;
|
||||
state1 = SASL_LOGIN;
|
||||
state2 = SASL_LOGIN_PASSWD;
|
||||
sasl->authused = SASL_MECH_LOGIN;
|
||||
|
||||
if(force_ir || data->set.sasl_ir)
|
||||
result = Curl_auth_create_login_message(data, conn->user, &resp, &len);
|
||||
}
|
||||
}
|
||||
|
||||
if(!result && mech) {
|
||||
if(resp && sasl->params->maxirlen &&
|
||||
strlen(mech) + len > sasl->params->maxirlen) {
|
||||
free(resp);
|
||||
resp = NULL;
|
||||
}
|
||||
|
||||
result = sasl->params->sendauth(conn, mech, resp);
|
||||
if(!result) {
|
||||
*progress = SASL_INPROGRESS;
|
||||
state(sasl, conn, resp ? state2 : state1);
|
||||
}
|
||||
}
|
||||
|
||||
free(resp);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_sasl_continue()
|
||||
*
|
||||
* Continue the authentication.
|
||||
*/
|
||||
CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn,
|
||||
int code, saslprogress *progress)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct Curl_easy *data = conn->data;
|
||||
saslstate newstate = SASL_FINAL;
|
||||
char *resp = NULL;
|
||||
const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
|
||||
conn->host.name;
|
||||
const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
|
||||
#if !defined(CURL_DISABLE_CRYPTO_AUTH)
|
||||
char *chlg = NULL;
|
||||
size_t chlglen = 0;
|
||||
#endif
|
||||
#if !defined(CURL_DISABLE_CRYPTO_AUTH) || defined(USE_KERBEROS5) || \
|
||||
defined(USE_NTLM)
|
||||
const char *service = data->set.str[STRING_SERVICE_NAME] ?
|
||||
data->set.str[STRING_SERVICE_NAME] :
|
||||
sasl->params->service;
|
||||
char *serverdata;
|
||||
#endif
|
||||
size_t len = 0;
|
||||
|
||||
*progress = SASL_INPROGRESS;
|
||||
|
||||
if(sasl->state == SASL_FINAL) {
|
||||
if(code != sasl->params->finalcode)
|
||||
result = CURLE_LOGIN_DENIED;
|
||||
*progress = SASL_DONE;
|
||||
state(sasl, conn, SASL_STOP);
|
||||
return result;
|
||||
}
|
||||
|
||||
if(sasl->state != SASL_CANCEL && sasl->state != SASL_OAUTH2_RESP &&
|
||||
code != sasl->params->contcode) {
|
||||
*progress = SASL_DONE;
|
||||
state(sasl, conn, SASL_STOP);
|
||||
return CURLE_LOGIN_DENIED;
|
||||
}
|
||||
|
||||
switch(sasl->state) {
|
||||
case SASL_STOP:
|
||||
*progress = SASL_DONE;
|
||||
return result;
|
||||
case SASL_PLAIN:
|
||||
result = Curl_auth_create_plain_message(data, NULL, conn->user,
|
||||
conn->passwd, &resp, &len);
|
||||
break;
|
||||
case SASL_LOGIN:
|
||||
result = Curl_auth_create_login_message(data, conn->user, &resp, &len);
|
||||
newstate = SASL_LOGIN_PASSWD;
|
||||
break;
|
||||
case SASL_LOGIN_PASSWD:
|
||||
result = Curl_auth_create_login_message(data, conn->passwd, &resp, &len);
|
||||
break;
|
||||
case SASL_EXTERNAL:
|
||||
result = Curl_auth_create_external_message(data, conn->user, &resp, &len);
|
||||
break;
|
||||
|
||||
#ifndef CURL_DISABLE_CRYPTO_AUTH
|
||||
case SASL_CRAMMD5:
|
||||
sasl->params->getmessage(data->state.buffer, &serverdata);
|
||||
result = Curl_auth_decode_cram_md5_message(serverdata, &chlg, &chlglen);
|
||||
if(!result)
|
||||
result = Curl_auth_create_cram_md5_message(data, chlg, conn->user,
|
||||
conn->passwd, &resp, &len);
|
||||
free(chlg);
|
||||
break;
|
||||
case SASL_DIGESTMD5:
|
||||
sasl->params->getmessage(data->state.buffer, &serverdata);
|
||||
result = Curl_auth_create_digest_md5_message(data, serverdata,
|
||||
conn->user, conn->passwd,
|
||||
service,
|
||||
&resp, &len);
|
||||
newstate = SASL_DIGESTMD5_RESP;
|
||||
break;
|
||||
case SASL_DIGESTMD5_RESP:
|
||||
resp = strdup("");
|
||||
if(!resp)
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef USE_NTLM
|
||||
case SASL_NTLM:
|
||||
/* Create the type-1 message */
|
||||
result = Curl_auth_create_ntlm_type1_message(data,
|
||||
conn->user, conn->passwd,
|
||||
service, hostname,
|
||||
&conn->ntlm, &resp, &len);
|
||||
newstate = SASL_NTLM_TYPE2MSG;
|
||||
break;
|
||||
case SASL_NTLM_TYPE2MSG:
|
||||
/* Decode the type-2 message */
|
||||
sasl->params->getmessage(data->state.buffer, &serverdata);
|
||||
result = Curl_auth_decode_ntlm_type2_message(data, serverdata,
|
||||
&conn->ntlm);
|
||||
if(!result)
|
||||
result = Curl_auth_create_ntlm_type3_message(data, conn->user,
|
||||
conn->passwd, &conn->ntlm,
|
||||
&resp, &len);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(USE_KERBEROS5)
|
||||
case SASL_GSSAPI:
|
||||
result = Curl_auth_create_gssapi_user_message(data, conn->user,
|
||||
conn->passwd,
|
||||
service,
|
||||
data->conn->host.name,
|
||||
sasl->mutual_auth, NULL,
|
||||
&conn->krb5,
|
||||
&resp, &len);
|
||||
newstate = SASL_GSSAPI_TOKEN;
|
||||
break;
|
||||
case SASL_GSSAPI_TOKEN:
|
||||
sasl->params->getmessage(data->state.buffer, &serverdata);
|
||||
if(sasl->mutual_auth) {
|
||||
/* Decode the user token challenge and create the optional response
|
||||
message */
|
||||
result = Curl_auth_create_gssapi_user_message(data, NULL, NULL,
|
||||
NULL, NULL,
|
||||
sasl->mutual_auth,
|
||||
serverdata, &conn->krb5,
|
||||
&resp, &len);
|
||||
newstate = SASL_GSSAPI_NO_DATA;
|
||||
}
|
||||
else
|
||||
/* Decode the security challenge and create the response message */
|
||||
result = Curl_auth_create_gssapi_security_message(data, serverdata,
|
||||
&conn->krb5,
|
||||
&resp, &len);
|
||||
break;
|
||||
case SASL_GSSAPI_NO_DATA:
|
||||
sasl->params->getmessage(data->state.buffer, &serverdata);
|
||||
/* Decode the security challenge and create the response message */
|
||||
result = Curl_auth_create_gssapi_security_message(data, serverdata,
|
||||
&conn->krb5,
|
||||
&resp, &len);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case SASL_OAUTH2:
|
||||
/* Create the authorisation message */
|
||||
if(sasl->authused == SASL_MECH_OAUTHBEARER) {
|
||||
result = Curl_auth_create_oauth_bearer_message(data, conn->user,
|
||||
hostname,
|
||||
port,
|
||||
conn->oauth_bearer,
|
||||
&resp, &len);
|
||||
|
||||
/* Failures maybe sent by the server as continuations for OAUTHBEARER */
|
||||
newstate = SASL_OAUTH2_RESP;
|
||||
}
|
||||
else
|
||||
result = Curl_auth_create_xoauth_bearer_message(data, conn->user,
|
||||
conn->oauth_bearer,
|
||||
&resp, &len);
|
||||
break;
|
||||
|
||||
case SASL_OAUTH2_RESP:
|
||||
/* The continuation is optional so check the response code */
|
||||
if(code == sasl->params->finalcode) {
|
||||
/* Final response was received so we are done */
|
||||
*progress = SASL_DONE;
|
||||
state(sasl, conn, SASL_STOP);
|
||||
return result;
|
||||
}
|
||||
else if(code == sasl->params->contcode) {
|
||||
/* Acknowledge the continuation by sending a 0x01 response base64
|
||||
encoded */
|
||||
resp = strdup("AQ==");
|
||||
if(!resp)
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
*progress = SASL_DONE;
|
||||
state(sasl, conn, SASL_STOP);
|
||||
return CURLE_LOGIN_DENIED;
|
||||
}
|
||||
|
||||
case SASL_CANCEL:
|
||||
/* Remove the offending mechanism from the supported list */
|
||||
sasl->authmechs ^= sasl->authused;
|
||||
|
||||
/* Start an alternative SASL authentication */
|
||||
result = Curl_sasl_start(sasl, conn, sasl->force_ir, progress);
|
||||
newstate = sasl->state; /* Use state from Curl_sasl_start() */
|
||||
break;
|
||||
default:
|
||||
failf(data, "Unsupported SASL authentication mechanism");
|
||||
result = CURLE_UNSUPPORTED_PROTOCOL; /* Should not happen */
|
||||
break;
|
||||
}
|
||||
|
||||
switch(result) {
|
||||
case CURLE_BAD_CONTENT_ENCODING:
|
||||
/* Cancel dialog */
|
||||
result = sasl->params->sendcont(conn, "*");
|
||||
newstate = SASL_CANCEL;
|
||||
break;
|
||||
case CURLE_OK:
|
||||
if(resp)
|
||||
result = sasl->params->sendcont(conn, resp);
|
||||
break;
|
||||
default:
|
||||
newstate = SASL_STOP; /* Stop on error */
|
||||
*progress = SASL_DONE;
|
||||
break;
|
||||
}
|
||||
|
||||
free(resp);
|
||||
|
||||
state(sasl, conn, newstate);
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif /* protocols are enabled that use SASL */
|
143
src/dependencies/cmcurl/lib/curl_sasl.h
Normal file
143
src/dependencies/cmcurl/lib/curl_sasl.h
Normal file
|
@ -0,0 +1,143 @@
|
|||
#ifndef HEADER_CURL_SASL_H
|
||||
#define HEADER_CURL_SASL_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2012 - 2016, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
struct Curl_easy;
|
||||
struct connectdata;
|
||||
|
||||
/* Authentication mechanism flags */
|
||||
#define SASL_MECH_LOGIN (1 << 0)
|
||||
#define SASL_MECH_PLAIN (1 << 1)
|
||||
#define SASL_MECH_CRAM_MD5 (1 << 2)
|
||||
#define SASL_MECH_DIGEST_MD5 (1 << 3)
|
||||
#define SASL_MECH_GSSAPI (1 << 4)
|
||||
#define SASL_MECH_EXTERNAL (1 << 5)
|
||||
#define SASL_MECH_NTLM (1 << 6)
|
||||
#define SASL_MECH_XOAUTH2 (1 << 7)
|
||||
#define SASL_MECH_OAUTHBEARER (1 << 8)
|
||||
|
||||
/* Authentication mechanism values */
|
||||
#define SASL_AUTH_NONE 0
|
||||
#define SASL_AUTH_ANY ~0U
|
||||
#define SASL_AUTH_DEFAULT (SASL_AUTH_ANY & ~SASL_MECH_EXTERNAL)
|
||||
|
||||
/* Authentication mechanism strings */
|
||||
#define SASL_MECH_STRING_LOGIN "LOGIN"
|
||||
#define SASL_MECH_STRING_PLAIN "PLAIN"
|
||||
#define SASL_MECH_STRING_CRAM_MD5 "CRAM-MD5"
|
||||
#define SASL_MECH_STRING_DIGEST_MD5 "DIGEST-MD5"
|
||||
#define SASL_MECH_STRING_GSSAPI "GSSAPI"
|
||||
#define SASL_MECH_STRING_EXTERNAL "EXTERNAL"
|
||||
#define SASL_MECH_STRING_NTLM "NTLM"
|
||||
#define SASL_MECH_STRING_XOAUTH2 "XOAUTH2"
|
||||
#define SASL_MECH_STRING_OAUTHBEARER "OAUTHBEARER"
|
||||
|
||||
/* SASL machine states */
|
||||
typedef enum {
|
||||
SASL_STOP,
|
||||
SASL_PLAIN,
|
||||
SASL_LOGIN,
|
||||
SASL_LOGIN_PASSWD,
|
||||
SASL_EXTERNAL,
|
||||
SASL_CRAMMD5,
|
||||
SASL_DIGESTMD5,
|
||||
SASL_DIGESTMD5_RESP,
|
||||
SASL_NTLM,
|
||||
SASL_NTLM_TYPE2MSG,
|
||||
SASL_GSSAPI,
|
||||
SASL_GSSAPI_TOKEN,
|
||||
SASL_GSSAPI_NO_DATA,
|
||||
SASL_OAUTH2,
|
||||
SASL_OAUTH2_RESP,
|
||||
SASL_CANCEL,
|
||||
SASL_FINAL
|
||||
} saslstate;
|
||||
|
||||
/* Progress indicator */
|
||||
typedef enum {
|
||||
SASL_IDLE,
|
||||
SASL_INPROGRESS,
|
||||
SASL_DONE
|
||||
} saslprogress;
|
||||
|
||||
/* Protocol dependent SASL parameters */
|
||||
struct SASLproto {
|
||||
const char *service; /* The service name */
|
||||
int contcode; /* Code to receive when continuation is expected */
|
||||
int finalcode; /* Code to receive upon authentication success */
|
||||
size_t maxirlen; /* Maximum initial response length */
|
||||
CURLcode (*sendauth)(struct connectdata *conn,
|
||||
const char *mech, const char *ir);
|
||||
/* Send authentication command */
|
||||
CURLcode (*sendcont)(struct connectdata *conn, const char *contauth);
|
||||
/* Send authentication continuation */
|
||||
void (*getmessage)(char *buffer, char **outptr);
|
||||
/* Get SASL response message */
|
||||
};
|
||||
|
||||
/* Per-connection parameters */
|
||||
struct SASL {
|
||||
const struct SASLproto *params; /* Protocol dependent parameters */
|
||||
saslstate state; /* Current machine state */
|
||||
unsigned int authmechs; /* Accepted authentication mechanisms */
|
||||
unsigned int prefmech; /* Preferred authentication mechanism */
|
||||
unsigned int authused; /* Auth mechanism used for the connection */
|
||||
bool resetprefs; /* For URL auth option parsing. */
|
||||
bool mutual_auth; /* Mutual authentication enabled (GSSAPI only) */
|
||||
bool force_ir; /* Protocol always supports initial response */
|
||||
};
|
||||
|
||||
/* This is used to test whether the line starts with the given mechanism */
|
||||
#define sasl_mech_equal(line, wordlen, mech) \
|
||||
(wordlen == (sizeof(mech) - 1) / sizeof(char) && \
|
||||
!memcmp(line, mech, wordlen))
|
||||
|
||||
/* This is used to cleanup any libraries or curl modules used by the sasl
|
||||
functions */
|
||||
void Curl_sasl_cleanup(struct connectdata *conn, unsigned int authused);
|
||||
|
||||
/* Convert a mechanism name to a token */
|
||||
unsigned int Curl_sasl_decode_mech(const char *ptr,
|
||||
size_t maxlen, size_t *len);
|
||||
|
||||
/* Parse the URL login options */
|
||||
CURLcode Curl_sasl_parse_url_auth_option(struct SASL *sasl,
|
||||
const char *value, size_t len);
|
||||
|
||||
/* Initializes an SASL structure */
|
||||
void Curl_sasl_init(struct SASL *sasl, const struct SASLproto *params);
|
||||
|
||||
/* Check if we have enough auth data and capabilities to authenticate */
|
||||
bool Curl_sasl_can_authenticate(struct SASL *sasl, struct connectdata *conn);
|
||||
|
||||
/* Calculate the required login details for SASL authentication */
|
||||
CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn,
|
||||
bool force_ir, saslprogress *progress);
|
||||
|
||||
/* Continue an SASL authentication */
|
||||
CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn,
|
||||
int code, saslprogress *progress);
|
||||
|
||||
#endif /* HEADER_CURL_SASL_H */
|
51
src/dependencies/cmcurl/lib/curl_sec.h
Normal file
51
src/dependencies/cmcurl/lib/curl_sec.h
Normal file
|
@ -0,0 +1,51 @@
|
|||
#ifndef HEADER_CURL_SECURITY_H
|
||||
#define HEADER_CURL_SECURITY_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
struct Curl_sec_client_mech {
|
||||
const char *name;
|
||||
size_t size;
|
||||
int (*init)(void *);
|
||||
int (*auth)(void *, struct connectdata *);
|
||||
void (*end)(void *);
|
||||
int (*check_prot)(void *, int);
|
||||
int (*overhead)(void *, int, int);
|
||||
int (*encode)(void *, const void *, int, int, void **);
|
||||
int (*decode)(void *, void *, int, int, struct connectdata *);
|
||||
};
|
||||
|
||||
#define AUTH_OK 0
|
||||
#define AUTH_CONTINUE 1
|
||||
#define AUTH_ERROR 2
|
||||
|
||||
#ifdef HAVE_GSSAPI
|
||||
int Curl_sec_read_msg(struct connectdata *conn, char *,
|
||||
enum protection_level);
|
||||
void Curl_sec_end(struct connectdata *);
|
||||
CURLcode Curl_sec_login(struct connectdata *);
|
||||
int Curl_sec_request_prot(struct connectdata *conn, const char *level);
|
||||
|
||||
extern struct Curl_sec_client_mech Curl_krb5_client_mech;
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_SECURITY_H */
|
845
src/dependencies/cmcurl/lib/curl_setup.h
Normal file
845
src/dependencies/cmcurl/lib/curl_setup.h
Normal file
|
@ -0,0 +1,845 @@
|
|||
#ifndef HEADER_CURL_SETUP_H
|
||||
#define HEADER_CURL_SETUP_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#if defined(BUILDING_LIBCURL) && !defined(CURL_NO_OLDIES)
|
||||
#define CURL_NO_OLDIES
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Define WIN32 when build target is Win32 API
|
||||
*/
|
||||
|
||||
#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) && \
|
||||
!defined(__SYMBIAN32__)
|
||||
#define WIN32
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
/*
|
||||
* Don't include unneeded stuff in Windows headers to avoid compiler
|
||||
* warnings and macro clashes.
|
||||
* Make sure to define this macro before including any Windows headers.
|
||||
*/
|
||||
# ifndef WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# endif
|
||||
# ifndef NOGDI
|
||||
# define NOGDI
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Include configuration script results or hand-crafted
|
||||
* configuration file for platforms which lack config tool.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
|
||||
#include "curl_config.h"
|
||||
|
||||
#else /* HAVE_CONFIG_H */
|
||||
|
||||
#ifdef _WIN32_WCE
|
||||
# include "config-win32ce.h"
|
||||
#else
|
||||
# ifdef WIN32
|
||||
# include "config-win32.h"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(macintosh) && defined(__MRC__)
|
||||
# include "config-mac.h"
|
||||
#endif
|
||||
|
||||
#ifdef __riscos__
|
||||
# include "config-riscos.h"
|
||||
#endif
|
||||
|
||||
#ifdef __AMIGA__
|
||||
# include "config-amigaos.h"
|
||||
#endif
|
||||
|
||||
#ifdef __SYMBIAN32__
|
||||
# include "config-symbian.h"
|
||||
#endif
|
||||
|
||||
#ifdef __OS400__
|
||||
# include "config-os400.h"
|
||||
#endif
|
||||
|
||||
#ifdef TPF
|
||||
# include "config-tpf.h"
|
||||
#endif
|
||||
|
||||
#ifdef __VXWORKS__
|
||||
# include "config-vxworks.h"
|
||||
#endif
|
||||
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(push,1)
|
||||
#endif
|
||||
|
||||
/* ================================================================ */
|
||||
/* Definition of preprocessor macros/symbols which modify compiler */
|
||||
/* behavior or generated code characteristics must be done here, */
|
||||
/* as appropriate, before any system header file is included. It is */
|
||||
/* also possible to have them defined in the config file included */
|
||||
/* before this point. As a result of all this we frown inclusion of */
|
||||
/* system header files in our config files, avoid this at any cost. */
|
||||
/* ================================================================ */
|
||||
|
||||
/*
|
||||
* AIX 4.3 and newer needs _THREAD_SAFE defined to build
|
||||
* proper reentrant code. Others may also need it.
|
||||
*/
|
||||
|
||||
#ifdef NEED_THREAD_SAFE
|
||||
# ifndef _THREAD_SAFE
|
||||
# define _THREAD_SAFE
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Tru64 needs _REENTRANT set for a few function prototypes and
|
||||
* things to appear in the system header files. Unixware needs it
|
||||
* to build proper reentrant code. Others may also need it.
|
||||
*/
|
||||
|
||||
#ifdef NEED_REENTRANT
|
||||
# ifndef _REENTRANT
|
||||
# define _REENTRANT
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Solaris needs this to get a POSIX-conformant getpwuid_r */
|
||||
#if defined(sun) || defined(__sun)
|
||||
# ifndef _POSIX_PTHREAD_SEMANTICS
|
||||
# define _POSIX_PTHREAD_SEMANTICS 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* ================================================================ */
|
||||
/* If you need to include a system header file for your platform, */
|
||||
/* please, do it beyond the point further indicated in this file. */
|
||||
/* ================================================================ */
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#define CURL_SIZEOF_CURL_OFF_T SIZEOF_CURL_OFF_T
|
||||
|
||||
/*
|
||||
* Disable other protocols when http is the only one desired.
|
||||
*/
|
||||
|
||||
#ifdef HTTP_ONLY
|
||||
# ifndef CURL_DISABLE_TFTP
|
||||
# define CURL_DISABLE_TFTP
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_FTP
|
||||
# define CURL_DISABLE_FTP
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_LDAP
|
||||
# define CURL_DISABLE_LDAP
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_TELNET
|
||||
# define CURL_DISABLE_TELNET
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_DICT
|
||||
# define CURL_DISABLE_DICT
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_FILE
|
||||
# define CURL_DISABLE_FILE
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_RTSP
|
||||
# define CURL_DISABLE_RTSP
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_POP3
|
||||
# define CURL_DISABLE_POP3
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_IMAP
|
||||
# define CURL_DISABLE_IMAP
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_SMTP
|
||||
# define CURL_DISABLE_SMTP
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_GOPHER
|
||||
# define CURL_DISABLE_GOPHER
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_SMB
|
||||
# define CURL_DISABLE_SMB
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* When http is disabled rtsp is not supported.
|
||||
*/
|
||||
|
||||
#if defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_RTSP)
|
||||
# define CURL_DISABLE_RTSP
|
||||
#endif
|
||||
|
||||
/* ================================================================ */
|
||||
/* No system header file shall be included in this file before this */
|
||||
/* point. The only allowed ones are those included from curl/system.h */
|
||||
/* ================================================================ */
|
||||
|
||||
/*
|
||||
* OS/400 setup file includes some system headers.
|
||||
*/
|
||||
|
||||
#ifdef __OS400__
|
||||
# include "setup-os400.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* VMS setup file includes some system headers.
|
||||
*/
|
||||
|
||||
#ifdef __VMS
|
||||
# include "setup-vms.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Use getaddrinfo to resolve the IPv4 address literal. If the current network
|
||||
* interface doesn't support IPv4, but supports IPv6, NAT64, and DNS64,
|
||||
* performing this task will result in a synthesized IPv6 address.
|
||||
*/
|
||||
#ifdef __APPLE__
|
||||
#define USE_RESOLVE_ON_IPS 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Include header files for windows builds before redefining anything.
|
||||
* Use this preprocessor block only to include or exclude windows.h,
|
||||
* winsock2.h, ws2tcpip.h or winsock.h. Any other windows thing belongs
|
||||
* to any other further and independent block. Under Cygwin things work
|
||||
* just as under linux (e.g. <sys/socket.h>) and the winsock headers should
|
||||
* never be included when __CYGWIN__ is defined. configure script takes
|
||||
* care of this, not defining HAVE_WINDOWS_H, HAVE_WINSOCK_H, HAVE_WINSOCK2_H,
|
||||
* neither HAVE_WS2TCPIP_H when __CYGWIN__ is defined.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_WINDOWS_H
|
||||
# if defined(UNICODE) && !defined(_UNICODE)
|
||||
# define _UNICODE
|
||||
# endif
|
||||
# if defined(_UNICODE) && !defined(UNICODE)
|
||||
# define UNICODE
|
||||
# endif
|
||||
# include <winerror.h>
|
||||
# include <windows.h>
|
||||
# ifdef HAVE_WINSOCK2_H
|
||||
# include <winsock2.h>
|
||||
# ifdef HAVE_WS2TCPIP_H
|
||||
# include <ws2tcpip.h>
|
||||
# endif
|
||||
# else
|
||||
# ifdef HAVE_WINSOCK_H
|
||||
# include <winsock.h>
|
||||
# endif
|
||||
# endif
|
||||
# include <tchar.h>
|
||||
# ifdef UNICODE
|
||||
typedef wchar_t *(*curl_wcsdup_callback)(const wchar_t *str);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Define USE_WINSOCK to 2 if we have and use WINSOCK2 API, else
|
||||
* define USE_WINSOCK to 1 if we have and use WINSOCK API, else
|
||||
* undefine USE_WINSOCK.
|
||||
*/
|
||||
|
||||
#undef USE_WINSOCK
|
||||
|
||||
#ifdef HAVE_WINSOCK2_H
|
||||
# define USE_WINSOCK 2
|
||||
#else
|
||||
# ifdef HAVE_WINSOCK_H
|
||||
# define USE_WINSOCK 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef USE_LWIPSOCK
|
||||
# include <lwip/init.h>
|
||||
# include <lwip/sockets.h>
|
||||
# include <lwip/netdb.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_EXTRA_STRICMP_H
|
||||
# include <extra/stricmp.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_EXTRA_STRDUP_H
|
||||
# include <extra/strdup.h>
|
||||
#endif
|
||||
|
||||
#ifdef TPF
|
||||
# include <strings.h> /* for bzero, strcasecmp, and strncasecmp */
|
||||
# include <string.h> /* for strcpy and strlen */
|
||||
# include <stdlib.h> /* for rand and srand */
|
||||
# include <sys/socket.h> /* for select and ioctl*/
|
||||
# include <netdb.h> /* for in_addr_t definition */
|
||||
# include <tpf/sysapi.h> /* for tpf_process_signals */
|
||||
/* change which select is used for libcurl */
|
||||
# define select(a,b,c,d,e) tpf_select_libcurl(a,b,c,d,e)
|
||||
#endif
|
||||
|
||||
#ifdef __VXWORKS__
|
||||
# include <sockLib.h> /* for generic BSD socket functions */
|
||||
# include <ioLib.h> /* for basic I/O interface functions */
|
||||
#endif
|
||||
|
||||
#ifdef __AMIGA__
|
||||
# include <exec/types.h>
|
||||
# include <exec/execbase.h>
|
||||
# include <proto/exec.h>
|
||||
# include <proto/dos.h>
|
||||
# ifdef HAVE_PROTO_BSDSOCKET_H
|
||||
# include <proto/bsdsocket.h> /* ensure bsdsocket.library use */
|
||||
# define select(a,b,c,d,e) WaitSelect(a,b,c,d,e,0)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_ASSERT_H
|
||||
#include <assert.h>
|
||||
#endif
|
||||
|
||||
#ifdef __TANDEM /* for nsr-tandem-nsk systems */
|
||||
#include <floss.h>
|
||||
#endif
|
||||
|
||||
#ifndef STDC_HEADERS /* no standard C headers! */
|
||||
#include <curl/stdcheaders.h>
|
||||
#endif
|
||||
|
||||
#ifdef __POCC__
|
||||
# include <sys/types.h>
|
||||
# include <unistd.h>
|
||||
# define sys_nerr EILSEQ
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Salford-C kludge section (mostly borrowed from wxWidgets).
|
||||
*/
|
||||
#ifdef __SALFORDC__
|
||||
#pragma suppress 353 /* Possible nested comments */
|
||||
#pragma suppress 593 /* Define not used */
|
||||
#pragma suppress 61 /* enum has no name */
|
||||
#pragma suppress 106 /* unnamed, unused parameter */
|
||||
#include <clib.h>
|
||||
#endif
|
||||
|
||||
/* Default Windows file API selection. */
|
||||
#ifdef _WIN32
|
||||
# if defined(_MSC_VER) && (_INTEGRAL_MAX_BITS >= 64)
|
||||
# define USE_WIN32_LARGE_FILES
|
||||
# elif defined(__MINGW32__)
|
||||
# define USE_WIN32_LARGE_FILES
|
||||
# else
|
||||
# define USE_WIN32_SMALL_FILES
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Large file (>2Gb) support using WIN32 functions.
|
||||
*/
|
||||
|
||||
#ifdef USE_WIN32_LARGE_FILES
|
||||
# include <io.h>
|
||||
# include <sys/types.h>
|
||||
# include <sys/stat.h>
|
||||
# undef lseek
|
||||
# define lseek(fdes,offset,whence) _lseeki64(fdes, offset, whence)
|
||||
# undef fstat
|
||||
# define fstat(fdes,stp) _fstati64(fdes, stp)
|
||||
# undef stat
|
||||
# define stat(fname,stp) _stati64(fname, stp)
|
||||
# define struct_stat struct _stati64
|
||||
# define LSEEK_ERROR (__int64)-1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Small file (<2Gb) support using WIN32 functions.
|
||||
*/
|
||||
|
||||
#ifdef USE_WIN32_SMALL_FILES
|
||||
# include <io.h>
|
||||
# include <sys/types.h>
|
||||
# include <sys/stat.h>
|
||||
# ifndef _WIN32_WCE
|
||||
# undef lseek
|
||||
# define lseek(fdes,offset,whence) _lseek(fdes, (long)offset, whence)
|
||||
# define fstat(fdes,stp) _fstat(fdes, stp)
|
||||
# define stat(fname,stp) _stat(fname, stp)
|
||||
# define struct_stat struct _stat
|
||||
# endif
|
||||
# define LSEEK_ERROR (long)-1
|
||||
#endif
|
||||
|
||||
#ifndef struct_stat
|
||||
# define struct_stat struct stat
|
||||
#endif
|
||||
|
||||
#ifndef LSEEK_ERROR
|
||||
# define LSEEK_ERROR (off_t)-1
|
||||
#endif
|
||||
|
||||
#ifndef SIZEOF_TIME_T
|
||||
/* assume default size of time_t to be 32 bit */
|
||||
#define SIZEOF_TIME_T 4
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Default sizeof(off_t) in case it hasn't been defined in config file.
|
||||
*/
|
||||
|
||||
#ifndef SIZEOF_OFF_T
|
||||
# if defined(__VMS) && !defined(__VAX)
|
||||
# if defined(_LARGEFILE)
|
||||
# define SIZEOF_OFF_T 8
|
||||
# endif
|
||||
# elif defined(__OS400__) && defined(__ILEC400__)
|
||||
# if defined(_LARGE_FILES)
|
||||
# define SIZEOF_OFF_T 8
|
||||
# endif
|
||||
# elif defined(__MVS__) && defined(__IBMC__)
|
||||
# if defined(_LP64) || defined(_LARGE_FILES)
|
||||
# define SIZEOF_OFF_T 8
|
||||
# endif
|
||||
# elif defined(__370__) && defined(__IBMC__)
|
||||
# if defined(_LP64) || defined(_LARGE_FILES)
|
||||
# define SIZEOF_OFF_T 8
|
||||
# endif
|
||||
# endif
|
||||
# ifndef SIZEOF_OFF_T
|
||||
# define SIZEOF_OFF_T 4
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if (SIZEOF_CURL_OFF_T == 4)
|
||||
# define CURL_OFF_T_MAX CURL_OFF_T_C(0x7FFFFFFF)
|
||||
#else
|
||||
/* assume CURL_SIZEOF_CURL_OFF_T == 8 */
|
||||
# define CURL_OFF_T_MAX CURL_OFF_T_C(0x7FFFFFFFFFFFFFFF)
|
||||
#endif
|
||||
#define CURL_OFF_T_MIN (-CURL_OFF_T_MAX - CURL_OFF_T_C(1))
|
||||
|
||||
#if (SIZEOF_TIME_T == 4)
|
||||
# ifdef HAVE_TIME_T_UNSIGNED
|
||||
# define TIME_T_MAX UINT_MAX
|
||||
# define TIME_T_MIN 0
|
||||
# else
|
||||
# define TIME_T_MAX INT_MAX
|
||||
# define TIME_T_MIN INT_MIN
|
||||
# endif
|
||||
#else
|
||||
# ifdef HAVE_TIME_T_UNSIGNED
|
||||
# define TIME_T_MAX 0xFFFFFFFFFFFFFFFF
|
||||
# define TIME_T_MIN 0
|
||||
# else
|
||||
# define TIME_T_MAX 0x7FFFFFFFFFFFFFFF
|
||||
# define TIME_T_MIN (-TIME_T_MAX - 1)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef SIZE_T_MAX
|
||||
/* some limits.h headers have this defined, some don't */
|
||||
#if defined(SIZEOF_SIZE_T) && (SIZEOF_SIZE_T > 4)
|
||||
#define SIZE_T_MAX 18446744073709551615U
|
||||
#else
|
||||
#define SIZE_T_MAX 4294967295U
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Arg 2 type for gethostname in case it hasn't been defined in config file.
|
||||
*/
|
||||
|
||||
#ifndef GETHOSTNAME_TYPE_ARG2
|
||||
# ifdef USE_WINSOCK
|
||||
# define GETHOSTNAME_TYPE_ARG2 int
|
||||
# else
|
||||
# define GETHOSTNAME_TYPE_ARG2 size_t
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Below we define some functions. They should
|
||||
|
||||
4. set the SIGALRM signal timeout
|
||||
5. set dir/file naming defines
|
||||
*/
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
# define DIR_CHAR "\\"
|
||||
# define DOT_CHAR "_"
|
||||
|
||||
#else /* WIN32 */
|
||||
|
||||
# ifdef MSDOS /* Watt-32 */
|
||||
|
||||
# include <sys/ioctl.h>
|
||||
# define select(n,r,w,x,t) select_s(n,r,w,x,t)
|
||||
# define ioctl(x,y,z) ioctlsocket(x,y,(char *)(z))
|
||||
# include <tcp.h>
|
||||
# ifdef word
|
||||
# undef word
|
||||
# endif
|
||||
# ifdef byte
|
||||
# undef byte
|
||||
# endif
|
||||
|
||||
# endif /* MSDOS */
|
||||
|
||||
# ifdef __minix
|
||||
/* Minix 3 versions up to at least 3.1.3 are missing these prototypes */
|
||||
extern char *strtok_r(char *s, const char *delim, char **last);
|
||||
extern struct tm *gmtime_r(const time_t * const timep, struct tm *tmp);
|
||||
# endif
|
||||
|
||||
# define DIR_CHAR "/"
|
||||
# ifndef DOT_CHAR
|
||||
# define DOT_CHAR "."
|
||||
# endif
|
||||
|
||||
# ifdef MSDOS
|
||||
# undef DOT_CHAR
|
||||
# define DOT_CHAR "_"
|
||||
# endif
|
||||
|
||||
# ifndef fileno /* sunos 4 have this as a macro! */
|
||||
int fileno(FILE *stream);
|
||||
# endif
|
||||
|
||||
#endif /* WIN32 */
|
||||
|
||||
/*
|
||||
* msvc 6.0 requires PSDK in order to have INET6_ADDRSTRLEN
|
||||
* defined in ws2tcpip.h as well as to provide IPv6 support.
|
||||
* Does not apply if lwIP is used.
|
||||
*/
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__POCC__) && !defined(USE_LWIPSOCK)
|
||||
# if !defined(HAVE_WS2TCPIP_H) || \
|
||||
((_MSC_VER < 1300) && !defined(INET6_ADDRSTRLEN))
|
||||
# undef HAVE_GETADDRINFO_THREADSAFE
|
||||
# undef HAVE_FREEADDRINFO
|
||||
# undef HAVE_GETADDRINFO
|
||||
# undef HAVE_GETNAMEINFO
|
||||
# undef ENABLE_IPV6
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* resolver specialty compile-time defines */
|
||||
/* CURLRES_* defines to use in the host*.c sources */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* lcc-win32 doesn't have _beginthreadex(), lacks threads support.
|
||||
*/
|
||||
|
||||
#if defined(__LCC__) && defined(WIN32)
|
||||
# undef USE_THREADS_POSIX
|
||||
# undef USE_THREADS_WIN32
|
||||
#endif
|
||||
|
||||
/*
|
||||
* MSVC threads support requires a multi-threaded runtime library.
|
||||
* _beginthreadex() is not available in single-threaded ones.
|
||||
*/
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__POCC__) && !defined(_MT)
|
||||
# undef USE_THREADS_POSIX
|
||||
# undef USE_THREADS_WIN32
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Mutually exclusive CURLRES_* definitions.
|
||||
*/
|
||||
|
||||
#ifdef USE_ARES
|
||||
# define CURLRES_ASYNCH
|
||||
# define CURLRES_ARES
|
||||
/* now undef the stock libc functions just to avoid them being used */
|
||||
# undef HAVE_GETADDRINFO
|
||||
# undef HAVE_FREEADDRINFO
|
||||
# undef HAVE_GETHOSTBYNAME
|
||||
#elif defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32)
|
||||
# define CURLRES_ASYNCH
|
||||
# define CURLRES_THREADED
|
||||
#else
|
||||
# define CURLRES_SYNCH
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_IPV6
|
||||
# define CURLRES_IPV6
|
||||
#else
|
||||
# define CURLRES_IPV4
|
||||
#endif
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* When using WINSOCK, TELNET protocol requires WINSOCK2 API.
|
||||
*/
|
||||
|
||||
#if defined(USE_WINSOCK) && (USE_WINSOCK != 2)
|
||||
# define CURL_DISABLE_TELNET 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* msvc 6.0 does not have struct sockaddr_storage and
|
||||
* does not define IPPROTO_ESP in winsock2.h. But both
|
||||
* are available if PSDK is properly installed.
|
||||
*/
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__POCC__)
|
||||
# if !defined(HAVE_WINSOCK2_H) || ((_MSC_VER < 1300) && !defined(IPPROTO_ESP))
|
||||
# undef HAVE_STRUCT_SOCKADDR_STORAGE
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Intentionally fail to build when using msvc 6.0 without PSDK installed.
|
||||
* The brave of heart can circumvent this, defining ALLOW_MSVC6_WITHOUT_PSDK
|
||||
* in lib/config-win32.h although absolutely discouraged and unsupported.
|
||||
*/
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__POCC__)
|
||||
# if !defined(HAVE_WINDOWS_H) || ((_MSC_VER < 1300) && !defined(_FILETIME_))
|
||||
# if !defined(ALLOW_MSVC6_WITHOUT_PSDK)
|
||||
# error MSVC 6.0 requires "February 2003 Platform SDK" a.k.a. \
|
||||
"Windows Server 2003 PSDK"
|
||||
# else
|
||||
# define CURL_DISABLE_LDAP 1
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef NETWARE
|
||||
int netware_init(void);
|
||||
#ifndef __NOVELL_LIBC__
|
||||
#include <sys/bsdskt.h>
|
||||
#include <sys/timeval.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_LIBIDN2) && defined(HAVE_IDN2_H) && !defined(USE_WIN32_IDN)
|
||||
/* The lib and header are present */
|
||||
#define USE_LIBIDN2
|
||||
#endif
|
||||
|
||||
#if defined(USE_LIBIDN2) && defined(USE_WIN32_IDN)
|
||||
#error "Both libidn2 and WinIDN are enabled, choose one."
|
||||
#endif
|
||||
|
||||
#define LIBIDN_REQUIRED_VERSION "0.4.1"
|
||||
|
||||
#if defined(USE_GNUTLS) || defined(USE_OPENSSL) || defined(USE_NSS) || \
|
||||
defined(USE_POLARSSL) || defined(USE_MBEDTLS) || \
|
||||
defined(USE_CYASSL) || defined(USE_SCHANNEL) || \
|
||||
defined(USE_SECTRANSP) || defined(USE_GSKIT) || defined(USE_MESALINK)
|
||||
#define USE_SSL /* SSL support has been enabled */
|
||||
#endif
|
||||
|
||||
/* Single point where USE_SPNEGO definition might be defined */
|
||||
#if !defined(CURL_DISABLE_CRYPTO_AUTH) && \
|
||||
(defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI))
|
||||
#define USE_SPNEGO
|
||||
#endif
|
||||
|
||||
/* Single point where USE_KERBEROS5 definition might be defined */
|
||||
#if !defined(CURL_DISABLE_CRYPTO_AUTH) && \
|
||||
(defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI))
|
||||
#define USE_KERBEROS5
|
||||
#endif
|
||||
|
||||
/* Single point where USE_NTLM definition might be defined */
|
||||
#if !defined(CURL_DISABLE_NTLM) && !defined(CURL_DISABLE_CRYPTO_AUTH)
|
||||
#if defined(USE_OPENSSL) || defined(USE_WINDOWS_SSPI) || \
|
||||
defined(USE_GNUTLS) || defined(USE_NSS) || defined(USE_SECTRANSP) || \
|
||||
defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO) || \
|
||||
defined(USE_MBEDTLS)
|
||||
|
||||
#define USE_NTLM
|
||||
|
||||
# if defined(USE_MBEDTLS)
|
||||
/* Get definition of MBEDTLS_MD4_C */
|
||||
# include <mbedtls/md4.h>
|
||||
# endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CURL_WANTS_CA_BUNDLE_ENV
|
||||
#error "No longer supported. Set CURLOPT_CAINFO at runtime instead."
|
||||
#endif
|
||||
|
||||
#if defined(USE_LIBSSH2) || defined(USE_LIBSSH) || defined(USE_WOLFSSH)
|
||||
#define USE_SSH
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Provide a mechanism to silence picky compilers, such as gcc 4.6+.
|
||||
* Parameters should of course normally not be unused, but for example when
|
||||
* we have multiple implementations of the same interface it may happen.
|
||||
*/
|
||||
|
||||
#if defined(__GNUC__) && ((__GNUC__ >= 3) || \
|
||||
((__GNUC__ == 2) && defined(__GNUC_MINOR__) && (__GNUC_MINOR__ >= 7)))
|
||||
# define UNUSED_PARAM __attribute__((__unused__))
|
||||
# define WARN_UNUSED_RESULT __attribute__((warn_unused_result))
|
||||
#else
|
||||
# define UNUSED_PARAM /*NOTHING*/
|
||||
# define WARN_UNUSED_RESULT
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Include macros and defines that should only be processed once.
|
||||
*/
|
||||
|
||||
#ifndef HEADER_CURL_SETUP_ONCE_H
|
||||
#include "curl_setup_once.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Definition of our NOP statement Object-like macro
|
||||
*/
|
||||
|
||||
#ifndef Curl_nop_stmt
|
||||
# define Curl_nop_stmt do { } WHILE_FALSE
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Ensure that Winsock and lwIP TCP/IP stacks are not mixed.
|
||||
*/
|
||||
|
||||
#if defined(__LWIP_OPT_H__) || defined(LWIP_HDR_OPT_H)
|
||||
# if defined(SOCKET) || \
|
||||
defined(USE_WINSOCK) || \
|
||||
defined(HAVE_WINSOCK_H) || \
|
||||
defined(HAVE_WINSOCK2_H) || \
|
||||
defined(HAVE_WS2TCPIP_H)
|
||||
# error "Winsock and lwIP TCP/IP stack definitions shall not coexist!"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Portable symbolic names for Winsock shutdown() mode flags.
|
||||
*/
|
||||
|
||||
#ifdef USE_WINSOCK
|
||||
# define SHUT_RD 0x00
|
||||
# define SHUT_WR 0x01
|
||||
# define SHUT_RDWR 0x02
|
||||
#endif
|
||||
|
||||
/* Define S_ISREG if not defined by system headers, f.e. MSVC */
|
||||
#if !defined(S_ISREG) && defined(S_IFMT) && defined(S_IFREG)
|
||||
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
|
||||
#endif
|
||||
|
||||
/* Define S_ISDIR if not defined by system headers, f.e. MSVC */
|
||||
#if !defined(S_ISDIR) && defined(S_IFMT) && defined(S_IFDIR)
|
||||
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
|
||||
#endif
|
||||
|
||||
/* In Windows the default file mode is text but an application can override it.
|
||||
Therefore we specify it explicitly. https://github.com/curl/curl/pull/258
|
||||
*/
|
||||
#if defined(WIN32) || defined(MSDOS)
|
||||
#define FOPEN_READTEXT "rt"
|
||||
#define FOPEN_WRITETEXT "wt"
|
||||
#define FOPEN_APPENDTEXT "at"
|
||||
#elif defined(__CYGWIN__)
|
||||
/* Cygwin has specific behavior we need to address when WIN32 is not defined.
|
||||
https://cygwin.com/cygwin-ug-net/using-textbinary.html
|
||||
For write we want our output to have line endings of LF and be compatible with
|
||||
other Cygwin utilities. For read we want to handle input that may have line
|
||||
endings either CRLF or LF so 't' is appropriate.
|
||||
*/
|
||||
#define FOPEN_READTEXT "rt"
|
||||
#define FOPEN_WRITETEXT "w"
|
||||
#define FOPEN_APPENDTEXT "a"
|
||||
#else
|
||||
#define FOPEN_READTEXT "r"
|
||||
#define FOPEN_WRITETEXT "w"
|
||||
#define FOPEN_APPENDTEXT "a"
|
||||
#endif
|
||||
|
||||
/* WinSock destroys recv() buffer when send() failed.
|
||||
* Enabled automatically for Windows and for Cygwin as Cygwin sockets are
|
||||
* wrappers for WinSock sockets. https://github.com/curl/curl/issues/657
|
||||
* Define DONT_USE_RECV_BEFORE_SEND_WORKAROUND to force disable workaround.
|
||||
*/
|
||||
#if !defined(DONT_USE_RECV_BEFORE_SEND_WORKAROUND)
|
||||
# if defined(WIN32) || defined(__CYGWIN__)
|
||||
# define USE_RECV_BEFORE_SEND_WORKAROUND
|
||||
# endif
|
||||
#else /* DONT_USE_RECV_BEFORE_SEND_WORKAROUND */
|
||||
# ifdef USE_RECV_BEFORE_SEND_WORKAROUND
|
||||
# undef USE_RECV_BEFORE_SEND_WORKAROUND
|
||||
# endif
|
||||
#endif /* DONT_USE_RECV_BEFORE_SEND_WORKAROUND */
|
||||
|
||||
/* Detect Windows App environment which has a restricted access
|
||||
* to the Win32 APIs. */
|
||||
# if (defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0602)) || \
|
||||
defined(WINAPI_FAMILY)
|
||||
# include <winapifamily.h>
|
||||
# if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && \
|
||||
!WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||
# define CURL_WINDOWS_APP
|
||||
# endif
|
||||
# endif
|
||||
|
||||
/* for systems that don't detect this in configure, use a sensible default */
|
||||
#ifndef CURL_SA_FAMILY_T
|
||||
#define CURL_SA_FAMILY_T unsigned short
|
||||
#endif
|
||||
|
||||
/* Some convenience macros to get the larger/smaller value out of two given.
|
||||
We prefix with CURL to prevent name collisions. */
|
||||
#define CURLMAX(x,y) ((x)>(y)?(x):(y))
|
||||
#define CURLMIN(x,y) ((x)<(y)?(x):(y))
|
||||
|
||||
/* Some versions of the Android SDK is missing the declaration */
|
||||
#if defined(HAVE_GETPWUID_R) && defined(HAVE_DECL_GETPWUID_R_MISSING)
|
||||
struct passwd;
|
||||
int getpwuid_r(uid_t uid, struct passwd *pwd, char *buf,
|
||||
size_t buflen, struct passwd **result);
|
||||
#endif
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
#define UNITTEST
|
||||
#else
|
||||
#define UNITTEST static
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_SETUP_H */
|
517
src/dependencies/cmcurl/lib/curl_setup_once.h
Normal file
517
src/dependencies/cmcurl/lib/curl_setup_once.h
Normal file
|
@ -0,0 +1,517 @@
|
|||
#ifndef HEADER_CURL_SETUP_ONCE_H
|
||||
#define HEADER_CURL_SETUP_ONCE_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
/*
|
||||
* Inclusion of common header files.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#ifdef NEED_MALLOC_H
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
#ifdef NEED_MEMORY_H
|
||||
#include <memory.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#ifdef TIME_WITH_SYS_TIME
|
||||
#include <time.h>
|
||||
#endif
|
||||
#else
|
||||
#ifdef HAVE_TIME_H
|
||||
#include <time.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_STDBOOL_H) && defined(HAVE_BOOL_T)
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef __hpux
|
||||
# if !defined(_XOPEN_SOURCE_EXTENDED) || defined(_KERNEL)
|
||||
# ifdef _APP32_64BIT_OFF_T
|
||||
# define OLD_APP32_64BIT_OFF_T _APP32_64BIT_OFF_T
|
||||
# undef _APP32_64BIT_OFF_T
|
||||
# else
|
||||
# undef OLD_APP32_64BIT_OFF_T
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
#ifdef __hpux
|
||||
# if !defined(_XOPEN_SOURCE_EXTENDED) || defined(_KERNEL)
|
||||
# ifdef OLD_APP32_64BIT_OFF_T
|
||||
# define _APP32_64BIT_OFF_T OLD_APP32_64BIT_OFF_T
|
||||
# undef OLD_APP32_64BIT_OFF_T
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Definition of timeval struct for platforms that don't have it.
|
||||
*/
|
||||
|
||||
#ifndef HAVE_STRUCT_TIMEVAL
|
||||
struct timeval {
|
||||
long tv_sec;
|
||||
long tv_usec;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* If we have the MSG_NOSIGNAL define, make sure we use
|
||||
* it as the fourth argument of function send()
|
||||
*/
|
||||
|
||||
#ifdef HAVE_MSG_NOSIGNAL
|
||||
#define SEND_4TH_ARG MSG_NOSIGNAL
|
||||
#else
|
||||
#define SEND_4TH_ARG 0
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__minix)
|
||||
/* Minix doesn't support recv on TCP sockets */
|
||||
#define sread(x,y,z) (ssize_t)read((RECV_TYPE_ARG1)(x), \
|
||||
(RECV_TYPE_ARG2)(y), \
|
||||
(RECV_TYPE_ARG3)(z))
|
||||
|
||||
#elif defined(HAVE_RECV)
|
||||
/*
|
||||
* The definitions for the return type and arguments types
|
||||
* of functions recv() and send() belong and come from the
|
||||
* configuration file. Do not define them in any other place.
|
||||
*
|
||||
* HAVE_RECV is defined if you have a function named recv()
|
||||
* which is used to read incoming data from sockets. If your
|
||||
* function has another name then don't define HAVE_RECV.
|
||||
*
|
||||
* If HAVE_RECV is defined then RECV_TYPE_ARG1, RECV_TYPE_ARG2,
|
||||
* RECV_TYPE_ARG3, RECV_TYPE_ARG4 and RECV_TYPE_RETV must also
|
||||
* be defined.
|
||||
*
|
||||
* HAVE_SEND is defined if you have a function named send()
|
||||
* which is used to write outgoing data on a connected socket.
|
||||
* If yours has another name then don't define HAVE_SEND.
|
||||
*
|
||||
* If HAVE_SEND is defined then SEND_TYPE_ARG1, SEND_QUAL_ARG2,
|
||||
* SEND_TYPE_ARG2, SEND_TYPE_ARG3, SEND_TYPE_ARG4 and
|
||||
* SEND_TYPE_RETV must also be defined.
|
||||
*/
|
||||
|
||||
#if !defined(RECV_TYPE_ARG1) || \
|
||||
!defined(RECV_TYPE_ARG2) || \
|
||||
!defined(RECV_TYPE_ARG3) || \
|
||||
!defined(RECV_TYPE_ARG4) || \
|
||||
!defined(RECV_TYPE_RETV)
|
||||
/* */
|
||||
Error Missing_definition_of_return_and_arguments_types_of_recv
|
||||
/* */
|
||||
#else
|
||||
#define sread(x,y,z) (ssize_t)recv((RECV_TYPE_ARG1)(x), \
|
||||
(RECV_TYPE_ARG2)(y), \
|
||||
(RECV_TYPE_ARG3)(z), \
|
||||
(RECV_TYPE_ARG4)(0))
|
||||
#endif
|
||||
#else /* HAVE_RECV */
|
||||
#ifndef sread
|
||||
/* */
|
||||
Error Missing_definition_of_macro_sread
|
||||
/* */
|
||||
#endif
|
||||
#endif /* HAVE_RECV */
|
||||
|
||||
|
||||
#if defined(__minix)
|
||||
/* Minix doesn't support send on TCP sockets */
|
||||
#define swrite(x,y,z) (ssize_t)write((SEND_TYPE_ARG1)(x), \
|
||||
(SEND_TYPE_ARG2)(y), \
|
||||
(SEND_TYPE_ARG3)(z))
|
||||
|
||||
#elif defined(HAVE_SEND)
|
||||
#if !defined(SEND_TYPE_ARG1) || \
|
||||
!defined(SEND_QUAL_ARG2) || \
|
||||
!defined(SEND_TYPE_ARG2) || \
|
||||
!defined(SEND_TYPE_ARG3) || \
|
||||
!defined(SEND_TYPE_ARG4) || \
|
||||
!defined(SEND_TYPE_RETV)
|
||||
/* */
|
||||
Error Missing_definition_of_return_and_arguments_types_of_send
|
||||
/* */
|
||||
#else
|
||||
#define swrite(x,y,z) (ssize_t)send((SEND_TYPE_ARG1)(x), \
|
||||
(SEND_QUAL_ARG2 SEND_TYPE_ARG2)(y), \
|
||||
(SEND_TYPE_ARG3)(z), \
|
||||
(SEND_TYPE_ARG4)(SEND_4TH_ARG))
|
||||
#endif
|
||||
#else /* HAVE_SEND */
|
||||
#ifndef swrite
|
||||
/* */
|
||||
Error Missing_definition_of_macro_swrite
|
||||
/* */
|
||||
#endif
|
||||
#endif /* HAVE_SEND */
|
||||
|
||||
|
||||
#if 0
|
||||
#if defined(HAVE_RECVFROM)
|
||||
/*
|
||||
* Currently recvfrom is only used on udp sockets.
|
||||
*/
|
||||
#if !defined(RECVFROM_TYPE_ARG1) || \
|
||||
!defined(RECVFROM_TYPE_ARG2) || \
|
||||
!defined(RECVFROM_TYPE_ARG3) || \
|
||||
!defined(RECVFROM_TYPE_ARG4) || \
|
||||
!defined(RECVFROM_TYPE_ARG5) || \
|
||||
!defined(RECVFROM_TYPE_ARG6) || \
|
||||
!defined(RECVFROM_TYPE_RETV)
|
||||
/* */
|
||||
Error Missing_definition_of_return_and_arguments_types_of_recvfrom
|
||||
/* */
|
||||
#else
|
||||
#define sreadfrom(s,b,bl,f,fl) (ssize_t)recvfrom((RECVFROM_TYPE_ARG1) (s), \
|
||||
(RECVFROM_TYPE_ARG2 *)(b), \
|
||||
(RECVFROM_TYPE_ARG3) (bl), \
|
||||
(RECVFROM_TYPE_ARG4) (0), \
|
||||
(RECVFROM_TYPE_ARG5 *)(f), \
|
||||
(RECVFROM_TYPE_ARG6 *)(fl))
|
||||
#endif
|
||||
#else /* HAVE_RECVFROM */
|
||||
#ifndef sreadfrom
|
||||
/* */
|
||||
Error Missing_definition_of_macro_sreadfrom
|
||||
/* */
|
||||
#endif
|
||||
#endif /* HAVE_RECVFROM */
|
||||
|
||||
|
||||
#ifdef RECVFROM_TYPE_ARG6_IS_VOID
|
||||
# define RECVFROM_ARG6_T int
|
||||
#else
|
||||
# define RECVFROM_ARG6_T RECVFROM_TYPE_ARG6
|
||||
#endif
|
||||
#endif /* if 0 */
|
||||
|
||||
|
||||
/*
|
||||
* Function-like macro definition used to close a socket.
|
||||
*/
|
||||
|
||||
#if defined(HAVE_CLOSESOCKET)
|
||||
# define sclose(x) closesocket((x))
|
||||
#elif defined(HAVE_CLOSESOCKET_CAMEL)
|
||||
# define sclose(x) CloseSocket((x))
|
||||
#elif defined(HAVE_CLOSE_S)
|
||||
# define sclose(x) close_s((x))
|
||||
#elif defined(USE_LWIPSOCK)
|
||||
# define sclose(x) lwip_close((x))
|
||||
#else
|
||||
# define sclose(x) close((x))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Stack-independent version of fcntl() on sockets:
|
||||
*/
|
||||
#if defined(USE_LWIPSOCK)
|
||||
# define sfcntl lwip_fcntl
|
||||
#else
|
||||
# define sfcntl fcntl
|
||||
#endif
|
||||
|
||||
#define TOLOWER(x) (tolower((int) ((unsigned char)x)))
|
||||
|
||||
|
||||
/*
|
||||
* 'bool' stuff compatible with HP-UX headers.
|
||||
*/
|
||||
|
||||
#if defined(__hpux) && !defined(HAVE_BOOL_T)
|
||||
typedef int bool;
|
||||
# define false 0
|
||||
# define true 1
|
||||
# define HAVE_BOOL_T
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* 'bool' exists on platforms with <stdbool.h>, i.e. C99 platforms.
|
||||
* On non-C99 platforms there's no bool, so define an enum for that.
|
||||
* On C99 platforms 'false' and 'true' also exist. Enum uses a
|
||||
* global namespace though, so use bool_false and bool_true.
|
||||
*/
|
||||
|
||||
#ifndef HAVE_BOOL_T
|
||||
typedef enum {
|
||||
bool_false = 0,
|
||||
bool_true = 1
|
||||
} bool;
|
||||
|
||||
/*
|
||||
* Use a define to let 'true' and 'false' use those enums. There
|
||||
* are currently no use of true and false in libcurl proper, but
|
||||
* there are some in the examples. This will cater for any later
|
||||
* code happening to use true and false.
|
||||
*/
|
||||
# define false bool_false
|
||||
# define true bool_true
|
||||
# define HAVE_BOOL_T
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Redefine TRUE and FALSE too, to catch current use. With this
|
||||
* change, 'bool found = 1' will give a warning on MIPSPro, but
|
||||
* 'bool found = TRUE' will not. Change tested on IRIX/MIPSPro,
|
||||
* AIX 5.1/Xlc, Tru64 5.1/cc, w/make test too.
|
||||
*/
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE true
|
||||
#endif
|
||||
#ifndef FALSE
|
||||
#define FALSE false
|
||||
#endif
|
||||
|
||||
#include "curl_ctype.h"
|
||||
|
||||
/*
|
||||
* Macro WHILE_FALSE may be used to build single-iteration do-while loops,
|
||||
* avoiding compiler warnings. Mostly intended for other macro definitions.
|
||||
*/
|
||||
|
||||
#define WHILE_FALSE while(0)
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__POCC__)
|
||||
# undef WHILE_FALSE
|
||||
# if (_MSC_VER < 1500)
|
||||
# define WHILE_FALSE while(1, 0)
|
||||
# else
|
||||
# define WHILE_FALSE \
|
||||
__pragma(warning(push)) \
|
||||
__pragma(warning(disable:4127)) \
|
||||
while(0) \
|
||||
__pragma(warning(pop))
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Typedef to 'int' if sig_atomic_t is not an available 'typedefed' type.
|
||||
*/
|
||||
|
||||
#ifndef HAVE_SIG_ATOMIC_T
|
||||
typedef int sig_atomic_t;
|
||||
#define HAVE_SIG_ATOMIC_T
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Convenience SIG_ATOMIC_T definition
|
||||
*/
|
||||
|
||||
#ifdef HAVE_SIG_ATOMIC_T_VOLATILE
|
||||
#define SIG_ATOMIC_T static sig_atomic_t
|
||||
#else
|
||||
#define SIG_ATOMIC_T static volatile sig_atomic_t
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Default return type for signal handlers.
|
||||
*/
|
||||
|
||||
#ifndef RETSIGTYPE
|
||||
#define RETSIGTYPE void
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Macro used to include code only in debug builds.
|
||||
*/
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
#define DEBUGF(x) x
|
||||
#else
|
||||
#define DEBUGF(x) do { } WHILE_FALSE
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Macro used to include assertion code only in debug builds.
|
||||
*/
|
||||
|
||||
#if defined(DEBUGBUILD) && defined(HAVE_ASSERT_H)
|
||||
#define DEBUGASSERT(x) assert(x)
|
||||
#else
|
||||
#define DEBUGASSERT(x) do { } WHILE_FALSE
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Macro SOCKERRNO / SET_SOCKERRNO() returns / sets the *socket-related* errno
|
||||
* (or equivalent) on this platform to hide platform details to code using it.
|
||||
*/
|
||||
|
||||
#ifdef USE_WINSOCK
|
||||
#define SOCKERRNO ((int)WSAGetLastError())
|
||||
#define SET_SOCKERRNO(x) (WSASetLastError((int)(x)))
|
||||
#else
|
||||
#define SOCKERRNO (errno)
|
||||
#define SET_SOCKERRNO(x) (errno = (x))
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Portable error number symbolic names defined to Winsock error codes.
|
||||
*/
|
||||
|
||||
#ifdef USE_WINSOCK
|
||||
#undef EBADF /* override definition in errno.h */
|
||||
#define EBADF WSAEBADF
|
||||
#undef EINTR /* override definition in errno.h */
|
||||
#define EINTR WSAEINTR
|
||||
#undef EINVAL /* override definition in errno.h */
|
||||
#define EINVAL WSAEINVAL
|
||||
#undef EWOULDBLOCK /* override definition in errno.h */
|
||||
#define EWOULDBLOCK WSAEWOULDBLOCK
|
||||
#undef EINPROGRESS /* override definition in errno.h */
|
||||
#define EINPROGRESS WSAEINPROGRESS
|
||||
#undef EALREADY /* override definition in errno.h */
|
||||
#define EALREADY WSAEALREADY
|
||||
#undef ENOTSOCK /* override definition in errno.h */
|
||||
#define ENOTSOCK WSAENOTSOCK
|
||||
#undef EDESTADDRREQ /* override definition in errno.h */
|
||||
#define EDESTADDRREQ WSAEDESTADDRREQ
|
||||
#undef EMSGSIZE /* override definition in errno.h */
|
||||
#define EMSGSIZE WSAEMSGSIZE
|
||||
#undef EPROTOTYPE /* override definition in errno.h */
|
||||
#define EPROTOTYPE WSAEPROTOTYPE
|
||||
#undef ENOPROTOOPT /* override definition in errno.h */
|
||||
#define ENOPROTOOPT WSAENOPROTOOPT
|
||||
#undef EPROTONOSUPPORT /* override definition in errno.h */
|
||||
#define EPROTONOSUPPORT WSAEPROTONOSUPPORT
|
||||
#define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT
|
||||
#undef EOPNOTSUPP /* override definition in errno.h */
|
||||
#define EOPNOTSUPP WSAEOPNOTSUPP
|
||||
#define EPFNOSUPPORT WSAEPFNOSUPPORT
|
||||
#undef EAFNOSUPPORT /* override definition in errno.h */
|
||||
#define EAFNOSUPPORT WSAEAFNOSUPPORT
|
||||
#undef EADDRINUSE /* override definition in errno.h */
|
||||
#define EADDRINUSE WSAEADDRINUSE
|
||||
#undef EADDRNOTAVAIL /* override definition in errno.h */
|
||||
#define EADDRNOTAVAIL WSAEADDRNOTAVAIL
|
||||
#undef ENETDOWN /* override definition in errno.h */
|
||||
#define ENETDOWN WSAENETDOWN
|
||||
#undef ENETUNREACH /* override definition in errno.h */
|
||||
#define ENETUNREACH WSAENETUNREACH
|
||||
#undef ENETRESET /* override definition in errno.h */
|
||||
#define ENETRESET WSAENETRESET
|
||||
#undef ECONNABORTED /* override definition in errno.h */
|
||||
#define ECONNABORTED WSAECONNABORTED
|
||||
#undef ECONNRESET /* override definition in errno.h */
|
||||
#define ECONNRESET WSAECONNRESET
|
||||
#undef ENOBUFS /* override definition in errno.h */
|
||||
#define ENOBUFS WSAENOBUFS
|
||||
#undef EISCONN /* override definition in errno.h */
|
||||
#define EISCONN WSAEISCONN
|
||||
#undef ENOTCONN /* override definition in errno.h */
|
||||
#define ENOTCONN WSAENOTCONN
|
||||
#define ESHUTDOWN WSAESHUTDOWN
|
||||
#define ETOOMANYREFS WSAETOOMANYREFS
|
||||
#undef ETIMEDOUT /* override definition in errno.h */
|
||||
#define ETIMEDOUT WSAETIMEDOUT
|
||||
#undef ECONNREFUSED /* override definition in errno.h */
|
||||
#define ECONNREFUSED WSAECONNREFUSED
|
||||
#undef ELOOP /* override definition in errno.h */
|
||||
#define ELOOP WSAELOOP
|
||||
#ifndef ENAMETOOLONG /* possible previous definition in errno.h */
|
||||
#define ENAMETOOLONG WSAENAMETOOLONG
|
||||
#endif
|
||||
#define EHOSTDOWN WSAEHOSTDOWN
|
||||
#undef EHOSTUNREACH /* override definition in errno.h */
|
||||
#define EHOSTUNREACH WSAEHOSTUNREACH
|
||||
#ifndef ENOTEMPTY /* possible previous definition in errno.h */
|
||||
#define ENOTEMPTY WSAENOTEMPTY
|
||||
#endif
|
||||
#define EPROCLIM WSAEPROCLIM
|
||||
#define EUSERS WSAEUSERS
|
||||
#define EDQUOT WSAEDQUOT
|
||||
#define ESTALE WSAESTALE
|
||||
#define EREMOTE WSAEREMOTE
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Macro argv_item_t hides platform details to code using it.
|
||||
*/
|
||||
|
||||
#ifdef __VMS
|
||||
#define argv_item_t __char_ptr32
|
||||
#else
|
||||
#define argv_item_t char *
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* We use this ZERO_NULL to avoid picky compiler warnings,
|
||||
* when assigning a NULL pointer to a function pointer var.
|
||||
*/
|
||||
|
||||
#define ZERO_NULL 0
|
||||
|
||||
|
||||
#endif /* HEADER_CURL_SETUP_ONCE_H */
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue