[Cmake-commits] CMake branch, master, updated. v3.8.1-1162-g836cb52

Kitware Robot kwrobot at kitware.com
Fri May 12 09:15:06 EDT 2017


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "CMake".

The branch, master has been updated
       via  836cb52e9aec83f88841cb5b45abb1d32bb02214 (commit)
       via  793b223c02bfbb9d5bd03194a7f9748f6cecf2f2 (commit)
       via  592206a157a57da031cd44d86269a92cfb17a736 (commit)
       via  040de18b36cddba470684e73f3a6bdcaa28474bd (commit)
       via  8843120ded39b90423afd48ebfde4c059d9495ed (commit)
       via  9ab81c4a9b1ffde12663388975759bd757a4f825 (commit)
       via  e0e414d6593d952facb2ce2364d17b34afac8760 (commit)
       via  5d13fe282255d828f7aaf7765a1b069839161ee8 (commit)
       via  e1e8f27ff284a59b8e57e802a6c159940367c51e (commit)
       via  a1218f59d9164407c6e28f816b0f11314b64fe5c (commit)
       via  4ba25a823e62271a74dfd1845f535400e2da125b (commit)
       via  a44dab461ffe269618f008f16e249d9101c5bd88 (commit)
       via  c734c8501b5e8865b8a2e92a8834644becb181e4 (commit)
       via  bd14e46400aaeb3afc826c6316b376eba6f082b2 (commit)
       via  587084052bbecc812de00e75aac389faef6b7eed (commit)
       via  036ffe815acd1ea4ee5cafb1b9547930bfbdbebf (commit)
       via  a890ca2f8dfc640f7096f3ad89a2429315d8b71a (commit)
       via  95d3ebcc4880c0b69108c6155b38abbbc6ca5e15 (commit)
       via  11ba72c6d604db44e12b0f67f20a0e192d69b970 (commit)
       via  299975908ada992800791fac7f3739050e0ae2a9 (commit)
       via  fd7d521c9d70655618db8232d45e5aaf81700f91 (commit)
       via  5af9c8e2451afd8e63d6b05e69cd141af543a164 (commit)
      from  91d987e15c3249f35bb1151a2a3b7e487c61f095 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=836cb52e9aec83f88841cb5b45abb1d32bb02214
commit 836cb52e9aec83f88841cb5b45abb1d32bb02214
Merge: 793b223 a1218f5
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Fri May 12 13:13:48 2017 +0000
Commit:     Kitware Robot <kwrobot at kitware.com>
CommitDate: Fri May 12 09:13:51 2017 -0400

    Merge topic 'command-name'
    
    a1218f59 cmCommand: remove unused methods from interface and all implementations
    4ba25a82 cmState: separate builtin and scripted commands
    a44dab46 cmState: introduce method for adding scripted commands
    c734c850 CTest: use new methods for builtin commands
    bd14e464 cmCommands: use new methods for builtin commands
    58708405 cmState: introduce methods for adding builtin commands
    a890ca2f cmakemain: use script role for -P
    
    Acked-by: Kitware Robot <kwrobot at kitware.com>
    Merge-request: !829


https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=793b223c02bfbb9d5bd03194a7f9748f6cecf2f2
commit 793b223c02bfbb9d5bd03194a7f9748f6cecf2f2
Merge: 592206a e0e414d
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Fri May 12 13:13:30 2017 +0000
Commit:     Kitware Robot <kwrobot at kitware.com>
CommitDate: Fri May 12 09:13:37 2017 -0400

    Merge topic 'getprerequisites-fix'
    
    e0e414d6 GetPrerequisites: Only recurse on resolved unseen prerequisites
    
    Acked-by: Kitware Robot <kwrobot at kitware.com>
    Merge-request: !804


https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=592206a157a57da031cd44d86269a92cfb17a736
commit 592206a157a57da031cd44d86269a92cfb17a736
Merge: 040de18 036ffe8
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Fri May 12 13:13:16 2017 +0000
Commit:     Kitware Robot <kwrobot at kitware.com>
CommitDate: Fri May 12 09:13:19 2017 -0400

    Merge topic 'add_cuda_cxx14_flag'
    
    036ffe81 CUDA: Add support for the C++14 standard flag.
    
    Acked-by: Kitware Robot <kwrobot at kitware.com>
    Merge-request: !830


https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=040de18b36cddba470684e73f3a6bdcaa28474bd
commit 040de18b36cddba470684e73f3a6bdcaa28474bd
Merge: 8843120 5d13fe2
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Fri May 12 13:12:37 2017 +0000
Commit:     Kitware Robot <kwrobot at kitware.com>
CommitDate: Fri May 12 09:12:48 2017 -0400

    Merge topic 'sunpro-c-features'
    
    5d13fe28 Features: Record features for SunPro C 5.13 and 5.14
    
    Acked-by: Kitware Robot <kwrobot at kitware.com>
    Merge-request: !832


https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=8843120ded39b90423afd48ebfde4c059d9495ed
commit 8843120ded39b90423afd48ebfde4c059d9495ed
Merge: 9ab81c4 95d3ebc
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Fri May 12 13:12:24 2017 +0000
Commit:     Kitware Robot <kwrobot at kitware.com>
CommitDate: Fri May 12 09:12:29 2017 -0400

    Merge topic 'update-curl'
    
    95d3ebcc curl: Set TLS/SSL build options the way we need for CMake
    11ba72c6 curl: Skip building docs within CMake
    29997590 Merge branch 'upstream-curl' into update-curl
    fd7d521c curl 2017-04-19 (d957e218)
    5af9c8e2 curl: Update script to get curl 7.54.0
    
    Acked-by: Kitware Robot <kwrobot at kitware.com>
    Merge-request: !828


https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=9ab81c4a9b1ffde12663388975759bd757a4f825
commit 9ab81c4a9b1ffde12663388975759bd757a4f825
Merge: 91d987e e1e8f27
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Fri May 12 13:11:43 2017 +0000
Commit:     Kitware Robot <kwrobot at kitware.com>
CommitDate: Fri May 12 09:11:56 2017 -0400

    Merge topic 'lexerparser-fix-bootstrap'
    
    e1e8f27f bootstrap: fix Bad substitution
    
    Acked-by: Kitware Robot <kwrobot at kitware.com>
    Merge-request: !831


https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=e0e414d6593d952facb2ce2364d17b34afac8760
commit e0e414d6593d952facb2ce2364d17b34afac8760
Author:     Guillaume Dumont <dumont.guillaume at gmail.com>
AuthorDate: Thu May 4 14:51:39 2017 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Thu May 11 16:12:38 2017 -0400

    GetPrerequisites: Only recurse on resolved unseen prerequisites
    
    I encountered an issue where not all prerequisites would be listed by
    `get_prerequisites` since some of the prerequisites cannot be resolved
    and are added to the list of unseen prerequisites.  This has the side
    effect of clearing the list of `prerequisites_var` and thus removes some
    prerequisites from the list.  Fix it.

diff --git a/Modules/GetPrerequisites.cmake b/Modules/GetPrerequisites.cmake
index a3b97ab..0090cdc 100644
--- a/Modules/GetPrerequisites.cmake
+++ b/Modules/GetPrerequisites.cmake
@@ -943,7 +943,11 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa
         #
         if(NOT list_length_before_append EQUAL list_length_after_append)
           gp_resolve_item("${target}" "${item}" "${exepath}" "${dirs}" resolved_item "${rpaths}")
-          set(unseen_prereqs ${unseen_prereqs} "${resolved_item}")
+          if(EXISTS "${resolved_item}")
+            # Recurse only if we could resolve the item.
+            # Otherwise the prerequisites_var list will be cleared
+            set(unseen_prereqs ${unseen_prereqs} "${resolved_item}")
+          endif()
         endif()
       endif()
     endif()

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=5d13fe282255d828f7aaf7765a1b069839161ee8
commit 5d13fe282255d828f7aaf7765a1b069839161ee8
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Thu May 11 15:56:27 2017 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Thu May 11 15:59:48 2017 -0400

    Features: Record features for SunPro C 5.13 and 5.14

diff --git a/Modules/Compiler/SunPro-C-FeatureTests.cmake b/Modules/Compiler/SunPro-C-FeatureTests.cmake
new file mode 100644
index 0000000..cccf3ae
--- /dev/null
+++ b/Modules/Compiler/SunPro-C-FeatureTests.cmake
@@ -0,0 +1,14 @@
+set(_cmake_oldestSupported "__SUNPRO_C >= 0x5130")
+
+set(SunPro_C11 "${_cmake_oldestSupported} && defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L || __STDC_VERSION__ >= 199901L && defined(__C11FEATURES__))")
+set(_cmake_feature_test_c_static_assert "${SunPro_C11}")
+unset(SunPro_C11)
+
+set(SunPro_C99 "${_cmake_oldestSupported} && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L")
+set(_cmake_feature_test_c_restrict "${SunPro_C99}")
+set(_cmake_feature_test_c_variadic_macros "${SunPro_C99}")
+unset(SunPro_C99)
+
+set(SunPro_C90 "${_cmake_oldestSupported}")
+set(_cmake_feature_test_c_function_prototypes "${SunPro_C90}")
+unset(SunPro_C90)
diff --git a/Modules/Compiler/SunPro-C.cmake b/Modules/Compiler/SunPro-C.cmake
index 29c2f22..ac88e6f 100644
--- a/Modules/Compiler/SunPro-C.cmake
+++ b/Modules/Compiler/SunPro-C.cmake
@@ -43,5 +43,20 @@ endif()
 
 __compiler_check_default_language_standard(C 5.11 90 5.14 11)
 
+macro(cmake_record_c_compile_features)
+  set(_result 0)
+  if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 5.13)
+    if(_result EQUAL 0 AND CMAKE_C11_STANDARD_COMPILE_OPTION)
+      _record_compiler_features_c(11)
+    endif()
+    if (_result EQUAL 0)
+      _record_compiler_features_c(99)
+    endif()
+    if (_result EQUAL 0)
+      _record_compiler_features_c(90)
+    endif()
+  endif()
+endmacro()
+
 set(CMAKE_C_CREATE_PREPROCESSED_SOURCE "<CMAKE_C_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
 set(CMAKE_C_CREATE_ASSEMBLY_SOURCE "<CMAKE_C_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
diff --git a/Tests/CompileFeatures/CMakeLists.txt b/Tests/CompileFeatures/CMakeLists.txt
index 2a307d0..bb18543 100644
--- a/Tests/CompileFeatures/CMakeLists.txt
+++ b/Tests/CompileFeatures/CMakeLists.txt
@@ -239,6 +239,16 @@ if (CMAKE_C_COMPILE_FEATURES)
         EXPECT_C_STATIC_ASSERT=0
         )
     endif()
+  elseif (CMAKE_C_COMPILER_ID STREQUAL "SunPro")
+    if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 5.13)
+      list(APPEND expected_defs
+        EXPECT_C_STATIC_ASSERT=1
+        )
+    else()
+      list(APPEND expected_defs
+        EXPECT_C_STATIC_ASSERT=0
+        )
+    endif()
   endif()
 
   list(APPEND expected_defs
diff --git a/Tests/CompileFeatures/default_dialect.c b/Tests/CompileFeatures/default_dialect.c
index 0e67095..4debd94 100644
--- a/Tests/CompileFeatures/default_dialect.c
+++ b/Tests/CompileFeatures/default_dialect.c
@@ -11,7 +11,8 @@
 #if !DEFAULT_C90
 #error Buildsystem error
 #endif
-#if defined(__STDC_VERSION__)
+#if defined(__STDC_VERSION__) &&                                              \
+  !(defined(__SUNPRO_C) && __STDC_VERSION__ == 199409L)
 #error Unexpected __STDC_VERSION__ definition
 #endif
 #endif

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=e1e8f27ff284a59b8e57e802a6c159940367c51e
commit e1e8f27ff284a59b8e57e802a6c159940367c51e
Author:     Daniel Pfeifer <daniel at pfeifer-mail.de>
AuthorDate: Thu May 11 21:53:14 2017 +0200
Commit:     Daniel Pfeifer <daniel at pfeifer-mail.de>
CommitDate: Thu May 11 21:53:14 2017 +0200

    bootstrap: fix Bad substitution

diff --git a/bootstrap b/bootstrap
index 515e8be..876f53b 100755
--- a/bootstrap
+++ b/bootstrap
@@ -240,10 +240,6 @@ CMAKE_UNUSED_SOURCES="\
 "
 
 CMAKE_CXX_SOURCES="\
-  LexerParser/cmCommandArgumentLexer \
-  LexerParser/cmCommandArgumentParser \
-  LexerParser/cmExprLexer \
-  LexerParser/cmExprParser \
   cmAddCustomCommandCommand \
   cmAddCustomTargetCommand \
   cmAddDefinitionsCommand \
@@ -416,9 +412,16 @@ if ${cmake_system_mingw}; then
     cmGlobalMinGWMakefileGenerator"
 fi
 
-CMAKE_C_SOURCES="\
-  LexerParser/cmListFileLexer \
-  "
+LexerParser_CXX_SOURCES="\
+  cmCommandArgumentLexer \
+  cmCommandArgumentParser \
+  cmExprLexer \
+  cmExprParser \
+"
+
+LexerParser_C_SOURCES="\
+  cmListFileLexer \
+"
 
 if ${cmake_system_mingw}; then
   KWSYS_C_SOURCES="\
@@ -810,11 +813,6 @@ if [ ! -d "cmsys" ]; then
   cmake_error 4 "Cannot create directory ${cmake_bootstrap_dir}/cmsys"
 fi
 
-[ -d "LexerParser" ] || mkdir "LexerParser"
-if [ ! -d "LexerParser" ]; then
-  cmake_error 5 "Cannot create directory ${cmake_bootstrap_dir}/LexerParser"
-fi
-
 # Delete all the bootstrap files
 rm -f "${cmake_bootstrap_dir}/cmake_bootstrap.log"
 rm -f "${cmake_bootstrap_dir}/cmConfigure.h${_tmp}"
@@ -1347,6 +1345,8 @@ cmake_compiler_settings_comment="/*
  *
  * Sources:
  * ${CMAKE_CXX_SOURCES} ${CMAKE_C_SOURCES}
+ * LexerParser Sources:
+ * ${LexerParser_CXX_SOURCES} ${LexerParser_C_SOURCES}
  * kwSys Sources:
  * ${KWSYS_CXX_SOURCES} ${KWSYS_C_SOURCES}
  */
@@ -1408,7 +1408,7 @@ cmake_generate_file "${cmake_bootstrap_dir}/cmThirdParty.h" ""
 # Generate Makefile
 dep="cmConfigure.h cmsys/*.hxx cmsys/*.h `cmake_escape \"${cmake_source_dir}\"`/Source/*.h"
 objs=""
-for a in ${CMAKE_CXX_SOURCES} ${CMAKE_C_SOURCES} ${KWSYS_CXX_SOURCES} ${KWSYS_C_SOURCES}; do
+for a in ${CMAKE_CXX_SOURCES} ${CMAKE_C_SOURCES} ${LexerParser_CXX_SOURCES} ${LexerParser_C_SOURCES} ${KWSYS_CXX_SOURCES} ${KWSYS_C_SOURCES}; do
   objs="${objs} ${a}.o"
 done
 
@@ -1459,6 +1459,17 @@ for a in ${CMAKE_C_SOURCES}; do
   echo "${a}.o : ${src} ${dep}" >> "${cmake_bootstrap_dir}/Makefile"
   echo "	${cmake_c_compiler} ${cmake_c_flags} -c ${src} -o ${a}.o" >> "${cmake_bootstrap_dir}/Makefile"
 done
+for a in ${LexerParser_CXX_SOURCES}; do
+  src=`cmake_escape "${cmake_source_dir}/Source/LexerParser/${a}.cxx"`
+  src_flags=`eval echo \\${cmake_cxx_flags_\${a}}`
+  echo "${a}.o : ${src} ${dep}" >> "${cmake_bootstrap_dir}/Makefile"
+  echo "	${cmake_cxx_compiler} ${cmake_cxx_flags} ${src_flags} -c ${src} -o ${a}.o" >> "${cmake_bootstrap_dir}/Makefile"
+done
+for a in ${LexerParser_C_SOURCES}; do
+  src=`cmake_escape "${cmake_source_dir}/Source/LexerParser/${a}.c"`
+  echo "${a}.o : ${src} ${dep}" >> "${cmake_bootstrap_dir}/Makefile"
+  echo "	${cmake_c_compiler} ${cmake_c_flags} -c ${src} -o ${a}.o" >> "${cmake_bootstrap_dir}/Makefile"
+done
 for a in ${KWSYS_C_SOURCES}; do
   src=`cmake_escape "${cmake_source_dir}/Source/kwsys/${a}.c"`
   src_flags=`eval echo \\${cmake_c_flags_\${a}}`

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=a1218f59d9164407c6e28f816b0f11314b64fe5c
commit a1218f59d9164407c6e28f816b0f11314b64fe5c
Author:     Daniel Pfeifer <daniel at pfeifer-mail.de>
AuthorDate: Wed May 10 22:48:31 2017 +0200
Commit:     Daniel Pfeifer <daniel at pfeifer-mail.de>
CommitDate: Thu May 11 19:49:06 2017 +0200

    cmCommand: remove unused methods from interface and all implementations

diff --git a/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h b/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h
index bfd4061..503ed23 100644
--- a/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h
+++ b/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h
@@ -42,14 +42,6 @@ public:
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE
-  {
-    return "ctest_empty_binary_directory";
-  }
 };
 
 #endif
diff --git a/Source/CTest/cmCTestHandlerCommand.h b/Source/CTest/cmCTestHandlerCommand.h
index adc1687..0ea0612 100644
--- a/Source/CTest/cmCTestHandlerCommand.h
+++ b/Source/CTest/cmCTestHandlerCommand.h
@@ -25,6 +25,11 @@ public:
   cmCTestHandlerCommand();
 
   /**
+   * The name of the command as specified in CMakeList.txt.
+   */
+  virtual std::string GetName() const = 0;
+
+  /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
diff --git a/Source/CTest/cmCTestMemCheckCommand.cxx b/Source/CTest/cmCTestMemCheckCommand.cxx
index fd7c3a9..b9cae3b 100644
--- a/Source/CTest/cmCTestMemCheckCommand.cxx
+++ b/Source/CTest/cmCTestMemCheckCommand.cxx
@@ -3,6 +3,7 @@
 #include "cmCTestMemCheckCommand.h"
 
 #include <sstream>
+#include <string>
 #include <vector>
 
 #include "cmCTest.h"
diff --git a/Source/CTest/cmCTestMemCheckCommand.h b/Source/CTest/cmCTestMemCheckCommand.h
index fea65e8..fa59559 100644
--- a/Source/CTest/cmCTestMemCheckCommand.h
+++ b/Source/CTest/cmCTestMemCheckCommand.h
@@ -7,8 +7,6 @@
 
 #include "cmCTestTestCommand.h"
 
-#include <string>
-
 class cmCTestGenericHandler;
 class cmCommand;
 
@@ -33,11 +31,6 @@ public:
     return ni;
   }
 
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "ctest_memcheck"; }
-
 protected:
   cmCTestGenericHandler* InitializeActualHandler() CM_OVERRIDE;
 
diff --git a/Source/CTest/cmCTestReadCustomFilesCommand.h b/Source/CTest/cmCTestReadCustomFilesCommand.h
index 04024ab..5989fa0 100644
--- a/Source/CTest/cmCTestReadCustomFilesCommand.h
+++ b/Source/CTest/cmCTestReadCustomFilesCommand.h
@@ -40,11 +40,6 @@ public:
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "ctest_read_custom_files"; }
 };
 
 #endif
diff --git a/Source/CTest/cmCTestRunScriptCommand.h b/Source/CTest/cmCTestRunScriptCommand.h
index aac5114..9bd0965 100644
--- a/Source/CTest/cmCTestRunScriptCommand.h
+++ b/Source/CTest/cmCTestRunScriptCommand.h
@@ -41,11 +41,6 @@ public:
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "ctest_run_script"; }
 };
 
 #endif
diff --git a/Source/CTest/cmCTestSleepCommand.h b/Source/CTest/cmCTestSleepCommand.h
index a55e9d9..f0b5f1e 100644
--- a/Source/CTest/cmCTestSleepCommand.h
+++ b/Source/CTest/cmCTestSleepCommand.h
@@ -41,11 +41,6 @@ public:
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "ctest_sleep"; }
 };
 
 #endif
diff --git a/Source/CTest/cmCTestStartCommand.h b/Source/CTest/cmCTestStartCommand.h
index 26a63fb..b4943f9 100644
--- a/Source/CTest/cmCTestStartCommand.h
+++ b/Source/CTest/cmCTestStartCommand.h
@@ -54,11 +54,6 @@ public:
    */
   bool ShouldBeQuiet() { return this->Quiet; }
 
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "ctest_start"; }
-
 private:
   bool InitialCheckout(std::ostream& ofs, std::string const& sourceDir);
   bool CreateNewTag;
diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx
index e1b0967..da3ae2f 100644
--- a/Source/CTest/cmCTestTestHandler.cxx
+++ b/Source/CTest/cmCTestTestHandler.cxx
@@ -56,11 +56,6 @@ public:
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& /*unused*/) CM_OVERRIDE;
 
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "subdirs"; }
-
   cmCTestTestHandler* TestHandler;
 };
 
@@ -136,11 +131,6 @@ public:
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& /*unused*/) CM_OVERRIDE;
 
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "add_subdirectory"; }
-
   cmCTestTestHandler* TestHandler;
 };
 
@@ -206,11 +196,6 @@ public:
   bool InitialPass(std::vector<std::string> const& /*args*/,
                    cmExecutionStatus& /*unused*/) CM_OVERRIDE;
 
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "add_test"; }
-
   cmCTestTestHandler* TestHandler;
 };
 
@@ -244,11 +229,6 @@ public:
   bool InitialPass(std::vector<std::string> const& /*args*/,
                    cmExecutionStatus& /*unused*/) CM_OVERRIDE;
 
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "set_tests_properties"; }
-
   cmCTestTestHandler* TestHandler;
 };
 
diff --git a/Source/cmAddCompileOptionsCommand.h b/Source/cmAddCompileOptionsCommand.h
index 105d323..297f901 100644
--- a/Source/cmAddCompileOptionsCommand.h
+++ b/Source/cmAddCompileOptionsCommand.h
@@ -26,11 +26,6 @@ public:
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "add_compile_options"; }
 };
 
 #endif
diff --git a/Source/cmAddCustomCommandCommand.h b/Source/cmAddCustomCommandCommand.h
index 912a91a..c3a91b2 100644
--- a/Source/cmAddCustomCommandCommand.h
+++ b/Source/cmAddCustomCommandCommand.h
@@ -33,11 +33,6 @@ public:
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
 
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "add_custom_command"; }
-
 protected:
   bool CheckOutputs(const std::vector<std::string>& outputs);
 };
diff --git a/Source/cmAddCustomTargetCommand.h b/Source/cmAddCustomTargetCommand.h
index c449b10..7229c27 100644
--- a/Source/cmAddCustomTargetCommand.h
+++ b/Source/cmAddCustomTargetCommand.h
@@ -33,11 +33,6 @@ public:
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "add_custom_target"; }
 };
 
 #endif
diff --git a/Source/cmAddDefinitionsCommand.h b/Source/cmAddDefinitionsCommand.h
index de4bc1c..abf5a59 100644
--- a/Source/cmAddDefinitionsCommand.h
+++ b/Source/cmAddDefinitionsCommand.h
@@ -32,11 +32,6 @@ public:
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "add_definitions"; }
 };
 
 #endif
diff --git a/Source/cmAddDependenciesCommand.h b/Source/cmAddDependenciesCommand.h
index 88ac336..c7328d6 100644
--- a/Source/cmAddDependenciesCommand.h
+++ b/Source/cmAddDependenciesCommand.h
@@ -31,11 +31,6 @@ public:
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "add_dependencies"; }
 };
 
 #endif
diff --git a/Source/cmAddExecutableCommand.h b/Source/cmAddExecutableCommand.h
index 6531829..8100da1 100644
--- a/Source/cmAddExecutableCommand.h
+++ b/Source/cmAddExecutableCommand.h
@@ -32,11 +32,6 @@ public:
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "add_executable"; }
 };
 
 #endif
diff --git a/Source/cmAddLibraryCommand.h b/Source/cmAddLibraryCommand.h
index 977645e..df49fae 100644
--- a/Source/cmAddLibraryCommand.h
+++ b/Source/cmAddLibraryCommand.h
@@ -32,11 +32,6 @@ public:
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "add_library"; }
 };
 
 #endif
diff --git a/Source/cmAddSubDirectoryCommand.h b/Source/cmAddSubDirectoryCommand.h
index b19477a..0e71ffd 100644
--- a/Source/cmAddSubDirectoryCommand.h
+++ b/Source/cmAddSubDirectoryCommand.h
@@ -33,11 +33,6 @@ public:
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "add_subdirectory"; }
 };
 
 #endif
diff --git a/Source/cmAddTestCommand.h b/Source/cmAddTestCommand.h
index 1d6c4cc..a098a03 100644
--- a/Source/cmAddTestCommand.h
+++ b/Source/cmAddTestCommand.h
@@ -32,11 +32,6 @@ public:
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
 
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "add_test"; }
-
 private:
   bool HandleNameMode(std::vector<std::string> const& args);
 };
diff --git a/Source/cmAuxSourceDirectoryCommand.h b/Source/cmAuxSourceDirectoryCommand.h
index f8800a5..e49e861 100644
--- a/Source/cmAuxSourceDirectoryCommand.h
+++ b/Source/cmAuxSourceDirectoryCommand.h
@@ -35,11 +35,6 @@ public:
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "aux_source_directory"; }
 };
 
 #endif
diff --git a/Source/cmBreakCommand.h b/Source/cmBreakCommand.h
index 0038883..fcca45c 100644
--- a/Source/cmBreakCommand.h
+++ b/Source/cmBreakCommand.h
@@ -31,11 +31,6 @@ public:
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "break"; }
 };
 
 #endif
diff --git a/Source/cmBuildCommand.h b/Source/cmBuildCommand.h
index 7df54ec..1f357a9 100644
--- a/Source/cmBuildCommand.h
+++ b/Source/cmBuildCommand.h
@@ -42,11 +42,6 @@ public:
    */
   virtual bool TwoArgsSignature(std::vector<std::string> const& args);
 
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "build_command"; }
-
 private:
   bool IgnoreErrors() const;
 };
diff --git a/Source/cmBuildNameCommand.h b/Source/cmBuildNameCommand.h
index 9008c27..ff26c55 100644
--- a/Source/cmBuildNameCommand.h
+++ b/Source/cmBuildNameCommand.h
@@ -18,7 +18,6 @@ public:
   cmCommand* Clone() CM_OVERRIDE { return new cmBuildNameCommand; }
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-  std::string GetName() const CM_OVERRIDE { return "build_name"; }
 };
 
 #endif
diff --git a/Source/cmCMakeHostSystemInformationCommand.h b/Source/cmCMakeHostSystemInformationCommand.h
index 4263e75..ef6ca37 100644
--- a/Source/cmCMakeHostSystemInformationCommand.h
+++ b/Source/cmCMakeHostSystemInformationCommand.h
@@ -40,14 +40,6 @@ public:
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
 
-  /**
-  * The name of the command as specified in CMakeList.txt.
-  */
-  std::string GetName() const CM_OVERRIDE
-  {
-    return "cmake_host_system_information";
-  }
-
 private:
   bool GetValue(cmsys::SystemInformation& info, std::string const& key,
                 std::string& value);
diff --git a/Source/cmCMakeMinimumRequired.h b/Source/cmCMakeMinimumRequired.h
index d264675..45b6b78 100644
--- a/Source/cmCMakeMinimumRequired.h
+++ b/Source/cmCMakeMinimumRequired.h
@@ -32,11 +32,6 @@ public:
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
 
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "cmake_minimum_required"; }
-
 private:
   std::vector<std::string> UnknownArguments;
   bool EnforceUnknownArguments();
diff --git a/Source/cmCMakePolicyCommand.h b/Source/cmCMakePolicyCommand.h
index cc02169..0e88243 100644
--- a/Source/cmCMakePolicyCommand.h
+++ b/Source/cmCMakePolicyCommand.h
@@ -33,11 +33,6 @@ public:
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
 
-  /**
-    * The name of the command as specified in CMakeList.txt.
-    */
-  std::string GetName() const CM_OVERRIDE { return "cmake_policy"; }
-
 private:
   bool HandleSetMode(std::vector<std::string> const& args);
   bool HandleGetMode(std::vector<std::string> const& args);
diff --git a/Source/cmCommand.h b/Source/cmCommand.h
index 2e2ba43..ad72fe2 100644
--- a/Source/cmCommand.h
+++ b/Source/cmCommand.h
@@ -80,17 +80,6 @@ public:
   virtual cmCommand* Clone() = 0;
 
   /**
-   * This determines if the command is defined in a cmake script.
-   * It is the case for cmMacroHelperCommand and cmFunctionHelperCommand.
-   */
-  virtual bool IsUserDefined() const { return false; }
-
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  virtual std::string GetName() const = 0;
-
-  /**
    * Return the last error string.
    */
   const char* GetError();
diff --git a/Source/cmConfigureFileCommand.h b/Source/cmConfigureFileCommand.h
index 402423d..6cebbd2 100644
--- a/Source/cmConfigureFileCommand.h
+++ b/Source/cmConfigureFileCommand.h
@@ -25,11 +25,6 @@ public:
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
 
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "configure_file"; }
-
 private:
   int ConfigureFile();
 
diff --git a/Source/cmContinueCommand.h b/Source/cmContinueCommand.h
index 4b416a4..92bc68e 100644
--- a/Source/cmContinueCommand.h
+++ b/Source/cmContinueCommand.h
@@ -31,11 +31,6 @@ public:
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "continue"; }
 };
 
 #endif
diff --git a/Source/cmCreateTestSourceList.h b/Source/cmCreateTestSourceList.h
index 47391f3..f1f1e4b 100644
--- a/Source/cmCreateTestSourceList.h
+++ b/Source/cmCreateTestSourceList.h
@@ -31,11 +31,6 @@ public:
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "create_test_sourcelist"; }
 };
 
 #endif
diff --git a/Source/cmDefinePropertyCommand.h b/Source/cmDefinePropertyCommand.h
index 7a6e127..bc120c5 100644
--- a/Source/cmDefinePropertyCommand.h
+++ b/Source/cmDefinePropertyCommand.h
@@ -24,11 +24,6 @@ public:
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
 
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "define_property"; }
-
 private:
   std::string PropertyName;
   std::string BriefDocs;
diff --git a/Source/cmDisallowedCommand.h b/Source/cmDisallowedCommand.h
index 38d1d93..0030116 100644
--- a/Source/cmDisallowedCommand.h
+++ b/Source/cmDisallowedCommand.h
@@ -42,8 +42,6 @@ public:
     return this->Command->HasFinalPass();
   }
 
-  std::string GetName() const CM_OVERRIDE { return this->Command->GetName(); }
-
 private:
   cmCommand* Command;
   cmPolicies::PolicyID Policy;
diff --git a/Source/cmEnableLanguageCommand.h b/Source/cmEnableLanguageCommand.h
index 0748283..33c1c22 100644
--- a/Source/cmEnableLanguageCommand.h
+++ b/Source/cmEnableLanguageCommand.h
@@ -34,11 +34,6 @@ public:
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "enable_language"; }
 };
 
 #endif
diff --git a/Source/cmEnableTestingCommand.h b/Source/cmEnableTestingCommand.h
index b4ac068..e249662 100644
--- a/Source/cmEnableTestingCommand.h
+++ b/Source/cmEnableTestingCommand.h
@@ -39,11 +39,6 @@ public:
    */
   bool InitialPass(std::vector<std::string> const&,
                    cmExecutionStatus&) CM_OVERRIDE;
-
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "enable_testing"; }
 };
 
 #endif
diff --git a/Source/cmExecProgramCommand.h b/Source/cmExecProgramCommand.h
index 2a59612..6463c4d 100644
--- a/Source/cmExecProgramCommand.h
+++ b/Source/cmExecProgramCommand.h
@@ -36,11 +36,6 @@ public:
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
 
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "exec_program"; }
-
 private:
   static bool RunCommand(const char* command, std::string& output, int& retVal,
                          const char* directory = CM_NULLPTR,
diff --git a/Source/cmExecuteProcessCommand.h b/Source/cmExecuteProcessCommand.h
index e57e22d..08fde0a 100644
--- a/Source/cmExecuteProcessCommand.h
+++ b/Source/cmExecuteProcessCommand.h
@@ -32,11 +32,6 @@ public:
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "execute_process"; }
 };
 
 #endif
diff --git a/Source/cmExportCommand.h b/Source/cmExportCommand.h
index b95ea86..c47bc42 100644
--- a/Source/cmExportCommand.h
+++ b/Source/cmExportCommand.h
@@ -36,11 +36,6 @@ public:
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
 
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "export"; }
-
 private:
   cmCommandArgumentsHelper Helper;
   cmCommandArgumentGroup ArgumentGroup;
diff --git a/Source/cmExportLibraryDependenciesCommand.h b/Source/cmExportLibraryDependenciesCommand.h
index 4d3e36e..5559af9 100644
--- a/Source/cmExportLibraryDependenciesCommand.h
+++ b/Source/cmExportLibraryDependenciesCommand.h
@@ -21,10 +21,6 @@ public:
   }
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-  std::string GetName() const CM_OVERRIDE
-  {
-    return "export_library_dependencies";
-  }
 
   void FinalPass() CM_OVERRIDE;
   bool HasFinalPass() const CM_OVERRIDE { return true; }
diff --git a/Source/cmFLTKWrapUICommand.h b/Source/cmFLTKWrapUICommand.h
index 7dde9c1..d8045ab 100644
--- a/Source/cmFLTKWrapUICommand.h
+++ b/Source/cmFLTKWrapUICommand.h
@@ -43,11 +43,6 @@ public:
   void FinalPass() CM_OVERRIDE;
   bool HasFinalPass() const CM_OVERRIDE { return true; }
 
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "fltk_wrap_ui"; }
-
 private:
   /**
    * List of produced files.
diff --git a/Source/cmFileCommand.h b/Source/cmFileCommand.h
index ff0b35e..d09ef42 100644
--- a/Source/cmFileCommand.h
+++ b/Source/cmFileCommand.h
@@ -31,11 +31,6 @@ public:
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
 
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "file"; }
-
 protected:
   bool HandleRename(std::vector<std::string> const& args);
   bool HandleRemove(std::vector<std::string> const& args, bool recurse);
diff --git a/Source/cmFindFileCommand.h b/Source/cmFindFileCommand.h
index 489df65..bf57fec 100644
--- a/Source/cmFindFileCommand.h
+++ b/Source/cmFindFileCommand.h
@@ -5,8 +5,6 @@
 
 #include "cmConfigure.h"
 
-#include <string>
-
 #include "cmFindPathCommand.h"
 
 class cmCommand;
@@ -27,7 +25,6 @@ public:
    * This is a virtual constructor for the command.
    */
   cmCommand* Clone() CM_OVERRIDE { return new cmFindFileCommand; }
-  std::string GetName() const CM_OVERRIDE { return "find_file"; }
 };
 
 #endif
diff --git a/Source/cmFindLibraryCommand.h b/Source/cmFindLibraryCommand.h
index 41af976..9d38eab 100644
--- a/Source/cmFindLibraryCommand.h
+++ b/Source/cmFindLibraryCommand.h
@@ -36,11 +36,6 @@ public:
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
 
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "find_library"; }
-
 protected:
   void AddArchitecturePaths(const char* suffix);
   void AddArchitecturePath(std::string const& dir,
diff --git a/Source/cmFindPackageCommand.h b/Source/cmFindPackageCommand.h
index e4ecfad..318b1dc 100644
--- a/Source/cmFindPackageCommand.h
+++ b/Source/cmFindPackageCommand.h
@@ -60,11 +60,6 @@ public:
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
 
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "find_package"; }
-
 private:
   class PathLabel : public cmFindCommon::PathLabel
   {
diff --git a/Source/cmFindPathCommand.h b/Source/cmFindPathCommand.h
index 92849c3..3761145 100644
--- a/Source/cmFindPathCommand.h
+++ b/Source/cmFindPathCommand.h
@@ -36,11 +36,6 @@ public:
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
 
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "find_path"; }
-
   bool IncludeFileInPath;
 
 private:
diff --git a/Source/cmFindProgramCommand.h b/Source/cmFindProgramCommand.h
index af56aef..a0d6af9 100644
--- a/Source/cmFindProgramCommand.h
+++ b/Source/cmFindProgramCommand.h
@@ -37,11 +37,6 @@ public:
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
 
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "find_program"; }
-
 private:
   std::string FindProgram();
   std::string FindNormalProgram();
diff --git a/Source/cmForEachCommand.h b/Source/cmForEachCommand.h
index 30f0342..7c8a6d8 100644
--- a/Source/cmForEachCommand.h
+++ b/Source/cmForEachCommand.h
@@ -48,11 +48,6 @@ public:
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
 
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "foreach"; }
-
 private:
   bool HandleInMode(std::vector<std::string> const& args);
 };
diff --git a/Source/cmFunctionCommand.cxx b/Source/cmFunctionCommand.cxx
index 642b029..ee52bde 100644
--- a/Source/cmFunctionCommand.cxx
+++ b/Source/cmFunctionCommand.cxx
@@ -21,11 +21,6 @@ public:
   ~cmFunctionHelperCommand() CM_OVERRIDE {}
 
   /**
-   * This determines if the command is defined in a cmake script.
-   */
-  bool IsUserDefined() const CM_OVERRIDE { return true; }
-
-  /**
    * This is a virtual constructor for the command.
    */
   cmCommand* Clone() CM_OVERRIDE
@@ -52,11 +47,6 @@ public:
     return false;
   }
 
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return this->Args[0]; }
-
   std::vector<std::string> Args;
   std::vector<cmListFileFunction> Functions;
   cmPolicies::PolicyMap Policies;
diff --git a/Source/cmFunctionCommand.h b/Source/cmFunctionCommand.h
index fa13aa4..f263126 100644
--- a/Source/cmFunctionCommand.h
+++ b/Source/cmFunctionCommand.h
@@ -44,11 +44,6 @@ public:
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "function"; }
 };
 
 #endif
diff --git a/Source/cmGetCMakePropertyCommand.h b/Source/cmGetCMakePropertyCommand.h
index b0ddb22..9dfc40f 100644
--- a/Source/cmGetCMakePropertyCommand.h
+++ b/Source/cmGetCMakePropertyCommand.h
@@ -23,11 +23,6 @@ public:
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "get_cmake_property"; }
 };
 
 #endif
diff --git a/Source/cmGetDirectoryPropertyCommand.h b/Source/cmGetDirectoryPropertyCommand.h
index f91a466..7d97950 100644
--- a/Source/cmGetDirectoryPropertyCommand.h
+++ b/Source/cmGetDirectoryPropertyCommand.h
@@ -24,11 +24,6 @@ public:
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
 
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "get_directory_property"; }
-
 private:
   void StoreResult(const std::string& variable, const char* prop);
 };
diff --git a/Source/cmGetFilenameComponentCommand.h b/Source/cmGetFilenameComponentCommand.h
index cf64564..c8a23c7 100644
--- a/Source/cmGetFilenameComponentCommand.h
+++ b/Source/cmGetFilenameComponentCommand.h
@@ -32,11 +32,6 @@ public:
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "get_filename_component"; }
 };
 
 #endif
diff --git a/Source/cmGetPropertyCommand.h b/Source/cmGetPropertyCommand.h
index 7bbcec0..6497801 100644
--- a/Source/cmGetPropertyCommand.h
+++ b/Source/cmGetPropertyCommand.h
@@ -26,11 +26,6 @@ public:
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
 
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "get_property"; }
-
 private:
   enum OutType
   {
diff --git a/Source/cmGetSourceFilePropertyCommand.h b/Source/cmGetSourceFilePropertyCommand.h
index 558e2ab..e96bb29 100644
--- a/Source/cmGetSourceFilePropertyCommand.h
+++ b/Source/cmGetSourceFilePropertyCommand.h
@@ -23,14 +23,6 @@ public:
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE
-  {
-    return "get_source_file_property";
-  }
 };
 
 #endif
diff --git a/Source/cmGetTargetPropertyCommand.h b/Source/cmGetTargetPropertyCommand.h
index 9cebb3b..5de3225 100644
--- a/Source/cmGetTargetPropertyCommand.h
+++ b/Source/cmGetTargetPropertyCommand.h
@@ -23,11 +23,6 @@ public:
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "get_target_property"; }
 };
 
 #endif
diff --git a/Source/cmGetTestPropertyCommand.h b/Source/cmGetTestPropertyCommand.h
index d3d10cb..b17e7a1 100644
--- a/Source/cmGetTestPropertyCommand.h
+++ b/Source/cmGetTestPropertyCommand.h
@@ -23,11 +23,6 @@ public:
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "get_test_property"; }
 };
 
 #endif
diff --git a/Source/cmIfCommand.h b/Source/cmIfCommand.h
index c6c44cb..5877a7d 100644
--- a/Source/cmIfCommand.h
+++ b/Source/cmIfCommand.h
@@ -64,11 +64,6 @@ public:
     return false;
   }
 
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "if"; }
-
   // Filter the given variable definition based on policy CMP0054.
   static const char* GetDefinitionIfUnquoted(
     const cmMakefile* mf, cmExpandedCommandArgument const& argument);
diff --git a/Source/cmIncludeCommand.h b/Source/cmIncludeCommand.h
index 5a37800..16dda0e 100644
--- a/Source/cmIncludeCommand.h
+++ b/Source/cmIncludeCommand.h
@@ -32,11 +32,6 @@ public:
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "include"; }
 };
 
 #endif
diff --git a/Source/cmIncludeDirectoryCommand.h b/Source/cmIncludeDirectoryCommand.h
index abe0c05..12de698 100644
--- a/Source/cmIncludeDirectoryCommand.h
+++ b/Source/cmIncludeDirectoryCommand.h
@@ -33,11 +33,6 @@ public:
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
 
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "include_directories"; }
-
 protected:
   // used internally
   void GetIncludes(const std::string& arg, std::vector<std::string>& incs);
diff --git a/Source/cmIncludeExternalMSProjectCommand.h b/Source/cmIncludeExternalMSProjectCommand.h
index 5274f9e..375646f 100644
--- a/Source/cmIncludeExternalMSProjectCommand.h
+++ b/Source/cmIncludeExternalMSProjectCommand.h
@@ -36,14 +36,6 @@ public:
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE
-  {
-    return "include_external_msproject";
-  }
 };
 
 #endif
diff --git a/Source/cmIncludeRegularExpressionCommand.h b/Source/cmIncludeRegularExpressionCommand.h
index a003360..bac4b8f 100644
--- a/Source/cmIncludeRegularExpressionCommand.h
+++ b/Source/cmIncludeRegularExpressionCommand.h
@@ -35,14 +35,6 @@ public:
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE
-  {
-    return "include_regular_expression";
-  }
 };
 
 #endif
diff --git a/Source/cmInstallCommand.h b/Source/cmInstallCommand.h
index fde629b..f5d1f92 100644
--- a/Source/cmInstallCommand.h
+++ b/Source/cmInstallCommand.h
@@ -33,11 +33,6 @@ public:
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
 
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "install"; }
-
 private:
   bool HandleScriptMode(std::vector<std::string> const& args);
   bool HandleTargetsMode(std::vector<std::string> const& args);
diff --git a/Source/cmInstallFilesCommand.h b/Source/cmInstallFilesCommand.h
index 588c289..b3c27b8 100644
--- a/Source/cmInstallFilesCommand.h
+++ b/Source/cmInstallFilesCommand.h
@@ -34,11 +34,6 @@ public:
                    cmExecutionStatus& status) CM_OVERRIDE;
 
   /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "install_files"; }
-
-  /**
    * This is called at the end after all the information
    * specified by the command is accumulated. Most commands do
    * not implement this method.  At this point, reading and
diff --git a/Source/cmInstallProgramsCommand.h b/Source/cmInstallProgramsCommand.h
index 2381d79..242fb95 100644
--- a/Source/cmInstallProgramsCommand.h
+++ b/Source/cmInstallProgramsCommand.h
@@ -34,11 +34,6 @@ public:
                    cmExecutionStatus& status) CM_OVERRIDE;
 
   /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "install_programs"; }
-
-  /**
    * This is called at the end after all the information
    * specified by the command is accumulated. Most commands do
    * not implement this method.  At this point, reading and
diff --git a/Source/cmInstallTargetsCommand.h b/Source/cmInstallTargetsCommand.h
index 77f461a..cc84843 100644
--- a/Source/cmInstallTargetsCommand.h
+++ b/Source/cmInstallTargetsCommand.h
@@ -33,11 +33,6 @@ public:
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "install_targets"; }
 };
 
 #endif
diff --git a/Source/cmLinkDirectoriesCommand.h b/Source/cmLinkDirectoriesCommand.h
index 334b1b8..b64e48d 100644
--- a/Source/cmLinkDirectoriesCommand.h
+++ b/Source/cmLinkDirectoriesCommand.h
@@ -35,11 +35,6 @@ public:
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
 
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "link_directories"; }
-
 private:
   void AddLinkDir(std::string const& dir);
 };
diff --git a/Source/cmLinkLibrariesCommand.h b/Source/cmLinkLibrariesCommand.h
index 430e5a8..f1b3a68 100644
--- a/Source/cmLinkLibrariesCommand.h
+++ b/Source/cmLinkLibrariesCommand.h
@@ -33,11 +33,6 @@ public:
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "link_libraries"; }
 };
 
 #endif
diff --git a/Source/cmListCommand.h b/Source/cmListCommand.h
index 7272ea1..7789f7d 100644
--- a/Source/cmListCommand.h
+++ b/Source/cmListCommand.h
@@ -31,11 +31,6 @@ public:
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
 
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "list"; }
-
 protected:
   bool HandleLengthCommand(std::vector<std::string> const& args);
   bool HandleGetCommand(std::vector<std::string> const& args);
diff --git a/Source/cmLoadCacheCommand.h b/Source/cmLoadCacheCommand.h
index 8dee973..1a8a0fc 100644
--- a/Source/cmLoadCacheCommand.h
+++ b/Source/cmLoadCacheCommand.h
@@ -33,11 +33,6 @@ public:
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
 
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "load_cache"; }
-
 protected:
   std::set<std::string> VariablesToRead;
   std::string Prefix;
diff --git a/Source/cmLoadCommandCommand.cxx b/Source/cmLoadCommandCommand.cxx
index 8bd212c..92a32a1 100644
--- a/Source/cmLoadCommandCommand.cxx
+++ b/Source/cmLoadCommandCommand.cxx
@@ -66,11 +66,6 @@ public:
     return this->info.FinalPass != CM_NULLPTR;
   }
 
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return info.Name; }
-
   static const char* LastName;
   static void TrapsForSignals(int sig)
   {
diff --git a/Source/cmLoadCommandCommand.h b/Source/cmLoadCommandCommand.h
index 97a6bd7..030786e 100644
--- a/Source/cmLoadCommandCommand.h
+++ b/Source/cmLoadCommandCommand.h
@@ -18,7 +18,6 @@ public:
   cmCommand* Clone() CM_OVERRIDE { return new cmLoadCommandCommand; }
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-  std::string GetName() const CM_OVERRIDE { return "load_command"; }
 };
 
 #endif
diff --git a/Source/cmMacroCommand.cxx b/Source/cmMacroCommand.cxx
index f386a22..a6a9ea3 100644
--- a/Source/cmMacroCommand.cxx
+++ b/Source/cmMacroCommand.cxx
@@ -22,11 +22,6 @@ public:
   ~cmMacroHelperCommand() CM_OVERRIDE {}
 
   /**
-   * This determines if the command is defined in a cmake script.
-   */
-  bool IsUserDefined() const CM_OVERRIDE { return true; }
-
-  /**
    * This is a virtual constructor for the command.
    */
   cmCommand* Clone() CM_OVERRIDE
@@ -53,11 +48,6 @@ public:
     return false;
   }
 
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return this->Args[0]; }
-
   std::vector<std::string> Args;
   std::vector<cmListFileFunction> Functions;
   cmPolicies::PolicyMap Policies;
diff --git a/Source/cmMacroCommand.h b/Source/cmMacroCommand.h
index fd9c92b..0d35fe0 100644
--- a/Source/cmMacroCommand.h
+++ b/Source/cmMacroCommand.h
@@ -44,11 +44,6 @@ public:
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "macro"; }
 };
 
 #endif
diff --git a/Source/cmMakeDirectoryCommand.h b/Source/cmMakeDirectoryCommand.h
index e2f0932..af72eab 100644
--- a/Source/cmMakeDirectoryCommand.h
+++ b/Source/cmMakeDirectoryCommand.h
@@ -35,11 +35,6 @@ public:
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "make_directory"; }
 };
 
 #endif
diff --git a/Source/cmMarkAsAdvancedCommand.h b/Source/cmMarkAsAdvancedCommand.h
index 4f80746..a7791a9 100644
--- a/Source/cmMarkAsAdvancedCommand.h
+++ b/Source/cmMarkAsAdvancedCommand.h
@@ -31,11 +31,6 @@ public:
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "mark_as_advanced"; }
 };
 
 #endif
diff --git a/Source/cmMathCommand.h b/Source/cmMathCommand.h
index ef0eb4a..67dbdda 100644
--- a/Source/cmMathCommand.h
+++ b/Source/cmMathCommand.h
@@ -28,11 +28,6 @@ public:
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
 
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "math"; }
-
 protected:
   bool HandleExprCommand(std::vector<std::string> const& args);
 };
diff --git a/Source/cmMessageCommand.h b/Source/cmMessageCommand.h
index fd2dbe7..96939e5 100644
--- a/Source/cmMessageCommand.h
+++ b/Source/cmMessageCommand.h
@@ -30,11 +30,6 @@ public:
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "message"; }
 };
 
 #endif
diff --git a/Source/cmOptionCommand.h b/Source/cmOptionCommand.h
index 0227357..634e3a8 100644
--- a/Source/cmOptionCommand.h
+++ b/Source/cmOptionCommand.h
@@ -31,11 +31,6 @@ public:
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "option"; }
 };
 
 #endif
diff --git a/Source/cmOutputRequiredFilesCommand.h b/Source/cmOutputRequiredFilesCommand.h
index e261eb0..d20bfbd 100644
--- a/Source/cmOutputRequiredFilesCommand.h
+++ b/Source/cmOutputRequiredFilesCommand.h
@@ -21,7 +21,6 @@ public:
   cmCommand* Clone() CM_OVERRIDE { return new cmOutputRequiredFilesCommand; }
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-  std::string GetName() const CM_OVERRIDE { return "output_required_files"; }
 
   void ListDependencies(cmDependInformation const* info, FILE* fout,
                         std::set<cmDependInformation const*>* visited);
diff --git a/Source/cmParseArgumentsCommand.h b/Source/cmParseArgumentsCommand.h
index f3de5b6..359fb85 100644
--- a/Source/cmParseArgumentsCommand.h
+++ b/Source/cmParseArgumentsCommand.h
@@ -29,11 +29,6 @@ public:
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "cmake_parse_arguments"; }
 };
 
 #endif
diff --git a/Source/cmProjectCommand.h b/Source/cmProjectCommand.h
index 8fc90d2..3c579ac 100644
--- a/Source/cmProjectCommand.h
+++ b/Source/cmProjectCommand.h
@@ -34,11 +34,6 @@ public:
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "project"; }
 };
 
 #endif
diff --git a/Source/cmQTWrapCPPCommand.h b/Source/cmQTWrapCPPCommand.h
index 34adf29..ad1ccf3 100644
--- a/Source/cmQTWrapCPPCommand.h
+++ b/Source/cmQTWrapCPPCommand.h
@@ -32,11 +32,6 @@ public:
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "qt_wrap_cpp"; }
 };
 
 #endif
diff --git a/Source/cmQTWrapUICommand.h b/Source/cmQTWrapUICommand.h
index 279d4e9..ac7ab01 100644
--- a/Source/cmQTWrapUICommand.h
+++ b/Source/cmQTWrapUICommand.h
@@ -31,11 +31,6 @@ public:
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "qt_wrap_ui"; }
 };
 
 #endif
diff --git a/Source/cmRemoveCommand.h b/Source/cmRemoveCommand.h
index 84e591d..f2e89f6 100644
--- a/Source/cmRemoveCommand.h
+++ b/Source/cmRemoveCommand.h
@@ -31,11 +31,6 @@ public:
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "remove"; }
 };
 
 #endif
diff --git a/Source/cmRemoveDefinitionsCommand.h b/Source/cmRemoveDefinitionsCommand.h
index 2f6c924..9a9a5d5 100644
--- a/Source/cmRemoveDefinitionsCommand.h
+++ b/Source/cmRemoveDefinitionsCommand.h
@@ -33,11 +33,6 @@ public:
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "remove_definitions"; }
 };
 
 #endif
diff --git a/Source/cmReturnCommand.h b/Source/cmReturnCommand.h
index a4a6283..87900e7 100644
--- a/Source/cmReturnCommand.h
+++ b/Source/cmReturnCommand.h
@@ -31,11 +31,6 @@ public:
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "return"; }
 };
 
 #endif
diff --git a/Source/cmSeparateArgumentsCommand.h b/Source/cmSeparateArgumentsCommand.h
index e4df5da..6bf8549 100644
--- a/Source/cmSeparateArgumentsCommand.h
+++ b/Source/cmSeparateArgumentsCommand.h
@@ -31,11 +31,6 @@ public:
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "separate_arguments"; }
 };
 
 #endif
diff --git a/Source/cmSetCommand.h b/Source/cmSetCommand.h
index e3a3175..c0858b1 100644
--- a/Source/cmSetCommand.h
+++ b/Source/cmSetCommand.h
@@ -31,11 +31,6 @@ public:
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "set"; }
 };
 
 #endif
diff --git a/Source/cmSetDirectoryPropertiesCommand.h b/Source/cmSetDirectoryPropertiesCommand.h
index 4657b66..8832b33 100644
--- a/Source/cmSetDirectoryPropertiesCommand.h
+++ b/Source/cmSetDirectoryPropertiesCommand.h
@@ -29,14 +29,6 @@ public:
                    cmExecutionStatus& status) CM_OVERRIDE;
 
   /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE
-  {
-    return "set_directory_properties";
-  }
-
-  /**
    * Static entry point for use by other commands
    */
   static bool RunCommand(cmMakefile* mf,
diff --git a/Source/cmSetPropertyCommand.h b/Source/cmSetPropertyCommand.h
index 7f5c977..0815824 100644
--- a/Source/cmSetPropertyCommand.h
+++ b/Source/cmSetPropertyCommand.h
@@ -31,11 +31,6 @@ public:
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
 
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "set_property"; }
-
 private:
   std::set<std::string> Names;
   std::string PropertyName;
diff --git a/Source/cmSetSourceFilesPropertiesCommand.h b/Source/cmSetSourceFilesPropertiesCommand.h
index 7dce437..2e22dc9 100644
--- a/Source/cmSetSourceFilesPropertiesCommand.h
+++ b/Source/cmSetSourceFilesPropertiesCommand.h
@@ -28,14 +28,6 @@ public:
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
 
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE
-  {
-    return "set_source_files_properties";
-  }
-
   static bool RunCommand(cmMakefile* mf,
                          std::vector<std::string>::const_iterator filebeg,
                          std::vector<std::string>::const_iterator fileend,
diff --git a/Source/cmSetTargetPropertiesCommand.h b/Source/cmSetTargetPropertiesCommand.h
index bb34d1e..4256181 100644
--- a/Source/cmSetTargetPropertiesCommand.h
+++ b/Source/cmSetTargetPropertiesCommand.h
@@ -26,11 +26,6 @@ public:
                    cmExecutionStatus& status) CM_OVERRIDE;
 
   /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "set_target_properties"; }
-
-  /**
    *  Used by this command and cmSetPropertiesCommand
    */
   static bool SetOneTarget(const std::string& tname,
diff --git a/Source/cmSetTestsPropertiesCommand.h b/Source/cmSetTestsPropertiesCommand.h
index 56a864f..90f004c 100644
--- a/Source/cmSetTestsPropertiesCommand.h
+++ b/Source/cmSetTestsPropertiesCommand.h
@@ -25,11 +25,6 @@ public:
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
 
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "set_tests_properties"; }
-
   static bool SetOneTest(const std::string& tname,
                          std::vector<std::string>& propertyPairs,
                          cmMakefile* mf, std::string& errors);
diff --git a/Source/cmSiteNameCommand.h b/Source/cmSiteNameCommand.h
index e133c6c..6c65480 100644
--- a/Source/cmSiteNameCommand.h
+++ b/Source/cmSiteNameCommand.h
@@ -31,11 +31,6 @@ public:
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "site_name"; }
 };
 
 #endif
diff --git a/Source/cmSourceGroupCommand.h b/Source/cmSourceGroupCommand.h
index 3086177..7d56b0d 100644
--- a/Source/cmSourceGroupCommand.h
+++ b/Source/cmSourceGroupCommand.h
@@ -33,11 +33,6 @@ public:
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
 
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "source_group"; }
-
 private:
   bool processTree(const std::vector<std::string>& args,
                    std::string& errorMsg);
diff --git a/Source/cmState.cxx b/Source/cmState.cxx
index 11ad6c0..ce9f470 100644
--- a/Source/cmState.cxx
+++ b/Source/cmState.cxx
@@ -381,7 +381,6 @@ void cmState::SetIsGeneratorMultiConfig(bool b)
 void cmState::AddBuiltinCommand(std::string const& name, cmCommand* command)
 {
   assert(name == cmSystemTools::LowerCase(name));
-  assert(name == cmSystemTools::LowerCase(command->GetName()));
   assert(this->BuiltinCommands.find(name) == this->BuiltinCommands.end());
   this->BuiltinCommands.insert(std::make_pair(name, command));
 }
diff --git a/Source/cmStringCommand.h b/Source/cmStringCommand.h
index dc3ce5a..88015ad 100644
--- a/Source/cmStringCommand.h
+++ b/Source/cmStringCommand.h
@@ -31,11 +31,6 @@ public:
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
 
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "string"; }
-
 protected:
   bool HandleConfigureCommand(std::vector<std::string> const& args);
   bool HandleAsciiCommand(std::vector<std::string> const& args);
diff --git a/Source/cmSubdirCommand.h b/Source/cmSubdirCommand.h
index ce2168d..a2af0fd 100644
--- a/Source/cmSubdirCommand.h
+++ b/Source/cmSubdirCommand.h
@@ -33,11 +33,6 @@ public:
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "subdirs"; }
 };
 
 #endif
diff --git a/Source/cmSubdirDependsCommand.h b/Source/cmSubdirDependsCommand.h
index ae8fbaf..d8ea928 100644
--- a/Source/cmSubdirDependsCommand.h
+++ b/Source/cmSubdirDependsCommand.h
@@ -18,7 +18,6 @@ public:
   cmCommand* Clone() CM_OVERRIDE { return new cmSubdirDependsCommand; }
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-  std::string GetName() const CM_OVERRIDE { return "subdir_depends"; }
 };
 
 #endif
diff --git a/Source/cmTargetCompileDefinitionsCommand.h b/Source/cmTargetCompileDefinitionsCommand.h
index 663b9d0..11abf57 100644
--- a/Source/cmTargetCompileDefinitionsCommand.h
+++ b/Source/cmTargetCompileDefinitionsCommand.h
@@ -32,14 +32,6 @@ public:
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
 
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE
-  {
-    return "target_compile_definitions";
-  }
-
 private:
   void HandleImportedTarget(const std::string& tgt) CM_OVERRIDE;
   void HandleMissingTarget(const std::string& name) CM_OVERRIDE;
diff --git a/Source/cmTargetCompileFeaturesCommand.h b/Source/cmTargetCompileFeaturesCommand.h
index 95214bf..9908680 100644
--- a/Source/cmTargetCompileFeaturesCommand.h
+++ b/Source/cmTargetCompileFeaturesCommand.h
@@ -21,8 +21,6 @@ class cmTargetCompileFeaturesCommand : public cmTargetPropCommandBase
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
 
-  std::string GetName() const CM_OVERRIDE { return "target_compile_features"; }
-
 private:
   void HandleImportedTarget(const std::string& tgt) CM_OVERRIDE;
   void HandleMissingTarget(const std::string& name) CM_OVERRIDE;
diff --git a/Source/cmTargetCompileOptionsCommand.h b/Source/cmTargetCompileOptionsCommand.h
index e4dfa75..b5408f7 100644
--- a/Source/cmTargetCompileOptionsCommand.h
+++ b/Source/cmTargetCompileOptionsCommand.h
@@ -29,11 +29,6 @@ public:
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
 
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "target_compile_options"; }
-
 private:
   void HandleImportedTarget(const std::string& tgt) CM_OVERRIDE;
   void HandleMissingTarget(const std::string& name) CM_OVERRIDE;
diff --git a/Source/cmTargetIncludeDirectoriesCommand.h b/Source/cmTargetIncludeDirectoriesCommand.h
index d6d33f2..374a867 100644
--- a/Source/cmTargetIncludeDirectoriesCommand.h
+++ b/Source/cmTargetIncludeDirectoriesCommand.h
@@ -32,14 +32,6 @@ public:
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
 
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE
-  {
-    return "target_include_directories";
-  }
-
 private:
   void HandleImportedTarget(const std::string& tgt) CM_OVERRIDE;
   void HandleMissingTarget(const std::string& name) CM_OVERRIDE;
diff --git a/Source/cmTargetLinkLibrariesCommand.h b/Source/cmTargetLinkLibrariesCommand.h
index bfa233e..3fd20ac 100644
--- a/Source/cmTargetLinkLibrariesCommand.h
+++ b/Source/cmTargetLinkLibrariesCommand.h
@@ -36,11 +36,6 @@ public:
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
 
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "target_link_libraries"; }
-
 private:
   void LinkLibraryTypeSpecifierWarning(int left, int right);
   static const char* LinkLibraryTypeNames[3];
diff --git a/Source/cmTargetSourcesCommand.h b/Source/cmTargetSourcesCommand.h
index 6cc1abc..09ba729 100644
--- a/Source/cmTargetSourcesCommand.h
+++ b/Source/cmTargetSourcesCommand.h
@@ -29,11 +29,6 @@ public:
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
 
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "target_sources"; }
-
 private:
   void HandleImportedTarget(const std::string& tgt) CM_OVERRIDE;
   void HandleMissingTarget(const std::string& name) CM_OVERRIDE;
diff --git a/Source/cmTryCompileCommand.h b/Source/cmTryCompileCommand.h
index 8972f7e..4836548 100644
--- a/Source/cmTryCompileCommand.h
+++ b/Source/cmTryCompileCommand.h
@@ -32,11 +32,6 @@ public:
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "try_compile"; }
 };
 
 #endif
diff --git a/Source/cmTryRunCommand.h b/Source/cmTryRunCommand.h
index b086dde..c27b026 100644
--- a/Source/cmTryRunCommand.h
+++ b/Source/cmTryRunCommand.h
@@ -33,11 +33,6 @@ public:
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
 
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "try_run"; }
-
 private:
   void RunExecutable(const std::string& runArgs,
                      std::string* runOutputContents);
diff --git a/Source/cmUnexpectedCommand.h b/Source/cmUnexpectedCommand.h
index 1605997..995d8a5 100644
--- a/Source/cmUnexpectedCommand.h
+++ b/Source/cmUnexpectedCommand.h
@@ -29,8 +29,6 @@ public:
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
 
-  std::string GetName() const CM_OVERRIDE { return this->Name; }
-
 private:
   std::string Name;
   const char* Error;
diff --git a/Source/cmUnsetCommand.h b/Source/cmUnsetCommand.h
index d60bd3e..2a1f3f0 100644
--- a/Source/cmUnsetCommand.h
+++ b/Source/cmUnsetCommand.h
@@ -31,11 +31,6 @@ public:
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "unset"; }
 };
 
 #endif
diff --git a/Source/cmUseMangledMesaCommand.h b/Source/cmUseMangledMesaCommand.h
index 104614a..5118829 100644
--- a/Source/cmUseMangledMesaCommand.h
+++ b/Source/cmUseMangledMesaCommand.h
@@ -18,7 +18,7 @@ public:
   cmCommand* Clone() CM_OVERRIDE { return new cmUseMangledMesaCommand; }
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-  std::string GetName() const CM_OVERRIDE { return "use_mangled_mesa"; }
+
 protected:
   void CopyAndFullPathMesaHeader(const char* source, const char* outdir);
 };
diff --git a/Source/cmUtilitySourceCommand.h b/Source/cmUtilitySourceCommand.h
index fa818bf..a95b48d 100644
--- a/Source/cmUtilitySourceCommand.h
+++ b/Source/cmUtilitySourceCommand.h
@@ -18,7 +18,6 @@ public:
   cmCommand* Clone() CM_OVERRIDE { return new cmUtilitySourceCommand; }
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-  std::string GetName() const CM_OVERRIDE { return "utility_source"; }
 };
 
 #endif
diff --git a/Source/cmVariableRequiresCommand.h b/Source/cmVariableRequiresCommand.h
index 6afb11a..9808d5f 100644
--- a/Source/cmVariableRequiresCommand.h
+++ b/Source/cmVariableRequiresCommand.h
@@ -18,7 +18,6 @@ public:
   cmCommand* Clone() CM_OVERRIDE { return new cmVariableRequiresCommand; }
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-  std::string GetName() const CM_OVERRIDE { return "variable_requires"; }
 };
 
 #endif
diff --git a/Source/cmVariableWatchCommand.h b/Source/cmVariableWatchCommand.h
index ca338e6..9f04391 100644
--- a/Source/cmVariableWatchCommand.h
+++ b/Source/cmVariableWatchCommand.h
@@ -42,11 +42,6 @@ public:
       stay alive since it owns variable watch callback information. */
   bool HasFinalPass() const CM_OVERRIDE { return true; }
 
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "variable_watch"; }
-
 protected:
   std::set<std::string> WatchedVariables;
 };
diff --git a/Source/cmWhileCommand.h b/Source/cmWhileCommand.h
index d353063..a95e4c3 100644
--- a/Source/cmWhileCommand.h
+++ b/Source/cmWhileCommand.h
@@ -57,11 +57,6 @@ public:
   {
     return false;
   }
-
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "while"; }
 };
 
 #endif
diff --git a/Source/cmWriteFileCommand.h b/Source/cmWriteFileCommand.h
index aea8653..19922cd 100644
--- a/Source/cmWriteFileCommand.h
+++ b/Source/cmWriteFileCommand.h
@@ -30,11 +30,6 @@ public:
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) CM_OVERRIDE;
-
-  /**
-   * The name of the command as specified in CMakeList.txt.
-   */
-  std::string GetName() const CM_OVERRIDE { return "write_file"; }
 };
 
 #endif

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=4ba25a823e62271a74dfd1845f535400e2da125b
commit 4ba25a823e62271a74dfd1845f535400e2da125b
Author:     Daniel Pfeifer <daniel at pfeifer-mail.de>
AuthorDate: Wed May 10 22:08:05 2017 +0200
Commit:     Daniel Pfeifer <daniel at pfeifer-mail.de>
CommitDate: Thu May 11 19:49:06 2017 +0200

    cmState: separate builtin and scripted commands

diff --git a/Source/cmState.cxx b/Source/cmState.cxx
index 6de4c9f..11ad6c0 100644
--- a/Source/cmState.cxx
+++ b/Source/cmState.cxx
@@ -36,7 +36,8 @@ cmState::cmState()
 cmState::~cmState()
 {
   delete this->CacheManager;
-  cmDeleteAll(this->Commands);
+  cmDeleteAll(this->BuiltinCommands);
+  cmDeleteAll(this->ScriptedCommands);
 }
 
 const char* cmState::GetTargetTypeName(cmStateEnums::TargetType targetType)
@@ -377,47 +378,12 @@ void cmState::SetIsGeneratorMultiConfig(bool b)
   this->IsGeneratorMultiConfig = b;
 }
 
-void cmState::RenameCommand(std::string const& oldName,
-                            std::string const& newName)
-{
-  // if the command already exists, free the old one
-  std::string sOldName = cmSystemTools::LowerCase(oldName);
-  std::string sNewName = cmSystemTools::LowerCase(newName);
-  std::map<std::string, cmCommand*>::iterator pos =
-    this->Commands.find(sOldName);
-  if (pos == this->Commands.end()) {
-    return;
-  }
-  cmCommand* cmd = pos->second;
-
-  pos = this->Commands.find(sNewName);
-  if (pos != this->Commands.end()) {
-    delete pos->second;
-    this->Commands.erase(pos);
-  }
-  this->Commands.insert(std::make_pair(sNewName, cmd));
-  pos = this->Commands.find(sOldName);
-  this->Commands.erase(pos);
-}
-
-void cmState::AddCommand(cmCommand* command)
-{
-  std::string name = cmSystemTools::LowerCase(command->GetName());
-  // if the command already exists, free the old one
-  std::map<std::string, cmCommand*>::iterator pos = this->Commands.find(name);
-  if (pos != this->Commands.end()) {
-    delete pos->second;
-    this->Commands.erase(pos);
-  }
-  this->Commands.insert(std::make_pair(name, command));
-}
-
 void cmState::AddBuiltinCommand(std::string const& name, cmCommand* command)
 {
   assert(name == cmSystemTools::LowerCase(name));
   assert(name == cmSystemTools::LowerCase(command->GetName()));
-  assert(this->Commands.find(name) == this->Commands.end());
-  this->Commands.insert(std::make_pair(name, command));
+  assert(this->BuiltinCommands.find(name) == this->BuiltinCommands.end());
+  this->BuiltinCommands.insert(std::make_pair(name, command));
 }
 
 void cmState::AddDisallowedCommand(std::string const& name, cmCommand* command,
@@ -435,53 +401,70 @@ void cmState::AddUnexpectedCommand(std::string const& name, const char* error)
 
 void cmState::AddScriptedCommand(std::string const& name, cmCommand* command)
 {
-  this->RenameCommand(name, "_" + name);
-  this->AddCommand(command);
+  std::string sName = cmSystemTools::LowerCase(name);
+
+  // if the command already exists, give a new name to the old command.
+  if (cmCommand* oldCmd = this->GetCommand(sName)) {
+    std::string const newName = "_" + sName;
+    std::map<std::string, cmCommand*>::iterator pos =
+      this->ScriptedCommands.find(newName);
+    if (pos != this->ScriptedCommands.end()) {
+      delete pos->second;
+      this->ScriptedCommands.erase(pos);
+    }
+    this->ScriptedCommands.insert(std::make_pair(newName, oldCmd->Clone()));
+  }
+
+  // if the command already exists, free the old one
+  std::map<std::string, cmCommand*>::iterator pos =
+    this->ScriptedCommands.find(sName);
+  if (pos != this->ScriptedCommands.end()) {
+    delete pos->second;
+    this->ScriptedCommands.erase(pos);
+  }
+  this->ScriptedCommands.insert(std::make_pair(sName, command));
 }
 
 cmCommand* cmState::GetCommand(std::string const& name) const
 {
-  cmCommand* command = CM_NULLPTR;
   std::string sName = cmSystemTools::LowerCase(name);
-  std::map<std::string, cmCommand*>::const_iterator pos =
-    this->Commands.find(sName);
-  if (pos != this->Commands.end()) {
-    command = (*pos).second;
+  std::map<std::string, cmCommand*>::const_iterator pos;
+  pos = this->ScriptedCommands.find(sName);
+  if (pos != this->ScriptedCommands.end()) {
+    return pos->second;
   }
-  return command;
+  pos = this->BuiltinCommands.find(sName);
+  if (pos != this->BuiltinCommands.end()) {
+    return pos->second;
+  }
+  return CM_NULLPTR;
 }
 
 std::vector<std::string> cmState::GetCommandNames() const
 {
   std::vector<std::string> commandNames;
-  commandNames.reserve(this->Commands.size());
-  std::map<std::string, cmCommand*>::const_iterator cmds =
-    this->Commands.begin();
-  for (; cmds != this->Commands.end(); ++cmds) {
+  commandNames.reserve(this->BuiltinCommands.size() +
+                       this->ScriptedCommands.size());
+  for (std::map<std::string, cmCommand*>::const_iterator cmds =
+         this->BuiltinCommands.begin();
+       cmds != this->BuiltinCommands.end(); ++cmds) {
+    commandNames.push_back(cmds->first);
+  }
+  for (std::map<std::string, cmCommand*>::const_iterator cmds =
+         this->ScriptedCommands.begin();
+       cmds != this->ScriptedCommands.end(); ++cmds) {
     commandNames.push_back(cmds->first);
   }
+  std::sort(commandNames.begin(), commandNames.end());
+  commandNames.erase(std::unique(commandNames.begin(), commandNames.end()),
+                     commandNames.end());
   return commandNames;
 }
 
 void cmState::RemoveUserDefinedCommands()
 {
-  std::vector<cmCommand*> renamedCommands;
-  for (std::map<std::string, cmCommand*>::iterator j = this->Commands.begin();
-       j != this->Commands.end();) {
-    if (j->second->IsUserDefined()) {
-      delete j->second;
-      this->Commands.erase(j++);
-    } else if (j->first != j->second->GetName()) {
-      renamedCommands.push_back(j->second);
-      this->Commands.erase(j++);
-    } else {
-      ++j;
-    }
-  }
-  for (std::vector<cmCommand*>::const_iterator it = renamedCommands.begin();
-       it != renamedCommands.end(); ++it) {
-    this->Commands[cmSystemTools::LowerCase((*it)->GetName())] = *it;
-  }
+  cmDeleteAll(this->ScriptedCommands);
+  this->ScriptedCommands.clear();
 }
 
 void cmState::SetGlobalProperty(const std::string& prop, const char* value)
diff --git a/Source/cmState.h b/Source/cmState.h
index 895561e..1a5738f 100644
--- a/Source/cmState.h
+++ b/Source/cmState.h
@@ -121,13 +121,11 @@ public:
   void SetIsGeneratorMultiConfig(bool b);
 
   cmCommand* GetCommand(std::string const& name) const;
-  void AddCommand(cmCommand* command);
   void AddBuiltinCommand(std::string const& name, cmCommand* command);
   void AddDisallowedCommand(std::string const& name, cmCommand* command,
                             cmPolicies::PolicyID policy, const char* message);
   void AddUnexpectedCommand(std::string const& name, const char* error);
   void AddScriptedCommand(std::string const& name, cmCommand* command);
-  void RenameCommand(std::string const& oldName, std::string const& newName);
   void RemoveUserDefinedCommands();
   std::vector<std::string> GetCommandNames() const;
 
@@ -166,7 +164,8 @@ private:
 
   std::map<cmProperty::ScopeType, cmPropertyDefinitionMap> PropertyDefinitions;
   std::vector<std::string> EnabledLanguages;
-  std::map<std::string, cmCommand*> Commands;
+  std::map<std::string, cmCommand*> BuiltinCommands;
+  std::map<std::string, cmCommand*> ScriptedCommands;
   cmPropertyMap GlobalProperties;
   cmCacheManager* CacheManager;
 

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=a44dab461ffe269618f008f16e249d9101c5bd88
commit a44dab461ffe269618f008f16e249d9101c5bd88
Author:     Daniel Pfeifer <daniel at pfeifer-mail.de>
AuthorDate: Wed May 10 21:33:06 2017 +0200
Commit:     Daniel Pfeifer <daniel at pfeifer-mail.de>
CommitDate: Thu May 11 19:49:06 2017 +0200

    cmState: introduce method for adding scripted commands

diff --git a/Source/cmFunctionCommand.cxx b/Source/cmFunctionCommand.cxx
index dccc29f..642b029 100644
--- a/Source/cmFunctionCommand.cxx
+++ b/Source/cmFunctionCommand.cxx
@@ -149,11 +149,7 @@ bool cmFunctionFunctionBlocker::IsFunctionBlocked(
       f->Functions = this->Functions;
       f->FilePath = this->GetStartingContext().FilePath;
       mf.RecordPolicies(f->Policies);
-
-      std::string newName = "_" + this->Args[0];
-      mf.GetState()->RenameCommand(this->Args[0], newName);
-      mf.GetState()->AddCommand(f);
-
+      mf.GetState()->AddScriptedCommand(this->Args[0], f);
       // remove the function blocker now that the function is defined
       mf.RemoveFunctionBlocker(this, lff);
       return true;
diff --git a/Source/cmLoadCommandCommand.cxx b/Source/cmLoadCommandCommand.cxx
index 5cf1853..8bd212c 100644
--- a/Source/cmLoadCommandCommand.cxx
+++ b/Source/cmLoadCommandCommand.cxx
@@ -246,7 +246,7 @@ bool cmLoadCommandCommand::InitialPass(std::vector<std::string> const& args,
     // create a function blocker and set it up
     cmLoadedCommand* f = new cmLoadedCommand();
     (*initFunction)(&f->info);
-    this->Makefile->GetState()->AddCommand(f);
+    this->Makefile->GetState()->AddScriptedCommand(args[0], f);
     return true;
   }
   this->SetError("Attempt to load command failed. "
diff --git a/Source/cmMacroCommand.cxx b/Source/cmMacroCommand.cxx
index 507b579..f386a22 100644
--- a/Source/cmMacroCommand.cxx
+++ b/Source/cmMacroCommand.cxx
@@ -184,10 +184,7 @@ bool cmMacroFunctionBlocker::IsFunctionBlocked(const cmListFileFunction& lff,
       f->Functions = this->Functions;
       f->FilePath = this->GetStartingContext().FilePath;
       mf.RecordPolicies(f->Policies);
-      std::string newName = "_" + this->Args[0];
-      mf.GetState()->RenameCommand(this->Args[0], newName);
-      mf.GetState()->AddCommand(f);
-
+      mf.GetState()->AddScriptedCommand(this->Args[0], f);
       // remove the function blocker now that the macro is defined
       mf.RemoveFunctionBlocker(this, lff);
       return true;
diff --git a/Source/cmState.cxx b/Source/cmState.cxx
index 510501b..6de4c9f 100644
--- a/Source/cmState.cxx
+++ b/Source/cmState.cxx
@@ -433,6 +433,12 @@ void cmState::AddUnexpectedCommand(std::string const& name, const char* error)
   this->AddBuiltinCommand(name, new cmUnexpectedCommand(name, error));
 }
 
+void cmState::AddScriptedCommand(std::string const& name, cmCommand* command)
+{
+  this->RenameCommand(name, "_" + name);
+  this->AddCommand(command);
+}
+
 cmCommand* cmState::GetCommand(std::string const& name) const
 {
   cmCommand* command = CM_NULLPTR;
diff --git a/Source/cmState.h b/Source/cmState.h
index 603fe5d..895561e 100644
--- a/Source/cmState.h
+++ b/Source/cmState.h
@@ -126,6 +126,7 @@ public:
   void AddDisallowedCommand(std::string const& name, cmCommand* command,
                             cmPolicies::PolicyID policy, const char* message);
   void AddUnexpectedCommand(std::string const& name, const char* error);
+  void AddScriptedCommand(std::string const& name, cmCommand* command);
   void RenameCommand(std::string const& oldName, std::string const& newName);
   void RemoveUserDefinedCommands();
   std::vector<std::string> GetCommandNames() const;

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=c734c8501b5e8865b8a2e92a8834644becb181e4
commit c734c8501b5e8865b8a2e92a8834644becb181e4
Author:     Daniel Pfeifer <daniel at pfeifer-mail.de>
AuthorDate: Wed May 10 21:06:48 2017 +0200
Commit:     Daniel Pfeifer <daniel at pfeifer-mail.de>
CommitDate: Thu May 11 19:49:06 2017 +0200

    CTest: use new methods for builtin commands

diff --git a/Source/CTest/cmCTestScriptHandler.cxx b/Source/CTest/cmCTestScriptHandler.cxx
index 1fea8e5..1d29dfa 100644
--- a/Source/CTest/cmCTestScriptHandler.cxx
+++ b/Source/CTest/cmCTestScriptHandler.cxx
@@ -166,12 +166,12 @@ void cmCTestScriptHandler::UpdateElapsedTime()
   }
 }
 
-void cmCTestScriptHandler::AddCTestCommand(cmCTestCommand* command)
+void cmCTestScriptHandler::AddCTestCommand(std::string const& name,
+                                           cmCTestCommand* command)
 {
-  cmCTestCommand* newCom = command;
-  newCom->CTest = this->CTest;
-  newCom->CTestScriptHandler = this;
-  this->CMake->GetState()->AddCommand(newCom);
+  command->CTest = this->CTest;
+  command->CTestScriptHandler = this;
+  this->CMake->GetState()->AddBuiltinCommand(name, command);
 }
 
 int cmCTestScriptHandler::ExecuteScript(const std::string& total_script_arg)
@@ -290,22 +290,21 @@ void cmCTestScriptHandler::CreateCMake()
 
   this->CMake->SetProgressCallback(ctestScriptProgressCallback, this->CTest);
 
-  // add any ctest specific commands, probably should have common superclass
-  // for ctest commands to clean this up. If a couple more commands are
-  // created with the same format lets do that - ken
-  this->AddCTestCommand(new cmCTestBuildCommand);
-  this->AddCTestCommand(new cmCTestConfigureCommand);
-  this->AddCTestCommand(new cmCTestCoverageCommand);
-  this->AddCTestCommand(new cmCTestEmptyBinaryDirectoryCommand);
-  this->AddCTestCommand(new cmCTestMemCheckCommand);
-  this->AddCTestCommand(new cmCTestReadCustomFilesCommand);
-  this->AddCTestCommand(new cmCTestRunScriptCommand);
-  this->AddCTestCommand(new cmCTestSleepCommand);
-  this->AddCTestCommand(new cmCTestStartCommand);
-  this->AddCTestCommand(new cmCTestSubmitCommand);
-  this->AddCTestCommand(new cmCTestTestCommand);
-  this->AddCTestCommand(new cmCTestUpdateCommand);
-  this->AddCTestCommand(new cmCTestUploadCommand);
+  this->AddCTestCommand("ctest_build", new cmCTestBuildCommand);
+  this->AddCTestCommand("ctest_configure", new cmCTestConfigureCommand);
+  this->AddCTestCommand("ctest_coverage", new cmCTestCoverageCommand);
+  this->AddCTestCommand("ctest_empty_binary_directory",
+                        new cmCTestEmptyBinaryDirectoryCommand);
+  this->AddCTestCommand("ctest_memcheck", new cmCTestMemCheckCommand);
+  this->AddCTestCommand("ctest_read_custom_files",
+                        new cmCTestReadCustomFilesCommand);
+  this->AddCTestCommand("ctest_run_script", new cmCTestRunScriptCommand);
+  this->AddCTestCommand("ctest_sleep", new cmCTestSleepCommand);
+  this->AddCTestCommand("ctest_start", new cmCTestStartCommand);
+  this->AddCTestCommand("ctest_submit", new cmCTestSubmitCommand);
+  this->AddCTestCommand("ctest_test", new cmCTestTestCommand);
+  this->AddCTestCommand("ctest_update", new cmCTestUpdateCommand);
+  this->AddCTestCommand("ctest_upload", new cmCTestUploadCommand);
 }
 
 // this sets up some variables for the script to use, creates the required
diff --git a/Source/CTest/cmCTestScriptHandler.h b/Source/CTest/cmCTestScriptHandler.h
index 3070796..6678702 100644
--- a/Source/CTest/cmCTestScriptHandler.h
+++ b/Source/CTest/cmCTestScriptHandler.h
@@ -126,7 +126,7 @@ private:
   int RunConfigurationDashboard();
 
   // Add ctest command
-  void AddCTestCommand(cmCTestCommand* command);
+  void AddCTestCommand(std::string const& name, cmCTestCommand* command);
 
   // Try to remove the binary directory once
   static bool TryToRemoveBinaryDirectoryOnce(const std::string& directoryPath);
diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx
index 349e91a..e1b0967 100644
--- a/Source/CTest/cmCTestTestHandler.cxx
+++ b/Source/CTest/cmCTestTestHandler.cxx
@@ -1662,23 +1662,23 @@ void cmCTestTestHandler::GetListOfTests()
   // Add handler for ADD_TEST
   cmCTestAddTestCommand* newCom1 = new cmCTestAddTestCommand;
   newCom1->TestHandler = this;
-  cm.GetState()->AddCommand(newCom1);
+  cm.GetState()->AddBuiltinCommand("add_test", newCom1);
 
   // Add handler for SUBDIRS
   cmCTestSubdirCommand* newCom2 = new cmCTestSubdirCommand;
   newCom2->TestHandler = this;
-  cm.GetState()->AddCommand(newCom2);
+  cm.GetState()->AddBuiltinCommand("subdirs", newCom2);
 
   // Add handler for ADD_SUBDIRECTORY
   cmCTestAddSubdirectoryCommand* newCom3 = new cmCTestAddSubdirectoryCommand;
   newCom3->TestHandler = this;
-  cm.GetState()->AddCommand(newCom3);
+  cm.GetState()->AddBuiltinCommand("add_subdirectory", newCom3);
 
-  // Add handler for SET_SOURCE_FILES_PROPERTIES
+  // Add handler for SET_TESTS_PROPERTIES
   cmCTestSetTestsPropertiesCommand* newCom4 =
     new cmCTestSetTestsPropertiesCommand;
   newCom4->TestHandler = this;
-  cm.GetState()->AddCommand(newCom4);
+  cm.GetState()->AddBuiltinCommand("set_tests_properties", newCom4);
 
   const char* testFilename;
   if (cmSystemTools::FileExists("CTestTestfile.cmake")) {

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=bd14e46400aaeb3afc826c6316b376eba6f082b2
commit bd14e46400aaeb3afc826c6316b376eba6f082b2
Author:     Daniel Pfeifer <daniel at pfeifer-mail.de>
AuthorDate: Wed May 10 21:06:11 2017 +0200
Commit:     Daniel Pfeifer <daniel at pfeifer-mail.de>
CommitDate: Thu May 11 19:49:06 2017 +0200

    cmCommands: use new methods for builtin commands

diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index adf46ff..e1d8ef1 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -70,7 +70,6 @@
 #include "cmTargetLinkLibrariesCommand.h"
 #include "cmTryCompileCommand.h"
 #include "cmTryRunCommand.h"
-#include "cmUnexpectedCommand.h"
 #include "cmUnsetCommand.h"
 #include "cmWhileCommand.h"
 
@@ -79,7 +78,6 @@
 #include "cmAuxSourceDirectoryCommand.h"
 #include "cmBuildNameCommand.h"
 #include "cmCMakeHostSystemInformationCommand.h"
-#include "cmDisallowedCommand.h"
 #include "cmExportCommand.h"
 #include "cmExportLibraryDependenciesCommand.h"
 #include "cmFLTKWrapUICommand.h"
@@ -109,169 +107,195 @@
 
 void GetScriptingCommands(cmState* state)
 {
-  state->AddCommand(new cmBreakCommand);
-  state->AddCommand(new cmCMakeMinimumRequired);
-  state->AddCommand(new cmCMakePolicyCommand);
-  state->AddCommand(new cmConfigureFileCommand);
-  state->AddCommand(new cmContinueCommand);
-  state->AddCommand(new cmExecProgramCommand);
-  state->AddCommand(new cmExecuteProcessCommand);
-  state->AddCommand(new cmFileCommand);
-  state->AddCommand(new cmFindFileCommand);
-  state->AddCommand(new cmFindLibraryCommand);
-  state->AddCommand(new cmFindPackageCommand);
-  state->AddCommand(new cmFindPathCommand);
-  state->AddCommand(new cmFindProgramCommand);
-  state->AddCommand(new cmForEachCommand);
-  state->AddCommand(new cmFunctionCommand);
-  state->AddCommand(new cmGetCMakePropertyCommand);
-  state->AddCommand(new cmGetDirectoryPropertyCommand);
-  state->AddCommand(new cmGetFilenameComponentCommand);
-  state->AddCommand(new cmGetPropertyCommand);
-  state->AddCommand(new cmIfCommand);
-  state->AddCommand(new cmIncludeCommand);
-  state->AddCommand(new cmListCommand);
-  state->AddCommand(new cmMacroCommand);
-  state->AddCommand(new cmMakeDirectoryCommand);
-  state->AddCommand(new cmMarkAsAdvancedCommand);
-  state->AddCommand(new cmMathCommand);
-  state->AddCommand(new cmMessageCommand);
-  state->AddCommand(new cmOptionCommand);
-  state->AddCommand(new cmParseArgumentsCommand);
-  state->AddCommand(new cmReturnCommand);
-  state->AddCommand(new cmSeparateArgumentsCommand);
-  state->AddCommand(new cmSetCommand);
-  state->AddCommand(new cmSetDirectoryPropertiesCommand);
-  state->AddCommand(new cmSetPropertyCommand);
-  state->AddCommand(new cmSiteNameCommand);
-  state->AddCommand(new cmStringCommand);
-  state->AddCommand(new cmUnsetCommand);
-  state->AddCommand(new cmWhileCommand);
+  state->AddBuiltinCommand("break", new cmBreakCommand);
+  state->AddBuiltinCommand("cmake_minimum_required",
+                           new cmCMakeMinimumRequired);
+  state->AddBuiltinCommand("cmake_policy", new cmCMakePolicyCommand);
+  state->AddBuiltinCommand("configure_file", new cmConfigureFileCommand);
+  state->AddBuiltinCommand("continue", new cmContinueCommand);
+  state->AddBuiltinCommand("exec_program", new cmExecProgramCommand);
+  state->AddBuiltinCommand("execute_process", new cmExecuteProcessCommand);
+  state->AddBuiltinCommand("file", new cmFileCommand);
+  state->AddBuiltinCommand("find_file", new cmFindFileCommand);
+  state->AddBuiltinCommand("find_library", new cmFindLibraryCommand);
+  state->AddBuiltinCommand("find_package", new cmFindPackageCommand);
+  state->AddBuiltinCommand("find_path", new cmFindPathCommand);
+  state->AddBuiltinCommand("find_program", new cmFindProgramCommand);
+  state->AddBuiltinCommand("foreach", new cmForEachCommand);
+  state->AddBuiltinCommand("function", new cmFunctionCommand);
+  state->AddBuiltinCommand("get_cmake_property",
+                           new cmGetCMakePropertyCommand);
+  state->AddBuiltinCommand("get_directory_property",
+                           new cmGetDirectoryPropertyCommand);
+  state->AddBuiltinCommand("get_filename_component",
+                           new cmGetFilenameComponentCommand);
+  state->AddBuiltinCommand("get_property", new cmGetPropertyCommand);
+  state->AddBuiltinCommand("if", new cmIfCommand);
+  state->AddBuiltinCommand("include", new cmIncludeCommand);
+  state->AddBuiltinCommand("list", new cmListCommand);
+  state->AddBuiltinCommand("macro", new cmMacroCommand);
+  state->AddBuiltinCommand("make_directory", new cmMakeDirectoryCommand);
+  state->AddBuiltinCommand("mark_as_advanced", new cmMarkAsAdvancedCommand);
+  state->AddBuiltinCommand("math", new cmMathCommand);
+  state->AddBuiltinCommand("message", new cmMessageCommand);
+  state->AddBuiltinCommand("option", new cmOptionCommand);
+  state->AddBuiltinCommand("cmake_parse_arguments",
+                           new cmParseArgumentsCommand);
+  state->AddBuiltinCommand("return", new cmReturnCommand);
+  state->AddBuiltinCommand("separate_arguments",
+                           new cmSeparateArgumentsCommand);
+  state->AddBuiltinCommand("set", new cmSetCommand);
+  state->AddBuiltinCommand("set_directory_properties",
+                           new cmSetDirectoryPropertiesCommand);
+  state->AddBuiltinCommand("set_property", new cmSetPropertyCommand);
+  state->AddBuiltinCommand("site_name", new cmSiteNameCommand);
+  state->AddBuiltinCommand("string", new cmStringCommand);
+  state->AddBuiltinCommand("unset", new cmUnsetCommand);
+  state->AddBuiltinCommand("while", new cmWhileCommand);
 
-  state->AddCommand(new cmUnexpectedCommand(
+  state->AddUnexpectedCommand(
     "else", "An ELSE command was found outside of a proper "
             "IF ENDIF structure. Or its arguments did not match "
-            "the opening IF command."));
-  state->AddCommand(new cmUnexpectedCommand(
+            "the opening IF command.");
+  state->AddUnexpectedCommand(
     "elseif", "An ELSEIF command was found outside of a proper "
-              "IF ENDIF structure."));
-  state->AddCommand(new cmUnexpectedCommand(
+              "IF ENDIF structure.");
+  state->AddUnexpectedCommand(
     "endforeach", "An ENDFOREACH command was found outside of a proper "
                   "FOREACH ENDFOREACH structure. Or its arguments did "
-                  "not match the opening FOREACH command."));
-  state->AddCommand(new cmUnexpectedCommand(
+                  "not match the opening FOREACH command.");
+  state->AddUnexpectedCommand(
     "endfunction", "An ENDFUNCTION command was found outside of a proper "
                    "FUNCTION ENDFUNCTION structure. Or its arguments did not "
-                   "match the opening FUNCTION command."));
-  state->AddCommand(new cmUnexpectedCommand(
+                   "match the opening FUNCTION command.");
+  state->AddUnexpectedCommand(
     "endif", "An ENDIF command was found outside of a proper "
              "IF ENDIF structure. Or its arguments did not match "
-             "the opening IF command."));
-  state->AddCommand(new cmUnexpectedCommand(
+             "the opening IF command.");
+  state->AddUnexpectedCommand(
     "endmacro", "An ENDMACRO command was found outside of a proper "
                 "MACRO ENDMACRO structure. Or its arguments did not "
-                "match the opening MACRO command."));
-  state->AddCommand(new cmUnexpectedCommand(
+                "match the opening MACRO command.");
+  state->AddUnexpectedCommand(
     "endwhile", "An ENDWHILE command was found outside of a proper "
                 "WHILE ENDWHILE structure. Or its arguments did not "
-                "match the opening WHILE command."));
+                "match the opening WHILE command.");
 
 #if defined(CMAKE_BUILD_WITH_CMAKE)
-  state->AddCommand(new cmCMakeHostSystemInformationCommand);
-  state->AddCommand(new cmRemoveCommand);
-  state->AddCommand(new cmVariableWatchCommand);
-  state->AddCommand(new cmWriteFileCommand);
+  state->AddBuiltinCommand("cmake_host_system_information",
+                           new cmCMakeHostSystemInformationCommand);
+  state->AddBuiltinCommand("remove", new cmRemoveCommand);
+  state->AddBuiltinCommand("variable_watch", new cmVariableWatchCommand);
+  state->AddBuiltinCommand("write_file", new cmWriteFileCommand);
 
-  state->AddCommand(new cmDisallowedCommand(
-    new cmBuildNameCommand, cmPolicies::CMP0036,
-    "The build_name command should not be called; see CMP0036."));
-  state->AddCommand(new cmDisallowedCommand(
-    new cmUseMangledMesaCommand, cmPolicies::CMP0030,
-    "The use_mangled_mesa command should not be called; see CMP0030."));
+  state->AddDisallowedCommand(
+    "build_name", new cmBuildNameCommand, cmPolicies::CMP0036,
+    "The build_name command should not be called; see CMP0036.");
+  state->AddDisallowedCommand(
+    "use_mangled_mesa", new cmUseMangledMesaCommand, cmPolicies::CMP0030,
+    "The use_mangled_mesa command should not be called; see CMP0030.");
 
 #endif
 }
 
 void GetProjectCommands(cmState* state)
 {
-  state->AddCommand(new cmAddCustomCommandCommand);
-  state->AddCommand(new cmAddCustomTargetCommand);
-  state->AddCommand(new cmAddDefinitionsCommand);
-  state->AddCommand(new cmAddDependenciesCommand);
-  state->AddCommand(new cmAddExecutableCommand);
-  state->AddCommand(new cmAddLibraryCommand);
-  state->AddCommand(new cmAddSubDirectoryCommand);
-  state->AddCommand(new cmAddTestCommand);
-  state->AddCommand(new cmBuildCommand);
-  state->AddCommand(new cmCreateTestSourceList);
-  state->AddCommand(new cmDefinePropertyCommand);
-  state->AddCommand(new cmEnableLanguageCommand);
-  state->AddCommand(new cmEnableTestingCommand);
-  state->AddCommand(new cmGetSourceFilePropertyCommand);
-  state->AddCommand(new cmGetTargetPropertyCommand);
-  state->AddCommand(new cmGetTestPropertyCommand);
-  state->AddCommand(new cmIncludeDirectoryCommand);
-  state->AddCommand(new cmIncludeRegularExpressionCommand);
-  state->AddCommand(new cmInstallCommand);
-  state->AddCommand(new cmInstallFilesCommand);
-  state->AddCommand(new cmInstallTargetsCommand);
-  state->AddCommand(new cmLinkDirectoriesCommand);
-  state->AddCommand(new cmProjectCommand);
-  state->AddCommand(new cmSetSourceFilesPropertiesCommand);
-  state->AddCommand(new cmSetTargetPropertiesCommand);
-  state->AddCommand(new cmSetTestsPropertiesCommand);
-  state->AddCommand(new cmSubdirCommand);
-  state->AddCommand(new cmTargetLinkLibrariesCommand);
-  state->AddCommand(new cmTryCompileCommand);
-  state->AddCommand(new cmTryRunCommand);
+  state->AddBuiltinCommand("add_custom_command",
+                           new cmAddCustomCommandCommand);
+  state->AddBuiltinCommand("add_custom_target", new cmAddCustomTargetCommand);
+  state->AddBuiltinCommand("add_definitions", new cmAddDefinitionsCommand);
+  state->AddBuiltinCommand("add_dependencies", new cmAddDependenciesCommand);
+  state->AddBuiltinCommand("add_executable", new cmAddExecutableCommand);
+  state->AddBuiltinCommand("add_library", new cmAddLibraryCommand);
+  state->AddBuiltinCommand("add_subdirectory", new cmAddSubDirectoryCommand);
+  state->AddBuiltinCommand("add_test", new cmAddTestCommand);
+  state->AddBuiltinCommand("build_command", new cmBuildCommand);
+  state->AddBuiltinCommand("create_test_sourcelist",
+                           new cmCreateTestSourceList);
+  state->AddBuiltinCommand("define_property", new cmDefinePropertyCommand);
+  state->AddBuiltinCommand("enable_language", new cmEnableLanguageCommand);
+  state->AddBuiltinCommand("enable_testing", new cmEnableTestingCommand);
+  state->AddBuiltinCommand("get_source_file_property",
+                           new cmGetSourceFilePropertyCommand);
+  state->AddBuiltinCommand("get_target_property",
+                           new cmGetTargetPropertyCommand);
+  state->AddBuiltinCommand("get_test_property", new cmGetTestPropertyCommand);
+  state->AddBuiltinCommand("include_directories",
+                           new cmIncludeDirectoryCommand);
+  state->AddBuiltinCommand("include_regular_expression",
+                           new cmIncludeRegularExpressionCommand);
+  state->AddBuiltinCommand("install", new cmInstallCommand);
+  state->AddBuiltinCommand("install_files", new cmInstallFilesCommand);
+  state->AddBuiltinCommand("install_targets", new cmInstallTargetsCommand);
+  state->AddBuiltinCommand("link_directories", new cmLinkDirectoriesCommand);
+  state->AddBuiltinCommand("project", new cmProjectCommand);
+  state->AddBuiltinCommand("set_source_files_properties",
+                           new cmSetSourceFilesPropertiesCommand);
+  state->AddBuiltinCommand("set_target_properties",
+                           new cmSetTargetPropertiesCommand);
+  state->AddBuiltinCommand("set_tests_properties",
+                           new cmSetTestsPropertiesCommand);
+  state->AddBuiltinCommand("subdirs", new cmSubdirCommand);
+  state->AddBuiltinCommand("target_link_libraries",
+                           new cmTargetLinkLibrariesCommand);
+  state->AddBuiltinCommand("try_compile", new cmTryCompileCommand);
+  state->AddBuiltinCommand("try_run", new cmTryRunCommand);
 
 #if defined(CMAKE_BUILD_WITH_CMAKE)
-  state->AddCommand(new cmAddCompileOptionsCommand);
-  state->AddCommand(new cmAuxSourceDirectoryCommand);
-  state->AddCommand(new cmExportCommand);
-  state->AddCommand(new cmFLTKWrapUICommand);
-  state->AddCommand(new cmIncludeExternalMSProjectCommand);
-  state->AddCommand(new cmInstallProgramsCommand);
-  state->AddCommand(new cmLinkLibrariesCommand);
-  state->AddCommand(new cmLoadCacheCommand);
-  state->AddCommand(new cmQTWrapCPPCommand);
-  state->AddCommand(new cmQTWrapUICommand);
-  state->AddCommand(new cmRemoveDefinitionsCommand);
-  state->AddCommand(new cmSourceGroupCommand);
-  state->AddCommand(new cmTargetCompileDefinitionsCommand);
-  state->AddCommand(new cmTargetCompileFeaturesCommand);
-  state->AddCommand(new cmTargetCompileOptionsCommand);
-  state->AddCommand(new cmTargetIncludeDirectoriesCommand);
-  state->AddCommand(new cmTargetSourcesCommand);
+  state->AddBuiltinCommand("add_compile_options",
+                           new cmAddCompileOptionsCommand);
+  state->AddBuiltinCommand("aux_source_directory",
+                           new cmAuxSourceDirectoryCommand);
+  state->AddBuiltinCommand("export", new cmExportCommand);
+  state->AddBuiltinCommand("fltk_wrap_ui", new cmFLTKWrapUICommand);
+  state->AddBuiltinCommand("include_external_msproject",
+                           new cmIncludeExternalMSProjectCommand);
+  state->AddBuiltinCommand("install_programs", new cmInstallProgramsCommand);
+  state->AddBuiltinCommand("link_libraries", new cmLinkLibrariesCommand);
+  state->AddBuiltinCommand("load_cache", new cmLoadCacheCommand);
+  state->AddBuiltinCommand("qt_wrap_cpp", new cmQTWrapCPPCommand);
+  state->AddBuiltinCommand("qt_wrap_ui", new cmQTWrapUICommand);
+  state->AddBuiltinCommand("remove_definitions",
+                           new cmRemoveDefinitionsCommand);
+  state->AddBuiltinCommand("source_group", new cmSourceGroupCommand);
+  state->AddBuiltinCommand("target_compile_definitions",
+                           new cmTargetCompileDefinitionsCommand);
+  state->AddBuiltinCommand("target_compile_features",
+                           new cmTargetCompileFeaturesCommand);
+  state->AddBuiltinCommand("target_compile_options",
+                           new cmTargetCompileOptionsCommand);
+  state->AddBuiltinCommand("target_include_directories",
+                           new cmTargetIncludeDirectoriesCommand);
+  state->AddBuiltinCommand("target_sources", new cmTargetSourcesCommand);
 
-  state->AddCommand(new cmDisallowedCommand(
-    new cmExportLibraryDependenciesCommand, cmPolicies::CMP0033,
+  state->AddDisallowedCommand(
+    "export_library_dependencies", new cmExportLibraryDependenciesCommand,
+    cmPolicies::CMP0033,
     "The export_library_dependencies command should not be called; "
-    "see CMP0033."));
-  state->AddCommand(new cmDisallowedCommand(
-    new cmLoadCommandCommand, cmPolicies::CMP0031,
-    "The load_command command should not be called; see CMP0031."));
-  state->AddCommand(new cmDisallowedCommand(
-    new cmOutputRequiredFilesCommand, cmPolicies::CMP0032,
-    "The output_required_files command should not be called; "
-    "see CMP0032."));
-  state->AddCommand(new cmDisallowedCommand(
-    new cmSubdirDependsCommand, cmPolicies::CMP0029,
-    "The subdir_depends command should not be called; see CMP0029."));
-  state->AddCommand(new cmDisallowedCommand(
-    new cmUtilitySourceCommand, cmPolicies::CMP0034,
-    "The utility_source command should not be called; see CMP0034."));
-  state->AddCommand(new cmDisallowedCommand(
-    new cmVariableRequiresCommand, cmPolicies::CMP0035,
-    "The variable_requires command should not be called; see CMP0035."));
+    "see CMP0033.");
+  state->AddDisallowedCommand(
+    "load_command", new cmLoadCommandCommand, cmPolicies::CMP0031,
+    "The load_command command should not be called; see CMP0031.");
+  state->AddDisallowedCommand(
+    "output_required_files", new cmOutputRequiredFilesCommand,
+    cmPolicies::CMP0032,
+    "The output_required_files command should not be called; see CMP0032.");
+  state->AddDisallowedCommand(
+    "subdir_depends", new cmSubdirDependsCommand, cmPolicies::CMP0029,
+    "The subdir_depends command should not be called; see CMP0029.");
+  state->AddDisallowedCommand(
+    "utility_source", new cmUtilitySourceCommand, cmPolicies::CMP0034,
+    "The utility_source command should not be called; see CMP0034.");
+  state->AddDisallowedCommand(
+    "variable_requires", new cmVariableRequiresCommand, cmPolicies::CMP0035,
+    "The variable_requires command should not be called; see CMP0035.");
 #endif
 }
 
 void GetProjectCommandsInScriptMode(cmState* state)
 {
 #define CM_UNEXPECTED_PROJECT_COMMAND(NAME)                                   \
-  state->AddCommand(new cmUnexpectedCommand(NAME, "command is not "           \
-                                                  "scriptable"))
+  state->AddUnexpectedCommand(NAME, "command is not scriptable")
 
   CM_UNEXPECTED_PROJECT_COMMAND("add_compile_options");
   CM_UNEXPECTED_PROJECT_COMMAND("add_custom_command");

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=587084052bbecc812de00e75aac389faef6b7eed
commit 587084052bbecc812de00e75aac389faef6b7eed
Author:     Daniel Pfeifer <daniel at pfeifer-mail.de>
AuthorDate: Wed May 10 21:05:29 2017 +0200
Commit:     Daniel Pfeifer <daniel at pfeifer-mail.de>
CommitDate: Thu May 11 19:49:06 2017 +0200

    cmState: introduce methods for adding builtin commands

diff --git a/Source/cmState.cxx b/Source/cmState.cxx
index 43f439c..510501b 100644
--- a/Source/cmState.cxx
+++ b/Source/cmState.cxx
@@ -12,10 +12,12 @@
 #include "cmCacheManager.h"
 #include "cmCommand.h"
 #include "cmDefinitions.h"
+#include "cmDisallowedCommand.h"
 #include "cmListFileCache.h"
 #include "cmStatePrivate.h"
 #include "cmStateSnapshot.h"
 #include "cmSystemTools.h"
+#include "cmUnexpectedCommand.h"
 #include "cmake.h"
 
 cmState::cmState()
@@ -410,6 +412,27 @@ void cmState::AddCommand(cmCommand* command)
   this->Commands.insert(std::make_pair(name, command));
 }
 
+void cmState::AddBuiltinCommand(std::string const& name, cmCommand* command)
+{
+  assert(name == cmSystemTools::LowerCase(name));
+  assert(name == cmSystemTools::LowerCase(command->GetName()));
+  assert(this->Commands.find(name) == this->Commands.end());
+  this->Commands.insert(std::make_pair(name, command));
+}
+
+void cmState::AddDisallowedCommand(std::string const& name, cmCommand* command,
+                                   cmPolicies::PolicyID policy,
+                                   const char* message)
+{
+  this->AddBuiltinCommand(name,
+                          new cmDisallowedCommand(command, policy, message));
+}
+
+void cmState::AddUnexpectedCommand(std::string const& name, const char* error)
+{
+  this->AddBuiltinCommand(name, new cmUnexpectedCommand(name, error));
+}
+
 cmCommand* cmState::GetCommand(std::string const& name) const
 {
   cmCommand* command = CM_NULLPTR;
diff --git a/Source/cmState.h b/Source/cmState.h
index 240d75b..603fe5d 100644
--- a/Source/cmState.h
+++ b/Source/cmState.h
@@ -12,6 +12,7 @@
 
 #include "cmDefinitions.h"
 #include "cmLinkedTree.h"
+#include "cmPolicies.h"
 #include "cmProperty.h"
 #include "cmPropertyDefinitionMap.h"
 #include "cmPropertyMap.h"
@@ -121,6 +122,10 @@ public:
 
   cmCommand* GetCommand(std::string const& name) const;
   void AddCommand(cmCommand* command);
+  void AddBuiltinCommand(std::string const& name, cmCommand* command);
+  void AddDisallowedCommand(std::string const& name, cmCommand* command,
+                            cmPolicies::PolicyID policy, const char* message);
+  void AddUnexpectedCommand(std::string const& name, const char* error);
   void RenameCommand(std::string const& oldName, std::string const& newName);
   void RemoveUserDefinedCommands();
   std::vector<std::string> GetCommandNames() const;
diff --git a/bootstrap b/bootstrap
index 515e8be..b4b4c28 100755
--- a/bootstrap
+++ b/bootstrap
@@ -278,6 +278,7 @@ CMAKE_CXX_SOURCES="\
   cmDefinitions \
   cmDepends \
   cmDependsC \
+  cmDisallowedCommand \
   cmDocumentationFormatter \
   cmEnableLanguageCommand \
   cmEnableTestingCommand \

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=036ffe815acd1ea4ee5cafb1b9547930bfbdbebf
commit 036ffe815acd1ea4ee5cafb1b9547930bfbdbebf
Author:     Robert Maynard <robert.maynard at kitware.com>
AuthorDate: Thu May 11 13:33:10 2017 -0400
Commit:     Robert Maynard <robert.maynard at kitware.com>
CommitDate: Thu May 11 13:42:42 2017 -0400

    CUDA: Add support for the C++14 standard flag.
    
    CUDA 9 toolkit has announced support for C++14 flag, so lets allow users
    to use it.

diff --git a/Modules/Compiler/NVIDIA-CUDA.cmake b/Modules/Compiler/NVIDIA-CUDA.cmake
index 316cab8..785e269 100644
--- a/Modules/Compiler/NVIDIA-CUDA.cmake
+++ b/Modules/Compiler/NVIDIA-CUDA.cmake
@@ -24,4 +24,10 @@ else()
   set(CMAKE_CUDA98_EXTENSION_COMPILE_OPTION "")
   set(CMAKE_CUDA11_STANDARD_COMPILE_OPTION "-std=c++11")
   set(CMAKE_CUDA11_EXTENSION_COMPILE_OPTION "-std=c++11")
+
+  if (NOT CMAKE_CUDA_COMPILER_VERSION VERSION_LESS 9.0)
+    set(CMAKE_CUDA14_STANDARD_COMPILE_OPTION "-std=c++14")
+    set(CMAKE_CUDA14_EXTENSION_COMPILE_OPTION "-std=c++14")
+  endif()
+
 endif()
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 0ab6e89..d51217c 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -1518,6 +1518,7 @@ void cmLocalGenerator::AddCompilerRequirementFlag(
     langStdMap["C"].push_back("99");
     langStdMap["C"].push_back("90");
 
+    langStdMap["CUDA"].push_back("14");
     langStdMap["CUDA"].push_back("11");
     langStdMap["CUDA"].push_back("98");
   }

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=a890ca2f8dfc640f7096f3ad89a2429315d8b71a
commit a890ca2f8dfc640f7096f3ad89a2429315d8b71a
Author:     Daniel Pfeifer <daniel at pfeifer-mail.de>
AuthorDate: Thu May 11 21:04:25 2017 +0200
Commit:     Daniel Pfeifer <daniel at pfeifer-mail.de>
CommitDate: Thu May 11 17:57:59 2017 +0200

    cmakemain: use script role for -P

diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx
index f472b8a..6e65955 100644
--- a/Source/cmakemain.cxx
+++ b/Source/cmakemain.cxx
@@ -289,7 +289,9 @@ int do_cmake(int ac, char const* const* av)
     int ret = cm.GetSystemInformation(args);
     return ret;
   }
-  cmake cm(cmake::RoleProject);
+  cmake::Role const role =
+    workingMode == cmake::NORMAL_MODE ? cmake::RoleProject : cmake::RoleScript;
+  cmake cm(role);
   cm.SetHomeDirectory("");
   cm.SetHomeOutputDirectory("");
   cmSystemTools::SetMessageCallback(cmakemainMessageCallback, (void*)&cm);

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=95d3ebcc4880c0b69108c6155b38abbbc6ca5e15
commit 95d3ebcc4880c0b69108c6155b38abbbc6ca5e15
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Thu May 11 11:07:48 2017 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Thu May 11 11:27:41 2017 -0400

    curl: Set TLS/SSL build options the way we need for CMake
    
    Restore settings to match what we had before resolving conflicts in the
    latest update.  Use native APIs on Windows and Apple.  Pass CA
    bundle/path options.

diff --git a/Utilities/cmcurl/CMakeLists.txt b/Utilities/cmcurl/CMakeLists.txt
index fd5416f..5049d7b 100644
--- a/Utilities/cmcurl/CMakeLists.txt
+++ b/Utilities/cmcurl/CMakeLists.txt
@@ -34,6 +34,29 @@ set(ENABLE_THREADED_RESOLVER OFF CACHE INTERNAL "No curl POSIX threaded DNS look
 set(ENABLE_UNIX_SOCKETS OFF CACHE INTERNAL "No curl Unix domain sockets support")
 set(HTTP_ONLY OFF CACHE INTERNAL "Curl is not http-only")
 set(USE_WIN32_LDAP OFF CACHE INTERNAL "No curl Windows LDAP")
+if(CMAKE_USE_OPENSSL)
+elseif(WIN32)
+  set(CMAKE_USE_WINSSL ON CACHE INTERNAL "enable Windows native SSL/TLS")
+  set(CURL_WINDOWS_SSPI ON CACHE INTERNAL "Use windows libraries to allow NTLM authentication without openssl")
+elseif(APPLE)
+  # Use OS X SSL/TLS native implementation if available on target version.
+  if(CMAKE_OSX_DEPLOYMENT_TARGET)
+    set(OSX_VERSION ${CMAKE_OSX_DEPLOYMENT_TARGET})
+  else()
+    execute_process(
+      COMMAND sw_vers -productVersion
+      OUTPUT_VARIABLE OSX_VERSION
+      OUTPUT_STRIP_TRAILING_WHITESPACE
+      )
+  endif()
+  if(NOT OSX_VERSION VERSION_LESS 10.6 AND
+      CMAKE_C_COMPILER_ID MATCHES "GNU|Clang|AppleClang")
+    set(CMAKE_USE_DARWINSSL ON CACHE INTERNAL "enable Apple OS native SSL/TLS")
+  else()
+    set(CMAKE_USE_DARWINSSL OFF CACHE INTERNAL "enable Apple OS native SSL/TLS")
+  endif()
+endif()
+set(CMAKE_USE_MBEDTLS OFF CACHE INTERNAL "Enable mbedTLS for SSL/TLS")
 
 # Windows Vista and above have inet_pton, but this will link on
 # older versions and then the executable will fail to launch at
@@ -389,7 +412,6 @@ set(openssl_default ON)
 if(WIN32 OR CMAKE_USE_DARWINSSL OR CMAKE_USE_WINSSL OR CMAKE_USE_MBEDTLS)
   set(openssl_default OFF)
 endif()
-option(CMAKE_USE_OPENSSL "Use OpenSSL code. Experimental" ${openssl_default})
 
 collect_true(enabled_ssl_options enabled_ssl_options_count
   CMAKE_USE_WINSSL
@@ -449,6 +471,15 @@ if(CMAKE_USE_OPENSSL)
   check_symbol_exists(RAND_status "${CURL_INCLUDES}" HAVE_RAND_STATUS)
   check_symbol_exists(RAND_screen "${CURL_INCLUDES}" HAVE_RAND_SCREEN)
   check_symbol_exists(RAND_egd    "${CURL_INCLUDES}" HAVE_RAND_EGD)
+
+  # Optionally build with a specific CA cert bundle.
+  if(CURL_CA_BUNDLE)
+    add_definitions(-DCURL_CA_BUNDLE="${CURL_CA_BUNDLE}")
+  endif()
+  # Optionally build with a specific CA cert dir.
+  if(CURL_CA_PATH)
+    add_definitions(-DCURL_CA_PATH="${CURL_CA_PATH}")
+  endif()
 endif()
 
 if(CMAKE_USE_MBEDTLS)

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=11ba72c6d604db44e12b0f67f20a0e192d69b970
commit 11ba72c6d604db44e12b0f67f20a0e192d69b970
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Thu May 11 10:58:27 2017 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Thu May 11 11:27:37 2017 -0400

    curl: Skip building docs within CMake

diff --git a/Utilities/cmcurl/CMakeLists.txt b/Utilities/cmcurl/CMakeLists.txt
index db08a1d..fd5416f 100644
--- a/Utilities/cmcurl/CMakeLists.txt
+++ b/Utilities/cmcurl/CMakeLists.txt
@@ -290,8 +290,11 @@ if(ENABLE_MANUAL)
     message(WARNING "Found no *nroff program")
   endif()
 endif()
+
+if(0) # This code not needed for building within CMake.
 # Required for building manual, docs, tests
 find_package(Perl REQUIRED)
+endif()
 
 # We need ansi c-flags, especially on HP
 set(CMAKE_C_FLAGS "${CMAKE_ANSI_CFLAGS} ${CMAKE_C_FLAGS}")
@@ -1125,7 +1128,9 @@ function(TRANSFORM_MAKEFILE_INC INPUT_FILE OUTPUT_FILE)
 
 endfunction()
 
+if(0) # This code not needed for building within CMake.
 add_subdirectory(docs)
+endif()
 add_subdirectory(lib)
 if(BUILD_CURL_EXE)
   add_subdirectory(src)

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=299975908ada992800791fac7f3739050e0ae2a9
commit 299975908ada992800791fac7f3739050e0ae2a9
Merge: 5af9c8e fd7d521
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Thu May 11 10:55:44 2017 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Thu May 11 11:27:21 2017 -0400

    Merge branch 'upstream-curl' into update-curl
    
    * upstream-curl:
      curl 2017-04-19 (d957e218)
    
    Resolve conflicts in `CMakeLists.txt` in favor of the upstream version.
    We will re-apply our logic as needed in following commits.

diff --cc Utilities/cmcurl/CMake/FindMbedTLS.cmake
index 0000000,a916395..a916395
mode 000000,100644..100644
--- a/Utilities/cmcurl/CMake/FindMbedTLS.cmake
+++ b/Utilities/cmcurl/CMake/FindMbedTLS.cmake
diff --cc Utilities/cmcurl/CMakeLists.txt
index 6a34e8d,0000000..db08a1d
mode 100644,000000..100644
--- a/Utilities/cmcurl/CMakeLists.txt
+++ b/Utilities/cmcurl/CMakeLists.txt
@@@ -1,1283 -1,0 +1,1304 @@@
 +# Set curl options as needed for CMake build
 +set(BUILD_CURL_EXE OFF CACHE INTERNAL "No curl exe")
 +set(BUILD_DASHBOARD_REPORTS OFF CACHE INTERNAL "No curl dashboard reports")
 +set(BUILD_RELEASE_DEBUG_DIRS OFF CACHE INTERNAL "No curl release/debug dirs")
 +set(CMAKE_USE_GSSAPI OFF CACHE INTERNAL "Disable curl gssapi")
 +set(CMAKE_USE_LIBSSH2 OFF CACHE INTERNAL "Disable curl libssh2")
 +set(CMAKE_USE_OPENLDAP OFF CACHE INTERNAL "No curl OpenLDAP")
 +set(CURL_DISABLE_COOKIES OFF CACHE INTERNAL "Do not disable curl cookie support")
 +set(CURL_DISABLE_CRYPTO_AUTH OFF CACHE INTERNAL "Do not disable curl crypto auth")
 +set(CURL_DISABLE_DICT ON CACHE INTERNAL "Disable curl dict protocol?")
 +set(CURL_DISABLE_FILE OFF CACHE INTERNAL "Disable curl file protocol?")
 +set(CURL_DISABLE_FTP OFF CACHE INTERNAL "Disable curl ftp protocol?")
 +set(CURL_DISABLE_GOPHER ON CACHE INTERNAL "Disable curl gopher protocol?")
 +set(CURL_DISABLE_HTTP OFF CACHE INTERNAL "Disable curl http protocol?")
 +set(CURL_DISABLE_IMAP ON CACHE INTERNAL "Disable curl imap protocol?")
 +set(CURL_DISABLE_LDAP ON CACHE INTERNAL "Disable curl ldap protocol?")
 +set(CURL_DISABLE_LDAPS ON CACHE INTERNAL "Disable curl ldaps protocol?")
 +set(CURL_DISABLE_POP3 ON CACHE INTERNAL "Disable curl pop3 protocol?")
 +set(CURL_DISABLE_PROXY OFF CACHE INTERNAL "Do not disable curl proxy")
 +set(CURL_DISABLE_RTSP ON CACHE INTERNAL "Disable curl rtsp protocol?")
 +set(CURL_DISABLE_SMTP ON CACHE INTERNAL "Disable curl smtp protocol?")
 +set(CURL_DISABLE_TELNET ON CACHE INTERNAL "Disable curl telnet protocol?")
 +set(CURL_DISABLE_TFTP ON CACHE INTERNAL "Disable curl tftp protocol?")
 +set(CURL_DISABLE_VERBOSE_STRINGS OFF CACHE INTERNAL "Do not disable curl verbosity")
 +set(CURL_HIDDEN_SYMBOLS OFF CACHE INTERNAL "No curl hidden symbols")
 +set(CURL_STATICLIB ON CACHE INTERNAL "Static curl")
 +set(DISABLED_THREADSAFE OFF CACHE INTERNAL "Curl can use thread-safe functions")
 +set(ENABLE_ARES OFF CACHE INTERNAL "No curl c-ares support")
 +set(ENABLE_CURLDEBUG OFF CACHE INTERNAL "No curl TrackMemory features")
 +set(ENABLE_DEBUG OFF CACHE INTERNAL "No curl debug features")
 +set(ENABLE_IPV6 OFF CACHE INTERNAL "No curl IPv6 support")
 +set(ENABLE_MANUAL OFF CACHE INTERNAL "No curl built-in manual")
 +set(ENABLE_THREADED_RESOLVER OFF CACHE INTERNAL "No curl POSIX threaded DNS lookup")
 +set(ENABLE_UNIX_SOCKETS OFF CACHE INTERNAL "No curl Unix domain sockets support")
 +set(HTTP_ONLY OFF CACHE INTERNAL "Curl is not http-only")
 +set(USE_WIN32_LDAP OFF CACHE INTERNAL "No curl Windows LDAP")
 +
 +# Windows Vista and above have inet_pton, but this will link on
 +# older versions and then the executable will fail to launch at
 +# runtime on older versions because no DLL provides the symbol.
 +if(WIN32)
 +  set(HAVE_INET_PTON 0 CACHE INTERNAL "Do not use inet_pton")
 +endif()
 +
 +# Starting with OSX 10.11 there is an unrelated libnetwork library which will
 +# be picked up during curl configuration. Linking against this library is
 +# unnecessary and breaks backward compatibility of the resulting binaries
 +# because libnetwork is unavailable on older OSX versions.
 +if(APPLE)
 +  set(HAVE_LIBNETWORK 0 CACHE INTERNAL "Do not use libnetwork")
 +endif(APPLE)
 +
 +# Disable warnings to avoid changing 3rd party code.
 +if(CMAKE_C_COMPILER_ID MATCHES
 +    "^(GNU|Clang|AppleClang|XL|VisualAge|SunPro|MIPSpro|HP|Intel)$")
 +  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w")
 +elseif(CMAKE_C_COMPILER_ID STREQUAL "PathScale")
 +  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -woffall")
 +endif()
 +
 +#***************************************************************************
 +#                                  _   _ ____  _
 +#  Project                     ___| | | |  _ \| |
 +#                             / __| | | | |_) | |
 +#                            | (__| |_| |  _ <| |___
 +#                             \___|\___/|_| \_\_____|
 +#
 +# Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at 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.
 +#
 +###########################################################################
 +# curl/libcurl CMake script
 +# by Tetetest and Sukender (Benoit Neil)
 +
 +# TODO:
 +# The output .so file lacks the soname number which we currently have within the lib/Makefile.am file
 +# Add full (4 or 5 libs) SSL support
 +# Add INSTALL target (EXTRA_DIST variables in Makefile.am may be moved to Makefile.inc so that CMake/CPack is aware of what's to include).
 +# Add CTests(?)
 +# Check on all possible platforms
 +# Test with as many configurations possible (With or without any option)
 +# Create scripts that help keeping the CMake build system up to date (to reduce maintenance). According to Tetetest:
 +#  - lists of headers that 'configure' checks for;
 +#  - curl-specific tests (the ones that are in m4/curl-*.m4 files);
 +#  - (most obvious thing:) curl version numbers.
 +# Add documentation subproject
 +#
 +# To check:
 +# (From Daniel Stenberg) The cmake build selected to run gcc with -fPIC on my box while the plain configure script did not.
 +# (From Daniel Stenberg) The gcc command line use neither -g nor any -O options. As a developer, I also treasure our configure scripts's --enable-debug option that sets a long range of "picky" compiler options.
 +cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
 +set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake;${CMAKE_MODULE_PATH}")
 +include(Utilities)
 +include(Macros)
 +include(CMakeDependentOption)
 +
 +project( CURL C )
 +
 +if(0) # This code not needed for building within CMake.
 +message(WARNING "the curl cmake build system is poorly maintained. Be aware")
 +endif()
 +
 +file (READ ${CURL_SOURCE_DIR}/include/curl/curlver.h CURL_VERSION_H_CONTENTS)
 +string (REGEX MATCH "#define LIBCURL_VERSION \"[^\"]*"
 +  CURL_VERSION ${CURL_VERSION_H_CONTENTS})
 +string (REGEX REPLACE "[^\"]+\"" "" CURL_VERSION ${CURL_VERSION})
 +string (REGEX MATCH "#define LIBCURL_VERSION_NUM 0x[0-9a-fA-F]+"
 +  CURL_VERSION_NUM ${CURL_VERSION_H_CONTENTS})
 +string (REGEX REPLACE "[^0]+0x" "" CURL_VERSION_NUM ${CURL_VERSION_NUM})
 +
 +include_regular_expression("^.*$")    # Sukender: Is it necessary?
 +
 +# Setup package meta-data
 +# SET(PACKAGE "curl")
 +if(0) # This code not needed for building within CMake.
 +message(STATUS "curl version=[${CURL_VERSION}]")
 +endif()
 +# SET(PACKAGE_TARNAME "curl")
 +# SET(PACKAGE_NAME "curl")
 +# SET(PACKAGE_VERSION "-")
 +# SET(PACKAGE_STRING "curl-")
 +# SET(PACKAGE_BUGREPORT "a suitable curl mailing list => https://curl.haxx.se/mail/")
 +set(OPERATING_SYSTEM "${CMAKE_SYSTEM_NAME}")
 +set(OS "\"${CMAKE_SYSTEM_NAME}\"")
 +
 +include_directories(${PROJECT_BINARY_DIR}/include/curl)
 +include_directories( ${CURL_SOURCE_DIR}/include )
 +
 +option(BUILD_CURL_EXE "Set to ON to build curl executable." ON)
 +option(CURL_STATICLIB "Set to ON to build libcurl with static linking." OFF)
 +option(ENABLE_ARES "Set to ON to enable c-ares support" OFF)
 +if(WIN32)
 +  CMAKE_DEPENDENT_OPTION(ENABLE_THREADED_RESOLVER
 +                         "Set to ON to enable threaded DNS lookup"
 +                         ON "NOT ENABLE_ARES"
 +                         OFF)
 +else()
 +  option(ENABLE_THREADED_RESOLVER "Set to ON to enable POSIX threaded DNS lookup" OFF)
 +endif()
 +option(ENABLE_DEBUG "Set to ON to enable curl debug features" OFF)
 +option(ENABLE_CURLDEBUG "Set to ON to build with TrackMemory feature enabled" OFF)
 +
 +if (ENABLE_DEBUG)
 +  # DEBUGBUILD will be defined only for Debug builds
 +  if(NOT CMAKE_VERSION VERSION_LESS 3.0)
 +    set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS $<$<CONFIG:Debug>:DEBUGBUILD>)
 +  else()
 +    set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_DEBUG DEBUGBUILD)
 +  endif()
 +  set(ENABLE_CURLDEBUG ON)
 +endif()
 +
 +if (ENABLE_CURLDEBUG)
 +  set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS CURLDEBUG)
 +endif()
 +
 +# initialize CURL_LIBS
 +set(CURL_LIBS "")
 +
 +if(ENABLE_THREADED_RESOLVER AND ENABLE_ARES)
 +  message(FATAL_ERROR "Options ENABLE_THREADED_RESOLVER and ENABLE_ARES are mutually exclusive")
 +endif()
 +
 +if(ENABLE_ARES)
 +  set(USE_ARES 1)
 +  find_package(CARES REQUIRED)
 +  list(APPEND CURL_LIBS ${CARES_LIBRARY} )
 +  set(CURL_LIBS ${CURL_LIBS} ${CARES_LIBRARY})
 +endif()
 +
 +if(MSVC)
 +  option(BUILD_RELEASE_DEBUG_DIRS "Set OFF to build each configuration to a separate directory" OFF)
 +  mark_as_advanced(BUILD_RELEASE_DEBUG_DIRS)
 +endif()
 +
 +if(0) # This code not needed for building within CMake.
 +include(CurlSymbolHiding)
 +endif()
 +
 +option(HTTP_ONLY "disables all protocols except HTTP (This overrides all CURL_DISABLE_* options)" OFF)
 +mark_as_advanced(HTTP_ONLY)
 +option(CURL_DISABLE_FTP "disables FTP" OFF)
 +mark_as_advanced(CURL_DISABLE_FTP)
 +option(CURL_DISABLE_LDAP "disables LDAP" OFF)
 +mark_as_advanced(CURL_DISABLE_LDAP)
 +option(CURL_DISABLE_TELNET "disables Telnet" OFF)
 +mark_as_advanced(CURL_DISABLE_TELNET)
 +option(CURL_DISABLE_DICT "disables DICT" OFF)
 +mark_as_advanced(CURL_DISABLE_DICT)
 +option(CURL_DISABLE_FILE "disables FILE" OFF)
 +mark_as_advanced(CURL_DISABLE_FILE)
 +option(CURL_DISABLE_TFTP "disables TFTP" OFF)
 +mark_as_advanced(CURL_DISABLE_TFTP)
 +option(CURL_DISABLE_HTTP "disables HTTP" OFF)
 +mark_as_advanced(CURL_DISABLE_HTTP)
 +
 +option(CURL_DISABLE_LDAPS "to disable LDAPS" OFF)
 +mark_as_advanced(CURL_DISABLE_LDAPS)
 +
 +option(CURL_DISABLE_RTSP "to disable RTSP" OFF)
 +mark_as_advanced(CURL_DISABLE_RTSP)
 +option(CURL_DISABLE_PROXY "to disable proxy" OFF)
 +mark_as_advanced(CURL_DISABLE_PROXY)
 +option(CURL_DISABLE_POP3 "to disable POP3" OFF)
 +mark_as_advanced(CURL_DISABLE_POP3)
 +option(CURL_DISABLE_IMAP "to disable IMAP" OFF)
 +mark_as_advanced(CURL_DISABLE_IMAP)
 +option(CURL_DISABLE_SMTP "to disable SMTP" OFF)
 +mark_as_advanced(CURL_DISABLE_SMTP)
 +option(CURL_DISABLE_GOPHER "to disable Gopher" OFF)
 +mark_as_advanced(CURL_DISABLE_GOPHER)
 +
 +if(HTTP_ONLY)
 +  set(CURL_DISABLE_FTP ON)
 +  set(CURL_DISABLE_LDAP ON)
 +  set(CURL_DISABLE_LDAPS ON)
 +  set(CURL_DISABLE_TELNET ON)
 +  set(CURL_DISABLE_DICT ON)
 +  set(CURL_DISABLE_FILE ON)
 +  set(CURL_DISABLE_TFTP ON)
 +  set(CURL_DISABLE_RTSP ON)
 +  set(CURL_DISABLE_POP3 ON)
 +  set(CURL_DISABLE_IMAP ON)
 +  set(CURL_DISABLE_SMTP ON)
 +  set(CURL_DISABLE_GOPHER ON)
 +endif()
 +
 +option(CURL_DISABLE_COOKIES "to disable cookies support" OFF)
 +mark_as_advanced(CURL_DISABLE_COOKIES)
 +
 +option(CURL_DISABLE_CRYPTO_AUTH "to disable cryptographic authentication" OFF)
 +mark_as_advanced(CURL_DISABLE_CRYPTO_AUTH)
 +option(CURL_DISABLE_VERBOSE_STRINGS "to disable verbose strings" OFF)
 +mark_as_advanced(CURL_DISABLE_VERBOSE_STRINGS)
 +option(DISABLED_THREADSAFE "Set to explicitly specify we don't want to use thread-safe functions" OFF)
 +mark_as_advanced(DISABLED_THREADSAFE)
 +option(ENABLE_IPV6 "Define if you want to enable IPv6 support" ON)
 +mark_as_advanced(ENABLE_IPV6)
 +if(ENABLE_IPV6 AND NOT WIN32)
 +  include(CheckStructHasMember)
 +  check_struct_has_member("struct sockaddr_in6" sin6_addr "netinet/in.h"
 +                          HAVE_SOCKADDR_IN6_SIN6_ADDR)
 +  check_struct_has_member("struct sockaddr_in6" sin6_scope_id "netinet/in.h"
 +                          HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID)
 +  if(NOT HAVE_SOCKADDR_IN6_SIN6_ADDR)
 +    message(WARNING "struct sockaddr_in6 not available, disabling IPv6 support")
 +    # Force the feature off as this name is used as guard macro...
 +    set(ENABLE_IPV6 OFF
 +        CACHE BOOL "Define if you want to enable IPv6 support" FORCE)
 +  endif()
 +endif()
 +
 +option(ENABLE_MANUAL "to provide the built-in manual" ON)
 +unset(USE_MANUAL CACHE) # TODO: cache NROFF/NROFF_MANOPT/USE_MANUAL vars?
 +if(ENABLE_MANUAL)
 +  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(USE_MANUAL 1)
 +        break()
 +      endif()
 +    endforeach()
 +    # No need for the temporary file
 +    file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/nroff-input.txt")
 +    if(NOT USE_MANUAL)
 +      message(WARNING "Found no *nroff option to get plaintext from man pages")
 +    endif()
 +  else()
 +    message(WARNING "Found no *nroff program")
 +  endif()
 +endif()
++# Required for building manual, docs, tests
++find_package(Perl REQUIRED)
 +
 +# We need ansi c-flags, especially on HP
 +set(CMAKE_C_FLAGS "${CMAKE_ANSI_CFLAGS} ${CMAKE_C_FLAGS}")
 +set(CMAKE_REQUIRED_FLAGS ${CMAKE_ANSI_CFLAGS})
 +
 +# Disable warnings on Borland to avoid changing 3rd party code.
 +if(BORLAND)
 +  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w-")
 +endif(BORLAND)
 +
 +# If we are on AIX, do the _ALL_SOURCE magic
 +if(${CMAKE_SYSTEM_NAME} MATCHES AIX)
 +  set(_ALL_SOURCE 1)
 +endif(${CMAKE_SYSTEM_NAME} MATCHES AIX)
 +
 +# Include all the necessary files for macros
 +include (CheckFunctionExists)
 +include (CheckIncludeFile)
 +include (CheckIncludeFiles)
 +include (CheckLibraryExists)
 +include (CheckSymbolExists)
 +include (CheckTypeSize)
 +include (CheckCSourceCompiles)
 +
 +# On windows preload settings
 +if(WIN32)
 +  set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -D_WINSOCKAPI_=")
 +  include(${CMAKE_CURRENT_SOURCE_DIR}/CMake/Platforms/WindowsCache.cmake)
 +endif(WIN32)
 +
 +if(ENABLE_THREADED_RESOLVER)
 +  if(WIN32)
 +    set(USE_THREADS_WIN32 ON)
 +  else()
 +    check_include_file_concat("pthread.h" HAVE_PTHREAD_H)
 +    if(HAVE_PTHREAD_H)
 +      set(CMAKE_THREAD_PREFER_PTHREAD 1)
 +      find_package(Threads)
 +      if(CMAKE_USE_PTHREADS_INIT)
 +        set(CURL_LIBS ${CURL_LIBS} ${CMAKE_THREAD_LIBS_INIT})
 +        set(USE_THREADS_POSIX 1)
 +      endif()
 +    endif()
 +  endif()
 +endif()
 +
 +# Check for all needed libraries
 +if(0) # This code not needed for building within CMake.
 +check_library_exists_concat("dl"     dlopen       HAVE_LIBDL)
 +else()
 +  # Use the cmake-defined dl libs as dl is should not be used
 +  # on HPUX, but rather dld this avoids a warning
 +  list(APPEND CURL_LIBS ${CMAKE_DL_LIBS})
 +endif()
 +check_library_exists_concat("socket" connect      HAVE_LIBSOCKET)
 +check_library_exists("c" gethostbyname "" NOT_NEED_LIBNSL)
 +
 +# Yellowtab Zeta needs different libraries than BeOS 5.
 +if(BEOS)
 +  set(NOT_NEED_LIBNSL 1)
 +  check_library_exists_concat("bind" gethostbyname HAVE_LIBBIND)
 +  check_library_exists_concat("bnetapi" closesocket HAVE_LIBBNETAPI)
 +endif(BEOS)
 +
 +check_library_exists_concat("network" recv HAVE_LIBNETWORK)
 +
 +if(NOT NOT_NEED_LIBNSL)
 +  check_library_exists_concat("nsl"    gethostbyname  HAVE_LIBNSL)
 +endif(NOT NOT_NEED_LIBNSL)
 +
 +check_function_exists(gethostname HAVE_GETHOSTNAME)
 +
 +if(WIN32)
 +  check_library_exists_concat("ws2_32" getch        HAVE_LIBWS2_32)
 +  check_library_exists_concat("winmm"  getch        HAVE_LIBWINMM)
 +endif()
 +
- set(USE_OPENSSL OFF)
- set(HAVE_LIBCRYPTO OFF)
- set(HAVE_LIBSSL OFF)
++# check SSL libraries
++# TODO support GNUTLS, NSS, POLARSSL, AXTLS, CYASSL
 +
- if(CMAKE_USE_OPENSSL)
-   find_package(OpenSSL)
-   if(OPENSSL_FOUND)
-     list(APPEND CURL_LIBS ${OPENSSL_LIBRARIES})
-     set(USE_OPENSSL ON)
-     set(HAVE_LIBCRYPTO ON)
-     set(HAVE_LIBSSL ON)
-     include_directories(${OPENSSL_INCLUDE_DIR})
-     set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
-     check_include_file("openssl/crypto.h" HAVE_OPENSSL_CRYPTO_H)
-     check_include_file("openssl/engine.h" HAVE_OPENSSL_ENGINE_H)
-     check_include_file("openssl/err.h"    HAVE_OPENSSL_ERR_H)
-     check_include_file("openssl/pem.h"    HAVE_OPENSSL_PEM_H)
-     check_include_file("openssl/pkcs12.h" HAVE_OPENSSL_PKCS12_H)
-     check_include_file("openssl/rsa.h"    HAVE_OPENSSL_RSA_H)
-     check_include_file("openssl/ssl.h"    HAVE_OPENSSL_SSL_H)
-     check_include_file("openssl/x509.h"   HAVE_OPENSSL_X509_H)
-     check_include_file("openssl/rand.h"   HAVE_OPENSSL_RAND_H)
- 
-     # Optionally build with a specific CA cert bundle.
-     if(CURL_CA_BUNDLE)
-       add_definitions(-DCURL_CA_BUNDLE="${CURL_CA_BUNDLE}")
-     endif()
-     # Optionally build with a specific CA cert dir.
-     if(CURL_CA_PATH)
-       add_definitions(-DCURL_CA_PATH="${CURL_CA_PATH}")
-     endif()
-   endif()
- elseif(WIN32)
-   # Use Windows SSL/TLS native implementation.
-   set(CURL_WINDOWS_SSPI ON)
- elseif(APPLE)
-   # Use OS X SSL/TLS native implementation if available on target version.
-   if(CMAKE_OSX_DEPLOYMENT_TARGET)
-     set(OSX_VERSION ${CMAKE_OSX_DEPLOYMENT_TARGET})
-   else()
-     execute_process(
-       COMMAND sw_vers -productVersion
-       OUTPUT_VARIABLE OSX_VERSION
-       OUTPUT_STRIP_TRAILING_WHITESPACE
-       )
++if(APPLE)
++  option(CMAKE_USE_DARWINSSL "enable Apple OS native SSL/TLS" OFF)
++endif()
++if(WIN32)
++  option(CMAKE_USE_WINSSL "enable Windows native SSL/TLS" OFF)
++  cmake_dependent_option(CURL_WINDOWS_SSPI "Use windows libraries to allow NTLM authentication without openssl" ON
++    CMAKE_USE_WINSSL OFF)
++endif()
++option(CMAKE_USE_MBEDTLS "Enable mbedTLS for SSL/TLS" OFF)
++
++set(openssl_default ON)
++if(WIN32 OR CMAKE_USE_DARWINSSL OR CMAKE_USE_WINSSL OR CMAKE_USE_MBEDTLS)
++  set(openssl_default OFF)
++endif()
++option(CMAKE_USE_OPENSSL "Use OpenSSL code. Experimental" ${openssl_default})
++
++collect_true(enabled_ssl_options enabled_ssl_options_count
++  CMAKE_USE_WINSSL
++  CMAKE_USE_DARWINSSL
++  CMAKE_USE_OPENSSL
++  CMAKE_USE_MBEDTLS
++)
++if(enabled_ssl_options_count GREATER 1)
++  message(FATAL_ERROR "Multiple SSL options specified: ${enabled_ssl_options}. Please pick at most one and disable the rest.")
++endif()
++
++if(CMAKE_USE_WINSSL)
++  set(SSL_ENABLED ON)
++  set(USE_SCHANNEL ON) # Windows native SSL/TLS support
++  set(USE_WINDOWS_SSPI ON) # CMAKE_USE_WINSSL implies CURL_WINDOWS_SSPI
++  list(APPEND CURL_LIBS "crypt32")
++endif()
++if(CURL_WINDOWS_SSPI)
++  set(USE_WINDOWS_SSPI ON)
++  set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -DSECURITY_WIN32")
++endif()
++
++if(CMAKE_USE_DARWINSSL)
++  find_library(COREFOUNDATION_FRAMEWORK "CoreFoundation")
++  if(NOT COREFOUNDATION_FRAMEWORK)
++      message(FATAL_ERROR "CoreFoundation framework not found")
 +  endif()
-   if(NOT OSX_VERSION VERSION_LESS 10.6 AND
-      CMAKE_C_COMPILER_ID MATCHES "GNU|Clang|AppleClang")
-     add_definitions(-DUSE_DARWINSSL)
-     list(APPEND CURL_LIBS
-       "-framework CoreFoundation"
-       "-framework Security"
-       )
++
++  find_library(SECURITY_FRAMEWORK "Security")
++  if(NOT SECURITY_FRAMEWORK)
++     message(FATAL_ERROR "Security framework not found")
 +  endif()
++
++  set(SSL_ENABLED ON)
++  set(USE_DARWINSSL ON)
++  list(APPEND CURL_LIBS "${COREFOUNDATION_FRAMEWORK}" "${SECURITY_FRAMEWORK}")
++endif()
++
++if(CMAKE_USE_OPENSSL)
++  find_package(OpenSSL REQUIRED)
++  set(SSL_ENABLED ON)
++  set(USE_OPENSSL ON)
++  set(HAVE_LIBCRYPTO ON)
++  set(HAVE_LIBSSL ON)
++  list(APPEND CURL_LIBS ${OPENSSL_LIBRARIES})
++  include_directories(${OPENSSL_INCLUDE_DIR})
++  set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
++  check_include_file("openssl/crypto.h" HAVE_OPENSSL_CRYPTO_H)
++  check_include_file("openssl/engine.h" HAVE_OPENSSL_ENGINE_H)
++  check_include_file("openssl/err.h"    HAVE_OPENSSL_ERR_H)
++  check_include_file("openssl/pem.h"    HAVE_OPENSSL_PEM_H)
++  check_include_file("openssl/pkcs12.h" HAVE_OPENSSL_PKCS12_H)
++  check_include_file("openssl/rsa.h"    HAVE_OPENSSL_RSA_H)
++  check_include_file("openssl/ssl.h"    HAVE_OPENSSL_SSL_H)
++  check_include_file("openssl/x509.h"   HAVE_OPENSSL_X509_H)
++  check_include_file("openssl/rand.h"   HAVE_OPENSSL_RAND_H)
++  check_symbol_exists(RAND_status "${CURL_INCLUDES}" HAVE_RAND_STATUS)
++  check_symbol_exists(RAND_screen "${CURL_INCLUDES}" HAVE_RAND_SCREEN)
++  check_symbol_exists(RAND_egd    "${CURL_INCLUDES}" HAVE_RAND_EGD)
++endif()
++
++if(CMAKE_USE_MBEDTLS)
++  find_package(MbedTLS REQUIRED)
++  set(SSL_ENABLED ON)
++  set(USE_MBEDTLS ON)
++  list(APPEND CURL_LIBS ${MBEDTLS_LIBRARIES})
++  include_directories(${MBEDTLS_INCLUDE_DIR})
 +endif()
 +
 +option(USE_NGHTTP2 "Use Nghttp2 library" OFF)
 +if(USE_NGHTTP2)
 +  find_package(NGHTTP2 REQUIRED)
 +  include_directories(${NGHTTP2_INCLUDE_DIRS})
 +  list(APPEND CURL_LIBS ${NGHTTP2_LIBRARIES})
 +endif()
 +
 +if(NOT CURL_DISABLE_LDAP)
 +  if(WIN32)
 +    option(USE_WIN32_LDAP "Use Windows LDAP implementation" ON)
 +    if(USE_WIN32_LDAP)
 +      check_library_exists_concat("wldap32" cldap_open HAVE_WLDAP32)
 +      if(NOT HAVE_WLDAP32)
 +        set(USE_WIN32_LDAP OFF)
 +      endif()
 +    endif()
 +  endif()
 +
 +  option(CMAKE_USE_OPENLDAP "Use OpenLDAP code." OFF)
 +  mark_as_advanced(CMAKE_USE_OPENLDAP)
 +  set(CMAKE_LDAP_LIB "ldap" CACHE STRING "Name or full path to ldap library")
 +  set(CMAKE_LBER_LIB "lber" CACHE STRING "Name or full path to lber library")
 +
 +  if(CMAKE_USE_OPENLDAP AND USE_WIN32_LDAP)
 +    message(FATAL_ERROR "Cannot use USE_WIN32_LDAP and CMAKE_USE_OPENLDAP at the same time")
 +  endif()
 +
 +  # Now that we know, we're not using windows LDAP...
 +  if(USE_WIN32_LDAP)
 +    check_include_file_concat("winldap.h" HAVE_WINLDAP_H)
 +    check_include_file_concat("winber.h"  HAVE_WINBER_H)
 +  else()
 +    # Check for LDAP
 +    set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_LIBRARIES})
 +    check_library_exists_concat(${CMAKE_LDAP_LIB} ldap_init HAVE_LIBLDAP)
 +    check_library_exists_concat(${CMAKE_LBER_LIB} ber_init HAVE_LIBLBER)
 +
 +    set(CMAKE_REQUIRED_INCLUDES_BAK ${CMAKE_REQUIRED_INCLUDES})
 +    set(CMAKE_LDAP_INCLUDE_DIR "" CACHE STRING "Path to LDAP include directory")
 +    if(CMAKE_LDAP_INCLUDE_DIR)
 +      list(APPEND CMAKE_REQUIRED_INCLUDES ${CMAKE_LDAP_INCLUDE_DIR})
 +    endif()
 +    check_include_file_concat("ldap.h"           HAVE_LDAP_H)
 +    check_include_file_concat("lber.h"           HAVE_LBER_H)
 +
 +    if(NOT HAVE_LDAP_H)
 +      message(STATUS "LDAP_H not found CURL_DISABLE_LDAP set ON")
 +      set(CURL_DISABLE_LDAP ON CACHE BOOL "" FORCE)
 +      set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES_BAK}) #LDAP includes won't be used
 +    elseif(NOT HAVE_LIBLDAP)
 +      message(STATUS "LDAP library '${CMAKE_LDAP_LIB}' not found CURL_DISABLE_LDAP set ON")
 +      set(CURL_DISABLE_LDAP ON CACHE BOOL "" FORCE)
 +      set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES_BAK}) #LDAP includes won't be used
 +    else()
 +      if(CMAKE_USE_OPENLDAP)
 +        set(USE_OPENLDAP ON)
 +      endif()
 +      if(CMAKE_LDAP_INCLUDE_DIR)
 +        include_directories(${CMAKE_LDAP_INCLUDE_DIR})
 +      endif()
 +      set(NEED_LBER_H ON)
 +      set(_HEADER_LIST)
 +      if(HAVE_WINDOWS_H)
 +        list(APPEND _HEADER_LIST "windows.h")
 +      endif()
 +      if(HAVE_SYS_TYPES_H)
 +        list(APPEND _HEADER_LIST "sys/types.h")
 +      endif()
 +      list(APPEND _HEADER_LIST "ldap.h")
 +
 +      set(_SRC_STRING "")
 +      foreach(_HEADER ${_HEADER_LIST})
 +        set(_INCLUDE_STRING "${_INCLUDE_STRING}#include <${_HEADER}>\n")
 +      endforeach()
 +
 +      set(_SRC_STRING
 +        "
 +        ${_INCLUDE_STRING}
 +        int main(int argc, char ** argv)
 +        {
 +          BerValue *bvp = NULL;
 +          BerElement *bep = ber_init(bvp);
 +          ber_free(bep, 1);
 +          return 0;
 +        }"
 +      )
 +      set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -DLDAP_DEPRECATED=1")
 +      list(APPEND CMAKE_REQUIRED_LIBRARIES ${CMAKE_LDAP_LIB})
 +      if(HAVE_LIBLBER)
 +        list(APPEND CMAKE_REQUIRED_LIBRARIES ${CMAKE_LBER_LIB})
 +      endif()
 +      check_c_source_compiles("${_SRC_STRING}" NOT_NEED_LBER_H)
 +
 +      if(NOT_NEED_LBER_H)
 +        set(NEED_LBER_H OFF)
 +      else()
 +        set(CURL_TEST_DEFINES "${CURL_TEST_DEFINES} -DNEED_LBER_H")
 +      endif()
 +    endif()
 +  endif()
 +
 +endif()
 +
 +# No ldap, no ldaps.
 +if(CURL_DISABLE_LDAP)
 +  if(NOT CURL_DISABLE_LDAPS)
 +    message(STATUS "LDAP needs to be enabled to support LDAPS")
 +    set(CURL_DISABLE_LDAPS ON CACHE BOOL "" FORCE)
 +  endif()
 +endif()
 +
 +if(NOT CURL_DISABLE_LDAPS)
 +  check_include_file_concat("ldap_ssl.h" HAVE_LDAP_SSL_H)
 +  check_include_file_concat("ldapssl.h"  HAVE_LDAPSSL_H)
 +endif()
 +
 +# Check for idn
 +check_library_exists_concat("idn2" idn2_lookup_ul HAVE_LIBIDN2)
 +
 +# Check for symbol dlopen (same as HAVE_LIBDL)
 +check_library_exists("${CURL_LIBS}" dlopen "" HAVE_DLOPEN)
 +
 +if(0) # This code not needed for building within CMake.
 +option(CURL_ZLIB "Set to ON to enable building curl with zlib support." ON)
 +set(HAVE_LIBZ OFF)
 +set(HAVE_ZLIB_H OFF)
 +set(HAVE_ZLIB OFF)
 +if(CURL_ZLIB)
 +  find_package(ZLIB QUIET)
 +  if(ZLIB_FOUND)
 +    set(HAVE_ZLIB_H ON)
 +    set(HAVE_ZLIB ON)
 +    set(HAVE_LIBZ ON)
 +    list(APPEND CURL_LIBS ${ZLIB_LIBRARIES})
 +    include_directories(${ZLIB_INCLUDE_DIRS})
 +    list(APPEND CMAKE_REQUIRED_INCLUDES ${ZLIB_INCLUDE_DIRS})
 +  endif()
 +endif()
 +endif()
 +
 +#-----------------------------------------------------------------------------
 +# CMake-specific curl code.
 +
 +if(CURL_SPECIAL_LIBZ)
 +  set(CURL_LIBS ${CURL_LIBS} "${CURL_SPECIAL_LIBZ}")
 +  include_directories(${CURL_SPECIAL_LIBZ_INCLUDES})
 +  set(HAVE_LIBZ 0)
 +  set(HAVE_ZLIB_H 0)
 +endif()
 +
 +#libSSH2
 +option(CMAKE_USE_LIBSSH2 "Use libSSH2" ON)
 +mark_as_advanced(CMAKE_USE_LIBSSH2)
 +set(USE_LIBSSH2 OFF)
 +set(HAVE_LIBSSH2 OFF)
 +set(HAVE_LIBSSH2_H OFF)
 +
 +if(CMAKE_USE_LIBSSH2)
 +  find_package(LibSSH2)
 +  if(LIBSSH2_FOUND)
 +    list(APPEND CURL_LIBS ${LIBSSH2_LIBRARY})
 +    set(CMAKE_REQUIRED_LIBRARIES ${LIBSSH2_LIBRARY})
 +    list(APPEND CMAKE_REQUIRED_INCLUDES "${LIBSSH2_INCLUDE_DIR}")
 +    include_directories("${LIBSSH2_INCLUDE_DIR}")
 +    set(HAVE_LIBSSH2 ON)
 +    set(USE_LIBSSH2 ON)
 +
 +    # find_package has already found the headers
 +    set(HAVE_LIBSSH2_H ON)
 +    set(CURL_INCLUDES ${CURL_INCLUDES} "${LIBSSH2_INCLUDE_DIR}/libssh2.h")
 +    set(CURL_TEST_DEFINES "${CURL_TEST_DEFINES} -DHAVE_LIBSSH2_H")
 +
 +    # now check for specific libssh2 symbols as they were added in different versions
 +    set(CMAKE_EXTRA_INCLUDE_FILES "libssh2.h")
 +    check_function_exists(libssh2_version           HAVE_LIBSSH2_VERSION)
 +    check_function_exists(libssh2_init              HAVE_LIBSSH2_INIT)
 +    check_function_exists(libssh2_exit              HAVE_LIBSSH2_EXIT)
 +    check_function_exists(libssh2_scp_send64        HAVE_LIBSSH2_SCP_SEND64)
 +    check_function_exists(libssh2_session_handshake HAVE_LIBSSH2_SESSION_HANDSHAKE)
 +    set(CMAKE_EXTRA_INCLUDE_FILES "")
 +
 +  endif(LIBSSH2_FOUND)
 +endif(CMAKE_USE_LIBSSH2)
 +
 +option(CMAKE_USE_GSSAPI "Use GSSAPI implementation (right now only Heimdal is supported with CMake build)" OFF)
 +mark_as_advanced(CMAKE_USE_GSSAPI)
 +
 +if(CMAKE_USE_GSSAPI)
 +  find_package(GSS)
 +
 +  set(HAVE_GSSAPI ${GSS_FOUND})
 +  if(GSS_FOUND)
 +
 +    message(STATUS "Found ${GSS_FLAVOUR} GSSAPI version: \"${GSS_VERSION}\"")
 +
 +    list(APPEND CMAKE_REQUIRED_INCLUDES ${GSS_INCLUDE_DIRECTORIES})
 +    check_include_file_concat("gssapi/gssapi.h"  HAVE_GSSAPI_GSSAPI_H)
 +    check_include_file_concat("gssapi/gssapi_generic.h" HAVE_GSSAPI_GSSAPI_GENERIC_H)
 +    check_include_file_concat("gssapi/gssapi_krb5.h" HAVE_GSSAPI_GSSAPI_KRB5_H)
 +
 +    if(GSS_FLAVOUR STREQUAL "Heimdal")
 +      set(HAVE_GSSHEIMDAL ON)
 +    else() # MIT
 +      set(HAVE_GSSMIT ON)
 +      set(_INCLUDE_LIST "")
 +      if(HAVE_GSSAPI_GSSAPI_H)
 +        list(APPEND _INCLUDE_LIST "gssapi/gssapi.h")
 +      endif()
 +      if(HAVE_GSSAPI_GSSAPI_GENERIC_H)
 +        list(APPEND _INCLUDE_LIST "gssapi/gssapi_generic.h")
 +      endif()
 +      if(HAVE_GSSAPI_GSSAPI_KRB5_H)
 +        list(APPEND _INCLUDE_LIST "gssapi/gssapi_krb5.h")
 +      endif()
 +
 +      string(REPLACE ";" " " _COMPILER_FLAGS_STR "${GSS_COMPILER_FLAGS}")
 +      string(REPLACE ";" " " _LINKER_FLAGS_STR "${GSS_LINKER_FLAGS}")
 +
 +      foreach(_dir ${GSS_LINK_DIRECTORIES})
 +        set(_LINKER_FLAGS_STR "${_LINKER_FLAGS_STR} -L\"${_dir}\"")
 +      endforeach()
 +
 +      set(CMAKE_REQUIRED_FLAGS "${_COMPILER_FLAGS_STR} ${_LINKER_FLAGS_STR}")
 +      set(CMAKE_REQUIRED_LIBRARIES ${GSS_LIBRARIES})
 +      check_symbol_exists("GSS_C_NT_HOSTBASED_SERVICE" ${_INCLUDE_LIST} HAVE_GSS_C_NT_HOSTBASED_SERVICE)
 +      if(NOT HAVE_GSS_C_NT_HOSTBASED_SERVICE)
 +        set(HAVE_OLD_GSSMIT ON)
 +      endif()
 +
 +    endif()
 +
 +    include_directories(${GSS_INCLUDE_DIRECTORIES})
 +    link_directories(${GSS_LINK_DIRECTORIES})
 +    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${GSS_COMPILER_FLAGS}")
 +    set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${GSS_LINKER_FLAGS}")
 +    set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GSS_LINKER_FLAGS}")
 +    list(APPEND CURL_LIBS ${GSS_LIBRARIES})
 +
 +  else()
 +    message(WARNING "GSSAPI support has been requested but no supporting libraries found. Skipping.")
 +  endif()
 +endif()
 +
 +option(ENABLE_UNIX_SOCKETS "Define if you want Unix domain sockets support" ON)
 +if(ENABLE_UNIX_SOCKETS)
 +  include(CheckStructHasMember)
 +  check_struct_has_member("struct sockaddr_un" sun_path "sys/un.h" USE_UNIX_SOCKETS)
 +else()
 +  unset(USE_UNIX_SOCKETS CACHE)
 +endif()
 +
 +
 +# Check for header files
 +if(NOT UNIX)
 +  check_include_file_concat("windows.h"      HAVE_WINDOWS_H)
 +  check_include_file_concat("winsock.h"      HAVE_WINSOCK_H)
 +  check_include_file_concat("ws2tcpip.h"     HAVE_WS2TCPIP_H)
 +  check_include_file_concat("winsock2.h"     HAVE_WINSOCK2_H)
-   if(CURL_WINDOWS_SSPI)
-     set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -DSECURITY_WIN32")
-     check_include_file_concat("sspi.h"       HAVE_SSPI_H)
-     if(HAVE_SSPI_H)
-       check_include_file_concat("schannel.h" HAVE_SCHANNEL_H)
-       set(USE_WINDOWS_SSPI ON)
-       if(HAVE_SCHANNEL_H)
-         set(USE_SCHANNEL ON)
-         set(SSL_ENABLED ON)
-         set(CURL_LIBS ${CURL_LIBS} "crypt32")
-       endif()
-     endif()
++  if(NOT CURL_WINDOWS_SSPI AND USE_OPENSSL)
++    set(CURL_LIBS ${CURL_LIBS} "crypt32")
 +  endif()
 +else()
 +  set(HAVE_WINDOWS_H 0)
 +  set(HAVE_WINSOCK_H 0)
 +  set(HAVE_WS2TCPIP_H 0)
 +  set(HAVE_WINSOCK2_H 0)
 +endif()
 +
 +check_include_file_concat("stdio.h"          HAVE_STDIO_H)
 +check_include_file_concat("inttypes.h"       HAVE_INTTYPES_H)
 +check_include_file_concat("sys/filio.h"      HAVE_SYS_FILIO_H)
 +check_include_file_concat("sys/ioctl.h"      HAVE_SYS_IOCTL_H)
 +check_include_file_concat("sys/param.h"      HAVE_SYS_PARAM_H)
 +check_include_file_concat("sys/poll.h"       HAVE_SYS_POLL_H)
 +check_include_file_concat("sys/resource.h"   HAVE_SYS_RESOURCE_H)
 +check_include_file_concat("sys/select.h"     HAVE_SYS_SELECT_H)
 +check_include_file_concat("sys/socket.h"     HAVE_SYS_SOCKET_H)
 +check_include_file_concat("sys/sockio.h"     HAVE_SYS_SOCKIO_H)
 +check_include_file_concat("sys/stat.h"       HAVE_SYS_STAT_H)
 +check_include_file_concat("sys/time.h"       HAVE_SYS_TIME_H)
 +check_include_file_concat("sys/types.h"      HAVE_SYS_TYPES_H)
 +check_include_file_concat("sys/uio.h"        HAVE_SYS_UIO_H)
 +check_include_file_concat("sys/un.h"         HAVE_SYS_UN_H)
 +check_include_file_concat("sys/utime.h"      HAVE_SYS_UTIME_H)
++check_include_file_concat("sys/xattr.h"      HAVE_SYS_XATTR_H)
 +check_include_file_concat("alloca.h"         HAVE_ALLOCA_H)
 +check_include_file_concat("arpa/inet.h"      HAVE_ARPA_INET_H)
 +check_include_file_concat("arpa/tftp.h"      HAVE_ARPA_TFTP_H)
 +check_include_file_concat("assert.h"         HAVE_ASSERT_H)
 +check_include_file_concat("crypto.h"         HAVE_CRYPTO_H)
 +check_include_file_concat("des.h"            HAVE_DES_H)
 +check_include_file_concat("err.h"            HAVE_ERR_H)
 +check_include_file_concat("errno.h"          HAVE_ERRNO_H)
 +check_include_file_concat("fcntl.h"          HAVE_FCNTL_H)
 +check_include_file_concat("idn2.h"           HAVE_IDN2_H)
 +check_include_file_concat("ifaddrs.h"        HAVE_IFADDRS_H)
 +check_include_file_concat("io.h"             HAVE_IO_H)
 +check_include_file_concat("krb.h"            HAVE_KRB_H)
 +check_include_file_concat("libgen.h"         HAVE_LIBGEN_H)
 +check_include_file_concat("limits.h"         HAVE_LIMITS_H)
 +check_include_file_concat("locale.h"         HAVE_LOCALE_H)
 +check_include_file_concat("net/if.h"         HAVE_NET_IF_H)
 +check_include_file_concat("netdb.h"          HAVE_NETDB_H)
 +check_include_file_concat("netinet/in.h"     HAVE_NETINET_IN_H)
 +check_include_file_concat("netinet/tcp.h"    HAVE_NETINET_TCP_H)
 +
 +check_include_file_concat("pem.h"            HAVE_PEM_H)
 +check_include_file_concat("poll.h"           HAVE_POLL_H)
 +check_include_file_concat("pwd.h"            HAVE_PWD_H)
 +check_include_file_concat("rsa.h"            HAVE_RSA_H)
 +check_include_file_concat("setjmp.h"         HAVE_SETJMP_H)
 +check_include_file_concat("sgtty.h"          HAVE_SGTTY_H)
 +check_include_file_concat("signal.h"         HAVE_SIGNAL_H)
 +check_include_file_concat("ssl.h"            HAVE_SSL_H)
 +check_include_file_concat("stdbool.h"        HAVE_STDBOOL_H)
 +check_include_file_concat("stdint.h"         HAVE_STDINT_H)
 +check_include_file_concat("stdio.h"          HAVE_STDIO_H)
 +check_include_file_concat("stdlib.h"         HAVE_STDLIB_H)
 +check_include_file_concat("string.h"         HAVE_STRING_H)
 +check_include_file_concat("strings.h"        HAVE_STRINGS_H)
 +check_include_file_concat("stropts.h"        HAVE_STROPTS_H)
 +check_include_file_concat("termio.h"         HAVE_TERMIO_H)
 +check_include_file_concat("termios.h"        HAVE_TERMIOS_H)
 +check_include_file_concat("time.h"           HAVE_TIME_H)
 +check_include_file_concat("unistd.h"         HAVE_UNISTD_H)
 +check_include_file_concat("utime.h"          HAVE_UTIME_H)
 +check_include_file_concat("x509.h"           HAVE_X509_H)
 +
 +check_include_file_concat("process.h"        HAVE_PROCESS_H)
 +check_include_file_concat("stddef.h"         HAVE_STDDEF_H)
 +check_include_file_concat("dlfcn.h"          HAVE_DLFCN_H)
 +check_include_file_concat("malloc.h"         HAVE_MALLOC_H)
 +check_include_file_concat("memory.h"         HAVE_MEMORY_H)
 +check_include_file_concat("netinet/if_ether.h" HAVE_NETINET_IF_ETHER_H)
 +check_include_file_concat("stdint.h"        HAVE_STDINT_H)
 +check_include_file_concat("sockio.h"        HAVE_SOCKIO_H)
 +check_include_file_concat("sys/utsname.h"   HAVE_SYS_UTSNAME_H)
 +
 +check_type_size(size_t  SIZEOF_SIZE_T)
 +check_type_size(ssize_t  SIZEOF_SSIZE_T)
 +check_type_size("long long"  SIZEOF_LONG_LONG)
 +check_type_size("long"  SIZEOF_LONG)
 +check_type_size("short"  SIZEOF_SHORT)
 +check_type_size("int"  SIZEOF_INT)
 +check_type_size("__int64"  SIZEOF___INT64)
 +check_type_size("time_t"  SIZEOF_TIME_T)
 +
 +# Make public versions of some type sizes for curlbuild.h.
 +foreach(t INT LONG LONG_LONG SSIZE_T)
 +  string(REPLACE "SIZEOF_" "CURL_SIZEOF_" CURL_SIZEOF_${t}_CODE "${SIZEOF_${t}_CODE}")
 +endforeach()
 +
 +if(HAVE_SIZEOF_LONG_LONG)
 +  set(HAVE_LONGLONG 1)
 +  set(HAVE_LL 1)
 +endif(HAVE_SIZEOF_LONG_LONG)
 +
 +find_file(RANDOM_FILE urandom /dev)
 +mark_as_advanced(RANDOM_FILE)
 +
 +# Check for some functions that are used
 +if(HAVE_LIBWS2_32)
 +  set(CMAKE_REQUIRED_LIBRARIES ws2_32)
 +elseif(HAVE_LIBSOCKET)
 +  set(CMAKE_REQUIRED_LIBRARIES socket)
 +endif()
 +
 +check_symbol_exists(basename      "${CURL_INCLUDES}" HAVE_BASENAME)
 +check_symbol_exists(socket        "${CURL_INCLUDES}" HAVE_SOCKET)
 +# poll on macOS is unreliable, it first did not exist, then was broken until
 +# fixed in 10.9 only to break again in 10.12.
 +if(NOT APPLE)
 +  check_symbol_exists(poll        "${CURL_INCLUDES}" HAVE_POLL)
 +endif()
 +check_symbol_exists(select        "${CURL_INCLUDES}" HAVE_SELECT)
 +check_symbol_exists(strdup        "${CURL_INCLUDES}" HAVE_STRDUP)
 +check_symbol_exists(strstr        "${CURL_INCLUDES}" HAVE_STRSTR)
 +check_symbol_exists(strtok_r      "${CURL_INCLUDES}" HAVE_STRTOK_R)
 +check_symbol_exists(strftime      "${CURL_INCLUDES}" HAVE_STRFTIME)
 +check_symbol_exists(uname         "${CURL_INCLUDES}" HAVE_UNAME)
 +check_symbol_exists(strcasecmp    "${CURL_INCLUDES}" HAVE_STRCASECMP)
 +check_symbol_exists(stricmp       "${CURL_INCLUDES}" HAVE_STRICMP)
 +check_symbol_exists(strcmpi       "${CURL_INCLUDES}" HAVE_STRCMPI)
 +check_symbol_exists(strncmpi      "${CURL_INCLUDES}" HAVE_STRNCMPI)
 +check_symbol_exists(alarm         "${CURL_INCLUDES}" HAVE_ALARM)
 +if(NOT HAVE_STRNCMPI)
 +  set(HAVE_STRCMPI)
 +endif(NOT HAVE_STRNCMPI)
 +check_symbol_exists(gethostbyaddr "${CURL_INCLUDES}" HAVE_GETHOSTBYADDR)
 +check_symbol_exists(gethostbyaddr_r "${CURL_INCLUDES}" HAVE_GETHOSTBYADDR_R)
 +check_symbol_exists(gettimeofday  "${CURL_INCLUDES}" HAVE_GETTIMEOFDAY)
 +check_symbol_exists(inet_addr     "${CURL_INCLUDES}" HAVE_INET_ADDR)
 +check_symbol_exists(inet_ntoa     "${CURL_INCLUDES}" HAVE_INET_NTOA)
 +check_symbol_exists(inet_ntoa_r   "${CURL_INCLUDES}" HAVE_INET_NTOA_R)
 +check_symbol_exists(tcsetattr     "${CURL_INCLUDES}" HAVE_TCSETATTR)
 +check_symbol_exists(tcgetattr     "${CURL_INCLUDES}" HAVE_TCGETATTR)
 +check_symbol_exists(perror        "${CURL_INCLUDES}" HAVE_PERROR)
 +check_symbol_exists(closesocket   "${CURL_INCLUDES}" HAVE_CLOSESOCKET)
 +check_symbol_exists(setvbuf       "${CURL_INCLUDES}" HAVE_SETVBUF)
 +check_symbol_exists(sigsetjmp     "${CURL_INCLUDES}" HAVE_SIGSETJMP)
 +check_symbol_exists(getpass_r     "${CURL_INCLUDES}" HAVE_GETPASS_R)
 +check_symbol_exists(strlcat       "${CURL_INCLUDES}" HAVE_STRLCAT)
 +check_symbol_exists(getpwuid      "${CURL_INCLUDES}" HAVE_GETPWUID)
 +check_symbol_exists(geteuid       "${CURL_INCLUDES}" HAVE_GETEUID)
 +check_symbol_exists(utime         "${CURL_INCLUDES}" HAVE_UTIME)
- if(CMAKE_USE_OPENSSL)
-   check_symbol_exists(RAND_status   "${CURL_INCLUDES}" HAVE_RAND_STATUS)
-   check_symbol_exists(RAND_screen   "${CURL_INCLUDES}" HAVE_RAND_SCREEN)
-   check_symbol_exists(RAND_egd      "${CURL_INCLUDES}" HAVE_RAND_EGD)
-   if(HAVE_LIBCRYPTO AND HAVE_LIBSSL)
-     set(USE_OPENSSL 1)
-   endif(HAVE_LIBCRYPTO AND HAVE_LIBSSL)
- endif(CMAKE_USE_OPENSSL)
 +check_symbol_exists(gmtime_r      "${CURL_INCLUDES}" HAVE_GMTIME_R)
 +check_symbol_exists(localtime_r   "${CURL_INCLUDES}" HAVE_LOCALTIME_R)
 +
 +check_symbol_exists(gethostbyname   "${CURL_INCLUDES}" HAVE_GETHOSTBYNAME)
 +check_symbol_exists(gethostbyname_r "${CURL_INCLUDES}" HAVE_GETHOSTBYNAME_R)
 +
 +check_symbol_exists(signal        "${CURL_INCLUDES}" HAVE_SIGNAL_FUNC)
 +check_symbol_exists(SIGALRM       "${CURL_INCLUDES}" HAVE_SIGNAL_MACRO)
 +if(HAVE_SIGNAL_FUNC AND HAVE_SIGNAL_MACRO)
 +  set(HAVE_SIGNAL 1)
 +endif(HAVE_SIGNAL_FUNC AND HAVE_SIGNAL_MACRO)
 +check_symbol_exists(uname          "${CURL_INCLUDES}" HAVE_UNAME)
 +check_symbol_exists(strtoll        "${CURL_INCLUDES}" HAVE_STRTOLL)
 +check_symbol_exists(_strtoi64      "${CURL_INCLUDES}" HAVE__STRTOI64)
 +check_symbol_exists(strerror_r     "${CURL_INCLUDES}" HAVE_STRERROR_R)
 +check_symbol_exists(siginterrupt   "${CURL_INCLUDES}" HAVE_SIGINTERRUPT)
 +check_symbol_exists(perror         "${CURL_INCLUDES}" HAVE_PERROR)
 +check_symbol_exists(fork           "${CURL_INCLUDES}" HAVE_FORK)
 +check_symbol_exists(getaddrinfo    "${CURL_INCLUDES}" HAVE_GETADDRINFO)
 +check_symbol_exists(freeaddrinfo   "${CURL_INCLUDES}" HAVE_FREEADDRINFO)
 +check_symbol_exists(freeifaddrs    "${CURL_INCLUDES}" HAVE_FREEIFADDRS)
 +check_symbol_exists(pipe           "${CURL_INCLUDES}" HAVE_PIPE)
 +check_symbol_exists(ftruncate      "${CURL_INCLUDES}" HAVE_FTRUNCATE)
 +check_symbol_exists(getprotobyname "${CURL_INCLUDES}" HAVE_GETPROTOBYNAME)
 +check_symbol_exists(getrlimit      "${CURL_INCLUDES}" HAVE_GETRLIMIT)
 +check_symbol_exists(setlocale      "${CURL_INCLUDES}" HAVE_SETLOCALE)
 +check_symbol_exists(setrlimit      "${CURL_INCLUDES}" HAVE_SETRLIMIT)
 +check_symbol_exists(fcntl          "${CURL_INCLUDES}" HAVE_FCNTL)
 +check_symbol_exists(ioctl          "${CURL_INCLUDES}" HAVE_IOCTL)
 +check_symbol_exists(setsockopt     "${CURL_INCLUDES}" HAVE_SETSOCKOPT)
 +
 +# symbol exists in win32, but function does not.
 +check_function_exists(inet_pton HAVE_INET_PTON)
 +
++check_symbol_exists(fsetxattr "${CURL_INCLUDES}" HAVE_FSETXATTR)
++if(HAVE_FSETXATTR)
++  foreach(CURL_TEST HAVE_FSETXATTR_5 HAVE_FSETXATTR_6)
++    curl_internal_test_run(${CURL_TEST})
++  endforeach(CURL_TEST)
++endif(HAVE_FSETXATTR)
++
 +# sigaction and sigsetjmp are special. Use special mechanism for
 +# detecting those, but only if previous attempt failed.
 +if(HAVE_SIGNAL_H)
 +  check_symbol_exists(sigaction "signal.h" HAVE_SIGACTION)
 +endif(HAVE_SIGNAL_H)
 +
 +if(NOT HAVE_SIGSETJMP)
 +  if(HAVE_SETJMP_H)
 +    check_symbol_exists(sigsetjmp "setjmp.h" HAVE_MACRO_SIGSETJMP)
 +    if(HAVE_MACRO_SIGSETJMP)
 +      set(HAVE_SIGSETJMP 1)
 +    endif(HAVE_MACRO_SIGSETJMP)
 +  endif(HAVE_SETJMP_H)
 +endif(NOT HAVE_SIGSETJMP)
 +
 +# If there is no stricmp(), do not allow LDAP to parse URLs
 +if(NOT HAVE_STRICMP)
 +  set(HAVE_LDAP_URL_PARSE 1)
 +endif(NOT HAVE_STRICMP)
 +
 +# Do curl specific tests
 +foreach(CURL_TEST
 +    HAVE_FCNTL_O_NONBLOCK
 +    HAVE_IOCTLSOCKET
 +    HAVE_IOCTLSOCKET_CAMEL
 +    HAVE_IOCTLSOCKET_CAMEL_FIONBIO
 +    HAVE_IOCTLSOCKET_FIONBIO
 +    HAVE_IOCTL_FIONBIO
 +    HAVE_IOCTL_SIOCGIFADDR
 +    HAVE_SETSOCKOPT_SO_NONBLOCK
 +    HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
 +    TIME_WITH_SYS_TIME
 +    HAVE_O_NONBLOCK
 +    HAVE_GETHOSTBYADDR_R_5
 +    HAVE_GETHOSTBYADDR_R_7
 +    HAVE_GETHOSTBYADDR_R_8
 +    HAVE_GETHOSTBYADDR_R_5_REENTRANT
 +    HAVE_GETHOSTBYADDR_R_7_REENTRANT
 +    HAVE_GETHOSTBYADDR_R_8_REENTRANT
 +    HAVE_GETHOSTBYNAME_R_3
 +    HAVE_GETHOSTBYNAME_R_5
 +    HAVE_GETHOSTBYNAME_R_6
 +    HAVE_GETHOSTBYNAME_R_3_REENTRANT
 +    HAVE_GETHOSTBYNAME_R_5_REENTRANT
 +    HAVE_GETHOSTBYNAME_R_6_REENTRANT
 +    HAVE_SOCKLEN_T
 +    HAVE_IN_ADDR_T
 +    HAVE_BOOL_T
 +    STDC_HEADERS
 +    RETSIGTYPE_TEST
 +    HAVE_INET_NTOA_R_DECL
 +    HAVE_INET_NTOA_R_DECL_REENTRANT
 +    HAVE_GETADDRINFO
 +    HAVE_FILE_OFFSET_BITS
 +    )
 +  curl_internal_test(${CURL_TEST})
 +endforeach(CURL_TEST)
 +
 +if(HAVE_FILE_OFFSET_BITS)
 +  set(_FILE_OFFSET_BITS 64)
 +  set(CMAKE_REQUIRED_FLAGS "-D_FILE_OFFSET_BITS=64")
 +endif(HAVE_FILE_OFFSET_BITS)
 +check_type_size("off_t"  SIZEOF_OFF_T)
 +set(CMAKE_REQUIRED_FLAGS)
 +
 +foreach(CURL_TEST
 +    HAVE_GLIBC_STRERROR_R
 +    HAVE_POSIX_STRERROR_R
 +    )
 +  curl_internal_test_run(${CURL_TEST})
 +endforeach(CURL_TEST)
 +
 +# Check for reentrant
 +foreach(CURL_TEST
 +    HAVE_GETHOSTBYADDR_R_5
 +    HAVE_GETHOSTBYADDR_R_7
 +    HAVE_GETHOSTBYADDR_R_8
 +    HAVE_GETHOSTBYNAME_R_3
 +    HAVE_GETHOSTBYNAME_R_5
 +    HAVE_GETHOSTBYNAME_R_6
 +    HAVE_INET_NTOA_R_DECL_REENTRANT)
 +  if(NOT ${CURL_TEST})
 +    if(${CURL_TEST}_REENTRANT)
 +      set(NEED_REENTRANT 1)
 +    endif(${CURL_TEST}_REENTRANT)
 +  endif(NOT ${CURL_TEST})
 +endforeach(CURL_TEST)
 +
 +if(NEED_REENTRANT)
 +  foreach(CURL_TEST
 +      HAVE_GETHOSTBYADDR_R_5
 +      HAVE_GETHOSTBYADDR_R_7
 +      HAVE_GETHOSTBYADDR_R_8
 +      HAVE_GETHOSTBYNAME_R_3
 +      HAVE_GETHOSTBYNAME_R_5
 +      HAVE_GETHOSTBYNAME_R_6)
 +    set(${CURL_TEST} 0)
 +    if(${CURL_TEST}_REENTRANT)
 +      set(${CURL_TEST} 1)
 +    endif(${CURL_TEST}_REENTRANT)
 +  endforeach(CURL_TEST)
 +endif(NEED_REENTRANT)
 +
 +if(HAVE_INET_NTOA_R_DECL_REENTRANT)
 +  set(HAVE_INET_NTOA_R_DECL 1)
 +  set(NEED_REENTRANT 1)
 +endif(HAVE_INET_NTOA_R_DECL_REENTRANT)
 +
 +# Some other minor tests
 +
 +if(NOT HAVE_IN_ADDR_T)
 +  set(in_addr_t "unsigned long")
 +endif(NOT HAVE_IN_ADDR_T)
 +
 +# Fix libz / zlib.h
 +
 +if(NOT CURL_SPECIAL_LIBZ)
 +  if(NOT HAVE_LIBZ)
 +    set(HAVE_ZLIB_H 0)
 +  endif(NOT HAVE_LIBZ)
 +
 +  if(NOT HAVE_ZLIB_H)
 +    set(HAVE_LIBZ 0)
 +  endif(NOT HAVE_ZLIB_H)
 +endif(NOT CURL_SPECIAL_LIBZ)
 +
 +# Check for nonblocking
 +set(HAVE_DISABLED_NONBLOCKING 1)
 +if(HAVE_FIONBIO OR
 +    HAVE_IOCTLSOCKET OR
 +    HAVE_IOCTLSOCKET_CASE OR
 +    HAVE_O_NONBLOCK)
 +  set(HAVE_DISABLED_NONBLOCKING)
 +endif(HAVE_FIONBIO OR
 +  HAVE_IOCTLSOCKET OR
 +  HAVE_IOCTLSOCKET_CASE OR
 +  HAVE_O_NONBLOCK)
 +
 +if(RETSIGTYPE_TEST)
 +  set(RETSIGTYPE void)
 +else(RETSIGTYPE_TEST)
 +  set(RETSIGTYPE int)
 +endif(RETSIGTYPE_TEST)
 +
 +if(CMAKE_COMPILER_IS_GNUCC AND APPLE)
 +  include(CheckCCompilerFlag)
 +  check_c_compiler_flag(-Wno-long-double HAVE_C_FLAG_Wno_long_double)
 +  if(HAVE_C_FLAG_Wno_long_double)
 +    # The Mac version of GCC warns about use of long double.  Disable it.
 +    get_source_file_property(MPRINTF_COMPILE_FLAGS mprintf.c COMPILE_FLAGS)
 +    if(MPRINTF_COMPILE_FLAGS)
 +      set(MPRINTF_COMPILE_FLAGS "${MPRINTF_COMPILE_FLAGS} -Wno-long-double")
 +    else(MPRINTF_COMPILE_FLAGS)
 +      set(MPRINTF_COMPILE_FLAGS "-Wno-long-double")
 +    endif(MPRINTF_COMPILE_FLAGS)
 +    set_source_files_properties(mprintf.c PROPERTIES
 +      COMPILE_FLAGS ${MPRINTF_COMPILE_FLAGS})
 +  endif(HAVE_C_FLAG_Wno_long_double)
 +endif(CMAKE_COMPILER_IS_GNUCC AND APPLE)
 +
 +if(HAVE_SOCKLEN_T)
 +  set(CURL_HAVE_SOCKLEN_T 1)
 +  set(CURL_TYPEOF_CURL_SOCKLEN_T "socklen_t")
 +  if(WIN32)
 +    set(CMAKE_EXTRA_INCLUDE_FILES "winsock2.h;ws2tcpip.h")
 +  elseif(HAVE_SYS_SOCKET_H)
 +    set(CMAKE_EXTRA_INCLUDE_FILES "sys/socket.h")
 +  endif()
 +  check_type_size("socklen_t" CURL_SIZEOF_CURL_SOCKLEN_T)
 +  set(CMAKE_EXTRA_INCLUDE_FILES)
 +  if(NOT HAVE_CURL_SIZEOF_CURL_SOCKLEN_T)
 +    message(FATAL_ERROR
 +     "Check for sizeof socklen_t failed, see CMakeFiles/CMakerror.log")
 +  endif()
 +else()
 +  set(CURL_HAVE_SOCKLEN_T 0)
 +endif()
 +
 +# TODO test which of these headers are required for the typedefs used in curlbuild.h
 +if(WIN32)
 +  set(CURL_PULL_WS2TCPIP_H ${HAVE_WS2TCPIP_H})
 +else()
 +  set(CURL_PULL_SYS_TYPES_H ${HAVE_SYS_TYPES_H})
 +  set(CURL_PULL_SYS_SOCKET_H ${HAVE_SYS_SOCKET_H})
 +  set(CURL_PULL_SYS_POLL_H ${HAVE_SYS_POLL_H})
 +endif()
 +set(CURL_PULL_STDINT_H ${HAVE_STDINT_H})
 +set(CURL_PULL_INTTYPES_H ${HAVE_INTTYPES_H})
 +
 +include(CMake/OtherTests.cmake)
 +
 +add_definitions(-DHAVE_CONFIG_H)
 +
 +# For windows, do not allow the compiler to use default target (Vista).
 +if(WIN32)
 +  add_definitions(-D_WIN32_WINNT=0x0501)
 +endif(WIN32)
 +
 +# For windows, all compilers used by cmake should support large files
 +if(WIN32)
 +  set(USE_WIN32_LARGE_FILES ON)
 +endif(WIN32)
 +
 +if(MSVC)
 +  add_definitions(-D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE)
 +endif(MSVC)
 +
 +# Ugly (but functional) way to include "Makefile.inc" by transforming it (= regenerate it).
 +function(TRANSFORM_MAKEFILE_INC INPUT_FILE OUTPUT_FILE)
 +  file(READ ${INPUT_FILE} MAKEFILE_INC_TEXT)
 +  string(REPLACE "$(top_srcdir)"   "\${CURL_SOURCE_DIR}" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})
 +  string(REPLACE "$(top_builddir)" "\${CURL_BINARY_DIR}" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})
 +
-   string(REGEX REPLACE "\\\\\n" "§!§" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})
++  string(REGEX REPLACE "\\\\\n" "!π!α!" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})
 +  string(REGEX REPLACE "([a-zA-Z_][a-zA-Z0-9_]*)[\t ]*=[\t ]*([^\n]*)" "SET(\\1 \\2)" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})
-   string(REPLACE "§!§" "\n" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})
++  string(REPLACE "!π!α!" "\n" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})
 +
 +  string(REGEX REPLACE "\\$\\(([a-zA-Z_][a-zA-Z0-9_]*)\\)" "\${\\1}" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})    # Replace $() with ${}
 +  string(REGEX REPLACE "@([a-zA-Z_][a-zA-Z0-9_]*)@" "\${\\1}" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})    # Replace @@ with ${}, even if that may not be read by CMake scripts.
 +  file(WRITE ${OUTPUT_FILE} ${MAKEFILE_INC_TEXT})
 +
 +endfunction()
 +
++add_subdirectory(docs)
 +add_subdirectory(lib)
 +if(BUILD_CURL_EXE)
 +  add_subdirectory(src)
 +endif()
 +
 +#-----------------------------------------------------------------------------
 +# CMake-specific curl code.
 +add_executable(LIBCURL curltest.c)
 +target_link_libraries(LIBCURL cmcurl)
 +
 +if(CMAKE_CURL_TEST_URL)
 +  add_test(curl LIBCURL ${CMAKE_CURL_TEST_URL})
 +endif()
 +
 +install(FILES COPYING DESTINATION ${CMAKE_DOC_DIR}/cmcurl)
 +#-----------------------------------------------------------------------------
 +
 +if(0) # This code not needed for building within CMake.
 +include(CTest)
 +if(BUILD_TESTING)
 +  add_subdirectory(tests)
 +endif()
 +
- # TODO support GNUTLS, NSS, POLARSSL, AXTLS, CYASSL, WINSSL, DARWINSSL
- if(USE_OPENSSL)
-   set(SSL_ENABLED 1)
- endif()
- 
 +# Helper to populate a list (_items) with a label when conditions (the remaining
 +# args) are satisfied
 +function(_add_if label)
 +  # TODO need to disable policy CMP0054 (CMake 3.1) to allow this indirection
 +  if(${ARGN})
 +    set(_items ${_items} "${label}" PARENT_SCOPE)
 +  endif()
 +endfunction()
 +
 +# Clear list and try to detect available features
 +set(_items)
 +_add_if("WinSSL"        SSL_ENABLED AND USE_WINDOWS_SSPI)
 +_add_if("OpenSSL"       SSL_ENABLED AND USE_OPENSSL)
++_add_if("DarwinSSL"     SSL_ENABLED AND USE_DARWINSSL)
++_add_if("mbedTLS"       SSL_ENABLED AND USE_MBEDTLS)
 +_add_if("IPv6"          ENABLE_IPV6)
 +_add_if("unix-sockets"  USE_UNIX_SOCKETS)
 +_add_if("libz"          HAVE_LIBZ)
 +_add_if("AsynchDNS"     USE_ARES OR USE_THREADS_POSIX OR USE_THREADS_WIN32)
 +_add_if("IDN"           HAVE_LIBIDN2)
 +_add_if("Largefile"     (CURL_SIZEOF_CURL_OFF_T GREATER 4) AND
 +                        ((SIZEOF_OFF_T GREATER 4) OR USE_WIN32_LARGE_FILES))
 +# TODO SSP1 (WinSSL) check is missing
 +_add_if("SSPI"          USE_WINDOWS_SSPI)
 +_add_if("GSS-API"       HAVE_GSSAPI)
 +# TODO SSP1 missing for SPNEGO
 +_add_if("SPNEGO"        NOT CURL_DISABLE_CRYPTO_AUTH AND
 +                        (HAVE_GSSAPI OR USE_WINDOWS_SSPI))
 +_add_if("Kerberos"      NOT CURL_DISABLE_CRYPTO_AUTH AND
 +                        (HAVE_GSSAPI OR USE_WINDOWS_SSPI))
 +# NTLM support requires crypto function adaptions from various SSL libs
- # TODO alternative SSL libs tests for SSP1, GNUTLS, NSS, DARWINSSL
++# TODO alternative SSL libs tests for SSP1, GNUTLS, NSS
 +if(NOT CURL_DISABLE_CRYPTO_AUTH AND (USE_OPENSSL OR
-    USE_WINDOWS_SSPI OR GNUTLS_ENABLED OR NSS_ENABLED OR DARWINSSL_ENABLED))
++   USE_WINDOWS_SSPI OR GNUTLS_ENABLED OR NSS_ENABLED OR USE_DARWINSSL OR USE_MBEDTLS))
 +  _add_if("NTLM"        1)
 +  # TODO missing option (autoconf: --enable-ntlm-wb)
 +  _add_if("NTLM_WB"     NOT CURL_DISABLE_HTTP AND NTLM_WB_ENABLED)
 +endif()
 +# TODO missing option (--enable-tls-srp), depends on GNUTLS_SRP/OPENSSL_SRP
 +_add_if("TLS-SRP"       USE_TLS_SRP)
 +# TODO option --with-nghttp2 tests for nghttp2 lib and nghttp2/nghttp2.h header
 +_add_if("HTTP2"         USE_NGHTTP2)
 +string(REPLACE ";" " " SUPPORT_FEATURES "${_items}")
 +message(STATUS "Enabled features: ${SUPPORT_FEATURES}")
 +
 +# Clear list and try to detect available protocols
 +set(_items)
 +_add_if("HTTP"          NOT CURL_DISABLE_HTTP)
 +_add_if("HTTPS"         NOT CURL_DISABLE_HTTP AND SSL_ENABLED)
 +_add_if("FTP"           NOT CURL_DISABLE_FTP)
 +_add_if("FTPS"          NOT CURL_DISABLE_FTP AND SSL_ENABLED)
 +_add_if("FILE"          NOT CURL_DISABLE_FILE)
 +_add_if("TELNET"        NOT CURL_DISABLE_TELNET)
 +_add_if("LDAP"          NOT CURL_DISABLE_LDAP)
 +# CURL_DISABLE_LDAP implies CURL_DISABLE_LDAPS
 +# TODO check HAVE_LDAP_SSL (in autoconf this is enabled with --enable-ldaps)
 +_add_if("LDAPS"         NOT CURL_DISABLE_LDAPS AND
 +                        ((USE_OPENLDAP AND SSL_ENABLED) OR
 +                        (NOT USE_OPENLDAP AND HAVE_LDAP_SSL)))
 +_add_if("DICT"          NOT CURL_DISABLE_DICT)
 +_add_if("TFTP"          NOT CURL_DISABLE_TFTP)
 +_add_if("GOPHER"        NOT CURL_DISABLE_GOPHER)
 +_add_if("POP3"          NOT CURL_DISABLE_POP3)
 +_add_if("POP3S"         NOT CURL_DISABLE_POP3 AND SSL_ENABLED)
 +_add_if("IMAP"          NOT CURL_DISABLE_IMAP)
 +_add_if("IMAPS"         NOT CURL_DISABLE_IMAP AND SSL_ENABLED)
 +_add_if("SMTP"          NOT CURL_DISABLE_SMTP)
 +_add_if("SMTPS"         NOT CURL_DISABLE_SMTP AND SSL_ENABLED)
 +_add_if("SCP"           USE_LIBSSH2)
 +_add_if("SFTP"          USE_LIBSSH2)
 +_add_if("RTSP"          NOT CURL_DISABLE_RTSP)
 +_add_if("RTMP"          USE_LIBRTMP)
 +list(SORT _items)
 +string(REPLACE ";" " " SUPPORT_PROTOCOLS "${_items}")
 +message(STATUS "Enabled protocols: ${SUPPORT_PROTOCOLS}")
 +
 +# curl-config needs the following options to be set.
 +set(CC                      "${CMAKE_C_COMPILER}")
 +# TODO probably put a -D... options here?
 +set(CONFIGURE_OPTIONS       "")
 +# TODO when to set "-DCURL_STATICLIB" for CPPFLAG_CURL_STATICLIB?
 +set(CPPFLAG_CURL_STATICLIB  "")
 +# TODO need to set this (see CURL_CHECK_CA_BUNDLE in acinclude.m4)
 +set(CURL_CA_BUNDLE          "")
 +set(CURLVERSION             "${CURL_VERSION}")
 +set(ENABLE_SHARED           "yes")
 +if(CURL_STATICLIB)
 +  set(ENABLE_STATIC         "yes")
 +else()
 +  set(ENABLE_STATIC         "no")
 +endif()
 +set(exec_prefix             "\${prefix}")
 +set(includedir              "\${prefix}/include")
 +set(LDFLAGS                 "${CMAKE_SHARED_LINKER_FLAGS}")
 +set(LIBCURL_LIBS            "")
 +set(libdir                  "${CMAKE_INSTALL_PREFIX}/lib")
 +foreach(_lib ${CMAKE_C_IMPLICIT_LINK_LIBRARIES} ${CURL_LIBS})
 +  if(_lib MATCHES ".*/.*")
 +    set(LIBCURL_LIBS          "${LIBCURL_LIBS} ${_lib}")
 +  else()
 +    set(LIBCURL_LIBS          "${LIBCURL_LIBS} -l${_lib}")
 +  endif()
 +endforeach()
 +# "a" (Linux) or "lib" (Windows)
 +string(REPLACE "." "" libext "${CMAKE_STATIC_LIBRARY_SUFFIX}")
 +set(prefix                  "${CMAKE_INSTALL_PREFIX}")
 +# Set this to "yes" to append all libraries on which -lcurl is dependent
 +set(REQUIRE_LIB_DEPS        "no")
 +# SUPPORT_FEATURES
 +# SUPPORT_PROTOCOLS
 +set(VERSIONNUM              "${CURL_VERSION_NUM}")
 +
 +# Finally generate a "curl-config" matching this config
 +configure_file("${CURL_SOURCE_DIR}/curl-config.in"
 +               "${CURL_BINARY_DIR}/curl-config" @ONLY)
 +install(FILES "${CURL_BINARY_DIR}/curl-config"
 +        DESTINATION bin
 +        PERMISSIONS
 +          OWNER_READ OWNER_WRITE OWNER_EXECUTE
 +          GROUP_READ GROUP_EXECUTE
 +          WORLD_READ WORLD_EXECUTE)
 +
 +# Finally generate a pkg-config file matching this config
 +configure_file("${CURL_SOURCE_DIR}/libcurl.pc.in"
 +               "${CURL_BINARY_DIR}/libcurl.pc" @ONLY)
 +install(FILES "${CURL_BINARY_DIR}/libcurl.pc"
 +        DESTINATION lib/pkgconfig)
 +
 +# This needs to be run very last so other parts of the scripts can take advantage of this.
 +if(NOT CURL_CONFIG_HAS_BEEN_RUN_BEFORE)
 +  set(CURL_CONFIG_HAS_BEEN_RUN_BEFORE 1 CACHE INTERNAL "Flag to track whether this is the first time running CMake or if CMake has been configured before")
 +endif()
 +
 +# Installation.
 +# First, install generated curlbuild.h
 +install(FILES "${CMAKE_CURRENT_BINARY_DIR}/include/curl/curlbuild.h"
 +    DESTINATION include/curl )
 +# Next, install other headers excluding curlbuild.h
 +install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/curl"
 +    DESTINATION include
 +    FILES_MATCHING PATTERN "*.h"
 +    PATTERN "curlbuild.h" EXCLUDE)
 +
 +
 +# Workaround for MSVS10 to avoid the Dialog Hell
 +# FIXME: This could be removed with future version of CMake.
 +if(MSVC_VERSION EQUAL 1600)
 +  set(CURL_SLN_FILENAME "${CMAKE_CURRENT_BINARY_DIR}/CURL.sln")
 +  if(EXISTS "${CURL_SLN_FILENAME}")
 +    file(APPEND "${CURL_SLN_FILENAME}" "\n# This should be regenerated!\n")
 +  endif()
 +endif()
 +endif()
diff --cc Utilities/cmcurl/include/curl/curl.h
index daca8d1,0000000..b19dd42
mode 100644,000000..100644
--- a/Utilities/cmcurl/include/curl/curl.h
+++ b/Utilities/cmcurl/include/curl/curl.h
@@@ -1,2530 -1,0 +1,2554 @@@
 +#ifndef __CURL_CURL_H
 +#define __CURL_CURL_H
 +/***************************************************************************
 + *                                  _   _ ____  _
 + *  Project                     ___| | | |  _ \| |
 + *                             / __| | | | |_) | |
 + *                            | (__| |_| |  _ <| |___
 + *                             \___|\___/|_| \_\_____|
 + *
-  * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
++ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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 you have libcurl problems, all docs and details are found here:
 + *   https://curl.haxx.se/libcurl/
 + *
 + * curl-library mailing list subscription and unsubscription web interface:
 + *   https://cool.haxx.se/mailman/listinfo/curl-library/
 + */
 +
 +#ifdef CURL_NO_OLDIES
 +#define CURL_STRICTER
 +#endif
 +
 +#include "curlver.h"         /* libcurl version defines   */
++#include "system.h"          /* determine things run-time */
 +#include "cmcurl/include/curl/curlbuild.h" /* libcurl build definitions */
 +#include "curlrules.h"       /* libcurl rules enforcement */
 +
 +/*
 + * Define WIN32 when build target is Win32 API
 + */
 +
 +#if (defined(_WIN32) || defined(__WIN32__)) && \
 +     !defined(WIN32) && !defined(__SYMBIAN32__)
 +#define WIN32
 +#endif
 +
 +#include <stdio.h>
 +#include <limits.h>
 +
 +#if defined(__FreeBSD__) && (__FreeBSD__ >= 2)
 +/* Needed for __FreeBSD_version symbol definition */
 +#include <osreldate.h>
 +#endif
 +
 +/* The include stuff here below is mainly for time_t! */
 +#include <sys/types.h>
 +#include <time.h>
 +
 +#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(__CYGWIN__)
 +#if !(defined(_WINSOCKAPI_) || defined(_WINSOCK_H) || \
 +      defined(__LWIP_OPT_H__) || defined(LWIP_HDR_OPT_H))
 +/* The check above prevents the winsock2 inclusion if winsock.h already was
 +   included, since they can't co-exist without problems */
 +#include <winsock2.h>
 +#include <ws2tcpip.h>
 +#endif
 +#endif
 +
 +/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish
 +   libc5-based Linux systems. Only include it on systems that are known to
 +   require it! */
 +#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \
 +    defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY) || \
 +    defined(ANDROID) || defined(__ANDROID__) || defined(__OpenBSD__) || \
 +   (defined(__FreeBSD_version) && (__FreeBSD_version < 800000))
 +#include <sys/select.h>
 +#endif
 +
 +#if !defined(WIN32) && !defined(_WIN32_WCE)
 +#include <sys/socket.h>
 +#endif
 +
 +#if !defined(WIN32) && !defined(__WATCOMC__) && !defined(__VXWORKS__)
 +#include <sys/time.h>
 +#endif
 +
 +#if defined __BEOS__ || defined __HAIKU__
 +#include <support/SupportDefs.h>
 +#endif
 +
 +#ifdef  __cplusplus
 +extern "C" {
 +#endif
 +
 +#if defined(BUILDING_LIBCURL) || defined(CURL_STRICTER)
 +typedef struct Curl_easy CURL;
 +typedef struct Curl_share CURLSH;
 +#else
 +typedef void CURL;
 +typedef void CURLSH;
 +#endif
 +
 +/*
 + * libcurl external API function linkage decorations.
 + */
 +
 +#ifdef CURL_STATICLIB
 +#  define CURL_EXTERN
 +#elif defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__)
 +#  if defined(BUILDING_LIBCURL)
 +#    define CURL_EXTERN  __declspec(dllexport)
 +#  else
 +#    define CURL_EXTERN  __declspec(dllimport)
 +#  endif
 +#elif defined(BUILDING_LIBCURL) && defined(CURL_HIDDEN_SYMBOLS)
 +#  define CURL_EXTERN CURL_EXTERN_SYMBOL
 +#else
 +#  define CURL_EXTERN
 +#endif
 +
 +#ifndef curl_socket_typedef
 +/* socket typedef */
 +#if defined(WIN32) && !defined(__LWIP_OPT_H__) && !defined(LWIP_HDR_OPT_H)
 +typedef SOCKET curl_socket_t;
 +#define CURL_SOCKET_BAD INVALID_SOCKET
 +#else
 +typedef int curl_socket_t;
 +#define CURL_SOCKET_BAD -1
 +#endif
 +#define curl_socket_typedef
 +#endif /* curl_socket_typedef */
 +
 +struct curl_httppost {
 +  struct curl_httppost *next;       /* next entry in the list */
 +  char *name;                       /* pointer to allocated name */
 +  long namelength;                  /* length of name length */
 +  char *contents;                   /* pointer to allocated data contents */
 +  long contentslength;              /* length of contents field, see also
 +                                       CURL_HTTPPOST_LARGE */
 +  char *buffer;                     /* pointer to allocated buffer contents */
 +  long bufferlength;                /* length of buffer field */
 +  char *contenttype;                /* Content-Type */
 +  struct curl_slist *contentheader; /* list of extra headers for this form */
 +  struct curl_httppost *more;       /* if one field name has more than one
 +                                       file, this link should link to following
 +                                       files */
 +  long flags;                       /* as defined below */
 +
 +/* specified content is a file name */
 +#define CURL_HTTPPOST_FILENAME (1<<0)
 +/* specified content is a file name */
 +#define CURL_HTTPPOST_READFILE (1<<1)
 +/* name is only stored pointer do not free in formfree */
 +#define CURL_HTTPPOST_PTRNAME (1<<2)
 +/* contents is only stored pointer do not free in formfree */
 +#define CURL_HTTPPOST_PTRCONTENTS (1<<3)
 +/* upload file from buffer */
 +#define CURL_HTTPPOST_BUFFER (1<<4)
 +/* upload file from pointer contents */
 +#define CURL_HTTPPOST_PTRBUFFER (1<<5)
 +/* upload file contents by using the regular read callback to get the data and
 +   pass the given pointer as custom pointer */
 +#define CURL_HTTPPOST_CALLBACK (1<<6)
 +/* use size in 'contentlen', added in 7.46.0 */
 +#define CURL_HTTPPOST_LARGE (1<<7)
 +
 +  char *showfilename;               /* The file name to show. If not set, the
 +                                       actual file name will be used (if this
 +                                       is a file part) */
 +  void *userp;                      /* custom pointer used for
 +                                       HTTPPOST_CALLBACK posts */
 +  curl_off_t contentlen;            /* alternative length of contents
 +                                       field. Used if CURL_HTTPPOST_LARGE is
 +                                       set. Added in 7.46.0 */
 +};
 +
 +/* This is the CURLOPT_PROGRESSFUNCTION callback proto. It is now considered
 +   deprecated but was the only choice up until 7.31.0 */
 +typedef int (*curl_progress_callback)(void *clientp,
 +                                      double dltotal,
 +                                      double dlnow,
 +                                      double ultotal,
 +                                      double ulnow);
 +
 +/* This is the CURLOPT_XFERINFOFUNCTION callback proto. It was introduced in
 +   7.32.0, it avoids floating point and provides more detailed information. */
 +typedef int (*curl_xferinfo_callback)(void *clientp,
 +                                      curl_off_t dltotal,
 +                                      curl_off_t dlnow,
 +                                      curl_off_t ultotal,
 +                                      curl_off_t ulnow);
 +
++#ifndef CURL_MAX_READ_SIZE
++  /* The maximum receive buffer size configurable via CURLOPT_BUFFERSIZE. */
++#define CURL_MAX_READ_SIZE 524288
++#endif
++
 +#ifndef CURL_MAX_WRITE_SIZE
 +  /* Tests have proven that 20K is a very bad buffer size for uploads on
 +     Windows, while 16K for some odd reason performed a lot better.
 +     We do the ifndef check to allow this value to easier be changed at build
 +     time for those who feel adventurous. The practical minimum is about
 +     400 bytes since libcurl uses a buffer of this size as a scratch area
 +     (unrelated to network send operations). */
 +#define CURL_MAX_WRITE_SIZE 16384
 +#endif
 +
 +#ifndef CURL_MAX_HTTP_HEADER
 +/* The only reason to have a max limit for this is to avoid the risk of a bad
 +   server feeding libcurl with a never-ending header that will cause reallocs
 +   infinitely */
 +#define CURL_MAX_HTTP_HEADER (100*1024)
 +#endif
 +
 +/* This is a magic return code for the write callback that, when returned,
 +   will signal libcurl to pause receiving on the current transfer. */
 +#define CURL_WRITEFUNC_PAUSE 0x10000001
 +
 +typedef size_t (*curl_write_callback)(char *buffer,
 +                                      size_t size,
 +                                      size_t nitems,
 +                                      void *outstream);
 +
 +
 +
 +/* enumeration of file types */
 +typedef enum {
 +  CURLFILETYPE_FILE = 0,
 +  CURLFILETYPE_DIRECTORY,
 +  CURLFILETYPE_SYMLINK,
 +  CURLFILETYPE_DEVICE_BLOCK,
 +  CURLFILETYPE_DEVICE_CHAR,
 +  CURLFILETYPE_NAMEDPIPE,
 +  CURLFILETYPE_SOCKET,
 +  CURLFILETYPE_DOOR, /* is possible only on Sun Solaris now */
 +
 +  CURLFILETYPE_UNKNOWN /* should never occur */
 +} curlfiletype;
 +
 +#define CURLFINFOFLAG_KNOWN_FILENAME    (1<<0)
 +#define CURLFINFOFLAG_KNOWN_FILETYPE    (1<<1)
 +#define CURLFINFOFLAG_KNOWN_TIME        (1<<2)
 +#define CURLFINFOFLAG_KNOWN_PERM        (1<<3)
 +#define CURLFINFOFLAG_KNOWN_UID         (1<<4)
 +#define CURLFINFOFLAG_KNOWN_GID         (1<<5)
 +#define CURLFINFOFLAG_KNOWN_SIZE        (1<<6)
 +#define CURLFINFOFLAG_KNOWN_HLINKCOUNT  (1<<7)
 +
 +/* Content of this structure depends on information which is known and is
 +   achievable (e.g. by FTP LIST parsing). Please see the url_easy_setopt(3) man
 +   page for callbacks returning this structure -- some fields are mandatory,
 +   some others are optional. The FLAG field has special meaning. */
 +struct curl_fileinfo {
 +  char *filename;
 +  curlfiletype filetype;
 +  time_t time;
 +  unsigned int perm;
 +  int uid;
 +  int gid;
 +  curl_off_t size;
 +  long int hardlinks;
 +
 +  struct {
 +    /* If some of these fields is not NULL, it is a pointer to b_data. */
 +    char *time;
 +    char *perm;
 +    char *user;
 +    char *group;
 +    char *target; /* pointer to the target filename of a symlink */
 +  } strings;
 +
 +  unsigned int flags;
 +
 +  /* used internally */
 +  char *b_data;
 +  size_t b_size;
 +  size_t b_used;
 +};
 +
 +/* return codes for CURLOPT_CHUNK_BGN_FUNCTION */
 +#define CURL_CHUNK_BGN_FUNC_OK      0
 +#define CURL_CHUNK_BGN_FUNC_FAIL    1 /* tell the lib to end the task */
 +#define CURL_CHUNK_BGN_FUNC_SKIP    2 /* skip this chunk over */
 +
 +/* if splitting of data transfer is enabled, this callback is called before
 +   download of an individual chunk started. Note that parameter "remains" works
 +   only for FTP wildcard downloading (for now), otherwise is not used */
 +typedef long (*curl_chunk_bgn_callback)(const void *transfer_info,
 +                                        void *ptr,
 +                                        int remains);
 +
 +/* return codes for CURLOPT_CHUNK_END_FUNCTION */
 +#define CURL_CHUNK_END_FUNC_OK      0
 +#define CURL_CHUNK_END_FUNC_FAIL    1 /* tell the lib to end the task */
 +
 +/* If splitting of data transfer is enabled this callback is called after
 +   download of an individual chunk finished.
 +   Note! After this callback was set then it have to be called FOR ALL chunks.
 +   Even if downloading of this chunk was skipped in CHUNK_BGN_FUNC.
 +   This is the reason why we don't need "transfer_info" parameter in this
 +   callback and we are not interested in "remains" parameter too. */
 +typedef long (*curl_chunk_end_callback)(void *ptr);
 +
 +/* return codes for FNMATCHFUNCTION */
 +#define CURL_FNMATCHFUNC_MATCH    0 /* string corresponds to the pattern */
 +#define CURL_FNMATCHFUNC_NOMATCH  1 /* pattern doesn't match the string */
 +#define CURL_FNMATCHFUNC_FAIL     2 /* an error occurred */
 +
 +/* callback type for wildcard downloading pattern matching. If the
 +   string matches the pattern, return CURL_FNMATCHFUNC_MATCH value, etc. */
 +typedef int (*curl_fnmatch_callback)(void *ptr,
 +                                     const char *pattern,
 +                                     const char *string);
 +
 +/* These are the return codes for the seek callbacks */
 +#define CURL_SEEKFUNC_OK       0
 +#define CURL_SEEKFUNC_FAIL     1 /* fail the entire transfer */
 +#define CURL_SEEKFUNC_CANTSEEK 2 /* tell libcurl seeking can't be done, so
 +                                    libcurl might try other means instead */
 +typedef int (*curl_seek_callback)(void *instream,
 +                                  curl_off_t offset,
 +                                  int origin); /* 'whence' */
 +
 +/* This is a return code for the read callback that, when returned, will
 +   signal libcurl to immediately abort the current transfer. */
 +#define CURL_READFUNC_ABORT 0x10000000
 +/* This is a return code for the read callback that, when returned, will
 +   signal libcurl to pause sending data on the current transfer. */
 +#define CURL_READFUNC_PAUSE 0x10000001
 +
 +typedef size_t (*curl_read_callback)(char *buffer,
 +                                      size_t size,
 +                                      size_t nitems,
 +                                      void *instream);
 +
 +typedef enum  {
 +  CURLSOCKTYPE_IPCXN,  /* socket created for a specific IP connection */
 +  CURLSOCKTYPE_ACCEPT, /* socket created by accept() call */
 +  CURLSOCKTYPE_LAST    /* never use */
 +} curlsocktype;
 +
 +/* The return code from the sockopt_callback can signal information back
 +   to libcurl: */
 +#define CURL_SOCKOPT_OK 0
 +#define CURL_SOCKOPT_ERROR 1 /* causes libcurl to abort and return
 +                                CURLE_ABORTED_BY_CALLBACK */
 +#define CURL_SOCKOPT_ALREADY_CONNECTED 2
 +
 +typedef int (*curl_sockopt_callback)(void *clientp,
 +                                     curl_socket_t curlfd,
 +                                     curlsocktype purpose);
 +
 +struct curl_sockaddr {
 +  int family;
 +  int socktype;
 +  int protocol;
 +  unsigned int addrlen; /* addrlen was a socklen_t type before 7.18.0 but it
 +                           turned really ugly and painful on the systems that
 +                           lack this type */
 +  struct sockaddr addr;
 +};
 +
 +typedef curl_socket_t
 +(*curl_opensocket_callback)(void *clientp,
 +                            curlsocktype purpose,
 +                            struct curl_sockaddr *address);
 +
 +typedef int
 +(*curl_closesocket_callback)(void *clientp, curl_socket_t item);
 +
 +typedef enum {
 +  CURLIOE_OK,            /* I/O operation successful */
 +  CURLIOE_UNKNOWNCMD,    /* command was unknown to callback */
 +  CURLIOE_FAILRESTART,   /* failed to restart the read */
 +  CURLIOE_LAST           /* never use */
 +} curlioerr;
 +
 +typedef enum  {
 +  CURLIOCMD_NOP,         /* no operation */
 +  CURLIOCMD_RESTARTREAD, /* restart the read stream from start */
 +  CURLIOCMD_LAST         /* never use */
 +} curliocmd;
 +
 +typedef curlioerr (*curl_ioctl_callback)(CURL *handle,
 +                                         int cmd,
 +                                         void *clientp);
 +
 +#ifndef CURL_DID_MEMORY_FUNC_TYPEDEFS
 +/*
 + * The following typedef's are signatures of malloc, free, realloc, strdup and
 + * calloc respectively.  Function pointers of these types can be passed to the
 + * curl_global_init_mem() function to set user defined memory management
 + * callback routines.
 + */
 +typedef void *(*curl_malloc_callback)(size_t size);
 +typedef void (*curl_free_callback)(void *ptr);
 +typedef void *(*curl_realloc_callback)(void *ptr, size_t size);
 +typedef char *(*curl_strdup_callback)(const char *str);
 +typedef void *(*curl_calloc_callback)(size_t nmemb, size_t size);
 +
 +#define CURL_DID_MEMORY_FUNC_TYPEDEFS
 +#endif
 +
 +/* the kind of data that is passed to information_callback*/
 +typedef enum {
 +  CURLINFO_TEXT = 0,
 +  CURLINFO_HEADER_IN,    /* 1 */
 +  CURLINFO_HEADER_OUT,   /* 2 */
 +  CURLINFO_DATA_IN,      /* 3 */
 +  CURLINFO_DATA_OUT,     /* 4 */
 +  CURLINFO_SSL_DATA_IN,  /* 5 */
 +  CURLINFO_SSL_DATA_OUT, /* 6 */
 +  CURLINFO_END
 +} curl_infotype;
 +
 +typedef int (*curl_debug_callback)
 +       (CURL *handle,      /* the handle/transfer this concerns */
 +        curl_infotype type, /* what kind of data */
 +        char *data,        /* points to the data */
 +        size_t size,       /* size of the data pointed to */
 +        void *userptr);    /* whatever the user please */
 +
 +/* All possible error codes from all sorts of curl functions. Future versions
 +   may return other values, stay prepared.
 +
 +   Always add new return codes last. Never *EVER* remove any. The return
 +   codes must remain the same!
 + */
 +
 +typedef enum {
 +  CURLE_OK = 0,
 +  CURLE_UNSUPPORTED_PROTOCOL,    /* 1 */
 +  CURLE_FAILED_INIT,             /* 2 */
 +  CURLE_URL_MALFORMAT,           /* 3 */
 +  CURLE_NOT_BUILT_IN,            /* 4 - [was obsoleted in August 2007 for
 +                                    7.17.0, reused in April 2011 for 7.21.5] */
 +  CURLE_COULDNT_RESOLVE_PROXY,   /* 5 */
 +  CURLE_COULDNT_RESOLVE_HOST,    /* 6 */
 +  CURLE_COULDNT_CONNECT,         /* 7 */
 +  CURLE_WEIRD_SERVER_REPLY,      /* 8 */
 +  CURLE_REMOTE_ACCESS_DENIED,    /* 9 a service was denied by the server
 +                                    due to lack of access - when login fails
 +                                    this is not returned. */
 +  CURLE_FTP_ACCEPT_FAILED,       /* 10 - [was obsoleted in April 2006 for
 +                                    7.15.4, reused in Dec 2011 for 7.24.0]*/
 +  CURLE_FTP_WEIRD_PASS_REPLY,    /* 11 */
 +  CURLE_FTP_ACCEPT_TIMEOUT,      /* 12 - timeout occurred accepting server
 +                                    [was obsoleted in August 2007 for 7.17.0,
 +                                    reused in Dec 2011 for 7.24.0]*/
 +  CURLE_FTP_WEIRD_PASV_REPLY,    /* 13 */
 +  CURLE_FTP_WEIRD_227_FORMAT,    /* 14 */
 +  CURLE_FTP_CANT_GET_HOST,       /* 15 */
 +  CURLE_HTTP2,                   /* 16 - A problem in the http2 framing layer.
 +                                    [was obsoleted in August 2007 for 7.17.0,
 +                                    reused in July 2014 for 7.38.0] */
 +  CURLE_FTP_COULDNT_SET_TYPE,    /* 17 */
 +  CURLE_PARTIAL_FILE,            /* 18 */
 +  CURLE_FTP_COULDNT_RETR_FILE,   /* 19 */
 +  CURLE_OBSOLETE20,              /* 20 - NOT USED */
 +  CURLE_QUOTE_ERROR,             /* 21 - quote command failure */
 +  CURLE_HTTP_RETURNED_ERROR,     /* 22 */
 +  CURLE_WRITE_ERROR,             /* 23 */
 +  CURLE_OBSOLETE24,              /* 24 - NOT USED */
 +  CURLE_UPLOAD_FAILED,           /* 25 - failed upload "command" */
 +  CURLE_READ_ERROR,              /* 26 - couldn't open/read from file */
 +  CURLE_OUT_OF_MEMORY,           /* 27 */
 +  /* Note: CURLE_OUT_OF_MEMORY may sometimes indicate a conversion error
 +           instead of a memory allocation error if CURL_DOES_CONVERSIONS
 +           is defined
 +  */
 +  CURLE_OPERATION_TIMEDOUT,      /* 28 - the timeout time was reached */
 +  CURLE_OBSOLETE29,              /* 29 - NOT USED */
 +  CURLE_FTP_PORT_FAILED,         /* 30 - FTP PORT operation failed */
 +  CURLE_FTP_COULDNT_USE_REST,    /* 31 - the REST command failed */
 +  CURLE_OBSOLETE32,              /* 32 - NOT USED */
 +  CURLE_RANGE_ERROR,             /* 33 - RANGE "command" didn't work */
 +  CURLE_HTTP_POST_ERROR,         /* 34 */
 +  CURLE_SSL_CONNECT_ERROR,       /* 35 - wrong when connecting with SSL */
 +  CURLE_BAD_DOWNLOAD_RESUME,     /* 36 - couldn't resume download */
 +  CURLE_FILE_COULDNT_READ_FILE,  /* 37 */
 +  CURLE_LDAP_CANNOT_BIND,        /* 38 */
 +  CURLE_LDAP_SEARCH_FAILED,      /* 39 */
 +  CURLE_OBSOLETE40,              /* 40 - NOT USED */
-   CURLE_FUNCTION_NOT_FOUND,      /* 41 */
++  CURLE_FUNCTION_NOT_FOUND,      /* 41 - NOT USED starting with 7.53.0 */
 +  CURLE_ABORTED_BY_CALLBACK,     /* 42 */
 +  CURLE_BAD_FUNCTION_ARGUMENT,   /* 43 */
 +  CURLE_OBSOLETE44,              /* 44 - NOT USED */
 +  CURLE_INTERFACE_FAILED,        /* 45 - CURLOPT_INTERFACE failed */
 +  CURLE_OBSOLETE46,              /* 46 - NOT USED */
 +  CURLE_TOO_MANY_REDIRECTS,      /* 47 - catch endless re-direct loops */
 +  CURLE_UNKNOWN_OPTION,          /* 48 - User specified an unknown option */
 +  CURLE_TELNET_OPTION_SYNTAX,    /* 49 - Malformed telnet option */
 +  CURLE_OBSOLETE50,              /* 50 - NOT USED */
 +  CURLE_PEER_FAILED_VERIFICATION, /* 51 - peer's certificate or fingerprint
 +                                     wasn't verified fine */
 +  CURLE_GOT_NOTHING,             /* 52 - when this is a specific error */
 +  CURLE_SSL_ENGINE_NOTFOUND,     /* 53 - SSL crypto engine not found */
 +  CURLE_SSL_ENGINE_SETFAILED,    /* 54 - can not set SSL crypto engine as
 +                                    default */
 +  CURLE_SEND_ERROR,              /* 55 - failed sending network data */
 +  CURLE_RECV_ERROR,              /* 56 - failure in receiving network data */
 +  CURLE_OBSOLETE57,              /* 57 - NOT IN USE */
 +  CURLE_SSL_CERTPROBLEM,         /* 58 - problem with the local certificate */
 +  CURLE_SSL_CIPHER,              /* 59 - couldn't use specified cipher */
 +  CURLE_SSL_CACERT,              /* 60 - problem with the CA cert (path?) */
 +  CURLE_BAD_CONTENT_ENCODING,    /* 61 - Unrecognized/bad encoding */
 +  CURLE_LDAP_INVALID_URL,        /* 62 - Invalid LDAP URL */
 +  CURLE_FILESIZE_EXCEEDED,       /* 63 - Maximum file size exceeded */
 +  CURLE_USE_SSL_FAILED,          /* 64 - Requested FTP SSL level failed */
 +  CURLE_SEND_FAIL_REWIND,        /* 65 - Sending the data requires a rewind
 +                                    that failed */
 +  CURLE_SSL_ENGINE_INITFAILED,   /* 66 - failed to initialise ENGINE */
 +  CURLE_LOGIN_DENIED,            /* 67 - user, password or similar was not
 +                                    accepted and we failed to login */
 +  CURLE_TFTP_NOTFOUND,           /* 68 - file not found on server */
 +  CURLE_TFTP_PERM,               /* 69 - permission problem on server */
 +  CURLE_REMOTE_DISK_FULL,        /* 70 - out of disk space on server */
 +  CURLE_TFTP_ILLEGAL,            /* 71 - Illegal TFTP operation */
 +  CURLE_TFTP_UNKNOWNID,          /* 72 - Unknown transfer ID */
 +  CURLE_REMOTE_FILE_EXISTS,      /* 73 - File already exists */
 +  CURLE_TFTP_NOSUCHUSER,         /* 74 - No such user */
 +  CURLE_CONV_FAILED,             /* 75 - conversion failed */
 +  CURLE_CONV_REQD,               /* 76 - caller must register conversion
 +                                    callbacks using curl_easy_setopt options
 +                                    CURLOPT_CONV_FROM_NETWORK_FUNCTION,
 +                                    CURLOPT_CONV_TO_NETWORK_FUNCTION, and
 +                                    CURLOPT_CONV_FROM_UTF8_FUNCTION */
 +  CURLE_SSL_CACERT_BADFILE,      /* 77 - could not load CACERT file, missing
 +                                    or wrong format */
 +  CURLE_REMOTE_FILE_NOT_FOUND,   /* 78 - remote file not found */
 +  CURLE_SSH,                     /* 79 - error from the SSH layer, somewhat
 +                                    generic so the error message will be of
 +                                    interest when this has happened */
 +
 +  CURLE_SSL_SHUTDOWN_FAILED,     /* 80 - Failed to shut down the SSL
 +                                    connection */
 +  CURLE_AGAIN,                   /* 81 - socket is not ready for send/recv,
 +                                    wait till it's ready and try again (Added
 +                                    in 7.18.2) */
 +  CURLE_SSL_CRL_BADFILE,         /* 82 - could not load CRL file, missing or
 +                                    wrong format (Added in 7.19.0) */
 +  CURLE_SSL_ISSUER_ERROR,        /* 83 - Issuer check failed.  (Added in
 +                                    7.19.0) */
 +  CURLE_FTP_PRET_FAILED,         /* 84 - a PRET command failed */
 +  CURLE_RTSP_CSEQ_ERROR,         /* 85 - mismatch of RTSP CSeq numbers */
 +  CURLE_RTSP_SESSION_ERROR,      /* 86 - mismatch of RTSP Session Ids */
 +  CURLE_FTP_BAD_FILE_LIST,       /* 87 - unable to parse FTP file list */
 +  CURLE_CHUNK_FAILED,            /* 88 - chunk callback reported error */
 +  CURLE_NO_CONNECTION_AVAILABLE, /* 89 - No connection available, the
 +                                    session will be queued */
 +  CURLE_SSL_PINNEDPUBKEYNOTMATCH, /* 90 - specified pinned public key did not
 +                                     match */
 +  CURLE_SSL_INVALIDCERTSTATUS,   /* 91 - invalid certificate status */
 +  CURLE_HTTP2_STREAM,            /* 92 - stream error in HTTP/2 framing layer
 +                                    */
 +  CURL_LAST /* never use! */
 +} CURLcode;
 +
 +#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
 +                          the obsolete stuff removed! */
 +
 +/* Previously obsolete error code re-used in 7.38.0 */
 +#define CURLE_OBSOLETE16 CURLE_HTTP2
 +
 +/* Previously obsolete error codes re-used in 7.24.0 */
 +#define CURLE_OBSOLETE10 CURLE_FTP_ACCEPT_FAILED
 +#define CURLE_OBSOLETE12 CURLE_FTP_ACCEPT_TIMEOUT
 +
 +/*  compatibility with older names */
 +#define CURLOPT_ENCODING CURLOPT_ACCEPT_ENCODING
 +#define CURLE_FTP_WEIRD_SERVER_REPLY CURLE_WEIRD_SERVER_REPLY
 +
 +/* The following were added in 7.21.5, April 2011 */
 +#define CURLE_UNKNOWN_TELNET_OPTION CURLE_UNKNOWN_OPTION
 +
 +/* The following were added in 7.17.1 */
 +/* These are scheduled to disappear by 2009 */
 +#define CURLE_SSL_PEER_CERTIFICATE CURLE_PEER_FAILED_VERIFICATION
 +
 +/* The following were added in 7.17.0 */
 +/* These are scheduled to disappear by 2009 */
 +#define CURLE_OBSOLETE CURLE_OBSOLETE50 /* no one should be using this! */
 +#define CURLE_BAD_PASSWORD_ENTERED CURLE_OBSOLETE46
 +#define CURLE_BAD_CALLING_ORDER CURLE_OBSOLETE44
 +#define CURLE_FTP_USER_PASSWORD_INCORRECT CURLE_OBSOLETE10
 +#define CURLE_FTP_CANT_RECONNECT CURLE_OBSOLETE16
 +#define CURLE_FTP_COULDNT_GET_SIZE CURLE_OBSOLETE32
 +#define CURLE_FTP_COULDNT_SET_ASCII CURLE_OBSOLETE29
 +#define CURLE_FTP_WEIRD_USER_REPLY CURLE_OBSOLETE12
 +#define CURLE_FTP_WRITE_ERROR CURLE_OBSOLETE20
 +#define CURLE_LIBRARY_NOT_FOUND CURLE_OBSOLETE40
 +#define CURLE_MALFORMAT_USER CURLE_OBSOLETE24
 +#define CURLE_SHARE_IN_USE CURLE_OBSOLETE57
 +#define CURLE_URL_MALFORMAT_USER CURLE_NOT_BUILT_IN
 +
 +#define CURLE_FTP_ACCESS_DENIED CURLE_REMOTE_ACCESS_DENIED
 +#define CURLE_FTP_COULDNT_SET_BINARY CURLE_FTP_COULDNT_SET_TYPE
 +#define CURLE_FTP_QUOTE_ERROR CURLE_QUOTE_ERROR
 +#define CURLE_TFTP_DISKFULL CURLE_REMOTE_DISK_FULL
 +#define CURLE_TFTP_EXISTS CURLE_REMOTE_FILE_EXISTS
 +#define CURLE_HTTP_RANGE_ERROR CURLE_RANGE_ERROR
 +#define CURLE_FTP_SSL_FAILED CURLE_USE_SSL_FAILED
 +
 +/* The following were added earlier */
 +
 +#define CURLE_OPERATION_TIMEOUTED CURLE_OPERATION_TIMEDOUT
 +
 +#define CURLE_HTTP_NOT_FOUND CURLE_HTTP_RETURNED_ERROR
 +#define CURLE_HTTP_PORT_FAILED CURLE_INTERFACE_FAILED
 +#define CURLE_FTP_COULDNT_STOR_FILE CURLE_UPLOAD_FAILED
 +
 +#define CURLE_FTP_PARTIAL_FILE CURLE_PARTIAL_FILE
 +#define CURLE_FTP_BAD_DOWNLOAD_RESUME CURLE_BAD_DOWNLOAD_RESUME
 +
 +/* This was the error code 50 in 7.7.3 and a few earlier versions, this
 +   is no longer used by libcurl but is instead #defined here only to not
 +   make programs break */
 +#define CURLE_ALREADY_COMPLETE 99999
 +
 +/* Provide defines for really old option names */
 +#define CURLOPT_FILE CURLOPT_WRITEDATA /* name changed in 7.9.7 */
 +#define CURLOPT_INFILE CURLOPT_READDATA /* name changed in 7.9.7 */
 +#define CURLOPT_WRITEHEADER CURLOPT_HEADERDATA
 +
 +/* Since long deprecated options with no code in the lib that does anything
 +   with them. */
 +#define CURLOPT_WRITEINFO CURLOPT_OBSOLETE40
 +#define CURLOPT_CLOSEPOLICY CURLOPT_OBSOLETE72
 +
 +#endif /*!CURL_NO_OLDIES*/
 +
 +/* This prototype applies to all conversion callbacks */
 +typedef CURLcode (*curl_conv_callback)(char *buffer, size_t length);
 +
 +typedef CURLcode (*curl_ssl_ctx_callback)(CURL *curl,    /* easy handle */
 +                                          void *ssl_ctx, /* actually an
 +                                                            OpenSSL SSL_CTX */
 +                                          void *userptr);
 +
 +typedef enum {
 +  CURLPROXY_HTTP = 0,   /* added in 7.10, new in 7.19.4 default is to use
 +                           CONNECT HTTP/1.1 */
 +  CURLPROXY_HTTP_1_0 = 1,   /* added in 7.19.4, force to use CONNECT
 +                               HTTP/1.0  */
 +  CURLPROXY_HTTPS = 2, /* added in 7.52.0 */
 +  CURLPROXY_SOCKS4 = 4, /* support added in 7.15.2, enum existed already
 +                           in 7.10 */
 +  CURLPROXY_SOCKS5 = 5, /* added in 7.10 */
 +  CURLPROXY_SOCKS4A = 6, /* added in 7.18.0 */
 +  CURLPROXY_SOCKS5_HOSTNAME = 7 /* Use the SOCKS5 protocol but pass along the
 +                                   host name rather than the IP address. added
 +                                   in 7.18.0 */
 +} curl_proxytype;  /* this enum was added in 7.10 */
 +
 +/*
 + * Bitmasks for CURLOPT_HTTPAUTH and CURLOPT_PROXYAUTH options:
 + *
 + * CURLAUTH_NONE         - No HTTP authentication
 + * CURLAUTH_BASIC        - HTTP Basic authentication (default)
 + * CURLAUTH_DIGEST       - HTTP Digest authentication
 + * CURLAUTH_NEGOTIATE    - HTTP Negotiate (SPNEGO) authentication
 + * CURLAUTH_GSSNEGOTIATE - Alias for CURLAUTH_NEGOTIATE (deprecated)
 + * CURLAUTH_NTLM         - HTTP NTLM authentication
 + * CURLAUTH_DIGEST_IE    - HTTP Digest authentication with IE flavour
 + * CURLAUTH_NTLM_WB      - HTTP NTLM authentication delegated to winbind helper
 + * CURLAUTH_ONLY         - Use together with a single other type to force no
 + *                         authentication or just that single type
 + * CURLAUTH_ANY          - All fine types set
 + * CURLAUTH_ANYSAFE      - All fine types except Basic
 + */
 +
 +#define CURLAUTH_NONE         ((unsigned long)0)
 +#define CURLAUTH_BASIC        (((unsigned long)1)<<0)
 +#define CURLAUTH_DIGEST       (((unsigned long)1)<<1)
 +#define CURLAUTH_NEGOTIATE    (((unsigned long)1)<<2)
 +/* Deprecated since the advent of CURLAUTH_NEGOTIATE */
 +#define CURLAUTH_GSSNEGOTIATE CURLAUTH_NEGOTIATE
 +#define CURLAUTH_NTLM         (((unsigned long)1)<<3)
 +#define CURLAUTH_DIGEST_IE    (((unsigned long)1)<<4)
 +#define CURLAUTH_NTLM_WB      (((unsigned long)1)<<5)
 +#define CURLAUTH_ONLY         (((unsigned long)1)<<31)
 +#define CURLAUTH_ANY          (~CURLAUTH_DIGEST_IE)
 +#define CURLAUTH_ANYSAFE      (~(CURLAUTH_BASIC|CURLAUTH_DIGEST_IE))
 +
 +#define CURLSSH_AUTH_ANY       ~0     /* all types supported by the server */
 +#define CURLSSH_AUTH_NONE      0      /* none allowed, silly but complete */
 +#define CURLSSH_AUTH_PUBLICKEY (1<<0) /* public/private key files */
 +#define CURLSSH_AUTH_PASSWORD  (1<<1) /* password */
 +#define CURLSSH_AUTH_HOST      (1<<2) /* host key files */
 +#define CURLSSH_AUTH_KEYBOARD  (1<<3) /* keyboard interactive */
 +#define CURLSSH_AUTH_AGENT     (1<<4) /* agent (ssh-agent, pageant...) */
 +#define CURLSSH_AUTH_DEFAULT CURLSSH_AUTH_ANY
 +
 +#define CURLGSSAPI_DELEGATION_NONE        0      /* no delegation (default) */
 +#define CURLGSSAPI_DELEGATION_POLICY_FLAG (1<<0) /* if permitted by policy */
 +#define CURLGSSAPI_DELEGATION_FLAG        (1<<1) /* delegate always */
 +
 +#define CURL_ERROR_SIZE 256
 +
 +enum curl_khtype {
 +  CURLKHTYPE_UNKNOWN,
 +  CURLKHTYPE_RSA1,
 +  CURLKHTYPE_RSA,
 +  CURLKHTYPE_DSS
 +};
 +
 +struct curl_khkey {
 +  const char *key; /* points to a zero-terminated string encoded with base64
 +                      if len is zero, otherwise to the "raw" data */
 +  size_t len;
 +  enum curl_khtype keytype;
 +};
 +
 +/* this is the set of return values expected from the curl_sshkeycallback
 +   callback */
 +enum curl_khstat {
 +  CURLKHSTAT_FINE_ADD_TO_FILE,
 +  CURLKHSTAT_FINE,
 +  CURLKHSTAT_REJECT, /* reject the connection, return an error */
 +  CURLKHSTAT_DEFER,  /* do not accept it, but we can't answer right now so
 +                        this causes a CURLE_DEFER error but otherwise the
 +                        connection will be left intact etc */
 +  CURLKHSTAT_LAST    /* not for use, only a marker for last-in-list */
 +};
 +
 +/* this is the set of status codes pass in to the callback */
 +enum curl_khmatch {
 +  CURLKHMATCH_OK,       /* match */
 +  CURLKHMATCH_MISMATCH, /* host found, key mismatch! */
 +  CURLKHMATCH_MISSING,  /* no matching host/key found */
 +  CURLKHMATCH_LAST      /* not for use, only a marker for last-in-list */
 +};
 +
 +typedef int
 +  (*curl_sshkeycallback) (CURL *easy,     /* easy handle */
 +                          const struct curl_khkey *knownkey, /* known */
 +                          const struct curl_khkey *foundkey, /* found */
 +                          enum curl_khmatch, /* libcurl's view on the keys */
 +                          void *clientp); /* custom pointer passed from app */
 +
 +/* parameter for the CURLOPT_USE_SSL option */
 +typedef enum {
 +  CURLUSESSL_NONE,    /* do not attempt to use SSL */
 +  CURLUSESSL_TRY,     /* try using SSL, proceed anyway otherwise */
 +  CURLUSESSL_CONTROL, /* SSL for the control connection or fail */
 +  CURLUSESSL_ALL,     /* SSL for all communication or fail */
 +  CURLUSESSL_LAST     /* not an option, never use */
 +} curl_usessl;
 +
 +/* Definition of bits for the CURLOPT_SSL_OPTIONS argument: */
 +
 +/* - ALLOW_BEAST tells libcurl to allow the BEAST SSL vulnerability in the
 +   name of improving interoperability with older servers. Some SSL libraries
 +   have introduced work-arounds for this flaw but those work-arounds sometimes
 +   make the SSL communication fail. To regain functionality with those broken
 +   servers, a user can this way allow the vulnerability back. */
 +#define CURLSSLOPT_ALLOW_BEAST (1<<0)
 +
 +/* - NO_REVOKE tells libcurl to disable certificate revocation checks for those
 +   SSL backends where such behavior is present. */
 +#define CURLSSLOPT_NO_REVOKE (1<<1)
 +
 +#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
 +                          the obsolete stuff removed! */
 +
 +/* Backwards compatibility with older names */
 +/* These are scheduled to disappear by 2009 */
 +
 +#define CURLFTPSSL_NONE CURLUSESSL_NONE
 +#define CURLFTPSSL_TRY CURLUSESSL_TRY
 +#define CURLFTPSSL_CONTROL CURLUSESSL_CONTROL
 +#define CURLFTPSSL_ALL CURLUSESSL_ALL
 +#define CURLFTPSSL_LAST CURLUSESSL_LAST
 +#define curl_ftpssl curl_usessl
 +#endif /*!CURL_NO_OLDIES*/
 +
 +/* parameter for the CURLOPT_FTP_SSL_CCC option */
 +typedef enum {
 +  CURLFTPSSL_CCC_NONE,    /* do not send CCC */
 +  CURLFTPSSL_CCC_PASSIVE, /* Let the server initiate the shutdown */
 +  CURLFTPSSL_CCC_ACTIVE,  /* Initiate the shutdown */
 +  CURLFTPSSL_CCC_LAST     /* not an option, never use */
 +} curl_ftpccc;
 +
 +/* parameter for the CURLOPT_FTPSSLAUTH option */
 +typedef enum {
 +  CURLFTPAUTH_DEFAULT, /* let libcurl decide */
 +  CURLFTPAUTH_SSL,     /* use "AUTH SSL" */
 +  CURLFTPAUTH_TLS,     /* use "AUTH TLS" */
 +  CURLFTPAUTH_LAST /* not an option, never use */
 +} curl_ftpauth;
 +
 +/* parameter for the CURLOPT_FTP_CREATE_MISSING_DIRS option */
 +typedef enum {
 +  CURLFTP_CREATE_DIR_NONE,  /* do NOT create missing dirs! */
 +  CURLFTP_CREATE_DIR,       /* (FTP/SFTP) if CWD fails, try MKD and then CWD
 +                               again if MKD succeeded, for SFTP this does
 +                               similar magic */
 +  CURLFTP_CREATE_DIR_RETRY, /* (FTP only) if CWD fails, try MKD and then CWD
 +                               again even if MKD failed! */
 +  CURLFTP_CREATE_DIR_LAST   /* not an option, never use */
 +} curl_ftpcreatedir;
 +
 +/* parameter for the CURLOPT_FTP_FILEMETHOD option */
 +typedef enum {
 +  CURLFTPMETHOD_DEFAULT,   /* let libcurl pick */
 +  CURLFTPMETHOD_MULTICWD,  /* single CWD operation for each path part */
 +  CURLFTPMETHOD_NOCWD,     /* no CWD at all */
 +  CURLFTPMETHOD_SINGLECWD, /* one CWD to full dir, then work on file */
 +  CURLFTPMETHOD_LAST       /* not an option, never use */
 +} curl_ftpmethod;
 +
 +/* bitmask defines for CURLOPT_HEADEROPT */
 +#define CURLHEADER_UNIFIED  0
 +#define CURLHEADER_SEPARATE (1<<0)
 +
 +/* CURLPROTO_ defines are for the CURLOPT_*PROTOCOLS options */
 +#define CURLPROTO_HTTP   (1<<0)
 +#define CURLPROTO_HTTPS  (1<<1)
 +#define CURLPROTO_FTP    (1<<2)
 +#define CURLPROTO_FTPS   (1<<3)
 +#define CURLPROTO_SCP    (1<<4)
 +#define CURLPROTO_SFTP   (1<<5)
 +#define CURLPROTO_TELNET (1<<6)
 +#define CURLPROTO_LDAP   (1<<7)
 +#define CURLPROTO_LDAPS  (1<<8)
 +#define CURLPROTO_DICT   (1<<9)
 +#define CURLPROTO_FILE   (1<<10)
 +#define CURLPROTO_TFTP   (1<<11)
 +#define CURLPROTO_IMAP   (1<<12)
 +#define CURLPROTO_IMAPS  (1<<13)
 +#define CURLPROTO_POP3   (1<<14)
 +#define CURLPROTO_POP3S  (1<<15)
 +#define CURLPROTO_SMTP   (1<<16)
 +#define CURLPROTO_SMTPS  (1<<17)
 +#define CURLPROTO_RTSP   (1<<18)
 +#define CURLPROTO_RTMP   (1<<19)
 +#define CURLPROTO_RTMPT  (1<<20)
 +#define CURLPROTO_RTMPE  (1<<21)
 +#define CURLPROTO_RTMPTE (1<<22)
 +#define CURLPROTO_RTMPS  (1<<23)
 +#define CURLPROTO_RTMPTS (1<<24)
 +#define CURLPROTO_GOPHER (1<<25)
 +#define CURLPROTO_SMB    (1<<26)
 +#define CURLPROTO_SMBS   (1<<27)
 +#define CURLPROTO_ALL    (~0) /* enable everything */
 +
 +/* long may be 32 or 64 bits, but we should never depend on anything else
 +   but 32 */
 +#define CURLOPTTYPE_LONG          0
 +#define CURLOPTTYPE_OBJECTPOINT   10000
 +#define CURLOPTTYPE_STRINGPOINT   10000
 +#define CURLOPTTYPE_FUNCTIONPOINT 20000
 +#define CURLOPTTYPE_OFF_T         30000
 +
 +/* *STRINGPOINT is an alias for OBJECTPOINT to allow tools to extract the
 +   string options from the header file */
 +
 +/* name is uppercase CURLOPT_<name>,
 +   type is one of the defined CURLOPTTYPE_<type>
 +   number is unique identifier */
 +#ifdef CINIT
 +#undef CINIT
 +#endif
 +
 +#ifdef CURL_ISOCPP
 +#define CINIT(na,t,nu) CURLOPT_ ## na = CURLOPTTYPE_ ## t + nu
 +#else
 +/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */
 +#define LONG          CURLOPTTYPE_LONG
 +#define OBJECTPOINT   CURLOPTTYPE_OBJECTPOINT
 +#define STRINGPOINT   CURLOPTTYPE_OBJECTPOINT
 +#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT
 +#define OFF_T         CURLOPTTYPE_OFF_T
 +#define CINIT(name,type,number) CURLOPT_/**/name = type + number
 +#endif
 +
 +/*
 + * This macro-mania below setups the CURLOPT_[what] enum, to be used with
 + * curl_easy_setopt(). The first argument in the CINIT() macro is the [what]
 + * word.
 + */
 +
 +typedef enum {
 +  /* This is the FILE * or void * the regular output should be written to. */
 +  CINIT(WRITEDATA, OBJECTPOINT, 1),
 +
 +  /* The full URL to get/put */
 +  CINIT(URL, STRINGPOINT, 2),
 +
 +  /* Port number to connect to, if other than default. */
 +  CINIT(PORT, LONG, 3),
 +
 +  /* Name of proxy to use. */
 +  CINIT(PROXY, STRINGPOINT, 4),
 +
 +  /* "user:password;options" to use when fetching. */
 +  CINIT(USERPWD, STRINGPOINT, 5),
 +
 +  /* "user:password" to use with proxy. */
 +  CINIT(PROXYUSERPWD, STRINGPOINT, 6),
 +
 +  /* Range to get, specified as an ASCII string. */
 +  CINIT(RANGE, STRINGPOINT, 7),
 +
 +  /* not used */
 +
 +  /* Specified file stream to upload from (use as input): */
 +  CINIT(READDATA, OBJECTPOINT, 9),
 +
 +  /* Buffer to receive error messages in, must be at least CURL_ERROR_SIZE
 +   * bytes big. If this is not used, error messages go to stderr instead: */
 +  CINIT(ERRORBUFFER, OBJECTPOINT, 10),
 +
 +  /* Function that will be called to store the output (instead of fwrite). The
 +   * parameters will use fwrite() syntax, make sure to follow them. */
 +  CINIT(WRITEFUNCTION, FUNCTIONPOINT, 11),
 +
 +  /* Function that will be called to read the input (instead of fread). The
 +   * parameters will use fread() syntax, make sure to follow them. */
 +  CINIT(READFUNCTION, FUNCTIONPOINT, 12),
 +
 +  /* Time-out the read operation after this amount of seconds */
 +  CINIT(TIMEOUT, LONG, 13),
 +
 +  /* If the CURLOPT_INFILE is used, this can be used to inform libcurl about
 +   * how large the file being sent really is. That allows better error
 +   * checking and better verifies that the upload was successful. -1 means
 +   * unknown size.
 +   *
 +   * For large file support, there is also a _LARGE version of the key
 +   * which takes an off_t type, allowing platforms with larger off_t
 +   * sizes to handle larger files.  See below for INFILESIZE_LARGE.
 +   */
 +  CINIT(INFILESIZE, LONG, 14),
 +
 +  /* POST static input fields. */
 +  CINIT(POSTFIELDS, OBJECTPOINT, 15),
 +
 +  /* Set the referrer page (needed by some CGIs) */
 +  CINIT(REFERER, STRINGPOINT, 16),
 +
 +  /* Set the FTP PORT string (interface name, named or numerical IP address)
 +     Use i.e '-' to use default address. */
 +  CINIT(FTPPORT, STRINGPOINT, 17),
 +
 +  /* Set the User-Agent string (examined by some CGIs) */
 +  CINIT(USERAGENT, STRINGPOINT, 18),
 +
 +  /* If the download receives less than "low speed limit" bytes/second
 +   * during "low speed time" seconds, the operations is aborted.
 +   * You could i.e if you have a pretty high speed connection, abort if
 +   * it is less than 2000 bytes/sec during 20 seconds.
 +   */
 +
 +  /* Set the "low speed limit" */
 +  CINIT(LOW_SPEED_LIMIT, LONG, 19),
 +
 +  /* Set the "low speed time" */
 +  CINIT(LOW_SPEED_TIME, LONG, 20),
 +
 +  /* Set the continuation offset.
 +   *
 +   * Note there is also a _LARGE version of this key which uses
 +   * off_t types, allowing for large file offsets on platforms which
 +   * use larger-than-32-bit off_t's.  Look below for RESUME_FROM_LARGE.
 +   */
 +  CINIT(RESUME_FROM, LONG, 21),
 +
 +  /* Set cookie in request: */
 +  CINIT(COOKIE, STRINGPOINT, 22),
 +
 +  /* This points to a linked list of headers, struct curl_slist kind. This
 +     list is also used for RTSP (in spite of its name) */
 +  CINIT(HTTPHEADER, OBJECTPOINT, 23),
 +
 +  /* This points to a linked list of post entries, struct curl_httppost */
 +  CINIT(HTTPPOST, OBJECTPOINT, 24),
 +
 +  /* name of the file keeping your private SSL-certificate */
 +  CINIT(SSLCERT, STRINGPOINT, 25),
 +
 +  /* password for the SSL or SSH private key */
 +  CINIT(KEYPASSWD, STRINGPOINT, 26),
 +
 +  /* send TYPE parameter? */
 +  CINIT(CRLF, LONG, 27),
 +
 +  /* send linked-list of QUOTE commands */
 +  CINIT(QUOTE, OBJECTPOINT, 28),
 +
 +  /* send FILE * or void * to store headers to, if you use a callback it
 +     is simply passed to the callback unmodified */
 +  CINIT(HEADERDATA, OBJECTPOINT, 29),
 +
 +  /* point to a file to read the initial cookies from, also enables
 +     "cookie awareness" */
 +  CINIT(COOKIEFILE, STRINGPOINT, 31),
 +
 +  /* What version to specifically try to use.
 +     See CURL_SSLVERSION defines below. */
 +  CINIT(SSLVERSION, LONG, 32),
 +
 +  /* What kind of HTTP time condition to use, see defines */
 +  CINIT(TIMECONDITION, LONG, 33),
 +
 +  /* Time to use with the above condition. Specified in number of seconds
 +     since 1 Jan 1970 */
 +  CINIT(TIMEVALUE, LONG, 34),
 +
 +  /* 35 = OBSOLETE */
 +
 +  /* Custom request, for customizing the get command like
 +     HTTP: DELETE, TRACE and others
 +     FTP: to use a different list command
 +     */
 +  CINIT(CUSTOMREQUEST, STRINGPOINT, 36),
 +
 +  /* FILE handle to use instead of stderr */
 +  CINIT(STDERR, OBJECTPOINT, 37),
 +
 +  /* 38 is not used */
 +
 +  /* send linked-list of post-transfer QUOTE commands */
 +  CINIT(POSTQUOTE, OBJECTPOINT, 39),
 +
 +  CINIT(OBSOLETE40, OBJECTPOINT, 40), /* OBSOLETE, do not use! */
 +
 +  CINIT(VERBOSE, LONG, 41),      /* talk a lot */
 +  CINIT(HEADER, LONG, 42),       /* throw the header out too */
 +  CINIT(NOPROGRESS, LONG, 43),   /* shut off the progress meter */
 +  CINIT(NOBODY, LONG, 44),       /* use HEAD to get http document */
 +  CINIT(FAILONERROR, LONG, 45),  /* no output on http error codes >= 400 */
 +  CINIT(UPLOAD, LONG, 46),       /* this is an upload */
 +  CINIT(POST, LONG, 47),         /* HTTP POST method */
 +  CINIT(DIRLISTONLY, LONG, 48),  /* bare names when listing directories */
 +
 +  CINIT(APPEND, LONG, 50),       /* Append instead of overwrite on upload! */
 +
 +  /* Specify whether to read the user+password from the .netrc or the URL.
 +   * This must be one of the CURL_NETRC_* enums below. */
 +  CINIT(NETRC, LONG, 51),
 +
 +  CINIT(FOLLOWLOCATION, LONG, 52),  /* use Location: Luke! */
 +
 +  CINIT(TRANSFERTEXT, LONG, 53), /* transfer data in text/ASCII format */
 +  CINIT(PUT, LONG, 54),          /* HTTP PUT */
 +
 +  /* 55 = OBSOLETE */
 +
 +  /* DEPRECATED
 +   * Function that will be called instead of the internal progress display
 +   * function. This function should be defined as the curl_progress_callback
 +   * prototype defines. */
 +  CINIT(PROGRESSFUNCTION, FUNCTIONPOINT, 56),
 +
 +  /* Data passed to the CURLOPT_PROGRESSFUNCTION and CURLOPT_XFERINFOFUNCTION
 +     callbacks */
 +  CINIT(PROGRESSDATA, OBJECTPOINT, 57),
 +#define CURLOPT_XFERINFODATA CURLOPT_PROGRESSDATA
 +
 +  /* We want the referrer field set automatically when following locations */
 +  CINIT(AUTOREFERER, LONG, 58),
 +
 +  /* Port of the proxy, can be set in the proxy string as well with:
 +     "[host]:[port]" */
 +  CINIT(PROXYPORT, LONG, 59),
 +
 +  /* size of the POST input data, if strlen() is not good to use */
 +  CINIT(POSTFIELDSIZE, LONG, 60),
 +
 +  /* tunnel non-http operations through a HTTP proxy */
 +  CINIT(HTTPPROXYTUNNEL, LONG, 61),
 +
 +  /* Set the interface string to use as outgoing network interface */
 +  CINIT(INTERFACE, STRINGPOINT, 62),
 +
 +  /* Set the krb4/5 security level, this also enables krb4/5 awareness.  This
 +   * is a string, 'clear', 'safe', 'confidential' or 'private'.  If the string
 +   * is set but doesn't match one of these, 'private' will be used.  */
 +  CINIT(KRBLEVEL, STRINGPOINT, 63),
 +
 +  /* Set if we should verify the peer in ssl handshake, set 1 to verify. */
 +  CINIT(SSL_VERIFYPEER, LONG, 64),
 +
 +  /* The CApath or CAfile used to validate the peer certificate
 +     this option is used only if SSL_VERIFYPEER is true */
 +  CINIT(CAINFO, STRINGPOINT, 65),
 +
 +  /* 66 = OBSOLETE */
 +  /* 67 = OBSOLETE */
 +
 +  /* Maximum number of http redirects to follow */
 +  CINIT(MAXREDIRS, LONG, 68),
 +
 +  /* Pass a long set to 1 to get the date of the requested document (if
 +     possible)! Pass a zero to shut it off. */
 +  CINIT(FILETIME, LONG, 69),
 +
 +  /* This points to a linked list of telnet options */
 +  CINIT(TELNETOPTIONS, OBJECTPOINT, 70),
 +
 +  /* Max amount of cached alive connections */
 +  CINIT(MAXCONNECTS, LONG, 71),
 +
 +  CINIT(OBSOLETE72, LONG, 72), /* OBSOLETE, do not use! */
 +
 +  /* 73 = OBSOLETE */
 +
 +  /* Set to explicitly use a new connection for the upcoming transfer.
 +     Do not use this unless you're absolutely sure of this, as it makes the
 +     operation slower and is less friendly for the network. */
 +  CINIT(FRESH_CONNECT, LONG, 74),
 +
 +  /* Set to explicitly forbid the upcoming transfer's connection to be re-used
 +     when done. Do not use this unless you're absolutely sure of this, as it
 +     makes the operation slower and is less friendly for the network. */
 +  CINIT(FORBID_REUSE, LONG, 75),
 +
 +  /* Set to a file name that contains random data for libcurl to use to
 +     seed the random engine when doing SSL connects. */
 +  CINIT(RANDOM_FILE, STRINGPOINT, 76),
 +
 +  /* Set to the Entropy Gathering Daemon socket pathname */
 +  CINIT(EGDSOCKET, STRINGPOINT, 77),
 +
 +  /* Time-out connect operations after this amount of seconds, if connects are
 +     OK within this time, then fine... This only aborts the connect phase. */
 +  CINIT(CONNECTTIMEOUT, LONG, 78),
 +
 +  /* Function that will be called to store headers (instead of fwrite). The
 +   * parameters will use fwrite() syntax, make sure to follow them. */
 +  CINIT(HEADERFUNCTION, FUNCTIONPOINT, 79),
 +
 +  /* Set this to force the HTTP request to get back to GET. Only really usable
 +     if POST, PUT or a custom request have been used first.
 +   */
 +  CINIT(HTTPGET, LONG, 80),
 +
 +  /* Set if we should verify the Common name from the peer certificate in ssl
 +   * handshake, set 1 to check existence, 2 to ensure that it matches the
 +   * provided hostname. */
 +  CINIT(SSL_VERIFYHOST, LONG, 81),
 +
 +  /* Specify which file name to write all known cookies in after completed
 +     operation. Set file name to "-" (dash) to make it go to stdout. */
 +  CINIT(COOKIEJAR, STRINGPOINT, 82),
 +
 +  /* Specify which SSL ciphers to use */
 +  CINIT(SSL_CIPHER_LIST, STRINGPOINT, 83),
 +
 +  /* Specify which HTTP version to use! This must be set to one of the
 +     CURL_HTTP_VERSION* enums set below. */
 +  CINIT(HTTP_VERSION, LONG, 84),
 +
 +  /* Specifically switch on or off the FTP engine's use of the EPSV command. By
 +     default, that one will always be attempted before the more traditional
 +     PASV command. */
 +  CINIT(FTP_USE_EPSV, LONG, 85),
 +
 +  /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") */
 +  CINIT(SSLCERTTYPE, STRINGPOINT, 86),
 +
 +  /* name of the file keeping your private SSL-key */
 +  CINIT(SSLKEY, STRINGPOINT, 87),
 +
 +  /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") */
 +  CINIT(SSLKEYTYPE, STRINGPOINT, 88),
 +
 +  /* crypto engine for the SSL-sub system */
 +  CINIT(SSLENGINE, STRINGPOINT, 89),
 +
 +  /* set the crypto engine for the SSL-sub system as default
 +     the param has no meaning...
 +   */
 +  CINIT(SSLENGINE_DEFAULT, LONG, 90),
 +
 +  /* Non-zero value means to use the global dns cache */
 +  CINIT(DNS_USE_GLOBAL_CACHE, LONG, 91), /* DEPRECATED, do not use! */
 +
 +  /* DNS cache timeout */
 +  CINIT(DNS_CACHE_TIMEOUT, LONG, 92),
 +
 +  /* send linked-list of pre-transfer QUOTE commands */
 +  CINIT(PREQUOTE, OBJECTPOINT, 93),
 +
 +  /* set the debug function */
 +  CINIT(DEBUGFUNCTION, FUNCTIONPOINT, 94),
 +
 +  /* set the data for the debug function */
 +  CINIT(DEBUGDATA, OBJECTPOINT, 95),
 +
 +  /* mark this as start of a cookie session */
 +  CINIT(COOKIESESSION, LONG, 96),
 +
 +  /* The CApath directory used to validate the peer certificate
 +     this option is used only if SSL_VERIFYPEER is true */
 +  CINIT(CAPATH, STRINGPOINT, 97),
 +
 +  /* Instruct libcurl to use a smaller receive buffer */
 +  CINIT(BUFFERSIZE, LONG, 98),
 +
 +  /* Instruct libcurl to not use any signal/alarm handlers, even when using
 +     timeouts. This option is useful for multi-threaded applications.
 +     See libcurl-the-guide for more background information. */
 +  CINIT(NOSIGNAL, LONG, 99),
 +
 +  /* Provide a CURLShare for mutexing non-ts data */
 +  CINIT(SHARE, OBJECTPOINT, 100),
 +
 +  /* indicates type of proxy. accepted values are CURLPROXY_HTTP (default),
 +     CURLPROXY_HTTPS, CURLPROXY_SOCKS4, CURLPROXY_SOCKS4A and
 +     CURLPROXY_SOCKS5. */
 +  CINIT(PROXYTYPE, LONG, 101),
 +
 +  /* Set the Accept-Encoding string. Use this to tell a server you would like
 +     the response to be compressed. Before 7.21.6, this was known as
 +     CURLOPT_ENCODING */
 +  CINIT(ACCEPT_ENCODING, STRINGPOINT, 102),
 +
 +  /* Set pointer to private data */
 +  CINIT(PRIVATE, OBJECTPOINT, 103),
 +
 +  /* Set aliases for HTTP 200 in the HTTP Response header */
 +  CINIT(HTTP200ALIASES, OBJECTPOINT, 104),
 +
 +  /* Continue to send authentication (user+password) when following locations,
 +     even when hostname changed. This can potentially send off the name
 +     and password to whatever host the server decides. */
 +  CINIT(UNRESTRICTED_AUTH, LONG, 105),
 +
 +  /* Specifically switch on or off the FTP engine's use of the EPRT command (
 +     it also disables the LPRT attempt). By default, those ones will always be
 +     attempted before the good old traditional PORT command. */
 +  CINIT(FTP_USE_EPRT, LONG, 106),
 +
 +  /* Set this to a bitmask value to enable the particular authentications
 +     methods you like. Use this in combination with CURLOPT_USERPWD.
 +     Note that setting multiple bits may cause extra network round-trips. */
 +  CINIT(HTTPAUTH, LONG, 107),
 +
 +  /* Set the ssl context callback function, currently only for OpenSSL ssl_ctx
 +     in second argument. The function must be matching the
 +     curl_ssl_ctx_callback proto. */
 +  CINIT(SSL_CTX_FUNCTION, FUNCTIONPOINT, 108),
 +
 +  /* Set the userdata for the ssl context callback function's third
 +     argument */
 +  CINIT(SSL_CTX_DATA, OBJECTPOINT, 109),
 +
 +  /* FTP Option that causes missing dirs to be created on the remote server.
 +     In 7.19.4 we introduced the convenience enums for this option using the
 +     CURLFTP_CREATE_DIR prefix.
 +  */
 +  CINIT(FTP_CREATE_MISSING_DIRS, LONG, 110),
 +
 +  /* Set this to a bitmask value to enable the particular authentications
 +     methods you like. Use this in combination with CURLOPT_PROXYUSERPWD.
 +     Note that setting multiple bits may cause extra network round-trips. */
 +  CINIT(PROXYAUTH, LONG, 111),
 +
 +  /* FTP option that changes the timeout, in seconds, associated with
 +     getting a response.  This is different from transfer timeout time and
 +     essentially places a demand on the FTP server to acknowledge commands
 +     in a timely manner. */
 +  CINIT(FTP_RESPONSE_TIMEOUT, LONG, 112),
 +#define CURLOPT_SERVER_RESPONSE_TIMEOUT CURLOPT_FTP_RESPONSE_TIMEOUT
 +
 +  /* Set this option to one of the CURL_IPRESOLVE_* defines (see below) to
 +     tell libcurl to resolve names to those IP versions only. This only has
 +     affect on systems with support for more than one, i.e IPv4 _and_ IPv6. */
 +  CINIT(IPRESOLVE, LONG, 113),
 +
 +  /* Set this option to limit the size of a file that will be downloaded from
 +     an HTTP or FTP server.
 +
 +     Note there is also _LARGE version which adds large file support for
 +     platforms which have larger off_t sizes.  See MAXFILESIZE_LARGE below. */
 +  CINIT(MAXFILESIZE, LONG, 114),
 +
 +  /* See the comment for INFILESIZE above, but in short, specifies
 +   * the size of the file being uploaded.  -1 means unknown.
 +   */
 +  CINIT(INFILESIZE_LARGE, OFF_T, 115),
 +
 +  /* Sets the continuation offset.  There is also a LONG version of this;
 +   * look above for RESUME_FROM.
 +   */
 +  CINIT(RESUME_FROM_LARGE, OFF_T, 116),
 +
 +  /* Sets the maximum size of data that will be downloaded from
 +   * an HTTP or FTP server.  See MAXFILESIZE above for the LONG version.
 +   */
 +  CINIT(MAXFILESIZE_LARGE, OFF_T, 117),
 +
 +  /* Set this option to the file name of your .netrc file you want libcurl
 +     to parse (using the CURLOPT_NETRC option). If not set, libcurl will do
 +     a poor attempt to find the user's home directory and check for a .netrc
 +     file in there. */
 +  CINIT(NETRC_FILE, STRINGPOINT, 118),
 +
 +  /* Enable SSL/TLS for FTP, pick one of:
 +     CURLUSESSL_TRY     - try using SSL, proceed anyway otherwise
 +     CURLUSESSL_CONTROL - SSL for the control connection or fail
 +     CURLUSESSL_ALL     - SSL for all communication or fail
 +  */
 +  CINIT(USE_SSL, LONG, 119),
 +
 +  /* The _LARGE version of the standard POSTFIELDSIZE option */
 +  CINIT(POSTFIELDSIZE_LARGE, OFF_T, 120),
 +
 +  /* Enable/disable the TCP Nagle algorithm */
 +  CINIT(TCP_NODELAY, LONG, 121),
 +
 +  /* 122 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
 +  /* 123 OBSOLETE. Gone in 7.16.0 */
 +  /* 124 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
 +  /* 125 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
 +  /* 126 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
 +  /* 127 OBSOLETE. Gone in 7.16.0 */
 +  /* 128 OBSOLETE. Gone in 7.16.0 */
 +
 +  /* When FTP over SSL/TLS is selected (with CURLOPT_USE_SSL), this option
 +     can be used to change libcurl's default action which is to first try
 +     "AUTH SSL" and then "AUTH TLS" in this order, and proceed when a OK
 +     response has been received.
 +
 +     Available parameters are:
 +     CURLFTPAUTH_DEFAULT - let libcurl decide
 +     CURLFTPAUTH_SSL     - try "AUTH SSL" first, then TLS
 +     CURLFTPAUTH_TLS     - try "AUTH TLS" first, then SSL
 +  */
 +  CINIT(FTPSSLAUTH, LONG, 129),
 +
 +  CINIT(IOCTLFUNCTION, FUNCTIONPOINT, 130),
 +  CINIT(IOCTLDATA, OBJECTPOINT, 131),
 +
 +  /* 132 OBSOLETE. Gone in 7.16.0 */
 +  /* 133 OBSOLETE. Gone in 7.16.0 */
 +
 +  /* zero terminated string for pass on to the FTP server when asked for
 +     "account" info */
 +  CINIT(FTP_ACCOUNT, STRINGPOINT, 134),
 +
 +  /* feed cookie into cookie engine */
 +  CINIT(COOKIELIST, STRINGPOINT, 135),
 +
 +  /* ignore Content-Length */
 +  CINIT(IGNORE_CONTENT_LENGTH, LONG, 136),
 +
 +  /* Set to non-zero to skip the IP address received in a 227 PASV FTP server
 +     response. Typically used for FTP-SSL purposes but is not restricted to
 +     that. libcurl will then instead use the same IP address it used for the
 +     control connection. */
 +  CINIT(FTP_SKIP_PASV_IP, LONG, 137),
 +
 +  /* Select "file method" to use when doing FTP, see the curl_ftpmethod
 +     above. */
 +  CINIT(FTP_FILEMETHOD, LONG, 138),
 +
 +  /* Local port number to bind the socket to */
 +  CINIT(LOCALPORT, LONG, 139),
 +
 +  /* Number of ports to try, including the first one set with LOCALPORT.
 +     Thus, setting it to 1 will make no additional attempts but the first.
 +  */
 +  CINIT(LOCALPORTRANGE, LONG, 140),
 +
 +  /* no transfer, set up connection and let application use the socket by
 +     extracting it with CURLINFO_LASTSOCKET */
 +  CINIT(CONNECT_ONLY, LONG, 141),
 +
 +  /* Function that will be called to convert from the
 +     network encoding (instead of using the iconv calls in libcurl) */
 +  CINIT(CONV_FROM_NETWORK_FUNCTION, FUNCTIONPOINT, 142),
 +
 +  /* Function that will be called to convert to the
 +     network encoding (instead of using the iconv calls in libcurl) */
 +  CINIT(CONV_TO_NETWORK_FUNCTION, FUNCTIONPOINT, 143),
 +
 +  /* Function that will be called to convert from UTF8
 +     (instead of using the iconv calls in libcurl)
 +     Note that this is used only for SSL certificate processing */
 +  CINIT(CONV_FROM_UTF8_FUNCTION, FUNCTIONPOINT, 144),
 +
 +  /* if the connection proceeds too quickly then need to slow it down */
 +  /* limit-rate: maximum number of bytes per second to send or receive */
 +  CINIT(MAX_SEND_SPEED_LARGE, OFF_T, 145),
 +  CINIT(MAX_RECV_SPEED_LARGE, OFF_T, 146),
 +
 +  /* Pointer to command string to send if USER/PASS fails. */
 +  CINIT(FTP_ALTERNATIVE_TO_USER, STRINGPOINT, 147),
 +
 +  /* callback function for setting socket options */
 +  CINIT(SOCKOPTFUNCTION, FUNCTIONPOINT, 148),
 +  CINIT(SOCKOPTDATA, OBJECTPOINT, 149),
 +
 +  /* set to 0 to disable session ID re-use for this transfer, default is
 +     enabled (== 1) */
 +  CINIT(SSL_SESSIONID_CACHE, LONG, 150),
 +
 +  /* allowed SSH authentication methods */
 +  CINIT(SSH_AUTH_TYPES, LONG, 151),
 +
 +  /* Used by scp/sftp to do public/private key authentication */
 +  CINIT(SSH_PUBLIC_KEYFILE, STRINGPOINT, 152),
 +  CINIT(SSH_PRIVATE_KEYFILE, STRINGPOINT, 153),
 +
 +  /* Send CCC (Clear Command Channel) after authentication */
 +  CINIT(FTP_SSL_CCC, LONG, 154),
 +
 +  /* Same as TIMEOUT and CONNECTTIMEOUT, but with ms resolution */
 +  CINIT(TIMEOUT_MS, LONG, 155),
 +  CINIT(CONNECTTIMEOUT_MS, LONG, 156),
 +
 +  /* set to zero to disable the libcurl's decoding and thus pass the raw body
 +     data to the application even when it is encoded/compressed */
 +  CINIT(HTTP_TRANSFER_DECODING, LONG, 157),
 +  CINIT(HTTP_CONTENT_DECODING, LONG, 158),
 +
 +  /* Permission used when creating new files and directories on the remote
 +     server for protocols that support it, SFTP/SCP/FILE */
 +  CINIT(NEW_FILE_PERMS, LONG, 159),
 +  CINIT(NEW_DIRECTORY_PERMS, LONG, 160),
 +
 +  /* Set the behaviour of POST when redirecting. Values must be set to one
 +     of CURL_REDIR* defines below. This used to be called CURLOPT_POST301 */
 +  CINIT(POSTREDIR, LONG, 161),
 +
 +  /* used by scp/sftp to verify the host's public key */
 +  CINIT(SSH_HOST_PUBLIC_KEY_MD5, STRINGPOINT, 162),
 +
 +  /* Callback function for opening socket (instead of socket(2)). Optionally,
 +     callback is able change the address or refuse to connect returning
 +     CURL_SOCKET_BAD.  The callback should have type
 +     curl_opensocket_callback */
 +  CINIT(OPENSOCKETFUNCTION, FUNCTIONPOINT, 163),
 +  CINIT(OPENSOCKETDATA, OBJECTPOINT, 164),
 +
 +  /* POST volatile input fields. */
 +  CINIT(COPYPOSTFIELDS, OBJECTPOINT, 165),
 +
 +  /* set transfer mode (;type=<a|i>) when doing FTP via an HTTP proxy */
 +  CINIT(PROXY_TRANSFER_MODE, LONG, 166),
 +
 +  /* Callback function for seeking in the input stream */
 +  CINIT(SEEKFUNCTION, FUNCTIONPOINT, 167),
 +  CINIT(SEEKDATA, OBJECTPOINT, 168),
 +
 +  /* CRL file */
 +  CINIT(CRLFILE, STRINGPOINT, 169),
 +
 +  /* Issuer certificate */
 +  CINIT(ISSUERCERT, STRINGPOINT, 170),
 +
 +  /* (IPv6) Address scope */
 +  CINIT(ADDRESS_SCOPE, LONG, 171),
 +
 +  /* Collect certificate chain info and allow it to get retrievable with
 +     CURLINFO_CERTINFO after the transfer is complete. */
 +  CINIT(CERTINFO, LONG, 172),
 +
 +  /* "name" and "pwd" to use when fetching. */
 +  CINIT(USERNAME, STRINGPOINT, 173),
 +  CINIT(PASSWORD, STRINGPOINT, 174),
 +
 +    /* "name" and "pwd" to use with Proxy when fetching. */
 +  CINIT(PROXYUSERNAME, STRINGPOINT, 175),
 +  CINIT(PROXYPASSWORD, STRINGPOINT, 176),
 +
 +  /* Comma separated list of hostnames defining no-proxy zones. These should
 +     match both hostnames directly, and hostnames within a domain. For
 +     example, local.com will match local.com and www.local.com, but NOT
 +     notlocal.com or www.notlocal.com. For compatibility with other
 +     implementations of this, .local.com will be considered to be the same as
 +     local.com. A single * is the only valid wildcard, and effectively
 +     disables the use of proxy. */
 +  CINIT(NOPROXY, STRINGPOINT, 177),
 +
 +  /* block size for TFTP transfers */
 +  CINIT(TFTP_BLKSIZE, LONG, 178),
 +
 +  /* Socks Service */
 +  CINIT(SOCKS5_GSSAPI_SERVICE, STRINGPOINT, 179), /* DEPRECATED, do not use! */
 +
 +  /* Socks Service */
 +  CINIT(SOCKS5_GSSAPI_NEC, LONG, 180),
 +
 +  /* set the bitmask for the protocols that are allowed to be used for the
 +     transfer, which thus helps the app which takes URLs from users or other
 +     external inputs and want to restrict what protocol(s) to deal
 +     with. Defaults to CURLPROTO_ALL. */
 +  CINIT(PROTOCOLS, LONG, 181),
 +
 +  /* set the bitmask for the protocols that libcurl is allowed to follow to,
 +     as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs
 +     to be set in both bitmasks to be allowed to get redirected to. Defaults
 +     to all protocols except FILE and SCP. */
 +  CINIT(REDIR_PROTOCOLS, LONG, 182),
 +
 +  /* set the SSH knownhost file name to use */
 +  CINIT(SSH_KNOWNHOSTS, STRINGPOINT, 183),
 +
 +  /* set the SSH host key callback, must point to a curl_sshkeycallback
 +     function */
 +  CINIT(SSH_KEYFUNCTION, FUNCTIONPOINT, 184),
 +
 +  /* set the SSH host key callback custom pointer */
 +  CINIT(SSH_KEYDATA, OBJECTPOINT, 185),
 +
 +  /* set the SMTP mail originator */
 +  CINIT(MAIL_FROM, STRINGPOINT, 186),
 +
 +  /* set the list of SMTP mail receiver(s) */
 +  CINIT(MAIL_RCPT, OBJECTPOINT, 187),
 +
 +  /* FTP: send PRET before PASV */
 +  CINIT(FTP_USE_PRET, LONG, 188),
 +
 +  /* RTSP request method (OPTIONS, SETUP, PLAY, etc...) */
 +  CINIT(RTSP_REQUEST, LONG, 189),
 +
 +  /* The RTSP session identifier */
 +  CINIT(RTSP_SESSION_ID, STRINGPOINT, 190),
 +
 +  /* The RTSP stream URI */
 +  CINIT(RTSP_STREAM_URI, STRINGPOINT, 191),
 +
 +  /* The Transport: header to use in RTSP requests */
 +  CINIT(RTSP_TRANSPORT, STRINGPOINT, 192),
 +
 +  /* Manually initialize the client RTSP CSeq for this handle */
 +  CINIT(RTSP_CLIENT_CSEQ, LONG, 193),
 +
 +  /* Manually initialize the server RTSP CSeq for this handle */
 +  CINIT(RTSP_SERVER_CSEQ, LONG, 194),
 +
 +  /* The stream to pass to INTERLEAVEFUNCTION. */
 +  CINIT(INTERLEAVEDATA, OBJECTPOINT, 195),
 +
 +  /* Let the application define a custom write method for RTP data */
 +  CINIT(INTERLEAVEFUNCTION, FUNCTIONPOINT, 196),
 +
 +  /* Turn on wildcard matching */
 +  CINIT(WILDCARDMATCH, LONG, 197),
 +
 +  /* Directory matching callback called before downloading of an
 +     individual file (chunk) started */
 +  CINIT(CHUNK_BGN_FUNCTION, FUNCTIONPOINT, 198),
 +
 +  /* Directory matching callback called after the file (chunk)
 +     was downloaded, or skipped */
 +  CINIT(CHUNK_END_FUNCTION, FUNCTIONPOINT, 199),
 +
 +  /* Change match (fnmatch-like) callback for wildcard matching */
 +  CINIT(FNMATCH_FUNCTION, FUNCTIONPOINT, 200),
 +
 +  /* Let the application define custom chunk data pointer */
 +  CINIT(CHUNK_DATA, OBJECTPOINT, 201),
 +
 +  /* FNMATCH_FUNCTION user pointer */
 +  CINIT(FNMATCH_DATA, OBJECTPOINT, 202),
 +
 +  /* send linked-list of name:port:address sets */
 +  CINIT(RESOLVE, OBJECTPOINT, 203),
 +
 +  /* Set a username for authenticated TLS */
 +  CINIT(TLSAUTH_USERNAME, STRINGPOINT, 204),
 +
 +  /* Set a password for authenticated TLS */
 +  CINIT(TLSAUTH_PASSWORD, STRINGPOINT, 205),
 +
 +  /* Set authentication type for authenticated TLS */
 +  CINIT(TLSAUTH_TYPE, STRINGPOINT, 206),
 +
 +  /* Set to 1 to enable the "TE:" header in HTTP requests to ask for
 +     compressed transfer-encoded responses. Set to 0 to disable the use of TE:
 +     in outgoing requests. The current default is 0, but it might change in a
 +     future libcurl release.
 +
 +     libcurl will ask for the compressed methods it knows of, and if that
 +     isn't any, it will not ask for transfer-encoding at all even if this
 +     option is set to 1.
 +
 +  */
 +  CINIT(TRANSFER_ENCODING, LONG, 207),
 +
 +  /* Callback function for closing socket (instead of close(2)). The callback
 +     should have type curl_closesocket_callback */
 +  CINIT(CLOSESOCKETFUNCTION, FUNCTIONPOINT, 208),
 +  CINIT(CLOSESOCKETDATA, OBJECTPOINT, 209),
 +
 +  /* allow GSSAPI credential delegation */
 +  CINIT(GSSAPI_DELEGATION, LONG, 210),
 +
 +  /* Set the name servers to use for DNS resolution */
 +  CINIT(DNS_SERVERS, STRINGPOINT, 211),
 +
 +  /* Time-out accept operations (currently for FTP only) after this amount
-      of miliseconds. */
++     of milliseconds. */
 +  CINIT(ACCEPTTIMEOUT_MS, LONG, 212),
 +
 +  /* Set TCP keepalive */
 +  CINIT(TCP_KEEPALIVE, LONG, 213),
 +
 +  /* non-universal keepalive knobs (Linux, AIX, HP-UX, more) */
 +  CINIT(TCP_KEEPIDLE, LONG, 214),
 +  CINIT(TCP_KEEPINTVL, LONG, 215),
 +
 +  /* Enable/disable specific SSL features with a bitmask, see CURLSSLOPT_* */
 +  CINIT(SSL_OPTIONS, LONG, 216),
 +
 +  /* Set the SMTP auth originator */
 +  CINIT(MAIL_AUTH, STRINGPOINT, 217),
 +
 +  /* Enable/disable SASL initial response */
 +  CINIT(SASL_IR, LONG, 218),
 +
 +  /* Function that will be called instead of the internal progress display
 +   * function. This function should be defined as the curl_xferinfo_callback
 +   * prototype defines. (Deprecates CURLOPT_PROGRESSFUNCTION) */
 +  CINIT(XFERINFOFUNCTION, FUNCTIONPOINT, 219),
 +
 +  /* The XOAUTH2 bearer token */
 +  CINIT(XOAUTH2_BEARER, STRINGPOINT, 220),
 +
 +  /* Set the interface string to use as outgoing network
 +   * interface for DNS requests.
 +   * Only supported by the c-ares DNS backend */
 +  CINIT(DNS_INTERFACE, STRINGPOINT, 221),
 +
 +  /* Set the local IPv4 address to use for outgoing DNS requests.
 +   * Only supported by the c-ares DNS backend */
 +  CINIT(DNS_LOCAL_IP4, STRINGPOINT, 222),
 +
 +  /* Set the local IPv4 address to use for outgoing DNS requests.
 +   * Only supported by the c-ares DNS backend */
 +  CINIT(DNS_LOCAL_IP6, STRINGPOINT, 223),
 +
 +  /* Set authentication options directly */
 +  CINIT(LOGIN_OPTIONS, STRINGPOINT, 224),
 +
 +  /* Enable/disable TLS NPN extension (http2 over ssl might fail without) */
 +  CINIT(SSL_ENABLE_NPN, LONG, 225),
 +
 +  /* Enable/disable TLS ALPN extension (http2 over ssl might fail without) */
 +  CINIT(SSL_ENABLE_ALPN, LONG, 226),
 +
 +  /* Time to wait for a response to a HTTP request containing an
 +   * Expect: 100-continue header before sending the data anyway. */
 +  CINIT(EXPECT_100_TIMEOUT_MS, LONG, 227),
 +
 +  /* This points to a linked list of headers used for proxy requests only,
 +     struct curl_slist kind */
 +  CINIT(PROXYHEADER, OBJECTPOINT, 228),
 +
 +  /* Pass in a bitmask of "header options" */
 +  CINIT(HEADEROPT, LONG, 229),
 +
 +  /* The public key in DER form used to validate the peer public key
 +     this option is used only if SSL_VERIFYPEER is true */
 +  CINIT(PINNEDPUBLICKEY, STRINGPOINT, 230),
 +
 +  /* Path to Unix domain socket */
 +  CINIT(UNIX_SOCKET_PATH, STRINGPOINT, 231),
 +
 +  /* Set if we should verify the certificate status. */
 +  CINIT(SSL_VERIFYSTATUS, LONG, 232),
 +
 +  /* Set if we should enable TLS false start. */
 +  CINIT(SSL_FALSESTART, LONG, 233),
 +
 +  /* Do not squash dot-dot sequences */
 +  CINIT(PATH_AS_IS, LONG, 234),
 +
 +  /* Proxy Service Name */
 +  CINIT(PROXY_SERVICE_NAME, STRINGPOINT, 235),
 +
 +  /* Service Name */
 +  CINIT(SERVICE_NAME, STRINGPOINT, 236),
 +
 +  /* Wait/don't wait for pipe/mutex to clarify */
 +  CINIT(PIPEWAIT, LONG, 237),
 +
 +  /* Set the protocol used when curl is given a URL without a protocol */
 +  CINIT(DEFAULT_PROTOCOL, STRINGPOINT, 238),
 +
 +  /* Set stream weight, 1 - 256 (default is 16) */
 +  CINIT(STREAM_WEIGHT, LONG, 239),
 +
 +  /* Set stream dependency on another CURL handle */
 +  CINIT(STREAM_DEPENDS, OBJECTPOINT, 240),
 +
 +  /* Set E-xclusive stream dependency on another CURL handle */
 +  CINIT(STREAM_DEPENDS_E, OBJECTPOINT, 241),
 +
 +  /* Do not send any tftp option requests to the server */
 +  CINIT(TFTP_NO_OPTIONS, LONG, 242),
 +
 +  /* Linked-list of host:port:connect-to-host:connect-to-port,
 +     overrides the URL's host:port (only for the network layer) */
 +  CINIT(CONNECT_TO, OBJECTPOINT, 243),
 +
 +  /* Set TCP Fast Open */
 +  CINIT(TCP_FASTOPEN, LONG, 244),
 +
 +  /* Continue to send data if the server responds early with an
 +   * HTTP status code >= 300 */
 +  CINIT(KEEP_SENDING_ON_ERROR, LONG, 245),
 +
 +  /* The CApath or CAfile used to validate the proxy certificate
 +     this option is used only if PROXY_SSL_VERIFYPEER is true */
 +  CINIT(PROXY_CAINFO, STRINGPOINT, 246),
 +
 +  /* The CApath directory used to validate the proxy certificate
 +     this option is used only if PROXY_SSL_VERIFYPEER is true */
 +  CINIT(PROXY_CAPATH, STRINGPOINT, 247),
 +
 +  /* Set if we should verify the proxy in ssl handshake,
 +     set 1 to verify. */
 +  CINIT(PROXY_SSL_VERIFYPEER, LONG, 248),
 +
 +  /* Set if we should verify the Common name from the proxy certificate in ssl
 +   * handshake, set 1 to check existence, 2 to ensure that it matches
 +   * the provided hostname. */
 +  CINIT(PROXY_SSL_VERIFYHOST, LONG, 249),
 +
 +  /* What version to specifically try to use for proxy.
 +     See CURL_SSLVERSION defines below. */
 +  CINIT(PROXY_SSLVERSION, LONG, 250),
 +
 +  /* Set a username for authenticated TLS for proxy */
 +  CINIT(PROXY_TLSAUTH_USERNAME, STRINGPOINT, 251),
 +
 +  /* Set a password for authenticated TLS for proxy */
 +  CINIT(PROXY_TLSAUTH_PASSWORD, STRINGPOINT, 252),
 +
 +  /* Set authentication type for authenticated TLS for proxy */
 +  CINIT(PROXY_TLSAUTH_TYPE, STRINGPOINT, 253),
 +
 +  /* name of the file keeping your private SSL-certificate for proxy */
 +  CINIT(PROXY_SSLCERT, STRINGPOINT, 254),
 +
 +  /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") for
 +     proxy */
 +  CINIT(PROXY_SSLCERTTYPE, STRINGPOINT, 255),
 +
 +  /* name of the file keeping your private SSL-key for proxy */
 +  CINIT(PROXY_SSLKEY, STRINGPOINT, 256),
 +
 +  /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") for
 +     proxy */
 +  CINIT(PROXY_SSLKEYTYPE, STRINGPOINT, 257),
 +
 +  /* password for the SSL private key for proxy */
 +  CINIT(PROXY_KEYPASSWD, STRINGPOINT, 258),
 +
 +  /* Specify which SSL ciphers to use for proxy */
 +  CINIT(PROXY_SSL_CIPHER_LIST, STRINGPOINT, 259),
 +
 +  /* CRL file for proxy */
 +  CINIT(PROXY_CRLFILE, STRINGPOINT, 260),
 +
 +  /* Enable/disable specific SSL features with a bitmask for proxy, see
 +     CURLSSLOPT_* */
 +  CINIT(PROXY_SSL_OPTIONS, LONG, 261),
 +
 +  /* Name of pre proxy to use. */
 +  CINIT(PRE_PROXY, STRINGPOINT, 262),
 +
 +  /* The public key in DER form used to validate the proxy public key
 +     this option is used only if PROXY_SSL_VERIFYPEER is true */
 +  CINIT(PROXY_PINNEDPUBLICKEY, STRINGPOINT, 263),
 +
++  /* Path to an abstract Unix domain socket */
++  CINIT(ABSTRACT_UNIX_SOCKET, STRINGPOINT, 264),
++
++  /* Suppress proxy CONNECT response headers from user callbacks */
++  CINIT(SUPPRESS_CONNECT_HEADERS, LONG, 265),
++
 +  CURLOPT_LASTENTRY /* the last unused */
 +} CURLoption;
 +
 +#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
 +                          the obsolete stuff removed! */
 +
 +/* Backwards compatibility with older names */
 +/* These are scheduled to disappear by 2011 */
 +
 +/* This was added in version 7.19.1 */
 +#define CURLOPT_POST301 CURLOPT_POSTREDIR
 +
 +/* These are scheduled to disappear by 2009 */
 +
 +/* The following were added in 7.17.0 */
 +#define CURLOPT_SSLKEYPASSWD CURLOPT_KEYPASSWD
 +#define CURLOPT_FTPAPPEND CURLOPT_APPEND
 +#define CURLOPT_FTPLISTONLY CURLOPT_DIRLISTONLY
 +#define CURLOPT_FTP_SSL CURLOPT_USE_SSL
 +
 +/* The following were added earlier */
 +
 +#define CURLOPT_SSLCERTPASSWD CURLOPT_KEYPASSWD
 +#define CURLOPT_KRB4LEVEL CURLOPT_KRBLEVEL
 +
 +#else
 +/* This is set if CURL_NO_OLDIES is defined at compile-time */
 +#undef CURLOPT_DNS_USE_GLOBAL_CACHE /* soon obsolete */
 +#endif
 +
 +
 +  /* Below here follows defines for the CURLOPT_IPRESOLVE option. If a host
 +     name resolves addresses using more than one IP protocol version, this
 +     option might be handy to force libcurl to use a specific IP version. */
 +#define CURL_IPRESOLVE_WHATEVER 0 /* default, resolves addresses to all IP
 +                                     versions that your system allows */
 +#define CURL_IPRESOLVE_V4       1 /* resolve to IPv4 addresses */
 +#define CURL_IPRESOLVE_V6       2 /* resolve to IPv6 addresses */
 +
 +  /* three convenient "aliases" that follow the name scheme better */
 +#define CURLOPT_RTSPHEADER CURLOPT_HTTPHEADER
 +
 +  /* These enums are for use with the CURLOPT_HTTP_VERSION option. */
 +enum {
 +  CURL_HTTP_VERSION_NONE, /* setting this means we don't care, and that we'd
 +                             like the library to choose the best possible
 +                             for us! */
 +  CURL_HTTP_VERSION_1_0,  /* please use HTTP 1.0 in the request */
 +  CURL_HTTP_VERSION_1_1,  /* please use HTTP 1.1 in the request */
 +  CURL_HTTP_VERSION_2_0,  /* please use HTTP 2 in the request */
 +  CURL_HTTP_VERSION_2TLS, /* use version 2 for HTTPS, version 1.1 for HTTP */
 +  CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE,  /* please use HTTP 2 without HTTP/1.1
 +                                           Upgrade */
 +
 +  CURL_HTTP_VERSION_LAST /* *ILLEGAL* http version */
 +};
 +
 +/* Convenience definition simple because the name of the version is HTTP/2 and
 +   not 2.0. The 2_0 version of the enum name was set while the version was
 +   still planned to be 2.0 and we stick to it for compatibility. */
 +#define CURL_HTTP_VERSION_2 CURL_HTTP_VERSION_2_0
 +
 +/*
 + * Public API enums for RTSP requests
 + */
 +enum {
 +    CURL_RTSPREQ_NONE, /* first in list */
 +    CURL_RTSPREQ_OPTIONS,
 +    CURL_RTSPREQ_DESCRIBE,
 +    CURL_RTSPREQ_ANNOUNCE,
 +    CURL_RTSPREQ_SETUP,
 +    CURL_RTSPREQ_PLAY,
 +    CURL_RTSPREQ_PAUSE,
 +    CURL_RTSPREQ_TEARDOWN,
 +    CURL_RTSPREQ_GET_PARAMETER,
 +    CURL_RTSPREQ_SET_PARAMETER,
 +    CURL_RTSPREQ_RECORD,
 +    CURL_RTSPREQ_RECEIVE,
 +    CURL_RTSPREQ_LAST /* last in list */
 +};
 +
 +  /* These enums are for use with the CURLOPT_NETRC option. */
 +enum CURL_NETRC_OPTION {
 +  CURL_NETRC_IGNORED,     /* The .netrc will never be read.
 +                           * This is the default. */
 +  CURL_NETRC_OPTIONAL,    /* A user:password in the URL will be preferred
 +                           * to one in the .netrc. */
 +  CURL_NETRC_REQUIRED,    /* A user:password in the URL will be ignored.
 +                           * Unless one is set programmatically, the .netrc
 +                           * will be queried. */
 +  CURL_NETRC_LAST
 +};
 +
 +enum {
 +  CURL_SSLVERSION_DEFAULT,
 +  CURL_SSLVERSION_TLSv1, /* TLS 1.x */
 +  CURL_SSLVERSION_SSLv2,
 +  CURL_SSLVERSION_SSLv3,
 +  CURL_SSLVERSION_TLSv1_0,
 +  CURL_SSLVERSION_TLSv1_1,
 +  CURL_SSLVERSION_TLSv1_2,
 +  CURL_SSLVERSION_TLSv1_3,
 +
 +  CURL_SSLVERSION_LAST /* never use, keep last */
 +};
 +
++enum {
++  CURL_SSLVERSION_MAX_NONE =     0,
++  CURL_SSLVERSION_MAX_DEFAULT =  (CURL_SSLVERSION_TLSv1   << 16),
++  CURL_SSLVERSION_MAX_TLSv1_0 =  (CURL_SSLVERSION_TLSv1_0 << 16),
++  CURL_SSLVERSION_MAX_TLSv1_1 =  (CURL_SSLVERSION_TLSv1_1 << 16),
++  CURL_SSLVERSION_MAX_TLSv1_2 =  (CURL_SSLVERSION_TLSv1_2 << 16),
++  CURL_SSLVERSION_MAX_TLSv1_3 =  (CURL_SSLVERSION_TLSv1_3 << 16),
++
++  /* never use, keep last */
++  CURL_SSLVERSION_MAX_LAST =     (CURL_SSLVERSION_LAST    << 16)
++};
++
 +enum CURL_TLSAUTH {
 +  CURL_TLSAUTH_NONE,
 +  CURL_TLSAUTH_SRP,
 +  CURL_TLSAUTH_LAST /* never use, keep last */
 +};
 +
 +/* symbols to use with CURLOPT_POSTREDIR.
 +   CURL_REDIR_POST_301, CURL_REDIR_POST_302 and CURL_REDIR_POST_303
 +   can be bitwise ORed so that CURL_REDIR_POST_301 | CURL_REDIR_POST_302
 +   | CURL_REDIR_POST_303 == CURL_REDIR_POST_ALL */
 +
 +#define CURL_REDIR_GET_ALL  0
 +#define CURL_REDIR_POST_301 1
 +#define CURL_REDIR_POST_302 2
 +#define CURL_REDIR_POST_303 4
 +#define CURL_REDIR_POST_ALL \
 +    (CURL_REDIR_POST_301|CURL_REDIR_POST_302|CURL_REDIR_POST_303)
 +
 +typedef enum {
 +  CURL_TIMECOND_NONE,
 +
 +  CURL_TIMECOND_IFMODSINCE,
 +  CURL_TIMECOND_IFUNMODSINCE,
 +  CURL_TIMECOND_LASTMOD,
 +
 +  CURL_TIMECOND_LAST
 +} curl_TimeCond;
 +
 +
 +/* curl_strequal() and curl_strnequal() are subject for removal in a future
 +   libcurl, see lib/README.curlx for details
 +
 +   !checksrc! disable SPACEBEFOREPAREN 2
 +*/
 +CURL_EXTERN int (curl_strequal)(const char *s1, const char *s2);
 +CURL_EXTERN int (curl_strnequal)(const char *s1, const char *s2, size_t n);
 +
 +/* name is uppercase CURLFORM_<name> */
 +#ifdef CFINIT
 +#undef CFINIT
 +#endif
 +
 +#ifdef CURL_ISOCPP
 +#define CFINIT(name) CURLFORM_ ## name
 +#else
 +/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */
 +#define CFINIT(name) CURLFORM_/**/name
 +#endif
 +
 +typedef enum {
 +  CFINIT(NOTHING),        /********* the first one is unused ************/
 +
 +  /*  */
 +  CFINIT(COPYNAME),
 +  CFINIT(PTRNAME),
 +  CFINIT(NAMELENGTH),
 +  CFINIT(COPYCONTENTS),
 +  CFINIT(PTRCONTENTS),
 +  CFINIT(CONTENTSLENGTH),
 +  CFINIT(FILECONTENT),
 +  CFINIT(ARRAY),
 +  CFINIT(OBSOLETE),
 +  CFINIT(FILE),
 +
 +  CFINIT(BUFFER),
 +  CFINIT(BUFFERPTR),
 +  CFINIT(BUFFERLENGTH),
 +
 +  CFINIT(CONTENTTYPE),
 +  CFINIT(CONTENTHEADER),
 +  CFINIT(FILENAME),
 +  CFINIT(END),
 +  CFINIT(OBSOLETE2),
 +
 +  CFINIT(STREAM),
 +  CFINIT(CONTENTLEN), /* added in 7.46.0, provide a curl_off_t length */
 +
 +  CURLFORM_LASTENTRY /* the last unused */
 +} CURLformoption;
 +
 +#undef CFINIT /* done */
 +
 +/* structure to be used as parameter for CURLFORM_ARRAY */
 +struct curl_forms {
 +  CURLformoption option;
 +  const char     *value;
 +};
 +
 +/* use this for multipart formpost building */
 +/* Returns code for curl_formadd()
 + *
 + * Returns:
 + * CURL_FORMADD_OK             on success
 + * CURL_FORMADD_MEMORY         if the FormInfo allocation fails
 + * CURL_FORMADD_OPTION_TWICE   if one option is given twice for one Form
 + * CURL_FORMADD_NULL           if a null pointer was given for a char
 + * CURL_FORMADD_MEMORY         if the allocation of a FormInfo struct failed
 + * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used
 + * CURL_FORMADD_INCOMPLETE     if the some FormInfo is not complete (or error)
 + * CURL_FORMADD_MEMORY         if a curl_httppost struct cannot be allocated
 + * CURL_FORMADD_MEMORY         if some allocation for string copying failed.
 + * CURL_FORMADD_ILLEGAL_ARRAY  if an illegal option is used in an array
 + *
 + ***************************************************************************/
 +typedef enum {
 +  CURL_FORMADD_OK, /* first, no error */
 +
 +  CURL_FORMADD_MEMORY,
 +  CURL_FORMADD_OPTION_TWICE,
 +  CURL_FORMADD_NULL,
 +  CURL_FORMADD_UNKNOWN_OPTION,
 +  CURL_FORMADD_INCOMPLETE,
 +  CURL_FORMADD_ILLEGAL_ARRAY,
 +  CURL_FORMADD_DISABLED, /* libcurl was built with this disabled */
 +
 +  CURL_FORMADD_LAST /* last */
 +} CURLFORMcode;
 +
 +/*
 + * NAME curl_formadd()
 + *
 + * DESCRIPTION
 + *
 + * Pretty advanced function for building multi-part formposts. Each invoke
 + * adds one part that together construct a full post. Then use
 + * CURLOPT_HTTPPOST to send it off to libcurl.
 + */
 +CURL_EXTERN CURLFORMcode curl_formadd(struct curl_httppost **httppost,
 +                                      struct curl_httppost **last_post,
 +                                      ...);
 +
 +/*
 + * callback function for curl_formget()
 + * The void *arg pointer will be the one passed as second argument to
 + *   curl_formget().
 + * The character buffer passed to it must not be freed.
 + * Should return the buffer length passed to it as the argument "len" on
 + *   success.
 + */
 +typedef size_t (*curl_formget_callback)(void *arg, const char *buf,
 +                                        size_t len);
 +
 +/*
 + * NAME curl_formget()
 + *
 + * DESCRIPTION
 + *
 + * Serialize a curl_httppost struct built with curl_formadd().
 + * Accepts a void pointer as second argument which will be passed to
 + * the curl_formget_callback function.
 + * Returns 0 on success.
 + */
 +CURL_EXTERN int curl_formget(struct curl_httppost *form, void *arg,
 +                             curl_formget_callback append);
 +/*
 + * NAME curl_formfree()
 + *
 + * DESCRIPTION
 + *
 + * Free a multipart formpost previously built with curl_formadd().
 + */
 +CURL_EXTERN void curl_formfree(struct curl_httppost *form);
 +
 +/*
 + * NAME curl_getenv()
 + *
 + * DESCRIPTION
 + *
 + * Returns a malloc()'ed string that MUST be curl_free()ed after usage is
 + * complete. DEPRECATED - see lib/README.curlx
 + */
 +CURL_EXTERN char *curl_getenv(const char *variable);
 +
 +/*
 + * NAME curl_version()
 + *
 + * DESCRIPTION
 + *
 + * Returns a static ascii string of the libcurl version.
 + */
 +CURL_EXTERN char *curl_version(void);
 +
 +/*
 + * NAME curl_easy_escape()
 + *
 + * DESCRIPTION
 + *
 + * Escapes URL strings (converts all letters consider illegal in URLs to their
 + * %XX versions). This function returns a new allocated string or NULL if an
 + * error occurred.
 + */
 +CURL_EXTERN char *curl_easy_escape(CURL *handle,
 +                                   const char *string,
 +                                   int length);
 +
 +/* the previous version: */
 +CURL_EXTERN char *curl_escape(const char *string,
 +                              int length);
 +
 +
 +/*
 + * NAME curl_easy_unescape()
 + *
 + * DESCRIPTION
 + *
 + * Unescapes URL encoding in strings (converts all %XX codes to their 8bit
 + * versions). This function returns a new allocated string or NULL if an error
 + * occurred.
 + * Conversion Note: On non-ASCII platforms the ASCII %XX codes are
 + * converted into the host encoding.
 + */
 +CURL_EXTERN char *curl_easy_unescape(CURL *handle,
 +                                     const char *string,
 +                                     int length,
 +                                     int *outlength);
 +
 +/* the previous version */
 +CURL_EXTERN char *curl_unescape(const char *string,
 +                                int length);
 +
 +/*
 + * NAME curl_free()
 + *
 + * DESCRIPTION
 + *
 + * Provided for de-allocation in the same translation unit that did the
 + * allocation. Added in libcurl 7.10
 + */
 +CURL_EXTERN void curl_free(void *p);
 +
 +/*
 + * NAME curl_global_init()
 + *
 + * DESCRIPTION
 + *
 + * curl_global_init() should be invoked exactly once for each application that
 + * uses libcurl and before any call of other libcurl functions.
 + *
 + * This function is not thread-safe!
 + */
 +CURL_EXTERN CURLcode curl_global_init(long flags);
 +
 +/*
 + * NAME curl_global_init_mem()
 + *
 + * DESCRIPTION
 + *
 + * curl_global_init() or curl_global_init_mem() should be invoked exactly once
 + * for each application that uses libcurl.  This function can be used to
 + * initialize libcurl and set user defined memory management callback
 + * functions.  Users can implement memory management routines to check for
 + * memory leaks, check for mis-use of the curl library etc.  User registered
 + * callback routines with be invoked by this library instead of the system
 + * memory management routines like malloc, free etc.
 + */
 +CURL_EXTERN CURLcode curl_global_init_mem(long flags,
 +                                          curl_malloc_callback m,
 +                                          curl_free_callback f,
 +                                          curl_realloc_callback r,
 +                                          curl_strdup_callback s,
 +                                          curl_calloc_callback c);
 +
 +/*
 + * NAME curl_global_cleanup()
 + *
 + * DESCRIPTION
 + *
 + * curl_global_cleanup() should be invoked exactly once for each application
 + * that uses libcurl
 + */
 +CURL_EXTERN void curl_global_cleanup(void);
 +
 +/* linked-list structure for the CURLOPT_QUOTE option (and other) */
 +struct curl_slist {
 +  char *data;
 +  struct curl_slist *next;
 +};
 +
 +/*
 + * NAME curl_slist_append()
 + *
 + * DESCRIPTION
 + *
 + * Appends a string to a linked list. If no list exists, it will be created
 + * first. Returns the new list, after appending.
 + */
 +CURL_EXTERN struct curl_slist *curl_slist_append(struct curl_slist *,
 +                                                 const char *);
 +
 +/*
 + * NAME curl_slist_free_all()
 + *
 + * DESCRIPTION
 + *
 + * free a previously built curl_slist.
 + */
 +CURL_EXTERN void curl_slist_free_all(struct curl_slist *);
 +
 +/*
 + * NAME curl_getdate()
 + *
 + * DESCRIPTION
 + *
 + * Returns the time, in seconds since 1 Jan 1970 of the time string given in
 + * the first argument. The time argument in the second parameter is unused
 + * and should be set to NULL.
 + */
 +CURL_EXTERN time_t curl_getdate(const char *p, const time_t *unused);
 +
 +/* info about the certificate chain, only for OpenSSL builds. Asked
 +   for with CURLOPT_CERTINFO / CURLINFO_CERTINFO */
 +struct curl_certinfo {
 +  int num_of_certs;             /* number of certificates with information */
 +  struct curl_slist **certinfo; /* for each index in this array, there's a
 +                                   linked list with textual information in the
 +                                   format "name: value" */
 +};
 +
 +/* enum for the different supported SSL backends */
 +typedef enum {
 +  CURLSSLBACKEND_NONE = 0,
 +  CURLSSLBACKEND_OPENSSL = 1,
 +  CURLSSLBACKEND_GNUTLS = 2,
 +  CURLSSLBACKEND_NSS = 3,
 +  CURLSSLBACKEND_OBSOLETE4 = 4,  /* Was QSOSSL. */
 +  CURLSSLBACKEND_GSKIT = 5,
 +  CURLSSLBACKEND_POLARSSL = 6,
 +  CURLSSLBACKEND_CYASSL = 7,
 +  CURLSSLBACKEND_SCHANNEL = 8,
 +  CURLSSLBACKEND_DARWINSSL = 9,
 +  CURLSSLBACKEND_AXTLS = 10,
 +  CURLSSLBACKEND_MBEDTLS = 11
 +} curl_sslbackend;
 +
 +/* aliases for library clones and renames */
 +#define CURLSSLBACKEND_LIBRESSL 1
 +#define CURLSSLBACKEND_BORINGSSL 1
 +#define CURLSSLBACKEND_WOLFSSL 6
 +
 +/* Information about the SSL library used and the respective internal SSL
 +   handle, which can be used to obtain further information regarding the
 +   connection. Asked for with CURLINFO_TLS_SSL_PTR or CURLINFO_TLS_SESSION. */
 +struct curl_tlssessioninfo {
 +  curl_sslbackend backend;
 +  void *internals;
 +};
 +
 +#define CURLINFO_STRING   0x100000
 +#define CURLINFO_LONG     0x200000
 +#define CURLINFO_DOUBLE   0x300000
 +#define CURLINFO_SLIST    0x400000
 +#define CURLINFO_SOCKET   0x500000
 +#define CURLINFO_MASK     0x0fffff
 +#define CURLINFO_TYPEMASK 0xf00000
 +
 +typedef enum {
 +  CURLINFO_NONE, /* first, never use this */
 +  CURLINFO_EFFECTIVE_URL    = CURLINFO_STRING + 1,
 +  CURLINFO_RESPONSE_CODE    = CURLINFO_LONG   + 2,
 +  CURLINFO_TOTAL_TIME       = CURLINFO_DOUBLE + 3,
 +  CURLINFO_NAMELOOKUP_TIME  = CURLINFO_DOUBLE + 4,
 +  CURLINFO_CONNECT_TIME     = CURLINFO_DOUBLE + 5,
 +  CURLINFO_PRETRANSFER_TIME = CURLINFO_DOUBLE + 6,
 +  CURLINFO_SIZE_UPLOAD      = CURLINFO_DOUBLE + 7,
 +  CURLINFO_SIZE_DOWNLOAD    = CURLINFO_DOUBLE + 8,
 +  CURLINFO_SPEED_DOWNLOAD   = CURLINFO_DOUBLE + 9,
 +  CURLINFO_SPEED_UPLOAD     = CURLINFO_DOUBLE + 10,
 +  CURLINFO_HEADER_SIZE      = CURLINFO_LONG   + 11,
 +  CURLINFO_REQUEST_SIZE     = CURLINFO_LONG   + 12,
 +  CURLINFO_SSL_VERIFYRESULT = CURLINFO_LONG   + 13,
 +  CURLINFO_FILETIME         = CURLINFO_LONG   + 14,
 +  CURLINFO_CONTENT_LENGTH_DOWNLOAD   = CURLINFO_DOUBLE + 15,
 +  CURLINFO_CONTENT_LENGTH_UPLOAD     = CURLINFO_DOUBLE + 16,
 +  CURLINFO_STARTTRANSFER_TIME = CURLINFO_DOUBLE + 17,
 +  CURLINFO_CONTENT_TYPE     = CURLINFO_STRING + 18,
 +  CURLINFO_REDIRECT_TIME    = CURLINFO_DOUBLE + 19,
 +  CURLINFO_REDIRECT_COUNT   = CURLINFO_LONG   + 20,
 +  CURLINFO_PRIVATE          = CURLINFO_STRING + 21,
 +  CURLINFO_HTTP_CONNECTCODE = CURLINFO_LONG   + 22,
 +  CURLINFO_HTTPAUTH_AVAIL   = CURLINFO_LONG   + 23,
 +  CURLINFO_PROXYAUTH_AVAIL  = CURLINFO_LONG   + 24,
 +  CURLINFO_OS_ERRNO         = CURLINFO_LONG   + 25,
 +  CURLINFO_NUM_CONNECTS     = CURLINFO_LONG   + 26,
 +  CURLINFO_SSL_ENGINES      = CURLINFO_SLIST  + 27,
 +  CURLINFO_COOKIELIST       = CURLINFO_SLIST  + 28,
 +  CURLINFO_LASTSOCKET       = CURLINFO_LONG   + 29,
 +  CURLINFO_FTP_ENTRY_PATH   = CURLINFO_STRING + 30,
 +  CURLINFO_REDIRECT_URL     = CURLINFO_STRING + 31,
 +  CURLINFO_PRIMARY_IP       = CURLINFO_STRING + 32,
 +  CURLINFO_APPCONNECT_TIME  = CURLINFO_DOUBLE + 33,
 +  CURLINFO_CERTINFO         = CURLINFO_SLIST  + 34,
 +  CURLINFO_CONDITION_UNMET  = CURLINFO_LONG   + 35,
 +  CURLINFO_RTSP_SESSION_ID  = CURLINFO_STRING + 36,
 +  CURLINFO_RTSP_CLIENT_CSEQ = CURLINFO_LONG   + 37,
 +  CURLINFO_RTSP_SERVER_CSEQ = CURLINFO_LONG   + 38,
 +  CURLINFO_RTSP_CSEQ_RECV   = CURLINFO_LONG   + 39,
 +  CURLINFO_PRIMARY_PORT     = CURLINFO_LONG   + 40,
 +  CURLINFO_LOCAL_IP         = CURLINFO_STRING + 41,
 +  CURLINFO_LOCAL_PORT       = CURLINFO_LONG   + 42,
 +  CURLINFO_TLS_SESSION      = CURLINFO_SLIST  + 43,
 +  CURLINFO_ACTIVESOCKET     = CURLINFO_SOCKET + 44,
 +  CURLINFO_TLS_SSL_PTR      = CURLINFO_SLIST  + 45,
 +  CURLINFO_HTTP_VERSION     = CURLINFO_LONG   + 46,
 +  CURLINFO_PROXY_SSL_VERIFYRESULT = CURLINFO_LONG + 47,
 +  CURLINFO_PROTOCOL         = CURLINFO_LONG   + 48,
 +  CURLINFO_SCHEME           = CURLINFO_STRING + 49,
 +  /* Fill in new entries below here! */
 +
 +  CURLINFO_LASTONE          = 49
 +} CURLINFO;
 +
 +/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as
 +   CURLINFO_HTTP_CODE */
 +#define CURLINFO_HTTP_CODE CURLINFO_RESPONSE_CODE
 +
 +typedef enum {
 +  CURLCLOSEPOLICY_NONE, /* first, never use this */
 +
 +  CURLCLOSEPOLICY_OLDEST,
 +  CURLCLOSEPOLICY_LEAST_RECENTLY_USED,
 +  CURLCLOSEPOLICY_LEAST_TRAFFIC,
 +  CURLCLOSEPOLICY_SLOWEST,
 +  CURLCLOSEPOLICY_CALLBACK,
 +
 +  CURLCLOSEPOLICY_LAST /* last, never use this */
 +} curl_closepolicy;
 +
 +#define CURL_GLOBAL_SSL (1<<0)
 +#define CURL_GLOBAL_WIN32 (1<<1)
 +#define CURL_GLOBAL_ALL (CURL_GLOBAL_SSL|CURL_GLOBAL_WIN32)
 +#define CURL_GLOBAL_NOTHING 0
 +#define CURL_GLOBAL_DEFAULT CURL_GLOBAL_ALL
 +#define CURL_GLOBAL_ACK_EINTR (1<<2)
 +
 +
 +/*****************************************************************************
 + * Setup defines, protos etc for the sharing stuff.
 + */
 +
 +/* Different data locks for a single share */
 +typedef enum {
 +  CURL_LOCK_DATA_NONE = 0,
 +  /*  CURL_LOCK_DATA_SHARE is used internally to say that
 +   *  the locking is just made to change the internal state of the share
 +   *  itself.
 +   */
 +  CURL_LOCK_DATA_SHARE,
 +  CURL_LOCK_DATA_COOKIE,
 +  CURL_LOCK_DATA_DNS,
 +  CURL_LOCK_DATA_SSL_SESSION,
 +  CURL_LOCK_DATA_CONNECT,
 +  CURL_LOCK_DATA_LAST
 +} curl_lock_data;
 +
 +/* Different lock access types */
 +typedef enum {
 +  CURL_LOCK_ACCESS_NONE = 0,   /* unspecified action */
 +  CURL_LOCK_ACCESS_SHARED = 1, /* for read perhaps */
 +  CURL_LOCK_ACCESS_SINGLE = 2, /* for write perhaps */
 +  CURL_LOCK_ACCESS_LAST        /* never use */
 +} curl_lock_access;
 +
 +typedef void (*curl_lock_function)(CURL *handle,
 +                                   curl_lock_data data,
 +                                   curl_lock_access locktype,
 +                                   void *userptr);
 +typedef void (*curl_unlock_function)(CURL *handle,
 +                                     curl_lock_data data,
 +                                     void *userptr);
 +
 +
 +typedef enum {
 +  CURLSHE_OK,  /* all is fine */
 +  CURLSHE_BAD_OPTION, /* 1 */
 +  CURLSHE_IN_USE,     /* 2 */
 +  CURLSHE_INVALID,    /* 3 */
 +  CURLSHE_NOMEM,      /* 4 out of memory */
 +  CURLSHE_NOT_BUILT_IN, /* 5 feature not present in lib */
 +  CURLSHE_LAST        /* never use */
 +} CURLSHcode;
 +
 +typedef enum {
 +  CURLSHOPT_NONE,  /* don't use */
 +  CURLSHOPT_SHARE,   /* specify a data type to share */
 +  CURLSHOPT_UNSHARE, /* specify which data type to stop sharing */
 +  CURLSHOPT_LOCKFUNC,   /* pass in a 'curl_lock_function' pointer */
 +  CURLSHOPT_UNLOCKFUNC, /* pass in a 'curl_unlock_function' pointer */
 +  CURLSHOPT_USERDATA,   /* pass in a user data pointer used in the lock/unlock
 +                           callback functions */
 +  CURLSHOPT_LAST  /* never use */
 +} CURLSHoption;
 +
 +CURL_EXTERN CURLSH *curl_share_init(void);
 +CURL_EXTERN CURLSHcode curl_share_setopt(CURLSH *, CURLSHoption option, ...);
 +CURL_EXTERN CURLSHcode curl_share_cleanup(CURLSH *);
 +
 +/****************************************************************************
 + * Structures for querying information about the curl library at runtime.
 + */
 +
 +typedef enum {
 +  CURLVERSION_FIRST,
 +  CURLVERSION_SECOND,
 +  CURLVERSION_THIRD,
 +  CURLVERSION_FOURTH,
 +  CURLVERSION_LAST /* never actually use this */
 +} CURLversion;
 +
 +/* The 'CURLVERSION_NOW' is the symbolic name meant to be used by
 +   basically all programs ever that want to get version information. It is
 +   meant to be a built-in version number for what kind of struct the caller
 +   expects. If the struct ever changes, we redefine the NOW to another enum
 +   from above. */
 +#define CURLVERSION_NOW CURLVERSION_FOURTH
 +
 +typedef struct {
 +  CURLversion age;          /* age of the returned struct */
 +  const char *version;      /* LIBCURL_VERSION */
 +  unsigned int version_num; /* LIBCURL_VERSION_NUM */
 +  const char *host;         /* OS/host/cpu/machine when configured */
 +  int features;             /* bitmask, see defines below */
 +  const char *ssl_version;  /* human readable string */
 +  long ssl_version_num;     /* not used anymore, always 0 */
 +  const char *libz_version; /* human readable string */
 +  /* protocols is terminated by an entry with a NULL protoname */
 +  const char * const *protocols;
 +
 +  /* The fields below this were added in CURLVERSION_SECOND */
 +  const char *ares;
 +  int ares_num;
 +
 +  /* This field was added in CURLVERSION_THIRD */
 +  const char *libidn;
 +
 +  /* These field were added in CURLVERSION_FOURTH */
 +
 +  /* Same as '_libiconv_version' if built with HAVE_ICONV */
 +  int iconv_ver_num;
 +
 +  const char *libssh_version; /* human readable string */
 +
 +} curl_version_info_data;
 +
 +#define CURL_VERSION_IPV6         (1<<0)  /* IPv6-enabled */
 +#define CURL_VERSION_KERBEROS4    (1<<1)  /* Kerberos V4 auth is supported
 +                                             (deprecated) */
 +#define CURL_VERSION_SSL          (1<<2)  /* SSL options are present */
 +#define CURL_VERSION_LIBZ         (1<<3)  /* libz features are present */
 +#define CURL_VERSION_NTLM         (1<<4)  /* NTLM auth is supported */
 +#define CURL_VERSION_GSSNEGOTIATE (1<<5)  /* Negotiate auth is supported
 +                                             (deprecated) */
 +#define CURL_VERSION_DEBUG        (1<<6)  /* Built with debug capabilities */
 +#define CURL_VERSION_ASYNCHDNS    (1<<7)  /* Asynchronous DNS resolves */
 +#define CURL_VERSION_SPNEGO       (1<<8)  /* SPNEGO auth is supported */
 +#define CURL_VERSION_LARGEFILE    (1<<9)  /* Supports files larger than 2GB */
 +#define CURL_VERSION_IDN          (1<<10) /* Internationized Domain Names are
 +                                             supported */
 +#define CURL_VERSION_SSPI         (1<<11) /* Built against Windows SSPI */
 +#define CURL_VERSION_CONV         (1<<12) /* Character conversions supported */
 +#define CURL_VERSION_CURLDEBUG    (1<<13) /* Debug memory tracking supported */
 +#define CURL_VERSION_TLSAUTH_SRP  (1<<14) /* TLS-SRP auth is supported */
 +#define CURL_VERSION_NTLM_WB      (1<<15) /* NTLM delegation to winbind helper
-                                              is suported */
++                                             is supported */
 +#define CURL_VERSION_HTTP2        (1<<16) /* HTTP2 support built-in */
 +#define CURL_VERSION_GSSAPI       (1<<17) /* Built against a GSS-API library */
 +#define CURL_VERSION_KERBEROS5    (1<<18) /* Kerberos V5 auth is supported */
 +#define CURL_VERSION_UNIX_SOCKETS (1<<19) /* Unix domain sockets support */
 +#define CURL_VERSION_PSL          (1<<20) /* Mozilla's Public Suffix List, used
 +                                             for cookie domain verification */
 +#define CURL_VERSION_HTTPS_PROXY  (1<<21) /* HTTPS-proxy support built-in */
 +
 + /*
 + * NAME curl_version_info()
 + *
 + * DESCRIPTION
 + *
 + * This function returns a pointer to a static copy of the version info
 + * struct. See above.
 + */
 +CURL_EXTERN curl_version_info_data *curl_version_info(CURLversion);
 +
 +/*
 + * NAME curl_easy_strerror()
 + *
 + * DESCRIPTION
 + *
 + * The curl_easy_strerror function may be used to turn a CURLcode value
 + * into the equivalent human readable error string.  This is useful
 + * for printing meaningful error messages.
 + */
 +CURL_EXTERN const char *curl_easy_strerror(CURLcode);
 +
 +/*
 + * NAME curl_share_strerror()
 + *
 + * DESCRIPTION
 + *
 + * The curl_share_strerror function may be used to turn a CURLSHcode value
 + * into the equivalent human readable error string.  This is useful
 + * for printing meaningful error messages.
 + */
 +CURL_EXTERN const char *curl_share_strerror(CURLSHcode);
 +
 +/*
 + * NAME curl_easy_pause()
 + *
 + * DESCRIPTION
 + *
 + * The curl_easy_pause function pauses or unpauses transfers. Select the new
 + * state by setting the bitmask, use the convenience defines below.
 + *
 + */
 +CURL_EXTERN CURLcode curl_easy_pause(CURL *handle, int bitmask);
 +
 +#define CURLPAUSE_RECV      (1<<0)
 +#define CURLPAUSE_RECV_CONT (0)
 +
 +#define CURLPAUSE_SEND      (1<<2)
 +#define CURLPAUSE_SEND_CONT (0)
 +
 +#define CURLPAUSE_ALL       (CURLPAUSE_RECV|CURLPAUSE_SEND)
 +#define CURLPAUSE_CONT      (CURLPAUSE_RECV_CONT|CURLPAUSE_SEND_CONT)
 +
 +#ifdef  __cplusplus
 +}
 +#endif
 +
 +/* unfortunately, the easy.h and multi.h include files need options and info
 +  stuff before they can be included! */
 +#include "easy.h" /* nothing in curl is fun without the easy stuff */
 +#include "multi.h"
 +
 +/* the typechecker doesn't work in C++ (yet) */
 +#if defined(__GNUC__) && defined(__GNUC_MINOR__) && \
 +    ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && \
 +    !defined(__cplusplus) && !defined(CURL_DISABLE_TYPECHECK)
 +#include "typecheck-gcc.h"
 +#else
 +#if defined(__STDC__) && (__STDC__ >= 1)
 +#if 0 /* Triggers clang -Wdisabled-macro-expansion, skip for CMake.  */
 +/* This preprocessor magic that replaces a call with the exact same call is
 +   only done to make sure application authors pass exactly three arguments
 +   to these functions. */
 +#define curl_easy_setopt(handle,opt,param) curl_easy_setopt(handle,opt,param)
 +#define curl_easy_getinfo(handle,info,arg) curl_easy_getinfo(handle,info,arg)
 +#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)
 +#endif
 +#endif /* __STDC__ >= 1 */
 +#endif /* gcc >= 4.3 && !__cplusplus */
 +
 +#endif /* __CURL_CURL_H */
diff --cc Utilities/cmcurl/include/curl/curlver.h
index 3967ad2,0000000..7f0e3b8
mode 100644,000000..100644
--- a/Utilities/cmcurl/include/curl/curlver.h
+++ b/Utilities/cmcurl/include/curl/curlver.h
@@@ -1,77 -1,0 +1,77 @@@
 +#ifndef __CURL_CURLVER_H
 +#define __CURL_CURLVER_H
 +/***************************************************************************
 + *                                  _   _ ____  _
 + *  Project                     ___| | | |  _ \| |
 + *                             / __| | | | |_) | |
 + *                            | (__| |_| |  _ <| |___
 + *                             \___|\___/|_| \_\_____|
 + *
-  * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
++ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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 - 2016 Daniel Stenberg, <daniel at haxx.se>."
++#define LIBCURL_COPYRIGHT "1996 - 2017 Daniel Stenberg, <daniel at haxx.se>."
 +
 +/* This is the version number of the libcurl package from which this header
 +   file origins: */
- #define LIBCURL_VERSION "7.52.1"
++#define LIBCURL_VERSION "7.54.0"
 +
 +/* The numeric version number is also available "in parts" by using these
 +   defines: */
 +#define LIBCURL_VERSION_MAJOR 7
- #define LIBCURL_VERSION_MINOR 52
- #define LIBCURL_VERSION_PATCH 1
++#define LIBCURL_VERSION_MINOR 54
++#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 0x073401
++#define LIBCURL_VERSION_NUM 0x073600
 +
 +/*
 + * This is the date and time when the full source package was created. The
 + * timestamp is not stored in git, as the timestamp is properly set in the
 + * tarballs by the maketgz script.
 + *
 + * The format of the date should follow this template:
 + *
 + * "Mon Feb 12 11:35:33 UTC 2007"
 + */
 +#define LIBCURL_TIMESTAMP "DEV"
 +
 +#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 */
diff --cc Utilities/cmcurl/include/curl/system.h
index 0000000,ed3a55c..ed3a55c
mode 000000,100644..100644
--- a/Utilities/cmcurl/include/curl/system.h
+++ b/Utilities/cmcurl/include/curl/system.h
diff --cc Utilities/cmcurl/lib/curl_config.h.cmake
index 13f69b2,0000000..f9d54b4
mode 100644,000000..100644
--- a/Utilities/cmcurl/lib/curl_config.h.cmake
+++ b/Utilities/cmcurl/lib/curl_config.h.cmake
@@@ -1,994 -1,0 +1,1006 @@@
 +/* lib/curl_config.h.in.  Generated somehow by cmake.  */
 +
 +/* when building libcurl itself */
 +#cmakedefine BUILDING_LIBCURL 1
 +
 +/* to disable cookies support */
 +#cmakedefine CURL_DISABLE_COOKIES 1
 +
 +/* to disable cryptographic authentication */
 +#cmakedefine CURL_DISABLE_CRYPTO_AUTH 1
 +
 +/* to disable DICT */
 +#cmakedefine CURL_DISABLE_DICT 1
 +
 +/* to disable FILE */
 +#cmakedefine CURL_DISABLE_FILE 1
 +
 +/* to disable FTP */
 +#cmakedefine CURL_DISABLE_FTP 1
 +
 +/* to disable GOPHER */
 +#cmakedefine CURL_DISABLE_GOPHER 1
 +
 +/* to disable IMAP */
 +#cmakedefine CURL_DISABLE_IMAP 1
 +
 +/* to disable HTTP */
 +#cmakedefine CURL_DISABLE_HTTP 1
 +
 +/* to disable LDAP */
 +#cmakedefine CURL_DISABLE_LDAP 1
 +
 +/* to disable LDAPS */
 +#cmakedefine CURL_DISABLE_LDAPS 1
 +
 +/* to disable POP3 */
 +#cmakedefine CURL_DISABLE_POP3 1
 +
 +/* to disable proxies */
 +#cmakedefine CURL_DISABLE_PROXY 1
 +
 +/* to disable RTSP */
 +#cmakedefine CURL_DISABLE_RTSP 1
 +
 +/* to disable RTMP */
 +#cmakedefine CURL_DISABLE_RTMP 1
 +
 +/* to disable SMB */
 +#cmakedefine CURL_DISABLE_SMB 1
 +
 +/* to disable SMTP */
 +#cmakedefine CURL_DISABLE_SMTP 1
 +
 +/* to disable TELNET */
 +#cmakedefine CURL_DISABLE_TELNET 1
 +
 +/* to disable TFTP */
 +#cmakedefine CURL_DISABLE_TFTP 1
 +
 +/* to disable verbose strings */
 +#cmakedefine CURL_DISABLE_VERBOSE_STRINGS 1
 +
 +/* to make a symbol visible */
 +#cmakedefine CURL_EXTERN_SYMBOL ${CURL_EXTERN_SYMBOL}
 +/* Ensure using CURL_EXTERN_SYMBOL is possible */
 +#ifndef CURL_EXTERN_SYMBOL
 +#define CURL_EXTERN_SYMBOL
 +#endif
 +
 +/* Use Windows LDAP implementation */
 +#cmakedefine USE_WIN32_LDAP 1
 +
 +/* when not building a shared library */
 +#cmakedefine CURL_STATICLIB 1
 +
 +/* Set to explicitly specify we don't want to use thread-safe functions */
 +#cmakedefine DISABLED_THREADSAFE 1
 +
 +/* your Entropy Gathering Daemon socket pathname */
 +#cmakedefine EGD_SOCKET ${EGD_SOCKET}
 +
 +/* Define if you want to enable IPv6 support */
 +#cmakedefine ENABLE_IPV6 1
 +
 +/* Define to the type qualifier of arg 1 for getnameinfo. */
 +#cmakedefine GETNAMEINFO_QUAL_ARG1 ${GETNAMEINFO_QUAL_ARG1}
 +
 +/* Define to the type of arg 1 for getnameinfo. */
 +#cmakedefine GETNAMEINFO_TYPE_ARG1 ${GETNAMEINFO_TYPE_ARG1}
 +
 +/* Define to the type of arg 2 for getnameinfo. */
 +#cmakedefine GETNAMEINFO_TYPE_ARG2 ${GETNAMEINFO_TYPE_ARG2}
 +
 +/* Define to the type of args 4 and 6 for getnameinfo. */
 +#cmakedefine GETNAMEINFO_TYPE_ARG46 ${GETNAMEINFO_TYPE_ARG46}
 +
 +/* Define to the type of arg 7 for getnameinfo. */
 +#cmakedefine GETNAMEINFO_TYPE_ARG7 ${GETNAMEINFO_TYPE_ARG7}
 +
 +/* Specifies the number of arguments to getservbyport_r */
 +#cmakedefine GETSERVBYPORT_R_ARGS ${GETSERVBYPORT_R_ARGS}
 +
 +/* Specifies the size of the buffer to pass to getservbyport_r */
 +#cmakedefine GETSERVBYPORT_R_BUFSIZE ${GETSERVBYPORT_R_BUFSIZE}
 +
 +/* Define to 1 if you have the alarm function. */
 +#cmakedefine HAVE_ALARM 1
 +
 +/* Define to 1 if you have the <alloca.h> header file. */
 +#cmakedefine HAVE_ALLOCA_H 1
 +
 +/* Define to 1 if you have the <arpa/inet.h> header file. */
 +#cmakedefine HAVE_ARPA_INET_H 1
 +
 +/* Define to 1 if you have the <arpa/tftp.h> header file. */
 +#cmakedefine HAVE_ARPA_TFTP_H 1
 +
 +/* Define to 1 if you have the <assert.h> header file. */
 +#cmakedefine HAVE_ASSERT_H 1
 +
 +/* Define to 1 if you have the `basename' function. */
 +#cmakedefine HAVE_BASENAME 1
 +
 +/* Define to 1 if bool is an available type. */
 +#cmakedefine HAVE_BOOL_T 1
 +
 +/* Define to 1 if you have the clock_gettime function and monotonic timer. */
 +#cmakedefine HAVE_CLOCK_GETTIME_MONOTONIC 1
 +
 +/* Define to 1 if you have the `closesocket' function. */
 +#cmakedefine HAVE_CLOSESOCKET 1
 +
 +/* Define to 1 if you have the `CRYPTO_cleanup_all_ex_data' function. */
 +#cmakedefine HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 1
 +
 +/* Define to 1 if you have the <crypto.h> header file. */
 +#cmakedefine HAVE_CRYPTO_H 1
 +
 +/* Define to 1 if you have the <des.h> header file. */
 +#cmakedefine HAVE_DES_H 1
 +
 +/* Define to 1 if you have the <dlfcn.h> header file. */
 +#cmakedefine HAVE_DLFCN_H 1
 +
 +/* Define to 1 if you have the `ENGINE_load_builtin_engines' function. */
 +#cmakedefine HAVE_ENGINE_LOAD_BUILTIN_ENGINES 1
 +
 +/* Define to 1 if you have the <errno.h> header file. */
 +#cmakedefine HAVE_ERRNO_H 1
 +
 +/* Define to 1 if you have the <err.h> header file. */
 +#cmakedefine HAVE_ERR_H 1
 +
 +/* Define to 1 if you have the fcntl function. */
 +#cmakedefine HAVE_FCNTL 1
 +
 +/* Define to 1 if you have the <fcntl.h> header file. */
 +#cmakedefine HAVE_FCNTL_H 1
 +
 +/* Define to 1 if you have a working fcntl O_NONBLOCK function. */
 +#cmakedefine HAVE_FCNTL_O_NONBLOCK 1
 +
 +/* Define to 1 if you have the fdopen function. */
 +#cmakedefine HAVE_FDOPEN 1
 +
 +/* Define to 1 if you have the `fork' function. */
 +#cmakedefine HAVE_FORK 1
 +
 +/* Define to 1 if you have the freeaddrinfo function. */
 +#cmakedefine HAVE_FREEADDRINFO 1
 +
 +/* Define to 1 if you have the freeifaddrs function. */
 +#cmakedefine HAVE_FREEIFADDRS 1
 +
 +/* Define to 1 if you have the ftruncate function. */
 +#cmakedefine HAVE_FTRUNCATE 1
 +
 +/* Define to 1 if you have a working getaddrinfo function. */
 +#cmakedefine HAVE_GETADDRINFO 1
 +
 +/* Define to 1 if you have the `geteuid' function. */
 +#cmakedefine HAVE_GETEUID 1
 +
 +/* Define to 1 if you have the gethostbyaddr function. */
 +#cmakedefine HAVE_GETHOSTBYADDR 1
 +
 +/* Define to 1 if you have the gethostbyaddr_r function. */
 +#cmakedefine HAVE_GETHOSTBYADDR_R 1
 +
 +/* gethostbyaddr_r() takes 5 args */
 +#cmakedefine HAVE_GETHOSTBYADDR_R_5 1
 +
 +/* gethostbyaddr_r() takes 7 args */
 +#cmakedefine HAVE_GETHOSTBYADDR_R_7 1
 +
 +/* gethostbyaddr_r() takes 8 args */
 +#cmakedefine HAVE_GETHOSTBYADDR_R_8 1
 +
 +/* Define to 1 if you have the gethostbyname function. */
 +#cmakedefine HAVE_GETHOSTBYNAME 1
 +
 +/* Define to 1 if you have the gethostbyname_r function. */
 +#cmakedefine HAVE_GETHOSTBYNAME_R 1
 +
 +/* gethostbyname_r() takes 3 args */
 +#cmakedefine HAVE_GETHOSTBYNAME_R_3 1
 +
 +/* gethostbyname_r() takes 5 args */
 +#cmakedefine HAVE_GETHOSTBYNAME_R_5 1
 +
 +/* gethostbyname_r() takes 6 args */
 +#cmakedefine HAVE_GETHOSTBYNAME_R_6 1
 +
 +/* Define to 1 if you have the gethostname function. */
 +#cmakedefine HAVE_GETHOSTNAME 1
 +
 +/* Define to 1 if you have a working getifaddrs function. */
 +#cmakedefine HAVE_GETIFADDRS 1
 +
 +/* Define to 1 if you have the getnameinfo function. */
 +#cmakedefine HAVE_GETNAMEINFO 1
 +
 +/* Define to 1 if you have the `getpass_r' function. */
 +#cmakedefine HAVE_GETPASS_R 1
 +
 +/* Define to 1 if you have the `getppid' function. */
 +#cmakedefine HAVE_GETPPID 1
 +
 +/* Define to 1 if you have the `getprotobyname' function. */
 +#cmakedefine HAVE_GETPROTOBYNAME 1
 +
 +/* Define to 1 if you have the `getpwuid' function. */
 +#cmakedefine HAVE_GETPWUID 1
 +
 +/* Define to 1 if you have the `getrlimit' function. */
 +#cmakedefine HAVE_GETRLIMIT 1
 +
 +/* Define to 1 if you have the getservbyport_r function. */
 +#cmakedefine HAVE_GETSERVBYPORT_R 1
 +
 +/* Define to 1 if you have the `gettimeofday' function. */
 +#cmakedefine HAVE_GETTIMEOFDAY 1
 +
 +/* Define to 1 if you have a working glibc-style strerror_r function. */
 +#cmakedefine HAVE_GLIBC_STRERROR_R 1
 +
 +/* Define to 1 if you have a working gmtime_r function. */
 +#cmakedefine HAVE_GMTIME_R 1
 +
 +/* if you have the gssapi libraries */
 +#cmakedefine HAVE_GSSAPI 1
 +
 +/* Define to 1 if you have the <gssapi/gssapi_generic.h> header file. */
 +#cmakedefine HAVE_GSSAPI_GSSAPI_GENERIC_H 1
 +
 +/* Define to 1 if you have the <gssapi/gssapi.h> header file. */
 +#cmakedefine HAVE_GSSAPI_GSSAPI_H 1
 +
 +/* Define to 1 if you have the <gssapi/gssapi_krb5.h> header file. */
 +#cmakedefine HAVE_GSSAPI_GSSAPI_KRB5_H 1
 +
 +/* if you have the GNU gssapi libraries */
 +#cmakedefine HAVE_GSSGNU 1
 +
 +/* if you have the Heimdal gssapi libraries */
 +#cmakedefine HAVE_GSSHEIMDAL 1
 +
 +/* if you have the MIT gssapi libraries */
 +#cmakedefine HAVE_GSSMIT 1
 +
 +/* Define to 1 if you have the `idna_strerror' function. */
 +#cmakedefine HAVE_IDNA_STRERROR 1
 +
 +/* Define to 1 if you have the `idn_free' function. */
 +#cmakedefine HAVE_IDN_FREE 1
 +
 +/* Define to 1 if you have the <idn-free.h> header file. */
 +#cmakedefine HAVE_IDN_FREE_H 1
 +
 +/* Define to 1 if you have the <ifaddrs.h> header file. */
 +#cmakedefine HAVE_IFADDRS_H 1
 +
 +/* Define to 1 if you have the `inet_addr' function. */
 +#cmakedefine HAVE_INET_ADDR 1
 +
 +/* Define to 1 if you have the inet_ntoa_r function. */
 +#cmakedefine HAVE_INET_NTOA_R 1
 +
 +/* inet_ntoa_r() takes 2 args */
 +#cmakedefine HAVE_INET_NTOA_R_2 1
 +
 +/* inet_ntoa_r() takes 3 args */
 +#cmakedefine HAVE_INET_NTOA_R_3 1
 +
 +/* Define to 1 if you have a IPv6 capable working inet_ntop function. */
 +#cmakedefine HAVE_INET_NTOP 1
 +
 +/* Define to 1 if you have a IPv6 capable working inet_pton function. */
 +#cmakedefine HAVE_INET_PTON 1
 +
 +/* Define to 1 if you have the <inttypes.h> header file. */
 +#cmakedefine HAVE_INTTYPES_H 1
 +
 +/* Define to 1 if you have the ioctl function. */
 +#cmakedefine HAVE_IOCTL 1
 +
 +/* Define to 1 if you have the ioctlsocket function. */
 +#cmakedefine HAVE_IOCTLSOCKET 1
 +
 +/* Define to 1 if you have the IoctlSocket camel case function. */
 +#cmakedefine HAVE_IOCTLSOCKET_CAMEL 1
 +
 +/* Define to 1 if you have a working IoctlSocket camel case FIONBIO function.
 +   */
 +#cmakedefine HAVE_IOCTLSOCKET_CAMEL_FIONBIO 1
 +
 +/* Define to 1 if you have a working ioctlsocket FIONBIO function. */
 +#cmakedefine HAVE_IOCTLSOCKET_FIONBIO 1
 +
 +/* Define to 1 if you have a working ioctl FIONBIO function. */
 +#cmakedefine HAVE_IOCTL_FIONBIO 1
 +
 +/* Define to 1 if you have a working ioctl SIOCGIFADDR function. */
 +#cmakedefine HAVE_IOCTL_SIOCGIFADDR 1
 +
 +/* Define to 1 if you have the <io.h> header file. */
 +#cmakedefine HAVE_IO_H 1
 +
 +/* if you have the Kerberos4 libraries (including -ldes) */
 +#cmakedefine HAVE_KRB4 1
 +
 +/* Define to 1 if you have the `krb_get_our_ip_for_realm' function. */
 +#cmakedefine HAVE_KRB_GET_OUR_IP_FOR_REALM 1
 +
 +/* Define to 1 if you have the <krb.h> header file. */
 +#cmakedefine HAVE_KRB_H 1
 +
 +/* Define to 1 if you have the lber.h header file. */
 +#cmakedefine HAVE_LBER_H 1
 +
 +/* Define to 1 if you have the ldapssl.h header file. */
 +#cmakedefine HAVE_LDAPSSL_H 1
 +
 +/* Define to 1 if you have the ldap.h header file. */
 +#cmakedefine HAVE_LDAP_H 1
 +
 +/* Use LDAPS implementation */
 +#cmakedefine HAVE_LDAP_SSL 1
 +
 +/* Define to 1 if you have the ldap_ssl.h header file. */
 +#cmakedefine HAVE_LDAP_SSL_H 1
 +
 +/* Define to 1 if you have the `ldap_url_parse' function. */
 +#cmakedefine HAVE_LDAP_URL_PARSE 1
 +
 +/* Define to 1 if you have the <libgen.h> header file. */
 +#cmakedefine HAVE_LIBGEN_H 1
 +
 +/* Define to 1 if you have the `idn' library (-lidn). */
 +#cmakedefine HAVE_LIBIDN 1
 +
 +/* Define to 1 if you have the `resolv' library (-lresolv). */
 +#cmakedefine HAVE_LIBRESOLV 1
 +
 +/* Define to 1 if you have the `resolve' library (-lresolve). */
 +#cmakedefine HAVE_LIBRESOLVE 1
 +
 +/* Define to 1 if you have the `socket' library (-lsocket). */
 +#cmakedefine HAVE_LIBSOCKET 1
 +
 +/* Define to 1 if you have the `ssh2' library (-lssh2). */
 +#cmakedefine HAVE_LIBSSH2 1
 +
 +/* Define to 1 if libssh2 provides `libssh2_version'. */
 +#cmakedefine HAVE_LIBSSH2_VERSION 1
 +
 +/* Define to 1 if libssh2 provides `libssh2_init'. */
 +#cmakedefine HAVE_LIBSSH2_INIT 1
 +
 +/* Define to 1 if libssh2 provides `libssh2_exit'. */
 +#cmakedefine HAVE_LIBSSH2_EXIT 1
 +
 +/* Define to 1 if libssh2 provides `libssh2_scp_send64'. */
 +#cmakedefine HAVE_LIBSSH2_SCP_SEND64 1
 +
 +/* Define to 1 if libssh2 provides `libssh2_session_handshake'. */
 +#cmakedefine HAVE_LIBSSH2_SESSION_HANDSHAKE 1
 +
 +/* Define to 1 if you have the <libssh2.h> header file. */
 +#cmakedefine HAVE_LIBSSH2_H 1
 +
 +/* Define to 1 if you have the `ssl' library (-lssl). */
 +#cmakedefine HAVE_LIBSSL 1
 +
 +/* if zlib is available */
 +#cmakedefine HAVE_LIBZ 1
 +
 +/* Define to 1 if you have the <limits.h> header file. */
 +#cmakedefine HAVE_LIMITS_H 1
 +
 +/* if your compiler supports LL */
 +#cmakedefine HAVE_LL 1
 +
 +/* Define to 1 if you have the <locale.h> header file. */
 +#cmakedefine HAVE_LOCALE_H 1
 +
 +/* Define to 1 if you have a working localtime_r function. */
 +#cmakedefine HAVE_LOCALTIME_R 1
 +
 +/* Define to 1 if the compiler supports the 'long long' data type. */
 +#cmakedefine HAVE_LONGLONG 1
 +
 +/* Define to 1 if you have the malloc.h header file. */
 +#cmakedefine HAVE_MALLOC_H 1
 +
 +/* Define to 1 if you have the <memory.h> header file. */
 +#cmakedefine HAVE_MEMORY_H 1
 +
 +/* Define to 1 if you have the MSG_NOSIGNAL flag. */
 +#cmakedefine HAVE_MSG_NOSIGNAL 1
 +
 +/* Define to 1 if you have the <netdb.h> header file. */
 +#cmakedefine HAVE_NETDB_H 1
 +
 +/* Define to 1 if you have the <netinet/in.h> header file. */
 +#cmakedefine HAVE_NETINET_IN_H 1
 +
 +/* Define to 1 if you have the <netinet/tcp.h> header file. */
 +#cmakedefine HAVE_NETINET_TCP_H 1
 +
 +/* Define to 1 if you have the <net/if.h> header file. */
 +#cmakedefine HAVE_NET_IF_H 1
 +
 +/* Define to 1 if NI_WITHSCOPEID exists and works. */
 +#cmakedefine HAVE_NI_WITHSCOPEID 1
 +
 +/* if you have an old MIT gssapi library, lacking GSS_C_NT_HOSTBASED_SERVICE */
 +#cmakedefine HAVE_OLD_GSSMIT 1
 +
 +/* Define to 1 if you have the <openssl/crypto.h> header file. */
 +#cmakedefine HAVE_OPENSSL_CRYPTO_H 1
 +
 +/* Define to 1 if you have the <openssl/engine.h> header file. */
 +#cmakedefine HAVE_OPENSSL_ENGINE_H 1
 +
 +/* Define to 1 if you have the <openssl/err.h> header file. */
 +#cmakedefine HAVE_OPENSSL_ERR_H 1
 +
 +/* Define to 1 if you have the <openssl/pem.h> header file. */
 +#cmakedefine HAVE_OPENSSL_PEM_H 1
 +
 +/* Define to 1 if you have the <openssl/pkcs12.h> header file. */
 +#cmakedefine HAVE_OPENSSL_PKCS12_H 1
 +
 +/* Define to 1 if you have the <openssl/rsa.h> header file. */
 +#cmakedefine HAVE_OPENSSL_RSA_H 1
 +
 +/* Define to 1 if you have the <openssl/ssl.h> header file. */
 +#cmakedefine HAVE_OPENSSL_SSL_H 1
 +
 +/* Define to 1 if you have the <openssl/x509.h> header file. */
 +#cmakedefine HAVE_OPENSSL_X509_H 1
 +
 +/* Define to 1 if you have the <pem.h> header file. */
 +#cmakedefine HAVE_PEM_H 1
 +
 +/* Define to 1 if you have the `perror' function. */
 +#cmakedefine HAVE_PERROR 1
 +
 +/* Define to 1 if you have the `pipe' function. */
 +#cmakedefine HAVE_PIPE 1
 +
 +/* Define to 1 if you have a working poll function. */
 +#cmakedefine HAVE_POLL 1
 +
 +/* If you have a fine poll */
 +#cmakedefine HAVE_POLL_FINE 1
 +
 +/* Define to 1 if you have the <poll.h> header file. */
 +#cmakedefine HAVE_POLL_H 1
 +
 +/* Define to 1 if you have a working POSIX-style strerror_r function. */
 +#cmakedefine HAVE_POSIX_STRERROR_R 1
 +
 +/* Define to 1 if you have the <pthread.h> header file */
 +#cmakedefine HAVE_PTHREAD_H 1
 +
 +/* Define to 1 if you have the <pwd.h> header file. */
 +#cmakedefine HAVE_PWD_H 1
 +
 +/* Define to 1 if you have the `RAND_egd' function. */
 +#cmakedefine HAVE_RAND_EGD 1
 +
 +/* Define to 1 if you have the `RAND_screen' function. */
 +#cmakedefine HAVE_RAND_SCREEN 1
 +
 +/* Define to 1 if you have the `RAND_status' function. */
 +#cmakedefine HAVE_RAND_STATUS 1
 +
 +/* Define to 1 if you have the recv function. */
 +#cmakedefine HAVE_RECV 1
 +
 +/* Define to 1 if you have the recvfrom function. */
 +#cmakedefine HAVE_RECVFROM 1
 +
 +/* Define to 1 if you have the <rsa.h> header file. */
 +#cmakedefine HAVE_RSA_H 1
 +
 +/* Define to 1 if you have the select function. */
 +#cmakedefine HAVE_SELECT 1
 +
 +/* Define to 1 if you have the send function. */
 +#cmakedefine HAVE_SEND 1
 +
++/* Define to 1 if you have the 'fsetxattr' function. */
++#cmakedefine HAVE_FSETXATTR 1
++
++/* fsetxattr() takes 5 args */
++#cmakedefine HAVE_FSETXATTR_5 1
++
++/* fsetxattr() takes 6 args */
++#cmakedefine HAVE_FSETXATTR_6 1
++
 +/* Define to 1 if you have the <setjmp.h> header file. */
 +#cmakedefine HAVE_SETJMP_H 1
 +
 +/* Define to 1 if you have the `setlocale' function. */
 +#cmakedefine HAVE_SETLOCALE 1
 +
 +/* Define to 1 if you have the `setmode' function. */
 +#cmakedefine HAVE_SETMODE 1
 +
 +/* Define to 1 if you have the `setrlimit' function. */
 +#cmakedefine HAVE_SETRLIMIT 1
 +
 +/* Define to 1 if you have the setsockopt function. */
 +#cmakedefine HAVE_SETSOCKOPT 1
 +
 +/* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */
 +#cmakedefine HAVE_SETSOCKOPT_SO_NONBLOCK 1
 +
 +/* Define to 1 if you have the <sgtty.h> header file. */
 +#cmakedefine HAVE_SGTTY_H 1
 +
 +/* Define to 1 if you have the sigaction function. */
 +#cmakedefine HAVE_SIGACTION 1
 +
 +/* Define to 1 if you have the siginterrupt function. */
 +#cmakedefine HAVE_SIGINTERRUPT 1
 +
 +/* Define to 1 if you have the signal function. */
 +#cmakedefine HAVE_SIGNAL 1
 +
 +/* Define to 1 if you have the <signal.h> header file. */
 +#cmakedefine HAVE_SIGNAL_H 1
 +
 +/* Define to 1 if you have the sigsetjmp function or macro. */
 +#cmakedefine HAVE_SIGSETJMP 1
 +
 +/* Define to 1 if sig_atomic_t is an available typedef. */
 +#cmakedefine HAVE_SIG_ATOMIC_T 1
 +
 +/* Define to 1 if sig_atomic_t is already defined as volatile. */
 +#cmakedefine HAVE_SIG_ATOMIC_T_VOLATILE 1
 +
 +/* Define to 1 if struct sockaddr_in6 has the sin6_scope_id member */
 +#cmakedefine HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1
 +
 +/* Define to 1 if you have the `socket' function. */
 +#cmakedefine HAVE_SOCKET 1
 +
 +/* Define to 1 if you have the `SSL_get_shutdown' function. */
 +#cmakedefine HAVE_SSL_GET_SHUTDOWN 1
 +
 +/* Define to 1 if you have the <ssl.h> header file. */
 +#cmakedefine HAVE_SSL_H 1
 +
 +/* Define to 1 if you have the <stdbool.h> header file. */
 +#cmakedefine HAVE_STDBOOL_H 1
 +
 +/* Define to 1 if you have the <stdint.h> header file. */
 +#cmakedefine HAVE_STDINT_H 1
 +
 +/* Define to 1 if you have the <stdio.h> header file. */
 +#cmakedefine HAVE_STDIO_H 1
 +
 +/* Define to 1 if you have the <stdlib.h> header file. */
 +#cmakedefine HAVE_STDLIB_H 1
 +
 +/* Define to 1 if you have the strcasecmp function. */
 +#cmakedefine HAVE_STRCASECMP 1
 +
 +/* Define to 1 if you have the strcasestr function. */
 +#cmakedefine HAVE_STRCASESTR 1
 +
 +/* Define to 1 if you have the strcmpi function. */
 +#cmakedefine HAVE_STRCMPI 1
 +
 +/* Define to 1 if you have the strdup function. */
 +#cmakedefine HAVE_STRDUP 1
 +
 +/* Define to 1 if you have the strerror_r function. */
 +#cmakedefine HAVE_STRERROR_R 1
 +
 +/* Define to 1 if you have the stricmp function. */
 +#cmakedefine HAVE_STRICMP 1
 +
 +/* Define to 1 if you have the <strings.h> header file. */
 +#cmakedefine HAVE_STRINGS_H 1
 +
 +/* Define to 1 if you have the <string.h> header file. */
 +#cmakedefine HAVE_STRING_H 1
 +
 +/* Define to 1 if you have the strlcat function. */
 +#cmakedefine HAVE_STRLCAT 1
 +
 +/* Define to 1 if you have the `strlcpy' function. */
 +#cmakedefine HAVE_STRLCPY 1
 +
 +/* Define to 1 if you have the strncasecmp function. */
 +#cmakedefine HAVE_STRNCASECMP 1
 +
 +/* Define to 1 if you have the strncmpi function. */
 +#cmakedefine HAVE_STRNCMPI 1
 +
 +/* Define to 1 if you have the strnicmp function. */
 +#cmakedefine HAVE_STRNICMP 1
 +
 +/* Define to 1 if you have the <stropts.h> header file. */
 +#cmakedefine HAVE_STROPTS_H 1
 +
 +/* Define to 1 if you have the strstr function. */
 +#cmakedefine HAVE_STRSTR 1
 +
 +/* Define to 1 if you have the strtok_r function. */
 +#cmakedefine HAVE_STRTOK_R 1
 +
 +/* Define to 1 if you have the strtoll function. */
 +#cmakedefine HAVE_STRTOLL 1
 +
 +/* if struct sockaddr_storage is defined */
 +#cmakedefine HAVE_STRUCT_SOCKADDR_STORAGE 1
 +
 +/* Define to 1 if you have the timeval struct. */
 +#cmakedefine HAVE_STRUCT_TIMEVAL 1
 +
 +/* Define to 1 if you have the <sys/filio.h> header file. */
 +#cmakedefine HAVE_SYS_FILIO_H 1
 +
 +/* Define to 1 if you have the <sys/ioctl.h> header file. */
 +#cmakedefine HAVE_SYS_IOCTL_H 1
 +
 +/* Define to 1 if you have the <sys/param.h> header file. */
 +#cmakedefine HAVE_SYS_PARAM_H 1
 +
 +/* Define to 1 if you have the <sys/poll.h> header file. */
 +#cmakedefine HAVE_SYS_POLL_H 1
 +
 +/* Define to 1 if you have the <sys/resource.h> header file. */
 +#cmakedefine HAVE_SYS_RESOURCE_H 1
 +
 +/* Define to 1 if you have the <sys/select.h> header file. */
 +#cmakedefine HAVE_SYS_SELECT_H 1
 +
 +/* Define to 1 if you have the <sys/socket.h> header file. */
 +#cmakedefine HAVE_SYS_SOCKET_H 1
 +
 +/* Define to 1 if you have the <sys/sockio.h> header file. */
 +#cmakedefine HAVE_SYS_SOCKIO_H 1
 +
 +/* Define to 1 if you have the <sys/stat.h> header file. */
 +#cmakedefine HAVE_SYS_STAT_H 1
 +
 +/* Define to 1 if you have the <sys/time.h> header file. */
 +#cmakedefine HAVE_SYS_TIME_H 1
 +
 +/* Define to 1 if you have the <sys/types.h> header file. */
 +#cmakedefine HAVE_SYS_TYPES_H 1
 +
 +/* Define to 1 if you have the <sys/uio.h> header file. */
 +#cmakedefine HAVE_SYS_UIO_H 1
 +
 +/* Define to 1 if you have the <sys/un.h> header file. */
 +#cmakedefine HAVE_SYS_UN_H 1
 +
 +/* Define to 1 if you have the <sys/utime.h> header file. */
 +#cmakedefine HAVE_SYS_UTIME_H 1
 +
 +/* Define to 1 if you have the <termios.h> header file. */
 +#cmakedefine HAVE_TERMIOS_H 1
 +
 +/* Define to 1 if you have the <termio.h> header file. */
 +#cmakedefine HAVE_TERMIO_H 1
 +
 +/* Define to 1 if you have the <time.h> header file. */
 +#cmakedefine HAVE_TIME_H 1
 +
 +/* Define to 1 if you have the <tld.h> header file. */
 +#cmakedefine HAVE_TLD_H 1
 +
 +/* Define to 1 if you have the `tld_strerror' function. */
 +#cmakedefine HAVE_TLD_STRERROR 1
 +
 +/* Define to 1 if you have the `uname' function. */
 +#cmakedefine HAVE_UNAME 1
 +
 +/* Define to 1 if you have the <unistd.h> header file. */
 +#cmakedefine HAVE_UNISTD_H 1
 +
 +/* Define to 1 if you have the `utime' function. */
 +#cmakedefine HAVE_UTIME 1
 +
 +/* Define to 1 if you have the <utime.h> header file. */
 +#cmakedefine HAVE_UTIME_H 1
 +
 +/* Define to 1 if compiler supports C99 variadic macro style. */
 +#cmakedefine HAVE_VARIADIC_MACROS_C99 1
 +
 +/* Define to 1 if compiler supports old gcc variadic macro style. */
 +#cmakedefine HAVE_VARIADIC_MACROS_GCC 1
 +
 +/* Define to 1 if you have the winber.h header file. */
 +#cmakedefine HAVE_WINBER_H 1
 +
 +/* Define to 1 if you have the windows.h header file. */
 +#cmakedefine HAVE_WINDOWS_H 1
 +
 +/* Define to 1 if you have the winldap.h header file. */
 +#cmakedefine HAVE_WINLDAP_H 1
 +
 +/* Define to 1 if you have the winsock2.h header file. */
 +#cmakedefine HAVE_WINSOCK2_H 1
 +
 +/* Define to 1 if you have the winsock.h header file. */
 +#cmakedefine HAVE_WINSOCK_H 1
 +
 +/* Define this symbol if your OS supports changing the contents of argv */
 +#cmakedefine HAVE_WRITABLE_ARGV 1
 +
 +/* Define to 1 if you have the writev function. */
 +#cmakedefine HAVE_WRITEV 1
 +
 +/* Define to 1 if you have the ws2tcpip.h header file. */
 +#cmakedefine HAVE_WS2TCPIP_H 1
 +
 +/* Define to 1 if you have the <x509.h> header file. */
 +#cmakedefine HAVE_X509_H 1
 +
 +/* Define if you have the <process.h> header file. */
 +#cmakedefine HAVE_PROCESS_H 1
 +
 +/* if you have the zlib.h header file */
 +#cmakedefine HAVE_ZLIB_H 1
 +
 +/* Define to the sub-directory in which libtool stores uninstalled libraries.
 +   */
 +#cmakedefine LT_OBJDIR ${LT_OBJDIR}
 +
 +/* If you lack a fine basename() prototype */
 +#cmakedefine NEED_BASENAME_PROTO 1
 +
 +/* Define to 1 if you need the lber.h header file even with ldap.h */
 +#cmakedefine NEED_LBER_H 1
 +
 +/* Define to 1 if you need the malloc.h header file even with stdlib.h */
 +#cmakedefine NEED_MALLOC_H 1
 +
 +/* Define to 1 if _REENTRANT preprocessor symbol must be defined. */
 +#cmakedefine NEED_REENTRANT 1
 +
 +/* cpu-machine-OS */
 +#cmakedefine OS ${OS}
 +
 +/* Name of package */
 +#cmakedefine PACKAGE ${PACKAGE}
 +
 +/* Define to the address where bug reports for this package should be sent. */
 +#cmakedefine PACKAGE_BUGREPORT ${PACKAGE_BUGREPORT}
 +
 +/* Define to the full name of this package. */
 +#cmakedefine PACKAGE_NAME ${PACKAGE_NAME}
 +
 +/* Define to the full name and version of this package. */
 +#cmakedefine PACKAGE_STRING ${PACKAGE_STRING}
 +
 +/* Define to the one symbol short name of this package. */
 +#cmakedefine PACKAGE_TARNAME ${PACKAGE_TARNAME}
 +
 +/* Define to the version of this package. */
 +#cmakedefine PACKAGE_VERSION ${PACKAGE_VERSION}
 +
 +/* a suitable file to read random data from */
 +#cmakedefine RANDOM_FILE "${RANDOM_FILE}"
 +
 +/* Define to the type of arg 1 for recvfrom. */
 +#cmakedefine RECVFROM_TYPE_ARG1 ${RECVFROM_TYPE_ARG1}
 +
 +/* Define to the type pointed by arg 2 for recvfrom. */
 +#cmakedefine RECVFROM_TYPE_ARG2 ${RECVFROM_TYPE_ARG2}
 +
 +/* Define to 1 if the type pointed by arg 2 for recvfrom is void. */
 +#cmakedefine RECVFROM_TYPE_ARG2_IS_VOID 1
 +
 +/* Define to the type of arg 3 for recvfrom. */
 +#cmakedefine RECVFROM_TYPE_ARG3 ${RECVFROM_TYPE_ARG3}
 +
 +/* Define to the type of arg 4 for recvfrom. */
 +#cmakedefine RECVFROM_TYPE_ARG4 ${RECVFROM_TYPE_ARG4}
 +
 +/* Define to the type pointed by arg 5 for recvfrom. */
 +#cmakedefine RECVFROM_TYPE_ARG5 ${RECVFROM_TYPE_ARG5}
 +
 +/* Define to 1 if the type pointed by arg 5 for recvfrom is void. */
 +#cmakedefine RECVFROM_TYPE_ARG5_IS_VOID 1
 +
 +/* Define to the type pointed by arg 6 for recvfrom. */
 +#cmakedefine RECVFROM_TYPE_ARG6 ${RECVFROM_TYPE_ARG6}
 +
 +/* Define to 1 if the type pointed by arg 6 for recvfrom is void. */
 +#cmakedefine RECVFROM_TYPE_ARG6_IS_VOID 1
 +
 +/* Define to the function return type for recvfrom. */
 +#cmakedefine RECVFROM_TYPE_RETV ${RECVFROM_TYPE_RETV}
 +
 +/* Define to the type of arg 1 for recv. */
 +#cmakedefine RECV_TYPE_ARG1 ${RECV_TYPE_ARG1}
 +
 +/* Define to the type of arg 2 for recv. */
 +#cmakedefine RECV_TYPE_ARG2 ${RECV_TYPE_ARG2}
 +
 +/* Define to the type of arg 3 for recv. */
 +#cmakedefine RECV_TYPE_ARG3 ${RECV_TYPE_ARG3}
 +
 +/* Define to the type of arg 4 for recv. */
 +#cmakedefine RECV_TYPE_ARG4 ${RECV_TYPE_ARG4}
 +
 +/* Define to the function return type for recv. */
 +#cmakedefine RECV_TYPE_RETV ${RECV_TYPE_RETV}
 +
 +/* Define as the return type of signal handlers (`int' or `void'). */
 +#cmakedefine RETSIGTYPE ${RETSIGTYPE}
 +
 +/* Define to the type qualifier of arg 5 for select. */
 +#cmakedefine SELECT_QUAL_ARG5 ${SELECT_QUAL_ARG5}
 +
 +/* Define to the type of arg 1 for select. */
 +#cmakedefine SELECT_TYPE_ARG1 ${SELECT_TYPE_ARG1}
 +
 +/* Define to the type of args 2, 3 and 4 for select. */
 +#cmakedefine SELECT_TYPE_ARG234 ${SELECT_TYPE_ARG234}
 +
 +/* Define to the type of arg 5 for select. */
 +#cmakedefine SELECT_TYPE_ARG5 ${SELECT_TYPE_ARG5}
 +
 +/* Define to the function return type for select. */
 +#cmakedefine SELECT_TYPE_RETV ${SELECT_TYPE_RETV}
 +
 +/* Define to the type qualifier of arg 2 for send. */
 +#cmakedefine SEND_QUAL_ARG2 ${SEND_QUAL_ARG2}
 +
 +/* Define to the type of arg 1 for send. */
 +#cmakedefine SEND_TYPE_ARG1 ${SEND_TYPE_ARG1}
 +
 +/* Define to the type of arg 2 for send. */
 +#cmakedefine SEND_TYPE_ARG2 ${SEND_TYPE_ARG2}
 +
 +/* Define to the type of arg 3 for send. */
 +#cmakedefine SEND_TYPE_ARG3 ${SEND_TYPE_ARG3}
 +
 +/* Define to the type of arg 4 for send. */
 +#cmakedefine SEND_TYPE_ARG4 ${SEND_TYPE_ARG4}
 +
 +/* Define to the function return type for send. */
 +#cmakedefine SEND_TYPE_RETV ${SEND_TYPE_RETV}
 +
 +/* The size of `int', as computed by sizeof. */
 + at SIZEOF_INT_CODE@
 +
 +/* The size of `short', as computed by sizeof. */
 + at SIZEOF_SHORT_CODE@
 +
 +/* The size of `long', as computed by sizeof. */
 + at SIZEOF_LONG_CODE@
 +
 +/* The size of `off_t', as computed by sizeof. */
 + at SIZEOF_OFF_T_CODE@
 +
 +/* The size of `size_t', as computed by sizeof. */
 + at SIZEOF_SIZE_T_CODE@
 +
 +/* The size of `ssize_t', as computed by sizeof. */
 + at SIZEOF_SSIZE_T_CODE@
 +
 +/* The size of `time_t', as computed by sizeof. */
 + at SIZEOF_TIME_T_CODE@
 +
 +/* Define to 1 if you have the ANSI C header files. */
 +#cmakedefine STDC_HEADERS 1
 +
 +/* Define to the type of arg 3 for strerror_r. */
 +#cmakedefine STRERROR_R_TYPE_ARG3 ${STRERROR_R_TYPE_ARG3}
 +
 +/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
 +#cmakedefine TIME_WITH_SYS_TIME 1
 +
 +/* Define if you want to enable c-ares support */
 +#cmakedefine USE_ARES 1
 +
 +/* Define if you want to enable POSIX threaded DNS lookup */
 +#cmakedefine USE_THREADS_POSIX 1
 +
 +/* Define if you want to enable WIN32 threaded DNS lookup */
 +#cmakedefine USE_THREADS_WIN32 1
 +
 +/* Define to disable non-blocking sockets. */
 +#cmakedefine USE_BLOCKING_SOCKETS 1
 +
 +/* if GnuTLS is enabled */
 +#cmakedefine USE_GNUTLS 1
 +
 +/* if PolarSSL is enabled */
 +#cmakedefine USE_POLARSSL 1
 +
++/* if DarwinSSL is enabled */
++#cmakedefine USE_DARWINSSL 1
++
 +/* if mbedTLS is enabled */
 +#cmakedefine USE_MBEDTLS 1
 +
 +/* if libSSH2 is in use */
 +#cmakedefine USE_LIBSSH2 1
 +
 +/* If you want to build curl with the built-in manual */
 +#cmakedefine USE_MANUAL 1
 +
 +/* if NSS is enabled */
 +#cmakedefine USE_NSS 1
 +
 +/* if you want to use OpenLDAP code instead of legacy ldap implementation */
 +#cmakedefine USE_OPENLDAP 1
 +
 +/* if OpenSSL is in use */
 +#cmakedefine USE_OPENSSL 1
 +
 +/* to enable NGHTTP2  */
 +#cmakedefine USE_NGHTTP2 1
 +
 +/* if Unix domain sockets are enabled  */
 +#cmakedefine USE_UNIX_SOCKETS
 +
 +/* to enable SSPI support */
 +#cmakedefine USE_WINDOWS_SSPI 1
 +
 +/* to enable Windows SSL  */
 +#cmakedefine USE_SCHANNEL 1
 +
 +/* Define to 1 if using yaSSL in OpenSSL compatibility mode. */
 +#cmakedefine USE_YASSLEMUL 1
 +
 +/* Version number of package */
 +#cmakedefine VERSION ${VERSION}
 +
 +/* Define to avoid automatic inclusion of winsock.h */
 +#cmakedefine WIN32_LEAN_AND_MEAN 1
 +
 +/* Define to 1 if OS is AIX. */
 +#ifndef _ALL_SOURCE
 +#  undef _ALL_SOURCE
 +#endif
 +
 +/* Number of bits in a file offset, on hosts where this is settable. */
 +#cmakedefine _FILE_OFFSET_BITS ${_FILE_OFFSET_BITS}
 +
 +/* Define for large files, on AIX-style hosts. */
 +#cmakedefine _LARGE_FILES ${_LARGE_FILES}
 +
 +/* define this if you need it to compile thread-safe code */
 +#cmakedefine _THREAD_SAFE ${_THREAD_SAFE}
 +
 +/* Define to empty if `const' does not conform to ANSI C. */
 +#cmakedefine const ${const}
 +
 +/* Type to use in place of in_addr_t when system does not provide it. */
 +#cmakedefine in_addr_t ${in_addr_t}
 +
 +/* Define to `__inline__' or `__inline' if that's what the C compiler
 +   calls it, or to nothing if 'inline' is not supported under any name.  */
 +#ifndef __cplusplus
 +#undef inline
 +#endif
 +
 +/* Define to `unsigned int' if <sys/types.h> does not define. */
 +#cmakedefine size_t ${size_t}
 +
 +/* the signed version of size_t */
 +#ifndef SIZEOF_SSIZE_T
 +# if SIZEOF_LONG == SIZEOF_SIZE_T
 +   typedef long ssize_t;
 +# elif SIZEOF_LONG_LONG == SIZEOF_SIZE_T
 +   typedef long long ssize_t;
 +# elif SIZEOF___INT64 == SIZEOF_SIZE_T
 +   typedef __int64 ssize_t;
 +# else
 +   typedef int ssize_t;
 +# endif
 +#endif
diff --cc Utilities/cmcurl/lib/curl_setup.h
index c861e97,0000000..6ab18cd
mode 100644,000000..100644
--- a/Utilities/cmcurl/lib/curl_setup.h
+++ b/Utilities/cmcurl/lib/curl_setup.h
@@@ -1,780 -1,0 +1,769 @@@
 +#ifndef HEADER_CURL_SETUP_H
 +#define HEADER_CURL_SETUP_H
 +/***************************************************************************
 + *                                  _   _ ____  _
 + *  Project                     ___| | | |  _ \| |
 + *                             / __| | | | |_) | |
 + *                            | (__| |_| |  _ <| |___
 + *                             \___|\___/|_| \_\_____|
 + *
 + * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at 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 WIN32 when build target is Win32 API
 + */
 +
 +#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) && \
 +    !defined(__SYMBIAN32__)
 +#define WIN32
 +#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.  */
 +/* ================================================================ */
 +
- /*
-  * libcurl's external interface definitions are also used internally,
-  * and might also include required system header files to define them.
-  */
- 
- #include <curl/curlbuild.h>
- 
- /*
-  * Compile time sanity checks must also be done when building the library.
-  */
- 
- #include <curl/curlrules.h>
++#include <curl/curl.h>
 +
 +/*
 + * Ensure that no one is using the old SIZEOF_CURL_OFF_T macro
 + */
 +
 +#ifdef SIZEOF_CURL_OFF_T
 +#  error "SIZEOF_CURL_OFF_T shall not be defined!"
 +   Error Compilation_aborted_SIZEOF_CURL_OFF_T_shall_not_be_defined
 +#endif
 +
 +/*
 + * 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_RTMP
 +#    define CURL_DISABLE_RTMP
 +#  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 curlbuild.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
 +#  ifndef WIN32_LEAN_AND_MEAN
 +#    define WIN32_LEAN_AND_MEAN
 +#  endif
 +#  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__
 +#  ifndef __ixemul__
 +#    include <exec/types.h>
 +#    include <exec/execbase.h>
 +#    include <proto/exec.h>
 +#    include <proto/dos.h>
 +#    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
 +
 +/*
 + * 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
 +
 +/*
 + * 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)
 +/* The lib and header are present */
 +#define USE_LIBIDN2
 +#endif
 +
 +#ifndef SIZEOF_TIME_T
 +/* assume default size of time_t to be 32 bit */
 +#define SIZEOF_TIME_T 4
 +#endif
 +
 +#define LIBIDN_REQUIRED_VERSION "0.4.1"
 +
 +#if defined(USE_GNUTLS) || defined(USE_OPENSSL) || defined(USE_NSS) || \
 +    defined(USE_POLARSSL) || defined(USE_AXTLS) || defined(USE_MBEDTLS) || \
 +    defined(USE_CYASSL) || defined(USE_SCHANNEL) || \
 +    defined(USE_DARWINSSL) || defined(USE_GSKIT)
 +#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_DARWINSSL) || \
 +    defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO)
 +
 +#define USE_NTLM
 +
 +#elif defined(USE_MBEDTLS)
 +#  include <mbedtls/md4.h>
 +#  if defined(MBEDTLS_MD4_C)
 +#define USE_NTLM
 +#  endif
 +
 +#endif
 +#endif
 +
 +/* non-configure builds may define CURL_WANTS_CA_BUNDLE_ENV */
 +#if defined(CURL_WANTS_CA_BUNDLE_ENV) && !defined(CURL_CA_BUNDLE)
 +#define CURL_CA_BUNDLE getenv("CURL_CA_BUNDLE")
 +#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"
 +#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"
 +#else
 +#define FOPEN_READTEXT "r"
 +#define FOPEN_WRITETEXT "w"
 +#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_WORKAROUNDS */
 +#  ifdef USE_RECV_BEFORE_SEND_WORKAROUND
 +#    undef USE_RECV_BEFORE_SEND_WORKAROUND
 +#  endif
 +#endif /* DONT_USE_RECV_BEFORE_SEND_WORKAROUNDS */
 +
 +/* Detect Windows App environment which has a restricted access
 + * to the Win32 APIs. */
 +# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0602)
 +#  include <winapifamily.h>
 +#  if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && \
 +     !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
 +#    define CURL_WINDOWS_APP
 +#  endif
 +# endif
 +
 +#endif /* HEADER_CURL_SETUP_H */
diff --cc Utilities/cmcurl/lib/ftp.c
index 89c7e40,0000000..a5ca2ab
mode 100644,000000..100644
--- a/Utilities/cmcurl/lib/ftp.c
+++ b/Utilities/cmcurl/lib/ftp.c
@@@ -1,4549 -1,0 +1,4545 @@@
 +/***************************************************************************
 + *                                  _   _ ____  _
 + *  Project                     ___| | | |  _ \| |
 + *                             / __| | | | |_) | |
 + *                            | (__| |_| |  _ <| |___
 + *                             \___|\___/|_| \_\_____|
 + *
-  * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
++ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
 +
 +#ifdef HAVE_NETINET_IN_H
 +#include <netinet/in.h>
 +#endif
 +#ifdef HAVE_ARPA_INET_H
 +#include <arpa/inet.h>
 +#endif
 +#ifdef HAVE_UTSNAME_H
 +#include <sys/utsname.h>
 +#endif
 +#ifdef HAVE_NETDB_H
 +#include <netdb.h>
 +#endif
 +#ifdef __VMS
 +#include <in.h>
 +#include <inet.h>
 +#endif
 +
 +#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
 +#undef in_addr_t
 +#define in_addr_t unsigned long
 +#endif
 +
 +#include <curl/curl.h>
 +#include "urldata.h"
 +#include "sendf.h"
 +#include "if2ip.h"
 +#include "hostip.h"
 +#include "progress.h"
 +#include "transfer.h"
 +#include "escape.h"
 +#include "http.h" /* for HTTP proxy tunnel stuff */
 +#include "socks.h"
 +#include "ftp.h"
 +#include "fileinfo.h"
 +#include "ftplistparser.h"
 +#include "curl_sec.h"
 +#include "strtoofft.h"
 +#include "strcase.h"
 +#include "vtls/vtls.h"
 +#include "connect.h"
 +#include "strerror.h"
 +#include "inet_ntop.h"
 +#include "inet_pton.h"
 +#include "select.h"
 +#include "parsedate.h" /* for the week day and month names */
 +#include "sockaddr.h" /* required for Curl_sockaddr_storage */
 +#include "multiif.h"
 +#include "url.h"
 +#include "strcase.h"
 +#include "speedcheck.h"
 +#include "warnless.h"
 +#include "http_proxy.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"
 +
 +#ifndef NI_MAXHOST
 +#define NI_MAXHOST 1025
 +#endif
 +#ifndef INET_ADDRSTRLEN
 +#define INET_ADDRSTRLEN 16
 +#endif
 +
 +#ifdef CURL_DISABLE_VERBOSE_STRINGS
 +#define ftp_pasv_verbose(a,b,c,d)  Curl_nop_stmt
 +#endif
 +
 +/* Local API functions */
 +#ifndef DEBUGBUILD
 +static void _state(struct connectdata *conn,
 +                   ftpstate newstate);
 +#define state(x,y) _state(x,y)
 +#else
 +static void _state(struct connectdata *conn,
 +                   ftpstate newstate,
 +                   int lineno);
 +#define state(x,y) _state(x,y,__LINE__)
 +#endif
 +
 +static CURLcode ftp_sendquote(struct connectdata *conn,
 +                              struct curl_slist *quote);
 +static CURLcode ftp_quit(struct connectdata *conn);
 +static CURLcode ftp_parse_url_path(struct connectdata *conn);
 +static CURLcode ftp_regular_transfer(struct connectdata *conn, bool *done);
 +#ifndef CURL_DISABLE_VERBOSE_STRINGS
 +static void ftp_pasv_verbose(struct connectdata *conn,
 +                             Curl_addrinfo *ai,
 +                             char *newhost, /* ascii version */
 +                             int port);
 +#endif
 +static CURLcode ftp_state_prepare_transfer(struct connectdata *conn);
 +static CURLcode ftp_state_mdtm(struct connectdata *conn);
 +static CURLcode ftp_state_quote(struct connectdata *conn,
 +                                bool init, ftpstate instate);
 +static CURLcode ftp_nb_type(struct connectdata *conn,
 +                            bool ascii, ftpstate newstate);
 +static int ftp_need_type(struct connectdata *conn,
 +                         bool ascii);
 +static CURLcode ftp_do(struct connectdata *conn, bool *done);
 +static CURLcode ftp_done(struct connectdata *conn,
 +                         CURLcode, bool premature);
 +static CURLcode ftp_connect(struct connectdata *conn, bool *done);
 +static CURLcode ftp_disconnect(struct connectdata *conn, bool dead_connection);
 +static CURLcode ftp_do_more(struct connectdata *conn, int *completed);
 +static CURLcode ftp_multi_statemach(struct connectdata *conn, bool *done);
 +static int ftp_getsock(struct connectdata *conn, curl_socket_t *socks,
 +                       int numsocks);
 +static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks,
 +                              int numsocks);
 +static CURLcode ftp_doing(struct connectdata *conn,
 +                          bool *dophase_done);
 +static CURLcode ftp_setup_connection(struct connectdata * conn);
 +
 +static CURLcode init_wc_data(struct connectdata *conn);
 +static CURLcode wc_statemach(struct connectdata *conn);
 +
 +static void wc_data_dtor(void *ptr);
 +
 +static CURLcode ftp_state_retr(struct connectdata *conn, curl_off_t filesize);
 +
 +static CURLcode ftp_readresp(curl_socket_t sockfd,
 +                             struct pingpong *pp,
 +                             int *ftpcode,
 +                             size_t *size);
 +static CURLcode ftp_dophase_done(struct connectdata *conn,
 +                                 bool connected);
 +
 +/* easy-to-use macro: */
 +#define PPSENDF(x,y,z)  result = Curl_pp_sendf(x,y,z); \
 +                        if(result)                     \
 +                          return result
 +
 +
 +/*
 + * FTP protocol handler.
 + */
 +
 +const struct Curl_handler Curl_handler_ftp = {
 +  "FTP",                           /* scheme */
 +  ftp_setup_connection,            /* setup_connection */
 +  ftp_do,                          /* do_it */
 +  ftp_done,                        /* done */
 +  ftp_do_more,                     /* do_more */
 +  ftp_connect,                     /* connect_it */
 +  ftp_multi_statemach,             /* connecting */
 +  ftp_doing,                       /* doing */
 +  ftp_getsock,                     /* proto_getsock */
 +  ftp_getsock,                     /* doing_getsock */
 +  ftp_domore_getsock,              /* domore_getsock */
 +  ZERO_NULL,                       /* perform_getsock */
 +  ftp_disconnect,                  /* disconnect */
 +  ZERO_NULL,                       /* readwrite */
 +  PORT_FTP,                        /* defport */
 +  CURLPROTO_FTP,                   /* protocol */
 +  PROTOPT_DUAL | PROTOPT_CLOSEACTION | PROTOPT_NEEDSPWD
 +  | PROTOPT_NOURLQUERY /* flags */
 +};
 +
 +
 +#ifdef USE_SSL
 +/*
 + * FTPS protocol handler.
 + */
 +
 +const struct Curl_handler Curl_handler_ftps = {
 +  "FTPS",                          /* scheme */
 +  ftp_setup_connection,            /* setup_connection */
 +  ftp_do,                          /* do_it */
 +  ftp_done,                        /* done */
 +  ftp_do_more,                     /* do_more */
 +  ftp_connect,                     /* connect_it */
 +  ftp_multi_statemach,             /* connecting */
 +  ftp_doing,                       /* doing */
 +  ftp_getsock,                     /* proto_getsock */
 +  ftp_getsock,                     /* doing_getsock */
 +  ftp_domore_getsock,              /* domore_getsock */
 +  ZERO_NULL,                       /* perform_getsock */
 +  ftp_disconnect,                  /* disconnect */
 +  ZERO_NULL,                       /* readwrite */
 +  PORT_FTPS,                       /* defport */
 +  CURLPROTO_FTPS,                  /* protocol */
 +  PROTOPT_SSL | PROTOPT_DUAL | PROTOPT_CLOSEACTION |
 +  PROTOPT_NEEDSPWD | PROTOPT_NOURLQUERY /* flags */
 +};
 +#endif
 +
 +#ifndef CURL_DISABLE_HTTP
 +/*
 + * HTTP-proxyed FTP protocol handler.
 + */
 +
 +static const struct Curl_handler Curl_handler_ftp_proxy = {
 +  "FTP",                                /* scheme */
 +  Curl_http_setup_conn,                 /* setup_connection */
 +  Curl_http,                            /* do_it */
 +  Curl_http_done,                       /* done */
 +  ZERO_NULL,                            /* do_more */
 +  ZERO_NULL,                            /* connect_it */
 +  ZERO_NULL,                            /* connecting */
 +  ZERO_NULL,                            /* doing */
 +  ZERO_NULL,                            /* proto_getsock */
 +  ZERO_NULL,                            /* doing_getsock */
 +  ZERO_NULL,                            /* domore_getsock */
 +  ZERO_NULL,                            /* perform_getsock */
 +  ZERO_NULL,                            /* disconnect */
 +  ZERO_NULL,                            /* readwrite */
 +  PORT_FTP,                             /* defport */
 +  CURLPROTO_HTTP,                       /* protocol */
 +  PROTOPT_NONE                          /* flags */
 +};
 +
 +
 +#ifdef USE_SSL
 +/*
 + * HTTP-proxyed FTPS protocol handler.
 + */
 +
 +static const struct Curl_handler Curl_handler_ftps_proxy = {
 +  "FTPS",                               /* scheme */
 +  Curl_http_setup_conn,                 /* setup_connection */
 +  Curl_http,                            /* do_it */
 +  Curl_http_done,                       /* done */
 +  ZERO_NULL,                            /* do_more */
 +  ZERO_NULL,                            /* connect_it */
 +  ZERO_NULL,                            /* connecting */
 +  ZERO_NULL,                            /* doing */
 +  ZERO_NULL,                            /* proto_getsock */
 +  ZERO_NULL,                            /* doing_getsock */
 +  ZERO_NULL,                            /* domore_getsock */
 +  ZERO_NULL,                            /* perform_getsock */
 +  ZERO_NULL,                            /* disconnect */
 +  ZERO_NULL,                            /* readwrite */
 +  PORT_FTPS,                            /* defport */
 +  CURLPROTO_HTTP,                       /* protocol */
 +  PROTOPT_NONE                          /* flags */
 +};
 +#endif
 +#endif
 +
 +static void close_secondarysocket(struct connectdata *conn)
 +{
 +  if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET]) {
 +    Curl_closesocket(conn, conn->sock[SECONDARYSOCKET]);
 +    conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
 +  }
 +  conn->bits.tcpconnect[SECONDARYSOCKET] = FALSE;
 +  conn->tunnel_state[SECONDARYSOCKET] = TUNNEL_INIT;
 +}
 +
 +/*
 + * NOTE: back in the old days, we added code in the FTP code that made NOBODY
 + * requests on files respond with headers passed to the client/stdout that
 + * looked like HTTP ones.
 + *
 + * This approach is not very elegant, it causes confusion and is error-prone.
 + * It is subject for removal at the next (or at least a future) soname bump.
 + * Until then you can test the effects of the removal by undefining the
 + * following define named CURL_FTP_HTTPSTYLE_HEAD.
 + */
 +#define CURL_FTP_HTTPSTYLE_HEAD 1
 +
 +static void freedirs(struct ftp_conn *ftpc)
 +{
 +  int i;
 +  if(ftpc->dirs) {
 +    for(i=0; i < ftpc->dirdepth; i++) {
 +      free(ftpc->dirs[i]);
 +      ftpc->dirs[i]=NULL;
 +    }
 +    free(ftpc->dirs);
 +    ftpc->dirs = NULL;
 +    ftpc->dirdepth = 0;
 +  }
 +  Curl_safefree(ftpc->file);
 +
 +  /* no longer of any use */
 +  Curl_safefree(ftpc->newhost);
 +}
 +
 +/* Returns non-zero if the given string contains CR (\r) or LF (\n),
 +   which are not allowed within RFC 959 <string>.
 +   Note: The input string is in the client's encoding which might
 +   not be ASCII, so escape sequences \r & \n must be used instead
 +   of hex values 0x0d & 0x0a.
 +*/
 +static bool isBadFtpString(const char *string)
 +{
 +  return ((NULL != strchr(string, '\r')) ||
 +          (NULL != strchr(string, '\n'))) ? TRUE : FALSE;
 +}
 +
 +/***********************************************************************
 + *
 + * AcceptServerConnect()
 + *
 + * After connection request is received from the server this function is
 + * called to accept the connection and close the listening socket
 + *
 + */
 +static CURLcode AcceptServerConnect(struct connectdata *conn)
 +{
 +  struct Curl_easy *data = conn->data;
 +  curl_socket_t sock = conn->sock[SECONDARYSOCKET];
 +  curl_socket_t s = CURL_SOCKET_BAD;
 +#ifdef ENABLE_IPV6
 +  struct Curl_sockaddr_storage add;
 +#else
 +  struct sockaddr_in add;
 +#endif
 +  curl_socklen_t size = (curl_socklen_t) sizeof(add);
 +
 +  if(0 == getsockname(sock, (struct sockaddr *) &add, &size)) {
 +    size = sizeof(add);
 +
 +    s=accept(sock, (struct sockaddr *) &add, &size);
 +  }
 +  Curl_closesocket(conn, sock); /* close the first socket */
 +
 +  if(CURL_SOCKET_BAD == s) {
 +    failf(data, "Error accept()ing server connect");
 +    return CURLE_FTP_PORT_FAILED;
 +  }
 +  infof(data, "Connection accepted from server\n");
 +  /* when this happens within the DO state it is important that we mark us as
 +     not needing DO_MORE anymore */
 +  conn->bits.do_more = FALSE;
 +
 +  conn->sock[SECONDARYSOCKET] = s;
 +  (void)curlx_nonblock(s, TRUE); /* enable non-blocking */
 +  conn->sock_accepted[SECONDARYSOCKET] = TRUE;
 +
 +  if(data->set.fsockopt) {
 +    int error = 0;
 +
 +    /* activate callback for setting socket options */
 +    error = data->set.fsockopt(data->set.sockopt_client,
 +                               s,
 +                               CURLSOCKTYPE_ACCEPT);
 +
 +    if(error) {
 +      close_secondarysocket(conn);
 +      return CURLE_ABORTED_BY_CALLBACK;
 +    }
 +  }
 +
 +  return CURLE_OK;
 +
 +}
 +
 +/*
 + * ftp_timeleft_accept() returns the amount of milliseconds left allowed for
 + * waiting server to connect. If the value is negative, the timeout time has
 + * already elapsed.
 + *
 + * The start time is stored in progress.t_acceptdata - as set with
 + * Curl_pgrsTime(..., TIMER_STARTACCEPT);
 + *
 + */
 +static time_t ftp_timeleft_accept(struct Curl_easy *data)
 +{
 +  time_t timeout_ms = DEFAULT_ACCEPT_TIMEOUT;
 +  time_t other;
 +  struct timeval now;
 +
 +  if(data->set.accepttimeout > 0)
 +    timeout_ms = data->set.accepttimeout;
 +
 +  now = Curl_tvnow();
 +
 +  /* check if the generic timeout possibly is set shorter */
 +  other =  Curl_timeleft(data, &now, FALSE);
 +  if(other && (other < timeout_ms))
 +    /* note that this also works fine for when other happens to be negative
 +       due to it already having elapsed */
 +    timeout_ms = other;
 +  else {
 +    /* subtract elapsed time */
 +    timeout_ms -= Curl_tvdiff(now, data->progress.t_acceptdata);
 +    if(!timeout_ms)
 +      /* avoid returning 0 as that means no timeout! */
 +      return -1;
 +  }
 +
 +  return timeout_ms;
 +}
 +
 +
 +/***********************************************************************
 + *
 + * ReceivedServerConnect()
 + *
 + * After allowing server to connect to us from data port, this function
 + * checks both data connection for connection establishment and ctrl
 + * connection for a negative response regarding a failure in connecting
 + *
 + */
 +static CURLcode ReceivedServerConnect(struct connectdata *conn, bool *received)
 +{
 +  struct Curl_easy *data = conn->data;
 +  curl_socket_t ctrl_sock = conn->sock[FIRSTSOCKET];
 +  curl_socket_t data_sock = conn->sock[SECONDARYSOCKET];
 +  struct ftp_conn *ftpc = &conn->proto.ftpc;
 +  struct pingpong *pp = &ftpc->pp;
 +  int result;
 +  time_t timeout_ms;
 +  ssize_t nread;
 +  int ftpcode;
 +
 +  *received = FALSE;
 +
 +  timeout_ms = ftp_timeleft_accept(data);
 +  infof(data, "Checking for server connect\n");
 +  if(timeout_ms < 0) {
 +    /* if a timeout was already reached, bail out */
 +    failf(data, "Accept timeout occurred while waiting server connect");
 +    return CURLE_FTP_ACCEPT_TIMEOUT;
 +  }
 +
 +  /* First check whether there is a cached response from server */
 +  if(pp->cache_size && pp->cache && pp->cache[0] > '3') {
 +    /* Data connection could not be established, let's return */
 +    infof(data, "There is negative response in cache while serv connect\n");
 +    Curl_GetFTPResponse(&nread, conn, &ftpcode);
 +    return CURLE_FTP_ACCEPT_FAILED;
 +  }
 +
 +  result = Curl_socket_check(ctrl_sock, data_sock, CURL_SOCKET_BAD, 0);
 +
 +  /* see if the connection request is already here */
 +  switch(result) {
 +  case -1: /* error */
 +    /* let's die here */
 +    failf(data, "Error while waiting for server connect");
 +    return CURLE_FTP_ACCEPT_FAILED;
 +  case 0:  /* Server connect is not received yet */
 +    break; /* loop */
 +  default:
 +
 +    if(result & CURL_CSELECT_IN2) {
 +      infof(data, "Ready to accept data connection from server\n");
 +      *received = TRUE;
 +    }
 +    else if(result & CURL_CSELECT_IN) {
 +      infof(data, "Ctrl conn has data while waiting for data conn\n");
 +      Curl_GetFTPResponse(&nread, conn, &ftpcode);
 +
 +      if(ftpcode/100 > 3)
 +        return CURLE_FTP_ACCEPT_FAILED;
 +
 +      return CURLE_WEIRD_SERVER_REPLY;
 +    }
 +
 +    break;
 +  } /* switch() */
 +
 +  return CURLE_OK;
 +}
 +
 +
 +/***********************************************************************
 + *
 + * InitiateTransfer()
 + *
 + * After connection from server is accepted this function is called to
 + * setup transfer parameters and initiate the data transfer.
 + *
 + */
 +static CURLcode InitiateTransfer(struct connectdata *conn)
 +{
 +  struct Curl_easy *data = conn->data;
 +  struct FTP *ftp = data->req.protop;
 +  CURLcode result = CURLE_OK;
 +
 +  if(conn->bits.ftp_use_data_ssl) {
 +    /* since we only have a plaintext TCP connection here, we must now
 +     * do the TLS stuff */
 +    infof(data, "Doing the SSL/TLS handshake on the data stream\n");
 +    result = Curl_ssl_connect(conn, SECONDARYSOCKET);
 +    if(result)
 +      return result;
 +  }
 +
 +  if(conn->proto.ftpc.state_saved == FTP_STOR) {
 +    *(ftp->bytecountp)=0;
 +
 +    /* When we know we're uploading a specified file, we can get the file
 +       size prior to the actual upload. */
 +
 +    Curl_pgrsSetUploadSize(data, data->state.infilesize);
 +
 +    /* set the SO_SNDBUF for the secondary socket for those who need it */
 +    Curl_sndbufset(conn->sock[SECONDARYSOCKET]);
 +
 +    Curl_setup_transfer(conn, -1, -1, FALSE, NULL, /* no download */
 +                        SECONDARYSOCKET, ftp->bytecountp);
 +  }
 +  else {
 +    /* FTP download: */
 +    Curl_setup_transfer(conn, SECONDARYSOCKET,
 +                        conn->proto.ftpc.retr_size_saved, FALSE,
 +                        ftp->bytecountp, -1, NULL); /* no upload here */
 +  }
 +
 +  conn->proto.ftpc.pp.pending_resp = TRUE; /* expect server response */
 +  state(conn, FTP_STOP);
 +
 +  return CURLE_OK;
 +}
 +
 +/***********************************************************************
 + *
 + * AllowServerConnect()
 + *
 + * When we've issue the PORT command, we have told the server to connect to
 + * us. This function checks whether data connection is established if so it is
 + * accepted.
 + *
 + */
 +static CURLcode AllowServerConnect(struct connectdata *conn, bool *connected)
 +{
 +  struct Curl_easy *data = conn->data;
 +  time_t timeout_ms;
 +  CURLcode result = CURLE_OK;
 +
 +  *connected = FALSE;
 +  infof(data, "Preparing for accepting server on data port\n");
 +
 +  /* Save the time we start accepting server connect */
 +  Curl_pgrsTime(data, TIMER_STARTACCEPT);
 +
 +  timeout_ms = ftp_timeleft_accept(data);
 +  if(timeout_ms < 0) {
 +    /* if a timeout was already reached, bail out */
 +    failf(data, "Accept timeout occurred while waiting server connect");
 +    return CURLE_FTP_ACCEPT_TIMEOUT;
 +  }
 +
 +  /* see if the connection request is already here */
 +  result = ReceivedServerConnect(conn, connected);
 +  if(result)
 +    return result;
 +
 +  if(*connected) {
 +    result = AcceptServerConnect(conn);
 +    if(result)
 +      return result;
 +
 +    result = InitiateTransfer(conn);
 +    if(result)
 +      return result;
 +  }
 +  else {
 +    /* Add timeout to multi handle and break out of the loop */
 +    if(!result && *connected == FALSE) {
 +      if(data->set.accepttimeout > 0)
 +        Curl_expire(data, data->set.accepttimeout);
 +      else
 +        Curl_expire(data, DEFAULT_ACCEPT_TIMEOUT);
 +    }
 +  }
 +
 +  return result;
 +}
 +
 +/* macro to check for a three-digit ftp status code at the start of the
 +   given string */
 +#define STATUSCODE(line) (ISDIGIT(line[0]) && ISDIGIT(line[1]) &&       \
 +                          ISDIGIT(line[2]))
 +
 +/* macro to check for the last line in an FTP server response */
 +#define LASTLINE(line) (STATUSCODE(line) && (' ' == line[3]))
 +
 +static bool ftp_endofresp(struct connectdata *conn, char *line, size_t len,
 +                          int *code)
 +{
 +  (void)conn;
 +
 +  if((len > 3) && LASTLINE(line)) {
 +    *code = curlx_sltosi(strtol(line, NULL, 10));
 +    return TRUE;
 +  }
 +
 +  return FALSE;
 +}
 +
 +static CURLcode ftp_readresp(curl_socket_t sockfd,
 +                             struct pingpong *pp,
 +                             int *ftpcode, /* return the ftp-code if done */
 +                             size_t *size) /* size of the response */
 +{
 +  struct connectdata *conn = pp->conn;
 +  struct Curl_easy *data = conn->data;
 +#ifdef HAVE_GSSAPI
 +  char * const buf = data->state.buffer;
 +#endif
 +  CURLcode result = CURLE_OK;
 +  int code;
 +
 +  result = Curl_pp_readresp(sockfd, pp, &code, size);
 +
 +#if defined(HAVE_GSSAPI)
 +  /* handle the security-oriented responses 6xx ***/
 +  /* FIXME: some errorchecking perhaps... ***/
 +  switch(code) {
 +  case 631:
 +    code = Curl_sec_read_msg(conn, buf, PROT_SAFE);
 +    break;
 +  case 632:
 +    code = Curl_sec_read_msg(conn, buf, PROT_PRIVATE);
 +    break;
 +  case 633:
 +    code = Curl_sec_read_msg(conn, buf, PROT_CONFIDENTIAL);
 +    break;
 +  default:
 +    /* normal ftp stuff we pass through! */
 +    break;
 +  }
 +#endif
 +
 +  /* store the latest code for later retrieval */
 +  data->info.httpcode=code;
 +
 +  if(ftpcode)
 +    *ftpcode = code;
 +
 +  if(421 == code) {
 +    /* 421 means "Service not available, closing control connection." and FTP
 +     * servers use it to signal that idle session timeout has been exceeded.
 +     * If we ignored the response, it could end up hanging in some cases.
 +     *
 +     * This response code can come at any point so having it treated
 +     * generically is a good idea.
 +     */
 +    infof(data, "We got a 421 - timeout!\n");
 +    state(conn, FTP_STOP);
 +    return CURLE_OPERATION_TIMEDOUT;
 +  }
 +
 +  return result;
 +}
 +
 +/* --- parse FTP server responses --- */
 +
 +/*
 + * Curl_GetFTPResponse() is a BLOCKING function to read the full response
 + * from a server after a command.
 + *
 + */
 +
 +CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */
 +                             struct connectdata *conn,
 +                             int *ftpcode) /* return the ftp-code */
 +{
 +  /*
 +   * We cannot read just one byte per read() and then go back to select() as
 +   * the OpenSSL read() doesn't grok that properly.
 +   *
 +   * Alas, read as much as possible, split up into lines, use the ending
 +   * line in a response or continue reading.  */
 +
 +  curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
 +  time_t timeout;              /* timeout in milliseconds */
 +  time_t interval_ms;
 +  struct Curl_easy *data = conn->data;
 +  CURLcode result = CURLE_OK;
 +  struct ftp_conn *ftpc = &conn->proto.ftpc;
 +  struct pingpong *pp = &ftpc->pp;
 +  size_t nread;
 +  int cache_skip=0;
 +  int value_to_be_ignored=0;
 +
 +  if(ftpcode)
 +    *ftpcode = 0; /* 0 for errors */
 +  else
 +    /* make the pointer point to something for the rest of this function */
 +    ftpcode = &value_to_be_ignored;
 +
 +  *nreadp=0;
 +
 +  while(!*ftpcode && !result) {
 +    /* check and reset timeout value every lap */
 +    timeout = Curl_pp_state_timeout(pp);
 +
 +    if(timeout <=0) {
 +      failf(data, "FTP response timeout");
 +      return CURLE_OPERATION_TIMEDOUT; /* already too little time */
 +    }
 +
 +    interval_ms = 1000;  /* use 1 second timeout intervals */
 +    if(timeout < interval_ms)
 +      interval_ms = timeout;
 +
 +    /*
 +     * Since this function is blocking, we need to wait here for input on the
 +     * connection and only then we call the response reading function. We do
 +     * timeout at least every second to make the timeout check run.
 +     *
 +     * A caution here is that the ftp_readresp() function has a cache that may
 +     * contain pieces of a response from the previous invoke and we need to
 +     * make sure we don't just wait for input while there is unhandled data in
 +     * that cache. But also, if the cache is there, we call ftp_readresp() and
 +     * the cache wasn't good enough to continue we must not just busy-loop
 +     * around this function.
 +     *
 +     */
 +
 +    if(pp->cache && (cache_skip < 2)) {
 +      /*
 +       * There's a cache left since before. We then skipping the wait for
 +       * socket action, unless this is the same cache like the previous round
 +       * as then the cache was deemed not enough to act on and we then need to
 +       * wait for more data anyway.
 +       */
 +    }
 +    else if(!Curl_conn_data_pending(conn, FIRSTSOCKET)) {
 +      switch(SOCKET_READABLE(sockfd, interval_ms)) {
 +      case -1: /* select() error, stop reading */
 +        failf(data, "FTP response aborted due to select/poll error: %d",
 +              SOCKERRNO);
 +        return CURLE_RECV_ERROR;
 +
 +      case 0: /* timeout */
 +        if(Curl_pgrsUpdate(conn))
 +          return CURLE_ABORTED_BY_CALLBACK;
 +        continue; /* just continue in our loop for the timeout duration */
 +
 +      default: /* for clarity */
 +        break;
 +      }
 +    }
 +    result = ftp_readresp(sockfd, pp, ftpcode, &nread);
 +    if(result)
 +      break;
 +
 +    if(!nread && pp->cache)
 +      /* bump cache skip counter as on repeated skips we must wait for more
 +         data */
 +      cache_skip++;
 +    else
 +      /* when we got data or there is no cache left, we reset the cache skip
 +         counter */
 +      cache_skip=0;
 +
 +    *nreadp += nread;
 +
 +  } /* while there's buffer left and loop is requested */
 +
 +  pp->pending_resp = FALSE;
 +
 +  return result;
 +}
 +
 +#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
 +  /* for debug purposes */
 +static const char * const ftp_state_names[]={
 +  "STOP",
 +  "WAIT220",
 +  "AUTH",
 +  "USER",
 +  "PASS",
 +  "ACCT",
 +  "PBSZ",
 +  "PROT",
 +  "CCC",
 +  "PWD",
 +  "SYST",
 +  "NAMEFMT",
 +  "QUOTE",
 +  "RETR_PREQUOTE",
 +  "STOR_PREQUOTE",
 +  "POSTQUOTE",
 +  "CWD",
 +  "MKD",
 +  "MDTM",
 +  "TYPE",
 +  "LIST_TYPE",
 +  "RETR_TYPE",
 +  "STOR_TYPE",
 +  "SIZE",
 +  "RETR_SIZE",
 +  "STOR_SIZE",
 +  "REST",
 +  "RETR_REST",
 +  "PORT",
 +  "PRET",
 +  "PASV",
 +  "LIST",
 +  "RETR",
 +  "STOR",
 +  "QUIT"
 +};
 +#endif
 +
 +/* This is the ONLY way to change FTP state! */
 +static void _state(struct connectdata *conn,
 +                   ftpstate newstate
 +#ifdef DEBUGBUILD
 +                   , int lineno
 +#endif
 +  )
 +{
 +  struct ftp_conn *ftpc = &conn->proto.ftpc;
 +
 +#if defined(DEBUGBUILD)
 +
 +#if defined(CURL_DISABLE_VERBOSE_STRINGS)
 +  (void) lineno;
 +#else
 +  if(ftpc->state != newstate)
 +    infof(conn->data, "FTP %p (line %d) state change from %s to %s\n",
 +          (void *)ftpc, lineno, ftp_state_names[ftpc->state],
 +          ftp_state_names[newstate]);
 +#endif
 +#endif
 +
 +  ftpc->state = newstate;
 +}
 +
 +static CURLcode ftp_state_user(struct connectdata *conn)
 +{
 +  CURLcode result;
 +  struct FTP *ftp = conn->data->req.protop;
 +  /* send USER */
 +  PPSENDF(&conn->proto.ftpc.pp, "USER %s", ftp->user?ftp->user:"");
 +
 +  state(conn, FTP_USER);
 +  conn->data->state.ftp_trying_alternative = FALSE;
 +
 +  return CURLE_OK;
 +}
 +
 +static CURLcode ftp_state_pwd(struct connectdata *conn)
 +{
 +  CURLcode result;
 +
 +  /* send PWD to discover our entry point */
 +  PPSENDF(&conn->proto.ftpc.pp, "%s", "PWD");
 +  state(conn, FTP_PWD);
 +
 +  return CURLE_OK;
 +}
 +
 +/* For the FTP "protocol connect" and "doing" phases only */
 +static int ftp_getsock(struct connectdata *conn,
 +                       curl_socket_t *socks,
 +                       int numsocks)
 +{
 +  return Curl_pp_getsock(&conn->proto.ftpc.pp, socks, numsocks);
 +}
 +
 +/* For the FTP "DO_MORE" phase only */
 +static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks,
 +                              int numsocks)
 +{
 +  struct ftp_conn *ftpc = &conn->proto.ftpc;
 +
 +  if(!numsocks)
 +    return GETSOCK_BLANK;
 +
 +  /* When in DO_MORE state, we could be either waiting for us to connect to a
 +   * remote site, or we could wait for that site to connect to us. Or just
 +   * handle ordinary commands.
 +   */
 +
 +  if(FTP_STOP == ftpc->state) {
 +    int bits = GETSOCK_READSOCK(0);
 +
 +    /* if stopped and still in this state, then we're also waiting for a
 +       connect on the secondary connection */
 +    socks[0] = conn->sock[FIRSTSOCKET];
 +
 +    if(!conn->data->set.ftp_use_port) {
 +      int s;
 +      int i;
 +      /* PORT is used to tell the server to connect to us, and during that we
 +         don't do happy eyeballs, but we do if we connect to the server */
 +      for(s=1, i=0; i<2; i++) {
 +        if(conn->tempsock[i] != CURL_SOCKET_BAD) {
 +          socks[s] = conn->tempsock[i];
 +          bits |= GETSOCK_WRITESOCK(s++);
 +        }
 +      }
 +    }
 +    else {
 +      socks[1] = conn->sock[SECONDARYSOCKET];
 +      bits |= GETSOCK_WRITESOCK(1) | GETSOCK_READSOCK(1);
 +    }
 +
 +    return bits;
 +  }
-   else
-     return Curl_pp_getsock(&conn->proto.ftpc.pp, socks, numsocks);
++  return Curl_pp_getsock(&conn->proto.ftpc.pp, socks, numsocks);
 +}
 +
 +/* This is called after the FTP_QUOTE state is passed.
 +
 +   ftp_state_cwd() sends the range of CWD commands to the server to change to
 +   the correct directory. It may also need to send MKD commands to create
 +   missing ones, if that option is enabled.
 +*/
 +static CURLcode ftp_state_cwd(struct connectdata *conn)
 +{
 +  CURLcode result = CURLE_OK;
 +  struct ftp_conn *ftpc = &conn->proto.ftpc;
 +
 +  if(ftpc->cwddone)
 +    /* already done and fine */
 +    result = ftp_state_mdtm(conn);
 +  else {
 +    ftpc->count2 = 0; /* count2 counts failed CWDs */
 +
 +    /* count3 is set to allow a MKD to fail once. In the case when first CWD
 +       fails and then MKD fails (due to another session raced it to create the
 +       dir) this then allows for a second try to CWD to it */
 +    ftpc->count3 = (conn->data->set.ftp_create_missing_dirs==2)?1:0;
 +
 +    if(conn->bits.reuse && ftpc->entrypath) {
 +      /* This is a re-used connection. Since we change directory to where the
 +         transfer is taking place, we must first get back to the original dir
 +         where we ended up after login: */
 +      ftpc->count1 = 0; /* we count this as the first path, then we add one
 +                          for all upcoming ones in the ftp->dirs[] array */
 +      PPSENDF(&conn->proto.ftpc.pp, "CWD %s", ftpc->entrypath);
 +      state(conn, FTP_CWD);
 +    }
 +    else {
 +      if(ftpc->dirdepth) {
 +        ftpc->count1 = 1;
 +        /* issue the first CWD, the rest is sent when the CWD responses are
 +           received... */
 +        PPSENDF(&conn->proto.ftpc.pp, "CWD %s", ftpc->dirs[ftpc->count1 -1]);
 +        state(conn, FTP_CWD);
 +      }
 +      else {
 +        /* No CWD necessary */
 +        result = ftp_state_mdtm(conn);
 +      }
 +    }
 +  }
 +  return result;
 +}
 +
 +typedef enum {
 +  EPRT,
 +  PORT,
 +  DONE
 +} ftpport;
 +
 +static CURLcode ftp_state_use_port(struct connectdata *conn,
 +                                   ftpport fcmd) /* start with this */
 +
 +{
 +  CURLcode result = CURLE_OK;
 +  struct ftp_conn *ftpc = &conn->proto.ftpc;
 +  struct Curl_easy *data=conn->data;
 +  curl_socket_t portsock= CURL_SOCKET_BAD;
 +  char myhost[256] = "";
 +
 +  struct Curl_sockaddr_storage ss;
 +  Curl_addrinfo *res, *ai;
 +  curl_socklen_t sslen;
 +  char hbuf[NI_MAXHOST];
 +  struct sockaddr *sa=(struct sockaddr *)&ss;
 +  struct sockaddr_in * const sa4 = (void *)sa;
 +#ifdef ENABLE_IPV6
 +  struct sockaddr_in6 * const sa6 = (void *)sa;
 +#endif
 +  char tmp[1024];
 +  static const char mode[][5] = { "EPRT", "PORT" };
 +  int rc;
 +  int error;
 +  char *host = NULL;
 +  char *string_ftpport = data->set.str[STRING_FTPPORT];
 +  struct Curl_dns_entry *h=NULL;
 +  unsigned short port_min = 0;
 +  unsigned short port_max = 0;
 +  unsigned short port;
 +  bool possibly_non_local = TRUE;
 +
 +  char *addr = NULL;
 +
 +  /* Step 1, figure out what is requested,
 +   * accepted format :
 +   * (ipv4|ipv6|domain|interface)?(:port(-range)?)?
 +   */
 +
 +  if(data->set.str[STRING_FTPPORT] &&
 +     (strlen(data->set.str[STRING_FTPPORT]) > 1)) {
 +
 +#ifdef ENABLE_IPV6
 +    size_t addrlen = INET6_ADDRSTRLEN > strlen(string_ftpport) ?
 +      INET6_ADDRSTRLEN : strlen(string_ftpport);
 +#else
 +    size_t addrlen = INET_ADDRSTRLEN > strlen(string_ftpport) ?
 +      INET_ADDRSTRLEN : strlen(string_ftpport);
 +#endif
 +    char *ip_start = string_ftpport;
 +    char *ip_end = NULL;
 +    char *port_start = NULL;
 +    char *port_sep = NULL;
 +
 +    addr = calloc(addrlen+1, 1);
 +    if(!addr)
 +      return CURLE_OUT_OF_MEMORY;
 +
 +#ifdef ENABLE_IPV6
 +    if(*string_ftpport == '[') {
 +      /* [ipv6]:port(-range) */
 +      ip_start = string_ftpport + 1;
 +      ip_end = strchr(string_ftpport, ']');
 +      if(ip_end)
 +        strncpy(addr, ip_start, ip_end - ip_start);
 +    }
 +    else
 +#endif
 +      if(*string_ftpport == ':') {
 +        /* :port */
 +        ip_end = string_ftpport;
 +      }
 +      else {
 +        ip_end = strchr(string_ftpport, ':');
 +        if(ip_end) {
 +          /* either ipv6 or (ipv4|domain|interface):port(-range) */
 +#ifdef ENABLE_IPV6
 +          if(Curl_inet_pton(AF_INET6, string_ftpport, sa6) == 1) {
 +            /* ipv6 */
 +            port_min = port_max = 0;
 +            strcpy(addr, string_ftpport);
 +            ip_end = NULL; /* this got no port ! */
 +          }
 +          else
 +#endif
 +            /* (ipv4|domain|interface):port(-range) */
 +            strncpy(addr, string_ftpport, ip_end - ip_start);
 +        }
 +        else
 +          /* ipv4|interface */
 +          strcpy(addr, string_ftpport);
 +      }
 +
 +    /* parse the port */
 +    if(ip_end != NULL) {
 +      port_start = strchr(ip_end, ':');
 +      if(port_start) {
 +        port_min = curlx_ultous(strtoul(port_start+1, NULL, 10));
 +        port_sep = strchr(port_start, '-');
 +        if(port_sep) {
 +          port_max = curlx_ultous(strtoul(port_sep + 1, NULL, 10));
 +        }
 +        else
 +          port_max = port_min;
 +      }
 +    }
 +
 +    /* correct errors like:
 +     *  :1234-1230
 +     *  :-4711,  in this case port_min is (unsigned)-1,
 +     *           therefore port_min > port_max for all cases
 +     *           but port_max = (unsigned)-1
 +     */
 +    if(port_min > port_max)
 +      port_min = port_max = 0;
 +
 +
 +    if(*addr != '\0') {
 +      /* attempt to get the address of the given interface name */
 +      switch(Curl_if2ip(conn->ip_addr->ai_family,
 +                        Curl_ipv6_scope(conn->ip_addr->ai_addr),
 +                        conn->scope_id, addr, hbuf, sizeof(hbuf))) {
 +        case IF2IP_NOT_FOUND:
 +          /* not an interface, use the given string as host name instead */
 +          host = addr;
 +          break;
 +        case IF2IP_AF_NOT_SUPPORTED:
 +          return CURLE_FTP_PORT_FAILED;
 +        case IF2IP_FOUND:
 +          host = hbuf; /* use the hbuf for host name */
 +      }
 +    }
 +    else
 +      /* there was only a port(-range) given, default the host */
 +      host = NULL;
 +  } /* data->set.ftpport */
 +
 +  if(!host) {
 +    /* not an interface and not a host name, get default by extracting
 +       the IP from the control connection */
 +
 +    sslen = sizeof(ss);
 +    if(getsockname(conn->sock[FIRSTSOCKET], sa, &sslen)) {
 +      failf(data, "getsockname() failed: %s",
 +          Curl_strerror(conn, SOCKERRNO) );
 +      free(addr);
 +      return CURLE_FTP_PORT_FAILED;
 +    }
 +    switch(sa->sa_family) {
 +#ifdef ENABLE_IPV6
 +    case AF_INET6:
 +      Curl_inet_ntop(sa->sa_family, &sa6->sin6_addr, hbuf, sizeof(hbuf));
 +      break;
 +#endif
 +    default:
 +      Curl_inet_ntop(sa->sa_family, &sa4->sin_addr, hbuf, sizeof(hbuf));
 +      break;
 +    }
 +    host = hbuf; /* use this host name */
 +    possibly_non_local = FALSE; /* we know it is local now */
 +  }
 +
 +  /* resolv ip/host to ip */
 +  rc = Curl_resolv(conn, host, 0, &h);
 +  if(rc == CURLRESOLV_PENDING)
 +    (void)Curl_resolver_wait_resolv(conn, &h);
 +  if(h) {
 +    res = h->addr;
 +    /* when we return from this function, we can forget about this entry
 +       to we can unlock it now already */
 +    Curl_resolv_unlock(data, h);
 +  } /* (h) */
 +  else
 +    res = NULL; /* failure! */
 +
 +  if(res == NULL) {
 +    failf(data, "failed to resolve the address provided to PORT: %s", host);
 +    free(addr);
 +    return CURLE_FTP_PORT_FAILED;
 +  }
 +
 +  free(addr);
 +  host = NULL;
 +
 +  /* step 2, create a socket for the requested address */
 +
 +  portsock = CURL_SOCKET_BAD;
 +  error = 0;
 +  for(ai = res; ai; ai = ai->ai_next) {
 +    result = Curl_socket(conn, ai, NULL, &portsock);
 +    if(result) {
 +      error = SOCKERRNO;
 +      continue;
 +    }
 +    break;
 +  }
 +  if(!ai) {
 +    failf(data, "socket failure: %s", Curl_strerror(conn, error));
 +    return CURLE_FTP_PORT_FAILED;
 +  }
 +
 +  /* step 3, bind to a suitable local address */
 +
 +  memcpy(sa, ai->ai_addr, ai->ai_addrlen);
 +  sslen = ai->ai_addrlen;
 +
 +  for(port = port_min; port <= port_max;) {
 +    if(sa->sa_family == AF_INET)
 +      sa4->sin_port = htons(port);
 +#ifdef ENABLE_IPV6
 +    else
 +      sa6->sin6_port = htons(port);
 +#endif
 +    /* Try binding the given address. */
 +    if(bind(portsock, sa, sslen) ) {
 +      /* It failed. */
 +      error = SOCKERRNO;
 +      if(possibly_non_local && (error == EADDRNOTAVAIL)) {
 +        /* The requested bind address is not local.  Use the address used for
 +         * the control connection instead and restart the port loop
 +         */
 +
 +        infof(data, "bind(port=%hu) on non-local address failed: %s\n", port,
 +              Curl_strerror(conn, error) );
 +
 +        sslen = sizeof(ss);
 +        if(getsockname(conn->sock[FIRSTSOCKET], sa, &sslen)) {
 +          failf(data, "getsockname() failed: %s",
 +                Curl_strerror(conn, SOCKERRNO) );
 +          Curl_closesocket(conn, portsock);
 +          return CURLE_FTP_PORT_FAILED;
 +        }
 +        port = port_min;
 +        possibly_non_local = FALSE; /* don't try this again */
 +        continue;
 +      }
-       else if(error != EADDRINUSE && error != EACCES) {
++      if(error != EADDRINUSE && error != EACCES) {
 +        failf(data, "bind(port=%hu) failed: %s", port,
 +              Curl_strerror(conn, error) );
 +        Curl_closesocket(conn, portsock);
 +        return CURLE_FTP_PORT_FAILED;
 +      }
 +    }
 +    else
 +      break;
 +
 +    port++;
 +  }
 +
 +  /* maybe all ports were in use already*/
 +  if(port > port_max) {
 +    failf(data, "bind() failed, we ran out of ports!");
 +    Curl_closesocket(conn, portsock);
 +    return CURLE_FTP_PORT_FAILED;
 +  }
 +
 +  /* get the name again after the bind() so that we can extract the
 +     port number it uses now */
 +  sslen = sizeof(ss);
 +  if(getsockname(portsock, (struct sockaddr *)sa, &sslen)) {
 +    failf(data, "getsockname() failed: %s",
 +          Curl_strerror(conn, SOCKERRNO) );
 +    Curl_closesocket(conn, portsock);
 +    return CURLE_FTP_PORT_FAILED;
 +  }
 +
 +  /* step 4, listen on the socket */
 +
 +  if(listen(portsock, 1)) {
 +    failf(data, "socket failure: %s", Curl_strerror(conn, SOCKERRNO));
 +    Curl_closesocket(conn, portsock);
 +    return CURLE_FTP_PORT_FAILED;
 +  }
 +
 +  /* step 5, send the proper FTP command */
 +
 +  /* get a plain printable version of the numerical address to work with
 +     below */
 +  Curl_printable_address(ai, myhost, sizeof(myhost));
 +
 +#ifdef ENABLE_IPV6
 +  if(!conn->bits.ftp_use_eprt && conn->bits.ipv6)
 +    /* EPRT is disabled but we are connected to a IPv6 host, so we ignore the
 +       request and enable EPRT again! */
 +    conn->bits.ftp_use_eprt = TRUE;
 +#endif
 +
 +  for(; fcmd != DONE; fcmd++) {
 +
 +    if(!conn->bits.ftp_use_eprt && (EPRT == fcmd))
 +      /* if disabled, goto next */
 +      continue;
 +
 +    if((PORT == fcmd) && sa->sa_family != AF_INET)
 +      /* PORT is IPv4 only */
 +      continue;
 +
 +    switch(sa->sa_family) {
 +    case AF_INET:
 +      port = ntohs(sa4->sin_port);
 +      break;
 +#ifdef ENABLE_IPV6
 +    case AF_INET6:
 +      port = ntohs(sa6->sin6_port);
 +      break;
 +#endif
 +    default:
 +      continue; /* might as well skip this */
 +    }
 +
 +    if(EPRT == fcmd) {
 +      /*
 +       * Two fine examples from RFC2428;
 +       *
 +       * EPRT |1|132.235.1.2|6275|
 +       *
 +       * EPRT |2|1080::8:800:200C:417A|5282|
 +       */
 +
 +      result = Curl_pp_sendf(&ftpc->pp, "%s |%d|%s|%hu|", mode[fcmd],
 +                             sa->sa_family == AF_INET?1:2,
 +                             myhost, port);
 +      if(result) {
 +        failf(data, "Failure sending EPRT command: %s",
 +              curl_easy_strerror(result));
 +        Curl_closesocket(conn, portsock);
 +        /* don't retry using PORT */
 +        ftpc->count1 = PORT;
 +        /* bail out */
 +        state(conn, FTP_STOP);
 +        return result;
 +      }
 +      break;
 +    }
-     else if(PORT == fcmd) {
++    if(PORT == fcmd) {
 +      char *source = myhost;
 +      char *dest = tmp;
 +
 +      /* translate x.x.x.x to x,x,x,x */
 +      while(source && *source) {
 +        if(*source == '.')
 +          *dest=',';
 +        else
 +          *dest = *source;
 +        dest++;
 +        source++;
 +      }
 +      *dest = 0;
 +      snprintf(dest, 20, ",%d,%d", (int)(port>>8), (int)(port&0xff));
 +
 +      result = Curl_pp_sendf(&ftpc->pp, "%s %s", mode[fcmd], tmp);
 +      if(result) {
 +        failf(data, "Failure sending PORT command: %s",
 +              curl_easy_strerror(result));
 +        Curl_closesocket(conn, portsock);
 +        /* bail out */
 +        state(conn, FTP_STOP);
 +        return result;
 +      }
 +      break;
 +    }
 +  }
 +
 +  /* store which command was sent */
 +  ftpc->count1 = fcmd;
 +
 +  close_secondarysocket(conn);
 +
 +  /* we set the secondary socket variable to this for now, it is only so that
 +     the cleanup function will close it in case we fail before the true
 +     secondary stuff is made */
 +  conn->sock[SECONDARYSOCKET] = portsock;
 +
 +  /* this tcpconnect assignment below is a hackish work-around to make the
 +     multi interface with active FTP work - as it will not wait for a
 +     (passive) connect in Curl_is_connected().
 +
 +     The *proper* fix is to make sure that the active connection from the
 +     server is done in a non-blocking way. Currently, it is still BLOCKING.
 +  */
 +  conn->bits.tcpconnect[SECONDARYSOCKET] = TRUE;
 +
 +  state(conn, FTP_PORT);
 +  return result;
 +}
 +
 +static CURLcode ftp_state_use_pasv(struct connectdata *conn)
 +{
 +  struct ftp_conn *ftpc = &conn->proto.ftpc;
 +  CURLcode result = CURLE_OK;
 +  /*
 +    Here's the excecutive summary on what to do:
 +
 +    PASV is RFC959, expect:
 +    227 Entering Passive Mode (a1,a2,a3,a4,p1,p2)
 +
 +    LPSV is RFC1639, expect:
 +    228 Entering Long Passive Mode (4,4,a1,a2,a3,a4,2,p1,p2)
 +
 +    EPSV is RFC2428, expect:
 +    229 Entering Extended Passive Mode (|||port|)
 +
 +  */
 +
 +  static const char mode[][5] = { "EPSV", "PASV" };
 +  int modeoff;
 +
 +#ifdef PF_INET6
 +  if(!conn->bits.ftp_use_epsv && conn->bits.ipv6)
 +    /* EPSV is disabled but we are connected to a IPv6 host, so we ignore the
 +       request and enable EPSV again! */
 +    conn->bits.ftp_use_epsv = TRUE;
 +#endif
 +
 +  modeoff = conn->bits.ftp_use_epsv?0:1;
 +
 +  PPSENDF(&ftpc->pp, "%s", mode[modeoff]);
 +
 +  ftpc->count1 = modeoff;
 +  state(conn, FTP_PASV);
 +  infof(conn->data, "Connect data stream passively\n");
 +
 +  return result;
 +}
 +
 +/*
 + * ftp_state_prepare_transfer() starts PORT, PASV or PRET etc.
 + *
 + * REST is the last command in the chain of commands when a "head"-like
 + * request is made. Thus, if an actual transfer is to be made this is where we
 + * take off for real.
 + */
 +static CURLcode ftp_state_prepare_transfer(struct connectdata *conn)
 +{
 +  CURLcode result = CURLE_OK;
 +  struct FTP *ftp = conn->data->req.protop;
 +  struct Curl_easy *data = conn->data;
 +
 +  if(ftp->transfer != FTPTRANSFER_BODY) {
 +    /* doesn't transfer any data */
 +
 +    /* still possibly do PRE QUOTE jobs */
 +    state(conn, FTP_RETR_PREQUOTE);
 +    result = ftp_state_quote(conn, TRUE, FTP_RETR_PREQUOTE);
 +  }
 +  else if(data->set.ftp_use_port) {
 +    /* We have chosen to use the PORT (or similar) command */
 +    result = ftp_state_use_port(conn, EPRT);
 +  }
 +  else {
 +    /* We have chosen (this is default) to use the PASV (or similar) command */
 +    if(data->set.ftp_use_pret) {
 +      /* The user has requested that we send a PRET command
 +         to prepare the server for the upcoming PASV */
 +      if(!conn->proto.ftpc.file) {
 +        PPSENDF(&conn->proto.ftpc.pp, "PRET %s",
 +                data->set.str[STRING_CUSTOMREQUEST]?
 +                data->set.str[STRING_CUSTOMREQUEST]:
 +                (data->set.ftp_list_only?"NLST":"LIST"));
 +      }
 +      else if(data->set.upload) {
 +        PPSENDF(&conn->proto.ftpc.pp, "PRET STOR %s", conn->proto.ftpc.file);
 +      }
 +      else {
 +        PPSENDF(&conn->proto.ftpc.pp, "PRET RETR %s", conn->proto.ftpc.file);
 +      }
 +      state(conn, FTP_PRET);
 +    }
 +    else {
 +      result = ftp_state_use_pasv(conn);
 +    }
 +  }
 +  return result;
 +}
 +
 +static CURLcode ftp_state_rest(struct connectdata *conn)
 +{
 +  CURLcode result = CURLE_OK;
 +  struct FTP *ftp = conn->data->req.protop;
 +  struct ftp_conn *ftpc = &conn->proto.ftpc;
 +
 +  if((ftp->transfer != FTPTRANSFER_BODY) && ftpc->file) {
 +    /* if a "head"-like request is being made (on a file) */
 +
 +    /* Determine if server can respond to REST command and therefore
 +       whether it supports range */
 +    PPSENDF(&conn->proto.ftpc.pp, "REST %d", 0);
 +
 +    state(conn, FTP_REST);
 +  }
 +  else
 +    result = ftp_state_prepare_transfer(conn);
 +
 +  return result;
 +}
 +
 +static CURLcode ftp_state_size(struct connectdata *conn)
 +{
 +  CURLcode result = CURLE_OK;
 +  struct FTP *ftp = conn->data->req.protop;
 +  struct ftp_conn *ftpc = &conn->proto.ftpc;
 +
 +  if((ftp->transfer == FTPTRANSFER_INFO) && ftpc->file) {
 +    /* if a "head"-like request is being made (on a file) */
 +
 +    /* we know ftpc->file is a valid pointer to a file name */
 +    PPSENDF(&ftpc->pp, "SIZE %s", ftpc->file);
 +
 +    state(conn, FTP_SIZE);
 +  }
 +  else
 +    result = ftp_state_rest(conn);
 +
 +  return result;
 +}
 +
 +static CURLcode ftp_state_list(struct connectdata *conn)
 +{
 +  CURLcode result = CURLE_OK;
 +  struct Curl_easy *data = conn->data;
 +
 +  /* If this output is to be machine-parsed, the NLST command might be better
 +     to use, since the LIST command output is not specified or standard in any
 +     way. It has turned out that the NLST list output is not the same on all
 +     servers either... */
 +
 +  /*
 +     if FTPFILE_NOCWD was specified, we are currently in
 +     the user's home directory, so we should add the path
 +     as argument for the LIST / NLST / or custom command.
 +     Whether the server will support this, is uncertain.
 +
 +     The other ftp_filemethods will CWD into dir/dir/ first and
 +     then just do LIST (in that case: nothing to do here)
 +  */
 +  char *cmd, *lstArg, *slashPos;
 +
 +  lstArg = NULL;
 +  if((data->set.ftp_filemethod == FTPFILE_NOCWD) &&
 +     data->state.path &&
 +     data->state.path[0] &&
 +     strchr(data->state.path, '/')) {
 +
 +    lstArg = strdup(data->state.path);
 +    if(!lstArg)
 +      return CURLE_OUT_OF_MEMORY;
 +
 +    /* Check if path does not end with /, as then we cut off the file part */
 +    if(lstArg[strlen(lstArg) - 1] != '/')  {
 +
 +      /* chop off the file part if format is dir/dir/file */
 +      slashPos = strrchr(lstArg, '/');
 +      if(slashPos)
 +        *(slashPos+1) = '\0';
 +    }
 +  }
 +
 +  cmd = aprintf("%s%s%s",
 +                data->set.str[STRING_CUSTOMREQUEST]?
 +                data->set.str[STRING_CUSTOMREQUEST]:
 +                (data->set.ftp_list_only?"NLST":"LIST"),
 +                lstArg? " ": "",
 +                lstArg? lstArg: "");
 +
 +  if(!cmd) {
 +    free(lstArg);
 +    return CURLE_OUT_OF_MEMORY;
 +  }
 +
 +  result = Curl_pp_sendf(&conn->proto.ftpc.pp, "%s", cmd);
 +
 +  free(lstArg);
 +  free(cmd);
 +
 +  if(result)
 +    return result;
 +
 +  state(conn, FTP_LIST);
 +
 +  return result;
 +}
 +
 +static CURLcode ftp_state_retr_prequote(struct connectdata *conn)
 +{
 +  CURLcode result = CURLE_OK;
 +
 +  /* We've sent the TYPE, now we must send the list of prequote strings */
 +
 +  result = ftp_state_quote(conn, TRUE, FTP_RETR_PREQUOTE);
 +
 +  return result;
 +}
 +
 +static CURLcode ftp_state_stor_prequote(struct connectdata *conn)
 +{
 +  CURLcode result = CURLE_OK;
 +
 +  /* We've sent the TYPE, now we must send the list of prequote strings */
 +
 +  result = ftp_state_quote(conn, TRUE, FTP_STOR_PREQUOTE);
 +
 +  return result;
 +}
 +
 +static CURLcode ftp_state_type(struct connectdata *conn)
 +{
 +  CURLcode result = CURLE_OK;
 +  struct FTP *ftp = conn->data->req.protop;
 +  struct Curl_easy *data = conn->data;
 +  struct ftp_conn *ftpc = &conn->proto.ftpc;
 +
 +  /* If we have selected NOBODY and HEADER, it means that we only want file
 +     information. Which in FTP can't be much more than the file size and
 +     date. */
 +  if(data->set.opt_no_body && ftpc->file &&
 +     ftp_need_type(conn, data->set.prefer_ascii)) {
 +    /* The SIZE command is _not_ RFC 959 specified, and therefor many servers
 +       may not support it! It is however the only way we have to get a file's
 +       size! */
 +
 +    ftp->transfer = FTPTRANSFER_INFO;
 +    /* this means no actual transfer will be made */
 +
 +    /* Some servers return different sizes for different modes, and thus we
 +       must set the proper type before we check the size */
 +    result = ftp_nb_type(conn, data->set.prefer_ascii, FTP_TYPE);
 +    if(result)
 +      return result;
 +  }
 +  else
 +    result = ftp_state_size(conn);
 +
 +  return result;
 +}
 +
 +/* This is called after the CWD commands have been done in the beginning of
 +   the DO phase */
 +static CURLcode ftp_state_mdtm(struct connectdata *conn)
 +{
 +  CURLcode result = CURLE_OK;
 +  struct Curl_easy *data = conn->data;
 +  struct ftp_conn *ftpc = &conn->proto.ftpc;
 +
 +  /* Requested time of file or time-depended transfer? */
 +  if((data->set.get_filetime || data->set.timecondition) && ftpc->file) {
 +
 +    /* we have requested to get the modified-time of the file, this is a white
 +       spot as the MDTM is not mentioned in RFC959 */
 +    PPSENDF(&ftpc->pp, "MDTM %s", ftpc->file);
 +
 +    state(conn, FTP_MDTM);
 +  }
 +  else
 +    result = ftp_state_type(conn);
 +
 +  return result;
 +}
 +
 +
 +/* This is called after the TYPE and possible quote commands have been sent */
 +static CURLcode ftp_state_ul_setup(struct connectdata *conn,
 +                                   bool sizechecked)
 +{
 +  CURLcode result = CURLE_OK;
 +  struct FTP *ftp = conn->data->req.protop;
 +  struct Curl_easy *data = conn->data;
 +  struct ftp_conn *ftpc = &conn->proto.ftpc;
 +  int seekerr = CURL_SEEKFUNC_OK;
 +
 +  if((data->state.resume_from && !sizechecked) ||
 +     ((data->state.resume_from > 0) && sizechecked)) {
 +    /* we're about to continue the uploading of a file */
 +    /* 1. get already existing file's size. We use the SIZE command for this
 +       which may not exist in the server!  The SIZE command is not in
 +       RFC959. */
 +
 +    /* 2. This used to set REST. But since we can do append, we
 +       don't another ftp command. We just skip the source file
 +       offset and then we APPEND the rest on the file instead */
 +
 +    /* 3. pass file-size number of bytes in the source file */
 +    /* 4. lower the infilesize counter */
 +    /* => transfer as usual */
 +
 +    if(data->state.resume_from < 0) {
 +      /* Got no given size to start from, figure it out */
 +      PPSENDF(&ftpc->pp, "SIZE %s", ftpc->file);
 +      state(conn, FTP_STOR_SIZE);
 +      return result;
 +    }
 +
 +    /* enable append */
 +    data->set.ftp_append = TRUE;
 +
 +    /* Let's read off the proper amount of bytes from the input. */
 +    if(conn->seek_func) {
 +      seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
 +                                SEEK_SET);
 +    }
 +
 +    if(seekerr != CURL_SEEKFUNC_OK) {
++      curl_off_t passed=0;
 +      if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
 +        failf(data, "Could not seek stream");
 +        return CURLE_FTP_COULDNT_USE_REST;
 +      }
 +      /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
-       else {
-         curl_off_t passed=0;
-         do {
-           size_t readthisamountnow =
-             (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
-             BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
- 
-           size_t actuallyread =
-             data->state.fread_func(data->state.buffer, 1, readthisamountnow,
-                                    data->state.in);
- 
-           passed += actuallyread;
-           if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
-             /* this checks for greater-than only to make sure that the
-                CURL_READFUNC_ABORT return code still aborts */
-             failf(data, "Failed to read data");
-             return CURLE_FTP_COULDNT_USE_REST;
-           }
-         } while(passed < data->state.resume_from);
-       }
++      do {
++        size_t readthisamountnow =
++          (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
++          BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
++
++        size_t actuallyread =
++          data->state.fread_func(data->state.buffer, 1, readthisamountnow,
++                                 data->state.in);
++
++        passed += actuallyread;
++        if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
++          /* this checks for greater-than only to make sure that the
++             CURL_READFUNC_ABORT return code still aborts */
++          failf(data, "Failed to read data");
++          return CURLE_FTP_COULDNT_USE_REST;
++        }
++      } while(passed < data->state.resume_from);
 +    }
 +    /* now, decrease the size of the read */
 +    if(data->state.infilesize>0) {
 +      data->state.infilesize -= data->state.resume_from;
 +
 +      if(data->state.infilesize <= 0) {
 +        infof(data, "File already completely uploaded\n");
 +
 +        /* no data to transfer */
 +        Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
 +
 +        /* Set ->transfer so that we won't get any error in
 +         * ftp_done() because we didn't transfer anything! */
 +        ftp->transfer = FTPTRANSFER_NONE;
 +
 +        state(conn, FTP_STOP);
 +        return CURLE_OK;
 +      }
 +    }
 +    /* we've passed, proceed as normal */
 +  } /* resume_from */
 +
 +  PPSENDF(&ftpc->pp, data->set.ftp_append?"APPE %s":"STOR %s",
 +          ftpc->file);
 +
 +  state(conn, FTP_STOR);
 +
 +  return result;
 +}
 +
 +static CURLcode ftp_state_quote(struct connectdata *conn,
 +                                bool init,
 +                                ftpstate instate)
 +{
 +  CURLcode result = CURLE_OK;
 +  struct Curl_easy *data = conn->data;
 +  struct FTP *ftp = data->req.protop;
 +  struct ftp_conn *ftpc = &conn->proto.ftpc;
 +  bool quote=FALSE;
 +  struct curl_slist *item;
 +
 +  switch(instate) {
 +  case FTP_QUOTE:
 +  default:
 +    item = data->set.quote;
 +    break;
 +  case FTP_RETR_PREQUOTE:
 +  case FTP_STOR_PREQUOTE:
 +    item = data->set.prequote;
 +    break;
 +  case FTP_POSTQUOTE:
 +    item = data->set.postquote;
 +    break;
 +  }
 +
 +  /*
 +   * This state uses:
 +   * 'count1' to iterate over the commands to send
-    * 'count2' to store wether to allow commands to fail
++   * 'count2' to store whether to allow commands to fail
 +   */
 +
 +  if(init)
 +    ftpc->count1 = 0;
 +  else
 +    ftpc->count1++;
 +
 +  if(item) {
 +    int i = 0;
 +
 +    /* Skip count1 items in the linked list */
 +    while((i< ftpc->count1) && item) {
 +      item = item->next;
 +      i++;
 +    }
 +    if(item) {
 +      char *cmd = item->data;
 +      if(cmd[0] == '*') {
 +        cmd++;
 +        ftpc->count2 = 1; /* the sent command is allowed to fail */
 +      }
 +      else
 +        ftpc->count2 = 0; /* failure means cancel operation */
 +
 +      PPSENDF(&ftpc->pp, "%s", cmd);
 +      state(conn, instate);
 +      quote = TRUE;
 +    }
 +  }
 +
 +  if(!quote) {
 +    /* No more quote to send, continue to ... */
 +    switch(instate) {
 +    case FTP_QUOTE:
 +    default:
 +      result = ftp_state_cwd(conn);
 +      break;
 +    case FTP_RETR_PREQUOTE:
 +      if(ftp->transfer != FTPTRANSFER_BODY)
 +        state(conn, FTP_STOP);
 +      else {
 +        if(ftpc->known_filesize != -1) {
 +          Curl_pgrsSetDownloadSize(data, ftpc->known_filesize);
 +          result = ftp_state_retr(conn, ftpc->known_filesize);
 +        }
 +        else {
 +          if(data->set.ignorecl) {
 +            /* This code is to support download of growing files.  It prevents
 +               the state machine from requesting the file size from the
 +               server.  With an unknown file size the download continues until
 +               the server terminates it, otherwise the client stops if the
 +               received byte count exceeds the reported file size.  Set option
 +               CURLOPT_IGNORE_CONTENT_LENGTH to 1 to enable this behavior.*/
 +            PPSENDF(&ftpc->pp, "RETR %s", ftpc->file);
 +            state(conn, FTP_RETR);
 +          }
 +          else {
 +            PPSENDF(&ftpc->pp, "SIZE %s", ftpc->file);
 +            state(conn, FTP_RETR_SIZE);
 +          }
 +        }
 +      }
 +      break;
 +    case FTP_STOR_PREQUOTE:
 +      result = ftp_state_ul_setup(conn, FALSE);
 +      break;
 +    case FTP_POSTQUOTE:
 +      break;
 +    }
 +  }
 +
 +  return result;
 +}
 +
 +/* called from ftp_state_pasv_resp to switch to PASV in case of EPSV
 +   problems */
 +static CURLcode ftp_epsv_disable(struct connectdata *conn)
 +{
 +  CURLcode result = CURLE_OK;
 +
 +  if(conn->bits.ipv6) {
 +    /* We can't disable EPSV when doing IPv6, so this is instead a fail */
 +    failf(conn->data, "Failed EPSV attempt, exiting\n");
 +    return CURLE_WEIRD_SERVER_REPLY;
 +  }
 +
 +  infof(conn->data, "Failed EPSV attempt. Disabling EPSV\n");
 +  /* disable it for next transfer */
 +  conn->bits.ftp_use_epsv = FALSE;
 +  conn->data->state.errorbuf = FALSE; /* allow error message to get
 +                                         rewritten */
 +  PPSENDF(&conn->proto.ftpc.pp, "%s", "PASV");
 +  conn->proto.ftpc.count1++;
 +  /* remain in/go to the FTP_PASV state */
 +  state(conn, FTP_PASV);
 +  return result;
 +}
 +
 +
 +static char *control_address(struct connectdata *conn)
 +{
 +  /* Returns the control connection IP address.
 +     If a proxy tunnel is used, returns the original host name instead, because
 +     the effective control connection address is the proxy address,
 +     not the ftp host. */
 +  if(conn->bits.tunnel_proxy || conn->bits.socksproxy)
 +    return conn->host.name;
 +
 +  return conn->ip_addr_str;
 +}
 +
 +static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
 +                                    int ftpcode)
 +{
 +  struct ftp_conn *ftpc = &conn->proto.ftpc;
 +  CURLcode result;
 +  struct Curl_easy *data=conn->data;
 +  struct Curl_dns_entry *addr=NULL;
 +  int rc;
 +  unsigned short connectport; /* the local port connect() should use! */
 +  char *str=&data->state.buffer[4];  /* start on the first letter */
 +
 +  /* if we come here again, make sure the former name is cleared */
 +  Curl_safefree(ftpc->newhost);
 +
 +  if((ftpc->count1 == 0) &&
 +     (ftpcode == 229)) {
 +    /* positive EPSV response */
 +    char *ptr = strchr(str, '(');
 +    if(ptr) {
 +      unsigned int num;
 +      char separator[4];
 +      ptr++;
 +      if(5 == sscanf(ptr, "%c%c%c%u%c",
 +                     &separator[0],
 +                     &separator[1],
 +                     &separator[2],
 +                     &num,
 +                     &separator[3])) {
 +        const char sep1 = separator[0];
 +        int i;
 +
 +        /* The four separators should be identical, or else this is an oddly
 +           formatted reply and we bail out immediately. */
 +        for(i=1; i<4; i++) {
 +          if(separator[i] != sep1) {
 +            ptr=NULL; /* set to NULL to signal error */
 +            break;
 +          }
 +        }
 +        if(num > 0xffff) {
 +          failf(data, "Illegal port number in EPSV reply");
 +          return CURLE_FTP_WEIRD_PASV_REPLY;
 +        }
 +        if(ptr) {
 +          ftpc->newport = (unsigned short)(num & 0xffff);
 +          ftpc->newhost = strdup(control_address(conn));
 +          if(!ftpc->newhost)
 +            return CURLE_OUT_OF_MEMORY;
 +        }
 +      }
 +      else
 +        ptr=NULL;
 +    }
 +    if(!ptr) {
 +      failf(data, "Weirdly formatted EPSV reply");
 +      return CURLE_FTP_WEIRD_PASV_REPLY;
 +    }
 +  }
 +  else if((ftpc->count1 == 1) &&
 +          (ftpcode == 227)) {
 +    /* positive PASV response */
 +    int ip[4];
 +    int port[2];
 +
 +    /*
 +     * Scan for a sequence of six comma-separated numbers and use them as
 +     * IP+port indicators.
 +     *
 +     * Found reply-strings include:
 +     * "227 Entering Passive Mode (127,0,0,1,4,51)"
 +     * "227 Data transfer will passively listen to 127,0,0,1,4,51"
 +     * "227 Entering passive mode. 127,0,0,1,4,51"
 +     */
 +    while(*str) {
 +      if(6 == sscanf(str, "%d,%d,%d,%d,%d,%d",
 +                     &ip[0], &ip[1], &ip[2], &ip[3],
 +                     &port[0], &port[1]))
 +        break;
 +      str++;
 +    }
 +
 +    if(!*str) {
 +      failf(data, "Couldn't interpret the 227-response");
 +      return CURLE_FTP_WEIRD_227_FORMAT;
 +    }
 +
 +    /* we got OK from server */
 +    if(data->set.ftp_skip_ip) {
 +      /* told to ignore the remotely given IP but instead use the host we used
 +         for the control connection */
 +      infof(data, "Skip %d.%d.%d.%d for data connection, re-use %s instead\n",
 +            ip[0], ip[1], ip[2], ip[3],
 +            conn->host.name);
 +      ftpc->newhost = strdup(control_address(conn));
 +    }
 +    else
 +      ftpc->newhost = aprintf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
 +
 +    if(!ftpc->newhost)
 +      return CURLE_OUT_OF_MEMORY;
 +
 +    ftpc->newport = (unsigned short)(((port[0]<<8) + port[1]) & 0xffff);
 +  }
 +  else if(ftpc->count1 == 0) {
 +    /* EPSV failed, move on to PASV */
 +    return ftp_epsv_disable(conn);
 +  }
 +  else {
 +    failf(data, "Bad PASV/EPSV response: %03d", ftpcode);
 +    return CURLE_FTP_WEIRD_PASV_REPLY;
 +  }
 +
 +  if(conn->bits.proxy) {
 +    /*
 +     * This connection uses a proxy and we need to connect to the proxy again
 +     * here. We don't want to rely on a former host lookup that might've
 +     * expired now, instead we remake the lookup here and now!
 +     */
 +    const char * const host_name = conn->bits.socksproxy ?
 +      conn->socks_proxy.host.name : conn->http_proxy.host.name;
 +    rc = Curl_resolv(conn, host_name, (int)conn->port, &addr);
 +    if(rc == CURLRESOLV_PENDING)
 +      /* BLOCKING, ignores the return code but 'addr' will be NULL in
 +         case of failure */
 +      (void)Curl_resolver_wait_resolv(conn, &addr);
 +
 +    connectport =
 +      (unsigned short)conn->port; /* we connect to the proxy's port */
 +
 +    if(!addr) {
 +      failf(data, "Can't resolve proxy host %s:%hu", host_name, connectport);
-       return CURLE_FTP_CANT_GET_HOST;
++      return CURLE_COULDNT_RESOLVE_PROXY;
 +    }
 +  }
 +  else {
 +    /* normal, direct, ftp connection */
 +    rc = Curl_resolv(conn, ftpc->newhost, ftpc->newport, &addr);
 +    if(rc == CURLRESOLV_PENDING)
 +      /* BLOCKING */
 +      (void)Curl_resolver_wait_resolv(conn, &addr);
 +
 +    connectport = ftpc->newport; /* we connect to the remote port */
 +
 +    if(!addr) {
 +      failf(data, "Can't resolve new host %s:%hu", ftpc->newhost, connectport);
 +      return CURLE_FTP_CANT_GET_HOST;
 +    }
 +  }
 +
 +  conn->bits.tcpconnect[SECONDARYSOCKET] = FALSE;
 +  result = Curl_connecthost(conn, addr);
 +
 +  if(result) {
 +    Curl_resolv_unlock(data, addr); /* we're done using this address */
 +    if(ftpc->count1 == 0 && ftpcode == 229)
 +      return ftp_epsv_disable(conn);
 +
 +    return result;
 +  }
 +
 +
 +  /*
 +   * When this is used from the multi interface, this might've returned with
 +   * the 'connected' set to FALSE and thus we are now awaiting a non-blocking
 +   * connect to connect.
 +   */
 +
 +  if(data->set.verbose)
 +    /* this just dumps information about this second connection */
 +    ftp_pasv_verbose(conn, addr->addr, ftpc->newhost, connectport);
 +
++  Curl_resolv_unlock(data, addr); /* we're done using this address */
++
 +  Curl_safefree(conn->secondaryhostname);
-   conn->secondaryhostname = strdup(ftpc->newhost);
 +  conn->secondary_port = ftpc->newport;
++  conn->secondaryhostname = strdup(ftpc->newhost);
++  if(!conn->secondaryhostname)
++    return CURLE_OUT_OF_MEMORY;
 +
-   Curl_resolv_unlock(data, addr); /* we're done using this address */
 +  conn->bits.do_more = TRUE;
 +  state(conn, FTP_STOP); /* this phase is completed */
 +
 +  return result;
 +}
 +
 +static CURLcode ftp_state_port_resp(struct connectdata *conn,
 +                                    int ftpcode)
 +{
 +  struct Curl_easy *data = conn->data;
 +  struct ftp_conn *ftpc = &conn->proto.ftpc;
 +  ftpport fcmd = (ftpport)ftpc->count1;
 +  CURLcode result = CURLE_OK;
 +
 +  /* The FTP spec tells a positive response should have code 200.
 +     Be more permissive here to tolerate deviant servers. */
 +  if(ftpcode / 100 != 2) {
 +    /* the command failed */
 +
 +    if(EPRT == fcmd) {
 +      infof(data, "disabling EPRT usage\n");
 +      conn->bits.ftp_use_eprt = FALSE;
 +    }
 +    fcmd++;
 +
 +    if(fcmd == DONE) {
 +      failf(data, "Failed to do PORT");
 +      result = CURLE_FTP_PORT_FAILED;
 +    }
 +    else
 +      /* try next */
 +      result = ftp_state_use_port(conn, fcmd);
 +  }
 +  else {
 +    infof(data, "Connect data stream actively\n");
 +    state(conn, FTP_STOP); /* end of DO phase */
 +    result = ftp_dophase_done(conn, FALSE);
 +  }
 +
 +  return result;
 +}
 +
 +static CURLcode ftp_state_mdtm_resp(struct connectdata *conn,
 +                                    int ftpcode)
 +{
 +  CURLcode result = CURLE_OK;
 +  struct Curl_easy *data=conn->data;
 +  struct FTP *ftp = data->req.protop;
 +  struct ftp_conn *ftpc = &conn->proto.ftpc;
 +
 +  switch(ftpcode) {
 +  case 213:
 +    {
 +      /* we got a time. Format should be: "YYYYMMDDHHMMSS[.sss]" where the
 +         last .sss part is optional and means fractions of a second */
 +      int year, month, day, hour, minute, second;
 +      char *buf = data->state.buffer;
 +      if(6 == sscanf(buf+4, "%04d%02d%02d%02d%02d%02d",
 +                     &year, &month, &day, &hour, &minute, &second)) {
 +        /* we have a time, reformat it */
 +        time_t secs=time(NULL);
 +        /* using the good old yacc/bison yuck */
-         snprintf(buf, sizeof(conn->data->state.buffer),
++        snprintf(buf, CURL_BUFSIZE(conn->data->set.buffer_size),
 +                 "%04d%02d%02d %02d:%02d:%02d GMT",
 +                 year, month, day, hour, minute, second);
 +        /* now, convert this into a time() value: */
 +        data->info.filetime = (long)curl_getdate(buf, &secs);
 +      }
 +
 +#ifdef CURL_FTP_HTTPSTYLE_HEAD
 +      /* If we asked for a time of the file and we actually got one as well,
 +         we "emulate" a HTTP-style header in our output. */
 +
 +      if(data->set.opt_no_body &&
 +         ftpc->file &&
 +         data->set.get_filetime &&
 +         (data->info.filetime>=0) ) {
 +        time_t filetime = (time_t)data->info.filetime;
 +        struct tm buffer;
 +        const struct tm *tm = &buffer;
 +
 +        result = Curl_gmtime(filetime, &buffer);
 +        if(result)
 +          return result;
 +
 +        /* format: "Tue, 15 Nov 1994 12:45:26" */
 +        snprintf(buf, BUFSIZE-1,
 +                 "Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n",
 +                 Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
 +                 tm->tm_mday,
 +                 Curl_month[tm->tm_mon],
 +                 tm->tm_year + 1900,
 +                 tm->tm_hour,
 +                 tm->tm_min,
 +                 tm->tm_sec);
 +        result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0);
 +        if(result)
 +          return result;
 +      } /* end of a ridiculous amount of conditionals */
 +#endif
 +    }
 +    break;
 +  default:
 +    infof(data, "unsupported MDTM reply format\n");
 +    break;
 +  case 550: /* "No such file or directory" */
 +    failf(data, "Given file does not exist");
 +    result = CURLE_FTP_COULDNT_RETR_FILE;
 +    break;
 +  }
 +
 +  if(data->set.timecondition) {
 +    if((data->info.filetime > 0) && (data->set.timevalue > 0)) {
 +      switch(data->set.timecondition) {
 +      case CURL_TIMECOND_IFMODSINCE:
 +      default:
 +        if(data->info.filetime <= data->set.timevalue) {
 +          infof(data, "The requested document is not new enough\n");
 +          ftp->transfer = FTPTRANSFER_NONE; /* mark to not transfer data */
 +          data->info.timecond = TRUE;
 +          state(conn, FTP_STOP);
 +          return CURLE_OK;
 +        }
 +        break;
 +      case CURL_TIMECOND_IFUNMODSINCE:
 +        if(data->info.filetime > data->set.timevalue) {
 +          infof(data, "The requested document is not old enough\n");
 +          ftp->transfer = FTPTRANSFER_NONE; /* mark to not transfer data */
 +          data->info.timecond = TRUE;
 +          state(conn, FTP_STOP);
 +          return CURLE_OK;
 +        }
 +        break;
 +      } /* switch */
 +    }
 +    else {
 +      infof(data, "Skipping time comparison\n");
 +    }
 +  }
 +
 +  if(!result)
 +    result = ftp_state_type(conn);
 +
 +  return result;
 +}
 +
 +static CURLcode ftp_state_type_resp(struct connectdata *conn,
 +                                    int ftpcode,
 +                                    ftpstate instate)
 +{
 +  CURLcode result = CURLE_OK;
 +  struct Curl_easy *data=conn->data;
 +
 +  if(ftpcode/100 != 2) {
 +    /* "sasserftpd" and "(u)r(x)bot ftpd" both responds with 226 after a
 +       successful 'TYPE I'. While that is not as RFC959 says, it is still a
 +       positive response code and we allow that. */
 +    failf(data, "Couldn't set desired mode");
 +    return CURLE_FTP_COULDNT_SET_TYPE;
 +  }
 +  if(ftpcode != 200)
 +    infof(data, "Got a %03d response code instead of the assumed 200\n",
 +          ftpcode);
 +
 +  if(instate == FTP_TYPE)
 +    result = ftp_state_size(conn);
 +  else if(instate == FTP_LIST_TYPE)
 +    result = ftp_state_list(conn);
 +  else if(instate == FTP_RETR_TYPE)
 +    result = ftp_state_retr_prequote(conn);
 +  else if(instate == FTP_STOR_TYPE)
 +    result = ftp_state_stor_prequote(conn);
 +
 +  return result;
 +}
 +
 +static CURLcode ftp_state_retr(struct connectdata *conn,
 +                                         curl_off_t filesize)
 +{
 +  CURLcode result = CURLE_OK;
 +  struct Curl_easy *data=conn->data;
 +  struct FTP *ftp = data->req.protop;
 +  struct ftp_conn *ftpc = &conn->proto.ftpc;
 +
 +  if(data->set.max_filesize && (filesize > data->set.max_filesize)) {
 +    failf(data, "Maximum file size exceeded");
 +    return CURLE_FILESIZE_EXCEEDED;
 +  }
 +  ftp->downloadsize = filesize;
 +
 +  if(data->state.resume_from) {
 +    /* We always (attempt to) get the size of downloads, so it is done before
 +       this even when not doing resumes. */
 +    if(filesize == -1) {
 +      infof(data, "ftp server doesn't support SIZE\n");
 +      /* We couldn't get the size and therefore we can't know if there really
 +         is a part of the file left to get, although the server will just
 +         close the connection when we start the connection so it won't cause
 +         us any harm, just not make us exit as nicely. */
 +    }
 +    else {
 +      /* We got a file size report, so we check that there actually is a
 +         part of the file left to get, or else we go home.  */
 +      if(data->state.resume_from< 0) {
 +        /* We're supposed to download the last abs(from) bytes */
 +        if(filesize < -data->state.resume_from) {
 +          failf(data, "Offset (%" CURL_FORMAT_CURL_OFF_T
 +                ") was beyond file size (%" CURL_FORMAT_CURL_OFF_T ")",
 +                data->state.resume_from, filesize);
 +          return CURLE_BAD_DOWNLOAD_RESUME;
 +        }
 +        /* convert to size to download */
 +        ftp->downloadsize = -data->state.resume_from;
 +        /* download from where? */
 +        data->state.resume_from = filesize - ftp->downloadsize;
 +      }
 +      else {
 +        if(filesize < data->state.resume_from) {
 +          failf(data, "Offset (%" CURL_FORMAT_CURL_OFF_T
 +                ") was beyond file size (%" CURL_FORMAT_CURL_OFF_T ")",
 +                data->state.resume_from, filesize);
 +          return CURLE_BAD_DOWNLOAD_RESUME;
 +        }
 +        /* Now store the number of bytes we are expected to download */
 +        ftp->downloadsize = filesize-data->state.resume_from;
 +      }
 +    }
 +
 +    if(ftp->downloadsize == 0) {
 +      /* no data to transfer */
 +      Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
 +      infof(data, "File already completely downloaded\n");
 +
 +      /* Set ->transfer so that we won't get any error in ftp_done()
 +       * because we didn't transfer the any file */
 +      ftp->transfer = FTPTRANSFER_NONE;
 +      state(conn, FTP_STOP);
 +      return CURLE_OK;
 +    }
 +
 +    /* Set resume file transfer offset */
 +    infof(data, "Instructs server to resume from offset %"
 +          CURL_FORMAT_CURL_OFF_T "\n", data->state.resume_from);
 +
 +    PPSENDF(&ftpc->pp, "REST %" CURL_FORMAT_CURL_OFF_T,
 +            data->state.resume_from);
 +
 +    state(conn, FTP_RETR_REST);
 +  }
 +  else {
 +    /* no resume */
 +    PPSENDF(&ftpc->pp, "RETR %s", ftpc->file);
 +    state(conn, FTP_RETR);
 +  }
 +
 +  return result;
 +}
 +
 +static CURLcode ftp_state_size_resp(struct connectdata *conn,
 +                                    int ftpcode,
 +                                    ftpstate instate)
 +{
 +  CURLcode result = CURLE_OK;
 +  struct Curl_easy *data=conn->data;
 +  curl_off_t filesize;
 +  char *buf = data->state.buffer;
 +
 +  /* get the size from the ascii string: */
 +  filesize = (ftpcode == 213)?curlx_strtoofft(buf+4, NULL, 0):-1;
 +
 +  if(instate == FTP_SIZE) {
 +#ifdef CURL_FTP_HTTPSTYLE_HEAD
 +    if(-1 != filesize) {
-       snprintf(buf, sizeof(data->state.buffer),
++      snprintf(buf, CURL_BUFSIZE(data->set.buffer_size),
 +               "Content-Length: %" CURL_FORMAT_CURL_OFF_T "\r\n", filesize);
 +      result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0);
 +      if(result)
 +        return result;
 +    }
 +#endif
 +    Curl_pgrsSetDownloadSize(data, filesize);
 +    result = ftp_state_rest(conn);
 +  }
 +  else if(instate == FTP_RETR_SIZE) {
 +    Curl_pgrsSetDownloadSize(data, filesize);
 +    result = ftp_state_retr(conn, filesize);
 +  }
 +  else if(instate == FTP_STOR_SIZE) {
 +    data->state.resume_from = filesize;
 +    result = ftp_state_ul_setup(conn, TRUE);
 +  }
 +
 +  return result;
 +}
 +
 +static CURLcode ftp_state_rest_resp(struct connectdata *conn,
 +                                    int ftpcode,
 +                                    ftpstate instate)
 +{
 +  CURLcode result = CURLE_OK;
 +  struct ftp_conn *ftpc = &conn->proto.ftpc;
 +
 +  switch(instate) {
 +  case FTP_REST:
 +  default:
 +#ifdef CURL_FTP_HTTPSTYLE_HEAD
 +    if(ftpcode == 350) {
 +      char buffer[24]= { "Accept-ranges: bytes\r\n" };
 +      result = Curl_client_write(conn, CLIENTWRITE_BOTH, buffer, 0);
 +      if(result)
 +        return result;
 +    }
 +#endif
 +    result = ftp_state_prepare_transfer(conn);
 +    break;
 +
 +  case FTP_RETR_REST:
 +    if(ftpcode != 350) {
 +      failf(conn->data, "Couldn't use REST");
 +      result = CURLE_FTP_COULDNT_USE_REST;
 +    }
 +    else {
 +      PPSENDF(&ftpc->pp, "RETR %s", ftpc->file);
 +      state(conn, FTP_RETR);
 +    }
 +    break;
 +  }
 +
 +  return result;
 +}
 +
 +static CURLcode ftp_state_stor_resp(struct connectdata *conn,
 +                                    int ftpcode, ftpstate instate)
 +{
 +  CURLcode result = CURLE_OK;
 +  struct Curl_easy *data = conn->data;
 +
 +  if(ftpcode>=400) {
 +    failf(data, "Failed FTP upload: %0d", ftpcode);
 +    state(conn, FTP_STOP);
 +    /* oops, we never close the sockets! */
 +    return CURLE_UPLOAD_FAILED;
 +  }
 +
 +  conn->proto.ftpc.state_saved = instate;
 +
 +  /* PORT means we are now awaiting the server to connect to us. */
 +  if(data->set.ftp_use_port) {
 +    bool connected;
 +
 +    state(conn, FTP_STOP); /* no longer in STOR state */
 +
 +    result = AllowServerConnect(conn, &connected);
 +    if(result)
 +      return result;
 +
 +    if(!connected) {
 +      struct ftp_conn *ftpc = &conn->proto.ftpc;
 +      infof(data, "Data conn was not available immediately\n");
 +      ftpc->wait_data_conn = TRUE;
 +    }
 +
 +    return CURLE_OK;
 +  }
-   else
-     return InitiateTransfer(conn);
++  return InitiateTransfer(conn);
 +}
 +
 +/* for LIST and RETR responses */
 +static CURLcode ftp_state_get_resp(struct connectdata *conn,
 +                                    int ftpcode,
 +                                    ftpstate instate)
 +{
 +  CURLcode result = CURLE_OK;
 +  struct Curl_easy *data = conn->data;
 +  struct FTP *ftp = data->req.protop;
 +  char *buf = data->state.buffer;
 +
 +  if((ftpcode == 150) || (ftpcode == 125)) {
 +
 +    /*
 +      A;
 +      150 Opening BINARY mode data connection for /etc/passwd (2241
 +      bytes).  (ok, the file is being transferred)
 +
 +      B:
 +      150 Opening ASCII mode data connection for /bin/ls
 +
 +      C:
 +      150 ASCII data connection for /bin/ls (137.167.104.91,37445) (0 bytes).
 +
 +      D:
 +      150 Opening ASCII mode data connection for [file] (0.0.0.0,0) (545 bytes)
 +
 +      E:
 +      125 Data connection already open; Transfer starting. */
 +
 +    curl_off_t size=-1; /* default unknown size */
 +
 +
 +    /*
 +     * It appears that there are FTP-servers that return size 0 for files when
 +     * SIZE is used on the file while being in BINARY mode. To work around
 +     * that (stupid) behavior, we attempt to parse the RETR response even if
 +     * the SIZE returned size zero.
 +     *
 +     * Debugging help from Salvatore Sorrentino on February 26, 2003.
 +     */
 +
 +    if((instate != FTP_LIST) &&
 +       !data->set.prefer_ascii &&
 +       (ftp->downloadsize < 1)) {
 +      /*
 +       * It seems directory listings either don't show the size or very
 +       * often uses size 0 anyway. ASCII transfers may very well turn out
 +       * that the transferred amount of data is not the same as this line
 +       * tells, why using this number in those cases only confuses us.
 +       *
 +       * Example D above makes this parsing a little tricky */
 +      char *bytes;
 +      bytes=strstr(buf, " bytes");
 +      if(bytes--) {
 +        long in=(long)(bytes-buf);
 +        /* this is a hint there is size information in there! ;-) */
 +        while(--in) {
 +          /* scan for the left parenthesis and break there */
 +          if('(' == *bytes)
 +            break;
 +          /* skip only digits */
 +          if(!ISDIGIT(*bytes)) {
 +            bytes=NULL;
 +            break;
 +          }
 +          /* one more estep backwards */
 +          bytes--;
 +        }
 +        /* if we have nothing but digits: */
 +        if(bytes++) {
 +          /* get the number! */
 +          size = curlx_strtoofft(bytes, NULL, 0);
 +        }
 +      }
 +    }
 +    else if(ftp->downloadsize > -1)
 +      size = ftp->downloadsize;
 +
 +    if(size > data->req.maxdownload && data->req.maxdownload > 0)
 +      size = data->req.size = data->req.maxdownload;
 +    else if((instate != FTP_LIST) && (data->set.prefer_ascii))
 +      size = -1; /* kludge for servers that understate ASCII mode file size */
 +
 +    infof(data, "Maxdownload = %" CURL_FORMAT_CURL_OFF_T "\n",
 +          data->req.maxdownload);
 +
 +    if(instate != FTP_LIST)
 +      infof(data, "Getting file with size: %" CURL_FORMAT_CURL_OFF_T "\n",
 +            size);
 +
 +    /* FTP download: */
 +    conn->proto.ftpc.state_saved = instate;
 +    conn->proto.ftpc.retr_size_saved = size;
 +
 +    if(data->set.ftp_use_port) {
 +      bool connected;
 +
 +      result = AllowServerConnect(conn, &connected);
 +      if(result)
 +        return result;
 +
 +      if(!connected) {
 +        struct ftp_conn *ftpc = &conn->proto.ftpc;
 +        infof(data, "Data conn was not available immediately\n");
 +        state(conn, FTP_STOP);
 +        ftpc->wait_data_conn = TRUE;
 +      }
 +    }
 +    else
 +      return InitiateTransfer(conn);
 +  }
 +  else {
 +    if((instate == FTP_LIST) && (ftpcode == 450)) {
 +      /* simply no matching files in the dir listing */
 +      ftp->transfer = FTPTRANSFER_NONE; /* don't download anything */
 +      state(conn, FTP_STOP); /* this phase is over */
 +    }
 +    else {
 +      failf(data, "RETR response: %03d", ftpcode);
 +      return instate == FTP_RETR && ftpcode == 550?
 +        CURLE_REMOTE_FILE_NOT_FOUND:
 +        CURLE_FTP_COULDNT_RETR_FILE;
 +    }
 +  }
 +
 +  return result;
 +}
 +
 +/* after USER, PASS and ACCT */
 +static CURLcode ftp_state_loggedin(struct connectdata *conn)
 +{
 +  CURLcode result = CURLE_OK;
 +
 +  if(conn->ssl[FIRSTSOCKET].use) {
 +    /* PBSZ = PROTECTION BUFFER SIZE.
 +
 +    The 'draft-murray-auth-ftp-ssl' (draft 12, page 7) says:
 +
 +    Specifically, the PROT command MUST be preceded by a PBSZ
 +    command and a PBSZ command MUST be preceded by a successful
 +    security data exchange (the TLS negotiation in this case)
 +
 +    ... (and on page 8):
 +
 +    Thus the PBSZ command must still be issued, but must have a
 +    parameter of '0' to indicate that no buffering is taking place
 +    and the data connection should not be encapsulated.
 +    */
 +    PPSENDF(&conn->proto.ftpc.pp, "PBSZ %d", 0);
 +    state(conn, FTP_PBSZ);
 +  }
 +  else {
 +    result = ftp_state_pwd(conn);
 +  }
 +  return result;
 +}
 +
 +/* for USER and PASS responses */
 +static CURLcode ftp_state_user_resp(struct connectdata *conn,
 +                                    int ftpcode,
 +                                    ftpstate instate)
 +{
 +  CURLcode result = CURLE_OK;
 +  struct Curl_easy *data = conn->data;
 +  struct FTP *ftp = data->req.protop;
 +  struct ftp_conn *ftpc = &conn->proto.ftpc;
 +  (void)instate; /* no use for this yet */
 +
 +  /* some need password anyway, and others just return 2xx ignored */
 +  if((ftpcode == 331) && (ftpc->state == FTP_USER)) {
 +    /* 331 Password required for ...
 +       (the server requires to send the user's password too) */
 +    PPSENDF(&ftpc->pp, "PASS %s", ftp->passwd?ftp->passwd:"");
 +    state(conn, FTP_PASS);
 +  }
 +  else if(ftpcode/100 == 2) {
 +    /* 230 User ... logged in.
 +       (the user logged in with or without password) */
 +    result = ftp_state_loggedin(conn);
 +  }
 +  else if(ftpcode == 332) {
 +    if(data->set.str[STRING_FTP_ACCOUNT]) {
 +      PPSENDF(&ftpc->pp, "ACCT %s", data->set.str[STRING_FTP_ACCOUNT]);
 +      state(conn, FTP_ACCT);
 +    }
 +    else {
 +      failf(data, "ACCT requested but none available");
 +      result = CURLE_LOGIN_DENIED;
 +    }
 +  }
 +  else {
 +    /* All other response codes, like:
 +
 +    530 User ... access denied
 +    (the server denies to log the specified user) */
 +
 +    if(conn->data->set.str[STRING_FTP_ALTERNATIVE_TO_USER] &&
 +        !conn->data->state.ftp_trying_alternative) {
 +      /* Ok, USER failed.  Let's try the supplied command. */
 +      PPSENDF(&conn->proto.ftpc.pp, "%s",
 +              conn->data->set.str[STRING_FTP_ALTERNATIVE_TO_USER]);
 +      conn->data->state.ftp_trying_alternative = TRUE;
 +      state(conn, FTP_USER);
 +      result = CURLE_OK;
 +    }
 +    else {
 +      failf(data, "Access denied: %03d", ftpcode);
 +      result = CURLE_LOGIN_DENIED;
 +    }
 +  }
 +  return result;
 +}
 +
 +/* for ACCT response */
 +static CURLcode ftp_state_acct_resp(struct connectdata *conn,
 +                                    int ftpcode)
 +{
 +  CURLcode result = CURLE_OK;
 +  struct Curl_easy *data = conn->data;
 +  if(ftpcode != 230) {
 +    failf(data, "ACCT rejected by server: %03d", ftpcode);
 +    result = CURLE_FTP_WEIRD_PASS_REPLY; /* FIX */
 +  }
 +  else
 +    result = ftp_state_loggedin(conn);
 +
 +  return result;
 +}
 +
 +
 +static CURLcode ftp_statemach_act(struct connectdata *conn)
 +{
 +  CURLcode result;
 +  curl_socket_t sock = conn->sock[FIRSTSOCKET];
 +  struct Curl_easy *data=conn->data;
 +  int ftpcode;
 +  struct ftp_conn *ftpc = &conn->proto.ftpc;
 +  struct pingpong *pp = &ftpc->pp;
 +  static const char ftpauth[][4]  = { "SSL", "TLS" };
 +  size_t nread = 0;
 +
 +  if(pp->sendleft)
 +    return Curl_pp_flushsend(pp);
 +
 +  result = ftp_readresp(sock, pp, &ftpcode, &nread);
 +  if(result)
 +    return result;
 +
 +  if(ftpcode) {
 +    /* we have now received a full FTP server response */
 +    switch(ftpc->state) {
 +    case FTP_WAIT220:
 +      if(ftpcode == 230)
 +        /* 230 User logged in - already! */
 +        return ftp_state_user_resp(conn, ftpcode, ftpc->state);
 +      else if(ftpcode != 220) {
 +        failf(data, "Got a %03d ftp-server response when 220 was expected",
 +              ftpcode);
 +        return CURLE_WEIRD_SERVER_REPLY;
 +      }
 +
 +      /* We have received a 220 response fine, now we proceed. */
 +#ifdef HAVE_GSSAPI
 +      if(data->set.krb) {
 +        /* If not anonymous login, try a secure login. Note that this
 +           procedure is still BLOCKING. */
 +
 +        Curl_sec_request_prot(conn, "private");
 +        /* We set private first as default, in case the line below fails to
 +           set a valid level */
 +        Curl_sec_request_prot(conn, data->set.str[STRING_KRB_LEVEL]);
 +
 +        if(Curl_sec_login(conn))
 +          infof(data, "Logging in with password in cleartext!\n");
 +        else
 +          infof(data, "Authentication successful\n");
 +      }
 +#endif
 +
 +      if(data->set.use_ssl &&
 +         (!conn->ssl[FIRSTSOCKET].use ||
 +          (conn->bits.proxy_ssl_connected[FIRSTSOCKET] &&
 +           !conn->proxy_ssl[FIRSTSOCKET].use))) {
 +        /* We don't have a SSL/TLS connection yet, but FTPS is
 +           requested. Try a FTPS connection now */
 +
 +        ftpc->count3=0;
 +        switch(data->set.ftpsslauth) {
 +        case CURLFTPAUTH_DEFAULT:
 +        case CURLFTPAUTH_SSL:
 +          ftpc->count2 = 1; /* add one to get next */
 +          ftpc->count1 = 0;
 +          break;
 +        case CURLFTPAUTH_TLS:
 +          ftpc->count2 = -1; /* subtract one to get next */
 +          ftpc->count1 = 1;
 +          break;
 +        default:
 +          failf(data, "unsupported parameter to CURLOPT_FTPSSLAUTH: %d",
 +                (int)data->set.ftpsslauth);
 +          return CURLE_UNKNOWN_OPTION; /* we don't know what to do */
 +        }
 +        PPSENDF(&ftpc->pp, "AUTH %s", ftpauth[ftpc->count1]);
 +        state(conn, FTP_AUTH);
 +      }
 +      else {
 +        result = ftp_state_user(conn);
 +        if(result)
 +          return result;
 +      }
 +
 +      break;
 +
 +    case FTP_AUTH:
 +      /* we have gotten the response to a previous AUTH command */
 +
 +      /* RFC2228 (page 5) says:
 +       *
 +       * If the server is willing to accept the named security mechanism,
 +       * and does not require any security data, it must respond with
 +       * reply code 234/334.
 +       */
 +
 +      if((ftpcode == 234) || (ftpcode == 334)) {
 +        /* Curl_ssl_connect is BLOCKING */
 +        result = Curl_ssl_connect(conn, FIRSTSOCKET);
 +        if(!result) {
 +          conn->bits.ftp_use_data_ssl = FALSE; /* clear-text data */
 +          result = ftp_state_user(conn);
 +        }
 +      }
 +      else if(ftpc->count3 < 1) {
 +        ftpc->count3++;
 +        ftpc->count1 += ftpc->count2; /* get next attempt */
 +        result = Curl_pp_sendf(&ftpc->pp, "AUTH %s", ftpauth[ftpc->count1]);
 +        /* remain in this same state */
 +      }
 +      else {
 +        if(data->set.use_ssl > CURLUSESSL_TRY)
 +          /* we failed and CURLUSESSL_CONTROL or CURLUSESSL_ALL is set */
 +          result = CURLE_USE_SSL_FAILED;
 +        else
 +          /* ignore the failure and continue */
 +          result = ftp_state_user(conn);
 +      }
 +
 +      if(result)
 +        return result;
 +      break;
 +
 +    case FTP_USER:
 +    case FTP_PASS:
 +      result = ftp_state_user_resp(conn, ftpcode, ftpc->state);
 +      break;
 +
 +    case FTP_ACCT:
 +      result = ftp_state_acct_resp(conn, ftpcode);
 +      break;
 +
 +    case FTP_PBSZ:
 +      PPSENDF(&ftpc->pp, "PROT %c",
 +              data->set.use_ssl == CURLUSESSL_CONTROL ? 'C' : 'P');
 +      state(conn, FTP_PROT);
 +
 +      break;
 +
 +    case FTP_PROT:
 +      if(ftpcode/100 == 2)
 +        /* We have enabled SSL for the data connection! */
 +        conn->bits.ftp_use_data_ssl =
 +          (data->set.use_ssl != CURLUSESSL_CONTROL) ? TRUE : FALSE;
 +      /* FTP servers typically responds with 500 if they decide to reject
 +         our 'P' request */
 +      else if(data->set.use_ssl > CURLUSESSL_CONTROL)
 +        /* we failed and bails out */
 +        return CURLE_USE_SSL_FAILED;
 +
 +      if(data->set.ftp_ccc) {
 +        /* CCC - Clear Command Channel
 +         */
 +        PPSENDF(&ftpc->pp, "%s", "CCC");
 +        state(conn, FTP_CCC);
 +      }
 +      else {
 +        result = ftp_state_pwd(conn);
 +        if(result)
 +          return result;
 +      }
 +      break;
 +
 +    case FTP_CCC:
 +      if(ftpcode < 500) {
 +        /* First shut down the SSL layer (note: this call will block) */
 +        result = Curl_ssl_shutdown(conn, FIRSTSOCKET);
 +
 +        if(result) {
 +          failf(conn->data, "Failed to clear the command channel (CCC)");
 +          return result;
 +        }
 +      }
 +
 +      /* Then continue as normal */
 +      result = ftp_state_pwd(conn);
 +      if(result)
 +        return result;
 +      break;
 +
 +    case FTP_PWD:
 +      if(ftpcode == 257) {
 +        char *ptr=&data->state.buffer[4];  /* start on the first letter */
++        const size_t buf_size = CURL_BUFSIZE(data->set.buffer_size);
 +        char *dir;
 +        char *store;
 +
 +        dir = malloc(nread + 1);
 +        if(!dir)
 +          return CURLE_OUT_OF_MEMORY;
 +
 +        /* Reply format is like
 +           257<space>[rubbish]"<directory-name>"<space><commentary> and the
 +           RFC959 says
 +
 +           The directory name can contain any character; embedded
 +           double-quotes should be escaped by double-quotes (the
 +           "quote-doubling" convention).
 +        */
 +
 +        /* scan for the first double-quote for non-standard responses */
-         while(ptr < &data->state.buffer[sizeof(data->state.buffer)]
++        while(ptr < &data->state.buffer[buf_size]
 +              && *ptr != '\n' && *ptr != '\0' && *ptr != '"')
 +          ptr++;
 +
 +        if('\"' == *ptr) {
 +          /* it started good */
 +          ptr++;
 +          for(store = dir; *ptr;) {
 +            if('\"' == *ptr) {
 +              if('\"' == ptr[1]) {
 +                /* "quote-doubling" */
 +                *store = ptr[1];
 +                ptr++;
 +              }
 +              else {
 +                /* end of path */
 +                *store = '\0'; /* zero terminate */
 +                break; /* get out of this loop */
 +              }
 +            }
 +            else
 +              *store = *ptr;
 +            store++;
 +            ptr++;
 +          }
 +
 +          /* If the path name does not look like an absolute path (i.e.: it
 +             does not start with a '/'), we probably need some server-dependent
 +             adjustments. For example, this is the case when connecting to
 +             an OS400 FTP server: this server supports two name syntaxes,
-              the default one being incompatible with standard pathes. In
++             the default one being incompatible with standard paths. In
 +             addition, this server switches automatically to the regular path
 +             syntax when one is encountered in a command: this results in
 +             having an entrypath in the wrong syntax when later used in CWD.
 +               The method used here is to check the server OS: we do it only
 +             if the path name looks strange to minimize overhead on other
 +             systems. */
 +
 +          if(!ftpc->server_os && dir[0] != '/') {
 +
 +            result = Curl_pp_sendf(&ftpc->pp, "%s", "SYST");
 +            if(result) {
 +              free(dir);
 +              return result;
 +            }
 +            Curl_safefree(ftpc->entrypath);
 +            ftpc->entrypath = dir; /* remember this */
 +            infof(data, "Entry path is '%s'\n", ftpc->entrypath);
 +            /* also save it where getinfo can access it: */
 +            data->state.most_recent_ftp_entrypath = ftpc->entrypath;
 +            state(conn, FTP_SYST);
 +            break;
 +          }
 +
 +          Curl_safefree(ftpc->entrypath);
 +          ftpc->entrypath = dir; /* remember this */
 +          infof(data, "Entry path is '%s'\n", ftpc->entrypath);
 +          /* also save it where getinfo can access it: */
 +          data->state.most_recent_ftp_entrypath = ftpc->entrypath;
 +        }
 +        else {
 +          /* couldn't get the path */
 +          free(dir);
 +          infof(data, "Failed to figure out path\n");
 +        }
 +      }
 +      state(conn, FTP_STOP); /* we are done with the CONNECT phase! */
 +      DEBUGF(infof(data, "protocol connect phase DONE\n"));
 +      break;
 +
 +    case FTP_SYST:
 +      if(ftpcode == 215) {
 +        char *ptr=&data->state.buffer[4];  /* start on the first letter */
 +        char *os;
 +        char *store;
 +
 +        os = malloc(nread + 1);
 +        if(!os)
 +          return CURLE_OUT_OF_MEMORY;
 +
 +        /* Reply format is like
 +           215<space><OS-name><space><commentary>
 +        */
 +        while(*ptr == ' ')
 +          ptr++;
 +        for(store = os; *ptr && *ptr != ' ';)
 +          *store++ = *ptr++;
 +        *store = '\0'; /* zero terminate */
 +
 +        /* Check for special servers here. */
 +
 +        if(strcasecompare(os, "OS/400")) {
 +          /* Force OS400 name format 1. */
 +          result = Curl_pp_sendf(&ftpc->pp, "%s", "SITE NAMEFMT 1");
 +          if(result) {
 +            free(os);
 +            return result;
 +          }
 +          /* remember target server OS */
 +          Curl_safefree(ftpc->server_os);
 +          ftpc->server_os = os;
 +          state(conn, FTP_NAMEFMT);
 +          break;
 +        }
-         else {
-           /* Nothing special for the target server. */
-           /* remember target server OS */
-           Curl_safefree(ftpc->server_os);
-           ftpc->server_os = os;
-         }
++        /* Nothing special for the target server. */
++        /* remember target server OS */
++        Curl_safefree(ftpc->server_os);
++        ftpc->server_os = os;
 +      }
 +      else {
 +        /* Cannot identify server OS. Continue anyway and cross fingers. */
 +      }
 +
 +      state(conn, FTP_STOP); /* we are done with the CONNECT phase! */
 +      DEBUGF(infof(data, "protocol connect phase DONE\n"));
 +      break;
 +
 +    case FTP_NAMEFMT:
 +      if(ftpcode == 250) {
 +        /* Name format change successful: reload initial path. */
 +        ftp_state_pwd(conn);
 +        break;
 +      }
 +
 +      state(conn, FTP_STOP); /* we are done with the CONNECT phase! */
 +      DEBUGF(infof(data, "protocol connect phase DONE\n"));
 +      break;
 +
 +    case FTP_QUOTE:
 +    case FTP_POSTQUOTE:
 +    case FTP_RETR_PREQUOTE:
 +    case FTP_STOR_PREQUOTE:
 +      if((ftpcode >= 400) && !ftpc->count2) {
 +        /* failure response code, and not allowed to fail */
 +        failf(conn->data, "QUOT command failed with %03d", ftpcode);
 +        return CURLE_QUOTE_ERROR;
 +      }
 +      result = ftp_state_quote(conn, FALSE, ftpc->state);
 +      if(result)
 +        return result;
 +
 +      break;
 +
 +    case FTP_CWD:
 +      if(ftpcode/100 != 2) {
 +        /* failure to CWD there */
 +        if(conn->data->set.ftp_create_missing_dirs &&
 +           ftpc->count1 && !ftpc->count2) {
 +          /* try making it */
 +          ftpc->count2++; /* counter to prevent CWD-MKD loops */
 +          PPSENDF(&ftpc->pp, "MKD %s", ftpc->dirs[ftpc->count1 - 1]);
 +          state(conn, FTP_MKD);
 +        }
 +        else {
 +          /* return failure */
 +          failf(data, "Server denied you to change to the given directory");
 +          ftpc->cwdfail = TRUE; /* don't remember this path as we failed
 +                                   to enter it */
 +          return CURLE_REMOTE_ACCESS_DENIED;
 +        }
 +      }
 +      else {
 +        /* success */
 +        ftpc->count2=0;
 +        if(++ftpc->count1 <= ftpc->dirdepth) {
 +          /* send next CWD */
 +          PPSENDF(&ftpc->pp, "CWD %s", ftpc->dirs[ftpc->count1 - 1]);
 +        }
 +        else {
 +          result = ftp_state_mdtm(conn);
 +          if(result)
 +            return result;
 +        }
 +      }
 +      break;
 +
 +    case FTP_MKD:
 +      if((ftpcode/100 != 2) && !ftpc->count3--) {
 +        /* failure to MKD the dir */
 +        failf(data, "Failed to MKD dir: %03d", ftpcode);
 +        return CURLE_REMOTE_ACCESS_DENIED;
 +      }
 +      state(conn, FTP_CWD);
 +      /* send CWD */
 +      PPSENDF(&ftpc->pp, "CWD %s", ftpc->dirs[ftpc->count1 - 1]);
 +      break;
 +
 +    case FTP_MDTM:
 +      result = ftp_state_mdtm_resp(conn, ftpcode);
 +      break;
 +
 +    case FTP_TYPE:
 +    case FTP_LIST_TYPE:
 +    case FTP_RETR_TYPE:
 +    case FTP_STOR_TYPE:
 +      result = ftp_state_type_resp(conn, ftpcode, ftpc->state);
 +      break;
 +
 +    case FTP_SIZE:
 +    case FTP_RETR_SIZE:
 +    case FTP_STOR_SIZE:
 +      result = ftp_state_size_resp(conn, ftpcode, ftpc->state);
 +      break;
 +
 +    case FTP_REST:
 +    case FTP_RETR_REST:
 +      result = ftp_state_rest_resp(conn, ftpcode, ftpc->state);
 +      break;
 +
 +    case FTP_PRET:
 +      if(ftpcode != 200) {
 +        /* there only is this one standard OK return code. */
 +        failf(data, "PRET command not accepted: %03d", ftpcode);
 +        return CURLE_FTP_PRET_FAILED;
 +      }
 +      result = ftp_state_use_pasv(conn);
 +      break;
 +
 +    case FTP_PASV:
 +      result = ftp_state_pasv_resp(conn, ftpcode);
 +      break;
 +
 +    case FTP_PORT:
 +      result = ftp_state_port_resp(conn, ftpcode);
 +      break;
 +
 +    case FTP_LIST:
 +    case FTP_RETR:
 +      result = ftp_state_get_resp(conn, ftpcode, ftpc->state);
 +      break;
 +
 +    case FTP_STOR:
 +      result = ftp_state_stor_resp(conn, ftpcode, ftpc->state);
 +      break;
 +
 +    case FTP_QUIT:
 +      /* fallthrough, just stop! */
 +    default:
 +      /* internal error */
 +      state(conn, FTP_STOP);
 +      break;
 +    }
 +  } /* if(ftpcode) */
 +
 +  return result;
 +}
 +
 +
 +/* called repeatedly until done from multi.c */
 +static CURLcode ftp_multi_statemach(struct connectdata *conn,
 +                                    bool *done)
 +{
 +  struct ftp_conn *ftpc = &conn->proto.ftpc;
 +  CURLcode result = Curl_pp_statemach(&ftpc->pp, FALSE);
 +
 +  /* Check for the state outside of the Curl_socket_check() return code checks
 +     since at times we are in fact already in this state when this function
 +     gets called. */
 +  *done = (ftpc->state == FTP_STOP) ? TRUE : FALSE;
 +
 +  return result;
 +}
 +
 +static CURLcode ftp_block_statemach(struct connectdata *conn)
 +{
 +  struct ftp_conn *ftpc = &conn->proto.ftpc;
 +  struct pingpong *pp = &ftpc->pp;
 +  CURLcode result = CURLE_OK;
 +
 +  while(ftpc->state != FTP_STOP) {
 +    result = Curl_pp_statemach(pp, TRUE);
 +    if(result)
 +      break;
 +  }
 +
 +  return result;
 +}
 +
 +/*
 + * ftp_connect() should do everything that is to be considered a part of
 + * the connection phase.
 + *
 + * The variable 'done' points to will be TRUE if the protocol-layer connect
 + * phase is done when this function returns, or FALSE if not.
 + *
 + */
 +static CURLcode ftp_connect(struct connectdata *conn,
 +                                 bool *done) /* see description above */
 +{
 +  CURLcode result;
 +  struct ftp_conn *ftpc = &conn->proto.ftpc;
 +  struct pingpong *pp = &ftpc->pp;
 +
 +  *done = FALSE; /* default to not done yet */
 +
 +  /* We always support persistent connections on ftp */
 +  connkeep(conn, "FTP default");
 +
 +  pp->response_time = RESP_TIMEOUT; /* set default response time-out */
 +  pp->statemach_act = ftp_statemach_act;
 +  pp->endofresp = ftp_endofresp;
 +  pp->conn = conn;
 +
 +  if(conn->handler->flags & PROTOPT_SSL) {
 +    /* BLOCKING */
 +    result = Curl_ssl_connect(conn, FIRSTSOCKET);
 +    if(result)
 +      return result;
 +  }
 +
 +  Curl_pp_init(pp); /* init the generic pingpong data */
 +
 +  /* When we connect, we start in the state where we await the 220
 +     response */
 +  state(conn, FTP_WAIT220);
 +
 +  result = ftp_multi_statemach(conn, done);
 +
 +  return result;
 +}
 +
 +/***********************************************************************
 + *
 + * ftp_done()
 + *
 + * The DONE function. This does what needs to be done after a single DO has
 + * performed.
 + *
 + * Input argument is already checked for validity.
 + */
 +static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
 +                         bool premature)
 +{
 +  struct Curl_easy *data = conn->data;
 +  struct FTP *ftp = data->req.protop;
 +  struct ftp_conn *ftpc = &conn->proto.ftpc;
 +  struct pingpong *pp = &ftpc->pp;
 +  ssize_t nread;
 +  int ftpcode;
 +  CURLcode result = CURLE_OK;
 +  char *path = NULL;
 +  const char *path_to_use = data->state.path;
 +
 +  if(!ftp)
 +    return CURLE_OK;
 +
 +  switch(status) {
 +  case CURLE_BAD_DOWNLOAD_RESUME:
 +  case CURLE_FTP_WEIRD_PASV_REPLY:
 +  case CURLE_FTP_PORT_FAILED:
 +  case CURLE_FTP_ACCEPT_FAILED:
 +  case CURLE_FTP_ACCEPT_TIMEOUT:
 +  case CURLE_FTP_COULDNT_SET_TYPE:
 +  case CURLE_FTP_COULDNT_RETR_FILE:
 +  case CURLE_PARTIAL_FILE:
 +  case CURLE_UPLOAD_FAILED:
 +  case CURLE_REMOTE_ACCESS_DENIED:
 +  case CURLE_FILESIZE_EXCEEDED:
 +  case CURLE_REMOTE_FILE_NOT_FOUND:
 +  case CURLE_WRITE_ERROR:
 +    /* the connection stays alive fine even though this happened */
 +    /* fall-through */
 +  case CURLE_OK: /* doesn't affect the control connection's status */
 +    if(!premature)
 +      break;
 +
 +    /* until we cope better with prematurely ended requests, let them
 +     * fallback as if in complete failure */
++    /* FALLTHROUGH */
 +  default:       /* by default, an error means the control connection is
 +                    wedged and should not be used anymore */
 +    ftpc->ctl_valid = FALSE;
 +    ftpc->cwdfail = TRUE; /* set this TRUE to prevent us to remember the
 +                             current path, as this connection is going */
 +    connclose(conn, "FTP ended with bad error code");
 +    result = status;      /* use the already set error code */
 +    break;
 +  }
 +
 +  /* now store a copy of the directory we are in */
 +  free(ftpc->prevpath);
 +
 +  if(data->set.wildcardmatch) {
 +    if(data->set.chunk_end && ftpc->file) {
 +      data->set.chunk_end(data->wildcard.customptr);
 +    }
 +    ftpc->known_filesize = -1;
 +  }
 +
 +  if(!result)
 +    /* get the "raw" path */
 +    result = Curl_urldecode(data, path_to_use, 0, &path, NULL, FALSE);
 +  if(result) {
 +    /* We can limp along anyway (and should try to since we may already be in
 +     * the error path) */
 +    ftpc->ctl_valid = FALSE; /* mark control connection as bad */
 +    connclose(conn, "FTP: out of memory!"); /* mark for connection closure */
 +    ftpc->prevpath = NULL; /* no path remembering */
 +  }
 +  else {
 +    size_t flen = ftpc->file?strlen(ftpc->file):0; /* file is "raw" already */
 +    size_t dlen = strlen(path)-flen;
 +    if(!ftpc->cwdfail) {
 +      if(dlen && (data->set.ftp_filemethod != FTPFILE_NOCWD)) {
 +        ftpc->prevpath = path;
 +        if(flen)
 +          /* if 'path' is not the whole string */
 +          ftpc->prevpath[dlen]=0; /* terminate */
 +      }
 +      else {
 +        /* we never changed dir */
 +        ftpc->prevpath=strdup("");
 +        free(path);
 +      }
 +      if(ftpc->prevpath)
 +        infof(data, "Remembering we are in dir \"%s\"\n", ftpc->prevpath);
 +    }
 +    else {
 +      ftpc->prevpath = NULL; /* no path */
 +      free(path);
 +    }
 +  }
 +  /* free the dir tree and file parts */
 +  freedirs(ftpc);
 +
 +  /* shut down the socket to inform the server we're done */
 +
 +#ifdef _WIN32_WCE
 +  shutdown(conn->sock[SECONDARYSOCKET], 2);  /* SD_BOTH */
 +#endif
 +
 +  if(conn->sock[SECONDARYSOCKET] != CURL_SOCKET_BAD) {
 +    if(!result && ftpc->dont_check && data->req.maxdownload > 0) {
 +      /* partial download completed */
 +      result = Curl_pp_sendf(pp, "%s", "ABOR");
 +      if(result) {
 +        failf(data, "Failure sending ABOR command: %s",
 +              curl_easy_strerror(result));
 +        ftpc->ctl_valid = FALSE; /* mark control connection as bad */
 +        connclose(conn, "ABOR command failed"); /* connection closure */
 +      }
 +    }
 +
 +    if(conn->ssl[SECONDARYSOCKET].use) {
 +      /* The secondary socket is using SSL so we must close down that part
 +         first before we close the socket for real */
 +      Curl_ssl_close(conn, SECONDARYSOCKET);
 +
 +      /* Note that we keep "use" set to TRUE since that (next) connection is
 +         still requested to use SSL */
 +    }
 +    close_secondarysocket(conn);
 +  }
 +
 +  if(!result && (ftp->transfer == FTPTRANSFER_BODY) && ftpc->ctl_valid &&
 +     pp->pending_resp && !premature) {
 +    /*
 +     * Let's see what the server says about the transfer we just performed,
 +     * but lower the timeout as sometimes this connection has died while the
 +     * data has been transferred. This happens when doing through NATs etc that
 +     * abandon old silent connections.
 +     */
 +    long old_time = pp->response_time;
 +
 +    pp->response_time = 60*1000; /* give it only a minute for now */
 +    pp->response = Curl_tvnow(); /* timeout relative now */
 +
 +    result = Curl_GetFTPResponse(&nread, conn, &ftpcode);
 +
 +    pp->response_time = old_time; /* set this back to previous value */
 +
 +    if(!nread && (CURLE_OPERATION_TIMEDOUT == result)) {
 +      failf(data, "control connection looks dead");
 +      ftpc->ctl_valid = FALSE; /* mark control connection as bad */
 +      connclose(conn, "Timeout or similar in FTP DONE operation"); /* close */
 +    }
 +
 +    if(result)
 +      return result;
 +
 +    if(ftpc->dont_check && data->req.maxdownload > 0) {
 +      /* we have just sent ABOR and there is no reliable way to check if it was
 +       * successful or not; we have to close the connection now */
 +      infof(data, "partial download completed, closing connection\n");
 +      connclose(conn, "Partial download with no ability to check");
 +      return result;
 +    }
 +
 +    if(!ftpc->dont_check) {
 +      /* 226 Transfer complete, 250 Requested file action okay, completed. */
 +      if((ftpcode != 226) && (ftpcode != 250)) {
 +        failf(data, "server did not report OK, got %d", ftpcode);
 +        result = CURLE_PARTIAL_FILE;
 +      }
 +    }
 +  }
 +
 +  if(result || premature)
 +    /* the response code from the transfer showed an error already so no
 +       use checking further */
 +    ;
 +  else if(data->set.upload) {
 +    if((-1 != data->state.infilesize) &&
 +       (data->state.infilesize != *ftp->bytecountp) &&
 +       !data->set.crlf &&
 +       (ftp->transfer == FTPTRANSFER_BODY)) {
 +      failf(data, "Uploaded unaligned file size (%" CURL_FORMAT_CURL_OFF_T
 +            " out of %" CURL_FORMAT_CURL_OFF_T " bytes)",
 +            *ftp->bytecountp, data->state.infilesize);
 +      result = CURLE_PARTIAL_FILE;
 +    }
 +  }
 +  else {
 +    if((-1 != data->req.size) &&
 +       (data->req.size != *ftp->bytecountp) &&
 +#ifdef CURL_DO_LINEEND_CONV
 +       /* Most FTP servers don't adjust their file SIZE response for CRLFs, so
 +        * we'll check to see if the discrepancy can be explained by the number
 +        * of CRLFs we've changed to LFs.
 +        */
 +       ((data->req.size + data->state.crlf_conversions) !=
 +        *ftp->bytecountp) &&
 +#endif /* CURL_DO_LINEEND_CONV */
 +       (data->req.maxdownload != *ftp->bytecountp)) {
 +      failf(data, "Received only partial file: %" CURL_FORMAT_CURL_OFF_T
 +            " bytes", *ftp->bytecountp);
 +      result = CURLE_PARTIAL_FILE;
 +    }
 +    else if(!ftpc->dont_check &&
 +            !*ftp->bytecountp &&
 +            (data->req.size>0)) {
 +      failf(data, "No data was received!");
 +      result = CURLE_FTP_COULDNT_RETR_FILE;
 +    }
 +  }
 +
 +  /* clear these for next connection */
 +  ftp->transfer = FTPTRANSFER_BODY;
 +  ftpc->dont_check = FALSE;
 +
 +  /* Send any post-transfer QUOTE strings? */
 +  if(!status && !result && !premature && data->set.postquote)
 +    result = ftp_sendquote(conn, data->set.postquote);
 +
 +  return result;
 +}
 +
 +/***********************************************************************
 + *
 + * ftp_sendquote()
 + *
 + * Where a 'quote' means a list of custom commands to send to the server.
 + * The quote list is passed as an argument.
 + *
 + * BLOCKING
 + */
 +
 +static
 +CURLcode ftp_sendquote(struct connectdata *conn, struct curl_slist *quote)
 +{
 +  struct curl_slist *item;
 +  ssize_t nread;
 +  int ftpcode;
 +  CURLcode result;
 +  struct ftp_conn *ftpc = &conn->proto.ftpc;
 +  struct pingpong *pp = &ftpc->pp;
 +
 +  item = quote;
 +  while(item) {
 +    if(item->data) {
 +      char *cmd = item->data;
 +      bool acceptfail = FALSE;
 +
 +      /* if a command starts with an asterisk, which a legal FTP command never
 +         can, the command will be allowed to fail without it causing any
 +         aborts or cancels etc. It will cause libcurl to act as if the command
 +         is successful, whatever the server reponds. */
 +
 +      if(cmd[0] == '*') {
 +        cmd++;
 +        acceptfail = TRUE;
 +      }
 +
 +      PPSENDF(&conn->proto.ftpc.pp, "%s", cmd);
 +
 +      pp->response = Curl_tvnow(); /* timeout relative now */
 +
 +      result = Curl_GetFTPResponse(&nread, conn, &ftpcode);
 +      if(result)
 +        return result;
 +
 +      if(!acceptfail && (ftpcode >= 400)) {
 +        failf(conn->data, "QUOT string not accepted: %s", cmd);
 +        return CURLE_QUOTE_ERROR;
 +      }
 +    }
 +
 +    item = item->next;
 +  }
 +
 +  return CURLE_OK;
 +}
 +
 +/***********************************************************************
 + *
 + * ftp_need_type()
 + *
 + * Returns TRUE if we in the current situation should send TYPE
 + */
 +static int ftp_need_type(struct connectdata *conn,
 +                         bool ascii_wanted)
 +{
 +  return conn->proto.ftpc.transfertype != (ascii_wanted?'A':'I');
 +}
 +
 +/***********************************************************************
 + *
 + * ftp_nb_type()
 + *
 + * Set TYPE. We only deal with ASCII or BINARY so this function
 + * sets one of them.
 + * If the transfer type is not sent, simulate on OK response in newstate
 + */
 +static CURLcode ftp_nb_type(struct connectdata *conn,
 +                            bool ascii, ftpstate newstate)
 +{
 +  struct ftp_conn *ftpc = &conn->proto.ftpc;
 +  CURLcode result;
 +  char want = (char)(ascii?'A':'I');
 +
 +  if(ftpc->transfertype == want) {
 +    state(conn, newstate);
 +    return ftp_state_type_resp(conn, 200, newstate);
 +  }
 +
 +  PPSENDF(&ftpc->pp, "TYPE %c", want);
 +  state(conn, newstate);
 +
 +  /* keep track of our current transfer type */
 +  ftpc->transfertype = want;
 +  return CURLE_OK;
 +}
 +
 +/***************************************************************************
 + *
 + * ftp_pasv_verbose()
 + *
 + * This function only outputs some informationals about this second connection
 + * when we've issued a PASV command before and thus we have connected to a
 + * possibly new IP address.
 + *
 + */
 +#ifndef CURL_DISABLE_VERBOSE_STRINGS
 +static void
 +ftp_pasv_verbose(struct connectdata *conn,
 +                 Curl_addrinfo *ai,
 +                 char *newhost, /* ascii version */
 +                 int port)
 +{
 +  char buf[256];
 +  Curl_printable_address(ai, buf, sizeof(buf));
 +  infof(conn->data, "Connecting to %s (%s) port %d\n", newhost, buf, port);
 +}
 +#endif
 +
 +/*
 +  Check if this is a range download, and if so, set the internal variables
 +  properly.
 + */
 +
 +static CURLcode ftp_range(struct connectdata *conn)
 +{
 +  curl_off_t from, to;
 +  char *ptr;
 +  char *ptr2;
 +  struct Curl_easy *data = conn->data;
 +  struct ftp_conn *ftpc = &conn->proto.ftpc;
 +
 +  if(data->state.use_range && data->state.range) {
 +    from=curlx_strtoofft(data->state.range, &ptr, 0);
 +    while(*ptr && (ISSPACE(*ptr) || (*ptr=='-')))
 +      ptr++;
 +    to=curlx_strtoofft(ptr, &ptr2, 0);
 +    if(ptr == ptr2) {
 +      /* we didn't get any digit */
 +      to=-1;
 +    }
 +    if((-1 == to) && (from>=0)) {
 +      /* X - */
 +      data->state.resume_from = from;
 +      DEBUGF(infof(conn->data, "FTP RANGE %" CURL_FORMAT_CURL_OFF_T
 +                   " to end of file\n", from));
 +    }
 +    else if(from < 0) {
 +      /* -Y */
 +      data->req.maxdownload = -from;
 +      data->state.resume_from = from;
 +      DEBUGF(infof(conn->data, "FTP RANGE the last %" CURL_FORMAT_CURL_OFF_T
 +                   " bytes\n", -from));
 +    }
 +    else {
 +      /* X-Y */
 +      data->req.maxdownload = (to-from)+1; /* include last byte */
 +      data->state.resume_from = from;
 +      DEBUGF(infof(conn->data, "FTP RANGE from %" CURL_FORMAT_CURL_OFF_T
 +                   " getting %" CURL_FORMAT_CURL_OFF_T " bytes\n",
 +                   from, data->req.maxdownload));
 +    }
 +    DEBUGF(infof(conn->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));
-     ftpc->dont_check = TRUE; /* dont check for successful transfer */
++    ftpc->dont_check = TRUE; /* don't check for successful transfer */
 +  }
 +  else
 +    data->req.maxdownload = -1;
 +  return CURLE_OK;
 +}
 +
 +
 +/*
 + * ftp_do_more()
 + *
 + * This function shall be called when the second FTP (data) connection is
 + * connected.
 + *
 + * 'complete' can return 0 for incomplete, 1 for done and -1 for go back
 + * (which basically is only for when PASV is being sent to retry a failed
 + * EPSV).
 + */
 +
 +static CURLcode ftp_do_more(struct connectdata *conn, int *completep)
 +{
 +  struct Curl_easy *data=conn->data;
 +  struct ftp_conn *ftpc = &conn->proto.ftpc;
 +  CURLcode result = CURLE_OK;
 +  bool connected = FALSE;
 +  bool complete = FALSE;
 +
 +  /* the ftp struct is inited in ftp_connect() */
 +  struct FTP *ftp = data->req.protop;
 +
 +  /* if the second connection isn't done yet, wait for it */
 +  if(!conn->bits.tcpconnect[SECONDARYSOCKET]) {
 +    if(conn->tunnel_state[SECONDARYSOCKET] == TUNNEL_CONNECT) {
 +      /* As we're in TUNNEL_CONNECT state now, we know the proxy name and port
 +         aren't used so we blank their arguments. TODO: make this nicer */
 +      result = Curl_proxyCONNECT(conn, SECONDARYSOCKET, NULL, 0, FALSE);
 +
 +      return result;
 +    }
 +
 +    result = Curl_is_connected(conn, SECONDARYSOCKET, &connected);
 +
 +    /* Ready to do more? */
 +    if(connected) {
 +      DEBUGF(infof(data, "DO-MORE connected phase starts\n"));
 +    }
 +    else {
 +      if(result && (ftpc->count1 == 0)) {
 +        *completep = -1; /* go back to DOING please */
 +        /* this is a EPSV connect failing, try PASV instead */
 +        return ftp_epsv_disable(conn);
 +      }
 +      return result;
 +    }
 +  }
 +
 +  result = Curl_proxy_connect(conn, SECONDARYSOCKET);
 +  if(result)
 +    return result;
 +
 +  if(CONNECT_SECONDARYSOCKET_PROXY_SSL())
 +    return result;
 +
 +  if(conn->bits.tunnel_proxy && conn->bits.httpproxy &&
 +     conn->tunnel_state[SECONDARYSOCKET] != TUNNEL_COMPLETE)
 +    return result;
 +
 +
 +  if(ftpc->state) {
 +    /* already in a state so skip the initial commands.
 +       They are only done to kickstart the do_more state */
 +    result = ftp_multi_statemach(conn, &complete);
 +
 +    *completep = (int)complete;
 +
 +    /* if we got an error or if we don't wait for a data connection return
 +       immediately */
 +    if(result || (ftpc->wait_data_conn != TRUE))
 +      return result;
 +
 +    if(ftpc->wait_data_conn)
 +      /* if we reach the end of the FTP state machine here, *complete will be
 +         TRUE but so is ftpc->wait_data_conn, which says we need to wait for
 +         the data connection and therefore we're not actually complete */
 +      *completep = 0;
 +  }
 +
 +  if(ftp->transfer <= FTPTRANSFER_INFO) {
 +    /* a transfer is about to take place, or if not a file name was given
 +       so we'll do a SIZE on it later and then we need the right TYPE first */
 +
 +    if(ftpc->wait_data_conn == TRUE) {
 +      bool serv_conned;
 +
 +      result = ReceivedServerConnect(conn, &serv_conned);
 +      if(result)
 +        return result; /* Failed to accept data connection */
 +
 +      if(serv_conned) {
 +        /* It looks data connection is established */
 +        result = AcceptServerConnect(conn);
 +        ftpc->wait_data_conn = FALSE;
 +        if(!result)
 +          result = InitiateTransfer(conn);
 +
 +        if(result)
 +          return result;
 +
 +        *completep = 1; /* this state is now complete when the server has
 +                           connected back to us */
 +      }
 +    }
 +    else if(data->set.upload) {
 +      result = ftp_nb_type(conn, data->set.prefer_ascii, FTP_STOR_TYPE);
 +      if(result)
 +        return result;
 +
 +      result = ftp_multi_statemach(conn, &complete);
 +      if(ftpc->wait_data_conn)
 +        /* if we reach the end of the FTP state machine here, *complete will be
 +           TRUE but so is ftpc->wait_data_conn, which says we need to wait for
 +           the data connection and therefore we're not actually complete */
 +        *completep = 0;
 +      else
 +        *completep = (int)complete;
 +    }
 +    else {
 +      /* download */
 +      ftp->downloadsize = -1; /* unknown as of yet */
 +
 +      result = ftp_range(conn);
 +      if(result)
 +        ;
 +      else if(data->set.ftp_list_only || !ftpc->file) {
 +        /* The specified path ends with a slash, and therefore we think this
 +           is a directory that is requested, use LIST. But before that we
 +           need to set ASCII transfer mode. */
 +
 +        /* But only if a body transfer was requested. */
 +        if(ftp->transfer == FTPTRANSFER_BODY) {
 +          result = ftp_nb_type(conn, TRUE, FTP_LIST_TYPE);
 +          if(result)
 +            return result;
 +        }
 +        /* otherwise just fall through */
 +      }
 +      else {
 +        result = ftp_nb_type(conn, data->set.prefer_ascii, FTP_RETR_TYPE);
 +        if(result)
 +          return result;
 +      }
 +
 +      result = ftp_multi_statemach(conn, &complete);
 +      *completep = (int)complete;
 +    }
 +    return result;
 +  }
 +
 +  if(!result && (ftp->transfer != FTPTRANSFER_BODY))
 +    /* no data to transfer. FIX: it feels like a kludge to have this here
 +       too! */
 +    Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
 +
 +  if(!ftpc->wait_data_conn) {
 +    /* no waiting for the data connection so this is now complete */
 +    *completep = 1;
 +    DEBUGF(infof(data, "DO-MORE phase ends with %d\n", (int)result));
 +  }
 +
 +  return result;
 +}
 +
 +
 +
 +/***********************************************************************
 + *
 + * ftp_perform()
 + *
 + * This is the actual DO function for FTP. Get a file/directory according to
 + * the options previously setup.
 + */
 +
 +static
 +CURLcode ftp_perform(struct connectdata *conn,
 +                     bool *connected,  /* connect status after PASV / PORT */
 +                     bool *dophase_done)
 +{
 +  /* this is FTP and no proxy */
 +  CURLcode result=CURLE_OK;
 +
 +  DEBUGF(infof(conn->data, "DO phase starts\n"));
 +
 +  if(conn->data->set.opt_no_body) {
 +    /* requested no body means no transfer... */
 +    struct FTP *ftp = conn->data->req.protop;
 +    ftp->transfer = FTPTRANSFER_INFO;
 +  }
 +
 +  *dophase_done = FALSE; /* not done yet */
 +
 +  /* start the first command in the DO phase */
 +  result = ftp_state_quote(conn, TRUE, FTP_QUOTE);
 +  if(result)
 +    return result;
 +
 +  /* run the state-machine */
 +  result = ftp_multi_statemach(conn, dophase_done);
 +
 +  *connected = conn->bits.tcpconnect[SECONDARYSOCKET];
 +
 +  infof(conn->data, "ftp_perform ends with SECONDARY: %d\n", *connected);
 +
 +  if(*dophase_done) {
 +    DEBUGF(infof(conn->data, "DO phase is complete1\n"));
 +  }
 +
 +  return result;
 +}
 +
 +static void wc_data_dtor(void *ptr)
 +{
 +  struct ftp_wc_tmpdata *tmp = ptr;
 +  if(tmp)
 +    Curl_ftp_parselist_data_free(&tmp->parser);
 +  free(tmp);
 +}
 +
 +static CURLcode init_wc_data(struct connectdata *conn)
 +{
 +  char *last_slash;
 +  char *path = conn->data->state.path;
 +  struct WildcardData *wildcard = &(conn->data->wildcard);
 +  CURLcode result = CURLE_OK;
 +  struct ftp_wc_tmpdata *ftp_tmp;
 +
 +  last_slash = strrchr(conn->data->state.path, '/');
 +  if(last_slash) {
 +    last_slash++;
 +    if(last_slash[0] == '\0') {
 +      wildcard->state = CURLWC_CLEAN;
 +      result = ftp_parse_url_path(conn);
 +      return result;
 +    }
-     else {
-       wildcard->pattern = strdup(last_slash);
-       if(!wildcard->pattern)
-         return CURLE_OUT_OF_MEMORY;
-       last_slash[0] = '\0'; /* cut file from path */
-     }
++    wildcard->pattern = strdup(last_slash);
++    if(!wildcard->pattern)
++      return CURLE_OUT_OF_MEMORY;
++    last_slash[0] = '\0'; /* cut file from path */
 +  }
 +  else { /* there is only 'wildcard pattern' or nothing */
 +    if(path[0]) {
 +      wildcard->pattern = strdup(path);
 +      if(!wildcard->pattern)
 +        return CURLE_OUT_OF_MEMORY;
 +      path[0] = '\0';
 +    }
 +    else { /* only list */
 +      wildcard->state = CURLWC_CLEAN;
 +      result = ftp_parse_url_path(conn);
 +      return result;
 +    }
 +  }
 +
 +  /* program continues only if URL is not ending with slash, allocate needed
 +     resources for wildcard transfer */
 +
 +  /* allocate ftp protocol specific temporary wildcard data */
 +  ftp_tmp = calloc(1, sizeof(struct ftp_wc_tmpdata));
 +  if(!ftp_tmp) {
 +    Curl_safefree(wildcard->pattern);
 +    return CURLE_OUT_OF_MEMORY;
 +  }
 +
 +  /* INITIALIZE parselist structure */
 +  ftp_tmp->parser = Curl_ftp_parselist_data_alloc();
 +  if(!ftp_tmp->parser) {
 +    Curl_safefree(wildcard->pattern);
 +    free(ftp_tmp);
 +    return CURLE_OUT_OF_MEMORY;
 +  }
 +
 +  wildcard->tmp = ftp_tmp; /* put it to the WildcardData tmp pointer */
 +  wildcard->tmp_dtor = wc_data_dtor;
 +
 +  /* wildcard does not support NOCWD option (assert it?) */
 +  if(conn->data->set.ftp_filemethod == FTPFILE_NOCWD)
 +    conn->data->set.ftp_filemethod = FTPFILE_MULTICWD;
 +
 +  /* try to parse ftp url */
 +  result = ftp_parse_url_path(conn);
 +  if(result) {
 +    Curl_safefree(wildcard->pattern);
 +    wildcard->tmp_dtor(wildcard->tmp);
 +    wildcard->tmp_dtor = ZERO_NULL;
 +    wildcard->tmp = NULL;
 +    return result;
 +  }
 +
 +  wildcard->path = strdup(conn->data->state.path);
 +  if(!wildcard->path) {
 +    Curl_safefree(wildcard->pattern);
 +    wildcard->tmp_dtor(wildcard->tmp);
 +    wildcard->tmp_dtor = ZERO_NULL;
 +    wildcard->tmp = NULL;
 +    return CURLE_OUT_OF_MEMORY;
 +  }
 +
 +  /* backup old write_function */
 +  ftp_tmp->backup.write_function = conn->data->set.fwrite_func;
 +  /* parsing write function */
 +  conn->data->set.fwrite_func = Curl_ftp_parselist;
 +  /* backup old file descriptor */
 +  ftp_tmp->backup.file_descriptor = conn->data->set.out;
 +  /* let the writefunc callback know what curl pointer is working with */
 +  conn->data->set.out = conn;
 +
 +  infof(conn->data, "Wildcard - Parsing started\n");
 +  return CURLE_OK;
 +}
 +
 +/* This is called recursively */
 +static CURLcode wc_statemach(struct connectdata *conn)
 +{
 +  struct WildcardData * const wildcard = &(conn->data->wildcard);
 +  CURLcode result = CURLE_OK;
 +
 +  switch(wildcard->state) {
 +  case CURLWC_INIT:
 +    result = init_wc_data(conn);
 +    if(wildcard->state == CURLWC_CLEAN)
 +      /* only listing! */
 +      break;
-     else
-       wildcard->state = result ? CURLWC_ERROR : CURLWC_MATCHING;
++    wildcard->state = result ? CURLWC_ERROR : CURLWC_MATCHING;
 +    break;
 +
 +  case CURLWC_MATCHING: {
 +    /* In this state is LIST response successfully parsed, so lets restore
 +       previous WRITEFUNCTION callback and WRITEDATA pointer */
 +    struct ftp_wc_tmpdata *ftp_tmp = wildcard->tmp;
 +    conn->data->set.fwrite_func = ftp_tmp->backup.write_function;
 +    conn->data->set.out = ftp_tmp->backup.file_descriptor;
 +    ftp_tmp->backup.write_function = ZERO_NULL;
 +    ftp_tmp->backup.file_descriptor = NULL;
 +    wildcard->state = CURLWC_DOWNLOADING;
 +
 +    if(Curl_ftp_parselist_geterror(ftp_tmp->parser)) {
 +      /* error found in LIST parsing */
 +      wildcard->state = CURLWC_CLEAN;
 +      return wc_statemach(conn);
 +    }
-     else if(wildcard->filelist->size == 0) {
++    if(wildcard->filelist.size == 0) {
 +      /* no corresponding file */
 +      wildcard->state = CURLWC_CLEAN;
 +      return CURLE_REMOTE_FILE_NOT_FOUND;
 +    }
 +    return wc_statemach(conn);
 +  }
 +
 +  case CURLWC_DOWNLOADING: {
 +    /* filelist has at least one file, lets get first one */
 +    struct ftp_conn *ftpc = &conn->proto.ftpc;
-     struct curl_fileinfo *finfo = wildcard->filelist->head->ptr;
++    struct curl_fileinfo *finfo = wildcard->filelist.head->ptr;
 +
 +    char *tmp_path = aprintf("%s%s", wildcard->path, finfo->filename);
 +    if(!tmp_path)
 +      return CURLE_OUT_OF_MEMORY;
 +
 +    /* switch default "state.pathbuffer" and tmp_path, good to see
 +       ftp_parse_url_path function to understand this trick */
 +    Curl_safefree(conn->data->state.pathbuffer);
 +    conn->data->state.pathbuffer = tmp_path;
 +    conn->data->state.path = tmp_path;
 +
 +    infof(conn->data, "Wildcard - START of \"%s\"\n", finfo->filename);
 +    if(conn->data->set.chunk_bgn) {
 +      long userresponse = conn->data->set.chunk_bgn(
-           finfo, wildcard->customptr, (int)wildcard->filelist->size);
++        finfo, wildcard->customptr, (int)wildcard->filelist.size);
 +      switch(userresponse) {
 +      case CURL_CHUNK_BGN_FUNC_SKIP:
 +        infof(conn->data, "Wildcard - \"%s\" skipped by user\n",
 +              finfo->filename);
 +        wildcard->state = CURLWC_SKIP;
 +        return wc_statemach(conn);
 +      case CURL_CHUNK_BGN_FUNC_FAIL:
 +        return CURLE_CHUNK_FAILED;
 +      }
 +    }
 +
 +    if(finfo->filetype != CURLFILETYPE_FILE) {
 +      wildcard->state = CURLWC_SKIP;
 +      return wc_statemach(conn);
 +    }
 +
 +    if(finfo->flags & CURLFINFOFLAG_KNOWN_SIZE)
 +      ftpc->known_filesize = finfo->size;
 +
 +    result = ftp_parse_url_path(conn);
 +    if(result)
 +      return result;
 +
 +    /* we don't need the Curl_fileinfo of first file anymore */
-     Curl_llist_remove(wildcard->filelist, wildcard->filelist->head, NULL);
++    Curl_llist_remove(&wildcard->filelist, wildcard->filelist.head, NULL);
 +
-     if(wildcard->filelist->size == 0) { /* remains only one file to down. */
++    if(wildcard->filelist.size == 0) { /* remains only one file to down. */
 +      wildcard->state = CURLWC_CLEAN;
 +      /* after that will be ftp_do called once again and no transfer
 +         will be done because of CURLWC_CLEAN state */
 +      return CURLE_OK;
 +    }
 +  } break;
 +
 +  case CURLWC_SKIP: {
 +    if(conn->data->set.chunk_end)
 +      conn->data->set.chunk_end(conn->data->wildcard.customptr);
-     Curl_llist_remove(wildcard->filelist, wildcard->filelist->head, NULL);
-     wildcard->state = (wildcard->filelist->size == 0) ?
++    Curl_llist_remove(&wildcard->filelist, wildcard->filelist.head, NULL);
++    wildcard->state = (wildcard->filelist.size == 0) ?
 +                      CURLWC_CLEAN : CURLWC_DOWNLOADING;
 +    return wc_statemach(conn);
 +  }
 +
 +  case CURLWC_CLEAN: {
 +    struct ftp_wc_tmpdata *ftp_tmp = wildcard->tmp;
 +    result = CURLE_OK;
 +    if(ftp_tmp)
 +      result = Curl_ftp_parselist_geterror(ftp_tmp->parser);
 +
 +    wildcard->state = result ? CURLWC_ERROR : CURLWC_DONE;
 +  } break;
 +
 +  case CURLWC_DONE:
 +  case CURLWC_ERROR:
++  case CURLWC_CLEAR:
 +    break;
 +  }
 +
 +  return result;
 +}
 +
 +/***********************************************************************
 + *
 + * ftp_do()
 + *
 + * This function is registered as 'curl_do' function. It decodes the path
 + * parts etc as a wrapper to the actual DO function (ftp_perform).
 + *
 + * The input argument is already checked for validity.
 + */
 +static CURLcode ftp_do(struct connectdata *conn, bool *done)
 +{
 +  CURLcode result = CURLE_OK;
 +  struct ftp_conn *ftpc = &conn->proto.ftpc;
 +
 +  *done = FALSE; /* default to false */
 +  ftpc->wait_data_conn = FALSE; /* default to no such wait */
 +
 +  if(conn->data->set.wildcardmatch) {
 +    result = wc_statemach(conn);
 +    if(conn->data->wildcard.state == CURLWC_SKIP ||
 +      conn->data->wildcard.state == CURLWC_DONE) {
 +      /* do not call ftp_regular_transfer */
 +      return CURLE_OK;
 +    }
 +    if(result) /* error, loop or skipping the file */
 +      return result;
 +  }
 +  else { /* no wildcard FSM needed */
 +    result = ftp_parse_url_path(conn);
 +    if(result)
 +      return result;
 +  }
 +
 +  result = ftp_regular_transfer(conn, done);
 +
 +  return result;
 +}
 +
 +
 +CURLcode Curl_ftpsend(struct connectdata *conn, const char *cmd)
 +{
 +  ssize_t bytes_written;
 +#define SBUF_SIZE 1024
 +  char s[SBUF_SIZE];
 +  size_t write_len;
 +  char *sptr=s;
 +  CURLcode result = CURLE_OK;
 +#ifdef HAVE_GSSAPI
 +  enum protection_level data_sec = conn->data_prot;
 +#endif
 +
 +  write_len = strlen(cmd);
 +  if(write_len > (sizeof(s) -3))
 +    return CURLE_BAD_FUNCTION_ARGUMENT;
 +
 +  strcpy(&s[write_len], "\r\n"); /* append a trailing CRLF */
 +  write_len +=2;
 +
 +  bytes_written=0;
 +
 +  result = Curl_convert_to_network(conn->data, s, write_len);
 +  /* Curl_convert_to_network calls failf if unsuccessful */
 +  if(result)
 +    return result;
 +
 +  for(;;) {
 +#ifdef HAVE_GSSAPI
 +    conn->data_prot = PROT_CMD;
 +#endif
 +    result = Curl_write(conn, conn->sock[FIRSTSOCKET], sptr, write_len,
 +                        &bytes_written);
 +#ifdef HAVE_GSSAPI
 +    DEBUGASSERT(data_sec > PROT_NONE && data_sec < PROT_LAST);
 +    conn->data_prot = data_sec;
 +#endif
 +
 +    if(result)
 +      break;
 +
 +    if(conn->data->set.verbose)
 +      Curl_debug(conn->data, CURLINFO_HEADER_OUT,
 +                 sptr, (size_t)bytes_written, conn);
 +
 +    if(bytes_written != (ssize_t)write_len) {
 +      write_len -= bytes_written;
 +      sptr += bytes_written;
 +    }
 +    else
 +      break;
 +  }
 +
 +  return result;
 +}
 +
 +/***********************************************************************
 + *
 + * ftp_quit()
 + *
 + * This should be called before calling sclose() on an ftp control connection
 + * (not data connections). We should then wait for the response from the
 + * server before returning. The calling code should then try to close the
 + * connection.
 + *
 + */
 +static CURLcode ftp_quit(struct connectdata *conn)
 +{
 +  CURLcode result = CURLE_OK;
 +
 +  if(conn->proto.ftpc.ctl_valid) {
 +    result = Curl_pp_sendf(&conn->proto.ftpc.pp, "%s", "QUIT");
 +    if(result) {
 +      failf(conn->data, "Failure sending QUIT command: %s",
 +            curl_easy_strerror(result));
 +      conn->proto.ftpc.ctl_valid = FALSE; /* mark control connection as bad */
 +      connclose(conn, "QUIT command failed"); /* mark for connection closure */
 +      state(conn, FTP_STOP);
 +      return result;
 +    }
 +
 +    state(conn, FTP_QUIT);
 +
 +    result = ftp_block_statemach(conn);
 +  }
 +
 +  return result;
 +}
 +
 +/***********************************************************************
 + *
 + * ftp_disconnect()
 + *
 + * Disconnect from an FTP server. Cleanup protocol-specific per-connection
 + * resources. BLOCKING.
 + */
 +static CURLcode ftp_disconnect(struct connectdata *conn, bool dead_connection)
 +{
 +  struct ftp_conn *ftpc= &conn->proto.ftpc;
 +  struct pingpong *pp = &ftpc->pp;
 +
 +  /* We cannot send quit unconditionally. If this connection is stale or
 +     bad in any way, sending quit and waiting around here will make the
 +     disconnect wait in vain and cause more problems than we need to.
 +
 +     ftp_quit() will check the state of ftp->ctl_valid. If it's ok it
 +     will try to send the QUIT command, otherwise it will just return.
 +  */
 +  if(dead_connection)
 +    ftpc->ctl_valid = FALSE;
 +
 +  /* The FTP session may or may not have been allocated/setup at this point! */
 +  (void)ftp_quit(conn); /* ignore errors on the QUIT */
 +
 +  if(ftpc->entrypath) {
 +    struct Curl_easy *data = conn->data;
 +    if(data->state.most_recent_ftp_entrypath == ftpc->entrypath) {
 +      data->state.most_recent_ftp_entrypath = NULL;
 +    }
 +    free(ftpc->entrypath);
 +    ftpc->entrypath = NULL;
 +  }
 +
 +  freedirs(ftpc);
 +  free(ftpc->prevpath);
 +  ftpc->prevpath = NULL;
 +  free(ftpc->server_os);
 +  ftpc->server_os = NULL;
 +
 +  Curl_pp_disconnect(pp);
 +
 +#ifdef HAVE_GSSAPI
 +  Curl_sec_end(conn);
 +#endif
 +
 +  return CURLE_OK;
 +}
 +
 +/***********************************************************************
 + *
 + * ftp_parse_url_path()
 + *
 + * Parse the URL path into separate path components.
 + *
 + */
 +static
 +CURLcode ftp_parse_url_path(struct connectdata *conn)
 +{
 +  struct Curl_easy *data = conn->data;
 +  /* the ftp struct is already inited in ftp_connect() */
 +  struct FTP *ftp = data->req.protop;
 +  struct ftp_conn *ftpc = &conn->proto.ftpc;
 +  const char *slash_pos;  /* position of the first '/' char in curpos */
 +  const char *path_to_use = data->state.path;
 +  const char *cur_pos;
 +  const char *filename = NULL;
 +
 +  cur_pos = path_to_use; /* current position in path. point at the begin of
 +                            next path component */
 +
 +  ftpc->ctl_valid = FALSE;
 +  ftpc->cwdfail = FALSE;
 +
 +  switch(data->set.ftp_filemethod) {
 +  case FTPFILE_NOCWD:
 +    /* fastest, but less standard-compliant */
 +
 +    /*
 +      The best time to check whether the path is a file or directory is right
 +      here. so:
 +
 +      the first condition in the if() right here, is there just in case
 +      someone decides to set path to NULL one day
 +   */
 +    if(path_to_use[0] &&
 +       (path_to_use[strlen(path_to_use) - 1] != '/') )
 +      filename = path_to_use;  /* this is a full file path */
 +    /*
 +      else {
 +        ftpc->file is not used anywhere other than for operations on a file.
 +        In other words, never for directory operations.
 +        So we can safely leave filename as NULL here and use it as a
 +        argument in dir/file decisions.
 +      }
 +    */
 +    break;
 +
 +  case FTPFILE_SINGLECWD:
 +    /* get the last slash */
 +    if(!path_to_use[0]) {
 +      /* no dir, no file */
 +      ftpc->dirdepth = 0;
 +      break;
 +    }
 +    slash_pos=strrchr(cur_pos, '/');
 +    if(slash_pos || !*cur_pos) {
 +      size_t dirlen = slash_pos-cur_pos;
 +      CURLcode result;
 +
 +      ftpc->dirs = calloc(1, sizeof(ftpc->dirs[0]));
 +      if(!ftpc->dirs)
 +        return CURLE_OUT_OF_MEMORY;
 +
 +      if(!dirlen)
 +        dirlen++;
 +
 +      result = Curl_urldecode(conn->data, slash_pos ? cur_pos : "/",
 +                              slash_pos ? dirlen : 1,
 +                              &ftpc->dirs[0], NULL,
 +                              FALSE);
 +      if(result) {
 +        freedirs(ftpc);
 +        return result;
 +      }
 +      ftpc->dirdepth = 1; /* we consider it to be a single dir */
 +      filename = slash_pos ? slash_pos+1 : cur_pos; /* rest is file name */
 +    }
 +    else
 +      filename = cur_pos;  /* this is a file name only */
 +    break;
 +
 +  default: /* allow pretty much anything */
 +  case FTPFILE_MULTICWD:
 +    ftpc->dirdepth = 0;
 +    ftpc->diralloc = 5; /* default dir depth to allocate */
 +    ftpc->dirs = calloc(ftpc->diralloc, sizeof(ftpc->dirs[0]));
 +    if(!ftpc->dirs)
 +      return CURLE_OUT_OF_MEMORY;
 +
 +    /* we have a special case for listing the root dir only */
 +    if(!strcmp(path_to_use, "/")) {
 +      cur_pos++; /* make it point to the zero byte */
 +      ftpc->dirs[0] = strdup("/");
 +      ftpc->dirdepth++;
 +    }
 +    else {
 +      /* parse the URL path into separate path components */
 +      while((slash_pos = strchr(cur_pos, '/')) != NULL) {
 +        /* 1 or 0 pointer offset to indicate absolute directory */
 +        ssize_t absolute_dir = ((cur_pos - data->state.path > 0) &&
 +                                (ftpc->dirdepth == 0))?1:0;
 +
 +        /* seek out the next path component */
 +        if(slash_pos-cur_pos) {
 +          /* we skip empty path components, like "x//y" since the FTP command
 +             CWD requires a parameter and a non-existent parameter a) doesn't
 +             work on many servers and b) has no effect on the others. */
 +          size_t len = slash_pos - cur_pos + absolute_dir;
 +          CURLcode result =
 +            Curl_urldecode(conn->data, cur_pos - absolute_dir, len,
 +                           &ftpc->dirs[ftpc->dirdepth], NULL,
 +                           TRUE);
 +          if(result) {
-             free(ftpc->dirs[ftpc->dirdepth]);
 +            freedirs(ftpc);
 +            return result;
 +          }
 +        }
 +        else {
 +          cur_pos = slash_pos + 1; /* jump to the rest of the string */
 +          if(!ftpc->dirdepth) {
 +            /* path starts with a slash, add that as a directory */
 +            ftpc->dirs[ftpc->dirdepth] = strdup("/");
 +            if(!ftpc->dirs[ftpc->dirdepth++]) { /* run out of memory ... */
 +              failf(data, "no memory");
 +              freedirs(ftpc);
 +              return CURLE_OUT_OF_MEMORY;
 +            }
 +          }
 +          continue;
 +        }
 +
 +        cur_pos = slash_pos + 1; /* jump to the rest of the string */
 +        if(++ftpc->dirdepth >= ftpc->diralloc) {
 +          /* enlarge array */
 +          char **bigger;
 +          ftpc->diralloc *= 2; /* double the size each time */
 +          bigger = realloc(ftpc->dirs, ftpc->diralloc * sizeof(ftpc->dirs[0]));
 +          if(!bigger) {
 +            freedirs(ftpc);
 +            return CURLE_OUT_OF_MEMORY;
 +          }
 +          ftpc->dirs = bigger;
 +        }
 +      }
 +    }
 +    filename = cur_pos;  /* the rest is the file name */
 +    break;
 +  } /* switch */
 +
 +  if(filename && *filename) {
 +    CURLcode result =
 +      Curl_urldecode(conn->data, filename, 0,  &ftpc->file, NULL, TRUE);
 +
 +    if(result) {
 +      freedirs(ftpc);
 +      return result;
 +    }
 +  }
 +  else
 +    ftpc->file=NULL; /* instead of point to a zero byte, we make it a NULL
 +                       pointer */
 +
 +  if(data->set.upload && !ftpc->file && (ftp->transfer == FTPTRANSFER_BODY)) {
 +    /* We need a file name when uploading. Return error! */
 +    failf(data, "Uploading to a URL without a file name!");
 +    return CURLE_URL_MALFORMAT;
 +  }
 +
 +  ftpc->cwddone = FALSE; /* default to not done */
 +
 +  if(ftpc->prevpath) {
 +    /* prevpath is "raw" so we convert the input path before we compare the
 +       strings */
 +    size_t dlen;
 +    char *path;
 +    CURLcode result =
 +      Curl_urldecode(conn->data, data->state.path, 0, &path, &dlen, FALSE);
 +    if(result) {
 +      freedirs(ftpc);
 +      return result;
 +    }
 +
 +    dlen -= ftpc->file?strlen(ftpc->file):0;
 +    if((dlen == strlen(ftpc->prevpath)) &&
 +       !strncmp(path, ftpc->prevpath, dlen)) {
 +      infof(data, "Request has same path as previous transfer\n");
 +      ftpc->cwddone = TRUE;
 +    }
 +    free(path);
 +  }
 +
 +  return CURLE_OK;
 +}
 +
 +/* call this when the DO phase has completed */
 +static CURLcode ftp_dophase_done(struct connectdata *conn,
 +                                 bool connected)
 +{
 +  struct FTP *ftp = conn->data->req.protop;
 +  struct ftp_conn *ftpc = &conn->proto.ftpc;
 +
 +  if(connected) {
 +    int completed;
 +    CURLcode result = ftp_do_more(conn, &completed);
 +
 +    if(result) {
 +      close_secondarysocket(conn);
 +      return result;
 +    }
 +  }
 +
 +  if(ftp->transfer != FTPTRANSFER_BODY)
 +    /* no data to transfer */
 +    Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
 +  else if(!connected)
 +    /* since we didn't connect now, we want do_more to get called */
 +    conn->bits.do_more = TRUE;
 +
 +  ftpc->ctl_valid = TRUE; /* seems good */
 +
 +  return CURLE_OK;
 +}
 +
 +/* called from multi.c while DOing */
 +static CURLcode ftp_doing(struct connectdata *conn,
 +                          bool *dophase_done)
 +{
 +  CURLcode result = ftp_multi_statemach(conn, dophase_done);
 +
 +  if(result)
 +    DEBUGF(infof(conn->data, "DO phase failed\n"));
 +  else if(*dophase_done) {
 +    result = ftp_dophase_done(conn, FALSE /* not connected */);
 +
 +    DEBUGF(infof(conn->data, "DO phase is complete2\n"));
 +  }
 +  return result;
 +}
 +
 +/***********************************************************************
 + *
 + * ftp_regular_transfer()
 + *
 + * The input argument is already checked for validity.
 + *
 + * Performs all commands done before a regular transfer between a local and a
 + * remote host.
 + *
 + * ftp->ctl_valid starts out as FALSE, and gets set to TRUE if we reach the
 + * ftp_done() function without finding any major problem.
 + */
 +static
 +CURLcode ftp_regular_transfer(struct connectdata *conn,
 +                              bool *dophase_done)
 +{
 +  CURLcode result=CURLE_OK;
 +  bool connected=FALSE;
 +  struct Curl_easy *data = conn->data;
 +  struct ftp_conn *ftpc = &conn->proto.ftpc;
 +  data->req.size = -1; /* make sure this is unknown at this point */
 +
 +  Curl_pgrsSetUploadCounter(data, 0);
 +  Curl_pgrsSetDownloadCounter(data, 0);
 +  Curl_pgrsSetUploadSize(data, -1);
 +  Curl_pgrsSetDownloadSize(data, -1);
 +
 +  ftpc->ctl_valid = TRUE; /* starts good */
 +
 +  result = ftp_perform(conn,
 +                       &connected, /* have we connected after PASV/PORT */
 +                       dophase_done); /* all commands in the DO-phase done? */
 +
 +  if(!result) {
 +
 +    if(!*dophase_done)
 +      /* the DO phase has not completed yet */
 +      return CURLE_OK;
 +
 +    result = ftp_dophase_done(conn, connected);
 +
 +    if(result)
 +      return result;
 +  }
 +  else
 +    freedirs(ftpc);
 +
 +  return result;
 +}
 +
 +static CURLcode ftp_setup_connection(struct connectdata *conn)
 +{
 +  struct Curl_easy *data = conn->data;
 +  char *type;
 +  char command;
 +  struct FTP *ftp;
 +
 +  if(conn->bits.httpproxy && !data->set.tunnel_thru_httpproxy) {
 +    /* Unless we have asked to tunnel ftp operations through the proxy, we
 +       switch and use HTTP operations only */
 +#ifndef CURL_DISABLE_HTTP
 +    if(conn->handler == &Curl_handler_ftp)
 +      conn->handler = &Curl_handler_ftp_proxy;
 +    else {
 +#ifdef USE_SSL
 +      conn->handler = &Curl_handler_ftps_proxy;
 +#else
 +      failf(data, "FTPS not supported!");
 +      return CURLE_UNSUPPORTED_PROTOCOL;
 +#endif
 +    }
 +    /* set it up as a HTTP connection instead */
 +    return conn->handler->setup_connection(conn);
 +#else
 +    failf(data, "FTP over http proxy requires HTTP support built-in!");
 +    return CURLE_UNSUPPORTED_PROTOCOL;
 +#endif
 +  }
 +
 +  conn->data->req.protop = ftp = malloc(sizeof(struct FTP));
 +  if(NULL == ftp)
 +    return CURLE_OUT_OF_MEMORY;
 +
 +  data->state.path++;   /* don't include the initial slash */
 +  data->state.slash_removed = TRUE; /* we've skipped the slash */
 +
 +  /* FTP URLs support an extension like ";type=<typecode>" that
 +   * we'll try to get now! */
 +  type = strstr(data->state.path, ";type=");
 +
 +  if(!type)
 +    type = strstr(conn->host.rawalloc, ";type=");
 +
 +  if(type) {
 +    *type = 0;                     /* it was in the middle of the hostname */
 +    command = Curl_raw_toupper(type[6]);
 +    conn->bits.type_set = TRUE;
 +
 +    switch(command) {
 +    case 'A': /* ASCII mode */
 +      data->set.prefer_ascii = TRUE;
 +      break;
 +
 +    case 'D': /* directory mode */
 +      data->set.ftp_list_only = TRUE;
 +      break;
 +
 +    case 'I': /* binary mode */
 +    default:
 +      /* switch off ASCII */
 +      data->set.prefer_ascii = FALSE;
 +      break;
 +    }
 +  }
 +
 +  /* get some initial data into the ftp struct */
 +  ftp->bytecountp = &conn->data->req.bytecount;
 +  ftp->transfer = FTPTRANSFER_BODY;
 +  ftp->downloadsize = 0;
 +
 +  /* No need to duplicate user+password, the connectdata struct won't change
 +     during a session, but we re-init them here since on subsequent inits
 +     since the conn struct may have changed or been replaced.
 +  */
 +  ftp->user = conn->user;
 +  ftp->passwd = conn->passwd;
 +  if(isBadFtpString(ftp->user))
 +    return CURLE_URL_MALFORMAT;
 +  if(isBadFtpString(ftp->passwd))
 +    return CURLE_URL_MALFORMAT;
 +
 +  conn->proto.ftpc.known_filesize = -1; /* unknown size for now */
 +
 +  return CURLE_OK;
 +}
 +
 +#endif /* CURL_DISABLE_FTP */
diff --cc Utilities/cmcurl/lib/mprintf.c
index 4baa1cc,0000000..6d4e733
mode 100644,000000..100644
--- a/Utilities/cmcurl/lib/mprintf.c
+++ b/Utilities/cmcurl/lib/mprintf.c
@@@ -1,1181 -1,0 +1,1179 @@@
 +/***************************************************************************
 + *                                  _   _ ____  _
 + *  Project                     ___| | | |  _ \| |
 + *                             / __| | | | |_) | |
 + *                            | (__| |_| |  _ <| |___
 + *                             \___|\___/|_| \_\_____|
 + *
 + * Copyright (C) 1999 - 2016, Daniel Stenberg, <daniel at 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.
 + *
 + *
 + * Purpose:
 + *  A merge of Bjorn Reese's format() function and Daniel's dsprintf()
 + *  1.0. A full blooded printf() clone with full support for <num>$
 + *  everywhere (parameters, widths and precisions) including variabled
 + *  sized parameters (like doubles, long longs, long doubles and even
 + *  void * in 64-bit architectures).
 + *
 + * Current restrictions:
 + * - Max 128 parameters
 + * - No 'long double' support.
 + *
 + * If you ever want truly portable and good *printf() clones, the project that
 + * took on from here is named 'Trio' and you find more details on the trio web
 + * page at https://daniel.haxx.se/projects/trio/
 + */
 +
 +#include "curl_setup.h"
 +#include <curl/mprintf.h>
 +
 +#include "curl_memory.h"
 +/* The last #include file should be: */
 +#include "memdebug.h"
 +
 +/*
 + * If SIZEOF_SIZE_T has not been defined, default to the size of long.
 + */
 +
 +#ifndef SIZEOF_SIZE_T
 +#  define SIZEOF_SIZE_T CURL_SIZEOF_LONG
 +#endif
 +
 +#ifdef HAVE_LONGLONG
 +#  define LONG_LONG_TYPE long long
 +#  define HAVE_LONG_LONG_TYPE
 +#else
 +#  if defined(_MSC_VER) && (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64)
 +#    define LONG_LONG_TYPE __int64
 +#    define HAVE_LONG_LONG_TYPE
 +#  else
 +#    undef LONG_LONG_TYPE
 +#    undef HAVE_LONG_LONG_TYPE
 +#  endif
 +#endif
 +
 +/*
 + * Non-ANSI integer extensions
 + */
 +
 +#if (defined(__BORLANDC__) && (__BORLANDC__ >= 0x520)) || \
 +    (defined(__WATCOMC__) && defined(__386__)) || \
 +    (defined(__POCC__) && defined(_MSC_VER)) || \
 +    (defined(_WIN32_WCE)) || \
 +    (defined(__MINGW32__)) || \
 +    (defined(_MSC_VER) && (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64))
 +#  define MP_HAVE_INT_EXTENSIONS
 +#endif
 +
 +/*
 + * Max integer data types that mprintf.c is capable
 + */
 +
 +#ifdef HAVE_LONG_LONG_TYPE
 +#  define mp_intmax_t LONG_LONG_TYPE
 +#  define mp_uintmax_t unsigned LONG_LONG_TYPE
 +#else
 +#  define mp_intmax_t long
 +#  define mp_uintmax_t unsigned long
 +#endif
 +
 +#define BUFFSIZE 326 /* buffer for long-to-str and float-to-str calcs, should
 +                        fit negative DBL_MAX (317 letters) */
 +#define MAX_PARAMETERS 128 /* lame static limit */
 +
 +#ifdef __AMIGA__
 +# undef FORMAT_INT
 +#endif
 +
 +/* Lower-case digits.  */
 +static const char lower_digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
 +
 +/* Upper-case digits.  */
 +static const char upper_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
 +
 +#define OUTCHAR(x) \
 +  do{ \
 +    if(stream((unsigned char)(x), (FILE *)data) != -1) \
 +      done++; \
 +    else \
 +     return done; /* return immediately on failure */ \
 +  } WHILE_FALSE
 +
 +/* Data type to read from the arglist */
 +typedef enum  {
 +  FORMAT_UNKNOWN = 0,
 +  FORMAT_STRING,
 +  FORMAT_PTR,
 +  FORMAT_INT,
 +  FORMAT_INTPTR,
 +  FORMAT_LONG,
 +  FORMAT_LONGLONG,
 +  FORMAT_DOUBLE,
 +  FORMAT_LONGDOUBLE,
 +  FORMAT_WIDTH /* For internal use */
 +} FormatType;
 +
 +/* conversion and display flags */
 +enum {
 +  FLAGS_NEW        = 0,
 +  FLAGS_SPACE      = 1<<0,
 +  FLAGS_SHOWSIGN   = 1<<1,
 +  FLAGS_LEFT       = 1<<2,
 +  FLAGS_ALT        = 1<<3,
 +  FLAGS_SHORT      = 1<<4,
 +  FLAGS_LONG       = 1<<5,
 +  FLAGS_LONGLONG   = 1<<6,
 +  FLAGS_LONGDOUBLE = 1<<7,
 +  FLAGS_PAD_NIL    = 1<<8,
 +  FLAGS_UNSIGNED   = 1<<9,
 +  FLAGS_OCTAL      = 1<<10,
 +  FLAGS_HEX        = 1<<11,
 +  FLAGS_UPPER      = 1<<12,
 +  FLAGS_WIDTH      = 1<<13, /* '*' or '*<num>$' used */
 +  FLAGS_WIDTHPARAM = 1<<14, /* width PARAMETER was specified */
 +  FLAGS_PREC       = 1<<15, /* precision was specified */
 +  FLAGS_PRECPARAM  = 1<<16, /* precision PARAMETER was specified */
 +  FLAGS_CHAR       = 1<<17, /* %c story */
 +  FLAGS_FLOATE     = 1<<18, /* %e or %E */
 +  FLAGS_FLOATG     = 1<<19  /* %g or %G */
 +};
 +
 +typedef struct {
 +  FormatType type;
 +  int flags;
 +  long width;     /* width OR width parameter number */
 +  long precision; /* precision OR precision parameter number */
 +  union {
 +    char *str;
 +    void *ptr;
 +    union {
 +      mp_intmax_t as_signed;
 +      mp_uintmax_t as_unsigned;
 +    } num;
 +    double dnum;
 +  } data;
 +} va_stack_t;
 +
 +struct nsprintf {
 +  char *buffer;
 +  size_t length;
 +  size_t max;
 +};
 +
 +struct asprintf {
 +  char *buffer; /* allocated buffer */
 +  size_t len;   /* length of string */
 +  size_t alloc; /* length of alloc */
 +  int fail;     /* (!= 0) if an alloc has failed and thus
 +                   the output is not the complete data */
 +};
 +
 +static long dprintf_DollarString(char *input, char **end)
 +{
 +  int number=0;
 +  while(ISDIGIT(*input)) {
 +    number *= 10;
 +    number += *input-'0';
 +    input++;
 +  }
 +  if(number && ('$'==*input++)) {
 +    *end = input;
 +    return number;
 +  }
 +  return 0;
 +}
 +
 +static bool dprintf_IsQualifierNoDollar(const char *fmt)
 +{
 +#if defined(MP_HAVE_INT_EXTENSIONS)
 +  if(!strncmp(fmt, "I32", 3) || !strncmp(fmt, "I64", 3)) {
 +    return TRUE;
 +  }
 +#endif
 +
 +  switch(*fmt) {
 +  case '-': case '+': case ' ': case '#': case '.':
 +  case '0': case '1': case '2': case '3': case '4':
 +  case '5': case '6': case '7': case '8': case '9':
 +  case 'h': case 'l': case 'L': case 'z': case 'q':
 +  case '*': case 'O':
 +#if defined(MP_HAVE_INT_EXTENSIONS)
 +  case 'I':
 +#endif
 +    return TRUE;
 +
 +  default:
 +    return FALSE;
 +  }
 +}
 +
 +/******************************************************************
 + *
 + * Pass 1:
 + * Create an index with the type of each parameter entry and its
 + * value (may vary in size)
 + *
 + * Returns zero on success.
 + *
 + ******************************************************************/
 +
 +static int dprintf_Pass1(const char *format, va_stack_t *vto, char **endpos,
 +                         va_list arglist)
 +{
 +  char *fmt = (char *)format;
 +  int param_num = 0;
 +  long this_param;
 +  long width;
 +  long precision;
 +  int flags;
 +  long max_param=0;
 +  long i;
 +
 +  while(*fmt) {
 +    if(*fmt++ == '%') {
 +      if(*fmt == '%') {
 +        fmt++;
 +        continue; /* while */
 +      }
 +
 +      flags = FLAGS_NEW;
 +
 +      /* Handle the positional case (N$) */
 +
 +      param_num++;
 +
 +      this_param = dprintf_DollarString(fmt, &fmt);
 +      if(0 == this_param)
 +        /* we got no positional, get the next counter */
 +        this_param = param_num;
 +
 +      if(this_param > max_param)
 +        max_param = this_param;
 +
 +      /*
 +       * The parameter with number 'i' should be used. Next, we need
 +       * to get SIZE and TYPE of the parameter. Add the information
 +       * to our array.
 +       */
 +
 +      width = 0;
 +      precision = 0;
 +
 +      /* Handle the flags */
 +
 +      while(dprintf_IsQualifierNoDollar(fmt)) {
 +#if defined(MP_HAVE_INT_EXTENSIONS)
 +        if(!strncmp(fmt, "I32", 3)) {
 +          flags |= FLAGS_LONG;
 +          fmt += 3;
 +        }
 +        else if(!strncmp(fmt, "I64", 3)) {
 +          flags |= FLAGS_LONGLONG;
 +          fmt += 3;
 +        }
 +        else
 +#endif
 +
 +        switch(*fmt++) {
 +        case ' ':
 +          flags |= FLAGS_SPACE;
 +          break;
 +        case '+':
 +          flags |= FLAGS_SHOWSIGN;
 +          break;
 +        case '-':
 +          flags |= FLAGS_LEFT;
 +          flags &= ~FLAGS_PAD_NIL;
 +          break;
 +        case '#':
 +          flags |= FLAGS_ALT;
 +          break;
 +        case '.':
 +          if('*' == *fmt) {
 +            /* The precision is picked from a specified parameter */
 +
 +            flags |= FLAGS_PRECPARAM;
 +            fmt++;
 +            param_num++;
 +
 +            i = dprintf_DollarString(fmt, &fmt);
 +            if(i)
 +              precision = i;
 +            else
 +              precision = param_num;
 +
 +            if(precision > max_param)
 +              max_param = precision;
 +          }
 +          else {
 +            flags |= FLAGS_PREC;
 +            precision = strtol(fmt, &fmt, 10);
 +          }
 +          break;
 +        case 'h':
 +          flags |= FLAGS_SHORT;
 +          break;
 +#if defined(MP_HAVE_INT_EXTENSIONS)
 +        case 'I':
 +#if (CURL_SIZEOF_CURL_OFF_T > CURL_SIZEOF_LONG)
 +          flags |= FLAGS_LONGLONG;
 +#else
 +          flags |= FLAGS_LONG;
 +#endif
 +          break;
 +#endif
 +        case 'l':
 +          if(flags & FLAGS_LONG)
 +            flags |= FLAGS_LONGLONG;
 +          else
 +            flags |= FLAGS_LONG;
 +          break;
 +        case 'L':
 +          flags |= FLAGS_LONGDOUBLE;
 +          break;
 +        case 'q':
 +          flags |= FLAGS_LONGLONG;
 +          break;
 +        case 'z':
 +          /* the code below generates a warning if -Wunreachable-code is
 +             used */
 +#if (SIZEOF_SIZE_T > CURL_SIZEOF_LONG)
 +          flags |= FLAGS_LONGLONG;
 +#else
 +          flags |= FLAGS_LONG;
 +#endif
 +          break;
 +        case 'O':
 +#if (CURL_SIZEOF_CURL_OFF_T > CURL_SIZEOF_LONG)
 +          flags |= FLAGS_LONGLONG;
 +#else
 +          flags |= FLAGS_LONG;
 +#endif
 +          break;
 +        case '0':
 +          if(!(flags & FLAGS_LEFT))
 +            flags |= FLAGS_PAD_NIL;
 +          /* FALLTHROUGH */
 +        case '1': case '2': case '3': case '4':
 +        case '5': case '6': case '7': case '8': case '9':
 +          flags |= FLAGS_WIDTH;
 +          width = strtol(fmt-1, &fmt, 10);
 +          break;
 +        case '*':  /* Special case */
 +          flags |= FLAGS_WIDTHPARAM;
 +          param_num++;
 +
 +          i = dprintf_DollarString(fmt, &fmt);
 +          if(i)
 +            width = i;
 +          else
 +            width = param_num;
 +          if(width > max_param)
 +            max_param=width;
 +          break;
 +        default:
 +          break;
 +        }
 +      } /* switch */
 +
 +      /* Handle the specifier */
 +
 +      i = this_param - 1;
 +
 +      if((i < 0) || (i >= MAX_PARAMETERS))
 +        /* out of allowed range */
 +        return 1;
 +
 +      switch (*fmt) {
 +      case 'S':
 +        flags |= FLAGS_ALT;
 +        /* FALLTHROUGH */
 +      case 's':
 +        vto[i].type = FORMAT_STRING;
 +        break;
 +      case 'n':
 +        vto[i].type = FORMAT_INTPTR;
 +        break;
 +      case 'p':
 +        vto[i].type = FORMAT_PTR;
 +        break;
 +      case 'd': case 'i':
 +        vto[i].type = FORMAT_INT;
 +        break;
 +      case 'u':
 +        vto[i].type = FORMAT_INT;
 +        flags |= FLAGS_UNSIGNED;
 +        break;
 +      case 'o':
 +        vto[i].type = FORMAT_INT;
 +        flags |= FLAGS_OCTAL;
 +        break;
 +      case 'x':
 +        vto[i].type = FORMAT_INT;
 +        flags |= FLAGS_HEX|FLAGS_UNSIGNED;
 +        break;
 +      case 'X':
 +        vto[i].type = FORMAT_INT;
 +        flags |= FLAGS_HEX|FLAGS_UPPER|FLAGS_UNSIGNED;
 +        break;
 +      case 'c':
 +        vto[i].type = FORMAT_INT;
 +        flags |= FLAGS_CHAR;
 +        break;
 +      case 'f':
 +        vto[i].type = FORMAT_DOUBLE;
 +        break;
 +      case 'e':
 +        vto[i].type = FORMAT_DOUBLE;
 +        flags |= FLAGS_FLOATE;
 +        break;
 +      case 'E':
 +        vto[i].type = FORMAT_DOUBLE;
 +        flags |= FLAGS_FLOATE|FLAGS_UPPER;
 +        break;
 +      case 'g':
 +        vto[i].type = FORMAT_DOUBLE;
 +        flags |= FLAGS_FLOATG;
 +        break;
 +      case 'G':
 +        vto[i].type = FORMAT_DOUBLE;
 +        flags |= FLAGS_FLOATG|FLAGS_UPPER;
 +        break;
 +      default:
 +        vto[i].type = FORMAT_UNKNOWN;
 +        break;
 +      } /* switch */
 +
 +      vto[i].flags = flags;
 +      vto[i].width = width;
 +      vto[i].precision = precision;
 +
 +      if(flags & FLAGS_WIDTHPARAM) {
 +        /* we have the width specified from a parameter, so we make that
 +           parameter's info setup properly */
 +        long k = width - 1;
 +        vto[i].width = k;
 +        vto[k].type = FORMAT_WIDTH;
 +        vto[k].flags = FLAGS_NEW;
 +        /* can't use width or precision of width! */
 +        vto[k].width = 0;
 +        vto[k].precision = 0;
 +      }
 +      if(flags & FLAGS_PRECPARAM) {
 +        /* we have the precision specified from a parameter, so we make that
 +           parameter's info setup properly */
 +        long k = precision - 1;
 +        vto[i].precision = k;
 +        vto[k].type = FORMAT_WIDTH;
 +        vto[k].flags = FLAGS_NEW;
 +        /* can't use width or precision of width! */
 +        vto[k].width = 0;
 +        vto[k].precision = 0;
 +      }
 +      *endpos++ = fmt + 1; /* end of this sequence */
 +    }
 +  }
 +
 +  /* Read the arg list parameters into our data list */
 +  for(i=0; i<max_param; i++) {
 +    /* Width/precision arguments must be read before the main argument
 +       they are attached to */
 +    if(vto[i].flags & FLAGS_WIDTHPARAM) {
 +      vto[vto[i].width].data.num.as_signed =
 +        (mp_intmax_t)va_arg(arglist, int);
 +    }
 +    if(vto[i].flags & FLAGS_PRECPARAM) {
 +      vto[vto[i].precision].data.num.as_signed =
 +        (mp_intmax_t)va_arg(arglist, int);
 +    }
 +
 +    switch(vto[i].type) {
 +    case FORMAT_STRING:
 +      vto[i].data.str = va_arg(arglist, char *);
 +      break;
 +
 +    case FORMAT_INTPTR:
 +    case FORMAT_UNKNOWN:
 +    case FORMAT_PTR:
 +      vto[i].data.ptr = va_arg(arglist, void *);
 +      break;
 +
 +    case FORMAT_INT:
 +#ifdef HAVE_LONG_LONG_TYPE
 +      if((vto[i].flags & FLAGS_LONGLONG) && (vto[i].flags & FLAGS_UNSIGNED))
 +        vto[i].data.num.as_unsigned =
 +          (mp_uintmax_t)va_arg(arglist, mp_uintmax_t);
 +      else if(vto[i].flags & FLAGS_LONGLONG)
 +        vto[i].data.num.as_signed =
 +          (mp_intmax_t)va_arg(arglist, mp_intmax_t);
 +      else
 +#endif
 +      {
 +        if((vto[i].flags & FLAGS_LONG) && (vto[i].flags & FLAGS_UNSIGNED))
 +          vto[i].data.num.as_unsigned =
 +            (mp_uintmax_t)va_arg(arglist, unsigned long);
 +        else if(vto[i].flags & FLAGS_LONG)
 +          vto[i].data.num.as_signed =
 +            (mp_intmax_t)va_arg(arglist, long);
 +        else if(vto[i].flags & FLAGS_UNSIGNED)
 +          vto[i].data.num.as_unsigned =
 +            (mp_uintmax_t)va_arg(arglist, unsigned int);
 +        else
 +          vto[i].data.num.as_signed =
 +            (mp_intmax_t)va_arg(arglist, int);
 +      }
 +      break;
 +
 +    case FORMAT_DOUBLE:
 +      vto[i].data.dnum = va_arg(arglist, double);
 +      break;
 +
 +    case FORMAT_WIDTH:
 +      /* Argument has been read. Silently convert it into an integer
 +       * for later use
 +       */
 +      vto[i].type = FORMAT_INT;
 +      break;
 +
 +    default:
 +      break;
 +    }
 +  }
 +
 +  return 0;
 +
 +}
 +
 +static int dprintf_formatf(
 +  void *data, /* untouched by format(), just sent to the stream() function in
 +                 the second argument */
 +  /* function pointer called for each output character */
 +  int (*stream)(int, FILE *),
 +  const char *format,    /* %-formatted string */
 +  va_list ap_save) /* list of parameters */
 +{
 +  /* Base-36 digits for numbers.  */
 +  const char *digits = lower_digits;
 +
 +  /* Pointer into the format string.  */
 +  char *f;
 +
 +  /* Number of characters written.  */
 +  int done = 0;
 +
 +  long param; /* current parameter to read */
 +  long param_num=0; /* parameter counter */
 +
 +  va_stack_t vto[MAX_PARAMETERS];
 +  char *endpos[MAX_PARAMETERS];
 +  char **end;
 +
 +  char work[BUFFSIZE];
 +
 +  va_stack_t *p;
 +
 +  /* 'workend' points to the final buffer byte position, but with an extra
 +     byte as margin to avoid the (false?) warning Coverity gives us
 +     otherwise */
 +  char *workend = &work[sizeof(work) - 2];
 +
 +  /* Do the actual %-code parsing */
 +  if(dprintf_Pass1(format, vto, endpos, ap_save))
 +    return -1;
 +
 +  end = &endpos[0]; /* the initial end-position from the list dprintf_Pass1()
 +                       created for us */
 +
 +  f = (char *)format;
 +  while(*f != '\0') {
 +    /* Format spec modifiers.  */
 +    int is_alt;
 +
 +    /* Width of a field.  */
 +    long width;
 +
 +    /* Precision of a field.  */
 +    long prec;
 +
 +    /* Decimal integer is negative.  */
 +    int is_neg;
 +
 +    /* Base of a number to be written.  */
 +    long base;
 +
 +    /* Integral values to be written.  */
 +    mp_uintmax_t num;
 +
 +    /* Used to convert negative in positive.  */
 +    mp_intmax_t signed_num;
 +
 +    char *w;
 +
 +    if(*f != '%') {
 +      /* This isn't a format spec, so write everything out until the next one
 +         OR end of string is reached.  */
 +      do {
 +        OUTCHAR(*f);
 +      } while(*++f && ('%' != *f));
 +      continue;
 +    }
 +
 +    ++f;
 +
 +    /* Check for "%%".  Note that although the ANSI standard lists
 +       '%' as a conversion specifier, it says "The complete format
 +       specification shall be `%%'," so we can avoid all the width
 +       and precision processing.  */
 +    if(*f == '%') {
 +      ++f;
 +      OUTCHAR('%');
 +      continue;
 +    }
 +
 +    /* If this is a positional parameter, the position must follow immediately
 +       after the %, thus create a %<num>$ sequence */
 +    param=dprintf_DollarString(f, &f);
 +
 +    if(!param)
 +      param = param_num;
 +    else
 +      --param;
 +
 +    param_num++; /* increase this always to allow "%2$s %1$s %s" and then the
 +                    third %s will pick the 3rd argument */
 +
 +    p = &vto[param];
 +
 +    /* pick up the specified width */
 +    if(p->flags & FLAGS_WIDTHPARAM) {
 +      width = (long)vto[p->width].data.num.as_signed;
 +      param_num++; /* since the width is extracted from a parameter, we
 +                      must skip that to get to the next one properly */
 +      if(width < 0) {
 +        /* "A negative field width is taken as a '-' flag followed by a
 +           positive field width." */
 +        width = -width;
 +        p->flags |= FLAGS_LEFT;
 +        p->flags &= ~FLAGS_PAD_NIL;
 +      }
 +    }
 +    else
 +      width = p->width;
 +
 +    /* pick up the specified precision */
 +    if(p->flags & FLAGS_PRECPARAM) {
 +      prec = (long)vto[p->precision].data.num.as_signed;
 +      param_num++; /* since the precision is extracted from a parameter, we
 +                      must skip that to get to the next one properly */
 +      if(prec < 0)
 +        /* "A negative precision is taken as if the precision were
 +           omitted." */
 +        prec = -1;
 +    }
 +    else if(p->flags & FLAGS_PREC)
 +      prec = p->precision;
 +    else
 +      prec = -1;
 +
 +    is_alt = (p->flags & FLAGS_ALT) ? 1 : 0;
 +
 +    switch(p->type) {
 +    case FORMAT_INT:
 +      num = p->data.num.as_unsigned;
 +      if(p->flags & FLAGS_CHAR) {
 +        /* Character.  */
 +        if(!(p->flags & FLAGS_LEFT))
 +          while(--width > 0)
 +            OUTCHAR(' ');
 +        OUTCHAR((char) num);
 +        if(p->flags & FLAGS_LEFT)
 +          while(--width > 0)
 +            OUTCHAR(' ');
 +        break;
 +      }
 +      if(p->flags & FLAGS_OCTAL) {
 +        /* Octal unsigned integer.  */
 +        base = 8;
 +        goto unsigned_number;
 +      }
 +      else if(p->flags & FLAGS_HEX) {
 +        /* Hexadecimal unsigned integer.  */
 +
 +        digits = (p->flags & FLAGS_UPPER)? upper_digits : lower_digits;
 +        base = 16;
 +        goto unsigned_number;
 +      }
 +      else if(p->flags & FLAGS_UNSIGNED) {
 +        /* Decimal unsigned integer.  */
 +        base = 10;
 +        goto unsigned_number;
 +      }
 +
 +      /* Decimal integer.  */
 +      base = 10;
 +
 +      is_neg = (p->data.num.as_signed < (mp_intmax_t)0) ? 1 : 0;
 +      if(is_neg) {
 +        /* signed_num might fail to hold absolute negative minimum by 1 */
 +        signed_num = p->data.num.as_signed + (mp_intmax_t)1;
 +        signed_num = -signed_num;
 +        num = (mp_uintmax_t)signed_num;
 +        num += (mp_uintmax_t)1;
 +      }
 +
 +      goto number;
 +
 +      unsigned_number:
 +      /* Unsigned number of base BASE.  */
 +      is_neg = 0;
 +
 +      number:
 +      /* Number of base BASE.  */
 +
 +      /* Supply a default precision if none was given.  */
 +      if(prec == -1)
 +        prec = 1;
 +
 +      /* Put the number in WORK.  */
 +      w = workend;
 +      while(num > 0) {
 +        *w-- = digits[num % base];
 +        num /= base;
 +      }
 +      width -= (long)(workend - w);
 +      prec -= (long)(workend - w);
 +
 +      if(is_alt && base == 8 && prec <= 0) {
 +        *w-- = '0';
 +        --width;
 +      }
 +
 +      if(prec > 0) {
 +        width -= prec;
 +        while(prec-- > 0)
 +          *w-- = '0';
 +      }
 +
 +      if(is_alt && base == 16)
 +        width -= 2;
 +
 +      if(is_neg || (p->flags & FLAGS_SHOWSIGN) || (p->flags & FLAGS_SPACE))
 +        --width;
 +
 +      if(!(p->flags & FLAGS_LEFT) && !(p->flags & FLAGS_PAD_NIL))
 +        while(width-- > 0)
 +          OUTCHAR(' ');
 +
 +      if(is_neg)
 +        OUTCHAR('-');
 +      else if(p->flags & FLAGS_SHOWSIGN)
 +        OUTCHAR('+');
 +      else if(p->flags & FLAGS_SPACE)
 +        OUTCHAR(' ');
 +
 +      if(is_alt && base == 16) {
 +        OUTCHAR('0');
 +        if(p->flags & FLAGS_UPPER)
 +          OUTCHAR('X');
 +        else
 +          OUTCHAR('x');
 +      }
 +
 +      if(!(p->flags & FLAGS_LEFT) && (p->flags & FLAGS_PAD_NIL))
 +        while(width-- > 0)
 +          OUTCHAR('0');
 +
 +      /* Write the number.  */
 +      while(++w <= workend) {
 +        OUTCHAR(*w);
 +      }
 +
 +      if(p->flags & FLAGS_LEFT)
 +        while(width-- > 0)
 +          OUTCHAR(' ');
 +      break;
 +
 +    case FORMAT_STRING:
 +            /* String.  */
 +      {
 +        static const char null[] = "(nil)";
 +        const char *str;
 +        size_t len;
 +
 +        str = (char *) p->data.str;
 +        if(str == NULL) {
 +          /* Write null[] if there's space.  */
 +          if(prec == -1 || prec >= (long) sizeof(null) - 1) {
 +            str = null;
 +            len = sizeof(null) - 1;
 +            /* Disable quotes around (nil) */
 +            p->flags &= (~FLAGS_ALT);
 +          }
 +          else {
 +            str = "";
 +            len = 0;
 +          }
 +        }
 +        else if(prec != -1)
 +          len = (size_t)prec;
 +        else
 +          len = strlen(str);
 +
 +        width -= (len > LONG_MAX) ? LONG_MAX : (long)len;
 +
 +        if(p->flags & FLAGS_ALT)
 +          OUTCHAR('"');
 +
 +        if(!(p->flags&FLAGS_LEFT))
 +          while(width-- > 0)
 +            OUTCHAR(' ');
 +
 +        while((len-- > 0) && *str)
 +          OUTCHAR(*str++);
 +        if(p->flags&FLAGS_LEFT)
 +          while(width-- > 0)
 +            OUTCHAR(' ');
 +
 +        if(p->flags & FLAGS_ALT)
 +          OUTCHAR('"');
 +      }
 +      break;
 +
 +    case FORMAT_PTR:
 +      /* Generic pointer.  */
 +      {
 +        void *ptr;
 +        ptr = (void *) p->data.ptr;
 +        if(ptr != NULL) {
 +          /* If the pointer is not NULL, write it as a %#x spec.  */
 +          base = 16;
 +          digits = (p->flags & FLAGS_UPPER)? upper_digits : lower_digits;
 +          is_alt = 1;
 +          num = (size_t) ptr;
 +          is_neg = 0;
 +          goto number;
 +        }
 +        else {
 +          /* Write "(nil)" for a nil pointer.  */
 +          static const char strnil[] = "(nil)";
 +          const char *point;
 +
 +          width -= (long)(sizeof(strnil) - 1);
 +          if(p->flags & FLAGS_LEFT)
 +            while(width-- > 0)
 +              OUTCHAR(' ');
 +          for(point = strnil; *point != '\0'; ++point)
 +            OUTCHAR(*point);
 +          if(! (p->flags & FLAGS_LEFT))
 +            while(width-- > 0)
 +              OUTCHAR(' ');
 +        }
 +      }
 +      break;
 +
 +    case FORMAT_DOUBLE:
 +      {
 +        char formatbuf[32]="%";
 +        char *fptr = &formatbuf[1];
 +        size_t left = sizeof(formatbuf)-strlen(formatbuf);
 +        int len;
 +
 +        width = -1;
 +        if(p->flags & FLAGS_WIDTH)
 +          width = p->width;
 +        else if(p->flags & FLAGS_WIDTHPARAM)
 +          width = (long)vto[p->width].data.num.as_signed;
 +
 +        prec = -1;
 +        if(p->flags & FLAGS_PREC)
 +          prec = p->precision;
 +        else if(p->flags & FLAGS_PRECPARAM)
 +          prec = (long)vto[p->precision].data.num.as_signed;
 +
 +        if(p->flags & FLAGS_LEFT)
 +          *fptr++ = '-';
 +        if(p->flags & FLAGS_SHOWSIGN)
 +          *fptr++ = '+';
 +        if(p->flags & FLAGS_SPACE)
 +          *fptr++ = ' ';
 +        if(p->flags & FLAGS_ALT)
 +          *fptr++ = '#';
 +
 +        *fptr = 0;
 +
 +        if(width >= 0) {
 +          if(width >= (long)sizeof(work))
 +            width = sizeof(work)-1;
 +          /* RECURSIVE USAGE */
 +          len = curl_msnprintf(fptr, left, "%ld", width);
 +          fptr += len;
 +          left -= len;
 +        }
 +        if(prec >= 0) {
 +          /* for each digit in the integer part, we can have one less
 +             precision */
 +          size_t maxprec = sizeof(work) - 2;
 +          double val = p->data.dnum;
 +          while(val >= 10.0) {
 +            val /= 10;
 +            maxprec--;
 +          }
 +
 +          if(prec > (long)maxprec)
 +            prec = (long)maxprec-1;
 +          /* RECURSIVE USAGE */
 +          len = curl_msnprintf(fptr, left, ".%ld", prec);
 +          fptr += len;
 +        }
 +        if(p->flags & FLAGS_LONG)
 +          *fptr++ = 'l';
 +
 +        if(p->flags & FLAGS_FLOATE)
 +          *fptr++ = (char)((p->flags & FLAGS_UPPER) ? 'E':'e');
 +        else if(p->flags & FLAGS_FLOATG)
 +          *fptr++ = (char)((p->flags & FLAGS_UPPER) ? 'G' : 'g');
 +        else
 +          *fptr++ = 'f';
 +
 +        *fptr = 0; /* and a final zero termination */
 +
 +        /* NOTE NOTE NOTE!! Not all sprintf implementations return number of
 +           output characters */
 +        (sprintf)(work, formatbuf, p->data.dnum);
 +#ifdef CURLDEBUG
 +        assert(strlen(work) <= sizeof(work));
 +#endif
 +        for(fptr=work; *fptr; fptr++)
 +          OUTCHAR(*fptr);
 +      }
 +      break;
 +
 +    case FORMAT_INTPTR:
 +      /* Answer the count of characters written.  */
 +#ifdef HAVE_LONG_LONG_TYPE
 +      if(p->flags & FLAGS_LONGLONG)
 +        *(LONG_LONG_TYPE *) p->data.ptr = (LONG_LONG_TYPE)done;
 +      else
 +#endif
 +        if(p->flags & FLAGS_LONG)
 +          *(long *) p->data.ptr = (long)done;
 +      else if(!(p->flags & FLAGS_SHORT))
 +        *(int *) p->data.ptr = (int)done;
 +      else
 +        *(short *) p->data.ptr = (short)done;
 +      break;
 +
 +    default:
 +      break;
 +    }
 +    f = *end++; /* goto end of %-code */
 +
 +  }
 +  return done;
 +}
 +
 +/* fputc() look-alike */
 +static int addbyter(int output, FILE *data)
 +{
 +  struct nsprintf *infop=(struct nsprintf *)data;
 +  unsigned char outc = (unsigned char)output;
 +
 +  if(infop->length < infop->max) {
 +    /* only do this if we haven't reached max length yet */
 +    infop->buffer[0] = outc; /* store */
 +    infop->buffer++; /* increase pointer */
 +    infop->length++; /* we are now one byte larger */
 +    return outc;     /* fputc() returns like this on success */
 +  }
 +  return -1;
 +}
 +
 +int curl_mvsnprintf(char *buffer, size_t maxlength, const char *format,
 +                    va_list ap_save)
 +{
 +  int retcode;
 +  struct nsprintf info;
 +
 +  info.buffer = buffer;
 +  info.length = 0;
 +  info.max = maxlength;
 +
 +  retcode = dprintf_formatf(&info, addbyter, format, ap_save);
 +  if((retcode != -1) && info.max) {
 +    /* we terminate this with a zero byte */
 +    if(info.max == info.length)
 +      /* we're at maximum, scrap the last letter */
 +      info.buffer[-1] = 0;
 +    else
 +      info.buffer[0] = 0;
 +  }
 +  return retcode;
 +}
 +
 +int curl_msnprintf(char *buffer, size_t maxlength, const char *format, ...)
 +{
 +  int retcode;
 +  va_list ap_save; /* argument pointer */
 +  va_start(ap_save, format);
 +  retcode = curl_mvsnprintf(buffer, maxlength, format, ap_save);
 +  va_end(ap_save);
 +  return retcode;
 +}
 +
 +/* fputc() look-alike */
 +static int alloc_addbyter(int output, FILE *data)
 +{
 +  struct asprintf *infop=(struct asprintf *)data;
 +  unsigned char outc = (unsigned char)output;
 +
 +  if(!infop->buffer) {
 +    infop->buffer = malloc(32);
 +    if(!infop->buffer) {
 +      infop->fail = 1;
 +      return -1; /* fail */
 +    }
 +    infop->alloc = 32;
 +    infop->len =0;
 +  }
 +  else if(infop->len+1 >= infop->alloc) {
 +    char *newptr = NULL;
 +    size_t newsize = infop->alloc*2;
 +
 +    /* detect wrap-around or other overflow problems */
 +    if(newsize > infop->alloc)
 +      newptr = realloc(infop->buffer, newsize);
 +
 +    if(!newptr) {
 +      infop->fail = 1;
 +      return -1; /* fail */
 +    }
 +    infop->buffer = newptr;
 +    infop->alloc = newsize;
 +  }
 +
 +  infop->buffer[ infop->len ] = outc;
 +
 +  infop->len++;
 +
 +  return outc; /* fputc() returns like this on success */
 +}
 +
 +char *curl_maprintf(const char *format, ...)
 +{
 +  va_list ap_save; /* argument pointer */
 +  int retcode;
 +  struct asprintf info;
 +
 +  info.buffer = NULL;
 +  info.len = 0;
 +  info.alloc = 0;
 +  info.fail = 0;
 +
 +  va_start(ap_save, format);
 +  retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save);
 +  va_end(ap_save);
 +  if((-1 == retcode) || info.fail) {
 +    if(info.alloc)
 +      free(info.buffer);
 +    return NULL;
 +  }
 +  if(info.alloc) {
 +    info.buffer[info.len] = 0; /* we terminate this with a zero byte */
 +    return info.buffer;
 +  }
-   else
-     return strdup("");
++  return strdup("");
 +}
 +
 +char *curl_mvaprintf(const char *format, va_list ap_save)
 +{
 +  int retcode;
 +  struct asprintf info;
 +
 +  info.buffer = NULL;
 +  info.len = 0;
 +  info.alloc = 0;
 +  info.fail = 0;
 +
 +  retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save);
 +  if((-1 == retcode) || info.fail) {
 +    if(info.alloc)
 +      free(info.buffer);
 +    return NULL;
 +  }
 +
 +  if(info.alloc) {
 +    info.buffer[info.len] = 0; /* we terminate this with a zero byte */
 +    return info.buffer;
 +  }
-   else
-     return strdup("");
++  return strdup("");
 +}
 +
 +static int storebuffer(int output, FILE *data)
 +{
 +  char **buffer = (char **)data;
 +  unsigned char outc = (unsigned char)output;
 +  **buffer = outc;
 +  (*buffer)++;
 +  return outc; /* act like fputc() ! */
 +}
 +
 +int curl_msprintf(char *buffer, const char *format, ...)
 +{
 +  va_list ap_save; /* argument pointer */
 +  int retcode;
 +  va_start(ap_save, format);
 +  retcode = dprintf_formatf(&buffer, storebuffer, format, ap_save);
 +  va_end(ap_save);
 +  *buffer=0; /* we terminate this with a zero byte */
 +  return retcode;
 +}
 +
 +int curl_mprintf(const char *format, ...)
 +{
 +  int retcode;
 +  va_list ap_save; /* argument pointer */
 +  va_start(ap_save, format);
 +
 +  retcode = dprintf_formatf(stdout, fputc, format, ap_save);
 +  va_end(ap_save);
 +  return retcode;
 +}
 +
 +int curl_mfprintf(FILE *whereto, const char *format, ...)
 +{
 +  int retcode;
 +  va_list ap_save; /* argument pointer */
 +  va_start(ap_save, format);
 +  retcode = dprintf_formatf(whereto, fputc, format, ap_save);
 +  va_end(ap_save);
 +  return retcode;
 +}
 +
 +int curl_mvsprintf(char *buffer, const char *format, va_list ap_save)
 +{
 +  int retcode;
 +  retcode = dprintf_formatf(&buffer, storebuffer, format, ap_save);
 +  *buffer=0; /* we terminate this with a zero byte */
 +  return retcode;
 +}
 +
 +int curl_mvprintf(const char *format, va_list ap_save)
 +{
 +  return dprintf_formatf(stdout, fputc, format, ap_save);
 +}
 +
 +int curl_mvfprintf(FILE *whereto, const char *format, va_list ap_save)
 +{
 +  return dprintf_formatf(whereto, fputc, format, ap_save);
 +}
diff --cc Utilities/cmcurl/lib/select.c
index 6bb0ab1,0000000..4430072
mode 100644,000000..100644
--- a/Utilities/cmcurl/lib/select.c
+++ b/Utilities/cmcurl/lib/select.c
@@@ -1,583 -1,0 +1,583 @@@
 +/***************************************************************************
 + *                                  _   _ ____  _
 + *  Project                     ___| | | |  _ \| |
 + *                             / __| | | | |_) | |
 + *                            | (__| |_| |  _ <| |___
 + *                             \___|\___/|_| \_\_____|
 + *
-  * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
++ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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_SYS_SELECT_H
 +#include <sys/select.h>
 +#endif
 +
 +#if !defined(HAVE_SELECT) && !defined(HAVE_POLL_FINE)
 +#error "We can't compile without select() or poll() support."
 +#endif
 +
 +#if defined(__BEOS__)
 +/* BeOS has FD_SET defined in socket.h */
 +#include <socket.h>
 +#endif
 +
 +#ifdef MSDOS
 +#include <dos.h>  /* delay() */
 +#endif
 +
 +#ifdef __VXWORKS__
 +#include <strings.h>  /* bzero() in FD_SET */
 +#endif
 +
 +#include <curl/curl.h>
 +
 +#include "urldata.h"
 +#include "connect.h"
 +#include "select.h"
 +#include "warnless.h"
 +
 +/* Convenience local macros */
 +#define ELAPSED_MS()  (int)curlx_tvdiff(curlx_tvnow(), initial_tv)
 +
 +int Curl_ack_eintr = 0;
 +#define ERROR_NOT_EINTR(error) (Curl_ack_eintr || error != EINTR)
 +
 +/*
 + * Internal function used for waiting a specific amount of ms
 + * in Curl_socket_check() and Curl_poll() when no file descriptor
 + * is provided to wait on, just being used to delay execution.
 + * WinSock select() and poll() timeout mechanisms need a valid
 + * socket descriptor in a not null file descriptor set to work.
 + * Waiting indefinitely with this function is not allowed, a
 + * zero or negative timeout value will return immediately.
 + * Timeout resolution, accuracy, as well as maximum supported
 + * value is system dependent, neither factor is a citical issue
 + * for the intended use of this function in the library.
 + *
 + * Return values:
 + *   -1 = system call error, invalid timeout value, or interrupted
 + *    0 = specified timeout has elapsed
 + */
 +int Curl_wait_ms(int timeout_ms)
 +{
 +#if !defined(MSDOS) && !defined(USE_WINSOCK)
 +#ifndef HAVE_POLL_FINE
 +  struct timeval pending_tv;
 +#endif
 +  struct timeval initial_tv;
 +  int pending_ms;
 +  int error;
 +#endif
 +  int r = 0;
 +
 +  if(!timeout_ms)
 +    return 0;
 +  if(timeout_ms < 0) {
 +    SET_SOCKERRNO(EINVAL);
 +    return -1;
 +  }
 +#if defined(MSDOS)
 +  delay(timeout_ms);
 +#elif defined(USE_WINSOCK)
 +  Sleep(timeout_ms);
 +#else
 +  pending_ms = timeout_ms;
 +  initial_tv = curlx_tvnow();
 +  do {
 +#if defined(HAVE_POLL_FINE)
 +    r = poll(NULL, 0, pending_ms);
 +#else
 +    pending_tv.tv_sec = pending_ms / 1000;
 +    pending_tv.tv_usec = (pending_ms % 1000) * 1000;
 +    r = select(0, NULL, NULL, NULL, &pending_tv);
 +#endif /* HAVE_POLL_FINE */
 +    if(r != -1)
 +      break;
 +    error = SOCKERRNO;
 +    if(error && ERROR_NOT_EINTR(error))
 +      break;
 +    pending_ms = timeout_ms - ELAPSED_MS();
 +    if(pending_ms <= 0) {
 +      r = 0;  /* Simulate a "call timed out" case */
 +      break;
 +    }
 +  } while(r == -1);
 +#endif /* USE_WINSOCK */
 +  if(r)
 +    r = -1;
 +  return r;
 +}
 +
 +/*
 + * Wait for read or write events on a set of file descriptors. It uses poll()
 + * when a fine poll() is available, in order to avoid limits with FD_SETSIZE,
 + * otherwise select() is used.  An error is returned if select() is being used
 + * and a file descriptor is too large for FD_SETSIZE.
 + *
 + * A negative timeout value makes this function wait indefinitely,
-  * unles no valid file descriptor is given, when this happens the
++ * unless no valid file descriptor is given, when this happens the
 + * negative timeout is ignored and the function times out immediately.
 + *
 + * Return values:
 + *   -1 = system call error or fd >= FD_SETSIZE
 + *    0 = timeout
 + *    [bitmask] = action as described below
 + *
 + * CURL_CSELECT_IN - first socket is readable
 + * CURL_CSELECT_IN2 - second socket is readable
 + * CURL_CSELECT_OUT - write socket is writable
 + * CURL_CSELECT_ERR - an error condition occurred
 + */
 +int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
 +                      curl_socket_t readfd1,
 +                      curl_socket_t writefd, /* socket to write to */
 +                      time_t timeout_ms)     /* milliseconds to wait */
 +{
 +#ifdef HAVE_POLL_FINE
 +  struct pollfd pfd[3];
 +  int num;
 +#else
 +  struct timeval pending_tv;
 +  struct timeval *ptimeout;
 +  fd_set fds_read;
 +  fd_set fds_write;
 +  fd_set fds_err;
 +  curl_socket_t maxfd;
 +#endif
 +  struct timeval initial_tv = {0, 0};
 +  int pending_ms = 0;
 +  int error;
 +  int r;
 +  int ret;
 +
- #if SIZEOF_LONG != SIZEOF_INT
++#if SIZEOF_TIME_T != SIZEOF_INT
 +  /* wrap-around precaution */
 +  if(timeout_ms >= INT_MAX)
 +    timeout_ms = INT_MAX;
 +#endif
 +
 +  if((readfd0 == CURL_SOCKET_BAD) && (readfd1 == CURL_SOCKET_BAD) &&
 +     (writefd == CURL_SOCKET_BAD)) {
 +    /* no sockets, just wait */
 +    r = Curl_wait_ms((int)timeout_ms);
 +    return r;
 +  }
 +
 +  /* Avoid initial timestamp, avoid curlx_tvnow() call, when elapsed
 +     time in this function does not need to be measured. This happens
 +     when function is called with a zero timeout or a negative timeout
 +     value indicating a blocking call should be performed. */
 +
 +  if(timeout_ms > 0) {
 +    pending_ms = (int)timeout_ms;
 +    initial_tv = curlx_tvnow();
 +  }
 +
 +#ifdef HAVE_POLL_FINE
 +
 +  num = 0;
 +  if(readfd0 != CURL_SOCKET_BAD) {
 +    pfd[num].fd = readfd0;
 +    pfd[num].events = POLLRDNORM|POLLIN|POLLRDBAND|POLLPRI;
 +    pfd[num].revents = 0;
 +    num++;
 +  }
 +  if(readfd1 != CURL_SOCKET_BAD) {
 +    pfd[num].fd = readfd1;
 +    pfd[num].events = POLLRDNORM|POLLIN|POLLRDBAND|POLLPRI;
 +    pfd[num].revents = 0;
 +    num++;
 +  }
 +  if(writefd != CURL_SOCKET_BAD) {
 +    pfd[num].fd = writefd;
 +    pfd[num].events = POLLWRNORM|POLLOUT;
 +    pfd[num].revents = 0;
 +    num++;
 +  }
 +
 +  do {
 +    if(timeout_ms < 0)
 +      pending_ms = -1;
 +    else if(!timeout_ms)
 +      pending_ms = 0;
 +    r = poll(pfd, num, pending_ms);
 +    if(r != -1)
 +      break;
 +    error = SOCKERRNO;
 +    if(error && ERROR_NOT_EINTR(error))
 +      break;
 +    if(timeout_ms > 0) {
 +      pending_ms = (int)(timeout_ms - ELAPSED_MS());
 +      if(pending_ms <= 0) {
 +        r = 0;  /* Simulate a "call timed out" case */
 +        break;
 +      }
 +    }
 +  } while(r == -1);
 +
 +  if(r < 0)
 +    return -1;
 +  if(r == 0)
 +    return 0;
 +
 +  ret = 0;
 +  num = 0;
 +  if(readfd0 != CURL_SOCKET_BAD) {
 +    if(pfd[num].revents & (POLLRDNORM|POLLIN|POLLERR|POLLHUP))
 +      ret |= CURL_CSELECT_IN;
 +    if(pfd[num].revents & (POLLRDBAND|POLLPRI|POLLNVAL))
 +      ret |= CURL_CSELECT_ERR;
 +    num++;
 +  }
 +  if(readfd1 != CURL_SOCKET_BAD) {
 +    if(pfd[num].revents & (POLLRDNORM|POLLIN|POLLERR|POLLHUP))
 +      ret |= CURL_CSELECT_IN2;
 +    if(pfd[num].revents & (POLLRDBAND|POLLPRI|POLLNVAL))
 +      ret |= CURL_CSELECT_ERR;
 +    num++;
 +  }
 +  if(writefd != CURL_SOCKET_BAD) {
 +    if(pfd[num].revents & (POLLWRNORM|POLLOUT))
 +      ret |= CURL_CSELECT_OUT;
 +    if(pfd[num].revents & (POLLERR|POLLHUP|POLLNVAL))
 +      ret |= CURL_CSELECT_ERR;
 +  }
 +
 +  return ret;
 +
 +#else  /* HAVE_POLL_FINE */
 +
 +  FD_ZERO(&fds_err);
 +  maxfd = (curl_socket_t)-1;
 +
 +  FD_ZERO(&fds_read);
 +  if(readfd0 != CURL_SOCKET_BAD) {
 +    VERIFY_SOCK(readfd0);
 +    FD_SET(readfd0, &fds_read);
 +    FD_SET(readfd0, &fds_err);
 +    maxfd = readfd0;
 +  }
 +  if(readfd1 != CURL_SOCKET_BAD) {
 +    VERIFY_SOCK(readfd1);
 +    FD_SET(readfd1, &fds_read);
 +    FD_SET(readfd1, &fds_err);
 +    if(readfd1 > maxfd)
 +      maxfd = readfd1;
 +  }
 +
 +  FD_ZERO(&fds_write);
 +  if(writefd != CURL_SOCKET_BAD) {
 +    VERIFY_SOCK(writefd);
 +    FD_SET(writefd, &fds_write);
 +    FD_SET(writefd, &fds_err);
 +    if(writefd > maxfd)
 +      maxfd = writefd;
 +  }
 +
 +  ptimeout = (timeout_ms < 0) ? NULL : &pending_tv;
 +
 +  do {
 +    if(timeout_ms > 0) {
 +      pending_tv.tv_sec = pending_ms / 1000;
 +      pending_tv.tv_usec = (pending_ms % 1000) * 1000;
 +    }
 +    else if(!timeout_ms) {
 +      pending_tv.tv_sec = 0;
 +      pending_tv.tv_usec = 0;
 +    }
 +
 +    /* WinSock select() must not be called with an fd_set that contains zero
 +       fd flags, or it will return WSAEINVAL.  But, it also can't be called
 +       with no fd_sets at all!  From the documentation:
 +
 +         Any two of the parameters, readfds, writefds, or exceptfds, can be
 +         given as null. At least one must be non-null, and any non-null
 +         descriptor set must contain at least one handle to a socket.
 +
 +       We know that we have at least one bit set in at least two fd_sets in
 +       this case, but we may have no bits set in either fds_read or fd_write,
 +       so check for that and handle it.  Luckily, with WinSock, we can _also_
 +       ask how many bits are set on an fd_set.
 +
 +       It is unclear why WinSock doesn't just handle this for us instead of
 +       calling this an error.
 +
 +       Note also that WinSock ignores the first argument, so we don't worry
 +       about the fact that maxfd is computed incorrectly with WinSock (since
 +       curl_socket_t is unsigned in such cases and thus -1 is the largest
 +       value).
 +    */
 +#ifdef USE_WINSOCK
 +    r = select((int)maxfd + 1,
 +               fds_read.fd_count ? &fds_read : NULL,
 +               fds_write.fd_count ? &fds_write : NULL,
 +               &fds_err, ptimeout);
 +#else
 +    r = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout);
 +#endif
 +
 +    if(r != -1)
 +      break;
 +    error = SOCKERRNO;
 +    if(error && ERROR_NOT_EINTR(error))
 +      break;
 +    if(timeout_ms > 0) {
 +      pending_ms = (int)(timeout_ms - ELAPSED_MS());
 +      if(pending_ms <= 0) {
 +        r = 0;  /* Simulate a "call timed out" case */
 +        break;
 +      }
 +    }
 +  } while(r == -1);
 +
 +  if(r < 0)
 +    return -1;
 +  if(r == 0)
 +    return 0;
 +
 +  ret = 0;
 +  if(readfd0 != CURL_SOCKET_BAD) {
 +    if(FD_ISSET(readfd0, &fds_read))
 +      ret |= CURL_CSELECT_IN;
 +    if(FD_ISSET(readfd0, &fds_err))
 +      ret |= CURL_CSELECT_ERR;
 +  }
 +  if(readfd1 != CURL_SOCKET_BAD) {
 +    if(FD_ISSET(readfd1, &fds_read))
 +      ret |= CURL_CSELECT_IN2;
 +    if(FD_ISSET(readfd1, &fds_err))
 +      ret |= CURL_CSELECT_ERR;
 +  }
 +  if(writefd != CURL_SOCKET_BAD) {
 +    if(FD_ISSET(writefd, &fds_write))
 +      ret |= CURL_CSELECT_OUT;
 +    if(FD_ISSET(writefd, &fds_err))
 +      ret |= CURL_CSELECT_ERR;
 +  }
 +
 +  return ret;
 +
 +#endif  /* HAVE_POLL_FINE */
 +
 +}
 +
 +/*
 + * This is a wrapper around poll().  If poll() does not exist, then
 + * select() is used instead.  An error is returned if select() is
 + * being used and a file descriptor is too large for FD_SETSIZE.
 + * A negative timeout value makes this function wait indefinitely,
-  * unles no valid file descriptor is given, when this happens the
++ * unless no valid file descriptor is given, when this happens the
 + * negative timeout is ignored and the function times out immediately.
 + *
 + * Return values:
 + *   -1 = system call error or fd >= FD_SETSIZE
 + *    0 = timeout
 + *    N = number of structures with non zero revent fields
 + */
 +int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
 +{
 +#ifndef HAVE_POLL_FINE
 +  struct timeval pending_tv;
 +  struct timeval *ptimeout;
 +  fd_set fds_read;
 +  fd_set fds_write;
 +  fd_set fds_err;
 +  curl_socket_t maxfd;
 +#endif
 +  struct timeval initial_tv = {0, 0};
 +  bool fds_none = TRUE;
 +  unsigned int i;
 +  int pending_ms = 0;
 +  int error;
 +  int r;
 +
 +  if(ufds) {
 +    for(i = 0; i < nfds; i++) {
 +      if(ufds[i].fd != CURL_SOCKET_BAD) {
 +        fds_none = FALSE;
 +        break;
 +      }
 +    }
 +  }
 +  if(fds_none) {
 +    r = Curl_wait_ms(timeout_ms);
 +    return r;
 +  }
 +
 +  /* Avoid initial timestamp, avoid curlx_tvnow() call, when elapsed
 +     time in this function does not need to be measured. This happens
 +     when function is called with a zero timeout or a negative timeout
 +     value indicating a blocking call should be performed. */
 +
 +  if(timeout_ms > 0) {
 +    pending_ms = timeout_ms;
 +    initial_tv = curlx_tvnow();
 +  }
 +
 +#ifdef HAVE_POLL_FINE
 +
 +  do {
 +    if(timeout_ms < 0)
 +      pending_ms = -1;
 +    else if(!timeout_ms)
 +      pending_ms = 0;
 +    r = poll(ufds, nfds, pending_ms);
 +    if(r != -1)
 +      break;
 +    error = SOCKERRNO;
 +    if(error && ERROR_NOT_EINTR(error))
 +      break;
 +    if(timeout_ms > 0) {
 +      pending_ms = (int)(timeout_ms - ELAPSED_MS());
 +      if(pending_ms <= 0) {
 +        r = 0;  /* Simulate a "call timed out" case */
 +        break;
 +      }
 +    }
 +  } while(r == -1);
 +
 +  if(r < 0)
 +    return -1;
 +  if(r == 0)
 +    return 0;
 +
 +  for(i = 0; i < nfds; i++) {
 +    if(ufds[i].fd == CURL_SOCKET_BAD)
 +      continue;
 +    if(ufds[i].revents & POLLHUP)
 +      ufds[i].revents |= POLLIN;
 +    if(ufds[i].revents & POLLERR)
 +      ufds[i].revents |= (POLLIN|POLLOUT);
 +  }
 +
 +#else  /* HAVE_POLL_FINE */
 +
 +  FD_ZERO(&fds_read);
 +  FD_ZERO(&fds_write);
 +  FD_ZERO(&fds_err);
 +  maxfd = (curl_socket_t)-1;
 +
 +  for(i = 0; i < nfds; i++) {
 +    ufds[i].revents = 0;
 +    if(ufds[i].fd == CURL_SOCKET_BAD)
 +      continue;
 +    VERIFY_SOCK(ufds[i].fd);
 +    if(ufds[i].events & (POLLIN|POLLOUT|POLLPRI|
 +                          POLLRDNORM|POLLWRNORM|POLLRDBAND)) {
 +      if(ufds[i].fd > maxfd)
 +        maxfd = ufds[i].fd;
 +      if(ufds[i].events & (POLLRDNORM|POLLIN))
 +        FD_SET(ufds[i].fd, &fds_read);
 +      if(ufds[i].events & (POLLWRNORM|POLLOUT))
 +        FD_SET(ufds[i].fd, &fds_write);
 +      if(ufds[i].events & (POLLRDBAND|POLLPRI))
 +        FD_SET(ufds[i].fd, &fds_err);
 +    }
 +  }
 +
 +#ifdef USE_WINSOCK
 +  /* WinSock select() can't handle zero events.  See the comment about this in
 +     Curl_check_socket(). */
 +  if(fds_read.fd_count == 0 && fds_write.fd_count == 0
 +     && fds_err.fd_count == 0) {
 +    r = Curl_wait_ms(timeout_ms);
 +    return r;
 +  }
 +#endif
 +
 +  ptimeout = (timeout_ms < 0) ? NULL : &pending_tv;
 +
 +  do {
 +    if(timeout_ms > 0) {
 +      pending_tv.tv_sec = pending_ms / 1000;
 +      pending_tv.tv_usec = (pending_ms % 1000) * 1000;
 +    }
 +    else if(!timeout_ms) {
 +      pending_tv.tv_sec = 0;
 +      pending_tv.tv_usec = 0;
 +    }
 +
 +#ifdef USE_WINSOCK
 +    r = select((int)maxfd + 1,
 +               /* WinSock select() can't handle fd_sets with zero bits set, so
 +                  don't give it such arguments.  See the comment about this in
 +                  Curl_check_socket().
 +               */
 +               fds_read.fd_count ? &fds_read : NULL,
 +               fds_write.fd_count ? &fds_write : NULL,
 +               fds_err.fd_count ? &fds_err : NULL, ptimeout);
 +#else
 +    r = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout);
 +#endif
 +    if(r != -1)
 +      break;
 +    error = SOCKERRNO;
 +    if(error && ERROR_NOT_EINTR(error))
 +      break;
 +    if(timeout_ms > 0) {
 +      pending_ms = timeout_ms - ELAPSED_MS();
 +      if(pending_ms <= 0) {
 +        r = 0;  /* Simulate a "call timed out" case */
 +        break;
 +      }
 +    }
 +  } while(r == -1);
 +
 +  if(r < 0)
 +    return -1;
 +  if(r == 0)
 +    return 0;
 +
 +  r = 0;
 +  for(i = 0; i < nfds; i++) {
 +    ufds[i].revents = 0;
 +    if(ufds[i].fd == CURL_SOCKET_BAD)
 +      continue;
 +    if(FD_ISSET(ufds[i].fd, &fds_read))
 +      ufds[i].revents |= POLLIN;
 +    if(FD_ISSET(ufds[i].fd, &fds_write))
 +      ufds[i].revents |= POLLOUT;
 +    if(FD_ISSET(ufds[i].fd, &fds_err))
 +      ufds[i].revents |= POLLPRI;
 +    if(ufds[i].revents != 0)
 +      r++;
 +  }
 +
 +#endif  /* HAVE_POLL_FINE */
 +
 +  return r;
 +}
 +
 +#ifdef TPF
 +/*
 + * This is a replacement for select() on the TPF platform.
 + * It is used whenever libcurl calls select().
 + * The call below to tpf_process_signals() is required because
 + * TPF's select calls are not signal interruptible.
 + *
 + * Return values are the same as select's.
 + */
 +int tpf_select_libcurl(int maxfds, fd_set* reads, fd_set* writes,
 +                       fd_set* excepts, struct timeval* tv)
 +{
 +   int rc;
 +
 +   rc = tpf_select_bsd(maxfds, reads, writes, excepts, tv);
 +   tpf_process_signals();
 +   return rc;
 +}
 +#endif /* TPF */

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=fd7d521c9d70655618db8232d45e5aaf81700f91
commit fd7d521c9d70655618db8232d45e5aaf81700f91
Author:     Curl Upstream <curl-library at cool.haxx.se>
AuthorDate: Wed Apr 19 07:41:40 2017 +0200
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Thu May 11 11:26:45 2017 -0400

    curl 2017-04-19 (d957e218)
    
    Code extracted from:
    
        https://github.com/curl/curl.git
    
    at commit d957e2189fdc73cef0ff3d1fb58043d354754449 (curl-7_54_0).

diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..562b12e
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1 @@
+* -whitespace
diff --git a/CMake/CurlTests.c b/CMake/CurlTests.c
index ceff391..bc36c8e 100644
--- a/CMake/CurlTests.c
+++ b/CMake/CurlTests.c
@@ -533,3 +533,19 @@ main () {
     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
diff --git a/CMake/FindGSS.cmake b/CMake/FindGSS.cmake
index dfaeaf3..60dcb73 100644
--- a/CMake/FindGSS.cmake
+++ b/CMake/FindGSS.cmake
@@ -12,7 +12,7 @@
 #  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 availabe it'll be set to "unknown"
+#                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)
diff --git a/CMake/FindMbedTLS.cmake b/CMake/FindMbedTLS.cmake
new file mode 100644
index 0000000..a916395
--- /dev/null
+++ b/CMake/FindMbedTLS.cmake
@@ -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)
diff --git a/CMake/Utilities.cmake b/CMake/Utilities.cmake
index 37cdfe3..8b6276d 100644
--- a/CMake/Utilities.cmake
+++ b/CMake/Utilities.cmake
@@ -29,3 +29,16 @@ function(IN_STR_LIST LIST_NAME ITEM_SEARCHED RETVAL)
     set(${RETVAL} TRUE PARENT_SCOPE)
   endif()
 endfunction()
+
+# Returns a list of arguments that evaluate to true
+function(collect_true output_var output_count_var)
+  set(${output_var})
+  foreach(option_var IN LISTS ARGN)
+    if(${option_var})
+      list(APPEND ${output_var} ${option_var})
+    endif()
+  endforeach()
+  set(${output_var} ${${output_var}} PARENT_SCOPE)
+  list(LENGTH ${output_var} ${output_count_var})
+  set(${output_count_var} ${${output_count_var}} PARENT_SCOPE)
+endfunction()
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a6a7368..58d159e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -224,6 +224,8 @@ if(ENABLE_MANUAL)
     message(WARNING "Found no *nroff program")
   endif()
 endif()
+# Required for building manual, docs, tests
+find_package(Perl REQUIRED)
 
 # We need ansi c-flags, especially on HP
 set(CMAKE_C_FLAGS "${CMAKE_ANSI_CFLAGS} ${CMAKE_C_FLAGS}")
@@ -251,7 +253,7 @@ include (CMakeDependentOption)
 
 # On windows preload settings
 if(WIN32)
-  set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -D_WINSOCKAPI_")
+  set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -D_WINSOCKAPI_=")
   include(${CMAKE_CURRENT_SOURCE_DIR}/CMake/Platforms/WindowsCache.cmake)
 endif(WIN32)
 
@@ -289,47 +291,96 @@ endif(NOT NOT_NEED_LIBNSL)
 
 check_function_exists(gethostname HAVE_GETHOSTNAME)
 
-set(OPENSSL_DEFAULT ON)
 if(WIN32)
-  set(OPENSSL_DEFAULT OFF)
   check_library_exists_concat("ws2_32" getch        HAVE_LIBWS2_32)
   check_library_exists_concat("winmm"  getch        HAVE_LIBWINMM)
 endif()
 
-option(CMAKE_USE_OPENSSL "Use OpenSSL code. Experimental" ${OPENSSL_DEFAULT})
-mark_as_advanced(CMAKE_USE_OPENSSL)
+# check SSL libraries
+# TODO support GNUTLS, NSS, POLARSSL, AXTLS, CYASSL
 
+if(APPLE)
+  option(CMAKE_USE_DARWINSSL "enable Apple OS native SSL/TLS" OFF)
+endif()
 if(WIN32)
-  CMAKE_DEPENDENT_OPTION(CURL_WINDOWS_SSPI "Use windows libraries to allow NTLM authentication without openssl" ON
-    "NOT CMAKE_USE_OPENSSL" OFF)
-  mark_as_advanced(CURL_WINDOWS_SSPI)
+  option(CMAKE_USE_WINSSL "enable Windows native SSL/TLS" OFF)
+  cmake_dependent_option(CURL_WINDOWS_SSPI "Use windows libraries to allow NTLM authentication without openssl" ON
+    CMAKE_USE_WINSSL OFF)
 endif()
+option(CMAKE_USE_MBEDTLS "Enable mbedTLS for SSL/TLS" OFF)
 
-set(USE_OPENSSL OFF)
-set(HAVE_LIBCRYPTO OFF)
-set(HAVE_LIBSSL OFF)
+set(openssl_default ON)
+if(WIN32 OR CMAKE_USE_DARWINSSL OR CMAKE_USE_WINSSL OR CMAKE_USE_MBEDTLS)
+  set(openssl_default OFF)
+endif()
+option(CMAKE_USE_OPENSSL "Use OpenSSL code. Experimental" ${openssl_default})
+
+collect_true(enabled_ssl_options enabled_ssl_options_count
+  CMAKE_USE_WINSSL
+  CMAKE_USE_DARWINSSL
+  CMAKE_USE_OPENSSL
+  CMAKE_USE_MBEDTLS
+)
+if(enabled_ssl_options_count GREATER 1)
+  message(FATAL_ERROR "Multiple SSL options specified: ${enabled_ssl_options}. Please pick at most one and disable the rest.")
+endif()
 
-if(CMAKE_USE_OPENSSL)
-  find_package(OpenSSL)
-  if(OPENSSL_FOUND)
-    list(APPEND CURL_LIBS ${OPENSSL_LIBRARIES})
-    set(USE_OPENSSL ON)
-    set(HAVE_LIBCRYPTO ON)
-    set(HAVE_LIBSSL ON)
-    include_directories(${OPENSSL_INCLUDE_DIR})
-    set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
-    check_include_file("openssl/crypto.h" HAVE_OPENSSL_CRYPTO_H)
-    check_include_file("openssl/engine.h" HAVE_OPENSSL_ENGINE_H)
-    check_include_file("openssl/err.h"    HAVE_OPENSSL_ERR_H)
-    check_include_file("openssl/pem.h"    HAVE_OPENSSL_PEM_H)
-    check_include_file("openssl/pkcs12.h" HAVE_OPENSSL_PKCS12_H)
-    check_include_file("openssl/rsa.h"    HAVE_OPENSSL_RSA_H)
-    check_include_file("openssl/ssl.h"    HAVE_OPENSSL_SSL_H)
-    check_include_file("openssl/x509.h"   HAVE_OPENSSL_X509_H)
-    check_include_file("openssl/rand.h"   HAVE_OPENSSL_RAND_H)
-  elseif(WIN32)
-    set(CURL_WINDOWS_SSPI ON)
+if(CMAKE_USE_WINSSL)
+  set(SSL_ENABLED ON)
+  set(USE_SCHANNEL ON) # Windows native SSL/TLS support
+  set(USE_WINDOWS_SSPI ON) # CMAKE_USE_WINSSL implies CURL_WINDOWS_SSPI
+  list(APPEND CURL_LIBS "crypt32")
+endif()
+if(CURL_WINDOWS_SSPI)
+  set(USE_WINDOWS_SSPI ON)
+  set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -DSECURITY_WIN32")
+endif()
+
+if(CMAKE_USE_DARWINSSL)
+  find_library(COREFOUNDATION_FRAMEWORK "CoreFoundation")
+  if(NOT COREFOUNDATION_FRAMEWORK)
+      message(FATAL_ERROR "CoreFoundation framework not found")
+  endif()
+
+  find_library(SECURITY_FRAMEWORK "Security")
+  if(NOT SECURITY_FRAMEWORK)
+     message(FATAL_ERROR "Security framework not found")
   endif()
+
+  set(SSL_ENABLED ON)
+  set(USE_DARWINSSL ON)
+  list(APPEND CURL_LIBS "${COREFOUNDATION_FRAMEWORK}" "${SECURITY_FRAMEWORK}")
+endif()
+
+if(CMAKE_USE_OPENSSL)
+  find_package(OpenSSL REQUIRED)
+  set(SSL_ENABLED ON)
+  set(USE_OPENSSL ON)
+  set(HAVE_LIBCRYPTO ON)
+  set(HAVE_LIBSSL ON)
+  list(APPEND CURL_LIBS ${OPENSSL_LIBRARIES})
+  include_directories(${OPENSSL_INCLUDE_DIR})
+  set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
+  check_include_file("openssl/crypto.h" HAVE_OPENSSL_CRYPTO_H)
+  check_include_file("openssl/engine.h" HAVE_OPENSSL_ENGINE_H)
+  check_include_file("openssl/err.h"    HAVE_OPENSSL_ERR_H)
+  check_include_file("openssl/pem.h"    HAVE_OPENSSL_PEM_H)
+  check_include_file("openssl/pkcs12.h" HAVE_OPENSSL_PKCS12_H)
+  check_include_file("openssl/rsa.h"    HAVE_OPENSSL_RSA_H)
+  check_include_file("openssl/ssl.h"    HAVE_OPENSSL_SSL_H)
+  check_include_file("openssl/x509.h"   HAVE_OPENSSL_X509_H)
+  check_include_file("openssl/rand.h"   HAVE_OPENSSL_RAND_H)
+  check_symbol_exists(RAND_status "${CURL_INCLUDES}" HAVE_RAND_STATUS)
+  check_symbol_exists(RAND_screen "${CURL_INCLUDES}" HAVE_RAND_SCREEN)
+  check_symbol_exists(RAND_egd    "${CURL_INCLUDES}" HAVE_RAND_EGD)
+endif()
+
+if(CMAKE_USE_MBEDTLS)
+  find_package(MbedTLS REQUIRED)
+  set(SSL_ENABLED ON)
+  set(USE_MBEDTLS ON)
+  list(APPEND CURL_LIBS ${MBEDTLS_LIBRARIES})
+  include_directories(${MBEDTLS_INCLUDE_DIR})
 endif()
 
 option(USE_NGHTTP2 "Use Nghttp2 library" OFF)
@@ -578,18 +629,8 @@ if(NOT UNIX)
   check_include_file_concat("winsock.h"      HAVE_WINSOCK_H)
   check_include_file_concat("ws2tcpip.h"     HAVE_WS2TCPIP_H)
   check_include_file_concat("winsock2.h"     HAVE_WINSOCK2_H)
-  if(CURL_WINDOWS_SSPI)
-    set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -DSECURITY_WIN32")
-    check_include_file_concat("sspi.h"       HAVE_SSPI_H)
-    if(HAVE_SSPI_H)
-      check_include_file_concat("schannel.h" HAVE_SCHANNEL_H)
-      set(USE_WINDOWS_SSPI ON)
-      if(HAVE_SCHANNEL_H)
-        set(USE_SCHANNEL ON)
-        set(SSL_ENABLED ON)
-        set(CURL_LIBS ${CURL_LIBS} "crypt32")
-      endif()
-    endif()
+  if(NOT CURL_WINDOWS_SSPI AND USE_OPENSSL)
+    set(CURL_LIBS ${CURL_LIBS} "crypt32")
   endif()
 endif(NOT UNIX)
 
@@ -609,6 +650,7 @@ check_include_file_concat("sys/types.h"      HAVE_SYS_TYPES_H)
 check_include_file_concat("sys/uio.h"        HAVE_SYS_UIO_H)
 check_include_file_concat("sys/un.h"         HAVE_SYS_UN_H)
 check_include_file_concat("sys/utime.h"      HAVE_SYS_UTIME_H)
+check_include_file_concat("sys/xattr.h"      HAVE_SYS_XATTR_H)
 check_include_file_concat("alloca.h"         HAVE_ALLOCA_H)
 check_include_file_concat("arpa/inet.h"      HAVE_ARPA_INET_H)
 check_include_file_concat("arpa/tftp.h"      HAVE_ARPA_TFTP_H)
@@ -778,14 +820,6 @@ check_symbol_exists(strlcat       "${CURL_INCLUDES}" HAVE_STRLCAT)
 check_symbol_exists(getpwuid      "${CURL_INCLUDES}" HAVE_GETPWUID)
 check_symbol_exists(geteuid       "${CURL_INCLUDES}" HAVE_GETEUID)
 check_symbol_exists(utime         "${CURL_INCLUDES}" HAVE_UTIME)
-if(CMAKE_USE_OPENSSL)
-  check_symbol_exists(RAND_status   "${CURL_INCLUDES}" HAVE_RAND_STATUS)
-  check_symbol_exists(RAND_screen   "${CURL_INCLUDES}" HAVE_RAND_SCREEN)
-  check_symbol_exists(RAND_egd      "${CURL_INCLUDES}" HAVE_RAND_EGD)
-  if(HAVE_LIBCRYPTO AND HAVE_LIBSSL)
-    set(USE_OPENSSL 1)
-  endif(HAVE_LIBCRYPTO AND HAVE_LIBSSL)
-endif(CMAKE_USE_OPENSSL)
 check_symbol_exists(gmtime_r      "${CURL_INCLUDES}" HAVE_GMTIME_R)
 check_symbol_exists(localtime_r   "${CURL_INCLUDES}" HAVE_LOCALTIME_R)
 
@@ -820,6 +854,13 @@ check_symbol_exists(setsockopt     "${CURL_INCLUDES}" HAVE_SETSOCKOPT)
 # symbol exists in win32, but function does not.
 check_function_exists(inet_pton HAVE_INET_PTON)
 
+check_symbol_exists(fsetxattr "${CURL_INCLUDES}" HAVE_FSETXATTR)
+if(HAVE_FSETXATTR)
+  foreach(CURL_TEST HAVE_FSETXATTR_5 HAVE_FSETXATTR_6)
+    curl_internal_test_run(${CURL_TEST})
+  endforeach(CURL_TEST)
+endif(HAVE_FSETXATTR)
+
 # sigaction and sigsetjmp are special. Use special mechanism for
 # detecting those, but only if previous attempt failed.
 if(HAVE_SIGNAL_H)
@@ -1033,9 +1074,9 @@ function(TRANSFORM_MAKEFILE_INC INPUT_FILE OUTPUT_FILE)
   string(REPLACE "$(top_srcdir)"   "\${CURL_SOURCE_DIR}" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})
   string(REPLACE "$(top_builddir)" "\${CURL_BINARY_DIR}" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})
 
-  string(REGEX REPLACE "\\\\\n" "§!§" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})
+  string(REGEX REPLACE "\\\\\n" "!π!α!" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})
   string(REGEX REPLACE "([a-zA-Z_][a-zA-Z0-9_]*)[\t ]*=[\t ]*([^\n]*)" "SET(\\1 \\2)" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})
-  string(REPLACE "§!§" "\n" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})
+  string(REPLACE "!π!α!" "\n" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})
 
   string(REGEX REPLACE "\\$\\(([a-zA-Z_][a-zA-Z0-9_]*)\\)" "\${\\1}" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})    # Replace $() with ${}
   string(REGEX REPLACE "@([a-zA-Z_][a-zA-Z0-9_]*)@" "\${\\1}" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})    # Replace @@ with ${}, even if that may not be read by CMake scripts.
@@ -1043,6 +1084,7 @@ function(TRANSFORM_MAKEFILE_INC INPUT_FILE OUTPUT_FILE)
 
 endfunction()
 
+add_subdirectory(docs)
 add_subdirectory(lib)
 if(BUILD_CURL_EXE)
   add_subdirectory(src)
@@ -1053,11 +1095,6 @@ if(BUILD_TESTING)
   add_subdirectory(tests)
 endif()
 
-# TODO support GNUTLS, NSS, POLARSSL, AXTLS, CYASSL, WINSSL, DARWINSSL
-if(USE_OPENSSL)
-  set(SSL_ENABLED 1)
-endif()
-
 # Helper to populate a list (_items) with a label when conditions (the remaining
 # args) are satisfied
 function(_add_if label)
@@ -1071,6 +1108,8 @@ endfunction()
 set(_items)
 _add_if("WinSSL"        SSL_ENABLED AND USE_WINDOWS_SSPI)
 _add_if("OpenSSL"       SSL_ENABLED AND USE_OPENSSL)
+_add_if("DarwinSSL"     SSL_ENABLED AND USE_DARWINSSL)
+_add_if("mbedTLS"       SSL_ENABLED AND USE_MBEDTLS)
 _add_if("IPv6"          ENABLE_IPV6)
 _add_if("unix-sockets"  USE_UNIX_SOCKETS)
 _add_if("libz"          HAVE_LIBZ)
@@ -1087,9 +1126,9 @@ _add_if("SPNEGO"        NOT CURL_DISABLE_CRYPTO_AUTH AND
 _add_if("Kerberos"      NOT CURL_DISABLE_CRYPTO_AUTH AND
                         (HAVE_GSSAPI OR USE_WINDOWS_SSPI))
 # NTLM support requires crypto function adaptions from various SSL libs
-# TODO alternative SSL libs tests for SSP1, GNUTLS, NSS, DARWINSSL
+# TODO alternative SSL libs tests for SSP1, GNUTLS, NSS
 if(NOT CURL_DISABLE_CRYPTO_AUTH AND (USE_OPENSSL OR
-   USE_WINDOWS_SSPI OR GNUTLS_ENABLED OR NSS_ENABLED OR DARWINSSL_ENABLED))
+   USE_WINDOWS_SSPI OR GNUTLS_ENABLED OR NSS_ENABLED OR USE_DARWINSSL OR USE_MBEDTLS))
   _add_if("NTLM"        1)
   # TODO missing option (autoconf: --enable-ntlm-wb)
   _add_if("NTLM_WB"     NOT CURL_DISABLE_HTTP AND NTLM_WB_ENABLED)
diff --git a/COPYING b/COPYING
index a98663e..1e45a5e 100644
--- a/COPYING
+++ b/COPYING
@@ -1,6 +1,6 @@
 COPYRIGHT AND PERMISSION NOTICE
 
-Copyright (c) 1996 - 2016, Daniel Stenberg, <daniel at haxx.se>, and many
+Copyright (c) 1996 - 2017, Daniel Stenberg, <daniel at haxx.se>, and many
 contributors, see the THANKS file.
 
 All rights reserved.
diff --git a/include/curl/curl.h b/include/curl/curl.h
index 5b4ae46..1030712 100644
--- a/include/curl/curl.h
+++ b/include/curl/curl.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
@@ -35,6 +35,7 @@
 #endif
 
 #include "curlver.h"         /* libcurl version defines   */
+#include "system.h"          /* determine things run-time */
 #include "curlbuild.h"       /* libcurl build definitions */
 #include "curlrules.h"       /* libcurl rules enforcement */
 
@@ -193,6 +194,11 @@ typedef int (*curl_xferinfo_callback)(void *clientp,
                                       curl_off_t ultotal,
                                       curl_off_t ulnow);
 
+#ifndef CURL_MAX_READ_SIZE
+  /* The maximum receive buffer size configurable via CURLOPT_BUFFERSIZE. */
+#define CURL_MAX_READ_SIZE 524288
+#endif
+
 #ifndef CURL_MAX_WRITE_SIZE
   /* Tests have proven that 20K is a very bad buffer size for uploads on
      Windows, while 16K for some odd reason performed a lot better.
@@ -479,7 +485,7 @@ typedef enum {
   CURLE_LDAP_CANNOT_BIND,        /* 38 */
   CURLE_LDAP_SEARCH_FAILED,      /* 39 */
   CURLE_OBSOLETE40,              /* 40 - NOT USED */
-  CURLE_FUNCTION_NOT_FOUND,      /* 41 */
+  CURLE_FUNCTION_NOT_FOUND,      /* 41 - NOT USED starting with 7.53.0 */
   CURLE_ABORTED_BY_CALLBACK,     /* 42 */
   CURLE_BAD_FUNCTION_ARGUMENT,   /* 43 */
   CURLE_OBSOLETE44,              /* 44 - NOT USED */
@@ -1595,7 +1601,7 @@ typedef enum {
   CINIT(DNS_SERVERS, STRINGPOINT, 211),
 
   /* Time-out accept operations (currently for FTP only) after this amount
-     of miliseconds. */
+     of milliseconds. */
   CINIT(ACCEPTTIMEOUT_MS, LONG, 212),
 
   /* Set TCP keepalive */
@@ -1770,6 +1776,12 @@ typedef enum {
      this option is used only if PROXY_SSL_VERIFYPEER is true */
   CINIT(PROXY_PINNEDPUBLICKEY, STRINGPOINT, 263),
 
+  /* Path to an abstract Unix domain socket */
+  CINIT(ABSTRACT_UNIX_SOCKET, STRINGPOINT, 264),
+
+  /* Suppress proxy CONNECT response headers from user callbacks */
+  CINIT(SUPPRESS_CONNECT_HEADERS, LONG, 265),
+
   CURLOPT_LASTENTRY /* the last unused */
 } CURLoption;
 
@@ -1876,6 +1888,18 @@ enum {
   CURL_SSLVERSION_LAST /* never use, keep last */
 };
 
+enum {
+  CURL_SSLVERSION_MAX_NONE =     0,
+  CURL_SSLVERSION_MAX_DEFAULT =  (CURL_SSLVERSION_TLSv1   << 16),
+  CURL_SSLVERSION_MAX_TLSv1_0 =  (CURL_SSLVERSION_TLSv1_0 << 16),
+  CURL_SSLVERSION_MAX_TLSv1_1 =  (CURL_SSLVERSION_TLSv1_1 << 16),
+  CURL_SSLVERSION_MAX_TLSv1_2 =  (CURL_SSLVERSION_TLSv1_2 << 16),
+  CURL_SSLVERSION_MAX_TLSv1_3 =  (CURL_SSLVERSION_TLSv1_3 << 16),
+
+  /* never use, keep last */
+  CURL_SSLVERSION_MAX_LAST =     (CURL_SSLVERSION_LAST    << 16)
+};
+
 enum CURL_TLSAUTH {
   CURL_TLSAUTH_NONE,
   CURL_TLSAUTH_SRP,
@@ -2438,7 +2462,7 @@ typedef struct {
 #define CURL_VERSION_CURLDEBUG    (1<<13) /* Debug memory tracking supported */
 #define CURL_VERSION_TLSAUTH_SRP  (1<<14) /* TLS-SRP auth is supported */
 #define CURL_VERSION_NTLM_WB      (1<<15) /* NTLM delegation to winbind helper
-                                             is suported */
+                                             is supported */
 #define CURL_VERSION_HTTP2        (1<<16) /* HTTP2 support built-in */
 #define CURL_VERSION_GSSAPI       (1<<17) /* Built against a GSS-API library */
 #define CURL_VERSION_KERBEROS5    (1<<18) /* Kerberos V5 auth is supported */
diff --git a/include/curl/curlrules.h b/include/curl/curlrules.h
index 55d21f6..0abd9f7 100644
--- a/include/curl/curlrules.h
+++ b/include/curl/curlrules.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
@@ -105,11 +105,6 @@
    Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_is_missing
 #endif
 
-#ifndef CURL_FORMAT_OFF_T
-#  error "CURL_FORMAT_OFF_T definition is missing!"
-   Error Compilation_aborted_CURL_FORMAT_OFF_T_is_missing
-#endif
-
 #ifndef CURL_SIZEOF_CURL_OFF_T
 #  error "CURL_SIZEOF_CURL_OFF_T definition is missing!"
    Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_is_missing
@@ -241,22 +236,4 @@ typedef char
 #undef CurlchkszEQ
 #undef CurlchkszGE
 
-/*
- * Get rid of macros not intended to exist beyond this point.
- */
-
-#undef CURL_PULL_WS2TCPIP_H
-#undef CURL_PULL_SYS_TYPES_H
-#undef CURL_PULL_SYS_SOCKET_H
-#undef CURL_PULL_SYS_POLL_H
-#undef CURL_PULL_STDINT_H
-#undef CURL_PULL_INTTYPES_H
-
-#undef CURL_TYPEOF_CURL_SOCKLEN_T
-#undef CURL_TYPEOF_CURL_OFF_T
-
-#ifdef CURL_NO_OLDIES
-#undef CURL_FORMAT_OFF_T /* not required since 7.19.0 - obsoleted in 7.20.0 */
-#endif
-
 #endif /* __CURL_CURLRULES_H */
diff --git a/include/curl/curlver.h b/include/curl/curlver.h
index 9126641..7beda3f 100644
--- a/include/curl/curlver.h
+++ b/include/curl/curlver.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
@@ -26,17 +26,17 @@
    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 - 2016 Daniel Stenberg, <daniel at haxx.se>."
+#define LIBCURL_COPYRIGHT "1996 - 2017 Daniel Stenberg, <daniel at haxx.se>."
 
 /* This is the version number of the libcurl package from which this header
    file origins: */
-#define LIBCURL_VERSION "7.52.1-DEV"
+#define LIBCURL_VERSION "7.54.0-DEV"
 
 /* The numeric version number is also available "in parts" by using these
    defines: */
 #define LIBCURL_VERSION_MAJOR 7
-#define LIBCURL_VERSION_MINOR 52
-#define LIBCURL_VERSION_PATCH 1
+#define LIBCURL_VERSION_MINOR 54
+#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
@@ -57,7 +57,7 @@
    CURL_VERSION_BITS() macro since curl's own configure script greps for it
    and needs it to contain the full number.
 */
-#define LIBCURL_VERSION_NUM 0x073401
+#define LIBCURL_VERSION_NUM 0x073600
 
 /*
  * This is the date and time when the full source package was created. The
diff --git a/include/curl/multi.h b/include/curl/multi.h
index d1e00cc..f93e511 100644
--- a/include/curl/multi.h
+++ b/include/curl/multi.h
@@ -218,7 +218,7 @@ CURL_EXTERN CURLMcode curl_multi_cleanup(CURLM *multi_handle);
  *          curl_multi_cleanup().
  *
  *          The 'CURLMsg' struct is meant to be very simple and only contain
- *          very basic informations. If more involved information is wanted,
+ *          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
diff --git a/include/curl/system.h b/include/curl/system.h
new file mode 100644
index 0000000..ed3a55c
--- /dev/null
+++ b/include/curl/system.h
@@ -0,0 +1,484 @@
+#ifndef __CURL_SYSTEM_H
+#define __CURL_SYSTEM_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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 is supposed to eventually replace curlbuild.h. This little one
+ * is still learning.  During the experimental phase, this header files
+ * defines symbols using the prefixes CURLSYS_ or curlsys_. When we feel
+ * confident enough, we replace curlbuild.h with this file and rename all
+ * prefixes to CURL_ and curl_.
+ */
+
+/*
+ * 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 CURLSYS_SIZEOF_LONG           4
+#    define CURLSYS_TYPEOF_CURL_OFF_T     long long
+#    define CURLSYS_FORMAT_CURL_OFF_T     "lld"
+#    define CURLSYS_FORMAT_CURL_OFF_TU    "llu"
+#    define CURLSYS_SIZEOF_CURL_OFF_T     8
+#    define CURLSYS_SUFFIX_CURL_OFF_T     LL
+#    define CURLSYS_SUFFIX_CURL_OFF_TU    ULL
+#  else
+#    define CURLSYS_SIZEOF_LONG           4
+#    define CURLSYS_TYPEOF_CURL_OFF_T     long
+#    define CURLSYS_FORMAT_CURL_OFF_T     "ld"
+#    define CURLSYS_FORMAT_CURL_OFF_TU    "lu"
+#    define CURLSYS_SIZEOF_CURL_OFF_T     4
+#    define CURLSYS_SUFFIX_CURL_OFF_T     L
+#    define CURLSYS_SUFFIX_CURL_OFF_TU    UL
+#  endif
+#  define CURLSYS_TYPEOF_CURL_SOCKLEN_T int
+#  define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4
+
+#elif defined(__SALFORDC__)
+#  define CURLSYS_SIZEOF_LONG           4
+#  define CURLSYS_TYPEOF_CURL_OFF_T     long
+#  define CURLSYS_FORMAT_CURL_OFF_T     "ld"
+#  define CURLSYS_FORMAT_CURL_OFF_TU    "lu"
+#  define CURLSYS_SIZEOF_CURL_OFF_T     4
+#  define CURLSYS_SUFFIX_CURL_OFF_T     L
+#  define CURLSYS_SUFFIX_CURL_OFF_TU    UL
+#  define CURLSYS_TYPEOF_CURL_SOCKLEN_T int
+#  define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4
+
+#elif defined(__BORLANDC__)
+#  if (__BORLANDC__ < 0x520)
+#    define CURLSYS_SIZEOF_LONG           4
+#    define CURLSYS_TYPEOF_CURL_OFF_T     long
+#    define CURLSYS_FORMAT_CURL_OFF_T     "ld"
+#    define CURLSYS_FORMAT_CURL_OFF_TU    "lu"
+#    define CURLSYS_SIZEOF_CURL_OFF_T     4
+#    define CURLSYS_SUFFIX_CURL_OFF_T     L
+#    define CURLSYS_SUFFIX_CURL_OFF_TU    UL
+#  else
+#    define CURLSYS_SIZEOF_LONG           4
+#    define CURLSYS_TYPEOF_CURL_OFF_T     __int64
+#    define CURLSYS_FORMAT_CURL_OFF_T     "I64d"
+#    define CURLSYS_FORMAT_CURL_OFF_TU    "I64u"
+#    define CURLSYS_SIZEOF_CURL_OFF_T     8
+#    define CURLSYS_SUFFIX_CURL_OFF_T     i64
+#    define CURLSYS_SUFFIX_CURL_OFF_TU    ui64
+#  endif
+#  define CURLSYS_TYPEOF_CURL_SOCKLEN_T int
+#  define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4
+
+#elif defined(__TURBOC__)
+#  define CURLSYS_SIZEOF_LONG           4
+#  define CURLSYS_TYPEOF_CURL_OFF_T     long
+#  define CURLSYS_FORMAT_CURL_OFF_T     "ld"
+#  define CURLSYS_FORMAT_CURL_OFF_TU    "lu"
+#  define CURLSYS_SIZEOF_CURL_OFF_T     4
+#  define CURLSYS_SUFFIX_CURL_OFF_T     L
+#  define CURLSYS_SUFFIX_CURL_OFF_TU    UL
+#  define CURLSYS_TYPEOF_CURL_SOCKLEN_T int
+#  define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4
+
+#elif defined(__WATCOMC__)
+#  if defined(__386__)
+#    define CURLSYS_SIZEOF_LONG           4
+#    define CURLSYS_TYPEOF_CURL_OFF_T     __int64
+#    define CURLSYS_FORMAT_CURL_OFF_T     "I64d"
+#    define CURLSYS_FORMAT_CURL_OFF_TU    "I64u"
+#    define CURLSYS_SIZEOF_CURL_OFF_T     8
+#    define CURLSYS_SUFFIX_CURL_OFF_T     i64
+#    define CURLSYS_SUFFIX_CURL_OFF_TU    ui64
+#  else
+#    define CURLSYS_SIZEOF_LONG           4
+#    define CURLSYS_TYPEOF_CURL_OFF_T     long
+#    define CURLSYS_FORMAT_CURL_OFF_T     "ld"
+#    define CURLSYS_FORMAT_CURL_OFF_TU    "lu"
+#    define CURLSYS_SIZEOF_CURL_OFF_T     4
+#    define CURLSYS_SUFFIX_CURL_OFF_T     L
+#    define CURLSYS_SUFFIX_CURL_OFF_TU    UL
+#  endif
+#  define CURLSYS_TYPEOF_CURL_SOCKLEN_T int
+#  define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4
+
+#elif defined(__POCC__)
+#  if (__POCC__ < 280)
+#    define CURLSYS_SIZEOF_LONG           4
+#    define CURLSYS_TYPEOF_CURL_OFF_T     long
+#    define CURLSYS_FORMAT_CURL_OFF_T     "ld"
+#    define CURLSYS_FORMAT_CURL_OFF_TU    "lu"
+#    define CURLSYS_SIZEOF_CURL_OFF_T     4
+#    define CURLSYS_SUFFIX_CURL_OFF_T     L
+#    define CURLSYS_SUFFIX_CURL_OFF_TU    UL
+#  elif defined(_MSC_VER)
+#    define CURLSYS_SIZEOF_LONG           4
+#    define CURLSYS_TYPEOF_CURL_OFF_T     __int64
+#    define CURLSYS_FORMAT_CURL_OFF_T     "I64d"
+#    define CURLSYS_FORMAT_CURL_OFF_TU    "I64u"
+#    define CURLSYS_SIZEOF_CURL_OFF_T     8
+#    define CURLSYS_SUFFIX_CURL_OFF_T     i64
+#    define CURLSYS_SUFFIX_CURL_OFF_TU    ui64
+#  else
+#    define CURLSYS_SIZEOF_LONG           4
+#    define CURLSYS_TYPEOF_CURL_OFF_T     long long
+#    define CURLSYS_FORMAT_CURL_OFF_T     "lld"
+#    define CURLSYS_FORMAT_CURL_OFF_TU    "llu"
+#    define CURLSYS_SIZEOF_CURL_OFF_T     8
+#    define CURLSYS_SUFFIX_CURL_OFF_T     LL
+#    define CURLSYS_SUFFIX_CURL_OFF_TU    ULL
+#  endif
+#  define CURLSYS_TYPEOF_CURL_SOCKLEN_T int
+#  define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4
+
+#elif defined(__LCC__)
+#  define CURLSYS_SIZEOF_LONG           4
+#  define CURLSYS_TYPEOF_CURL_OFF_T     long
+#  define CURLSYS_FORMAT_CURL_OFF_T     "ld"
+#  define CURLSYS_FORMAT_CURL_OFF_TU    "lu"
+#  define CURLSYS_SIZEOF_CURL_OFF_T     4
+#  define CURLSYS_SUFFIX_CURL_OFF_T     L
+#  define CURLSYS_SUFFIX_CURL_OFF_TU    UL
+#  define CURLSYS_TYPEOF_CURL_SOCKLEN_T int
+#  define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4
+
+#elif defined(__SYMBIAN32__)
+#  if defined(__EABI__)  /* Treat all ARM compilers equally */
+#    define CURLSYS_SIZEOF_LONG           4
+#    define CURLSYS_TYPEOF_CURL_OFF_T     long long
+#    define CURLSYS_FORMAT_CURL_OFF_T     "lld"
+#    define CURLSYS_FORMAT_CURL_OFF_TU    "llu"
+#    define CURLSYS_SIZEOF_CURL_OFF_T     8
+#    define CURLSYS_SUFFIX_CURL_OFF_T     LL
+#    define CURLSYS_SUFFIX_CURL_OFF_TU    ULL
+#  elif defined(__CW32__)
+#    pragma longlong on
+#    define CURLSYS_SIZEOF_LONG           4
+#    define CURLSYS_TYPEOF_CURL_OFF_T     long long
+#    define CURLSYS_FORMAT_CURL_OFF_T     "lld"
+#    define CURLSYS_FORMAT_CURL_OFF_TU    "llu"
+#    define CURLSYS_SIZEOF_CURL_OFF_T     8
+#    define CURLSYS_SUFFIX_CURL_OFF_T     LL
+#    define CURLSYS_SUFFIX_CURL_OFF_TU    ULL
+#  elif defined(__VC32__)
+#    define CURLSYS_SIZEOF_LONG           4
+#    define CURLSYS_TYPEOF_CURL_OFF_T     __int64
+#    define CURLSYS_FORMAT_CURL_OFF_T     "lld"
+#    define CURLSYS_FORMAT_CURL_OFF_TU    "llu"
+#    define CURLSYS_SIZEOF_CURL_OFF_T     8
+#    define CURLSYS_SUFFIX_CURL_OFF_T     LL
+#    define CURLSYS_SUFFIX_CURL_OFF_TU    ULL
+#  endif
+#  define CURLSYS_TYPEOF_CURL_SOCKLEN_T unsigned int
+#  define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4
+
+#elif defined(__MWERKS__)
+#  define CURLSYS_SIZEOF_LONG           4
+#  define CURLSYS_TYPEOF_CURL_OFF_T     long long
+#  define CURLSYS_FORMAT_CURL_OFF_T     "lld"
+#  define CURLSYS_FORMAT_CURL_OFF_TU    "llu"
+#  define CURLSYS_SIZEOF_CURL_OFF_T     8
+#  define CURLSYS_SUFFIX_CURL_OFF_T     LL
+#  define CURLSYS_SUFFIX_CURL_OFF_TU    ULL
+#  define CURLSYS_TYPEOF_CURL_SOCKLEN_T int
+#  define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4
+
+#elif defined(_WIN32_WCE)
+#  define CURLSYS_SIZEOF_LONG           4
+#  define CURLSYS_TYPEOF_CURL_OFF_T     __int64
+#  define CURLSYS_FORMAT_CURL_OFF_T     "I64d"
+#  define CURLSYS_FORMAT_CURL_OFF_TU    "I64u"
+#  define CURLSYS_SIZEOF_CURL_OFF_T     8
+#  define CURLSYS_SUFFIX_CURL_OFF_T     i64
+#  define CURLSYS_SUFFIX_CURL_OFF_TU    ui64
+#  define CURLSYS_TYPEOF_CURL_SOCKLEN_T int
+#  define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4
+
+#elif defined(__MINGW32__)
+#  define CURLSYS_SIZEOF_LONG           4
+#  define CURLSYS_TYPEOF_CURL_OFF_T     long long
+#  define CURLSYS_FORMAT_CURL_OFF_T     "I64d"
+#  define CURLSYS_FORMAT_CURL_OFF_TU    "I64u"
+#  define CURLSYS_SIZEOF_CURL_OFF_T     8
+#  define CURLSYS_SUFFIX_CURL_OFF_T     LL
+#  define CURLSYS_SUFFIX_CURL_OFF_TU    ULL
+#  define CURLSYS_TYPEOF_CURL_SOCKLEN_T socklen_t
+#  define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4
+#  define CURLSYS_PULL_SYS_TYPES_H      1
+#  define CURLSYS_PULL_WS2TCPIP_H       1
+
+#elif defined(__VMS)
+#  if defined(__VAX)
+#    define CURLSYS_SIZEOF_LONG           4
+#    define CURLSYS_TYPEOF_CURL_OFF_T     long
+#    define CURLSYS_FORMAT_CURL_OFF_T     "ld"
+#    define CURLSYS_FORMAT_CURL_OFF_TU    "lu"
+#    define CURLSYS_SIZEOF_CURL_OFF_T     4
+#    define CURLSYS_SUFFIX_CURL_OFF_T     L
+#    define CURLSYS_SUFFIX_CURL_OFF_TU    UL
+#  else
+#    define CURLSYS_SIZEOF_LONG           4
+#    define CURLSYS_TYPEOF_CURL_OFF_T     long long
+#    define CURLSYS_FORMAT_CURL_OFF_T     "lld"
+#    define CURLSYS_FORMAT_CURL_OFF_TU    "llu"
+#    define CURLSYS_SIZEOF_CURL_OFF_T     8
+#    define CURLSYS_SUFFIX_CURL_OFF_T     LL
+#    define CURLSYS_SUFFIX_CURL_OFF_TU    ULL
+#  endif
+#  define CURLSYS_TYPEOF_CURL_SOCKLEN_T unsigned int
+#  define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4
+
+#elif defined(__OS400__)
+#  if defined(__ILEC400__)
+#    define CURLSYS_SIZEOF_LONG           4
+#    define CURLSYS_TYPEOF_CURL_OFF_T     long long
+#    define CURLSYS_FORMAT_CURL_OFF_T     "lld"
+#    define CURLSYS_FORMAT_CURL_OFF_TU    "llu"
+#    define CURLSYS_SIZEOF_CURL_OFF_T     8
+#    define CURLSYS_SUFFIX_CURL_OFF_T     LL
+#    define CURLSYS_SUFFIX_CURL_OFF_TU    ULL
+#    define CURLSYS_TYPEOF_CURL_SOCKLEN_T socklen_t
+#    define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4
+#    define CURLSYS_PULL_SYS_TYPES_H      1
+#    define CURLSYS_PULL_SYS_SOCKET_H     1
+#  endif
+
+#elif defined(__MVS__)
+#  if defined(__IBMC__) || defined(__IBMCPP__)
+#    if defined(_ILP32)
+#      define CURLSYS_SIZEOF_LONG           4
+#    elif defined(_LP64)
+#      define CURLSYS_SIZEOF_LONG           8
+#    endif
+#    if defined(_LONG_LONG)
+#      define CURLSYS_TYPEOF_CURL_OFF_T     long long
+#      define CURLSYS_FORMAT_CURL_OFF_T     "lld"
+#      define CURLSYS_FORMAT_CURL_OFF_TU    "llu"
+#      define CURLSYS_SIZEOF_CURL_OFF_T     8
+#      define CURLSYS_SUFFIX_CURL_OFF_T     LL
+#      define CURLSYS_SUFFIX_CURL_OFF_TU    ULL
+#    elif defined(_LP64)
+#      define CURLSYS_TYPEOF_CURL_OFF_T     long
+#      define CURLSYS_FORMAT_CURL_OFF_T     "ld"
+#      define CURLSYS_FORMAT_CURL_OFF_TU    "lu"
+#      define CURLSYS_SIZEOF_CURL_OFF_T     8
+#      define CURLSYS_SUFFIX_CURL_OFF_T     L
+#      define CURLSYS_SUFFIX_CURL_OFF_TU    UL
+#    else
+#      define CURLSYS_TYPEOF_CURL_OFF_T     long
+#      define CURLSYS_FORMAT_CURL_OFF_T     "ld"
+#      define CURLSYS_FORMAT_CURL_OFF_TU    "lu"
+#      define CURLSYS_SIZEOF_CURL_OFF_T     4
+#      define CURLSYS_SUFFIX_CURL_OFF_T     L
+#      define CURLSYS_SUFFIX_CURL_OFF_TU    UL
+#    endif
+#    define CURLSYS_TYPEOF_CURL_SOCKLEN_T socklen_t
+#    define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4
+#    define CURLSYS_PULL_SYS_TYPES_H      1
+#    define CURLSYS_PULL_SYS_SOCKET_H     1
+#  endif
+
+#elif defined(__370__)
+#  if defined(__IBMC__) || defined(__IBMCPP__)
+#    if defined(_ILP32)
+#      define CURLSYS_SIZEOF_LONG           4
+#    elif defined(_LP64)
+#      define CURLSYS_SIZEOF_LONG           8
+#    endif
+#    if defined(_LONG_LONG)
+#      define CURLSYS_TYPEOF_CURL_OFF_T     long long
+#      define CURLSYS_FORMAT_CURL_OFF_T     "lld"
+#      define CURLSYS_FORMAT_CURL_OFF_TU    "llu"
+#      define CURLSYS_SIZEOF_CURL_OFF_T     8
+#      define CURLSYS_SUFFIX_CURL_OFF_T     LL
+#      define CURLSYS_SUFFIX_CURL_OFF_TU    ULL
+#    elif defined(_LP64)
+#      define CURLSYS_TYPEOF_CURL_OFF_T     long
+#      define CURLSYS_FORMAT_CURL_OFF_T     "ld"
+#      define CURLSYS_FORMAT_CURL_OFF_TU    "lu"
+#      define CURLSYS_SIZEOF_CURL_OFF_T     8
+#      define CURLSYS_SUFFIX_CURL_OFF_T     L
+#      define CURLSYS_SUFFIX_CURL_OFF_TU    UL
+#    else
+#      define CURLSYS_TYPEOF_CURL_OFF_T     long
+#      define CURLSYS_FORMAT_CURL_OFF_T     "ld"
+#      define CURLSYS_FORMAT_CURL_OFF_TU    "lu"
+#      define CURLSYS_SIZEOF_CURL_OFF_T     4
+#      define CURLSYS_SUFFIX_CURL_OFF_T     L
+#      define CURLSYS_SUFFIX_CURL_OFF_TU    UL
+#    endif
+#    define CURLSYS_TYPEOF_CURL_SOCKLEN_T socklen_t
+#    define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4
+#    define CURLSYS_PULL_SYS_TYPES_H      1
+#    define CURLSYS_PULL_SYS_SOCKET_H     1
+#  endif
+
+#elif defined(TPF)
+#  define CURLSYS_SIZEOF_LONG           8
+#  define CURLSYS_TYPEOF_CURL_OFF_T     long
+#  define CURLSYS_FORMAT_CURL_OFF_T     "ld"
+#  define CURLSYS_FORMAT_CURL_OFF_TU    "lu"
+#  define CURLSYS_SIZEOF_CURL_OFF_T     8
+#  define CURLSYS_SUFFIX_CURL_OFF_T     L
+#  define CURLSYS_SUFFIX_CURL_OFF_TU    UL
+#  define CURLSYS_TYPEOF_CURL_SOCKLEN_T int
+#  define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4
+
+#elif defined(__TINYC__) /* also known as tcc */
+
+#  define CURLSYS_SIZEOF_LONG           4
+#  define CURLSYS_TYPEOF_CURL_OFF_T     long long
+#  define CURLSYS_FORMAT_CURL_OFF_T     "lld"
+#  define CURLSYS_FORMAT_CURL_OFF_TU    "llu"
+#  define CURLSYS_SIZEOF_CURL_OFF_T     8
+#  define CURLSYS_SUFFIX_CURL_OFF_T     LL
+#  define CURLSYS_SUFFIX_CURL_OFF_TU    ULL
+#  define CURLSYS_TYPEOF_CURL_SOCKLEN_T socklen_t
+#  define CURLSYS_PULL_SYS_TYPES_H      1
+#  define CURLSYS_PULL_SYS_SOCKET_H     1
+
+/* ===================================== */
+/*    KEEP MSVC THE PENULTIMATE ENTRY    */
+/* ===================================== */
+
+#elif defined(_MSC_VER)
+#  if (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64)
+#    define CURLSYS_SIZEOF_LONG           4
+#    define CURLSYS_TYPEOF_CURL_OFF_T     __int64
+#    define CURLSYS_FORMAT_CURL_OFF_T     "I64d"
+#    define CURLSYS_FORMAT_CURL_OFF_TU    "I64u"
+#    define CURLSYS_SIZEOF_CURL_OFF_T     8
+#    define CURLSYS_SUFFIX_CURL_OFF_T     i64
+#    define CURLSYS_SUFFIX_CURL_OFF_TU    ui64
+#  else
+#    define CURLSYS_SIZEOF_LONG           4
+#    define CURLSYS_TYPEOF_CURL_OFF_T     long
+#    define CURLSYS_FORMAT_CURL_OFF_T     "ld"
+#    define CURLSYS_FORMAT_CURL_OFF_TU    "lu"
+#    define CURLSYS_SIZEOF_CURL_OFF_T     4
+#    define CURLSYS_SUFFIX_CURL_OFF_T     L
+#    define CURLSYS_SUFFIX_CURL_OFF_TU    UL
+#  endif
+#  define CURLSYS_TYPEOF_CURL_SOCKLEN_T int
+#  define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4
+
+/* ===================================== */
+/*    KEEP GENERIC GCC THE LAST ENTRY    */
+/* ===================================== */
+
+#elif defined(__GNUC__)
+#  if !defined(__LP64__) && (defined(__ILP32__) || \
+      defined(__i386__) || defined(__ppc__) || defined(__arm__) || \
+      defined(__sparc__) || defined(__mips__) || defined(__sh__))
+#    define CURLSYS_SIZEOF_LONG           4
+#    define CURLSYS_TYPEOF_CURL_OFF_T     long long
+#    define CURLSYS_FORMAT_CURL_OFF_T     "lld"
+#    define CURLSYS_FORMAT_CURL_OFF_TU    "llu"
+#    define CURLSYS_SIZEOF_CURL_OFF_T     8
+#    define CURLSYS_SUFFIX_CURL_OFF_T     LL
+#    define CURLSYS_SUFFIX_CURL_OFF_TU    ULL
+#  elif defined(__LP64__) || \
+        defined(__x86_64__) || defined(__ppc64__) || defined(__sparc64__)
+#    define CURLSYS_SIZEOF_LONG           8
+#    define CURLSYS_TYPEOF_CURL_OFF_T     long
+#    define CURLSYS_FORMAT_CURL_OFF_T     "ld"
+#    define CURLSYS_FORMAT_CURL_OFF_TU    "lu"
+#    define CURLSYS_SIZEOF_CURL_OFF_T     8
+#    define CURLSYS_SUFFIX_CURL_OFF_T     L
+#    define CURLSYS_SUFFIX_CURL_OFF_TU    UL
+#  endif
+#  define CURLSYS_TYPEOF_CURL_SOCKLEN_T socklen_t
+#  define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4
+#  define CURLSYS_PULL_SYS_TYPES_H      1
+#  define CURLSYS_PULL_SYS_SOCKET_H     1
+
+#else
+/* generic "safe guess" on old 32 bit style */
+# define CURLSYS_SIZEOF_LONG 4
+# define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4
+# define CURLSYS_SIZEOF_CURL_OFF_T 4
+# define CURLSYS_TYPEOF_CURL_OFF_T     long
+# define CURLSYS_FORMAT_CURL_OFF_T     "ld"
+# define CURLSYS_FORMAT_CURL_OFF_TU    "lu"
+# define CURLSYS_SUFFIX_CURL_OFF_T     L
+# define CURLSYS_SUFFIX_CURL_OFF_TU    UL
+# define CURLSYS_TYPEOF_CURL_SOCKLEN_T int
+#endif
+
+/* CURLSYS_PULL_WS2TCPIP_H is defined above when inclusion of header file  */
+/* ws2tcpip.h is required here to properly make type definitions below. */
+#ifdef CURLSYS_PULL_WS2TCPIP_H
+#  ifndef WIN32_LEAN_AND_MEAN
+#    define WIN32_LEAN_AND_MEAN
+#  endif
+#  include <windows.h>
+#  include <winsock2.h>
+#  include <ws2tcpip.h>
+#endif
+
+/* CURLSYS_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 CURLSYS_PULL_SYS_TYPES_H
+#  include <sys/types.h>
+#endif
+
+/* CURLSYS_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 CURLSYS_PULL_SYS_SOCKET_H
+#  include <sys/socket.h>
+#endif
+
+/* Data type definition of curl_socklen_t. */
+#ifdef CURLSYS_TYPEOF_CURL_SOCKLEN_T
+  typedef CURLSYS_TYPEOF_CURL_SOCKLEN_T curlsys_socklen_t;
+#endif
+
+/* Data type definition of curl_off_t. */
+
+#ifdef CURLSYS_TYPEOF_CURL_OFF_T
+  typedef CURLSYS_TYPEOF_CURL_OFF_T curlsys_off_t;
+#endif
+
+#endif /* __CURL_SYSTEM_H */
+
diff --git a/include/curl/typecheck-gcc.h b/include/curl/typecheck-gcc.h
index 4eb896e..3d68315 100644
--- a/include/curl/typecheck-gcc.h
+++ b/include/curl/typecheck-gcc.h
@@ -219,7 +219,8 @@ _CURL_WARNING(_curl_easy_getinfo_err_curl_slist,
 
 /* evaluates to true if option takes a char* argument */
 #define _curl_is_string_option(option)                                        \
-  ((option) == CURLOPT_ACCEPT_ENCODING ||                                     \
+  ((option) == CURLOPT_ABSTRACT_UNIX_SOCKET ||                                \
+   (option) == CURLOPT_ACCEPT_ENCODING ||                                     \
    (option) == CURLOPT_CAINFO ||                                              \
    (option) == CURLOPT_CAPATH ||                                              \
    (option) == CURLOPT_COOKIE ||                                              \
diff --git a/lib/asyn-ares.c b/lib/asyn-ares.c
index c038c2a..281fb03 100644
--- a/lib/asyn-ares.c
+++ b/lib/asyn-ares.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
@@ -358,12 +358,20 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
   struct timeval now = Curl_tvnow();
   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. */
-  for(;;) {
+  while(!result) {
     struct timeval *tvp, tv, store;
     long timediff;
     int itimeout;
@@ -385,28 +393,25 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
       timeout_ms = 1000;
 
     waitperform(conn, timeout_ms);
-    Curl_resolver_is_resolved(conn, &temp_entry);
+    result = Curl_resolver_is_resolved(conn, &temp_entry);
 
-    if(conn->async.done)
+    if(result || conn->async.done)
       break;
 
-    if(Curl_pgrsUpdate(conn)) {
+    if(Curl_pgrsUpdate(conn))
       result = CURLE_ABORTED_BY_CALLBACK;
-      timeout = -1; /* trigger the cancel below */
-    }
     else {
       struct timeval now2 = Curl_tvnow();
       timediff = Curl_tvdiff(now2, now); /* spent time */
       timeout -= timediff?timediff:1; /* always deduct at least 1 */
       now = now2; /* for next loop */
     }
-
-    if(timeout < 0) {
-      /* our timeout, so we cancel the ares operation */
-      ares_cancel((ares_channel)data->state.resolver);
-      break;
-    }
+    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. */
diff --git a/lib/conncache.c b/lib/conncache.c
index d8ef9a5..0590ec6 100644
--- a/lib/conncache.c
+++ b/lib/conncache.c
@@ -5,8 +5,8 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2012, 2016, Linus Nielsen Feltzing, <linus at haxx.se>
- * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 2012 - 2016, Linus Nielsen Feltzing, <linus at haxx.se>
+ * Copyright (C) 2012 - 2017, Daniel Stenberg, <daniel at 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
@@ -56,11 +56,7 @@ static CURLcode bundle_create(struct Curl_easy *data,
   (*cb_ptr)->num_connections = 0;
   (*cb_ptr)->multiuse = BUNDLE_UNKNOWN;
 
-  (*cb_ptr)->conn_list = Curl_llist_alloc((curl_llist_dtor) conn_llist_dtor);
-  if(!(*cb_ptr)->conn_list) {
-    Curl_safefree(*cb_ptr);
-    return CURLE_OUT_OF_MEMORY;
-  }
+  Curl_llist_init(&(*cb_ptr)->conn_list, (curl_llist_dtor) conn_llist_dtor);
   return CURLE_OK;
 }
 
@@ -69,10 +65,8 @@ static void bundle_destroy(struct connectbundle *cb_ptr)
   if(!cb_ptr)
     return;
 
-  if(cb_ptr->conn_list) {
-    Curl_llist_destroy(cb_ptr->conn_list, NULL);
-    cb_ptr->conn_list = NULL;
-  }
+  Curl_llist_destroy(&cb_ptr->conn_list, NULL);
+
   free(cb_ptr);
 }
 
@@ -80,7 +74,7 @@ static void bundle_destroy(struct connectbundle *cb_ptr)
 static CURLcode bundle_add_conn(struct connectbundle *cb_ptr,
                               struct connectdata *conn)
 {
-  if(!Curl_llist_insert_next(cb_ptr->conn_list, cb_ptr->conn_list->tail, conn))
+  if(!Curl_llist_insert_next(&cb_ptr->conn_list, cb_ptr->conn_list.tail, conn))
     return CURLE_OUT_OF_MEMORY;
 
   conn->bundle = cb_ptr;
@@ -95,10 +89,10 @@ static int bundle_remove_conn(struct connectbundle *cb_ptr,
 {
   struct curl_llist_element *curr;
 
-  curr = cb_ptr->conn_list->head;
+  curr = cb_ptr->conn_list.head;
   while(curr) {
     if(curr->ptr == conn) {
-      Curl_llist_remove(cb_ptr->conn_list, curr, NULL);
+      Curl_llist_remove(&cb_ptr->conn_list, curr, NULL);
       cb_ptr->num_connections--;
       conn->bundle = NULL;
       return 1; /* we removed a handle */
@@ -127,8 +121,9 @@ void Curl_conncache_destroy(struct conncache *connc)
     Curl_hash_destroy(&connc->hash);
 }
 
-/* returns an allocated key to find a bundle for this connection */
-static char *hashkey(struct connectdata *conn)
+/* 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;
 
@@ -141,7 +136,10 @@ static char *hashkey(struct connectdata *conn)
   else
     hostname = conn->host.name;
 
-  return aprintf("%s:%d", hostname, conn->port);
+  DEBUGASSERT(len > 32);
+
+  /* put the number first so that the hostname gets cut off if too long */
+  snprintf(buf, len, "%ld%s", conn->port, hostname);
 }
 
 /* Look up the bundle with all the connections to the same host this
@@ -151,11 +149,9 @@ struct connectbundle *Curl_conncache_find_bundle(struct connectdata *conn,
 {
   struct connectbundle *bundle = NULL;
   if(connc) {
-    char *key = hashkey(conn);
-    if(key) {
-      bundle = Curl_hash_pick(&connc->hash, key, strlen(key));
-      free(key);
-    }
+    char key[128];
+    hashkey(conn, key, sizeof(key));
+    bundle = Curl_hash_pick(&connc->hash, key, strlen(key));
   }
 
   return bundle;
@@ -204,21 +200,16 @@ CURLcode Curl_conncache_add_conn(struct conncache *connc,
 
   bundle = Curl_conncache_find_bundle(conn, data->state.conn_cache);
   if(!bundle) {
-    char *key;
     int rc;
+    char key[128];
 
     result = bundle_create(data, &new_bundle);
     if(result)
       return result;
 
-    key = hashkey(conn);
-    if(!key) {
-      bundle_destroy(new_bundle);
-      return CURLE_OUT_OF_MEMORY;
-    }
-
+    hashkey(conn, key, sizeof(key));
     rc = conncache_add_bundle(data->state.conn_cache, key, new_bundle);
-    free(key);
+
     if(!rc) {
       bundle_destroy(new_bundle);
       return CURLE_OUT_OF_MEMORY;
@@ -292,7 +283,7 @@ void Curl_conncache_foreach(struct conncache *connc,
     bundle = he->ptr;
     he = Curl_hash_next_element(&iter);
 
-    curr = bundle->conn_list->head;
+    curr = bundle->conn_list.head;
     while(curr) {
       /* Yes, we need to update curr before calling func(), because func()
          might decide to remove the connection */
@@ -321,7 +312,7 @@ Curl_conncache_find_first_connection(struct conncache *connc)
     struct curl_llist_element *curr;
     bundle = he->ptr;
 
-    curr = bundle->conn_list->head;
+    curr = bundle->conn_list.head;
     if(curr) {
       return curr->ptr;
     }
diff --git a/lib/conncache.h b/lib/conncache.h
index b1dadf9..f976cfd 100644
--- a/lib/conncache.h
+++ b/lib/conncache.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 2015 - 2017, Daniel Stenberg, <daniel at haxx.se>, et al.
  * Copyright (C) 2012 - 2014, Linus Nielsen Feltzing, <linus at haxx.se>
  *
  * This software is licensed as described in the file COPYING, which
@@ -38,7 +38,7 @@ struct conncache {
 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 */
+  struct curl_llist conn_list;  /* The connectdata members of the bundle */
 };
 
 int Curl_conncache_init(struct conncache *, int size);
diff --git a/lib/connect.c b/lib/connect.c
index 524d885..63ec50f 100644
--- a/lib/connect.c
+++ b/lib/connect.c
@@ -810,8 +810,7 @@ CURLcode Curl_is_connected(struct connectdata *conn,
 
         return CURLE_OK;
       }
-      else
-        infof(data, "Connection failed\n");
+      infof(data, "Connection failed\n");
     }
     else if(rc & CURL_CSELECT_ERR)
       (void)verifyconnect(conn->tempsock[i], &error);
@@ -1386,7 +1385,7 @@ CURLcode Curl_socket(struct connectdata *conn,
  */
 void Curl_conncontrol(struct connectdata *conn,
                       int ctrl /* see defines in header */
-#ifdef DEBUGBUILD
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
                       , const char *reason
 #endif
   )
diff --git a/lib/connect.h b/lib/connect.h
index 5653cb4..44bdb10 100644
--- a/lib/connect.h
+++ b/lib/connect.h
@@ -127,16 +127,16 @@ void Curl_tcpnodelay(struct connectdata *conn, curl_socket_t sockfd);
 
 void Curl_conncontrol(struct connectdata *conn,
                       int closeit
-#ifdef DEBUGBUILD
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
                       , const char *reason
 #endif
   );
 
-#ifdef DEBUGBUILD
+#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 !CURLDEBUG */
+#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)
diff --git a/lib/content_encoding.c b/lib/content_encoding.c
index 5385058..652ed97 100644
--- a/lib/content_encoding.c
+++ b/lib/content_encoding.c
@@ -130,8 +130,7 @@ inflate_stream(struct connectdata *conn,
         free(decomp);
         if(inflateEnd(z) == Z_OK)
           return exit_zlib(z, &k->zlib_init, result);
-        else
-          return exit_zlib(z, &k->zlib_init, process_zlib_error(conn, z));
+        return exit_zlib(z, &k->zlib_init, process_zlib_error(conn, z));
       }
 
       /* Done with these bytes, exit */
@@ -314,7 +313,7 @@ Curl_unencode_gzip_write(struct connectdata *conn,
 #ifndef OLD_ZLIB_SUPPORT
   /* Support for old zlib versions is compiled away and we are running with
      an old version, so return an error. */
-  return exit_zlib(z, &k->zlib_init, CURLE_FUNCTION_NOT_FOUND);
+  return exit_zlib(z, &k->zlib_init, CURLE_WRITE_ERROR);
 
 #else
   /* This next mess is to get around the potential case where there isn't
diff --git a/lib/cookie.c b/lib/cookie.c
index 092a226..6b678ae 100644
--- a/lib/cookie.c
+++ b/lib/cookie.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
@@ -492,7 +492,6 @@ Curl_cookie_add(struct Curl_easy *data,
         }
         else if(strcasecompare("domain", name)) {
           bool is_ip;
-          const char *dotp;
 
           /* Now, we make sure that our host is within the given domain,
              or the given domain is not valid and thus cannot be set. */
@@ -500,12 +499,22 @@ Curl_cookie_add(struct Curl_easy *data,
           if('.' == whatptr[0])
             whatptr++; /* ignore preceding dot */
 
-          is_ip = isip(domain ? domain : whatptr);
+#ifndef USE_LIBPSL
+          /*
+           * Without PSL we don't know when the incoming cookie is set on a
+           * TLD or otherwise "protected" suffix. To reduce risk, we require a
+           * dot OR the exact host name being "localhost".
+           */
+          {
+            const char *dotp;
+            /* check for more dots */
+            dotp = strchr(whatptr, '.');
+            if(!dotp && !strcasecompare("localhost", whatptr))
+              domain=":";
+          }
+#endif
 
-          /* check for more dots */
-          dotp = strchr(whatptr, '.');
-          if(!dotp)
-            domain=":";
+          is_ip = isip(domain ? domain : whatptr);
 
           if(!domain
              || (is_ip && !strcmp(whatptr, domain))
@@ -920,9 +929,8 @@ static char *get_line(char *buf, int len, FILE *input)
         }
         return b;
       }
-      else
-        /* read a partial, discard the next piece that ends with newline */
-        partial = TRUE;
+      /* read a partial, discard the next piece that ends with newline */
+      partial = TRUE;
     }
     else
       break;
@@ -1055,16 +1063,16 @@ static int cookie_sort(const void *p1, const void *p2)
 #define CLONE(field)                     \
   do {                                   \
     if(src->field) {                     \
-      dup->field = strdup(src->field);   \
-      if(!dup->field)                    \
+      d->field = strdup(src->field);     \
+      if(!d->field)                      \
         goto fail;                       \
     }                                    \
   } while(0)
 
 static struct Cookie *dup_cookie(struct Cookie *src)
 {
-  struct Cookie *dup = calloc(sizeof(struct Cookie), 1);
-  if(dup) {
+  struct Cookie *d = calloc(sizeof(struct Cookie), 1);
+  if(d) {
     CLONE(expirestr);
     CLONE(domain);
     CLONE(path);
@@ -1073,16 +1081,16 @@ static struct Cookie *dup_cookie(struct Cookie *src)
     CLONE(value);
     CLONE(maxage);
     CLONE(version);
-    dup->expires = src->expires;
-    dup->tailmatch = src->tailmatch;
-    dup->secure = src->secure;
-    dup->livecookie = src->livecookie;
-    dup->httponly = src->httponly;
+    d->expires = src->expires;
+    d->tailmatch = src->tailmatch;
+    d->secure = src->secure;
+    d->livecookie = src->livecookie;
+    d->httponly = src->httponly;
   }
-  return dup;
+  return d;
 
   fail:
-  freecookie(dup);
+  freecookie(d);
   return NULL;
 }
 
diff --git a/lib/curl_addrinfo.c b/lib/curl_addrinfo.c
index 61cdadd..1adf319 100644
--- a/lib/curl_addrinfo.c
+++ b/lib/curl_addrinfo.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
@@ -47,6 +47,8 @@
 #  define in_addr_t unsigned long
 #endif
 
+#include <stddef.h>
+
 #include "curl_addrinfo.h"
 #include "inet_pton.h"
 #include "warnless.h"
@@ -467,7 +469,7 @@ Curl_addrinfo *Curl_str2addr(char *address, int port)
     /* This is a dotted IP address 123.123.123.123-style */
     return Curl_ip2addr(AF_INET, &in, address, port);
 #ifdef ENABLE_IPV6
-  else {
+  {
     struct in6_addr in6;
     if(Curl_inet_pton(AF_INET6, address, &in6) > 0)
       /* This is a dotted IPv6 address ::1-style */
@@ -483,24 +485,29 @@ Curl_addrinfo *Curl_str2addr(char *address, int port)
  * struct initialized with this path.
  * Set '*longpath' to TRUE if the error is a too long path.
  */
-Curl_addrinfo *Curl_unix2addr(const char *path, int *longpath)
+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);
-    *longpath = FALSE;
     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);
-  if(path_len >= sizeof(sa_un->sun_path)) {
+  path_len = strlen(path) + 1;
+  if(path_len > sizeof(sa_un->sun_path)) {
     free(ai->ai_addr);
     free(ai);
     *longpath = TRUE;
@@ -509,10 +516,15 @@ Curl_addrinfo *Curl_unix2addr(const char *path, int *longpath)
 
   ai->ai_family = AF_UNIX;
   ai->ai_socktype = SOCK_STREAM; /* assume reliable transport for HTTP */
-  ai->ai_addrlen = (curl_socklen_t) sizeof(struct sockaddr_un);
-  sa_un = (void *) ai->ai_addr;
-  sa_un->sun_family = AF_UNIX;
-  memcpy(sa_un->sun_path, path, path_len + 1); /* copy NUL byte */
+  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
diff --git a/lib/curl_addrinfo.h b/lib/curl_addrinfo.h
index 4f24730..8f6f3d1 100644
--- a/lib/curl_addrinfo.h
+++ b/lib/curl_addrinfo.h
@@ -80,7 +80,7 @@ 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, int *longpath);
+Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath, bool abstract);
 #endif
 
 #if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) && \
diff --git a/lib/curl_config.h.cmake b/lib/curl_config.h.cmake
index 33c15cb..9fcdd97 100644
--- a/lib/curl_config.h.cmake
+++ b/lib/curl_config.h.cmake
@@ -518,6 +518,15 @@
 /* Define to 1 if you have the send function. */
 #cmakedefine HAVE_SEND 1
 
+/* Define to 1 if you have the 'fsetxattr' function. */
+#cmakedefine HAVE_FSETXATTR 1
+
+/* fsetxattr() takes 5 args */
+#cmakedefine HAVE_FSETXATTR_5 1
+
+/* fsetxattr() takes 6 args */
+#cmakedefine HAVE_FSETXATTR_6 1
+
 /* Define to 1 if you have the <setjmp.h> header file. */
 #cmakedefine HAVE_SETJMP_H 1
 
@@ -918,6 +927,9 @@
 /* if PolarSSL is enabled */
 #cmakedefine USE_POLARSSL 1
 
+/* if DarwinSSL is enabled */
+#cmakedefine USE_DARWINSSL 1
+
 /* if mbedTLS is enabled */
 #cmakedefine USE_MBEDTLS 1
 
diff --git a/lib/curl_des.c b/lib/curl_des.c
index 421c9f7..b123a00 100644
--- a/lib/curl_des.c
+++ b/lib/curl_des.c
@@ -34,7 +34,7 @@
  *
  * The function is a port of the Java based oddParity() function over at:
  *
- * http://davenport.sourceforge.net/ntlm.html
+ * https://davenport.sourceforge.io/ntlm.html
  *
  * Parameters:
  *
diff --git a/lib/curl_fnmatch.c b/lib/curl_fnmatch.c
index e8108bb..46d3ada 100644
--- a/lib/curl_fnmatch.c
+++ b/lib/curl_fnmatch.c
@@ -145,8 +145,7 @@ static int setcharset(unsigned char **p, unsigned char *charset)
       else if(c == ']') {
         if(something_found)
           return SETCHARSET_OK;
-        else
-          something_found = TRUE;
+        something_found = TRUE;
         state = CURLFNM_SCHS_RIGHTBR;
         charset[c] = 1;
         (*p)++;
@@ -244,7 +243,7 @@ static int setcharset(unsigned char **p, unsigned char *charset)
       if(c == ']') {
         return SETCHARSET_OK;
       }
-      else if(c == '\\') {
+      if(c == '\\') {
         c = *(++(*p));
         if(ISPRINT(c)) {
           charset[c] = 1;
@@ -345,8 +344,7 @@ static int loop(const unsigned char *pattern, const unsigned char *string)
       else if(*p == '\0') {
         if(*s == '\0')
           return CURL_FNMATCH_MATCH;
-        else
-          return CURL_FNMATCH_NOMATCH;
+        return CURL_FNMATCH_NOMATCH;
       }
       else if(*p == '\\') {
         state = CURLFNM_LOOP_BACKSLASH;
diff --git a/lib/curl_memory.h b/lib/curl_memory.h
index 6f792ff..fccf468 100644
--- a/lib/curl_memory.h
+++ b/lib/curl_memory.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
@@ -70,7 +70,7 @@
  *
  * Programs and libraries in 'tests' subdirectories have specific
  * purposes and needs, and as such each one will use whatever fits
- * best, depending additionally wether it links with libcurl or not.
+ * 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
diff --git a/lib/curl_ntlm_core.c b/lib/curl_ntlm_core.c
index 73d983c..fb43dda 100644
--- a/lib/curl_ntlm_core.c
+++ b/lib/curl_ntlm_core.c
@@ -27,7 +27,7 @@
 /*
  * NTLM details:
  *
- * http://davenport.sourceforge.net/ntlm.html
+ * https://davenport.sourceforge.io/ntlm.html
  * https://www.innovation.ch/java/ntlm.html
  */
 
@@ -501,7 +501,7 @@ CURLcode Curl_ntlm_core_mk_lm_hash(struct Curl_easy *data,
   return CURLE_OK;
 }
 
-#if USE_NTRESPONSES
+#ifdef USE_NTRESPONSES
 static void ascii_to_unicode_le(unsigned char *dest, const char *src,
                                 size_t srclen)
 {
@@ -512,7 +512,7 @@ static void ascii_to_unicode_le(unsigned char *dest, const char *src,
   }
 }
 
-#if USE_NTLM_V2 && !defined(USE_WINDOWS_SSPI)
+#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)
@@ -597,7 +597,7 @@ CURLcode Curl_ntlm_core_mk_nt_hash(struct Curl_easy *data,
   return CURLE_OK;
 }
 
-#if USE_NTLM_V2 && !defined(USE_WINDOWS_SSPI)
+#if defined(USE_NTLM_V2) && !defined(USE_WINDOWS_SSPI)
 
 /* This returns the HMAC MD5 digest */
 CURLcode Curl_hmac_md5(const unsigned char *key, unsigned int keylen,
@@ -715,8 +715,10 @@ CURLcode Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash,
 
   /* Create the BLOB structure */
   snprintf((char *)ptr + NTLM_HMAC_MD5_LEN, NTLMv2_BLOB_LEN,
-           NTLMv2_BLOB_SIGNATURE
+           "%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);
diff --git a/lib/curl_ntlm_core.h b/lib/curl_ntlm_core.h
index c5f90e7..4a83d40 100644
--- a/lib/curl_ntlm_core.h
+++ b/lib/curl_ntlm_core.h
@@ -33,31 +33,26 @@
       !defined(HEADER_SSL_H) && !defined(HEADER_MD5_H)
 #    error "curl_ntlm_core.h shall not be included before OpenSSL headers."
 #  endif
-#  ifdef OPENSSL_NO_MD4
-#    define USE_NTRESPONSES 0
-#    define USE_NTLM2SESSION 0
-#    define USE_NTLM_V2 0
-#  endif
 #endif
 
-/* Define USE_NTRESPONSES to 1 in order to make the type-3 message include
+/* Define USE_NTRESPONSES in order to make the type-3 message include
  * the NT response message. */
-#ifndef USE_NTRESPONSES
-#define USE_NTRESPONSES 1
+#if !defined(USE_OPENSSL) || !defined(OPENSSL_NO_MD4)
+#define USE_NTRESPONSES
 #endif
 
-/* Define USE_NTLM2SESSION to 1 in order to make the type-3 message include the
+/* 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_NTLM2SESSION) && USE_NTRESPONSES && !defined(USE_WIN32_CRYPTO)
-#define USE_NTLM2SESSION 1
+#if defined(USE_NTRESPONSES) && !defined(USE_WIN32_CRYPTO)
+#define USE_NTLM2SESSION
 #endif
 
-/* Define USE_NTLM_V2 to 1 in order to allow the type-3 message to include the
+/* 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_NTLM_V2) && USE_NTRESPONSES && (CURL_SIZEOF_CURL_OFF_T > 4)
-#define USE_NTLM_V2 1
+#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,
@@ -68,12 +63,12 @@ CURLcode Curl_ntlm_core_mk_lm_hash(struct Curl_easy *data,
                                    const char *password,
                                    unsigned char *lmbuffer /* 21 bytes */);
 
-#if USE_NTRESPONSES
+#ifdef USE_NTRESPONSES
 CURLcode Curl_ntlm_core_mk_nt_hash(struct Curl_easy *data,
                                    const char *password,
                                    unsigned char *ntbuffer /* 21 bytes */);
 
-#if USE_NTLM_V2 && !defined(USE_WINDOWS_SSPI)
+#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,
diff --git a/lib/curl_ntlm_wb.c b/lib/curl_ntlm_wb.c
index 6a90e62..9f5b87b 100644
--- a/lib/curl_ntlm_wb.c
+++ b/lib/curl_ntlm_wb.c
@@ -28,7 +28,7 @@
 /*
  * NTLM details:
  *
- * http://davenport.sourceforge.net/ntlm.html
+ * https://davenport.sourceforge.io/ntlm.html
  * https://www.innovation.ch/java/ntlm.html
  */
 
diff --git a/lib/curl_sasl.c b/lib/curl_sasl.c
index 807f5de..b3789da 100644
--- a/lib/curl_sasl.c
+++ b/lib/curl_sasl.c
@@ -50,7 +50,7 @@
 #include "memdebug.h"
 
 /* Supported mechanisms */
-const struct {
+static const struct {
   const char   *name;  /* Name */
   size_t        len;   /* Name length */
   unsigned int  bit;   /* Flag bit */
diff --git a/lib/curl_setup.h b/lib/curl_setup.h
index 0fe3633..9d99f13 100644
--- a/lib/curl_setup.h
+++ b/lib/curl_setup.h
@@ -124,18 +124,7 @@
 /*  please, do it beyond the point further indicated in this file.  */
 /* ================================================================ */
 
-/*
- * libcurl's external interface definitions are also used internally,
- * and might also include required system header files to define them.
- */
-
-#include <curl/curlbuild.h>
-
-/*
- * Compile time sanity checks must also be done when building the library.
- */
-
-#include <curl/curlrules.h>
+#include <curl/curl.h>
 
 /*
  * Ensure that no one is using the old SIZEOF_CURL_OFF_T macro
diff --git a/lib/dict.c b/lib/dict.c
index 69defc4..451ec38 100644
--- a/lib/dict.c
+++ b/lib/dict.c
@@ -92,7 +92,7 @@ const struct Curl_handler Curl_handler_dict = {
 
 static char *unescape_word(struct Curl_easy *data, const char *inputbuff)
 {
-  char *newp;
+  char *newp = NULL;
   char *dictp;
   char *ptr;
   size_t len;
diff --git a/lib/easy.c b/lib/easy.c
index 1242369..2b5f972 100644
--- a/lib/easy.c
+++ b/lib/easy.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
@@ -179,7 +179,7 @@ curl_wcsdup_callback Curl_cwcsdup = (curl_wcsdup_callback)_wcsdup;
 #endif
 #else
 /*
- * Symbian OS doesn't support initialization to code in writeable static data.
+ * Symbian OS doesn't support initialization to code in writable static data.
  * Initialization will occur in the curl_global_init() call.
  */
 curl_malloc_callback Curl_cmalloc;
@@ -619,7 +619,7 @@ static CURLcode wait_or_timeout(struct Curl_multi *multi, struct events *ev)
         /* If nothing updated the timeout, we decrease it by the spent time.
          * If it was updated, it has the new timeout time stored already.
          */
-        ev->ms += curlx_tvdiff(after, before);
+        ev->ms += (long)curlx_tvdiff(after, before);
 
     }
     else
@@ -773,8 +773,7 @@ static CURLcode easy_perform(struct Curl_easy *data, bool events)
     curl_multi_cleanup(multi);
     if(mcode == CURLM_OUT_OF_MEMORY)
       return CURLE_OUT_OF_MEMORY;
-    else
-      return CURLE_FAILED_INIT;
+    return CURLE_FAILED_INIT;
   }
 
   sigpipe_ignore(data, &pipe_st);
@@ -870,6 +869,11 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data)
    * get setup on-demand in the code, as that would probably decrease
    * the likeliness of us forgetting to init a buffer here in the future.
    */
+  outcurl->set.buffer_size = data->set.buffer_size;
+  outcurl->state.buffer = malloc(CURL_BUFSIZE(outcurl->set.buffer_size) + 1);
+  if(!outcurl->state.buffer)
+    goto fail;
+
   outcurl->state.headerbuff = malloc(HEADERSIZE);
   if(!outcurl->state.headerbuff)
     goto fail;
@@ -940,6 +944,7 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data)
   if(outcurl) {
     curl_slist_free_all(outcurl->change.cookielist);
     outcurl->change.cookielist = NULL;
+    Curl_safefree(outcurl->state.buffer);
     Curl_safefree(outcurl->state.headerbuff);
     Curl_safefree(outcurl->change.url);
     Curl_safefree(outcurl->change.referer);
@@ -975,6 +980,10 @@ void curl_easy_reset(struct Curl_easy *data)
 
   data->progress.flags |= PGRS_HIDE;
   data->state.current_speed = -1; /* init to negative == impossible */
+
+  /* zero out authentication data: */
+  memset(&data->state.authhost, 0, sizeof(struct auth));
+  memset(&data->state.authproxy, 0, sizeof(struct auth));
 }
 
 /*
@@ -1002,19 +1011,32 @@ CURLcode curl_easy_pause(struct Curl_easy *data, int action)
   /* put it back in the keepon */
   k->keepon = newstate;
 
-  if(!(newstate & KEEP_RECV_PAUSE) && data->state.tempwrite) {
-    /* we have a buffer for sending that we now seem to be able to deliver
-       since the receive pausing is lifted! */
-
-    /* get the pointer in local copy since the function may return PAUSE
-       again and then we'll get a new copy allocted and stored in
-       the tempwrite variables */
-    char *tempwrite = data->state.tempwrite;
-
-    data->state.tempwrite = NULL;
-    result = Curl_client_chop_write(data->easy_conn, data->state.tempwritetype,
-                                    tempwrite, data->state.tempwritesize);
-    free(tempwrite);
+  if(!(newstate & KEEP_RECV_PAUSE) && data->state.tempcount) {
+    /* there are buffers for sending that can be delivered as the receive
+       pausing is lifted! */
+    unsigned int i;
+    unsigned int count = data->state.tempcount;
+    struct tempbuf writebuf[3]; /* there can only be three */
+
+    /* copy the structs to allow for immediate re-pausing */
+    for(i=0; i < data->state.tempcount; i++) {
+      writebuf[i] = data->state.tempwrite[i];
+      data->state.tempwrite[i].buf = NULL;
+    }
+    data->state.tempcount = 0;
+
+    for(i=0; i < count; i++) {
+      /* even if one function returns error, this loops through and frees all
+         buffers */
+      if(!result)
+        result = Curl_client_chop_write(data->easy_conn,
+                                        writebuf[i].type,
+                                        writebuf[i].buf,
+                                        writebuf[i].len);
+      free(writebuf[i].buf);
+    }
+    if(result)
+      return result;
   }
 
   /* if there's no error and we're not pausing both directions, we want
diff --git a/lib/escape.c b/lib/escape.c
index 9c811b8..973aeb6 100644
--- a/lib/escape.c
+++ b/lib/escape.c
@@ -113,9 +113,7 @@ char *curl_easy_escape(struct Curl_easy *data, const char *string,
         testing_ptr = Curl_saferealloc(ns, alloc);
         if(!testing_ptr)
           return NULL;
-        else {
-          ns = testing_ptr;
-        }
+        ns = testing_ptr;
       }
 
       result = Curl_convert_to_network(data, &in, 1);
diff --git a/lib/file.c b/lib/file.c
index 3dbc0f2..b26bdea 100644
--- a/lib/file.c
+++ b/lib/file.c
@@ -355,8 +355,7 @@ static CURLcode file_upload(struct connectdata *conn)
       failf(data, "Can't get the size of %s", file->path);
       return CURLE_WRITE_ERROR;
     }
-    else
-      data->state.resume_from = (curl_off_t)file_stat.st_size;
+    data->state.resume_from = (curl_off_t)file_stat.st_size;
   }
 
   while(!result) {
@@ -476,7 +475,7 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
     time_t filetime;
     struct tm buffer;
     const struct tm *tm = &buffer;
-    snprintf(buf, sizeof(data->state.buffer),
+    snprintf(buf, CURL_BUFSIZE(data->set.buffer_size),
              "Content-Length: %" CURL_FORMAT_CURL_OFF_T "\r\n", expected_size);
     result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0);
     if(result)
@@ -519,8 +518,7 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
       failf(data, "Can't get the size of file.");
       return CURLE_READ_ERROR;
     }
-    else
-      data->state.resume_from += (curl_off_t)statbuf.st_size;
+    data->state.resume_from += (curl_off_t)statbuf.st_size;
   }
 
   if(data->state.resume_from <= expected_size)
diff --git a/lib/formdata.c b/lib/formdata.c
index abd2da0..2a93434 100644
--- a/lib/formdata.c
+++ b/lib/formdata.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
@@ -342,6 +342,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
 #else
       current_form->flags |= HTTPPOST_PTRNAME; /* fall through */
 #endif
+      /* FALLTHROUGH */
     case CURLFORM_COPYNAME:
       if(current_form->name)
         return_value = CURL_FORMADD_OPTION_TWICE;
@@ -629,70 +630,68 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
         return_value = CURL_FORMADD_INCOMPLETE;
         break;
       }
-      else {
-        if(((form->flags & HTTPPOST_FILENAME) ||
-            (form->flags & HTTPPOST_BUFFER)) &&
-           !form->contenttype) {
-          char *f = form->flags & HTTPPOST_BUFFER?
-            form->showfilename : form->value;
-
-          /* our contenttype is missing */
-          form->contenttype = strdup(ContentTypeForFilename(f, prevtype));
-          if(!form->contenttype) {
-            return_value = CURL_FORMADD_MEMORY;
-            break;
-          }
-          form->contenttype_alloc = TRUE;
+      if(((form->flags & HTTPPOST_FILENAME) ||
+          (form->flags & HTTPPOST_BUFFER)) &&
+         !form->contenttype) {
+        char *f = form->flags & HTTPPOST_BUFFER?
+          form->showfilename : form->value;
+
+        /* our contenttype is missing */
+        form->contenttype = strdup(ContentTypeForFilename(f, prevtype));
+        if(!form->contenttype) {
+          return_value = CURL_FORMADD_MEMORY;
+          break;
         }
-        if(!(form->flags & HTTPPOST_PTRNAME) &&
-           (form == first_form) ) {
-          /* Note that there's small risk that form->name is NULL here if the
-             app passed in a bad combo, so we better check for that first. */
-          if(form->name) {
-            /* copy name (without strdup; possibly contains null characters) */
-            form->name = Curl_memdup(form->name, form->namelength?
-                                     form->namelength:
-                                     strlen(form->name)+1);
-          }
-          if(!form->name) {
-            return_value = CURL_FORMADD_MEMORY;
-            break;
-          }
-          form->name_alloc = TRUE;
+        form->contenttype_alloc = TRUE;
+      }
+      if(!(form->flags & HTTPPOST_PTRNAME) &&
+         (form == first_form) ) {
+        /* Note that there's small risk that form->name is NULL here if the
+           app passed in a bad combo, so we better check for that first. */
+        if(form->name) {
+          /* copy name (without strdup; possibly contains null characters) */
+          form->name = Curl_memdup(form->name, form->namelength?
+                                   form->namelength:
+                                   strlen(form->name)+1);
         }
-        if(!(form->flags & (HTTPPOST_FILENAME | HTTPPOST_READFILE |
-                            HTTPPOST_PTRCONTENTS | HTTPPOST_PTRBUFFER |
-                            HTTPPOST_CALLBACK)) && form->value) {
-          /* copy value (without strdup; possibly contains null characters) */
-          size_t clen  = (size_t) form->contentslength;
-          if(!clen)
-            clen = strlen(form->value)+1;
+        if(!form->name) {
+          return_value = CURL_FORMADD_MEMORY;
+          break;
+        }
+        form->name_alloc = TRUE;
+      }
+      if(!(form->flags & (HTTPPOST_FILENAME | HTTPPOST_READFILE |
+                          HTTPPOST_PTRCONTENTS | HTTPPOST_PTRBUFFER |
+                          HTTPPOST_CALLBACK)) && form->value) {
+        /* copy value (without strdup; possibly contains null characters) */
+        size_t clen  = (size_t) form->contentslength;
+        if(!clen)
+          clen = strlen(form->value)+1;
 
-          form->value = Curl_memdup(form->value, clen);
+        form->value = Curl_memdup(form->value, clen);
 
-          if(!form->value) {
-            return_value = CURL_FORMADD_MEMORY;
-            break;
-          }
-          form->value_alloc = TRUE;
-        }
-        post = AddHttpPost(form->name, form->namelength,
-                           form->value, form->contentslength,
-                           form->buffer, form->bufferlength,
-                           form->contenttype, form->flags,
-                           form->contentheader, form->showfilename,
-                           form->userp,
-                           post, httppost,
-                           last_post);
-
-        if(!post) {
+        if(!form->value) {
           return_value = CURL_FORMADD_MEMORY;
           break;
         }
-
-        if(form->contenttype)
-          prevtype = form->contenttype;
+        form->value_alloc = TRUE;
+      }
+      post = AddHttpPost(form->name, form->namelength,
+                         form->value, form->contentslength,
+                         form->buffer, form->bufferlength,
+                         form->contenttype, form->flags,
+                         form->contentheader, form->showfilename,
+                         form->userp,
+                         post, httppost,
+                         last_post);
+
+      if(!post) {
+        return_value = CURL_FORMADD_MEMORY;
+        break;
       }
+
+      if(form->contenttype)
+        prevtype = form->contenttype;
     }
     if(CURL_FORMADD_OK != return_value) {
       /* On error, free allocated fields for nodes of the FormInfo linked
@@ -1332,7 +1331,7 @@ CURLcode Curl_getformdata(struct Curl_easy *data,
             char buffer[512];
             while((nread = fread(buffer, 1, sizeof(buffer), fileread)) != 0) {
               result = AddFormData(&form, FORM_CONTENT, buffer, nread, &size);
-              if(result)
+              if(result || feof(fileread) || ferror(fileread))
                 break;
             }
           }
@@ -1462,8 +1461,7 @@ static size_t readfromfile(struct Form *form, char *buffer,
   if(callback) {
     if(form->fread_func == ZERO_NULL)
       return 0;
-    else
-      nread = form->fread_func(buffer, 1, size, form->data->line);
+    nread = form->fread_func(buffer, 1, size, form->data->line);
   }
   else {
     if(!form->fp) {
@@ -1553,7 +1551,7 @@ char *Curl_formpostheader(void *formp, size_t *len)
   struct Form *form=(struct Form *)formp;
 
   if(!form->data)
-    return 0; /* nothing, ERROR! */
+    return NULL; /* nothing, ERROR! */
 
   header = form->data->line;
   *len = form->data->length;
diff --git a/lib/ftp.c b/lib/ftp.c
index fd77a5a..059bd2a 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
@@ -916,8 +916,7 @@ static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks,
 
     return bits;
   }
-  else
-    return Curl_pp_getsock(&conn->proto.ftpc.pp, socks, numsocks);
+  return Curl_pp_getsock(&conn->proto.ftpc.pp, socks, numsocks);
 }
 
 /* This is called after the FTP_QUOTE state is passed.
@@ -1209,7 +1208,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
         possibly_non_local = FALSE; /* don't try this again */
         continue;
       }
-      else if(error != EADDRINUSE && error != EACCES) {
+      if(error != EADDRINUSE && error != EACCES) {
         failf(data, "bind(port=%hu) failed: %s", port,
               Curl_strerror(conn, error) );
         Curl_closesocket(conn, portsock);
@@ -1307,7 +1306,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
       }
       break;
     }
-    else if(PORT == fcmd) {
+    if(PORT == fcmd) {
       char *source = myhost;
       char *dest = tmp;
 
@@ -1674,31 +1673,29 @@ static CURLcode ftp_state_ul_setup(struct connectdata *conn,
     }
 
     if(seekerr != CURL_SEEKFUNC_OK) {
+      curl_off_t passed=0;
       if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
         failf(data, "Could not seek stream");
         return CURLE_FTP_COULDNT_USE_REST;
       }
       /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
-      else {
-        curl_off_t passed=0;
-        do {
-          size_t readthisamountnow =
-            (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
-            BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
-
-          size_t actuallyread =
-            data->state.fread_func(data->state.buffer, 1, readthisamountnow,
-                                   data->state.in);
-
-          passed += actuallyread;
-          if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
-            /* this checks for greater-than only to make sure that the
-               CURL_READFUNC_ABORT return code still aborts */
-            failf(data, "Failed to read data");
-            return CURLE_FTP_COULDNT_USE_REST;
-          }
-        } while(passed < data->state.resume_from);
-      }
+      do {
+        size_t readthisamountnow =
+          (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
+          BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
+
+        size_t actuallyread =
+          data->state.fread_func(data->state.buffer, 1, readthisamountnow,
+                                 data->state.in);
+
+        passed += actuallyread;
+        if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
+          /* this checks for greater-than only to make sure that the
+             CURL_READFUNC_ABORT return code still aborts */
+          failf(data, "Failed to read data");
+          return CURLE_FTP_COULDNT_USE_REST;
+        }
+      } while(passed < data->state.resume_from);
     }
     /* now, decrease the size of the read */
     if(data->state.infilesize>0) {
@@ -1757,7 +1754,7 @@ static CURLcode ftp_state_quote(struct connectdata *conn,
   /*
    * This state uses:
    * 'count1' to iterate over the commands to send
-   * 'count2' to store wether to allow commands to fail
+   * 'count2' to store whether to allow commands to fail
    */
 
   if(init)
@@ -2000,7 +1997,7 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
 
     if(!addr) {
       failf(data, "Can't resolve proxy host %s:%hu", host_name, connectport);
-      return CURLE_FTP_CANT_GET_HOST;
+      return CURLE_COULDNT_RESOLVE_PROXY;
     }
   }
   else {
@@ -2040,11 +2037,14 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
     /* this just dumps information about this second connection */
     ftp_pasv_verbose(conn, addr->addr, ftpc->newhost, connectport);
 
+  Curl_resolv_unlock(data, addr); /* we're done using this address */
+
   Curl_safefree(conn->secondaryhostname);
-  conn->secondaryhostname = strdup(ftpc->newhost);
   conn->secondary_port = ftpc->newport;
+  conn->secondaryhostname = strdup(ftpc->newhost);
+  if(!conn->secondaryhostname)
+    return CURLE_OUT_OF_MEMORY;
 
-  Curl_resolv_unlock(data, addr); /* we're done using this address */
   conn->bits.do_more = TRUE;
   state(conn, FTP_STOP); /* this phase is completed */
 
@@ -2107,7 +2107,7 @@ static CURLcode ftp_state_mdtm_resp(struct connectdata *conn,
         /* we have a time, reformat it */
         time_t secs=time(NULL);
         /* using the good old yacc/bison yuck */
-        snprintf(buf, sizeof(conn->data->state.buffer),
+        snprintf(buf, CURL_BUFSIZE(conn->data->set.buffer_size),
                  "%04d%02d%02d %02d:%02d:%02d GMT",
                  year, month, day, hour, minute, second);
         /* now, convert this into a time() value: */
@@ -2318,7 +2318,7 @@ static CURLcode ftp_state_size_resp(struct connectdata *conn,
   if(instate == FTP_SIZE) {
 #ifdef CURL_FTP_HTTPSTYLE_HEAD
     if(-1 != filesize) {
-      snprintf(buf, sizeof(data->state.buffer),
+      snprintf(buf, CURL_BUFSIZE(data->set.buffer_size),
                "Content-Length: %" CURL_FORMAT_CURL_OFF_T "\r\n", filesize);
       result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0);
       if(result)
@@ -2409,8 +2409,7 @@ static CURLcode ftp_state_stor_resp(struct connectdata *conn,
 
     return CURLE_OK;
   }
-  else
-    return InitiateTransfer(conn);
+  return InitiateTransfer(conn);
 }
 
 /* for LIST and RETR responses */
@@ -2823,6 +2822,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
     case FTP_PWD:
       if(ftpcode == 257) {
         char *ptr=&data->state.buffer[4];  /* start on the first letter */
+        const size_t buf_size = CURL_BUFSIZE(data->set.buffer_size);
         char *dir;
         char *store;
 
@@ -2840,7 +2840,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
         */
 
         /* scan for the first double-quote for non-standard responses */
-        while(ptr < &data->state.buffer[sizeof(data->state.buffer)]
+        while(ptr < &data->state.buffer[buf_size]
               && *ptr != '\n' && *ptr != '\0' && *ptr != '"')
           ptr++;
 
@@ -2870,7 +2870,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
              does not start with a '/'), we probably need some server-dependent
              adjustments. For example, this is the case when connecting to
              an OS400 FTP server: this server supports two name syntaxes,
-             the default one being incompatible with standard pathes. In
+             the default one being incompatible with standard paths. In
              addition, this server switches automatically to the regular path
              syntax when one is encountered in a command: this results in
              having an entrypath in the wrong syntax when later used in CWD.
@@ -2944,12 +2944,10 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
           state(conn, FTP_NAMEFMT);
           break;
         }
-        else {
-          /* Nothing special for the target server. */
-          /* remember target server OS */
-          Curl_safefree(ftpc->server_os);
-          ftpc->server_os = os;
-        }
+        /* Nothing special for the target server. */
+        /* remember target server OS */
+        Curl_safefree(ftpc->server_os);
+        ftpc->server_os = os;
       }
       else {
         /* Cannot identify server OS. Continue anyway and cross fingers. */
@@ -3210,6 +3208,7 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
 
     /* until we cope better with prematurely ended requests, let them
      * fallback as if in complete failure */
+    /* FALLTHROUGH */
   default:       /* by default, an error means the control connection is
                     wedged and should not be used anymore */
     ftpc->ctl_valid = FALSE;
@@ -3553,7 +3552,7 @@ static CURLcode ftp_range(struct connectdata *conn)
                  " to %" CURL_FORMAT_CURL_OFF_T ", totally %"
                  CURL_FORMAT_CURL_OFF_T " bytes\n",
                  from, to, data->req.maxdownload));
-    ftpc->dont_check = TRUE; /* dont check for successful transfer */
+    ftpc->dont_check = TRUE; /* don't check for successful transfer */
   }
   else
     data->req.maxdownload = -1;
@@ -3622,7 +3621,7 @@ static CURLcode ftp_do_more(struct connectdata *conn, int *completep)
 
 
   if(ftpc->state) {
-    /* already in a state so skip the intial commands.
+    /* already in a state so skip the initial commands.
        They are only done to kickstart the do_more state */
     result = ftp_multi_statemach(conn, &complete);
 
@@ -3795,12 +3794,10 @@ static CURLcode init_wc_data(struct connectdata *conn)
       result = ftp_parse_url_path(conn);
       return result;
     }
-    else {
-      wildcard->pattern = strdup(last_slash);
-      if(!wildcard->pattern)
-        return CURLE_OUT_OF_MEMORY;
-      last_slash[0] = '\0'; /* cut file from path */
-    }
+    wildcard->pattern = strdup(last_slash);
+    if(!wildcard->pattern)
+      return CURLE_OUT_OF_MEMORY;
+    last_slash[0] = '\0'; /* cut file from path */
   }
   else { /* there is only 'wildcard pattern' or nothing */
     if(path[0]) {
@@ -3885,8 +3882,7 @@ static CURLcode wc_statemach(struct connectdata *conn)
     if(wildcard->state == CURLWC_CLEAN)
       /* only listing! */
       break;
-    else
-      wildcard->state = result ? CURLWC_ERROR : CURLWC_MATCHING;
+    wildcard->state = result ? CURLWC_ERROR : CURLWC_MATCHING;
     break;
 
   case CURLWC_MATCHING: {
@@ -3904,7 +3900,7 @@ static CURLcode wc_statemach(struct connectdata *conn)
       wildcard->state = CURLWC_CLEAN;
       return wc_statemach(conn);
     }
-    else if(wildcard->filelist->size == 0) {
+    if(wildcard->filelist.size == 0) {
       /* no corresponding file */
       wildcard->state = CURLWC_CLEAN;
       return CURLE_REMOTE_FILE_NOT_FOUND;
@@ -3915,7 +3911,7 @@ static CURLcode wc_statemach(struct connectdata *conn)
   case CURLWC_DOWNLOADING: {
     /* filelist has at least one file, lets get first one */
     struct ftp_conn *ftpc = &conn->proto.ftpc;
-    struct curl_fileinfo *finfo = wildcard->filelist->head->ptr;
+    struct curl_fileinfo *finfo = wildcard->filelist.head->ptr;
 
     char *tmp_path = aprintf("%s%s", wildcard->path, finfo->filename);
     if(!tmp_path)
@@ -3930,7 +3926,7 @@ static CURLcode wc_statemach(struct connectdata *conn)
     infof(conn->data, "Wildcard - START of \"%s\"\n", finfo->filename);
     if(conn->data->set.chunk_bgn) {
       long userresponse = conn->data->set.chunk_bgn(
-          finfo, wildcard->customptr, (int)wildcard->filelist->size);
+        finfo, wildcard->customptr, (int)wildcard->filelist.size);
       switch(userresponse) {
       case CURL_CHUNK_BGN_FUNC_SKIP:
         infof(conn->data, "Wildcard - \"%s\" skipped by user\n",
@@ -3955,9 +3951,9 @@ static CURLcode wc_statemach(struct connectdata *conn)
       return result;
 
     /* we don't need the Curl_fileinfo of first file anymore */
-    Curl_llist_remove(wildcard->filelist, wildcard->filelist->head, NULL);
+    Curl_llist_remove(&wildcard->filelist, wildcard->filelist.head, NULL);
 
-    if(wildcard->filelist->size == 0) { /* remains only one file to down. */
+    if(wildcard->filelist.size == 0) { /* remains only one file to down. */
       wildcard->state = CURLWC_CLEAN;
       /* after that will be ftp_do called once again and no transfer
          will be done because of CURLWC_CLEAN state */
@@ -3968,8 +3964,8 @@ static CURLcode wc_statemach(struct connectdata *conn)
   case CURLWC_SKIP: {
     if(conn->data->set.chunk_end)
       conn->data->set.chunk_end(conn->data->wildcard.customptr);
-    Curl_llist_remove(wildcard->filelist, wildcard->filelist->head, NULL);
-    wildcard->state = (wildcard->filelist->size == 0) ?
+    Curl_llist_remove(&wildcard->filelist, wildcard->filelist.head, NULL);
+    wildcard->state = (wildcard->filelist.size == 0) ?
                       CURLWC_CLEAN : CURLWC_DOWNLOADING;
     return wc_statemach(conn);
   }
@@ -3985,6 +3981,7 @@ static CURLcode wc_statemach(struct connectdata *conn)
 
   case CURLWC_DONE:
   case CURLWC_ERROR:
+  case CURLWC_CLEAR:
     break;
   }
 
@@ -4282,7 +4279,6 @@ CURLcode ftp_parse_url_path(struct connectdata *conn)
                            &ftpc->dirs[ftpc->dirdepth], NULL,
                            TRUE);
           if(result) {
-            free(ftpc->dirs[ftpc->dirdepth]);
             freedirs(ftpc);
             return result;
           }
diff --git a/lib/ftplistparser.c b/lib/ftplistparser.c
index f94b31b..bc18680 100644
--- a/lib/ftplistparser.c
+++ b/lib/ftplistparser.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
@@ -280,7 +280,7 @@ static CURLcode ftp_pl_insert_finfo(struct connectdata *conn,
   curl_fnmatch_callback compare;
   struct WildcardData *wc = &conn->data->wildcard;
   struct ftp_wc_tmpdata *tmpdata = wc->tmp;
-  struct curl_llist *llist = wc->filelist;
+  struct curl_llist *llist = &wc->filelist;
   struct ftp_parselist_data *parser = tmpdata->parser;
   bool add = TRUE;
 
@@ -433,10 +433,8 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
                 PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
                 return bufflen;
               }
-              else {
-                parser->state.UNIX.main = PL_UNIX_FILETYPE;
-                finfo->b_used = 0;
-              }
+              parser->state.UNIX.main = PL_UNIX_FILETYPE;
+              finfo->b_used = 0;
             }
             else {
               PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
diff --git a/lib/gopher.c b/lib/gopher.c
index a073d0b..e6d2746 100644
--- a/lib/gopher.c
+++ b/lib/gopher.c
@@ -78,7 +78,7 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
 
   curl_off_t *bytecount = &data->req.bytecount;
   char *path = data->state.path;
-  char *sel;
+  char *sel = NULL;
   char *sel_org = NULL;
   ssize_t amount, k;
   size_t len;
@@ -106,8 +106,8 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
 
     /* ... and finally unescape */
     result = Curl_urldecode(data, newp, 0, &sel, &len, FALSE);
-    if(!sel)
-      return CURLE_OUT_OF_MEMORY;
+    if(result)
+      return result;
     sel_org = sel;
   }
 
diff --git a/lib/hash.c b/lib/hash.c
index 0655042..b7305a5 100644
--- a/lib/hash.c
+++ b/lib/hash.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
@@ -37,8 +37,6 @@ hash_element_dtor(void *user, void *element)
   struct curl_hash *h = (struct curl_hash *) user;
   struct curl_hash_element *e = (struct curl_hash_element *) element;
 
-  Curl_safefree(e->key);
-
   if(e->ptr) {
     h->dtor(e->ptr);
     e->ptr = NULL;
@@ -74,54 +72,32 @@ Curl_hash_init(struct curl_hash *h,
   h->size = 0;
   h->slots = slots;
 
-  h->table = malloc(slots * sizeof(struct curl_llist *));
+  h->table = malloc(slots * sizeof(struct curl_llist));
   if(h->table) {
-    for(i = 0; i < slots; ++i) {
-      h->table[i] = Curl_llist_alloc((curl_llist_dtor) hash_element_dtor);
-      if(!h->table[i]) {
-        while(i--) {
-          Curl_llist_destroy(h->table[i], NULL);
-          h->table[i] = NULL;
-        }
-        free(h->table);
-        h->table = NULL;
-        h->slots = 0;
-        return 1; /* failure */
-      }
-    }
+    for(i = 0; i < slots; ++i)
+      Curl_llist_init(&h->table[i], (curl_llist_dtor) hash_element_dtor);
     return 0; /* fine */
   }
-  else {
-    h->slots = 0;
-    return 1; /* failure */
-  }
+  h->slots = 0;
+  return 1; /* failure */
 }
 
 static struct curl_hash_element *
 mk_hash_element(const void *key, size_t key_len, const void *p)
 {
-  struct curl_hash_element *he = malloc(sizeof(struct curl_hash_element));
-
+  /* allocate the struct plus memory after it to store the key */
+  struct curl_hash_element *he = malloc(sizeof(struct curl_hash_element) +
+                                        key_len);
   if(he) {
-    void *dupkey = malloc(key_len);
-    if(dupkey) {
-      /* copy the key */
-      memcpy(dupkey, key, key_len);
-
-      he->key = dupkey;
-      he->key_len = key_len;
-      he->ptr = (void *) p;
-    }
-    else {
-      /* failed to duplicate the key, free memory and fail */
-      free(he);
-      he = NULL;
-    }
+    /* copy the key */
+    memcpy(he->key, key, key_len);
+    he->key_len = key_len;
+    he->ptr = (void *) p;
   }
   return he;
 }
 
-#define FETCH_LIST(x,y,z) x->table[x->hash_func(y, z, x->slots)]
+#define FETCH_LIST(x,y,z) &x->table[x->hash_func(y, z, x->slots)]
 
 /* Insert the data in the hash. If there already was a match in the hash,
  * that data is replaced.
@@ -158,7 +134,6 @@ Curl_hash_add(struct curl_hash *h, void *key, size_t key_len, void *p)
      * "destructor" for the actual data 'p'. When we fail, we shall not touch
      * that data.
      */
-    free(he->key);
     free(he);
   }
 
@@ -243,8 +218,7 @@ Curl_hash_destroy(struct curl_hash *h)
   int i;
 
   for(i = 0; i < h->slots; ++i) {
-    Curl_llist_destroy(h->table[i], (void *) h);
-    h->table[i] = NULL;
+    Curl_llist_destroy(&h->table[i], (void *) h);
   }
 
   Curl_safefree(h->table);
@@ -276,7 +250,7 @@ Curl_hash_clean_with_criterium(struct curl_hash *h, void *user,
     return;
 
   for(i = 0; i < h->slots; ++i) {
-    list = h->table[i];
+    list = &h->table[i];
     le = list->head; /* get first list entry */
     while(le) {
       struct curl_hash_element *he = le->ptr;
@@ -335,8 +309,8 @@ Curl_hash_next_element(struct curl_hash_iterator *iter)
   /* If we have reached the end of the list, find the next one */
   if(!iter->current_element) {
     for(i = iter->slot_index;i < h->slots;i++) {
-      if(h->table[i]->head) {
-        iter->current_element = h->table[i]->head;
+      if(h->table[i].head) {
+        iter->current_element = h->table[i].head;
         iter->slot_index = i+1;
         break;
       }
@@ -347,10 +321,8 @@ Curl_hash_next_element(struct curl_hash_iterator *iter)
     struct curl_hash_element *he = iter->current_element->ptr;
     return he;
   }
-  else {
-    iter->current_element = NULL;
-    return NULL;
-  }
+  iter->current_element = NULL;
+  return NULL;
 }
 
 #if 0 /* useful function for debugging hashes and their contents */
diff --git a/lib/hash.h b/lib/hash.h
index a5a6cac..a345c8c 100644
--- a/lib/hash.h
+++ b/lib/hash.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
@@ -44,7 +44,7 @@ typedef size_t (*comp_function) (void *key1,
 typedef void (*curl_hash_dtor)(void *);
 
 struct curl_hash {
-  struct curl_llist **table;
+  struct curl_llist *table;
 
   /* Hash function to be used for this hash table */
   hash_function hash_func;
@@ -58,8 +58,8 @@ struct curl_hash {
 
 struct curl_hash_element {
   void   *ptr;
-  char   *key;
   size_t key_len;
+  char   key[1]; /* allocated memory following the struct */
 };
 
 struct curl_hash_iterator {
diff --git a/lib/hostcheck.c b/lib/hostcheck.c
index cbd0893..156091c 100644
--- a/lib/hostcheck.c
+++ b/lib/hostcheck.c
@@ -87,7 +87,7 @@ static int hostmatch(char *hostname, char *pattern)
   if(Curl_inet_pton(AF_INET, hostname, &ignored) > 0)
     return CURL_HOST_NOMATCH;
 #ifdef ENABLE_IPV6
-  else if(Curl_inet_pton(AF_INET6, hostname, &si6.sin6_addr) > 0)
+  if(Curl_inet_pton(AF_INET6, hostname, &si6.sin6_addr) > 0)
     return CURL_HOST_NOMATCH;
 #endif
 
diff --git a/lib/hostip.c b/lib/hostip.c
index fa4bad9..ed18763 100644
--- a/lib/hostip.c
+++ b/lib/hostip.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
@@ -143,7 +143,7 @@ void Curl_global_host_cache_dtor(void)
 }
 
 /*
- * Return # of adresses in a Curl_addrinfo struct
+ * Return # of addresses in a Curl_addrinfo struct
  */
 int Curl_num_addresses(const Curl_addrinfo *addr)
 {
@@ -573,7 +573,7 @@ int Curl_resolv_timeout(struct connectdata *conn,
 #ifdef USE_ALARM_TIMEOUT
 #ifdef HAVE_SIGACTION
   struct sigaction keep_sigact;   /* store the old struct here */
-  volatile bool keep_copysig = FALSE; /* wether old sigact has been saved */
+  volatile bool keep_copysig = FALSE; /* whether old sigact has been saved */
   struct sigaction sigact;
 #else
 #ifdef HAVE_SIGNAL
diff --git a/lib/hostip.h b/lib/hostip.h
index 1dc4079..298eeeee 100644
--- a/lib/hostip.h
+++ b/lib/hostip.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
@@ -130,7 +130,7 @@ int Curl_mk_dnscache(struct curl_hash *hash);
 /* prune old entries from the DNS cache */
 void Curl_hostcache_prune(struct Curl_easy *data);
 
-/* Return # of adresses in a Curl_addrinfo struct */
+/* Return # of addresses in a Curl_addrinfo struct */
 int Curl_num_addresses(const Curl_addrinfo *addr);
 
 #if defined(CURLDEBUG) && defined(HAVE_GETNAMEINFO)
diff --git a/lib/http.c b/lib/http.c
index 4c1c07f..22d4547 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
@@ -297,7 +297,8 @@ static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
     pwd = conn->passwd;
   }
 
-  snprintf(data->state.buffer, sizeof(data->state.buffer), "%s:%s", user, pwd);
+  snprintf(data->state.buffer, CURL_BUFSIZE(data->set.buffer_size),
+           "%s:%s", user, pwd);
 
   result = Curl_base64_encode(data,
                               data->state.buffer, strlen(data->state.buffer),
@@ -644,10 +645,10 @@ output_auth_headers(struct connectdata *conn,
           proxy ? "Proxy" : "Server", auth,
           proxy ? (conn->http_proxy.user ? conn->http_proxy.user : "") :
                   (conn->user ? conn->user : ""));
-    authstatus->multi = (!authstatus->done) ? TRUE : FALSE;
+    authstatus->multipass = (!authstatus->done) ? TRUE : FALSE;
   }
   else
-    authstatus->multi = FALSE;
+    authstatus->multipass = FALSE;
 
   return CURLE_OK;
 }
@@ -1196,8 +1197,7 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
            This needs FIXing.
         */
         return CURLE_SEND_ERROR;
-      else
-        Curl_pipeline_leave_write(conn);
+      Curl_pipeline_leave_write(conn);
     }
   }
   Curl_add_buffer_free(in);
@@ -1358,6 +1358,10 @@ CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
   if(result)
     return result;
 
+  if(conn->bits.proxy_connect_closed)
+    /* this is not an error, just part of the connection negotiation */
+    return CURLE_OK;
+
   if(CONNECT_FIRSTSOCKET_PROXY_SSL())
     return CURLE_OK; /* wait for HTTPS proxy SSL initialization to complete */
 
@@ -1365,7 +1369,7 @@ CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
     /* nothing else to do except wait right now - we're not done here. */
     return CURLE_OK;
 
-  if(conn->given->flags & PROTOPT_SSL) {
+  if(conn->given->protocol & CURLPROTO_HTTPS) {
     /* perform SSL initialization */
     result = https_connecting(conn, done);
     if(result)
@@ -1425,7 +1429,10 @@ CURLcode Curl_http_done(struct connectdata *conn,
   struct Curl_easy *data = conn->data;
   struct HTTP *http = data->req.protop;
 
-  infof(data, "Curl_http_done: called premature == %d\n", premature);
+  /* Clear multipass flag. If authentication isn't done yet, then it will get
+   * a chance to be set back to true when we output the next auth header */
+  data->state.authhost.multipass = FALSE;
+  data->state.authproxy.multipass = FALSE;
 
   Curl_unencode_cleanup(conn);
 
@@ -1511,6 +1518,20 @@ static bool use_http_1_1plus(const struct Curl_easy *data,
           (data->set.httpversion >= CURL_HTTP_VERSION_1_1));
 }
 
+static const char *get_http_string(const struct Curl_easy *data,
+                                   const struct connectdata *conn)
+{
+#ifdef USE_NGHTTP2
+  if(conn->proto.httpc.h2)
+    return "2";
+#endif
+
+  if(use_http_1_1plus(data, conn))
+    return "1.1";
+
+  return "1.0";
+}
+
 /* check and possibly add an Expect: header */
 static CURLcode expect100(struct Curl_easy *data,
                           struct connectdata *conn,
@@ -1849,7 +1870,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
   if(result)
     return result;
 
-  if((data->state.authhost.multi || data->state.authproxy.multi) &&
+  if((data->state.authhost.multipass || data->state.authproxy.multipass) &&
      (httpreq != HTTPREQ_GET) &&
      (httpreq != HTTPREQ_HEAD)) {
     /* Auth is required and we are not authenticated yet. Make a PUT or POST
@@ -2134,32 +2155,31 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
       }
 
       if(seekerr != CURL_SEEKFUNC_OK) {
+        curl_off_t passed=0;
+
         if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
           failf(data, "Could not seek stream");
           return CURLE_READ_ERROR;
         }
         /* when seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
-        else {
-          curl_off_t passed=0;
-          do {
-            size_t readthisamountnow =
-              (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
-              BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
-
-            size_t actuallyread =
-              data->state.fread_func(data->state.buffer, 1, readthisamountnow,
-                                     data->state.in);
-
-            passed += actuallyread;
-            if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
-              /* this checks for greater-than only to make sure that the
-                 CURL_READFUNC_ABORT return code still aborts */
-              failf(data, "Could only read %" CURL_FORMAT_CURL_OFF_T
-                    " bytes from the input", passed);
-              return CURLE_READ_ERROR;
-            }
-          } while(passed < data->state.resume_from);
-        }
+        do {
+          size_t readthisamountnow =
+            (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
+            BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
+
+          size_t actuallyread =
+            data->state.fread_func(data->state.buffer, 1, readthisamountnow,
+                                   data->state.in);
+
+          passed += actuallyread;
+          if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
+            /* this checks for greater-than only to make sure that the
+               CURL_READFUNC_ABORT return code still aborts */
+            failf(data, "Could only read %" CURL_FORMAT_CURL_OFF_T
+                  " bytes from the input", passed);
+            return CURLE_READ_ERROR;
+          }
+        } while(passed < data->state.resume_from);
       }
 
       /* now, decrease the size of the read */
@@ -2225,9 +2245,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
     }
   }
 
-  /* Use 1.1 unless the user specifically asked for 1.0 or the server only
-     supports 1.0 */
-  httpstring= use_http_1_1plus(data, conn)?"1.1":"1.0";
+  httpstring = get_http_string(data, conn);
 
   /* initialize a dynamic send-buffer */
   req_buffer = Curl_add_buffer_init();
@@ -2294,20 +2312,10 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
                      te
       );
 
-  /* clear userpwd to avoid re-using credentials from re-used connections */
+  /* clear userpwd and proxyuserpwd to avoid re-using old credentials
+   * from re-used connections */
   Curl_safefree(conn->allocptr.userpwd);
-
-  /*
-   * Free proxyuserpwd for Negotiate/NTLM. Cannot reuse as it is associated
-   * with the connection and shouldn't be repeated over it either.
-   */
-  switch(data->state.authproxy.picked) {
-  case CURLAUTH_NEGOTIATE:
-  case CURLAUTH_NTLM:
-  case CURLAUTH_NTLM_WB:
-    Curl_safefree(conn->allocptr.proxyuserpwd);
-    break;
-  }
+  Curl_safefree(conn->allocptr.proxyuserpwd);
 
   if(result)
     return result;
@@ -2501,7 +2509,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
       postsize = data->state.infilesize;
 
     if((postsize != -1) && !data->req.upload_chunky &&
-       !Curl_checkheaders(conn, "Content-Length:")) {
+       (conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length:"))) {
       /* only add Content-Length if not uploading chunked */
       result = Curl_add_bufferf(req_buffer,
                                 "Content-Length: %" CURL_FORMAT_CURL_OFF_T
@@ -2553,7 +2561,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
        we don't upload data chunked, as RFC2616 forbids us to set both
        kinds of headers (Transfer-Encoding: chunked and Content-Length) */
     if((postsize != -1) && !data->req.upload_chunky &&
-       !Curl_checkheaders(conn, "Content-Length:")) {
+       (conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length:"))) {
       /* we allow replacing this header if not during auth negotiation,
          although it isn't very wise to actually set your own */
       result = Curl_add_bufferf(req_buffer,
@@ -2807,8 +2815,7 @@ checkrtspprefix(struct Curl_easy *data,
 #endif /* CURL_DOES_CONVERSIONS */
   if(checkprefix("RTSP/", s))
     return TRUE;
-  else
-    return FALSE;
+  return FALSE;
 }
 #endif /* CURL_DISABLE_RTSP */
 
@@ -3229,9 +3236,17 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
           k->maxdownload = k->size;
         }
 
-        /* If max download size is *zero* (nothing) we already
-           have nothing and can safely return ok now! */
-        if(0 == k->maxdownload)
+        /* If max download size is *zero* (nothing) we already have
+           nothing and can safely return ok now!  But for HTTP/2, we'd
+           like to call http2_handle_stream_close to properly close a
+           stream.  In order to do this, we keep reading until we
+           close the stream. */
+        if(0 == k->maxdownload
+#if defined(USE_NGHTTP2)
+           && !((conn->handler->protocol & PROTO_FAMILY_HTTP) &&
+                conn->httpversion == 20)
+#endif
+           )
           *stop_reading = TRUE;
 
         if(*stop_reading) {
@@ -3288,7 +3303,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
         /*
          * https://tools.ietf.org/html/rfc7230#section-3.1.2
          *
-         * The reponse code is always a three-digit number in HTTP as the spec
+         * The response code is always a three-digit number in HTTP as the spec
          * says. We try to allow any number here, but we cannot make
          * guarantees on future behaviors since it isn't within the protocol.
          */
diff --git a/lib/http.h b/lib/http.h
index 9fb669c..7ce4bd9 100644
--- a/lib/http.h
+++ b/lib/http.h
@@ -219,6 +219,10 @@ struct http_conn {
 
   /* this is a hash of all individual streams (Curl_easy structs) */
   struct h2settings settings;
+
+  /* list of settings that will be sent */
+  nghttp2_settings_entry local_settings[3];
+  size_t local_settings_num;
 #else
   int unused; /* prevent a compiler warning */
 #endif
diff --git a/lib/http2.c b/lib/http2.c
index 4cc17ba..264c667 100644
--- a/lib/http2.c
+++ b/lib/http2.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
@@ -116,18 +116,11 @@ static int http2_getsock(struct connectdata *conn,
   return http2_perform_getsock(conn, sock, numsocks);
 }
 
-static CURLcode http2_disconnect(struct connectdata *conn,
-                                 bool dead_connection)
+/*
+ * http2_stream_free() free HTTP2 stream related data
+ */
+static void http2_stream_free(struct HTTP *http)
 {
-  struct HTTP *http = conn->data->req.protop;
-  struct http_conn *c = &conn->proto.httpc;
-  (void)dead_connection;
-
-  DEBUGF(infof(conn->data, "HTTP/2 DISCONNECT starts now\n"));
-
-  nghttp2_session_del(c->h2);
-  Curl_safefree(c->inbuf);
-
   if(http) {
     Curl_add_buffer_free(http->header_recvbuf);
     http->header_recvbuf = NULL; /* clear the pointer */
@@ -139,6 +132,19 @@ static CURLcode http2_disconnect(struct connectdata *conn,
     free(http->push_headers);
     http->push_headers = NULL;
   }
+}
+
+static CURLcode http2_disconnect(struct connectdata *conn,
+                                 bool dead_connection)
+{
+  struct http_conn *c = &conn->proto.httpc;
+  (void)dead_connection;
+
+  DEBUGF(infof(conn->data, "HTTP/2 DISCONNECT starts now\n"));
+
+  nghttp2_session_del(c->h2);
+  Curl_safefree(c->inbuf);
+  http2_stream_free(conn->data->req.protop);
 
   DEBUGF(infof(conn->data, "HTTP/2 DISCONNECT done\n"));
 
@@ -402,6 +408,7 @@ static int push_promise(struct Curl_easy *data,
     stream = data->req.protop;
     if(!stream) {
       failf(data, "Internal NULL stream!\n");
+      (void)Curl_close(newhandle);
       rv = 1;
       goto fail;
     }
@@ -415,9 +422,11 @@ static int push_promise(struct Curl_easy *data,
       free(stream->push_headers[i]);
     free(stream->push_headers);
     stream->push_headers = NULL;
+    stream->push_headers_used = 0;
 
     if(rv) {
       /* denied, kill off the new handle again */
+      http2_stream_free(newhandle->req.protop);
       (void)Curl_close(newhandle);
       goto fail;
     }
@@ -432,6 +441,7 @@ static int push_promise(struct Curl_easy *data,
     rc = Curl_multi_add_perform(data->multi, newhandle, conn);
     if(rc) {
       infof(data, "failed to add handle to multi\n");
+      http2_stream_free(newhandle->req.protop);
       Curl_close(newhandle);
       rv = 1;
       goto fail;
@@ -587,6 +597,9 @@ static int on_invalid_frame_recv(nghttp2_session *session,
 {
   struct Curl_easy *data_s = NULL;
   (void)userp;
+#if !defined(DEBUGBUILD) || defined(CURL_DISABLE_VERBOSE_STRINGS)
+  (void)lib_error_code;
+#endif
 
   data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id);
   if(data_s) {
@@ -697,6 +710,9 @@ static int on_frame_not_send(nghttp2_session *session,
 {
   struct Curl_easy *data_s;
   (void)userp;
+#if !defined(DEBUGBUILD) || defined(CURL_DISABLE_VERBOSE_STRINGS)
+  (void)lib_error_code;
+#endif
 
   data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id);
   if(data_s) {
@@ -967,14 +983,6 @@ static ssize_t data_source_read_callback(nghttp2_session *session,
   return nread;
 }
 
-/*
- * The HTTP2 settings we send in the Upgrade request
- */
-static nghttp2_settings_entry settings[] = {
-  { NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, 100 },
-  { NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE, HTTP2_HUGE_WINDOW_SIZE },
-};
-
 #define H2_BUFSIZE 32768
 
 #ifdef NGHTTP2_HAS_ERROR_CALLBACK
@@ -990,6 +998,23 @@ static int error_callback(nghttp2_session *session,
 }
 #endif
 
+static void populate_settings(struct connectdata *conn,
+                              struct http_conn *httpc)
+{
+  nghttp2_settings_entry *iv = httpc->local_settings;
+
+  iv[0].settings_id = NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS;
+  iv[0].value = 100;
+
+  iv[1].settings_id = NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE;
+  iv[1].value = HTTP2_HUGE_WINDOW_SIZE;
+
+  iv[2].settings_id = NGHTTP2_SETTINGS_ENABLE_PUSH;
+  iv[2].value = conn->data->multi->push_cb != NULL;
+
+  httpc->local_settings_num = 3;
+}
+
 void Curl_http2_done(struct connectdata *conn, bool premature)
 {
   struct Curl_easy *data = conn->data;
@@ -1103,16 +1128,14 @@ CURLcode Curl_http2_request_upgrade(Curl_send_buffer *req,
   size_t blen;
   struct SingleRequest *k = &conn->data->req;
   uint8_t *binsettings = conn->proto.httpc.binsettings;
+  struct http_conn *httpc = &conn->proto.httpc;
 
-  /* As long as we have a fixed set of settings, we don't have to dynamically
-   * figure out the base64 strings since it'll always be the same. However,
-   * the settings will likely not be fixed every time in the future.
-   */
+  populate_settings(conn, httpc);
 
   /* this returns number of bytes it wrote */
   binlen = nghttp2_pack_settings_payload(binsettings, H2_BINSETTINGS_LEN,
-                                         settings,
-                                         sizeof(settings)/sizeof(settings[0]));
+                                         httpc->local_settings,
+                                         httpc->local_settings_num);
   if(!binlen) {
     failf(conn->data, "nghttp2 unexpectedly failed on pack_settings_payload");
     return CURLE_FAILED_INIT;
@@ -1862,28 +1885,22 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
 
   /* Warn stream may be rejected if cumulative length of headers is too large.
      It appears nghttp2 will not send a header frame larger than 64KB. */
+#define MAX_ACC 60000  /* <64KB to account for some overhead */
   {
     size_t acc = 0;
-    const size_t max_acc = 60000;  /* <64KB to account for some overhead */
 
     for(i = 0; i < nheader; ++i) {
-      if(nva[i].namelen > max_acc - acc)
-        break;
-      acc += nva[i].namelen;
-
-      if(nva[i].valuelen > max_acc - acc)
-        break;
-      acc += nva[i].valuelen;
+      acc += nva[i].namelen + nva[i].valuelen;
 
       DEBUGF(infof(conn->data, "h2 header: %.*s:%.*s\n",
                    nva[i].namelen, nva[i].name,
                    nva[i].valuelen, nva[i].value));
     }
 
-    if(i != nheader) {
+    if(acc > MAX_ACC) {
       infof(conn->data, "http2_send: Warning: The cumulative length of all "
-                        "headers exceeds %zu bytes and that could cause the "
-                        "stream to be rejected.\n", max_acc);
+            "headers exceeds %zu bytes and that could cause the "
+            "stream to be rejected.\n", MAX_ACC);
     }
   }
 
@@ -2037,10 +2054,13 @@ CURLcode Curl_http2_switched(struct connectdata *conn,
                                          conn->data);
   }
   else {
+    populate_settings(conn, httpc);
+
     /* stream ID is unknown at this point */
     stream->stream_id = -1;
-    rv = nghttp2_submit_settings(httpc->h2, NGHTTP2_FLAG_NONE, settings,
-                                 sizeof(settings) / sizeof(settings[0]));
+    rv = nghttp2_submit_settings(httpc->h2, NGHTTP2_FLAG_NONE,
+                                 httpc->local_settings,
+                                 httpc->local_settings_num);
     if(rv != 0) {
       failf(data, "nghttp2_submit_settings() failed: %s(%d)",
             nghttp2_strerror(rv), rv);
diff --git a/lib/http_ntlm.c b/lib/http_ntlm.c
index 21c77cd..8a78bd2 100644
--- a/lib/http_ntlm.c
+++ b/lib/http_ntlm.c
@@ -27,7 +27,7 @@
 /*
  * NTLM details:
  *
- * http://davenport.sourceforge.net/ntlm.html
+ * https://davenport.sourceforge.io/ntlm.html
  * https://www.innovation.ch/java/ntlm.html
  */
 
diff --git a/lib/http_proxy.c b/lib/http_proxy.c
index e0213f3..d53685f 100644
--- a/lib/http_proxy.c
+++ b/lib/http_proxy.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
@@ -98,16 +98,21 @@ CURLcode Curl_proxy_connect(struct connectdata *conn, int sockindex)
      * original pointer
      *
      * This function might be called several times in the multi interface case
-     * if the proxy's CONNTECT response is not instant.
+     * if the proxy's CONNECT response is not instant.
      */
     prot_save = conn->data->req.protop;
     memset(&http_proxy, 0, sizeof(http_proxy));
     conn->data->req.protop = &http_proxy;
     connkeep(conn, "HTTP proxy CONNECT");
-    if(sockindex == SECONDARYSOCKET)
-      hostname = conn->secondaryhostname;
-    else if(conn->bits.conn_to_host)
+
+    /* for the secondary socket (FTP), use the "connect to host"
+     * but ignore the "connect to port" (use the secondary port)
+     */
+
+    if(conn->bits.conn_to_host)
       hostname = conn->conn_to_host.name;
+    else if(sockindex == SECONDARYSOCKET)
+      hostname = conn->secondaryhostname;
     else
       hostname = conn->host.name;
 
@@ -199,7 +204,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
       free(host_port);
 
       if(!result) {
-        char *host=(char *)"";
+        char *host = NULL;
         const char *proxyconn="";
         const char *useragent="";
         const char *http = (conn->http_proxy.proxytype == CURLPROXY_HTTP_1_0) ?
@@ -242,13 +247,13 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
                            "%s", /* Proxy-Connection */
                            hostheader,
                            http,
-                           host,
+                           host?host:"",
                            conn->allocptr.proxyuserpwd?
                            conn->allocptr.proxyuserpwd:"",
                            useragent,
                            proxyconn);
 
-        if(host && *host)
+        if(host)
           free(host);
         free(hostheader);
 
@@ -288,10 +293,8 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
       if(!Curl_conn_data_pending(conn, sockindex))
         /* return so we'll be called again polling-style */
         return CURLE_OK;
-      else {
-        DEBUGF(infof(data,
-               "Read response immediately from proxy CONNECT\n"));
-      }
+      DEBUGF(infof(data,
+             "Read response immediately from proxy CONNECT\n"));
     }
 
     /* at this point, the tunnel_connecting phase is over. */
@@ -311,8 +314,6 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
       perline = 0;
 
       while(nread < BUFSIZE && keepon && !error) {
-        int writetype;
-
         if(Curl_pgrsUpdate(conn))
           return CURLE_ABORTED_BY_CALLBACK;
 
@@ -339,7 +340,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
           }
           continue;
         }
-        else if(result) {
+        if(result) {
           keepon = FALSE;
           break;
         }
@@ -414,19 +415,20 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
           Curl_debug(data, CURLINFO_HEADER_IN,
                      line_start, (size_t)perline, conn);
 
-        /* send the header to the callback */
-        writetype = CLIENTWRITE_HEADER;
-        if(data->set.include_header)
-          writetype |= CLIENTWRITE_BODY;
+        if(!data->set.suppress_connect_headers) {
+          /* send the header to the callback */
+          int writetype = CLIENTWRITE_HEADER;
+          if(data->set.include_header)
+            writetype |= CLIENTWRITE_BODY;
 
-        result = Curl_client_write(conn, writetype, line_start, perline);
+          result = Curl_client_write(conn, writetype, line_start, perline);
+          if(result)
+            return result;
+        }
 
         data->info.header_size += (long)perline;
         data->req.headerbytecount += (long)perline;
 
-        if(result)
-          return result;
-
         /* Newlines are CRLF, so the CR is ignored as the line isn't
            really terminated until the LF comes. Treat a following CR
            as end-of-headers as well.*/
@@ -510,33 +512,34 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
         }
         else if(checkprefix("Content-Length:", line_start)) {
           if(k->httpcode/100 == 2) {
-            /* A server MUST NOT send any Transfer-Encoding or
-               Content-Length header fields in a 2xx (Successful)
-               response to CONNECT. (RFC 7231 section 4.3.6) */
-            failf(data, "Content-Length: in %03d response",
+            /* A client MUST ignore any Content-Length or Transfer-Encoding
+               header fields received in a successful response to CONNECT.
+               "Successful" described as: 2xx (Successful). RFC 7231 4.3.6 */
+            infof(data, "Ignoring Content-Length in CONNECT %03d response\n",
                   k->httpcode);
-            return CURLE_RECV_ERROR;
           }
-
-          cl = curlx_strtoofft(line_start +
-                               strlen("Content-Length:"), NULL, 10);
+          else {
+            cl = curlx_strtoofft(line_start +
+                                 strlen("Content-Length:"), NULL, 10);
+          }
         }
         else if(Curl_compareheader(line_start, "Connection:", "close"))
           closeConnection = TRUE;
-        else if(Curl_compareheader(line_start,
-                                   "Transfer-Encoding:",
-                                   "chunked")) {
+        else if(checkprefix("Transfer-Encoding:", line_start)) {
           if(k->httpcode/100 == 2) {
-            /* A server MUST NOT send any Transfer-Encoding or
-               Content-Length header fields in a 2xx (Successful)
-               response to CONNECT. (RFC 7231 section 4.3.6) */
-            failf(data, "Transfer-Encoding: in %03d response", k->httpcode);
-            return CURLE_RECV_ERROR;
+            /* A client MUST ignore any Content-Length or Transfer-Encoding
+               header fields received in a successful response to CONNECT.
+               "Successful" described as: 2xx (Successful). RFC 7231 4.3.6 */
+            infof(data, "Ignoring Transfer-Encoding in "
+                  "CONNECT %03d response\n", k->httpcode);
+          }
+          else if(Curl_compareheader(line_start,
+                                     "Transfer-Encoding:", "chunked")) {
+            infof(data, "CONNECT responded chunked\n");
+            chunked_encoding = TRUE;
+            /* init our chunky engine */
+            Curl_httpchunk_init(conn);
           }
-          infof(data, "CONNECT responded chunked\n");
-          chunked_encoding = TRUE;
-          /* init our chunky engine */
-          Curl_httpchunk_init(conn);
         }
         else if(Curl_compareheader(line_start, "Proxy-Connection:", "close"))
           closeConnection = TRUE;
@@ -612,11 +615,9 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
     if(conn->bits.proxy_connect_closed)
       /* this is not an error, just part of the connection negotiation */
       return CURLE_OK;
-    else {
-      failf(data, "Received HTTP code %d from proxy after CONNECT",
-            data->req.httpcode);
-      return CURLE_RECV_ERROR;
-    }
+    failf(data, "Received HTTP code %d from proxy after CONNECT",
+          data->req.httpcode);
+    return CURLE_RECV_ERROR;
   }
 
   conn->tunnel_state[sockindex] = TUNNEL_COMPLETE;
diff --git a/lib/imap.c b/lib/imap.c
index 78dc6fa..b528f77 100644
--- a/lib/imap.c
+++ b/lib/imap.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
@@ -130,7 +130,8 @@ const struct Curl_handler Curl_handler_imap = {
   ZERO_NULL,                        /* readwrite */
   PORT_IMAP,                        /* defport */
   CURLPROTO_IMAP,                   /* protocol */
-  PROTOPT_CLOSEACTION               /* flags */
+  PROTOPT_CLOSEACTION|              /* flags */
+  PROTOPT_URLOPTIONS
 };
 
 #ifdef USE_SSL
@@ -952,7 +953,7 @@ static CURLcode imap_state_starttls_resp(struct connectdata *conn,
 
   if(imapcode != 'O') {
     if(data->set.use_ssl != CURLUSESSL_TRY) {
-      failf(data, "STARTTLS denied. %c", imapcode);
+      failf(data, "STARTTLS denied");
       result = CURLE_USE_SSL_FAILED;
     }
     else
@@ -1748,7 +1749,7 @@ static CURLcode imap_setup_connection(struct connectdata *conn)
  *
  * imap_sendf()
  *
- * Sends the formated string as an IMAP command to the server.
+ * Sends the formatted string as an IMAP command to the server.
  *
  * Designed to never block.
  */
diff --git a/lib/libcurl.rc b/lib/libcurl.rc
index c1efbad..3316fba 100644
--- a/lib/libcurl.rc
+++ b/lib/libcurl.rc
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
@@ -51,7 +51,7 @@ BEGIN
       VALUE "OriginalFilename", "libcurl.dll\0"
       VALUE "ProductName",      "The curl library\0"
       VALUE "ProductVersion",   LIBCURL_VERSION "\0"
-      VALUE "LegalCopyright",   "© " LIBCURL_COPYRIGHT "\0"
+      VALUE "LegalCopyright",   "\xa9 " LIBCURL_COPYRIGHT "\0"  /* a9: Copyright symbol */
       VALUE "License",          "https://curl.haxx.se/docs/copyright.html\0"
     END
   END
diff --git a/lib/llist.c b/lib/llist.c
index 482aaa0..b8836bb 100644
--- a/lib/llist.c
+++ b/lib/llist.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
@@ -33,8 +33,8 @@
 /*
  * @unittest: 1300
  */
-static void
-llist_init(struct curl_llist *l, curl_llist_dtor dtor)
+void
+Curl_llist_init(struct curl_llist *l, curl_llist_dtor dtor)
 {
   l->size = 0;
   l->dtor = dtor;
@@ -42,20 +42,6 @@ llist_init(struct curl_llist *l, curl_llist_dtor dtor)
   l->tail = NULL;
 }
 
-struct curl_llist *
-Curl_llist_alloc(curl_llist_dtor dtor)
-{
-  struct curl_llist *list;
-
-  list = malloc(sizeof(struct curl_llist));
-  if(!list)
-    return NULL;
-
-  llist_init(list, dtor);
-
-  return list;
-}
-
 /*
  * Curl_llist_insert_next()
  *
@@ -149,8 +135,6 @@ Curl_llist_destroy(struct curl_llist *list, void *user)
   if(list) {
     while(list->size > 0)
       Curl_llist_remove(list, list->tail, user);
-
-    free(list);
   }
 }
 
diff --git a/lib/llist.h b/lib/llist.h
index 39ff408..47935ad 100644
--- a/lib/llist.h
+++ b/lib/llist.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
@@ -43,7 +43,7 @@ struct curl_llist {
   size_t size;
 };
 
-struct curl_llist *Curl_llist_alloc(curl_llist_dtor);
+void Curl_llist_init(struct curl_llist *, curl_llist_dtor);
 int Curl_llist_insert_next(struct curl_llist *, struct curl_llist_element *,
                            const void *);
 int Curl_llist_remove(struct curl_llist *, struct curl_llist_element *,
diff --git a/lib/memdebug.c b/lib/memdebug.c
index 15e8661..32d2adf 100644
--- a/lib/memdebug.c
+++ b/lib/memdebug.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
@@ -458,7 +458,7 @@ int curl_fclose(FILE *file, int line, const char *source)
 
 #define LOGLINE_BUFSIZE  1024
 
-/* this does the writting to the memory tracking log file */
+/* this does the writing to the memory tracking log file */
 void curl_memlog(const char *format, ...)
 {
   char *buf;
diff --git a/lib/mprintf.c b/lib/mprintf.c
index e4270ab..6b7d317 100644
--- a/lib/mprintf.c
+++ b/lib/mprintf.c
@@ -1096,8 +1096,7 @@ char *curl_maprintf(const char *format, ...)
     info.buffer[info.len] = 0; /* we terminate this with a zero byte */
     return info.buffer;
   }
-  else
-    return strdup("");
+  return strdup("");
 }
 
 char *curl_mvaprintf(const char *format, va_list ap_save)
@@ -1121,8 +1120,7 @@ char *curl_mvaprintf(const char *format, va_list ap_save)
     info.buffer[info.len] = 0; /* we terminate this with a zero byte */
     return info.buffer;
   }
-  else
-    return strdup("");
+  return strdup("");
 }
 
 static int storebuffer(int output, FILE *data)
diff --git a/lib/multi.c b/lib/multi.c
index 950b600..b24ce19 100644
--- a/lib/multi.c
+++ b/lib/multi.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
@@ -280,7 +280,7 @@ static int sh_init(struct curl_hash *hash, int hashsize)
 static CURLMcode multi_addmsg(struct Curl_multi *multi,
                               struct Curl_message *msg)
 {
-  if(!Curl_llist_insert_next(multi->msglist, multi->msglist->tail, msg))
+  if(!Curl_llist_insert_next(&multi->msglist, multi->msglist.tail, msg))
     return CURLM_OUT_OF_MEMORY;
 
   return CURLM_OK;
@@ -316,13 +316,8 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */
   if(Curl_conncache_init(&multi->conn_cache, chashsize))
     goto error;
 
-  multi->msglist = Curl_llist_alloc(multi_freeamsg);
-  if(!multi->msglist)
-    goto error;
-
-  multi->pending = Curl_llist_alloc(multi_freeamsg);
-  if(!multi->pending)
-    goto error;
+  Curl_llist_init(&multi->msglist, multi_freeamsg);
+  Curl_llist_init(&multi->pending, multi_freeamsg);
 
   /* allocate a new easy handle to use when closing cached connections */
   multi->closure_handle = curl_easy_init();
@@ -345,8 +340,8 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */
   Curl_conncache_destroy(&multi->conn_cache);
   Curl_close(multi->closure_handle);
   multi->closure_handle = NULL;
-  Curl_llist_destroy(multi->msglist, NULL);
-  Curl_llist_destroy(multi->pending, NULL);
+  Curl_llist_destroy(&multi->msglist, NULL);
+  Curl_llist_destroy(&multi->pending, NULL);
 
   free(multi);
   return NULL;
@@ -361,8 +356,6 @@ struct Curl_multi *curl_multi_init(void)
 CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
                                 struct Curl_easy *data)
 {
-  struct curl_llist *timeoutlist;
-
   /* First, make some basic checks that the CURLM handle is a good handle */
   if(!GOOD_MULTI_HANDLE(multi))
     return CURLM_BAD_HANDLE;
@@ -376,10 +369,8 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
   if(data->multi)
     return CURLM_ADDED_ALREADY;
 
-  /* Allocate and initialize timeout list for easy handle */
-  timeoutlist = Curl_llist_alloc(multi_freetimeout);
-  if(!timeoutlist)
-    return CURLM_OUT_OF_MEMORY;
+  /* Initialize timeout list for this handle */
+  Curl_llist_init(&data->state.timeoutlist, multi_freetimeout);
 
   /*
    * No failure allowed in this function beyond this point. And no
@@ -388,10 +379,6 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
    * function no matter what.
    */
 
-  /* Make easy handle use timeout list initialized above */
-  data->state.timeoutlist = timeoutlist;
-  timeoutlist = NULL;
-
   /* set the easy handle */
   multistate(data, CURLM_STATE_INIT);
 
@@ -532,6 +519,7 @@ static CURLcode multi_done(struct connectdata **connp,
   CURLcode result;
   struct connectdata *conn;
   struct Curl_easy *data;
+  unsigned int i;
 
   DEBUGASSERT(*connp);
 
@@ -579,7 +567,7 @@ static CURLcode multi_done(struct connectdata **connp,
       result = CURLE_ABORTED_BY_CALLBACK;
   }
 
-  if(conn->send_pipe->size + conn->recv_pipe->size != 0 &&
+  if(conn->send_pipe.size + conn->recv_pipe.size != 0 &&
      !data->set.reuse_forbid &&
      !conn->bits.close) {
     /* Stop if pipeline is not empty and we do not have to close
@@ -598,9 +586,11 @@ static CURLcode multi_done(struct connectdata **connp,
   }
 
   /* if the transfer was completed in a paused state there can be buffered
-     data left to write and then kill */
-  free(data->state.tempwrite);
-  data->state.tempwrite = NULL;
+     data left to free */
+  for(i=0; i < data->state.tempcount; i++) {
+    free(data->state.tempwrite[i].buf);
+  }
+  data->state.tempcount = 0;
 
   /* if data->set.reuse_forbid is TRUE, it means the libcurl client has
      forced us to close this connection. This is ignored for requests taking
@@ -638,7 +628,10 @@ static CURLcode multi_done(struct connectdata **connp,
 
       infof(data, "Connection #%ld to host %s left intact\n",
             conn->connection_id,
-            conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname);
+            conn->bits.socksproxy ? conn->socks_proxy.host.dispname :
+            conn->bits.httpproxy ? conn->http_proxy.host.dispname :
+            conn->bits.conn_to_host ? conn->conn_to_host.dispname :
+            conn->host.dispname);
     }
     else
       data->state.lastconnect = NULL;
@@ -692,13 +685,13 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
   if(data->easy_conn &&
      data->mstate > CURLM_STATE_DO &&
      data->mstate < CURLM_STATE_COMPLETED) {
+    /* Set connection owner so that the DONE function closes it.  We can
+       safely do this here since connection is killed. */
+    data->easy_conn->data = easy;
     /* If the handle is in a pipeline and has started sending off its
        request but not received its response yet, we need to close
        connection. */
     streamclose(data->easy_conn, "Removed with partial response");
-    /* Set connection owner so that the DONE function closes it.  We can
-       safely do this here since connection is killed. */
-    data->easy_conn->data = easy;
     easy_owns_conn = TRUE;
   }
 
@@ -735,10 +728,7 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
 
   /* destroy the timeout list that is held in the easy handle, do this *after*
      multi_done() as that may actually call Curl_expire that uses this */
-  if(data->state.timeoutlist) {
-    Curl_llist_destroy(data->state.timeoutlist, NULL);
-    data->state.timeoutlist = NULL;
-  }
+  Curl_llist_destroy(&data->state.timeoutlist, NULL);
 
   /* as this was using a shared connection cache we clear the pointer to that
      since we're not part of that multi handle anymore */
@@ -761,11 +751,11 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
   /* make sure there's no pending message in the queue sent from this easy
      handle */
 
-  for(e = multi->msglist->head; e; e = e->next) {
+  for(e = multi->msglist.head; e; e = e->next) {
     struct Curl_message *msg = e->ptr;
 
     if(msg->extmsg.easy_handle == easy) {
-      Curl_llist_remove(multi->msglist, e, NULL);
+      Curl_llist_remove(&multi->msglist, e, NULL);
       /* there can only be one from this specific handle */
       break;
     }
@@ -956,10 +946,8 @@ CURLMcode curl_multi_fdset(struct Curl_multi *multi,
       if(s == CURL_SOCKET_BAD)
         /* this socket is unused, break out of loop */
         break;
-      else {
-        if((int)s > this_max_fd)
-          this_max_fd = (int)s;
-      }
+      if((int)s > this_max_fd)
+        this_max_fd = (int)s;
     }
 
     data = data->next; /* check next handle */
@@ -970,6 +958,8 @@ CURLMcode curl_multi_fdset(struct Curl_multi *multi,
   return CURLM_OK;
 }
 
+#define NUM_POLLS_ON_STACK 10
+
 CURLMcode curl_multi_wait(struct Curl_multi *multi,
                           struct curl_waitfd extra_fds[],
                           unsigned int extra_nfds,
@@ -983,8 +973,10 @@ CURLMcode curl_multi_wait(struct Curl_multi *multi,
   unsigned int nfds = 0;
   unsigned int curlfds;
   struct pollfd *ufds = NULL;
+  bool ufds_malloc = FALSE;
   long timeout_internal;
   int retcode = 0;
+  struct pollfd a_few_on_stack[NUM_POLLS_ON_STACK];
 
   if(!GOOD_MULTI_HANDLE(multi))
     return CURLM_BAD_HANDLE;
@@ -1024,9 +1016,14 @@ CURLMcode curl_multi_wait(struct Curl_multi *multi,
   nfds += extra_nfds; /* add the externally provided ones */
 
   if(nfds || extra_nfds) {
-    ufds = malloc(nfds * sizeof(struct pollfd));
-    if(!ufds)
-      return CURLM_OUT_OF_MEMORY;
+    if(nfds > NUM_POLLS_ON_STACK) {
+      ufds = malloc(nfds * sizeof(struct pollfd));
+      if(!ufds)
+        return CURLM_OUT_OF_MEMORY;
+      ufds_malloc = TRUE;
+    }
+    else
+      ufds = &a_few_on_stack[0];
   }
   nfds = 0;
 
@@ -1104,7 +1101,8 @@ CURLMcode curl_multi_wait(struct Curl_multi *multi,
     }
   }
 
-  free(ufds);
+  if(ufds_malloc)
+    free(ufds);
   if(ret)
     *ret = retcode;
   return CURLM_OK;
@@ -1307,6 +1305,8 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
   CURLcode result = CURLE_OK;
   struct SingleRequest *k;
   time_t timeout_ms;
+  time_t recv_timeout_ms;
+  time_t send_timeout_ms;
   int control;
 
   if(!GOOD_EASY_HANDLE(data))
@@ -1432,7 +1432,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
         multistate(data, CURLM_STATE_CONNECT_PEND);
 
         /* add this handle to the list of connect-pending handles */
-        if(!Curl_llist_insert_next(multi->pending, multi->pending->tail, data))
+        if(!Curl_llist_insert_next(&multi->pending, multi->pending.tail, data))
           result = CURLE_OUT_OF_MEMORY;
         else
           result = CURLE_OK;
@@ -1477,8 +1477,8 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
       struct connectdata *conn = data->easy_conn;
       const char *hostname;
 
-      if(conn->bits.proxy)
-        hostname = conn->proxy.name;
+      if(conn->bits.httpproxy)
+        hostname = conn->http_proxy.host.name;
       else if(conn->bits.conn_to_host)
         hostname = conn->conn_to_host.name;
       else
@@ -1826,19 +1826,30 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
       else
         result = Curl_speedcheck(data, now);
 
-      if(( (data->set.max_send_speed == 0) ||
-           (Curl_pgrsLimitWaitTime(data->progress.uploaded,
-                                   data->progress.ul_limit_size,
-                                   data->set.max_send_speed,
-                                   data->progress.ul_limit_start,
-                                   now) <= 0))  &&
-         ( (data->set.max_recv_speed == 0) ||
-           (Curl_pgrsLimitWaitTime(data->progress.downloaded,
-                                   data->progress.dl_limit_size,
-                                   data->set.max_recv_speed,
-                                   data->progress.dl_limit_start,
-                                   now) <= 0)))
-        multistate(data, CURLM_STATE_PERFORM);
+      if(!result) {
+        send_timeout_ms = 0;
+        if(data->set.max_send_speed > 0)
+          send_timeout_ms = Curl_pgrsLimitWaitTime(data->progress.uploaded,
+                                data->progress.ul_limit_size,
+                                data->set.max_send_speed,
+                                data->progress.ul_limit_start,
+                                now);
+
+        recv_timeout_ms = 0;
+        if(data->set.max_recv_speed > 0)
+          recv_timeout_ms = Curl_pgrsLimitWaitTime(data->progress.downloaded,
+                                data->progress.dl_limit_size,
+                                data->set.max_recv_speed,
+                                data->progress.dl_limit_start,
+                                now);
+
+        if(send_timeout_ms <= 0 && recv_timeout_ms <= 0)
+          multistate(data, CURLM_STATE_PERFORM);
+        else if(send_timeout_ms >= recv_timeout_ms)
+          Curl_expire_latest(data, send_timeout_ms);
+        else
+          Curl_expire_latest(data, recv_timeout_ms);
+      }
       break;
 
     case CURLM_STATE_PERFORM:
@@ -1848,31 +1859,30 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
       bool comeback = FALSE;
 
       /* check if over send speed */
-      if(data->set.max_send_speed > 0) {
-        timeout_ms = Curl_pgrsLimitWaitTime(data->progress.uploaded,
-                                            data->progress.ul_limit_size,
-                                            data->set.max_send_speed,
-                                            data->progress.ul_limit_start,
-                                            now);
-        if(timeout_ms > 0) {
-          multistate(data, CURLM_STATE_TOOFAST);
-          Curl_expire_latest(data, timeout_ms);
-          break;
-        }
-      }
+      send_timeout_ms = 0;
+      if(data->set.max_send_speed > 0)
+        send_timeout_ms = Curl_pgrsLimitWaitTime(data->progress.uploaded,
+                                                 data->progress.ul_limit_size,
+                                                 data->set.max_send_speed,
+                                                 data->progress.ul_limit_start,
+                                                 now);
 
       /* check if over recv speed */
-      if(data->set.max_recv_speed > 0) {
-        timeout_ms = Curl_pgrsLimitWaitTime(data->progress.downloaded,
-                                            data->progress.dl_limit_size,
-                                            data->set.max_recv_speed,
-                                            data->progress.dl_limit_start,
-                                            now);
-        if(timeout_ms > 0) {
-          multistate(data, CURLM_STATE_TOOFAST);
-          Curl_expire_latest(data, timeout_ms);
-          break;
-        }
+      recv_timeout_ms = 0;
+      if(data->set.max_recv_speed > 0)
+        recv_timeout_ms = Curl_pgrsLimitWaitTime(data->progress.downloaded,
+                                                 data->progress.dl_limit_size,
+                                                 data->set.max_recv_speed,
+                                                 data->progress.dl_limit_start,
+                                                 now);
+
+      if(send_timeout_ms > 0 || recv_timeout_ms > 0) {
+        multistate(data, CURLM_STATE_TOOFAST);
+        if(send_timeout_ms >= recv_timeout_ms)
+          Curl_expire_latest(data, send_timeout_ms);
+        else
+          Curl_expire_latest(data, recv_timeout_ms);
+        break;
       }
 
       /* read/write data if it is ready to do so */
@@ -1928,11 +1938,11 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
         Curl_posttransfer(data);
 
         /* we're no longer receiving */
-        Curl_removeHandleFromPipeline(data, data->easy_conn->recv_pipe);
+        Curl_removeHandleFromPipeline(data, &data->easy_conn->recv_pipe);
 
         /* expire the new receiving pipeline head */
-        if(data->easy_conn->recv_pipe->head)
-          Curl_expire_latest(data->easy_conn->recv_pipe->head->ptr, 0);
+        if(data->easy_conn->recv_pipe.head)
+          Curl_expire_latest(data->easy_conn->recv_pipe.head->ptr, 0);
 
         /* Check if we can move pending requests to send pipe */
         Curl_multi_process_pending_handles(multi);
@@ -1997,7 +2007,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
         CURLcode res;
 
         /* Remove ourselves from the receive pipeline, if we are there. */
-        Curl_removeHandleFromPipeline(data, data->easy_conn->recv_pipe);
+        Curl_removeHandleFromPipeline(data, &data->easy_conn->recv_pipe);
         /* Check if we can move pending requests to send pipe */
         Curl_multi_process_pending_handles(multi);
 
@@ -2073,8 +2083,8 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
           /* if this has a connection, unsubscribe from the pipelines */
           Curl_pipeline_leave_write(data->easy_conn);
           Curl_pipeline_leave_read(data->easy_conn);
-          Curl_removeHandleFromPipeline(data, data->easy_conn->send_pipe);
-          Curl_removeHandleFromPipeline(data, data->easy_conn->recv_pipe);
+          Curl_removeHandleFromPipeline(data, &data->easy_conn->send_pipe);
+          Curl_removeHandleFromPipeline(data, &data->easy_conn->recv_pipe);
 
           if(stream_error) {
             /* Don't attempt to send data over a connection that timed out */
@@ -2229,8 +2239,8 @@ CURLMcode curl_multi_cleanup(struct Curl_multi *multi)
 
     Curl_hash_destroy(&multi->sockhash);
     Curl_conncache_destroy(&multi->conn_cache);
-    Curl_llist_destroy(multi->msglist, NULL);
-    Curl_llist_destroy(multi->pending, NULL);
+    Curl_llist_destroy(&multi->msglist, NULL);
+    Curl_llist_destroy(&multi->pending, NULL);
 
     /* remove all easy handles */
     data = multi->easyp;
@@ -2262,8 +2272,7 @@ CURLMcode curl_multi_cleanup(struct Curl_multi *multi)
 
     return CURLM_OK;
   }
-  else
-    return CURLM_BAD_HANDLE;
+  return CURLM_BAD_HANDLE;
 }
 
 /*
@@ -2282,24 +2291,23 @@ CURLMsg *curl_multi_info_read(struct Curl_multi *multi, int *msgs_in_queue)
 
   *msgs_in_queue = 0; /* default to none */
 
-  if(GOOD_MULTI_HANDLE(multi) && Curl_llist_count(multi->msglist)) {
+  if(GOOD_MULTI_HANDLE(multi) && Curl_llist_count(&multi->msglist)) {
     /* there is one or more messages in the list */
     struct curl_llist_element *e;
 
     /* extract the head of the list to return */
-    e = multi->msglist->head;
+    e = multi->msglist.head;
 
     msg = e->ptr;
 
     /* remove the extracted entry */
-    Curl_llist_remove(multi->msglist, e, NULL);
+    Curl_llist_remove(&multi->msglist, e, NULL);
 
-    *msgs_in_queue = curlx_uztosi(Curl_llist_count(multi->msglist));
+    *msgs_in_queue = curlx_uztosi(Curl_llist_count(&multi->msglist));
 
     return &msg->extmsg;
   }
-  else
-    return NULL;
+  return NULL;
 }
 
 /*
@@ -2394,7 +2402,7 @@ static void singlesocket(struct Curl_multi *multi,
          removed. */
       struct connectdata *easy_conn = data->easy_conn;
       if(easy_conn) {
-        if(easy_conn->recv_pipe && easy_conn->recv_pipe->size > 1) {
+        if(easy_conn->recv_pipe.size > 1) {
           /* the handle should not be removed from the pipe yet */
           remove_sock_from_hash = FALSE;
 
@@ -2403,12 +2411,12 @@ static void singlesocket(struct Curl_multi *multi,
              isn't already) */
           if(entry->easy == data) {
             if(Curl_recvpipe_head(data, easy_conn))
-              entry->easy = easy_conn->recv_pipe->head->next->ptr;
+              entry->easy = easy_conn->recv_pipe.head->next->ptr;
             else
-              entry->easy = easy_conn->recv_pipe->head->ptr;
+              entry->easy = easy_conn->recv_pipe.head->ptr;
           }
         }
-        if(easy_conn->send_pipe  && easy_conn->send_pipe->size > 1) {
+        if(easy_conn->send_pipe.size > 1) {
           /* the handle should not be removed from the pipe yet */
           remove_sock_from_hash = FALSE;
 
@@ -2417,9 +2425,9 @@ static void singlesocket(struct Curl_multi *multi,
              isn't already) */
           if(entry->easy == data) {
             if(Curl_sendpipe_head(data, easy_conn))
-              entry->easy = easy_conn->send_pipe->head->next->ptr;
+              entry->easy = easy_conn->send_pipe.head->next->ptr;
             else
-              entry->easy = easy_conn->send_pipe->head->ptr;
+              entry->easy = easy_conn->send_pipe.head->ptr;
           }
         }
         /* Don't worry about overwriting recv_pipe head with send_pipe_head,
@@ -2494,7 +2502,7 @@ static CURLMcode add_next_timeout(struct timeval now,
                                   struct Curl_easy *d)
 {
   struct timeval *tv = &d->state.expiretime;
-  struct curl_llist *list = d->state.timeoutlist;
+  struct curl_llist *list = &d->state.timeoutlist;
   struct curl_llist_element *e;
 
   /* move over the timeout list for this specific handle and remove all
@@ -2560,7 +2568,7 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
     /* or should we fall-through and do the timer-based stuff? */
     return result;
   }
-  else if(s != CURL_SOCKET_TIMEOUT) {
+  if(s != CURL_SOCKET_TIMEOUT) {
 
     struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s);
 
@@ -2585,13 +2593,11 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
          head.  If we should read from the socket, take the recv_pipe head. */
       if(data->easy_conn) {
         if((ev_bitmask & CURL_POLL_OUT) &&
-           data->easy_conn->send_pipe &&
-           data->easy_conn->send_pipe->head)
-          data = data->easy_conn->send_pipe->head->ptr;
+           data->easy_conn->send_pipe.head)
+          data = data->easy_conn->send_pipe.head->ptr;
         else if((ev_bitmask & CURL_POLL_IN) &&
-                data->easy_conn->recv_pipe &&
-                data->easy_conn->recv_pipe->head)
-          data = data->easy_conn->recv_pipe->head->ptr;
+                data->easy_conn->recv_pipe.head)
+          data = data->easy_conn->recv_pipe.head->ptr;
       }
 
       if(data->easy_conn &&
@@ -2928,7 +2934,7 @@ void Curl_expire(struct Curl_easy *data, time_t milli)
 
   set = Curl_tvnow();
   set.tv_sec += (long)(milli/1000);
-  set.tv_usec += (milli%1000)*1000;
+  set.tv_usec += (long)(milli%1000)*1000;
 
   if(set.tv_usec >= 1000000) {
     set.tv_sec++;
@@ -2943,13 +2949,13 @@ void Curl_expire(struct Curl_easy *data, time_t milli)
     if(diff > 0) {
       /* the new expire time was later so just add it to the queue
          and get out */
-      multi_addtimeout(data->state.timeoutlist, &set);
+      multi_addtimeout(&data->state.timeoutlist, &set);
       return;
     }
 
     /* the new time is newer than the presently set one, so add the current
        to the queue and update the head */
-    multi_addtimeout(data->state.timeoutlist, nowp);
+    multi_addtimeout(&data->state.timeoutlist, nowp);
 
     /* Since this is an updated time, we must remove the previous entry from
        the splay tree first and then re-add the new value */
@@ -2985,7 +2991,7 @@ void Curl_expire_latest(struct Curl_easy *data, time_t milli)
 
   set = Curl_tvnow();
   set.tv_sec += (long)(milli / 1000);
-  set.tv_usec += (milli % 1000) * 1000;
+  set.tv_usec += (long)(milli % 1000) * 1000;
 
   if(set.tv_usec >= 1000000) {
     set.tv_sec++;
@@ -2995,11 +3001,14 @@ void Curl_expire_latest(struct Curl_easy *data, time_t milli)
   if(expire->tv_sec || expire->tv_usec) {
     /* This means that the struct is added as a node in the splay tree.
        Compare if the new time is earlier, and only remove-old/add-new if it
-         is. */
+       is. */
     time_t diff = curlx_tvdiff(set, *expire);
-    if(diff > 0)
-      /* the new expire time was later than the top time, so just skip this */
+    if((diff > 0) && (diff < milli)) {
+      /* if the new expire time is later than the top time, skip it, but not
+         if the diff is larger than the new offset since then the previous
+         time is already expired! */
       return;
+    }
   }
 
   /* Just add the timeout like normal */
@@ -3026,7 +3035,7 @@ void Curl_expire_clear(struct Curl_easy *data)
   if(nowp->tv_sec || nowp->tv_usec) {
     /* Since this is an cleared time, we must remove the previous entry from
        the splay tree */
-    struct curl_llist *list = data->state.timeoutlist;
+    struct curl_llist *list = &data->state.timeoutlist;
 
     rc = Curl_splayremovebyaddr(multi->timetree,
                                 &data->state.timenode,
@@ -3086,17 +3095,17 @@ curl_off_t Curl_multi_chunk_length_penalty_size(struct Curl_multi *multi)
 
 struct curl_llist *Curl_multi_pipelining_site_bl(struct Curl_multi *multi)
 {
-  return multi->pipelining_site_bl;
+  return &multi->pipelining_site_bl;
 }
 
 struct curl_llist *Curl_multi_pipelining_server_bl(struct Curl_multi *multi)
 {
-  return multi->pipelining_server_bl;
+  return &multi->pipelining_server_bl;
 }
 
 void Curl_multi_process_pending_handles(struct Curl_multi *multi)
 {
-  struct curl_llist_element *e = multi->pending->head;
+  struct curl_llist_element *e = multi->pending.head;
 
   while(e) {
     struct Curl_easy *data = e->ptr;
@@ -3106,7 +3115,7 @@ void Curl_multi_process_pending_handles(struct Curl_multi *multi)
       multistate(data, CURLM_STATE_CONNECT);
 
       /* Remove this node from the list */
-      Curl_llist_remove(multi->pending, e, NULL);
+      Curl_llist_remove(&multi->pending, e, NULL);
 
       /* Make sure that the handle will be processed soonish. */
       Curl_expire_latest(data, 0);
diff --git a/lib/multihandle.h b/lib/multihandle.h
index 0b78de9..915b857 100644
--- a/lib/multihandle.h
+++ b/lib/multihandle.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
@@ -80,10 +80,10 @@ struct Curl_multi {
   int num_alive; /* amount of easy handles that are added but have not yet
                     reached COMPLETE state */
 
-  struct curl_llist *msglist; /* a list of messages from completed transfers */
+  struct curl_llist msglist; /* a list of messages from completed transfers */
 
-  struct curl_llist *pending; /* Curl_easys that are in the
-                                 CURLM_STATE_CONNECT_PEND state */
+  struct curl_llist pending; /* Curl_easys that are in the
+                                CURLM_STATE_CONNECT_PEND state */
 
   /* callback function and user data pointer for the *socket() API */
   curl_socket_callback socket_cb;
@@ -138,11 +138,11 @@ struct Curl_multi {
                                      bigger than this is not
                                      considered for pipelining */
 
-  struct curl_llist *pipelining_site_bl; /* List of sites that are blacklisted
-                                            from pipelining */
+  struct curl_llist pipelining_site_bl; /* List of sites that are blacklisted
+                                           from pipelining */
 
-  struct curl_llist *pipelining_server_bl; /* List of server types that are
-                                              blacklisted from pipelining */
+  struct curl_llist pipelining_server_bl; /* List of server types that are
+                                             blacklisted from pipelining */
 
   /* timer callback and user data pointer for the *socket() API */
   curl_multi_timer_callback timer_cb;
diff --git a/lib/nonblock.c b/lib/nonblock.c
index b764278..5959281 100644
--- a/lib/nonblock.c
+++ b/lib/nonblock.c
@@ -58,8 +58,7 @@ int curlx_nonblock(curl_socket_t sockfd,    /* operate on this */
   flags = sfcntl(sockfd, F_GETFL, 0);
   if(nonblock)
     return sfcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
-  else
-    return sfcntl(sockfd, F_SETFL, flags & (~O_NONBLOCK));
+  return sfcntl(sockfd, F_SETFL, flags & (~O_NONBLOCK));
 
 #elif defined(HAVE_IOCTL_FIONBIO)
 
diff --git a/lib/pingpong.c b/lib/pingpong.c
index 7a99357..b833fcd 100644
--- a/lib/pingpong.c
+++ b/lib/pingpong.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
@@ -152,7 +152,7 @@ void Curl_pp_init(struct pingpong *pp)
  *
  * Curl_pp_vsendf()
  *
- * Send the formated string as a command to a pingpong server. Note that
+ * Send the formatted string as a command to a pingpong server. Note that
  * the string should not have any CRLF appended, as this function will
  * append the necessary things itself.
  *
@@ -239,7 +239,7 @@ CURLcode Curl_pp_vsendf(struct pingpong *pp,
  *
  * Curl_pp_sendf()
  *
- * Send the formated string as a command to a pingpong server. Note that
+ * Send the formatted string as a command to a pingpong server. Note that
  * the string should not have any CRLF appended, as this function will
  * append the necessary things itself.
  *
diff --git a/lib/pingpong.h b/lib/pingpong.h
index 500100a..ee1a59b 100644
--- a/lib/pingpong.h
+++ b/lib/pingpong.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
@@ -95,7 +95,7 @@ time_t Curl_pp_state_timeout(struct pingpong *pp);
  *
  * Curl_pp_sendf()
  *
- * Send the formated string as a command to a pingpong server. Note that
+ * Send the formatted string as a command to a pingpong server. Note that
  * the string should not have any CRLF appended, as this function will
  * append the necessary things itself.
  *
@@ -108,7 +108,7 @@ CURLcode Curl_pp_sendf(struct pingpong *pp,
  *
  * Curl_pp_vsendf()
  *
- * Send the formated string as a command to a pingpong server. Note that
+ * Send the formatted string as a command to a pingpong server. Note that
  * the string should not have any CRLF appended, as this function will
  * append the necessary things itself.
  *
diff --git a/lib/pipeline.c b/lib/pipeline.c
index 40a5e82..4a14fdd 100644
--- a/lib/pipeline.c
+++ b/lib/pipeline.c
@@ -6,7 +6,7 @@
  *                             \___|\___/|_| \_\_____|
  *
  * Copyright (C) 2013, Linus Nielsen Feltzing, <linus at haxx.se>
- * Copyright (C) 2013-2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 2013 - 2017, Daniel Stenberg, <daniel at 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
@@ -69,8 +69,8 @@ bool Curl_pipeline_penalized(struct Curl_easy *data,
     curl_off_t recv_size = -2; /* Make it easy to spot in the log */
 
     /* Find the head of the recv pipe, if any */
-    if(conn->recv_pipe && conn->recv_pipe->head) {
-      struct Curl_easy *recv_handle = conn->recv_pipe->head->ptr;
+    if(conn->recv_pipe.head) {
+      struct Curl_easy *recv_handle = conn->recv_pipe.head->ptr;
 
       recv_size = recv_handle->req.size;
 
@@ -103,18 +103,18 @@ static CURLcode addHandleToPipeline(struct Curl_easy *data,
 CURLcode Curl_add_handle_to_pipeline(struct Curl_easy *handle,
                                      struct connectdata *conn)
 {
-  struct curl_llist_element *sendhead = conn->send_pipe->head;
+  struct curl_llist_element *sendhead = conn->send_pipe.head;
   struct curl_llist *pipeline;
   CURLcode result;
 
-  pipeline = conn->send_pipe;
+  pipeline = &conn->send_pipe;
 
   result = addHandleToPipeline(handle, pipeline);
 
-  if(pipeline == conn->send_pipe && sendhead != conn->send_pipe->head) {
+  if(pipeline == &conn->send_pipe && sendhead != conn->send_pipe.head) {
     /* this is a new one as head, expire it */
     Curl_pipeline_leave_write(conn); /* not in use yet */
-    Curl_expire(conn->send_pipe->head->ptr, 0);
+    Curl_expire(conn->send_pipe.head->ptr, 0);
   }
 
 #if 0 /* enable for pipeline debugging */
@@ -135,21 +135,21 @@ void Curl_move_handle_from_send_to_recv_pipe(struct Curl_easy *handle,
 {
   struct curl_llist_element *curr;
 
-  curr = conn->send_pipe->head;
+  curr = conn->send_pipe.head;
   while(curr) {
     if(curr->ptr == handle) {
-      Curl_llist_move(conn->send_pipe, curr,
-                      conn->recv_pipe, conn->recv_pipe->tail);
+      Curl_llist_move(&conn->send_pipe, curr,
+                      &conn->recv_pipe, conn->recv_pipe.tail);
 
-      if(conn->send_pipe->head) {
+      if(conn->send_pipe.head) {
         /* Since there's a new easy handle at the start of the send pipeline,
            set its timeout value to 1ms to make it trigger instantly */
         Curl_pipeline_leave_write(conn); /* not used now */
 #ifdef DEBUGBUILD
         infof(conn->data, "%p is at send pipe head B!\n",
-              (void *)conn->send_pipe->head->ptr);
+              (void *)conn->send_pipe.head->ptr);
 #endif
-        Curl_expire(conn->send_pipe->head->ptr, 0);
+        Curl_expire(conn->send_pipe.head->ptr, 0);
       }
 
       /* The receiver's list is not really interesting here since either this
@@ -191,15 +191,14 @@ bool Curl_pipeline_site_blacklisted(struct Curl_easy *handle,
 }
 
 CURLMcode Curl_pipeline_set_site_blacklist(char **sites,
-                                           struct curl_llist **list_ptr)
+                                           struct curl_llist *list)
 {
-  struct curl_llist *old_list = *list_ptr;
-  struct curl_llist *new_list = NULL;
+  /* Free the old list */
+  if(list->size)
+    Curl_llist_destroy(list, NULL);
 
   if(sites) {
-    new_list = Curl_llist_alloc((curl_llist_dtor) site_blacklist_llist_dtor);
-    if(!new_list)
-      return CURLM_OUT_OF_MEMORY;
+    Curl_llist_init(list, (curl_llist_dtor) site_blacklist_llist_dtor);
 
     /* Parse the URLs and populate the list */
     while(*sites) {
@@ -209,14 +208,14 @@ CURLMcode Curl_pipeline_set_site_blacklist(char **sites,
 
       hostname = strdup(*sites);
       if(!hostname) {
-        Curl_llist_destroy(new_list, NULL);
+        Curl_llist_destroy(list, NULL);
         return CURLM_OUT_OF_MEMORY;
       }
 
       entry = malloc(sizeof(struct site_blacklist_entry));
       if(!entry) {
         free(hostname);
-        Curl_llist_destroy(new_list, NULL);
+        Curl_llist_destroy(list, NULL);
         return CURLM_OUT_OF_MEMORY;
       }
 
@@ -233,9 +232,9 @@ CURLMcode Curl_pipeline_set_site_blacklist(char **sites,
 
       entry->hostname = hostname;
 
-      if(!Curl_llist_insert_next(new_list, new_list->tail, entry)) {
+      if(!Curl_llist_insert_next(list, list->tail, entry)) {
         site_blacklist_llist_dtor(NULL, entry);
-        Curl_llist_destroy(new_list, NULL);
+        Curl_llist_destroy(list, NULL);
         return CURLM_OUT_OF_MEMORY;
       }
 
@@ -243,14 +242,6 @@ CURLMcode Curl_pipeline_set_site_blacklist(char **sites,
     }
   }
 
-  /* Free the old list */
-  if(old_list) {
-    Curl_llist_destroy(old_list, NULL);
-  }
-
-  /* This might be NULL if sites == NULL, i.e the blacklist is cleared */
-  *list_ptr = new_list;
-
   return CURLM_OK;
 }
 
@@ -284,15 +275,14 @@ bool Curl_pipeline_server_blacklisted(struct Curl_easy *handle,
 }
 
 CURLMcode Curl_pipeline_set_server_blacklist(char **servers,
-                                             struct curl_llist **list_ptr)
+                                             struct curl_llist *list)
 {
-  struct curl_llist *old_list = *list_ptr;
-  struct curl_llist *new_list = NULL;
+  /* Free the old list */
+  if(list->size)
+    Curl_llist_destroy(list, NULL);
 
   if(servers) {
-    new_list = Curl_llist_alloc((curl_llist_dtor) server_blacklist_llist_dtor);
-    if(!new_list)
-      return CURLM_OUT_OF_MEMORY;
+    Curl_llist_init(list, (curl_llist_dtor) server_blacklist_llist_dtor);
 
     /* Parse the URLs and populate the list */
     while(*servers) {
@@ -300,12 +290,12 @@ CURLMcode Curl_pipeline_set_server_blacklist(char **servers,
 
       server_name = strdup(*servers);
       if(!server_name) {
-        Curl_llist_destroy(new_list, NULL);
+        Curl_llist_destroy(list, NULL);
         return CURLM_OUT_OF_MEMORY;
       }
 
-      if(!Curl_llist_insert_next(new_list, new_list->tail, server_name)) {
-        Curl_llist_destroy(new_list, NULL);
+      if(!Curl_llist_insert_next(list, list->tail, server_name)) {
+        Curl_llist_destroy(list, NULL);
         Curl_safefree(server_name);
         return CURLM_OUT_OF_MEMORY;
       }
@@ -314,13 +304,6 @@ CURLMcode Curl_pipeline_set_server_blacklist(char **servers,
     }
   }
 
-  /* Free the old list */
-  if(old_list) {
-    Curl_llist_destroy(old_list, NULL);
-  }
-
-  /* This might be NULL if sites == NULL, i.e the blacklist is cleared */
-  *list_ptr = new_list;
 
   return CURLM_OK;
 }
@@ -340,14 +323,14 @@ static bool pipe_head(struct Curl_easy *data,
 bool Curl_recvpipe_head(struct Curl_easy *data,
                         struct connectdata *conn)
 {
-  return pipe_head(data, conn->recv_pipe);
+  return pipe_head(data, &conn->recv_pipe);
 }
 
 /* returns TRUE if the given handle is head of the send pipe */
 bool Curl_sendpipe_head(struct Curl_easy *data,
                         struct connectdata *conn)
 {
-  return pipe_head(data, conn->send_pipe);
+  return pipe_head(data, &conn->send_pipe);
 }
 
 
diff --git a/lib/pipeline.h b/lib/pipeline.h
index a64f710..413ba31 100644
--- a/lib/pipeline.h
+++ b/lib/pipeline.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 2015 - 2017, Daniel Stenberg, <daniel at haxx.se>, et al.
  * Copyright (C) 2013 - 2014, Linus Nielsen Feltzing, <linus at haxx.se>
  *
  * This software is licensed as described in the file COPYING, which
@@ -34,13 +34,13 @@ bool Curl_pipeline_site_blacklisted(struct Curl_easy *handle,
                                     struct connectdata *conn);
 
 CURLMcode Curl_pipeline_set_site_blacklist(char **sites,
-                                           struct curl_llist **list_ptr);
+                                           struct curl_llist *list_ptr);
 
 bool Curl_pipeline_server_blacklisted(struct Curl_easy *handle,
                                       char *server_name);
 
 CURLMcode Curl_pipeline_set_server_blacklist(char **servers,
-                                             struct curl_llist **list_ptr);
+                                             struct curl_llist *list_ptr);
 
 bool Curl_pipeline_checkget_write(struct Curl_easy *data,
                                   struct connectdata *conn);
diff --git a/lib/pop3.c b/lib/pop3.c
index 9bb691c..3feb3be 100644
--- a/lib/pop3.c
+++ b/lib/pop3.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
@@ -127,7 +127,8 @@ const struct Curl_handler Curl_handler_pop3 = {
   ZERO_NULL,                        /* readwrite */
   PORT_POP3,                        /* defport */
   CURLPROTO_POP3,                   /* protocol */
-  PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY /* flags */
+  PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY | /* flags */
+  PROTOPT_URLOPTIONS
 };
 
 #ifdef USE_SSL
@@ -153,7 +154,7 @@ const struct Curl_handler Curl_handler_pop3s = {
   PORT_POP3S,                       /* defport */
   CURLPROTO_POP3S,                  /* protocol */
   PROTOPT_CLOSEACTION | PROTOPT_SSL
-  | PROTOPT_NOURLQUERY              /* flags */
+  | PROTOPT_NOURLQUERY | PROTOPT_URLOPTIONS /* flags */
 };
 #endif
 
@@ -799,7 +800,7 @@ static CURLcode pop3_state_starttls_resp(struct connectdata *conn,
 
   if(pop3code != '+') {
     if(data->set.use_ssl != CURLUSESSL_TRY) {
-      failf(data, "STARTTLS denied. %c", pop3code);
+      failf(data, "STARTTLS denied");
       result = CURLE_USE_SSL_FAILED;
     }
     else
diff --git a/lib/progress.c b/lib/progress.c
index 60627b2..cfaf404 100644
--- a/lib/progress.c
+++ b/lib/progress.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
@@ -229,16 +229,16 @@ void Curl_pgrsStartNow(struct Curl_easy *data)
  * need to wait until we're back under the speed limit, if needed.
  *
  * The way it works is by having a "starting point" (time & amount of data
- * transfered by then) used in the speed computation, to be used instead of the
- * start of the transfer.
- * This starting point is regularly moved as transfer goes on, to keep getting
- * accurate values (instead of average over the entire tranfer).
+ * transferred by then) used in the speed computation, to be used instead of
+ * the start of the transfer.  This starting point is regularly moved as
+ * transfer goes on, to keep getting accurate values (instead of average over
+ * the entire transfer).
  *
- * This function takes the current amount of data transfered, the amount at the
- * starting point, the limit (in bytes/s), the time of the starting point and
- * the current time.
+ * This function takes the current amount of data transferred, the amount at
+ * the starting point, the limit (in bytes/s), the time of the starting point
+ * and the current time.
  *
- * Returns -1 if no waiting is needed (not enough data transfered since
+ * Returns -1 if no waiting is needed (not enough data transferred since
  * starting point yet), 0 when no waiting is needed but the starting point
  * should be reset (to current), or the number of milliseconds to wait to get
  * back under the speed limit.
@@ -267,8 +267,8 @@ long Curl_pgrsLimitWaitTime(curl_off_t cursize,
   if(actual < minimum)
     /* this is a conversion on some systems (64bit time_t => 32bit long) */
     return (long)(minimum - actual);
-  else
-    return 0;
+
+  return 0;
 }
 
 void Curl_pgrsSetDownloadCounter(struct Curl_easy *data, curl_off_t size)
@@ -454,7 +454,7 @@ int Curl_pgrsUpdate(struct connectdata *conn)
         failf(data, "Callback aborted");
       return result;
     }
-    else if(data->set.fprogress) {
+    if(data->set.fprogress) {
       /* The older deprecated callback is set, call that */
       result= data->set.fprogress(data->set.progress_client,
                                   (double)data->progress.size_dl,
diff --git a/lib/rand.c b/lib/rand.c
index a51951c..8a14084 100644
--- a/lib/rand.c
+++ b/lib/rand.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
@@ -22,7 +22,9 @@
 
 #include "curl_setup.h"
 
+#ifdef HAVE_FCNTL_H
 #include <fcntl.h>
+#endif
 
 #include <curl/curl.h>
 #include "vtls/vtls.h"
@@ -61,7 +63,7 @@ static CURLcode randit(struct Curl_easy *data, unsigned int *rnd)
   /* data may be NULL! */
   result = Curl_ssl_random(data, (unsigned char *)rnd, sizeof(*rnd));
   if(result != CURLE_NOT_BUILT_IN)
-    /* only if there is no random funtion in the TLS backend do the non crypto
+    /* only if there is no random function in the TLS backend do the non crypto
        version, otherwise return result */
     return result;
 
diff --git a/lib/rtsp.c b/lib/rtsp.c
index 65c6c3b..1810cda 100644
--- a/lib/rtsp.c
+++ b/lib/rtsp.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
@@ -216,7 +216,7 @@ static CURLcode rtsp_done(struct connectdata *conn,
             CSeq_sent, CSeq_recv);
       return CURLE_RTSP_CSEQ_ERROR;
     }
-    else if(data->set.rtspreq == RTSPREQ_RECEIVE &&
+    if(data->set.rtspreq == RTSPREQ_RECEIVE &&
             (conn->proto.rtspc.rtp_channel == -1)) {
       infof(data, "Got an RTP Receive with a CSeq of %ld\n", CSeq_recv);
       /* TODO CPC: Server -> Client logic here */
@@ -648,31 +648,29 @@ static CURLcode rtsp_rtp_readwrite(struct Curl_easy *data,
         *readmore = TRUE;
         break;
       }
-      else {
-        /* We have the full RTP interleaved packet
-         * Write out the header including the leading '$' */
-        DEBUGF(infof(data, "RTP write channel %d rtp_length %d\n",
-              rtspc->rtp_channel, rtp_length));
-        result = rtp_client_write(conn, &rtp[0], rtp_length + 4);
-        if(result) {
-          failf(data, "Got an error writing an RTP packet");
-          *readmore = FALSE;
-          Curl_safefree(rtspc->rtp_buf);
-          rtspc->rtp_buf = NULL;
-          rtspc->rtp_bufsize = 0;
-          return result;
-        }
+      /* We have the full RTP interleaved packet
+       * Write out the header including the leading '$' */
+      DEBUGF(infof(data, "RTP write channel %d rtp_length %d\n",
+             rtspc->rtp_channel, rtp_length));
+      result = rtp_client_write(conn, &rtp[0], rtp_length + 4);
+      if(result) {
+        failf(data, "Got an error writing an RTP packet");
+        *readmore = FALSE;
+        Curl_safefree(rtspc->rtp_buf);
+        rtspc->rtp_buf = NULL;
+        rtspc->rtp_bufsize = 0;
+        return result;
+      }
 
-        /* Move forward in the buffer */
-        rtp_dataleft -= rtp_length + 4;
-        rtp += rtp_length + 4;
+      /* Move forward in the buffer */
+      rtp_dataleft -= rtp_length + 4;
+      rtp += rtp_length + 4;
 
-        if(data->set.rtspreq == RTSPREQ_RECEIVE) {
-          /* If we are in a passive receive, give control back
-           * to the app as often as we can.
-           */
-          k->keepon &= ~KEEP_RECV;
-        }
+      if(data->set.rtspreq == RTSPREQ_RECEIVE) {
+        /* If we are in a passive receive, give control back
+         * to the app as often as we can.
+         */
+        k->keepon &= ~KEEP_RECV;
       }
     }
     else {
@@ -703,20 +701,18 @@ static CURLcode rtsp_rtp_readwrite(struct Curl_easy *data,
     *nread = 0;
     return CURLE_OK;
   }
-  else {
-    /* Fix up k->str to point just after the last RTP packet */
-    k->str += *nread - rtp_dataleft;
+  /* Fix up k->str to point just after the last RTP packet */
+  k->str += *nread - rtp_dataleft;
 
-    /* either all of the data has been read or...
-     * rtp now points at the next byte to parse
-     */
-    if(rtp_dataleft > 0)
-      DEBUGASSERT(k->str[0] == rtp[0]);
+  /* either all of the data has been read or...
+   * rtp now points at the next byte to parse
+   */
+  if(rtp_dataleft > 0)
+    DEBUGASSERT(k->str[0] == rtp[0]);
 
-    DEBUGASSERT(rtp_dataleft <= *nread); /* sanity check */
+  DEBUGASSERT(rtp_dataleft <= *nread); /* sanity check */
 
-    *nread = rtp_dataleft;
-  }
+  *nread = rtp_dataleft;
 
   /* If we get here, we have finished with the leftover/merge buffer */
   Curl_safefree(rtspc->rtp_buf);
@@ -797,7 +793,7 @@ CURLcode Curl_rtsp_parseheader(struct connectdata *conn,
       /* If the Session ID is not set, and we find it in a response, then set
        * it.
        *
-       * Allow any non whitespace content, up to the field seperator or end of
+       * Allow any non whitespace content, up to the field separator or end of
        * line. RFC 2326 isn't 100% clear on the session ID and for example
        * gstreamer does url-encoded session ID's not covered by the standard.
        */
diff --git a/lib/security.c b/lib/security.c
index 4a8f444..f4a8763 100644
--- a/lib/security.c
+++ b/lib/security.c
@@ -367,6 +367,10 @@ int Curl_sec_read_msg(struct connectdata *conn, char *buffer,
   size_t decoded_sz = 0;
   CURLcode error;
 
+  if(!conn->mech)
+    /* not inititalized, return error */
+    return -1;
+
   DEBUGASSERT(level > PROT_NONE && level < PROT_LAST);
 
   error = Curl_base64_decode(buffer + 4, (unsigned char **)&buf, &decoded_sz);
diff --git a/lib/select.c b/lib/select.c
index 03af645..f49314b 100644
--- a/lib/select.c
+++ b/lib/select.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
@@ -129,7 +129,7 @@ int Curl_wait_ms(int timeout_ms)
  * and a file descriptor is too large for FD_SETSIZE.
  *
  * A negative timeout value makes this function wait indefinitely,
- * unles no valid file descriptor is given, when this happens the
+ * unless no valid file descriptor is given, when this happens the
  * negative timeout is ignored and the function times out immediately.
  *
  * Return values:
@@ -164,7 +164,7 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
   int r;
   int ret;
 
-#if SIZEOF_LONG != SIZEOF_INT
+#if SIZEOF_TIME_T != SIZEOF_INT
   /* wrap-around precaution */
   if(timeout_ms >= INT_MAX)
     timeout_ms = INT_MAX;
@@ -380,7 +380,7 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
  * select() is used instead.  An error is returned if select() is
  * being used and a file descriptor is too large for FD_SETSIZE.
  * A negative timeout value makes this function wait indefinitely,
- * unles no valid file descriptor is given, when this happens the
+ * unless no valid file descriptor is given, when this happens the
  * negative timeout is ignored and the function times out immediately.
  *
  * Return values:
diff --git a/lib/select.h b/lib/select.h
index e247bd9..4ed5dd2 100644
--- a/lib/select.h
+++ b/lib/select.h
@@ -24,10 +24,10 @@
 
 #include "curl_setup.h"
 
-#ifdef HAVE_SYS_POLL_H
-#include <sys/poll.h>
-#elif defined(HAVE_POLL_H)
+#ifdef HAVE_POLL_H
 #include <poll.h>
+#elif defined(HAVE_SYS_POLL_H)
+#include <sys/poll.h>
 #endif
 
 /*
diff --git a/lib/sendf.c b/lib/sendf.c
index 7601697..84b6b4b 100644
--- a/lib/sendf.c
+++ b/lib/sendf.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
@@ -33,6 +33,7 @@
 #include "non-ascii.h"
 #include "strerror.h"
 #include "select.h"
+#include "strdup.h"
 
 /* The last 3 #include files should be in this order */
 #include "curl_printf.h"
@@ -262,7 +263,7 @@ void Curl_failf(struct Curl_easy *data, const char *fmt, ...)
   va_end(ap);
 }
 
-/* Curl_sendf() sends formated data to the server */
+/* Curl_sendf() sends formatted data to the server */
 CURLcode Curl_sendf(curl_socket_t sockfd, struct connectdata *conn,
                     const char *fmt, ...)
 {
@@ -474,21 +475,58 @@ static CURLcode pausewrite(struct Curl_easy *data,
      we want to send we need to dup it to save a copy for when the sending
      is again enabled */
   struct SingleRequest *k = &data->req;
-  char *dupl = malloc(len);
-  if(!dupl)
-    return CURLE_OUT_OF_MEMORY;
+  struct UrlState *s = &data->state;
+  char *dupl;
+  unsigned int i;
+  bool newtype = TRUE;
+
+  if(s->tempcount) {
+    for(i=0; i< s->tempcount; i++) {
+      if(s->tempwrite[i].type == type) {
+        /* data for this type exists */
+        newtype = FALSE;
+        break;
+      }
+    }
+    DEBUGASSERT(i < 3);
+  }
+  else
+    i = 0;
+
+  if(!newtype) {
+    /* append new data to old data */
+
+    /* figure out the new size of the data to save */
+    size_t newlen = len + s->tempwrite[i].len;
+    /* allocate the new memory area */
+    char *newptr = realloc(s->tempwrite[i].buf, newlen);
+    if(!newptr)
+      return CURLE_OUT_OF_MEMORY;
+    /* copy the new data to the end of the new area */
+    memcpy(newptr + s->tempwrite[i].len, ptr, len);
+
+    /* update the pointer and the size */
+    s->tempwrite[i].buf = newptr;
+    s->tempwrite[i].len = newlen;
+  }
+  else {
+    dupl = Curl_memdup(ptr, len);
+    if(!dupl)
+      return CURLE_OUT_OF_MEMORY;
 
-  memcpy(dupl, ptr, len);
+    /* store this information in the state struct for later use */
+    s->tempwrite[i].buf = dupl;
+    s->tempwrite[i].len = len;
+    s->tempwrite[i].type = type;
 
-  /* store this information in the state struct for later use */
-  data->state.tempwrite = dupl;
-  data->state.tempwritesize = len;
-  data->state.tempwritetype = type;
+    if(newtype)
+      s->tempcount++;
+  }
 
   /* mark the connection as RECV paused */
   k->keepon |= KEEP_RECV_PAUSE;
 
-  DEBUGF(infof(data, "Pausing with %zu bytes in buffer for type %02x\n",
+  DEBUGF(infof(data, "Paused %zu bytes in buffer for type %02x\n",
                len, type));
 
   return CURLE_OK;
@@ -511,31 +549,10 @@ CURLcode Curl_client_chop_write(struct connectdata *conn,
   if(!len)
     return CURLE_OK;
 
-  /* If reading is actually paused, we're forced to append this chunk of data
-     to the already held data, but only if it is the same type as otherwise it
-     can't work and it'll return error instead. */
-  if(data->req.keepon & KEEP_RECV_PAUSE) {
-    size_t newlen;
-    char *newptr;
-    if(type != data->state.tempwritetype)
-      /* major internal confusion */
-      return CURLE_RECV_ERROR;
-
-    DEBUGASSERT(data->state.tempwrite);
-
-    /* figure out the new size of the data to save */
-    newlen = len + data->state.tempwritesize;
-    /* allocate the new memory area */
-    newptr = realloc(data->state.tempwrite, newlen);
-    if(!newptr)
-      return CURLE_OUT_OF_MEMORY;
-    /* copy the new data to the end of the new area */
-    memcpy(newptr + data->state.tempwritesize, ptr, len);
-    /* update the pointer and the size */
-    data->state.tempwrite = newptr;
-    data->state.tempwritesize = newlen;
-    return CURLE_OK;
-  }
+  /* If reading is paused, append this data to the already held data for this
+     type. */
+  if(data->req.keepon & KEEP_RECV_PAUSE)
+    return pausewrite(data, type, ptr, len);
 
   /* Determine the callback(s) to use. */
   if(type & CLIENTWRITE_BODY)
@@ -565,10 +582,9 @@ CURLcode Curl_client_chop_write(struct connectdata *conn,
           failf(data, "Write callback asked for PAUSE when not supported!");
           return CURLE_WRITE_ERROR;
         }
-        else
-          return pausewrite(data, type, ptr, len);
+        return pausewrite(data, type, ptr, len);
       }
-      else if(wrote != chunklen) {
+      if(wrote != chunklen) {
         failf(data, "Failed writing body (%zu != %zu)", wrote, chunklen);
         return CURLE_WRITE_ERROR;
       }
@@ -616,6 +632,8 @@ CURLcode Curl_client_write(struct connectdata *conn,
   if(0 == len)
     len = strlen(ptr);
 
+  DEBUGASSERT(type <= 3);
+
   /* FTP data may need conversion. */
   if((type & CLIENTWRITE_BODY) &&
     (conn->handler->protocol & PROTO_FAMILY_FTP) &&
@@ -652,8 +670,7 @@ CURLcode Curl_read_plain(curl_socket_t sockfd,
 #endif
     if(return_error)
       return CURLE_AGAIN;
-    else
-      return CURLE_RECV_ERROR;
+    return CURLE_RECV_ERROR;
   }
 
   /* we only return number of bytes read when we return OK */
diff --git a/lib/smb.c b/lib/smb.c
index f197fe1..51b3434 100644
--- a/lib/smb.c
+++ b/lib/smb.c
@@ -6,7 +6,7 @@
  *                             \___|\___/|_| \_\_____|
  *
  * Copyright (C) 2014, Bill Nagel <wnagel at tycoint.com>, Exacq Technologies
- * Copyright (C) 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 2016-2017, Daniel Stenberg, <daniel at 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
@@ -23,8 +23,8 @@
 
 #include "curl_setup.h"
 
-#if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \
-    (CURL_SIZEOF_CURL_OFF_T > 4)
+#if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) &&  \
+  (CURL_SIZEOF_CURL_OFF_T > 4)
 
 #if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO)
 
@@ -32,8 +32,12 @@
 
 #ifdef HAVE_PROCESS_H
 #include <process.h>
+#ifdef CURL_WINDOWS_APP
+#define getpid GetCurrentProcessId
+#else
 #define getpid _getpid
 #endif
+#endif
 
 #include "smb.h"
 #include "urldata.h"
@@ -117,18 +121,18 @@ const struct Curl_handler Curl_handler_smbs = {
 #define SERVICENAME       "?????"
 
 /* Append a string to an SMB message */
-#define MSGCAT(str) \
-  strcpy(p, (str)); \
+#define MSGCAT(str)                             \
+  strcpy(p, (str));                             \
   p += strlen(str);
 
 /* Append a null-terminated string to an SMB message */
-#define MSGCATNULL(str) \
-  strcpy(p, (str)); \
+#define MSGCATNULL(str)                         \
+  strcpy(p, (str));                             \
   p += strlen(str) + 1;
 
 /* SMB is mostly little endian */
 #if (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) || \
-   defined(__OS400__)
+  defined(__OS400__)
 static unsigned short smb_swap16(unsigned short x)
 {
   return (unsigned short) ((x << 8) | ((x >> 8) & 0xff));
@@ -137,20 +141,20 @@ static unsigned short smb_swap16(unsigned short x)
 static unsigned int smb_swap32(unsigned int x)
 {
   return (x << 24) | ((x << 8) & 0xff0000) | ((x >> 8) & 0xff00) |
-         ((x >> 24) & 0xff);
+    ((x >> 24) & 0xff);
 }
 
 #ifdef HAVE_LONGLONG
 static unsigned long long smb_swap64(unsigned long long x)
 {
   return ((unsigned long long) smb_swap32((unsigned int) x) << 32) |
-          smb_swap32((unsigned int) (x >> 32));
+    smb_swap32((unsigned int) (x >> 32));
 }
 #else
 static unsigned __int64 smb_swap64(unsigned __int64 x)
 {
   return ((unsigned __int64) smb_swap32((unsigned int) x) << 32) |
-          smb_swap32((unsigned int) (x >> 32));
+    smb_swap32((unsigned int) (x >> 32));
 }
 #endif
 #else
@@ -197,7 +201,7 @@ static void conn_state(struct connectdata *conn, enum smb_conn_state newstate)
 
   if(smb->state != newstate)
     infof(conn->data, "SMB conn %p state change from %s to %s\n",
-    (void *)smb, names[smb->state], names[newstate]);
+          (void *)smb, names[smb->state], names[newstate]);
 #endif
 
   smb->state = newstate;
@@ -223,7 +227,7 @@ static void request_state(struct connectdata *conn,
 
   if(req->state != newstate)
     infof(conn->data, "SMB request %p state change from %s to %s\n",
-    (void *)req, names[req->state], names[newstate]);
+          (void *)req, names[req->state], names[newstate]);
 #endif
 
   req->state = newstate;
@@ -308,8 +312,9 @@ static CURLcode smb_recv_message(struct connectdata *conn, void **msg)
   if(smbc->got < sizeof(unsigned int))
     return CURLE_OK;
 
-  nbt_size = Curl_read16_be((const unsigned char *)(buf +
-             sizeof(unsigned short))) + sizeof(unsigned int);
+  nbt_size = Curl_read16_be((const unsigned char *)
+                            (buf + sizeof(unsigned short))) +
+    sizeof(unsigned int);
   if(smbc->got < nbt_size)
     return CURLE_OK;
 
@@ -320,7 +325,7 @@ static CURLcode smb_recv_message(struct connectdata *conn, void **msg)
     if(nbt_size >= msg_size + sizeof(unsigned short)) {
       /* Add the byte count */
       msg_size += sizeof(unsigned short) +
-                  Curl_read16_le((const unsigned char *)&buf[msg_size]);
+        Curl_read16_le((const unsigned char *)&buf[msg_size]);
       if(nbt_size < msg_size)
         return CURLE_READ_ERROR;
     }
@@ -441,7 +446,7 @@ static CURLcode smb_send_setup(struct connectdata *conn)
 
   Curl_ntlm_core_mk_lm_hash(conn->data, conn->passwd, lm_hash);
   Curl_ntlm_core_lm_resp(lm_hash, smbc->challenge, lm);
-#if USE_NTRESPONSES
+#ifdef USE_NTRESPONSES
   Curl_ntlm_core_mk_nt_hash(conn->data, conn->passwd, nt_hash);
   Curl_ntlm_core_lm_resp(nt_hash, smbc->challenge, nt);
 #else
@@ -603,7 +608,7 @@ static CURLcode smb_send_and_recv(struct connectdata *conn, void **msg)
   /* Check if there is data in the transfer buffer */
   if(!smbc->send_size && smbc->upload_size) {
     int nread = smbc->upload_size > BUFSIZE ? BUFSIZE :
-                                              (int) smbc->upload_size;
+      (int) smbc->upload_size;
     conn->data->req.upload_fromhere = conn->data->state.uploadbuffer;
     result = Curl_fillreadbuffer(conn, nread, &nread);
     if(result && result != CURLE_AGAIN)
diff --git a/lib/smtp.c b/lib/smtp.c
index ff8e80d..adc346a 100644
--- a/lib/smtp.c
+++ b/lib/smtp.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
@@ -126,7 +126,8 @@ const struct Curl_handler Curl_handler_smtp = {
   ZERO_NULL,                        /* readwrite */
   PORT_SMTP,                        /* defport */
   CURLPROTO_SMTP,                   /* protocol */
-  PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY /* flags */
+  PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY | /* flags */
+  PROTOPT_URLOPTIONS
 };
 
 #ifdef USE_SSL
@@ -152,7 +153,7 @@ const struct Curl_handler Curl_handler_smtps = {
   PORT_SMTPS,                       /* defport */
   CURLPROTO_SMTPS,                  /* protocol */
   PROTOPT_CLOSEACTION | PROTOPT_SSL
-  | PROTOPT_NOURLQUERY              /* flags */
+  | PROTOPT_NOURLQUERY | PROTOPT_URLOPTIONS /* flags */
 };
 #endif
 
@@ -692,7 +693,7 @@ static CURLcode smtp_state_starttls_resp(struct connectdata *conn,
 
   if(smtpcode != 220) {
     if(data->set.use_ssl != CURLUSESSL_TRY) {
-      failf(data, "STARTTLS denied. %c", smtpcode);
+      failf(data, "STARTTLS denied, code %d", smtpcode);
       result = CURLE_USE_SSL_FAILED;
     }
     else
diff --git a/lib/socks.c b/lib/socks.c
index 774fb20..97a44b2 100644
--- a/lib/socks.c
+++ b/lib/socks.c
@@ -73,7 +73,7 @@ int Curl_blockread_all(struct connectdata *conn, /* connection data */
     result = Curl_read_plain(sockfd, buf, buffersize, &nread);
     if(CURLE_AGAIN == result)
       continue;
-    else if(result)
+    if(result)
       break;
 
     if(buffersize == nread) {
@@ -416,7 +416,7 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
     failf(conn->data, "SOCKS5: no connection here");
     return CURLE_COULDNT_CONNECT;
   }
-  else if(0 == result) {
+  if(0 == result) {
     failf(conn->data, "SOCKS5: connection timeout");
     return CURLE_OPERATION_TIMEDOUT;
   }
@@ -457,7 +457,7 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
     failf(conn->data, "SOCKS5 nothing to read");
     return CURLE_COULDNT_CONNECT;
   }
-  else if(0 == result) {
+  if(0 == result) {
     failf(conn->data, "SOCKS5 read timeout");
     return CURLE_OPERATION_TIMEDOUT;
   }
@@ -553,7 +553,7 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
             "SOCKS5 GSSAPI per-message authentication is not supported.");
       return CURLE_COULDNT_CONNECT;
     }
-    else if(socksreq[1] == 255) {
+    if(socksreq[1] == 255) {
 #endif
       if(!proxy_name || !*proxy_name) {
         failf(data,
@@ -772,9 +772,7 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
     }
     return CURLE_COULDNT_CONNECT;
   }
-  else {
-    infof(data, "SOCKS5 request granted.\n");
-  }
+  infof(data, "SOCKS5 request granted.\n");
 
   (void)curlx_nonblock(sock, TRUE);
   return CURLE_OK; /* Proxy was successful! */
diff --git a/lib/speedcheck.c b/lib/speedcheck.c
index bc15d97..f0daf82 100644
--- a/lib/speedcheck.c
+++ b/lib/speedcheck.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
@@ -33,42 +33,41 @@ void Curl_speedinit(struct Curl_easy *data)
   memset(&data->state.keeps_speed, 0, sizeof(struct timeval));
 }
 
+/*
+ * @unittest: 1606
+ */
 CURLcode Curl_speedcheck(struct Curl_easy *data,
                          struct timeval now)
 {
-  if((data->progress.current_speed >= 0) &&
-     data->set.low_speed_time &&
-     (Curl_tvlong(data->state.keeps_speed) != 0) &&
-     (data->progress.current_speed < data->set.low_speed_limit)) {
-    time_t howlong = Curl_tvdiff(now, data->state.keeps_speed);
-    time_t nextcheck = (data->set.low_speed_time * 1000) - howlong;
+  if((data->progress.current_speed >= 0) && data->set.low_speed_time) {
+    if(data->progress.current_speed < data->set.low_speed_limit) {
+      if(!data->state.keeps_speed.tv_sec)
+        /* under the limit at this very moment */
+        data->state.keeps_speed = now;
+      else {
+        /* how long has it been under the limit */
+        time_t howlong = Curl_tvdiff(now, data->state.keeps_speed);
 
-    /* We are now below the "low speed limit". If we are below it
-       for "low speed time" seconds we consider that enough reason
-       to abort the download. */
-    if(nextcheck <= 0) {
-      /* we have been this slow for long enough, now die */
-      failf(data,
-            "Operation too slow. "
-            "Less than %ld bytes/sec transferred the last %ld seconds",
-            data->set.low_speed_limit,
-            data->set.low_speed_time);
-      return CURLE_OPERATION_TIMEDOUT;
-    }
-    else {
-      /* wait complete low_speed_time */
-      Curl_expire_latest(data, nextcheck);
+        if(howlong >= data->set.low_speed_time * 1000) {
+          /* too long */
+          failf(data,
+                "Operation too slow. "
+                "Less than %ld bytes/sec transferred the last %ld seconds",
+                data->set.low_speed_limit,
+                data->set.low_speed_time);
+          return CURLE_OPERATION_TIMEDOUT;
+        }
+      }
     }
+    else
+      /* faster right now */
+      data->state.keeps_speed.tv_sec = 0;
   }
-  else {
-    /* we keep up the required speed all right */
-    data->state.keeps_speed = now;
 
-    if(data->set.low_speed_limit)
-      /* if there is a low speed limit enabled, we set the expire timer to
-         make this connection's speed get checked again no later than when
-         this time is up */
-      Curl_expire_latest(data, data->set.low_speed_time*1000);
-  }
+  if(data->set.low_speed_limit)
+    /* if low speed limit is enabled, set the expire timer to make this
+       connection's speed get checked again in a second */
+    Curl_expire_latest(data, 1000);
+
   return CURLE_OK;
 }
diff --git a/lib/splay.c b/lib/splay.c
index 7aa2e4b..1b301f9 100644
--- a/lib/splay.c
+++ b/lib/splay.c
@@ -110,22 +110,17 @@ struct Curl_tree *Curl_splayinsert(struct timeval i,
     t = Curl_splay(i, t);
     if(compare(i, t->key)==0) {
       /* There already exists a node in the tree with the very same key. Build
-         a linked list of nodes. We make the new 'node' struct the new master
-         node and make the previous node the first one in the 'same' list. */
+         a doubly-linked circular list of nodes. We add the new 'node' struct
+         to the end of this list. */
 
-      node->same = t;
-      node->key = i;
-      node->smaller = t->smaller;
-      node->larger = t->larger;
-
-      t->smaller = node; /* in the sub node for this same key, we use the
-                            smaller pointer to point back to the master
-                            node */
-
-      t->key = KEY_NOTUSED; /* and we set the key in the sub node to NOTUSED
+      node->key = KEY_NOTUSED; /* we set the key in the sub node to NOTUSED
                                to quickly identify this node as a subnode */
+      node->samen = t;
+      node->samep = t->samep;
+      t->samep->samen = node;
+      t->samep = node;
 
-      return node; /* new root node */
+      return t; /* the root node always stays the same */
     }
   }
 
@@ -145,16 +140,20 @@ struct Curl_tree *Curl_splayinsert(struct timeval i,
   }
   node->key = i;
 
-  node->same = NULL; /* no identical node (yet) */
+  /* no identical nodes (yet), we are the only one in the list of nodes */
+  node->samen = node;
+  node->samep = node;
   return node;
 }
 
 /* Finds and deletes the best-fit node from the tree. Return a pointer to the
-   resulting tree.  best-fit means the node with the given or lower key */
+   resulting tree.  best-fit means the smallest node if it is not larger than
+   the key */
 struct Curl_tree *Curl_splaygetbest(struct timeval i,
-                                    struct Curl_tree *t,
-                                    struct Curl_tree **removed)
+                                       struct Curl_tree *t,
+                                       struct Curl_tree **removed)
 {
+  static struct timeval tv_zero = {0, 0};
   struct Curl_tree *x;
 
   if(!t) {
@@ -162,49 +161,36 @@ struct Curl_tree *Curl_splaygetbest(struct timeval i,
     return NULL;
   }
 
-  t = Curl_splay(i, t);
+  /* find smallest */
+  t = Curl_splay(tv_zero, t);
   if(compare(i, t->key) < 0) {
-    /* too big node, try the smaller chain */
-    if(t->smaller)
-      t=Curl_splay(t->smaller->key, t);
-    else {
-      /* fail */
-      *removed = NULL;
-      return t;
-    }
+    /* even the smallest is too big */
+    *removed = NULL;
+    return t;
   }
 
-  if(compare(i, t->key) >= 0) {               /* found it */
-    /* FIRST! Check if there is a list with identical keys */
-    x = t->same;
-    if(x) {
-      /* there is, pick one from the list */
+  /* FIRST! Check if there is a list with identical keys */
+  x = t->samen;
+  if(x != t) {
+    /* there is, pick one from the list */
 
-      /* 'x' is the new root node */
+    /* 'x' is the new root node */
 
-      x->key = t->key;
-      x->larger = t->larger;
-      x->smaller = t->smaller;
-
-      *removed = t;
-      return x; /* new root */
-    }
+    x->key = t->key;
+    x->larger = t->larger;
+    x->smaller = t->smaller;
+    x->samep = t->samep;
+    t->samep->samen = x;
 
-    if(t->smaller == NULL) {
-      x = t->larger;
-    }
-    else {
-      x = Curl_splay(i, t->smaller);
-      x->larger = t->larger;
-    }
     *removed = t;
-
-    return x;
-  }
-  else {
-    *removed = NULL; /* no match */
-    return t;        /* It wasn't there */
+    return x; /* new root */
   }
+
+  /* we splayed the tree to the smallest element, there is no smaller */
+  x = t->larger;
+  *removed = t;
+
+  return x;
 }
 
 
@@ -231,19 +217,17 @@ int Curl_splayremovebyaddr(struct Curl_tree *t,
 
   if(compare(KEY_NOTUSED, removenode->key) == 0) {
     /* Key set to NOTUSED means it is a subnode within a 'same' linked list
-       and thus we can unlink it easily. The 'smaller' link of a subnode
-       links to the parent node. */
-    if(removenode->smaller == NULL)
+       and thus we can unlink it easily. */
+    if(removenode->samen == removenode)
+      /* A non-subnode should never be set to KEY_NOTUSED */
       return 3;
 
-    removenode->smaller->same = removenode->same;
-    if(removenode->same)
-      removenode->same->smaller = removenode->smaller;
+    removenode->samep->samen = removenode->samen;
+    removenode->samen->samep = removenode->samep;
 
     /* Ensures that double-remove gets caught. */
-    removenode->smaller = NULL;
+    removenode->samen = removenode;
 
-    /* voila, we're done! */
     *newroot = t; /* return the same root */
     return 0;
   }
@@ -262,14 +246,16 @@ int Curl_splayremovebyaddr(struct Curl_tree *t,
 
   /* Check if there is a list with identical sizes, as then we're trying to
      remove the root node of a list of nodes with identical keys. */
-  x = t->same;
-  if(x) {
+  x = t->samen;
+  if(x != t) {
     /* 'x' is the new root node, we just make it use the root node's
        smaller/larger links */
 
     x->key = t->key;
     x->larger = t->larger;
     x->smaller = t->smaller;
+    x->samep = t->samep;
+    t->samep->samen = x;
   }
   else {
     /* Remove the root node */
diff --git a/lib/splay.h b/lib/splay.h
index 427bfc8..da81894 100644
--- a/lib/splay.h
+++ b/lib/splay.h
@@ -26,7 +26,8 @@
 struct Curl_tree {
   struct Curl_tree *smaller; /* smaller node */
   struct Curl_tree *larger;  /* larger node */
-  struct Curl_tree *same;    /* points to a node with identical key */
+  struct Curl_tree *samen;   /* points to the next node with identical key */
+  struct Curl_tree *samep;   /* points to the prev node with identical key */
   struct timeval key;        /* this node's "sort" key */
   void *payload;             /* data the splay code doesn't care about */
 };
diff --git a/lib/ssh.c b/lib/ssh.c
index 5ed036a..72fa06a 100644
--- a/lib/ssh.c
+++ b/lib/ssh.c
@@ -688,14 +688,11 @@ static CURLcode ssh_check_fingerprint(struct connectdata *conn)
       sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
       return sshc->actualcode;
     }
-    else {
-      infof(data, "MD5 checksum match!\n");
-      /* as we already matched, we skip the check for known hosts */
-      return CURLE_OK;
-    }
+    infof(data, "MD5 checksum match!\n");
+    /* as we already matched, we skip the check for known hosts */
+    return CURLE_OK;
   }
-  else
-    return ssh_knownhost(conn);
+  return ssh_knownhost(conn);
 }
 
 /*
@@ -738,7 +735,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
       if(rc == LIBSSH2_ERROR_EAGAIN) {
         break;
       }
-      else if(rc) {
+      if(rc) {
         failf(data, "Failure establishing ssh session");
         state(conn, SSH_SESSION_FREE);
         sshc->actualcode = CURLE_FAILED_INIT;
@@ -782,16 +779,14 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
           state(conn, SSH_AUTH_DONE);
           break;
         }
+        err = libssh2_session_last_errno(sshc->ssh_session);
+        if(err == LIBSSH2_ERROR_EAGAIN)
+          rc = LIBSSH2_ERROR_EAGAIN;
         else {
-          err = libssh2_session_last_errno(sshc->ssh_session);
-          if(err == LIBSSH2_ERROR_EAGAIN)
-            rc = LIBSSH2_ERROR_EAGAIN;
-          else {
-            state(conn, SSH_SESSION_FREE);
-            sshc->actualcode = libssh2_session_error_to_CURLE(err);
-          }
-          break;
+          state(conn, SSH_SESSION_FREE);
+          sshc->actualcode = libssh2_session_error_to_CURLE(err);
         }
+        break;
       }
       infof(data, "SSH authentication methods available: %s\n",
             sshc->authlist);
@@ -918,6 +913,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
                                          &err_msg, NULL, 0);
         infof(data, "SSH public key authentication failed: %s\n", err_msg);
         state(conn, SSH_AUTH_PASS_INIT);
+        rc = 0; /* clear rc and continue */
       }
       break;
 
@@ -928,6 +924,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
       }
       else {
         state(conn, SSH_AUTH_HOST_INIT);
+        rc = 0; /* clear rc and continue */
       }
       break;
 
@@ -940,7 +937,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
       if(rc == LIBSSH2_ERROR_EAGAIN) {
         break;
       }
-      else if(rc == 0) {
+      if(rc == 0) {
         sshc->authed = TRUE;
         infof(data, "Initialized password authentication\n");
         state(conn, SSH_AUTH_DONE);
@@ -989,6 +986,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
         if(rc < 0) {
           infof(data, "Failure connecting to agent\n");
           state(conn, SSH_AUTH_KEY_INIT);
+          rc = 0; /* clear rc and continue */
         }
         else {
           state(conn, SSH_AUTH_AGENT_LIST);
@@ -1008,6 +1006,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
       if(rc < 0) {
         infof(data, "Failure requesting identities to agent\n");
         state(conn, SSH_AUTH_KEY_INIT);
+        rc = 0; /* clear rc and continue */
       }
       else {
         state(conn, SSH_AUTH_AGENT);
@@ -1077,7 +1076,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
       if(rc == LIBSSH2_ERROR_EAGAIN) {
         break;
       }
-      else if(rc == 0) {
+      if(rc == 0) {
         sshc->authed = TRUE;
         infof(data, "Initialized keyboard interactive authentication\n");
       }
@@ -1116,21 +1115,19 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
        */
       sshc->sftp_session = libssh2_sftp_init(sshc->ssh_session);
       if(!sshc->sftp_session) {
+        char *err_msg;
         if(libssh2_session_last_errno(sshc->ssh_session) ==
            LIBSSH2_ERROR_EAGAIN) {
           rc = LIBSSH2_ERROR_EAGAIN;
           break;
         }
-        else {
-          char *err_msg;
 
-          (void)libssh2_session_last_error(sshc->ssh_session,
-                                           &err_msg, NULL, 0);
-          failf(data, "Failure initializing sftp session: %s", err_msg);
-          state(conn, SSH_SESSION_FREE);
-          sshc->actualcode = CURLE_FAILED_INIT;
-          break;
-        }
+        (void)libssh2_session_last_error(sshc->ssh_session,
+                                         &err_msg, NULL, 0);
+        failf(data, "Failure initializing sftp session: %s", err_msg);
+        state(conn, SSH_SESSION_FREE);
+        sshc->actualcode = CURLE_FAILED_INIT;
+        break;
       }
       state(conn, SSH_SFTP_REALPATH);
       break;
@@ -1147,7 +1144,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
       if(rc == LIBSSH2_ERROR_EAGAIN) {
         break;
       }
-      else if(rc > 0) {
+      if(rc > 0) {
         /* It seems that this string is not always NULL terminated */
         tempHome[rc] = '\0';
         sshc->homedir = strdup(tempHome);
@@ -1261,7 +1258,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
           state(conn, SSH_SFTP_NEXT_QUOTE);
         break;
       }
-      else if(cmd) {
+      if(cmd) {
         /*
          * the arguments following the command must be separated from the
          * command with a space so we can check for it unconditionally
@@ -1321,7 +1318,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
           state(conn, SSH_SFTP_QUOTE_STAT);
           break;
         }
-        else if(strncasecompare(cmd, "ln ", 3) ||
+        if(strncasecompare(cmd, "ln ", 3) ||
                 strncasecompare(cmd, "symlink ", 8)) {
           /* symbolic linking */
           /* sshc->quote_path1 is the source */
@@ -1443,7 +1440,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
         if(rc == LIBSSH2_ERROR_EAGAIN) {
           break;
         }
-        else if(rc != 0 && !sshc->acceptfail) { /* get those attributes */
+        if(rc != 0 && !sshc->acceptfail) { /* get those attributes */
           err = sftp_libssh2_last_error(sshc->sftp_session);
           Curl_safefree(sshc->quote_path1);
           Curl_safefree(sshc->quote_path2);
@@ -1514,7 +1511,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
       if(rc == LIBSSH2_ERROR_EAGAIN) {
         break;
       }
-      else if(rc != 0 && !sshc->acceptfail) {
+      if(rc != 0 && !sshc->acceptfail) {
         err = sftp_libssh2_last_error(sshc->sftp_session);
         Curl_safefree(sshc->quote_path1);
         Curl_safefree(sshc->quote_path2);
@@ -1537,7 +1534,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
       if(rc == LIBSSH2_ERROR_EAGAIN) {
         break;
       }
-      else if(rc != 0 && !sshc->acceptfail) {
+      if(rc != 0 && !sshc->acceptfail) {
         err = sftp_libssh2_last_error(sshc->sftp_session);
         Curl_safefree(sshc->quote_path1);
         Curl_safefree(sshc->quote_path2);
@@ -1558,7 +1555,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
       if(rc == LIBSSH2_ERROR_EAGAIN) {
         break;
       }
-      else if(rc != 0 && !sshc->acceptfail) {
+      if(rc != 0 && !sshc->acceptfail) {
         err = sftp_libssh2_last_error(sshc->sftp_session);
         Curl_safefree(sshc->quote_path1);
         failf(data, "mkdir command failed: %s", sftp_libssh2_strerror(err));
@@ -1582,7 +1579,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
       if(rc == LIBSSH2_ERROR_EAGAIN) {
         break;
       }
-      else if(rc != 0 && !sshc->acceptfail) {
+      if(rc != 0 && !sshc->acceptfail) {
         err = sftp_libssh2_last_error(sshc->sftp_session);
         Curl_safefree(sshc->quote_path1);
         Curl_safefree(sshc->quote_path2);
@@ -1601,7 +1598,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
       if(rc == LIBSSH2_ERROR_EAGAIN) {
         break;
       }
-      else if(rc != 0 && !sshc->acceptfail) {
+      if(rc != 0 && !sshc->acceptfail) {
         err = sftp_libssh2_last_error(sshc->sftp_session);
         Curl_safefree(sshc->quote_path1);
         failf(data, "rmdir command failed: %s", sftp_libssh2_strerror(err));
@@ -1619,7 +1616,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
       if(rc == LIBSSH2_ERROR_EAGAIN) {
         break;
       }
-      else if(rc != 0 && !sshc->acceptfail) {
+      if(rc != 0 && !sshc->acceptfail) {
         err = sftp_libssh2_last_error(sshc->sftp_session);
         Curl_safefree(sshc->quote_path1);
         failf(data, "rm command failed: %s", sftp_libssh2_strerror(err));
@@ -1642,7 +1639,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
       if(rc == LIBSSH2_ERROR_EAGAIN) {
         break;
       }
-      else if(rc != 0 && !sshc->acceptfail) {
+      if(rc != 0 && !sshc->acceptfail) {
         err = sftp_libssh2_last_error(sshc->sftp_session);
         Curl_safefree(sshc->quote_path1);
         failf(data, "statvfs command failed: %s", sftp_libssh2_strerror(err));
@@ -1705,7 +1702,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
       if(rc == LIBSSH2_ERROR_EAGAIN) {
         break;
       }
-      else if(rc == 0) {
+      if(rc == 0) {
         data->info.filetime = (long)attrs.mtime;
       }
 
@@ -1743,7 +1740,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
           if(rc == LIBSSH2_ERROR_EAGAIN) {
             break;
           }
-          else if(rc) {
+          if(rc) {
             data->state.resume_from = 0;
           }
           else {
@@ -1778,47 +1775,47 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
 
         if(LIBSSH2_ERROR_EAGAIN == rc)
           break;
-        else {
-          if(LIBSSH2_ERROR_SFTP_PROTOCOL == rc)
-            /* only when there was an SFTP protocol error can we extract
-               the sftp error! */
-            err = sftp_libssh2_last_error(sshc->sftp_session);
-          else
-            err = -1; /* not an sftp error at all */
 
-          if(sshc->secondCreateDirs) {
-            state(conn, SSH_SFTP_CLOSE);
-            sshc->actualcode = err>= LIBSSH2_FX_OK?
-              sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
-            failf(data, "Creating the dir/file failed: %s",
-                  sftp_libssh2_strerror(err));
-            break;
-          }
-          else if(((err == LIBSSH2_FX_NO_SUCH_FILE) ||
-                   (err == LIBSSH2_FX_FAILURE) ||
-                   (err == LIBSSH2_FX_NO_SUCH_PATH)) &&
-                  (data->set.ftp_create_missing_dirs &&
-                   (strlen(sftp_scp->path) > 1))) {
-            /* try to create the path remotely */
-            sshc->secondCreateDirs = 1;
-            state(conn, SSH_SFTP_CREATE_DIRS_INIT);
-            break;
-          }
+        if(LIBSSH2_ERROR_SFTP_PROTOCOL == rc)
+          /* only when there was an SFTP protocol error can we extract
+             the sftp error! */
+          err = sftp_libssh2_last_error(sshc->sftp_session);
+        else
+          err = -1; /* not an sftp error at all */
+
+        if(sshc->secondCreateDirs) {
           state(conn, SSH_SFTP_CLOSE);
           sshc->actualcode = err>= LIBSSH2_FX_OK?
             sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
-          if(!sshc->actualcode) {
-            /* Sometimes, for some reason libssh2_sftp_last_error() returns
-               zero even though libssh2_sftp_open() failed previously! We need
-               to work around that! */
-            sshc->actualcode = CURLE_SSH;
-            err=-1;
-          }
-          failf(data, "Upload failed: %s (%d/%d)",
-                err>= LIBSSH2_FX_OK?sftp_libssh2_strerror(err):"ssh error",
-                err, rc);
+          failf(data, "Creating the dir/file failed: %s",
+                sftp_libssh2_strerror(err));
+          break;
+        }
+        if(((err == LIBSSH2_FX_NO_SUCH_FILE) ||
+            (err == LIBSSH2_FX_FAILURE) ||
+            (err == LIBSSH2_FX_NO_SUCH_PATH)) &&
+           (data->set.ftp_create_missing_dirs &&
+            (strlen(sftp_scp->path) > 1))) {
+          /* try to create the path remotely */
+          rc = 0; /* clear rc and continue */
+          sshc->secondCreateDirs = 1;
+          state(conn, SSH_SFTP_CREATE_DIRS_INIT);
           break;
         }
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->actualcode = err>= LIBSSH2_FX_OK?
+          sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
+        if(!sshc->actualcode) {
+          /* Sometimes, for some reason libssh2_sftp_last_error() returns
+             zero even though libssh2_sftp_open() failed previously! We need
+             to work around that! */
+          sshc->actualcode = CURLE_SSH;
+          err=-1;
+        }
+        failf(data, "Upload failed: %s (%d/%d)",
+              err>= LIBSSH2_FX_OK?sftp_libssh2_strerror(err):"ssh error",
+              err, rc);
+        break;
       }
 
       /* If we have a restart point then we need to seek to the correct
@@ -1831,32 +1828,30 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
         }
 
         if(seekerr != CURL_SEEKFUNC_OK) {
+          curl_off_t passed=0;
 
           if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
             failf(data, "Could not seek stream");
             return CURLE_FTP_COULDNT_USE_REST;
           }
           /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
-          else {
-            curl_off_t passed=0;
-            do {
-              size_t readthisamountnow =
-                (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
-                BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
-
-              size_t actuallyread =
-                data->state.fread_func(data->state.buffer, 1,
-                                       readthisamountnow, data->state.in);
-
-              passed += actuallyread;
-              if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
-                /* this checks for greater-than only to make sure that the
-                   CURL_READFUNC_ABORT return code still aborts */
-                failf(data, "Failed to read data");
-                return CURLE_FTP_COULDNT_USE_REST;
-              }
-            } while(passed < data->state.resume_from);
-          }
+          do {
+            size_t readthisamountnow =
+              (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
+              BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
+
+            size_t actuallyread =
+              data->state.fread_func(data->state.buffer, 1,
+                                     readthisamountnow, data->state.in);
+
+            passed += actuallyread;
+            if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
+              /* this checks for greater-than only to make sure that the
+                 CURL_READFUNC_ABORT return code still aborts */
+              failf(data, "Failed to read data");
+              return CURLE_FTP_COULDNT_USE_REST;
+            }
+          } while(passed < data->state.resume_from);
         }
 
         /* now, decrease the size of the read */
@@ -1921,9 +1916,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
         state(conn, SSH_SFTP_CREATE_DIRS_MKDIR);
         break;
       }
-      else {
-        state(conn, SSH_SFTP_UPLOAD_INIT);
-      }
+      state(conn, SSH_SFTP_UPLOAD_INIT);
       break;
 
     case SSH_SFTP_CREATE_DIRS_MKDIR:
@@ -1936,7 +1929,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
       }
       *sshc->slash_pos = '/';
       ++sshc->slash_pos;
-      if(rc == -1) {
+      if(rc < 0) {
         /*
          * Abort if failure wasn't that the dir already exists or the
          * permission was denied (creation might succeed further down the
@@ -1951,6 +1944,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
           sshc->actualcode = result?result:CURLE_SSH;
           break;
         }
+        rc = 0; /* clear rc and continue */
       }
       state(conn, SSH_SFTP_CREATE_DIRS);
       break;
@@ -1977,15 +1971,13 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
           rc = LIBSSH2_ERROR_EAGAIN;
           break;
         }
-        else {
-          err = sftp_libssh2_last_error(sshc->sftp_session);
-          failf(data, "Could not open directory for reading: %s",
-                sftp_libssh2_strerror(err));
-          state(conn, SSH_SFTP_CLOSE);
-          result = sftp_libssh2_error_to_CURLE(err);
-          sshc->actualcode = result?result:CURLE_SSH;
-          break;
-        }
+        err = sftp_libssh2_last_error(sshc->sftp_session);
+        failf(data, "Could not open directory for reading: %s",
+              sftp_libssh2_strerror(err));
+        state(conn, SSH_SFTP_CLOSE);
+        result = sftp_libssh2_error_to_CURLE(err);
+        sshc->actualcode = result?result:CURLE_SSH;
+        break;
       }
       sshc->readdir_filename = malloc(PATH_MAX+1);
       if(!sshc->readdir_filename) {
@@ -2192,15 +2184,13 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
           rc = LIBSSH2_ERROR_EAGAIN;
           break;
         }
-        else {
-          err = sftp_libssh2_last_error(sshc->sftp_session);
-          failf(data, "Could not open remote file for reading: %s",
-                sftp_libssh2_strerror(err));
-          state(conn, SSH_SFTP_CLOSE);
-          result = sftp_libssh2_error_to_CURLE(err);
-          sshc->actualcode = result?result:CURLE_SSH;
-          break;
-        }
+        err = sftp_libssh2_last_error(sshc->sftp_session);
+        failf(data, "Could not open remote file for reading: %s",
+              sftp_libssh2_strerror(err));
+        state(conn, SSH_SFTP_CLOSE);
+        result = sftp_libssh2_error_to_CURLE(err);
+        sshc->actualcode = result?result:CURLE_SSH;
+        break;
       }
       state(conn, SSH_SFTP_DOWNLOAD_STAT);
       break;
@@ -2215,7 +2205,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
       if(rc == LIBSSH2_ERROR_EAGAIN) {
         break;
       }
-      else if(rc ||
+      if(rc ||
               !(attrs.flags & LIBSSH2_SFTP_ATTR_SIZE) ||
               (attrs.filesize == 0)) {
         /*
@@ -2313,18 +2303,17 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
       state(conn, SSH_STOP);
       break;
     }
-    else {
-      Curl_setup_transfer(conn, FIRSTSOCKET, data->req.size,
-                          FALSE, NULL, -1, NULL);
+    Curl_setup_transfer(conn, FIRSTSOCKET, data->req.size,
+                        FALSE, NULL, -1, NULL);
 
-      /* not set by Curl_setup_transfer to preserve keepon bits */
-      conn->writesockfd = conn->sockfd;
+    /* not set by Curl_setup_transfer to preserve keepon bits */
+    conn->writesockfd = conn->sockfd;
+
+    /* we want to use the _receiving_ function even when the socket turns
+       out writableable as the underlying libssh2 recv function will deal
+       with both accordingly */
+    conn->cselect_bits = CURL_CSELECT_IN;
 
-      /* we want to use the _receiving_ function even when the socket turns
-         out writableable as the underlying libssh2 recv function will deal
-         with both accordingly */
-      conn->cselect_bits = CURL_CSELECT_IN;
-    }
     if(result) {
       /* this should never occur; the close state should be entered
          at the time the error occurs */
@@ -2342,7 +2331,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
         if(rc == LIBSSH2_ERROR_EAGAIN) {
           break;
         }
-        else if(rc < 0) {
+        if(rc < 0) {
           infof(data, "Failed to close libssh2 file\n");
         }
         sshc->sftp_handle = NULL;
@@ -2376,7 +2365,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
         if(rc == LIBSSH2_ERROR_EAGAIN) {
           break;
         }
-        else if(rc < 0) {
+        if(rc < 0) {
           infof(data, "Failed to close libssh2 file\n");
         }
         sshc->sftp_handle = NULL;
@@ -2386,7 +2375,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
         if(rc == LIBSSH2_ERROR_EAGAIN) {
           break;
         }
-        else if(rc < 0) {
+        if(rc < 0) {
           infof(data, "Failed to stop libssh2 sftp subsystem\n");
         }
         sshc->sftp_session = NULL;
@@ -2431,22 +2420,21 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
         SCP_SEND(sshc->ssh_session, sftp_scp->path, data->set.new_file_perms,
                  data->state.infilesize);
       if(!sshc->ssh_channel) {
+        int ssh_err;
+        char *err_msg;
+
         if(libssh2_session_last_errno(sshc->ssh_session) ==
            LIBSSH2_ERROR_EAGAIN) {
           rc = LIBSSH2_ERROR_EAGAIN;
           break;
         }
-        else {
-          int ssh_err;
-          char *err_msg;
 
-          ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
-                                                     &err_msg, NULL, 0));
-          failf(conn->data, "%s", err_msg);
-          state(conn, SSH_SCP_CHANNEL_FREE);
-          sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
-          break;
-        }
+        ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
+                                                   &err_msg, NULL, 0));
+        failf(conn->data, "%s", err_msg);
+        state(conn, SSH_SCP_CHANNEL_FREE);
+        sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
+        break;
       }
 
       /* upload data */
@@ -2501,22 +2489,22 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
 #endif
 
       if(!sshc->ssh_channel) {
+        int ssh_err;
+        char *err_msg;
+
         if(libssh2_session_last_errno(sshc->ssh_session) ==
            LIBSSH2_ERROR_EAGAIN) {
           rc = LIBSSH2_ERROR_EAGAIN;
           break;
         }
-        else {
-          int ssh_err;
-          char *err_msg;
 
-          ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
-                                                     &err_msg, NULL, 0));
-          failf(conn->data, "%s", err_msg);
-          state(conn, SSH_SCP_CHANNEL_FREE);
-          sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
-          break;
-        }
+
+        ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
+                                                   &err_msg, NULL, 0));
+        failf(conn->data, "%s", err_msg);
+        state(conn, SSH_SCP_CHANNEL_FREE);
+        sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
+        break;
       }
 
       /* download data */
@@ -2554,7 +2542,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
         if(rc == LIBSSH2_ERROR_EAGAIN) {
           break;
         }
-        else if(rc) {
+        if(rc) {
           infof(data, "Failed to send libssh2 channel EOF\n");
         }
       }
@@ -2567,7 +2555,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
         if(rc == LIBSSH2_ERROR_EAGAIN) {
           break;
         }
-        else if(rc) {
+        if(rc) {
           infof(data, "Failed to get channel EOF: %d\n", rc);
         }
       }
@@ -2580,7 +2568,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
         if(rc == LIBSSH2_ERROR_EAGAIN) {
           break;
         }
-        else if(rc) {
+        if(rc) {
           infof(data, "Channel failed to close: %d\n", rc);
         }
       }
@@ -2593,7 +2581,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
         if(rc == LIBSSH2_ERROR_EAGAIN) {
           break;
         }
-        else if(rc < 0) {
+        if(rc < 0) {
           infof(data, "Failed to free libssh2 scp subsystem\n");
         }
         sshc->ssh_channel = NULL;
@@ -2615,7 +2603,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
         if(rc == LIBSSH2_ERROR_EAGAIN) {
           break;
         }
-        else if(rc < 0) {
+        if(rc < 0) {
           infof(data, "Failed to free libssh2 scp subsystem\n");
         }
         sshc->ssh_channel = NULL;
@@ -2626,7 +2614,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
         if(rc == LIBSSH2_ERROR_EAGAIN) {
           break;
         }
-        else if(rc < 0) {
+        if(rc < 0) {
           infof(data, "Failed to disconnect libssh2 session\n");
         }
       }
@@ -2651,7 +2639,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
         if(rc == LIBSSH2_ERROR_EAGAIN) {
           break;
         }
-        else if(rc < 0) {
+        if(rc < 0) {
           infof(data, "Failed to disconnect from libssh2 agent\n");
         }
         libssh2_agent_free(sshc->ssh_agent);
@@ -2669,7 +2657,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
         if(rc == LIBSSH2_ERROR_EAGAIN) {
           break;
         }
-        else if(rc < 0) {
+        if(rc < 0) {
           infof(data, "Failed to free libssh2 session\n");
         }
         sshc->ssh_session = NULL;
@@ -2834,7 +2822,8 @@ static CURLcode ssh_block_statemach(struct connectdata *conn,
 
   while((sshc->state != SSH_STOP) && !result) {
     bool block;
-    long left;
+    time_t left;
+    struct timeval now = Curl_tvnow();
 
     result = ssh_statemach_act(conn, &block);
     if(result)
@@ -2842,12 +2831,10 @@ static CURLcode ssh_block_statemach(struct connectdata *conn,
 
     if(Curl_pgrsUpdate(conn))
       return CURLE_ABORTED_BY_CALLBACK;
-    else {
-      struct timeval now = Curl_tvnow();
-      result = Curl_speedcheck(data, now);
-      if(result)
-        break;
-    }
+
+    result = Curl_speedcheck(data, now);
+    if(result)
+      break;
 
     left = Curl_timeleft(data, NULL, duringconnect);
     if(left < 0) {
diff --git a/lib/strcase.c b/lib/strcase.c
index a750f7b..a74a4be 100644
--- a/lib/strcase.c
+++ b/lib/strcase.c
@@ -125,9 +125,9 @@ int Curl_safe_strcasecompare(const char *first, const char *second)
   if(first && second)
     /* both pointers point to something then compare them */
     return Curl_strcasecompare(first, second);
-  else
-    /* if both pointers are NULL then treat them as equal */
-    return (NULL == first && NULL == second);
+
+  /* if both pointers are NULL then treat them as equal */
+  return (NULL == first && NULL == second);
 }
 
 /*
diff --git a/lib/system_win32.c b/lib/system_win32.c
index 7873759..cfbbf32 100644
--- a/lib/system_win32.c
+++ b/lib/system_win32.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2016, Steve Holme, <steve_holme at hotmail.com>.
+ * Copyright (C) 2016 - 2017, Steve Holme, <steve_holme at hotmail.com>.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -68,7 +68,7 @@ typedef HMODULE (APIENTRY *LOADLIBRARYEX_FN)(LPCTSTR, HANDLE, DWORD);
  *
  * majorVersion [in] - The major version number.
  * minorVersion [in] - The minor version number.
- * platform     [in] - The optional platform identifer.
+ * platform     [in] - The optional platform identifier.
  * condition    [in] - The test condition used to specifier whether we are
  *                     checking a version less then, equal to or greater than
  *                     what is specified in the major and minor version
diff --git a/lib/telnet.c b/lib/telnet.c
index 551af60..5cceed2 100644
--- a/lib/telnet.c
+++ b/lib/telnet.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
@@ -872,7 +872,7 @@ static CURLcode check_telnet_options(struct connectdata *conn)
         continue;
       }
 
-          /* Window Size */
+      /* Window Size */
       if(strcasecompare(option_keyword, "WS")) {
         if(sscanf(option_arg, "%hu%*[xX]%hu",
                   &tn->subopt_wsx, &tn->subopt_wsy) == 2)
@@ -899,11 +899,9 @@ static CURLcode check_telnet_options(struct connectdata *conn)
       result = CURLE_UNKNOWN_TELNET_OPTION;
       break;
     }
-    else {
-      failf(data, "Syntax error in telnet option: %s", head->data);
-      result = CURLE_TELNET_OPTION_SYNTAX;
-      break;
-    }
+    failf(data, "Syntax error in telnet option: %s", head->data);
+    result = CURLE_TELNET_OPTION_SYNTAX;
+    break;
   }
 
   if(result) {
@@ -1016,7 +1014,7 @@ static void sendsuboption(struct connectdata *conn, int option)
     CURL_SB_ACCUM(tn, CURL_IAC);
     CURL_SB_ACCUM(tn, CURL_SB);
     CURL_SB_ACCUM(tn, CURL_TELOPT_NAWS);
-    /* We must deal either with litte or big endien processors */
+    /* We must deal either with litte or big endian processors */
     /* Window size must be sent according to the 'network order' */
     x=htons(tn->subopt_wsx);
     y=htons(tn->subopt_wsy);
@@ -1186,7 +1184,7 @@ CURLcode telrcv(struct connectdata *conn,
              * IAC SE was left off, or another option got inserted into the
              * suboption are all possibilities.  If we assume that the IAC was
              * not doubled, and really the IAC SE was left off, we could get
-             * into an infinate loop here.  So, instead, we terminate the
+             * into an infinite loop here.  So, instead, we terminate the
              * suboption, and process the partial suboption if we can.
              */
             CURL_SB_ACCUM(tn, CURL_IAC);
@@ -1326,7 +1324,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
 #ifdef USE_WINSOCK
   /*
   ** This functionality only works with WinSock >= 2.0.  So,
-  ** make sure have it.
+  ** make sure we have it.
   */
   result = check_wsock2(data);
   if(result)
@@ -1416,28 +1414,29 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
 
   /* Keep on listening and act on events */
   while(keepon) {
+    const DWORD buf_size = (DWORD)CURL_BUFSIZE(data->set.buffer_size);
     waitret = WaitForMultipleObjects(obj_count, objs, FALSE, wait_timeout);
     switch(waitret) {
     case WAIT_TIMEOUT:
     {
       for(;;) {
         if(data->set.is_fread_set) {
+          size_t n;
           /* read from user-supplied method */
-          result = (int)data->state.fread_func(buf, 1, BUFSIZE - 1,
-                                               data->state.in);
-          if(result == CURL_READFUNC_ABORT) {
+          n = data->state.fread_func(buf, 1, BUFSIZE - 1, data->state.in);
+          if(n == CURL_READFUNC_ABORT) {
             keepon = FALSE;
             result = CURLE_READ_ERROR;
             break;
           }
 
-          if(result == CURL_READFUNC_PAUSE)
+          if(n == CURL_READFUNC_PAUSE)
             break;
 
-          if(result == 0)                        /* no bytes */
+          if(n == 0)                        /* no bytes */
             break;
 
-          readfile_read = result; /* fall thru with number of bytes read */
+          readfile_read = (DWORD)n; /* fall thru with number of bytes read */
         }
         else {
           /* read from stdin */
@@ -1451,7 +1450,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
           if(!readfile_read)
             break;
 
-          if(!ReadFile(stdin_handle, buf, sizeof(data->state.buffer),
+          if(!ReadFile(stdin_handle, buf, buf_size,
                        &readfile_read, NULL)) {
             keepon = FALSE;
             result = CURLE_READ_ERROR;
@@ -1470,7 +1469,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
 
     case WAIT_OBJECT_0 + 1:
     {
-      if(!ReadFile(stdin_handle, buf, sizeof(data->state.buffer),
+      if(!ReadFile(stdin_handle, buf, buf_size,
                    &readfile_read, NULL)) {
         keepon = FALSE;
         result = CURLE_READ_ERROR;
@@ -1593,7 +1592,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
         if(result == CURLE_AGAIN)
           break;
         /* returned not-zero, this an error */
-        else if(result) {
+        if(result) {
           keepon = FALSE;
           break;
         }
diff --git a/lib/tftp.c b/lib/tftp.c
index f2f8347..098b1bb 100644
--- a/lib/tftp.c
+++ b/lib/tftp.c
@@ -359,7 +359,7 @@ static CURLcode tftp_parse_option_ack(tftp_state_data_t *state,
         failf(data, "invalid blocksize value in OACK packet");
         return CURLE_TFTP_ILLEGAL;
       }
-      else if(blksize > TFTP_BLKSIZE_MAX) {
+      if(blksize > TFTP_BLKSIZE_MAX) {
         failf(data, "%s (%d)", "blksize is larger than max supported",
               TFTP_BLKSIZE_MAX);
         return CURLE_TFTP_ILLEGAL;
@@ -1189,7 +1189,7 @@ static long tftp_state_timeout(struct connectdata *conn, tftp_event_t *event)
     state->state = TFTP_STATE_FIN;
     return 0;
   }
-  else if(current > state->rx_time+state->retry_time) {
+  if(current > state->rx_time+state->retry_time) {
     if(event)
       *event = TFTP_EVENT_TIMEOUT;
     time(&state->rx_time); /* update even though we received nothing */
@@ -1223,7 +1223,7 @@ static CURLcode tftp_multi_statemach(struct connectdata *conn, bool *done)
     failf(data, "TFTP response timeout");
     return CURLE_OPERATION_TIMEDOUT;
   }
-  else if(event != TFTP_EVENT_NONE) {
+  if(event != TFTP_EVENT_NONE) {
     result = tftp_state_machine(state, event);
     if(result)
       return result;
diff --git a/lib/timeval.c b/lib/timeval.c
index f3b207a..0d6036b 100644
--- a/lib/timeval.c
+++ b/lib/timeval.c
@@ -139,8 +139,7 @@ double curlx_tvdiff_secs(struct timeval newer, struct timeval older)
   if(newer.tv_sec != older.tv_sec)
     return (double)(newer.tv_sec-older.tv_sec)+
       (double)(newer.tv_usec-older.tv_usec)/1000000.0;
-  else
-    return (double)(newer.tv_usec-older.tv_usec)/1000000.0;
+  return (double)(newer.tv_usec-older.tv_usec)/1000000.0;
 }
 
 /* return the number of seconds in the given input timeval struct */
diff --git a/lib/transfer.c b/lib/transfer.c
index 750fb04..1f6d26d 100644
--- a/lib/transfer.c
+++ b/lib/transfer.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
@@ -117,7 +117,8 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp)
     *nreadp = 0;
     return CURLE_ABORTED_BY_CALLBACK;
   }
-  else if(nread == CURL_READFUNC_PAUSE) {
+  if(nread == CURL_READFUNC_PAUSE) {
+    struct SingleRequest *k = &data->req;
 
     if(conn->handler->flags & PROTOPT_NONETWORK) {
       /* protocols that work without network cannot be paused. This is
@@ -126,16 +127,15 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp)
       failf(data, "Read callback asked for PAUSE when not supported!");
       return CURLE_READ_ERROR;
     }
-    else {
-      struct SingleRequest *k = &data->req;
-      /* CURL_READFUNC_PAUSE pauses read callbacks that feed socket writes */
-      k->keepon |= KEEP_SEND_PAUSE; /* mark socket send as paused */
-      if(data->req.upload_chunky) {
+
+    /* CURL_READFUNC_PAUSE pauses read callbacks that feed socket writes */
+    k->keepon |= KEEP_SEND_PAUSE; /* mark socket send as paused */
+    if(data->req.upload_chunky) {
         /* Back out the preallocation done above */
-        data->req.upload_fromhere -= (8 + 2);
-      }
-      *nreadp = 0;
+      data->req.upload_fromhere -= (8 + 2);
     }
+    *nreadp = 0;
+
     return CURLE_OK; /* nothing was read */
   }
   else if((size_t)nread > buffersize) {
@@ -642,7 +642,7 @@ static CURLcode readwrite_data(struct Curl_easy *data,
           failf(data, "%s in chunked-encoding", Curl_chunked_strerror(res));
           return CURLE_RECV_ERROR;
         }
-        else if(CHUNKE_STOP == res) {
+        if(CHUNKE_STOP == res) {
           size_t dataleft;
           /* we're done reading chunks! */
           k->keepon &= ~KEEP_RECV; /* read no more */
@@ -918,7 +918,7 @@ static CURLcode readwrite_upload(struct Curl_easy *data,
         /* this is a paused transfer */
         break;
       }
-      else if(nread<=0) {
+      if(nread<=0) {
         result = done_sending(conn, k);
         if(result)
           return result;
@@ -1192,7 +1192,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
             k->size - k->bytecount);
       return CURLE_PARTIAL_FILE;
     }
-    else if(!(data->set.opt_no_body) &&
+    if(!(data->set.opt_no_body) &&
             k->chunk &&
             (conn->chunk.state != CHUNK_STOP)) {
       /*
@@ -1356,13 +1356,12 @@ CURLcode Curl_pretransfer(struct Curl_easy *data)
 
     if(data->set.wildcardmatch) {
       struct WildcardData *wc = &data->wildcard;
-      if(!wc->filelist) {
+      if(wc->state < CURLWC_INIT) {
         result = Curl_wildcard_init(wc); /* init wildcard structures */
         if(result)
           return CURLE_OUT_OF_MEMORY;
       }
     }
-
   }
 
   return result;
@@ -1795,7 +1794,7 @@ CURLcode Curl_follow(struct Curl_easy *data,
     break;
 
   case 303: /* See Other */
-    /* Disable both types of POSTs, unless the user explicitely
+    /* Disable both types of POSTs, unless the user explicitly
        asks for POST after POST */
     if(data->set.httpreq != HTTPREQ_GET
       && !(data->set.keep_post & CURL_REDIR_POST_303)) {
@@ -1843,12 +1842,17 @@ CURLcode Curl_retry_request(struct connectdata *conn,
     return CURLE_OK;
 
   if((data->req.bytecount + data->req.headerbytecount == 0) &&
-     conn->bits.reuse &&
-     (data->set.rtspreq != RTSPREQ_RECEIVE)) {
-    /* We didn't get a single byte when we attempted to re-use a
-       connection. This might happen if the connection was left alive when we
-       were done using it before, but that was closed when we wanted to use it
-       again. Bad luck. Retry the same request on a fresh connect! */
+      conn->bits.reuse &&
+      (!data->set.opt_no_body
+        || (conn->handler->protocol & PROTO_FAMILY_HTTP)) &&
+      (data->set.rtspreq != RTSPREQ_RECEIVE)) {
+    /* We got no data, we attempted to re-use a connection. For HTTP this
+       can be a retry so we try again regardless if we expected a body.
+       For other protocols we only try again only if we expected a body.
+
+       This might happen if the connection was left alive when we were
+       done using it before, but that was closed when we wanted to read from
+       it again. Bad luck. Retry the same request on a fresh connect! */
     infof(conn->data, "Connection died, retrying a fresh connect\n");
     *url = strdup(conn->data->change.url);
     if(!*url)
diff --git a/lib/url.c b/lib/url.c
index 7944d7b..caa28f5 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
@@ -411,10 +411,7 @@ CURLcode Curl_close(struct Curl_easy *data)
   /* Destroy the timeout list that is held in the easy handle. It is
      /normally/ done by curl_multi_remove_handle() but this is "just in
      case" */
-  if(data->state.timeoutlist) {
-    Curl_llist_destroy(data->state.timeoutlist, NULL);
-    data->state.timeoutlist = NULL;
-  }
+  Curl_llist_destroy(&data->state.timeoutlist, NULL);
 
   data->magic = 0; /* force a clear AFTER the possibly enforced removal from
                       the multi handle, since that function uses the magic
@@ -452,6 +449,7 @@ CURLcode Curl_close(struct Curl_easy *data)
   }
   data->change.url = NULL;
 
+  Curl_safefree(data->state.buffer);
   Curl_safefree(data->state.headerbuff);
 
   Curl_flush_cookies(data, 1);
@@ -548,7 +546,7 @@ CURLcode Curl_init_userdefined(struct UserDefined *set)
 #endif
   set->ssh_auth_types = CURLSSH_AUTH_DEFAULT; /* defaults to any auth
                                                       type */
-  set->general_ssl.sessionid = TRUE; /* session ID caching enabled by
+  set->ssl.primary.sessionid = TRUE; /* session ID caching enabled by
                                         default */
   set->proxy_ssl = set->ssl;
 
@@ -576,14 +574,19 @@ CURLcode Curl_init_userdefined(struct UserDefined *set)
   result = setstropt(&set->str[STRING_SSL_CAFILE_ORIG], CURL_CA_BUNDLE);
   if(result)
     return result;
+
+  result = setstropt(&set->str[STRING_SSL_CAFILE_PROXY], CURL_CA_BUNDLE);
+  if(result)
+    return result;
 #endif
 #if defined(CURL_CA_PATH)
   result = setstropt(&set->str[STRING_SSL_CAPATH_ORIG], CURL_CA_PATH);
   if(result)
     return result;
 
-  result = setstropt(&set->str[STRING_SSL_CAPATH_PROXY],
-                     (char *) CURL_CA_PATH);
+  result = setstropt(&set->str[STRING_SSL_CAPATH_PROXY], CURL_CA_PATH);
+  if(result)
+    return result;
 #endif
 
   set->wildcardmatch  = FALSE;
@@ -641,6 +644,12 @@ CURLcode Curl_open(struct Curl_easy **curl)
 
   /* We do some initial setup here, all those fields that can't be just 0 */
 
+  data->state.buffer = malloc(BUFSIZE + 1);
+  if(!data->state.buffer) {
+    DEBUGF(fprintf(stderr, "Error: malloc of buffer failed\n"));
+    result = CURLE_OUT_OF_MEMORY;
+  }
+
   data->state.headerbuff = malloc(HEADERSIZE);
   if(!data->state.headerbuff) {
     DEBUGF(fprintf(stderr, "Error: malloc of headerbuff failed\n"));
@@ -660,9 +669,6 @@ CURLcode Curl_open(struct Curl_easy **curl)
 
     data->progress.flags |= PGRS_HIDE;
     data->state.current_speed = -1; /* init to negative == impossible */
-
-    data->wildcard.state = CURLWC_INIT;
-    data->wildcard.filelist = NULL;
     data->set.fnmatch = ZERO_NULL;
     data->set.maxconnects = DEFAULT_CONNCACHE_SIZE; /* for easy handles */
 
@@ -671,6 +677,7 @@ CURLcode Curl_open(struct Curl_easy **curl)
 
   if(result) {
     Curl_resolver_cleanup(data->state.resolver);
+    free(data->state.buffer);
     free(data->state.headerbuff);
     Curl_freeset(data);
     free(data);
@@ -682,6 +689,9 @@ CURLcode Curl_open(struct Curl_easy **curl)
   return result;
 }
 
+#define C_SSLVERSION_VALUE(x) (x & 0xffff)
+#define C_SSLVERSION_MAX_VALUE(x) (x & 0xffff0000)
+
 CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
                      va_list param)
 {
@@ -914,7 +924,9 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
      * implementations are lame.
      */
 #ifdef USE_SSL
-    data->set.ssl.primary.version = va_arg(param, long);
+    arg = va_arg(param, long);
+    data->set.ssl.primary.version = C_SSLVERSION_VALUE(arg);
+    data->set.ssl.primary.version_max = C_SSLVERSION_MAX_VALUE(arg);
 #else
     result = CURLE_UNKNOWN_OPTION;
 #endif
@@ -925,7 +937,9 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
      * implementations are lame.
      */
 #ifdef USE_SSL
-    data->set.proxy_ssl.primary.version = va_arg(param, long);
+    arg = va_arg(param, long);
+    data->set.proxy_ssl.primary.version = C_SSLVERSION_VALUE(arg);
+    data->set.proxy_ssl.primary.version_max = C_SSLVERSION_MAX_VALUE(arg);
 #else
     result = CURLE_UNKNOWN_OPTION;
 #endif
@@ -2217,8 +2231,12 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
     /* This does not work on windows. */
     result = setstropt(&data->set.str[STRING_SSL_CAPATH_ORIG],
                        va_arg(param, char *));
+#else
+    result = CURLE_NOT_BUILT_IN;
+#endif
     break;
   case CURLOPT_PROXY_CAPATH:
+#ifdef have_curlssl_ca_path /* not supported by all backends */
     /*
      * Set CA path info for SSL connection proxy. Specify directory name of the
      * CA certificates which have been prepared using openssl c_rehash utility.
@@ -2268,9 +2286,20 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
      */
     data->set.buffer_size = va_arg(param, long);
 
-    if((data->set.buffer_size> (BUFSIZE -1)) ||
-       (data->set.buffer_size < 1))
-      data->set.buffer_size = 0; /* huge internal default */
+    if(data->set.buffer_size > MAX_BUFSIZE)
+      data->set.buffer_size = MAX_BUFSIZE; /* huge internal default */
+    else if(data->set.buffer_size < 1)
+      data->set.buffer_size = BUFSIZE;
+
+    /* Resize only if larger than default buffer size. */
+    if(data->set.buffer_size > BUFSIZE) {
+      data->state.buffer = realloc(data->state.buffer,
+                                   data->set.buffer_size + 1);
+      if(!data->state.buffer) {
+        DEBUGF(fprintf(stderr, "Error: realloc of buffer failed\n"));
+        result = CURLE_OUT_OF_MEMORY;
+      }
+    }
 
     break;
 
@@ -2470,8 +2499,9 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
     break;
 
   case CURLOPT_SSL_SESSIONID_CACHE:
-    data->set.general_ssl.sessionid = (0 != va_arg(param, long)) ?
+    data->set.ssl.primary.sessionid = (0 != va_arg(param, long)) ?
                                       TRUE : FALSE;
+    data->set.proxy_ssl.primary.sessionid = data->set.ssl.primary.sessionid;
     break;
 
 #ifdef USE_LIBSSH2
@@ -2814,6 +2844,12 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
 
 #ifdef USE_UNIX_SOCKETS
   case CURLOPT_UNIX_SOCKET_PATH:
+    data->set.abstract_unix_socket = FALSE;
+    result = setstropt(&data->set.str[STRING_UNIX_SOCKET_PATH],
+                       va_arg(param, char *));
+    break;
+  case CURLOPT_ABSTRACT_UNIX_SOCKET:
+    data->set.abstract_unix_socket = TRUE;
     result = setstropt(&data->set.str[STRING_UNIX_SOCKET_PATH],
                        va_arg(param, char *));
     break;
@@ -2853,6 +2889,9 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
   case CURLOPT_CONNECT_TO:
     data->set.connect_to = va_arg(param, struct curl_slist *);
     break;
+  case CURLOPT_SUPPRESS_CONNECT_HEADERS:
+    data->set.suppress_connect_headers = (0 != va_arg(param, long))?TRUE:FALSE;
+    break;
   default:
     /* unknown tag and its companion, just ignore: */
     result = CURLE_UNKNOWN_OPTION;
@@ -2957,11 +2996,8 @@ static void conn_free(struct connectdata *conn)
 
   conn_reset_all_postponed_data(conn);
 
-  Curl_llist_destroy(conn->send_pipe, NULL);
-  Curl_llist_destroy(conn->recv_pipe, NULL);
-
-  conn->send_pipe = NULL;
-  conn->recv_pipe = NULL;
+  Curl_llist_destroy(&conn->send_pipe, NULL);
+  Curl_llist_destroy(&conn->recv_pipe, NULL);
 
   Curl_safefree(conn->localdev);
   Curl_free_primary_ssl_config(&conn->ssl_config);
@@ -3001,9 +3037,9 @@ CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection)
    * are other users of it
    */
   if(!conn->bits.close &&
-     (conn->send_pipe->size + conn->recv_pipe->size)) {
+     (conn->send_pipe.size + conn->recv_pipe.size)) {
     DEBUGF(infof(data, "Curl_disconnect, usecounter: %d\n",
-                 conn->send_pipe->size + conn->recv_pipe->size));
+                 conn->send_pipe.size + conn->recv_pipe.size));
     return CURLE_OK;
   }
 
@@ -3029,7 +3065,6 @@ CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection)
 
   free_fixed_hostname(&conn->host);
   free_fixed_hostname(&conn->conn_to_host);
-  free_fixed_hostname(&conn->proxy);
   free_fixed_hostname(&conn->http_proxy.host);
   free_fixed_hostname(&conn->socks_proxy.host);
 
@@ -3037,8 +3072,8 @@ CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection)
 
   /* Indicate to all handles on the pipe that we're dead */
   if(Curl_pipeline_wanted(data->multi, CURLPIPE_ANY)) {
-    signalPipeClose(conn->send_pipe, TRUE);
-    signalPipeClose(conn->recv_pipe, TRUE);
+    signalPipeClose(&conn->send_pipe, TRUE);
+    signalPipeClose(&conn->recv_pipe, TRUE);
   }
 
   conn_free(conn);
@@ -3143,9 +3178,9 @@ void Curl_getoff_all_pipelines(struct Curl_easy *data,
   bool send_head = (conn->writechannel_inuse &&
                     Curl_sendpipe_head(data, conn));
 
-  if(Curl_removeHandleFromPipeline(data, conn->recv_pipe) && recv_head)
+  if(Curl_removeHandleFromPipeline(data, &conn->recv_pipe) && recv_head)
     Curl_pipeline_leave_read(conn);
-  if(Curl_removeHandleFromPipeline(data, conn->send_pipe) && send_head)
+  if(Curl_removeHandleFromPipeline(data, &conn->send_pipe) && send_head)
     Curl_pipeline_leave_write(conn);
 }
 
@@ -3206,7 +3241,7 @@ Curl_oldest_idle_connection(struct Curl_easy *data)
 
     bundle = he->ptr;
 
-    curr = bundle->conn_list->head;
+    curr = bundle->conn_list.head;
     while(curr) {
       conn = curr->ptr;
 
@@ -3234,9 +3269,7 @@ proxy_info_matches(const struct proxy_info* data,
 {
   if((data->proxytype == needle->proxytype) &&
      (data->port == needle->port) &&
-     Curl_safe_strcasecompare(data->host.name, needle->host.name) &&
-     Curl_safe_strcasecompare(data->user, needle->user) &&
-     Curl_safe_strcasecompare(data->passwd, needle->passwd))
+     Curl_safe_strcasecompare(data->host.name, needle->host.name))
     return TRUE;
 
   return FALSE;
@@ -3265,7 +3298,7 @@ find_oldest_idle_connection_in_bundle(struct Curl_easy *data,
 
   now = Curl_tvnow();
 
-  curr = bundle->conn_list->head;
+  curr = bundle->conn_list.head;
   while(curr) {
     conn = curr->ptr;
 
@@ -3293,7 +3326,7 @@ find_oldest_idle_connection_in_bundle(struct Curl_easy *data,
 static bool disconnect_if_dead(struct connectdata *conn,
                                struct Curl_easy *data)
 {
-  size_t pipeLen = conn->send_pipe->size + conn->recv_pipe->size;
+  size_t pipeLen = conn->send_pipe.size + conn->recv_pipe.size;
   if(!pipeLen && !conn->inuse) {
     /* The check for a dead socket makes sense only if there are no
        handles in pipeline and the connection isn't already marked in
@@ -3406,19 +3439,14 @@ ConnectionExists(struct Curl_easy *data,
       max_pipeline_length(data->multi):0;
     size_t best_pipe_len = max_pipe_len;
     struct curl_llist_element *curr;
-    const char *hostname;
-
-    if(needle->bits.conn_to_host)
-      hostname = needle->conn_to_host.name;
-    else
-      hostname = needle->host.name;
 
     infof(data, "Found bundle for host %s: %p [%s]\n",
-          hostname, (void *)bundle,
-          (bundle->multiuse== BUNDLE_PIPELINING?
-           "can pipeline":
-           (bundle->multiuse== BUNDLE_MULTIPLEX?
-            "can multiplex":"serially")));
+          (needle->bits.conn_to_host ? needle->conn_to_host.name :
+           needle->host.name), (void *)bundle,
+          (bundle->multiuse == BUNDLE_PIPELINING ?
+           "can pipeline" :
+           (bundle->multiuse == BUNDLE_MULTIPLEX ?
+            "can multiplex" : "serially")));
 
     /* We can't pipe if we don't know anything about the server */
     if(canPipeline) {
@@ -3445,7 +3473,7 @@ ConnectionExists(struct Curl_easy *data,
       }
     }
 
-    curr = bundle->conn_list->head;
+    curr = bundle->conn_list.head;
     while(curr) {
       bool match = FALSE;
       size_t pipeLen;
@@ -3460,7 +3488,7 @@ ConnectionExists(struct Curl_easy *data,
       if(disconnect_if_dead(check, data))
         continue;
 
-      pipeLen = check->send_pipe->size + check->recv_pipe->size;
+      pipeLen = check->send_pipe.size + check->recv_pipe.size;
 
       if(canPipeline) {
         if(check->bits.protoconnstart && check->bits.close)
@@ -3468,8 +3496,8 @@ ConnectionExists(struct Curl_easy *data,
 
         if(!check->bits.multiplex) {
           /* If not multiplexing, make sure the pipe has only GET requests */
-          struct Curl_easy* sh = gethandleathead(check->send_pipe);
-          struct Curl_easy* rh = gethandleathead(check->recv_pipe);
+          struct Curl_easy* sh = gethandleathead(&check->send_pipe);
+          struct Curl_easy* rh = gethandleathead(&check->recv_pipe);
           if(sh) {
             if(!IsPipeliningPossible(sh, check))
               continue;
@@ -3507,7 +3535,7 @@ ConnectionExists(struct Curl_easy *data,
           infof(data, "Connection #%ld isn't open enough, can't reuse\n",
                 check->connection_id);
 #ifdef DEBUGBUILD
-          if(check->recv_pipe->size > 0) {
+          if(check->recv_pipe.size > 0) {
             infof(data,
                   "BAD! Unconnected #%ld has a non-empty recv pipeline!\n",
                   check->connection_id);
@@ -3523,6 +3551,8 @@ ConnectionExists(struct Curl_easy *data,
           continue;
         if(strcmp(needle->unix_domain_socket, check->unix_domain_socket))
           continue;
+        if(needle->abstract_unix_socket != check->abstract_unix_socket)
+          continue;
       }
       else if(check->unix_domain_socket)
         continue;
@@ -3644,7 +3674,7 @@ ConnectionExists(struct Curl_easy *data,
                            check->connection_id));
               continue;
             }
-            else if(check->ssl[FIRSTSOCKET].state != ssl_connection_complete) {
+            if(check->ssl[FIRSTSOCKET].state != ssl_connection_complete) {
               foundPendingCandidate = TRUE;
               DEBUGF(infof(data,
                            "Connection #%ld has not started SSL connect, "
@@ -3797,17 +3827,19 @@ CURLcode Curl_connected_proxy(struct connectdata *conn, int sockindex)
 
   if(conn->bits.socksproxy) {
 #ifndef CURL_DISABLE_PROXY
-    const char * const host = conn->bits.conn_to_host ?
-                              conn->conn_to_host.name :
-                              conn->bits.httpproxy ?
+    /* for the secondary socket (FTP), use the "connect to host"
+     * but ignore the "connect to port" (use the secondary port)
+     */
+    const char * const host = conn->bits.httpproxy ?
                               conn->http_proxy.host.name :
+                              conn->bits.conn_to_host ?
+                              conn->conn_to_host.name :
                               sockindex == SECONDARYSOCKET ?
                               conn->secondaryhostname : conn->host.name;
-    const int port = conn->bits.conn_to_port ? conn->conn_to_port :
-                     conn->bits.httpproxy ?
-                     (int)conn->http_proxy.port :
-                     sockindex == SECONDARYSOCKET ?
-                      conn->secondary_port : conn->remote_port;
+    const int port = conn->bits.httpproxy ? (int)conn->http_proxy.port :
+                     sockindex == SECONDARYSOCKET ? conn->secondary_port :
+                     conn->bits.conn_to_port ? conn->conn_to_port :
+                     conn->remote_port;
     conn->bits.socksproxy_connecting = TRUE;
     switch(conn->socks_proxy.proxytype) {
     case CURLPROXY_SOCKS5:
@@ -3845,7 +3877,8 @@ void Curl_verboseconnect(struct connectdata *conn)
     infof(conn->data, "Connected to %s (%s) port %ld (#%ld)\n",
           conn->bits.socksproxy ? conn->socks_proxy.host.dispname :
           conn->bits.httpproxy ? conn->http_proxy.host.dispname :
-                             conn->host.dispname,
+          conn->bits.conn_to_host ? conn->conn_to_host.dispname :
+          conn->host.dispname,
           conn->ip_addr_str, conn->port, conn->connection_id);
 }
 #endif
@@ -3968,7 +4001,7 @@ CURLcode Curl_protocol_connect(struct connectdata *conn,
 }
 
 /*
- * Helpers for IDNA convertions.
+ * Helpers for IDNA conversions.
  */
 static bool is_ASCII_name(const char *hostname)
 {
@@ -4010,7 +4043,15 @@ static void fix_hostname(struct connectdata *conn, struct hostname *host)
 #ifdef USE_LIBIDN2
     if(idn2_check_version(IDN2_VERSION)) {
       char *ace_hostname = NULL;
-      int rc = idn2_lookup_ul((const char *)host->name, &ace_hostname, 0);
+#if IDN2_VERSION_NUMBER >= 0x00140000
+      /* IDN2_NFC_INPUT: Normalize input string using normalization form C.
+         IDN2_NONTRANSITIONAL: Perform Unicode TR46 non-transitional
+         processing. */
+      int flags = IDN2_NFC_INPUT | IDN2_NONTRANSITIONAL;
+#else
+      int flags = IDN2_NFC_INPUT;
+#endif
+      int rc = idn2_lookup_ul((const char *)host->name, &ace_hostname, flags);
       if(rc == IDN2_OK) {
         host->encalloc = (char *)ace_hostname;
         /* change the name pointer to point to the encoded hostname */
@@ -4084,7 +4125,7 @@ static struct connectdata *allocate_conn(struct Curl_easy *data)
   conn->tempsock[1] = CURL_SOCKET_BAD; /* no file descriptor */
   conn->connection_id = -1;    /* no ID */
   conn->port = -1; /* unknown at this point */
-  conn->remote_port = -1; /* unknown */
+  conn->remote_port = -1; /* unknown at this point */
 #if defined(USE_RECV_BEFORE_SEND_WORKAROUND) && defined(DEBUGBUILD)
   conn->postponed[0].bindsock = CURL_SOCKET_BAD; /* no file descriptor */
   conn->postponed[1].bindsock = CURL_SOCKET_BAD; /* no file descriptor */
@@ -4141,8 +4182,11 @@ static struct connectdata *allocate_conn(struct Curl_easy *data)
   conn->bits.ftp_use_epsv = data->set.ftp_use_epsv;
   conn->bits.ftp_use_eprt = data->set.ftp_use_eprt;
 
+  conn->ssl_config.verifystatus = data->set.ssl.primary.verifystatus;
   conn->ssl_config.verifypeer = data->set.ssl.primary.verifypeer;
   conn->ssl_config.verifyhost = data->set.ssl.primary.verifyhost;
+  conn->proxy_ssl_config.verifystatus =
+    data->set.proxy_ssl.primary.verifystatus;
   conn->proxy_ssl_config.verifypeer = data->set.proxy_ssl.primary.verifypeer;
   conn->proxy_ssl_config.verifyhost = data->set.proxy_ssl.primary.verifyhost;
 
@@ -4165,10 +4209,8 @@ static struct connectdata *allocate_conn(struct Curl_easy *data)
   }
 
   /* Initialize the pipeline lists */
-  conn->send_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor);
-  conn->recv_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor);
-  if(!conn->send_pipe || !conn->recv_pipe)
-    goto error;
+  Curl_llist_init(&conn->send_pipe, (curl_llist_dtor) llist_dtor);
+  Curl_llist_init(&conn->recv_pipe, (curl_llist_dtor) llist_dtor);
 
 #ifdef HAVE_GSSAPI
   conn->data_prot = PROT_CLEAR;
@@ -4191,11 +4233,8 @@ static struct connectdata *allocate_conn(struct Curl_easy *data)
   return conn;
   error:
 
-  Curl_llist_destroy(conn->send_pipe, NULL);
-  Curl_llist_destroy(conn->recv_pipe, NULL);
-
-  conn->send_pipe = NULL;
-  conn->recv_pipe = NULL;
+  Curl_llist_destroy(&conn->send_pipe, NULL);
+  Curl_llist_destroy(&conn->recv_pipe, NULL);
 
   free(conn->master_buffer);
   free(conn->localdev);
@@ -4258,11 +4297,13 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
   char *fragment;
   char *path = data->state.path;
   char *query;
+  int i;
   int rc;
-  char protobuf[16] = "";
   const char *protop = "";
   CURLcode result;
   bool rebuild_url = FALSE;
+  bool url_has_scheme = FALSE;
+  char protobuf[16];
 
   *prot_missing = FALSE;
 
@@ -4281,10 +4322,47 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
    * proxy -- and we don't know if we will need to use SSL until we parse the
    * url ...
    ************************************************************/
-  if((2 == sscanf(data->change.url, "%15[^:]:%[^\n]",
-                  protobuf, path)) &&
-     strcasecompare(protobuf, "file")) {
-    if(path[0] == '/' && path[1] == '/') {
+  if(data->change.url[0] == ':') {
+    failf(data, "Bad URL, colon is first character");
+    return CURLE_URL_MALFORMAT;
+  }
+
+  /* Make sure we don't mistake a drive letter for a scheme, for example:
+     curld --proto-default file c:/foo/bar.txt */
+  if((('a' <= data->change.url[0] && data->change.url[0] <= 'z') ||
+      ('A' <= data->change.url[0] && data->change.url[0] <= 'Z')) &&
+     data->change.url[1] == ':' && data->set.str[STRING_DEFAULT_PROTOCOL] &&
+     strcasecompare(data->set.str[STRING_DEFAULT_PROTOCOL], "file")) {
+    ; /* do nothing */
+  }
+  else { /* check for a scheme */
+    for(i = 0; i < 16 && data->change.url[i]; ++i) {
+      if(data->change.url[i] == '/')
+        break;
+      if(data->change.url[i] == ':') {
+        url_has_scheme = TRUE;
+        break;
+      }
+    }
+  }
+
+  /* handle the file: scheme */
+  if((url_has_scheme && strncasecompare(data->change.url, "file:", 5)) ||
+     (!url_has_scheme && data->set.str[STRING_DEFAULT_PROTOCOL] &&
+      strcasecompare(data->set.str[STRING_DEFAULT_PROTOCOL], "file"))) {
+    bool path_has_drive = FALSE;
+
+    if(url_has_scheme)
+      rc = sscanf(data->change.url, "%*15[^\n/:]:%[^\n]", path);
+    else
+      rc = sscanf(data->change.url, "%[^\n]", path);
+
+    if(rc != 1) {
+      failf(data, "Bad URL");
+      return CURLE_URL_MALFORMAT;
+    }
+
+    if(url_has_scheme && path[0] == '/' && path[1] == '/') {
       /* Allow omitted hostname (e.g. file:/<path>).  This is not strictly
        * speaking a valid file: URL by RFC 1738, but treating file:/<path> as
        * file://localhost/<path> is similar to how other schemes treat missing
@@ -4294,18 +4372,25 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
          memory areas overlap! */
       memmove(path, path + 2, strlen(path + 2)+1);
     }
+
+    /* the path may start with a drive letter. for backwards compatibility
+       we skip some processing on those paths. */
+    path_has_drive = (('a' <= path[0] && path[0] <= 'z') ||
+                      ('A' <= path[0] && path[0] <= 'Z')) && path[1] == ':';
+
     /*
      * we deal with file://<host>/<path> differently since it supports no
      * hostname other than "localhost" and "127.0.0.1", which is unique among
      * the URL protocols specified in RFC 1738
      */
-    if(path[0] != '/') {
+    if(path[0] != '/' && !path_has_drive) {
       /* the URL includes a host name, it must match "localhost" or
          "127.0.0.1" to be valid */
       char *ptr;
       if(!checkprefix("localhost/", path) &&
          !checkprefix("127.0.0.1/", path)) {
-        failf(data, "Valid host name with slash missing in URL");
+        failf(data, "Invalid file://hostname/, "
+                    "expected localhost or 127.0.0.1 or none");
         return CURLE_URL_MALFORMAT;
       }
       ptr = &path[9]; /* now points to the slash after the host */
@@ -4332,7 +4417,17 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
 
       /* This cannot be made with strcpy, as the memory chunks overlap! */
       memmove(path, ptr, strlen(ptr)+1);
+
+      path_has_drive = (('a' <= path[0] && path[0] <= 'z') ||
+                        ('A' <= path[0] && path[0] <= 'Z')) && path[1] == ':';
+    }
+
+#if !defined(MSDOS) && !defined(WIN32) && !defined(__CYGWIN__)
+    if(path_has_drive) {
+      failf(data, "File drive letters are only accepted in MSDOS/Windows.");
+      return CURLE_URL_MALFORMAT;
     }
+#endif
 
     protop = "file"; /* protocol string */
   }
@@ -4342,7 +4437,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
     path[0]=0;
 
     rc = sscanf(data->change.url,
-                "%15[^\n:]:%3[/]%[^\n/?#]%[^\n]",
+                "%15[^\n/:]:%3[/]%[^\n/?#]%[^\n]",
                 protobuf, slashbuf, conn->host.name, path);
     if(2 == rc) {
       failf(data, "Bad URL");
@@ -4527,6 +4622,10 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
     data->change.url_alloc = TRUE; /* free this later */
   }
 
+  result = findprotocol(data, conn, protop);
+  if(result)
+    return result;
+
   /*
    * Parse the login details from the URL and strip them out of
    * the host name
@@ -4613,8 +4712,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
    *   conn->host.name is B
    *   data->state.path is /C
    */
-
-  return findprotocol(data, conn, protop);
+  return CURLE_OK;
 }
 
 /*
@@ -4783,6 +4881,7 @@ static bool check_noproxy(const char *name, const char *no_proxy)
   return FALSE;
 }
 
+#ifndef CURL_DISABLE_HTTP
 /****************************************************************
 * Detect what (if any) proxy to use. Remember that this selects a host
 * name and is not limited to HTTP proxies only.
@@ -4792,7 +4891,6 @@ static char *detect_proxy(struct connectdata *conn)
 {
   char *proxy = NULL;
 
-#ifndef CURL_DISABLE_HTTP
   /* If proxy was not specified, we check for default proxy environment
    * variables, to enable i.e Lynx compliance:
    *
@@ -4810,65 +4908,50 @@ static char *detect_proxy(struct connectdata *conn)
    * For compatibility, the all-uppercase versions of these variables are
    * checked if the lowercase versions don't exist.
    */
-  char *no_proxy=NULL;
   char proxy_env[128];
+  const char *protop = conn->handler->scheme;
+  char *envp = proxy_env;
+  char *prox;
 
-  no_proxy=curl_getenv("no_proxy");
-  if(!no_proxy)
-    no_proxy=curl_getenv("NO_PROXY");
-
-  if(!check_noproxy(conn->host.name, no_proxy)) {
-    /* It was not listed as without proxy */
-    const char *protop = conn->handler->scheme;
-    char *envp = proxy_env;
-    char *prox;
+  /* Now, build <protocol>_proxy and check for such a one to use */
+  while(*protop)
+    *envp++ = (char)tolower((int)*protop++);
 
-    /* Now, build <protocol>_proxy and check for such a one to use */
-    while(*protop)
-      *envp++ = (char)tolower((int)*protop++);
+  /* append _proxy */
+  strcpy(envp, "_proxy");
 
-    /* append _proxy */
-    strcpy(envp, "_proxy");
+  /* read the protocol proxy: */
+  prox=curl_getenv(proxy_env);
 
-    /* read the protocol proxy: */
+  /*
+   * We don't try the uppercase version of HTTP_PROXY because of
+   * security reasons:
+   *
+   * When curl is used in a webserver application
+   * environment (cgi or php), this environment variable can
+   * be controlled by the web server user by setting the
+   * http header 'Proxy:' to some value.
+   *
+   * This can cause 'internal' http/ftp requests to be
+   * arbitrarily redirected by any external attacker.
+   */
+  if(!prox && !strcasecompare("http_proxy", proxy_env)) {
+    /* There was no lowercase variable, try the uppercase version: */
+    Curl_strntoupper(proxy_env, proxy_env, sizeof(proxy_env));
     prox=curl_getenv(proxy_env);
+  }
 
-    /*
-     * We don't try the uppercase version of HTTP_PROXY because of
-     * security reasons:
-     *
-     * When curl is used in a webserver application
-     * environment (cgi or php), this environment variable can
-     * be controlled by the web server user by setting the
-     * http header 'Proxy:' to some value.
-     *
-     * This can cause 'internal' http/ftp requests to be
-     * arbitrarily redirected by any external attacker.
-     */
-    if(!prox && !strcasecompare("http_proxy", proxy_env)) {
-      /* There was no lowercase variable, try the uppercase version: */
-      Curl_strntoupper(proxy_env, proxy_env, sizeof(proxy_env));
-      prox=curl_getenv(proxy_env);
-    }
-
-    if(prox)
-      proxy = prox; /* use this */
-    else {
-      proxy = curl_getenv("all_proxy"); /* default proxy to use */
-      if(!proxy)
-        proxy=curl_getenv("ALL_PROXY");
-    }
-  } /* if(!check_noproxy(conn->host.name, no_proxy)) - it wasn't specified
-       non-proxy */
-  free(no_proxy);
-
-#else /* !CURL_DISABLE_HTTP */
-
-  (void)conn;
-#endif /* CURL_DISABLE_HTTP */
+  if(prox)
+    proxy = prox; /* use this */
+  else {
+    proxy = curl_getenv("all_proxy"); /* default proxy to use */
+    if(!proxy)
+      proxy=curl_getenv("ALL_PROXY");
+  }
 
   return proxy;
 }
+#endif /* CURL_DISABLE_HTTP */
 
 /*
  * If this is supposed to use a proxy, we need to figure out the proxy
@@ -5032,15 +5115,19 @@ static CURLcode parse_proxy(struct Curl_easy *data,
          with reserved characters like ':' in them. */
       Curl_safefree(proxyinfo->user);
       proxyinfo->user = curl_easy_unescape(data, proxyuser, 0, NULL);
+      Curl_safefree(proxyuser);
 
-      if(!proxyinfo->user)
+      if(!proxyinfo->user) {
+        Curl_safefree(proxypasswd);
         return CURLE_OUT_OF_MEMORY;
+      }
 
       Curl_safefree(proxyinfo->passwd);
       if(proxypasswd && strlen(proxypasswd) < MAX_CURL_PASSWORD_LENGTH)
         proxyinfo->passwd = curl_easy_unescape(data, proxypasswd, 0, NULL);
       else
         proxyinfo->passwd = strdup("");
+      Curl_safefree(proxypasswd);
 
       if(!proxyinfo->passwd)
         return CURLE_OUT_OF_MEMORY;
@@ -5097,6 +5184,168 @@ static CURLcode parse_proxy_auth(struct Curl_easy *data,
                             NULL, FALSE);
   return result;
 }
+
+/* create_conn helper to parse and init proxy values. to be called after unix
+   socket init but before any proxy vars are evaluated. */
+static CURLcode create_conn_helper_init_proxy(struct connectdata *conn)
+{
+  char *proxy = NULL;
+  char *socksproxy = NULL;
+  char *no_proxy = NULL;
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+
+  /*************************************************************
+   * Extract the user and password from the authentication string
+   *************************************************************/
+  if(conn->bits.proxy_user_passwd) {
+    result = parse_proxy_auth(data, conn);
+    if(result)
+      goto out;
+  }
+
+  /*************************************************************
+   * Detect what (if any) proxy to use
+   *************************************************************/
+  if(data->set.str[STRING_PROXY]) {
+    proxy = strdup(data->set.str[STRING_PROXY]);
+    /* if global proxy is set, this is it */
+    if(NULL == proxy) {
+      failf(data, "memory shortage");
+      result = CURLE_OUT_OF_MEMORY;
+      goto out;
+    }
+  }
+
+  if(data->set.str[STRING_PRE_PROXY]) {
+    socksproxy = strdup(data->set.str[STRING_PRE_PROXY]);
+    /* if global socks proxy is set, this is it */
+    if(NULL == socksproxy) {
+      failf(data, "memory shortage");
+      result = CURLE_OUT_OF_MEMORY;
+      goto out;
+    }
+  }
+
+  no_proxy = curl_getenv("no_proxy");
+  if(!no_proxy)
+    no_proxy = curl_getenv("NO_PROXY");
+
+  if(check_noproxy(conn->host.name, data->set.str[STRING_NOPROXY]) ||
+     (!data->set.str[STRING_NOPROXY] &&
+      check_noproxy(conn->host.name, no_proxy))) {
+    Curl_safefree(proxy);
+    Curl_safefree(socksproxy);
+  }
+  else if(!proxy && !socksproxy)
+#ifndef CURL_DISABLE_HTTP
+    /* if the host is not in the noproxy list, detect proxy. */
+    proxy = detect_proxy(conn);
+#else  /* !CURL_DISABLE_HTTP */
+    proxy = NULL;
+#endif /* CURL_DISABLE_HTTP */
+
+  Curl_safefree(no_proxy);
+
+#ifdef USE_UNIX_SOCKETS
+  /* For the time being do not mix proxy and unix domain sockets. See #1274 */
+  if(proxy && conn->unix_domain_socket) {
+    free(proxy);
+    proxy = NULL;
+  }
+#endif
+
+  if(proxy && (!*proxy || (conn->handler->flags & PROTOPT_NONETWORK))) {
+    free(proxy);  /* Don't bother with an empty proxy string or if the
+                     protocol doesn't work with network */
+    proxy = NULL;
+  }
+  if(socksproxy && (!*socksproxy ||
+                    (conn->handler->flags & PROTOPT_NONETWORK))) {
+    free(socksproxy);  /* Don't bother with an empty socks proxy string or if
+                          the protocol doesn't work with network */
+    socksproxy = NULL;
+  }
+
+  /***********************************************************************
+   * If this is supposed to use a proxy, we need to figure out the proxy host
+   * name, proxy type and port number, so that we can re-use an existing
+   * connection that may exist registered to the same proxy host.
+   ***********************************************************************/
+  if(proxy || socksproxy) {
+    if(proxy) {
+      result = parse_proxy(data, conn, proxy, conn->http_proxy.proxytype);
+      Curl_safefree(proxy); /* parse_proxy copies the proxy string */
+      if(result)
+        goto out;
+    }
+
+    if(socksproxy) {
+      result = parse_proxy(data, conn, socksproxy,
+                           conn->socks_proxy.proxytype);
+      /* parse_proxy copies the socks proxy string */
+      Curl_safefree(socksproxy);
+      if(result)
+        goto out;
+    }
+
+    if(conn->http_proxy.host.rawalloc) {
+#ifdef CURL_DISABLE_HTTP
+      /* asking for a HTTP proxy is a bit funny when HTTP is disabled... */
+      result = CURLE_UNSUPPORTED_PROTOCOL;
+      goto out;
+#else
+      /* force this connection's protocol to become HTTP if not already
+         compatible - if it isn't tunneling through */
+      if(!(conn->handler->protocol & PROTO_FAMILY_HTTP) &&
+         !conn->bits.tunnel_proxy)
+        conn->handler = &Curl_handler_http;
+
+      conn->bits.httpproxy = TRUE;
+#endif
+    }
+    else {
+      conn->bits.httpproxy = FALSE; /* not a HTTP proxy */
+      conn->bits.tunnel_proxy = FALSE; /* no tunneling if not HTTP */
+    }
+
+    if(conn->socks_proxy.host.rawalloc) {
+      if(!conn->http_proxy.host.rawalloc) {
+        /* once a socks proxy */
+        if(!conn->socks_proxy.user) {
+          conn->socks_proxy.user = conn->http_proxy.user;
+          conn->http_proxy.user = NULL;
+          Curl_safefree(conn->socks_proxy.passwd);
+          conn->socks_proxy.passwd = conn->http_proxy.passwd;
+          conn->http_proxy.passwd = NULL;
+        }
+      }
+      conn->bits.socksproxy = TRUE;
+    }
+    else
+      conn->bits.socksproxy = FALSE; /* not a socks proxy */
+  }
+  else {
+    conn->bits.socksproxy = FALSE;
+    conn->bits.httpproxy = FALSE;
+  }
+  conn->bits.proxy = conn->bits.httpproxy || conn->bits.socksproxy;
+
+  if(!conn->bits.proxy) {
+    /* we aren't using the proxy after all... */
+    conn->bits.proxy = FALSE;
+    conn->bits.httpproxy = FALSE;
+    conn->bits.socksproxy = FALSE;
+    conn->bits.proxy_user_passwd = FALSE;
+    conn->bits.tunnel_proxy = FALSE;
+  }
+
+out:
+
+  free(socksproxy);
+  free(proxy);
+  return result;
+}
 #endif /* CURL_DISABLE_PROXY */
 
 /*
@@ -5137,6 +5386,7 @@ static CURLcode parse_url_login(struct Curl_easy *data,
   DEBUGASSERT(!**user);
   DEBUGASSERT(!**passwd);
   DEBUGASSERT(!**options);
+  DEBUGASSERT(conn->handler);
 
   if(!ptr)
     goto out;
@@ -5155,9 +5405,12 @@ static CURLcode parse_url_login(struct Curl_easy *data,
   if(data->set.use_netrc == CURL_NETRC_REQUIRED)
     goto out;
 
-  /* We could use the login information in the URL so extract it */
+  /* We could use the login information in the URL so extract it. Only parse
+     options if the handler says we should. */
   result = parse_login_details(login, ptr - login - 1,
-                               &userp, &passwdp, &optionsp);
+                               &userp, &passwdp,
+                               (conn->handler->flags & PROTOPT_URLOPTIONS)?
+                               &optionsp:NULL);
   if(result)
     goto out;
 
@@ -5387,7 +5640,7 @@ static CURLcode parse_remote_port(struct Curl_easy *data,
     }
 #endif
 
-    portptr = strrchr(conn->host.name, ':');
+    portptr = strchr(conn->host.name, ':');
   }
 
   if(data->set.use_port && data->state.allow_port) {
@@ -5442,15 +5695,16 @@ static CURLcode parse_remote_port(struct Curl_easy *data,
       return CURLE_URL_MALFORMAT;
     }
 
-    else if(rest != &portptr[1]) {
+    if(rest[0]) {
+      failf(data, "Port number ended with '%c'", rest[0]);
+      return CURLE_URL_MALFORMAT;
+    }
+
+    if(rest != &portptr[1]) {
       *portptr = '\0'; /* cut off the name there */
       conn->remote_port = curlx_ultous(port);
     }
     else {
-      if(rest[0]) {
-        failf(data, "Illegal port number");
-        return CURLE_URL_MALFORMAT;
-      }
       /* Browser behavior adaptation. If there's a colon with no digits after,
          just cut off the name there which makes us ignore the colon and just
          use the default port. Firefox and Chrome both do that. */
@@ -5584,6 +5838,10 @@ static CURLcode parse_connect_to_host_port(struct Curl_easy *data,
   char *portptr;
   int port = -1;
 
+#if defined(CURL_DISABLE_VERBOSE_STRINGS)
+  (void) data;
+#endif
+
   *hostname_result = NULL;
   *port_result = -1;
 
@@ -5749,14 +6007,11 @@ static CURLcode parse_connect_to_slist(struct Curl_easy *data,
       return result;
 
     if(host && *host) {
-      bool ipv6host;
       conn->conn_to_host.rawalloc = host;
       conn->conn_to_host.name = host;
       conn->bits.conn_to_host = TRUE;
 
-      ipv6host = strchr(host, ':') != NULL;
-      infof(data, "Connecting to hostname: %s%s%s\n",
-            ipv6host ? "[" : "", host, ipv6host ? "]" : "");
+      infof(data, "Connecting to hostname: %s\n", host);
     }
     else {
       /* no "connect to host" */
@@ -5816,8 +6071,9 @@ static CURLcode resolve_server(struct Curl_easy *data,
       if(!hostaddr)
         result = CURLE_OUT_OF_MEMORY;
       else {
-        int longpath=0;
-        hostaddr->addr = Curl_unix2addr(path, &longpath);
+        bool longpath = FALSE;
+        hostaddr->addr = Curl_unix2addr(path, &longpath,
+                                        conn->abstract_unix_socket);
         if(hostaddr->addr)
           hostaddr->inuse++;
         else {
@@ -5847,7 +6103,7 @@ static CURLcode resolve_server(struct Curl_easy *data,
       if(conn->bits.conn_to_port)
         conn->port = conn->conn_to_port;
       else
-        conn->port = conn->remote_port; /* it is the same port */
+        conn->port = conn->remote_port;
 
       /* Resolve target host right on */
       rc = Curl_resolv_timeout(conn, connhost->name, (int)conn->port,
@@ -5903,11 +6159,9 @@ static void reuse_conn(struct connectdata *old_conn,
 {
   free_fixed_hostname(&old_conn->http_proxy.host);
   free_fixed_hostname(&old_conn->socks_proxy.host);
-  free_fixed_hostname(&old_conn->proxy);
 
   free(old_conn->http_proxy.host.rawalloc);
   free(old_conn->socks_proxy.host.rawalloc);
-  free(old_conn->proxy.rawalloc);
 
   /* free the SSL config struct from this connection struct as this was
      allocated in vain and is targeted for destruction */
@@ -5962,7 +6216,6 @@ static void reuse_conn(struct connectdata *old_conn,
   Curl_persistconninfo(conn);
 
   conn_reset_all_postponed_data(old_conn); /* free buffers */
-  conn_reset_all_postponed_data(conn);     /* reset unprocessed data */
 
   /* re-use init */
   conn->bits.reuse = TRUE; /* yes, we're re-using here */
@@ -5975,11 +6228,8 @@ static void reuse_conn(struct connectdata *old_conn,
   Curl_safefree(old_conn->socks_proxy.passwd);
   Curl_safefree(old_conn->localdev);
 
-  Curl_llist_destroy(old_conn->send_pipe, NULL);
-  Curl_llist_destroy(old_conn->recv_pipe, NULL);
-
-  old_conn->send_pipe = NULL;
-  old_conn->recv_pipe = NULL;
+  Curl_llist_destroy(&old_conn->send_pipe, NULL);
+  Curl_llist_destroy(&old_conn->recv_pipe, NULL);
 
   Curl_safefree(old_conn->master_buffer);
 
@@ -6016,8 +6266,6 @@ static CURLcode create_conn(struct Curl_easy *data,
   char *passwd = NULL;
   char *options = NULL;
   bool reuse;
-  char *proxy = NULL;
-  char *socksproxy = NULL;
   bool prot_missing = FALSE;
   bool connections_available = TRUE;
   bool force_reuse = FALSE;
@@ -6161,147 +6409,24 @@ static CURLcode create_conn(struct Curl_easy *data,
     }
   }
 
-#ifndef CURL_DISABLE_PROXY
-  /*************************************************************
-   * Extract the user and password from the authentication string
-   *************************************************************/
-  if(conn->bits.proxy_user_passwd) {
-    result = parse_proxy_auth(data, conn);
-    if(result)
-      goto out;
-  }
-
-  /*************************************************************
-   * Detect what (if any) proxy to use
-   *************************************************************/
-  if(data->set.str[STRING_PROXY]) {
-    proxy = strdup(data->set.str[STRING_PROXY]);
-    /* if global proxy is set, this is it */
-    if(NULL == proxy) {
-      failf(data, "memory shortage");
-      result = CURLE_OUT_OF_MEMORY;
-      goto out;
-    }
-  }
-
-  if(data->set.str[STRING_PRE_PROXY]) {
-    socksproxy = strdup(data->set.str[STRING_PRE_PROXY]);
-    /* if global socks proxy is set, this is it */
-    if(NULL == socksproxy) {
-      failf(data, "memory shortage");
-      result = CURLE_OUT_OF_MEMORY;
-      goto out;
-    }
-  }
-
-  if(data->set.str[STRING_NOPROXY] &&
-     check_noproxy(conn->host.name, data->set.str[STRING_NOPROXY])) {
-    Curl_safefree(proxy);
-    Curl_safefree(socksproxy);
-  }
-  else if(!proxy && !socksproxy)
-    proxy = detect_proxy(conn);
-
 #ifdef USE_UNIX_SOCKETS
   if(data->set.str[STRING_UNIX_SOCKET_PATH]) {
-    if(proxy) {
-      free(proxy); /* Unix domain sockets cannot be proxied, so disable it */
-      proxy = NULL;
-    }
     conn->unix_domain_socket = strdup(data->set.str[STRING_UNIX_SOCKET_PATH]);
     if(conn->unix_domain_socket == NULL) {
       result = CURLE_OUT_OF_MEMORY;
       goto out;
     }
+    conn->abstract_unix_socket = data->set.abstract_unix_socket;
   }
 #endif
 
-  if(proxy && (!*proxy || (conn->handler->flags & PROTOPT_NONETWORK))) {
-    free(proxy);  /* Don't bother with an empty proxy string or if the
-                     protocol doesn't work with network */
-    proxy = NULL;
-  }
-  if(socksproxy && (!*socksproxy ||
-                    (conn->handler->flags & PROTOPT_NONETWORK))) {
-    free(socksproxy);  /* Don't bother with an empty socks proxy string or if
-                          the protocol doesn't work with network */
-    socksproxy = NULL;
-  }
-
-  /***********************************************************************
-   * If this is supposed to use a proxy, we need to figure out the proxy host
-   * name, proxy type and port number, so that we can re-use an existing
-   * connection that may exist registered to the same proxy host.
-   ***********************************************************************/
-  if(proxy || socksproxy) {
-    if(proxy) {
-      result = parse_proxy(data, conn, proxy, conn->http_proxy.proxytype);
-      Curl_safefree(proxy); /* parse_proxy copies the proxy string */
-      if(result)
-        goto out;
-    }
-
-    if(socksproxy) {
-      result = parse_proxy(data, conn, socksproxy,
-                           conn->socks_proxy.proxytype);
-      /* parse_proxy copies the socks proxy string */
-      Curl_safefree(socksproxy);
-      if(result)
-        goto out;
-    }
-
-    if(conn->http_proxy.host.rawalloc) {
-#ifdef CURL_DISABLE_HTTP
-      /* asking for a HTTP proxy is a bit funny when HTTP is disabled... */
-      result = CURLE_UNSUPPORTED_PROTOCOL;
-      goto out;
-#else
-      /* force this connection's protocol to become HTTP if not already
-         compatible - if it isn't tunneling through */
-      if(!(conn->handler->protocol & PROTO_FAMILY_HTTP) &&
-         !conn->bits.tunnel_proxy)
-        conn->handler = &Curl_handler_http;
-
-      conn->bits.httpproxy = TRUE;
+  /* After the unix socket init but before the proxy vars are used, parse and
+     initialize the proxy vars */
+#ifndef CURL_DISABLE_PROXY
+  result = create_conn_helper_init_proxy(conn);
+  if(result)
+    goto out;
 #endif
-    }
-    else {
-      conn->bits.httpproxy = FALSE; /* not a HTTP proxy */
-      conn->bits.tunnel_proxy = FALSE; /* no tunneling if not HTTP */
-    }
-
-    if(conn->socks_proxy.host.rawalloc) {
-      if(!conn->http_proxy.host.rawalloc) {
-        /* once a socks proxy */
-        if(!conn->socks_proxy.user) {
-          conn->socks_proxy.user = conn->http_proxy.user;
-          conn->http_proxy.user = NULL;
-          Curl_safefree(conn->socks_proxy.passwd);
-          conn->socks_proxy.passwd = conn->http_proxy.passwd;
-          conn->http_proxy.passwd = NULL;
-        }
-      }
-      conn->bits.socksproxy = TRUE;
-    }
-    else
-      conn->bits.socksproxy = FALSE; /* not a socks proxy */
-  }
-  else {
-    conn->bits.socksproxy = FALSE;
-    conn->bits.httpproxy = FALSE;
-  }
-  conn->bits.proxy = conn->bits.httpproxy || conn->bits.socksproxy;
-
-  if(!conn->bits.proxy) {
-    /* we aren't using the proxy after all... */
-    conn->bits.proxy = FALSE;
-    conn->bits.httpproxy = FALSE;
-    conn->bits.socksproxy = FALSE;
-    conn->bits.proxy_user_passwd = FALSE;
-    conn->bits.tunnel_proxy = FALSE;
-  }
-
-#endif /* CURL_DISABLE_PROXY */
 
   /*************************************************************
    * If the protocol is using SSL and HTTP proxy is used, we set
@@ -6340,12 +6465,14 @@ static CURLcode create_conn(struct Curl_easy *data,
   fix_hostname(conn, &conn->host);
   if(conn->bits.conn_to_host)
     fix_hostname(conn, &conn->conn_to_host);
-  if(conn->proxy.name && *conn->proxy.name)
-    fix_hostname(conn, &conn->proxy);
+  if(conn->bits.httpproxy)
+    fix_hostname(conn, &conn->http_proxy.host);
+  if(conn->bits.socksproxy)
+    fix_hostname(conn, &conn->socks_proxy.host);
 
   /*************************************************************
    * Check whether the host and the "connect to host" are equal.
-   * Do this after the hostnames have been IDN-fixed .
+   * Do this after the hostnames have been IDN-fixed.
    *************************************************************/
   if(conn->bits.conn_to_host &&
      strcasecompare(conn->conn_to_host.name, conn->host.name)) {
@@ -6501,7 +6628,7 @@ static CURLcode create_conn(struct Curl_easy *data,
   /* If we found a reusable connection, we may still want to
      open a new connection if we are pipelining. */
   if(reuse && !force_reuse && IsPipeliningPossible(data, conn_temp)) {
-    size_t pipelen = conn_temp->send_pipe->size + conn_temp->recv_pipe->size;
+    size_t pipelen = conn_temp->send_pipe.size + conn_temp->recv_pipe.size;
     if(pipelen > 0) {
       infof(data, "Found connection %ld, with requests in the pipe (%zu)\n",
             conn_temp->connection_id, pipelen);
@@ -6661,13 +6788,11 @@ static CURLcode create_conn(struct Curl_easy *data,
    *************************************************************/
   result = resolve_server(data, conn, async);
 
-  out:
+out:
 
   free(options);
   free(passwd);
   free(user);
-  free(socksproxy);
-  free(proxy);
   return result;
 }
 
@@ -6771,7 +6896,7 @@ CURLcode Curl_connect(struct Curl_easy *data,
 
   if(!result) {
     /* no error */
-    if((*in_connect)->send_pipe->size || (*in_connect)->recv_pipe->size)
+    if((*in_connect)->send_pipe.size || (*in_connect)->recv_pipe.size)
       /* pipelining */
       *protocol_done = TRUE;
     else if(!*asyncp) {
diff --git a/lib/urldata.h b/lib/urldata.h
index 0271d26..3c94553 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
@@ -136,8 +136,10 @@
 #undef realloc
 #endif /* USE_AXTLS */
 
-#ifdef USE_SCHANNEL
+#if defined(USE_SCHANNEL) || defined(USE_WINDOWS_SSPI)
 #include "curl_sspi.h"
+#endif
+#ifdef USE_SCHANNEL
 #include <schnlsp.h>
 #include <schannel.h>
 #endif
@@ -201,6 +203,9 @@
 /* Download buffer size, keep it fairly big for speed reasons */
 #undef BUFSIZE
 #define BUFSIZE CURL_MAX_WRITE_SIZE
+#undef MAX_BUFSIZE
+#define MAX_BUFSIZE CURL_MAX_READ_SIZE
+#define CURL_BUFSIZE(x) ((x)?(x):(BUFSIZE))
 
 /* Initial size of the buffer to store headers in, it'll be enlarged in case
    of need. */
@@ -311,7 +316,7 @@ struct ssl_connect_data {
   PRFileDesc *handle;
   char *client_nickname;
   struct Curl_easy *data;
-  struct curl_llist *obj_list;
+  struct curl_llist obj_list;
   PK11GenericObject *obj_clicert;
 #elif defined(USE_GSKIT)
   gsk_handle handle;
@@ -345,6 +350,7 @@ struct ssl_connect_data {
 
 struct ssl_primary_config {
   long version;          /* what version the client wants to use */
+  long version_max;      /* max supported version the client wants to use*/
   bool verifypeer;       /* set TRUE if this is desired */
   bool verifyhost;       /* set TRUE if CN/SAN must match hostname */
   bool verifystatus;     /* set TRUE if certificate status must be checked */
@@ -354,6 +360,7 @@ struct ssl_primary_config {
   char *random_file;     /* path to file containing "random" data */
   char *egdsocket;       /* path to file containing the EGD daemon socket */
   char *cipher_list;     /* list of ciphers to use */
+  bool sessionid;        /* cache session IDs or not */
 };
 
 struct ssl_config_data {
@@ -383,7 +390,6 @@ struct ssl_config_data {
 };
 
 struct ssl_general_config {
-  bool sessionid; /* cache session IDs or not */
   size_t max_ssl_sessions; /* SSL session id cache size */
 };
 
@@ -405,6 +411,7 @@ struct digestdata {
 #if defined(USE_WINDOWS_SSPI)
   BYTE *input_token;
   size_t input_token_len;
+  CtxtHandle *http_context;
 #else
   char *nonce;
   char *cnonce;
@@ -842,6 +849,8 @@ struct Curl_handler {
                                           request instead of per connection */
 #define PROTOPT_ALPN_NPN (1<<8) /* set ALPN and/or NPN for this */
 #define PROTOPT_STREAM (1<<9) /* a protocol with individual logical streams */
+#define PROTOPT_URLOPTIONS (1<<10) /* allow options part in the userinfo field
+                                      of the URL */
 
 /* return the count of bytes sent, or -1 on error */
 typedef ssize_t (Curl_send)(struct connectdata *conn, /* connection data */
@@ -931,7 +940,6 @@ struct connectdata {
   char *secondaryhostname; /* secondary socket host name (ftp) */
   struct hostname conn_to_host; /* the host to connect to. valid only if
                                    bits.conn_to_host is set */
-  struct hostname proxy;
 
   struct proxy_info socks_proxy;
   struct proxy_info http_proxy;
@@ -1050,10 +1058,10 @@ struct connectdata {
                               handle */
   bool writechannel_inuse; /* whether the write channel is in use by an easy
                               handle */
-  struct curl_llist *send_pipe; /* List of handles waiting to
-                                   send on this pipeline */
-  struct curl_llist *recv_pipe; /* List of handles waiting to read
-                                   their responses on this pipeline */
+  struct curl_llist send_pipe; /* List of handles waiting to send on this
+                                  pipeline */
+  struct curl_llist recv_pipe; /* List of handles waiting to read their
+                                  responses on this pipeline */
   char *master_buffer; /* The master buffer allocated on-demand;
                           used for pipelining. */
   size_t read_pos; /* Current read position in the master buffer */
@@ -1133,6 +1141,7 @@ struct connectdata {
 
 #ifdef USE_UNIX_SOCKETS
   char *unix_domain_socket;
+  bool abstract_unix_socket;
 #endif
 };
 
@@ -1274,8 +1283,8 @@ struct auth {
                           this resource */
   bool done;  /* TRUE when the auth phase is done and ready to do the *actual*
                  request */
-  bool multi; /* TRUE if this is not yet authenticated but within the auth
-                 multipass negotiation */
+  bool multipass; /* TRUE if this is not yet authenticated but within the
+                     auth multipass negotiation */
   bool iestyle; /* TRUE if digest should be done IE-style or FALSE if it should
                    be RFC compliant */
 };
@@ -1285,6 +1294,19 @@ struct Curl_http2_dep {
   struct Curl_easy *data;
 };
 
+/*
+ * This struct is for holding data that was attemped to get sent to the user's
+ * callback but is held due to pausing. One instance per type (BOTH, HEADER,
+ * BODY).
+ */
+struct tempbuf {
+  char *buf;  /* allocated buffer to keep data in when a write callback
+                 returns to make the connection paused */
+  size_t len; /* size of the 'tempwrite' allocated buffer */
+  int type;   /* type of the 'tempwrite' buffer as a bitmask that is used with
+                 Curl_client_write() */
+};
+
 struct UrlState {
 
   /* Points to the connection cache */
@@ -1303,9 +1325,9 @@ struct UrlState {
   char *headerbuff; /* allocated buffer to store headers in */
   size_t headersize;   /* size of the allocation */
 
-  char buffer[BUFSIZE+1]; /* download buffer */
+  char *buffer; /* download buffer */
   char uploadbuffer[BUFSIZE+1]; /* upload buffer */
-  curl_off_t current_speed;  /* the ProgressShow() funcion sets this,
+  curl_off_t current_speed;  /* the ProgressShow() function sets this,
                                 bytes / second */
   bool this_is_a_follow; /* this is a followed Location: request */
 
@@ -1318,11 +1340,8 @@ struct UrlState {
   int first_remote_port; /* remote port of the first (not followed) request */
   struct curl_ssl_session *session; /* array of 'max_ssl_sessions' size */
   long sessionage;                  /* number of the most recent session */
-  char *tempwrite;      /* allocated buffer to keep data in when a write
-                           callback returns to make the connection paused */
-  size_t tempwritesize; /* size of the 'tempwrite' allocated buffer */
-  int tempwritetype;    /* type of the 'tempwrite' buffer as a bitmask that is
-                           used with Curl_client_write() */
+  unsigned int tempcount; /* number of entries in use in tempwrite, 0 - 3 */
+  struct tempbuf tempwrite[3]; /* BOTH, HEADER, BODY */
   char *scratch; /* huge buffer[BUFSIZE*2] when doing upload CRLF replacing */
   bool errorbuf; /* Set to TRUE if the error buffer is already filled in.
                     This must be set to FALSE every time _easy_perform() is
@@ -1355,7 +1374,7 @@ struct UrlState {
 #endif /* USE_OPENSSL */
   struct timeval expiretime; /* set this with Curl_expire() only */
   struct Curl_tree timenode; /* for the splay stuff */
-  struct curl_llist *timeoutlist; /* list of pending timeouts */
+  struct curl_llist timeoutlist; /* list of pending timeouts */
 
   /* a place to store the most recently set FTP entrypath */
   char *most_recent_ftp_entrypath;
@@ -1638,7 +1657,6 @@ struct UserDefined {
   struct ssl_config_data proxy_ssl;  /* user defined SSL stuff for proxy */
   struct ssl_general_config general_ssl; /* general user defined SSL stuff */
   curl_proxytype proxytype; /* what kind of proxy that is in use */
-  curl_proxytype socks_proxytype; /* what kind of socks proxy that is in use */
   long dns_cache_timeout; /* DNS cache timeout */
   long buffer_size;      /* size of receive buffer to use */
   void *private_data; /* application-private data */
@@ -1748,12 +1766,16 @@ struct UserDefined {
   bool pipewait;        /* wait for pipe/multiplex status before starting a
                            new connection */
   long expect_100_timeout; /* in milliseconds */
+  bool suppress_connect_headers;  /* suppress proxy CONNECT response headers
+                                     from user callbacks */
 
   struct Curl_easy *stream_depends_on;
   bool stream_depends_e; /* set or don't set the Exclusive bit */
   int stream_weight;
 
   struct Curl_http2_dep *stream_dependents;
+
+  bool abstract_unix_socket;
 };
 
 struct Names {
diff --git a/lib/vauth/digest.c b/lib/vauth/digest.c
index 7d9200a..31d25cf 100644
--- a/lib/vauth/digest.c
+++ b/lib/vauth/digest.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
@@ -237,7 +237,7 @@ static CURLcode auth_digest_get_qop_values(const char *options, int *value)
  * auth_decode_digest_md5_message()
  *
  * This is used internally to decode an already encoded DIGEST-MD5 challenge
- * message into the seperate attributes.
+ * message into the separate attributes.
  *
  * Parameters:
  *
@@ -366,7 +366,7 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
   char qop[]        = DIGEST_QOP_VALUE_STRING_AUTH;
   char *spn         = NULL;
 
-  /* Decode the challange message */
+  /* Decode the challenge message */
   result = auth_decode_digest_md5_message(chlg64, nonce, sizeof(nonce),
                                           realm, sizeof(realm),
                                           algorithm, sizeof(algorithm),
@@ -502,7 +502,7 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
 /*
  * Curl_auth_decode_digest_http_message()
  *
- * This is used to decode a HTTP DIGEST challenge message into the seperate
+ * This is used to decode a HTTP DIGEST challenge message into the separate
  * attributes.
  *
  * Parameters:
diff --git a/lib/vauth/digest_sspi.c b/lib/vauth/digest_sspi.c
index b9ceb12..0bd9444 100644
--- a/lib/vauth/digest_sspi.c
+++ b/lib/vauth/digest_sspi.c
@@ -6,7 +6,7 @@
  *                             \___|\___/|_| \_\_____|
  *
  * Copyright (C) 2014 - 2016, Steve Holme, <steve_holme at hotmail.com>.
- * Copyright (C) 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 2015 - 2017, Daniel Stenberg, <daniel at 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
@@ -320,7 +320,7 @@ CURLcode Curl_override_sspi_http_realm(const char *chlg,
 /*
  * Curl_auth_decode_digest_http_message()
  *
- * This is used to decode a HTTP DIGEST challenge message into the seperate
+ * This is used to decode a HTTP DIGEST challenge message into the separate
  * attributes.
  *
  * Parameters:
@@ -335,13 +335,44 @@ CURLcode Curl_auth_decode_digest_http_message(const char *chlg,
 {
   size_t chlglen = strlen(chlg);
 
-  /* We had an input token before and we got another one now. This means we
-     provided bad credentials in the previous request. */
-  if(digest->input_token)
-    return CURLE_BAD_CONTENT_ENCODING;
+  /* We had an input token before so if there's another one now that means we
+     provided bad credentials in the previous request or it's stale. */
+  if(digest->input_token) {
+    bool stale = false;
+    const char *p = chlg;
+
+    /* Check for the 'stale' directive */
+    for(;;) {
+      char value[DIGEST_MAX_VALUE_LENGTH];
+      char content[DIGEST_MAX_CONTENT_LENGTH];
+
+      while(*p && ISSPACE(*p))
+        p++;
+
+      if(!Curl_auth_digest_get_pair(p, value, content, &p))
+        break;
+
+      if(Curl_strcasecompare(value, "stale")
+         && Curl_strcasecompare(content, "true")) {
+        stale = true;
+        break;
+      }
+
+      while(*p && ISSPACE(*p))
+        p++;
+
+      if(',' == *p)
+        p++;
+    }
+
+    if(stale)
+      Curl_auth_digest_cleanup(digest);
+    else
+      return CURLE_LOGIN_DENIED;
+  }
 
-  /* Simply store the challenge for use later */
-  digest->input_token = (BYTE *) Curl_memdup(chlg, chlglen);
+  /* Store the challenge for use later */
+  digest->input_token = (BYTE *) Curl_memdup(chlg, chlglen + 1);
   if(!digest->input_token)
     return CURLE_OUT_OF_MEMORY;
 
@@ -379,21 +410,13 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data,
                                               char **outptr, size_t *outlen)
 {
   size_t token_max;
-  CredHandle credentials;
-  CtxtHandle context;
   char *resp;
   BYTE *output_token;
+  size_t output_token_len = 0;
   PSecPkgInfo SecurityPackage;
-  SEC_WINNT_AUTH_IDENTITY identity;
-  SEC_WINNT_AUTH_IDENTITY *p_identity;
-  SecBuffer chlg_buf[3];
-  SecBuffer resp_buf;
+  SecBuffer chlg_buf[5];
   SecBufferDesc chlg_desc;
-  SecBufferDesc resp_desc;
   SECURITY_STATUS status;
-  unsigned long attrs;
-  TimeStamp expiry; /* For Windows 9x compatibility of SSPI calls */
-  TCHAR *spn;
 
   (void) data;
 
@@ -408,123 +431,168 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data,
   /* Release the package buffer as it is not required anymore */
   s_pSecFn->FreeContextBuffer(SecurityPackage);
 
-  if(userp && *userp) {
-    /* Populate our identity structure */
-    if(Curl_create_sspi_identity(userp, passwdp, &identity))
-      return CURLE_OUT_OF_MEMORY;
-
-    /* Populate our identity domain */
-    if(Curl_override_sspi_http_realm((const char *) digest->input_token,
-                                     &identity))
-      return CURLE_OUT_OF_MEMORY;
+  /* Allocate the output buffer according to the max token size as indicated
+     by the security package */
+  output_token = malloc(token_max);
+  if(!output_token) {
+    return CURLE_OUT_OF_MEMORY;
+  }
 
-    /* Allow proper cleanup of the identity structure */
-    p_identity = &identity;
+  if(digest->http_context) {
+    chlg_desc.ulVersion    = SECBUFFER_VERSION;
+    chlg_desc.cBuffers     = 5;
+    chlg_desc.pBuffers     = chlg_buf;
+    chlg_buf[0].BufferType = SECBUFFER_TOKEN;
+    chlg_buf[0].pvBuffer   = NULL;
+    chlg_buf[0].cbBuffer   = 0;
+    chlg_buf[1].BufferType = SECBUFFER_PKG_PARAMS;
+    chlg_buf[1].pvBuffer   = (void *) request;
+    chlg_buf[1].cbBuffer   = curlx_uztoul(strlen((const char *) request));
+    chlg_buf[2].BufferType = SECBUFFER_PKG_PARAMS;
+    chlg_buf[2].pvBuffer   = (void *) uripath;
+    chlg_buf[2].cbBuffer   = curlx_uztoul(strlen((const char *) uripath));
+    chlg_buf[3].BufferType = SECBUFFER_PKG_PARAMS;
+    chlg_buf[3].pvBuffer   = NULL;
+    chlg_buf[3].cbBuffer   = 0;
+    chlg_buf[4].BufferType = SECBUFFER_PADDING;
+    chlg_buf[4].pvBuffer   = output_token;
+    chlg_buf[4].cbBuffer   = curlx_uztoul(token_max);
+
+    status = s_pSecFn->MakeSignature(digest->http_context, 0, &chlg_desc, 0);
+    if(status == SEC_E_OK)
+      output_token_len = chlg_buf[4].cbBuffer;
+    else { /* delete the context so a new one can be made */
+      infof(data, "digest_sspi: MakeSignature failed, error 0x%08lx\n",
+            (long)status);
+      s_pSecFn->DeleteSecurityContext(digest->http_context);
+      Curl_safefree(digest->http_context);
+    }
   }
-  else
-    /* Use the current Windows user */
-    p_identity = NULL;
 
-  /* Acquire our credentials handle */
-  status = s_pSecFn->AcquireCredentialsHandle(NULL,
-                                              (TCHAR *) TEXT(SP_NAME_DIGEST),
-                                              SECPKG_CRED_OUTBOUND, NULL,
-                                              p_identity, NULL, NULL,
-                                              &credentials, &expiry);
-  if(status != SEC_E_OK) {
-    Curl_sspi_free_identity(p_identity);
+  if(!digest->http_context) {
+    CredHandle credentials;
+    SEC_WINNT_AUTH_IDENTITY identity;
+    SEC_WINNT_AUTH_IDENTITY *p_identity;
+    SecBuffer resp_buf;
+    SecBufferDesc resp_desc;
+    unsigned long attrs;
+    TimeStamp expiry; /* For Windows 9x compatibility of SSPI calls */
+    TCHAR *spn;
+
+    if(userp && *userp) {
+      /* Populate our identity structure */
+      if(Curl_create_sspi_identity(userp, passwdp, &identity)) {
+        free(output_token);
+        return CURLE_OUT_OF_MEMORY;
+      }
 
-    return CURLE_LOGIN_DENIED;
-  }
+      /* Populate our identity domain */
+      if(Curl_override_sspi_http_realm((const char *) digest->input_token,
+                                       &identity)) {
+        free(output_token);
+        return CURLE_OUT_OF_MEMORY;
+      }
 
-  /* Allocate the output buffer according to the max token size as indicated
-     by the security package */
-  output_token = malloc(token_max);
-  if(!output_token) {
-    s_pSecFn->FreeCredentialsHandle(&credentials);
+      /* Allow proper cleanup of the identity structure */
+      p_identity = &identity;
+    }
+    else
+      /* Use the current Windows user */
+      p_identity = NULL;
+
+    /* Acquire our credentials handle */
+    status = s_pSecFn->AcquireCredentialsHandle(NULL,
+                                                (TCHAR *) TEXT(SP_NAME_DIGEST),
+                                                SECPKG_CRED_OUTBOUND, NULL,
+                                                p_identity, NULL, NULL,
+                                                &credentials, &expiry);
+    if(status != SEC_E_OK) {
+      Curl_sspi_free_identity(p_identity);
+      free(output_token);
 
-    Curl_sspi_free_identity(p_identity);
+      return CURLE_LOGIN_DENIED;
+    }
 
-    return CURLE_OUT_OF_MEMORY;
-  }
+    /* Setup the challenge "input" security buffer if present */
+    chlg_desc.ulVersion    = SECBUFFER_VERSION;
+    chlg_desc.cBuffers     = 3;
+    chlg_desc.pBuffers     = chlg_buf;
+    chlg_buf[0].BufferType = SECBUFFER_TOKEN;
+    chlg_buf[0].pvBuffer   = digest->input_token;
+    chlg_buf[0].cbBuffer   = curlx_uztoul(digest->input_token_len);
+    chlg_buf[1].BufferType = SECBUFFER_PKG_PARAMS;
+    chlg_buf[1].pvBuffer   = (void *) request;
+    chlg_buf[1].cbBuffer   = curlx_uztoul(strlen((const char *) request));
+    chlg_buf[2].BufferType = SECBUFFER_PKG_PARAMS;
+    chlg_buf[2].pvBuffer   = NULL;
+    chlg_buf[2].cbBuffer   = 0;
+
+    /* Setup the response "output" security buffer */
+    resp_desc.ulVersion = SECBUFFER_VERSION;
+    resp_desc.cBuffers  = 1;
+    resp_desc.pBuffers  = &resp_buf;
+    resp_buf.BufferType = SECBUFFER_TOKEN;
+    resp_buf.pvBuffer   = output_token;
+    resp_buf.cbBuffer   = curlx_uztoul(token_max);
+
+    spn = Curl_convert_UTF8_to_tchar((char *) uripath);
+    if(!spn) {
+      s_pSecFn->FreeCredentialsHandle(&credentials);
+
+      Curl_sspi_free_identity(p_identity);
+      free(output_token);
 
-  /* Setup the challenge "input" security buffer if present */
-  chlg_desc.ulVersion    = SECBUFFER_VERSION;
-  chlg_desc.cBuffers     = 3;
-  chlg_desc.pBuffers     = chlg_buf;
-  chlg_buf[0].BufferType = SECBUFFER_TOKEN;
-  chlg_buf[0].pvBuffer   = digest->input_token;
-  chlg_buf[0].cbBuffer   = curlx_uztoul(digest->input_token_len);
-  chlg_buf[1].BufferType = SECBUFFER_PKG_PARAMS;
-  chlg_buf[1].pvBuffer   = (void *) request;
-  chlg_buf[1].cbBuffer   = curlx_uztoul(strlen((const char *) request));
-  chlg_buf[2].BufferType = SECBUFFER_PKG_PARAMS;
-  chlg_buf[2].pvBuffer   = NULL;
-  chlg_buf[2].cbBuffer   = 0;
+      return CURLE_OUT_OF_MEMORY;
+    }
 
-  /* Setup the response "output" security buffer */
-  resp_desc.ulVersion = SECBUFFER_VERSION;
-  resp_desc.cBuffers  = 1;
-  resp_desc.pBuffers  = &resp_buf;
-  resp_buf.BufferType = SECBUFFER_TOKEN;
-  resp_buf.pvBuffer   = output_token;
-  resp_buf.cbBuffer   = curlx_uztoul(token_max);
+    /* Allocate our new context handle */
+    digest->http_context = calloc(1, sizeof(CtxtHandle));
+    if(!digest->http_context)
+      return CURLE_OUT_OF_MEMORY;
 
-  spn = Curl_convert_UTF8_to_tchar((char *) uripath);
-  if(!spn) {
-    s_pSecFn->FreeCredentialsHandle(&credentials);
+    /* Generate our response message */
+    status = s_pSecFn->InitializeSecurityContext(&credentials, NULL,
+                                                 spn,
+                                                 ISC_REQ_USE_HTTP_STYLE, 0, 0,
+                                                 &chlg_desc, 0,
+                                                 digest->http_context,
+                                                 &resp_desc, &attrs, &expiry);
+    Curl_unicodefree(spn);
+
+    if(status == SEC_I_COMPLETE_NEEDED ||
+       status == SEC_I_COMPLETE_AND_CONTINUE)
+      s_pSecFn->CompleteAuthToken(&credentials, &resp_desc);
+    else if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) {
+      s_pSecFn->FreeCredentialsHandle(&credentials);
+
+      Curl_sspi_free_identity(p_identity);
+      free(output_token);
 
-    Curl_sspi_free_identity(p_identity);
-    free(output_token);
+      Curl_safefree(digest->http_context);
 
-    return CURLE_OUT_OF_MEMORY;
-  }
+      return CURLE_OUT_OF_MEMORY;
+    }
 
-  /* Generate our reponse message */
-  status = s_pSecFn->InitializeSecurityContext(&credentials, NULL,
-                                               spn,
-                                               ISC_REQ_USE_HTTP_STYLE, 0, 0,
-                                               &chlg_desc, 0, &context,
-                                               &resp_desc, &attrs, &expiry);
-  Curl_unicodefree(spn);
+    output_token_len = resp_buf.cbBuffer;
 
-  if(status == SEC_I_COMPLETE_NEEDED ||
-     status == SEC_I_COMPLETE_AND_CONTINUE)
-    s_pSecFn->CompleteAuthToken(&credentials, &resp_desc);
-  else if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) {
     s_pSecFn->FreeCredentialsHandle(&credentials);
-
     Curl_sspi_free_identity(p_identity);
-    free(output_token);
-
-    return CURLE_OUT_OF_MEMORY;
   }
 
-  resp = malloc(resp_buf.cbBuffer + 1);
+  resp = malloc(output_token_len + 1);
   if(!resp) {
-    s_pSecFn->DeleteSecurityContext(&context);
-    s_pSecFn->FreeCredentialsHandle(&credentials);
-
-    Curl_sspi_free_identity(p_identity);
     free(output_token);
 
     return CURLE_OUT_OF_MEMORY;
   }
 
-  /* Copy the generated reponse */
-  memcpy(resp, resp_buf.pvBuffer, resp_buf.cbBuffer);
-  resp[resp_buf.cbBuffer] = 0x00;
+  /* Copy the generated response */
+  memcpy(resp, output_token, output_token_len);
+  resp[output_token_len] = 0;
 
   /* Return the response */
   *outptr = resp;
-  *outlen = resp_buf.cbBuffer;
-
-  /* Free our handles */
-  s_pSecFn->DeleteSecurityContext(&context);
-  s_pSecFn->FreeCredentialsHandle(&credentials);
-
-  /* Free the identity structure */
-  Curl_sspi_free_identity(p_identity);
+  *outlen = output_token_len;
 
   /* Free the response buffer */
   free(output_token);
@@ -549,6 +617,12 @@ void Curl_auth_digest_cleanup(struct digestdata *digest)
 
   /* Reset any variables */
   digest->input_token_len = 0;
+
+  /* Delete security context */
+  if(digest->http_context) {
+    s_pSecFn->DeleteSecurityContext(digest->http_context);
+    Curl_safefree(digest->http_context);
+  }
 }
 
 #endif /* USE_WINDOWS_SSPI && !CURL_DISABLE_CRYPTO_AUTH */
diff --git a/lib/vauth/krb5_gssapi.c b/lib/vauth/krb5_gssapi.c
index c754fae..560ecc5 100644
--- a/lib/vauth/krb5_gssapi.c
+++ b/lib/vauth/krb5_gssapi.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2014 - 2016, Steve Holme, <steve_holme at hotmail.com>.
+ * Copyright (C) 2014 - 2017, Steve Holme, <steve_holme at hotmail.com>.
  * Copyright (C) 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
@@ -68,7 +68,7 @@ bool Curl_auth_is_gssapi_supported(void)
  * passdwp     [in]     - The user's password.
  * service     [in]     - The service type such as http, smtp, pop or imap.
  * host        [in[     - The host name.
- * mutual_auth [in]     - Flag specifing whether or not mutual authentication
+ * mutual_auth [in]     - Flag specifying whether or not mutual authentication
  *                        is enabled.
  * chlg64      [in]     - Pointer to the optional base64 encoded challenge
  *                        message.
diff --git a/lib/vauth/krb5_sspi.c b/lib/vauth/krb5_sspi.c
index 151794e..1b4cef4 100644
--- a/lib/vauth/krb5_sspi.c
+++ b/lib/vauth/krb5_sspi.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2014 - 2016, Steve Holme, <steve_holme at hotmail.com>.
+ * Copyright (C) 2014 - 2017, Steve Holme, <steve_holme at hotmail.com>.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -74,7 +74,7 @@ bool Curl_auth_is_gssapi_supported(void)
  * passdwp     [in]     - The user's password.
  * service     [in]     - The service type such as http, smtp, pop or imap.
  * host        [in]     - The host name.
- * mutual_auth [in]     - Flag specifing whether or not mutual authentication
+ * mutual_auth [in]     - Flag specifying whether or not mutual authentication
  *                        is enabled.
  * chlg64      [in]     - The optional base64 encoded challenge message.
  * krb5        [in/out] - The Kerberos 5 data struct being used and modified.
diff --git a/lib/vauth/ntlm.c b/lib/vauth/ntlm.c
index b4d345d..d02eec4 100644
--- a/lib/vauth/ntlm.c
+++ b/lib/vauth/ntlm.c
@@ -27,7 +27,7 @@
 /*
  * NTLM details:
  *
- * http://davenport.sourceforge.net/ntlm.html
+ * https://davenport.sourceforge.io/ntlm.html
  * https://www.innovation.ch/java/ntlm.html
  */
 
@@ -394,7 +394,7 @@ CURLcode Curl_auth_create_ntlm_type1_message(const char *userp,
   /* Clean up any former leftovers and initialise to defaults */
   Curl_auth_ntlm_cleanup(ntlm);
 
-#if USE_NTRESPONSES && USE_NTLM2SESSION
+#if defined(USE_NTRESPONSES) && defined(USE_NTLM2SESSION)
 #define NTLM2FLAG NTLMFLAG_NEGOTIATE_NTLM2_KEY
 #else
 #define NTLM2FLAG 0
@@ -509,7 +509,7 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
   unsigned char ntlmbuf[NTLM_BUFSIZE];
   int lmrespoff;
   unsigned char lmresp[24]; /* fixed-size */
-#if USE_NTRESPONSES
+#ifdef USE_NTRESPONSES
   int ntrespoff;
   unsigned int ntresplen = 24;
   unsigned char ntresp[24]; /* fixed-size */
@@ -552,7 +552,7 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
     hostlen = strlen(host);
   }
 
-#if USE_NTRESPONSES && USE_NTLM_V2
+#if defined(USE_NTRESPONSES) && defined(USE_NTLM_V2)
   if(ntlm->target_info_len) {
     unsigned char ntbuffer[0x18];
     unsigned int entropy[2];
@@ -590,7 +590,7 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
   else
 #endif
 
-#if USE_NTRESPONSES && USE_NTLM2SESSION
+#if defined(USE_NTRESPONSES) && defined(USE_NTLM2SESSION)
   /* We don't support NTLM2 if we don't have USE_NTRESPONSES */
   if(ntlm->flags & NTLMFLAG_NEGOTIATE_NTLM2_KEY) {
     unsigned char ntbuffer[0x18];
@@ -630,12 +630,12 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
 #endif
   {
 
-#if USE_NTRESPONSES
+#ifdef USE_NTRESPONSES
     unsigned char ntbuffer[0x18];
 #endif
     unsigned char lmbuffer[0x18];
 
-#if USE_NTRESPONSES
+#ifdef USE_NTRESPONSES
     result = Curl_ntlm_core_mk_nt_hash(data, passwdp, ntbuffer);
     if(result)
       return result;
@@ -651,7 +651,7 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
 
     /* A safer but less compatible alternative is:
      *   Curl_ntlm_core_lm_resp(ntbuffer, &ntlm->nonce[0], lmresp);
-     * See http://davenport.sourceforge.net/ntlm.html#ntlmVersion2 */
+     * See https://davenport.sourceforge.io/ntlm.html#ntlmVersion2 */
   }
 
   if(unicode) {
@@ -661,7 +661,7 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
   }
 
   lmrespoff = 64; /* size of the message header */
-#if USE_NTRESPONSES
+#ifdef USE_NTRESPONSES
   ntrespoff = lmrespoff + 0x18;
   domoff = ntrespoff + ntresplen;
 #else
@@ -721,7 +721,7 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
                   SHORTPAIR(lmrespoff),
                   0x0, 0x0,
 
-#if USE_NTRESPONSES
+#ifdef USE_NTRESPONSES
                   SHORTPAIR(ntresplen),  /* NT-response length, twice */
                   SHORTPAIR(ntresplen),
                   SHORTPAIR(ntrespoff),
@@ -768,7 +768,7 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
     ntlm_print_hex(stderr, (char *)&ntlmbuf[lmrespoff], 0x18);
   });
 
-#if USE_NTRESPONSES
+#ifdef USE_NTRESPONSES
   if(size < (NTLM_BUFSIZE - ntresplen)) {
     DEBUGASSERT(size == (size_t)ntrespoff);
     memcpy(&ntlmbuf[size], ptr_ntresp, ntresplen);
diff --git a/lib/vauth/ntlm.h b/lib/vauth/ntlm.h
index b14e7a5..f906a3c 100644
--- a/lib/vauth/ntlm.h
+++ b/lib/vauth/ntlm.h
@@ -32,7 +32,7 @@
 /* Stuff only required for curl_ntlm_msgs.c */
 #ifdef BUILDING_CURL_NTLM_MSGS_C
 
-/* Flag bits definitions based on http://davenport.sourceforge.net/ntlm.html */
+/* Flag bits definitions based on https://davenport.sourceforge.io/ntlm.html */
 
 #define NTLMFLAG_NEGOTIATE_UNICODE               (1<<0)
 /* Indicates that Unicode strings are supported for use in security buffer
diff --git a/lib/vauth/spnego_sspi.c b/lib/vauth/spnego_sspi.c
index 5fa95e2..a6797cd 100644
--- a/lib/vauth/spnego_sspi.c
+++ b/lib/vauth/spnego_sspi.c
@@ -34,6 +34,7 @@
 #include "warnless.h"
 #include "curl_multibyte.h"
 #include "sendf.h"
+#include "strerror.h"
 
 /* The last #include files should be: */
 #include "curl_memory.h"
@@ -224,6 +225,8 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data,
   free(chlg);
 
   if(GSS_ERROR(nego->status)) {
+    failf(data, "InitializeSecurityContext failed: %s",
+          Curl_sspi_strerror(data->easy_conn, nego->status));
     return CURLE_OUT_OF_MEMORY;
   }
 
diff --git a/lib/vtls/axtls.c b/lib/vtls/axtls.c
index ff4634e..f0e3766 100644
--- a/lib/vtls/axtls.c
+++ b/lib/vtls/axtls.c
@@ -6,7 +6,7 @@
  *                             \___|\___/|_| \_\_____|
  *
  * Copyright (C) 2010, DirecTV, Contact: Eric Hu, <ehu at directv.com>.
- * Copyright (C) 2010 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 2010 - 2017, Daniel Stenberg, <daniel at 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
@@ -156,6 +156,12 @@ static CURLcode connect_prep(struct connectdata *conn, int sockindex)
        same connection */
     return CURLE_OK;
 
+  if(SSL_CONN_CONFIG(version_max) != CURL_SSLVERSION_MAX_NONE) {
+    failf(data, "axtls does not support CURL_SSLVERSION_MAX");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+
   /* axTLS only supports TLSv1 */
   /* check to see if we've been told to use an explicit SSL/TLS version */
   switch(SSL_CONN_CONFIG(version)) {
@@ -256,7 +262,7 @@ static CURLcode connect_prep(struct connectdata *conn, int sockindex)
    * 2) setting up callbacks.  these seem gnutls specific
    */
 
-  if(data->set.general_ssl.sessionid) {
+  if(SSL_SET_OPTION(primary.sessionid)) {
     const uint8_t *ssl_sessionid;
     size_t ssl_idsize;
 
@@ -267,13 +273,13 @@ static CURLcode connect_prep(struct connectdata *conn, int sockindex)
       /* we got a session id, use it! */
       infof(data, "SSL re-using session ID\n");
       ssl = ssl_client_new(ssl_ctx, conn->sock[sockindex],
-                           ssl_sessionid, (uint8_t)ssl_idsize);
+                           ssl_sessionid, (uint8_t)ssl_idsize, NULL);
     }
     Curl_ssl_sessionid_unlock(conn);
   }
 
   if(!ssl)
-    ssl = ssl_client_new(ssl_ctx, conn->sock[sockindex], NULL, 0);
+    ssl = ssl_client_new(ssl_ctx, conn->sock[sockindex], NULL, 0, NULL);
 
   conn->ssl[sockindex].ssl = ssl;
   return CURLE_OK;
@@ -386,9 +392,9 @@ static CURLcode connect_finish(struct connectdata *conn, int sockindex)
   conn->send[sockindex] = axtls_send;
 
   /* Put our freshly minted SSL session in cache */
-  if(data->set.general_ssl.sessionid) {
-    const uint8_t *ssl_sessionid = ssl_get_session_id_size(ssl);
-    size_t ssl_idsize = ssl_get_session_id(ssl);
+  if(SSL_SET_OPTION(primary.sessionid)) {
+    const uint8_t *ssl_sessionid = ssl_get_session_id(ssl);
+    size_t ssl_idsize = ssl_get_session_id_size(ssl);
     Curl_ssl_sessionid_lock(conn);
     if(Curl_ssl_addsessionid(conn, (void *) ssl_sessionid, ssl_idsize,
                              sockindex) != CURLE_OK)
@@ -680,9 +686,9 @@ size_t Curl_axtls_version(char *buffer, size_t size)
   return snprintf(buffer, size, "axTLS/%s", ssl_version());
 }
 
-int Curl_axtls_random(struct Curl_easy *data,
-                      unsigned char *entropy,
-                      size_t length)
+CURLcode Curl_axtls_random(struct Curl_easy *data,
+                           unsigned char *entropy,
+                           size_t length)
 {
   static bool ssl_seeded = FALSE;
   (void)data;
@@ -694,7 +700,7 @@ int Curl_axtls_random(struct Curl_easy *data,
     RNG_initialize();
   }
   get_random((int)length, entropy);
-  return 0;
+  return CURLE_OK;
 }
 
 #endif /* USE_AXTLS */
diff --git a/lib/vtls/axtls.h b/lib/vtls/axtls.h
index b16d051..53797ea 100644
--- a/lib/vtls/axtls.h
+++ b/lib/vtls/axtls.h
@@ -8,7 +8,7 @@
  *                             \___|\___/|_| \_\_____|
  *
  * Copyright (C) 2010, DirecTV, Contact: Eric Hu <ehu at directv.com>
- * Copyright (C) 2010 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 2010 - 2017, Daniel Stenberg, <daniel at 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
@@ -42,9 +42,9 @@ void Curl_axtls_session_free(void *ptr);
 size_t Curl_axtls_version(char *buffer, size_t size);
 int Curl_axtls_shutdown(struct connectdata *conn, int sockindex);
 int Curl_axtls_check_cxn(struct connectdata *conn);
-int Curl_axtls_random(struct Curl_easy *data,
-                      unsigned char *entropy,
-                      size_t length);
+CURLcode Curl_axtls_random(struct Curl_easy *data,
+                           unsigned char *entropy,
+                           size_t length);
 
 /* Set the API backend definition to axTLS */
 #define CURL_SSL_BACKEND CURLSSLBACKEND_AXTLS
diff --git a/lib/vtls/cyassl.c b/lib/vtls/cyassl.c
index fc4dde4..5f51ad5 100644
--- a/lib/vtls/cyassl.c
+++ b/lib/vtls/cyassl.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
@@ -134,6 +134,7 @@ cyassl_connect_step1(struct connectdata *conn,
                      int sockindex)
 {
   char error_buffer[CYASSL_MAX_ERROR_SZ];
+  char *ciphers;
   struct Curl_easy *data = conn->data;
   struct ssl_connect_data* conssl = &conn->ssl[sockindex];
   SSL_METHOD* req_method = NULL;
@@ -148,6 +149,11 @@ cyassl_connect_step1(struct connectdata *conn,
   if(conssl->state == ssl_connection_complete)
     return CURLE_OK;
 
+  if(SSL_CONN_CONFIG(version_max) != CURL_SSLVERSION_MAX_NONE) {
+    failf(data, "CyaSSL does not support to set maximum SSL/TLS version");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
   /* check to see if we've been told to use an explicit SSL/TLS version */
   switch(SSL_CONN_CONFIG(version)) {
   case CURL_SSLVERSION_DEFAULT:
@@ -229,6 +235,15 @@ cyassl_connect_step1(struct connectdata *conn,
     break;
   }
 
+  ciphers = SSL_CONN_CONFIG(cipher_list);
+  if(ciphers) {
+    if(!SSL_CTX_set_cipher_list(conssl->ctx, ciphers)) {
+      failf(data, "failed setting cipher list: %s", ciphers);
+      return CURLE_SSL_CIPHER;
+    }
+    infof(data, "Cipher selection: %s\n", ciphers);
+  }
+
 #ifndef NO_FILESYSTEM
   /* load trusted cacert */
   if(SSL_CONN_CONFIG(CAfile)) {
@@ -383,7 +398,7 @@ cyassl_connect_step1(struct connectdata *conn,
 #endif /* HAVE_ALPN */
 
   /* Check if there's a cached ID we can/should use here! */
-  if(data->set.general_ssl.sessionid) {
+  if(SSL_SET_OPTION(primary.sessionid)) {
     void *ssl_sessionid = NULL;
 
     Curl_ssl_sessionid_lock(conn);
@@ -581,7 +596,13 @@ cyassl_connect_step2(struct connectdata *conn,
 #endif /* HAVE_ALPN */
 
   conssl->connecting_state = ssl_connect_3;
+#if (LIBCYASSL_VERSION_HEX >= 0x03009010)
+  infof(data, "SSL connection using %s / %s\n",
+        wolfSSL_get_version(conssl->handle),
+        wolfSSL_get_cipher_name(conssl->handle));
+#else
   infof(data, "SSL connected\n");
+#endif
 
   return CURLE_OK;
 }
@@ -597,7 +618,7 @@ cyassl_connect_step3(struct connectdata *conn,
 
   DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
 
-  if(data->set.general_ssl.sessionid) {
+  if(SSL_SET_OPTION(primary.sessionid)) {
     bool incache;
     SSL_SESSION *our_ssl_sessionid;
     void *old_ssl_sessionid = NULL;
@@ -720,7 +741,9 @@ void Curl_cyassl_session_free(void *ptr)
 
 size_t Curl_cyassl_version(char *buffer, size_t size)
 {
-#ifdef WOLFSSL_VERSION
+#if LIBCYASSL_VERSION_HEX >= 0x03006000
+  return snprintf(buffer, size, "wolfSSL/%s", wolfSSL_lib_version());
+#elif defined(WOLFSSL_VERSION)
   return snprintf(buffer, size, "wolfSSL/%s", WOLFSSL_VERSION);
 #elif defined(CYASSL_VERSION)
   return snprintf(buffer, size, "CyaSSL/%s", CYASSL_VERSION);
@@ -772,7 +795,7 @@ cyassl_connect_common(struct connectdata *conn,
   struct Curl_easy *data = conn->data;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
   curl_socket_t sockfd = conn->sock[sockindex];
-  long timeout_ms;
+  time_t timeout_ms;
   int what;
 
   /* check if the connection has already been established */
@@ -901,19 +924,19 @@ Curl_cyassl_connect(struct connectdata *conn,
   return CURLE_OK;
 }
 
-int Curl_cyassl_random(struct Curl_easy *data,
-                       unsigned char *entropy,
-                       size_t length)
+CURLcode Curl_cyassl_random(struct Curl_easy *data,
+                            unsigned char *entropy,
+                            size_t length)
 {
   RNG rng;
   (void)data;
   if(InitRng(&rng))
-    return 1;
+    return CURLE_FAILED_INIT;
   if(length > UINT_MAX)
-    return 1;
+    return CURLE_FAILED_INIT;
   if(RNG_GenerateBlock(&rng, entropy, (unsigned)length))
-    return 1;
-  return 0;
+    return CURLE_FAILED_INIT;
+  return CURLE_OK;
 }
 
 void Curl_cyassl_sha256sum(const unsigned char *tmp, /* input */
diff --git a/lib/vtls/cyassl.h b/lib/vtls/cyassl.h
index 508dfaa..f47719e 100644
--- a/lib/vtls/cyassl.h
+++ b/lib/vtls/cyassl.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
@@ -51,15 +51,15 @@ int Curl_cyassl_init(void);
 CURLcode Curl_cyassl_connect_nonblocking(struct connectdata *conn,
                                          int sockindex,
                                          bool *done);
-int Curl_cyassl_random(struct Curl_easy *data,
-                       unsigned char *entropy,
-                       size_t length);
+CURLcode Curl_cyassl_random(struct Curl_easy *data,
+                            unsigned char *entropy,
+                            size_t length);
 void Curl_cyassl_sha256sum(const unsigned char *tmp, /* input */
                      size_t tmplen,
                      unsigned char *sha256sum, /* output */
                      size_t unused);
 
-/* Set the API backend definition to Schannel */
+/* Set the API backend definition to CyaSSL */
 #define CURL_SSL_BACKEND CURLSSLBACKEND_CYASSL
 
 /* this backend supports CURLOPT_SSL_CTX_* */
diff --git a/lib/vtls/darwinssl.c b/lib/vtls/darwinssl.c
index a43e391..5533dfe 100644
--- a/lib/vtls/darwinssl.c
+++ b/lib/vtls/darwinssl.c
@@ -6,7 +6,7 @@
  *                             \___|\___/|_| \_\_____|
  *
  * Copyright (C) 2012 - 2014, Nick Zitzmann, <nickzman at gmail.com>.
- * Copyright (C) 2012 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 2012 - 2017, Daniel Stenberg, <daniel at 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
@@ -219,6 +219,7 @@ static OSStatus SocketWrite(SSLConnectionRef connection,
   return ortn;
 }
 
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
 CF_INLINE const char *SSLCipherNameForNumber(SSLCipherSuite cipher)
 {
   switch(cipher) {
@@ -776,6 +777,7 @@ CF_INLINE const char *TLSCipherNameForNumber(SSLCipherSuite cipher)
   }
   return "TLS_NULL_WITH_NULL_NULL";
 }
+#endif /* !CURL_DISABLE_VERBOSE_STRINGS */
 
 #if CURL_BUILD_MAC
 CF_INLINE void GetDarwinVersionNumber(int *major, int *minor)
@@ -885,12 +887,13 @@ static OSStatus CopyIdentityWithLabel(char *label,
                                       SecIdentityRef *out_cert_and_key)
 {
   OSStatus status = errSecItemNotFound;
+
+#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
   CFArrayRef keys_list;
   CFIndex keys_list_count;
   CFIndex i;
   CFStringRef common_name;
 
-#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
   /* SecItemCopyMatching() was introduced in iOS and Snow Leopard.
      kSecClassIdentity was introduced in Lion. If both exist, let's use them
      to find the certificate. */
@@ -929,28 +932,35 @@ static OSStatus CopyIdentityWithLabel(char *label,
     if(status == noErr) {
       keys_list_count = CFArrayGetCount(keys_list);
       *out_cert_and_key = NULL;
+      status = 1;
       for(i=0; i<keys_list_count; i++) {
         OSStatus err = noErr;
         SecCertificateRef cert = NULL;
-        *out_cert_and_key =
+        SecIdentityRef identity =
           (SecIdentityRef) CFArrayGetValueAtIndex(keys_list, i);
-        err = SecIdentityCopyCertificate(*out_cert_and_key, &cert);
+        err = SecIdentityCopyCertificate(identity, &cert);
         if(err == noErr) {
+#if CURL_BUILD_IOS
+          common_name = SecCertificateCopySubjectSummary(cert);
+#elif CURL_BUILD_MAC_10_7
           SecCertificateCopyCommonName(cert, &common_name);
+#endif
           if(CFStringCompare(common_name, label_cf, 0) == kCFCompareEqualTo) {
             CFRelease(cert);
             CFRelease(common_name);
+            CFRetain(identity);
+            *out_cert_and_key = identity;
             status = noErr;
             break;
           }
           CFRelease(common_name);
         }
-        *out_cert_and_key = NULL;
-        status = 1;
         CFRelease(cert);
       }
     }
 
+    if(keys_list)
+      CFRelease(keys_list);
     CFRelease(query_dict);
     CFRelease(label_cf);
   }
@@ -1034,6 +1044,109 @@ CF_INLINE bool is_file(const char *filename)
   return false;
 }
 
+#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
+static CURLcode darwinssl_version_from_curl(long *darwinver, long ssl_version)
+{
+  switch(ssl_version) {
+    case CURL_SSLVERSION_TLSv1_0:
+      *darwinver = kTLSProtocol1;
+      return CURLE_OK;
+    case CURL_SSLVERSION_TLSv1_1:
+      *darwinver = kTLSProtocol11;
+      return CURLE_OK;
+    case CURL_SSLVERSION_TLSv1_2:
+      *darwinver = kTLSProtocol12;
+      return CURLE_OK;
+    case CURL_SSLVERSION_TLSv1_3:
+      break;
+  }
+  return CURLE_SSL_CONNECT_ERROR;
+}
+#endif
+
+static CURLcode
+set_ssl_version_min_max(struct connectdata *conn, int sockindex)
+{
+  struct Curl_easy *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  long ssl_version = SSL_CONN_CONFIG(version);
+  long ssl_version_max = SSL_CONN_CONFIG(version_max);
+
+  switch(ssl_version) {
+    case CURL_SSLVERSION_DEFAULT:
+    case CURL_SSLVERSION_TLSv1:
+      ssl_version = CURL_SSLVERSION_TLSv1_0;
+      ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2;
+      break;
+  }
+
+  switch(ssl_version_max) {
+    case CURL_SSLVERSION_MAX_NONE:
+      ssl_version_max = ssl_version << 16;
+      break;
+    case CURL_SSLVERSION_MAX_DEFAULT:
+      ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2;
+      break;
+  }
+
+#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
+  if(SSLSetProtocolVersionMax != NULL) {
+    SSLProtocol darwin_ver_min = kTLSProtocol1;
+    SSLProtocol darwin_ver_max = kTLSProtocol1;
+    CURLcode result = darwinssl_version_from_curl(&darwin_ver_min,
+                                                  ssl_version);
+    if(result) {
+      failf(data, "unsupported min version passed via CURLOPT_SSLVERSION");
+      return result;
+    }
+    result = darwinssl_version_from_curl(&darwin_ver_max,
+                                         ssl_version_max >> 16);
+    if(result) {
+      failf(data, "unsupported max version passed via CURLOPT_SSLVERSION");
+      return result;
+    }
+
+    (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, darwin_ver_min);
+    (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, darwin_ver_max);
+    return result;
+  }
+  else {
+#if CURL_SUPPORT_MAC_10_8
+    long i = ssl_version;
+    (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+                                       kSSLProtocolAll,
+                                       false);
+    for(; i <= (ssl_version_max >> 16); i++) {
+      switch(i) {
+        case CURL_SSLVERSION_TLSv1_0:
+          (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+                                            kTLSProtocol1,
+                                            true);
+          break;
+        case CURL_SSLVERSION_TLSv1_1:
+          (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+                                            kTLSProtocol11,
+                                            true);
+          break;
+        case CURL_SSLVERSION_TLSv1_2:
+          (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+                                            kTLSProtocol12,
+                                            true);
+          break;
+        case CURL_SSLVERSION_TLSv1_3:
+          failf(data, "DarwinSSL: TLS 1.3 is not yet supported");
+          return CURLE_SSL_CONNECT_ERROR;
+      }
+    }
+    return CURLE_OK;
+#endif  /* CURL_SUPPORT_MAC_10_8 */
+  }
+#endif  /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
+  failf(data, "DarwinSSL: cannot set SSL protocol");
+  return CURLE_SSL_CONNECT_ERROR;
+}
+
+
 static CURLcode darwinssl_connect_step1(struct connectdata *conn,
                                         int sockindex)
 {
@@ -1103,20 +1216,15 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
       (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
       break;
     case CURL_SSLVERSION_TLSv1_0:
-      (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1);
-      (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol1);
-      break;
     case CURL_SSLVERSION_TLSv1_1:
-      (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol11);
-      (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol11);
-      break;
     case CURL_SSLVERSION_TLSv1_2:
-      (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol12);
-      (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
-      break;
     case CURL_SSLVERSION_TLSv1_3:
-      failf(data, "DarwinSSL: TLS 1.3 is not yet supported");
-      return CURLE_SSL_CONNECT_ERROR;
+      {
+        CURLcode result = set_ssl_version_min_max(conn, sockindex);
+        if(result != CURLE_OK)
+          return result;
+        break;
+      }
     case CURL_SSLVERSION_SSLv3:
       err = SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol3);
       if(err != noErr) {
@@ -1157,23 +1265,15 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
                                          true);
       break;
     case CURL_SSLVERSION_TLSv1_0:
-      (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
-                                         kTLSProtocol1,
-                                         true);
-      break;
     case CURL_SSLVERSION_TLSv1_1:
-      (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
-                                         kTLSProtocol11,
-                                         true);
-      break;
     case CURL_SSLVERSION_TLSv1_2:
-      (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
-                                         kTLSProtocol12,
-                                         true);
-      break;
     case CURL_SSLVERSION_TLSv1_3:
-      failf(data, "DarwinSSL: TLS 1.3 is not yet supported");
-      return CURLE_SSL_CONNECT_ERROR;
+      {
+        CURLcode result = set_ssl_version_min_max(conn, sockindex);
+        if(result != CURLE_OK)
+          return result;
+        break;
+      }
     case CURL_SSLVERSION_SSLv3:
       err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
                                          kSSLProtocol3,
@@ -1199,6 +1299,11 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
 #endif  /* CURL_SUPPORT_MAC_10_8 */
   }
 #else
+  if(conn->ssl_config.version_max != CURL_SSLVERSION_MAX_NONE) {
+    failf(data, "Your version of the OS does not support to set maximum"
+                " SSL/TLS version");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
   (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, kSSLProtocolAll, false);
   switch(conn->ssl_config.version) {
   case CURL_SSLVERSION_DEFAULT:
@@ -1385,18 +1490,13 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
   }
 #endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
 
-  if(ssl_cafile) {
+  if(ssl_cafile && verifypeer) {
     bool is_cert_file = is_file(ssl_cafile);
 
     if(!is_cert_file) {
       failf(data, "SSL: can't load CA certificate file %s", ssl_cafile);
       return CURLE_SSL_CACERT_BADFILE;
     }
-    if(!verifypeer) {
-      failf(data, "SSL: CA certificate set, but certificate verification "
-            "is disabled");
-      return CURLE_SSL_CONNECT_ERROR;
-    }
   }
 
   /* Configure hostname check. SNI is used if available.
@@ -1420,6 +1520,9 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
             "the OS.\n");
     }
   }
+  else {
+    infof(data, "WARNING: disabling hostname validation also disables SNI.\n");
+  }
 
   /* Disable cipher suites that ST supports but are not safe. These ciphers
      are unlikely to be used in any case since ST gives other ciphers a much
@@ -1541,7 +1644,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
 #endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
 
   /* Check if there's a cached ID we can/should use here! */
-  if(data->set.general_ssl.sessionid) {
+  if(SSL_SET_OPTION(primary.sessionid)) {
     char *ssl_sessionid;
     size_t ssl_sessionid_len;
 
@@ -1921,7 +2024,7 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex)
       /* The below is errSSLServerAuthCompleted; it's not defined in
         Leopard's headers */
       case -9841:
-        if(SSL_CONN_CONFIG(CAfile)) {
+        if(SSL_CONN_CONFIG(CAfile) && SSL_CONN_CONFIG(verifypeer)) {
           int res = verify_cert(SSL_CONN_CONFIG(CAfile), data,
                                 connssl->ssl_ctx);
           if(res != CURLE_OK)
@@ -2034,9 +2137,11 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex)
   }
 }
 
-static CURLcode
-darwinssl_connect_step3(struct connectdata *conn,
-                        int sockindex)
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+/* This should be called during step3 of the connection at the earliest */
+static void
+show_verbose_server_cert(struct connectdata *conn,
+                         int sockindex)
 {
   struct Curl_easy *data = conn->data;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
@@ -2048,9 +2153,9 @@ darwinssl_connect_step3(struct connectdata *conn,
   CFIndex i, count;
   SecTrustRef trust = NULL;
 
-  /* There is no step 3!
-   * Well, okay, if verbose mode is on, let's print the details of the
-   * server certificates. */
+  if(!connssl->ssl_ctx)
+    return;
+
 #if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
 #if CURL_BUILD_IOS
 #pragma unused(server_certs)
@@ -2147,6 +2252,23 @@ darwinssl_connect_step3(struct connectdata *conn,
     CFRelease(server_certs);
   }
 #endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
+}
+#endif /* !CURL_DISABLE_VERBOSE_STRINGS */
+
+static CURLcode
+darwinssl_connect_step3(struct connectdata *conn,
+                        int sockindex)
+{
+  struct Curl_easy *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+
+  /* There is no step 3!
+   * Well, okay, if verbose mode is on, let's print the details of the
+   * server certificates. */
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+  if(data->set.verbose)
+    show_verbose_server_cert(conn, sockindex);
+#endif
 
   connssl->connecting_state = ssl_connect_done;
   return CURLE_OK;
@@ -2424,8 +2546,8 @@ bool Curl_darwinssl_data_pending(const struct connectdata *conn,
     return false;
 }
 
-int Curl_darwinssl_random(unsigned char *entropy,
-                          size_t length)
+CURLcode Curl_darwinssl_random(unsigned char *entropy,
+                               size_t length)
 {
   /* arc4random_buf() isn't available on cats older than Lion, so let's
      do this manually for the benefit of the older cats. */
@@ -2439,7 +2561,7 @@ int Curl_darwinssl_random(unsigned char *entropy,
     random_number >>= 8;
   }
   i = random_number = 0;
-  return 0;
+  return CURLE_OK;
 }
 
 void Curl_darwinssl_md5sum(unsigned char *tmp, /* input */
diff --git a/lib/vtls/darwinssl.h b/lib/vtls/darwinssl.h
index 8b185b6..4bd41ca 100644
--- a/lib/vtls/darwinssl.h
+++ b/lib/vtls/darwinssl.h
@@ -8,7 +8,7 @@
  *                             \___|\___/|_| \_\_____|
  *
  * Copyright (C) 2012 - 2014, Nick Zitzmann, <nickzman at gmail.com>.
- * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 2012 - 2017, Daniel Stenberg, <daniel at 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
@@ -42,8 +42,8 @@ int Curl_darwinssl_check_cxn(struct connectdata *conn);
 bool Curl_darwinssl_data_pending(const struct connectdata *conn,
                                  int connindex);
 
-int Curl_darwinssl_random(unsigned char *entropy,
-                          size_t length);
+CURLcode Curl_darwinssl_random(unsigned char *entropy,
+                               size_t length);
 void Curl_darwinssl_md5sum(unsigned char *tmp, /* input */
                            size_t tmplen,
                            unsigned char *md5sum, /* output */
diff --git a/lib/vtls/gskit.c b/lib/vtls/gskit.c
index a0d462b..bf75bdd 100644
--- a/lib/vtls/gskit.c
+++ b/lib/vtls/gskit.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
@@ -320,7 +320,7 @@ static CURLcode set_ciphers(struct connectdata *conn,
 
   /* We allocate GSKit buffers of the same size as the input string: since
      GSKit tokens are always shorter than their cipher names, allocated buffers
-     will always be large enough to accomodate the result. */
+     will always be large enough to accommodate the result. */
   l = strlen(cipherlist) + 1;
   memset((char *) ciphers, 0, sizeof ciphers);
   for(i = 0; i < CURL_GSKPROTO_LAST; i++) {
@@ -748,6 +748,40 @@ static ssize_t gskit_recv(struct connectdata *conn, int num, char *buf,
   return (ssize_t) nread;
 }
 
+static CURLcode
+set_ssl_version_min_max(unsigned int *protoflags, struct connectdata *conn)
+{
+  struct Curl_easy *data = conn->data;
+  long ssl_version = SSL_CONN_CONFIG(version);
+  long ssl_version_max = SSL_CONN_CONFIG(version_max);
+  long i = ssl_version;
+  switch(ssl_version_max) {
+    case CURL_SSLVERSION_MAX_NONE:
+      ssl_version_max = ssl_version;
+      break;
+    case CURL_SSLVERSION_MAX_DEFAULT:
+      ssl_version_max = CURL_SSLVERSION_TLSv1_2;
+      break;
+  }
+  for(; i <= (ssl_version_max >> 16); ++i) {
+    switch(i) {
+      case CURL_SSLVERSION_TLSv1_0:
+        *protoflags |= CURL_GSKPROTO_TLSV10_MASK;
+        break;
+      case CURL_SSLVERSION_TLSv1_1:
+        *protoflags |= CURL_GSKPROTO_TLSV11_MASK;
+        break;
+      case CURL_SSLVERSION_TLSv1_2:
+        *protoflags |= CURL_GSKPROTO_TLSV11_MASK;
+        break;
+      case CURL_SSLVERSION_TLSv1_3:
+        failf(data, "GSKit: TLS 1.3 is not yet supported");
+        return CURLE_SSL_CONNECT_ERROR;
+    }
+  }
+
+  return CURLE_OK;
+}
 
 static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
 {
@@ -764,7 +798,7 @@ static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
   const char * const hostname = SSL_IS_PROXY()? conn->http_proxy.host.name:
     conn->host.name;
   const char *sni;
-  unsigned int protoflags;
+  unsigned int protoflags = 0;
   long timeout;
   Qso_OverlappedIO_t commarea;
   int sockpair[2];
@@ -849,17 +883,13 @@ static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
                  CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK;
     break;
   case CURL_SSLVERSION_TLSv1_0:
-    protoflags = CURL_GSKPROTO_TLSV10_MASK;
-    break;
   case CURL_SSLVERSION_TLSv1_1:
-    protoflags = CURL_GSKPROTO_TLSV11_MASK;
-    break;
   case CURL_SSLVERSION_TLSv1_2:
-    protoflags = CURL_GSKPROTO_TLSV12_MASK;
-    break;
   case CURL_SSLVERSION_TLSv1_3:
-    failf(data, "GSKit: TLS 1.3 is not yet supported");
-    return CURLE_SSL_CONNECT_ERROR;
+    result = set_ssl_version_min_max(&protoflags, conn);
+    if(result != CURLE_OK)
+      return result;
+    break;
   default:
     failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
     return CURLE_SSL_CONNECT_ERROR;
diff --git a/lib/vtls/gtls.c b/lib/vtls/gtls.c
index 0e308cb..0230778 100644
--- a/lib/vtls/gtls.c
+++ b/lib/vtls/gtls.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
@@ -92,11 +92,11 @@ static bool gtls_inited = FALSE;
 #    define GNUTLS_MAPS_WINSOCK_ERRORS 1
 #  endif
 
-#  if (GNUTLS_VERSION_NUMBER >= 0x030200)
+#  if HAVE_GNUTLS_ALPN_SET_PROTOCOLS
 #    define HAS_ALPN
 #  endif
 
-#  if (GNUTLS_VERSION_NUMBER >= 0x03020d)
+#  if HAVE_GNUTLS_OCSP_REQ_INIT
 #    define HAS_OCSP
 #  endif
 
@@ -278,7 +278,7 @@ static CURLcode handshake(struct connectdata *conn,
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
   gnutls_session_t session = conn->ssl[sockindex].session;
   curl_socket_t sockfd = conn->sock[sockindex];
-  long timeout_ms;
+  time_t timeout_ms;
   int rc;
   int what;
 
@@ -314,7 +314,7 @@ static CURLcode handshake(struct connectdata *conn,
           return CURLE_OK;
         else if(timeout_ms) {
           /* timeout */
-          failf(data, "SSL connection timeout at %ld", timeout_ms);
+          failf(data, "SSL connection timeout at %ld", (long)timeout_ms);
           return CURLE_OPERATION_TIMEDOUT;
         }
       }
@@ -375,11 +375,106 @@ static gnutls_x509_crt_fmt_t do_file_type(const char *type)
   return -1;
 }
 
+#ifndef USE_GNUTLS_PRIORITY_SET_DIRECT
+static CURLcode
+set_ssl_version_min_max(int *list, size_t list_size, struct connectdata *conn)
+{
+  struct Curl_easy *data = conn->data;
+  long ssl_version = SSL_CONN_CONFIG(version);
+  long ssl_version_max = SSL_CONN_CONFIG(version_max);
+  long i = ssl_version;
+  long protocol_priority_idx = 0;
+
+  switch(ssl_version_max) {
+    case CURL_SSLVERSION_MAX_NONE:
+      ssl_version_max = ssl_version << 16;
+      break;
+    case CURL_SSLVERSION_MAX_DEFAULT:
+      ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2;
+      break;
+  }
+
+  for(; i <= (ssl_version_max >> 16) &&
+        protocol_priority_idx < list_size; ++i) {
+    switch(i) {
+      case CURL_SSLVERSION_TLSv1_0:
+        protocol_priority[protocol_priority_idx++] = GNUTLS_TLS1_0;
+        break;
+      case CURL_SSLVERSION_TLSv1_1:
+        protocol_priority[protocol_priority_idx++] = GNUTLS_TLS1_1;
+        break;
+      case CURL_SSLVERSION_TLSv1_2:
+        protocol_priority[protocol_priority_idx++] = GNUTLS_TLS1_2;
+        break;
+      case CURL_SSLVERSION_TLSv1_3:
+        failf(data, "GnuTLS: TLS 1.3 is not yet supported");
+        return CURLE_SSL_CONNECT_ERROR;
+    }
+  }
+  return CURLE_OK;
+}
+#else
+#define GNUTLS_CIPHERS "NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509"
+/* If GnuTLS was compiled without support for SRP it will error out if SRP is
+   requested in the priority string, so treat it specially
+ */
+#define GNUTLS_SRP "+SRP"
+
+static CURLcode
+set_ssl_version_min_max(const char **prioritylist, struct connectdata *conn)
+{
+  struct Curl_easy *data = conn->data;
+  long ssl_version = SSL_CONN_CONFIG(version);
+  long ssl_version_max = SSL_CONN_CONFIG(version_max);
+  if(ssl_version == CURL_SSLVERSION_TLSv1_3 ||
+     ssl_version_max == CURL_SSLVERSION_MAX_TLSv1_3) {
+    failf(data, "GnuTLS: TLS 1.3 is not yet supported");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+  if(ssl_version_max == CURL_SSLVERSION_MAX_NONE) {
+    ssl_version_max = ssl_version << 16;
+  }
+  switch(ssl_version | ssl_version_max) {
+    case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_0:
+      *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
+                      "+VERS-TLS1.0:" GNUTLS_SRP;
+      return CURLE_OK;
+    case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_1:
+      *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
+                      "+VERS-TLS1.0:+VERS-TLS1.1:" GNUTLS_SRP;
+      return CURLE_OK;
+    case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_2:
+    case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_DEFAULT:
+      *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
+                      "+VERS-TLS1.0:+VERS-TLS1.1:+VERS-TLS1.2:" GNUTLS_SRP;
+      return CURLE_OK;
+    case CURL_SSLVERSION_TLSv1_1 | CURL_SSLVERSION_MAX_TLSv1_1:
+      *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
+                      "+VERS-TLS1.1:" GNUTLS_SRP;
+      return CURLE_OK;
+    case CURL_SSLVERSION_TLSv1_1 | CURL_SSLVERSION_MAX_TLSv1_2:
+    case CURL_SSLVERSION_TLSv1_1 | CURL_SSLVERSION_MAX_DEFAULT:
+      *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
+                      "+VERS-TLS1.1:+VERS-TLS1.2:" GNUTLS_SRP;
+      return CURLE_OK;
+    case CURL_SSLVERSION_TLSv1_2 | CURL_SSLVERSION_MAX_TLSv1_2:
+    case CURL_SSLVERSION_TLSv1_2 | CURL_SSLVERSION_MAX_DEFAULT:
+      *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
+                      "+VERS-TLS1.2:" GNUTLS_SRP;
+      return CURLE_OK;
+  }
+
+  failf(data, "GnuTLS: cannot set ssl protocol");
+  return CURLE_SSL_CONNECT_ERROR;
+}
+#endif
+
 static CURLcode
 gtls_connect_step1(struct connectdata *conn,
                    int sockindex)
 {
   struct Curl_easy *data = conn->data;
+  unsigned int init_flags;
   gnutls_session_t session;
   int rc;
   bool sni = TRUE; /* default is SNI enabled */
@@ -405,13 +500,8 @@ gtls_connect_step1(struct connectdata *conn,
     GNUTLS_CIPHER_3DES_CBC,
   };
   static const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 };
-  static int protocol_priority[] = { 0, 0, 0, 0 };
+  int protocol_priority[] = { 0, 0, 0, 0 };
 #else
-#define GNUTLS_CIPHERS "NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509"
-/* If GnuTLS was compiled without support for SRP it will error out if SRP is
-   requested in the priority string, so treat it specially
- */
-#define GNUTLS_SRP "+SRP"
   const char *prioritylist;
   const char *err = NULL;
 #endif
@@ -526,7 +616,14 @@ gtls_connect_step1(struct connectdata *conn,
   }
 
   /* Initialize TLS session as a client */
-  rc = gnutls_init(&conn->ssl[sockindex].session, GNUTLS_CLIENT);
+  init_flags = GNUTLS_CLIENT;
+
+#if defined(GNUTLS_NO_TICKETS)
+  /* Disable TLS session tickets */
+  init_flags |= GNUTLS_NO_TICKETS;
+#endif
+
+  rc = gnutls_init(&conn->ssl[sockindex].session, init_flags);
   if(rc != GNUTLS_E_SUCCESS) {
     failf(data, "gnutls_init() failed: %d", rc);
     return CURLE_SSL_CONNECT_ERROR;
@@ -568,7 +665,7 @@ gtls_connect_step1(struct connectdata *conn,
     return CURLE_SSL_CONNECT_ERROR;
   }
 
-  switch(SSL_CONN_CONFIG(version) {
+  switch(SSL_CONN_CONFIG(version)) {
     case CURL_SSLVERSION_SSLv3:
       protocol_priority[0] = GNUTLS_SSL3;
       break;
@@ -579,17 +676,16 @@ gtls_connect_step1(struct connectdata *conn,
       protocol_priority[2] = GNUTLS_TLS1_2;
       break;
     case CURL_SSLVERSION_TLSv1_0:
-      protocol_priority[0] = GNUTLS_TLS1_0;
-      break;
     case CURL_SSLVERSION_TLSv1_1:
-      protocol_priority[0] = GNUTLS_TLS1_1;
-      break;
     case CURL_SSLVERSION_TLSv1_2:
-      protocol_priority[0] = GNUTLS_TLS1_2;
-      break;
     case CURL_SSLVERSION_TLSv1_3:
-      failf(data, "GnuTLS: TLS 1.3 is not yet supported");
-      return CURLE_SSL_CONNECT_ERROR;
+      {
+        CURLcode result = set_ssl_version_min_max(protocol_priority,
+                sizeof(protocol_priority)/sizeof(protocol_priority[0]), conn);
+        if(result != CURLE_OK)
+          return result;
+        break;
+      }
     case CURL_SSLVERSION_SSLv2:
       failf(data, "GnuTLS does not support SSLv2");
       return CURLE_SSL_CONNECT_ERROR;
@@ -617,20 +713,15 @@ gtls_connect_step1(struct connectdata *conn,
       prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:" GNUTLS_SRP;
       break;
     case CURL_SSLVERSION_TLSv1_0:
-      prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
-                     "+VERS-TLS1.0:" GNUTLS_SRP;
-      break;
     case CURL_SSLVERSION_TLSv1_1:
-      prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
-                     "+VERS-TLS1.1:" GNUTLS_SRP;
-      break;
     case CURL_SSLVERSION_TLSv1_2:
-      prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
-                     "+VERS-TLS1.2:" GNUTLS_SRP;
-      break;
     case CURL_SSLVERSION_TLSv1_3:
-      failf(data, "GnuTLS: TLS 1.3 is not yet supported");
-      return CURLE_SSL_CONNECT_ERROR;
+      {
+        CURLcode result = set_ssl_version_min_max(&prioritylist, conn);
+        if(result != CURLE_OK)
+          return result;
+        break;
+      }
     case CURL_SSLVERSION_SSLv2:
       failf(data, "GnuTLS does not support SSLv2");
       return CURLE_SSL_CONNECT_ERROR;
@@ -782,7 +873,7 @@ gtls_connect_step1(struct connectdata *conn,
 
   /* This might be a reconnect, so we check for a session ID in the cache
      to speed up things */
-  if(data->set.general_ssl.sessionid) {
+  if(SSL_SET_OPTION(primary.sessionid)) {
     void *ssl_sessionid;
     size_t ssl_idsize;
 
@@ -882,7 +973,9 @@ gtls_connect_step3(struct connectdata *conn,
   gnutls_datum_t proto;
 #endif
   CURLcode result = CURLE_OK;
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
   gnutls_protocol_t version = gnutls_protocol_get_version(session);
+#endif
   const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
     conn->host.name;
 
@@ -1311,7 +1404,7 @@ gtls_connect_step3(struct connectdata *conn,
   conn->recv[sockindex] = gtls_recv;
   conn->send[sockindex] = gtls_send;
 
-  if(data->set.general_ssl.sessionid) {
+  if(SSL_SET_OPTION(primary.sessionid)) {
     /* we always unconditionally get the session id here, as even if we
        already got it from the cache and asked to use it in the connection, it
        might've been rejected and then a new one is in use now and we need to
@@ -1625,19 +1718,21 @@ static int Curl_gtls_seed(struct Curl_easy *data)
 #endif
 
 /* data might be NULL! */
-int Curl_gtls_random(struct Curl_easy *data,
-                     unsigned char *entropy,
-                     size_t length)
+CURLcode Curl_gtls_random(struct Curl_easy *data,
+                          unsigned char *entropy,
+                          size_t length)
 {
 #if defined(USE_GNUTLS_NETTLE)
+  int rc;
   (void)data;
-  gnutls_rnd(GNUTLS_RND_RANDOM, entropy, length);
+  rc = gnutls_rnd(GNUTLS_RND_RANDOM, entropy, length);
+  return rc?CURLE_FAILED_INIT:CURLE_OK;
 #elif defined(USE_GNUTLS)
   if(data)
     Curl_gtls_seed(data); /* Initiate the seed if not already done */
   gcry_randomize(entropy, length, GCRY_STRONG_RANDOM);
 #endif
-  return 0;
+  return CURLE_OK;
 }
 
 void Curl_gtls_md5sum(unsigned char *tmp, /* input */
diff --git a/lib/vtls/gtls.h b/lib/vtls/gtls.h
index 6531201..462c048 100644
--- a/lib/vtls/gtls.h
+++ b/lib/vtls/gtls.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
@@ -43,9 +43,9 @@ void Curl_gtls_close(struct connectdata *conn, int sockindex);
 void Curl_gtls_session_free(void *ptr);
 size_t Curl_gtls_version(char *buffer, size_t size);
 int Curl_gtls_shutdown(struct connectdata *conn, int sockindex);
-int Curl_gtls_random(struct Curl_easy *data,
-                     unsigned char *entropy,
-                     size_t length);
+CURLcode Curl_gtls_random(struct Curl_easy *data,
+                          unsigned char *entropy,
+                          size_t length);
 void Curl_gtls_md5sum(unsigned char *tmp, /* input */
                       size_t tmplen,
                       unsigned char *md5sum, /* output */
diff --git a/lib/vtls/mbedtls.c b/lib/vtls/mbedtls.c
index 8bcaddd..3ffa957 100644
--- a/lib/vtls/mbedtls.c
+++ b/lib/vtls/mbedtls.c
@@ -6,7 +6,7 @@
  *                             \___|\___/|_| \_\_____|
  *
  * Copyright (C) 2010 - 2011, Hoi-Ho Chan, <hoiho.chan at gmail.com>
- * Copyright (C) 2012 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 2012 - 2017, Daniel Stenberg, <daniel at 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
@@ -157,6 +157,71 @@ const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_fr =
 static Curl_recv mbed_recv;
 static Curl_send mbed_send;
 
+static CURLcode mbedtls_version_from_curl(int *mbedver, long version)
+{
+  switch(version) {
+    case CURL_SSLVERSION_TLSv1_0:
+      *mbedver = MBEDTLS_SSL_MINOR_VERSION_1;
+      return CURLE_OK;
+    case CURL_SSLVERSION_TLSv1_1:
+      *mbedver = MBEDTLS_SSL_MINOR_VERSION_2;
+      return CURLE_OK;
+    case CURL_SSLVERSION_TLSv1_2:
+      *mbedver = MBEDTLS_SSL_MINOR_VERSION_3;
+      return CURLE_OK;
+    case CURL_SSLVERSION_TLSv1_3:
+      break;
+  }
+  return CURLE_SSL_CONNECT_ERROR;
+}
+
+static CURLcode
+set_ssl_version_min_max(struct connectdata *conn, int sockindex)
+{
+  struct Curl_easy *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  int mbedtls_ver_min = MBEDTLS_SSL_MINOR_VERSION_1;
+  int mbedtls_ver_max = MBEDTLS_SSL_MINOR_VERSION_1;
+  long ssl_version = SSL_CONN_CONFIG(version);
+  long ssl_version_max = SSL_CONN_CONFIG(version_max);
+  CURLcode result = CURLE_OK;
+
+  switch(ssl_version) {
+    case CURL_SSLVERSION_DEFAULT:
+    case CURL_SSLVERSION_TLSv1:
+      ssl_version = CURL_SSLVERSION_TLSv1_0;
+      ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2;
+      break;
+  }
+
+  switch(ssl_version_max) {
+    case CURL_SSLVERSION_MAX_NONE:
+      ssl_version_max = ssl_version << 16;
+      break;
+    case CURL_SSLVERSION_MAX_DEFAULT:
+      ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2;
+      break;
+  }
+
+  result = mbedtls_version_from_curl(&mbedtls_ver_min, ssl_version);
+  if(result) {
+    failf(data, "unsupported min version passed via CURLOPT_SSLVERSION");
+    return result;
+  }
+  result = mbedtls_version_from_curl(&mbedtls_ver_max, ssl_version_max >> 16);
+  if(result) {
+    failf(data, "unsupported max version passed via CURLOPT_SSLVERSION");
+    return result;
+  }
+
+  mbedtls_ssl_conf_min_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
+                               mbedtls_ver_min);
+  mbedtls_ssl_conf_max_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
+                               mbedtls_ver_max);
+
+  return result;
+}
+
 static CURLcode
 mbed_connect_step1(struct connectdata *conn,
                    int sockindex)
@@ -333,29 +398,15 @@ mbed_connect_step1(struct connectdata *conn,
     infof(data, "mbedTLS: Set SSL version to SSLv3\n");
     break;
   case CURL_SSLVERSION_TLSv1_0:
-    mbedtls_ssl_conf_min_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
-                                 MBEDTLS_SSL_MINOR_VERSION_1);
-    mbedtls_ssl_conf_max_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
-                                 MBEDTLS_SSL_MINOR_VERSION_1);
-    infof(data, "mbedTLS: Set SSL version to TLS 1.0\n");
-    break;
   case CURL_SSLVERSION_TLSv1_1:
-    mbedtls_ssl_conf_min_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
-                                 MBEDTLS_SSL_MINOR_VERSION_2);
-    mbedtls_ssl_conf_max_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
-                                 MBEDTLS_SSL_MINOR_VERSION_2);
-    infof(data, "mbedTLS: Set SSL version to TLS 1.1\n");
-    break;
   case CURL_SSLVERSION_TLSv1_2:
-    mbedtls_ssl_conf_min_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
-                                 MBEDTLS_SSL_MINOR_VERSION_3);
-    mbedtls_ssl_conf_max_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
-                                 MBEDTLS_SSL_MINOR_VERSION_3);
-    infof(data, "mbedTLS: Set SSL version to TLS 1.2\n");
-    break;
   case CURL_SSLVERSION_TLSv1_3:
-    failf(data, "mbedTLS: TLS 1.3 is not yet supported");
-    return CURLE_SSL_CONNECT_ERROR;
+    {
+      CURLcode result = set_ssl_version_min_max(conn, sockindex);
+      if(result != CURLE_OK)
+        return result;
+      break;
+    }
   default:
     failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
     return CURLE_SSL_CONNECT_ERROR;
@@ -373,8 +424,13 @@ mbed_connect_step1(struct connectdata *conn,
   mbedtls_ssl_conf_ciphersuites(&connssl->config,
                                 mbedtls_ssl_list_ciphersuites());
 
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+  mbedtls_ssl_conf_session_tickets(&connssl->config,
+                                   MBEDTLS_SSL_SESSION_TICKETS_DISABLED);
+#endif
+
   /* Check if there's a cached ID we can/should use here! */
-  if(data->set.general_ssl.sessionid) {
+  if(SSL_SET_OPTION(primary.sessionid)) {
     void *old_session = NULL;
 
     Curl_ssl_sessionid_lock(conn);
@@ -439,6 +495,16 @@ mbed_connect_step1(struct connectdata *conn,
   mbedtls_debug_set_threshold(4);
 #endif
 
+  /* give application a chance to interfere with mbedTLS set up. */
+  if(data->set.ssl.fsslctx) {
+    ret = (*data->set.ssl.fsslctx)(data, &connssl->config,
+                                   data->set.ssl.fsslctxp);
+    if(ret) {
+      failf(data, "error signaled by ssl ctx callback");
+      return ret;
+    }
+  }
+
   connssl->connecting_state = ssl_connect_2;
 
   return CURLE_OK;
@@ -618,7 +684,7 @@ mbed_connect_step3(struct connectdata *conn,
 
   DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
 
-  if(data->set.general_ssl.sessionid) {
+  if(SSL_SET_OPTION(primary.sessionid)) {
     int ret;
     mbedtls_ssl_session *our_ssl_sessionid;
     void *old_ssl_sessionid = NULL;
@@ -631,6 +697,7 @@ mbed_connect_step3(struct connectdata *conn,
 
     ret = mbedtls_ssl_get_session(&connssl->ssl, our_ssl_sessionid);
     if(ret) {
+      free(our_ssl_sessionid);
       failf(data, "mbedtls_ssl_get_session returned -0x%x", -ret);
       return CURLE_SSL_CONNECT_ERROR;
     }
@@ -729,6 +796,55 @@ size_t Curl_mbedtls_version(char *buffer, size_t size)
                   (version>>16)&0xff, (version>>8)&0xff);
 }
 
+CURLcode Curl_mbedtls_random(struct Curl_easy *data, unsigned char *entropy,
+                             size_t length)
+{
+#if defined(MBEDTLS_CTR_DRBG_C)
+  int ret = -1;
+  char errorbuf[128];
+  mbedtls_entropy_context ctr_entropy;
+  mbedtls_ctr_drbg_context ctr_drbg;
+  mbedtls_entropy_init(&ctr_entropy);
+  mbedtls_ctr_drbg_init(&ctr_drbg);
+  errorbuf[0]=0;
+
+  ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func,
+                              &ctr_entropy, NULL, 0);
+
+  if(ret) {
+#ifdef MBEDTLS_ERROR_C
+    mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
+#endif /* MBEDTLS_ERROR_C */
+    failf(data, "Failed - mbedTLS: ctr_drbg_seed returned (-0x%04X) %s\n",
+          -ret, errorbuf);
+  }
+  else {
+    ret = mbedtls_ctr_drbg_random(&ctr_drbg, entropy, length);
+
+    if(ret) {
+#ifdef MBEDTLS_ERROR_C
+      mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
+#endif /* MBEDTLS_ERROR_C */
+      failf(data, "mbedTLS: ctr_drbg_init returned (-0x%04X) %s\n",
+            -ret, errorbuf);
+    }
+  }
+
+  mbedtls_ctr_drbg_free(&ctr_drbg);
+  mbedtls_entropy_free(&ctr_entropy);
+
+  return ret == 0 ? CURLE_OK : CURLE_FAILED_INIT;
+#elif defined(MBEDTLS_HAVEGE_C)
+  mbedtls_havege_state hs;
+  mbedtls_havege_init(&hs);
+  mbedtls_havege_random(&hs, entropy, length);
+  mbedtls_havege_free(&hs);
+  return CURLE_OK;
+#else
+  return CURLE_NOT_BUILT_IN;
+#endif
+}
+
 static CURLcode
 mbed_connect_common(struct connectdata *conn,
                     int sockindex,
@@ -883,9 +999,7 @@ void Curl_mbedtls_cleanup(void)
 
 int Curl_mbedtls_data_pending(const struct connectdata *conn, int sockindex)
 {
-  mbedtls_ssl_context *ssl =
-    (mbedtls_ssl_context *)&conn->ssl[sockindex].ssl;
-  return ssl->in_msglen != 0;
+  return mbedtls_ssl_get_bytes_avail(&conn->ssl[sockindex].ssl) != 0;
 }
 
 #endif /* USE_MBEDTLS */
diff --git a/lib/vtls/mbedtls.h b/lib/vtls/mbedtls.h
index 1021d54..71d17a4 100644
--- a/lib/vtls/mbedtls.h
+++ b/lib/vtls/mbedtls.h
@@ -50,9 +50,15 @@ void Curl_mbedtls_session_free(void *ptr);
 size_t Curl_mbedtls_version(char *buffer, size_t size);
 int Curl_mbedtls_shutdown(struct connectdata *conn, int sockindex);
 
+CURLcode Curl_mbedtls_random(struct Curl_easy *data, unsigned char *entropy,
+                     size_t length);
+
 /* this backends supports CURLOPT_PINNEDPUBLICKEY */
 #define have_curlssl_pinnedpubkey 1
 
+/* this backend supports CURLOPT_SSL_CTX_* */
+#define have_curlssl_ssl_ctx 1
+
 /* API setup for mbedTLS */
 #define curlssl_init() Curl_mbedtls_init()
 #define curlssl_cleanup() Curl_mbedtls_cleanup()
@@ -70,11 +76,7 @@ int Curl_mbedtls_shutdown(struct connectdata *conn, int sockindex);
 #define curlssl_data_pending(x,y) Curl_mbedtls_data_pending(x, y)
 #define CURL_SSL_BACKEND CURLSSLBACKEND_MBEDTLS
 #define curlssl_sha256sum(a,b,c,d) mbedtls_sha256(a,b,c,0)
-
-/* This might cause libcurl to use a weeker random!
-   TODO: implement proper use of Polarssl's CTR-DRBG or HMAC-DRBG and use that
-*/
-#define curlssl_random(x,y,z) (x=x, y=y, z=z, CURLE_NOT_BUILT_IN)
+#define curlssl_random(x,y,z) Curl_mbedtls_random(x, y, z)
 
 #endif /* USE_MBEDTLS */
 #endif /* HEADER_CURL_MBEDTLS_H */
diff --git a/lib/vtls/nss.c b/lib/vtls/nss.c
index ba8d582..89a16d3 100644
--- a/lib/vtls/nss.c
+++ b/lib/vtls/nss.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
@@ -56,7 +56,8 @@
 #include <base64.h>
 #include <cert.h>
 #include <prerror.h>
-#include <keyhi.h>        /* for SECKEY_DestroyPublicKey() */
+#include <keyhi.h>         /* for SECKEY_DestroyPublicKey() */
+#include <private/pprio.h> /* for PR_ImportTCPSocket */
 
 #define NSSVERNUM ((NSS_VMAJOR<<16)|(NSS_VMINOR<<8)|NSS_VPATCH)
 
@@ -77,11 +78,10 @@
 /* enough to fit the string "PEM Token #[0|1]" */
 #define SLOTSIZE 13
 
-PRFileDesc *PR_ImportTCPSocket(PRInt32 osfd);
 static PRLock *nss_initlock = NULL;
 static PRLock *nss_crllock = NULL;
 static PRLock *nss_findslot_lock = NULL;
-static struct curl_llist *nss_crl_list = NULL;
+static struct curl_llist nss_crl_list;
 static NSSInitContext *nss_context = NULL;
 static volatile int initialized = 0;
 
@@ -365,9 +365,9 @@ static char *dup_nickname(struct Curl_easy *data, const char *str)
 static PK11SlotInfo* nss_find_slot_by_name(const char *slot_name)
 {
   PK11SlotInfo *slot;
-  PR_Lock(nss_initlock);
+  PR_Lock(nss_findslot_lock);
   slot = PK11_FindSlotByName(slot_name);
-  PR_Unlock(nss_initlock);
+  PR_Unlock(nss_findslot_lock);
   return slot;
 }
 
@@ -401,7 +401,7 @@ static CURLcode nss_create_object(struct ssl_connect_data *ssl,
   PK11_SETATTRS(attrs, attr_cnt, CKA_CLASS, &obj_class, sizeof(obj_class));
   PK11_SETATTRS(attrs, attr_cnt, CKA_TOKEN, &cktrue, sizeof(CK_BBOOL));
   PK11_SETATTRS(attrs, attr_cnt, CKA_LABEL, (unsigned char *)filename,
-                strlen(filename) + 1);
+                (CK_ULONG)strlen(filename) + 1);
 
   if(CKO_CERTIFICATE == obj_class) {
     CK_BBOOL *pval = (cacert) ? (&cktrue) : (&ckfalse);
@@ -413,7 +413,7 @@ static CURLcode nss_create_object(struct ssl_connect_data *ssl,
   if(!obj)
     return result;
 
-  if(!Curl_llist_insert_next(ssl->obj_list, ssl->obj_list->tail, obj)) {
+  if(!Curl_llist_insert_next(&ssl->obj_list, ssl->obj_list.tail, obj)) {
     PK11_DestroyGenericObject(obj);
     return CURLE_OUT_OF_MEMORY;
   }
@@ -496,7 +496,7 @@ static CURLcode nss_cache_crl(SECItem *crl_der)
   PR_Lock(nss_crllock);
 
   /* store the CRL item so that we can free it in Curl_nss_cleanup() */
-  if(!Curl_llist_insert_next(nss_crl_list, nss_crl_list->tail, crl_der)) {
+  if(!Curl_llist_insert_next(&nss_crl_list, nss_crl_list.tail, crl_der)) {
     SECITEM_FreeItem(crl_der, PR_TRUE);
     PR_Unlock(nss_crllock);
     return CURLE_OUT_OF_MEMORY;
@@ -1227,9 +1227,7 @@ static CURLcode nss_init(struct Curl_easy *data)
     return CURLE_OK;
 
   /* list of all CRL items we need to destroy in Curl_nss_cleanup() */
-  nss_crl_list = Curl_llist_alloc(nss_destroy_crl_item);
-  if(!nss_crl_list)
-    return CURLE_OUT_OF_MEMORY;
+  Curl_llist_init(&nss_crl_list, nss_destroy_crl_item);
 
   /* First we check if $SSL_DIR points to a valid dir */
   cert_dir = getenv("SSL_DIR");
@@ -1336,8 +1334,7 @@ void Curl_nss_cleanup(void)
   }
 
   /* destroy all CRL items */
-  Curl_llist_destroy(nss_crl_list, NULL);
-  nss_crl_list = NULL;
+  Curl_llist_destroy(&nss_crl_list, NULL);
 
   PR_Unlock(nss_initlock);
 
@@ -1385,8 +1382,7 @@ static void nss_close(struct ssl_connect_data *connssl)
   connssl->client_nickname = NULL;
 
   /* destroy all NSS objects in order to avoid failure of NSS shutdown */
-  Curl_llist_destroy(connssl->obj_list, NULL);
-  connssl->obj_list = NULL;
+  Curl_llist_destroy(&connssl->obj_list, NULL);
   connssl->obj_clicert = NULL;
 
   if(connssl->handle) {
@@ -1512,78 +1508,108 @@ static CURLcode nss_load_ca_certificates(struct connectdata *conn,
   return CURLE_OK;
 }
 
-static CURLcode nss_init_sslver(SSLVersionRange *sslver,
-                                struct Curl_easy *data,
-                                struct connectdata *conn)
+static CURLcode nss_sslver_from_curl(PRUint16 *nssver, long version)
 {
-  switch(SSL_CONN_CONFIG(version)) {
-  case CURL_SSLVERSION_DEFAULT:
-    /* map CURL_SSLVERSION_DEFAULT to NSS default */
-    if(SSL_VersionRangeGetDefault(ssl_variant_stream, sslver) != SECSuccess)
-      return CURLE_SSL_CONNECT_ERROR;
-    /* ... but make sure we use at least TLSv1.0 according to libcurl API */
-    if(sslver->min < SSL_LIBRARY_VERSION_TLS_1_0)
-      sslver->min = SSL_LIBRARY_VERSION_TLS_1_0;
-    return CURLE_OK;
-
+  switch(version) {
   case CURL_SSLVERSION_TLSv1:
-    sslver->min = SSL_LIBRARY_VERSION_TLS_1_0;
     /* TODO: set sslver->max to SSL_LIBRARY_VERSION_TLS_1_3 once stable */
 #ifdef SSL_LIBRARY_VERSION_TLS_1_2
-    sslver->max = SSL_LIBRARY_VERSION_TLS_1_2;
+    *nssver = SSL_LIBRARY_VERSION_TLS_1_2;
 #elif defined SSL_LIBRARY_VERSION_TLS_1_1
-    sslver->max = SSL_LIBRARY_VERSION_TLS_1_1;
+    *nssver = SSL_LIBRARY_VERSION_TLS_1_1;
 #else
-    sslver->max = SSL_LIBRARY_VERSION_TLS_1_0;
+    *nssver = SSL_LIBRARY_VERSION_TLS_1_0;
 #endif
     return CURLE_OK;
 
   case CURL_SSLVERSION_SSLv2:
-    sslver->min = SSL_LIBRARY_VERSION_2;
-    sslver->max = SSL_LIBRARY_VERSION_2;
+    *nssver = SSL_LIBRARY_VERSION_2;
     return CURLE_OK;
 
   case CURL_SSLVERSION_SSLv3:
-    sslver->min = SSL_LIBRARY_VERSION_3_0;
-    sslver->max = SSL_LIBRARY_VERSION_3_0;
+    *nssver = SSL_LIBRARY_VERSION_3_0;
     return CURLE_OK;
 
   case CURL_SSLVERSION_TLSv1_0:
-    sslver->min = SSL_LIBRARY_VERSION_TLS_1_0;
-    sslver->max = SSL_LIBRARY_VERSION_TLS_1_0;
+    *nssver = SSL_LIBRARY_VERSION_TLS_1_0;
     return CURLE_OK;
 
   case CURL_SSLVERSION_TLSv1_1:
 #ifdef SSL_LIBRARY_VERSION_TLS_1_1
-    sslver->min = SSL_LIBRARY_VERSION_TLS_1_1;
-    sslver->max = SSL_LIBRARY_VERSION_TLS_1_1;
+    *nssver = SSL_LIBRARY_VERSION_TLS_1_1;
     return CURLE_OK;
+#else
+    return CURLE_SSL_CONNECT_ERROR;
 #endif
-    break;
 
   case CURL_SSLVERSION_TLSv1_2:
 #ifdef SSL_LIBRARY_VERSION_TLS_1_2
-    sslver->min = SSL_LIBRARY_VERSION_TLS_1_2;
-    sslver->max = SSL_LIBRARY_VERSION_TLS_1_2;
+    *nssver = SSL_LIBRARY_VERSION_TLS_1_2;
     return CURLE_OK;
+#else
+    return CURLE_SSL_CONNECT_ERROR;
 #endif
-    break;
 
   case CURL_SSLVERSION_TLSv1_3:
 #ifdef SSL_LIBRARY_VERSION_TLS_1_3
-    sslver->min = SSL_LIBRARY_VERSION_TLS_1_3;
-    sslver->max = SSL_LIBRARY_VERSION_TLS_1_3;
+    *nssver = SSL_LIBRARY_VERSION_TLS_1_3;
     return CURLE_OK;
+#else
+    return CURLE_SSL_CONNECT_ERROR;
 #endif
-    break;
 
   default:
-    failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
     return CURLE_SSL_CONNECT_ERROR;
   }
+}
+
+static CURLcode nss_init_sslver(SSLVersionRange *sslver,
+                                struct Curl_easy *data,
+                                struct connectdata *conn)
+{
+  CURLcode result;
+  const long min = SSL_CONN_CONFIG(version);
+  const long max = SSL_CONN_CONFIG(version_max);
+
+  /* map CURL_SSLVERSION_DEFAULT to NSS default */
+  if(min == CURL_SSLVERSION_DEFAULT || max == CURL_SSLVERSION_MAX_DEFAULT) {
+    /* map CURL_SSLVERSION_DEFAULT to NSS default */
+    if(SSL_VersionRangeGetDefault(ssl_variant_stream, sslver) != SECSuccess)
+      return CURLE_SSL_CONNECT_ERROR;
+    /* ... but make sure we use at least TLSv1.0 according to libcurl API */
+    if(sslver->min < SSL_LIBRARY_VERSION_TLS_1_0)
+      sslver->min = SSL_LIBRARY_VERSION_TLS_1_0;
+  }
+
+  switch(min) {
+  case CURL_SSLVERSION_DEFAULT:
+    break;
+  case CURL_SSLVERSION_TLSv1:
+    sslver->min = SSL_LIBRARY_VERSION_TLS_1_0;
+    break;
+  default:
+    result = nss_sslver_from_curl(&sslver->min, min);
+    if(result) {
+      failf(data, "unsupported min version passed via CURLOPT_SSLVERSION");
+      return result;
+    }
+    if(max == CURL_SSLVERSION_MAX_NONE)
+      sslver->max = sslver->min;
+  }
+
+  switch(max) {
+  case CURL_SSLVERSION_MAX_NONE:
+  case CURL_SSLVERSION_MAX_DEFAULT:
+    break;
+  default:
+    result = nss_sslver_from_curl(&sslver->max, max >> 16);
+    if(result) {
+      failf(data, "unsupported max version passed via CURLOPT_SSLVERSION");
+      return result;
+    }
+  }
 
-  failf(data, "TLS minor version cannot be set");
-  return CURLE_SSL_CONNECT_ERROR;
+  return CURLE_OK;
 }
 
 static CURLcode nss_fail_connect(struct ssl_connect_data *connssl,
@@ -1606,19 +1632,19 @@ static CURLcode nss_fail_connect(struct ssl_connect_data *connssl,
   }
 
   /* cleanup on connection failure */
-  Curl_llist_destroy(connssl->obj_list, NULL);
-  connssl->obj_list = NULL;
+  Curl_llist_destroy(&connssl->obj_list, NULL);
 
   return curlerr;
 }
 
-/* Switch the SSL socket into non-blocking mode. */
-static CURLcode nss_set_nonblock(struct ssl_connect_data *connssl,
-                                 struct Curl_easy *data)
+/* Switch the SSL socket into blocking or non-blocking mode. */
+static CURLcode nss_set_blocking(struct ssl_connect_data *connssl,
+                                 struct Curl_easy *data,
+                                 bool blocking)
 {
   static PRSocketOptionData sock_opt;
   sock_opt.option = PR_SockOpt_Nonblocking;
-  sock_opt.value.non_blocking = PR_TRUE;
+  sock_opt.value.non_blocking = !blocking;
 
   if(PR_SetSocketOption(connssl->handle, &sock_opt) != PR_SUCCESS)
     return nss_fail_connect(connssl, data, CURLE_SSL_CONNECT_ERROR);
@@ -1647,9 +1673,7 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
   connssl->data = data;
 
   /* list of all NSS objects we need to destroy in Curl_nss_close() */
-  connssl->obj_list = Curl_llist_alloc(nss_destroy_object);
-  if(!connssl->obj_list)
-    return CURLE_OUT_OF_MEMORY;
+  Curl_llist_init(&connssl->obj_list, nss_destroy_object);
 
   /* FIXME. NSS doesn't support multiple databases open at the same time. */
   PR_Lock(nss_initlock);
@@ -1696,7 +1720,7 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
     goto error;
 
   /* do not use SSL cache if disabled or we are not going to verify peer */
-  ssl_no_cache = (data->set.general_ssl.sessionid
+  ssl_no_cache = (SSL_SET_OPTION(primary.sessionid)
                   && SSL_CONN_CONFIG(verifypeer)) ? PR_FALSE : PR_TRUE;
   if(SSL_OptionSet(model, SSL_NO_CACHE, ssl_no_cache) != SECSuccess)
     goto error;
@@ -1746,9 +1770,12 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
   if(SSL_HandshakeCallback(model, HandshakeCallback, conn) != SECSuccess)
     goto error;
 
-  if(SSL_CONN_CONFIG(verifypeer)) {
+  {
     const CURLcode rv = nss_load_ca_certificates(conn, sockindex);
-    if(rv) {
+    if((rv == CURLE_SSL_CACERT_BADFILE) && !SSL_CONN_CONFIG(verifypeer))
+      /* not a fatal error because we are not going to verify the peer */
+      infof(data, "warning: CA certificates failed to load\n");
+    else if(rv) {
       result = rv;
       goto error;
     }
@@ -1933,8 +1960,8 @@ static CURLcode nss_do_connect(struct connectdata *conn, int sockindex)
 
 
   /* check timeout situation */
-  const long time_left = Curl_timeleft(data, NULL, TRUE);
-  if(time_left < 0L) {
+  const time_t time_left = Curl_timeleft(data, NULL, TRUE);
+  if(time_left < 0) {
     failf(data, "timed out before SSL handshake");
     result = CURLE_OPERATION_TIMEDOUT;
     goto error;
@@ -2007,16 +2034,14 @@ static CURLcode nss_connect_common(struct connectdata *conn, int sockindex,
       /* we do not expect CURLE_AGAIN from nss_setup_connect() */
       return result;
 
-    if(!blocking) {
-      /* in non-blocking mode, set NSS non-blocking mode before handshake */
-      result = nss_set_nonblock(connssl, data);
-      if(result)
-        return result;
-    }
-
     connssl->connecting_state = ssl_connect_2;
   }
 
+  /* enable/disable blocking mode before handshake */
+  result = nss_set_blocking(connssl, data, blocking);
+  if(result)
+    return result;
+
   result = nss_do_connect(conn, sockindex);
   switch(result) {
   case CURLE_OK:
@@ -2032,7 +2057,7 @@ static CURLcode nss_connect_common(struct connectdata *conn, int sockindex,
 
   if(blocking) {
     /* in blocking mode, set NSS non-blocking mode _after_ SSL handshake */
-    result = nss_set_nonblock(connssl, data);
+    result = nss_set_blocking(connssl, data, /* blocking */ FALSE);
     if(result)
       return result;
   }
@@ -2138,17 +2163,17 @@ int Curl_nss_seed(struct Curl_easy *data)
 }
 
 /* data might be NULL */
-int Curl_nss_random(struct Curl_easy *data,
-                    unsigned char *entropy,
-                    size_t length)
+CURLcode Curl_nss_random(struct Curl_easy *data,
+                         unsigned char *entropy,
+                         size_t length)
 {
   Curl_nss_seed(data);  /* Initiate the seed if not already done */
 
   if(SECSuccess != PK11_GenerateRandom(entropy, curlx_uztosi(length)))
     /* signal a failure */
-    return -1;
+    return CURLE_FAILED_INIT;
 
-  return 0;
+  return CURLE_OK;
 }
 
 void Curl_nss_md5sum(unsigned char *tmp, /* input */
diff --git a/lib/vtls/nssg.h b/lib/vtls/nssg.h
index fd94003..8c46929 100644
--- a/lib/vtls/nssg.h
+++ b/lib/vtls/nssg.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
@@ -47,9 +47,9 @@ int Curl_nss_seed(struct Curl_easy *data);
 /* initialize NSS library if not already */
 CURLcode Curl_nss_force_init(struct Curl_easy *data);
 
-int Curl_nss_random(struct Curl_easy *data,
-                    unsigned char *entropy,
-                    size_t length);
+CURLcode Curl_nss_random(struct Curl_easy *data,
+                         unsigned char *entropy,
+                         size_t length);
 
 void Curl_nss_md5sum(unsigned char *tmp, /* input */
                      size_t tmplen,
diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c
index d92e713..58a014a 100644
--- a/lib/vtls/openssl.c
+++ b/lib/vtls/openssl.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
@@ -55,7 +55,9 @@
 #include <openssl/ssl.h>
 #include <openssl/rand.h>
 #include <openssl/x509v3.h>
+#ifndef OPENSSL_NO_DSA
 #include <openssl/dsa.h>
+#endif
 #include <openssl/dh.h>
 #include <openssl/err.h>
 #include <openssl/md5.h>
@@ -156,10 +158,56 @@ static unsigned long OpenSSL_version_num(void)
  * Number of bytes to read from the random number seed file. This must be
  * a finite value (because some entropy "files" like /dev/urandom have
  * an infinite length), but must be large enough to provide enough
- * entopy to properly seed OpenSSL's PRNG.
+ * entropy to properly seed OpenSSL's PRNG.
  */
 #define RAND_LOAD_LENGTH 1024
 
+static const char *SSL_ERROR_to_str(int err)
+{
+  switch(err) {
+  case SSL_ERROR_NONE:
+    return "SSL_ERROR_NONE";
+  case SSL_ERROR_SSL:
+    return "SSL_ERROR_SSL";
+  case SSL_ERROR_WANT_READ:
+    return "SSL_ERROR_WANT_READ";
+  case SSL_ERROR_WANT_WRITE:
+    return "SSL_ERROR_WANT_WRITE";
+  case SSL_ERROR_WANT_X509_LOOKUP:
+    return "SSL_ERROR_WANT_X509_LOOKUP";
+  case SSL_ERROR_SYSCALL:
+    return "SSL_ERROR_SYSCALL";
+  case SSL_ERROR_ZERO_RETURN:
+    return "SSL_ERROR_ZERO_RETURN";
+  case SSL_ERROR_WANT_CONNECT:
+    return "SSL_ERROR_WANT_CONNECT";
+  case SSL_ERROR_WANT_ACCEPT:
+    return "SSL_ERROR_WANT_ACCEPT";
+#if defined(SSL_ERROR_WANT_ASYNC)
+  case SSL_ERROR_WANT_ASYNC:
+    return "SSL_ERROR_WANT_ASYNC";
+#endif
+#if defined(SSL_ERROR_WANT_ASYNC_JOB)
+  case SSL_ERROR_WANT_ASYNC_JOB:
+    return "SSL_ERROR_WANT_ASYNC_JOB";
+#endif
+#if defined(SSL_ERROR_WANT_EARLY)
+  case SSL_ERROR_WANT_EARLY:
+    return "SSL_ERROR_WANT_EARLY";
+#endif
+  default:
+    return "SSL_ERROR unknown";
+  }
+}
+
+/* Return error string for last OpenSSL error
+ */
+static char *ossl_strerror(unsigned long error, char *buf, size_t size)
+{
+  ERR_error_string_n(error, buf, size);
+  return buf;
+}
+
 static int passwd_callback(char *buf, int num, int encrypting,
                            void *global_passwd)
 {
@@ -335,6 +383,7 @@ int cert_stuff(struct connectdata *conn,
                char *key_passwd)
 {
   struct Curl_easy *data = conn->data;
+  char error_buffer[256];
 
   int file_type = do_file_type(cert_type);
 
@@ -360,7 +409,8 @@ int cert_stuff(struct connectdata *conn,
               "could not load PEM client certificate, " OSSL_PACKAGE
               " error %s, "
               "(no key found, wrong pass phrase, or wrong file format?)",
-              ERR_error_string(ERR_get_error(), NULL) );
+              ossl_strerror(ERR_get_error(), error_buffer,
+                            sizeof(error_buffer)) );
         return 0;
       }
       break;
@@ -376,7 +426,8 @@ int cert_stuff(struct connectdata *conn,
               "could not load ASN1 client certificate, " OSSL_PACKAGE
               " error %s, "
               "(no key found, wrong pass phrase, or wrong file format?)",
-              ERR_error_string(ERR_get_error(), NULL) );
+              ossl_strerror(ERR_get_error(), error_buffer,
+                            sizeof(error_buffer)) );
         return 0;
       }
       break;
@@ -405,7 +456,8 @@ int cert_stuff(struct connectdata *conn,
                               0, &params, NULL, 1)) {
             failf(data, "ssl engine cannot load client cert with id"
                   " '%s' [%s]", cert_file,
-                  ERR_error_string(ERR_get_error(), NULL));
+                  ossl_strerror(ERR_get_error(), error_buffer,
+                                sizeof(error_buffer)));
             return 0;
           }
 
@@ -461,7 +513,8 @@ int cert_stuff(struct connectdata *conn,
         failf(data,
               "could not parse PKCS12 file, check password, " OSSL_PACKAGE
               " error %s",
-              ERR_error_string(ERR_get_error(), NULL) );
+              ossl_strerror(ERR_get_error(), error_buffer,
+                            sizeof(error_buffer)) );
         PKCS12_free(p12);
         return 0;
       }
@@ -472,7 +525,8 @@ int cert_stuff(struct connectdata *conn,
         failf(data,
               "could not load PKCS12 client certificate, " OSSL_PACKAGE
               " error %s",
-              ERR_error_string(ERR_get_error(), NULL) );
+              ossl_strerror(ERR_get_error(), error_buffer,
+                            sizeof(error_buffer)) );
         goto fail;
       }
 
@@ -493,21 +547,19 @@ int cert_stuff(struct connectdata *conn,
           /*
            * Note that sk_X509_pop() is used below to make sure the cert is
            * removed from the stack properly before getting passed to
-           * SSL_CTX_add_extra_chain_cert(). Previously we used
-           * sk_X509_value() instead, but then we'd clean it in the subsequent
-           * sk_X509_pop_free() call.
+           * SSL_CTX_add_extra_chain_cert(), which takes ownership. Previously
+           * we used sk_X509_value() instead, but then we'd clean it in the
+           * subsequent sk_X509_pop_free() call.
            */
           X509 *x = sk_X509_pop(ca);
-          if(!SSL_CTX_add_extra_chain_cert(ctx, x)) {
+          if(!SSL_CTX_add_client_CA(ctx, x)) {
             X509_free(x);
-            failf(data, "cannot add certificate to certificate chain");
+            failf(data, "cannot add certificate to client CA list");
             goto fail;
           }
-          /* SSL_CTX_add_client_CA() seems to work with either sk_* function,
-           * presumably because it duplicates what we pass to it.
-           */
-          if(!SSL_CTX_add_client_CA(ctx, x)) {
-            failf(data, "cannot add certificate to client CA list");
+          if(!SSL_CTX_add_extra_chain_cert(ctx, x)) {
+            X509_free(x);
+            failf(data, "cannot add certificate to certificate chain");
             goto fail;
           }
         }
@@ -541,6 +593,7 @@ int cert_stuff(struct connectdata *conn,
       if(!key_file)
         /* cert & key can only be in PEM case in the same file */
         key_file=cert_file;
+      /* FALLTHROUGH */
     case SSL_FILETYPE_ASN1:
       if(SSL_CTX_use_PrivateKey_file(ctx, key_file, file_type) != 1) {
         failf(data, "unable to set private key file: '%s' type %s",
@@ -664,17 +717,6 @@ static int x509_name_oneline(X509_NAME *a, char *buf, size_t size)
 #endif
 }
 
-/* Return error string for last OpenSSL error
- */
-static char *ossl_strerror(unsigned long error, char *buf, size_t size)
-{
-  /* OpenSSL 0.9.6 and later has a function named
-     ERR_error_string_n() that takes the size of the buffer as a
-     third argument */
-  ERR_error_string_n(error, buf, size);
-  return buf;
-}
-
 /**
  * Global SSL init
  *
@@ -776,7 +818,7 @@ int Curl_ossl_check_cxn(struct connectdata *conn)
                (RECV_TYPE_ARG3)1, (RECV_TYPE_ARG4)MSG_PEEK);
   if(nread == 0)
     return 0; /* connection has been closed */
-  else if(nread == 1)
+  if(nread == 1)
     return 1; /* connection still in place */
   else if(nread == -1) {
       int err = SOCKERRNO;
@@ -981,8 +1023,10 @@ int Curl_ossl_shutdown(struct connectdata *conn, int sockindex)
         default:
           /* openssl/ssl.h says "look at error stack/return value/errno" */
           sslerror = ERR_get_error();
-          failf(conn->data, OSSL_PACKAGE " SSL read: %s, errno %d",
-                ossl_strerror(sslerror, buf, sizeof(buf)),
+          failf(conn->data, OSSL_PACKAGE " SSL_read on shutdown: %s, errno %d",
+                (sslerror ?
+                 ossl_strerror(sslerror, buf, sizeof(buf)) :
+                 SSL_ERROR_to_str(err)),
                 SOCKERRNO);
           done = 1;
           break;
@@ -1609,7 +1653,7 @@ static void ssl_tls_trace(int direction, int ssl_ver, int content_type,
 #ifdef HAS_NPN
 
 /*
- * in is a list of lenght prefixed strings. this function has to select
+ * in is a list of length prefixed strings. this function has to select
  * the protocol we want to use from the list and write its string into out.
  */
 
@@ -1693,6 +1737,85 @@ get_ssl_version_txt(SSL *ssl)
   return "unknown";
 }
 
+static CURLcode
+set_ssl_version_min_max(long *ctx_options, struct connectdata *conn,
+                        int sockindex)
+{
+#if (OPENSSL_VERSION_NUMBER < 0x1000100FL) || !defined(TLS1_3_VERSION)
+  /* convoluted #if condition just to avoid compiler warnings on unused
+     variable */
+  struct Curl_easy *data = conn->data;
+#endif
+  long ssl_version = SSL_CONN_CONFIG(version);
+  long ssl_version_max = SSL_CONN_CONFIG(version_max);
+
+  if(ssl_version_max == CURL_SSLVERSION_MAX_NONE) {
+    ssl_version_max = ssl_version << 16;
+  }
+
+  switch(ssl_version) {
+    case CURL_SSLVERSION_TLSv1_3:
+#ifdef TLS1_3_VERSION
+    {
+      struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+      SSL_CTX_set_max_proto_version(connssl->ctx, TLS1_3_VERSION);
+      *ctx_options |= SSL_OP_NO_TLSv1_2;
+    }
+#else
+      (void)sockindex;
+      failf(data, OSSL_PACKAGE " was built without TLS 1.3 support");
+      return CURLE_NOT_BUILT_IN;
+#endif
+    case CURL_SSLVERSION_TLSv1_2:
+#if OPENSSL_VERSION_NUMBER >= 0x1000100FL
+      *ctx_options |= SSL_OP_NO_TLSv1_1;
+#else
+      failf(data, OSSL_PACKAGE " was built without TLS 1.2 support");
+      return CURLE_NOT_BUILT_IN;
+#endif
+      /* FALLTHROUGH */
+    case CURL_SSLVERSION_TLSv1_1:
+#if OPENSSL_VERSION_NUMBER >= 0x1000100FL
+      *ctx_options |= SSL_OP_NO_TLSv1;
+#else
+      failf(data, OSSL_PACKAGE " was built without TLS 1.1 support");
+      return CURLE_NOT_BUILT_IN;
+#endif
+      /* FALLTHROUGH */
+    case CURL_SSLVERSION_TLSv1_0:
+      *ctx_options |= SSL_OP_NO_SSLv2;
+      *ctx_options |= SSL_OP_NO_SSLv3;
+      break;
+  }
+
+  switch(ssl_version_max) {
+    case CURL_SSLVERSION_MAX_TLSv1_0:
+#if OPENSSL_VERSION_NUMBER >= 0x1000100FL
+      *ctx_options |= SSL_OP_NO_TLSv1_1;
+#endif
+      /* FALLTHROUGH */
+    case CURL_SSLVERSION_MAX_TLSv1_1:
+#if OPENSSL_VERSION_NUMBER >= 0x1000100FL
+      *ctx_options |= SSL_OP_NO_TLSv1_2;
+#endif
+      /* FALLTHROUGH */
+    case CURL_SSLVERSION_MAX_TLSv1_2:
+    case CURL_SSLVERSION_MAX_DEFAULT:
+#ifdef TLS1_3_VERSION
+      *ctx_options |= SSL_OP_NO_TLSv1_3;
+#endif
+      break;
+    case CURL_SSLVERSION_MAX_TLSv1_3:
+#ifdef TLS1_3_VERSION
+      break;
+#else
+      failf(data, OSSL_PACKAGE " was built without TLS 1.3 support");
+      return CURLE_NOT_BUILT_IN;
+#endif
+  }
+  return CURLE_OK;
+}
+
 static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
 {
   CURLcode result = CURLE_OK;
@@ -1702,9 +1825,11 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
   X509_LOOKUP *lookup = NULL;
   curl_socket_t sockfd = conn->sock[sockindex];
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-  long ctx_options;
+  long ctx_options = 0;
 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
   bool sni;
+  const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
+    conn->host.name;
 #ifdef ENABLE_IPV6
   struct in6_addr addr;
 #else
@@ -1723,8 +1848,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
   const char * const ssl_capath = SSL_CONN_CONFIG(CApath);
   const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
   const char * const ssl_crlfile = SSL_SET_OPTION(CRLfile);
-  const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
-    conn->host.name;
+  char error_buffer[256];
 
   DEBUGASSERT(ssl_connect_1 == connssl->connecting_state);
 
@@ -1790,7 +1914,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
 
   if(!connssl->ctx) {
     failf(data, "SSL: couldn't create a context: %s",
-          ERR_error_string(ERR_peek_error(), NULL));
+          ossl_strerror(ERR_peek_error(), error_buffer, sizeof(error_buffer)));
     return CURLE_OUT_OF_MEMORY;
   }
 
@@ -1889,60 +2013,13 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
     break;
 
   case CURL_SSLVERSION_TLSv1_0:
-    ctx_options |= SSL_OP_NO_SSLv2;
-    ctx_options |= SSL_OP_NO_SSLv3;
-#if OPENSSL_VERSION_NUMBER >= 0x1000100FL
-    ctx_options |= SSL_OP_NO_TLSv1_1;
-    ctx_options |= SSL_OP_NO_TLSv1_2;
-#ifdef TLS1_3_VERSION
-    ctx_options |= SSL_OP_NO_TLSv1_3;
-#endif
-#endif
-    break;
-
   case CURL_SSLVERSION_TLSv1_1:
-#if OPENSSL_VERSION_NUMBER >= 0x1000100FL
-    ctx_options |= SSL_OP_NO_SSLv2;
-    ctx_options |= SSL_OP_NO_SSLv3;
-    ctx_options |= SSL_OP_NO_TLSv1;
-    ctx_options |= SSL_OP_NO_TLSv1_2;
-#ifdef TLS1_3_VERSION
-    ctx_options |= SSL_OP_NO_TLSv1_3;
-#endif
-    break;
-#else
-    failf(data, OSSL_PACKAGE " was built without TLS 1.1 support");
-    return CURLE_NOT_BUILT_IN;
-#endif
-
   case CURL_SSLVERSION_TLSv1_2:
-#if OPENSSL_VERSION_NUMBER >= 0x1000100FL
-    ctx_options |= SSL_OP_NO_SSLv2;
-    ctx_options |= SSL_OP_NO_SSLv3;
-    ctx_options |= SSL_OP_NO_TLSv1;
-    ctx_options |= SSL_OP_NO_TLSv1_1;
-#ifdef TLS1_3_VERSION
-    ctx_options |= SSL_OP_NO_TLSv1_3;
-#endif
-    break;
-#else
-    failf(data, OSSL_PACKAGE " was built without TLS 1.2 support");
-    return CURLE_NOT_BUILT_IN;
-#endif
-
   case CURL_SSLVERSION_TLSv1_3:
-#ifdef TLS1_3_VERSION
-    SSL_CTX_set_max_proto_version(connssl->ctx, TLS1_3_VERSION);
-    ctx_options |= SSL_OP_NO_SSLv2;
-    ctx_options |= SSL_OP_NO_SSLv3;
-    ctx_options |= SSL_OP_NO_TLSv1;
-    ctx_options |= SSL_OP_NO_TLSv1_1;
-    ctx_options |= SSL_OP_NO_TLSv1_2;
+    result = set_ssl_version_min_max(&ctx_options, conn, sockindex);
+    if(result != CURLE_OK)
+       return result;
     break;
-#else
-    failf(data, OSSL_PACKAGE " was built without TLS 1.3 support");
-    return CURLE_NOT_BUILT_IN;
-#endif
 
   case CURL_SSLVERSION_SSLv2:
 #ifndef OPENSSL_NO_SSL2
@@ -2056,12 +2133,10 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
               ssl_capath ? ssl_capath : "none");
         return CURLE_SSL_CACERT_BADFILE;
       }
-      else {
-        /* Just continue with a warning if no strict  certificate verification
-           is required. */
-        infof(data, "error setting certificate verify locations,"
-              " continuing anyway:\n");
-      }
+      /* Just continue with a warning if no strict  certificate verification
+         is required. */
+      infof(data, "error setting certificate verify locations,"
+            " continuing anyway:\n");
     }
     else {
       /* Everything is fine. */
@@ -2091,12 +2166,11 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
       failf(data, "error loading CRL file: %s", ssl_crlfile);
       return CURLE_SSL_CRL_BADFILE;
     }
-    else {
-      /* Everything is fine. */
-      infof(data, "successfully load CRL file:\n");
-      X509_STORE_set_flags(SSL_CTX_get_cert_store(connssl->ctx),
-                           X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
-    }
+    /* Everything is fine. */
+    infof(data, "successfully load CRL file:\n");
+    X509_STORE_set_flags(SSL_CTX_get_cert_store(connssl->ctx),
+                         X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
+
     infof(data, "  CRLfile: %s\n", ssl_crlfile);
   }
 
@@ -2161,7 +2235,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
 #endif
 
   /* Check if there's a cached ID we can/should use here! */
-  if(data->set.general_ssl.sessionid) {
+  if(SSL_SET_OPTION(primary.sessionid)) {
     void *ssl_sessionid = NULL;
 
     Curl_ssl_sessionid_lock(conn);
@@ -2170,7 +2244,8 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
       if(!SSL_set_session(connssl->handle, ssl_sessionid)) {
         Curl_ssl_sessionid_unlock(conn);
         failf(data, "SSL: SSL_set_session failed: %s",
-              ERR_error_string(ERR_get_error(), NULL));
+              ossl_strerror(ERR_get_error(), error_buffer,
+                            sizeof(error_buffer)));
         return CURLE_SSL_CONNECT_ERROR;
       }
       /* Informational message */
@@ -2190,7 +2265,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
   else if(!SSL_set_fd(connssl->handle, (int)sockfd)) {
     /* pass the raw socket into the SSL layers */
     failf(data, "SSL: SSL_set_fd failed: %s",
-          ERR_error_string(ERR_get_error(), NULL));
+          ossl_strerror(ERR_get_error(), error_buffer, sizeof(error_buffer)));
     return CURLE_SSL_CONNECT_ERROR;
   }
 
@@ -2224,15 +2299,14 @@ static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex)
       connssl->connecting_state = ssl_connect_2_reading;
       return CURLE_OK;
     }
-    else if(SSL_ERROR_WANT_WRITE == detail) {
+    if(SSL_ERROR_WANT_WRITE == detail) {
       connssl->connecting_state = ssl_connect_2_writing;
       return CURLE_OK;
     }
     else {
       /* untreated error */
       unsigned long errdetail;
-      char error_buffer[256]=""; /* OpenSSL documents that this must be at
-                                    least 256 bytes long. */
+      char error_buffer[256]="";
       CURLcode result;
       long lerr;
       int lib;
@@ -2280,8 +2354,8 @@ static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex)
         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;
-        failf(data, "Unknown SSL protocol error in connection to %s:%ld ",
-              hostname, port);
+        failf(data, OSSL_PACKAGE " SSL_connect: %s in connection to %s:%ld ",
+              SSL_ERROR_to_str(detail), hostname, port);
         return result;
       }
 
@@ -2554,44 +2628,25 @@ static CURLcode get_cert_chain(struct connectdata *conn,
         {
           const BIGNUM *n;
           const BIGNUM *e;
-          const BIGNUM *d;
-          const BIGNUM *p;
-          const BIGNUM *q;
-          const BIGNUM *dmp1;
-          const BIGNUM *dmq1;
-          const BIGNUM *iqmp;
 
-          RSA_get0_key(rsa, &n, &e, &d);
-          RSA_get0_factors(rsa, &p, &q);
-          RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp);
+          RSA_get0_key(rsa, &n, &e, NULL);
           BN_print(mem, n);
           push_certinfo("RSA Public Key", i);
           print_pubkey_BN(rsa, n, i);
           print_pubkey_BN(rsa, e, i);
-          print_pubkey_BN(rsa, d, i);
-          print_pubkey_BN(rsa, p, i);
-          print_pubkey_BN(rsa, q, i);
-          print_pubkey_BN(rsa, dmp1, i);
-          print_pubkey_BN(rsa, dmq1, i);
-          print_pubkey_BN(rsa, iqmp, i);
         }
 #else
         BIO_printf(mem, "%d", BN_num_bits(rsa->n));
         push_certinfo("RSA Public Key", i);
         print_pubkey_BN(rsa, n, i);
         print_pubkey_BN(rsa, e, i);
-        print_pubkey_BN(rsa, d, i);
-        print_pubkey_BN(rsa, p, i);
-        print_pubkey_BN(rsa, q, i);
-        print_pubkey_BN(rsa, dmp1, i);
-        print_pubkey_BN(rsa, dmq1, i);
-        print_pubkey_BN(rsa, iqmp, i);
 #endif
 
         break;
       }
       case EVP_PKEY_DSA:
       {
+#ifndef OPENSSL_NO_DSA
         DSA *dsa;
 #ifdef HAVE_OPAQUE_EVP_PKEY
         dsa = EVP_PKEY_get0_DSA(pubkey);
@@ -2603,25 +2658,23 @@ static CURLcode get_cert_chain(struct connectdata *conn,
           const BIGNUM *p;
           const BIGNUM *q;
           const BIGNUM *g;
-          const BIGNUM *priv_key;
           const BIGNUM *pub_key;
 
           DSA_get0_pqg(dsa, &p, &q, &g);
-          DSA_get0_key(dsa, &pub_key, &priv_key);
+          DSA_get0_key(dsa, &pub_key, NULL);
 
           print_pubkey_BN(dsa, p, i);
           print_pubkey_BN(dsa, q, i);
           print_pubkey_BN(dsa, g, i);
-          print_pubkey_BN(dsa, priv_key, i);
           print_pubkey_BN(dsa, pub_key, i);
         }
 #else
         print_pubkey_BN(dsa, p, i);
         print_pubkey_BN(dsa, q, i);
         print_pubkey_BN(dsa, g, i);
-        print_pubkey_BN(dsa, priv_key, i);
         print_pubkey_BN(dsa, pub_key, i);
 #endif
+#endif /* !OPENSSL_NO_DSA */
         break;
       }
       case EVP_PKEY_DH:
@@ -2637,20 +2690,17 @@ static CURLcode get_cert_chain(struct connectdata *conn,
           const BIGNUM *p;
           const BIGNUM *q;
           const BIGNUM *g;
-          const BIGNUM *priv_key;
           const BIGNUM *pub_key;
           DH_get0_pqg(dh, &p, &q, &g);
-          DH_get0_key(dh, &pub_key, &priv_key);
+          DH_get0_key(dh, &pub_key, NULL);
           print_pubkey_BN(dh, p, i);
           print_pubkey_BN(dh, q, i);
           print_pubkey_BN(dh, g, i);
-          print_pubkey_BN(dh, priv_key, i);
           print_pubkey_BN(dh, pub_key, i);
        }
 #else
         print_pubkey_BN(dh, p, i);
         print_pubkey_BN(dh, g, i);
-        print_pubkey_BN(dh, priv_key, i);
         print_pubkey_BN(dh, pub_key, i);
 #endif
         break;
@@ -2915,7 +2965,7 @@ static CURLcode ossl_connect_step3(struct connectdata *conn, int sockindex)
 
   DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
 
-  if(data->set.general_ssl.sessionid) {
+  if(SSL_SET_OPTION(primary.sessionid)) {
     bool incache;
     SSL_SESSION *our_ssl_sessionid;
     void *old_ssl_sessionid = NULL;
@@ -3037,16 +3087,14 @@ static CURLcode ossl_connect_common(struct connectdata *conn,
         failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
         return CURLE_SSL_CONNECT_ERROR;
       }
-      else if(0 == what) {
+      if(0 == what) {
         if(nonblocking) {
           *done = FALSE;
           return CURLE_OK;
         }
-        else {
-          /* timeout */
-          failf(data, "SSL connection timeout");
-          return CURLE_OPERATION_TIMEDOUT;
-        }
+        /* timeout */
+        failf(data, "SSL connection timeout");
+        return CURLE_OPERATION_TIMEDOUT;
       }
       /* socket is readable or writable */
     }
@@ -3116,8 +3164,7 @@ bool Curl_ossl_data_pending(const struct connectdata *conn, int connindex)
            (conn->proxy_ssl[connindex].handle &&
             0 != SSL_pending(conn->proxy_ssl[connindex].handle))) ?
            TRUE : FALSE;
-  else
-    return FALSE;
+  return FALSE;
 }
 
 static ssize_t ossl_send(struct connectdata *conn,
@@ -3129,8 +3176,7 @@ static ssize_t ossl_send(struct connectdata *conn,
   /* SSL_write() is said to return 'int' while write() and send() returns
      'size_t' */
   int err;
-  char error_buffer[256]; /* OpenSSL documents that this must be at least 256
-                             bytes long. */
+  char error_buffer[256];
   unsigned long sslerror;
   int memlen;
   int rc;
@@ -3176,7 +3222,8 @@ static ssize_t ossl_send(struct connectdata *conn,
       return -1;
     }
     /* a true error */
-    failf(conn->data, "SSL_write() return error %d", err);
+    failf(conn->data, OSSL_PACKAGE " SSL_write: %s, errno %d",
+          SSL_ERROR_to_str(err), SOCKERRNO);
     *curlcode = CURLE_SEND_ERROR;
     return -1;
   }
@@ -3190,8 +3237,7 @@ static ssize_t ossl_recv(struct connectdata *conn, /* connection data */
                          size_t buffersize,        /* max amount to read */
                          CURLcode *curlcode)
 {
-  char error_buffer[256]; /* OpenSSL documents that this must be at
-                             least 256 bytes long. */
+  char error_buffer[256];
   unsigned long sslerror;
   ssize_t nread;
   int buffsize;
@@ -3221,8 +3267,10 @@ static ssize_t ossl_recv(struct connectdata *conn, /* connection data */
       if((nread < 0) || sslerror) {
         /* If the return code was negative or there actually is an error in the
            queue */
-        failf(conn->data, "SSL read: %s, errno %d",
-              ossl_strerror(sslerror, error_buffer, sizeof(error_buffer)),
+        failf(conn->data, OSSL_PACKAGE " SSL_read: %s, errno %d",
+              (sslerror ?
+               ossl_strerror(sslerror, error_buffer, sizeof(error_buffer)) :
+               SSL_ERROR_to_str(err)),
               SOCKERRNO);
         *curlcode = CURLE_RECV_ERROR;
         return -1;
@@ -3272,19 +3320,21 @@ size_t Curl_ossl_version(char *buffer, size_t size)
 }
 
 /* can be called with data == NULL */
-int Curl_ossl_random(struct Curl_easy *data, unsigned char *entropy,
-                     size_t length)
+CURLcode Curl_ossl_random(struct Curl_easy *data, unsigned char *entropy,
+                          size_t length)
 {
+  int rc;
   if(data) {
     if(Curl_ossl_seed(data)) /* Initiate the seed if not already done */
-      return 1; /* couldn't seed for some reason */
+      return CURLE_FAILED_INIT; /* couldn't seed for some reason */
   }
   else {
     if(!rand_enough())
-      return 1;
+      return CURLE_FAILED_INIT;
   }
-  RAND_bytes(entropy, curlx_uztosi(length));
-  return 0; /* 0 as in no problem */
+  /* RAND_bytes() returns 1 on success, 0 otherwise.  */
+  rc = RAND_bytes(entropy, curlx_uztosi(length));
+  return (rc == 1 ? CURLE_OK : CURLE_FAILED_INIT);
 }
 
 void Curl_ossl_md5sum(unsigned char *tmp, /* input */
diff --git a/lib/vtls/openssl.h b/lib/vtls/openssl.h
index cff1e90..b9648d5 100644
--- a/lib/vtls/openssl.h
+++ b/lib/vtls/openssl.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
@@ -66,8 +66,8 @@ bool Curl_ossl_data_pending(const struct connectdata *conn,
                             int connindex);
 
 /* return 0 if a find random is filled in */
-int Curl_ossl_random(struct Curl_easy *data, unsigned char *entropy,
-                     size_t length);
+CURLcode Curl_ossl_random(struct Curl_easy *data, unsigned char *entropy,
+                          size_t length);
 void Curl_ossl_md5sum(unsigned char *tmp, /* input */
                       size_t tmplen,
                       unsigned char *md5sum /* output */,
diff --git a/lib/vtls/polarssl.c b/lib/vtls/polarssl.c
index 4bba3e3..669091c 100644
--- a/lib/vtls/polarssl.c
+++ b/lib/vtls/polarssl.c
@@ -140,6 +140,68 @@ static void polarssl_debug(void *context, int level, const char *line)
 static Curl_recv polarssl_recv;
 static Curl_send polarssl_send;
 
+static CURLcode polarssl_version_from_curl(int *polarver, long ssl_version)
+{
+  switch(ssl_version) {
+    case CURL_SSLVERSION_TLSv1_0:
+      *polarver = SSL_MINOR_VERSION_1;
+      return CURLE_OK;
+    case CURL_SSLVERSION_TLSv1_1:
+      *polarver = SSL_MINOR_VERSION_2;
+      return CURLE_OK;
+    case CURL_SSLVERSION_TLSv1_2:
+      *polarver = SSL_MINOR_VERSION_3;
+      return CURLE_OK;
+    case CURL_SSLVERSION_TLSv1_3:
+      break;
+  }
+  return CURLE_SSL_CONNECT_ERROR;
+}
+
+static CURLcode
+set_ssl_version_min_max(struct connectdata *conn, int sockindex)
+{
+  struct Curl_easy *data = conn->data;
+  struct ssl_connect_data* connssl = &conn->ssl[sockindex];
+  long ssl_version = SSL_CONN_CONFIG(version);
+  long ssl_version_max = SSL_CONN_CONFIG(version_max);
+  int ssl_min_ver = SSL_MINOR_VERSION_1;
+  int ssl_max_ver = SSL_MINOR_VERSION_1;
+  CURLcode result = CURLE_OK;
+
+  switch(ssl_version) {
+    case CURL_SSLVERSION_DEFAULT:
+    case CURL_SSLVERSION_TLSv1:
+      ssl_version = CURL_SSLVERSION_TLSv1_0;
+      ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2;
+      break;
+  }
+
+  switch(ssl_version_max) {
+    case CURL_SSLVERSION_MAX_NONE:
+      ssl_version_max = ssl_version << 16;
+      break;
+    case CURL_SSLVERSION_MAX_DEFAULT:
+      ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2;
+      break;
+  }
+
+  result = polarssl_version_from_curl(&ssl_min_ver, ssl_version);
+  if(result) {
+    failf(data, "unsupported min version passed via CURLOPT_SSLVERSION");
+    return result;
+  }
+  result = polarssl_version_from_curl(&ssl_max_ver, ssl_version_max >> 16);
+  if(result) {
+    failf(data, "unsupported max version passed via CURLOPT_SSLVERSION");
+    return result;
+  }
+
+  ssl_set_min_version(&connssl->ssl, SSL_MAJOR_VERSION_3, ssl_min_ver);
+  ssl_set_max_version(&connssl->ssl, SSL_MAJOR_VERSION_3, ssl_max_ver);
+
+  return result;
+}
 
 static CURLcode
 polarssl_connect_step1(struct connectdata *conn,
@@ -287,29 +349,15 @@ polarssl_connect_step1(struct connectdata *conn,
     infof(data, "PolarSSL: Forced min. SSL Version to be SSLv3\n");
     break;
   case CURL_SSLVERSION_TLSv1_0:
-    ssl_set_min_version(&connssl->ssl, SSL_MAJOR_VERSION_3,
-                        SSL_MINOR_VERSION_1);
-    ssl_set_max_version(&connssl->ssl, SSL_MAJOR_VERSION_3,
-                        SSL_MINOR_VERSION_1);
-    infof(data, "PolarSSL: Forced min. SSL Version to be TLS 1.0\n");
-    break;
   case CURL_SSLVERSION_TLSv1_1:
-    ssl_set_min_version(&connssl->ssl, SSL_MAJOR_VERSION_3,
-                        SSL_MINOR_VERSION_2);
-    ssl_set_max_version(&connssl->ssl, SSL_MAJOR_VERSION_3,
-                        SSL_MINOR_VERSION_2);
-    infof(data, "PolarSSL: Forced min. SSL Version to be TLS 1.1\n");
-    break;
   case CURL_SSLVERSION_TLSv1_2:
-    ssl_set_min_version(&connssl->ssl, SSL_MAJOR_VERSION_3,
-                        SSL_MINOR_VERSION_3);
-    ssl_set_max_version(&connssl->ssl, SSL_MAJOR_VERSION_3,
-                        SSL_MINOR_VERSION_3);
-    infof(data, "PolarSSL: Forced min. SSL Version to be TLS 1.2\n");
-    break;
   case CURL_SSLVERSION_TLSv1_3:
-    failf(data, "PolarSSL: TLS 1.3 is not yet supported");
-    return CURLE_SSL_CONNECT_ERROR;
+    {
+      CURLcode result = set_ssl_version_min_max(conn, sockindex);
+      if(result != CURLE_OK)
+        return result;
+      break;
+    }
   default:
     failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
     return CURLE_SSL_CONNECT_ERROR;
@@ -327,7 +375,7 @@ polarssl_connect_step1(struct connectdata *conn,
   ssl_set_ciphersuites(&connssl->ssl, ssl_list_ciphersuites());
 
   /* Check if there's a cached ID we can/should use here! */
-  if(data->set.general_ssl.sessionid) {
+  if(SSL_SET_OPTION(primary.sessionid)) {
     void *old_session = NULL;
 
     Curl_ssl_sessionid_lock(conn);
@@ -555,7 +603,7 @@ polarssl_connect_step3(struct connectdata *conn,
 
   DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
 
-  if(data->set.general_ssl.sessionid) {
+  if(SSL_SET_OPTION(primary.sessionid)) {
     int ret;
     ssl_session *our_ssl_sessionid;
     void *old_ssl_sessionid = NULL;
@@ -564,7 +612,7 @@ polarssl_connect_step3(struct connectdata *conn,
     if(!our_ssl_sessionid)
       return CURLE_OUT_OF_MEMORY;
 
-    ssl_session_init(our_ssl_sessionid);
+    memset(our_ssl_sessionid, 0, sizeof(ssl_session));
 
     ret = ssl_get_session(&connssl->ssl, our_ssl_sessionid);
     if(ret) {
@@ -816,4 +864,10 @@ void Curl_polarssl_cleanup(void)
   (void)Curl_polarsslthreadlock_thread_cleanup();
 }
 
+
+int Curl_polarssl_data_pending(const struct connectdata *conn, int sockindex)
+{
+  return ssl_get_bytes_avail(&conn->ssl[sockindex].ssl) != 0;
+}
+
 #endif /* USE_POLARSSL */
diff --git a/lib/vtls/polarssl.h b/lib/vtls/polarssl.h
index 7098b24..47af7b4 100644
--- a/lib/vtls/polarssl.h
+++ b/lib/vtls/polarssl.h
@@ -31,6 +31,7 @@
 /* Called on first use PolarSSL, setup threading if supported */
 int  Curl_polarssl_init(void);
 void Curl_polarssl_cleanup(void);
+int Curl_polarssl_data_pending(const struct connectdata *conn, int sockindex);
 
 
 CURLcode Curl_polarssl_connect(struct connectdata *conn, int sockindex);
@@ -69,7 +70,7 @@ int Curl_polarssl_shutdown(struct connectdata *conn, int sockindex);
 #define curlssl_engines_list(x) ((void)x, (struct curl_slist *)NULL)
 #define curlssl_version Curl_polarssl_version
 #define curlssl_check_cxn(x) ((void)x, -1)
-#define curlssl_data_pending(x,y) ((void)x, (void)y, 0)
+#define curlssl_data_pending(x,y) Curl_polarssl_data_pending(x, y)
 #define curlssl_sha256sum(a,b,c,d) sha256(a,b,c,0)
 
 /* This might cause libcurl to use a weeker random!
diff --git a/lib/vtls/schannel.c b/lib/vtls/schannel.c
index ac8b705..c9b5132 100644
--- a/lib/vtls/schannel.c
+++ b/lib/vtls/schannel.c
@@ -7,7 +7,7 @@
  *
  * Copyright (C) 2012 - 2016, Marc Hoersken, <info at marc-hoersken.de>
  * Copyright (C) 2012, Mark Salisbury, <mark.salisbury at hp.com>
- * Copyright (C) 2012 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 2012 - 2017, Daniel Stenberg, <daniel at 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
@@ -103,6 +103,41 @@ static void InitSecBufferDesc(SecBufferDesc *desc, SecBuffer *BufArr,
 }
 
 static CURLcode
+set_ssl_version_min_max(SCHANNEL_CRED *schannel_cred, struct connectdata *conn)
+{
+  struct Curl_easy *data = conn->data;
+  long ssl_version = SSL_CONN_CONFIG(version);
+  long ssl_version_max = SSL_CONN_CONFIG(version_max);
+  long i = ssl_version;
+
+  switch(ssl_version_max) {
+    case CURL_SSLVERSION_MAX_NONE:
+      ssl_version_max = ssl_version << 16;
+      break;
+    case CURL_SSLVERSION_MAX_DEFAULT:
+      ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2;
+      break;
+  }
+  for(; i <= (ssl_version_max >> 16); ++i) {
+    switch(i) {
+      case CURL_SSLVERSION_TLSv1_0:
+        schannel_cred->grbitEnabledProtocols |= SP_PROT_TLS1_0_CLIENT;
+        break;
+      case CURL_SSLVERSION_TLSv1_1:
+        schannel_cred->grbitEnabledProtocols |= SP_PROT_TLS1_1_CLIENT;
+        break;
+      case CURL_SSLVERSION_TLSv1_2:
+        schannel_cred->grbitEnabledProtocols |= SP_PROT_TLS1_2_CLIENT;
+        break;
+      case CURL_SSLVERSION_TLSv1_3:
+        failf(data, "Schannel: TLS 1.3 is not yet supported");
+        return CURLE_SSL_CONNECT_ERROR;
+    }
+  }
+  return CURLE_OK;
+}
+
+static CURLcode
 schannel_connect_step1(struct connectdata *conn, int sockindex)
 {
   ssize_t written = -1;
@@ -124,12 +159,20 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
 #endif
   TCHAR *host_name;
   CURLcode result;
-  const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
+  char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
     conn->host.name;
 
   infof(data, "schannel: SSL/TLS connection with %s port %hu (step 1/3)\n",
         hostname, conn->remote_port);
 
+  if(Curl_verify_windows_version(5, 1, PLATFORM_WINNT,
+                                 VERSION_LESS_THAN_EQUAL)) {
+     /* SChannel in Windows XP (OS version 5.1) uses legacy handshakes and
+        algorithms that may not be supported by all servers. */
+     infof(data, "schannel: WinSSL version is old and may not be able to "
+           "connect to some servers due to lack of SNI, algorithms, etc.\n");
+  }
+
 #ifdef HAS_ALPN
   /* ALPN is only supported on Windows 8.1 / Server 2012 R2 and above.
      Also it doesn't seem to be supported for Wine, see curl bug #983. */
@@ -145,7 +188,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
   connssl->cred = NULL;
 
   /* check for an existing re-usable credential handle */
-  if(data->set.general_ssl.sessionid) {
+  if(SSL_SET_OPTION(primary.sessionid)) {
     Curl_ssl_sessionid_lock(conn);
     if(!Curl_ssl_getsessionid(conn, (void **)&old_cred, NULL, sockindex)) {
       connssl->cred = old_cred;
@@ -197,7 +240,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
       schannel_cred.dwFlags |= SCH_CRED_NO_SERVERNAME_CHECK;
       infof(data, "schannel: verifyhost setting prevents Schannel from "
             "comparing the supplied target name with the subject "
-            "names in server certificates. Also disables SNI.\n");
+            "names in server certificates.\n");
     }
 
     switch(conn->ssl_config.version) {
@@ -208,17 +251,15 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
         SP_PROT_TLS1_2_CLIENT;
       break;
     case CURL_SSLVERSION_TLSv1_0:
-      schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1_0_CLIENT;
-      break;
     case CURL_SSLVERSION_TLSv1_1:
-      schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1_1_CLIENT;
-      break;
     case CURL_SSLVERSION_TLSv1_2:
-      schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1_2_CLIENT;
-      break;
     case CURL_SSLVERSION_TLSv1_3:
-      failf(data, "Schannel: TLS 1.3 is not yet supported");
-      return CURLE_SSL_CONNECT_ERROR;
+      {
+        result = set_ssl_version_min_max(&schannel_cred, conn);
+        if(result != CURLE_OK)
+          return result;
+        break;
+      }
     case CURL_SSLVERSION_SSLv3:
       schannel_cred.grbitEnabledProtocols = SP_PROT_SSL3_CLIENT;
       break;
@@ -415,7 +456,7 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
   TCHAR *host_name;
   CURLcode result;
   bool doread;
-  const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
+  char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
     conn->host.name;
 
   doread = (connssl->connecting_state != ssl_connect_2_writing) ? TRUE : FALSE;
@@ -649,8 +690,10 @@ schannel_connect_step3(struct connectdata *conn, int sockindex)
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
   SECURITY_STATUS sspi_status = SEC_E_OK;
   CERT_CONTEXT *ccert_context = NULL;
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
   const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
     conn->host.name;
+#endif
 #ifdef HAS_ALPN
   SecPkgContext_ApplicationProtocol alpn_result;
 #endif
@@ -714,7 +757,7 @@ schannel_connect_step3(struct connectdata *conn, int sockindex)
 #endif
 
   /* save the current session data for possible re-use */
-  if(data->set.general_ssl.sessionid) {
+  if(SSL_SET_OPTION(primary.sessionid)) {
     bool incache;
     struct curl_schannel_cred *old_cred = NULL;
 
@@ -1391,7 +1434,7 @@ int Curl_schannel_shutdown(struct connectdata *conn, int sockindex)
    */
   struct Curl_easy *data = conn->data;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-  const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
+  char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
     conn->host.name;
 
   infof(data, "schannel: shutting down SSL/TLS connection with %s port %hu\n",
@@ -1516,21 +1559,21 @@ size_t Curl_schannel_version(char *buffer, size_t size)
   return size;
 }
 
-int Curl_schannel_random(unsigned char *entropy, size_t length)
+CURLcode Curl_schannel_random(unsigned char *entropy, size_t length)
 {
   HCRYPTPROV hCryptProv = 0;
 
   if(!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL,
                           CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
-    return 1;
+    return CURLE_FAILED_INIT;
 
   if(!CryptGenRandom(hCryptProv, (DWORD)length, entropy)) {
     CryptReleaseContext(hCryptProv, 0UL);
-    return 1;
+    return CURLE_FAILED_INIT;
   }
 
   CryptReleaseContext(hCryptProv, 0UL);
-  return 0;
+  return CURLE_OK;
 }
 
 #ifdef _WIN32_WCE
diff --git a/lib/vtls/schannel.h b/lib/vtls/schannel.h
index 8a4991e..8627c63 100644
--- a/lib/vtls/schannel.h
+++ b/lib/vtls/schannel.h
@@ -8,7 +8,7 @@
  *                             \___|\___/|_| \_\_____|
  *
  * Copyright (C) 2012, Marc Hoersken, <info at marc-hoersken.de>, et al.
- * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 2012 - 2017, Daniel Stenberg, <daniel at 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
@@ -92,7 +92,7 @@ int Curl_schannel_init(void);
 void Curl_schannel_cleanup(void);
 size_t Curl_schannel_version(char *buffer, size_t size);
 
-int Curl_schannel_random(unsigned char *entropy, size_t length);
+CURLcode Curl_schannel_random(unsigned char *entropy, size_t length);
 
 /* Set the API backend definition to Schannel */
 #define CURL_SSL_BACKEND CURLSSLBACKEND_SCHANNEL
diff --git a/lib/vtls/vtls.c b/lib/vtls/vtls.c
index b808e1c..d5d0971 100644
--- a/lib/vtls/vtls.c
+++ b/lib/vtls/vtls.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
@@ -95,6 +95,7 @@ Curl_ssl_config_matches(struct ssl_primary_config* data,
                         struct ssl_primary_config* needle)
 {
   if((data->version == needle->version) &&
+     (data->version_max == needle->version_max) &&
      (data->verifypeer == needle->verifypeer) &&
      (data->verifyhost == needle->verifyhost) &&
      Curl_safe_strcasecompare(data->CApath, needle->CApath) &&
@@ -113,6 +114,7 @@ Curl_clone_primary_ssl_config(struct ssl_primary_config *source,
   dest->verifyhost = source->verifyhost;
   dest->verifypeer = source->verifypeer;
   dest->version = source->version;
+  dest->version_max = source->version_max;
 
   CLONE_STRING(CAfile);
   CLONE_STRING(CApath);
@@ -120,6 +122,9 @@ Curl_clone_primary_ssl_config(struct ssl_primary_config *source,
   CLONE_STRING(egdsocket);
   CLONE_STRING(random_file);
   CLONE_STRING(clientcert);
+
+  /* Disable dest sessionid cache if a client cert is used, CVE-2016-5419. */
+  dest->sessionid = (dest->clientcert ? false : source->sessionid);
   return TRUE;
 }
 
@@ -173,11 +178,24 @@ void Curl_ssl_cleanup(void)
 static bool ssl_prefs_check(struct Curl_easy *data)
 {
   /* check for CURLOPT_SSLVERSION invalid parameter value */
-  if((data->set.ssl.primary.version < 0)
-     || (data->set.ssl.primary.version >= CURL_SSLVERSION_LAST)) {
+  const long sslver = data->set.ssl.primary.version;
+  if((sslver < 0) || (sslver >= CURL_SSLVERSION_LAST)) {
     failf(data, "Unrecognized parameter value passed via CURLOPT_SSLVERSION");
     return FALSE;
   }
+
+  switch(data->set.ssl.primary.version_max) {
+  case CURL_SSLVERSION_MAX_NONE:
+  case CURL_SSLVERSION_MAX_DEFAULT:
+    break;
+
+  default:
+    if((data->set.ssl.primary.version_max >> 16) < sslver) {
+      failf(data, "CURL_SSLVERSION_MAX incompatible with CURL_SSLVERSION");
+      return FALSE;
+    }
+  }
+
   return TRUE;
 }
 
@@ -286,16 +304,16 @@ bool Curl_ssl_getsessionid(struct connectdata *conn,
 
   const bool isProxy = CONNECT_PROXY_SSL();
   struct ssl_primary_config * const ssl_config = isProxy ?
-                                                 &conn->proxy_ssl_config :
-                                                 &conn->ssl_config;
+    &conn->proxy_ssl_config :
+    &conn->ssl_config;
   const char * const name = isProxy ? conn->http_proxy.host.name :
-                                      conn->host.name;
+    conn->host.name;
   int port = isProxy ? (int)conn->port : conn->remote_port;
   *ssl_sessionid = NULL;
 
-  DEBUGASSERT(data->set.general_ssl.sessionid);
+  DEBUGASSERT(SSL_SET_OPTION(primary.sessionid));
 
-  if(!data->set.general_ssl.sessionid)
+  if(!SSL_SET_OPTION(primary.sessionid))
     /* session ID re-use is disabled */
     return TRUE;
 
@@ -394,10 +412,10 @@ CURLcode Curl_ssl_addsessionid(struct connectdata *conn,
   long *general_age;
   const bool isProxy = CONNECT_PROXY_SSL();
   struct ssl_primary_config * const ssl_config = isProxy ?
-                                           &conn->proxy_ssl_config :
-                                           &conn->ssl_config;
+    &conn->proxy_ssl_config :
+    &conn->ssl_config;
 
-  DEBUGASSERT(data->set.general_ssl.sessionid);
+  DEBUGASSERT(SSL_SET_OPTION(primary.sessionid));
 
   clone_host = strdup(isProxy ? conn->http_proxy.host.name : conn->host.name);
   if(!clone_host)
@@ -447,7 +465,7 @@ CURLcode Curl_ssl_addsessionid(struct connectdata *conn,
   store->sessionid = ssl_sessionid;
   store->idsize = idsize;
   store->age = *general_age;    /* set current age */
-    /* free it if there's one already present */
+  /* free it if there's one already present */
   free(store->name);
   free(store->conn_to_host);
   store->name = clone_host;               /* clone host name */
@@ -484,9 +502,9 @@ void Curl_ssl_close_all(struct Curl_easy *data)
   curlssl_close_all(data);
 }
 
-#if defined(USE_SSLEAY) || defined(USE_GNUTLS) || defined(USE_SCHANNEL) || \
-    defined(USE_DARWINSSL) || defined(USE_NSS)
-/* This function is for OpenSSL, GnuTLS, darwinssl, and schannel only. */
+#if defined(USE_OPENSSL) || defined(USE_GNUTLS) || defined(USE_SCHANNEL) || \
+  defined(USE_DARWINSSL) || defined(USE_POLARSSL) || defined(USE_NSS) || \
+  defined(USE_MBEDTLS)
 int Curl_ssl_getsock(struct connectdata *conn, curl_socket_t *socks,
                      int numsocks)
 {
@@ -500,7 +518,7 @@ int Curl_ssl_getsock(struct connectdata *conn, curl_socket_t *socks,
     socks[0] = conn->sock[FIRSTSOCKET];
     return GETSOCK_WRITESOCK(0);
   }
-  else if(connssl->connecting_state == ssl_connect_2_reading) {
+  if(connssl->connecting_state == ssl_connect_2_reading) {
     /* read mode */
     socks[0] = conn->sock[FIRSTSOCKET];
     return GETSOCK_READSOCK(0);
@@ -510,15 +528,15 @@ int Curl_ssl_getsock(struct connectdata *conn, curl_socket_t *socks,
 }
 #else
 int Curl_ssl_getsock(struct connectdata *conn,
-                          curl_socket_t *socks,
-                          int numsocks)
+                     curl_socket_t *socks,
+                     int numsocks)
 {
   (void)conn;
   (void)socks;
   (void)numsocks;
   return GETSOCK_BLANK;
 }
-/* USE_SSLEAY || USE_GNUTLS || USE_SCHANNEL || USE_DARWINSSL || USE_NSS */
+/* USE_OPENSSL || USE_GNUTLS || USE_SCHANNEL || USE_DARWINSSL || USE_NSS */
 #endif
 
 void Curl_ssl_close(struct connectdata *conn, int sockindex)
@@ -703,12 +721,7 @@ CURLcode Curl_ssl_random(struct Curl_easy *data,
                          unsigned char *entropy,
                          size_t length)
 {
-  int rc = curlssl_random(data, entropy, length);
-  if(rc) {
-    failf(data, "PRNG seeding failed");
-    return CURLE_FAILED_INIT; /* possibly weird return code */
-  }
-  return CURLE_OK;
+  return curlssl_random(data, entropy, length);
 }
 
 /*
diff --git a/lib/warnless.c b/lib/warnless.c
index 0c4472e..fb085c8 100644
--- a/lib/warnless.c
+++ b/lib/warnless.c
@@ -183,12 +183,15 @@ curl_off_t curlx_uztoso(size_t uznum)
 #ifdef __INTEL_COMPILER
 #  pragma warning(push)
 #  pragma warning(disable:810) /* conversion may lose significant bits */
+#elif defined(_MSC_VER)
+#  pragma warning(push)
+#  pragma warning(disable:4310) /* cast truncates constant value */
 #endif
 
   DEBUGASSERT(uznum <= (size_t) CURL_MASK_SCOFFT);
   return (curl_off_t)(uznum & (size_t) CURL_MASK_SCOFFT);
 
-#ifdef __INTEL_COMPILER
+#if defined(__INTEL_COMPILER) || defined(_MSC_VER)
 #  pragma warning(pop)
 #endif
 }
diff --git a/lib/wildcard.c b/lib/wildcard.c
index dbbe45f..af45c79 100644
--- a/lib/wildcard.c
+++ b/lib/wildcard.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel at 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
@@ -32,13 +32,9 @@
 
 CURLcode Curl_wildcard_init(struct WildcardData *wc)
 {
-  DEBUGASSERT(wc->filelist == NULL);
-  /* now allocate only wc->filelist, everything else
-     will be allocated if it is needed. */
-  wc->filelist = Curl_llist_alloc(Curl_fileinfo_dtor);
-  if(!wc->filelist) {;
-    return CURLE_OUT_OF_MEMORY;
-  }
+  Curl_llist_init(&wc->filelist, Curl_fileinfo_dtor);
+  wc->state = CURLWC_INIT;
+
   return CURLE_OK;
 }
 
@@ -54,10 +50,8 @@ void Curl_wildcard_dtor(struct WildcardData *wc)
   }
   DEBUGASSERT(wc->tmp == NULL);
 
-  if(wc->filelist) {
-    Curl_llist_destroy(wc->filelist, NULL);
-    wc->filelist = NULL;
-  }
+  Curl_llist_destroy(&wc->filelist, NULL);
+
 
   free(wc->path);
   wc->path = NULL;
diff --git a/lib/wildcard.h b/lib/wildcard.h
index 7f61cd1..8a5e4b7 100644
--- a/lib/wildcard.h
+++ b/lib/wildcard.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2010 - 2013, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 2010 - 2017, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -24,9 +24,12 @@
 
 #include <curl/curl.h>
 
+#include "llist.h"
+
 /* list of wildcard process states */
 typedef enum {
-  CURLWC_INIT = 0,
+  CURLWC_CLEAR = 0,
+  CURLWC_INIT = 1,
   CURLWC_MATCHING, /* library is trying to get list of addresses for
                       downloading */
   CURLWC_DOWNLOADING,
@@ -44,7 +47,7 @@ struct WildcardData {
   curl_wildcard_states state;
   char *path; /* path to the directory, where we trying wildcard-match */
   char *pattern; /* wildcard pattern */
-  struct curl_llist *filelist; /* llist with struct Curl_fileinfo */
+  struct curl_llist filelist; /* llist with struct Curl_fileinfo */
   void *tmp; /* pointer to protocol specific temporary data */
   curl_wildcard_tmp_dtor tmp_dtor;
   void *customptr;  /* for CURLOPT_CHUNK_DATA pointer */

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=5af9c8e2451afd8e63d6b05e69cd141af543a164
commit 5af9c8e2451afd8e63d6b05e69cd141af543a164
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Thu May 11 10:47:38 2017 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Thu May 11 11:26:18 2017 -0400

    curl: Update script to get curl 7.54.0

diff --git a/Utilities/Scripts/update-curl.bash b/Utilities/Scripts/update-curl.bash
index 9cff7ca..d270d37 100755
--- a/Utilities/Scripts/update-curl.bash
+++ b/Utilities/Scripts/update-curl.bash
@@ -8,7 +8,7 @@ readonly name="curl"
 readonly ownership="Curl Upstream <curl-library at cool.haxx.se>"
 readonly subtree="Utilities/cmcurl"
 readonly repo="https://github.com/curl/curl.git"
-readonly tag="curl-7_52_1"
+readonly tag="curl-7_54_0"
 readonly shortlog=false
 readonly paths="
   CMake/*
@@ -32,6 +32,7 @@ extract_source () {
     git_archive
     pushd "${extractdir}/${name}-reduced"
     rm lib/config-*.h
+    echo "* -whitespace" > .gitattributes
     popd
 }
 

-----------------------------------------------------------------------

Summary of changes:
 Modules/Compiler/NVIDIA-CUDA.cmake                |    6 +
 Modules/Compiler/SunPro-C-FeatureTests.cmake      |   14 +
 Modules/Compiler/SunPro-C.cmake                   |   15 +
 Modules/GetPrerequisites.cmake                    |    6 +-
 Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h |    8 -
 Source/CTest/cmCTestHandlerCommand.h              |    5 +
 Source/CTest/cmCTestMemCheckCommand.cxx           |    1 +
 Source/CTest/cmCTestMemCheckCommand.h             |    7 -
 Source/CTest/cmCTestReadCustomFilesCommand.h      |    5 -
 Source/CTest/cmCTestRunScriptCommand.h            |    5 -
 Source/CTest/cmCTestScriptHandler.cxx             |   41 +-
 Source/CTest/cmCTestScriptHandler.h               |    2 +-
 Source/CTest/cmCTestSleepCommand.h                |    5 -
 Source/CTest/cmCTestStartCommand.h                |    5 -
 Source/CTest/cmCTestTestHandler.cxx               |   30 +-
 Source/cmAddCompileOptionsCommand.h               |    5 -
 Source/cmAddCustomCommandCommand.h                |    5 -
 Source/cmAddCustomTargetCommand.h                 |    5 -
 Source/cmAddDefinitionsCommand.h                  |    5 -
 Source/cmAddDependenciesCommand.h                 |    5 -
 Source/cmAddExecutableCommand.h                   |    5 -
 Source/cmAddLibraryCommand.h                      |    5 -
 Source/cmAddSubDirectoryCommand.h                 |    5 -
 Source/cmAddTestCommand.h                         |    5 -
 Source/cmAuxSourceDirectoryCommand.h              |    5 -
 Source/cmBreakCommand.h                           |    5 -
 Source/cmBuildCommand.h                           |    5 -
 Source/cmBuildNameCommand.h                       |    1 -
 Source/cmCMakeHostSystemInformationCommand.h      |    8 -
 Source/cmCMakeMinimumRequired.h                   |    5 -
 Source/cmCMakePolicyCommand.h                     |    5 -
 Source/cmCommand.h                                |   11 -
 Source/cmCommands.cxx                             |  288 +++++----
 Source/cmConfigureFileCommand.h                   |    5 -
 Source/cmContinueCommand.h                        |    5 -
 Source/cmCreateTestSourceList.h                   |    5 -
 Source/cmDefinePropertyCommand.h                  |    5 -
 Source/cmDisallowedCommand.h                      |    2 -
 Source/cmEnableLanguageCommand.h                  |    5 -
 Source/cmEnableTestingCommand.h                   |    5 -
 Source/cmExecProgramCommand.h                     |    5 -
 Source/cmExecuteProcessCommand.h                  |    5 -
 Source/cmExportCommand.h                          |    5 -
 Source/cmExportLibraryDependenciesCommand.h       |    4 -
 Source/cmFLTKWrapUICommand.h                      |    5 -
 Source/cmFileCommand.h                            |    5 -
 Source/cmFindFileCommand.h                        |    3 -
 Source/cmFindLibraryCommand.h                     |    5 -
 Source/cmFindPackageCommand.h                     |    5 -
 Source/cmFindPathCommand.h                        |    5 -
 Source/cmFindProgramCommand.h                     |    5 -
 Source/cmForEachCommand.h                         |    5 -
 Source/cmFunctionCommand.cxx                      |   16 +-
 Source/cmFunctionCommand.h                        |    5 -
 Source/cmGetCMakePropertyCommand.h                |    5 -
 Source/cmGetDirectoryPropertyCommand.h            |    5 -
 Source/cmGetFilenameComponentCommand.h            |    5 -
 Source/cmGetPropertyCommand.h                     |    5 -
 Source/cmGetSourceFilePropertyCommand.h           |    8 -
 Source/cmGetTargetPropertyCommand.h               |    5 -
 Source/cmGetTestPropertyCommand.h                 |    5 -
 Source/cmIfCommand.h                              |    5 -
 Source/cmIncludeCommand.h                         |    5 -
 Source/cmIncludeDirectoryCommand.h                |    5 -
 Source/cmIncludeExternalMSProjectCommand.h        |    8 -
 Source/cmIncludeRegularExpressionCommand.h        |    8 -
 Source/cmInstallCommand.h                         |    5 -
 Source/cmInstallFilesCommand.h                    |    5 -
 Source/cmInstallProgramsCommand.h                 |    5 -
 Source/cmInstallTargetsCommand.h                  |    5 -
 Source/cmLinkDirectoriesCommand.h                 |    5 -
 Source/cmLinkLibrariesCommand.h                   |    5 -
 Source/cmListCommand.h                            |    5 -
 Source/cmLoadCacheCommand.h                       |    5 -
 Source/cmLoadCommandCommand.cxx                   |    7 +-
 Source/cmLoadCommandCommand.h                     |    1 -
 Source/cmLocalGenerator.cxx                       |    1 +
 Source/cmMacroCommand.cxx                         |   15 +-
 Source/cmMacroCommand.h                           |    5 -
 Source/cmMakeDirectoryCommand.h                   |    5 -
 Source/cmMarkAsAdvancedCommand.h                  |    5 -
 Source/cmMathCommand.h                            |    5 -
 Source/cmMessageCommand.h                         |    5 -
 Source/cmOptionCommand.h                          |    5 -
 Source/cmOutputRequiredFilesCommand.h             |    1 -
 Source/cmParseArgumentsCommand.h                  |    5 -
 Source/cmProjectCommand.h                         |    5 -
 Source/cmQTWrapCPPCommand.h                       |    5 -
 Source/cmQTWrapUICommand.h                        |    5 -
 Source/cmRemoveCommand.h                          |    5 -
 Source/cmRemoveDefinitionsCommand.h               |    5 -
 Source/cmReturnCommand.h                          |    5 -
 Source/cmSeparateArgumentsCommand.h               |    5 -
 Source/cmSetCommand.h                             |    5 -
 Source/cmSetDirectoryPropertiesCommand.h          |    8 -
 Source/cmSetPropertyCommand.h                     |    5 -
 Source/cmSetSourceFilesPropertiesCommand.h        |    8 -
 Source/cmSetTargetPropertiesCommand.h             |    5 -
 Source/cmSetTestsPropertiesCommand.h              |    5 -
 Source/cmSiteNameCommand.h                        |    5 -
 Source/cmSourceGroupCommand.h                     |    5 -
 Source/cmState.cxx                                |  117 ++--
 Source/cmState.h                                  |   11 +-
 Source/cmStringCommand.h                          |    5 -
 Source/cmSubdirCommand.h                          |    5 -
 Source/cmSubdirDependsCommand.h                   |    1 -
 Source/cmTargetCompileDefinitionsCommand.h        |    8 -
 Source/cmTargetCompileFeaturesCommand.h           |    2 -
 Source/cmTargetCompileOptionsCommand.h            |    5 -
 Source/cmTargetIncludeDirectoriesCommand.h        |    8 -
 Source/cmTargetLinkLibrariesCommand.h             |    5 -
 Source/cmTargetSourcesCommand.h                   |    5 -
 Source/cmTryCompileCommand.h                      |    5 -
 Source/cmTryRunCommand.h                          |    5 -
 Source/cmUnexpectedCommand.h                      |    2 -
 Source/cmUnsetCommand.h                           |    5 -
 Source/cmUseMangledMesaCommand.h                  |    2 +-
 Source/cmUtilitySourceCommand.h                   |    1 -
 Source/cmVariableRequiresCommand.h                |    1 -
 Source/cmVariableWatchCommand.h                   |    5 -
 Source/cmWhileCommand.h                           |    5 -
 Source/cmWriteFileCommand.h                       |    5 -
 Source/cmakemain.cxx                              |    4 +-
 Tests/CompileFeatures/CMakeLists.txt              |   10 +
 Tests/CompileFeatures/default_dialect.c           |    3 +-
 Utilities/Scripts/update-curl.bash                |    3 +-
 Utilities/cmcurl/CMake/CurlTests.c                |   16 +
 Utilities/cmcurl/CMake/FindGSS.cmake              |    2 +-
 Utilities/cmcurl/CMake/FindMbedTLS.cmake          |   13 +
 Utilities/cmcurl/CMake/Utilities.cmake            |   13 +
 Utilities/cmcurl/CMakeLists.txt                   |  215 +++---
 Utilities/cmcurl/COPYING                          |    2 +-
 Utilities/cmcurl/include/curl/curl.h              |   32 +-
 Utilities/cmcurl/include/curl/curlrules.h         |   25 +-
 Utilities/cmcurl/include/curl/curlver.h           |   12 +-
 Utilities/cmcurl/include/curl/system.h            |  484 ++++++++++++++
 Utilities/cmcurl/include/curl/typecheck-gcc.h     |    3 +-
 Utilities/cmcurl/lib/asyn-ares.c                  |   31 +-
 Utilities/cmcurl/lib/conncache.c                  |   55 +-
 Utilities/cmcurl/lib/conncache.h                  |    4 +-
 Utilities/cmcurl/lib/connect.c                    |    5 +-
 Utilities/cmcurl/lib/connect.h                    |    6 +-
 Utilities/cmcurl/lib/content_encoding.c           |    5 +-
 Utilities/cmcurl/lib/cookie.c                     |   50 +-
 Utilities/cmcurl/lib/curl_addrinfo.c              |   32 +-
 Utilities/cmcurl/lib/curl_addrinfo.h              |    2 +-
 Utilities/cmcurl/lib/curl_config.h.cmake          |   12 +
 Utilities/cmcurl/lib/curl_des.c                   |    2 +-
 Utilities/cmcurl/lib/curl_fnmatch.c               |    8 +-
 Utilities/cmcurl/lib/curl_memory.h                |    4 +-
 Utilities/cmcurl/lib/curl_ntlm_core.c             |   12 +-
 Utilities/cmcurl/lib/curl_ntlm_core.h             |   27 +-
 Utilities/cmcurl/lib/curl_ntlm_wb.c               |    2 +-
 Utilities/cmcurl/lib/curl_sasl.c                  |    2 +-
 Utilities/cmcurl/lib/curl_setup.h                 |   13 +-
 Utilities/cmcurl/lib/dict.c                       |    2 +-
 Utilities/cmcurl/lib/easy.c                       |   58 +-
 Utilities/cmcurl/lib/escape.c                     |    4 +-
 Utilities/cmcurl/lib/file.c                       |    8 +-
 Utilities/cmcurl/lib/formdata.c                   |  120 ++--
 Utilities/cmcurl/lib/ftp.c                        |  112 ++--
 Utilities/cmcurl/lib/ftplistparser.c              |   10 +-
 Utilities/cmcurl/lib/gopher.c                     |    6 +-
 Utilities/cmcurl/lib/hash.c                       |   68 +-
 Utilities/cmcurl/lib/hash.h                       |    6 +-
 Utilities/cmcurl/lib/hostcheck.c                  |    2 +-
 Utilities/cmcurl/lib/hostip.c                     |    6 +-
 Utilities/cmcurl/lib/hostip.h                     |    4 +-
 Utilities/cmcurl/lib/http.c                       |  123 ++--
 Utilities/cmcurl/lib/http.h                       |    4 +
 Utilities/cmcurl/lib/http2.c                      |   98 +--
 Utilities/cmcurl/lib/http_ntlm.c                  |    2 +-
 Utilities/cmcurl/lib/http_proxy.c                 |   97 +--
 Utilities/cmcurl/lib/imap.c                       |    9 +-
 Utilities/cmcurl/lib/libcurl.rc                   |    4 +-
 Utilities/cmcurl/lib/llist.c                      |   22 +-
 Utilities/cmcurl/lib/llist.h                      |    4 +-
 Utilities/cmcurl/lib/memdebug.c                   |    4 +-
 Utilities/cmcurl/lib/mprintf.c                    |    6 +-
 Utilities/cmcurl/lib/multi.c                      |  257 ++++----
 Utilities/cmcurl/lib/multihandle.h                |   16 +-
 Utilities/cmcurl/lib/nonblock.c                   |    3 +-
 Utilities/cmcurl/lib/pingpong.c                   |    6 +-
 Utilities/cmcurl/lib/pingpong.h                   |    6 +-
 Utilities/cmcurl/lib/pipeline.c                   |   81 +--
 Utilities/cmcurl/lib/pipeline.h                   |    6 +-
 Utilities/cmcurl/lib/pop3.c                       |    9 +-
 Utilities/cmcurl/lib/progress.c                   |   24 +-
 Utilities/cmcurl/lib/rand.c                       |    6 +-
 Utilities/cmcurl/lib/rtsp.c                       |   70 +-
 Utilities/cmcurl/lib/security.c                   |    4 +
 Utilities/cmcurl/lib/select.c                     |    8 +-
 Utilities/cmcurl/lib/select.h                     |    6 +-
 Utilities/cmcurl/lib/sendf.c                      |   99 +--
 Utilities/cmcurl/lib/smb.c                        |   41 +-
 Utilities/cmcurl/lib/smtp.c                       |    9 +-
 Utilities/cmcurl/lib/socks.c                      |   12 +-
 Utilities/cmcurl/lib/speedcheck.c                 |   61 +-
 Utilities/cmcurl/lib/splay.c                      |  110 ++--
 Utilities/cmcurl/lib/splay.h                      |    3 +-
 Utilities/cmcurl/lib/ssh.c                        |  319 +++++----
 Utilities/cmcurl/lib/strcase.c                    |    6 +-
 Utilities/cmcurl/lib/system_win32.c               |    4 +-
 Utilities/cmcurl/lib/telnet.c                     |   37 +-
 Utilities/cmcurl/lib/tftp.c                       |    6 +-
 Utilities/cmcurl/lib/timeval.c                    |    3 +-
 Utilities/cmcurl/lib/transfer.c                   |   48 +-
 Utilities/cmcurl/lib/url.c                        |  719 ++++++++++++---------
 Utilities/cmcurl/lib/urldata.h                    |   62 +-
 Utilities/cmcurl/lib/vauth/digest.c               |    8 +-
 Utilities/cmcurl/lib/vauth/digest_sspi.c          |  290 +++++----
 Utilities/cmcurl/lib/vauth/krb5_gssapi.c          |    4 +-
 Utilities/cmcurl/lib/vauth/krb5_sspi.c            |    4 +-
 Utilities/cmcurl/lib/vauth/ntlm.c                 |   22 +-
 Utilities/cmcurl/lib/vauth/ntlm.h                 |    2 +-
 Utilities/cmcurl/lib/vauth/spnego_sspi.c          |    3 +
 Utilities/cmcurl/lib/vtls/axtls.c                 |   28 +-
 Utilities/cmcurl/lib/vtls/axtls.h                 |    8 +-
 Utilities/cmcurl/lib/vtls/cyassl.c                |   47 +-
 Utilities/cmcurl/lib/vtls/cyassl.h                |   10 +-
 Utilities/cmcurl/lib/vtls/darwinssl.c             |  218 +++++--
 Utilities/cmcurl/lib/vtls/darwinssl.h             |    6 +-
 Utilities/cmcurl/lib/vtls/gskit.c                 |   52 +-
 Utilities/cmcurl/lib/vtls/gtls.c                  |  173 +++--
 Utilities/cmcurl/lib/vtls/gtls.h                  |    8 +-
 Utilities/cmcurl/lib/vtls/mbedtls.c               |  166 ++++-
 Utilities/cmcurl/lib/vtls/mbedtls.h               |   12 +-
 Utilities/cmcurl/lib/vtls/nss.c                   |  181 +++---
 Utilities/cmcurl/lib/vtls/nssg.h                  |    8 +-
 Utilities/cmcurl/lib/vtls/openssl.c               |  364 ++++++-----
 Utilities/cmcurl/lib/vtls/openssl.h               |    6 +-
 Utilities/cmcurl/lib/vtls/polarssl.c              |  100 ++-
 Utilities/cmcurl/lib/vtls/polarssl.h              |    3 +-
 Utilities/cmcurl/lib/vtls/schannel.c              |   81 ++-
 Utilities/cmcurl/lib/vtls/schannel.h              |    4 +-
 Utilities/cmcurl/lib/vtls/vtls.c                  |   63 +-
 Utilities/cmcurl/lib/warnless.c                   |    5 +-
 Utilities/cmcurl/lib/wildcard.c                   |   18 +-
 Utilities/cmcurl/lib/wildcard.h                   |    9 +-
 bootstrap                                         |   38 +-
 240 files changed, 3949 insertions(+), 3022 deletions(-)
 create mode 100644 Modules/Compiler/SunPro-C-FeatureTests.cmake
 create mode 100644 Utilities/cmcurl/CMake/FindMbedTLS.cmake
 create mode 100644 Utilities/cmcurl/include/curl/system.h


hooks/post-receive
-- 
CMake


More information about the Cmake-commits mailing list