Explorar o código

curl 2018-09-04 (432eb5f5)

Code extracted from:

    https://github.com/curl/curl.git

at commit 432eb5f5c254ee8383b2522ce597c9219877923e (curl-7_61_1).
Curl Upstream %!s(int64=7) %!d(string=hai) anos
pai
achega
18812a9c3d
Modificáronse 100 ficheiros con 2058 adicións e 1720 borrados
  1. 46 46
      CMake/CurlSymbolHiding.cmake
  2. 15 15
      CMake/CurlTests.c
  3. 19 19
      CMake/FindCARES.cmake
  4. 203 207
      CMake/FindGSS.cmake
  5. 7 7
      CMake/FindLibSSH2.cmake
  6. 1 1
      CMake/FindNGHTTP2.cmake
  7. 13 49
      CMake/Macros.cmake
  8. 30 31
      CMake/OtherTests.cmake
  9. 3 4
      CMake/Platforms/WindowsCache.cmake
  10. 5 36
      CMake/Utilities.cmake
  11. 9 9
      CMake/cmake_uninstall.cmake.in
  12. 0 59
      CMake/curl-config.cmake
  13. 64 0
      CMake/curl-config.cmake.in
  14. 145 140
      CMakeLists.txt
  15. 21 1
      include/curl/curl.h
  16. 4 4
      include/curl/curlver.h
  17. 19 1
      include/curl/system.h
  18. 1 1
      include/curl/typecheck-gcc.h
  19. 16 20
      lib/CMakeLists.txt
  20. 2 2
      lib/Makefile.inc
  21. 21 16
      lib/asyn-ares.c
  22. 7 7
      lib/asyn-thread.c
  23. 1 2
      lib/base64.c
  24. 23 39
      lib/conncache.c
  25. 2 2
      lib/conncache.h
  26. 5 7
      lib/connect.c
  27. 24 16
      lib/content_encoding.c
  28. 83 47
      lib/cookie.c
  29. 3 1
      lib/cookie.h
  30. 2 1
      lib/curl_addrinfo.c
  31. 6 0
      lib/curl_config.h.cmake
  32. 40 3
      lib/curl_fnmatch.c
  33. 4 1
      lib/curl_ntlm_core.c
  34. 1 2
      lib/curl_sasl.c
  35. 14 1
      lib/curl_setup.h
  36. 2 1
      lib/curl_threads.c
  37. 5 5
      lib/dict.c
  38. 15 19
      lib/easy.c
  39. 2 4
      lib/escape.c
  40. 6 6
      lib/file.c
  41. 7 9
      lib/formdata.c
  42. 7 9
      lib/ftp.c
  43. 22 0
      lib/getinfo.c
  44. 2 9
      lib/gopher.c
  45. 4 7
      lib/hash.c
  46. 2 2
      lib/hmac.c
  47. 2 2
      lib/hostasyn.c
  48. 23 15
      lib/hostip.c
  49. 1 34
      lib/hostip6.c
  50. 156 70
      lib/http.c
  51. 95 116
      lib/http2.c
  52. 2 2
      lib/http2.h
  53. 1 1
      lib/http_ntlm.c
  54. 3 4
      lib/http_proxy.c
  55. 7 9
      lib/imap.c
  56. 1 1
      lib/inet_ntop.c
  57. 0 9
      lib/ldap.c
  58. 23 17
      lib/md5.c
  59. 1 8
      lib/memdebug.h
  60. 24 29
      lib/mime.c
  61. 119 88
      lib/multi.c
  62. 7 1
      lib/multihandle.h
  63. 2 2
      lib/netrc.c
  64. 4 6
      lib/pingpong.c
  65. 5 4
      lib/pipeline.c
  66. 2 2
      lib/pop3.c
  67. 20 19
      lib/progress.c
  68. 0 13
      lib/progress.h
  69. 111 0
      lib/psl.c
  70. 47 0
      lib/psl.h
  71. 1 1
      lib/rand.c
  72. 2 4
      lib/rtsp.c
  73. 2 2
      lib/security.c
  74. 5 3
      lib/select.c
  75. 5 43
      lib/sendf.c
  76. 2 3
      lib/sendf.h
  77. 40 3
      lib/setopt.c
  78. 8 11
      lib/sha256.c
  79. 10 1
      lib/share.c
  80. 5 1
      lib/share.h
  81. 52 53
      lib/smb.c
  82. 1 0
      lib/smb.h
  83. 3 2
      lib/smtp.c
  84. 7 7
      lib/socks.c
  85. 1 2
      lib/splay.c
  86. 38 26
      lib/ssh-libssh.c
  87. 23 22
      lib/ssh.c
  88. 2 2
      lib/ssh.h
  89. 0 1
      lib/strcase.h
  90. 10 5
      lib/system_win32.c
  91. 29 30
      lib/telnet.c
  92. 14 13
      lib/tftp.c
  93. 61 25
      lib/transfer.c
  94. 3 1
      lib/transfer.h
  95. 106 113
      lib/url.c
  96. 2 1
      lib/url.h
  97. 28 21
      lib/urldata.h
  98. 3 3
      lib/vauth/digest.c
  99. 1 1
      lib/version.c
  100. 5 0
      lib/vtls/axtls.c

+ 46 - 46
CMake/CurlSymbolHiding.cmake

@@ -4,57 +4,57 @@ option(CURL_HIDDEN_SYMBOLS "Set to ON to hide libcurl internal symbols (=hide al
 mark_as_advanced(CURL_HIDDEN_SYMBOLS)
 mark_as_advanced(CURL_HIDDEN_SYMBOLS)
 
 
 if(CURL_HIDDEN_SYMBOLS)
 if(CURL_HIDDEN_SYMBOLS)
-    set(SUPPORTS_SYMBOL_HIDING FALSE)
+  set(SUPPORTS_SYMBOL_HIDING FALSE)
 
 
-    if(CMAKE_C_COMPILER_ID MATCHES "Clang")
-        set(SUPPORTS_SYMBOL_HIDING TRUE)
-        set(_SYMBOL_EXTERN "__attribute__ ((__visibility__ (\"default\")))")
-        set(_CFLAG_SYMBOLS_HIDE "-fvisibility=hidden")
-    elseif(CMAKE_COMPILER_IS_GNUCC)
-        if(NOT CMAKE_VERSION VERSION_LESS 2.8.10)
-            set(GCC_VERSION ${CMAKE_C_COMPILER_VERSION})
-        else()
-            execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion
-                            OUTPUT_VARIABLE GCC_VERSION)
-        endif()
-        if(NOT GCC_VERSION VERSION_LESS 3.4)
-            # note: this is considered buggy prior to 4.0 but the autotools don't care, so let's ignore that fact
-            set(SUPPORTS_SYMBOL_HIDING TRUE)
-            set(_SYMBOL_EXTERN "__attribute__ ((__visibility__ (\"default\")))")
-            set(_CFLAG_SYMBOLS_HIDE "-fvisibility=hidden")
-        endif()
-    elseif(CMAKE_C_COMPILER_ID MATCHES "SunPro" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 8.0)
-        set(SUPPORTS_SYMBOL_HIDING TRUE)
-        set(_SYMBOL_EXTERN "__global")
-        set(_CFLAG_SYMBOLS_HIDE "-xldscope=hidden")
-    elseif(CMAKE_C_COMPILER_ID MATCHES "Intel" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 9.0)
-        # note: this should probably just check for version 9.1.045 but I'm not 100% sure
-        #       so let's to it the same way autotools do.
-        set(SUPPORTS_SYMBOL_HIDING TRUE)
-        set(_SYMBOL_EXTERN "__attribute__ ((__visibility__ (\"default\")))")
-        set(_CFLAG_SYMBOLS_HIDE "-fvisibility=hidden")
-        check_c_source_compiles("#include <stdio.h>
-            int main (void) { printf(\"icc fvisibility bug test\"); return 0; }" _no_bug)
-        if(NOT _no_bug)
-            set(SUPPORTS_SYMBOL_HIDING FALSE)
-            set(_SYMBOL_EXTERN "")
-            set(_CFLAG_SYMBOLS_HIDE "")
-        endif()
-    elseif(MSVC)
-        set(SUPPORTS_SYMBOL_HIDING TRUE)
+  if(CMAKE_C_COMPILER_ID MATCHES "Clang")
+    set(SUPPORTS_SYMBOL_HIDING TRUE)
+    set(_SYMBOL_EXTERN "__attribute__ ((__visibility__ (\"default\")))")
+    set(_CFLAG_SYMBOLS_HIDE "-fvisibility=hidden")
+  elseif(CMAKE_COMPILER_IS_GNUCC)
+    if(NOT CMAKE_VERSION VERSION_LESS 2.8.10)
+      set(GCC_VERSION ${CMAKE_C_COMPILER_VERSION})
+    else()
+      execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion
+                      OUTPUT_VARIABLE GCC_VERSION)
+    endif()
+    if(NOT GCC_VERSION VERSION_LESS 3.4)
+      # note: this is considered buggy prior to 4.0 but the autotools don't care, so let's ignore that fact
+      set(SUPPORTS_SYMBOL_HIDING TRUE)
+      set(_SYMBOL_EXTERN "__attribute__ ((__visibility__ (\"default\")))")
+      set(_CFLAG_SYMBOLS_HIDE "-fvisibility=hidden")
     endif()
     endif()
+  elseif(CMAKE_C_COMPILER_ID MATCHES "SunPro" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 8.0)
+    set(SUPPORTS_SYMBOL_HIDING TRUE)
+    set(_SYMBOL_EXTERN "__global")
+    set(_CFLAG_SYMBOLS_HIDE "-xldscope=hidden")
+  elseif(CMAKE_C_COMPILER_ID MATCHES "Intel" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 9.0)
+    # note: this should probably just check for version 9.1.045 but I'm not 100% sure
+    #       so let's to it the same way autotools do.
+    set(SUPPORTS_SYMBOL_HIDING TRUE)
+    set(_SYMBOL_EXTERN "__attribute__ ((__visibility__ (\"default\")))")
+    set(_CFLAG_SYMBOLS_HIDE "-fvisibility=hidden")
+    check_c_source_compiles("#include <stdio.h>
+        int main (void) { printf(\"icc fvisibility bug test\"); return 0; }" _no_bug)
+    if(NOT _no_bug)
+      set(SUPPORTS_SYMBOL_HIDING FALSE)
+      set(_SYMBOL_EXTERN "")
+      set(_CFLAG_SYMBOLS_HIDE "")
+    endif()
+  elseif(MSVC)
+    set(SUPPORTS_SYMBOL_HIDING TRUE)
+  endif()
 
 
-    set(HIDES_CURL_PRIVATE_SYMBOLS ${SUPPORTS_SYMBOL_HIDING})
+  set(HIDES_CURL_PRIVATE_SYMBOLS ${SUPPORTS_SYMBOL_HIDING})
 elseif(MSVC)
 elseif(MSVC)
-    if(NOT CMAKE_VERSION VERSION_LESS 3.7)
-        set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE) #present since 3.4.3 but broken
-        set(HIDES_CURL_PRIVATE_SYMBOLS FALSE)
-    else()
-        message(WARNING "Hiding private symbols regardless CURL_HIDDEN_SYMBOLS being disabled.")
-        set(HIDES_CURL_PRIVATE_SYMBOLS TRUE)
-    endif()
-elseif()
+  if(NOT CMAKE_VERSION VERSION_LESS 3.7)
+    set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE) #present since 3.4.3 but broken
     set(HIDES_CURL_PRIVATE_SYMBOLS FALSE)
     set(HIDES_CURL_PRIVATE_SYMBOLS FALSE)
+  else()
+    message(WARNING "Hiding private symbols regardless CURL_HIDDEN_SYMBOLS being disabled.")
+    set(HIDES_CURL_PRIVATE_SYMBOLS TRUE)
+  endif()
+elseif()
+  set(HIDES_CURL_PRIVATE_SYMBOLS FALSE)
 endif()
 endif()
 
 
 set(CURL_CFLAG_SYMBOLS_HIDE ${_CFLAG_SYMBOLS_HIDE})
 set(CURL_CFLAG_SYMBOLS_HIDE ${_CFLAG_SYMBOLS_HIDE})

+ 15 - 15
CMake/CurlTests.c

@@ -507,30 +507,30 @@ main ()
 #ifdef HAVE_GLIBC_STRERROR_R
 #ifdef HAVE_GLIBC_STRERROR_R
 #include <string.h>
 #include <string.h>
 #include <errno.h>
 #include <errno.h>
+
+void check(char c) {}
+
 int
 int
 main () {
 main () {
-  char buffer[1024]; /* big enough to play with */
-  char *string =
-    strerror_r(EACCES, buffer, sizeof(buffer));
-    /* this should've returned a string */
-    if(!string || !string[0])
-      return 99;
-    return 0;
+  char buffer[1024];
+  /* This will not compile if strerror_r does not return a char* */
+  check(strerror_r(EACCES, buffer, sizeof(buffer))[0]);
+  return 0;
 }
 }
 #endif
 #endif
 #ifdef HAVE_POSIX_STRERROR_R
 #ifdef HAVE_POSIX_STRERROR_R
 #include <string.h>
 #include <string.h>
 #include <errno.h>
 #include <errno.h>
+
+/* float, because a pointer can't be implicitly cast to float */
+void check(float f) {}
+
 int
 int
 main () {
 main () {
-  char buffer[1024]; /* big enough to play with */
-  int error =
-    strerror_r(EACCES, buffer, sizeof(buffer));
-    /* This should've returned zero, and written an error string in the
-       buffer.*/
-    if(!buffer[0] || error)
-      return 99;
-    return 0;
+  char buffer[1024];
+  /* This will not compile if strerror_r does not return an int */
+  check(strerror_r(EACCES, buffer, sizeof(buffer)));
+  return 0;
 }
 }
 #endif
 #endif
 #ifdef HAVE_FSETXATTR_6
 #ifdef HAVE_FSETXATTR_6

+ 19 - 19
CMake/FindCARES.cmake

@@ -7,36 +7,36 @@
 # also defined, but not for general use are
 # also defined, but not for general use are
 # CARES_LIBRARY, where to find the c-ares library.
 # CARES_LIBRARY, where to find the c-ares library.
 
 
-FIND_PATH(CARES_INCLUDE_DIR ares.h
+find_path(CARES_INCLUDE_DIR ares.h
   /usr/local/include
   /usr/local/include
   /usr/include
   /usr/include
   )
   )
 
 
-SET(CARES_NAMES ${CARES_NAMES} cares)
-FIND_LIBRARY(CARES_LIBRARY
+set(CARES_NAMES ${CARES_NAMES} cares)
+find_library(CARES_LIBRARY
   NAMES ${CARES_NAMES}
   NAMES ${CARES_NAMES}
   PATHS /usr/lib /usr/local/lib
   PATHS /usr/lib /usr/local/lib
   )
   )
 
 
-IF (CARES_LIBRARY AND CARES_INCLUDE_DIR)
-  SET(CARES_LIBRARIES ${CARES_LIBRARY})
-  SET(CARES_FOUND "YES")
-ELSE (CARES_LIBRARY AND CARES_INCLUDE_DIR)
-  SET(CARES_FOUND "NO")
-ENDIF (CARES_LIBRARY AND CARES_INCLUDE_DIR)
+if(CARES_LIBRARY AND CARES_INCLUDE_DIR)
+  set(CARES_LIBRARIES ${CARES_LIBRARY})
+  set(CARES_FOUND "YES")
+else()
+  set(CARES_FOUND "NO")
+endif()
 
 
 
 
-IF (CARES_FOUND)
-  IF (NOT CARES_FIND_QUIETLY)
-    MESSAGE(STATUS "Found c-ares: ${CARES_LIBRARIES}")
-  ENDIF (NOT CARES_FIND_QUIETLY)
-ELSE (CARES_FOUND)
-  IF (CARES_FIND_REQUIRED)
-    MESSAGE(FATAL_ERROR "Could not find c-ares library")
-  ENDIF (CARES_FIND_REQUIRED)
-ENDIF (CARES_FOUND)
+if(CARES_FOUND)
+  if(NOT CARES_FIND_QUIETLY)
+    message(STATUS "Found c-ares: ${CARES_LIBRARIES}")
+  endif()
+else()
+  if(CARES_FIND_REQUIRED)
+    message(FATAL_ERROR "Could not find c-ares library")
+  endif()
+endif()
 
 
-MARK_AS_ADVANCED(
+mark_as_advanced(
   CARES_LIBRARY
   CARES_LIBRARY
   CARES_INCLUDE_DIR
   CARES_INCLUDE_DIR
   )
   )

+ 203 - 207
CMake/FindGSS.cmake

@@ -28,211 +28,209 @@ set(_GSS_ROOT_HINTS
 
 
 # try to find library using system pkg-config if user didn't specify root dir
 # try to find library using system pkg-config if user didn't specify root dir
 if(NOT GSS_ROOT_DIR AND NOT "$ENV{GSS_ROOT_DIR}")
 if(NOT GSS_ROOT_DIR AND NOT "$ENV{GSS_ROOT_DIR}")
-    if(UNIX)
-        find_package(PkgConfig QUIET)
-        pkg_search_module(_GSS_PKG ${_MIT_MODNAME} ${_HEIMDAL_MODNAME})
-        list(APPEND _GSS_ROOT_HINTS "${_GSS_PKG_PREFIX}")
-    elseif(WIN32)
-        list(APPEND _GSS_ROOT_HINTS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MIT\\Kerberos;InstallDir]")
-    endif()
+  if(UNIX)
+    find_package(PkgConfig QUIET)
+    pkg_search_module(_GSS_PKG ${_MIT_MODNAME} ${_HEIMDAL_MODNAME})
+    list(APPEND _GSS_ROOT_HINTS "${_GSS_PKG_PREFIX}")
+  elseif(WIN32)
+    list(APPEND _GSS_ROOT_HINTS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MIT\\Kerberos;InstallDir]")
+  endif()
 endif()
 endif()
 
 
 if(NOT _GSS_FOUND) #not found by pkg-config. Let's take more traditional approach.
 if(NOT _GSS_FOUND) #not found by pkg-config. Let's take more traditional approach.
-    find_file(_GSS_CONFIGURE_SCRIPT
-        NAMES
-            "krb5-config"
-        HINTS
-            ${_GSS_ROOT_HINTS}
-        PATH_SUFFIXES
-            bin
-        NO_CMAKE_PATH
-        NO_CMAKE_ENVIRONMENT_PATH
+  find_file(_GSS_CONFIGURE_SCRIPT
+      NAMES
+          "krb5-config"
+      HINTS
+          ${_GSS_ROOT_HINTS}
+      PATH_SUFFIXES
+          bin
+      NO_CMAKE_PATH
+      NO_CMAKE_ENVIRONMENT_PATH
+  )
+
+  # if not found in user-supplied directories, maybe system knows better
+  find_file(_GSS_CONFIGURE_SCRIPT
+      NAMES
+          "krb5-config"
+      PATH_SUFFIXES
+          bin
+  )
+
+  if(_GSS_CONFIGURE_SCRIPT)
+    execute_process(
+          COMMAND ${_GSS_CONFIGURE_SCRIPT} "--cflags" "gssapi"
+          OUTPUT_VARIABLE _GSS_CFLAGS
+          RESULT_VARIABLE _GSS_CONFIGURE_FAILED
+      )
+    message(STATUS "CFLAGS: ${_GSS_CFLAGS}")
+    if(NOT _GSS_CONFIGURE_FAILED) # 0 means success
+      # should also work in an odd case when multiple directories are given
+      string(STRIP "${_GSS_CFLAGS}" _GSS_CFLAGS)
+      string(REGEX REPLACE " +-I" ";" _GSS_CFLAGS "${_GSS_CFLAGS}")
+      string(REGEX REPLACE " +-([^I][^ \\t;]*)" ";-\\1"_GSS_CFLAGS "${_GSS_CFLAGS}")
+
+      foreach(_flag ${_GSS_CFLAGS})
+        if(_flag MATCHES "^-I.*")
+          string(REGEX REPLACE "^-I" "" _val "${_flag}")
+          list(APPEND _GSS_INCLUDE_DIR "${_val}")
+        else()
+          list(APPEND _GSS_COMPILER_FLAGS "${_flag}")
+        endif()
+      endforeach()
+    endif()
+
+    execute_process(
+        COMMAND ${_GSS_CONFIGURE_SCRIPT} "--libs" "gssapi"
+        OUTPUT_VARIABLE _GSS_LIB_FLAGS
+        RESULT_VARIABLE _GSS_CONFIGURE_FAILED
     )
     )
+    message(STATUS "LDFLAGS: ${_GSS_LIB_FLAGS}")
+
+    if(NOT _GSS_CONFIGURE_FAILED) # 0 means success
+      # this script gives us libraries and link directories. Blah. We have to deal with it.
+      string(STRIP "${_GSS_LIB_FLAGS}" _GSS_LIB_FLAGS)
+      string(REGEX REPLACE " +-(L|l)" ";-\\1" _GSS_LIB_FLAGS "${_GSS_LIB_FLAGS}")
+      string(REGEX REPLACE " +-([^Ll][^ \\t;]*)" ";-\\1"_GSS_LIB_FLAGS "${_GSS_LIB_FLAGS}")
+
+      foreach(_flag ${_GSS_LIB_FLAGS})
+        if(_flag MATCHES "^-l.*")
+          string(REGEX REPLACE "^-l" "" _val "${_flag}")
+          list(APPEND _GSS_LIBRARIES "${_val}")
+        elseif(_flag MATCHES "^-L.*")
+          string(REGEX REPLACE "^-L" "" _val "${_flag}")
+          list(APPEND _GSS_LINK_DIRECTORIES "${_val}")
+        else()
+          list(APPEND _GSS_LINKER_FLAGS "${_flag}")
+        endif()
+      endforeach()
+    endif()
 
 
-    # if not found in user-supplied directories, maybe system knows better
-    find_file(_GSS_CONFIGURE_SCRIPT
-        NAMES
-            "krb5-config"
-        PATH_SUFFIXES
-            bin
+    execute_process(
+        COMMAND ${_GSS_CONFIGURE_SCRIPT} "--version"
+        OUTPUT_VARIABLE _GSS_VERSION
+        RESULT_VARIABLE _GSS_CONFIGURE_FAILED
     )
     )
 
 
-    if(_GSS_CONFIGURE_SCRIPT)
-        execute_process(
-            COMMAND ${_GSS_CONFIGURE_SCRIPT} "--cflags" "gssapi"
-            OUTPUT_VARIABLE _GSS_CFLAGS
-            RESULT_VARIABLE _GSS_CONFIGURE_FAILED
-        )
-message(STATUS "CFLAGS: ${_GSS_CFLAGS}")
-        if(NOT _GSS_CONFIGURE_FAILED) # 0 means success
-            # should also work in an odd case when multiple directories are given
-            string(STRIP "${_GSS_CFLAGS}" _GSS_CFLAGS)
-            string(REGEX REPLACE " +-I" ";" _GSS_CFLAGS "${_GSS_CFLAGS}")
-            string(REGEX REPLACE " +-([^I][^ \\t;]*)" ";-\\1"_GSS_CFLAGS "${_GSS_CFLAGS}")
-
-            foreach(_flag ${_GSS_CFLAGS})
-                if(_flag MATCHES "^-I.*")
-                    string(REGEX REPLACE "^-I" "" _val "${_flag}")
-                    list(APPEND _GSS_INCLUDE_DIR "${_val}")
-                else()
-                    list(APPEND _GSS_COMPILER_FLAGS "${_flag}")
-                endif()
-            endforeach()
-        endif()
+    # older versions may not have the "--version" parameter. In this case we just don't care.
+    if(_GSS_CONFIGURE_FAILED)
+      set(_GSS_VERSION 0)
+    endif()
 
 
-        execute_process(
-            COMMAND ${_GSS_CONFIGURE_SCRIPT} "--libs" "gssapi"
-            OUTPUT_VARIABLE _GSS_LIB_FLAGS
-            RESULT_VARIABLE _GSS_CONFIGURE_FAILED
-        )
-message(STATUS "LDFLAGS: ${_GSS_LIB_FLAGS}")
-        if(NOT _GSS_CONFIGURE_FAILED) # 0 means success
-            # this script gives us libraries and link directories. Blah. We have to deal with it.
-            string(STRIP "${_GSS_LIB_FLAGS}" _GSS_LIB_FLAGS)
-            string(REGEX REPLACE " +-(L|l)" ";-\\1" _GSS_LIB_FLAGS "${_GSS_LIB_FLAGS}")
-            string(REGEX REPLACE " +-([^Ll][^ \\t;]*)" ";-\\1"_GSS_LIB_FLAGS "${_GSS_LIB_FLAGS}")
-
-            foreach(_flag ${_GSS_LIB_FLAGS})
-                if(_flag MATCHES "^-l.*")
-                    string(REGEX REPLACE "^-l" "" _val "${_flag}")
-                    list(APPEND _GSS_LIBRARIES "${_val}")
-                elseif(_flag MATCHES "^-L.*")
-                    string(REGEX REPLACE "^-L" "" _val "${_flag}")
-                    list(APPEND _GSS_LINK_DIRECTORIES "${_val}")
-                else()
-                    list(APPEND _GSS_LINKER_FLAGS "${_flag}")
-                endif()
-            endforeach()
-        endif()
+    execute_process(
+        COMMAND ${_GSS_CONFIGURE_SCRIPT} "--vendor"
+        OUTPUT_VARIABLE _GSS_VENDOR
+        RESULT_VARIABLE _GSS_CONFIGURE_FAILED
+    )
 
 
+    # older versions may not have the "--vendor" parameter. In this case we just don't care.
+    if(_GSS_CONFIGURE_FAILED)
+      set(GSS_FLAVOUR "Heimdal") # most probably, shouldn't really matter
+    else()
+      if(_GSS_VENDOR MATCHES ".*H|heimdal.*")
+        set(GSS_FLAVOUR "Heimdal")
+      else()
+        set(GSS_FLAVOUR "MIT")
+      endif()
+    endif()
 
 
-        execute_process(
-            COMMAND ${_GSS_CONFIGURE_SCRIPT} "--version"
-            OUTPUT_VARIABLE _GSS_VERSION
-            RESULT_VARIABLE _GSS_CONFIGURE_FAILED
-        )
+  else() # either there is no config script or we are on platform that doesn't provide one (Windows?)
 
 
-        # older versions may not have the "--version" parameter. In this case we just don't care.
-        if(_GSS_CONFIGURE_FAILED)
-            set(_GSS_VERSION 0)
-        endif()
+    find_path(_GSS_INCLUDE_DIR
+        NAMES
+            "gssapi/gssapi.h"
+        HINTS
+            ${_GSS_ROOT_HINTS}
+        PATH_SUFFIXES
+            include
+            inc
+    )
 
 
+    if(_GSS_INCLUDE_DIR) #jay, we've found something
+      set(CMAKE_REQUIRED_INCLUDES "${_GSS_INCLUDE_DIR}")
+      check_include_files( "gssapi/gssapi_generic.h;gssapi/gssapi_krb5.h" _GSS_HAVE_MIT_HEADERS)
 
 
-        execute_process(
-            COMMAND ${_GSS_CONFIGURE_SCRIPT} "--vendor"
-            OUTPUT_VARIABLE _GSS_VENDOR
-            RESULT_VARIABLE _GSS_CONFIGURE_FAILED
-        )
+      if(_GSS_HAVE_MIT_HEADERS)
+        set(GSS_FLAVOUR "MIT")
+      else()
+        # prevent compiling the header - just check if we can include it
+        set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -D__ROKEN_H__")
+        check_include_file( "roken.h" _GSS_HAVE_ROKEN_H)
+
+        check_include_file( "heimdal/roken.h" _GSS_HAVE_HEIMDAL_ROKEN_H)
+        if(_GSS_HAVE_ROKEN_H OR _GSS_HAVE_HEIMDAL_ROKEN_H)
+          set(GSS_FLAVOUR "Heimdal")
+        endif()
+        set(CMAKE_REQUIRED_DEFINITIONS "")
+      endif()
+    else()
+      # I'm not convienced if this is the right way but this is what autotools do at the moment
+      find_path(_GSS_INCLUDE_DIR
+          NAMES
+              "gssapi.h"
+          HINTS
+              ${_GSS_ROOT_HINTS}
+          PATH_SUFFIXES
+              include
+              inc
+      )
+
+      if(_GSS_INCLUDE_DIR)
+        set(GSS_FLAVOUR "Heimdal")
+      endif()
+    endif()
+
+    # if we have headers, check if we can link libraries
+    if(GSS_FLAVOUR)
+      set(_GSS_LIBDIR_SUFFIXES "")
+      set(_GSS_LIBDIR_HINTS ${_GSS_ROOT_HINTS})
+      get_filename_component(_GSS_CALCULATED_POTENTIAL_ROOT "${_GSS_INCLUDE_DIR}" PATH)
+      list(APPEND _GSS_LIBDIR_HINTS ${_GSS_CALCULATED_POTENTIAL_ROOT})
 
 
-        # older versions may not have the "--vendor" parameter. In this case we just don't care.
-        if(_GSS_CONFIGURE_FAILED)
-            set(GSS_FLAVOUR "Heimdal") # most probably, shouldn't really matter
+      if(WIN32)
+        if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+          list(APPEND _GSS_LIBDIR_SUFFIXES "lib/AMD64")
+          if(GSS_FLAVOUR STREQUAL "MIT")
+            set(_GSS_LIBNAME "gssapi64")
+          else()
+            set(_GSS_LIBNAME "libgssapi")
+          endif()
         else()
         else()
-            if(_GSS_VENDOR MATCHES ".*H|heimdal.*")
-                set(GSS_FLAVOUR "Heimdal")
-            else()
-                set(GSS_FLAVOUR "MIT")
-            endif()
+          list(APPEND _GSS_LIBDIR_SUFFIXES "lib/i386")
+          if(GSS_FLAVOUR STREQUAL "MIT")
+            set(_GSS_LIBNAME "gssapi32")
+          else()
+            set(_GSS_LIBNAME "libgssapi")
+          endif()
         endif()
         endif()
-
-    else() # either there is no config script or we are on platform that doesn't provide one (Windows?)
-
-        find_path(_GSS_INCLUDE_DIR
-            NAMES
-                "gssapi/gssapi.h"
-            HINTS
-                ${_GSS_ROOT_HINTS}
-            PATH_SUFFIXES
-                include
-                inc
-        )
-
-        if(_GSS_INCLUDE_DIR) #jay, we've found something
-            set(CMAKE_REQUIRED_INCLUDES "${_GSS_INCLUDE_DIR}")
-            check_include_files( "gssapi/gssapi_generic.h;gssapi/gssapi_krb5.h" _GSS_HAVE_MIT_HEADERS)
-
-            if(_GSS_HAVE_MIT_HEADERS)
-                set(GSS_FLAVOUR "MIT")
-            else()
-                # prevent compiling the header - just check if we can include it
-                set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -D__ROKEN_H__")
-                check_include_file( "roken.h" _GSS_HAVE_ROKEN_H)
-
-                check_include_file( "heimdal/roken.h" _GSS_HAVE_HEIMDAL_ROKEN_H)
-                if(_GSS_HAVE_ROKEN_H OR _GSS_HAVE_HEIMDAL_ROKEN_H)
-                    set(GSS_FLAVOUR "Heimdal")
-                endif()
-                set(CMAKE_REQUIRED_DEFINITIONS "")
-            endif()
+      else()
+        list(APPEND _GSS_LIBDIR_SUFFIXES "lib;lib64") # those suffixes are not checked for HINTS
+        if(GSS_FLAVOUR STREQUAL "MIT")
+          set(_GSS_LIBNAME "gssapi_krb5")
         else()
         else()
-            # I'm not convienced if this is the right way but this is what autotools do at the moment
-            find_path(_GSS_INCLUDE_DIR
-                NAMES
-                    "gssapi.h"
-                HINTS
-                    ${_GSS_ROOT_HINTS}
-                PATH_SUFFIXES
-                    include
-                    inc
-            )
-
-            if(_GSS_INCLUDE_DIR)
-                set(GSS_FLAVOUR "Heimdal")
-            endif()
+          set(_GSS_LIBNAME "gssapi")
         endif()
         endif()
+      endif()
 
 
-        # if we have headers, check if we can link libraries
-        if(GSS_FLAVOUR)
-            set(_GSS_LIBDIR_SUFFIXES "")
-            set(_GSS_LIBDIR_HINTS ${_GSS_ROOT_HINTS})
-            get_filename_component(_GSS_CALCULATED_POTENTIAL_ROOT "${_GSS_INCLUDE_DIR}" PATH)
-            list(APPEND _GSS_LIBDIR_HINTS ${_GSS_CALCULATED_POTENTIAL_ROOT})
-
-            if(WIN32)
-                if(CMAKE_SIZEOF_VOID_P EQUAL 8)
-                    list(APPEND _GSS_LIBDIR_SUFFIXES "lib/AMD64")
-                    if(GSS_FLAVOUR STREQUAL "MIT")
-                        set(_GSS_LIBNAME "gssapi64")
-                    else()
-                        set(_GSS_LIBNAME "libgssapi")
-                    endif()
-                else()
-                    list(APPEND _GSS_LIBDIR_SUFFIXES "lib/i386")
-                    if(GSS_FLAVOUR STREQUAL "MIT")
-                        set(_GSS_LIBNAME "gssapi32")
-                    else()
-                        set(_GSS_LIBNAME "libgssapi")
-                    endif()
-                endif()
-            else()
-                list(APPEND _GSS_LIBDIR_SUFFIXES "lib;lib64") # those suffixes are not checked for HINTS
-                if(GSS_FLAVOUR STREQUAL "MIT")
-                    set(_GSS_LIBNAME "gssapi_krb5")
-                else()
-                    set(_GSS_LIBNAME "gssapi")
-                endif()
-            endif()
-
-            find_library(_GSS_LIBRARIES
-                NAMES
-                    ${_GSS_LIBNAME}
-                HINTS
-                    ${_GSS_LIBDIR_HINTS}
-                PATH_SUFFIXES
-                    ${_GSS_LIBDIR_SUFFIXES}
-            )
-
-        endif()
+      find_library(_GSS_LIBRARIES
+          NAMES
+              ${_GSS_LIBNAME}
+          HINTS
+              ${_GSS_LIBDIR_HINTS}
+          PATH_SUFFIXES
+              ${_GSS_LIBDIR_SUFFIXES}
+      )
 
 
     endif()
     endif()
+  endif()
 else()
 else()
-    if(_GSS_PKG_${_MIT_MODNAME}_VERSION)
-        set(GSS_FLAVOUR "MIT")
-        set(_GSS_VERSION _GSS_PKG_${_MIT_MODNAME}_VERSION)
-    else()
-        set(GSS_FLAVOUR "Heimdal")
-        set(_GSS_VERSION _GSS_PKG_${_MIT_HEIMDAL}_VERSION)
-    endif()
+  if(_GSS_PKG_${_MIT_MODNAME}_VERSION)
+    set(GSS_FLAVOUR "MIT")
+    set(_GSS_VERSION _GSS_PKG_${_MIT_MODNAME}_VERSION)
+  else()
+    set(GSS_FLAVOUR "Heimdal")
+    set(_GSS_VERSION _GSS_PKG_${_MIT_HEIMDAL}_VERSION)
+  endif()
 endif()
 endif()
 
 
 set(GSS_INCLUDE_DIR ${_GSS_INCLUDE_DIR})
 set(GSS_INCLUDE_DIR ${_GSS_INCLUDE_DIR})
@@ -243,36 +241,34 @@ set(GSS_COMPILER_FLAGS ${_GSS_COMPILER_FLAGS})
 set(GSS_VERSION ${_GSS_VERSION})
 set(GSS_VERSION ${_GSS_VERSION})
 
 
 if(GSS_FLAVOUR)
 if(GSS_FLAVOUR)
+  if(NOT GSS_VERSION AND GSS_FLAVOUR STREQUAL "Heimdal")
+    if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+      set(HEIMDAL_MANIFEST_FILE "Heimdal.Application.amd64.manifest")
+    else()
+      set(HEIMDAL_MANIFEST_FILE "Heimdal.Application.x86.manifest")
+    endif()
 
 
-    if(NOT GSS_VERSION AND GSS_FLAVOUR STREQUAL "Heimdal")
-        if(CMAKE_SIZEOF_VOID_P EQUAL 8)
-            set(HEIMDAL_MANIFEST_FILE "Heimdal.Application.amd64.manifest")
-        else()
-            set(HEIMDAL_MANIFEST_FILE "Heimdal.Application.x86.manifest")
-        endif()
-
-        if(EXISTS "${GSS_INCLUDE_DIR}/${HEIMDAL_MANIFEST_FILE}")
-            file(STRINGS "${GSS_INCLUDE_DIR}/${HEIMDAL_MANIFEST_FILE}" heimdal_version_str
-                 REGEX "^.*version=\"[0-9]\\.[^\"]+\".*$")
+    if(EXISTS "${GSS_INCLUDE_DIR}/${HEIMDAL_MANIFEST_FILE}")
+      file(STRINGS "${GSS_INCLUDE_DIR}/${HEIMDAL_MANIFEST_FILE}" heimdal_version_str
+           REGEX "^.*version=\"[0-9]\\.[^\"]+\".*$")
 
 
-            string(REGEX MATCH "[0-9]\\.[^\"]+"
-                   GSS_VERSION "${heimdal_version_str}")
-        endif()
+      string(REGEX MATCH "[0-9]\\.[^\"]+"
+             GSS_VERSION "${heimdal_version_str}")
+    endif()
 
 
-        if(NOT GSS_VERSION)
-            set(GSS_VERSION "Heimdal Unknown")
-        endif()
-    elseif(NOT GSS_VERSION AND GSS_FLAVOUR STREQUAL "MIT")
-        get_filename_component(_MIT_VERSION "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MIT\\Kerberos\\SDK\\CurrentVersion;VersionString]" NAME CACHE)
-        if(WIN32 AND _MIT_VERSION)
-            set(GSS_VERSION "${_MIT_VERSION}")
-        else()
-            set(GSS_VERSION "MIT Unknown")
-        endif()
+    if(NOT GSS_VERSION)
+      set(GSS_VERSION "Heimdal Unknown")
     endif()
     endif()
+  elseif(NOT GSS_VERSION AND GSS_FLAVOUR STREQUAL "MIT")
+    get_filename_component(_MIT_VERSION "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MIT\\Kerberos\\SDK\\CurrentVersion;VersionString]" NAME CACHE)
+    if(WIN32 AND _MIT_VERSION)
+      set(GSS_VERSION "${_MIT_VERSION}")
+    else()
+      set(GSS_VERSION "MIT Unknown")
+    endif()
+  endif()
 endif()
 endif()
 
 
-
 include(FindPackageHandleStandardArgs)
 include(FindPackageHandleStandardArgs)
 
 
 set(_GSS_REQUIRED_VARS GSS_LIBRARIES GSS_FLAVOUR)
 set(_GSS_REQUIRED_VARS GSS_LIBRARIES GSS_FLAVOUR)

+ 7 - 7
CMake/FindLibSSH2.cmake

@@ -5,14 +5,14 @@
 # LIBSSH2_INCLUDE_DIR - the libssh2 include directory
 # LIBSSH2_INCLUDE_DIR - the libssh2 include directory
 # LIBSSH2_LIBRARY - the libssh2 library name
 # LIBSSH2_LIBRARY - the libssh2 library name
 
 
-if (LIBSSH2_INCLUDE_DIR AND LIBSSH2_LIBRARY)
+if(LIBSSH2_INCLUDE_DIR AND LIBSSH2_LIBRARY)
   set(LibSSH2_FIND_QUIETLY TRUE)
   set(LibSSH2_FIND_QUIETLY TRUE)
-endif (LIBSSH2_INCLUDE_DIR AND LIBSSH2_LIBRARY)
+endif()
 
 
-FIND_PATH(LIBSSH2_INCLUDE_DIR libssh2.h
+find_path(LIBSSH2_INCLUDE_DIR libssh2.h
 )
 )
 
 
-FIND_LIBRARY(LIBSSH2_LIBRARY NAMES ssh2
+find_library(LIBSSH2_LIBRARY NAMES ssh2
 )
 )
 
 
 if(LIBSSH2_INCLUDE_DIR)
 if(LIBSSH2_INCLUDE_DIR)
@@ -27,9 +27,9 @@ if(LIBSSH2_INCLUDE_DIR)
   string(REGEX REPLACE "^0(.+)" "\\1" LIBSSH2_VERSION_PATCH "${LIBSSH2_VERSION_PATCH}")
   string(REGEX REPLACE "^0(.+)" "\\1" LIBSSH2_VERSION_PATCH "${LIBSSH2_VERSION_PATCH}")
 
 
   set(LIBSSH2_VERSION "${LIBSSH2_VERSION_MAJOR}.${LIBSSH2_VERSION_MINOR}.${LIBSSH2_VERSION_PATCH}")
   set(LIBSSH2_VERSION "${LIBSSH2_VERSION_MAJOR}.${LIBSSH2_VERSION_MINOR}.${LIBSSH2_VERSION_PATCH}")
-endif(LIBSSH2_INCLUDE_DIR)
+endif()
 
 
 include(FindPackageHandleStandardArgs)
 include(FindPackageHandleStandardArgs)
-FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibSSH2 DEFAULT_MSG LIBSSH2_INCLUDE_DIR LIBSSH2_LIBRARY )
+find_package_handle_standard_args(LibSSH2 DEFAULT_MSG LIBSSH2_INCLUDE_DIR LIBSSH2_LIBRARY )
 
 
-MARK_AS_ADVANCED(LIBSSH2_INCLUDE_DIR LIBSSH2_LIBRARY LIBSSH2_VERSION_MAJOR LIBSSH2_VERSION_MINOR LIBSSH2_VERSION_PATCH LIBSSH2_VERSION)
+mark_as_advanced(LIBSSH2_INCLUDE_DIR LIBSSH2_LIBRARY LIBSSH2_VERSION_MAJOR LIBSSH2_VERSION_MINOR LIBSSH2_VERSION_PATCH LIBSSH2_VERSION)

+ 1 - 1
CMake/FindNGHTTP2.cmake

@@ -14,5 +14,5 @@ find_package_handle_standard_args(NGHTTP2
       "Could NOT find NGHTTP2"
       "Could NOT find NGHTTP2"
 )
 )
 
 
-set(NGHTTP2_INCLUDE_DIRS ${NGHTTP2_INCLUDE_DIR} )
+set(NGHTTP2_INCLUDE_DIRS ${NGHTTP2_INCLUDE_DIR})
 set(NGHTTP2_LIBRARIES ${NGHTTP2_LIBRARY})
 set(NGHTTP2_LIBRARIES ${NGHTTP2_LIBRARY})

+ 13 - 49
CMake/Macros.cmake

@@ -5,35 +5,35 @@
 # multiple times with a sequence of possibly dependent libraries in
 # multiple times with a sequence of possibly dependent libraries in
 # order of least-to-most-dependent.  Some libraries depend on others
 # order of least-to-most-dependent.  Some libraries depend on others
 # to link correctly.
 # to link correctly.
-macro(CHECK_LIBRARY_EXISTS_CONCAT LIBRARY SYMBOL VARIABLE)
+macro(check_library_exists_concat LIBRARY SYMBOL VARIABLE)
   check_library_exists("${LIBRARY};${CURL_LIBS}" ${SYMBOL} "${CMAKE_LIBRARY_PATH}"
   check_library_exists("${LIBRARY};${CURL_LIBS}" ${SYMBOL} "${CMAKE_LIBRARY_PATH}"
     ${VARIABLE})
     ${VARIABLE})
   if(${VARIABLE})
   if(${VARIABLE})
     set(CURL_LIBS ${LIBRARY} ${CURL_LIBS})
     set(CURL_LIBS ${LIBRARY} ${CURL_LIBS})
-  endif(${VARIABLE})
-endmacro(CHECK_LIBRARY_EXISTS_CONCAT)
+  endif()
+endmacro()
 
 
 # Check if header file exists and add it to the list.
 # Check if header file exists and add it to the list.
 # This macro is intended to be called multiple times with a sequence of
 # This macro is intended to be called multiple times with a sequence of
 # possibly dependent header files.  Some headers depend on others to be
 # possibly dependent header files.  Some headers depend on others to be
 # compiled correctly.
 # compiled correctly.
-macro(CHECK_INCLUDE_FILE_CONCAT FILE VARIABLE)
+macro(check_include_file_concat FILE VARIABLE)
   check_include_files("${CURL_INCLUDES};${FILE}" ${VARIABLE})
   check_include_files("${CURL_INCLUDES};${FILE}" ${VARIABLE})
   if(${VARIABLE})
   if(${VARIABLE})
     set(CURL_INCLUDES ${CURL_INCLUDES} ${FILE})
     set(CURL_INCLUDES ${CURL_INCLUDES} ${FILE})
     set(CURL_TEST_DEFINES "${CURL_TEST_DEFINES} -D${VARIABLE}")
     set(CURL_TEST_DEFINES "${CURL_TEST_DEFINES} -D${VARIABLE}")
-  endif(${VARIABLE})
-endmacro(CHECK_INCLUDE_FILE_CONCAT)
+  endif()
+endmacro()
 
 
 # For other curl specific tests, use this macro.
 # For other curl specific tests, use this macro.
-macro(CURL_INTERNAL_TEST CURL_TEST)
+macro(curl_internal_test CURL_TEST)
   if(NOT DEFINED "${CURL_TEST}")
   if(NOT DEFINED "${CURL_TEST}")
     set(MACRO_CHECK_FUNCTION_DEFINITIONS
     set(MACRO_CHECK_FUNCTION_DEFINITIONS
       "-D${CURL_TEST} ${CURL_TEST_DEFINES} ${CMAKE_REQUIRED_FLAGS}")
       "-D${CURL_TEST} ${CURL_TEST_DEFINES} ${CMAKE_REQUIRED_FLAGS}")
     if(CMAKE_REQUIRED_LIBRARIES)
     if(CMAKE_REQUIRED_LIBRARIES)
       set(CURL_TEST_ADD_LIBRARIES
       set(CURL_TEST_ADD_LIBRARIES
         "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}")
         "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}")
-    endif(CMAKE_REQUIRED_LIBRARIES)
+    endif()
 
 
     message(STATUS "Performing Curl Test ${CURL_TEST}")
     message(STATUS "Performing Curl Test ${CURL_TEST}")
     try_compile(${CURL_TEST}
     try_compile(${CURL_TEST}
@@ -48,53 +48,17 @@ macro(CURL_INTERNAL_TEST CURL_TEST)
       file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
       file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
         "Performing Curl Test ${CURL_TEST} passed with the following output:\n"
         "Performing Curl Test ${CURL_TEST} passed with the following output:\n"
         "${OUTPUT}\n")
         "${OUTPUT}\n")
-    else(${CURL_TEST})
+    else()
       message(STATUS "Performing Curl Test ${CURL_TEST} - Failed")
       message(STATUS "Performing Curl Test ${CURL_TEST} - Failed")
       set(${CURL_TEST} "" CACHE INTERNAL "Curl test ${FUNCTION}")
       set(${CURL_TEST} "" CACHE INTERNAL "Curl test ${FUNCTION}")
       file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
       file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
         "Performing Curl Test ${CURL_TEST} failed with the following output:\n"
         "Performing Curl Test ${CURL_TEST} failed with the following output:\n"
         "${OUTPUT}\n")
         "${OUTPUT}\n")
-    endif(${CURL_TEST})
-  endif()
-endmacro(CURL_INTERNAL_TEST)
-
-macro(CURL_INTERNAL_TEST_RUN CURL_TEST)
-  if(NOT DEFINED "${CURL_TEST}_COMPILE")
-    set(MACRO_CHECK_FUNCTION_DEFINITIONS
-      "-D${CURL_TEST} ${CMAKE_REQUIRED_FLAGS}")
-    if(CMAKE_REQUIRED_LIBRARIES)
-      set(CURL_TEST_ADD_LIBRARIES
-        "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}")
-    endif(CMAKE_REQUIRED_LIBRARIES)
-
-    message(STATUS "Performing Curl Test ${CURL_TEST}")
-    try_run(${CURL_TEST} ${CURL_TEST}_COMPILE
-      ${CMAKE_BINARY_DIR}
-      ${CMAKE_CURRENT_SOURCE_DIR}/CMake/CurlTests.c
-      CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
-      "${CURL_TEST_ADD_LIBRARIES}"
-      OUTPUT_VARIABLE OUTPUT)
-    if(${CURL_TEST}_COMPILE AND NOT ${CURL_TEST})
-      set(${CURL_TEST} 1 CACHE INTERNAL "Curl test ${FUNCTION}")
-      message(STATUS "Performing Curl Test ${CURL_TEST} - Success")
-    else(${CURL_TEST}_COMPILE AND NOT ${CURL_TEST})
-      message(STATUS "Performing Curl Test ${CURL_TEST} - Failed")
-      set(${CURL_TEST} "" CACHE INTERNAL "Curl test ${FUNCTION}")
-      file(APPEND "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log"
-        "Performing Curl Test ${CURL_TEST} failed with the following output:\n"
-        "${OUTPUT}")
-      if(${CURL_TEST}_COMPILE)
-        file(APPEND
-          "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log"
-          "There was a problem running this test\n")
-      endif(${CURL_TEST}_COMPILE)
-      file(APPEND "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log"
-        "\n\n")
-    endif(${CURL_TEST}_COMPILE AND NOT ${CURL_TEST})
+    endif()
   endif()
   endif()
-endmacro(CURL_INTERNAL_TEST_RUN)
+endmacro()
 
 
-macro(CURL_NROFF_CHECK)
+macro(curl_nroff_check)
   find_program(NROFF NAMES gnroff nroff)
   find_program(NROFF NAMES gnroff nroff)
   if(NROFF)
   if(NROFF)
     # Need a way to write to stdin, this will do
     # Need a way to write to stdin, this will do
@@ -121,4 +85,4 @@ macro(CURL_NROFF_CHECK)
   else()
   else()
     message(WARNING "Found no *nroff program")
     message(WARNING "Found no *nroff program")
   endif()
   endif()
-endmacro(CURL_NROFF_CHECK)
+endmacro()

+ 30 - 31
CMake/OtherTests.cmake

@@ -5,8 +5,8 @@ set(_source_epilogue "#undef inline")
 macro(add_header_include check header)
 macro(add_header_include check header)
   if(${check})
   if(${check})
     set(_source_epilogue "${_source_epilogue}\n#include <${header}>")
     set(_source_epilogue "${_source_epilogue}\n#include <${header}>")
-  endif(${check})
-endmacro(add_header_include)
+  endif()
+endmacro()
 
 
 set(signature_call_conv)
 set(signature_call_conv)
 if(HAVE_WINDOWS_H)
 if(HAVE_WINDOWS_H)
@@ -19,10 +19,10 @@ if(HAVE_WINDOWS_H)
   if(HAVE_LIBWS2_32)
   if(HAVE_LIBWS2_32)
     set(CMAKE_REQUIRED_LIBRARIES ws2_32)
     set(CMAKE_REQUIRED_LIBRARIES ws2_32)
   endif()
   endif()
-else(HAVE_WINDOWS_H)
+else()
   add_header_include(HAVE_SYS_TYPES_H "sys/types.h")
   add_header_include(HAVE_SYS_TYPES_H "sys/types.h")
   add_header_include(HAVE_SYS_SOCKET_H "sys/socket.h")
   add_header_include(HAVE_SYS_SOCKET_H "sys/socket.h")
-endif(HAVE_WINDOWS_H)
+endif()
 
 
 check_c_source_compiles("${_source_epilogue}
 check_c_source_compiles("${_source_epilogue}
 int main(void) {
 int main(void) {
@@ -64,13 +64,13 @@ if(curl_cv_recv)
                   set(RECV_TYPE_RETV "${recv_retv}")
                   set(RECV_TYPE_RETV "${recv_retv}")
                   set(HAVE_RECV 1)
                   set(HAVE_RECV 1)
                   set(curl_cv_func_recv_done 1)
                   set(curl_cv_func_recv_done 1)
-                endif(curl_cv_func_recv_test)
-              endif(NOT curl_cv_func_recv_done)
-            endforeach(recv_arg4)
-          endforeach(recv_arg3)
-        endforeach(recv_arg2)
-      endforeach(recv_arg1)
-    endforeach(recv_retv)
+                endif()
+              endif()
+            endforeach()
+          endforeach()
+        endforeach()
+      endforeach()
+    endforeach()
   else()
   else()
     string(REGEX REPLACE "^([^,]*),[^,]*,[^,]*,[^,]*,[^,]*$" "\\1" RECV_TYPE_ARG1 "${curl_cv_func_recv_args}")
     string(REGEX REPLACE "^([^,]*),[^,]*,[^,]*,[^,]*,[^,]*$" "\\1" RECV_TYPE_ARG1 "${curl_cv_func_recv_args}")
     string(REGEX REPLACE "^[^,]*,([^,]*),[^,]*,[^,]*,[^,]*$" "\\1" RECV_TYPE_ARG2 "${curl_cv_func_recv_args}")
     string(REGEX REPLACE "^[^,]*,([^,]*),[^,]*,[^,]*,[^,]*$" "\\1" RECV_TYPE_ARG2 "${curl_cv_func_recv_args}")
@@ -81,10 +81,10 @@ if(curl_cv_recv)
 
 
   if("${curl_cv_func_recv_args}" STREQUAL "unknown")
   if("${curl_cv_func_recv_args}" STREQUAL "unknown")
     message(FATAL_ERROR "Cannot find proper types to use for recv args")
     message(FATAL_ERROR "Cannot find proper types to use for recv args")
-  endif("${curl_cv_func_recv_args}" STREQUAL "unknown")
-else(curl_cv_recv)
+  endif()
+else()
   message(FATAL_ERROR "Unable to link function recv")
   message(FATAL_ERROR "Unable to link function recv")
-endif(curl_cv_recv)
+endif()
 set(curl_cv_func_recv_args "${curl_cv_func_recv_args}" CACHE INTERNAL "Arguments for recv")
 set(curl_cv_func_recv_args "${curl_cv_func_recv_args}" CACHE INTERNAL "Arguments for recv")
 set(HAVE_RECV 1)
 set(HAVE_RECV 1)
 
 
@@ -130,13 +130,13 @@ if(curl_cv_send)
                   set(SEND_TYPE_RETV "${send_retv}")
                   set(SEND_TYPE_RETV "${send_retv}")
                   set(HAVE_SEND 1)
                   set(HAVE_SEND 1)
                   set(curl_cv_func_send_done 1)
                   set(curl_cv_func_send_done 1)
-                endif(curl_cv_func_send_test)
-              endif(NOT curl_cv_func_send_done)
-            endforeach(send_arg4)
-          endforeach(send_arg3)
-        endforeach(send_arg2)
-      endforeach(send_arg1)
-    endforeach(send_retv)
+                endif()
+              endif()
+            endforeach()
+          endforeach()
+        endforeach()
+      endforeach()
+    endforeach()
   else()
   else()
     string(REGEX REPLACE "^([^,]*),[^,]*,[^,]*,[^,]*,[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG1 "${curl_cv_func_send_args}")
     string(REGEX REPLACE "^([^,]*),[^,]*,[^,]*,[^,]*,[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG1 "${curl_cv_func_send_args}")
     string(REGEX REPLACE "^[^,]*,([^,]*),[^,]*,[^,]*,[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG2 "${curl_cv_func_send_args}")
     string(REGEX REPLACE "^[^,]*,([^,]*),[^,]*,[^,]*,[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG2 "${curl_cv_func_send_args}")
@@ -148,11 +148,11 @@ if(curl_cv_send)
 
 
   if("${curl_cv_func_send_args}" STREQUAL "unknown")
   if("${curl_cv_func_send_args}" STREQUAL "unknown")
     message(FATAL_ERROR "Cannot find proper types to use for send args")
     message(FATAL_ERROR "Cannot find proper types to use for send args")
-  endif("${curl_cv_func_send_args}" STREQUAL "unknown")
+  endif()
   set(SEND_QUAL_ARG2 "const")
   set(SEND_QUAL_ARG2 "const")
-else(curl_cv_send)
+else()
   message(FATAL_ERROR "Unable to link function send")
   message(FATAL_ERROR "Unable to link function send")
-endif(curl_cv_send)
+endif()
 set(curl_cv_func_send_args "${curl_cv_func_send_args}" CACHE INTERNAL "Arguments for send")
 set(curl_cv_func_send_args "${curl_cv_func_send_args}" CACHE INTERNAL "Arguments for send")
 set(HAVE_SEND 1)
 set(HAVE_SEND 1)
 
 
@@ -184,7 +184,7 @@ if(NOT APPLE)
   set(CMAKE_REQUIRED_FLAGS)
   set(CMAKE_REQUIRED_FLAGS)
   if(HAVE_SYS_POLL_H)
   if(HAVE_SYS_POLL_H)
     set(CMAKE_REQUIRED_FLAGS "-DHAVE_SYS_POLL_H")
     set(CMAKE_REQUIRED_FLAGS "-DHAVE_SYS_POLL_H")
-  endif(HAVE_SYS_POLL_H)
+  endif()
   check_c_source_runs("
   check_c_source_runs("
     #ifdef HAVE_SYS_POLL_H
     #ifdef HAVE_SYS_POLL_H
     #  include <sys/poll.h>
     #  include <sys/poll.h>
@@ -199,7 +199,7 @@ set(CMAKE_REQUIRED_FLAGS)
 if(HAVE_SIGNAL_H)
 if(HAVE_SIGNAL_H)
   set(CMAKE_REQUIRED_FLAGS "-DHAVE_SIGNAL_H")
   set(CMAKE_REQUIRED_FLAGS "-DHAVE_SIGNAL_H")
   set(CMAKE_EXTRA_INCLUDE_FILES "signal.h")
   set(CMAKE_EXTRA_INCLUDE_FILES "signal.h")
-endif(HAVE_SIGNAL_H)
+endif()
 check_type_size("sig_atomic_t" SIZEOF_SIG_ATOMIC_T)
 check_type_size("sig_atomic_t" SIZEOF_SIG_ATOMIC_T)
 if(HAVE_SIZEOF_SIG_ATOMIC_T)
 if(HAVE_SIZEOF_SIG_ATOMIC_T)
   check_c_source_compiles("
   check_c_source_compiles("
@@ -213,8 +213,8 @@ if(HAVE_SIZEOF_SIG_ATOMIC_T)
     }" HAVE_SIG_ATOMIC_T_NOT_VOLATILE)
     }" HAVE_SIG_ATOMIC_T_NOT_VOLATILE)
   if(NOT HAVE_SIG_ATOMIC_T_NOT_VOLATILE)
   if(NOT HAVE_SIG_ATOMIC_T_NOT_VOLATILE)
     set(HAVE_SIG_ATOMIC_T_VOLATILE 1)
     set(HAVE_SIG_ATOMIC_T_VOLATILE 1)
-  endif(NOT HAVE_SIG_ATOMIC_T_NOT_VOLATILE)
-endif(HAVE_SIZEOF_SIG_ATOMIC_T)
+  endif()
+endif()
 
 
 if(HAVE_WINDOWS_H)
 if(HAVE_WINDOWS_H)
   set(CMAKE_EXTRA_INCLUDE_FILES winsock2.h)
   set(CMAKE_EXTRA_INCLUDE_FILES winsock2.h)
@@ -222,11 +222,10 @@ else()
   set(CMAKE_EXTRA_INCLUDE_FILES)
   set(CMAKE_EXTRA_INCLUDE_FILES)
   if(HAVE_SYS_SOCKET_H)
   if(HAVE_SYS_SOCKET_H)
     set(CMAKE_EXTRA_INCLUDE_FILES sys/socket.h)
     set(CMAKE_EXTRA_INCLUDE_FILES sys/socket.h)
-  endif(HAVE_SYS_SOCKET_H)
+  endif()
 endif()
 endif()
 
 
 check_type_size("struct sockaddr_storage" SIZEOF_STRUCT_SOCKADDR_STORAGE)
 check_type_size("struct sockaddr_storage" SIZEOF_STRUCT_SOCKADDR_STORAGE)
 if(HAVE_SIZEOF_STRUCT_SOCKADDR_STORAGE)
 if(HAVE_SIZEOF_STRUCT_SOCKADDR_STORAGE)
   set(HAVE_STRUCT_SOCKADDR_STORAGE 1)
   set(HAVE_STRUCT_SOCKADDR_STORAGE 1)
-endif(HAVE_SIZEOF_STRUCT_SOCKADDR_STORAGE)
-
+endif()

+ 3 - 4
CMake/Platforms/WindowsCache.cmake

@@ -118,8 +118,7 @@ if(NOT UNIX)
 
 
     set(HAVE_SIGACTION 0)
     set(HAVE_SIGACTION 0)
     set(HAVE_MACRO_SIGSETJMP 0)
     set(HAVE_MACRO_SIGSETJMP 0)
-  else(WIN32)
+  else()
     message("This file should be included on Windows platform only")
     message("This file should be included on Windows platform only")
-  endif(WIN32)
-endif(NOT UNIX)
-
+  endif()
+endif()

+ 5 - 36
CMake/Utilities.cmake

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

+ 9 - 9
CMake/cmake_uninstall.cmake.in

@@ -1,11 +1,11 @@
 if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
 if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
   message(FATAL_ERROR "Cannot find install manifest: @CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
   message(FATAL_ERROR "Cannot find install manifest: @CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
-endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
+endif()
 
 
-if (NOT DEFINED CMAKE_INSTALL_PREFIX)
-  set (CMAKE_INSTALL_PREFIX "@CMAKE_INSTALL_PREFIX@")
-endif ()
- message(${CMAKE_INSTALL_PREFIX})
+if(NOT DEFINED CMAKE_INSTALL_PREFIX)
+  set(CMAKE_INSTALL_PREFIX "@CMAKE_INSTALL_PREFIX@")
+endif()
+message(${CMAKE_INSTALL_PREFIX})
 
 
 file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
 file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
 string(REGEX REPLACE "\n" ";" files "${files}")
 string(REGEX REPLACE "\n" ";" files "${files}")
@@ -19,8 +19,8 @@ foreach(file ${files})
       )
       )
     if(NOT "${rm_retval}" STREQUAL 0)
     if(NOT "${rm_retval}" STREQUAL 0)
       message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}")
       message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}")
-    endif(NOT "${rm_retval}" STREQUAL 0)
-  else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
+    endif()
+  else()
     message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
     message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
-  endif(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
-endforeach(file)
+  endif()
+endforeach()

+ 0 - 59
CMake/curl-config.cmake

@@ -1,59 +0,0 @@
-
-get_filename_component(_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
-
-if(NOT CURL_FIND_COMPONENTS)
-    set(CURL_FIND_COMPONENTS curl libcurl)
-    if(CURL_FIND_REQUIRED)
-        set(CURL_FIND_REQUIRED_curl TRUE)
-        set(CURL_FIND_REQUIRED_libcurl TRUE)
-    endif()
-endif()
-
-set(_curl_missing_components)
-foreach(_comp ${CURL_FIND_COMPONENTS})
-    if(EXISTS "${_DIR}/${_comp}-target.cmake")
-        include("${_DIR}/${_comp}-target.cmake")
-        set(CURL_${_comp}_FOUND TRUE)
-    else()
-        set(CURL_${_comp}_FOUND FALSE)
-        if(CURL_FIND_REQUIRED_${_comp})
-            set(CURL_FOUND FALSE)
-            list(APPEND _curl_missing_components ${_comp})
-        endif()
-    endif()
-endforeach()
-
-if(_curl_missing_components)
-    set(CURL_NOT_FOUND_MESSAGE "Following required components not found: " ${_curl_missing_components})
-else()
-    if(TARGET CURL::libcurl)
-        string(TOUPPER "${CMAKE_BUILD_TYPE}" _curl_current_config)
-        if(NOT _curl_current_config)
-            set(_curl_current_config "NOCONFIG")
-        endif()
-        get_target_property(_curl_configurations CURL::libcurl IMPORTED_CONFIGURATIONS)
-        list(FIND _curl_configurations "${_curl_current_config}" _i)
-        if(_i LESS 0)
-            set(_curl_config "RELEASE")
-            list(FIND _curl_configurations "${_curl_current_config}" _i)
-            if(_i LESS 0)
-                set(_curl_config "NOCONFIG")
-                list(FIND _curl_configurations "${_curl_current_config}" _i)
-            endif()
-        endif()
-
-        if(_i LESS 0)
-            set(_curl_current_config "") # let CMake pick config at random
-        else()
-	    set(_curl_current_config "_${_curl_current_config}")
-        endif()
-
-        get_target_property(CURL_INCLUDE_DIRS CURL::libcurl INTERFACE_INCLUDE_DIRECTORIES)
-        get_target_property(CURL_LIBRARIES CURL::libcurl "LOCATION${_curl_current_config}")
-        set(_curl_current_config)
-        set(_curl_configurations)
-        set(_i)
-    endif()
-endif()
-
-unset(_curl_missing_components)

+ 64 - 0
CMake/curl-config.cmake.in

@@ -0,0 +1,64 @@
+
+get_filename_component(_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
+
+if(NOT CURL_FIND_COMPONENTS)
+  set(CURL_FIND_COMPONENTS curl libcurl)
+  if(CURL_FIND_REQUIRED)
+    set(CURL_FIND_REQUIRED_curl TRUE)
+    set(CURL_FIND_REQUIRED_libcurl TRUE)
+  endif()
+endif()
+
+include(CMakeFindDependencyMacro)
+if(CURL_FIND_REQUIRED_libcurl)
+    find_dependency(OpenSSL "@OPENSSL_VERSION_MAJOR@")
+endif()
+
+set(_curl_missing_components)
+foreach(_comp ${CURL_FIND_COMPONENTS})
+  if(EXISTS "${_DIR}/${_comp}-target.cmake")
+    include("${_DIR}/${_comp}-target.cmake")
+    set(CURL_${_comp}_FOUND TRUE)
+  else()
+    set(CURL_${_comp}_FOUND FALSE)
+    if(CURL_FIND_REQUIRED_${_comp})
+      set(CURL_FOUND FALSE)
+      list(APPEND _curl_missing_components ${_comp})
+    endif()
+  endif()
+endforeach()
+
+if(_curl_missing_components)
+  set(CURL_NOT_FOUND_MESSAGE "Following required components not found: " ${_curl_missing_components})
+else()
+  if(TARGET CURL::libcurl)
+    string(TOUPPER "${CMAKE_BUILD_TYPE}" _curl_current_config)
+    if(NOT _curl_current_config)
+      set(_curl_current_config "NOCONFIG")
+    endif()
+    get_target_property(_curl_configurations CURL::libcurl IMPORTED_CONFIGURATIONS)
+    list(FIND _curl_configurations "${_curl_current_config}" _i)
+    if(_i LESS 0)
+      set(_curl_config "RELEASE")
+      list(FIND _curl_configurations "${_curl_current_config}" _i)
+      if(_i LESS 0)
+        set(_curl_config "NOCONFIG")
+        list(FIND _curl_configurations "${_curl_current_config}" _i)
+      endif()
+    endif()
+
+    if(_i LESS 0)
+      set(_curl_current_config "") # let CMake pick config at random
+    else()
+      set(_curl_current_config "_${_curl_current_config}")
+    endif()
+
+    get_target_property(CURL_INCLUDE_DIRS CURL::libcurl INTERFACE_INCLUDE_DIRECTORIES)
+    get_target_property(CURL_LIBRARIES CURL::libcurl "LOCATION${_curl_current_config}")
+    set(_curl_current_config)
+    set(_curl_configurations)
+    set(_i)
+  endif()
+endif()
+
+unset(_curl_missing_components)

+ 145 - 140
CMakeLists.txt

@@ -38,24 +38,24 @@
 # To check:
 # 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 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.
 # (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.12 FATAL_ERROR)
+cmake_minimum_required(VERSION 3.4 FATAL_ERROR)
 set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake;${CMAKE_MODULE_PATH}")
 set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake;${CMAKE_MODULE_PATH}")
 include(Utilities)
 include(Utilities)
 include(Macros)
 include(Macros)
 include(CMakeDependentOption)
 include(CMakeDependentOption)
 include(CheckCCompilerFlag)
 include(CheckCCompilerFlag)
 
 
-project( CURL C )
+project(CURL C)
 
 
 message(WARNING "the curl cmake build system is poorly maintained. Be aware")
 message(WARNING "the curl cmake build system is poorly maintained. Be aware")
 
 
-file (READ ${CURL_SOURCE_DIR}/include/curl/curlver.h CURL_VERSION_H_CONTENTS)
-string (REGEX MATCH "#define LIBCURL_VERSION \"[^\"]*"
+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})
   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]+"
+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})
   CURL_VERSION_NUM ${CURL_VERSION_H_CONTENTS})
-string (REGEX REPLACE "[^0]+0x" "" CURL_VERSION_NUM ${CURL_VERSION_NUM})
+string(REGEX REPLACE "[^0]+0x" "" CURL_VERSION_NUM ${CURL_VERSION_NUM})
 
 
 include_regular_expression("^.*$")    # Sukender: Is it necessary?
 include_regular_expression("^.*$")    # Sukender: Is it necessary?
 
 
@@ -71,19 +71,19 @@ set(OPERATING_SYSTEM "${CMAKE_SYSTEM_NAME}")
 set(OS "\"${CMAKE_SYSTEM_NAME}\"")
 set(OS "\"${CMAKE_SYSTEM_NAME}\"")
 
 
 include_directories(${PROJECT_BINARY_DIR}/include/curl)
 include_directories(${PROJECT_BINARY_DIR}/include/curl)
-include_directories( ${CURL_SOURCE_DIR}/include )
+include_directories(${CURL_SOURCE_DIR}/include)
 
 
 option(CURL_WERROR "Turn compiler warnings into errors" OFF)
 option(CURL_WERROR "Turn compiler warnings into errors" OFF)
 option(PICKY_COMPILER "Enable picky compiler options" ON)
 option(PICKY_COMPILER "Enable picky compiler options" ON)
 option(BUILD_CURL_EXE "Set to ON to build curl executable." ON)
 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(BUILD_SHARED_LIBS "Build shared libraries" ON)
 option(ENABLE_ARES "Set to ON to enable c-ares support" OFF)
 option(ENABLE_ARES "Set to ON to enable c-ares support" OFF)
 if(WIN32)
 if(WIN32)
   option(CURL_STATIC_CRT "Set to ON to build libcurl with static CRT on Windows (/MT)." OFF)
   option(CURL_STATIC_CRT "Set to ON to build libcurl with static CRT on Windows (/MT)." OFF)
   option(ENABLE_INET_PTON "Set to OFF to prevent usage of inet_pton when building against modern SDKs while still requiring compatibility with older Windows versions, such as Windows XP, Windows Server 2003 etc." ON)
   option(ENABLE_INET_PTON "Set to OFF to prevent usage of inet_pton when building against modern SDKs while still requiring compatibility with older Windows versions, such as Windows XP, Windows Server 2003 etc." ON)
 endif()
 endif()
 
 
-CMAKE_DEPENDENT_OPTION(ENABLE_THREADED_RESOLVER "Set to ON to enable threaded DNS lookup"
+cmake_dependent_option(ENABLE_THREADED_RESOLVER "Set to ON to enable threaded DNS lookup"
         ON "NOT ENABLE_ARES"
         ON "NOT ENABLE_ARES"
         OFF)
         OFF)
 
 
@@ -91,19 +91,19 @@ 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)
 option(ENABLE_CURLDEBUG "Set to ON to build with TrackMemory feature enabled" OFF)
 
 
 if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG)
 if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG)
-  if (PICKY_COMPILER)
-    foreach (_CCOPT -pedantic -Wall -W -Wpointer-arith -Wwrite-strings -Wunused -Wshadow -Winline -Wnested-externs -Wmissing-declarations -Wmissing-prototypes -Wno-long-long -Wfloat-equal -Wno-multichar -Wsign-compare -Wundef -Wno-format-nonliteral -Wendif-labels -Wstrict-prototypes -Wdeclaration-after-statement -Wstrict-aliasing=3 -Wcast-align -Wtype-limits -Wold-style-declaration -Wmissing-parameter-type -Wempty-body -Wclobbered -Wignored-qualifiers -Wconversion -Wno-sign-conversion -Wvla -Wdouble-promotion -Wno-system-headers)
+  if(PICKY_COMPILER)
+    foreach(_CCOPT -pedantic -Wall -W -Wpointer-arith -Wwrite-strings -Wunused -Wshadow -Winline -Wnested-externs -Wmissing-declarations -Wmissing-prototypes -Wno-long-long -Wfloat-equal -Wno-multichar -Wsign-compare -Wundef -Wno-format-nonliteral -Wendif-labels -Wstrict-prototypes -Wdeclaration-after-statement -Wstrict-aliasing=3 -Wcast-align -Wtype-limits -Wold-style-declaration -Wmissing-parameter-type -Wempty-body -Wclobbered -Wignored-qualifiers -Wconversion -Wno-sign-conversion -Wvla -Wdouble-promotion -Wno-system-headers)
       # surprisingly, CHECK_C_COMPILER_FLAG needs a new variable to store each new
       # surprisingly, CHECK_C_COMPILER_FLAG needs a new variable to store each new
       # test result in.
       # test result in.
-      CHECK_C_COMPILER_FLAG(${_CCOPT} OPT${_CCOPT})
+      check_c_compiler_flag(${_CCOPT} OPT${_CCOPT})
       if(OPT${_CCOPT})
       if(OPT${_CCOPT})
         set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${_CCOPT}")
         set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${_CCOPT}")
       endif()
       endif()
     endforeach()
     endforeach()
-  endif(PICKY_COMPILER)
-endif(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG)
+  endif()
+endif()
 
 
-if (ENABLE_DEBUG)
+if(ENABLE_DEBUG)
   # DEBUGBUILD will be defined only for Debug builds
   # DEBUGBUILD will be defined only for Debug builds
   if(NOT CMAKE_VERSION VERSION_LESS 3.0)
   if(NOT CMAKE_VERSION VERSION_LESS 3.0)
     set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS $<$<CONFIG:Debug>:DEBUGBUILD>)
     set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS $<$<CONFIG:Debug>:DEBUGBUILD>)
@@ -113,12 +113,14 @@ if (ENABLE_DEBUG)
   set(ENABLE_CURLDEBUG ON)
   set(ENABLE_CURLDEBUG ON)
 endif()
 endif()
 
 
-if (ENABLE_CURLDEBUG)
+if(ENABLE_CURLDEBUG)
   set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS CURLDEBUG)
   set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS CURLDEBUG)
 endif()
 endif()
 
 
 # For debug libs and exes, add "-d" postfix
 # For debug libs and exes, add "-d" postfix
-set(CMAKE_DEBUG_POSTFIX "-d" CACHE STRING "Set debug library postfix")
+if(NOT DEFINED CMAKE_DEBUG_POSTFIX)
+  set(CMAKE_DEBUG_POSTFIX "-d")
+endif()
 
 
 # initialize CURL_LIBS
 # initialize CURL_LIBS
 set(CURL_LIBS "")
 set(CURL_LIBS "")
@@ -126,7 +128,7 @@ set(CURL_LIBS "")
 if(ENABLE_ARES)
 if(ENABLE_ARES)
   set(USE_ARES 1)
   set(USE_ARES 1)
   find_package(CARES REQUIRED)
   find_package(CARES REQUIRED)
-  list(APPEND CURL_LIBS ${CARES_LIBRARY} )
+  list(APPEND CURL_LIBS ${CARES_LIBRARY})
   set(CURL_LIBS ${CURL_LIBS} ${CARES_LIBRARY})
   set(CURL_LIBS ${CURL_LIBS} ${CARES_LIBRARY})
 endif()
 endif()
 
 
@@ -203,10 +205,10 @@ if(ENABLE_IPV6 AND NOT WIN32)
   endif()
   endif()
 endif()
 endif()
 
 
-CURL_NROFF_CHECK()
+curl_nroff_check()
 find_package(Perl)
 find_package(Perl)
 
 
-CMAKE_DEPENDENT_OPTION(ENABLE_MANUAL "to provide the built-in manual"
+cmake_dependent_option(ENABLE_MANUAL "to provide the built-in manual"
     ON "NROFF_USEFUL;PERL_FOUND"
     ON "NROFF_USEFUL;PERL_FOUND"
     OFF)
     OFF)
 
 
@@ -230,28 +232,28 @@ endif()
 # Disable warnings on Borland to avoid changing 3rd party code.
 # Disable warnings on Borland to avoid changing 3rd party code.
 if(BORLAND)
 if(BORLAND)
   set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w-")
   set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w-")
-endif(BORLAND)
+endif()
 
 
 # If we are on AIX, do the _ALL_SOURCE magic
 # If we are on AIX, do the _ALL_SOURCE magic
 if(${CMAKE_SYSTEM_NAME} MATCHES AIX)
 if(${CMAKE_SYSTEM_NAME} MATCHES AIX)
   set(_ALL_SOURCE 1)
   set(_ALL_SOURCE 1)
-endif(${CMAKE_SYSTEM_NAME} MATCHES AIX)
+endif()
 
 
 # Include all the necessary files for macros
 # Include all the necessary files for macros
-include (CheckFunctionExists)
-include (CheckIncludeFile)
-include (CheckIncludeFiles)
-include (CheckLibraryExists)
-include (CheckSymbolExists)
-include (CheckTypeSize)
-include (CheckCSourceCompiles)
-include (CMakeDependentOption)
+include(CheckFunctionExists)
+include(CheckIncludeFile)
+include(CheckIncludeFiles)
+include(CheckLibraryExists)
+include(CheckSymbolExists)
+include(CheckTypeSize)
+include(CheckCSourceCompiles)
+include(CMakeDependentOption)
 
 
 # On windows preload settings
 # On windows preload settings
 if(WIN32)
 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)
   include(${CMAKE_CURRENT_SOURCE_DIR}/CMake/Platforms/WindowsCache.cmake)
-endif(WIN32)
+endif()
 
 
 if(ENABLE_THREADED_RESOLVER)
 if(ENABLE_THREADED_RESOLVER)
   find_package(Threads REQUIRED)
   find_package(Threads REQUIRED)
@@ -274,11 +276,11 @@ if(BEOS)
   set(NOT_NEED_LIBNSL 1)
   set(NOT_NEED_LIBNSL 1)
   check_library_exists_concat("bind" gethostbyname HAVE_LIBBIND)
   check_library_exists_concat("bind" gethostbyname HAVE_LIBBIND)
   check_library_exists_concat("bnetapi" closesocket HAVE_LIBBNETAPI)
   check_library_exists_concat("bnetapi" closesocket HAVE_LIBBNETAPI)
-endif(BEOS)
+endif()
 
 
 if(NOT NOT_NEED_LIBNSL)
 if(NOT NOT_NEED_LIBNSL)
   check_library_exists_concat("nsl"    gethostbyname  HAVE_LIBNSL)
   check_library_exists_concat("nsl"    gethostbyname  HAVE_LIBNSL)
-endif(NOT NOT_NEED_LIBNSL)
+endif()
 
 
 check_function_exists(gethostname HAVE_GETHOSTNAME)
 check_function_exists(gethostname HAVE_GETHOSTNAME)
 
 
@@ -307,14 +309,14 @@ if(WIN32 OR CMAKE_USE_DARWINSSL OR CMAKE_USE_WINSSL OR CMAKE_USE_MBEDTLS)
 endif()
 endif()
 option(CMAKE_USE_OPENSSL "Use OpenSSL code. Experimental" ${openssl_default})
 option(CMAKE_USE_OPENSSL "Use OpenSSL code. Experimental" ${openssl_default})
 
 
-collect_true(enabled_ssl_options enabled_ssl_options_count
+count_true(enabled_ssl_options_count
   CMAKE_USE_WINSSL
   CMAKE_USE_WINSSL
   CMAKE_USE_DARWINSSL
   CMAKE_USE_DARWINSSL
   CMAKE_USE_OPENSSL
   CMAKE_USE_OPENSSL
   CMAKE_USE_MBEDTLS
   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.")
+if(enabled_ssl_options_count GREATER "1")
+  set(CURL_WITH_MULTI_SSL ON)
 endif()
 endif()
 
 
 if(CMAKE_USE_WINSSL)
 if(CMAKE_USE_WINSSL)
@@ -350,11 +352,10 @@ if(CMAKE_USE_OPENSSL)
   set(USE_OPENSSL ON)
   set(USE_OPENSSL ON)
   set(HAVE_LIBCRYPTO ON)
   set(HAVE_LIBCRYPTO ON)
   set(HAVE_LIBSSL ON)
   set(HAVE_LIBSSL ON)
-  list(APPEND CURL_LIBS ${OPENSSL_LIBRARIES})
-  include_directories(${OPENSSL_INCLUDE_DIR})
+  list(APPEND CURL_LIBS OpenSSL::SSL OpenSSL::Crypto)
+
   set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
   set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
   check_include_file("openssl/crypto.h" HAVE_OPENSSL_CRYPTO_H)
   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/err.h"    HAVE_OPENSSL_ERR_H)
   check_include_file("openssl/pem.h"    HAVE_OPENSSL_PEM_H)
   check_include_file("openssl/pem.h"    HAVE_OPENSSL_PEM_H)
   check_include_file("openssl/rsa.h"    HAVE_OPENSSL_RSA_H)
   check_include_file("openssl/rsa.h"    HAVE_OPENSSL_RSA_H)
@@ -474,7 +475,6 @@ if(NOT CURL_DISABLE_LDAP)
       endif()
       endif()
     endif()
     endif()
   endif()
   endif()
-
 endif()
 endif()
 
 
 # No ldap, no ldaps.
 # No ldap, no ldaps.
@@ -554,9 +554,8 @@ if(CMAKE_USE_LIBSSH2)
     check_function_exists(libssh2_scp_send64        HAVE_LIBSSH2_SCP_SEND64)
     check_function_exists(libssh2_scp_send64        HAVE_LIBSSH2_SCP_SEND64)
     check_function_exists(libssh2_session_handshake HAVE_LIBSSH2_SESSION_HANDSHAKE)
     check_function_exists(libssh2_session_handshake HAVE_LIBSSH2_SESSION_HANDSHAKE)
     set(CMAKE_EXTRA_INCLUDE_FILES "")
     set(CMAKE_EXTRA_INCLUDE_FILES "")
-
-  endif(LIBSSH2_FOUND)
-endif(CMAKE_USE_LIBSSH2)
+  endif()
+endif()
 
 
 option(CMAKE_USE_GSSAPI "Use GSSAPI implementation (right now only Heimdal is supported with CMake build)" OFF)
 option(CMAKE_USE_GSSAPI "Use GSSAPI implementation (right now only Heimdal is supported with CMake build)" OFF)
 mark_as_advanced(CMAKE_USE_GSSAPI)
 mark_as_advanced(CMAKE_USE_GSSAPI)
@@ -625,7 +624,6 @@ else()
   unset(USE_UNIX_SOCKETS CACHE)
   unset(USE_UNIX_SOCKETS CACHE)
 endif()
 endif()
 
 
-
 #
 #
 # CA handling
 # CA handling
 #
 #
@@ -637,67 +635,66 @@ set(CURL_CA_PATH "auto" CACHE STRING
     "Location of default CA path. Set 'none' to disable or 'auto' for auto-detection. Defaults to 'auto'.")
     "Location of default CA path. Set 'none' to disable or 'auto' for auto-detection. Defaults to 'auto'.")
 
 
 if("${CURL_CA_BUNDLE}" STREQUAL "")
 if("${CURL_CA_BUNDLE}" STREQUAL "")
-    message(FATAL_ERROR "Invalid value of CURL_CA_BUNDLE. Use 'none', 'auto' or file path.")
+  message(FATAL_ERROR "Invalid value of CURL_CA_BUNDLE. Use 'none', 'auto' or file path.")
 elseif("${CURL_CA_BUNDLE}" STREQUAL "none")
 elseif("${CURL_CA_BUNDLE}" STREQUAL "none")
-    unset(CURL_CA_BUNDLE CACHE)
+  unset(CURL_CA_BUNDLE CACHE)
 elseif("${CURL_CA_BUNDLE}" STREQUAL "auto")
 elseif("${CURL_CA_BUNDLE}" STREQUAL "auto")
-    unset(CURL_CA_BUNDLE CACHE)
-    set(CURL_CA_BUNDLE_AUTODETECT TRUE)
+  unset(CURL_CA_BUNDLE CACHE)
+  set(CURL_CA_BUNDLE_AUTODETECT TRUE)
 else()
 else()
-    set(CURL_CA_BUNDLE_SET TRUE)
+  set(CURL_CA_BUNDLE_SET TRUE)
 endif()
 endif()
 
 
 if("${CURL_CA_PATH}" STREQUAL "")
 if("${CURL_CA_PATH}" STREQUAL "")
-    message(FATAL_ERROR "Invalid value of CURL_CA_PATH. Use 'none', 'auto' or directory path.")
+  message(FATAL_ERROR "Invalid value of CURL_CA_PATH. Use 'none', 'auto' or directory path.")
 elseif("${CURL_CA_PATH}" STREQUAL "none")
 elseif("${CURL_CA_PATH}" STREQUAL "none")
-    unset(CURL_CA_PATH CACHE)
+  unset(CURL_CA_PATH CACHE)
 elseif("${CURL_CA_PATH}" STREQUAL "auto")
 elseif("${CURL_CA_PATH}" STREQUAL "auto")
-    unset(CURL_CA_PATH CACHE)
-    set(CURL_CA_PATH_AUTODETECT TRUE)
+  unset(CURL_CA_PATH CACHE)
+  set(CURL_CA_PATH_AUTODETECT TRUE)
 else()
 else()
-    set(CURL_CA_PATH_SET TRUE)
+  set(CURL_CA_PATH_SET TRUE)
 endif()
 endif()
 
 
 if(CURL_CA_BUNDLE_SET AND CURL_CA_PATH_AUTODETECT)
 if(CURL_CA_BUNDLE_SET AND CURL_CA_PATH_AUTODETECT)
-    # Skip autodetection of unset CA path because CA bundle is set explicitly
+  # Skip autodetection of unset CA path because CA bundle is set explicitly
 elseif(CURL_CA_PATH_SET AND CURL_CA_BUNDLE_AUTODETECT)
 elseif(CURL_CA_PATH_SET AND CURL_CA_BUNDLE_AUTODETECT)
-    # Skip autodetection of unset CA bundle because CA path is set explicitly
+  # Skip autodetection of unset CA bundle because CA path is set explicitly
 elseif(CURL_CA_PATH_AUTODETECT OR CURL_CA_BUNDLE_AUTODETECT)
 elseif(CURL_CA_PATH_AUTODETECT OR CURL_CA_BUNDLE_AUTODETECT)
-    # first try autodetecting a CA bundle, then a CA path
-
-    if(CURL_CA_BUNDLE_AUTODETECT)
-        set(SEARCH_CA_BUNDLE_PATHS
-            /etc/ssl/certs/ca-certificates.crt
-            /etc/pki/tls/certs/ca-bundle.crt
-            /usr/share/ssl/certs/ca-bundle.crt
-            /usr/local/share/certs/ca-root-nss.crt
-            /etc/ssl/cert.pem)
-
-        foreach(SEARCH_CA_BUNDLE_PATH ${SEARCH_CA_BUNDLE_PATHS})
-            if(EXISTS "${SEARCH_CA_BUNDLE_PATH}")
-                message(STATUS "Found CA bundle: ${SEARCH_CA_BUNDLE_PATH}")
-                set(CURL_CA_BUNDLE "${SEARCH_CA_BUNDLE_PATH}")
-                set(CURL_CA_BUNDLE_SET TRUE CACHE BOOL "Path to the CA bundle has been set")
-                break()
-            endif()
-        endforeach()
-    endif()
+  # first try autodetecting a CA bundle, then a CA path
+
+  if(CURL_CA_BUNDLE_AUTODETECT)
+    set(SEARCH_CA_BUNDLE_PATHS
+        /etc/ssl/certs/ca-certificates.crt
+        /etc/pki/tls/certs/ca-bundle.crt
+        /usr/share/ssl/certs/ca-bundle.crt
+        /usr/local/share/certs/ca-root-nss.crt
+        /etc/ssl/cert.pem)
+
+    foreach(SEARCH_CA_BUNDLE_PATH ${SEARCH_CA_BUNDLE_PATHS})
+      if(EXISTS "${SEARCH_CA_BUNDLE_PATH}")
+        message(STATUS "Found CA bundle: ${SEARCH_CA_BUNDLE_PATH}")
+        set(CURL_CA_BUNDLE "${SEARCH_CA_BUNDLE_PATH}")
+        set(CURL_CA_BUNDLE_SET TRUE CACHE BOOL "Path to the CA bundle has been set")
+        break()
+      endif()
+    endforeach()
+  endif()
 
 
-    if(CURL_CA_PATH_AUTODETECT AND (NOT CURL_CA_PATH_SET))
-        if(EXISTS "/etc/ssl/certs")
-            set(CURL_CA_PATH "/etc/ssl/certs")
-            set(CURL_CA_PATH_SET TRUE CACHE BOOL "Path to the CA bundle has been set")
-        endif()
+  if(CURL_CA_PATH_AUTODETECT AND (NOT CURL_CA_PATH_SET))
+    if(EXISTS "/etc/ssl/certs")
+      set(CURL_CA_PATH "/etc/ssl/certs")
+      set(CURL_CA_PATH_SET TRUE CACHE BOOL "Path to the CA bundle has been set")
     endif()
     endif()
+  endif()
 endif()
 endif()
 
 
 if(CURL_CA_PATH_SET AND NOT USE_OPENSSL AND NOT USE_MBEDTLS)
 if(CURL_CA_PATH_SET AND NOT USE_OPENSSL AND NOT USE_MBEDTLS)
-    message(FATAL_ERROR
-            "CA path only supported by OpenSSL, GnuTLS or mbed TLS. "
-            "Set CURL_CA_PATH=none or enable one of those TLS backends.")
+  message(FATAL_ERROR
+          "CA path only supported by OpenSSL, GnuTLS or mbed TLS. "
+          "Set CURL_CA_PATH=none or enable one of those TLS backends.")
 endif()
 endif()
 
 
-
 # Check for header files
 # Check for header files
 if(NOT UNIX)
 if(NOT UNIX)
   check_include_file_concat("windows.h"      HAVE_WINDOWS_H)
   check_include_file_concat("windows.h"      HAVE_WINDOWS_H)
@@ -707,7 +704,7 @@ if(NOT UNIX)
   if(NOT CURL_WINDOWS_SSPI AND USE_OPENSSL)
   if(NOT CURL_WINDOWS_SSPI AND USE_OPENSSL)
     set(CURL_LIBS ${CURL_LIBS} "crypt32")
     set(CURL_LIBS ${CURL_LIBS} "crypt32")
   endif()
   endif()
-endif(NOT UNIX)
+endif()
 
 
 check_include_file_concat("stdio.h"          HAVE_STDIO_H)
 check_include_file_concat("stdio.h"          HAVE_STDIO_H)
 check_include_file_concat("inttypes.h"       HAVE_INTTYPES_H)
 check_include_file_concat("inttypes.h"       HAVE_INTTYPES_H)
@@ -790,17 +787,17 @@ check_type_size("time_t"  SIZEOF_TIME_T)
 if(NOT HAVE_SIZEOF_SSIZE_T)
 if(NOT HAVE_SIZEOF_SSIZE_T)
   if(SIZEOF_LONG EQUAL SIZEOF_SIZE_T)
   if(SIZEOF_LONG EQUAL SIZEOF_SIZE_T)
     set(ssize_t long)
     set(ssize_t long)
-  endif(SIZEOF_LONG EQUAL SIZEOF_SIZE_T)
+  endif()
   if(NOT ssize_t AND SIZEOF___INT64 EQUAL SIZEOF_SIZE_T)
   if(NOT ssize_t AND SIZEOF___INT64 EQUAL SIZEOF_SIZE_T)
     set(ssize_t __int64)
     set(ssize_t __int64)
-  endif(NOT ssize_t AND SIZEOF___INT64 EQUAL SIZEOF_SIZE_T)
-endif(NOT HAVE_SIZEOF_SSIZE_T)
+  endif()
+endif()
 # off_t is sized later, after the HAVE_FILE_OFFSET_BITS test
 # off_t is sized later, after the HAVE_FILE_OFFSET_BITS test
 
 
 if(HAVE_SIZEOF_LONG_LONG)
 if(HAVE_SIZEOF_LONG_LONG)
   set(HAVE_LONGLONG 1)
   set(HAVE_LONGLONG 1)
   set(HAVE_LL 1)
   set(HAVE_LL 1)
-endif(HAVE_SIZEOF_LONG_LONG)
+endif()
 
 
 find_file(RANDOM_FILE urandom /dev)
 find_file(RANDOM_FILE urandom /dev)
 mark_as_advanced(RANDOM_FILE)
 mark_as_advanced(RANDOM_FILE)
@@ -832,7 +829,7 @@ check_symbol_exists(strncmpi      "${CURL_INCLUDES}" HAVE_STRNCMPI)
 check_symbol_exists(alarm         "${CURL_INCLUDES}" HAVE_ALARM)
 check_symbol_exists(alarm         "${CURL_INCLUDES}" HAVE_ALARM)
 if(NOT HAVE_STRNCMPI)
 if(NOT HAVE_STRNCMPI)
   set(HAVE_STRCMPI)
   set(HAVE_STRCMPI)
-endif(NOT HAVE_STRNCMPI)
+endif()
 check_symbol_exists(gethostbyaddr "${CURL_INCLUDES}" HAVE_GETHOSTBYADDR)
 check_symbol_exists(gethostbyaddr "${CURL_INCLUDES}" HAVE_GETHOSTBYADDR)
 check_symbol_exists(gethostbyaddr_r "${CURL_INCLUDES}" HAVE_GETHOSTBYADDR_R)
 check_symbol_exists(gethostbyaddr_r "${CURL_INCLUDES}" HAVE_GETHOSTBYADDR_R)
 check_symbol_exists(gettimeofday  "${CURL_INCLUDES}" HAVE_GETTIMEOFDAY)
 check_symbol_exists(gettimeofday  "${CURL_INCLUDES}" HAVE_GETTIMEOFDAY)
@@ -848,6 +845,7 @@ check_symbol_exists(sigsetjmp     "${CURL_INCLUDES}" HAVE_SIGSETJMP)
 check_symbol_exists(getpass_r     "${CURL_INCLUDES}" HAVE_GETPASS_R)
 check_symbol_exists(getpass_r     "${CURL_INCLUDES}" HAVE_GETPASS_R)
 check_symbol_exists(strlcat       "${CURL_INCLUDES}" HAVE_STRLCAT)
 check_symbol_exists(strlcat       "${CURL_INCLUDES}" HAVE_STRLCAT)
 check_symbol_exists(getpwuid      "${CURL_INCLUDES}" HAVE_GETPWUID)
 check_symbol_exists(getpwuid      "${CURL_INCLUDES}" HAVE_GETPWUID)
+check_symbol_exists(getpwuid_r    "${CURL_INCLUDES}" HAVE_GETPWUID_R)
 check_symbol_exists(geteuid       "${CURL_INCLUDES}" HAVE_GETEUID)
 check_symbol_exists(geteuid       "${CURL_INCLUDES}" HAVE_GETEUID)
 check_symbol_exists(utime         "${CURL_INCLUDES}" HAVE_UTIME)
 check_symbol_exists(utime         "${CURL_INCLUDES}" HAVE_UTIME)
 check_symbol_exists(gmtime_r      "${CURL_INCLUDES}" HAVE_GMTIME_R)
 check_symbol_exists(gmtime_r      "${CURL_INCLUDES}" HAVE_GMTIME_R)
@@ -860,7 +858,7 @@ check_symbol_exists(signal        "${CURL_INCLUDES}" HAVE_SIGNAL_FUNC)
 check_symbol_exists(SIGALRM       "${CURL_INCLUDES}" HAVE_SIGNAL_MACRO)
 check_symbol_exists(SIGALRM       "${CURL_INCLUDES}" HAVE_SIGNAL_MACRO)
 if(HAVE_SIGNAL_FUNC AND HAVE_SIGNAL_MACRO)
 if(HAVE_SIGNAL_FUNC AND HAVE_SIGNAL_MACRO)
   set(HAVE_SIGNAL 1)
   set(HAVE_SIGNAL 1)
-endif(HAVE_SIGNAL_FUNC AND HAVE_SIGNAL_MACRO)
+endif()
 check_symbol_exists(uname          "${CURL_INCLUDES}" HAVE_UNAME)
 check_symbol_exists(uname          "${CURL_INCLUDES}" HAVE_UNAME)
 check_symbol_exists(strtoll        "${CURL_INCLUDES}" HAVE_STRTOLL)
 check_symbol_exists(strtoll        "${CURL_INCLUDES}" HAVE_STRTOLL)
 check_symbol_exists(_strtoi64      "${CURL_INCLUDES}" HAVE__STRTOI64)
 check_symbol_exists(_strtoi64      "${CURL_INCLUDES}" HAVE__STRTOI64)
@@ -894,35 +892,35 @@ if(WIN32)
     add_definitions(-D_WIN32_WINNT=0x0501)
     add_definitions(-D_WIN32_WINNT=0x0501)
   endif()
   endif()
 else()
 else()
-    check_function_exists(inet_pton HAVE_INET_PTON)
+  check_function_exists(inet_pton HAVE_INET_PTON)
 endif()
 endif()
 
 
 check_symbol_exists(fsetxattr "${CURL_INCLUDES}" HAVE_FSETXATTR)
 check_symbol_exists(fsetxattr "${CURL_INCLUDES}" HAVE_FSETXATTR)
 if(HAVE_FSETXATTR)
 if(HAVE_FSETXATTR)
   foreach(CURL_TEST HAVE_FSETXATTR_5 HAVE_FSETXATTR_6)
   foreach(CURL_TEST HAVE_FSETXATTR_5 HAVE_FSETXATTR_6)
-    curl_internal_test_run(${CURL_TEST})
-  endforeach(CURL_TEST)
-endif(HAVE_FSETXATTR)
+    curl_internal_test(${CURL_TEST})
+  endforeach()
+endif()
 
 
 # sigaction and sigsetjmp are special. Use special mechanism for
 # sigaction and sigsetjmp are special. Use special mechanism for
 # detecting those, but only if previous attempt failed.
 # detecting those, but only if previous attempt failed.
 if(HAVE_SIGNAL_H)
 if(HAVE_SIGNAL_H)
   check_symbol_exists(sigaction "signal.h" HAVE_SIGACTION)
   check_symbol_exists(sigaction "signal.h" HAVE_SIGACTION)
-endif(HAVE_SIGNAL_H)
+endif()
 
 
 if(NOT HAVE_SIGSETJMP)
 if(NOT HAVE_SIGSETJMP)
   if(HAVE_SETJMP_H)
   if(HAVE_SETJMP_H)
     check_symbol_exists(sigsetjmp "setjmp.h" HAVE_MACRO_SIGSETJMP)
     check_symbol_exists(sigsetjmp "setjmp.h" HAVE_MACRO_SIGSETJMP)
     if(HAVE_MACRO_SIGSETJMP)
     if(HAVE_MACRO_SIGSETJMP)
       set(HAVE_SIGSETJMP 1)
       set(HAVE_SIGSETJMP 1)
-    endif(HAVE_MACRO_SIGSETJMP)
-  endif(HAVE_SETJMP_H)
-endif(NOT HAVE_SIGSETJMP)
+    endif()
+  endif()
+endif()
 
 
 # If there is no stricmp(), do not allow LDAP to parse URLs
 # If there is no stricmp(), do not allow LDAP to parse URLs
 if(NOT HAVE_STRICMP)
 if(NOT HAVE_STRICMP)
   set(HAVE_LDAP_URL_PARSE 1)
   set(HAVE_LDAP_URL_PARSE 1)
-endif(NOT HAVE_STRICMP)
+endif()
 
 
 # Do curl specific tests
 # Do curl specific tests
 foreach(CURL_TEST
 foreach(CURL_TEST
@@ -960,12 +958,12 @@ foreach(CURL_TEST
     HAVE_FILE_OFFSET_BITS
     HAVE_FILE_OFFSET_BITS
     )
     )
   curl_internal_test(${CURL_TEST})
   curl_internal_test(${CURL_TEST})
-endforeach(CURL_TEST)
+endforeach()
 
 
 if(HAVE_FILE_OFFSET_BITS)
 if(HAVE_FILE_OFFSET_BITS)
   set(_FILE_OFFSET_BITS 64)
   set(_FILE_OFFSET_BITS 64)
   set(CMAKE_REQUIRED_FLAGS "-D_FILE_OFFSET_BITS=64")
   set(CMAKE_REQUIRED_FLAGS "-D_FILE_OFFSET_BITS=64")
-endif(HAVE_FILE_OFFSET_BITS)
+endif()
 check_type_size("off_t"  SIZEOF_OFF_T)
 check_type_size("off_t"  SIZEOF_OFF_T)
 
 
 # include this header to get the type
 # include this header to get the type
@@ -980,8 +978,8 @@ foreach(CURL_TEST
     HAVE_GLIBC_STRERROR_R
     HAVE_GLIBC_STRERROR_R
     HAVE_POSIX_STRERROR_R
     HAVE_POSIX_STRERROR_R
     )
     )
-  curl_internal_test_run(${CURL_TEST})
-endforeach(CURL_TEST)
+  curl_internal_test(${CURL_TEST})
+endforeach()
 
 
 # Check for reentrant
 # Check for reentrant
 foreach(CURL_TEST
 foreach(CURL_TEST
@@ -995,9 +993,9 @@ foreach(CURL_TEST
   if(NOT ${CURL_TEST})
   if(NOT ${CURL_TEST})
     if(${CURL_TEST}_REENTRANT)
     if(${CURL_TEST}_REENTRANT)
       set(NEED_REENTRANT 1)
       set(NEED_REENTRANT 1)
-    endif(${CURL_TEST}_REENTRANT)
-  endif(NOT ${CURL_TEST})
-endforeach(CURL_TEST)
+    endif()
+  endif()
+endforeach()
 
 
 if(NEED_REENTRANT)
 if(NEED_REENTRANT)
   foreach(CURL_TEST
   foreach(CURL_TEST
@@ -1010,32 +1008,32 @@ if(NEED_REENTRANT)
     set(${CURL_TEST} 0)
     set(${CURL_TEST} 0)
     if(${CURL_TEST}_REENTRANT)
     if(${CURL_TEST}_REENTRANT)
       set(${CURL_TEST} 1)
       set(${CURL_TEST} 1)
-    endif(${CURL_TEST}_REENTRANT)
-  endforeach(CURL_TEST)
-endif(NEED_REENTRANT)
+    endif()
+  endforeach()
+endif()
 
 
 if(HAVE_INET_NTOA_R_DECL_REENTRANT)
 if(HAVE_INET_NTOA_R_DECL_REENTRANT)
   set(HAVE_INET_NTOA_R_DECL 1)
   set(HAVE_INET_NTOA_R_DECL 1)
   set(NEED_REENTRANT 1)
   set(NEED_REENTRANT 1)
-endif(HAVE_INET_NTOA_R_DECL_REENTRANT)
+endif()
 
 
 # Some other minor tests
 # Some other minor tests
 
 
 if(NOT HAVE_IN_ADDR_T)
 if(NOT HAVE_IN_ADDR_T)
   set(in_addr_t "unsigned long")
   set(in_addr_t "unsigned long")
-endif(NOT HAVE_IN_ADDR_T)
+endif()
 
 
 # Fix libz / zlib.h
 # Fix libz / zlib.h
 
 
 if(NOT CURL_SPECIAL_LIBZ)
 if(NOT CURL_SPECIAL_LIBZ)
   if(NOT HAVE_LIBZ)
   if(NOT HAVE_LIBZ)
     set(HAVE_ZLIB_H 0)
     set(HAVE_ZLIB_H 0)
-  endif(NOT HAVE_LIBZ)
+  endif()
 
 
   if(NOT HAVE_ZLIB_H)
   if(NOT HAVE_ZLIB_H)
     set(HAVE_LIBZ 0)
     set(HAVE_LIBZ 0)
-  endif(NOT HAVE_ZLIB_H)
-endif(NOT CURL_SPECIAL_LIBZ)
+  endif()
+endif()
 
 
 # Check for nonblocking
 # Check for nonblocking
 set(HAVE_DISABLED_NONBLOCKING 1)
 set(HAVE_DISABLED_NONBLOCKING 1)
@@ -1044,16 +1042,13 @@ if(HAVE_FIONBIO OR
     HAVE_IOCTLSOCKET_CASE OR
     HAVE_IOCTLSOCKET_CASE OR
     HAVE_O_NONBLOCK)
     HAVE_O_NONBLOCK)
   set(HAVE_DISABLED_NONBLOCKING)
   set(HAVE_DISABLED_NONBLOCKING)
-endif(HAVE_FIONBIO OR
-  HAVE_IOCTLSOCKET OR
-  HAVE_IOCTLSOCKET_CASE OR
-  HAVE_O_NONBLOCK)
+endif()
 
 
 if(RETSIGTYPE_TEST)
 if(RETSIGTYPE_TEST)
   set(RETSIGTYPE void)
   set(RETSIGTYPE void)
-else(RETSIGTYPE_TEST)
+else()
   set(RETSIGTYPE int)
   set(RETSIGTYPE int)
-endif(RETSIGTYPE_TEST)
+endif()
 
 
 if(CMAKE_COMPILER_IS_GNUCC AND APPLE)
 if(CMAKE_COMPILER_IS_GNUCC AND APPLE)
   include(CheckCCompilerFlag)
   include(CheckCCompilerFlag)
@@ -1063,13 +1058,13 @@ if(CMAKE_COMPILER_IS_GNUCC AND APPLE)
     get_source_file_property(MPRINTF_COMPILE_FLAGS mprintf.c COMPILE_FLAGS)
     get_source_file_property(MPRINTF_COMPILE_FLAGS mprintf.c COMPILE_FLAGS)
     if(MPRINTF_COMPILE_FLAGS)
     if(MPRINTF_COMPILE_FLAGS)
       set(MPRINTF_COMPILE_FLAGS "${MPRINTF_COMPILE_FLAGS} -Wno-long-double")
       set(MPRINTF_COMPILE_FLAGS "${MPRINTF_COMPILE_FLAGS} -Wno-long-double")
-    else(MPRINTF_COMPILE_FLAGS)
+    else()
       set(MPRINTF_COMPILE_FLAGS "-Wno-long-double")
       set(MPRINTF_COMPILE_FLAGS "-Wno-long-double")
-    endif(MPRINTF_COMPILE_FLAGS)
+    endif()
     set_source_files_properties(mprintf.c PROPERTIES
     set_source_files_properties(mprintf.c PROPERTIES
       COMPILE_FLAGS ${MPRINTF_COMPILE_FLAGS})
       COMPILE_FLAGS ${MPRINTF_COMPILE_FLAGS})
-  endif(HAVE_C_FLAG_Wno_long_double)
-endif(CMAKE_COMPILER_IS_GNUCC AND APPLE)
+  endif()
+endif()
 
 
 if(HAVE_SOCKLEN_T)
 if(HAVE_SOCKLEN_T)
   set(CURL_TYPEOF_CURL_SOCKLEN_T "socklen_t")
   set(CURL_TYPEOF_CURL_SOCKLEN_T "socklen_t")
@@ -1104,19 +1099,25 @@ include(CMake/OtherTests.cmake)
 
 
 add_definitions(-DHAVE_CONFIG_H)
 add_definitions(-DHAVE_CONFIG_H)
 
 
-# For windows, all compilers used by cmake should support large files
+# For Windows, all compilers used by CMake should support large files
 if(WIN32)
 if(WIN32)
   set(USE_WIN32_LARGE_FILES ON)
   set(USE_WIN32_LARGE_FILES ON)
-endif(WIN32)
+
+  # Use the manifest embedded in the Windows Resource
+  set(CMAKE_RC_FLAGS "${CMAKE_RC_FLAGS} -DCURL_EMBED_MANIFEST")
+endif()
 
 
 if(MSVC)
 if(MSVC)
+  # Disable default manifest added by CMake
+  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /MANIFEST:NO")
+
   add_definitions(-D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE)
   add_definitions(-D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE)
   if(CMAKE_C_FLAGS MATCHES "/W[0-4]")
   if(CMAKE_C_FLAGS MATCHES "/W[0-4]")
     string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
     string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
-  else(CMAKE_C_FLAGS MATCHES "/W[0-4]")
+  else()
     set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W4")
     set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W4")
-  endif(CMAKE_C_FLAGS MATCHES "/W[0-4]")
-endif(MSVC)
+  endif()
+endif()
 
 
 if(CURL_WERROR)
 if(CURL_WERROR)
   if(MSVC_VERSION)
   if(MSVC_VERSION)
@@ -1125,7 +1126,7 @@ if(CURL_WERROR)
     # this assumes clang or gcc style options
     # this assumes clang or gcc style options
     set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
     set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
   endif()
   endif()
-endif(CURL_WERROR)
+endif()
 
 
 # Ugly (but functional) way to include "Makefile.inc" by transforming it (= regenerate it).
 # Ugly (but functional) way to include "Makefile.inc" by transforming it (= regenerate it).
 function(TRANSFORM_MAKEFILE_INC INPUT_FILE OUTPUT_FILE)
 function(TRANSFORM_MAKEFILE_INC INPUT_FILE OUTPUT_FILE)
@@ -1144,9 +1145,9 @@ function(TRANSFORM_MAKEFILE_INC INPUT_FILE OUTPUT_FILE)
 endfunction()
 endfunction()
 
 
 if(WIN32 AND NOT CYGWIN)
 if(WIN32 AND NOT CYGWIN)
-    set(CURL_INSTALL_CMAKE_DIR CMake)
+  set(CURL_INSTALL_CMAKE_DIR CMake)
 else()
 else()
-    set(CURL_INSTALL_CMAKE_DIR lib/cmake/curl)
+  set(CURL_INSTALL_CMAKE_DIR lib/cmake/curl)
 endif()
 endif()
 
 
 if(USE_MANUAL)
 if(USE_MANUAL)
@@ -1246,11 +1247,12 @@ set(CONFIGURE_OPTIONS       "")
 # TODO when to set "-DCURL_STATICLIB" for CPPFLAG_CURL_STATICLIB?
 # TODO when to set "-DCURL_STATICLIB" for CPPFLAG_CURL_STATICLIB?
 set(CPPFLAG_CURL_STATICLIB  "")
 set(CPPFLAG_CURL_STATICLIB  "")
 set(CURLVERSION             "${CURL_VERSION}")
 set(CURLVERSION             "${CURL_VERSION}")
-set(ENABLE_SHARED           "yes")
-if(CURL_STATICLIB)
-  set(ENABLE_STATIC         "yes")
-else()
+if(BUILD_SHARED_LIBS)
+  set(ENABLE_SHARED         "yes")
   set(ENABLE_STATIC         "no")
   set(ENABLE_STATIC         "no")
+else()
+  set(ENABLE_SHARED         "no")
+  set(ENABLE_STATIC         "yes")
 endif()
 endif()
 set(exec_prefix             "\${prefix}")
 set(exec_prefix             "\${prefix}")
 set(includedir              "\${prefix}/include")
 set(includedir              "\${prefix}/include")
@@ -1274,6 +1276,9 @@ set(REQUIRE_LIB_DEPS        "no")
 set(VERSIONNUM              "${CURL_VERSION_NUM}")
 set(VERSIONNUM              "${CURL_VERSION_NUM}")
 
 
 # Finally generate a "curl-config" matching this config
 # Finally generate a "curl-config" matching this config
+# Use:
+# * ENABLE_SHARED
+# * ENABLE_STATIC
 configure_file("${CURL_SOURCE_DIR}/curl-config.in"
 configure_file("${CURL_SOURCE_DIR}/curl-config.in"
                "${CURL_BINARY_DIR}/curl-config" @ONLY)
                "${CURL_BINARY_DIR}/curl-config" @ONLY)
 install(FILES "${CURL_BINARY_DIR}/curl-config"
 install(FILES "${CURL_BINARY_DIR}/curl-config"
@@ -1307,9 +1312,9 @@ write_basic_package_version_file(
     COMPATIBILITY SameMajorVersion
     COMPATIBILITY SameMajorVersion
 )
 )
 
 
-configure_file(CMake/curl-config.cmake
+configure_file(CMake/curl-config.cmake.in
         "${PROJECT_BINARY_DIR}/curl-config.cmake"
         "${PROJECT_BINARY_DIR}/curl-config.cmake"
-        COPYONLY
+        @ONLY
 )
 )
 
 
 install(
 install(

+ 21 - 1
include/curl/curl.h

@@ -691,6 +691,7 @@ typedef enum {
  * CURLAUTH_NTLM         - HTTP NTLM authentication
  * CURLAUTH_NTLM         - HTTP NTLM authentication
  * CURLAUTH_DIGEST_IE    - HTTP Digest authentication with IE flavour
  * CURLAUTH_DIGEST_IE    - HTTP Digest authentication with IE flavour
  * CURLAUTH_NTLM_WB      - HTTP NTLM authentication delegated to winbind helper
  * CURLAUTH_NTLM_WB      - HTTP NTLM authentication delegated to winbind helper
+ * CURLAUTH_BEARER       - HTTP Bearer token authentication
  * CURLAUTH_ONLY         - Use together with a single other type to force no
  * CURLAUTH_ONLY         - Use together with a single other type to force no
  *                         authentication or just that single type
  *                         authentication or just that single type
  * CURLAUTH_ANY          - All fine types set
  * CURLAUTH_ANY          - All fine types set
@@ -708,6 +709,7 @@ typedef enum {
 #define CURLAUTH_NTLM         (((unsigned long)1)<<3)
 #define CURLAUTH_NTLM         (((unsigned long)1)<<3)
 #define CURLAUTH_DIGEST_IE    (((unsigned long)1)<<4)
 #define CURLAUTH_DIGEST_IE    (((unsigned long)1)<<4)
 #define CURLAUTH_NTLM_WB      (((unsigned long)1)<<5)
 #define CURLAUTH_NTLM_WB      (((unsigned long)1)<<5)
+#define CURLAUTH_BEARER       (((unsigned long)1)<<6)
 #define CURLAUTH_ONLY         (((unsigned long)1)<<31)
 #define CURLAUTH_ONLY         (((unsigned long)1)<<31)
 #define CURLAUTH_ANY          (~CURLAUTH_DIGEST_IE)
 #define CURLAUTH_ANY          (~CURLAUTH_DIGEST_IE)
 #define CURLAUTH_ANYSAFE      (~(CURLAUTH_BASIC|CURLAUTH_DIGEST_IE))
 #define CURLAUTH_ANYSAFE      (~(CURLAUTH_BASIC|CURLAUTH_DIGEST_IE))
@@ -1847,6 +1849,13 @@ typedef enum {
   /* shuffle addresses before use when DNS returns multiple */
   /* shuffle addresses before use when DNS returns multiple */
   CINIT(DNS_SHUFFLE_ADDRESSES, LONG, 275),
   CINIT(DNS_SHUFFLE_ADDRESSES, LONG, 275),
 
 
+  /* Specify which TLS 1.3 ciphers suites to use */
+  CINIT(TLS13_CIPHERS, STRINGPOINT, 276),
+  CINIT(PROXY_TLS13_CIPHERS, STRINGPOINT, 277),
+
+  /* Disallow specifying username/login in URL. */
+  CINIT(DISALLOW_USERNAME_IN_URL, LONG, 278),
+
   CURLOPT_LASTENTRY /* the last unused */
   CURLOPT_LASTENTRY /* the last unused */
 } CURLoption;
 } CURLoption;
 
 
@@ -2527,7 +2536,17 @@ typedef enum {
   CURLINFO_SCHEME           = CURLINFO_STRING + 49,
   CURLINFO_SCHEME           = CURLINFO_STRING + 49,
   /* Fill in new entries below here! */
   /* Fill in new entries below here! */
 
 
-  CURLINFO_LASTONE          = 49
+  /* Preferably these would be defined conditionally based on the
+     sizeof curl_off_t being 64-bits */
+  CURLINFO_TOTAL_TIME_T     = CURLINFO_OFF_T + 50,
+  CURLINFO_NAMELOOKUP_TIME_T = CURLINFO_OFF_T + 51,
+  CURLINFO_CONNECT_TIME_T   = CURLINFO_OFF_T + 52,
+  CURLINFO_PRETRANSFER_TIME_T = CURLINFO_OFF_T + 53,
+  CURLINFO_STARTTRANSFER_TIME_T = CURLINFO_OFF_T + 54,
+  CURLINFO_REDIRECT_TIME_T  = CURLINFO_OFF_T + 55,
+  CURLINFO_APPCONNECT_TIME_T = CURLINFO_OFF_T + 56,
+
+  CURLINFO_LASTONE          = 56
 } CURLINFO;
 } CURLINFO;
 
 
 /* CURLINFO_RESPONSE_CODE is the new name for the option previously known as
 /* CURLINFO_RESPONSE_CODE is the new name for the option previously known as
@@ -2570,6 +2589,7 @@ typedef enum {
   CURL_LOCK_DATA_DNS,
   CURL_LOCK_DATA_DNS,
   CURL_LOCK_DATA_SSL_SESSION,
   CURL_LOCK_DATA_SSL_SESSION,
   CURL_LOCK_DATA_CONNECT,
   CURL_LOCK_DATA_CONNECT,
+  CURL_LOCK_DATA_PSL,
   CURL_LOCK_DATA_LAST
   CURL_LOCK_DATA_LAST
 } curl_lock_data;
 } curl_lock_data;
 
 

+ 4 - 4
include/curl/curlver.h

@@ -30,13 +30,13 @@
 
 
 /* This is the version number of the libcurl package from which this header
 /* This is the version number of the libcurl package from which this header
    file origins: */
    file origins: */
-#define LIBCURL_VERSION "7.60.0-DEV"
+#define LIBCURL_VERSION "7.61.1-DEV"
 
 
 /* The numeric version number is also available "in parts" by using these
 /* The numeric version number is also available "in parts" by using these
    defines: */
    defines: */
 #define LIBCURL_VERSION_MAJOR 7
 #define LIBCURL_VERSION_MAJOR 7
-#define LIBCURL_VERSION_MINOR 60
-#define LIBCURL_VERSION_PATCH 0
+#define LIBCURL_VERSION_MINOR 61
+#define LIBCURL_VERSION_PATCH 1
 
 
 /* This is the numeric version of the libcurl version number, meant for easier
 /* This is the numeric version of the libcurl version number, meant for easier
    parsing and comparions by programs. The LIBCURL_VERSION_NUM define will
    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
    CURL_VERSION_BITS() macro since curl's own configure script greps for it
    and needs it to contain the full number.
    and needs it to contain the full number.
 */
 */
-#define LIBCURL_VERSION_NUM 0x073C00
+#define LIBCURL_VERSION_NUM 0x073D01
 
 
 /*
 /*
  * This is the date and time when the full source package was created. The
  * This is the date and time when the full source package was created. The

+ 19 - 1
include/curl/system.h

@@ -320,6 +320,24 @@
 #  define CURL_PULL_SYS_TYPES_H      1
 #  define CURL_PULL_SYS_TYPES_H      1
 #  define CURL_PULL_SYS_SOCKET_H     1
 #  define CURL_PULL_SYS_SOCKET_H     1
 
 
+#elif defined(__xlc__) /* IBM xlc compiler */
+#  if !defined(_LP64)
+#    define CURL_TYPEOF_CURL_OFF_T     long long
+#    define CURL_FORMAT_CURL_OFF_T     "lld"
+#    define CURL_FORMAT_CURL_OFF_TU    "llu"
+#    define CURL_SUFFIX_CURL_OFF_T     LL
+#    define CURL_SUFFIX_CURL_OFF_TU    ULL
+#  else
+#    define CURL_TYPEOF_CURL_OFF_T     long
+#    define CURL_FORMAT_CURL_OFF_T     "ld"
+#    define CURL_FORMAT_CURL_OFF_TU    "lu"
+#    define CURL_SUFFIX_CURL_OFF_T     L
+#    define CURL_SUFFIX_CURL_OFF_TU    UL
+#  endif
+#  define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
+#  define CURL_PULL_SYS_TYPES_H      1
+#  define CURL_PULL_SYS_SOCKET_H     1
+
 /* ===================================== */
 /* ===================================== */
 /*    KEEP MSVC THE PENULTIMATE ENTRY    */
 /*    KEEP MSVC THE PENULTIMATE ENTRY    */
 /* ===================================== */
 /* ===================================== */
@@ -344,7 +362,7 @@
 /*    KEEP GENERIC GCC THE LAST ENTRY    */
 /*    KEEP GENERIC GCC THE LAST ENTRY    */
 /* ===================================== */
 /* ===================================== */
 
 
-#elif defined(__GNUC__)
+#elif defined(__GNUC__) && !defined(_SCO_DS)
 #  if !defined(__LP64__) &&                                             \
 #  if !defined(__LP64__) &&                                             \
   (defined(__ILP32__) || defined(__i386__) || defined(__hppa__) ||      \
   (defined(__ILP32__) || defined(__i386__) || defined(__hppa__) ||      \
    defined(__ppc__) || defined(__powerpc__) || defined(__arm__) ||      \
    defined(__ppc__) || defined(__powerpc__) || defined(__arm__) ||      \

+ 1 - 1
include/curl/typecheck-gcc.h

@@ -428,7 +428,7 @@ _CURL_WARNING(_curl_easy_getinfo_err_curl_off_t,
  * == or whatsoever.
  * == or whatsoever.
  */
  */
 
 
-/* XXX: should evaluate to true iff expr is a pointer */
+/* XXX: should evaluate to true if expr is a pointer */
 #define _curl_is_any_ptr(expr)                                                \
 #define _curl_is_any_ptr(expr)                                                \
   (sizeof(expr) == sizeof(void *))
   (sizeof(expr) == sizeof(void *))
 
 

+ 16 - 20
lib/CMakeLists.txt

@@ -1,5 +1,13 @@
 set(LIB_NAME libcurl)
 set(LIB_NAME libcurl)
 
 
+if(BUILD_SHARED_LIBS)
+  set(CURL_STATICLIB NO)
+else()
+  set(CURL_STATICLIB YES)
+endif()
+
+# Use:
+# * CURL_STATICLIB
 configure_file(curl_config.h.cmake
 configure_file(curl_config.h.cmake
   ${CMAKE_CURRENT_BINARY_DIR}/curl_config.h)
   ${CMAKE_CURRENT_BINARY_DIR}/curl_config.h)
 
 
@@ -59,28 +67,23 @@ if(USE_ARES)
   include_directories(${CARES_INCLUDE_DIR})
   include_directories(${CARES_INCLUDE_DIR})
 endif()
 endif()
 
 
-if(CURL_STATICLIB)
-  # Static lib
-  set(CURL_USER_DEFINED_DYNAMIC_OR_STATIC STATIC)
-else()
-  # DLL / so dynamic lib
-  set(CURL_USER_DEFINED_DYNAMIC_OR_STATIC SHARED)
-endif()
-
 add_library(
 add_library(
   ${LIB_NAME}
   ${LIB_NAME}
-  ${CURL_USER_DEFINED_DYNAMIC_OR_STATIC}
   ${HHEADERS} ${CSOURCES}
   ${HHEADERS} ${CSOURCES}
   )
   )
 
 
-if(MSVC AND CURL_STATICLIB)
+if(MSVC AND NOT BUILD_SHARED_LIBS)
   set_target_properties(${LIB_NAME} PROPERTIES STATIC_LIBRARY_FLAGS ${CMAKE_EXE_LINKER_FLAGS})
   set_target_properties(${LIB_NAME} PROPERTIES STATIC_LIBRARY_FLAGS ${CMAKE_EXE_LINKER_FLAGS})
 endif()
 endif()
 
 
+if(NOT BUILD_SHARED_LIBS)
+    set_target_properties(${LIB_NAME} PROPERTIES INTERFACE_COMPILE_DEFINITIONS CURL_STATICLIB)
+endif()
+
 target_link_libraries(${LIB_NAME} ${CURL_LIBS})
 target_link_libraries(${LIB_NAME} ${CURL_LIBS})
 
 
 if(WIN32)
 if(WIN32)
-  add_definitions( -D_USRDLL )
+  add_definitions(-D_USRDLL)
 endif()
 endif()
 
 
 set_target_properties(${LIB_NAME} PROPERTIES COMPILE_DEFINITIONS BUILDING_LIBCURL)
 set_target_properties(${LIB_NAME} PROPERTIES COMPILE_DEFINITIONS BUILDING_LIBCURL)
@@ -95,21 +98,14 @@ set_target_properties(${LIB_NAME} PROPERTIES PREFIX "")
 set_target_properties(${LIB_NAME} PROPERTIES IMPORT_PREFIX "")
 set_target_properties(${LIB_NAME} PROPERTIES IMPORT_PREFIX "")
 
 
 if(WIN32)
 if(WIN32)
-  if(NOT CURL_STATICLIB)
+  if(BUILD_SHARED_LIBS)
     # Add "_imp" as a suffix before the extension to avoid conflicting with the statically linked "libcurl.lib"
     # Add "_imp" as a suffix before the extension to avoid conflicting with the statically linked "libcurl.lib"
     set_target_properties(${LIB_NAME} PROPERTIES IMPORT_SUFFIX "_imp.lib")
     set_target_properties(${LIB_NAME} PROPERTIES IMPORT_SUFFIX "_imp.lib")
-
-    set_target_properties (${LIB_NAME} PROPERTIES
-       DEBUG_POSTFIX "-d"
-       # Note: no postfix for release variants, let user choose what style of release he wants
-       # MINSIZEREL_POSTFIX "-z"
-       # RELWITHDEBINFO_POSTFIX "-g"
-       )
   endif()
   endif()
 endif()
 endif()
 
 
 target_include_directories(${LIB_NAME} INTERFACE
 target_include_directories(${LIB_NAME} INTERFACE
-	$<INSTALL_INTERFACE:include>)
+  $<INSTALL_INTERFACE:include>)
 
 
 install(TARGETS ${LIB_NAME}
 install(TARGETS ${LIB_NAME}
   EXPORT libcurl-target
   EXPORT libcurl-target

+ 2 - 2
lib/Makefile.inc

@@ -54,7 +54,7 @@ LIB_CFILES = file.c timeval.c base64.c hostip.c progress.c formdata.c   \
   http_ntlm.c curl_ntlm_wb.c curl_ntlm_core.c curl_sasl.c rand.c        \
   http_ntlm.c curl_ntlm_wb.c curl_ntlm_core.c curl_sasl.c rand.c        \
   curl_multibyte.c hostcheck.c conncache.c pipeline.c dotdot.c          \
   curl_multibyte.c hostcheck.c conncache.c pipeline.c dotdot.c          \
   x509asn1.c http2.c smb.c curl_endian.c curl_des.c system_win32.c      \
   x509asn1.c http2.c smb.c curl_endian.c curl_des.c system_win32.c      \
-  mime.c sha256.c setopt.c curl_path.c curl_ctype.c curl_range.c
+  mime.c sha256.c setopt.c curl_path.c curl_ctype.c curl_range.c psl.c
 
 
 LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h \
 LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h \
   formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h if2ip.h         \
   formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h if2ip.h         \
@@ -74,7 +74,7 @@ LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h \
   curl_setup_once.h multihandle.h setup-vms.h pipeline.h dotdot.h       \
   curl_setup_once.h multihandle.h setup-vms.h pipeline.h dotdot.h       \
   x509asn1.h http2.h sigpipe.h smb.h curl_endian.h curl_des.h           \
   x509asn1.h http2.h sigpipe.h smb.h curl_endian.h curl_des.h           \
   curl_printf.h system_win32.h rand.h mime.h curl_sha256.h setopt.h     \
   curl_printf.h system_win32.h rand.h mime.h curl_sha256.h setopt.h     \
-  curl_path.h curl_ctype.h curl_range.h
+  curl_path.h curl_ctype.h curl_range.h psl.h
 
 
 LIB_RCFILES = libcurl.rc
 LIB_RCFILES = libcurl.rc
 
 

+ 21 - 16
lib/asyn-ares.c

@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *                             \___|\___/|_| \_\_____|
  *
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <[email protected]>, et al.
+ * Copyright (C) 1998 - 2018, Daniel Stenberg, <[email protected]>, et al.
  *
  *
  * This software is licensed as described in the file COPYING, which
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * you should have received as part of this distribution. The terms
@@ -312,22 +312,25 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
     conn->async.os_specific;
     conn->async.os_specific;
   CURLcode result = CURLE_OK;
   CURLcode result = CURLE_OK;
 
 
-  *dns = NULL;
+  if(dns)
+    *dns = NULL;
 
 
   waitperform(conn, 0);
   waitperform(conn, 0);
 
 
   if(res && !res->num_pending) {
   if(res && !res->num_pending) {
-    (void)Curl_addrinfo_callback(conn, res->last_status, res->temp_ai);
-    /* temp_ai ownership is moved to the connection, so we need not free-up
-       them */
-    res->temp_ai = NULL;
+    if(dns) {
+      (void)Curl_addrinfo_callback(conn, res->last_status, res->temp_ai);
+      /* temp_ai ownership is moved to the connection, so we need not free-up
+         them */
+      res->temp_ai = NULL;
+    }
     if(!conn->async.dns) {
     if(!conn->async.dns) {
       failf(data, "Could not resolve: %s (%s)",
       failf(data, "Could not resolve: %s (%s)",
             conn->async.hostname, ares_strerror(conn->async.status));
             conn->async.hostname, ares_strerror(conn->async.status));
       result = conn->bits.proxy?CURLE_COULDNT_RESOLVE_PROXY:
       result = conn->bits.proxy?CURLE_COULDNT_RESOLVE_PROXY:
         CURLE_COULDNT_RESOLVE_HOST;
         CURLE_COULDNT_RESOLVE_HOST;
     }
     }
-    else
+    else if(dns)
       *dns = conn->async.dns;
       *dns = conn->async.dns;
 
 
     destroy_async_data(&conn->async);
     destroy_async_data(&conn->async);
@@ -390,7 +393,7 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
       timeout_ms = 1000;
       timeout_ms = 1000;
 
 
     waitperform(conn, timeout_ms);
     waitperform(conn, timeout_ms);
-    result = Curl_resolver_is_resolved(conn, &temp_entry);
+    result = Curl_resolver_is_resolved(conn, entry?&temp_entry:NULL);
 
 
     if(result || conn->async.done)
     if(result || conn->async.done)
       break;
       break;
@@ -472,17 +475,19 @@ static void query_completed_cb(void *arg,  /* (struct connectdata *) */
     return;
     return;
 
 
   res = (struct ResolverResults *)conn->async.os_specific;
   res = (struct ResolverResults *)conn->async.os_specific;
-  res->num_pending--;
+  if(res) {
+    res->num_pending--;
 
 
-  if(CURL_ASYNC_SUCCESS == status) {
-    Curl_addrinfo *ai = Curl_he2ai(hostent, conn->async.port);
-    if(ai) {
-      compound_results(res, ai);
+    if(CURL_ASYNC_SUCCESS == status) {
+      Curl_addrinfo *ai = Curl_he2ai(hostent, conn->async.port);
+      if(ai) {
+        compound_results(res, ai);
+      }
     }
     }
+    /* A successful result overwrites any previous error */
+    if(res->last_status != ARES_SUCCESS)
+      res->last_status = status;
   }
   }
-  /* A successful result overwrites any previous error */
-  if(res->last_status != ARES_SUCCESS)
-    res->last_status = status;
 }
 }
 
 
 /*
 /*

+ 7 - 7
lib/asyn-thread.c

@@ -182,8 +182,6 @@ static struct thread_sync_data *conn_thread_sync_data(struct connectdata *conn)
   return &(((struct thread_data *)conn->async.os_specific)->tsd);
   return &(((struct thread_data *)conn->async.os_specific)->tsd);
 }
 }
 
 
-#define CONN_THREAD_SYNC_DATA(conn) &(((conn)->async.os_specific)->tsd);
-
 /* Destroy resolver thread synchronization data */
 /* Destroy resolver thread synchronization data */
 static
 static
 void destroy_thread_sync_data(struct thread_sync_data * tsd)
 void destroy_thread_sync_data(struct thread_sync_data * tsd)
@@ -481,8 +479,10 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
   DEBUGASSERT(conn && td);
   DEBUGASSERT(conn && td);
 
 
   /* wait for the thread to resolve the name */
   /* wait for the thread to resolve the name */
-  if(Curl_thread_join(&td->thread_hnd))
-    result = getaddrinfo_complete(conn);
+  if(Curl_thread_join(&td->thread_hnd)) {
+    if(entry)
+      result = getaddrinfo_complete(conn);
+  }
   else
   else
     DEBUGASSERT(0);
     DEBUGASSERT(0);
 
 
@@ -572,10 +572,10 @@ int Curl_resolver_getsock(struct connectdata *conn,
   (void)socks;
   (void)socks;
   (void)numsocks;
   (void)numsocks;
   ms = Curl_timediff(Curl_now(), reslv->start);
   ms = Curl_timediff(Curl_now(), reslv->start);
-  if(ms < 10)
-    milli = ms/3;
+  if(ms < 3)
+    milli = 0;
   else if(ms <= 50)
   else if(ms <= 50)
-    milli = 10;
+    milli = ms/3;
   else if(ms <= 250)
   else if(ms <= 250)
     milli = 50;
     milli = 50;
   else
   else

+ 1 - 2
lib/base64.c

@@ -49,13 +49,12 @@ static size_t decodeQuantum(unsigned char *dest, const char *src)
   unsigned long i, x = 0;
   unsigned long i, x = 0;
 
 
   for(i = 0, s = src; i < 4; i++, s++) {
   for(i = 0, s = src; i < 4; i++, s++) {
-    unsigned long v = 0;
-
     if(*s == '=') {
     if(*s == '=') {
       x = (x << 6);
       x = (x << 6);
       padding++;
       padding++;
     }
     }
     else {
     else {
+      unsigned long v = 0;
       p = base64;
       p = base64;
 
 
       while(*p && (*p != *s)) {
       while(*p && (*p != *s)) {

+ 23 - 39
lib/conncache.c

@@ -6,7 +6,7 @@
  *                             \___|\___/|_| \_\_____|
  *                             \___|\___/|_| \_\_____|
  *
  *
  * Copyright (C) 2012 - 2016, Linus Nielsen Feltzing, <[email protected]>
  * Copyright (C) 2012 - 2016, Linus Nielsen Feltzing, <[email protected]>
- * Copyright (C) 2012 - 2017, Daniel Stenberg, <[email protected]>, et al.
+ * Copyright (C) 2012 - 2018, Daniel Stenberg, <[email protected]>, et al.
  *
  *
  * This software is licensed as described in the file COPYING, which
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * you should have received as part of this distribution. The terms
@@ -63,10 +63,9 @@
 
 
 static void conn_llist_dtor(void *user, void *element)
 static void conn_llist_dtor(void *user, void *element)
 {
 {
-  struct connectdata *data = element;
+  struct connectdata *conn = element;
   (void)user;
   (void)user;
-
-  data->bundle = NULL;
+  conn->bundle = NULL;
 }
 }
 
 
 static CURLcode bundle_create(struct Curl_easy *data,
 static CURLcode bundle_create(struct Curl_easy *data,
@@ -96,14 +95,13 @@ static void bundle_destroy(struct connectbundle *cb_ptr)
 }
 }
 
 
 /* Add a connection to a bundle */
 /* Add a connection to a bundle */
-static CURLcode bundle_add_conn(struct connectbundle *cb_ptr,
-                                struct connectdata *conn)
+static void bundle_add_conn(struct connectbundle *cb_ptr,
+                            struct connectdata *conn)
 {
 {
   Curl_llist_insert_next(&cb_ptr->conn_list, cb_ptr->conn_list.tail, conn,
   Curl_llist_insert_next(&cb_ptr->conn_list, cb_ptr->conn_list.tail, conn,
                          &conn->bundle_node);
                          &conn->bundle_node);
   conn->bundle = cb_ptr;
   conn->bundle = cb_ptr;
   cb_ptr->num_connections++;
   cb_ptr->num_connections++;
-  return CURLE_OK;
 }
 }
 
 
 /* Remove a connection from a bundle */
 /* Remove a connection from a bundle */
@@ -263,7 +261,7 @@ static void conncache_remove_bundle(struct conncache *connc,
 CURLcode Curl_conncache_add_conn(struct conncache *connc,
 CURLcode Curl_conncache_add_conn(struct conncache *connc,
                                  struct connectdata *conn)
                                  struct connectdata *conn)
 {
 {
-  CURLcode result;
+  CURLcode result = CURLE_OK;
   struct connectbundle *bundle;
   struct connectbundle *bundle;
   struct connectbundle *new_bundle = NULL;
   struct connectbundle *new_bundle = NULL;
   struct Curl_easy *data = conn->data;
   struct Curl_easy *data = conn->data;
@@ -290,19 +288,13 @@ CURLcode Curl_conncache_add_conn(struct conncache *connc,
     bundle = new_bundle;
     bundle = new_bundle;
   }
   }
 
 
-  result = bundle_add_conn(bundle, conn);
-  if(result) {
-    if(new_bundle)
-      conncache_remove_bundle(data->state.conn_cache, new_bundle);
-    goto unlock;
-  }
-
+  bundle_add_conn(bundle, conn);
   conn->connection_id = connc->next_connection_id++;
   conn->connection_id = connc->next_connection_id++;
   connc->num_conn++;
   connc->num_conn++;
 
 
   DEBUGF(infof(conn->data, "Added connection %ld. "
   DEBUGF(infof(conn->data, "Added connection %ld. "
-               "The cache now contains %" CURL_FORMAT_CURL_OFF_TU " members\n",
-               conn->connection_id, (curl_off_t) connc->num_conn));
+               "The cache now contains %zu members\n",
+               conn->connection_id, connc->num_conn));
 
 
   unlock:
   unlock:
   CONN_UNLOCK(data);
   CONN_UNLOCK(data);
@@ -320,7 +312,7 @@ void Curl_conncache_remove_conn(struct connectdata *conn, bool lock)
      due to a failed connection attempt, before being added to a bundle */
      due to a failed connection attempt, before being added to a bundle */
   if(bundle) {
   if(bundle) {
     if(lock) {
     if(lock) {
-      CONN_LOCK(conn->data);
+      CONN_LOCK(data);
     }
     }
     bundle_remove_conn(bundle, conn);
     bundle_remove_conn(bundle, conn);
     if(bundle->num_connections == 0)
     if(bundle->num_connections == 0)
@@ -328,12 +320,11 @@ void Curl_conncache_remove_conn(struct connectdata *conn, bool lock)
     conn->bundle = NULL; /* removed from it */
     conn->bundle = NULL; /* removed from it */
     if(connc) {
     if(connc) {
       connc->num_conn--;
       connc->num_conn--;
-      DEBUGF(infof(conn->data, "The cache now contains %"
-                   CURL_FORMAT_CURL_OFF_TU " members\n",
-                   (curl_off_t) connc->num_conn));
+      DEBUGF(infof(data, "The cache now contains %zu members\n",
+                   connc->num_conn));
     }
     }
     if(lock) {
     if(lock) {
-      CONN_UNLOCK(conn->data);
+      CONN_UNLOCK(data);
     }
     }
   }
   }
 }
 }
@@ -441,18 +432,11 @@ bool Curl_conncache_return_conn(struct connectdata *conn)
     infof(data, "Connection cache is full, closing the oldest one.\n");
     infof(data, "Connection cache is full, closing the oldest one.\n");
 
 
     conn_candidate = Curl_conncache_extract_oldest(data);
     conn_candidate = Curl_conncache_extract_oldest(data);
-
     if(conn_candidate) {
     if(conn_candidate) {
-      /* Set the connection's owner correctly */
-      conn_candidate->data = data;
-
       /* the winner gets the honour of being disconnected */
       /* the winner gets the honour of being disconnected */
-      (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE);
+      (void)Curl_disconnect(data, conn_candidate, /* dead_connection */ FALSE);
     }
     }
   }
   }
-  CONN_LOCK(data);
-  conn->inuse = FALSE; /* Mark the connection unused */
-  CONN_UNLOCK(data);
 
 
   return (conn_candidate == conn) ? FALSE : TRUE;
   return (conn_candidate == conn) ? FALSE : TRUE;
 
 
@@ -486,7 +470,7 @@ Curl_conncache_extract_bundle(struct Curl_easy *data,
   while(curr) {
   while(curr) {
     conn = curr->ptr;
     conn = curr->ptr;
 
 
-    if(!conn->inuse) {
+    if(!CONN_INUSE(conn)) {
       /* Set higher score for the age passed since the connection was used */
       /* Set higher score for the age passed since the connection was used */
       score = Curl_timediff(now, conn->now);
       score = Curl_timediff(now, conn->now);
 
 
@@ -501,9 +485,9 @@ Curl_conncache_extract_bundle(struct Curl_easy *data,
     /* remove it to prevent another thread from nicking it */
     /* remove it to prevent another thread from nicking it */
     bundle_remove_conn(bundle, conn_candidate);
     bundle_remove_conn(bundle, conn_candidate);
     data->state.conn_cache->num_conn--;
     data->state.conn_cache->num_conn--;
-    DEBUGF(infof(data, "The cache now contains %"
-                 CURL_FORMAT_CURL_OFF_TU " members\n",
-                 (curl_off_t) data->state.conn_cache->num_conn));
+    DEBUGF(infof(data, "The cache now contains %zu members\n",
+                 data->state.conn_cache->num_conn));
+    conn_candidate->data = data; /* associate! */
   }
   }
 
 
   return conn_candidate;
   return conn_candidate;
@@ -544,7 +528,7 @@ Curl_conncache_extract_oldest(struct Curl_easy *data)
     while(curr) {
     while(curr) {
       conn = curr->ptr;
       conn = curr->ptr;
 
 
-      if(!conn->inuse) {
+      if(!CONN_INUSE(conn)) {
         /* Set higher score for the age passed since the connection was used */
         /* Set higher score for the age passed since the connection was used */
         score = Curl_timediff(now, conn->now);
         score = Curl_timediff(now, conn->now);
 
 
@@ -563,9 +547,9 @@ Curl_conncache_extract_oldest(struct Curl_easy *data)
     /* remove it to prevent another thread from nicking it */
     /* remove it to prevent another thread from nicking it */
     bundle_remove_conn(bundle_candidate, conn_candidate);
     bundle_remove_conn(bundle_candidate, conn_candidate);
     connc->num_conn--;
     connc->num_conn--;
-    DEBUGF(infof(data, "The cache now contains %"
-                 CURL_FORMAT_CURL_OFF_TU " members\n",
-                 (curl_off_t) connc->num_conn));
+    DEBUGF(infof(data, "The cache now contains %zu members\n",
+                 connc->num_conn));
+    conn_candidate->data = data; /* associate! */
   }
   }
   CONN_UNLOCK(data);
   CONN_UNLOCK(data);
 
 
@@ -586,7 +570,7 @@ void Curl_conncache_close_all_connections(struct conncache *connc)
                                      pointer */
                                      pointer */
     /* This will remove the connection from the cache */
     /* This will remove the connection from the cache */
     connclose(conn, "kill all");
     connclose(conn, "kill all");
-    (void)Curl_disconnect(conn, FALSE);
+    (void)Curl_disconnect(connc->closure_handle, conn, FALSE);
     sigpipe_restore(&pipe_st);
     sigpipe_restore(&pipe_st);
 
 
     conn = Curl_conncache_find_first_connection(connc);
     conn = Curl_conncache_find_first_connection(connc);

+ 2 - 2
lib/conncache.h

@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *                             \___|\___/|_| \_\_____|
  *
  *
- * Copyright (C) 2015 - 2017, Daniel Stenberg, <[email protected]>, et al.
+ * Copyright (C) 2015 - 2018, Daniel Stenberg, <[email protected]>, et al.
  * Copyright (C) 2012 - 2014, Linus Nielsen Feltzing, <[email protected]>
  * Copyright (C) 2012 - 2014, Linus Nielsen Feltzing, <[email protected]>
  *
  *
  * This software is licensed as described in the file COPYING, which
  * This software is licensed as described in the file COPYING, which
@@ -63,7 +63,7 @@ size_t Curl_conncache_bundle_size(struct connectdata *conn);
 
 
 bool Curl_conncache_return_conn(struct connectdata *conn);
 bool Curl_conncache_return_conn(struct connectdata *conn);
 CURLcode Curl_conncache_add_conn(struct conncache *connc,
 CURLcode Curl_conncache_add_conn(struct conncache *connc,
-                                 struct connectdata *conn);
+                                 struct connectdata *conn) WARN_UNUSED_RESULT;
 void Curl_conncache_remove_conn(struct connectdata *conn,
 void Curl_conncache_remove_conn(struct connectdata *conn,
                                 bool lock);
                                 bool lock);
 bool Curl_conncache_foreach(struct Curl_easy *data,
 bool Curl_conncache_foreach(struct Curl_easy *data,

+ 5 - 7
lib/connect.c

@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *                             \___|\___/|_| \_\_____|
  *
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <[email protected]>, et al.
+ * Copyright (C) 1998 - 2018, Daniel Stenberg, <[email protected]>, et al.
  *
  *
  * This software is licensed as described in the file COPYING, which
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * you should have received as part of this distribution. The terms
@@ -1237,8 +1237,6 @@ static int conn_is_conn(struct connectdata *conn, void *param)
 curl_socket_t Curl_getconnectinfo(struct Curl_easy *data,
 curl_socket_t Curl_getconnectinfo(struct Curl_easy *data,
                                   struct connectdata **connp)
                                   struct connectdata **connp)
 {
 {
-  curl_socket_t sockfd;
-
   DEBUGASSERT(data);
   DEBUGASSERT(data);
 
 
   /* this works for an easy handle:
   /* this works for an easy handle:
@@ -1261,15 +1259,15 @@ curl_socket_t Curl_getconnectinfo(struct Curl_easy *data,
       return CURL_SOCKET_BAD;
       return CURL_SOCKET_BAD;
     }
     }
 
 
-    if(connp)
+    if(connp) {
       /* only store this if the caller cares for it */
       /* only store this if the caller cares for it */
       *connp = c;
       *connp = c;
-    sockfd = c->sock[FIRSTSOCKET];
+      c->data = data;
+    }
+    return c->sock[FIRSTSOCKET];
   }
   }
   else
   else
     return CURL_SOCKET_BAD;
     return CURL_SOCKET_BAD;
-
-  return sockfd;
 }
 }
 
 
 /*
 /*

+ 24 - 16
lib/content_encoding.c

@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *                             \___|\___/|_| \_\_____|
  *
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <[email protected]>, et al.
+ * Copyright (C) 1998 - 2018, Daniel Stenberg, <[email protected]>, et al.
  *
  *
  * This software is licensed as described in the file COPYING, which
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * you should have received as part of this distribution. The terms
@@ -71,13 +71,13 @@
 #define RESERVED     0xE0 /* bits 5..7: reserved */
 #define RESERVED     0xE0 /* bits 5..7: reserved */
 
 
 typedef enum {
 typedef enum {
-  ZLIB_UNINIT,          /* uninitialized */
-  ZLIB_INIT,            /* initialized */
-  ZLIB_INFLATING,       /* Inflating started. */
-  ZLIB_GZIP_HEADER,     /* reading gzip header */
-  ZLIB_GZIP_TRAILER,    /* reading gzip trailer */
-  ZLIB_GZIP_INFLATING,  /* inflating gzip stream */
-  ZLIB_INIT_GZIP        /* initialized in transparent gzip mode */
+  ZLIB_UNINIT,               /* uninitialized */
+  ZLIB_INIT,                 /* initialized */
+  ZLIB_INFLATING,            /* inflating started. */
+  ZLIB_EXTERNAL_TRAILER,     /* reading external trailer */
+  ZLIB_GZIP_HEADER,          /* reading gzip header */
+  ZLIB_GZIP_INFLATING,       /* inflating gzip stream */
+  ZLIB_INIT_GZIP             /* initialized in transparent gzip mode */
 } zlibInitState;
 } zlibInitState;
 
 
 /* Writer parameters. */
 /* Writer parameters. */
@@ -150,8 +150,8 @@ static CURLcode process_trailer(struct connectdata *conn, zlib_params *zp)
   if(result || !zp->trailerlen)
   if(result || !zp->trailerlen)
     result = exit_zlib(conn, z, &zp->zlib_init, result);
     result = exit_zlib(conn, z, &zp->zlib_init, result);
   else {
   else {
-    /* Only occurs for gzip with zlib < 1.2.0.4. */
-    zp->zlib_init = ZLIB_GZIP_TRAILER;
+    /* Only occurs for gzip with zlib < 1.2.0.4 or raw deflate. */
+    zp->zlib_init = ZLIB_EXTERNAL_TRAILER;
   }
   }
   return result;
   return result;
 }
 }
@@ -163,7 +163,6 @@ static CURLcode inflate_stream(struct connectdata *conn,
   z_stream *z = &zp->z;         /* zlib state structure */
   z_stream *z = &zp->z;         /* zlib state structure */
   uInt nread = z->avail_in;
   uInt nread = z->avail_in;
   Bytef *orig_in = z->next_in;
   Bytef *orig_in = z->next_in;
-  int status;                   /* zlib status */
   bool done = FALSE;
   bool done = FALSE;
   CURLcode result = CURLE_OK;   /* Curl_client_write status */
   CURLcode result = CURLE_OK;   /* Curl_client_write status */
   char *decomp;                 /* Put the decompressed data here. */
   char *decomp;                 /* Put the decompressed data here. */
@@ -184,13 +183,20 @@ static CURLcode inflate_stream(struct connectdata *conn,
   /* because the buffer size is fixed, iteratively decompress and transfer to
   /* because the buffer size is fixed, iteratively decompress and transfer to
      the client via downstream_write function. */
      the client via downstream_write function. */
   while(!done) {
   while(!done) {
+    int status;                   /* zlib status */
     done = TRUE;
     done = TRUE;
 
 
     /* (re)set buffer for decompressed output for every iteration */
     /* (re)set buffer for decompressed output for every iteration */
     z->next_out = (Bytef *) decomp;
     z->next_out = (Bytef *) decomp;
     z->avail_out = DSIZ;
     z->avail_out = DSIZ;
 
 
+#ifdef Z_BLOCK
+    /* Z_BLOCK is only available in zlib ver. >= 1.2.0.5 */
     status = inflate(z, Z_BLOCK);
     status = inflate(z, Z_BLOCK);
+#else
+    /* fallback for zlib ver. < 1.2.0.5 */
+    status = inflate(z, Z_SYNC_FLUSH);
+#endif
 
 
     /* Flush output data if some. */
     /* Flush output data if some. */
     if(z->avail_out != DSIZ) {
     if(z->avail_out != DSIZ) {
@@ -227,6 +233,7 @@ static CURLcode inflate_stream(struct connectdata *conn,
           z->next_in = orig_in;
           z->next_in = orig_in;
           z->avail_in = nread;
           z->avail_in = nread;
           zp->zlib_init = ZLIB_INFLATING;
           zp->zlib_init = ZLIB_INFLATING;
+          zp->trailerlen = 4; /* Tolerate up to 4 unknown trailer bytes. */
           done = FALSE;
           done = FALSE;
           break;
           break;
         }
         }
@@ -281,6 +288,9 @@ static CURLcode deflate_unencode_write(struct connectdata *conn,
   z->next_in = (Bytef *) buf;
   z->next_in = (Bytef *) buf;
   z->avail_in = (uInt) nbytes;
   z->avail_in = (uInt) nbytes;
 
 
+  if(zp->zlib_init == ZLIB_EXTERNAL_TRAILER)
+    return process_trailer(conn, zp);
+
   /* Now uncompress the data */
   /* Now uncompress the data */
   return inflate_stream(conn, writer, ZLIB_INFLATING);
   return inflate_stream(conn, writer, ZLIB_INFLATING);
 }
 }
@@ -526,7 +536,7 @@ static CURLcode gzip_unencode_write(struct connectdata *conn,
   }
   }
   break;
   break;
 
 
-  case ZLIB_GZIP_TRAILER:
+  case ZLIB_EXTERNAL_TRAILER:
     z->next_in = (Bytef *) buf;
     z->next_in = (Bytef *) buf;
     z->avail_in = (uInt) nbytes;
     z->avail_in = (uInt) nbytes;
     return process_trailer(conn, zp);
     return process_trailer(conn, zp);
@@ -755,7 +765,6 @@ char *Curl_all_content_encodings(void)
   const content_encoding * const *cep;
   const content_encoding * const *cep;
   const content_encoding *ce;
   const content_encoding *ce;
   char *ace;
   char *ace;
-  char *p;
 
 
   for(cep = encodings; *cep; cep++) {
   for(cep = encodings; *cep; cep++) {
     ce = *cep;
     ce = *cep;
@@ -768,7 +777,7 @@ char *Curl_all_content_encodings(void)
 
 
   ace = malloc(len);
   ace = malloc(len);
   if(ace) {
   if(ace) {
-    p = ace;
+    char *p = ace;
     for(cep = encodings; *cep; cep++) {
     for(cep = encodings; *cep; cep++) {
       ce = *cep;
       ce = *cep;
       if(!strcasecompare(ce->name, CONTENT_ENCODING_DEFAULT)) {
       if(!strcasecompare(ce->name, CONTENT_ENCODING_DEFAULT)) {
@@ -915,10 +924,9 @@ void Curl_unencode_cleanup(struct connectdata *conn)
 static const content_encoding *find_encoding(const char *name, size_t len)
 static const content_encoding *find_encoding(const char *name, size_t len)
 {
 {
   const content_encoding * const *cep;
   const content_encoding * const *cep;
-  const content_encoding *ce;
 
 
   for(cep = encodings; *cep; cep++) {
   for(cep = encodings; *cep; cep++) {
-    ce = *cep;
+    const content_encoding *ce = *cep;
     if((strncasecompare(name, ce->name, len) && !ce->name[len]) ||
     if((strncasecompare(name, ce->name, len) && !ce->name[len]) ||
        (ce->alias && strncasecompare(name, ce->alias, len) && !ce->alias[len]))
        (ce->alias && strncasecompare(name, ce->alias, len) && !ce->alias[len]))
       return ce;
       return ce;

+ 83 - 47
lib/cookie.c

@@ -40,7 +40,7 @@ struct Cookie *Curl_cookie_add(struct Curl_easy *data,
         received from a server.
         received from a server.
 
 
         The function need to replace previously stored lines that this new
         The function need to replace previously stored lines that this new
-        line superceeds.
+        line supersedes.
 
 
         It may remove lines that are expired.
         It may remove lines that are expired.
 
 
@@ -84,12 +84,9 @@ Example set of cookies:
 
 
 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
 
 
-#ifdef USE_LIBPSL
-# include <libpsl.h>
-#endif
-
 #include "urldata.h"
 #include "urldata.h"
 #include "cookie.h"
 #include "cookie.h"
+#include "psl.h"
 #include "strtok.h"
 #include "strtok.h"
 #include "sendf.h"
 #include "sendf.h"
 #include "slist.h"
 #include "slist.h"
@@ -253,9 +250,9 @@ static const char *get_top_domain(const char * const domain, size_t *outlen)
   len = strlen(domain);
   len = strlen(domain);
   last = memrchr(domain, '.', len);
   last = memrchr(domain, '.', len);
   if(last) {
   if(last) {
-    first = memrchr(domain, '.', (size_t) (last - domain));
+    first = memrchr(domain, '.', (last - domain));
     if(first)
     if(first)
-      len -= (size_t) (++first - domain);
+      len -= (++first - domain);
   }
   }
 
 
   if(outlen)
   if(outlen)
@@ -379,13 +376,13 @@ static void strstore(char **str, const char *newstr)
  */
  */
 static void remove_expired(struct CookieInfo *cookies)
 static void remove_expired(struct CookieInfo *cookies)
 {
 {
-  struct Cookie *co, *nx, *pv;
+  struct Cookie *co, *nx;
   curl_off_t now = (curl_off_t)time(NULL);
   curl_off_t now = (curl_off_t)time(NULL);
   unsigned int i;
   unsigned int i;
 
 
   for(i = 0; i < COOKIE_HASH_SIZE; i++) {
   for(i = 0; i < COOKIE_HASH_SIZE; i++) {
+    struct Cookie *pv = NULL;
     co = cookies->cookies[i];
     co = cookies->cookies[i];
-    pv = NULL;
     while(co) {
     while(co) {
       nx = co->next;
       nx = co->next;
       if(co->expires && co->expires < now) {
       if(co->expires && co->expires < now) {
@@ -406,6 +403,12 @@ static void remove_expired(struct CookieInfo *cookies)
   }
   }
 }
 }
 
 
+/* Make sure domain contains a dot or is localhost. */
+static bool bad_domain(const char *domain)
+{
+  return !strchr(domain, '.') && !strcasecompare(domain, "localhost");
+}
+
 /****************************************************************************
 /****************************************************************************
  *
  *
  * Curl_cookie_add()
  * Curl_cookie_add()
@@ -442,10 +445,6 @@ Curl_cookie_add(struct Curl_easy *data,
   bool badcookie = FALSE; /* cookies are good by default. mmmmm yummy */
   bool badcookie = FALSE; /* cookies are good by default. mmmmm yummy */
   size_t myhash;
   size_t myhash;
 
 
-#ifdef USE_LIBPSL
-  const psl_ctx_t *psl;
-#endif
-
 #ifdef CURL_DISABLE_VERBOSE_STRINGS
 #ifdef CURL_DISABLE_VERBOSE_STRINGS
   (void)data;
   (void)data;
 #endif
 #endif
@@ -497,7 +496,7 @@ Curl_cookie_add(struct Curl_easy *data,
              name + contents. Chrome and Firefox support 4095 or 4096 bytes
              name + contents. Chrome and Firefox support 4095 or 4096 bytes
              combo. */
              combo. */
           freecookie(co);
           freecookie(co);
-          infof(data, "oversized cookie dropped, name/val %d + %d bytes\n",
+          infof(data, "oversized cookie dropped, name/val %zu + %zu bytes\n",
                 nlen, len);
                 nlen, len);
           return NULL;
           return NULL;
         }
         }
@@ -585,13 +584,8 @@ Curl_cookie_add(struct Curl_easy *data,
            * TLD or otherwise "protected" suffix. To reduce risk, we require a
            * TLD or otherwise "protected" suffix. To reduce risk, we require a
            * dot OR the exact host name being "localhost".
            * dot OR the exact host name being "localhost".
            */
            */
-          {
-            const char *dotp;
-            /* check for more dots */
-            dotp = strchr(whatptr, '.');
-            if(!dotp && !strcasecompare("localhost", whatptr))
-              domain = ":";
-          }
+          if(bad_domain(whatptr))
+            domain = ":";
 #endif
 #endif
 
 
           is_ip = isip(domain ? domain : whatptr);
           is_ip = isip(domain ? domain : whatptr);
@@ -723,9 +717,9 @@ Curl_cookie_add(struct Curl_easy *data,
       if(!queryp)
       if(!queryp)
         endslash = strrchr(path, '/');
         endslash = strrchr(path, '/');
       else
       else
-        endslash = memrchr(path, '/', (size_t)(queryp - path));
+        endslash = memrchr(path, '/', (queryp - path));
       if(endslash) {
       if(endslash) {
-        size_t pathlen = (size_t)(endslash-path + 1); /* include end slash */
+        size_t pathlen = (endslash-path + 1); /* include end slash */
         co->path = malloc(pathlen + 1); /* one extra for the zero byte */
         co->path = malloc(pathlen + 1); /* one extra for the zero byte */
         if(co->path) {
         if(co->path) {
           memcpy(co->path, path, pathlen);
           memcpy(co->path, path, pathlen);
@@ -880,9 +874,10 @@ Curl_cookie_add(struct Curl_easy *data,
   }
   }
 
 
   co->livecookie = c->running;
   co->livecookie = c->running;
+  co->creationtime = ++c->lastct;
 
 
   /* now, we have parsed the incoming line, we must now check if this
   /* now, we have parsed the incoming line, we must now check if this
-     superceeds an already existing cookie, which it may if the previous have
+     supersedes an already existing cookie, which it may if the previous have
      the same domain and path as this */
      the same domain and path as this */
 
 
   /* at first, remove expired cookies */
   /* at first, remove expired cookies */
@@ -890,14 +885,21 @@ Curl_cookie_add(struct Curl_easy *data,
     remove_expired(c);
     remove_expired(c);
 
 
 #ifdef USE_LIBPSL
 #ifdef USE_LIBPSL
-  /* Check if the domain is a Public Suffix and if yes, ignore the cookie.
-     This needs a libpsl compiled with builtin data. */
+  /* Check if the domain is a Public Suffix and if yes, ignore the cookie. */
   if(domain && co->domain && !isip(co->domain)) {
   if(domain && co->domain && !isip(co->domain)) {
-    psl = psl_builtin();
-    if(psl && !psl_is_cookie_domain_acceptable(psl, domain, co->domain)) {
-      infof(data,
-            "cookie '%s' dropped, domain '%s' must not set cookies for '%s'\n",
-            co->name, domain, co->domain);
+    const psl_ctx_t *psl = Curl_psl_use(data);
+    int acceptable;
+
+    if(psl) {
+      acceptable = psl_is_cookie_domain_acceptable(psl, domain, co->domain);
+      Curl_psl_release(data);
+    }
+    else
+      acceptable = !bad_domain(domain);
+
+    if(!acceptable) {
+      infof(data, "cookie '%s' dropped, domain '%s' must not "
+                  "set cookies for '%s'\n", co->name, domain, co->domain);
       freecookie(co);
       freecookie(co);
       return NULL;
       return NULL;
     }
     }
@@ -951,6 +953,9 @@ Curl_cookie_add(struct Curl_easy *data,
       if(replace_old) {
       if(replace_old) {
         co->next = clist->next; /* get the next-pointer first */
         co->next = clist->next; /* get the next-pointer first */
 
 
+        /* when replacing, creationtime is kept from old */
+        co->creationtime = clist->creationtime;
+
         /* then free all the old pointers */
         /* then free all the old pointers */
         free(clist->name);
         free(clist->name);
         free(clist->value);
         free(clist->value);
@@ -1140,12 +1145,24 @@ static int cookie_sort(const void *p1, const void *p2)
   if(l1 != l2)
   if(l1 != l2)
     return (l2 > l1) ? 1 : -1 ;  /* avoid size_t <=> int conversions */
     return (l2 > l1) ? 1 : -1 ;  /* avoid size_t <=> int conversions */
 
 
-  /* 3 - compare cookie names */
-  if(c1->name && c2->name)
-    return strcmp(c1->name, c2->name);
+  /* 3 - compare cookie name lengths */
+  l1 = c1->name ? strlen(c1->name) : 0;
+  l2 = c2->name ? strlen(c2->name) : 0;
 
 
-  /* sorry, can't be more deterministic */
-  return 0;
+  if(l1 != l2)
+    return (l2 > l1) ? 1 : -1;
+
+  /* 4 - compare cookie creation time */
+  return (c2->creationtime > c1->creationtime) ? 1 : -1;
+}
+
+/* sort cookies only according to creation time */
+static int cookie_sort_ct(const void *p1, const void *p2)
+{
+  struct Cookie *c1 = *(struct Cookie **)p1;
+  struct Cookie *c2 = *(struct Cookie **)p2;
+
+  return (c2->creationtime > c1->creationtime) ? 1 : -1;
 }
 }
 
 
 #define CLONE(field)                     \
 #define CLONE(field)                     \
@@ -1174,6 +1191,7 @@ static struct Cookie *dup_cookie(struct Cookie *src)
     d->secure = src->secure;
     d->secure = src->secure;
     d->livecookie = src->livecookie;
     d->livecookie = src->livecookie;
     d->httponly = src->httponly;
     d->httponly = src->httponly;
+    d->creationtime = src->creationtime;
   }
   }
   return d;
   return d;
 
 
@@ -1384,9 +1402,8 @@ void Curl_cookie_clearsess(struct CookieInfo *cookies)
  ****************************************************************************/
  ****************************************************************************/
 void Curl_cookie_cleanup(struct CookieInfo *c)
 void Curl_cookie_cleanup(struct CookieInfo *c)
 {
 {
-  unsigned int i;
-
   if(c) {
   if(c) {
+    unsigned int i;
     free(c->filename);
     free(c->filename);
     for(i = 0; i < COOKIE_HASH_SIZE; i++)
     for(i = 0; i < COOKIE_HASH_SIZE; i++)
       Curl_cookie_freelist(c->cookies[i]);
       Curl_cookie_freelist(c->cookies[i]);
@@ -1439,6 +1456,8 @@ static int cookie_output(struct CookieInfo *c, const char *dumphere)
   bool use_stdout = FALSE;
   bool use_stdout = FALSE;
   char *format_ptr;
   char *format_ptr;
   unsigned int i;
   unsigned int i;
+  unsigned int j;
+  struct Cookie **array;
 
 
   if((NULL == c) || (0 == c->numcookies))
   if((NULL == c) || (0 == c->numcookies))
     /* If there are no known cookies, we don't write or even create any
     /* If there are no known cookies, we don't write or even create any
@@ -1452,6 +1471,10 @@ static int cookie_output(struct CookieInfo *c, const char *dumphere)
   if(0 == c->numcookies)
   if(0 == c->numcookies)
     return 0;
     return 0;
 
 
+  array = malloc(sizeof(struct Cookie *) * c->numcookies);
+  if(!array)
+    return 1;
+
   if(!strcmp("-", dumphere)) {
   if(!strcmp("-", dumphere)) {
     /* use stdout */
     /* use stdout */
     out = stdout;
     out = stdout;
@@ -1459,8 +1482,10 @@ static int cookie_output(struct CookieInfo *c, const char *dumphere)
   }
   }
   else {
   else {
     out = fopen(dumphere, FOPEN_WRITETEXT);
     out = fopen(dumphere, FOPEN_WRITETEXT);
-    if(!out)
+    if(!out) {
+      free(array);
       return 1; /* failure */
       return 1; /* failure */
+    }
   }
   }
 
 
   fputs("# Netscape HTTP Cookie File\n"
   fputs("# Netscape HTTP Cookie File\n"
@@ -1468,22 +1493,33 @@ static int cookie_output(struct CookieInfo *c, const char *dumphere)
         "# This file was generated by libcurl! Edit at your own risk.\n\n",
         "# This file was generated by libcurl! Edit at your own risk.\n\n",
         out);
         out);
 
 
+  j = 0;
   for(i = 0; i < COOKIE_HASH_SIZE; i++) {
   for(i = 0; i < COOKIE_HASH_SIZE; i++) {
     for(co = c->cookies[i]; co; co = co->next) {
     for(co = c->cookies[i]; co; co = co->next) {
       if(!co->domain)
       if(!co->domain)
         continue;
         continue;
-      format_ptr = get_netscape_format(co);
-      if(format_ptr == NULL) {
-        fprintf(out, "#\n# Fatal libcurl error\n");
-        if(!use_stdout)
-          fclose(out);
-        return 1;
+      array[j++] = co;
+    }
+  }
+
+  qsort(array, c->numcookies, sizeof(struct Cookie *), cookie_sort_ct);
+
+  for(i = 0; i < j; i++) {
+    format_ptr = get_netscape_format(array[i]);
+    if(format_ptr == NULL) {
+      fprintf(out, "#\n# Fatal libcurl error\n");
+      if(!use_stdout) {
+        free(array);
+        fclose(out);
       }
       }
-      fprintf(out, "%s\n", format_ptr);
-      free(format_ptr);
+      return 1;
     }
     }
+    fprintf(out, "%s\n", format_ptr);
+    free(format_ptr);
   }
   }
 
 
+  free(array);
+
   if(!use_stdout)
   if(!use_stdout)
     fclose(out);
     fclose(out);
 
 

+ 3 - 1
lib/cookie.h

@@ -34,7 +34,7 @@ struct Cookie {
   char *domain;      /* domain = <this> */
   char *domain;      /* domain = <this> */
   curl_off_t expires;  /* expires = <this> */
   curl_off_t expires;  /* expires = <this> */
   char *expirestr;   /* the plain text version */
   char *expirestr;   /* the plain text version */
-  bool tailmatch;    /* weather we do tail-matchning of the domain name */
+  bool tailmatch;    /* whether we do tail-matching of the domain name */
 
 
   /* RFC 2109 keywords. Version=1 means 2109-compliant cookie sending */
   /* RFC 2109 keywords. Version=1 means 2109-compliant cookie sending */
   char *version;     /* Version = <value> */
   char *version;     /* Version = <value> */
@@ -43,6 +43,7 @@ struct Cookie {
   bool secure;       /* whether the 'secure' keyword was used */
   bool secure;       /* whether the 'secure' keyword was used */
   bool livecookie;   /* updated from a server, not a stored file */
   bool livecookie;   /* updated from a server, not a stored file */
   bool httponly;     /* true if the httponly directive is present */
   bool httponly;     /* true if the httponly directive is present */
+  int creationtime;  /* time when the cookie was written */
 };
 };
 
 
 #define COOKIE_HASH_SIZE 256
 #define COOKIE_HASH_SIZE 256
@@ -55,6 +56,7 @@ struct CookieInfo {
   bool running;    /* state info, for cookie adding information */
   bool running;    /* state info, for cookie adding information */
   long numcookies; /* number of cookies in the "jar" */
   long numcookies; /* number of cookies in the "jar" */
   bool newsession; /* new session, discard session cookies on load */
   bool newsession; /* new session, discard session cookies on load */
+  int lastct;      /* last creation-time used in the jar */
 };
 };
 
 
 /* This is the maximum line length we accept for a cookie line. RFC 2109
 /* This is the maximum line length we accept for a cookie line. RFC 2109

+ 2 - 1
lib/curl_addrinfo.c

@@ -536,7 +536,8 @@ Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath, bool abstract)
 }
 }
 #endif
 #endif
 
 
-#if defined(CURLDEBUG) && defined(HAVE_FREEADDRINFO)
+#if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) &&  \
+  defined(HAVE_FREEADDRINFO)
 /*
 /*
  * curl_dofreeaddrinfo()
  * curl_dofreeaddrinfo()
  *
  *

+ 6 - 0
lib/curl_config.h.cmake

@@ -235,6 +235,9 @@
 /* Define to 1 if you have the `getpwuid' function. */
 /* Define to 1 if you have the `getpwuid' function. */
 #cmakedefine HAVE_GETPWUID 1
 #cmakedefine HAVE_GETPWUID 1
 
 
+/* Define to 1 if you have the `getpwuid_r' function. */
+#cmakedefine HAVE_GETPWUID_R 1
+
 /* Define to 1 if you have the `getrlimit' function. */
 /* Define to 1 if you have the `getrlimit' function. */
 #cmakedefine HAVE_GETRLIMIT 1
 #cmakedefine HAVE_GETRLIMIT 1
 
 
@@ -963,6 +966,9 @@
 /* to enable Windows SSL  */
 /* to enable Windows SSL  */
 #cmakedefine USE_SCHANNEL 1
 #cmakedefine USE_SCHANNEL 1
 
 
+/* enable multiple SSL backends */
+#cmakedefine CURL_WITH_MULTI_SSL 1
+
 /* Define to 1 if using yaSSL in OpenSSL compatibility mode. */
 /* Define to 1 if using yaSSL in OpenSSL compatibility mode. */
 #cmakedefine USE_YASSLEMUL 1
 #cmakedefine USE_YASSLEMUL 1
 
 

+ 40 - 3
lib/curl_fnmatch.c

@@ -30,6 +30,17 @@
 /* The last #include file should be: */
 /* The last #include file should be: */
 #include "memdebug.h"
 #include "memdebug.h"
 
 
+#ifndef HAVE_FNMATCH
+
+/*
+ * TODO:
+ *
+ * Make this function match POSIX. Test 1307 includes a set of test patterns
+ * that returns different results with a POSIX fnmatch() than with this
+ * implementation and this is considered a bug where POSIX is the guiding
+ * light.
+ */
+
 #define CURLFNM_CHARSET_LEN (sizeof(char) * 256)
 #define CURLFNM_CHARSET_LEN (sizeof(char) * 256)
 #define CURLFNM_CHSET_SIZE (CURLFNM_CHARSET_LEN + 15)
 #define CURLFNM_CHSET_SIZE (CURLFNM_CHARSET_LEN + 15)
 
 
@@ -334,9 +345,9 @@ static int loop(const unsigned char *pattern, const unsigned char *string,
         s++;
         s++;
         break;
         break;
       }
       }
+      /* Syntax error in set; mismatch! */
+      return CURL_FNMATCH_NOMATCH;
 
 
-      /* Syntax error in set: this must be taken as a regular character. */
-      /* FALLTHROUGH */
     default:
     default:
       if(*p++ != *s++)
       if(*p++ != *s++)
         return CURL_FNMATCH_NOMATCH;
         return CURL_FNMATCH_NOMATCH;
@@ -355,5 +366,31 @@ int Curl_fnmatch(void *ptr, const char *pattern, const char *string)
   if(!pattern || !string) {
   if(!pattern || !string) {
     return CURL_FNMATCH_FAIL;
     return CURL_FNMATCH_FAIL;
   }
   }
-  return loop((unsigned char *)pattern, (unsigned char *)string, 5);
+  return loop((unsigned char *)pattern, (unsigned char *)string, 2);
+}
+#else
+#include <fnmatch.h>
+/*
+ * @unittest: 1307
+ */
+int Curl_fnmatch(void *ptr, const char *pattern, const char *string)
+{
+  int rc;
+  (void)ptr; /* the argument is specified by the curl_fnmatch_callback
+                prototype, but not used by Curl_fnmatch() */
+  if(!pattern || !string) {
+    return CURL_FNMATCH_FAIL;
+  }
+  rc = fnmatch(pattern, string, 0);
+  switch(rc) {
+  case 0:
+    return CURL_FNMATCH_MATCH;
+  case FNM_NOMATCH:
+    return CURL_FNMATCH_NOMATCH;
+  default:
+    return CURL_FNMATCH_FAIL;
+  }
+  /* not reached */
 }
 }
+
+#endif

+ 4 - 1
lib/curl_ntlm_core.c

@@ -557,8 +557,11 @@ CURLcode Curl_ntlm_core_mk_nt_hash(struct Curl_easy *data,
                                    unsigned char *ntbuffer /* 21 bytes */)
                                    unsigned char *ntbuffer /* 21 bytes */)
 {
 {
   size_t len = strlen(password);
   size_t len = strlen(password);
-  unsigned char *pw = len ? malloc(len * 2) : strdup("");
+  unsigned char *pw;
   CURLcode result;
   CURLcode result;
+  if(len > SIZE_T_MAX/2) /* avoid integer overflow */
+    return CURLE_OUT_OF_MEMORY;
+  pw = len ? malloc(len * 2) : strdup("");
   if(!pw)
   if(!pw)
     return CURLE_OUT_OF_MEMORY;
     return CURLE_OUT_OF_MEMORY;
 
 

+ 1 - 2
lib/curl_sasl.c

@@ -146,7 +146,6 @@ CURLcode Curl_sasl_parse_url_auth_option(struct SASL *sasl,
                                          const char *value, size_t len)
                                          const char *value, size_t len)
 {
 {
   CURLcode result = CURLE_OK;
   CURLcode result = CURLE_OK;
-  unsigned int mechbit;
   size_t mechlen;
   size_t mechlen;
 
 
   if(!len)
   if(!len)
@@ -160,7 +159,7 @@ CURLcode Curl_sasl_parse_url_auth_option(struct SASL *sasl,
   if(!strncmp(value, "*", len))
   if(!strncmp(value, "*", len))
     sasl->prefmech = SASL_AUTH_DEFAULT;
     sasl->prefmech = SASL_AUTH_DEFAULT;
   else {
   else {
-    mechbit = Curl_sasl_decode_mech(value, len, &mechlen);
+    unsigned int mechbit = Curl_sasl_decode_mech(value, len, &mechlen);
     if(mechbit && mechlen == len)
     if(mechbit && mechlen == len)
       sasl->prefmech |= mechbit;
       sasl->prefmech |= mechbit;
     else
     else

+ 14 - 1
lib/curl_setup.h

@@ -217,7 +217,7 @@
 
 
 /*
 /*
  * Use getaddrinfo to resolve the IPv4 address literal. If the current network
  * Use getaddrinfo to resolve the IPv4 address literal. If the current network
- * interface doesnt support IPv4, but supports IPv6, NAT64, and DNS64,
+ * interface doesn't support IPv4, but supports IPv6, NAT64, and DNS64,
  * performing this task will result in a synthesized IPv6 address.
  * performing this task will result in a synthesized IPv6 address.
  */
  */
 #ifdef  __APPLE__
 #ifdef  __APPLE__
@@ -242,6 +242,7 @@
 #  if defined(_UNICODE) && !defined(UNICODE)
 #  if defined(_UNICODE) && !defined(UNICODE)
 #    define UNICODE
 #    define UNICODE
 #  endif
 #  endif
+#  include <winerror.h>
 #  include <windows.h>
 #  include <windows.h>
 #  ifdef HAVE_WINSOCK2_H
 #  ifdef HAVE_WINSOCK2_H
 #    include <winsock2.h>
 #    include <winsock2.h>
@@ -800,4 +801,16 @@ endings either CRLF or LF so 't' is appropriate.
 #define CURL_SA_FAMILY_T unsigned short
 #define CURL_SA_FAMILY_T unsigned short
 #endif
 #endif
 
 
+/* Some convenience macros to get the larger/smaller value out of two given.
+   We prefix with CURL to prevent name collisions. */
+#define CURLMAX(x,y) ((x)>(y)?(x):(y))
+#define CURLMIN(x,y) ((x)<(y)?(x):(y))
+
+/* Some versions of the Android SDK is missing the declaration */
+#if defined(HAVE_GETPWUID_R) && defined(HAVE_DECL_GETPWUID_R_MISSING)
+struct passwd;
+int getpwuid_r(uid_t uid, struct passwd *pwd, char *buf,
+               size_t buflen, struct passwd **result);
+#endif
+
 #endif /* HEADER_CURL_SETUP_H */
 #endif /* HEADER_CURL_SETUP_H */

+ 2 - 1
lib/curl_threads.c

@@ -108,7 +108,8 @@ curl_thread_t Curl_thread_create(unsigned int (CURL_STDCALL *func) (void *),
 #ifdef _WIN32_WCE
 #ifdef _WIN32_WCE
   t = CreateThread(NULL, 0, func, arg, 0, NULL);
   t = CreateThread(NULL, 0, func, arg, 0, NULL);
 #else
 #else
-  t = (curl_thread_t)_beginthreadex(NULL, 0, func, arg, 0, NULL);
+  uintptr_t thread_handle = _beginthreadex(NULL, 0, func, arg, 0, NULL);
+  t = (curl_thread_t)thread_handle;
 #endif
 #endif
   if((t == 0) || (t == LongToHandle(-1L))) {
   if((t == 0) || (t == LongToHandle(-1L))) {
 #ifdef _WIN32_WCE
 #ifdef _WIN32_WCE

+ 5 - 5
lib/dict.c

@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *                             \___|\___/|_| \_\_____|
  *
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <[email protected]>, et al.
+ * Copyright (C) 1998 - 2018, Daniel Stenberg, <[email protected]>, et al.
  *
  *
  * This software is licensed as described in the file COPYING, which
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * you should have received as part of this distribution. The terms
@@ -95,17 +95,17 @@ static char *unescape_word(struct Curl_easy *data, const char *inputbuff)
 {
 {
   char *newp = NULL;
   char *newp = NULL;
   char *dictp;
   char *dictp;
-  char *ptr;
   size_t len;
   size_t len;
-  char ch;
-  int olen = 0;
 
 
   CURLcode result = Curl_urldecode(data, inputbuff, 0, &newp, &len, FALSE);
   CURLcode result = Curl_urldecode(data, inputbuff, 0, &newp, &len, FALSE);
   if(!newp || result)
   if(!newp || result)
     return NULL;
     return NULL;
 
 
-  dictp = malloc(((size_t)len)*2 + 1); /* add one for terminating zero */
+  dictp = malloc(len*2 + 1); /* add one for terminating zero */
   if(dictp) {
   if(dictp) {
+    char *ptr;
+    char ch;
+    int olen = 0;
     /* According to RFC2229 section 2.2, these letters need to be escaped with
     /* According to RFC2229 section 2.2, these letters need to be escaped with
        \[letter] */
        \[letter] */
     for(ptr = newp;
     for(ptr = newp;

+ 15 - 19
lib/easy.c

@@ -113,7 +113,7 @@ static CURLcode win32_init(void)
   res = WSAStartup(wVersionRequested, &wsaData);
   res = WSAStartup(wVersionRequested, &wsaData);
 
 
   if(res != 0)
   if(res != 0)
-    /* Tell the user that we couldn't find a useable */
+    /* Tell the user that we couldn't find a usable */
     /* winsock.dll.     */
     /* winsock.dll.     */
     return CURLE_FAILED_INIT;
     return CURLE_FAILED_INIT;
 
 
@@ -125,7 +125,7 @@ static CURLcode win32_init(void)
 
 
   if(LOBYTE(wsaData.wVersion) != LOBYTE(wVersionRequested) ||
   if(LOBYTE(wsaData.wVersion) != LOBYTE(wVersionRequested) ||
      HIBYTE(wsaData.wVersion) != HIBYTE(wVersionRequested) ) {
      HIBYTE(wsaData.wVersion) != HIBYTE(wVersionRequested) ) {
-    /* Tell the user that we couldn't find a useable */
+    /* Tell the user that we couldn't find a usable */
 
 
     /* winsock.dll. */
     /* winsock.dll. */
     WSACleanup();
     WSACleanup();
@@ -661,38 +661,27 @@ static CURLcode easy_transfer(struct Curl_multi *multi)
   bool done = FALSE;
   bool done = FALSE;
   CURLMcode mcode = CURLM_OK;
   CURLMcode mcode = CURLM_OK;
   CURLcode result = CURLE_OK;
   CURLcode result = CURLE_OK;
-  struct curltime before;
-  int without_fds = 0;  /* count number of consecutive returns from
-                           curl_multi_wait() without any filedescriptors */
 
 
   while(!done && !mcode) {
   while(!done && !mcode) {
     int still_running = 0;
     int still_running = 0;
     int rc;
     int rc;
 
 
-    before = Curl_now();
     mcode = curl_multi_wait(multi, NULL, 0, 1000, &rc);
     mcode = curl_multi_wait(multi, NULL, 0, 1000, &rc);
 
 
     if(!mcode) {
     if(!mcode) {
       if(!rc) {
       if(!rc) {
-        struct curltime after = Curl_now();
+        long sleep_ms;
 
 
         /* If it returns without any filedescriptor instantly, we need to
         /* If it returns without any filedescriptor instantly, we need to
            avoid busy-looping during periods where it has nothing particular
            avoid busy-looping during periods where it has nothing particular
            to wait for */
            to wait for */
-        if(Curl_timediff(after, before) <= 10) {
-          without_fds++;
-          if(without_fds > 2) {
-            int sleep_ms = without_fds < 10 ? (1 << (without_fds - 1)) : 1000;
-            Curl_wait_ms(sleep_ms);
-          }
+        curl_multi_timeout(multi, &sleep_ms);
+        if(sleep_ms) {
+          if(sleep_ms > 1000)
+            sleep_ms = 1000;
+          Curl_wait_ms((int)sleep_ms);
         }
         }
-        else
-          /* it wasn't "instant", restart counter */
-          without_fds = 0;
       }
       }
-      else
-        /* got file descriptor, restart counter */
-        without_fds = 0;
 
 
       mcode = curl_multi_perform(multi, &still_running);
       mcode = curl_multi_perform(multi, &still_running);
     }
     }
@@ -969,6 +958,13 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data)
     outcurl->change.referer_alloc = TRUE;
     outcurl->change.referer_alloc = TRUE;
   }
   }
 
 
+  /* Reinitialize an SSL engine for the new handle
+   * note: the engine name has already been copied by dupset */
+  if(outcurl->set.str[STRING_SSL_ENGINE]) {
+    if(Curl_ssl_set_engine(outcurl, outcurl->set.str[STRING_SSL_ENGINE]))
+      goto fail;
+  }
+
   /* Clone the resolver handle, if present, for the new handle */
   /* Clone the resolver handle, if present, for the new handle */
   if(Curl_resolver_duphandle(&outcurl->state.resolver,
   if(Curl_resolver_duphandle(&outcurl->state.resolver,
                              data->state.resolver))
                              data->state.resolver))

+ 2 - 4
lib/escape.c

@@ -82,7 +82,6 @@ char *curl_easy_escape(struct Curl_easy *data, const char *string,
   size_t alloc;
   size_t alloc;
   char *ns;
   char *ns;
   char *testing_ptr = NULL;
   char *testing_ptr = NULL;
-  unsigned char in; /* we need to treat the characters unsigned */
   size_t newlen;
   size_t newlen;
   size_t strindex = 0;
   size_t strindex = 0;
   size_t length;
   size_t length;
@@ -100,7 +99,7 @@ char *curl_easy_escape(struct Curl_easy *data, const char *string,
 
 
   length = alloc-1;
   length = alloc-1;
   while(length--) {
   while(length--) {
-    in = *string;
+    unsigned char in = *string; /* we need to treat the characters unsigned */
 
 
     if(Curl_isunreserved(in))
     if(Curl_isunreserved(in))
       /* just copy this */
       /* just copy this */
@@ -150,7 +149,6 @@ CURLcode Curl_urldecode(struct Curl_easy *data,
 {
 {
   size_t alloc = (length?length:strlen(string)) + 1;
   size_t alloc = (length?length:strlen(string)) + 1;
   char *ns = malloc(alloc);
   char *ns = malloc(alloc);
-  unsigned char in;
   size_t strindex = 0;
   size_t strindex = 0;
   unsigned long hex;
   unsigned long hex;
   CURLcode result;
   CURLcode result;
@@ -159,7 +157,7 @@ CURLcode Curl_urldecode(struct Curl_easy *data,
     return CURLE_OUT_OF_MEMORY;
     return CURLE_OUT_OF_MEMORY;
 
 
   while(--alloc > 0) {
   while(--alloc > 0) {
-    in = *string;
+    unsigned char in = *string;
     if(('%' == in) && (alloc > 2) &&
     if(('%' == in) && (alloc > 2) &&
        ISXDIGIT(string[1]) && ISXDIGIT(string[2])) {
        ISXDIGIT(string[1]) && ISXDIGIT(string[2])) {
       /* this is two hexadecimal digits following a '%' */
       /* this is two hexadecimal digits following a '%' */

+ 6 - 6
lib/file.c

@@ -256,8 +256,6 @@ static CURLcode file_upload(struct connectdata *conn)
   CURLcode result = CURLE_OK;
   CURLcode result = CURLE_OK;
   struct Curl_easy *data = conn->data;
   struct Curl_easy *data = conn->data;
   char *buf = data->state.buffer;
   char *buf = data->state.buffer;
-  size_t nread;
-  size_t nwrite;
   curl_off_t bytecount = 0;
   curl_off_t bytecount = 0;
   struct_stat file_stat;
   struct_stat file_stat;
   const char *buf2;
   const char *buf2;
@@ -306,7 +304,9 @@ static CURLcode file_upload(struct connectdata *conn)
   }
   }
 
 
   while(!result) {
   while(!result) {
-    int readcount;
+    size_t nread;
+    size_t nwrite;
+    size_t readcount;
     result = Curl_fillreadbuffer(conn, (int)data->set.buffer_size, &readcount);
     result = Curl_fillreadbuffer(conn, (int)data->set.buffer_size, &readcount);
     if(result)
     if(result)
       break;
       break;
@@ -314,7 +314,7 @@ static CURLcode file_upload(struct connectdata *conn)
     if(readcount <= 0)  /* fix questionable compare error. curlvms */
     if(readcount <= 0)  /* fix questionable compare error. curlvms */
       break;
       break;
 
 
-    nread = (size_t)readcount;
+    nread = readcount;
 
 
     /*skip bytes before resume point*/
     /*skip bytes before resume point*/
     if(data->state.resume_from) {
     if(data->state.resume_from) {
@@ -378,7 +378,6 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
   curl_off_t expected_size = 0;
   curl_off_t expected_size = 0;
   bool size_known;
   bool size_known;
   bool fstated = FALSE;
   bool fstated = FALSE;
-  ssize_t nread;
   struct Curl_easy *data = conn->data;
   struct Curl_easy *data = conn->data;
   char *buf = data->state.buffer;
   char *buf = data->state.buffer;
   curl_off_t bytecount = 0;
   curl_off_t bytecount = 0;
@@ -461,7 +460,7 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
     return result;
     return result;
 
 
   /* Adjust the start offset in case we want to get the N last bytes
   /* Adjust the start offset in case we want to get the N last bytes
-   * of the stream iff the filesize could be determined */
+   * of the stream if the filesize could be determined */
   if(data->state.resume_from < 0) {
   if(data->state.resume_from < 0) {
     if(!fstated) {
     if(!fstated) {
       failf(data, "Can't get the size of file.");
       failf(data, "Can't get the size of file.");
@@ -502,6 +501,7 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
   Curl_pgrsTime(data, TIMER_STARTTRANSFER);
   Curl_pgrsTime(data, TIMER_STARTTRANSFER);
 
 
   while(!result) {
   while(!result) {
+    ssize_t nread;
     /* Don't fill a whole buffer if we want less than all data */
     /* Don't fill a whole buffer if we want less than all data */
     size_t bytestoread;
     size_t bytestoread;
 
 

+ 7 - 9
lib/formdata.c

@@ -39,16 +39,13 @@
 #include "sendf.h"
 #include "sendf.h"
 #include "strdup.h"
 #include "strdup.h"
 #include "rand.h"
 #include "rand.h"
+#include "warnless.h"
 /* The last 3 #include files should be in this order */
 /* The last 3 #include files should be in this order */
 #include "curl_printf.h"
 #include "curl_printf.h"
 #include "curl_memory.h"
 #include "curl_memory.h"
 #include "memdebug.h"
 #include "memdebug.h"
 
 
 
 
-/* What kind of Content-Type to use on un-specified files with unrecognized
-   extensions. */
-#define HTTPPOST_CONTENTTYPE_DEFAULT "application/octet-stream"
-
 #define HTTPPOST_PTRNAME CURL_HTTPPOST_PTRNAME
 #define HTTPPOST_PTRNAME CURL_HTTPPOST_PTRNAME
 #define HTTPPOST_FILENAME CURL_HTTPPOST_FILENAME
 #define HTTPPOST_FILENAME CURL_HTTPPOST_FILENAME
 #define HTTPPOST_PTRCONTENTS CURL_HTTPPOST_PTRCONTENTS
 #define HTTPPOST_PTRCONTENTS CURL_HTTPPOST_PTRCONTENTS
@@ -305,7 +302,8 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
        * Set the contents property.
        * Set the contents property.
        */
        */
     case CURLFORM_PTRCONTENTS:
     case CURLFORM_PTRCONTENTS:
-      current_form->flags |= HTTPPOST_PTRCONTENTS; /* fall through */
+      current_form->flags |= HTTPPOST_PTRCONTENTS;
+      /* FALLTHROUGH */
     case CURLFORM_COPYCONTENTS:
     case CURLFORM_COPYCONTENTS:
       if(current_form->value)
       if(current_form->value)
         return_value = CURL_FORMADD_OPTION_TWICE;
         return_value = CURL_FORMADD_OPTION_TWICE;
@@ -725,7 +723,7 @@ int curl_formget(struct curl_httppost *form, void *arg,
 
 
   while(!result) {
   while(!result) {
     char buffer[8192];
     char buffer[8192];
-    size_t nread = Curl_mime_read(buffer, 1, sizeof buffer, &toppart);
+    size_t nread = Curl_mime_read(buffer, 1, sizeof(buffer), &toppart);
 
 
     if(!nread)
     if(!nread)
       break;
       break;
@@ -812,7 +810,6 @@ CURLcode Curl_getformdata(struct Curl_easy *data,
 {
 {
   CURLcode result = CURLE_OK;
   CURLcode result = CURLE_OK;
   curl_mime *form = NULL;
   curl_mime *form = NULL;
-  curl_mime *multipart;
   curl_mimepart *part;
   curl_mimepart *part;
   struct curl_httppost *file;
   struct curl_httppost *file;
 
 
@@ -831,7 +828,7 @@ CURLcode Curl_getformdata(struct Curl_easy *data,
   /* Process each top part. */
   /* Process each top part. */
   for(; !result && post; post = post->next) {
   for(; !result && post; post = post->next) {
     /* If we have more than a file here, create a mime subpart and fill it. */
     /* If we have more than a file here, create a mime subpart and fill it. */
-    multipart = form;
+    curl_mime *multipart = form;
     if(post->more) {
     if(post->more) {
       part = curl_mime_addpart(form);
       part = curl_mime_addpart(form);
       if(!part)
       if(!part)
@@ -883,7 +880,8 @@ CURLcode Curl_getformdata(struct Curl_easy *data,
                compatibility: use of "-" pseudo file name should be avoided. */
                compatibility: use of "-" pseudo file name should be avoided. */
             result = curl_mime_data_cb(part, (curl_off_t) -1,
             result = curl_mime_data_cb(part, (curl_off_t) -1,
                                        (curl_read_callback) fread,
                                        (curl_read_callback) fread,
-                                       (curl_seek_callback) fseek,
+                                       CURLX_FUNCTION_CAST(curl_seek_callback,
+                                                           fseek),
                                        NULL, (void *) stdin);
                                        NULL, (void *) stdin);
           }
           }
           else
           else

+ 7 - 9
lib/ftp.c

@@ -239,8 +239,8 @@ static void close_secondarysocket(struct connectdata *conn)
 
 
 static void freedirs(struct ftp_conn *ftpc)
 static void freedirs(struct ftp_conn *ftpc)
 {
 {
-  int i;
   if(ftpc->dirs) {
   if(ftpc->dirs) {
+    int i;
     for(i = 0; i < ftpc->dirdepth; i++) {
     for(i = 0; i < ftpc->dirdepth; i++) {
       free(ftpc->dirs[i]);
       free(ftpc->dirs[i]);
       ftpc->dirs[i] = NULL;
       ftpc->dirs[i] = NULL;
@@ -637,8 +637,6 @@ CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */
    * line in a response or continue reading.  */
    * line in a response or continue reading.  */
 
 
   curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
   curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
-  time_t timeout;              /* timeout in milliseconds */
-  time_t interval_ms;
   struct Curl_easy *data = conn->data;
   struct Curl_easy *data = conn->data;
   CURLcode result = CURLE_OK;
   CURLcode result = CURLE_OK;
   struct ftp_conn *ftpc = &conn->proto.ftpc;
   struct ftp_conn *ftpc = &conn->proto.ftpc;
@@ -657,7 +655,8 @@ CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */
 
 
   while(!*ftpcode && !result) {
   while(!*ftpcode && !result) {
     /* check and reset timeout value every lap */
     /* check and reset timeout value every lap */
-    timeout = Curl_pp_state_timeout(pp);
+    time_t timeout = Curl_pp_state_timeout(pp); /* timeout in milliseconds */
+    time_t interval_ms;
 
 
     if(timeout <= 0) {
     if(timeout <= 0) {
       failf(data, "FTP response timeout");
       failf(data, "FTP response timeout");
@@ -1589,7 +1588,6 @@ static CURLcode ftp_state_ul_setup(struct connectdata *conn,
   struct FTP *ftp = conn->data->req.protop;
   struct FTP *ftp = conn->data->req.protop;
   struct Curl_easy *data = conn->data;
   struct Curl_easy *data = conn->data;
   struct ftp_conn *ftpc = &conn->proto.ftpc;
   struct ftp_conn *ftpc = &conn->proto.ftpc;
-  int seekerr = CURL_SEEKFUNC_OK;
 
 
   if((data->state.resume_from && !sizechecked) ||
   if((data->state.resume_from && !sizechecked) ||
      ((data->state.resume_from > 0) && sizechecked)) {
      ((data->state.resume_from > 0) && sizechecked)) {
@@ -1605,6 +1603,7 @@ static CURLcode ftp_state_ul_setup(struct connectdata *conn,
     /* 3. pass file-size number of bytes in the source file */
     /* 3. pass file-size number of bytes in the source file */
     /* 4. lower the infilesize counter */
     /* 4. lower the infilesize counter */
     /* => transfer as usual */
     /* => transfer as usual */
+    int seekerr = CURL_SEEKFUNC_OK;
 
 
     if(data->state.resume_from < 0) {
     if(data->state.resume_from < 0) {
       /* Got no given size to start from, figure it out */
       /* Got no given size to start from, figure it out */
@@ -2782,7 +2781,6 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
         char *ptr = &data->state.buffer[4];  /* start on the first letter */
         char *ptr = &data->state.buffer[4];  /* start on the first letter */
         const size_t buf_size = data->set.buffer_size;
         const size_t buf_size = data->set.buffer_size;
         char *dir;
         char *dir;
-        char *store;
         bool entry_extracted = FALSE;
         bool entry_extracted = FALSE;
 
 
         dir = malloc(nread + 1);
         dir = malloc(nread + 1);
@@ -2805,6 +2803,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
 
 
         if('\"' == *ptr) {
         if('\"' == *ptr) {
           /* it started good */
           /* it started good */
+          char *store;
           ptr++;
           ptr++;
           for(store = dir; *ptr;) {
           for(store = dir; *ptr;) {
             if('\"' == *ptr) {
             if('\"' == *ptr) {
@@ -3992,8 +3991,7 @@ CURLcode Curl_ftpsend(struct connectdata *conn, const char *cmd)
       break;
       break;
 
 
     if(conn->data->set.verbose)
     if(conn->data->set.verbose)
-      Curl_debug(conn->data, CURLINFO_HEADER_OUT,
-                 sptr, (size_t)bytes_written, conn);
+      Curl_debug(conn->data, CURLINFO_HEADER_OUT, sptr, (size_t)bytes_written);
 
 
     if(bytes_written != (ssize_t)write_len) {
     if(bytes_written != (ssize_t)write_len) {
       write_len -= bytes_written;
       write_len -= bytes_written;
@@ -4384,7 +4382,6 @@ static CURLcode ftp_setup_connection(struct connectdata *conn)
 {
 {
   struct Curl_easy *data = conn->data;
   struct Curl_easy *data = conn->data;
   char *type;
   char *type;
-  char command;
   struct FTP *ftp;
   struct FTP *ftp;
 
 
   conn->data->req.protop = ftp = malloc(sizeof(struct FTP));
   conn->data->req.protop = ftp = malloc(sizeof(struct FTP));
@@ -4402,6 +4399,7 @@ static CURLcode ftp_setup_connection(struct connectdata *conn)
     type = strstr(conn->host.rawalloc, ";type=");
     type = strstr(conn->host.rawalloc, ";type=");
 
 
   if(type) {
   if(type) {
+    char command;
     *type = 0;                     /* it was in the middle of the hostname */
     *type = 0;                     /* it was in the middle of the hostname */
     command = Curl_raw_toupper(type[6]);
     command = Curl_raw_toupper(type[6]);
     conn->bits.type_set = TRUE;
     conn->bits.type_set = TRUE;

+ 22 - 0
lib/getinfo.c

@@ -281,6 +281,28 @@ static CURLcode getinfo_offt(struct Curl_easy *data, CURLINFO info,
     *param_offt = (data->progress.flags & PGRS_UL_SIZE_KNOWN)?
     *param_offt = (data->progress.flags & PGRS_UL_SIZE_KNOWN)?
       data->progress.size_ul:-1;
       data->progress.size_ul:-1;
     break;
     break;
+  case CURLINFO_TOTAL_TIME_T:
+    *param_offt = data->progress.timespent;
+    break;
+  case CURLINFO_NAMELOOKUP_TIME_T:
+    *param_offt = data->progress.t_nslookup;
+    break;
+  case CURLINFO_CONNECT_TIME_T:
+    *param_offt = data->progress.t_connect;
+    break;
+  case CURLINFO_APPCONNECT_TIME_T:
+    *param_offt = data->progress.t_appconnect;
+    break;
+  case CURLINFO_PRETRANSFER_TIME_T:
+    *param_offt = data->progress.t_pretransfer;
+    break;
+  case CURLINFO_STARTTRANSFER_TIME_T:
+    *param_offt = data->progress.t_starttransfer;
+    break;
+  case CURLINFO_REDIRECT_TIME_T:
+    *param_offt = data->progress.t_redirect;
+    break;
+
   default:
   default:
     return CURLE_UNKNOWN_OPTION;
     return CURLE_UNKNOWN_OPTION;
   }
   }

+ 2 - 9
lib/gopher.c

@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *                             \___|\___/|_| \_\_____|
  *
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <[email protected]>, et al.
+ * Copyright (C) 1998 - 2018, Daniel Stenberg, <[email protected]>, et al.
  *
  *
  * This software is licensed as described in the file COPYING, which
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * you should have received as part of this distribution. The terms
@@ -89,22 +89,15 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
   /* Create selector. Degenerate cases: / and /1 => convert to "" */
   /* Create selector. Degenerate cases: / and /1 => convert to "" */
   if(strlen(path) <= 2) {
   if(strlen(path) <= 2) {
     sel = (char *)"";
     sel = (char *)"";
-    len = (int)strlen(sel);
+    len = strlen(sel);
   }
   }
   else {
   else {
     char *newp;
     char *newp;
-    size_t j, i;
 
 
     /* Otherwise, drop / and the first character (i.e., item type) ... */
     /* Otherwise, drop / and the first character (i.e., item type) ... */
     newp = path;
     newp = path;
     newp += 2;
     newp += 2;
 
 
-    /* ... then turn ? into TAB for search servers, Veronica, etc. ... */
-    j = strlen(newp);
-    for(i = 0; i<j; i++)
-      if(newp[i] == '?')
-        newp[i] = '\x09';
-
     /* ... and finally unescape */
     /* ... and finally unescape */
     result = Curl_urldecode(data, newp, 0, &sel, &len, FALSE);
     result = Curl_urldecode(data, newp, 0, &sel, &len, FALSE);
     if(result)
     if(result)

+ 4 - 7
lib/hash.c

@@ -60,8 +60,6 @@ Curl_hash_init(struct curl_hash *h,
                comp_function comparator,
                comp_function comparator,
                curl_hash_dtor dtor)
                curl_hash_dtor dtor)
 {
 {
-  int i;
-
   if(!slots || !hfunc || !comparator ||!dtor) {
   if(!slots || !hfunc || !comparator ||!dtor) {
     return 1; /* failure */
     return 1; /* failure */
   }
   }
@@ -74,6 +72,7 @@ Curl_hash_init(struct curl_hash *h,
 
 
   h->table = malloc(slots * sizeof(struct curl_llist));
   h->table = malloc(slots * sizeof(struct curl_llist));
   if(h->table) {
   if(h->table) {
+    int i;
     for(i = 0; i < slots; ++i)
     for(i = 0; i < slots; ++i)
       Curl_llist_init(&h->table[i], (curl_llist_dtor) hash_element_dtor);
       Curl_llist_init(&h->table[i], (curl_llist_dtor) hash_element_dtor);
     return 0; /* fine */
     return 0; /* fine */
@@ -140,11 +139,10 @@ Curl_hash_add(struct curl_hash *h, void *key, size_t key_len, void *p)
 int Curl_hash_delete(struct curl_hash *h, void *key, size_t key_len)
 int Curl_hash_delete(struct curl_hash *h, void *key, size_t key_len)
 {
 {
   struct curl_llist_element *le;
   struct curl_llist_element *le;
-  struct curl_hash_element  *he;
   struct curl_llist *l = FETCH_LIST(h, key, key_len);
   struct curl_llist *l = FETCH_LIST(h, key, key_len);
 
 
   for(le = l->head; le; le = le->next) {
   for(le = l->head; le; le = le->next) {
-    he = le->ptr;
+    struct curl_hash_element *he = le->ptr;
     if(h->comp_func(he->key, he->key_len, key, key_len)) {
     if(h->comp_func(he->key, he->key_len, key, key_len)) {
       Curl_llist_remove(l, le, (void *) h);
       Curl_llist_remove(l, le, (void *) h);
       --h->size;
       --h->size;
@@ -162,13 +160,12 @@ void *
 Curl_hash_pick(struct curl_hash *h, void *key, size_t key_len)
 Curl_hash_pick(struct curl_hash *h, void *key, size_t key_len)
 {
 {
   struct curl_llist_element *le;
   struct curl_llist_element *le;
-  struct curl_hash_element  *he;
   struct curl_llist *l;
   struct curl_llist *l;
 
 
   if(h) {
   if(h) {
     l = FETCH_LIST(h, key, key_len);
     l = FETCH_LIST(h, key, key_len);
     for(le = l->head; le; le = le->next) {
     for(le = l->head; le; le = le->next) {
-      he = le->ptr;
+      struct curl_hash_element *he = le->ptr;
       if(h->comp_func(he->key, he->key_len, key, key_len)) {
       if(h->comp_func(he->key, he->key_len, key, key_len)) {
         return he->ptr;
         return he->ptr;
       }
       }
@@ -291,7 +288,6 @@ void Curl_hash_start_iterate(struct curl_hash *hash,
 struct curl_hash_element *
 struct curl_hash_element *
 Curl_hash_next_element(struct curl_hash_iterator *iter)
 Curl_hash_next_element(struct curl_hash_iterator *iter)
 {
 {
-  int i;
   struct curl_hash *h = iter->hash;
   struct curl_hash *h = iter->hash;
 
 
   /* Get the next element in the current list, if any */
   /* Get the next element in the current list, if any */
@@ -300,6 +296,7 @@ Curl_hash_next_element(struct curl_hash_iterator *iter)
 
 
   /* If we have reached the end of the list, find the next one */
   /* If we have reached the end of the list, find the next one */
   if(!iter->current_element) {
   if(!iter->current_element) {
+    int i;
     for(i = iter->slot_index; i < h->slots; i++) {
     for(i = iter->slot_index; i < h->slots; i++) {
       if(h->table[i].head) {
       if(h->table[i].head) {
         iter->current_element = h->table[i].head;
         iter->current_element = h->table[i].head;

+ 2 - 2
lib/hmac.c

@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *                             \___|\___/|_| \_\_____|
  *
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <[email protected]>, et al.
+ * Copyright (C) 1998 - 2018, Daniel Stenberg, <[email protected]>, et al.
  *
  *
  * This software is licensed as described in the file COPYING, which
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * you should have received as part of this distribution. The terms
@@ -58,7 +58,7 @@ Curl_HMAC_init(const HMAC_params * hashparams,
   unsigned char b;
   unsigned char b;
 
 
   /* Create HMAC context. */
   /* Create HMAC context. */
-  i = sizeof *ctxt + 2 * hashparams->hmac_ctxtsize +
+  i = sizeof(*ctxt) + 2 * hashparams->hmac_ctxtsize +
     hashparams->hmac_resultlen;
     hashparams->hmac_resultlen;
   ctxt = malloc(i);
   ctxt = malloc(i);
 
 

+ 2 - 2
lib/hostasyn.c

@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *                             \___|\___/|_| \_\_____|
  *
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <[email protected]>, et al.
+ * Copyright (C) 1998 - 2018, Daniel Stenberg, <[email protected]>, et al.
  *
  *
  * This software is licensed as described in the file COPYING, which
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * you should have received as part of this distribution. The terms
@@ -131,7 +131,7 @@ CURLcode Curl_async_resolved(struct connectdata *conn,
   if(result)
   if(result)
     /* We're not allowed to return failure with memory left allocated
     /* We're not allowed to return failure with memory left allocated
        in the connectdata struct, free those here */
        in the connectdata struct, free those here */
-    Curl_disconnect(conn, FALSE); /* close the connection */
+    Curl_disconnect(conn->data, conn, TRUE); /* close the connection */
 
 
   return result;
   return result;
 }
 }

+ 23 - 15
lib/hostip.c

@@ -907,7 +907,9 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
       char *entry_id;
       char *entry_id;
       size_t entry_len;
       size_t entry_len;
       char address[64];
       char address[64];
+#if !defined(CURL_DISABLE_VERBOSE_STRINGS)
       char *addresses = NULL;
       char *addresses = NULL;
+#endif
       char *addr_begin;
       char *addr_begin;
       char *addr_end;
       char *addr_end;
       char *port_ptr;
       char *port_ptr;
@@ -930,7 +932,9 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
         goto err;
         goto err;
 
 
       port = (int)tmp_port;
       port = (int)tmp_port;
+#if !defined(CURL_DISABLE_VERBOSE_STRINGS)
       addresses = end_ptr + 1;
       addresses = end_ptr + 1;
+#endif
 
 
       while(*end_ptr) {
       while(*end_ptr) {
         size_t alen;
         size_t alen;
@@ -1010,24 +1014,28 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
       /* See if its already in our dns cache */
       /* See if its already in our dns cache */
       dns = Curl_hash_pick(data->dns.hostcache, entry_id, entry_len + 1);
       dns = Curl_hash_pick(data->dns.hostcache, entry_id, entry_len + 1);
 
 
+      if(dns) {
+        infof(data, "RESOLVE %s:%d is - old addresses discarded!\n",
+                hostname, port);
+        /* delete old entry entry, there are two reasons for this
+         1. old entry may have different addresses.
+         2. even if entry with correct addresses is already in the cache,
+            but if it is close to expire, then by the time next http
+            request is made, it can get expired and pruned because old
+            entry is not necessarily marked as added by CURLOPT_RESOLVE. */
+
+        Curl_hash_delete(data->dns.hostcache, entry_id, entry_len + 1);
+      }
       /* free the allocated entry_id again */
       /* free the allocated entry_id again */
       free(entry_id);
       free(entry_id);
 
 
-      if(!dns) {
-        /* if not in the cache already, put this host in the cache */
-        dns = Curl_cache_addr(data, head, hostname, port);
-        if(dns) {
-          dns->timestamp = 0; /* mark as added by CURLOPT_RESOLVE */
-          /* release the returned reference; the cache itself will keep the
-           * entry alive: */
-          dns->inuse--;
-        }
-      }
-      else {
-        /* this is a duplicate, free it again */
-        infof(data, "RESOLVE %s:%d is already cached, %s not stored!\n",
-              hostname, port, addresses);
-        Curl_freeaddrinfo(head);
+      /* put this new host in the cache */
+      dns = Curl_cache_addr(data, head, hostname, port);
+      if(dns) {
+        dns->timestamp = 0; /* mark as added by CURLOPT_RESOLVE */
+        /* release the returned reference; the cache itself will keep the
+         * entry alive: */
+            dns->inuse--;
       }
       }
 
 
       if(data->share)
       if(data->share)

+ 1 - 34
lib/hostip6.c

@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *                             \___|\___/|_| \_\_____|
  *
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <[email protected]>, et al.
+ * Copyright (C) 1998 - 2018, Daniel Stenberg, <[email protected]>, et al.
  *
  *
  * This software is licensed as described in the file COPYING, which
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * you should have received as part of this distribution. The terms
@@ -59,39 +59,6 @@
 #include "curl_memory.h"
 #include "curl_memory.h"
 #include "memdebug.h"
 #include "memdebug.h"
 
 
-#if defined(CURLDEBUG) && defined(HAVE_GETNAMEINFO)
-/* These are strictly for memory tracing and are using the same style as the
- * family otherwise present in memdebug.c. I put these ones here since they
- * require a bunch of structs I didn't want to include in memdebug.c
- */
-
-/*
- * For CURLRES_ARS, this should be written using ares_gethostbyaddr()
- * (ignoring the fact c-ares doesn't return 'serv').
- */
-
-int curl_dogetnameinfo(GETNAMEINFO_QUAL_ARG1 GETNAMEINFO_TYPE_ARG1 sa,
-                       GETNAMEINFO_TYPE_ARG2 salen,
-                       char *host, GETNAMEINFO_TYPE_ARG46 hostlen,
-                       char *serv, GETNAMEINFO_TYPE_ARG46 servlen,
-                       GETNAMEINFO_TYPE_ARG7 flags,
-                       int line, const char *source)
-{
-  int res = (getnameinfo)(sa, salen,
-                          host, hostlen,
-                          serv, servlen,
-                          flags);
-  if(0 == res)
-    /* success */
-    curl_memlog("GETNAME %s:%d getnameinfo()\n",
-                source, line);
-  else
-    curl_memlog("GETNAME %s:%d getnameinfo() failed = %d\n",
-                source, line, res);
-  return res;
-}
-#endif /* defined(CURLDEBUG) && defined(HAVE_GETNAMEINFO) */
-
 /*
 /*
  * Curl_ipv6works() returns TRUE if IPv6 seems to work.
  * Curl_ipv6works() returns TRUE if IPv6 seems to work.
  */
  */

+ 156 - 70
lib/http.c

@@ -158,18 +158,20 @@ CURLcode Curl_http_setup_conn(struct connectdata *conn)
   /* allocate the HTTP-specific struct for the Curl_easy, only to survive
   /* allocate the HTTP-specific struct for the Curl_easy, only to survive
      during this request */
      during this request */
   struct HTTP *http;
   struct HTTP *http;
-  DEBUGASSERT(conn->data->req.protop == NULL);
+  struct Curl_easy *data = conn->data;
+  DEBUGASSERT(data->req.protop == NULL);
 
 
   http = calloc(1, sizeof(struct HTTP));
   http = calloc(1, sizeof(struct HTTP));
   if(!http)
   if(!http)
     return CURLE_OUT_OF_MEMORY;
     return CURLE_OUT_OF_MEMORY;
 
 
   Curl_mime_initpart(&http->form, conn->data);
   Curl_mime_initpart(&http->form, conn->data);
-  conn->data->req.protop = http;
-
-  Curl_http2_setup_conn(conn);
-  Curl_http2_setup_req(conn->data);
+  data->req.protop = http;
 
 
+  if(!CONN_INUSE(conn))
+    /* if not alredy multi-using, setup connection details */
+    Curl_http2_setup_conn(conn);
+  Curl_http2_setup_req(data);
   return CURLE_OK;
   return CURLE_OK;
 }
 }
 
 
@@ -310,22 +312,49 @@ static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
   return result;
   return result;
 }
 }
 
 
+/*
+ * http_output_bearer() sets up an Authorization: header
+ * for HTTP Bearer authentication.
+ *
+ * Returns CURLcode.
+ */
+static CURLcode http_output_bearer(struct connectdata *conn)
+{
+  char **userp;
+  CURLcode result = CURLE_OK;
+
+  userp = &conn->allocptr.userpwd;
+  free(*userp);
+  *userp = aprintf("Authorization: Bearer %s\r\n",
+                   conn->oauth_bearer);
+
+  if(!*userp) {
+    result = CURLE_OUT_OF_MEMORY;
+    goto fail;
+  }
+
+  fail:
+  return result;
+}
+
 /* pickoneauth() selects the most favourable authentication method from the
 /* pickoneauth() selects the most favourable authentication method from the
  * ones available and the ones we want.
  * ones available and the ones we want.
  *
  *
  * return TRUE if one was picked
  * return TRUE if one was picked
  */
  */
-static bool pickoneauth(struct auth *pick)
+static bool pickoneauth(struct auth *pick, unsigned long mask)
 {
 {
   bool picked;
   bool picked;
   /* only deal with authentication we want */
   /* only deal with authentication we want */
-  unsigned long avail = pick->avail & pick->want;
+  unsigned long avail = pick->avail & pick->want & mask;
   picked = TRUE;
   picked = TRUE;
 
 
   /* The order of these checks is highly relevant, as this will be the order
   /* The order of these checks is highly relevant, as this will be the order
      of preference in case of the existence of multiple accepted types. */
      of preference in case of the existence of multiple accepted types. */
   if(avail & CURLAUTH_NEGOTIATE)
   if(avail & CURLAUTH_NEGOTIATE)
     pick->picked = CURLAUTH_NEGOTIATE;
     pick->picked = CURLAUTH_NEGOTIATE;
+  else if(avail & CURLAUTH_BEARER)
+    pick->picked = CURLAUTH_BEARER;
   else if(avail & CURLAUTH_DIGEST)
   else if(avail & CURLAUTH_DIGEST)
     pick->picked = CURLAUTH_DIGEST;
     pick->picked = CURLAUTH_DIGEST;
   else if(avail & CURLAUTH_NTLM)
   else if(avail & CURLAUTH_NTLM)
@@ -479,6 +508,10 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
   bool pickhost = FALSE;
   bool pickhost = FALSE;
   bool pickproxy = FALSE;
   bool pickproxy = FALSE;
   CURLcode result = CURLE_OK;
   CURLcode result = CURLE_OK;
+  unsigned long authmask = ~0ul;
+
+  if(!conn->oauth_bearer)
+    authmask &= (unsigned long)~CURLAUTH_BEARER;
 
 
   if(100 <= data->req.httpcode && 199 >= data->req.httpcode)
   if(100 <= data->req.httpcode && 199 >= data->req.httpcode)
     /* this is a transient response code, ignore */
     /* this is a transient response code, ignore */
@@ -487,17 +520,18 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
   if(data->state.authproblem)
   if(data->state.authproblem)
     return data->set.http_fail_on_error?CURLE_HTTP_RETURNED_ERROR:CURLE_OK;
     return data->set.http_fail_on_error?CURLE_HTTP_RETURNED_ERROR:CURLE_OK;
 
 
-  if(conn->bits.user_passwd &&
+  if((conn->bits.user_passwd || conn->oauth_bearer) &&
      ((data->req.httpcode == 401) ||
      ((data->req.httpcode == 401) ||
       (conn->bits.authneg && data->req.httpcode < 300))) {
       (conn->bits.authneg && data->req.httpcode < 300))) {
-    pickhost = pickoneauth(&data->state.authhost);
+    pickhost = pickoneauth(&data->state.authhost, authmask);
     if(!pickhost)
     if(!pickhost)
       data->state.authproblem = TRUE;
       data->state.authproblem = TRUE;
   }
   }
   if(conn->bits.proxy_user_passwd &&
   if(conn->bits.proxy_user_passwd &&
      ((data->req.httpcode == 407) ||
      ((data->req.httpcode == 407) ||
       (conn->bits.authneg && data->req.httpcode < 300))) {
       (conn->bits.authneg && data->req.httpcode < 300))) {
-    pickproxy = pickoneauth(&data->state.authproxy);
+    pickproxy = pickoneauth(&data->state.authproxy,
+                            authmask & ~CURLAUTH_BEARER);
     if(!pickproxy)
     if(!pickproxy)
       data->state.authproblem = TRUE;
       data->state.authproblem = TRUE;
   }
   }
@@ -628,6 +662,20 @@ output_auth_headers(struct connectdata *conn,
        functions work that way */
        functions work that way */
     authstatus->done = TRUE;
     authstatus->done = TRUE;
   }
   }
+  if(authstatus->picked == CURLAUTH_BEARER) {
+    /* Bearer */
+    if((!proxy && conn->oauth_bearer &&
+        !Curl_checkheaders(conn, "Authorization:"))) {
+      auth = "Bearer";
+      result = http_output_bearer(conn);
+      if(result)
+        return result;
+    }
+
+    /* NOTE: this function should set 'done' TRUE, as the other auth
+       functions work that way */
+    authstatus->done = TRUE;
+  }
 
 
   if(auth) {
   if(auth) {
     infof(data, "%s auth using %s with user '%s'\n",
     infof(data, "%s auth using %s with user '%s'\n",
@@ -674,7 +722,7 @@ Curl_http_output_auth(struct connectdata *conn,
   authproxy = &data->state.authproxy;
   authproxy = &data->state.authproxy;
 
 
   if((conn->bits.httpproxy && conn->bits.proxy_user_passwd) ||
   if((conn->bits.httpproxy && conn->bits.proxy_user_passwd) ||
-     conn->bits.user_passwd)
+     conn->bits.user_passwd || conn->oauth_bearer)
     /* continue please */;
     /* continue please */;
   else {
   else {
     authhost->done = TRUE;
     authhost->done = TRUE;
@@ -883,6 +931,18 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
               data->state.authproblem = TRUE;
               data->state.authproblem = TRUE;
             }
             }
           }
           }
+          else
+            if(checkprefix("Bearer", auth)) {
+              *availp |= CURLAUTH_BEARER;
+              authp->avail |= CURLAUTH_BEARER;
+              if(authp->picked == CURLAUTH_BEARER) {
+                /* We asked for Bearer authentication but got a 40X back
+                  anyway, which basically means our token isn't valid. */
+                authp->avail = CURLAUTH_NONE;
+                infof(data, "Authentication problem. Ignoring this.\n");
+                data->state.authproblem = TRUE;
+              }
+            }
 
 
     /* there may be multiple methods on one line, so keep reading */
     /* there may be multiple methods on one line, so keep reading */
     while(*auth && *auth != ',') /* read up to the next comma */
     while(*auth && *auth != ',') /* read up to the next comma */
@@ -1063,7 +1123,8 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
   CURLcode result;
   CURLcode result;
   char *ptr;
   char *ptr;
   size_t size;
   size_t size;
-  struct HTTP *http = conn->data->req.protop;
+  struct Curl_easy *data = conn->data;
+  struct HTTP *http = data->req.protop;
   size_t sendsize;
   size_t sendsize;
   curl_socket_t sockfd;
   curl_socket_t sockfd;
   size_t headersize;
   size_t headersize;
@@ -1083,7 +1144,7 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
 
 
   DEBUGASSERT(size > included_body_bytes);
   DEBUGASSERT(size > included_body_bytes);
 
 
-  result = Curl_convert_to_network(conn->data, ptr, headersize);
+  result = Curl_convert_to_network(data, ptr, headersize);
   /* Curl_convert_to_network calls failf if unsuccessful */
   /* Curl_convert_to_network calls failf if unsuccessful */
   if(result) {
   if(result) {
     /* conversion failed, free memory and return to the caller */
     /* conversion failed, free memory and return to the caller */
@@ -1108,8 +1169,14 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
        must copy the data to the uploadbuffer first, since that is the buffer
        must copy the data to the uploadbuffer first, since that is the buffer
        we will be using if this send is retried later.
        we will be using if this send is retried later.
     */
     */
-    memcpy(conn->data->state.uploadbuffer, ptr, sendsize);
-    ptr = conn->data->state.uploadbuffer;
+    result = Curl_get_upload_buffer(data);
+    if(result) {
+      /* malloc failed, free memory and return to the caller */
+      Curl_add_buffer_free(in);
+      return result;
+    }
+    memcpy(data->state.ulbuf, ptr, sendsize);
+    ptr = data->state.ulbuf;
   }
   }
   else
   else
     sendsize = size;
     sendsize = size;
@@ -1126,14 +1193,14 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
     size_t headlen = (size_t)amount>headersize ? headersize : (size_t)amount;
     size_t headlen = (size_t)amount>headersize ? headersize : (size_t)amount;
     size_t bodylen = amount - headlen;
     size_t bodylen = amount - headlen;
 
 
-    if(conn->data->set.verbose) {
+    if(data->set.verbose) {
       /* this data _may_ contain binary stuff */
       /* this data _may_ contain binary stuff */
-      Curl_debug(conn->data, CURLINFO_HEADER_OUT, ptr, headlen, conn);
+      Curl_debug(data, CURLINFO_HEADER_OUT, ptr, headlen);
       if(bodylen) {
       if(bodylen) {
         /* there was body data sent beyond the initial header part, pass that
         /* there was body data sent beyond the initial header part, pass that
            on to the debug callback too */
            on to the debug callback too */
-        Curl_debug(conn->data, CURLINFO_DATA_OUT,
-                   ptr + headlen, bodylen, conn);
+        Curl_debug(data, CURLINFO_DATA_OUT,
+                   ptr + headlen, bodylen);
       }
       }
     }
     }
 
 
@@ -1157,14 +1224,14 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
         ptr = in->buffer + amount;
         ptr = in->buffer + amount;
 
 
         /* backup the currently set pointers */
         /* backup the currently set pointers */
-        http->backup.fread_func = conn->data->state.fread_func;
-        http->backup.fread_in = conn->data->state.in;
+        http->backup.fread_func = data->state.fread_func;
+        http->backup.fread_in = data->state.in;
         http->backup.postdata = http->postdata;
         http->backup.postdata = http->postdata;
         http->backup.postsize = http->postsize;
         http->backup.postsize = http->postsize;
 
 
         /* set the new pointers for the request-sending */
         /* set the new pointers for the request-sending */
-        conn->data->state.fread_func = (curl_read_callback)readmoredata;
-        conn->data->state.in = (void *)conn;
+        data->state.fread_func = (curl_read_callback)readmoredata;
+        data->state.in = (void *)conn;
         http->postdata = ptr;
         http->postdata = ptr;
         http->postsize = (curl_off_t)size;
         http->postsize = (curl_off_t)size;
 
 
@@ -1223,7 +1290,6 @@ CURLcode Curl_add_bufferf(Curl_send_buffer *in, const char *fmt, ...)
 CURLcode Curl_add_buffer(Curl_send_buffer *in, const void *inptr, size_t size)
 CURLcode Curl_add_buffer(Curl_send_buffer *in, const void *inptr, size_t size)
 {
 {
   char *new_rb;
   char *new_rb;
-  size_t new_size;
 
 
   if(~size < in->size_used) {
   if(~size < in->size_used) {
     /* If resulting used size of send buffer would wrap size_t, cleanup
     /* If resulting used size of send buffer would wrap size_t, cleanup
@@ -1236,10 +1302,10 @@ CURLcode Curl_add_buffer(Curl_send_buffer *in, const void *inptr, size_t size)
 
 
   if(!in->buffer ||
   if(!in->buffer ||
      ((in->size_used + size) > (in->size_max - 1))) {
      ((in->size_used + size) > (in->size_max - 1))) {
-
     /* If current buffer size isn't enough to hold the result, use a
     /* If current buffer size isn't enough to hold the result, use a
        buffer size that doubles the required size. If this new size
        buffer size that doubles the required size. If this new size
        would wrap size_t, then just use the largest possible one */
        would wrap size_t, then just use the largest possible one */
+    size_t new_size;
 
 
     if((size > (size_t)-1 / 2) || (in->size_used > (size_t)-1 / 2) ||
     if((size > (size_t)-1 / 2) || (in->size_used > (size_t)-1 / 2) ||
        (~(size * 2) < (in->size_used * 2)))
        (~(size * 2) < (in->size_used * 2)))
@@ -1406,7 +1472,7 @@ static CURLcode add_haproxy_protocol_header(struct connectdata *conn)
   }
   }
 
 
   snprintf(proxy_header,
   snprintf(proxy_header,
-           sizeof proxy_header,
+           sizeof(proxy_header),
            "PROXY %s %s %s %li %li\r\n",
            "PROXY %s %s %s %li %li\r\n",
            tcp_version,
            tcp_version,
            conn->data->info.conn_local_ip,
            conn->data->info.conn_local_ip,
@@ -1574,7 +1640,6 @@ static CURLcode expect100(struct Curl_easy *data,
                           Curl_send_buffer *req_buffer)
                           Curl_send_buffer *req_buffer)
 {
 {
   CURLcode result = CURLE_OK;
   CURLcode result = CURLE_OK;
-  const char *ptr;
   data->state.expect100header = FALSE; /* default to false unless it is set
   data->state.expect100header = FALSE; /* default to false unless it is set
                                           to TRUE below */
                                           to TRUE below */
   if(use_http_1_1plus(data, conn) &&
   if(use_http_1_1plus(data, conn) &&
@@ -1582,7 +1647,7 @@ static CURLcode expect100(struct Curl_easy *data,
     /* if not doing HTTP 1.0 or version 2, or disabled explicitly, we add an
     /* if not doing HTTP 1.0 or version 2, or disabled explicitly, we add an
        Expect: 100-continue to the headers which actually speeds up post
        Expect: 100-continue to the headers which actually speeds up post
        operations (as there is one packet coming back from the web server) */
        operations (as there is one packet coming back from the web server) */
-    ptr = Curl_checkheaders(conn, "Expect");
+    const char *ptr = Curl_checkheaders(conn, "Expect");
     if(ptr) {
     if(ptr) {
       data->state.expect100header =
       data->state.expect100header =
         Curl_compareheader(ptr, "Expect:", "100-continue");
         Curl_compareheader(ptr, "Expect:", "100-continue");
@@ -1819,7 +1884,6 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
   const char *httpstring;
   const char *httpstring;
   Curl_send_buffer *req_buffer;
   Curl_send_buffer *req_buffer;
   curl_off_t postsize = 0; /* curl_off_t to handle large file sizes */
   curl_off_t postsize = 0; /* curl_off_t to handle large file sizes */
-  int seekerr = CURL_SEEKFUNC_CANTSEEK;
 
 
   /* Always consider the DO phase done after this function call, even if there
   /* Always consider the DO phase done after this function call, even if there
      may be parts of the request that is not yet sent, since we can deal with
      may be parts of the request that is not yet sent, since we can deal with
@@ -1863,6 +1927,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
   }
   }
 
 
   http = data->req.protop;
   http = data->req.protop;
+  DEBUGASSERT(http);
 
 
   if(!data->state.this_is_a_follow) {
   if(!data->state.this_is_a_follow) {
     /* Free to avoid leaking memory on multiple requests*/
     /* Free to avoid leaking memory on multiple requests*/
@@ -2088,7 +2153,6 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
     else {
     else {
       /* If the host begins with '[', we start searching for the port after
       /* If the host begins with '[', we start searching for the port after
          the bracket has been closed */
          the bracket has been closed */
-      int startsearch = 0;
       if(*cookiehost == '[') {
       if(*cookiehost == '[') {
         char *closingbracket;
         char *closingbracket;
         /* since the 'cookiehost' is an allocated memory area that will be
         /* since the 'cookiehost' is an allocated memory area that will be
@@ -2099,6 +2163,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
           *closingbracket = 0;
           *closingbracket = 0;
       }
       }
       else {
       else {
+        int startsearch = 0;
         char *colon = strchr(cookiehost + startsearch, ':');
         char *colon = strchr(cookiehost + startsearch, ':');
         if(colon)
         if(colon)
           *colon = 0; /* The host must not include an embedded port number */
           *colon = 0; /* The host must not include an embedded port number */
@@ -2244,6 +2309,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
 
 
       /* Now, let's read off the proper amount of bytes from the
       /* Now, let's read off the proper amount of bytes from the
          input. */
          input. */
+      int seekerr = CURL_SEEKFUNC_CANTSEEK;
       if(conn->seek_func) {
       if(conn->seek_func) {
         Curl_set_in_callback(data, true);
         Curl_set_in_callback(data, true);
         seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
         seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
@@ -2828,6 +2894,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
       data->req.exp100 = EXP100_SEND_DATA; /* already sent */
       data->req.exp100 = EXP100_SEND_DATA; /* already sent */
       Curl_expire_done(data, EXPIRE_100_TIMEOUT);
       Curl_expire_done(data, EXPIRE_100_TIMEOUT);
     }
     }
+    else
+      data->req.writebytecount = http->writebytecount;
   }
   }
 
 
   if((conn->httpversion == 20) && data->req.upload_chunky)
   if((conn->httpversion == 20) && data->req.upload_chunky)
@@ -2838,17 +2906,32 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
   return result;
   return result;
 }
 }
 
 
+typedef enum {
+  STATUS_UNKNOWN, /* not enough data to tell yet */
+  STATUS_DONE, /* a status line was read */
+  STATUS_BAD /* not a status line */
+} statusline;
+
+
+/* Check a string for a prefix. Check no more than 'len' bytes */
+static bool checkprefixmax(const char *prefix, const char *buffer, size_t len)
+{
+  size_t ch = CURLMIN(strlen(prefix), len);
+  return curl_strnequal(prefix, buffer, ch);
+}
+
 /*
 /*
  * checkhttpprefix()
  * checkhttpprefix()
  *
  *
  * Returns TRUE if member of the list matches prefix of string
  * Returns TRUE if member of the list matches prefix of string
  */
  */
-static bool
+static statusline
 checkhttpprefix(struct Curl_easy *data,
 checkhttpprefix(struct Curl_easy *data,
-                const char *s)
+                const char *s, size_t len)
 {
 {
   struct curl_slist *head = data->set.http200aliases;
   struct curl_slist *head = data->set.http200aliases;
-  bool rc = FALSE;
+  statusline rc = STATUS_BAD;
+  statusline onmatch = len >= 5? STATUS_DONE : STATUS_UNKNOWN;
 #ifdef CURL_DOES_CONVERSIONS
 #ifdef CURL_DOES_CONVERSIONS
   /* convert from the network encoding using a scratch area */
   /* convert from the network encoding using a scratch area */
   char *scratch = strdup(s);
   char *scratch = strdup(s);
@@ -2865,15 +2948,15 @@ checkhttpprefix(struct Curl_easy *data,
 #endif /* CURL_DOES_CONVERSIONS */
 #endif /* CURL_DOES_CONVERSIONS */
 
 
   while(head) {
   while(head) {
-    if(checkprefix(head->data, s)) {
-      rc = TRUE;
+    if(checkprefixmax(head->data, s, len)) {
+      rc = onmatch;
       break;
       break;
     }
     }
     head = head->next;
     head = head->next;
   }
   }
 
 
-  if(!rc && (checkprefix("HTTP/", s)))
-    rc = TRUE;
+  if((rc != STATUS_DONE) && (checkprefixmax("HTTP/", s, len)))
+    rc = onmatch;
 
 
 #ifdef CURL_DOES_CONVERSIONS
 #ifdef CURL_DOES_CONVERSIONS
   free(scratch);
   free(scratch);
@@ -2882,11 +2965,12 @@ checkhttpprefix(struct Curl_easy *data,
 }
 }
 
 
 #ifndef CURL_DISABLE_RTSP
 #ifndef CURL_DISABLE_RTSP
-static bool
+static statusline
 checkrtspprefix(struct Curl_easy *data,
 checkrtspprefix(struct Curl_easy *data,
-                const char *s)
+                const char *s, size_t len)
 {
 {
-  bool result = FALSE;
+  statusline result = STATUS_BAD;
+  statusline onmatch = len >= 5? STATUS_DONE : STATUS_UNKNOWN;
 
 
 #ifdef CURL_DOES_CONVERSIONS
 #ifdef CURL_DOES_CONVERSIONS
   /* convert from the network encoding using a scratch area */
   /* convert from the network encoding using a scratch area */
@@ -2899,30 +2983,31 @@ checkrtspprefix(struct Curl_easy *data,
     /* Curl_convert_from_network calls failf if unsuccessful */
     /* Curl_convert_from_network calls failf if unsuccessful */
     result = FALSE; /* can't return CURLE_foobar so return FALSE */
     result = FALSE; /* can't return CURLE_foobar so return FALSE */
   }
   }
-  else
-    result = checkprefix("RTSP/", scratch)? TRUE: FALSE;
+  else if(checkprefixmax("RTSP/", scratch, len))
+    result = onmatch;
   free(scratch);
   free(scratch);
 #else
 #else
   (void)data; /* unused */
   (void)data; /* unused */
-  result = checkprefix("RTSP/", s)? TRUE: FALSE;
+  if(checkprefixmax("RTSP/", s, len))
+    result = onmatch;
 #endif /* CURL_DOES_CONVERSIONS */
 #endif /* CURL_DOES_CONVERSIONS */
 
 
   return result;
   return result;
 }
 }
 #endif /* CURL_DISABLE_RTSP */
 #endif /* CURL_DISABLE_RTSP */
 
 
-static bool
+static statusline
 checkprotoprefix(struct Curl_easy *data, struct connectdata *conn,
 checkprotoprefix(struct Curl_easy *data, struct connectdata *conn,
-                 const char *s)
+                 const char *s, size_t len)
 {
 {
 #ifndef CURL_DISABLE_RTSP
 #ifndef CURL_DISABLE_RTSP
   if(conn->handler->protocol & CURLPROTO_RTSP)
   if(conn->handler->protocol & CURLPROTO_RTSP)
-    return checkrtspprefix(data, s);
+    return checkrtspprefix(data, s, len);
 #else
 #else
   (void)conn;
   (void)conn;
 #endif /* CURL_DISABLE_RTSP */
 #endif /* CURL_DISABLE_RTSP */
 
 
-  return checkhttpprefix(data, s);
+  return checkhttpprefix(data, s, len);
 }
 }
 
 
 /*
 /*
@@ -2939,7 +3024,7 @@ static CURLcode header_append(struct Curl_easy *data,
     /* The reason to have a max limit for this is to avoid the risk of a bad
     /* The 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
        server feeding libcurl with a never-ending header that will cause
        reallocs infinitely */
        reallocs infinitely */
-    failf(data, "Rejected %zd bytes header (max is %d)!", newsize,
+    failf(data, "Rejected %zu bytes header (max is %d)!", newsize,
           CURL_MAX_HTTP_HEADER);
           CURL_MAX_HTTP_HEADER);
     return CURLE_OUT_OF_MEMORY;
     return CURLE_OUT_OF_MEMORY;
   }
   }
@@ -3036,12 +3121,15 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
       if(result)
       if(result)
         return result;
         return result;
 
 
-      if(!k->headerline && (k->hbuflen>5)) {
-        /* make a first check that this looks like a protocol header */
-        if(!checkprotoprefix(data, conn, data->state.headerbuff)) {
+      if(!k->headerline) {
+        /* check if this looks like a protocol header */
+        statusline st = checkprotoprefix(data, conn, data->state.headerbuff,
+                                         k->hbuflen);
+        if(st == STATUS_BAD) {
           /* this is not the beginning of a protocol first header line */
           /* this is not the beginning of a protocol first header line */
           k->header = FALSE;
           k->header = FALSE;
           k->badheader = HEADER_ALLBAD;
           k->badheader = HEADER_ALLBAD;
+          streamclose(conn, "bad HTTP: No end-of-message indicator");
           break;
           break;
         }
         }
       }
       }
@@ -3070,8 +3158,10 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
 
 
     if(!k->headerline) {
     if(!k->headerline) {
       /* the first read header */
       /* the first read header */
-      if((k->hbuflen>5) &&
-         !checkprotoprefix(data, conn, data->state.headerbuff)) {
+      statusline st = checkprotoprefix(data, conn, data->state.headerbuff,
+                                       k->hbuflen);
+      if(st == STATUS_BAD) {
+        streamclose(conn, "bad HTTP: No end-of-message indicator");
         /* this is not the beginning of a protocol first header line */
         /* this is not the beginning of a protocol first header line */
         k->header = FALSE;
         k->header = FALSE;
         if(*nread)
         if(*nread)
@@ -3354,7 +3444,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
 
 
         if(data->set.verbose)
         if(data->set.verbose)
           Curl_debug(data, CURLINFO_HEADER_IN,
           Curl_debug(data, CURLINFO_HEADER_IN,
-                     k->str_start, headerlen, conn);
+                     k->str_start, headerlen);
         break;          /* exit header line loop */
         break;          /* exit header line loop */
       }
       }
 
 
@@ -3440,7 +3530,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
              compare header line against list of aliases
              compare header line against list of aliases
           */
           */
           if(!nc) {
           if(!nc) {
-            if(checkhttpprefix(data, k->p)) {
+            if(checkhttpprefix(data, k->p, k->hbuflen) == STATUS_DONE) {
               nc = 1;
               nc = 1;
               k->httpcode = 200;
               k->httpcode = 200;
               conn->httpversion = 10;
               conn->httpversion = 10;
@@ -3487,21 +3577,18 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
          * depending on how authentication is working.  Other codes
          * depending on how authentication is working.  Other codes
          * are definitely errors, so give up here.
          * are definitely errors, so give up here.
          */
          */
-        if(data->set.http_fail_on_error && (k->httpcode >= 400) &&
+        if(data->state.resume_from && data->set.httpreq == HTTPREQ_GET &&
+             k->httpcode == 416) {
+          /* "Requested Range Not Satisfiable", just proceed and
+             pretend this is no error */
+          k->ignorebody = TRUE; /* Avoid appending error msg to good data. */
+        }
+        else if(data->set.http_fail_on_error && (k->httpcode >= 400) &&
            ((k->httpcode != 401) || !conn->bits.user_passwd) &&
            ((k->httpcode != 401) || !conn->bits.user_passwd) &&
            ((k->httpcode != 407) || !conn->bits.proxy_user_passwd) ) {
            ((k->httpcode != 407) || !conn->bits.proxy_user_passwd) ) {
-
-          if(data->state.resume_from &&
-             (data->set.httpreq == HTTPREQ_GET) &&
-             (k->httpcode == 416)) {
-            /* "Requested Range Not Satisfiable", just proceed and
-               pretend this is no error */
-          }
-          else {
-            /* serious error, go home! */
-            print_http_error(data);
-            return CURLE_HTTP_RETURNED_ERROR;
-          }
+          /* serious error, go home! */
+          print_http_error(data);
+          return CURLE_HTTP_RETURNED_ERROR;
         }
         }
 
 
         if(conn->httpversion == 10) {
         if(conn->httpversion == 10) {
@@ -3812,8 +3899,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
       writetype |= CLIENTWRITE_BODY;
       writetype |= CLIENTWRITE_BODY;
 
 
     if(data->set.verbose)
     if(data->set.verbose)
-      Curl_debug(data, CURLINFO_HEADER_IN,
-                 k->p, (size_t)k->hbuflen, conn);
+      Curl_debug(data, CURLINFO_HEADER_IN, k->p, (size_t)k->hbuflen);
 
 
     result = Curl_client_write(conn, writetype, k->p, k->hbuflen);
     result = Curl_client_write(conn, writetype, k->p, k->hbuflen);
     if(result)
     if(result)

+ 95 - 116
lib/http2.c

@@ -42,7 +42,6 @@
 #include "memdebug.h"
 #include "memdebug.h"
 
 
 #define H2_BUFSIZE 32768
 #define H2_BUFSIZE 32768
-#define MIN(x,y) ((x)<(y)?(x):(y))
 
 
 #if (NGHTTP2_VERSION_NUM < 0x010000)
 #if (NGHTTP2_VERSION_NUM < 0x010000)
 #error too old nghttp2 version, upgrade!
 #error too old nghttp2 version, upgrade!
@@ -154,6 +153,11 @@ static void http2_stream_free(struct HTTP *http)
   }
   }
 }
 }
 
 
+/*
+ * Disconnects *a* connection used for HTTP/2. It might be an old one from the
+ * connection cache and not the "main" one. Don't touch the easy handle!
+ */
+
 static CURLcode http2_disconnect(struct connectdata *conn,
 static CURLcode http2_disconnect(struct connectdata *conn,
                                  bool dead_connection)
                                  bool dead_connection)
 {
 {
@@ -164,8 +168,6 @@ static CURLcode http2_disconnect(struct connectdata *conn,
 
 
   nghttp2_session_del(c->h2);
   nghttp2_session_del(c->h2);
   Curl_safefree(c->inbuf);
   Curl_safefree(c->inbuf);
-  http2_stream_free(conn->data->req.protop);
-  conn->data->state.drain = 0;
 
 
   H2BUGF(infof(conn->data, "HTTP/2 DISCONNECT done\n"));
   H2BUGF(infof(conn->data, "HTTP/2 DISCONNECT done\n"));
 
 
@@ -345,7 +347,7 @@ const char *Curl_http2_strerror(uint32_t err)
     "INADEQUATE_SECURITY",  /* 0xC */
     "INADEQUATE_SECURITY",  /* 0xC */
     "HTTP_1_1_REQUIRED"     /* 0xD */
     "HTTP_1_1_REQUIRED"     /* 0xD */
   };
   };
-  return (err < sizeof str / sizeof str[0]) ? str[err] : "unknown";
+  return (err < sizeof(str) / sizeof(str[0])) ? str[err] : "unknown";
 #else
 #else
   return nghttp2_http2_strerror(err);
   return nghttp2_http2_strerror(err);
 #endif
 #endif
@@ -368,6 +370,10 @@ static ssize_t send_callback(nghttp2_session *h2,
   (void)h2;
   (void)h2;
   (void)flags;
   (void)flags;
 
 
+  if(!c->send_underlying)
+    /* called before setup properly! */
+    return NGHTTP2_ERR_CALLBACK_FAILURE;
+
   written = ((Curl_send*)c->send_underlying)(conn, FIRSTSOCKET,
   written = ((Curl_send*)c->send_underlying)(conn, FIRSTSOCKET,
                                              data, length, &result);
                                              data, length, &result);
 
 
@@ -441,6 +447,28 @@ char *curl_pushheader_byname(struct curl_pushheaders *h, const char *header)
   return NULL;
   return NULL;
 }
 }
 
 
+/*
+ * This specific transfer on this connection has been "drained".
+ */
+static void drained_transfer(struct Curl_easy *data,
+                             struct http_conn *httpc)
+{
+  DEBUGASSERT(httpc->drain_total >= data->state.drain);
+  httpc->drain_total -= data->state.drain;
+  data->state.drain = 0;
+}
+
+/*
+ * Mark this transfer to get "drained".
+ */
+static void drain_this(struct Curl_easy *data,
+                       struct http_conn *httpc)
+{
+  data->state.drain++;
+  httpc->drain_total++;
+  DEBUGASSERT(httpc->drain_total >= data->state.drain);
+}
+
 static struct Curl_easy *duphandle(struct Curl_easy *data)
 static struct Curl_easy *duphandle(struct Curl_easy *data)
 {
 {
   struct Curl_easy *second = curl_easy_duphandle(data);
   struct Curl_easy *second = curl_easy_duphandle(data);
@@ -520,6 +548,7 @@ static int push_promise(struct Curl_easy *data,
     if(rv) {
     if(rv) {
       /* denied, kill off the new handle again */
       /* denied, kill off the new handle again */
       http2_stream_free(newhandle->req.protop);
       http2_stream_free(newhandle->req.protop);
+      newhandle->req.protop = NULL;
       (void)Curl_close(newhandle);
       (void)Curl_close(newhandle);
       goto fail;
       goto fail;
     }
     }
@@ -535,14 +564,22 @@ static int push_promise(struct Curl_easy *data,
     if(rc) {
     if(rc) {
       infof(data, "failed to add handle to multi\n");
       infof(data, "failed to add handle to multi\n");
       http2_stream_free(newhandle->req.protop);
       http2_stream_free(newhandle->req.protop);
+      newhandle->req.protop = NULL;
       Curl_close(newhandle);
       Curl_close(newhandle);
       rv = 1;
       rv = 1;
       goto fail;
       goto fail;
     }
     }
 
 
     httpc = &conn->proto.httpc;
     httpc = &conn->proto.httpc;
-    nghttp2_session_set_stream_user_data(httpc->h2,
-                                         frame->promised_stream_id, newhandle);
+    rv = nghttp2_session_set_stream_user_data(httpc->h2,
+                                              frame->promised_stream_id,
+                                              newhandle);
+    if(rv) {
+      infof(data, "failed to set user_data for stream %d\n",
+            frame->promised_stream_id);
+      DEBUGASSERT(0);
+      goto fail;
+    }
   }
   }
   else {
   else {
     H2BUGF(infof(data, "Got PUSH_PROMISE, ignore it!\n"));
     H2BUGF(infof(data, "Got PUSH_PROMISE, ignore it!\n"));
@@ -581,7 +618,7 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
       if(max_conn != httpc->settings.max_concurrent_streams) {
       if(max_conn != httpc->settings.max_concurrent_streams) {
         /* only signal change if the value actually changed */
         /* only signal change if the value actually changed */
         infof(conn->data,
         infof(conn->data,
-              "Connection state changed (MAX_CONCURRENT_STREAMS == %d)!\n",
+              "Connection state changed (MAX_CONCURRENT_STREAMS == %u)!\n",
               httpc->settings.max_concurrent_streams);
               httpc->settings.max_concurrent_streams);
         Curl_multi_connchanged(conn->data->multi);
         Curl_multi_connchanged(conn->data->multi);
       }
       }
@@ -640,7 +677,7 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
     Curl_add_buffer(stream->header_recvbuf, "\r\n", 2);
     Curl_add_buffer(stream->header_recvbuf, "\r\n", 2);
 
 
     left = stream->header_recvbuf->size_used - stream->nread_header_recvbuf;
     left = stream->header_recvbuf->size_used - stream->nread_header_recvbuf;
-    ncopy = MIN(stream->len, left);
+    ncopy = CURLMIN(stream->len, left);
 
 
     memcpy(&stream->mem[stream->memlen],
     memcpy(&stream->mem[stream->memlen],
            stream->header_recvbuf->buffer + stream->nread_header_recvbuf,
            stream->header_recvbuf->buffer + stream->nread_header_recvbuf,
@@ -653,8 +690,7 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
     stream->len -= ncopy;
     stream->len -= ncopy;
     stream->memlen += ncopy;
     stream->memlen += ncopy;
 
 
-    data_s->state.drain++;
-    httpc->drain_total++;
+    drain_this(data_s, httpc);
     {
     {
       /* get the pointer from userp again since it was re-assigned above */
       /* get the pointer from userp again since it was re-assigned above */
       struct connectdata *conn_s = (struct connectdata *)userp;
       struct connectdata *conn_s = (struct connectdata *)userp;
@@ -683,25 +719,6 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
   return 0;
   return 0;
 }
 }
 
 
-static int on_invalid_frame_recv(nghttp2_session *session,
-                                 const nghttp2_frame *frame,
-                                 int lib_error_code, void *userp)
-{
-  struct Curl_easy *data_s = NULL;
-  (void)userp;
-#if !defined(DEBUG_HTTP2) || 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) {
-    H2BUGF(infof(data_s,
-                 "on_invalid_frame_recv() was called, error=%d:%s\n",
-                 lib_error_code, nghttp2_strerror(lib_error_code)));
-  }
-  return 0;
-}
-
 static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
 static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
                               int32_t stream_id,
                               int32_t stream_id,
                               const uint8_t *data, size_t len, void *userp)
                               const uint8_t *data, size_t len, void *userp)
@@ -727,14 +744,13 @@ static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
   if(!stream)
   if(!stream)
     return NGHTTP2_ERR_CALLBACK_FAILURE;
     return NGHTTP2_ERR_CALLBACK_FAILURE;
 
 
-  nread = MIN(stream->len, len);
+  nread = CURLMIN(stream->len, len);
   memcpy(&stream->mem[stream->memlen], data, nread);
   memcpy(&stream->mem[stream->memlen], data, nread);
 
 
   stream->len -= nread;
   stream->len -= nread;
   stream->memlen += nread;
   stream->memlen += nread;
 
 
-  data_s->state.drain++;
-  conn->proto.httpc.drain_total++;
+  drain_this(data_s, &conn->proto.httpc);
 
 
   /* if we receive data for another handle, wake that up */
   /* if we receive data for another handle, wake that up */
   if(conn->data != data_s)
   if(conn->data != data_s)
@@ -768,58 +784,13 @@ static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
   return 0;
   return 0;
 }
 }
 
 
-static int before_frame_send(nghttp2_session *session,
-                             const nghttp2_frame *frame,
-                             void *userp)
-{
-  struct Curl_easy *data_s;
-  (void)userp;
-
-  data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id);
-  if(data_s) {
-    H2BUGF(infof(data_s, "before_frame_send() was called\n"));
-  }
-
-  return 0;
-}
-static int on_frame_send(nghttp2_session *session,
-                         const nghttp2_frame *frame,
-                         void *userp)
-{
-  struct Curl_easy *data_s;
-  (void)userp;
-
-  data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id);
-  if(data_s) {
-    H2BUGF(infof(data_s, "on_frame_send() was called, length = %zd\n",
-                 frame->hd.length));
-  }
-  return 0;
-}
-static int on_frame_not_send(nghttp2_session *session,
-                             const nghttp2_frame *frame,
-                             int lib_error_code, void *userp)
-{
-  struct Curl_easy *data_s;
-  (void)userp;
-#if !defined(DEBUG_HTTP2) || 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) {
-    H2BUGF(infof(data_s,
-                 "on_frame_not_send() was called, lib_error_code = %d\n",
-                 lib_error_code));
-  }
-  return 0;
-}
 static int on_stream_close(nghttp2_session *session, int32_t stream_id,
 static int on_stream_close(nghttp2_session *session, int32_t stream_id,
                            uint32_t error_code, void *userp)
                            uint32_t error_code, void *userp)
 {
 {
   struct Curl_easy *data_s;
   struct Curl_easy *data_s;
   struct HTTP *stream;
   struct HTTP *stream;
   struct connectdata *conn = (struct connectdata *)userp;
   struct connectdata *conn = (struct connectdata *)userp;
+  int rv;
   (void)session;
   (void)session;
   (void)stream_id;
   (void)stream_id;
 
 
@@ -840,14 +811,19 @@ static int on_stream_close(nghttp2_session *session, int32_t stream_id,
       return NGHTTP2_ERR_CALLBACK_FAILURE;
       return NGHTTP2_ERR_CALLBACK_FAILURE;
 
 
     stream->closed = TRUE;
     stream->closed = TRUE;
-    data_s->state.drain++;
     httpc = &conn->proto.httpc;
     httpc = &conn->proto.httpc;
-    httpc->drain_total++;
+    drain_this(data_s, httpc);
     httpc->error_code = error_code;
     httpc->error_code = error_code;
 
 
     /* remove the entry from the hash as the stream is now gone */
     /* remove the entry from the hash as the stream is now gone */
-    nghttp2_session_set_stream_user_data(session, stream_id, 0);
+    rv = nghttp2_session_set_stream_user_data(session, stream_id, 0);
+    if(rv) {
+      infof(data_s, "http/2: failed to clear user_data for stream %d!\n",
+            stream_id);
+      DEBUGASSERT(0);
+    }
     H2BUGF(infof(data_s, "Removed stream %u hash!\n", stream_id));
     H2BUGF(infof(data_s, "Removed stream %u hash!\n", stream_id));
+    stream->stream_id = 0; /* cleared */
   }
   }
   return 0;
   return 0;
 }
 }
@@ -1052,7 +1028,7 @@ static ssize_t data_source_read_callback(nghttp2_session *session,
   else
   else
     return NGHTTP2_ERR_INVALID_ARGUMENT;
     return NGHTTP2_ERR_INVALID_ARGUMENT;
 
 
-  nread = MIN(stream->upload_len, length);
+  nread = CURLMIN(stream->upload_len, length);
   if(nread > 0) {
   if(nread > 0) {
     memcpy(buf, stream->upload_mem, nread);
     memcpy(buf, stream->upload_mem, nread);
     stream->upload_mem += nread;
     stream->upload_mem += nread;
@@ -1109,6 +1085,12 @@ void Curl_http2_done(struct connectdata *conn, bool premature)
   struct HTTP *http = data->req.protop;
   struct HTTP *http = data->req.protop;
   struct http_conn *httpc = &conn->proto.httpc;
   struct http_conn *httpc = &conn->proto.httpc;
 
 
+  if(!httpc->h2) /* not HTTP/2 ? */
+    return;
+
+  if(data->state.drain)
+    drained_transfer(data, httpc);
+
   if(http->header_recvbuf) {
   if(http->header_recvbuf) {
     Curl_add_buffer_free(http->header_recvbuf);
     Curl_add_buffer_free(http->header_recvbuf);
     http->header_recvbuf = NULL; /* clear the pointer */
     http->header_recvbuf = NULL; /* clear the pointer */
@@ -1126,15 +1108,24 @@ void Curl_http2_done(struct connectdata *conn, bool premature)
 
 
   if(premature) {
   if(premature) {
     /* RST_STREAM */
     /* RST_STREAM */
-    nghttp2_submit_rst_stream(httpc->h2, NGHTTP2_FLAG_NONE, http->stream_id,
-                              NGHTTP2_STREAM_CLOSED);
+    if(!nghttp2_submit_rst_stream(httpc->h2, NGHTTP2_FLAG_NONE,
+                                  http->stream_id, NGHTTP2_STREAM_CLOSED))
+      (void)nghttp2_session_send(httpc->h2);
+
     if(http->stream_id == httpc->pause_stream_id) {
     if(http->stream_id == httpc->pause_stream_id) {
       infof(data, "stopped the pause stream!\n");
       infof(data, "stopped the pause stream!\n");
       httpc->pause_stream_id = 0;
       httpc->pause_stream_id = 0;
     }
     }
   }
   }
-  if(http->stream_id) {
-    nghttp2_session_set_stream_user_data(httpc->h2, http->stream_id, 0);
+  /* -1 means unassigned and 0 means cleared */
+  if(http->stream_id > 0) {
+    int rv = nghttp2_session_set_stream_user_data(httpc->h2,
+                                                  http->stream_id, 0);
+    if(rv) {
+      infof(data, "http/2: failed to clear user_data for stream %d!\n",
+            http->stream_id);
+      DEBUGASSERT(0);
+    }
     http->stream_id = 0;
     http->stream_id = 0;
   }
   }
 }
 }
@@ -1164,21 +1155,9 @@ CURLcode Curl_http2_init(struct connectdata *conn)
     /* nghttp2_on_frame_recv_callback */
     /* nghttp2_on_frame_recv_callback */
     nghttp2_session_callbacks_set_on_frame_recv_callback
     nghttp2_session_callbacks_set_on_frame_recv_callback
       (callbacks, on_frame_recv);
       (callbacks, on_frame_recv);
-    /* nghttp2_on_invalid_frame_recv_callback */
-    nghttp2_session_callbacks_set_on_invalid_frame_recv_callback
-      (callbacks, on_invalid_frame_recv);
     /* nghttp2_on_data_chunk_recv_callback */
     /* nghttp2_on_data_chunk_recv_callback */
     nghttp2_session_callbacks_set_on_data_chunk_recv_callback
     nghttp2_session_callbacks_set_on_data_chunk_recv_callback
       (callbacks, on_data_chunk_recv);
       (callbacks, on_data_chunk_recv);
-    /* nghttp2_before_frame_send_callback */
-    nghttp2_session_callbacks_set_before_frame_send_callback
-      (callbacks, before_frame_send);
-    /* nghttp2_on_frame_send_callback */
-    nghttp2_session_callbacks_set_on_frame_send_callback
-      (callbacks, on_frame_send);
-    /* nghttp2_on_frame_not_send_callback */
-    nghttp2_session_callbacks_set_on_frame_not_send_callback
-      (callbacks, on_frame_not_send);
     /* nghttp2_on_stream_close_callback */
     /* nghttp2_on_stream_close_callback */
     nghttp2_session_callbacks_set_on_stream_close_callback
     nghttp2_session_callbacks_set_on_stream_close_callback
       (callbacks, on_stream_close);
       (callbacks, on_stream_close);
@@ -1280,7 +1259,7 @@ static int h2_process_pending_input(struct connectdata *conn,
   if(rv < 0) {
   if(rv < 0) {
     failf(data,
     failf(data,
           "h2_process_pending_input: nghttp2_session_mem_recv() returned "
           "h2_process_pending_input: nghttp2_session_mem_recv() returned "
-          "%d:%s\n", rv, nghttp2_strerror((int)rv));
+          "%zd:%s\n", rv, nghttp2_strerror((int)rv));
     *err = CURLE_RECV_ERROR;
     *err = CURLE_RECV_ERROR;
     return -1;
     return -1;
   }
   }
@@ -1352,7 +1331,6 @@ CURLcode Curl_http2_done_sending(struct connectdata *conn)
   return result;
   return result;
 }
 }
 
 
-
 static ssize_t http2_handle_stream_close(struct connectdata *conn,
 static ssize_t http2_handle_stream_close(struct connectdata *conn,
                                          struct Curl_easy *data,
                                          struct Curl_easy *data,
                                          struct HTTP *stream, CURLcode *err)
                                          struct HTTP *stream, CURLcode *err)
@@ -1365,9 +1343,7 @@ static ssize_t http2_handle_stream_close(struct connectdata *conn,
     httpc->pause_stream_id = 0;
     httpc->pause_stream_id = 0;
   }
   }
 
 
-  DEBUGASSERT(httpc->drain_total >= data->state.drain);
-  httpc->drain_total -= data->state.drain;
-  data->state.drain = 0;
+  drained_transfer(data, httpc);
 
 
   if(httpc->pause_stream_id == 0) {
   if(httpc->pause_stream_id == 0) {
     if(h2_process_pending_input(conn, httpc, err) != 0) {
     if(h2_process_pending_input(conn, httpc, err) != 0) {
@@ -1388,7 +1364,7 @@ static ssize_t http2_handle_stream_close(struct connectdata *conn,
     return -1;
     return -1;
   }
   }
   else if(httpc->error_code != NGHTTP2_NO_ERROR) {
   else if(httpc->error_code != NGHTTP2_NO_ERROR) {
-    failf(data, "HTTP/2 stream %u was not closed cleanly: %s (err %d)",
+    failf(data, "HTTP/2 stream %d was not closed cleanly: %s (err %u)",
           stream->stream_id, Curl_http2_strerror(httpc->error_code),
           stream->stream_id, Curl_http2_strerror(httpc->error_code),
           httpc->error_code);
           httpc->error_code);
     *err = CURLE_HTTP2_STREAM;
     *err = CURLE_HTTP2_STREAM;
@@ -1396,7 +1372,7 @@ static ssize_t http2_handle_stream_close(struct connectdata *conn,
   }
   }
 
 
   if(!stream->bodystarted) {
   if(!stream->bodystarted) {
-    failf(data, "HTTP/2 stream %u was closed cleanly, but before getting "
+    failf(data, "HTTP/2 stream %d was closed cleanly, but before getting "
           " all response header fields, treated as error",
           " all response header fields, treated as error",
           stream->stream_id);
           stream->stream_id);
     *err = CURLE_HTTP2_STREAM;
     *err = CURLE_HTTP2_STREAM;
@@ -1510,7 +1486,7 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
     /* If there is body data pending for this stream to return, do that */
     /* If there is body data pending for this stream to return, do that */
     size_t left =
     size_t left =
       stream->header_recvbuf->size_used - stream->nread_header_recvbuf;
       stream->header_recvbuf->size_used - stream->nread_header_recvbuf;
-    size_t ncopy = MIN(len, left);
+    size_t ncopy = CURLMIN(len, left);
     memcpy(mem, stream->header_recvbuf->buffer + stream->nread_header_recvbuf,
     memcpy(mem, stream->header_recvbuf->buffer + stream->nread_header_recvbuf,
            ncopy);
            ncopy);
     stream->nread_header_recvbuf += ncopy;
     stream->nread_header_recvbuf += ncopy;
@@ -1546,13 +1522,13 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
   }
   }
   else if(stream->pausedata) {
   else if(stream->pausedata) {
     DEBUGASSERT(httpc->pause_stream_id == stream->stream_id);
     DEBUGASSERT(httpc->pause_stream_id == stream->stream_id);
-    nread = MIN(len, stream->pauselen);
+    nread = CURLMIN(len, stream->pauselen);
     memcpy(mem, stream->pausedata, nread);
     memcpy(mem, stream->pausedata, nread);
 
 
     stream->pausedata += nread;
     stream->pausedata += nread;
     stream->pauselen -= nread;
     stream->pauselen -= nread;
 
 
-    infof(data, "%zu data bytes written\n", nread);
+    infof(data, "%zd data bytes written\n", nread);
     if(stream->pauselen == 0) {
     if(stream->pauselen == 0) {
       H2BUGF(infof(data, "Unpaused by stream %u\n", stream->stream_id));
       H2BUGF(infof(data, "Unpaused by stream %u\n", stream->stream_id));
       DEBUGASSERT(httpc->pause_stream_id == stream->stream_id);
       DEBUGASSERT(httpc->pause_stream_id == stream->stream_id);
@@ -1635,7 +1611,7 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
     rv = nghttp2_session_mem_recv(httpc->h2, (const uint8_t *)inbuf, nread);
     rv = nghttp2_session_mem_recv(httpc->h2, (const uint8_t *)inbuf, nread);
 
 
     if(nghttp2_is_fatal((int)rv)) {
     if(nghttp2_is_fatal((int)rv)) {
-      failf(data, "nghttp2_session_mem_recv() returned %d:%s\n",
+      failf(data, "nghttp2_session_mem_recv() returned %zd:%s\n",
             rv, nghttp2_strerror((int)rv));
             rv, nghttp2_strerror((int)rv));
       *err = CURLE_RECV_ERROR;
       *err = CURLE_RECV_ERROR;
       return -1;
       return -1;
@@ -1678,9 +1654,7 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
                    stream->stream_id));
                    stream->stream_id));
     }
     }
     else if(!stream->closed) {
     else if(!stream->closed) {
-      DEBUGASSERT(httpc->drain_total >= data->state.drain);
-      httpc->drain_total -= data->state.drain;
-      data->state.drain = 0; /* this stream is hereby drained */
+      drained_transfer(data, httpc);
     }
     }
 
 
     return retlen;
     return retlen;
@@ -2040,7 +2014,7 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
   }
   }
 
 
   infof(conn->data, "Using Stream ID: %x (easy handle %p)\n",
   infof(conn->data, "Using Stream ID: %x (easy handle %p)\n",
-        stream_id, conn->data);
+        stream_id, (void *)conn->data);
   stream->stream_id = stream_id;
   stream->stream_id = stream_id;
 
 
   /* this does not call h2_session_send() since there can not have been any
   /* this does not call h2_session_send() since there can not have been any
@@ -2154,9 +2128,14 @@ CURLcode Curl_http2_switched(struct connectdata *conn,
       return CURLE_HTTP2;
       return CURLE_HTTP2;
     }
     }
 
 
-    nghttp2_session_set_stream_user_data(httpc->h2,
-                                         stream->stream_id,
-                                         conn->data);
+    rv = nghttp2_session_set_stream_user_data(httpc->h2,
+                                              stream->stream_id,
+                                              data);
+    if(rv) {
+      infof(data, "http/2: failed to set user_data for stream %d!\n",
+            stream->stream_id);
+      DEBUGASSERT(0);
+    }
   }
   }
   else {
   else {
     populate_settings(conn, httpc);
     populate_settings(conn, httpc);

+ 2 - 2
lib/http2.h

@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *                             \___|\___/|_| \_\_____|
  *
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <[email protected]>, et al.
+ * Copyright (C) 1998 - 2018, Daniel Stenberg, <[email protected]>, et al.
  *
  *
  * This software is licensed as described in the file COPYING, which
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * you should have received as part of this distribution. The terms
@@ -65,7 +65,7 @@ void Curl_http2_cleanup_dependencies(struct Curl_easy *data);
 #define Curl_http2_request_upgrade(x,y) CURLE_UNSUPPORTED_PROTOCOL
 #define Curl_http2_request_upgrade(x,y) CURLE_UNSUPPORTED_PROTOCOL
 #define Curl_http2_setup(x) CURLE_UNSUPPORTED_PROTOCOL
 #define Curl_http2_setup(x) CURLE_UNSUPPORTED_PROTOCOL
 #define Curl_http2_switched(x,y,z) CURLE_UNSUPPORTED_PROTOCOL
 #define Curl_http2_switched(x,y,z) CURLE_UNSUPPORTED_PROTOCOL
-#define Curl_http2_setup_conn(x)
+#define Curl_http2_setup_conn(x) Curl_nop_stmt
 #define Curl_http2_setup_req(x)
 #define Curl_http2_setup_req(x)
 #define Curl_http2_init_state(x)
 #define Curl_http2_init_state(x)
 #define Curl_http2_init_userset(x)
 #define Curl_http2_init_userset(x)

+ 1 - 1
lib/http_ntlm.c

@@ -228,7 +228,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy)
     /* connection is already authenticated,
     /* connection is already authenticated,
      * don't send a header in future requests */
      * don't send a header in future requests */
     ntlm->state = NTLMSTATE_LAST;
     ntlm->state = NTLMSTATE_LAST;
-    /* fall-through */
+    /* FALLTHROUGH */
   case NTLMSTATE_LAST:
   case NTLMSTATE_LAST:
     Curl_safefree(*allocuserpwd);
     Curl_safefree(*allocuserpwd);
     authp->done = TRUE;
     authp->done = TRUE;

+ 3 - 4
lib/http_proxy.c

@@ -188,12 +188,10 @@ static CURLcode CONNECT(struct connectdata *conn,
   struct SingleRequest *k = &data->req;
   struct SingleRequest *k = &data->req;
   CURLcode result;
   CURLcode result;
   curl_socket_t tunnelsocket = conn->sock[sockindex];
   curl_socket_t tunnelsocket = conn->sock[sockindex];
-  timediff_t check;
   struct http_connect_state *s = conn->connect_state;
   struct http_connect_state *s = conn->connect_state;
 
 
 #define SELECT_OK      0
 #define SELECT_OK      0
 #define SELECT_ERROR   1
 #define SELECT_ERROR   1
-#define SELECT_TIMEOUT 2
 
 
   if(Curl_connect_complete(conn))
   if(Curl_connect_complete(conn))
     return CURLE_OK; /* CONNECT is already completed */
     return CURLE_OK; /* CONNECT is already completed */
@@ -201,12 +199,13 @@ static CURLcode CONNECT(struct connectdata *conn,
   conn->bits.proxy_connect_closed = FALSE;
   conn->bits.proxy_connect_closed = FALSE;
 
 
   do {
   do {
+    timediff_t check;
     if(TUNNEL_INIT == s->tunnel_state) {
     if(TUNNEL_INIT == s->tunnel_state) {
       /* BEGIN CONNECT PHASE */
       /* BEGIN CONNECT PHASE */
       char *host_port;
       char *host_port;
       Curl_send_buffer *req_buffer;
       Curl_send_buffer *req_buffer;
 
 
-      infof(data, "Establish HTTP proxy tunnel to %s:%hu\n",
+      infof(data, "Establish HTTP proxy tunnel to %s:%d\n",
             hostname, remote_port);
             hostname, remote_port);
 
 
         /* This only happens if we've looped here due to authentication
         /* This only happens if we've looped here due to authentication
@@ -419,7 +418,7 @@ static CURLcode CONNECT(struct connectdata *conn,
         /* output debug if that is requested */
         /* output debug if that is requested */
         if(data->set.verbose)
         if(data->set.verbose)
           Curl_debug(data, CURLINFO_HEADER_IN,
           Curl_debug(data, CURLINFO_HEADER_IN,
-                     s->line_start, (size_t)s->perline, conn);
+                     s->line_start, (size_t)s->perline);
 
 
         if(!data->set.suppress_connect_headers) {
         if(!data->set.suppress_connect_headers) {
           /* send the header to the callback */
           /* send the header to the callback */

+ 7 - 9
lib/imap.c

@@ -609,7 +609,6 @@ static CURLcode imap_perform_list(struct connectdata *conn)
   CURLcode result = CURLE_OK;
   CURLcode result = CURLE_OK;
   struct Curl_easy *data = conn->data;
   struct Curl_easy *data = conn->data;
   struct IMAP *imap = data->req.protop;
   struct IMAP *imap = data->req.protop;
-  char *mailbox;
 
 
   if(imap->custom)
   if(imap->custom)
     /* Send the custom request */
     /* Send the custom request */
@@ -617,7 +616,8 @@ static CURLcode imap_perform_list(struct connectdata *conn)
                         imap->custom_params ? imap->custom_params : "");
                         imap->custom_params ? imap->custom_params : "");
   else {
   else {
     /* Make sure the mailbox is in the correct atom format if necessary */
     /* Make sure the mailbox is in the correct atom format if necessary */
-    mailbox = imap->mailbox ? imap_atom(imap->mailbox, true) : strdup("");
+    char *mailbox = imap->mailbox ? imap_atom(imap->mailbox, true)
+                                  : strdup("");
     if(!mailbox)
     if(!mailbox)
       return CURLE_OUT_OF_MEMORY;
       return CURLE_OUT_OF_MEMORY;
 
 
@@ -854,7 +854,6 @@ static CURLcode imap_state_capability_resp(struct connectdata *conn,
   struct Curl_easy *data = conn->data;
   struct Curl_easy *data = conn->data;
   struct imap_conn *imapc = &conn->proto.imapc;
   struct imap_conn *imapc = &conn->proto.imapc;
   const char *line = data->state.buffer;
   const char *line = data->state.buffer;
-  size_t wordlen;
 
 
   (void)instate; /* no use for this yet */
   (void)instate; /* no use for this yet */
 
 
@@ -864,6 +863,7 @@ static CURLcode imap_state_capability_resp(struct connectdata *conn,
 
 
     /* Loop through the data line */
     /* Loop through the data line */
     for(;;) {
     for(;;) {
+      size_t wordlen;
       while(*line &&
       while(*line &&
             (*line == ' ' || *line == '\t' ||
             (*line == ' ' || *line == '\t' ||
               *line == '\r' || *line == '\n')) {
               *line == '\r' || *line == '\n')) {
@@ -1046,12 +1046,12 @@ static CURLcode imap_state_select_resp(struct connectdata *conn, int imapcode,
   struct IMAP *imap = conn->data->req.protop;
   struct IMAP *imap = conn->data->req.protop;
   struct imap_conn *imapc = &conn->proto.imapc;
   struct imap_conn *imapc = &conn->proto.imapc;
   const char *line = data->state.buffer;
   const char *line = data->state.buffer;
-  char tmp[20];
 
 
   (void)instate; /* no use for this yet */
   (void)instate; /* no use for this yet */
 
 
   if(imapcode == '*') {
   if(imapcode == '*') {
     /* See if this is an UIDVALIDITY response */
     /* See if this is an UIDVALIDITY response */
+    char tmp[20];
     if(sscanf(line + 2, "OK [UIDVALIDITY %19[0123456789]]", tmp) == 1) {
     if(sscanf(line + 2, "OK [UIDVALIDITY %19[0123456789]]", tmp) == 1) {
       Curl_safefree(imapc->mailbox_uidvalidity);
       Curl_safefree(imapc->mailbox_uidvalidity);
       imapc->mailbox_uidvalidity = strdup(tmp);
       imapc->mailbox_uidvalidity = strdup(tmp);
@@ -1119,7 +1119,7 @@ static CURLcode imap_state_fetch_resp(struct connectdata *conn, int imapcode,
   }
   }
 
 
   if(parsed) {
   if(parsed) {
-    infof(data, "Found %" CURL_FORMAT_CURL_OFF_TU " bytes to download\n",
+    infof(data, "Found %" CURL_FORMAT_CURL_OFF_T " bytes to download\n",
           size);
           size);
     Curl_pgrsSetDownloadSize(data, size);
     Curl_pgrsSetDownloadSize(data, size);
 
 
@@ -1144,10 +1144,8 @@ static CURLcode imap_state_fetch_resp(struct connectdata *conn, int imapcode,
 
 
       data->req.bytecount += chunk;
       data->req.bytecount += chunk;
 
 
-      infof(data, "Written %" CURL_FORMAT_CURL_OFF_TU
-            " bytes, %" CURL_FORMAT_CURL_OFF_TU
-            " bytes are left for transfer\n", (curl_off_t)chunk,
-            size - chunk);
+      infof(data, "Written %zu bytes, %" CURL_FORMAT_CURL_OFF_TU
+            " bytes are left for transfer\n", chunk, size - chunk);
 
 
       /* Have we used the entire cache or just part of it?*/
       /* Have we used the entire cache or just part of it?*/
       if(pp->cache_size > chunk) {
       if(pp->cache_size > chunk) {

+ 1 - 1
lib/inet_ntop.c

@@ -49,7 +49,7 @@
  */
  */
 static char *inet_ntop4 (const unsigned char *src, char *dst, size_t size)
 static char *inet_ntop4 (const unsigned char *src, char *dst, size_t size)
 {
 {
-  char tmp[sizeof "255.255.255.255"];
+  char tmp[sizeof("255.255.255.255")];
   size_t len;
   size_t len;
 
 
   DEBUGASSERT(size >= 16);
   DEBUGASSERT(size >= 16);

+ 0 - 9
lib/ldap.c

@@ -54,15 +54,6 @@
 # endif /* HAVE_LDAP_SSL && HAVE_LDAP_SSL_H */
 # endif /* HAVE_LDAP_SSL && HAVE_LDAP_SSL_H */
 #endif
 #endif
 
 
-/* These are macros in both <wincrypt.h> (in above <winldap.h>) and typedefs
- * in BoringSSL's <openssl/x509.h>
- */
-#ifdef HAVE_BORINGSSL
-# undef X509_NAME
-# undef X509_CERT_PAIR
-# undef X509_EXTENSIONS
-#endif
-
 #include "urldata.h"
 #include "urldata.h"
 #include <curl/curl.h>
 #include <curl/curl.h>
 #include "sendf.h"
 #include "sendf.h"

+ 23 - 17
lib/md5.c

@@ -484,29 +484,35 @@ static void MD5_Final(unsigned char *result, MD5_CTX *ctx)
 
 
 #endif /* CRYPTO LIBS */
 #endif /* CRYPTO LIBS */
 
 
-/* Disable this picky gcc-8 compiler warning */
-#if defined(__GNUC__) && (__GNUC__ >= 8)
-#pragma GCC diagnostic ignored "-Wcast-function-type"
-#endif
-
 const HMAC_params Curl_HMAC_MD5[] = {
 const HMAC_params Curl_HMAC_MD5[] = {
   {
   {
-    (HMAC_hinit_func) MD5_Init,           /* Hash initialization function. */
-    (HMAC_hupdate_func) MD5_Update,       /* Hash update function. */
-    (HMAC_hfinal_func) MD5_Final,         /* Hash computation end function. */
-    sizeof(MD5_CTX),                      /* Size of hash context structure. */
-    64,                                   /* Maximum key length. */
-    16                                    /* Result size. */
+    /* Hash initialization function. */
+    CURLX_FUNCTION_CAST(HMAC_hinit_func, MD5_Init),
+    /* Hash update function. */
+    CURLX_FUNCTION_CAST(HMAC_hupdate_func, MD5_Update),
+    /* Hash computation end function. */
+    CURLX_FUNCTION_CAST(HMAC_hfinal_func, MD5_Final),
+    /* Size of hash context structure. */
+    sizeof(MD5_CTX),
+    /* Maximum key length. */
+    64,
+    /* Result size. */
+    16
   }
   }
 };
 };
 
 
 const MD5_params Curl_DIGEST_MD5[] = {
 const MD5_params Curl_DIGEST_MD5[] = {
   {
   {
-    (Curl_MD5_init_func) MD5_Init,      /* Digest initialization function */
-    (Curl_MD5_update_func) MD5_Update,  /* Digest update function */
-    (Curl_MD5_final_func) MD5_Final,    /* Digest computation end function */
-    sizeof(MD5_CTX),                    /* Size of digest context struct */
-    16                                  /* Result size */
+    /* Digest initialization function */
+    CURLX_FUNCTION_CAST(Curl_MD5_init_func, MD5_Init),
+    /* Digest update function */
+    CURLX_FUNCTION_CAST(Curl_MD5_update_func, MD5_Update),
+    /* Digest computation end function */
+    CURLX_FUNCTION_CAST(Curl_MD5_final_func, MD5_Final),
+    /* Size of digest context struct */
+    sizeof(MD5_CTX),
+    /* Result size */
+    16
   }
   }
 };
 };
 
 
@@ -527,7 +533,7 @@ MD5_context *Curl_MD5_init(const MD5_params *md5params)
   MD5_context *ctxt;
   MD5_context *ctxt;
 
 
   /* Create MD5 context */
   /* Create MD5 context */
-  ctxt = malloc(sizeof *ctxt);
+  ctxt = malloc(sizeof(*ctxt));
 
 
   if(!ctxt)
   if(!ctxt)
     return ctxt;
     return ctxt;

+ 1 - 8
lib/memdebug.h

@@ -8,7 +8,7 @@
  *                            | (__| |_| |  _ <| |___
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *                             \___|\___/|_| \_\_____|
  *
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <[email protected]>, et al.
+ * Copyright (C) 1998 - 2018, Daniel Stenberg, <[email protected]>, et al.
  *
  *
  * This software is licensed as described in the file COPYING, which
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * you should have received as part of this distribution. The terms
@@ -137,13 +137,6 @@ CURL_EXTERN int curl_fclose(FILE *file, int line, const char *source);
 #endif
 #endif
 #endif /* HAVE_GETADDRINFO */
 #endif /* HAVE_GETADDRINFO */
 
 
-#ifdef HAVE_GETNAMEINFO
-#undef getnameinfo
-#define getnameinfo(sa,salen,host,hostlen,serv,servlen,flags) \
-  curl_dogetnameinfo(sa, salen, host, hostlen, serv, servlen, flags, \
-                     __LINE__, __FILE__)
-#endif /* HAVE_GETNAMEINFO */
-
 #ifdef HAVE_FREEADDRINFO
 #ifdef HAVE_FREEADDRINFO
 #undef freeaddrinfo
 #undef freeaddrinfo
 #define freeaddrinfo(data) \
 #define freeaddrinfo(data) \

+ 24 - 29
lib/mime.c

@@ -505,9 +505,6 @@ static size_t encoder_qp_read(char *buffer, size_t size, bool ateof,
   mime_encoder_state *st = &part->encstate;
   mime_encoder_state *st = &part->encstate;
   char *ptr = buffer;
   char *ptr = buffer;
   size_t cursize = 0;
   size_t cursize = 0;
-  int i;
-  size_t len;
-  size_t consumed;
   int softlinebreak;
   int softlinebreak;
   char buf[4];
   char buf[4];
 
 
@@ -516,9 +513,9 @@ static size_t encoder_qp_read(char *buffer, size_t size, bool ateof,
      character constants that can be interpreted as non-ascii on some
      character constants that can be interpreted as non-ascii on some
      platforms. Preserve ASCII encoding on output too. */
      platforms. Preserve ASCII encoding on output too. */
   while(st->bufbeg < st->bufend) {
   while(st->bufbeg < st->bufend) {
-    len = 1;
-    consumed = 1;
-    i = st->buf[st->bufbeg];
+    size_t len = 1;
+    size_t consumed = 1;
+    int i = st->buf[st->bufbeg];
     buf[0] = (char) i;
     buf[0] = (char) i;
     buf[1] = aschex[(i >> 4) & 0xF];
     buf[1] = aschex[(i >> 4) & 0xF];
     buf[2] = aschex[i & 0xF];
     buf[2] = aschex[i & 0xF];
@@ -787,10 +784,10 @@ static size_t read_encoded_part_content(curl_mimepart *part,
       st->bufbeg = 0;
       st->bufbeg = 0;
       st->bufend = len;
       st->bufend = len;
     }
     }
-    if(st->bufend >= sizeof st->buf)
+    if(st->bufend >= sizeof(st->buf))
       return cursize? cursize: READ_ERROR;    /* Buffer full. */
       return cursize? cursize: READ_ERROR;    /* Buffer full. */
     sz = read_part_content(part, st->buf + st->bufend,
     sz = read_part_content(part, st->buf + st->bufend,
-                           sizeof st->buf - st->bufend);
+                           sizeof(st->buf) - st->bufend);
     switch(sz) {
     switch(sz) {
     case 0:
     case 0:
       ateof = TRUE;
       ateof = TRUE;
@@ -813,8 +810,6 @@ static size_t readback_part(curl_mimepart *part,
                             char *buffer, size_t bufsize)
                             char *buffer, size_t bufsize)
 {
 {
   size_t cursize = 0;
   size_t cursize = 0;
-  size_t sz;
-  struct curl_slist *hdr;
 #ifdef CURL_DOES_CONVERSIONS
 #ifdef CURL_DOES_CONVERSIONS
   char *convbuf = buffer;
   char *convbuf = buffer;
 #endif
 #endif
@@ -822,8 +817,8 @@ static size_t readback_part(curl_mimepart *part,
   /* Readback from part. */
   /* Readback from part. */
 
 
   while(bufsize) {
   while(bufsize) {
-    sz = 0;
-    hdr = (struct curl_slist *) part->state.ptr;
+    size_t sz = 0;
+    struct curl_slist *hdr = (struct curl_slist *) part->state.ptr;
     switch(part->state.state) {
     switch(part->state.state) {
     case MIMESTATE_BEGIN:
     case MIMESTATE_BEGIN:
       mimesetstate(&part->state, part->flags & MIME_BODY_ONLY? MIMESTATE_BODY:
       mimesetstate(&part->state, part->flags & MIME_BODY_ONLY? MIMESTATE_BODY:
@@ -918,8 +913,6 @@ static size_t mime_subparts_read(char *buffer, size_t size, size_t nitems,
 {
 {
   curl_mime *mime = (curl_mime *) instream;
   curl_mime *mime = (curl_mime *) instream;
   size_t cursize = 0;
   size_t cursize = 0;
-  size_t sz;
-  curl_mimepart *part;
 #ifdef CURL_DOES_CONVERSIONS
 #ifdef CURL_DOES_CONVERSIONS
   char *convbuf = buffer;
   char *convbuf = buffer;
 #endif
 #endif
@@ -927,8 +920,8 @@ static size_t mime_subparts_read(char *buffer, size_t size, size_t nitems,
   (void) size;   /* Always 1. */
   (void) size;   /* Always 1. */
 
 
   while(nitems) {
   while(nitems) {
-    sz = 0;
-    part = mime->state.ptr;
+    size_t sz = 0;
+    curl_mimepart *part = mime->state.ptr;
     switch(mime->state.state) {
     switch(mime->state.state) {
     case MIMESTATE_BEGIN:
     case MIMESTATE_BEGIN:
     case MIMESTATE_BODY:
     case MIMESTATE_BODY:
@@ -1044,7 +1037,6 @@ static int mime_subparts_seek(void *instream, curl_off_t offset, int whence)
   curl_mime *mime = (curl_mime *) instream;
   curl_mime *mime = (curl_mime *) instream;
   curl_mimepart *part;
   curl_mimepart *part;
   int result = CURL_SEEKFUNC_OK;
   int result = CURL_SEEKFUNC_OK;
-  int res;
 
 
   if(whence != SEEK_SET || offset)
   if(whence != SEEK_SET || offset)
     return CURL_SEEKFUNC_CANTSEEK;    /* Only support full rewind. */
     return CURL_SEEKFUNC_CANTSEEK;    /* Only support full rewind. */
@@ -1053,7 +1045,7 @@ static int mime_subparts_seek(void *instream, curl_off_t offset, int whence)
    return CURL_SEEKFUNC_OK;           /* Already rewound. */
    return CURL_SEEKFUNC_OK;           /* Already rewound. */
 
 
   for(part = mime->firstpart; part; part = part->nextpart) {
   for(part = mime->firstpart; part; part = part->nextpart) {
-    res = mime_part_rewind(part);
+    int res = mime_part_rewind(part);
     if(res != CURL_SEEKFUNC_OK)
     if(res != CURL_SEEKFUNC_OK)
       result = res;
       result = res;
   }
   }
@@ -1220,7 +1212,7 @@ curl_mime *curl_mime_init(struct Curl_easy *easy)
 {
 {
   curl_mime *mime;
   curl_mime *mime;
 
 
-  mime = (curl_mime *) malloc(sizeof *mime);
+  mime = (curl_mime *) malloc(sizeof(*mime));
 
 
   if(mime) {
   if(mime) {
     mime->easy = easy;
     mime->easy = easy;
@@ -1236,8 +1228,13 @@ curl_mime *curl_mime_init(struct Curl_easy *easy)
     }
     }
 
 
     memset(mime->boundary, '-', 24);
     memset(mime->boundary, '-', 24);
-    Curl_rand_hex(easy, (unsigned char *) mime->boundary + 24,
-                  MIME_RAND_BOUNDARY_CHARS + 1);
+    if(Curl_rand_hex(easy, (unsigned char *) mime->boundary + 24,
+                     MIME_RAND_BOUNDARY_CHARS + 1)) {
+      /* failed to get random separator, bail out */
+      free(mime->boundary);
+      free(mime);
+      return NULL;
+    }
     mimesetstate(&mime->state, MIMESTATE_BEGIN, NULL);
     mimesetstate(&mime->state, MIMESTATE_BEGIN, NULL);
   }
   }
 
 
@@ -1247,7 +1244,7 @@ curl_mime *curl_mime_init(struct Curl_easy *easy)
 /* Initialize a mime part. */
 /* Initialize a mime part. */
 void Curl_mime_initpart(curl_mimepart *part, struct Curl_easy *easy)
 void Curl_mime_initpart(curl_mimepart *part, struct Curl_easy *easy)
 {
 {
-  memset((char *) part, 0, sizeof *part);
+  memset((char *) part, 0, sizeof(*part));
   part->easy = easy;
   part->easy = easy;
   mimesetstate(&part->state, MIMESTATE_BEGIN, NULL);
   mimesetstate(&part->state, MIMESTATE_BEGIN, NULL);
 }
 }
@@ -1260,7 +1257,7 @@ curl_mimepart *curl_mime_addpart(curl_mime *mime)
   if(!mime)
   if(!mime)
     return NULL;
     return NULL;
 
 
-  part = (curl_mimepart *) malloc(sizeof *part);
+  part = (curl_mimepart *) malloc(sizeof(*part));
 
 
   if(part) {
   if(part) {
     Curl_mime_initpart(part, mime->easy);
     Curl_mime_initpart(part, mime->easy);
@@ -1349,7 +1346,6 @@ CURLcode curl_mime_data(curl_mimepart *part,
 CURLcode curl_mime_filedata(curl_mimepart *part, const char *filename)
 CURLcode curl_mime_filedata(curl_mimepart *part, const char *filename)
 {
 {
   CURLcode result = CURLE_OK;
   CURLcode result = CURLE_OK;
-  char *base;
 
 
   if(!part)
   if(!part)
     return CURLE_BAD_FUNCTION_ARGUMENT;
     return CURLE_BAD_FUNCTION_ARGUMENT;
@@ -1357,6 +1353,7 @@ CURLcode curl_mime_filedata(curl_mimepart *part, const char *filename)
   cleanup_part_content(part);
   cleanup_part_content(part);
 
 
   if(filename) {
   if(filename) {
+    char *base;
     struct_stat sbuf;
     struct_stat sbuf;
 
 
     if(stat(filename, &sbuf) || access(filename, R_OK))
     if(stat(filename, &sbuf) || access(filename, R_OK))
@@ -1564,7 +1561,6 @@ static size_t slist_size(struct curl_slist *s,
 static curl_off_t multipart_size(curl_mime *mime)
 static curl_off_t multipart_size(curl_mime *mime)
 {
 {
   curl_off_t size;
   curl_off_t size;
-  curl_off_t sz;
   size_t boundarysize;
   size_t boundarysize;
   curl_mimepart *part;
   curl_mimepart *part;
 
 
@@ -1575,7 +1571,7 @@ static curl_off_t multipart_size(curl_mime *mime)
   size = boundarysize;  /* Final boundary - CRLF after headers. */
   size = boundarysize;  /* Final boundary - CRLF after headers. */
 
 
   for(part = mime->firstpart; part; part = part->nextpart) {
   for(part = mime->firstpart; part; part = part->nextpart) {
-    sz = Curl_mime_size(part);
+    curl_off_t sz = Curl_mime_size(part);
 
 
     if(sz < 0)
     if(sz < 0)
       size = sz;
       size = sz;
@@ -1643,8 +1639,6 @@ static CURLcode add_content_type(struct curl_slist **slp,
 
 
 const char *Curl_mime_contenttype(const char *filename)
 const char *Curl_mime_contenttype(const char *filename)
 {
 {
-  unsigned int i;
-
   /*
   /*
    * If no content type was specified, we scan through a few well-known
    * If no content type was specified, we scan through a few well-known
    * extensions and pick the first we match!
    * extensions and pick the first we match!
@@ -1669,8 +1663,9 @@ const char *Curl_mime_contenttype(const char *filename)
   if(filename) {
   if(filename) {
     size_t len1 = strlen(filename);
     size_t len1 = strlen(filename);
     const char *nameend = filename + len1;
     const char *nameend = filename + len1;
+    unsigned int i;
 
 
-    for(i = 0; i < sizeof ctts / sizeof ctts[0]; i++) {
+    for(i = 0; i < sizeof(ctts) / sizeof(ctts[0]); i++) {
       size_t len2 = strlen(ctts[i].extension);
       size_t len2 = strlen(ctts[i].extension);
 
 
       if(len1 >= len2 && strcasecompare(nameend - len2, ctts[i].extension))
       if(len1 >= len2 && strcasecompare(nameend - len2, ctts[i].extension))

+ 119 - 88
lib/multi.c

@@ -31,6 +31,7 @@
 #include "progress.h"
 #include "progress.h"
 #include "easyif.h"
 #include "easyif.h"
 #include "share.h"
 #include "share.h"
+#include "psl.h"
 #include "multiif.h"
 #include "multiif.h"
 #include "sendf.h"
 #include "sendf.h"
 #include "timeval.h"
 #include "timeval.h"
@@ -68,8 +69,8 @@
 #define GOOD_MULTI_HANDLE(x) \
 #define GOOD_MULTI_HANDLE(x) \
   ((x) && (x)->type == CURL_MULTI_HANDLE)
   ((x) && (x)->type == CURL_MULTI_HANDLE)
 
 
-static void singlesocket(struct Curl_multi *multi,
-                         struct Curl_easy *data);
+static CURLMcode singlesocket(struct Curl_multi *multi,
+                              struct Curl_easy *data);
 static int update_timer(struct Curl_multi *multi);
 static int update_timer(struct Curl_multi *multi);
 
 
 static CURLMcode add_next_timeout(struct curltime now,
 static CURLMcode add_next_timeout(struct curltime now,
@@ -106,6 +107,16 @@ static const char * const statename[]={
 /* function pointer called once when switching TO a state */
 /* function pointer called once when switching TO a state */
 typedef void (*init_multistate_func)(struct Curl_easy *data);
 typedef void (*init_multistate_func)(struct Curl_easy *data);
 
 
+static void Curl_init_completed(struct Curl_easy *data)
+{
+  /* this is a completed transfer */
+
+  /* Important: reset the conn pointer so that we don't point to memory
+     that could be freed anytime */
+  data->easy_conn = NULL;
+  Curl_expire_clear(data); /* stop all timers */
+}
+
 /* always use this function to change state, to make debugging easier */
 /* always use this function to change state, to make debugging easier */
 static void mstate(struct Curl_easy *data, CURLMstate state
 static void mstate(struct Curl_easy *data, CURLMstate state
 #ifdef DEBUGBUILD
 #ifdef DEBUGBUILD
@@ -115,17 +126,25 @@ static void mstate(struct Curl_easy *data, CURLMstate state
 {
 {
   CURLMstate oldstate = data->mstate;
   CURLMstate oldstate = data->mstate;
   static const init_multistate_func finit[CURLM_STATE_LAST] = {
   static const init_multistate_func finit[CURLM_STATE_LAST] = {
-    NULL,
-    NULL,
+    NULL,              /* INIT */
+    NULL,              /* CONNECT_PEND */
     Curl_init_CONNECT, /* CONNECT */
     Curl_init_CONNECT, /* CONNECT */
-    NULL,
-    NULL,
-    NULL,
-    NULL,
-    NULL,
-    NULL,
-    Curl_connect_free /* DO */
-    /* the rest is NULL too */
+    NULL,              /* WAITRESOLVE */
+    NULL,              /* WAITCONNECT */
+    NULL,              /* WAITPROXYCONNECT */
+    NULL,              /* SENDPROTOCONNECT */
+    NULL,              /* PROTOCONNECT */
+    NULL,              /* WAITDO */
+    Curl_connect_free, /* DO */
+    NULL,              /* DOING */
+    NULL,              /* DO_MORE */
+    NULL,              /* DO_DONE */
+    NULL,              /* WAITPERFORM */
+    NULL,              /* PERFORM */
+    NULL,              /* TOOFAST */
+    NULL,              /* DONE */
+    Curl_init_completed, /* COMPLETED */
+    NULL               /* MSGSENT */
   };
   };
 
 
 #if defined(DEBUGBUILD) && defined(CURL_DISABLE_VERBOSE_STRINGS)
 #if defined(DEBUGBUILD) && defined(CURL_DISABLE_VERBOSE_STRINGS)
@@ -409,6 +428,14 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
   else
   else
     data->state.conn_cache = &multi->conn_cache;
     data->state.conn_cache = &multi->conn_cache;
 
 
+#ifdef USE_LIBPSL
+  /* Do the same for PSL. */
+  if(data->share && (data->share->specifier & (1 << CURL_LOCK_DATA_PSL)))
+    data->psl = &data->share->psl;
+  else
+    data->psl = &multi->psl;
+#endif
+
   /* This adds the new entry at the 'end' of the doubly-linked circular
   /* This adds the new entry at the 'end' of the doubly-linked circular
      list of Curl_easy structs to try and maintain a FIFO queue so
      list of Curl_easy structs to try and maintain a FIFO queue so
      the pipelined requests are in order. */
      the pipelined requests are in order. */
@@ -449,7 +476,7 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
      happens if the lastcall time is set to the same time when the handle is
      happens if the lastcall time is set to the same time when the handle is
      removed as when the next handle is added, as then the check in
      removed as when the next handle is added, as then the check in
      update_timer() that prevents calling the application multiple times with
      update_timer() that prevents calling the application multiple times with
-     the same timer infor will not trigger and then the new handle's timeout
+     the same timer info will not trigger and then the new handle's timeout
      will not be notified to the app.
      will not be notified to the app.
 
 
      The work-around is thus simply to clear the 'lastcall' variable to force
      The work-around is thus simply to clear the 'lastcall' variable to force
@@ -506,6 +533,11 @@ static CURLcode multi_done(struct connectdata **connp,
     /* Stop if multi_done() has already been called */
     /* Stop if multi_done() has already been called */
     return CURLE_OK;
     return CURLE_OK;
 
 
+  if(data->mstate == CURLM_STATE_WAITRESOLVE) {
+    /* still waiting for the resolve to complete */
+    (void)Curl_resolver_wait_resolv(conn, NULL);
+  }
+
   Curl_getoff_all_pipelines(data, conn);
   Curl_getoff_all_pipelines(data, conn);
 
 
   /* Cleanup possible redirect junk */
   /* Cleanup possible redirect junk */
@@ -546,7 +578,7 @@ static CURLcode multi_done(struct connectdata **connp,
   if(conn->send_pipe.size || conn->recv_pipe.size) {
   if(conn->send_pipe.size || conn->recv_pipe.size) {
     /* Stop if pipeline is not empty . */
     /* Stop if pipeline is not empty . */
     data->easy_conn = NULL;
     data->easy_conn = NULL;
-    DEBUGF(infof(data, "Connection still in use %d/%d, "
+    DEBUGF(infof(data, "Connection still in use %zu/%zu, "
                  "no more multi_done now!\n",
                  "no more multi_done now!\n",
                  conn->send_pipe.size, conn->recv_pipe.size));
                  conn->send_pipe.size, conn->recv_pipe.size));
     return CURLE_OK;
     return CURLE_OK;
@@ -560,6 +592,7 @@ static CURLcode multi_done(struct connectdata **connp,
     conn->dns_entry = NULL;
     conn->dns_entry = NULL;
   }
   }
   Curl_hostcache_prune(data);
   Curl_hostcache_prune(data);
+  Curl_safefree(data->state.ulbuf);
 
 
   /* if the transfer was completed in a paused state there can be buffered
   /* if the transfer was completed in a paused state there can be buffered
      data left to free */
      data left to free */
@@ -590,7 +623,7 @@ static CURLcode multi_done(struct connectdata **connp,
 #endif
 #endif
      ) || conn->bits.close
      ) || conn->bits.close
        || (premature && !(conn->handler->flags & PROTOPT_STREAM))) {
        || (premature && !(conn->handler->flags & PROTOPT_STREAM))) {
-    CURLcode res2 = Curl_disconnect(conn, premature); /* close connection */
+    CURLcode res2 = Curl_disconnect(data, conn, premature);
 
 
     /* If we had an error already, make sure we return that one. But
     /* If we had an error already, make sure we return that one. But
        if we got a new error, return that. */
        if we got a new error, return that. */
@@ -608,7 +641,7 @@ static CURLcode multi_done(struct connectdata **connp,
              conn->bits.conn_to_host ? conn->conn_to_host.dispname :
              conn->bits.conn_to_host ? conn->conn_to_host.dispname :
              conn->host.dispname);
              conn->host.dispname);
 
 
-    /* the connection is no longer in use */
+    /* the connection is no longer in use by this transfer */
     if(Curl_conncache_return_conn(conn)) {
     if(Curl_conncache_return_conn(conn)) {
       /* remember the most recently used connection */
       /* remember the most recently used connection */
       data->state.lastconnect = conn;
       data->state.lastconnect = conn;
@@ -698,6 +731,11 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
       Curl_getoff_all_pipelines(data, data->easy_conn);
       Curl_getoff_all_pipelines(data, data->easy_conn);
   }
   }
 
 
+  if(data->connect_queue.ptr)
+    /* the handle was in the pending list waiting for an available connection,
+       so go ahead and remove it */
+    Curl_llist_remove(&multi->pending, &data->connect_queue, NULL);
+
   if(data->dns.hostcachetype == HCACHE_MULTI) {
   if(data->dns.hostcachetype == HCACHE_MULTI) {
     /* stop using the multi handle's DNS cache, *after* the possible
     /* stop using the multi handle's DNS cache, *after* the possible
        multi_done() call above */
        multi_done() call above */
@@ -727,6 +765,12 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
     data->easy_conn = NULL;
     data->easy_conn = NULL;
   }
   }
 
 
+#ifdef USE_LIBPSL
+  /* Remove the PSL association. */
+  if(data->psl == &multi->psl)
+    data->psl = NULL;
+#endif
+
   data->multi = NULL; /* clear the association to this multi handle */
   data->multi = NULL; /* clear the association to this multi handle */
 
 
   /* make sure there's no pending message in the queue sent from this easy
   /* make sure there's no pending message in the queue sent from this easy
@@ -831,12 +875,10 @@ static int multi_getsock(struct Curl_easy *data,
                                                   of sockets */
                                                   of sockets */
                          int numsocks)
                          int numsocks)
 {
 {
-  /* If the pipe broke, or if there's no connection left for this easy handle,
-     then we MUST bail out now with no bitmask set. The no connection case can
-     happen when this is called from curl_multi_remove_handle() =>
-     singlesocket() => multi_getsock().
+  /* The no connection case can happen when this is called from
+     curl_multi_remove_handle() => singlesocket() => multi_getsock().
   */
   */
-  if(data->state.pipe_broke || !data->easy_conn)
+  if(!data->easy_conn)
     return 0;
     return 0;
 
 
   if(data->mstate > CURLM_STATE_CONNECT &&
   if(data->mstate > CURLM_STATE_CONNECT &&
@@ -902,7 +944,6 @@ CURLMcode curl_multi_fdset(struct Curl_multi *multi,
   struct Curl_easy *data;
   struct Curl_easy *data;
   int this_max_fd = -1;
   int this_max_fd = -1;
   curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE];
   curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE];
-  int bitmap;
   int i;
   int i;
   (void)exc_fd_set; /* not used */
   (void)exc_fd_set; /* not used */
 
 
@@ -914,7 +955,7 @@ CURLMcode curl_multi_fdset(struct Curl_multi *multi,
 
 
   data = multi->easyp;
   data = multi->easyp;
   while(data) {
   while(data) {
-    bitmap = multi_getsock(data, sockbunch, MAX_SOCKSPEREASYHANDLE);
+    int bitmap = multi_getsock(data, sockbunch, MAX_SOCKSPEREASYHANDLE);
 
 
     for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++) {
     for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++) {
       curl_socket_t s = CURL_SOCKET_BAD;
       curl_socket_t s = CURL_SOCKET_BAD;
@@ -1068,8 +1109,6 @@ CURLMcode curl_multi_wait(struct Curl_multi *multi,
     int pollrc;
     int pollrc;
     /* wait... */
     /* wait... */
     pollrc = Curl_poll(ufds, nfds, timeout_ms);
     pollrc = Curl_poll(ufds, nfds, timeout_ms);
-    DEBUGF(infof(data, "Curl_poll(%d ds, %d ms) == %d\n",
-                 nfds, timeout_ms, pollrc));
 
 
     if(pollrc > 0) {
     if(pollrc > 0) {
       retcode = pollrc;
       retcode = pollrc;
@@ -1312,24 +1351,6 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
     bool stream_error = FALSE;
     bool stream_error = FALSE;
     rc = CURLM_OK;
     rc = CURLM_OK;
 
 
-    /* Handle the case when the pipe breaks, i.e., the connection
-       we're using gets cleaned up and we're left with nothing. */
-    if(data->state.pipe_broke) {
-      infof(data, "Pipe broke: handle %p, url = %s\n",
-            (void *)data, data->state.path);
-
-      if(data->mstate < CURLM_STATE_COMPLETED) {
-        /* Head back to the CONNECT state */
-        multistate(data, CURLM_STATE_CONNECT);
-        rc = CURLM_CALL_MULTI_PERFORM;
-        result = CURLE_OK;
-      }
-
-      data->state.pipe_broke = FALSE;
-      data->easy_conn = NULL;
-      continue;
-    }
-
     if(!data->easy_conn &&
     if(!data->easy_conn &&
        data->mstate > CURLM_STATE_CONNECT &&
        data->mstate > CURLM_STATE_CONNECT &&
        data->mstate < CURLM_STATE_DONE) {
        data->mstate < CURLM_STATE_DONE) {
@@ -1555,6 +1576,8 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
           multistate(data, CURLM_STATE_SENDPROTOCONNECT);
           multistate(data, CURLM_STATE_SENDPROTOCONNECT);
         }
         }
       }
       }
+      else if(result)
+        stream_error = TRUE;
       break;
       break;
 #endif
 #endif
 
 
@@ -1909,6 +1932,8 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
         CURLcode ret = Curl_retry_request(data->easy_conn, &newurl);
         CURLcode ret = Curl_retry_request(data->easy_conn, &newurl);
         if(!ret)
         if(!ret)
           retry = (newurl)?TRUE:FALSE;
           retry = (newurl)?TRUE:FALSE;
+        else if(!result)
+          result = ret;
 
 
         if(retry) {
         if(retry) {
           /* if we are to retry, set the result to OK and consider the
           /* if we are to retry, set the result to OK and consider the
@@ -2040,16 +2065,6 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
       break;
       break;
 
 
     case CURLM_STATE_COMPLETED:
     case CURLM_STATE_COMPLETED:
-      /* this is a completed transfer, it is likely to still be connected */
-
-      /* This node should be delinked from the list now and we should post
-         an information message that we are complete. */
-
-      /* Important: reset the conn pointer so that we don't point to memory
-         that could be freed anytime */
-      data->easy_conn = NULL;
-
-      Curl_expire_clear(data); /* stop all timers */
       break;
       break;
 
 
     case CURLM_STATE_MSGSENT:
     case CURLM_STATE_MSGSENT:
@@ -2071,8 +2086,6 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
         /* NOTE: no attempt to disconnect connections must be made
         /* NOTE: no attempt to disconnect connections must be made
            in the case blocks above - cleanup happens only here */
            in the case blocks above - cleanup happens only here */
 
 
-        data->state.pipe_broke = FALSE;
-
         /* Check if we can move pending requests to send pipe */
         /* Check if we can move pending requests to send pipe */
         process_pending_handles(multi); /* connection */
         process_pending_handles(multi); /* connection */
 
 
@@ -2087,7 +2100,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
             /* Don't attempt to send data over a connection that timed out */
             /* Don't attempt to send data over a connection that timed out */
             bool dead_connection = result == CURLE_OPERATION_TIMEDOUT;
             bool dead_connection = result == CURLE_OPERATION_TIMEDOUT;
             /* disconnect properly */
             /* disconnect properly */
-            Curl_disconnect(data->easy_conn, dead_connection);
+            Curl_disconnect(data, data->easy_conn, dead_connection);
 
 
             /* This is where we make sure that the easy_conn pointer is reset.
             /* This is where we make sure that the easy_conn pointer is reset.
                We don't have to do this in every case block above where a
                We don't have to do this in every case block above where a
@@ -2101,6 +2114,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
         }
         }
 
 
         multistate(data, CURLM_STATE_COMPLETED);
         multistate(data, CURLM_STATE_COMPLETED);
+        rc = CURLM_CALL_MULTI_PERFORM;
       }
       }
       /* if there's still a connection to use, call the progress function */
       /* if there's still a connection to use, call the progress function */
       else if(data->easy_conn && Curl_pgrsUpdate(data->easy_conn)) {
       else if(data->easy_conn && Curl_pgrsUpdate(data->easy_conn)) {
@@ -2125,14 +2139,12 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
       msg->extmsg.data.result = result;
       msg->extmsg.data.result = result;
 
 
       rc = multi_addmsg(multi, msg);
       rc = multi_addmsg(multi, msg);
-
+      DEBUGASSERT(!data->easy_conn);
       multistate(data, CURLM_STATE_MSGSENT);
       multistate(data, CURLM_STATE_MSGSENT);
     }
     }
   } while((rc == CURLM_CALL_MULTI_PERFORM) || multi_ischanged(multi, FALSE));
   } while((rc == CURLM_CALL_MULTI_PERFORM) || multi_ischanged(multi, FALSE));
 
 
   data->result = result;
   data->result = result;
-
-
   return rc;
   return rc;
 }
 }
 
 
@@ -2220,6 +2232,11 @@ CURLMcode curl_multi_cleanup(struct Curl_multi *multi)
       data->state.conn_cache = NULL;
       data->state.conn_cache = NULL;
       data->multi = NULL; /* clear the association */
       data->multi = NULL; /* clear the association */
 
 
+#ifdef USE_LIBPSL
+      if(data->psl == &multi->psl)
+        data->psl = NULL;
+#endif
+
       data = nextdata;
       data = nextdata;
     }
     }
 
 
@@ -2232,6 +2249,7 @@ CURLMcode curl_multi_cleanup(struct Curl_multi *multi)
     Curl_llist_destroy(&multi->pending, NULL);
     Curl_llist_destroy(&multi->pending, NULL);
 
 
     Curl_hash_destroy(&multi->hostcache);
     Curl_hash_destroy(&multi->hostcache);
+    Curl_psl_destroy(&multi->psl);
 
 
     /* Free the blacklists by setting them to NULL */
     /* Free the blacklists by setting them to NULL */
     Curl_pipeline_set_site_blacklist(NULL, &multi->pipelining_site_bl);
     Curl_pipeline_set_site_blacklist(NULL, &multi->pipelining_site_bl);
@@ -2286,8 +2304,8 @@ CURLMsg *curl_multi_info_read(struct Curl_multi *multi, int *msgs_in_queue)
  * and if we have a different state in any of those sockets from last time we
  * and if we have a different state in any of those sockets from last time we
  * call the callback accordingly.
  * call the callback accordingly.
  */
  */
-static void singlesocket(struct Curl_multi *multi,
-                         struct Curl_easy *data)
+static CURLMcode singlesocket(struct Curl_multi *multi,
+                              struct Curl_easy *data)
 {
 {
   curl_socket_t socks[MAX_SOCKSPEREASYHANDLE];
   curl_socket_t socks[MAX_SOCKSPEREASYHANDLE];
   int i;
   int i;
@@ -2334,7 +2352,7 @@ static void singlesocket(struct Curl_multi *multi,
       entry = sh_addentry(&multi->sockhash, s, data);
       entry = sh_addentry(&multi->sockhash, s, data);
       if(!entry)
       if(!entry)
         /* fatal */
         /* fatal */
-        return;
+        return CURLM_OUT_OF_MEMORY;
     }
     }
 
 
     /* we know (entry != NULL) at this point, see the logic above */
     /* we know (entry != NULL) at this point, see the logic above */
@@ -2422,6 +2440,7 @@ static void singlesocket(struct Curl_multi *multi,
 
 
   memcpy(data->sockets, socks, num*sizeof(curl_socket_t));
   memcpy(data->sockets, socks, num*sizeof(curl_socket_t));
   data->numsocks = num;
   data->numsocks = num;
+  return CURLM_OK;
 }
 }
 
 
 void Curl_updatesocket(struct Curl_easy *data)
 void Curl_updatesocket(struct Curl_easy *data)
@@ -2442,20 +2461,23 @@ void Curl_updatesocket(struct Curl_easy *data)
 
 
 void Curl_multi_closed(struct connectdata *conn, curl_socket_t s)
 void Curl_multi_closed(struct connectdata *conn, curl_socket_t s)
 {
 {
-  struct Curl_multi *multi = conn->data->multi;
-  if(multi) {
-    /* this is set if this connection is part of a handle that is added to
-       a multi handle, and only then this is necessary */
-    struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s);
-
-    if(entry) {
-      if(multi->socket_cb)
-        multi->socket_cb(conn->data, s, CURL_POLL_REMOVE,
-                         multi->socket_userp,
-                         entry->socketp);
+  if(conn->data) {
+    /* if there's still an easy handle associated with this connection */
+    struct Curl_multi *multi = conn->data->multi;
+    if(multi) {
+      /* this is set if this connection is part of a handle that is added to
+         a multi handle, and only then this is necessary */
+      struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s);
+
+      if(entry) {
+        if(multi->socket_cb)
+          multi->socket_cb(conn->data, s, CURL_POLL_REMOVE,
+                           multi->socket_userp,
+                           entry->socketp);
 
 
-      /* now remove it from the socket hash */
-      sh_delentry(&multi->sockhash, s);
+        /* now remove it from the socket hash */
+        sh_delentry(&multi->sockhash, s);
+      }
     }
     }
   }
   }
 }
 }
@@ -2535,8 +2557,8 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
        and callbacks */
        and callbacks */
     if(result != CURLM_BAD_HANDLE) {
     if(result != CURLM_BAD_HANDLE) {
       data = multi->easyp;
       data = multi->easyp;
-      while(data) {
-        singlesocket(multi, data);
+      while(data && !result) {
+        result = singlesocket(multi, data);
         data = data->next;
         data = data->next;
       }
       }
     }
     }
@@ -2590,10 +2612,13 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
         /* clear the bitmask only if not locked */
         /* clear the bitmask only if not locked */
         data->easy_conn->cselect_bits = 0;
         data->easy_conn->cselect_bits = 0;
 
 
-      if(CURLM_OK >= result)
+      if(CURLM_OK >= result) {
         /* get the socket(s) and check if the state has been changed since
         /* get the socket(s) and check if the state has been changed since
            last */
            last */
-        singlesocket(multi, data);
+        result = singlesocket(multi, data);
+        if(result)
+          return result;
+      }
 
 
       /* Now we fall-through and do the timer-based stuff, since we don't want
       /* Now we fall-through and do the timer-based stuff, since we don't want
          to force the user to have to deal with timeouts as long as at least
          to force the user to have to deal with timeouts as long as at least
@@ -2627,10 +2652,13 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
       result = multi_runsingle(multi, now, data);
       result = multi_runsingle(multi, now, data);
       sigpipe_restore(&pipe_st);
       sigpipe_restore(&pipe_st);
 
 
-      if(CURLM_OK >= result)
+      if(CURLM_OK >= result) {
         /* get the socket(s) and check if the state has been changed since
         /* get the socket(s) and check if the state has been changed since
            last */
            last */
-        singlesocket(multi, data);
+        result = singlesocket(multi, data);
+        if(result)
+          return result;
+      }
     }
     }
 
 
     /* Check if there's one (more) expired timer to deal with! This function
     /* Check if there's one (more) expired timer to deal with! This function
@@ -2924,7 +2952,6 @@ void Curl_expire(struct Curl_easy *data, time_t milli, expire_id id)
 {
 {
   struct Curl_multi *multi = data->multi;
   struct Curl_multi *multi = data->multi;
   struct curltime *nowp = &data->state.expiretime;
   struct curltime *nowp = &data->state.expiretime;
-  int rc;
   struct curltime set;
   struct curltime set;
 
 
   /* this is only interesting while there is still an associated multi struct
   /* this is only interesting while there is still an associated multi struct
@@ -2955,6 +2982,7 @@ void Curl_expire(struct Curl_easy *data, time_t milli, expire_id id)
        Compare if the new time is earlier, and only remove-old/add-new if it
        Compare if the new time is earlier, and only remove-old/add-new if it
        is. */
        is. */
     timediff_t diff = Curl_timediff(set, *nowp);
     timediff_t diff = Curl_timediff(set, *nowp);
+    int rc;
 
 
     if(diff > 0) {
     if(diff > 0) {
       /* The current splay tree entry is sooner than this new expiry time.
       /* The current splay tree entry is sooner than this new expiry time.
@@ -3000,7 +3028,6 @@ void Curl_expire_clear(struct Curl_easy *data)
 {
 {
   struct Curl_multi *multi = data->multi;
   struct Curl_multi *multi = data->multi;
   struct curltime *nowp = &data->state.expiretime;
   struct curltime *nowp = &data->state.expiretime;
-  int rc;
 
 
   /* this is only interesting while there is still an associated multi struct
   /* this is only interesting while there is still an associated multi struct
      remaining! */
      remaining! */
@@ -3011,6 +3038,7 @@ void Curl_expire_clear(struct Curl_easy *data)
     /* Since this is an cleared time, we must remove the previous entry from
     /* Since this is an cleared time, we must remove the previous entry from
        the splay tree */
        the splay tree */
     struct curl_llist *list = &data->state.timeoutlist;
     struct curl_llist *list = &data->state.timeoutlist;
+    int rc;
 
 
     rc = Curl_splayremovebyaddr(multi->timetree,
     rc = Curl_splayremovebyaddr(multi->timetree,
                                 &data->state.timenode,
                                 &data->state.timenode,
@@ -3100,12 +3128,15 @@ static void process_pending_handles(struct Curl_multi *multi)
   }
   }
 }
 }
 
 
-void Curl_set_in_callback(struct Curl_easy *easy, bool value)
+void Curl_set_in_callback(struct Curl_easy *data, bool value)
 {
 {
-  if(easy->multi_easy)
-    easy->multi_easy->in_callback = value;
-  else if(easy->multi)
-      easy->multi->in_callback = value;
+  /* might get called when there is no data pointer! */
+  if(data) {
+    if(data->multi_easy)
+      data->multi_easy->in_callback = value;
+    else if(data->multi)
+      data->multi->in_callback = value;
+  }
 }
 }
 
 
 bool Curl_is_in_callback(struct Curl_easy *easy)
 bool Curl_is_in_callback(struct Curl_easy *easy)

+ 7 - 1
lib/multihandle.h

@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *                             \___|\___/|_| \_\_____|
  *
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <[email protected]>, et al.
+ * Copyright (C) 1998 - 2018, Daniel Stenberg, <[email protected]>, et al.
  *
  *
  * This software is licensed as described in the file COPYING, which
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * you should have received as part of this distribution. The terms
@@ -23,6 +23,7 @@
  ***************************************************************************/
  ***************************************************************************/
 
 
 #include "conncache.h"
 #include "conncache.h"
+#include "psl.h"
 
 
 struct Curl_message {
 struct Curl_message {
   struct curl_llist_element list;
   struct curl_llist_element list;
@@ -97,6 +98,11 @@ struct Curl_multi {
   /* Hostname cache */
   /* Hostname cache */
   struct curl_hash hostcache;
   struct curl_hash hostcache;
 
 
+#ifdef USE_LIBPSL
+  /* PSL cache. */
+  struct PslCache psl;
+#endif
+
   /* timetree points to the splay-tree of time nodes to figure out expire
   /* timetree points to the splay-tree of time nodes to figure out expire
      times of all currently set timers */
      times of all currently set timers */
   struct Curl_tree *timetree;
   struct Curl_tree *timetree;

+ 2 - 2
lib/netrc.c

@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *                             \___|\___/|_| \_\_____|
  *
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <[email protected]>, et al.
+ * Copyright (C) 1998 - 2018, Daniel Stenberg, <[email protected]>, et al.
  *
  *
  * This software is licensed as described in the file COPYING, which
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * you should have received as part of this distribution. The terms
@@ -115,7 +115,7 @@ int Curl_parsenetrc(const char *host,
     char *tok;
     char *tok;
     char *tok_buf;
     char *tok_buf;
     bool done = FALSE;
     bool done = FALSE;
-    char netrcbuffer[256];
+    char netrcbuffer[4096];
     int  netrcbuffsize = (int)sizeof(netrcbuffer);
     int  netrcbuffsize = (int)sizeof(netrcbuffer);
 
 
     while(!done && fgets(netrcbuffer, netrcbuffsize, file)) {
     while(!done && fgets(netrcbuffer, netrcbuffsize, file)) {

+ 4 - 6
lib/pingpong.c

@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *                             \___|\___/|_| \_\_____|
  *
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <[email protected]>, et al.
+ * Copyright (C) 1998 - 2018, Daniel Stenberg, <[email protected]>, et al.
  *
  *
  * This software is licensed as described in the file COPYING, which
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * you should have received as part of this distribution. The terms
@@ -49,7 +49,6 @@ time_t Curl_pp_state_timeout(struct pingpong *pp)
   struct connectdata *conn = pp->conn;
   struct connectdata *conn = pp->conn;
   struct Curl_easy *data = conn->data;
   struct Curl_easy *data = conn->data;
   time_t timeout_ms; /* in milliseconds */
   time_t timeout_ms; /* in milliseconds */
-  time_t timeout2_ms; /* in milliseconds */
   long response_time = (data->set.server_response_timeout)?
   long response_time = (data->set.server_response_timeout)?
     data->set.server_response_timeout: pp->response_time;
     data->set.server_response_timeout: pp->response_time;
 
 
@@ -65,7 +64,7 @@ time_t Curl_pp_state_timeout(struct pingpong *pp)
 
 
   if(data->set.timeout) {
   if(data->set.timeout) {
     /* if timeout is requested, find out how much remaining time we have */
     /* if timeout is requested, find out how much remaining time we have */
-    timeout2_ms = data->set.timeout - /* timeout time */
+    time_t timeout2_ms = data->set.timeout - /* timeout time */
       Curl_timediff(Curl_now(), conn->now); /* spent time */
       Curl_timediff(Curl_now(), conn->now); /* spent time */
 
 
     /* pick the lowest number */
     /* pick the lowest number */
@@ -222,8 +221,7 @@ CURLcode Curl_pp_vsendf(struct pingpong *pp,
   }
   }
 
 
   if(conn->data->set.verbose)
   if(conn->data->set.verbose)
-    Curl_debug(conn->data, CURLINFO_HEADER_OUT,
-               s, (size_t)bytes_written, conn);
+    Curl_debug(conn->data, CURLINFO_HEADER_OUT, s, (size_t)bytes_written);
 
 
   if(bytes_written != (ssize_t)write_len) {
   if(bytes_written != (ssize_t)write_len) {
     /* the whole chunk was not sent, keep it around and adjust sizes */
     /* the whole chunk was not sent, keep it around and adjust sizes */
@@ -371,7 +369,7 @@ CURLcode Curl_pp_readresp(curl_socket_t sockfd,
 #endif
 #endif
             if(data->set.verbose)
             if(data->set.verbose)
               Curl_debug(data, CURLINFO_HEADER_IN,
               Curl_debug(data, CURLINFO_HEADER_IN,
-                         pp->linestart_resp, (size_t)perline, conn);
+                         pp->linestart_resp, (size_t)perline);
 
 
           /*
           /*
            * We pass all response-lines to the callback function registered
            * We pass all response-lines to the callback function registered

+ 5 - 4
lib/pipeline.c

@@ -6,7 +6,7 @@
  *                             \___|\___/|_| \_\_____|
  *                             \___|\___/|_| \_\_____|
  *
  *
  * Copyright (C) 2013, Linus Nielsen Feltzing, <[email protected]>
  * Copyright (C) 2013, Linus Nielsen Feltzing, <[email protected]>
- * Copyright (C) 2013 - 2017, Daniel Stenberg, <[email protected]>, et al.
+ * Copyright (C) 2013 - 2018, Daniel Stenberg, <[email protected]>, et al.
  *
  *
  * This software is licensed as described in the file COPYING, which
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * you should have received as part of this distribution. The terms
@@ -82,7 +82,8 @@ bool Curl_pipeline_penalized(struct Curl_easy *data,
       penalized = TRUE;
       penalized = TRUE;
 
 
     infof(data, "Conn: %ld (%p) Receive pipe weight: (%"
     infof(data, "Conn: %ld (%p) Receive pipe weight: (%"
-          CURL_FORMAT_CURL_OFF_T "/%zu), penalized: %s\n",
+          CURL_FORMAT_CURL_OFF_T "/%" CURL_FORMAT_CURL_OFF_T
+          "), penalized: %s\n",
           conn->connection_id, (void *)conn, recv_size,
           conn->connection_id, (void *)conn, recv_size,
           conn->chunk.datasize, penalized?"TRUE":"FALSE");
           conn->chunk.datasize, penalized?"TRUE":"FALSE");
     return penalized;
     return penalized;
@@ -109,8 +110,8 @@ CURLcode Curl_add_handle_to_pipeline(struct Curl_easy *handle,
   pipeline = &conn->send_pipe;
   pipeline = &conn->send_pipe;
 
 
   result = addHandleToPipeline(handle, pipeline);
   result = addHandleToPipeline(handle, pipeline);
-
-  if(pipeline == &conn->send_pipe && sendhead != conn->send_pipe.head) {
+  if((conn->bundle->multiuse == BUNDLE_PIPELINING) &&
+     (pipeline == &conn->send_pipe && sendhead != conn->send_pipe.head)) {
     /* this is a new one as head, expire it */
     /* this is a new one as head, expire it */
     Curl_pipeline_leave_write(conn); /* not in use yet */
     Curl_pipeline_leave_write(conn); /* not in use yet */
     Curl_expire(conn->send_pipe.head->ptr, 0, EXPIRE_RUN_NOW);
     Curl_expire(conn->send_pipe.head->ptr, 0, EXPIRE_RUN_NOW);

+ 2 - 2
lib/pop3.c

@@ -613,7 +613,6 @@ static CURLcode pop3_state_servergreet_resp(struct connectdata *conn,
   struct pop3_conn *pop3c = &conn->proto.pop3c;
   struct pop3_conn *pop3c = &conn->proto.pop3c;
   const char *line = data->state.buffer;
   const char *line = data->state.buffer;
   size_t len = strlen(line);
   size_t len = strlen(line);
-  size_t i;
 
 
   (void)instate; /* no use for this yet */
   (void)instate; /* no use for this yet */
 
 
@@ -625,6 +624,7 @@ static CURLcode pop3_state_servergreet_resp(struct connectdata *conn,
     /* Does the server support APOP authentication? */
     /* Does the server support APOP authentication? */
     if(len >= 4 && line[len - 2] == '>') {
     if(len >= 4 && line[len - 2] == '>') {
       /* Look for the APOP timestamp */
       /* Look for the APOP timestamp */
+      size_t i;
       for(i = 3; i < len - 2; ++i) {
       for(i = 3; i < len - 2; ++i) {
         if(line[i] == '<') {
         if(line[i] == '<') {
           /* Calculate the length of the timestamp */
           /* Calculate the length of the timestamp */
@@ -664,7 +664,6 @@ static CURLcode pop3_state_capa_resp(struct connectdata *conn, int pop3code,
   struct pop3_conn *pop3c = &conn->proto.pop3c;
   struct pop3_conn *pop3c = &conn->proto.pop3c;
   const char *line = data->state.buffer;
   const char *line = data->state.buffer;
   size_t len = strlen(line);
   size_t len = strlen(line);
-  size_t wordlen;
 
 
   (void)instate; /* no use for this yet */
   (void)instate; /* no use for this yet */
 
 
@@ -689,6 +688,7 @@ static CURLcode pop3_state_capa_resp(struct connectdata *conn, int pop3code,
       /* Loop through the data line */
       /* Loop through the data line */
       for(;;) {
       for(;;) {
         size_t llen;
         size_t llen;
+        size_t wordlen;
         unsigned int mechbit;
         unsigned int mechbit;
 
 
         while(len &&
         while(len &&

+ 20 - 19
lib/progress.c

@@ -35,22 +35,22 @@
    byte) */
    byte) */
 static void time2str(char *r, curl_off_t seconds)
 static void time2str(char *r, curl_off_t seconds)
 {
 {
-  curl_off_t d, h, m, s;
+  curl_off_t h;
   if(seconds <= 0) {
   if(seconds <= 0) {
     strcpy(r, "--:--:--");
     strcpy(r, "--:--:--");
     return;
     return;
   }
   }
   h = seconds / CURL_OFF_T_C(3600);
   h = seconds / CURL_OFF_T_C(3600);
   if(h <= CURL_OFF_T_C(99)) {
   if(h <= CURL_OFF_T_C(99)) {
-    m = (seconds - (h*CURL_OFF_T_C(3600))) / CURL_OFF_T_C(60);
-    s = (seconds - (h*CURL_OFF_T_C(3600))) - (m*CURL_OFF_T_C(60));
+    curl_off_t m = (seconds - (h*CURL_OFF_T_C(3600))) / CURL_OFF_T_C(60);
+    curl_off_t s = (seconds - (h*CURL_OFF_T_C(3600))) - (m*CURL_OFF_T_C(60));
     snprintf(r, 9, "%2" CURL_FORMAT_CURL_OFF_T ":%02" CURL_FORMAT_CURL_OFF_T
     snprintf(r, 9, "%2" CURL_FORMAT_CURL_OFF_T ":%02" CURL_FORMAT_CURL_OFF_T
              ":%02" CURL_FORMAT_CURL_OFF_T, h, m, s);
              ":%02" CURL_FORMAT_CURL_OFF_T, h, m, s);
   }
   }
   else {
   else {
     /* this equals to more than 99 hours, switch to a more suitable output
     /* this equals to more than 99 hours, switch to a more suitable output
        format to fit within the limits. */
        format to fit within the limits. */
-    d = seconds / CURL_OFF_T_C(86400);
+    curl_off_t d = seconds / CURL_OFF_T_C(86400);
     h = (seconds - (d*CURL_OFF_T_C(86400))) / CURL_OFF_T_C(3600);
     h = (seconds - (d*CURL_OFF_T_C(86400))) / CURL_OFF_T_C(3600);
     if(d <= CURL_OFF_T_C(999))
     if(d <= CURL_OFF_T_C(999))
       snprintf(r, 9, "%3" CURL_FORMAT_CURL_OFF_T
       snprintf(r, 9, "%3" CURL_FORMAT_CURL_OFF_T
@@ -369,25 +369,10 @@ void Curl_pgrsSetUploadSize(struct Curl_easy *data, curl_off_t size)
 int Curl_pgrsUpdate(struct connectdata *conn)
 int Curl_pgrsUpdate(struct connectdata *conn)
 {
 {
   struct curltime now;
   struct curltime now;
-  int result;
-  char max5[6][10];
-  curl_off_t dlpercen = 0;
-  curl_off_t ulpercen = 0;
-  curl_off_t total_percen = 0;
-  curl_off_t total_transfer;
-  curl_off_t total_expected_transfer;
   curl_off_t timespent;
   curl_off_t timespent;
   curl_off_t timespent_ms; /* milliseconds */
   curl_off_t timespent_ms; /* milliseconds */
   struct Curl_easy *data = conn->data;
   struct Curl_easy *data = conn->data;
   int nowindex = data->progress.speeder_c% CURR_TIME;
   int nowindex = data->progress.speeder_c% CURR_TIME;
-  int checkindex;
-  int countindex; /* amount of seconds stored in the speeder array */
-  char time_left[10];
-  char time_total[10];
-  char time_spent[10];
-  curl_off_t ulestimate = 0;
-  curl_off_t dlestimate = 0;
-  curl_off_t total_estimate;
   bool shownow = FALSE;
   bool shownow = FALSE;
   curl_off_t dl = data->progress.downloaded;
   curl_off_t dl = data->progress.downloaded;
   curl_off_t ul = data->progress.uploaded;
   curl_off_t ul = data->progress.uploaded;
@@ -413,6 +398,7 @@ int Curl_pgrsUpdate(struct connectdata *conn)
 
 
   /* Calculations done at most once a second, unless end is reached */
   /* Calculations done at most once a second, unless end is reached */
   if(data->progress.lastshow != now.tv_sec) {
   if(data->progress.lastshow != now.tv_sec) {
+    int countindex; /* amount of seconds stored in the speeder array */
     shownow = TRUE;
     shownow = TRUE;
 
 
     data->progress.lastshow = now.tv_sec;
     data->progress.lastshow = now.tv_sec;
@@ -438,6 +424,7 @@ int Curl_pgrsUpdate(struct connectdata *conn)
 
 
     /* first of all, we don't do this if there's no counted seconds yet */
     /* first of all, we don't do this if there's no counted seconds yet */
     if(countindex) {
     if(countindex) {
+      int checkindex;
       timediff_t span_ms;
       timediff_t span_ms;
 
 
       /* Get the index position to compare with the 'nowindex' position.
       /* Get the index position to compare with the 'nowindex' position.
@@ -477,8 +464,21 @@ int Curl_pgrsUpdate(struct connectdata *conn)
 
 
   if(!(data->progress.flags & PGRS_HIDE)) {
   if(!(data->progress.flags & PGRS_HIDE)) {
     /* progress meter has not been shut off */
     /* progress meter has not been shut off */
+    char max5[6][10];
+    curl_off_t dlpercen = 0;
+    curl_off_t ulpercen = 0;
+    curl_off_t total_percen = 0;
+    curl_off_t total_transfer;
+    curl_off_t total_expected_transfer;
+    char time_left[10];
+    char time_total[10];
+    char time_spent[10];
+    curl_off_t ulestimate = 0;
+    curl_off_t dlestimate = 0;
+    curl_off_t total_estimate;
 
 
     if(data->set.fxferinfo) {
     if(data->set.fxferinfo) {
+      int result;
       /* There's a callback set, call that */
       /* There's a callback set, call that */
       Curl_set_in_callback(data, true);
       Curl_set_in_callback(data, true);
       result = data->set.fxferinfo(data->set.progress_client,
       result = data->set.fxferinfo(data->set.progress_client,
@@ -492,6 +492,7 @@ int Curl_pgrsUpdate(struct connectdata *conn)
       return result;
       return result;
     }
     }
     if(data->set.fprogress) {
     if(data->set.fprogress) {
+      int result;
       /* The older deprecated callback is set, call that */
       /* The older deprecated callback is set, call that */
       Curl_set_in_callback(data, true);
       Curl_set_in_callback(data, true);
       result = data->set.fprogress(data->set.progress_client,
       result = data->set.fprogress(data->set.progress_client,

+ 0 - 13
lib/progress.h

@@ -56,23 +56,10 @@ timediff_t Curl_pgrsLimitWaitTime(curl_off_t cursize,
                                   struct curltime start,
                                   struct curltime start,
                                   struct curltime now);
                                   struct curltime now);
 
 
-/* Don't show progress for sizes smaller than: */
-#define LEAST_SIZE_PROGRESS BUFSIZE
-
-#define PROGRESS_DOWNLOAD (1<<0)
-#define PROGRESS_UPLOAD   (1<<1)
-#define PROGRESS_DOWN_AND_UP (PROGRESS_UPLOAD | PROGRESS_DOWNLOAD)
-
-#define PGRS_SHOW_DL (1<<0)
-#define PGRS_SHOW_UL (1<<1)
-#define PGRS_DONE_DL (1<<2)
-#define PGRS_DONE_UL (1<<3)
 #define PGRS_HIDE    (1<<4)
 #define PGRS_HIDE    (1<<4)
 #define PGRS_UL_SIZE_KNOWN (1<<5)
 #define PGRS_UL_SIZE_KNOWN (1<<5)
 #define PGRS_DL_SIZE_KNOWN (1<<6)
 #define PGRS_DL_SIZE_KNOWN (1<<6)
-
 #define PGRS_HEADERS_OUT (1<<7) /* set when the headers have been written */
 #define PGRS_HEADERS_OUT (1<<7) /* set when the headers have been written */
 
 
-
 #endif /* HEADER_CURL_PROGRESS_H */
 #endif /* HEADER_CURL_PROGRESS_H */
 
 

+ 111 - 0
lib/psl.c

@@ -0,0 +1,111 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2018, Daniel Stenberg, <[email protected]>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+
+#ifdef USE_LIBPSL
+
+#include "psl.h"
+#include "share.h"
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+void Curl_psl_destroy(struct PslCache *pslcache)
+{
+  if(pslcache->psl) {
+    if(pslcache->dynamic)
+      psl_free((psl_ctx_t *) pslcache->psl);
+    pslcache->psl = NULL;
+    pslcache->dynamic = FALSE;
+  }
+}
+
+static time_t now_seconds(void)
+{
+  struct curltime now = Curl_now();
+
+  return now.tv_sec;
+}
+
+const psl_ctx_t *Curl_psl_use(struct Curl_easy *easy)
+{
+  struct PslCache *pslcache = easy->psl;
+  const psl_ctx_t *psl;
+  time_t now;
+
+  if(!pslcache)
+    return NULL;
+
+  Curl_share_lock(easy, CURL_LOCK_DATA_PSL, CURL_LOCK_ACCESS_SHARED);
+  now = now_seconds();
+  if(!pslcache->psl || pslcache->expires <= now) {
+    /* Let a chance to other threads to do the job: avoids deadlock. */
+    Curl_share_unlock(easy, CURL_LOCK_DATA_PSL);
+
+    /* Update cache: this needs an exclusive lock. */
+    Curl_share_lock(easy, CURL_LOCK_DATA_PSL, CURL_LOCK_ACCESS_SINGLE);
+
+    /* Recheck in case another thread did the job. */
+    now = now_seconds();
+    if(!pslcache->psl || pslcache->expires <= now) {
+      bool dynamic = FALSE;
+      time_t expires = TIME_T_MAX;
+
+#if defined(PSL_VERSION_NUMBER) && PSL_VERSION_NUMBER >= 0x001000
+      psl = psl_latest(NULL);
+      dynamic = psl != NULL;
+      /* Take care of possible time computation overflow. */
+      expires = now < TIME_T_MAX - PSL_TTL? now + PSL_TTL: TIME_T_MAX;
+
+      /* Only get the built-in PSL if we do not already have the "latest". */
+      if(!psl && !pslcache->dynamic)
+#endif
+
+        psl = psl_builtin();
+
+      if(psl) {
+        Curl_psl_destroy(pslcache);
+        pslcache->psl = psl;
+        pslcache->dynamic = dynamic;
+        pslcache->expires = expires;
+      }
+    }
+    Curl_share_unlock(easy, CURL_LOCK_DATA_PSL);  /* Release exclusive lock. */
+    Curl_share_lock(easy, CURL_LOCK_DATA_PSL, CURL_LOCK_ACCESS_SHARED);
+  }
+  psl = pslcache->psl;
+  if(!psl)
+    Curl_share_unlock(easy, CURL_LOCK_DATA_PSL);
+  return psl;
+}
+
+void Curl_psl_release(struct Curl_easy *easy)
+{
+  Curl_share_unlock(easy, CURL_LOCK_DATA_PSL);
+}
+
+#endif /* USE_LIBPSL */

+ 47 - 0
lib/psl.h

@@ -0,0 +1,47 @@
+#ifndef HEADER_PSL_H
+#define HEADER_PSL_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2018, Daniel Stenberg, <[email protected]>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#ifdef USE_LIBPSL
+#include <libpsl.h>
+
+#define PSL_TTL (72 * 3600)     /* PSL time to live before a refresh. */
+
+struct PslCache {
+  const psl_ctx_t *psl; /* The PSL. */
+  time_t expires; /* Time this PSL life expires. */
+  bool dynamic; /* PSL should be released when no longer needed. */
+};
+
+const psl_ctx_t *Curl_psl_use(struct Curl_easy *easy);
+void Curl_psl_release(struct Curl_easy *easy);
+void Curl_psl_destroy(struct PslCache *pslcache);
+
+#else
+
+#define Curl_psl_use(easy) NULL
+#define Curl_psl_release(easy)
+#define Curl_psl_destroy(pslcache)
+
+#endif /* USE_LIBPSL */
+#endif /* HEADER_PSL_H */

+ 1 - 1
lib/rand.c

@@ -158,7 +158,7 @@ CURLcode Curl_rand_hex(struct Curl_easy *data, unsigned char *rnd,
   DEBUGASSERT(num > 1);
   DEBUGASSERT(num > 1);
 
 
 #ifdef __clang_analyzer__
 #ifdef __clang_analyzer__
-  /* This silences a scan-build warning about accesssing this buffer with
+  /* This silences a scan-build warning about accessing this buffer with
      uninitialized memory. */
      uninitialized memory. */
   memset(buffer, 0, sizeof(buffer));
   memset(buffer, 0, sizeof(buffer));
 #endif
 #endif

+ 2 - 4
lib/rtsp.c

@@ -218,8 +218,6 @@ static CURLcode rtsp_done(struct connectdata *conn,
   struct Curl_easy *data = conn->data;
   struct Curl_easy *data = conn->data;
   struct RTSP *rtsp = data->req.protop;
   struct RTSP *rtsp = data->req.protop;
   CURLcode httpStatus;
   CURLcode httpStatus;
-  long CSeq_sent;
-  long CSeq_recv;
 
 
   /* Bypass HTTP empty-reply checks on receive */
   /* Bypass HTTP empty-reply checks on receive */
   if(data->set.rtspreq == RTSPREQ_RECEIVE)
   if(data->set.rtspreq == RTSPREQ_RECEIVE)
@@ -229,8 +227,8 @@ static CURLcode rtsp_done(struct connectdata *conn,
 
 
   if(rtsp) {
   if(rtsp) {
     /* Check the sequence numbers */
     /* Check the sequence numbers */
-    CSeq_sent = rtsp->CSeq_sent;
-    CSeq_recv = rtsp->CSeq_recv;
+    long CSeq_sent = rtsp->CSeq_sent;
+    long CSeq_recv = rtsp->CSeq_recv;
     if((data->set.rtspreq != RTSPREQ_RECEIVE) && (CSeq_sent != CSeq_recv)) {
     if((data->set.rtspreq != RTSPREQ_RECEIVE) && (CSeq_sent != CSeq_recv)) {
       failf(data,
       failf(data,
             "The CSeq of this request %ld did not match the response %ld",
             "The CSeq of this request %ld did not match the response %ld",

+ 2 - 2
lib/security.c

@@ -390,7 +390,7 @@ int Curl_sec_read_msg(struct connectdata *conn, char *buffer,
 
 
   if(conn->data->set.verbose) {
   if(conn->data->set.verbose) {
     buf[decoded_len] = '\n';
     buf[decoded_len] = '\n';
-    Curl_debug(conn->data, CURLINFO_HEADER_IN, buf, decoded_len + 1, conn);
+    Curl_debug(conn->data, CURLINFO_HEADER_IN, buf, decoded_len + 1);
   }
   }
 
 
   buf[decoded_len] = '\0';
   buf[decoded_len] = '\0';
@@ -488,7 +488,7 @@ static CURLcode choose_mech(struct connectdata *conn)
 
 
   tmp_allocation = realloc(conn->app_data, mech->size);
   tmp_allocation = realloc(conn->app_data, mech->size);
   if(tmp_allocation == NULL) {
   if(tmp_allocation == NULL) {
-    failf(data, "Failed realloc of size %u", mech->size);
+    failf(data, "Failed realloc of size %zu", mech->size);
     mech = NULL;
     mech = NULL;
     return CURLE_OUT_OF_MEMORY;
     return CURLE_OUT_OF_MEMORY;
   }
   }

+ 5 - 3
lib/select.c

@@ -80,7 +80,6 @@ int Curl_wait_ms(int timeout_ms)
 #endif
 #endif
   struct curltime initial_tv;
   struct curltime initial_tv;
   int pending_ms;
   int pending_ms;
-  int error;
 #endif
 #endif
   int r = 0;
   int r = 0;
 
 
@@ -98,6 +97,7 @@ int Curl_wait_ms(int timeout_ms)
   pending_ms = timeout_ms;
   pending_ms = timeout_ms;
   initial_tv = Curl_now();
   initial_tv = Curl_now();
   do {
   do {
+    int error;
 #if defined(HAVE_POLL_FINE)
 #if defined(HAVE_POLL_FINE)
     r = poll(NULL, 0, pending_ms);
     r = poll(NULL, 0, pending_ms);
 #else
 #else
@@ -160,7 +160,6 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
 #endif
 #endif
   struct curltime initial_tv = {0, 0};
   struct curltime initial_tv = {0, 0};
   int pending_ms = 0;
   int pending_ms = 0;
-  int error;
   int r;
   int r;
   int ret;
   int ret;
 
 
@@ -210,6 +209,7 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
   }
   }
 
 
   do {
   do {
+    int error;
     if(timeout_ms < 0)
     if(timeout_ms < 0)
       pending_ms = -1;
       pending_ms = -1;
     else if(!timeout_ms)
     else if(!timeout_ms)
@@ -291,6 +291,7 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
   ptimeout = (timeout_ms < 0) ? NULL : &pending_tv;
   ptimeout = (timeout_ms < 0) ? NULL : &pending_tv;
 
 
   do {
   do {
+    int error;
     if(timeout_ms > 0) {
     if(timeout_ms > 0) {
       pending_tv.tv_sec = pending_ms / 1000;
       pending_tv.tv_sec = pending_ms / 1000;
       pending_tv.tv_usec = (pending_ms % 1000) * 1000;
       pending_tv.tv_usec = (pending_ms % 1000) * 1000;
@@ -402,7 +403,6 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
   bool fds_none = TRUE;
   bool fds_none = TRUE;
   unsigned int i;
   unsigned int i;
   int pending_ms = 0;
   int pending_ms = 0;
-  int error;
   int r;
   int r;
 
 
   if(ufds) {
   if(ufds) {
@@ -431,6 +431,7 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
 #ifdef HAVE_POLL_FINE
 #ifdef HAVE_POLL_FINE
 
 
   do {
   do {
+    int error;
     if(timeout_ms < 0)
     if(timeout_ms < 0)
       pending_ms = -1;
       pending_ms = -1;
     else if(!timeout_ms)
     else if(!timeout_ms)
@@ -502,6 +503,7 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
   ptimeout = (timeout_ms < 0) ? NULL : &pending_tv;
   ptimeout = (timeout_ms < 0) ? NULL : &pending_tv;
 
 
   do {
   do {
+    int error;
     if(timeout_ms > 0) {
     if(timeout_ms > 0) {
       pending_tv.tv_sec = pending_ms / 1000;
       pending_tv.tv_sec = pending_ms / 1000;
       pending_tv.tv_usec = (pending_ms % 1000) * 1000;
       pending_tv.tv_usec = (pending_ms % 1000) * 1000;

+ 5 - 43
lib/sendf.c

@@ -240,7 +240,7 @@ void Curl_infof(struct Curl_easy *data, const char *fmt, ...)
     vsnprintf(print_buffer, sizeof(print_buffer), fmt, ap);
     vsnprintf(print_buffer, sizeof(print_buffer), fmt, ap);
     va_end(ap);
     va_end(ap);
     len = strlen(print_buffer);
     len = strlen(print_buffer);
-    Curl_debug(data, CURLINFO_TEXT, print_buffer, len, NULL);
+    Curl_debug(data, CURLINFO_TEXT, print_buffer, len);
   }
   }
 }
 }
 
 
@@ -265,7 +265,7 @@ void Curl_failf(struct Curl_easy *data, const char *fmt, ...)
     if(data->set.verbose) {
     if(data->set.verbose) {
       error[len] = '\n';
       error[len] = '\n';
       error[++len] = '\0';
       error[++len] = '\0';
-      Curl_debug(data, CURLINFO_TEXT, error, len, NULL);
+      Curl_debug(data, CURLINFO_TEXT, error, len);
     }
     }
     va_end(ap);
     va_end(ap);
   }
   }
@@ -300,7 +300,7 @@ CURLcode Curl_sendf(curl_socket_t sockfd, struct connectdata *conn,
       break;
       break;
 
 
     if(data->set.verbose)
     if(data->set.verbose)
-      Curl_debug(data, CURLINFO_DATA_OUT, sptr, (size_t)bytes_written, conn);
+      Curl_debug(data, CURLINFO_DATA_OUT, sptr, (size_t)bytes_written);
 
 
     if((size_t)bytes_written != write_len) {
     if((size_t)bytes_written != write_len) {
       /* if not all was written at once, we must advance the pointer, decrease
       /* if not all was written at once, we must advance the pointer, decrease
@@ -762,8 +762,8 @@ CURLcode Curl_read(struct connectdata *conn, /* connection data */
 }
 }
 
 
 /* return 0 on success */
 /* return 0 on success */
-static int showit(struct Curl_easy *data, curl_infotype type,
-                  char *ptr, size_t size)
+int Curl_debug(struct Curl_easy *data, curl_infotype type,
+               char *ptr, size_t size)
 {
 {
   static const char s_infotype[CURLINFO_END][3] = {
   static const char s_infotype[CURLINFO_END][3] = {
     "* ", "< ", "> ", "{ ", "} ", "{ ", "} " };
     "* ", "< ", "> ", "{ ", "} ", "{ ", "} " };
@@ -834,41 +834,3 @@ static int showit(struct Curl_easy *data, curl_infotype type,
 #endif
 #endif
   return rc;
   return rc;
 }
 }
-
-int Curl_debug(struct Curl_easy *data, curl_infotype type,
-               char *ptr, size_t size,
-               struct connectdata *conn)
-{
-  int rc;
-  if(data->set.printhost && conn && conn->host.dispname) {
-    char buffer[160];
-    const char *t = NULL;
-    const char *w = "Data";
-    switch(type) {
-    case CURLINFO_HEADER_IN:
-      w = "Header";
-      /* FALLTHROUGH */
-    case CURLINFO_DATA_IN:
-      t = "from";
-      break;
-    case CURLINFO_HEADER_OUT:
-      w = "Header";
-      /* FALLTHROUGH */
-    case CURLINFO_DATA_OUT:
-      t = "to";
-      break;
-    default:
-      break;
-    }
-
-    if(t) {
-      snprintf(buffer, sizeof(buffer), "[%s %s %s]", w, t,
-               conn->host.dispname);
-      rc = showit(data, CURLINFO_TEXT, buffer, strlen(buffer));
-      if(rc)
-        return rc;
-    }
-  }
-  rc = showit(data, type, ptr, size);
-  return rc;
-}

+ 2 - 3
lib/sendf.h

@@ -84,9 +84,8 @@ CURLcode Curl_write_plain(struct connectdata *conn,
                           ssize_t *written);
                           ssize_t *written);
 
 
 /* the function used to output verbose information */
 /* the function used to output verbose information */
-int Curl_debug(struct Curl_easy *handle, curl_infotype type,
-               char *data, size_t size,
-               struct connectdata *conn);
+int Curl_debug(struct Curl_easy *data, curl_infotype type,
+               char *ptr, size_t size);
 
 
 
 
 #endif /* HEADER_CURL_SENDF_H */
 #endif /* HEADER_CURL_SENDF_H */

+ 40 - 3
lib/setopt.c

@@ -142,6 +142,25 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option,
                             va_arg(param, char *));
                             va_arg(param, char *));
     break;
     break;
 
 
+  case CURLOPT_TLS13_CIPHERS:
+    if(Curl_ssl_tls13_ciphersuites()) {
+      /* set preferred list of TLS 1.3 cipher suites */
+      result = Curl_setstropt(&data->set.str[STRING_SSL_CIPHER13_LIST_ORIG],
+                              va_arg(param, char *));
+    }
+    else
+      return CURLE_NOT_BUILT_IN;
+    break;
+  case CURLOPT_PROXY_TLS13_CIPHERS:
+    if(Curl_ssl_tls13_ciphersuites()) {
+      /* set preferred list of TLS 1.3 cipher suites for proxy */
+      result = Curl_setstropt(&data->set.str[STRING_SSL_CIPHER13_LIST_PROXY],
+                              va_arg(param, char *));
+    }
+    else
+      return CURLE_NOT_BUILT_IN;
+    break;
+
   case CURLOPT_RANDOM_FILE:
   case CURLOPT_RANDOM_FILE:
     /*
     /*
      * This is the path name to a file that contains random data to seed
      * This is the path name to a file that contains random data to seed
@@ -1584,14 +1603,19 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option,
      * String that holds the SSL crypto engine.
      * String that holds the SSL crypto engine.
      */
      */
     argptr = va_arg(param, char *);
     argptr = va_arg(param, char *);
-    if(argptr && argptr[0])
-      result = Curl_ssl_set_engine(data, argptr);
+    if(argptr && argptr[0]) {
+      result = Curl_setstropt(&data->set.str[STRING_SSL_ENGINE], argptr);
+      if(!result) {
+        result = Curl_ssl_set_engine(data, argptr);
+      }
+    }
     break;
     break;
 
 
   case CURLOPT_SSLENGINE_DEFAULT:
   case CURLOPT_SSLENGINE_DEFAULT:
     /*
     /*
      * flag to set engine as default.
      * flag to set engine as default.
      */
      */
+    Curl_setstropt(&data->set.str[STRING_SSL_ENGINE], NULL);
     result = Curl_ssl_set_engine_default(data);
     result = Curl_ssl_set_engine_default(data);
     break;
     break;
   case CURLOPT_CRLF:
   case CURLOPT_CRLF:
@@ -1942,6 +1966,11 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option,
       if(data->share->sslsession == data->state.session)
       if(data->share->sslsession == data->state.session)
         data->state.session = NULL;
         data->state.session = NULL;
 
 
+#ifdef USE_LIBPSL
+      if(data->psl == &data->share->psl)
+        data->psl = data->multi? &data->multi->psl: NULL;
+#endif
+
       data->share->dirty--;
       data->share->dirty--;
 
 
       Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
       Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
@@ -1973,8 +2002,12 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option,
         data->set.general_ssl.max_ssl_sessions = data->share->max_ssl_sessions;
         data->set.general_ssl.max_ssl_sessions = data->share->max_ssl_sessions;
         data->state.session = data->share->sslsession;
         data->state.session = data->share->sslsession;
       }
       }
-      Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
+#ifdef USE_LIBPSL
+      if(data->share->specifier & (1 << CURL_LOCK_DATA_PSL))
+        data->psl = &data->share->psl;
+#endif
 
 
+      Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
     }
     }
     /* check for host cache not needed,
     /* check for host cache not needed,
      * it will be done by curl_easy_perform */
      * it will be done by curl_easy_perform */
@@ -2562,6 +2595,10 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option,
   case CURLOPT_DNS_SHUFFLE_ADDRESSES:
   case CURLOPT_DNS_SHUFFLE_ADDRESSES:
     data->set.dns_shuffle_addresses = (0 != va_arg(param, long)) ? TRUE:FALSE;
     data->set.dns_shuffle_addresses = (0 != va_arg(param, long)) ? TRUE:FALSE;
     break;
     break;
+  case CURLOPT_DISALLOW_USERNAME_IN_URL:
+    data->set.disallow_username_in_url =
+      (0 != va_arg(param, long)) ? TRUE : FALSE;
+    break;
   default:
   default:
     /* unknown tag and its companion, just ignore: */
     /* unknown tag and its companion, just ignore: */
     result = CURLE_UNKNOWN_OPTION;
     result = CURLE_UNKNOWN_OPTION;

+ 8 - 11
lib/sha256.c

@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *                             \___|\___/|_| \_\_____|
  *
  *
- * Copyright (C) 1998 - 2016, Florin Petriuc, <[email protected]>
+ * Copyright (C) 1998 - 2018, Florin Petriuc, <[email protected]>
  *
  *
  * This software is licensed as described in the file COPYING, which
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * you should have received as part of this distribution. The terms
@@ -123,15 +123,11 @@ static const unsigned long K[64] = {
 #define Sigma1(x)   (S(x, 6) ^ S(x, 11) ^ S(x, 25))
 #define Sigma1(x)   (S(x, 6) ^ S(x, 11) ^ S(x, 25))
 #define Gamma0(x)   (S(x, 7) ^ S(x, 18) ^ R(x, 3))
 #define Gamma0(x)   (S(x, 7) ^ S(x, 18) ^ R(x, 3))
 #define Gamma1(x)   (S(x, 17) ^ S(x, 19) ^ R(x, 10))
 #define Gamma1(x)   (S(x, 17) ^ S(x, 19) ^ R(x, 10))
-#ifndef MIN
-#define MIN(x, y)   (((x) < (y)) ? (x) : (y))
-#endif
 /* compress 512-bits */
 /* compress 512-bits */
 static int sha256_compress(struct sha256_state *md,
 static int sha256_compress(struct sha256_state *md,
                            unsigned char *buf)
                            unsigned char *buf)
 {
 {
-  unsigned long S[8], W[64], t0, t1;
-  unsigned long t;
+  unsigned long S[8], W[64];
   int i;
   int i;
   /* copy state into S */
   /* copy state into S */
   for(i = 0; i < 8; i++) {
   for(i = 0; i < 8; i++) {
@@ -146,12 +142,13 @@ static int sha256_compress(struct sha256_state *md,
       W[i - 16];
       W[i - 16];
   }
   }
   /* Compress */
   /* Compress */
-#define RND(a,b,c,d,e,f,g,h,i)                    \
-  t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
-  t1 = Sigma0(a) + Maj(a, b, c);                  \
-  d += t0;                                        \
+#define RND(a,b,c,d,e,f,g,h,i)                                  \
+  unsigned long t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
+  unsigned long t1 = Sigma0(a) + Maj(a, b, c);                  \
+  d += t0;                                                      \
   h = t0 + t1;
   h = t0 + t1;
   for(i = 0; i < 64; ++i) {
   for(i = 0; i < 64; ++i) {
+    unsigned long t;
     RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i);
     RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i);
     t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4];
     t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4];
     S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t;
     S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t;
@@ -200,7 +197,7 @@ static int SHA256_Update(struct sha256_state *md,
       inlen -= block_size;
       inlen -= block_size;
     }
     }
     else {
     else {
-      n = MIN(inlen, (block_size - md->curlen));
+      n = CURLMIN(inlen, (block_size - md->curlen));
       memcpy(md->buf + md->curlen, in, n);
       memcpy(md->buf + md->curlen, in, n);
       md->curlen += n;
       md->curlen += n;
       in += n;
       in += n;

+ 10 - 1
lib/share.c

@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *                             \___|\___/|_| \_\_____|
  *
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <[email protected]>, et al.
+ * Copyright (C) 1998 - 2018, Daniel Stenberg, <[email protected]>, et al.
  *
  *
  * This software is licensed as described in the file COPYING, which
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * you should have received as part of this distribution. The terms
@@ -25,6 +25,7 @@
 #include <curl/curl.h>
 #include <curl/curl.h>
 #include "urldata.h"
 #include "urldata.h"
 #include "share.h"
 #include "share.h"
+#include "psl.h"
 #include "vtls/vtls.h"
 #include "vtls/vtls.h"
 #include "curl_memory.h"
 #include "curl_memory.h"
 
 
@@ -106,6 +107,12 @@ curl_share_setopt(struct Curl_share *share, CURLSHoption option, ...)
         res = CURLSHE_NOMEM;
         res = CURLSHE_NOMEM;
       break;
       break;
 
 
+    case CURL_LOCK_DATA_PSL:
+#ifndef USE_LIBPSL
+      res = CURLSHE_NOT_BUILT_IN;
+#endif
+      break;
+
     default:
     default:
       res = CURLSHE_BAD_OPTION;
       res = CURLSHE_BAD_OPTION;
     }
     }
@@ -205,6 +212,8 @@ curl_share_cleanup(struct Curl_share *share)
   }
   }
 #endif
 #endif
 
 
+  Curl_psl_destroy(&share->psl);
+
   if(share->unlockfunc)
   if(share->unlockfunc)
     share->unlockfunc(NULL, CURL_LOCK_DATA_SHARE, share->clientdata);
     share->unlockfunc(NULL, CURL_LOCK_DATA_SHARE, share->clientdata);
   free(share);
   free(share);

+ 5 - 1
lib/share.h

@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *                             \___|\___/|_| \_\_____|
  *
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <[email protected]>, et al.
+ * Copyright (C) 1998 - 2018, Daniel Stenberg, <[email protected]>, et al.
  *
  *
  * This software is licensed as described in the file COPYING, which
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * you should have received as part of this distribution. The terms
@@ -25,6 +25,7 @@
 #include "curl_setup.h"
 #include "curl_setup.h"
 #include <curl/curl.h>
 #include <curl/curl.h>
 #include "cookie.h"
 #include "cookie.h"
+#include "psl.h"
 #include "urldata.h"
 #include "urldata.h"
 #include "conncache.h"
 #include "conncache.h"
 
 
@@ -49,6 +50,9 @@ struct Curl_share {
 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
   struct CookieInfo *cookies;
   struct CookieInfo *cookies;
 #endif
 #endif
+#ifdef USE_LIBPSL
+  struct PslCache psl;
+#endif
 
 
   struct curl_ssl_session *sslsession;
   struct curl_ssl_session *sslsession;
   size_t max_ssl_sessions;
   size_t max_ssl_sessions;

+ 52 - 53
lib/smb.c

@@ -59,6 +59,7 @@
 static CURLcode smb_setup_connection(struct connectdata *conn);
 static CURLcode smb_setup_connection(struct connectdata *conn);
 static CURLcode smb_connect(struct connectdata *conn, bool *done);
 static CURLcode smb_connect(struct connectdata *conn, bool *done);
 static CURLcode smb_connection_state(struct connectdata *conn, bool *done);
 static CURLcode smb_connection_state(struct connectdata *conn, bool *done);
+static CURLcode smb_do(struct connectdata *conn, bool *done);
 static CURLcode smb_request_state(struct connectdata *conn, bool *done);
 static CURLcode smb_request_state(struct connectdata *conn, bool *done);
 static CURLcode smb_done(struct connectdata *conn, CURLcode status,
 static CURLcode smb_done(struct connectdata *conn, CURLcode status,
                          bool premature);
                          bool premature);
@@ -73,7 +74,7 @@ static CURLcode smb_parse_url_path(struct connectdata *conn);
 const struct Curl_handler Curl_handler_smb = {
 const struct Curl_handler Curl_handler_smb = {
   "SMB",                                /* scheme */
   "SMB",                                /* scheme */
   smb_setup_connection,                 /* setup_connection */
   smb_setup_connection,                 /* setup_connection */
-  ZERO_NULL,                            /* do_it */
+  smb_do,                               /* do_it */
   smb_done,                             /* done */
   smb_done,                             /* done */
   ZERO_NULL,                            /* do_more */
   ZERO_NULL,                            /* do_more */
   smb_connect,                          /* connect_it */
   smb_connect,                          /* connect_it */
@@ -98,7 +99,7 @@ const struct Curl_handler Curl_handler_smb = {
 const struct Curl_handler Curl_handler_smbs = {
 const struct Curl_handler Curl_handler_smbs = {
   "SMBS",                               /* scheme */
   "SMBS",                               /* scheme */
   smb_setup_connection,                 /* setup_connection */
   smb_setup_connection,                 /* setup_connection */
-  ZERO_NULL,                            /* do_it */
+  smb_do,                               /* do_it */
   smb_done,                             /* done */
   smb_done,                             /* done */
   ZERO_NULL,                            /* do_more */
   ZERO_NULL,                            /* do_more */
   smb_connect,                          /* connect_it */
   smb_connect,                          /* connect_it */
@@ -173,7 +174,6 @@ enum smb_req_state {
 /* SMB request data */
 /* SMB request data */
 struct smb_request {
 struct smb_request {
   enum smb_req_state state;
   enum smb_req_state state;
-  char *share;
   char *path;
   char *path;
   unsigned short tid; /* Even if we connect to the same tree as another */
   unsigned short tid; /* Even if we connect to the same tree as another */
   unsigned short fid; /* request, the tid will be different */
   unsigned short fid; /* request, the tid will be different */
@@ -182,7 +182,7 @@ struct smb_request {
 
 
 static void conn_state(struct connectdata *conn, enum smb_conn_state newstate)
 static void conn_state(struct connectdata *conn, enum smb_conn_state newstate)
 {
 {
-  struct smb_conn *smb = &conn->proto.smbc;
+  struct smb_conn *smbc = &conn->proto.smbc;
 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
   /* For debug purposes */
   /* For debug purposes */
   static const char * const names[] = {
   static const char * const names[] = {
@@ -194,12 +194,12 @@ static void conn_state(struct connectdata *conn, enum smb_conn_state newstate)
     /* LAST */
     /* LAST */
   };
   };
 
 
-  if(smb->state != newstate)
+  if(smbc->state != newstate)
     infof(conn->data, "SMB conn %p state change from %s to %s\n",
     infof(conn->data, "SMB conn %p state change from %s to %s\n",
-          (void *)smb, names[smb->state], names[newstate]);
+          (void *)smbc, names[smbc->state], names[newstate]);
 #endif
 #endif
 
 
-  smb->state = newstate;
+  smbc->state = newstate;
 }
 }
 
 
 static void request_state(struct connectdata *conn,
 static void request_state(struct connectdata *conn,
@@ -228,6 +228,8 @@ static void request_state(struct connectdata *conn,
   req->state = newstate;
   req->state = newstate;
 }
 }
 
 
+/* this should setup things in the connection, not in the easy
+   handle */
 static CURLcode smb_setup_connection(struct connectdata *conn)
 static CURLcode smb_setup_connection(struct connectdata *conn)
 {
 {
   struct smb_request *req;
   struct smb_request *req;
@@ -253,7 +255,6 @@ static CURLcode smb_connect(struct connectdata *conn, bool *done)
     return CURLE_LOGIN_DENIED;
     return CURLE_LOGIN_DENIED;
 
 
   /* Initialize the connection state */
   /* Initialize the connection state */
-  memset(smbc, 0, sizeof(*smbc));
   smbc->state = SMB_CONNECTING;
   smbc->state = SMB_CONNECTING;
   smbc->recv_buf = malloc(MAX_MESSAGE_SIZE);
   smbc->recv_buf = malloc(MAX_MESSAGE_SIZE);
   if(!smbc->recv_buf)
   if(!smbc->recv_buf)
@@ -366,7 +367,7 @@ static CURLcode smb_send(struct connectdata *conn, ssize_t len,
   ssize_t bytes_written;
   ssize_t bytes_written;
   CURLcode result;
   CURLcode result;
 
 
-  result = Curl_write(conn, FIRSTSOCKET, conn->data->state.uploadbuffer,
+  result = Curl_write(conn, FIRSTSOCKET, conn->data->state.ulbuf,
                       len, &bytes_written);
                       len, &bytes_written);
   if(result)
   if(result)
     return result;
     return result;
@@ -392,7 +393,7 @@ static CURLcode smb_flush(struct connectdata *conn)
     return CURLE_OK;
     return CURLE_OK;
 
 
   result = Curl_write(conn, FIRSTSOCKET,
   result = Curl_write(conn, FIRSTSOCKET,
-                      conn->data->state.uploadbuffer + smbc->sent,
+                      conn->data->state.ulbuf + smbc->sent,
                       len, &bytes_written);
                       len, &bytes_written);
   if(result)
   if(result)
     return result;
     return result;
@@ -408,9 +409,12 @@ static CURLcode smb_flush(struct connectdata *conn)
 static CURLcode smb_send_message(struct connectdata *conn, unsigned char cmd,
 static CURLcode smb_send_message(struct connectdata *conn, unsigned char cmd,
                                  const void *msg, size_t msg_len)
                                  const void *msg, size_t msg_len)
 {
 {
-  smb_format_message(conn, (struct smb_header *)conn->data->state.uploadbuffer,
+  CURLcode result = Curl_get_upload_buffer(conn->data);
+  if(result)
+    return result;
+  smb_format_message(conn, (struct smb_header *)conn->data->state.ulbuf,
                      cmd, msg_len);
                      cmd, msg_len);
-  memcpy(conn->data->state.uploadbuffer + sizeof(struct smb_header),
+  memcpy(conn->data->state.ulbuf + sizeof(struct smb_header),
          msg, msg_len);
          msg, msg_len);
 
 
   return smb_send(conn, sizeof(struct smb_header) + msg_len, 0);
   return smb_send(conn, sizeof(struct smb_header) + msg_len, 0);
@@ -475,11 +479,11 @@ static CURLcode smb_send_setup(struct connectdata *conn)
 
 
 static CURLcode smb_send_tree_connect(struct connectdata *conn)
 static CURLcode smb_send_tree_connect(struct connectdata *conn)
 {
 {
-  struct smb_request *req = conn->data->req.protop;
   struct smb_tree_connect msg;
   struct smb_tree_connect msg;
+  struct smb_conn *smbc = &conn->proto.smbc;
   char *p = msg.bytes;
   char *p = msg.bytes;
 
 
-  size_t byte_count = strlen(conn->host.name) + strlen(req->share);
+  size_t byte_count = strlen(conn->host.name) + strlen(smbc->share);
   byte_count += strlen(SERVICENAME) + 5; /* 2 nulls and 3 backslashes */
   byte_count += strlen(SERVICENAME) + 5; /* 2 nulls and 3 backslashes */
   if(byte_count > sizeof(msg.bytes))
   if(byte_count > sizeof(msg.bytes))
     return CURLE_FILESIZE_EXCEEDED;
     return CURLE_FILESIZE_EXCEEDED;
@@ -491,7 +495,7 @@ static CURLcode smb_send_tree_connect(struct connectdata *conn)
   MSGCAT("\\\\");
   MSGCAT("\\\\");
   MSGCAT(conn->host.name);
   MSGCAT(conn->host.name);
   MSGCAT("\\");
   MSGCAT("\\");
-  MSGCATNULL(req->share);
+  MSGCATNULL(smbc->share);
   MSGCATNULL(SERVICENAME); /* Match any type of service */
   MSGCATNULL(SERVICENAME); /* Match any type of service */
   byte_count = p - msg.bytes;
   byte_count = p - msg.bytes;
   msg.byte_count = smb_swap16((unsigned short)byte_count);
   msg.byte_count = smb_swap16((unsigned short)byte_count);
@@ -571,11 +575,15 @@ static CURLcode smb_send_read(struct connectdata *conn)
 
 
 static CURLcode smb_send_write(struct connectdata *conn)
 static CURLcode smb_send_write(struct connectdata *conn)
 {
 {
-  struct smb_write *msg = (struct smb_write *)conn->data->state.uploadbuffer;
+  struct smb_write *msg;
   struct smb_request *req = conn->data->req.protop;
   struct smb_request *req = conn->data->req.protop;
   curl_off_t offset = conn->data->req.offset;
   curl_off_t offset = conn->data->req.offset;
-
   curl_off_t upload_size = conn->data->req.size - conn->data->req.bytecount;
   curl_off_t upload_size = conn->data->req.size - conn->data->req.bytecount;
+  CURLcode result = Curl_get_upload_buffer(conn->data);
+  if(result)
+    return result;
+  msg = (struct smb_write *)conn->data->state.ulbuf;
+
   if(upload_size >= MAX_PAYLOAD_SIZE - 1) /* There is one byte of padding */
   if(upload_size >= MAX_PAYLOAD_SIZE - 1) /* There is one byte of padding */
     upload_size = MAX_PAYLOAD_SIZE - 1;
     upload_size = MAX_PAYLOAD_SIZE - 1;
 
 
@@ -602,9 +610,9 @@ static CURLcode smb_send_and_recv(struct connectdata *conn, void **msg)
 
 
   /* Check if there is data in the transfer buffer */
   /* Check if there is data in the transfer buffer */
   if(!smbc->send_size && smbc->upload_size) {
   if(!smbc->send_size && smbc->upload_size) {
-    int nread = smbc->upload_size > UPLOAD_BUFSIZE ? UPLOAD_BUFSIZE :
-      (int) smbc->upload_size;
-    conn->data->req.upload_fromhere = conn->data->state.uploadbuffer;
+    size_t nread = smbc->upload_size > UPLOAD_BUFSIZE ? UPLOAD_BUFSIZE :
+      smbc->upload_size;
+    conn->data->req.upload_fromhere = conn->data->state.ulbuf;
     result = Curl_fillreadbuffer(conn, nread, &nread);
     result = Curl_fillreadbuffer(conn, nread, &nread);
     if(result && result != CURLE_AGAIN)
     if(result && result != CURLE_AGAIN)
       return result;
       return result;
@@ -910,55 +918,52 @@ static CURLcode smb_request_state(struct connectdata *conn, bool *done)
 static CURLcode smb_done(struct connectdata *conn, CURLcode status,
 static CURLcode smb_done(struct connectdata *conn, CURLcode status,
                          bool premature)
                          bool premature)
 {
 {
-  struct smb_request *req = conn->data->req.protop;
-
   (void) premature;
   (void) premature;
-
-  Curl_safefree(req->share);
   Curl_safefree(conn->data->req.protop);
   Curl_safefree(conn->data->req.protop);
-
   return status;
   return status;
 }
 }
 
 
 static CURLcode smb_disconnect(struct connectdata *conn, bool dead)
 static CURLcode smb_disconnect(struct connectdata *conn, bool dead)
 {
 {
   struct smb_conn *smbc = &conn->proto.smbc;
   struct smb_conn *smbc = &conn->proto.smbc;
-  struct smb_request *req = conn->data->req.protop;
-
   (void) dead;
   (void) dead;
-
+  Curl_safefree(smbc->share);
   Curl_safefree(smbc->domain);
   Curl_safefree(smbc->domain);
   Curl_safefree(smbc->recv_buf);
   Curl_safefree(smbc->recv_buf);
-
-  /* smb_done is not always called, so cleanup the request */
-  if(req) {
-    Curl_safefree(req->share);
-  }
-
   return CURLE_OK;
   return CURLE_OK;
 }
 }
 
 
 static int smb_getsock(struct connectdata *conn, curl_socket_t *socks,
 static int smb_getsock(struct connectdata *conn, curl_socket_t *socks,
                        int numsocks)
                        int numsocks)
 {
 {
-  struct smb_conn *smbc = &conn->proto.smbc;
-
   if(!numsocks)
   if(!numsocks)
     return GETSOCK_BLANK;
     return GETSOCK_BLANK;
 
 
   socks[0] = conn->sock[FIRSTSOCKET];
   socks[0] = conn->sock[FIRSTSOCKET];
+  return GETSOCK_READSOCK(0) | GETSOCK_WRITESOCK(0);
+}
 
 
-  if(smbc->send_size || smbc->upload_size)
-    return GETSOCK_WRITESOCK(0);
+static CURLcode smb_do(struct connectdata *conn, bool *done)
+{
+  struct smb_conn *smbc = &conn->proto.smbc;
+  struct smb_request *req = conn->data->req.protop;
 
 
-  return GETSOCK_READSOCK(0);
+  *done = FALSE;
+  if(smbc->share) {
+    req->path = strchr(smbc->share, '\0');
+    if(req->path) {
+      req->path++;
+      return CURLE_OK;
+    }
+  }
+  return CURLE_URL_MALFORMAT;
 }
 }
 
 
 static CURLcode smb_parse_url_path(struct connectdata *conn)
 static CURLcode smb_parse_url_path(struct connectdata *conn)
 {
 {
   CURLcode result = CURLE_OK;
   CURLcode result = CURLE_OK;
   struct Curl_easy *data = conn->data;
   struct Curl_easy *data = conn->data;
-  struct smb_request *req = data->req.protop;
+  struct smb_conn *smbc = &conn->proto.smbc;
   char *path;
   char *path;
   char *slash;
   char *slash;
 
 
@@ -968,35 +973,29 @@ static CURLcode smb_parse_url_path(struct connectdata *conn)
     return result;
     return result;
 
 
   /* Parse the path for the share */
   /* Parse the path for the share */
-  req->share = strdup((*path == '/' || *path == '\\') ? path + 1 : path);
-  if(!req->share) {
-    free(path);
-
+  smbc->share = strdup((*path == '/' || *path == '\\') ? path + 1 : path);
+  free(path);
+  if(!smbc->share)
     return CURLE_OUT_OF_MEMORY;
     return CURLE_OUT_OF_MEMORY;
-  }
 
 
-  slash = strchr(req->share, '/');
+  slash = strchr(smbc->share, '/');
   if(!slash)
   if(!slash)
-    slash = strchr(req->share, '\\');
+    slash = strchr(smbc->share, '\\');
 
 
   /* The share must be present */
   /* The share must be present */
   if(!slash) {
   if(!slash) {
-    free(path);
-
+    Curl_safefree(smbc->share);
     return CURLE_URL_MALFORMAT;
     return CURLE_URL_MALFORMAT;
   }
   }
 
 
   /* Parse the path for the file path converting any forward slashes into
   /* Parse the path for the file path converting any forward slashes into
      backslashes */
      backslashes */
   *slash++ = 0;
   *slash++ = 0;
-  req->path = slash;
+
   for(; *slash; slash++) {
   for(; *slash; slash++) {
     if(*slash == '/')
     if(*slash == '/')
       *slash = '\\';
       *slash = '\\';
   }
   }
-
-  free(path);
-
   return CURLE_OK;
   return CURLE_OK;
 }
 }
 
 

+ 1 - 0
lib/smb.h

@@ -35,6 +35,7 @@ struct smb_conn {
   enum smb_conn_state state;
   enum smb_conn_state state;
   char *user;
   char *user;
   char *domain;
   char *domain;
+  char *share;
   unsigned char challenge[8];
   unsigned char challenge[8];
   unsigned int session_key;
   unsigned int session_key;
   unsigned short uid;
   unsigned short uid;

+ 3 - 2
lib/smtp.c

@@ -704,7 +704,6 @@ static CURLcode smtp_state_ehlo_resp(struct connectdata *conn, int smtpcode,
   struct smtp_conn *smtpc = &conn->proto.smtpc;
   struct smtp_conn *smtpc = &conn->proto.smtpc;
   const char *line = data->state.buffer;
   const char *line = data->state.buffer;
   size_t len = strlen(line);
   size_t len = strlen(line);
-  size_t wordlen;
 
 
   (void)instate; /* no use for this yet */
   (void)instate; /* no use for this yet */
 
 
@@ -739,6 +738,7 @@ static CURLcode smtp_state_ehlo_resp(struct connectdata *conn, int smtpcode,
       /* Loop through the data line */
       /* Loop through the data line */
       for(;;) {
       for(;;) {
         size_t llen;
         size_t llen;
+        size_t wordlen;
         unsigned int mechbit;
         unsigned int mechbit;
 
 
         while(len &&
         while(len &&
@@ -1563,13 +1563,14 @@ CURLcode Curl_smtp_escape_eob(struct connectdata *conn, const ssize_t nread)
   if(!scratch || data->set.crlf) {
   if(!scratch || data->set.crlf) {
     oldscratch = scratch;
     oldscratch = scratch;
 
 
-    scratch = newscratch = malloc(2 * data->set.buffer_size);
+    scratch = newscratch = malloc(2 * UPLOAD_BUFSIZE);
     if(!newscratch) {
     if(!newscratch) {
       failf(data, "Failed to alloc scratch buffer!");
       failf(data, "Failed to alloc scratch buffer!");
 
 
       return CURLE_OUT_OF_MEMORY;
       return CURLE_OUT_OF_MEMORY;
     }
     }
   }
   }
+  DEBUGASSERT(UPLOAD_BUFSIZE >= nread);
 
 
   /* Have we already sent part of the EOB? */
   /* Have we already sent part of the EOB? */
   eob_sent = smtp->eob;
   eob_sent = smtp->eob;

+ 7 - 7
lib/socks.c

@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *                             \___|\___/|_| \_\_____|
  *
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <[email protected]>, et al.
+ * Copyright (C) 1998 - 2018, Daniel Stenberg, <[email protected]>, et al.
  *
  *
  * This software is licensed as described in the file COPYING, which
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * you should have received as part of this distribution. The terms
@@ -57,10 +57,9 @@ int Curl_blockread_all(struct connectdata *conn, /* connection data */
   ssize_t nread;
   ssize_t nread;
   ssize_t allread = 0;
   ssize_t allread = 0;
   int result;
   int result;
-  timediff_t timeleft;
   *n = 0;
   *n = 0;
   for(;;) {
   for(;;) {
-    timeleft = Curl_timeleft(conn->data, NULL, TRUE);
+    timediff_t timeleft = Curl_timeleft(conn->data, NULL, TRUE);
     if(timeleft < 0) {
     if(timeleft < 0) {
       /* we already got the timeout */
       /* we already got the timeout */
       result = CURLE_OPERATION_TIMEDOUT;
       result = CURLE_OPERATION_TIMEDOUT;
@@ -116,7 +115,6 @@ CURLcode Curl_SOCKS4(const char *proxy_user,
 #define SOCKS4REQLEN 262
 #define SOCKS4REQLEN 262
   unsigned char socksreq[SOCKS4REQLEN]; /* room for SOCKS4 request incl. user
   unsigned char socksreq[SOCKS4REQLEN]; /* room for SOCKS4 request incl. user
                                            id */
                                            id */
-  int result;
   CURLcode code;
   CURLcode code;
   curl_socket_t sock = conn->sock[sockindex];
   curl_socket_t sock = conn->sock[sockindex];
   struct Curl_easy *data = conn->data;
   struct Curl_easy *data = conn->data;
@@ -220,11 +218,12 @@ CURLcode Curl_SOCKS4(const char *proxy_user,
    * Make connection
    * Make connection
    */
    */
   {
   {
+    int result;
     ssize_t actualread;
     ssize_t actualread;
     ssize_t written;
     ssize_t written;
     ssize_t hostnamelen = 0;
     ssize_t hostnamelen = 0;
-    int packetsize = 9 +
-      (int)strlen((char *)socksreq + 8); /* size including NUL */
+    ssize_t packetsize = 9 +
+      strlen((char *)socksreq + 8); /* size including NUL */
 
 
     /* If SOCKS4a, set special invalid IP address 0.0.0.x */
     /* If SOCKS4a, set special invalid IP address 0.0.0.x */
     if(protocol4a) {
     if(protocol4a) {
@@ -617,11 +616,11 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
     if(dns)
     if(dns)
       hp = dns->addr;
       hp = dns->addr;
     if(hp) {
     if(hp) {
-      int i;
       char buf[64];
       char buf[64];
       Curl_printable_address(hp, buf, sizeof(buf));
       Curl_printable_address(hp, buf, sizeof(buf));
 
 
       if(hp->ai_family == AF_INET) {
       if(hp->ai_family == AF_INET) {
+        int i;
         struct sockaddr_in *saddr_in;
         struct sockaddr_in *saddr_in;
         socksreq[len++] = 1; /* ATYP: IPv4 = 1 */
         socksreq[len++] = 1; /* ATYP: IPv4 = 1 */
 
 
@@ -634,6 +633,7 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
       }
       }
 #ifdef ENABLE_IPV6
 #ifdef ENABLE_IPV6
       else if(hp->ai_family == AF_INET6) {
       else if(hp->ai_family == AF_INET6) {
+        int i;
         struct sockaddr_in6 *saddr_in6;
         struct sockaddr_in6 *saddr_in6;
         socksreq[len++] = 4; /* ATYP: IPv6 = 4 */
         socksreq[len++] = 4; /* ATYP: IPv6 = 4 */
 
 

+ 1 - 2
lib/splay.c

@@ -41,7 +41,6 @@ struct Curl_tree *Curl_splay(struct curltime i,
                              struct Curl_tree *t)
                              struct Curl_tree *t)
 {
 {
   struct Curl_tree N, *l, *r, *y;
   struct Curl_tree N, *l, *r, *y;
-  long comp;
 
 
   if(t == NULL)
   if(t == NULL)
     return t;
     return t;
@@ -49,7 +48,7 @@ struct Curl_tree *Curl_splay(struct curltime i,
   l = r = &N;
   l = r = &N;
 
 
   for(;;) {
   for(;;) {
-    comp = compare(i, t->key);
+    long comp = compare(i, t->key);
     if(comp < 0) {
     if(comp < 0) {
       if(t->smaller == NULL)
       if(t->smaller == NULL)
         break;
         break;

+ 38 - 26
lib/ssh-libssh.c

@@ -204,11 +204,21 @@ static CURLcode sftp_error_to_CURLE(int err)
   return CURLE_SSH;
   return CURLE_SSH;
 }
 }
 
 
+#ifndef DEBUGBUILD
+#define state(x,y) mystate(x,y)
+#else
+#define state(x,y) mystate(x,y, __LINE__)
+#endif
+
 /*
 /*
  * SSH State machine related code
  * SSH State machine related code
  */
  */
 /* This is the ONLY way to change SSH state! */
 /* This is the ONLY way to change SSH state! */
-static void state(struct connectdata *conn, sshstate nowstate)
+static void mystate(struct connectdata *conn, sshstate nowstate
+#ifdef DEBUGBUILD
+                    , int lineno
+#endif
+  )
 {
 {
   struct ssh_conn *sshc = &conn->proto.sshc;
   struct ssh_conn *sshc = &conn->proto.sshc;
 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
@@ -278,8 +288,9 @@ static void state(struct connectdata *conn, sshstate nowstate)
 
 
 
 
   if(sshc->state != nowstate) {
   if(sshc->state != nowstate) {
-    infof(conn->data, "SSH %p state change from %s to %s\n",
-          (void *) sshc, names[sshc->state], names[nowstate]);
+    infof(conn->data, "SSH %p state change from %s to %s (line %d)\n",
+          (void *) sshc, names[sshc->state], names[nowstate],
+          lineno);
   }
   }
 #endif
 #endif
 
 
@@ -418,7 +429,7 @@ cleanup:
 }
 }
 
 
 #define MOVE_TO_ERROR_STATE(_r) { \
 #define MOVE_TO_ERROR_STATE(_r) { \
-  state(conn, SSH_SESSION_FREE); \
+  state(conn, SSH_SESSION_DISCONNECT); \
   sshc->actualcode = _r; \
   sshc->actualcode = _r; \
   rc = SSH_ERROR; \
   rc = SSH_ERROR; \
   break; \
   break; \
@@ -486,7 +497,7 @@ restart:
       if(rc < 0)
       if(rc < 0)
         return SSH_ERROR;
         return SSH_ERROR;
 
 
-    /* fallthrough */
+    /* FALLTHROUGH */
     case 1:
     case 1:
       sshc->kbd_state = 1;
       sshc->kbd_state = 1;
 
 
@@ -561,7 +572,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
       ssh_set_blocking(sshc->ssh_session, 0);
       ssh_set_blocking(sshc->ssh_session, 0);
 
 
       state(conn, SSH_S_STARTUP);
       state(conn, SSH_S_STARTUP);
-      /* fall-through */
+      /* FALLTHROUGH */
 
 
     case SSH_S_STARTUP:
     case SSH_S_STARTUP:
       rc = ssh_connect(sshc->ssh_session);
       rc = ssh_connect(sshc->ssh_session);
@@ -575,7 +586,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
 
 
       state(conn, SSH_HOSTKEY);
       state(conn, SSH_HOSTKEY);
 
 
-      /* fall-through */
+      /* FALLTHROUGH */
     case SSH_HOSTKEY:
     case SSH_HOSTKEY:
 
 
       rc = myssh_is_known(conn);
       rc = myssh_is_known(conn);
@@ -584,7 +595,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
       }
       }
 
 
       state(conn, SSH_AUTHLIST);
       state(conn, SSH_AUTHLIST);
-      /* fall through */
+      /* FALLTHROUGH */
     case SSH_AUTHLIST:{
     case SSH_AUTHLIST:{
         sshc->authed = FALSE;
         sshc->authed = FALSE;
 
 
@@ -607,6 +618,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
         sshc->auth_methods = ssh_userauth_list(sshc->ssh_session, NULL);
         sshc->auth_methods = ssh_userauth_list(sshc->ssh_session, NULL);
         if(sshc->auth_methods & SSH_AUTH_METHOD_PUBLICKEY) {
         if(sshc->auth_methods & SSH_AUTH_METHOD_PUBLICKEY) {
           state(conn, SSH_AUTH_PKEY_INIT);
           state(conn, SSH_AUTH_PKEY_INIT);
+          infof(data, "Authentication using SSH public key file\n");
         }
         }
         else if(sshc->auth_methods & SSH_AUTH_METHOD_GSSAPI_MIC) {
         else if(sshc->auth_methods & SSH_AUTH_METHOD_GSSAPI_MIC) {
           state(conn, SSH_AUTH_GSSAPI);
           state(conn, SSH_AUTH_GSSAPI);
@@ -651,6 +663,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
         if(rc != SSH_OK) {
         if(rc != SSH_OK) {
           failf(data, "Could not load private key file %s",
           failf(data, "Could not load private key file %s",
                 data->set.str[STRING_SSH_PRIVATE_KEY]);
                 data->set.str[STRING_SSH_PRIVATE_KEY]);
+          MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED);
           break;
           break;
         }
         }
 
 
@@ -659,8 +672,6 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
 
 
       }
       }
       else {
       else {
-        infof(data, "Authentication using SSH public key file\n");
-
         rc = ssh_userauth_publickey_auto(sshc->ssh_session, NULL,
         rc = ssh_userauth_publickey_auto(sshc->ssh_session, NULL,
                                          data->set.ssl.key_passwd);
                                          data->set.ssl.key_passwd);
         if(rc == SSH_AUTH_AGAIN) {
         if(rc == SSH_AUTH_AGAIN) {
@@ -748,7 +759,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
         MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED);
         MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED);
       }
       }
       state(conn, SSH_AUTH_PASS);
       state(conn, SSH_AUTH_PASS);
-      /* fall through */
+      /* FALLTHROUGH */
 
 
     case SSH_AUTH_PASS:
     case SSH_AUTH_PASS:
       rc = ssh_userauth_password(sshc->ssh_session, NULL, conn->passwd);
       rc = ssh_userauth_password(sshc->ssh_session, NULL, conn->passwd);
@@ -812,7 +823,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
         break;
         break;
       }
       }
       state(conn, SSH_SFTP_REALPATH);
       state(conn, SSH_SFTP_REALPATH);
-      /* fall through */
+      /* FALLTHROUGH */
     case SSH_SFTP_REALPATH:
     case SSH_SFTP_REALPATH:
       /*
       /*
        * Get the "home" directory
        * Get the "home" directory
@@ -1279,7 +1290,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
       if(sshc->readdir_attrs) {
       if(sshc->readdir_attrs) {
         sshc->readdir_filename = sshc->readdir_attrs->name;
         sshc->readdir_filename = sshc->readdir_attrs->name;
         sshc->readdir_longentry = sshc->readdir_attrs->longname;
         sshc->readdir_longentry = sshc->readdir_attrs->longname;
-        sshc->readdir_len = (int)strlen(sshc->readdir_filename);
+        sshc->readdir_len = strlen(sshc->readdir_filename);
 
 
         if(data->set.ftp_list_only) {
         if(data->set.ftp_list_only) {
           char *tmpLine;
           char *tmpLine;
@@ -1306,11 +1317,11 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
           if(data->set.verbose) {
           if(data->set.verbose) {
             Curl_debug(data, CURLINFO_DATA_OUT,
             Curl_debug(data, CURLINFO_DATA_OUT,
                        (char *)sshc->readdir_filename,
                        (char *)sshc->readdir_filename,
-                       sshc->readdir_len, conn);
+                       sshc->readdir_len);
           }
           }
         }
         }
         else {
         else {
-          sshc->readdir_currLen = (int)strlen(sshc->readdir_longentry);
+          sshc->readdir_currLen = strlen(sshc->readdir_longentry);
           sshc->readdir_totalLen = 80 + sshc->readdir_currLen;
           sshc->readdir_totalLen = 80 + sshc->readdir_currLen;
           sshc->readdir_line = calloc(sshc->readdir_totalLen, 1);
           sshc->readdir_line = calloc(sshc->readdir_totalLen, 1);
           if(!sshc->readdir_line) {
           if(!sshc->readdir_line) {
@@ -1371,12 +1382,12 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
         if(sshc->readdir_filename == NULL)
         if(sshc->readdir_filename == NULL)
           sshc->readdir_len = 0;
           sshc->readdir_len = 0;
         else
         else
-          sshc->readdir_len = (int)strlen(sshc->readdir_tmp);
+          sshc->readdir_len = strlen(sshc->readdir_tmp);
         sshc->readdir_longentry = NULL;
         sshc->readdir_longentry = NULL;
         sshc->readdir_filename = sshc->readdir_tmp;
         sshc->readdir_filename = sshc->readdir_tmp;
       }
       }
       else {
       else {
-        sshc->readdir_len = (int)strlen(sshc->readdir_link_attrs->name);
+        sshc->readdir_len = strlen(sshc->readdir_link_attrs->name);
         sshc->readdir_filename = sshc->readdir_link_attrs->name;
         sshc->readdir_filename = sshc->readdir_link_attrs->name;
         sshc->readdir_longentry = sshc->readdir_link_attrs->longname;
         sshc->readdir_longentry = sshc->readdir_link_attrs->longname;
       }
       }
@@ -1408,7 +1419,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
       sshc->readdir_longentry = NULL;
       sshc->readdir_longentry = NULL;
 
 
       state(conn, SSH_SFTP_READDIR_BOTTOM);
       state(conn, SSH_SFTP_READDIR_BOTTOM);
-      /* fall through */
+      /* FALLTHROUGH */
     case SSH_SFTP_READDIR_BOTTOM:
     case SSH_SFTP_READDIR_BOTTOM:
       sshc->readdir_currLen += snprintf(sshc->readdir_line +
       sshc->readdir_currLen += snprintf(sshc->readdir_line +
                                         sshc->readdir_currLen,
                                         sshc->readdir_currLen,
@@ -1423,7 +1434,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
         /* output debug output if that is requested */
         /* output debug output if that is requested */
         if(data->set.verbose) {
         if(data->set.verbose) {
           Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line,
           Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line,
-                     sshc->readdir_currLen, conn);
+                     sshc->readdir_currLen);
         }
         }
         data->req.bytecount += sshc->readdir_currLen;
         data->req.bytecount += sshc->readdir_currLen;
       }
       }
@@ -1740,7 +1751,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
         MOVE_TO_ERROR_STATE(CURLE_COULDNT_CONNECT);
         MOVE_TO_ERROR_STATE(CURLE_COULDNT_CONNECT);
       }
       }
       state(conn, SSH_SCP_DOWNLOAD);
       state(conn, SSH_SCP_DOWNLOAD);
-      /* fall through */
+      /* FALLTHROUGH */
 
 
     case SSH_SCP_DOWNLOAD:{
     case SSH_SCP_DOWNLOAD:{
         curl_off_t bytecount;
         curl_off_t bytecount;
@@ -1805,7 +1816,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
       ssh_set_blocking(sshc->ssh_session, 0);
       ssh_set_blocking(sshc->ssh_session, 0);
 
 
       state(conn, SSH_SESSION_DISCONNECT);
       state(conn, SSH_SESSION_DISCONNECT);
-      /* fall through */
+      /* FALLTHROUGH */
 
 
     case SSH_SESSION_DISCONNECT:
     case SSH_SESSION_DISCONNECT:
       /* during weird times when we've been prematurely aborted, the channel
       /* during weird times when we've been prematurely aborted, the channel
@@ -1822,7 +1833,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
       conn->data->state.most_recent_ftp_entrypath = NULL;
       conn->data->state.most_recent_ftp_entrypath = NULL;
 
 
       state(conn, SSH_SESSION_FREE);
       state(conn, SSH_SESSION_FREE);
-      /* fall through */
+      /* FALLTHROUGH */
     case SSH_SESSION_FREE:
     case SSH_SESSION_FREE:
       if(sshc->ssh_session) {
       if(sshc->ssh_session) {
         ssh_free(sshc->ssh_session);
         ssh_free(sshc->ssh_session);
@@ -2379,7 +2390,8 @@ static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
     /* Post quote commands are executed after the SFTP_CLOSE state to avoid
     /* Post quote commands are executed after the SFTP_CLOSE state to avoid
        errors that could happen due to open file handles during POSTQUOTE
        errors that could happen due to open file handles during POSTQUOTE
        operation */
        operation */
-    if(!status && !premature && conn->data->set.postquote) {
+    if(!status && !premature && conn->data->set.postquote &&
+       !conn->bits.retry) {
       sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT;
       sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT;
       state(conn, SSH_SFTP_CLOSE);
       state(conn, SSH_SFTP_CLOSE);
     }
     }
@@ -2437,7 +2449,7 @@ static ssize_t sftp_recv(struct connectdata *conn, int sockindex,
         return -1;
         return -1;
       }
       }
 
 
-      /* fall-through */
+      /* FALLTHROUGH */
     case 1:
     case 1:
       conn->proto.sshc.sftp_recv_state = 1;
       conn->proto.sshc.sftp_recv_state = 1;
 
 
@@ -2500,8 +2512,8 @@ static void sftp_quote(struct connectdata *conn)
       return;
       return;
     }
     }
     if(data->set.verbose) {
     if(data->set.verbose) {
-      Curl_debug(data, CURLINFO_HEADER_OUT, (char *) "PWD\n", 4, conn);
-      Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp), conn);
+      Curl_debug(data, CURLINFO_HEADER_OUT, (char *) "PWD\n", 4);
+      Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp));
     }
     }
     /* this sends an FTP-like "header" to the header callback so that the
     /* this sends an FTP-like "header" to the header callback so that the
        current directory can be read very similar to how it is read when
        current directory can be read very similar to how it is read when

+ 23 - 22
lib/ssh.c

@@ -659,7 +659,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
       libssh2_session_set_blocking(sshc->ssh_session, 0);
       libssh2_session_set_blocking(sshc->ssh_session, 0);
 
 
       state(conn, SSH_S_STARTUP);
       state(conn, SSH_S_STARTUP);
-      /* fall-through */
+      /* FALLTHROUGH */
 
 
     case SSH_S_STARTUP:
     case SSH_S_STARTUP:
       rc = libssh2_session_startup(sshc->ssh_session, (int)sock);
       rc = libssh2_session_startup(sshc->ssh_session, (int)sock);
@@ -675,7 +675,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
 
 
       state(conn, SSH_HOSTKEY);
       state(conn, SSH_HOSTKEY);
 
 
-      /* fall-through */
+      /* FALLTHROUGH */
     case SSH_HOSTKEY:
     case SSH_HOSTKEY:
       /*
       /*
        * Before we authenticate we should check the hostkey's fingerprint
        * Before we authenticate we should check the hostkey's fingerprint
@@ -1175,8 +1175,8 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
           break;
           break;
         }
         }
         if(data->set.verbose) {
         if(data->set.verbose) {
-          Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"PWD\n", 4, conn);
-          Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp), conn);
+          Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"PWD\n", 4);
+          Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp));
         }
         }
         /* this sends an FTP-like "header" to the header callback so that the
         /* this sends an FTP-like "header" to the header callback so that the
            current directory can be read very similar to how it is read when
            current directory can be read very similar to how it is read when
@@ -1933,17 +1933,17 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
       break;
       break;
 
 
     case SSH_SFTP_READDIR:
     case SSH_SFTP_READDIR:
-      sshc->readdir_len = libssh2_sftp_readdir_ex(sshc->sftp_handle,
-                                                  sshc->readdir_filename,
-                                                  PATH_MAX,
-                                                  sshc->readdir_longentry,
-                                                  PATH_MAX,
-                                                  &sshc->readdir_attrs);
-      if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
-        rc = LIBSSH2_ERROR_EAGAIN;
+      rc = libssh2_sftp_readdir_ex(sshc->sftp_handle,
+                                   sshc->readdir_filename,
+                                   PATH_MAX,
+                                   sshc->readdir_longentry,
+                                   PATH_MAX,
+                                   &sshc->readdir_attrs);
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
         break;
         break;
       }
       }
-      if(sshc->readdir_len > 0) {
+      if(rc > 0) {
+        sshc->readdir_len = (size_t) rc;
         sshc->readdir_filename[sshc->readdir_len] = '\0';
         sshc->readdir_filename[sshc->readdir_len] = '\0';
 
 
         if(data->set.ftp_list_only) {
         if(data->set.ftp_list_only) {
@@ -1970,11 +1970,11 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
           /* output debug output if that is requested */
           /* output debug output if that is requested */
           if(data->set.verbose) {
           if(data->set.verbose) {
             Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_filename,
             Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_filename,
-                       sshc->readdir_len, conn);
+                       sshc->readdir_len);
           }
           }
         }
         }
         else {
         else {
-          sshc->readdir_currLen = (int)strlen(sshc->readdir_longentry);
+          sshc->readdir_currLen = strlen(sshc->readdir_longentry);
           sshc->readdir_totalLen = 80 + sshc->readdir_currLen;
           sshc->readdir_totalLen = 80 + sshc->readdir_currLen;
           sshc->readdir_line = calloc(sshc->readdir_totalLen, 1);
           sshc->readdir_line = calloc(sshc->readdir_totalLen, 1);
           if(!sshc->readdir_line) {
           if(!sshc->readdir_line) {
@@ -2008,13 +2008,13 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
           break;
           break;
         }
         }
       }
       }
-      else if(sshc->readdir_len == 0) {
+      else if(rc == 0) {
         Curl_safefree(sshc->readdir_filename);
         Curl_safefree(sshc->readdir_filename);
         Curl_safefree(sshc->readdir_longentry);
         Curl_safefree(sshc->readdir_longentry);
         state(conn, SSH_SFTP_READDIR_DONE);
         state(conn, SSH_SFTP_READDIR_DONE);
         break;
         break;
       }
       }
-      else if(sshc->readdir_len <= 0) {
+      else if(rc < 0) {
         err = sftp_libssh2_last_error(sshc->sftp_session);
         err = sftp_libssh2_last_error(sshc->sftp_session);
         result = sftp_libssh2_error_to_CURLE(err);
         result = sftp_libssh2_error_to_CURLE(err);
         sshc->actualcode = result?result:CURLE_SSH;
         sshc->actualcode = result?result:CURLE_SSH;
@@ -2029,16 +2029,16 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
       break;
       break;
 
 
     case SSH_SFTP_READDIR_LINK:
     case SSH_SFTP_READDIR_LINK:
-      sshc->readdir_len =
+      rc =
         libssh2_sftp_symlink_ex(sshc->sftp_session,
         libssh2_sftp_symlink_ex(sshc->sftp_session,
                                 sshc->readdir_linkPath,
                                 sshc->readdir_linkPath,
                                 curlx_uztoui(strlen(sshc->readdir_linkPath)),
                                 curlx_uztoui(strlen(sshc->readdir_linkPath)),
                                 sshc->readdir_filename,
                                 sshc->readdir_filename,
                                 PATH_MAX, LIBSSH2_SFTP_READLINK);
                                 PATH_MAX, LIBSSH2_SFTP_READLINK);
-      if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
-        rc = LIBSSH2_ERROR_EAGAIN;
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
         break;
         break;
       }
       }
+      sshc->readdir_len = (size_t) rc;
       Curl_safefree(sshc->readdir_linkPath);
       Curl_safefree(sshc->readdir_linkPath);
 
 
       /* get room for the filename and extra output */
       /* get room for the filename and extra output */
@@ -2079,7 +2079,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
         /* output debug output if that is requested */
         /* output debug output if that is requested */
         if(data->set.verbose) {
         if(data->set.verbose) {
           Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line,
           Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line,
-                     sshc->readdir_currLen, conn);
+                     sshc->readdir_currLen);
         }
         }
         data->req.bytecount += sshc->readdir_currLen;
         data->req.bytecount += sshc->readdir_currLen;
       }
       }
@@ -3219,7 +3219,8 @@ static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
     /* Post quote commands are executed after the SFTP_CLOSE state to avoid
     /* Post quote commands are executed after the SFTP_CLOSE state to avoid
        errors that could happen due to open file handles during POSTQUOTE
        errors that could happen due to open file handles during POSTQUOTE
        operation */
        operation */
-    if(!status && !premature && conn->data->set.postquote) {
+    if(!status && !premature && conn->data->set.postquote &&
+       !conn->bits.retry) {
       sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT;
       sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT;
       state(conn, SSH_SFTP_CLOSE);
       state(conn, SSH_SFTP_CLOSE);
     }
     }

+ 2 - 2
lib/ssh.h

@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *                             \___|\___/|_| \_\_____|
  *
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <[email protected]>, et al.
+ * Copyright (C) 1998 - 2018, Daniel Stenberg, <[email protected]>, et al.
  *
  *
  * This software is licensed as described in the file COPYING, which
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * you should have received as part of this distribution. The terms
@@ -131,7 +131,7 @@ struct ssh_conn {
                                  quote command fails) */
                                  quote command fails) */
   char *homedir;              /* when doing SFTP we figure out home dir in the
   char *homedir;              /* when doing SFTP we figure out home dir in the
                                  connect phase */
                                  connect phase */
-  int readdir_len, readdir_totalLen, readdir_currLen;
+  size_t readdir_len, readdir_totalLen, readdir_currLen;
   char *readdir_line;
   char *readdir_line;
   char *readdir_linkPath;
   char *readdir_linkPath;
   /* end of READDIR stuff */
   /* end of READDIR stuff */

+ 0 - 1
lib/strcase.h

@@ -46,6 +46,5 @@ char Curl_raw_toupper(char in);
 #define checkprefix(a,b)    curl_strnequal(a,b,strlen(a))
 #define checkprefix(a,b)    curl_strnequal(a,b,strlen(a))
 
 
 void Curl_strntoupper(char *dest, const char *src, size_t n);
 void Curl_strntoupper(char *dest, const char *src, size_t n);
-char Curl_raw_toupper(char in);
 
 
 #endif /* HEADER_CURL_STRCASE_H */
 #endif /* HEADER_CURL_STRCASE_H */

+ 10 - 5
lib/system_win32.c

@@ -26,6 +26,7 @@
 
 
 #include <curl/curl.h>
 #include <curl/curl.h>
 #include "system_win32.h"
 #include "system_win32.h"
+#include "warnless.h"
 
 
 /* The last #include files should be: */
 /* The last #include files should be: */
 #include "curl_memory.h"
 #include "curl_memory.h"
@@ -134,8 +135,9 @@ bool Curl_verify_windows_version(const unsigned int majorVersion,
       break;
       break;
 
 
     case VERSION_LESS_THAN_EQUAL:
     case VERSION_LESS_THAN_EQUAL:
-      if(osver.dwMajorVersion <= majorVersion &&
-         osver.dwMinorVersion <= minorVersion)
+      if(osver.dwMajorVersion < majorVersion ||
+        (osver.dwMajorVersion == majorVersion &&
+         osver.dwMinorVersion <= minorVersion))
         matched = TRUE;
         matched = TRUE;
       break;
       break;
 
 
@@ -146,8 +148,9 @@ bool Curl_verify_windows_version(const unsigned int majorVersion,
       break;
       break;
 
 
     case VERSION_GREATER_THAN_EQUAL:
     case VERSION_GREATER_THAN_EQUAL:
-      if(osver.dwMajorVersion >= majorVersion &&
-         osver.dwMinorVersion >= minorVersion)
+      if(osver.dwMajorVersion > majorVersion ||
+        (osver.dwMajorVersion == majorVersion &&
+         osver.dwMinorVersion >= minorVersion))
         matched = TRUE;
         matched = TRUE;
       break;
       break;
 
 
@@ -278,7 +281,9 @@ HMODULE Curl_load_library(LPCTSTR filename)
 
 
   /* Attempt to find LoadLibraryEx() which is only available on Windows 2000
   /* Attempt to find LoadLibraryEx() which is only available on Windows 2000
      and above */
      and above */
-  pLoadLibraryEx = (LOADLIBRARYEX_FN) GetProcAddress(hKernel32, LOADLIBARYEX);
+  pLoadLibraryEx =
+    CURLX_FUNCTION_CAST(LOADLIBRARYEX_FN,
+                        (GetProcAddress(hKernel32, LOADLIBARYEX)));
 
 
   /* Detect if there's already a path in the filename and load the library if
   /* Detect if there's already a path in the filename and load the library if
      there is. Note: Both back slashes and forward slashes have been supported
      there is. Note: Both back slashes and forward slashes have been supported

+ 29 - 30
lib/telnet.c

@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *                             \___|\___/|_| \_\_____|
  *
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <[email protected]>, et al.
+ * Copyright (C) 1998 - 2018, Daniel Stenberg, <[email protected]>, et al.
  *
  *
  * This software is licensed as described in the file COPYING, which
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * you should have received as part of this distribution. The terms
@@ -52,10 +52,6 @@
 #include "connect.h"
 #include "connect.h"
 #include "progress.h"
 #include "progress.h"
 #include "system_win32.h"
 #include "system_win32.h"
-
-#define  TELOPTS
-#define  TELCMDS
-
 #include "arpa_telnet.h"
 #include "arpa_telnet.h"
 #include "select.h"
 #include "select.h"
 #include "strcase.h"
 #include "strcase.h"
@@ -74,10 +70,10 @@
     x->subend = x->subpointer;                          \
     x->subend = x->subpointer;                          \
     CURL_SB_CLEAR(x);                                   \
     CURL_SB_CLEAR(x);                                   \
   } WHILE_FALSE
   } WHILE_FALSE
-#define CURL_SB_ACCUM(x,c)                                   \
-  do {                                                       \
-    if(x->subpointer < (x->subbuffer + sizeof x->subbuffer)) \
-      *x->subpointer++ = (c);                                \
+#define CURL_SB_ACCUM(x,c)                                      \
+  do {                                                          \
+    if(x->subpointer < (x->subbuffer + sizeof(x->subbuffer)))   \
+      *x->subpointer++ = (c);                                   \
   } WHILE_FALSE
   } WHILE_FALSE
 
 
 #define  CURL_SB_GET(x) ((*x->subpointer++)&0xff)
 #define  CURL_SB_GET(x) ((*x->subpointer++)&0xff)
@@ -92,6 +88,7 @@
 #endif
 #endif
 
 
 #ifdef USE_WINSOCK
 #ifdef USE_WINSOCK
+typedef WSAEVENT (WINAPI *WSOCK2_EVENT)(void);
 typedef FARPROC WSOCK2_FUNC;
 typedef FARPROC WSOCK2_FUNC;
 static CURLcode check_wsock2(struct Curl_easy *data);
 static CURLcode check_wsock2(struct Curl_easy *data);
 #endif
 #endif
@@ -109,8 +106,10 @@ static void printoption(struct Curl_easy *data,
 
 
 static void negotiate(struct connectdata *);
 static void negotiate(struct connectdata *);
 static void send_negotiation(struct connectdata *, int cmd, int option);
 static void send_negotiation(struct connectdata *, int cmd, int option);
-static void set_local_option(struct connectdata *, int cmd, int option);
-static void set_remote_option(struct connectdata *, int cmd, int option);
+static void set_local_option(struct connectdata *conn,
+                             int option, int newstate);
+static void set_remote_option(struct connectdata *conn,
+                              int option, int newstate);
 
 
 static void printsub(struct Curl_easy *data,
 static void printsub(struct Curl_easy *data,
                      int direction, unsigned char *pointer,
                      int direction, unsigned char *pointer,
@@ -311,9 +310,6 @@ static void negotiate(struct connectdata *conn)
 static void printoption(struct Curl_easy *data,
 static void printoption(struct Curl_easy *data,
                         const char *direction, int cmd, int option)
                         const char *direction, int cmd, int option)
 {
 {
-  const char *fmt;
-  const char *opt;
-
   if(data->set.verbose) {
   if(data->set.verbose) {
     if(cmd == CURL_IAC) {
     if(cmd == CURL_IAC) {
       if(CURL_TELCMD_OK(option))
       if(CURL_TELCMD_OK(option))
@@ -322,9 +318,12 @@ static void printoption(struct Curl_easy *data,
         infof(data, "%s IAC %d\n", direction, option);
         infof(data, "%s IAC %d\n", direction, option);
     }
     }
     else {
     else {
-      fmt = (cmd == CURL_WILL) ? "WILL" : (cmd == CURL_WONT) ? "WONT" :
-        (cmd == CURL_DO) ? "DO" : (cmd == CURL_DONT) ? "DONT" : 0;
+      const char *fmt = (cmd == CURL_WILL) ? "WILL" :
+                        (cmd == CURL_WONT) ? "WONT" :
+                        (cmd == CURL_DO) ? "DO" :
+                        (cmd == CURL_DONT) ? "DONT" : 0;
       if(fmt) {
       if(fmt) {
+        const char *opt;
         if(CURL_TELOPT_OK(option))
         if(CURL_TELOPT_OK(option))
           opt = CURL_TELOPT(option);
           opt = CURL_TELOPT(option);
         else if(option == CURL_TELOPT_EXOPL)
         else if(option == CURL_TELOPT_EXOPL)
@@ -348,7 +347,6 @@ static void send_negotiation(struct connectdata *conn, int cmd, int option)
 {
 {
    unsigned char buf[3];
    unsigned char buf[3];
    ssize_t bytes_written;
    ssize_t bytes_written;
-   int err;
    struct Curl_easy *data = conn->data;
    struct Curl_easy *data = conn->data;
 
 
    buf[0] = CURL_IAC;
    buf[0] = CURL_IAC;
@@ -357,7 +355,7 @@ static void send_negotiation(struct connectdata *conn, int cmd, int option)
 
 
    bytes_written = swrite(conn->sock[FIRSTSOCKET], buf, 3);
    bytes_written = swrite(conn->sock[FIRSTSOCKET], buf, 3);
    if(bytes_written < 0) {
    if(bytes_written < 0) {
-     err = SOCKERRNO;
+     int err = SOCKERRNO;
      failf(data,"Sending data failed (%d)",err);
      failf(data,"Sending data failed (%d)",err);
    }
    }
 
 
@@ -710,9 +708,8 @@ static void printsub(struct Curl_easy *data,
                      unsigned char *pointer,    /* where suboption data is */
                      unsigned char *pointer,    /* where suboption data is */
                      size_t length)             /* length of suboption data */
                      size_t length)             /* length of suboption data */
 {
 {
-  unsigned int i = 0;
-
   if(data->set.verbose) {
   if(data->set.verbose) {
+    unsigned int i = 0;
     if(direction) {
     if(direction) {
       infof(data, "%s IAC SB ", (direction == '<')? "RCVD":"SENT");
       infof(data, "%s IAC SB ", (direction == '<')? "RCVD":"SENT");
       if(length >= 3) {
       if(length >= 3) {
@@ -764,7 +761,7 @@ static void printsub(struct Curl_easy *data,
     switch(pointer[0]) {
     switch(pointer[0]) {
     case CURL_TELOPT_NAWS:
     case CURL_TELOPT_NAWS:
       if(length > 4)
       if(length > 4)
-        infof(data, "Width: %hu ; Height: %hu", (pointer[1]<<8) | pointer[2],
+        infof(data, "Width: %d ; Height: %d", (pointer[1]<<8) | pointer[2],
               (pointer[3]<<8) | pointer[4]);
               (pointer[3]<<8) | pointer[4]);
       break;
       break;
     default:
     default:
@@ -928,7 +925,6 @@ static void suboption(struct connectdata *conn)
   unsigned char temp[2048];
   unsigned char temp[2048];
   ssize_t bytes_written;
   ssize_t bytes_written;
   size_t len;
   size_t len;
-  size_t tmplen;
   int err;
   int err;
   char varname[128] = "";
   char varname[128] = "";
   char varval[128] = "";
   char varval[128] = "";
@@ -968,7 +964,7 @@ static void suboption(struct connectdata *conn)
       len = 4;
       len = 4;
 
 
       for(v = tn->telnet_vars; v; v = v->next) {
       for(v = tn->telnet_vars; v; v = v->next) {
-        tmplen = (strlen(v->data) + 1);
+        size_t tmplen = (strlen(v->data) + 1);
         /* Add the variable only if it fits */
         /* Add the variable only if it fits */
         if(len + tmplen < (int)sizeof(temp)-6) {
         if(len + tmplen < (int)sizeof(temp)-6) {
           if(sscanf(v->data, "%127[^,],%127s", varname, varval)) {
           if(sscanf(v->data, "%127[^,],%127s", varname, varval)) {
@@ -1017,7 +1013,7 @@ static void sendsuboption(struct connectdata *conn, int option)
     CURL_SB_ACCUM(tn, CURL_IAC);
     CURL_SB_ACCUM(tn, CURL_IAC);
     CURL_SB_ACCUM(tn, CURL_SB);
     CURL_SB_ACCUM(tn, CURL_SB);
     CURL_SB_ACCUM(tn, CURL_TELOPT_NAWS);
     CURL_SB_ACCUM(tn, CURL_TELOPT_NAWS);
-    /* We must deal either with litte or big endian processors */
+    /* We must deal either with little or big endian processors */
     /* Window size must be sent according to the 'network order' */
     /* Window size must be sent according to the 'network order' */
     x = htons(tn->subopt_wsx);
     x = htons(tn->subopt_wsx);
     y = htons(tn->subopt_wsy);
     y = htons(tn->subopt_wsy);
@@ -1223,7 +1219,7 @@ CURLcode telrcv(struct connectdata *conn,
 static CURLcode send_telnet_data(struct connectdata *conn,
 static CURLcode send_telnet_data(struct connectdata *conn,
                                  char *buffer, ssize_t nread)
                                  char *buffer, ssize_t nread)
 {
 {
-  ssize_t escapes, i, j, outlen;
+  ssize_t escapes, i, outlen;
   unsigned char *outbuf = NULL;
   unsigned char *outbuf = NULL;
   CURLcode result = CURLE_OK;
   CURLcode result = CURLE_OK;
   ssize_t bytes_written, total_written;
   ssize_t bytes_written, total_written;
@@ -1238,6 +1234,7 @@ static CURLcode send_telnet_data(struct connectdata *conn,
   if(outlen == nread)
   if(outlen == nread)
     outbuf = (unsigned char *)buffer;
     outbuf = (unsigned char *)buffer;
   else {
   else {
+    ssize_t j;
     outbuf = malloc(nread + escapes + 1);
     outbuf = malloc(nread + escapes + 1);
     if(!outbuf)
     if(!outbuf)
       return CURLE_OUT_OF_MEMORY;
       return CURLE_OUT_OF_MEMORY;
@@ -1306,7 +1303,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
 #ifdef USE_WINSOCK
 #ifdef USE_WINSOCK
   HMODULE wsock2;
   HMODULE wsock2;
   WSOCK2_FUNC close_event_func;
   WSOCK2_FUNC close_event_func;
-  WSOCK2_FUNC create_event_func;
+  WSOCK2_EVENT create_event_func;
   WSOCK2_FUNC event_select_func;
   WSOCK2_FUNC event_select_func;
   WSOCK2_FUNC enum_netevents_func;
   WSOCK2_FUNC enum_netevents_func;
   WSAEVENT event_handle;
   WSAEVENT event_handle;
@@ -1315,7 +1312,6 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
   HANDLE objs[2];
   HANDLE objs[2];
   DWORD  obj_count;
   DWORD  obj_count;
   DWORD  wait_timeout;
   DWORD  wait_timeout;
-  DWORD waitret;
   DWORD readfile_read;
   DWORD readfile_read;
   int err;
   int err;
 #else
 #else
@@ -1361,7 +1357,9 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
   }
   }
 
 
   /* Grab a pointer to WSACreateEvent */
   /* Grab a pointer to WSACreateEvent */
-  create_event_func = GetProcAddress(wsock2, "WSACreateEvent");
+  create_event_func =
+    CURLX_FUNCTION_CAST(WSOCK2_EVENT,
+                        (GetProcAddress(wsock2, "WSACreateEvent")));
   if(create_event_func == NULL) {
   if(create_event_func == NULL) {
     failf(data, "failed to find WSACreateEvent function (%u)", GetLastError());
     failf(data, "failed to find WSACreateEvent function (%u)", GetLastError());
     FreeLibrary(wsock2);
     FreeLibrary(wsock2);
@@ -1438,7 +1436,8 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
   /* Keep on listening and act on events */
   /* Keep on listening and act on events */
   while(keepon) {
   while(keepon) {
     const DWORD buf_size = (DWORD)data->set.buffer_size;
     const DWORD buf_size = (DWORD)data->set.buffer_size;
-    waitret = WaitForMultipleObjects(obj_count, objs, FALSE, wait_timeout);
+    DWORD waitret = WaitForMultipleObjects(obj_count, objs,
+                                           FALSE, wait_timeout);
     switch(waitret) {
     switch(waitret) {
     case WAIT_TIMEOUT:
     case WAIT_TIMEOUT:
     {
     {
@@ -1607,7 +1606,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
     case 0:                     /* timeout */
     case 0:                     /* timeout */
       pfd[0].revents = 0;
       pfd[0].revents = 0;
       pfd[1].revents = 0;
       pfd[1].revents = 0;
-      /* fall through */
+      /* FALLTHROUGH */
     default:                    /* read! */
     default:                    /* read! */
       if(pfd[0].revents & POLLIN) {
       if(pfd[0].revents & POLLIN) {
         /* read data from network */
         /* read data from network */

+ 14 - 13
lib/tftp.c

@@ -451,7 +451,6 @@ static CURLcode tftp_send_first(tftp_state_data_t *state, tftp_event_t event)
   ssize_t senddata;
   ssize_t senddata;
   const char *mode = "octet";
   const char *mode = "octet";
   char *filename;
   char *filename;
-  char buf[64];
   struct Curl_easy *data = state->conn->data;
   struct Curl_easy *data = state->conn->data;
   CURLcode result = CURLE_OK;
   CURLcode result = CURLE_OK;
 
 
@@ -504,6 +503,7 @@ static CURLcode tftp_send_first(tftp_state_data_t *state, tftp_event_t event)
 
 
     /* optional addition of TFTP options */
     /* optional addition of TFTP options */
     if(!data->set.tftp_no_options) {
     if(!data->set.tftp_no_options) {
+      char buf[64];
       /* add tsize option */
       /* add tsize option */
       if(data->set.upload && (data->state.infilesize != -1))
       if(data->set.upload && (data->state.infilesize != -1))
         snprintf(buf, sizeof(buf), "%" CURL_FORMAT_CURL_OFF_T,
         snprintf(buf, sizeof(buf), "%" CURL_FORMAT_CURL_OFF_T,
@@ -710,10 +710,9 @@ static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event)
 {
 {
   struct Curl_easy *data = state->conn->data;
   struct Curl_easy *data = state->conn->data;
   ssize_t sbytes;
   ssize_t sbytes;
-  int rblock;
   CURLcode result = CURLE_OK;
   CURLcode result = CURLE_OK;
   struct SingleRequest *k = &data->req;
   struct SingleRequest *k = &data->req;
-  int cb; /* Bytes currently read */
+  size_t cb; /* Bytes currently read */
 
 
   switch(event) {
   switch(event) {
 
 
@@ -721,7 +720,7 @@ static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event)
   case TFTP_EVENT_OACK:
   case TFTP_EVENT_OACK:
     if(event == TFTP_EVENT_ACK) {
     if(event == TFTP_EVENT_ACK) {
       /* Ack the packet */
       /* Ack the packet */
-      rblock = getrpacketblock(&state->rpacket);
+      int rblock = getrpacketblock(&state->rpacket);
 
 
       if(rblock != state->block &&
       if(rblock != state->block &&
          /* There's a bug in tftpd-hpa that causes it to send us an ack for
          /* There's a bug in tftpd-hpa that causes it to send us an ack for
@@ -766,7 +765,7 @@ static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event)
     state->retries = 0;
     state->retries = 0;
     setpacketevent(&state->spacket, TFTP_EVENT_DATA);
     setpacketevent(&state->spacket, TFTP_EVENT_DATA);
     setpacketblock(&state->spacket, state->block);
     setpacketblock(&state->spacket, state->block);
-    if(state->block > 1 && state->sbytes < (int)state->blksize) {
+    if(state->block > 1 && state->sbytes < state->blksize) {
       state->state = TFTP_STATE_FIN;
       state->state = TFTP_STATE_FIN;
       return CURLE_OK;
       return CURLE_OK;
     }
     }
@@ -782,7 +781,7 @@ static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event)
                                    &cb);
                                    &cb);
       if(result)
       if(result)
         return result;
         return result;
-      state->sbytes += cb;
+      state->sbytes += (int)cb;
       state->conn->data->req.upload_fromhere += cb;
       state->conn->data->req.upload_fromhere += cb;
     } while(state->sbytes < state->blksize && cb != 0);
     } while(state->sbytes < state->blksize && cb != 0);
 
 
@@ -969,7 +968,7 @@ static CURLcode tftp_disconnect(struct connectdata *conn, bool dead_connection)
 static CURLcode tftp_connect(struct connectdata *conn, bool *done)
 static CURLcode tftp_connect(struct connectdata *conn, bool *done)
 {
 {
   tftp_state_data_t *state;
   tftp_state_data_t *state;
-  int blksize, rc;
+  int blksize;
 
 
   blksize = TFTP_BLKSIZE_DEFAULT;
   blksize = TFTP_BLKSIZE_DEFAULT;
 
 
@@ -1028,8 +1027,8 @@ static CURLcode tftp_connect(struct connectdata *conn, bool *done)
      * assume uses the same IP version and thus hopefully this works for both
      * assume uses the same IP version and thus hopefully this works for both
      * IPv4 and IPv6...
      * IPv4 and IPv6...
      */
      */
-    rc = bind(state->sockfd, (struct sockaddr *)&state->local_addr,
-              conn->ip_addr->ai_addrlen);
+    int rc = bind(state->sockfd, (struct sockaddr *)&state->local_addr,
+                  conn->ip_addr->ai_addrlen);
     if(rc) {
     if(rc) {
       failf(conn->data, "bind() failed; %s",
       failf(conn->data, "bind() failed; %s",
             Curl_strerror(conn, SOCKERRNO));
             Curl_strerror(conn, SOCKERRNO));
@@ -1148,8 +1147,11 @@ static CURLcode tftp_receive_packet(struct connectdata *conn)
     case TFTP_EVENT_ERROR:
     case TFTP_EVENT_ERROR:
     {
     {
       unsigned short error = getrpacketblock(&state->rpacket);
       unsigned short error = getrpacketblock(&state->rpacket);
+      char *str = (char *)state->rpacket.data + 4;
+      size_t strn = state->rbytes - 4;
       state->error = (tftp_error_t)error;
       state->error = (tftp_error_t)error;
-      infof(data, "%s\n", (const char *)state->rpacket.data + 4);
+      if(Curl_strnlen(str, strn) < strn)
+        infof(data, "TFTP error: %s\n", str);
       break;
       break;
     }
     }
     case TFTP_EVENT_ACK:
     case TFTP_EVENT_ACK:
@@ -1221,7 +1223,6 @@ static long tftp_state_timeout(struct connectdata *conn, tftp_event_t *event)
  **********************************************************/
  **********************************************************/
 static CURLcode tftp_multi_statemach(struct connectdata *conn, bool *done)
 static CURLcode tftp_multi_statemach(struct connectdata *conn, bool *done)
 {
 {
-  int                   rc;
   tftp_event_t          event;
   tftp_event_t          event;
   CURLcode              result = CURLE_OK;
   CURLcode              result = CURLE_OK;
   struct Curl_easy  *data = conn->data;
   struct Curl_easy  *data = conn->data;
@@ -1245,7 +1246,7 @@ static CURLcode tftp_multi_statemach(struct connectdata *conn, bool *done)
   }
   }
   else {
   else {
     /* no timeouts to handle, check our socket */
     /* no timeouts to handle, check our socket */
-    rc = SOCKET_READABLE(state->sockfd, 0);
+    int rc = SOCKET_READABLE(state->sockfd, 0);
 
 
     if(rc == -1) {
     if(rc == -1) {
       /* bail out */
       /* bail out */
@@ -1368,7 +1369,6 @@ static CURLcode tftp_setup_connection(struct connectdata * conn)
 {
 {
   struct Curl_easy *data = conn->data;
   struct Curl_easy *data = conn->data;
   char *type;
   char *type;
-  char command;
 
 
   conn->socktype = SOCK_DGRAM;   /* UDP datagram based */
   conn->socktype = SOCK_DGRAM;   /* UDP datagram based */
 
 
@@ -1380,6 +1380,7 @@ static CURLcode tftp_setup_connection(struct connectdata * conn)
     type = strstr(conn->host.rawalloc, ";mode=");
     type = strstr(conn->host.rawalloc, ";mode=");
 
 
   if(type) {
   if(type) {
+    char command;
     *type = 0;                   /* it was in the middle of the hostname */
     *type = 0;                   /* it was in the middle of the hostname */
     command = Curl_raw_toupper(type[6]);
     command = Curl_raw_toupper(type[6]);
 
 

+ 61 - 25
lib/transfer.c

@@ -106,15 +106,26 @@ char *Curl_checkheaders(const struct connectdata *conn,
 }
 }
 #endif
 #endif
 
 
+CURLcode Curl_get_upload_buffer(struct Curl_easy *data)
+{
+  if(!data->state.ulbuf) {
+    data->state.ulbuf = malloc(data->set.upload_buffer_size);
+    if(!data->state.ulbuf)
+      return CURLE_OUT_OF_MEMORY;
+  }
+  return CURLE_OK;
+}
+
 /*
 /*
  * This function will call the read callback to fill our buffer with data
  * This function will call the read callback to fill our buffer with data
  * to upload.
  * to upload.
  */
  */
-CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp)
+CURLcode Curl_fillreadbuffer(struct connectdata *conn, size_t bytes,
+                             size_t *nreadp)
 {
 {
   struct Curl_easy *data = conn->data;
   struct Curl_easy *data = conn->data;
-  size_t buffersize = (size_t)bytes;
-  int nread;
+  size_t buffersize = bytes;
+  size_t nread;
 #ifdef CURL_DOES_CONVERSIONS
 #ifdef CURL_DOES_CONVERSIONS
   bool sending_http_headers = FALSE;
   bool sending_http_headers = FALSE;
 
 
@@ -134,11 +145,9 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp)
     data->req.upload_fromhere += (8 + 2); /* 32bit hex + CRLF */
     data->req.upload_fromhere += (8 + 2); /* 32bit hex + CRLF */
   }
   }
 
 
-  /* this function returns a size_t, so we typecast to int to prevent warnings
-     with picky compilers */
   Curl_set_in_callback(data, true);
   Curl_set_in_callback(data, true);
-  nread = (int)data->state.fread_func(data->req.upload_fromhere, 1,
-                                      buffersize, data->state.in);
+  nread = data->state.fread_func(data->req.upload_fromhere, 1,
+                                 buffersize, data->state.in);
   Curl_set_in_callback(data, false);
   Curl_set_in_callback(data, false);
 
 
   if(nread == CURL_READFUNC_ABORT) {
   if(nread == CURL_READFUNC_ABORT) {
@@ -167,7 +176,7 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp)
 
 
     return CURLE_OK; /* nothing was read */
     return CURLE_OK; /* nothing was read */
   }
   }
-  else if((size_t)nread > buffersize) {
+  else if(nread > buffersize) {
     /* the read function returned a too large value */
     /* the read function returned a too large value */
     *nreadp = 0;
     *nreadp = 0;
     failf(data, "read function returned funny value");
     failf(data, "read function returned funny value");
@@ -226,13 +235,13 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp)
 #ifdef CURL_DOES_CONVERSIONS
 #ifdef CURL_DOES_CONVERSIONS
     {
     {
       CURLcode result;
       CURLcode result;
-      int length;
+      size_t length;
       if(data->set.prefer_ascii)
       if(data->set.prefer_ascii)
         /* translate the protocol and data */
         /* translate the protocol and data */
         length = nread;
         length = nread;
       else
       else
         /* just translate the protocol portion */
         /* just translate the protocol portion */
-        length = (int)strlen(hexbuffer);
+        length = strlen(hexbuffer);
       result = Curl_convert_to_network(data, data->req.upload_fromhere,
       result = Curl_convert_to_network(data, data->req.upload_fromhere,
                                        length);
                                        length);
       /* Curl_convert_to_network calls failf if unsuccessful */
       /* Curl_convert_to_network calls failf if unsuccessful */
@@ -247,7 +256,7 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp)
       infof(data, "Signaling end of chunked upload via terminating chunk.\n");
       infof(data, "Signaling end of chunked upload via terminating chunk.\n");
     }
     }
 
 
-    nread += (int)strlen(endofline_native); /* for the added end of line */
+    nread += strlen(endofline_native); /* for the added end of line */
   }
   }
 #ifdef CURL_DOES_CONVERSIONS
 #ifdef CURL_DOES_CONVERSIONS
   else if((data->set.prefer_ascii) && (!sending_http_headers)) {
   else if((data->set.prefer_ascii) && (!sending_http_headers)) {
@@ -444,7 +453,6 @@ static CURLcode readwrite_data(struct Curl_easy *data,
   CURLcode result = CURLE_OK;
   CURLcode result = CURLE_OK;
   ssize_t nread; /* number of bytes read */
   ssize_t nread; /* number of bytes read */
   size_t excess = 0; /* excess bytes read */
   size_t excess = 0; /* excess bytes read */
-  bool is_empty_data = FALSE;
   bool readmore = FALSE; /* used by RTP to signal for more data */
   bool readmore = FALSE; /* used by RTP to signal for more data */
   int maxloops = 100;
   int maxloops = 100;
 
 
@@ -454,6 +462,7 @@ static CURLcode readwrite_data(struct Curl_easy *data,
   /* This is where we loop until we have read everything there is to
   /* This is where we loop until we have read everything there is to
      read or we get a CURLE_AGAIN */
      read or we get a CURLE_AGAIN */
   do {
   do {
+    bool is_empty_data = FALSE;
     size_t buffersize = data->set.buffer_size;
     size_t buffersize = data->set.buffer_size;
     size_t bytestoread = buffersize;
     size_t bytestoread = buffersize;
 
 
@@ -660,14 +669,14 @@ static CURLcode readwrite_data(struct Curl_easy *data,
       if(data->set.verbose) {
       if(data->set.verbose) {
         if(k->badheader) {
         if(k->badheader) {
           Curl_debug(data, CURLINFO_DATA_IN, data->state.headerbuff,
           Curl_debug(data, CURLINFO_DATA_IN, data->state.headerbuff,
-                     (size_t)k->hbuflen, conn);
+                     (size_t)k->hbuflen);
           if(k->badheader == HEADER_PARTHEADER)
           if(k->badheader == HEADER_PARTHEADER)
             Curl_debug(data, CURLINFO_DATA_IN,
             Curl_debug(data, CURLINFO_DATA_IN,
-                       k->str, (size_t)nread, conn);
+                       k->str, (size_t)nread);
         }
         }
         else
         else
           Curl_debug(data, CURLINFO_DATA_IN,
           Curl_debug(data, CURLINFO_DATA_IN,
-                     k->str, (size_t)nread, conn);
+                     k->str, (size_t)nread);
       }
       }
 
 
 #ifndef CURL_DISABLE_HTTP
 #ifndef CURL_DISABLE_HTTP
@@ -797,7 +806,7 @@ static CURLcode readwrite_data(struct Curl_easy *data,
                                            nread);
                                            nread);
             }
             }
           }
           }
-          else
+          else if(!k->ignorebody)
             result = Curl_unencode_write(conn, k->writer_stack, k->str, nread);
             result = Curl_unencode_write(conn, k->writer_stack, k->str, nread);
         }
         }
         k->badheader = HEADER_NORMAL; /* taken care of now */
         k->badheader = HEADER_NORMAL; /* taken care of now */
@@ -869,6 +878,26 @@ static CURLcode done_sending(struct connectdata *conn,
   return CURLE_OK;
   return CURLE_OK;
 }
 }
 
 
+#ifdef WIN32
+#ifndef SIO_IDEAL_SEND_BACKLOG_QUERY
+#define SIO_IDEAL_SEND_BACKLOG_QUERY 0x4004747B
+#endif
+
+static void win_update_buffer_size(curl_socket_t sockfd)
+{
+  int result;
+  ULONG ideal;
+  DWORD ideallen;
+  result = WSAIoctl(sockfd, SIO_IDEAL_SEND_BACKLOG_QUERY, 0, 0,
+                    &ideal, sizeof(ideal), &ideallen, 0, 0);
+  if(result == 0) {
+    setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF,
+               (const char *)&ideal, sizeof(ideal));
+  }
+}
+#else
+#define win_update_buffer_size(x)
+#endif
 
 
 /*
 /*
  * Send data to upload to the server, when the socket is writable.
  * Send data to upload to the server, when the socket is writable.
@@ -894,13 +923,16 @@ static CURLcode readwrite_upload(struct Curl_easy *data,
     /* only read more data if there's no upload data already
     /* only read more data if there's no upload data already
        present in the upload buffer */
        present in the upload buffer */
     if(0 == k->upload_present) {
     if(0 == k->upload_present) {
+      result = Curl_get_upload_buffer(data);
+      if(result)
+        return result;
       /* init the "upload from here" pointer */
       /* init the "upload from here" pointer */
-      k->upload_fromhere = data->state.uploadbuffer;
+      k->upload_fromhere = data->state.ulbuf;
 
 
       if(!k->upload_done) {
       if(!k->upload_done) {
         /* HTTP pollution, this should be written nicer to become more
         /* HTTP pollution, this should be written nicer to become more
            protocol agnostic. */
            protocol agnostic. */
-        int fillcount;
+        size_t fillcount;
         struct HTTP *http = k->protop;
         struct HTTP *http = k->protop;
 
 
         if((k->exp100 == EXP100_SENDING_REQUEST) &&
         if((k->exp100 == EXP100_SENDING_REQUEST) &&
@@ -931,7 +963,7 @@ static CURLcode readwrite_upload(struct Curl_easy *data,
         if(result)
         if(result)
           return result;
           return result;
 
 
-        nread = (ssize_t)fillcount;
+        nread = fillcount;
       }
       }
       else
       else
         nread = 0; /* we're done uploading/reading */
         nread = 0; /* we're done uploading/reading */
@@ -959,7 +991,7 @@ static CURLcode readwrite_upload(struct Curl_easy *data,
          (data->set.crlf))) {
          (data->set.crlf))) {
         /* Do we need to allocate a scratch buffer? */
         /* Do we need to allocate a scratch buffer? */
         if(!data->state.scratch) {
         if(!data->state.scratch) {
-          data->state.scratch = malloc(2 * data->set.buffer_size);
+          data->state.scratch = malloc(2 * UPLOAD_BUFSIZE);
           if(!data->state.scratch) {
           if(!data->state.scratch) {
             failf(data, "Failed to alloc scratch buffer!");
             failf(data, "Failed to alloc scratch buffer!");
 
 
@@ -1020,14 +1052,15 @@ static CURLcode readwrite_upload(struct Curl_easy *data,
                         k->upload_fromhere, /* buffer pointer */
                         k->upload_fromhere, /* buffer pointer */
                         k->upload_present,  /* buffer size */
                         k->upload_present,  /* buffer size */
                         &bytes_written);    /* actually sent */
                         &bytes_written);    /* actually sent */
-
     if(result)
     if(result)
       return result;
       return result;
 
 
+    win_update_buffer_size(conn->writesockfd);
+
     if(data->set.verbose)
     if(data->set.verbose)
       /* show the data before we change the pointer upload_fromhere */
       /* show the data before we change the pointer upload_fromhere */
       Curl_debug(data, CURLINFO_DATA_OUT, k->upload_fromhere,
       Curl_debug(data, CURLINFO_DATA_OUT, k->upload_fromhere,
-                 (size_t)bytes_written, conn);
+                 (size_t)bytes_written);
 
 
     k->writebytecount += bytes_written;
     k->writebytecount += bytes_written;
 
 
@@ -1050,7 +1083,10 @@ static CURLcode readwrite_upload(struct Curl_easy *data,
     }
     }
     else {
     else {
       /* we've uploaded that buffer now */
       /* we've uploaded that buffer now */
-      k->upload_fromhere = data->state.uploadbuffer;
+      result = Curl_get_upload_buffer(data);
+      if(result)
+        return result;
+      k->upload_fromhere = data->state.ulbuf;
       k->upload_present = 0; /* no more bytes left */
       k->upload_present = 0; /* no more bytes left */
 
 
       if(k->upload_done) {
       if(k->upload_done) {
@@ -1482,7 +1518,7 @@ static size_t strlen_url(const char *url, bool relative)
     switch(*ptr) {
     switch(*ptr) {
     case '?':
     case '?':
       left = FALSE;
       left = FALSE;
-      /* fall through */
+      /* FALLTHROUGH */
     default:
     default:
       if(urlchar_needs_escaping(*ptr))
       if(urlchar_needs_escaping(*ptr))
         newlen += 2;
         newlen += 2;
@@ -1527,7 +1563,7 @@ static void strcpy_url(char *output, const char *url, bool relative)
     switch(*iptr) {
     switch(*iptr) {
     case '?':
     case '?':
       left = FALSE;
       left = FALSE;
-      /* fall through */
+      /* FALLTHROUGH */
     default:
     default:
       if(urlchar_needs_escaping(*iptr)) {
       if(urlchar_needs_escaping(*iptr)) {
         snprintf(optr, 4, "%%%02x", *iptr);
         snprintf(optr, 4, "%%%02x", *iptr);

+ 3 - 1
lib/transfer.h

@@ -51,9 +51,11 @@ int Curl_single_getsock(const struct connectdata *conn,
                         curl_socket_t *socks,
                         curl_socket_t *socks,
                         int numsocks);
                         int numsocks);
 CURLcode Curl_readrewind(struct connectdata *conn);
 CURLcode Curl_readrewind(struct connectdata *conn);
-CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp);
+CURLcode Curl_fillreadbuffer(struct connectdata *conn, size_t bytes,
+                             size_t *nreadp);
 CURLcode Curl_retry_request(struct connectdata *conn, char **url);
 CURLcode Curl_retry_request(struct connectdata *conn, char **url);
 bool Curl_meets_timecondition(struct Curl_easy *data, time_t timeofdoc);
 bool Curl_meets_timecondition(struct Curl_easy *data, time_t timeofdoc);
+CURLcode Curl_get_upload_buffer(struct Curl_easy *data);
 
 
 /* This sets up a forthcoming transfer */
 /* This sets up a forthcoming transfer */
 void
 void

+ 106 - 113
lib/url.c

@@ -127,7 +127,6 @@ bool curl_win32_idn_to_ascii(const char *in, char **out);
 
 
 static void conn_free(struct connectdata *conn);
 static void conn_free(struct connectdata *conn);
 static void free_fixed_hostname(struct hostname *host);
 static void free_fixed_hostname(struct hostname *host);
-static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke);
 static CURLcode parse_url_login(struct Curl_easy *data,
 static CURLcode parse_url_login(struct Curl_easy *data,
                                 struct connectdata *conn,
                                 struct connectdata *conn,
                                 char **userptr, char **passwdptr,
                                 char **userptr, char **passwdptr,
@@ -368,11 +367,9 @@ CURLcode Curl_close(struct Curl_easy *data)
 
 
   Curl_safefree(data->state.buffer);
   Curl_safefree(data->state.buffer);
   Curl_safefree(data->state.headerbuff);
   Curl_safefree(data->state.headerbuff);
-
+  Curl_safefree(data->state.ulbuf);
   Curl_flush_cookies(data, 1);
   Curl_flush_cookies(data, 1);
-
   Curl_digest_cleanup(data);
   Curl_digest_cleanup(data);
-
   Curl_safefree(data->info.contenttype);
   Curl_safefree(data->info.contenttype);
   Curl_safefree(data->info.wouldredirect);
   Curl_safefree(data->info.wouldredirect);
 
 
@@ -535,6 +532,7 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data)
   set->expect_100_timeout = 1000L; /* Wait for a second by default. */
   set->expect_100_timeout = 1000L; /* Wait for a second by default. */
   set->sep_headers = TRUE; /* separated header lists by default */
   set->sep_headers = TRUE; /* separated header lists by default */
   set->buffer_size = READBUFFER_SIZE;
   set->buffer_size = READBUFFER_SIZE;
+  set->upload_buffer_size = UPLOAD_BUFSIZE;
   set->happy_eyeballs_timeout = CURL_HET_DEFAULT;
   set->happy_eyeballs_timeout = CURL_HET_DEFAULT;
 
 
   Curl_http2_init_userset(set);
   Curl_http2_init_userset(set);
@@ -734,20 +732,23 @@ static void conn_free(struct connectdata *conn)
  * primary connection, like when freeing room in the connection cache or
  * primary connection, like when freeing room in the connection cache or
  * killing of a dead old connection.
  * killing of a dead old connection.
  *
  *
+ * A connection needs an easy handle when closing down. We support this passed
+ * in separately since the connection to get closed here is often already
+ * disassociated from an easy handle.
+ *
  * This function MUST NOT reset state in the Curl_easy struct if that
  * This function MUST NOT reset state in the Curl_easy struct if that
  * isn't strictly bound to the life-time of *this* particular connection.
  * isn't strictly bound to the life-time of *this* particular connection.
  *
  *
  */
  */
 
 
-CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection)
+CURLcode Curl_disconnect(struct Curl_easy *data,
+                         struct connectdata *conn, bool dead_connection)
 {
 {
-  struct Curl_easy *data;
   if(!conn)
   if(!conn)
     return CURLE_OK; /* this is closed and fine already */
     return CURLE_OK; /* this is closed and fine already */
-  data = conn->data;
 
 
   if(!data) {
   if(!data) {
-    DEBUGF(fprintf(stderr, "DISCONNECT without easy handle, ignoring\n"));
+    DEBUGF(infof(data, "DISCONNECT without easy handle, ignoring\n"));
     return CURLE_OK;
     return CURLE_OK;
   }
   }
 
 
@@ -755,13 +756,12 @@ CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection)
    * If this connection isn't marked to force-close, leave it open if there
    * If this connection isn't marked to force-close, leave it open if there
    * are other users of it
    * are other users of it
    */
    */
-  if(!conn->bits.close &&
-     (conn->send_pipe.size + conn->recv_pipe.size)) {
-    DEBUGF(infof(data, "Curl_disconnect, usecounter: %d\n",
-                 conn->send_pipe.size + conn->recv_pipe.size));
+  if(CONN_INUSE(conn) && !dead_connection) {
+    DEBUGF(infof(data, "Curl_disconnect when inuse: %zu\n", CONN_INUSE(conn)));
     return CURLE_OK;
     return CURLE_OK;
   }
   }
 
 
+  conn->data = data;
   if(conn->dns_entry != NULL) {
   if(conn->dns_entry != NULL) {
     Curl_resolv_unlock(data, conn->dns_entry);
     Curl_resolv_unlock(data, conn->dns_entry);
     conn->dns_entry = NULL;
     conn->dns_entry = NULL;
@@ -787,16 +787,12 @@ CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection)
   free_fixed_hostname(&conn->http_proxy.host);
   free_fixed_hostname(&conn->http_proxy.host);
   free_fixed_hostname(&conn->socks_proxy.host);
   free_fixed_hostname(&conn->socks_proxy.host);
 
 
+  DEBUGASSERT(conn->data == data);
+  /* this assumes that the pointer is still there after the connection was
+     detected from the cache */
   Curl_ssl_close(conn, FIRSTSOCKET);
   Curl_ssl_close(conn, FIRSTSOCKET);
 
 
-  /* 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);
-  }
-
   conn_free(conn);
   conn_free(conn);
-
   return CURLE_OK;
   return CURLE_OK;
 }
 }
 
 
@@ -848,6 +844,7 @@ static int IsPipeliningPossible(const struct Curl_easy *handle,
   return avail;
   return avail;
 }
 }
 
 
+/* Returns non-zero if a handle was removed */
 int Curl_removeHandleFromPipeline(struct Curl_easy *handle,
 int Curl_removeHandleFromPipeline(struct Curl_easy *handle,
                                   struct curl_llist *pipeline)
                                   struct curl_llist *pipeline)
 {
 {
@@ -884,6 +881,16 @@ static void Curl_printPipeline(struct curl_llist *pipeline)
 static struct Curl_easy* gethandleathead(struct curl_llist *pipeline)
 static struct Curl_easy* gethandleathead(struct curl_llist *pipeline)
 {
 {
   struct curl_llist_element *curr = pipeline->head;
   struct curl_llist_element *curr = pipeline->head;
+#ifdef DEBUGBUILD
+  {
+    struct curl_llist_element *p = pipeline->head;
+    while(p) {
+      struct Curl_easy *e = p->ptr;
+      DEBUGASSERT(GOOD_EASY_HANDLE(e));
+      p = p->next;
+    }
+  }
+#endif
   if(curr) {
   if(curr) {
     return (struct Curl_easy *) curr->ptr;
     return (struct Curl_easy *) curr->ptr;
   }
   }
@@ -896,41 +903,22 @@ static struct Curl_easy* gethandleathead(struct curl_llist *pipeline)
 void Curl_getoff_all_pipelines(struct Curl_easy *data,
 void Curl_getoff_all_pipelines(struct Curl_easy *data,
                                struct connectdata *conn)
                                struct connectdata *conn)
 {
 {
-  bool recv_head = (conn->readchannel_inuse &&
-                    Curl_recvpipe_head(data, conn));
-  bool send_head = (conn->writechannel_inuse &&
-                    Curl_sendpipe_head(data, conn));
-
-  if(Curl_removeHandleFromPipeline(data, &conn->recv_pipe) && recv_head)
-    Curl_pipeline_leave_read(conn);
-  if(Curl_removeHandleFromPipeline(data, &conn->send_pipe) && send_head)
-    Curl_pipeline_leave_write(conn);
-}
-
-static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke)
-{
-  struct curl_llist_element *curr;
-
-  if(!pipeline)
+  if(!conn->bundle)
     return;
     return;
+  if(conn->bundle->multiuse == BUNDLE_PIPELINING) {
+    bool recv_head = (conn->readchannel_inuse &&
+                      Curl_recvpipe_head(data, conn));
+    bool send_head = (conn->writechannel_inuse &&
+                      Curl_sendpipe_head(data, conn));
 
 
-  curr = pipeline->head;
-  while(curr) {
-    struct curl_llist_element *next = curr->next;
-    struct Curl_easy *data = (struct Curl_easy *) curr->ptr;
-
-#ifdef DEBUGBUILD /* debug-only code */
-    if(data->magic != CURLEASY_MAGIC_NUMBER) {
-      /* MAJOR BADNESS */
-      infof(data, "signalPipeClose() found BAAD easy handle\n");
-    }
-#endif
-
-    if(pipe_broke)
-      data->state.pipe_broke = TRUE;
-    Curl_multi_handlePipeBreak(data);
-    Curl_llist_remove(pipeline, curr, NULL);
-    curr = next;
+    if(Curl_removeHandleFromPipeline(data, &conn->recv_pipe) && recv_head)
+      Curl_pipeline_leave_read(conn);
+    if(Curl_removeHandleFromPipeline(data, &conn->send_pipe) && send_head)
+      Curl_pipeline_leave_write(conn);
+  }
+  else {
+    (void)Curl_removeHandleFromPipeline(data, &conn->recv_pipe);
+    (void)Curl_removeHandleFromPipeline(data, &conn->send_pipe);
   }
   }
 }
 }
 
 
@@ -959,12 +947,13 @@ static bool extract_if_dead(struct connectdata *conn,
                             struct Curl_easy *data)
                             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) {
+  if(!pipeLen && !CONN_INUSE(conn)) {
     /* The check for a dead socket makes sense only if there are no
     /* The check for a dead socket makes sense only if there are no
        handles in pipeline and the connection isn't already marked in
        handles in pipeline and the connection isn't already marked in
        use */
        use */
     bool dead;
     bool dead;
 
 
+    conn->data = data;
     if(conn->handler->connection_check) {
     if(conn->handler->connection_check) {
       /* The protocol has a special method for checking the state of the
       /* The protocol has a special method for checking the state of the
          connection. Use it to check if the connection is dead. */
          connection. Use it to check if the connection is dead. */
@@ -979,9 +968,9 @@ static bool extract_if_dead(struct connectdata *conn,
     }
     }
 
 
     if(dead) {
     if(dead) {
-      conn->data = data;
       infof(data, "Connection %ld seems to be dead!\n", conn->connection_id);
       infof(data, "Connection %ld seems to be dead!\n", conn->connection_id);
       Curl_conncache_remove_conn(conn, FALSE);
       Curl_conncache_remove_conn(conn, FALSE);
+      conn->data = NULL; /* detach */
       return TRUE;
       return TRUE;
     }
     }
   }
   }
@@ -1025,7 +1014,7 @@ static void prune_dead_connections(struct Curl_easy *data)
     while(Curl_conncache_foreach(data, data->state.conn_cache, &prune,
     while(Curl_conncache_foreach(data, data->state.conn_cache, &prune,
                                  call_extract_if_dead)) {
                                  call_extract_if_dead)) {
       /* disconnect it */
       /* disconnect it */
-      (void)Curl_disconnect(prune.extracted, /* dead_connection */TRUE);
+      (void)Curl_disconnect(data, prune.extracted, /* dead_connection */TRUE);
     }
     }
     data->state.conn_cache->last_cleanup = now;
     data->state.conn_cache->last_cleanup = now;
   }
   }
@@ -1139,7 +1128,7 @@ ConnectionExists(struct Curl_easy *data,
 
 
       if(extract_if_dead(check, data)) {
       if(extract_if_dead(check, data)) {
         /* disconnect it */
         /* disconnect it */
-        (void)Curl_disconnect(check, /* dead_connection */TRUE);
+        (void)Curl_disconnect(data, check, /* dead_connection */TRUE);
         continue;
         continue;
       }
       }
 
 
@@ -1267,12 +1256,12 @@ ConnectionExists(struct Curl_easy *data,
         }
         }
       }
       }
 
 
-      if(!canpipe && check->inuse)
+      if(!canpipe && CONN_INUSE(check))
         /* this request can't be pipelined but the checked connection is
         /* this request can't be pipelined but the checked connection is
            already in use so we skip it */
            already in use so we skip it */
         continue;
         continue;
 
 
-      if((check->inuse) && (check->data->multi != needle->data->multi))
+      if(CONN_INUSE(check) && (check->data->multi != needle->data->multi))
         /* this could be subject for pipeline/multiplex use, but only
         /* this could be subject for pipeline/multiplex use, but only
            if they belong to the same multi handle */
            if they belong to the same multi handle */
         continue;
         continue;
@@ -1464,7 +1453,7 @@ ConnectionExists(struct Curl_easy *data,
 
 
   if(chosen) {
   if(chosen) {
     /* mark it as used before releasing the lock */
     /* mark it as used before releasing the lock */
-    chosen->inuse = TRUE;
+    chosen->data = data; /* own it! */
     Curl_conncache_unlock(needle);
     Curl_conncache_unlock(needle);
     *usethis = chosen;
     *usethis = chosen;
     return TRUE; /* yes, we found one to use! */
     return TRUE; /* yes, we found one to use! */
@@ -1554,7 +1543,11 @@ int Curl_protocol_getsock(struct connectdata *conn,
 {
 {
   if(conn->handler->proto_getsock)
   if(conn->handler->proto_getsock)
     return conn->handler->proto_getsock(conn, socks, numsocks);
     return conn->handler->proto_getsock(conn, socks, numsocks);
-  return GETSOCK_BLANK;
+  /* Backup getsock logic. Since there is a live socket in use, we must wait
+     for it or it will be removed from watching when the multi_socket API is
+     used. */
+  socks[0] = conn->sock[FIRSTSOCKET];
+  return GETSOCK_READSOCK(0) | GETSOCK_WRITESOCK(0);
 }
 }
 
 
 int Curl_doing_getsock(struct connectdata *conn,
 int Curl_doing_getsock(struct connectdata *conn,
@@ -1999,7 +1992,6 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
   char *fragment;
   char *fragment;
   char *path = data->state.path;
   char *path = data->state.path;
   char *query;
   char *query;
-  int i;
   int rc;
   int rc;
   const char *protop = "";
   const char *protop = "";
   CURLcode result;
   CURLcode result;
@@ -2051,6 +2043,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
     ; /* do nothing */
     ; /* do nothing */
   }
   }
   else { /* check for a scheme */
   else { /* check for a scheme */
+    int i;
     for(i = 0; i < 16 && data->change.url[i]; ++i) {
     for(i = 0; i < 16 && data->change.url[i]; ++i) {
       if(data->change.url[i] == '/')
       if(data->change.url[i] == '/')
         break;
         break;
@@ -2203,7 +2196,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
       size_t s = strlen(slashbuf);
       size_t s = strlen(slashbuf);
       protop = protobuf;
       protop = protobuf;
       if(s != 2) {
       if(s != 2) {
-        infof(data, "Unwillingly accepted illegal URL using %d slash%s!\n",
+        infof(data, "Unwillingly accepted illegal URL using %zu slash%s!\n",
               s, s>1?"es":"");
               s, s>1?"es":"");
 
 
         if(data->change.url_alloc)
         if(data->change.url_alloc)
@@ -2449,7 +2442,7 @@ static CURLcode setup_range(struct Curl_easy *data)
       free(s->range);
       free(s->range);
 
 
     if(s->resume_from)
     if(s->resume_from)
-      s->range = aprintf("%" CURL_FORMAT_CURL_OFF_TU "-", s->resume_from);
+      s->range = aprintf("%" CURL_FORMAT_CURL_OFF_T "-", s->resume_from);
     else
     else
       s->range = strdup(data->set.str[STRING_SET_RANGE]);
       s->range = strdup(data->set.str[STRING_SET_RANGE]);
 
 
@@ -2481,18 +2474,6 @@ static CURLcode setup_connection_internals(struct connectdata *conn)
 {
 {
   const struct Curl_handler * p;
   const struct Curl_handler * p;
   CURLcode result;
   CURLcode result;
-  struct Curl_easy *data = conn->data;
-
-  /* in some case in the multi state-machine, we go back to the CONNECT state
-     and then a second (or third or...) call to this function will be made
-     without doing a DISCONNECT or DONE in between (since the connection is
-     yet in place) and therefore this function needs to first make sure
-     there's no lingering previous data allocated. */
-  Curl_free_request_state(data);
-
-  memset(&data->req, 0, sizeof(struct SingleRequest));
-  data->req.maxdownload = -1;
-
   conn->socktype = SOCK_STREAM; /* most of them are TCP streams */
   conn->socktype = SOCK_STREAM; /* most of them are TCP streams */
 
 
   /* Perform setup complement if some. */
   /* Perform setup complement if some. */
@@ -2539,14 +2520,13 @@ static bool check_noproxy(const char *name, const char *no_proxy)
    *   not be proxied, or an asterisk to override
    *   not be proxied, or an asterisk to override
    *   all proxy variables)
    *   all proxy variables)
    */
    */
-  size_t tok_start;
-  size_t tok_end;
-  const char *separator = ", ";
-  size_t no_proxy_len;
-  size_t namelen;
-  char *endptr;
-
   if(no_proxy && no_proxy[0]) {
   if(no_proxy && no_proxy[0]) {
+    size_t tok_start;
+    size_t tok_end;
+    const char *separator = ", ";
+    size_t no_proxy_len;
+    size_t namelen;
+    char *endptr;
     if(strcasecompare("*", no_proxy)) {
     if(strcasecompare("*", no_proxy)) {
       return TRUE;
       return TRUE;
     }
     }
@@ -3166,6 +3146,13 @@ static CURLcode parse_url_login(struct Curl_easy *data,
   if(userp) {
   if(userp) {
     char *newname;
     char *newname;
 
 
+    if(data->set.disallow_username_in_url) {
+      failf(data, "Option DISALLOW_USERNAME_IN_URL is set "
+                  "and url contains username.");
+      result = CURLE_LOGIN_DENIED;
+      goto out;
+    }
+
     /* We have a user in the URL */
     /* We have a user in the URL */
     conn->bits.userpwd_in_url = TRUE;
     conn->bits.userpwd_in_url = TRUE;
     conn->bits.user_passwd = TRUE; /* enable user+password */
     conn->bits.user_passwd = TRUE; /* enable user+password */
@@ -3982,6 +3969,7 @@ static void reuse_conn(struct connectdata *old_conn,
 
 
   Curl_safefree(old_conn->user);
   Curl_safefree(old_conn->user);
   Curl_safefree(old_conn->passwd);
   Curl_safefree(old_conn->passwd);
+  Curl_safefree(old_conn->options);
   Curl_safefree(old_conn->http_proxy.user);
   Curl_safefree(old_conn->http_proxy.user);
   Curl_safefree(old_conn->socks_proxy.user);
   Curl_safefree(old_conn->socks_proxy.user);
   Curl_safefree(old_conn->http_proxy.passwd);
   Curl_safefree(old_conn->http_proxy.passwd);
@@ -4297,7 +4285,9 @@ static CURLcode create_conn(struct Curl_easy *data,
       conn->data = data;
       conn->data = data;
       conn->bits.tcpconnect[FIRSTSOCKET] = TRUE; /* we are "connected */
       conn->bits.tcpconnect[FIRSTSOCKET] = TRUE; /* we are "connected */
 
 
-      Curl_conncache_add_conn(data->state.conn_cache, conn);
+      result = Curl_conncache_add_conn(data->state.conn_cache, conn);
+      if(result)
+        goto out;
 
 
       /*
       /*
        * Setup whatever necessary for a resumed transfer
        * Setup whatever necessary for a resumed transfer
@@ -4343,6 +4333,10 @@ static CURLcode create_conn(struct Curl_easy *data,
     data->set.str[STRING_SSL_CIPHER_LIST_ORIG];
     data->set.str[STRING_SSL_CIPHER_LIST_ORIG];
   data->set.proxy_ssl.primary.cipher_list =
   data->set.proxy_ssl.primary.cipher_list =
     data->set.str[STRING_SSL_CIPHER_LIST_PROXY];
     data->set.str[STRING_SSL_CIPHER_LIST_PROXY];
+  data->set.ssl.primary.cipher_list13 =
+    data->set.str[STRING_SSL_CIPHER13_LIST_ORIG];
+  data->set.proxy_ssl.primary.cipher_list13 =
+    data->set.str[STRING_SSL_CIPHER13_LIST_PROXY];
 
 
   data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_ORIG];
   data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_ORIG];
   data->set.proxy_ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_PROXY];
   data->set.proxy_ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_PROXY];
@@ -4468,13 +4462,11 @@ static CURLcode create_conn(struct Curl_easy *data,
         conn_candidate = Curl_conncache_extract_bundle(data, bundle);
         conn_candidate = Curl_conncache_extract_bundle(data, bundle);
         Curl_conncache_unlock(conn);
         Curl_conncache_unlock(conn);
 
 
-        if(conn_candidate) {
-          /* Set the connection's owner correctly, then kill it */
-          conn_candidate->data = data;
-          (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE);
-        }
+        if(conn_candidate)
+          (void)Curl_disconnect(data, conn_candidate,
+                                /* dead_connection */ FALSE);
         else {
         else {
-          infof(data, "No more connections allowed to host: %d\n",
+          infof(data, "No more connections allowed to host: %zu\n",
                 max_host_connections);
                 max_host_connections);
           connections_available = FALSE;
           connections_available = FALSE;
         }
         }
@@ -4491,12 +4483,9 @@ static CURLcode create_conn(struct Curl_easy *data,
 
 
       /* The cache is full. Let's see if we can kill a connection. */
       /* The cache is full. Let's see if we can kill a connection. */
       conn_candidate = Curl_conncache_extract_oldest(data);
       conn_candidate = Curl_conncache_extract_oldest(data);
-
-      if(conn_candidate) {
-        /* Set the connection's owner correctly, then kill it */
-        conn_candidate->data = data;
-        (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE);
-      }
+      if(conn_candidate)
+        (void)Curl_disconnect(data, conn_candidate,
+                              /* dead_connection */ FALSE);
       else {
       else {
         infof(data, "No connections available in cache\n");
         infof(data, "No connections available in cache\n");
         connections_available = FALSE;
         connections_available = FALSE;
@@ -4513,14 +4502,13 @@ static CURLcode create_conn(struct Curl_easy *data,
       goto out;
       goto out;
     }
     }
     else {
     else {
-      /* Mark the connection as used, before we add it */
-      conn->inuse = TRUE;
-
       /*
       /*
        * This is a brand new connection, so let's store it in the connection
        * This is a brand new connection, so let's store it in the connection
        * cache of ours!
        * cache of ours!
        */
        */
-      Curl_conncache_add_conn(data->state.conn_cache, conn);
+      result = Curl_conncache_add_conn(data->state.conn_cache, conn);
+      if(result)
+        goto out;
     }
     }
 
 
 #if defined(USE_NTLM)
 #if defined(USE_NTLM)
@@ -4656,12 +4644,16 @@ CURLcode Curl_connect(struct Curl_easy *data,
 
 
   *asyncp = FALSE; /* assume synchronous resolves by default */
   *asyncp = FALSE; /* assume synchronous resolves by default */
 
 
+  /* init the single-transfer specific data */
+  Curl_free_request_state(data);
+  memset(&data->req, 0, sizeof(struct SingleRequest));
+  data->req.maxdownload = -1;
+
   /* call the stuff that needs to be called */
   /* call the stuff that needs to be called */
   result = create_conn(data, in_connect, asyncp);
   result = create_conn(data, in_connect, asyncp);
 
 
   if(!result) {
   if(!result) {
-    /* no error */
-    if((*in_connect)->send_pipe.size || (*in_connect)->recv_pipe.size)
+    if(CONN_INUSE(*in_connect))
       /* pipelining */
       /* pipelining */
       *protocol_done = TRUE;
       *protocol_done = TRUE;
     else if(!*asyncp) {
     else if(!*asyncp) {
@@ -4676,12 +4668,11 @@ CURLcode Curl_connect(struct Curl_easy *data,
     *in_connect = NULL;
     *in_connect = NULL;
     return result;
     return result;
   }
   }
-
-  if(result && *in_connect) {
-    /* We're not allowed to return failure with memory left allocated
-       in the connectdata struct, free those here */
-    Curl_disconnect(*in_connect, FALSE); /* close the connection */
-    *in_connect = NULL;           /* return a NULL */
+  else if(result && *in_connect) {
+    /* We're not allowed to return failure with memory left allocated in the
+       connectdata struct, free those here */
+    Curl_disconnect(data, *in_connect, TRUE);
+    *in_connect = NULL; /* return a NULL */
   }
   }
 
 
   return result;
   return result;
@@ -4701,16 +4692,18 @@ CURLcode Curl_init_do(struct Curl_easy *data, struct connectdata *conn)
 {
 {
   struct SingleRequest *k = &data->req;
   struct SingleRequest *k = &data->req;
 
 
-  conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to
-                                 use */
+  if(conn) {
+    conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to
+                                   use */
+    /* if the protocol used doesn't support wildcards, switch it off */
+    if(data->state.wildcardmatch &&
+       !(conn->handler->flags & PROTOPT_WILDCARD))
+      data->state.wildcardmatch = FALSE;
+  }
 
 
   data->state.done = FALSE; /* *_done() is not called yet */
   data->state.done = FALSE; /* *_done() is not called yet */
   data->state.expect100header = FALSE;
   data->state.expect100header = FALSE;
 
 
-  /* if the protocol used doesn't support wildcards, switch it off */
-  if(data->state.wildcardmatch &&
-     !(conn->handler->flags & PROTOPT_WILDCARD))
-    data->state.wildcardmatch = FALSE;
 
 
   if(data->set.opt_no_body)
   if(data->set.opt_no_body)
     /* in HTTP lingo, no body means using the HEAD request... */
     /* in HTTP lingo, no body means using the HEAD request... */

+ 2 - 1
lib/url.h

@@ -39,7 +39,8 @@ void Curl_freeset(struct Curl_easy * data);
 CURLcode Curl_close(struct Curl_easy *data); /* opposite of curl_open() */
 CURLcode Curl_close(struct Curl_easy *data); /* opposite of curl_open() */
 CURLcode Curl_connect(struct Curl_easy *, struct connectdata **,
 CURLcode Curl_connect(struct Curl_easy *, struct connectdata **,
                       bool *async, bool *protocol_connect);
                       bool *async, bool *protocol_connect);
-CURLcode Curl_disconnect(struct connectdata *, bool dead_connection);
+CURLcode Curl_disconnect(struct Curl_easy *data,
+                         struct connectdata *, bool dead_connection);
 CURLcode Curl_protocol_connect(struct connectdata *conn, bool *done);
 CURLcode Curl_protocol_connect(struct connectdata *conn, bool *done);
 CURLcode Curl_protocol_connecting(struct connectdata *conn, bool *done);
 CURLcode Curl_protocol_connecting(struct connectdata *conn, bool *done);
 CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done);
 CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done);

+ 28 - 21
lib/urldata.h

@@ -80,6 +80,7 @@
 #define RESP_TIMEOUT (1800*1000)
 #define RESP_TIMEOUT (1800*1000)
 
 
 #include "cookie.h"
 #include "cookie.h"
+#include "psl.h"
 #include "formdata.h"
 #include "formdata.h"
 
 
 #ifdef HAVE_NETINET_IN_H
 #ifdef HAVE_NETINET_IN_H
@@ -142,8 +143,13 @@ typedef ssize_t (Curl_recv)(struct connectdata *conn, /* connection data */
 #endif /* HAVE_LIBSSH2_H */
 #endif /* HAVE_LIBSSH2_H */
 
 
 /* The upload buffer size, should not be smaller than CURL_MAX_WRITE_SIZE, as
 /* The upload buffer size, should not be smaller than CURL_MAX_WRITE_SIZE, as
-   it needs to hold a full buffer as could be sent in a write callback */
-#define UPLOAD_BUFSIZE CURL_MAX_WRITE_SIZE
+   it needs to hold a full buffer as could be sent in a write callback.
+
+   The size was 16KB for many years but was bumped to 64KB because it makes
+   libcurl able to do significantly faster uploads in some circumstances. Even
+   larger buffers can help further, but this is deemed a fair memory/speed
+   compromise. */
+#define UPLOAD_BUFSIZE 65536
 
 
 /* The "master buffer" is for HTTP pipelining */
 /* The "master buffer" is for HTTP pipelining */
 #define MASTERBUF_SIZE 16384
 #define MASTERBUF_SIZE 16384
@@ -156,11 +162,6 @@ typedef ssize_t (Curl_recv)(struct connectdata *conn, /* connection data */
 #define GOOD_EASY_HANDLE(x) \
 #define GOOD_EASY_HANDLE(x) \
   ((x) && ((x)->magic == CURLEASY_MAGIC_NUMBER))
   ((x) && ((x)->magic == CURLEASY_MAGIC_NUMBER))
 
 
-/* Some convenience macros to get the larger/smaller value out of two given.
-   We prefix with CURL to prevent name collisions. */
-#define CURLMAX(x,y) ((x)>(y)?(x):(y))
-#define CURLMIN(x,y) ((x)<(y)?(x):(y))
-
 #ifdef HAVE_GSSAPI
 #ifdef HAVE_GSSAPI
 /* Types needed for krb5-ftp connections */
 /* Types needed for krb5-ftp connections */
 struct krb5buffer {
 struct krb5buffer {
@@ -226,6 +227,7 @@ struct ssl_primary_config {
   char *random_file;     /* path to file containing "random" data */
   char *random_file;     /* path to file containing "random" data */
   char *egdsocket;       /* path to file containing the EGD daemon socket */
   char *egdsocket;       /* path to file containing the EGD daemon socket */
   char *cipher_list;     /* list of ciphers to use */
   char *cipher_list;     /* list of ciphers to use */
+  char *cipher_list13;   /* list of TLS 1.3 cipher suites to use */
 };
 };
 
 
 struct ssl_config_data {
 struct ssl_config_data {
@@ -779,11 +781,12 @@ struct connectdata {
   curl_closesocket_callback fclosesocket; /* function closing the socket(s) */
   curl_closesocket_callback fclosesocket; /* function closing the socket(s) */
   void *closesocket_client;
   void *closesocket_client;
 
 
-  bool inuse; /* This is a marker for the connection cache logic. If this is
-                 TRUE this handle is being used by one or more easy handles
-                 and can only used by any other easy handle without careful
-                 consideration (== only for pipelining/multiplexing) and it
-                 cannot be used by another multi handle! */
+  /* This is used by the connection cache logic. If this returns TRUE, this
+     handle is being used by one or more easy handles and can only used by any
+     other easy handle without careful consideration (== only for
+     pipelining/multiplexing) and it cannot be used by another multi
+     handle! */
+#define CONN_INUSE(c) ((c)->send_pipe.size + (c)->recv_pipe.size)
 
 
   /**** Fields set when inited and not modified again */
   /**** Fields set when inited and not modified again */
   long connection_id; /* Contains a unique number to make it easier to
   long connection_id; /* Contains a unique number to make it easier to
@@ -1222,7 +1225,7 @@ struct UrlState {
   size_t headersize;   /* size of the allocation */
   size_t headersize;   /* size of the allocation */
 
 
   char *buffer; /* download buffer */
   char *buffer; /* download buffer */
-  char uploadbuffer[UPLOAD_BUFSIZE + 1]; /* upload buffer */
+  char *ulbuf; /* alloced upload buffer or NULL */
   curl_off_t current_speed;  /* the ProgressShow() function sets this,
   curl_off_t current_speed;  /* the ProgressShow() function sets this,
                                 bytes / second */
                                 bytes / second */
   bool this_is_a_follow; /* this is a followed Location: request */
   bool this_is_a_follow; /* this is a followed Location: request */
@@ -1265,7 +1268,7 @@ struct UrlState {
   void *resolver; /* resolver state, if it is used in the URL state -
   void *resolver; /* resolver state, if it is used in the URL state -
                      ares_channel f.e. */
                      ares_channel f.e. */
 
 
-#if defined(USE_OPENSSL) && defined(HAVE_OPENSSL_ENGINE_H)
+#if defined(USE_OPENSSL)
   /* void instead of ENGINE to avoid bleeding OpenSSL into this header */
   /* void instead of ENGINE to avoid bleeding OpenSSL into this header */
   void *engine;
   void *engine;
 #endif /* USE_OPENSSL */
 #endif /* USE_OPENSSL */
@@ -1284,9 +1287,6 @@ struct UrlState {
                             involved in this request */
                             involved in this request */
   bool expect100header;  /* TRUE if we added Expect: 100-continue */
   bool expect100header;  /* TRUE if we added Expect: 100-continue */
 
 
-  bool pipe_broke; /* TRUE if the connection we were pipelined on broke
-                      and we need to restart from the beginning */
-
 #if !defined(WIN32) && !defined(MSDOS) && !defined(__EMX__) && \
 #if !defined(WIN32) && !defined(MSDOS) && !defined(__EMX__) && \
     !defined(__SYMBIAN32__)
     !defined(__SYMBIAN32__)
 /* do FTP line-end conversions on most platforms */
 /* do FTP line-end conversions on most platforms */
@@ -1346,7 +1346,7 @@ struct DynamicStatic {
   char *url;        /* work URL, copied from UserDefined */
   char *url;        /* work URL, copied from UserDefined */
   bool url_alloc;   /* URL string is malloc()'ed */
   bool url_alloc;   /* URL string is malloc()'ed */
   char *referer;    /* referer string */
   char *referer;    /* referer string */
-  bool referer_alloc; /* referer sting is malloc()ed */
+  bool referer_alloc; /* referer string is malloc()ed */
   struct curl_slist *cookielist; /* list of cookie files set by
   struct curl_slist *cookielist; /* list of cookie files set by
                                     curl_easy_setopt(COOKIEFILE) calls */
                                     curl_easy_setopt(COOKIEFILE) calls */
   struct curl_slist *resolve; /* set to point to the set.resolve list when
   struct curl_slist *resolve; /* set to point to the set.resolve list when
@@ -1400,6 +1400,8 @@ enum dupstring {
   STRING_SSL_PINNEDPUBLICKEY_PROXY, /* public key file to verify proxy */
   STRING_SSL_PINNEDPUBLICKEY_PROXY, /* public key file to verify proxy */
   STRING_SSL_CIPHER_LIST_ORIG, /* list of ciphers to use */
   STRING_SSL_CIPHER_LIST_ORIG, /* list of ciphers to use */
   STRING_SSL_CIPHER_LIST_PROXY, /* list of ciphers to use */
   STRING_SSL_CIPHER_LIST_PROXY, /* list of ciphers to use */
+  STRING_SSL_CIPHER13_LIST_ORIG, /* list of TLS 1.3 ciphers to use */
+  STRING_SSL_CIPHER13_LIST_PROXY, /* list of TLS 1.3 ciphers to use */
   STRING_SSL_EGDSOCKET,   /* path to file containing the EGD daemon socket */
   STRING_SSL_EGDSOCKET,   /* path to file containing the EGD daemon socket */
   STRING_SSL_RANDOM_FILE, /* path to file containing "random" data */
   STRING_SSL_RANDOM_FILE, /* path to file containing "random" data */
   STRING_USERAGENT,       /* User-Agent string */
   STRING_USERAGENT,       /* User-Agent string */
@@ -1407,6 +1409,7 @@ enum dupstring {
   STRING_SSL_CRLFILE_PROXY, /* crl file to check certificate */
   STRING_SSL_CRLFILE_PROXY, /* crl file to check certificate */
   STRING_SSL_ISSUERCERT_ORIG, /* issuer cert file to check certificate */
   STRING_SSL_ISSUERCERT_ORIG, /* issuer cert file to check certificate */
   STRING_SSL_ISSUERCERT_PROXY, /* issuer cert file to check certificate */
   STRING_SSL_ISSUERCERT_PROXY, /* issuer cert file to check certificate */
+  STRING_SSL_ENGINE,      /* name of ssl engine */
   STRING_USERNAME,        /* <username>, if used */
   STRING_USERNAME,        /* <username>, if used */
   STRING_PASSWORD,        /* <password>, if used */
   STRING_PASSWORD,        /* <password>, if used */
   STRING_OPTIONS,         /* <options>, if used */
   STRING_OPTIONS,         /* <options>, if used */
@@ -1559,6 +1562,8 @@ struct UserDefined {
   curl_proxytype proxytype; /* what kind of proxy that is in use */
   curl_proxytype proxytype; /* what kind of proxy that is in use */
   long dns_cache_timeout; /* DNS cache timeout */
   long dns_cache_timeout; /* DNS cache timeout */
   long buffer_size;      /* size of receive buffer to use */
   long buffer_size;      /* size of receive buffer to use */
+  long upload_buffer_size; /* size of upload buffer to use,
+                              keep it >= CURL_MAX_WRITE_SIZE */
   void *private_data; /* application-private data */
   void *private_data; /* application-private data */
 
 
   struct curl_slist *http200aliases; /* linked list of aliases for http200 */
   struct curl_slist *http200aliases; /* linked list of aliases for http200 */
@@ -1581,8 +1586,6 @@ struct UserDefined {
 /* Here follows boolean settings that define how to behave during
 /* Here follows boolean settings that define how to behave during
    this session. They are STATIC, set by libcurl users or at least initially
    this session. They are STATIC, set by libcurl users or at least initially
    and they don't change during operations. */
    and they don't change during operations. */
-
-  bool printhost;        /* printing host name in debug info */
   bool get_filetime;     /* get the time and get of the remote file */
   bool get_filetime;     /* get the time and get of the remote file */
   bool tunnel_thru_httpproxy; /* use CONNECT through a HTTP proxy */
   bool tunnel_thru_httpproxy; /* use CONNECT through a HTTP proxy */
   bool prefer_ascii;     /* ASCII rather than binary */
   bool prefer_ascii;     /* ASCII rather than binary */
@@ -1676,7 +1679,7 @@ struct UserDefined {
   bool stream_depends_e; /* set or don't set the Exclusive bit */
   bool stream_depends_e; /* set or don't set the Exclusive bit */
   int stream_weight;
   int stream_weight;
 
 
-  bool haproxyprotocol; /* whether to send HAProxy PROXY protocol header */
+  bool haproxyprotocol; /* whether to send HAProxy PROXY protocol v1 header */
 
 
   struct Curl_http2_dep *stream_dependents;
   struct Curl_http2_dep *stream_dependents;
 
 
@@ -1685,6 +1688,7 @@ struct UserDefined {
   curl_resolver_start_callback resolver_start; /* optional callback called
   curl_resolver_start_callback resolver_start; /* optional callback called
                                                   before resolver start */
                                                   before resolver start */
   void *resolver_start_client; /* pointer to pass to resolver start callback */
   void *resolver_start_client; /* pointer to pass to resolver start callback */
+  bool disallow_username_in_url; /* disallow username in url */
 };
 };
 
 
 struct Names {
 struct Names {
@@ -1736,6 +1740,9 @@ struct Curl_easy {
                                     struct to which this "belongs" when used
                                     struct to which this "belongs" when used
                                     by the easy interface */
                                     by the easy interface */
   struct Curl_share *share;    /* Share, handles global variable mutexing */
   struct Curl_share *share;    /* Share, handles global variable mutexing */
+#ifdef USE_LIBPSL
+  struct PslCache *psl;        /* The associated PSL cache. */
+#endif
   struct SingleRequest req;    /* Request-specific data */
   struct SingleRequest req;    /* Request-specific data */
   struct UserDefined set;      /* values set by the libcurl user */
   struct UserDefined set;      /* values set by the libcurl user */
   struct DynamicStatic change; /* possibly modified userdefined data */
   struct DynamicStatic change; /* possibly modified userdefined data */

+ 3 - 3
lib/vauth/digest.c

@@ -158,7 +158,7 @@ static void auth_digest_sha256_to_ascii(unsigned char *source, /* 32 bytes */
 /* Perform quoted-string escaping as described in RFC2616 and its errata */
 /* Perform quoted-string escaping as described in RFC2616 and its errata */
 static char *auth_digest_string_quoted(const char *source)
 static char *auth_digest_string_quoted(const char *source)
 {
 {
-  char *dest, *d;
+  char *dest;
   const char *s = source;
   const char *s = source;
   size_t n = 1; /* null terminator */
   size_t n = 1; /* null terminator */
 
 
@@ -173,8 +173,8 @@ static char *auth_digest_string_quoted(const char *source)
 
 
   dest = malloc(n);
   dest = malloc(n);
   if(dest) {
   if(dest) {
+    char *d = dest;
     s = source;
     s = source;
-    d = dest;
     while(*s) {
     while(*s) {
       if(*s == '"' || *s == '\\') {
       if(*s == '"' || *s == '\\') {
         *d++ = '\\';
         *d++ = '\\';
@@ -696,7 +696,6 @@ static CURLcode _Curl_auth_create_digest_http_message(
   unsigned char ha1[65];    /* 64 digits and 1 zero byte */
   unsigned char ha1[65];    /* 64 digits and 1 zero byte */
   unsigned char ha2[65];    /* 64 digits and 1 zero byte */
   unsigned char ha2[65];    /* 64 digits and 1 zero byte */
   char userh[65];
   char userh[65];
-  char cnoncebuf[33];
   char *cnonce = NULL;
   char *cnonce = NULL;
   size_t cnonce_sz = 0;
   size_t cnonce_sz = 0;
   char *userp_quoted;
   char *userp_quoted;
@@ -707,6 +706,7 @@ static CURLcode _Curl_auth_create_digest_http_message(
     digest->nc = 1;
     digest->nc = 1;
 
 
   if(!digest->cnonce) {
   if(!digest->cnonce) {
+    char cnoncebuf[33];
     result = Curl_rand_hex(data, (unsigned char *)cnoncebuf,
     result = Curl_rand_hex(data, (unsigned char *)cnoncebuf,
                            sizeof(cnoncebuf));
                            sizeof(cnoncebuf));
     if(result)
     if(result)

+ 1 - 1
lib/version.c

@@ -445,7 +445,7 @@ curl_version_info_data *curl_version_info(CURLversion stamp)
 
 
 #ifdef HAVE_BROTLI
 #ifdef HAVE_BROTLI
   version_info.brotli_ver_num = BrotliDecoderVersion();
   version_info.brotli_ver_num = BrotliDecoderVersion();
-  brotli_version(brotli_buffer, sizeof brotli_buffer);
+  brotli_version(brotli_buffer, sizeof(brotli_buffer));
   version_info.brotli_version = brotli_buffer;
   version_info.brotli_version = brotli_buffer;
 #endif
 #endif
 
 

+ 5 - 0
lib/vtls/axtls.c

@@ -29,6 +29,11 @@
 #include "curl_setup.h"
 #include "curl_setup.h"
 
 
 #ifdef USE_AXTLS
 #ifdef USE_AXTLS
+
+#error axTLS support has been disabled in curl due to doubts about quality,
+#error user dedication and a lack of use/testing. We urge users to consider
+#error using a more established TLS backend instead.
+
 #include <axTLS/config.h>
 #include <axTLS/config.h>
 #include <axTLS/ssl.h>
 #include <axTLS/ssl.h>
 #include "axtls.h"
 #include "axtls.h"

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio