Compare commits
34 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
77d03052a6 | ||
|
|
628fc70727 | ||
|
|
7ff60e9de7 | ||
|
|
4588831dcd | ||
|
|
adbc46a5b8 | ||
|
|
249b96b975 | ||
|
|
d8402d7ad2 | ||
|
|
b268caa220 | ||
|
|
fb59dd6aba | ||
|
|
ef100363a7 | ||
|
|
c3e1a202c1 | ||
|
|
f55f68c94e | ||
|
|
749de004c7 | ||
|
|
09e3e1f62b | ||
|
|
4364e6c93e | ||
|
|
35319c05be | ||
|
|
e4fbe856e5 | ||
|
|
4f49eec86b | ||
|
|
f8ed3e771f | ||
|
|
4231a141d3 | ||
|
|
314ee45350 | ||
|
|
54d93200a4 | ||
|
|
6e98e33495 | ||
|
|
67c4668a3b | ||
|
|
e6015e29bb | ||
|
|
ba53bca32e | ||
|
|
5b59cdb159 | ||
|
|
c520d81f6b | ||
|
|
0748fa44e9 | ||
|
|
0ced83ccfc | ||
|
|
171ffb0754 | ||
|
|
e12fe63246 | ||
|
|
ff266a0e61 | ||
|
|
dfc0efff3a |
2
.github/workflows/appstream-network.yml
vendored
@@ -22,7 +22,7 @@ jobs:
|
||||
- name: Install appstreamcli
|
||||
run: |
|
||||
set -euo pipefail
|
||||
sudo apt-get update
|
||||
sudo apt-get update || true # a third-party source in the runner image can 403 (#1097)
|
||||
sudo apt-get install -y --no-install-recommends appstream
|
||||
appstreamcli --version
|
||||
|
||||
|
||||
94
.github/workflows/ci.yml
vendored
@@ -38,7 +38,7 @@ jobs:
|
||||
- name: Install build dependencies
|
||||
run: |
|
||||
set -euo pipefail
|
||||
sudo apt-get update
|
||||
sudo apt-get update || true # a third-party source in the runner image can 403 (#1097)
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
build-essential clang autoconf automake libtool autoconf-archive \
|
||||
zlib1g-dev libssl-dev libbrotli-dev libzstd-dev \
|
||||
@@ -80,6 +80,27 @@ jobs:
|
||||
- name: Build
|
||||
run: make -j"$(nproc)"
|
||||
|
||||
# FTP_PASV is 1 in every build, so #if !FTP_PASV never reaches a compiler
|
||||
# and rots unnoticed (#1091). Compiling is all this proves; nothing runs it.
|
||||
- name: Compile the FTP active-mode branch
|
||||
run: |
|
||||
set -euo pipefail
|
||||
objs="src/libhttrack_la-htsftp.lo src/libhttrack_la-htsftp.o src/.libs/libhttrack_la-htsftp.o"
|
||||
# accept() marks active-mode code: absent from the object Build made,
|
||||
# present below. One-sided, it passes on a file that ignored the define.
|
||||
syms=$(nm --undefined-only src/.libs/libhttrack_la-htsftp.o)
|
||||
if grep -qw accept <<<"$syms"; then
|
||||
echo "::error::accept() is reachable with FTP_PASV=1; the marker no longer discriminates"
|
||||
exit 1
|
||||
fi
|
||||
rm -f $objs
|
||||
# Through CC: overriding CPPFLAGS would drop configure's
|
||||
# -D_FORTIFY_SOURCE and the object-size warnings that come with it.
|
||||
make -C src libhttrack_la-htsftp.lo CC="$CC -DFTP_PASV=0 -Werror"
|
||||
syms=$(nm --undefined-only src/.libs/libhttrack_la-htsftp.o)
|
||||
grep -qw accept <<<"$syms" || { echo "::error::-DFTP_PASV=0 built no active-mode code"; exit 1; }
|
||||
rm -f $objs
|
||||
|
||||
# A backstop only: tests/test-timeout.sh bounds each test, and a healthy run
|
||||
# is a minute here, two on macOS. Without it a stall ran to the job's 6h default.
|
||||
- name: Test
|
||||
@@ -108,7 +129,7 @@ jobs:
|
||||
- name: Install build dependencies
|
||||
run: |
|
||||
set -euo pipefail
|
||||
sudo apt-get update
|
||||
sudo apt-get update || true # a third-party source in the runner image can 403 (#1097)
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
build-essential autoconf automake libtool autoconf-archive \
|
||||
zlib1g-dev libssl-dev libbrotli-dev libzstd-dev
|
||||
@@ -138,6 +159,48 @@ jobs:
|
||||
if: failure()
|
||||
run: cat tests/test-suite.log 2>/dev/null || true
|
||||
|
||||
# Reproduces the buildds that refuse TEST-NET-1 instead of dropping it, where
|
||||
# every fixture needing a stalled connect must skip rather than fail (#1108).
|
||||
hostile-network:
|
||||
name: build (network refuses TEST-NET-1)
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Install build dependencies
|
||||
run: |
|
||||
set -euo pipefail
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
build-essential autoconf automake libtool autoconf-archive \
|
||||
zlib1g-dev libssl-dev libbrotli-dev libzstd-dev iproute2
|
||||
|
||||
- name: Configure
|
||||
run: |
|
||||
set -euo pipefail
|
||||
autoreconf -fi
|
||||
./configure
|
||||
|
||||
- name: Build
|
||||
run: make -j"$(nproc)"
|
||||
|
||||
- name: Test on a network that refuses TEST-NET-1
|
||||
timeout-minutes: 20
|
||||
run: |
|
||||
set -euo pipefail
|
||||
jobs=$(( $(nproc) * 2 )); [ "$jobs" -le 16 ] || jobs=16
|
||||
tools/hostile-net.sh make check -j"$jobs"
|
||||
# A refusal landing before connect() returns skips on the older probe
|
||||
# instead, leaving the settle this leg exists to guard unrun.
|
||||
cat tests/246_engine-connect-stop.log
|
||||
grep -q 'within 500 ms' tests/246_engine-connect-stop.log
|
||||
|
||||
- name: Print the test log on failure
|
||||
if: failure()
|
||||
run: cat tests/test-suite.log 2>/dev/null || true
|
||||
|
||||
# The Ubuntu buildds run a development release every runner above is well behind.
|
||||
# That gap is what shipped 3.49.18 broken on every Ubuntu architecture but
|
||||
# riscv64, when 25.10 made uutils the default coreutils (#1042).
|
||||
@@ -292,7 +355,7 @@ jobs:
|
||||
- name: Install build dependencies
|
||||
run: |
|
||||
set -euo pipefail
|
||||
sudo apt-get update
|
||||
sudo apt-get update || true # a third-party source in the runner image can 403 (#1097)
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
build-essential autoconf automake libtool autoconf-archive \
|
||||
zlib1g-dev libssl-dev libbrotli-dev libzstd-dev
|
||||
@@ -401,7 +464,7 @@ jobs:
|
||||
run: |
|
||||
set -euo pipefail
|
||||
sudo dpkg --add-architecture i386
|
||||
sudo apt-get update
|
||||
sudo apt-get update || true # a third-party source in the runner image can 403 (#1097)
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
build-essential gcc-multilib autoconf automake libtool \
|
||||
autoconf-archive zlib1g-dev:i386 libssl-dev:i386 \
|
||||
@@ -444,7 +507,7 @@ jobs:
|
||||
- name: Install build dependencies
|
||||
run: |
|
||||
set -euo pipefail
|
||||
sudo apt-get update
|
||||
sudo apt-get update || true # a third-party source in the runner image can 403 (#1097)
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
build-essential autoconf automake libtool autoconf-archive \
|
||||
zlib1g-dev libssl-dev libbrotli-dev libzstd-dev
|
||||
@@ -499,7 +562,7 @@ jobs:
|
||||
- name: Install build dependencies
|
||||
run: |
|
||||
set -euo pipefail
|
||||
sudo apt-get update
|
||||
sudo apt-get update || true # a third-party source in the runner image can 403 (#1097)
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
build-essential clang autoconf automake libtool autoconf-archive \
|
||||
zlib1g-dev
|
||||
@@ -548,7 +611,7 @@ jobs:
|
||||
- name: Install build dependencies
|
||||
run: |
|
||||
set -euo pipefail
|
||||
sudo apt-get update
|
||||
sudo apt-get update || true # a third-party source in the runner image can 403 (#1097)
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
build-essential clang autoconf automake libtool autoconf-archive \
|
||||
zlib1g-dev libssl-dev libbrotli-dev libzstd-dev
|
||||
@@ -584,7 +647,7 @@ jobs:
|
||||
- name: Install build dependencies
|
||||
run: |
|
||||
set -euo pipefail
|
||||
sudo apt-get update
|
||||
sudo apt-get update || true # a third-party source in the runner image can 403 (#1097)
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
build-essential clang autoconf automake libtool autoconf-archive \
|
||||
zlib1g-dev libssl-dev libbrotli-dev libzstd-dev
|
||||
@@ -614,7 +677,7 @@ jobs:
|
||||
- name: Install build dependencies (no libssl)
|
||||
run: |
|
||||
set -euo pipefail
|
||||
sudo apt-get update
|
||||
sudo apt-get update || true # a third-party source in the runner image can 403 (#1097)
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
build-essential autoconf automake libtool autoconf-archive zlib1g-dev
|
||||
|
||||
@@ -651,7 +714,7 @@ jobs:
|
||||
- name: Install build dependencies
|
||||
run: |
|
||||
set -euo pipefail
|
||||
sudo apt-get update
|
||||
sudo apt-get update || true # a third-party source in the runner image can 403 (#1097)
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
build-essential autoconf automake libtool autoconf-archive \
|
||||
zlib1g-dev libssl-dev libbrotli-dev libzstd-dev
|
||||
@@ -730,7 +793,7 @@ jobs:
|
||||
- name: Install build dependencies
|
||||
run: |
|
||||
set -euo pipefail
|
||||
sudo apt-get update
|
||||
sudo apt-get update || true # a third-party source in the runner image can 403 (#1097)
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
build-essential autoconf automake libtool autoconf-archive \
|
||||
zlib1g-dev libssl-dev libbrotli-dev libzstd-dev
|
||||
@@ -790,17 +853,14 @@ jobs:
|
||||
src/webhttrack.in
|
||||
tests/*.sh
|
||||
tests/*.test
|
||||
tools/macos-app.sh
|
||||
tools/macos-bundle.sh
|
||||
tools/macos-release.sh
|
||||
tools/mkdeb.sh
|
||||
tools/*.sh
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
|
||||
- name: Install linters
|
||||
run: |
|
||||
set -euo pipefail
|
||||
sudo apt-get update
|
||||
sudo apt-get update || true # a third-party source in the runner image can 403 (#1097)
|
||||
# noble ships shfmt 3.8.0 (universe), matching the pinned local dev
|
||||
# version; use it rather than fetching a release binary from github.com.
|
||||
sudo apt-get install -y --no-install-recommends shellcheck shfmt appstream \
|
||||
@@ -859,7 +919,7 @@ jobs:
|
||||
| sudo tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc >/dev/null
|
||||
echo "deb http://apt.llvm.org/noble/ llvm-toolchain-noble-19 main" \
|
||||
| sudo tee /etc/apt/sources.list.d/llvm-19.list >/dev/null
|
||||
sudo apt-get update
|
||||
sudo apt-get update || true # a third-party source in the runner image can 403 (#1097)
|
||||
sudo apt-get install -y --no-install-recommends clang-format-19
|
||||
# The clang-format-19 package ships the git-clang-format driver;
|
||||
# expose it unsuffixed so "git clang-format" finds it.
|
||||
|
||||
2
.github/workflows/codeql.yml
vendored
@@ -33,7 +33,7 @@ jobs:
|
||||
- name: Install build dependencies
|
||||
run: |
|
||||
set -euo pipefail
|
||||
sudo apt-get update
|
||||
sudo apt-get update || true # a third-party source in the runner image can 403 (#1097)
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
build-essential autoconf automake libtool autoconf-archive \
|
||||
zlib1g-dev libssl-dev
|
||||
|
||||
12
.github/workflows/screenshots.yml
vendored
@@ -34,7 +34,7 @@ jobs:
|
||||
- name: Install build dependencies
|
||||
run: |
|
||||
set -euo pipefail
|
||||
sudo apt-get update
|
||||
sudo apt-get update || true # a third-party source in the runner image can 403 (#1097)
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
build-essential autoconf automake libtool autoconf-archive \
|
||||
zlib1g-dev libssl-dev libbrotli-dev libzstd-dev
|
||||
@@ -52,6 +52,15 @@ jobs:
|
||||
pip install --quiet playwright
|
||||
playwright install --with-deps chromium
|
||||
|
||||
# The address is on screen in the wizard panes and names the mirror folder,
|
||||
# so the crawl needs a presentable host rather than 127.0.0.1 and a random
|
||||
# port. example.com is reserved for documentation (RFC 2606).
|
||||
- name: Let the crawl address a named site on port 80
|
||||
run: |
|
||||
set -euo pipefail
|
||||
echo "127.0.0.1 www.example.com" | sudo tee -a /etc/hosts
|
||||
sudo sysctl -w net.ipv4.ip_unprivileged_port_start=80 # bind 80 unprivileged
|
||||
|
||||
- name: Capture
|
||||
env:
|
||||
LANGN: ${{ inputs.lang || '1' }}
|
||||
@@ -61,6 +70,7 @@ jobs:
|
||||
# --root is the dist root; the source tree already holds every piece
|
||||
# htsserver reads, so this needs no install.
|
||||
python3 tools/screenshot-walk.py --htsserver src/htsserver --root . \
|
||||
--site-host www.example.com --site-port 80 \
|
||||
--lang "$LANGN" --scale "$SCALE" --out shots
|
||||
|
||||
- name: Upload the screens
|
||||
|
||||
@@ -46,6 +46,12 @@ the operational checklist: toolchain, invariants, and how to ship a change.
|
||||
platform-specific: GNU `tail | head -c 3` survives, the uutils coreutils leg
|
||||
turns the same line into exit 141 with no output at all. Let the reader seek
|
||||
instead: `od -An -c -j <skip> -N <len> file`.
|
||||
- Never assert a fault by signal *number*: SIGBUS is 7 on x86, arm, powerpc and
|
||||
s390x but 10 on hppa, alpha, mips and sparc. Map it with `kill -l "$n"`.
|
||||
- A fixture that needs a host to stay silent must settle (500ms), re-probe every
|
||||
socket, and SKIP when one answered: the powerpc and ppc64 buildds refuse
|
||||
TEST-NET-1 milliseconds after `connect()` where runners drop it.
|
||||
`tools/hostile-net.sh` runs a command on such a network.
|
||||
|
||||
## Hard invariants
|
||||
- **Generated autotools files are NOT in git.** `configure`, every
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
AC_PREREQ([2.71])
|
||||
|
||||
AC_INIT([httrack], [3.49.19], [roche+packaging@httrack.com], [httrack], [http://www.httrack.com/])
|
||||
AC_INIT([httrack], [3.49.20], [roche+packaging@httrack.com], [httrack], [http://www.httrack.com/])
|
||||
AC_COPYRIGHT([
|
||||
HTTrack Website Copier, Offline Browser for Windows and Unix
|
||||
Copyright (C) 1998-2015 Xavier Roche and other contributors
|
||||
@@ -29,6 +29,8 @@ AC_CONFIG_SRCDIR(src/httrack.c)
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AC_CONFIG_HEADERS(config.h)
|
||||
AM_INIT_AUTOMAKE([subdir-objects])
|
||||
# 3:13:0: revision-only bump. htsstrings.h's StringRoomTotal grew saturation in
|
||||
# its macro body; no installed struct moved and no export came or went.
|
||||
# 3:12:0: revision-only bump. httrackp gained a tail field (singlefile_state) and
|
||||
# htsopt.h added volatile qualifiers; no layout moved, nothing went away.
|
||||
# 3:11:0: revision-only bump. #1001 moved SOCaddr_inetntoa_ out of htsnet.h, adding
|
||||
@@ -42,7 +44,7 @@ AM_INIT_AUTOMAKE([subdir-objects])
|
||||
# moves nothing). Soname stays .so.3: HTTrackQt is the only consumer of the installed
|
||||
# headers, so a libhttrack4 rename isn't worth it.
|
||||
# (3:0:0 was the htsblk mime-buffer widening, the ABI break that moved .so.2 -> .so.3.)
|
||||
VERSION_INFO="3:12:0"
|
||||
VERSION_INFO="3:13:0"
|
||||
AM_MAINTAINER_MODE
|
||||
AC_USE_SYSTEM_EXTENSIONS
|
||||
|
||||
|
||||
10
debian/changelog
vendored
@@ -1,3 +1,13 @@
|
||||
httrack (3.49.20-1) unstable; urgency=medium
|
||||
|
||||
* New upstream release: an off-site link that looked like a file could pull
|
||||
in the whole foreign site, and a mirror asked to stop while receiving over
|
||||
FTP hung; full list in history.txt. The documentation was also refreshed.
|
||||
* debian/copyright: record the League Spartan webfont the documentation now
|
||||
bundles (OFL-1.1).
|
||||
|
||||
-- Xavier Roche <xavier@debian.org> Mon, 10 Aug 2026 21:08:40 +0200
|
||||
|
||||
httrack (3.49.19-1) unstable; urgency=medium
|
||||
|
||||
* New upstream release: mostly FTP fixes, plus stack-overflow, mirror
|
||||
|
||||
95
debian/copyright
vendored
@@ -44,6 +44,13 @@ License: FSFAP
|
||||
permitted in any medium without royalty provided the copyright notice and
|
||||
this notice are preserved. This file is offered as-is, without any warranty.
|
||||
|
||||
Files: html/fonts/*
|
||||
Copyright: 2020 The League Spartan Project Authors
|
||||
License: OFL-1.1
|
||||
Comment:
|
||||
The woff2 is the latin subset at weight 700, as served by Google Fonts.
|
||||
Upstream declares no Reserved Font Name, so the subset keeps the family name.
|
||||
|
||||
Files: debian/*
|
||||
Copyright: 2002-2026 Xavier Roche <xavier@debian.org>
|
||||
License: GPL-3+
|
||||
@@ -106,3 +113,91 @@ License: BSD-3-clause
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
License: OFL-1.1
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
.
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
.
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
.
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
.
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
.
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
.
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
.
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
.
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
.
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
.
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
.
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
.
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
.
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
.
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
.
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
|
||||
13
history.txt
@@ -4,6 +4,19 @@ HTTrack Website Copier release history:
|
||||
|
||||
This file lists all changes and fixes that have been made for HTTrack
|
||||
|
||||
3.49-20
|
||||
+ Fixed: a link to another host whose name looked like a file was scanned as a page, so one link could mirror the whole foreign site on the referring page's depth budget (#121)
|
||||
+ Fixed: a size-bounded filter built both of its filter URLs wrong when the path had no leading slash (#1095)
|
||||
+ Fixed: a mirror told to quit while an FTP file was being received announced the exit and then waited forever on that slot (#1106)
|
||||
+ Fixed: stopping an FTP transfer closed its data socket twice, so a threaded crawl could lose another worker's connection (#1090)
|
||||
+ Fixed: WebHTTrack's welcome page opened its language menu blank instead of marking the language in use (#1084)
|
||||
+ Fixed: two suite tests failed on the hppa, powerpc and ppc64 Debian buildds, holding the package back on those ports (#1108)
|
||||
+ Fixed: a growable string could wrap its capacity to zero instead of saturating (#1062)
|
||||
+ Changed: the macOS disk image carries its architecture in its name, so an Intel user can tell before downloading that the build is for Apple Silicon (#1083)
|
||||
+ Changed: refreshed the GUI guide, its screenshots, the documentation typography and the footer contrast
|
||||
+ Changed: settled on one spelling of the product name across the docs and the site
|
||||
+ Changed: multiple internal hardening, build, test and CI improvements
|
||||
|
||||
3.49-19
|
||||
+ Fixed: an over-long user name in an ftp:// URL was truncated at the credential boundary, so the login went to a different account (#1032)
|
||||
+ Fixed: an over-long FTP path or host name aborted the process instead of failing that one link (#1019)
|
||||
|
||||
@@ -4,6 +4,7 @@ HelpHtmldir = $(htmldir)
|
||||
HelpHtmlimgdir = $(HelpHtmldir)/img
|
||||
HelpHtmldivdir = $(HelpHtmldir)/div
|
||||
HelpHtmlimagesdir = $(HelpHtmldir)/images
|
||||
HelpHtmlfontsdir = $(HelpHtmldir)/fonts
|
||||
HelpHtmlTxtdir = $(HelpHtmldir)
|
||||
WebHtmldir = $(HelpHtmldir)/server
|
||||
WebHtmlimagesdir = $(HelpHtmldir)/server/images
|
||||
@@ -27,6 +28,8 @@ HelpHtml_DATA = $(srcdir)/*.html $(srcdir)/*.js $(srcdir)/*.css
|
||||
HelpHtmldiv_DATA = div/search.sh
|
||||
HelpHtmlimg_DATA = $(srcdir)/img/*
|
||||
HelpHtmlimages_DATA = $(srcdir)/images/*
|
||||
# doc.css reaches the woff2 by a relative URL, so it installs beside the pages.
|
||||
HelpHtmlfonts_DATA = $(srcdir)/fonts/*
|
||||
HelpHtmlTxt_DATA = ../greetings.txt ../history.txt ../license.txt
|
||||
WebHtml_DATA = $(srcdir)/server/*.html $(srcdir)/server/*.js $(srcdir)/server/*.css
|
||||
WebHtmlimages_DATA = $(srcdir)/server/images/*
|
||||
@@ -45,6 +48,7 @@ VFolderEntry_DATA = $(srcdir)/server/div/*.desktop
|
||||
MetaInfo_DATA = $(srcdir)/server/div/*.metainfo.xml
|
||||
|
||||
EXTRA_DIST = $(HelpHtml_DATA) $(HelpHtmlimg_DATA) $(HelpHtmlimages_DATA) \
|
||||
$(HelpHtmlfonts_DATA) \
|
||||
$(HelpHtmldiv_DATA) $(WebHtml_DATA) $(WebHtmlimages_DATA) \
|
||||
$(WebPixmap_DATA) $(WebIcon16x16_DATA) $(WebIcon32x32_DATA) $(WebIcon48x48_DATA) \
|
||||
$(WebIcon64x64_DATA) $(WebIcon128x128_DATA) $(WebIcon256x256_DATA) \
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
<header class="masthead">
|
||||
<img src="images/wordmark.svg" width="400" height="36" alt="HTTrack Website Copier">
|
||||
<div class="tagline">Open Source offline browser</div>
|
||||
<div class="tagline">Free software offline browser</div>
|
||||
</header>
|
||||
|
||||
<div class="wrap">
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
<header class="masthead">
|
||||
<img src="images/wordmark.svg" width="400" height="36" alt="HTTrack Website Copier">
|
||||
<div class="tagline">Open Source offline browser</div>
|
||||
<div class="tagline">Free software offline browser</div>
|
||||
</header>
|
||||
|
||||
<div class="wrap">
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
<header class="masthead">
|
||||
<img src="images/wordmark.svg" width="400" height="36" alt="HTTrack Website Copier">
|
||||
<div class="tagline">Open Source offline browser</div>
|
||||
<div class="tagline">Free software offline browser</div>
|
||||
</header>
|
||||
|
||||
<div class="wrap">
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
<header class="masthead">
|
||||
<img src="images/wordmark.svg" width="400" height="36" alt="HTTrack Website Copier">
|
||||
<div class="tagline">Open Source offline browser</div>
|
||||
<div class="tagline">Free software offline browser</div>
|
||||
</header>
|
||||
|
||||
<div class="wrap">
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
<header class="masthead">
|
||||
<img src="images/wordmark.svg" width="400" height="36" alt="HTTrack Website Copier">
|
||||
<div class="tagline">Open Source offline browser</div>
|
||||
<div class="tagline">Free software offline browser</div>
|
||||
</header>
|
||||
|
||||
<div class="wrap">
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
<header class="masthead">
|
||||
<img src="images/wordmark.svg" width="400" height="36" alt="HTTrack Website Copier">
|
||||
<div class="tagline">Open Source offline browser</div>
|
||||
<div class="tagline">Free software offline browser</div>
|
||||
</header>
|
||||
|
||||
<div class="wrap">
|
||||
|
||||
22
html/doc.css
@@ -32,6 +32,20 @@
|
||||
}
|
||||
}
|
||||
|
||||
/* Additions stay out of the palette block above: it is kept byte-identical with the website's. */
|
||||
:root {
|
||||
--body-font: system-ui, -apple-system, "Segoe UI", Roboto, "Trebuchet MS", Verdana, sans-serif;
|
||||
}
|
||||
|
||||
/* Relative URL: the docs are read from an installed directory too. */
|
||||
@font-face {
|
||||
font-family: "League Spartan";
|
||||
src: url(fonts/league-spartan-700-latin.woff2) format("woff2");
|
||||
font-weight: 700;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
* { box-sizing: border-box; }
|
||||
|
||||
/* The plain declaration before each var() is what IE11 gets: it drops the
|
||||
@@ -44,6 +58,7 @@ body {
|
||||
color: #111;
|
||||
color: var(--ink);
|
||||
font: 1em/1.6 "Trebuchet MS", Verdana, system-ui, -apple-system, "Segoe UI", sans-serif;
|
||||
font-family: var(--body-font);
|
||||
}
|
||||
|
||||
/* ---- page frame ---- */
|
||||
@@ -72,7 +87,6 @@ body {
|
||||
/* A one-line label has no use for the body's prose leading. */
|
||||
line-height: 1;
|
||||
padding: .3rem .4rem;
|
||||
margin-top: .4rem;
|
||||
}
|
||||
|
||||
.wrap {
|
||||
@@ -106,10 +120,11 @@ body {
|
||||
.wrap.solo { display: block; }
|
||||
}
|
||||
|
||||
/* Colour inherited: nothing lighter than --ink reaches 4.5:1 on the --field
|
||||
this sits on, and at .8em it is small text. */
|
||||
footer {
|
||||
max-width: 68rem;
|
||||
margin: .5rem auto 0;
|
||||
color: #eef;
|
||||
font-size: .8em;
|
||||
}
|
||||
|
||||
@@ -121,6 +136,9 @@ footer {
|
||||
|
||||
h2, h3 { scroll-margin-top: 1rem; }
|
||||
|
||||
/* Top two levels only: a display face reads worse than the system font over prose. */
|
||||
h1, h2 { font-family: "League Spartan", var(--body-font); font-weight: 700; }
|
||||
|
||||
h1 { font-size: 1.9em; margin: 0 0 .3em; line-height: 1.2; }
|
||||
h2 { font-size: 1.45em; margin: 2.5em 0 .5em; padding-bottom: .2em; border-bottom: 2px solid var(--rule); }
|
||||
h3 { font-size: 1.15em; margin: 2em 0 .4em; }
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
<header class="masthead">
|
||||
<img src="images/wordmark.svg" width="400" height="36" alt="HTTrack Website Copier">
|
||||
<div class="tagline">Open Source offline browser</div>
|
||||
<div class="tagline">Free software offline browser</div>
|
||||
</header>
|
||||
|
||||
<div class="wrap">
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
<header class="masthead">
|
||||
<img src="images/wordmark.svg" width="400" height="36" alt="HTTrack Website Copier">
|
||||
<div class="tagline">Open Source offline browser</div>
|
||||
<div class="tagline">Free software offline browser</div>
|
||||
</header>
|
||||
|
||||
<div class="wrap">
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
<header class="masthead">
|
||||
<img src="images/wordmark.svg" width="400" height="36" alt="HTTrack Website Copier">
|
||||
<div class="tagline">Open Source offline browser</div>
|
||||
<div class="tagline">Free software offline browser</div>
|
||||
</header>
|
||||
|
||||
<div class="wrap">
|
||||
|
||||
93
html/fonts/OFL.txt
Normal file
@@ -0,0 +1,93 @@
|
||||
Copyright 2020 The League Spartan Project Authors (https://github.com/theleagueof/league-spartan)
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
https://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
BIN
html/fonts/league-spartan-700-latin.woff2
Normal file
@@ -13,12 +13,14 @@
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- doc-chrome:masthead -->
|
||||
<a class="skip" href="#main">Skip to content</a>
|
||||
|
||||
<header class="masthead">
|
||||
<img src="images/wordmark.svg" width="400" height="36" alt="HTTrack Website Copier">
|
||||
<div class="tagline">Open Source offline browser</div>
|
||||
<div class="tagline">Free software offline browser</div>
|
||||
</header>
|
||||
<!-- /doc-chrome:masthead -->
|
||||
|
||||
<div class="wrap">
|
||||
|
||||
@@ -120,13 +122,13 @@ data-for="droid">Tap <b>Next</b></span> to create a project, or open one you alr
|
||||
|
||||
<figure>
|
||||
<img data-for="win" src="img/guide-win-start.png" alt="WinHTTrack welcome pane" width="1040" height="744">
|
||||
<img data-for="web" src="img/guide-web-start.png" alt="WebHTTrack welcome page" width="1024" height="388">
|
||||
<img data-for="web" src="img/guide-web-start.png" alt="WebHTTrack welcome page" width="1024" height="387">
|
||||
<img data-for="droid" src="img/guide-droid-start.png" alt="HTTrack for Android welcome screen" width="600" height="1300">
|
||||
<figcaption>The welcome screen.</figcaption>
|
||||
</figure>
|
||||
|
||||
<p class="note" data-for="web">The language dropdown starts blank on purpose: its first entry
|
||||
means "leave the interface as it is". Pick a language only if you want to change it.</p>
|
||||
<p class="note" data-for="web">The dropdown shows the language the interface is already in.
|
||||
Picking another one reloads the page in it.</p>
|
||||
|
||||
<p class="note" data-for="web">On macOS, <code>brew install httrack</code> installs WebHTTrack
|
||||
alongside the command line tool. Open <b>HTTrack.app</b> if you have it, or run
|
||||
@@ -141,7 +143,7 @@ together in the list.</p>
|
||||
|
||||
<figure>
|
||||
<img data-for="win" src="img/guide-win-project-name.png" alt="WinHTTrack project name, category and base path" width="1040" height="744">
|
||||
<img data-for="web" src="img/guide-web-project-name.png" alt="WebHTTrack project name, category and base path" width="1024" height="346">
|
||||
<img data-for="web" src="img/guide-web-project-name.png" alt="WebHTTrack project name, category and base path" width="1024" height="345">
|
||||
<img data-for="droid" src="img/guide-droid-project-name.png" alt="Android project name, category and base path" width="600" height="1300">
|
||||
<figcaption>Project name, category, and where the files go.</figcaption>
|
||||
</figure>
|
||||
@@ -160,7 +162,7 @@ keep their links to each other.</p>
|
||||
|
||||
<figure>
|
||||
<img data-for="win" src="img/guide-win-project-setup.png" alt="WinHTTrack action and web addresses" width="1040" height="744">
|
||||
<img data-for="web" src="img/guide-web-project-setup.png" alt="WebHTTrack action and web addresses" width="1024" height="496">
|
||||
<img data-for="web" src="img/guide-web-project-setup.png" alt="WebHTTrack action and web addresses" width="1024" height="495">
|
||||
<img data-for="droid" src="img/guide-droid-project-setup.png" alt="Android web address and action" width="600" height="1300">
|
||||
<figcaption>The addresses to copy, and what to do with them.</figcaption>
|
||||
</figure>
|
||||
@@ -215,7 +217,7 @@ port, you point your browser at it as a proxy and click the link or the submit b
|
||||
usual, and the address the browser asks for is added to the project.</p>
|
||||
|
||||
<figure data-for="web">
|
||||
<img data-for="web" src="img/guide-web-add-url.png" alt="WebHTTrack add-a-URL dialog" width="1024" height="634">
|
||||
<img data-for="web" src="img/guide-web-add-url.png" alt="WebHTTrack add-a-URL dialog" width="1024" height="600">
|
||||
<figcaption>Adding a single address, with an optional login.</figcaption>
|
||||
</figure>
|
||||
|
||||
@@ -244,7 +246,7 @@ mirror straight away.</p>
|
||||
|
||||
<figure data-for="win web">
|
||||
<img data-for="win" src="img/guide-win-ready.png" alt="WinHTTrack connection settings before starting" width="1040" height="744">
|
||||
<img data-for="web" src="img/guide-web-ready.png" alt="WebHTTrack ready to start" width="1024" height="508">
|
||||
<img data-for="web" src="img/guide-web-ready.png" alt="WebHTTrack ready to start" width="1024" height="489">
|
||||
<figcaption>The last screen before the mirror runs.</figcaption>
|
||||
</figure>
|
||||
|
||||
@@ -277,7 +279,7 @@ mirrored pages are rewritten to point at each other, so it browses offline in an
|
||||
|
||||
<figure>
|
||||
<img data-for="win" src="img/guide-win-finished.png" alt="WinHTTrack mirror complete" width="1040" height="744">
|
||||
<img data-for="web" src="img/guide-web-finished.png" alt="WebHTTrack mirror complete" width="1024" height="487">
|
||||
<img data-for="web" src="img/guide-web-finished.png" alt="WebHTTrack mirror complete" width="1024" height="486">
|
||||
<img data-for="droid" src="img/guide-droid-finished.png" alt="Android mirror complete" width="600" height="1300">
|
||||
<figcaption>Done.</figcaption>
|
||||
</figure>
|
||||
@@ -441,7 +443,7 @@ bottom are the ones that keep you welcome.</p>
|
||||
|
||||
<figure>
|
||||
<img data-for="win" src="img/guide-win-opt-flow-control.png" alt="WinHTTrack Flow Control tab" width="524" height="448">
|
||||
<img data-for="web" src="img/guide-web-opt-flow-control.png" alt="WebHTTrack Flow Control tab" width="1024" height="910">
|
||||
<img data-for="web" src="img/guide-web-opt-flow-control.png" alt="WebHTTrack Flow Control tab" width="1024" height="862">
|
||||
<img data-for="droid" src="img/guide-droid-opt-flow-control.png" alt="Android Flow Control tab" width="600" height="1300">
|
||||
</figure>
|
||||
|
||||
@@ -484,7 +486,7 @@ bottom are the ones that keep you welcome.</p>
|
||||
|
||||
<figure>
|
||||
<img data-for="win" src="img/guide-win-opt-links.png" alt="WinHTTrack Links tab" width="524" height="448">
|
||||
<img data-for="web" src="img/guide-web-opt-links.png" alt="WebHTTrack Links tab" width="1024" height="781">
|
||||
<img data-for="web" src="img/guide-web-opt-links.png" alt="WebHTTrack Links tab" width="1024" height="749">
|
||||
<img data-for="droid" src="img/guide-droid-opt-links.png" alt="Android Links tab" width="600" height="1300">
|
||||
</figure>
|
||||
|
||||
@@ -521,7 +523,7 @@ bottom are the ones that keep you welcome.</p>
|
||||
|
||||
<figure>
|
||||
<img data-for="win" src="img/guide-win-opt-build.png" alt="WinHTTrack Build tab" width="524" height="448">
|
||||
<img data-for="web" src="img/guide-web-opt-build.png" alt="WebHTTrack Build tab" width="1024" height="986">
|
||||
<img data-for="web" src="img/guide-web-opt-build.png" alt="WebHTTrack Build tab" width="1024" height="976">
|
||||
<img data-for="droid" src="img/guide-droid-opt-build.png" alt="Android Build tab" width="600" height="1300">
|
||||
</figure>
|
||||
|
||||
@@ -587,7 +589,7 @@ bottom are the ones that keep you welcome.</p>
|
||||
|
||||
<figure>
|
||||
<img data-for="win" src="img/guide-win-opt-browser-id.png" alt="WinHTTrack Browser ID tab" width="524" height="448">
|
||||
<img data-for="web" src="img/guide-web-opt-browser-id.png" alt="WebHTTrack Browser ID tab" width="1024" height="706">
|
||||
<img data-for="web" src="img/guide-web-opt-browser-id.png" alt="WebHTTrack Browser ID tab" width="1024" height="654">
|
||||
<img data-for="droid" src="img/guide-droid-opt-browser-id.png" alt="Android Browser ID tab" width="600" height="1300">
|
||||
</figure>
|
||||
|
||||
@@ -627,7 +629,7 @@ bottom are the ones that keep you welcome.</p>
|
||||
|
||||
<figure>
|
||||
<img data-for="win" src="img/guide-win-opt-spider.png" alt="WinHTTrack Spider tab" width="524" height="448">
|
||||
<img data-for="web" src="img/guide-web-opt-spider.png" alt="WebHTTrack Spider tab" width="1024" height="1557">
|
||||
<img data-for="web" src="img/guide-web-opt-spider.png" alt="WebHTTrack Spider tab" width="1024" height="1541">
|
||||
<img data-for="droid" src="img/guide-droid-opt-spider.png" alt="Android Spider tab" width="600" height="1300">
|
||||
</figure>
|
||||
|
||||
@@ -714,7 +716,7 @@ bottom are the ones that keep you welcome.</p>
|
||||
|
||||
<figure>
|
||||
<img data-for="win" src="img/guide-win-opt-proxy.png" alt="WinHTTrack Proxy tab" width="524" height="448">
|
||||
<img data-for="web" src="img/guide-web-opt-proxy.png" alt="WebHTTrack Proxy tab" width="1024" height="762">
|
||||
<img data-for="web" src="img/guide-web-opt-proxy.png" alt="WebHTTrack Proxy tab" width="1024" height="760">
|
||||
<img data-for="droid" src="img/guide-droid-opt-proxy.png" alt="Android Proxy tab" width="600" height="1300">
|
||||
</figure>
|
||||
|
||||
@@ -751,7 +753,7 @@ bottom are the ones that keep you welcome.</p>
|
||||
|
||||
<figure>
|
||||
<img data-for="win" src="img/guide-win-opt-log-index-cache.png" alt="WinHTTrack Log, Index, Cache tab" width="524" height="448">
|
||||
<img data-for="web" src="img/guide-web-opt-log-index-cache.png" alt="WebHTTrack Log, Index, Cache tab" width="1024" height="1278">
|
||||
<img data-for="web" src="img/guide-web-opt-log-index-cache.png" alt="WebHTTrack Log, Index, Cache tab" width="1024" height="1266">
|
||||
<img data-for="droid" src="img/guide-droid-opt-log-index-cache.png" alt="Android Log, Index, Cache tab" width="600" height="1300">
|
||||
</figure>
|
||||
|
||||
@@ -850,7 +852,7 @@ bottom are the ones that keep you welcome.</p>
|
||||
|
||||
<figure>
|
||||
<img data-for="win" src="img/guide-win-opt-experts-only.png" alt="WinHTTrack Experts Only tab" width="524" height="448">
|
||||
<img data-for="web" src="img/guide-web-opt-experts-only.png" alt="WebHTTrack Experts Only tab" width="1024" height="1088">
|
||||
<img data-for="web" src="img/guide-web-opt-experts-only.png" alt="WebHTTrack Experts Only tab" width="1024" height="1085">
|
||||
<img data-for="droid" src="img/guide-droid-opt-experts-only.png" alt="Android Experts Only tab" width="600" height="1300">
|
||||
</figure>
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 49 KiB |
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 51 KiB |
|
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 110 KiB |
|
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 94 KiB |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 51 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 64 KiB |
|
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 82 KiB |
|
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 93 KiB |
|
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 72 KiB |
|
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 82 KiB |
|
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 83 KiB After Width: | Height: | Size: 97 KiB |
|
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 61 KiB |
|
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 85 KiB After Width: | Height: | Size: 98 KiB |
|
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 113 KiB |
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 8.9 KiB |
|
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 7.5 KiB |
|
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 7.4 KiB |
|
Before Width: | Height: | Size: 8.9 KiB After Width: | Height: | Size: 9.0 KiB |
|
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 7.0 KiB |
|
Before Width: | Height: | Size: 7.7 KiB After Width: | Height: | Size: 7.9 KiB |
|
Before Width: | Height: | Size: 7.8 KiB After Width: | Height: | Size: 8.0 KiB |
|
Before Width: | Height: | Size: 8.6 KiB After Width: | Height: | Size: 8.8 KiB |
|
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.5 KiB |
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 9.3 KiB After Width: | Height: | Size: 9.5 KiB |
|
Before Width: | Height: | Size: 8.5 KiB After Width: | Height: | Size: 8.6 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 13 KiB |
@@ -10,12 +10,14 @@
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- doc-chrome:masthead -->
|
||||
<a class="skip" href="#main">Skip to content</a>
|
||||
|
||||
<header class="masthead">
|
||||
<img src="images/wordmark.svg" width="400" height="36" alt="HTTrack Website Copier">
|
||||
<div class="tagline">Open Source offline browser</div>
|
||||
<div class="tagline">Free software offline browser</div>
|
||||
</header>
|
||||
<!-- /doc-chrome:masthead -->
|
||||
|
||||
<div class="wrap solo">
|
||||
<main id="main">
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
<header class="masthead">
|
||||
<img src="images/wordmark.svg" width="400" height="36" alt="HTTrack Website Copier">
|
||||
<div class="tagline">Open Source offline browser</div>
|
||||
<div class="tagline">Free software offline browser</div>
|
||||
</header>
|
||||
|
||||
<div class="wrap">
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
<header class="masthead">
|
||||
<img src="images/wordmark.svg" width="400" height="36" alt="HTTrack Website Copier">
|
||||
<div class="tagline">Open Source offline browser</div>
|
||||
<div class="tagline">Free software offline browser</div>
|
||||
</header>
|
||||
|
||||
<div class="wrap">
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
<header class="masthead">
|
||||
<img src="images/wordmark.svg" width="400" height="36" alt="HTTrack Website Copier">
|
||||
<div class="tagline">Open Source offline browser</div>
|
||||
<div class="tagline">Free software offline browser</div>
|
||||
</header>
|
||||
|
||||
<div class="wrap">
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
<header class="masthead">
|
||||
<img src="images/wordmark.svg" width="400" height="36" alt="HTTrack Website Copier">
|
||||
<div class="tagline">Open Source offline browser</div>
|
||||
<div class="tagline">Free software offline browser</div>
|
||||
</header>
|
||||
|
||||
<div class="wrap">
|
||||
|
||||
@@ -43,13 +43,29 @@
|
||||
</developer>
|
||||
<screenshots>
|
||||
<screenshot type="default">
|
||||
<caption>Choosing the addresses and options for a new mirror</caption>
|
||||
<image>https://www.httrack.com/html/images/screenshot_01b.jpg</image>
|
||||
<caption>Choosing which files a mirror includes</caption>
|
||||
<!-- A guide asset, so every screenshot reshoot refreshes this too.
|
||||
appstream-network.yml resolves the URL weekly if the name moves.
|
||||
Not a wizard pane: the walk crawls a loopback server, so every pane
|
||||
showing the address advertises 127.0.0.1 and an ephemeral port. -->
|
||||
<image>https://www.httrack.com/html/img/guide-web-opt-scan-rules.png</image>
|
||||
</screenshot>
|
||||
</screenshots>
|
||||
<content_rating type="oars-1.1"/>
|
||||
<!-- Newest first; tests/01_engine-version-macros.test enforces it. -->
|
||||
<releases>
|
||||
<release version="3.49.20" date="2026-08-10">
|
||||
<description>
|
||||
<ul>
|
||||
<li>A link pointing to another site is no longer mistaken for a page of your own and mirrored in full</li>
|
||||
<li>A mirror told to quit while an FTP file is being received now stops, instead of hanging</li>
|
||||
<li>Stopping an FTP download no longer closes its connection twice, which could interrupt another download</li>
|
||||
<li>The welcome page's language menu shows the language in use</li>
|
||||
<li>The macOS download says in its name that it is for Apple Silicon</li>
|
||||
<li>Refreshed screenshots and typography throughout the documentation</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="3.49.19" date="2026-08-08">
|
||||
<description>
|
||||
<ul>
|
||||
|
||||
@@ -105,8 +105,7 @@ ${LANG_THANKYOU}!
|
||||
<tr><td align="right">
|
||||
${LANG_P15}
|
||||
<select name="lang" onChange="form.redirect.value='index.html'; form.submit()">
|
||||
<option value=0></option>
|
||||
${list:#iso}
|
||||
${listid:lang:#iso}
|
||||
</select>
|
||||
</td></tr>
|
||||
|
||||
|
||||
@@ -6,8 +6,15 @@ body, td {
|
||||
font: 14px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif;
|
||||
}
|
||||
|
||||
/* Take back the whitespace the SVG carries around the letters, so the bar sits on
|
||||
the wordmark's baseline as it does on the doc pages (html/doc.css). */
|
||||
#title {
|
||||
display: block;
|
||||
margin: -1.7px 0 -1.1px;
|
||||
}
|
||||
|
||||
#subTitle {
|
||||
background: #000; color: #fff; padding: 4px; font-weight: bold;
|
||||
background: #000; color: #fff; padding: 4px; font-weight: bold;
|
||||
}
|
||||
|
||||
.tabCtrl {
|
||||
|
||||
@@ -1693,6 +1693,21 @@ int httpmirror(char *url1, httrackp * opt) {
|
||||
// traitement (parsing)
|
||||
// ------------------------------------------------------
|
||||
|
||||
/* An asset URL on a foreign host that answers an HTML page gets no depth:
|
||||
its links are same-host, and would mirror that whole site (#121). */
|
||||
if (!is_binary && heap(ptr)->depth > 0 &&
|
||||
is_html_mime_type(r.contenttype) &&
|
||||
hts_link_is_foreign_asset(opt, ptr)) {
|
||||
hts_log_print(
|
||||
opt, LOG_INFO,
|
||||
"Note: not scanning %s%s, an HTML page on a host foreign "
|
||||
"to %s; mirror it by adding it as a starting URL",
|
||||
/* normalized: a page-supplied link can carry credentials */
|
||||
jump_identification_const(urladr()), urlfil(),
|
||||
jump_identification_const(heap(heap(ptr)->precedent)->adr));
|
||||
heap(ptr)->depth = 0;
|
||||
}
|
||||
|
||||
// traiter
|
||||
if (!is_binary && ((is_hypertext_mime(opt, r.contenttype, urlfil())) /* Is HTML or Js, .. */
|
||||
||(may_be_hypertext_mime(opt, r.contenttype, urlfil()) && r.adr != NULL) /* Is real media, .. */
|
||||
|
||||
54
src/htsftp.c
@@ -56,8 +56,10 @@ Please visit our Website: http://www.httrack.com
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// ftp mode passif
|
||||
/* Passive FTP; overridable so CI can compile the active branch (#1091). */
|
||||
#ifndef FTP_PASV
|
||||
#define FTP_PASV 1
|
||||
#endif
|
||||
|
||||
#define FTP_DEBUG 0
|
||||
|
||||
@@ -314,6 +316,36 @@ static hts_boolean ftp_connect(lien_back *back, T_SOC soc, SOCaddr *server,
|
||||
return socket_set_nonblocking(soc, HTS_FALSE);
|
||||
}
|
||||
|
||||
#if !FTP_PASV
|
||||
/* The active-mode counterpart: an unbounded accept() waits for a data
|
||||
connection the server may never make (#1074). */
|
||||
static T_SOC ftp_accept(lien_back *back, T_SOC soc, int timeout,
|
||||
const httrackp *opt) {
|
||||
const TStamp started = time_local();
|
||||
T_SOC soc_dat;
|
||||
|
||||
timeout = ftp_wait_left(opt, timeout);
|
||||
if (!socket_set_nonblocking(soc, HTS_TRUE))
|
||||
return INVALID_SOCKET;
|
||||
/* state.stop counts as in ftp_connect: nothing is established yet */
|
||||
while (check_socket(soc) == 0) {
|
||||
if (back->stop_ftp || (opt != NULL && opt->state.stop) ||
|
||||
(int) (time_local() - started) >= timeout)
|
||||
return INVALID_SOCKET;
|
||||
Sleep(100);
|
||||
}
|
||||
soc_dat = accept(soc, NULL, NULL);
|
||||
/* BSD hands the listener's non-blocking flag down to the accepted socket,
|
||||
which the transfer below reads blocking. */
|
||||
if (soc_dat != INVALID_SOCKET &&
|
||||
!socket_set_nonblocking(soc_dat, HTS_FALSE)) {
|
||||
deletesoc(soc_dat);
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
return soc_dat;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Resolve, likewise: the shared resolver bounds itself by opt->timeout alone
|
||||
and takes no stop flag. */
|
||||
static SOCaddr *ftp_dns_resolve(httrackp *opt, lien_back *back,
|
||||
@@ -817,8 +849,8 @@ int run_launch_ftp(FTPDownloadStruct * pStruct) {
|
||||
get_ftp_line(back, soc_ctl, line, sizeof(line), timeout, opt);
|
||||
_CHECK_HALT_FTP;
|
||||
if (line[0] == '1') {
|
||||
//T_SOC soc_dat;
|
||||
if ((soc_dat = accept(soc_servdat, NULL, NULL)) == INVALID_SOCKET) {
|
||||
if ((soc_dat = ftp_accept(back, soc_servdat, timeout, opt)) ==
|
||||
INVALID_SOCKET) {
|
||||
strcpybuff(back->r.msg, "Unable to accept connection");
|
||||
back->r.statuscode = STATUSCODE_INVALID;
|
||||
}
|
||||
@@ -830,11 +862,9 @@ int run_launch_ftp(FTPDownloadStruct * pStruct) {
|
||||
htsblk_failf(&back->r, "PORT command error: %s", linejmp(line));
|
||||
back->r.statuscode = STATUSCODE_INVALID;
|
||||
}
|
||||
#ifdef _WIN32
|
||||
closesocket(soc_servdat);
|
||||
#else
|
||||
close(soc_servdat);
|
||||
#endif
|
||||
/* invalidate, or the _CHECK_HALT_FTP below re-closes a stale fd */
|
||||
deletesoc(soc_servdat);
|
||||
soc_servdat = INVALID_SOCKET;
|
||||
} else {
|
||||
strcpybuff(back->r.msg, "Unable to listen to a port");
|
||||
back->r.statuscode = STATUSCODE_INVALID;
|
||||
@@ -931,11 +961,9 @@ int run_launch_ftp(FTPDownloadStruct * pStruct) {
|
||||
strcpybuff(back->r.msg, "Unable to write file");
|
||||
back->r.statuscode = STATUSCODE_INVALID;
|
||||
}
|
||||
#ifdef _WIN32
|
||||
closesocket(soc_dat);
|
||||
#else
|
||||
close(soc_dat);
|
||||
#endif
|
||||
/* invalidate, or the _CHECK_HALT_FTP below re-closes a stale fd */
|
||||
deletesoc(soc_dat);
|
||||
soc_dat = INVALID_SOCKET;
|
||||
|
||||
// 226 Transfer complete?
|
||||
if (back->r.statuscode != -1) {
|
||||
|
||||
@@ -43,8 +43,8 @@ Please visit our Website: http://www.httrack.com
|
||||
configure.ac, decoupled from these). VERSION is the display form, VERSIONID
|
||||
the dotted numeric form, AFF_VERSION the short form shown in footers,
|
||||
LIB_VERSION the data/cache format generation. */
|
||||
#define HTTRACK_VERSION "3.49-19"
|
||||
#define HTTRACK_VERSIONID "3.49.19"
|
||||
#define HTTRACK_VERSION "3.49-20"
|
||||
#define HTTRACK_VERSIONID "3.49.20"
|
||||
#define HTTRACK_AFF_VERSION "3.x"
|
||||
#define HTTRACK_LIB_VERSION "2.0"
|
||||
|
||||
|
||||
@@ -4119,6 +4119,12 @@ void hts_mirror_process_user_interaction(htsmoduleStruct * str,
|
||||
XH_uninit;
|
||||
return;
|
||||
}
|
||||
/* Same omission as the wait for the current link: with every slot busy
|
||||
the mirror parks here instead, and the exit never lands (#1096). */
|
||||
if (*stre->exit_xh_) {
|
||||
XH_uninit;
|
||||
return;
|
||||
}
|
||||
Sleep(100); // pause
|
||||
}
|
||||
opt->state._hts_in_html_parsing = prev;
|
||||
@@ -4226,6 +4232,12 @@ int hts_mirror_wait_for_next_file(htsmoduleStruct * str,
|
||||
XH_uninit;
|
||||
return 0;
|
||||
}
|
||||
/* An exit asked of the engine must leave this wait too: only teardown
|
||||
stops a live FTP worker, so waiting on its slot never ends (#1096). */
|
||||
if (*stre->exit_xh_) {
|
||||
XH_uninit;
|
||||
return 0;
|
||||
}
|
||||
// And fill the backing stack
|
||||
if (back[b].status > 0)
|
||||
back_fillmax(sback, opt, cache, ptr, numero_passe);
|
||||
|
||||
@@ -7874,6 +7874,9 @@ static void st_backstop_slot(struct_back *sback, int p, int status,
|
||||
sback->connect_fallback[p].addr_count = 1;
|
||||
}
|
||||
|
||||
/* A network that rejects TEST-NET-1 instead of dropping it answers in ms. */
|
||||
#define ST_BACKSTOP_SETTLE_MS 500
|
||||
|
||||
/* Refill every slot: a fresh pending connect for each state that owns a socket,
|
||||
plus the poison the assertions read back. False if the blackhole answered. */
|
||||
static hts_boolean st_backstop_arm(httrackp *opt, struct_back *sback,
|
||||
@@ -7893,6 +7896,17 @@ static hts_boolean st_backstop_arm(httrackp *opt, struct_back *sback,
|
||||
}
|
||||
st_backstop_slot(sback, i, status[i], &r[i]);
|
||||
}
|
||||
/* The readback above is too early to see a refusal, and back_wait() then
|
||||
ends slots the caller asserts are intact (the powerpc buildds). */
|
||||
Sleep(ST_BACKSTOP_SETTLE_MS);
|
||||
for (i = 0; i < slots; i++) {
|
||||
if (i != dnsslot && check_socket_connect(sback->lnk[i].r.soc) != 0) {
|
||||
printf("backstop: SKIP (the network answered for " ST_BACKSTOP_DEADHOST
|
||||
" within %d ms)\n",
|
||||
ST_BACKSTOP_SETTLE_MS);
|
||||
return HTS_FALSE;
|
||||
}
|
||||
}
|
||||
return HTS_TRUE;
|
||||
}
|
||||
|
||||
|
||||
@@ -1509,7 +1509,11 @@ int smallserver(T_SOC soc, char *url, char *method, char *data, char *path) {
|
||||
|
||||
StringClear(tmpbuff);
|
||||
if (format == 2) {
|
||||
StringCat(output, "<option value=1>");
|
||||
/* Check the default here too: the loop only opens
|
||||
* ids 2 and up. */
|
||||
StringCat(output, listDefault == 1
|
||||
? "<option value=1 selected>"
|
||||
: "<option value=1>");
|
||||
} else if (format == -2) {
|
||||
StringCat(output, "<option value=\"");
|
||||
}
|
||||
|
||||
@@ -156,7 +156,14 @@ HTS_STATIC void StringOom_(size_t size) {
|
||||
do { \
|
||||
const size_t capacity_ = (size_t) (CAPACITY); \
|
||||
while ((BLK).capacity_ < capacity_) { \
|
||||
const size_t newcap_ = (BLK).capacity_ < 16 ? 16 : (BLK).capacity_ * 2; \
|
||||
const size_t maxcap_ = (size_t) -1; \
|
||||
const size_t mincap_ = 16; \
|
||||
const size_t cur_ = (BLK).capacity_; \
|
||||
/* Past the halfway point cur_*2 wraps below cur_, which no further \
|
||||
doubling climbs back out of; ask for the requested total instead. */ \
|
||||
const size_t newcap_ = cur_ < mincap_ ? mincap_ \
|
||||
: cur_ > maxcap_ / 2 ? capacity_ \
|
||||
: cur_ * 2; \
|
||||
char *const buff_ = STRING_REALLOC((BLK).buffer_, newcap_); \
|
||||
\
|
||||
if (buff_ == NULL) { \
|
||||
|
||||
@@ -930,6 +930,24 @@ int hts_acceptmime(httrackp * opt, int ptr,
|
||||
#undef _ROBOTS
|
||||
}
|
||||
|
||||
hts_boolean hts_link_is_foreign_asset(httrackp *opt, int ptr) {
|
||||
int parent;
|
||||
|
||||
if (ptr <= 0)
|
||||
return HTS_FALSE;
|
||||
parent = heap(ptr)->precedent;
|
||||
/* Seeds hang off the synthetic primary link 0: the user asked for those. */
|
||||
if (parent <= 0 || parent >= opt->lien_tot)
|
||||
return HTS_FALSE;
|
||||
if (ishtml(opt, heap(ptr)->fil) != 0) /* hypertext, or no telling */
|
||||
return HTS_FALSE;
|
||||
/* adr carries the scheme and any user:pw@, so compare bare authorities. */
|
||||
return strfield2(jump_identification_const(heap(ptr)->adr),
|
||||
jump_identification_const(heap(parent)->adr))
|
||||
? HTS_FALSE
|
||||
: HTS_TRUE;
|
||||
}
|
||||
|
||||
// tester taille
|
||||
int hts_testlinksize(httrackp * opt, const char *adr, const char *fil, LLint size) {
|
||||
int jok = 0;
|
||||
@@ -954,7 +972,7 @@ int hts_testlinksize(httrackp * opt, const char *adr, const char *fil, LLint siz
|
||||
lfull[0] = '\0';
|
||||
strcatbuff(lfull, adr);
|
||||
if (*fil != '/')
|
||||
strcatbuff(l, "/");
|
||||
strcatbuff(lfull, "/");
|
||||
strcatbuff(lfull, fil);
|
||||
|
||||
// filters, 0=sait pas 1=ok -1=interdit
|
||||
|
||||
@@ -69,6 +69,10 @@ typedef struct htspair_t {
|
||||
/* HTS_TRUE if tag starts with the whole token cmp; NULL tag never matches. */
|
||||
hts_boolean hts_cmp_tag_token(const char *tag, const char *cmp);
|
||||
|
||||
/* HTS_TRUE when link `ptr` was taken for an asset on a host foreign to its
|
||||
referer: its URL does not look like hypertext, and the hosts differ. */
|
||||
hts_boolean hts_link_is_foreign_asset(httrackp *opt, int ptr);
|
||||
|
||||
int hts_acceptlink(httrackp * opt, int ptr,
|
||||
const char *adr, const char *fil,
|
||||
const char *tag, const char *attribute,
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
#endif
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 3, 49, 19, 0
|
||||
PRODUCTVERSION 3, 49, 19, 0
|
||||
FILEVERSION 3, 49, 20, 0
|
||||
PRODUCTVERSION 3, 49, 20, 0
|
||||
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS VS_FF_DEBUG
|
||||
@@ -35,12 +35,12 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Xavier Roche"
|
||||
VALUE "FileDescription", VER_FILE_DESCRIPTION
|
||||
VALUE "FileVersion", "3.49.19"
|
||||
VALUE "FileVersion", "3.49.20"
|
||||
VALUE "InternalName", VER_ORIGINAL_FILENAME
|
||||
VALUE "LegalCopyright", "Copyright (C) 1998-2026 Xavier Roche and other contributors. GNU GPL v3 or later."
|
||||
VALUE "OriginalFilename", VER_ORIGINAL_FILENAME
|
||||
VALUE "ProductName", "HTTrack Website Copier"
|
||||
VALUE "ProductVersion", "3.49-19"
|
||||
VALUE "ProductVersion", "3.49-20"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
||||
@@ -3,8 +3,11 @@
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# shellcheck source=tests/testlib.sh
|
||||
. "$(dirname "$0")/testlib.sh"
|
||||
|
||||
# Cache-index (.ndx) parse must stay inside the buffer on a corrupt length
|
||||
# prefix (ASan aborts here on the pre-fix binary; the OK check gates the
|
||||
# non-sanitized build too).
|
||||
|
||||
test "$(httrack -O /dev/null -#test=cacheindex)" == 'cacheindex: OK'
|
||||
assert_selftest 'cacheindex: OK' cacheindex
|
||||
|
||||
@@ -3,13 +3,11 @@
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
testdir=$(cd "$(dirname "$0")" && pwd)
|
||||
# shellcheck source=tests/testlib.sh
|
||||
. "${testdir}/testlib.sh"
|
||||
. "$(dirname "$0")/testlib.sh"
|
||||
|
||||
tmpdir=$(mktemp -d "${TMPDIR:-/tmp}/httrack_changes_st.XXXXXX") || exit 1
|
||||
trap 'set +e; rm -rf "$tmpdir"' EXIT
|
||||
trap 'rm -rf "$tmpdir"' HUP INT QUIT PIPE TERM
|
||||
cleanup_push rm -rf "$tmpdir"
|
||||
|
||||
# --changes bucket accounting and JSON escaping (#714).
|
||||
expect_ok "changes self-test" httrack -O "${tmpdir}/o1" -#test=changes run
|
||||
|
||||
@@ -3,14 +3,15 @@
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# shellcheck source=tests/testlib.sh
|
||||
. "$(dirname "$0")/testlib.sh"
|
||||
|
||||
# charset -> UTF-8 conversion (hts_convertStringToUTF8).
|
||||
# -#test=charset <charset> <string> prints the string re-decoded from <charset> as UTF-8.
|
||||
conv() {
|
||||
test "$(httrack -O /dev/null -#test=charset "$1" "$2")" == "$3" || exit 1
|
||||
}
|
||||
conv() { assert_selftest "$3" charset "$1" "$2"; }
|
||||
# crash probe: malformed input must exit cleanly, not abort.
|
||||
runs() {
|
||||
httrack -O /dev/null -#test=charset "$1" "$2" >/dev/null 2>&1 || exit 1
|
||||
httrack -O /dev/null -#test=charset "$1" "$2" >/dev/null 2>&1 || fail "charset '$1' '$2' exited non-zero"
|
||||
}
|
||||
|
||||
# the source bytes below are UTF-8 (this file is UTF-8); "café" is 0x63 61 66 C3 A9.
|
||||
@@ -31,7 +32,7 @@ conv 'us-ascii' 'hello' 'hello'
|
||||
# unknown charset: ASCII passes through unchanged, but non-ASCII input cannot be
|
||||
# decoded and yields empty output (an error is printed to stderr).
|
||||
conv 'no-such-charset-xyz' 'abc' 'abc'
|
||||
test "$(httrack -O /dev/null -#test=charset 'no-such-charset-xyz' 'café' 2>/dev/null)" == "" || exit 1
|
||||
assert_eq "" "$(httrack -O /dev/null -#test=charset 'no-such-charset-xyz' 'café' 2>/dev/null)"
|
||||
|
||||
# malformed UTF-8 (lone continuation byte, truncated lead byte) must not crash
|
||||
runs 'utf-8' 'hex:80'
|
||||
@@ -39,9 +40,7 @@ runs 'utf-8' 'hex:c3'
|
||||
|
||||
# hts_getCharsetFromMeta: <meta> charset extraction, HTML5 and legacy forms.
|
||||
# -#test=metacharset <html> prints the charset, or "(none)".
|
||||
meta() {
|
||||
test "$(httrack -O /dev/null -#test=metacharset "$1")" == "$2" || exit 1
|
||||
}
|
||||
meta() { assert_selftest "$2" metacharset "$1"; }
|
||||
|
||||
# HTML5 form, quoting/spacing flavors
|
||||
meta '<meta charset="utf-8">' 'utf-8'
|
||||
@@ -50,7 +49,7 @@ meta '<meta charset=utf-8>' 'utf-8'
|
||||
meta '<meta charset=utf-8 />' 'utf-8'
|
||||
meta '<meta charset=utf-8/>' 'utf-8'
|
||||
# charset labels are case-insensitive downstream; only require case-insensitive match
|
||||
test "$(httrack -O /dev/null -#test=metacharset '<META CHARSET=UTF-8>' | tr '[:upper:]' '[:lower:]')" == 'utf-8' || exit 1
|
||||
assert_eq 'utf-8' "$(httrack -O /dev/null -#test=metacharset '<META CHARSET=UTF-8>' | tr '[:upper:]' '[:lower:]')"
|
||||
meta '<html><head><meta charset = "utf-8" ></head>' 'utf-8'
|
||||
|
||||
# legacy http-equiv form, attributes in any order
|
||||
@@ -83,9 +82,7 @@ meta '<meta ' '(none)'
|
||||
meta '<meta' '(none)'
|
||||
|
||||
# hts_isStringUTF8: valid-UTF-8 probe (guards the #180 link conversion).
|
||||
utf8() {
|
||||
test "$(httrack -O /dev/null -#test=isutf8 "$1")" == "$2" || exit 1
|
||||
}
|
||||
utf8() { assert_selftest "$2" isutf8 "$1"; }
|
||||
utf8 'plain' '1'
|
||||
utf8 'café' '1'
|
||||
utf8 '统计' '1'
|
||||
|
||||