mirror of
https://github.com/xroche/httrack.git
synced 2026-07-16 13:51:46 +03:00
Compare commits
42 Commits
drop-swf-j
...
windows-wa
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ab70228fb1 | ||
|
|
6c836248fb | ||
|
|
2d417c600d | ||
|
|
9cc223e213 | ||
|
|
d49e26343c | ||
|
|
f3038c2095 | ||
|
|
938a873e19 | ||
|
|
567a6caecd | ||
|
|
5abcd496b0 | ||
|
|
ed05faaaa8 | ||
|
|
5e56a913a5 | ||
|
|
29e868b2ca | ||
|
|
f1418bac3c | ||
|
|
092a557305 | ||
|
|
cfe7c7e68f | ||
|
|
89b1e485d7 | ||
|
|
08481464bd | ||
|
|
3e7b9f91ee | ||
|
|
800d498893 | ||
|
|
991d259981 | ||
|
|
d1bf4f7a25 | ||
|
|
86e145fc1c | ||
|
|
d9ff780d0f | ||
|
|
b026c80bb6 | ||
|
|
e0648beff9 | ||
|
|
ee1aebd935 | ||
|
|
b4957f0625 | ||
|
|
c9d36c82c7 | ||
|
|
1fa0184468 | ||
|
|
79e46eeceb | ||
|
|
436ac53793 | ||
|
|
bc4b2c7b8e | ||
|
|
4fafe283b4 | ||
|
|
9ec5a3a067 | ||
|
|
cd38e6e68d | ||
|
|
e692e56592 | ||
|
|
7d9d4ed890 | ||
|
|
573167e8dd | ||
|
|
e26a5f5c6a | ||
|
|
627ae2b043 | ||
|
|
71ab3574ef | ||
|
|
076127ddea |
8
.gitattributes
vendored
Normal file
8
.gitattributes
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
# Resource scripts are Windows tooling input and must stay CRLF: the engine has no
|
||||
# encoding guard, so an autocrlf checkout could otherwise flatten them silently.
|
||||
*.rc text eol=crlf
|
||||
|
||||
# The test scripts run under Git Bash on the Windows CI; a CRLF checkout makes
|
||||
# bash die on $'\r' on every line of them.
|
||||
*.test text eol=lf
|
||||
*.sh text eol=lf
|
||||
42
.github/workflows/ci.yml
vendored
42
.github/workflows/ci.yml
vendored
@@ -41,7 +41,7 @@ jobs:
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
build-essential clang autoconf automake libtool autoconf-archive \
|
||||
zlib1g-dev libssl-dev
|
||||
zlib1g-dev libssl-dev libbrotli-dev libzstd-dev
|
||||
|
||||
- name: Configure
|
||||
run: |
|
||||
@@ -50,6 +50,9 @@ jobs:
|
||||
# committed generated files already let a plain checkout build.
|
||||
autoreconf -fi
|
||||
./configure
|
||||
# a missing decoder would silently drop the coding from Accept-Encoding
|
||||
grep -q "define HTS_USEBROTLI 1" config.h
|
||||
grep -q "define HTS_USEZSTD 1" config.h
|
||||
|
||||
- name: Build
|
||||
run: make -j"$(nproc)"
|
||||
@@ -82,7 +85,7 @@ jobs:
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
build-essential autoconf automake libtool autoconf-archive \
|
||||
zlib1g-dev libssl-dev
|
||||
zlib1g-dev libssl-dev libbrotli-dev libzstd-dev
|
||||
|
||||
- name: Configure
|
||||
run: |
|
||||
@@ -123,14 +126,18 @@ jobs:
|
||||
- name: Install build dependencies
|
||||
run: |
|
||||
set -euo pipefail
|
||||
brew install autoconf automake libtool autoconf-archive
|
||||
brew install autoconf automake libtool autoconf-archive brotli zstd
|
||||
|
||||
- name: Configure
|
||||
run: |
|
||||
set -euo pipefail
|
||||
ssl="$(brew --prefix openssl@3)"
|
||||
brewp="$(brew --prefix)"
|
||||
autoreconf -fi
|
||||
./configure CPPFLAGS="-I${ssl}/include" LDFLAGS="-L${ssl}/lib"
|
||||
./configure CPPFLAGS="-I${ssl}/include -I${brewp}/include" \
|
||||
LDFLAGS="-L${ssl}/lib -L${brewp}/lib"
|
||||
grep -q "define HTS_USEBROTLI 1" config.h
|
||||
grep -q "define HTS_USEZSTD 1" config.h
|
||||
|
||||
- name: Build
|
||||
run: make -j"$(sysctl -n hw.ncpu)"
|
||||
@@ -166,14 +173,16 @@ jobs:
|
||||
- name: Install build dependencies
|
||||
run: |
|
||||
set -euo pipefail
|
||||
brew install autoconf automake libtool autoconf-archive
|
||||
brew install autoconf automake libtool autoconf-archive brotli zstd
|
||||
|
||||
- name: Build and install into a temp prefix
|
||||
run: |
|
||||
set -euo pipefail
|
||||
ssl="$(brew --prefix openssl@3)"
|
||||
brewp="$(brew --prefix)"
|
||||
autoreconf -fi
|
||||
./configure CPPFLAGS="-I${ssl}/include" LDFLAGS="-L${ssl}/lib" \
|
||||
./configure CPPFLAGS="-I${ssl}/include -I${brewp}/include" \
|
||||
LDFLAGS="-L${ssl}/lib -L${brewp}/lib" \
|
||||
--prefix="$RUNNER_TEMP/inst"
|
||||
make -j"$(sysctl -n hw.ncpu)"
|
||||
make install
|
||||
@@ -201,7 +210,8 @@ jobs:
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
build-essential gcc-multilib autoconf automake libtool \
|
||||
autoconf-archive zlib1g-dev:i386 libssl-dev:i386
|
||||
autoconf-archive zlib1g-dev:i386 libssl-dev:i386 \
|
||||
libbrotli-dev:i386 libzstd-dev:i386
|
||||
|
||||
- name: Configure
|
||||
run: |
|
||||
@@ -242,7 +252,7 @@ jobs:
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
build-essential autoconf automake libtool autoconf-archive \
|
||||
zlib1g-dev libssl-dev
|
||||
zlib1g-dev libssl-dev libbrotli-dev libzstd-dev
|
||||
|
||||
- name: Configure (sanitized)
|
||||
run: |
|
||||
@@ -344,7 +354,7 @@ jobs:
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
build-essential clang autoconf automake libtool autoconf-archive \
|
||||
zlib1g-dev libssl-dev
|
||||
zlib1g-dev libssl-dev libbrotli-dev libzstd-dev
|
||||
|
||||
- name: Configure (fuzzers, static)
|
||||
run: |
|
||||
@@ -424,7 +434,7 @@ jobs:
|
||||
apt-get install -y --no-install-recommends \
|
||||
ca-certificates git \
|
||||
build-essential autoconf automake libtool autoconf-archive \
|
||||
zlib1g-dev libssl-dev \
|
||||
zlib1g-dev libssl-dev libbrotli-dev libzstd-dev \
|
||||
debhelper devscripts lintian fakeroot
|
||||
|
||||
- uses: actions/checkout@v6
|
||||
@@ -468,7 +478,7 @@ jobs:
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
build-essential autoconf automake libtool autoconf-archive \
|
||||
zlib1g-dev libssl-dev
|
||||
zlib1g-dev libssl-dev libbrotli-dev libzstd-dev
|
||||
|
||||
- name: distcheck
|
||||
run: |
|
||||
@@ -544,6 +554,16 @@ jobs:
|
||||
- name: shfmt
|
||||
run: shfmt -d -i 4 $SHELL_SCRIPTS
|
||||
|
||||
# MSBuild rejects a malformed .vcxproj with a bare MSB4025 and no build, so
|
||||
# catch it here in seconds rather than on a Windows runner minutes in.
|
||||
- name: XML well-formedness (MSBuild project files)
|
||||
run: |
|
||||
set -euo pipefail
|
||||
for f in src/*.vcxproj; do
|
||||
python3 -c "import sys,xml.dom.minidom; xml.dom.minidom.parse(sys.argv[1])" "$f"
|
||||
echo "ok $f"
|
||||
done
|
||||
|
||||
# Check clang-format on CHANGED LINES ONLY. The engine predates clang-format
|
||||
# (it was shaped by an old Visual Studio formatter) and does not round-trip,
|
||||
# so we never reformat the whole tree -- only the lines a PR touches.
|
||||
|
||||
6
.github/workflows/codeql.yml
vendored
6
.github/workflows/codeql.yml
vendored
@@ -46,6 +46,12 @@ jobs:
|
||||
# fopen's umask-controlled 0666 is intended for mirror/cache/log
|
||||
# output; the one credential file (cookies.txt) is kept 0600 on Unix.
|
||||
config: |
|
||||
paths-ignore:
|
||||
# Demo callback samples, not part of libhttrack.
|
||||
- libtest
|
||||
# ProxyTrack: a separate legacy binary with no auth surface; its
|
||||
# recv/cache-parse code trips taint queries by design.
|
||||
- src/proxy
|
||||
query-filters:
|
||||
- exclude:
|
||||
id: cpp/world-writable-file-creation
|
||||
|
||||
202
.github/workflows/windows-build.yml
vendored
Normal file
202
.github/workflows/windows-build.yml
vendored
Normal file
@@ -0,0 +1,202 @@
|
||||
# Windows build of the engine (VS2022 v143 + vcpkg): libhttrack, the CLI,
|
||||
# webhttrack, proxytrack.
|
||||
#
|
||||
# The autotools CI covers the unix builds; this covers the MSVC one, which had
|
||||
# no coverage at all and had drifted (the old .vcproj pinned OpenSSL 1.0.1j).
|
||||
# libhttrack.dll is what the WinHTTrack GUI links against.
|
||||
name: windows-build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
libhttrack:
|
||||
runs-on: windows-2022
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
platform: [x64, Win32]
|
||||
configuration: [Release]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive # coucal lives in src/coucal
|
||||
|
||||
# Located through vswhere rather than microsoft/setup-msbuild: the repo
|
||||
# only allows GitHub-owned actions.
|
||||
- name: Find MSBuild
|
||||
shell: pwsh
|
||||
run: |
|
||||
$vswhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe"
|
||||
$msbuild = & $vswhere -latest -products * -requires Microsoft.Component.MSBuild `
|
||||
-find MSBuild\**\Bin\MSBuild.exe | Select-Object -First 1
|
||||
if (-not $msbuild) { throw "MSBuild not found" }
|
||||
Write-Host "MSBuild: $msbuild"
|
||||
"MSBUILD=$msbuild" | Out-File -FilePath $env:GITHUB_ENV -Append
|
||||
|
||||
- name: Enable vcpkg MSBuild integration
|
||||
shell: pwsh
|
||||
run: vcpkg integrate install
|
||||
|
||||
# httrack and webhttrack carry a ProjectReference to libhttrack, so building
|
||||
# them builds it first; proxytrack is standalone.
|
||||
- name: Build
|
||||
shell: pwsh
|
||||
run: |
|
||||
foreach ($proj in @("libhttrack", "httrack", "webhttrack", "proxytrack")) {
|
||||
& $env:MSBUILD "src\$proj.vcxproj" `
|
||||
/m `
|
||||
/p:Configuration=${{ matrix.configuration }} `
|
||||
/p:Platform=${{ matrix.platform }} `
|
||||
/p:VcpkgEnableManifest=true `
|
||||
/flp:LogFile=msbuild-$proj.log`;Verbosity=normal
|
||||
if ($LASTEXITCODE -ne 0) { throw "$proj failed" }
|
||||
}
|
||||
|
||||
# WinHTTrack links src\$(Platform)\$(Configuration)\libhttrack.lib, so the
|
||||
# import lib and the DLL both have to land there under that exact name.
|
||||
- name: Check the binaries landed where they are expected
|
||||
shell: pwsh
|
||||
run: |
|
||||
$dir = "src\${{ matrix.platform }}\${{ matrix.configuration }}"
|
||||
$want = @("libhttrack.dll", "libhttrack.lib", "httrack.exe",
|
||||
"webhttrack.exe", "proxytrack.exe")
|
||||
foreach ($f in $want) {
|
||||
if (-not (Test-Path "$dir\$f")) { throw "missing $dir\$f" }
|
||||
Write-Host "found $dir\$f"
|
||||
}
|
||||
|
||||
# A CRT split across the exe/DLL boundary links fine and crashes on the
|
||||
# first cross-heap free, so assert both sides import the *same* vcruntime.
|
||||
# Also assert the machine type: Test-Path alone would accept an x64 binary
|
||||
# sitting in the Win32 output dir.
|
||||
- name: Check the CRT is shared across the boundary
|
||||
shell: pwsh
|
||||
run: |
|
||||
$ErrorActionPreference = "Stop"
|
||||
$dir = "src\${{ matrix.platform }}\${{ matrix.configuration }}"
|
||||
$dumpbin = & "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" `
|
||||
-latest -find VC\Tools\MSVC\**\bin\Host*\*\dumpbin.exe | Select-Object -First 1
|
||||
if (-not $dumpbin) { throw "dumpbin not found" }
|
||||
$wantMachine = if ("${{ matrix.platform }}" -eq "x64") { "x64" } else { "x86" }
|
||||
|
||||
function Get-Crt($path) {
|
||||
$out = & $dumpbin /dependents /headers $path
|
||||
if ($LASTEXITCODE -ne 0) { throw "dumpbin failed on $path" }
|
||||
,@($out | Select-String -Pattern '^\s*(vcruntime\d+d?\.dll)$' |
|
||||
ForEach-Object { $_.Matches[0].Groups[1].Value.ToLower() })
|
||||
}
|
||||
|
||||
# Negative control: cmd.exe links the old msvcrt, not vcruntime140. If
|
||||
# this came back non-empty the detector would match anything, and the
|
||||
# assertion below would pass on a mismatched CRT too.
|
||||
if ((Get-Crt "$env:SystemRoot\System32\cmd.exe").Count -ne 0) {
|
||||
throw "negative control failed: the vcruntime detector matches anything"
|
||||
}
|
||||
|
||||
$crts = @{}
|
||||
foreach ($f in @("libhttrack.dll", "httrack.exe")) {
|
||||
$crt = Get-Crt "$dir\$f"
|
||||
if ($crt.Count -eq 0) { throw "$f imports no vcruntime: static or mismatched CRT" }
|
||||
$crts[$f] = $crt
|
||||
|
||||
$hdr = & $dumpbin /headers "$dir\$f"
|
||||
if (-not ($hdr | Select-String -SimpleMatch "machine ($wantMachine)")) {
|
||||
throw "$f is not $wantMachine"
|
||||
}
|
||||
Write-Host "$f -> $($crt -join ',') ($wantMachine)"
|
||||
}
|
||||
|
||||
$a = $crts["libhttrack.dll"] | Sort-Object
|
||||
$b = $crts["httrack.exe"] | Sort-Object
|
||||
if (Compare-Object $a $b) {
|
||||
throw "CRT mismatch across the boundary: libhttrack.dll=$a httrack.exe=$b"
|
||||
}
|
||||
|
||||
# The engine ships ~90 tests and none had ever run on Windows: "make check"
|
||||
# is Linux/macOS only. These are the offline ones, driven from Git Bash
|
||||
# against the native httrack.exe. They subsume the self-tests this step
|
||||
# used to run inline (codecs, cache, fsize).
|
||||
# The *_local-* ones crawl the bundled Python server over loopback: the real
|
||||
# TLS handshake, cache and file writer, which nothing else on Windows covers.
|
||||
- name: Run the engine test suite (offline tests)
|
||||
shell: bash
|
||||
working-directory: tests
|
||||
timeout-minutes: 45
|
||||
run: |
|
||||
set -u
|
||||
bin="$(cygpath -u "$GITHUB_WORKSPACE")/src/${{ matrix.platform }}/${{ matrix.configuration }}"
|
||||
export PATH="$bin:$PATH"
|
||||
command -v httrack >/dev/null || { echo "::error::no httrack.exe in $bin"; exit 1; }
|
||||
|
||||
# httrack.exe is native, so MSYS rewrites any argument shaped like a
|
||||
# POSIX path, and a URL path is shaped exactly like one: "/a/b.html"
|
||||
# reached the engine as "C:/Program Files/Git/a/b.html". Switch that
|
||||
# off, and hand the tests a TMPDIR that is already a Windows path.
|
||||
export MSYS_NO_PATHCONV=1
|
||||
export MSYS2_ARG_CONV_EXCL='*'
|
||||
TMPDIR="$(cygpath -m "$RUNNER_TEMP")"
|
||||
export TMPDIR
|
||||
|
||||
# Mirror what configure hands the suite. LC_ALL sets the codeset MSYS maps
|
||||
# a UTF-8 mirror name onto UTF-16 with, which the intl crawls "test -f".
|
||||
export HTTPS_SUPPORT=yes BROTLI_ENABLED=yes ZSTD_ENABLED=yes
|
||||
export LC_ALL=C.UTF-8
|
||||
|
||||
# A wedged crawl must not eat the job's timeout budget. timeout(1)'s
|
||||
# signals can't reap a native httrack.exe (MSYS signals don't reach it),
|
||||
# so a hang orphaned processes that starved the runner; run_with_timeout
|
||||
# TerminateProcess-es the whole tree. 600s clears the slowest multi-pass
|
||||
# crawl (a few passes at --max-time=120 each).
|
||||
. ./testlib.sh
|
||||
|
||||
pass=0 fail=0 skip=0 failed="" skipped=""
|
||||
for t in 00_runnable.test 01_engine-*.test 01_zlib-*.test \
|
||||
*_local-*.test 13_crawl_proxy_https.test 58_watchdog.test; do
|
||||
rc=0
|
||||
run_with_timeout 600 bash "$t" >"$t.log" 2>&1 || rc=$?
|
||||
case "$rc" in
|
||||
0) pass=$((pass + 1)); echo "PASS $t" ;;
|
||||
77) skip=$((skip + 1)) skipped="$skipped $t"; echo "SKIP $t" ;;
|
||||
124) fail=$((fail + 1)) failed="$failed $t"; echo "FAIL $t (timed out, tree killed)" ;;
|
||||
*)
|
||||
fail=$((fail + 1)) failed="$failed $t"
|
||||
echo "FAIL $t (exit $rc)"
|
||||
# These assert with `test "$(...)" == "..." || exit 1`, which
|
||||
# says nothing at all on failure. Re-run traced, still bounded.
|
||||
run_with_timeout 600 bash -x "$t" >>"$t.log" 2>&1 || true
|
||||
tail -n 25 "$t.log" | sed 's/^/ /'
|
||||
;;
|
||||
esac
|
||||
done
|
||||
echo "ran=$((pass + fail + skip)) pass=$pass fail=$fail skip=$skip" |
|
||||
tee -a "$GITHUB_STEP_SUMMARY"
|
||||
|
||||
# Every gate here exits 77, so an all-skipped suite would report green having
|
||||
# tested nothing: pin the skips, and floor the passes in case the glob empties.
|
||||
expected_skips=" 48_local-crange-memresume.test" # pending #581
|
||||
[ "$pass" -ge 90 ] || { echo "::error::only $pass tests passed ($skip skipped)"; exit 1; }
|
||||
[ "$skipped" = "$expected_skips" ] || { echo "::error::unexpected skips:$skipped"; exit 1; }
|
||||
[ "$fail" -eq 0 ] || { echo "::error::failing:$failed"; exit 1; }
|
||||
|
||||
- name: Upload the test logs
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: engine-tests-${{ matrix.platform }}-${{ matrix.configuration }}
|
||||
path: tests/*.log
|
||||
if-no-files-found: warn
|
||||
|
||||
- name: Upload MSBuild logs
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: msbuild-${{ matrix.platform }}-${{ matrix.configuration }}
|
||||
path: msbuild-*.log
|
||||
if-no-files-found: ignore
|
||||
1
CLAUDE.local.md
Symbolic link
1
CLAUDE.local.md
Symbolic link
@@ -0,0 +1 @@
|
||||
/home/roche/git/httrack-works/CLAUDE.httrack.local.md
|
||||
@@ -173,6 +173,10 @@ AC_CHECK_HEADERS([execinfo.h])
|
||||
### zlib
|
||||
CHECK_ZLIB()
|
||||
|
||||
### brotli and zstd content codings (optional)
|
||||
CHECK_BROTLI()
|
||||
CHECK_ZSTD()
|
||||
|
||||
### OpenSSL is explicitly enabled/disabled ?
|
||||
AC_MSG_CHECKING(whether to enable https support)
|
||||
AC_ARG_ENABLE([https],
|
||||
|
||||
2
debian/control
vendored
2
debian/control
vendored
@@ -2,7 +2,7 @@ Source: httrack
|
||||
Section: web
|
||||
Maintainer: Xavier Roche <roche@httrack.com>
|
||||
Standards-Version: 4.7.4
|
||||
Build-Depends: debhelper-compat (= 14), autoconf, autoconf-archive, automake, libtool, zlib1g-dev, libssl-dev
|
||||
Build-Depends: debhelper-compat (= 14), autoconf, autoconf-archive, automake, libtool, zlib1g-dev, libssl-dev, libbrotli-dev, libzstd-dev
|
||||
Rules-Requires-Root: no
|
||||
Homepage: http://www.httrack.com
|
||||
Vcs-Git: https://github.com/xroche/httrack.git
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# libFuzzer harnesses; built only with --enable-fuzzers (requires clang).
|
||||
if FUZZERS
|
||||
noinst_PROGRAMS = fuzz-charset fuzz-meta fuzz-idna fuzz-entities \
|
||||
fuzz-unescape fuzz-filters fuzz-url fuzz-header fuzz-cachendx
|
||||
fuzz-unescape fuzz-filters fuzz-url fuzz-header fuzz-cachendx \
|
||||
fuzz-htsparse
|
||||
endif
|
||||
|
||||
AM_CPPFLAGS = \
|
||||
@@ -25,6 +26,7 @@ fuzz_filters_SOURCES = fuzz-filters.c fuzz.h
|
||||
fuzz_url_SOURCES = fuzz-url.c fuzz.h
|
||||
fuzz_header_SOURCES = fuzz-header.c fuzz.h
|
||||
fuzz_cachendx_SOURCES = fuzz-cachendx.c fuzz.h
|
||||
fuzz_htsparse_SOURCES = fuzz-htsparse.c fuzz.h
|
||||
|
||||
# List corpus files explicitly: automake does not expand EXTRA_DIST globs.
|
||||
EXTRA_DIST = README.md run-fuzzers.sh \
|
||||
@@ -37,9 +39,12 @@ EXTRA_DIST = README.md run-fuzzers.sh \
|
||||
corpus/filters/filter.bin corpus/filters/filter-size.bin \
|
||||
corpus/filters/regress-empty-subject-unique.bin \
|
||||
corpus/filters/redos-star-classes.bin \
|
||||
corpus/filters/regress-classdepth-timeout.bin \
|
||||
corpus/url/http-url.txt corpus/url/relative-path.txt \
|
||||
corpus/url/regress-file-empty-path.txt corpus/url/regress-long-path-abort.txt \
|
||||
corpus/header/full-response.txt corpus/header/redirect.txt \
|
||||
corpus/cachendx/new-format.txt corpus/cachendx/old-format.txt \
|
||||
corpus/cachendx/regress-overadvance.bin \
|
||||
corpus/cachendx/regress-truncated-entry.bin
|
||||
corpus/cachendx/regress-truncated-entry.bin \
|
||||
corpus/htsparse/basic.html corpus/htsparse/script-inscript.html \
|
||||
corpus/htsparse/meta-usemap.html corpus/htsparse/malformed.html
|
||||
|
||||
BIN
fuzz/corpus/filters/regress-classdepth-timeout.bin
Normal file
BIN
fuzz/corpus/filters/regress-classdepth-timeout.bin
Normal file
Binary file not shown.
15
fuzz/corpus/htsparse/basic.html
Normal file
15
fuzz/corpus/htsparse/basic.html
Normal file
@@ -0,0 +1,15 @@
|
||||
<!DOCTYPE html>
|
||||
<html><head>
|
||||
<meta charset="utf-8">
|
||||
<base href="http://example.com/dir/">
|
||||
<title>Seed</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
<script src="app.js"></script>
|
||||
</head><body>
|
||||
<h1>Hi</h1>
|
||||
<a href="page2.html">next</a>
|
||||
<a href="http://other.example.org/x?y=1#frag">abs</a>
|
||||
<img src="pic.png" srcset="a.png 1x, b.png 2x">
|
||||
<script>var u="inline.html"; document.write('<a href="gen.html">g</a>');</script>
|
||||
<form action="/cgi/submit"><input name="q"></form>
|
||||
</body></html>
|
||||
8
fuzz/corpus/htsparse/malformed.html
Normal file
8
fuzz/corpus/htsparse/malformed.html
Normal file
@@ -0,0 +1,8 @@
|
||||
<a href="unclosed.html
|
||||
<img src='mix"ed.png>
|
||||
<a href=noquote.html >bare</a>
|
||||
<!-- comment <a href="incomment.html"> -->
|
||||
<a href="tab newline
|
||||
.html">wsp</a>
|
||||
<script>unterminated "string and <a href=
|
||||
<a href=
|
||||
11
fuzz/corpus/htsparse/meta-usemap.html
Normal file
11
fuzz/corpus/htsparse/meta-usemap.html
Normal file
@@ -0,0 +1,11 @@
|
||||
<html><head>
|
||||
<meta http-equiv="refresh" content="0; url=redir.html">
|
||||
<base href="http://h/b/">
|
||||
<link rel="alternate" href="feed.xml">
|
||||
</head><body background="page-bg.jpg">
|
||||
<img src="map.png" usemap="#m">
|
||||
<map name="m"><area href="area1.html" coords="0,0,10,10"></map>
|
||||
<applet code="A.class" codebase="applets/"><param name="src" value="p.dat"></applet>
|
||||
<object data="o.swf"><embed src="e.svg"></object>
|
||||
<a href="http://ent/e.html">entity</a>
|
||||
</body></html>
|
||||
13
fuzz/corpus/htsparse/script-inscript.html
Normal file
13
fuzz/corpus/htsparse/script-inscript.html
Normal file
@@ -0,0 +1,13 @@
|
||||
<html><body>
|
||||
<script type="text/javascript">
|
||||
var a = "http://x/1.html", b = 'q\'uote', c = "/*not*/comment";
|
||||
// line "with" quotes and http://y/2.html
|
||||
/* block 'with' <a href="notparsed"> */
|
||||
var re = /a\/b\//g;
|
||||
document.write('<img src="w1.png">');
|
||||
document.writeln("<a href='w2.html'>k</a>");
|
||||
element.onclick = "location='onh.html'";
|
||||
</script>
|
||||
<a href="after.html" onmouseover="go('ev.html')">x</a>
|
||||
<div style="background:url(bg.png)">z</div>
|
||||
</body></html>
|
||||
175
fuzz/fuzz-htsparse.c
Normal file
175
fuzz/fuzz-htsparse.c
Normal file
@@ -0,0 +1,175 @@
|
||||
/* ------------------------------------------------------------ */
|
||||
/*
|
||||
HTTrack Website Copier, Offline Browser for Windows and Unix
|
||||
Copyright (C) 2026 Xavier Roche and other contributors
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Please visit our Website: http://www.httrack.com
|
||||
*/
|
||||
|
||||
/* Fuzz the real htsparse() over a mocked engine: the minimal crawl state
|
||||
httpmirror() builds, then a page walked through the parser and discarded. The
|
||||
str/stre wiring below mirrors htsparse()'s call site in htscore.c; update it
|
||||
in lockstep if those structs gain a field the parser reads. */
|
||||
#include "fuzz.h"
|
||||
|
||||
#include "httrack-library.h"
|
||||
#include "htscore.h"
|
||||
#include "htsback.h"
|
||||
#include "htshash.h"
|
||||
#include "htsrobots.h"
|
||||
#include "htsparse.h"
|
||||
#include "htsmodules.h"
|
||||
#include "coucal.h"
|
||||
|
||||
/* htsparse ignores str.addLink on the internal parse; stub it. */
|
||||
static int fuzz_addlink(htsmoduleStruct *str, char *link) {
|
||||
(void) str;
|
||||
(void) link;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
||||
static int inited = 0;
|
||||
|
||||
httrackp *opt;
|
||||
cache_back cache;
|
||||
hash_struct hash;
|
||||
robots_wizard robots;
|
||||
struct_back *sback;
|
||||
char **filters = NULL;
|
||||
int filptr = 0;
|
||||
|
||||
htsblk r;
|
||||
htsmoduleStruct str;
|
||||
htsmoduleStructExtended stre;
|
||||
int ptr, error = 0, store_errpage = 0;
|
||||
int makeindex_done = 0, makeindex_links = 0;
|
||||
FILE *makeindex_fp = NULL;
|
||||
char makeindex_firstlink[HTS_URLMAXSIZE * 2] = "";
|
||||
LLint stat_fragment = 0, makestat_total = 0;
|
||||
int makestat_lnk = 0;
|
||||
char base[HTS_URLMAXSIZE * 2] = "";
|
||||
char codebase[HTS_URLMAXSIZE * 2] = "";
|
||||
char err_msg[1024] = "";
|
||||
|
||||
if (!inited) {
|
||||
hts_init();
|
||||
inited = 1;
|
||||
}
|
||||
|
||||
opt = hts_create_opt();
|
||||
opt->log = opt->errlog = NULL;
|
||||
opt->robots = 0;
|
||||
|
||||
memset(&cache, 0, sizeof(cache));
|
||||
cache.type = 0; /* no on-disk cache */
|
||||
cache.hashtable = coucal_new(0);
|
||||
cache.cached_tests = coucal_new(0);
|
||||
coucal_value_is_malloc(cache.cached_tests, 1);
|
||||
|
||||
memset(&robots, 0, sizeof(robots));
|
||||
strcpybuff(robots.adr, "!");
|
||||
opt->robotsptr = &robots;
|
||||
|
||||
opt->maxfilter = maximum(opt->maxfilter, 128);
|
||||
filters_init(&filters, opt->maxfilter, 0);
|
||||
opt->filters.filters = &filters;
|
||||
opt->filters.filptr = &filptr;
|
||||
|
||||
opt->hash = &hash;
|
||||
hts_record_init(opt);
|
||||
hash_init(opt, &hash, opt->urlhack);
|
||||
hash.liens = (const lien_url *const *const *) &opt->liens;
|
||||
|
||||
sback = back_new(opt, opt->maxsoc * 32 + 1024);
|
||||
|
||||
/* ptr=1 (index 1 is the parsed page) selects full HTML parsing + the
|
||||
rewriter; urladr()/urlfil()/savename() alias heap(ptr), save=/dev/null. */
|
||||
hts_record_link(opt, "example.com", "/", "/dev/null", "", "", NULL);
|
||||
hts_record_link(opt, "example.com", "/index.html", "/dev/null", "", "", NULL);
|
||||
ptr = 1;
|
||||
|
||||
/* NUL-terminated in a size+1 alloc: htsparse one-past-reads onto the NUL. */
|
||||
hts_init_htsblk(&r);
|
||||
r.statuscode = 200;
|
||||
r.size = (LLint) size;
|
||||
r.adr = malloct(size + 1);
|
||||
if (size)
|
||||
memcpy(r.adr, data, size);
|
||||
r.adr[size] = '\0';
|
||||
strcpybuff(r.contenttype, "text/html");
|
||||
|
||||
memset(&str, 0, sizeof(str));
|
||||
memset(&stre, 0, sizeof(stre));
|
||||
str.err_msg = err_msg;
|
||||
str.filename = heap(ptr)->sav;
|
||||
str.mime = r.contenttype;
|
||||
str.url_host = heap(ptr)->adr;
|
||||
str.url_file = heap(ptr)->fil;
|
||||
str.size = (int) r.size;
|
||||
str.addLink = fuzz_addlink;
|
||||
str.opt = opt;
|
||||
str.sback = sback;
|
||||
str.cache = &cache;
|
||||
str.hashptr = &hash;
|
||||
str.numero_passe = 0;
|
||||
str.ptr_ = &ptr;
|
||||
str.page_charset_ = NULL;
|
||||
|
||||
stre.r_ = &r;
|
||||
stre.error_ = &error;
|
||||
stre.exit_xh_ = &opt->state.exit_xh;
|
||||
stre.store_errpage_ = &store_errpage;
|
||||
stre.base = base;
|
||||
stre.codebase = codebase;
|
||||
stre.filters_ = &filters;
|
||||
stre.filptr_ = &filptr;
|
||||
stre.robots_ = &robots;
|
||||
stre.hash_ = &hash;
|
||||
stre.makeindex_done_ = &makeindex_done;
|
||||
stre.makeindex_fp_ = &makeindex_fp;
|
||||
stre.makeindex_links_ = &makeindex_links;
|
||||
stre.makeindex_firstlink_ = makeindex_firstlink;
|
||||
stre.template_header_ = "";
|
||||
stre.template_body_ = "";
|
||||
stre.template_footer_ = "";
|
||||
stre.stat_fragment_ = &stat_fragment;
|
||||
stre.makestat_time = 0;
|
||||
stre.makestat_fp = NULL;
|
||||
stre.makestat_total_ = &makestat_total;
|
||||
stre.makestat_lnk_ = &makestat_lnk;
|
||||
stre.maketrack_fp = NULL;
|
||||
|
||||
(void) htsparse(&str, &stre);
|
||||
|
||||
freet(r.adr);
|
||||
back_delete_all(opt, &cache, sback);
|
||||
back_free(&sback);
|
||||
hash_free(&hash);
|
||||
coucal_delete(&cache.hashtable);
|
||||
coucal_delete(&cache.cached_tests);
|
||||
checkrobots_free(&robots);
|
||||
if (filters != NULL) {
|
||||
if (filters[0] != NULL)
|
||||
freet(filters[0]);
|
||||
freet(filters);
|
||||
}
|
||||
hts_record_free(opt);
|
||||
hts_free_opt(opt);
|
||||
return 0;
|
||||
}
|
||||
@@ -69,7 +69,7 @@ ${LANG_K3} : ${HTTRACK_WEB}
|
||||
|
||||
<form>
|
||||
<input type="button" value="OK" onClick="window.close();"
|
||||
onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPOK}' onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</form>
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ function info(str) {
|
||||
<td id="subTitle" align="right">
|
||||
<a href="/server/file.html" target="_blank"
|
||||
onClick="window.open('/server/file.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
|
||||
onMouseOver="info('${html:LANG_O1}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_O1}' onMouseOver="info('${html:LANG_O1}'); return true" onMouseOut="info(' '); return true"
|
||||
style="color:#FFFFFF"
|
||||
>
|
||||
${LANG_O1}
|
||||
@@ -85,7 +85,7 @@ ${do:if-file-exists:html/index.html}
|
||||
<td id="subTitle" align="right">
|
||||
<a href="/index.html" target="_blank"
|
||||
onClick="window.open('/server/help.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
|
||||
onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPHELP}' onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info(' '); return true"
|
||||
style="color:#FFFFFF"
|
||||
>
|
||||
${LANG_O5}
|
||||
@@ -118,20 +118,20 @@ ${do:end-if}
|
||||
<form action="${thisfile}" name="form">
|
||||
<table width="100%">
|
||||
<tr><td>${LANG_T2}</td><td>http://<input name="urladr"
|
||||
onMouseOver="info('${html:LANG_T10}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_T10}' onMouseOver="info('${html:LANG_T10}'); return true" onMouseOut="info(' '); return true"
|
||||
></td></tr>
|
||||
<tr><td colspan=2>
|
||||
|
||||
<table width="100%">
|
||||
<th>${LANG_T4}</th>
|
||||
<tr><td>${LANG_T5}:</td><td><input name="urllogin"
|
||||
onMouseOver="info('${html:LANG_T12}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_T12}' onMouseOver="info('${html:LANG_T12}'); return true" onMouseOut="info(' '); return true"
|
||||
></td></tr>
|
||||
<tr><td>${LANG_T6}:</td><td><input name="urlpass"
|
||||
onMouseOver="info('${html:LANG_T13}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_T13}' onMouseOver="info('${html:LANG_T13}'); return true" onMouseOut="info(' '); return true"
|
||||
></td></tr>
|
||||
<tr><td>${LANG_T7}:</td><td><input type="button" value="${LANG_T8}" onClick="alert('not yet implemented!')"
|
||||
onMouseOver="info('${html:LANG_T14}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_T14}' onMouseOver="info('${html:LANG_T14}'); return true" onMouseOut="info(' '); return true"
|
||||
></td></tr>
|
||||
</table>
|
||||
|
||||
@@ -139,7 +139,7 @@ ${do:end-if}
|
||||
|
||||
<tr><td>
|
||||
<input type="button" value="OK" onClick="if (do_add()) { window.close(); }"
|
||||
onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPOK}' onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td></tr>
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ function info(str) {
|
||||
<td id="subTitle" align="right">
|
||||
<a href="/server/file.html" target="_blank"
|
||||
onClick="window.open('/server/file.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
|
||||
onMouseOver="info('${html:LANG_O1}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_O1}' onMouseOver="info('${html:LANG_O1}'); return true" onMouseOut="info(' '); return true"
|
||||
style="color:#FFFFFF"
|
||||
>
|
||||
${LANG_O1}
|
||||
@@ -48,7 +48,7 @@ ${do:if-file-exists:html/index.html}
|
||||
<td id="subTitle" align="right">
|
||||
<a href="/index.html" target="_blank"
|
||||
onClick="window.open('/server/help.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
|
||||
onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPHELP}' onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info(' '); return true"
|
||||
style="color:#FFFFFF"
|
||||
>
|
||||
${LANG_O5}
|
||||
|
||||
@@ -58,7 +58,7 @@ function info(str) {
|
||||
<table class="tableWidth" border="0" width="100%" cellspacing="0">
|
||||
<tr><td class="tabCtrl" align="left">
|
||||
<a style="background:black;color: white" href="about.html" target="_new"
|
||||
onMouseOver="info('${html:LANG_G21}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_G21}' onMouseOver="info('${html:LANG_G21}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
${LANG_O16}...
|
||||
</a>
|
||||
@@ -67,7 +67,7 @@ ${LANG_O16}...
|
||||
<tr><td class="tabCtrl" align="left">
|
||||
<a style="background:black;color: white"
|
||||
href="http://www.httrack.com/update.php3?Product=HTTrack&Version=${HTTRACK_VERSIONID}&VersionStr=${HTTRACK_VERSION}&Platform=${HTS_PLATFORM}&LanguageId=${lang}" target="_new"
|
||||
onMouseOver="info('${html:LANG_O17}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_O17}' onMouseOver="info('${html:LANG_O17}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
${LANG_O17}...
|
||||
</a>
|
||||
@@ -78,7 +78,7 @@ ${do:if-file-exists:html/index.html}
|
||||
<tr><td class="tabCtrl" align="left">
|
||||
<a style="background:black;color: white"
|
||||
href="/index.html" target="_new"
|
||||
onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPHELP}' onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
${LANG_P16}
|
||||
</a>
|
||||
|
||||
@@ -43,7 +43,7 @@ function info(str) {
|
||||
<td id="subTitle" align="right">
|
||||
<a href="/server/file.html" target="_blank"
|
||||
onClick="window.open('/server/file.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
|
||||
onMouseOver="info('${html:LANG_O1}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_O1}' onMouseOver="info('${html:LANG_O1}'); return true" onMouseOut="info(' '); return true"
|
||||
style="color:#FFFFFF"
|
||||
>
|
||||
${LANG_O1}
|
||||
@@ -55,7 +55,7 @@ ${do:if-file-exists:html/index.html}
|
||||
<td id="subTitle" align="right">
|
||||
<a href="/index.html" target="_blank"
|
||||
onClick="window.open('/server/help.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
|
||||
onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPHELP}' onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info(' '); return true"
|
||||
style="color:#FFFFFF"
|
||||
>
|
||||
${LANG_O5}
|
||||
@@ -113,7 +113,7 @@ ${LANG_THANKYOU}!
|
||||
|
||||
<tr><td align="right">
|
||||
<input name="nextBtn" type="submit" value=" ${LANG_NEXT} >> "
|
||||
onMouseOver="info('${html:LANG_TIPNEXT}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPNEXT}' onMouseOver="info('${html:LANG_TIPNEXT}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td></tr>
|
||||
</table>
|
||||
|
||||
@@ -60,7 +60,7 @@ ${do:if-file-exists:html/index.html}
|
||||
<td>
|
||||
<a href="/step9_opt1.html" target="_blank"
|
||||
onClick="window.open('/step9_opt1.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
|
||||
onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPHELP}' onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info(' '); return true"
|
||||
>${LANG_TIPHELP}</a>
|
||||
</td>
|
||||
${do:end-if}
|
||||
@@ -71,18 +71,18 @@ ${do:end-if}
|
||||
<table class="tableWidth" border="0" width="100%" cellspacing="0">
|
||||
<tr>
|
||||
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option1.html" onClick="form.redirect.value='option1.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT1}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT1}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option2.html" onClick="form.redirect.value='option2.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT2}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT2}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option3.html" onClick="form.redirect.value='option3.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT3}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT3}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option4.html" onClick="form.redirect.value='option4.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT4}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT4}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option5.html" onClick="form.redirect.value='option5.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT5}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT5}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option11.html" onClick="form.redirect.value='option11.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT11}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT11}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option1.html" onClick="form.redirect.value='option1.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT1}' onMouseOver="info('${html:LANG_IOPT1}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT1}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option2.html" onClick="form.redirect.value='option2.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT2}' onMouseOver="info('${html:LANG_IOPT2}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT2}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option3.html" onClick="form.redirect.value='option3.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT3}' onMouseOver="info('${html:LANG_IOPT3}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT3}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option4.html" onClick="form.redirect.value='option4.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT4}' onMouseOver="info('${html:LANG_IOPT4}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT4}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option5.html" onClick="form.redirect.value='option5.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT5}' onMouseOver="info('${html:LANG_IOPT5}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT5}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option11.html" onClick="form.redirect.value='option11.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT11}' onMouseOver="info('${html:LANG_IOPT11}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT11}</a></td>
|
||||
</tr><tr>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option6.html" onClick="form.redirect.value='option6.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT6}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT6}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option7.html" onClick="form.redirect.value='option7.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT7}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT7}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option8.html" onClick="form.redirect.value='option8.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT8}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT8}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option9.html" onClick="form.redirect.value='option9.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT9}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT9}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option10.html" onClick="form.redirect.value='option10.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT10}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT10}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option6.html" onClick="form.redirect.value='option6.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT6}' onMouseOver="info('${html:LANG_IOPT6}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT6}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option7.html" onClick="form.redirect.value='option7.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT7}' onMouseOver="info('${html:LANG_IOPT7}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT7}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option8.html" onClick="form.redirect.value='option8.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT8}' onMouseOver="info('${html:LANG_IOPT8}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT8}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option9.html" onClick="form.redirect.value='option9.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT9}' onMouseOver="info('${html:LANG_IOPT9}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT9}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option10.html" onClick="form.redirect.value='option10.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT10}' onMouseOver="info('${html:LANG_IOPT10}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT10}</a></td>
|
||||
<td class="tabCtrl" align="center"> </td>
|
||||
|
||||
</tr>
|
||||
@@ -107,16 +107,16 @@ ${do:end-if}
|
||||
<!-- checkboxes -->
|
||||
<table border="0" width="100%" cellspacing="0">
|
||||
<tr><td><input type="checkbox" name="parseall" ${checked:parseall}
|
||||
onMouseOver="info('${html:LANG_I1}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_I1}' onMouseOver="info('${html:LANG_I1}'); return true" onMouseOut="info(' '); return true"
|
||||
> ${LANG_I31}</td></tr>
|
||||
<tr><td><input type="checkbox" name="link" ${checked:link}
|
||||
onMouseOver="info('${html:LANG_I2}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_I2}' onMouseOver="info('${html:LANG_I2}'); return true" onMouseOut="info(' '); return true"
|
||||
> ${LANG_I32}</td></tr>
|
||||
<tr><td><input type="checkbox" name="testall" ${checked:testall}
|
||||
onMouseOver="info('${html:LANG_I2b}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_I2b}' onMouseOver="info('${html:LANG_I2b}'); return true" onMouseOut="info(' '); return true"
|
||||
> ${LANG_I32b}</td></tr>
|
||||
<tr><td><input type="checkbox" name="htmlfirst" ${checked:htmlfirst}
|
||||
onMouseOver="info('${html:LANG_I2c}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_I2c}' onMouseOver="info('${html:LANG_I2c}'); return true" onMouseOut="info(' '); return true"
|
||||
> ${LANG_I32c}</td></tr>
|
||||
</table>
|
||||
|
||||
@@ -125,12 +125,12 @@ ${do:end-if}
|
||||
<tr><td align="left">
|
||||
<input type="submit" value="${LANG_OK}"
|
||||
onClick="form.closeme.value=1; form.submit(); return false;"
|
||||
onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPOK}' onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td><td align="right">
|
||||
<input type="button" value="${LANG_CANCEL}"
|
||||
onClick="window.close();"
|
||||
onMouseOver="info('${html:LANG_TIPCANCEL}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPCANCEL}' onMouseOver="info('${html:LANG_TIPCANCEL}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td></tr>
|
||||
</table>
|
||||
|
||||
@@ -60,7 +60,7 @@ ${do:if-file-exists:html/index.html}
|
||||
<td>
|
||||
<a href="/step9_opt7.html" target="_blank"
|
||||
onClick="window.open('/step9_opt7.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
|
||||
onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPHELP}' onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info(' '); return true"
|
||||
>${LANG_TIPHELP}</a>
|
||||
</td>
|
||||
${do:end-if}
|
||||
@@ -71,18 +71,18 @@ ${do:end-if}
|
||||
<table class="tableWidth" border="0" width="100%" cellspacing="0">
|
||||
<tr>
|
||||
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option1.html" onClick="form.redirect.value='option1.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT1}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT1}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option2.html" onClick="form.redirect.value='option2.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT2}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT2}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option3.html" onClick="form.redirect.value='option3.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT3}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT3}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option4.html" onClick="form.redirect.value='option4.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT4}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT4}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option5.html" onClick="form.redirect.value='option5.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT5}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT5}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option11.html" onClick="form.redirect.value='option11.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT11}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT11}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option1.html" onClick="form.redirect.value='option1.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT1}' onMouseOver="info('${html:LANG_IOPT1}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT1}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option2.html" onClick="form.redirect.value='option2.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT2}' onMouseOver="info('${html:LANG_IOPT2}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT2}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option3.html" onClick="form.redirect.value='option3.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT3}' onMouseOver="info('${html:LANG_IOPT3}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT3}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option4.html" onClick="form.redirect.value='option4.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT4}' onMouseOver="info('${html:LANG_IOPT4}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT4}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option5.html" onClick="form.redirect.value='option5.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT5}' onMouseOver="info('${html:LANG_IOPT5}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT5}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option11.html" onClick="form.redirect.value='option11.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT11}' onMouseOver="info('${html:LANG_IOPT11}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT11}</a></td>
|
||||
</tr><tr>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option6.html" onClick="form.redirect.value='option6.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT6}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT6}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option7.html" onClick="form.redirect.value='option7.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT7}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT7}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option8.html" onClick="form.redirect.value='option8.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT8}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT8}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option9.html" onClick="form.redirect.value='option9.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT9}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT9}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option10.html" onClick="form.redirect.value='option10.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT10}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT10}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option6.html" onClick="form.redirect.value='option6.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT6}' onMouseOver="info('${html:LANG_IOPT6}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT6}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option7.html" onClick="form.redirect.value='option7.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT7}' onMouseOver="info('${html:LANG_IOPT7}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT7}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option8.html" onClick="form.redirect.value='option8.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT8}' onMouseOver="info('${html:LANG_IOPT8}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT8}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option9.html" onClick="form.redirect.value='option9.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT9}' onMouseOver="info('${html:LANG_IOPT9}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT9}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option10.html" onClick="form.redirect.value='option10.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT10}' onMouseOver="info('${html:LANG_IOPT10}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT10}</a></td>
|
||||
<td class="tabCtrl" align="center"> </td>
|
||||
|
||||
</tr>
|
||||
@@ -98,17 +98,27 @@ ${do:end-if}
|
||||
<input type="hidden" name="redirect" value="">
|
||||
<input type="hidden" name="closeme" value="">
|
||||
|
||||
${LANG_IOPT10}:
|
||||
${LANG_PROXYTYPE}
|
||||
<select name="proxytype"
|
||||
title='${html:LANG_PROXYTYPETIP}' onMouseOver="info('${html:LANG_PROXYTYPETIP}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
<option value=""${ztest:proxytype: selected:}>HTTP</option>
|
||||
<option value="2"${test:proxytype::: selected}>HTTP (CONNECT tunnel)</option>
|
||||
<option value="1"${test:proxytype:: selected}>SOCKS5</option>
|
||||
</select>
|
||||
<br><br>
|
||||
|
||||
${LANG_IOPT10}:
|
||||
<input name="prox" value="${prox}" size="32"
|
||||
onMouseOver="info('${html:LANG_G14}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_G14}' onMouseOver="info('${html:LANG_G14}'); return true" onMouseOut="info(' '); return true"
|
||||
>:
|
||||
<input name="portprox" value="${portprox}" size="4"
|
||||
onMouseOver="info('${html:LANG_G15}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_G15}' onMouseOver="info('${html:LANG_G15}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
<br>
|
||||
|
||||
<input type="checkbox" name="ftpprox" ${checked:ftpprox}
|
||||
onMouseOver="info('${html:LANG_G15c}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_G15c}' onMouseOver="info('${html:LANG_G15c}'); return true" onMouseOut="info(' '); return true"
|
||||
> ${LANG_I47c}
|
||||
<br><br>
|
||||
|
||||
@@ -117,12 +127,12 @@ ${LANG_IOPT10}:
|
||||
<tr><td align="left">
|
||||
<input type="submit" value="${LANG_OK}"
|
||||
onClick="form.closeme.value=1; form.submit(); return false;"
|
||||
onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPOK}' onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td><td align="right">
|
||||
<input type="button" value="${LANG_CANCEL}"
|
||||
onClick="window.close();"
|
||||
onMouseOver="info('${html:LANG_TIPCANCEL}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPCANCEL}' onMouseOver="info('${html:LANG_TIPCANCEL}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td></tr>
|
||||
</table>
|
||||
|
||||
@@ -60,7 +60,7 @@ ${do:if-file-exists:html/index.html}
|
||||
<td>
|
||||
<a href="/step9_opt9.html" target="_blank"
|
||||
onClick="window.open('/step9_opt9.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
|
||||
onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPHELP}' onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info(' '); return true"
|
||||
>${LANG_TIPHELP}</a>
|
||||
</td>
|
||||
${do:end-if}
|
||||
@@ -71,18 +71,18 @@ ${do:end-if}
|
||||
<table class="tableWidth" border="0" width="100%" cellspacing="0">
|
||||
<tr>
|
||||
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option1.html" onClick="form.redirect.value='option1.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT1}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT1}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option2.html" onClick="form.redirect.value='option2.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT2}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT2}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option3.html" onClick="form.redirect.value='option3.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT3}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT3}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option4.html" onClick="form.redirect.value='option4.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT4}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT4}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option5.html" onClick="form.redirect.value='option5.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT5}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT5}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option11.html" onClick="form.redirect.value='option11.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT11}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT11}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option1.html" onClick="form.redirect.value='option1.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT1}' onMouseOver="info('${html:LANG_IOPT1}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT1}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option2.html" onClick="form.redirect.value='option2.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT2}' onMouseOver="info('${html:LANG_IOPT2}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT2}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option3.html" onClick="form.redirect.value='option3.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT3}' onMouseOver="info('${html:LANG_IOPT3}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT3}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option4.html" onClick="form.redirect.value='option4.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT4}' onMouseOver="info('${html:LANG_IOPT4}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT4}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option5.html" onClick="form.redirect.value='option5.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT5}' onMouseOver="info('${html:LANG_IOPT5}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT5}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option11.html" onClick="form.redirect.value='option11.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT11}' onMouseOver="info('${html:LANG_IOPT11}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT11}</a></td>
|
||||
</tr><tr>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option6.html" onClick="form.redirect.value='option6.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT6}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT6}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option7.html" onClick="form.redirect.value='option7.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT7}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT7}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option8.html" onClick="form.redirect.value='option8.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT8}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT8}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option9.html" onClick="form.redirect.value='option9.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT9}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT9}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option10.html" onClick="form.redirect.value='option10.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT10}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT10}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option6.html" onClick="form.redirect.value='option6.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT6}' onMouseOver="info('${html:LANG_IOPT6}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT6}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option7.html" onClick="form.redirect.value='option7.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT7}' onMouseOver="info('${html:LANG_IOPT7}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT7}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option8.html" onClick="form.redirect.value='option8.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT8}' onMouseOver="info('${html:LANG_IOPT8}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT8}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option9.html" onClick="form.redirect.value='option9.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT9}' onMouseOver="info('${html:LANG_IOPT9}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT9}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option10.html" onClick="form.redirect.value='option10.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT10}' onMouseOver="info('${html:LANG_IOPT10}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT10}</a></td>
|
||||
<td class="tabCtrl" align="center"> </td>
|
||||
|
||||
</tr>
|
||||
@@ -112,97 +112,97 @@ ${LANG_W3}
|
||||
|
||||
<td align="left">
|
||||
<input name="ext1" value="${ext1}"
|
||||
onMouseOver="info('${html:LANG_W4}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_W4}' onMouseOver="info('${html:LANG_W4}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td><td align="left">
|
||||
⇔
|
||||
</td><td align="left">
|
||||
<input name="mime1" value="${mime1}"
|
||||
onMouseOver="info('${html:LANG_W5}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_W5}' onMouseOver="info('${html:LANG_W5}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td></tr>
|
||||
<!-- -->
|
||||
<td align="left">
|
||||
<input name="ext2" value="${ext2}"
|
||||
onMouseOver="info('${html:LANG_W4}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_W4}' onMouseOver="info('${html:LANG_W4}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td><td align="left">
|
||||
⇔
|
||||
</td><td align="left">
|
||||
<input name="mime2" value="${mime2}"
|
||||
onMouseOver="info('${html:LANG_W5}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_W5}' onMouseOver="info('${html:LANG_W5}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td></tr>
|
||||
<!-- -->
|
||||
<td align="left">
|
||||
<input name="ext3" value="${ext3}"
|
||||
onMouseOver="info('${html:LANG_W4}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_W4}' onMouseOver="info('${html:LANG_W4}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td><td align="left">
|
||||
⇔
|
||||
</td><td align="left">
|
||||
<input name="mime3" value="${mime3}"
|
||||
onMouseOver="info('${html:LANG_W5}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_W5}' onMouseOver="info('${html:LANG_W5}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td></tr>
|
||||
<!-- -->
|
||||
<td align="left">
|
||||
<input name="ext4" value="${ext4}"
|
||||
onMouseOver="info('${html:LANG_W4}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_W4}' onMouseOver="info('${html:LANG_W4}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td><td align="left">
|
||||
⇔
|
||||
</td><td align="left">
|
||||
<input name="mime4" value="${mime4}"
|
||||
onMouseOver="info('${html:LANG_W5}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_W5}' onMouseOver="info('${html:LANG_W5}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td></tr>
|
||||
<!-- -->
|
||||
<td align="left">
|
||||
<input name="ext5" value="${ext5}"
|
||||
onMouseOver="info('${html:LANG_W4}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_W4}' onMouseOver="info('${html:LANG_W4}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td><td align="left">
|
||||
⇔
|
||||
</td><td align="left">
|
||||
<input name="mime5" value="${mime5}"
|
||||
onMouseOver="info('${html:LANG_W5}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_W5}' onMouseOver="info('${html:LANG_W5}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td></tr>
|
||||
<!-- -->
|
||||
<td align="left">
|
||||
<input name="ext6" value="${ext6}"
|
||||
onMouseOver="info('${html:LANG_W4}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_W4}' onMouseOver="info('${html:LANG_W4}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td><td align="left">
|
||||
⇔
|
||||
</td><td align="left">
|
||||
<input name="mime6" value="${mime6}"
|
||||
onMouseOver="info('${html:LANG_W5}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_W5}' onMouseOver="info('${html:LANG_W5}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td></tr>
|
||||
<!-- -->
|
||||
<td align="left">
|
||||
<input name="ext7" value="${ext7}"
|
||||
onMouseOver="info('${html:LANG_W4}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_W4}' onMouseOver="info('${html:LANG_W4}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td><td align="left">
|
||||
⇔
|
||||
</td><td align="left">
|
||||
<input name="mime7" value="${mime7}"
|
||||
onMouseOver="info('${html:LANG_W5}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_W5}' onMouseOver="info('${html:LANG_W5}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td></tr>
|
||||
<!-- -->
|
||||
<td align="left">
|
||||
<input name="ext8" value="${ext8}"
|
||||
onMouseOver="info('${html:LANG_W4}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_W4}' onMouseOver="info('${html:LANG_W4}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td><td align="left">
|
||||
⇔
|
||||
</td><td align="left">
|
||||
<input name="mime8" value="${mime8}"
|
||||
onMouseOver="info('${html:LANG_W5}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_W5}' onMouseOver="info('${html:LANG_W5}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td></tr>
|
||||
<!-- -->
|
||||
@@ -217,12 +217,12 @@ ${LANG_W3}
|
||||
<tr><td align="left">
|
||||
<input type="submit" value="${LANG_OK}"
|
||||
onClick="form.closeme.value=1; form.submit(); return false;"
|
||||
onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPOK}' onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td><td align="right">
|
||||
<input type="button" value="${LANG_CANCEL}"
|
||||
onClick="window.close();"
|
||||
onMouseOver="info('${html:LANG_TIPCANCEL}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPCANCEL}' onMouseOver="info('${html:LANG_TIPCANCEL}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td></tr>
|
||||
</table>
|
||||
|
||||
@@ -60,7 +60,7 @@ ${do:if-file-exists:html/index.html}
|
||||
<td>
|
||||
<a href="/step9_opt5.html" target="_blank"
|
||||
onClick="window.open('/step9_opt5.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
|
||||
onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPHELP}' onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info(' '); return true"
|
||||
>${LANG_TIPHELP}</a>
|
||||
</td>
|
||||
${do:end-if}
|
||||
@@ -71,18 +71,18 @@ ${do:end-if}
|
||||
<table class="tableWidth" border="0" width="100%" cellspacing="0">
|
||||
<tr>
|
||||
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option1.html" onClick="form.redirect.value='option1.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT1}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT1}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option2.html" onClick="form.redirect.value='option2.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT2}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT2}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option3.html" onClick="form.redirect.value='option3.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT3}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT3}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option4.html" onClick="form.redirect.value='option4.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT4}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT4}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option5.html" onClick="form.redirect.value='option5.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT5}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT5}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option11.html" onClick="form.redirect.value='option11.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT11}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT11}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option1.html" onClick="form.redirect.value='option1.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT1}' onMouseOver="info('${html:LANG_IOPT1}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT1}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option2.html" onClick="form.redirect.value='option2.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT2}' onMouseOver="info('${html:LANG_IOPT2}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT2}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option3.html" onClick="form.redirect.value='option3.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT3}' onMouseOver="info('${html:LANG_IOPT3}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT3}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option4.html" onClick="form.redirect.value='option4.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT4}' onMouseOver="info('${html:LANG_IOPT4}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT4}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option5.html" onClick="form.redirect.value='option5.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT5}' onMouseOver="info('${html:LANG_IOPT5}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT5}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option11.html" onClick="form.redirect.value='option11.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT11}' onMouseOver="info('${html:LANG_IOPT11}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT11}</a></td>
|
||||
</tr><tr>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option6.html" onClick="form.redirect.value='option6.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT6}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT6}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option7.html" onClick="form.redirect.value='option7.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT7}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT7}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option8.html" onClick="form.redirect.value='option8.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT8}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT8}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option9.html" onClick="form.redirect.value='option9.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT9}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT9}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option10.html" onClick="form.redirect.value='option10.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT10}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT10}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option6.html" onClick="form.redirect.value='option6.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT6}' onMouseOver="info('${html:LANG_IOPT6}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT6}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option7.html" onClick="form.redirect.value='option7.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT7}' onMouseOver="info('${html:LANG_IOPT7}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT7}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option8.html" onClick="form.redirect.value='option8.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT8}' onMouseOver="info('${html:LANG_IOPT8}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT8}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option9.html" onClick="form.redirect.value='option9.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT9}' onMouseOver="info('${html:LANG_IOPT9}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT9}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option10.html" onClick="form.redirect.value='option10.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT10}' onMouseOver="info('${html:LANG_IOPT10}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT10}</a></td>
|
||||
<td class="tabCtrl" align="center"> </td>
|
||||
|
||||
</tr>
|
||||
@@ -101,20 +101,20 @@ ${do:end-if}
|
||||
${LANG_I33}
|
||||
<br>
|
||||
<select name="build"
|
||||
onMouseOver="info('${html:LANG_I3}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_I3}' onMouseOver="info('${html:LANG_I3}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
${listid:build:LISTDEF_3}
|
||||
</select>
|
||||
<input type="button" value="${LANG_O2}"
|
||||
onClick="form.build.selectedIndex=14; window.open('option2b.html', 'option2b', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480').wparent=document; form.submit();"
|
||||
onMouseOver="info('${html:LANG_I4}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_I4}' onMouseOver="info('${html:LANG_I4}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
|
||||
<!-- checkboxes -->
|
||||
<table border="0" width="100%" cellspacing="0">
|
||||
<tr><td>
|
||||
<select name="dos"
|
||||
onMouseOver="info('${html:LANG_I8}\r\n${LANG_I8b}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_I8} ${html:LANG_I8b}' onMouseOver="info('${html:LANG_I8}\r\n${LANG_I8b}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
<option value="0"${ztest:dos: selected::}> </option>
|
||||
<option value="1"${ztest:dos:: selected:}>${LANG_I37}</option>
|
||||
@@ -122,19 +122,19 @@ ${listid:build:LISTDEF_3}
|
||||
</select>
|
||||
</td></tr>
|
||||
<tr><td><input type="checkbox" name="errpage" ${checked:errpage}
|
||||
onMouseOver="info('${html:LANG_I9}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_I9}' onMouseOver="info('${html:LANG_I9}'); return true" onMouseOut="info(' '); return true"
|
||||
> ${LANG_I38}</td></tr>
|
||||
<tr><td><input type="checkbox" name="external" ${checked:external}
|
||||
onMouseOver="info('${html:LANG_I29}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_I29}' onMouseOver="info('${html:LANG_I29}'); return true" onMouseOut="info(' '); return true"
|
||||
> ${LANG_I56}</td></tr>
|
||||
<tr><td><input type="checkbox" name="hidepwd" ${checked:hidepwd}
|
||||
onMouseOver="info('${html:LANG_I30}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_I30}' onMouseOver="info('${html:LANG_I30}'); return true" onMouseOut="info(' '); return true"
|
||||
> ${LANG_I66}</td></tr>
|
||||
<tr><td><input type="checkbox" name="hidequery" ${checked:hidequery}
|
||||
onMouseOver="info('${html:LANG_I30b}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_I30b}' onMouseOver="info('${html:LANG_I30b}'); return true" onMouseOut="info(' '); return true"
|
||||
> ${LANG_I67}</td></tr>
|
||||
<tr><td><input type="checkbox" name="nopurge" ${checked:nopurge}
|
||||
onMouseOver="info('${html:LANG_I1a}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_I1a}' onMouseOver="info('${html:LANG_I1a}'); return true" onMouseOut="info(' '); return true"
|
||||
> ${LANG_I57}</td></tr>
|
||||
</table>
|
||||
|
||||
@@ -143,12 +143,12 @@ ${listid:build:LISTDEF_3}
|
||||
<tr><td align="left">
|
||||
<input type="submit" value="${LANG_OK}"
|
||||
onClick="form.closeme.value=1; form.submit(); return false;"
|
||||
onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPOK}' onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td><td align="right">
|
||||
<input type="button" value="${LANG_CANCEL}"
|
||||
onClick="window.close();"
|
||||
onMouseOver="info('${html:LANG_TIPCANCEL}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPCANCEL}' onMouseOver="info('${html:LANG_TIPCANCEL}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td></tr>
|
||||
</table>
|
||||
|
||||
@@ -70,7 +70,7 @@ ${do:if-file-exists:html/index.html}
|
||||
<td>
|
||||
<a href="/step9_opt5.html" target="_blank"
|
||||
onClick="window.open('/step9_opt5.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
|
||||
onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPHELP}' onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info(' '); return true"
|
||||
>${LANG_TIPHELP}</a>
|
||||
</td>
|
||||
${do:end-if}
|
||||
@@ -107,12 +107,12 @@ ${LANG_Q3}
|
||||
${do:output-mode:html-urlescaped}
|
||||
onClick="if (confirm(str_replace(str_replace('${LANG_DIAL7}', '%20', ' '), '%0a', ' '))) { form.closeme.value=1; form.submit(); } return false;"
|
||||
${do:output-mode:}
|
||||
onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPOK}' onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td><td align="right">
|
||||
<input type="button" value="${LANG_CANCEL}"
|
||||
onClick="window.close();"
|
||||
onMouseOver="info('${html:LANG_TIPCANCEL}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPCANCEL}' onMouseOver="info('${html:LANG_TIPCANCEL}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td></tr>
|
||||
</table>
|
||||
|
||||
@@ -60,7 +60,7 @@ ${do:if-file-exists:html/index.html}
|
||||
<td>
|
||||
<a href="/step9_opt10.html" target="_blank"
|
||||
onClick="window.open('/step9_opt10.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
|
||||
onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPHELP}' onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info(' '); return true"
|
||||
>${LANG_TIPHELP}</a>
|
||||
</td>
|
||||
${do:end-if}
|
||||
@@ -71,18 +71,18 @@ ${do:end-if}
|
||||
<table class="tableWidth" border="0" width="100%" cellspacing="0">
|
||||
<tr>
|
||||
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option1.html" onClick="form.redirect.value='option1.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT1}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT1}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option2.html" onClick="form.redirect.value='option2.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT2}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT2}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option3.html" onClick="form.redirect.value='option3.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT3}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT3}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option4.html" onClick="form.redirect.value='option4.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT4}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT4}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option5.html" onClick="form.redirect.value='option5.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT5}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT5}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option11.html" onClick="form.redirect.value='option11.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT11}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT11}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option1.html" onClick="form.redirect.value='option1.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT1}' onMouseOver="info('${html:LANG_IOPT1}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT1}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option2.html" onClick="form.redirect.value='option2.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT2}' onMouseOver="info('${html:LANG_IOPT2}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT2}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option3.html" onClick="form.redirect.value='option3.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT3}' onMouseOver="info('${html:LANG_IOPT3}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT3}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option4.html" onClick="form.redirect.value='option4.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT4}' onMouseOver="info('${html:LANG_IOPT4}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT4}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option5.html" onClick="form.redirect.value='option5.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT5}' onMouseOver="info('${html:LANG_IOPT5}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT5}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option11.html" onClick="form.redirect.value='option11.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT11}' onMouseOver="info('${html:LANG_IOPT11}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT11}</a></td>
|
||||
</tr><tr>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option6.html" onClick="form.redirect.value='option6.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT6}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT6}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option7.html" onClick="form.redirect.value='option7.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT7}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT7}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option8.html" onClick="form.redirect.value='option8.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT8}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT8}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option9.html" onClick="form.redirect.value='option9.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT9}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT9}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option10.html" onClick="form.redirect.value='option10.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT10}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT10}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option6.html" onClick="form.redirect.value='option6.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT6}' onMouseOver="info('${html:LANG_IOPT6}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT6}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option7.html" onClick="form.redirect.value='option7.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT7}' onMouseOver="info('${html:LANG_IOPT7}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT7}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option8.html" onClick="form.redirect.value='option8.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT8}' onMouseOver="info('${html:LANG_IOPT8}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT8}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option9.html" onClick="form.redirect.value='option9.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT9}' onMouseOver="info('${html:LANG_IOPT9}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT9}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option10.html" onClick="form.redirect.value='option10.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT10}' onMouseOver="info('${html:LANG_IOPT10}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT10}</a></td>
|
||||
<td class="tabCtrl" align="center"> </td>
|
||||
|
||||
</tr>
|
||||
@@ -104,7 +104,7 @@ ${LANG_I40c}
|
||||
<!-- checkboxes -->
|
||||
<table border="0" width="100%" cellspacing="0">
|
||||
<tr><td><input type="checkbox" name="cache" ${checked:cache}
|
||||
onMouseOver="info('${html:LANG_I5}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_I5}' onMouseOver="info('${html:LANG_I5}'); return true" onMouseOut="info(' '); return true"
|
||||
> ${LANG_I34}</td></tr>
|
||||
</table>
|
||||
<br>
|
||||
@@ -112,7 +112,7 @@ ${LANG_I40c}
|
||||
${LANG_I39}
|
||||
<br>
|
||||
<select name="filter"
|
||||
onMouseOver="info('${html:LANG_I29}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_I29}' onMouseOver="info('${html:LANG_I29}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
${listid:filter:LISTDEF_4}
|
||||
</select>
|
||||
@@ -121,7 +121,7 @@ ${listid:filter:LISTDEF_4}
|
||||
${LANG_I40}
|
||||
<br>
|
||||
<select name="travel"
|
||||
onMouseOver="info('${html:LANG_I11}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_I11}' onMouseOver="info('${html:LANG_I11}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
${listid:travel:LISTDEF_5}
|
||||
</select>
|
||||
@@ -130,7 +130,7 @@ ${listid:travel:LISTDEF_5}
|
||||
${LANG_I40b}
|
||||
<br>
|
||||
<select name="travel2"
|
||||
onMouseOver="info('${html:LANG_I11b}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_I11b}' onMouseOver="info('${html:LANG_I11b}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
${listid:travel2:LISTDEF_6}
|
||||
</select>
|
||||
@@ -139,7 +139,7 @@ ${listid:travel2:LISTDEF_6}
|
||||
${LANG_I40e}
|
||||
<br>
|
||||
<select name="travel3"
|
||||
onMouseOver="info('${html:LANG_I11c}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_I11c}' onMouseOver="info('${html:LANG_I11c}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
${listid:travel3:LISTDEF_11}
|
||||
</select>
|
||||
@@ -148,7 +148,7 @@ ${listid:travel3:LISTDEF_11}
|
||||
<!-- checkboxes -->
|
||||
<table border="0" width="100%" cellspacing="0">
|
||||
<tr><td><input type="checkbox" name="windebug" ${checked:windebug}
|
||||
onMouseOver="info('${html:LANG_I1h}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_I1h}' onMouseOver="info('${html:LANG_I1h}'); return true" onMouseOut="info(' '); return true"
|
||||
> ${LANG_I40d}</td></tr>
|
||||
</table>
|
||||
<br>
|
||||
@@ -158,12 +158,12 @@ ${listid:travel3:LISTDEF_11}
|
||||
<tr><td align="left">
|
||||
<input type="submit" value="${LANG_OK}"
|
||||
onClick="form.closeme.value=1; form.submit(); return false;"
|
||||
onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPOK}' onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td><td align="right">
|
||||
<input type="button" value="${LANG_CANCEL}"
|
||||
onClick="window.close();"
|
||||
onMouseOver="info('${html:LANG_TIPCANCEL}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPCANCEL}' onMouseOver="info('${html:LANG_TIPCANCEL}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td></tr>
|
||||
</table>
|
||||
|
||||
@@ -60,7 +60,7 @@ ${do:if-file-exists:html/index.html}
|
||||
<td>
|
||||
<a href="/step9_opt3.html" target="_blank"
|
||||
onClick="window.open('/step9_opt3.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
|
||||
onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPHELP}' onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info(' '); return true"
|
||||
>${LANG_TIPHELP}</a>
|
||||
</td>
|
||||
${do:end-if}
|
||||
@@ -71,18 +71,18 @@ ${do:end-if}
|
||||
<table class="tableWidth" border="0" width="100%" cellspacing="0">
|
||||
<tr>
|
||||
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option1.html" onClick="form.redirect.value='option1.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT1}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT1}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option2.html" onClick="form.redirect.value='option2.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT2}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT2}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option3.html" onClick="form.redirect.value='option3.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT3}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT3}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option4.html" onClick="form.redirect.value='option4.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT4}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT4}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option5.html" onClick="form.redirect.value='option5.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT5}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT5}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option11.html" onClick="form.redirect.value='option11.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT11}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT11}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option1.html" onClick="form.redirect.value='option1.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT1}' onMouseOver="info('${html:LANG_IOPT1}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT1}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option2.html" onClick="form.redirect.value='option2.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT2}' onMouseOver="info('${html:LANG_IOPT2}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT2}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option3.html" onClick="form.redirect.value='option3.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT3}' onMouseOver="info('${html:LANG_IOPT3}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT3}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option4.html" onClick="form.redirect.value='option4.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT4}' onMouseOver="info('${html:LANG_IOPT4}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT4}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option5.html" onClick="form.redirect.value='option5.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT5}' onMouseOver="info('${html:LANG_IOPT5}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT5}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option11.html" onClick="form.redirect.value='option11.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT11}' onMouseOver="info('${html:LANG_IOPT11}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT11}</a></td>
|
||||
</tr><tr>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option6.html" onClick="form.redirect.value='option6.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT6}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT6}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option7.html" onClick="form.redirect.value='option7.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT7}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT7}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option8.html" onClick="form.redirect.value='option8.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT8}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT8}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option9.html" onClick="form.redirect.value='option9.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT9}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT9}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option10.html" onClick="form.redirect.value='option10.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT10}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT10}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option6.html" onClick="form.redirect.value='option6.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT6}' onMouseOver="info('${html:LANG_IOPT6}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT6}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option7.html" onClick="form.redirect.value='option7.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT7}' onMouseOver="info('${html:LANG_IOPT7}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT7}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option8.html" onClick="form.redirect.value='option8.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT8}' onMouseOver="info('${html:LANG_IOPT8}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT8}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option9.html" onClick="form.redirect.value='option9.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT9}' onMouseOver="info('${html:LANG_IOPT9}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT9}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option10.html" onClick="form.redirect.value='option10.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT10}' onMouseOver="info('${html:LANG_IOPT10}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT10}</a></td>
|
||||
<td class="tabCtrl" align="center"> </td>
|
||||
|
||||
</tr>
|
||||
@@ -104,11 +104,11 @@ ${do:end-if}
|
||||
${LANG_I44}
|
||||
</td><td>
|
||||
<input name="connexion" value="${connexion}" size="4"
|
||||
onMouseOver="info('${html:LANG_I12}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_I12}' onMouseOver="info('${html:LANG_I12}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td></tr><tr><td></td><td>
|
||||
<input type="checkbox" name="ka" ${checked:ka}
|
||||
onMouseOver="info('${html:LANG_I47f}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_I47f}' onMouseOver="info('${html:LANG_I47f}'); return true" onMouseOut="info(' '); return true"
|
||||
> ${LANG_I47e}
|
||||
</td></tr>
|
||||
|
||||
@@ -116,11 +116,11 @@ ${LANG_I44}
|
||||
${LANG_I47d}
|
||||
</td><td>
|
||||
<input name="timeout" value="${timeout}" size="4"
|
||||
onMouseOver="info('${html:LANG_I13}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_I13}' onMouseOver="info('${html:LANG_I13}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td></tr><tr><td></td><td>
|
||||
<input type="checkbox" name="remt" ${checked:remt}
|
||||
onMouseOver="info('${html:LANG_I14}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_I14}' onMouseOver="info('${html:LANG_I14}'); return true" onMouseOut="info(' '); return true"
|
||||
> ${LANG_I45}
|
||||
</td></tr>
|
||||
|
||||
@@ -128,7 +128,7 @@ ${LANG_I47d}
|
||||
${LANG_I48}
|
||||
</td><td>
|
||||
<input name="retry" value="${retry}" size="4"
|
||||
onMouseOver="info('${html:LANG_I17}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_I17}' onMouseOver="info('${html:LANG_I17}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td></tr>
|
||||
|
||||
@@ -136,11 +136,11 @@ ${LANG_I48}
|
||||
${LANG_I46}
|
||||
</td><td>
|
||||
<input name="rate" value="${rate}" size="4"
|
||||
onMouseOver="info('${html:LANG_I15}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_I15}' onMouseOver="info('${html:LANG_I15}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td></tr><tr><td></td><td>
|
||||
<input type="checkbox" name="rems" ${checked:rems}
|
||||
onMouseOver="info('${html:LANG_I16}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_I16}' onMouseOver="info('${html:LANG_I16}'); return true" onMouseOut="info(' '); return true"
|
||||
> ${LANG_I47}
|
||||
</td></tr>
|
||||
|
||||
@@ -151,12 +151,12 @@ ${LANG_I46}
|
||||
<tr><td align="left">
|
||||
<input type="submit" value="${LANG_OK}"
|
||||
onClick="form.closeme.value=1; form.submit(); return false;"
|
||||
onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPOK}' onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td><td align="right">
|
||||
<input type="button" value="${LANG_CANCEL}"
|
||||
onClick="window.close();"
|
||||
onMouseOver="info('${html:LANG_TIPCANCEL}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPCANCEL}' onMouseOver="info('${html:LANG_TIPCANCEL}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td></tr>
|
||||
</table>
|
||||
|
||||
@@ -60,7 +60,7 @@ ${do:if-file-exists:html/index.html}
|
||||
<td>
|
||||
<a href="/step9_opt2.html" target="_blank"
|
||||
onClick="window.open('/step9_opt2.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
|
||||
onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPHELP}' onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info(' '); return true"
|
||||
>${LANG_TIPHELP}</a>
|
||||
</td>
|
||||
${do:end-if}
|
||||
@@ -71,18 +71,18 @@ ${do:end-if}
|
||||
<table class="tableWidth" border="0" width="100%" cellspacing="0">
|
||||
<tr>
|
||||
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option1.html" onClick="form.redirect.value='option1.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT1}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT1}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option2.html" onClick="form.redirect.value='option2.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT2}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT2}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option3.html" onClick="form.redirect.value='option3.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT3}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT3}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option4.html" onClick="form.redirect.value='option4.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT4}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT4}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option5.html" onClick="form.redirect.value='option5.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT5}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT5}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option11.html" onClick="form.redirect.value='option11.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT11}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT11}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option1.html" onClick="form.redirect.value='option1.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT1}' onMouseOver="info('${html:LANG_IOPT1}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT1}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option2.html" onClick="form.redirect.value='option2.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT2}' onMouseOver="info('${html:LANG_IOPT2}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT2}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option3.html" onClick="form.redirect.value='option3.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT3}' onMouseOver="info('${html:LANG_IOPT3}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT3}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option4.html" onClick="form.redirect.value='option4.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT4}' onMouseOver="info('${html:LANG_IOPT4}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT4}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option5.html" onClick="form.redirect.value='option5.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT5}' onMouseOver="info('${html:LANG_IOPT5}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT5}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option11.html" onClick="form.redirect.value='option11.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT11}' onMouseOver="info('${html:LANG_IOPT11}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT11}</a></td>
|
||||
</tr><tr>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option6.html" onClick="form.redirect.value='option6.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT6}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT6}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option7.html" onClick="form.redirect.value='option7.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT7}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT7}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option8.html" onClick="form.redirect.value='option8.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT8}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT8}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option9.html" onClick="form.redirect.value='option9.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT9}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT9}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option10.html" onClick="form.redirect.value='option10.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT10}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT10}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option6.html" onClick="form.redirect.value='option6.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT6}' onMouseOver="info('${html:LANG_IOPT6}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT6}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option7.html" onClick="form.redirect.value='option7.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT7}' onMouseOver="info('${html:LANG_IOPT7}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT7}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option8.html" onClick="form.redirect.value='option8.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT8}' onMouseOver="info('${html:LANG_IOPT8}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT8}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option9.html" onClick="form.redirect.value='option9.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT9}' onMouseOver="info('${html:LANG_IOPT9}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT9}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option10.html" onClick="form.redirect.value='option10.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT10}' onMouseOver="info('${html:LANG_IOPT10}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT10}</a></td>
|
||||
<td class="tabCtrl" align="center"> </td>
|
||||
|
||||
</tr>
|
||||
@@ -104,7 +104,7 @@ ${do:end-if}
|
||||
${LANG_G32}
|
||||
</td><td>
|
||||
<input name="depth" value="${depth}" size="4"
|
||||
onMouseOver="info('${html:LANG_I1g}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_I1g}' onMouseOver="info('${html:LANG_I1g}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td></tr>
|
||||
|
||||
@@ -112,7 +112,7 @@ ${LANG_G32}
|
||||
${LANG_G32b}
|
||||
</td><td>
|
||||
<input name="depth2" value="${depth2}" size="4"
|
||||
onMouseOver="info('${html:LANG_I1g2}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_I1g2}' onMouseOver="info('${html:LANG_I1g2}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td></tr>
|
||||
|
||||
@@ -120,7 +120,7 @@ ${LANG_G32b}
|
||||
${LANG_I50}
|
||||
</td><td>
|
||||
<input name="maxhtml" value="${maxhtml}" size="4"
|
||||
onMouseOver="info('${html:LANG_I18}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_I18}' onMouseOver="info('${html:LANG_I18}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td></tr>
|
||||
|
||||
@@ -128,7 +128,7 @@ ${LANG_I50}
|
||||
${LANG_I50b}
|
||||
</td><td>
|
||||
<input name="othermax" value="${othermax}" size="4"
|
||||
onMouseOver="info('${html:LANG_I19}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_I19}' onMouseOver="info('${html:LANG_I19}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td></tr>
|
||||
|
||||
@@ -136,7 +136,7 @@ ${LANG_I50b}
|
||||
${LANG_I51}
|
||||
</td><td>
|
||||
<input name="sizemax" value="${sizemax}" size="4"
|
||||
onMouseOver="info('${html:LANG_I20}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_I20}' onMouseOver="info('${html:LANG_I20}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td></tr>
|
||||
|
||||
@@ -144,7 +144,15 @@ ${LANG_I51}
|
||||
${LANG_I65}
|
||||
</td><td>
|
||||
<input name="pausebytes" value="${pausebytes}" size="4"
|
||||
onMouseOver="info('${html:LANG_I20b}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_I20b}' onMouseOver="info('${html:LANG_I20b}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td></tr>
|
||||
|
||||
<tr><td>
|
||||
${LANG_PAUSEFILES}
|
||||
</td><td>
|
||||
<input name="pausefiles" value="${pausefiles}" size="8"
|
||||
title='${html:LANG_PAUSEFILESTIP}' onMouseOver="info('${html:LANG_PAUSEFILESTIP}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td></tr>
|
||||
|
||||
@@ -152,7 +160,7 @@ ${LANG_I65}
|
||||
${LANG_I52}
|
||||
</td><td>
|
||||
<input name="maxtime" value="${maxtime}" size="4"
|
||||
onMouseOver="info('${html:LANG_I21}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_I21}' onMouseOver="info('${html:LANG_I21}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td></tr>
|
||||
|
||||
@@ -160,7 +168,7 @@ ${LANG_I52}
|
||||
${LANG_I54}
|
||||
</td><td>
|
||||
<input name="maxrate" value="${maxrate}" size="4"
|
||||
onMouseOver="info('${html:LANG_I22}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_I22}' onMouseOver="info('${html:LANG_I22}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td></tr>
|
||||
|
||||
@@ -168,7 +176,7 @@ ${LANG_I54}
|
||||
${LANG_I64}
|
||||
</td><td>
|
||||
<input name="maxconn" value="${maxconn}" size="4"
|
||||
onMouseOver="info('${html:LANG_I22b}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_I22b}' onMouseOver="info('${html:LANG_I22b}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td></tr>
|
||||
|
||||
@@ -176,7 +184,7 @@ ${LANG_I64}
|
||||
${LANG_I64b}
|
||||
</td><td>
|
||||
<input name="maxlinks" value="${maxlinks}" size="4"
|
||||
onMouseOver="info('${html:LANG_I22c}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_I22c}' onMouseOver="info('${html:LANG_I22c}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td></tr>
|
||||
|
||||
@@ -185,12 +193,12 @@ ${LANG_I64b}
|
||||
<tr><td align="left">
|
||||
<input type="submit" value="${LANG_OK}"
|
||||
onClick="form.closeme.value=1; form.submit(); return false;"
|
||||
onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPOK}' onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td><td align="right">
|
||||
<input type="button" value="${LANG_CANCEL}"
|
||||
onClick="window.close();"
|
||||
onMouseOver="info('${html:LANG_TIPCANCEL}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPCANCEL}' onMouseOver="info('${html:LANG_TIPCANCEL}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td></tr>
|
||||
</table>
|
||||
|
||||
@@ -60,7 +60,7 @@ ${do:if-file-exists:html/index.html}
|
||||
<td>
|
||||
<a href="/step9_opt8.html" target="_blank"
|
||||
onClick="window.open('/step9_opt8.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
|
||||
onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPHELP}' onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info(' '); return true"
|
||||
>${LANG_TIPHELP}</a>
|
||||
</td>
|
||||
${do:end-if}
|
||||
@@ -71,18 +71,18 @@ ${do:end-if}
|
||||
<table class="tableWidth" border="0" width="100%" cellspacing="0">
|
||||
<tr>
|
||||
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option1.html" onClick="form.redirect.value='option1.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT1}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT1}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option2.html" onClick="form.redirect.value='option2.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT2}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT2}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option3.html" onClick="form.redirect.value='option3.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT3}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT3}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option4.html" onClick="form.redirect.value='option4.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT4}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT4}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option5.html" onClick="form.redirect.value='option5.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT5}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT5}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option11.html" onClick="form.redirect.value='option11.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT11}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT11}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option1.html" onClick="form.redirect.value='option1.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT1}' onMouseOver="info('${html:LANG_IOPT1}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT1}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option2.html" onClick="form.redirect.value='option2.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT2}' onMouseOver="info('${html:LANG_IOPT2}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT2}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option3.html" onClick="form.redirect.value='option3.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT3}' onMouseOver="info('${html:LANG_IOPT3}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT3}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option4.html" onClick="form.redirect.value='option4.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT4}' onMouseOver="info('${html:LANG_IOPT4}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT4}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option5.html" onClick="form.redirect.value='option5.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT5}' onMouseOver="info('${html:LANG_IOPT5}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT5}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option11.html" onClick="form.redirect.value='option11.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT11}' onMouseOver="info('${html:LANG_IOPT11}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT11}</a></td>
|
||||
</tr><tr>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option6.html" onClick="form.redirect.value='option6.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT6}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT6}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option7.html" onClick="form.redirect.value='option7.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT7}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT7}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option8.html" onClick="form.redirect.value='option8.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT8}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT8}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option9.html" onClick="form.redirect.value='option9.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT9}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT9}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option10.html" onClick="form.redirect.value='option10.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT10}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT10}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option6.html" onClick="form.redirect.value='option6.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT6}' onMouseOver="info('${html:LANG_IOPT6}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT6}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option7.html" onClick="form.redirect.value='option7.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT7}' onMouseOver="info('${html:LANG_IOPT7}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT7}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option8.html" onClick="form.redirect.value='option8.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT8}' onMouseOver="info('${html:LANG_IOPT8}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT8}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option9.html" onClick="form.redirect.value='option9.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT9}' onMouseOver="info('${html:LANG_IOPT9}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT9}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option10.html" onClick="form.redirect.value='option10.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT10}' onMouseOver="info('${html:LANG_IOPT10}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT10}</a></td>
|
||||
<td class="tabCtrl" align="center"> </td>
|
||||
|
||||
</tr>
|
||||
@@ -104,7 +104,7 @@ ${do:end-if}
|
||||
${LANG_I43}
|
||||
</td><td>
|
||||
<input name="user" value="${user}" size="60"
|
||||
onMouseOver="info('${html:LANG_I23}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_I23}' onMouseOver="info('${html:LANG_I23}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td></tr>
|
||||
|
||||
@@ -112,7 +112,7 @@ ${LANG_I43}
|
||||
${LANG_I43b}
|
||||
</td><td>
|
||||
<input name="footer" value="${footer}" size="60"
|
||||
onMouseOver="info('${html:LANG_I23b}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_I23b}' onMouseOver="info('${html:LANG_I23b}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td></tr>
|
||||
|
||||
@@ -123,12 +123,12 @@ ${LANG_I43b}
|
||||
<tr><td align="left">
|
||||
<input type="submit" value="${LANG_OK}"
|
||||
onClick="form.closeme.value=1; form.submit(); return false;"
|
||||
onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPOK}' onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td><td align="right">
|
||||
<input type="button" value="${LANG_CANCEL}"
|
||||
onClick="window.close();"
|
||||
onMouseOver="info('${html:LANG_TIPCANCEL}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPCANCEL}' onMouseOver="info('${html:LANG_TIPCANCEL}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td></tr>
|
||||
</table>
|
||||
|
||||
@@ -60,7 +60,7 @@ ${do:if-file-exists:html/index.html}
|
||||
<td>
|
||||
<a href="/step9_opt4.html" target="_blank"
|
||||
onClick="window.open('/step9_opt4.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
|
||||
onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPHELP}' onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info(' '); return true"
|
||||
>${LANG_TIPHELP}</a>
|
||||
</td>
|
||||
${do:end-if}
|
||||
@@ -71,18 +71,18 @@ ${do:end-if}
|
||||
<table class="tableWidth" border="0" width="100%" cellspacing="0">
|
||||
<tr>
|
||||
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option1.html" onClick="form.redirect.value='option1.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT1}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT1}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option2.html" onClick="form.redirect.value='option2.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT2}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT2}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option3.html" onClick="form.redirect.value='option3.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT3}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT3}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option4.html" onClick="form.redirect.value='option4.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT4}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT4}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option5.html" onClick="form.redirect.value='option5.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT5}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT5}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option11.html" onClick="form.redirect.value='option11.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT11}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT11}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option1.html" onClick="form.redirect.value='option1.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT1}' onMouseOver="info('${html:LANG_IOPT1}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT1}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option2.html" onClick="form.redirect.value='option2.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT2}' onMouseOver="info('${html:LANG_IOPT2}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT2}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option3.html" onClick="form.redirect.value='option3.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT3}' onMouseOver="info('${html:LANG_IOPT3}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT3}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option4.html" onClick="form.redirect.value='option4.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT4}' onMouseOver="info('${html:LANG_IOPT4}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT4}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option5.html" onClick="form.redirect.value='option5.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT5}' onMouseOver="info('${html:LANG_IOPT5}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT5}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option11.html" onClick="form.redirect.value='option11.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT11}' onMouseOver="info('${html:LANG_IOPT11}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT11}</a></td>
|
||||
</tr><tr>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option6.html" onClick="form.redirect.value='option6.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT6}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT6}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option7.html" onClick="form.redirect.value='option7.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT7}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT7}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option8.html" onClick="form.redirect.value='option8.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT8}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT8}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option9.html" onClick="form.redirect.value='option9.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT9}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT9}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option10.html" onClick="form.redirect.value='option10.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT10}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT10}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option6.html" onClick="form.redirect.value='option6.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT6}' onMouseOver="info('${html:LANG_IOPT6}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT6}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option7.html" onClick="form.redirect.value='option7.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT7}' onMouseOver="info('${html:LANG_IOPT7}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT7}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option8.html" onClick="form.redirect.value='option8.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT8}' onMouseOver="info('${html:LANG_IOPT8}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT8}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option9.html" onClick="form.redirect.value='option9.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT9}' onMouseOver="info('${html:LANG_IOPT9}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT9}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option10.html" onClick="form.redirect.value='option10.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT10}' onMouseOver="info('${html:LANG_IOPT10}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT10}</a></td>
|
||||
<td class="tabCtrl" align="center"> </td>
|
||||
|
||||
</tr>
|
||||
@@ -102,7 +102,7 @@ ${do:end-if}
|
||||
${LANG_B10}
|
||||
</tt>
|
||||
<textarea name="url2" cols="60" rows="8"
|
||||
onMouseOver="info('${html:LANG_C3}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_C3}' onMouseOver="info('${html:LANG_C3}'); return true" onMouseOut="info(' '); return true"
|
||||
>${url2}</textarea>
|
||||
|
||||
<br>
|
||||
@@ -115,12 +115,12 @@ ${LANG_B13}
|
||||
<tr><td align="left">
|
||||
<input type="submit" value="${LANG_OK}"
|
||||
onClick="form.closeme.value=1; form.submit(); return false;"
|
||||
onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPOK}' onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td><td align="right">
|
||||
<input type="button" value="${LANG_CANCEL}"
|
||||
onClick="window.close();"
|
||||
onMouseOver="info('${html:LANG_TIPCANCEL}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPCANCEL}' onMouseOver="info('${html:LANG_TIPCANCEL}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td></tr>
|
||||
</table>
|
||||
|
||||
@@ -60,7 +60,7 @@ ${do:if-file-exists:html/index.html}
|
||||
<td>
|
||||
<a href="/step9_opt6.html" target="_blank"
|
||||
onClick="window.open('/step9_opt6.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
|
||||
onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPHELP}' onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info(' '); return true"
|
||||
>${LANG_TIPHELP}</a>
|
||||
</td>
|
||||
${do:end-if}
|
||||
@@ -71,18 +71,18 @@ ${do:end-if}
|
||||
<table class="tableWidth" border="0" width="100%" cellspacing="0">
|
||||
<tr>
|
||||
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option1.html" onClick="form.redirect.value='option1.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT1}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT1}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option2.html" onClick="form.redirect.value='option2.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT2}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT2}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option3.html" onClick="form.redirect.value='option3.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT3}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT3}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option4.html" onClick="form.redirect.value='option4.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT4}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT4}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option5.html" onClick="form.redirect.value='option5.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT5}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT5}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option11.html" onClick="form.redirect.value='option11.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT11}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT11}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option1.html" onClick="form.redirect.value='option1.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT1}' onMouseOver="info('${html:LANG_IOPT1}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT1}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option2.html" onClick="form.redirect.value='option2.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT2}' onMouseOver="info('${html:LANG_IOPT2}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT2}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option3.html" onClick="form.redirect.value='option3.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT3}' onMouseOver="info('${html:LANG_IOPT3}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT3}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option4.html" onClick="form.redirect.value='option4.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT4}' onMouseOver="info('${html:LANG_IOPT4}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT4}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option5.html" onClick="form.redirect.value='option5.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT5}' onMouseOver="info('${html:LANG_IOPT5}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT5}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option11.html" onClick="form.redirect.value='option11.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT11}' onMouseOver="info('${html:LANG_IOPT11}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT11}</a></td>
|
||||
</tr><tr>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option6.html" onClick="form.redirect.value='option6.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT6}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT6}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option7.html" onClick="form.redirect.value='option7.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT7}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT7}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option8.html" onClick="form.redirect.value='option8.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT8}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT8}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option9.html" onClick="form.redirect.value='option9.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT9}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT9}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option10.html" onClick="form.redirect.value='option10.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT10}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT10}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option6.html" onClick="form.redirect.value='option6.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT6}' onMouseOver="info('${html:LANG_IOPT6}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT6}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option7.html" onClick="form.redirect.value='option7.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT7}' onMouseOver="info('${html:LANG_IOPT7}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT7}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option8.html" onClick="form.redirect.value='option8.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT8}' onMouseOver="info('${html:LANG_IOPT8}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT8}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option9.html" onClick="form.redirect.value='option9.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT9}' onMouseOver="info('${html:LANG_IOPT9}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT9}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option10.html" onClick="form.redirect.value='option10.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT10}' onMouseOver="info('${html:LANG_IOPT10}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT10}</a></td>
|
||||
<td class="tabCtrl" align="center"> </td>
|
||||
|
||||
</tr>
|
||||
@@ -99,50 +99,77 @@ ${do:end-if}
|
||||
<input type="hidden" name="closeme" value="">
|
||||
|
||||
<input type="checkbox" name="cookies" ${checked:cookies}
|
||||
onMouseOver="info('${html:LANG_I1b}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_I1b}' onMouseOver="info('${html:LANG_I1b}'); return true" onMouseOut="info(' '); return true"
|
||||
> ${LANG_I58}
|
||||
<br><br>
|
||||
|
||||
${LANG_COOKIEFILE}
|
||||
<input name="cookiesfile" value="${cookiesfile}" size="40"
|
||||
title='${html:LANG_COOKIEFILETIP}' onMouseOver="info('${html:LANG_COOKIEFILETIP}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
<br><br>
|
||||
|
||||
${LANG_I59}
|
||||
<br>
|
||||
<select name="checktype"
|
||||
onMouseOver="info('${html:LANG_I1c}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_I1c}' onMouseOver="info('${html:LANG_I1c}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
${listid:checktype:LISTDEF_7}
|
||||
</select>
|
||||
<br><br>
|
||||
|
||||
<input type="checkbox" name="parsejava" ${checked:parsejava}
|
||||
onMouseOver="info('${html:LANG_I1d}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_I1d}' onMouseOver="info('${html:LANG_I1d}'); return true" onMouseOut="info(' '); return true"
|
||||
> ${LANG_I60}
|
||||
<br><br>
|
||||
|
||||
${LANG_I55}
|
||||
<br>
|
||||
<select name="robots"
|
||||
onMouseOver="info('${html:LANG_I28}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_I28}' onMouseOver="info('${html:LANG_I28}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
${listid:robots:LISTDEF_8}
|
||||
</select>
|
||||
<br><br>
|
||||
|
||||
<input type="checkbox" name="updhack" ${checked:updhack}
|
||||
onMouseOver="info('${html:LANG_I1k}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_I1k}' onMouseOver="info('${html:LANG_I1k}'); return true" onMouseOut="info(' '); return true"
|
||||
> ${LANG_I62b}
|
||||
<br><br>
|
||||
|
||||
<input type="checkbox" name="urlhack" ${checked:urlhack}
|
||||
onMouseOver="info('${html:LANG_I1k2}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_I1k2}' onMouseOver="info('${html:LANG_I1k2}'); return true" onMouseOut="info(' '); return true"
|
||||
> ${LANG_I62b2}
|
||||
<br><br>
|
||||
|
||||
<input type="checkbox" name="keepwww" ${checked:keepwww}
|
||||
title='${html:LANG_KEEPWWWTIP}' onMouseOver="info('${html:LANG_KEEPWWWTIP}'); return true" onMouseOut="info(' '); return true"
|
||||
> ${LANG_KEEPWWW}
|
||||
<br><br>
|
||||
|
||||
<input type="checkbox" name="keepslashes" ${checked:keepslashes}
|
||||
title='${html:LANG_KEEPSLASHESTIP}' onMouseOver="info('${html:LANG_KEEPSLASHESTIP}'); return true" onMouseOut="info(' '); return true"
|
||||
> ${LANG_KEEPSLASHES}
|
||||
<br><br>
|
||||
|
||||
<input type="checkbox" name="keepqueryorder" ${checked:keepqueryorder}
|
||||
title='${html:LANG_KEEPQUERYORDERTIP}' onMouseOver="info('${html:LANG_KEEPQUERYORDERTIP}'); return true" onMouseOut="info(' '); return true"
|
||||
> ${LANG_KEEPQUERYORDER}
|
||||
<br><br>
|
||||
|
||||
${LANG_STRIPQUERY}
|
||||
<input name="stripquery" value="${stripquery}" size="40"
|
||||
title='${html:LANG_STRIPQUERYTIP}' onMouseOver="info('${html:LANG_STRIPQUERYTIP}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
<br><br>
|
||||
|
||||
<input type="checkbox" name="toler" ${checked:toler}
|
||||
onMouseOver="info('${html:LANG_I1i}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_I1i}' onMouseOver="info('${html:LANG_I1i}'); return true" onMouseOut="info(' '); return true"
|
||||
> ${LANG_I62}
|
||||
<br><br>
|
||||
|
||||
<input type="checkbox" name="http10" ${checked:http10}
|
||||
onMouseOver="info('${html:LANG_I1j}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_I1j}' onMouseOver="info('${html:LANG_I1j}'); return true" onMouseOut="info(' '); return true"
|
||||
> ${LANG_I63}
|
||||
<br><br>
|
||||
|
||||
@@ -152,12 +179,12 @@ ${listid:robots:LISTDEF_8}
|
||||
<tr><td align="left">
|
||||
<input type="submit" value="${LANG_OK}"
|
||||
onClick="form.closeme.value=1; form.submit(); return false;"
|
||||
onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPOK}' onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td><td align="right">
|
||||
<input type="button" value="${LANG_CANCEL}"
|
||||
onClick="window.close();"
|
||||
onMouseOver="info('${html:LANG_TIPCANCEL}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPCANCEL}' onMouseOver="info('${html:LANG_TIPCANCEL}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td></tr>
|
||||
</table>
|
||||
|
||||
@@ -60,7 +60,7 @@ ${do:if-file-exists:html/index.html}
|
||||
<td>
|
||||
<a href="/step9_opt9.html" target="_blank"
|
||||
onClick="window.open('/step9_opt9.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
|
||||
onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPHELP}' onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info(' '); return true"
|
||||
>${LANG_TIPHELP}</a>
|
||||
</td>
|
||||
${do:end-if}
|
||||
@@ -71,18 +71,18 @@ ${do:end-if}
|
||||
<table class="tableWidth" border="0" width="100%" cellspacing="0">
|
||||
<tr>
|
||||
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option1.html" onClick="form.redirect.value='option1.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT1}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT1}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option2.html" onClick="form.redirect.value='option2.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT2}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT2}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option3.html" onClick="form.redirect.value='option3.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT3}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT3}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option4.html" onClick="form.redirect.value='option4.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT4}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT4}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option5.html" onClick="form.redirect.value='option5.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT5}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT5}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option11.html" onClick="form.redirect.value='option11.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT11}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT11}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option1.html" onClick="form.redirect.value='option1.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT1}' onMouseOver="info('${html:LANG_IOPT1}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT1}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option2.html" onClick="form.redirect.value='option2.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT2}' onMouseOver="info('${html:LANG_IOPT2}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT2}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option3.html" onClick="form.redirect.value='option3.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT3}' onMouseOver="info('${html:LANG_IOPT3}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT3}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option4.html" onClick="form.redirect.value='option4.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT4}' onMouseOver="info('${html:LANG_IOPT4}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT4}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option5.html" onClick="form.redirect.value='option5.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT5}' onMouseOver="info('${html:LANG_IOPT5}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT5}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option11.html" onClick="form.redirect.value='option11.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT11}' onMouseOver="info('${html:LANG_IOPT11}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT11}</a></td>
|
||||
</tr><tr>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option6.html" onClick="form.redirect.value='option6.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT6}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT6}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option7.html" onClick="form.redirect.value='option7.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT7}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT7}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option8.html" onClick="form.redirect.value='option8.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT8}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT8}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option9.html" onClick="form.redirect.value='option9.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT9}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT9}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option10.html" onClick="form.redirect.value='option10.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT10}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT10}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option6.html" onClick="form.redirect.value='option6.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT6}' onMouseOver="info('${html:LANG_IOPT6}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT6}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option7.html" onClick="form.redirect.value='option7.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT7}' onMouseOver="info('${html:LANG_IOPT7}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT7}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option8.html" onClick="form.redirect.value='option8.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT8}' onMouseOver="info('${html:LANG_IOPT8}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT8}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option9.html" onClick="form.redirect.value='option9.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT9}' onMouseOver="info('${html:LANG_IOPT9}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT9}</a></td>
|
||||
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option10.html" onClick="form.redirect.value='option10.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT10}' onMouseOver="info('${html:LANG_IOPT10}'); return true" onMouseOut="info(' '); return true">${LANG_IOPT10}</a></td>
|
||||
<td class="tabCtrl" align="center"> </td>
|
||||
|
||||
</tr>
|
||||
@@ -99,32 +99,32 @@ ${do:end-if}
|
||||
<input type="hidden" name="closeme" value="">
|
||||
|
||||
<input type="checkbox" name="cache2" ${checked:cache2}
|
||||
onMouseOver="info('${html:LANG_I1e}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_I1e}' onMouseOver="info('${html:LANG_I1e}'); return true" onMouseOut="info(' '); return true"
|
||||
> ${LANG_I61}
|
||||
<br><br>
|
||||
|
||||
<input type="checkbox" name="norecatch" ${checked:norecatch}
|
||||
onMouseOver="info('${html:LANG_I5b}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_I5b}' onMouseOver="info('${html:LANG_I5b}'); return true" onMouseOut="info(' '); return true"
|
||||
> ${LANG_I34b}
|
||||
<br><br>
|
||||
|
||||
<input type="checkbox" name="logf" ${checked:logf}
|
||||
onMouseOver="info('${html:LANG_I7}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_I7}' onMouseOver="info('${html:LANG_I7}'); return true" onMouseOut="info(' '); return true"
|
||||
> ${LANG_I36}
|
||||
<select name="logtype"
|
||||
onMouseOver="info('${html:LANG_I1f}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_I1f}' onMouseOver="info('${html:LANG_I1f}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
${listid:logtype:LISTDEF_9}
|
||||
</select>
|
||||
<br><br>
|
||||
|
||||
<input type="checkbox" name="index" ${checked:index}
|
||||
onMouseOver="info('${html:LANG_I6}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_I6}' onMouseOver="info('${html:LANG_I6}'); return true" onMouseOut="info(' '); return true"
|
||||
> ${LANG_I35}
|
||||
<br><br>
|
||||
|
||||
<input type="checkbox" name="index2" ${checked:index2}
|
||||
onMouseOver="info('${html:LANG_I6b}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_I6b}' onMouseOver="info('${html:LANG_I6b}'); return true" onMouseOut="info(' '); return true"
|
||||
> ${LANG_I35b}
|
||||
<br><br>
|
||||
|
||||
@@ -133,12 +133,12 @@ ${listid:logtype:LISTDEF_9}
|
||||
<tr><td align="left">
|
||||
<input type="submit" value="${LANG_OK}"
|
||||
onClick="form.closeme.value=1; form.submit(); return false;"
|
||||
onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPOK}' onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td><td align="right">
|
||||
<input type="button" value="${LANG_CANCEL}"
|
||||
onClick="window.close();"
|
||||
onMouseOver="info('${html:LANG_TIPCANCEL}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPCANCEL}' onMouseOver="info('${html:LANG_TIPCANCEL}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td></tr>
|
||||
</table>
|
||||
|
||||
@@ -73,7 +73,7 @@ function no_refresh() {
|
||||
<td id="subTitle" align="right">
|
||||
<a href="/server/file.html" target="_blank"
|
||||
onClick="window.open('/server/file.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
|
||||
onMouseOver="info('${html:LANG_O1}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_O1}' onMouseOver="info('${html:LANG_O1}'); return true" onMouseOut="info(' '); return true"
|
||||
style="color:#FFFFFF"
|
||||
>
|
||||
${LANG_O1}
|
||||
@@ -85,7 +85,7 @@ ${do:if-file-exists:html/index.html}
|
||||
<td id="subTitle" align="right">
|
||||
<a href="/index.html" target="_blank"
|
||||
onClick="window.open('/server/help.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
|
||||
onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPHELP}' onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info(' '); return true"
|
||||
style="color:#FFFFFF"
|
||||
>
|
||||
${LANG_O5}
|
||||
@@ -152,20 +152,20 @@ ${LANG_H20} ${info.currentjob}
|
||||
|
||||
<table border="0" width="100%">
|
||||
|
||||
<tr><td>${info.state[0]}</td><td>${info.name[0]}</td><td>${info.file[0]}</td><td>${info.size[0]}/${info.sizetot[0]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[0]}'; form.submit()" onMouseOver="info('${html:LANG_H6}'); return true" onMouseOut="info(' '); return true"></td></tr>
|
||||
<tr><td>${info.state[1]}</td><td>${info.name[1]}</td><td>${info.file[1]}</td><td>${info.size[1]}/${info.sizetot[1]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[1]}'; form.submit()" onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info(' '); return true"></td></tr>
|
||||
<tr><td>${info.state[2]}</td><td>${info.name[2]}</td><td>${info.file[2]}</td><td>${info.size[2]}/${info.sizetot[2]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[2]}'; form.submit()" onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info(' '); return true"></td></tr>
|
||||
<tr><td>${info.state[3]}</td><td>${info.name[3]}</td><td>${info.file[3]}</td><td>${info.size[3]}/${info.sizetot[3]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[3]}'; form.submit()" onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info(' '); return true"></td></tr>
|
||||
<tr><td>${info.state[4]}</td><td>${info.name[4]}</td><td>${info.file[4]}</td><td>${info.size[4]}/${info.sizetot[4]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[4]}'; form.submit()" onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info(' '); return true"></td></tr>
|
||||
<tr><td>${info.state[5]}</td><td>${info.name[5]}</td><td>${info.file[5]}</td><td>${info.size[5]}/${info.sizetot[5]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[5]}'; form.submit()" onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info(' '); return true"></td></tr>
|
||||
<tr><td>${info.state[6]}</td><td>${info.name[6]}</td><td>${info.file[6]}</td><td>${info.size[6]}/${info.sizetot[6]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[6]}'; form.submit()" onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info(' '); return true"></td></tr>
|
||||
<tr><td>${info.state[7]}</td><td>${info.name[7]}</td><td>${info.file[7]}</td><td>${info.size[7]}/${info.sizetot[7]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[7]}'; form.submit()" onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info(' '); return true"></td></tr>
|
||||
<tr><td>${info.state[8]}</td><td>${info.name[8]}</td><td>${info.file[8]}</td><td>${info.size[8]}/${info.sizetot[8]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[8]}'; form.submit()" onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info(' '); return true"></td></tr>
|
||||
<tr><td>${info.state[9]}</td><td>${info.name[9]}</td><td>${info.file[9]}</td><td>${info.size[9]}/${info.sizetot[9]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[9]}'; form.submit()" onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info(' '); return true"></td></tr>
|
||||
<tr><td>${info.state[10]}</td><td>${info.name[10]}</td><td>${info.file[10]}</td><td>${info.size[10]}/${info.sizetot[10]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[10]}'; form.submit()" onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info(' '); return true"></td></tr>
|
||||
<tr><td>${info.state[11]}</td><td>${info.name[11]}</td><td>${info.file[11]}</td><td>${info.size[11]}/${info.sizetot[11]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[11]}'; form.submit()" onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info(' '); return true"></td></tr>
|
||||
<tr><td>${info.state[12]}</td><td>${info.name[12]}</td><td>${info.file[12]}</td><td>${info.size[12]}/${info.sizetot[12]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[12]}'; form.submit()" onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info(' '); return true"></td></tr>
|
||||
<tr><td>${info.state[13]}</td><td>${info.name[13]}</td><td>${info.file[13]}</td><td>${info.size[13]}/${info.sizetot[13]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[13]}'; form.submit()" onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info(' '); return true"></td></tr>
|
||||
<tr><td>${info.state[0]}</td><td>${info.name[0]}</td><td>${info.file[0]}</td><td>${info.size[0]}/${info.sizetot[0]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[0]}'; form.submit()" title='${html:LANG_H6}' onMouseOver="info('${html:LANG_H6}'); return true" onMouseOut="info(' '); return true"></td></tr>
|
||||
<tr><td>${info.state[1]}</td><td>${info.name[1]}</td><td>${info.file[1]}</td><td>${info.size[1]}/${info.sizetot[1]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[1]}'; form.submit()" title='${html:LANG_H7}' onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info(' '); return true"></td></tr>
|
||||
<tr><td>${info.state[2]}</td><td>${info.name[2]}</td><td>${info.file[2]}</td><td>${info.size[2]}/${info.sizetot[2]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[2]}'; form.submit()" title='${html:LANG_H7}' onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info(' '); return true"></td></tr>
|
||||
<tr><td>${info.state[3]}</td><td>${info.name[3]}</td><td>${info.file[3]}</td><td>${info.size[3]}/${info.sizetot[3]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[3]}'; form.submit()" title='${html:LANG_H7}' onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info(' '); return true"></td></tr>
|
||||
<tr><td>${info.state[4]}</td><td>${info.name[4]}</td><td>${info.file[4]}</td><td>${info.size[4]}/${info.sizetot[4]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[4]}'; form.submit()" title='${html:LANG_H7}' onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info(' '); return true"></td></tr>
|
||||
<tr><td>${info.state[5]}</td><td>${info.name[5]}</td><td>${info.file[5]}</td><td>${info.size[5]}/${info.sizetot[5]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[5]}'; form.submit()" title='${html:LANG_H7}' onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info(' '); return true"></td></tr>
|
||||
<tr><td>${info.state[6]}</td><td>${info.name[6]}</td><td>${info.file[6]}</td><td>${info.size[6]}/${info.sizetot[6]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[6]}'; form.submit()" title='${html:LANG_H7}' onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info(' '); return true"></td></tr>
|
||||
<tr><td>${info.state[7]}</td><td>${info.name[7]}</td><td>${info.file[7]}</td><td>${info.size[7]}/${info.sizetot[7]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[7]}'; form.submit()" title='${html:LANG_H7}' onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info(' '); return true"></td></tr>
|
||||
<tr><td>${info.state[8]}</td><td>${info.name[8]}</td><td>${info.file[8]}</td><td>${info.size[8]}/${info.sizetot[8]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[8]}'; form.submit()" title='${html:LANG_H7}' onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info(' '); return true"></td></tr>
|
||||
<tr><td>${info.state[9]}</td><td>${info.name[9]}</td><td>${info.file[9]}</td><td>${info.size[9]}/${info.sizetot[9]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[9]}'; form.submit()" title='${html:LANG_H7}' onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info(' '); return true"></td></tr>
|
||||
<tr><td>${info.state[10]}</td><td>${info.name[10]}</td><td>${info.file[10]}</td><td>${info.size[10]}/${info.sizetot[10]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[10]}'; form.submit()" title='${html:LANG_H7}' onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info(' '); return true"></td></tr>
|
||||
<tr><td>${info.state[11]}</td><td>${info.name[11]}</td><td>${info.file[11]}</td><td>${info.size[11]}/${info.sizetot[11]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[11]}'; form.submit()" title='${html:LANG_H7}' onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info(' '); return true"></td></tr>
|
||||
<tr><td>${info.state[12]}</td><td>${info.name[12]}</td><td>${info.file[12]}</td><td>${info.size[12]}/${info.sizetot[12]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[12]}'; form.submit()" title='${html:LANG_H7}' onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info(' '); return true"></td></tr>
|
||||
<tr><td>${info.state[13]}</td><td>${info.name[13]}</td><td>${info.file[13]}</td><td>${info.size[13]}/${info.sizetot[13]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[13]}'; form.submit()" title='${html:LANG_H7}' onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info(' '); return true"></td></tr>
|
||||
|
||||
</table>
|
||||
|
||||
@@ -180,7 +180,7 @@ ${LANG_H20} ${info.currentjob}
|
||||
|
||||
</td><td align="right">
|
||||
<input type="submit" value=" ${LANG_V4} "
|
||||
onMouseOver="disable_timer(); info('${LANG_D3}'); return true"
|
||||
title='${html:LANG_D3}' onMouseOver="disable_timer(); info('${LANG_D3}'); return true"
|
||||
onMouseOut="info(' '); enable_timer(); return true"
|
||||
onClick="if (do_confirm('${LANG_G1}')) { form.command.value='cancel'; form.submit(); } return false"
|
||||
>
|
||||
|
||||
@@ -52,7 +52,7 @@ function info(str) {
|
||||
<td id="subTitle" align="right">
|
||||
<a href="/server/file.html" target="_blank"
|
||||
onClick="window.open('/server/file.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
|
||||
onMouseOver="info('${html:html:LANG_O1}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_O1}' onMouseOver="info('${html:html:LANG_O1}'); return true" onMouseOut="info(' '); return true"
|
||||
style="color:#FFFFFF"
|
||||
>
|
||||
${LANG_O1}
|
||||
@@ -64,7 +64,7 @@ ${do:if-file-exists:html/index.html}
|
||||
<td id="subTitle" align="right">
|
||||
<a href="/index.html" target="_blank"
|
||||
onClick="window.open('/server/help.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
|
||||
onMouseOver="info('${html:html:LANG_TIPHELP}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPHELP}' onMouseOver="info('${html:html:LANG_TIPHELP}'); return true" onMouseOut="info(' '); return true"
|
||||
style="color:#FFFFFF"
|
||||
>
|
||||
${LANG_O5}
|
||||
@@ -93,7 +93,7 @@ ${do:if-file-exists:html/index.html}
|
||||
<td>
|
||||
<a href="/step1.html" target="_blank"
|
||||
onClick="window.open('/step1.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
|
||||
onMouseOver="info('${html:html:LANG_TIPHELP}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPHELP}' onMouseOver="info('${html:html:LANG_TIPHELP}'); return true" onMouseOut="info(' '); return true"
|
||||
>${LANG_TIPHELP}</a>
|
||||
</td>
|
||||
${do:end-if}
|
||||
@@ -129,15 +129,21 @@ ${do:copy:NoPwdInPages:hidepwd}
|
||||
${do:copy:NoQueryStrings:hidequery}
|
||||
${do:copy:NoPurgeOldFiles:nopurge}
|
||||
${do:copy:Cookies:cookies}
|
||||
${do:copy:CookiesFile:cookiesfile}
|
||||
${do:copy:CheckType:checktype}
|
||||
${do:copy:ParseJava:parsejava}
|
||||
${do:copy:HTTP10:http10}
|
||||
${do:copy:TolerantRequests:toler}
|
||||
${do:copy:UpdateHack:updhack}
|
||||
${do:copy:URLHack:urlhack}
|
||||
${do:copy:KeepWww:keepwww}
|
||||
${do:copy:KeepSlashes:keepslashes}
|
||||
${do:copy:KeepQueryOrder:keepqueryorder}
|
||||
${do:copy:StripQuery:stripquery}
|
||||
${do:copy:StoreAllInCache:cache2}
|
||||
${do:copy:LogType:logtype}
|
||||
${do:copy:UseHTTPProxyForFTP:ftpprox}
|
||||
${do:copy:ProxyType:proxytype}
|
||||
${do:copy:Build:build}
|
||||
${do:copy:PrimaryScan:filter}
|
||||
${do:copy:Travel:travel}
|
||||
@@ -148,6 +154,7 @@ ${do:copy:MaxHtml:maxhtml}
|
||||
${do:copy:MaxOther:othermax}
|
||||
${do:copy:MaxAll:sizemax}
|
||||
${do:copy:MaxWait:pausebytes}
|
||||
${do:copy:PauseFiles:pausefiles}
|
||||
${do:copy:Sockets:connexion}
|
||||
${do:copy:Retry:retry}
|
||||
${do:copy:MaxTime:maxtime}
|
||||
@@ -211,7 +218,7 @@ ${do:loadhash}
|
||||
|
||||
${LANG_S11}
|
||||
<input name="projname" value="${projname}"
|
||||
onMouseOver="info('${html:html:LANG_S1}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_S1}' onMouseOver="info('${html:html:LANG_S1}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
|
||||
<br>
|
||||
@@ -226,7 +233,7 @@ ${do:loadhash}
|
||||
</select>
|
||||
</td><td>
|
||||
<input name="projcateg" value="${projcateg}"
|
||||
onMouseOver="info('${html:html:LANG_S5}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_S5}' onMouseOver="info('${html:html:LANG_S5}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
|
||||
</td></tr></table>
|
||||
@@ -234,7 +241,7 @@ ${do:loadhash}
|
||||
<br>
|
||||
${LANG_S12}
|
||||
<input name="path" value="${path}"
|
||||
onMouseOver="info('${html:html:LANG_S2}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_S2}' onMouseOver="info('${html:html:LANG_S2}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
<input type="button" value="refresh" onClick="form.redirect.value='step2.html'; form.submit()">
|
||||
|
||||
@@ -243,11 +250,11 @@ ${do:loadhash}
|
||||
<tr><td>
|
||||
<table width="100%" border="0"><tr><td align="left">
|
||||
<input type="submit" value=" << ${LANG_PREVIOUS} " onClick="form.redirect.value='index.html'; form.submit()"
|
||||
onMouseOver="info('${html:html:LANG_TIPPREV}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPPREV}' onMouseOver="info('${html:html:LANG_TIPPREV}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td><td align="right">
|
||||
<input name="nextBtn" type="submit" value=" ${LANG_NEXT} >> " onClick="return checkname();" default
|
||||
onMouseOver="info('${html:html:LANG_TIPNEXT}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPNEXT}' onMouseOver="info('${html:html:LANG_TIPNEXT}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td></tr></table>
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ function do_check_child() {
|
||||
<td id="subTitle" align="right">
|
||||
<a href="/server/file.html" target="_blank"
|
||||
onClick="window.open('/server/file.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
|
||||
onMouseOver="info('${html:LANG_O1}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_O1}' onMouseOver="info('${html:LANG_O1}'); return true" onMouseOut="info(' '); return true"
|
||||
style="color:#FFFFFF"
|
||||
>
|
||||
${LANG_O1}
|
||||
@@ -73,7 +73,7 @@ ${do:if-file-exists:html/index.html}
|
||||
<td id="subTitle" align="right">
|
||||
<a href="/index.html" target="_blank"
|
||||
onClick="window.open('/server/help.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
|
||||
onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPHELP}' onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info(' '); return true"
|
||||
style="color:#FFFFFF"
|
||||
>
|
||||
${LANG_O5}
|
||||
@@ -102,7 +102,7 @@ ${do:if-file-exists:html/index.html}
|
||||
<td>
|
||||
<a href="/step2.html" target="_blank"
|
||||
onClick="window.open('/step2.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
|
||||
onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPHELP}' onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info(' '); return true"
|
||||
>${LANG_TIPHELP}</a>
|
||||
</td>
|
||||
${do:end-if}
|
||||
@@ -118,7 +118,7 @@ ${do:end-if}
|
||||
<tr><td>
|
||||
${LANG_G31}
|
||||
<select name="todo"
|
||||
onMouseOver="info('${html:LANG_G9}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_G9}' onMouseOver="info('${html:LANG_G9}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
${listid:todo:LISTDEF_10}
|
||||
</select>
|
||||
@@ -131,12 +131,12 @@ ${do:end-if}
|
||||
</td><td>
|
||||
<input type="button" value="${LANG_G43}"
|
||||
onClick="doOpenWindow()"
|
||||
onMouseOver="info('${html:LANG_G24b}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_G24b}' onMouseOver="info('${html:LANG_G24b}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td></tr></table>
|
||||
<br>
|
||||
<textarea name="urls" cols="50" rows="8"
|
||||
onMouseOver="info('${html:LANG_G11}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_G11}' onMouseOver="info('${html:LANG_G11}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
${do:output-mode:html}
|
||||
${urls}
|
||||
@@ -150,7 +150,7 @@ ${do:output-mode:}
|
||||
${LANG_URLLIST}:
|
||||
</td><td>
|
||||
<input name="filelist" value="${filelist}" size="40"
|
||||
onMouseOver="info('${html:LANG_G24c}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_G24c}' onMouseOver="info('${html:LANG_G24c}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td></tr></table>
|
||||
|
||||
@@ -161,7 +161,7 @@ ${do:output-mode:}
|
||||
${LANG_G41}
|
||||
</td><td>
|
||||
<input type="button" value="${LANG_G40}" onClick="window.open('option1.html', 'option1', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
|
||||
onMouseOver="info('${html:LANG_G24}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_G24}' onMouseOver="info('${html:LANG_G24}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td></tr></table>
|
||||
|
||||
@@ -170,11 +170,11 @@ ${do:output-mode:}
|
||||
<tr><td align="right">
|
||||
<table width="100%" border="0"><tr><td align="left">
|
||||
<input type="submit" value=" << ${LANG_PREVIOUS} " onClick="form.redirect.value='step2.html'; form.submit()"
|
||||
onMouseOver="info('${html:LANG_TIPPREV}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPPREV}' onMouseOver="info('${html:LANG_TIPPREV}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td><td align="right">
|
||||
<input name="nextBtn" type="submit" value=" ${LANG_NEXT} >> "
|
||||
onMouseOver="info('${html:LANG_TIPNEXT}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPNEXT}' onMouseOver="info('${html:LANG_TIPNEXT}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td></tr></table>
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ function info(str) {
|
||||
<td id="subTitle" align="right">
|
||||
<a href="/server/file.html" target="_blank"
|
||||
onClick="window.open('/server/file.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
|
||||
onMouseOver="info('${html:LANG_O1}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_O1}' onMouseOver="info('${html:LANG_O1}'); return true" onMouseOut="info(' '); return true"
|
||||
style="color:#FFFFFF"
|
||||
>
|
||||
${LANG_O1}
|
||||
@@ -55,7 +55,7 @@ ${do:if-file-exists:html/index.html}
|
||||
<td id="subTitle" align="right">
|
||||
<a href="/index.html" target="_blank"
|
||||
onClick="window.open('/server/help.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
|
||||
onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPHELP}' onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info(' '); return true"
|
||||
style="color:#FFFFFF"
|
||||
>
|
||||
${LANG_O5}
|
||||
@@ -84,7 +84,7 @@ ${do:if-file-exists:html/index.html}
|
||||
<td>
|
||||
<a href="/step3.html" target="_blank"
|
||||
onClick="window.open('/step3.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
|
||||
onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPHELP}' onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info(' '); return true"
|
||||
>${LANG_TIPHELP}</a>
|
||||
</td>
|
||||
${do:end-if}
|
||||
@@ -178,6 +178,12 @@ ${do:end-if}
|
||||
${test:parsejava:--parse-java=0:}
|
||||
${test:updhack:--updatehack}
|
||||
${test:urlhack:--urlhack=0:--urlhack}
|
||||
${test:keepwww:--keep-www-prefix}
|
||||
${test:keepslashes:--keep-double-slashes}
|
||||
${test:keepqueryorder:--keep-query-order}
|
||||
${test:cookiesfile:--cookies-file "}${html:cookiesfile}${test:cookiesfile:"}
|
||||
${test:pausefiles:--pause "}${pausefiles}${test:pausefiles:"}
|
||||
${test:stripquery:--strip-query "}${html:stripquery}${test:stripquery:"}
|
||||
${test:toler:--tolerant}
|
||||
${test:http10:--http-10}
|
||||
${test:cache2:--store-all-in-cache}
|
||||
@@ -186,7 +192,7 @@ ${do:end-if}
|
||||
${test:logtype:::--extra-log:--debug-log}
|
||||
${test:index:--index=0:}
|
||||
${test:index2:--search-index=0:--search-index}
|
||||
${test:prox:--proxy "}${prox}${test:prox:\3A}${portprox}${test:prox:"}
|
||||
${test:prox:--proxy "}${do:if-not-empty:prox}${test:proxytype::socks5:connect}${test:proxytype:\3A//}${do:end-if}${do:output-mode:html}${prox}${test:prox:\3A}${portprox}${test:prox:"}
|
||||
${test:ftpprox:--httpproxy-ftp=0:--httpproxy-ftp}
|
||||
</textarea>
|
||||
|
||||
@@ -219,15 +225,21 @@ NoPwdInPages=${ztest:hidepwd:0:1}
|
||||
NoQueryStrings=${ztest:hidequery:0:1}
|
||||
NoPurgeOldFiles=${ztest:nopurge:0:1}
|
||||
Cookies=${ztest:cookies:0:1}
|
||||
CookiesFile=${cookiesfile}
|
||||
CheckType=${ztest:checktype:0:1:2}
|
||||
ParseJava=${ztest:parsejava:0:1}
|
||||
HTTP10=${ztest:http10:0:1}
|
||||
TolerantRequests=${ztest:toler:0:1}
|
||||
UpdateHack=${ztest:updhack:0:1}
|
||||
URLHack=${ztest:urlhack:0:1}
|
||||
KeepWww=${ztest:keepwww:0:1}
|
||||
KeepSlashes=${ztest:keepslashes:0:1}
|
||||
KeepQueryOrder=${ztest:keepqueryorder:0:1}
|
||||
StripQuery=${stripquery}
|
||||
StoreAllInCache=${ztest:cache2:0:1}
|
||||
LogType=${logtype}
|
||||
UseHTTPProxyForFTP=${ztest:ftpprox:0:1}
|
||||
ProxyType=${proxytype}
|
||||
Build=${build}
|
||||
PrimaryScan=${filter}
|
||||
Travel=${travel}
|
||||
@@ -238,6 +250,7 @@ MaxHtml=${maxhtml}
|
||||
MaxOther=${othermax}
|
||||
MaxAll=${sizemax}
|
||||
MaxWait=${pausebytes}
|
||||
PauseFiles=${pausefiles}
|
||||
Sockets=${connexion}
|
||||
Retry=${retry}
|
||||
MaxTime=${maxtime}
|
||||
@@ -285,11 +298,11 @@ ${do:output-mode:}
|
||||
</td></tr><tr><td>
|
||||
<table width="100%" border="0"><tr><td align="left">
|
||||
<input type="submit" value=" << ${LANG_PREVIOUS} " onClick="form.command.value=''; form.redirect.value='step3.html'; form.submit()"
|
||||
onMouseOver="info('${html:LANG_TIPPREV}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPPREV}' onMouseOver="info('${html:LANG_TIPPREV}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td><td align="right">
|
||||
<input name="nextBtn" type="submit" value=" ${LANG_J9} >> "
|
||||
onMouseOver="info('${html:LANG_TIPNEXT}'); return true" onMouseOut="info(' '); return true"
|
||||
title='${html:LANG_TIPNEXT}' onMouseOver="info('${html:LANG_TIPNEXT}'); return true" onMouseOut="info(' '); return true"
|
||||
>
|
||||
</td></tr></table>
|
||||
|
||||
|
||||
28
lang.def
28
lang.def
@@ -1006,3 +1006,31 @@ LANG_SERVEND
|
||||
Server terminated
|
||||
LANG_FATALERR
|
||||
A fatal error has occurred during this mirror
|
||||
LANG_PROXYTYPE
|
||||
Proxy type:
|
||||
LANG_PROXYTYPETIP
|
||||
Proxy protocol. HTTP: standard proxy. HTTP (CONNECT tunnel): sends every request through a CONNECT tunnel, for CONNECT-only proxies like Tor's HTTPTunnelPort. SOCKS5: default port 1080.
|
||||
LANG_COOKIEFILE
|
||||
Load cookies from file:
|
||||
LANG_COOKIEFILETIP
|
||||
Preload cookies from a Netscape cookies.txt file before crawling.
|
||||
LANG_PAUSEFILES
|
||||
Pause between files:
|
||||
LANG_PAUSEFILESTIP
|
||||
Random delay between file downloads, in seconds. Use MIN:MAX for a random range (e.g. 2:8).
|
||||
LANG_KEEPWWW
|
||||
Keep the www. prefix (do not merge www.host with host)
|
||||
LANG_KEEPWWWTIP
|
||||
Do not treat www.host and host as the same site.
|
||||
LANG_KEEPSLASHES
|
||||
Keep double slashes in URLs
|
||||
LANG_KEEPSLASHESTIP
|
||||
Do not collapse duplicate slashes in URLs.
|
||||
LANG_KEEPQUERYORDER
|
||||
Keep the original query-string order
|
||||
LANG_KEEPQUERYORDERTIP
|
||||
Do not reorder query-string parameters when deduplicating URLs.
|
||||
LANG_STRIPQUERY
|
||||
Strip query keys:
|
||||
LANG_STRIPQUERYTIP
|
||||
Comma-separated query keys to drop from the saved-file naming (e.g. sid,utm_source).
|
||||
|
||||
@@ -928,3 +928,31 @@ Server terminated
|
||||
Ñúðâúðúò íå îòãîâàðÿ
|
||||
A fatal error has occurred during this mirror
|
||||
Ôàòàëíà ãðåøêà ïðè ñúçäàâàíåòî íà òîçè îãëåäàëåí ñàéò
|
||||
Proxy type:
|
||||
Òèï íà ïðîêñè:
|
||||
Proxy protocol. HTTP: standard proxy. HTTP (CONNECT tunnel): sends every request through a CONNECT tunnel, for CONNECT-only proxies like Tor's HTTPTunnelPort. SOCKS5: default port 1080.
|
||||
Ïðîòîêîë íà ïðîêñè. HTTP: ñòàíäàðòíî ïðîêñè. HTTP (CONNECT òóíåë): èçïðàùà âñÿêà çàÿâêà ïðåç CONNECT òóíåë, çà ïðîêñè ïîääúðæàùè ñàìî CONNECT êàòî HTTPTunnelPort íà Tor. SOCKS5: ïîðò ïî ïîäðàçáèðàíå 1080.
|
||||
Load cookies from file:
|
||||
Çàðåæäàíå íà 'áèñêâèòêè' îò ôàéë:
|
||||
Preload cookies from a Netscape cookies.txt file before crawling.
|
||||
Ïðåäâàðèòåëíî çàðåæäàíå íà 'áèñêâèòêè' îò ôàéë Netscape cookies.txt ïðåäè îáõîæäàíåòî.
|
||||
Pause between files:
|
||||
Ïàóçà ìåæäó ôàéëîâåòå:
|
||||
Random delay between file downloads, in seconds. Use MIN:MAX for a random range (e.g. 2:8).
|
||||
Ñëó÷àéíî çàáàâÿíå ìåæäó èçòåãëÿíèÿòà íà ôàéëîâå, â ñåêóíäè. Èçïîëçâàéòå MIN:MAX çà ñëó÷àåí äèàïàçîí (íàïðèìåð 2:8).
|
||||
Keep the www. prefix (do not merge www.host with host)
|
||||
Çàïàçâàíå íà ïðåôèêñà www. (áåç ñëèâàíå íà www.host ñ host)
|
||||
Do not treat www.host and host as the same site.
|
||||
www.host è host äà íå ñå òðåòèðàò êàòî åäèí è ñúù ñàéò.
|
||||
Keep double slashes in URLs
|
||||
Çàïàçâàíå íà äâîéíèòå íàêëîíåíè ÷åðòè â URL
|
||||
Do not collapse duplicate slashes in URLs.
|
||||
Áåç ïðåìàõâàíå íà ïîâòàðÿùèòå ñå íàêëîíåíè ÷åðòè â URL.
|
||||
Keep the original query-string order
|
||||
Çàïàçâàíå íà îðèãèíàëíèÿ ðåä íà ïàðàìåòðèòå â çàÿâêàòà
|
||||
Do not reorder query-string parameters when deduplicating URLs.
|
||||
Áåç ïðåíàðåæäàíå íà ïàðàìåòðèòå íà çàÿâêàòà ïðè ïðåìàõâàíå íà äóáëèðàíè URL.
|
||||
Strip query keys:
|
||||
Ïðåìàõâàíå íà êëþ÷îâå îò çàÿâêàòà:
|
||||
Comma-separated query keys to drop from the saved-file naming (e.g. sid,utm_source).
|
||||
Êëþ÷îâå îò çàÿâêàòà, ðàçäåëåíè ñúñ çàïåòàÿ, êîèòî äà ñå ïðåìàõíàò îò èìåòî íà çàïèñàíèÿ ôàéë (íàïðèìåð sid,utm_source).
|
||||
|
||||
@@ -928,3 +928,31 @@ Server terminated
|
||||
Servidor desconectado
|
||||
A fatal error has occurred during this mirror
|
||||
Ha ocurrido un error fatal durante esta copia
|
||||
Proxy type:
|
||||
Tipo de proxy:
|
||||
Proxy protocol. HTTP: standard proxy. HTTP (CONNECT tunnel): sends every request through a CONNECT tunnel, for CONNECT-only proxies like Tor's HTTPTunnelPort. SOCKS5: default port 1080.
|
||||
Protocolo del proxy. HTTP: proxy estándar. HTTP (túnel CONNECT): envía cada petición a través de un túnel CONNECT, para proxys que solo admiten CONNECT como el HTTPTunnelPort de Tor. SOCKS5: puerto predeterminado 1080.
|
||||
Load cookies from file:
|
||||
Cargar cookies desde un archivo:
|
||||
Preload cookies from a Netscape cookies.txt file before crawling.
|
||||
Precargar cookies desde un archivo Netscape cookies.txt antes de comenzar la descarga.
|
||||
Pause between files:
|
||||
Pausa entre archivos:
|
||||
Random delay between file downloads, in seconds. Use MIN:MAX for a random range (e.g. 2:8).
|
||||
Retardo aleatorio entre descargas de archivos, en segundos. Use MIN:MAX para un rango aleatorio (p. ej. 2:8).
|
||||
Keep the www. prefix (do not merge www.host with host)
|
||||
Mantener el prefijo www. (no combinar www.host con host)
|
||||
Do not treat www.host and host as the same site.
|
||||
No tratar www.host y host como el mismo sitio.
|
||||
Keep double slashes in URLs
|
||||
Mantener las barras dobles en las URL
|
||||
Do not collapse duplicate slashes in URLs.
|
||||
No colapsar las barras duplicadas en las URL.
|
||||
Keep the original query-string order
|
||||
Mantener el orden original de la query string
|
||||
Do not reorder query-string parameters when deduplicating URLs.
|
||||
No reordenar los parámetros de la query string al deduplicar las URL.
|
||||
Strip query keys:
|
||||
Eliminar claves de query string:
|
||||
Comma-separated query keys to drop from the saved-file naming (e.g. sid,utm_source).
|
||||
Claves de query string, separadas por comas, que se eliminarán del nombre de los archivos guardados (p. ej. sid,utm_source).
|
||||
|
||||
@@ -928,3 +928,31 @@ Server terminated
|
||||
|
||||
A fatal error has occurred during this mirror
|
||||
|
||||
Proxy type:
|
||||
Typ proxy:
|
||||
Proxy protocol. HTTP: standard proxy. HTTP (CONNECT tunnel): sends every request through a CONNECT tunnel, for CONNECT-only proxies like Tor's HTTPTunnelPort. SOCKS5: default port 1080.
|
||||
Protokol proxy. HTTP: standardní proxy. HTTP (tunel CONNECT): odešle každý požadavek pøes tunel CONNECT, pro proxy podporující jen CONNECT jako HTTPTunnelPort v Toru. SOCKS5: výchozí port 1080.
|
||||
Load cookies from file:
|
||||
Naèíst cookies ze souboru:
|
||||
Preload cookies from a Netscape cookies.txt file before crawling.
|
||||
Naèíst cookies ze souboru Netscape cookies.txt pøed zahájením stahování.
|
||||
Pause between files:
|
||||
Prodleva mezi soubory:
|
||||
Random delay between file downloads, in seconds. Use MIN:MAX for a random range (e.g. 2:8).
|
||||
Náhodná prodleva mezi stahováním souborù, v sekundách. Pro náhodný rozsah použijte MIN:MAX (napø. 2:8).
|
||||
Keep the www. prefix (do not merge www.host with host)
|
||||
Zachovat pøedponu www. (nesluèovat www.host s host)
|
||||
Do not treat www.host and host as the same site.
|
||||
Nepovažovat www.host a host za stejný web.
|
||||
Keep double slashes in URLs
|
||||
Zachovat dvojitá lomítka v URL
|
||||
Do not collapse duplicate slashes in URLs.
|
||||
Nesluèovat opakovaná lomítka v URL.
|
||||
Keep the original query-string order
|
||||
Zachovat pùvodní poøadí øetìzce dotazu
|
||||
Do not reorder query-string parameters when deduplicating URLs.
|
||||
Nemìnit poøadí parametrù øetìzce dotazu pøi odstraòování duplicitních URL.
|
||||
Strip query keys:
|
||||
Odebrat klíèe dotazu:
|
||||
Comma-separated query keys to drop from the saved-file naming (e.g. sid,utm_source).
|
||||
Klíèe dotazu oddìlené èárkami, které se vynechají z pojmenování ukládaných souborù (napø. sid,utm_source).
|
||||
|
||||
@@ -928,3 +928,31 @@ Server terminated
|
||||
伺服器已終止
|
||||
A fatal error has occurred during this mirror
|
||||
這鏡像發生了不可回復的錯誤
|
||||
Proxy type:
|
||||
proxy 類型:
|
||||
Proxy protocol. HTTP: standard proxy. HTTP (CONNECT tunnel): sends every request through a CONNECT tunnel, for CONNECT-only proxies like Tor's HTTPTunnelPort. SOCKS5: default port 1080.
|
||||
代理協定。HTTP:標準代理。HTTP(CONNECT 隧道):透過 CONNECT 隧道傳送每個請求,用於僅支援 CONNECT 的代理,例如 Tor 的 HTTPTunnelPort。SOCKS5:預設連接埠 1080。
|
||||
Load cookies from file:
|
||||
從檔案載入 cookies:
|
||||
Preload cookies from a Netscape cookies.txt file before crawling.
|
||||
在抓取前從 Netscape 格式的 cookies.txt 檔案預先載入 cookies。
|
||||
Pause between files:
|
||||
檔案之間暫停:
|
||||
Random delay between file downloads, in seconds. Use MIN:MAX for a random range (e.g. 2:8).
|
||||
檔案下載之間的隨機延遲(秒)。使用 MIN:MAX 指定隨機範圍 (例如 2:8)。
|
||||
Keep the www. prefix (do not merge www.host with host)
|
||||
保留 www. 前綴 (不將 www.host 與 host 合併)
|
||||
Do not treat www.host and host as the same site.
|
||||
不將 www.host 與 host 視為同一站點。
|
||||
Keep double slashes in URLs
|
||||
保留 URL 中的雙斜線
|
||||
Do not collapse duplicate slashes in URLs.
|
||||
不合併 URL 中重複的斜線。
|
||||
Keep the original query-string order
|
||||
保留查詢字串的原始順序
|
||||
Do not reorder query-string parameters when deduplicating URLs.
|
||||
在對 URL 去重時不重新排列查詢字串參數。
|
||||
Strip query keys:
|
||||
移除查詢鍵:
|
||||
Comma-separated query keys to drop from the saved-file naming (e.g. sid,utm_source).
|
||||
以逗號分隔的查詢鍵,將其從儲存檔案的命名中移除 (例如 sid,utm_source)。
|
||||
|
||||
@@ -928,3 +928,31 @@ Server terminated
|
||||
|
||||
A fatal error has occurred during this mirror
|
||||
|
||||
Proxy type:
|
||||
代理类型:
|
||||
Proxy protocol. HTTP: standard proxy. HTTP (CONNECT tunnel): sends every request through a CONNECT tunnel, for CONNECT-only proxies like Tor's HTTPTunnelPort. SOCKS5: default port 1080.
|
||||
代理协议。HTTP:标准代理。HTTP(CONNECT 隧道):通过 CONNECT 隧道发送每个请求,用于仅支持 CONNECT 的代理,例如 Tor 的 HTTPTunnelPort。SOCKS5:默认端口 1080。
|
||||
Load cookies from file:
|
||||
从文件加载 cookies:
|
||||
Preload cookies from a Netscape cookies.txt file before crawling.
|
||||
在抓取前从 Netscape 格式的 cookies.txt 文件预加载 cookies。
|
||||
Pause between files:
|
||||
文件间暂停:
|
||||
Random delay between file downloads, in seconds. Use MIN:MAX for a random range (e.g. 2:8).
|
||||
文件下载之间的随机延迟(秒)。使用 MIN:MAX 指定随机范围 (例如 2:8)。
|
||||
Keep the www. prefix (do not merge www.host with host)
|
||||
保留 www. 前缀 (不将 www.host 与 host 合并)
|
||||
Do not treat www.host and host as the same site.
|
||||
不把 www.host 和 host 视为同一站点。
|
||||
Keep double slashes in URLs
|
||||
保留 URL 中的双斜杠
|
||||
Do not collapse duplicate slashes in URLs.
|
||||
不合并 URL 中重复的斜杠。
|
||||
Keep the original query-string order
|
||||
保留查询字符串的原始顺序
|
||||
Do not reorder query-string parameters when deduplicating URLs.
|
||||
在对 URL 去重时不重新排列查询字符串参数。
|
||||
Strip query keys:
|
||||
剥离查询键:
|
||||
Comma-separated query keys to drop from the saved-file naming (e.g. sid,utm_source).
|
||||
用逗号分隔的查询键,将其从保存文件的命名中删除 (例如 sid,utm_source)。
|
||||
|
||||
@@ -930,3 +930,31 @@ Server terminated
|
||||
Poslužitelj je razriješen
|
||||
A fatal error has occurred during this mirror
|
||||
Tijekom ovog zrcaljenja je nastala fatalna pogreška
|
||||
Proxy type:
|
||||
Vrsta posrednika:
|
||||
Proxy protocol. HTTP: standard proxy. HTTP (CONNECT tunnel): sends every request through a CONNECT tunnel, for CONNECT-only proxies like Tor's HTTPTunnelPort. SOCKS5: default port 1080.
|
||||
Protokol posrednika. HTTP: standardni posrednik. HTTP (CONNECT tunel): ¹alje svaki zahtjev kroz CONNECT tunel, za posrednike koji podr¾avaju samo CONNECT poput Torovog HTTPTunnelPorta. SOCKS5: zadani port 1080.
|
||||
Load cookies from file:
|
||||
Uèitati kolaèiæe iz datoteke:
|
||||
Preload cookies from a Netscape cookies.txt file before crawling.
|
||||
Prije zrcaljenja uèitati kolaèiæe iz datoteke Netscape cookies.txt.
|
||||
Pause between files:
|
||||
Stanka izmeðu datoteka:
|
||||
Random delay between file downloads, in seconds. Use MIN:MAX for a random range (e.g. 2:8).
|
||||
Nasumièna odgoda izmeðu preuzimanja datoteka, u sekundama. Za nasumièni raspon koristiti MIN:MAX (npr. 2:8).
|
||||
Keep the www. prefix (do not merge www.host with host)
|
||||
Zadr¾ati www. predmetak (ne spajati www.host s host)
|
||||
Do not treat www.host and host as the same site.
|
||||
www.host i host ne smatrati istim web-mjestom.
|
||||
Keep double slashes in URLs
|
||||
Zadr¾ati dvostruke kose crte u URL-ovima
|
||||
Do not collapse duplicate slashes in URLs.
|
||||
Ne sa¾imati ponovljene kose crte u URL-ovima.
|
||||
Keep the original query-string order
|
||||
Zadr¾ati izvorni redoslijed teksta za upite
|
||||
Do not reorder query-string parameters when deduplicating URLs.
|
||||
Ne mijenjati redoslijed parametara teksta za upite pri uklanjanju dvostrukih URL-ova.
|
||||
Strip query keys:
|
||||
Ukloniti kljuèeve upita:
|
||||
Comma-separated query keys to drop from the saved-file naming (e.g. sid,utm_source).
|
||||
Zarezom odvojeni kljuèevi upita koji se izostavljaju iz naziva spremljenih datoteka (npr. sid,utm_source).
|
||||
|
||||
@@ -976,3 +976,31 @@ Click on this notification to restart the interrupted mirror
|
||||
Klik på denne notifikation for at genstarte den afbrudte spejlkopiering
|
||||
HTTrack: could not save profile for '%s'!
|
||||
HTTrack: kunne ikke gemme profil for '%s'!
|
||||
Proxy type:
|
||||
Proxytype:
|
||||
Proxy protocol. HTTP: standard proxy. HTTP (CONNECT tunnel): sends every request through a CONNECT tunnel, for CONNECT-only proxies like Tor's HTTPTunnelPort. SOCKS5: default port 1080.
|
||||
Proxyprotokol. HTTP: standardproxy. HTTP (CONNECT-tunnel): sender hver forespørgsel gennem en CONNECT-tunnel, til proxyer der kun understøtter CONNECT som Tors HTTPTunnelPort. SOCKS5: standardport 1080.
|
||||
Load cookies from file:
|
||||
Indlæs cookies fra fil:
|
||||
Preload cookies from a Netscape cookies.txt file before crawling.
|
||||
Indlæs cookies fra en Netscape cookies.txt-fil, før crawlingen starter.
|
||||
Pause between files:
|
||||
Pause mellem filer:
|
||||
Random delay between file downloads, in seconds. Use MIN:MAX for a random range (e.g. 2:8).
|
||||
Tilfældig forsinkelse mellem filoverførsler, i sekunder. Brug MIN:MAX for et tilfældigt interval (f.eks. 2:8).
|
||||
Keep the www. prefix (do not merge www.host with host)
|
||||
Behold www.-præfikset (sammenlæg ikke www.host med host)
|
||||
Do not treat www.host and host as the same site.
|
||||
Behandl ikke www.host og host som det samme websted.
|
||||
Keep double slashes in URLs
|
||||
Behold dobbelte skråstreger i URL'er
|
||||
Do not collapse duplicate slashes in URLs.
|
||||
Sammenfold ikke gentagne skråstreger i URL'er.
|
||||
Keep the original query-string order
|
||||
Behold den oprindelige rækkefølge i forespørgselsstrengen
|
||||
Do not reorder query-string parameters when deduplicating URLs.
|
||||
Omorden ikke forespørgselsstrengens parametre, når dublerede URL'er fjernes.
|
||||
Strip query keys:
|
||||
Fjern forespørgselsnøgler:
|
||||
Comma-separated query keys to drop from the saved-file naming (e.g. sid,utm_source).
|
||||
Kommaseparerede forespørgselsnøgler, der udelades i navngivningen af gemte filer (f.eks. sid,utm_source).
|
||||
|
||||
@@ -928,3 +928,31 @@ Server terminated
|
||||
Der Server wurde beendet
|
||||
A fatal error has occurred during this mirror
|
||||
Fataler Fehler während der Webseiten-Kopie
|
||||
Proxy type:
|
||||
Proxy-Typ:
|
||||
Proxy protocol. HTTP: standard proxy. HTTP (CONNECT tunnel): sends every request through a CONNECT tunnel, for CONNECT-only proxies like Tor's HTTPTunnelPort. SOCKS5: default port 1080.
|
||||
Proxy-Protokoll. HTTP: normaler Proxy. HTTP (CONNECT-Tunnel): sendet jede Anfrage durch einen CONNECT-Tunnel, für Proxys, die nur CONNECT unterstützen, wie Tors HTTPTunnelPort. SOCKS5: Standardport 1080.
|
||||
Load cookies from file:
|
||||
Cookies aus Datei laden:
|
||||
Preload cookies from a Netscape cookies.txt file before crawling.
|
||||
Cookies aus einer Netscape-cookies.txt-Datei laden, bevor das Crawlen beginnt.
|
||||
Pause between files:
|
||||
Pause zwischen Dateien:
|
||||
Random delay between file downloads, in seconds. Use MIN:MAX for a random range (e.g. 2:8).
|
||||
Zufällige Verzögerung zwischen Datei-Downloads, in Sekunden. MIN:MAX für einen Zufallsbereich verwenden (z. B. 2:8).
|
||||
Keep the www. prefix (do not merge www.host with host)
|
||||
www.-Präfix beibehalten (www.host nicht mit host zusammenführen)
|
||||
Do not treat www.host and host as the same site.
|
||||
www.host und host nicht als dieselbe Website behandeln.
|
||||
Keep double slashes in URLs
|
||||
Doppelte Schrägstriche in URLs beibehalten
|
||||
Do not collapse duplicate slashes in URLs.
|
||||
Doppelte Schrägstriche in URLs nicht zusammenführen.
|
||||
Keep the original query-string order
|
||||
Ursprüngliche Reihenfolge des Query-Strings beibehalten
|
||||
Do not reorder query-string parameters when deduplicating URLs.
|
||||
Query-String-Parameter beim Entfernen doppelter URLs nicht neu anordnen.
|
||||
Strip query keys:
|
||||
Query-Schlüssel entfernen:
|
||||
Comma-separated query keys to drop from the saved-file naming (e.g. sid,utm_source).
|
||||
Kommagetrennte Query-Schlüssel, die bei der Benennung gespeicherter Dateien entfallen (z. B. sid,utm_source).
|
||||
|
||||
@@ -928,3 +928,31 @@ Server terminated
|
||||
|
||||
A fatal error has occurred during this mirror
|
||||
|
||||
Proxy type:
|
||||
Proxy tüüp:
|
||||
Proxy protocol. HTTP: standard proxy. HTTP (CONNECT tunnel): sends every request through a CONNECT tunnel, for CONNECT-only proxies like Tor's HTTPTunnelPort. SOCKS5: default port 1080.
|
||||
Puhverserveri protokoll. HTTP: tavaline puhverserver. HTTP (CONNECT-tunnel): saadab iga päringu läbi CONNECT-tunneli, ainult CONNECT-it toetavate puhverserverite jaoks nagu Tori HTTPTunnelPort. SOCKS5: vaikeport 1080.
|
||||
Load cookies from file:
|
||||
Lae küpsised failist:
|
||||
Preload cookies from a Netscape cookies.txt file before crawling.
|
||||
Lae küpsised eelnevalt Netscape cookies.txt failist enne kopeerimist.
|
||||
Pause between files:
|
||||
Paus failide vahel:
|
||||
Random delay between file downloads, in seconds. Use MIN:MAX for a random range (e.g. 2:8).
|
||||
Juhuslik viivitus failide allalaadimiste vahel, sekundites. Juhusliku vahemiku jaoks kasuta MIN:MAX (nt 2:8).
|
||||
Keep the www. prefix (do not merge www.host with host)
|
||||
Säilita www. eesliide (ära ühenda www.host ja host)
|
||||
Do not treat www.host and host as the same site.
|
||||
Ära käsitle www.host ja host sama saidina.
|
||||
Keep double slashes in URLs
|
||||
Säilita topeltkaldkriipsud URL-ides
|
||||
Do not collapse duplicate slashes in URLs.
|
||||
Ära ühenda korduvaid kaldkriipse URL-ides.
|
||||
Keep the original query-string order
|
||||
Säilita päringustringi algne järjekord
|
||||
Do not reorder query-string parameters when deduplicating URLs.
|
||||
Ära järjesta päringustringi parameetreid ümber URL-ide korduste eemaldamisel.
|
||||
Strip query keys:
|
||||
Eemalda päringuvõtmed:
|
||||
Comma-separated query keys to drop from the saved-file naming (e.g. sid,utm_source).
|
||||
Komadega eraldatud päringuvõtmed, mis jäetakse salvestatud faili nimest välja (nt sid,utm_source).
|
||||
|
||||
@@ -976,3 +976,31 @@ Click on this notification to restart the interrupted mirror
|
||||
Click on this notification to restart the interrupted mirror
|
||||
HTTrack: could not save profile for '%s'!
|
||||
HTTrack: could not save profile for '%s'!
|
||||
Proxy type:
|
||||
Proxy type:
|
||||
Proxy protocol. HTTP: standard proxy. HTTP (CONNECT tunnel): sends every request through a CONNECT tunnel, for CONNECT-only proxies like Tor's HTTPTunnelPort. SOCKS5: default port 1080.
|
||||
Proxy protocol. HTTP: standard proxy. HTTP (CONNECT tunnel): sends every request through a CONNECT tunnel, for CONNECT-only proxies like Tor's HTTPTunnelPort. SOCKS5: default port 1080.
|
||||
Load cookies from file:
|
||||
Load cookies from file:
|
||||
Preload cookies from a Netscape cookies.txt file before crawling.
|
||||
Preload cookies from a Netscape cookies.txt file before crawling.
|
||||
Pause between files:
|
||||
Pause between files:
|
||||
Random delay between file downloads, in seconds. Use MIN:MAX for a random range (e.g. 2:8).
|
||||
Random delay between file downloads, in seconds. Use MIN:MAX for a random range (e.g. 2:8).
|
||||
Keep the www. prefix (do not merge www.host with host)
|
||||
Keep the www. prefix (do not merge www.host with host)
|
||||
Do not treat www.host and host as the same site.
|
||||
Do not treat www.host and host as the same site.
|
||||
Keep double slashes in URLs
|
||||
Keep double slashes in URLs
|
||||
Do not collapse duplicate slashes in URLs.
|
||||
Do not collapse duplicate slashes in URLs.
|
||||
Keep the original query-string order
|
||||
Keep the original query-string order
|
||||
Do not reorder query-string parameters when deduplicating URLs.
|
||||
Do not reorder query-string parameters when deduplicating URLs.
|
||||
Strip query keys:
|
||||
Strip query keys:
|
||||
Comma-separated query keys to drop from the saved-file naming (e.g. sid,utm_source).
|
||||
Comma-separated query keys to drop from the saved-file naming (e.g. sid,utm_source).
|
||||
|
||||
@@ -931,3 +931,31 @@ Palvelin lopetettu
|
||||
A fatal error has occurred during this mirror
|
||||
Tällä peilillä tapahtui vakava virhe
|
||||
|
||||
Proxy type:
|
||||
Välityspalvelimen tyyppi:
|
||||
Proxy protocol. HTTP: standard proxy. HTTP (CONNECT tunnel): sends every request through a CONNECT tunnel, for CONNECT-only proxies like Tor's HTTPTunnelPort. SOCKS5: default port 1080.
|
||||
Välityspalvelimen protokolla. HTTP: tavallinen välityspalvelin. HTTP (CONNECT-tunneli): lähettää jokaisen pyynnön CONNECT-tunnelin kautta, vain CONNECT-yhteyksiä tukeville välityspalvelimille kuten Torin HTTPTunnelPort. SOCKS5: oletusportti 1080.
|
||||
Load cookies from file:
|
||||
Lataa evästeet tiedostosta:
|
||||
Preload cookies from a Netscape cookies.txt file before crawling.
|
||||
Lataa evästeet Netscape cookies.txt -tiedostosta ennen sivuston läpikäyntiä.
|
||||
Pause between files:
|
||||
Tauko tiedostojen välillä:
|
||||
Random delay between file downloads, in seconds. Use MIN:MAX for a random range (e.g. 2:8).
|
||||
Satunnainen viive tiedostolatausten välillä, sekunteina. Käytä muotoa MIN:MAX satunnaista väliä varten (esim. 2:8).
|
||||
Keep the www. prefix (do not merge www.host with host)
|
||||
Säilytä www.-etuliite (älä yhdistä www.host- ja host-osoitteita)
|
||||
Do not treat www.host and host as the same site.
|
||||
Älä käsittele www.host- ja host-osoitteita samana sivustona.
|
||||
Keep double slashes in URLs
|
||||
Säilytä kaksoiskenoviivat URL-osoitteissa
|
||||
Do not collapse duplicate slashes in URLs.
|
||||
Älä yhdistä toistuvia kenoviivoja URL-osoitteissa.
|
||||
Keep the original query-string order
|
||||
Säilytä kyselymerkkijonon alkuperäinen järjestys
|
||||
Do not reorder query-string parameters when deduplicating URLs.
|
||||
Älä järjestä kyselymerkkijonon parametreja uudelleen, kun URL-osoitteiden kaksoiskappaleet poistetaan.
|
||||
Strip query keys:
|
||||
Poista kyselyavaimet:
|
||||
Comma-separated query keys to drop from the saved-file naming (e.g. sid,utm_source).
|
||||
Pilkuin erotellut kyselyavaimet, jotka jätetään pois tallennettujen tiedostojen nimeämisestä (esim. sid,utm_source).
|
||||
|
||||
@@ -976,3 +976,31 @@ Build a mail archive
|
||||
Construire une archive mail
|
||||
Default referer URL
|
||||
Champ referer par défaut
|
||||
Proxy type:
|
||||
Type de proxy :
|
||||
Proxy protocol. HTTP: standard proxy. HTTP (CONNECT tunnel): sends every request through a CONNECT tunnel, for CONNECT-only proxies like Tor's HTTPTunnelPort. SOCKS5: default port 1080.
|
||||
Protocole du proxy. HTTP : proxy standard. HTTP (tunnel CONNECT) : envoie chaque requête via un tunnel CONNECT, pour les proxys acceptant uniquement CONNECT comme le HTTPTunnelPort de Tor. SOCKS5 : port par défaut 1080.
|
||||
Load cookies from file:
|
||||
Charger les cookies depuis un fichier :
|
||||
Preload cookies from a Netscape cookies.txt file before crawling.
|
||||
Précharger les cookies depuis un fichier Netscape cookies.txt avant la copie du site.
|
||||
Pause between files:
|
||||
Pause entre les fichiers :
|
||||
Random delay between file downloads, in seconds. Use MIN:MAX for a random range (e.g. 2:8).
|
||||
Délai aléatoire entre les téléchargements de fichiers, en secondes. Utilisez MIN:MAX pour une plage aléatoire (par ex. 2:8).
|
||||
Keep the www. prefix (do not merge www.host with host)
|
||||
Conserver le préfixe www. (ne pas fusionner www.host avec host)
|
||||
Do not treat www.host and host as the same site.
|
||||
Ne pas traiter www.host et host comme le même site.
|
||||
Keep double slashes in URLs
|
||||
Conserver les doubles barres obliques dans les URL
|
||||
Do not collapse duplicate slashes in URLs.
|
||||
Ne pas réduire les barres obliques en double dans les URL.
|
||||
Keep the original query-string order
|
||||
Conserver l'ordre d'origine de la query string
|
||||
Do not reorder query-string parameters when deduplicating URLs.
|
||||
Ne pas réordonner les paramètres de la query string lors de la déduplication des URL.
|
||||
Strip query keys:
|
||||
Supprimer les clés de query string :
|
||||
Comma-separated query keys to drop from the saved-file naming (e.g. sid,utm_source).
|
||||
Clés de query string à retirer du nommage des fichiers enregistrés, séparées par des virgules (par ex. sid,utm_source).
|
||||
|
||||
@@ -930,3 +930,31 @@ Server terminated
|
||||
Ακυρώθηκε από τον εξυπηρετητή
|
||||
A fatal error has occurred during this mirror
|
||||
Ένα καταστροφικό σφάλμα προκλήθηκε κατά την αντιγραφή αυτού του τόπου
|
||||
Proxy type:
|
||||
Τύπος proxy:
|
||||
Proxy protocol. HTTP: standard proxy. HTTP (CONNECT tunnel): sends every request through a CONNECT tunnel, for CONNECT-only proxies like Tor's HTTPTunnelPort. SOCKS5: default port 1080.
|
||||
Πρωτόκολλο διαμεσολαβητή. HTTP: τυπικός διαμεσολαβητής. HTTP (σήραγγα CONNECT): στέλνει κάθε αίτημα μέσω σήραγγας CONNECT, για διαμεσολαβητές που υποστηρίζουν μόνο CONNECT όπως το HTTPTunnelPort του Tor. SOCKS5: προεπιλεγμένη θύρα 1080.
|
||||
Load cookies from file:
|
||||
Φόρτωση cookies από αρχείο:
|
||||
Preload cookies from a Netscape cookies.txt file before crawling.
|
||||
Προφόρτωση των cookies από ένα αρχείο Netscape cookies.txt πριν την ανίχνευση.
|
||||
Pause between files:
|
||||
Παύση μεταξύ αρχείων:
|
||||
Random delay between file downloads, in seconds. Use MIN:MAX for a random range (e.g. 2:8).
|
||||
Τυχαία καθυστέρηση μεταξύ των λήψεων αρχείων, σε δευτερόλεπτα. Χρησιμοποιήστε MIN:MAX για τυχαίο εύρος (π.χ. 2:8).
|
||||
Keep the www. prefix (do not merge www.host with host)
|
||||
Διατήρηση του προθέματος www. (χωρίς συγχώνευση του www.host με το host)
|
||||
Do not treat www.host and host as the same site.
|
||||
Να μην θεωρούνται τα www.host και host ως ο ίδιος ιστότοπος.
|
||||
Keep double slashes in URLs
|
||||
Διατήρηση των διπλών καθέτων στα URL
|
||||
Do not collapse duplicate slashes in URLs.
|
||||
Να μην συμπτύσσονται οι διπλές κάθετοι στα URL.
|
||||
Keep the original query-string order
|
||||
Διατήρηση της αρχικής σειράς του ερωτήματος αναζήτησης
|
||||
Do not reorder query-string parameters when deduplicating URLs.
|
||||
Να μην αναδιατάσσονται οι παράμετροι του ερωτήματος αναζήτησης κατά την αφαίρεση διπλότυπων URL.
|
||||
Strip query keys:
|
||||
Αφαίρεση κλειδιών ερωτήματος:
|
||||
Comma-separated query keys to drop from the saved-file naming (e.g. sid,utm_source).
|
||||
Κλειδιά ερωτήματος χωρισμένα με κόμμα, που θα αφαιρεθούν από την ονομασία των αποθηκευμένων αρχείων (π.χ. sid,utm_source).
|
||||
|
||||
@@ -928,3 +928,31 @@ Server terminated
|
||||
Server disconnesso
|
||||
A fatal error has occurred during this mirror
|
||||
Si è verificato un errore fatale durante la copia
|
||||
Proxy type:
|
||||
Tipo di proxy:
|
||||
Proxy protocol. HTTP: standard proxy. HTTP (CONNECT tunnel): sends every request through a CONNECT tunnel, for CONNECT-only proxies like Tor's HTTPTunnelPort. SOCKS5: default port 1080.
|
||||
Protocollo del proxy. HTTP: proxy standard. HTTP (tunnel CONNECT): invia ogni richiesta attraverso un tunnel CONNECT, per proxy che supportano solo CONNECT come l'HTTPTunnelPort di Tor. SOCKS5: porta predefinita 1080.
|
||||
Load cookies from file:
|
||||
Carica i cookie da un file:
|
||||
Preload cookies from a Netscape cookies.txt file before crawling.
|
||||
Precarica i cookie da un file Netscape cookies.txt prima della copia.
|
||||
Pause between files:
|
||||
Pausa tra i file:
|
||||
Random delay between file downloads, in seconds. Use MIN:MAX for a random range (e.g. 2:8).
|
||||
Ritardo casuale tra i download dei file, in secondi. Usa MIN:MAX per un intervallo casuale (ad es. 2:8).
|
||||
Keep the www. prefix (do not merge www.host with host)
|
||||
Mantieni il prefisso www. (non unire www.host con host)
|
||||
Do not treat www.host and host as the same site.
|
||||
Non trattare www.host e host come lo stesso sito.
|
||||
Keep double slashes in URLs
|
||||
Mantieni le doppie barre negli URL
|
||||
Do not collapse duplicate slashes in URLs.
|
||||
Non ridurre le barre duplicate negli URL.
|
||||
Keep the original query-string order
|
||||
Mantieni l'ordine originale della query string
|
||||
Do not reorder query-string parameters when deduplicating URLs.
|
||||
Non riordinare i parametri della query string durante la deduplicazione degli URL.
|
||||
Strip query keys:
|
||||
Rimuovi chiavi della query string:
|
||||
Comma-separated query keys to drop from the saved-file naming (e.g. sid,utm_source).
|
||||
Chiavi della query string, separate da virgole, da rimuovere dai nomi dei file salvati (ad es. sid,utm_source).
|
||||
|
||||
@@ -928,3 +928,31 @@ Server terminated
|
||||
|
||||
A fatal error has occurred during this mirror
|
||||
|
||||
Proxy type:
|
||||
プロキシの種類:
|
||||
Proxy protocol. HTTP: standard proxy. HTTP (CONNECT tunnel): sends every request through a CONNECT tunnel, for CONNECT-only proxies like Tor's HTTPTunnelPort. SOCKS5: default port 1080.
|
||||
プロキシのプロトコル。HTTP: 標準のプロキシ。HTTP (CONNECT トンネル): すべてのリクエストを CONNECT トンネル経由で送信します。Tor の HTTPTunnelPort のような CONNECT のみのプロキシ用です。SOCKS5: 既定ポート 1080。
|
||||
Load cookies from file:
|
||||
クッキーをファイルから読み込む:
|
||||
Preload cookies from a Netscape cookies.txt file before crawling.
|
||||
クロールを開始する前に Netscape の cookies.txt ファイルからクッキーを読み込みます。
|
||||
Pause between files:
|
||||
ファイル間の待機:
|
||||
Random delay between file downloads, in seconds. Use MIN:MAX for a random range (e.g. 2:8).
|
||||
ファイルのダウンロード間のランダムな遅延(秒)。範囲を指定するには MIN:MAX を使用します (例: 2:8)。
|
||||
Keep the www. prefix (do not merge www.host with host)
|
||||
www. プレフィックスを保持する (www.host と host を統合しない)
|
||||
Do not treat www.host and host as the same site.
|
||||
www.host と host を同じサイトとして扱いません。
|
||||
Keep double slashes in URLs
|
||||
URL 内の二重スラッシュを保持する
|
||||
Do not collapse duplicate slashes in URLs.
|
||||
URL 内の連続したスラッシュをまとめません。
|
||||
Keep the original query-string order
|
||||
クエリ文字列の元の順序を保持する
|
||||
Do not reorder query-string parameters when deduplicating URLs.
|
||||
URL の重複排除時にクエリ文字列のパラメータを並べ替えません。
|
||||
Strip query keys:
|
||||
削除するクエリキー:
|
||||
Comma-separated query keys to drop from the saved-file naming (e.g. sid,utm_source).
|
||||
保存ファイル名の生成から除外するクエリキーをカンマ区切りで指定します (例: sid,utm_source)。
|
||||
|
||||
@@ -928,3 +928,31 @@ Server terminated
|
||||
Ñåðâåðîò å ïðåêèíàò
|
||||
A fatal error has occurred during this mirror
|
||||
Íàñòàíà ôàòàëíà ãðåøêà ïðè îâî¼ mirror
|
||||
Proxy type:
|
||||
ÂØß ÝÐ ßàÞÚáØ:
|
||||
Proxy protocol. HTTP: standard proxy. HTTP (CONNECT tunnel): sends every request through a CONNECT tunnel, for CONNECT-only proxies like Tor's HTTPTunnelPort. SOCKS5: default port 1080.
|
||||
¿àÞâÞÚÞÛ ÝÐ ßàÞÚáØ. HTTP: áâÐÝÔÐàÔÕÝ ßàÞÚáØ. HTTP (âãÝÕÛ CONNECT): ÓÞ ØáßàÐüÐ áÕÚÞÕ ÑÐàÐúÕ ßàÕÚã âãÝÕÛ CONNECT, ×Ð ßàÞÚáØ èâÞ ßÞÔÔàÖãÒÐÐâ áÐÜÞ CONNECT ÚÐÚÞ HTTPTunnelPort ÝÐ Tor. SOCKS5: áâÐÝÔÐàÔÝÐ ßÞàâÐ 1080.
|
||||
Load cookies from file:
|
||||
²çØâÐø ÚÞÛÐçØúÐ ÞÔ ÔÐâÞâÕÚÐ:
|
||||
Preload cookies from a Netscape cookies.txt file before crawling.
|
||||
¾ÔÝÐßàÕÔ ÒçØâÐø ÚÞÛÐçØúÐ ÞÔ ÔÐâÞâÕÚÐ Netscape cookies.txt ßàÕÔ ßàÕ×ÕÜÐúÕâÞ.
|
||||
Pause between files:
|
||||
¿Ðã×Ð ÜÕóã ÔÐâÞâÕÚØ:
|
||||
Random delay between file downloads, in seconds. Use MIN:MAX for a random range (e.g. 2:8).
|
||||
ÁÛãçÐøÝÞ ÔÞæÝÕúÕ ÜÕóã ßàÕ×ÕÜÐúÐâÐ ÝÐ ÔÐâÞâÕÚØ, ÒÞ áÕÚãÝÔØ. ºÞàØáâØ MIN:MAX ×Ð áÛãçÐÕÝ ÞßáÕÓ (ÝÐ ßàØÜÕà 2:8).
|
||||
Keep the www. prefix (do not merge www.host with host)
|
||||
·ÐÔàÖØ ÓÞ ßàÕäØÚáÞâ www. (ÝÕ áßÞøãÒÐø www.host áÞ host)
|
||||
Do not treat www.host and host as the same site.
|
||||
½Õ âàÕâØàÐø ÓØ www.host Ø host ÚÐÚÞ Øáâ áÐøâ.
|
||||
Keep double slashes in URLs
|
||||
·ÐÔàÖØ ÓØ ÔÒÞøÝØâÕ ÚÞáØ æàâØ ÒÞ URL
|
||||
Do not collapse duplicate slashes in URLs.
|
||||
½Õ ÞâáâàÐÝãÒÐø ÓØ ßÞÒâÞàÕÝØâÕ ÚÞáØ æàâØ ÒÞ URL.
|
||||
Keep the original query-string order
|
||||
·ÐÔàÖØ ÓÞ Ø×ÒÞàÝØÞâ àÕÔÞáÛÕÔ ÝÐ ßÐàÐÜÕâàØâÕ ÒÞ ÑÐàÐúÕâÞ
|
||||
Do not reorder query-string parameters when deduplicating URLs.
|
||||
½Õ ÜÕÝãÒÐø ÓÞ àÕÔÞáÛÕÔÞâ ÝÐ ßÐàÐÜÕâàØâÕ ÝÐ ÑÐàÐúÕâÞ ßàØ ÞâáâàÐÝãÒÐúÕ ÔãßÛØÚÐâØ URL.
|
||||
Strip query keys:
|
||||
¾âáâàÐÝØ ÚÛãçÕÒØ ÞÔ ÑÐàÐúÕâÞ:
|
||||
Comma-separated query keys to drop from the saved-file naming (e.g. sid,utm_source).
|
||||
ºÛãçÕÒØ ÞÔ ÑÐàÐúÕâÞ, ÞÔÔÕÛÕÝØ áÞ ×ÐߨàÚÐ, èâÞ áÕ ÞâáâàÐÝãÒÐÐâ ÞÔ ØÜÕâÞ ÝÐ ×ÐçãÒÐÝÐâÐ ÔÐâÞâÕÚÐ (ÝÐ ßàØÜÕà sid,utm_source).
|
||||
|
||||
@@ -928,3 +928,31 @@ Server terminated
|
||||
A kiszolgáló befejezte a kapcsolatot
|
||||
A fatal error has occurred during this mirror
|
||||
Végzetes hiba történt a tükrözés közben
|
||||
Proxy type:
|
||||
Proxy típusa:
|
||||
Proxy protocol. HTTP: standard proxy. HTTP (CONNECT tunnel): sends every request through a CONNECT tunnel, for CONNECT-only proxies like Tor's HTTPTunnelPort. SOCKS5: default port 1080.
|
||||
Proxy protokoll. HTTP: szabványos proxy. HTTP (CONNECT alagút): minden kérést CONNECT alagúton keresztül küld, a csak CONNECT-et támogató proxykhoz, mint a Tor HTTPTunnelPortja. SOCKS5: alapértelmezett port 1080.
|
||||
Load cookies from file:
|
||||
Sütik betöltése fájlból:
|
||||
Preload cookies from a Netscape cookies.txt file before crawling.
|
||||
Sütik elõzetes betöltése egy Netscape cookies.txt fájlból a tükrözés elõtt.
|
||||
Pause between files:
|
||||
Szünet a fájlok között:
|
||||
Random delay between file downloads, in seconds. Use MIN:MAX for a random range (e.g. 2:8).
|
||||
Véletlenszerû késleltetés a fájlletöltések között, másodpercben. Véletlen tartományhoz használja a MIN:MAX formát (pl. 2:8).
|
||||
Keep the www. prefix (do not merge www.host with host)
|
||||
A www. elõtag megtartása (ne vonja össze a www.host és a host címet)
|
||||
Do not treat www.host and host as the same site.
|
||||
Ne kezelje a www.host és a host címet ugyanazon webhelyként.
|
||||
Keep double slashes in URLs
|
||||
Dupla perjelek megtartása az URL-ekben
|
||||
Do not collapse duplicate slashes in URLs.
|
||||
Ne vonja össze az ismétlõdõ perjeleket az URL-ekben.
|
||||
Keep the original query-string order
|
||||
Az eredeti lekérdezési szöveg sorrendjének megtartása
|
||||
Do not reorder query-string parameters when deduplicating URLs.
|
||||
Ne rendezze át a lekérdezési szöveg paramétereit az ismétlõdõ URL-ek kiszûrésekor.
|
||||
Strip query keys:
|
||||
Lekérdezési kulcsok eltávolítása:
|
||||
Comma-separated query keys to drop from the saved-file naming (e.g. sid,utm_source).
|
||||
Vesszõvel elválasztott lekérdezési kulcsok, amelyeket el kell hagyni a mentett fájl elnevezésébõl (pl. sid,utm_source).
|
||||
|
||||
@@ -928,3 +928,31 @@ Server terminated
|
||||
Server beeindigd
|
||||
A fatal error has occurred during this mirror
|
||||
Een fatale fout is opgetreden tijdens deze spiegeling
|
||||
Proxy type:
|
||||
Proxytype:
|
||||
Proxy protocol. HTTP: standard proxy. HTTP (CONNECT tunnel): sends every request through a CONNECT tunnel, for CONNECT-only proxies like Tor's HTTPTunnelPort. SOCKS5: default port 1080.
|
||||
Proxyprotocol. HTTP: standaardproxy. HTTP (CONNECT-tunnel): stuurt elke aanvraag via een CONNECT-tunnel, voor proxy's die alleen CONNECT ondersteunen zoals Tors HTTPTunnelPort. SOCKS5: standaardpoort 1080.
|
||||
Load cookies from file:
|
||||
Cookies uit bestand laden:
|
||||
Preload cookies from a Netscape cookies.txt file before crawling.
|
||||
Cookies vooraf laden uit een Netscape cookies.txt-bestand voordat het crawlen begint.
|
||||
Pause between files:
|
||||
Pauze tussen bestanden:
|
||||
Random delay between file downloads, in seconds. Use MIN:MAX for a random range (e.g. 2:8).
|
||||
Willekeurige vertraging tussen bestandsdownloads, in seconden. Gebruik MIN:MAX voor een willekeurig bereik (bijv. 2:8).
|
||||
Keep the www. prefix (do not merge www.host with host)
|
||||
www.-voorvoegsel behouden (www.host niet samenvoegen met host)
|
||||
Do not treat www.host and host as the same site.
|
||||
Behandel www.host en host niet als dezelfde site.
|
||||
Keep double slashes in URLs
|
||||
Dubbele schuine strepen in URL's behouden
|
||||
Do not collapse duplicate slashes in URLs.
|
||||
Dubbele schuine strepen in URL's niet samenvoegen.
|
||||
Keep the original query-string order
|
||||
Oorspronkelijke volgorde van de query string behouden
|
||||
Do not reorder query-string parameters when deduplicating URLs.
|
||||
Query string-parameters niet herordenen bij het ontdubbelen van URL's.
|
||||
Strip query keys:
|
||||
Query-sleutels verwijderen:
|
||||
Comma-separated query keys to drop from the saved-file naming (e.g. sid,utm_source).
|
||||
Door komma's gescheiden query-sleutels die bij het benoemen van opgeslagen bestanden worden weggelaten (bijv. sid,utm_source).
|
||||
|
||||
@@ -928,3 +928,31 @@ Server terminated
|
||||
|
||||
A fatal error has occurred during this mirror
|
||||
|
||||
Proxy type:
|
||||
Proxytype:
|
||||
Proxy protocol. HTTP: standard proxy. HTTP (CONNECT tunnel): sends every request through a CONNECT tunnel, for CONNECT-only proxies like Tor's HTTPTunnelPort. SOCKS5: default port 1080.
|
||||
Proxyprotokoll. HTTP: standard proxy. HTTP (CONNECT-tunnel): sender hver forespørsel gjennom en CONNECT-tunnel, for proxyer som bare støtter CONNECT som Tors HTTPTunnelPort. SOCKS5: standardport 1080.
|
||||
Load cookies from file:
|
||||
Last inn cookies fra fil:
|
||||
Preload cookies from a Netscape cookies.txt file before crawling.
|
||||
Last inn cookies fra en Netscape cookies.txt-fil før crawlingen starter.
|
||||
Pause between files:
|
||||
Pause mellom filer:
|
||||
Random delay between file downloads, in seconds. Use MIN:MAX for a random range (e.g. 2:8).
|
||||
Tilfeldig forsinkelse mellom filnedlastinger, i sekunder. Bruk MIN:MAX for et tilfeldig intervall (f.eks. 2:8).
|
||||
Keep the www. prefix (do not merge www.host with host)
|
||||
Behold www.-prefikset (slå ikke sammen www.host med host)
|
||||
Do not treat www.host and host as the same site.
|
||||
Behandle ikke www.host og host som samme nettsted.
|
||||
Keep double slashes in URLs
|
||||
Behold doble skråstreker i URL-er
|
||||
Do not collapse duplicate slashes in URLs.
|
||||
Slå ikke sammen gjentatte skråstreker i URL-er.
|
||||
Keep the original query-string order
|
||||
Behold den opprinnelige rekkefølgen i spørrestrengen
|
||||
Do not reorder query-string parameters when deduplicating URLs.
|
||||
Endre ikke rekkefølgen på spørrestrengens parametere når dupliserte URL-er fjernes.
|
||||
Strip query keys:
|
||||
Fjern spørrenøkler:
|
||||
Comma-separated query keys to drop from the saved-file naming (e.g. sid,utm_source).
|
||||
Kommaseparerte spørrenøkler som utelates i navngivingen av lagrede filer (f.eks. sid,utm_source).
|
||||
|
||||
@@ -928,3 +928,31 @@ Server terminated
|
||||
Serwer zakonczyl prace
|
||||
A fatal error has occurred during this mirror
|
||||
Podczas tworzenia lustra wydarzyl sie fatalny blad.
|
||||
Proxy type:
|
||||
Typ proxy:
|
||||
Proxy protocol. HTTP: standard proxy. HTTP (CONNECT tunnel): sends every request through a CONNECT tunnel, for CONNECT-only proxies like Tor's HTTPTunnelPort. SOCKS5: default port 1080.
|
||||
Protokó³ proxy. HTTP: standardowe proxy. HTTP (tunel CONNECT): wysy³a ka¿de ¿±danie przez tunel CONNECT, dla proxy obs³uguj±cych tylko CONNECT, jak HTTPTunnelPort w Torze. SOCKS5: port domy¶lny 1080.
|
||||
Load cookies from file:
|
||||
Wczytaj ciasteczka z pliku:
|
||||
Preload cookies from a Netscape cookies.txt file before crawling.
|
||||
Wczytaj ciasteczka z pliku Netscape cookies.txt przed rozpoczêciem pobierania.
|
||||
Pause between files:
|
||||
Pauza miêdzy plikami:
|
||||
Random delay between file downloads, in seconds. Use MIN:MAX for a random range (e.g. 2:8).
|
||||
Losowe opó¼nienie miêdzy pobieraniem plików, w sekundach. U¿yj MIN:MAX dla losowego zakresu (np. 2:8).
|
||||
Keep the www. prefix (do not merge www.host with host)
|
||||
Zachowaj przedrostek www. (nie ³±cz www.host z host)
|
||||
Do not treat www.host and host as the same site.
|
||||
Nie traktuj www.host i host jako tej samej witryny.
|
||||
Keep double slashes in URLs
|
||||
Zachowaj podwójne uko¶niki w adresach URL
|
||||
Do not collapse duplicate slashes in URLs.
|
||||
Nie scalaj powtórzonych uko¶ników w adresach URL.
|
||||
Keep the original query-string order
|
||||
Zachowaj oryginaln± kolejno¶æ ci±gu zapytania
|
||||
Do not reorder query-string parameters when deduplicating URLs.
|
||||
Nie zmieniaj kolejno¶ci parametrów zapytania podczas usuwania duplikatów adresów URL.
|
||||
Strip query keys:
|
||||
Usuñ klucze zapytania:
|
||||
Comma-separated query keys to drop from the saved-file naming (e.g. sid,utm_source).
|
||||
Rozdzielone przecinkami klucze zapytania pomijane przy nazywaniu zapisanych plików (np. sid,utm_source).
|
||||
|
||||
@@ -976,3 +976,31 @@ Click on this notification to restart the interrupted mirror
|
||||
Clique nesta notificação para reiniciar o espelho interrompido
|
||||
HTTrack: could not save profile for '%s'!
|
||||
HTTrack: não foi possível salvar o perfil para '%s'!
|
||||
Proxy type:
|
||||
Tipo de proxy:
|
||||
Proxy protocol. HTTP: standard proxy. HTTP (CONNECT tunnel): sends every request through a CONNECT tunnel, for CONNECT-only proxies like Tor's HTTPTunnelPort. SOCKS5: default port 1080.
|
||||
Protocolo do proxy. HTTP: proxy padrão. HTTP (túnel CONNECT): envia cada requisição através de um túnel CONNECT, para proxies que só suportam CONNECT como o HTTPTunnelPort do Tor. SOCKS5: porta padrão 1080.
|
||||
Load cookies from file:
|
||||
Carregar cookies de um arquivo:
|
||||
Preload cookies from a Netscape cookies.txt file before crawling.
|
||||
Pré-carregar cookies de um arquivo Netscape cookies.txt antes de iniciar a cópia.
|
||||
Pause between files:
|
||||
Pausa entre arquivos:
|
||||
Random delay between file downloads, in seconds. Use MIN:MAX for a random range (e.g. 2:8).
|
||||
Atraso aleatório entre downloads de arquivos, em segundos. Use MIN:MAX para um intervalo aleatório (ex.: 2:8).
|
||||
Keep the www. prefix (do not merge www.host with host)
|
||||
Manter o prefixo www. (não mesclar www.host com host)
|
||||
Do not treat www.host and host as the same site.
|
||||
Não tratar www.host e host como o mesmo site.
|
||||
Keep double slashes in URLs
|
||||
Manter as barras duplas nas URLs
|
||||
Do not collapse duplicate slashes in URLs.
|
||||
Não reduzir as barras duplicadas nas URLs.
|
||||
Keep the original query-string order
|
||||
Manter a ordem original da query string
|
||||
Do not reorder query-string parameters when deduplicating URLs.
|
||||
Não reordenar os parâmetros da query string ao remover URLs duplicadas.
|
||||
Strip query keys:
|
||||
Remover chaves da query string:
|
||||
Comma-separated query keys to drop from the saved-file naming (e.g. sid,utm_source).
|
||||
Chaves da query string, separadas por vírgulas, a serem removidas da nomeação dos arquivos salvos (ex.: sid,utm_source).
|
||||
|
||||
@@ -928,3 +928,31 @@ Server terminated
|
||||
|
||||
A fatal error has occurred during this mirror
|
||||
|
||||
Proxy type:
|
||||
Tipo de proxy:
|
||||
Proxy protocol. HTTP: standard proxy. HTTP (CONNECT tunnel): sends every request through a CONNECT tunnel, for CONNECT-only proxies like Tor's HTTPTunnelPort. SOCKS5: default port 1080.
|
||||
Protocolo do proxy. HTTP: proxy padrão. HTTP (túnel CONNECT): envia cada pedido através de um túnel CONNECT, para proxies que só suportam CONNECT como o HTTPTunnelPort do Tor. SOCKS5: porta predefinida 1080.
|
||||
Load cookies from file:
|
||||
Carregar cookies de um ficheiro:
|
||||
Preload cookies from a Netscape cookies.txt file before crawling.
|
||||
Pré-carregar cookies de um ficheiro Netscape cookies.txt antes de iniciar a cópia.
|
||||
Pause between files:
|
||||
Pausa entre ficheiros:
|
||||
Random delay between file downloads, in seconds. Use MIN:MAX for a random range (e.g. 2:8).
|
||||
Atraso aleatório entre transferências de ficheiros, em segundos. Utilize MIN:MAX para um intervalo aleatório (por ex. 2:8).
|
||||
Keep the www. prefix (do not merge www.host with host)
|
||||
Manter o prefixo www. (não combinar www.host com host)
|
||||
Do not treat www.host and host as the same site.
|
||||
Não tratar www.host e host como o mesmo site.
|
||||
Keep double slashes in URLs
|
||||
Manter as barras duplas nos URL
|
||||
Do not collapse duplicate slashes in URLs.
|
||||
Não reduzir as barras duplicadas nos URL.
|
||||
Keep the original query-string order
|
||||
Manter a ordem original da query string
|
||||
Do not reorder query-string parameters when deduplicating URLs.
|
||||
Não reordenar os parâmetros da query string ao eliminar URL duplicados.
|
||||
Strip query keys:
|
||||
Remover chaves da query string:
|
||||
Comma-separated query keys to drop from the saved-file naming (e.g. sid,utm_source).
|
||||
Chaves da query string, separadas por vírgulas, a remover da nomeação dos ficheiros guardados (por ex. sid,utm_source).
|
||||
|
||||
@@ -928,3 +928,31 @@ Server terminated
|
||||
Server terminat
|
||||
A fatal error has occurred during this mirror
|
||||
A survenit o eroare fatală în timpul acestei clonări.
|
||||
Proxy type:
|
||||
Tip proxy:
|
||||
Proxy protocol. HTTP: standard proxy. HTTP (CONNECT tunnel): sends every request through a CONNECT tunnel, for CONNECT-only proxies like Tor's HTTPTunnelPort. SOCKS5: default port 1080.
|
||||
Protocol proxy. HTTP: proxy standard. HTTP (tunel CONNECT): trimite fiecare cerere printr-un tunel CONNECT, pentru proxy care accepta doar CONNECT precum HTTPTunnelPort al lui Tor. SOCKS5: port implicit 1080.
|
||||
Load cookies from file:
|
||||
Încarca cookies dintr-un fisier:
|
||||
Preload cookies from a Netscape cookies.txt file before crawling.
|
||||
Preîncarca cookies dintr-un fisier Netscape cookies.txt înainte de copiere.
|
||||
Pause between files:
|
||||
Pauza între fisiere:
|
||||
Random delay between file downloads, in seconds. Use MIN:MAX for a random range (e.g. 2:8).
|
||||
Întârziere aleatoare între descarcari de fisiere, în secunde. Folositi MIN:MAX pentru un interval aleatoriu (de ex. 2:8).
|
||||
Keep the www. prefix (do not merge www.host with host)
|
||||
Pastreaza prefixul www. (nu combina www.host cu host)
|
||||
Do not treat www.host and host as the same site.
|
||||
Nu trata www.host si host ca fiind acelasi site.
|
||||
Keep double slashes in URLs
|
||||
Pastreaza barele duble din URL-uri
|
||||
Do not collapse duplicate slashes in URLs.
|
||||
Nu comprima barele duplicate din URL-uri.
|
||||
Keep the original query-string order
|
||||
Pastreaza ordinea originala din query string
|
||||
Do not reorder query-string parameters when deduplicating URLs.
|
||||
Nu reordona parametrii din query string la eliminarea URL-urilor duplicate.
|
||||
Strip query keys:
|
||||
Elimina cheile din query string:
|
||||
Comma-separated query keys to drop from the saved-file naming (e.g. sid,utm_source).
|
||||
Chei din query string, separate prin virgula, de eliminat din denumirea fisierelor salvate (de ex. sid,utm_source).
|
||||
|
||||
@@ -928,3 +928,31 @@ Server terminated
|
||||
Server terminated
|
||||
A fatal error has occurred during this mirror
|
||||
Âî âðåìÿ òåêóùåé çàêà÷êè ïðîèçîøëà ôàòàëüíàÿ îøèáêà
|
||||
Proxy type:
|
||||
Òèï ïðîêñè:
|
||||
Proxy protocol. HTTP: standard proxy. HTTP (CONNECT tunnel): sends every request through a CONNECT tunnel, for CONNECT-only proxies like Tor's HTTPTunnelPort. SOCKS5: default port 1080.
|
||||
Ïðîòîêîë ïðîêñè. HTTP: îáû÷íûé ïðîêñè. HTTP (òóííåëü CONNECT): îòïðàâëÿåò êàæäûé çàïðîñ ÷åðåç òóííåëü CONNECT, äëÿ ïðîêñè, ïîääåðæèâàþùèõ òîëüêî CONNECT, íàïðèìåð HTTPTunnelPort â Tor. SOCKS5: ïîðò ïî óìîë÷àíèþ 1080.
|
||||
Load cookies from file:
|
||||
Çàãðóçèòü cookies èç ôàéëà:
|
||||
Preload cookies from a Netscape cookies.txt file before crawling.
|
||||
Ïðåäâàðèòåëüíî çàãðóçèòü cookies èç ôàéëà Netscape cookies.txt ïåðåä çàêà÷êîé.
|
||||
Pause between files:
|
||||
Ïàóçà ìåæäó ôàéëàìè:
|
||||
Random delay between file downloads, in seconds. Use MIN:MAX for a random range (e.g. 2:8).
|
||||
Ñëó÷àéíàÿ çàäåðæêà ìåæäó çàêà÷êàìè ôàéëîâ, â ñåêóíäàõ. Èñïîëüçóéòå MIN:MAX äëÿ ñëó÷àéíîãî äèàïàçîíà (íàïðèìåð, 2:8).
|
||||
Keep the www. prefix (do not merge www.host with host)
|
||||
Ñîõðàíÿòü ïðåôèêñ www. (íå îáúåäèíÿòü www.host ñ host)
|
||||
Do not treat www.host and host as the same site.
|
||||
Íå ñ÷èòàòü www.host è host îäíèì è òåì æå ñàéòîì.
|
||||
Keep double slashes in URLs
|
||||
Ñîõðàíÿòü äâîéíûå ñëýøè â URL
|
||||
Do not collapse duplicate slashes in URLs.
|
||||
Íå óäàëÿòü ïîâòîðÿþùèåñÿ ñëýøè â URL.
|
||||
Keep the original query-string order
|
||||
Ñîõðàíÿòü èñõîäíûé ïîðÿäîê ïàðàìåòðîâ çàïðîñà
|
||||
Do not reorder query-string parameters when deduplicating URLs.
|
||||
Íå ìåíÿòü ïîðÿäîê ïàðàìåòðîâ ñòðîêè çàïðîñà ïðè óäàëåíèè äóáëèêàòîâ URL.
|
||||
Strip query keys:
|
||||
Óäàëÿòü êëþ÷è çàïðîñà:
|
||||
Comma-separated query keys to drop from the saved-file naming (e.g. sid,utm_source).
|
||||
Êëþ÷è çàïðîñà ÷åðåç çàïÿòóþ, óäàëÿåìûå èç èìåíè ñîõðàíÿåìîãî ôàéëà (íàïðèìåð, sid,utm_source).
|
||||
|
||||
@@ -928,3 +928,31 @@ Server terminated
|
||||
|
||||
A fatal error has occurred during this mirror
|
||||
|
||||
Proxy type:
|
||||
Typ proxy:
|
||||
Proxy protocol. HTTP: standard proxy. HTTP (CONNECT tunnel): sends every request through a CONNECT tunnel, for CONNECT-only proxies like Tor's HTTPTunnelPort. SOCKS5: default port 1080.
|
||||
Protokol proxy. HTTP: ¹tandardné proxy. HTTP (tunel CONNECT): odo¹le ka¾dú po¾iadavku cez tunel CONNECT, pre proxy podporujúce len CONNECT ako HTTPTunnelPort v Tore. SOCKS5: predvolený port 1080.
|
||||
Load cookies from file:
|
||||
Naèíta» cookies zo súboru:
|
||||
Preload cookies from a Netscape cookies.txt file before crawling.
|
||||
Naèíta» cookies zo súboru Netscape cookies.txt pred zaèatím s»ahovania.
|
||||
Pause between files:
|
||||
Prestávka medzi súbormi:
|
||||
Random delay between file downloads, in seconds. Use MIN:MAX for a random range (e.g. 2:8).
|
||||
Náhodné oneskorenie medzi s»ahovaním súborov, v sekundách. Pre náhodný rozsah pou¾ite MIN:MAX (napr. 2:8).
|
||||
Keep the www. prefix (do not merge www.host with host)
|
||||
Zachova» predponu www. (nezluèova» www.host s host)
|
||||
Do not treat www.host and host as the same site.
|
||||
Nepova¾ova» www.host a host za tú istú lokalitu.
|
||||
Keep double slashes in URLs
|
||||
Zachova» dvojité lomky v URL
|
||||
Do not collapse duplicate slashes in URLs.
|
||||
Nezluèova» opakované lomky v URL.
|
||||
Keep the original query-string order
|
||||
Zachova» pôvodné poradie re»azca dotazu
|
||||
Do not reorder query-string parameters when deduplicating URLs.
|
||||
Nemeni» poradie parametrov re»azca dotazu pri odstraòovaní duplicitných URL.
|
||||
Strip query keys:
|
||||
Odstráni» kµúèe dotazu:
|
||||
Comma-separated query keys to drop from the saved-file naming (e.g. sid,utm_source).
|
||||
Kµúèe dotazu oddelené èiarkami, ktoré sa vynechajú z pomenovania ukladaných súborov (napr. sid,utm_source).
|
||||
|
||||
@@ -928,3 +928,31 @@ Server terminated
|
||||
|
||||
A fatal error has occurred during this mirror
|
||||
|
||||
Proxy type:
|
||||
Vrsta proxyja:
|
||||
Proxy protocol. HTTP: standard proxy. HTTP (CONNECT tunnel): sends every request through a CONNECT tunnel, for CONNECT-only proxies like Tor's HTTPTunnelPort. SOCKS5: default port 1080.
|
||||
Protokol proxy. HTTP: standardni proxy. HTTP (tunel CONNECT): poslje vsako zahtevo skozi tunel CONNECT, za posrednike, ki podpirajo samo CONNECT, kot je HTTPTunnelPort v Toru. SOCKS5: privzeta vrata 1080.
|
||||
Load cookies from file:
|
||||
Nalozi piskotke iz datoteke:
|
||||
Preload cookies from a Netscape cookies.txt file before crawling.
|
||||
Predhodno nalozi piskotke iz datoteke Netscape cookies.txt pred zajemanjem.
|
||||
Pause between files:
|
||||
Premor med datotekami:
|
||||
Random delay between file downloads, in seconds. Use MIN:MAX for a random range (e.g. 2:8).
|
||||
Nakljucni zamik med prenosi datotek, v sekundah. Za nakljucni obseg uporabite MIN:MAX (npr. 2:8).
|
||||
Keep the www. prefix (do not merge www.host with host)
|
||||
Ohrani predpono www. (ne zdruzi www.host z host)
|
||||
Do not treat www.host and host as the same site.
|
||||
www.host in host ne obravnavaj kot isto spletno mesto.
|
||||
Keep double slashes in URLs
|
||||
Ohrani dvojne posevnice v URL-jih
|
||||
Do not collapse duplicate slashes in URLs.
|
||||
Ne zdruzuj podvojenih posevnic v URL-jih.
|
||||
Keep the original query-string order
|
||||
Ohrani izvirni vrstni red poizvedovalnega niza
|
||||
Do not reorder query-string parameters when deduplicating URLs.
|
||||
Pri odstranjevanju podvojenih URL-jev ne spreminjaj vrstnega reda parametrov poizvedbe.
|
||||
Strip query keys:
|
||||
Odstrani kljuce poizvedbe:
|
||||
Comma-separated query keys to drop from the saved-file naming (e.g. sid,utm_source).
|
||||
Z vejicami loceni kljuci poizvedbe, ki se izpustijo pri poimenovanju shranjenih datotek (npr. sid,utm_source).
|
||||
|
||||
@@ -928,3 +928,31 @@ Server terminated
|
||||
|
||||
A fatal error has occurred during this mirror
|
||||
|
||||
Proxy type:
|
||||
Proxytyp:
|
||||
Proxy protocol. HTTP: standard proxy. HTTP (CONNECT tunnel): sends every request through a CONNECT tunnel, for CONNECT-only proxies like Tor's HTTPTunnelPort. SOCKS5: default port 1080.
|
||||
Proxyprotokoll. HTTP: standardproxy. HTTP (CONNECT-tunnel): skickar varje begäran genom en CONNECT-tunnel, för proxyservrar som bara stöder CONNECT som Tors HTTPTunnelPort. SOCKS5: standardport 1080.
|
||||
Load cookies from file:
|
||||
Läs in cookies från fil:
|
||||
Preload cookies from a Netscape cookies.txt file before crawling.
|
||||
Läs in cookies från en Netscape cookies.txt-fil innan crawlningen börjar.
|
||||
Pause between files:
|
||||
Paus mellan filer:
|
||||
Random delay between file downloads, in seconds. Use MIN:MAX for a random range (e.g. 2:8).
|
||||
Slumpmässig fördröjning mellan filnedladdningar, i sekunder. Använd MIN:MAX för ett slumpmässigt intervall (t.ex. 2:8).
|
||||
Keep the www. prefix (do not merge www.host with host)
|
||||
Behåll www.-prefixet (slå inte ihop www.host med host)
|
||||
Do not treat www.host and host as the same site.
|
||||
Behandla inte www.host och host som samma webbplats.
|
||||
Keep double slashes in URLs
|
||||
Behåll dubbla snedstreck i URL:er
|
||||
Do not collapse duplicate slashes in URLs.
|
||||
Slå inte ihop upprepade snedstreck i URL:er.
|
||||
Keep the original query-string order
|
||||
Behåll frågesträngens ursprungliga ordning
|
||||
Do not reorder query-string parameters when deduplicating URLs.
|
||||
Ändra inte ordningen på frågesträngens parametrar när dubbletter av URL:er tas bort.
|
||||
Strip query keys:
|
||||
Ta bort frågenycklar:
|
||||
Comma-separated query keys to drop from the saved-file naming (e.g. sid,utm_source).
|
||||
Kommaseparerade frågenycklar som utelämnas vid namngivningen av sparade filer (t.ex. sid,utm_source).
|
||||
|
||||
@@ -928,3 +928,31 @@ Server terminated
|
||||
Sunucu sonlandýrdý
|
||||
A fatal error has occurred during this mirror
|
||||
Bu yansýlama iþlemi sýrasýnda ölümcül bir hata oluþtu
|
||||
Proxy type:
|
||||
Proxy türü:
|
||||
Proxy protocol. HTTP: standard proxy. HTTP (CONNECT tunnel): sends every request through a CONNECT tunnel, for CONNECT-only proxies like Tor's HTTPTunnelPort. SOCKS5: default port 1080.
|
||||
Proxy protokolü. HTTP: standart proxy. HTTP (CONNECT tüneli): her isteði bir CONNECT tüneli üzerinden gönderir; Tor'un HTTPTunnelPort gibi yalnýzca CONNECT destekleyen proxy'ler için. SOCKS5: varsayýlan baðlantý noktasý 1080.
|
||||
Load cookies from file:
|
||||
Çerezleri dosyadan yükle:
|
||||
Preload cookies from a Netscape cookies.txt file before crawling.
|
||||
Taramadan önce bir Netscape cookies.txt dosyasýndan çerezleri önceden yükle.
|
||||
Pause between files:
|
||||
Dosyalar arasýnda bekleme:
|
||||
Random delay between file downloads, in seconds. Use MIN:MAX for a random range (e.g. 2:8).
|
||||
Dosya indirmeleri arasýnda saniye cinsinden rastgele gecikme. Rastgele bir aralýk için MIN:MAX kullanýn (örn. 2:8).
|
||||
Keep the www. prefix (do not merge www.host with host)
|
||||
www. önekini koru (www.host ile host'u birleþtirme)
|
||||
Do not treat www.host and host as the same site.
|
||||
www.host ve host'u ayný site olarak deðerlendirme.
|
||||
Keep double slashes in URLs
|
||||
URL'lerdeki çift eðik çizgileri koru
|
||||
Do not collapse duplicate slashes in URLs.
|
||||
URL'lerdeki yinelenen eðik çizgileri birleþtirme.
|
||||
Keep the original query-string order
|
||||
Özgün sorgu dizesi sýrasýný koru
|
||||
Do not reorder query-string parameters when deduplicating URLs.
|
||||
URL'lerin yinelenenlerini ayýklarken sorgu dizesi parametrelerini yeniden sýralama.
|
||||
Strip query keys:
|
||||
Sorgu anahtarlarýný çýkar:
|
||||
Comma-separated query keys to drop from the saved-file naming (e.g. sid,utm_source).
|
||||
Kaydedilen dosya adlandýrmasýndan çýkarýlacak, virgülle ayrýlmýþ sorgu anahtarlarý (örn. sid,utm_source).
|
||||
|
||||
@@ -928,3 +928,31 @@ Server terminated
|
||||
|
||||
A fatal error has occurred during this mirror
|
||||
|
||||
Proxy type:
|
||||
Òèï ïðîêñ³:
|
||||
Proxy protocol. HTTP: standard proxy. HTTP (CONNECT tunnel): sends every request through a CONNECT tunnel, for CONNECT-only proxies like Tor's HTTPTunnelPort. SOCKS5: default port 1080.
|
||||
Ïðîòîêîë ïðîêñ³. HTTP: ñòàíäàðòíèé ïðîêñ³. HTTP (òóíåëü CONNECT): íàäñèëຠêîæåí çàïèò ÷åðåç òóíåëü CONNECT, äëÿ ïðîêñ³, ùî ï³äòðèìóþòü ëèøå CONNECT, ÿê-îò HTTPTunnelPort ó Tor. SOCKS5: ïîðò çà çàìîâ÷óâàííÿì 1080.
|
||||
Load cookies from file:
|
||||
Çàâàíòàæèòè cookies ç ôàéëó:
|
||||
Preload cookies from a Netscape cookies.txt file before crawling.
|
||||
Ïîïåðåäíüî çàâàíòàæèòè cookies ç ôàéëó Netscape cookies.txt ïåðåä çàâàíòàæåííÿì.
|
||||
Pause between files:
|
||||
Ïàóçà ì³æ ôàéëàìè:
|
||||
Random delay between file downloads, in seconds. Use MIN:MAX for a random range (e.g. 2:8).
|
||||
Âèïàäêîâà çàòðèìêà ì³æ çàâàíòàæåííÿìè ôàéë³â, ó ñåêóíäàõ. Âèêîðèñòîâóéòå MIN:MAX äëÿ âèïàäêîâîãî ä³àïàçîíó (íàïðèêëàä, 2:8).
|
||||
Keep the www. prefix (do not merge www.host with host)
|
||||
Çáåð³ãàòè ïðåô³êñ www. (íå îá'ºäíóâàòè www.host ç host)
|
||||
Do not treat www.host and host as the same site.
|
||||
Íå ââàæàòè www.host ³ host îäíèì ³ òèì ñàìèì ñàéòîì.
|
||||
Keep double slashes in URLs
|
||||
Çáåð³ãàòè ïîäâ³éí³ ñëåø³ â URL
|
||||
Do not collapse duplicate slashes in URLs.
|
||||
Íå âèäàëÿòè ïîâòîðþâàí³ ñëåø³ â URL.
|
||||
Keep the original query-string order
|
||||
Çáåð³ãàòè ïî÷àòêîâèé ïîðÿäîê ïàðàìåòð³â çàïèòó
|
||||
Do not reorder query-string parameters when deduplicating URLs.
|
||||
Íå çì³íþâàòè ïîðÿäîê ïàðàìåòð³â ðÿäêà çàïèòó ï³ä ÷àñ óñóíåííÿ äóáë³êàò³â URL.
|
||||
Strip query keys:
|
||||
Âèëó÷àòè êëþ÷³ çàïèòó:
|
||||
Comma-separated query keys to drop from the saved-file naming (e.g. sid,utm_source).
|
||||
Êëþ÷³ çàïèòó ÷åðåç êîìó, ÿê³ âèëó÷àþòüñÿ ç ³ìåí³ çáåðåæåíîãî ôàéëó (íàïðèêëàä, sid,utm_source).
|
||||
|
||||
@@ -928,3 +928,31 @@ Server terminated
|
||||
Server terminated
|
||||
A fatal error has occurred during this mirror
|
||||
Joriy ko’chirish vaqtida jiddiy xatolik yuz berdi
|
||||
Proxy type:
|
||||
Proksi turi:
|
||||
Proxy protocol. HTTP: standard proxy. HTTP (CONNECT tunnel): sends every request through a CONNECT tunnel, for CONNECT-only proxies like Tor's HTTPTunnelPort. SOCKS5: default port 1080.
|
||||
Proksi protokoli. HTTP: oddiy proksi. HTTP (CONNECT tuneli): har bir so'rovni CONNECT tuneli orqali yuboradi; faqat CONNECT'ni qo'llab-quvvatlaydigan proksilar uchun, masalan Tor HTTPTunnelPort. SOCKS5: standart port 1080.
|
||||
Load cookies from file:
|
||||
Fayldan cookies yuklamoq:
|
||||
Preload cookies from a Netscape cookies.txt file before crawling.
|
||||
Ko’chirib olishdan oldin Netscape cookies.txt faylidan cookies’ni oldindan yuklamoq.
|
||||
Pause between files:
|
||||
Fayllar orasidagi pauza:
|
||||
Random delay between file downloads, in seconds. Use MIN:MAX for a random range (e.g. 2:8).
|
||||
Fayllarni ko’chirib olish orasidagi tasodifiy kechikish, soniyalarda. Tasodifiy diapazon uchun MIN:MAX dan foydalaning (masalan, 2:8).
|
||||
Keep the www. prefix (do not merge www.host with host)
|
||||
www. prefiksini saqlash (www.host ni host bilan birlashtirmaslik)
|
||||
Do not treat www.host and host as the same site.
|
||||
www.host va host ni bir xil sayt deb hisoblamaslik.
|
||||
Keep double slashes in URLs
|
||||
URL lardagi qo’sh sleshlarni saqlash
|
||||
Do not collapse duplicate slashes in URLs.
|
||||
URL lardagi takroriy sleshlarni olib tashlamaslik.
|
||||
Keep the original query-string order
|
||||
So’rov satrining asl tartibini saqlash
|
||||
Do not reorder query-string parameters when deduplicating URLs.
|
||||
URL dublikatlarini olib tashlashda so’rov satri parametrlari tartibini o’zgartirmaslik.
|
||||
Strip query keys:
|
||||
Olib tashlanadigan so’rov kalitlari:
|
||||
Comma-separated query keys to drop from the saved-file naming (e.g. sid,utm_source).
|
||||
Saqlangan fayl nomidan olib tashlanadigan, vergul bilan ajratilgan so’rov kalitlari (masalan, sid,utm_source).
|
||||
|
||||
66
m4/check_codecs.m4
Normal file
66
m4/check_codecs.m4
Normal file
@@ -0,0 +1,66 @@
|
||||
dnl @synopsis CHECK_BROTLI()
|
||||
dnl @synopsis CHECK_ZSTD()
|
||||
dnl
|
||||
dnl Look for libbrotlidec and libzstd, the decoders for the "br" and "zstd"
|
||||
dnl HTTP content codings. Both are optional: a missing library only drops the
|
||||
dnl coding from Accept-Encoding. --with-brotli=DIR / --with-zstd=DIR point at a
|
||||
dnl prefix; --without-brotli / --without-zstd disable the coding; the default
|
||||
dnl is to use the library when it is found.
|
||||
dnl
|
||||
dnl Define HTS_USEBROTLI / HTS_USEZSTD to 1 or 0, and substitute BROTLI_LIBS /
|
||||
dnl ZSTD_LIBS.
|
||||
|
||||
dnl CHECK_CODEC(name, NAME, header, library, symbol, companion-libs)
|
||||
AC_DEFUN([CHECK_CODEC], [
|
||||
AC_ARG_WITH([$1],
|
||||
[AS_HELP_STRING([--with-$1@<:@=DIR@:>@],[Enable the $1 content coding @<:@default=auto@:>@])],
|
||||
[codec_want=$withval], [codec_want=auto])
|
||||
$2_LIBS=""
|
||||
codec_have=no
|
||||
if test "$codec_want" != "no"; then
|
||||
codec_old_cppflags="$CPPFLAGS"
|
||||
codec_old_ldflags="$LDFLAGS"
|
||||
codec_dir=no
|
||||
if test "$codec_want" != "yes" -a "$codec_want" != "auto"; then
|
||||
codec_dir=yes
|
||||
# An explicit prefix is authoritative: if the header is not under
|
||||
# it, error rather than silently pick a system copy.
|
||||
if test ! -f "$codec_want/include/$3"; then
|
||||
AC_MSG_ERROR([$1 requested at $codec_want but $codec_want/include/$3 is missing])
|
||||
fi
|
||||
CPPFLAGS="$CPPFLAGS -I$codec_want/include"
|
||||
LDFLAGS="$LDFLAGS -L$codec_want/lib"
|
||||
fi
|
||||
AC_CHECK_HEADER([$3], [codec_h=yes], [codec_h=no])
|
||||
AC_CHECK_LIB([$4], [$5], [codec_lib=yes], [codec_lib=no], [$6])
|
||||
CPPFLAGS="$codec_old_cppflags"
|
||||
LDFLAGS="$codec_old_ldflags"
|
||||
if test "$codec_h" = "yes" -a "$codec_lib" = "yes"; then
|
||||
codec_have=yes
|
||||
$2_LIBS="-l$4 $6"
|
||||
if test "$codec_dir" = "yes"; then
|
||||
$2_LIBS="-L$codec_want/lib -l$4 $6"
|
||||
# The rest of configure still needs the header path.
|
||||
CPPFLAGS="$CPPFLAGS -I$codec_want/include"
|
||||
fi
|
||||
elif test "$codec_want" != "auto"; then
|
||||
AC_MSG_ERROR([$1 requested but lib$4/$3 not found])
|
||||
fi
|
||||
fi
|
||||
AC_MSG_CHECKING([whether to enable the $1 content coding])
|
||||
AC_MSG_RESULT([$codec_have])
|
||||
if test "$codec_have" = "yes"; then
|
||||
AC_DEFINE([HTS_USE$2], [1], [Define to 1 to decode the $1 content coding])
|
||||
else
|
||||
AC_DEFINE([HTS_USE$2], [0], [Define to 1 to decode the $1 content coding])
|
||||
fi
|
||||
AC_SUBST([$2_LIBS])
|
||||
AC_SUBST([$2_ENABLED], [$codec_have])
|
||||
])
|
||||
|
||||
dnl brotlidec needs brotlicommon (the static dictionary) for a fully-static link.
|
||||
AC_DEFUN([CHECK_BROTLI],
|
||||
[CHECK_CODEC([brotli], [BROTLI], [brotli/decode.h], [brotlidec], [BrotliDecoderDecompressStream], [-lbrotlicommon])])
|
||||
|
||||
AC_DEFUN([CHECK_ZSTD],
|
||||
[CHECK_CODEC([zstd], [ZSTD], [zstd.h], [zstd], [ZSTD_decompressStream], [])])
|
||||
@@ -3,7 +3,7 @@
|
||||
.\"
|
||||
.\" This file is generated by man/makeman.sh; do not edit by hand.
|
||||
.\" SPDX-License-Identifier: GPL-3.0-or-later
|
||||
.TH httrack 1 "12 July 2026" "httrack website copier"
|
||||
.TH httrack 1 "14 July 2026" "httrack website copier"
|
||||
.SH NAME
|
||||
httrack \- offline browser : copy websites to a local directory
|
||||
.SH SYNOPSIS
|
||||
@@ -135,7 +135,7 @@ continue an interrupted mirror using the cache (\-\-continue)
|
||||
mirror ALL links located in the first level pages (mirror links) (\-\-mirrorlinks)
|
||||
.SS Proxy options:
|
||||
.IP \-P
|
||||
proxy use (\-P proxy:port or \-P user:pass@proxy:port) (\-\-proxy <param>)
|
||||
proxy use (\-P [socks5://|connect://][user:pass@]proxy:port) (\-\-proxy <param>)
|
||||
.IP \-%f
|
||||
*use proxy for ftp (f0 don't use) (\-\-httpproxy\-ftp[=N])
|
||||
.IP \-%b
|
||||
|
||||
@@ -61,7 +61,7 @@ libhttrack_la_SOURCES = htscore.c htsparse.c htsback.c htscache.c \
|
||||
htshelp.c htslib.c htscoremain.c \
|
||||
htsname.c htsrobots.c htstools.c htswizard.c \
|
||||
htsalias.c htsthread.c htsindex.c htsbauth.c \
|
||||
htsmd5.c htszlib.c htswrap.c htsconcat.c \
|
||||
htsmd5.c htscodec.c htsproxy.c htszlib.c htswrap.c htsconcat.c \
|
||||
htsmodules.c htscharset.c punycode.c htsencoding.c htssniff.c \
|
||||
md5.c \
|
||||
minizip/ioapi.c minizip/mztools.c minizip/unzip.c minizip/zip.c \
|
||||
@@ -72,17 +72,20 @@ libhttrack_la_SOURCES = htscore.c htsparse.c htsback.c htscache.c \
|
||||
htshelp.h htsindex.h htslib.h htsmd5.h \
|
||||
htsmodules.h htsname.h htsnet.h htssniff.h \
|
||||
htsopt.h htsrobots.h htsthread.h \
|
||||
htstools.h htswizard.h htswrap.h htszlib.h \
|
||||
htstools.h htswizard.h htswrap.h htscodec.h htsproxy.h htszlib.h \
|
||||
htsstrings.h htsarrays.h httrack-library.h \
|
||||
htscharset.h punycode.h htsencoding.h \
|
||||
htsentities.h htsentities.sh htsbasiccharsets.sh htscodepages.h \
|
||||
md5.h coucal/murmurhash3.h \
|
||||
minizip/crypt.h minizip/ioapi.h minizip/mztools.h minizip/unzip.h minizip/zip.h
|
||||
libhttrack_la_LIBADD = $(THREADS_LIBS) $(ZLIB_LIBS) $(OPENSSL_LIBS) $(DL_LIBS) $(SOCKET_LIBS) $(ICONV_LIBS)
|
||||
libhttrack_la_LIBADD = $(THREADS_LIBS) $(ZLIB_LIBS) $(BROTLI_LIBS) $(ZSTD_LIBS) $(OPENSSL_LIBS) $(DL_LIBS) $(SOCKET_LIBS) $(ICONV_LIBS)
|
||||
libhttrack_la_CFLAGS = $(AM_CFLAGS) -DLIBHTTRACK_EXPORTS -DZLIB_CONST
|
||||
libhttrack_la_LDFLAGS = $(AM_LDFLAGS) -version-info $(VERSION_INFO)
|
||||
|
||||
EXTRA_DIST = httrack.h webhttrack \
|
||||
version.rc \
|
||||
libhttrack.rc \
|
||||
httrack.rc \
|
||||
coucal/murmurhash3.h.diff \
|
||||
coucal/murmurhash3.h.orig \
|
||||
minizip/iowin32.c \
|
||||
@@ -105,12 +108,13 @@ EXTRA_DIST = httrack.h webhttrack \
|
||||
proxy/proxystrings.h \
|
||||
proxy/proxytrack.h \
|
||||
proxy/store.h \
|
||||
proxy/proxytrack.vcproj \
|
||||
coucal/LICENSE \
|
||||
coucal/Makefile \
|
||||
coucal/README.md \
|
||||
coucal/sample.c \
|
||||
coucal/tests.c \
|
||||
httrack.dsp httrack.dsw httrack.vcproj \
|
||||
libhttrack.dsp libhttrack.dsw libhttrack.vcproj \
|
||||
webhttrack.dsp webhttrack.dsw webhttrack.vcproj
|
||||
vcpkg.json \
|
||||
httrack.vcxproj \
|
||||
libhttrack.vcxproj \
|
||||
proxytrack.vcxproj \
|
||||
webhttrack.vcxproj
|
||||
|
||||
Submodule src/coucal updated: fadf29bd2a...ab59c6a7a0
235
src/htsback.c
235
src/htsback.c
@@ -44,6 +44,8 @@ Please visit our Website: http://www.httrack.com
|
||||
#include "htsback.h"
|
||||
|
||||
#include "htsftp.h"
|
||||
#include "htscodec.h"
|
||||
#include "htsproxy.h"
|
||||
#if HTS_USEZLIB
|
||||
#include "htszlib.h"
|
||||
#else
|
||||
@@ -138,8 +140,9 @@ int back_connect_fallback_due(int addr_index, int addr_count, int elapsed,
|
||||
|
||||
/* Pending-connect result for a non-blocking socket reported ready by select():
|
||||
0 = connected, >0 = the connect errno (refused, unreachable, ...), -1 if the
|
||||
probe itself failed. A failed connect is reported writable too, so this is
|
||||
how success is told from failure without blocking. */
|
||||
probe itself failed. A failed connect is reported ready as well (writable on
|
||||
posix, exception set on winsock), so this is how success is told from failure
|
||||
without blocking. */
|
||||
static int connect_socket_error(T_SOC soc) {
|
||||
int soerr = 0;
|
||||
socklen_t len = (socklen_t) sizeof(soerr);
|
||||
@@ -556,6 +559,14 @@ static int create_back_tmpfile(httrackp *opt, lien_back *const back,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Move src onto dst; RENAME does not clobber an existing target on Windows. */
|
||||
static hts_boolean replace_file(const char *src, const char *dst) {
|
||||
if (RENAME(src, dst) == 0)
|
||||
return HTS_TRUE;
|
||||
(void) UNLINK(dst);
|
||||
return RENAME(src, dst) == 0 ? HTS_TRUE : HTS_FALSE;
|
||||
}
|
||||
|
||||
/* Commit or restore a re-fetch backup (#77 follow-up): a re-fetch over an
|
||||
existing file moved the good copy to back->tmpfile before truncating url_sav.
|
||||
commit keeps the new file and drops the backup; else restore it so an aborted
|
||||
@@ -571,10 +582,9 @@ static void back_finalize_backup(httrackp *opt, lien_back *const back,
|
||||
fclose(back->r.out);
|
||||
back->r.out = NULL;
|
||||
}
|
||||
(void) UNLINK(back->url_sav); /* drop the failed partial */
|
||||
/* On rename failure keep the backup: it still holds the good copy, so
|
||||
losing it would be worse than an orphaned temp. */
|
||||
if (RENAME(back->tmpfile, back->url_sav) != 0)
|
||||
/* On failure keep the backup: an orphaned temp beats losing the good copy.
|
||||
*/
|
||||
if (!replace_file(back->tmpfile, back->url_sav))
|
||||
hts_log_print(opt, LOG_WARNING | LOG_ERRNO,
|
||||
"could not restore %s; previous copy kept as %s",
|
||||
back->url_sav, back->tmpfile);
|
||||
@@ -618,6 +628,10 @@ int back_finalize(httrackp * opt, cache_back * cache, struct_back * sback,
|
||||
back[p].r.size, back[p].url_adr, back[p].url_fil);
|
||||
}
|
||||
back_finalize_backup(opt, &back[p], HTS_FALSE);
|
||||
/* Keep the surviving copy in new.lst, else the update purge drops the
|
||||
file we refused to overwrite with the partial body (#562). */
|
||||
if (fexist_utf8(back[p].url_sav))
|
||||
filenote(&opt->state.strc, back[p].url_sav, NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -627,8 +641,7 @@ int back_finalize(httrackp * opt, cache_back * cache, struct_back * sback,
|
||||
if (!back[p].testmode) { // not test mode
|
||||
const char *state = "unknown";
|
||||
|
||||
/* décompression */
|
||||
#if HTS_USEZLIB
|
||||
/* Undo the content coding */
|
||||
if (back[p].r.compressed) {
|
||||
if (back[p].r.size > 0) {
|
||||
// stats
|
||||
@@ -674,28 +687,67 @@ int back_finalize(httrackp * opt, cache_back * cache, struct_back * sback,
|
||||
// décompression
|
||||
if (back[p].tmpfile != NULL) {
|
||||
if (back[p].url_sav[0]) {
|
||||
const hts_codec codec =
|
||||
hts_codec_parse(back[p].r.contentencoding);
|
||||
/* Never decode over url_sav: a failed decode would destroy the
|
||||
copy an --update re-fetch is supposed to refresh (#557). */
|
||||
char BIGSTK unpacked[HTS_URLMAXSIZE * 2 + 4]; // room for ".u"
|
||||
LLint size;
|
||||
|
||||
file_notify(opt, back[p].url_adr, back[p].url_fil,
|
||||
back[p].url_sav, 1, 1, back[p].r.notmodified);
|
||||
filecreateempty(&opt->state.strc, back[p].url_sav); // filenote & co
|
||||
if ((size = hts_zunpack(back[p].tmpfile, back[p].url_sav)) >= 0) {
|
||||
snprintf(unpacked, sizeof(unpacked), "%s.u", back[p].url_sav);
|
||||
if ((size = hts_codec_unpack(codec, back[p].tmpfile,
|
||||
unpacked)) >= 0) {
|
||||
back[p].r.size = back[p].r.totalsize = size;
|
||||
// fichier -> mémoire
|
||||
if (!back[p].r.is_write) {
|
||||
// fichier -> mémoire ; le fichier est écrit plus tard
|
||||
deleteaddr(&back[p].r);
|
||||
back[p].r.adr = readfile_utf8(back[p].url_sav);
|
||||
back[p].r.adr = readfile_utf8(unpacked);
|
||||
if (!back[p].r.adr) {
|
||||
back[p].r.statuscode = STATUSCODE_INVALID;
|
||||
strcpybuff(back[p].r.msg,
|
||||
"Read error when decompressing");
|
||||
}
|
||||
UNLINK(back[p].url_sav);
|
||||
UNLINK(unpacked);
|
||||
} else if (replace_file(unpacked, back[p].url_sav)) {
|
||||
/* The temp bypassed filecreate(), which is what chmods. */
|
||||
#ifndef _WIN32
|
||||
chmod(back[p].url_sav, HTS_ACCESS_FILE);
|
||||
#endif
|
||||
file_notify(opt, back[p].url_adr, back[p].url_fil,
|
||||
back[p].url_sav, 1, 1, back[p].r.notmodified);
|
||||
filenote(&opt->state.strc, back[p].url_sav, NULL);
|
||||
} else {
|
||||
back[p].r.statuscode = STATUSCODE_INVALID;
|
||||
strcpybuff(back[p].r.msg,
|
||||
"Write error when decompressing (can not rename "
|
||||
"the temporary file)");
|
||||
/* Keep the decoded body: the failed replace may have
|
||||
removed the previous copy, leaving this as the only one.
|
||||
*/
|
||||
hts_log_print(
|
||||
opt, LOG_WARNING | LOG_ERRNO,
|
||||
"could not replace %s; decoded copy kept as %s",
|
||||
back[p].url_sav, unpacked);
|
||||
}
|
||||
} else {
|
||||
back[p].r.statuscode = STATUSCODE_INVALID;
|
||||
strcpybuff(back[p].r.msg, "Error when decompressing");
|
||||
snprintf(back[p].r.msg, sizeof(back[p].r.msg),
|
||||
codec == HTS_CODEC_UNSUPPORTED
|
||||
? "Unsupported Content-Encoding (%s)"
|
||||
: "Error when decompressing (%s)",
|
||||
back[p].r.contentencoding);
|
||||
/* Drop the undecoded body so the writer can't commit the
|
||||
coded bytes as the page; url_sav is left untouched. */
|
||||
if (!back[p].r.is_write)
|
||||
deleteaddr(&back[p].r);
|
||||
UNLINK(unpacked);
|
||||
}
|
||||
/* A failed decode keeps the previously-mirrored copy: note it,
|
||||
or the update purge (in old.lst, absent from new.lst) would
|
||||
delete what we just took care not to overwrite. */
|
||||
if (back[p].r.statuscode == STATUSCODE_INVALID &&
|
||||
fexist_utf8(back[p].url_sav))
|
||||
filenote(&opt->state.strc, back[p].url_sav, NULL);
|
||||
}
|
||||
/* ensure that no remaining temporary file exists */
|
||||
unlink(back[p].tmpfile);
|
||||
@@ -708,7 +760,6 @@ int back_finalize(httrackp * opt, cache_back * cache, struct_back * sback,
|
||||
// unflag
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* Body fully received: keep the freshly written url_sav, drop the
|
||||
backup of the previous copy. */
|
||||
back_finalize_backup(opt, &back[p], HTS_TRUE);
|
||||
@@ -730,7 +781,7 @@ int back_finalize(httrackp * opt, cache_back * cache, struct_back * sback,
|
||||
if (back[p].r.statuscode == HTTP_OK) { // OK (ou 304 en backing)
|
||||
if (back[p].r.is_write) { // Written file
|
||||
if (may_be_hypertext_mime(opt, back[p].r.contenttype, back[p].url_fil)) { // to parse!
|
||||
off_t sz;
|
||||
LLint sz;
|
||||
|
||||
sz = fsize_utf8(back[p].url_sav);
|
||||
if (sz > 0) { // ok, exists!
|
||||
@@ -807,7 +858,7 @@ int back_finalize(httrackp * opt, cache_back * cache, struct_back * sback,
|
||||
else
|
||||
strcatbuff(flags, "-");
|
||||
if (back[p].r.compressed)
|
||||
strcatbuff(flags, "Z"); // gzip
|
||||
strcatbuff(flags, "Z"); // content coding
|
||||
else
|
||||
strcatbuff(flags, "-");
|
||||
/* Err I had to split these.. */
|
||||
@@ -816,9 +867,7 @@ int back_finalize(httrackp * opt, cache_back * cache, struct_back * sback,
|
||||
fprintf(cache->txt, LLintP, (LLint) back[p].r.totalsize);
|
||||
fprintf(cache->txt, "\t%s\t", flags);
|
||||
}
|
||||
#if HTS_USEZLIB
|
||||
back[p].r.compressed = 0;
|
||||
#endif
|
||||
|
||||
if (back[p].r.statuscode == HTTP_OK) {
|
||||
if (back[p].r.size >= 0) {
|
||||
@@ -1909,7 +1958,7 @@ int back_add(struct_back * sback, httrackp * opt, cache_back * cache, const char
|
||||
/* Not in cache ; maybe in temporary cache ? Warning: non-movable
|
||||
"url_sav" */
|
||||
else if (back_unserialize_ref(opt, adr, fil, &itemback) == 0) {
|
||||
const off_t file_size = fsize_utf8(itemback->url_sav);
|
||||
const LLint file_size = fsize_utf8(itemback->url_sav);
|
||||
|
||||
/* Found file on disk */
|
||||
if (file_size > 0) {
|
||||
@@ -1944,7 +1993,7 @@ int back_add(struct_back * sback, httrackp * opt, cache_back * cache, const char
|
||||
}
|
||||
/* Not in cache or temporary cache ; found on disk ? (hack) */
|
||||
else if (fexist_utf8(save)) {
|
||||
const off_t sz = fsize_utf8(save);
|
||||
const LLint sz = fsize_utf8(save);
|
||||
|
||||
// Bon, là il est possible que le fichier ait été partiellement transféré
|
||||
// (s'il l'avait été en totalité il aurait été inscrit dans le cache ET existerait sur disque)
|
||||
@@ -2068,6 +2117,17 @@ int back_add(struct_back * sback, httrackp * opt, cache_back * cache, const char
|
||||
"error: forbidden test with ftp link for back_add");
|
||||
return -1; // erreur pas de test permis
|
||||
}
|
||||
// the ftp client dials the origin itself: over socks that would bypass
|
||||
// the proxy, so fail the link rather than leak the connection (#563)
|
||||
if (back[p].r.req.proxy.active &&
|
||||
hts_proxy_is_socks(back[p].r.req.proxy.name)) {
|
||||
back[p].r.statuscode = STATUSCODE_NON_FATAL;
|
||||
strcpybuff(back[p].r.msg,
|
||||
"ftp:// is not supported over a SOCKS proxy");
|
||||
back[p].status = STATUS_READY;
|
||||
back_set_finished(sback, p);
|
||||
return 0;
|
||||
}
|
||||
if (!(back[p].r.req.proxy.active && opt->ftp_proxy)) { // connexion directe, gérée en thread
|
||||
FTPDownloadStruct *str =
|
||||
(FTPDownloadStruct *) malloc(sizeof(FTPDownloadStruct));
|
||||
@@ -2603,7 +2663,9 @@ void back_wait(struct_back * sback, httrackp * opt, cache_back * cache,
|
||||
for (i_mod = 0; i_mod < (unsigned int) back_max; i_mod++) {
|
||||
unsigned int i = (i_mod + mod_random) % (back_max);
|
||||
|
||||
if (back[i].status > 0) {
|
||||
// winsock flags a failed connect in the exception set only: leave a
|
||||
// connecting slot to the connect handler, which can still fall back
|
||||
if (back[i].status > 0 && back[i].status != STATUS_CONNECTING) {
|
||||
if (!back[i].r.is_file) { // not file..
|
||||
if (back[i].r.soc != INVALID_SOCKET) { // hey, you never know..
|
||||
int err = FD_ISSET(back[i].r.soc, &fds_e);
|
||||
@@ -2617,10 +2679,7 @@ void back_wait(struct_back * sback, httrackp * opt, cache_back * cache,
|
||||
}
|
||||
back[i].r.soc = INVALID_SOCKET;
|
||||
back[i].r.statuscode = STATUSCODE_CONNERROR;
|
||||
if (back[i].status == STATUS_CONNECTING)
|
||||
strcpybuff(back[i].r.msg, "Connect Error");
|
||||
else
|
||||
strcpybuff(back[i].r.msg, "Receive Error");
|
||||
strcpybuff(back[i].r.msg, "Receive Error");
|
||||
if (back[i].status == STATUS_ALIVE) { /* Keep-alive socket */
|
||||
back_delete(opt, cache, sback, i);
|
||||
} else {
|
||||
@@ -2637,9 +2696,12 @@ void back_wait(struct_back * sback, httrackp * opt, cache_back * cache,
|
||||
int dispo = 0;
|
||||
|
||||
// probe the resolved address list once per fresh connect (cache hit:
|
||||
// the host was resolved when this connect was opened)
|
||||
// the host was resolved when this connect was opened). Not under a
|
||||
// proxy: the socket dials the proxy, so resolving the origin here leaks
|
||||
// its DNS and lets a proxy-connect failure fall back to dialing it
|
||||
// direct.
|
||||
if (cf->addr_count < 0 && back[i].r.soc != INVALID_SOCKET &&
|
||||
!back[i].r.is_file) {
|
||||
!back[i].r.is_file && !back[i].r.req.proxy.active) {
|
||||
SOCaddr scratch[HTS_MAXADDRNUM];
|
||||
|
||||
cf->addr_count = hts_dns_resolve_all(opt, back[i].url_adr, scratch,
|
||||
@@ -2653,10 +2715,11 @@ void back_wait(struct_back * sback, httrackp * opt, cache_back * cache,
|
||||
gestion_timeout = 1;
|
||||
|
||||
// connecté?
|
||||
dispo = FD_ISSET(back[i].r.soc, &fds_c);
|
||||
dispo = back[i].r.soc != INVALID_SOCKET &&
|
||||
(FD_ISSET(back[i].r.soc, &fds_c) ||
|
||||
FD_ISSET(back[i].r.soc, &fds_e));
|
||||
if (dispo) { // socket ready: connect() finished (ok or failed)
|
||||
// a refused/failed connect is reported writable too; probe SO_ERROR
|
||||
// and, on failure, fall back to the next address (or fail the slot)
|
||||
// probe SO_ERROR and, on failure, fall back to the next address
|
||||
if (connect_socket_error(back[i].r.soc) != 0) {
|
||||
if (!back_connect_next(opt, sback, i)) {
|
||||
deletehttp(&back[i].r);
|
||||
@@ -2670,13 +2733,62 @@ void back_wait(struct_back * sback, httrackp * opt, cache_back * cache,
|
||||
}
|
||||
busy_state = 1;
|
||||
|
||||
// socks5: tunnel to the origin before anything is written, for http
|
||||
// as well as https. Skip on a reused keep-alive socket (already
|
||||
// tunneled) and on the post-TLS re-entry (ssl_con set) (#563).
|
||||
if (back[i].r.req.proxy.active &&
|
||||
hts_proxy_is_socks(back[i].r.req.proxy.name) &&
|
||||
!back[i].r.keep_alive
|
||||
#if HTS_USEOPENSSL
|
||||
&& back[i].r.ssl_con == NULL
|
||||
#endif
|
||||
) {
|
||||
const int timeout = back[i].timeout > 0 ? back[i].timeout : 30;
|
||||
|
||||
if (!socks5_handshake(opt, &back[i].r, back[i].url_adr, timeout)) {
|
||||
if (!strnotempty(back[i].r.msg))
|
||||
strcpybuff(back[i].r.msg, "SOCKS5 handshake failed");
|
||||
deletehttp(&back[i].r);
|
||||
back[i].r.soc = INVALID_SOCKET;
|
||||
back[i].r.statuscode = STATUSCODE_NON_FATAL;
|
||||
back[i].status = STATUS_READY;
|
||||
back_set_finished(sback, i);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// plain http tunneled through a CONNECT-only proxy (#564)
|
||||
if (back[i].r.req.proxy.active &&
|
||||
hts_proxy_is_connect(back[i].r.req.proxy.name) &&
|
||||
!back[i].r.keep_alive
|
||||
#if HTS_USEOPENSSL
|
||||
&& !back[i].r.ssl
|
||||
#endif
|
||||
) {
|
||||
const int timeout = back[i].timeout > 0 ? back[i].timeout : 30;
|
||||
|
||||
if (!http_proxy_tunnel(opt, &back[i].r, back[i].url_adr, timeout)) {
|
||||
if (!strnotempty(back[i].r.msg))
|
||||
strcpybuff(back[i].r.msg, "proxy CONNECT failed");
|
||||
deletehttp(&back[i].r);
|
||||
back[i].r.soc = INVALID_SOCKET;
|
||||
back[i].r.statuscode = STATUSCODE_NON_FATAL;
|
||||
back[i].status = STATUS_READY;
|
||||
back_set_finished(sback, i);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
#if HTS_USEOPENSSL
|
||||
/* SSL mode */
|
||||
if (back[i].r.ssl) {
|
||||
int tunnel_ok = 1;
|
||||
|
||||
// https via proxy: CONNECT-tunnel before TLS (#85)
|
||||
if (back[i].r.req.proxy.active && back[i].r.ssl_con == NULL) {
|
||||
// https via an http proxy: CONNECT-tunnel before TLS (#85); socks
|
||||
// already carries the origin connection
|
||||
if (back[i].r.req.proxy.active &&
|
||||
!hts_proxy_is_socks(back[i].r.req.proxy.name) &&
|
||||
back[i].r.ssl_con == NULL) {
|
||||
const int timeout = back[i].timeout > 0 ? back[i].timeout : 30;
|
||||
|
||||
tunnel_ok =
|
||||
@@ -2941,11 +3053,13 @@ void back_wait(struct_back * sback, httrackp * opt, cache_back * cache,
|
||||
int last_errno = 0;
|
||||
|
||||
back[i].r.is_write = 1; // écrire
|
||||
/* a .gz/.br/.zst saved under its own coding stays
|
||||
packed on disk */
|
||||
if (back[i].r.compressed &&
|
||||
/* .gz are *NOT* depacked!! */
|
||||
strfield(get_ext(catbuff, sizeof(catbuff), back[i].url_sav), "gz") == 0
|
||||
&& strfield(get_ext(catbuff, sizeof(catbuff), back[i].url_sav), "tgz") == 0
|
||||
) {
|
||||
!hts_codec_is_archive_ext(
|
||||
hts_codec_parse(back[i].r.contentencoding),
|
||||
get_ext(catbuff, sizeof(catbuff),
|
||||
back[i].url_sav))) {
|
||||
if (create_back_tmpfile(opt, &back[i], "z") ==
|
||||
0) {
|
||||
assertf(back[i].tmpfile != NULL);
|
||||
@@ -3221,16 +3335,26 @@ void back_wait(struct_back * sback, httrackp * opt, cache_back * cache,
|
||||
back[i].chunk_blocksize = -1; /* ending */
|
||||
back[i].r.totalsize += chunk_size; // noter taille
|
||||
if (back[i].r.adr != NULL || !back[i].r.is_write) { // Not to disk
|
||||
back[i].r.adr =
|
||||
(char *) realloct(back[i].r.adr,
|
||||
(size_t) back[i].r.totalsize + 1);
|
||||
if (!back[i].r.adr) {
|
||||
if (cache->log != NULL) {
|
||||
hts_log_print(opt, LOG_ERROR,
|
||||
"not enough memory (" LLintP
|
||||
") for %s%s",
|
||||
(LLint) back[i].r.totalsize,
|
||||
back[i].url_adr, back[i].url_fil);
|
||||
// totalsize sums attacker-declared chunk sizes; past
|
||||
// 2GB the (size_t) cast below truncates on 32-bit and
|
||||
// under-allocates. Mark the chunk invalid so the shared
|
||||
// error path tears the transfer down.
|
||||
if (back[i].r.totalsize > INT32_MAX) {
|
||||
hts_log_print(opt, LOG_WARNING,
|
||||
"Chunked resource too large for %s%s",
|
||||
back[i].url_adr, back[i].url_fil);
|
||||
chunk_size = -1;
|
||||
} else {
|
||||
back[i].r.adr = (char *) realloct(
|
||||
back[i].r.adr, (size_t) back[i].r.totalsize + 1);
|
||||
if (!back[i].r.adr) {
|
||||
if (cache->log != NULL) {
|
||||
hts_log_print(opt, LOG_ERROR,
|
||||
"not enough memory (" LLintP
|
||||
") for %s%s",
|
||||
(LLint) back[i].r.totalsize,
|
||||
back[i].url_adr, back[i].url_fil);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3611,7 +3735,7 @@ void back_wait(struct_back * sback, httrackp * opt, cache_back * cache,
|
||||
if (back[i].r.statuscode == HTTP_OK && !back[i].testmode) { // 'OK'
|
||||
if (!is_hypertext_mime(opt, back[i].r.contenttype, back[i].url_fil)) { // not HTML
|
||||
if (strnotempty(back[i].url_sav)) { // target found
|
||||
off_t size = fsize_utf8(back[i].url_sav);
|
||||
LLint size = fsize_utf8(back[i].url_sav);
|
||||
|
||||
if (size >= 0) {
|
||||
if (back[i].r.totalsize == size) { // same size!
|
||||
@@ -3830,7 +3954,7 @@ void back_wait(struct_back * sback, httrackp * opt, cache_back * cache,
|
||||
// traiter 206 (partial content)
|
||||
// xxc SI CHUNK VERIFIER QUE CA MARCHE??
|
||||
if (back[i].r.statuscode == 206) { // on nous envoie un morceau (la fin) coz une partie sur disque!
|
||||
off_t sz = fsize_utf8(back[i].url_sav);
|
||||
LLint sz = fsize_utf8(back[i].url_sav);
|
||||
/* RFC 7233: resume at the server's Content-Range start,
|
||||
not the offset we requested; a server may resume
|
||||
earlier and appending the overlap duplicates bytes
|
||||
@@ -3868,8 +3992,9 @@ void back_wait(struct_back * sback, httrackp * opt, cache_back * cache,
|
||||
// drop bytes past the resume point; a silent
|
||||
// failure could leave a stale tail, so on error
|
||||
// drop the partial and refetch the whole file
|
||||
if (HTS_FTRUNCATE(back[i].r.out,
|
||||
(off_t) resume) != 0) {
|
||||
/* not (off_t): 32-bit on MSVC, wrapping a resume
|
||||
past 2GB */
|
||||
if (HTS_FTRUNCATE(back[i].r.out, resume) != 0) {
|
||||
fclose(back[i].r.out);
|
||||
back[i].r.out = NULL;
|
||||
url_savename_refname_remove(
|
||||
@@ -3881,7 +4006,9 @@ void back_wait(struct_back * sback, httrackp * opt, cache_back * cache,
|
||||
"Can not truncate partial file, "
|
||||
"restarting");
|
||||
} else {
|
||||
fseeko(back[i].r.out, (off_t) resume, SEEK_SET);
|
||||
/* not (off_t): 32-bit on MSVC, truncating a
|
||||
resume past 2GB */
|
||||
fseeko(back[i].r.out, resume, SEEK_SET);
|
||||
/* create a temporary reference file in case of
|
||||
* broken mirror */
|
||||
if (back_serialize_ref(opt, &back[i]) != 0) {
|
||||
|
||||
@@ -356,7 +356,7 @@ void cache_add(httrackp * opt, cache_back * cache, const htsblk * r,
|
||||
FILE *fp;
|
||||
|
||||
// On recopie le fichier->.
|
||||
off_t file_size = fsize_utf8(fconv(catbuff, sizeof(catbuff), url_save));
|
||||
LLint file_size = fsize_utf8(fconv(catbuff, sizeof(catbuff), url_save));
|
||||
|
||||
if (file_size >= 0) {
|
||||
fp = FOPEN(fconv(catbuff, sizeof(catbuff), url_save), "rb");
|
||||
@@ -1241,23 +1241,27 @@ char *readfile(const char *fil) {
|
||||
char *readfile2(const char *fil, LLint * size) {
|
||||
char *adr = NULL;
|
||||
char catbuff[CATBUFF_SIZE];
|
||||
INTsys len = 0;
|
||||
const LLint len = fsize(fil);
|
||||
|
||||
len = fsize(fil);
|
||||
if (len >= 0) { // exists
|
||||
/* a size too large for size_t (32-bit Windows/i386) must fail closed: it
|
||||
would wrap malloct() short while fread() still read the untruncated len */
|
||||
const size_t buflen = len >= 0 ? llint_to_size_t(len) : (size_t) -1;
|
||||
|
||||
if (buflen != (size_t) -1) { // exists, and is addressable
|
||||
FILE *fp;
|
||||
|
||||
fp = fopen(fconv(catbuff, sizeof(catbuff), fil), "rb");
|
||||
if (fp != NULL) { // n'existe pas (!)
|
||||
adr = (char *) malloct(len + 1);
|
||||
adr = (char *) malloct(buflen + 1);
|
||||
if (size != NULL)
|
||||
*size = len;
|
||||
if (adr != NULL) {
|
||||
if (len > 0 && fread(adr, 1, len, fp) != len) { // fichier endommagé ?
|
||||
if (buflen > 0 &&
|
||||
fread(adr, 1, buflen, fp) != buflen) { // fichier endommagé ?
|
||||
freet(adr);
|
||||
adr = NULL;
|
||||
} else
|
||||
*(adr + len) = '\0';
|
||||
*(adr + buflen) = '\0';
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
@@ -1269,19 +1273,21 @@ char *readfile2(const char *fil, LLint * size) {
|
||||
char *readfile_utf8(const char *fil) {
|
||||
char *adr = NULL;
|
||||
char catbuff[CATBUFF_SIZE];
|
||||
const off_t len = fsize_utf8(fil);
|
||||
const LLint len = fsize_utf8(fil);
|
||||
const size_t buflen = len >= 0 ? llint_to_size_t(len) : (size_t) -1;
|
||||
|
||||
if (len >= 0) { // exists
|
||||
if (buflen != (size_t) -1) { // exists, and is addressable (see readfile2)
|
||||
FILE *const fp = FOPEN(fconv(catbuff, sizeof(catbuff), fil), "rb");
|
||||
|
||||
if (fp != NULL) { // n'existe pas (!)
|
||||
adr = (char *) malloct(len + 1);
|
||||
adr = (char *) malloct(buflen + 1);
|
||||
if (adr != NULL) {
|
||||
if (len > 0 && fread(adr, 1, len, fp) != len) { // fichier endommagé ?
|
||||
if (buflen > 0 &&
|
||||
fread(adr, 1, buflen, fp) != buflen) { // fichier endommagé ?
|
||||
freet(adr);
|
||||
adr = NULL;
|
||||
} else {
|
||||
adr[len] = '\0';
|
||||
adr[buflen] = '\0';
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
@@ -232,11 +232,10 @@ static int disk_fallback_selftest(httrackp *opt) {
|
||||
static const char body[] = "BINARY-on-disk-body-0123456789-no-trailing-nul";
|
||||
const size_t body_len = sizeof(body) - 1;
|
||||
|
||||
/* X-Save must start with path_html_utf8 so the reader resolves it verbatim
|
||||
(otherwise it re-roots it as a pre-3.40 relative path); then the body we
|
||||
create at fconv(save) is exactly where cache_readex looks for it. */
|
||||
fconcat(save, sizeof(save), StringBuff(opt->path_html_utf8),
|
||||
"example.com/blob.bin");
|
||||
/* a DOS-ified X-Save loses the path_html_utf8 prefix the reader matches on,
|
||||
and gets re-rooted as a pre-3.40 relative path; fconv() only on access */
|
||||
concat(save, sizeof(save), StringBuff(opt->path_html_utf8),
|
||||
"example.com/blob.bin");
|
||||
|
||||
/* write only the header (X-In-Cache: 0); the body stays on disk */
|
||||
selftest_open_for_write(&cache, opt);
|
||||
@@ -939,9 +938,9 @@ static void reconcile_put(httrackp *opt, const char *name, size_t size) {
|
||||
}
|
||||
|
||||
/* Expect `name` to weigh `size` bytes, or be absent when size == -1. */
|
||||
static int reconcile_expect(httrackp *opt, const char *name, off_t size,
|
||||
static int reconcile_expect(httrackp *opt, const char *name, LLint size,
|
||||
const char *what) {
|
||||
const off_t got = fsize(reconcile_st_path(opt, name));
|
||||
const LLint got = fsize(reconcile_st_path(opt, name));
|
||||
|
||||
if (got != size) {
|
||||
fprintf(stderr, "cache-reconcile: %s: %s is %d bytes, expected %d\n", what,
|
||||
@@ -955,7 +954,7 @@ int cache_reconcile_selftest(httrackp *opt, const char *dir) {
|
||||
int failures = 0;
|
||||
|
||||
/* around the interrupted-run thresholds (new < 32768, old > 65536) */
|
||||
static const off_t TINY = 1024, MID = 40000, SOLID = 131072;
|
||||
static const LLint TINY = 1024, MID = 40000, SOLID = 131072;
|
||||
|
||||
golden_setup(opt, dir);
|
||||
#ifdef _WIN32
|
||||
@@ -1253,8 +1252,9 @@ static void corrupt_build_disk(httrackp *opt) {
|
||||
memset(corrupt_body_a, 'a', sizeof(corrupt_body_a) - 1);
|
||||
remove(reconcile_st_path(opt, "hts-cache/new.zip"));
|
||||
remove(reconcile_st_path(opt, "hts-cache/old.zip"));
|
||||
fconcat(save, sizeof(save), StringBuff(opt->path_html_utf8),
|
||||
CORRUPT_ADR "/victim.bin");
|
||||
/* X-Save stored verbatim: see disk_fallback_selftest */
|
||||
concat(save, sizeof(save), StringBuff(opt->path_html_utf8),
|
||||
CORRUPT_ADR "/victim.bin");
|
||||
selftest_open_for_write(&cache, opt);
|
||||
store_entry(opt, &cache, CORRUPT_ADR, "/canary.html", "canary.html", 200,
|
||||
"OK", "text/html", "utf-8", "", "", "", "", corrupt_body_a,
|
||||
|
||||
@@ -31,6 +31,9 @@ Please visit our Website: http://www.httrack.com
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
#include "htscharset.h"
|
||||
#ifdef _WIN32
|
||||
#include <shellapi.h>
|
||||
#endif
|
||||
#include "htsbase.h"
|
||||
#include "punycode.h"
|
||||
#include "htssafe.h"
|
||||
@@ -382,10 +385,44 @@ char *hts_convertStringFromUTF8(const char *s, size_t size, const char *charset)
|
||||
return hts_convertStringCPFromUTF8(s, size, cp);
|
||||
}
|
||||
|
||||
char *hts_convertStringSystemToUTF8(const char *s, size_t size) {
|
||||
HTSEXT_API char *hts_convertStringSystemToUTF8(const char *s, size_t size) {
|
||||
return hts_convertStringCPToUTF8(s, size, GetACP());
|
||||
}
|
||||
|
||||
HTSEXT_API void hts_argv_utf8(int *pargc, char ***pargv) {
|
||||
int wargc = 0;
|
||||
LPWSTR *const wargv = CommandLineToArgvW(GetCommandLineW(), &wargc);
|
||||
char **argv;
|
||||
int i;
|
||||
|
||||
// On any failure keep the CRT's ANSI argv: lossy, but never half-converted.
|
||||
if (wargv == NULL)
|
||||
return;
|
||||
if (wargc <= 0 ||
|
||||
(argv = calloct((size_t) wargc + 1, sizeof(char *))) == NULL) {
|
||||
LocalFree(wargv);
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < wargc; i++) {
|
||||
const int wsize = (int) wcslen(wargv[i]);
|
||||
|
||||
// hts_convertUCS2StringToUTF8() returns NULL on an empty string
|
||||
argv[i] =
|
||||
wsize != 0 ? hts_convertUCS2StringToUTF8(wargv[i], wsize) : strdupt("");
|
||||
if (argv[i] == NULL) {
|
||||
while (i-- != 0)
|
||||
freet(argv[i]);
|
||||
freet(argv);
|
||||
LocalFree(wargv);
|
||||
return;
|
||||
}
|
||||
}
|
||||
argv[wargc] = NULL; // callers may rely on argv[argc] == NULL
|
||||
LocalFree(wargv);
|
||||
*pargc = wargc;
|
||||
*pargv = argv; // never freed: argv lives for the process
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
@@ -34,6 +34,7 @@ Please visit our Website: http://www.httrack.com
|
||||
#define HTS_CHARSET_DEFH
|
||||
|
||||
/** Standard includes. **/
|
||||
#include "htsglobal.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef _WIN32
|
||||
@@ -174,7 +175,16 @@ extern char *hts_convertUCS2StringToUTF8(LPWSTR woutput, int wsize);
|
||||
* Convert current system codepage to UTF-8.
|
||||
* This function is WIN32 specific.
|
||||
**/
|
||||
extern char *hts_convertStringSystemToUTF8(const char *s, size_t size);
|
||||
HTSEXT_API char *hts_convertStringSystemToUTF8(const char *s, size_t size);
|
||||
|
||||
/**
|
||||
* Replace the CRT's ANSI argv by a UTF-8 one decoded from the real UTF-16
|
||||
* command line: every char* is UTF-8 on Windows (FOPEN, STAT, ... convert at
|
||||
* the syscall boundary). Keeps the CRT's argv on failure; the new array is
|
||||
* writable, NULL-terminated, and lives for the process.
|
||||
* This function is WIN32 specific.
|
||||
**/
|
||||
HTSEXT_API void hts_argv_utf8(int *pargc, char ***pargv);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
366
src/htscodec.c
Normal file
366
src/htscodec.c
Normal file
@@ -0,0 +1,366 @@
|
||||
/* ------------------------------------------------------------ */
|
||||
/*
|
||||
HTTrack Website Copier, Offline Browser for Windows and Unix
|
||||
Copyright (C) 2026 Xavier Roche and other contributors
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Ethical use: we kindly ask that you NOT use this software to harvest email
|
||||
addresses or to collect any other private information about people. Doing so
|
||||
would dishonor our work and waste the many hours we have spent on it.
|
||||
|
||||
Please visit our Website: http://www.httrack.com
|
||||
*/
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/* File: HTTP content codings (gzip/deflate, brotli, zstd) */
|
||||
/* Author: Xavier Roche */
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
/* Internal engine bytecode */
|
||||
#define HTS_INTERNAL_BYTECODE
|
||||
|
||||
#include "htsbase.h"
|
||||
#include "htscore.h"
|
||||
#include "htscodec.h"
|
||||
#include "htszlib.h"
|
||||
|
||||
#if HTS_USEBROTLI
|
||||
#include <brotli/decode.h>
|
||||
#endif
|
||||
|
||||
#if HTS_USEZSTD
|
||||
#include <zstd.h>
|
||||
/* 8 MB, the window an HTTP zstd decoder must honor (RFC 9659); libzstd
|
||||
defaults to 128 MB. */
|
||||
#define HTS_ZSTD_WINDOWLOG_MAX 23
|
||||
#endif
|
||||
|
||||
/* Decoded-size budget, bounding a bomb: brotli and zstd reach a million to one.
|
||||
Deflate cannot pass 1032x, so it only meets this at the 2 GiB ceiling. */
|
||||
#define HTS_CODEC_MAX_RATIO 4096
|
||||
#define HTS_CODEC_MIN_MAXOUT (1024 * 1024)
|
||||
|
||||
LLint hts_codec_maxout(LLint in_size) {
|
||||
LLint maxout;
|
||||
|
||||
if (in_size <= 0 || in_size > INT_MAX / HTS_CODEC_MAX_RATIO)
|
||||
maxout = INT_MAX;
|
||||
else
|
||||
maxout = in_size * HTS_CODEC_MAX_RATIO;
|
||||
if (maxout < HTS_CODEC_MIN_MAXOUT)
|
||||
maxout = HTS_CODEC_MIN_MAXOUT;
|
||||
return maxout;
|
||||
}
|
||||
|
||||
hts_codec hts_codec_parse(const char *encoding) {
|
||||
if (encoding == NULL || encoding[0] == '\0' ||
|
||||
strfield2(encoding, "identity"))
|
||||
return HTS_CODEC_IDENTITY;
|
||||
if (strfield2(encoding, "gzip") || strfield2(encoding, "x-gzip") ||
|
||||
strfield2(encoding, "deflate") || strfield2(encoding, "x-deflate"))
|
||||
return HTS_USEZLIB ? HTS_CODEC_DEFLATE : HTS_CODEC_UNSUPPORTED;
|
||||
if (strfield2(encoding, "br"))
|
||||
return HTS_USEBROTLI ? HTS_CODEC_BROTLI : HTS_CODEC_UNSUPPORTED;
|
||||
if (strfield2(encoding, "zstd"))
|
||||
return HTS_USEZSTD ? HTS_CODEC_ZSTD : HTS_CODEC_UNSUPPORTED;
|
||||
if (strfield2(encoding, "compress") || strfield2(encoding, "x-compress"))
|
||||
return HTS_CODEC_UNSUPPORTED; /* LZW: never advertised, no decoder here */
|
||||
/* Not a coding at all: broken servers put charsets and the like here, and
|
||||
the plain body they sent must survive it. */
|
||||
return HTS_CODEC_IDENTITY;
|
||||
}
|
||||
|
||||
#if HTS_USEBROTLI
|
||||
#define HTS_AE_BROTLI ", br"
|
||||
#else
|
||||
#define HTS_AE_BROTLI ""
|
||||
#endif
|
||||
#if HTS_USEZSTD
|
||||
#define HTS_AE_ZSTD ", zstd"
|
||||
#else
|
||||
#define HTS_AE_ZSTD ""
|
||||
#endif
|
||||
|
||||
const char *hts_acceptencoding(hts_boolean compressible, hts_boolean secure) {
|
||||
if (!compressible)
|
||||
return "identity";
|
||||
#if HTS_USEZLIB
|
||||
/* br and zstd over TLS only, as browsers do: a cleartext intermediary that
|
||||
rewrites a coding it can not read would corrupt the mirror. */
|
||||
if (secure)
|
||||
return "gzip, deflate" HTS_AE_BROTLI HTS_AE_ZSTD ", identity;q=0.9";
|
||||
return "gzip, deflate, identity;q=0.9";
|
||||
#else
|
||||
(void) secure;
|
||||
return "identity";
|
||||
#endif
|
||||
}
|
||||
|
||||
hts_boolean hts_codec_is_archive_ext(hts_codec codec, const char *ext) {
|
||||
if (ext == NULL || ext[0] == '\0')
|
||||
return HTS_FALSE;
|
||||
switch (codec) {
|
||||
case HTS_CODEC_DEFLATE:
|
||||
return strfield2(ext, "gz") || strfield2(ext, "tgz") ? HTS_TRUE : HTS_FALSE;
|
||||
case HTS_CODEC_BROTLI:
|
||||
return strfield2(ext, "br") ? HTS_TRUE : HTS_FALSE;
|
||||
case HTS_CODEC_ZSTD:
|
||||
return strfield2(ext, "zst") || strfield2(ext, "tzst") ? HTS_TRUE
|
||||
: HTS_FALSE;
|
||||
default:
|
||||
return HTS_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
#if HTS_USEBROTLI || HTS_USEZSTD
|
||||
/* Append produced bytes to out under the decoded-size budget, advancing *total.
|
||||
HTS_FALSE on a short write or once the budget is exceeded (a bomb); the
|
||||
over-budget bytes are never written. */
|
||||
static hts_boolean codec_sink(FILE *out, const void *buf, size_t produced,
|
||||
LLint *total, LLint maxout) {
|
||||
if (produced == 0)
|
||||
return HTS_TRUE;
|
||||
*total += (LLint) produced;
|
||||
if (*total > maxout)
|
||||
return HTS_FALSE;
|
||||
return fwrite(buf, 1, produced, out) == produced ? HTS_TRUE : HTS_FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HTS_USEBROTLI
|
||||
static int codec_unpack_brotli(FILE *in, FILE *out, LLint maxout) {
|
||||
BrotliDecoderState *const state =
|
||||
BrotliDecoderCreateInstance(NULL, NULL, NULL);
|
||||
hts_boolean ok = HTS_TRUE, done = HTS_FALSE;
|
||||
LLint total = 0;
|
||||
|
||||
if (state == NULL)
|
||||
return -1;
|
||||
while (ok && !done) {
|
||||
unsigned char BIGSTK inbuf[8192];
|
||||
size_t avail_in = fread(inbuf, 1, sizeof(inbuf), in);
|
||||
const uint8_t *next_in = inbuf;
|
||||
|
||||
if (avail_in == 0)
|
||||
break; /* EOF; a stream still hungry for input is truncated */
|
||||
for (;;) {
|
||||
unsigned char BIGSTK outbuf[8192];
|
||||
uint8_t *next_out = outbuf;
|
||||
size_t avail_out = sizeof(outbuf);
|
||||
size_t produced;
|
||||
BrotliDecoderResult res;
|
||||
|
||||
res = BrotliDecoderDecompressStream(state, &avail_in, &next_in,
|
||||
&avail_out, &next_out, NULL);
|
||||
produced = sizeof(outbuf) - avail_out;
|
||||
if (!codec_sink(out, outbuf, produced, &total, maxout)) {
|
||||
ok = HTS_FALSE;
|
||||
break;
|
||||
}
|
||||
if (res == BROTLI_DECODER_RESULT_ERROR) {
|
||||
ok = HTS_FALSE;
|
||||
break;
|
||||
}
|
||||
if (res == BROTLI_DECODER_RESULT_SUCCESS) {
|
||||
done = HTS_TRUE;
|
||||
break;
|
||||
}
|
||||
if (res == BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT)
|
||||
break;
|
||||
}
|
||||
if (ferror(in))
|
||||
ok = HTS_FALSE;
|
||||
}
|
||||
BrotliDecoderDestroyInstance(state);
|
||||
return (ok && done && !ferror(in)) ? (int) total : -1;
|
||||
}
|
||||
|
||||
static size_t codec_head_brotli(const void *in, size_t in_len, void *out,
|
||||
size_t out_len) {
|
||||
BrotliDecoderState *const state =
|
||||
BrotliDecoderCreateInstance(NULL, NULL, NULL);
|
||||
const uint8_t *next_in = (const uint8_t *) in;
|
||||
uint8_t *next_out = (uint8_t *) out;
|
||||
size_t avail_in = in_len, avail_out = out_len;
|
||||
BrotliDecoderResult res;
|
||||
|
||||
if (state == NULL)
|
||||
return 0;
|
||||
res = BrotliDecoderDecompressStream(state, &avail_in, &next_in, &avail_out,
|
||||
&next_out, NULL);
|
||||
BrotliDecoderDestroyInstance(state);
|
||||
return (res != BROTLI_DECODER_RESULT_ERROR) ? out_len - avail_out : 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HTS_USEZSTD
|
||||
static int codec_unpack_zstd(FILE *in, FILE *out, LLint maxout) {
|
||||
ZSTD_DStream *const zds = ZSTD_createDStream();
|
||||
hts_boolean ok = HTS_TRUE, eof = HTS_FALSE;
|
||||
size_t zret = 1; /* 0 once a frame is fully flushed */
|
||||
LLint total = 0;
|
||||
|
||||
if (zds == NULL)
|
||||
return -1;
|
||||
if (ZSTD_isError(ZSTD_DCtx_setParameter(zds, ZSTD_d_windowLogMax,
|
||||
HTS_ZSTD_WINDOWLOG_MAX))) {
|
||||
ZSTD_freeDStream(zds);
|
||||
return -1;
|
||||
}
|
||||
while (ok && !eof) {
|
||||
unsigned char BIGSTK inbuf[8192];
|
||||
ZSTD_inBuffer input;
|
||||
|
||||
input.src = inbuf;
|
||||
input.size = fread(inbuf, 1, sizeof(inbuf), in);
|
||||
input.pos = 0;
|
||||
if (input.size == 0) {
|
||||
eof = HTS_TRUE;
|
||||
break;
|
||||
}
|
||||
while (input.pos < input.size) {
|
||||
unsigned char BIGSTK outbuf[8192];
|
||||
ZSTD_outBuffer output;
|
||||
|
||||
output.dst = outbuf;
|
||||
output.size = sizeof(outbuf);
|
||||
output.pos = 0;
|
||||
zret = ZSTD_decompressStream(zds, &output, &input);
|
||||
if (ZSTD_isError(zret)) {
|
||||
ok = HTS_FALSE;
|
||||
break;
|
||||
}
|
||||
if (!codec_sink(out, outbuf, output.pos, &total, maxout)) {
|
||||
ok = HTS_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ferror(in))
|
||||
ok = HTS_FALSE;
|
||||
}
|
||||
ZSTD_freeDStream(zds);
|
||||
/* zret != 0 at EOF: the last frame never completed */
|
||||
return (ok && zret == 0 && !ferror(in)) ? (int) total : -1;
|
||||
}
|
||||
|
||||
static size_t codec_head_zstd(const void *in, size_t in_len, void *out,
|
||||
size_t out_len) {
|
||||
ZSTD_DStream *const zds = ZSTD_createDStream();
|
||||
ZSTD_inBuffer input;
|
||||
ZSTD_outBuffer output;
|
||||
size_t zret;
|
||||
|
||||
if (zds == NULL)
|
||||
return 0;
|
||||
if (ZSTD_isError(ZSTD_DCtx_setParameter(zds, ZSTD_d_windowLogMax,
|
||||
HTS_ZSTD_WINDOWLOG_MAX))) {
|
||||
ZSTD_freeDStream(zds);
|
||||
return 0;
|
||||
}
|
||||
input.src = in;
|
||||
input.size = in_len;
|
||||
input.pos = 0;
|
||||
output.dst = out;
|
||||
output.size = out_len;
|
||||
output.pos = 0;
|
||||
zret = ZSTD_decompressStream(zds, &output, &input);
|
||||
ZSTD_freeDStream(zds);
|
||||
return ZSTD_isError(zret) ? 0 : output.pos;
|
||||
}
|
||||
#endif
|
||||
|
||||
LLint hts_codec_coded_size(FILE *in) {
|
||||
long size;
|
||||
|
||||
if (fseek(in, 0, SEEK_END) != 0)
|
||||
return -1;
|
||||
size = ftell(in);
|
||||
if (size < 0 || fseek(in, 0, SEEK_SET) != 0)
|
||||
return -1;
|
||||
return (LLint) size;
|
||||
}
|
||||
|
||||
int hts_codec_unpack(hts_codec codec, const char *filename,
|
||||
const char *newfile) {
|
||||
if (filename == NULL || newfile == NULL || !filename[0] || !newfile[0])
|
||||
return -1;
|
||||
switch (codec) {
|
||||
case HTS_CODEC_DEFLATE:
|
||||
#if HTS_USEZLIB
|
||||
return hts_zunpack(filename, newfile);
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
case HTS_CODEC_BROTLI:
|
||||
case HTS_CODEC_ZSTD:
|
||||
break;
|
||||
default: /* IDENTITY never reaches the unpacker; UNSUPPORTED must fail */
|
||||
return -1;
|
||||
}
|
||||
#if HTS_USEBROTLI || HTS_USEZSTD
|
||||
{
|
||||
char catbuff[CATBUFF_SIZE];
|
||||
FILE *out, *in = FOPEN(fconv(catbuff, sizeof(catbuff), filename), "rb");
|
||||
LLint maxout;
|
||||
int ret = -1;
|
||||
|
||||
if (in == NULL)
|
||||
return -1;
|
||||
maxout = hts_codec_maxout(hts_codec_coded_size(in));
|
||||
out = FOPEN(fconv(catbuff, sizeof(catbuff), newfile), "wb");
|
||||
if (out == NULL) {
|
||||
fclose(in);
|
||||
return -1;
|
||||
}
|
||||
#if HTS_USEBROTLI
|
||||
if (codec == HTS_CODEC_BROTLI)
|
||||
ret = codec_unpack_brotli(in, out, maxout);
|
||||
#endif
|
||||
#if HTS_USEZSTD
|
||||
if (codec == HTS_CODEC_ZSTD)
|
||||
ret = codec_unpack_zstd(in, out, maxout);
|
||||
#endif
|
||||
fclose(out);
|
||||
fclose(in);
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
size_t hts_codec_head(hts_codec codec, const void *in, size_t in_len, void *out,
|
||||
size_t out_len) {
|
||||
if (in == NULL || in_len == 0 || out == NULL || out_len == 0)
|
||||
return 0;
|
||||
switch (codec) {
|
||||
#if HTS_USEZLIB
|
||||
case HTS_CODEC_DEFLATE:
|
||||
return hts_zhead(in, in_len, out, out_len);
|
||||
#endif
|
||||
#if HTS_USEBROTLI
|
||||
case HTS_CODEC_BROTLI:
|
||||
return codec_head_brotli(in, in_len, out, out_len);
|
||||
#endif
|
||||
#if HTS_USEZSTD
|
||||
case HTS_CODEC_ZSTD:
|
||||
return codec_head_zstd(in, in_len, out, out_len);
|
||||
#endif
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
79
src/htscodec.h
Normal file
79
src/htscodec.h
Normal file
@@ -0,0 +1,79 @@
|
||||
/* ------------------------------------------------------------ */
|
||||
/*
|
||||
HTTrack Website Copier, Offline Browser for Windows and Unix
|
||||
Copyright (C) 2026 Xavier Roche and other contributors
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Ethical use: we kindly ask that you NOT use this software to harvest email
|
||||
addresses or to collect any other private information about people. Doing so
|
||||
would dishonor our work and waste the many hours we have spent on it.
|
||||
|
||||
Please visit our Website: http://www.httrack.com
|
||||
*/
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/* File: HTTP content codings (gzip/deflate, brotli, zstd) */
|
||||
/* Author: Xavier Roche */
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
#ifndef HTS_DEFCODEC
|
||||
#define HTS_DEFCODEC
|
||||
|
||||
#include "htsglobal.h"
|
||||
|
||||
/* Content codings we may meet in a Content-Encoding header. */
|
||||
typedef enum {
|
||||
HTS_CODEC_IDENTITY = 0, /**< no coding, or a token we treat as none */
|
||||
HTS_CODEC_DEFLATE, /**< gzip, x-gzip, deflate, x-deflate */
|
||||
HTS_CODEC_BROTLI, /**< br */
|
||||
HTS_CODEC_ZSTD, /**< zstd */
|
||||
HTS_CODEC_UNSUPPORTED /**< a real coding we can not decode */
|
||||
} hts_codec;
|
||||
|
||||
#ifdef HTS_INTERNAL_BYTECODE
|
||||
|
||||
/* Codec for a Content-Encoding token. A known coding we can not decode is
|
||||
UNSUPPORTED; an unrecognized token is IDENTITY (servers do emit junk). */
|
||||
extern hts_codec hts_codec_parse(const char *encoding);
|
||||
|
||||
/* Accept-Encoding value to advertise; secure (TLS) also offers br and zstd. */
|
||||
extern const char *hts_acceptencoding(hts_boolean compressible,
|
||||
hts_boolean secure);
|
||||
|
||||
/* HTS_TRUE if ext is the codec's own archive extension: a foo.gz served as
|
||||
Content-Encoding: gzip stays packed on disk. */
|
||||
extern hts_boolean hts_codec_is_archive_ext(hts_codec codec, const char *ext);
|
||||
|
||||
/* Decode filename into newfile. Returns the decoded size, or -1 on a truncated
|
||||
or corrupt stream, an unsupported coding, a bomb over the budget, or I/O. */
|
||||
extern int hts_codec_unpack(hts_codec codec, const char *filename,
|
||||
const char *newfile);
|
||||
|
||||
/* Decode up to out_len leading bytes of a coded body for the MIME sniffer;
|
||||
0 when nothing could be decoded. */
|
||||
extern size_t hts_codec_head(hts_codec codec, const void *in, size_t in_len,
|
||||
void *out, size_t out_len);
|
||||
|
||||
/* Ceiling on the decoded size of a body of in_size coded bytes. */
|
||||
extern LLint hts_codec_maxout(LLint in_size);
|
||||
|
||||
/* Coded size of an open stream, left rewound; -1 if unknown. */
|
||||
extern LLint hts_codec_coded_size(FILE *in);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -855,7 +855,7 @@ int httpmirror(char *url1, httrackp * opt) {
|
||||
char *filelist_buff = NULL;
|
||||
size_t filelist_sz = 0;
|
||||
const char *filelist_err = NULL; /* failure reason, NULL on success */
|
||||
const off_t fs = fsize(StringBuff(opt->filelist));
|
||||
const LLint fs = fsize(StringBuff(opt->filelist));
|
||||
|
||||
if (fs < 0) {
|
||||
/* fsize() hides the cause; redo stat() for a precise errno (#49) */
|
||||
@@ -863,7 +863,7 @@ int httpmirror(char *url1, httrackp * opt) {
|
||||
filelist_err = stat(StringBuff(opt->filelist), &st) != 0
|
||||
? strerror(errno)
|
||||
: "not a regular file";
|
||||
} else if ((filelist_sz = off_t_to_size_t(fs)) == (size_t) -1) {
|
||||
} else if ((filelist_sz = llint_to_size_t(fs)) == (size_t) -1) {
|
||||
filelist_err = "file too large";
|
||||
filelist_sz = 0;
|
||||
} else {
|
||||
@@ -2089,10 +2089,9 @@ int httpmirror(char *url1, httrackp * opt) {
|
||||
(OPT_GET_BUFF(opt), OPT_GET_BUFF_SIZE(opt), StringBuff(opt->path_log),
|
||||
"hts-cache/old.lst"), "rb");
|
||||
if (old_lst) {
|
||||
const size_t sz =
|
||||
off_t_to_size_t(fsize(fconcat
|
||||
(OPT_GET_BUFF(opt), OPT_GET_BUFF_SIZE(opt), StringBuff(opt->path_log),
|
||||
"hts-cache/new.lst")));
|
||||
const size_t sz = llint_to_size_t(
|
||||
fsize(fconcat(OPT_GET_BUFF(opt), OPT_GET_BUFF_SIZE(opt),
|
||||
StringBuff(opt->path_log), "hts-cache/new.lst")));
|
||||
new_lst =
|
||||
fopen(fconcat
|
||||
(OPT_GET_BUFF(opt), OPT_GET_BUFF_SIZE(opt), StringBuff(opt->path_log),
|
||||
|
||||
@@ -1509,7 +1509,7 @@ static int hts_main_internal(int argc, char **argv, httrackp * opt) {
|
||||
htsmain_free();
|
||||
return -1;
|
||||
} else {
|
||||
off_t fz;
|
||||
LLint fz;
|
||||
|
||||
na++;
|
||||
fz = fsize(argv[na]);
|
||||
@@ -2253,21 +2253,12 @@ static int hts_main_internal(int argc, char **argv, httrackp * opt) {
|
||||
htsmain_free();
|
||||
return -1;
|
||||
} else {
|
||||
char *a;
|
||||
char BIGSTK pname[HTS_URLMAXSIZE * 2];
|
||||
|
||||
na++;
|
||||
opt->proxy.active = 1;
|
||||
// Rechercher MAIS en partant de la fin à cause de user:pass@proxy:port
|
||||
a = argv[na] + strlen(argv[na]) - 1;
|
||||
while((a > argv[na]) && (*a != ':') && (*a != '@'))
|
||||
a--;
|
||||
if (*a == ':') { // un port est présent, <proxy>:port
|
||||
sscanf(a + 1, "%d", &opt->proxy.port);
|
||||
StringCopyN(opt->proxy.name, argv[na], (int) (a - argv[na]));
|
||||
} else { // <proxy>
|
||||
opt->proxy.port = 8080;
|
||||
StringCopy(opt->proxy.name, argv[na]);
|
||||
}
|
||||
hts_parse_proxy(argv[na], pname, sizeof(pname), &opt->proxy.port);
|
||||
StringCopy(opt->proxy.name, pname);
|
||||
}
|
||||
break;
|
||||
case 'F': // user-agent field
|
||||
@@ -2593,21 +2584,11 @@ static int hts_main_internal(int argc, char **argv, httrackp * opt) {
|
||||
hts_get_version_info(opt), t, url);
|
||||
fprintf(opt->log, "(");
|
||||
for(i = 0; i < argc; i++) {
|
||||
#ifdef _WIN32
|
||||
char *carg =
|
||||
hts_convertStringSystemToUTF8(argv[i], (int) strlen(argv[i]));
|
||||
char *arg = carg != NULL ? carg : argv[i];
|
||||
#else
|
||||
const char *arg = argv[i];
|
||||
#endif
|
||||
const char *arg = argv[i]; // already UTF-8 on every platform
|
||||
if (strchr(arg, ' ') == NULL || strchr(arg, '\"') != NULL)
|
||||
fprintf(opt->log, "%s ", arg);
|
||||
else // entre "" (si espace(s) et pas déja de ")
|
||||
fprintf(opt->log, "\"%s\" ", arg);
|
||||
#ifdef _WIN32
|
||||
if (carg != NULL)
|
||||
free(carg);
|
||||
#endif
|
||||
}
|
||||
fprintf(opt->log, ")" LF);
|
||||
fprintf(opt->log, LF);
|
||||
|
||||
@@ -133,9 +133,10 @@ static struct addrinfo *mock_mkai(const mock_addr *a) {
|
||||
return ai;
|
||||
}
|
||||
|
||||
static int mock_getaddrinfo(const char *node, const char *service,
|
||||
const struct addrinfo *hints,
|
||||
struct addrinfo **res) {
|
||||
static int HTS_RESOLVER_CALL mock_getaddrinfo(const char *node,
|
||||
const char *service,
|
||||
const struct addrinfo *hints,
|
||||
struct addrinfo **res) {
|
||||
mock_host *const h = mock_find(node);
|
||||
const int want = (hints != NULL) ? hints->ai_family : PF_UNSPEC;
|
||||
struct addrinfo *head = NULL, *tail = NULL;
|
||||
@@ -164,7 +165,7 @@ static int mock_getaddrinfo(const char *node, const char *service,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mock_freeaddrinfo(struct addrinfo *res) {
|
||||
static void HTS_RESOLVER_CALL mock_freeaddrinfo(struct addrinfo *res) {
|
||||
while (res != NULL) {
|
||||
struct addrinfo *const next = res->ai_next;
|
||||
|
||||
|
||||
@@ -122,8 +122,11 @@ int fa_strjoker_dual(int type, char **filters, int nfil, const char *nom1,
|
||||
}
|
||||
|
||||
/* Real filters/URLs fit HTS_URLMAXSIZE*2; past it a hostile pattern recurses
|
||||
O(len) deep or runs O(n^2*stars). Cap length (depth) and steps (work). */
|
||||
O(len) deep or runs O(n^2*stars). Cap length, recursion depth and steps
|
||||
(work): the length cap alone still allows ~2000 frames, ~900KB of stack,
|
||||
which overflows the 1MB a Windows thread gets (#574). */
|
||||
#define STRJOKER_MAXLEN (HTS_URLMAXSIZE * 2)
|
||||
#define STRJOKER_MAXDEPTH 256u
|
||||
#define STRJOKER_MAXSTEPS 2000000u
|
||||
|
||||
/* Failure memo for the recursive matcher: one bit per (chaine, joker) offset
|
||||
@@ -133,30 +136,41 @@ typedef struct strjoker_memo {
|
||||
size_t stride; /* strlen(joker0) + 1 */
|
||||
unsigned char *failed; /* failed-pair bitmap; NULL: no memo */
|
||||
size_t *nsteps; /* shared work counter; NULL: unbounded (oracle) */
|
||||
size_t maxdepth; /* deepest recursion reached */
|
||||
hts_boolean cut; /* a branch hit the depth cap: its failures are not final */
|
||||
} strjoker_memo;
|
||||
|
||||
static const char *strjoker_impl(const strjoker_memo *memo, const char *chaine,
|
||||
const char *joker, LLint *size,
|
||||
int *size_flag);
|
||||
static const char *strjoker_impl(strjoker_memo *memo, const char *chaine,
|
||||
const char *joker, LLint *size, int *size_flag,
|
||||
size_t depth);
|
||||
|
||||
/* A pair that failed once fails forever (*size is only written on the success
|
||||
path), so record NULL results and cut the re-exploration. */
|
||||
static const char *strjoker_rec(const strjoker_memo *memo, const char *chaine,
|
||||
const char *joker, LLint *size,
|
||||
int *size_flag) {
|
||||
static const char *strjoker_rec(strjoker_memo *memo, const char *chaine,
|
||||
const char *joker, LLint *size, int *size_flag,
|
||||
size_t depth) {
|
||||
size_t bit = 0;
|
||||
const char *adr;
|
||||
|
||||
if (depth > memo->maxdepth)
|
||||
memo->maxdepth = depth;
|
||||
/* Charge the budget before the depth cap: cut disables the memo, so uncounted
|
||||
deep calls would let the sub-cap search explode (OSS-Fuzz 535114376). */
|
||||
if (memo->nsteps != NULL && ++*memo->nsteps > STRJOKER_MAXSTEPS)
|
||||
return NULL; /* work budget spent: fail the match safely */
|
||||
if (depth >= STRJOKER_MAXDEPTH) {
|
||||
memo->cut = HTS_TRUE;
|
||||
return NULL; /* nesting beyond any real filter: fail the branch safely */
|
||||
}
|
||||
if (memo->failed) {
|
||||
bit = (size_t) (chaine - memo->chaine0) * memo->stride +
|
||||
(size_t) (joker - memo->joker0);
|
||||
if (memo->failed[bit >> 3] & (unsigned char) (1u << (bit & 7)))
|
||||
return NULL;
|
||||
}
|
||||
adr = strjoker_impl(memo, chaine, joker, size, size_flag);
|
||||
if (adr == NULL && memo->failed)
|
||||
adr = strjoker_impl(memo, chaine, joker, size, size_flag, depth + 1);
|
||||
/* a cut branch may fail here yet match when reached at a shallower depth */
|
||||
if (adr == NULL && memo->failed && !memo->cut)
|
||||
memo->failed[bit >> 3] |= (unsigned char) (1u << (bit & 7));
|
||||
return adr;
|
||||
}
|
||||
@@ -164,13 +178,15 @@ static const char *strjoker_rec(const strjoker_memo *memo, const char *chaine,
|
||||
/* Match chaine against joker with a shared work budget *nsteps (a strjokerfind
|
||||
sweep passes one counter, bounding the whole scan). */
|
||||
static const char *strjoker_bounded(const char *chaine, const char *joker,
|
||||
LLint *size, int *size_flag,
|
||||
size_t *nsteps) {
|
||||
strjoker_memo memo = {chaine, joker, 0, NULL, nsteps};
|
||||
LLint *size, int *size_flag, size_t *nsteps,
|
||||
size_t *maxdepth) {
|
||||
strjoker_memo memo = {chaine, joker, 0, NULL, nsteps, 0, HTS_FALSE};
|
||||
unsigned char stackbits[2048];
|
||||
hts_boolean onheap = HTS_FALSE;
|
||||
const char *adr;
|
||||
|
||||
if (maxdepth != NULL)
|
||||
*maxdepth = 0;
|
||||
if (chaine != NULL && joker != NULL) {
|
||||
const size_t l1 = strlen(chaine), l2 = strlen(joker);
|
||||
|
||||
@@ -189,9 +205,11 @@ static const char *strjoker_bounded(const char *chaine, const char *joker,
|
||||
}
|
||||
}
|
||||
}
|
||||
adr = strjoker_rec(&memo, chaine, joker, size, size_flag);
|
||||
adr = strjoker_rec(&memo, chaine, joker, size, size_flag, 0);
|
||||
if (onheap)
|
||||
freet(memo.failed);
|
||||
if (maxdepth != NULL)
|
||||
*maxdepth = memo.maxdepth;
|
||||
return adr;
|
||||
}
|
||||
|
||||
@@ -202,20 +220,39 @@ HTS_INLINE const char *strjoker(const char *chaine, const char *joker,
|
||||
LLint *size, int *size_flag) {
|
||||
size_t nsteps = 0;
|
||||
|
||||
return strjoker_bounded(chaine, joker, size, size_flag, &nsteps);
|
||||
return strjoker_bounded(chaine, joker, size, size_flag, &nsteps, NULL);
|
||||
}
|
||||
|
||||
/* Test-only oracle: the same matcher without the failure memo. */
|
||||
const char *strjoker_nomemo(const char *chaine, const char *joker, LLint *size,
|
||||
int *size_flag) {
|
||||
const strjoker_memo memo = {chaine, joker, 0, NULL};
|
||||
strjoker_memo memo = {chaine, joker, 0, NULL, NULL, 0, HTS_FALSE};
|
||||
|
||||
return strjoker_rec(&memo, chaine, joker, size, size_flag);
|
||||
return strjoker_rec(&memo, chaine, joker, size, size_flag, 0);
|
||||
}
|
||||
|
||||
static const char *strjoker_impl(const strjoker_memo *memo, const char *chaine,
|
||||
const char *joker, LLint *size,
|
||||
int *size_flag) {
|
||||
/* Test-only: strjoker() reporting the work and depth spent and their caps, so a
|
||||
self-test can prove both bound a hostile pattern. */
|
||||
const char *strjoker_bounds(const char *chaine, const char *joker,
|
||||
size_t *nsteps_out, size_t *maxsteps_out,
|
||||
size_t *depth_out, size_t *maxdepth_out) {
|
||||
size_t nsteps = 0, depth = 0;
|
||||
const char *r = strjoker_bounded(chaine, joker, NULL, NULL, &nsteps, &depth);
|
||||
|
||||
if (nsteps_out != NULL)
|
||||
*nsteps_out = nsteps;
|
||||
if (maxsteps_out != NULL)
|
||||
*maxsteps_out = STRJOKER_MAXSTEPS;
|
||||
if (depth_out != NULL)
|
||||
*depth_out = depth;
|
||||
if (maxdepth_out != NULL)
|
||||
*maxdepth_out = STRJOKER_MAXDEPTH;
|
||||
return r;
|
||||
}
|
||||
|
||||
static const char *strjoker_impl(strjoker_memo *memo, const char *chaine,
|
||||
const char *joker, LLint *size, int *size_flag,
|
||||
size_t depth) {
|
||||
if (strnotempty(joker) == 0) { // fin de chaine joker
|
||||
if (strnotempty(chaine) == 0) // fin aussi pour la chaine: ok
|
||||
return chaine;
|
||||
@@ -389,7 +426,8 @@ static const char *strjoker_impl(const strjoker_memo *memo, const char *chaine,
|
||||
|
||||
// tester sans le joker (pas ()+ mais ()*)
|
||||
if (!unique) {
|
||||
if ((adr = strjoker_rec(memo, chaine, joker + jmp, size, size_flag))) {
|
||||
if ((adr = strjoker_rec(memo, chaine, joker + jmp, size, size_flag,
|
||||
depth))) {
|
||||
return adr;
|
||||
}
|
||||
}
|
||||
@@ -402,7 +440,7 @@ static const char *strjoker_impl(const strjoker_memo *memo, const char *chaine,
|
||||
while(i < (int) max) {
|
||||
if (pass[(int) (unsigned char) chaine[i]]) { // caractère autorisé
|
||||
if ((adr = strjoker_rec(memo, chaine + i + 1, joker + jmp, size,
|
||||
size_flag))) {
|
||||
size_flag, depth))) {
|
||||
return adr;
|
||||
}
|
||||
i++;
|
||||
@@ -413,7 +451,7 @@ static const char *strjoker_impl(const strjoker_memo *memo, const char *chaine,
|
||||
// tester chaîne vide
|
||||
if (i != max + 2) // avant c'est ok
|
||||
if ((adr = strjoker_rec(memo, chaine + max, joker + jmp, size,
|
||||
size_flag)))
|
||||
size_flag, depth)))
|
||||
return adr;
|
||||
|
||||
return NULL; // perdu
|
||||
@@ -435,7 +473,8 @@ static const char *strjoker_impl(const strjoker_memo *memo, const char *chaine,
|
||||
// comparaison ok?
|
||||
if (ok) {
|
||||
// continuer la comparaison.
|
||||
if (strjoker_rec(memo, chaine + jmp, joker + jmp, size, size_flag))
|
||||
if (strjoker_rec(memo, chaine + jmp, joker + jmp, size, size_flag,
|
||||
depth))
|
||||
return chaine; // retourner 1e lettre
|
||||
}
|
||||
|
||||
@@ -457,8 +496,8 @@ const char *strjokerfind(const char *chaine, const char *joker) {
|
||||
if (chaine != NULL && strlen(chaine) > STRJOKER_MAXLEN)
|
||||
return NULL;
|
||||
while(*chaine) {
|
||||
if ((adr = strjoker_bounded(chaine, joker, NULL, NULL,
|
||||
&nsteps))) { // ok trouvé
|
||||
if ((adr = strjoker_bounded(chaine, joker, NULL, NULL, &nsteps,
|
||||
NULL))) { // ok trouvé
|
||||
return adr;
|
||||
}
|
||||
if (nsteps > STRJOKER_MAXSTEPS) // scan budget spent: no match
|
||||
|
||||
@@ -52,6 +52,12 @@ HTS_INLINE const char *strjoker(const char *chaine, const char *joker, LLint * s
|
||||
oracle for the memoized matcher. */
|
||||
const char *strjoker_nomemo(const char *chaine, const char *joker, LLint *size,
|
||||
int *size_flag);
|
||||
/* strjoker() reporting the work-budget steps and the recursion depth it spent,
|
||||
with their caps; test-only, lets a self-test assert both bound a hostile
|
||||
pattern (depth bounds the stack: an uncapped one overflows Windows' 1MB). */
|
||||
const char *strjoker_bounds(const char *chaine, const char *joker,
|
||||
size_t *nsteps_out, size_t *maxsteps_out,
|
||||
size_t *depth_out, size_t *maxdepth_out);
|
||||
const char *strjokerfind(const char *chaine, const char *joker);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -140,6 +140,15 @@ Please visit our Website: http://www.httrack.com
|
||||
#define HTS_USEZLIB 1
|
||||
#endif
|
||||
|
||||
// brotli and zstd content codings; off unless the build opted in (configure,
|
||||
// or the Visual Studio projects, which link the vcpkg libraries)
|
||||
#ifndef HTS_USEBROTLI
|
||||
#define HTS_USEBROTLI 0
|
||||
#endif
|
||||
#ifndef HTS_USEZSTD
|
||||
#define HTS_USEZSTD 0
|
||||
#endif
|
||||
|
||||
#ifndef HTS_INET6
|
||||
#define HTS_INET6 0
|
||||
#endif
|
||||
@@ -313,16 +322,15 @@ typedef int64_t TStamp;
|
||||
/* Full printf conversion, '%' included (PRId64 has none): "X: " LLintP. */
|
||||
#define LLintP "%" PRId64
|
||||
|
||||
/* Integer type for file offsets/sizes passed to the C library. Widens to
|
||||
LLint (with HTS_FSEEKO for fseeko/ftello) under large-file support, plain
|
||||
int otherwise; INTsysP is its printf conversion. */
|
||||
#ifdef LFS_FLAG
|
||||
/* Integer type for file offsets/sizes passed to the C library; INTsysP is its
|
||||
printf conversion. FIXME: LFS_FLAG is a configure make variable, never a C
|
||||
macro, so this test is dead and INTsys stays int on POSIX despite large-file
|
||||
support (the real macro is HTS_LFS). Widening it there is an installed-header
|
||||
type change, so it is left alone here. */
|
||||
#if defined(LFS_FLAG) || defined(_MSC_VER)
|
||||
typedef LLint INTsys;
|
||||
|
||||
#define INTsysP LLintP
|
||||
#ifdef __linux
|
||||
#define HTS_FSEEKO
|
||||
#endif
|
||||
#else
|
||||
typedef int INTsys;
|
||||
|
||||
|
||||
@@ -477,7 +477,7 @@ void help(const char *app, int more) {
|
||||
(" Y mirror ALL links located in the first level pages (mirror links)");
|
||||
infomsg("");
|
||||
infomsg("Proxy options:");
|
||||
infomsg(" P proxy use (-P proxy:port or -P user:pass@proxy:port)");
|
||||
infomsg(" P proxy use (-P [socks5://|connect://][user:pass@]proxy:port)");
|
||||
infomsg(" %f *use proxy for ftp (f0 don't use)");
|
||||
infomsg(" %b use this local hostname to make/send requests (-%b hostname)");
|
||||
infomsg("");
|
||||
|
||||
@@ -318,7 +318,7 @@ void index_finish(const char *indexpath, int mode) {
|
||||
char catbuff[CATBUFF_SIZE];
|
||||
char **tab;
|
||||
char *blk;
|
||||
off_t size = fpsize(fp_tmpproject);
|
||||
LLint size = fpsize(fp_tmpproject);
|
||||
|
||||
if (size > 0) {
|
||||
if (fp_tmpproject) {
|
||||
|
||||
317
src/htslib.c
317
src/htslib.c
@@ -48,6 +48,7 @@ Please visit our Website: http://www.httrack.com
|
||||
#include "htsmodules.h"
|
||||
#include "htscharset.h"
|
||||
#include "htsencoding.h"
|
||||
#include "htscodec.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <direct.h>
|
||||
@@ -648,165 +649,6 @@ T_SOC http_fopen(httrackp * opt, const char *adr, const char *fil, htsblk * reto
|
||||
return http_xfopen(opt, 0, 1, 1, NULL, adr, fil, retour);
|
||||
}
|
||||
|
||||
// Read a CRLF line from a non-blocking socket (waits up to timeout per recv).
|
||||
// Returns the line length (0 = empty), or -1 on timeout/EOF/error.
|
||||
static int proxy_getline(T_SOC soc, char *s, int max, int timeout) {
|
||||
int j = 0;
|
||||
|
||||
for (;;) {
|
||||
unsigned char ch;
|
||||
int n;
|
||||
|
||||
if (!check_readinput_t(soc, timeout))
|
||||
return -1; // timed out waiting for data
|
||||
n = (int) recv(soc, &ch, 1, 0);
|
||||
if (n == 1) {
|
||||
if (ch == 13) // CR
|
||||
continue;
|
||||
if (ch == 10) // LF: end of line
|
||||
break;
|
||||
if (j >= max - 1)
|
||||
return -1; // line too long: bound the read against a hostile proxy
|
||||
s[j++] = (char) ch;
|
||||
} else if (n == 0) {
|
||||
return -1; // connection closed
|
||||
} else {
|
||||
#ifdef _WIN32
|
||||
if (WSAGetLastError() == WSAEWOULDBLOCK)
|
||||
continue;
|
||||
#else
|
||||
if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)
|
||||
continue;
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
s[j] = '\0';
|
||||
return j;
|
||||
}
|
||||
|
||||
int http_proxy_tunnel(httrackp *opt, htsblk *retour, const char *adr,
|
||||
int timeout) {
|
||||
const T_SOC soc = retour->soc;
|
||||
const char *const host = jump_identification_const(adr); // host[:port]
|
||||
const char *const portsep = jump_toport_const(adr); // ":port" or NULL
|
||||
char BIGSTK authority[HTS_URLMAXSIZE * 2];
|
||||
char BIGSTK req[HTS_URLMAXSIZE * 4 + 1100];
|
||||
char line[1024];
|
||||
int code;
|
||||
|
||||
if (soc == INVALID_SOCKET)
|
||||
return 0;
|
||||
|
||||
// CONNECT needs an explicit host:port; default the https port
|
||||
authority[0] = '\0';
|
||||
if (portsep != NULL)
|
||||
strlcatbuff(authority, host, sizeof(authority)); // already host:port
|
||||
else
|
||||
snprintf(authority, sizeof(authority), "%s:%d", host, 443);
|
||||
|
||||
// backstop: never let a stray CR/LF in the host smuggle a second line into
|
||||
// the CONNECT request (the host is already sanitized upstream)
|
||||
{
|
||||
const char *c;
|
||||
|
||||
for (c = authority; *c != '\0'; c++) {
|
||||
if ((unsigned char) *c < ' ') {
|
||||
strcpybuff(retour->msg, "proxy CONNECT: invalid host");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
snprintf(req, sizeof(req), "CONNECT %s HTTP/1.0" H_CRLF "Host: %s" H_CRLF,
|
||||
authority, authority);
|
||||
|
||||
// creds go on the CONNECT, not the tunneled origin request
|
||||
if (link_has_authorization(retour->req.proxy.name)) {
|
||||
const char *a = jump_identification_const(retour->req.proxy.name);
|
||||
const char *astart = jump_protocol_const(retour->req.proxy.name);
|
||||
char autorisation[1100];
|
||||
char user_pass[256];
|
||||
|
||||
autorisation[0] = user_pass[0] = '\0';
|
||||
strncatbuff(user_pass, astart, (int) (a - astart) - 1);
|
||||
strcpybuff(user_pass, unescape_http(OPT_GET_BUFF(opt),
|
||||
OPT_GET_BUFF_SIZE(opt), user_pass));
|
||||
code64((unsigned char *) user_pass, (int) strlen(user_pass),
|
||||
(unsigned char *) autorisation, 0);
|
||||
strlcatbuff(req, "Proxy-Authorization: Basic ", sizeof(req));
|
||||
strlcatbuff(req, autorisation, sizeof(req));
|
||||
strlcatbuff(req, H_CRLF, sizeof(req));
|
||||
}
|
||||
strlcatbuff(req, H_CRLF, sizeof(req)); // end of request headers
|
||||
|
||||
// raw send: ssl is set, so sendc() would route to TLS
|
||||
{
|
||||
const char *p = req;
|
||||
size_t remain = strlen(req);
|
||||
int stalls = 0;
|
||||
|
||||
while (remain > 0) {
|
||||
const int n = (int) send(soc, p, (int) remain, 0);
|
||||
|
||||
if (n > 0) {
|
||||
p += n;
|
||||
remain -= (size_t) n;
|
||||
stalls = 0;
|
||||
} else {
|
||||
#ifdef _WIN32
|
||||
const int wouldblock = (WSAGetLastError() == WSAEWOULDBLOCK);
|
||||
#else
|
||||
const int wouldblock =
|
||||
(errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR);
|
||||
#endif
|
||||
// don't spin forever on a fatal error or an unwritable socket
|
||||
if (!wouldblock || !check_writeinput_t(soc, timeout) ||
|
||||
++stalls > 100) {
|
||||
strcpybuff(retour->msg, "proxy CONNECT: write error");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// proxy status line: "HTTP/1.x <code> ..."
|
||||
if (proxy_getline(soc, line, sizeof(line), timeout) < 0) {
|
||||
strcpybuff(retour->msg, "proxy CONNECT: no response");
|
||||
return 0;
|
||||
}
|
||||
if (sscanf(line, "HTTP/%*d.%*d %d", &code) < 1)
|
||||
code = 0;
|
||||
if (code < 200 || code >= 300) {
|
||||
snprintf(retour->msg, sizeof(retour->msg), "proxy CONNECT refused: %s",
|
||||
strnotempty(line) ? line : "(no status)");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// drain headers to the blank line; cap the count so a flooding proxy can't
|
||||
// stall the crawl
|
||||
{
|
||||
int headers = 0;
|
||||
|
||||
for (;;) {
|
||||
const int n = proxy_getline(soc, line, sizeof(line), timeout);
|
||||
|
||||
if (n < 0) {
|
||||
strcpybuff(retour->msg, "proxy CONNECT: truncated response");
|
||||
return 0;
|
||||
}
|
||||
if (n == 0)
|
||||
break; // blank line: tunnel ready
|
||||
if (++headers > 64) {
|
||||
strcpybuff(retour->msg, "proxy CONNECT: too many response headers");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ouverture d'une liaison http, envoi d'une requète
|
||||
// mode: 0 GET 1 HEAD [2 POST]
|
||||
// treat: traiter header?
|
||||
@@ -1105,8 +947,10 @@ int http_sendhead(httrackp * opt, t_cookie * cookie, int mode,
|
||||
/* widths bound method[256], url[HTS_URLMAXSIZE*2], protocol[256] */
|
||||
if (sscanf(line, "%255s %2047s %255s", method, url, protocol) == 3) {
|
||||
size_t ret;
|
||||
// selon que l'on a ou pas un proxy
|
||||
if (retour->req.proxy.active) {
|
||||
// http proxy: absolute-URI; socks/CONNECT tunnel: origin-form
|
||||
if (retour->req.proxy.active &&
|
||||
!hts_proxy_is_socks(retour->req.proxy.name) &&
|
||||
!hts_proxy_is_connect(retour->req.proxy.name)) {
|
||||
print_buffer(&bstr,
|
||||
"%s http://%s%s %s\r\n", method, adr, url,
|
||||
protocol);
|
||||
@@ -1142,8 +986,11 @@ int http_sendhead(httrackp * opt, t_cookie * cookie, int mode,
|
||||
print_buffer(&bstr, "HEAD ");
|
||||
}
|
||||
|
||||
// si on gère un proxy, il faut une Absolute URI: on ajoute avant http://www.adr.dom
|
||||
if (retour->req.proxy.active && (strncmp(adr, "https://", 8) != 0)) {
|
||||
// an http proxy needs an absolute URI; a socks or CONNECT tunnel does not
|
||||
if (retour->req.proxy.active &&
|
||||
!hts_proxy_is_socks(retour->req.proxy.name) &&
|
||||
!hts_proxy_is_connect(retour->req.proxy.name) &&
|
||||
(strncmp(adr, "https://", 8) != 0)) {
|
||||
if (!link_has_authority(adr)) { // default http
|
||||
#if HDEBUG
|
||||
printf("Proxy Use: for %s%s proxy %d port %d\n", adr, fil,
|
||||
@@ -1187,8 +1034,11 @@ int http_sendhead(httrackp * opt, t_cookie * cookie, int mode,
|
||||
if (xsend)
|
||||
print_buffer(&bstr, "%s", xsend); // éventuelles autres lignes
|
||||
|
||||
// for https, auth rides the CONNECT (the tunneled GET would leak it)
|
||||
if (retour->req.proxy.active && strncmp(adr, "https://", 8) != 0) {
|
||||
// https/connect://: auth rides the CONNECT; socks: the handshake
|
||||
if (retour->req.proxy.active &&
|
||||
!hts_proxy_is_socks(retour->req.proxy.name) &&
|
||||
!hts_proxy_is_connect(retour->req.proxy.name) &&
|
||||
strncmp(adr, "https://", 8) != 0) {
|
||||
if (link_has_authorization(retour->req.proxy.name)) { // et hop, authentification proxy!
|
||||
const char *a = jump_identification_const(retour->req.proxy.name);
|
||||
const char *astart = jump_protocol_const(retour->req.proxy.name);
|
||||
@@ -1279,11 +1129,16 @@ int http_sendhead(httrackp * opt, t_cookie * cookie, int mode,
|
||||
// Compression accepted ?
|
||||
if (retour->req.http11) {
|
||||
hts_boolean compressible = HTS_FALSE;
|
||||
hts_boolean secure = HTS_FALSE;
|
||||
|
||||
#if HTS_USEZLIB
|
||||
compressible = (!retour->req.range_used && !retour->req.nocompression);
|
||||
#endif
|
||||
#if HTS_USEOPENSSL
|
||||
secure = retour->ssl ? HTS_TRUE : HTS_FALSE;
|
||||
#endif
|
||||
print_buffer(&bstr, "Accept-Encoding: %s" H_CRLF,
|
||||
hts_acceptencoding(compressible));
|
||||
hts_acceptencoding(compressible, secure));
|
||||
}
|
||||
|
||||
/* Authentification */
|
||||
@@ -1668,22 +1523,10 @@ void treathead(t_cookie * cookie, const char *adr, const char *fil, htsblk * ret
|
||||
strcpybuff(retour->contentencoding, tempo);
|
||||
else
|
||||
retour->contentencoding[0] = '\0';
|
||||
#if HTS_USEZLIB
|
||||
/* Check known encodings */
|
||||
if (retour->contentencoding[0]) {
|
||||
if ((strfield2(retour->contentencoding, "gzip"))
|
||||
|| (strfield2(retour->contentencoding, "x-gzip"))
|
||||
/*
|
||||
|| (strfield2(retour->contentencoding, "compress"))
|
||||
|| (strfield2(retour->contentencoding, "x-compress"))
|
||||
*/
|
||||
|| (strfield2(retour->contentencoding, "deflate"))
|
||||
|| (strfield2(retour->contentencoding, "x-deflate"))
|
||||
) {
|
||||
retour->compressed = 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* A coding to undo (or one we can not undo, which must fail the fetch
|
||||
rather than save the coded bytes as the page) */
|
||||
if (hts_codec_parse(retour->contentencoding) != HTS_CODEC_IDENTITY)
|
||||
retour->compressed = 1;
|
||||
}
|
||||
} else if ((p = strfield(rcvd, "Location:")) != 0) {
|
||||
if (retour) {
|
||||
@@ -3872,6 +3715,12 @@ const char *jump_protocol_const(const char *source) {
|
||||
source += p;
|
||||
else if ((p = strfield(source, "file:")))
|
||||
source += p;
|
||||
else if ((p = strfield(source, "socks5h:")))
|
||||
source += p;
|
||||
else if ((p = strfield(source, "socks5:")))
|
||||
source += p;
|
||||
else if ((p = strfield(source, "connect:")))
|
||||
source += p;
|
||||
// net_path
|
||||
if (strncmp(source, "//", 2) == 0)
|
||||
source += 2;
|
||||
@@ -3880,6 +3729,54 @@ const char *jump_protocol_const(const char *source) {
|
||||
|
||||
DECLARE_NON_CONST_VERSION(jump_protocol)
|
||||
|
||||
hts_boolean hts_proxy_is_socks(const char *name) {
|
||||
if (name == NULL)
|
||||
return HTS_FALSE;
|
||||
return (strfield(name, "socks5h:") || strfield(name, "socks5:")) ? HTS_TRUE
|
||||
: HTS_FALSE;
|
||||
}
|
||||
|
||||
hts_boolean hts_proxy_is_connect(const char *name) {
|
||||
if (name == NULL)
|
||||
return HTS_FALSE;
|
||||
return strfield(name, "connect:") ? HTS_TRUE : HTS_FALSE;
|
||||
}
|
||||
|
||||
// default proxy port for a -P argument, keyed on the scheme
|
||||
static int proxy_default_port(const char *arg) {
|
||||
return hts_proxy_is_socks(arg) ? 1080 : 8080;
|
||||
}
|
||||
|
||||
void hts_parse_proxy(const char *arg, char *name, size_t name_size, int *port) {
|
||||
const char *authority = strstr(arg, "://");
|
||||
const char *a;
|
||||
size_t namelen;
|
||||
|
||||
if (name_size == 0)
|
||||
return;
|
||||
// scan back to the port ':' (or userinfo '@'), but never past the authority,
|
||||
// so a scheme's own colon is not read as a port separator; inspect a[-1] from
|
||||
// one-past-end so no pointer below the string is ever formed
|
||||
authority = (authority != NULL) ? authority + 3 : arg;
|
||||
a = arg + strlen(arg);
|
||||
while (a > authority && a[-1] != ':' && a[-1] != '@')
|
||||
a--;
|
||||
if (a > authority && a[-1] == ':') {
|
||||
int p = -1;
|
||||
|
||||
sscanf(a, "%d", &p);
|
||||
*port = (p > 0) ? p : proxy_default_port(arg);
|
||||
namelen = (size_t) (a - 1 - arg);
|
||||
} else {
|
||||
*port = proxy_default_port(arg);
|
||||
namelen = strlen(arg);
|
||||
}
|
||||
if (namelen >= name_size) // arg is user-controlled: truncate, don't overflow
|
||||
namelen = name_size - 1;
|
||||
memcpy(name, arg, namelen);
|
||||
name[namelen] = '\0';
|
||||
}
|
||||
|
||||
// codage base 64 a vers b
|
||||
void code64(unsigned char *a, int size_a, unsigned char *b, int crlf) {
|
||||
int i1 = 0, i2 = 0, i3 = 0, i4 = 0;
|
||||
@@ -4365,11 +4262,6 @@ HTSEXT_API void get_httptype(httrackp *opt, char *s, const char *fil,
|
||||
(void) get_httptype_sized(opt, s, HTS_MIMETYPE_SIZE, fil, flag);
|
||||
}
|
||||
|
||||
/* Advertised Accept-Encoding; gzip and deflate both decode via hts_zunpack */
|
||||
const char *hts_acceptencoding(hts_boolean compressible) {
|
||||
return compressible ? "gzip, deflate, identity;q=0.9" : "identity";
|
||||
}
|
||||
|
||||
// get type of fil (php)
|
||||
// s: buffer (text/html) or NULL
|
||||
// return: 1 if known by user
|
||||
@@ -4709,26 +4601,31 @@ int fexist_utf8(const char *s) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Taille d'un fichier, -1 si n'existe pas */
|
||||
/* File size, -1 if absent */
|
||||
/* Note: NOT utf-8 */
|
||||
off_t fsize(const char *s) {
|
||||
struct stat st;
|
||||
LLint fsize(const char *s) {
|
||||
STRUCT_STAT st;
|
||||
|
||||
if (!strnotempty(s)) // nom vide: erreur
|
||||
if (!strnotempty(s)) // empty name: error
|
||||
return -1;
|
||||
/* _stat64, not stat(): the latter is 32-bit on MSVC */
|
||||
#ifdef _WIN32
|
||||
if (_stat64(s, &st) == 0 && S_ISREG(st.st_mode)) {
|
||||
#else
|
||||
if (stat(s, &st) == 0 && S_ISREG(st.st_mode)) {
|
||||
#endif
|
||||
return st.st_size;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Taille d'un fichier, -1 si n'existe pas */
|
||||
/* File size, -1 if absent */
|
||||
/* Note: utf-8 */
|
||||
off_t fsize_utf8(const char *s) {
|
||||
LLint fsize_utf8(const char *s) {
|
||||
STRUCT_STAT st;
|
||||
|
||||
if (!strnotempty(s)) // nom vide: erreur
|
||||
if (!strnotempty(s)) // empty name: error
|
||||
return -1;
|
||||
if (STAT(s, &st) == 0 && S_ISREG(st.st_mode)) {
|
||||
return st.st_size;
|
||||
@@ -4737,24 +4634,17 @@ off_t fsize_utf8(const char *s) {
|
||||
}
|
||||
}
|
||||
|
||||
off_t fpsize(FILE * fp) {
|
||||
off_t oldpos, size;
|
||||
/* fseeko/ftello, never fseek/ftell: ftell returns long, which cannot carry an
|
||||
offset past 2GB on a 32-bit platform and fails with EOVERFLOW there. */
|
||||
LLint fpsize(FILE *fp) {
|
||||
LLint oldpos, size;
|
||||
|
||||
if (!fp)
|
||||
return -1;
|
||||
#ifdef HTS_FSEEKO
|
||||
oldpos = ftello(fp);
|
||||
#else
|
||||
oldpos = ftell(fp);
|
||||
#endif
|
||||
fseek(fp, 0, SEEK_END);
|
||||
#ifdef HTS_FSEEKO
|
||||
fseeko(fp, 0, SEEK_END);
|
||||
size = ftello(fp);
|
||||
fseeko(fp, oldpos, SEEK_SET);
|
||||
#else
|
||||
size = ftell(fp);
|
||||
fseek(fp, oldpos, SEEK_SET);
|
||||
#endif
|
||||
return size;
|
||||
}
|
||||
|
||||
@@ -5018,7 +4908,7 @@ static struct addrinfo *resolver_make_ai(const char *ip, int want_family) {
|
||||
return ai;
|
||||
}
|
||||
|
||||
static void override_freeaddrinfo(struct addrinfo *res) {
|
||||
static void HTS_RESOLVER_CALL override_freeaddrinfo(struct addrinfo *res) {
|
||||
while (res != NULL) {
|
||||
struct addrinfo *const next = res->ai_next;
|
||||
|
||||
@@ -5028,9 +4918,10 @@ static void override_freeaddrinfo(struct addrinfo *res) {
|
||||
}
|
||||
}
|
||||
|
||||
static int override_getaddrinfo(const char *node, const char *service,
|
||||
const struct addrinfo *hints,
|
||||
struct addrinfo **res) {
|
||||
static int HTS_RESOLVER_CALL override_getaddrinfo(const char *node,
|
||||
const char *service,
|
||||
const struct addrinfo *hints,
|
||||
struct addrinfo **res) {
|
||||
const char *const spec = getenv("HTTRACK_DEBUG_RESOLVE");
|
||||
const int want = (hints != NULL) ? hints->ai_family : PF_UNSPEC;
|
||||
const char *colon;
|
||||
@@ -6149,6 +6040,8 @@ HTSEXT_API void hts_free_opt(httrackp * opt) {
|
||||
StringFree(opt->referer);
|
||||
StringFree(opt->from);
|
||||
StringFree(opt->lang_iso);
|
||||
StringFree(opt->accept);
|
||||
StringFree(opt->headers);
|
||||
StringFree(opt->sys_com);
|
||||
StringFree(opt->mimedefs);
|
||||
StringFree(opt->filelist);
|
||||
@@ -6517,13 +6410,13 @@ int hts_stat_utf8(const char *path, STRUCT_STAT * buf) {
|
||||
LPWSTR wpath = hts_convertUTF8StringToUCS2(path, (int) strlen(path), NULL);
|
||||
|
||||
if (wpath != NULL) {
|
||||
const int result = _wstat(wpath, buf);
|
||||
const int result = _wstat64(wpath, buf);
|
||||
|
||||
free(wpath);
|
||||
return result;
|
||||
} else {
|
||||
// Fallback on conversion error.
|
||||
return _stat(path, buf);
|
||||
return _stat64(path, buf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
48
src/htslib.h
48
src/htslib.h
@@ -207,15 +207,12 @@ int check_readinput(htsblk * r);
|
||||
int check_readinput_t(T_SOC soc, int timeout);
|
||||
int check_writeinput_t(T_SOC soc, int timeout);
|
||||
|
||||
/* Open an HTTP CONNECT tunnel through the active proxy for an https request:
|
||||
`retour->soc` must already be TCP-connected to the proxy, and `adr` is the
|
||||
origin authority (url_adr, e.g. "https://host:port"). Sends the CONNECT
|
||||
request (with Proxy-Authorization when the proxy carries credentials) and
|
||||
reads the proxy's status line, so the caller's TLS handshake then runs
|
||||
end-to-end with the origin. Blocks up to `timeout` seconds. Returns 1 on a
|
||||
2xx tunnel, 0 on failure (retour->msg/statuscode set). */
|
||||
int http_proxy_tunnel(httrackp *opt, htsblk *retour, const char *adr,
|
||||
int timeout);
|
||||
/* TRUE if this -P proxy name (which keeps its scheme) is a SOCKS5 proxy. */
|
||||
hts_boolean hts_proxy_is_socks(const char *name);
|
||||
|
||||
/* TRUE if this -P proxy name is a "connect://" CONNECT-only proxy (#564). */
|
||||
hts_boolean hts_proxy_is_connect(const char *name);
|
||||
|
||||
void treathead(t_cookie * cookie, const char *adr, const char *fil, htsblk * retour,
|
||||
char *rcvd);
|
||||
void treatfirstline(htsblk * retour, const char *rcvd);
|
||||
@@ -283,15 +280,18 @@ int ishttperror(int err);
|
||||
int get_userhttptype(httrackp * opt, char *s, const char *fil);
|
||||
int give_mimext(char *s, size_t ssize, const char *st);
|
||||
|
||||
/* Advertised Accept-Encoding value (no header name/CRLF); see htslib.c. */
|
||||
const char *hts_acceptencoding(hts_boolean compressible);
|
||||
|
||||
int may_bogus_multiple(httrackp * opt, const char *mime, const char *filename);
|
||||
int may_unknown2(httrackp * opt, const char *mime, const char *filename);
|
||||
|
||||
const char *strrchr_limit(const char *s, char c, const char *limit);
|
||||
char *jump_protocol(char *source);
|
||||
const char *jump_protocol_const(const char *source);
|
||||
|
||||
/* Split a -P proxy argument "[scheme://][user:pass@]host[:port]" into the proxy
|
||||
host string (scheme and any user:pass kept, for later stripping and auth),
|
||||
written NUL-terminated into name[name_size] (truncated to fit), and the port
|
||||
in *port. The port defaults by scheme: 1080 for socks5/socks5h, else 8080. */
|
||||
void hts_parse_proxy(const char *arg, char *name, size_t name_size, int *port);
|
||||
void code64(unsigned char *a, int size_a, unsigned char *b, int crlf);
|
||||
|
||||
#define copychar(catbuff,a) concat(catbuff,(a),NULL)
|
||||
@@ -313,10 +313,11 @@ void cut_path(char *fullpath, char *path, size_t path_size, char *pname,
|
||||
int fexist(const char *s);
|
||||
int fexist_utf8(const char *s);
|
||||
|
||||
/*LLint fsize(const char* s); */
|
||||
off_t fpsize(FILE * fp);
|
||||
off_t fsize(const char *s);
|
||||
off_t fsize_utf8(const char *s);
|
||||
/* File size in bytes, -1 if absent or not a regular file. LLint, not off_t:
|
||||
the latter is a 32-bit long on MSVC, truncating any file of 2GB or more. */
|
||||
LLint fpsize(FILE *fp);
|
||||
LLint fsize(const char *s);
|
||||
LLint fsize_utf8(const char *s);
|
||||
|
||||
// Threads
|
||||
typedef void *(*beginthread_type) (void *);
|
||||
@@ -396,7 +397,8 @@ void *hts_get_callback(t_hts_htmlcheck_callbacks * callbacks,
|
||||
HTSEXT_API FILE *hts_fopen_utf8(const char *path, const char *mode);
|
||||
|
||||
#define STAT hts_stat_utf8
|
||||
typedef struct _stat STRUCT_STAT;
|
||||
/* _stat64: _stat's st_size is a 32-bit long, even in x64 builds */
|
||||
typedef struct _stat64 STRUCT_STAT;
|
||||
HTSEXT_API int hts_stat_utf8(const char *path, STRUCT_STAT * buf);
|
||||
|
||||
#define UNLINK hts_unlink_utf8
|
||||
@@ -493,6 +495,14 @@ HTS_STATIC int strcmpnocase(const char *a, const char *b) {
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
/* MSVC ships these POSIX functions under other names. Kept out of the installed
|
||||
headers: they would rewrite the same identifiers in a consumer's own code. */
|
||||
#ifdef _MSC_VER
|
||||
#define fseeko _fseeki64
|
||||
#define ftello _ftelli64
|
||||
#define timegm _mkgmtime
|
||||
#endif
|
||||
|
||||
#define strfield2(f,s) ( (strlen(f)!=strlen(s)) ? 0 : (strfield(f,s)) )
|
||||
|
||||
// is this MIME an hypertext MIME (text/html), html/js-style or other script/text type?
|
||||
@@ -586,9 +596,9 @@ HTS_STATIC int compare_mime(httrackp * opt, const char *mime, const char *file,
|
||||
#endif
|
||||
|
||||
// returns (size_t) -1 upon error
|
||||
static HTS_UNUSED size_t off_t_to_size_t(off_t o) {
|
||||
static HTS_UNUSED size_t llint_to_size_t(LLint o) {
|
||||
const size_t so = (size_t) o;
|
||||
if ((off_t) so == o) {
|
||||
if ((LLint) so == o) {
|
||||
return so;
|
||||
} else {
|
||||
return (size_t) -1;
|
||||
|
||||
@@ -42,6 +42,7 @@ Please visit our Website: http://www.httrack.com
|
||||
#include "htscharset.h"
|
||||
#include "htsencoding.h"
|
||||
#include "htssniff.h"
|
||||
#include "htscodec.h"
|
||||
#if HTS_USEZLIB
|
||||
#include "htszlib.h"
|
||||
#endif
|
||||
@@ -151,29 +152,6 @@ typedef struct sniff_src {
|
||||
const char *prev_save; /* previous run's save name (cache X-Save) */
|
||||
} sniff_src;
|
||||
|
||||
#if HTS_USEZLIB
|
||||
/* Inflate the head of a gzip/zlib stream; 0 when undecodable. */
|
||||
static size_t sniff_inflate_head(const void *in, size_t in_len, void *out,
|
||||
size_t out_len) {
|
||||
z_stream zs;
|
||||
size_t n = 0;
|
||||
int err;
|
||||
|
||||
memset(&zs, 0, sizeof(zs));
|
||||
if (inflateInit2(&zs, 47) != Z_OK) /* 47: gzip or zlib, autodetected */
|
||||
return 0;
|
||||
zs.next_in = (const Bytef *) in;
|
||||
zs.avail_in = (uInt) in_len;
|
||||
zs.next_out = (Bytef *) out;
|
||||
zs.avail_out = (uInt) out_len;
|
||||
err = inflate(&zs, Z_SYNC_FLUSH);
|
||||
if (err == Z_OK || err == Z_STREAM_END || err == Z_BUF_ERROR)
|
||||
n = out_len - zs.avail_out;
|
||||
inflateEnd(&zs);
|
||||
return n;
|
||||
}
|
||||
#endif
|
||||
|
||||
static size_t sniff_read_head(const char *path, void *buf, size_t len) {
|
||||
char catbuff[CATBUFF_SIZE];
|
||||
FILE *const fp = FOPEN(fconv(catbuff, sizeof(catbuff), path), "rb");
|
||||
@@ -205,16 +183,12 @@ static size_t sniff_slot_head(const lien_back *slot, void *buf, size_t len) {
|
||||
n = sniff_read_head(slot->tmpfile, buf, len);
|
||||
}
|
||||
if (n > 0 && r->compressed) {
|
||||
#if HTS_USEZLIB
|
||||
unsigned char raw[HTS_SNIFF_LEN];
|
||||
|
||||
if (n > sizeof(raw))
|
||||
n = sizeof(raw);
|
||||
memcpy(raw, buf, n);
|
||||
n = sniff_inflate_head(raw, n, buf, len);
|
||||
#else
|
||||
n = 0;
|
||||
#endif
|
||||
n = hts_codec_head(hts_codec_parse(r->contentencoding), raw, n, buf, len);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
15
src/htsnet.h
15
src/htsnet.h
@@ -309,10 +309,19 @@ typedef socklen_t SOClen;
|
||||
self-test can script DNS answers (families, multiplicity, errors)
|
||||
in-process. The free function must match its getaddrinfo (a fake allocates
|
||||
its own chain), hence the pair. */
|
||||
/* Winsock's resolver is __stdcall; a plain pointer only compiles on x64, where
|
||||
there is one convention. Backend implementations must carry this too. */
|
||||
#ifdef _WIN32
|
||||
#define HTS_RESOLVER_CALL WSAAPI
|
||||
#else
|
||||
#define HTS_RESOLVER_CALL
|
||||
#endif
|
||||
|
||||
typedef struct hts_resolver_backend {
|
||||
int (*getaddrinfo)(const char *node, const char *service,
|
||||
const struct addrinfo *hints, struct addrinfo **res);
|
||||
void (*freeaddrinfo)(struct addrinfo *res);
|
||||
int(HTS_RESOLVER_CALL *getaddrinfo)(const char *node, const char *service,
|
||||
const struct addrinfo *hints,
|
||||
struct addrinfo **res);
|
||||
void(HTS_RESOLVER_CALL *freeaddrinfo)(struct addrinfo *res);
|
||||
} hts_resolver_backend;
|
||||
|
||||
/** Install a resolver backend for the process; NULL restores the libc default.
|
||||
|
||||
@@ -328,8 +328,8 @@ typedef enum hts_wizard {
|
||||
|
||||
typedef enum hts_robots {
|
||||
HTS_ROBOTS_NEVER = 0, /**< ignore robots rules */
|
||||
HTS_ROBOTS_SOMETIMES = 1, /**< partial obedience (default) */
|
||||
HTS_ROBOTS_ALWAYS = 2, /**< obey robots rules */
|
||||
HTS_ROBOTS_SOMETIMES = 1, /**< partial obedience, set by -s */
|
||||
HTS_ROBOTS_ALWAYS = 2, /**< obey robots rules (default) */
|
||||
HTS_ROBOTS_ALWAYS_STRICT = 3 /**< obey even strict rules */
|
||||
} hts_robots;
|
||||
#endif
|
||||
|
||||
542
src/htsproxy.c
Normal file
542
src/htsproxy.c
Normal file
@@ -0,0 +1,542 @@
|
||||
/* ------------------------------------------------------------ */
|
||||
/*
|
||||
HTTrack Website Copier, Offline Browser for Windows and Unix
|
||||
Copyright (C) 2026 Xavier Roche and other contributors
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Ethical use: we kindly ask that you NOT use this software to harvest email
|
||||
addresses or to collect any other private information about people. Doing so
|
||||
would dishonor our work and waste the many hours we have spent on it.
|
||||
|
||||
Please visit our Website: http://www.httrack.com
|
||||
*/
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/* File: Proxy tunneling (HTTP CONNECT, SOCKS5) */
|
||||
/* Author: Xavier Roche */
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
/* Internal engine bytecode */
|
||||
#define HTS_INTERNAL_BYTECODE
|
||||
|
||||
#include "htscore.h"
|
||||
|
||||
#include "htslib.h"
|
||||
#include "htsproxy.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
// Read a CRLF line from a non-blocking socket (waits up to timeout per recv).
|
||||
// Returns the line length (0 = empty), or -1 on timeout/EOF/error.
|
||||
static int proxy_getline(T_SOC soc, char *s, int max, int timeout) {
|
||||
int j = 0;
|
||||
|
||||
for (;;) {
|
||||
unsigned char ch;
|
||||
int n;
|
||||
|
||||
if (!check_readinput_t(soc, timeout))
|
||||
return -1; // timed out waiting for data
|
||||
n = (int) recv(soc, &ch, 1, 0);
|
||||
if (n == 1) {
|
||||
if (ch == 13) // CR
|
||||
continue;
|
||||
if (ch == 10) // LF: end of line
|
||||
break;
|
||||
if (j >= max - 1)
|
||||
return -1; // line too long: bound the read against a hostile proxy
|
||||
s[j++] = (char) ch;
|
||||
} else if (n == 0) {
|
||||
return -1; // connection closed
|
||||
} else {
|
||||
#ifdef _WIN32
|
||||
if (WSAGetLastError() == WSAEWOULDBLOCK)
|
||||
continue;
|
||||
#else
|
||||
if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)
|
||||
continue;
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
s[j] = '\0';
|
||||
return j;
|
||||
}
|
||||
|
||||
int http_proxy_tunnel(httrackp *opt, htsblk *retour, const char *adr,
|
||||
int timeout) {
|
||||
const T_SOC soc = retour->soc;
|
||||
const char *const host = jump_identification_const(adr); // host[:port]
|
||||
const char *const portsep = jump_toport_const(adr); // ":port" or NULL
|
||||
char BIGSTK authority[HTS_URLMAXSIZE * 2];
|
||||
char BIGSTK req[HTS_URLMAXSIZE * 4 + 1100];
|
||||
char line[1024];
|
||||
int code;
|
||||
|
||||
if (soc == INVALID_SOCKET)
|
||||
return 0;
|
||||
|
||||
// CONNECT needs an explicit host:port; default :80 for http, :443 for https
|
||||
authority[0] = '\0';
|
||||
if (portsep != NULL)
|
||||
strlcatbuff(authority, host, sizeof(authority)); // already host:port
|
||||
else {
|
||||
const int defport = (strncmp(adr, "https://", 8) == 0) ? 443 : 80;
|
||||
|
||||
snprintf(authority, sizeof(authority), "%s:%d", host, defport);
|
||||
}
|
||||
|
||||
// backstop: never let a stray CR/LF in the host smuggle a second line into
|
||||
// the CONNECT request (the host is already sanitized upstream)
|
||||
{
|
||||
const char *c;
|
||||
|
||||
for (c = authority; *c != '\0'; c++) {
|
||||
if ((unsigned char) *c < ' ') {
|
||||
strcpybuff(retour->msg, "proxy CONNECT: invalid host");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
snprintf(req, sizeof(req), "CONNECT %s HTTP/1.0" H_CRLF "Host: %s" H_CRLF,
|
||||
authority, authority);
|
||||
|
||||
// creds go on the CONNECT, not the tunneled origin request
|
||||
if (link_has_authorization(retour->req.proxy.name)) {
|
||||
const char *a = jump_identification_const(retour->req.proxy.name);
|
||||
const char *astart = jump_protocol_const(retour->req.proxy.name);
|
||||
char autorisation[1100];
|
||||
char user_pass[256];
|
||||
|
||||
autorisation[0] = user_pass[0] = '\0';
|
||||
strncatbuff(user_pass, astart, (int) (a - astart) - 1);
|
||||
strcpybuff(user_pass, unescape_http(OPT_GET_BUFF(opt),
|
||||
OPT_GET_BUFF_SIZE(opt), user_pass));
|
||||
code64((unsigned char *) user_pass, (int) strlen(user_pass),
|
||||
(unsigned char *) autorisation, 0);
|
||||
strlcatbuff(req, "Proxy-Authorization: Basic ", sizeof(req));
|
||||
strlcatbuff(req, autorisation, sizeof(req));
|
||||
strlcatbuff(req, H_CRLF, sizeof(req));
|
||||
}
|
||||
strlcatbuff(req, H_CRLF, sizeof(req)); // end of request headers
|
||||
|
||||
// raw send(): sendc() would route to TLS when ssl is set (https tunnel)
|
||||
{
|
||||
const char *p = req;
|
||||
size_t remain = strlen(req);
|
||||
int stalls = 0;
|
||||
|
||||
while (remain > 0) {
|
||||
const int n = (int) send(soc, p, (int) remain, 0);
|
||||
|
||||
if (n > 0) {
|
||||
p += n;
|
||||
remain -= (size_t) n;
|
||||
stalls = 0;
|
||||
} else {
|
||||
#ifdef _WIN32
|
||||
const int wouldblock = (WSAGetLastError() == WSAEWOULDBLOCK);
|
||||
#else
|
||||
const int wouldblock =
|
||||
(errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR);
|
||||
#endif
|
||||
// don't spin forever on a fatal error or an unwritable socket
|
||||
if (!wouldblock || !check_writeinput_t(soc, timeout) ||
|
||||
++stalls > 100) {
|
||||
strcpybuff(retour->msg, "proxy CONNECT: write error");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// proxy status line: "HTTP/1.x <code> ..."
|
||||
if (proxy_getline(soc, line, sizeof(line), timeout) < 0) {
|
||||
strcpybuff(retour->msg, "proxy CONNECT: no response");
|
||||
return 0;
|
||||
}
|
||||
if (sscanf(line, "HTTP/%*d.%*d %d", &code) < 1)
|
||||
code = 0;
|
||||
if (code < 200 || code >= 300) {
|
||||
snprintf(retour->msg, sizeof(retour->msg), "proxy CONNECT refused: %s",
|
||||
strnotempty(line) ? line : "(no status)");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// drain headers to the blank line; cap the count so a flooding proxy can't
|
||||
// stall the crawl
|
||||
{
|
||||
int headers = 0;
|
||||
|
||||
for (;;) {
|
||||
const int n = proxy_getline(soc, line, sizeof(line), timeout);
|
||||
|
||||
if (n < 0) {
|
||||
strcpybuff(retour->msg, "proxy CONNECT: truncated response");
|
||||
return 0;
|
||||
}
|
||||
if (n == 0)
|
||||
break; // blank line: tunnel ready
|
||||
if (++headers > 64) {
|
||||
strcpybuff(retour->msg, "proxy CONNECT: too many response headers");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* SOCKS5 client (RFC 1928, RFC 1929 auth), hostname mode only: the proxy
|
||||
resolves the origin name (remote DNS, curl's socks5h). The stream is the
|
||||
proxy socket, or a scripted buffer under -#test=socks5. */
|
||||
|
||||
#define SOCKS5_VERSION 0x05
|
||||
#define SOCKS5_AUTH_VERSION 0x01
|
||||
#define SOCKS5_METHOD_NONE 0x00
|
||||
#define SOCKS5_METHOD_USERPASS 0x02
|
||||
#define SOCKS5_METHOD_NOACCEPTABLE 0xFF
|
||||
#define SOCKS5_CMD_CONNECT 0x01
|
||||
#define SOCKS5_ATYP_IPV4 0x01
|
||||
#define SOCKS5_ATYP_DOMAIN 0x03
|
||||
#define SOCKS5_ATYP_IPV6 0x04
|
||||
#define SOCKS5_MAXFIELD 255 /* one length byte: host, user and password */
|
||||
|
||||
typedef struct socks5_stream {
|
||||
T_SOC soc; /* INVALID_SOCKET when scripted (self-test) */
|
||||
int timeout;
|
||||
socks5_test_io *io;
|
||||
} socks5_stream;
|
||||
|
||||
static int socks5_fail(char *msg, size_t msgsize, const char *text) {
|
||||
if (msgsize != 0)
|
||||
strlcpybuff(msg, text, msgsize);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Read exactly n bytes, or fail: SOCKS frames are not self-delimiting, so a
|
||||
short read would desync the stream shared with the origin traffic. */
|
||||
static int socks5_read_n(socks5_stream *st, unsigned char *buf, size_t n) {
|
||||
size_t got = 0;
|
||||
int stalls = 0;
|
||||
|
||||
if (st->soc == INVALID_SOCKET) { /* scripted */
|
||||
socks5_test_io *const io = st->io;
|
||||
|
||||
if (n > io->reply_len - io->consumed)
|
||||
return 0;
|
||||
memcpy(buf, io->reply + io->consumed, n);
|
||||
io->consumed += n;
|
||||
return 1;
|
||||
}
|
||||
while (got < n) {
|
||||
const int r = (int) recv(st->soc, (char *) buf + got, (int) (n - got), 0);
|
||||
|
||||
if (r > 0) {
|
||||
got += (size_t) r;
|
||||
stalls = 0;
|
||||
} else if (r == 0) {
|
||||
return 0; // proxy closed mid-frame
|
||||
} else {
|
||||
#ifdef _WIN32
|
||||
const int wouldblock = (WSAGetLastError() == WSAEWOULDBLOCK);
|
||||
#else
|
||||
const int wouldblock =
|
||||
(errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR);
|
||||
#endif
|
||||
if (!wouldblock || !check_readinput_t(st->soc, st->timeout) ||
|
||||
++stalls > 100)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int socks5_write_all(socks5_stream *st, const unsigned char *buf,
|
||||
size_t len) {
|
||||
size_t remain = len;
|
||||
int stalls = 0;
|
||||
|
||||
if (st->soc == INVALID_SOCKET) { /* scripted */
|
||||
socks5_test_io *const io = st->io;
|
||||
|
||||
if (len > sizeof(io->sent) - io->sent_len)
|
||||
return 0;
|
||||
memcpy(io->sent + io->sent_len, buf, len);
|
||||
io->sent_len += len;
|
||||
return 1;
|
||||
}
|
||||
while (remain > 0) {
|
||||
// raw send: the socket is still plain here, sendc() would route to TLS
|
||||
const int n = (int) send(st->soc, (const char *) buf, (int) remain, 0);
|
||||
|
||||
if (n > 0) {
|
||||
buf += n;
|
||||
remain -= (size_t) n;
|
||||
stalls = 0;
|
||||
} else {
|
||||
#ifdef _WIN32
|
||||
const int wouldblock = (WSAGetLastError() == WSAEWOULDBLOCK);
|
||||
#else
|
||||
const int wouldblock =
|
||||
(errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR);
|
||||
#endif
|
||||
if (!wouldblock || !check_writeinput_t(st->soc, st->timeout) ||
|
||||
++stalls > 100)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const char *socks5_rep_message(unsigned char rep) {
|
||||
switch (rep) {
|
||||
case 0x01:
|
||||
return "general failure";
|
||||
case 0x02:
|
||||
return "connection not allowed by ruleset";
|
||||
case 0x03:
|
||||
return "network unreachable";
|
||||
case 0x04:
|
||||
return "host unreachable";
|
||||
case 0x05:
|
||||
return "connection refused";
|
||||
case 0x06:
|
||||
return "TTL expired";
|
||||
case 0x07:
|
||||
return "command not supported";
|
||||
case 0x08:
|
||||
return "address type not supported";
|
||||
default:
|
||||
return "unknown error";
|
||||
}
|
||||
}
|
||||
|
||||
/* The reply's BND.ADDR is variable-length: consume exactly what ATYP says, or
|
||||
the leftover bytes prepend to the first origin (or TLS) read. */
|
||||
static int socks5_read_reply(socks5_stream *st, char *msg, size_t msgsize) {
|
||||
unsigned char head[4];
|
||||
unsigned char addr[SOCKS5_MAXFIELD + 2];
|
||||
size_t addrlen;
|
||||
|
||||
if (!socks5_read_n(st, head, sizeof(head)))
|
||||
return socks5_fail(msg, msgsize, "SOCKS5: no reply from proxy");
|
||||
if (head[0] != SOCKS5_VERSION)
|
||||
return socks5_fail(msg, msgsize, "SOCKS5: bad version in reply");
|
||||
if (head[1] != 0x00) {
|
||||
snprintf(msg, msgsize, "SOCKS5 connect failed: %s",
|
||||
socks5_rep_message(head[1]));
|
||||
return 0;
|
||||
}
|
||||
switch (head[3]) {
|
||||
case SOCKS5_ATYP_IPV4:
|
||||
addrlen = 4;
|
||||
break;
|
||||
case SOCKS5_ATYP_IPV6:
|
||||
addrlen = 16;
|
||||
break;
|
||||
case SOCKS5_ATYP_DOMAIN: {
|
||||
unsigned char len;
|
||||
|
||||
if (!socks5_read_n(st, &len, 1))
|
||||
return socks5_fail(msg, msgsize, "SOCKS5: truncated reply");
|
||||
addrlen = len; // <= 255, always fits addr[]
|
||||
break;
|
||||
}
|
||||
default: // unknown length: the stream cannot be resynchronized
|
||||
return socks5_fail(msg, msgsize, "SOCKS5: unknown address type in reply");
|
||||
}
|
||||
if (addrlen != 0 && !socks5_read_n(st, addr, addrlen))
|
||||
return socks5_fail(msg, msgsize, "SOCKS5: truncated reply address");
|
||||
if (!socks5_read_n(st, addr, 2)) // BND.PORT, unused
|
||||
return socks5_fail(msg, msgsize, "SOCKS5: truncated reply port");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int socks5_negotiate(socks5_stream *st, const char *host, size_t hostlen,
|
||||
int port, const char *user, size_t userlen,
|
||||
const char *pass, size_t passlen, int want_auth,
|
||||
char *msg, size_t msgsize) {
|
||||
unsigned char frame[3 + SOCKS5_MAXFIELD + SOCKS5_MAXFIELD];
|
||||
unsigned char rep[2];
|
||||
|
||||
/* greeting */
|
||||
frame[0] = SOCKS5_VERSION;
|
||||
frame[1] = (unsigned char) (want_auth ? 2 : 1);
|
||||
frame[2] = SOCKS5_METHOD_NONE;
|
||||
frame[3] = SOCKS5_METHOD_USERPASS;
|
||||
if (!socks5_write_all(st, frame, (size_t) 2 + frame[1]))
|
||||
return socks5_fail(msg, msgsize, "SOCKS5: write error");
|
||||
if (!socks5_read_n(st, rep, sizeof(rep)))
|
||||
return socks5_fail(msg, msgsize, "SOCKS5: no method reply from proxy");
|
||||
if (rep[0] != SOCKS5_VERSION)
|
||||
return socks5_fail(msg, msgsize, "SOCKS5: bad version in method reply");
|
||||
switch (rep[1]) {
|
||||
case SOCKS5_METHOD_NONE:
|
||||
break;
|
||||
case SOCKS5_METHOD_USERPASS:
|
||||
if (!want_auth)
|
||||
return socks5_fail(msg, msgsize,
|
||||
"SOCKS5: proxy requires authentication, none given");
|
||||
/* RFC 1929 sub-negotiation; its version byte is 0x01, not 0x05 */
|
||||
frame[0] = SOCKS5_AUTH_VERSION;
|
||||
frame[1] = (unsigned char) userlen;
|
||||
memcpy(frame + 2, user, userlen);
|
||||
frame[2 + userlen] = (unsigned char) passlen;
|
||||
memcpy(frame + 3 + userlen, pass, passlen);
|
||||
if (!socks5_write_all(st, frame, 3 + userlen + passlen))
|
||||
return socks5_fail(msg, msgsize, "SOCKS5: write error");
|
||||
if (!socks5_read_n(st, rep, sizeof(rep)))
|
||||
return socks5_fail(msg, msgsize, "SOCKS5: no authentication reply");
|
||||
if (rep[1] != 0x00)
|
||||
return socks5_fail(msg, msgsize, "SOCKS5: authentication failed");
|
||||
break;
|
||||
case SOCKS5_METHOD_NOACCEPTABLE:
|
||||
return socks5_fail(
|
||||
msg, msgsize,
|
||||
"SOCKS5: proxy accepts no authentication method we offer");
|
||||
default:
|
||||
return socks5_fail(msg, msgsize,
|
||||
"SOCKS5: proxy selected an unknown method");
|
||||
}
|
||||
|
||||
/* CONNECT to the origin, by name */
|
||||
frame[0] = SOCKS5_VERSION;
|
||||
frame[1] = SOCKS5_CMD_CONNECT;
|
||||
frame[2] = 0x00; // RSV
|
||||
frame[3] = SOCKS5_ATYP_DOMAIN;
|
||||
frame[4] = (unsigned char) hostlen;
|
||||
memcpy(frame + 5, host, hostlen);
|
||||
frame[5 + hostlen] = (unsigned char) (port >> 8);
|
||||
frame[6 + hostlen] = (unsigned char) (port & 0xFF);
|
||||
if (!socks5_write_all(st, frame, 7 + hostlen))
|
||||
return socks5_fail(msg, msgsize, "SOCKS5: write error");
|
||||
|
||||
return socks5_read_reply(st, msg, msgsize);
|
||||
}
|
||||
|
||||
/* Decode the proxy userinfo into the two RFC 1929 fields. Split on the first
|
||||
colon of the still-escaped string, so a %3A stays inside the username. */
|
||||
static int socks5_credentials(httrackp *opt, const char *proxy_name, char *user,
|
||||
size_t user_size, size_t *userlen, char *pass,
|
||||
size_t pass_size, size_t *passlen, char *msg,
|
||||
size_t msgsize) {
|
||||
const char *const a = jump_identification_const(proxy_name); // past the '@'
|
||||
const char *const astart = jump_protocol_const(proxy_name);
|
||||
char userinfo[1024];
|
||||
char *colon;
|
||||
|
||||
if (a <= astart || (size_t) (a - astart) - 1 >= sizeof(userinfo))
|
||||
return socks5_fail(msg, msgsize, "SOCKS5: credentials too long");
|
||||
userinfo[0] = '\0';
|
||||
strncatbuff(userinfo, astart, (int) (a - astart) - 1);
|
||||
colon = strchr(userinfo, ':');
|
||||
if (colon != NULL)
|
||||
*colon++ = '\0';
|
||||
strlcpybuff(
|
||||
user, unescape_http(OPT_GET_BUFF(opt), OPT_GET_BUFF_SIZE(opt), userinfo),
|
||||
user_size);
|
||||
strlcpybuff(pass,
|
||||
colon != NULL ? unescape_http(OPT_GET_BUFF(opt),
|
||||
OPT_GET_BUFF_SIZE(opt), colon)
|
||||
: "",
|
||||
pass_size);
|
||||
*userlen = strlen(user);
|
||||
*passlen = strlen(pass);
|
||||
// reject, never truncate: a clipped secret would authenticate as another one
|
||||
if (*userlen > SOCKS5_MAXFIELD || *passlen > SOCKS5_MAXFIELD)
|
||||
return socks5_fail(msg, msgsize, "SOCKS5: credentials too long");
|
||||
if (*userlen == 0)
|
||||
return socks5_fail(msg, msgsize, "SOCKS5: empty proxy username");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int socks5_handshake_stream(httrackp *opt, socks5_stream *st,
|
||||
const char *adr, const char *proxy_name,
|
||||
int ssl, char *msg, size_t msgsize) {
|
||||
const char *const host = jump_identification_const(adr);
|
||||
const char *const portsep = jump_toport_const(adr);
|
||||
const size_t hostlen =
|
||||
portsep != NULL ? (size_t) (portsep - host) : strlen(host);
|
||||
// sized for the whole userinfo: decoding shrinks, so an over-long credential
|
||||
// lands intact and is rejected below rather than silently clipped
|
||||
char user[1024];
|
||||
char pass[1024];
|
||||
size_t userlen = 0, passlen = 0;
|
||||
int want_auth = 0;
|
||||
int port = ssl ? 443 : 80;
|
||||
size_t i;
|
||||
|
||||
if (hostlen == 0 || hostlen > SOCKS5_MAXFIELD)
|
||||
return socks5_fail(msg, msgsize, "SOCKS5: invalid origin host");
|
||||
if (host[0] == '[') // ATYP=domain cannot carry an IPv6 literal
|
||||
return socks5_fail(msg, msgsize,
|
||||
"SOCKS5: IPv6 literal origin is not supported");
|
||||
for (i = 0; i < hostlen; i++) {
|
||||
if ((unsigned char) host[i] < ' ')
|
||||
return socks5_fail(msg, msgsize, "SOCKS5: invalid origin host");
|
||||
}
|
||||
if (portsep != NULL) {
|
||||
int p = -1;
|
||||
|
||||
sscanf(portsep + 1, "%d", &p);
|
||||
if (p <= 0 || p > 65535)
|
||||
return socks5_fail(msg, msgsize, "SOCKS5: invalid origin port");
|
||||
port = p;
|
||||
}
|
||||
if (link_has_authorization(proxy_name)) {
|
||||
if (!socks5_credentials(opt, proxy_name, user, sizeof(user), &userlen, pass,
|
||||
sizeof(pass), &passlen, msg, msgsize))
|
||||
return 0;
|
||||
want_auth = 1;
|
||||
}
|
||||
return socks5_negotiate(st, host, hostlen, port, user, userlen, pass, passlen,
|
||||
want_auth, msg, msgsize);
|
||||
}
|
||||
|
||||
int socks5_handshake(httrackp *opt, htsblk *retour, const char *adr,
|
||||
int timeout) {
|
||||
socks5_stream st;
|
||||
#if HTS_USEOPENSSL
|
||||
const int ssl = retour->ssl;
|
||||
#else
|
||||
const int ssl = 0;
|
||||
#endif
|
||||
|
||||
if (retour->soc == INVALID_SOCKET)
|
||||
return 0;
|
||||
st.soc = retour->soc;
|
||||
st.timeout = timeout;
|
||||
st.io = NULL;
|
||||
return socks5_handshake_stream(opt, &st, adr, retour->req.proxy.name, ssl,
|
||||
retour->msg, sizeof(retour->msg));
|
||||
}
|
||||
|
||||
int socks5_handshake_scripted(httrackp *opt, const char *adr,
|
||||
const char *proxy_name, socks5_test_io *io) {
|
||||
socks5_stream st;
|
||||
|
||||
st.soc = INVALID_SOCKET;
|
||||
st.timeout = 0;
|
||||
st.io = io;
|
||||
io->consumed = 0;
|
||||
io->sent_len = 0;
|
||||
io->msg[0] = '\0';
|
||||
return socks5_handshake_stream(opt, &st, adr, proxy_name, 0, io->msg,
|
||||
sizeof(io->msg));
|
||||
}
|
||||
82
src/htsproxy.h
Normal file
82
src/htsproxy.h
Normal file
@@ -0,0 +1,82 @@
|
||||
/* ------------------------------------------------------------ */
|
||||
/*
|
||||
HTTrack Website Copier, Offline Browser for Windows and Unix
|
||||
Copyright (C) 2026 Xavier Roche and other contributors
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Ethical use: we kindly ask that you NOT use this software to harvest email
|
||||
addresses or to collect any other private information about people. Doing so
|
||||
would dishonor our work and waste the many hours we have spent on it.
|
||||
|
||||
Please visit our Website: http://www.httrack.com
|
||||
*/
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/* File: Proxy tunneling (HTTP CONNECT, SOCKS5) .h */
|
||||
/* Author: Xavier Roche */
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
#ifndef HTS_DEFPROXY
|
||||
#define HTS_DEFPROXY
|
||||
|
||||
#include "htsglobal.h"
|
||||
|
||||
/* Forward definitions */
|
||||
#ifndef HTS_DEF_FWSTRUCT_httrackp
|
||||
#define HTS_DEF_FWSTRUCT_httrackp
|
||||
typedef struct httrackp httrackp;
|
||||
#endif
|
||||
#ifndef HTS_DEF_FWSTRUCT_htsblk
|
||||
#define HTS_DEF_FWSTRUCT_htsblk
|
||||
typedef struct htsblk htsblk;
|
||||
#endif
|
||||
|
||||
/* Open an HTTP CONNECT tunnel through the active proxy for an https request:
|
||||
`retour->soc` must already be TCP-connected to the proxy, and `adr` is the
|
||||
origin authority (url_adr, e.g. "https://host:port"). Sends the CONNECT
|
||||
request (with Proxy-Authorization when the proxy carries credentials) and
|
||||
reads the proxy's status line, so the caller's TLS handshake then runs
|
||||
end-to-end with the origin. Blocks up to `timeout` seconds. Returns 1 on a
|
||||
2xx tunnel, 0 on failure (retour->msg/statuscode set). */
|
||||
int http_proxy_tunnel(httrackp *opt, htsblk *retour, const char *adr,
|
||||
int timeout);
|
||||
|
||||
/* SOCKS5 (RFC 1928, RFC 1929 auth) handshake on the raw proxy socket, before
|
||||
any TLS: `retour->soc` must be TCP-connected to the proxy and `adr` is the
|
||||
origin (url_adr). The origin name is sent verbatim (ATYP=domain), so the
|
||||
proxy resolves it; a bracketed IPv6 literal origin is rejected. Blocks up to
|
||||
`timeout` seconds. Returns 1 with the stream positioned on the first origin
|
||||
byte, 0 on failure (retour->msg set). */
|
||||
int socks5_handshake(httrackp *opt, htsblk *retour, const char *adr,
|
||||
int timeout);
|
||||
|
||||
/* Self-test hook (-#test=socks5): run the handshake against `reply`, a scripted
|
||||
server byte stream, instead of a socket. `sent` captures the client frames,
|
||||
`consumed` the reply bytes eaten (the frame-desync guard). */
|
||||
typedef struct socks5_test_io {
|
||||
const unsigned char *reply;
|
||||
size_t reply_len;
|
||||
size_t consumed;
|
||||
unsigned char sent[1024];
|
||||
size_t sent_len;
|
||||
char msg[256];
|
||||
} socks5_test_io;
|
||||
|
||||
int socks5_handshake_scripted(httrackp *opt, const char *adr,
|
||||
const char *proxy_name, socks5_test_io *io);
|
||||
|
||||
#endif
|
||||
@@ -54,12 +54,18 @@ Please visit our Website: http://www.httrack.com
|
||||
#include "htsftp.h"
|
||||
#include "htsmd5.h"
|
||||
#include "htssniff.h"
|
||||
#include "htscodec.h"
|
||||
#include "htsproxy.h"
|
||||
#if HTS_USEZLIB
|
||||
#include "htszlib.h"
|
||||
#endif
|
||||
#if HTS_USEZSTD
|
||||
#include <zstd.h>
|
||||
#endif
|
||||
#include "coucal/coucal.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -67,6 +73,9 @@ Please visit our Website: http://www.httrack.com
|
||||
#ifndef _WIN32
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#include <io.h> /* _get_osfhandle, for the sparse-file hint */
|
||||
#include <winioctl.h> /* FSCTL_SET_SPARSE */
|
||||
#endif
|
||||
|
||||
/* very minimalistic internal tests */
|
||||
@@ -744,30 +753,61 @@ static int st_filterdual(httrackp *opt, int argc, char **argv) {
|
||||
process (OSS-Fuzz 5060751291908096 / 5745936014573568). */
|
||||
static int st_filterbounds(httrackp *opt, int argc, char **argv) {
|
||||
const size_t big = 100000; /* well past the length cap */
|
||||
const size_t stars = 900; /* star-heavy pattern, under the cap */
|
||||
const size_t stars = 1023; /* pattern len 2047, under the length cap */
|
||||
const size_t subjlen = 2048;
|
||||
char *subj = malloct(big + 1);
|
||||
char *pat = malloct(2 * stars + 2);
|
||||
size_t i;
|
||||
size_t steps = 0, maxsteps = 0, depth = 0, maxdepth = 0, i;
|
||||
|
||||
(void) opt;
|
||||
(void) argc;
|
||||
(void) argv;
|
||||
memset(subj, 'a', big);
|
||||
subj[big] = '\0';
|
||||
/* '*' matches anything, but an over-length subject is refused by the cap */
|
||||
/* '*' matches anything, but an over-length subject trips the length cap */
|
||||
assertf(strjoker(subj, "*", NULL, NULL) == NULL);
|
||||
assertf(strjokerfind(subj, "*") == NULL);
|
||||
/* within-cap star-heavy dead-end: the step budget keeps it bounded (a hang
|
||||
would time the test out) */
|
||||
/* Star-heavy dead-end at the length cap: unbounded it runs ~1.26e9 memo-steps
|
||||
(~6s). */
|
||||
for (i = 0; i < stars; i++) {
|
||||
pat[2 * i] = '*';
|
||||
pat[2 * i + 1] = 'a';
|
||||
}
|
||||
pat[2 * stars] = 'b'; /* never matches an all-'a' subject */
|
||||
pat[2 * stars + 1] = '\0';
|
||||
subj[stars] = '\0';
|
||||
assertf(strjoker(subj, pat, NULL, NULL) == NULL);
|
||||
subj[subjlen] = '\0';
|
||||
/* Budget must fire and hold: steps > cap (deleting the budget zeroes the
|
||||
counter that is the enforcement), steps < 10*cap (unbudgeted ~1.26e9). */
|
||||
assertf(strjoker_bounds(subj, pat, &steps, &maxsteps, &depth, &maxdepth) ==
|
||||
NULL);
|
||||
assertf(steps > maxsteps && steps < 10 * maxsteps);
|
||||
/* Depth caps the stack: uncapped this recurses 2046 frames, ~900KB (#574). */
|
||||
assertf(depth == maxdepth);
|
||||
assertf(strjokerfind(subj, pat) == NULL);
|
||||
/* Pin the cap from below: 32 segments must still match, so a cap set so low
|
||||
it would break real multi-segment filters (which use far fewer) fails. */
|
||||
for (i = 0; i < 32; i++) {
|
||||
pat[2 * i] = '*';
|
||||
pat[2 * i + 1] = 'a';
|
||||
}
|
||||
pat[64] = '\0';
|
||||
memset(subj, 'a', 32);
|
||||
subj[32] = '\0';
|
||||
assertf(strjoker(subj, pat, NULL, NULL) != NULL);
|
||||
/* Same pin for the class-branch shape users actually write (*[..]), against a
|
||||
long subject: it must match with room to spare under the work cap. */
|
||||
{
|
||||
const char *seg = "*[A-Z,a-z,0-9]";
|
||||
const size_t seglen = strlen(seg), nseg = 16;
|
||||
|
||||
for (i = 0; i < (int) nseg; i++)
|
||||
memcpy(pat + i * seglen, seg, seglen);
|
||||
pat[nseg * seglen] = '\0';
|
||||
memset(subj, 'a', 512);
|
||||
subj[512] = '\0';
|
||||
assertf(strjoker_bounds(subj, pat, &steps, &maxsteps, NULL, NULL) != NULL);
|
||||
assertf(steps < maxsteps);
|
||||
}
|
||||
freet(pat);
|
||||
freet(subj);
|
||||
printf("filterbounds: OK\n");
|
||||
@@ -804,7 +844,11 @@ static int st_mime(httrackp *opt, int argc, char **argv) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static size_t st_decode_body(const char *arg, char *buf, size_t size);
|
||||
|
||||
static int st_charset(httrackp *opt, int argc, char **argv) {
|
||||
char buf[512];
|
||||
size_t len;
|
||||
char *s;
|
||||
|
||||
(void) opt;
|
||||
@@ -812,7 +856,8 @@ static int st_charset(httrackp *opt, int argc, char **argv) {
|
||||
fprintf(stderr, "charset: needs a charset and a string\n");
|
||||
return 1;
|
||||
}
|
||||
s = hts_convertStringToUTF8(argv[1], strlen(argv[1]), argv[0]);
|
||||
len = st_decode_body(argv[1], buf, sizeof(buf));
|
||||
s = hts_convertStringToUTF8(buf, len, argv[0]);
|
||||
if (s != NULL) {
|
||||
printf("%s\n", s);
|
||||
freet(s);
|
||||
@@ -837,16 +882,22 @@ static int st_metacharset(httrackp *opt, int argc, char **argv) {
|
||||
}
|
||||
|
||||
static int st_isutf8(httrackp *opt, int argc, char **argv) {
|
||||
char buf[512];
|
||||
size_t len;
|
||||
|
||||
(void) opt;
|
||||
if (argc < 1) {
|
||||
fprintf(stderr, "isutf8: needs a string\n");
|
||||
return 1;
|
||||
}
|
||||
printf("%d\n", hts_isStringUTF8(argv[0], strlen(argv[0])) ? 1 : 0);
|
||||
len = st_decode_body(argv[0], buf, sizeof(buf));
|
||||
printf("%d\n", hts_isStringUTF8(buf, len) ? 1 : 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int st_idna_encode(httrackp *opt, int argc, char **argv) {
|
||||
char buf[512];
|
||||
size_t len;
|
||||
char *s;
|
||||
|
||||
(void) opt;
|
||||
@@ -854,7 +905,8 @@ static int st_idna_encode(httrackp *opt, int argc, char **argv) {
|
||||
fprintf(stderr, "idna-encode: needs a hostname\n");
|
||||
return 1;
|
||||
}
|
||||
s = hts_convertStringUTF8ToIDNA(argv[0], strlen(argv[0]));
|
||||
len = st_decode_body(argv[0], buf, sizeof(buf));
|
||||
s = hts_convertStringUTF8ToIDNA(buf, len);
|
||||
if (s != NULL) {
|
||||
printf("%s\n", s);
|
||||
freet(s);
|
||||
@@ -1016,7 +1068,7 @@ static int st_hashtable(httrackp *opt, int argc, char **argv) {
|
||||
|
||||
/* produce random patterns, or read from a file */
|
||||
if (sscanf(snum, "%lu", &count) != 1) {
|
||||
const off_t size = fsize(snum);
|
||||
const LLint size = fsize(snum);
|
||||
FILE *fp = fopen(snum, "rb");
|
||||
if (fp != NULL) {
|
||||
buff = malloct(size);
|
||||
@@ -1116,7 +1168,10 @@ static int st_strsafe(httrackp *opt, int argc, char **argv) {
|
||||
comes from argv so its length is opaque to the compiler (no static
|
||||
-Wstringop-overflow, genuine runtime check). "overflow-buff" exercises
|
||||
htsbuff. */
|
||||
char small[4];
|
||||
/* Not sizeof(char*): on ILP32 a char[4] equals the pointer size, and the
|
||||
MSVC array-vs-pointer heuristic (sizeof(A) != sizeof(char*)) then reads
|
||||
it as a pointer and silently skips the bound. */
|
||||
char small[6];
|
||||
const char *const src = (argc >= 2) ? argv[1] : "overflowing";
|
||||
|
||||
if (strcmp(argv[0], "overflow-buff") == 0) {
|
||||
@@ -1300,6 +1355,165 @@ static int st_identurl(httrackp *opt, int argc, char **argv) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int st_proxyurl(httrackp *opt, int argc, char **argv) {
|
||||
char BIGSTK name[HTS_URLMAXSIZE * 2];
|
||||
int port = -1;
|
||||
|
||||
(void) opt;
|
||||
if (argc < 1) {
|
||||
fprintf(stderr, "proxyurl: needs a proxy argument\n");
|
||||
return 1;
|
||||
}
|
||||
hts_parse_proxy(argv[0], name, sizeof(name), &port);
|
||||
// host= is the resolved host (scheme/userinfo stripped); kind= the transport
|
||||
printf("name=%s port=%d host=%s kind=%s\n", name, port,
|
||||
jump_identification_const(name),
|
||||
hts_proxy_is_socks(name) ? "socks"
|
||||
: hts_proxy_is_connect(name) ? "connect"
|
||||
: "http");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Scripted SOCKS5 server: no-auth method reply, then a success CONNECT reply
|
||||
carrying the given ATYP address, then a sentinel origin byte the handshake
|
||||
must leave unread (an off-by-one in the reply framing eats it). */
|
||||
static size_t socks5_reply(unsigned char *buf, unsigned char atyp,
|
||||
const unsigned char *addr, size_t addrlen) {
|
||||
size_t n = 0;
|
||||
|
||||
buf[n++] = 0x05;
|
||||
buf[n++] = 0x00; /* method: no authentication */
|
||||
buf[n++] = 0x05;
|
||||
buf[n++] = 0x00; /* REP: succeeded */
|
||||
buf[n++] = 0x00;
|
||||
buf[n++] = atyp;
|
||||
memcpy(buf + n, addr, addrlen);
|
||||
n += addrlen;
|
||||
buf[n++] = 0x1f;
|
||||
buf[n++] = 0x90; /* BND.PORT */
|
||||
buf[n++] = 0xAA; /* sentinel */
|
||||
return n;
|
||||
}
|
||||
|
||||
#define SOCKS5_SENTINEL_LEFT(io, len) ((io).consumed == (len) - 1)
|
||||
|
||||
static int st_socks5(httrackp *opt, int argc, char **argv) {
|
||||
static const unsigned char v4[4] = {127, 0, 0, 1};
|
||||
static const unsigned char v6[16] = {0};
|
||||
static const unsigned char domain[6] = {5, 'p', 'r', 'o', 'x', 'y'};
|
||||
const char *const proxy = "socks5://127.0.0.1";
|
||||
unsigned char script[64];
|
||||
socks5_test_io io;
|
||||
size_t len;
|
||||
|
||||
(void) argc;
|
||||
(void) argv;
|
||||
|
||||
/* each reply address type is drained exactly, sentinel untouched */
|
||||
len = socks5_reply(script, 0x01, v4, sizeof(v4));
|
||||
io.reply = script;
|
||||
io.reply_len = len;
|
||||
assertf(socks5_handshake_scripted(opt, "origin.test", proxy, &io) == 1);
|
||||
assertf(SOCKS5_SENTINEL_LEFT(io, len));
|
||||
/* the greeting offers no-auth only, and the origin goes out by name, port 80
|
||||
*/
|
||||
assertf(io.sent_len == 3 + 7 + 11);
|
||||
assertf(memcmp(io.sent, "\x05\x01\x00", 3) == 0);
|
||||
assertf(memcmp(io.sent + 3, "\x05\x01\x00\x03\x0borigin.test\x00\x50", 18) ==
|
||||
0);
|
||||
|
||||
len = socks5_reply(script, 0x04, v6, sizeof(v6));
|
||||
io.reply = script;
|
||||
io.reply_len = len;
|
||||
assertf(socks5_handshake_scripted(opt, "origin.test", proxy, &io) == 1);
|
||||
assertf(SOCKS5_SENTINEL_LEFT(io, len));
|
||||
|
||||
len = socks5_reply(script, 0x03, domain, sizeof(domain));
|
||||
io.reply = script;
|
||||
io.reply_len = len;
|
||||
assertf(socks5_handshake_scripted(opt, "origin.test", proxy, &io) == 1);
|
||||
assertf(SOCKS5_SENTINEL_LEFT(io, len));
|
||||
|
||||
/* an unknown address type has no known length: fail, never guess */
|
||||
len = socks5_reply(script, 0x02, v4, sizeof(v4));
|
||||
io.reply = script;
|
||||
io.reply_len = len;
|
||||
assertf(socks5_handshake_scripted(opt, "origin.test", proxy, &io) == 0);
|
||||
|
||||
/* truncated frames (here: no BND.PORT) fail instead of over-reading */
|
||||
len = socks5_reply(script, 0x01, v4, sizeof(v4)) - 3;
|
||||
io.reply = script;
|
||||
io.reply_len = len;
|
||||
assertf(socks5_handshake_scripted(opt, "origin.test", proxy, &io) == 0);
|
||||
|
||||
/* explicit origin port is encoded big-endian (8443 = 0x20fb) */
|
||||
len = socks5_reply(script, 0x01, v4, sizeof(v4));
|
||||
io.reply = script;
|
||||
io.reply_len = len;
|
||||
assertf(socks5_handshake_scripted(opt, "origin.test:8443", proxy, &io) == 1);
|
||||
assertf(memcmp(io.sent + io.sent_len - 2, "\x20\xfb", 2) == 0);
|
||||
|
||||
/* credentials: split on the first colon of the escaped userinfo, so %3a stays
|
||||
inside the username and a colon in the password is not a delimiter */
|
||||
{
|
||||
static const unsigned char auth_script[] = {
|
||||
0x05, 0x02, /* method: user/pass */
|
||||
0x01, 0x00, /* auth: success */
|
||||
0x05, 0x00, 0x00, 0x01, /* REP: succeeded, ATYP ipv4 */
|
||||
127, 0, 0, 1, 0x1f, 0x90, 0xAA};
|
||||
|
||||
io.reply = auth_script;
|
||||
io.reply_len = sizeof(auth_script);
|
||||
assertf(socks5_handshake_scripted(opt, "origin.test",
|
||||
"socks5://us%3aer:p:ass@127.0.0.1",
|
||||
&io) == 1);
|
||||
assertf(SOCKS5_SENTINEL_LEFT(io, sizeof(auth_script)));
|
||||
assertf(memcmp(io.sent, "\x05\x02\x00\x02", 4) == 0);
|
||||
assertf(memcmp(io.sent + 4, "\x01\x05us:er\x05p:ass", 13) == 0);
|
||||
}
|
||||
|
||||
/* a proxy demanding auth we cannot provide, and one refusing every method */
|
||||
io.reply = (const unsigned char *) "\x05\x02";
|
||||
io.reply_len = 2;
|
||||
assertf(socks5_handshake_scripted(opt, "origin.test", proxy, &io) == 0);
|
||||
io.reply = (const unsigned char *) "\x05\xff";
|
||||
io.reply_len = 2;
|
||||
assertf(socks5_handshake_scripted(opt, "origin.test", proxy, &io) == 0);
|
||||
|
||||
/* a refused CONNECT is an error, not a tunnel */
|
||||
io.reply = (const unsigned char
|
||||
*) "\x05\x00\x05\x05\x00\x01\x7f\x00\x00\x01\x1f\x90";
|
||||
io.reply_len = 12;
|
||||
assertf(socks5_handshake_scripted(opt, "origin.test", proxy, &io) == 0);
|
||||
|
||||
/* over-long host or credentials are rejected before anything is sent */
|
||||
{
|
||||
char host[512];
|
||||
char name[1024];
|
||||
size_t i;
|
||||
|
||||
host[0] = '\0';
|
||||
for (i = 0; i < 256; i++)
|
||||
strcatbuff(host, "a");
|
||||
io.reply = script;
|
||||
io.reply_len = len;
|
||||
assertf(socks5_handshake_scripted(opt, host, proxy, &io) == 0);
|
||||
assertf(io.sent_len == 0);
|
||||
|
||||
strcpybuff(name, "socks5://user:");
|
||||
for (i = 0; i < 256; i++)
|
||||
strcatbuff(name, "p");
|
||||
strcatbuff(name, "@127.0.0.1");
|
||||
io.reply = script;
|
||||
io.reply_len = len;
|
||||
assertf(socks5_handshake_scripted(opt, "origin.test", name, &io) == 0);
|
||||
assertf(io.sent_len == 0);
|
||||
}
|
||||
|
||||
printf("socks5 self-test OK\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Regression for the one-byte fil[] overflow: a 2047-byte hostless "?"-URL used
|
||||
to abort in strncat_safe_ when the missing leading '/' pushed fil to 2048. */
|
||||
static int st_identabs(httrackp *opt, int argc, char **argv) {
|
||||
@@ -1444,7 +1658,8 @@ static int st_crange(httrackp *opt, int argc, char **argv) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Decode a body argument ("hex:FFD8.." or literal text) into buf. */
|
||||
/* Decode an argument ("hex:FFD8.." or literal text) into buf. Raw non-UTF-8
|
||||
bytes cannot survive a Windows command line, so hostile inputs go as hex. */
|
||||
static size_t st_decode_body(const char *arg, char *buf, size_t size) {
|
||||
size_t n = 0;
|
||||
|
||||
@@ -1484,6 +1699,94 @@ static int st_sniff(httrackp *opt, int argc, char **argv) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* fsize()/fsize_utf8()/fpsize() must report a size past 4GB: 32-bit wraps both
|
||||
ways there (MSVC's off_t and struct _stat st_size are long, 32-bit even on
|
||||
x64), and a size under 4GB would survive an *unsigned* 32-bit truncation. */
|
||||
static int st_fsize(httrackp *opt, int argc, char **argv) {
|
||||
const LLint expected = 5 * 1024 * 1024 * 1024LL;
|
||||
char BIGSTK path[HTS_URLMAXSIZE * 2];
|
||||
char BIGSTK absent[HTS_URLMAXSIZE * 2];
|
||||
/* both variants: only fsize() feeds the >2GB readers (file://, --list) */
|
||||
const int width = (int) sizeof(fsize(""));
|
||||
const int width_utf8 = (int) sizeof(fsize_utf8(""));
|
||||
FILE *fp;
|
||||
LLint got, got_utf8, gotp, gone;
|
||||
int rc = 0;
|
||||
|
||||
(void) opt;
|
||||
if (argc < 1) {
|
||||
fprintf(stderr, "fsize: needs a directory\n");
|
||||
return 1;
|
||||
}
|
||||
concat(path, sizeof(path), argv[0], "/sparse-5g.bin");
|
||||
concat(absent, sizeof(absent), argv[0], "/no-such-file.bin");
|
||||
|
||||
/* sparse: seek past 4GB and write the last byte */
|
||||
fp = FOPEN(path, "wb");
|
||||
if (fp == NULL) {
|
||||
fprintf(stderr, "fsize: cannot create '%s': %s\n", path, strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
#ifdef _WIN32
|
||||
{
|
||||
/* NTFS allocates the hole unless asked not to; POSIX gives it for free.
|
||||
Best-effort: a non-sparse file still measures the same, just costs 5GB.
|
||||
*/
|
||||
HANDLE h = (HANDLE) _get_osfhandle(_fileno(fp));
|
||||
DWORD ret;
|
||||
|
||||
if (h != INVALID_HANDLE_VALUE)
|
||||
(void) DeviceIoControl(h, FSCTL_SET_SPARSE, NULL, 0, NULL, 0, &ret, NULL);
|
||||
}
|
||||
#endif
|
||||
if (fseeko(fp, expected - 1, SEEK_SET) != 0 || fputc(0, fp) == EOF ||
|
||||
fclose(fp) != 0) {
|
||||
fprintf(stderr, "fsize: cannot extend '%s' to " LLintP ": %s\n", path,
|
||||
expected, strerror(errno));
|
||||
UNLINK(path);
|
||||
return 1;
|
||||
}
|
||||
|
||||
got = fsize(path);
|
||||
got_utf8 = fsize_utf8(path);
|
||||
fp = FOPEN(path, "rb");
|
||||
if (fp == NULL) {
|
||||
fprintf(stderr, "fsize: cannot reopen '%s': %s\n", path, strerror(errno));
|
||||
gotp = -1;
|
||||
} else {
|
||||
gotp = fpsize(fp);
|
||||
fclose(fp);
|
||||
}
|
||||
UNLINK(path);
|
||||
gone = fsize(absent); /* contract: -1, not 0, when absent */
|
||||
|
||||
printf("fsize: width=%d,%d size=" LLintP "," LLintP " psize=" LLintP
|
||||
" absent=" LLintP "\n",
|
||||
width, width_utf8, got, got_utf8, gotp, gone);
|
||||
if (width != 8 || width_utf8 != 8) {
|
||||
fprintf(stderr, "fsize: return types are %d/%d bytes, expected 8\n", width,
|
||||
width_utf8);
|
||||
rc = 1;
|
||||
}
|
||||
if (got != expected || got_utf8 != expected) {
|
||||
fprintf(stderr,
|
||||
"fsize: fsize/fsize_utf8 are " LLintP "/" LLintP
|
||||
", expected " LLintP "\n",
|
||||
got, got_utf8, expected);
|
||||
rc = 1;
|
||||
}
|
||||
if (gotp != expected) {
|
||||
fprintf(stderr, "fsize: fpsize is " LLintP ", expected " LLintP "\n", gotp,
|
||||
expected);
|
||||
rc = 1;
|
||||
}
|
||||
if (gone != -1) {
|
||||
fprintf(stderr, "fsize: absent file is " LLintP ", expected -1\n", gone);
|
||||
rc = 1;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int st_savename(httrackp *opt, int argc, char **argv) {
|
||||
lien_adrfilsave afs;
|
||||
cache_back cache;
|
||||
@@ -2301,6 +2604,7 @@ static int ae_write_collision(const char *path, const unsigned char *src,
|
||||
freet(buf);
|
||||
return ok ? 0 : 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Write src[0..len) to path as-is; 0 on success. */
|
||||
static int ae_write_raw(const char *path, const unsigned char *src,
|
||||
@@ -2334,17 +2638,22 @@ static int ae_check_decoded(const char *path, const unsigned char *expect,
|
||||
fclose(f);
|
||||
return (off == len) ? 0 : 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Accept-Encoding (#450): advertise gzip+deflate; both decode (hts_zunpack) */
|
||||
static int st_acceptencoding(httrackp *opt, int argc, char **argv) {
|
||||
const char *off = hts_acceptencoding(HTS_FALSE);
|
||||
const char *on = hts_acceptencoding(HTS_TRUE);
|
||||
const char *off = hts_acceptencoding(HTS_FALSE, HTS_TRUE);
|
||||
const char *on = hts_acceptencoding(HTS_TRUE, HTS_FALSE);
|
||||
const char *tls = hts_acceptencoding(HTS_TRUE, HTS_TRUE);
|
||||
|
||||
(void) opt;
|
||||
assertf(strcmp(off, "identity") == 0);
|
||||
assertf(strstr(on, "gzip") != NULL);
|
||||
assertf(strstr(on, "deflate") != NULL); /* fails on the old gzip-only list */
|
||||
/* br and zstd ride on TLS only, so a cleartext proxy can not be handed a
|
||||
coding it may try to rewrite */
|
||||
assertf(strstr(on, "br") == NULL && strstr(on, "zstd") == NULL);
|
||||
assertf((strstr(tls, ", br") != NULL) == (HTS_USEBROTLI != 0));
|
||||
assertf((strstr(tls, "zstd") != NULL) == (HTS_USEZSTD != 0));
|
||||
#if HTS_USEZLIB
|
||||
if (argc >= 1) {
|
||||
static const int windowBits[] = {16 + MAX_WBITS, MAX_WBITS, -MAX_WBITS};
|
||||
@@ -2432,6 +2741,115 @@ static int st_acceptencoding(httrackp *opt, int argc, char **argv) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if HTS_USEBROTLI
|
||||
/* No brotli encoder is linked, so the coded bytes are canned: brotli quality 9
|
||||
over cc_text, and over 4 MiB of 'A' (14 bytes, ~300000x). */
|
||||
static const unsigned char cc_br_text[] = {
|
||||
0x1b, 0x43, 0x00, 0x00, 0x44, 0xdd, 0x96, 0xea, 0xe8, 0x22, 0xdd, 0x90,
|
||||
0xa4, 0x1b, 0x8a, 0xf7, 0x47, 0x0e, 0xc2, 0xc5, 0x3d, 0x09, 0x1b, 0x70,
|
||||
0xe0, 0x1e, 0x60, 0xa0, 0x8b, 0xcc, 0xbe, 0xcb, 0xb0, 0x31, 0x76, 0x9e,
|
||||
0xcf, 0x6e, 0x41, 0xb5, 0xe8, 0x2e, 0x56, 0x78, 0x08, 0x1b, 0xfa, 0x08,
|
||||
0x8a, 0x50, 0x83, 0x4e, 0x62, 0x7f, 0xbf, 0x05, 0xf2, 0x22, 0x8f, 0xdf,
|
||||
0x28, 0xdc, 0x9f, 0xa9, 0x90, 0x50, 0x37, 0x62, 0x56, 0x4f, 0xa8};
|
||||
static const unsigned char cc_br_bomb[] = {0x9b, 0xff, 0xff, 0x3f, 0x00,
|
||||
0x24, 0x82, 0xe2, 0xb1, 0x40,
|
||||
0x72, 0xef, 0x7f, 0x00};
|
||||
#endif
|
||||
|
||||
static const unsigned char cc_text[] =
|
||||
"content codings: HTTrack decodes gzip, brotli and zstd bodies alike.";
|
||||
|
||||
/* Content codings: br and zstd decode, junk tokens stay identity, a coding we
|
||||
can not undo fails the fetch, and a bomb never lands on disk. */
|
||||
static int st_contentcodings(httrackp *opt, int argc, char **argv) {
|
||||
const size_t tlen = sizeof(cc_text) - 1;
|
||||
char inpath[HTS_URLMAXSIZE], outpath[HTS_URLMAXSIZE];
|
||||
|
||||
(void) opt;
|
||||
assertf(hts_codec_parse("gzip") == HTS_CODEC_DEFLATE);
|
||||
assertf(hts_codec_parse("x-deflate") == HTS_CODEC_DEFLATE);
|
||||
assertf(hts_codec_parse("") == HTS_CODEC_IDENTITY);
|
||||
assertf(hts_codec_parse("identity") == HTS_CODEC_IDENTITY);
|
||||
/* servers do label plain bodies with junk; the page must survive that */
|
||||
assertf(hts_codec_parse("utf-8") == HTS_CODEC_IDENTITY);
|
||||
/* a real coding with no decoder here: fail, never save the coded bytes */
|
||||
assertf(hts_codec_parse("compress") == HTS_CODEC_UNSUPPORTED);
|
||||
assertf(hts_codec_parse("br") ==
|
||||
(HTS_USEBROTLI ? HTS_CODEC_BROTLI : HTS_CODEC_UNSUPPORTED));
|
||||
assertf(hts_codec_parse("zstd") ==
|
||||
(HTS_USEZSTD ? HTS_CODEC_ZSTD : HTS_CODEC_UNSUPPORTED));
|
||||
assertf(hts_codec_is_archive_ext(HTS_CODEC_DEFLATE, "tgz"));
|
||||
assertf(!hts_codec_is_archive_ext(HTS_CODEC_DEFLATE, "html"));
|
||||
assertf(hts_codec_is_archive_ext(HTS_CODEC_BROTLI, "br"));
|
||||
assertf(hts_codec_is_archive_ext(HTS_CODEC_ZSTD, "zst"));
|
||||
/* decoded-size budget: 4096x, floor 1 MiB, ceiling INT_MAX */
|
||||
assertf(hts_codec_maxout(1) == 1024 * 1024);
|
||||
assertf(hts_codec_maxout(1024) == 4096 * 1024);
|
||||
assertf(hts_codec_maxout(1024 * 1024) == INT_MAX);
|
||||
|
||||
if (argc >= 1) {
|
||||
snprintf(inpath, sizeof(inpath), "%s/cc-in", argv[0]);
|
||||
snprintf(outpath, sizeof(outpath), "%s/cc-out", argv[0]);
|
||||
#if HTS_USEBROTLI
|
||||
{
|
||||
unsigned char head[16];
|
||||
|
||||
assertf(ae_write_raw(inpath, cc_br_text, sizeof(cc_br_text)) == 0);
|
||||
assertf(hts_codec_unpack(HTS_CODEC_BROTLI, inpath, outpath) ==
|
||||
(int) tlen);
|
||||
assertf(ae_check_decoded(outpath, cc_text, tlen) == 0);
|
||||
assertf(hts_codec_head(HTS_CODEC_BROTLI, cc_br_text, sizeof(cc_br_text),
|
||||
head, sizeof(head)) == sizeof(head));
|
||||
assertf(memcmp(head, cc_text, sizeof(head)) == 0);
|
||||
/* truncated: must fail, not fall back to a verbatim copy */
|
||||
assertf(ae_write_raw(inpath, cc_br_text, sizeof(cc_br_text) - 4) == 0);
|
||||
assertf(hts_codec_unpack(HTS_CODEC_BROTLI, inpath, outpath) < 0);
|
||||
/* cc_br_bomb is a valid stream that expands to 4 MiB; the budget, not a
|
||||
corrupt frame, is what must reject it. */
|
||||
assertf((LLint) (4 * 1024 * 1024) >
|
||||
hts_codec_maxout((LLint) sizeof(cc_br_bomb)));
|
||||
assertf(ae_write_raw(inpath, cc_br_bomb, sizeof(cc_br_bomb)) == 0);
|
||||
assertf(hts_codec_unpack(HTS_CODEC_BROTLI, inpath, outpath) < 0);
|
||||
}
|
||||
#endif
|
||||
#if HTS_USEZSTD
|
||||
{
|
||||
const size_t bomblen = 4 * 1024 * 1024;
|
||||
const size_t bound = ZSTD_compressBound(bomblen);
|
||||
unsigned char *bomb = malloct(bomblen);
|
||||
unsigned char *zbuf = malloct(bound);
|
||||
unsigned char head[16];
|
||||
size_t zlen;
|
||||
|
||||
assertf(bomb != NULL && zbuf != NULL);
|
||||
zlen = ZSTD_compress(zbuf, bound, cc_text, tlen, 6);
|
||||
assertf(!ZSTD_isError(zlen));
|
||||
assertf(ae_write_raw(inpath, zbuf, zlen) == 0);
|
||||
assertf(hts_codec_unpack(HTS_CODEC_ZSTD, inpath, outpath) == (int) tlen);
|
||||
assertf(ae_check_decoded(outpath, cc_text, tlen) == 0);
|
||||
assertf(hts_codec_head(HTS_CODEC_ZSTD, zbuf, zlen, head, sizeof(head)) ==
|
||||
sizeof(head));
|
||||
assertf(memcmp(head, cc_text, sizeof(head)) == 0);
|
||||
assertf(ae_write_raw(inpath, zbuf, zlen - 4) == 0);
|
||||
assertf(hts_codec_unpack(HTS_CODEC_ZSTD, inpath, outpath) < 0);
|
||||
memset(bomb, 'A', bomblen);
|
||||
zlen = ZSTD_compress(zbuf, bound, bomb, bomblen, 6);
|
||||
assertf(!ZSTD_isError(zlen));
|
||||
/* the fixture must really be past the budget, whatever the ratio is */
|
||||
assertf((LLint) bomblen > hts_codec_maxout((LLint) zlen));
|
||||
assertf(ae_write_raw(inpath, zbuf, zlen) == 0);
|
||||
assertf(hts_codec_unpack(HTS_CODEC_ZSTD, inpath, outpath) < 0);
|
||||
freet(bomb);
|
||||
freet(zbuf);
|
||||
}
|
||||
#endif
|
||||
/* a coding we can not undo yields no file at all */
|
||||
assertf(hts_codec_unpack(HTS_CODEC_UNSUPPORTED, inpath, outpath) < 0);
|
||||
}
|
||||
printf("contentcodings self-test OK\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Each call parses `txt` under a fresh host, then checkrobots() for `path`. */
|
||||
static int rb_decide(robots_wizard *r, const char *txt, const char *path) {
|
||||
static int n = 0;
|
||||
@@ -2515,11 +2933,43 @@ static int st_robots(httrackp *opt, int argc, char **argv) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Connected stream pair over loopback; Windows has no socketpair(). */
|
||||
static int st_socketpair(T_SOC sv[2]) {
|
||||
struct sockaddr_in sa;
|
||||
socklen_t len = sizeof(sa);
|
||||
T_SOC srv, cli, acc;
|
||||
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.sin_family = AF_INET;
|
||||
sa.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
if ((srv = (T_SOC) socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
|
||||
return -1;
|
||||
if (bind(srv, (struct sockaddr *) &sa, sizeof(sa)) != 0 ||
|
||||
listen(srv, 1) != 0 ||
|
||||
getsockname(srv, (struct sockaddr *) &sa, &len) != 0) {
|
||||
deletesoc(srv);
|
||||
return -1;
|
||||
}
|
||||
if ((cli = (T_SOC) socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
|
||||
deletesoc(srv);
|
||||
return -1;
|
||||
}
|
||||
if (connect(cli, (struct sockaddr *) &sa, sizeof(sa)) != 0 ||
|
||||
(acc = (T_SOC) accept(srv, NULL, NULL)) == INVALID_SOCKET) {
|
||||
deletesoc(cli);
|
||||
deletesoc(srv);
|
||||
return -1;
|
||||
}
|
||||
deletesoc(srv);
|
||||
sv[0] = acc;
|
||||
sv[1] = cli;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* get_ftp_line must bound a hostile, CRLF-less reply into its internal
|
||||
1024-byte buffer; ASan turns the pre-fix overflow into an abort here. */
|
||||
#ifndef _WIN32
|
||||
static int st_ftpline(httrackp *opt, int argc, char **argv) {
|
||||
int sv[2];
|
||||
T_SOC sv[2];
|
||||
char line[2048];
|
||||
char flood[4096];
|
||||
|
||||
@@ -2527,19 +2977,19 @@ static int st_ftpline(httrackp *opt, int argc, char **argv) {
|
||||
(void) argc;
|
||||
(void) argv;
|
||||
memset(flood, 'x', sizeof(flood));
|
||||
assertf(socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == 0);
|
||||
assertf(write(sv[1], "220 ", 4) == 4); // valid 3-digit code
|
||||
assertf(write(sv[1], flood, sizeof(flood)) == (ssize_t) sizeof(flood));
|
||||
assertf(write(sv[1], "\r\n", 2) == 2); // end the line so we return
|
||||
close(sv[1]);
|
||||
assertf(st_socketpair(sv) == 0);
|
||||
// the 4102-byte reply fits the loopback send buffer, so no reader is needed
|
||||
assertf(send(sv[1], "220 ", 4, 0) == 4); // valid 3-digit code
|
||||
assertf(send(sv[1], flood, (int) sizeof(flood), 0) == (int) sizeof(flood));
|
||||
assertf(send(sv[1], "\r\n", 2, 0) == 2); // end the line so we return
|
||||
deletesoc(sv[1]);
|
||||
line[0] = '\0';
|
||||
get_ftp_line(sv[0], line, sizeof(line), 5);
|
||||
close(sv[0]);
|
||||
deletesoc(sv[0]);
|
||||
printf("ftp-line self-test OK (bounded %d-byte reply)\n",
|
||||
(int) sizeof(flood));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ftp_split_userpass: well-formed split, plus a hostile over-long userinfo
|
||||
that pre-fix overran user[256]/pass[256]. */
|
||||
@@ -2611,11 +3061,11 @@ static const struct selftest_entry {
|
||||
{"redirect-samefile", "", "same-file redirect detection self-test (#159)",
|
||||
st_redirect_samefile},
|
||||
{"mime", "<filename>", "MIME type for a filename", st_mime},
|
||||
{"charset", "<charset> <string>",
|
||||
{"charset", "<charset> <hex:..|string>",
|
||||
"convert a string to UTF-8 from a charset", st_charset},
|
||||
{"metacharset", "<html>", "extract the <meta> charset from an HTML page",
|
||||
st_metacharset},
|
||||
{"isutf8", "<string>", "is the string valid UTF-8 (1/0)", st_isutf8},
|
||||
{"isutf8", "<hex:..|string>", "is the string valid UTF-8 (1/0)", st_isutf8},
|
||||
{"idna-encode", "<host>", "encode a hostname to IDNA/punycode",
|
||||
st_idna_encode},
|
||||
{"idna-decode", "<host>", "decode an IDNA/punycode hostname",
|
||||
@@ -2633,6 +3083,10 @@ static const struct selftest_entry {
|
||||
{"resolve", "<link> <adr> <fil>", "resolve a link against an origin",
|
||||
st_resolve},
|
||||
{"identurl", "<url>", "split an absolute URL into (adr, fil)", st_identurl},
|
||||
{"proxyurl", "<proxy-arg>", "parse a -P proxy URL into host/port",
|
||||
st_proxyurl},
|
||||
{"socks5", "", "SOCKS5 handshake framing and credential self-test",
|
||||
st_socks5},
|
||||
{"identabs", "", "ident_url_absolute one-byte fil[] overflow self-test",
|
||||
st_identabs},
|
||||
{"header", "<raw-header-line> ...", "response header-line parsing",
|
||||
@@ -2648,6 +3102,7 @@ static const struct selftest_entry {
|
||||
"local save-name for a URL", st_savename},
|
||||
{"sniff", "<content-type> <hex:..|text>", "MIME magic consistency",
|
||||
st_sniff},
|
||||
{"fsize", "<dir>", "file size past the 2GB signed-32-bit wrap", st_fsize},
|
||||
{"cache", "<dir>", "cache read/write round-trip self-test", st_cache},
|
||||
{"cacheindex", "", "cache-index (.ndx) parse must stay in bounds",
|
||||
st_cacheindex},
|
||||
@@ -2673,12 +3128,13 @@ static const struct selftest_entry {
|
||||
{"status", "", "HTTP status code -> reason phrase self-test", st_status},
|
||||
{"acceptencoding", "[dir]",
|
||||
"Accept-Encoding advertises gzip+deflate, both decode", st_acceptencoding},
|
||||
{"contentcodings", "[dir]",
|
||||
"brotli and zstd bodies decode; bombs and unknown codings are refused",
|
||||
st_contentcodings},
|
||||
{"robots", "", "robots.txt RFC 9309 Allow/Disallow precedence self-test",
|
||||
st_robots},
|
||||
#ifndef _WIN32
|
||||
{"ftp-line", "", "get_ftp_line bounds a hostile FTP reply line",
|
||||
st_ftpline},
|
||||
#endif
|
||||
{"ftp-userpass", "", "ftp_split_userpass bounds URL userinfo", st_ftpuser},
|
||||
};
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ Please visit our Website: http://www.httrack.com
|
||||
/* specific definitions */
|
||||
#include "htsbase.h"
|
||||
#include "htscore.h"
|
||||
#include "htscodec.h"
|
||||
#include "htszlib.h"
|
||||
|
||||
#if HTS_USEZLIB
|
||||
@@ -46,13 +47,8 @@ Please visit our Website: http://www.httrack.com
|
||||
#include "htszlib.h"
|
||||
*/
|
||||
|
||||
/*
|
||||
Unpack file into a new file (gzip, zlib RFC1950 or raw deflate RFC1951).
|
||||
A body provably in no deflate framing is copied verbatim (identity).
|
||||
Return value: size of the new file, or -1 if an error occurred
|
||||
*/
|
||||
/* Note: utf-8 */
|
||||
int hts_zunpack(char *filename, char *newfile) {
|
||||
int hts_zunpack(const char *filename, const char *newfile) {
|
||||
int ret = -1;
|
||||
|
||||
if (filename != NULL && newfile != NULL && filename[0] && newfile[0]) {
|
||||
@@ -61,6 +57,7 @@ int hts_zunpack(char *filename, char *newfile) {
|
||||
|
||||
if (in != NULL) {
|
||||
unsigned char BIGSTK inbuf[8192];
|
||||
const LLint maxout = hts_codec_maxout(hts_codec_coded_size(in));
|
||||
size_t navail = fread(inbuf, 1, sizeof(inbuf), in);
|
||||
/* gzip/zlib headers -> +32 windowBits; else raw deflate (RFC1951) */
|
||||
const hts_boolean wrapped =
|
||||
@@ -73,9 +70,10 @@ int hts_zunpack(char *filename, char *newfile) {
|
||||
deflate framing at all. env_error: local I/O or memory failure. */
|
||||
hts_boolean not_deflate = HTS_FALSE;
|
||||
hts_boolean env_error = HTS_FALSE;
|
||||
hts_boolean bomb = HTS_FALSE;
|
||||
|
||||
/* deflate is ambiguous; on failure retry with the other windowBits */
|
||||
for (attempt = 0; attempt < 2 && ret < 0; attempt++) {
|
||||
for (attempt = 0; attempt < 2 && ret < 0 && !bomb; attempt++) {
|
||||
const int windowBits =
|
||||
(attempt == 0 ? wrapped : !wrapped) ? (32 + MAX_WBITS) : -MAX_WBITS;
|
||||
FILE *fpout;
|
||||
@@ -102,7 +100,7 @@ int hts_zunpack(char *filename, char *newfile) {
|
||||
}
|
||||
{
|
||||
hts_boolean ok = HTS_TRUE;
|
||||
int size = 0;
|
||||
LLint size = 0;
|
||||
int zerr = Z_OK;
|
||||
|
||||
/* chunked inflate; first chunk in inbuf, single member */
|
||||
@@ -126,27 +124,33 @@ int hts_zunpack(char *filename, char *newfile) {
|
||||
break;
|
||||
}
|
||||
produced = sizeof(outbuf) - strm.avail_out;
|
||||
size += (LLint) produced;
|
||||
if (size > maxout) { /* decompression bomb: no retry, no copy */
|
||||
bomb = HTS_TRUE;
|
||||
ok = HTS_FALSE;
|
||||
break;
|
||||
}
|
||||
if (produced > 0 &&
|
||||
fwrite(outbuf, 1, produced, fpout) != produced) {
|
||||
env_error = HTS_TRUE;
|
||||
ok = HTS_FALSE;
|
||||
break;
|
||||
}
|
||||
size += (int) produced;
|
||||
} while (strm.avail_out == 0);
|
||||
if (!ok || zerr == Z_STREAM_END)
|
||||
break;
|
||||
navail = fread(inbuf, 1, sizeof(inbuf), in);
|
||||
} while (navail > 0);
|
||||
if (ok && zerr == Z_STREAM_END)
|
||||
ret = size;
|
||||
ret = (int) size;
|
||||
}
|
||||
inflateEnd(&strm);
|
||||
fclose(fpout);
|
||||
}
|
||||
/* keep a mislabeled identity body verbatim only when provably not
|
||||
deflate; truncation or a local failure must keep failing (#47) */
|
||||
if (ret < 0 && !wrapped && not_deflate && !env_error && !ferror(in)) {
|
||||
if (ret < 0 && !bomb && !wrapped && not_deflate && !env_error &&
|
||||
!ferror(in)) {
|
||||
FILE *const fpout =
|
||||
FOPEN(fconv(catbuff, sizeof(catbuff), newfile), "wb");
|
||||
|
||||
@@ -172,6 +176,25 @@ int hts_zunpack(char *filename, char *newfile) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t hts_zhead(const void *in, size_t in_len, void *out, size_t out_len) {
|
||||
z_stream zs;
|
||||
size_t n = 0;
|
||||
int err;
|
||||
|
||||
memset(&zs, 0, sizeof(zs));
|
||||
if (inflateInit2(&zs, 47) != Z_OK) /* 47: gzip or zlib, autodetected */
|
||||
return 0;
|
||||
zs.next_in = (const Bytef *) in;
|
||||
zs.avail_in = (uInt) in_len;
|
||||
zs.next_out = (Bytef *) out;
|
||||
zs.avail_out = (uInt) out_len;
|
||||
err = inflate(&zs, Z_SYNC_FLUSH);
|
||||
if (err == Z_OK || err == Z_STREAM_END || err == Z_BUF_ERROR)
|
||||
n = out_len - zs.avail_out;
|
||||
inflateEnd(&zs);
|
||||
return n;
|
||||
}
|
||||
|
||||
int hts_extract_meta(const char *path) {
|
||||
char catbuff[CATBUFF_SIZE];
|
||||
unzFile zFile = unzOpen(fconcat(catbuff, sizeof(catbuff), path, "hts-cache/new.zip"));
|
||||
|
||||
@@ -44,7 +44,13 @@ Please visit our Website: http://www.httrack.com
|
||||
|
||||
/* Library internal definictions */
|
||||
#ifdef HTS_INTERNAL_BYTECODE
|
||||
extern int hts_zunpack(char *filename, char *newfile);
|
||||
/* Inflate filename into newfile (gzip, zlib or raw deflate); decoded size, or
|
||||
-1 on a corrupt/truncated stream, an over-budget body, or an I/O failure. A
|
||||
body provably in no deflate framing is copied verbatim. */
|
||||
extern int hts_zunpack(const char *filename, const char *newfile);
|
||||
/* Inflate the head of a gzip/zlib stream, out_len max; 0 if undecodable */
|
||||
extern size_t hts_zhead(const void *in, size_t in_len, void *out,
|
||||
size_t out_len);
|
||||
extern int hts_extract_meta(const char *path);
|
||||
extern const char *hts_get_zerror(int err);
|
||||
#endif
|
||||
|
||||
@@ -743,7 +743,8 @@ HTSEXT_API hts_boolean hts_findissystem(find_handle find);
|
||||
HTSEXT_API FILE *hts_fopen_utf8(const char *path, const char *mode);
|
||||
|
||||
#define STAT hts_stat_utf8
|
||||
typedef struct _stat STRUCT_STAT;
|
||||
/* _stat64: _stat's st_size is a 32-bit long, even in x64 builds */
|
||||
typedef struct _stat64 STRUCT_STAT;
|
||||
|
||||
HTSEXT_API int hts_stat_utf8(const char *path, STRUCT_STAT *buf);
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ Please visit our Website: http://www.httrack.com
|
||||
#include "htsdefines.h"
|
||||
#include "httrack.h"
|
||||
#include "htslib.h"
|
||||
#include "htscharset.h" // after htslib.h: winsock2.h must precede windows.h
|
||||
|
||||
/* Static definitions */
|
||||
static int fexist(const char *s);
|
||||
@@ -206,6 +207,7 @@ int main(int argc, char **argv) {
|
||||
httrackp *opt;
|
||||
|
||||
#ifdef _WIN32
|
||||
hts_argv_utf8(&argc, &argv);
|
||||
{
|
||||
WORD wVersionRequested; // requested version WinSock API
|
||||
WSADATA wsadata; // Windows Sockets API data
|
||||
|
||||
127
src/httrack.dsp
127
src/httrack.dsp
@@ -1,127 +0,0 @@
|
||||
# Microsoft Developer Studio Project File - Name="httrack" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Console Application" 0x0103
|
||||
|
||||
CFG=httrack - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "httrack.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "httrack.mak" CFG="httrack - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "httrack - Win32 Release" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE "httrack - Win32 Debug" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE "httrack - Win32 Release avec debug" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "httrack - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "c:\temp\vcpp"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /MD /W3 /Gi /O2 /Op /Ob2 /I "C:\Dev\IPv6Kit\inc\\" /I "C:\Dev\zlib\\" /I "C:\Dev\openssl\include" /I "C:\Dev\Winhttrack" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "HTS_ANALYSTE_CONSOLE" /YX /FD /Zm200 /c
|
||||
# SUBTRACT CPP /Fr
|
||||
# ADD BASE RSC /l 0x40c /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
# ADD LINK32 wsock32.lib libhttrack.lib /nologo /subsystem:console /machine:I386 /out:"L:\HTTrack\httrack\httrack.exe" /libpath:"C:\Dev\openssl\lib" /libpath:"C:\Dev\zlib\dll32" /libpath:"C:\Dev\openssl\lib\out32dll" /libpath:"C:\temp\Releaselib"
|
||||
# SUBTRACT LINK32 /verbose
|
||||
|
||||
!ELSEIF "$(CFG)" == "httrack - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "c:\temp\vcpp"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm /GR /ZI /Od /I "C:\Dev\IPv6Kit\inc\\" /I "C:\Dev\zlib\\" /I "C:\Dev\openssl\include" /I "C:\Dev\Winhttrack" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "HTS_ANALYSTE_CONSOLE" /FAcs /Fr /FD /Zm200 /c
|
||||
# ADD BASE RSC /l 0x40c /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 wsock32.lib libhttrack.lib /nologo /subsystem:console /debug /debugtype:both /machine:I386 /out:"C:\temp\httrack.exe" /pdbtype:sept /libpath:"C:\Dev\openssl\lib" /libpath:"C:\Dev\zlib\dll32" /libpath:"C:\Dev\openssl\lib\out32dll" /libpath:"C:\temp\Debuglib"
|
||||
# SUBTRACT LINK32 /profile /map
|
||||
|
||||
!ELSEIF "$(CFG)" == "httrack - Win32 Release avec debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "httrack___Win32_Release_avec_debug"
|
||||
# PROP BASE Intermediate_Dir "httrack___Win32_Release_avec_debug"
|
||||
# PROP BASE Ignore_Export_Lib 0
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release_avec_debug"
|
||||
# PROP Intermediate_Dir "c:\temp\vcpp"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /Ot /Oi /Oy /Ob2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# SUBTRACT BASE CPP /Ox /Oa /Ow /Og /Os
|
||||
# ADD CPP /nologo /MD /W3 /GX /Zi /Ot /Oi /Oy /Ob2 /I "C:\Dev\IPv6Kit\inc\\" /I "C:\Dev\zlib\\" /I "C:\Dev\openssl\include" /I "C:\Dev\Winhttrack" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "HTS_ANALYSTE_CONSOLE" /FAcs /FR /YX /FD /Zm200 /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 wsock32.lib /nologo /subsystem:console /machine:I386 /out:"c:\temp\httrack.exe"
|
||||
# SUBTRACT BASE LINK32 /verbose
|
||||
# ADD LINK32 wsock32.lib libhttrack.lib /nologo /subsystem:console /debug /machine:I386 /out:"L:\HTTrack\httrack\httrack.exe" /libpath:"C:\Dev\openssl\lib" /libpath:"C:\Dev\zlib\dll32" /libpath:"C:\Dev\openssl\lib\out32dll"
|
||||
# SUBTRACT LINK32 /verbose
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "httrack - Win32 Release"
|
||||
# Name "httrack - Win32 Debug"
|
||||
# Name "httrack - Win32 Release avec debug"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=httrack.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=httrack.h
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
||||
@@ -1,44 +0,0 @@
|
||||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "httrack"=.\httrack.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name libhttrack
|
||||
End Project Dependency
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "libhttrack"=.\libhttrack\libhttrack.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
5
src/httrack.rc
Normal file
5
src/httrack.rc
Normal file
@@ -0,0 +1,5 @@
|
||||
// Version resource for httrack.exe, the command line program. See version.rc.
|
||||
#define VER_FILE_DESCRIPTION "HTTrack Website Copier (command line)"
|
||||
#define VER_ORIGINAL_FILENAME "httrack.exe"
|
||||
#define VER_FILETYPE VFT_APP
|
||||
#include "version.rc"
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user