diff options
89 files changed, 2119 insertions, 2134 deletions
diff --git a/.github/workflows/curl-for-win.yml b/.github/workflows/curl-for-win.yml index 5b0d2e03c..c70ac13e9 100644 --- a/.github/workflows/curl-for-win.yml +++ b/.github/workflows/curl-for-win.yml @@ -45,7 +45,7 @@ env: jobs: linux-glibc-gcc: - name: 'Linux gcc glibc' + name: 'Linux gcc glibc (amd64, arm64)' runs-on: ubuntu-latest timeout-minutes: 10 steps: @@ -74,7 +74,7 @@ jobs: sh -c ./_ci-linux-debian.sh linux-musl-llvm: - name: 'Linux llvm MUSL' + name: 'Linux llvm MUSL (amd64, riscv64)' runs-on: ubuntu-latest timeout-minutes: 10 steps: @@ -101,7 +101,7 @@ jobs: sh -c ./_ci-linux-debian.sh mac-clang: - name: 'macOS clang' + name: 'macOS clang (x86_64)' runs-on: macos-latest timeout-minutes: 10 env: @@ -121,7 +121,7 @@ jobs: sh -c ./_ci-mac-homebrew.sh win-llvm: - name: 'Windows llvm' + name: 'Windows llvm (x64)' runs-on: ubuntu-latest timeout-minutes: 10 steps: @@ -148,7 +148,7 @@ jobs: sh -c ./_ci-linux-debian.sh win-gcc-libssh-zlibold-x86: - name: 'Windows gcc libssh zlib-classic x86' + name: 'Windows gcc libssh zlib-classic (x86)' runs-on: ubuntu-latest timeout-minutes: 10 steps: diff --git a/.github/workflows/distcheck.yml b/.github/workflows/distcheck.yml index 3d5adc759..386c2ddfc 100644 --- a/.github/workflows/distcheck.yml +++ b/.github/workflows/distcheck.yml @@ -73,7 +73,7 @@ jobs: timeout-minutes: 10 needs: maketgz-and-verify-in-tree steps: - - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 + - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5 with: name: 'release-tgz' @@ -97,7 +97,7 @@ jobs: timeout-minutes: 10 needs: maketgz-and-verify-in-tree steps: - - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 + - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5 with: name: 'release-tgz' @@ -123,7 +123,7 @@ jobs: timeout-minutes: 10 needs: maketgz-and-verify-in-tree steps: - - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 + - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5 with: name: 'release-tgz' @@ -147,7 +147,7 @@ jobs: timeout-minutes: 10 needs: maketgz-and-verify-in-tree steps: - - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 + - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5 with: name: 'release-tgz' @@ -168,7 +168,7 @@ jobs: timeout-minutes: 5 needs: maketgz-and-verify-in-tree steps: - - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 + - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5 with: name: 'release-tgz' @@ -190,7 +190,7 @@ jobs: timeout-minutes: 5 needs: maketgz-and-verify-in-tree steps: - - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 + - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5 with: name: 'release-tgz' @@ -216,7 +216,7 @@ jobs: with: persist-credentials: false - - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 + - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5 with: name: 'release-tgz' @@ -301,6 +301,9 @@ jobs: with: persist-credentials: false + - name: 'via ExternalProject' + if: ${{ !contains(matrix.image, 'ubuntu') }} + run: ./tests/cmake/test.sh ExternalProject ${TESTOPTS} - name: 'via FetchContent' run: ./tests/cmake/test.sh FetchContent ${TESTOPTS} -DCURL_USE_OPENSSL=ON - name: 'via add_subdirectory' @@ -308,6 +311,19 @@ jobs: - name: 'via find_package' run: ./tests/cmake/test.sh find_package ${TESTOPTS} -DCURL_USE_OPENSSL=ON + - name: 'via ExternalProject (old cmake)' + if: ${{ contains(matrix.image, 'ubuntu') }} + run: | + export TEST_CMAKE_CONSUMER; TEST_CMAKE_CONSUMER="$(cat ~/old-cmake-path.txt)" + if [[ "${MATRIX_IMAGE}" = *'macos'* ]]; then + export CFLAGS='-arch arm64' + fi + if [[ "${MATRIX_IMAGE}" = *'windows'* ]]; then + export TEST_CMAKE_GENERATOR='MSYS Makefiles' + export TEST_CMAKE_FLAGS='-DCMAKE_C_COMPILER=x86_64-w64-mingw32-gcc' + fi + ./tests/cmake/test.sh ExternalProject ${TESTOPTS} + - name: 'via add_subdirectory OpenSSL (old cmake)' run: | export TEST_CMAKE_CONSUMER; TEST_CMAKE_CONSUMER="$(cat ~/old-cmake-path.txt)" diff --git a/.github/workflows/http3-linux.yml b/.github/workflows/http3-linux.yml index 99e99332a..12b66fd1b 100644 --- a/.github/workflows/http3-linux.yml +++ b/.github/workflows/http3-linux.yml @@ -65,7 +65,7 @@ jobs: steps: - name: 'cache openssl' - uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf # v4 + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4 id: cache-openssl-http3 env: cache-name: cache-openssl-http3 @@ -74,7 +74,7 @@ jobs: key: ${{ runner.os }}-http3-build-${{ env.cache-name }}-${{ env.OPENSSL_VERSION }} - name: 'cache quictls' - uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf # v4 + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4 id: cache-quictls-no-deprecated env: cache-name: cache-quictls-no-deprecated @@ -83,7 +83,7 @@ jobs: key: ${{ runner.os }}-http3-build-${{ env.cache-name }}-${{ env.QUICTLS_VERSION }}-quic1 - name: 'cache gnutls' - uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf # v4 + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4 id: cache-gnutls env: cache-name: cache-gnutls @@ -92,7 +92,7 @@ jobs: key: ${{ runner.os }}-http3-build-${{ env.cache-name }}-${{ env.GNUTLS_VERSION }} - name: 'cache wolfssl' - uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf # v4 + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4 id: cache-wolfssl env: cache-name: cache-wolfssl @@ -101,7 +101,7 @@ jobs: key: ${{ runner.os }}-http3-build-${{ env.cache-name }}-${{ env.WOLFSSL_VERSION }} - name: 'cache nghttp3' - uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf # v4 + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4 id: cache-nghttp3 env: cache-name: cache-nghttp3 @@ -110,7 +110,7 @@ jobs: key: ${{ runner.os }}-http3-build-${{ env.cache-name }}-${{ env.NGHTTP3_VERSION }} - name: 'cache ngtcp2' - uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf # v4 + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4 id: cache-ngtcp2 env: cache-name: cache-ngtcp2 @@ -119,7 +119,7 @@ jobs: key: ${{ runner.os }}-http3-build-${{ env.cache-name }}-${{ env.NGTCP2_VERSION }}-${{ env.OPENSSL_VERSION }}-${{ env.QUICTLS_VERSION }}-${{ env.GNUTLS_VERSION }}-${{ env.WOLFSSL_VERSION }} - name: 'cache nghttp2' - uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf # v4 + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4 id: cache-nghttp2 env: cache-name: cache-nghttp2 @@ -350,7 +350,7 @@ jobs: - name: 'cache openssl' if: ${{ matrix.build.name == 'openssl' || matrix.build.name == 'openssl-quic' }} - uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf # v4 + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4 id: cache-openssl-http3 env: cache-name: cache-openssl-http3 @@ -360,7 +360,7 @@ jobs: fail-on-cache-miss: true - name: 'cache quictls' - uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf # v4 + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4 id: cache-quictls-no-deprecated env: cache-name: cache-quictls-no-deprecated @@ -371,7 +371,7 @@ jobs: - name: 'cache gnutls' if: ${{ matrix.build.name == 'gnutls' }} - uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf # v4 + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4 id: cache-gnutls env: cache-name: cache-gnutls @@ -382,7 +382,7 @@ jobs: - name: 'cache wolfssl' if: ${{ matrix.build.name == 'wolfssl' }} - uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf # v4 + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4 id: cache-wolfssl env: cache-name: cache-wolfssl @@ -392,7 +392,7 @@ jobs: fail-on-cache-miss: true - name: 'cache nghttp3' - uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf # v4 + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4 id: cache-nghttp3 env: cache-name: cache-nghttp3 @@ -402,7 +402,7 @@ jobs: fail-on-cache-miss: true - name: 'cache ngtcp2' - uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf # v4 + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4 id: cache-ngtcp2 env: cache-name: cache-ngtcp2 @@ -412,7 +412,7 @@ jobs: fail-on-cache-miss: true - name: 'cache nghttp2' - uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf # v4 + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4 id: cache-nghttp2 env: cache-name: cache-nghttp2 @@ -423,7 +423,7 @@ jobs: - name: 'cache quiche' if: ${{ matrix.build.name == 'quiche' }} - uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf # v4 + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4 id: cache-quiche env: cache-name: cache-quiche diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index c0be95f43..b293a140f 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -325,7 +325,7 @@ jobs: - name: 'cache libressl' if: ${{ contains(matrix.build.install_steps, 'libressl') }} - uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf # v4 + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4 id: cache-libressl env: cache-name: cache-libressl @@ -344,7 +344,7 @@ jobs: - name: 'cache wolfssl (all)' if: ${{ contains(matrix.build.install_steps, 'wolfssl-all') }} - uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf # v4 + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4 id: cache-wolfssl-all env: cache-name: cache-wolfssl-all @@ -365,7 +365,7 @@ jobs: - name: 'cache wolfssl (opensslextra)' # does support `OPENSSL_COEXIST` if: ${{ contains(matrix.build.install_steps, 'wolfssl-opensslextra') }} - uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf # v4 + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4 id: cache-wolfssl-opensslextra env: cache-name: cache-wolfssl-opensslextra @@ -386,7 +386,7 @@ jobs: - name: 'cache wolfssh' if: ${{ contains(matrix.build.install_steps, 'wolfssh') }} - uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf # v4 + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4 id: cache-wolfssh env: cache-name: cache-wolfssh @@ -407,7 +407,7 @@ jobs: - name: 'cache mbedtls' if: ${{ contains(matrix.build.install_steps, 'mbedtls') }} - uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf # v4 + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4 id: cache-mbedtls env: cache-name: cache-mbedtls-threadsafe @@ -430,7 +430,7 @@ jobs: - name: 'cache openldap-static' if: ${{ contains(matrix.build.install_steps, 'openldap-static') }} - uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf # v4 + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4 id: cache-openldap-static env: cache-name: cache-openldap-static @@ -450,7 +450,7 @@ jobs: - name: 'cache openssl (thread sanitizer)' if: ${{ contains(matrix.build.install_steps, 'openssl-tsan') }} - uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf # v4 + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4 id: cache-openssl-tsan env: cache-name: cache-openssl-tsan @@ -469,7 +469,7 @@ jobs: - name: 'cache quictls' if: ${{ contains(matrix.build.install_steps, 'quictls') }} - uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf # v4 + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4 id: cache-quictls env: cache-name: cache-quictls @@ -488,7 +488,7 @@ jobs: - name: 'cache awslc' if: ${{ contains(matrix.build.install_steps, 'awslc') }} - uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf # v4 + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4 id: cache-awslc env: cache-name: cache-awslc @@ -509,7 +509,7 @@ jobs: - name: 'cache rustls' if: ${{ contains(matrix.build.install_steps, 'rustls') }} - uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf # v4 + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4 id: cache-rustls env: cache-name: cache-rustls diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index cdb6de283..04c30a75c 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -111,7 +111,7 @@ jobs: - name: 'cache libressl' if: ${{ contains(matrix.build.install_steps, 'libressl') }} - uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf # v4 + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4 id: cache-libressl env: cache-name: cache-libressl diff --git a/.github/workflows/non-native.yml b/.github/workflows/non-native.yml index e4c837654..9a9280421 100644 --- a/.github/workflows/non-native.yml +++ b/.github/workflows/non-native.yml @@ -385,7 +385,7 @@ jobs: sudo apt-get -o Dpkg::Use-Pty=0 install libfl2 - name: 'cache compiler (djgpp)' - uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf # v4 + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4 id: cache-compiler with: path: ~/djgpp diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 812bc9b79..ed722a9ba 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -479,7 +479,7 @@ jobs: ${{ matrix.install }} - name: 'cache compiler (gcc ${{ matrix.ver }}-${{ matrix.env }})' - uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf # v4 + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4 id: cache-compiler with: path: D:\my-cache diff --git a/RELEASE-NOTES b/RELEASE-NOTES index f63d85522..e6bab4c2c 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -1,18 +1,19 @@ curl and libcurl 8.15.1 Public curl releases: 270 - Command line options: 271 + Command line options: 272 curl_easy_setopt() options: 308 - Public functions in libcurl: 96 - Contributors: 3478 + Public functions in libcurl: 97 + Contributors: 3483 This release includes the following changes: o build: bump minimum required mingw-w64 to v3.0 (from v1.0) [33] o curl: add --follow [129] - o curl: add --parallel-max-host to limit concurrent connections per host [81] o curl: add --out-null [101] + o curl: add --parallel-max-host to limit concurrent connections per host [81] o curl: make --retry-delay and --retry-max-time accept decimal seconds [112] + o hostip: cache negative name resolves [175] o ip happy eyeballing: keep attempts running [80] o multi: add curl_multi_get_offt [56] o multi: add CURLMOPT_NETWORK_CHANGED to signal network changed [84] @@ -27,8 +28,10 @@ This release includes the following bugfixes: o _PROTOCOLS.md: mention file:// is only for absolute paths [102] o alpn: query filter [104] + o BINDINGS.md: add LibQurl [156] o bufq: add integer overflow checks before chunk allocations [108] o build: allow libtests/clients to use libcurl dependencies directly [87] + o build: disable `TCP_NODELAY` for emscripten [176] o build: enable _GNU_SOURCE on GNU/Hurd [27] o build: extend GNU C guards to clang where applicable, fix fallouts [61] o build: fix build errors/warnings in rare configurations [7] @@ -105,11 +108,13 @@ This release includes the following bugfixes: o multi event: remove only announced [25] o multi: don't insert a node into the splay tree twice [68] o multi: fix assert in multi_getsock() [53] + o multi: fix bad splay management [133] o multi: process pending, one by one [90] o multi: replace remaining EXPIRE_RUN_NOW [67] o multissl: initialize when requesting a random number [30] o ngtcp2: extend callback tables for nghttp3 1.11.0 and ngtcp2 1.14.0 [47] o openssl: check SSL_write() length on retries [152] + o openssl: output unescaped utf8 x509 issuer/subject DNs [169] o openssl: some small cleanups [42] o openssl: split cert_stuff into smaller sub functions [72] o parallel-max: bump the max value to 65535 [86] @@ -136,6 +141,7 @@ This release includes the following bugfixes: o test1560: skip some URLs if UTF-8 is not supported [34] o test1: raise alloc limits [11] o test428: re-enable for Windows [5] + o tests/ech_tests.sh: indent, if/for style, inline ifs [131] o tests: constify command-line arguments [82] o tests: drop unused `CURL_FORCEHOST` envs [36] o tests: fix perl warnings in http2-server, http3-server [119] @@ -149,11 +155,16 @@ This release includes the following bugfixes: o tidy-up: prefer `ifdef`/`ifndef` for single checks [64] o tls: CURLINFO_TLS_SSL_PTR testing [79] o tool_operate: avoid superfluous strdup'ing output [1] + o tool_operate: use the correct config pointer [115] o tool_paramhlp: fix secs2ms() [116] + o tool_urlglob: polish, cleanups, improvements [141] o unit-tests: build the unitprotos.h from here [73] o unit2604: avoid `UNCONST()` [135] o urlapi: allow more path characters "raw" when asked to URL encode [146] + o urldata: reduce two long struct fields to unsigned short [174] o vquic-tls: fix SSL backend type for QUIC connections using gnutls [29] + o vquic: use curl_getenv [168] + o vtls: set seen http version on successful ALPN [160] o windows: assume `ADDRESS_FAMILY`, drop feature checks [88] o windows: document toolchain support for `CERT_NAME_SEARCH_ALL_NAMES_FLAG` o windows: document toolchain support for some macros (cont.) [111] @@ -164,6 +175,7 @@ This release includes the following bugfixes: o windows: fix `if_nametoindex()` detection with autotools, improve with cmake [24] o windows: include `wincrypt.h` before `iphlpapi.h` for mingw-w64 <6 [50] o windows: target version macro tidy-ups [3] + o wolfssl: rename ML-KEM hybrids to match IETF draft [173] o ws: avoid NULL pointer deref in curl_ws_recv [91] This release includes the following known bugs: @@ -185,16 +197,17 @@ Planned upcoming removals include: This release would not have looked like this without help, code, reports and advice from friends like these: - adamse on github, Ahmad Gani, Alice Lee Poetics, Ammar Faizi, + adamse on github, Ahmad Gani, Alice Lee Poetics, Ammar Faizi, Anthony Hu, Berthin Torres Callañaupa, Caolán McNamara, Cole Leavitt, d1r3ct0r, Dan Fandrich, Daniel Böhmer, Daniel Stenberg, David Zhuang, Dominik Tomecki, - Eshan Kelkar, Harry Sintonen, Jeroen Ooms, Kai Pastor, lf- on github, - LoRd_MuldeR, nevakrien on github, Paul Gilmartin, Petar Popovic, - Philippe Antoine, Pino Toscano, Qriist on github, Ray Satiro, renovate[bot], - rm-rmonaghan on github, Schrijvers Luc, Sergio Durigan Junior, - Stefan Eissing, Tal Regev, Todd Gamblin, Viktor Szakats, Waldemar Kornewald, - yaoy6 on github, ウさん - (37 contributors) + Eshan Kelkar, Harry Sintonen, IoannisGS on github, Jeroen Ooms, Kai Pastor, + kkmuffme on github, letshack9707 on hackerone, lf- on github, LoRd_MuldeR, + nevakrien on github, Paul Gilmartin, Petar Popovic, Philippe Antoine, + Pino Toscano, Qriist, Qriist on github, Ray Satiro, renovate[bot], + rm-rmonaghan on github, Roberto Hidalgo, Schrijvers Luc, + Sergio Durigan Junior, Stefan Eissing, Tal Regev, Todd Gamblin, + Viktor Szakats, Waldemar Kornewald, yaoy6 on github, ウさん + (43 contributors) References to bug reports and discussions on issues: @@ -312,6 +325,7 @@ References to bug reports and discussions on issues: [112] = https://curl.se/bug/?i=18109 [113] = https://curl.se/bug/?i=18085 [114] = https://curl.se/bug/?i=18108 + [115] = https://curl.se/bug/?i=18200 [116] = https://curl.se/bug/?i=18167 [117] = https://curl.se/bug/?i=18096 [118] = https://curl.se/bug/?i=18092 @@ -327,13 +341,16 @@ References to bug reports and discussions on issues: [128] = https://curl.se/bug/?i=18165 [129] = https://curl.se/bug/?i=16543 [130] = https://curl.se/bug/?i=18162 + [131] = https://curl.se/bug/?i=18187 [132] = https://curl.se/bug/?i=18160 + [133] = https://curl.se/bug/?i=18201 [134] = https://curl.se/bug/?i=18147 [135] = https://curl.se/bug/?i=18143 [136] = https://curl.se/bug/?i=18142 [137] = https://curl.se/bug/?i=18141 [138] = https://curl.se/bug/?i=18158 [139] = https://curl.se/bug/?i=18149 + [141] = https://curl.se/bug/?i=18198 [142] = https://curl.se/bug/?i=18145 [143] = https://curl.se/bug/?i=18130 [144] = https://curl.se/bug/?i=18118 @@ -345,3 +362,11 @@ References to bug reports and discussions on issues: [150] = https://curl.se/bug/?i=18137 [151] = https://curl.se/bug/?i=18138 [152] = https://curl.se/bug/?i=18121 + [156] = https://curl.se/bug/?i=18195 + [160] = https://curl.se/bug/?i=18177 + [168] = https://curl.se/bug/?i=18170 + [169] = https://curl.se/bug/?i=18171 + [173] = https://curl.se/bug/?i=18123 + [174] = https://curl.se/bug/?i=18173 + [175] = https://curl.se/bug/?i=18157 + [176] = https://curl.se/bug/?i=17974 diff --git a/docs/BINDINGS.md b/docs/BINDINGS.md index e6287761b..d0b836ab9 100644 --- a/docs/BINDINGS.md +++ b/docs/BINDINGS.md @@ -71,6 +71,8 @@ Go: [go-curl](https://github.com/andelf/go-curl) by ShuYu Wang [Lisp](https://common-lisp.net/project/cl-curl/) Written by Liam Healy +[LibQurl](https://github.com/Qriist/LibQurl) a feature rich AutoHotKey v2 (AHKv2) wrapper around libcurl. + Lua: [luacurl](https://web.archive.org/web/20201205052437/luacurl.luaforge.net/) by Alexander Marinov, [Lua-cURL](https://github.com/Lua-cURL) by Jürgen Hötzel [Mono](https://web.archive.org/web/20070606064500/https://forge.novell.com/modules/xfmod/project/?libcurl-mono) Written by Jeffrey Phillips diff --git a/docs/cmdline-opts/write-out.md b/docs/cmdline-opts/write-out.md index 4f2f99dc4..ecf1ffcd6 100644 --- a/docs/cmdline-opts/write-out.md +++ b/docs/cmdline-opts/write-out.md @@ -356,8 +356,13 @@ performed using the same connection cache. TIME OUTPUT FORMAT -When showing time with `%time{}`, the following output qualifiers are -available: +To show time with `%time{}` the characters within `{}` creates a special +format string that may contain special character sequences called conversion +specifications. Each conversion specification starts with `%` and is followed +by a character that instructs curl to output a particular time detail. All +other characters used are displayed as-is and- + +The following conversion specification are available: ## `%a` @@ -378,7 +383,7 @@ The full month name according to the current locale. ## `%c` The preferred date and time representation for the current locale. (In the -POSIX locale this is equivalent to %a %b %e %H:%M:%S %Y.) +POSIX locale this is equivalent to `%a %b %e %H:%M:%S %Y`.) ## `%C` @@ -390,12 +395,12 @@ The day of the month as a decimal number (range 01 to 31). ## `%D` -Equivalent to %m/%d/%y. In international contexts, this format is ambiguous +Equivalent to `%m/%d/%y`. In international contexts, this format is ambiguous and should be avoided.) ## `%e` -Like %d, the day of the month as a decimal number, but a leading zero is +Like `%d`, the day of the month as a decimal number, but a leading zero is replaced by a space. ## `%f` @@ -405,14 +410,14 @@ code and not a standard one.) ## `%F` -Equivalent to %Y-%m-%d (the ISO 8601 date format). +Equivalent to `%Y-%m-%d` (the ISO 8601 date format). ## `%G` The ISO 8601 week-based year with century as a decimal number. The 4-digit -year corresponding to the ISO week number (see %V). This has the same format -and value as %Y, except that if the ISO week number belongs to the previous or -next year, that year is used instead. +year corresponding to the ISO week number (see `%V`). This has the same format +and value as `%Y`, except that if the ISO week number belongs to the previous +or next year, that year is used instead. ## `%g` @@ -459,7 +464,7 @@ strings for the current locale. Noon is treated as "PM" and midnight as "AM". ## `%P` -Like %p but in lowercase: "am" or "pm" or a corresponding string for the +Like `%p` but in lowercase: "am" or "pm" or a corresponding string for the current locale. ## `%r` @@ -468,8 +473,8 @@ The time in am or pm notation. ## `%R` -The time in 24-hour notation (%H:%M). For a version including the seconds, see -`%T` below. +The time in 24-hour notation (`%H:%M`). For a version including the seconds, +see `%T` below. ## `%s` @@ -478,11 +483,11 @@ The number of seconds since the Epoch, 1970-01-01 00:00:00 +0000 (UTC). ## `%S` The second as a decimal number (range 00 to 60). (The range is up to 60 to -allow for occasional leap seconds.) +allow for occasional leap seconds.) See `%f` for microseconds. ## `%T` -The time in 24-hour notation (%H:%M:%S). +The time in 24-hour notation (`%H:%M:%S`). ## `%u` @@ -533,3 +538,7 @@ from UTC). As time is always UTC, this outputs `+0000`. ## `%Z` The timezone name. For some reason `GMT`. + +## `%%` + +A literal `%` character. diff --git a/lib/asyn-ares.c b/lib/asyn-ares.c index 375f1a6eb..815d7ab57 100644 --- a/lib/asyn-ares.c +++ b/lib/asyn-ares.c @@ -237,26 +237,6 @@ CURLcode Curl_async_get_impl(struct Curl_easy *data, void **impl) return result; } -static void async_ares_cleanup(struct Curl_easy *data); - -void Curl_async_ares_shutdown(struct Curl_easy *data) -{ - struct async_ares_ctx *ares = &data->state.async.ares; - if(ares->channel) - ares_cancel(ares->channel); - async_ares_cleanup(data); -} - -void Curl_async_ares_destroy(struct Curl_easy *data) -{ - struct async_ares_ctx *ares = &data->state.async.ares; - Curl_async_ares_shutdown(data); - if(ares->channel) { - ares_destroy(ares->channel); - ares->channel = NULL; - } -} - /* * async_ares_cleanup() cleans up async resolver data. */ @@ -272,6 +252,26 @@ static void async_ares_cleanup(struct Curl_easy *data) #endif } +void Curl_async_ares_shutdown(struct Curl_easy *data) +{ + /* c-ares has a method to "cancel" operations on a channel, but + * as reported in #18216, this does not totally reset the channel + * and ares may get stuck. + * We need to destroy the channel and on demand create a new + * one to avoid that. */ + Curl_async_ares_destroy(data); +} + +void Curl_async_ares_destroy(struct Curl_easy *data) +{ + struct async_ares_ctx *ares = &data->state.async.ares; + if(ares->channel) { + ares_destroy(ares->channel); + ares->channel = NULL; + } + async_ares_cleanup(data); +} + /* * Curl_async_pollset() is called when someone from the outside world * (using curl_multi_fdset()) wants to get our fd_set setup. diff --git a/lib/cfilters.c b/lib/cfilters.c index e4b630bc8..efd2ac6f6 100644 --- a/lib/cfilters.c +++ b/lib/cfilters.c @@ -177,6 +177,10 @@ CURLcode Curl_conn_shutdown(struct Curl_easy *data, int sockindex, bool *done) struct curltime now; DEBUGASSERT(data->conn); + + if(!CONN_SOCK_IDX_VALID(sockindex)) + return CURLE_BAD_FUNCTION_ARGUMENT; + /* Get the first connected filter that is not shut down already. */ cf = data->conn->cfilter[sockindex]; while(cf && (!cf->connected || cf->shutdown)) @@ -477,6 +481,8 @@ CURLcode Curl_conn_connect(struct Curl_easy *data, DEBUGASSERT(data); DEBUGASSERT(data->conn); + if(!CONN_SOCK_IDX_VALID(sockindex)) + return CURLE_BAD_FUNCTION_ARGUMENT; cf = data->conn->cfilter[sockindex]; if(!cf) { @@ -568,6 +574,8 @@ out: bool Curl_conn_is_setup(struct connectdata *conn, int sockindex) { + if(!CONN_SOCK_IDX_VALID(sockindex)) + return FALSE; return (conn->cfilter[sockindex] != NULL); } @@ -575,6 +583,8 @@ bool Curl_conn_is_connected(struct connectdata *conn, int sockindex) { struct Curl_cfilter *cf; + if(!CONN_SOCK_IDX_VALID(sockindex)) + return FALSE; cf = conn->cfilter[sockindex]; return cf && cf->connected; } @@ -583,6 +593,8 @@ bool Curl_conn_is_ip_connected(struct Curl_easy *data, int sockindex) { struct Curl_cfilter *cf; + if(!CONN_SOCK_IDX_VALID(sockindex)) + return FALSE; cf = data->conn->cfilter[sockindex]; while(cf) { if(cf->connected) @@ -607,6 +619,8 @@ static bool cf_is_ssl(struct Curl_cfilter *cf) bool Curl_conn_is_ssl(struct connectdata *conn, int sockindex) { + if(!CONN_SOCK_IDX_VALID(sockindex)) + return FALSE; return conn ? cf_is_ssl(conn->cfilter[sockindex]) : FALSE; } @@ -614,6 +628,8 @@ bool Curl_conn_get_ssl_info(struct Curl_easy *data, struct connectdata *conn, int sockindex, struct curl_tlssessioninfo *info) { + if(!CONN_SOCK_IDX_VALID(sockindex)) + return FALSE; if(Curl_conn_is_ssl(conn, sockindex)) { struct Curl_cfilter *cf = conn->cfilter[sockindex]; CURLcode result = cf ? cf->cft->query(cf, data, CF_QUERY_SSL_INFO, @@ -627,13 +643,20 @@ CURLcode Curl_conn_get_ip_info(struct Curl_easy *data, struct connectdata *conn, int sockindex, bool *is_ipv6, struct ip_quadruple *ipquad) { - struct Curl_cfilter *cf = conn ? conn->cfilter[sockindex] : NULL; + struct Curl_cfilter *cf; + if(!CONN_SOCK_IDX_VALID(sockindex)) + return CURLE_BAD_FUNCTION_ARGUMENT; + cf = conn ? conn->cfilter[sockindex] : NULL; return Curl_conn_cf_get_ip_info(cf, data, is_ipv6, ipquad); } bool Curl_conn_is_multiplex(struct connectdata *conn, int sockindex) { - struct Curl_cfilter *cf = conn ? conn->cfilter[sockindex] : NULL; + struct Curl_cfilter *cf; + + if(!CONN_SOCK_IDX_VALID(sockindex)) + return FALSE; + cf = conn ? conn->cfilter[sockindex] : NULL; for(; cf; cf = cf->next) { if(cf->cft->flags & CF_TYPE_MULTIPLEX) @@ -689,6 +712,8 @@ bool Curl_conn_data_pending(struct Curl_easy *data, int sockindex) (void)data; DEBUGASSERT(data); DEBUGASSERT(data->conn); + if(!CONN_SOCK_IDX_VALID(sockindex)) + return FALSE; cf = data->conn->cfilter[sockindex]; while(cf && !cf->connected) { @@ -712,6 +737,8 @@ bool Curl_conn_cf_needs_flush(struct Curl_cfilter *cf, bool Curl_conn_needs_flush(struct Curl_easy *data, int sockindex) { + if(!CONN_SOCK_IDX_VALID(sockindex)) + return FALSE; return Curl_conn_cf_needs_flush(data->conn->cfilter[sockindex], data); } @@ -774,8 +801,14 @@ void Curl_conn_get_current_host(struct Curl_easy *data, int sockindex, { struct Curl_cfilter *cf, *cf_proxy = NULL; - DEBUGASSERT(data->conn); - cf = data->conn->cfilter[sockindex]; + if(!data->conn) { + DEBUGASSERT(0); + *phost = ""; + *pport = -1; + return; + } + + cf = CONN_SOCK_IDX_VALID(sockindex) ? data->conn->cfilter[sockindex] : NULL; /* Find the "lowest" tunneling proxy filter that has not connected yet. */ while(cf && !cf->connected) { if((cf->cft->flags & (CF_TYPE_IP_CONNECT|CF_TYPE_PROXY)) == @@ -877,29 +910,33 @@ CURLcode Curl_conn_cf_get_ip_info(struct Curl_cfilter *cf, return result; } -curl_socket_t Curl_conn_get_socket(struct Curl_easy *data, int sockindex) +curl_socket_t Curl_conn_get_first_socket(struct Curl_easy *data) { struct Curl_cfilter *cf; - cf = data->conn ? data->conn->cfilter[sockindex] : NULL; + if(!data->conn) + return CURL_SOCKET_BAD; + + cf = data->conn->cfilter[FIRSTSOCKET]; /* if the top filter has not connected, ask it (and its sub-filters) - * for the socket. Otherwise conn->sock[sockindex] should have it. - */ + * for the socket. Otherwise conn->sock[sockindex] should have it. */ if(cf && !cf->connected) return Curl_conn_cf_get_socket(cf, data); - return data->conn ? data->conn->sock[sockindex] : CURL_SOCKET_BAD; + return data->conn->sock[FIRSTSOCKET]; } const struct Curl_sockaddr_ex * Curl_conn_get_remote_addr(struct Curl_easy *data, int sockindex) { - struct Curl_cfilter *cf = data->conn ? data->conn->cfilter[sockindex] : NULL; + struct Curl_cfilter *cf = + (data->conn && CONN_SOCK_IDX_VALID(sockindex)) ? + data->conn->cfilter[sockindex] : NULL; return cf ? cf_get_remote_addr(cf, data) : NULL; } void Curl_conn_forget_socket(struct Curl_easy *data, int sockindex) { - if(data->conn) { + if(data->conn && CONN_SOCK_IDX_VALID(sockindex)) { struct Curl_cfilter *cf = data->conn->cfilter[sockindex]; if(cf) (void)Curl_conn_cf_cntrl(cf, data, TRUE, @@ -941,6 +978,8 @@ CURLcode Curl_conn_ev_data_idle(struct Curl_easy *data) CURLcode Curl_conn_flush(struct Curl_easy *data, int sockindex) { + if(!CONN_SOCK_IDX_VALID(sockindex)) + return CURLE_BAD_FUNCTION_ARGUMENT; return Curl_conn_cf_cntrl(data->conn->cfilter[sockindex], data, FALSE, CF_CTRL_FLUSH, 0, NULL); } @@ -1010,7 +1049,11 @@ CURLcode Curl_conn_keep_alive(struct Curl_easy *data, struct connectdata *conn, int sockindex) { - struct Curl_cfilter *cf = conn->cfilter[sockindex]; + struct Curl_cfilter *cf; + + if(!CONN_SOCK_IDX_VALID(sockindex)) + return CURLE_BAD_FUNCTION_ARGUMENT; + cf = conn->cfilter[sockindex]; return cf ? cf->cft->keep_alive(cf, data) : CURLE_OK; } @@ -1018,10 +1061,14 @@ size_t Curl_conn_get_max_concurrent(struct Curl_easy *data, struct connectdata *conn, int sockindex) { + struct Curl_cfilter *cf; CURLcode result; int n = -1; - struct Curl_cfilter *cf = conn->cfilter[sockindex]; + if(!CONN_SOCK_IDX_VALID(sockindex)) + return 0; + + cf = conn->cfilter[sockindex]; result = cf ? cf->cft->query(cf, data, CF_QUERY_MAX_CONCURRENT, &n, NULL) : CURLE_UNKNOWN_OPTION; /* If no filter answered the query, the default is a non-multiplexed @@ -1034,10 +1081,14 @@ int Curl_conn_get_stream_error(struct Curl_easy *data, struct connectdata *conn, int sockindex) { + struct Curl_cfilter *cf; CURLcode result; int n = 0; - struct Curl_cfilter *cf = conn->cfilter[sockindex]; + if(!CONN_SOCK_IDX_VALID(sockindex)) + return 0; + + cf = conn->cfilter[sockindex]; result = cf ? cf->cft->query(cf, data, CF_QUERY_STREAM_ERROR, &n, NULL) : CURLE_UNKNOWN_OPTION; return (result || n < 0) ? 0 : n; @@ -1056,6 +1107,8 @@ CURLcode Curl_conn_recv(struct Curl_easy *data, int sockindex, { DEBUGASSERT(data); DEBUGASSERT(data->conn); + if(!CONN_SOCK_IDX_VALID(sockindex)) + return CURLE_BAD_FUNCTION_ARGUMENT; if(data && data->conn && data->conn->recv[sockindex]) return data->conn->recv[sockindex](data, sockindex, buf, blen, pnread); *pnread = 0; @@ -1070,7 +1123,9 @@ CURLcode Curl_conn_send(struct Curl_easy *data, int sockindex, DEBUGASSERT(data); DEBUGASSERT(data->conn); - DEBUGASSERT(sockindex >= 0 && sockindex < 2); + DEBUGASSERT(CONN_SOCK_IDX_VALID(sockindex)); + if(!CONN_SOCK_IDX_VALID(sockindex)) + return CURLE_BAD_FUNCTION_ARGUMENT; #ifdef DEBUGBUILD if(write_len) { /* Allow debug builds to override this logic to force short sends diff --git a/lib/cfilters.h b/lib/cfilters.h index 458ce5893..815b72a6e 100644 --- a/lib/cfilters.h +++ b/lib/cfilters.h @@ -460,10 +460,11 @@ bool Curl_conn_needs_flush(struct Curl_easy *data, int sockindex); CURLcode Curl_conn_flush(struct Curl_easy *data, int sockindex); /** - * Return the socket used on data's connection for the index. + * Return the socket used on data's connection for FIRSTSOCKET, + * querying filters if the whole chain has not connected yet. * Returns CURL_SOCKET_BAD if not available. */ -curl_socket_t Curl_conn_get_socket(struct Curl_easy *data, int sockindex); +curl_socket_t Curl_conn_get_first_socket(struct Curl_easy *data); /* Return a pointer to the connected socket address or NULL. */ const struct Curl_sockaddr_ex * diff --git a/lib/curl_rtmp.c b/lib/curl_rtmp.c index 584c8a9df..b178dff84 100644 --- a/lib/curl_rtmp.c +++ b/lib/curl_rtmp.c @@ -296,10 +296,10 @@ static CURLcode rtmp_do(struct Curl_easy *data, bool *done) if(data->state.upload) { Curl_pgrsSetUploadSize(data, data->state.infilesize); - Curl_xfer_setup1(data, CURL_XFER_SEND, -1, FALSE); + Curl_xfer_setup_send(data, FIRSTSOCKET); } else - Curl_xfer_setup1(data, CURL_XFER_RECV, -1, FALSE); + Curl_xfer_setup_recv(data, FIRSTSOCKET, -1); *done = TRUE; return CURLE_OK; } diff --git a/lib/curlx/dynbuf.c b/lib/curlx/dynbuf.c index cd4f4635a..447203e42 100644 --- a/lib/curlx/dynbuf.c +++ b/lib/curlx/dynbuf.c @@ -231,6 +231,7 @@ CURLcode curlx_dyn_addf(struct dynbuf *s, const char *fmt, ...) DEBUGASSERT(s); DEBUGASSERT(s->init == DYNINIT); DEBUGASSERT(!s->leng || s->bufr); + DEBUGASSERT(strcmp(fmt, "%s")); /* use curlx_dyn_add instead */ va_start(ap, fmt); result = curlx_dyn_vaddf(s, fmt, ap); va_end(ap); diff --git a/lib/dict.c b/lib/dict.c index 30e13b454..819584f28 100644 --- a/lib/dict.c +++ b/lib/dict.c @@ -242,7 +242,7 @@ static CURLcode dict_do(struct Curl_easy *data, bool *done) failf(data, "Failed sending DICT request"); goto error; } - Curl_xfer_setup1(data, CURL_XFER_RECV, -1, FALSE); /* no upload */ + Curl_xfer_setup_recv(data, FIRSTSOCKET, -1); } else if(curl_strnequal(path, DICT_DEFINE, sizeof(DICT_DEFINE)-1) || curl_strnequal(path, DICT_DEFINE2, sizeof(DICT_DEFINE2)-1) || @@ -283,7 +283,7 @@ static CURLcode dict_do(struct Curl_easy *data, bool *done) failf(data, "Failed sending DICT request"); goto error; } - Curl_xfer_setup1(data, CURL_XFER_RECV, -1, FALSE); + Curl_xfer_setup_recv(data, FIRSTSOCKET, -1); } else { @@ -305,7 +305,7 @@ static CURLcode dict_do(struct Curl_easy *data, bool *done) goto error; } - Curl_xfer_setup1(data, CURL_XFER_RECV, -1, FALSE); + Curl_xfer_setup_recv(data, FIRSTSOCKET, -1); } } @@ -546,12 +546,13 @@ static CURLcode ftp_initiate_transfer(struct Curl_easy *data, /* FTP upload, shutdown DATA, ignore shutdown errors, as we rely * on the server response on the CONTROL connection. */ - Curl_xfer_setup2(data, CURL_XFER_SEND, -1, TRUE, TRUE); + Curl_xfer_setup_send(data, SECONDARYSOCKET); + Curl_xfer_set_shutdown(data, TRUE, TRUE); } else { /* FTP download, shutdown, do not ignore errors */ - Curl_xfer_setup2(data, CURL_XFER_RECV, - ftpc->retr_size_saved, TRUE, FALSE); + Curl_xfer_setup_recv(data, SECONDARYSOCKET, ftpc->retr_size_saved); + Curl_xfer_set_shutdown(data, TRUE, FALSE); } ftpc->pp.pending_resp = TRUE; /* expect server response */ diff --git a/lib/gopher.c b/lib/gopher.c index 82e02ed17..93db85e9d 100644 --- a/lib/gopher.c +++ b/lib/gopher.c @@ -240,7 +240,7 @@ static CURLcode gopher_do(struct Curl_easy *data, bool *done) if(result) return result; - Curl_xfer_setup1(data, CURL_XFER_RECV, -1, FALSE); + Curl_xfer_setup_recv(data, FIRSTSOCKET, -1); return CURLE_OK; } #endif /* CURL_DISABLE_GOPHER */ diff --git a/lib/http.c b/lib/http.c index 8eb137885..758ee50de 100644 --- a/lib/http.c +++ b/lib/http.c @@ -1528,8 +1528,7 @@ CURLcode Curl_http_do_pollset(struct Curl_easy *data, struct easy_pollset *ps) { /* write mode */ - curl_socket_t sock = Curl_conn_get_socket(data, FIRSTSOCKET); - return Curl_pollset_add_out(data, ps, sock); + return Curl_pollset_add_out(data, ps, data->conn->sock[FIRSTSOCKET]); } /* @@ -2415,7 +2414,7 @@ static CURLcode http_req_complete(struct Curl_easy *data, out: if(!result) { /* setup variables for the upcoming transfer */ - Curl_xfer_setup1(data, CURL_XFER_SENDRECV, -1, TRUE); + Curl_xfer_setup_sendrecv(data, FIRSTSOCKET, -1); } return result; } diff --git a/lib/imap.c b/lib/imap.c index 5949b667e..7e6b132ba 100644 --- a/lib/imap.c +++ b/lib/imap.c @@ -1347,7 +1347,7 @@ static CURLcode imap_state_fetch_resp(struct Curl_easy *data, else { /* IMAP download */ data->req.maxdownload = size; - Curl_xfer_setup1(data, CURL_XFER_RECV, size, FALSE); + Curl_xfer_setup_recv(data, FIRSTSOCKET, size); } } else { @@ -1398,7 +1398,7 @@ static CURLcode imap_state_append_resp(struct Curl_easy *data, Curl_pgrsSetUploadSize(data, data->state.infilesize); /* IMAP upload */ - Curl_xfer_setup1(data, CURL_XFER_SEND, -1, FALSE); + Curl_xfer_setup_send(data, FIRSTSOCKET); /* End of DO phase */ imap_state(data, imapc, IMAP_STOP); diff --git a/lib/multi.c b/lib/multi.c index 370cb97d5..d38155cd9 100644 --- a/lib/multi.c +++ b/lib/multi.c @@ -912,7 +912,7 @@ static CURLcode mstate_connecting_pollset(struct Curl_easy *data, struct easy_pollset *ps) { if(data->conn) { - curl_socket_t sockfd = Curl_conn_get_socket(data, FIRSTSOCKET); + curl_socket_t sockfd = Curl_conn_get_first_socket(data); if(sockfd != CURL_SOCKET_BAD) { /* Default is to wait to something from the server */ return Curl_pollset_change(data, ps, sockfd, CURL_POLL_IN, 0); @@ -928,7 +928,7 @@ static CURLcode mstate_protocol_pollset(struct Curl_easy *data, curl_socket_t sockfd; if(data->conn->handler->proto_pollset) return data->conn->handler->proto_pollset(data, ps); - sockfd = Curl_conn_get_socket(data, FIRSTSOCKET); + sockfd = data->conn->sock[FIRSTSOCKET]; if(sockfd != CURL_SOCKET_BAD) { /* Default is to wait to something from the server */ return Curl_pollset_change(data, ps, sockfd, CURL_POLL_IN, 0); @@ -940,13 +940,13 @@ static CURLcode mstate_protocol_pollset(struct Curl_easy *data, static CURLcode mstate_do_pollset(struct Curl_easy *data, struct easy_pollset *ps) { - struct connectdata *conn = data->conn; if(data->conn) { if(data->conn->handler->doing_pollset) return data->conn->handler->doing_pollset(data, ps); - else if(conn->sockfd != CURL_SOCKET_BAD) { + else if(CONN_SOCK_IDX_VALID(data->conn->send_idx)) { /* Default is that we want to send something to the server */ - return Curl_pollset_add_out(data, ps, conn->sockfd); + return Curl_pollset_add_out( + data, ps, data->conn->sock[data->conn->send_idx]); } } return CURLE_OK; @@ -958,9 +958,10 @@ static CURLcode mstate_domore_pollset(struct Curl_easy *data, if(data->conn) { if(data->conn->handler->domore_pollset) return data->conn->handler->domore_pollset(data, ps); - else if(data->conn->sockfd != CURL_SOCKET_BAD) { + else if(CONN_SOCK_IDX_VALID(data->conn->send_idx)) { /* Default is that we want to send something to the server */ - return Curl_pollset_add_out(data, ps, data->conn->sockfd); + return Curl_pollset_add_out( + data, ps, data->conn->sock[data->conn->send_idx]); } } return CURLE_OK; @@ -976,14 +977,15 @@ static CURLcode mstate_perform_pollset(struct Curl_easy *data, else { /* Default is to obey the data->req.keepon flags for send/recv */ CURLcode result = CURLE_OK; - if(CURL_WANT_RECV(data)) { - DEBUGASSERT(data->conn->sockfd != CURL_SOCKET_BAD); - result = Curl_pollset_add_in(data, ps, data->conn->sockfd); + if(CURL_WANT_RECV(data) && CONN_SOCK_IDX_VALID(data->conn->recv_idx)) { + result = Curl_pollset_add_in( + data, ps, data->conn->sock[data->conn->recv_idx]); } - if(!result && Curl_req_want_send(data)) { - DEBUGASSERT(data->conn->writesockfd != CURL_SOCKET_BAD); - result = Curl_pollset_add_out(data, ps, data->conn->writesockfd); + if(!result && Curl_req_want_send(data) && + CONN_SOCK_IDX_VALID(data->conn->send_idx)) { + result = Curl_pollset_add_out( + data, ps, data->conn->sock[data->conn->send_idx]); } return result; } @@ -2555,8 +2557,8 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, /* Only perform the transfer if there is a good socket to work with. Having both BAD is a signal to skip immediately to DONE */ - if((data->conn->sockfd != CURL_SOCKET_BAD) || - (data->conn->writesockfd != CURL_SOCKET_BAD)) + if(CONN_SOCK_IDX_VALID(data->conn->recv_idx) || + CONN_SOCK_IDX_VALID(data->conn->send_idx)) multistate(data, MSTATE_PERFORMING); else { #ifndef CURL_DISABLE_FTP @@ -2791,16 +2793,15 @@ CURLMcode curl_multi_perform(CURLM *m, int *running_handles) if(t) { /* the removed may have another timeout in queue */ struct Curl_easy *data = Curl_splayget(t); + (void)add_next_timeout(now, multi, data); if(data->mstate == MSTATE_PENDING) { bool stream_unused; CURLcode result_unused; if(multi_handle_timeout(data, &now, &stream_unused, &result_unused)) { infof(data, "PENDING handle timeout"); move_pending_to_connect(multi, data); - continue; } } - (void)add_next_timeout(now, multi, Curl_splayget(t)); } } while(t); diff --git a/lib/openldap.c b/lib/openldap.c index c532be3f3..1b32e12b6 100644 --- a/lib/openldap.c +++ b/lib/openldap.c @@ -993,7 +993,7 @@ static CURLcode oldap_do(struct Curl_easy *data, bool *done) } lr->msgid = msgid; - Curl_xfer_setup1(data, CURL_XFER_RECV, -1, FALSE); + Curl_xfer_setup_recv(data, FIRSTSOCKET, -1); *done = TRUE; out: diff --git a/lib/pop3.c b/lib/pop3.c index 493b36f45..508f8faed 100644 --- a/lib/pop3.c +++ b/lib/pop3.c @@ -1116,7 +1116,7 @@ static CURLcode pop3_state_command_resp(struct Curl_easy *data, if(pop3->transfer == PPTRANSFER_BODY) { /* POP3 download */ - Curl_xfer_setup1(data, CURL_XFER_RECV, -1, FALSE); + Curl_xfer_setup_recv(data, FIRSTSOCKET, -1); if(pp->overflow) { /* The recv buffer contains data that is actually body content so send diff --git a/lib/request.c b/lib/request.c index 9fc9ab4d6..733e3e929 100644 --- a/lib/request.c +++ b/lib/request.c @@ -62,7 +62,7 @@ CURLcode Curl_req_soft_reset(struct SingleRequest *req, req->shutdown = FALSE; req->bytecount = 0; req->writebytecount = 0; - req->header = TRUE; /* assume header */ + req->header = FALSE; req->headerline = 0; req->headerbytecount = 0; req->allheadercount = 0; @@ -153,6 +153,7 @@ void Curl_req_hard_reset(struct SingleRequest *req, struct Curl_easy *data) req->eos_written = FALSE; req->eos_read = FALSE; req->eos_sent = FALSE; + req->rewind_read = FALSE; req->upload_done = FALSE; req->upload_aborted = FALSE; req->ignorebody = FALSE; @@ -160,7 +161,6 @@ void Curl_req_hard_reset(struct SingleRequest *req, struct Curl_easy *data) req->chunk = FALSE; req->ignore_cl = FALSE; req->upload_chunky = FALSE; - req->getheader = FALSE; req->no_body = data->set.opt_no_body; req->authneg = FALSE; req->shutdown = FALSE; diff --git a/lib/request.h b/lib/request.h index 74d9f5343..bce34de8b 100644 --- a/lib/request.h +++ b/lib/request.h @@ -123,7 +123,6 @@ struct SingleRequest { BIT(ignore_cl); /* ignore content-length */ BIT(upload_chunky); /* set TRUE if we are doing chunked transfer-encoding on upload */ - BIT(getheader); /* TRUE if header parsing is wanted */ BIT(no_body); /* the response has no body */ BIT(authneg); /* TRUE when the auth phase has started, which means that we are creating a request with an auth header, diff --git a/lib/rtsp.c b/lib/rtsp.c index 46ff660ae..dbe3e63cf 100644 --- a/lib/rtsp.c +++ b/lib/rtsp.c @@ -100,6 +100,10 @@ static CURLcode rtsp_rtp_write_resp(struct Curl_easy *data, const char *buf, size_t blen, bool is_eos); +static CURLcode rtsp_rtp_write_resp_hd(struct Curl_easy *data, + const char *buf, + size_t blen, + bool is_eos); static CURLcode rtsp_setup_connection(struct Curl_easy *data, struct connectdata *conn); @@ -141,7 +145,7 @@ const struct Curl_handler Curl_handler_rtsp = { ZERO_NULL, /* perform_pollset */ ZERO_NULL, /* disconnect */ rtsp_rtp_write_resp, /* write_resp */ - ZERO_NULL, /* write_resp_hd */ + rtsp_rtp_write_resp_hd, /* write_resp_hd */ rtsp_conncheck, /* connection_check */ ZERO_NULL, /* attach connection */ Curl_http_follow, /* follow */ @@ -370,7 +374,7 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done) } if(rtspreq == RTSPREQ_RECEIVE) { - Curl_xfer_setup1(data, CURL_XFER_RECV, -1, TRUE); + Curl_xfer_setup_recv(data, FIRSTSOCKET, -1); goto out; } @@ -636,7 +640,7 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done) if(result) goto out; - Curl_xfer_setup1(data, CURL_XFER_SENDRECV, -1, TRUE); + Curl_xfer_setup_sendrecv(data, FIRSTSOCKET, -1); /* issue the request */ result = Curl_req_send(data, &req_buffer, httpversion); @@ -935,6 +939,14 @@ out: return result; } +static CURLcode rtsp_rtp_write_resp_hd(struct Curl_easy *data, + const char *buf, + size_t blen, + bool is_eos) +{ + return rtsp_rtp_write_resp(data, buf, blen, is_eos); +} + static CURLcode rtp_client_write(struct Curl_easy *data, const char *ptr, size_t len) { diff --git a/lib/smtp.c b/lib/smtp.c index 4bb3bde4a..97083e41f 100644 --- a/lib/smtp.c +++ b/lib/smtp.c @@ -1257,7 +1257,7 @@ static CURLcode smtp_state_data_resp(struct Curl_easy *data, Curl_pgrsSetUploadSize(data, data->state.infilesize); /* SMTP upload */ - Curl_xfer_setup1(data, CURL_XFER_SEND, -1, FALSE); + Curl_xfer_setup_send(data, FIRSTSOCKET); /* End of DO phase */ smtp_state(data, smtpc, SMTP_STOP); diff --git a/lib/splay.c b/lib/splay.c index 609b799bf..3ca8678b2 100644 --- a/lib/splay.c +++ b/lib/splay.c @@ -223,6 +223,7 @@ int Curl_splayremove(struct Curl_tree *t, if(compare(SPLAY_SUBNODE, removenode->key) == 0) { /* It is a subnode within a 'same' linked list and thus we can unlink it easily. */ + DEBUGASSERT(removenode->samen != removenode); if(removenode->samen == removenode) /* A non-subnode should never be set to SPLAY_SUBNODE */ return 3; diff --git a/lib/transfer.c b/lib/transfer.c index 84e4c5e92..50f621056 100644 --- a/lib/transfer.c +++ b/lib/transfer.c @@ -162,38 +162,23 @@ bool Curl_meets_timecondition(struct Curl_easy *data, time_t timeofdoc) static CURLcode xfer_recv_shutdown(struct Curl_easy *data, bool *done) { - int sockindex; - if(!data || !data->conn) return CURLE_FAILED_INIT; - if(data->conn->sockfd == CURL_SOCKET_BAD) - return CURLE_FAILED_INIT; - sockindex = (data->conn->sockfd == data->conn->sock[SECONDARYSOCKET]); - return Curl_conn_shutdown(data, sockindex, done); + return Curl_conn_shutdown(data, data->conn->recv_idx, done); } static bool xfer_recv_shutdown_started(struct Curl_easy *data) { - int sockindex; - if(!data || !data->conn) return FALSE; - if(data->conn->sockfd == CURL_SOCKET_BAD) - return FALSE; - sockindex = (data->conn->sockfd == data->conn->sock[SECONDARYSOCKET]); - return Curl_shutdown_started(data, sockindex); + return Curl_shutdown_started(data, data->conn->recv_idx); } CURLcode Curl_xfer_send_shutdown(struct Curl_easy *data, bool *done) { - int sockindex; - if(!data || !data->conn) return CURLE_FAILED_INIT; - if(data->conn->writesockfd == CURL_SOCKET_BAD) - return CURLE_FAILED_INIT; - sockindex = (data->conn->writesockfd == data->conn->sock[SECONDARYSOCKET]); - return Curl_conn_shutdown(data, sockindex, done); + return Curl_conn_shutdown(data, data->conn->send_idx, done); } /** @@ -732,101 +717,88 @@ CURLcode Curl_retry_request(struct Curl_easy *data, char **url) return CURLE_OK; } -/* - * xfer_setup() is called to setup basic properties for the transfer. - */ static void xfer_setup( struct Curl_easy *data, /* transfer */ - int sockindex, /* socket index to read from or -1 */ - curl_off_t size, /* -1 if unknown at this point */ - bool getheader, /* TRUE if header parsing is wanted */ - int writesockindex, /* socket index to write to, it may be the same we - read from. -1 disables */ - bool shutdown, /* shutdown connection at transfer end. Only - * supported when sending OR receiving. */ - bool shutdown_err_ignore /* errors during shutdown do not fail the - * transfer */ + int send_idx, /* sockindex to send on or -1 */ + int recv_idx, /* sockindex to receive on or -1 */ + curl_off_t recv_size /* how much to receive, -1 if unknown */ ) { struct SingleRequest *k = &data->req; struct connectdata *conn = data->conn; - bool want_send = Curl_req_want_send(data); DEBUGASSERT(conn != NULL); - DEBUGASSERT((sockindex <= 1) && (sockindex >= -1)); - DEBUGASSERT((writesockindex <= 1) && (writesockindex >= -1)); - DEBUGASSERT(!shutdown || (sockindex == -1) || (writesockindex == -1)); - - if(Curl_conn_is_multiplex(conn, FIRSTSOCKET) || want_send) { - /* when multiplexing, the read/write sockets need to be the same! */ - conn->sockfd = sockindex == -1 ? - ((writesockindex == -1 ? CURL_SOCKET_BAD : conn->sock[writesockindex])) : - conn->sock[sockindex]; - conn->writesockfd = conn->sockfd; - if(want_send) - /* special and HTTP-specific */ - writesockindex = FIRSTSOCKET; - } - else { - conn->sockfd = sockindex == -1 ? - CURL_SOCKET_BAD : conn->sock[sockindex]; - conn->writesockfd = writesockindex == -1 ? - CURL_SOCKET_BAD : conn->sock[writesockindex]; - } - - k->getheader = getheader; - k->size = size; - k->shutdown = shutdown; - k->shutdown_err_ignore = shutdown_err_ignore; + /* indexes are in range */ + DEBUGASSERT((send_idx <= 1) && (send_idx >= -1)); + DEBUGASSERT((recv_idx <= 1) && (recv_idx >= -1)); + /* if request wants to send, switching off the send direction is wrong */ + DEBUGASSERT((send_idx >= 0) || !Curl_req_want_send(data)); + + conn->send_idx = send_idx; + conn->recv_idx = recv_idx; + + /* without receiving, there should be not recv_size */ + DEBUGASSERT((conn->recv_idx >= 0) || (recv_size == -1)); + k->size = recv_size; + k->header = !!conn->handler->write_resp_hd; + /* by default, we do not shutdown at the end of the transfer */ + k->shutdown = FALSE; + k->shutdown_err_ignore = FALSE; /* The code sequence below is placed in this function just because all necessary input is not always known in do_complete() as this function may be called after that */ + if(!k->header && (recv_size > 0)) + Curl_pgrsSetDownloadSize(data, recv_size); - if(!k->getheader) { - k->header = FALSE; - if(size > 0) - Curl_pgrsSetDownloadSize(data, size); - } /* we want header and/or body, if neither then do not do this! */ - if(k->getheader || !data->req.no_body) { + if(conn->handler->write_resp_hd || !data->req.no_body) { - if(sockindex != -1) + if(conn->recv_idx != -1) k->keepon |= KEEP_RECV; - if(writesockindex != -1) + if(conn->send_idx != -1) k->keepon |= KEEP_SEND; - } /* if(k->getheader || !data->req.no_body) */ + } + CURL_TRC_M(data, "xfer_setup: recv_idx=%d, send_idx=%d", + conn->recv_idx, conn->send_idx); } void Curl_xfer_setup_nop(struct Curl_easy *data) { - xfer_setup(data, -1, -1, FALSE, -1, FALSE, FALSE); + xfer_setup(data, -1, -1, -1); +} + +void Curl_xfer_setup_sendrecv(struct Curl_easy *data, + int sockindex, + curl_off_t recv_size) +{ + xfer_setup(data, sockindex, sockindex, recv_size); } -void Curl_xfer_setup1(struct Curl_easy *data, - int send_recv, - curl_off_t recv_size, - bool getheader) +void Curl_xfer_setup_send(struct Curl_easy *data, + int sockindex) { - int recv_index = (send_recv & CURL_XFER_RECV) ? FIRSTSOCKET : -1; - int send_index = (send_recv & CURL_XFER_SEND) ? FIRSTSOCKET : -1; - DEBUGASSERT((recv_index >= 0) || (recv_size == -1)); - xfer_setup(data, recv_index, recv_size, getheader, send_index, FALSE, FALSE); + xfer_setup(data, sockindex, -1, -1); } -void Curl_xfer_setup2(struct Curl_easy *data, - int send_recv, - curl_off_t recv_size, - bool shutdown, - bool shutdown_err_ignore) +void Curl_xfer_setup_recv(struct Curl_easy *data, + int sockindex, + curl_off_t recv_size) { - int recv_index = (send_recv & CURL_XFER_RECV) ? SECONDARYSOCKET : -1; - int send_index = (send_recv & CURL_XFER_SEND) ? SECONDARYSOCKET : -1; - DEBUGASSERT((recv_index >= 0) || (recv_size == -1)); - xfer_setup(data, recv_index, recv_size, FALSE, send_index, - shutdown, shutdown_err_ignore); + xfer_setup(data, -1, sockindex, recv_size); +} + +void Curl_xfer_set_shutdown(struct Curl_easy *data, + bool shutdown, + bool ignore_errors) +{ + /* Shutdown should only be set when the transfer only sends or receives. */ + DEBUGASSERT(!shutdown || + (data->conn->send_idx < 0) || (data->conn->recv_idx < 0)); + data->req.shutdown = shutdown; + data->req.shutdown_err_ignore = ignore_errors; } CURLcode Curl_xfer_write_resp(struct Curl_easy *data, @@ -886,18 +858,12 @@ CURLcode Curl_xfer_write_done(struct Curl_easy *data, bool premature) bool Curl_xfer_needs_flush(struct Curl_easy *data) { - int sockindex; - sockindex = ((data->conn->writesockfd != CURL_SOCKET_BAD) && - (data->conn->writesockfd == data->conn->sock[SECONDARYSOCKET])); - return Curl_conn_needs_flush(data, sockindex); + return Curl_conn_needs_flush(data, data->conn->send_idx); } CURLcode Curl_xfer_flush(struct Curl_easy *data) { - int sockindex; - sockindex = ((data->conn->writesockfd != CURL_SOCKET_BAD) && - (data->conn->writesockfd == data->conn->sock[SECONDARYSOCKET])); - return Curl_conn_flush(data, sockindex); + return Curl_conn_flush(data, data->conn->send_idx); } CURLcode Curl_xfer_send(struct Curl_easy *data, @@ -905,14 +871,12 @@ CURLcode Curl_xfer_send(struct Curl_easy *data, size_t *pnwritten) { CURLcode result; - int sockindex; DEBUGASSERT(data); DEBUGASSERT(data->conn); - sockindex = ((data->conn->writesockfd != CURL_SOCKET_BAD) && - (data->conn->writesockfd == data->conn->sock[SECONDARYSOCKET])); - result = Curl_conn_send(data, sockindex, buf, blen, eos, pnwritten); + result = Curl_conn_send(data, data->conn->send_idx, + buf, blen, eos, pnwritten); if(result == CURLE_AGAIN) { result = CURLE_OK; *pnwritten = 0; @@ -929,17 +893,13 @@ CURLcode Curl_xfer_recv(struct Curl_easy *data, char *buf, size_t blen, size_t *pnrcvd) { - int sockindex; - DEBUGASSERT(data); DEBUGASSERT(data->conn); DEBUGASSERT(data->set.buffer_size > 0); - sockindex = ((data->conn->sockfd != CURL_SOCKET_BAD) && - (data->conn->sockfd == data->conn->sock[SECONDARYSOCKET])); if((size_t)data->set.buffer_size < blen) blen = (size_t)data->set.buffer_size; - return Curl_conn_recv(data, sockindex, buf, blen, pnrcvd); + return Curl_conn_recv(data, data->conn->recv_idx, buf, blen, pnrcvd); } CURLcode Curl_xfer_send_close(struct Curl_easy *data) diff --git a/lib/transfer.h b/lib/transfer.h index 157c6b991..91a81e52e 100644 --- a/lib/transfer.h +++ b/lib/transfer.h @@ -64,38 +64,33 @@ bool Curl_xfer_write_is_paused(struct Curl_easy *data); CURLcode Curl_xfer_write_resp_hd(struct Curl_easy *data, const char *hd0, size_t hdlen, bool is_eos); -#define CURL_XFER_NOP (0) -#define CURL_XFER_RECV (1<<(0)) -#define CURL_XFER_SEND (1<<(1)) -#define CURL_XFER_SENDRECV (CURL_XFER_RECV|CURL_XFER_SEND) - -/** - * The transfer is neither receiving nor sending now. - */ +/* The transfer is neither receiving nor sending. */ void Curl_xfer_setup_nop(struct Curl_easy *data); -/** - * The transfer will use socket 1 to send/recv. `recv_size` is - * the amount to receive or -1 if unknown. `getheader` indicates - * response header processing is expected. - */ -void Curl_xfer_setup1(struct Curl_easy *data, - int send_recv, - curl_off_t recv_size, - bool getheader); +/* The transfer sends data on the given socket index */ +void Curl_xfer_setup_send(struct Curl_easy *data, + int sockindex); + +/* The transfer receives data on the given socket index, the + * amount to receive (or -1 if unknown). */ +void Curl_xfer_setup_recv(struct Curl_easy *data, + int sockindex, + curl_off_t recv_size); + +/* *After* Curl_xfer_setup_xxx(), tell the transfer to shutdown the + * connection at the end. Let the transfer either fail or ignore any + * errors during shutdown. */ +void Curl_xfer_set_shutdown(struct Curl_easy *data, + bool shutdown, + bool ignore_errors); /** - * The transfer will use socket 2 to send/recv. `recv_size` is - * the amount to receive or -1 if unknown. With `shutdown` being - * set, the transfer is only allowed to either send OR receive - * and the socket 2 connection will be shutdown at the end of - * the transfer. An unclean shutdown will fail the transfer - * unless `shutdown_err_ignore` is TRUE. + * The transfer will use socket 1 to send/recv. `recv_size` is + * the amount to receive or -1 if unknown. */ -void Curl_xfer_setup2(struct Curl_easy *data, - int send_recv, - curl_off_t recv_size, - bool shutdown, bool shutdown_err_ignore); +void Curl_xfer_setup_sendrecv(struct Curl_easy *data, + int sockindex, + curl_off_t recv_size); /** * Multi has set transfer to DONE. Last chance to trigger @@ -1397,8 +1397,8 @@ static struct connectdata *allocate_conn(struct Curl_easy *data) conn->sock[FIRSTSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */ conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */ - conn->sockfd = CURL_SOCKET_BAD; - conn->writesockfd = CURL_SOCKET_BAD; + conn->recv_idx = 0; /* default for receiving transfer data */ + conn->send_idx = 0; /* default for sending transfer data */ conn->connection_id = -1; /* no ID */ conn->remote_port = -1; /* unknown at this point */ diff --git a/lib/urldata.h b/lib/urldata.h index b9cc25b9b..a35512cf7 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -672,11 +672,18 @@ struct connectdata { char *oauth_bearer; /* OAUTH2 bearer, allocated */ struct curltime created; /* creation time */ struct curltime lastused; /* when returned to the connection poolas idle */ - curl_socket_t sock[2]; /* two sockets, the second is used for the data - transfer when doing FTP */ + + /* A connection can have one or two sockets and connection filters. + * The protocol using the 2nd one is FTP for CONTROL+DATA sockets */ + curl_socket_t sock[2]; + struct Curl_cfilter *cfilter[2]; /* connection filters */ Curl_recv *recv[2]; Curl_send *send[2]; - struct Curl_cfilter *cfilter[2]; /* connection filters */ + int recv_idx; /* on which socket index to receive, default 0 */ + int send_idx; /* on which socket index to send, default 0 */ + +#define CONN_SOCK_IDX_VALID(i) (((i) >= 0) && ((i) < 2)) + struct { struct curltime start[2]; /* when filter shutdown started */ timediff_t timeout_ms; /* 0 means no timeout */ @@ -698,10 +705,6 @@ struct connectdata { /**** curl_get() phase fields */ - curl_socket_t sockfd; /* socket to read from or CURL_SOCKET_BAD */ - curl_socket_t writesockfd; /* socket to write to, it may be the same we read - from. CURL_SOCKET_BAD disables */ - #ifdef HAVE_GSSAPI BIT(sec_complete); /* if Kerberos is enabled for this connection */ unsigned char command_prot; /* enum protection_level */ diff --git a/lib/vquic/curl_quiche.c b/lib/vquic/curl_quiche.c index f22566781..179ccf8aa 100644 --- a/lib/vquic/curl_quiche.c +++ b/lib/vquic/curl_quiche.c @@ -40,6 +40,7 @@ #include "../connect.h" #include "../progress.h" #include "../strerror.h" +#include "../select.h" #include "../http1.h" #include "vquic.h" #include "vquic_int.h" diff --git a/lib/vssh/libssh.c b/lib/vssh/libssh.c index d6ce1a65f..8c366aafa 100644 --- a/lib/vssh/libssh.c +++ b/lib/vssh/libssh.c @@ -1115,8 +1115,8 @@ static int myssh_in_AUTH_DONE(struct Curl_easy *data, /* At this point we have an authenticated ssh session. */ infof(data, "Authentication complete"); Curl_pgrsTime(data, TIMER_APPCONNECT); /* SSH is connected */ - data->conn->sockfd = data->conn->sock[FIRSTSOCKET]; - data->conn->writesockfd = CURL_SOCKET_BAD; + data->conn->recv_idx = FIRSTSOCKET; + data->conn->send_idx = -1; if(data->conn->handler->protocol == CURLPROTO_SFTP) { myssh_to(data, sshc, SSH_SFTP_INIT); @@ -1251,10 +1251,10 @@ static int myssh_in_UPLOAD_INIT(struct Curl_easy *data, Curl_pgrsSetUploadSize(data, data->state.infilesize); } /* upload data */ - Curl_xfer_setup1(data, CURL_XFER_SEND, -1, FALSE); + Curl_xfer_setup_send(data, FIRSTSOCKET); /* not set by Curl_xfer_setup to preserve keepon bits */ - data->conn->sockfd = data->conn->writesockfd; + data->conn->recv_idx = FIRSTSOCKET; /* store this original bitmask setup to use later on if we cannot figure out a "real" bitmask */ @@ -1423,10 +1423,10 @@ static int myssh_in_SFTP_DOWNLOAD_STAT(struct Curl_easy *data, myssh_to(data, sshc, SSH_STOP); return rc; } - Curl_xfer_setup1(data, CURL_XFER_RECV, data->req.size, FALSE); + Curl_xfer_setup_recv(data, FIRSTSOCKET, data->req.size); /* not set by Curl_xfer_setup to preserve keepon bits */ - data->conn->writesockfd = data->conn->sockfd; + data->conn->send_idx = 0; sshc->sftp_recv_state = 0; myssh_to(data, sshc, SSH_STOP); @@ -2240,10 +2240,10 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, } /* upload data */ - Curl_xfer_setup1(data, CURL_XFER_SEND, -1, FALSE); + Curl_xfer_setup_send(data, FIRSTSOCKET); /* not set by Curl_xfer_setup to preserve keepon bits */ - conn->sockfd = conn->writesockfd; + data->conn->recv_idx = FIRSTSOCKET; /* store this original bitmask setup to use later on if we cannot figure out a "real" bitmask */ @@ -2279,10 +2279,10 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, /* download data */ bytecount = ssh_scp_request_get_size(sshc->scp_session); data->req.maxdownload = (curl_off_t) bytecount; - Curl_xfer_setup1(data, CURL_XFER_RECV, bytecount, FALSE); + Curl_xfer_setup_recv(data, FIRSTSOCKET, bytecount); /* not set by Curl_xfer_setup to preserve keepon bits */ - conn->writesockfd = conn->sockfd; + conn->send_idx = 0; myssh_to(data, sshc, SSH_STOP); break; diff --git a/lib/vssh/libssh2.c b/lib/vssh/libssh2.c index bac362dd5..f6985ed25 100644 --- a/lib/vssh/libssh2.c +++ b/lib/vssh/libssh2.c @@ -1199,10 +1199,10 @@ sftp_upload_init(struct Curl_easy *data, Curl_pgrsSetUploadSize(data, data->state.infilesize); } /* upload data */ - Curl_xfer_setup1(data, CURL_XFER_SEND, -1, FALSE); + Curl_xfer_setup_send(data, FIRSTSOCKET); /* not set by Curl_xfer_setup to preserve keepon bits */ - data->conn->sockfd = data->conn->writesockfd; + data->conn->recv_idx = FIRSTSOCKET; /* store this original bitmask setup to use later on if we cannot figure out a "real" bitmask */ @@ -1540,10 +1540,10 @@ sftp_download_stat(struct Curl_easy *data, myssh_state(data, sshc, SSH_STOP); return CURLE_OK; } - Curl_xfer_setup1(data, CURL_XFER_RECV, data->req.size, FALSE); + Curl_xfer_setup_recv(data, FIRSTSOCKET, data->req.size); /* not set by Curl_xfer_setup to preserve keepon bits */ - data->conn->writesockfd = data->conn->sockfd; + data->conn->send_idx = 0; myssh_state(data, sshc, SSH_STOP); @@ -1945,8 +1945,8 @@ static CURLcode ssh_state_auth_done(struct Curl_easy *data, Curl_pgrsTime(data, TIMER_APPCONNECT); /* SSH is connected */ - conn->sockfd = conn->sock[FIRSTSOCKET]; - conn->writesockfd = CURL_SOCKET_BAD; + data->conn->recv_idx = FIRSTSOCKET; + conn->send_idx = -1; if(conn->handler->protocol == CURLPROTO_SFTP) { myssh_state(data, sshc, SSH_SFTP_INIT); @@ -2460,10 +2460,10 @@ static CURLcode ssh_state_scp_download_init(struct Curl_easy *data, /* download data */ bytecount = (curl_off_t)sb.st_size; data->req.maxdownload = (curl_off_t)sb.st_size; - Curl_xfer_setup1(data, CURL_XFER_RECV, bytecount, FALSE); + Curl_xfer_setup_recv(data, FIRSTSOCKET, bytecount); /* not set by Curl_xfer_setup to preserve keepon bits */ - data->conn->writesockfd = data->conn->sockfd; + data->conn->send_idx = 0; myssh_state(data, sshc, SSH_STOP); return CURLE_OK; @@ -2609,10 +2609,10 @@ static CURLcode ssh_state_scp_upload_init(struct Curl_easy *data, /* upload data */ data->req.size = data->state.infilesize; Curl_pgrsSetUploadSize(data, data->state.infilesize); - Curl_xfer_setup1(data, CURL_XFER_SEND, -1, FALSE); + Curl_xfer_setup_send(data, FIRSTSOCKET); /* not set by Curl_xfer_setup to preserve keepon bits */ - data->conn->sockfd = data->conn->writesockfd; + data->conn->recv_idx = FIRSTSOCKET; /* store this original bitmask setup to use later on if we cannot figure out a "real" bitmask */ diff --git a/lib/vssh/wolfssh.c b/lib/vssh/wolfssh.c index 15f504a01..556eda0cb 100644 --- a/lib/vssh/wolfssh.c +++ b/lib/vssh/wolfssh.c @@ -717,10 +717,10 @@ static CURLcode wssh_statemach_act(struct Curl_easy *data, Curl_pgrsSetUploadSize(data, data->state.infilesize); } /* upload data */ - Curl_xfer_setup1(data, CURL_XFER_SEND, -1, FALSE); + Curl_xfer_setup_send(data, FIRSTSOCKET); /* not set by Curl_xfer_setup to preserve keepon bits */ - conn->sockfd = conn->writesockfd; + data->conn->recv_idx = FIRSTSOCKET; if(result) { wssh_state(data, sshc, SSH_SFTP_CLOSE); @@ -816,10 +816,10 @@ static CURLcode wssh_statemach_act(struct Curl_easy *data, wssh_state(data, sshc, SSH_STOP); break; } - Curl_xfer_setup1(data, CURL_XFER_RECV, data->req.size, FALSE); + Curl_xfer_setup_recv(data, FIRSTSOCKET, data->req.size); /* not set by Curl_xfer_setup to preserve keepon bits */ - conn->writesockfd = conn->sockfd; + conn->send_idx = 0; if(result) { /* this should never occur; the close state should be entered diff --git a/src/config2setopts.c b/src/config2setopts.c index dfc41398e..ba31de9ab 100644 --- a/src/config2setopts.c +++ b/src/config2setopts.c @@ -87,8 +87,7 @@ static int sockopt_callback(void *clientp, curl_socket_t curlfd, } if(result < 0) { int error = errno; - warnf(config->global, - "Setting type of service to %d failed with errno %d: %s;\n", + warnf("Setting type of service to %d failed with errno %d: %s", tos, error, strerror(error)); } } @@ -97,9 +96,9 @@ static int sockopt_callback(void *clientp, curl_socket_t curlfd, if(config->vlan_priority > 0) { int priority = (int)config->vlan_priority; if(setsockopt(curlfd, SOL_SOCKET, SO_PRIORITY, - (void *)&priority, sizeof(priority)) != 0) { + (void *)&priority, sizeof(priority)) != 0) { int error = errno; - warnf(config->global, "VLAN priority %d failed with errno %d: %s;\n", + warnf("VLAN priority %d failed with errno %d: %s", priority, error, strerror(error)); } } @@ -173,7 +172,6 @@ static CURLcode url_proto_and_rewrite(char **url, static CURLcode ssh_setopts(struct OperationConfig *config, CURL *curl) { - struct GlobalConfig *global = config->global; CURLcode result; /* SSH and SSL private key uses same command-line option */ @@ -213,11 +211,11 @@ static CURLcode ssh_setopts(struct OperationConfig *config, CURL *curl) global->knownhosts = known; } else if(!config->hostpubmd5 && !config->hostpubsha256) { - errorf(global, "Couldn't find a known_hosts file"); + errorf("Couldn't find a known_hosts file"); return CURLE_FAILED_INIT; } else - warnf(global, "Couldn't find a known_hosts file"); + warnf("Couldn't find a known_hosts file"); } return CURLE_OK; /* ignore if SHA256 did not work */ } @@ -279,7 +277,6 @@ static long tlsversion(unsigned char mintls, /* only called if libcurl supports TLS */ static CURLcode ssl_setopts(struct OperationConfig *config, CURL *curl) { - struct GlobalConfig *global = config->global; CURLcode result = CURLE_OK; if(config->cacert) @@ -301,7 +298,7 @@ static CURLcode ssl_setopts(struct OperationConfig *config, CURL *curl) if((result == CURLE_NOT_BUILT_IN) || (result == CURLE_UNKNOWN_OPTION)) { if(config->proxy_capath) { - warnf(global, "ignoring %s, not supported by libcurl with %s", + warnf("ignoring %s, not supported by libcurl with %s", config->proxy_capath ? "--proxy-capath" : "--capath", ssl_backend()); } @@ -316,12 +313,10 @@ static CURLcode ssl_setopts(struct OperationConfig *config, CURL *curl) blob.data = CURL_UNCONST(curl_ca_embed); blob.len = strlen((const char *)curl_ca_embed); blob.flags = CURL_BLOB_NOCOPY; - notef(config->global, - "Using embedded CA bundle (%zu bytes)", - blob.len); + notef("Using embedded CA bundle (%zu bytes)", blob.len); result = curl_easy_setopt(curl, CURLOPT_CAINFO_BLOB, &blob); if(result == CURLE_NOT_BUILT_IN) { - warnf(global, "ignoring %s, not supported by libcurl with %s", + warnf("ignoring %s, not supported by libcurl with %s", "embedded CA bundle", ssl_backend()); } } @@ -330,12 +325,10 @@ static CURLcode ssl_setopts(struct OperationConfig *config, CURL *curl) blob.data = CURL_UNCONST(curl_ca_embed); blob.len = strlen((const char *)curl_ca_embed); blob.flags = CURL_BLOB_NOCOPY; - notef(config->global, - "Using embedded CA bundle, for proxies (%zu bytes)", - blob.len); + notef("Using embedded CA bundle, for proxies (%zu bytes)", blob.len); result = curl_easy_setopt(curl, CURLOPT_PROXY_CAINFO_BLOB, &blob); if(result == CURLE_NOT_BUILT_IN) { - warnf(global, "ignoring %s, not supported by libcurl with %s", + warnf("ignoring %s, not supported by libcurl with %s", "embedded CA bundle", ssl_backend()); } } @@ -352,14 +345,14 @@ static CURLcode ssl_setopts(struct OperationConfig *config, CURL *curl) result = my_setopt_str(curl, CURLOPT_PINNEDPUBLICKEY, config->pinnedpubkey); if(result == CURLE_NOT_BUILT_IN) - warnf(global, "ignoring %s, not supported by libcurl with %s", + warnf("ignoring %s, not supported by libcurl with %s", "--pinnedpubkey", ssl_backend()); } if(config->proxy_pinnedpubkey) { result = my_setopt_str(curl, CURLOPT_PROXY_PINNEDPUBLICKEY, config->proxy_pinnedpubkey); if(result == CURLE_NOT_BUILT_IN) - warnf(global, "ignoring %s, not supported by libcurl with %s", + warnf("ignoring %s, not supported by libcurl with %s", "--proxy-pinnedpubkey", ssl_backend()); } @@ -441,28 +434,28 @@ static CURLcode ssl_setopts(struct OperationConfig *config, CURL *curl) result = my_setopt_str(curl, CURLOPT_SSL_CIPHER_LIST, config->cipher_list); if(result == CURLE_NOT_BUILT_IN) - warnf(global, "ignoring %s, not supported by libcurl with %s", + warnf("ignoring %s, not supported by libcurl with %s", "--ciphers", ssl_backend()); } if(config->proxy_cipher_list) { result = my_setopt_str(curl, CURLOPT_PROXY_SSL_CIPHER_LIST, config->proxy_cipher_list); if(result == CURLE_NOT_BUILT_IN) - warnf(global, "ignoring %s, not supported by libcurl with %s", + warnf("ignoring %s, not supported by libcurl with %s", "--proxy-ciphers", ssl_backend()); } if(config->cipher13_list) { result = my_setopt_str(curl, CURLOPT_TLS13_CIPHERS, config->cipher13_list); if(result == CURLE_NOT_BUILT_IN) - warnf(global, "ignoring %s, not supported by libcurl with %s", + warnf("ignoring %s, not supported by libcurl with %s", "--tls13-ciphers", ssl_backend()); } if(config->proxy_cipher13_list) { result = my_setopt_str(curl, CURLOPT_PROXY_TLS13_CIPHERS, config->proxy_cipher13_list); if(result == CURLE_NOT_BUILT_IN) - warnf(global, "ignoring %s, not supported by libcurl with %s", + warnf("ignoring %s, not supported by libcurl with %s", "--proxy-tls13-ciphers", ssl_backend()); } @@ -576,13 +569,12 @@ static CURLcode cookie_setopts(struct OperationConfig *config, CURL *curl) curlx_dyn_init(&cookies, MAX_COOKIE_LINE); for(cl = config->cookies; cl; cl = cl->next) { if(cl == config->cookies) - result = curlx_dyn_addf(&cookies, "%s", cl->data); + result = curlx_dyn_add(&cookies, cl->data); else result = curlx_dyn_addf(&cookies, ";%s", cl->data); if(result) { - warnf(config->global, - "skipped provided cookie, the cookie header " + warnf("skipped provided cookie, the cookie header " "would go over %u bytes", MAX_COOKIE_LINE); return result; } @@ -675,7 +667,7 @@ static CURLcode ftp_setopts(struct OperationConfig *config, CURL *curl) static void gen_trace_setopts(struct OperationConfig *config, CURL *curl) { - if(config->global->tracetype != TRACE_NONE) { + if(global->tracetype != TRACE_NONE) { my_setopt(curl, CURLOPT_DEBUGFUNCTION, tool_debug_cb); my_setopt(curl, CURLOPT_DEBUGDATA, config); my_setopt_long(curl, CURLOPT_VERBOSE, 1L); @@ -686,8 +678,8 @@ static void gen_cb_setopts(struct OperationConfig *config, struct per_transfer *per, CURL *curl) { - struct GlobalConfig *global = config->global; - (void)config; + (void)config; /* when --libcurl is disabled */ + /* where to store */ my_setopt(curl, CURLOPT_WRITEDATA, per); my_setopt(curl, CURLOPT_INTERLEAVEDATA, per); @@ -729,7 +721,7 @@ static CURLcode proxy_setopts(struct OperationConfig *config, CURL *curl) CURLcode result = my_setopt_str(curl, CURLOPT_PROXY, config->proxy); if(result) { - errorf(config->global, "proxy support is disabled in this libcurl"); + errorf("proxy support is disabled in this libcurl"); config->synthetic_error = TRUE; return CURLE_NOT_BUILT_IN; } @@ -806,7 +798,6 @@ CURLcode config2setopts(struct OperationConfig *config, CURL *curl, CURLSH *share) { - struct GlobalConfig *global = config->global; const char *use_proto; CURLcode result = url_proto_and_rewrite(&per->url, config, &use_proto); @@ -887,7 +878,7 @@ CURLcode config2setopts(struct OperationConfig *config, switch(config->httpreq) { case TOOL_HTTPREQ_SIMPLEPOST: if(config->resume_from) { - errorf(global, "cannot mix --continue-at with --data"); + errorf("cannot mix --continue-at with --data"); result = CURLE_FAILED_INIT; } else { @@ -902,7 +893,7 @@ CURLcode config2setopts(struct OperationConfig *config, curl_mime_free(config->mimepost); config->mimepost = NULL; if(config->resume_from) { - errorf(global, "cannot mix --continue-at with --form"); + errorf("cannot mix --continue-at with --form"); result = CURLE_FAILED_INIT; } else { @@ -985,7 +976,7 @@ CURLcode config2setopts(struct OperationConfig *config, my_setopt_enum(curl, CURLOPT_TIMECONDITION, config->timecond); my_setopt_offt(curl, CURLOPT_TIMEVALUE_LARGE, config->condtime); my_setopt_str(curl, CURLOPT_CUSTOMREQUEST, config->customrequest); - customrequest_helper(config, config->httpreq, config->customrequest); + customrequest_helper(config->httpreq, config->customrequest); my_setopt(curl, CURLOPT_STDERR, tool_stderr); my_setopt_str(curl, CURLOPT_INTERFACE, config->iface); my_setopt_str(curl, CURLOPT_KRBLEVEL, config->krblevel); @@ -1080,13 +1071,11 @@ CURLcode config2setopts(struct OperationConfig *config, my_setopt(curl, CURLOPT_SOCKOPTDATA, config); #else if(config->ip_tos > 0) { - errorf(config->global, - "Type of service is not supported in this build."); + errorf("Type of service is not supported in this build."); result = CURLE_NOT_BUILT_IN; } if(config->vlan_priority > 0) { - errorf(config->global, - "VLAN priority is not supported in this build."); + errorf("VLAN priority is not supported in this build."); result = CURLE_NOT_BUILT_IN; } #endif diff --git a/src/tool_cb_dbg.c b/src/tool_cb_dbg.c index 0e79c8d25..0b36236ab 100644 --- a/src/tool_cb_dbg.c +++ b/src/tool_cb_dbg.c @@ -79,8 +79,6 @@ int tool_debug_cb(CURL *handle, curl_infotype type, char *data, size_t size, void *userdata) { - struct OperationConfig *operation = userdata; - struct GlobalConfig *global = operation->global; FILE *output = tool_stderr; const char *text; struct timeval tv; @@ -94,6 +92,7 @@ int tool_debug_cb(CURL *handle, curl_infotype type, curl_off_t xfer_id, conn_id; (void)handle; /* not used */ + (void)userdata; if(global->tracetime) { tv = tvrealnow(); @@ -134,7 +133,7 @@ int tool_debug_cb(CURL *handle, curl_infotype type, output = global->trace_stream; if(!output) { - warnf(global, "Failed to create/open output"); + warnf("Failed to create/open output"); return 0; } diff --git a/src/tool_cb_hdr.c b/src/tool_cb_hdr.c index d8cd117e3..6af9d1947 100644 --- a/src/tool_cb_hdr.c +++ b/src/tool_cb_hdr.c @@ -99,7 +99,7 @@ size_t tool_header_cb(char *ptr, size_t size, size_t nmemb, void *userdata) #ifdef DEBUGBUILD if(size * nmemb > (size_t)CURL_MAX_HTTP_HEADER) { - warnf(per->config->global, "Header data exceeds write limit"); + warnf("Header data exceeds write limit"); return CURL_WRITEFUNC_ERROR; } #endif @@ -120,8 +120,7 @@ size_t tool_header_cb(char *ptr, size_t size, size_t nmemb, void *userdata) return rc; /* flush the stream to send off what we got earlier */ if(fflush(heads->stream)) { - errorf(per->config->global, "Failed writing headers to %s", - per->config->headerfile); + errorf("Failed writing headers to %s", per->config->headerfile); return CURL_WRITEFUNC_ERROR; } } @@ -286,11 +285,11 @@ size_t tool_header_cb(char *ptr, size_t size, size_t nmemb, void *userdata) if(!outs->stream && !tool_create_output_file(outs, per->config)) return CURL_WRITEFUNC_ERROR; - if(hdrcbdata->config->global->isatty && + if(global->isatty && #ifdef _WIN32 tool_term_has_bold && #endif - hdrcbdata->config->global->styled_output) + global->styled_output) value = memchr(ptr, ':', cb); if(value) { size_t namelen = value - ptr; diff --git a/src/tool_cb_rea.c b/src/tool_cb_rea.c index 1c8e99b99..5b8ba62a5 100644 --- a/src/tool_cb_rea.c +++ b/src/tool_cb_rea.c @@ -103,7 +103,7 @@ size_t tool_read_cb(char *buffer, size_t sz, size_t nmemb, void *userdata) rc = 0; } #else - warnf(per->config->global, "per->infd != 0: FD == %d. This behavior" + warnf("per->infd != 0: FD == %d. This behavior" " is only supported on desktop Windows", per->infd); #endif } @@ -123,7 +123,7 @@ size_t tool_read_cb(char *buffer, size_t sz, size_t nmemb, void *userdata) (per->uploadedsofar + rc > per->uploadfilesize)) { /* do not allow uploading more than originally set out to do */ curl_off_t delta = per->uploadedsofar + rc - per->uploadfilesize; - warnf(per->config->global, "File size larger in the end than when " + warnf("File size larger in the end than when " "started. Dropping at least %" CURL_FORMAT_CURL_OFF_T " bytes", delta); rc = (ssize_t)(per->uploadfilesize - per->uploadedsofar); diff --git a/src/tool_cb_wrt.c b/src/tool_cb_wrt.c index 3ac14cd01..ff544e61a 100644 --- a/src/tool_cb_wrt.c +++ b/src/tool_cb_wrt.c @@ -45,12 +45,10 @@ bool tool_create_output_file(struct OutStruct *outs, struct OperationConfig *config) { - struct GlobalConfig *global; FILE *file = NULL; const char *fname = outs->filename; DEBUGASSERT(outs); DEBUGASSERT(config); - global = config->global; DEBUGASSERT(fname && *fname); if(config->file_clobber_mode == CLOBBER_ALWAYS || @@ -101,8 +99,7 @@ bool tool_create_output_file(struct OutStruct *outs, } if(!file) { - warnf(global, "Failed to open the file %s: %s", fname, - strerror(errno)); + warnf("Failed to open the file %s: %s", fname, strerror(errno)); return FALSE; } outs->s_isreg = TRUE; @@ -248,7 +245,7 @@ size_t tool_write_cb(char *buffer, size_t sz, size_t nmemb, void *userdata) struct OutStruct *outs = &per->outs; struct OperationConfig *config = per->config; size_t bytes = sz * nmemb; - bool is_tty = config->global->isatty; + bool is_tty = global->isatty; #if defined(_WIN32) && !defined(UNDER_CE) CONSOLE_SCREEN_BUFFER_INFO console_info; intptr_t fhnd; @@ -268,13 +265,13 @@ size_t tool_write_cb(char *buffer, size_t sz, size_t nmemb, void *userdata) if(config->show_headers) { if(bytes > (size_t)CURL_MAX_HTTP_HEADER) { - warnf(config->global, "Header data size exceeds write limit"); + warnf("Header data size exceeds write limit"); return CURL_WRITEFUNC_ERROR; } } else { if(bytes > (size_t)CURL_MAX_WRITE_SIZE) { - warnf(config->global, "Data size exceeds write limit"); + warnf("Data size exceeds write limit"); return CURL_WRITEFUNC_ERROR; } } @@ -303,7 +300,7 @@ size_t tool_write_cb(char *buffer, size_t sz, size_t nmemb, void *userdata) check_fails = TRUE; } if(check_fails) { - warnf(config->global, "Invalid output struct data for write callback"); + warnf("Invalid output struct data for write callback"); return CURL_WRITEFUNC_ERROR; } } @@ -315,7 +312,7 @@ size_t tool_write_cb(char *buffer, size_t sz, size_t nmemb, void *userdata) if(is_tty && (outs->bytes < 2000) && !config->terminal_binary_ok) { /* binary output to terminal? */ if(memchr(buffer, 0, bytes)) { - warnf(config->global, "Binary output can mess up your terminal. " + warnf("Binary output can mess up your terminal. " "Use \"--output -\" to tell curl to output it to your terminal " "anyway, or consider \"--output <FILE>\" to save to a file."); config->synthetic_error = TRUE; diff --git a/src/tool_cfgable.c b/src/tool_cfgable.c index 975ef2a45..b6c8bf5c8 100644 --- a/src/tool_cfgable.c +++ b/src/tool_cfgable.c @@ -27,16 +27,19 @@ #include "tool_formparse.h" #include "tool_paramhlp.h" #include "tool_main.h" +#include "tool_msgs.h" #include "memdebug.h" /* keep this as LAST include */ -struct OperationConfig *config_alloc(struct GlobalConfig *global) +static struct GlobalConfig globalconf; +struct GlobalConfig *global; + +struct OperationConfig *config_alloc(void) { struct OperationConfig *config = calloc(1, sizeof(struct OperationConfig)); if(!config) return NULL; - config->global = global; config->use_httpget = FALSE; config->create_dirs = FALSE; config->maxredirs = DEFAULT_MAXREDIRS; @@ -202,3 +205,78 @@ void config_free(struct OperationConfig *config) last = prev; } } + +/* + * This is the main global constructor for the app. Call this before + * _any_ libcurl usage. If this fails, *NO* libcurl functions may be + * used, or havoc may be the result. + */ +CURLcode globalconf_init(void) +{ + CURLcode result = CURLE_OK; + global = &globalconf; + +#ifdef __DJGPP__ + /* stop stat() wasting time */ + _djstat_flags |= _STAT_INODE | _STAT_EXEC_MAGIC | _STAT_DIRSIZE; +#endif + + /* Initialise the global config */ + global->showerror = FALSE; /* show errors when silent */ + global->styled_output = TRUE; /* enable detection */ + global->parallel_max = PARALLEL_DEFAULT; + + /* Allocate the initial operate config */ + global->first = global->last = config_alloc(); + if(global->first) { + /* Perform the libcurl initialization */ + result = curl_global_init(CURL_GLOBAL_DEFAULT); + if(!result) { + /* Get information about libcurl */ + result = get_libcurl_info(); + + if(result) { + errorf("error retrieving curl library information"); + free(global->first); + } + } + else { + errorf("error initializing curl library"); + free(global->first); + } + } + else { + errorf("error initializing curl"); + result = CURLE_FAILED_INIT; + } + + return result; +} + +static void free_globalconfig(void) +{ + tool_safefree(global->trace_dump); + + if(global->trace_fopened && global->trace_stream) + fclose(global->trace_stream); + global->trace_stream = NULL; + + tool_safefree(global->libcurl); +} + +/* + * This is the main global destructor for the app. Call this after _all_ + * libcurl usage is done. + */ +void globalconf_free(void) +{ + /* Cleanup the easy handle */ + /* Main cleanup */ + curl_global_cleanup(); + free_globalconfig(); + + /* Free the OperationConfig structures */ + config_free(global->last); + global->first = NULL; + global->last = NULL; +} diff --git a/src/tool_cfgable.h b/src/tool_cfgable.h index 28f90d264..40cc52b8d 100644 --- a/src/tool_cfgable.h +++ b/src/tool_cfgable.h @@ -62,12 +62,12 @@ #define tool_safefree(ptr) \ do { free((ptr)); (ptr) = NULL;} while(0) -struct GlobalConfig; +extern struct GlobalConfig *global; struct State { struct getout *urlnode; - struct URLGlob *inglob; - struct URLGlob *urls; + struct URLGlob inglob; + struct URLGlob urlglob; char *outfiles; char *httpgetfields; char *uploadfile; @@ -188,7 +188,6 @@ struct OperationConfig { char *ech; /* Config set by --ech keywords */ char *ech_config; /* Config set by "--ech esl:" option */ char *ech_public; /* Config set by "--ech pn:" option */ - struct GlobalConfig *global; struct OperationConfig *prev; struct OperationConfig *next; /* Always last in the struct */ curl_off_t condtime; @@ -377,7 +376,9 @@ struct GlobalConfig { BIT(isatty); /* Updated internally if output is a tty */ }; -struct OperationConfig *config_alloc(struct GlobalConfig *global); +struct OperationConfig *config_alloc(void); void config_free(struct OperationConfig *config); +CURLcode globalconf_init(void); +void globalconf_free(void); #endif /* HEADER_CURL_TOOL_CFGABLE_H */ diff --git a/src/tool_dirhie.c b/src/tool_dirhie.c index 2c8aba362..91cc1b60c 100644 --- a/src/tool_dirhie.c +++ b/src/tool_dirhie.c @@ -39,39 +39,39 @@ # endif #endif -static void show_dir_errno(struct GlobalConfig *global, const char *name) +static void show_dir_errno(const char *name) { switch(errno) { #ifdef EACCES /* !checksrc! disable ERRNOVAR 1 */ case EACCES: - errorf(global, "You do not have permission to create %s", name); + errorf("You do not have permission to create %s", name); break; #endif #ifdef ENAMETOOLONG case ENAMETOOLONG: - errorf(global, "The directory name %s is too long", name); + errorf("The directory name %s is too long", name); break; #endif #ifdef EROFS case EROFS: - errorf(global, "%s resides on a read-only file system", name); + errorf("%s resides on a read-only file system", name); break; #endif #ifdef ENOSPC case ENOSPC: - errorf(global, "No space left on the file system that will " + errorf("No space left on the file system that will " "contain the directory %s", name); break; #endif #ifdef EDQUOT case EDQUOT: - errorf(global, "Cannot create directory %s because you " + errorf("Cannot create directory %s because you " "exceeded your quota", name); break; #endif default: - errorf(global, "Error creating directory %s", name); + errorf("Error creating directory %s", name); break; } } @@ -90,7 +90,7 @@ static void show_dir_errno(struct GlobalConfig *global, const char *name) #define PATH_DELIMITERS DIR_CHAR #endif -CURLcode create_dir_hierarchy(const char *outfile, struct GlobalConfig *global) +CURLcode create_dir_hierarchy(const char *outfile) { CURLcode result = CURLE_OK; size_t outlen = strlen(outfile); @@ -128,7 +128,7 @@ CURLcode create_dir_hierarchy(const char *outfile, struct GlobalConfig *global) /* !checksrc! disable ERRNOVAR 1 */ if(!skip && (mkdir(curlx_dyn_ptr(&dirbuf), (mode_t)0000750) == -1) && (errno != EACCES) && (errno != EEXIST)) { - show_dir_errno(global, curlx_dyn_ptr(&dirbuf)); + show_dir_errno(curlx_dyn_ptr(&dirbuf)); result = CURLE_WRITE_ERROR; break; /* get out of loop */ } diff --git a/src/tool_dirhie.h b/src/tool_dirhie.h index 0ee407fe5..cb59208d9 100644 --- a/src/tool_dirhie.h +++ b/src/tool_dirhie.h @@ -26,7 +26,6 @@ #include "tool_setup.h" #include "tool_cfgable.h" -CURLcode create_dir_hierarchy(const char *outfile, - struct GlobalConfig *global); +CURLcode create_dir_hierarchy(const char *outfileo); #endif /* HEADER_CURL_TOOL_DIRHIE_H */ diff --git a/src/tool_doswin.c b/src/tool_doswin.c index 07a85bc11..23233bc2d 100644 --- a/src/tool_doswin.c +++ b/src/tool_doswin.c @@ -746,13 +746,11 @@ CURLcode win32_init(void) by nmap and ncat (https://nmap.org/ncat/) */ struct win_thread_data { /* This is a copy of the true stdin file handle before any redirection. It is - read by the thread. */ + read by the thread. */ HANDLE stdin_handle; /* This is the listen socket for the thread. It is closed after the first - connection. */ + connection. */ curl_socket_t socket_l; - /* This is the global config - used for printing errors and so forth */ - struct GlobalConfig *global; }; static DWORD WINAPI win_stdin_thread_func(void *thread_data) @@ -770,14 +768,14 @@ static DWORD WINAPI win_stdin_thread_func(void *thread_data) &clientAddrLen); if(socket_w == CURL_SOCKET_BAD) { - errorf(tdata->global, "accept error: %08lx\n", GetLastError()); + errorf("accept error: %08lx", GetLastError()); goto ThreadCleanup; } closesocket(tdata->socket_l); /* sclose here fails test 1498 */ tdata->socket_l = CURL_SOCKET_BAD; if(shutdown(socket_w, SD_RECEIVE) == SOCKET_ERROR) { - errorf(tdata->global, "shutdown error: %08lx\n", GetLastError()); + errorf("shutdown error: %08lx", GetLastError()); goto ThreadCleanup; } for(;;) { @@ -813,7 +811,7 @@ ThreadCleanup: static HANDLE stdin_thread = NULL; static curl_socket_t socket_r = CURL_SOCKET_BAD; -curl_socket_t win32_stdin_read_thread(struct GlobalConfig *global) +curl_socket_t win32_stdin_read_thread(void) { int result; bool r; @@ -831,7 +829,7 @@ curl_socket_t win32_stdin_read_thread(struct GlobalConfig *global) /* Prepare handles for thread */ tdata = (struct win_thread_data*)calloc(1, sizeof(struct win_thread_data)); if(!tdata) { - errorf(global, "calloc() error"); + errorf("calloc() error"); break; } /* Create the listening socket for the thread. When it starts, it will @@ -840,7 +838,7 @@ curl_socket_t win32_stdin_read_thread(struct GlobalConfig *global) IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED); if(tdata->socket_l == CURL_SOCKET_BAD) { - errorf(global, "WSASocketW error: %08lx", GetLastError()); + errorf("WSASocketW error: %08lx", GetLastError()); break; } @@ -851,20 +849,20 @@ curl_socket_t win32_stdin_read_thread(struct GlobalConfig *global) /* Bind to any available loopback port */ result = bind(tdata->socket_l, (SOCKADDR*)&selfaddr, socksize); if(result == SOCKET_ERROR) { - errorf(global, "bind error: %08lx", GetLastError()); + errorf("bind error: %08lx", GetLastError()); break; } /* Bind to any available loopback port */ result = getsockname(tdata->socket_l, (SOCKADDR*)&selfaddr, &socksize); if(result == SOCKET_ERROR) { - errorf(global, "getsockname error: %08lx", GetLastError()); + errorf("getsockname error: %08lx", GetLastError()); break; } result = listen(tdata->socket_l, 1); if(result == SOCKET_ERROR) { - errorf(global, "listen error: %08lx\n", GetLastError()); + errorf("listen error: %08lx", GetLastError()); break; } @@ -874,7 +872,7 @@ curl_socket_t win32_stdin_read_thread(struct GlobalConfig *global) 0, FALSE, DUPLICATE_SAME_ACCESS); if(!r) { - errorf(global, "DuplicateHandle error: %08lx", GetLastError()); + errorf("DuplicateHandle error: %08lx", GetLastError()); break; } @@ -885,14 +883,14 @@ curl_socket_t win32_stdin_read_thread(struct GlobalConfig *global) stdin_thread = CreateThread(NULL, 0, win_stdin_thread_func, tdata, 0, NULL); if(!stdin_thread) { - errorf(global, "CreateThread error: %08lx", GetLastError()); + errorf("CreateThread error: %08lx", GetLastError()); break; } /* Connect to the thread and rearrange our own STDIN handles */ socket_r = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if(socket_r == CURL_SOCKET_BAD) { - errorf(global, "socket error: %08lx", GetLastError()); + errorf("socket error: %08lx", GetLastError()); break; } @@ -900,18 +898,18 @@ curl_socket_t win32_stdin_read_thread(struct GlobalConfig *global) setsockopt(socket_r, SOL_SOCKET, SO_DONTLINGER, 0, 0); if(connect(socket_r, (SOCKADDR*)&selfaddr, socksize) == SOCKET_ERROR) { - errorf(global, "connect error: %08lx", GetLastError()); + errorf("connect error: %08lx", GetLastError()); break; } if(shutdown(socket_r, SD_SEND) == SOCKET_ERROR) { - errorf(global, "shutdown error: %08lx", GetLastError()); + errorf("shutdown error: %08lx", GetLastError()); break; } /* Set the stdin handle to read from the socket. */ if(SetStdHandle(STD_INPUT_HANDLE, (HANDLE)socket_r) == 0) { - errorf(global, "SetStdHandle error: %08lx", GetLastError()); + errorf("SetStdHandle error: %08lx", GetLastError()); break; } diff --git a/src/tool_doswin.h b/src/tool_doswin.h index 92948b950..7fe526047 100644 --- a/src/tool_doswin.h +++ b/src/tool_doswin.h @@ -56,7 +56,7 @@ struct curl_slist *GetLoadedModulePaths(void); CURLcode win32_init(void); #if !defined(CURL_WINDOWS_UWP) && !defined(UNDER_CE) -curl_socket_t win32_stdin_read_thread(struct GlobalConfig *global); +curl_socket_t win32_stdin_read_thread(void); #endif /* !CURL_WINDOWS_UWP && !UNDER_CE */ #endif /* _WIN32 */ diff --git a/src/tool_easysrc.c b/src/tool_easysrc.c index de3133c63..223c66bdf 100644 --- a/src/tool_easysrc.c +++ b/src/tool_easysrc.c @@ -170,7 +170,7 @@ CURLcode easysrc_cleanup(void) return ret; } -void dumpeasysrc(struct GlobalConfig *global) +void dumpeasysrc(void) { struct curl_slist *ptr; char *o = global->libcurl; @@ -184,7 +184,7 @@ void dumpeasysrc(struct GlobalConfig *global) else out = stdout; if(!out) - warnf(global, "Failed to open %s to write libcurl code", o); + warnf("Failed to open %s to write libcurl code", o); else { int i; const char *c; diff --git a/src/tool_easysrc.h b/src/tool_easysrc.h index 8cd602d93..44d40b727 100644 --- a/src/tool_easysrc.h +++ b/src/tool_easysrc.h @@ -43,8 +43,7 @@ extern CURLcode easysrc_addf(struct slist_wc **plist, const char *fmt, ...) CURL_PRINTF(2, 3); extern CURLcode easysrc_perform(void); extern CURLcode easysrc_cleanup(void); - -void dumpeasysrc(struct GlobalConfig *global); +void dumpeasysrc(void); #else /* CURL_DISABLE_LIBCURL_OPTION is defined */ diff --git a/src/tool_filetime.c b/src/tool_filetime.c index 29c1e481d..8907bcda6 100644 --- a/src/tool_filetime.c +++ b/src/tool_filetime.c @@ -32,8 +32,7 @@ #endif /* Returns 0 on success, non-zero on file problems */ -int getfiletime(const char *filename, struct GlobalConfig *global, - curl_off_t *stamp) +int getfiletime(const char *filename, curl_off_t *stamp) { int rc = 1; @@ -56,21 +55,21 @@ int getfiletime(const char *filename, struct GlobalConfig *global, | ((curl_off_t)ft.dwHighDateTime) << 32; if(converted < 116444736000000000) - warnf(global, "Failed to get filetime: underflow"); + warnf("Failed to get filetime: underflow"); else { *stamp = (converted - 116444736000000000) / 10000000; rc = 0; } } else { - warnf(global, "Failed to get filetime: " + warnf("Failed to get filetime: " "GetFileTime failed: GetLastError %u", (unsigned int)GetLastError()); } CloseHandle(hfile); } else if(GetLastError() != ERROR_FILE_NOT_FOUND) { - warnf(global, "Failed to get filetime: " + warnf("Failed to get filetime: " "CreateFile failed: GetLastError %u", (unsigned int)GetLastError()); } @@ -81,14 +80,13 @@ int getfiletime(const char *filename, struct GlobalConfig *global, rc = 0; } else - warnf(global, "Failed to get filetime: %s", strerror(errno)); + warnf("Failed to get filetime: %s", strerror(errno)); #endif return rc; } #if defined(HAVE_UTIME) || defined(HAVE_UTIMES) || defined(_WIN32) -void setfiletime(curl_off_t filetime, const char *filename, - struct GlobalConfig *global) +void setfiletime(curl_off_t filetime, const char *filename) { if(filetime >= 0) { /* Windows utime() may attempt to adjust the Unix GMT file time by a daylight @@ -101,7 +99,7 @@ void setfiletime(curl_off_t filetime, const char *filename, /* 910670515199 is the maximum Unix filetime that can be used as a Windows FILETIME without overflow: 30827-12-31T23:59:59. */ if(filetime > 910670515199) { - warnf(global, "Failed to set filetime %" CURL_FORMAT_CURL_OFF_T + warnf("Failed to set filetime %" CURL_FORMAT_CURL_OFF_T " on outfile: overflow", filetime); curlx_unicodefree(tchar_filename); return; @@ -119,14 +117,14 @@ void setfiletime(curl_off_t filetime, const char *filename, ft.dwLowDateTime = (DWORD)(converted & 0xFFFFFFFF); ft.dwHighDateTime = (DWORD)(converted >> 32); if(!SetFileTime(hfile, NULL, &ft, &ft)) { - warnf(global, "Failed to set filetime %" CURL_FORMAT_CURL_OFF_T + warnf("Failed to set filetime %" CURL_FORMAT_CURL_OFF_T " on outfile: SetFileTime failed: GetLastError %u", filetime, (unsigned int)GetLastError()); } CloseHandle(hfile); } else { - warnf(global, "Failed to set filetime %" CURL_FORMAT_CURL_OFF_T + warnf("Failed to set filetime %" CURL_FORMAT_CURL_OFF_T " on outfile: CreateFile failed: GetLastError %u", filetime, (unsigned int)GetLastError()); } @@ -136,7 +134,7 @@ void setfiletime(curl_off_t filetime, const char *filename, times[0].tv_sec = times[1].tv_sec = (time_t)filetime; times[0].tv_usec = times[1].tv_usec = 0; if(utimes(filename, times)) { - warnf(global, "Failed to set filetime %" CURL_FORMAT_CURL_OFF_T + warnf("Failed to set filetime %" CURL_FORMAT_CURL_OFF_T " on '%s': %s", filetime, filename, strerror(errno)); } @@ -145,7 +143,7 @@ void setfiletime(curl_off_t filetime, const char *filename, times.actime = (time_t)filetime; times.modtime = (time_t)filetime; if(utime(filename, ×)) { - warnf(global, "Failed to set filetime %" CURL_FORMAT_CURL_OFF_T + warnf("Failed to set filetime %" CURL_FORMAT_CURL_OFF_T " on '%s': %s", filetime, filename, strerror(errno)); } #endif diff --git a/src/tool_filetime.h b/src/tool_filetime.h index 6c0c44207..c3663617b 100644 --- a/src/tool_filetime.h +++ b/src/tool_filetime.h @@ -25,15 +25,11 @@ ***************************************************************************/ #include "tool_setup.h" -struct GlobalConfig; - -int getfiletime(const char *filename, struct GlobalConfig *global, - curl_off_t *stamp); +int getfiletime(const char *filename, curl_off_t *stamp); #if defined(HAVE_UTIME) || defined(HAVE_UTIMES) || \ (defined(_WIN32) && (SIZEOF_CURL_OFF_T >= 8)) -void setfiletime(curl_off_t filetime, const char *filename, - struct GlobalConfig *global); +void setfiletime(curl_off_t filetime, const char *filename); #else #define setfiletime(a,b,c) tool_nop_stmt #endif diff --git a/src/tool_formparse.c b/src/tool_formparse.c index 84d6a029b..b5ab10a00 100644 --- a/src/tool_formparse.c +++ b/src/tool_formparse.c @@ -223,10 +223,7 @@ size_t tool_mime_stdin_read(char *buffer, nitems = fread(buffer, 1, nitems, stdin); if(ferror(stdin)) { /* Show error only once. */ - if(sip->global) { - warnf(sip->global, "stdin: %s", strerror(errno)); - sip->global = NULL; - } + warnf("stdin: %s", strerror(errno)); return CURL_READFUNC_ABORT; } } @@ -348,8 +345,7 @@ CURLcode tool2curlmime(CURL *curl, struct tool_mime *m, curl_mime **mime) * after call get_param_word, str either point to string end * or point to any of end chars. */ -static char *get_param_word(struct OperationConfig *config, char **str, - char **end_pos, char endchar) +static char *get_param_word(char **str, char **end_pos, char endchar) { char *ptr = *str; /* the first non-space char is here */ @@ -391,7 +387,7 @@ static char *get_param_word(struct OperationConfig *config, char **str, ++ptr; } if(trailing_data) - warnf(config->global, "Trailing data after quoted form parameter"); + warnf("Trailing data after quoted form parameter"); *str = ptr; return word_begin + 1; } @@ -420,8 +416,7 @@ static int slist_append(struct curl_slist **plist, const char *data) } /* Read headers from a file and append to list. */ -static int read_field_headers(struct OperationConfig *config, - const char *filename, FILE *fp, +static int read_field_headers(const char *filename, FILE *fp, struct curl_slist **pheaders) { size_t hdrlen = 0; @@ -439,7 +434,7 @@ static int read_field_headers(struct OperationConfig *config, if(hdrlen) { hdrbuf[hdrlen] = '\0'; if(slist_append(pheaders, hdrbuf)) { - errorf(config->global, "Out of memory for field headers"); + errorf("Out of memory for field headers"); return -1; } hdrlen = 0; @@ -449,7 +444,7 @@ static int read_field_headers(struct OperationConfig *config, switch(c) { case EOF: if(ferror(fp)) { - errorf(config->global, "Header file %s read error: %s", filename, + errorf("Header file %s read error: %s", filename, strerror(errno)); return -1; } @@ -470,7 +465,7 @@ static int read_field_headers(struct OperationConfig *config, pos++; if(!incomment) { if(hdrlen == sizeof(hdrbuf) - 1) { - warnf(config->global, "File %s line %d: header too long (truncated)", + warnf("File %s line %d: header too long (truncated)", filename, lineno); c = ' '; } @@ -481,7 +476,7 @@ static int read_field_headers(struct OperationConfig *config, /* NOTREACHED */ } -static int get_param_part(struct OperationConfig *config, char endchar, +static int get_param_part(char endchar, char **str, char **pdata, char **ptype, char **pfilename, char **pencoder, struct curl_slist **pheaders) @@ -507,7 +502,7 @@ static int get_param_part(struct OperationConfig *config, char endchar, while(ISBLANK(*p)) p++; tp = p; - *pdata = get_param_word(config, &p, &endpos, endchar); + *pdata = get_param_word(&p, &endpos, endchar); /* If not quoted, strip trailing spaces. */ if(*pdata == tp) while(endpos > *pdata && ISBLANK(endpos[-1])) @@ -539,7 +534,7 @@ static int get_param_part(struct OperationConfig *config, char endchar, for(p += 9; ISBLANK(*p); p++) ; tp = p; - filename = get_param_word(config, &p, &endpos, endchar); + filename = get_param_word(&p, &endpos, endchar); /* If not quoted, strip trailing spaces. */ if(filename == tp) while(endpos > filename && ISBLANK(endpos[-1])) @@ -561,7 +556,7 @@ static int get_param_part(struct OperationConfig *config, char endchar, p++; } while(ISBLANK(*p)); tp = p; - hdrfile = get_param_word(config, &p, &endpos, endchar); + hdrfile = get_param_word(&p, &endpos, endchar); /* If not quoted, strip trailing spaces. */ if(hdrfile == tp) while(endpos > hdrfile && ISBLANK(endpos[-1])) @@ -570,10 +565,10 @@ static int get_param_part(struct OperationConfig *config, char endchar, *endpos = '\0'; fp = fopen(hdrfile, FOPEN_READTEXT); if(!fp) - warnf(config->global, "Cannot read from %s: %s", hdrfile, + warnf("Cannot read from %s: %s", hdrfile, strerror(errno)); else { - int i = read_field_headers(config, hdrfile, fp, &headers); + int i = read_field_headers(hdrfile, fp, &headers); fclose(fp); if(i) { @@ -588,7 +583,7 @@ static int get_param_part(struct OperationConfig *config, char endchar, while(ISBLANK(*p)) p++; tp = p; - hdr = get_param_word(config, &p, &endpos, endchar); + hdr = get_param_word(&p, &endpos, endchar); /* If not quoted, strip trailing spaces. */ if(hdr == tp) while(endpos > hdr && ISBLANK(endpos[-1])) @@ -596,7 +591,7 @@ static int get_param_part(struct OperationConfig *config, char endchar, sep = *p; *endpos = '\0'; if(slist_append(&headers, hdr)) { - errorf(config->global, "Out of memory for field header"); + errorf("Out of memory for field header"); curl_slist_free_all(headers); return -1; } @@ -610,7 +605,7 @@ static int get_param_part(struct OperationConfig *config, char endchar, for(p += 8; ISBLANK(*p); p++) ; tp = p; - encoder = get_param_word(config, &p, &endpos, endchar); + encoder = get_param_word(&p, &endpos, endchar); /* If not quoted, strip trailing spaces. */ if(encoder == tp) while(endpos > encoder && ISSPACE(endpos[-1])) @@ -627,12 +622,12 @@ static int get_param_part(struct OperationConfig *config, char endchar, } else { /* unknown prefix, skip to next block */ - char *unknown = get_param_word(config, &p, &endpos, endchar); + char *unknown = get_param_word(&p, &endpos, endchar); sep = *p; *endpos = '\0'; if(*unknown) - warnf(config->global, "skip unknown form field: %s", unknown); + warnf("skip unknown form field: %s", unknown); } } @@ -643,25 +638,22 @@ static int get_param_part(struct OperationConfig *config, char endchar, if(ptype) *ptype = type; else if(type) - warnf(config->global, "Field content type not allowed here: %s", type); + warnf("Field content type not allowed here: %s", type); if(pfilename) *pfilename = filename; else if(filename) - warnf(config->global, - "Field filename not allowed here: %s", filename); + warnf("Field filename not allowed here: %s", filename); if(pencoder) *pencoder = encoder; else if(encoder) - warnf(config->global, - "Field encoder not allowed here: %s", encoder); + warnf("Field encoder not allowed here: %s", encoder); if(pheaders) *pheaders = headers; else if(headers) { - warnf(config->global, - "Field headers not allowed here: %s", headers->data); + warnf("Field headers not allowed here: %s", headers->data); curl_slist_free_all(headers); } @@ -726,8 +718,7 @@ static int get_param_part(struct OperationConfig *config, char endchar, } \ } while(0) -int formparse(struct OperationConfig *config, - const char *input, +int formparse(const char *input, struct tool_mime **mimeroot, struct tool_mime **mimecurrent, bool literal_value) @@ -769,8 +760,7 @@ int formparse(struct OperationConfig *config, if(*contp == '(' && !literal_value) { /* Starting a multipart. */ - sep = get_param_part(config, '\0', - &contp, &data, &type, NULL, NULL, &headers); + sep = get_param_part('\0', &contp, &data, &type, NULL, NULL, &headers); if(sep < 0) goto fail; part = tool_mime_new_parts(*mimecurrent); @@ -784,7 +774,7 @@ int formparse(struct OperationConfig *config, else if(!name && !strcmp(contp, ")") && !literal_value) { /* Ending a multipart. */ if(*mimecurrent == *mimeroot) { - warnf(config->global, "no multipart to terminate"); + warnf("no multipart to terminate"); goto fail; } *mimecurrent = (*mimecurrent)->parent; @@ -799,7 +789,7 @@ int formparse(struct OperationConfig *config, /* since this was a file, it may have a content-type specifier at the end too, or a filename. Or both. */ ++contp; - sep = get_param_part(config, ',', &contp, + sep = get_param_part(',', &contp, &data, &type, &filename, &encoder, &headers); if(sep < 0) { goto fail; @@ -823,14 +813,12 @@ int formparse(struct OperationConfig *config, goto fail; part->headers = headers; headers = NULL; - part->global = config->global; if(res == CURLE_READ_ERROR) { /* An error occurred while reading stdin: if read has started, issue the error now. Else, delay it until processed by libcurl. */ if(part->size > 0) { - warnf(config->global, - "error while reading standard input"); + warnf("error while reading standard input"); goto fail; } tool_safefree(part->data); @@ -848,7 +836,7 @@ int formparse(struct OperationConfig *config, else { if(*contp == '<' && !literal_value) { ++contp; - sep = get_param_part(config, '\0', &contp, + sep = get_param_part('\0', &contp, &data, &type, NULL, &encoder, &headers); if(sep < 0) goto fail; @@ -859,14 +847,12 @@ int formparse(struct OperationConfig *config, goto fail; part->headers = headers; headers = NULL; - part->global = config->global; if(res == CURLE_READ_ERROR) { /* An error occurred while reading stdin: if read has started, issue the error now. Else, delay it until processed by libcurl. */ if(part->size > 0) { - warnf(config->global, - "error while reading standard input"); + warnf("error while reading standard input"); goto fail; } tool_safefree(part->data); @@ -878,7 +864,7 @@ int formparse(struct OperationConfig *config, if(literal_value) data = contp; else { - sep = get_param_part(config, '\0', &contp, + sep = get_param_part('\0', &contp, &data, &type, &filename, &encoder, &headers); if(sep < 0) goto fail; @@ -897,8 +883,7 @@ int formparse(struct OperationConfig *config, if(sep) { *contp = (char) sep; - warnf(config->global, - "garbage at end of field specification: %s", contp); + warnf("garbage at end of field specification: %s", contp); } } @@ -906,7 +891,7 @@ int formparse(struct OperationConfig *config, SET_TOOL_MIME_PTR(part, name); } else { - warnf(config->global, "Illegally formatted input field"); + warnf("Illegally formatted input field"); goto fail; } err = 0; diff --git a/src/tool_formparse.h b/src/tool_formparse.h index 96562fced..d2222330e 100644 --- a/src/tool_formparse.h +++ b/src/tool_formparse.h @@ -55,15 +55,13 @@ struct tool_mime { curl_off_t origin; /* Stdin read origin offset. */ curl_off_t size; /* Stdin data size. */ curl_off_t curpos; /* Stdin current read position. */ - struct GlobalConfig *global; /* For access from callback. */ }; size_t tool_mime_stdin_read(char *buffer, size_t size, size_t nitems, void *arg); int tool_mime_stdin_seek(void *instream, curl_off_t offset, int whence); -int formparse(struct OperationConfig *config, - const char *input, +int formparse(const char *input, struct tool_mime **mimeroot, struct tool_mime **mimecurrent, bool literal_value); diff --git a/src/tool_getparam.c b/src/tool_getparam.c index cf606663f..475cbd492 100644 --- a/src/tool_getparam.c +++ b/src/tool_getparam.c @@ -523,8 +523,7 @@ GetFileAndPassword(const char *nextarg, char **file, char **password) /* Get a size parameter for '--limit-rate' or '--max-filesize'. * We support a 'G', 'M' or 'K' suffix too. */ -static ParameterError GetSizeParameter(struct GlobalConfig *global, - const char *arg, +static ParameterError GetSizeParameter(const char *arg, const char *which, curl_off_t *value_out) { @@ -532,7 +531,7 @@ static ParameterError GetSizeParameter(struct GlobalConfig *global, curl_off_t value; if(curlx_str_number(&unit, &value, CURL_OFF_T_MAX)) { - warnf(global, "invalid number specified for %s", which); + warnf("invalid number specified for %s", which); return PARAM_BAD_USE; } @@ -565,7 +564,7 @@ static ParameterError GetSizeParameter(struct GlobalConfig *global, /* for plain bytes, leave as-is */ break; default: - warnf(global, "unsupported %s unit. Use G, M, K or B", which); + warnf("unsupported %s unit. Use G, M, K or B", which); return PARAM_BAD_USE; } *value_out = value; @@ -591,8 +590,7 @@ static void cleanarg(char *str) #define MAX_DATAURLENCODE (500*1024*1024) /* --data-urlencode */ -static ParameterError data_urlencode(struct GlobalConfig *global, - const char *nextarg, +static ParameterError data_urlencode(const char *nextarg, char **postp, size_t *lenp) { @@ -631,7 +629,7 @@ static ParameterError data_urlencode(struct GlobalConfig *global, else { file = fopen(p, "rb"); if(!file) { - errorf(global, "Failed to open %s", p); + errorf("Failed to open %s", p); return PARAM_READ_ERROR; } } @@ -698,13 +696,12 @@ static void sethttpver(struct OperationConfig *config, { if(config->httpversion && (config->httpversion != httpversion)) - warnf(config->global, "Overrides previous HTTP version option"); + warnf("Overrides previous HTTP version option"); config->httpversion = httpversion; } -static CURLcode set_trace_config(struct GlobalConfig *global, - const char *token) +static CURLcode set_trace_config(const char *token) { CURLcode result = CURLE_OK; const char *next, *name; @@ -858,7 +855,7 @@ static ParameterError url_query(const char *nextarg, err = PARAM_NO_MEM; } else - err = data_urlencode(config->global, nextarg, &query, &size); + err = data_urlencode(nextarg, &query, &size); if(!err) { if(config->query) { @@ -885,10 +882,9 @@ static ParameterError set_data(cmdline_t cmd, FILE *file; size_t size = 0; ParameterError err = PARAM_OK; - struct GlobalConfig *global = config->global; if(cmd == C_DATA_URLENCODE) { /* --data-urlencode */ - err = data_urlencode(global, nextarg, &postdata, &size); + err = data_urlencode(nextarg, &postdata, &size); if(err) return err; } @@ -905,7 +901,7 @@ static ParameterError set_data(cmdline_t cmd, else { file = fopen(nextarg, "rb"); if(!file) { - errorf(global, "Failed to open %s", nextarg); + errorf("Failed to open %s", nextarg); return PARAM_READ_ERROR; } } @@ -958,8 +954,7 @@ static ParameterError set_data(cmdline_t cmd, return err; } -static ParameterError set_rate(struct GlobalConfig *global, - const char *nextarg) +static ParameterError set_rate(const char *nextarg) { /* --rate */ /* support a few different suffixes, extract the suffix first, then @@ -1007,14 +1002,14 @@ static ParameterError set_rate(struct GlobalConfig *global, numerator = 24*60*60*1000; break; default: - errorf(global, "unsupported --rate unit"); + errorf("unsupported --rate unit"); err = PARAM_BAD_USE; break; } if((LONG_MAX / numerator) < numunits) { /* overflow, too large number */ - errorf(global, "too large --rate unit"); + errorf("too large --rate unit"); err = PARAM_NUMBER_TOO_LARGE; } /* this typecast is okay based on the check above */ @@ -1076,7 +1071,7 @@ static ParameterError add_url(struct OperationConfig *config, url->useremote = url->noglob = TRUE; if(!err && (++config->num_urls > 1) && (config->etag_save_file || config->etag_compare_file)) { - errorf(config->global, "The etag options only work on a single URL"); + errorf("The etag options only work on a single URL"); return PARAM_BAD_USE; } } @@ -1159,20 +1154,17 @@ static ParameterError parse_localport(struct OperationConfig *config, static ParameterError parse_continue_at(struct OperationConfig *config, const char *nextarg) { - struct GlobalConfig *global = config->global; ParameterError err = PARAM_OK; if(config->range) { - errorf(global, "--continue-at is mutually exclusive with --range"); + errorf("--continue-at is mutually exclusive with --range"); return PARAM_BAD_USE; } if(config->rm_partial) { - errorf(config->global, - "--continue-at is mutually exclusive with --remove-on-error"); + errorf("--continue-at is mutually exclusive with --remove-on-error"); return PARAM_BAD_USE; } if(config->file_clobber_mode == CLOBBER_NEVER) { - errorf(config->global, - "--continue-at is mutually exclusive with --no-clobber"); + errorf("--continue-at is mutually exclusive with --no-clobber"); return PARAM_BAD_USE; } /* This makes us continue an ftp transfer at given position */ @@ -1216,8 +1208,7 @@ static ParameterError parse_ech(struct OperationConfig *config, file = fopen(nextarg, FOPEN_READTEXT); } if(!file) { - warnf(config->global, - "Couldn't read file \"%s\" " + warnf("Couldn't read file \"%s\" " "specified for \"--ech ecl:\" option", nextarg); return PARAM_BAD_USE; /* */ @@ -1252,7 +1243,7 @@ static ParameterError parse_header(struct OperationConfig *config, bool use_stdin = !strcmp(&nextarg[1], "-"); FILE *file = use_stdin ? stdin : fopen(&nextarg[1], FOPEN_READTEXT); if(!file) { - errorf(config->global, "Failed to open %s", &nextarg[1]); + errorf("Failed to open %s", &nextarg[1]); err = PARAM_READ_ERROR; } else { @@ -1392,10 +1383,9 @@ static ParameterError parse_range(struct OperationConfig *config, ParameterError err = PARAM_OK; curl_off_t value; const char *orig = nextarg; - struct GlobalConfig *global = config->global; if(config->use_resume) { - errorf(global, "--continue-at is mutually exclusive with --range"); + errorf("--continue-at is mutually exclusive with --range"); return PARAM_BAD_USE; } if(!curlx_str_number(&nextarg, &value, CURL_OFF_T_MAX) && @@ -1405,7 +1395,7 @@ static ParameterError parse_range(struct OperationConfig *config, claimed that to be a good way, why this code is added to work-around it. */ char buffer[32]; - warnf(global, "A specified range MUST include at least one dash (-). " + warnf("A specified range MUST include at least one dash (-). " "Appending one for you"); msnprintf(buffer, sizeof(buffer), "%" CURL_FORMAT_CURL_OFF_T "-", value); @@ -1418,7 +1408,7 @@ static ParameterError parse_range(struct OperationConfig *config, /* byte range requested */ while(*nextarg) { if(!ISDIGIT(*nextarg) && *nextarg != '-' && *nextarg != ',') { - warnf(global, "Invalid character is found in given range. " + warnf("Invalid character is found in given range. " "A specified range MUST have only digits in " "\'start\'-\'stop\'. The server's response to this " "request is uncertain."); @@ -1471,8 +1461,7 @@ static ParameterError parse_upload_file(struct OperationConfig *config, static size_t verbose_nopts; -static ParameterError parse_verbose(struct GlobalConfig *global, - bool toggle) +static ParameterError parse_verbose(bool toggle) { ParameterError err = PARAM_OK; @@ -1480,7 +1469,7 @@ static ParameterError parse_verbose(struct GlobalConfig *global, * more than once in the same argument flag, like `-vvv`. */ if(!toggle) { global->verbosity = 0; - if(set_trace_config(global, "-all")) + if(set_trace_config("-all")) err = PARAM_NO_MEM; global->tracetype = TRACE_NONE; return err; @@ -1488,7 +1477,7 @@ static ParameterError parse_verbose(struct GlobalConfig *global, else if(!verbose_nopts) { /* fist `-v` in an argument resets to base verbosity */ global->verbosity = 0; - if(set_trace_config(global, "-all")) + if(set_trace_config("-all")) return PARAM_NO_MEM; } /* the '%' thing here will cause the trace get sent to stderr */ @@ -1501,25 +1490,24 @@ static ParameterError parse_verbose(struct GlobalConfig *global, err = PARAM_NO_MEM; else { if(global->tracetype && (global->tracetype != TRACE_PLAIN)) - warnf(global, - "-v, --verbose overrides an earlier trace option"); + warnf("-v, --verbose overrides an earlier trace option"); global->tracetype = TRACE_PLAIN; } break; case 1: global->verbosity = 2; - if(set_trace_config(global, "ids,time,protocol")) + if(set_trace_config("ids,time,protocol")) err = PARAM_NO_MEM; break; case 2: global->verbosity = 3; global->tracetype = TRACE_ASCII; - if(set_trace_config(global, "ssl,read,write")) + if(set_trace_config("ssl,read,write")) err = PARAM_NO_MEM; break; case 3: global->verbosity = 4; - if(set_trace_config(global, "network")) + if(set_trace_config("network")) err = PARAM_NO_MEM; break; default: @@ -1549,7 +1537,7 @@ static ParameterError parse_writeout(struct OperationConfig *config, fname = nextarg; file = fopen(fname, FOPEN_READTEXT); if(!file) { - errorf(config->global, "Failed to open %s", fname); + errorf("Failed to open %s", fname); return PARAM_READ_ERROR; } } @@ -1560,7 +1548,7 @@ static ParameterError parse_writeout(struct OperationConfig *config, if(err) return err; if(!config->writeout) - warnf(config->global, "Failed to read %s", fname); + warnf("Failed to read %s", fname); } else err = getstr(&config->writeout, nextarg, ALLOW_BLANK); @@ -1596,15 +1584,14 @@ static ParameterError parse_time_cond(struct OperationConfig *config, if(config->condtime == -1) { curl_off_t value; /* now let's see if it is a filename to get the time from instead! */ - int rc = getfiletime(nextarg, config->global, &value); + int rc = getfiletime(nextarg, &value); if(!rc) /* pull the time out from the file */ config->condtime = value; else { /* failed, remove time condition */ config->timecond = CURL_TIMECOND_NONE; - warnf(config->global, - "Illegal date format for -z, --time-cond (and not " + warnf("Illegal date format for -z, --time-cond (and not " "a filename). Disabling time condition. " "See curl_getdate(3) for valid date syntax."); } @@ -1684,10 +1671,9 @@ static void togglebit(bool toggle, unsigned long *modify, unsigned long bits) } /* opt_depr is the function that handles ARG_DEPR options */ -static void opt_depr(struct GlobalConfig *global, - const struct LongShort *a) +static void opt_depr(const struct LongShort *a) { - warnf(global, "--%s is deprecated and has no function anymore", a->lname); + warnf("--%s is deprecated and has no function anymore", a->lname); } static ParameterError opt_sslver(struct OperationConfig *config, @@ -1695,7 +1681,7 @@ static ParameterError opt_sslver(struct OperationConfig *config, { if(config->ssl_version_max && (config->ssl_version_max < ver)) { - errorf(config->global, "Minimum TLS version set higher than max"); + errorf("Minimum TLS version set higher than max"); return PARAM_BAD_USE; } config->ssl_version = ver; @@ -1787,7 +1773,6 @@ static ParameterError opt_bool(struct OperationConfig *config, const struct LongShort *a, bool toggle) { - struct GlobalConfig *global = config->global; switch(a->cmd) { case C_ALPN: /* --alpn */ config->noalpn = !toggle; @@ -1864,7 +1849,7 @@ static ParameterError opt_bool(struct OperationConfig *config, case C_SSL: /* --ssl */ config->ftp_ssl = toggle; if(config->ftp_ssl) - warnf(global, "--%s is an insecure option, consider --ssl-reqd instead", + warnf("--%s is an insecure option, consider --ssl-reqd instead", a->lname); break; case C_FTP_SSL_CCC: /* --ftp-ssl-ccc */ @@ -2011,7 +1996,7 @@ static ParameterError opt_bool(struct OperationConfig *config, config->doh_verifystatus = toggle; break; case C_FALSE_START: /* --false-start */ - opt_depr(global, a); + opt_depr(a); break; case C_SSL_NO_REVOKE: /* --ssl-no-revoke */ config->ssl_no_revoke = toggle; @@ -2046,15 +2031,14 @@ static ParameterError opt_bool(struct OperationConfig *config, case C_FAIL_WITH_BODY: /* --fail-with-body */ config->failwithbody = toggle; if(config->failonerror && config->failwithbody) { - errorf(config->global, "You must select either --fail or " + errorf("You must select either --fail or " "--fail-with-body, not both."); return PARAM_BAD_USE; } break; case C_REMOVE_ON_ERROR: /* --remove-on-error */ if(config->use_resume && toggle) { - errorf(config->global, - "--continue-at is mutually exclusive with --remove-on-error"); + errorf("--continue-at is mutually exclusive with --remove-on-error"); return PARAM_BAD_USE; } config->rm_partial = toggle; @@ -2062,7 +2046,7 @@ static ParameterError opt_bool(struct OperationConfig *config, case C_FAIL: /* --fail */ config->failonerror = toggle; if(config->failonerror && config->failwithbody) { - errorf(config->global, "You must select either --fail or " + errorf("You must select either --fail or " "--fail-with-body, not both."); return PARAM_BAD_USE; } @@ -2083,7 +2067,7 @@ static ParameterError opt_bool(struct OperationConfig *config, case C_HEAD: /* --head */ config->no_body = toggle; config->show_headers = toggle; - if(SetHTTPrequest(config, (config->no_body) ? TOOL_HTTPREQ_HEAD : + if(SetHTTPrequest((config->no_body) ? TOOL_HTTPREQ_HEAD : TOOL_HTTPREQ_GET, &config->httpreq)) return PARAM_BAD_USE; break; @@ -2117,8 +2101,7 @@ static ParameterError opt_bool(struct OperationConfig *config, break; case C_CLOBBER: /* --clobber */ if(config->use_resume && !toggle) { - errorf(config->global, - "--continue-at is mutually exclusive with --no-clobber"); + errorf("--continue-at is mutually exclusive with --no-clobber"); return PARAM_BAD_USE; } config->file_clobber_mode = toggle ? CLOBBER_ALWAYS : CLOBBER_NEVER; @@ -2146,7 +2129,7 @@ static ParameterError opt_bool(struct OperationConfig *config, global->showerror = toggle; break; case C_VERBOSE: /* --verbose */ - return parse_verbose(global, toggle); + return parse_verbose(toggle); break; case C_VERSION: /* --version */ if(toggle) /* --no-version yields no output! */ @@ -2166,12 +2149,12 @@ static ParameterError opt_bool(struct OperationConfig *config, FALLTHROUGH(); case C_LOCATION: /* --location */ if(config->followlocation == CURLFOLLOW_OBEYCODE) - warnf(global, "--location overrides --follow"); + warnf("--location overrides --follow"); config->followlocation = toggle ? CURLFOLLOW_ALL : 0; break; case C_FOLLOW: /* --follow */ if(config->followlocation == CURLFOLLOW_ALL) - warnf(global, "--follow overrides --location"); + warnf("--follow overrides --location"); config->followlocation = toggle ? CURLFOLLOW_OBEYCODE : 0; break; default: @@ -2189,7 +2172,6 @@ static ParameterError opt_filestring(struct OperationConfig *config, ParameterError err = PARAM_OK; curl_off_t value; long val; - struct GlobalConfig *global = config->global; static const char *redir_protos[] = { "http", "https", @@ -2249,7 +2231,7 @@ static ParameterError opt_filestring(struct OperationConfig *config, err = getstr(&global->trace_dump, nextarg, DENY_BLANK); if(!err) { if(global->tracetype && (global->tracetype != TRACE_BIN)) - warnf(global, "--trace overrides an earlier trace/verbose option"); + warnf("--trace overrides an earlier trace/verbose option"); global->tracetype = TRACE_BIN; } break; @@ -2257,20 +2239,19 @@ static ParameterError opt_filestring(struct OperationConfig *config, err = getstr(&global->trace_dump, nextarg, DENY_BLANK); if(!err) { if(global->tracetype && (global->tracetype != TRACE_ASCII)) - warnf(global, - "--trace-ascii overrides an earlier trace/verbose option"); + warnf("--trace-ascii overrides an earlier trace/verbose option"); global->tracetype = TRACE_ASCII; } break; case C_LIMIT_RATE: /* --limit-rate */ - err = GetSizeParameter(global, nextarg, "rate", &value); + err = GetSizeParameter(nextarg, "rate", &value); if(!err) { config->recvpersecond = value; config->sendpersecond = value; } break; case C_RATE: - err = set_rate(global, nextarg); + err = set_rate(nextarg); break; case C_CREATE_FILE_MODE: /* --create-file-mode */ err = oct2nummax(&config->create_file_mode, nextarg, 0777); @@ -2292,7 +2273,7 @@ static ParameterError opt_filestring(struct OperationConfig *config, err = getstr(&config->aws_sigv4, nextarg, ALLOW_BLANK); break; case C_STDERR: /* --stderr */ - tool_set_stderr_file(global, nextarg); + tool_set_stderr_file(nextarg); break; case C_INTERFACE: /* --interface */ /* interface */ @@ -2309,7 +2290,7 @@ static ParameterError opt_filestring(struct OperationConfig *config, err = getstr(&config->haproxy_clientip, nextarg, DENY_BLANK); break; case C_MAX_FILESIZE: /* --max-filesize */ - err = GetSizeParameter(global, nextarg, "max-filesize", &value); + err = GetSizeParameter(nextarg, "max-filesize", &value); if(!err) config->max_filesize = value; break; @@ -2363,7 +2344,7 @@ static ParameterError opt_filestring(struct OperationConfig *config, err = getstr(&config->ftp_account, nextarg, DENY_BLANK); break; case C_FTP_METHOD: /* --ftp-method */ - config->ftp_filemethod = ftpfilemethod(config, nextarg); + config->ftp_filemethod = ftpfilemethod(nextarg); break; case C_LOCAL_PORT: /* --local-port */ err = parse_localport(config, nextarg); @@ -2373,8 +2354,7 @@ static ParameterError opt_filestring(struct OperationConfig *config, break; case C_LIBCURL: /* --libcurl */ #ifdef CURL_DISABLE_LIBCURL_OPTION - warnf(global, - "--libcurl option was disabled at build-time"); + warnf("--libcurl option was disabled at build-time"); err = PARAM_OPTION_UNKNOWN; #else err = getstr(&global->libcurl, nextarg, DENY_BLANK); @@ -2407,19 +2387,18 @@ static ParameterError opt_filestring(struct OperationConfig *config, break; case C_PROTO: /* --proto */ config->proto_present = TRUE; - err = proto2num(config, built_in_protos, &config->proto_str, nextarg); + err = proto2num(built_in_protos, &config->proto_str, nextarg); break; case C_PROTO_REDIR: /* --proto-redir */ config->proto_redir_present = TRUE; - if(proto2num(config, redir_protos, &config->proto_redir_str, - nextarg)) + if(proto2num(redir_protos, &config->proto_redir_str, nextarg)) err = PARAM_BAD_USE; break; case C_RESOLVE: /* --resolve */ err = add2list(&config->resolve, nextarg); break; case C_DELEGATION: /* --delegation */ - config->gssapi_delegation = delegation(config, nextarg); + config->gssapi_delegation = delegation(nextarg); break; case C_MAIL_AUTH: /* --mail-auth */ err = getstr(&config->mail_auth, nextarg, DENY_BLANK); @@ -2455,7 +2434,7 @@ static ParameterError opt_filestring(struct OperationConfig *config, case C_TLS_MAX: /* --tls-max */ err = str2tls_max(&config->ssl_version_max, nextarg); if(!err && (config->ssl_version_max < config->ssl_version)) { - errorf(global, "--tls-max set lower than minimum accepted version"); + errorf("--tls-max set lower than minimum accepted version"); err = PARAM_BAD_USE; } break; @@ -2464,11 +2443,11 @@ static ParameterError opt_filestring(struct OperationConfig *config, /* 0 is a valid value for this timeout */ break; case C_TRACE_CONFIG: /* --trace-config */ - if(set_trace_config(global, nextarg)) + if(set_trace_config(nextarg)) err = PARAM_NO_MEM; break; case C_VARIABLE: /* --variable */ - err = setvariable(global, nextarg); + err = setvariable(nextarg); break; case C_TLS13_CIPHERS: /* --tls13-ciphers */ err = getstr(&config->cipher13_list, nextarg, DENY_BLANK); @@ -2678,7 +2657,7 @@ static ParameterError opt_filestring(struct OperationConfig *config, break; case C_ETAG_SAVE: /* --etag-save */ if(config->num_urls > 1) { - errorf(global, "The etag options only work on a single URL"); + errorf("The etag options only work on a single URL"); err = PARAM_BAD_USE; } else @@ -2686,7 +2665,7 @@ static ParameterError opt_filestring(struct OperationConfig *config, break; case C_ETAG_COMPARE: /* --etag-compare */ if(config->num_urls > 1) { - errorf(global, "The etag options only work on a single URL"); + errorf("The etag options only work on a single URL"); err = PARAM_BAD_USE; } else @@ -2702,13 +2681,10 @@ static ParameterError opt_filestring(struct OperationConfig *config, case C_FORM_STRING: /* --form-string */ /* "form data" simulation, this is a little advanced so lets do our best to sort this out slowly and carefully */ - if(formparse(config, - nextarg, - &config->mimeroot, - &config->mimecurrent, + if(formparse(nextarg, &config->mimeroot, &config->mimecurrent, (a->cmd == C_FORM_STRING))) /* literal string */ err = PARAM_BAD_USE; - else if(SetHTTPrequest(config, TOOL_HTTPREQ_MIMEPOST, &config->httpreq)) + else if(SetHTTPrequest(TOOL_HTTPREQ_MIMEPOST, &config->httpreq)) err = PARAM_BAD_USE; break; case C_REQUEST_TARGET: /* --request-target */ @@ -2719,8 +2695,8 @@ static ParameterError opt_filestring(struct OperationConfig *config, err = parse_header(config, (cmdline_t)a->cmd, nextarg); break; case C_CONFIG: /* --config */ - if(parseconfig(nextarg, global)) { - errorf(global, "cannot read config from '%s'", nextarg); + if(parseconfig(nextarg)) { + errorf("cannot read config from '%s'", nextarg); err = PARAM_READ_ERROR; } break; @@ -2747,7 +2723,7 @@ static ParameterError opt_filestring(struct OperationConfig *config, break; case C_FTP_SSL_CCC_MODE: /* --ftp-ssl-ccc-mode */ config->ftp_ssl_ccc = TRUE; - config->ftp_ssl_ccc_mode = ftpcccmethod(config, nextarg); + config->ftp_ssl_ccc_mode = ftpcccmethod(nextarg); break; case C_QUOTE: /* --quote */ err = parse_quote(config, nextarg); @@ -2849,7 +2825,6 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ bool nextalloc = FALSE; /* if nextarg is allocated */ bool consumearg = TRUE; /* the argument comes separate */ const struct LongShort *a = NULL; - struct GlobalConfig *global = config->global; verbose_nopts = 0; /* options processed in `flag`*/ *usedarg = FALSE; /* default is that we do not use the arg */ @@ -2911,7 +2886,7 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ err = PARAM_EXPAND_ERROR; goto error; } - err = varexpand(global, nextarg, &nbuf, &replaced); + err = varexpand(nextarg, &nbuf, &replaced); if(err) { curlx_dyn_free(&nbuf); goto error; @@ -2961,18 +2936,18 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ *usedarg = consumearg; /* mark it as used */ } if(a->desc & ARG_DEPR) { - opt_depr(global, a); + opt_depr(a); break; } if((ARGTYPE(a->desc) == ARG_FILE) && (nextarg[0] == '-') && nextarg[1]) { /* if the filename looks like a command line option */ - warnf(global, "The filename argument '%s' looks like a flag.", + warnf("The filename argument '%s' looks like a flag.", nextarg); } else if(!strncmp("\xe2\x80\x9c", nextarg, 3)) { - warnf(global, "The argument '%s' starts with a Unicode quote where " + warnf("The argument '%s' starts with a Unicode quote where " "maybe an ASCII \" was intended?", nextarg); } @@ -2983,7 +2958,7 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ } else { if(a->desc & ARG_DEPR) { - opt_depr(global, a); + opt_depr(a); break; } /* ARG_NONE | ARG_BOOL */ @@ -3003,8 +2978,7 @@ error: return err; } -ParameterError parse_args(struct GlobalConfig *global, int argc, - argv_item_t argv[]) +ParameterError parse_args(int argc, argv_item_t argv[]) { int i; bool stillflags; @@ -3045,7 +3019,7 @@ ParameterError parse_args(struct GlobalConfig *global, int argc, if(config->url_list && config->url_list->url) { /* Allocate the next config */ - config->next = config_alloc(global); + config->next = config_alloc(); if(config->next) { /* Update the last config pointer */ global->last = config->next; @@ -3058,7 +3032,7 @@ ParameterError parse_args(struct GlobalConfig *global, int argc, result = PARAM_NO_MEM; } else { - errorf(global, "missing URL before --next"); + errorf("missing URL before --next"); result = PARAM_BAD_USE; } } @@ -3092,9 +3066,9 @@ ParameterError parse_args(struct GlobalConfig *global, int argc, const char *reason = param2text(result); if(orig_opt && strcmp(":", orig_opt)) - helpf(tool_stderr, "option %s: %s", orig_opt, reason); + helpf("option %s: %s", orig_opt, reason); else - helpf(tool_stderr, "%s", reason); + helpf("%s", reason); } unicodefree(orig_opt); diff --git a/src/tool_getparam.h b/src/tool_getparam.h index ca630e297..a08bbac7b 100644 --- a/src/tool_getparam.h +++ b/src/tool_getparam.h @@ -360,7 +360,6 @@ typedef enum { PARAM_LAST } ParameterError; -struct GlobalConfig; struct OperationConfig; const struct LongShort *findlongopt(const char *opt); @@ -376,8 +375,7 @@ void parse_cert_parameter(const char *cert_parameter, char **passphrase); #endif -ParameterError parse_args(struct GlobalConfig *global, int argc, - argv_item_t argv[]); +ParameterError parse_args(int argc, argv_item_t argv[]); #if defined(UNICODE) && defined(_WIN32) && !defined(UNDER_CE) diff --git a/src/tool_helpers.c b/src/tool_helpers.c index ec5671208..fbf3f1c93 100644 --- a/src/tool_helpers.c +++ b/src/tool_helpers.c @@ -75,7 +75,7 @@ const char *param2text(ParameterError error) } } -int SetHTTPrequest(struct OperationConfig *config, HttpReq req, HttpReq *store) +int SetHTTPrequest(HttpReq req, HttpReq *store) { /* this mirrors the HttpReq enum in tool_sdecls.h */ const char *reqname[]= { @@ -92,15 +92,14 @@ int SetHTTPrequest(struct OperationConfig *config, HttpReq req, HttpReq *store) *store = req; return 0; } - warnf(config->global, "You can only select one HTTP request method! " + warnf("You can only select one HTTP request method! " "You asked for both %s and %s.", reqname[req], reqname[*store]); return 1; } -void customrequest_helper(struct OperationConfig *config, HttpReq req, - char *method) +void customrequest_helper(HttpReq req, char *method) { /* this mirrors the HttpReq enum in tool_sdecls.h */ const char *dflt[]= { @@ -115,12 +114,11 @@ void customrequest_helper(struct OperationConfig *config, HttpReq req, if(!method) ; else if(curl_strequal(method, dflt[req])) { - notef(config->global, "Unnecessary use of -X or --request, %s is already " + notef("Unnecessary use of -X or --request, %s is already " "inferred.", dflt[req]); } else if(curl_strequal(method, "head")) { - warnf(config->global, - "Setting custom HTTP method to HEAD with -X/--request may not work " + warnf("Setting custom HTTP method to HEAD with -X/--request may not work " "the way you want. Consider using -I/--head instead."); } } diff --git a/src/tool_helpers.h b/src/tool_helpers.h index dd085e2cc..fab026b05 100644 --- a/src/tool_helpers.h +++ b/src/tool_helpers.h @@ -26,11 +26,7 @@ #include "tool_setup.h" const char *param2text(ParameterError error); - -int SetHTTPrequest(struct OperationConfig *config, HttpReq req, - HttpReq *store); - -void customrequest_helper(struct OperationConfig *config, HttpReq req, - char *method); +int SetHTTPrequest(HttpReq req, HttpReq *store); +void customrequest_helper(HttpReq req, char *method); #endif /* HEADER_CURL_TOOL_HELPERS_H */ diff --git a/src/tool_ipfs.c b/src/tool_ipfs.c index 06c45cb57..dd030f09b 100644 --- a/src/tool_ipfs.c +++ b/src/tool_ipfs.c @@ -271,13 +271,13 @@ clean: { switch(result) { case CURLE_URL_MALFORMAT: - helpf(tool_stderr, "malformed target URL"); + helpf("malformed target URL"); break; case CURLE_FILE_COULDNT_READ_FILE: - helpf(tool_stderr, "IPFS automatic gateway detection failed"); + helpf("IPFS automatic gateway detection failed"); break; case CURLE_BAD_FUNCTION_ARGUMENT: - helpf(tool_stderr, "--ipfs-gateway was given a malformed URL"); + helpf("--ipfs-gateway was given a malformed URL"); break; default: break; diff --git a/src/tool_main.c b/src/tool_main.c index 49a629a5f..0ad40dc29 100644 --- a/src/tool_main.c +++ b/src/tool_main.c @@ -141,80 +141,6 @@ static void memory_tracking_init(void) #endif /* - * This is the main global constructor for the app. Call this before - * _any_ libcurl usage. If this fails, *NO* libcurl functions may be - * used, or havoc may be the result. - */ -static CURLcode main_init(struct GlobalConfig *global) -{ - CURLcode result = CURLE_OK; - -#ifdef __DJGPP__ - /* stop stat() wasting time */ - _djstat_flags |= _STAT_INODE | _STAT_EXEC_MAGIC | _STAT_DIRSIZE; -#endif - - /* Initialise the global config */ - global->showerror = FALSE; /* show errors when silent */ - global->styled_output = TRUE; /* enable detection */ - global->parallel_max = PARALLEL_DEFAULT; - - /* Allocate the initial operate config */ - global->first = global->last = config_alloc(global); - if(global->first) { - /* Perform the libcurl initialization */ - result = curl_global_init(CURL_GLOBAL_DEFAULT); - if(!result) { - /* Get information about libcurl */ - result = get_libcurl_info(); - - if(result) { - errorf(global, "error retrieving curl library information"); - free(global->first); - } - } - else { - errorf(global, "error initializing curl library"); - free(global->first); - } - } - else { - errorf(global, "error initializing curl"); - result = CURLE_FAILED_INIT; - } - - return result; -} - -static void free_globalconfig(struct GlobalConfig *global) -{ - tool_safefree(global->trace_dump); - - if(global->trace_fopened && global->trace_stream) - fclose(global->trace_stream); - global->trace_stream = NULL; - - tool_safefree(global->libcurl); -} - -/* - * This is the main global destructor for the app. Call this after _all_ - * libcurl usage is done. - */ -static void main_free(struct GlobalConfig *global) -{ - /* Cleanup the easy handle */ - /* Main cleanup */ - curl_global_cleanup(); - free_globalconfig(global); - - /* Free the OperationConfig structures */ - config_free(global->last); - global->first = NULL; - global->last = NULL; -} - -/* ** curl tool main function. */ #if defined(_UNICODE) && !defined(UNDER_CE) @@ -230,8 +156,6 @@ int main(int argc, char *argv[]) #endif { CURLcode result = CURLE_OK; - struct GlobalConfig global; - memset(&global, 0, sizeof(global)); tool_init_stderr(); @@ -250,13 +174,13 @@ int main(int argc, char *argv[]) /* win32_init must be called before other init routines. */ result = win32_init(); if(result) { - errorf(&global, "(%d) Windows-specific init failed", result); + errorf("(%d) Windows-specific init failed", result); return (int)result; } #endif if(main_checkfds()) { - errorf(&global, "out of file descriptors"); + errorf("out of file descriptors"); return CURLE_FAILED_INIT; } @@ -269,13 +193,13 @@ int main(int argc, char *argv[]) /* Initialize the curl library - do not call any libcurl functions before this point */ - result = main_init(&global); + result = globalconf_init(); if(!result) { /* Start our curl operation */ - result = operate(&global, argc, argv); + result = operate(argc, argv); /* Perform the main cleanup */ - main_free(&global); + globalconf_free(); } #ifdef _WIN32 diff --git a/src/tool_msgs.c b/src/tool_msgs.c index 8c954cced..de0c1431e 100644 --- a/src/tool_msgs.c +++ b/src/tool_msgs.c @@ -34,13 +34,11 @@ #define NOTE_PREFIX "Note: " #define ERROR_PREFIX "curl: " -static void voutf(struct GlobalConfig *global, - const char *prefix, +static void voutf(const char *prefix, const char *fmt, - va_list ap) CURL_PRINTF(3, 0); + va_list ap) CURL_PRINTF(2, 0); -static void voutf(struct GlobalConfig *global, - const char *prefix, +static void voutf(const char *prefix, const char *fmt, va_list ap) { @@ -90,12 +88,12 @@ static void voutf(struct GlobalConfig *global, * Emit 'note' formatted message on configured 'errors' stream, if verbose was * selected. */ -void notef(struct GlobalConfig *global, const char *fmt, ...) +void notef(const char *fmt, ...) { va_list ap; va_start(ap, fmt); if(global->tracetype) - voutf(global, NOTE_PREFIX, fmt, ap); + voutf(NOTE_PREFIX, fmt, ap); va_end(ap); } @@ -103,11 +101,11 @@ void notef(struct GlobalConfig *global, const char *fmt, ...) * Emit warning formatted message on configured 'errors' stream unless * mute (--silent) was selected. */ -void warnf(struct GlobalConfig *global, const char *fmt, ...) +void warnf(const char *fmt, ...) { va_list ap; va_start(ap, fmt); - voutf(global, WARN_PREFIX, fmt, ap); + voutf(WARN_PREFIX, fmt, ap); va_end(ap); } @@ -115,18 +113,18 @@ void warnf(struct GlobalConfig *global, const char *fmt, ...) * Emit help formatted message on given stream. This is for errors with or * related to command line arguments. */ -void helpf(FILE *errors, const char *fmt, ...) +void helpf(const char *fmt, ...) { if(fmt) { va_list ap; va_start(ap, fmt); DEBUGASSERT(!strchr(fmt, '\n')); - fputs("curl: ", errors); /* prefix it */ - vfprintf(errors, fmt, ap); + fputs("curl: ", tool_stderr); /* prefix it */ + vfprintf(tool_stderr, fmt, ap); va_end(ap); - fputs("\n", errors); /* newline it */ + fputs("\n", tool_stderr); /* newline it */ } - fprintf(errors, "curl: try 'curl --help' " + fprintf(tool_stderr, "curl: try 'curl --help' " #ifdef USE_MANUAL "or 'curl --manual' " #endif @@ -137,12 +135,12 @@ void helpf(FILE *errors, const char *fmt, ...) * Emit error message on error stream if not muted. When errors are not tied * to command line arguments, use helpf() for such errors. */ -void errorf(struct GlobalConfig *global, const char *fmt, ...) +void errorf(const char *fmt, ...) { if(!global->silent || global->showerror) { va_list ap; va_start(ap, fmt); - voutf(global, ERROR_PREFIX, fmt, ap); + voutf(ERROR_PREFIX, fmt, ap); va_end(ap); } } diff --git a/src/tool_msgs.h b/src/tool_msgs.h index 681c98a56..99a980234 100644 --- a/src/tool_msgs.h +++ b/src/tool_msgs.h @@ -26,13 +26,13 @@ #include "tool_setup.h" #include "tool_cfgable.h" -void warnf(struct GlobalConfig *global, const char *fmt, ...) - CURL_PRINTF(2, 3); -void notef(struct GlobalConfig *global, const char *fmt, ...) - CURL_PRINTF(2, 3); -void helpf(FILE *errors, const char *fmt, ...) - CURL_PRINTF(2, 3); -void errorf(struct GlobalConfig *global, const char *fmt, ...) - CURL_PRINTF(2, 3); +void warnf(const char *fmt, ...) + CURL_PRINTF(1, 2); +void notef(const char *fmt, ...) + CURL_PRINTF(1, 2); +void helpf(const char *fmt, ...) + CURL_PRINTF(1, 2); +void errorf(const char *fmt, ...) + CURL_PRINTF(1, 2); #endif /* HEADER_CURL_TOOL_MSGS_H */ diff --git a/src/tool_operate.c b/src/tool_operate.c index e785bc321..ab1e898c9 100644 --- a/src/tool_operate.c +++ b/src/tool_operate.c @@ -114,8 +114,7 @@ static CURLcode single_transfer(struct OperationConfig *config, CURLSH *share, bool *added, bool *skipped); -static CURLcode create_transfer(struct GlobalConfig *global, - CURLSH *share, +static CURLcode create_transfer(CURLSH *share, bool *added, bool *skipped); @@ -260,17 +259,11 @@ static struct per_transfer *del_per_transfer(struct per_transfer *per) return n; } -static CURLcode pre_transfer(struct GlobalConfig *global, - struct per_transfer *per) +static CURLcode pre_transfer(struct per_transfer *per) { curl_off_t uploadfilesize = -1; struct_stat fileinfo; CURLcode result = CURLE_OK; -#ifdef CURL_DISABLE_LIBCURL_OPTION - (void)global; /* otherwise used in the my_setopt macros */ -#else - struct OperationConfig *config = global->current; -#endif if(per->uploadfile && !stdin_upload(per->uploadfile)) { /* VMS Note: @@ -309,7 +302,7 @@ static CURLcode pre_transfer(struct GlobalConfig *global, if((per->infd == -1) || fstat(per->infd, &fileinfo)) #endif { - helpf(tool_stderr, "cannot open '%s'", per->uploadfile); + helpf("cannot open '%s'", per->uploadfile); if(per->infd != -1) { close(per->infd); per->infd = STDIN_FILENO; @@ -348,7 +341,7 @@ void single_transfer_cleanup(struct OperationConfig *config) state = &config->state; /* Free list of remaining URLs */ - glob_cleanup(&state->urls); + glob_cleanup(&state->urlglob); state->outfiles = NULL; tool_safefree(state->uploadfile); /* Free list of globbed upload files */ @@ -470,7 +463,7 @@ static CURLcode retrycheck(struct OperationConfig *config, if((CURL_OFF_T_MAX - sleeptime < ms) || (ms + sleeptime > config->retry_maxtime_ms)) { - warnf(config->global, "The Retry-After: time would " + warnf("The Retry-After: time would " "make this command line exceed the maximum allowed time " "for retries."); *retryp = FALSE; @@ -479,7 +472,7 @@ static CURLcode retrycheck(struct OperationConfig *config, } } } - warnf(config->global, "Problem %s. " + warnf("Problem %s. " "Will retry in %ld second%s. " "%ld retr%s left.", m[retry], sleeptime/1000L, @@ -509,8 +502,7 @@ static CURLcode retrycheck(struct OperationConfig *config, int rc; /* We have written data to an output file, we truncate file */ fflush(outs->stream); - notef(config->global, - "Throwing away %" CURL_FORMAT_CURL_OFF_T " bytes", + notef("Throwing away %" CURL_FORMAT_CURL_OFF_T " bytes", outs->bytes); /* truncate file at the position where we started appending */ #if defined(HAVE_FTRUNCATE) && !defined(__DJGPP__) && !defined(__AMIGA__) && \ @@ -518,7 +510,7 @@ static CURLcode retrycheck(struct OperationConfig *config, if(ftruncate(fileno(outs->stream), outs->init)) { /* when truncate fails, we cannot just append as then we will create something strange, bail out */ - errorf(config->global, "Failed to truncate file"); + errorf("Failed to truncate file"); return CURLE_WRITE_ERROR; } /* now seek to the end of the file, the position where we @@ -532,7 +524,7 @@ static CURLcode retrycheck(struct OperationConfig *config, rc = fseek(outs->stream, (long)outs->init, SEEK_SET); #endif if(rc) { - errorf(config->global, "Failed seeking to end of file"); + errorf("Failed seeking to end of file"); return CURLE_WRITE_ERROR; } outs->bytes = 0; /* clear for next round */ @@ -550,8 +542,7 @@ static CURLcode retrycheck(struct OperationConfig *config, /* * Call this after a transfer has completed. */ -static CURLcode post_per_transfer(struct GlobalConfig *global, - struct per_transfer *per, +static CURLcode post_per_transfer(struct per_transfer *per, CURLcode result, bool *retryp, long *delay) /* milliseconds! */ @@ -572,7 +563,7 @@ static CURLcode post_per_transfer(struct GlobalConfig *global, #if defined(_WIN32) && !defined(CURL_WINDOWS_UWP) && !defined(UNDER_CE) sclose(per->infd); #else - warnf(per->config->global, "Closing per->infd != 0: FD == " + warnf("Closing per->infd != 0: FD == " "%d. This behavior is only supported on desktop " " Windows", per->infd); #endif @@ -619,7 +610,7 @@ static CURLcode post_per_transfer(struct GlobalConfig *global, if(!result && config->xattr && outs->fopened && outs->stream) { rc = fwrite_xattr(curl, per->url, fileno(outs->stream)); if(rc) - warnf(config->global, "Error setting extended attributes on '%s': %s", + warnf("Error setting extended attributes on '%s': %s", outs->filename, strerror(errno)); } @@ -641,7 +632,7 @@ static CURLcode post_per_transfer(struct GlobalConfig *global, if(!result && rc) { /* something went wrong in the writing process */ result = CURLE_WRITE_ERROR; - errorf(global, "Failed writing body"); + errorf("Failed writing body"); } } @@ -674,19 +665,19 @@ static CURLcode post_per_transfer(struct GlobalConfig *global, if(!result && rc) { /* something went wrong in the writing process */ result = CURLE_WRITE_ERROR; - errorf(config->global, "curl: (%d) Failed writing body", result); + errorf("curl: (%d) Failed writing body", result); } if(result && config->rm_partial) { struct_stat st; if(!stat(outs->filename, &st) && S_ISREG(st.st_mode)) { if(!unlink(outs->filename)) - notef(global, "Removed output file: %s", outs->filename); + notef("Removed output file: %s", outs->filename); else - warnf(global, "Failed removing: %s", outs->filename); + warnf("Failed removing: %s", outs->filename); } else - warnf(global, "Skipping removal; not a regular file: %s", + warnf("Skipping removal; not a regular file: %s", outs->filename); } } @@ -696,7 +687,7 @@ static CURLcode post_per_transfer(struct GlobalConfig *global, /* Ask libcurl if we got a remote file time */ curl_off_t filetime = -1; curl_easy_getinfo(curl, CURLINFO_FILETIME_T, &filetime); - setfiletime(filetime, outs->filename, global); + setfiletime(filetime, outs->filename); } skip: /* Write the --write-out data before cleanup but after result is final */ @@ -781,7 +772,7 @@ static CURLcode append2query(struct OperationConfig *config, CURLU_GUESS_SCHEME); if(uerr) { result = urlerr_cvt(uerr); - errorf(config->global, "(%d) Could not parse the URL, " + errorf("(%d) Could not parse the URL, " "failed to set query", result); config->synthetic_error = TRUE; } @@ -813,7 +804,7 @@ static CURLcode etag_compare(struct OperationConfig *config) /* open file for reading: */ FILE *file = fopen(config->etag_compare_file, FOPEN_READTEXT); if(!file) - warnf(config->global, "Failed to open %s: %s", config->etag_compare_file, + warnf("Failed to open %s: %s", config->etag_compare_file, strerror(errno)); if((PARAM_OK == file2string(&etag_from_file, file)) && @@ -827,8 +818,7 @@ static CURLcode etag_compare(struct OperationConfig *config) if(!header) { if(file) fclose(file); - errorf(config->global, - "Failed to allocate memory for custom etag header"); + errorf("Failed to allocate memory for custom etag header"); return CURLE_OUT_OF_MEMORY; } @@ -848,8 +838,7 @@ static CURLcode etag_store(struct OperationConfig *config, bool *skip) { if(config->create_dirs) { - CURLcode result = create_dir_hierarchy(config->etag_save_file, - config->global); + CURLcode result = create_dir_hierarchy(config->etag_save_file); if(result) return result; } @@ -859,10 +848,10 @@ static CURLcode etag_store(struct OperationConfig *config, FILE *newfile = fopen(config->etag_save_file, "ab"); if(!newfile) { struct State *state = &config->state; - warnf(config->global, "Failed creating file for saving etags: \"%s\". " + warnf("Failed creating file for saving etags: \"%s\". " "Skip this transfer", config->etag_save_file); state->outfiles = NULL; - glob_cleanup(&state->urls); + glob_cleanup(&state->urlglob); *skip = TRUE; return CURLE_OK; } @@ -903,8 +892,7 @@ static CURLcode setup_headerfile(struct OperationConfig *config, * that it does not need to be opened/closed for every transfer. */ if(config->create_dirs) { - CURLcode result = create_dir_hierarchy(config->headerfile, - config->global); + CURLcode result = create_dir_hierarchy(config->headerfile); /* create_dir_hierarchy shows error upon CURLE_WRITE_ERROR */ if(result) return result; @@ -917,7 +905,7 @@ static CURLcode setup_headerfile(struct OperationConfig *config, newfile = fopen(config->headerfile, "ab"); if(!newfile) { - errorf(config->global, "Failed to open %s", config->headerfile); + errorf("Failed to open %s", config->headerfile); return CURLE_WRITE_ERROR; } else { @@ -944,29 +932,29 @@ static CURLcode setup_outfile(struct OperationConfig *config, * decided we want to use the remote filename. */ struct State *state = &config->state; - struct GlobalConfig *global = config->global; if(!per->outfile) { /* extract the filename from the URL */ - CURLcode result = get_url_file_name(global, &per->outfile, per->url); + CURLcode result = get_url_file_name(&per->outfile, per->url); if(result) { - errorf(global, "Failed to extract a filename" + errorf("Failed to extract a filename" " from the URL to use for storage"); return result; } } - else if(state->urls) { + else if(glob_inuse(&state->urlglob)) { /* fill '#1' ... '#9' terms from URL pattern */ char *storefile = per->outfile; - CURLcode result = glob_match_url(&per->outfile, storefile, state->urls); + CURLcode result = + glob_match_url(&per->outfile, storefile, &state->urlglob); tool_safefree(storefile); if(result) { /* bad globbing */ - warnf(global, "bad output glob"); + warnf("bad output glob"); return result; } if(!*per->outfile) { - warnf(global, "output glob produces empty string"); + warnf("output glob produces empty string"); return CURLE_WRITE_ERROR; } } @@ -983,7 +971,7 @@ static CURLcode setup_outfile(struct OperationConfig *config, file output call */ if(config->create_dirs) { - CURLcode result = create_dir_hierarchy(per->outfile, global); + CURLcode result = create_dir_hierarchy(per->outfile); /* create_dir_hierarchy shows error upon CURLE_WRITE_ERROR */ if(result) return result; @@ -993,8 +981,7 @@ static CURLcode setup_outfile(struct OperationConfig *config, struct_stat fileinfo; if(!stat(per->outfile, &fileinfo)) { /* file is present */ - notef(global, "skips transfer, \"%s\" exists locally", - per->outfile); + notef("skips transfer, \"%s\" exists locally", per->outfile); per->skip = TRUE; *skipped = TRUE; } @@ -1024,7 +1011,7 @@ static CURLcode setup_outfile(struct OperationConfig *config, FILE *file = fopen(per->outfile, "ab"); #endif if(!file) { - errorf(global, "cannot open '%s'", per->outfile); + errorf("cannot open '%s'", per->outfile); return CURLE_WRITE_ERROR; } outs->fopened = TRUE; @@ -1042,7 +1029,6 @@ static CURLcode setup_outfile(struct OperationConfig *config, static void check_stdin_upload(struct OperationConfig *config, struct per_transfer *per) { - struct GlobalConfig *global = config->global; /* count to see if there are more than one auth bit set in the authtype field */ int authbits = 0; @@ -1062,8 +1048,7 @@ static void check_stdin_upload(struct OperationConfig *config, * we should warn them. */ if(config->proxyanyauth || (authbits > 1)) { - warnf(global, - "Using --anyauth or --proxy-anyauth with upload from stdin" + warnf("Using --anyauth or --proxy-anyauth with upload from stdin" " involves a big risk of it not working. Use a temporary" " file or a fixed auth type instead"); } @@ -1077,13 +1062,13 @@ static void check_stdin_upload(struct OperationConfig *config, /* non-blocking stdin behavior on Windows is challenging Spawn a new thread that will read from stdin and write out to a socket */ - curl_socket_t f = win32_stdin_read_thread(global); + curl_socket_t f = win32_stdin_read_thread(); if(f == CURL_SOCKET_BAD) - warnf(global, "win32_stdin_read_thread returned INVALID_SOCKET " + warnf("win32_stdin_read_thread returned INVALID_SOCKET " "falling back to blocking mode"); else if(f > INT_MAX) { - warnf(global, "win32_stdin_read_thread returned identifier " + warnf("win32_stdin_read_thread returned identifier " "larger than INT_MAX. This should not happen unless " "the upper 32 bits of a Windows socket have started " "being used for something... falling back to blocking " @@ -1094,8 +1079,7 @@ static void check_stdin_upload(struct OperationConfig *config, per->infd = (int)f; #endif if(curlx_nonblock((curl_socket_t)per->infd, TRUE) < 0) - warnf(global, - "fcntl failed on fd=%d: %s", per->infd, strerror(errno)); + warnf("fcntl failed on fd=%d: %s", per->infd, strerror(errno)); } } @@ -1106,7 +1090,6 @@ static CURLcode single_transfer(struct OperationConfig *config, bool *skipped) { CURLcode result = CURLE_OK; - struct GlobalConfig *global = config->global; bool orig_noprogress = global->noprogress; bool orig_isatty = global->isatty; struct State *state = &config->state; @@ -1120,12 +1103,12 @@ static CURLcode single_transfer(struct OperationConfig *config, /* Use the postfields data for an HTTP get */ httpgetfields = state->httpgetfields = config->postfields; config->postfields = NULL; - if(SetHTTPrequest(config, (config->no_body ? TOOL_HTTPREQ_HEAD : - TOOL_HTTPREQ_GET), &config->httpreq)) + if(SetHTTPrequest((config->no_body ? TOOL_HTTPREQ_HEAD : + TOOL_HTTPREQ_GET), &config->httpreq)) return CURLE_FAILED_INIT; } } - else if(SetHTTPrequest(config, TOOL_HTTPREQ_SIMPLEPOST, &config->httpreq)) + else if(SetHTTPrequest(TOOL_HTTPREQ_SIMPLEPOST, &config->httpreq)) return CURLE_FAILED_INIT; } @@ -1145,7 +1128,7 @@ static CURLcode single_transfer(struct OperationConfig *config, /* u->url is the full URL or NULL */ if(!u->url) { /* This node has no URL. End of the road. */ - warnf(config->global, "Got more output options than URLs"); + warnf("Got more output options than URLs"); break; } @@ -1153,7 +1136,7 @@ static CURLcode single_transfer(struct OperationConfig *config, if(u->outfile && !state->outfiles) state->outfiles = u->outfile; - if(!config->globoff && u->infile && !state->inglob) { + if(!config->globoff && u->infile && !glob_inuse(&state->inglob)) { /* Unless explicitly shut off */ result = glob_url(&state->inglob, u->infile, &state->infilenum, (!global->silent || global->showerror) ? @@ -1165,10 +1148,10 @@ static CURLcode single_transfer(struct OperationConfig *config, if(state->up || u->infile) { if(!state->uploadfile) { - if(state->inglob) { - result = glob_next_url(&state->uploadfile, state->inglob); + if(glob_inuse(&state->inglob)) { + result = glob_next_url(&state->uploadfile, &state->inglob); if(result == CURLE_OUT_OF_MEMORY) - errorf(global, "out of memory"); + errorf("out of memory"); } else if(!state->up) { /* copy the allocated string */ @@ -1184,7 +1167,7 @@ static CURLcode single_transfer(struct OperationConfig *config, if(!config->globoff && !u->noglob) { /* Unless explicitly shut off, we expand '{...}' and '[...]' expressions and return total number of URLs in pattern set */ - result = glob_url(&state->urls, u->url, &state->urlnum, + result = glob_url(&state->urlglob, u->url, &state->urlnum, (!global->silent || global->showerror) ? tool_stderr : NULL); if(result) @@ -1237,7 +1220,7 @@ static CURLcode single_transfer(struct OperationConfig *config, if(state->uploadfile) { per->uploadfile = strdup(state->uploadfile); if(!per->uploadfile || - SetHTTPrequest(config, TOOL_HTTPREQ_PUT, &config->httpreq)) { + SetHTTPrequest(TOOL_HTTPREQ_PUT, &config->httpreq)) { tool_safefree(per->uploadfile); curl_easy_cleanup(curl); return CURLE_FAILED_INIT; @@ -1268,8 +1251,8 @@ static CURLcode single_transfer(struct OperationConfig *config, /* default output stream is stdout */ outs->stream = stdout; - if(state->urls) { - result = glob_next_url(&per->url, state->urls); + if(glob_inuse(&state->urlglob)) { + result = glob_next_url(&per->url, &state->urlglob); if(result) return result; } @@ -1371,7 +1354,7 @@ static CURLcode single_transfer(struct OperationConfig *config, if(state->li >= state->urlnum) { state->li = 0; state->urlnum = 0; /* forced reglob of URLs */ - glob_cleanup(&state->urls); + glob_cleanup(&state->urlglob); state->up++; tool_safefree(state->uploadfile); /* clear it to get the next */ } @@ -1383,7 +1366,7 @@ static CURLcode single_transfer(struct OperationConfig *config, node itself nor modifying next pointer. */ u->outset = u->urlset = u->useremote = u->uploadset = u->noupload = u->noglob = FALSE; - glob_cleanup(&state->urls); + glob_cleanup(&state->urlglob); state->urlnum = 0; state->outfiles = NULL; @@ -1404,11 +1387,8 @@ static long all_added; /* number of easy handles currently added */ * to add even after this call returns. sets 'addedp' to TRUE if one or more * transfers were added. */ -static CURLcode add_parallel_transfers(struct GlobalConfig *global, - CURLM *multi, - CURLSH *share, - bool *morep, - bool *addedp) +static CURLcode add_parallel_transfers(CURLM *multi, CURLSH *share, + bool *morep, bool *addedp) { struct per_transfer *per; CURLcode result = CURLE_OK; @@ -1428,7 +1408,7 @@ static CURLcode add_parallel_transfers(struct GlobalConfig *global, if(nxfers < (curl_off_t)(global->parallel_max*2)) { bool skipped = FALSE; do { - result = create_transfer(global, share, addedp, &skipped); + result = create_transfer(share, addedp, &skipped); if(result) return result; } while(skipped); @@ -1445,7 +1425,7 @@ static CURLcode add_parallel_transfers(struct GlobalConfig *global, } per->added = TRUE; - result = pre_transfer(global, per); + result = pre_transfer(per); if(result) return result; @@ -1478,7 +1458,7 @@ static CURLcode add_parallel_transfers(struct GlobalConfig *global, bool getadded = FALSE; bool skipped = FALSE; do { - result = create_transfer(global, share, &getadded, &skipped); + result = create_transfer(share, &getadded, &skipped); if(result) break; } while(skipped); @@ -1499,7 +1479,6 @@ static CURLcode add_parallel_transfers(struct GlobalConfig *global, } struct parastate { - struct GlobalConfig *global; CURLM *multi; CURLSH *share; CURLMcode mcode; @@ -1543,8 +1522,7 @@ static void check_multi_info(struct datauv *uv) uv->s->result = result; if(uv->s->more_transfers) { - result = add_parallel_transfers(uv->s->global, uv->s->multi, - uv->s->share, + result = add_parallel_transfers(uv->s->multi, uv->s->share, &uv->s->more_transfers, &uv->s->added_transfers); if(result && !uv->s->result) @@ -1693,7 +1671,7 @@ static CURLcode parallel_event(struct parastate *s) curl_multi_setopt(s->multi, CURLMOPT_TIMERFUNCTION, cb_timeout); curl_multi_setopt(s->multi, CURLMOPT_TIMERDATA, &uv); curl_multi_setopt(s->multi, CURLMOPT_MAX_HOST_CONNECTIONS, - s->global->parallel_host); + global->parallel_host); /* kickstart the thing */ curl_multi_socket_action(s->multi, CURL_SOCKET_TIMEOUT, 0, @@ -1727,8 +1705,8 @@ static CURLcode parallel_event(struct parastate *s) } if(s->more_transfers) { - result = add_parallel_transfers(s->global, s->multi, s->share, - &s->more_transfers, &s->added_transfers); + result = add_parallel_transfers(s->multi, s->share, &s->more_transfers, + &s->added_transfers); if(result && !s->result) s->result = result; } @@ -1764,8 +1742,7 @@ static CURLcode check_finished(struct parastate *s) int rc; CURLMsg *msg; bool checkmore = FALSE; - struct GlobalConfig *global = s->global; - progress_meter(global, s->multi, &s->start, FALSE); + progress_meter(s->multi, &s->start, FALSE); do { msg = curl_multi_info_read(s->multi, &rc); if(msg) { @@ -1783,7 +1760,7 @@ static CURLcode check_finished(struct parastate *s) "Transfer aborted due to critical error " "in another transfer"); } - tres = post_per_transfer(global, ended, tres, &retry, &delay); + tres = post_per_transfer(ended, tres, &retry, &delay); progress_finalize(ended); /* before it goes away */ all_added--; /* one fewer added */ checkmore = TRUE; @@ -1813,8 +1790,7 @@ static CURLcode check_finished(struct parastate *s) } if(checkmore) { /* one or more transfers completed, add more! */ - CURLcode tres = add_parallel_transfers(global, - s->multi, s->share, + CURLcode tres = add_parallel_transfers(s->multi, s->share, &s->more_transfers, &s->added_transfers); if(tres) @@ -1829,8 +1805,7 @@ static CURLcode check_finished(struct parastate *s) return result; } -static CURLcode parallel_transfers(struct GlobalConfig *global, - CURLSH *share) +static CURLcode parallel_transfers(CURLSH *share) { CURLcode result; struct parastate p; @@ -1843,12 +1818,11 @@ static CURLcode parallel_transfers(struct GlobalConfig *global, s->wrapitup = FALSE; s->wrapitup_processed = FALSE; s->tick = time(NULL); - s->global = global; s->multi = curl_multi_init(); if(!s->multi) return CURLE_OUT_OF_MEMORY; - result = add_parallel_transfers(global, s->multi, s->share, + result = add_parallel_transfers(s->multi, s->share, &s->more_transfers, &s->added_transfers); if(result) { curl_multi_cleanup(s->multi); @@ -1860,7 +1834,7 @@ static CURLcode parallel_transfers(struct GlobalConfig *global, #ifdef USE_LIBUV return parallel_event(s); #else - errorf(global, "Testing --parallel event-based requires libuv"); + errorf("Testing --parallel event-based requires libuv"); #endif else #endif @@ -1890,7 +1864,7 @@ static CURLcode parallel_transfers(struct GlobalConfig *global, result = check_finished(s); } - (void)progress_meter(global, s->multi, &s->start, TRUE); + (void)progress_meter(s->multi, &s->start, TRUE); } /* Make sure to return some kind of error if there was a multi problem */ @@ -1906,8 +1880,7 @@ static CURLcode parallel_transfers(struct GlobalConfig *global, return result; } -static CURLcode serial_transfers(struct GlobalConfig *global, - CURLSH *share) +static CURLcode serial_transfers(CURLSH *share) { CURLcode returncode = CURLE_OK; CURLcode result = CURLE_OK; @@ -1915,11 +1888,11 @@ static CURLcode serial_transfers(struct GlobalConfig *global, bool added = FALSE; bool skipped = FALSE; - result = create_transfer(global, share, &added, &skipped); + result = create_transfer(share, &added, &skipped); if(result) return result; if(!added) { - errorf(global, "no transfer performed"); + errorf("no transfer performed"); return CURLE_READ_ERROR; } for(per = transfers; per;) { @@ -1930,7 +1903,7 @@ static CURLcode serial_transfers(struct GlobalConfig *global, start = curlx_now(); if(!per->skip) { - result = pre_transfer(global, per); + result = pre_transfer(per); if(result) break; @@ -1962,7 +1935,7 @@ static CURLcode serial_transfers(struct GlobalConfig *global, result = curl_easy_perform(per->curl); } - returncode = post_per_transfer(global, per, result, &retry, &delay_ms); + returncode = post_per_transfer(per, result, &retry, &delay_ms); if(retry) { curlx_wait_ms(delay_ms); continue; @@ -1974,7 +1947,7 @@ static CURLcode serial_transfers(struct GlobalConfig *global, else { do { /* setup the next one just before we delete this */ - result = create_transfer(global, share, &added, &skipped); + result = create_transfer(share, &added, &skipped); if(result) { returncode = result; bailout = TRUE; @@ -1993,8 +1966,8 @@ static CURLcode serial_transfers(struct GlobalConfig *global, milliseconds */ timediff_t milli = curlx_timediff(curlx_now(), start); if(milli < global->ms_per_transfer) { - notef(global, "Transfer took %" CURL_FORMAT_CURL_OFF_T " ms, " - "waits %ldms as set by --rate", + notef("Transfer took %" CURL_FORMAT_CURL_OFF_T " ms, " + "waits %ldms as set by --rate", milli, (long)(global->ms_per_transfer - milli)); /* The transfer took less time than wanted. Wait a little. */ curlx_wait_ms((long)(global->ms_per_transfer - milli)); @@ -2109,7 +2082,7 @@ static CURLcode transfer_per_config(struct OperationConfig *config, /* Check we have a url */ if(!config->url_list || !config->url_list->url) { - helpf(tool_stderr, "(%d) no URL specified", CURLE_FAILED_INIT); + helpf("(%d) no URL specified", CURLE_FAILED_INIT); return CURLE_FAILED_INIT; } @@ -2151,8 +2124,7 @@ static CURLcode transfer_per_config(struct OperationConfig *config, * 'create_transfer' gets the details and sets up a new transfer if 'added' * returns TRUE. */ -static CURLcode create_transfer(struct GlobalConfig *global, - CURLSH *share, +static CURLcode create_transfer(CURLSH *share, bool *added, bool *skipped) { @@ -2170,8 +2142,7 @@ static CURLcode create_transfer(struct GlobalConfig *global, return result; } -static CURLcode run_all_transfers(struct GlobalConfig *global, - CURLSH *share, +static CURLcode run_all_transfers(CURLSH *share, CURLcode result) { /* Save the values of noprogress and isatty to restore them later on */ @@ -2182,16 +2153,16 @@ static CURLcode run_all_transfers(struct GlobalConfig *global, /* Time to actually do the transfers */ if(!result) { if(global->parallel) - result = parallel_transfers(global, share); + result = parallel_transfers(share); else - result = serial_transfers(global, share); + result = serial_transfers(share); } /* cleanup if there are any left */ for(per = transfers; per;) { bool retry; long delay; - CURLcode result2 = post_per_transfer(global, per, result, &retry, &delay); + CURLcode result2 = post_per_transfer(per, result, &retry, &delay); if(!result) /* do not overwrite the original error */ result = result2; @@ -2210,7 +2181,7 @@ static CURLcode run_all_transfers(struct GlobalConfig *global, return result; } -CURLcode operate(struct GlobalConfig *global, int argc, argv_item_t argv[]) +CURLcode operate(int argc, argv_item_t argv[]) { CURLcode result = CURLE_OK; const char *first_arg; @@ -2230,11 +2201,11 @@ CURLcode operate(struct GlobalConfig *global, int argc, argv_item_t argv[]) if((argc == 1) || (first_arg && strncmp(first_arg, "-q", 2) && strcmp(first_arg, "--disable"))) { - parseconfig(NULL, global); /* ignore possible failure */ + parseconfig(NULL); /* ignore possible failure */ /* If we had no arguments then make sure a url was specified in .curlrc */ if((argc < 2) && (!global->first->url_list)) { - helpf(tool_stderr, NULL); + helpf(NULL); result = CURLE_FAILED_INIT; } } @@ -2243,7 +2214,7 @@ CURLcode operate(struct GlobalConfig *global, int argc, argv_item_t argv[]) if(!result) { /* Parse the command line arguments */ - ParameterError res = parse_args(global, argc, argv); + ParameterError res = parse_args(argc, argv); if(res) { result = CURLE_OK; @@ -2255,8 +2226,7 @@ CURLcode operate(struct GlobalConfig *global, int argc, argv_item_t argv[]) #ifdef USE_MANUAL hugehelp(); #else - warnf(global, - "built-in manual was disabled at build-time"); + warnf("built-in manual was disabled at build-time"); #endif } /* Check if we were asked for the version information */ @@ -2324,7 +2294,7 @@ CURLcode operate(struct GlobalConfig *global, int argc, argv_item_t argv[]) global->current = global->first; /* now run! */ - result = run_all_transfers(global, share, result); + result = run_all_transfers(share, result); if(global->ssl_sessions && feature_ssls_export) { CURLcode r2 = tool_ssls_save(global->first, share, @@ -2340,16 +2310,16 @@ CURLcode operate(struct GlobalConfig *global, int argc, argv_item_t argv[]) easysrc_cleanup(); /* Dump the libcurl code if previously enabled */ - dumpeasysrc(global); + dumpeasysrc(); } } } else - errorf(global, "out of memory"); + errorf("out of memory"); } } - varcleanup(global); + varcleanup(); curl_free(global->knownhosts); return result; diff --git a/src/tool_operate.h b/src/tool_operate.h index 2fe49931c..ec4204486 100644 --- a/src/tool_operate.h +++ b/src/tool_operate.h @@ -79,7 +79,7 @@ struct per_transfer { BIT(skip); /* considered already done */ }; -CURLcode operate(struct GlobalConfig *global, int argc, argv_item_t argv[]); +CURLcode operate(int argc, argv_item_t argv[]); void single_transfer_cleanup(struct OperationConfig *config); extern struct per_transfer *transfers; /* first node */ diff --git a/src/tool_operhlp.c b/src/tool_operhlp.c index 48129973f..e25a3cf60 100644 --- a/src/tool_operhlp.c +++ b/src/tool_operhlp.c @@ -173,8 +173,7 @@ fail: * Returns a pointer to a heap-allocated string or NULL if * no name part, at location indicated by first argument. */ -CURLcode get_url_file_name(struct GlobalConfig *global, - char **filename, const char *url) +CURLcode get_url_file_name(char **filename, const char *url) { CURLU *uh = curl_url(); char *path = NULL; @@ -212,7 +211,7 @@ CURLcode get_url_file_name(struct GlobalConfig *global, else { /* no slash => empty string, use default */ *filename = strdup("curl_response"); - warnf(global, "No remote file name, uses \"%s\"", *filename); + warnf("No remote file name, uses \"%s\"", *filename); } curl_free(path); diff --git a/src/tool_operhlp.h b/src/tool_operhlp.h index 19daa8e43..c83c10a59 100644 --- a/src/tool_operhlp.h +++ b/src/tool_operhlp.h @@ -28,16 +28,10 @@ struct OperationConfig; void clean_getout(struct OperationConfig *config); - bool output_expected(const char *url, const char *uploadfile); - bool stdin_upload(const char *uploadfile); - CURLcode add_file_name_to_url(CURL *curl, char **inurlp, const char *filename); - -CURLcode get_url_file_name(struct GlobalConfig *global, - char **filename, const char *url); - +CURLcode get_url_file_name(char **filename, const char *url); CURLcode urlerr_cvt(CURLUcode ucode); #endif /* HEADER_CURL_TOOL_OPERHLP_H */ diff --git a/src/tool_paramhlp.c b/src/tool_paramhlp.c index 43b5bee45..a1505115b 100644 --- a/src/tool_paramhlp.c +++ b/src/tool_paramhlp.c @@ -405,8 +405,7 @@ static void protoset_clear(const char **protoset, const char *proto) #define MAX_PROTOSTRING (64*11) /* Enough room for 64 10-chars proto names. */ -ParameterError proto2num(struct OperationConfig *config, - const char * const *val, char **ostr, const char *str) +ParameterError proto2num(const char * const *val, char **ostr, const char *str) { const char **protoset; struct dynbuf obuf; @@ -497,7 +496,7 @@ ParameterError proto2num(struct OperationConfig *config, if no protocols are allowed */ if(action == set) protoset[0] = NULL; - warnf(config->global, "unrecognized protocol '%s'", buffer); + warnf("unrecognized protocol '%s'", buffer); } } if(next) @@ -620,7 +619,7 @@ ParameterError add2list(struct curl_slist **list, const char *ptr) return PARAM_OK; } -long ftpfilemethod(struct OperationConfig *config, const char *str) +long ftpfilemethod(const char *str) { if(curl_strequal("singlecwd", str)) return CURLFTPMETHOD_SINGLECWD; @@ -629,26 +628,24 @@ long ftpfilemethod(struct OperationConfig *config, const char *str) if(curl_strequal("multicwd", str)) return CURLFTPMETHOD_MULTICWD; - warnf(config->global, "unrecognized ftp file method '%s', using default", - str); + warnf("unrecognized ftp file method '%s', using default", str); return CURLFTPMETHOD_MULTICWD; } -long ftpcccmethod(struct OperationConfig *config, const char *str) +long ftpcccmethod(const char *str) { if(curl_strequal("passive", str)) return CURLFTPSSL_CCC_PASSIVE; if(curl_strequal("active", str)) return CURLFTPSSL_CCC_ACTIVE; - warnf(config->global, "unrecognized ftp CCC method '%s', using default", - str); + warnf("unrecognized ftp CCC method '%s', using default", str); return CURLFTPSSL_CCC_PASSIVE; } -long delegation(struct OperationConfig *config, const char *str) +long delegation(const char *str) { if(curl_strequal("none", str)) return CURLGSSAPI_DELEGATION_NONE; @@ -657,8 +654,7 @@ long delegation(struct OperationConfig *config, const char *str) if(curl_strequal("always", str)) return CURLGSSAPI_DELEGATION_FLAG; - warnf(config->global, "unrecognized delegation method '%s', using none", - str); + warnf("unrecognized delegation method '%s', using none", str); return CURLGSSAPI_DELEGATION_NONE; } @@ -722,7 +718,7 @@ CURLcode get_args(struct OperationConfig *config, const size_t i) if(!result && !config->useragent) { config->useragent = my_useragent(); if(!config->useragent) { - errorf(config->global, "out of memory"); + errorf("out of memory"); result = CURLE_OUT_OF_MEMORY; } } diff --git a/src/tool_paramhlp.h b/src/tool_paramhlp.h index 16d431152..a9e8539cf 100644 --- a/src/tool_paramhlp.h +++ b/src/tool_paramhlp.h @@ -45,24 +45,15 @@ ParameterError str2unum(long *val, const char *str); ParameterError oct2nummax(long *val, const char *str, long max); ParameterError str2unummax(long *val, const char *str, long max); ParameterError secs2ms(long *val, const char *str); - -ParameterError proto2num(struct OperationConfig *config, - const char * const *val, char **obuf, +ParameterError proto2num(const char * const *val, char **obuf, const char *str); - ParameterError check_protocol(const char *str); - ParameterError str2offset(curl_off_t *val, const char *str); - CURLcode get_args(struct OperationConfig *config, const size_t i); - ParameterError add2list(struct curl_slist **list, const char *ptr); - -long ftpfilemethod(struct OperationConfig *config, const char *str); - -long ftpcccmethod(struct OperationConfig *config, const char *str); - -long delegation(struct OperationConfig *config, const char *str); +long ftpfilemethod(const char *str); +long ftpcccmethod(const char *str); +long delegation(const char *str); ParameterError str2tls_max(unsigned char *val, const char *str); diff --git a/src/tool_parsecfg.c b/src/tool_parsecfg.c index 0c70bdba5..d5303e679 100644 --- a/src/tool_parsecfg.c +++ b/src/tool_parsecfg.c @@ -41,7 +41,7 @@ static const char *unslashquote(const char *line, char *param); #define MAX_CONFIG_LINE_LENGTH (10*1024*1024) /* return 0 on everything-is-fine, and non-zero otherwise */ -int parseconfig(const char *filename, struct GlobalConfig *global) +int parseconfig(const char *filename) { FILE *file = NULL; bool usedarg = FALSE; @@ -156,9 +156,9 @@ int parseconfig(const char *filename, struct GlobalConfig *global) case '#': /* comment */ break; default: - warnf(config->global, "%s:%d: warning: '%s' uses unquoted " + warnf("%s:%d: warning: '%s' uses unquoted " "whitespace", filename, lineno, option); - warnf(config->global, "This may cause side-effects. " + warnf("This may cause side-effects. " "Consider using double quotes?"); } } @@ -181,7 +181,7 @@ int parseconfig(const char *filename, struct GlobalConfig *global) if(res == PARAM_NEXT_OPERATION) { if(config->url_list && config->url_list->url) { /* Allocate the next config */ - config->next = config_alloc(global); + config->next = config_alloc(); if(config->next) { /* Update the last operation pointer */ global->last = config->next; @@ -206,7 +206,7 @@ int parseconfig(const char *filename, struct GlobalConfig *global) res != PARAM_ENGINES_REQUESTED && res != PARAM_CA_EMBED_REQUESTED) { const char *reason = param2text(res); - errorf(config->global, "%s:%d: '%s' %s", + errorf("%s:%d: '%s' %s", filename, lineno, option, reason); rc = (int)res; } diff --git a/src/tool_parsecfg.h b/src/tool_parsecfg.h index 0116d6a68..46977d8ed 100644 --- a/src/tool_parsecfg.h +++ b/src/tool_parsecfg.h @@ -25,8 +25,7 @@ ***************************************************************************/ #include "tool_setup.h" -int parseconfig(const char *filename, struct GlobalConfig *global); - +int parseconfig(const char *filename); bool my_get_line(FILE *fp, struct dynbuf *db, bool *error); #endif /* HEADER_CURL_TOOL_PARSECFG_H */ diff --git a/src/tool_progress.c b/src/tool_progress.c index a477dbac2..666fe9869 100644 --- a/src/tool_progress.c +++ b/src/tool_progress.c @@ -148,8 +148,7 @@ static struct speedcount speedstore[SPEEDCNT]; |DL% UL% Dled Uled Xfers Live Total Current Left Speed | 6 -- 9.9G 0 2 2 0:00:40 0:00:02 0:00:37 4087M */ -bool progress_meter(struct GlobalConfig *global, - CURLM *multi, +bool progress_meter(CURLM *multi, struct curltime *start, bool final) { diff --git a/src/tool_progress.h b/src/tool_progress.h index d9009504a..41b36ca02 100644 --- a/src/tool_progress.h +++ b/src/tool_progress.h @@ -31,8 +31,7 @@ int xferinfo_cb(void *clientp, curl_off_t ultotal, curl_off_t ulnow); -bool progress_meter(struct GlobalConfig *global, - CURLM *multi, +bool progress_meter(CURLM *multi, struct curltime *start, bool final); void progress_finalize(struct per_transfer *per); diff --git a/src/tool_setopt.c b/src/tool_setopt.c index 5c905c86f..b1b3f0a8b 100644 --- a/src/tool_setopt.c +++ b/src/tool_setopt.c @@ -231,8 +231,7 @@ static char *c_escape(const char *str, curl_off_t len) } /* setopt wrapper for enum types */ -CURLcode tool_setopt_enum(CURL *curl, struct OperationConfig *config, - const char *name, CURLoption tag, +CURLcode tool_setopt_enum(CURL *curl, const char *name, CURLoption tag, const struct NameValue *nvlist, long lval) { CURLcode ret = CURLE_OK; @@ -242,7 +241,7 @@ CURLcode tool_setopt_enum(CURL *curl, struct OperationConfig *config, if(!lval) skip = TRUE; - if(config->global->libcurl && !skip && !ret) { + if(global->libcurl && !skip && !ret) { /* we only use this for real if --libcurl was used */ const struct NameValue *nv = NULL; for(nv = nvlist; nv->name; nv++) { @@ -264,14 +263,13 @@ CURLcode tool_setopt_enum(CURL *curl, struct OperationConfig *config, #ifdef DEBUGBUILD if(ret) - warnf(config->global, "option %s returned error (%d)", name, (int)ret); + warnf("option %s returned error (%d)", name, (int)ret); #endif return ret; } /* setopt wrapper for CURLOPT_SSLVERSION */ -CURLcode tool_setopt_SSLVERSION(CURL *curl, struct OperationConfig *config, - const char *name, CURLoption tag, +CURLcode tool_setopt_SSLVERSION(CURL *curl, const char *name, CURLoption tag, long lval) { CURLcode ret = CURLE_OK; @@ -281,7 +279,7 @@ CURLcode tool_setopt_SSLVERSION(CURL *curl, struct OperationConfig *config, if(!lval) skip = TRUE; - if(config->global->libcurl && !skip && !ret) { + if(global->libcurl && !skip && !ret) { /* we only use this for real if --libcurl was used */ const struct NameValue *nv = NULL; const struct NameValue *nv2 = NULL; @@ -316,14 +314,13 @@ CURLcode tool_setopt_SSLVERSION(CURL *curl, struct OperationConfig *config, #ifdef DEBUGBUILD if(ret) - warnf(config->global, "option %s returned error (%d)", name, (int)ret); + warnf("option %s returned error (%d)", name, (int)ret); #endif return ret; } /* setopt wrapper for bitmasks */ -CURLcode tool_setopt_bitmask(CURL *curl, struct OperationConfig *config, - const char *name, CURLoption tag, +CURLcode tool_setopt_bitmask(CURL *curl, const char *name, CURLoption tag, const struct NameValueUnsigned *nvlist, long lval) { @@ -332,7 +329,7 @@ CURLcode tool_setopt_bitmask(CURL *curl, struct OperationConfig *config, if(!lval) skip = TRUE; - if(config->global->libcurl && !skip && !ret) { + if(global->libcurl && !skip && !ret) { /* we only use this for real if --libcurl was used */ char preamble[80]; unsigned long rest = (unsigned long)lval; @@ -558,7 +555,7 @@ CURLcode tool_setopt_mimepost(CURL *curl, struct OperationConfig *config, CURLcode ret = curl_easy_setopt(curl, tag, mimepost); int mimeno = 0; - if(!ret && config->global->libcurl) { + if(!ret && global->libcurl) { ret = libcurl_generate_mime(curl, config, config->mimeroot, &mimeno); if(!ret) @@ -570,15 +567,14 @@ CURLcode tool_setopt_mimepost(CURL *curl, struct OperationConfig *config, } /* setopt wrapper for curl_slist options */ -CURLcode tool_setopt_slist(CURL *curl, struct OperationConfig *config, - const char *name, CURLoption tag, +CURLcode tool_setopt_slist(CURL *curl, const char *name, CURLoption tag, struct curl_slist *list) { CURLcode ret = CURLE_OK; ret = curl_easy_setopt(curl, tag, list); - if(config->global->libcurl && list && !ret) { + if(global->libcurl && list && !ret) { int i; ret = libcurl_generate_slist(list, &i); @@ -591,8 +587,7 @@ CURLcode tool_setopt_slist(CURL *curl, struct OperationConfig *config, } /* options that set long */ -CURLcode tool_setopt_long(CURL *curl, struct OperationConfig *config, - const char *name, CURLoption tag, +CURLcode tool_setopt_long(CURL *curl, const char *name, CURLoption tag, long lval) { long defval = 0L; @@ -608,7 +603,7 @@ CURLcode tool_setopt_long(CURL *curl, struct OperationConfig *config, } ret = curl_easy_setopt(curl, tag, lval); - if((lval != defval) && config->global->libcurl && !ret) { + if((lval != defval) && global->libcurl && !ret) { /* we only use this for real if --libcurl was used */ ret = easysrc_addf(&easysrc_code, "curl_easy_setopt(hnd, %s, %ldL);", name, lval); @@ -617,15 +612,14 @@ CURLcode tool_setopt_long(CURL *curl, struct OperationConfig *config, } /* options that set curl_off_t */ -CURLcode tool_setopt_offt(CURL *curl, struct OperationConfig *config, - const char *name, CURLoption tag, +CURLcode tool_setopt_offt(CURL *curl, const char *name, CURLoption tag, curl_off_t lval) { CURLcode ret = CURLE_OK; DEBUGASSERT((tag >= CURLOPTTYPE_OFF_T) && (tag < CURLOPTTYPE_BLOB)); ret = curl_easy_setopt(curl, tag, lval); - if(config->global->libcurl && !ret && lval) { + if(global->libcurl && !ret && lval) { /* we only use this for real if --libcurl was used */ ret = easysrc_addf(&easysrc_code, "curl_easy_setopt(hnd, %s, (curl_off_t)%" CURL_FORMAT_CURL_OFF_T ");", name, lval); @@ -635,8 +629,9 @@ CURLcode tool_setopt_offt(CURL *curl, struct OperationConfig *config, } /* setopt wrapper for setting object and function pointer options */ -CURLcode tool_setopt(CURL *curl, bool str, struct OperationConfig *config, - const char *name, CURLoption tag, ...) +CURLcode tool_setopt(CURL *curl, struct OperationConfig *config, + bool str, const char *name, CURLoption tag, + ...) { va_list arg; CURLcode ret = CURLE_OK; @@ -657,7 +652,7 @@ CURLcode tool_setopt(CURL *curl, bool str, struct OperationConfig *config, va_end(arg); - if(config->global->libcurl && pval && !ret) { + if(global->libcurl && pval && !ret) { /* we only use this if --libcurl was used */ if(!str) { diff --git a/src/tool_setopt.h b/src/tool_setopt.h index 2d179fa99..4f28df980 100644 --- a/src/tool_setopt.h +++ b/src/tool_setopt.h @@ -76,60 +76,55 @@ extern const struct NameValueUnsigned setopt_nv_CURLHSTS[]; /* Intercept setopt calls for --libcurl */ -CURLcode tool_setopt_enum(CURL *curl, struct OperationConfig *config, - const char *name, CURLoption tag, +CURLcode tool_setopt_enum(CURL *curl, const char *name, CURLoption tag, const struct NameValue *nv, long lval); -CURLcode tool_setopt_SSLVERSION(CURL *curl, struct OperationConfig *config, - const char *name, CURLoption tag, +CURLcode tool_setopt_SSLVERSION(CURL *curl, const char *name, CURLoption tag, long lval); CURLcode tool_setopt_flags(CURL *curl, struct OperationConfig *config, const char *name, CURLoption tag, const struct NameValue *nv, long lval); -CURLcode tool_setopt_bitmask(CURL *curl, struct OperationConfig *config, +CURLcode tool_setopt_bitmask(CURL *curl, const char *name, CURLoption tag, const struct NameValueUnsigned *nv, long lval); CURLcode tool_setopt_mimepost(CURL *curl, struct OperationConfig *config, const char *name, CURLoption tag, curl_mime *mimepost); -CURLcode tool_setopt_slist(CURL *curl, struct OperationConfig *config, - const char *name, CURLoption tag, +CURLcode tool_setopt_slist(CURL *curl, const char *name, CURLoption tag, struct curl_slist *list); -CURLcode tool_setopt_long(CURL *curl, struct OperationConfig *config, - const char *name, CURLoption tag, +CURLcode tool_setopt_long(CURL *curl, const char *name, CURLoption tag, long lval); -CURLcode tool_setopt_offt(CURL *curl, struct OperationConfig *config, - const char *name, CURLoption tag, +CURLcode tool_setopt_offt(CURL *curl, const char *name, CURLoption tag, curl_off_t lval); -CURLcode tool_setopt(CURL *curl, bool str, - struct OperationConfig *config, - const char *name, CURLoption tag, ...); +CURLcode tool_setopt(CURL *curl, struct OperationConfig *config, + bool str, const char *name, CURLoption tag, + ...); #define my_setopt(x,y,z) \ - tool_setopt(x, FALSE, config, #y, y, z) + tool_setopt(x, config, FALSE, #y, y, z) #define my_setopt_long(x,y,z) \ - tool_setopt_long(x, config, #y, y, z) + tool_setopt_long(x, #y, y, z) #define my_setopt_offt(x,y,z) \ - tool_setopt_offt(x, config, #y, y, z) + tool_setopt_offt(x, #y, y, z) #define my_setopt_str(x,y,z) \ - tool_setopt(x, TRUE, config, #y, y, z) + tool_setopt(x, config, TRUE, #y, y, z) #define my_setopt_enum(x,y,z) \ - tool_setopt_enum(x, config, #y, y, setopt_nv_ ## y, z) + tool_setopt_enum(x, #y, y, setopt_nv_ ## y, z) #define my_setopt_SSLVERSION(x,y,z) \ - tool_setopt_SSLVERSION(x, config, #y, y, z) + tool_setopt_SSLVERSION(x, #y, y, z) #define my_setopt_bitmask(x,y,z) \ - tool_setopt_bitmask(x, config, #y, y, setopt_nv_ ## y, z) + tool_setopt_bitmask(x, #y, y, setopt_nv_ ## y, z) #define my_setopt_mimepost(x,y,z) \ tool_setopt_mimepost(x, config, #y, y, z) #define my_setopt_slist(x,y,z) \ - tool_setopt_slist(x, config, #y, y, z) + tool_setopt_slist(x, #y, y, z) #else /* CURL_DISABLE_LIBCURL_OPTION */ diff --git a/src/tool_ssls.c b/src/tool_ssls.c index 516a7d3c9..edf8d6095 100644 --- a/src/tool_ssls.c +++ b/src/tool_ssls.c @@ -38,7 +38,6 @@ static CURLcode tool_ssls_easy(struct OperationConfig *config, CURLSH *share, CURL **peasy) { CURLcode result = CURLE_OK; - struct GlobalConfig *global = config->global; *peasy = curl_easy_init(); if(!*peasy) @@ -65,12 +64,11 @@ CURLcode tool_ssls_load(struct OperationConfig *config, CURLcode r = CURLE_OK; int i, imported; bool error = FALSE; - struct GlobalConfig *global = config->global; curlx_dyn_init(&buf, MAX_SSLS_LINE); fp = fopen(filename, FOPEN_READTEXT); if(!fp) { /* ok if it does not exist */ - notef(global, "SSL session file does not exist (yet?): %s", filename); + notef("SSL session file does not exist (yet?): %s", filename); goto out; } @@ -87,14 +85,13 @@ CURLcode tool_ssls_load(struct OperationConfig *config, c = memchr(line, ':', strlen(line)); if(!c) { - warnf(global, "unrecognized line %d in ssl session file %s", - i, filename); + warnf("unrecognized line %d in ssl session file %s", i, filename); continue; } *c = '\0'; r = curlx_base64_decode(line, &shmac, &shmac_len); if(r) { - warnf(global, "invalid shmax base64 encoding in line %d", i); + warnf("invalid shmax base64 encoding in line %d", i); continue; } line = c + 1; @@ -105,13 +102,13 @@ CURLcode tool_ssls_load(struct OperationConfig *config, } r = curlx_base64_decode(line, &sdata, &sdata_len); if(r) { - warnf(global, "invalid sdata base64 encoding in line %d: %s", i, line); + warnf("invalid sdata base64 encoding in line %d: %s", i, line); continue; } r = curl_easy_ssls_import(easy, NULL, shmac, shmac_len, sdata, sdata_len); if(r) { - warnf(global, "import of session from line %d rejected(%d)", i, r); + warnf("import of session from line %d rejected(%d)", i, r); continue; } ++imported; @@ -133,7 +130,6 @@ out: } struct tool_ssls_ctx { - struct GlobalConfig *global; FILE *fp; int exported; }; @@ -181,8 +177,7 @@ static CURLcode tool_ssls_exp(CURL *easy, void *userptr, ctx->exported++; out: if(r) - warnf(ctx->global, "Warning: error saving SSL session for '%s': %d", - session_key, r); + warnf("Warning: error saving SSL session for '%s': %d", session_key, r); curl_free(enc); return r; } @@ -194,11 +189,10 @@ CURLcode tool_ssls_save(struct OperationConfig *config, CURL *easy = NULL; CURLcode r = CURLE_OK; - ctx.global = config->global; ctx.exported = 0; ctx.fp = fopen(filename, FOPEN_WRITETEXT); if(!ctx.fp) { - warnf(config->global, "Warning: Failed to create SSL session file %s", + warnf("Warning: Failed to create SSL session file %s", filename); goto out; } diff --git a/src/tool_stderr.c b/src/tool_stderr.c index 602da613a..b023d6c80 100644 --- a/src/tool_stderr.c +++ b/src/tool_stderr.c @@ -36,7 +36,7 @@ void tool_init_stderr(void) tool_stderr = stderr; } -void tool_set_stderr_file(struct GlobalConfig *global, const char *filename) +void tool_set_stderr_file(const char *filename) { FILE *fp; @@ -52,7 +52,7 @@ void tool_set_stderr_file(struct GlobalConfig *global, const char *filename) subsequent freopen will fail. */ fp = fopen(filename, FOPEN_WRITETEXT); if(!fp) { - warnf(global, "Warning: Failed to open %s", filename); + warnf("Warning: Failed to open %s", filename); return; } fclose(fp); diff --git a/src/tool_stderr.h b/src/tool_stderr.h index 8edc8ab65..94c508579 100644 --- a/src/tool_stderr.h +++ b/src/tool_stderr.h @@ -27,6 +27,6 @@ #include "tool_cfgable.h" void tool_init_stderr(void); -void tool_set_stderr_file(struct GlobalConfig *global, const char *filename); +void tool_set_stderr_file(const char *filename); #endif /* HEADER_CURL_TOOL_STDERR_H */ diff --git a/src/tool_urlglob.c b/src/tool_urlglob.c index d79aa2990..63d3a7c72 100644 --- a/src/tool_urlglob.c +++ b/src/tool_urlglob.c @@ -30,25 +30,30 @@ #include "tool_strdup.h" #include "memdebug.h" /* keep this as LAST include */ -#define GLOBERROR(string, column, code) \ - glob->error = string, glob->pos = column, code +static CURLcode globerror(struct URLGlob *glob, const char *err, + size_t pos, CURLcode error) +{ + glob->error = err; + glob->pos = pos; + return error; +} static CURLcode glob_fixed(struct URLGlob *glob, char *fixed, size_t len) { struct URLPattern *pat = &glob->pattern[glob->size]; - pat->type = UPTSet; - pat->content.Set.size = 1; - pat->content.Set.ptr_s = 0; + pat->type = GLOB_SET; + pat->c.set.size = 1; + pat->c.set.idx = 0; pat->globindex = -1; - pat->content.Set.elements = malloc(sizeof(char *)); + pat->c.set.elem = malloc(sizeof(char *)); - if(!pat->content.Set.elements) - return GLOBERROR("out of memory", 0, CURLE_OUT_OF_MEMORY); + if(!pat->c.set.elem) + return globerror(glob, NULL, 0, CURLE_OUT_OF_MEMORY); - pat->content.Set.elements[0] = memdup0(fixed, len); - if(!pat->content.Set.elements[0]) - return GLOBERROR("out of memory", 0, CURLE_OUT_OF_MEMORY); + pat->c.set.elem[0] = memdup0(fixed, len); + if(!pat->c.set.elem[0]) + return globerror(glob, NULL, 0, CURLE_OUT_OF_MEMORY); return CURLE_OK; } @@ -90,61 +95,58 @@ static CURLcode glob_set(struct URLGlob *glob, const char **patternp, */ struct URLPattern *pat; bool done = FALSE; - char *buf = glob->glob_buffer; const char *pattern = *patternp; const char *opattern = pattern; size_t opos = *posp-1; pat = &glob->pattern[glob->size]; /* patterns 0,1,2,... correspond to size=1,3,5,... */ - pat->type = UPTSet; - pat->content.Set.size = 0; - pat->content.Set.ptr_s = 0; - pat->content.Set.elements = NULL; + pat->type = GLOB_SET; + pat->c.set.size = 0; + pat->c.set.idx = 0; + pat->c.set.elem = NULL; pat->globindex = globindex; while(!done) { switch(*pattern) { case '\0': /* URL ended while set was still open */ - return GLOBERROR("unmatched brace", opos, CURLE_URL_MALFORMAT); + return globerror(glob, "unmatched brace", opos, CURLE_URL_MALFORMAT); case '{': case '[': /* no nested expressions at this time */ - return GLOBERROR("nested brace", *posp, CURLE_URL_MALFORMAT); + return globerror(glob, "nested brace", *posp, CURLE_URL_MALFORMAT); case '}': /* set element completed */ if(opattern == pattern) - return GLOBERROR("empty string within braces", *posp, + return globerror(glob, "empty string within braces", *posp, CURLE_URL_MALFORMAT); /* add 1 to size since it will be incremented below */ - if(multiply(amount, pat->content.Set.size + 1)) - return GLOBERROR("range overflow", 0, CURLE_URL_MALFORMAT); + if(multiply(amount, pat->c.set.size + 1)) + return globerror(glob, "range overflow", 0, CURLE_URL_MALFORMAT); FALLTHROUGH(); case ',': - - *buf = '\0'; - if(pat->content.Set.elements) { - char **new_arr = realloc(pat->content.Set.elements, - (size_t)(pat->content.Set.size + 1) * + if(pat->c.set.elem) { + char **new_arr = realloc(pat->c.set.elem, + (size_t)(pat->c.set.size + 1) * sizeof(char *)); if(!new_arr) - return GLOBERROR("out of memory", 0, CURLE_OUT_OF_MEMORY); + return globerror(glob, NULL, 0, CURLE_OUT_OF_MEMORY); - pat->content.Set.elements = new_arr; + pat->c.set.elem = new_arr; } else - pat->content.Set.elements = malloc(sizeof(char *)); + pat->c.set.elem = malloc(sizeof(char *)); - if(!pat->content.Set.elements) - return GLOBERROR("out of memory", 0, CURLE_OUT_OF_MEMORY); + if(!pat->c.set.elem) + return globerror(glob, NULL, 0, CURLE_OUT_OF_MEMORY); - pat->content.Set.elements[pat->content.Set.size] = - strdup(glob->glob_buffer); - if(!pat->content.Set.elements[pat->content.Set.size]) - return GLOBERROR("out of memory", 0, CURLE_OUT_OF_MEMORY); - ++pat->content.Set.size; + pat->c.set.elem[pat->c.set.size] = strdup(curlx_dyn_ptr(&glob->buf)); + if(!pat->c.set.elem[pat->c.set.size]) + return globerror(glob, NULL, 0, CURLE_OUT_OF_MEMORY); + ++pat->c.set.size; + curlx_dyn_reset(&glob->buf); if(*pattern == '}') { pattern++; /* pass the closing brace */ @@ -152,13 +154,13 @@ static CURLcode glob_set(struct URLGlob *glob, const char **patternp, continue; } - buf = glob->glob_buffer; ++pattern; ++(*posp); break; case ']': /* illegal closing bracket */ - return GLOBERROR("unexpected close bracket", *posp, CURLE_URL_MALFORMAT); + return globerror(glob, "unexpected close bracket", *posp, + CURLE_URL_MALFORMAT); case '\\': /* escaped character, skip '\' */ if(pattern[1]) { @@ -167,7 +169,9 @@ static CURLcode glob_set(struct URLGlob *glob, const char **patternp, } FALLTHROUGH(); default: - *buf++ = *pattern++; /* copy character to set element */ + /* copy character to set element */ + if(curlx_dyn_addn(&glob->buf, pattern++, 1)) + return CURLE_OUT_OF_MEMORY; ++(*posp); } } @@ -199,9 +203,9 @@ static CURLcode glob_range(struct URLGlob *glob, const char **patternp, char min_c = 0; char max_c = 0; char end_c = 0; - unsigned long step = 1; + unsigned char step = 1; - pat->type = UPTCharRange; + pat->type = GLOB_ASCII; if((pattern[1] == '-') && pattern[2] && pattern[3]) { min_c = pattern[0]; @@ -215,7 +219,7 @@ static CURLcode glob_range(struct URLGlob *glob, const char **patternp, if(curlx_str_number(&p, &num, 256) || curlx_str_single(&p, ']')) step = 0; else - step = (unsigned long)num; + step = (unsigned char)num; pattern = p; } else if(end_c != ']') @@ -233,50 +237,49 @@ static CURLcode glob_range(struct URLGlob *glob, const char **patternp, (min_c != max_c && (min_c > max_c || step > (unsigned)(max_c - min_c) || (max_c - min_c) > ('z' - 'a')))) /* the pattern is not well-formed */ - return GLOBERROR("bad range", *posp, CURLE_URL_MALFORMAT); + return globerror(glob, "bad range", *posp, CURLE_URL_MALFORMAT); /* if there was a ":[num]" thing, use that as step or else use 1 */ - pat->content.CharRange.step = (int)step; - pat->content.CharRange.ptr_c = pat->content.CharRange.min_c = min_c; - pat->content.CharRange.max_c = max_c; - - if(multiply(amount, ((pat->content.CharRange.max_c - - pat->content.CharRange.min_c) / - pat->content.CharRange.step + 1))) - return GLOBERROR("range overflow", *posp, CURLE_URL_MALFORMAT); + pat->c.ascii.step = step; + pat->c.ascii.letter = pat->c.ascii.min = min_c; + pat->c.ascii.max = max_c; + + if(multiply(amount, ((pat->c.ascii.max - pat->c.ascii.min) / + pat->c.ascii.step + 1))) + return globerror(glob, "range overflow", *posp, CURLE_URL_MALFORMAT); } else if(ISDIGIT(*pattern)) { /* numeric range detected */ - unsigned long min_n = 0; - unsigned long max_n = 0; - unsigned long step_n = 0; + curl_off_t min_n = 0; + curl_off_t max_n = 0; + curl_off_t step_n = 0; curl_off_t num; - pat->type = UPTNumRange; - pat->content.NumRange.padlength = 0; + pat->type = GLOB_NUM; + pat->c.num.npad = 0; if(*pattern == '0') { /* leading zero specified, count them! */ c = pattern; while(ISDIGIT(*c)) { c++; - ++pat->content.NumRange.padlength; /* padding length is set for all - instances of this pattern */ + ++pat->c.num.npad; /* padding length is set for all instances of this + pattern */ } } if(!curlx_str_number(&pattern, &num, CURL_OFF_T_MAX)) { - min_n = (unsigned long)num; + min_n = num; if(!curlx_str_single(&pattern, '-')) { curlx_str_passblanks(&pattern); if(!curlx_str_number(&pattern, &num, CURL_OFF_T_MAX)) { - max_n = (unsigned long)num; + max_n = num; if(!curlx_str_single(&pattern, ']')) step_n = 1; else if(!curlx_str_single(&pattern, ':') && !curlx_str_number(&pattern, &num, CURL_OFF_T_MAX) && !curlx_str_single(&pattern, ']')) { - step_n = (unsigned long)num; + step_n = num; } /* else bad syntax */ } @@ -289,21 +292,21 @@ static CURLcode glob_range(struct URLGlob *glob, const char **patternp, (min_n == max_n && step_n != 1) || (min_n != max_n && (min_n > max_n || step_n > (max_n - min_n)))) /* the pattern is not well-formed */ - return GLOBERROR("bad range", *posp, CURLE_URL_MALFORMAT); + return globerror(glob, "bad range", *posp, CURLE_URL_MALFORMAT); /* typecasting to ints are fine here since we make sure above that we are within 31 bits */ - pat->content.NumRange.ptr_n = pat->content.NumRange.min_n = min_n; - pat->content.NumRange.max_n = max_n; - pat->content.NumRange.step = step_n; - - if(multiply(amount, ((pat->content.NumRange.max_n - - pat->content.NumRange.min_n) / - pat->content.NumRange.step + 1))) - return GLOBERROR("range overflow", *posp, CURLE_URL_MALFORMAT); + pat->c.num.idx = pat->c.num.min = min_n; + pat->c.num.max = max_n; + pat->c.num.step = step_n; + + if(multiply(amount, ((pat->c.num.max - pat->c.num.min) / + pat->c.num.step + 1))) + return globerror(glob, "range overflow", *posp, CURLE_URL_MALFORMAT); } else - return GLOBERROR("bad range specification", *posp, CURLE_URL_MALFORMAT); + return globerror(glob, "bad range specification", *posp, + CURLE_URL_MALFORMAT); *patternp = pattern; return CURLE_OK; @@ -358,8 +361,6 @@ static CURLcode glob_parse(struct URLGlob *glob, const char *pattern, *amount = 1; while(*pattern && !res) { - char *buf = glob->glob_buffer; - size_t sublen = 0; while(*pattern && *pattern != '{') { if(*pattern == '[') { /* skip over IPv6 literals and [] */ @@ -367,16 +368,15 @@ static CURLcode glob_parse(struct URLGlob *glob, const char *pattern, if(!peek_ipv6(pattern, &skip) && (pattern[1] == ']')) skip = 2; if(skip) { - memcpy(buf, pattern, skip); - buf += skip; + if(curlx_dyn_addn(&glob->buf, pattern, skip)) + return CURLE_OUT_OF_MEMORY; pattern += skip; - sublen += skip; continue; } break; } if(*pattern == '}' || *pattern == ']') - return GLOBERROR("unmatched close brace/bracket", pos, + return globerror(glob, "unmatched close brace/bracket", pos, CURLE_URL_MALFORMAT); /* only allow \ to escape known "special letters" */ @@ -388,14 +388,16 @@ static CURLcode glob_parse(struct URLGlob *glob, const char *pattern, ++pattern; ++pos; } - *buf++ = *pattern++; /* copy character to literal */ + /* copy character to literal */ + if(curlx_dyn_addn(&glob->buf, pattern++, 1)) + return CURLE_OUT_OF_MEMORY; ++pos; - sublen++; } - if(sublen) { + if(curlx_dyn_len(&glob->buf)) { /* we got a literal string, add it as a single-item list */ - *buf = '\0'; - res = glob_fixed(glob, glob->glob_buffer, sublen); + res = glob_fixed(glob, curlx_dyn_ptr(&glob->buf), + curlx_dyn_len(&glob->buf)); + curlx_dyn_reset(&glob->buf); } else { switch(*pattern) { @@ -418,102 +420,96 @@ static CURLcode glob_parse(struct URLGlob *glob, const char *pattern, } } - if(++glob->size >= GLOB_PATTERN_NUM) - return GLOBERROR("too many globs", pos, CURLE_URL_MALFORMAT); + if(++glob->size >= glob->palloc) { + struct URLPattern *np = NULL; + glob->palloc *= 2; + if(glob->size < 10000) /* avoid ridiculous amounts */ + np = realloc(glob->pattern, glob->palloc * sizeof(struct URLPattern)); + if(!np) + return globerror(glob, NULL, pos, CURLE_OUT_OF_MEMORY); + glob->pattern = np; + } } return res; } -CURLcode glob_url(struct URLGlob **glob, char *url, curl_off_t *urlnum, +bool glob_inuse(struct URLGlob *glob) +{ + return glob->palloc ? TRUE : FALSE; +} + +CURLcode glob_url(struct URLGlob *glob, char *url, curl_off_t *urlnum, FILE *error) { /* * We can deal with any-size, just make a buffer with the same length * as the specified URL! */ - struct URLGlob *glob_expand; curl_off_t amount = 0; - char *glob_buffer; CURLcode res; - *glob = NULL; - - glob_buffer = malloc(strlen(url) + 1); - if(!glob_buffer) - return CURLE_OUT_OF_MEMORY; - glob_buffer[0] = 0; - - glob_expand = calloc(1, sizeof(struct URLGlob)); - if(!glob_expand) { - tool_safefree(glob_buffer); + memset(glob, 0, sizeof(struct URLGlob)); + curlx_dyn_init(&glob->buf, 1024*1024); + glob->pattern = malloc(2 * sizeof(struct URLPattern)); + if(!glob->pattern) return CURLE_OUT_OF_MEMORY; - } - glob_expand->urllen = strlen(url); - glob_expand->glob_buffer = glob_buffer; + glob->palloc = 2; - res = glob_parse(glob_expand, url, 1, &amount); + res = glob_parse(glob, url, 1, &amount); if(!res) *urlnum = amount; else { - if(error && glob_expand->error) { + if(error && glob->error) { char text[512]; const char *t; - if(glob_expand->pos) { + if(glob->pos) { msnprintf(text, sizeof(text), "%s in URL position %zu:\n%s\n%*s^", - glob_expand->error, - glob_expand->pos, url, (int)glob_expand->pos - 1, " "); + glob->error, + glob->pos, url, (int)glob->pos - 1, " "); t = text; } else - t = glob_expand->error; + t = glob->error; /* send error description to the error-stream */ fprintf(error, "curl: (%d) %s\n", res, t); } /* it failed, we cleanup */ - glob_cleanup(&glob_expand); + glob_cleanup(glob); *urlnum = 1; return res; } - *glob = glob_expand; return CURLE_OK; } -void glob_cleanup(struct URLGlob **globp) +void glob_cleanup(struct URLGlob *glob) { size_t i; curl_off_t elem; - struct URLGlob *glob = *globp; - - if(!glob) - return; - - for(i = 0; i < glob->size; i++) { - if((glob->pattern[i].type == UPTSet) && - (glob->pattern[i].content.Set.elements)) { - for(elem = glob->pattern[i].content.Set.size - 1; - elem >= 0; - --elem) { - tool_safefree(glob->pattern[i].content.Set.elements[elem]); + + if(glob->pattern) { + for(i = 0; i < glob->size; i++) { + if((glob->pattern[i].type == GLOB_SET) && + (glob->pattern[i].c.set.elem)) { + for(elem = glob->pattern[i].c.set.size - 1; elem >= 0; --elem) + tool_safefree(glob->pattern[i].c.set.elem[elem]); + tool_safefree(glob->pattern[i].c.set.elem); } - tool_safefree(glob->pattern[i].content.Set.elements); } + tool_safefree(glob->pattern); + glob->palloc = 0; + curlx_dyn_free(&glob->buf); } - tool_safefree(glob->glob_buffer); - tool_safefree(glob); - *globp = NULL; } CURLcode glob_next_url(char **globbed, struct URLGlob *glob) { struct URLPattern *pat; size_t i; - size_t len; - size_t buflen = glob->urllen + 1; - char *buf = glob->glob_buffer; *globbed = NULL; + curlx_dyn_reset(&glob->buf); if(!glob->beenhere) glob->beenhere = 1; @@ -526,31 +522,28 @@ CURLcode glob_next_url(char **globbed, struct URLGlob *glob) carry = FALSE; pat = &glob->pattern[glob->size - 1 - i]; switch(pat->type) { - case UPTSet: - if((pat->content.Set.elements) && - (++pat->content.Set.ptr_s == pat->content.Set.size)) { - pat->content.Set.ptr_s = 0; + case GLOB_SET: + if((pat->c.set.elem) && (++pat->c.set.idx == pat->c.set.size)) { + pat->c.set.idx = 0; carry = TRUE; } break; - case UPTCharRange: - pat->content.CharRange.ptr_c = - (char)(pat->content.CharRange.step + - (int)((unsigned char)pat->content.CharRange.ptr_c)); - if(pat->content.CharRange.ptr_c > pat->content.CharRange.max_c) { - pat->content.CharRange.ptr_c = pat->content.CharRange.min_c; + case GLOB_ASCII: + pat->c.ascii.letter += pat->c.ascii.step; + if(pat->c.ascii.letter > pat->c.ascii.max) { + pat->c.ascii.letter = pat->c.ascii.min; carry = TRUE; } break; - case UPTNumRange: - pat->content.NumRange.ptr_n += pat->content.NumRange.step; - if(pat->content.NumRange.ptr_n > pat->content.NumRange.max_n) { - pat->content.NumRange.ptr_n = pat->content.NumRange.min_n; + case GLOB_NUM: + pat->c.num.idx += pat->c.num.step; + if(pat->c.num.idx > pat->c.num.max) { + pat->c.num.idx = pat->c.num.min; carry = TRUE; } break; default: - printf("internal error: invalid pattern type (%d)\n", (int)pat->type); + DEBUGASSERT(0); return CURLE_FAILED_INIT; } } @@ -562,68 +555,55 @@ CURLcode glob_next_url(char **globbed, struct URLGlob *glob) for(i = 0; i < glob->size; ++i) { pat = &glob->pattern[i]; switch(pat->type) { - case UPTSet: - if(pat->content.Set.elements) { - msnprintf(buf, buflen, "%s", - pat->content.Set.elements[pat->content.Set.ptr_s]); - len = strlen(buf); - buf += len; - buflen -= len; + case GLOB_SET: + if(pat->c.set.elem) { + if(curlx_dyn_add(&glob->buf, pat->c.set.elem[pat->c.set.idx])) + return CURLE_OUT_OF_MEMORY; } break; - case UPTCharRange: - if(buflen) { - *buf++ = pat->content.CharRange.ptr_c; - *buf = '\0'; - buflen--; - } + case GLOB_ASCII: { + char letter = (char)pat->c.ascii.letter; + if(curlx_dyn_addn(&glob->buf, &letter, 1)) + return CURLE_OUT_OF_MEMORY; break; - case UPTNumRange: - msnprintf(buf, buflen, "%0*" CURL_FORMAT_CURL_OFF_T, - pat->content.NumRange.padlength, - pat->content.NumRange.ptr_n); - len = strlen(buf); - buf += len; - buflen -= len; + } + case GLOB_NUM: + if(curlx_dyn_addf(&glob->buf, "%0*" CURL_FORMAT_CURL_OFF_T, + pat->c.num.npad, pat->c.num.idx)) + return CURLE_OUT_OF_MEMORY; break; default: - printf("internal error: invalid pattern type (%d)\n", (int)pat->type); + DEBUGASSERT(0); return CURLE_FAILED_INIT; } } - *globbed = strdup(glob->glob_buffer); + *globbed = strdup(curlx_dyn_ptr(&glob->buf)); if(!*globbed) return CURLE_OUT_OF_MEMORY; return CURLE_OK; } -#define MAX_OUTPUT_GLOB_LENGTH (10*1024) +#define MAX_OUTPUT_GLOB_LENGTH (1024*1024) -CURLcode glob_match_url(char **result, const char *filename, +CURLcode glob_match_url(char **output, const char *filename, struct URLGlob *glob) { - char numbuf[18]; - const char *appendthis = ""; - size_t appendlen = 0; struct dynbuf dyn; + *output = NULL; - *result = NULL; - - /* We cannot use the glob_buffer for storage since the filename may be - * longer than the URL we use. - */ curlx_dyn_init(&dyn, MAX_OUTPUT_GLOB_LENGTH); while(*filename) { + CURLcode result = CURLE_OK; if(*filename == '#' && ISDIGIT(filename[1])) { const char *ptr = filename; curl_off_t num; struct URLPattern *pat = NULL; filename++; if(!curlx_str_number(&filename, &num, glob->size) && num) { - unsigned long i; + size_t i; num--; /* make it zero based */ /* find the correct glob entry */ for(i = 0; i < glob->size; i++) { @@ -636,46 +616,33 @@ CURLcode glob_match_url(char **result, const char *filename, if(pat) { switch(pat->type) { - case UPTSet: - if(pat->content.Set.elements) { - appendthis = pat->content.Set.elements[pat->content.Set.ptr_s]; - appendlen = - strlen(pat->content.Set.elements[pat->content.Set.ptr_s]); - } + case GLOB_SET: + if(pat->c.set.elem) + result = curlx_dyn_add(&dyn, pat->c.set.elem[pat->c.set.idx]); break; - case UPTCharRange: - numbuf[0] = pat->content.CharRange.ptr_c; - numbuf[1] = 0; - appendthis = numbuf; - appendlen = 1; + case GLOB_ASCII: { + char letter = (char)pat->c.ascii.letter; + result = curlx_dyn_addn(&dyn, &letter, 1); break; - case UPTNumRange: - msnprintf(numbuf, sizeof(numbuf), "%0*" CURL_FORMAT_CURL_OFF_T, - pat->content.NumRange.padlength, - pat->content.NumRange.ptr_n); - appendthis = numbuf; - appendlen = strlen(numbuf); + } + case GLOB_NUM: + result = curlx_dyn_addf(&dyn, "%0*" CURL_FORMAT_CURL_OFF_T, + pat->c.num.npad, pat->c.num.idx); break; default: - fprintf(tool_stderr, "internal error: invalid pattern type (%d)\n", - (int)pat->type); + DEBUGASSERT(0); curlx_dyn_free(&dyn); return CURLE_FAILED_INIT; } } - else { + else /* #[num] out of range, use the #[num] in the output */ - filename = ptr; - appendthis = filename++; - appendlen = 1; - } - } - else { - appendthis = filename++; - appendlen = 1; + result = curlx_dyn_addn(&dyn, ptr, filename - ptr); } - if(curlx_dyn_addn(&dyn, appendthis, appendlen)) - return CURLE_OUT_OF_MEMORY; + else + result = curlx_dyn_addn(&dyn, filename++, 1); + if(result) + return result; } if(curlx_dyn_addn(&dyn, "", 0)) @@ -690,11 +657,11 @@ CURLcode glob_match_url(char **result, const char *filename, curlx_dyn_free(&dyn); if(sc) return CURLE_URL_MALFORMAT; - *result = sanitized; + *output = sanitized; return CURLE_OK; } #else - *result = curlx_dyn_ptr(&dyn); + *output = curlx_dyn_ptr(&dyn); return CURLE_OK; #endif /* _WIN32 || MSDOS */ } diff --git a/src/tool_urlglob.h b/src/tool_urlglob.h index 6fcd0db49..4bcf229ec 100644 --- a/src/tool_urlglob.h +++ b/src/tool_urlglob.h @@ -26,53 +26,54 @@ #include "tool_setup.h" typedef enum { - UPTSet = 1, - UPTCharRange, - UPTNumRange -} URLPatternType; + GLOB_SET = 1, + GLOB_ASCII, + GLOB_NUM +} globtype; struct URLPattern { - URLPatternType type; + globtype type; int globindex; /* the number of this particular glob or -1 if not used within {} or [] */ union { struct { - char **elements; + char **elem; curl_off_t size; - int ptr_s; - } Set; + curl_off_t idx; + } set; struct { - char min_c; - char max_c; - char ptr_c; - int step; - } CharRange; + int min; + int max; + int letter; + unsigned char step; + } ascii; struct { - curl_off_t min_n; - curl_off_t max_n; - int padlength; - curl_off_t ptr_n; + curl_off_t min; + curl_off_t max; + curl_off_t idx; curl_off_t step; - } NumRange; - } content; + int npad; + } num; + } c; }; /* the total number of globs supported */ -#define GLOB_PATTERN_NUM 100 +#define GLOB_PATTERN_NUM 30 struct URLGlob { - struct URLPattern pattern[GLOB_PATTERN_NUM]; + struct dynbuf buf; + struct URLPattern *pattern; + size_t palloc; /* number of pattern entries allocated */ size_t size; - size_t urllen; - char *glob_buffer; char beenhere; const char *error; /* error message */ size_t pos; /* column position of error or 0 */ }; -CURLcode glob_url(struct URLGlob**, char *, curl_off_t *, FILE *); +CURLcode glob_url(struct URLGlob *, char *, curl_off_t *, FILE *); CURLcode glob_next_url(char **, struct URLGlob *); CURLcode glob_match_url(char **, const char *, struct URLGlob *); -void glob_cleanup(struct URLGlob **glob); +void glob_cleanup(struct URLGlob *glob); +bool glob_inuse(struct URLGlob *glob); #endif /* HEADER_CURL_TOOL_URLGLOB_H */ diff --git a/src/tool_writeout.c b/src/tool_writeout.c index 7e38b1a20..246971274 100644 --- a/src/tool_writeout.c +++ b/src/tool_writeout.c @@ -603,8 +603,9 @@ static const char *outtime(const char *ptr, /* %time{ ... */ if(!result) { /* !checksrc! disable BANNEDFUNC 1 */ utc = gmtime(&secs); - strftime(output, sizeof(output), curlx_dyn_ptr(&format), utc); - fputs(output, stream); + if(curlx_dyn_len(&format) && + strftime(output, sizeof(output), curlx_dyn_ptr(&format), utc)) + fputs(output, stream); curlx_dyn_free(&format); } ptr = end + 1; @@ -39,7 +39,7 @@ #define MAX_VAR_LEN 128 /* max length of a name */ /* free everything */ -void varcleanup(struct GlobalConfig *global) +void varcleanup(void) { struct tool_var *list = global->variables; while(list) { @@ -50,8 +50,7 @@ void varcleanup(struct GlobalConfig *global) } } -static const struct tool_var *varcontent(struct GlobalConfig *global, - const char *name, size_t nlen) +static const struct tool_var *varcontent(const char *name, size_t nlen) { struct tool_var *list = global->variables; while(list) { @@ -79,8 +78,7 @@ static const struct tool_var *varcontent(struct GlobalConfig *global, #define FUNC_64DEC "64dec" /* base64 decode */ #define FUNC_64DEC_LEN (sizeof(FUNC_64DEC) - 1) -static ParameterError varfunc(struct GlobalConfig *global, - char *c, /* content */ +static ParameterError varfunc(char *c, /* content */ size_t clen, /* content length */ char *f, /* functions */ size_t flen, /* function string length */ @@ -189,8 +187,7 @@ static ParameterError varfunc(struct GlobalConfig *global, } else { /* unsupported function */ - errorf(global, "unknown variable function in '%.*s'", - (int)flen, finput); + errorf("unknown variable function in '%.*s'", (int)flen, finput); err = PARAM_EXPAND_ERROR; break; } @@ -212,8 +209,7 @@ static ParameterError varfunc(struct GlobalConfig *global, return err; } -ParameterError varexpand(struct GlobalConfig *global, - const char *line, struct dynbuf *out, +ParameterError varexpand(const char *line, struct dynbuf *out, bool *replaced) { CURLcode result; @@ -248,7 +244,7 @@ ParameterError varexpand(struct GlobalConfig *global, if(!clp) { /* uneven braces */ - warnf(global, "missing close '}}' in '%s'", input); + warnf("missing close '}}' in '%s'", input); break; } @@ -262,7 +258,7 @@ ParameterError varexpand(struct GlobalConfig *global, else nlen = clp - envp; if(!nlen || (nlen >= sizeof(name))) { - warnf(global, "bad variable name length '%s'", input); + warnf("bad variable name length '%s'", input); /* insert the text as-is since this is not an env variable */ result = curlx_dyn_addn(out, line, clp - line + prefix); if(result) @@ -282,7 +278,7 @@ ParameterError varexpand(struct GlobalConfig *global, for(i = 0; (i < nlen) && (ISALNUM(name[i]) || (name[i] == '_')); i++); if(i != nlen) { - warnf(global, "bad variable name: %s", name); + warnf("bad variable name: %s", name); /* insert the text as-is since this is not an env variable */ result = curlx_dyn_addn(out, envp - prefix, clp - envp + prefix + 2); @@ -293,7 +289,7 @@ ParameterError varexpand(struct GlobalConfig *global, char *value; size_t vlen = 0; struct dynbuf buf; - const struct tool_var *v = varcontent(global, name, nlen); + const struct tool_var *v = varcontent(name, nlen); if(v) { value = (char *)CURL_UNCONST(v->content); vlen = v->clen; @@ -305,8 +301,7 @@ ParameterError varexpand(struct GlobalConfig *global, if(funcp) { /* apply the list of functions on the value */ size_t flen = clp - funcp; - ParameterError err = varfunc(global, value, vlen, funcp, flen, - &buf); + ParameterError err = varfunc(value, vlen, funcp, flen, &buf); if(err) return err; value = curlx_dyn_ptr(&buf); @@ -318,7 +313,7 @@ ParameterError varexpand(struct GlobalConfig *global, using normal means, this is an error. */ char *nb = memchr(value, '\0', vlen); if(nb) { - errorf(global, "variable contains null byte"); + errorf("variable contains null byte"); return PARAM_EXPAND_ERROR; } } @@ -352,18 +347,17 @@ ParameterError varexpand(struct GlobalConfig *global, * that we can improve this if we want better performance when managing many * at a later point. */ -static ParameterError addvariable(struct GlobalConfig *global, - const char *name, +static ParameterError addvariable(const char *name, size_t nlen, const char *content, size_t clen, bool contalloc) { struct tool_var *p; - const struct tool_var *check = varcontent(global, name, nlen); + const struct tool_var *check = varcontent(name, nlen); DEBUGASSERT(nlen); if(check) - notef(global, "Overwriting variable '%s'", check->name); + notef("Overwriting variable '%s'", check->name); p = calloc(1, sizeof(struct tool_var) + nlen); if(p) { @@ -384,8 +378,7 @@ static ParameterError addvariable(struct GlobalConfig *global, #define MAX_FILENAME 10000 -ParameterError setvariable(struct GlobalConfig *global, - const char *input) +ParameterError setvariable(const char *input) { const char *name; size_t nlen; @@ -409,7 +402,7 @@ ParameterError setvariable(struct GlobalConfig *global, line++; nlen = line - name; if(!nlen || (nlen >= MAX_VAR_LEN)) { - warnf(global, "Bad variable name length (%zd), skipping", nlen); + warnf("Bad variable name length (%zd), skipping", nlen); return PARAM_OK; } if(import) { @@ -424,7 +417,7 @@ ParameterError setvariable(struct GlobalConfig *global, ge = getenv(name); if(!*line && !ge) { /* no assign, no variable, fail */ - errorf(global, "Variable '%s' import fail, not set", name); + errorf("Variable '%s' import fail, not set", name); return PARAM_EXPAND_ERROR; } else if(ge) { @@ -464,8 +457,7 @@ ParameterError setvariable(struct GlobalConfig *global, else { file = fopen(line, "rb"); if(!file) { - errorf(global, "Failed to open %s: %s", line, - strerror(errno)); + errorf("Failed to open %s: %s", line, strerror(errno)); err = PARAM_READ_ERROR; } } @@ -499,10 +491,10 @@ ParameterError setvariable(struct GlobalConfig *global, } } else { - warnf(global, "Bad --variable syntax, skipping: %s", input); + warnf("Bad --variable syntax, skipping: %s", input); return PARAM_OK; } - err = addvariable(global, name, nlen, content, clen, contalloc); + err = addvariable(name, nlen, content, clen, contalloc); if(err) { if(contalloc) free(content); @@ -33,14 +33,11 @@ struct tool_var { char name[1]; /* allocated as part of the struct */ }; -struct GlobalConfig; - -ParameterError setvariable(struct GlobalConfig *global, const char *input); -ParameterError varexpand(struct GlobalConfig *global, - const char *line, struct dynbuf *out, +ParameterError setvariable(const char *input); +ParameterError varexpand(const char *line, struct dynbuf *out, bool *replaced); /* free everything */ -void varcleanup(struct GlobalConfig *global); +void varcleanup(void); #endif /* HEADER_CURL_VAR_H */ diff --git a/tests/cmake/CMakeLists.txt b/tests/cmake/CMakeLists.txt index d40a6b25d..2c3d0daeb 100644 --- a/tests/cmake/CMakeLists.txt +++ b/tests/cmake/CMakeLists.txt @@ -31,20 +31,7 @@ option(TEST_INTEGRATION_MODE "Integration mode" "find_package") message(STATUS "TEST_INTEGRATION_MODE: ${TEST_INTEGRATION_MODE}") -if(TEST_INTEGRATION_MODE STREQUAL "FetchContent" AND CMAKE_VERSION VERSION_LESS 3.14) - message(FATAL_ERROR "This test requires CMake 3.14 or upper") -endif() - -if(TEST_INTEGRATION_MODE STREQUAL "ExternalProject") # Broken - include(ExternalProject) - ExternalProject_Add(libssh2 - URL "${FROM_ARCHIVE}" URL_HASH "SHA256=${FROM_HASH}" - INSTALL_COMMAND "" - DOWNLOAD_EXTRACT_TIMESTAMP ON) -endif() - -if(TEST_INTEGRATION_MODE STREQUAL "find_package" OR - TEST_INTEGRATION_MODE STREQUAL "ExternalProject") +if(TEST_INTEGRATION_MODE STREQUAL "find_package") find_package(CURL REQUIRED CONFIG) find_package(CURL REQUIRED CONFIG) # Double-inclusion test foreach(_result_var IN ITEMS @@ -75,6 +62,9 @@ elseif(TEST_INTEGRATION_MODE STREQUAL "add_subdirectory") set(BUILD_STATIC_LIBS ON CACHE BOOL "") add_subdirectory(curl) elseif(TEST_INTEGRATION_MODE STREQUAL "FetchContent") + if(CMAKE_VERSION VERSION_LESS 3.14) + message(FATAL_ERROR "This test requires CMake 3.14 or upper") + endif() include(FetchContent) option(FROM_GIT_REPO "Git URL" "https://github.com/curl/curl.git") option(FROM_GIT_TAG "Git tag" "master") @@ -85,17 +75,48 @@ elseif(TEST_INTEGRATION_MODE STREQUAL "FetchContent") set(BUILD_SHARED_LIBS ON CACHE BOOL "") set(BUILD_STATIC_LIBS ON CACHE BOOL "") FetchContent_MakeAvailable(curl) # Requires CMake 3.14 +elseif(TEST_INTEGRATION_MODE STREQUAL "ExternalProject") + include(ExternalProject) + set(_curl_install_dir "${CMAKE_BINARY_DIR}/curl-external-install") + set(_curl_static_lib "${_curl_install_dir}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}curl${CMAKE_STATIC_LIBRARY_SUFFIX}") + string(REPLACE " " ";" CURL_TEST_OPTS "${CURL_TEST_OPTS}") + if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.24) + set(_download_extract_timestamp "DOWNLOAD_EXTRACT_TIMESTAMP" "ON") + endif() + ExternalProject_Add(curl-external + URL "${FROM_ARCHIVE}" URL_HASH "SHA256=${FROM_HASH}" + ${_download_extract_timestamp} + PREFIX "${CMAKE_BINARY_DIR}/curl-external" + CMAKE_ARGS "-DCMAKE_INSTALL_PREFIX=${_curl_install_dir}" -DBUILD_SHARED_LIBS=OFF -DCURL_USE_LIBPSL=OFF -DCURL_USE_PKGCONFIG=OFF + -DCURL_ENABLE_SSL=OFF -DCURL_ENABLE_SSL=OFF -DCURL_DISABLE_LDAP=ON -DCURL_USE_LIBSSH2=OFF -DUSE_NGHTTP2=OFF + -DCURL_BROTLI=OFF -DCURL_ZLIB=OFF -DCURL_ZSTD=OFF -DUSE_LIBIDN2=OFF -DENABLE_IPV6=OFF + ${CURL_TEST_OPTS} + BUILD_BYPRODUCTS "${_curl_static_lib}") + + add_executable(test-consumer-static-fetch "test.c") + add_dependencies(test-consumer-static-fetch curl-external) + if(WIN32) + target_compile_definitions(test-consumer-static-fetch PRIVATE "CURL_STATICLIB") + list(APPEND _curl_static_lib "ws2_32" "bcrypt") + endif() + target_include_directories(test-consumer-static-fetch PRIVATE "${_curl_install_dir}/include") + target_link_libraries(test-consumer-static-fetch PRIVATE "${_curl_static_lib}") endif() -add_executable(test-consumer-static-ns "test.c") -target_link_libraries(test-consumer-static-ns PRIVATE "CURL::libcurl_static") +if(TEST_INTEGRATION_MODE STREQUAL "find_package" OR + TEST_INTEGRATION_MODE STREQUAL "add_subdirectory" OR + TEST_INTEGRATION_MODE STREQUAL "FetchContent") + + add_executable(test-consumer-static-ns "test.c") + target_link_libraries(test-consumer-static-ns PRIVATE "CURL::libcurl_static") -add_executable(test-consumer-shared-ns "test.c") -target_link_libraries(test-consumer-shared-ns PRIVATE "CURL::libcurl_shared") + add_executable(test-consumer-shared-ns "test.c") + target_link_libraries(test-consumer-shared-ns PRIVATE "CURL::libcurl_shared") -# Alias for either shared or static library -add_executable(test-consumer-selected-ns "test.c") -target_link_libraries(test-consumer-selected-ns PRIVATE "CURL::libcurl") + # Alias for either shared or static library + add_executable(test-consumer-selected-ns "test.c") + target_link_libraries(test-consumer-selected-ns PRIVATE "CURL::libcurl") +endif() if(TEST_INTEGRATION_MODE STREQUAL "add_subdirectory" OR TEST_INTEGRATION_MODE STREQUAL "FetchContent") diff --git a/tests/cmake/test.sh b/tests/cmake/test.sh index a1d11e8ad..451235484 100755 --- a/tests/cmake/test.sh +++ b/tests/cmake/test.sh @@ -41,20 +41,20 @@ runresults() { set -x } -if [ "${mode}" = 'ExternalProject' ]; then # Broken +if [ "${mode}" = 'all' ] || [ "${mode}" = 'ExternalProject' ]; then (cd "${src}"; git archive --format=tar HEAD) | gzip > source.tar.gz src="${PWD}/source.tar.gz" sha="$(openssl dgst -sha256 "${src}" | grep -a -i -o -E '[0-9a-f]{64}$')" bldc='bld-externalproject' rm -rf "${bldc}" if [ -n "${cmake_consumer_modern:-}" ]; then # 3.15+ - "${cmake_consumer}" -B "${bldc}" -G "${gen}" ${cmake_opts} -DCMAKE_UNITY_BUILD=ON ${TEST_CMAKE_FLAGS:-} "$@" \ + "${cmake_consumer}" -B "${bldc}" -G "${gen}" ${TEST_CMAKE_FLAGS:-} -DCURL_TEST_OPTS="${cmake_opts} -DCMAKE_UNITY_BUILD=ON $*" \ -DTEST_INTEGRATION_MODE=ExternalProject \ -DFROM_ARCHIVE="${src}" -DFROM_HASH="${sha}" "${cmake_consumer}" --build "${bldc}" --verbose else mkdir "${bldc}"; cd "${bldc}" - "${cmake_consumer}" .. -G "${gen}" ${cmake_opts} ${TEST_CMAKE_FLAGS:-} "$@" \ + "${cmake_consumer}" .. -G "${gen}" ${TEST_CMAKE_FLAGS:-} -DCURL_TEST_OPTS="${cmake_opts} $*" \ -DTEST_INTEGRATION_MODE=ExternalProject \ -DFROM_ARCHIVE="${src}" -DFROM_HASH="${sha}" VERBOSE=1 "${cmake_consumer}" --build . diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am index c01d93eb8..1c0258e17 100644 --- a/tests/data/Makefile.am +++ b/tests/data/Makefile.am @@ -273,7 +273,7 @@ test3000 test3001 test3002 test3003 test3004 test3005 test3006 test3007 \ test3008 test3009 test3010 test3011 test3012 test3013 test3014 test3015 \ test3016 test3017 test3018 test3019 test3020 test3021 test3022 test3023 \ test3024 test3025 test3026 test3027 test3028 test3029 test3030 test3031 \ -test3032 test3033 \ +test3032 test3033 test3034 \ \ test3100 test3101 test3102 test3103 test3104 test3105 \ \ diff --git a/tests/data/test3034 b/tests/data/test3034 new file mode 100644 index 000000000..5b1ace225 --- /dev/null +++ b/tests/data/test3034 @@ -0,0 +1,40 @@ +<testcase> +<info> +<keywords> +CURLOPT_READFUNCTION +curl_easy_reset +rewind +</keywords> +</info> + +# Server side +<reply> +<data nocheck="yes"> +HTTP/1.1 307 Temporary Redirect OK swsclose +Content-Length: 0 +Location: /%TESTNUMBER +</data> +</reply> + +# Client side +<client> +<server> +http +</server> +<tool> +lib%TESTNUMBER +</tool> +<name> +Test reset resolves rewind failure +</name> +<command> +http://%HOSTIP:%HTTPPORT/%TESTNUMBER +</command> +</client> + +<verify> +<errorcode> +0 +</errorcode> +</verify> +</testcase> diff --git a/tests/data/test96 b/tests/data/test96 index 426715a2c..4efc3491a 100644 --- a/tests/data/test96 +++ b/tests/data/test96 @@ -36,6 +36,7 @@ MEM tool_paramhlp.c MEM tool_cfgable.c MEM tool_cfgable.c MEM tool_cfgable.c +MEM tool_cfgable.c </file> <stripfile> $_ = '' if((($_ !~ /tool_paramhlp/) && ($_ !~ /tool_cfgable/)) || ($_ =~ /free\(\(nil\)\)/)) diff --git a/tests/ech_tests.sh b/tests/ech_tests.sh index ce0b4870e..9912929ff 100755 --- a/tests/ech_tests.sh +++ b/tests/ech_tests.sh @@ -41,49 +41,47 @@ # success or vice versa) : "${CURL_CFG_FILE=$HOME/.curlrc}" active_ech=$(grep ech "$CURL_CFG_FILE" | grep -v "#.*ech") -if [[ "$active_ech" != "" ]] -then - echo "You seem to have an active ECH setting in $CURL_CFG_FILE" - echo "That might affect results so please remove that or comment" - echo "it out - exiting." - exit 1 +if [[ "$active_ech" != "" ]]; then + echo "You seem to have an active ECH setting in $CURL_CFG_FILE" + echo "That might affect results so please remove that or comment" + echo "it out - exiting." + exit 1 fi - # Targets we expect to be ECH-enabled servers # for which an HTTPS RR is published. # structure is host:port mapped to pathname # TODO: add negative tests for these declare -A ech_targets=( - [my-own.net]="ech-check.php" - [my-own.net:8443]="ech-check.php" - [defo.ie]="ech-check.php" - [cover.defo.ie]="" - [draft-13.esni.defo.ie:8413]="stats" - [draft-13.esni.defo.ie:8414]="stats" - [draft-13.esni.defo.ie:9413]="" - [draft-13.esni.defo.ie:10413]="" - [draft-13.esni.defo.ie:11413]="" - [draft-13.esni.defo.ie:12413]="" - [draft-13.esni.defo.ie:12414]="" - [cloudflare-ech.com]="cdn-cgi/trace" - [tls-ech.dev]="" - # this one's gone away for now (possibly temporarily) - # [epochbelt.com]="" + [my-own.net]="ech-check.php" + [my-own.net:8443]="ech-check.php" + [defo.ie]="ech-check.php" + [cover.defo.ie]="" + [draft-13.esni.defo.ie:8413]="stats" + [draft-13.esni.defo.ie:8414]="stats" + [draft-13.esni.defo.ie:9413]="" + [draft-13.esni.defo.ie:10413]="" + [draft-13.esni.defo.ie:11413]="" + [draft-13.esni.defo.ie:12413]="" + [draft-13.esni.defo.ie:12414]="" + [cloudflare-ech.com]="cdn-cgi/trace" + [tls-ech.dev]="" + # this one's gone away for now (possibly temporarily) + # [epochbelt.com]="" ) # Targets we expect not to be ECH-enabled servers # but for which an HTTPS RR is published. declare -A httpsrr_targets=( - [ietf.org]="" - [rte.ie]="" + [ietf.org]="" + [rte.ie]="" ) # Targets we expect not to be ECH-enabled servers # and for which no HTTPS RR is published. declare -A neither_targets=( - [www.tcd.ie]="" - [jell.ie]="" + [www.tcd.ie]="" + [jell.ie]="" ) # @@ -124,83 +122,80 @@ DEFPORT=443 function whenisitagain() { - /bin/date -u +%Y%m%d-%H%M%S + /bin/date -u +%Y%m%d-%H%M%S } function fileage() { - echo $(($(date +%s) - $(date +%s -r "$1"))) + echo $(($(date +%s) - $(date +%s -r "$1"))) } function hostport2host() { - case $1 in - *:*) host=${1%:*} port=${1##*:};; - *) host=$1 port=$DEFPORT;; - esac - echo "$host" + case $1 in + *:*) host=${1%:*} port=${1##*:};; + *) host=$1 port=$DEFPORT;; + esac + echo "$host" } function hostport2port() { - case $1 in - *:*) host=${1%:*} port=${1##*:};; - *) host=$1 port=$DEFPORT;; - esac - echo "$port" + case $1 in + *:*) host=${1%:*} port=${1##*:};; + *) host=$1 port=$DEFPORT;; + esac + echo "$port" } function cli_test() { - # 1st param is target URL - turl=$1 - # 2nd param is 0 if we expect curl to not work or 1 if we expect it - # to have worked - curl_winorlose=$2 - # 3rd param is 0 if we expect ECH to not work or 1 if we expect it - # to have worked - ech_winorlose=$3 - # remaining params are passed to command line - # echparms=(${@:4}) - IFS=" " read -r -a echparms <<< "${@:4}" + # 1st param is target URL + turl=$1 + # 2nd param is 0 if we expect curl to not work or 1 if we expect it + # to have worked + curl_winorlose=$2 + # 3rd param is 0 if we expect ECH to not work or 1 if we expect it + # to have worked + ech_winorlose=$3 + # remaining params are passed to command line + # echparms=(${@:4}) + IFS=" " read -r -a echparms <<< "${@:4}" - TMPF=$(mktemp) - cmd="timeout $tout $CURL ${CURL_PARAMS[*]} ${echparms[*]} $turl >$TMPF 2>&1" - echo "cli_test: $cmd " >> "$logfile" - timeout "$tout" "$CURL" "${CURL_PARAMS[@]}" "${echparms[@]}" "$turl" >"$TMPF" 2>&1 - eres=$? - if [[ "$eres" == "124" ]] - then - allgood="no" - echo "cli_test: Timeout running $cmd" - cat "$TMPF" >> "$logfile" - echo "cli_test: Timeout running $cmd" >> "$logfile" - fi - if [[ "$eres" != "0" && "$curl_winorlose" == "1" ]] - then - allgood="no" - echo "cli_test: curl failure running $cmd" - cat "$TMPF" >> "$logfile" - echo "cli_test: curl failure running $cmd" >> "$logfile" - fi - ech_success=$(grep -c "ECH: result: status is succeeded" "$TMPF") - if [[ "$ech_success" == "$ech_winorlose" ]] - then - echo "cli_test ok for ${echparms[*]}" - else - allgood="no" - echo "cli_test: ECH failure running $cmd" - cat "$TMPF" >> "$logfile" - echo "cli_test: ECH failure running $cmd" >> "$logfile" - fi - rm -f "$TMPF" + TMPF=$(mktemp) + cmd="timeout $tout $CURL ${CURL_PARAMS[*]} ${echparms[*]} $turl > $TMPF 2>&1" + echo "cli_test: $cmd " >> "$logfile" + timeout "$tout" "$CURL" "${CURL_PARAMS[@]}" "${echparms[@]}" "$turl" > "$TMPF" 2>&1 + eres=$? + if [[ "$eres" == "124" ]]; then + allgood="no" + echo "cli_test: Timeout running $cmd" + cat "$TMPF" >> "$logfile" + echo "cli_test: Timeout running $cmd" >> "$logfile" + fi + if [[ "$eres" != "0" && "$curl_winorlose" == "1" ]]; then + allgood="no" + echo "cli_test: curl failure running $cmd" + cat "$TMPF" >> "$logfile" + echo "cli_test: curl failure running $cmd" >> "$logfile" + fi + ech_success=$(grep -c "ECH: result: status is succeeded" "$TMPF") + if [[ "$ech_success" == "$ech_winorlose" ]]; then + echo "cli_test ok for ${echparms[*]}" + else + allgood="no" + echo "cli_test: ECH failure running $cmd" + cat "$TMPF" >> "$logfile" + echo "cli_test: ECH failure running $cmd" >> "$logfile" + fi + rm -f "$TMPF" } function get_ech_configlist() { - domain=$1 - ecl=$(dig +short https "$domain" | grep "ech=" | sed -e 's/^.*ech=//' | sed -e 's/ .*//') - echo "$ecl" + domain=$1 + ecl=$(dig +short https "$domain" | grep "ech=" | sed -e 's/^.*ech=//' | sed -e 's/ .*//') + echo "$ecl" } # start of main script @@ -221,88 +216,75 @@ have_portsblocked="no" # setup logging NOW=$(whenisitagain) BINNAME=$(basename "$0" .sh) -if [ ! -d "$LTOP" ] -then - mkdir -p "$LTOP" +if [ ! -d "$LTOP" ]; then + mkdir -p "$LTOP" fi -if [ ! -d "$LTOP" ] -then - echo "Can't see $LTOP for logs - exiting" - exit 1 +if [ ! -d "$LTOP" ]; then + echo "Can't see $LTOP for logs - exiting" + exit 1 fi logfile=$LTOP/${BINNAME}_$NOW.log echo "-----" > "$logfile" -echo "Running $0 at $NOW" >> "$logfile" +echo "Running $0 at $NOW" >> "$logfile" echo "Running $0 at $NOW" # check we have the binaries needed and which TLS library we'll be using -if [ -f "$OSSL"/libssl.so ] -then - have_ossl="yes" +if [ -f "$OSSL"/libssl.so ]; then + have_ossl="yes" fi -if [ -f "$WSSL"/libwolfssl.so ] -then - have_wolf="yes" +if [ -f "$WSSL"/libwolfssl.so ]; then + have_wolf="yes" fi -if [ -f "$BSSL"/libssl.so ] -then - have_bssl="yes" +if [ -f "$BSSL"/libssl.so ]; then + have_bssl="yes" fi CURL="$CTOP/src/curl" CURL_PARAMS=(-vvv --doh-url https://one.one.one.one/dns-query) -if [ -f "$CTOP"/src/curl ] -then - have_curl="yes" +if [ -f "$CTOP"/src/curl ]; then + have_curl="yes" fi ossl_cnt=$(LD_LIBRARY_PATH=$OSSL $CURL "${CURL_PARAMS[@]}" -V 2> /dev/null | grep -c OpenSSL) -if ((ossl_cnt == 1)) -then - using_ossl="yes" - # setup access to our .so - export LD_LIBRARY_PATH=$OSSL +if ((ossl_cnt == 1)); then + using_ossl="yes" + # setup access to our .so + export LD_LIBRARY_PATH=$OSSL fi bssl_cnt=$(LD_LIBRARY_PATH=$BSSL $CURL "${CURL_PARAMS[@]}" -V 2> /dev/null | grep -c BoringSSL) -if ((bssl_cnt == 1)) -then - using_bssl="yes" - # setup access to our .so - export LD_LIBRARY_PATH=$BSSL +if ((bssl_cnt == 1)); then + using_bssl="yes" + # setup access to our .so + export LD_LIBRARY_PATH=$BSSL fi wolf_cnt=$($CURL "${CURL_PARAMS[@]}" -V 2> /dev/null | grep -c wolfSSL) -if ((wolf_cnt == 1)) -then - using_wolf="yes" - # for some reason curl+wolfSSL dislikes certs that are ok - # for browsers, so we'll test using "insecure" mode (-k) - # but that's ok here as we're only interested in ECH testing - CURL_PARAMS+=(-k) +if ((wolf_cnt == 1)); then + using_wolf="yes" + # for some reason curl+wolfSSL dislikes certs that are ok + # for browsers, so we'll test using "insecure" mode (-k) + # but that's ok here as we're only interested in ECH testing + CURL_PARAMS+=(-k) fi # check if we have dig and it knows https or not digcmd="dig +short" wdig=$(type -p dig) -if [[ "$wdig" != "" ]] -then - have_dig="yes" +if [[ "$wdig" != "" ]]; then + have_dig="yes" fi wkdig=$(type -p kdig) -if [[ "$wkdig" != "" ]] -then - have_kdig="yes" - digcmd="kdig @$DOHSERVER +https +short" +if [[ "$wkdig" != "" ]]; then + have_kdig="yes" + digcmd="kdig @$DOHSERVER +https +short" fi # see if our dig version knows HTTPS digout=$($digcmd https defo.ie) -if [[ $digout != "1 . "* ]] -then - digout=$($digcmd -t TYPE65 defo.ie) - if [[ $digout == "1 . "* ]] - then - # we're good - have_presout="yes" - fi -else +if [[ $digout != "1 . "* ]]; then + digout=$($digcmd -t TYPE65 defo.ie) + if [[ $digout == "1 . "* ]]; then + # we're good have_presout="yes" + fi +else + have_presout="yes" fi # Check if ports other than 443 are blocked from this @@ -312,25 +294,24 @@ fi not443testurl="https://draft-13.esni.defo.ie:9413/" timeout "$tout" "$CURL" "${CURL_PARAMS[@]}" "$not443testurl" >/dev/null 2>&1 eres=$? -if [[ "$eres" == "124" ]] -then - echo "Timeout running curl for $not443testurl" >> "$logfile" - echo "Timeout running curl for $not443testurl" - have_portsblocked="yes" +if [[ "$eres" == "124" ]]; then + echo "Timeout running curl for $not443testurl" >> "$logfile" + echo "Timeout running curl for $not443testurl" + have_portsblocked="yes" fi { - echo "have_ossl: $have_ossl" - echo "have_wolf: $have_wolf" - echo "have_bssl: $have_bssl" - echo "using_ossl: $using_ossl" - echo "using_wolf: $using_wolf" - echo "using_bssl: $using_bssl" - echo "have_curl: $have_curl" - echo "have_dig: $have_dig" - echo "have_kdig: $have_kdig" - echo "have_presout: $have_presout" - echo "have_portsblocked: $have_portsblocked" + echo "have_ossl: $have_ossl" + echo "have_wolf: $have_wolf" + echo "have_bssl: $have_bssl" + echo "using_ossl: $using_ossl" + echo "using_wolf: $using_wolf" + echo "using_bssl: $using_bssl" + echo "have_curl: $have_curl" + echo "have_dig: $have_dig" + echo "have_kdig: $have_kdig" + echo "have_presout: $have_presout" + echo "have_portsblocked: $have_portsblocked" } >> "$logfile" echo "curl: have $have_curl, cURL command: |$CURL ${CURL_PARAMS[*]}|" @@ -341,199 +322,176 @@ echo "dig: $have_dig, kdig: $have_kdig, HTTPS presentation format: $have_presout echo "dig command: |$digcmd|" echo "ports != 443 blocked: $have_portsblocked" -if [[ "$have_curl" == "no" ]] -then - echo "Can't proceed without curl - exiting" - exit 32 +if [[ "$have_curl" == "no" ]]; then + echo "Can't proceed without curl - exiting" + exit 32 fi allgood="yes" skip="false" -if [[ "$skip" != "true" ]] -then +if [[ "$skip" != "true" ]]; then # basic ECH good/bad -for targ in "${!ech_targets[@]}" -do - if [[ "$using_wolf" == "yes" ]] - then - case $targ in - "draft-13.esni.defo.ie:8414" | "tls-ech.dev" | \ - "cloudflare-ech.com" | "epochbelt.com") - echo "Skipping $targ 'cause wolf"; continue;; - *) - ;; - esac - fi - host=$(hostport2host "$targ") - port=$(hostport2port "$targ") - if [[ "$port" != "443" && "$have_portsblocked" == "yes" ]] - then - echo "Skipping $targ as ports != 443 seem blocked" - continue - fi - path=${ech_targets[$targ]} - turl="https://$host:$port/$path" +for targ in "${!ech_targets[@]}"; do + if [[ "$using_wolf" == "yes" ]]; then + case $targ in + "draft-13.esni.defo.ie:8414" | "tls-ech.dev" | \ + "cloudflare-ech.com" | "epochbelt.com") + echo "Skipping $targ 'cause wolf"; continue;; + *) + ;; + esac + fi + host=$(hostport2host "$targ") + port=$(hostport2port "$targ") + if [[ "$port" != "443" && "$have_portsblocked" == "yes" ]]; then + echo "Skipping $targ as ports != 443 seem blocked" + continue + fi + path=${ech_targets[$targ]} + turl="https://$host:$port/$path" + echo "ECH check for $turl" + { + echo "" echo "ECH check for $turl" + } >> "$logfile" + timeout "$tout" "$CURL" "${CURL_PARAMS[@]}" --ech hard "$turl" >> "$logfile" 2>&1 + eres=$? + if [[ "$eres" == "124" ]]; then + allgood="no" { - echo "" - echo "ECH check for $turl" + echo "Timeout for $turl" + echo -e "\tTimeout for $turl" + echo "Timeout running curl for $host:$port/$path" } >> "$logfile" - timeout "$tout" "$CURL" "${CURL_PARAMS[@]}" --ech hard "$turl" >> "$logfile" 2>&1 - eres=$? - if [[ "$eres" == "124" ]] - then - allgood="no" - { - echo "Timeout for $turl" - echo -e "\tTimeout for $turl" - echo "Timeout running curl for $host:$port/$path" - } >> "$logfile" - fi - if [[ "$eres" != "0" ]] - then - allgood="no" - echo "Error ($eres) for $turl" >> "$logfile" - echo -e "\tError ($eres) for $turl" - fi - echo "" >> "$logfile" + fi + if [[ "$eres" != "0" ]]; then + allgood="no" + echo "Error ($eres) for $turl" >> "$logfile" + echo -e "\tError ($eres) for $turl" + fi + echo "" >> "$logfile" done # check if public_name override works (OpenSSL only) -if [[ "$using_ossl" == "yes" ]] -then - for targ in "${!ech_targets[@]}" - do - host=$(hostport2host "$targ") - port=$(hostport2port "$targ") - if [[ "$port" != "443" && "$have_portsblocked" == "yes" ]] - then - echo "Skipping $targ as ports != 443 seem blocked" - continue - fi - if [[ "$host" == "cloudflare-ech.com" ]] - then - echo "Skipping $host as they've blocked PN override" - continue - fi - path=${ech_targets[$targ]} - turl="https://$host:$port/$path" - echo "PN override check for $turl" - { - echo "" - echo "PN override check for $turl" - } >> "$logfile" - timeout "$tout" "$CURL" "${CURL_PARAMS[@]}" --ech pn:override --ech hard "$turl" >> "$logfile" 2>&1 - eres=$? - if [[ "$eres" == "124" ]] - then - allgood="no" - { - echo "Timeout for $turl" - echo -e "\tTimeout for $turl" - echo "Timeout running curl for $host:$port/$path" - } >> "$logfile" - fi - if [[ "$eres" != "0" ]] - then - allgood="no" - echo "PN override Error ($eres) for $turl" >> "$logfile" - echo -e "\tPN override Error ($eres) for $turl" - fi - echo "" >> "$logfile" - done -fi - -for targ in "${!httpsrr_targets[@]}" -do +if [[ "$using_ossl" == "yes" ]]; then + for targ in "${!ech_targets[@]}"; do host=$(hostport2host "$targ") port=$(hostport2port "$targ") - if [[ "$port" != "443" && "$have_portsblocked" == "yes" ]] - then - echo "Skipping $targ as ports != 443 seem blocked" - continue + if [[ "$port" != "443" && "$have_portsblocked" == "yes" ]]; then + echo "Skipping $targ as ports != 443 seem blocked" + continue + fi + if [[ "$host" == "cloudflare-ech.com" ]]; then + echo "Skipping $host as they've blocked PN override" + continue fi - path=${httpsrr_targets[$targ]} + path=${ech_targets[$targ]} turl="https://$host:$port/$path" - echo "HTTPS RR but no ECHConfig check for $turl" + echo "PN override check for $turl" { - echo "" - echo "HTTPS RR but no ECHConfig check for $turl" + echo "" + echo "PN override check for $turl" } >> "$logfile" - timeout "$tout" "$CURL" "${CURL_PARAMS[@]}" --ech true "$turl" >> "$logfile" 2>&1 + timeout "$tout" "$CURL" "${CURL_PARAMS[@]}" --ech pn:override --ech hard "$turl" >> "$logfile" 2>&1 eres=$? - if [[ "$eres" == "124" ]] - then - allgood="no" - { - echo "Timeout for $turl" - echo -e "\tTimeout for $turl" - echo "Timeout running curl for $host:$port/$path" - } >> "$logfile" + if [[ "$eres" == "124" ]]; then + allgood="no" + { + echo "Timeout for $turl" + echo -e "\tTimeout for $turl" + echo "Timeout running curl for $host:$port/$path" + } >> "$logfile" fi - if [[ "$eres" != "0" ]] - then - allgood="no" - echo "Error ($eres) for $turl" >> "$logfile" - echo -e "\tError ($eres) for $turl" + if [[ "$eres" != "0" ]]; then + allgood="no" + echo "PN override Error ($eres) for $turl" >> "$logfile" + echo -e "\tPN override Error ($eres) for $turl" fi echo "" >> "$logfile" + done +fi + +for targ in "${!httpsrr_targets[@]}"; do + host=$(hostport2host "$targ") + port=$(hostport2port "$targ") + if [[ "$port" != "443" && "$have_portsblocked" == "yes" ]]; then + echo "Skipping $targ as ports != 443 seem blocked" + continue + fi + path=${httpsrr_targets[$targ]} + turl="https://$host:$port/$path" + echo "HTTPS RR but no ECHConfig check for $turl" + { + echo "" + echo "HTTPS RR but no ECHConfig check for $turl" + } >> "$logfile" + timeout "$tout" "$CURL" "${CURL_PARAMS[@]}" --ech true "$turl" >> "$logfile" 2>&1 + eres=$? + if [[ "$eres" == "124" ]]; then + allgood="no" + { + echo "Timeout for $turl" + echo -e "\tTimeout for $turl" + echo "Timeout running curl for $host:$port/$path" + } >> "$logfile" + fi + if [[ "$eres" != "0" ]]; then + allgood="no" + echo "Error ($eres) for $turl" >> "$logfile" + echo -e "\tError ($eres) for $turl" + fi + echo "" >> "$logfile" done -for targ in "${!neither_targets[@]}" -do - host=$(hostport2host "$targ") - port=$(hostport2port "$targ") - if [[ "$port" != "443" && "$have_portsblocked" == "yes" ]] - then - echo "Skipping $targ as ports != 443 seem blocked" - continue - fi - path=${neither_targets[$targ]} - turl="https://$host:$port/$path" +for targ in "${!neither_targets[@]}"; do + host=$(hostport2host "$targ") + port=$(hostport2port "$targ") + if [[ "$port" != "443" && "$have_portsblocked" == "yes" ]]; then + echo "Skipping $targ as ports != 443 seem blocked" + continue + fi + path=${neither_targets[$targ]} + turl="https://$host:$port/$path" + echo "Neither HTTPS nor ECHConfig check for $turl" + { + echo "" echo "Neither HTTPS nor ECHConfig check for $turl" + } >> "$logfile" + timeout "$tout" "$CURL" "${CURL_PARAMS[@]}" --ech true "$turl" >> "$logfile" 2>&1 + eres=$? + if [[ "$eres" == "124" ]]; then + allgood="no" { - echo "" - echo "Neither HTTPS nor ECHConfig check for $turl" + echo "Timeout for $turl" + echo -e "\tTimeout for $turl" + echo "Timeout running curl for $host:$port/$path" } >> "$logfile" - timeout "$tout" "$CURL" "${CURL_PARAMS[@]}" --ech true "$turl" >> "$logfile" 2>&1 - eres=$? - if [[ "$eres" == "124" ]] - then - allgood="no" - { - echo "Timeout for $turl" - echo -e "\tTimeout for $turl" - echo "Timeout running curl for $host:$port/$path" - } >> "$logfile" - fi - if [[ "$eres" != "0" ]] - then - allgood="no" - echo "Error ($eres) for $turl" >> "$logfile" - echo -e "\tError ($eres) for $turl" - fi - echo "" >> "$logfile" + fi + if [[ "$eres" != "0" ]]; then + allgood="no" + echo "Error ($eres) for $turl" >> "$logfile" + echo -e "\tError ($eres) for $turl" + fi + echo "" >> "$logfile" done - # Check various command line options, if we're good so far -if [[ "$using_ossl" == "yes" && "$allgood" == "yes" ]] -then - # use this test URL as it'll tell us if things worked - turl="https://defo.ie/ech-check.php" - echo "cli_test with $turl" - echo "cli_test with $turl" >> "$logfile" - cli_test "$turl" 1 1 --ech true - cli_test "$turl" 1 0 --ech false - cli_test "$turl" 1 1 --ech false --ech true - cli_test "$turl" 1 1 --ech false --ech true --ech pn:foobar - cli_test "$turl" 1 1 --ech false --ech pn:foobar --ech true - echconfiglist=$(get_ech_configlist defo.ie) - cli_test "$turl" 1 1 --ech ecl:"$echconfiglist" - cli_test "$turl" 1 0 --ech ecl: +if [[ "$using_ossl" == "yes" && "$allgood" == "yes" ]]; then + # use this test URL as it'll tell us if things worked + turl="https://defo.ie/ech-check.php" + echo "cli_test with $turl" + echo "cli_test with $turl" >> "$logfile" + cli_test "$turl" 1 1 --ech true + cli_test "$turl" 1 0 --ech false + cli_test "$turl" 1 1 --ech false --ech true + cli_test "$turl" 1 1 --ech false --ech true --ech pn:foobar + cli_test "$turl" 1 1 --ech false --ech pn:foobar --ech true + echconfiglist=$(get_ech_configlist defo.ie) + cli_test "$turl" 1 1 --ech ecl:"$echconfiglist" + cli_test "$turl" 1 0 --ech ecl: fi fi # skip @@ -541,616 +499,610 @@ fi # skip # Check combinations of command line options, if we're good so far # Most of this only works for OpenSSL, which is ok, as we're checking # the argument handling here, not the ECH protocol -if [[ "$using_ossl" == "yes" && "$allgood" == "yes" ]] -then - # ech can be hard, true, grease or false - # ecl:ecl can be correct, incorrect or missing - # ech:pn can be correct, incorrect or missing - # in all cases the "last" argument provided should "win" - # but only one of hard, true, grease or false will apply - turl="https://defo.ie/ech-check.php" - echconfiglist=$(get_ech_configlist defo.ie) - goodecl=$echconfiglist - echconfiglist=$(get_ech_configlist hidden.hoba.ie) - badecl=$echconfiglist - goodpn="cover.defo.ie" - badpn="hoba.ie" - echo "more cli_test with $turl" - echo "more cli_test with $turl" >> "$logfile" +if [[ "$using_ossl" == "yes" && "$allgood" == "yes" ]]; then + # ech can be hard, true, grease or false + # ecl:ecl can be correct, incorrect or missing + # ech:pn can be correct, incorrect or missing + # in all cases the "last" argument provided should "win" + # but only one of hard, true, grease or false will apply + turl="https://defo.ie/ech-check.php" + echconfiglist=$(get_ech_configlist defo.ie) + goodecl=$echconfiglist + echconfiglist=$(get_ech_configlist hidden.hoba.ie) + badecl=$echconfiglist + goodpn="cover.defo.ie" + badpn="hoba.ie" + echo "more cli_test with $turl" + echo "more cli_test with $turl" >> "$logfile" - # The combinatorics here are handled via the tests/ech_combos.py script - # which produces all the relevant combinations or inputs and orders - # thereof. We have to manually assess whether or not ECH is expected to - # work for each case. - cli_test "$turl" 0 0 - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech ecl:"$badecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech ecl:"$badecl" --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech ecl:"$badecl" --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech hard - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech ecl:"$badecl" --ech hard --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech ecl:"$badecl" --ech hard --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech hard --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech hard --ech true - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech ecl:"$badecl" --ech hard --ech true --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech ecl:"$badecl" --ech hard --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech hard --ech true --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech pn:"$badpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech ecl:"$badecl" --ech pn:"$badpn" --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech ecl:"$badecl" --ech pn:"$badpn" --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech true - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech true --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech true --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech pn:"$badpn" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech pn:"$badpn" --ech true - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech ecl:"$badecl" --ech pn:"$badpn" --ech true --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech ecl:"$badecl" --ech pn:"$badpn" --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" - 0 --ech ecl:"$badecl" --ech pn:"$badpn" --ech true --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech true - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech ecl:"$badecl" --ech true --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech ecl:"$badecl" --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech true --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 0 --ech false - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 0 --ech false --ech ecl:"$badecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 0 --ech false --ech ecl:"$badecl" --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 0 --ech false --ech ecl:"$badecl" --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech hard - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech false --ech ecl:"$badecl" --ech hard --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech false --ech ecl:"$badecl" --ech hard --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech hard --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech hard --ech true - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech false --ech ecl:"$badecl" --ech hard --ech true --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech false --ech ecl:"$badecl" --ech hard --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech hard --ech true --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech true - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech true --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech true --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech true - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech true --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech true --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 0 --ech false --ech ecl:"$badecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech true - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech false --ech ecl:"$badecl" --ech true --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech false --ech ecl:"$badecl" --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech true --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 0 --ech false --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 0 --ech false --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech false --ech hard - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech false --ech hard --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech false --ech hard --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech false --ech hard --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech false --ech hard --ech true - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech false --ech hard --ech true --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech false --ech hard --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech false --ech hard --ech true --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 0 --ech false --ech pn:"$badpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 0 --ech false --ech pn:"$badpn" --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 0 --ech false --ech pn:"$badpn" --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech false --ech pn:"$badpn" --ech hard - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech false --ech pn:"$badpn" --ech hard --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech false --ech pn:"$badpn" --ech hard --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech false --ech pn:"$badpn" --ech hard --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech false --ech pn:"$badpn" --ech hard --ech true - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech false --ech pn:"$badpn" --ech hard --ech true --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech false --ech pn:"$badpn" --ech hard --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech false --ech pn:"$badpn" --ech hard --ech true --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 0 --ech false --ech pn:"$badpn" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech false --ech pn:"$badpn" --ech true - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech false --ech pn:"$badpn" --ech true --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech false --ech pn:"$badpn" --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech false --ech pn:"$badpn" --ech true --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 0 --ech false --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech false --ech true - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech false --ech true --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech false --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech false --ech true --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech hard - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech hard --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech hard --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech hard --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech hard --ech true - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech hard --ech true --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech hard --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech hard --ech true --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 0 --ech pn:"$badpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech pn:"$badpn" --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech pn:"$badpn" --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech pn:"$badpn" --ech hard - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech pn:"$badpn" --ech hard --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech pn:"$badpn" --ech hard --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech pn:"$badpn" --ech hard --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech pn:"$badpn" --ech hard --ech true - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech pn:"$badpn" --ech hard --ech true --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech pn:"$badpn" --ech hard --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech pn:"$badpn" --ech hard --ech true --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 0 --ech pn:"$badpn" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech pn:"$badpn" --ech true - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech pn:"$badpn" --ech true --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech pn:"$badpn" --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech pn:"$badpn" --ech true --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 0 --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech true - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech true --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech true --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 0 - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 0 --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech true - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech true --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 1 1 --ech true --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi + # The combinatorics here are handled via the tests/ech_combos.py script + # which produces all the relevant combinations or inputs and orders + # thereof. We have to manually assess whether or not ECH is expected to + # work for each case. + cli_test "$turl" 0 0 + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech ecl:"$badecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech ecl:"$badecl" --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech ecl:"$badecl" --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech hard + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech ecl:"$badecl" --ech hard --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech ecl:"$badecl" --ech hard --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech hard --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech hard --ech true + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech ecl:"$badecl" --ech hard --ech true --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech ecl:"$badecl" --ech hard --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech hard --ech true --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech pn:"$badpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech ecl:"$badecl" --ech pn:"$badpn" --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech ecl:"$badecl" --ech pn:"$badpn" --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech true + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech true --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech true --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech pn:"$badpn" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech pn:"$badpn" --ech true + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech ecl:"$badecl" --ech pn:"$badpn" --ech true --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech ecl:"$badecl" --ech pn:"$badpn" --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" - 0 --ech ecl:"$badecl" --ech pn:"$badpn" --ech true --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech true + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech ecl:"$badecl" --ech true --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech ecl:"$badecl" --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech true --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 0 --ech false + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 0 --ech false --ech ecl:"$badecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 0 --ech false --ech ecl:"$badecl" --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 0 --ech false --ech ecl:"$badecl" --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech hard + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech false --ech ecl:"$badecl" --ech hard --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech false --ech ecl:"$badecl" --ech hard --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech hard --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech hard --ech true + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech false --ech ecl:"$badecl" --ech hard --ech true --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech false --ech ecl:"$badecl" --ech hard --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech hard --ech true --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech true + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech true --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech true --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech true + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech true --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech true --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 0 --ech false --ech ecl:"$badecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech true + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech false --ech ecl:"$badecl" --ech true --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech false --ech ecl:"$badecl" --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech true --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 0 --ech false --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 0 --ech false --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech false --ech hard + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech false --ech hard --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech false --ech hard --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech false --ech hard --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech false --ech hard --ech true + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech false --ech hard --ech true --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech false --ech hard --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech false --ech hard --ech true --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 0 --ech false --ech pn:"$badpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 0 --ech false --ech pn:"$badpn" --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 0 --ech false --ech pn:"$badpn" --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech false --ech pn:"$badpn" --ech hard + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech false --ech pn:"$badpn" --ech hard --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech false --ech pn:"$badpn" --ech hard --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech false --ech pn:"$badpn" --ech hard --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech false --ech pn:"$badpn" --ech hard --ech true + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech false --ech pn:"$badpn" --ech hard --ech true --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech false --ech pn:"$badpn" --ech hard --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech false --ech pn:"$badpn" --ech hard --ech true --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 0 --ech false --ech pn:"$badpn" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech false --ech pn:"$badpn" --ech true + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech false --ech pn:"$badpn" --ech true --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech false --ech pn:"$badpn" --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech false --ech pn:"$badpn" --ech true --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 0 --ech false --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech false --ech true + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech false --ech true --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech false --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech false --ech true --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech hard + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech hard --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech hard --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech hard --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech hard --ech true + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech hard --ech true --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech hard --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech hard --ech true --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 0 --ech pn:"$badpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech pn:"$badpn" --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech pn:"$badpn" --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech pn:"$badpn" --ech hard + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech pn:"$badpn" --ech hard --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech pn:"$badpn" --ech hard --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech pn:"$badpn" --ech hard --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech pn:"$badpn" --ech hard --ech true + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech pn:"$badpn" --ech hard --ech true --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech pn:"$badpn" --ech hard --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech pn:"$badpn" --ech hard --ech true --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 0 --ech pn:"$badpn" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech pn:"$badpn" --ech true + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech pn:"$badpn" --ech true --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech pn:"$badpn" --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech pn:"$badpn" --ech true --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 0 --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech true + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech true --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech true --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 0 + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 0 --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech true + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech true --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 1 1 --ech true --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" - # a target URL that doesn't support ECH - turl="https://tcd.ie" - echo "cli_test with $turl" - echo "cli_test with $turl" >> "$logfile" - # the params below don't matter much here as we'll fail anyway - echconfiglist=$(get_ech_configlist defo.ie) - goodecl=$echconfiglist - badecl="$goodecl" - goodpn="tcd.ie" - badpn="tcd.ie" - cli_test "$turl" 1 0 - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech ecl:"$badecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech hard - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech hard --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech hard --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech hard --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech hard --ech true - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech hard --ech true --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech hard --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech hard --ech true --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech pn:"$badpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech pn:"$badpn" --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech pn:"$badpn" --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech true - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech true --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech true --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech pn:"$badpn" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech pn:"$badpn" --ech true - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech pn:"$badpn" --ech true --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech pn:"$badpn" --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech pn:"$badpn" --ech true --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech true - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech true --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech true --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech hard - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech hard --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech hard --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech hard --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech hard --ech true - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech hard --ech true --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech hard --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech hard --ech true --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech true - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech true --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech true --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech true - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech true --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech true --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech true - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech true --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech true --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech hard - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech hard --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech hard --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech hard --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech hard --ech true - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech hard --ech true --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech hard --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech hard --ech true --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech pn:"$badpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech pn:"$badpn" --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech pn:"$badpn" --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech pn:"$badpn" --ech hard - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech pn:"$badpn" --ech hard --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech pn:"$badpn" --ech hard --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech pn:"$badpn" --ech hard --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech pn:"$badpn" --ech hard --ech true - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech pn:"$badpn" --ech hard --ech true --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech pn:"$badpn" --ech hard --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech pn:"$badpn" --ech hard --ech true --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech pn:"$badpn" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech pn:"$badpn" --ech true - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech pn:"$badpn" --ech true --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech pn:"$badpn" --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech pn:"$badpn" --ech true --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech true - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech true --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech false --ech true --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech hard - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech hard --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech hard --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech hard --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech hard --ech true - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech hard --ech true --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech hard --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech hard --ech true --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech pn:"$badpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech pn:"$badpn" --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech pn:"$badpn" --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech pn:"$badpn" --ech hard - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech pn:"$badpn" --ech hard --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech pn:"$badpn" --ech hard --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech pn:"$badpn" --ech hard --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech pn:"$badpn" --ech hard --ech true - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech pn:"$badpn" --ech hard --ech true --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech pn:"$badpn" --ech hard --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech pn:"$badpn" --ech hard --ech true --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech pn:"$badpn" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech pn:"$badpn" --ech true - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech pn:"$badpn" --ech true --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech pn:"$badpn" --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech pn:"$badpn" --ech true --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech true - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech true --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech true --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech true - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech true --ech ecl:"$goodecl" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi - cli_test "$turl" 0 0 --ech true --ech pn:"$goodpn" - if [[ "$allgood" != "yes" ]]; then echo "$LINENO"; fi + # a target URL that doesn't support ECH + turl="https://tcd.ie" + echo "cli_test with $turl" + echo "cli_test with $turl" >> "$logfile" + # the params below don't matter much here as we'll fail anyway + echconfiglist=$(get_ech_configlist defo.ie) + goodecl=$echconfiglist + badecl="$goodecl" + goodpn="tcd.ie" + badpn="tcd.ie" + cli_test "$turl" 1 0 + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech ecl:"$badecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech hard + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech hard --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech hard --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech hard --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech hard --ech true + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech hard --ech true --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech hard --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech hard --ech true --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech pn:"$badpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech pn:"$badpn" --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech pn:"$badpn" --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech true + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech true --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech true --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech pn:"$badpn" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech pn:"$badpn" --ech true + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech pn:"$badpn" --ech true --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech pn:"$badpn" --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech pn:"$badpn" --ech true --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech true + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech true --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech ecl:"$badecl" --ech true --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech hard + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech hard --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech hard --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech hard --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech hard --ech true + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech hard --ech true --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech hard --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech hard --ech true --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech true + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech true --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech hard --ech true --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech true + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech true --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech pn:"$badpn" --ech true --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech true + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech true --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech ecl:"$badecl" --ech true --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech hard + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech hard --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech hard --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech hard --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech hard --ech true + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech hard --ech true --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech hard --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech hard --ech true --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech pn:"$badpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech pn:"$badpn" --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech pn:"$badpn" --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech pn:"$badpn" --ech hard + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech pn:"$badpn" --ech hard --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech pn:"$badpn" --ech hard --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech pn:"$badpn" --ech hard --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech pn:"$badpn" --ech hard --ech true + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech pn:"$badpn" --ech hard --ech true --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech pn:"$badpn" --ech hard --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech pn:"$badpn" --ech hard --ech true --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech pn:"$badpn" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech pn:"$badpn" --ech true + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech pn:"$badpn" --ech true --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech pn:"$badpn" --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech pn:"$badpn" --ech true --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech true + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech true --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech false --ech true --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech hard + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech hard --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech hard --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech hard --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech hard --ech true + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech hard --ech true --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech hard --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech hard --ech true --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech pn:"$badpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech pn:"$badpn" --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech pn:"$badpn" --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech pn:"$badpn" --ech hard + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech pn:"$badpn" --ech hard --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech pn:"$badpn" --ech hard --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech pn:"$badpn" --ech hard --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech pn:"$badpn" --ech hard --ech true + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech pn:"$badpn" --ech hard --ech true --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech pn:"$badpn" --ech hard --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech pn:"$badpn" --ech hard --ech true --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech pn:"$badpn" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech pn:"$badpn" --ech true + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech pn:"$badpn" --ech true --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech pn:"$badpn" --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech pn:"$badpn" --ech true --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech true + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech true --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech true --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech true + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech true --ech ecl:"$goodecl" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech true --ech ecl:"$goodecl" --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" + cli_test "$turl" 0 0 --ech true --ech pn:"$goodpn" + [ "$allgood" != "yes" ] && echo "$LINENO" fi - END=$(whenisitagain) -echo "Finished $0 at $END" >> "$logfile" +echo "Finished $0 at $END" >> "$logfile" echo "-----" >> "$logfile" -if [[ "$allgood" == "yes" ]] -then - echo "Finished $0 at $END" - echo "All good, log in $logfile" - exit 0 +if [[ "$allgood" == "yes" ]]; then + echo "Finished $0 at $END" + echo "All good, log in $logfile" + exit 0 else - echo "Finished $0 at $END" - echo "NOT all good, log in $logfile" + echo "Finished $0 at $END" + echo "NOT all good, log in $logfile" fi # send a mail to root (will be fwd'd) but just once every 24 hours # 'cause we only really need "new" news itsnews="yes" age_of_news=0 -if [ -f "$LTOP"/bad_runs ] -then - age_of_news=$(fileage "$LTOP"/bad_runs) - # only consider news "new" if we haven't mailed today - if ((age_of_news < 24*3600)) - then - itsnews="no" - fi +if [ -f "$LTOP"/bad_runs ]; then + age_of_news=$(fileage "$LTOP"/bad_runs) + # only consider news "new" if we haven't mailed today + if ((age_of_news < 24*3600)); then + itsnews="no" + fi fi -if [[ "$DOMAIL" == "yes" && "$itsnews" == "yes" ]] -then - echo "ECH badness at $NOW" | mail -s "ECH badness at $NOW" root +if [[ "$DOMAIL" == "yes" && "$itsnews" == "yes" ]]; then + echo "ECH badness at $NOW" | mail -s "ECH badness at $NOW" root fi # add to list of bad runs (updating file age) -echo "ECH badness at $NOW" >>"$LTOP"/bad_runs +echo "ECH badness at $NOW" >> "$LTOP"/bad_runs exit 2 diff --git a/tests/libtest/Makefile.inc b/tests/libtest/Makefile.inc index 770184f71..5e1462108 100644 --- a/tests/libtest/Makefile.inc +++ b/tests/libtest/Makefile.inc @@ -104,6 +104,6 @@ TESTS_C = \ lib2402.c lib2404.c lib2405.c \ lib2502.c \ lib2700.c \ - lib3010.c lib3025.c lib3026.c lib3027.c lib3033.c \ + lib3010.c lib3025.c lib3026.c lib3027.c lib3033.c lib3034.c \ lib3100.c lib3101.c lib3102.c lib3103.c lib3104.c lib3105.c \ lib3207.c lib3208.c diff --git a/tests/libtest/lib3034.c b/tests/libtest/lib3034.c new file mode 100644 index 000000000..b21c68d15 --- /dev/null +++ b/tests/libtest/lib3034.c @@ -0,0 +1,77 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * SPDX-License-Identifier: curl + * + ***************************************************************************/ +#include "first.h" + +static const char data_3034[] = "hello"; + +static size_t t3034_read_cb(char *ptr, size_t size, size_t nmemb, void *userp) +{ + size_t len = size * nmemb; + size_t tocopy = sizeof(data_3034) < len ? sizeof(data_3034) : len; + (void)userp; + memcpy(ptr, data_3034, tocopy); + return tocopy; +} + +static CURLcode test_lib3034(const char *URL) +{ + CURL *curl; + CURLcode res = CURLE_OK; + + global_init(CURL_GLOBAL_ALL); + easy_init(curl); + + /* This first request will receive a redirect response; deliberately only + * set the CURLOPT_READFUNCTION but not the CURLOPT_SEEKFUNCTION to force a + * rewind failure (CURLE_SEND_FAIL_REWIND). + */ + test_setopt(curl, CURLOPT_VERBOSE, 1L); + test_setopt(curl, CURLOPT_URL, URL); + test_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + test_setopt(curl, CURLOPT_UPLOAD, 1L); + test_setopt(curl, CURLOPT_INFILESIZE, 5L); + test_setopt(curl, CURLOPT_READFUNCTION, t3034_read_cb); + + res = curl_easy_perform(curl); + if(res != CURLE_SEND_FAIL_REWIND) { + curl_mfprintf(stderr, + "%s:%d curl_easy_perform() failed with code %d (%s)\n", + __FILE__, __LINE__, res, curl_easy_strerror(res)); + goto test_cleanup; + } + + /* Reset the easy handle, which should clear the rewind failure. */ + curl_easy_reset(curl); + + /* Perform a second request, which should succeed. */ + test_setopt(curl, CURLOPT_VERBOSE, 1L); + test_setopt(curl, CURLOPT_URL, URL); + + res = curl_easy_perform(curl); + +test_cleanup: + curl_easy_cleanup(curl); + curl_global_cleanup(); + return res; +} |