mirror of
https://github.com/xroche/httrack.git
synced 2026-06-28 21:17:57 +03:00
Compare commits
111 Commits
ci/cache-g
...
fix/urlhac
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
600001b282 | ||
|
|
40a66600ff | ||
|
|
768756e231 | ||
|
|
b138c87a93 | ||
|
|
3de47433b7 | ||
|
|
fb8827718e | ||
|
|
7228210061 | ||
|
|
38882c0aee | ||
|
|
bfc4a016ab | ||
|
|
756d8fb8bd | ||
|
|
5501faa7b1 | ||
|
|
6322b6fb1f | ||
|
|
58f368a91a | ||
|
|
c97b3e233e | ||
|
|
b615a4e7fd | ||
|
|
594cf0da39 | ||
|
|
3845cd1fb3 | ||
|
|
94bffb0804 | ||
|
|
a5c86e7e89 | ||
|
|
54f5717057 | ||
|
|
40fc9de360 | ||
|
|
4614eefefe | ||
|
|
b0e8262db0 | ||
|
|
addbd3136b | ||
|
|
a64c4cd160 | ||
|
|
1611dbcabf | ||
|
|
099501ee50 | ||
|
|
1b9eefa3b4 | ||
|
|
9c8d3a41eb | ||
|
|
ae77cd9d6d | ||
|
|
51b8dcd81c | ||
|
|
bcce664143 | ||
|
|
7a24add87c | ||
|
|
2308e7bafd | ||
|
|
ef5691fc47 | ||
|
|
0a6eb73903 | ||
|
|
fdb243e5a2 | ||
|
|
f8546e146d | ||
|
|
b7f602f2eb | ||
|
|
550100b56a | ||
|
|
33ddb27243 | ||
|
|
4606dfbf66 | ||
|
|
a6f1b9a3dd | ||
|
|
fb35d6a0f1 | ||
|
|
8a270fec03 | ||
|
|
0cbd5279f2 | ||
|
|
05306ee4fd | ||
|
|
1d0fc0a566 | ||
|
|
a4452592b4 | ||
|
|
62c2364b59 | ||
|
|
fe7041ddbf | ||
|
|
f5543df1af | ||
|
|
fee30aa95d | ||
|
|
f9f4700ee1 | ||
|
|
f030fa21e3 | ||
|
|
bdd1c1bc2c | ||
|
|
56665a268f | ||
|
|
2e948b9acd | ||
|
|
cae11499f1 | ||
|
|
02c7f4ebf6 | ||
|
|
9070b44a70 | ||
|
|
799c045061 | ||
|
|
fb1ee3bf2e | ||
|
|
6a08ca7d39 | ||
|
|
a8b491e509 | ||
|
|
a8e4bb3b81 | ||
|
|
0145ec37a3 | ||
|
|
a80fab38ba | ||
|
|
c52a524a63 | ||
|
|
1907621d37 | ||
|
|
3b2d7afdaa | ||
|
|
6ee539619e | ||
|
|
fb098b27b4 | ||
|
|
5f6a3fb917 | ||
|
|
f9e676dbe3 | ||
|
|
1b440c44b5 | ||
|
|
ac6dd1a570 | ||
|
|
4549ec3695 | ||
|
|
ac56c31b24 | ||
|
|
ee6beeeb7d | ||
|
|
6788bda380 | ||
|
|
7ead8d595e | ||
|
|
93f502990c | ||
|
|
0f4b2596b2 | ||
|
|
4a676bb5e1 | ||
|
|
36b4e834b8 | ||
|
|
bbb423f025 | ||
|
|
eed46e0b09 | ||
|
|
fa57f0148f | ||
|
|
76260d5e6e | ||
|
|
5d0913dfce | ||
|
|
9b7601a987 | ||
|
|
4ec38c4e66 | ||
|
|
1142b64696 | ||
|
|
22d3eb44cd | ||
|
|
8246c7bbcd | ||
|
|
f13f90e9c4 | ||
|
|
c177923fa1 | ||
|
|
7091f85104 | ||
|
|
a498745df3 | ||
|
|
f875590b90 | ||
|
|
c1a8c5ffa8 | ||
|
|
46a9f6db5d | ||
|
|
d90f3e356d | ||
|
|
845e2e72eb | ||
|
|
447c2d1d6f | ||
|
|
c86ca62366 | ||
|
|
9bf741f4b0 | ||
|
|
d9c7ea41e8 | ||
|
|
b52b117b90 | ||
|
|
19d925e6e0 |
@@ -16,6 +16,7 @@ BasedOnStyle: LLVM
|
|||||||
SpaceAfterCStyleCast: true # "(int) x", overwhelmingly dominant (542 vs 7)
|
SpaceAfterCStyleCast: true # "(int) x", overwhelmingly dominant (542 vs 7)
|
||||||
SortIncludes: false # C include order can be significant; never reorder
|
SortIncludes: false # C include order can be significant; never reorder
|
||||||
IncludeBlocks: Preserve # do not merge/reflow include groups
|
IncludeBlocks: Preserve # do not merge/reflow include groups
|
||||||
|
SeparateDefinitionBlocks: Always # blank line between definitions (readability)
|
||||||
|
|
||||||
# Stated explicitly for robustness against base-style drift (these match LLVM):
|
# Stated explicitly for robustness against base-style drift (these match LLVM):
|
||||||
IndentWidth: 2
|
IndentWidth: 2
|
||||||
|
|||||||
5
.flake8
Normal file
5
.flake8
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
[flake8]
|
||||||
|
# Match black's formatting so the two tools don't fight.
|
||||||
|
max-line-length = 88
|
||||||
|
# E203/W503 conflict with black's slice and line-break style.
|
||||||
|
extend-ignore = E203, W503
|
||||||
160
.github/workflows/ci.yml
vendored
160
.github/workflows/ci.yml
vendored
@@ -188,6 +188,51 @@ jobs:
|
|||||||
if: failure()
|
if: failure()
|
||||||
run: cat tests/test-suite.log 2>/dev/null || true
|
run: cat tests/test-suite.log 2>/dev/null || true
|
||||||
|
|
||||||
|
# MemorySanitizer catches reads of uninitialized memory (#143's stack-garbage
|
||||||
|
# size filter) that ASan/UBSan miss. It flags any byte an uninstrumented lib
|
||||||
|
# wrote, so the job stays in our own code: offline self-tests only, no openssl
|
||||||
|
# (--disable-https), no zlib cache tests, static (the runtime is not in .so's).
|
||||||
|
msan:
|
||||||
|
name: msan (MemorySanitizer, clang)
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v6
|
||||||
|
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 clang autoconf automake libtool autoconf-archive \
|
||||||
|
zlib1g-dev
|
||||||
|
|
||||||
|
- name: Configure (MSan, static, no https)
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
autoreconf -fi
|
||||||
|
./configure CC=clang \
|
||||||
|
CFLAGS="-fsanitize=memory -fsanitize-memory-track-origins=2 -fno-sanitize-recover=all -g -O1 -fno-omit-frame-pointer" \
|
||||||
|
LDFLAGS="-fsanitize=memory" \
|
||||||
|
--disable-https --disable-shared --enable-static
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: make -j"$(nproc)"
|
||||||
|
|
||||||
|
- name: Test (offline self-tests under MSan)
|
||||||
|
env:
|
||||||
|
MSAN_OPTIONS: abort_on_error=1:halt_on_error=1
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
# Engine self-tests only; the cache trio pulls in uninstrumented zlib.
|
||||||
|
tests="$(cd tests && ls 01_engine-*.test | grep -v -- '-cache' | tr '\n' ' ')"
|
||||||
|
make check TESTS="$tests"
|
||||||
|
|
||||||
|
- name: Print the test log on failure
|
||||||
|
if: failure()
|
||||||
|
run: cat tests/test-suite.log 2>/dev/null || true
|
||||||
|
|
||||||
# Optional-dependency build: compile and test with HTTPS/OpenSSL disabled --
|
# Optional-dependency build: compile and test with HTTPS/OpenSSL disabled --
|
||||||
# the configuration users on minimal systems build, and one libssl is not even
|
# the configuration users on minimal systems build, and one libssl is not even
|
||||||
# installed here so configure cannot silently re-enable it. The matrix above
|
# installed here so configure cannot silently re-enable it. The matrix above
|
||||||
@@ -227,34 +272,47 @@ jobs:
|
|||||||
# Validate the Debian packaging via the same script maintainers release with.
|
# Validate the Debian packaging via the same script maintainers release with.
|
||||||
# One amd64/gcc run is enough: packaging (control/rules/manifest/lintian/quilt
|
# One amd64/gcc run is enough: packaging (control/rules/manifest/lintian/quilt
|
||||||
# source build) is arch- and compiler-independent, and the build matrix above
|
# source build) is arch- and compiler-independent, and the build matrix above
|
||||||
# already covers compile portability. lintian runs with --fail-on=error.
|
# already covers compile portability. mkdeb.sh runs lintian as an explicit gate
|
||||||
|
# (debuild does not propagate lintian's exit) with --fail-on=error,warning.
|
||||||
deb:
|
deb:
|
||||||
name: deb package (lintian)
|
name: deb package (lintian)
|
||||||
runs-on: ubuntu-24.04
|
runs-on: ubuntu-24.04
|
||||||
|
# Build and gate inside Debian sid, the upload target. A Debian dpkg-deb
|
||||||
|
# produces archive-legal xz members (an Ubuntu host defaults to zstd, which
|
||||||
|
# the archive's lintian rejects), and sid's lintian carries the same
|
||||||
|
# data-driven checks (embedded-lib fingerprints and the like) the buildds and
|
||||||
|
# UDD apply -- so issues surface here instead of after upload.
|
||||||
|
container: debian:sid
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
|
|
||||||
- name: Install packaging toolchain
|
- name: Install packaging toolchain
|
||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
sudo apt-get update
|
apt-get update
|
||||||
sudo apt-get install -y --no-install-recommends \
|
apt-get install -y --no-install-recommends \
|
||||||
|
ca-certificates git \
|
||||||
build-essential autoconf automake libtool autoconf-archive \
|
build-essential autoconf automake libtool autoconf-archive \
|
||||||
zlib1g-dev libssl-dev \
|
zlib1g-dev libssl-dev \
|
||||||
debhelper devscripts lintian fakeroot
|
debhelper devscripts lintian fakeroot
|
||||||
|
|
||||||
|
- uses: actions/checkout@v6
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
|
||||||
# --unsigned: CI has no GPG key (also skips the release sig/checksums).
|
# --unsigned: CI has no GPG key (also skips the release sig/checksums).
|
||||||
# debuild builds every package, then lintian gates on errors.
|
# mkdeb builds every package then runs the lintian gate (--fail-on=error,
|
||||||
|
# warning); debuild runs the packaged test pass.
|
||||||
#
|
#
|
||||||
# DEB_BUILD_OPTIONS trims work CI does not need (release builds via
|
# DEB_BUILD_OPTIONS trims work CI does not need (release builds via
|
||||||
# mkdeb.sh are untouched): noautodbgsym drops the -dbgsym packages whose
|
# mkdeb.sh are untouched): noautodbgsym drops the -dbgsym packages whose
|
||||||
# LTO payloads are slow to compress and that CI never ships; parallel uses
|
# LTO payloads are slow to compress and that CI never ships; parallel uses
|
||||||
# every core. We let debuild run its test pass -- the only one now that
|
# every core.
|
||||||
# mkdeb no longer runs its own -- so CI exercises the packaged tests.
|
- name: Build and lint Debian packages
|
||||||
- name: Build Debian packages
|
|
||||||
run: |
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
# The workspace volume is owned by the host runner uid, but the
|
||||||
|
# container runs as root, so mkdeb's git calls (superproject and the
|
||||||
|
# coucal submodule) trip "dubious ownership"; mark them all safe.
|
||||||
|
git config --global --add safe.directory "*"
|
||||||
export DEB_BUILD_OPTIONS="noautodbgsym parallel=$(nproc)"
|
export DEB_BUILD_OPTIONS="noautodbgsym parallel=$(nproc)"
|
||||||
bash tools/mkdeb.sh --unsigned --no-release-artifacts
|
bash tools/mkdeb.sh --unsigned --no-release-artifacts
|
||||||
|
|
||||||
@@ -320,44 +378,38 @@ jobs:
|
|||||||
lint:
|
lint:
|
||||||
name: lint (shellcheck, shfmt)
|
name: lint (shellcheck, shfmt)
|
||||||
runs-on: ubuntu-24.04
|
runs-on: ubuntu-24.04
|
||||||
|
# Every tracked shell script; the globs expand at run time. Kept here so the
|
||||||
|
# shellcheck and shfmt steps below cannot drift apart.
|
||||||
env:
|
env:
|
||||||
SHFMT_VERSION: v3.8.0
|
SHELL_SCRIPTS: >-
|
||||||
|
.githooks/pre-commit
|
||||||
|
bootstrap
|
||||||
|
build.sh
|
||||||
|
html/div/search.sh
|
||||||
|
man/makeman.sh
|
||||||
|
src/htsbasiccharsets.sh
|
||||||
|
src/htsentities.sh
|
||||||
|
src/webhttrack
|
||||||
|
tests/*.sh
|
||||||
|
tests/*.test
|
||||||
|
tools/mkdeb.sh
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v6
|
||||||
|
|
||||||
# shfmt is a pinned release binary, so it never changes: cache it keyed on
|
|
||||||
# the version. Same rationale as the git-clang-format driver below -- avoid
|
|
||||||
# re-downloading an unchanging file from github.com on every run.
|
|
||||||
- name: Cache shfmt binary
|
|
||||||
uses: actions/cache@v4
|
|
||||||
with:
|
|
||||||
path: ~/.cache/shfmt/shfmt
|
|
||||||
key: shfmt-${{ env.SHFMT_VERSION }}-${{ runner.arch }}
|
|
||||||
|
|
||||||
- name: Install linters
|
- name: Install linters
|
||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install -y --no-install-recommends shellcheck
|
# noble ships shfmt 3.8.0 (universe), matching the pinned local dev
|
||||||
# shfmt is not packaged in apt; fetch a pinned release binary (cold
|
# version; use it rather than fetching a release binary from github.com.
|
||||||
# cache only), retrying through transient errors.
|
sudo apt-get install -y --no-install-recommends shellcheck shfmt
|
||||||
shfmt="$HOME/.cache/shfmt/shfmt"
|
shfmt --version
|
||||||
if [ ! -s "$shfmt" ]; then
|
|
||||||
echo "shfmt cache MISS: fetching ${SHFMT_VERSION} from github.com"
|
|
||||||
mkdir -p "$(dirname "$shfmt")"
|
|
||||||
curl --retry 5 --retry-all-errors -fsSL -o "$shfmt" \
|
|
||||||
"https://github.com/mvdan/sh/releases/download/${SHFMT_VERSION}/shfmt_${SHFMT_VERSION}_linux_$(dpkg --print-architecture)"
|
|
||||||
else
|
|
||||||
echo "shfmt cache HIT: using cached ${SHFMT_VERSION}"
|
|
||||||
fi
|
|
||||||
sudo install -m 0755 "$shfmt" /usr/local/bin/shfmt
|
|
||||||
|
|
||||||
# Lint the scripts we maintain; the legacy scripts are a separate cleanup.
|
|
||||||
- name: shellcheck
|
- name: shellcheck
|
||||||
run: shellcheck man/makeman.sh tools/mkdeb.sh .githooks/pre-commit tests/*.test tests/check-network.sh
|
run: shellcheck $SHELL_SCRIPTS
|
||||||
|
|
||||||
- name: shfmt
|
- name: shfmt
|
||||||
run: shfmt -d -i 4 man/makeman.sh tools/mkdeb.sh .githooks/pre-commit
|
run: shfmt -d -i 4 $SHELL_SCRIPTS
|
||||||
|
|
||||||
# Check clang-format on CHANGED LINES ONLY. The engine predates clang-format
|
# 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,
|
# (it was shaped by an old Visual Studio formatter) and does not round-trip,
|
||||||
@@ -366,24 +418,11 @@ jobs:
|
|||||||
name: format (clang-format-19, changed lines)
|
name: format (clang-format-19, changed lines)
|
||||||
if: github.event_name == 'pull_request'
|
if: github.event_name == 'pull_request'
|
||||||
runs-on: ubuntu-24.04
|
runs-on: ubuntu-24.04
|
||||||
env:
|
|
||||||
# Single-source the tag so the cache key and the fetch URL can never drift.
|
|
||||||
LLVM_TAG: llvmorg-19.1.7
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v6
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
# The git-clang-format driver is pinned to an immutable release tag, so the
|
|
||||||
# fetched file never changes: cache it keyed on the tag. raw.githubusercontent.com
|
|
||||||
# 429-rate-limits the shared runner egress IPs, and re-downloading an unchanging
|
|
||||||
# file every run was the only thing that could (and did) hit that limit.
|
|
||||||
- name: Cache git-clang-format driver
|
|
||||||
uses: actions/cache@v4
|
|
||||||
with:
|
|
||||||
path: ~/.cache/git-clang-format/git-clang-format
|
|
||||||
key: git-clang-format-${{ env.LLVM_TAG }}
|
|
||||||
|
|
||||||
- name: Install clang-format 19 (pinned, from apt.llvm.org)
|
- name: Install clang-format 19 (pinned, from apt.llvm.org)
|
||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
@@ -394,17 +433,9 @@ jobs:
|
|||||||
| sudo tee /etc/apt/sources.list.d/llvm-19.list >/dev/null
|
| sudo tee /etc/apt/sources.list.d/llvm-19.list >/dev/null
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install -y --no-install-recommends clang-format-19
|
sudo apt-get install -y --no-install-recommends clang-format-19
|
||||||
# Cold cache only: fetch the driver, retrying through transient 429s.
|
# The clang-format-19 package ships the git-clang-format driver;
|
||||||
driver="$HOME/.cache/git-clang-format/git-clang-format"
|
# expose it unsuffixed so "git clang-format" finds it.
|
||||||
if [ ! -s "$driver" ]; then
|
sudo ln -sf /usr/bin/git-clang-format-19 /usr/local/bin/git-clang-format
|
||||||
echo "git-clang-format cache MISS: fetching ${LLVM_TAG} from raw.githubusercontent.com"
|
|
||||||
mkdir -p "$(dirname "$driver")"
|
|
||||||
curl --retry 5 --retry-all-errors -fsSL -o "$driver" \
|
|
||||||
"https://raw.githubusercontent.com/llvm/llvm-project/${LLVM_TAG}/clang/tools/clang-format/git-clang-format"
|
|
||||||
else
|
|
||||||
echo "git-clang-format cache HIT: using cached ${LLVM_TAG}"
|
|
||||||
fi
|
|
||||||
sudo install -m 0755 "$driver" /usr/local/bin/git-clang-format
|
|
||||||
clang-format-19 --version
|
clang-format-19 --version
|
||||||
|
|
||||||
- name: Check formatting of changed lines
|
- name: Check formatting of changed lines
|
||||||
@@ -418,10 +449,9 @@ jobs:
|
|||||||
--diff --extensions c,h "$base")"
|
--diff --extensions c,h "$base")"
|
||||||
rc=$?
|
rc=$?
|
||||||
set -e
|
set -e
|
||||||
# Classify by output first: a non-empty diff means "not clean",
|
# Classify by output, not exit code: a non-empty diff means "not
|
||||||
# regardless of the driver's exit convention (the release-tag driver
|
# clean" (git-clang-format may exit 0 or 1 on a diff). A nonzero exit
|
||||||
# exits 0 and signals via stdout; some packaged drivers exit 1 on a
|
# with clean output is a real checker error.
|
||||||
# diff). A nonzero exit with clean output is a real checker error.
|
|
||||||
case "$diff" in
|
case "$diff" in
|
||||||
"" | "no modified files to format" | *"did not modify any files"*)
|
"" | "no modified files to format" | *"did not modify any files"*)
|
||||||
if [ "$rc" -ne 0 ]; then
|
if [ "$rc" -ne 0 ]; then
|
||||||
|
|||||||
41
.gitignore
vendored
Normal file
41
.gitignore
vendored
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
# Generated by autoreconf/bootstrap (run ./bootstrap after a fresh clone).
|
||||||
|
# Release tarballs ("make dist") ship these; the git tree does not.
|
||||||
|
/configure
|
||||||
|
/config.h.in
|
||||||
|
/config.h.in~
|
||||||
|
/aclocal.m4
|
||||||
|
/ltmain.sh
|
||||||
|
/libtool
|
||||||
|
/config.guess
|
||||||
|
/config.sub
|
||||||
|
/install-sh
|
||||||
|
/missing
|
||||||
|
/depcomp
|
||||||
|
/compile
|
||||||
|
/ar-lib
|
||||||
|
/test-driver
|
||||||
|
/autom4te.cache/
|
||||||
|
/m4/libtool.m4
|
||||||
|
/m4/lt*.m4
|
||||||
|
Makefile.in
|
||||||
|
|
||||||
|
# Generated by configure / make.
|
||||||
|
/config.h
|
||||||
|
/config.log
|
||||||
|
/config.status
|
||||||
|
/stamp-h1
|
||||||
|
Makefile
|
||||||
|
.deps/
|
||||||
|
.libs/
|
||||||
|
*.o
|
||||||
|
*.lo
|
||||||
|
*.la
|
||||||
|
*.so
|
||||||
|
*.so.*
|
||||||
|
*.a
|
||||||
|
|
||||||
|
# make dist output.
|
||||||
|
/httrack-*.tar.gz
|
||||||
|
|
||||||
|
# Editor / autotools backup files.
|
||||||
|
*~
|
||||||
20
AGENTS.md
20
AGENTS.md
@@ -5,13 +5,18 @@ the operational checklist: toolchain, invariants, and how to ship a change.
|
|||||||
|
|
||||||
## Build & test
|
## Build & test
|
||||||
- Fresh clone first: `git submodule update --init src/coucal`
|
- Fresh clone first: `git submodule update --init src/coucal`
|
||||||
- `bash configure && make && make check`
|
- `./bootstrap` (regenerates `configure` via `autoreconf`; needs autoconf,
|
||||||
|
automake, libtool), then `bash configure && make && make check`. Or run
|
||||||
|
`sh build.sh` to do bootstrap + configure + make in one shot.
|
||||||
|
|
||||||
## Hard invariants
|
## Hard invariants
|
||||||
- **Toolchain edit** (`configure.ac`, any `Makefile.am`, `m4/`) → run
|
- **Generated autotools files are NOT in git.** `configure`, every
|
||||||
`autoreconf -fi` and commit the regenerated tracked files. The repo ships the
|
`Makefile.in`, `config.h.in`, `ltmain.sh`, `config.guess/sub`, and the aux
|
||||||
generated `configure`/`Makefile.in` so users build without autotools; CI does
|
scripts are build products: `.gitignore`d, regenerated by `./bootstrap`, and
|
||||||
**not** catch staleness.
|
shipped only in `make dist` tarballs (so tarball users still need no
|
||||||
|
autotools). Never commit them. After editing `configure.ac`, any
|
||||||
|
`Makefile.am`, or `m4/`, just commit those sources — re-run `./bootstrap`
|
||||||
|
locally to rebuild and test, but do not stage the regenerated output.
|
||||||
- **Format only changed lines** with `git clang-format` (clang-format 19). Never
|
- **Format only changed lines** with `git clang-format` (clang-format 19). Never
|
||||||
reformat untouched code: the engine was formatted by an old tool and won't
|
reformat untouched code: the engine was formatted by an old tool and won't
|
||||||
round-trip.
|
round-trip.
|
||||||
@@ -28,8 +33,9 @@ the operational checklist: toolchain, invariants, and how to ship a change.
|
|||||||
- Be terse. Comment the why, in English; translate French comments you touch.
|
- Be terse. Comment the why, in English; translate French comments you touch.
|
||||||
- Strip AI tells from prose (em-dash overuse, rule-of-three, filler, vague
|
- Strip AI tells from prose (em-dash overuse, rule-of-three, filler, vague
|
||||||
attributions). Ref: Wikipedia "Signs of AI writing". Claude Code: `/humanizer`.
|
attributions). Ref: Wikipedia "Signs of AI writing". Claude Code: `/humanizer`.
|
||||||
- Behavior change → add a test. Fast path: a hidden `httrack -#N` debug
|
- Behavior change → add a test. Fast path: a hidden `httrack -#test=NAME` engine
|
||||||
subcommand (`htscoremain.c`) driven by a `tests/NN_*.test`, over a slow crawl.
|
self-test (registry in `htsselftest.c`; `-#test` lists them) driven by a
|
||||||
|
`tests/NN_*.test`, over a slow crawl.
|
||||||
|
|
||||||
## Review your change adversarially (strongly suggested)
|
## Review your change adversarially (strongly suggested)
|
||||||
Before pushing, and when reviewing others, don't skim for bugs:
|
Before pushing, and when reviewing others, don't skim for bugs:
|
||||||
|
|||||||
@@ -7,4 +7,15 @@ On most systems (including GNU/Linux), installing can be easily achieved using t
|
|||||||
-or- (if not compiling as root)
|
-or- (if not compiling as root)
|
||||||
./configure --prefix=$HOME && make && make install
|
./configure --prefix=$HOME && make && make install
|
||||||
|
|
||||||
|
Building from a git checkout (not a release tarball) first needs the build
|
||||||
|
system regenerated, which requires autoconf, automake and libtool:
|
||||||
|
|
||||||
|
./bootstrap
|
||||||
|
./configure && make && make install
|
||||||
|
|
||||||
|
You can also use the one-shot wrapper, which runs bootstrap, configure and make
|
||||||
|
(extra arguments are passed to configure):
|
||||||
|
|
||||||
|
./build.sh --prefix=$HOME
|
||||||
|
|
||||||
See also the INSTALL generic help file.
|
See also the INSTALL generic help file.
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ ACLOCAL_AMFLAGS = -I m4
|
|||||||
|
|
||||||
EXTRA_DIST = INSTALL.Linux \
|
EXTRA_DIST = INSTALL.Linux \
|
||||||
gpl-fr.txt license.txt greetings.txt history.txt \
|
gpl-fr.txt license.txt greetings.txt history.txt \
|
||||||
httrack-doc.html lang.def README.md tools/mkdeb.sh
|
httrack-doc.html lang.def README.md tools/mkdeb.sh \
|
||||||
|
bootstrap build.sh
|
||||||
|
|
||||||
# Build the signed Debian packages from a clean source export. Pass the signing
|
# Build the signed Debian packages from a clean source export. Pass the signing
|
||||||
# key and other options through DEB_FLAGS, e.g.:
|
# key and other options through DEB_FLAGS, e.g.:
|
||||||
|
|||||||
871
Makefile.in
871
Makefile.in
@@ -1,871 +0,0 @@
|
|||||||
# Makefile.in generated by automake 1.17 from Makefile.am.
|
|
||||||
# @configure_input@
|
|
||||||
|
|
||||||
# Copyright (C) 1994-2024 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
# This Makefile.in is free software; the Free Software Foundation
|
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
|
||||||
# with or without modifications, as long as this notice is preserved.
|
|
||||||
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
|
||||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
|
||||||
# PARTICULAR PURPOSE.
|
|
||||||
|
|
||||||
@SET_MAKE@
|
|
||||||
VPATH = @srcdir@
|
|
||||||
am__is_gnu_make = { \
|
|
||||||
if test -z '$(MAKELEVEL)'; then \
|
|
||||||
false; \
|
|
||||||
elif test -n '$(MAKE_HOST)'; then \
|
|
||||||
true; \
|
|
||||||
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
|
|
||||||
true; \
|
|
||||||
else \
|
|
||||||
false; \
|
|
||||||
fi; \
|
|
||||||
}
|
|
||||||
am__make_running_with_option = \
|
|
||||||
case $${target_option-} in \
|
|
||||||
?) ;; \
|
|
||||||
*) echo "am__make_running_with_option: internal error: invalid" \
|
|
||||||
"target option '$${target_option-}' specified" >&2; \
|
|
||||||
exit 1;; \
|
|
||||||
esac; \
|
|
||||||
has_opt=no; \
|
|
||||||
sane_makeflags=$$MAKEFLAGS; \
|
|
||||||
if $(am__is_gnu_make); then \
|
|
||||||
sane_makeflags=$$MFLAGS; \
|
|
||||||
else \
|
|
||||||
case $$MAKEFLAGS in \
|
|
||||||
*\\[\ \ ]*) \
|
|
||||||
bs=\\; \
|
|
||||||
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
|
|
||||||
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
|
|
||||||
esac; \
|
|
||||||
fi; \
|
|
||||||
skip_next=no; \
|
|
||||||
strip_trailopt () \
|
|
||||||
{ \
|
|
||||||
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
|
|
||||||
}; \
|
|
||||||
for flg in $$sane_makeflags; do \
|
|
||||||
test $$skip_next = yes && { skip_next=no; continue; }; \
|
|
||||||
case $$flg in \
|
|
||||||
*=*|--*) continue;; \
|
|
||||||
-*I) strip_trailopt 'I'; skip_next=yes;; \
|
|
||||||
-*I?*) strip_trailopt 'I';; \
|
|
||||||
-*O) strip_trailopt 'O'; skip_next=yes;; \
|
|
||||||
-*O?*) strip_trailopt 'O';; \
|
|
||||||
-*l) strip_trailopt 'l'; skip_next=yes;; \
|
|
||||||
-*l?*) strip_trailopt 'l';; \
|
|
||||||
-[dEDm]) skip_next=yes;; \
|
|
||||||
-[JT]) skip_next=yes;; \
|
|
||||||
esac; \
|
|
||||||
case $$flg in \
|
|
||||||
*$$target_option*) has_opt=yes; break;; \
|
|
||||||
esac; \
|
|
||||||
done; \
|
|
||||||
test $$has_opt = yes
|
|
||||||
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
|
|
||||||
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
|
|
||||||
am__rm_f = rm -f $(am__rm_f_notfound)
|
|
||||||
am__rm_rf = rm -rf $(am__rm_f_notfound)
|
|
||||||
pkgdatadir = $(datadir)/@PACKAGE@
|
|
||||||
pkgincludedir = $(includedir)/@PACKAGE@
|
|
||||||
pkglibdir = $(libdir)/@PACKAGE@
|
|
||||||
pkglibexecdir = $(libexecdir)/@PACKAGE@
|
|
||||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
|
||||||
install_sh_DATA = $(install_sh) -c -m 644
|
|
||||||
install_sh_PROGRAM = $(install_sh) -c
|
|
||||||
install_sh_SCRIPT = $(install_sh) -c
|
|
||||||
INSTALL_HEADER = $(INSTALL_DATA)
|
|
||||||
transform = $(program_transform_name)
|
|
||||||
NORMAL_INSTALL = :
|
|
||||||
PRE_INSTALL = :
|
|
||||||
POST_INSTALL = :
|
|
||||||
NORMAL_UNINSTALL = :
|
|
||||||
PRE_UNINSTALL = :
|
|
||||||
POST_UNINSTALL = :
|
|
||||||
build_triplet = @build@
|
|
||||||
host_triplet = @host@
|
|
||||||
subdir = .
|
|
||||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
|
||||||
am__aclocal_m4_deps = $(top_srcdir)/m4/check_zlib.m4 \
|
|
||||||
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
|
|
||||||
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
|
|
||||||
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/snprintf.m4 \
|
|
||||||
$(top_srcdir)/m4/visibility.m4 $(top_srcdir)/configure.ac
|
|
||||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
|
||||||
$(ACLOCAL_M4)
|
|
||||||
DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \
|
|
||||||
$(am__configure_deps) $(am__DIST_COMMON)
|
|
||||||
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
|
|
||||||
configure.lineno config.status.lineno
|
|
||||||
mkinstalldirs = $(install_sh) -d
|
|
||||||
CONFIG_HEADER = config.h
|
|
||||||
CONFIG_CLEAN_FILES =
|
|
||||||
CONFIG_CLEAN_VPATH_FILES =
|
|
||||||
AM_V_P = $(am__v_P_@AM_V@)
|
|
||||||
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
|
|
||||||
am__v_P_0 = false
|
|
||||||
am__v_P_1 = :
|
|
||||||
AM_V_GEN = $(am__v_GEN_@AM_V@)
|
|
||||||
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
|
|
||||||
am__v_GEN_0 = @echo " GEN " $@;
|
|
||||||
am__v_GEN_1 =
|
|
||||||
AM_V_at = $(am__v_at_@AM_V@)
|
|
||||||
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
|
|
||||||
am__v_at_0 = @
|
|
||||||
am__v_at_1 =
|
|
||||||
SOURCES =
|
|
||||||
DIST_SOURCES =
|
|
||||||
RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
|
|
||||||
ctags-recursive dvi-recursive html-recursive info-recursive \
|
|
||||||
install-data-recursive install-dvi-recursive \
|
|
||||||
install-exec-recursive install-html-recursive \
|
|
||||||
install-info-recursive install-pdf-recursive \
|
|
||||||
install-ps-recursive install-recursive installcheck-recursive \
|
|
||||||
installdirs-recursive pdf-recursive ps-recursive \
|
|
||||||
tags-recursive uninstall-recursive
|
|
||||||
am__can_run_installinfo = \
|
|
||||||
case $$AM_UPDATE_INFO_DIR in \
|
|
||||||
n|no|NO) false;; \
|
|
||||||
*) (install-info --version) >/dev/null 2>&1;; \
|
|
||||||
esac
|
|
||||||
RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
|
|
||||||
distclean-recursive maintainer-clean-recursive
|
|
||||||
am__recursive_targets = \
|
|
||||||
$(RECURSIVE_TARGETS) \
|
|
||||||
$(RECURSIVE_CLEAN_TARGETS) \
|
|
||||||
$(am__extra_recursive_targets)
|
|
||||||
AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
|
|
||||||
cscope distdir distdir-am dist dist-all distcheck
|
|
||||||
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \
|
|
||||||
config.h.in
|
|
||||||
# Read a list of newline-separated strings from the standard input,
|
|
||||||
# and print each of them once, without duplicates. Input order is
|
|
||||||
# *not* preserved.
|
|
||||||
am__uniquify_input = $(AWK) '\
|
|
||||||
BEGIN { nonempty = 0; } \
|
|
||||||
{ items[$$0] = 1; nonempty = 1; } \
|
|
||||||
END { if (nonempty) { for (i in items) print i; }; } \
|
|
||||||
'
|
|
||||||
# Make sure the list of sources is unique. This is necessary because,
|
|
||||||
# e.g., the same source file might be shared among _SOURCES variables
|
|
||||||
# for different programs/libraries.
|
|
||||||
am__define_uniq_tagged_files = \
|
|
||||||
list='$(am__tagged_files)'; \
|
|
||||||
unique=`for i in $$list; do \
|
|
||||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
|
||||||
done | $(am__uniquify_input)`
|
|
||||||
DIST_SUBDIRS = $(SUBDIRS)
|
|
||||||
am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in AUTHORS \
|
|
||||||
COPYING ChangeLog INSTALL NEWS README compile config.guess \
|
|
||||||
config.sub install-sh ltmain.sh missing
|
|
||||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
|
||||||
distdir = $(PACKAGE)-$(VERSION)
|
|
||||||
top_distdir = $(distdir)
|
|
||||||
am__remove_distdir = \
|
|
||||||
if test -d "$(distdir)"; then \
|
|
||||||
find "$(distdir)" -type d ! -perm -700 -exec chmod u+rwx {} ';' \
|
|
||||||
; rm -rf "$(distdir)" \
|
|
||||||
|| { sleep 5 && rm -rf "$(distdir)"; }; \
|
|
||||||
else :; fi
|
|
||||||
am__post_remove_distdir = $(am__remove_distdir)
|
|
||||||
am__relativize = \
|
|
||||||
dir0=`pwd`; \
|
|
||||||
sed_first='s,^\([^/]*\)/.*$$,\1,'; \
|
|
||||||
sed_rest='s,^[^/]*/*,,'; \
|
|
||||||
sed_last='s,^.*/\([^/]*\)$$,\1,'; \
|
|
||||||
sed_butlast='s,/*[^/]*$$,,'; \
|
|
||||||
while test -n "$$dir1"; do \
|
|
||||||
first=`echo "$$dir1" | sed -e "$$sed_first"`; \
|
|
||||||
if test "$$first" != "."; then \
|
|
||||||
if test "$$first" = ".."; then \
|
|
||||||
dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
|
|
||||||
dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
|
|
||||||
else \
|
|
||||||
first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
|
|
||||||
if test "$$first2" = "$$first"; then \
|
|
||||||
dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
|
|
||||||
else \
|
|
||||||
dir2="../$$dir2"; \
|
|
||||||
fi; \
|
|
||||||
dir0="$$dir0"/"$$first"; \
|
|
||||||
fi; \
|
|
||||||
fi; \
|
|
||||||
dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
|
|
||||||
done; \
|
|
||||||
reldir="$$dir2"
|
|
||||||
DIST_ARCHIVES = $(distdir).tar.gz
|
|
||||||
GZIP_ENV = -9
|
|
||||||
DIST_TARGETS = dist-gzip
|
|
||||||
# Exists only to be overridden by the user if desired.
|
|
||||||
AM_DISTCHECK_DVI_TARGET = dvi
|
|
||||||
distuninstallcheck_listfiles = find . -type f -print
|
|
||||||
am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
|
|
||||||
| sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
|
|
||||||
distcleancheck_listfiles = \
|
|
||||||
find . \( -type f -a \! \
|
|
||||||
\( -name .nfs* -o -name .smb* -o -name .__afs* \) \) -print
|
|
||||||
ACLOCAL = @ACLOCAL@
|
|
||||||
AMTAR = @AMTAR@
|
|
||||||
AM_CFLAGS = @AM_CFLAGS@
|
|
||||||
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
|
|
||||||
AR = @AR@
|
|
||||||
AUTOCONF = @AUTOCONF@
|
|
||||||
AUTOHEADER = @AUTOHEADER@
|
|
||||||
AUTOMAKE = @AUTOMAKE@
|
|
||||||
AWK = @AWK@
|
|
||||||
BASH = @BASH@
|
|
||||||
CC = @CC@
|
|
||||||
CCDEPMODE = @CCDEPMODE@
|
|
||||||
CFLAGS = @CFLAGS@
|
|
||||||
CFLAGS_PIE = @CFLAGS_PIE@
|
|
||||||
CFLAG_VISIBILITY = @CFLAG_VISIBILITY@
|
|
||||||
CPPFLAGS = @CPPFLAGS@
|
|
||||||
CSCOPE = @CSCOPE@
|
|
||||||
CTAGS = @CTAGS@
|
|
||||||
CYGPATH_W = @CYGPATH_W@
|
|
||||||
DEFAULT_CFLAGS = @DEFAULT_CFLAGS@
|
|
||||||
DEFAULT_LDFLAGS = @DEFAULT_LDFLAGS@
|
|
||||||
DEFS = @DEFS@
|
|
||||||
DEPDIR = @DEPDIR@
|
|
||||||
DLLTOOL = @DLLTOOL@
|
|
||||||
DL_LIBS = @DL_LIBS@
|
|
||||||
DSYMUTIL = @DSYMUTIL@
|
|
||||||
DUMPBIN = @DUMPBIN@
|
|
||||||
ECHO_C = @ECHO_C@
|
|
||||||
ECHO_N = @ECHO_N@
|
|
||||||
ECHO_T = @ECHO_T@
|
|
||||||
EGREP = @EGREP@
|
|
||||||
ETAGS = @ETAGS@
|
|
||||||
EXEEXT = @EXEEXT@
|
|
||||||
FGREP = @FGREP@
|
|
||||||
FILECMD = @FILECMD@
|
|
||||||
GREP = @GREP@
|
|
||||||
HAVE_VISIBILITY = @HAVE_VISIBILITY@
|
|
||||||
HTTPS_SUPPORT = @HTTPS_SUPPORT@
|
|
||||||
ICONV_LIBS = @ICONV_LIBS@
|
|
||||||
INSTALL = @INSTALL@
|
|
||||||
INSTALL_DATA = @INSTALL_DATA@
|
|
||||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
|
||||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
|
||||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
|
||||||
LD = @LD@
|
|
||||||
LDFLAGS = @LDFLAGS@
|
|
||||||
LDFLAGS_PIE = @LDFLAGS_PIE@
|
|
||||||
LFS_FLAG = @LFS_FLAG@
|
|
||||||
LIBC_FORCE_LINK = @LIBC_FORCE_LINK@
|
|
||||||
LIBOBJS = @LIBOBJS@
|
|
||||||
LIBS = @LIBS@
|
|
||||||
LIBTOOL = @LIBTOOL@
|
|
||||||
LIPO = @LIPO@
|
|
||||||
LN_S = @LN_S@
|
|
||||||
LTLIBOBJS = @LTLIBOBJS@
|
|
||||||
LT_CV_OBJDIR = @LT_CV_OBJDIR@
|
|
||||||
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
|
|
||||||
MAINT = @MAINT@
|
|
||||||
MAKEINFO = @MAKEINFO@
|
|
||||||
MANIFEST_TOOL = @MANIFEST_TOOL@
|
|
||||||
MKDIR_P = @MKDIR_P@
|
|
||||||
NM = @NM@
|
|
||||||
NMEDIT = @NMEDIT@
|
|
||||||
OBJDUMP = @OBJDUMP@
|
|
||||||
OBJEXT = @OBJEXT@
|
|
||||||
ONLINE_UNIT_TESTS = @ONLINE_UNIT_TESTS@
|
|
||||||
OPENSSL_LIBS = @OPENSSL_LIBS@
|
|
||||||
OTOOL = @OTOOL@
|
|
||||||
OTOOL64 = @OTOOL64@
|
|
||||||
PACKAGE = @PACKAGE@
|
|
||||||
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
|
||||||
PACKAGE_NAME = @PACKAGE_NAME@
|
|
||||||
PACKAGE_STRING = @PACKAGE_STRING@
|
|
||||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
|
||||||
PACKAGE_URL = @PACKAGE_URL@
|
|
||||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
|
||||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
|
||||||
RANLIB = @RANLIB@
|
|
||||||
SED = @SED@
|
|
||||||
SET_MAKE = @SET_MAKE@
|
|
||||||
SHELL = @SHELL@
|
|
||||||
SHLIBPATH_VAR = @SHLIBPATH_VAR@
|
|
||||||
SOCKET_LIBS = @SOCKET_LIBS@
|
|
||||||
STRIP = @STRIP@
|
|
||||||
THREADS_CFLAGS = @THREADS_CFLAGS@
|
|
||||||
THREADS_LIBS = @THREADS_LIBS@
|
|
||||||
V6_FLAG = @V6_FLAG@
|
|
||||||
VERSION = @VERSION@
|
|
||||||
VERSION_INFO = @VERSION_INFO@
|
|
||||||
abs_builddir = @abs_builddir@
|
|
||||||
abs_srcdir = @abs_srcdir@
|
|
||||||
abs_top_builddir = @abs_top_builddir@
|
|
||||||
abs_top_srcdir = @abs_top_srcdir@
|
|
||||||
ac_ct_AR = @ac_ct_AR@
|
|
||||||
ac_ct_CC = @ac_ct_CC@
|
|
||||||
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
|
|
||||||
am__include = @am__include@
|
|
||||||
am__leading_dot = @am__leading_dot@
|
|
||||||
am__quote = @am__quote@
|
|
||||||
am__rm_f_notfound = @am__rm_f_notfound@
|
|
||||||
am__tar = @am__tar@
|
|
||||||
am__untar = @am__untar@
|
|
||||||
am__xargs_n = @am__xargs_n@
|
|
||||||
bindir = @bindir@
|
|
||||||
build = @build@
|
|
||||||
build_alias = @build_alias@
|
|
||||||
build_cpu = @build_cpu@
|
|
||||||
build_os = @build_os@
|
|
||||||
build_vendor = @build_vendor@
|
|
||||||
builddir = @builddir@
|
|
||||||
datadir = @datadir@
|
|
||||||
datarootdir = @datarootdir@
|
|
||||||
docdir = @docdir@
|
|
||||||
dvidir = @dvidir@
|
|
||||||
exec_prefix = @exec_prefix@
|
|
||||||
host = @host@
|
|
||||||
host_alias = @host_alias@
|
|
||||||
host_cpu = @host_cpu@
|
|
||||||
host_os = @host_os@
|
|
||||||
host_vendor = @host_vendor@
|
|
||||||
htmldir = @htmldir@
|
|
||||||
includedir = @includedir@
|
|
||||||
infodir = @infodir@
|
|
||||||
install_sh = @install_sh@
|
|
||||||
libdir = @libdir@
|
|
||||||
libexecdir = @libexecdir@
|
|
||||||
localedir = @localedir@
|
|
||||||
localstatedir = @localstatedir@
|
|
||||||
mandir = @mandir@
|
|
||||||
mkdir_p = @mkdir_p@
|
|
||||||
oldincludedir = @oldincludedir@
|
|
||||||
pdfdir = @pdfdir@
|
|
||||||
prefix = @prefix@
|
|
||||||
program_transform_name = @program_transform_name@
|
|
||||||
psdir = @psdir@
|
|
||||||
runstatedir = @runstatedir@
|
|
||||||
sbindir = @sbindir@
|
|
||||||
sharedstatedir = @sharedstatedir@
|
|
||||||
srcdir = @srcdir@
|
|
||||||
sysconfdir = @sysconfdir@
|
|
||||||
target_alias = @target_alias@
|
|
||||||
top_build_prefix = @top_build_prefix@
|
|
||||||
top_builddir = @top_builddir@
|
|
||||||
top_srcdir = @top_srcdir@
|
|
||||||
SUBDIRS = src man m4 libtest templates lang html tests
|
|
||||||
ACLOCAL_AMFLAGS = -I m4
|
|
||||||
EXTRA_DIST = INSTALL.Linux \
|
|
||||||
gpl-fr.txt license.txt greetings.txt history.txt \
|
|
||||||
httrack-doc.html lang.def README.md tools/mkdeb.sh
|
|
||||||
|
|
||||||
|
|
||||||
# Build the signed Debian packages from a clean source export. Pass the signing
|
|
||||||
# key and other options through DEB_FLAGS, e.g.:
|
|
||||||
# make deb DEB_FLAGS="--key BB71C7E6CB1AD8FAF53FE42A60C3AA7180598EFB"
|
|
||||||
# See tools/mkdeb.sh --help for all options.
|
|
||||||
DEB_FLAGS =
|
|
||||||
all: config.h
|
|
||||||
$(MAKE) $(AM_MAKEFLAGS) all-recursive
|
|
||||||
|
|
||||||
.SUFFIXES:
|
|
||||||
am--refresh: Makefile
|
|
||||||
@:
|
|
||||||
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
|
|
||||||
@for dep in $?; do \
|
|
||||||
case '$(am__configure_deps)' in \
|
|
||||||
*$$dep*) \
|
|
||||||
echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \
|
|
||||||
$(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \
|
|
||||||
&& exit 0; \
|
|
||||||
exit 1;; \
|
|
||||||
esac; \
|
|
||||||
done; \
|
|
||||||
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \
|
|
||||||
$(am__cd) $(top_srcdir) && \
|
|
||||||
$(AUTOMAKE) --gnu Makefile
|
|
||||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
|
||||||
@case '$?' in \
|
|
||||||
*config.status*) \
|
|
||||||
echo ' $(SHELL) ./config.status'; \
|
|
||||||
$(SHELL) ./config.status;; \
|
|
||||||
*) \
|
|
||||||
echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \
|
|
||||||
cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \
|
|
||||||
esac;
|
|
||||||
|
|
||||||
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
|
||||||
$(SHELL) ./config.status --recheck
|
|
||||||
|
|
||||||
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
|
|
||||||
$(am__cd) $(srcdir) && $(AUTOCONF)
|
|
||||||
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
|
|
||||||
$(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
|
|
||||||
$(am__aclocal_m4_deps):
|
|
||||||
|
|
||||||
config.h: stamp-h1
|
|
||||||
@test -f $@ || rm -f stamp-h1
|
|
||||||
@test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1
|
|
||||||
|
|
||||||
stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
|
|
||||||
$(AM_V_at)rm -f stamp-h1
|
|
||||||
$(AM_V_GEN)cd $(top_builddir) && $(SHELL) ./config.status config.h
|
|
||||||
$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
|
|
||||||
$(AM_V_GEN)($(am__cd) $(top_srcdir) && $(AUTOHEADER))
|
|
||||||
$(AM_V_at)rm -f stamp-h1
|
|
||||||
$(AM_V_at)touch $@
|
|
||||||
|
|
||||||
distclean-hdr:
|
|
||||||
-rm -f config.h stamp-h1
|
|
||||||
|
|
||||||
mostlyclean-libtool:
|
|
||||||
-rm -f *.lo
|
|
||||||
|
|
||||||
clean-libtool:
|
|
||||||
-rm -rf .libs _libs
|
|
||||||
|
|
||||||
distclean-libtool:
|
|
||||||
-rm -f libtool config.lt
|
|
||||||
|
|
||||||
# This directory's subdirectories are mostly independent; you can cd
|
|
||||||
# into them and run 'make' without going through this Makefile.
|
|
||||||
# To change the values of 'make' variables: instead of editing Makefiles,
|
|
||||||
# (1) if the variable is set in 'config.status', edit 'config.status'
|
|
||||||
# (which will cause the Makefiles to be regenerated when you run 'make');
|
|
||||||
# (2) otherwise, pass the desired values on the 'make' command line.
|
|
||||||
$(am__recursive_targets):
|
|
||||||
@fail=; \
|
|
||||||
if $(am__make_keepgoing); then \
|
|
||||||
failcom='fail=yes'; \
|
|
||||||
else \
|
|
||||||
failcom='exit 1'; \
|
|
||||||
fi; \
|
|
||||||
dot_seen=no; \
|
|
||||||
target=`echo $@ | sed s/-recursive//`; \
|
|
||||||
case "$@" in \
|
|
||||||
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
|
|
||||||
*) list='$(SUBDIRS)' ;; \
|
|
||||||
esac; \
|
|
||||||
for subdir in $$list; do \
|
|
||||||
echo "Making $$target in $$subdir"; \
|
|
||||||
if test "$$subdir" = "."; then \
|
|
||||||
dot_seen=yes; \
|
|
||||||
local_target="$$target-am"; \
|
|
||||||
else \
|
|
||||||
local_target="$$target"; \
|
|
||||||
fi; \
|
|
||||||
($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|
|
||||||
|| eval $$failcom; \
|
|
||||||
done; \
|
|
||||||
if test "$$dot_seen" = "no"; then \
|
|
||||||
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
|
|
||||||
fi; test -z "$$fail"
|
|
||||||
|
|
||||||
ID: $(am__tagged_files)
|
|
||||||
$(am__define_uniq_tagged_files); mkid -fID $$unique
|
|
||||||
tags: tags-recursive
|
|
||||||
TAGS: tags
|
|
||||||
|
|
||||||
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
|
|
||||||
set x; \
|
|
||||||
here=`pwd`; \
|
|
||||||
if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
|
|
||||||
include_option=--etags-include; \
|
|
||||||
empty_fix=.; \
|
|
||||||
else \
|
|
||||||
include_option=--include; \
|
|
||||||
empty_fix=; \
|
|
||||||
fi; \
|
|
||||||
list='$(SUBDIRS)'; for subdir in $$list; do \
|
|
||||||
if test "$$subdir" = .; then :; else \
|
|
||||||
test ! -f $$subdir/TAGS || \
|
|
||||||
set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
|
|
||||||
fi; \
|
|
||||||
done; \
|
|
||||||
$(am__define_uniq_tagged_files); \
|
|
||||||
shift; \
|
|
||||||
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
|
|
||||||
test -n "$$unique" || unique=$$empty_fix; \
|
|
||||||
if test $$# -gt 0; then \
|
|
||||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
|
||||||
"$$@" $$unique; \
|
|
||||||
else \
|
|
||||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
|
||||||
$$unique; \
|
|
||||||
fi; \
|
|
||||||
fi
|
|
||||||
ctags: ctags-recursive
|
|
||||||
|
|
||||||
CTAGS: ctags
|
|
||||||
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
|
|
||||||
$(am__define_uniq_tagged_files); \
|
|
||||||
test -z "$(CTAGS_ARGS)$$unique" \
|
|
||||||
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
|
|
||||||
$$unique
|
|
||||||
|
|
||||||
GTAGS:
|
|
||||||
here=`$(am__cd) $(top_builddir) && pwd` \
|
|
||||||
&& $(am__cd) $(top_srcdir) \
|
|
||||||
&& gtags -i $(GTAGS_ARGS) "$$here"
|
|
||||||
cscope: cscope.files
|
|
||||||
test ! -s cscope.files \
|
|
||||||
|| $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS)
|
|
||||||
clean-cscope:
|
|
||||||
-rm -f cscope.files
|
|
||||||
cscope.files: clean-cscope cscopelist
|
|
||||||
cscopelist: cscopelist-recursive
|
|
||||||
|
|
||||||
cscopelist-am: $(am__tagged_files)
|
|
||||||
list='$(am__tagged_files)'; \
|
|
||||||
case "$(srcdir)" in \
|
|
||||||
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
|
|
||||||
*) sdir=$(subdir)/$(srcdir) ;; \
|
|
||||||
esac; \
|
|
||||||
for i in $$list; do \
|
|
||||||
if test -f "$$i"; then \
|
|
||||||
echo "$(subdir)/$$i"; \
|
|
||||||
else \
|
|
||||||
echo "$$sdir/$$i"; \
|
|
||||||
fi; \
|
|
||||||
done >> $(top_builddir)/cscope.files
|
|
||||||
|
|
||||||
distclean-tags:
|
|
||||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
|
||||||
-rm -f cscope.out cscope.in.out cscope.po.out cscope.files
|
|
||||||
distdir: $(BUILT_SOURCES)
|
|
||||||
$(MAKE) $(AM_MAKEFLAGS) distdir-am
|
|
||||||
|
|
||||||
distdir-am: $(DISTFILES)
|
|
||||||
$(am__remove_distdir)
|
|
||||||
$(AM_V_at)$(MKDIR_P) "$(distdir)"
|
|
||||||
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
|
||||||
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
|
||||||
list='$(DISTFILES)'; \
|
|
||||||
dist_files=`for file in $$list; do echo $$file; done | \
|
|
||||||
sed -e "s|^$$srcdirstrip/||;t" \
|
|
||||||
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
|
|
||||||
case $$dist_files in \
|
|
||||||
*/*) $(MKDIR_P) `echo "$$dist_files" | \
|
|
||||||
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
|
|
||||||
sort -u` ;; \
|
|
||||||
esac; \
|
|
||||||
for file in $$dist_files; do \
|
|
||||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
|
||||||
if test -d $$d/$$file; then \
|
|
||||||
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
|
|
||||||
if test -d "$(distdir)/$$file"; then \
|
|
||||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
|
||||||
fi; \
|
|
||||||
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
|
||||||
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
|
|
||||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
|
||||||
fi; \
|
|
||||||
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
|
|
||||||
else \
|
|
||||||
test -f "$(distdir)/$$file" \
|
|
||||||
|| cp -p $$d/$$file "$(distdir)/$$file" \
|
|
||||||
|| exit 1; \
|
|
||||||
fi; \
|
|
||||||
done
|
|
||||||
@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
|
|
||||||
if test "$$subdir" = .; then :; else \
|
|
||||||
$(am__make_dryrun) \
|
|
||||||
|| test -d "$(distdir)/$$subdir" \
|
|
||||||
|| $(MKDIR_P) "$(distdir)/$$subdir" \
|
|
||||||
|| exit 1; \
|
|
||||||
dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
|
|
||||||
$(am__relativize); \
|
|
||||||
new_distdir=$$reldir; \
|
|
||||||
dir1=$$subdir; dir2="$(top_distdir)"; \
|
|
||||||
$(am__relativize); \
|
|
||||||
new_top_distdir=$$reldir; \
|
|
||||||
echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
|
|
||||||
echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
|
|
||||||
($(am__cd) $$subdir && \
|
|
||||||
$(MAKE) $(AM_MAKEFLAGS) \
|
|
||||||
top_distdir="$$new_top_distdir" \
|
|
||||||
distdir="$$new_distdir" \
|
|
||||||
am__remove_distdir=: \
|
|
||||||
am__skip_length_check=: \
|
|
||||||
am__skip_mode_fix=: \
|
|
||||||
distdir) \
|
|
||||||
|| exit 1; \
|
|
||||||
fi; \
|
|
||||||
done
|
|
||||||
-test -n "$(am__skip_mode_fix)" \
|
|
||||||
|| find "$(distdir)" -type d ! -perm -755 \
|
|
||||||
-exec chmod u+rwx,go+rx {} \; -o \
|
|
||||||
! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
|
|
||||||
! -type d ! -perm -400 -exec chmod a+r {} \; -o \
|
|
||||||
! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
|
|
||||||
|| chmod -R a+r "$(distdir)"
|
|
||||||
dist-gzip: distdir
|
|
||||||
tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz
|
|
||||||
$(am__post_remove_distdir)
|
|
||||||
|
|
||||||
dist-bzip2: distdir
|
|
||||||
tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
|
|
||||||
$(am__post_remove_distdir)
|
|
||||||
|
|
||||||
dist-lzip: distdir
|
|
||||||
tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz
|
|
||||||
$(am__post_remove_distdir)
|
|
||||||
|
|
||||||
dist-xz: distdir
|
|
||||||
tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
|
|
||||||
$(am__post_remove_distdir)
|
|
||||||
|
|
||||||
dist-zstd: distdir
|
|
||||||
tardir=$(distdir) && $(am__tar) | zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} >$(distdir).tar.zst
|
|
||||||
$(am__post_remove_distdir)
|
|
||||||
|
|
||||||
dist-tarZ: distdir
|
|
||||||
@echo WARNING: "Support for distribution archives compressed with" \
|
|
||||||
"legacy program 'compress' is deprecated." >&2
|
|
||||||
@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
|
|
||||||
tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
|
|
||||||
$(am__post_remove_distdir)
|
|
||||||
|
|
||||||
dist-shar: distdir
|
|
||||||
@echo WARNING: "Support for shar distribution archives is" \
|
|
||||||
"deprecated." >&2
|
|
||||||
@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
|
|
||||||
shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz
|
|
||||||
$(am__post_remove_distdir)
|
|
||||||
|
|
||||||
dist-zip: distdir
|
|
||||||
-rm -f $(distdir).zip
|
|
||||||
zip -rq $(distdir).zip $(distdir)
|
|
||||||
$(am__post_remove_distdir)
|
|
||||||
|
|
||||||
dist dist-all:
|
|
||||||
$(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:'
|
|
||||||
$(am__post_remove_distdir)
|
|
||||||
|
|
||||||
# This target untars the dist file and tries a VPATH configuration. Then
|
|
||||||
# it guarantees that the distribution is self-contained by making another
|
|
||||||
# tarfile.
|
|
||||||
distcheck: dist
|
|
||||||
case '$(DIST_ARCHIVES)' in \
|
|
||||||
*.tar.gz*) \
|
|
||||||
eval GZIP= gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
|
|
||||||
*.tar.bz2*) \
|
|
||||||
bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
|
|
||||||
*.tar.lz*) \
|
|
||||||
lzip -dc $(distdir).tar.lz | $(am__untar) ;;\
|
|
||||||
*.tar.xz*) \
|
|
||||||
xz -dc $(distdir).tar.xz | $(am__untar) ;;\
|
|
||||||
*.tar.Z*) \
|
|
||||||
uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
|
|
||||||
*.shar.gz*) \
|
|
||||||
eval GZIP= gzip -dc $(distdir).shar.gz | unshar ;;\
|
|
||||||
*.zip*) \
|
|
||||||
unzip $(distdir).zip ;;\
|
|
||||||
*.tar.zst*) \
|
|
||||||
zstd -dc $(distdir).tar.zst | $(am__untar) ;;\
|
|
||||||
esac
|
|
||||||
chmod -R a-w $(distdir)
|
|
||||||
chmod u+w $(distdir)
|
|
||||||
mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst
|
|
||||||
chmod a-w $(distdir)
|
|
||||||
test -d $(distdir)/_build || exit 0; \
|
|
||||||
dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
|
|
||||||
&& dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
|
|
||||||
&& am__cwd=`pwd` \
|
|
||||||
&& $(am__cd) $(distdir)/_build/sub \
|
|
||||||
&& ../../configure \
|
|
||||||
$(AM_DISTCHECK_CONFIGURE_FLAGS) \
|
|
||||||
$(DISTCHECK_CONFIGURE_FLAGS) \
|
|
||||||
--srcdir=../.. --prefix="$$dc_install_base" \
|
|
||||||
&& $(MAKE) $(AM_MAKEFLAGS) \
|
|
||||||
&& $(MAKE) $(AM_MAKEFLAGS) $(AM_DISTCHECK_DVI_TARGET) \
|
|
||||||
&& $(MAKE) $(AM_MAKEFLAGS) check \
|
|
||||||
&& $(MAKE) $(AM_MAKEFLAGS) install \
|
|
||||||
&& $(MAKE) $(AM_MAKEFLAGS) installcheck \
|
|
||||||
&& $(MAKE) $(AM_MAKEFLAGS) uninstall \
|
|
||||||
&& $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
|
|
||||||
distuninstallcheck \
|
|
||||||
&& chmod -R a-w "$$dc_install_base" \
|
|
||||||
&& ({ \
|
|
||||||
(cd ../.. && umask 077 && mkdir "$$dc_destdir") \
|
|
||||||
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
|
|
||||||
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
|
|
||||||
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
|
|
||||||
distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
|
|
||||||
} || { rm -rf "$$dc_destdir"; exit 1; }) \
|
|
||||||
&& rm -rf "$$dc_destdir" \
|
|
||||||
&& $(MAKE) $(AM_MAKEFLAGS) dist \
|
|
||||||
&& rm -rf $(DIST_ARCHIVES) \
|
|
||||||
&& $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
|
|
||||||
&& cd "$$am__cwd" \
|
|
||||||
|| exit 1
|
|
||||||
$(am__post_remove_distdir)
|
|
||||||
@(echo "$(distdir) archives ready for distribution: "; \
|
|
||||||
list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
|
|
||||||
sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
|
|
||||||
distuninstallcheck:
|
|
||||||
@test -n '$(distuninstallcheck_dir)' || { \
|
|
||||||
echo 'ERROR: trying to run $@ with an empty' \
|
|
||||||
'$$(distuninstallcheck_dir)' >&2; \
|
|
||||||
exit 1; \
|
|
||||||
}; \
|
|
||||||
$(am__cd) '$(distuninstallcheck_dir)' || { \
|
|
||||||
echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \
|
|
||||||
exit 1; \
|
|
||||||
}; \
|
|
||||||
test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \
|
|
||||||
|| { echo "ERROR: files left after uninstall:" ; \
|
|
||||||
if test -n "$(DESTDIR)"; then \
|
|
||||||
echo " (check DESTDIR support)"; \
|
|
||||||
fi ; \
|
|
||||||
$(distuninstallcheck_listfiles) ; \
|
|
||||||
exit 1; } >&2
|
|
||||||
distcleancheck: distclean
|
|
||||||
@if test '$(srcdir)' = . ; then \
|
|
||||||
echo "ERROR: distcleancheck can only run from a VPATH build" ; \
|
|
||||||
exit 1 ; \
|
|
||||||
fi
|
|
||||||
@test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
|
|
||||||
|| { echo "ERROR: files left in build directory after distclean:" ; \
|
|
||||||
$(distcleancheck_listfiles) ; \
|
|
||||||
exit 1; } >&2
|
|
||||||
check-am: all-am
|
|
||||||
check: check-recursive
|
|
||||||
all-am: Makefile config.h
|
|
||||||
installdirs: installdirs-recursive
|
|
||||||
installdirs-am:
|
|
||||||
install: install-recursive
|
|
||||||
install-exec: install-exec-recursive
|
|
||||||
install-data: install-data-recursive
|
|
||||||
uninstall: uninstall-recursive
|
|
||||||
|
|
||||||
install-am: all-am
|
|
||||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
|
||||||
|
|
||||||
installcheck: installcheck-recursive
|
|
||||||
install-strip:
|
|
||||||
if test -z '$(STRIP)'; then \
|
|
||||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
|
||||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
|
||||||
install; \
|
|
||||||
else \
|
|
||||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
|
||||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
|
||||||
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
|
|
||||||
fi
|
|
||||||
mostlyclean-generic:
|
|
||||||
|
|
||||||
clean-generic:
|
|
||||||
|
|
||||||
distclean-generic:
|
|
||||||
-$(am__rm_f) $(CONFIG_CLEAN_FILES)
|
|
||||||
-test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES)
|
|
||||||
|
|
||||||
maintainer-clean-generic:
|
|
||||||
@echo "This command is intended for maintainers to use"
|
|
||||||
@echo "it deletes files that may require special tools to rebuild."
|
|
||||||
clean: clean-recursive
|
|
||||||
|
|
||||||
clean-am: clean-generic clean-libtool mostlyclean-am
|
|
||||||
|
|
||||||
distclean: distclean-recursive
|
|
||||||
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
|
|
||||||
-rm -f Makefile
|
|
||||||
distclean-am: clean-am distclean-generic distclean-hdr \
|
|
||||||
distclean-libtool distclean-tags
|
|
||||||
|
|
||||||
dvi: dvi-recursive
|
|
||||||
|
|
||||||
dvi-am:
|
|
||||||
|
|
||||||
html: html-recursive
|
|
||||||
|
|
||||||
html-am:
|
|
||||||
|
|
||||||
info: info-recursive
|
|
||||||
|
|
||||||
info-am:
|
|
||||||
|
|
||||||
install-data-am:
|
|
||||||
|
|
||||||
install-dvi: install-dvi-recursive
|
|
||||||
|
|
||||||
install-dvi-am:
|
|
||||||
|
|
||||||
install-exec-am:
|
|
||||||
|
|
||||||
install-html: install-html-recursive
|
|
||||||
|
|
||||||
install-html-am:
|
|
||||||
|
|
||||||
install-info: install-info-recursive
|
|
||||||
|
|
||||||
install-info-am:
|
|
||||||
|
|
||||||
install-man:
|
|
||||||
|
|
||||||
install-pdf: install-pdf-recursive
|
|
||||||
|
|
||||||
install-pdf-am:
|
|
||||||
|
|
||||||
install-ps: install-ps-recursive
|
|
||||||
|
|
||||||
install-ps-am:
|
|
||||||
|
|
||||||
installcheck-am:
|
|
||||||
|
|
||||||
maintainer-clean: maintainer-clean-recursive
|
|
||||||
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
|
|
||||||
-rm -rf $(top_srcdir)/autom4te.cache
|
|
||||||
-rm -f Makefile
|
|
||||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
|
||||||
|
|
||||||
mostlyclean: mostlyclean-recursive
|
|
||||||
|
|
||||||
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
|
|
||||||
|
|
||||||
pdf: pdf-recursive
|
|
||||||
|
|
||||||
pdf-am:
|
|
||||||
|
|
||||||
ps: ps-recursive
|
|
||||||
|
|
||||||
ps-am:
|
|
||||||
|
|
||||||
uninstall-am:
|
|
||||||
|
|
||||||
.MAKE: $(am__recursive_targets) all install-am install-strip
|
|
||||||
|
|
||||||
.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \
|
|
||||||
am--refresh check check-am clean clean-cscope clean-generic \
|
|
||||||
clean-libtool cscope cscopelist-am ctags ctags-am dist \
|
|
||||||
dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \
|
|
||||||
dist-xz dist-zip dist-zstd distcheck distclean \
|
|
||||||
distclean-generic distclean-hdr distclean-libtool \
|
|
||||||
distclean-tags distcleancheck distdir distuninstallcheck dvi \
|
|
||||||
dvi-am html html-am info info-am install install-am \
|
|
||||||
install-data install-data-am install-dvi install-dvi-am \
|
|
||||||
install-exec install-exec-am install-html install-html-am \
|
|
||||||
install-info install-info-am install-man install-pdf \
|
|
||||||
install-pdf-am install-ps install-ps-am install-strip \
|
|
||||||
installcheck installcheck-am installdirs installdirs-am \
|
|
||||||
maintainer-clean maintainer-clean-generic mostlyclean \
|
|
||||||
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
|
|
||||||
tags tags-am uninstall uninstall-am
|
|
||||||
|
|
||||||
.PRECIOUS: Makefile
|
|
||||||
|
|
||||||
deb:
|
|
||||||
$(SHELL) $(top_srcdir)/tools/mkdeb.sh $(DEB_FLAGS)
|
|
||||||
.PHONY: deb
|
|
||||||
|
|
||||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
|
||||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
|
||||||
.NOEXPORT:
|
|
||||||
|
|
||||||
# Tell GNU make to disable its built-in pattern rules.
|
|
||||||
%:: %,v
|
|
||||||
%:: RCS/%,v
|
|
||||||
%:: RCS/%
|
|
||||||
%:: s.%
|
|
||||||
%:: SCCS/s.%
|
|
||||||
14
README.md
14
README.md
@@ -22,8 +22,22 @@ HTTrack can also update an existing mirrored site, and resume interrupted downlo
|
|||||||
http://www.httrack.com/
|
http://www.httrack.com/
|
||||||
|
|
||||||
## Compile trunk release
|
## Compile trunk release
|
||||||
|
|
||||||
|
A git checkout ships only the autotools sources, so `./bootstrap` (which runs
|
||||||
|
`autoreconf`) regenerates `configure` first; this needs autoconf, automake and
|
||||||
|
libtool. Released tarballs already include `configure`, so building from a
|
||||||
|
tarball skips `./bootstrap`.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
git clone https://github.com/xroche/httrack.git --recurse-submodules
|
git clone https://github.com/xroche/httrack.git --recurse-submodules
|
||||||
cd httrack
|
cd httrack
|
||||||
|
./bootstrap
|
||||||
./configure --prefix=$HOME/usr && make -j8 && make install
|
./configure --prefix=$HOME/usr && make -j8 && make install
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Or use the one-shot wrapper (bootstrap + configure + make), which forwards its
|
||||||
|
arguments to `configure`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
./build.sh --prefix=$HOME/usr
|
||||||
|
```
|
||||||
|
|||||||
24
bootstrap
Executable file
24
bootstrap
Executable file
@@ -0,0 +1,24 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# Regenerate the autotools build system (configure, Makefile.in, config.h.in,
|
||||||
|
# libtool, the aux scripts) from configure.ac and the Makefile.am files.
|
||||||
|
#
|
||||||
|
# Run this once after a fresh git clone, before ./configure. Release tarballs
|
||||||
|
# (made with "make dist") already ship these files, so people building from a
|
||||||
|
# tarball do not need autotools and do not run this.
|
||||||
|
#
|
||||||
|
# Requires: autoconf, automake, libtool (the autoreconf toolchain).
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# shellcheck disable=SC1007 # "CDPATH= cd" is a deliberate empty-CDPATH prefix.
|
||||||
|
srcdir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
||||||
|
cd "$srcdir"
|
||||||
|
|
||||||
|
if ! command -v autoreconf >/dev/null 2>&1; then
|
||||||
|
echo "bootstrap: autoreconf not found; install autoconf, automake and libtool" >&2
|
||||||
|
echo " (or build from a release tarball, which ships ./configure)" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
exec autoreconf -fi "$@"
|
||||||
34
build.sh
Executable file
34
build.sh
Executable file
@@ -0,0 +1,34 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# One-shot build from a git checkout: bootstrap (autoreconf) -> configure -> make.
|
||||||
|
# A convenience wrapper; the canonical steps are ./bootstrap && ./configure && make.
|
||||||
|
#
|
||||||
|
# Extra arguments are passed straight to ./configure, e.g.
|
||||||
|
# ./build.sh --prefix="$HOME" --disable-https
|
||||||
|
#
|
||||||
|
# Build out of tree (recommended; required if the source tree is read-only or
|
||||||
|
# mounted noexec) by pointing BUILD_DIR at a scratch directory:
|
||||||
|
# BUILD_DIR=/var/tmp/httrack-build ./build.sh
|
||||||
|
#
|
||||||
|
# On a noexec filesystem the executable bit does not take effect, so invoke the
|
||||||
|
# script explicitly with sh: sh build.sh
|
||||||
|
#
|
||||||
|
# Requires autoconf/automake/libtool (for bootstrap); the release tarball ships
|
||||||
|
# ./configure, so from a tarball just run ./configure && make.
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# shellcheck disable=SC1007 # "CDPATH= cd" is a deliberate empty-CDPATH prefix.
|
||||||
|
srcdir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
||||||
|
|
||||||
|
# 1. Regenerate the build system in the source tree (autotools requires it).
|
||||||
|
sh "$srcdir/bootstrap"
|
||||||
|
|
||||||
|
# 2. Configure and build, out of tree when BUILD_DIR is set.
|
||||||
|
builddir=${BUILD_DIR:-$srcdir}
|
||||||
|
mkdir -p "$builddir"
|
||||||
|
cd "$builddir"
|
||||||
|
# Invoke configure via the shell, not execve: it is a portable sh script, and a
|
||||||
|
# noexec source tree (or a cleared executable bit) would make ./configure fail.
|
||||||
|
"${CONFIG_SHELL:-/bin/sh}" "$srcdir/configure" "$@"
|
||||||
|
make
|
||||||
351
compile
351
compile
@@ -1,351 +0,0 @@
|
|||||||
#! /bin/sh
|
|
||||||
# Wrapper for compilers which do not understand '-c -o'.
|
|
||||||
|
|
||||||
scriptversion=2024-06-19.01; # UTC
|
|
||||||
|
|
||||||
# Copyright (C) 1999-2024 Free Software Foundation, Inc.
|
|
||||||
# Written by Tom Tromey <tromey@cygnus.com>.
|
|
||||||
#
|
|
||||||
# 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 2, 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 <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
# As a special exception to the GNU General Public License, if you
|
|
||||||
# distribute this file as part of a program that contains a
|
|
||||||
# configuration script generated by Autoconf, you may include it under
|
|
||||||
# the same distribution terms that you use for the rest of that program.
|
|
||||||
|
|
||||||
# This file is maintained in Automake, please report
|
|
||||||
# bugs to <bug-automake@gnu.org> or send patches to
|
|
||||||
# <automake-patches@gnu.org>.
|
|
||||||
|
|
||||||
nl='
|
|
||||||
'
|
|
||||||
|
|
||||||
# We need space, tab and new line, in precisely that order. Quoting is
|
|
||||||
# there to prevent tools from complaining about whitespace usage.
|
|
||||||
IFS=" "" $nl"
|
|
||||||
|
|
||||||
file_conv=
|
|
||||||
|
|
||||||
# func_file_conv build_file lazy
|
|
||||||
# Convert a $build file to $host form and store it in $file
|
|
||||||
# Currently only supports Windows hosts. If the determined conversion
|
|
||||||
# type is listed in (the comma separated) LAZY, no conversion will
|
|
||||||
# take place.
|
|
||||||
func_file_conv ()
|
|
||||||
{
|
|
||||||
file=$1
|
|
||||||
case $file in
|
|
||||||
/ | /[!/]*) # absolute file, and not a UNC file
|
|
||||||
if test -z "$file_conv"; then
|
|
||||||
# lazily determine how to convert abs files
|
|
||||||
case `uname -s` in
|
|
||||||
MINGW*)
|
|
||||||
file_conv=mingw
|
|
||||||
;;
|
|
||||||
CYGWIN* | MSYS*)
|
|
||||||
file_conv=cygwin
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
file_conv=wine
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
case $file_conv/,$2, in
|
|
||||||
*,$file_conv,*)
|
|
||||||
;;
|
|
||||||
mingw/*)
|
|
||||||
file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
|
|
||||||
;;
|
|
||||||
cygwin/* | msys/*)
|
|
||||||
file=`cygpath -m "$file" || echo "$file"`
|
|
||||||
;;
|
|
||||||
wine/*)
|
|
||||||
file=`winepath -w "$file" || echo "$file"`
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
# func_cl_dashL linkdir
|
|
||||||
# Make cl look for libraries in LINKDIR
|
|
||||||
func_cl_dashL ()
|
|
||||||
{
|
|
||||||
func_file_conv "$1"
|
|
||||||
if test -z "$lib_path"; then
|
|
||||||
lib_path=$file
|
|
||||||
else
|
|
||||||
lib_path="$lib_path;$file"
|
|
||||||
fi
|
|
||||||
linker_opts="$linker_opts -LIBPATH:$file"
|
|
||||||
}
|
|
||||||
|
|
||||||
# func_cl_dashl library
|
|
||||||
# Do a library search-path lookup for cl
|
|
||||||
func_cl_dashl ()
|
|
||||||
{
|
|
||||||
lib=$1
|
|
||||||
found=no
|
|
||||||
save_IFS=$IFS
|
|
||||||
IFS=';'
|
|
||||||
for dir in $lib_path $LIB
|
|
||||||
do
|
|
||||||
IFS=$save_IFS
|
|
||||||
if $shared && test -f "$dir/$lib.dll.lib"; then
|
|
||||||
found=yes
|
|
||||||
lib=$dir/$lib.dll.lib
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
if test -f "$dir/$lib.lib"; then
|
|
||||||
found=yes
|
|
||||||
lib=$dir/$lib.lib
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
if test -f "$dir/lib$lib.a"; then
|
|
||||||
found=yes
|
|
||||||
lib=$dir/lib$lib.a
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
IFS=$save_IFS
|
|
||||||
|
|
||||||
if test "$found" != yes; then
|
|
||||||
lib=$lib.lib
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# func_cl_wrapper cl arg...
|
|
||||||
# Adjust compile command to suit cl
|
|
||||||
func_cl_wrapper ()
|
|
||||||
{
|
|
||||||
# Assume a capable shell
|
|
||||||
lib_path=
|
|
||||||
shared=:
|
|
||||||
linker_opts=
|
|
||||||
for arg
|
|
||||||
do
|
|
||||||
if test -n "$eat"; then
|
|
||||||
eat=
|
|
||||||
else
|
|
||||||
case $1 in
|
|
||||||
-o)
|
|
||||||
# configure might choose to run compile as 'compile cc -o foo foo.c'.
|
|
||||||
eat=1
|
|
||||||
case $2 in
|
|
||||||
*.o | *.lo | *.[oO][bB][jJ])
|
|
||||||
func_file_conv "$2"
|
|
||||||
set x "$@" -Fo"$file"
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
func_file_conv "$2"
|
|
||||||
set x "$@" -Fe"$file"
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
-I)
|
|
||||||
eat=1
|
|
||||||
func_file_conv "$2" mingw
|
|
||||||
set x "$@" -I"$file"
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
-I*)
|
|
||||||
func_file_conv "${1#-I}" mingw
|
|
||||||
set x "$@" -I"$file"
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
-l)
|
|
||||||
eat=1
|
|
||||||
func_cl_dashl "$2"
|
|
||||||
set x "$@" "$lib"
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
-l*)
|
|
||||||
func_cl_dashl "${1#-l}"
|
|
||||||
set x "$@" "$lib"
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
-L)
|
|
||||||
eat=1
|
|
||||||
func_cl_dashL "$2"
|
|
||||||
;;
|
|
||||||
-L*)
|
|
||||||
func_cl_dashL "${1#-L}"
|
|
||||||
;;
|
|
||||||
-static)
|
|
||||||
shared=false
|
|
||||||
;;
|
|
||||||
-Wl,*)
|
|
||||||
arg=${1#-Wl,}
|
|
||||||
save_ifs="$IFS"; IFS=','
|
|
||||||
for flag in $arg; do
|
|
||||||
IFS="$save_ifs"
|
|
||||||
linker_opts="$linker_opts $flag"
|
|
||||||
done
|
|
||||||
IFS="$save_ifs"
|
|
||||||
;;
|
|
||||||
-Xlinker)
|
|
||||||
eat=1
|
|
||||||
linker_opts="$linker_opts $2"
|
|
||||||
;;
|
|
||||||
-*)
|
|
||||||
set x "$@" "$1"
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
*.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
|
|
||||||
func_file_conv "$1"
|
|
||||||
set x "$@" -Tp"$file"
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
*.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
|
|
||||||
func_file_conv "$1" mingw
|
|
||||||
set x "$@" "$file"
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
set x "$@" "$1"
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
shift
|
|
||||||
done
|
|
||||||
if test -n "$linker_opts"; then
|
|
||||||
linker_opts="-link$linker_opts"
|
|
||||||
fi
|
|
||||||
exec "$@" $linker_opts
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
eat=
|
|
||||||
|
|
||||||
case $1 in
|
|
||||||
'')
|
|
||||||
echo "$0: No command. Try '$0 --help' for more information." 1>&2
|
|
||||||
exit 1;
|
|
||||||
;;
|
|
||||||
-h | --h*)
|
|
||||||
cat <<\EOF
|
|
||||||
Usage: compile [--help] [--version] PROGRAM [ARGS]
|
|
||||||
|
|
||||||
Wrapper for compilers which do not understand '-c -o'.
|
|
||||||
Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
|
|
||||||
arguments, and rename the output as expected.
|
|
||||||
|
|
||||||
If you are trying to build a whole package this is not the
|
|
||||||
right script to run: please start by reading the file 'INSTALL'.
|
|
||||||
|
|
||||||
Report bugs to <bug-automake@gnu.org>.
|
|
||||||
GNU Automake home page: <https://www.gnu.org/software/automake/>.
|
|
||||||
General help using GNU software: <https://www.gnu.org/gethelp/>.
|
|
||||||
EOF
|
|
||||||
exit $?
|
|
||||||
;;
|
|
||||||
-v | --v*)
|
|
||||||
echo "compile (GNU Automake) $scriptversion"
|
|
||||||
exit $?
|
|
||||||
;;
|
|
||||||
cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \
|
|
||||||
clang-cl | *[/\\]clang-cl | clang-cl.exe | *[/\\]clang-cl.exe | \
|
|
||||||
icl | *[/\\]icl | icl.exe | *[/\\]icl.exe )
|
|
||||||
func_cl_wrapper "$@" # Doesn't return...
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
ofile=
|
|
||||||
cfile=
|
|
||||||
|
|
||||||
for arg
|
|
||||||
do
|
|
||||||
if test -n "$eat"; then
|
|
||||||
eat=
|
|
||||||
else
|
|
||||||
case $1 in
|
|
||||||
-o)
|
|
||||||
# configure might choose to run compile as 'compile cc -o foo foo.c'.
|
|
||||||
# So we strip '-o arg' only if arg is an object.
|
|
||||||
eat=1
|
|
||||||
case $2 in
|
|
||||||
*.o | *.obj)
|
|
||||||
ofile=$2
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
set x "$@" -o "$2"
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
*.c)
|
|
||||||
cfile=$1
|
|
||||||
set x "$@" "$1"
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
set x "$@" "$1"
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
shift
|
|
||||||
done
|
|
||||||
|
|
||||||
if test -z "$ofile" || test -z "$cfile"; then
|
|
||||||
# If no '-o' option was seen then we might have been invoked from a
|
|
||||||
# pattern rule where we don't need one. That is ok -- this is a
|
|
||||||
# normal compilation that the losing compiler can handle. If no
|
|
||||||
# '.c' file was seen then we are probably linking. That is also
|
|
||||||
# ok.
|
|
||||||
exec "$@"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Name of file we expect compiler to create.
|
|
||||||
cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
|
|
||||||
|
|
||||||
# Create the lock directory.
|
|
||||||
# Note: use '[/\\:.-]' here to ensure that we don't use the same name
|
|
||||||
# that we are using for the .o file. Also, base the name on the expected
|
|
||||||
# object file name, since that is what matters with a parallel build.
|
|
||||||
lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
|
|
||||||
while true; do
|
|
||||||
if mkdir "$lockdir" >/dev/null 2>&1; then
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
sleep 1
|
|
||||||
done
|
|
||||||
# FIXME: race condition here if user kills between mkdir and trap.
|
|
||||||
trap "rmdir '$lockdir'; exit 1" 1 2 15
|
|
||||||
|
|
||||||
# Run the compile.
|
|
||||||
"$@"
|
|
||||||
ret=$?
|
|
||||||
|
|
||||||
if test -f "$cofile"; then
|
|
||||||
test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
|
|
||||||
elif test -f "${cofile}bj"; then
|
|
||||||
test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
|
|
||||||
fi
|
|
||||||
|
|
||||||
rmdir "$lockdir"
|
|
||||||
exit $ret
|
|
||||||
|
|
||||||
# Local Variables:
|
|
||||||
# mode: shell-script
|
|
||||||
# sh-indentation: 2
|
|
||||||
# eval: (add-hook 'before-save-hook 'time-stamp)
|
|
||||||
# time-stamp-start: "scriptversion="
|
|
||||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
|
||||||
# time-stamp-time-zone: "UTC0"
|
|
||||||
# time-stamp-end: "; # UTC"
|
|
||||||
# End:
|
|
||||||
1815
config.guess
vendored
1815
config.guess
vendored
File diff suppressed because it is too large
Load Diff
222
config.h.in
222
config.h.in
@@ -1,222 +0,0 @@
|
|||||||
/* config.h.in. Generated from configure.ac by autoheader. */
|
|
||||||
|
|
||||||
/* Check for dlopen in c */
|
|
||||||
#undef DLLIB
|
|
||||||
|
|
||||||
/* Define if pointers to integers require aligned access */
|
|
||||||
#undef HAVE_ALIGNED_ACCESS_REQUIRED
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
|
||||||
#undef HAVE_DLFCN_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <execinfo.h> header file. */
|
|
||||||
#undef HAVE_EXECINFO_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
|
||||||
#undef HAVE_INTTYPES_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the 'z' library (-lz). */
|
|
||||||
#undef HAVE_LIBZ
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <minix/config.h> header file. */
|
|
||||||
#undef HAVE_MINIX_CONFIG_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the 'snprintf' function. */
|
|
||||||
#undef HAVE_SNPRINTF
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <stdint.h> header file. */
|
|
||||||
#undef HAVE_STDINT_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <stdio.h> header file. */
|
|
||||||
#undef HAVE_STDIO_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
|
||||||
#undef HAVE_STDLIB_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <strings.h> header file. */
|
|
||||||
#undef HAVE_STRINGS_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <string.h> header file. */
|
|
||||||
#undef HAVE_STRING_H
|
|
||||||
|
|
||||||
/* Check for strnlen */
|
|
||||||
#undef HAVE_STRNLEN
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
|
||||||
#undef HAVE_SYS_STAT_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
|
||||||
#undef HAVE_SYS_TYPES_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <unistd.h> header file. */
|
|
||||||
#undef HAVE_UNISTD_H
|
|
||||||
|
|
||||||
/* Define to 1 or 0, depending whether the compiler supports simple visibility
|
|
||||||
declarations. */
|
|
||||||
#undef HAVE_VISIBILITY
|
|
||||||
|
|
||||||
/* Define to 1 if you have the 'vsnprintf' function. */
|
|
||||||
#undef HAVE_VSNPRINTF
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <wchar.h> header file. */
|
|
||||||
#undef HAVE_WCHAR_H
|
|
||||||
|
|
||||||
/* Check for in_addr_t */
|
|
||||||
#undef HTS_DO_NOT_REDEFINE_in_addr_t
|
|
||||||
|
|
||||||
/* Check for IPv6 */
|
|
||||||
#undef HTS_INET6
|
|
||||||
|
|
||||||
/* Check for large files support */
|
|
||||||
#undef HTS_LFS
|
|
||||||
|
|
||||||
/* Check for OpenSSL */
|
|
||||||
#undef HTS_USEOPENSSL
|
|
||||||
|
|
||||||
/* Check for libiconv */
|
|
||||||
#undef LIBICONV
|
|
||||||
|
|
||||||
/* Check for libsocket */
|
|
||||||
#undef LIBSOCKET
|
|
||||||
|
|
||||||
/* Define to the sub-directory where libtool stores uninstalled libraries. */
|
|
||||||
#undef LT_OBJDIR
|
|
||||||
|
|
||||||
/* Name of package */
|
|
||||||
#undef PACKAGE
|
|
||||||
|
|
||||||
/* Define to the address where bug reports for this package should be sent. */
|
|
||||||
#undef PACKAGE_BUGREPORT
|
|
||||||
|
|
||||||
/* Define to the full name of this package. */
|
|
||||||
#undef PACKAGE_NAME
|
|
||||||
|
|
||||||
/* Define to the full name and version of this package. */
|
|
||||||
#undef PACKAGE_STRING
|
|
||||||
|
|
||||||
/* Define to the one symbol short name of this package. */
|
|
||||||
#undef PACKAGE_TARNAME
|
|
||||||
|
|
||||||
/* Define to the home page for this package. */
|
|
||||||
#undef PACKAGE_URL
|
|
||||||
|
|
||||||
/* Define to the version of this package. */
|
|
||||||
#undef PACKAGE_VERSION
|
|
||||||
|
|
||||||
/* "enable replacement (v)snprintf if system (v)snprintf is broken" */
|
|
||||||
#undef PREFER_PORTABLE_SNPRINTF
|
|
||||||
|
|
||||||
/* Check for setuid */
|
|
||||||
#undef SETUID
|
|
||||||
|
|
||||||
/* The size of 'long long', as computed by sizeof. */
|
|
||||||
#undef SIZEOF_LONG_LONG
|
|
||||||
|
|
||||||
/* Define to 1 if all of the C89 standard headers exist (not just the ones
|
|
||||||
required in a freestanding environment). This macro is provided for
|
|
||||||
backward compatibility; new code need not use it. */
|
|
||||||
#undef STDC_HEADERS
|
|
||||||
|
|
||||||
/* Check for pthread in pthreads */
|
|
||||||
#undef THREADS
|
|
||||||
|
|
||||||
/* Enable extensions on AIX, Interix, z/OS. */
|
|
||||||
#ifndef _ALL_SOURCE
|
|
||||||
# undef _ALL_SOURCE
|
|
||||||
#endif
|
|
||||||
/* Enable general extensions on macOS. */
|
|
||||||
#ifndef _DARWIN_C_SOURCE
|
|
||||||
# undef _DARWIN_C_SOURCE
|
|
||||||
#endif
|
|
||||||
/* Enable general extensions on Solaris. */
|
|
||||||
#ifndef __EXTENSIONS__
|
|
||||||
# undef __EXTENSIONS__
|
|
||||||
#endif
|
|
||||||
/* Enable GNU extensions on systems that have them. */
|
|
||||||
#ifndef _GNU_SOURCE
|
|
||||||
# undef _GNU_SOURCE
|
|
||||||
#endif
|
|
||||||
/* Enable X/Open compliant socket functions that do not require linking
|
|
||||||
with -lxnet on HP-UX 11.11. */
|
|
||||||
#ifndef _HPUX_ALT_XOPEN_SOCKET_API
|
|
||||||
# undef _HPUX_ALT_XOPEN_SOCKET_API
|
|
||||||
#endif
|
|
||||||
/* Identify the host operating system as Minix.
|
|
||||||
This macro does not affect the system headers' behavior.
|
|
||||||
A future release of Autoconf may stop defining this macro. */
|
|
||||||
#ifndef _MINIX
|
|
||||||
# undef _MINIX
|
|
||||||
#endif
|
|
||||||
/* Enable general extensions on NetBSD.
|
|
||||||
Enable NetBSD compatibility extensions on Minix. */
|
|
||||||
#ifndef _NETBSD_SOURCE
|
|
||||||
# undef _NETBSD_SOURCE
|
|
||||||
#endif
|
|
||||||
/* Enable OpenBSD compatibility extensions on NetBSD.
|
|
||||||
Oddly enough, this does nothing on OpenBSD. */
|
|
||||||
#ifndef _OPENBSD_SOURCE
|
|
||||||
# undef _OPENBSD_SOURCE
|
|
||||||
#endif
|
|
||||||
/* Define to 1 if needed for POSIX-compatible behavior. */
|
|
||||||
#ifndef _POSIX_SOURCE
|
|
||||||
# undef _POSIX_SOURCE
|
|
||||||
#endif
|
|
||||||
/* Define to 2 if needed for POSIX-compatible behavior. */
|
|
||||||
#ifndef _POSIX_1_SOURCE
|
|
||||||
# undef _POSIX_1_SOURCE
|
|
||||||
#endif
|
|
||||||
/* Enable POSIX-compatible threading on Solaris. */
|
|
||||||
#ifndef _POSIX_PTHREAD_SEMANTICS
|
|
||||||
# undef _POSIX_PTHREAD_SEMANTICS
|
|
||||||
#endif
|
|
||||||
/* Enable extensions specified by ISO/IEC TS 18661-5:2014. */
|
|
||||||
#ifndef __STDC_WANT_IEC_60559_ATTRIBS_EXT__
|
|
||||||
# undef __STDC_WANT_IEC_60559_ATTRIBS_EXT__
|
|
||||||
#endif
|
|
||||||
/* Enable extensions specified by ISO/IEC TS 18661-1:2014. */
|
|
||||||
#ifndef __STDC_WANT_IEC_60559_BFP_EXT__
|
|
||||||
# undef __STDC_WANT_IEC_60559_BFP_EXT__
|
|
||||||
#endif
|
|
||||||
/* Enable extensions specified by ISO/IEC TS 18661-2:2015. */
|
|
||||||
#ifndef __STDC_WANT_IEC_60559_DFP_EXT__
|
|
||||||
# undef __STDC_WANT_IEC_60559_DFP_EXT__
|
|
||||||
#endif
|
|
||||||
/* Enable extensions specified by C23 Annex F. */
|
|
||||||
#ifndef __STDC_WANT_IEC_60559_EXT__
|
|
||||||
# undef __STDC_WANT_IEC_60559_EXT__
|
|
||||||
#endif
|
|
||||||
/* Enable extensions specified by ISO/IEC TS 18661-4:2015. */
|
|
||||||
#ifndef __STDC_WANT_IEC_60559_FUNCS_EXT__
|
|
||||||
# undef __STDC_WANT_IEC_60559_FUNCS_EXT__
|
|
||||||
#endif
|
|
||||||
/* Enable extensions specified by C23 Annex H and ISO/IEC TS 18661-3:2015. */
|
|
||||||
#ifndef __STDC_WANT_IEC_60559_TYPES_EXT__
|
|
||||||
# undef __STDC_WANT_IEC_60559_TYPES_EXT__
|
|
||||||
#endif
|
|
||||||
/* Enable extensions specified by ISO/IEC TR 24731-2:2010. */
|
|
||||||
#ifndef __STDC_WANT_LIB_EXT2__
|
|
||||||
# undef __STDC_WANT_LIB_EXT2__
|
|
||||||
#endif
|
|
||||||
/* Enable extensions specified by ISO/IEC 24747:2009. */
|
|
||||||
#ifndef __STDC_WANT_MATH_SPEC_FUNCS__
|
|
||||||
# undef __STDC_WANT_MATH_SPEC_FUNCS__
|
|
||||||
#endif
|
|
||||||
/* Enable extensions on HP NonStop. */
|
|
||||||
#ifndef _TANDEM_SOURCE
|
|
||||||
# undef _TANDEM_SOURCE
|
|
||||||
#endif
|
|
||||||
/* Enable X/Open extensions. Define to 500 only if necessary
|
|
||||||
to make mbstate_t available. */
|
|
||||||
#ifndef _XOPEN_SOURCE
|
|
||||||
# undef _XOPEN_SOURCE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* Version number of package */
|
|
||||||
#undef VERSION
|
|
||||||
|
|
||||||
/* in_port_t */
|
|
||||||
#undef in_port_t
|
|
||||||
|
|
||||||
/* sa_family_t */
|
|
||||||
#undef sa_family_t
|
|
||||||
2354
config.sub
vendored
2354
config.sub
vendored
File diff suppressed because it is too large
Load Diff
17
configure.ac
17
configure.ac
@@ -1,6 +1,6 @@
|
|||||||
AC_PREREQ([2.71])
|
AC_PREREQ([2.71])
|
||||||
|
|
||||||
AC_INIT([httrack], [3.49.8], [roche+packaging@httrack.com], [httrack], [http://www.httrack.com/])
|
AC_INIT([httrack], [3.49.9], [roche+packaging@httrack.com], [httrack], [http://www.httrack.com/])
|
||||||
AC_COPYRIGHT([
|
AC_COPYRIGHT([
|
||||||
HTTrack Website Copier, Offline Browser for Windows and Unix
|
HTTrack Website Copier, Offline Browser for Windows and Unix
|
||||||
Copyright (C) 1998-2015 Xavier Roche and other contributors
|
Copyright (C) 1998-2015 Xavier Roche and other contributors
|
||||||
@@ -29,9 +29,10 @@ AC_CONFIG_SRCDIR(src/httrack.c)
|
|||||||
AC_CONFIG_MACRO_DIR([m4])
|
AC_CONFIG_MACRO_DIR([m4])
|
||||||
AC_CONFIG_HEADERS(config.h)
|
AC_CONFIG_HEADERS(config.h)
|
||||||
AM_INIT_AUTOMAKE([subdir-objects])
|
AM_INIT_AUTOMAKE([subdir-objects])
|
||||||
# 3:0:0: htsblk layout changed (contenttype/charset/contentencoding widened to
|
# 3:1:0: 3.49.9 changed code but not the exported interface vs 3.49.8 (same 164
|
||||||
# 128), an incompatible ABI break, so bump current and reset revision/age.
|
# symbols, no struct-layout change), so bump revision only. (3:0:0 was the htsblk
|
||||||
VERSION_INFO="3:0:0"
|
# mime-buffer widening, an ABI break that moved the soname .so.2 -> .so.3.)
|
||||||
|
VERSION_INFO="3:1:0"
|
||||||
AM_MAINTAINER_MODE
|
AM_MAINTAINER_MODE
|
||||||
AC_USE_SYSTEM_EXTENSIONS
|
AC_USE_SYSTEM_EXTENSIONS
|
||||||
|
|
||||||
@@ -84,6 +85,11 @@ AX_CHECK_COMPILE_FLAG([-Wformat-nonliteral], [DEFAULT_CFLAGS="$DEFAULT_CFLAGS -W
|
|||||||
AX_CHECK_COMPILE_FLAG([-Wmissing-parameter-type], [DEFAULT_CFLAGS="$DEFAULT_CFLAGS -Wmissing-parameter-type"])
|
AX_CHECK_COMPILE_FLAG([-Wmissing-parameter-type], [DEFAULT_CFLAGS="$DEFAULT_CFLAGS -Wmissing-parameter-type"])
|
||||||
AX_CHECK_COMPILE_FLAG([-Wold-style-definition], [DEFAULT_CFLAGS="$DEFAULT_CFLAGS -Wold-style-definition"])
|
AX_CHECK_COMPILE_FLAG([-Wold-style-definition], [DEFAULT_CFLAGS="$DEFAULT_CFLAGS -Wold-style-definition"])
|
||||||
AX_CHECK_COMPILE_FLAG([-Wignored-qualifiers], [DEFAULT_CFLAGS="$DEFAULT_CFLAGS -Wignored-qualifiers"])
|
AX_CHECK_COMPILE_FLAG([-Wignored-qualifiers], [DEFAULT_CFLAGS="$DEFAULT_CFLAGS -Wignored-qualifiers"])
|
||||||
|
# Make htssafe.h's pointer-dest 'warning' attribute a hard error in our build
|
||||||
|
# (migration is at zero; a new char* dest is a regression). gcc/clang each take
|
||||||
|
# only their own spelling; downstream keeps the plain warning, not a build break.
|
||||||
|
AX_CHECK_COMPILE_FLAG([-Werror=attribute-warning], [DEFAULT_CFLAGS="$DEFAULT_CFLAGS -Werror=attribute-warning"])
|
||||||
|
AX_CHECK_COMPILE_FLAG([-Werror=user-defined-warnings], [DEFAULT_CFLAGS="$DEFAULT_CFLAGS -Werror=user-defined-warnings"])
|
||||||
AX_CHECK_COMPILE_FLAG([-fstrict-aliasing -Wstrict-aliasing], [DEFAULT_CFLAGS="$DEFAULT_CFLAGS -fstrict-aliasing -Wstrict-aliasing"])
|
AX_CHECK_COMPILE_FLAG([-fstrict-aliasing -Wstrict-aliasing], [DEFAULT_CFLAGS="$DEFAULT_CFLAGS -fstrict-aliasing -Wstrict-aliasing"])
|
||||||
AX_CHECK_COMPILE_FLAG([-fstack-protector], [DEFAULT_CFLAGS="$DEFAULT_CFLAGS -fstack-protector"])
|
AX_CHECK_COMPILE_FLAG([-fstack-protector], [DEFAULT_CFLAGS="$DEFAULT_CFLAGS -fstack-protector"])
|
||||||
AX_CHECK_COMPILE_FLAG([-fstack-clash-protection], [DEFAULT_CFLAGS="$DEFAULT_CFLAGS -fstack-clash-protection"])
|
AX_CHECK_COMPILE_FLAG([-fstack-clash-protection], [DEFAULT_CFLAGS="$DEFAULT_CFLAGS -fstack-clash-protection"])
|
||||||
@@ -209,9 +215,12 @@ AC_SUBST(OPENSSL_LIBS)
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
### Support IPv6
|
### Support IPv6
|
||||||
|
V6_SUPPORT=no
|
||||||
AC_CHECK_LIB(c, getaddrinfo, [V6_FLAG="-DINET6"
|
AC_CHECK_LIB(c, getaddrinfo, [V6_FLAG="-DINET6"
|
||||||
|
V6_SUPPORT=yes
|
||||||
AC_DEFINE(HTS_INET6, 1, [Check for IPv6])], AC_MSG_WARN([*** IPv6 not found IPv6 compatibility disabled]))
|
AC_DEFINE(HTS_INET6, 1, [Check for IPv6])], AC_MSG_WARN([*** IPv6 not found IPv6 compatibility disabled]))
|
||||||
AC_SUBST(V6_FLAG)
|
AC_SUBST(V6_FLAG)
|
||||||
|
AC_SUBST(V6_SUPPORT)
|
||||||
|
|
||||||
### Check for LFS
|
### Check for LFS
|
||||||
AC_CHECK_LIB(c, fopen64, [LFS_FLAG="-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE"
|
AC_CHECK_LIB(c, fopen64, [LFS_FLAG="-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE"
|
||||||
|
|||||||
31
debian/changelog
vendored
31
debian/changelog
vendored
@@ -1,6 +1,33 @@
|
|||||||
|
httrack (3.49.9-1) unstable; urgency=medium
|
||||||
|
|
||||||
|
* New upstream release: Content-Type and file-type detection fixes (trust a
|
||||||
|
declared Content-Type over a binary URL extension, honor --assume under the
|
||||||
|
delayed type check, keep a known extension against a bogus or empty
|
||||||
|
Content-Type, and avoid an uninitialised read on an empty Content-Type), and
|
||||||
|
restored C++ source-compatibility of the installed headers so reverse
|
||||||
|
dependencies (httraqt) build again.
|
||||||
|
|
||||||
|
-- Xavier Roche <xavier@debian.org> Sun, 21 Jun 2026 17:59:38 +0200
|
||||||
|
|
||||||
|
httrack (3.49.8-2) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Rename libhttrack2 to libhttrack3 to follow the SONAME, which the 3.49.8
|
||||||
|
ABI bump moved to libhttrack.so.3 (package-name-doesnt-match-sonames). In
|
||||||
|
3.49.8-1 the libhttrack2.files glob still matched .so.2, so the runtime
|
||||||
|
libraries fell through into the httrack package and libhttrack2 shipped no
|
||||||
|
library. The new .files uses a .so.3* wildcard so a future SONAME bump no
|
||||||
|
longer silently misplaces the libraries. New binary package, via NEW.
|
||||||
|
* Drop the stale debian/libhttrack-swf1.files: the swf module is no longer
|
||||||
|
built and no libhttrack-swf1 package exists.
|
||||||
|
|
||||||
|
-- Xavier Roche <xavier@debian.org> Sat, 20 Jun 2026 14:42:13 +0200
|
||||||
|
|
||||||
httrack (3.49.8-1) unstable; urgency=medium
|
httrack (3.49.8-1) unstable; urgency=medium
|
||||||
|
|
||||||
* New upstream release.
|
* New upstream release: HTTPS-proxy CONNECT tunnelling and wider srcset
|
||||||
|
parsing, a batch of crawler and parser fixes (CSS @import, xmlns
|
||||||
|
namespaces, relative paths, RFC 6265 cookies), and security hardening of
|
||||||
|
the parser and of buffer copies throughout the engine.
|
||||||
* Drop the OpenSSL linking exception from the license: OpenSSL 3.0+ is
|
* Drop the OpenSSL linking exception from the license: OpenSSL 3.0+ is
|
||||||
Apache-2.0 and GPL-compatible, so it is no longer needed. httrack is now
|
Apache-2.0 and GPL-compatible, so it is no longer needed. httrack is now
|
||||||
plain GPL-3.0-or-later. Updated debian/copyright accordingly.
|
plain GPL-3.0-or-later. Updated debian/copyright accordingly.
|
||||||
@@ -14,7 +41,7 @@ httrack (3.49.8-1) unstable; urgency=medium
|
|||||||
the QA debcheck page. Depend on firefox-esr | chromium | www-browser
|
the QA debcheck page. Depend on firefox-esr | chromium | www-browser
|
||||||
instead.
|
instead.
|
||||||
|
|
||||||
-- Xavier Roche <xavier@debian.org> Sun, 07 Jun 2026 14:29:24 +0200
|
-- Xavier Roche <xavier@debian.org> Sat, 20 Jun 2026 13:02:08 +0200
|
||||||
|
|
||||||
httrack (3.49.7-2) unstable; urgency=medium
|
httrack (3.49.7-2) unstable; urgency=medium
|
||||||
|
|
||||||
|
|||||||
6
debian/control
vendored
6
debian/control
vendored
@@ -58,13 +58,13 @@ Description: webhttrack common files
|
|||||||
This package is the common files of webhttrack, website copier and
|
This package is the common files of webhttrack, website copier and
|
||||||
mirroring utility
|
mirroring utility
|
||||||
|
|
||||||
Package: libhttrack2
|
Package: libhttrack3
|
||||||
Architecture: any
|
Architecture: any
|
||||||
Multi-Arch: same
|
Multi-Arch: same
|
||||||
Section: libs
|
Section: libs
|
||||||
Replaces: libhttrack1
|
|
||||||
Conflicts: libhttrack1
|
|
||||||
Depends: ${misc:Depends}, ${shlibs:Depends}
|
Depends: ${misc:Depends}, ${shlibs:Depends}
|
||||||
|
Replaces: libhttrack2, httrack (<< 3.49.8-2~)
|
||||||
|
Breaks: libhttrack2, httrack (<< 3.49.8-2~)
|
||||||
Description: Httrack website copier library
|
Description: Httrack website copier library
|
||||||
This package is the library part of httrack, website copier and mirroring
|
This package is the library part of httrack, website copier and mirroring
|
||||||
utility
|
utility
|
||||||
|
|||||||
118
debian/copyright
vendored
118
debian/copyright
vendored
@@ -1,21 +1,109 @@
|
|||||||
This package was debianized by Xavier Roche <roche@httrack.com> on
|
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||||
Fri, 27 Sep 2002 16:42:26 +0200
|
Upstream-Name: httrack
|
||||||
|
Upstream-Contact: Xavier Roche <roche@httrack.com>
|
||||||
|
Source: https://www.httrack.com/
|
||||||
|
|
||||||
The current Debian maintainer is Xavier Roche <xavier@debian.org>
|
Files: *
|
||||||
|
Copyright: 1998-2026 Xavier Roche and other contributors
|
||||||
|
License: GPL-3+
|
||||||
|
Comment:
|
||||||
|
The engine includes contributions from Yann Philippot (src/htsjava.c,
|
||||||
|
src/htsjava.h). htsbasenet.h links against the system OpenSSL library
|
||||||
|
(originally by Eric Young); no OpenSSL/SSLeay code is bundled here.
|
||||||
|
|
||||||
Upstream author: Xavier Roche <roche@httrack.com>
|
Files: src/minizip/*
|
||||||
|
Copyright: 1998-2010 Gilles Vollant
|
||||||
|
2007-2008 Even Rouault
|
||||||
|
2009-2010 Mathias Svensson
|
||||||
|
1990-2000 Info-ZIP
|
||||||
|
License: Zlib
|
||||||
|
Comment:
|
||||||
|
The decryption code in src/minizip/crypt.h and src/minizip/unzip.c derives
|
||||||
|
from the Info-ZIP distribution, distributed under the same terms.
|
||||||
|
|
||||||
Copyright: 1998-2014 Xavier Roche and other contributors
|
Files: src/md5.c
|
||||||
|
Copyright: 1993 Colin Plumb
|
||||||
|
License: public-domain-md5
|
||||||
|
This code implements the MD5 message-digest algorithm, due to Ron Rivest.
|
||||||
|
It was written by Colin Plumb in 1993, no copyright is claimed. This code
|
||||||
|
is in the public domain; do with it what you wish.
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
Files: src/coucal/*
|
||||||
it under the terms of the GNU General Public License as published by
|
Copyright: 2013-2014 Xavier Roche
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
License: BSD-3-clause
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
On Debian systems, the complete text of the GNU General Public
|
Files: src/coucal/murmurhash3.h*
|
||||||
License version 3 can be found in /usr/share/common-licenses/GPL-3 file.
|
Copyright: Austin Appleby
|
||||||
|
License: public-domain-murmurhash3
|
||||||
|
MurmurHash3 was written by Austin Appleby, and is placed in the public
|
||||||
|
domain. The author hereby disclaims copyright to this source code.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
Files: html/server/div/com.httrack.WebHTTrack.metainfo.xml
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
Copyright: 1998-2026 Xavier Roche and other contributors
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
License: FSFAP
|
||||||
GNU General Public License for more details.
|
Copying and distribution of this file, with or without modification, are
|
||||||
|
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: debian/*
|
||||||
|
Copyright: 2002-2026 Xavier Roche <xavier@debian.org>
|
||||||
|
License: GPL-3+
|
||||||
|
|
||||||
|
License: GPL-3+
|
||||||
|
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 <https://www.gnu.org/licenses/>.
|
||||||
|
.
|
||||||
|
On Debian systems, the complete text of the GNU General Public License
|
||||||
|
version 3 can be found in /usr/share/common-licenses/GPL-3.
|
||||||
|
|
||||||
|
License: Zlib
|
||||||
|
This software is provided 'as-is', without any express or implied warranty.
|
||||||
|
In no event will the authors be held liable for any damages arising from the
|
||||||
|
use of this software.
|
||||||
|
.
|
||||||
|
Permission is granted to anyone to use this software for any purpose,
|
||||||
|
including commercial applications, and to alter it and redistribute it
|
||||||
|
freely, subject to the following restrictions:
|
||||||
|
.
|
||||||
|
1. The origin of this software must not be misrepresented; you must not claim
|
||||||
|
that you wrote the original software. If you use this software in a product,
|
||||||
|
an acknowledgment in the product documentation would be appreciated but is
|
||||||
|
not required.
|
||||||
|
2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
misrepresented as being the original software.
|
||||||
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
|
|
||||||
|
License: BSD-3-clause
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
.
|
||||||
|
1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
3. Neither the name of the copyright holder nor the names of its contributors
|
||||||
|
may be used to endorse or promote products derived from this software
|
||||||
|
without specific prior written permission.
|
||||||
|
.
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
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.
|
||||||
|
|||||||
3
debian/httrack-doc.lintian-overrides
vendored
3
debian/httrack-doc.lintian-overrides
vendored
@@ -4,3 +4,6 @@
|
|||||||
# so the path lives in the display pointer, not the override -- match with '*'.
|
# so the path lives in the display pointer, not the override -- match with '*'.
|
||||||
httrack-doc: extra-license-file *
|
httrack-doc: extra-license-file *
|
||||||
httrack-doc: package-contains-documentation-outside-usr-share-doc *
|
httrack-doc: package-contains-documentation-outside-usr-share-doc *
|
||||||
|
# search.sh is a sample CGI shipped alongside the HTML manual, not meant to be
|
||||||
|
# run from the package tree; it stays non-executable by design.
|
||||||
|
httrack-doc: script-not-executable *
|
||||||
|
|||||||
2
debian/libhttrack-swf1.files
vendored
2
debian/libhttrack-swf1.files
vendored
@@ -1,2 +0,0 @@
|
|||||||
usr/lib/*/libhtsswf.so.1.0.0
|
|
||||||
usr/lib/*/libhtsswf.so.1
|
|
||||||
5
debian/libhttrack2.files
vendored
5
debian/libhttrack2.files
vendored
@@ -1,5 +0,0 @@
|
|||||||
usr/lib/*/libhttrack.so.2.0.49
|
|
||||||
usr/lib/*/libhttrack.so.2
|
|
||||||
usr/lib/*/libhtsjava.so.2.0.49
|
|
||||||
usr/lib/*/libhtsjava.so.2
|
|
||||||
usr/share/httrack/templates
|
|
||||||
3
debian/libhttrack2.lintian-overrides
vendored
3
debian/libhttrack2.lintian-overrides
vendored
@@ -1,3 +0,0 @@
|
|||||||
# The shared libraries ship without a versioned symbols control file (ABI is
|
|
||||||
# tracked via the SONAME and a strict =version dependency, see debian/rules).
|
|
||||||
libhttrack2: no-symbols-control-file usr/lib/*
|
|
||||||
3
debian/libhttrack3.files
vendored
Normal file
3
debian/libhttrack3.files
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
usr/lib/*/libhttrack.so.3*
|
||||||
|
usr/lib/*/libhtsjava.so.3*
|
||||||
|
usr/share/httrack/templates
|
||||||
8
debian/libhttrack3.lintian-overrides
vendored
Normal file
8
debian/libhttrack3.lintian-overrides
vendored
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# The shared libraries ship without a versioned symbols control file (ABI is
|
||||||
|
# tracked via the SONAME plus a >= upstream-version dependency, see debian/rules).
|
||||||
|
libhttrack3: no-symbols-control-file usr/lib/*
|
||||||
|
|
||||||
|
# Bundled, locally patched minizip (src/minizip): it adds a zipFlush() API the
|
||||||
|
# system libminizip lacks (htscache.c flushes the cache .zip so an interrupted
|
||||||
|
# crawl leaves a valid archive), plus Android/old-zlib portability fixes.
|
||||||
|
libhttrack3: embedded-library *libminizip*
|
||||||
3
debian/proxytrack.lintian-overrides
vendored
Normal file
3
debian/proxytrack.lintian-overrides
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# Statically linked against httrack's bundled, patched minizip (see src/minizip
|
||||||
|
# and libhttrack3's override): the zipFlush() API is absent from the system one.
|
||||||
|
proxytrack: embedded-library *libminizip*
|
||||||
2
debian/rules
vendored
2
debian/rules
vendored
@@ -135,7 +135,7 @@ binary-arch: build install
|
|||||||
dh_makeshlibs -a -X/usr/lib/$(DEB_HOST_MULTIARCH)/httrack/libtest --version-info
|
dh_makeshlibs -a -X/usr/lib/$(DEB_HOST_MULTIARCH)/httrack/libtest --version-info
|
||||||
dh_installdeb -a
|
dh_installdeb -a
|
||||||
# we depend on the current version (ABI may change)
|
# we depend on the current version (ABI may change)
|
||||||
dh_shlibdeps -a -ldebian/libhttrack2/usr/lib/$(DEB_HOST_MULTIARCH)
|
dh_shlibdeps -a -ldebian/libhttrack3/usr/lib/$(DEB_HOST_MULTIARCH)
|
||||||
dh_gencontrol -a
|
dh_gencontrol -a
|
||||||
dh_md5sums -a
|
dh_md5sums -a
|
||||||
dh_builddeb -a
|
dh_builddeb -a
|
||||||
|
|||||||
792
depcomp
792
depcomp
@@ -1,792 +0,0 @@
|
|||||||
#! /bin/sh
|
|
||||||
# depcomp - compile a program generating dependencies as side-effects
|
|
||||||
|
|
||||||
scriptversion=2024-06-19.01; # UTC
|
|
||||||
|
|
||||||
# Copyright (C) 1999-2024 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
# 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 2, 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 <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
# As a special exception to the GNU General Public License, if you
|
|
||||||
# distribute this file as part of a program that contains a
|
|
||||||
# configuration script generated by Autoconf, you may include it under
|
|
||||||
# the same distribution terms that you use for the rest of that program.
|
|
||||||
|
|
||||||
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
|
|
||||||
|
|
||||||
case $1 in
|
|
||||||
'')
|
|
||||||
echo "$0: No command. Try '$0 --help' for more information." 1>&2
|
|
||||||
exit 1;
|
|
||||||
;;
|
|
||||||
-h | --h*)
|
|
||||||
cat <<\EOF
|
|
||||||
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
|
|
||||||
|
|
||||||
Run PROGRAMS ARGS to compile a file, generating dependencies
|
|
||||||
as side-effects.
|
|
||||||
|
|
||||||
Environment variables:
|
|
||||||
depmode Dependency tracking mode.
|
|
||||||
source Source file read by 'PROGRAMS ARGS'.
|
|
||||||
object Object file output by 'PROGRAMS ARGS'.
|
|
||||||
DEPDIR directory where to store dependencies.
|
|
||||||
depfile Dependency file to output.
|
|
||||||
tmpdepfile Temporary file to use when outputting dependencies.
|
|
||||||
libtool Whether libtool is used (yes/no).
|
|
||||||
|
|
||||||
Report bugs to <bug-automake@gnu.org>.
|
|
||||||
GNU Automake home page: <https://www.gnu.org/software/automake/>.
|
|
||||||
General help using GNU software: <https://www.gnu.org/gethelp/>.
|
|
||||||
EOF
|
|
||||||
exit $?
|
|
||||||
;;
|
|
||||||
-v | --v*)
|
|
||||||
echo "depcomp (GNU Automake) $scriptversion"
|
|
||||||
exit $?
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
# Get the directory component of the given path, and save it in the
|
|
||||||
# global variables '$dir'. Note that this directory component will
|
|
||||||
# be either empty or ending with a '/' character. This is deliberate.
|
|
||||||
set_dir_from ()
|
|
||||||
{
|
|
||||||
case $1 in
|
|
||||||
*/*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;;
|
|
||||||
*) dir=;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get the suffix-stripped basename of the given path, and save it the
|
|
||||||
# global variable '$base'.
|
|
||||||
set_base_from ()
|
|
||||||
{
|
|
||||||
base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'`
|
|
||||||
}
|
|
||||||
|
|
||||||
# If no dependency file was actually created by the compiler invocation,
|
|
||||||
# we still have to create a dummy depfile, to avoid errors with the
|
|
||||||
# Makefile "include basename.Plo" scheme.
|
|
||||||
make_dummy_depfile ()
|
|
||||||
{
|
|
||||||
echo "#dummy" > "$depfile"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Factor out some common post-processing of the generated depfile.
|
|
||||||
# Requires the auxiliary global variable '$tmpdepfile' to be set.
|
|
||||||
aix_post_process_depfile ()
|
|
||||||
{
|
|
||||||
# If the compiler actually managed to produce a dependency file,
|
|
||||||
# post-process it.
|
|
||||||
if test -f "$tmpdepfile"; then
|
|
||||||
# Each line is of the form 'foo.o: dependency.h'.
|
|
||||||
# Do two passes, one to just change these to
|
|
||||||
# $object: dependency.h
|
|
||||||
# and one to simply output
|
|
||||||
# dependency.h:
|
|
||||||
# which is needed to avoid the deleted-header problem.
|
|
||||||
{ sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile"
|
|
||||||
sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile"
|
|
||||||
} > "$depfile"
|
|
||||||
rm -f "$tmpdepfile"
|
|
||||||
else
|
|
||||||
make_dummy_depfile
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# A tabulation character.
|
|
||||||
tab=' '
|
|
||||||
# A newline character.
|
|
||||||
nl='
|
|
||||||
'
|
|
||||||
# Character ranges might be problematic outside the C locale.
|
|
||||||
# These definitions help.
|
|
||||||
upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ
|
|
||||||
lower=abcdefghijklmnopqrstuvwxyz
|
|
||||||
alpha=${upper}${lower}
|
|
||||||
|
|
||||||
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
|
|
||||||
echo "depcomp: Variables source, object and depmode must be set" 1>&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
|
|
||||||
depfile=${depfile-`echo "$object" |
|
|
||||||
sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
|
|
||||||
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
|
|
||||||
|
|
||||||
rm -f "$tmpdepfile"
|
|
||||||
|
|
||||||
# Avoid interference from the environment.
|
|
||||||
gccflag= dashmflag=
|
|
||||||
|
|
||||||
# Some modes work just like other modes, but use different flags. We
|
|
||||||
# parameterize here, but still list the modes in the big case below,
|
|
||||||
# to make depend.m4 easier to write. Note that we *cannot* use a case
|
|
||||||
# here, because this file can only contain one case statement.
|
|
||||||
if test "$depmode" = hp; then
|
|
||||||
# HP compiler uses -M and no extra arg.
|
|
||||||
gccflag=-M
|
|
||||||
depmode=gcc
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test "$depmode" = dashXmstdout; then
|
|
||||||
# This is just like dashmstdout with a different argument.
|
|
||||||
dashmflag=-xM
|
|
||||||
depmode=dashmstdout
|
|
||||||
fi
|
|
||||||
|
|
||||||
cygpath_u="cygpath -u -f -"
|
|
||||||
if test "$depmode" = msvcmsys; then
|
|
||||||
# This is just like msvisualcpp but w/o cygpath translation.
|
|
||||||
# Just convert the backslash-escaped backslashes to single forward
|
|
||||||
# slashes to satisfy depend.m4
|
|
||||||
cygpath_u='sed s,\\\\,/,g'
|
|
||||||
depmode=msvisualcpp
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test "$depmode" = msvc7msys; then
|
|
||||||
# This is just like msvc7 but w/o cygpath translation.
|
|
||||||
# Just convert the backslash-escaped backslashes to single forward
|
|
||||||
# slashes to satisfy depend.m4
|
|
||||||
cygpath_u='sed s,\\\\,/,g'
|
|
||||||
depmode=msvc7
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test "$depmode" = xlc; then
|
|
||||||
# IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information.
|
|
||||||
gccflag=-qmakedep=gcc,-MF
|
|
||||||
depmode=gcc
|
|
||||||
fi
|
|
||||||
|
|
||||||
case "$depmode" in
|
|
||||||
gcc3)
|
|
||||||
## gcc 3 implements dependency tracking that does exactly what
|
|
||||||
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
|
|
||||||
## it if -MD -MP comes after the -MF stuff. Hmm.
|
|
||||||
## Unfortunately, FreeBSD c89 acceptance of flags depends upon
|
|
||||||
## the command line argument order; so add the flags where they
|
|
||||||
## appear in depend2.am. Note that the slowdown incurred here
|
|
||||||
## affects only configure: in makefiles, %FASTDEP% shortcuts this.
|
|
||||||
for arg
|
|
||||||
do
|
|
||||||
case $arg in
|
|
||||||
-c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
|
|
||||||
*) set fnord "$@" "$arg" ;;
|
|
||||||
esac
|
|
||||||
shift # fnord
|
|
||||||
shift # $arg
|
|
||||||
done
|
|
||||||
"$@"
|
|
||||||
stat=$?
|
|
||||||
if test $stat -ne 0; then
|
|
||||||
rm -f "$tmpdepfile"
|
|
||||||
exit $stat
|
|
||||||
fi
|
|
||||||
mv "$tmpdepfile" "$depfile"
|
|
||||||
;;
|
|
||||||
|
|
||||||
gcc)
|
|
||||||
## Note that this doesn't just cater to obsolete pre-3.x GCC compilers.
|
|
||||||
## but also to in-use compilers like IBM xlc/xlC and the HP C compiler.
|
|
||||||
## (see the conditional assignment to $gccflag above).
|
|
||||||
## There are various ways to get dependency output from gcc. Here's
|
|
||||||
## why we pick this rather obscure method:
|
|
||||||
## - Don't want to use -MD because we'd like the dependencies to end
|
|
||||||
## up in a subdir. Having to rename by hand is ugly.
|
|
||||||
## (We might end up doing this anyway to support other compilers.)
|
|
||||||
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
|
|
||||||
## -MM, not -M (despite what the docs say). Also, it might not be
|
|
||||||
## supported by the other compilers which use the 'gcc' depmode.
|
|
||||||
## - Using -M directly means running the compiler twice (even worse
|
|
||||||
## than renaming).
|
|
||||||
if test -z "$gccflag"; then
|
|
||||||
gccflag=-MD,
|
|
||||||
fi
|
|
||||||
"$@" -Wp,"$gccflag$tmpdepfile"
|
|
||||||
stat=$?
|
|
||||||
if test $stat -ne 0; then
|
|
||||||
rm -f "$tmpdepfile"
|
|
||||||
exit $stat
|
|
||||||
fi
|
|
||||||
rm -f "$depfile"
|
|
||||||
echo "$object : \\" > "$depfile"
|
|
||||||
# The second -e expression handles DOS-style file names with drive
|
|
||||||
# letters.
|
|
||||||
sed -e 's/^[^:]*: / /' \
|
|
||||||
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
|
|
||||||
## This next piece of magic avoids the "deleted header file" problem.
|
|
||||||
## The problem is that when a header file which appears in a .P file
|
|
||||||
## is deleted, the dependency causes make to die (because there is
|
|
||||||
## typically no way to rebuild the header). We avoid this by adding
|
|
||||||
## dummy dependencies for each header file. Too bad gcc doesn't do
|
|
||||||
## this for us directly.
|
|
||||||
## Some versions of gcc put a space before the ':'. On the theory
|
|
||||||
## that the space means something, we add a space to the output as
|
|
||||||
## well. hp depmode also adds that space, but also prefixes the VPATH
|
|
||||||
## to the object. Take care to not repeat it in the output.
|
|
||||||
## Some versions of the HPUX 10.20 sed can't process this invocation
|
|
||||||
## correctly. Breaking it into two sed invocations is a workaround.
|
|
||||||
tr ' ' "$nl" < "$tmpdepfile" \
|
|
||||||
| sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
|
|
||||||
| sed -e 's/$/ :/' >> "$depfile"
|
|
||||||
rm -f "$tmpdepfile"
|
|
||||||
;;
|
|
||||||
|
|
||||||
hp)
|
|
||||||
# This case exists only to let depend.m4 do its work. It works by
|
|
||||||
# looking at the text of this script. This case will never be run,
|
|
||||||
# since it is checked for above.
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
|
|
||||||
sgi)
|
|
||||||
if test "$libtool" = yes; then
|
|
||||||
"$@" "-Wp,-MDupdate,$tmpdepfile"
|
|
||||||
else
|
|
||||||
"$@" -MDupdate "$tmpdepfile"
|
|
||||||
fi
|
|
||||||
stat=$?
|
|
||||||
if test $stat -ne 0; then
|
|
||||||
rm -f "$tmpdepfile"
|
|
||||||
exit $stat
|
|
||||||
fi
|
|
||||||
rm -f "$depfile"
|
|
||||||
|
|
||||||
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
|
|
||||||
echo "$object : \\" > "$depfile"
|
|
||||||
# Clip off the initial element (the dependent). Don't try to be
|
|
||||||
# clever and replace this with sed code, as IRIX sed won't handle
|
|
||||||
# lines with more than a fixed number of characters (4096 in
|
|
||||||
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
|
|
||||||
# the IRIX cc adds comments like '#:fec' to the end of the
|
|
||||||
# dependency line.
|
|
||||||
tr ' ' "$nl" < "$tmpdepfile" \
|
|
||||||
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \
|
|
||||||
| tr "$nl" ' ' >> "$depfile"
|
|
||||||
echo >> "$depfile"
|
|
||||||
# The second pass generates a dummy entry for each header file.
|
|
||||||
tr ' ' "$nl" < "$tmpdepfile" \
|
|
||||||
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
|
|
||||||
>> "$depfile"
|
|
||||||
else
|
|
||||||
make_dummy_depfile
|
|
||||||
fi
|
|
||||||
rm -f "$tmpdepfile"
|
|
||||||
;;
|
|
||||||
|
|
||||||
xlc)
|
|
||||||
# This case exists only to let depend.m4 do its work. It works by
|
|
||||||
# looking at the text of this script. This case will never be run,
|
|
||||||
# since it is checked for above.
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
|
|
||||||
aix)
|
|
||||||
# The C for AIX Compiler uses -M and outputs the dependencies
|
|
||||||
# in a .u file. In older versions, this file always lives in the
|
|
||||||
# current directory. Also, the AIX compiler puts '$object:' at the
|
|
||||||
# start of each line; $object doesn't have directory information.
|
|
||||||
# Version 6 uses the directory in both cases.
|
|
||||||
set_dir_from "$object"
|
|
||||||
set_base_from "$object"
|
|
||||||
if test "$libtool" = yes; then
|
|
||||||
tmpdepfile1=$dir$base.u
|
|
||||||
tmpdepfile2=$base.u
|
|
||||||
tmpdepfile3=$dir.libs/$base.u
|
|
||||||
"$@" -Wc,-M
|
|
||||||
else
|
|
||||||
tmpdepfile1=$dir$base.u
|
|
||||||
tmpdepfile2=$dir$base.u
|
|
||||||
tmpdepfile3=$dir$base.u
|
|
||||||
"$@" -M
|
|
||||||
fi
|
|
||||||
stat=$?
|
|
||||||
if test $stat -ne 0; then
|
|
||||||
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
|
||||||
exit $stat
|
|
||||||
fi
|
|
||||||
|
|
||||||
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
|
||||||
do
|
|
||||||
test -f "$tmpdepfile" && break
|
|
||||||
done
|
|
||||||
aix_post_process_depfile
|
|
||||||
;;
|
|
||||||
|
|
||||||
tcc)
|
|
||||||
# tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26
|
|
||||||
# FIXME: That version still under development at the moment of writing.
|
|
||||||
# Make that this statement remains true also for stable, released
|
|
||||||
# versions.
|
|
||||||
# It will wrap lines (doesn't matter whether long or short) with a
|
|
||||||
# trailing '\', as in:
|
|
||||||
#
|
|
||||||
# foo.o : \
|
|
||||||
# foo.c \
|
|
||||||
# foo.h \
|
|
||||||
#
|
|
||||||
# It will put a trailing '\' even on the last line, and will use leading
|
|
||||||
# spaces rather than leading tabs (at least since its commit 0394caf7
|
|
||||||
# "Emit spaces for -MD").
|
|
||||||
"$@" -MD -MF "$tmpdepfile"
|
|
||||||
stat=$?
|
|
||||||
if test $stat -ne 0; then
|
|
||||||
rm -f "$tmpdepfile"
|
|
||||||
exit $stat
|
|
||||||
fi
|
|
||||||
rm -f "$depfile"
|
|
||||||
# Each non-empty line is of the form 'foo.o : \' or ' dep.h \'.
|
|
||||||
# We have to change lines of the first kind to '$object: \'.
|
|
||||||
sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile"
|
|
||||||
# And for each line of the second kind, we have to emit a 'dep.h:'
|
|
||||||
# dummy dependency, to avoid the deleted-header problem.
|
|
||||||
sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile"
|
|
||||||
rm -f "$tmpdepfile"
|
|
||||||
;;
|
|
||||||
|
|
||||||
## The order of this option in the case statement is important, since the
|
|
||||||
## shell code in configure will try each of these formats in the order
|
|
||||||
## listed in this file. A plain '-MD' option would be understood by many
|
|
||||||
## compilers, so we must ensure this comes after the gcc and icc options.
|
|
||||||
pgcc)
|
|
||||||
# Portland's C compiler understands '-MD'.
|
|
||||||
# Will always output deps to 'file.d' where file is the root name of the
|
|
||||||
# source file under compilation, even if file resides in a subdirectory.
|
|
||||||
# The object file name does not affect the name of the '.d' file.
|
|
||||||
# pgcc 10.2 will output
|
|
||||||
# foo.o: sub/foo.c sub/foo.h
|
|
||||||
# and will wrap long lines using '\' :
|
|
||||||
# foo.o: sub/foo.c ... \
|
|
||||||
# sub/foo.h ... \
|
|
||||||
# ...
|
|
||||||
set_dir_from "$object"
|
|
||||||
# Use the source, not the object, to determine the base name, since
|
|
||||||
# that's sadly what pgcc will do too.
|
|
||||||
set_base_from "$source"
|
|
||||||
tmpdepfile=$base.d
|
|
||||||
|
|
||||||
# For projects that build the same source file twice into different object
|
|
||||||
# files, the pgcc approach of using the *source* file root name can cause
|
|
||||||
# problems in parallel builds. Use a locking strategy to avoid stomping on
|
|
||||||
# the same $tmpdepfile.
|
|
||||||
lockdir=$base.d-lock
|
|
||||||
trap "
|
|
||||||
echo '$0: caught signal, cleaning up...' >&2
|
|
||||||
rmdir '$lockdir'
|
|
||||||
exit 1
|
|
||||||
" 1 2 13 15
|
|
||||||
numtries=100
|
|
||||||
i=$numtries
|
|
||||||
while test $i -gt 0; do
|
|
||||||
# mkdir is a portable test-and-set.
|
|
||||||
if mkdir "$lockdir" 2>/dev/null; then
|
|
||||||
# This process acquired the lock.
|
|
||||||
"$@" -MD
|
|
||||||
stat=$?
|
|
||||||
# Release the lock.
|
|
||||||
rmdir "$lockdir"
|
|
||||||
break
|
|
||||||
else
|
|
||||||
# If the lock is being held by a different process, wait
|
|
||||||
# until the winning process is done or we timeout.
|
|
||||||
while test -d "$lockdir" && test $i -gt 0; do
|
|
||||||
sleep 1
|
|
||||||
i=`expr $i - 1`
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
i=`expr $i - 1`
|
|
||||||
done
|
|
||||||
trap - 1 2 13 15
|
|
||||||
if test $i -le 0; then
|
|
||||||
echo "$0: failed to acquire lock after $numtries attempts" >&2
|
|
||||||
echo "$0: check lockdir '$lockdir'" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test $stat -ne 0; then
|
|
||||||
rm -f "$tmpdepfile"
|
|
||||||
exit $stat
|
|
||||||
fi
|
|
||||||
rm -f "$depfile"
|
|
||||||
# Each line is of the form `foo.o: dependent.h',
|
|
||||||
# or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
|
|
||||||
# Do two passes, one to just change these to
|
|
||||||
# `$object: dependent.h' and one to simply `dependent.h:'.
|
|
||||||
sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
|
|
||||||
# Some versions of the HPUX 10.20 sed can't process this invocation
|
|
||||||
# correctly. Breaking it into two sed invocations is a workaround.
|
|
||||||
sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \
|
|
||||||
| sed -e 's/$/ :/' >> "$depfile"
|
|
||||||
rm -f "$tmpdepfile"
|
|
||||||
;;
|
|
||||||
|
|
||||||
hp2)
|
|
||||||
# The "hp" stanza above does not work with aCC (C++) and HP's ia64
|
|
||||||
# compilers, which have integrated preprocessors. The correct option
|
|
||||||
# to use with these is +Maked; it writes dependencies to a file named
|
|
||||||
# 'foo.d', which lands next to the object file, wherever that
|
|
||||||
# happens to be.
|
|
||||||
# Much of this is similar to the tru64 case; see comments there.
|
|
||||||
set_dir_from "$object"
|
|
||||||
set_base_from "$object"
|
|
||||||
if test "$libtool" = yes; then
|
|
||||||
tmpdepfile1=$dir$base.d
|
|
||||||
tmpdepfile2=$dir.libs/$base.d
|
|
||||||
"$@" -Wc,+Maked
|
|
||||||
else
|
|
||||||
tmpdepfile1=$dir$base.d
|
|
||||||
tmpdepfile2=$dir$base.d
|
|
||||||
"$@" +Maked
|
|
||||||
fi
|
|
||||||
stat=$?
|
|
||||||
if test $stat -ne 0; then
|
|
||||||
rm -f "$tmpdepfile1" "$tmpdepfile2"
|
|
||||||
exit $stat
|
|
||||||
fi
|
|
||||||
|
|
||||||
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
|
|
||||||
do
|
|
||||||
test -f "$tmpdepfile" && break
|
|
||||||
done
|
|
||||||
if test -f "$tmpdepfile"; then
|
|
||||||
sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile"
|
|
||||||
# Add 'dependent.h:' lines.
|
|
||||||
sed -ne '2,${
|
|
||||||
s/^ *//
|
|
||||||
s/ \\*$//
|
|
||||||
s/$/:/
|
|
||||||
p
|
|
||||||
}' "$tmpdepfile" >> "$depfile"
|
|
||||||
else
|
|
||||||
make_dummy_depfile
|
|
||||||
fi
|
|
||||||
rm -f "$tmpdepfile" "$tmpdepfile2"
|
|
||||||
;;
|
|
||||||
|
|
||||||
tru64)
|
|
||||||
# The Tru64 compiler uses -MD to generate dependencies as a side
|
|
||||||
# effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'.
|
|
||||||
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
|
|
||||||
# dependencies in 'foo.d' instead, so we check for that too.
|
|
||||||
# Subdirectories are respected.
|
|
||||||
set_dir_from "$object"
|
|
||||||
set_base_from "$object"
|
|
||||||
|
|
||||||
if test "$libtool" = yes; then
|
|
||||||
# Libtool generates 2 separate objects for the 2 libraries. These
|
|
||||||
# two compilations output dependencies in $dir.libs/$base.o.d and
|
|
||||||
# in $dir$base.o.d. We have to check for both files, because
|
|
||||||
# one of the two compilations can be disabled. We should prefer
|
|
||||||
# $dir$base.o.d over $dir.libs/$base.o.d because the latter is
|
|
||||||
# automatically cleaned when .libs/ is deleted, while ignoring
|
|
||||||
# the former would cause a distcleancheck panic.
|
|
||||||
tmpdepfile1=$dir$base.o.d # libtool 1.5
|
|
||||||
tmpdepfile2=$dir.libs/$base.o.d # Likewise.
|
|
||||||
tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504
|
|
||||||
"$@" -Wc,-MD
|
|
||||||
else
|
|
||||||
tmpdepfile1=$dir$base.d
|
|
||||||
tmpdepfile2=$dir$base.d
|
|
||||||
tmpdepfile3=$dir$base.d
|
|
||||||
"$@" -MD
|
|
||||||
fi
|
|
||||||
|
|
||||||
stat=$?
|
|
||||||
if test $stat -ne 0; then
|
|
||||||
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
|
||||||
exit $stat
|
|
||||||
fi
|
|
||||||
|
|
||||||
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
|
||||||
do
|
|
||||||
test -f "$tmpdepfile" && break
|
|
||||||
done
|
|
||||||
# Same post-processing that is required for AIX mode.
|
|
||||||
aix_post_process_depfile
|
|
||||||
;;
|
|
||||||
|
|
||||||
msvc7)
|
|
||||||
if test "$libtool" = yes; then
|
|
||||||
showIncludes=-Wc,-showIncludes
|
|
||||||
else
|
|
||||||
showIncludes=-showIncludes
|
|
||||||
fi
|
|
||||||
"$@" $showIncludes > "$tmpdepfile"
|
|
||||||
stat=$?
|
|
||||||
grep -v '^Note: including file: ' "$tmpdepfile"
|
|
||||||
if test $stat -ne 0; then
|
|
||||||
rm -f "$tmpdepfile"
|
|
||||||
exit $stat
|
|
||||||
fi
|
|
||||||
rm -f "$depfile"
|
|
||||||
echo "$object : \\" > "$depfile"
|
|
||||||
# The first sed program below extracts the file names and escapes
|
|
||||||
# backslashes for cygpath. The second sed program outputs the file
|
|
||||||
# name when reading, but also accumulates all include files in the
|
|
||||||
# hold buffer in order to output them again at the end. This only
|
|
||||||
# works with sed implementations that can handle large buffers.
|
|
||||||
sed < "$tmpdepfile" -n '
|
|
||||||
/^Note: including file: *\(.*\)/ {
|
|
||||||
s//\1/
|
|
||||||
s/\\/\\\\/g
|
|
||||||
p
|
|
||||||
}' | $cygpath_u | sort -u | sed -n '
|
|
||||||
s/ /\\ /g
|
|
||||||
s/\(.*\)/'"$tab"'\1 \\/p
|
|
||||||
s/.\(.*\) \\/\1:/
|
|
||||||
H
|
|
||||||
$ {
|
|
||||||
s/.*/'"$tab"'/
|
|
||||||
G
|
|
||||||
p
|
|
||||||
}' >> "$depfile"
|
|
||||||
echo >> "$depfile" # make sure the fragment doesn't end with a backslash
|
|
||||||
rm -f "$tmpdepfile"
|
|
||||||
;;
|
|
||||||
|
|
||||||
msvc7msys)
|
|
||||||
# This case exists only to let depend.m4 do its work. It works by
|
|
||||||
# looking at the text of this script. This case will never be run,
|
|
||||||
# since it is checked for above.
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
|
|
||||||
#nosideeffect)
|
|
||||||
# This comment above is used by automake to tell side-effect
|
|
||||||
# dependency tracking mechanisms from slower ones.
|
|
||||||
|
|
||||||
dashmstdout)
|
|
||||||
# Important note: in order to support this mode, a compiler *must*
|
|
||||||
# always write the preprocessed file to stdout, regardless of -o.
|
|
||||||
"$@" || exit $?
|
|
||||||
|
|
||||||
# Remove the call to Libtool.
|
|
||||||
if test "$libtool" = yes; then
|
|
||||||
while test "X$1" != 'X--mode=compile'; do
|
|
||||||
shift
|
|
||||||
done
|
|
||||||
shift
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Remove '-o $object'.
|
|
||||||
IFS=" "
|
|
||||||
for arg
|
|
||||||
do
|
|
||||||
case $arg in
|
|
||||||
-o)
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
$object)
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
set fnord "$@" "$arg"
|
|
||||||
shift # fnord
|
|
||||||
shift # $arg
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
test -z "$dashmflag" && dashmflag=-M
|
|
||||||
# Require at least two characters before searching for ':'
|
|
||||||
# in the target name. This is to cope with DOS-style filenames:
|
|
||||||
# a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise.
|
|
||||||
"$@" $dashmflag |
|
|
||||||
sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile"
|
|
||||||
rm -f "$depfile"
|
|
||||||
cat < "$tmpdepfile" > "$depfile"
|
|
||||||
# Some versions of the HPUX 10.20 sed can't process this sed invocation
|
|
||||||
# correctly. Breaking it into two sed invocations is a workaround.
|
|
||||||
tr ' ' "$nl" < "$tmpdepfile" \
|
|
||||||
| sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
|
|
||||||
| sed -e 's/$/ :/' >> "$depfile"
|
|
||||||
rm -f "$tmpdepfile"
|
|
||||||
;;
|
|
||||||
|
|
||||||
dashXmstdout)
|
|
||||||
# This case only exists to satisfy depend.m4. It is never actually
|
|
||||||
# run, as this mode is specially recognized in the preamble.
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
|
|
||||||
makedepend)
|
|
||||||
"$@" || exit $?
|
|
||||||
# Remove any Libtool call
|
|
||||||
if test "$libtool" = yes; then
|
|
||||||
while test "X$1" != 'X--mode=compile'; do
|
|
||||||
shift
|
|
||||||
done
|
|
||||||
shift
|
|
||||||
fi
|
|
||||||
# X makedepend
|
|
||||||
shift
|
|
||||||
cleared=no eat=no
|
|
||||||
for arg
|
|
||||||
do
|
|
||||||
case $cleared in
|
|
||||||
no)
|
|
||||||
set ""; shift
|
|
||||||
cleared=yes ;;
|
|
||||||
esac
|
|
||||||
if test $eat = yes; then
|
|
||||||
eat=no
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
case "$arg" in
|
|
||||||
-D*|-I*)
|
|
||||||
set fnord "$@" "$arg"; shift ;;
|
|
||||||
# Strip any option that makedepend may not understand. Remove
|
|
||||||
# the object too, otherwise makedepend will parse it as a source file.
|
|
||||||
-arch)
|
|
||||||
eat=yes ;;
|
|
||||||
-*|$object)
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
set fnord "$@" "$arg"; shift ;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
obj_suffix=`echo "$object" | sed 's/^.*\././'`
|
|
||||||
touch "$tmpdepfile"
|
|
||||||
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
|
|
||||||
rm -f "$depfile"
|
|
||||||
# makedepend may prepend the VPATH from the source file name to the object.
|
|
||||||
# No need to regex-escape $object, excess matching of '.' is harmless.
|
|
||||||
sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
|
|
||||||
# Some versions of the HPUX 10.20 sed can't process the last invocation
|
|
||||||
# correctly. Breaking it into two sed invocations is a workaround.
|
|
||||||
sed '1,2d' "$tmpdepfile" \
|
|
||||||
| tr ' ' "$nl" \
|
|
||||||
| sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
|
|
||||||
| sed -e 's/$/ :/' >> "$depfile"
|
|
||||||
rm -f "$tmpdepfile" "$tmpdepfile".bak
|
|
||||||
;;
|
|
||||||
|
|
||||||
cpp)
|
|
||||||
# Important note: in order to support this mode, a compiler *must*
|
|
||||||
# always write the preprocessed file to stdout.
|
|
||||||
"$@" || exit $?
|
|
||||||
|
|
||||||
# Remove the call to Libtool.
|
|
||||||
if test "$libtool" = yes; then
|
|
||||||
while test "X$1" != 'X--mode=compile'; do
|
|
||||||
shift
|
|
||||||
done
|
|
||||||
shift
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Remove '-o $object'.
|
|
||||||
IFS=" "
|
|
||||||
for arg
|
|
||||||
do
|
|
||||||
case $arg in
|
|
||||||
-o)
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
$object)
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
set fnord "$@" "$arg"
|
|
||||||
shift # fnord
|
|
||||||
shift # $arg
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
"$@" -E \
|
|
||||||
| sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
|
|
||||||
-e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
|
|
||||||
| sed '$ s: \\$::' > "$tmpdepfile"
|
|
||||||
rm -f "$depfile"
|
|
||||||
echo "$object : \\" > "$depfile"
|
|
||||||
cat < "$tmpdepfile" >> "$depfile"
|
|
||||||
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
|
|
||||||
rm -f "$tmpdepfile"
|
|
||||||
;;
|
|
||||||
|
|
||||||
msvisualcpp)
|
|
||||||
# Important note: in order to support this mode, a compiler *must*
|
|
||||||
# always write the preprocessed file to stdout.
|
|
||||||
"$@" || exit $?
|
|
||||||
|
|
||||||
# Remove the call to Libtool.
|
|
||||||
if test "$libtool" = yes; then
|
|
||||||
while test "X$1" != 'X--mode=compile'; do
|
|
||||||
shift
|
|
||||||
done
|
|
||||||
shift
|
|
||||||
fi
|
|
||||||
|
|
||||||
IFS=" "
|
|
||||||
for arg
|
|
||||||
do
|
|
||||||
case "$arg" in
|
|
||||||
-o)
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
$object)
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
|
|
||||||
set fnord "$@"
|
|
||||||
shift
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
set fnord "$@" "$arg"
|
|
||||||
shift
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
"$@" -E 2>/dev/null |
|
|
||||||
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
|
|
||||||
rm -f "$depfile"
|
|
||||||
echo "$object : \\" > "$depfile"
|
|
||||||
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
|
|
||||||
echo "$tab" >> "$depfile"
|
|
||||||
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
|
|
||||||
rm -f "$tmpdepfile"
|
|
||||||
;;
|
|
||||||
|
|
||||||
msvcmsys)
|
|
||||||
# This case exists only to let depend.m4 do its work. It works by
|
|
||||||
# looking at the text of this script. This case will never be run,
|
|
||||||
# since it is checked for above.
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
|
|
||||||
none)
|
|
||||||
exec "$@"
|
|
||||||
;;
|
|
||||||
|
|
||||||
*)
|
|
||||||
echo "Unknown depmode $depmode" 1>&2
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
exit 0
|
|
||||||
|
|
||||||
# Local Variables:
|
|
||||||
# mode: shell-script
|
|
||||||
# sh-indentation: 2
|
|
||||||
# eval: (add-hook 'before-save-hook 'time-stamp)
|
|
||||||
# time-stamp-start: "scriptversion="
|
|
||||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
|
||||||
# time-stamp-time-zone: "UTC0"
|
|
||||||
# time-stamp-end: "; # UTC"
|
|
||||||
# End:
|
|
||||||
27
history.txt
27
history.txt
@@ -4,13 +4,38 @@ HTTrack Website Copier release history:
|
|||||||
|
|
||||||
This file lists all changes and fixes that have been made for HTTrack
|
This file lists all changes and fixes that have been made for HTTrack
|
||||||
|
|
||||||
|
3.49-9
|
||||||
|
+ Fixed: file-type detection from the Content-Type header: trust a declared type over a binary URL extension, honor --assume under the delayed type check, and keep a known extension against a bogus or empty Content-Type (#267, #29, #56)
|
||||||
|
+ Fixed: an uninitialized-buffer read when the Content-Type is empty (#411)
|
||||||
|
+ Fixed: restored C++ source-compatibility of the installed headers so reverse dependencies (httraqt) build again (#413)
|
||||||
|
+ Changed: multiple internal build, packaging and test-harness improvements
|
||||||
|
|
||||||
3.49-8
|
3.49-8
|
||||||
|
+ New: tunnel HTTPS downloads through the configured HTTP proxy via CONNECT (#85)
|
||||||
|
+ New: parse every candidate URL in <img> and <source> srcset lists (#326)
|
||||||
+ Changed: dropped the obsolete OpenSSL linking exception (OpenSSL 3.0+ is Apache-2.0 and GPL-compatible); httrack is now plain GPLv3-or-later
|
+ Changed: dropped the obsolete OpenSSL linking exception (OpenSSL 3.0+ is Apache-2.0 and GPL-compatible); httrack is now plain GPLv3-or-later
|
||||||
+ Fixed: link libhtsjava and the libtest examples directly against libc
|
+ Fixed: several out-of-bounds reads in the HTML/CSS parser on hostile input (#94, #396)
|
||||||
|
+ Fixed: stored XSS via an unescaped URL in the generated page footer (#165)
|
||||||
|
+ Fixed: hardened buffer copies throughout the engine against overflow
|
||||||
|
+ Fixed: capture conditional CSS @import URLs (#94)
|
||||||
|
+ Fixed: don't crawl xmlns namespace declarations as links (#191)
|
||||||
|
+ Fixed: don't mistake the method argument of XMLHttpRequest.open for a URL (#218)
|
||||||
|
+ Fixed: percent-encode parentheses when rewriting CSS url() targets (#163)
|
||||||
|
+ Fixed: collapse ../ in file:// URLs and widen relative-link handling (#137, #162)
|
||||||
|
+ Fixed: drop the obsolete $Version/$Path attributes from the request Cookie header, per RFC 6265 (#151)
|
||||||
|
+ Fixed: keep empty quoted arguments when reloading doit.log for --update/--continue (#106)
|
||||||
|
+ Fixed: raise the User-Agent and custom-header length limits (#152)
|
||||||
|
+ Fixed: abort on a long log path (lock-file buffer too small) (#183)
|
||||||
|
+ Fixed: race in lazy mutex initialization (#297)
|
||||||
|
+ Fixed: sub-second mtime precision when comparing local files on POSIX (#383)
|
||||||
|
+ Fixed: modernize OpenSSL TLS initialization for the 3.x to 4.x transition (#308)
|
||||||
+ Fixed: in-place changes made by the postprocess callback were not applied (Roman Sęk)
|
+ Fixed: in-place changes made by the postprocess callback were not applied (Roman Sęk)
|
||||||
+ Fixed: "preffered" typo in the help text and man page (yosinn1-blip)
|
+ Fixed: "preffered" typo in the help text and man page (yosinn1-blip)
|
||||||
+ Fixed: corrections and updates of the Russian translation (German Aizek)
|
+ Fixed: corrections and updates of the Russian translation (German Aizek)
|
||||||
+ Fixed: corrections and updates of the Danish translation (scootergrisen)
|
+ Fixed: corrections and updates of the Danish translation (scootergrisen)
|
||||||
|
+ Fixed: link libhtsjava and the libtest examples directly against libc
|
||||||
|
+ New: documented the public library API headers and typed the option fields as named enums
|
||||||
|
+ Fixed: numerous build, packaging, CI and test-coverage improvements (out-of-tree builds, sanitizer/distcheck CI, shell and Python linting, AppStream metainfo)
|
||||||
|
|
||||||
3.49-7
|
3.49-7
|
||||||
+ Fixed: keep generated config.h architecture-independent (Debian #1133728)
|
+ Fixed: keep generated config.h architecture-independent (Debian #1133728)
|
||||||
|
|||||||
888
html/Makefile.in
888
html/Makefile.in
@@ -1,888 +0,0 @@
|
|||||||
# Makefile.in generated by automake 1.17 from Makefile.am.
|
|
||||||
# @configure_input@
|
|
||||||
|
|
||||||
# Copyright (C) 1994-2024 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
# This Makefile.in is free software; the Free Software Foundation
|
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
|
||||||
# with or without modifications, as long as this notice is preserved.
|
|
||||||
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
|
||||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
|
||||||
# PARTICULAR PURPOSE.
|
|
||||||
|
|
||||||
@SET_MAKE@
|
|
||||||
|
|
||||||
VPATH = @srcdir@
|
|
||||||
am__is_gnu_make = { \
|
|
||||||
if test -z '$(MAKELEVEL)'; then \
|
|
||||||
false; \
|
|
||||||
elif test -n '$(MAKE_HOST)'; then \
|
|
||||||
true; \
|
|
||||||
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
|
|
||||||
true; \
|
|
||||||
else \
|
|
||||||
false; \
|
|
||||||
fi; \
|
|
||||||
}
|
|
||||||
am__make_running_with_option = \
|
|
||||||
case $${target_option-} in \
|
|
||||||
?) ;; \
|
|
||||||
*) echo "am__make_running_with_option: internal error: invalid" \
|
|
||||||
"target option '$${target_option-}' specified" >&2; \
|
|
||||||
exit 1;; \
|
|
||||||
esac; \
|
|
||||||
has_opt=no; \
|
|
||||||
sane_makeflags=$$MAKEFLAGS; \
|
|
||||||
if $(am__is_gnu_make); then \
|
|
||||||
sane_makeflags=$$MFLAGS; \
|
|
||||||
else \
|
|
||||||
case $$MAKEFLAGS in \
|
|
||||||
*\\[\ \ ]*) \
|
|
||||||
bs=\\; \
|
|
||||||
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
|
|
||||||
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
|
|
||||||
esac; \
|
|
||||||
fi; \
|
|
||||||
skip_next=no; \
|
|
||||||
strip_trailopt () \
|
|
||||||
{ \
|
|
||||||
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
|
|
||||||
}; \
|
|
||||||
for flg in $$sane_makeflags; do \
|
|
||||||
test $$skip_next = yes && { skip_next=no; continue; }; \
|
|
||||||
case $$flg in \
|
|
||||||
*=*|--*) continue;; \
|
|
||||||
-*I) strip_trailopt 'I'; skip_next=yes;; \
|
|
||||||
-*I?*) strip_trailopt 'I';; \
|
|
||||||
-*O) strip_trailopt 'O'; skip_next=yes;; \
|
|
||||||
-*O?*) strip_trailopt 'O';; \
|
|
||||||
-*l) strip_trailopt 'l'; skip_next=yes;; \
|
|
||||||
-*l?*) strip_trailopt 'l';; \
|
|
||||||
-[dEDm]) skip_next=yes;; \
|
|
||||||
-[JT]) skip_next=yes;; \
|
|
||||||
esac; \
|
|
||||||
case $$flg in \
|
|
||||||
*$$target_option*) has_opt=yes; break;; \
|
|
||||||
esac; \
|
|
||||||
done; \
|
|
||||||
test $$has_opt = yes
|
|
||||||
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
|
|
||||||
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
|
|
||||||
am__rm_f = rm -f $(am__rm_f_notfound)
|
|
||||||
am__rm_rf = rm -rf $(am__rm_f_notfound)
|
|
||||||
pkgdatadir = $(datadir)/@PACKAGE@
|
|
||||||
pkgincludedir = $(includedir)/@PACKAGE@
|
|
||||||
pkglibdir = $(libdir)/@PACKAGE@
|
|
||||||
pkglibexecdir = $(libexecdir)/@PACKAGE@
|
|
||||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
|
||||||
install_sh_DATA = $(install_sh) -c -m 644
|
|
||||||
install_sh_PROGRAM = $(install_sh) -c
|
|
||||||
install_sh_SCRIPT = $(install_sh) -c
|
|
||||||
INSTALL_HEADER = $(INSTALL_DATA)
|
|
||||||
transform = $(program_transform_name)
|
|
||||||
NORMAL_INSTALL = :
|
|
||||||
PRE_INSTALL = :
|
|
||||||
POST_INSTALL = :
|
|
||||||
NORMAL_UNINSTALL = :
|
|
||||||
PRE_UNINSTALL = :
|
|
||||||
POST_UNINSTALL = :
|
|
||||||
build_triplet = @build@
|
|
||||||
host_triplet = @host@
|
|
||||||
subdir = html
|
|
||||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
|
||||||
am__aclocal_m4_deps = $(top_srcdir)/m4/check_zlib.m4 \
|
|
||||||
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
|
|
||||||
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
|
|
||||||
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/snprintf.m4 \
|
|
||||||
$(top_srcdir)/m4/visibility.m4 $(top_srcdir)/configure.ac
|
|
||||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
|
||||||
$(ACLOCAL_M4)
|
|
||||||
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
|
|
||||||
mkinstalldirs = $(install_sh) -d
|
|
||||||
CONFIG_HEADER = $(top_builddir)/config.h
|
|
||||||
CONFIG_CLEAN_FILES =
|
|
||||||
CONFIG_CLEAN_VPATH_FILES =
|
|
||||||
AM_V_P = $(am__v_P_@AM_V@)
|
|
||||||
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
|
|
||||||
am__v_P_0 = false
|
|
||||||
am__v_P_1 = :
|
|
||||||
AM_V_GEN = $(am__v_GEN_@AM_V@)
|
|
||||||
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
|
|
||||||
am__v_GEN_0 = @echo " GEN " $@;
|
|
||||||
am__v_GEN_1 =
|
|
||||||
AM_V_at = $(am__v_at_@AM_V@)
|
|
||||||
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
|
|
||||||
am__v_at_0 = @
|
|
||||||
am__v_at_1 =
|
|
||||||
SOURCES =
|
|
||||||
DIST_SOURCES =
|
|
||||||
am__can_run_installinfo = \
|
|
||||||
case $$AM_UPDATE_INFO_DIR in \
|
|
||||||
n|no|NO) false;; \
|
|
||||||
*) (install-info --version) >/dev/null 2>&1;; \
|
|
||||||
esac
|
|
||||||
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
|
|
||||||
am__vpath_adj = case $$p in \
|
|
||||||
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
|
|
||||||
*) f=$$p;; \
|
|
||||||
esac;
|
|
||||||
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
|
|
||||||
am__install_max = 40
|
|
||||||
am__nobase_strip_setup = \
|
|
||||||
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
|
|
||||||
am__nobase_strip = \
|
|
||||||
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
|
|
||||||
am__nobase_list = $(am__nobase_strip_setup); \
|
|
||||||
for p in $$list; do echo "$$p $$p"; done | \
|
|
||||||
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
|
|
||||||
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
|
|
||||||
if (++n[$$2] == $(am__install_max)) \
|
|
||||||
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
|
|
||||||
END { for (dir in files) print dir, files[dir] }'
|
|
||||||
am__base_list = \
|
|
||||||
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
|
|
||||||
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
|
|
||||||
am__uninstall_files_from_dir = { \
|
|
||||||
{ test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|
|
||||||
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
|
|
||||||
$(am__cd) "$$dir" && echo $$files | $(am__xargs_n) 40 $(am__rm_f); }; \
|
|
||||||
}
|
|
||||||
am__installdirs = "$(DESTDIR)$(HelpHtmldir)" \
|
|
||||||
"$(DESTDIR)$(HelpHtmlTxtdir)" "$(DESTDIR)$(HelpHtmldivdir)" \
|
|
||||||
"$(DESTDIR)$(HelpHtmlimagesdir)" "$(DESTDIR)$(HelpHtmlimgdir)" \
|
|
||||||
"$(DESTDIR)$(HelpHtmlrootdir)" "$(DESTDIR)$(MetaInfodir)" \
|
|
||||||
"$(DESTDIR)$(VFolderEntrydir)" "$(DESTDIR)$(WebHtmldir)" \
|
|
||||||
"$(DESTDIR)$(WebHtmlimagesdir)" "$(DESTDIR)$(WebIcon16x16dir)" \
|
|
||||||
"$(DESTDIR)$(WebIcon32x32dir)" "$(DESTDIR)$(WebIcon48x48dir)" \
|
|
||||||
"$(DESTDIR)$(WebPixmapdir)"
|
|
||||||
DATA = $(HelpHtml_DATA) $(HelpHtmlTxt_DATA) $(HelpHtmldiv_DATA) \
|
|
||||||
$(HelpHtmlimages_DATA) $(HelpHtmlimg_DATA) \
|
|
||||||
$(HelpHtmlroot_DATA) $(MetaInfo_DATA) $(VFolderEntry_DATA) \
|
|
||||||
$(WebHtml_DATA) $(WebHtmlimages_DATA) $(WebIcon16x16_DATA) \
|
|
||||||
$(WebIcon32x32_DATA) $(WebIcon48x48_DATA) $(WebPixmap_DATA)
|
|
||||||
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
|
|
||||||
am__DIST_COMMON = $(srcdir)/Makefile.in
|
|
||||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
|
||||||
ACLOCAL = @ACLOCAL@
|
|
||||||
AMTAR = @AMTAR@
|
|
||||||
AM_CFLAGS = @AM_CFLAGS@
|
|
||||||
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
|
|
||||||
AR = @AR@
|
|
||||||
AUTOCONF = @AUTOCONF@
|
|
||||||
AUTOHEADER = @AUTOHEADER@
|
|
||||||
AUTOMAKE = @AUTOMAKE@
|
|
||||||
AWK = @AWK@
|
|
||||||
BASH = @BASH@
|
|
||||||
CC = @CC@
|
|
||||||
CCDEPMODE = @CCDEPMODE@
|
|
||||||
CFLAGS = @CFLAGS@
|
|
||||||
CFLAGS_PIE = @CFLAGS_PIE@
|
|
||||||
CFLAG_VISIBILITY = @CFLAG_VISIBILITY@
|
|
||||||
CPPFLAGS = @CPPFLAGS@
|
|
||||||
CSCOPE = @CSCOPE@
|
|
||||||
CTAGS = @CTAGS@
|
|
||||||
CYGPATH_W = @CYGPATH_W@
|
|
||||||
DEFAULT_CFLAGS = @DEFAULT_CFLAGS@
|
|
||||||
DEFAULT_LDFLAGS = @DEFAULT_LDFLAGS@
|
|
||||||
DEFS = @DEFS@
|
|
||||||
DEPDIR = @DEPDIR@
|
|
||||||
DLLTOOL = @DLLTOOL@
|
|
||||||
DL_LIBS = @DL_LIBS@
|
|
||||||
DSYMUTIL = @DSYMUTIL@
|
|
||||||
DUMPBIN = @DUMPBIN@
|
|
||||||
ECHO_C = @ECHO_C@
|
|
||||||
ECHO_N = @ECHO_N@
|
|
||||||
ECHO_T = @ECHO_T@
|
|
||||||
EGREP = @EGREP@
|
|
||||||
ETAGS = @ETAGS@
|
|
||||||
EXEEXT = @EXEEXT@
|
|
||||||
FGREP = @FGREP@
|
|
||||||
FILECMD = @FILECMD@
|
|
||||||
GREP = @GREP@
|
|
||||||
HAVE_VISIBILITY = @HAVE_VISIBILITY@
|
|
||||||
HTTPS_SUPPORT = @HTTPS_SUPPORT@
|
|
||||||
ICONV_LIBS = @ICONV_LIBS@
|
|
||||||
INSTALL = @INSTALL@
|
|
||||||
INSTALL_DATA = @INSTALL_DATA@
|
|
||||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
|
||||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
|
||||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
|
||||||
LD = @LD@
|
|
||||||
LDFLAGS = @LDFLAGS@
|
|
||||||
LDFLAGS_PIE = @LDFLAGS_PIE@
|
|
||||||
LFS_FLAG = @LFS_FLAG@
|
|
||||||
LIBC_FORCE_LINK = @LIBC_FORCE_LINK@
|
|
||||||
LIBOBJS = @LIBOBJS@
|
|
||||||
LIBS = @LIBS@
|
|
||||||
LIBTOOL = @LIBTOOL@
|
|
||||||
LIPO = @LIPO@
|
|
||||||
LN_S = @LN_S@
|
|
||||||
LTLIBOBJS = @LTLIBOBJS@
|
|
||||||
LT_CV_OBJDIR = @LT_CV_OBJDIR@
|
|
||||||
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
|
|
||||||
MAINT = @MAINT@
|
|
||||||
MAKEINFO = @MAKEINFO@
|
|
||||||
MANIFEST_TOOL = @MANIFEST_TOOL@
|
|
||||||
MKDIR_P = @MKDIR_P@
|
|
||||||
NM = @NM@
|
|
||||||
NMEDIT = @NMEDIT@
|
|
||||||
OBJDUMP = @OBJDUMP@
|
|
||||||
OBJEXT = @OBJEXT@
|
|
||||||
ONLINE_UNIT_TESTS = @ONLINE_UNIT_TESTS@
|
|
||||||
OPENSSL_LIBS = @OPENSSL_LIBS@
|
|
||||||
OTOOL = @OTOOL@
|
|
||||||
OTOOL64 = @OTOOL64@
|
|
||||||
PACKAGE = @PACKAGE@
|
|
||||||
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
|
||||||
PACKAGE_NAME = @PACKAGE_NAME@
|
|
||||||
PACKAGE_STRING = @PACKAGE_STRING@
|
|
||||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
|
||||||
PACKAGE_URL = @PACKAGE_URL@
|
|
||||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
|
||||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
|
||||||
RANLIB = @RANLIB@
|
|
||||||
SED = @SED@
|
|
||||||
SET_MAKE = @SET_MAKE@
|
|
||||||
SHELL = @SHELL@
|
|
||||||
SHLIBPATH_VAR = @SHLIBPATH_VAR@
|
|
||||||
SOCKET_LIBS = @SOCKET_LIBS@
|
|
||||||
STRIP = @STRIP@
|
|
||||||
THREADS_CFLAGS = @THREADS_CFLAGS@
|
|
||||||
THREADS_LIBS = @THREADS_LIBS@
|
|
||||||
V6_FLAG = @V6_FLAG@
|
|
||||||
VERSION = @VERSION@
|
|
||||||
VERSION_INFO = @VERSION_INFO@
|
|
||||||
abs_builddir = @abs_builddir@
|
|
||||||
abs_srcdir = @abs_srcdir@
|
|
||||||
abs_top_builddir = @abs_top_builddir@
|
|
||||||
abs_top_srcdir = @abs_top_srcdir@
|
|
||||||
ac_ct_AR = @ac_ct_AR@
|
|
||||||
ac_ct_CC = @ac_ct_CC@
|
|
||||||
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
|
|
||||||
am__include = @am__include@
|
|
||||||
am__leading_dot = @am__leading_dot@
|
|
||||||
am__quote = @am__quote@
|
|
||||||
am__rm_f_notfound = @am__rm_f_notfound@
|
|
||||||
am__tar = @am__tar@
|
|
||||||
am__untar = @am__untar@
|
|
||||||
am__xargs_n = @am__xargs_n@
|
|
||||||
bindir = @bindir@
|
|
||||||
build = @build@
|
|
||||||
build_alias = @build_alias@
|
|
||||||
build_cpu = @build_cpu@
|
|
||||||
build_os = @build_os@
|
|
||||||
build_vendor = @build_vendor@
|
|
||||||
builddir = @builddir@
|
|
||||||
datadir = @datadir@
|
|
||||||
datarootdir = @datarootdir@
|
|
||||||
docdir = @docdir@
|
|
||||||
dvidir = @dvidir@
|
|
||||||
exec_prefix = @exec_prefix@
|
|
||||||
host = @host@
|
|
||||||
host_alias = @host_alias@
|
|
||||||
host_cpu = @host_cpu@
|
|
||||||
host_os = @host_os@
|
|
||||||
host_vendor = @host_vendor@
|
|
||||||
htmldir = @htmldir@
|
|
||||||
includedir = @includedir@
|
|
||||||
infodir = @infodir@
|
|
||||||
install_sh = @install_sh@
|
|
||||||
libdir = @libdir@
|
|
||||||
libexecdir = @libexecdir@
|
|
||||||
localedir = @localedir@
|
|
||||||
localstatedir = @localstatedir@
|
|
||||||
mandir = @mandir@
|
|
||||||
mkdir_p = @mkdir_p@
|
|
||||||
oldincludedir = @oldincludedir@
|
|
||||||
pdfdir = @pdfdir@
|
|
||||||
prefix = @prefix@
|
|
||||||
program_transform_name = @program_transform_name@
|
|
||||||
psdir = @psdir@
|
|
||||||
runstatedir = @runstatedir@
|
|
||||||
sbindir = @sbindir@
|
|
||||||
sharedstatedir = @sharedstatedir@
|
|
||||||
srcdir = @srcdir@
|
|
||||||
sysconfdir = @sysconfdir@
|
|
||||||
target_alias = @target_alias@
|
|
||||||
top_build_prefix = @top_build_prefix@
|
|
||||||
top_builddir = @top_builddir@
|
|
||||||
top_srcdir = @top_srcdir@
|
|
||||||
HelpHtmlrootdir = $(docdir)
|
|
||||||
HelpHtmldir = $(htmldir)
|
|
||||||
HelpHtmlimgdir = $(HelpHtmldir)/img
|
|
||||||
HelpHtmldivdir = $(HelpHtmldir)/div
|
|
||||||
HelpHtmlimagesdir = $(HelpHtmldir)/images
|
|
||||||
HelpHtmlTxtdir = $(HelpHtmldir)
|
|
||||||
WebHtmldir = $(HelpHtmldir)/server
|
|
||||||
WebHtmlimagesdir = $(HelpHtmldir)/server/images
|
|
||||||
WebPixmapdir = $(datadir)/pixmaps
|
|
||||||
WebIcon16x16dir = $(datadir)/icons/hicolor/16x16/apps
|
|
||||||
WebIcon32x32dir = $(datadir)/icons/hicolor/32x32/apps
|
|
||||||
WebIcon48x48dir = $(datadir)/icons/hicolor/48x48/apps
|
|
||||||
VFolderEntrydir = $(prefix)/share/applications
|
|
||||||
MetaInfodir = $(datadir)/metainfo
|
|
||||||
|
|
||||||
# Wildcards are globbed against $(srcdir): a bare "*.html" is resolved against
|
|
||||||
# the build dir and stays unexpanded (breaking "make") in an out-of-tree build.
|
|
||||||
# Explicit filenames (e.g. ../history.txt, div/search.sh) resolve via VPATH and
|
|
||||||
# need no prefix.
|
|
||||||
HelpHtmlroot_DATA = ../httrack-doc.html ../history.txt
|
|
||||||
HelpHtml_DATA = $(srcdir)/*.html
|
|
||||||
HelpHtmldiv_DATA = div/search.sh
|
|
||||||
HelpHtmlimg_DATA = $(srcdir)/img/*
|
|
||||||
HelpHtmlimages_DATA = $(srcdir)/images/*
|
|
||||||
HelpHtmlTxt_DATA = ../greetings.txt ../history.txt ../license.txt
|
|
||||||
WebHtml_DATA = $(srcdir)/server/*.html $(srcdir)/server/*.js $(srcdir)/server/*.css
|
|
||||||
WebHtmlimages_DATA = $(srcdir)/server/images/*
|
|
||||||
# note: converted & normalized by
|
|
||||||
# ico2xpm favicon.ico -o httrack.xpm
|
|
||||||
# mogrify -format xpm -map /usr/share/doc/menu/examples/cmap.xpm httrack.xpm
|
|
||||||
WebPixmap_DATA = $(srcdir)/server/div/*.xpm
|
|
||||||
WebIcon16x16_DATA = $(srcdir)/server/div/16x16/*.png
|
|
||||||
WebIcon32x32_DATA = $(srcdir)/server/div/32x32/*.png
|
|
||||||
WebIcon48x48_DATA = $(srcdir)/server/div/48x48/*.png
|
|
||||||
VFolderEntry_DATA = $(srcdir)/server/div/*.desktop
|
|
||||||
MetaInfo_DATA = $(srcdir)/server/div/*.metainfo.xml
|
|
||||||
EXTRA_DIST = $(HelpHtml_DATA) $(HelpHtmlimg_DATA) $(HelpHtmlimages_DATA) \
|
|
||||||
$(HelpHtmldiv_DATA) $(WebHtml_DATA) $(WebHtmlimages_DATA) \
|
|
||||||
$(WebPixmap_DATA) $(WebIcon16x16_DATA) $(WebIcon32x32_DATA) $(WebIcon48x48_DATA) \
|
|
||||||
$(VFolderEntry_DATA) $(MetaInfo_DATA) \
|
|
||||||
httrack.css
|
|
||||||
|
|
||||||
all: all-am
|
|
||||||
|
|
||||||
.SUFFIXES:
|
|
||||||
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
|
|
||||||
@for dep in $?; do \
|
|
||||||
case '$(am__configure_deps)' in \
|
|
||||||
*$$dep*) \
|
|
||||||
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
|
|
||||||
&& { if test -f $@; then exit 0; else break; fi; }; \
|
|
||||||
exit 1;; \
|
|
||||||
esac; \
|
|
||||||
done; \
|
|
||||||
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu html/Makefile'; \
|
|
||||||
$(am__cd) $(top_srcdir) && \
|
|
||||||
$(AUTOMAKE) --gnu html/Makefile
|
|
||||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
|
||||||
@case '$?' in \
|
|
||||||
*config.status*) \
|
|
||||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
|
|
||||||
*) \
|
|
||||||
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
|
|
||||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
|
|
||||||
esac;
|
|
||||||
|
|
||||||
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
|
||||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
|
||||||
|
|
||||||
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
|
|
||||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
|
||||||
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
|
|
||||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
|
||||||
$(am__aclocal_m4_deps):
|
|
||||||
|
|
||||||
mostlyclean-libtool:
|
|
||||||
-rm -f *.lo
|
|
||||||
|
|
||||||
clean-libtool:
|
|
||||||
-rm -rf .libs _libs
|
|
||||||
install-HelpHtmlDATA: $(HelpHtml_DATA)
|
|
||||||
@$(NORMAL_INSTALL)
|
|
||||||
@list='$(HelpHtml_DATA)'; test -n "$(HelpHtmldir)" || list=; \
|
|
||||||
if test -n "$$list"; then \
|
|
||||||
echo " $(MKDIR_P) '$(DESTDIR)$(HelpHtmldir)'"; \
|
|
||||||
$(MKDIR_P) "$(DESTDIR)$(HelpHtmldir)" || exit 1; \
|
|
||||||
fi; \
|
|
||||||
for p in $$list; do \
|
|
||||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
|
||||||
echo "$$d$$p"; \
|
|
||||||
done | $(am__base_list) | \
|
|
||||||
while read files; do \
|
|
||||||
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(HelpHtmldir)'"; \
|
|
||||||
$(INSTALL_DATA) $$files "$(DESTDIR)$(HelpHtmldir)" || exit $$?; \
|
|
||||||
done
|
|
||||||
|
|
||||||
uninstall-HelpHtmlDATA:
|
|
||||||
@$(NORMAL_UNINSTALL)
|
|
||||||
@list='$(HelpHtml_DATA)'; test -n "$(HelpHtmldir)" || list=; \
|
|
||||||
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
|
|
||||||
dir='$(DESTDIR)$(HelpHtmldir)'; $(am__uninstall_files_from_dir)
|
|
||||||
install-HelpHtmlTxtDATA: $(HelpHtmlTxt_DATA)
|
|
||||||
@$(NORMAL_INSTALL)
|
|
||||||
@list='$(HelpHtmlTxt_DATA)'; test -n "$(HelpHtmlTxtdir)" || list=; \
|
|
||||||
if test -n "$$list"; then \
|
|
||||||
echo " $(MKDIR_P) '$(DESTDIR)$(HelpHtmlTxtdir)'"; \
|
|
||||||
$(MKDIR_P) "$(DESTDIR)$(HelpHtmlTxtdir)" || exit 1; \
|
|
||||||
fi; \
|
|
||||||
for p in $$list; do \
|
|
||||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
|
||||||
echo "$$d$$p"; \
|
|
||||||
done | $(am__base_list) | \
|
|
||||||
while read files; do \
|
|
||||||
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(HelpHtmlTxtdir)'"; \
|
|
||||||
$(INSTALL_DATA) $$files "$(DESTDIR)$(HelpHtmlTxtdir)" || exit $$?; \
|
|
||||||
done
|
|
||||||
|
|
||||||
uninstall-HelpHtmlTxtDATA:
|
|
||||||
@$(NORMAL_UNINSTALL)
|
|
||||||
@list='$(HelpHtmlTxt_DATA)'; test -n "$(HelpHtmlTxtdir)" || list=; \
|
|
||||||
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
|
|
||||||
dir='$(DESTDIR)$(HelpHtmlTxtdir)'; $(am__uninstall_files_from_dir)
|
|
||||||
install-HelpHtmldivDATA: $(HelpHtmldiv_DATA)
|
|
||||||
@$(NORMAL_INSTALL)
|
|
||||||
@list='$(HelpHtmldiv_DATA)'; test -n "$(HelpHtmldivdir)" || list=; \
|
|
||||||
if test -n "$$list"; then \
|
|
||||||
echo " $(MKDIR_P) '$(DESTDIR)$(HelpHtmldivdir)'"; \
|
|
||||||
$(MKDIR_P) "$(DESTDIR)$(HelpHtmldivdir)" || exit 1; \
|
|
||||||
fi; \
|
|
||||||
for p in $$list; do \
|
|
||||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
|
||||||
echo "$$d$$p"; \
|
|
||||||
done | $(am__base_list) | \
|
|
||||||
while read files; do \
|
|
||||||
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(HelpHtmldivdir)'"; \
|
|
||||||
$(INSTALL_DATA) $$files "$(DESTDIR)$(HelpHtmldivdir)" || exit $$?; \
|
|
||||||
done
|
|
||||||
|
|
||||||
uninstall-HelpHtmldivDATA:
|
|
||||||
@$(NORMAL_UNINSTALL)
|
|
||||||
@list='$(HelpHtmldiv_DATA)'; test -n "$(HelpHtmldivdir)" || list=; \
|
|
||||||
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
|
|
||||||
dir='$(DESTDIR)$(HelpHtmldivdir)'; $(am__uninstall_files_from_dir)
|
|
||||||
install-HelpHtmlimagesDATA: $(HelpHtmlimages_DATA)
|
|
||||||
@$(NORMAL_INSTALL)
|
|
||||||
@list='$(HelpHtmlimages_DATA)'; test -n "$(HelpHtmlimagesdir)" || list=; \
|
|
||||||
if test -n "$$list"; then \
|
|
||||||
echo " $(MKDIR_P) '$(DESTDIR)$(HelpHtmlimagesdir)'"; \
|
|
||||||
$(MKDIR_P) "$(DESTDIR)$(HelpHtmlimagesdir)" || exit 1; \
|
|
||||||
fi; \
|
|
||||||
for p in $$list; do \
|
|
||||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
|
||||||
echo "$$d$$p"; \
|
|
||||||
done | $(am__base_list) | \
|
|
||||||
while read files; do \
|
|
||||||
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(HelpHtmlimagesdir)'"; \
|
|
||||||
$(INSTALL_DATA) $$files "$(DESTDIR)$(HelpHtmlimagesdir)" || exit $$?; \
|
|
||||||
done
|
|
||||||
|
|
||||||
uninstall-HelpHtmlimagesDATA:
|
|
||||||
@$(NORMAL_UNINSTALL)
|
|
||||||
@list='$(HelpHtmlimages_DATA)'; test -n "$(HelpHtmlimagesdir)" || list=; \
|
|
||||||
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
|
|
||||||
dir='$(DESTDIR)$(HelpHtmlimagesdir)'; $(am__uninstall_files_from_dir)
|
|
||||||
install-HelpHtmlimgDATA: $(HelpHtmlimg_DATA)
|
|
||||||
@$(NORMAL_INSTALL)
|
|
||||||
@list='$(HelpHtmlimg_DATA)'; test -n "$(HelpHtmlimgdir)" || list=; \
|
|
||||||
if test -n "$$list"; then \
|
|
||||||
echo " $(MKDIR_P) '$(DESTDIR)$(HelpHtmlimgdir)'"; \
|
|
||||||
$(MKDIR_P) "$(DESTDIR)$(HelpHtmlimgdir)" || exit 1; \
|
|
||||||
fi; \
|
|
||||||
for p in $$list; do \
|
|
||||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
|
||||||
echo "$$d$$p"; \
|
|
||||||
done | $(am__base_list) | \
|
|
||||||
while read files; do \
|
|
||||||
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(HelpHtmlimgdir)'"; \
|
|
||||||
$(INSTALL_DATA) $$files "$(DESTDIR)$(HelpHtmlimgdir)" || exit $$?; \
|
|
||||||
done
|
|
||||||
|
|
||||||
uninstall-HelpHtmlimgDATA:
|
|
||||||
@$(NORMAL_UNINSTALL)
|
|
||||||
@list='$(HelpHtmlimg_DATA)'; test -n "$(HelpHtmlimgdir)" || list=; \
|
|
||||||
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
|
|
||||||
dir='$(DESTDIR)$(HelpHtmlimgdir)'; $(am__uninstall_files_from_dir)
|
|
||||||
install-HelpHtmlrootDATA: $(HelpHtmlroot_DATA)
|
|
||||||
@$(NORMAL_INSTALL)
|
|
||||||
@list='$(HelpHtmlroot_DATA)'; test -n "$(HelpHtmlrootdir)" || list=; \
|
|
||||||
if test -n "$$list"; then \
|
|
||||||
echo " $(MKDIR_P) '$(DESTDIR)$(HelpHtmlrootdir)'"; \
|
|
||||||
$(MKDIR_P) "$(DESTDIR)$(HelpHtmlrootdir)" || exit 1; \
|
|
||||||
fi; \
|
|
||||||
for p in $$list; do \
|
|
||||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
|
||||||
echo "$$d$$p"; \
|
|
||||||
done | $(am__base_list) | \
|
|
||||||
while read files; do \
|
|
||||||
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(HelpHtmlrootdir)'"; \
|
|
||||||
$(INSTALL_DATA) $$files "$(DESTDIR)$(HelpHtmlrootdir)" || exit $$?; \
|
|
||||||
done
|
|
||||||
|
|
||||||
uninstall-HelpHtmlrootDATA:
|
|
||||||
@$(NORMAL_UNINSTALL)
|
|
||||||
@list='$(HelpHtmlroot_DATA)'; test -n "$(HelpHtmlrootdir)" || list=; \
|
|
||||||
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
|
|
||||||
dir='$(DESTDIR)$(HelpHtmlrootdir)'; $(am__uninstall_files_from_dir)
|
|
||||||
install-MetaInfoDATA: $(MetaInfo_DATA)
|
|
||||||
@$(NORMAL_INSTALL)
|
|
||||||
@list='$(MetaInfo_DATA)'; test -n "$(MetaInfodir)" || list=; \
|
|
||||||
if test -n "$$list"; then \
|
|
||||||
echo " $(MKDIR_P) '$(DESTDIR)$(MetaInfodir)'"; \
|
|
||||||
$(MKDIR_P) "$(DESTDIR)$(MetaInfodir)" || exit 1; \
|
|
||||||
fi; \
|
|
||||||
for p in $$list; do \
|
|
||||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
|
||||||
echo "$$d$$p"; \
|
|
||||||
done | $(am__base_list) | \
|
|
||||||
while read files; do \
|
|
||||||
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(MetaInfodir)'"; \
|
|
||||||
$(INSTALL_DATA) $$files "$(DESTDIR)$(MetaInfodir)" || exit $$?; \
|
|
||||||
done
|
|
||||||
|
|
||||||
uninstall-MetaInfoDATA:
|
|
||||||
@$(NORMAL_UNINSTALL)
|
|
||||||
@list='$(MetaInfo_DATA)'; test -n "$(MetaInfodir)" || list=; \
|
|
||||||
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
|
|
||||||
dir='$(DESTDIR)$(MetaInfodir)'; $(am__uninstall_files_from_dir)
|
|
||||||
install-VFolderEntryDATA: $(VFolderEntry_DATA)
|
|
||||||
@$(NORMAL_INSTALL)
|
|
||||||
@list='$(VFolderEntry_DATA)'; test -n "$(VFolderEntrydir)" || list=; \
|
|
||||||
if test -n "$$list"; then \
|
|
||||||
echo " $(MKDIR_P) '$(DESTDIR)$(VFolderEntrydir)'"; \
|
|
||||||
$(MKDIR_P) "$(DESTDIR)$(VFolderEntrydir)" || exit 1; \
|
|
||||||
fi; \
|
|
||||||
for p in $$list; do \
|
|
||||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
|
||||||
echo "$$d$$p"; \
|
|
||||||
done | $(am__base_list) | \
|
|
||||||
while read files; do \
|
|
||||||
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(VFolderEntrydir)'"; \
|
|
||||||
$(INSTALL_DATA) $$files "$(DESTDIR)$(VFolderEntrydir)" || exit $$?; \
|
|
||||||
done
|
|
||||||
|
|
||||||
uninstall-VFolderEntryDATA:
|
|
||||||
@$(NORMAL_UNINSTALL)
|
|
||||||
@list='$(VFolderEntry_DATA)'; test -n "$(VFolderEntrydir)" || list=; \
|
|
||||||
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
|
|
||||||
dir='$(DESTDIR)$(VFolderEntrydir)'; $(am__uninstall_files_from_dir)
|
|
||||||
install-WebHtmlDATA: $(WebHtml_DATA)
|
|
||||||
@$(NORMAL_INSTALL)
|
|
||||||
@list='$(WebHtml_DATA)'; test -n "$(WebHtmldir)" || list=; \
|
|
||||||
if test -n "$$list"; then \
|
|
||||||
echo " $(MKDIR_P) '$(DESTDIR)$(WebHtmldir)'"; \
|
|
||||||
$(MKDIR_P) "$(DESTDIR)$(WebHtmldir)" || exit 1; \
|
|
||||||
fi; \
|
|
||||||
for p in $$list; do \
|
|
||||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
|
||||||
echo "$$d$$p"; \
|
|
||||||
done | $(am__base_list) | \
|
|
||||||
while read files; do \
|
|
||||||
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(WebHtmldir)'"; \
|
|
||||||
$(INSTALL_DATA) $$files "$(DESTDIR)$(WebHtmldir)" || exit $$?; \
|
|
||||||
done
|
|
||||||
|
|
||||||
uninstall-WebHtmlDATA:
|
|
||||||
@$(NORMAL_UNINSTALL)
|
|
||||||
@list='$(WebHtml_DATA)'; test -n "$(WebHtmldir)" || list=; \
|
|
||||||
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
|
|
||||||
dir='$(DESTDIR)$(WebHtmldir)'; $(am__uninstall_files_from_dir)
|
|
||||||
install-WebHtmlimagesDATA: $(WebHtmlimages_DATA)
|
|
||||||
@$(NORMAL_INSTALL)
|
|
||||||
@list='$(WebHtmlimages_DATA)'; test -n "$(WebHtmlimagesdir)" || list=; \
|
|
||||||
if test -n "$$list"; then \
|
|
||||||
echo " $(MKDIR_P) '$(DESTDIR)$(WebHtmlimagesdir)'"; \
|
|
||||||
$(MKDIR_P) "$(DESTDIR)$(WebHtmlimagesdir)" || exit 1; \
|
|
||||||
fi; \
|
|
||||||
for p in $$list; do \
|
|
||||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
|
||||||
echo "$$d$$p"; \
|
|
||||||
done | $(am__base_list) | \
|
|
||||||
while read files; do \
|
|
||||||
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(WebHtmlimagesdir)'"; \
|
|
||||||
$(INSTALL_DATA) $$files "$(DESTDIR)$(WebHtmlimagesdir)" || exit $$?; \
|
|
||||||
done
|
|
||||||
|
|
||||||
uninstall-WebHtmlimagesDATA:
|
|
||||||
@$(NORMAL_UNINSTALL)
|
|
||||||
@list='$(WebHtmlimages_DATA)'; test -n "$(WebHtmlimagesdir)" || list=; \
|
|
||||||
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
|
|
||||||
dir='$(DESTDIR)$(WebHtmlimagesdir)'; $(am__uninstall_files_from_dir)
|
|
||||||
install-WebIcon16x16DATA: $(WebIcon16x16_DATA)
|
|
||||||
@$(NORMAL_INSTALL)
|
|
||||||
@list='$(WebIcon16x16_DATA)'; test -n "$(WebIcon16x16dir)" || list=; \
|
|
||||||
if test -n "$$list"; then \
|
|
||||||
echo " $(MKDIR_P) '$(DESTDIR)$(WebIcon16x16dir)'"; \
|
|
||||||
$(MKDIR_P) "$(DESTDIR)$(WebIcon16x16dir)" || exit 1; \
|
|
||||||
fi; \
|
|
||||||
for p in $$list; do \
|
|
||||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
|
||||||
echo "$$d$$p"; \
|
|
||||||
done | $(am__base_list) | \
|
|
||||||
while read files; do \
|
|
||||||
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(WebIcon16x16dir)'"; \
|
|
||||||
$(INSTALL_DATA) $$files "$(DESTDIR)$(WebIcon16x16dir)" || exit $$?; \
|
|
||||||
done
|
|
||||||
|
|
||||||
uninstall-WebIcon16x16DATA:
|
|
||||||
@$(NORMAL_UNINSTALL)
|
|
||||||
@list='$(WebIcon16x16_DATA)'; test -n "$(WebIcon16x16dir)" || list=; \
|
|
||||||
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
|
|
||||||
dir='$(DESTDIR)$(WebIcon16x16dir)'; $(am__uninstall_files_from_dir)
|
|
||||||
install-WebIcon32x32DATA: $(WebIcon32x32_DATA)
|
|
||||||
@$(NORMAL_INSTALL)
|
|
||||||
@list='$(WebIcon32x32_DATA)'; test -n "$(WebIcon32x32dir)" || list=; \
|
|
||||||
if test -n "$$list"; then \
|
|
||||||
echo " $(MKDIR_P) '$(DESTDIR)$(WebIcon32x32dir)'"; \
|
|
||||||
$(MKDIR_P) "$(DESTDIR)$(WebIcon32x32dir)" || exit 1; \
|
|
||||||
fi; \
|
|
||||||
for p in $$list; do \
|
|
||||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
|
||||||
echo "$$d$$p"; \
|
|
||||||
done | $(am__base_list) | \
|
|
||||||
while read files; do \
|
|
||||||
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(WebIcon32x32dir)'"; \
|
|
||||||
$(INSTALL_DATA) $$files "$(DESTDIR)$(WebIcon32x32dir)" || exit $$?; \
|
|
||||||
done
|
|
||||||
|
|
||||||
uninstall-WebIcon32x32DATA:
|
|
||||||
@$(NORMAL_UNINSTALL)
|
|
||||||
@list='$(WebIcon32x32_DATA)'; test -n "$(WebIcon32x32dir)" || list=; \
|
|
||||||
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
|
|
||||||
dir='$(DESTDIR)$(WebIcon32x32dir)'; $(am__uninstall_files_from_dir)
|
|
||||||
install-WebIcon48x48DATA: $(WebIcon48x48_DATA)
|
|
||||||
@$(NORMAL_INSTALL)
|
|
||||||
@list='$(WebIcon48x48_DATA)'; test -n "$(WebIcon48x48dir)" || list=; \
|
|
||||||
if test -n "$$list"; then \
|
|
||||||
echo " $(MKDIR_P) '$(DESTDIR)$(WebIcon48x48dir)'"; \
|
|
||||||
$(MKDIR_P) "$(DESTDIR)$(WebIcon48x48dir)" || exit 1; \
|
|
||||||
fi; \
|
|
||||||
for p in $$list; do \
|
|
||||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
|
||||||
echo "$$d$$p"; \
|
|
||||||
done | $(am__base_list) | \
|
|
||||||
while read files; do \
|
|
||||||
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(WebIcon48x48dir)'"; \
|
|
||||||
$(INSTALL_DATA) $$files "$(DESTDIR)$(WebIcon48x48dir)" || exit $$?; \
|
|
||||||
done
|
|
||||||
|
|
||||||
uninstall-WebIcon48x48DATA:
|
|
||||||
@$(NORMAL_UNINSTALL)
|
|
||||||
@list='$(WebIcon48x48_DATA)'; test -n "$(WebIcon48x48dir)" || list=; \
|
|
||||||
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
|
|
||||||
dir='$(DESTDIR)$(WebIcon48x48dir)'; $(am__uninstall_files_from_dir)
|
|
||||||
install-WebPixmapDATA: $(WebPixmap_DATA)
|
|
||||||
@$(NORMAL_INSTALL)
|
|
||||||
@list='$(WebPixmap_DATA)'; test -n "$(WebPixmapdir)" || list=; \
|
|
||||||
if test -n "$$list"; then \
|
|
||||||
echo " $(MKDIR_P) '$(DESTDIR)$(WebPixmapdir)'"; \
|
|
||||||
$(MKDIR_P) "$(DESTDIR)$(WebPixmapdir)" || exit 1; \
|
|
||||||
fi; \
|
|
||||||
for p in $$list; do \
|
|
||||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
|
||||||
echo "$$d$$p"; \
|
|
||||||
done | $(am__base_list) | \
|
|
||||||
while read files; do \
|
|
||||||
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(WebPixmapdir)'"; \
|
|
||||||
$(INSTALL_DATA) $$files "$(DESTDIR)$(WebPixmapdir)" || exit $$?; \
|
|
||||||
done
|
|
||||||
|
|
||||||
uninstall-WebPixmapDATA:
|
|
||||||
@$(NORMAL_UNINSTALL)
|
|
||||||
@list='$(WebPixmap_DATA)'; test -n "$(WebPixmapdir)" || list=; \
|
|
||||||
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
|
|
||||||
dir='$(DESTDIR)$(WebPixmapdir)'; $(am__uninstall_files_from_dir)
|
|
||||||
tags TAGS:
|
|
||||||
|
|
||||||
ctags CTAGS:
|
|
||||||
|
|
||||||
cscope cscopelist:
|
|
||||||
|
|
||||||
distdir: $(BUILT_SOURCES)
|
|
||||||
$(MAKE) $(AM_MAKEFLAGS) distdir-am
|
|
||||||
|
|
||||||
distdir-am: $(DISTFILES)
|
|
||||||
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
|
||||||
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
|
||||||
list='$(DISTFILES)'; \
|
|
||||||
dist_files=`for file in $$list; do echo $$file; done | \
|
|
||||||
sed -e "s|^$$srcdirstrip/||;t" \
|
|
||||||
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
|
|
||||||
case $$dist_files in \
|
|
||||||
*/*) $(MKDIR_P) `echo "$$dist_files" | \
|
|
||||||
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
|
|
||||||
sort -u` ;; \
|
|
||||||
esac; \
|
|
||||||
for file in $$dist_files; do \
|
|
||||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
|
||||||
if test -d $$d/$$file; then \
|
|
||||||
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
|
|
||||||
if test -d "$(distdir)/$$file"; then \
|
|
||||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
|
||||||
fi; \
|
|
||||||
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
|
||||||
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
|
|
||||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
|
||||||
fi; \
|
|
||||||
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
|
|
||||||
else \
|
|
||||||
test -f "$(distdir)/$$file" \
|
|
||||||
|| cp -p $$d/$$file "$(distdir)/$$file" \
|
|
||||||
|| exit 1; \
|
|
||||||
fi; \
|
|
||||||
done
|
|
||||||
check-am: all-am
|
|
||||||
check: check-am
|
|
||||||
all-am: Makefile $(DATA)
|
|
||||||
installdirs:
|
|
||||||
for dir in "$(DESTDIR)$(HelpHtmldir)" "$(DESTDIR)$(HelpHtmlTxtdir)" "$(DESTDIR)$(HelpHtmldivdir)" "$(DESTDIR)$(HelpHtmlimagesdir)" "$(DESTDIR)$(HelpHtmlimgdir)" "$(DESTDIR)$(HelpHtmlrootdir)" "$(DESTDIR)$(MetaInfodir)" "$(DESTDIR)$(VFolderEntrydir)" "$(DESTDIR)$(WebHtmldir)" "$(DESTDIR)$(WebHtmlimagesdir)" "$(DESTDIR)$(WebIcon16x16dir)" "$(DESTDIR)$(WebIcon32x32dir)" "$(DESTDIR)$(WebIcon48x48dir)" "$(DESTDIR)$(WebPixmapdir)"; do \
|
|
||||||
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
|
|
||||||
done
|
|
||||||
install: install-am
|
|
||||||
install-exec: install-exec-am
|
|
||||||
install-data: install-data-am
|
|
||||||
uninstall: uninstall-am
|
|
||||||
|
|
||||||
install-am: all-am
|
|
||||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
|
||||||
|
|
||||||
installcheck: installcheck-am
|
|
||||||
install-strip:
|
|
||||||
if test -z '$(STRIP)'; then \
|
|
||||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
|
||||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
|
||||||
install; \
|
|
||||||
else \
|
|
||||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
|
||||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
|
||||||
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
|
|
||||||
fi
|
|
||||||
mostlyclean-generic:
|
|
||||||
|
|
||||||
clean-generic:
|
|
||||||
|
|
||||||
distclean-generic:
|
|
||||||
-$(am__rm_f) $(CONFIG_CLEAN_FILES)
|
|
||||||
-test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES)
|
|
||||||
|
|
||||||
maintainer-clean-generic:
|
|
||||||
@echo "This command is intended for maintainers to use"
|
|
||||||
@echo "it deletes files that may require special tools to rebuild."
|
|
||||||
clean: clean-am
|
|
||||||
|
|
||||||
clean-am: clean-generic clean-libtool mostlyclean-am
|
|
||||||
|
|
||||||
distclean: distclean-am
|
|
||||||
-rm -f Makefile
|
|
||||||
distclean-am: clean-am distclean-generic
|
|
||||||
|
|
||||||
dvi: dvi-am
|
|
||||||
|
|
||||||
dvi-am:
|
|
||||||
|
|
||||||
html: html-am
|
|
||||||
|
|
||||||
html-am:
|
|
||||||
|
|
||||||
info: info-am
|
|
||||||
|
|
||||||
info-am:
|
|
||||||
|
|
||||||
install-data-am: install-HelpHtmlDATA install-HelpHtmlTxtDATA \
|
|
||||||
install-HelpHtmldivDATA install-HelpHtmlimagesDATA \
|
|
||||||
install-HelpHtmlimgDATA install-HelpHtmlrootDATA \
|
|
||||||
install-MetaInfoDATA install-VFolderEntryDATA \
|
|
||||||
install-WebHtmlDATA install-WebHtmlimagesDATA \
|
|
||||||
install-WebIcon16x16DATA install-WebIcon32x32DATA \
|
|
||||||
install-WebIcon48x48DATA install-WebPixmapDATA
|
|
||||||
@$(NORMAL_INSTALL)
|
|
||||||
$(MAKE) $(AM_MAKEFLAGS) install-data-hook
|
|
||||||
install-dvi: install-dvi-am
|
|
||||||
|
|
||||||
install-dvi-am:
|
|
||||||
|
|
||||||
install-exec-am:
|
|
||||||
|
|
||||||
install-html: install-html-am
|
|
||||||
|
|
||||||
install-html-am:
|
|
||||||
|
|
||||||
install-info: install-info-am
|
|
||||||
|
|
||||||
install-info-am:
|
|
||||||
|
|
||||||
install-man:
|
|
||||||
|
|
||||||
install-pdf: install-pdf-am
|
|
||||||
|
|
||||||
install-pdf-am:
|
|
||||||
|
|
||||||
install-ps: install-ps-am
|
|
||||||
|
|
||||||
install-ps-am:
|
|
||||||
|
|
||||||
installcheck-am:
|
|
||||||
|
|
||||||
maintainer-clean: maintainer-clean-am
|
|
||||||
-rm -f Makefile
|
|
||||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
|
||||||
|
|
||||||
mostlyclean: mostlyclean-am
|
|
||||||
|
|
||||||
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
|
|
||||||
|
|
||||||
pdf: pdf-am
|
|
||||||
|
|
||||||
pdf-am:
|
|
||||||
|
|
||||||
ps: ps-am
|
|
||||||
|
|
||||||
ps-am:
|
|
||||||
|
|
||||||
uninstall-am: uninstall-HelpHtmlDATA uninstall-HelpHtmlTxtDATA \
|
|
||||||
uninstall-HelpHtmldivDATA uninstall-HelpHtmlimagesDATA \
|
|
||||||
uninstall-HelpHtmlimgDATA uninstall-HelpHtmlrootDATA \
|
|
||||||
uninstall-MetaInfoDATA uninstall-VFolderEntryDATA \
|
|
||||||
uninstall-WebHtmlDATA uninstall-WebHtmlimagesDATA \
|
|
||||||
uninstall-WebIcon16x16DATA uninstall-WebIcon32x32DATA \
|
|
||||||
uninstall-WebIcon48x48DATA uninstall-WebPixmapDATA
|
|
||||||
|
|
||||||
.MAKE: install-am install-data-am install-strip
|
|
||||||
|
|
||||||
.PHONY: all all-am check check-am clean clean-generic clean-libtool \
|
|
||||||
cscopelist-am ctags-am distclean distclean-generic \
|
|
||||||
distclean-libtool distdir dvi dvi-am html html-am info info-am \
|
|
||||||
install install-HelpHtmlDATA install-HelpHtmlTxtDATA \
|
|
||||||
install-HelpHtmldivDATA install-HelpHtmlimagesDATA \
|
|
||||||
install-HelpHtmlimgDATA install-HelpHtmlrootDATA \
|
|
||||||
install-MetaInfoDATA install-VFolderEntryDATA \
|
|
||||||
install-WebHtmlDATA install-WebHtmlimagesDATA \
|
|
||||||
install-WebIcon16x16DATA install-WebIcon32x32DATA \
|
|
||||||
install-WebIcon48x48DATA install-WebPixmapDATA install-am \
|
|
||||||
install-data install-data-am install-data-hook install-dvi \
|
|
||||||
install-dvi-am install-exec install-exec-am install-html \
|
|
||||||
install-html-am install-info install-info-am install-man \
|
|
||||||
install-pdf install-pdf-am install-ps install-ps-am \
|
|
||||||
install-strip installcheck installcheck-am installdirs \
|
|
||||||
maintainer-clean maintainer-clean-generic mostlyclean \
|
|
||||||
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
|
|
||||||
tags-am uninstall uninstall-HelpHtmlDATA \
|
|
||||||
uninstall-HelpHtmlTxtDATA uninstall-HelpHtmldivDATA \
|
|
||||||
uninstall-HelpHtmlimagesDATA uninstall-HelpHtmlimgDATA \
|
|
||||||
uninstall-HelpHtmlrootDATA uninstall-MetaInfoDATA \
|
|
||||||
uninstall-VFolderEntryDATA uninstall-WebHtmlDATA \
|
|
||||||
uninstall-WebHtmlimagesDATA uninstall-WebIcon16x16DATA \
|
|
||||||
uninstall-WebIcon32x32DATA uninstall-WebIcon48x48DATA \
|
|
||||||
uninstall-WebPixmapDATA uninstall-am
|
|
||||||
|
|
||||||
.PRECIOUS: Makefile
|
|
||||||
|
|
||||||
|
|
||||||
install-data-hook:
|
|
||||||
if test ! -L $(DESTDIR)$(prefix)/share/httrack/html ; then \
|
|
||||||
( cd $(DESTDIR)$(prefix)/share/httrack \
|
|
||||||
&& $(LN_S) $(htmldir) html \
|
|
||||||
) \
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
|
||||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
|
||||||
.NOEXPORT:
|
|
||||||
|
|
||||||
# Tell GNU make to disable its built-in pattern rules.
|
|
||||||
%:: %,v
|
|
||||||
%:: RCS/%,v
|
|
||||||
%:: RCS/%
|
|
||||||
%:: s.%
|
|
||||||
%:: SCCS/s.%
|
|
||||||
@@ -1,8 +1,7 @@
|
|||||||
|
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
# Simple indexing test using HTTrack
|
# Simple indexing test using HTTrack
|
||||||
# A "real" script/program would use advanced search, and
|
# A "real" script/program would use advanced search, and
|
||||||
# use dichotomy to find the word in the index.txt file
|
# use dichotomy to find the word in the index.txt file
|
||||||
# This script is really basic and NOT optimized, and
|
# This script is really basic and NOT optimized, and
|
||||||
# should not be used for professional purpose :)
|
# should not be used for professional purpose :)
|
||||||
@@ -11,50 +10,49 @@ TESTSITE="http://localhost/"
|
|||||||
|
|
||||||
# Create an index if necessary
|
# Create an index if necessary
|
||||||
if ! test -f "index.txt"; then
|
if ! test -f "index.txt"; then
|
||||||
echo "Building the index .."
|
echo "Building the index .."
|
||||||
rm -rf test
|
rm -rf test
|
||||||
httrack --display "$TESTSITE" -%I -O test
|
httrack --display "$TESTSITE" -%I -O test
|
||||||
mv test/index.txt ./
|
mv test/index.txt ./
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Convert crlf to lf
|
# Convert crlf to lf
|
||||||
if test "`head index.txt -n 1 | tr '\r' '#' | grep -c '#'`" = "1"; then
|
if test "$(head index.txt -n 1 | tr '\r' '#' | grep -c '#')" = "1"; then
|
||||||
echo "Converting index to Unix LF style (not CR/LF) .."
|
echo "Converting index to Unix LF style (not CR/LF) .."
|
||||||
mv -f index.txt index.txt.old
|
mv -f index.txt index.txt.old
|
||||||
cat index.txt.old|tr -d '\r' > index.txt
|
tr -d '\r' <index.txt.old >index.txt
|
||||||
fi
|
fi
|
||||||
|
|
||||||
keyword=-
|
keyword=-
|
||||||
while test -n "$keyword"; do
|
while test -n "$keyword"; do
|
||||||
printf "Enter a keyword: "
|
printf "Enter a keyword: "
|
||||||
read keyword
|
read -r keyword
|
||||||
|
|
||||||
if test -n "$keyword"; then
|
if test -n "$keyword"; then
|
||||||
FOUNDK="`grep -niE \"^$keyword\" index.txt`"
|
FOUNDK="$(grep -niE "^$keyword" index.txt)"
|
||||||
|
|
||||||
if test -n "$FOUNDK"; then
|
if test -n "$FOUNDK"; then
|
||||||
if ! test `echo "$FOUNDK"|wc -l` = "1"; then
|
if ! test "$(echo "$FOUNDK" | wc -l)" = "1"; then
|
||||||
# Multiple matches
|
# Multiple matches
|
||||||
printf "Found multiple keywords: "
|
printf "Found multiple keywords: "
|
||||||
echo "$FOUNDK"|cut -f2 -d':'|tr '\n' ' '
|
echo "$FOUNDK" | cut -f2 -d':' | tr '\n' ' '
|
||||||
echo ""
|
echo ""
|
||||||
echo "Use keyword$ to find only one"
|
echo "Use keyword$ to find only one"
|
||||||
else
|
else
|
||||||
# One match
|
# One match
|
||||||
N=`echo "$FOUNDK"|cut -f1 -d':'`
|
N=$(echo "$FOUNDK" | cut -f1 -d':')
|
||||||
PM=`tail +$N index.txt|grep -nE "\("|head -n 1`
|
PM=$(tail "+$N" index.txt | grep -nE "\(" | head -n 1)
|
||||||
if ! echo "$PM"|grep "ignored">/dev/null; then
|
if ! echo "$PM" | grep "ignored" >/dev/null; then
|
||||||
M=`echo $PM|cut -f1 -d':'`
|
M=$(echo "$PM" | cut -f1 -d':')
|
||||||
echo "Found in:"
|
echo "Found in:"
|
||||||
cat index.txt | tail "+$N" | head -n "$M" | grep -E "[0-9]* " | cut -f2 -d' '
|
tail "+$N" index.txt | head -n "$M" | grep -E "[0-9]* " | cut -f2 -d' '
|
||||||
else
|
else
|
||||||
echo "keyword ignored (too many hits)"
|
echo "keyword ignored (too many hits)"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
echo "not found"
|
echo "not found"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|||||||
541
install-sh
541
install-sh
@@ -1,541 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
# install - install a program, script, or datafile
|
|
||||||
|
|
||||||
scriptversion=2024-06-19.01; # UTC
|
|
||||||
|
|
||||||
# This originates from X11R5 (mit/util/scripts/install.sh), which was
|
|
||||||
# later released in X11R6 (xc/config/util/install.sh) with the
|
|
||||||
# following copyright and license.
|
|
||||||
#
|
|
||||||
# Copyright (C) 1994 X Consortium
|
|
||||||
#
|
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
# of this software and associated documentation files (the "Software"), to
|
|
||||||
# deal in the Software without restriction, including without limitation the
|
|
||||||
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
||||||
# sell copies of the Software, and to permit persons to whom the Software is
|
|
||||||
# furnished to do so, subject to the following conditions:
|
|
||||||
#
|
|
||||||
# The above copyright notice and this permission notice shall be included in
|
|
||||||
# all copies or substantial portions of the Software.
|
|
||||||
#
|
|
||||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
|
||||||
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
|
|
||||||
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
#
|
|
||||||
# Except as contained in this notice, the name of the X Consortium shall not
|
|
||||||
# be used in advertising or otherwise to promote the sale, use or other deal-
|
|
||||||
# ings in this Software without prior written authorization from the X Consor-
|
|
||||||
# tium.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# FSF changes to this file are in the public domain.
|
|
||||||
#
|
|
||||||
# Calling this script install-sh is preferred over install.sh, to prevent
|
|
||||||
# 'make' implicit rules from creating a file called install from it
|
|
||||||
# when there is no Makefile.
|
|
||||||
#
|
|
||||||
# This script is compatible with the BSD install script, but was written
|
|
||||||
# from scratch.
|
|
||||||
|
|
||||||
tab=' '
|
|
||||||
nl='
|
|
||||||
'
|
|
||||||
IFS=" $tab$nl"
|
|
||||||
|
|
||||||
# Set DOITPROG to "echo" to test this script.
|
|
||||||
|
|
||||||
doit=${DOITPROG-}
|
|
||||||
doit_exec=${doit:-exec}
|
|
||||||
|
|
||||||
# Put in absolute file names if you don't have them in your path;
|
|
||||||
# or use environment vars.
|
|
||||||
|
|
||||||
chgrpprog=${CHGRPPROG-chgrp}
|
|
||||||
chmodprog=${CHMODPROG-chmod}
|
|
||||||
chownprog=${CHOWNPROG-chown}
|
|
||||||
cmpprog=${CMPPROG-cmp}
|
|
||||||
cpprog=${CPPROG-cp}
|
|
||||||
mkdirprog=${MKDIRPROG-mkdir}
|
|
||||||
mvprog=${MVPROG-mv}
|
|
||||||
rmprog=${RMPROG-rm}
|
|
||||||
stripprog=${STRIPPROG-strip}
|
|
||||||
|
|
||||||
posix_mkdir=
|
|
||||||
|
|
||||||
# Desired mode of installed file.
|
|
||||||
mode=0755
|
|
||||||
|
|
||||||
# Create dirs (including intermediate dirs) using mode 755.
|
|
||||||
# This is like GNU 'install' as of coreutils 8.32 (2020).
|
|
||||||
mkdir_umask=22
|
|
||||||
|
|
||||||
backupsuffix=
|
|
||||||
chgrpcmd=
|
|
||||||
chmodcmd=$chmodprog
|
|
||||||
chowncmd=
|
|
||||||
mvcmd=$mvprog
|
|
||||||
rmcmd="$rmprog -f"
|
|
||||||
stripcmd=
|
|
||||||
|
|
||||||
src=
|
|
||||||
dst=
|
|
||||||
dir_arg=
|
|
||||||
dst_arg=
|
|
||||||
|
|
||||||
copy_on_change=false
|
|
||||||
is_target_a_directory=possibly
|
|
||||||
|
|
||||||
usage="\
|
|
||||||
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
|
|
||||||
or: $0 [OPTION]... SRCFILES... DIRECTORY
|
|
||||||
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
|
|
||||||
or: $0 [OPTION]... -d DIRECTORIES...
|
|
||||||
|
|
||||||
In the 1st form, copy SRCFILE to DSTFILE.
|
|
||||||
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
|
|
||||||
In the 4th, create DIRECTORIES.
|
|
||||||
|
|
||||||
Options:
|
|
||||||
--help display this help and exit.
|
|
||||||
--version display version info and exit.
|
|
||||||
|
|
||||||
-c (ignored)
|
|
||||||
-C install only if different (preserve data modification time)
|
|
||||||
-d create directories instead of installing files.
|
|
||||||
-g GROUP $chgrpprog installed files to GROUP.
|
|
||||||
-m MODE $chmodprog installed files to MODE.
|
|
||||||
-o USER $chownprog installed files to USER.
|
|
||||||
-p pass -p to $cpprog.
|
|
||||||
-s $stripprog installed files.
|
|
||||||
-S SUFFIX attempt to back up existing files, with suffix SUFFIX.
|
|
||||||
-t DIRECTORY install into DIRECTORY.
|
|
||||||
-T report an error if DSTFILE is a directory.
|
|
||||||
|
|
||||||
Environment variables override the default commands:
|
|
||||||
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
|
|
||||||
RMPROG STRIPPROG
|
|
||||||
|
|
||||||
By default, rm is invoked with -f; when overridden with RMPROG,
|
|
||||||
it's up to you to specify -f if you want it.
|
|
||||||
|
|
||||||
If -S is not specified, no backups are attempted.
|
|
||||||
|
|
||||||
Report bugs to <bug-automake@gnu.org>.
|
|
||||||
GNU Automake home page: <https://www.gnu.org/software/automake/>.
|
|
||||||
General help using GNU software: <https://www.gnu.org/gethelp/>."
|
|
||||||
|
|
||||||
while test $# -ne 0; do
|
|
||||||
case $1 in
|
|
||||||
-c) ;;
|
|
||||||
|
|
||||||
-C) copy_on_change=true;;
|
|
||||||
|
|
||||||
-d) dir_arg=true;;
|
|
||||||
|
|
||||||
-g) chgrpcmd="$chgrpprog $2"
|
|
||||||
shift;;
|
|
||||||
|
|
||||||
--help) echo "$usage"; exit $?;;
|
|
||||||
|
|
||||||
-m) mode=$2
|
|
||||||
case $mode in
|
|
||||||
*' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
|
|
||||||
echo "$0: invalid mode: $mode" >&2
|
|
||||||
exit 1;;
|
|
||||||
esac
|
|
||||||
shift;;
|
|
||||||
|
|
||||||
-o) chowncmd="$chownprog $2"
|
|
||||||
shift;;
|
|
||||||
|
|
||||||
-p) cpprog="$cpprog -p";;
|
|
||||||
|
|
||||||
-s) stripcmd=$stripprog;;
|
|
||||||
|
|
||||||
-S) backupsuffix="$2"
|
|
||||||
shift;;
|
|
||||||
|
|
||||||
-t)
|
|
||||||
is_target_a_directory=always
|
|
||||||
dst_arg=$2
|
|
||||||
# Protect names problematic for 'test' and other utilities.
|
|
||||||
case $dst_arg in
|
|
||||||
-* | [=\(\)!]) dst_arg=./$dst_arg;;
|
|
||||||
esac
|
|
||||||
shift;;
|
|
||||||
|
|
||||||
-T) is_target_a_directory=never;;
|
|
||||||
|
|
||||||
--version) echo "$0 (GNU Automake) $scriptversion"; exit $?;;
|
|
||||||
|
|
||||||
--) shift
|
|
||||||
break;;
|
|
||||||
|
|
||||||
-*) echo "$0: invalid option: $1" >&2
|
|
||||||
exit 1;;
|
|
||||||
|
|
||||||
*) break;;
|
|
||||||
esac
|
|
||||||
shift
|
|
||||||
done
|
|
||||||
|
|
||||||
# We allow the use of options -d and -T together, by making -d
|
|
||||||
# take the precedence; this is for compatibility with GNU install.
|
|
||||||
|
|
||||||
if test -n "$dir_arg"; then
|
|
||||||
if test -n "$dst_arg"; then
|
|
||||||
echo "$0: target directory not allowed when installing a directory." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
|
|
||||||
# When -d is used, all remaining arguments are directories to create.
|
|
||||||
# When -t is used, the destination is already specified.
|
|
||||||
# Otherwise, the last argument is the destination. Remove it from $@.
|
|
||||||
for arg
|
|
||||||
do
|
|
||||||
if test -n "$dst_arg"; then
|
|
||||||
# $@ is not empty: it contains at least $arg.
|
|
||||||
set fnord "$@" "$dst_arg"
|
|
||||||
shift # fnord
|
|
||||||
fi
|
|
||||||
shift # arg
|
|
||||||
dst_arg=$arg
|
|
||||||
# Protect names problematic for 'test' and other utilities.
|
|
||||||
case $dst_arg in
|
|
||||||
-* | [=\(\)!]) dst_arg=./$dst_arg;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test $# -eq 0; then
|
|
||||||
if test -z "$dir_arg"; then
|
|
||||||
echo "$0: no input file specified." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
# It's OK to call 'install-sh -d' without argument.
|
|
||||||
# This can happen when creating conditional directories.
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test -z "$dir_arg"; then
|
|
||||||
if test $# -gt 1 || test "$is_target_a_directory" = always; then
|
|
||||||
if test ! -d "$dst_arg"; then
|
|
||||||
echo "$0: $dst_arg: Is not a directory." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test -z "$dir_arg"; then
|
|
||||||
do_exit='(exit $ret); exit $ret'
|
|
||||||
trap "ret=129; $do_exit" 1
|
|
||||||
trap "ret=130; $do_exit" 2
|
|
||||||
trap "ret=141; $do_exit" 13
|
|
||||||
trap "ret=143; $do_exit" 15
|
|
||||||
|
|
||||||
# Set umask so as not to create temps with too-generous modes.
|
|
||||||
# However, 'strip' requires both read and write access to temps.
|
|
||||||
case $mode in
|
|
||||||
# Optimize common cases.
|
|
||||||
*644) cp_umask=133;;
|
|
||||||
*755) cp_umask=22;;
|
|
||||||
|
|
||||||
*[0-7])
|
|
||||||
if test -z "$stripcmd"; then
|
|
||||||
u_plus_rw=
|
|
||||||
else
|
|
||||||
u_plus_rw='% 200'
|
|
||||||
fi
|
|
||||||
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
|
|
||||||
*)
|
|
||||||
if test -z "$stripcmd"; then
|
|
||||||
u_plus_rw=
|
|
||||||
else
|
|
||||||
u_plus_rw=,u+rw
|
|
||||||
fi
|
|
||||||
cp_umask=$mode$u_plus_rw;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
|
|
||||||
for src
|
|
||||||
do
|
|
||||||
# Protect names problematic for 'test' and other utilities.
|
|
||||||
case $src in
|
|
||||||
-* | [=\(\)!]) src=./$src;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
if test -n "$dir_arg"; then
|
|
||||||
dst=$src
|
|
||||||
dstdir=$dst
|
|
||||||
test -d "$dstdir"
|
|
||||||
dstdir_status=$?
|
|
||||||
# Don't chown directories that already exist.
|
|
||||||
if test $dstdir_status = 0; then
|
|
||||||
chowncmd=""
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
|
|
||||||
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
|
|
||||||
# might cause directories to be created, which would be especially bad
|
|
||||||
# if $src (and thus $dsttmp) contains '*'.
|
|
||||||
if test ! -f "$src" && test ! -d "$src"; then
|
|
||||||
echo "$0: $src does not exist." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test -z "$dst_arg"; then
|
|
||||||
echo "$0: no destination specified." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
dst=$dst_arg
|
|
||||||
|
|
||||||
# If destination is a directory, append the input filename.
|
|
||||||
if test -d "$dst"; then
|
|
||||||
if test "$is_target_a_directory" = never; then
|
|
||||||
echo "$0: $dst_arg: Is a directory" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
dstdir=$dst
|
|
||||||
dstbase=`basename "$src"`
|
|
||||||
case $dst in
|
|
||||||
*/) dst=$dst$dstbase;;
|
|
||||||
*) dst=$dst/$dstbase;;
|
|
||||||
esac
|
|
||||||
dstdir_status=0
|
|
||||||
else
|
|
||||||
dstdir=`dirname "$dst"`
|
|
||||||
test -d "$dstdir"
|
|
||||||
dstdir_status=$?
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
case $dstdir in
|
|
||||||
*/) dstdirslash=$dstdir;;
|
|
||||||
*) dstdirslash=$dstdir/;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
obsolete_mkdir_used=false
|
|
||||||
|
|
||||||
if test $dstdir_status != 0; then
|
|
||||||
case $posix_mkdir in
|
|
||||||
'')
|
|
||||||
# With -d, create the new directory with the user-specified mode.
|
|
||||||
# Otherwise, rely on $mkdir_umask.
|
|
||||||
if test -n "$dir_arg"; then
|
|
||||||
mkdir_mode=-m$mode
|
|
||||||
else
|
|
||||||
mkdir_mode=
|
|
||||||
fi
|
|
||||||
|
|
||||||
posix_mkdir=false
|
|
||||||
# The $RANDOM variable is not portable (e.g., dash). Use it
|
|
||||||
# here however when possible just to lower collision chance.
|
|
||||||
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
|
|
||||||
|
|
||||||
trap '
|
|
||||||
ret=$?
|
|
||||||
rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null
|
|
||||||
exit $ret
|
|
||||||
' 0
|
|
||||||
|
|
||||||
# Because "mkdir -p" follows existing symlinks and we likely work
|
|
||||||
# directly in world-writable /tmp, make sure that the '$tmpdir'
|
|
||||||
# directory is successfully created first before we actually test
|
|
||||||
# 'mkdir -p'.
|
|
||||||
if (umask $mkdir_umask &&
|
|
||||||
$mkdirprog $mkdir_mode "$tmpdir" &&
|
|
||||||
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
|
|
||||||
then
|
|
||||||
if test -z "$dir_arg" || {
|
|
||||||
# Check for POSIX incompatibility with -m.
|
|
||||||
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
|
|
||||||
# other-writable bit of parent directory when it shouldn't.
|
|
||||||
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
|
|
||||||
test_tmpdir="$tmpdir/a"
|
|
||||||
ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
|
|
||||||
case $ls_ld_tmpdir in
|
|
||||||
d????-?r-*) different_mode=700;;
|
|
||||||
d????-?--*) different_mode=755;;
|
|
||||||
*) false;;
|
|
||||||
esac &&
|
|
||||||
$mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
|
|
||||||
ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
|
|
||||||
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
then posix_mkdir=:
|
|
||||||
fi
|
|
||||||
rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
|
|
||||||
else
|
|
||||||
# Remove any dirs left behind by ancient mkdir implementations.
|
|
||||||
rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
|
|
||||||
fi
|
|
||||||
trap '' 0;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
if
|
|
||||||
$posix_mkdir && (
|
|
||||||
umask $mkdir_umask &&
|
|
||||||
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
|
|
||||||
)
|
|
||||||
then :
|
|
||||||
else
|
|
||||||
|
|
||||||
# mkdir does not conform to POSIX,
|
|
||||||
# or it failed possibly due to a race condition. Create the
|
|
||||||
# directory the slow way, step by step, checking for races as we go.
|
|
||||||
|
|
||||||
case $dstdir in
|
|
||||||
/*) prefix='/';;
|
|
||||||
[-=\(\)!]*) prefix='./';;
|
|
||||||
*) prefix='';;
|
|
||||||
esac
|
|
||||||
|
|
||||||
oIFS=$IFS
|
|
||||||
IFS=/
|
|
||||||
set -f
|
|
||||||
set fnord $dstdir
|
|
||||||
shift
|
|
||||||
set +f
|
|
||||||
IFS=$oIFS
|
|
||||||
|
|
||||||
prefixes=
|
|
||||||
|
|
||||||
for d
|
|
||||||
do
|
|
||||||
test X"$d" = X && continue
|
|
||||||
|
|
||||||
prefix=$prefix$d
|
|
||||||
if test -d "$prefix"; then
|
|
||||||
prefixes=
|
|
||||||
else
|
|
||||||
if $posix_mkdir; then
|
|
||||||
(umask $mkdir_umask &&
|
|
||||||
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
|
|
||||||
# Don't fail if two instances are running concurrently.
|
|
||||||
test -d "$prefix" || exit 1
|
|
||||||
else
|
|
||||||
case $prefix in
|
|
||||||
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
|
|
||||||
*) qprefix=$prefix;;
|
|
||||||
esac
|
|
||||||
prefixes="$prefixes '$qprefix'"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
prefix=$prefix/
|
|
||||||
done
|
|
||||||
|
|
||||||
if test -n "$prefixes"; then
|
|
||||||
# Don't fail if two instances are running concurrently.
|
|
||||||
(umask $mkdir_umask &&
|
|
||||||
eval "\$doit_exec \$mkdirprog $prefixes") ||
|
|
||||||
test -d "$dstdir" || exit 1
|
|
||||||
obsolete_mkdir_used=true
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test -n "$dir_arg"; then
|
|
||||||
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
|
|
||||||
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
|
|
||||||
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
|
|
||||||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
|
|
||||||
else
|
|
||||||
|
|
||||||
# Make a couple of temp file names in the proper directory.
|
|
||||||
dsttmp=${dstdirslash}_inst.$$_
|
|
||||||
rmtmp=${dstdirslash}_rm.$$_
|
|
||||||
|
|
||||||
# Trap to clean up those temp files at exit.
|
|
||||||
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
|
|
||||||
|
|
||||||
# Copy the file name to the temp name.
|
|
||||||
(umask $cp_umask &&
|
|
||||||
{ test -z "$stripcmd" || {
|
|
||||||
# Create $dsttmp read-write so that cp doesn't create it read-only,
|
|
||||||
# which would cause strip to fail.
|
|
||||||
if test -z "$doit"; then
|
|
||||||
: >"$dsttmp" # No need to fork-exec 'touch'.
|
|
||||||
else
|
|
||||||
$doit touch "$dsttmp"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
} &&
|
|
||||||
$doit_exec $cpprog "$src" "$dsttmp") &&
|
|
||||||
|
|
||||||
# and set any options; do chmod last to preserve setuid bits.
|
|
||||||
#
|
|
||||||
# If any of these fail, we abort the whole thing. If we want to
|
|
||||||
# ignore errors from any of these, just make sure not to ignore
|
|
||||||
# errors from the above "$doit $cpprog $src $dsttmp" command.
|
|
||||||
#
|
|
||||||
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
|
|
||||||
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
|
|
||||||
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
|
|
||||||
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
|
|
||||||
|
|
||||||
# If -C, don't bother to copy if it wouldn't change the file.
|
|
||||||
if $copy_on_change &&
|
|
||||||
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
|
|
||||||
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
|
|
||||||
set -f &&
|
|
||||||
set X $old && old=:$2:$4:$5:$6 &&
|
|
||||||
set X $new && new=:$2:$4:$5:$6 &&
|
|
||||||
set +f &&
|
|
||||||
test "$old" = "$new" &&
|
|
||||||
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
|
|
||||||
then
|
|
||||||
rm -f "$dsttmp"
|
|
||||||
else
|
|
||||||
# If $backupsuffix is set, and the file being installed
|
|
||||||
# already exists, attempt a backup. Don't worry if it fails,
|
|
||||||
# e.g., if mv doesn't support -f.
|
|
||||||
if test -n "$backupsuffix" && test -f "$dst"; then
|
|
||||||
$doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Rename the file to the real destination.
|
|
||||||
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
|
|
||||||
|
|
||||||
# The rename failed, perhaps because mv can't rename something else
|
|
||||||
# to itself, or perhaps because mv is so ancient that it does not
|
|
||||||
# support -f.
|
|
||||||
{
|
|
||||||
# Now remove or move aside any old file at destination location.
|
|
||||||
# We try this two ways since rm can't unlink itself on some
|
|
||||||
# systems and the destination file might be busy for other
|
|
||||||
# reasons. In this case, the final cleanup might fail but the new
|
|
||||||
# file should still install successfully.
|
|
||||||
{
|
|
||||||
test ! -f "$dst" ||
|
|
||||||
$doit $rmcmd "$dst" 2>/dev/null ||
|
|
||||||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
|
|
||||||
{ $doit $rmcmd "$rmtmp" 2>/dev/null; :; }
|
|
||||||
} ||
|
|
||||||
{ echo "$0: cannot unlink or rename $dst" >&2
|
|
||||||
(exit 1); exit 1
|
|
||||||
}
|
|
||||||
} &&
|
|
||||||
|
|
||||||
# Now rename the file to the real destination.
|
|
||||||
$doit $mvcmd "$dsttmp" "$dst"
|
|
||||||
}
|
|
||||||
fi || exit 1
|
|
||||||
|
|
||||||
trap '' 0
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# Local variables:
|
|
||||||
# eval: (add-hook 'before-save-hook 'time-stamp)
|
|
||||||
# time-stamp-start: "scriptversion="
|
|
||||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
|
||||||
# time-stamp-time-zone: "UTC0"
|
|
||||||
# time-stamp-end: "; # UTC"
|
|
||||||
# End:
|
|
||||||
559
lang/Makefile.in
559
lang/Makefile.in
@@ -1,559 +0,0 @@
|
|||||||
# Makefile.in generated by automake 1.17 from Makefile.am.
|
|
||||||
# @configure_input@
|
|
||||||
|
|
||||||
# Copyright (C) 1994-2024 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
# This Makefile.in is free software; the Free Software Foundation
|
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
|
||||||
# with or without modifications, as long as this notice is preserved.
|
|
||||||
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
|
||||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
|
||||||
# PARTICULAR PURPOSE.
|
|
||||||
|
|
||||||
@SET_MAKE@
|
|
||||||
|
|
||||||
VPATH = @srcdir@
|
|
||||||
am__is_gnu_make = { \
|
|
||||||
if test -z '$(MAKELEVEL)'; then \
|
|
||||||
false; \
|
|
||||||
elif test -n '$(MAKE_HOST)'; then \
|
|
||||||
true; \
|
|
||||||
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
|
|
||||||
true; \
|
|
||||||
else \
|
|
||||||
false; \
|
|
||||||
fi; \
|
|
||||||
}
|
|
||||||
am__make_running_with_option = \
|
|
||||||
case $${target_option-} in \
|
|
||||||
?) ;; \
|
|
||||||
*) echo "am__make_running_with_option: internal error: invalid" \
|
|
||||||
"target option '$${target_option-}' specified" >&2; \
|
|
||||||
exit 1;; \
|
|
||||||
esac; \
|
|
||||||
has_opt=no; \
|
|
||||||
sane_makeflags=$$MAKEFLAGS; \
|
|
||||||
if $(am__is_gnu_make); then \
|
|
||||||
sane_makeflags=$$MFLAGS; \
|
|
||||||
else \
|
|
||||||
case $$MAKEFLAGS in \
|
|
||||||
*\\[\ \ ]*) \
|
|
||||||
bs=\\; \
|
|
||||||
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
|
|
||||||
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
|
|
||||||
esac; \
|
|
||||||
fi; \
|
|
||||||
skip_next=no; \
|
|
||||||
strip_trailopt () \
|
|
||||||
{ \
|
|
||||||
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
|
|
||||||
}; \
|
|
||||||
for flg in $$sane_makeflags; do \
|
|
||||||
test $$skip_next = yes && { skip_next=no; continue; }; \
|
|
||||||
case $$flg in \
|
|
||||||
*=*|--*) continue;; \
|
|
||||||
-*I) strip_trailopt 'I'; skip_next=yes;; \
|
|
||||||
-*I?*) strip_trailopt 'I';; \
|
|
||||||
-*O) strip_trailopt 'O'; skip_next=yes;; \
|
|
||||||
-*O?*) strip_trailopt 'O';; \
|
|
||||||
-*l) strip_trailopt 'l'; skip_next=yes;; \
|
|
||||||
-*l?*) strip_trailopt 'l';; \
|
|
||||||
-[dEDm]) skip_next=yes;; \
|
|
||||||
-[JT]) skip_next=yes;; \
|
|
||||||
esac; \
|
|
||||||
case $$flg in \
|
|
||||||
*$$target_option*) has_opt=yes; break;; \
|
|
||||||
esac; \
|
|
||||||
done; \
|
|
||||||
test $$has_opt = yes
|
|
||||||
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
|
|
||||||
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
|
|
||||||
am__rm_f = rm -f $(am__rm_f_notfound)
|
|
||||||
am__rm_rf = rm -rf $(am__rm_f_notfound)
|
|
||||||
pkgdatadir = $(datadir)/@PACKAGE@
|
|
||||||
pkgincludedir = $(includedir)/@PACKAGE@
|
|
||||||
pkglibdir = $(libdir)/@PACKAGE@
|
|
||||||
pkglibexecdir = $(libexecdir)/@PACKAGE@
|
|
||||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
|
||||||
install_sh_DATA = $(install_sh) -c -m 644
|
|
||||||
install_sh_PROGRAM = $(install_sh) -c
|
|
||||||
install_sh_SCRIPT = $(install_sh) -c
|
|
||||||
INSTALL_HEADER = $(INSTALL_DATA)
|
|
||||||
transform = $(program_transform_name)
|
|
||||||
NORMAL_INSTALL = :
|
|
||||||
PRE_INSTALL = :
|
|
||||||
POST_INSTALL = :
|
|
||||||
NORMAL_UNINSTALL = :
|
|
||||||
PRE_UNINSTALL = :
|
|
||||||
POST_UNINSTALL = :
|
|
||||||
build_triplet = @build@
|
|
||||||
host_triplet = @host@
|
|
||||||
subdir = lang
|
|
||||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
|
||||||
am__aclocal_m4_deps = $(top_srcdir)/m4/check_zlib.m4 \
|
|
||||||
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
|
|
||||||
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
|
|
||||||
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/snprintf.m4 \
|
|
||||||
$(top_srcdir)/m4/visibility.m4 $(top_srcdir)/configure.ac
|
|
||||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
|
||||||
$(ACLOCAL_M4)
|
|
||||||
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
|
|
||||||
mkinstalldirs = $(install_sh) -d
|
|
||||||
CONFIG_HEADER = $(top_builddir)/config.h
|
|
||||||
CONFIG_CLEAN_FILES =
|
|
||||||
CONFIG_CLEAN_VPATH_FILES =
|
|
||||||
AM_V_P = $(am__v_P_@AM_V@)
|
|
||||||
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
|
|
||||||
am__v_P_0 = false
|
|
||||||
am__v_P_1 = :
|
|
||||||
AM_V_GEN = $(am__v_GEN_@AM_V@)
|
|
||||||
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
|
|
||||||
am__v_GEN_0 = @echo " GEN " $@;
|
|
||||||
am__v_GEN_1 =
|
|
||||||
AM_V_at = $(am__v_at_@AM_V@)
|
|
||||||
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
|
|
||||||
am__v_at_0 = @
|
|
||||||
am__v_at_1 =
|
|
||||||
SOURCES =
|
|
||||||
DIST_SOURCES =
|
|
||||||
am__can_run_installinfo = \
|
|
||||||
case $$AM_UPDATE_INFO_DIR in \
|
|
||||||
n|no|NO) false;; \
|
|
||||||
*) (install-info --version) >/dev/null 2>&1;; \
|
|
||||||
esac
|
|
||||||
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
|
|
||||||
am__vpath_adj = case $$p in \
|
|
||||||
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
|
|
||||||
*) f=$$p;; \
|
|
||||||
esac;
|
|
||||||
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
|
|
||||||
am__install_max = 40
|
|
||||||
am__nobase_strip_setup = \
|
|
||||||
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
|
|
||||||
am__nobase_strip = \
|
|
||||||
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
|
|
||||||
am__nobase_list = $(am__nobase_strip_setup); \
|
|
||||||
for p in $$list; do echo "$$p $$p"; done | \
|
|
||||||
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
|
|
||||||
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
|
|
||||||
if (++n[$$2] == $(am__install_max)) \
|
|
||||||
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
|
|
||||||
END { for (dir in files) print dir, files[dir] }'
|
|
||||||
am__base_list = \
|
|
||||||
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
|
|
||||||
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
|
|
||||||
am__uninstall_files_from_dir = { \
|
|
||||||
{ test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|
|
||||||
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
|
|
||||||
$(am__cd) "$$dir" && echo $$files | $(am__xargs_n) 40 $(am__rm_f); }; \
|
|
||||||
}
|
|
||||||
am__installdirs = "$(DESTDIR)$(langdir)" "$(DESTDIR)$(langrootdir)"
|
|
||||||
DATA = $(lang_DATA) $(langroot_DATA)
|
|
||||||
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
|
|
||||||
am__DIST_COMMON = $(srcdir)/Makefile.in
|
|
||||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
|
||||||
ACLOCAL = @ACLOCAL@
|
|
||||||
AMTAR = @AMTAR@
|
|
||||||
AM_CFLAGS = @AM_CFLAGS@
|
|
||||||
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
|
|
||||||
AR = @AR@
|
|
||||||
AUTOCONF = @AUTOCONF@
|
|
||||||
AUTOHEADER = @AUTOHEADER@
|
|
||||||
AUTOMAKE = @AUTOMAKE@
|
|
||||||
AWK = @AWK@
|
|
||||||
BASH = @BASH@
|
|
||||||
CC = @CC@
|
|
||||||
CCDEPMODE = @CCDEPMODE@
|
|
||||||
CFLAGS = @CFLAGS@
|
|
||||||
CFLAGS_PIE = @CFLAGS_PIE@
|
|
||||||
CFLAG_VISIBILITY = @CFLAG_VISIBILITY@
|
|
||||||
CPPFLAGS = @CPPFLAGS@
|
|
||||||
CSCOPE = @CSCOPE@
|
|
||||||
CTAGS = @CTAGS@
|
|
||||||
CYGPATH_W = @CYGPATH_W@
|
|
||||||
DEFAULT_CFLAGS = @DEFAULT_CFLAGS@
|
|
||||||
DEFAULT_LDFLAGS = @DEFAULT_LDFLAGS@
|
|
||||||
DEFS = @DEFS@
|
|
||||||
DEPDIR = @DEPDIR@
|
|
||||||
DLLTOOL = @DLLTOOL@
|
|
||||||
DL_LIBS = @DL_LIBS@
|
|
||||||
DSYMUTIL = @DSYMUTIL@
|
|
||||||
DUMPBIN = @DUMPBIN@
|
|
||||||
ECHO_C = @ECHO_C@
|
|
||||||
ECHO_N = @ECHO_N@
|
|
||||||
ECHO_T = @ECHO_T@
|
|
||||||
EGREP = @EGREP@
|
|
||||||
ETAGS = @ETAGS@
|
|
||||||
EXEEXT = @EXEEXT@
|
|
||||||
FGREP = @FGREP@
|
|
||||||
FILECMD = @FILECMD@
|
|
||||||
GREP = @GREP@
|
|
||||||
HAVE_VISIBILITY = @HAVE_VISIBILITY@
|
|
||||||
HTTPS_SUPPORT = @HTTPS_SUPPORT@
|
|
||||||
ICONV_LIBS = @ICONV_LIBS@
|
|
||||||
INSTALL = @INSTALL@
|
|
||||||
INSTALL_DATA = @INSTALL_DATA@
|
|
||||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
|
||||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
|
||||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
|
||||||
LD = @LD@
|
|
||||||
LDFLAGS = @LDFLAGS@
|
|
||||||
LDFLAGS_PIE = @LDFLAGS_PIE@
|
|
||||||
LFS_FLAG = @LFS_FLAG@
|
|
||||||
LIBC_FORCE_LINK = @LIBC_FORCE_LINK@
|
|
||||||
LIBOBJS = @LIBOBJS@
|
|
||||||
LIBS = @LIBS@
|
|
||||||
LIBTOOL = @LIBTOOL@
|
|
||||||
LIPO = @LIPO@
|
|
||||||
LN_S = @LN_S@
|
|
||||||
LTLIBOBJS = @LTLIBOBJS@
|
|
||||||
LT_CV_OBJDIR = @LT_CV_OBJDIR@
|
|
||||||
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
|
|
||||||
MAINT = @MAINT@
|
|
||||||
MAKEINFO = @MAKEINFO@
|
|
||||||
MANIFEST_TOOL = @MANIFEST_TOOL@
|
|
||||||
MKDIR_P = @MKDIR_P@
|
|
||||||
NM = @NM@
|
|
||||||
NMEDIT = @NMEDIT@
|
|
||||||
OBJDUMP = @OBJDUMP@
|
|
||||||
OBJEXT = @OBJEXT@
|
|
||||||
ONLINE_UNIT_TESTS = @ONLINE_UNIT_TESTS@
|
|
||||||
OPENSSL_LIBS = @OPENSSL_LIBS@
|
|
||||||
OTOOL = @OTOOL@
|
|
||||||
OTOOL64 = @OTOOL64@
|
|
||||||
PACKAGE = @PACKAGE@
|
|
||||||
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
|
||||||
PACKAGE_NAME = @PACKAGE_NAME@
|
|
||||||
PACKAGE_STRING = @PACKAGE_STRING@
|
|
||||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
|
||||||
PACKAGE_URL = @PACKAGE_URL@
|
|
||||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
|
||||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
|
||||||
RANLIB = @RANLIB@
|
|
||||||
SED = @SED@
|
|
||||||
SET_MAKE = @SET_MAKE@
|
|
||||||
SHELL = @SHELL@
|
|
||||||
SHLIBPATH_VAR = @SHLIBPATH_VAR@
|
|
||||||
SOCKET_LIBS = @SOCKET_LIBS@
|
|
||||||
STRIP = @STRIP@
|
|
||||||
THREADS_CFLAGS = @THREADS_CFLAGS@
|
|
||||||
THREADS_LIBS = @THREADS_LIBS@
|
|
||||||
V6_FLAG = @V6_FLAG@
|
|
||||||
VERSION = @VERSION@
|
|
||||||
VERSION_INFO = @VERSION_INFO@
|
|
||||||
abs_builddir = @abs_builddir@
|
|
||||||
abs_srcdir = @abs_srcdir@
|
|
||||||
abs_top_builddir = @abs_top_builddir@
|
|
||||||
abs_top_srcdir = @abs_top_srcdir@
|
|
||||||
ac_ct_AR = @ac_ct_AR@
|
|
||||||
ac_ct_CC = @ac_ct_CC@
|
|
||||||
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
|
|
||||||
am__include = @am__include@
|
|
||||||
am__leading_dot = @am__leading_dot@
|
|
||||||
am__quote = @am__quote@
|
|
||||||
am__rm_f_notfound = @am__rm_f_notfound@
|
|
||||||
am__tar = @am__tar@
|
|
||||||
am__untar = @am__untar@
|
|
||||||
am__xargs_n = @am__xargs_n@
|
|
||||||
bindir = @bindir@
|
|
||||||
build = @build@
|
|
||||||
build_alias = @build_alias@
|
|
||||||
build_cpu = @build_cpu@
|
|
||||||
build_os = @build_os@
|
|
||||||
build_vendor = @build_vendor@
|
|
||||||
builddir = @builddir@
|
|
||||||
datadir = @datadir@
|
|
||||||
datarootdir = @datarootdir@
|
|
||||||
docdir = @docdir@
|
|
||||||
dvidir = @dvidir@
|
|
||||||
exec_prefix = @exec_prefix@
|
|
||||||
host = @host@
|
|
||||||
host_alias = @host_alias@
|
|
||||||
host_cpu = @host_cpu@
|
|
||||||
host_os = @host_os@
|
|
||||||
host_vendor = @host_vendor@
|
|
||||||
htmldir = @htmldir@
|
|
||||||
includedir = @includedir@
|
|
||||||
infodir = @infodir@
|
|
||||||
install_sh = @install_sh@
|
|
||||||
libdir = @libdir@
|
|
||||||
libexecdir = @libexecdir@
|
|
||||||
localedir = @localedir@
|
|
||||||
localstatedir = @localstatedir@
|
|
||||||
mandir = @mandir@
|
|
||||||
mkdir_p = @mkdir_p@
|
|
||||||
oldincludedir = @oldincludedir@
|
|
||||||
pdfdir = @pdfdir@
|
|
||||||
prefix = @prefix@
|
|
||||||
program_transform_name = @program_transform_name@
|
|
||||||
psdir = @psdir@
|
|
||||||
runstatedir = @runstatedir@
|
|
||||||
sbindir = @sbindir@
|
|
||||||
sharedstatedir = @sharedstatedir@
|
|
||||||
srcdir = @srcdir@
|
|
||||||
sysconfdir = @sysconfdir@
|
|
||||||
target_alias = @target_alias@
|
|
||||||
top_build_prefix = @top_build_prefix@
|
|
||||||
top_builddir = @top_builddir@
|
|
||||||
top_srcdir = @top_srcdir@
|
|
||||||
langdir = $(datadir)/httrack/lang
|
|
||||||
# Glob against $(srcdir): a bare "*.txt" is resolved against the build dir and
|
|
||||||
# stays unexpanded (breaking "make") in an out-of-tree build.
|
|
||||||
lang_DATA = $(srcdir)/*.txt
|
|
||||||
langrootdir = $(datadir)/httrack
|
|
||||||
langroot_DATA = ../lang.def ../lang.indexes
|
|
||||||
EXTRA_DIST = $(lang_DATA) $(langroot_DATA)
|
|
||||||
all: all-am
|
|
||||||
|
|
||||||
.SUFFIXES:
|
|
||||||
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
|
|
||||||
@for dep in $?; do \
|
|
||||||
case '$(am__configure_deps)' in \
|
|
||||||
*$$dep*) \
|
|
||||||
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
|
|
||||||
&& { if test -f $@; then exit 0; else break; fi; }; \
|
|
||||||
exit 1;; \
|
|
||||||
esac; \
|
|
||||||
done; \
|
|
||||||
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lang/Makefile'; \
|
|
||||||
$(am__cd) $(top_srcdir) && \
|
|
||||||
$(AUTOMAKE) --gnu lang/Makefile
|
|
||||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
|
||||||
@case '$?' in \
|
|
||||||
*config.status*) \
|
|
||||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
|
|
||||||
*) \
|
|
||||||
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
|
|
||||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
|
|
||||||
esac;
|
|
||||||
|
|
||||||
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
|
||||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
|
||||||
|
|
||||||
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
|
|
||||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
|
||||||
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
|
|
||||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
|
||||||
$(am__aclocal_m4_deps):
|
|
||||||
|
|
||||||
mostlyclean-libtool:
|
|
||||||
-rm -f *.lo
|
|
||||||
|
|
||||||
clean-libtool:
|
|
||||||
-rm -rf .libs _libs
|
|
||||||
install-langDATA: $(lang_DATA)
|
|
||||||
@$(NORMAL_INSTALL)
|
|
||||||
@list='$(lang_DATA)'; test -n "$(langdir)" || list=; \
|
|
||||||
if test -n "$$list"; then \
|
|
||||||
echo " $(MKDIR_P) '$(DESTDIR)$(langdir)'"; \
|
|
||||||
$(MKDIR_P) "$(DESTDIR)$(langdir)" || exit 1; \
|
|
||||||
fi; \
|
|
||||||
for p in $$list; do \
|
|
||||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
|
||||||
echo "$$d$$p"; \
|
|
||||||
done | $(am__base_list) | \
|
|
||||||
while read files; do \
|
|
||||||
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(langdir)'"; \
|
|
||||||
$(INSTALL_DATA) $$files "$(DESTDIR)$(langdir)" || exit $$?; \
|
|
||||||
done
|
|
||||||
|
|
||||||
uninstall-langDATA:
|
|
||||||
@$(NORMAL_UNINSTALL)
|
|
||||||
@list='$(lang_DATA)'; test -n "$(langdir)" || list=; \
|
|
||||||
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
|
|
||||||
dir='$(DESTDIR)$(langdir)'; $(am__uninstall_files_from_dir)
|
|
||||||
install-langrootDATA: $(langroot_DATA)
|
|
||||||
@$(NORMAL_INSTALL)
|
|
||||||
@list='$(langroot_DATA)'; test -n "$(langrootdir)" || list=; \
|
|
||||||
if test -n "$$list"; then \
|
|
||||||
echo " $(MKDIR_P) '$(DESTDIR)$(langrootdir)'"; \
|
|
||||||
$(MKDIR_P) "$(DESTDIR)$(langrootdir)" || exit 1; \
|
|
||||||
fi; \
|
|
||||||
for p in $$list; do \
|
|
||||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
|
||||||
echo "$$d$$p"; \
|
|
||||||
done | $(am__base_list) | \
|
|
||||||
while read files; do \
|
|
||||||
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(langrootdir)'"; \
|
|
||||||
$(INSTALL_DATA) $$files "$(DESTDIR)$(langrootdir)" || exit $$?; \
|
|
||||||
done
|
|
||||||
|
|
||||||
uninstall-langrootDATA:
|
|
||||||
@$(NORMAL_UNINSTALL)
|
|
||||||
@list='$(langroot_DATA)'; test -n "$(langrootdir)" || list=; \
|
|
||||||
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
|
|
||||||
dir='$(DESTDIR)$(langrootdir)'; $(am__uninstall_files_from_dir)
|
|
||||||
tags TAGS:
|
|
||||||
|
|
||||||
ctags CTAGS:
|
|
||||||
|
|
||||||
cscope cscopelist:
|
|
||||||
|
|
||||||
distdir: $(BUILT_SOURCES)
|
|
||||||
$(MAKE) $(AM_MAKEFLAGS) distdir-am
|
|
||||||
|
|
||||||
distdir-am: $(DISTFILES)
|
|
||||||
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
|
||||||
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
|
||||||
list='$(DISTFILES)'; \
|
|
||||||
dist_files=`for file in $$list; do echo $$file; done | \
|
|
||||||
sed -e "s|^$$srcdirstrip/||;t" \
|
|
||||||
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
|
|
||||||
case $$dist_files in \
|
|
||||||
*/*) $(MKDIR_P) `echo "$$dist_files" | \
|
|
||||||
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
|
|
||||||
sort -u` ;; \
|
|
||||||
esac; \
|
|
||||||
for file in $$dist_files; do \
|
|
||||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
|
||||||
if test -d $$d/$$file; then \
|
|
||||||
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
|
|
||||||
if test -d "$(distdir)/$$file"; then \
|
|
||||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
|
||||||
fi; \
|
|
||||||
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
|
||||||
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
|
|
||||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
|
||||||
fi; \
|
|
||||||
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
|
|
||||||
else \
|
|
||||||
test -f "$(distdir)/$$file" \
|
|
||||||
|| cp -p $$d/$$file "$(distdir)/$$file" \
|
|
||||||
|| exit 1; \
|
|
||||||
fi; \
|
|
||||||
done
|
|
||||||
check-am: all-am
|
|
||||||
check: check-am
|
|
||||||
all-am: Makefile $(DATA)
|
|
||||||
installdirs:
|
|
||||||
for dir in "$(DESTDIR)$(langdir)" "$(DESTDIR)$(langrootdir)"; do \
|
|
||||||
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
|
|
||||||
done
|
|
||||||
install: install-am
|
|
||||||
install-exec: install-exec-am
|
|
||||||
install-data: install-data-am
|
|
||||||
uninstall: uninstall-am
|
|
||||||
|
|
||||||
install-am: all-am
|
|
||||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
|
||||||
|
|
||||||
installcheck: installcheck-am
|
|
||||||
install-strip:
|
|
||||||
if test -z '$(STRIP)'; then \
|
|
||||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
|
||||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
|
||||||
install; \
|
|
||||||
else \
|
|
||||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
|
||||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
|
||||||
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
|
|
||||||
fi
|
|
||||||
mostlyclean-generic:
|
|
||||||
|
|
||||||
clean-generic:
|
|
||||||
|
|
||||||
distclean-generic:
|
|
||||||
-$(am__rm_f) $(CONFIG_CLEAN_FILES)
|
|
||||||
-test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES)
|
|
||||||
|
|
||||||
maintainer-clean-generic:
|
|
||||||
@echo "This command is intended for maintainers to use"
|
|
||||||
@echo "it deletes files that may require special tools to rebuild."
|
|
||||||
clean: clean-am
|
|
||||||
|
|
||||||
clean-am: clean-generic clean-libtool mostlyclean-am
|
|
||||||
|
|
||||||
distclean: distclean-am
|
|
||||||
-rm -f Makefile
|
|
||||||
distclean-am: clean-am distclean-generic
|
|
||||||
|
|
||||||
dvi: dvi-am
|
|
||||||
|
|
||||||
dvi-am:
|
|
||||||
|
|
||||||
html: html-am
|
|
||||||
|
|
||||||
html-am:
|
|
||||||
|
|
||||||
info: info-am
|
|
||||||
|
|
||||||
info-am:
|
|
||||||
|
|
||||||
install-data-am: install-langDATA install-langrootDATA
|
|
||||||
|
|
||||||
install-dvi: install-dvi-am
|
|
||||||
|
|
||||||
install-dvi-am:
|
|
||||||
|
|
||||||
install-exec-am:
|
|
||||||
|
|
||||||
install-html: install-html-am
|
|
||||||
|
|
||||||
install-html-am:
|
|
||||||
|
|
||||||
install-info: install-info-am
|
|
||||||
|
|
||||||
install-info-am:
|
|
||||||
|
|
||||||
install-man:
|
|
||||||
|
|
||||||
install-pdf: install-pdf-am
|
|
||||||
|
|
||||||
install-pdf-am:
|
|
||||||
|
|
||||||
install-ps: install-ps-am
|
|
||||||
|
|
||||||
install-ps-am:
|
|
||||||
|
|
||||||
installcheck-am:
|
|
||||||
|
|
||||||
maintainer-clean: maintainer-clean-am
|
|
||||||
-rm -f Makefile
|
|
||||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
|
||||||
|
|
||||||
mostlyclean: mostlyclean-am
|
|
||||||
|
|
||||||
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
|
|
||||||
|
|
||||||
pdf: pdf-am
|
|
||||||
|
|
||||||
pdf-am:
|
|
||||||
|
|
||||||
ps: ps-am
|
|
||||||
|
|
||||||
ps-am:
|
|
||||||
|
|
||||||
uninstall-am: uninstall-langDATA uninstall-langrootDATA
|
|
||||||
|
|
||||||
.MAKE: install-am install-strip
|
|
||||||
|
|
||||||
.PHONY: all all-am check check-am clean clean-generic clean-libtool \
|
|
||||||
cscopelist-am ctags-am distclean distclean-generic \
|
|
||||||
distclean-libtool distdir dvi dvi-am html html-am info info-am \
|
|
||||||
install install-am install-data install-data-am install-dvi \
|
|
||||||
install-dvi-am install-exec install-exec-am install-html \
|
|
||||||
install-html-am install-info install-info-am install-langDATA \
|
|
||||||
install-langrootDATA install-man install-pdf install-pdf-am \
|
|
||||||
install-ps install-ps-am install-strip installcheck \
|
|
||||||
installcheck-am installdirs maintainer-clean \
|
|
||||||
maintainer-clean-generic mostlyclean mostlyclean-generic \
|
|
||||||
mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \
|
|
||||||
uninstall-am uninstall-langDATA uninstall-langrootDATA
|
|
||||||
|
|
||||||
.PRECIOUS: Makefile
|
|
||||||
|
|
||||||
|
|
||||||
#dist-hook:
|
|
||||||
|
|
||||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
|
||||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
|
||||||
.NOEXPORT:
|
|
||||||
|
|
||||||
# Tell GNU make to disable its built-in pattern rules.
|
|
||||||
%:: %,v
|
|
||||||
%:: RCS/%,v
|
|
||||||
%:: RCS/%
|
|
||||||
%:: s.%
|
|
||||||
%:: SCCS/s.%
|
|
||||||
@@ -1,908 +0,0 @@
|
|||||||
# Makefile.in generated by automake 1.17 from Makefile.am.
|
|
||||||
# @configure_input@
|
|
||||||
|
|
||||||
# Copyright (C) 1994-2024 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
# This Makefile.in is free software; the Free Software Foundation
|
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
|
||||||
# with or without modifications, as long as this notice is preserved.
|
|
||||||
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
|
||||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
|
||||||
# PARTICULAR PURPOSE.
|
|
||||||
|
|
||||||
@SET_MAKE@
|
|
||||||
|
|
||||||
|
|
||||||
VPATH = @srcdir@
|
|
||||||
am__is_gnu_make = { \
|
|
||||||
if test -z '$(MAKELEVEL)'; then \
|
|
||||||
false; \
|
|
||||||
elif test -n '$(MAKE_HOST)'; then \
|
|
||||||
true; \
|
|
||||||
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
|
|
||||||
true; \
|
|
||||||
else \
|
|
||||||
false; \
|
|
||||||
fi; \
|
|
||||||
}
|
|
||||||
am__make_running_with_option = \
|
|
||||||
case $${target_option-} in \
|
|
||||||
?) ;; \
|
|
||||||
*) echo "am__make_running_with_option: internal error: invalid" \
|
|
||||||
"target option '$${target_option-}' specified" >&2; \
|
|
||||||
exit 1;; \
|
|
||||||
esac; \
|
|
||||||
has_opt=no; \
|
|
||||||
sane_makeflags=$$MAKEFLAGS; \
|
|
||||||
if $(am__is_gnu_make); then \
|
|
||||||
sane_makeflags=$$MFLAGS; \
|
|
||||||
else \
|
|
||||||
case $$MAKEFLAGS in \
|
|
||||||
*\\[\ \ ]*) \
|
|
||||||
bs=\\; \
|
|
||||||
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
|
|
||||||
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
|
|
||||||
esac; \
|
|
||||||
fi; \
|
|
||||||
skip_next=no; \
|
|
||||||
strip_trailopt () \
|
|
||||||
{ \
|
|
||||||
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
|
|
||||||
}; \
|
|
||||||
for flg in $$sane_makeflags; do \
|
|
||||||
test $$skip_next = yes && { skip_next=no; continue; }; \
|
|
||||||
case $$flg in \
|
|
||||||
*=*|--*) continue;; \
|
|
||||||
-*I) strip_trailopt 'I'; skip_next=yes;; \
|
|
||||||
-*I?*) strip_trailopt 'I';; \
|
|
||||||
-*O) strip_trailopt 'O'; skip_next=yes;; \
|
|
||||||
-*O?*) strip_trailopt 'O';; \
|
|
||||||
-*l) strip_trailopt 'l'; skip_next=yes;; \
|
|
||||||
-*l?*) strip_trailopt 'l';; \
|
|
||||||
-[dEDm]) skip_next=yes;; \
|
|
||||||
-[JT]) skip_next=yes;; \
|
|
||||||
esac; \
|
|
||||||
case $$flg in \
|
|
||||||
*$$target_option*) has_opt=yes; break;; \
|
|
||||||
esac; \
|
|
||||||
done; \
|
|
||||||
test $$has_opt = yes
|
|
||||||
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
|
|
||||||
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
|
|
||||||
am__rm_f = rm -f $(am__rm_f_notfound)
|
|
||||||
am__rm_rf = rm -rf $(am__rm_f_notfound)
|
|
||||||
pkgdatadir = $(datadir)/@PACKAGE@
|
|
||||||
pkgincludedir = $(includedir)/@PACKAGE@
|
|
||||||
pkglibdir = $(libdir)/@PACKAGE@
|
|
||||||
pkglibexecdir = $(libexecdir)/@PACKAGE@
|
|
||||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
|
||||||
install_sh_DATA = $(install_sh) -c -m 644
|
|
||||||
install_sh_PROGRAM = $(install_sh) -c
|
|
||||||
install_sh_SCRIPT = $(install_sh) -c
|
|
||||||
INSTALL_HEADER = $(INSTALL_DATA)
|
|
||||||
transform = $(program_transform_name)
|
|
||||||
NORMAL_INSTALL = :
|
|
||||||
PRE_INSTALL = :
|
|
||||||
POST_INSTALL = :
|
|
||||||
NORMAL_UNINSTALL = :
|
|
||||||
PRE_UNINSTALL = :
|
|
||||||
POST_UNINSTALL = :
|
|
||||||
build_triplet = @build@
|
|
||||||
host_triplet = @host@
|
|
||||||
subdir = libtest
|
|
||||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
|
||||||
am__aclocal_m4_deps = $(top_srcdir)/m4/check_zlib.m4 \
|
|
||||||
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
|
|
||||||
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
|
|
||||||
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/snprintf.m4 \
|
|
||||||
$(top_srcdir)/m4/visibility.m4 $(top_srcdir)/configure.ac
|
|
||||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
|
||||||
$(ACLOCAL_M4)
|
|
||||||
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
|
|
||||||
mkinstalldirs = $(install_sh) -d
|
|
||||||
CONFIG_HEADER = $(top_builddir)/config.h
|
|
||||||
CONFIG_CLEAN_FILES =
|
|
||||||
CONFIG_CLEAN_VPATH_FILES =
|
|
||||||
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
|
|
||||||
am__vpath_adj = case $$p in \
|
|
||||||
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
|
|
||||||
*) f=$$p;; \
|
|
||||||
esac;
|
|
||||||
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
|
|
||||||
am__install_max = 40
|
|
||||||
am__nobase_strip_setup = \
|
|
||||||
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
|
|
||||||
am__nobase_strip = \
|
|
||||||
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
|
|
||||||
am__nobase_list = $(am__nobase_strip_setup); \
|
|
||||||
for p in $$list; do echo "$$p $$p"; done | \
|
|
||||||
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
|
|
||||||
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
|
|
||||||
if (++n[$$2] == $(am__install_max)) \
|
|
||||||
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
|
|
||||||
END { for (dir in files) print dir, files[dir] }'
|
|
||||||
am__base_list = \
|
|
||||||
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
|
|
||||||
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
|
|
||||||
am__uninstall_files_from_dir = { \
|
|
||||||
{ test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|
|
||||||
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
|
|
||||||
$(am__cd) "$$dir" && echo $$files | $(am__xargs_n) 40 $(am__rm_f); }; \
|
|
||||||
}
|
|
||||||
am__installdirs = "$(DESTDIR)$(pkglibdir)" "$(DESTDIR)$(exemplesdir)"
|
|
||||||
LTLIBRARIES = $(pkglib_LTLIBRARIES)
|
|
||||||
am__DEPENDENCIES_1 =
|
|
||||||
libbaselinks_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
|
|
||||||
$(am__DEPENDENCIES_1) $(top_builddir)/src/libhttrack.la
|
|
||||||
am_libbaselinks_la_OBJECTS = callbacks-example-baselinks.lo
|
|
||||||
libbaselinks_la_OBJECTS = $(am_libbaselinks_la_OBJECTS)
|
|
||||||
AM_V_lt = $(am__v_lt_@AM_V@)
|
|
||||||
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
|
|
||||||
am__v_lt_0 = --silent
|
|
||||||
am__v_lt_1 =
|
|
||||||
libbaselinks_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
|
|
||||||
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
|
|
||||||
$(AM_CFLAGS) $(CFLAGS) $(libbaselinks_la_LDFLAGS) $(LDFLAGS) \
|
|
||||||
-o $@
|
|
||||||
libchangecontent_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
|
|
||||||
$(am__DEPENDENCIES_1) $(top_builddir)/src/libhttrack.la
|
|
||||||
am_libchangecontent_la_OBJECTS = callbacks-example-changecontent.lo
|
|
||||||
libchangecontent_la_OBJECTS = $(am_libchangecontent_la_OBJECTS)
|
|
||||||
libchangecontent_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
|
|
||||||
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
|
|
||||||
$(AM_CFLAGS) $(CFLAGS) $(libchangecontent_la_LDFLAGS) \
|
|
||||||
$(LDFLAGS) -o $@
|
|
||||||
libcontentfilter_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
|
|
||||||
$(am__DEPENDENCIES_1) $(top_builddir)/src/libhttrack.la
|
|
||||||
am_libcontentfilter_la_OBJECTS = callbacks-example-contentfilter.lo
|
|
||||||
libcontentfilter_la_OBJECTS = $(am_libcontentfilter_la_OBJECTS)
|
|
||||||
libcontentfilter_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
|
|
||||||
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
|
|
||||||
$(AM_CFLAGS) $(CFLAGS) $(libcontentfilter_la_LDFLAGS) \
|
|
||||||
$(LDFLAGS) -o $@
|
|
||||||
libdisplayheader_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
|
|
||||||
$(am__DEPENDENCIES_1) $(top_builddir)/src/libhttrack.la
|
|
||||||
am_libdisplayheader_la_OBJECTS = callbacks-example-displayheader.lo
|
|
||||||
libdisplayheader_la_OBJECTS = $(am_libdisplayheader_la_OBJECTS)
|
|
||||||
libdisplayheader_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
|
|
||||||
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
|
|
||||||
$(AM_CFLAGS) $(CFLAGS) $(libdisplayheader_la_LDFLAGS) \
|
|
||||||
$(LDFLAGS) -o $@
|
|
||||||
libfilename_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
|
|
||||||
$(am__DEPENDENCIES_1) $(top_builddir)/src/libhttrack.la
|
|
||||||
am_libfilename_la_OBJECTS = callbacks-example-filename.lo
|
|
||||||
libfilename_la_OBJECTS = $(am_libfilename_la_OBJECTS)
|
|
||||||
libfilename_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
|
|
||||||
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
|
|
||||||
$(AM_CFLAGS) $(CFLAGS) $(libfilename_la_LDFLAGS) $(LDFLAGS) -o \
|
|
||||||
$@
|
|
||||||
libfilename2_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
|
|
||||||
$(am__DEPENDENCIES_1) $(top_builddir)/src/libhttrack.la
|
|
||||||
am_libfilename2_la_OBJECTS = callbacks-example-filename2.lo
|
|
||||||
libfilename2_la_OBJECTS = $(am_libfilename2_la_OBJECTS)
|
|
||||||
libfilename2_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
|
|
||||||
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
|
|
||||||
$(AM_CFLAGS) $(CFLAGS) $(libfilename2_la_LDFLAGS) $(LDFLAGS) \
|
|
||||||
-o $@
|
|
||||||
libfilenameiisbug_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
|
|
||||||
$(am__DEPENDENCIES_1) $(top_builddir)/src/libhttrack.la
|
|
||||||
am_libfilenameiisbug_la_OBJECTS = callbacks-example-filenameiisbug.lo
|
|
||||||
libfilenameiisbug_la_OBJECTS = $(am_libfilenameiisbug_la_OBJECTS)
|
|
||||||
libfilenameiisbug_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
|
|
||||||
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
|
|
||||||
$(AM_CFLAGS) $(CFLAGS) $(libfilenameiisbug_la_LDFLAGS) \
|
|
||||||
$(LDFLAGS) -o $@
|
|
||||||
liblistlinks_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
|
|
||||||
$(am__DEPENDENCIES_1) $(top_builddir)/src/libhttrack.la
|
|
||||||
am_liblistlinks_la_OBJECTS = callbacks-example-listlinks.lo
|
|
||||||
liblistlinks_la_OBJECTS = $(am_liblistlinks_la_OBJECTS)
|
|
||||||
liblistlinks_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
|
|
||||||
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
|
|
||||||
$(AM_CFLAGS) $(CFLAGS) $(liblistlinks_la_LDFLAGS) $(LDFLAGS) \
|
|
||||||
-o $@
|
|
||||||
liblog_la_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
|
|
||||||
$(top_builddir)/src/libhttrack.la
|
|
||||||
am_liblog_la_OBJECTS = callbacks-example-log.lo
|
|
||||||
liblog_la_OBJECTS = $(am_liblog_la_OBJECTS)
|
|
||||||
liblog_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
|
|
||||||
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
|
|
||||||
$(liblog_la_LDFLAGS) $(LDFLAGS) -o $@
|
|
||||||
libsimple_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
|
|
||||||
$(am__DEPENDENCIES_1) $(top_builddir)/src/libhttrack.la
|
|
||||||
am_libsimple_la_OBJECTS = callbacks-example-simple.lo
|
|
||||||
libsimple_la_OBJECTS = $(am_libsimple_la_OBJECTS)
|
|
||||||
libsimple_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
|
|
||||||
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
|
|
||||||
$(libsimple_la_LDFLAGS) $(LDFLAGS) -o $@
|
|
||||||
AM_V_P = $(am__v_P_@AM_V@)
|
|
||||||
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
|
|
||||||
am__v_P_0 = false
|
|
||||||
am__v_P_1 = :
|
|
||||||
AM_V_GEN = $(am__v_GEN_@AM_V@)
|
|
||||||
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
|
|
||||||
am__v_GEN_0 = @echo " GEN " $@;
|
|
||||||
am__v_GEN_1 =
|
|
||||||
AM_V_at = $(am__v_at_@AM_V@)
|
|
||||||
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
|
|
||||||
am__v_at_0 = @
|
|
||||||
am__v_at_1 =
|
|
||||||
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
|
|
||||||
depcomp = $(SHELL) $(top_srcdir)/depcomp
|
|
||||||
am__maybe_remake_depfiles = depfiles
|
|
||||||
am__depfiles_remade = ./$(DEPDIR)/callbacks-example-baselinks.Plo \
|
|
||||||
./$(DEPDIR)/callbacks-example-changecontent.Plo \
|
|
||||||
./$(DEPDIR)/callbacks-example-contentfilter.Plo \
|
|
||||||
./$(DEPDIR)/callbacks-example-displayheader.Plo \
|
|
||||||
./$(DEPDIR)/callbacks-example-filename.Plo \
|
|
||||||
./$(DEPDIR)/callbacks-example-filename2.Plo \
|
|
||||||
./$(DEPDIR)/callbacks-example-filenameiisbug.Plo \
|
|
||||||
./$(DEPDIR)/callbacks-example-listlinks.Plo \
|
|
||||||
./$(DEPDIR)/callbacks-example-log.Plo \
|
|
||||||
./$(DEPDIR)/callbacks-example-simple.Plo
|
|
||||||
am__mv = mv -f
|
|
||||||
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
|
|
||||||
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
|
||||||
LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
|
|
||||||
$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
|
|
||||||
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
|
|
||||||
$(AM_CFLAGS) $(CFLAGS)
|
|
||||||
AM_V_CC = $(am__v_CC_@AM_V@)
|
|
||||||
am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
|
|
||||||
am__v_CC_0 = @echo " CC " $@;
|
|
||||||
am__v_CC_1 =
|
|
||||||
CCLD = $(CC)
|
|
||||||
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
|
|
||||||
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
|
|
||||||
$(AM_LDFLAGS) $(LDFLAGS) -o $@
|
|
||||||
AM_V_CCLD = $(am__v_CCLD_@AM_V@)
|
|
||||||
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
|
|
||||||
am__v_CCLD_0 = @echo " CCLD " $@;
|
|
||||||
am__v_CCLD_1 =
|
|
||||||
SOURCES = $(libbaselinks_la_SOURCES) $(libchangecontent_la_SOURCES) \
|
|
||||||
$(libcontentfilter_la_SOURCES) $(libdisplayheader_la_SOURCES) \
|
|
||||||
$(libfilename_la_SOURCES) $(libfilename2_la_SOURCES) \
|
|
||||||
$(libfilenameiisbug_la_SOURCES) $(liblistlinks_la_SOURCES) \
|
|
||||||
$(liblog_la_SOURCES) $(libsimple_la_SOURCES)
|
|
||||||
DIST_SOURCES = $(libbaselinks_la_SOURCES) \
|
|
||||||
$(libchangecontent_la_SOURCES) $(libcontentfilter_la_SOURCES) \
|
|
||||||
$(libdisplayheader_la_SOURCES) $(libfilename_la_SOURCES) \
|
|
||||||
$(libfilename2_la_SOURCES) $(libfilenameiisbug_la_SOURCES) \
|
|
||||||
$(liblistlinks_la_SOURCES) $(liblog_la_SOURCES) \
|
|
||||||
$(libsimple_la_SOURCES)
|
|
||||||
am__can_run_installinfo = \
|
|
||||||
case $$AM_UPDATE_INFO_DIR in \
|
|
||||||
n|no|NO) false;; \
|
|
||||||
*) (install-info --version) >/dev/null 2>&1;; \
|
|
||||||
esac
|
|
||||||
DATA = $(exemples_DATA)
|
|
||||||
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
|
|
||||||
# Read a list of newline-separated strings from the standard input,
|
|
||||||
# and print each of them once, without duplicates. Input order is
|
|
||||||
# *not* preserved.
|
|
||||||
am__uniquify_input = $(AWK) '\
|
|
||||||
BEGIN { nonempty = 0; } \
|
|
||||||
{ items[$$0] = 1; nonempty = 1; } \
|
|
||||||
END { if (nonempty) { for (i in items) print i; }; } \
|
|
||||||
'
|
|
||||||
# Make sure the list of sources is unique. This is necessary because,
|
|
||||||
# e.g., the same source file might be shared among _SOURCES variables
|
|
||||||
# for different programs/libraries.
|
|
||||||
am__define_uniq_tagged_files = \
|
|
||||||
list='$(am__tagged_files)'; \
|
|
||||||
unique=`for i in $$list; do \
|
|
||||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
|
||||||
done | $(am__uniquify_input)`
|
|
||||||
am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
|
|
||||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
|
||||||
ACLOCAL = @ACLOCAL@
|
|
||||||
AMTAR = @AMTAR@
|
|
||||||
AM_CFLAGS = @AM_CFLAGS@
|
|
||||||
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
|
|
||||||
AR = @AR@
|
|
||||||
AUTOCONF = @AUTOCONF@
|
|
||||||
AUTOHEADER = @AUTOHEADER@
|
|
||||||
AUTOMAKE = @AUTOMAKE@
|
|
||||||
AWK = @AWK@
|
|
||||||
BASH = @BASH@
|
|
||||||
CC = @CC@
|
|
||||||
CCDEPMODE = @CCDEPMODE@
|
|
||||||
CFLAGS = @CFLAGS@
|
|
||||||
CFLAGS_PIE = @CFLAGS_PIE@
|
|
||||||
CFLAG_VISIBILITY = @CFLAG_VISIBILITY@
|
|
||||||
CPPFLAGS = @CPPFLAGS@
|
|
||||||
CSCOPE = @CSCOPE@
|
|
||||||
CTAGS = @CTAGS@
|
|
||||||
CYGPATH_W = @CYGPATH_W@
|
|
||||||
DEFAULT_CFLAGS = @DEFAULT_CFLAGS@
|
|
||||||
DEFAULT_LDFLAGS = @DEFAULT_LDFLAGS@
|
|
||||||
DEFS = @DEFS@
|
|
||||||
DEPDIR = @DEPDIR@
|
|
||||||
DLLTOOL = @DLLTOOL@
|
|
||||||
DL_LIBS = @DL_LIBS@
|
|
||||||
DSYMUTIL = @DSYMUTIL@
|
|
||||||
DUMPBIN = @DUMPBIN@
|
|
||||||
ECHO_C = @ECHO_C@
|
|
||||||
ECHO_N = @ECHO_N@
|
|
||||||
ECHO_T = @ECHO_T@
|
|
||||||
EGREP = @EGREP@
|
|
||||||
ETAGS = @ETAGS@
|
|
||||||
EXEEXT = @EXEEXT@
|
|
||||||
FGREP = @FGREP@
|
|
||||||
FILECMD = @FILECMD@
|
|
||||||
GREP = @GREP@
|
|
||||||
HAVE_VISIBILITY = @HAVE_VISIBILITY@
|
|
||||||
HTTPS_SUPPORT = @HTTPS_SUPPORT@
|
|
||||||
ICONV_LIBS = @ICONV_LIBS@
|
|
||||||
INSTALL = @INSTALL@
|
|
||||||
INSTALL_DATA = @INSTALL_DATA@
|
|
||||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
|
||||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
|
||||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
|
||||||
LD = @LD@
|
|
||||||
LDFLAGS = @LDFLAGS@
|
|
||||||
LDFLAGS_PIE = @LDFLAGS_PIE@
|
|
||||||
LFS_FLAG = @LFS_FLAG@
|
|
||||||
LIBC_FORCE_LINK = @LIBC_FORCE_LINK@
|
|
||||||
LIBOBJS = @LIBOBJS@
|
|
||||||
LIBS = @LIBS@
|
|
||||||
LIBTOOL = @LIBTOOL@
|
|
||||||
LIPO = @LIPO@
|
|
||||||
LN_S = @LN_S@
|
|
||||||
LTLIBOBJS = @LTLIBOBJS@
|
|
||||||
LT_CV_OBJDIR = @LT_CV_OBJDIR@
|
|
||||||
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
|
|
||||||
MAINT = @MAINT@
|
|
||||||
MAKEINFO = @MAKEINFO@
|
|
||||||
MANIFEST_TOOL = @MANIFEST_TOOL@
|
|
||||||
MKDIR_P = @MKDIR_P@
|
|
||||||
NM = @NM@
|
|
||||||
NMEDIT = @NMEDIT@
|
|
||||||
OBJDUMP = @OBJDUMP@
|
|
||||||
OBJEXT = @OBJEXT@
|
|
||||||
ONLINE_UNIT_TESTS = @ONLINE_UNIT_TESTS@
|
|
||||||
OPENSSL_LIBS = @OPENSSL_LIBS@
|
|
||||||
OTOOL = @OTOOL@
|
|
||||||
OTOOL64 = @OTOOL64@
|
|
||||||
PACKAGE = @PACKAGE@
|
|
||||||
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
|
||||||
PACKAGE_NAME = @PACKAGE_NAME@
|
|
||||||
PACKAGE_STRING = @PACKAGE_STRING@
|
|
||||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
|
||||||
PACKAGE_URL = @PACKAGE_URL@
|
|
||||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
|
||||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
|
||||||
RANLIB = @RANLIB@
|
|
||||||
SED = @SED@
|
|
||||||
SET_MAKE = @SET_MAKE@
|
|
||||||
SHELL = @SHELL@
|
|
||||||
SHLIBPATH_VAR = @SHLIBPATH_VAR@
|
|
||||||
SOCKET_LIBS = @SOCKET_LIBS@
|
|
||||||
STRIP = @STRIP@
|
|
||||||
THREADS_CFLAGS = @THREADS_CFLAGS@
|
|
||||||
THREADS_LIBS = @THREADS_LIBS@
|
|
||||||
V6_FLAG = @V6_FLAG@
|
|
||||||
VERSION = @VERSION@
|
|
||||||
VERSION_INFO = @VERSION_INFO@
|
|
||||||
abs_builddir = @abs_builddir@
|
|
||||||
abs_srcdir = @abs_srcdir@
|
|
||||||
abs_top_builddir = @abs_top_builddir@
|
|
||||||
abs_top_srcdir = @abs_top_srcdir@
|
|
||||||
ac_ct_AR = @ac_ct_AR@
|
|
||||||
ac_ct_CC = @ac_ct_CC@
|
|
||||||
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
|
|
||||||
am__include = @am__include@
|
|
||||||
am__leading_dot = @am__leading_dot@
|
|
||||||
am__quote = @am__quote@
|
|
||||||
am__rm_f_notfound = @am__rm_f_notfound@
|
|
||||||
am__tar = @am__tar@
|
|
||||||
am__untar = @am__untar@
|
|
||||||
am__xargs_n = @am__xargs_n@
|
|
||||||
bindir = @bindir@
|
|
||||||
build = @build@
|
|
||||||
build_alias = @build_alias@
|
|
||||||
build_cpu = @build_cpu@
|
|
||||||
build_os = @build_os@
|
|
||||||
build_vendor = @build_vendor@
|
|
||||||
builddir = @builddir@
|
|
||||||
datadir = @datadir@
|
|
||||||
datarootdir = @datarootdir@
|
|
||||||
docdir = @docdir@
|
|
||||||
dvidir = @dvidir@
|
|
||||||
exec_prefix = @exec_prefix@
|
|
||||||
host = @host@
|
|
||||||
host_alias = @host_alias@
|
|
||||||
host_cpu = @host_cpu@
|
|
||||||
host_os = @host_os@
|
|
||||||
host_vendor = @host_vendor@
|
|
||||||
htmldir = @htmldir@
|
|
||||||
includedir = @includedir@
|
|
||||||
infodir = @infodir@
|
|
||||||
install_sh = @install_sh@
|
|
||||||
libdir = @libdir@
|
|
||||||
libexecdir = @libexecdir@
|
|
||||||
localedir = @localedir@
|
|
||||||
localstatedir = @localstatedir@
|
|
||||||
mandir = @mandir@
|
|
||||||
mkdir_p = @mkdir_p@
|
|
||||||
oldincludedir = @oldincludedir@
|
|
||||||
pdfdir = @pdfdir@
|
|
||||||
prefix = @prefix@
|
|
||||||
program_transform_name = @program_transform_name@
|
|
||||||
psdir = @psdir@
|
|
||||||
runstatedir = @runstatedir@
|
|
||||||
sbindir = @sbindir@
|
|
||||||
sharedstatedir = @sharedstatedir@
|
|
||||||
srcdir = @srcdir@
|
|
||||||
sysconfdir = @sysconfdir@
|
|
||||||
target_alias = @target_alias@
|
|
||||||
top_build_prefix = @top_build_prefix@
|
|
||||||
top_builddir = @top_builddir@
|
|
||||||
top_srcdir = @top_srcdir@
|
|
||||||
exemplesdir = $(datadir)/httrack/libtest
|
|
||||||
# Glob against $(srcdir), not the build dir: a bare "*.c" is resolved relative to
|
|
||||||
# the build dir and stays unexpanded (breaking "make") in an out-of-tree build.
|
|
||||||
exemples_DATA = $(srcdir)/*.c $(srcdir)/*.h $(srcdir)/*.txt
|
|
||||||
EXTRA_DIST = $(exemples_DATA) libtest.mak libtest.vcproj
|
|
||||||
# Use $(top_srcdir)/src, not ../src: the latter is relative to the build dir and
|
|
||||||
# misses the source headers (e.g. httrack-library.h) in an out-of-tree build.
|
|
||||||
AM_CPPFLAGS = @DEFAULT_CFLAGS@ @THREADS_CFLAGS@ @V6_FLAG@ @LFS_FLAG@ \
|
|
||||||
-DPREFIX=\""$(prefix)"\" -DSYSCONFDIR=\""$(sysconfdir)"\" \
|
|
||||||
-DDATADIR=\""$(datadir)"\" -DLIBDIR=\""$(libdir)"\" \
|
|
||||||
-I$(top_srcdir)/src
|
|
||||||
|
|
||||||
# The callback examples reference libc only through libhttrack, so the direct
|
|
||||||
# libc edge gets dropped from DT_NEEDED (library-not-linked-against-libc).
|
|
||||||
# Force libc back; configure gates the flag since only a GNU-style linker
|
|
||||||
# accepts it (LIBC_FORCE_LINK is empty on e.g. macOS).
|
|
||||||
AM_LDFLAGS = \
|
|
||||||
@DEFAULT_LDFLAGS@ \
|
|
||||||
-L../src \
|
|
||||||
@LIBC_FORCE_LINK@
|
|
||||||
|
|
||||||
|
|
||||||
# Examples
|
|
||||||
libbaselinks_la_SOURCES = callbacks-example-baselinks.c
|
|
||||||
libbaselinks_la_LIBADD = $(THREADS_LIBS) $(SOCKET_LIBS) $(top_builddir)/src/libhttrack.la
|
|
||||||
libbaselinks_la_LDFLAGS = $(AM_LDFLAGS) -version-info 1:0:0
|
|
||||||
libchangecontent_la_SOURCES = callbacks-example-changecontent.c
|
|
||||||
libchangecontent_la_LIBADD = $(THREADS_LIBS) $(SOCKET_LIBS) $(top_builddir)/src/libhttrack.la
|
|
||||||
libchangecontent_la_LDFLAGS = $(AM_LDFLAGS) -version-info 1:0:0
|
|
||||||
libcontentfilter_la_SOURCES = callbacks-example-contentfilter.c
|
|
||||||
libcontentfilter_la_LIBADD = $(THREADS_LIBS) $(SOCKET_LIBS) $(top_builddir)/src/libhttrack.la
|
|
||||||
libcontentfilter_la_LDFLAGS = $(AM_LDFLAGS) -version-info 1:0:0
|
|
||||||
libdisplayheader_la_SOURCES = callbacks-example-displayheader.c
|
|
||||||
libdisplayheader_la_LIBADD = $(THREADS_LIBS) $(SOCKET_LIBS) $(top_builddir)/src/libhttrack.la
|
|
||||||
libdisplayheader_la_LDFLAGS = $(AM_LDFLAGS) -version-info 1:0:0
|
|
||||||
libfilename2_la_SOURCES = callbacks-example-filename2.c
|
|
||||||
libfilename2_la_LIBADD = $(THREADS_LIBS) $(SOCKET_LIBS) $(top_builddir)/src/libhttrack.la
|
|
||||||
libfilename2_la_LDFLAGS = $(AM_LDFLAGS) -version-info 1:0:0
|
|
||||||
libfilename_la_SOURCES = callbacks-example-filename.c
|
|
||||||
libfilename_la_LIBADD = $(THREADS_LIBS) $(SOCKET_LIBS) $(top_builddir)/src/libhttrack.la
|
|
||||||
libfilename_la_LDFLAGS = $(AM_LDFLAGS) -version-info 1:0:0
|
|
||||||
libfilenameiisbug_la_SOURCES = callbacks-example-filenameiisbug.c
|
|
||||||
libfilenameiisbug_la_LIBADD = $(THREADS_LIBS) $(SOCKET_LIBS) $(top_builddir)/src/libhttrack.la
|
|
||||||
libfilenameiisbug_la_LDFLAGS = $(AM_LDFLAGS) -version-info 1:0:0
|
|
||||||
liblistlinks_la_SOURCES = callbacks-example-listlinks.c
|
|
||||||
liblistlinks_la_LIBADD = $(THREADS_LIBS) $(SOCKET_LIBS) $(top_builddir)/src/libhttrack.la
|
|
||||||
liblistlinks_la_LDFLAGS = $(AM_LDFLAGS) -version-info 1:0:0
|
|
||||||
liblog_la_SOURCES = callbacks-example-log.c
|
|
||||||
liblog_la_LIBADD = $(THREADS_LIBS) $(SOCKET_LIBS) $(top_builddir)/src/libhttrack.la
|
|
||||||
liblog_la_LDFLAGS = $(AM_LDFLAGS) -version-info 1:0:0
|
|
||||||
libsimple_la_SOURCES = callbacks-example-simple.c
|
|
||||||
libsimple_la_LIBADD = $(THREADS_LIBS) $(SOCKET_LIBS) $(top_builddir)/src/libhttrack.la
|
|
||||||
libsimple_la_LDFLAGS = $(AM_LDFLAGS) -version-info 1:0:0
|
|
||||||
pkglib_LTLIBRARIES = libbaselinks.la libchangecontent.la libcontentfilter.la libdisplayheader.la libfilename2.la libfilename.la libfilenameiisbug.la liblistlinks.la liblog.la libsimple.la
|
|
||||||
all: all-am
|
|
||||||
|
|
||||||
.SUFFIXES:
|
|
||||||
.SUFFIXES: .c .lo .o .obj
|
|
||||||
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
|
|
||||||
@for dep in $?; do \
|
|
||||||
case '$(am__configure_deps)' in \
|
|
||||||
*$$dep*) \
|
|
||||||
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
|
|
||||||
&& { if test -f $@; then exit 0; else break; fi; }; \
|
|
||||||
exit 1;; \
|
|
||||||
esac; \
|
|
||||||
done; \
|
|
||||||
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu libtest/Makefile'; \
|
|
||||||
$(am__cd) $(top_srcdir) && \
|
|
||||||
$(AUTOMAKE) --gnu libtest/Makefile
|
|
||||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
|
||||||
@case '$?' in \
|
|
||||||
*config.status*) \
|
|
||||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
|
|
||||||
*) \
|
|
||||||
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
|
|
||||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
|
|
||||||
esac;
|
|
||||||
|
|
||||||
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
|
||||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
|
||||||
|
|
||||||
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
|
|
||||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
|
||||||
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
|
|
||||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
|
||||||
$(am__aclocal_m4_deps):
|
|
||||||
|
|
||||||
install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES)
|
|
||||||
@$(NORMAL_INSTALL)
|
|
||||||
@list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \
|
|
||||||
list2=; for p in $$list; do \
|
|
||||||
if test -f $$p; then \
|
|
||||||
list2="$$list2 $$p"; \
|
|
||||||
else :; fi; \
|
|
||||||
done; \
|
|
||||||
test -z "$$list2" || { \
|
|
||||||
echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \
|
|
||||||
$(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \
|
|
||||||
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \
|
|
||||||
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \
|
|
||||||
}
|
|
||||||
|
|
||||||
uninstall-pkglibLTLIBRARIES:
|
|
||||||
@$(NORMAL_UNINSTALL)
|
|
||||||
@list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \
|
|
||||||
for p in $$list; do \
|
|
||||||
$(am__strip_dir) \
|
|
||||||
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \
|
|
||||||
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \
|
|
||||||
done
|
|
||||||
|
|
||||||
clean-pkglibLTLIBRARIES:
|
|
||||||
-$(am__rm_f) $(pkglib_LTLIBRARIES)
|
|
||||||
@list='$(pkglib_LTLIBRARIES)'; \
|
|
||||||
locs=`for p in $$list; do echo $$p; done | \
|
|
||||||
sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
|
|
||||||
sort -u`; \
|
|
||||||
echo rm -f $${locs}; \
|
|
||||||
$(am__rm_f) $${locs}
|
|
||||||
|
|
||||||
libbaselinks.la: $(libbaselinks_la_OBJECTS) $(libbaselinks_la_DEPENDENCIES) $(EXTRA_libbaselinks_la_DEPENDENCIES)
|
|
||||||
$(AM_V_CCLD)$(libbaselinks_la_LINK) -rpath $(pkglibdir) $(libbaselinks_la_OBJECTS) $(libbaselinks_la_LIBADD) $(LIBS)
|
|
||||||
|
|
||||||
libchangecontent.la: $(libchangecontent_la_OBJECTS) $(libchangecontent_la_DEPENDENCIES) $(EXTRA_libchangecontent_la_DEPENDENCIES)
|
|
||||||
$(AM_V_CCLD)$(libchangecontent_la_LINK) -rpath $(pkglibdir) $(libchangecontent_la_OBJECTS) $(libchangecontent_la_LIBADD) $(LIBS)
|
|
||||||
|
|
||||||
libcontentfilter.la: $(libcontentfilter_la_OBJECTS) $(libcontentfilter_la_DEPENDENCIES) $(EXTRA_libcontentfilter_la_DEPENDENCIES)
|
|
||||||
$(AM_V_CCLD)$(libcontentfilter_la_LINK) -rpath $(pkglibdir) $(libcontentfilter_la_OBJECTS) $(libcontentfilter_la_LIBADD) $(LIBS)
|
|
||||||
|
|
||||||
libdisplayheader.la: $(libdisplayheader_la_OBJECTS) $(libdisplayheader_la_DEPENDENCIES) $(EXTRA_libdisplayheader_la_DEPENDENCIES)
|
|
||||||
$(AM_V_CCLD)$(libdisplayheader_la_LINK) -rpath $(pkglibdir) $(libdisplayheader_la_OBJECTS) $(libdisplayheader_la_LIBADD) $(LIBS)
|
|
||||||
|
|
||||||
libfilename.la: $(libfilename_la_OBJECTS) $(libfilename_la_DEPENDENCIES) $(EXTRA_libfilename_la_DEPENDENCIES)
|
|
||||||
$(AM_V_CCLD)$(libfilename_la_LINK) -rpath $(pkglibdir) $(libfilename_la_OBJECTS) $(libfilename_la_LIBADD) $(LIBS)
|
|
||||||
|
|
||||||
libfilename2.la: $(libfilename2_la_OBJECTS) $(libfilename2_la_DEPENDENCIES) $(EXTRA_libfilename2_la_DEPENDENCIES)
|
|
||||||
$(AM_V_CCLD)$(libfilename2_la_LINK) -rpath $(pkglibdir) $(libfilename2_la_OBJECTS) $(libfilename2_la_LIBADD) $(LIBS)
|
|
||||||
|
|
||||||
libfilenameiisbug.la: $(libfilenameiisbug_la_OBJECTS) $(libfilenameiisbug_la_DEPENDENCIES) $(EXTRA_libfilenameiisbug_la_DEPENDENCIES)
|
|
||||||
$(AM_V_CCLD)$(libfilenameiisbug_la_LINK) -rpath $(pkglibdir) $(libfilenameiisbug_la_OBJECTS) $(libfilenameiisbug_la_LIBADD) $(LIBS)
|
|
||||||
|
|
||||||
liblistlinks.la: $(liblistlinks_la_OBJECTS) $(liblistlinks_la_DEPENDENCIES) $(EXTRA_liblistlinks_la_DEPENDENCIES)
|
|
||||||
$(AM_V_CCLD)$(liblistlinks_la_LINK) -rpath $(pkglibdir) $(liblistlinks_la_OBJECTS) $(liblistlinks_la_LIBADD) $(LIBS)
|
|
||||||
|
|
||||||
liblog.la: $(liblog_la_OBJECTS) $(liblog_la_DEPENDENCIES) $(EXTRA_liblog_la_DEPENDENCIES)
|
|
||||||
$(AM_V_CCLD)$(liblog_la_LINK) -rpath $(pkglibdir) $(liblog_la_OBJECTS) $(liblog_la_LIBADD) $(LIBS)
|
|
||||||
|
|
||||||
libsimple.la: $(libsimple_la_OBJECTS) $(libsimple_la_DEPENDENCIES) $(EXTRA_libsimple_la_DEPENDENCIES)
|
|
||||||
$(AM_V_CCLD)$(libsimple_la_LINK) -rpath $(pkglibdir) $(libsimple_la_OBJECTS) $(libsimple_la_LIBADD) $(LIBS)
|
|
||||||
|
|
||||||
mostlyclean-compile:
|
|
||||||
-rm -f *.$(OBJEXT)
|
|
||||||
|
|
||||||
distclean-compile:
|
|
||||||
-rm -f *.tab.c
|
|
||||||
|
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/callbacks-example-baselinks.Plo@am__quote@ # am--include-marker
|
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/callbacks-example-changecontent.Plo@am__quote@ # am--include-marker
|
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/callbacks-example-contentfilter.Plo@am__quote@ # am--include-marker
|
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/callbacks-example-displayheader.Plo@am__quote@ # am--include-marker
|
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/callbacks-example-filename.Plo@am__quote@ # am--include-marker
|
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/callbacks-example-filename2.Plo@am__quote@ # am--include-marker
|
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/callbacks-example-filenameiisbug.Plo@am__quote@ # am--include-marker
|
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/callbacks-example-listlinks.Plo@am__quote@ # am--include-marker
|
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/callbacks-example-log.Plo@am__quote@ # am--include-marker
|
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/callbacks-example-simple.Plo@am__quote@ # am--include-marker
|
|
||||||
|
|
||||||
$(am__depfiles_remade):
|
|
||||||
@$(MKDIR_P) $(@D)
|
|
||||||
@: >>$@
|
|
||||||
|
|
||||||
am--depfiles: $(am__depfiles_remade)
|
|
||||||
|
|
||||||
.c.o:
|
|
||||||
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
|
|
||||||
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
|
|
||||||
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
|
|
||||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
|
||||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
|
||||||
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
|
|
||||||
|
|
||||||
.c.obj:
|
|
||||||
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
|
|
||||||
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
|
|
||||||
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
|
|
||||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
|
||||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
|
||||||
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
|
|
||||||
|
|
||||||
.c.lo:
|
|
||||||
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
|
|
||||||
@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
|
|
||||||
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
|
|
||||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
|
|
||||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
|
||||||
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
|
|
||||||
|
|
||||||
mostlyclean-libtool:
|
|
||||||
-rm -f *.lo
|
|
||||||
|
|
||||||
clean-libtool:
|
|
||||||
-rm -rf .libs _libs
|
|
||||||
install-exemplesDATA: $(exemples_DATA)
|
|
||||||
@$(NORMAL_INSTALL)
|
|
||||||
@list='$(exemples_DATA)'; test -n "$(exemplesdir)" || list=; \
|
|
||||||
if test -n "$$list"; then \
|
|
||||||
echo " $(MKDIR_P) '$(DESTDIR)$(exemplesdir)'"; \
|
|
||||||
$(MKDIR_P) "$(DESTDIR)$(exemplesdir)" || exit 1; \
|
|
||||||
fi; \
|
|
||||||
for p in $$list; do \
|
|
||||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
|
||||||
echo "$$d$$p"; \
|
|
||||||
done | $(am__base_list) | \
|
|
||||||
while read files; do \
|
|
||||||
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(exemplesdir)'"; \
|
|
||||||
$(INSTALL_DATA) $$files "$(DESTDIR)$(exemplesdir)" || exit $$?; \
|
|
||||||
done
|
|
||||||
|
|
||||||
uninstall-exemplesDATA:
|
|
||||||
@$(NORMAL_UNINSTALL)
|
|
||||||
@list='$(exemples_DATA)'; test -n "$(exemplesdir)" || list=; \
|
|
||||||
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
|
|
||||||
dir='$(DESTDIR)$(exemplesdir)'; $(am__uninstall_files_from_dir)
|
|
||||||
|
|
||||||
ID: $(am__tagged_files)
|
|
||||||
$(am__define_uniq_tagged_files); mkid -fID $$unique
|
|
||||||
tags: tags-am
|
|
||||||
TAGS: tags
|
|
||||||
|
|
||||||
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
|
|
||||||
set x; \
|
|
||||||
here=`pwd`; \
|
|
||||||
$(am__define_uniq_tagged_files); \
|
|
||||||
shift; \
|
|
||||||
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
|
|
||||||
test -n "$$unique" || unique=$$empty_fix; \
|
|
||||||
if test $$# -gt 0; then \
|
|
||||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
|
||||||
"$$@" $$unique; \
|
|
||||||
else \
|
|
||||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
|
||||||
$$unique; \
|
|
||||||
fi; \
|
|
||||||
fi
|
|
||||||
ctags: ctags-am
|
|
||||||
|
|
||||||
CTAGS: ctags
|
|
||||||
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
|
|
||||||
$(am__define_uniq_tagged_files); \
|
|
||||||
test -z "$(CTAGS_ARGS)$$unique" \
|
|
||||||
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
|
|
||||||
$$unique
|
|
||||||
|
|
||||||
GTAGS:
|
|
||||||
here=`$(am__cd) $(top_builddir) && pwd` \
|
|
||||||
&& $(am__cd) $(top_srcdir) \
|
|
||||||
&& gtags -i $(GTAGS_ARGS) "$$here"
|
|
||||||
cscopelist: cscopelist-am
|
|
||||||
|
|
||||||
cscopelist-am: $(am__tagged_files)
|
|
||||||
list='$(am__tagged_files)'; \
|
|
||||||
case "$(srcdir)" in \
|
|
||||||
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
|
|
||||||
*) sdir=$(subdir)/$(srcdir) ;; \
|
|
||||||
esac; \
|
|
||||||
for i in $$list; do \
|
|
||||||
if test -f "$$i"; then \
|
|
||||||
echo "$(subdir)/$$i"; \
|
|
||||||
else \
|
|
||||||
echo "$$sdir/$$i"; \
|
|
||||||
fi; \
|
|
||||||
done >> $(top_builddir)/cscope.files
|
|
||||||
|
|
||||||
distclean-tags:
|
|
||||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
|
||||||
distdir: $(BUILT_SOURCES)
|
|
||||||
$(MAKE) $(AM_MAKEFLAGS) distdir-am
|
|
||||||
|
|
||||||
distdir-am: $(DISTFILES)
|
|
||||||
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
|
||||||
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
|
||||||
list='$(DISTFILES)'; \
|
|
||||||
dist_files=`for file in $$list; do echo $$file; done | \
|
|
||||||
sed -e "s|^$$srcdirstrip/||;t" \
|
|
||||||
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
|
|
||||||
case $$dist_files in \
|
|
||||||
*/*) $(MKDIR_P) `echo "$$dist_files" | \
|
|
||||||
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
|
|
||||||
sort -u` ;; \
|
|
||||||
esac; \
|
|
||||||
for file in $$dist_files; do \
|
|
||||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
|
||||||
if test -d $$d/$$file; then \
|
|
||||||
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
|
|
||||||
if test -d "$(distdir)/$$file"; then \
|
|
||||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
|
||||||
fi; \
|
|
||||||
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
|
||||||
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
|
|
||||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
|
||||||
fi; \
|
|
||||||
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
|
|
||||||
else \
|
|
||||||
test -f "$(distdir)/$$file" \
|
|
||||||
|| cp -p $$d/$$file "$(distdir)/$$file" \
|
|
||||||
|| exit 1; \
|
|
||||||
fi; \
|
|
||||||
done
|
|
||||||
check-am: all-am
|
|
||||||
check: check-am
|
|
||||||
all-am: Makefile $(LTLIBRARIES) $(DATA)
|
|
||||||
installdirs:
|
|
||||||
for dir in "$(DESTDIR)$(pkglibdir)" "$(DESTDIR)$(exemplesdir)"; do \
|
|
||||||
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
|
|
||||||
done
|
|
||||||
install: install-am
|
|
||||||
install-exec: install-exec-am
|
|
||||||
install-data: install-data-am
|
|
||||||
uninstall: uninstall-am
|
|
||||||
|
|
||||||
install-am: all-am
|
|
||||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
|
||||||
|
|
||||||
installcheck: installcheck-am
|
|
||||||
install-strip:
|
|
||||||
if test -z '$(STRIP)'; then \
|
|
||||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
|
||||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
|
||||||
install; \
|
|
||||||
else \
|
|
||||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
|
||||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
|
||||||
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
|
|
||||||
fi
|
|
||||||
mostlyclean-generic:
|
|
||||||
|
|
||||||
clean-generic:
|
|
||||||
|
|
||||||
distclean-generic:
|
|
||||||
-$(am__rm_f) $(CONFIG_CLEAN_FILES)
|
|
||||||
-test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES)
|
|
||||||
|
|
||||||
maintainer-clean-generic:
|
|
||||||
@echo "This command is intended for maintainers to use"
|
|
||||||
@echo "it deletes files that may require special tools to rebuild."
|
|
||||||
clean: clean-am
|
|
||||||
|
|
||||||
clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \
|
|
||||||
mostlyclean-am
|
|
||||||
|
|
||||||
distclean: distclean-am
|
|
||||||
-rm -f ./$(DEPDIR)/callbacks-example-baselinks.Plo
|
|
||||||
-rm -f ./$(DEPDIR)/callbacks-example-changecontent.Plo
|
|
||||||
-rm -f ./$(DEPDIR)/callbacks-example-contentfilter.Plo
|
|
||||||
-rm -f ./$(DEPDIR)/callbacks-example-displayheader.Plo
|
|
||||||
-rm -f ./$(DEPDIR)/callbacks-example-filename.Plo
|
|
||||||
-rm -f ./$(DEPDIR)/callbacks-example-filename2.Plo
|
|
||||||
-rm -f ./$(DEPDIR)/callbacks-example-filenameiisbug.Plo
|
|
||||||
-rm -f ./$(DEPDIR)/callbacks-example-listlinks.Plo
|
|
||||||
-rm -f ./$(DEPDIR)/callbacks-example-log.Plo
|
|
||||||
-rm -f ./$(DEPDIR)/callbacks-example-simple.Plo
|
|
||||||
-rm -f Makefile
|
|
||||||
distclean-am: clean-am distclean-compile distclean-generic \
|
|
||||||
distclean-tags
|
|
||||||
|
|
||||||
dvi: dvi-am
|
|
||||||
|
|
||||||
dvi-am:
|
|
||||||
|
|
||||||
html: html-am
|
|
||||||
|
|
||||||
html-am:
|
|
||||||
|
|
||||||
info: info-am
|
|
||||||
|
|
||||||
info-am:
|
|
||||||
|
|
||||||
install-data-am: install-exemplesDATA
|
|
||||||
|
|
||||||
install-dvi: install-dvi-am
|
|
||||||
|
|
||||||
install-dvi-am:
|
|
||||||
|
|
||||||
install-exec-am: install-pkglibLTLIBRARIES
|
|
||||||
|
|
||||||
install-html: install-html-am
|
|
||||||
|
|
||||||
install-html-am:
|
|
||||||
|
|
||||||
install-info: install-info-am
|
|
||||||
|
|
||||||
install-info-am:
|
|
||||||
|
|
||||||
install-man:
|
|
||||||
|
|
||||||
install-pdf: install-pdf-am
|
|
||||||
|
|
||||||
install-pdf-am:
|
|
||||||
|
|
||||||
install-ps: install-ps-am
|
|
||||||
|
|
||||||
install-ps-am:
|
|
||||||
|
|
||||||
installcheck-am:
|
|
||||||
|
|
||||||
maintainer-clean: maintainer-clean-am
|
|
||||||
-rm -f ./$(DEPDIR)/callbacks-example-baselinks.Plo
|
|
||||||
-rm -f ./$(DEPDIR)/callbacks-example-changecontent.Plo
|
|
||||||
-rm -f ./$(DEPDIR)/callbacks-example-contentfilter.Plo
|
|
||||||
-rm -f ./$(DEPDIR)/callbacks-example-displayheader.Plo
|
|
||||||
-rm -f ./$(DEPDIR)/callbacks-example-filename.Plo
|
|
||||||
-rm -f ./$(DEPDIR)/callbacks-example-filename2.Plo
|
|
||||||
-rm -f ./$(DEPDIR)/callbacks-example-filenameiisbug.Plo
|
|
||||||
-rm -f ./$(DEPDIR)/callbacks-example-listlinks.Plo
|
|
||||||
-rm -f ./$(DEPDIR)/callbacks-example-log.Plo
|
|
||||||
-rm -f ./$(DEPDIR)/callbacks-example-simple.Plo
|
|
||||||
-rm -f Makefile
|
|
||||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
|
||||||
|
|
||||||
mostlyclean: mostlyclean-am
|
|
||||||
|
|
||||||
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
|
|
||||||
mostlyclean-libtool
|
|
||||||
|
|
||||||
pdf: pdf-am
|
|
||||||
|
|
||||||
pdf-am:
|
|
||||||
|
|
||||||
ps: ps-am
|
|
||||||
|
|
||||||
ps-am:
|
|
||||||
|
|
||||||
uninstall-am: uninstall-exemplesDATA uninstall-pkglibLTLIBRARIES
|
|
||||||
|
|
||||||
.MAKE: install-am install-strip
|
|
||||||
|
|
||||||
.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
|
|
||||||
clean-generic clean-libtool clean-pkglibLTLIBRARIES \
|
|
||||||
cscopelist-am ctags ctags-am distclean distclean-compile \
|
|
||||||
distclean-generic distclean-libtool distclean-tags distdir dvi \
|
|
||||||
dvi-am html html-am info info-am install install-am \
|
|
||||||
install-data install-data-am install-dvi install-dvi-am \
|
|
||||||
install-exec install-exec-am install-exemplesDATA install-html \
|
|
||||||
install-html-am install-info install-info-am install-man \
|
|
||||||
install-pdf install-pdf-am install-pkglibLTLIBRARIES \
|
|
||||||
install-ps install-ps-am install-strip installcheck \
|
|
||||||
installcheck-am installdirs maintainer-clean \
|
|
||||||
maintainer-clean-generic mostlyclean mostlyclean-compile \
|
|
||||||
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
|
|
||||||
tags tags-am uninstall uninstall-am uninstall-exemplesDATA \
|
|
||||||
uninstall-pkglibLTLIBRARIES
|
|
||||||
|
|
||||||
.PRECIOUS: Makefile
|
|
||||||
|
|
||||||
|
|
||||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
|
||||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
|
||||||
.NOEXPORT:
|
|
||||||
|
|
||||||
# Tell GNU make to disable its built-in pattern rules.
|
|
||||||
%:: %,v
|
|
||||||
%:: RCS/%,v
|
|
||||||
%:: RCS/%
|
|
||||||
%:: s.%
|
|
||||||
%:: SCCS/s.%
|
|
||||||
479
m4/Makefile.in
479
m4/Makefile.in
@@ -1,479 +0,0 @@
|
|||||||
# Makefile.in generated by automake 1.17 from Makefile.am.
|
|
||||||
# @configure_input@
|
|
||||||
|
|
||||||
# Copyright (C) 1994-2024 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
# This Makefile.in is free software; the Free Software Foundation
|
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
|
||||||
# with or without modifications, as long as this notice is preserved.
|
|
||||||
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
|
||||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
|
||||||
# PARTICULAR PURPOSE.
|
|
||||||
|
|
||||||
@SET_MAKE@
|
|
||||||
VPATH = @srcdir@
|
|
||||||
am__is_gnu_make = { \
|
|
||||||
if test -z '$(MAKELEVEL)'; then \
|
|
||||||
false; \
|
|
||||||
elif test -n '$(MAKE_HOST)'; then \
|
|
||||||
true; \
|
|
||||||
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
|
|
||||||
true; \
|
|
||||||
else \
|
|
||||||
false; \
|
|
||||||
fi; \
|
|
||||||
}
|
|
||||||
am__make_running_with_option = \
|
|
||||||
case $${target_option-} in \
|
|
||||||
?) ;; \
|
|
||||||
*) echo "am__make_running_with_option: internal error: invalid" \
|
|
||||||
"target option '$${target_option-}' specified" >&2; \
|
|
||||||
exit 1;; \
|
|
||||||
esac; \
|
|
||||||
has_opt=no; \
|
|
||||||
sane_makeflags=$$MAKEFLAGS; \
|
|
||||||
if $(am__is_gnu_make); then \
|
|
||||||
sane_makeflags=$$MFLAGS; \
|
|
||||||
else \
|
|
||||||
case $$MAKEFLAGS in \
|
|
||||||
*\\[\ \ ]*) \
|
|
||||||
bs=\\; \
|
|
||||||
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
|
|
||||||
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
|
|
||||||
esac; \
|
|
||||||
fi; \
|
|
||||||
skip_next=no; \
|
|
||||||
strip_trailopt () \
|
|
||||||
{ \
|
|
||||||
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
|
|
||||||
}; \
|
|
||||||
for flg in $$sane_makeflags; do \
|
|
||||||
test $$skip_next = yes && { skip_next=no; continue; }; \
|
|
||||||
case $$flg in \
|
|
||||||
*=*|--*) continue;; \
|
|
||||||
-*I) strip_trailopt 'I'; skip_next=yes;; \
|
|
||||||
-*I?*) strip_trailopt 'I';; \
|
|
||||||
-*O) strip_trailopt 'O'; skip_next=yes;; \
|
|
||||||
-*O?*) strip_trailopt 'O';; \
|
|
||||||
-*l) strip_trailopt 'l'; skip_next=yes;; \
|
|
||||||
-*l?*) strip_trailopt 'l';; \
|
|
||||||
-[dEDm]) skip_next=yes;; \
|
|
||||||
-[JT]) skip_next=yes;; \
|
|
||||||
esac; \
|
|
||||||
case $$flg in \
|
|
||||||
*$$target_option*) has_opt=yes; break;; \
|
|
||||||
esac; \
|
|
||||||
done; \
|
|
||||||
test $$has_opt = yes
|
|
||||||
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
|
|
||||||
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
|
|
||||||
am__rm_f = rm -f $(am__rm_f_notfound)
|
|
||||||
am__rm_rf = rm -rf $(am__rm_f_notfound)
|
|
||||||
pkgdatadir = $(datadir)/@PACKAGE@
|
|
||||||
pkgincludedir = $(includedir)/@PACKAGE@
|
|
||||||
pkglibdir = $(libdir)/@PACKAGE@
|
|
||||||
pkglibexecdir = $(libexecdir)/@PACKAGE@
|
|
||||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
|
||||||
install_sh_DATA = $(install_sh) -c -m 644
|
|
||||||
install_sh_PROGRAM = $(install_sh) -c
|
|
||||||
install_sh_SCRIPT = $(install_sh) -c
|
|
||||||
INSTALL_HEADER = $(INSTALL_DATA)
|
|
||||||
transform = $(program_transform_name)
|
|
||||||
NORMAL_INSTALL = :
|
|
||||||
PRE_INSTALL = :
|
|
||||||
POST_INSTALL = :
|
|
||||||
NORMAL_UNINSTALL = :
|
|
||||||
PRE_UNINSTALL = :
|
|
||||||
POST_UNINSTALL = :
|
|
||||||
build_triplet = @build@
|
|
||||||
host_triplet = @host@
|
|
||||||
subdir = m4
|
|
||||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
|
||||||
am__aclocal_m4_deps = $(top_srcdir)/m4/check_zlib.m4 \
|
|
||||||
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
|
|
||||||
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
|
|
||||||
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/snprintf.m4 \
|
|
||||||
$(top_srcdir)/m4/visibility.m4 $(top_srcdir)/configure.ac
|
|
||||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
|
||||||
$(ACLOCAL_M4)
|
|
||||||
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
|
|
||||||
mkinstalldirs = $(install_sh) -d
|
|
||||||
CONFIG_HEADER = $(top_builddir)/config.h
|
|
||||||
CONFIG_CLEAN_FILES =
|
|
||||||
CONFIG_CLEAN_VPATH_FILES =
|
|
||||||
AM_V_P = $(am__v_P_@AM_V@)
|
|
||||||
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
|
|
||||||
am__v_P_0 = false
|
|
||||||
am__v_P_1 = :
|
|
||||||
AM_V_GEN = $(am__v_GEN_@AM_V@)
|
|
||||||
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
|
|
||||||
am__v_GEN_0 = @echo " GEN " $@;
|
|
||||||
am__v_GEN_1 =
|
|
||||||
AM_V_at = $(am__v_at_@AM_V@)
|
|
||||||
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
|
|
||||||
am__v_at_0 = @
|
|
||||||
am__v_at_1 =
|
|
||||||
SOURCES =
|
|
||||||
DIST_SOURCES =
|
|
||||||
am__can_run_installinfo = \
|
|
||||||
case $$AM_UPDATE_INFO_DIR in \
|
|
||||||
n|no|NO) false;; \
|
|
||||||
*) (install-info --version) >/dev/null 2>&1;; \
|
|
||||||
esac
|
|
||||||
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
|
|
||||||
am__DIST_COMMON = $(srcdir)/Makefile.in
|
|
||||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
|
||||||
ACLOCAL = @ACLOCAL@
|
|
||||||
AMTAR = @AMTAR@
|
|
||||||
AM_CFLAGS = @AM_CFLAGS@
|
|
||||||
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
|
|
||||||
AR = @AR@
|
|
||||||
AUTOCONF = @AUTOCONF@
|
|
||||||
AUTOHEADER = @AUTOHEADER@
|
|
||||||
AUTOMAKE = @AUTOMAKE@
|
|
||||||
AWK = @AWK@
|
|
||||||
BASH = @BASH@
|
|
||||||
CC = @CC@
|
|
||||||
CCDEPMODE = @CCDEPMODE@
|
|
||||||
CFLAGS = @CFLAGS@
|
|
||||||
CFLAGS_PIE = @CFLAGS_PIE@
|
|
||||||
CFLAG_VISIBILITY = @CFLAG_VISIBILITY@
|
|
||||||
CPPFLAGS = @CPPFLAGS@
|
|
||||||
CSCOPE = @CSCOPE@
|
|
||||||
CTAGS = @CTAGS@
|
|
||||||
CYGPATH_W = @CYGPATH_W@
|
|
||||||
DEFAULT_CFLAGS = @DEFAULT_CFLAGS@
|
|
||||||
DEFAULT_LDFLAGS = @DEFAULT_LDFLAGS@
|
|
||||||
DEFS = @DEFS@
|
|
||||||
DEPDIR = @DEPDIR@
|
|
||||||
DLLTOOL = @DLLTOOL@
|
|
||||||
DL_LIBS = @DL_LIBS@
|
|
||||||
DSYMUTIL = @DSYMUTIL@
|
|
||||||
DUMPBIN = @DUMPBIN@
|
|
||||||
ECHO_C = @ECHO_C@
|
|
||||||
ECHO_N = @ECHO_N@
|
|
||||||
ECHO_T = @ECHO_T@
|
|
||||||
EGREP = @EGREP@
|
|
||||||
ETAGS = @ETAGS@
|
|
||||||
EXEEXT = @EXEEXT@
|
|
||||||
FGREP = @FGREP@
|
|
||||||
FILECMD = @FILECMD@
|
|
||||||
GREP = @GREP@
|
|
||||||
HAVE_VISIBILITY = @HAVE_VISIBILITY@
|
|
||||||
HTTPS_SUPPORT = @HTTPS_SUPPORT@
|
|
||||||
ICONV_LIBS = @ICONV_LIBS@
|
|
||||||
INSTALL = @INSTALL@
|
|
||||||
INSTALL_DATA = @INSTALL_DATA@
|
|
||||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
|
||||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
|
||||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
|
||||||
LD = @LD@
|
|
||||||
LDFLAGS = @LDFLAGS@
|
|
||||||
LDFLAGS_PIE = @LDFLAGS_PIE@
|
|
||||||
LFS_FLAG = @LFS_FLAG@
|
|
||||||
LIBC_FORCE_LINK = @LIBC_FORCE_LINK@
|
|
||||||
LIBOBJS = @LIBOBJS@
|
|
||||||
LIBS = @LIBS@
|
|
||||||
LIBTOOL = @LIBTOOL@
|
|
||||||
LIPO = @LIPO@
|
|
||||||
LN_S = @LN_S@
|
|
||||||
LTLIBOBJS = @LTLIBOBJS@
|
|
||||||
LT_CV_OBJDIR = @LT_CV_OBJDIR@
|
|
||||||
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
|
|
||||||
MAINT = @MAINT@
|
|
||||||
MAKEINFO = @MAKEINFO@
|
|
||||||
MANIFEST_TOOL = @MANIFEST_TOOL@
|
|
||||||
MKDIR_P = @MKDIR_P@
|
|
||||||
NM = @NM@
|
|
||||||
NMEDIT = @NMEDIT@
|
|
||||||
OBJDUMP = @OBJDUMP@
|
|
||||||
OBJEXT = @OBJEXT@
|
|
||||||
ONLINE_UNIT_TESTS = @ONLINE_UNIT_TESTS@
|
|
||||||
OPENSSL_LIBS = @OPENSSL_LIBS@
|
|
||||||
OTOOL = @OTOOL@
|
|
||||||
OTOOL64 = @OTOOL64@
|
|
||||||
PACKAGE = @PACKAGE@
|
|
||||||
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
|
||||||
PACKAGE_NAME = @PACKAGE_NAME@
|
|
||||||
PACKAGE_STRING = @PACKAGE_STRING@
|
|
||||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
|
||||||
PACKAGE_URL = @PACKAGE_URL@
|
|
||||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
|
||||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
|
||||||
RANLIB = @RANLIB@
|
|
||||||
SED = @SED@
|
|
||||||
SET_MAKE = @SET_MAKE@
|
|
||||||
SHELL = @SHELL@
|
|
||||||
SHLIBPATH_VAR = @SHLIBPATH_VAR@
|
|
||||||
SOCKET_LIBS = @SOCKET_LIBS@
|
|
||||||
STRIP = @STRIP@
|
|
||||||
THREADS_CFLAGS = @THREADS_CFLAGS@
|
|
||||||
THREADS_LIBS = @THREADS_LIBS@
|
|
||||||
V6_FLAG = @V6_FLAG@
|
|
||||||
VERSION = @VERSION@
|
|
||||||
VERSION_INFO = @VERSION_INFO@
|
|
||||||
abs_builddir = @abs_builddir@
|
|
||||||
abs_srcdir = @abs_srcdir@
|
|
||||||
abs_top_builddir = @abs_top_builddir@
|
|
||||||
abs_top_srcdir = @abs_top_srcdir@
|
|
||||||
ac_ct_AR = @ac_ct_AR@
|
|
||||||
ac_ct_CC = @ac_ct_CC@
|
|
||||||
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
|
|
||||||
am__include = @am__include@
|
|
||||||
am__leading_dot = @am__leading_dot@
|
|
||||||
am__quote = @am__quote@
|
|
||||||
am__rm_f_notfound = @am__rm_f_notfound@
|
|
||||||
am__tar = @am__tar@
|
|
||||||
am__untar = @am__untar@
|
|
||||||
am__xargs_n = @am__xargs_n@
|
|
||||||
bindir = @bindir@
|
|
||||||
build = @build@
|
|
||||||
build_alias = @build_alias@
|
|
||||||
build_cpu = @build_cpu@
|
|
||||||
build_os = @build_os@
|
|
||||||
build_vendor = @build_vendor@
|
|
||||||
builddir = @builddir@
|
|
||||||
datadir = @datadir@
|
|
||||||
datarootdir = @datarootdir@
|
|
||||||
docdir = @docdir@
|
|
||||||
dvidir = @dvidir@
|
|
||||||
exec_prefix = @exec_prefix@
|
|
||||||
host = @host@
|
|
||||||
host_alias = @host_alias@
|
|
||||||
host_cpu = @host_cpu@
|
|
||||||
host_os = @host_os@
|
|
||||||
host_vendor = @host_vendor@
|
|
||||||
htmldir = @htmldir@
|
|
||||||
includedir = @includedir@
|
|
||||||
infodir = @infodir@
|
|
||||||
install_sh = @install_sh@
|
|
||||||
libdir = @libdir@
|
|
||||||
libexecdir = @libexecdir@
|
|
||||||
localedir = @localedir@
|
|
||||||
localstatedir = @localstatedir@
|
|
||||||
mandir = @mandir@
|
|
||||||
mkdir_p = @mkdir_p@
|
|
||||||
oldincludedir = @oldincludedir@
|
|
||||||
pdfdir = @pdfdir@
|
|
||||||
prefix = @prefix@
|
|
||||||
program_transform_name = @program_transform_name@
|
|
||||||
psdir = @psdir@
|
|
||||||
runstatedir = @runstatedir@
|
|
||||||
sbindir = @sbindir@
|
|
||||||
sharedstatedir = @sharedstatedir@
|
|
||||||
srcdir = @srcdir@
|
|
||||||
sysconfdir = @sysconfdir@
|
|
||||||
target_alias = @target_alias@
|
|
||||||
top_build_prefix = @top_build_prefix@
|
|
||||||
top_builddir = @top_builddir@
|
|
||||||
top_srcdir = @top_srcdir@
|
|
||||||
|
|
||||||
# Glob against $(srcdir) so "make dist" works out-of-tree (a bare "*.m4" is
|
|
||||||
# resolved against the build dir, where there are no sources).
|
|
||||||
EXTRA_DIST = $(srcdir)/*.m4
|
|
||||||
all: all-am
|
|
||||||
|
|
||||||
.SUFFIXES:
|
|
||||||
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
|
|
||||||
@for dep in $?; do \
|
|
||||||
case '$(am__configure_deps)' in \
|
|
||||||
*$$dep*) \
|
|
||||||
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
|
|
||||||
&& { if test -f $@; then exit 0; else break; fi; }; \
|
|
||||||
exit 1;; \
|
|
||||||
esac; \
|
|
||||||
done; \
|
|
||||||
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu m4/Makefile'; \
|
|
||||||
$(am__cd) $(top_srcdir) && \
|
|
||||||
$(AUTOMAKE) --gnu m4/Makefile
|
|
||||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
|
||||||
@case '$?' in \
|
|
||||||
*config.status*) \
|
|
||||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
|
|
||||||
*) \
|
|
||||||
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
|
|
||||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
|
|
||||||
esac;
|
|
||||||
|
|
||||||
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
|
||||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
|
||||||
|
|
||||||
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
|
|
||||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
|
||||||
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
|
|
||||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
|
||||||
$(am__aclocal_m4_deps):
|
|
||||||
|
|
||||||
mostlyclean-libtool:
|
|
||||||
-rm -f *.lo
|
|
||||||
|
|
||||||
clean-libtool:
|
|
||||||
-rm -rf .libs _libs
|
|
||||||
tags TAGS:
|
|
||||||
|
|
||||||
ctags CTAGS:
|
|
||||||
|
|
||||||
cscope cscopelist:
|
|
||||||
|
|
||||||
distdir: $(BUILT_SOURCES)
|
|
||||||
$(MAKE) $(AM_MAKEFLAGS) distdir-am
|
|
||||||
|
|
||||||
distdir-am: $(DISTFILES)
|
|
||||||
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
|
||||||
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
|
||||||
list='$(DISTFILES)'; \
|
|
||||||
dist_files=`for file in $$list; do echo $$file; done | \
|
|
||||||
sed -e "s|^$$srcdirstrip/||;t" \
|
|
||||||
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
|
|
||||||
case $$dist_files in \
|
|
||||||
*/*) $(MKDIR_P) `echo "$$dist_files" | \
|
|
||||||
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
|
|
||||||
sort -u` ;; \
|
|
||||||
esac; \
|
|
||||||
for file in $$dist_files; do \
|
|
||||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
|
||||||
if test -d $$d/$$file; then \
|
|
||||||
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
|
|
||||||
if test -d "$(distdir)/$$file"; then \
|
|
||||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
|
||||||
fi; \
|
|
||||||
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
|
||||||
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
|
|
||||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
|
||||||
fi; \
|
|
||||||
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
|
|
||||||
else \
|
|
||||||
test -f "$(distdir)/$$file" \
|
|
||||||
|| cp -p $$d/$$file "$(distdir)/$$file" \
|
|
||||||
|| exit 1; \
|
|
||||||
fi; \
|
|
||||||
done
|
|
||||||
check-am: all-am
|
|
||||||
check: check-am
|
|
||||||
all-am: Makefile
|
|
||||||
installdirs:
|
|
||||||
install: install-am
|
|
||||||
install-exec: install-exec-am
|
|
||||||
install-data: install-data-am
|
|
||||||
uninstall: uninstall-am
|
|
||||||
|
|
||||||
install-am: all-am
|
|
||||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
|
||||||
|
|
||||||
installcheck: installcheck-am
|
|
||||||
install-strip:
|
|
||||||
if test -z '$(STRIP)'; then \
|
|
||||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
|
||||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
|
||||||
install; \
|
|
||||||
else \
|
|
||||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
|
||||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
|
||||||
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
|
|
||||||
fi
|
|
||||||
mostlyclean-generic:
|
|
||||||
|
|
||||||
clean-generic:
|
|
||||||
|
|
||||||
distclean-generic:
|
|
||||||
-$(am__rm_f) $(CONFIG_CLEAN_FILES)
|
|
||||||
-test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES)
|
|
||||||
|
|
||||||
maintainer-clean-generic:
|
|
||||||
@echo "This command is intended for maintainers to use"
|
|
||||||
@echo "it deletes files that may require special tools to rebuild."
|
|
||||||
clean: clean-am
|
|
||||||
|
|
||||||
clean-am: clean-generic clean-libtool mostlyclean-am
|
|
||||||
|
|
||||||
distclean: distclean-am
|
|
||||||
-rm -f Makefile
|
|
||||||
distclean-am: clean-am distclean-generic
|
|
||||||
|
|
||||||
dvi: dvi-am
|
|
||||||
|
|
||||||
dvi-am:
|
|
||||||
|
|
||||||
html: html-am
|
|
||||||
|
|
||||||
html-am:
|
|
||||||
|
|
||||||
info: info-am
|
|
||||||
|
|
||||||
info-am:
|
|
||||||
|
|
||||||
install-data-am:
|
|
||||||
|
|
||||||
install-dvi: install-dvi-am
|
|
||||||
|
|
||||||
install-dvi-am:
|
|
||||||
|
|
||||||
install-exec-am:
|
|
||||||
|
|
||||||
install-html: install-html-am
|
|
||||||
|
|
||||||
install-html-am:
|
|
||||||
|
|
||||||
install-info: install-info-am
|
|
||||||
|
|
||||||
install-info-am:
|
|
||||||
|
|
||||||
install-man:
|
|
||||||
|
|
||||||
install-pdf: install-pdf-am
|
|
||||||
|
|
||||||
install-pdf-am:
|
|
||||||
|
|
||||||
install-ps: install-ps-am
|
|
||||||
|
|
||||||
install-ps-am:
|
|
||||||
|
|
||||||
installcheck-am:
|
|
||||||
|
|
||||||
maintainer-clean: maintainer-clean-am
|
|
||||||
-rm -f Makefile
|
|
||||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
|
||||||
|
|
||||||
mostlyclean: mostlyclean-am
|
|
||||||
|
|
||||||
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
|
|
||||||
|
|
||||||
pdf: pdf-am
|
|
||||||
|
|
||||||
pdf-am:
|
|
||||||
|
|
||||||
ps: ps-am
|
|
||||||
|
|
||||||
ps-am:
|
|
||||||
|
|
||||||
uninstall-am:
|
|
||||||
|
|
||||||
.MAKE: install-am install-strip
|
|
||||||
|
|
||||||
.PHONY: all all-am check check-am clean clean-generic clean-libtool \
|
|
||||||
cscopelist-am ctags-am distclean distclean-generic \
|
|
||||||
distclean-libtool distdir dvi dvi-am html html-am info info-am \
|
|
||||||
install install-am install-data install-data-am install-dvi \
|
|
||||||
install-dvi-am install-exec install-exec-am install-html \
|
|
||||||
install-html-am install-info install-info-am install-man \
|
|
||||||
install-pdf install-pdf-am install-ps install-ps-am \
|
|
||||||
install-strip installcheck installcheck-am installdirs \
|
|
||||||
maintainer-clean maintainer-clean-generic mostlyclean \
|
|
||||||
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
|
|
||||||
tags-am uninstall uninstall-am
|
|
||||||
|
|
||||||
.PRECIOUS: Makefile
|
|
||||||
|
|
||||||
|
|
||||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
|
||||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
|
||||||
.NOEXPORT:
|
|
||||||
|
|
||||||
# Tell GNU make to disable its built-in pattern rules.
|
|
||||||
%:: %,v
|
|
||||||
%:: RCS/%,v
|
|
||||||
%:: RCS/%
|
|
||||||
%:: s.%
|
|
||||||
%:: SCCS/s.%
|
|
||||||
574
man/Makefile.in
574
man/Makefile.in
@@ -1,574 +0,0 @@
|
|||||||
# Makefile.in generated by automake 1.17 from Makefile.am.
|
|
||||||
# @configure_input@
|
|
||||||
|
|
||||||
# Copyright (C) 1994-2024 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
# This Makefile.in is free software; the Free Software Foundation
|
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
|
||||||
# with or without modifications, as long as this notice is preserved.
|
|
||||||
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
|
||||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
|
||||||
# PARTICULAR PURPOSE.
|
|
||||||
|
|
||||||
@SET_MAKE@
|
|
||||||
VPATH = @srcdir@
|
|
||||||
am__is_gnu_make = { \
|
|
||||||
if test -z '$(MAKELEVEL)'; then \
|
|
||||||
false; \
|
|
||||||
elif test -n '$(MAKE_HOST)'; then \
|
|
||||||
true; \
|
|
||||||
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
|
|
||||||
true; \
|
|
||||||
else \
|
|
||||||
false; \
|
|
||||||
fi; \
|
|
||||||
}
|
|
||||||
am__make_running_with_option = \
|
|
||||||
case $${target_option-} in \
|
|
||||||
?) ;; \
|
|
||||||
*) echo "am__make_running_with_option: internal error: invalid" \
|
|
||||||
"target option '$${target_option-}' specified" >&2; \
|
|
||||||
exit 1;; \
|
|
||||||
esac; \
|
|
||||||
has_opt=no; \
|
|
||||||
sane_makeflags=$$MAKEFLAGS; \
|
|
||||||
if $(am__is_gnu_make); then \
|
|
||||||
sane_makeflags=$$MFLAGS; \
|
|
||||||
else \
|
|
||||||
case $$MAKEFLAGS in \
|
|
||||||
*\\[\ \ ]*) \
|
|
||||||
bs=\\; \
|
|
||||||
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
|
|
||||||
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
|
|
||||||
esac; \
|
|
||||||
fi; \
|
|
||||||
skip_next=no; \
|
|
||||||
strip_trailopt () \
|
|
||||||
{ \
|
|
||||||
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
|
|
||||||
}; \
|
|
||||||
for flg in $$sane_makeflags; do \
|
|
||||||
test $$skip_next = yes && { skip_next=no; continue; }; \
|
|
||||||
case $$flg in \
|
|
||||||
*=*|--*) continue;; \
|
|
||||||
-*I) strip_trailopt 'I'; skip_next=yes;; \
|
|
||||||
-*I?*) strip_trailopt 'I';; \
|
|
||||||
-*O) strip_trailopt 'O'; skip_next=yes;; \
|
|
||||||
-*O?*) strip_trailopt 'O';; \
|
|
||||||
-*l) strip_trailopt 'l'; skip_next=yes;; \
|
|
||||||
-*l?*) strip_trailopt 'l';; \
|
|
||||||
-[dEDm]) skip_next=yes;; \
|
|
||||||
-[JT]) skip_next=yes;; \
|
|
||||||
esac; \
|
|
||||||
case $$flg in \
|
|
||||||
*$$target_option*) has_opt=yes; break;; \
|
|
||||||
esac; \
|
|
||||||
done; \
|
|
||||||
test $$has_opt = yes
|
|
||||||
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
|
|
||||||
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
|
|
||||||
am__rm_f = rm -f $(am__rm_f_notfound)
|
|
||||||
am__rm_rf = rm -rf $(am__rm_f_notfound)
|
|
||||||
pkgdatadir = $(datadir)/@PACKAGE@
|
|
||||||
pkgincludedir = $(includedir)/@PACKAGE@
|
|
||||||
pkglibdir = $(libdir)/@PACKAGE@
|
|
||||||
pkglibexecdir = $(libexecdir)/@PACKAGE@
|
|
||||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
|
||||||
install_sh_DATA = $(install_sh) -c -m 644
|
|
||||||
install_sh_PROGRAM = $(install_sh) -c
|
|
||||||
install_sh_SCRIPT = $(install_sh) -c
|
|
||||||
INSTALL_HEADER = $(INSTALL_DATA)
|
|
||||||
transform = $(program_transform_name)
|
|
||||||
NORMAL_INSTALL = :
|
|
||||||
PRE_INSTALL = :
|
|
||||||
POST_INSTALL = :
|
|
||||||
NORMAL_UNINSTALL = :
|
|
||||||
PRE_UNINSTALL = :
|
|
||||||
POST_UNINSTALL = :
|
|
||||||
build_triplet = @build@
|
|
||||||
host_triplet = @host@
|
|
||||||
subdir = man
|
|
||||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
|
||||||
am__aclocal_m4_deps = $(top_srcdir)/m4/check_zlib.m4 \
|
|
||||||
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
|
|
||||||
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
|
|
||||||
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/snprintf.m4 \
|
|
||||||
$(top_srcdir)/m4/visibility.m4 $(top_srcdir)/configure.ac
|
|
||||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
|
||||||
$(ACLOCAL_M4)
|
|
||||||
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
|
|
||||||
mkinstalldirs = $(install_sh) -d
|
|
||||||
CONFIG_HEADER = $(top_builddir)/config.h
|
|
||||||
CONFIG_CLEAN_FILES =
|
|
||||||
CONFIG_CLEAN_VPATH_FILES =
|
|
||||||
AM_V_P = $(am__v_P_@AM_V@)
|
|
||||||
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
|
|
||||||
am__v_P_0 = false
|
|
||||||
am__v_P_1 = :
|
|
||||||
AM_V_GEN = $(am__v_GEN_@AM_V@)
|
|
||||||
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
|
|
||||||
am__v_GEN_0 = @echo " GEN " $@;
|
|
||||||
am__v_GEN_1 =
|
|
||||||
AM_V_at = $(am__v_at_@AM_V@)
|
|
||||||
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
|
|
||||||
am__v_at_0 = @
|
|
||||||
am__v_at_1 =
|
|
||||||
SOURCES =
|
|
||||||
DIST_SOURCES =
|
|
||||||
am__can_run_installinfo = \
|
|
||||||
case $$AM_UPDATE_INFO_DIR in \
|
|
||||||
n|no|NO) false;; \
|
|
||||||
*) (install-info --version) >/dev/null 2>&1;; \
|
|
||||||
esac
|
|
||||||
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
|
|
||||||
am__vpath_adj = case $$p in \
|
|
||||||
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
|
|
||||||
*) f=$$p;; \
|
|
||||||
esac;
|
|
||||||
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
|
|
||||||
am__install_max = 40
|
|
||||||
am__nobase_strip_setup = \
|
|
||||||
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
|
|
||||||
am__nobase_strip = \
|
|
||||||
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
|
|
||||||
am__nobase_list = $(am__nobase_strip_setup); \
|
|
||||||
for p in $$list; do echo "$$p $$p"; done | \
|
|
||||||
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
|
|
||||||
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
|
|
||||||
if (++n[$$2] == $(am__install_max)) \
|
|
||||||
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
|
|
||||||
END { for (dir in files) print dir, files[dir] }'
|
|
||||||
am__base_list = \
|
|
||||||
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
|
|
||||||
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
|
|
||||||
am__uninstall_files_from_dir = { \
|
|
||||||
{ test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|
|
||||||
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
|
|
||||||
$(am__cd) "$$dir" && echo $$files | $(am__xargs_n) 40 $(am__rm_f); }; \
|
|
||||||
}
|
|
||||||
man1dir = $(mandir)/man1
|
|
||||||
am__installdirs = "$(DESTDIR)$(man1dir)"
|
|
||||||
NROFF = nroff
|
|
||||||
MANS = $(man_MANS)
|
|
||||||
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
|
|
||||||
am__DIST_COMMON = $(srcdir)/Makefile.in
|
|
||||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
|
||||||
ACLOCAL = @ACLOCAL@
|
|
||||||
AMTAR = @AMTAR@
|
|
||||||
AM_CFLAGS = @AM_CFLAGS@
|
|
||||||
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
|
|
||||||
AR = @AR@
|
|
||||||
AUTOCONF = @AUTOCONF@
|
|
||||||
AUTOHEADER = @AUTOHEADER@
|
|
||||||
AUTOMAKE = @AUTOMAKE@
|
|
||||||
AWK = @AWK@
|
|
||||||
BASH = @BASH@
|
|
||||||
CC = @CC@
|
|
||||||
CCDEPMODE = @CCDEPMODE@
|
|
||||||
CFLAGS = @CFLAGS@
|
|
||||||
CFLAGS_PIE = @CFLAGS_PIE@
|
|
||||||
CFLAG_VISIBILITY = @CFLAG_VISIBILITY@
|
|
||||||
CPPFLAGS = @CPPFLAGS@
|
|
||||||
CSCOPE = @CSCOPE@
|
|
||||||
CTAGS = @CTAGS@
|
|
||||||
CYGPATH_W = @CYGPATH_W@
|
|
||||||
DEFAULT_CFLAGS = @DEFAULT_CFLAGS@
|
|
||||||
DEFAULT_LDFLAGS = @DEFAULT_LDFLAGS@
|
|
||||||
DEFS = @DEFS@
|
|
||||||
DEPDIR = @DEPDIR@
|
|
||||||
DLLTOOL = @DLLTOOL@
|
|
||||||
DL_LIBS = @DL_LIBS@
|
|
||||||
DSYMUTIL = @DSYMUTIL@
|
|
||||||
DUMPBIN = @DUMPBIN@
|
|
||||||
ECHO_C = @ECHO_C@
|
|
||||||
ECHO_N = @ECHO_N@
|
|
||||||
ECHO_T = @ECHO_T@
|
|
||||||
EGREP = @EGREP@
|
|
||||||
ETAGS = @ETAGS@
|
|
||||||
EXEEXT = @EXEEXT@
|
|
||||||
FGREP = @FGREP@
|
|
||||||
FILECMD = @FILECMD@
|
|
||||||
GREP = @GREP@
|
|
||||||
HAVE_VISIBILITY = @HAVE_VISIBILITY@
|
|
||||||
HTTPS_SUPPORT = @HTTPS_SUPPORT@
|
|
||||||
ICONV_LIBS = @ICONV_LIBS@
|
|
||||||
INSTALL = @INSTALL@
|
|
||||||
INSTALL_DATA = @INSTALL_DATA@
|
|
||||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
|
||||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
|
||||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
|
||||||
LD = @LD@
|
|
||||||
LDFLAGS = @LDFLAGS@
|
|
||||||
LDFLAGS_PIE = @LDFLAGS_PIE@
|
|
||||||
LFS_FLAG = @LFS_FLAG@
|
|
||||||
LIBC_FORCE_LINK = @LIBC_FORCE_LINK@
|
|
||||||
LIBOBJS = @LIBOBJS@
|
|
||||||
LIBS = @LIBS@
|
|
||||||
LIBTOOL = @LIBTOOL@
|
|
||||||
LIPO = @LIPO@
|
|
||||||
LN_S = @LN_S@
|
|
||||||
LTLIBOBJS = @LTLIBOBJS@
|
|
||||||
LT_CV_OBJDIR = @LT_CV_OBJDIR@
|
|
||||||
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
|
|
||||||
MAINT = @MAINT@
|
|
||||||
MAKEINFO = @MAKEINFO@
|
|
||||||
MANIFEST_TOOL = @MANIFEST_TOOL@
|
|
||||||
MKDIR_P = @MKDIR_P@
|
|
||||||
NM = @NM@
|
|
||||||
NMEDIT = @NMEDIT@
|
|
||||||
OBJDUMP = @OBJDUMP@
|
|
||||||
OBJEXT = @OBJEXT@
|
|
||||||
ONLINE_UNIT_TESTS = @ONLINE_UNIT_TESTS@
|
|
||||||
OPENSSL_LIBS = @OPENSSL_LIBS@
|
|
||||||
OTOOL = @OTOOL@
|
|
||||||
OTOOL64 = @OTOOL64@
|
|
||||||
PACKAGE = @PACKAGE@
|
|
||||||
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
|
||||||
PACKAGE_NAME = @PACKAGE_NAME@
|
|
||||||
PACKAGE_STRING = @PACKAGE_STRING@
|
|
||||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
|
||||||
PACKAGE_URL = @PACKAGE_URL@
|
|
||||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
|
||||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
|
||||||
RANLIB = @RANLIB@
|
|
||||||
SED = @SED@
|
|
||||||
SET_MAKE = @SET_MAKE@
|
|
||||||
SHELL = @SHELL@
|
|
||||||
SHLIBPATH_VAR = @SHLIBPATH_VAR@
|
|
||||||
SOCKET_LIBS = @SOCKET_LIBS@
|
|
||||||
STRIP = @STRIP@
|
|
||||||
THREADS_CFLAGS = @THREADS_CFLAGS@
|
|
||||||
THREADS_LIBS = @THREADS_LIBS@
|
|
||||||
V6_FLAG = @V6_FLAG@
|
|
||||||
VERSION = @VERSION@
|
|
||||||
VERSION_INFO = @VERSION_INFO@
|
|
||||||
abs_builddir = @abs_builddir@
|
|
||||||
abs_srcdir = @abs_srcdir@
|
|
||||||
abs_top_builddir = @abs_top_builddir@
|
|
||||||
abs_top_srcdir = @abs_top_srcdir@
|
|
||||||
ac_ct_AR = @ac_ct_AR@
|
|
||||||
ac_ct_CC = @ac_ct_CC@
|
|
||||||
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
|
|
||||||
am__include = @am__include@
|
|
||||||
am__leading_dot = @am__leading_dot@
|
|
||||||
am__quote = @am__quote@
|
|
||||||
am__rm_f_notfound = @am__rm_f_notfound@
|
|
||||||
am__tar = @am__tar@
|
|
||||||
am__untar = @am__untar@
|
|
||||||
am__xargs_n = @am__xargs_n@
|
|
||||||
bindir = @bindir@
|
|
||||||
build = @build@
|
|
||||||
build_alias = @build_alias@
|
|
||||||
build_cpu = @build_cpu@
|
|
||||||
build_os = @build_os@
|
|
||||||
build_vendor = @build_vendor@
|
|
||||||
builddir = @builddir@
|
|
||||||
datadir = @datadir@
|
|
||||||
datarootdir = @datarootdir@
|
|
||||||
docdir = @docdir@
|
|
||||||
dvidir = @dvidir@
|
|
||||||
exec_prefix = @exec_prefix@
|
|
||||||
host = @host@
|
|
||||||
host_alias = @host_alias@
|
|
||||||
host_cpu = @host_cpu@
|
|
||||||
host_os = @host_os@
|
|
||||||
host_vendor = @host_vendor@
|
|
||||||
htmldir = @htmldir@
|
|
||||||
includedir = @includedir@
|
|
||||||
infodir = @infodir@
|
|
||||||
install_sh = @install_sh@
|
|
||||||
libdir = @libdir@
|
|
||||||
libexecdir = @libexecdir@
|
|
||||||
localedir = @localedir@
|
|
||||||
localstatedir = @localstatedir@
|
|
||||||
mandir = @mandir@
|
|
||||||
mkdir_p = @mkdir_p@
|
|
||||||
oldincludedir = @oldincludedir@
|
|
||||||
pdfdir = @pdfdir@
|
|
||||||
prefix = @prefix@
|
|
||||||
program_transform_name = @program_transform_name@
|
|
||||||
psdir = @psdir@
|
|
||||||
runstatedir = @runstatedir@
|
|
||||||
sbindir = @sbindir@
|
|
||||||
sharedstatedir = @sharedstatedir@
|
|
||||||
srcdir = @srcdir@
|
|
||||||
sysconfdir = @sysconfdir@
|
|
||||||
target_alias = @target_alias@
|
|
||||||
top_build_prefix = @top_build_prefix@
|
|
||||||
top_builddir = @top_builddir@
|
|
||||||
top_srcdir = @top_srcdir@
|
|
||||||
|
|
||||||
# man_MANS = httrack.1
|
|
||||||
man_MANS = httrack.1 webhttrack.1 htsserver.1 proxytrack.1
|
|
||||||
EXTRA_DIST = $(man_MANS) makeman.sh
|
|
||||||
all: all-am
|
|
||||||
|
|
||||||
.SUFFIXES:
|
|
||||||
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
|
|
||||||
@for dep in $?; do \
|
|
||||||
case '$(am__configure_deps)' in \
|
|
||||||
*$$dep*) \
|
|
||||||
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
|
|
||||||
&& { if test -f $@; then exit 0; else break; fi; }; \
|
|
||||||
exit 1;; \
|
|
||||||
esac; \
|
|
||||||
done; \
|
|
||||||
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu man/Makefile'; \
|
|
||||||
$(am__cd) $(top_srcdir) && \
|
|
||||||
$(AUTOMAKE) --gnu man/Makefile
|
|
||||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
|
||||||
@case '$?' in \
|
|
||||||
*config.status*) \
|
|
||||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
|
|
||||||
*) \
|
|
||||||
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
|
|
||||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
|
|
||||||
esac;
|
|
||||||
|
|
||||||
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
|
||||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
|
||||||
|
|
||||||
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
|
|
||||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
|
||||||
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
|
|
||||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
|
||||||
$(am__aclocal_m4_deps):
|
|
||||||
|
|
||||||
mostlyclean-libtool:
|
|
||||||
-rm -f *.lo
|
|
||||||
|
|
||||||
clean-libtool:
|
|
||||||
-rm -rf .libs _libs
|
|
||||||
install-man1: $(man_MANS)
|
|
||||||
@$(NORMAL_INSTALL)
|
|
||||||
@list1=''; \
|
|
||||||
list2='$(man_MANS)'; \
|
|
||||||
test -n "$(man1dir)" \
|
|
||||||
&& test -n "`echo $$list1$$list2`" \
|
|
||||||
|| exit 0; \
|
|
||||||
echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \
|
|
||||||
$(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \
|
|
||||||
{ for i in $$list1; do echo "$$i"; done; \
|
|
||||||
if test -n "$$list2"; then \
|
|
||||||
for i in $$list2; do echo "$$i"; done \
|
|
||||||
| sed -n '/\.1[a-z]*$$/p'; \
|
|
||||||
fi; \
|
|
||||||
} | while read p; do \
|
|
||||||
if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
|
|
||||||
echo "$$d$$p"; echo "$$p"; \
|
|
||||||
done | \
|
|
||||||
sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
|
|
||||||
-e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
|
|
||||||
sed 'N;N;s,\n, ,g' | { \
|
|
||||||
list=; while read file base inst; do \
|
|
||||||
if test "$$base" = "$$inst"; then list="$$list $$file"; else \
|
|
||||||
echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \
|
|
||||||
$(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \
|
|
||||||
fi; \
|
|
||||||
done; \
|
|
||||||
for i in $$list; do echo "$$i"; done | $(am__base_list) | \
|
|
||||||
while read files; do \
|
|
||||||
test -z "$$files" || { \
|
|
||||||
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \
|
|
||||||
$(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \
|
|
||||||
done; }
|
|
||||||
|
|
||||||
uninstall-man1:
|
|
||||||
@$(NORMAL_UNINSTALL)
|
|
||||||
@list=''; test -n "$(man1dir)" || exit 0; \
|
|
||||||
files=`{ for i in $$list; do echo "$$i"; done; \
|
|
||||||
l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
|
|
||||||
sed -n '/\.1[a-z]*$$/p'; \
|
|
||||||
} | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
|
|
||||||
-e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
|
|
||||||
dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir)
|
|
||||||
tags TAGS:
|
|
||||||
|
|
||||||
ctags CTAGS:
|
|
||||||
|
|
||||||
cscope cscopelist:
|
|
||||||
|
|
||||||
distdir: $(BUILT_SOURCES)
|
|
||||||
$(MAKE) $(AM_MAKEFLAGS) distdir-am
|
|
||||||
|
|
||||||
distdir-am: $(DISTFILES)
|
|
||||||
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
|
||||||
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
|
||||||
list='$(DISTFILES)'; \
|
|
||||||
dist_files=`for file in $$list; do echo $$file; done | \
|
|
||||||
sed -e "s|^$$srcdirstrip/||;t" \
|
|
||||||
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
|
|
||||||
case $$dist_files in \
|
|
||||||
*/*) $(MKDIR_P) `echo "$$dist_files" | \
|
|
||||||
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
|
|
||||||
sort -u` ;; \
|
|
||||||
esac; \
|
|
||||||
for file in $$dist_files; do \
|
|
||||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
|
||||||
if test -d $$d/$$file; then \
|
|
||||||
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
|
|
||||||
if test -d "$(distdir)/$$file"; then \
|
|
||||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
|
||||||
fi; \
|
|
||||||
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
|
||||||
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
|
|
||||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
|
||||||
fi; \
|
|
||||||
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
|
|
||||||
else \
|
|
||||||
test -f "$(distdir)/$$file" \
|
|
||||||
|| cp -p $$d/$$file "$(distdir)/$$file" \
|
|
||||||
|| exit 1; \
|
|
||||||
fi; \
|
|
||||||
done
|
|
||||||
check-am: all-am
|
|
||||||
check: check-am
|
|
||||||
all-am: Makefile $(MANS)
|
|
||||||
installdirs:
|
|
||||||
for dir in "$(DESTDIR)$(man1dir)"; do \
|
|
||||||
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
|
|
||||||
done
|
|
||||||
install: install-am
|
|
||||||
install-exec: install-exec-am
|
|
||||||
install-data: install-data-am
|
|
||||||
uninstall: uninstall-am
|
|
||||||
|
|
||||||
install-am: all-am
|
|
||||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
|
||||||
|
|
||||||
installcheck: installcheck-am
|
|
||||||
install-strip:
|
|
||||||
if test -z '$(STRIP)'; then \
|
|
||||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
|
||||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
|
||||||
install; \
|
|
||||||
else \
|
|
||||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
|
||||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
|
||||||
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
|
|
||||||
fi
|
|
||||||
mostlyclean-generic:
|
|
||||||
|
|
||||||
clean-generic:
|
|
||||||
|
|
||||||
distclean-generic:
|
|
||||||
-$(am__rm_f) $(CONFIG_CLEAN_FILES)
|
|
||||||
-test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES)
|
|
||||||
|
|
||||||
maintainer-clean-generic:
|
|
||||||
@echo "This command is intended for maintainers to use"
|
|
||||||
@echo "it deletes files that may require special tools to rebuild."
|
|
||||||
clean: clean-am
|
|
||||||
|
|
||||||
clean-am: clean-generic clean-libtool mostlyclean-am
|
|
||||||
|
|
||||||
distclean: distclean-am
|
|
||||||
-rm -f Makefile
|
|
||||||
distclean-am: clean-am distclean-generic
|
|
||||||
|
|
||||||
dvi: dvi-am
|
|
||||||
|
|
||||||
dvi-am:
|
|
||||||
|
|
||||||
html: html-am
|
|
||||||
|
|
||||||
html-am:
|
|
||||||
|
|
||||||
info: info-am
|
|
||||||
|
|
||||||
info-am:
|
|
||||||
|
|
||||||
install-data-am: install-man
|
|
||||||
|
|
||||||
install-dvi: install-dvi-am
|
|
||||||
|
|
||||||
install-dvi-am:
|
|
||||||
|
|
||||||
install-exec-am:
|
|
||||||
|
|
||||||
install-html: install-html-am
|
|
||||||
|
|
||||||
install-html-am:
|
|
||||||
|
|
||||||
install-info: install-info-am
|
|
||||||
|
|
||||||
install-info-am:
|
|
||||||
|
|
||||||
install-man: install-man1
|
|
||||||
|
|
||||||
install-pdf: install-pdf-am
|
|
||||||
|
|
||||||
install-pdf-am:
|
|
||||||
|
|
||||||
install-ps: install-ps-am
|
|
||||||
|
|
||||||
install-ps-am:
|
|
||||||
|
|
||||||
installcheck-am:
|
|
||||||
|
|
||||||
maintainer-clean: maintainer-clean-am
|
|
||||||
-rm -f Makefile
|
|
||||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
|
||||||
|
|
||||||
mostlyclean: mostlyclean-am
|
|
||||||
|
|
||||||
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
|
|
||||||
|
|
||||||
pdf: pdf-am
|
|
||||||
|
|
||||||
pdf-am:
|
|
||||||
|
|
||||||
ps: ps-am
|
|
||||||
|
|
||||||
ps-am:
|
|
||||||
|
|
||||||
uninstall-am: uninstall-man
|
|
||||||
|
|
||||||
uninstall-man: uninstall-man1
|
|
||||||
|
|
||||||
.MAKE: install-am install-strip
|
|
||||||
|
|
||||||
.PHONY: all all-am check check-am clean clean-generic clean-libtool \
|
|
||||||
cscopelist-am ctags-am distclean distclean-generic \
|
|
||||||
distclean-libtool distdir dvi dvi-am html html-am info info-am \
|
|
||||||
install install-am install-data install-data-am install-dvi \
|
|
||||||
install-dvi-am install-exec install-exec-am install-html \
|
|
||||||
install-html-am install-info install-info-am install-man \
|
|
||||||
install-man1 install-pdf install-pdf-am install-ps \
|
|
||||||
install-ps-am install-strip installcheck installcheck-am \
|
|
||||||
installdirs maintainer-clean maintainer-clean-generic \
|
|
||||||
mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
|
|
||||||
ps ps-am tags-am uninstall uninstall-am uninstall-man \
|
|
||||||
uninstall-man1
|
|
||||||
|
|
||||||
.PRECIOUS: Makefile
|
|
||||||
|
|
||||||
|
|
||||||
# Regenerate httrack.1 from the "httrack --help" output and the top-level
|
|
||||||
# README. Run by hand after changing options or help text:
|
|
||||||
# make -C man regen-man
|
|
||||||
# The generated page is committed; this target only refreshes it. Honors
|
|
||||||
# SOURCE_DATE_EPOCH for a reproducible date.
|
|
||||||
regen-man: makeman.sh $(top_builddir)/src/httrack$(EXEEXT)
|
|
||||||
README='$(top_srcdir)/README' $(SHELL) $(srcdir)/makeman.sh \
|
|
||||||
'$(top_builddir)/src/httrack$(EXEEXT)' > $(srcdir)/httrack.1
|
|
||||||
.PHONY: regen-man
|
|
||||||
|
|
||||||
# Render html/httrack.man.html from httrack.1. Needs the groff html device
|
|
||||||
# (Debian: full "groff" package, not "groff-base"). Run by hand: make -C man regen-man-html
|
|
||||||
regen-man-html: httrack.1
|
|
||||||
groff -t -man -Thtml $(srcdir)/httrack.1 > $(top_srcdir)/html/httrack.man.html
|
|
||||||
.PHONY: regen-man-html
|
|
||||||
|
|
||||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
|
||||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
|
||||||
.NOEXPORT:
|
|
||||||
|
|
||||||
# Tell GNU make to disable its built-in pattern rules.
|
|
||||||
%:: %,v
|
|
||||||
%:: RCS/%,v
|
|
||||||
%:: RCS/%
|
|
||||||
%:: s.%
|
|
||||||
%:: SCCS/s.%
|
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" This file is generated by man/makeman.sh; do not edit by hand.
|
.\" This file is generated by man/makeman.sh; do not edit by hand.
|
||||||
.\" SPDX-License-Identifier: GPL-3.0-or-later
|
.\" SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
.TH httrack 1 "13 June 2026" "httrack website copier"
|
.TH httrack 1 "27 June 2026" "httrack website copier"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
httrack \- offline browser : copy websites to a local directory
|
httrack \- offline browser : copy websites to a local directory
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@@ -43,6 +43,7 @@ httrack \- offline browser : copy websites to a local directory
|
|||||||
[ \fB\-x, \-\-replace\-external\fR ]
|
[ \fB\-x, \-\-replace\-external\fR ]
|
||||||
[ \fB\-%x, \-\-disable\-passwords\fR ]
|
[ \fB\-%x, \-\-disable\-passwords\fR ]
|
||||||
[ \fB\-%q, \-\-include\-query\-string\fR ]
|
[ \fB\-%q, \-\-include\-query\-string\fR ]
|
||||||
|
[ \fB\-%g, \-\-strip\-query\fR ]
|
||||||
[ \fB\-o, \-\-generate\-errors\fR ]
|
[ \fB\-o, \-\-generate\-errors\fR ]
|
||||||
[ \fB\-X, \-\-purge\-old[=N]\fR ]
|
[ \fB\-X, \-\-purge\-old[=N]\fR ]
|
||||||
[ \fB\-%p, \-\-preserve\fR ]
|
[ \fB\-%p, \-\-preserve\fR ]
|
||||||
@@ -198,6 +199,8 @@ replace external html links by error pages (\-\-replace\-external)
|
|||||||
do not include any password for external password protected websites (%x0 include) (\-\-disable\-passwords)
|
do not include any password for external password protected websites (%x0 include) (\-\-disable\-passwords)
|
||||||
.IP \-%q
|
.IP \-%q
|
||||||
*include query string for local files (useless, for information purpose only) (%q0 don't include) (\-\-include\-query\-string)
|
*include query string for local files (useless, for information purpose only) (%q0 don't include) (\-\-include\-query\-string)
|
||||||
|
.IP \-%g
|
||||||
|
strip query keys for dedup ([host/pattern=]key1,key2,...) (\-\-strip\-query <param>)
|
||||||
.IP \-o
|
.IP \-o
|
||||||
*generate output html file in case of error (404..) (o0 don't generate) (\-\-generate\-errors)
|
*generate output html file in case of error (404..) (o0 don't generate) (\-\-generate\-errors)
|
||||||
.IP \-X
|
.IP \-X
|
||||||
@@ -225,6 +228,8 @@ tolerant requests (accept bogus responses on some servers, but not standard!) (\
|
|||||||
update hacks: various hacks to limit re\-transfers when updating (identical size, bogus response..) (\-\-updatehack)
|
update hacks: various hacks to limit re\-transfers when updating (identical size, bogus response..) (\-\-updatehack)
|
||||||
.IP \-%u
|
.IP \-%u
|
||||||
url hacks: various hacks to limit duplicate URLs (strip //, www.foo.com==foo.com..) (\-\-urlhack)
|
url hacks: various hacks to limit duplicate URLs (strip //, www.foo.com==foo.com..) (\-\-urlhack)
|
||||||
|
.br
|
||||||
|
opt out of one url\-hack part: \-\-keep\-www\-prefix (www.foo.com<>foo.com), \-\-keep\-double\-slashes (//), \-\-keep\-query\-order (?b&a)
|
||||||
.IP \-%A
|
.IP \-%A
|
||||||
assume that a type (cgi,asp..) is always linked with a mime type (\-%A php3,cgi=text/html;dat,bin=application/x\-zip) (\-\-assume <param>)
|
assume that a type (cgi,asp..) is always linked with a mime type (\-%A php3,cgi=text/html;dat,bin=application/x\-zip) (\-\-assume <param>)
|
||||||
.br
|
.br
|
||||||
@@ -313,12 +318,8 @@ debug HTTP headers in logfile (\-\-debug\-headers)
|
|||||||
.SS Guru options: (do NOT use if possible)
|
.SS Guru options: (do NOT use if possible)
|
||||||
.IP \-#X
|
.IP \-#X
|
||||||
*use optimized engine (limited memory boundary checks) (\-\-fast\-engine)
|
*use optimized engine (limited memory boundary checks) (\-\-fast\-engine)
|
||||||
.IP \-#0
|
.IP \-#test
|
||||||
filter test (\-#0 '*.gif' 'www.bar.com/foo.gif') (\-\-debug\-testfilters <param>)
|
list engine self\-tests (run one with \-#test=NAME [args])
|
||||||
.IP \-#1
|
|
||||||
simplify test (\-#1 ./foo/bar/../foobar)
|
|
||||||
.IP \-#2
|
|
||||||
type test (\-#2 /foo/bar.php)
|
|
||||||
.IP \-#C
|
.IP \-#C
|
||||||
cache list (\-#C '*.com/spider*.gif' (\-\-debug\-cache <param>)
|
cache list (\-#C '*.com/spider*.gif' (\-\-debug\-cache <param>)
|
||||||
.IP \-#R
|
.IP \-#R
|
||||||
|
|||||||
236
missing
236
missing
@@ -1,236 +0,0 @@
|
|||||||
#! /bin/sh
|
|
||||||
# Common wrapper for a few potentially missing GNU and other programs.
|
|
||||||
|
|
||||||
scriptversion=2024-06-07.14; # UTC
|
|
||||||
|
|
||||||
# shellcheck disable=SC2006,SC2268 # we must support pre-POSIX shells
|
|
||||||
|
|
||||||
# Copyright (C) 1996-2024 Free Software Foundation, Inc.
|
|
||||||
# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
|
|
||||||
|
|
||||||
# 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 2, 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 <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
# As a special exception to the GNU General Public License, if you
|
|
||||||
# distribute this file as part of a program that contains a
|
|
||||||
# configuration script generated by Autoconf, you may include it under
|
|
||||||
# the same distribution terms that you use for the rest of that program.
|
|
||||||
|
|
||||||
if test $# -eq 0; then
|
|
||||||
echo 1>&2 "Try '$0 --help' for more information"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
case $1 in
|
|
||||||
|
|
||||||
--is-lightweight)
|
|
||||||
# Used by our autoconf macros to check whether the available missing
|
|
||||||
# script is modern enough.
|
|
||||||
exit 0
|
|
||||||
;;
|
|
||||||
|
|
||||||
--run)
|
|
||||||
# Back-compat with the calling convention used by older automake.
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
|
|
||||||
-h|--h|--he|--hel|--help)
|
|
||||||
echo "\
|
|
||||||
$0 [OPTION]... PROGRAM [ARGUMENT]...
|
|
||||||
|
|
||||||
Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due
|
|
||||||
to PROGRAM being missing or too old.
|
|
||||||
|
|
||||||
Options:
|
|
||||||
-h, --help display this help and exit
|
|
||||||
-v, --version output version information and exit
|
|
||||||
|
|
||||||
Supported PROGRAM values:
|
|
||||||
aclocal autoconf autogen autoheader autom4te automake autoreconf
|
|
||||||
bison flex help2man lex makeinfo perl yacc
|
|
||||||
|
|
||||||
Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and
|
|
||||||
'g' are ignored when checking the name.
|
|
||||||
|
|
||||||
Report bugs to <bug-automake@gnu.org>.
|
|
||||||
GNU Automake home page: <https://www.gnu.org/software/automake/>.
|
|
||||||
General help using GNU software: <https://www.gnu.org/gethelp/>."
|
|
||||||
exit $?
|
|
||||||
;;
|
|
||||||
|
|
||||||
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
|
|
||||||
echo "missing (GNU Automake) $scriptversion"
|
|
||||||
exit $?
|
|
||||||
;;
|
|
||||||
|
|
||||||
-*)
|
|
||||||
echo 1>&2 "$0: unknown '$1' option"
|
|
||||||
echo 1>&2 "Try '$0 --help' for more information"
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
|
|
||||||
esac
|
|
||||||
|
|
||||||
# Run the given program, remember its exit status.
|
|
||||||
"$@"; st=$?
|
|
||||||
|
|
||||||
# If it succeeded, we are done.
|
|
||||||
test $st -eq 0 && exit 0
|
|
||||||
|
|
||||||
# Also exit now if we it failed (or wasn't found), and '--version' was
|
|
||||||
# passed; such an option is passed most likely to detect whether the
|
|
||||||
# program is present and works.
|
|
||||||
case $2 in --version|--help) exit $st;; esac
|
|
||||||
|
|
||||||
# Exit code 63 means version mismatch. This often happens when the user
|
|
||||||
# tries to use an ancient version of a tool on a file that requires a
|
|
||||||
# minimum version.
|
|
||||||
if test $st -eq 63; then
|
|
||||||
msg="probably too old"
|
|
||||||
elif test $st -eq 127; then
|
|
||||||
# Program was missing.
|
|
||||||
msg="missing on your system"
|
|
||||||
else
|
|
||||||
# Program was found and executed, but failed. Give up.
|
|
||||||
exit $st
|
|
||||||
fi
|
|
||||||
|
|
||||||
perl_URL=https://www.perl.org/
|
|
||||||
flex_URL=https://github.com/westes/flex
|
|
||||||
gnu_software_URL=https://www.gnu.org/software
|
|
||||||
|
|
||||||
program_details ()
|
|
||||||
{
|
|
||||||
case $1 in
|
|
||||||
aclocal|automake|autoreconf)
|
|
||||||
echo "The '$1' program is part of the GNU Automake package:"
|
|
||||||
echo "<$gnu_software_URL/automake>"
|
|
||||||
echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:"
|
|
||||||
echo "<$gnu_software_URL/autoconf>"
|
|
||||||
echo "<$gnu_software_URL/m4/>"
|
|
||||||
echo "<$perl_URL>"
|
|
||||||
;;
|
|
||||||
autoconf|autom4te|autoheader)
|
|
||||||
echo "The '$1' program is part of the GNU Autoconf package:"
|
|
||||||
echo "<$gnu_software_URL/autoconf/>"
|
|
||||||
echo "It also requires GNU m4 and Perl in order to run:"
|
|
||||||
echo "<$gnu_software_URL/m4/>"
|
|
||||||
echo "<$perl_URL>"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
:
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
give_advice ()
|
|
||||||
{
|
|
||||||
# Normalize program name to check for.
|
|
||||||
normalized_program=`echo "$1" | sed '
|
|
||||||
s/^gnu-//; t
|
|
||||||
s/^gnu//; t
|
|
||||||
s/^g//; t'`
|
|
||||||
|
|
||||||
printf '%s\n' "'$1' is $msg."
|
|
||||||
|
|
||||||
configure_deps="'configure.ac' or m4 files included by 'configure.ac'"
|
|
||||||
autoheader_deps="'acconfig.h'"
|
|
||||||
automake_deps="'Makefile.am'"
|
|
||||||
aclocal_deps="'acinclude.m4'"
|
|
||||||
case $normalized_program in
|
|
||||||
aclocal*)
|
|
||||||
echo "You should only need it if you modified $aclocal_deps or"
|
|
||||||
echo "$configure_deps."
|
|
||||||
;;
|
|
||||||
autoconf*)
|
|
||||||
echo "You should only need it if you modified $configure_deps."
|
|
||||||
;;
|
|
||||||
autogen*)
|
|
||||||
echo "You should only need it if you modified a '.def' or '.tpl' file."
|
|
||||||
echo "You may want to install the GNU AutoGen package:"
|
|
||||||
echo "<$gnu_software_URL/autogen/>"
|
|
||||||
;;
|
|
||||||
autoheader*)
|
|
||||||
echo "You should only need it if you modified $autoheader_deps or"
|
|
||||||
echo "$configure_deps."
|
|
||||||
;;
|
|
||||||
automake*)
|
|
||||||
echo "You should only need it if you modified $automake_deps or"
|
|
||||||
echo "$configure_deps."
|
|
||||||
;;
|
|
||||||
autom4te*)
|
|
||||||
echo "You might have modified some maintainer files that require"
|
|
||||||
echo "the 'autom4te' program to be rebuilt."
|
|
||||||
;;
|
|
||||||
autoreconf*)
|
|
||||||
echo "You should only need it if you modified $aclocal_deps or"
|
|
||||||
echo "$automake_deps or $autoheader_deps or $automake_deps or"
|
|
||||||
echo "$configure_deps."
|
|
||||||
;;
|
|
||||||
bison*|yacc*)
|
|
||||||
echo "You should only need it if you modified a '.y' file."
|
|
||||||
echo "You may want to install the GNU Bison package:"
|
|
||||||
echo "<$gnu_software_URL/bison/>"
|
|
||||||
;;
|
|
||||||
help2man*)
|
|
||||||
echo "You should only need it if you modified a dependency" \
|
|
||||||
"of a man page."
|
|
||||||
echo "You may want to install the GNU Help2man package:"
|
|
||||||
echo "<$gnu_software_URL/help2man/>"
|
|
||||||
;;
|
|
||||||
lex*|flex*)
|
|
||||||
echo "You should only need it if you modified a '.l' file."
|
|
||||||
echo "You may want to install the Fast Lexical Analyzer package:"
|
|
||||||
echo "<$flex_URL>"
|
|
||||||
;;
|
|
||||||
makeinfo*)
|
|
||||||
echo "You should only need it if you modified a '.texi' file, or"
|
|
||||||
echo "any other file indirectly affecting the aspect of the manual."
|
|
||||||
echo "You might want to install the Texinfo package:"
|
|
||||||
echo "<$gnu_software_URL/texinfo/>"
|
|
||||||
echo "The spurious makeinfo call might also be the consequence of"
|
|
||||||
echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might"
|
|
||||||
echo "want to install GNU make:"
|
|
||||||
echo "<$gnu_software_URL/make/>"
|
|
||||||
;;
|
|
||||||
perl*)
|
|
||||||
echo "You should only need it to run GNU Autoconf, GNU Automake, "
|
|
||||||
echo " assorted other tools, or if you modified a Perl source file."
|
|
||||||
echo "You may want to install the Perl 5 language interpreter:"
|
|
||||||
echo "<$perl_URL>"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "You might have modified some files without having the proper"
|
|
||||||
echo "tools for further handling them. Check the 'README' file, it"
|
|
||||||
echo "often tells you about the needed prerequisites for installing"
|
|
||||||
echo "this package. You may also peek at any GNU archive site, in"
|
|
||||||
echo "case some other package contains this missing '$1' program."
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
program_details "$normalized_program"
|
|
||||||
}
|
|
||||||
|
|
||||||
give_advice "$1" | sed -e '1s/^/WARNING: /' \
|
|
||||||
-e '2,$s/^/ /' >&2
|
|
||||||
|
|
||||||
# Propagate the correct exit status (expected to be 127 for a program
|
|
||||||
# not found, 63 for a program that failed due to version mismatch).
|
|
||||||
exit $st
|
|
||||||
|
|
||||||
# Local variables:
|
|
||||||
# eval: (add-hook 'before-save-hook 'time-stamp)
|
|
||||||
# time-stamp-start: "scriptversion="
|
|
||||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
|
||||||
# time-stamp-time-zone: "UTC0"
|
|
||||||
# time-stamp-end: "; # UTC"
|
|
||||||
# End:
|
|
||||||
@@ -56,7 +56,7 @@ whttrackrundir = $(bindir)
|
|||||||
whttrackrun_SCRIPTS = webhttrack
|
whttrackrun_SCRIPTS = webhttrack
|
||||||
|
|
||||||
libhttrack_la_SOURCES = htscore.c htsparse.c htsback.c htscache.c \
|
libhttrack_la_SOURCES = htscore.c htsparse.c htsback.c htscache.c \
|
||||||
htscache_selftest.c \
|
htscache_selftest.c htsdns_selftest.c htsselftest.c \
|
||||||
htscatchurl.c htsfilters.c htsftp.c htshash.c coucal/coucal.c \
|
htscatchurl.c htsfilters.c htsftp.c htshash.c coucal/coucal.c \
|
||||||
htshelp.c htslib.c htscoremain.c \
|
htshelp.c htslib.c htscoremain.c \
|
||||||
htsname.c htsrobots.c htstools.c htswizard.c \
|
htsname.c htsrobots.c htstools.c htswizard.c \
|
||||||
@@ -66,7 +66,7 @@ libhttrack_la_SOURCES = htscore.c htsparse.c htsback.c htscache.c \
|
|||||||
md5.c \
|
md5.c \
|
||||||
minizip/ioapi.c minizip/mztools.c minizip/unzip.c minizip/zip.c \
|
minizip/ioapi.c minizip/mztools.c minizip/unzip.c minizip/zip.c \
|
||||||
hts-indextmpl.h htsalias.h htsback.h htsbase.h htssafe.h \
|
hts-indextmpl.h htsalias.h htsback.h htsbase.h htssafe.h \
|
||||||
htsbasenet.h htsbauth.h htscache.h htscache_selftest.h htscatchurl.h \
|
htsbasenet.h htsbauth.h htscache.h htscache_selftest.h htsdns_selftest.h htsselftest.h htscatchurl.h \
|
||||||
htsconfig.h htscore.h htsparse.h htscoremain.h htsdefines.h \
|
htsconfig.h htscore.h htsparse.h htscoremain.h htsdefines.h \
|
||||||
htsfilters.h htsftp.h htsglobal.h htshash.h coucal/coucal.h \
|
htsfilters.h htsftp.h htsglobal.h htshash.h coucal/coucal.h \
|
||||||
htshelp.h htsindex.h htslib.h htsmd5.h \
|
htshelp.h htsindex.h htslib.h htsmd5.h \
|
||||||
|
|||||||
1652
src/Makefile.in
1652
src/Makefile.in
File diff suppressed because it is too large
Load Diff
@@ -41,25 +41,6 @@ Please visit our Website: http://www.httrack.com
|
|||||||
|
|
||||||
#define _NOT_NULL(a) ( (a!=NULL) ? (a) : "" )
|
#define _NOT_NULL(a) ( (a!=NULL) ? (a) : "" )
|
||||||
|
|
||||||
// COPY OF cmdl_ins in htscoremain.c
|
|
||||||
/* Bytes left in x_argvblk from offset ptr. The offset can in principle outrun
|
|
||||||
the block (alias/doit.log expansion), so the copy aborts cleanly instead of
|
|
||||||
the subtraction wrapping to a huge unbounded size. */
|
|
||||||
#define cmdl_room(bufsize, ptr) \
|
|
||||||
((ptr) < (size_t) (bufsize) ? (size_t) (bufsize) - (ptr) : 0)
|
|
||||||
// Insert a command in the argc/argv (buff has total capacity bufsize)
|
|
||||||
#define cmdl_ins(token, argc, argv, buff, bufsize, ptr) \
|
|
||||||
{ \
|
|
||||||
int i; \
|
|
||||||
for (i = argc; i > 0; i--) \
|
|
||||||
argv[i] = argv[i - 1]; \
|
|
||||||
} \
|
|
||||||
argv[0] = (buff + ptr); \
|
|
||||||
strlcpybuff(argv[0], token, cmdl_room(bufsize, ptr)); \
|
|
||||||
ptr += (int) (strlen(argv[0]) + 1); \
|
|
||||||
argc++
|
|
||||||
// END OF COPY OF cmdl_ins in htscoremain.c
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Aliases for command-line and config file definitions
|
Aliases for command-line and config file definitions
|
||||||
These definitions can be used:
|
These definitions can be used:
|
||||||
@@ -79,6 +60,9 @@ Please visit our Website: http://www.httrack.com
|
|||||||
param1 : this option must be alone, and needs one distinct parameter (-P <path>)
|
param1 : this option must be alone, and needs one distinct parameter (-P <path>)
|
||||||
param0 : this option must be alone, but the parameter should be put together (+*.gif)
|
param0 : this option must be alone, but the parameter should be put together (+*.gif)
|
||||||
*/
|
*/
|
||||||
|
/* clang-format off: hand-aligned table; clang-format reflows the whole
|
||||||
|
initializer (2->4 space) on any edit, churning every untouched row. */
|
||||||
|
/* clang-format off */
|
||||||
const char *hts_optalias[][4] = {
|
const char *hts_optalias[][4] = {
|
||||||
/* {"","","",""}, */
|
/* {"","","",""}, */
|
||||||
{"path", "-O", "param1", "output path"},
|
{"path", "-O", "param1", "output path"},
|
||||||
@@ -126,6 +110,8 @@ const char *hts_optalias[][4] = {
|
|||||||
{"disable-passwords", "-%x", "single", ""}, {"disable-password", "-%x",
|
{"disable-passwords", "-%x", "single", ""}, {"disable-password", "-%x",
|
||||||
"single", ""},
|
"single", ""},
|
||||||
{"include-query-string", "-%q", "single", ""},
|
{"include-query-string", "-%q", "single", ""},
|
||||||
|
{"strip-query", "-%g", "param1",
|
||||||
|
"strip [host/pattern=]key1,key2,... from URLs"},
|
||||||
{"generate-errors", "-o", "single", ""},
|
{"generate-errors", "-o", "single", ""},
|
||||||
{"do-not-generate-errors", "-o0", "single", ""},
|
{"do-not-generate-errors", "-o0", "single", ""},
|
||||||
{"purge-old", "-X", "param", ""},
|
{"purge-old", "-X", "param", ""},
|
||||||
@@ -142,6 +128,9 @@ const char *hts_optalias[][4] = {
|
|||||||
{"tolerant", "-%B", "single", ""},
|
{"tolerant", "-%B", "single", ""},
|
||||||
{"updatehack", "-%s", "single", ""}, {"sizehack", "-%s", "single", ""},
|
{"updatehack", "-%s", "single", ""}, {"sizehack", "-%s", "single", ""},
|
||||||
{"urlhack", "-%u", "single", ""},
|
{"urlhack", "-%u", "single", ""},
|
||||||
|
{"keep-www-prefix", "-%j", "single", ""},
|
||||||
|
{"keep-double-slashes", "-%o", "single", ""},
|
||||||
|
{"keep-query-order", "-%y", "single", ""},
|
||||||
{"user-agent", "-F", "param1", "user-agent identity"},
|
{"user-agent", "-F", "param1", "user-agent identity"},
|
||||||
{"referer", "-%R", "param1", "default referer URL"},
|
{"referer", "-%R", "param1", "default referer URL"},
|
||||||
{"from", "-%E", "param1", "from email address"},
|
{"from", "-%E", "param1", "from email address"},
|
||||||
@@ -260,6 +249,7 @@ const char *hts_optalias[][4] = {
|
|||||||
|
|
||||||
{"", "", "", ""}
|
{"", "", "", ""}
|
||||||
};
|
};
|
||||||
|
/* clang-format on */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Check for alias in command-line
|
Check for alias in command-line
|
||||||
|
|||||||
@@ -52,6 +52,34 @@ const char *opttype_value(int p);
|
|||||||
const char *opthelp_value(int p);
|
const char *opthelp_value(int p);
|
||||||
const char *hts_gethome(void);
|
const char *hts_gethome(void);
|
||||||
void expand_home(String * str);
|
void expand_home(String * str);
|
||||||
|
|
||||||
|
/* Command-line argv-block builders, shared by htscoremain.c (the CLI parser)
|
||||||
|
and htsalias.c (config-file alias expansion). Tokens are packed back-to-back
|
||||||
|
into x_argvblk (total capacity bufsize); each argv[] entry points into the
|
||||||
|
block. cmdl_room bounds every copy: the running offset ptr can outrun the
|
||||||
|
block (alias / doit.log expansion outpacing the +32768 slack), so it yields
|
||||||
|
0 rather than a wrapped size_t and the bounded copy aborts cleanly. */
|
||||||
|
#define cmdl_room(bufsize, ptr) \
|
||||||
|
((ptr) < (size_t) (bufsize) ? (size_t) (bufsize) - (ptr) : 0)
|
||||||
|
|
||||||
|
/* Append a token as a new argv[argc]. */
|
||||||
|
#define cmdl_add(token, argc, argv, buff, bufsize, ptr) \
|
||||||
|
argv[argc] = (buff + ptr); \
|
||||||
|
strlcpybuff(argv[argc], token, cmdl_room(bufsize, ptr)); \
|
||||||
|
ptr += (int) (strlen(argv[argc]) + 1); \
|
||||||
|
argc++
|
||||||
|
|
||||||
|
/* Insert a token at argv[0], shifting the existing argc entries up by one. */
|
||||||
|
#define cmdl_ins(token, argc, argv, buff, bufsize, ptr) \
|
||||||
|
{ \
|
||||||
|
int i; \
|
||||||
|
for (i = argc; i > 0; i--) \
|
||||||
|
argv[i] = argv[i - 1]; \
|
||||||
|
} \
|
||||||
|
argv[0] = (buff + ptr); \
|
||||||
|
strlcpybuff(argv[0], token, cmdl_room(bufsize, ptr)); \
|
||||||
|
ptr += (int) (strlen(argv[0]) + 1); \
|
||||||
|
argc++
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
151
src/htsarrays.h
151
src/htsarrays.h
@@ -30,6 +30,12 @@ Please visit our Website: http://www.httrack.com
|
|||||||
/* Author: Xavier Roche */
|
/* Author: Xavier Roche */
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
|
||||||
|
/** @file htsarrays.h
|
||||||
|
* Header-only generic dynamic array (a typed growable vector). All operations
|
||||||
|
* are macros parameterized by the array lvalue A; the element type T is fixed
|
||||||
|
* by the struct TypedArray(T) declares. Counts and capacities are in
|
||||||
|
* elements, not bytes. The array owns its backing store: grow it via the Add/
|
||||||
|
* Append/EnsureRoom macros and release it with TypedArrayFree. */
|
||||||
#ifndef HTS_ARRAYS_DEFSTATIC
|
#ifndef HTS_ARRAYS_DEFSTATIC
|
||||||
#define HTS_ARRAYS_DEFSTATIC
|
#define HTS_ARRAYS_DEFSTATIC
|
||||||
|
|
||||||
@@ -39,111 +45,118 @@ Please visit our Website: http://www.httrack.com
|
|||||||
|
|
||||||
#include "htssafe.h"
|
#include "htssafe.h"
|
||||||
|
|
||||||
/* Memory allocation assertion failure */
|
/* Abort (with the failed byte count) when a growth allocation fails. The
|
||||||
|
array macros never return an out-of-memory error; they assert and abort. */
|
||||||
static void hts_record_assert_memory_failed(const size_t size) {
|
static void hts_record_assert_memory_failed(const size_t size) {
|
||||||
fprintf(stderr, "memory allocation failed (%lu bytes)", \
|
fprintf(stderr, "memory allocation failed (%lu bytes)", (long int) size);
|
||||||
(long int) size); \
|
assertf(!"memory allocation failed");
|
||||||
assertf(! "memory allocation failed"); \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Dynamic array of T elements. **/
|
/** Dynamic array of T elements. **/
|
||||||
#define TypedArray(T) \
|
#define TypedArray(T) \
|
||||||
struct { \
|
struct { \
|
||||||
/** Elements. **/ \
|
/** Elements. **/ \
|
||||||
union { \
|
union { \
|
||||||
/** Typed. **/ \
|
/** Typed. **/ \
|
||||||
T* elts; \
|
T *elts; \
|
||||||
/** Opaque. **/ \
|
/** Opaque. **/ \
|
||||||
void* ptr; \
|
void *ptr; \
|
||||||
} data; \
|
} data; \
|
||||||
/** Count. **/ \
|
/** Count. **/ \
|
||||||
size_t size; \
|
size_t size; \
|
||||||
/** Capacity. **/ \
|
/** Capacity. **/ \
|
||||||
size_t capa; \
|
size_t capa; \
|
||||||
}
|
}
|
||||||
#define EMPTY_TYPED_ARRAY { { NULL }, 0, 0 }
|
|
||||||
|
/** Initializer for an empty array (no backing store, size and capacity 0). **/
|
||||||
|
#define EMPTY_TYPED_ARRAY {{NULL}, 0, 0}
|
||||||
|
|
||||||
/** Array size, in elements. **/
|
/** Array size, in elements. **/
|
||||||
#define TypedArraySize(A) ((A).size)
|
#define TypedArraySize(A) ((A).size)
|
||||||
|
|
||||||
/** Array capacity, in elements. **/
|
/** Array capacity, in elements. **/
|
||||||
#define TypedArrayCapa(A) ((A).capa)
|
#define TypedArrayCapa(A) ((A).capa)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remaining free space, in elements.
|
* Remaining free space, in elements.
|
||||||
* Macro, first element evaluated multiple times.
|
* Macro, first element evaluated multiple times.
|
||||||
**/
|
**/
|
||||||
#define TypedArrayRoom(A) ( TypedArrayCapa(A) - TypedArraySize(A) )
|
#define TypedArrayRoom(A) (TypedArrayCapa(A) - TypedArraySize(A))
|
||||||
|
|
||||||
/** Array elements, of type T*. **/
|
/** Array elements, of type T*. **/
|
||||||
#define TypedArrayElts(A) ((A).data.elts)
|
#define TypedArrayElts(A) ((A).data.elts)
|
||||||
|
|
||||||
/** Array pointer, of type void*. **/
|
/** Array pointer, of type void*. **/
|
||||||
#define TypedArrayPtr(A) ((A).data.ptr)
|
#define TypedArrayPtr(A) ((A).data.ptr)
|
||||||
|
|
||||||
/** Size of T. **/
|
/** Size of T. **/
|
||||||
#define TypedArrayWidth(A) (sizeof(*TypedArrayElts(A)))
|
#define TypedArrayWidth(A) (sizeof(*TypedArrayElts(A)))
|
||||||
|
|
||||||
/** Nth element of the array. **/
|
/** Nth element of the array, as an lvalue. No bounds check; N must be
|
||||||
|
< TypedArraySize(A). **/
|
||||||
#define TypedArrayNth(A, N) (TypedArrayElts(A)[N])
|
#define TypedArrayNth(A, N) (TypedArrayElts(A)[N])
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tail of the array (outside the array).
|
* Tail of the array (outside the array).
|
||||||
* The returned pointer points to the beginning of TypedArrayRoom(A)
|
* The returned pointer points to the beginning of TypedArrayRoom(A)
|
||||||
* free elements.
|
* free elements.
|
||||||
**/
|
**/
|
||||||
#define TypedArrayTail(A) (TypedArrayNth(A, TypedArraySize(A)))
|
#define TypedArrayTail(A) (TypedArrayNth(A, TypedArraySize(A)))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ensure at least 'ROOM' elements can be put in the remaining space.
|
* Ensure at least 'ROOM' elements can be put in the remaining space.
|
||||||
* After a call to this macro, TypedArrayRoom(A) is guaranteed to be at
|
* After a call to this macro, TypedArrayRoom(A) is guaranteed to be at
|
||||||
* least equal to 'ROOM'.
|
* least equal to 'ROOM'.
|
||||||
**/
|
**/
|
||||||
#define TypedArrayEnsureRoom(A, ROOM) do { \
|
#define TypedArrayEnsureRoom(A, ROOM) \
|
||||||
const size_t room_ = (ROOM); \
|
do { \
|
||||||
while (TypedArrayRoom(A) < room_) { \
|
const size_t room_ = (ROOM); \
|
||||||
TypedArrayCapa(A) = TypedArrayCapa(A) < 16 ? 16 : TypedArrayCapa(A) * 2; \
|
while (TypedArrayRoom(A) < room_) { \
|
||||||
} \
|
TypedArrayCapa(A) = TypedArrayCapa(A) < 16 ? 16 : TypedArrayCapa(A) * 2; \
|
||||||
TypedArrayPtr(A) = realloc(TypedArrayPtr(A), \
|
} \
|
||||||
TypedArrayCapa(A)*TypedArrayWidth(A)); \
|
TypedArrayPtr(A) = \
|
||||||
if (TypedArrayPtr(A) == NULL) { \
|
realloc(TypedArrayPtr(A), TypedArrayCapa(A) * TypedArrayWidth(A)); \
|
||||||
hts_record_assert_memory_failed(TypedArrayCapa(A)*TypedArrayWidth(A)); \
|
if (TypedArrayPtr(A) == NULL) { \
|
||||||
} \
|
hts_record_assert_memory_failed(TypedArrayCapa(A) * TypedArrayWidth(A)); \
|
||||||
} while(0)
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
/** Add an element. Macro, first element evaluated multiple times. **/
|
/** Add an element. Macro, first element evaluated multiple times. **/
|
||||||
#define TypedArrayAdd(A, E) do { \
|
#define TypedArrayAdd(A, E) \
|
||||||
TypedArrayEnsureRoom(A, 1); \
|
do { \
|
||||||
assertf(TypedArraySize(A) < TypedArrayCapa(A)); \
|
TypedArrayEnsureRoom(A, 1); \
|
||||||
TypedArrayTail(A) = (E); \
|
assertf(TypedArraySize(A) < TypedArrayCapa(A)); \
|
||||||
TypedArraySize(A)++; \
|
TypedArrayTail(A) = (E); \
|
||||||
} while(0)
|
TypedArraySize(A)++; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add 'COUNT' elements from 'PTR'.
|
* Add 'COUNT' elements from 'PTR'.
|
||||||
* Macro, first element evaluated multiple times.
|
* Macro, first element evaluated multiple times.
|
||||||
**/
|
**/
|
||||||
#define TypedArrayAppend(A, PTR, COUNT) do { \
|
#define TypedArrayAppend(A, PTR, COUNT) \
|
||||||
const size_t count_ = (COUNT); \
|
do { \
|
||||||
/* This 1-case is to benefit from type safety. */ \
|
const size_t count_ = (COUNT); \
|
||||||
if (count_ == 1) { \
|
/* This 1-case is to benefit from type safety. */ \
|
||||||
TypedArrayAdd(A, *(PTR)); \
|
if (count_ == 1) { \
|
||||||
} else { \
|
TypedArrayAdd(A, *(PTR)); \
|
||||||
const void *const source_ = (PTR); \
|
} else { \
|
||||||
TypedArrayEnsureRoom(A, count_); \
|
const void *const source_ = (PTR); \
|
||||||
assertf(count_ <= TypedArrayRoom(A)); \
|
TypedArrayEnsureRoom(A, count_); \
|
||||||
memcpy(&TypedArrayTail(A), source_, count_ * TypedArrayWidth(A)); \
|
assertf(count_ <= TypedArrayRoom(A)); \
|
||||||
TypedArraySize(A) += count_; \
|
memcpy(&TypedArrayTail(A), source_, count_ *TypedArrayWidth(A)); \
|
||||||
} \
|
TypedArraySize(A) += count_; \
|
||||||
} while(0)
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
/** Clear an array, freeing memory and clearing size and capacity. **/
|
/** Clear an array, freeing memory and clearing size and capacity. **/
|
||||||
#define TypedArrayFree(A) do { \
|
#define TypedArrayFree(A) \
|
||||||
if (TypedArrayPtr(A) != NULL) { \
|
do { \
|
||||||
TypedArrayCapa(A) = TypedArraySize(A) = 0; \
|
if (TypedArrayPtr(A) != NULL) { \
|
||||||
free(TypedArrayPtr(A)); \
|
TypedArrayCapa(A) = TypedArraySize(A) = 0; \
|
||||||
TypedArrayPtr(A) = NULL; \
|
free(TypedArrayPtr(A)); \
|
||||||
} \
|
TypedArrayPtr(A) = NULL; \
|
||||||
} while(0)
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
301
src/htsback.c
301
src/htsback.c
@@ -57,7 +57,10 @@ Please visit our Website: http://www.httrack.com
|
|||||||
// DOS
|
// DOS
|
||||||
#include <process.h> /* _beginthread, _endthread */
|
#include <process.h> /* _beginthread, _endthread */
|
||||||
#endif
|
#endif
|
||||||
|
#include <io.h> /* _chsize_s */
|
||||||
|
#define HTS_FTRUNCATE(fp, sz) _chsize_s(_fileno(fp), (sz))
|
||||||
#else
|
#else
|
||||||
|
#define HTS_FTRUNCATE(fp, sz) ftruncate(fileno(fp), (sz))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define VT_CLREOL "\33[K"
|
#define VT_CLREOL "\33[K"
|
||||||
@@ -73,6 +76,8 @@ struct_back *back_new(httrackp *opt, int back_max) {
|
|||||||
|
|
||||||
sback->count = back_max;
|
sback->count = back_max;
|
||||||
sback->lnk = (lien_back *) calloct((back_max + 1), sizeof(lien_back));
|
sback->lnk = (lien_back *) calloct((back_max + 1), sizeof(lien_back));
|
||||||
|
sback->connect_fallback = (hts_connect_fallback *) calloct(
|
||||||
|
(back_max + 1), sizeof(hts_connect_fallback));
|
||||||
sback->ready = coucal_new(0);
|
sback->ready = coucal_new(0);
|
||||||
hts_set_hash_handler(sback->ready, opt);
|
hts_set_hash_handler(sback->ready, opt);
|
||||||
coucal_set_name(sback->ready, "back_new");
|
coucal_set_name(sback->ready, "back_new");
|
||||||
@@ -83,6 +88,7 @@ struct_back *back_new(httrackp *opt, int back_max) {
|
|||||||
sback->lnk[i].r.location = sback->lnk[i].location_buffer;
|
sback->lnk[i].r.location = sback->lnk[i].location_buffer;
|
||||||
sback->lnk[i].status = STATUS_FREE;
|
sback->lnk[i].status = STATUS_FREE;
|
||||||
sback->lnk[i].r.soc = INVALID_SOCKET;
|
sback->lnk[i].r.soc = INVALID_SOCKET;
|
||||||
|
sback->connect_fallback[i].addr_count = -1; // not yet probed
|
||||||
}
|
}
|
||||||
return sback;
|
return sback;
|
||||||
}
|
}
|
||||||
@@ -93,6 +99,7 @@ void back_free(struct_back ** sback) {
|
|||||||
freet((*sback)->lnk);
|
freet((*sback)->lnk);
|
||||||
(*sback)->lnk = NULL;
|
(*sback)->lnk = NULL;
|
||||||
}
|
}
|
||||||
|
freet((*sback)->connect_fallback);
|
||||||
if ((*sback)->ready != NULL) {
|
if ((*sback)->ready != NULL) {
|
||||||
coucal_delete(&(*sback)->ready);
|
coucal_delete(&(*sback)->ready);
|
||||||
(*sback)->ready_size_bytes = 0;
|
(*sback)->ready_size_bytes = 0;
|
||||||
@@ -102,6 +109,72 @@ void back_free(struct_back ** sback) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Per-candidate connect deadline cap (seconds): a connecting slot with another
|
||||||
|
address to try waits at most this long before falling back, instead of the
|
||||||
|
full (default 120s) slot timeout. Caps the dead-IPv6 stall while staying well
|
||||||
|
above a normal handshake. The last candidate still gets the full timeout. */
|
||||||
|
#define HTS_CONNECT_FALLBACK_TIMEOUT 10
|
||||||
|
|
||||||
|
int back_connect_fallback_due(int addr_index, int addr_count, int elapsed,
|
||||||
|
int timeout) {
|
||||||
|
int deadline;
|
||||||
|
|
||||||
|
if (addr_index + 1 >= addr_count) // last (or only) candidate: no fallback
|
||||||
|
return 0;
|
||||||
|
if (timeout <= 0) // no timeout management: never force it
|
||||||
|
return 0;
|
||||||
|
deadline = (timeout < HTS_CONNECT_FALLBACK_TIMEOUT)
|
||||||
|
? timeout
|
||||||
|
: HTS_CONNECT_FALLBACK_TIMEOUT;
|
||||||
|
return elapsed >= deadline;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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. */
|
||||||
|
static int connect_socket_error(T_SOC soc) {
|
||||||
|
int soerr = 0;
|
||||||
|
socklen_t len = (socklen_t) sizeof(soerr);
|
||||||
|
|
||||||
|
if (getsockopt(soc, SOL_SOCKET, SO_ERROR, (char *) &soerr, &len) != 0)
|
||||||
|
return -1;
|
||||||
|
return soerr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Retry a stuck/failed connecting slot against its next resolved address.
|
||||||
|
Closes the current socket and starts a non-blocking connect to the next
|
||||||
|
candidate, leaving the slot in STATUS_CONNECTING. Returns 1 if a new connect
|
||||||
|
was started, 0 if no fallback address remains (caller fails the slot). */
|
||||||
|
static int back_connect_next(httrackp *opt, struct_back *sback, int i) {
|
||||||
|
hts_connect_fallback *const cf = &sback->connect_fallback[i];
|
||||||
|
lien_back *const back = sback->lnk;
|
||||||
|
const int next = cf->addr_index + 1;
|
||||||
|
T_SOC soc;
|
||||||
|
|
||||||
|
if (next >= cf->addr_count)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (back[i].r.soc != INVALID_SOCKET) {
|
||||||
|
deletehttp(&back[i].r);
|
||||||
|
back[i].r.soc = INVALID_SOCKET;
|
||||||
|
}
|
||||||
|
soc = newhttp_addr(opt, back[i].url_adr, &back[i].r, -1, 0, next, NULL);
|
||||||
|
if (soc == INVALID_SOCKET)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
back[i].r.soc = soc;
|
||||||
|
cf->addr_index = next;
|
||||||
|
cf->connect_start = time_local();
|
||||||
|
if (back[i].timeout > 0)
|
||||||
|
back[i].timeout_refresh = cf->connect_start;
|
||||||
|
back[i].status = STATUS_CONNECTING;
|
||||||
|
hts_log_print(opt, LOG_DEBUG,
|
||||||
|
"connect failed, trying next address (%d/%d) for %s", next + 1,
|
||||||
|
cf->addr_count, back[i].url_adr);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
void back_delete_all(httrackp * opt, cache_back * cache, struct_back * sback) {
|
void back_delete_all(httrackp * opt, cache_back * cache, struct_back * sback) {
|
||||||
if (sback != NULL) {
|
if (sback != NULL) {
|
||||||
int i;
|
int i;
|
||||||
@@ -1911,8 +1984,11 @@ int back_add(struct_back * sback, httrackp * opt, cache_back * cache, const char
|
|||||||
// ouvrir liaison, envoyer requète
|
// ouvrir liaison, envoyer requète
|
||||||
// ne pas traiter ou recevoir l'en tête immédiatement
|
// ne pas traiter ou recevoir l'en tête immédiatement
|
||||||
hts_init_htsblk(&back[p].r);
|
hts_init_htsblk(&back[p].r);
|
||||||
//memset(&(back[p].r), 0, sizeof(htsblk));
|
// memset(&(back[p].r), 0, sizeof(htsblk));
|
||||||
back[p].r.location = back[p].location_buffer;
|
back[p].r.location = back[p].location_buffer;
|
||||||
|
// fresh connect: address list not yet probed, start at the first
|
||||||
|
sback->connect_fallback[p].addr_index = 0;
|
||||||
|
sback->connect_fallback[p].addr_count = -1;
|
||||||
// recopier proxy
|
// recopier proxy
|
||||||
if ((back[p].r.req.proxy.active = opt->proxy.active)) {
|
if ((back[p].r.req.proxy.active = opt->proxy.active)) {
|
||||||
if (StringBuff(opt->proxy.bindhost) != NULL)
|
if (StringBuff(opt->proxy.bindhost) != NULL)
|
||||||
@@ -2369,21 +2445,25 @@ void back_wait(struct_back * sback, httrackp * opt, cache_back * cache,
|
|||||||
// en cas de gestion du connect préemptif
|
// en cas de gestion du connect préemptif
|
||||||
#if HTS_XCONN
|
#if HTS_XCONN
|
||||||
if (back[i].status == STATUS_CONNECTING) { // connexion
|
if (back[i].status == STATUS_CONNECTING) { // connexion
|
||||||
do_wait = 1;
|
// a connecting slot always carries a live socket; guard anyway so a
|
||||||
|
// stray INVALID_SOCKET can never reach FD_SET (mirrors the recv branch)
|
||||||
|
if (back[i].r.soc != INVALID_SOCKET) {
|
||||||
|
do_wait = 1;
|
||||||
|
|
||||||
// noter socket write
|
// noter socket write
|
||||||
FD_SET(back[i].r.soc, &fds_c);
|
FD_SET(back[i].r.soc, &fds_c);
|
||||||
|
|
||||||
// noter socket erreur
|
// noter socket erreur
|
||||||
FD_SET(back[i].r.soc, &fds_e);
|
FD_SET(back[i].r.soc, &fds_e);
|
||||||
|
|
||||||
// calculer max
|
// calculer max
|
||||||
if (max_c) {
|
if (max_c) {
|
||||||
max_c = 0;
|
max_c = 0;
|
||||||
nfds = back[i].r.soc;
|
nfds = back[i].r.soc;
|
||||||
} else if (back[i].r.soc > nfds) {
|
} else if (back[i].r.soc > nfds) {
|
||||||
// ID socket la plus élevée
|
// ID socket la plus élevée
|
||||||
nfds = back[i].r.soc;
|
nfds = back[i].r.soc;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else
|
} else
|
||||||
@@ -2517,8 +2597,20 @@ void back_wait(struct_back * sback, httrackp * opt, cache_back * cache,
|
|||||||
}
|
}
|
||||||
// ---- FLAG WRITE MIS A UN?: POUR LE CONNECT
|
// ---- FLAG WRITE MIS A UN?: POUR LE CONNECT
|
||||||
if (back[i].status == STATUS_CONNECTING) { // attendre connect
|
if (back[i].status == STATUS_CONNECTING) { // attendre connect
|
||||||
|
hts_connect_fallback *const cf = &sback->connect_fallback[i];
|
||||||
int dispo = 0;
|
int dispo = 0;
|
||||||
|
|
||||||
|
// probe the resolved address list once per fresh connect (cache hit:
|
||||||
|
// the host was resolved when this connect was opened)
|
||||||
|
if (cf->addr_count < 0 && back[i].r.soc != INVALID_SOCKET &&
|
||||||
|
!back[i].r.is_file) {
|
||||||
|
SOCaddr scratch[HTS_MAXADDRNUM];
|
||||||
|
|
||||||
|
cf->addr_count = hts_dns_resolve_all(opt, back[i].url_adr, scratch,
|
||||||
|
HTS_MAXADDRNUM, NULL);
|
||||||
|
cf->connect_start = time_local();
|
||||||
|
}
|
||||||
|
|
||||||
// vérifier l'existance de timeout-check
|
// vérifier l'existance de timeout-check
|
||||||
if (!gestion_timeout)
|
if (!gestion_timeout)
|
||||||
if (back[i].timeout > 0)
|
if (back[i].timeout > 0)
|
||||||
@@ -2526,14 +2618,45 @@ void back_wait(struct_back * sback, httrackp * opt, cache_back * cache,
|
|||||||
|
|
||||||
// connecté?
|
// connecté?
|
||||||
dispo = FD_ISSET(back[i].r.soc, &fds_c);
|
dispo = FD_ISSET(back[i].r.soc, &fds_c);
|
||||||
if (dispo) { // ok connected!!
|
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)
|
||||||
|
if (connect_socket_error(back[i].r.soc) != 0) {
|
||||||
|
if (!back_connect_next(opt, sback, i)) {
|
||||||
|
deletehttp(&back[i].r);
|
||||||
|
back[i].r.soc = INVALID_SOCKET;
|
||||||
|
back[i].r.statuscode = STATUSCODE_CONNERROR;
|
||||||
|
strcpybuff(back[i].r.msg, "Connect Error");
|
||||||
|
back[i].status = STATUS_READY;
|
||||||
|
back_set_finished(sback, i);
|
||||||
|
}
|
||||||
|
continue; // reconnected (stay connecting) or failed
|
||||||
|
}
|
||||||
busy_state = 1;
|
busy_state = 1;
|
||||||
|
|
||||||
#if HTS_USEOPENSSL
|
#if HTS_USEOPENSSL
|
||||||
/* SSL mode */
|
/* SSL mode */
|
||||||
if (back[i].r.ssl) {
|
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) {
|
||||||
|
const int timeout = back[i].timeout > 0 ? back[i].timeout : 30;
|
||||||
|
|
||||||
|
tunnel_ok =
|
||||||
|
http_proxy_tunnel(opt, &back[i].r, back[i].url_adr, timeout);
|
||||||
|
if (!tunnel_ok) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
// handshake not yet launched
|
// handshake not yet launched
|
||||||
if (!back[i].r.ssl_con) {
|
if (tunnel_ok && !back[i].r.ssl_con) {
|
||||||
SSL_CTX_set_options(openssl_ctx, SSL_OP_ALL);
|
SSL_CTX_set_options(openssl_ctx, SSL_OP_ALL);
|
||||||
// new session
|
// new session
|
||||||
back[i].r.ssl_con = SSL_new(openssl_ctx);
|
back[i].r.ssl_con = SSL_new(openssl_ctx);
|
||||||
@@ -2551,7 +2674,7 @@ void back_wait(struct_back * sback, httrackp * opt, cache_back * cache,
|
|||||||
back[i].r.statuscode = STATUSCODE_SSL_HANDSHAKE;
|
back[i].r.statuscode = STATUSCODE_SSL_HANDSHAKE;
|
||||||
}
|
}
|
||||||
/* Error */
|
/* Error */
|
||||||
if (back[i].r.statuscode == STATUSCODE_SSL_HANDSHAKE) {
|
if (tunnel_ok && back[i].r.statuscode == STATUSCODE_SSL_HANDSHAKE) {
|
||||||
strcpybuff(back[i].r.msg, "bad SSL/TLS handshake");
|
strcpybuff(back[i].r.msg, "bad SSL/TLS handshake");
|
||||||
deletehttp(&back[i].r);
|
deletehttp(&back[i].r);
|
||||||
back[i].r.soc = INVALID_SOCKET;
|
back[i].r.soc = INVALID_SOCKET;
|
||||||
@@ -2779,7 +2902,7 @@ void back_wait(struct_back * sback, httrackp * opt, cache_back * cache,
|
|||||||
if (strcmp(back[i].url_fil, "/robots.txt")) {
|
if (strcmp(back[i].url_fil, "/robots.txt")) {
|
||||||
if (back[i].r.statuscode == HTTP_OK) { // 'OK'
|
if (back[i].r.statuscode == HTTP_OK) { // 'OK'
|
||||||
if (!is_hypertext_mime(opt, back[i].r.contenttype, back[i].url_fil)) { // pas HTML
|
if (!is_hypertext_mime(opt, back[i].r.contenttype, back[i].url_fil)) { // pas HTML
|
||||||
if (opt->getmode & 2) { // on peut ecrire des non html
|
if (opt->getmode & HTS_GETMODE_NONHTML) {
|
||||||
int fcheck = 0;
|
int fcheck = 0;
|
||||||
int last_errno = 0;
|
int last_errno = 0;
|
||||||
|
|
||||||
@@ -2852,7 +2975,7 @@ void back_wait(struct_back * sback, httrackp * opt, cache_back * cache,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else { // on coupe tout!
|
} else { // on coupe tout!
|
||||||
hts_log_print(opt, LOG_DEBUG,
|
hts_log_print(opt, LOG_DEBUG,
|
||||||
"File cancelled (non HTML): %s%s",
|
"File cancelled (non HTML): %s%s",
|
||||||
back[i].url_adr, back[i].url_fil);
|
back[i].url_adr, back[i].url_fil);
|
||||||
@@ -3643,7 +3766,27 @@ void back_wait(struct_back * sback, httrackp * opt, cache_back * cache,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/********** **************************** ********** */
|
/********** **************************** ********** */
|
||||||
} else { // il faut aller le chercher
|
}
|
||||||
|
// MIME type excluded by a -mime: filter: abort, don't fetch
|
||||||
|
// the body (#58)
|
||||||
|
else if (HTTP_IS_OK(back[i].r.statuscode) &&
|
||||||
|
!back[i].testmode &&
|
||||||
|
strnotempty(back[i].r.contenttype) &&
|
||||||
|
hts_acceptmime(opt, 0, back[i].url_adr,
|
||||||
|
back[i].url_fil,
|
||||||
|
back[i].r.contenttype) == 1) {
|
||||||
|
deletehttp(&back[i].r);
|
||||||
|
back[i].r.soc = INVALID_SOCKET;
|
||||||
|
back[i].status = STATUS_READY;
|
||||||
|
back_set_finished(sback, i);
|
||||||
|
back[i].r.statuscode = STATUSCODE_EXCLUDED;
|
||||||
|
strcpybuff(back[i].r.msg, "Excluded by MIME type filter");
|
||||||
|
hts_log_print(
|
||||||
|
opt, LOG_NOTICE,
|
||||||
|
"File excluded by MIME type filter (%s): %s%s",
|
||||||
|
back[i].r.contenttype, back[i].url_adr,
|
||||||
|
back[i].url_fil);
|
||||||
|
} else { // il faut aller le chercher
|
||||||
|
|
||||||
// effacer buffer (requète)
|
// effacer buffer (requète)
|
||||||
if (!noFreebuff) {
|
if (!noFreebuff) {
|
||||||
@@ -3654,35 +3797,70 @@ void back_wait(struct_back * sback, httrackp * opt, cache_back * cache,
|
|||||||
// xxc SI CHUNK VERIFIER QUE CA MARCHE??
|
// 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!
|
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);
|
off_t 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
|
||||||
|
(#198). */
|
||||||
|
const LLint resume = back[i].r.crange_start;
|
||||||
|
const hts_boolean range_ok =
|
||||||
|
back[i].r.crange > 0 && resume >= 0 &&
|
||||||
|
resume <= (LLint) sz &&
|
||||||
|
back[i].r.crange_end + 1 == back[i].r.crange &&
|
||||||
|
(back[i].r.totalsize < 0 ||
|
||||||
|
back[i].r.totalsize ==
|
||||||
|
back[i].r.crange_end - resume + 1);
|
||||||
|
|
||||||
#if HDEBUG
|
#if HDEBUG
|
||||||
printf("partial content: " LLintP " on disk..\n",
|
printf("partial content: " LLintP " on disk..\n",
|
||||||
(LLint) sz);
|
(LLint) sz);
|
||||||
#endif
|
#endif
|
||||||
if (sz >= 0) {
|
if (sz >= 0 && range_ok) {
|
||||||
if (!is_hypertext_mime(opt, back[i].r.contenttype, back[i].url_sav)) { // pas HTML
|
if (!is_hypertext_mime(opt, back[i].r.contenttype, back[i].url_sav)) { // pas HTML
|
||||||
if (opt->getmode & 2) { // on peut ecrire des non html **sinon ben euhh sera intercepté plus loin, donc rap sur ce qui va sortir**
|
if (opt->getmode & HTS_GETMODE_NONHTML) {
|
||||||
filenote(&opt->state.strc, back[i].url_sav, NULL); // noter fichier comme connu
|
filenote(&opt->state.strc, back[i].url_sav, NULL); // noter fichier comme connu
|
||||||
file_notify(opt, back[i].url_adr, back[i].url_fil,
|
file_notify(opt, back[i].url_adr, back[i].url_fil,
|
||||||
back[i].url_sav, 0, 1,
|
back[i].url_sav, 0, 1,
|
||||||
back[i].r.notmodified);
|
back[i].r.notmodified);
|
||||||
back[i].r.out = FOPEN(fconv(catbuff, sizeof(catbuff), back[i].url_sav), "ab"); // append
|
back[i].r.out =
|
||||||
|
FOPEN(fconv(catbuff, sizeof(catbuff),
|
||||||
|
back[i].url_sav),
|
||||||
|
"r+b"); // resume in place
|
||||||
if (back[i].r.out && opt->cache != 0) {
|
if (back[i].r.out && opt->cache != 0) {
|
||||||
back[i].r.is_write = 1; // écrire
|
back[i].r.is_write = 1;
|
||||||
back[i].r.size = sz; // déja écrit
|
back[i].r.size = resume; // bytes already on disk
|
||||||
back[i].r.statuscode = HTTP_OK; // Forcer 'OK'
|
back[i].r.statuscode = HTTP_OK; // force 'OK'
|
||||||
if (back[i].r.totalsize >= 0)
|
if (back[i].r.totalsize >= 0)
|
||||||
back[i].r.totalsize += sz; // plus en fait
|
back[i].r.totalsize += resume; // -> full size
|
||||||
fseek(back[i].r.out, 0, SEEK_END); // à la fin
|
// drop bytes past the resume point; a silent
|
||||||
/* create a temporary reference file in case of broken mirror */
|
// failure could leave a stale tail, so on error
|
||||||
if (back_serialize_ref(opt, &back[i]) != 0) {
|
// drop the partial and refetch the whole file
|
||||||
hts_log_print(opt, LOG_WARNING,
|
if (HTS_FTRUNCATE(back[i].r.out,
|
||||||
"Could not create temporary reference file for %s%s",
|
(off_t) resume) != 0) {
|
||||||
back[i].url_adr, back[i].url_fil);
|
fclose(back[i].r.out);
|
||||||
}
|
back[i].r.out = NULL;
|
||||||
|
url_savename_refname_remove(
|
||||||
|
opt, back[i].url_adr, back[i].url_fil);
|
||||||
|
UNLINK(back[i].url_sav);
|
||||||
|
back[i].status = STATUS_READY;
|
||||||
|
back_set_finished(sback, i);
|
||||||
|
strcpybuff(back[i].r.msg,
|
||||||
|
"Can not truncate partial file, "
|
||||||
|
"restarting");
|
||||||
|
} else {
|
||||||
|
fseeko(back[i].r.out, (off_t) resume, SEEK_SET);
|
||||||
|
/* create a temporary reference file in case of
|
||||||
|
* broken mirror */
|
||||||
|
if (back_serialize_ref(opt, &back[i]) != 0) {
|
||||||
|
hts_log_print(opt, LOG_WARNING,
|
||||||
|
"Could not create temporary "
|
||||||
|
"reference file for %s%s",
|
||||||
|
back[i].url_adr,
|
||||||
|
back[i].url_fil);
|
||||||
|
}
|
||||||
#if HDEBUG
|
#if HDEBUG
|
||||||
printf("continue interrupted file\n");
|
printf("continue interrupted file\n");
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
} else { // On est dans la m**
|
} else { // On est dans la m**
|
||||||
back[i].status = STATUS_READY; // terminé (voir plus loin)
|
back[i].status = STATUS_READY; // terminé (voir plus loin)
|
||||||
back_set_finished(sback, i);
|
back_set_finished(sback, i);
|
||||||
@@ -3694,17 +3872,18 @@ void back_wait(struct_back * sback, httrackp * opt, cache_back * cache,
|
|||||||
FILE *fp =
|
FILE *fp =
|
||||||
FOPEN(fconv(catbuff, sizeof(catbuff), back[i].url_sav), "rb");
|
FOPEN(fconv(catbuff, sizeof(catbuff), back[i].url_sav), "rb");
|
||||||
if (fp) {
|
if (fp) {
|
||||||
LLint alloc_mem = sz + 1;
|
LLint alloc_mem = resume + 1;
|
||||||
|
|
||||||
if (back[i].r.totalsize >= 0)
|
if (back[i].r.totalsize >= 0)
|
||||||
alloc_mem += back[i].r.totalsize; // AJOUTER RESTANT!
|
alloc_mem += back[i].r.totalsize; // AJOUTER RESTANT!
|
||||||
if (deleteaddr(&back[i].r)
|
if (deleteaddr(&back[i].r)
|
||||||
&& (back[i].r.adr =
|
&& (back[i].r.adr =
|
||||||
(char *) malloct((size_t) alloc_mem))) {
|
(char *) malloct((size_t) alloc_mem))) {
|
||||||
back[i].r.size = sz;
|
back[i].r.size = resume;
|
||||||
if (back[i].r.totalsize >= 0)
|
if (back[i].r.totalsize >= 0)
|
||||||
back[i].r.totalsize += sz; // plus en fait
|
back[i].r.totalsize += resume; // -> full size
|
||||||
if ((fread(back[i].r.adr, 1, sz, fp)) != sz) {
|
if ((fread(back[i].r.adr, 1, (size_t) resume,
|
||||||
|
fp)) != (size_t) resume) {
|
||||||
back[i].status = STATUS_READY; // terminé (voir plus loin)
|
back[i].status = STATUS_READY; // terminé (voir plus loin)
|
||||||
back_set_finished(sback, i);
|
back_set_finished(sback, i);
|
||||||
strcpybuff(back[i].r.msg,
|
strcpybuff(back[i].r.msg,
|
||||||
@@ -3722,14 +3901,30 @@ void back_wait(struct_back * sback, httrackp * opt, cache_back * cache,
|
|||||||
"No memory for partial file");
|
"No memory for partial file");
|
||||||
}
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
} else { // Argh..
|
} else { // open failed
|
||||||
back[i].status = STATUS_READY; // terminé (voir plus loin)
|
back[i].status = STATUS_READY; // terminé (voir plus loin)
|
||||||
back_set_finished(sback, i);
|
back_set_finished(sback, i);
|
||||||
strcpybuff(back[i].r.msg,
|
strcpybuff(back[i].r.msg,
|
||||||
"Can not open partial file");
|
"Can not open partial file");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else { // Non trouvé??
|
} else if (sz >=
|
||||||
|
0) { // unusable range -> restart whole file
|
||||||
|
hts_log_print(opt, LOG_WARNING,
|
||||||
|
"Unusable partial-content range for %s%s "
|
||||||
|
"(have " LLintP " bytes, got " LLintP
|
||||||
|
"-" LLintP "/" LLintP "), restarting",
|
||||||
|
back[i].url_adr, back[i].url_fil,
|
||||||
|
(LLint) sz, back[i].r.crange_start,
|
||||||
|
back[i].r.crange_end, back[i].r.crange);
|
||||||
|
url_savename_refname_remove(opt, back[i].url_adr,
|
||||||
|
back[i].url_fil);
|
||||||
|
UNLINK(back[i].url_sav);
|
||||||
|
back[i].status = STATUS_READY;
|
||||||
|
back_set_finished(sback, i);
|
||||||
|
strcpybuff(back[i].r.msg,
|
||||||
|
"Unusable partial content, restarting");
|
||||||
|
} else { // partial not found
|
||||||
back[i].status = STATUS_READY; // terminé (voir plus loin)
|
back[i].status = STATUS_READY; // terminé (voir plus loin)
|
||||||
back_set_finished(sback, i);
|
back_set_finished(sback, i);
|
||||||
strcpybuff(back[i].r.msg, "Can not find partial file");
|
strcpybuff(back[i].r.msg, "Can not find partial file");
|
||||||
@@ -3810,7 +4005,6 @@ void back_wait(struct_back * sback, httrackp * opt, cache_back * cache,
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*} */
|
/*} */
|
||||||
@@ -3838,7 +4032,7 @@ void back_wait(struct_back * sback, httrackp * opt, cache_back * cache,
|
|||||||
/* funny log for commandline users */
|
/* funny log for commandline users */
|
||||||
//if (!opt->quiet) {
|
//if (!opt->quiet) {
|
||||||
// petite animation
|
// petite animation
|
||||||
if (opt->verbosedisplay == 1) {
|
if (opt->verbosedisplay == HTS_VERBOSE_SIMPLE) {
|
||||||
if (back[i].status == STATUS_READY) {
|
if (back[i].status == STATUS_READY) {
|
||||||
if (back[i].r.statuscode == HTTP_OK)
|
if (back[i].r.statuscode == HTTP_OK)
|
||||||
printf("* %s%s (" LLintP " bytes) - OK" VT_CLREOL "\r",
|
printf("* %s%s (" LLintP " bytes) - OK" VT_CLREOL "\r",
|
||||||
@@ -3866,6 +4060,29 @@ void back_wait(struct_back * sback, httrackp * opt, cache_back * cache,
|
|||||||
|
|
||||||
if (back[i].status > 0) { // réception/connexion/..
|
if (back[i].status > 0) { // réception/connexion/..
|
||||||
if (back[i].timeout > 0) {
|
if (back[i].timeout > 0) {
|
||||||
|
// a stuck connect with a fallback address: retry the next one well
|
||||||
|
// before the full timeout (dead IPv6 on a dual-stack host, ...)
|
||||||
|
if (back[i].status == STATUS_CONNECTING) {
|
||||||
|
const hts_connect_fallback *const cf =
|
||||||
|
&sback->connect_fallback[i];
|
||||||
|
|
||||||
|
if (back_connect_fallback_due(cf->addr_index, cf->addr_count,
|
||||||
|
(int) (act - cf->connect_start),
|
||||||
|
back[i].timeout)) {
|
||||||
|
if (back_connect_next(opt, sback, i)) {
|
||||||
|
continue; // reconnected to the next candidate
|
||||||
|
}
|
||||||
|
// fallback was due but no socket could be opened
|
||||||
|
// (back_connect_next closed the dead one): stop now rather than
|
||||||
|
// spin on an invalid fd
|
||||||
|
back[i].r.soc = INVALID_SOCKET;
|
||||||
|
back[i].r.statuscode = STATUSCODE_CONNERROR;
|
||||||
|
strcpybuff(back[i].r.msg, "Connect Error");
|
||||||
|
back[i].status = STATUS_READY;
|
||||||
|
back_set_finished(sback, i);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
//printf("time check %d\n",((int) (act-back[i].timeout_refresh))-back[i].timeout);
|
//printf("time check %d\n",((int) (act-back[i].timeout_refresh))-back[i].timeout);
|
||||||
if (((int) (act - back[i].timeout_refresh)) >= back[i].timeout) {
|
if (((int) (act - back[i].timeout_refresh)) >= back[i].timeout) {
|
||||||
hts_log_print(opt, LOG_DEBUG, "connection timed out for %s%s", back[i].url_adr,
|
hts_log_print(opt, LOG_DEBUG, "connection timed out for %s%s", back[i].url_adr,
|
||||||
|
|||||||
@@ -63,12 +63,15 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
/* GCC extension */
|
/* Compiler-portability attribute macros (no-ops on non-GCC). */
|
||||||
#ifndef HTS_UNUSED
|
#ifndef HTS_UNUSED
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
#define HTS_UNUSED __attribute__ ((unused))
|
#define HTS_UNUSED __attribute__ ((unused))
|
||||||
|
|
||||||
#define HTS_STATIC static __attribute__ ((unused))
|
#define HTS_STATIC static __attribute__ ((unused))
|
||||||
|
|
||||||
#define HTS_INLINE __inline__
|
#define HTS_INLINE __inline__
|
||||||
|
/* printf-style format check; fmt/arg are 1-based argument positions. */
|
||||||
#define HTS_PRINTF_FUN(fmt, arg) __attribute__ ((format (printf, fmt, arg)))
|
#define HTS_PRINTF_FUN(fmt, arg) __attribute__ ((format (printf, fmt, arg)))
|
||||||
#else
|
#else
|
||||||
#define HTS_UNUSED
|
#define HTS_UNUSED
|
||||||
@@ -78,29 +81,37 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* min/max evaluate their arguments twice; pass side-effect-free expressions. */
|
||||||
#undef min
|
#undef min
|
||||||
#undef max
|
#undef max
|
||||||
#define min(a,b) ((a)>(b)?(b):(a))
|
#define min(a,b) ((a)>(b)?(b):(a))
|
||||||
|
|
||||||
#define max(a,b) ((a)>(b)?(a):(b))
|
#define max(a,b) ((a)>(b)?(a):(b))
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#undef Sleep
|
#undef Sleep
|
||||||
#define min(a,b) ((a)>(b)?(b):(a))
|
#define min(a,b) ((a)>(b)?(b):(a))
|
||||||
|
|
||||||
#define max(a,b) ((a)>(b)?(a):(b))
|
#define max(a,b) ((a)>(b)?(a):(b))
|
||||||
|
|
||||||
|
/* Win32 Sleep() shim for POSIX; argument is milliseconds. */
|
||||||
#define Sleep(a) { if (((a)*1000)%1000000) usleep(((a)*1000)%1000000); if (((a)*1000)/1000000) sleep(((a)*1000)/1000000); }
|
#define Sleep(a) { if (((a)*1000)%1000000) usleep(((a)*1000)%1000000); if (((a)*1000)/1000000) sleep(((a)*1000)/1000000); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// teste égalité de 2 chars, case insensitive
|
/* hichar: ASCII uppercasing of one char. streql: case-insensitive equality of
|
||||||
|
two chars. ASCII only; not locale-aware. */
|
||||||
#define hichar(a) ((((a)>='a') && ((a)<='z')) ? ((a)-('a'-'A')) : (a))
|
#define hichar(a) ((((a)>='a') && ((a)<='z')) ? ((a)-('a'-'A')) : (a))
|
||||||
|
|
||||||
#define streql(a,b) (hichar(a)==hichar(b))
|
#define streql(a,b) (hichar(a)==hichar(b))
|
||||||
|
|
||||||
// caractère maj
|
/* True if c is an ASCII uppercase letter. */
|
||||||
#define isUpperLetter(a) ( ((a) >= 'A') && ((a) <= 'Z') )
|
#define isUpperLetter(a) ( ((a) >= 'A') && ((a) <= 'Z') )
|
||||||
|
|
||||||
/* Library internal definictions */
|
/* Library-internal only (engine translation units that define
|
||||||
|
HTS_INTERNAL_BYTECODE); not part of the consumer surface. */
|
||||||
#ifdef HTS_INTERNAL_BYTECODE
|
#ifdef HTS_INTERNAL_BYTECODE
|
||||||
|
|
||||||
// functions
|
/* Resolve a symbol in an already-loaded dynamic module. */
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define DynamicGet(handle, sym) GetProcAddress(handle, sym)
|
#define DynamicGet(handle, sym) GetProcAddress(handle, sym)
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -31,12 +31,17 @@ Please visit our Website: http://www.httrack.com
|
|||||||
/* Author: Xavier Roche */
|
/* Author: Xavier Roche */
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
|
||||||
|
/** @file htsbasenet.h
|
||||||
|
Base networking definitions: platform socket headers, the optional global
|
||||||
|
OpenSSL context, and the status-code/connection-state enumerations stored in
|
||||||
|
htsblk and lien_back. Pulled in by htsnet.h. */
|
||||||
|
|
||||||
#ifndef HTS_DEFBASENETH
|
#ifndef HTS_DEFBASENETH
|
||||||
#define HTS_DEFBASENETH
|
#define HTS_DEFBASENETH
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
||||||
#if HTS_INET6==0
|
#if HTS_INET6 == 0
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#else
|
#else
|
||||||
|
|
||||||
@@ -44,13 +49,14 @@ Please visit our Website: http://www.httrack.com
|
|||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
// KB955045 (http://support.microsoft.com/kb/955045)
|
// KB955045 (http://support.microsoft.com/kb/955045)
|
||||||
// To execute an application using this function on earlier versions of Windows
|
// To execute an application using this function on earlier versions of Windows
|
||||||
// (Windows 2000, Windows NT, and Windows Me/98/95), then it is mandatary to #include Ws2tcpip.h
|
// (Windows 2000, Windows NT, and Windows Me/98/95), then it is mandatary to
|
||||||
// and also Wspiapi.h. When the Wspiapi.h header file is included, the 'getaddrinfo' function is
|
// #include Ws2tcpip.h and also Wspiapi.h. When the Wspiapi.h header file is
|
||||||
// #defined to the 'WspiapiGetAddrInfo' inline function in Wspiapi.h.
|
// included, the 'getaddrinfo' function is #defined to the 'WspiapiGetAddrInfo'
|
||||||
|
// inline function in Wspiapi.h.
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
#include <Wspiapi.h>
|
#include <Wspiapi.h>
|
||||||
//#include <winsock2.h>
|
// #include <winsock2.h>
|
||||||
//#include <tpipv6.h>
|
// #include <tpipv6.h>
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -80,7 +86,8 @@ extern "C" {
|
|||||||
/* OpenSSL structure */
|
/* OpenSSL structure */
|
||||||
#include <openssl/bio.h>
|
#include <openssl/bio.h>
|
||||||
|
|
||||||
/* Global SSL context */
|
/** Process-wide OpenSSL client context, created lazily on first TLS use;
|
||||||
|
shared by all connections. NULL until initialized. */
|
||||||
extern SSL_CTX *openssl_ctx;
|
extern SSL_CTX *openssl_ctx;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -139,7 +146,8 @@ typedef enum BackStatusCode {
|
|||||||
STATUSCODE_NON_FATAL = -5,
|
STATUSCODE_NON_FATAL = -5,
|
||||||
STATUSCODE_SSL_HANDSHAKE = -6,
|
STATUSCODE_SSL_HANDSHAKE = -6,
|
||||||
STATUSCODE_TOO_BIG = -7,
|
STATUSCODE_TOO_BIG = -7,
|
||||||
STATUSCODE_TEST_OK = -10
|
STATUSCODE_TEST_OK = -10,
|
||||||
|
STATUSCODE_EXCLUDED = -11 /* aborted: MIME excluded by a -mime: filter */
|
||||||
} BackStatusCode;
|
} BackStatusCode;
|
||||||
|
|
||||||
/** HTTrack status ('status' member of of 'lien_back') **/
|
/** HTTrack status ('status' member of of 'lien_back') **/
|
||||||
|
|||||||
@@ -3,57 +3,59 @@
|
|||||||
|
|
||||||
# Change this to download files
|
# Change this to download files
|
||||||
if false; then
|
if false; then
|
||||||
echo "mget ftp://ftp.unicode.org/Public/MAPPINGS/ISO8859/8859-*.TXT" | lftp
|
echo "mget ftp://ftp.unicode.org/Public/MAPPINGS/ISO8859/8859-*.TXT" | lftp
|
||||||
echo "mget ftp://ftp.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP*.TXT" | lftp
|
echo "mget ftp://ftp.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP*.TXT" | lftp
|
||||||
echo "mget ftp://ftp.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP*.TXT" | lftp
|
echo "mget ftp://ftp.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP*.TXT" | lftp
|
||||||
echo "mget ftp://ftp.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/EBCDIC/CP*.TXT" | lftp
|
echo "mget ftp://ftp.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/EBCDIC/CP*.TXT" | lftp
|
||||||
echo "mget ftp://ftp.unicode.org/Public/MAPPINGS/VENDORS/MISC/CP*.TXT" | lftp
|
echo "mget ftp://ftp.unicode.org/Public/MAPPINGS/VENDORS/MISC/CP*.TXT" | lftp
|
||||||
echo "mget ftp://ftp.unicode.org/Public/MAPPINGS/VENDORS/MISC/KOI8*.TXT" | lftp
|
echo "mget ftp://ftp.unicode.org/Public/MAPPINGS/VENDORS/MISC/KOI8*.TXT" | lftp
|
||||||
rm -f CP932.TXT CP936.TXT CP949.TXT CP950.TXT
|
rm -f CP932.TXT CP936.TXT CP949.TXT CP950.TXT
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Produce code
|
# Produce code
|
||||||
printf "/** GENERATED FILE ($0), DO NOT EDIT **/\n\n"
|
printf '/** GENERATED FILE (%s), DO NOT EDIT **/\n\n' "$0"
|
||||||
for i in *.TXT ; do
|
for i in *.TXT; do
|
||||||
echo "processing $i" >&2
|
echo "processing $i" >&2
|
||||||
grep -vE "^(#|$)" $i | grep -E "^0x" | sed -e 's/[[:space:]]/ /g' | cut -f1,2 -d' ' | \
|
grep -vE "^(#|$)" "$i" | grep -E "^0x" | sed -e 's/[[:space:]]/ /g' | cut -f1,2 -d' ' |
|
||||||
(
|
(
|
||||||
unset arr
|
unset arr
|
||||||
while read LINE ; do
|
while read -r LINE; do
|
||||||
from=$[$(echo $LINE | cut -f1 -d' ')]
|
from=$(($(echo "$LINE" | cut -f1 -d' ')))
|
||||||
if ! test -n "$from"; then
|
if ! test -n "$from"; then
|
||||||
echo "error with $i" >&2
|
echo "error with $i" >&2
|
||||||
exit 1
|
exit 1
|
||||||
elif test $from -ge 256; then
|
elif test $from -ge 256; then
|
||||||
echo "out-of-range ($LINE) with $i" >&2
|
echo "out-of-range ($LINE) with $i" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
to=$(echo $LINE | cut -f2 -d' ')
|
to=$(echo "$LINE" | cut -f2 -d' ')
|
||||||
arr[$from]=$to
|
arr[from]=$to
|
||||||
done
|
done
|
||||||
name=$(echo $i | tr 'A-Z' 'a-z' | tr '-' '_' | sed -e 's/\.txt//' -e 's/8859/iso_8859/')
|
# shellcheck disable=SC2018,SC2019 # charset filenames are ASCII; keep C-locale A-Z/a-z
|
||||||
printf "/* Table for $i */\nstatic const hts_UCS4 table_${name}[256] = {\n "
|
name=$(echo "$i" | tr 'A-Z' 'a-z' | tr '-' '_' | sed -e 's/\.txt//' -e 's/8859/iso_8859/')
|
||||||
i=0
|
printf '/* Table for %s */\nstatic const hts_UCS4 table_%s[256] = {\n ' "$i" "$name"
|
||||||
while test "$i" -lt 256; do
|
idx=0
|
||||||
if test "$i" -gt 0; then
|
while test "$idx" -lt 256; do
|
||||||
printf ", "
|
if test "$idx" -gt 0; then
|
||||||
if test $[${i}%8] -eq 0; then
|
printf ", "
|
||||||
printf "\n "
|
if test $((idx % 8)) -eq 0; then
|
||||||
fi
|
printf "\n "
|
||||||
fi
|
fi
|
||||||
value=${arr[$i]:-0}
|
fi
|
||||||
printf "0x%04x" $value
|
value=${arr[$idx]:-0}
|
||||||
i=$[${i}+1]
|
printf "0x%04x" "$value"
|
||||||
done
|
idx=$((idx + 1))
|
||||||
printf " };\n\n"
|
done
|
||||||
)
|
printf " };\n\n"
|
||||||
echo "processed $i" >&2
|
)
|
||||||
|
echo "processed $i" >&2
|
||||||
done
|
done
|
||||||
|
|
||||||
# Indexes
|
# Indexes
|
||||||
printf "static const struct {\n const char *name;\n const hts_UCS4 *table;\n} table_mappings[] = {\n"
|
printf "static const struct {\n const char *name;\n const hts_UCS4 *table;\n} table_mappings[] = {\n"
|
||||||
for i in *.TXT ; do
|
for i in *.TXT; do
|
||||||
name=$(echo $i | tr 'A-Z' 'a-z' | tr '-' '_' | sed -e 's/\.txt//' -e 's/8859/iso_8859/')
|
# shellcheck disable=SC2018,SC2019 # charset filenames are ASCII; keep C-locale A-Z/a-z
|
||||||
printf " { \"$(echo $name | tr -d '_')\", table_${name} },\n"
|
name=$(echo "$i" | tr 'A-Z' 'a-z' | tr '-' '_' | sed -e 's/\.txt//' -e 's/8859/iso_8859/')
|
||||||
|
printf ' { "%s", table_%s },\n' "$(echo "$name" | tr -d '_')" "$name"
|
||||||
done
|
done
|
||||||
printf " { NULL, NULL }\n};\n"
|
printf " { NULL, NULL }\n};\n"
|
||||||
|
|||||||
@@ -31,51 +31,80 @@ Please visit our Website: http://www.httrack.com
|
|||||||
/* Author: Xavier Roche */
|
/* Author: Xavier Roche */
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
|
||||||
|
/** @file htsbauth.h
|
||||||
|
HTTP Basic authentication storage: a per-session list of (URL-prefix,
|
||||||
|
credentials) pairs, plus the cookie jar that holds it. */
|
||||||
|
|
||||||
#ifndef HTSBAUTH_DEFH
|
#ifndef HTSBAUTH_DEFH
|
||||||
#define HTSBAUTH_DEFH
|
#define HTSBAUTH_DEFH
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
// robots wizard
|
/** One stored credential: the longest-prefix match against a request's
|
||||||
|
host+path selects which auth header to send. */
|
||||||
#ifndef HTS_DEF_FWSTRUCT_bauth_chain
|
#ifndef HTS_DEF_FWSTRUCT_bauth_chain
|
||||||
#define HTS_DEF_FWSTRUCT_bauth_chain
|
#define HTS_DEF_FWSTRUCT_bauth_chain
|
||||||
typedef struct bauth_chain bauth_chain;
|
typedef struct bauth_chain bauth_chain;
|
||||||
#endif
|
#endif
|
||||||
struct bauth_chain {
|
struct bauth_chain {
|
||||||
char prefix[1024]; /* www.foo.com/secure/ */
|
char prefix[1024]; /* host + path prefix, e.g. www.foo.com/secure/ */
|
||||||
char auth[1024]; /* base-64 encoded user:pass */
|
char auth[1024]; /* base-64 encoded user:pass (Authorization payload) */
|
||||||
struct bauth_chain *next; /* next element */
|
struct bauth_chain *next; /* next element, NULL-terminated list */
|
||||||
};
|
};
|
||||||
|
|
||||||
// buffer pour les cookies et authentification
|
/** Per-session cookie jar; also holds the basic-auth list head (auth).
|
||||||
|
The head node (auth) is embedded, not heap-allocated. */
|
||||||
#ifndef HTS_DEF_FWSTRUCT_t_cookie
|
#ifndef HTS_DEF_FWSTRUCT_t_cookie
|
||||||
#define HTS_DEF_FWSTRUCT_t_cookie
|
#define HTS_DEF_FWSTRUCT_t_cookie
|
||||||
typedef struct t_cookie t_cookie;
|
typedef struct t_cookie t_cookie;
|
||||||
#endif
|
#endif
|
||||||
struct t_cookie {
|
struct t_cookie {
|
||||||
int max_len;
|
int max_len; /* capacity of data[] in use */
|
||||||
char data[32768];
|
char data[32768]; /* raw cookie store (NUL-terminated field list) */
|
||||||
bauth_chain auth;
|
bauth_chain auth; /* embedded head of the basic-auth list */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Library internal definictions */
|
/* Library internal definictions */
|
||||||
#ifdef HTS_INTERNAL_BYTECODE
|
#ifdef HTS_INTERNAL_BYTECODE
|
||||||
|
|
||||||
// cookies
|
/* cookies */
|
||||||
int cookie_add(t_cookie * cookie, const char *cook_name, const char *cook_value,
|
int cookie_add(t_cookie *cookie, const char *cook_name, const char *cook_value,
|
||||||
const char *domain, const char *path);
|
const char *domain, const char *path);
|
||||||
int cookie_del(t_cookie * cookie, const char *cook_name, const char *domain, const char *path);
|
|
||||||
int cookie_load(t_cookie * cookie, const char *path, const char *name);
|
int cookie_del(t_cookie *cookie, const char *cook_name, const char *domain,
|
||||||
int cookie_save(t_cookie * cookie, const char *name);
|
const char *path);
|
||||||
|
|
||||||
|
int cookie_load(t_cookie *cookie, const char *path, const char *name);
|
||||||
|
|
||||||
|
int cookie_save(t_cookie *cookie, const char *name);
|
||||||
|
|
||||||
void cookie_insert(char *s, size_t s_size, const char *ins);
|
void cookie_insert(char *s, size_t s_size, const char *ins);
|
||||||
|
|
||||||
void cookie_delete(char *s, size_t s_size, size_t pos);
|
void cookie_delete(char *s, size_t s_size, size_t pos);
|
||||||
|
|
||||||
const char *cookie_get(char *buffer, const char *cookie_base, int param);
|
const char *cookie_get(char *buffer, const char *cookie_base, int param);
|
||||||
char *cookie_find(char *s, const char *cook_name, const char *domain, const char *path);
|
|
||||||
|
char *cookie_find(char *s, const char *cook_name, const char *domain,
|
||||||
|
const char *path);
|
||||||
|
|
||||||
char *cookie_nextfield(char *a);
|
char *cookie_nextfield(char *a);
|
||||||
|
|
||||||
// basic auth
|
/* basic auth */
|
||||||
int bauth_add(t_cookie * cookie, const char *adr, const char *fil, const char *auth);
|
|
||||||
char *bauth_check(t_cookie * cookie, const char *adr, const char *fil);
|
/** Register credentials (auth = base-64 user:pass) for the prefix derived from
|
||||||
|
adr (host) and fil (path). No-op returning 0 if cookie is NULL, allocation
|
||||||
|
fails, or a matching prefix is already stored; returns 1 on insertion. */
|
||||||
|
int bauth_add(t_cookie *cookie, const char *adr, const char *fil,
|
||||||
|
const char *auth);
|
||||||
|
|
||||||
|
/** Return the stored base-64 credentials whose prefix matches adr+fil, or NULL
|
||||||
|
if none (or cookie is NULL). Returned pointer aliases the jar's bauth_chain;
|
||||||
|
caller must not free it. */
|
||||||
|
char *bauth_check(t_cookie *cookie, const char *adr, const char *fil);
|
||||||
|
|
||||||
|
/** Build the auth lookup key (host + path, query string stripped, truncated at
|
||||||
|
the last '/') from adr and fil into prefix; returns prefix. Caller must
|
||||||
|
supply a buffer of HTS_URLMAXSIZE * 2 bytes. */
|
||||||
char *bauth_prefix(char *buffer, const char *adr, const char *fil);
|
char *bauth_prefix(char *buffer, const char *adr, const char *fil);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -220,6 +220,25 @@ struct cache_back_zip_entry {
|
|||||||
} \
|
} \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
/* A cache (new.zip) write failed: storage is gone (disk full / dropped share),
|
||||||
|
so the mirror is doomed too. Abort it via exit_xh, don't crash as assertf
|
||||||
|
did. */
|
||||||
|
static void cache_zip_write_failed(httrackp *opt, cache_back *cache,
|
||||||
|
const char *what, int zErr) {
|
||||||
|
if (!cache->zipWriteFailed) {
|
||||||
|
cache->zipWriteFailed = HTS_TRUE;
|
||||||
|
if (check_fatal_io_errno()) {
|
||||||
|
hts_log_print(opt, LOG_ERROR,
|
||||||
|
"Mirror aborted: disk full or filesystem problems");
|
||||||
|
} else {
|
||||||
|
hts_log_print(opt, LOG_ERROR,
|
||||||
|
"Mirror aborted: cache write failed (%s): %s", what,
|
||||||
|
hts_get_zerror(zErr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
opt->state.exit_xh = -1; /* fatal: stop the mirror, exit non-zero */
|
||||||
|
}
|
||||||
|
|
||||||
/* Ajout d'un fichier en cache */
|
/* Ajout d'un fichier en cache */
|
||||||
void cache_add(httrackp * opt, cache_back * cache, const htsblk * r,
|
void cache_add(httrackp * opt, cache_back * cache, const htsblk * r,
|
||||||
const char *url_adr, const char *url_fil, const char *url_save,
|
const char *url_adr, const char *url_fil, const char *url_save,
|
||||||
@@ -236,6 +255,10 @@ void cache_add(httrackp * opt, cache_back * cache, const htsblk * r,
|
|||||||
const char *url_save_suffix = url_save;
|
const char *url_save_suffix = url_save;
|
||||||
int zErr;
|
int zErr;
|
||||||
|
|
||||||
|
/* already failed and aborting; don't touch the broken stream again */
|
||||||
|
if (cache->zipWriteFailed)
|
||||||
|
return;
|
||||||
|
|
||||||
// robots.txt hack
|
// robots.txt hack
|
||||||
if (url_save == NULL) {
|
if (url_save == NULL) {
|
||||||
dataincache = 0; // testing links
|
dataincache = 0; // testing links
|
||||||
@@ -346,9 +369,8 @@ void cache_add(httrackp * opt, cache_back * cache, const htsblk * r,
|
|||||||
*/
|
*/
|
||||||
headers, (uInt) strlen(headers), NULL, 0, NULL, /* comment */
|
headers, (uInt) strlen(headers), NULL, 0, NULL, /* comment */
|
||||||
Z_DEFLATED, Z_DEFAULT_COMPRESSION)) != Z_OK) {
|
Z_DEFLATED, Z_DEFAULT_COMPRESSION)) != Z_OK) {
|
||||||
int zip_zipOpenNewFileInZip_failed = 0;
|
cache_zip_write_failed(opt, cache, "opening a cache entry", zErr);
|
||||||
|
return;
|
||||||
assertf(zip_zipOpenNewFileInZip_failed);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write data in cache */
|
/* Write data in cache */
|
||||||
@@ -358,9 +380,8 @@ void cache_add(httrackp * opt, cache_back * cache, const htsblk * r,
|
|||||||
if ((zErr =
|
if ((zErr =
|
||||||
zipWriteInFileInZip((zipFile) cache->zipOutput, r->adr,
|
zipWriteInFileInZip((zipFile) cache->zipOutput, r->adr,
|
||||||
(int) r->size)) != Z_OK) {
|
(int) r->size)) != Z_OK) {
|
||||||
int zip_zipWriteInFileInZip_failed = 0;
|
cache_zip_write_failed(opt, cache, "writing to the cache", zErr);
|
||||||
|
return;
|
||||||
assertf(zip_zipWriteInFileInZip_failed);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -381,9 +402,10 @@ void cache_add(httrackp * opt, cache_back * cache, const htsblk * r,
|
|||||||
if ((zErr =
|
if ((zErr =
|
||||||
zipWriteInFileInZip((zipFile) cache->zipOutput, buff,
|
zipWriteInFileInZip((zipFile) cache->zipOutput, buff,
|
||||||
(int) nl)) != Z_OK) {
|
(int) nl)) != Z_OK) {
|
||||||
int zip_zipWriteInFileInZip_failed = 0;
|
cache_zip_write_failed(opt, cache, "writing to the cache",
|
||||||
|
zErr);
|
||||||
assertf(zip_zipWriteInFileInZip_failed);
|
fclose(fp);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while(nl > 0);
|
} while(nl > 0);
|
||||||
@@ -397,16 +419,14 @@ void cache_add(httrackp * opt, cache_back * cache, const htsblk * r,
|
|||||||
|
|
||||||
/* Close */
|
/* Close */
|
||||||
if ((zErr = zipCloseFileInZip((zipFile) cache->zipOutput)) != Z_OK) {
|
if ((zErr = zipCloseFileInZip((zipFile) cache->zipOutput)) != Z_OK) {
|
||||||
int zip_zipCloseFileInZip_failed = 0;
|
cache_zip_write_failed(opt, cache, "closing a cache entry", zErr);
|
||||||
|
return;
|
||||||
assertf(zip_zipCloseFileInZip_failed);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Flush */
|
/* Flush */
|
||||||
if ((zErr = zipFlush((zipFile) cache->zipOutput)) != 0) {
|
if ((zErr = zipFlush((zipFile) cache->zipOutput)) != 0) {
|
||||||
int zip_zipFlush_failed = 0;
|
cache_zip_write_failed(opt, cache, "flushing the cache", zErr);
|
||||||
|
return;
|
||||||
assertf(zip_zipFlush_failed);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,11 +47,15 @@ Please visit our Website: http://www.httrack.com
|
|||||||
#include "htslib.h"
|
#include "htslib.h"
|
||||||
#include "htszlib.h"
|
#include "htszlib.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#define SELFTEST_VOLUME 3000 /* number of small entries in the scale pass */
|
#define SELFTEST_VOLUME 3000 /* number of small entries in the scale pass */
|
||||||
|
|
||||||
|
/* prefix on assertion failures; set per entry point (-#A vs -#B) */
|
||||||
|
static const char *selftest_tag = "cache-selftest";
|
||||||
|
|
||||||
/* Open a cache session. A write session (ro=0) rotates new.zip -> old.zip and
|
/* Open a cache session. A write session (ro=0) rotates new.zip -> old.zip and
|
||||||
opens a fresh new.zip; a read session (ro=1) opens new.zip in place. */
|
opens a fresh new.zip; a read session (ro=1) opens new.zip in place. */
|
||||||
static void selftest_open(cache_back *cache, httrackp *opt, int ro) {
|
static void selftest_open(cache_back *cache, httrackp *opt, int ro) {
|
||||||
@@ -95,15 +99,13 @@ static void selftest_close(cache_back *cache) {
|
|||||||
that exits right after (same choice as the other -# cache subcommands) */
|
that exits right after (same choice as the other -# cache subcommands) */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Store one entry. The body is copied into a private buffer (any size), so
|
/* Store one entry; the body is copied so callers may pass const data. */
|
||||||
callers may pass const data and cache_add never sees a cast-away qualifier;
|
|
||||||
it consumes everything synchronously, so the copy is freed on return. */
|
|
||||||
static void store_entry(httrackp *opt, cache_back *cache, const char *adr,
|
static void store_entry(httrackp *opt, cache_back *cache, const char *adr,
|
||||||
const char *fil, const char *save, int statuscode,
|
const char *fil, const char *save, int statuscode,
|
||||||
const char *msg, const char *contenttype,
|
const char *msg, const char *contenttype,
|
||||||
const char *charset, const char *lastmodified,
|
const char *charset, const char *lastmodified,
|
||||||
const char *etag, const char *location,
|
const char *etag, const char *location,
|
||||||
const char *body, size_t body_len) {
|
const char *cdispo, const char *body, size_t body_len) {
|
||||||
htsblk r;
|
htsblk r;
|
||||||
char locbuf[HTS_URLMAXSIZE * 2];
|
char locbuf[HTS_URLMAXSIZE * 2];
|
||||||
char *bodycopy = NULL;
|
char *bodycopy = NULL;
|
||||||
@@ -116,32 +118,30 @@ static void store_entry(httrackp *opt, cache_back *cache, const char *adr,
|
|||||||
strcpybuff(r.charset, charset);
|
strcpybuff(r.charset, charset);
|
||||||
strcpybuff(r.lastmodified, lastmodified);
|
strcpybuff(r.lastmodified, lastmodified);
|
||||||
strcpybuff(r.etag, etag);
|
strcpybuff(r.etag, etag);
|
||||||
|
strcpybuff(r.cdispo, cdispo);
|
||||||
strcpybuff(locbuf, location);
|
strcpybuff(locbuf, location);
|
||||||
r.location = locbuf;
|
r.location = locbuf;
|
||||||
r.is_write = 0;
|
r.is_write = 0;
|
||||||
/* an empty body must be a NULL pointer: cache_add rejects a non-NULL
|
/* an empty body must be NULL: cache_add rejects non-NULL with size 0 */
|
||||||
pointer with size 0 */
|
|
||||||
if (body_len != 0) {
|
if (body_len != 0) {
|
||||||
bodycopy = malloct(body_len);
|
bodycopy = malloct(body_len);
|
||||||
memcpy(bodycopy, body, body_len);
|
memcpy(bodycopy, body, body_len);
|
||||||
r.adr = bodycopy;
|
r.adr = bodycopy;
|
||||||
}
|
}
|
||||||
/* all_in_cache=1: keep the body in the ZIP whatever the content-type,
|
/* all_in_cache=1: body stays in the ZIP, so reads never need a disk file */
|
||||||
so the read path never depends on a file on disk */
|
|
||||||
cache_add(opt, cache, &r, adr, fil, save, 1, NULL);
|
cache_add(opt, cache, &r, adr, fil, save, 1, NULL);
|
||||||
if (bodycopy != NULL) {
|
if (bodycopy != NULL) {
|
||||||
freet(bodycopy);
|
freet(bodycopy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read one entry back and check every field. Returns the number of
|
/* Read one entry back and check every field. Returns the mismatch count. */
|
||||||
mismatches (0 == success). */
|
|
||||||
static int check_entry(httrackp *opt, cache_back *cache, const char *adr,
|
static int check_entry(httrackp *opt, cache_back *cache, const char *adr,
|
||||||
const char *fil, int statuscode, const char *msg,
|
const char *fil, int statuscode, const char *msg,
|
||||||
const char *contenttype, const char *charset,
|
const char *contenttype, const char *charset,
|
||||||
const char *lastmodified, const char *etag,
|
const char *lastmodified, const char *etag,
|
||||||
const char *location, const char *body,
|
const char *location, const char *cdispo,
|
||||||
size_t body_len) {
|
const char *body, size_t body_len) {
|
||||||
int fail = 0;
|
int fail = 0;
|
||||||
char *locbuf = malloct(HTS_URLMAXSIZE * 2);
|
char *locbuf = malloct(HTS_URLMAXSIZE * 2);
|
||||||
htsblk r;
|
htsblk r;
|
||||||
@@ -153,15 +153,14 @@ static int check_entry(httrackp *opt, cache_back *cache, const char *adr,
|
|||||||
#define CHECK_STR(field, want) \
|
#define CHECK_STR(field, want) \
|
||||||
do { \
|
do { \
|
||||||
if (strcmp((field), (want)) != 0) { \
|
if (strcmp((field), (want)) != 0) { \
|
||||||
fprintf(stderr, \
|
fprintf(stderr, "%s: %s%s: " #field " is '%s', expected '%s'\n", \
|
||||||
"cache-selftest: %s%s: " #field " is '%s', expected '%s'\n", \
|
selftest_tag, adr, fil, (field), (want)); \
|
||||||
adr, fil, (field), (want)); \
|
|
||||||
fail++; \
|
fail++; \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
if (r.statuscode != statuscode) {
|
if (r.statuscode != statuscode) {
|
||||||
fprintf(stderr, "cache-selftest: %s%s: statuscode is %d, expected %d\n",
|
fprintf(stderr, "%s: %s%s: statuscode is %d, expected %d\n", selftest_tag,
|
||||||
adr, fil, r.statuscode, statuscode);
|
adr, fil, r.statuscode, statuscode);
|
||||||
fail++;
|
fail++;
|
||||||
}
|
}
|
||||||
@@ -171,24 +170,23 @@ static int check_entry(httrackp *opt, cache_back *cache, const char *adr,
|
|||||||
CHECK_STR(r.lastmodified, lastmodified);
|
CHECK_STR(r.lastmodified, lastmodified);
|
||||||
CHECK_STR(r.etag, etag);
|
CHECK_STR(r.etag, etag);
|
||||||
CHECK_STR(locbuf, location);
|
CHECK_STR(locbuf, location);
|
||||||
|
CHECK_STR(r.cdispo, cdispo);
|
||||||
|
|
||||||
if (r.size != (LLint) body_len) {
|
if (r.size != (LLint) body_len) {
|
||||||
fprintf(stderr, "cache-selftest: %s%s: size is " LLintP ", expected %d\n",
|
fprintf(stderr, "%s: %s%s: size is " LLintP ", expected %d\n", selftest_tag,
|
||||||
adr, fil, (LLint) r.size, (int) body_len);
|
adr, fil, (LLint) r.size, (int) body_len);
|
||||||
fail++;
|
fail++;
|
||||||
} else if (body_len != 0 &&
|
} else if (body_len != 0 &&
|
||||||
(r.adr == NULL || memcmp(r.adr, body, body_len) != 0)) {
|
(r.adr == NULL || memcmp(r.adr, body, body_len) != 0)) {
|
||||||
fprintf(stderr, "cache-selftest: %s%s: body mismatch\n", adr, fil);
|
fprintf(stderr, "%s: %s%s: body mismatch\n", selftest_tag, adr, fil);
|
||||||
fail++;
|
fail++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The loaded body must be NUL-terminated at [size]: cache_readex's strlen()
|
/* loaded body must be NUL-terminated at [size] for cache_readex's strlen()
|
||||||
consumers (htscore.c:1046, htscache.c) rely on it, and a missing
|
consumers; buffer is malloc(size + slack) so [size] is in bounds */
|
||||||
terminator is a heap over-read. The buffer is malloc(size + slack), so
|
|
||||||
reading [size] is in bounds. */
|
|
||||||
if (r.adr != NULL && r.adr[r.size] != '\0') {
|
if (r.adr != NULL && r.adr[r.size] != '\0') {
|
||||||
fprintf(stderr, "cache-selftest: %s%s: body not NUL-terminated at [size]\n",
|
fprintf(stderr, "%s: %s%s: body not NUL-terminated at [size]\n",
|
||||||
adr, fil);
|
selftest_tag, adr, fil);
|
||||||
fail++;
|
fail++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -319,6 +317,136 @@ static int disk_fallback_selftest(httrackp *opt) {
|
|||||||
return fail;
|
return fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
size_t budget; /**< bytes allowed through before writes start failing */
|
||||||
|
int fail_errno; /**< errno set on the failing write (ENOSPC, EIO, ...) */
|
||||||
|
int writes; /**< zwrite call count, to detect re-entry into the stream */
|
||||||
|
} writefail_inject;
|
||||||
|
|
||||||
|
/* zwrite that copies until the budget runs out, then fails with inj->fail_errno
|
||||||
|
(the #174/#219 condition). Counts calls so the test can prove a flagged cache
|
||||||
|
never re-enters the stream. */
|
||||||
|
static uLong selftest_failing_zwrite(voidpf opaque, voidpf stream,
|
||||||
|
const void *buf, uLong size) {
|
||||||
|
writefail_inject *inj = (writefail_inject *) opaque;
|
||||||
|
|
||||||
|
inj->writes++;
|
||||||
|
if (inj->budget >= (size_t) size) {
|
||||||
|
inj->budget -= (size_t) size;
|
||||||
|
return (uLong) fwrite(buf, 1, (size_t) size, (FILE *) stream);
|
||||||
|
}
|
||||||
|
errno = inj->fail_errno;
|
||||||
|
return 0; /* short write -> the minizip op returns an error */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Open a ZIP whose writes fail past inj->budget, so cache_add() hits an error.
|
||||||
|
*/
|
||||||
|
static zipFile selftest_open_failing_zip(const char *path,
|
||||||
|
writefail_inject *inj) {
|
||||||
|
zlib_filefunc_def ff;
|
||||||
|
|
||||||
|
fill_fopen_filefunc(&ff); /* real fopen/read/seek/close; ignores opaque */
|
||||||
|
ff.zwrite_file = selftest_failing_zwrite;
|
||||||
|
ff.opaque = inj;
|
||||||
|
return zipOpen2(path, APPEND_STATUS_CREATE, NULL, &ff);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store one octet-stream body into `cache` (all-in-cache, body in the ZIP). */
|
||||||
|
static void writefail_store(httrackp *opt, cache_back *cache, const char *fil,
|
||||||
|
const char *body, size_t body_len) {
|
||||||
|
htsblk r;
|
||||||
|
char locbuf[4];
|
||||||
|
char *bodycopy = malloct(body_len);
|
||||||
|
|
||||||
|
hts_init_htsblk(&r);
|
||||||
|
r.statuscode = 200;
|
||||||
|
r.size = (LLint) body_len;
|
||||||
|
strcpybuff(r.msg, "OK");
|
||||||
|
strcpybuff(r.contenttype, "application/octet-stream");
|
||||||
|
locbuf[0] = '\0';
|
||||||
|
r.location = locbuf;
|
||||||
|
r.is_write = 0;
|
||||||
|
memcpy(bodycopy, body, body_len);
|
||||||
|
r.adr = bodycopy;
|
||||||
|
cache_add(opt, cache, &r, "example.com", fil, "example.com/blob.bin", 1,
|
||||||
|
NULL);
|
||||||
|
freet(bodycopy);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* #174/#219: a failing cache write used to crash via assertf(); it must instead
|
||||||
|
stop the mirror (exit_xh = -1) without crashing. Assert that, plus the cache
|
||||||
|
is flagged and a sibling write doesn't re-enter the broken stream. */
|
||||||
|
int cache_write_failure_selftest(httrackp *opt, const char *dir) {
|
||||||
|
int fail = 0;
|
||||||
|
char path[HTS_URLMAXSIZE];
|
||||||
|
/* incompressible + big, so deflate flushes (and fails) mid-write, before
|
||||||
|
* close */
|
||||||
|
static const size_t body_len = 256 * 1024;
|
||||||
|
char *body = malloct(body_len);
|
||||||
|
int phase;
|
||||||
|
|
||||||
|
gen_body(body, body_len, 1 /* incompressible */);
|
||||||
|
fconcat(path, sizeof(path), dir, "/wfail.zip");
|
||||||
|
|
||||||
|
/* phase 0: fail on the body write, fatal errno (ENOSPC, the disk-full
|
||||||
|
branch). phase 1: fail on the open, non-fatal errno (EIO, dropped-share
|
||||||
|
branch). Both must abort the mirror. */
|
||||||
|
for (phase = 0; phase < 2; phase++) {
|
||||||
|
cache_back cache;
|
||||||
|
writefail_inject inj;
|
||||||
|
int writes_after_fail;
|
||||||
|
|
||||||
|
inj.budget = (phase == 0) ? 4096 : 0;
|
||||||
|
inj.fail_errno = (phase == 0) ? ENOSPC : EIO;
|
||||||
|
inj.writes = 0;
|
||||||
|
memset(&cache, 0, sizeof(cache));
|
||||||
|
cache.type = 1;
|
||||||
|
cache.log = stderr;
|
||||||
|
cache.errlog = stderr;
|
||||||
|
cache.hashtable = coucal_new(0);
|
||||||
|
cache.zipOutput = selftest_open_failing_zip(path, &inj);
|
||||||
|
if (cache.zipOutput == NULL) {
|
||||||
|
fprintf(stderr, "cache-writefail: could not open injected ZIP\n");
|
||||||
|
fail++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
opt->state.exit_xh = 0; /* clear; the failing write must set it to -1 */
|
||||||
|
writefail_store(opt, &cache, "/blob.bin", body, body_len);
|
||||||
|
if (!cache.zipWriteFailed) {
|
||||||
|
fprintf(stderr, "cache-writefail: phase %d: write error not caught\n",
|
||||||
|
phase);
|
||||||
|
fail++;
|
||||||
|
}
|
||||||
|
if (opt->state.exit_xh != -1) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"cache-writefail: phase %d: mirror not aborted (exit_xh=%d)\n",
|
||||||
|
phase, opt->state.exit_xh);
|
||||||
|
fail++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* a flagged cache must no-op a sibling write: no further backend write */
|
||||||
|
writes_after_fail = inj.writes;
|
||||||
|
writefail_store(opt, &cache, "/blob2.bin", body, 16);
|
||||||
|
if (inj.writes != writes_after_fail) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"cache-writefail: phase %d: sibling write re-entered the broken "
|
||||||
|
"stream (%d extra backend writes)\n",
|
||||||
|
phase, inj.writes - writes_after_fail);
|
||||||
|
fail++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cache.zipOutput != NULL) {
|
||||||
|
zipClose(cache.zipOutput,
|
||||||
|
NULL); /* best-effort; may fail on the backend */
|
||||||
|
cache.zipOutput = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
freet(body);
|
||||||
|
return fail;
|
||||||
|
}
|
||||||
|
|
||||||
int cache_selftests(httrackp *opt, const char *dir) {
|
int cache_selftests(httrackp *opt, const char *dir) {
|
||||||
int failures = 0;
|
int failures = 0;
|
||||||
cache_back cache;
|
cache_back cache;
|
||||||
@@ -373,32 +501,34 @@ int cache_selftests(httrackp *opt, const char *dir) {
|
|||||||
StringCopy(opt->path_html, base);
|
StringCopy(opt->path_html, base);
|
||||||
StringCopy(opt->path_html_utf8, base);
|
StringCopy(opt->path_html_utf8, base);
|
||||||
}
|
}
|
||||||
opt->cache = 1;
|
opt->cache = HTS_CACHE_PRIORITY;
|
||||||
|
|
||||||
/* pass 1: create everything in a single write session */
|
/* pass 1: create everything in a single write session */
|
||||||
selftest_open_for_write(&cache, opt);
|
selftest_open_for_write(&cache, opt);
|
||||||
|
|
||||||
/* edge cases: normal HTML page */
|
/* edge cases (cdispo "" except where noted): normal HTML page */
|
||||||
store_entry(opt, &cache, "example.com", "/", "example.com/index.html", 200,
|
store_entry(opt, &cache, "example.com", "/", "example.com/index.html", 200,
|
||||||
"OK", "text/html", "utf-8", "Mon, 01 Jan 2024 00:00:00 GMT",
|
"OK", "text/html", "utf-8", "Mon, 01 Jan 2024 00:00:00 GMT",
|
||||||
"etag-normal", "", body_index, strlen(body_index));
|
"etag-normal", "", "", body_index, strlen(body_index));
|
||||||
/* redirect: empty body, empty optional fields, near-limit location */
|
/* redirect: empty body, empty optional fields, near-limit location */
|
||||||
store_entry(opt, &cache, "example.com", "/moved", "example.com/moved.html",
|
store_entry(opt, &cache, "example.com", "/moved", "example.com/moved.html",
|
||||||
301, "Moved Permanently", "text/html", "", "", "", location_long,
|
301, "Moved Permanently", "text/html", "", "", "", location_long,
|
||||||
NULL, 0);
|
"", NULL, 0);
|
||||||
/* non-HTML content-type kept in cache via all_in_cache, near-limit etag */
|
/* non-HTML content-type, near-limit etag */
|
||||||
store_entry(opt, &cache, "example.com", "/api", "example.com/api.json", 200,
|
store_entry(opt, &cache, "example.com", "/api", "example.com/api.json", 200,
|
||||||
"OK", "application/json", "utf-8",
|
"OK", "application/json", "utf-8",
|
||||||
"Tue, 02 Jan 2024 12:00:00 GMT", etag_long, "", body_api,
|
"Tue, 02 Jan 2024 12:00:00 GMT", etag_long, "", "", body_api,
|
||||||
strlen(body_api));
|
strlen(body_api));
|
||||||
/* binary body */
|
/* binary body, with a Content-Disposition */
|
||||||
store_entry(opt, &cache, "example.com", "/logo", "example.com/logo.png", 200,
|
store_entry(opt, &cache, "example.com", "/logo", "example.com/logo.png", 200,
|
||||||
"OK", "image/png", "", "", "etag-bin", "", binary_body,
|
"OK", "image/png", "", "", "etag-bin", "",
|
||||||
|
"attachment; filename=\"logo.png\"", binary_body,
|
||||||
sizeof(binary_body));
|
sizeof(binary_body));
|
||||||
/* error status with a body and a location (non-2xx codes are cached too) */
|
/* error status with a body and a location */
|
||||||
store_entry(opt, &cache, "example.com", "/gone", "example.com/gone.html", 404,
|
store_entry(opt, &cache, "example.com", "/gone", "example.com/gone.html", 404,
|
||||||
"Not Found", "text/html", "utf-8", "", "etag-404",
|
"Not Found", "text/html", "utf-8", "", "etag-404",
|
||||||
"https://example.com/where-it-went", body_404, strlen(body_404));
|
"https://example.com/where-it-went", "", body_404,
|
||||||
|
strlen(body_404));
|
||||||
|
|
||||||
/* scale: a few thousand small entries */
|
/* scale: a few thousand small entries */
|
||||||
for (i = 0; i < SELFTEST_VOLUME; i++) {
|
for (i = 0; i < SELFTEST_VOLUME; i++) {
|
||||||
@@ -408,7 +538,7 @@ int cache_selftests(httrackp *opt, const char *dir) {
|
|||||||
sprintf(save, "example.com/v/%05d.html", i);
|
sprintf(save, "example.com/v/%05d.html", i);
|
||||||
sprintf(body, "<html>volume entry %d</html>", i);
|
sprintf(body, "<html>volume entry %d</html>", i);
|
||||||
store_entry(opt, &cache, "example.com", fil, save, 200, "OK", "text/html",
|
store_entry(opt, &cache, "example.com", fil, save, 200, "OK", "text/html",
|
||||||
"utf-8", "", "", "", body, strlen(body));
|
"utf-8", "", "", "", "", body, strlen(body));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* compression: a few large bodies */
|
/* compression: a few large bodies */
|
||||||
@@ -418,7 +548,7 @@ int cache_selftests(httrackp *opt, const char *dir) {
|
|||||||
sprintf(fil, "/big/%d.bin", i);
|
sprintf(fil, "/big/%d.bin", i);
|
||||||
sprintf(save, "example.com/big/%d.bin", i);
|
sprintf(save, "example.com/big/%d.bin", i);
|
||||||
store_entry(opt, &cache, "example.com", fil, save, 200, "OK",
|
store_entry(opt, &cache, "example.com", fil, save, 200, "OK",
|
||||||
"application/octet-stream", "", "", "", "", large_body[i],
|
"application/octet-stream", "", "", "", "", "", large_body[i],
|
||||||
large_size[i]);
|
large_size[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -427,22 +557,24 @@ int cache_selftests(httrackp *opt, const char *dir) {
|
|||||||
/* pass 2: read back and verify everything round-tripped */
|
/* pass 2: read back and verify everything round-tripped */
|
||||||
selftest_open_for_read(&cache, opt);
|
selftest_open_for_read(&cache, opt);
|
||||||
|
|
||||||
failures += check_entry(opt, &cache, "example.com", "/", 200, "OK",
|
failures +=
|
||||||
"text/html", "utf-8", "Mon, 01 Jan 2024 00:00:00 GMT",
|
check_entry(opt, &cache, "example.com", "/", 200, "OK", "text/html",
|
||||||
"etag-normal", "", body_index, strlen(body_index));
|
"utf-8", "Mon, 01 Jan 2024 00:00:00 GMT", "etag-normal", "",
|
||||||
|
"", body_index, strlen(body_index));
|
||||||
failures += check_entry(opt, &cache, "example.com", "/moved", 301,
|
failures += check_entry(opt, &cache, "example.com", "/moved", 301,
|
||||||
"Moved Permanently", "text/html", "", "", "",
|
"Moved Permanently", "text/html", "", "", "",
|
||||||
location_long, NULL, 0);
|
location_long, "", NULL, 0);
|
||||||
failures +=
|
failures +=
|
||||||
check_entry(opt, &cache, "example.com", "/api", 200, "OK",
|
check_entry(opt, &cache, "example.com", "/api", 200, "OK",
|
||||||
"application/json", "utf-8", "Tue, 02 Jan 2024 12:00:00 GMT",
|
"application/json", "utf-8", "Tue, 02 Jan 2024 12:00:00 GMT",
|
||||||
etag_long, "", body_api, strlen(body_api));
|
etag_long, "", "", body_api, strlen(body_api));
|
||||||
failures +=
|
failures +=
|
||||||
check_entry(opt, &cache, "example.com", "/logo", 200, "OK", "image/png",
|
check_entry(opt, &cache, "example.com", "/logo", 200, "OK", "image/png",
|
||||||
"", "", "etag-bin", "", binary_body, sizeof(binary_body));
|
"", "", "etag-bin", "", "attachment; filename=\"logo.png\"",
|
||||||
|
binary_body, sizeof(binary_body));
|
||||||
failures += check_entry(opt, &cache, "example.com", "/gone", 404, "Not Found",
|
failures += check_entry(opt, &cache, "example.com", "/gone", 404, "Not Found",
|
||||||
"text/html", "utf-8", "", "etag-404",
|
"text/html", "utf-8", "", "etag-404",
|
||||||
"https://example.com/where-it-went", body_404,
|
"https://example.com/where-it-went", "", body_404,
|
||||||
strlen(body_404));
|
strlen(body_404));
|
||||||
|
|
||||||
for (i = 0; i < SELFTEST_VOLUME; i++) {
|
for (i = 0; i < SELFTEST_VOLUME; i++) {
|
||||||
@@ -452,7 +584,7 @@ int cache_selftests(httrackp *opt, const char *dir) {
|
|||||||
sprintf(body, "<html>volume entry %d</html>", i);
|
sprintf(body, "<html>volume entry %d</html>", i);
|
||||||
failures +=
|
failures +=
|
||||||
check_entry(opt, &cache, "example.com", fil, 200, "OK", "text/html",
|
check_entry(opt, &cache, "example.com", fil, 200, "OK", "text/html",
|
||||||
"utf-8", "", "", "", body, strlen(body));
|
"utf-8", "", "", "", "", body, strlen(body));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < large_count; i++) {
|
for (i = 0; i < large_count; i++) {
|
||||||
@@ -460,7 +592,7 @@ int cache_selftests(httrackp *opt, const char *dir) {
|
|||||||
|
|
||||||
sprintf(fil, "/big/%d.bin", i);
|
sprintf(fil, "/big/%d.bin", i);
|
||||||
failures += check_entry(opt, &cache, "example.com", fil, 200, "OK",
|
failures += check_entry(opt, &cache, "example.com", fil, 200, "OK",
|
||||||
"application/octet-stream", "", "", "", "",
|
"application/octet-stream", "", "", "", "", "",
|
||||||
large_body[i], large_size[i]);
|
large_body[i], large_size[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -470,7 +602,7 @@ int cache_selftests(httrackp *opt, const char *dir) {
|
|||||||
selftest_open_for_write(&cache, opt);
|
selftest_open_for_write(&cache, opt);
|
||||||
store_entry(opt, &cache, "example.com", "/", "example.com/index.html", 200,
|
store_entry(opt, &cache, "example.com", "/", "example.com/index.html", 200,
|
||||||
"OK", "text/html", "iso-8859-1", "Wed, 03 Jan 2024 09:30:00 GMT",
|
"OK", "text/html", "iso-8859-1", "Wed, 03 Jan 2024 09:30:00 GMT",
|
||||||
"etag-updated", "", body_updated, strlen(body_updated));
|
"etag-updated", "", "", body_updated, strlen(body_updated));
|
||||||
selftest_close(&cache);
|
selftest_close(&cache);
|
||||||
|
|
||||||
/* pass 4: re-read and confirm the updated value, not the old one */
|
/* pass 4: re-read and confirm the updated value, not the old one */
|
||||||
@@ -478,7 +610,7 @@ int cache_selftests(httrackp *opt, const char *dir) {
|
|||||||
failures +=
|
failures +=
|
||||||
check_entry(opt, &cache, "example.com", "/", 200, "OK", "text/html",
|
check_entry(opt, &cache, "example.com", "/", 200, "OK", "text/html",
|
||||||
"iso-8859-1", "Wed, 03 Jan 2024 09:30:00 GMT", "etag-updated",
|
"iso-8859-1", "Wed, 03 Jan 2024 09:30:00 GMT", "etag-updated",
|
||||||
"", body_updated, strlen(body_updated));
|
"", "", body_updated, strlen(body_updated));
|
||||||
selftest_close(&cache);
|
selftest_close(&cache);
|
||||||
|
|
||||||
/* pass 5: the disk-fallback read path (X-In-Cache: 0, body on disk) */
|
/* pass 5: the disk-fallback read path (X-In-Cache: 0, body on disk) */
|
||||||
@@ -490,3 +622,97 @@ int cache_selftests(httrackp *opt, const char *dir) {
|
|||||||
|
|
||||||
return failures;
|
return failures;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Golden fixture: a small frozen cache read back to guard the read path and ZIP
|
||||||
|
format. The table is the contract; tests/fixtures/cache-golden/.../new.zip is
|
||||||
|
a witness written once via `httrack -#B <dir> regen`. Bodies stay in the ZIP
|
||||||
|
(all_in_cache=1), so a read needs only new.zip -- fully portable. */
|
||||||
|
|
||||||
|
/* embedded NUL + high bytes: the binary-safe read path */
|
||||||
|
static const char golden_binary[] = {
|
||||||
|
'P', 'N', 'G', '\0', '\r', '\n', (char) 0xFF, (char) 0x80,
|
||||||
|
'\0', '\0', 'e', 'n', 'd', (char) 0xCA, (char) 0xFE, '\n'};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char *adr, *fil, *save, *msg, *contenttype, *charset, *lastmodified,
|
||||||
|
*etag, *location, *cdispo, *body;
|
||||||
|
size_t body_len;
|
||||||
|
int statuscode;
|
||||||
|
} golden_entry;
|
||||||
|
|
||||||
|
/* string-literal body + length (drops the terminator); the binary array passes
|
||||||
|
its length explicitly, every byte counts */
|
||||||
|
#define GBODY(s) (s), (sizeof(s) - 1)
|
||||||
|
|
||||||
|
static const golden_entry golden_entries[] = {
|
||||||
|
/* normal HTML page */
|
||||||
|
{"example.com", "/", "example.com/index.html", "OK", "text/html", "utf-8",
|
||||||
|
"Mon, 01 Jan 2024 00:00:00 GMT", "etag-normal", "", "",
|
||||||
|
GBODY("<html><body>hello</body></html>"), 200},
|
||||||
|
/* redirect: empty body and optionals, a Location */
|
||||||
|
{"example.com", "/moved", "example.com/moved.html", "Moved Permanently",
|
||||||
|
"text/html", "", "", "", "https://example.com/new-home", "", NULL, 0, 301},
|
||||||
|
/* non-HTML content */
|
||||||
|
{"example.com", "/api", "example.com/api.json", "OK", "application/json",
|
||||||
|
"utf-8", "Tue, 02 Jan 2024 12:00:00 GMT", "etag-api", "", "",
|
||||||
|
GBODY("{\"k\":\"v\"}"), 200},
|
||||||
|
/* binary body with a Content-Disposition */
|
||||||
|
{"example.com", "/logo", "example.com/logo.png", "OK", "image/png", "", "",
|
||||||
|
"etag-bin", "", "attachment; filename=\"logo.png\"", golden_binary,
|
||||||
|
sizeof(golden_binary), 200},
|
||||||
|
/* error status with a body and a Location */
|
||||||
|
{"example.com", "/gone", "example.com/gone.html", "Not Found", "text/html",
|
||||||
|
"utf-8", "", "etag-404", "https://example.com/where-it-went", "",
|
||||||
|
GBODY("<html><body>404 Not Found</body></html>"), 404},
|
||||||
|
};
|
||||||
|
|
||||||
|
#define GOLDEN_COUNT (sizeof(golden_entries) / sizeof(golden_entries[0]))
|
||||||
|
|
||||||
|
static void golden_setup(httrackp *opt, const char *dir) {
|
||||||
|
char base[HTS_URLMAXSIZE];
|
||||||
|
|
||||||
|
strcpybuff(base, dir);
|
||||||
|
if (base[0] != '\0' && base[strlen(base) - 1] != '/') {
|
||||||
|
strcatbuff(base, "/");
|
||||||
|
}
|
||||||
|
StringCopy(opt->path_log, base);
|
||||||
|
StringCopy(opt->path_html, base);
|
||||||
|
StringCopy(opt->path_html_utf8, base);
|
||||||
|
opt->cache = HTS_CACHE_PRIORITY;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cache_golden_selftest(httrackp *opt, const char *dir, int regen) {
|
||||||
|
int failures = 0;
|
||||||
|
size_t k;
|
||||||
|
cache_back cache;
|
||||||
|
|
||||||
|
selftest_tag = "cache-golden";
|
||||||
|
golden_setup(opt, dir);
|
||||||
|
|
||||||
|
/* regen rewrites the fixture from the table; the test never passes it, so the
|
||||||
|
read pass verifies bytes a previous build froze */
|
||||||
|
if (regen) {
|
||||||
|
selftest_open_for_write(&cache, opt);
|
||||||
|
for (k = 0; k < GOLDEN_COUNT; k++) {
|
||||||
|
const golden_entry *e = &golden_entries[k];
|
||||||
|
|
||||||
|
store_entry(opt, &cache, e->adr, e->fil, e->save, e->statuscode, e->msg,
|
||||||
|
e->contenttype, e->charset, e->lastmodified, e->etag,
|
||||||
|
e->location, e->cdispo, e->body, e->body_len);
|
||||||
|
}
|
||||||
|
selftest_close(&cache);
|
||||||
|
}
|
||||||
|
|
||||||
|
selftest_open_for_read(&cache, opt);
|
||||||
|
for (k = 0; k < GOLDEN_COUNT; k++) {
|
||||||
|
const golden_entry *e = &golden_entries[k];
|
||||||
|
|
||||||
|
failures +=
|
||||||
|
check_entry(opt, &cache, e->adr, e->fil, e->statuscode, e->msg,
|
||||||
|
e->contenttype, e->charset, e->lastmodified, e->etag,
|
||||||
|
e->location, e->cdispo, e->body, e->body_len);
|
||||||
|
}
|
||||||
|
selftest_close(&cache);
|
||||||
|
|
||||||
|
return failures;
|
||||||
|
}
|
||||||
|
|||||||
@@ -44,6 +44,18 @@ typedef struct httrackp httrackp;
|
|||||||
Returns the number of failed checks (0 == success). */
|
Returns the number of failed checks (0 == success). */
|
||||||
int cache_selftests(httrackp *opt, const char *dir);
|
int cache_selftests(httrackp *opt, const char *dir);
|
||||||
|
|
||||||
|
/* Read a committed (frozen) cache fixture under <dir>/hts-cache/new.zip and
|
||||||
|
assert a fixed set of entries decodes field- and byte-exact. Unlike
|
||||||
|
cache_selftests (write-then-read with the same build, a round-trip), this
|
||||||
|
reads bytes an earlier build froze, so it catches read-path / format drift.
|
||||||
|
regen!=0 first rewrites the fixture from the same table (to regenerate the
|
||||||
|
committed file, never by the test). Returns the failed-check count. */
|
||||||
|
int cache_golden_selftest(httrackp *opt, const char *dir, int regen);
|
||||||
|
|
||||||
|
/* #174/#219: assert a failing cache write aborts the mirror cleanly instead of
|
||||||
|
crashing. Returns the failed-check count. */
|
||||||
|
int cache_write_failure_selftest(httrackp *opt, const char *dir);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -135,7 +135,8 @@ HTSEXT_API T_SOC catch_url_init(int *port, /* 128 bytes */ char *adr) {
|
|||||||
// returns 0 if error
|
// returns 0 if error
|
||||||
// url: buffer where URL must be stored - or ip:port in case of failure
|
// url: buffer where URL must be stored - or ip:port in case of failure
|
||||||
// data: 32Kb
|
// data: 32Kb
|
||||||
HTSEXT_API int catch_url(T_SOC soc, char *url, char *method, char *data) {
|
HTSEXT_API hts_boolean catch_url(T_SOC soc, char *url, char *method,
|
||||||
|
char *data) {
|
||||||
int retour = 0;
|
int retour = 0;
|
||||||
|
|
||||||
// connexion (accept)
|
// connexion (accept)
|
||||||
|
|||||||
@@ -52,12 +52,12 @@ Please visit our Website: http://www.httrack.com
|
|||||||
#define DEFAULT_FTP "index.txt"
|
#define DEFAULT_FTP "index.txt"
|
||||||
|
|
||||||
// extension par défaut pour fichiers n'en ayant pas
|
// extension par défaut pour fichiers n'en ayant pas
|
||||||
#define DEFAULT_EXT ".html"
|
#define DEFAULT_EXT ".html"
|
||||||
#define DEFAULT_EXT_SHORT ".htm"
|
#define DEFAULT_EXT_SHORT ".htm"
|
||||||
//#define DEFAULT_BIN_EXT ".bin"
|
// #define DEFAULT_BIN_EXT ".bin"
|
||||||
//#define DEFAULT_BIN_EXT_SHORT ".bin"
|
// #define DEFAULT_BIN_EXT_SHORT ".bin"
|
||||||
//#define DEFAULT_EXT ".txt"
|
// #define DEFAULT_EXT ".txt"
|
||||||
//#define DEFAULT_EXT_SHORT ".txt"
|
// #define DEFAULT_EXT_SHORT ".txt"
|
||||||
|
|
||||||
// éviter les /nul, /con..
|
// éviter les /nul, /con..
|
||||||
#define HTS_OVERRIDE_DOS_FOLDERS 1
|
#define HTS_OVERRIDE_DOS_FOLDERS 1
|
||||||
@@ -87,7 +87,8 @@ Please visit our Website: http://www.httrack.com
|
|||||||
// fast cache (build hash table)
|
// fast cache (build hash table)
|
||||||
#define HTS_FAST_CACHE 1
|
#define HTS_FAST_CACHE 1
|
||||||
|
|
||||||
// le > peut être considéré comme un tag de fermeture de commentaire (<!-- > est valide)
|
// le > peut être considéré comme un tag de fermeture de commentaire (<!-- > est
|
||||||
|
// valide)
|
||||||
#define GT_ENDS_COMMENT 1
|
#define GT_ENDS_COMMENT 1
|
||||||
|
|
||||||
// always adds a '/' at the end if a '~' is encountered (/~smith -> /~smith/)
|
// always adds a '/' at the end if a '~' is encountered (/~smith -> /~smith/)
|
||||||
@@ -97,7 +98,8 @@ Please visit our Website: http://www.httrack.com
|
|||||||
#define HTS_STRIP_DOUBLE_SLASH 0
|
#define HTS_STRIP_DOUBLE_SLASH 0
|
||||||
|
|
||||||
// case-sensitive pour les dossiers et fichiers (0/1)
|
// case-sensitive pour les dossiers et fichiers (0/1)
|
||||||
// [normalement 1, mais pose des problèmes (url malformée par exemple) et n'est pas très utile..
|
// [normalement 1, mais pose des problèmes (url malformée par exemple) et n'est
|
||||||
|
// pas très utile..
|
||||||
// ..et pas bcp respecté]
|
// ..et pas bcp respecté]
|
||||||
// REMOVED
|
// REMOVED
|
||||||
// #define HTS_CASSE 0
|
// #define HTS_CASSE 0
|
||||||
|
|||||||
@@ -736,26 +736,39 @@ int httpmirror(char *url1, httrackp * opt) {
|
|||||||
/* OPTIMIZED for fast load */
|
/* OPTIMIZED for fast load */
|
||||||
if (StringNotEmpty(opt->filelist)) {
|
if (StringNotEmpty(opt->filelist)) {
|
||||||
char *filelist_buff = NULL;
|
char *filelist_buff = NULL;
|
||||||
const size_t filelist_sz = off_t_to_size_t(fsize(StringBuff(opt->filelist)));
|
size_t filelist_sz = 0;
|
||||||
|
const char *filelist_err = NULL; /* failure reason, NULL on success */
|
||||||
|
const off_t fs = fsize(StringBuff(opt->filelist));
|
||||||
|
|
||||||
if (filelist_sz != (size_t) -1) {
|
if (fs < 0) {
|
||||||
|
/* fsize() hides the cause; redo stat() for a precise errno (#49) */
|
||||||
|
struct stat st;
|
||||||
|
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) {
|
||||||
|
filelist_err = "file too large";
|
||||||
|
filelist_sz = 0;
|
||||||
|
} else {
|
||||||
FILE *fp = fopen(StringBuff(opt->filelist), "rb");
|
FILE *fp = fopen(StringBuff(opt->filelist), "rb");
|
||||||
|
|
||||||
if (fp) {
|
if (fp == NULL) {
|
||||||
|
filelist_err = strerror(errno);
|
||||||
|
} else {
|
||||||
filelist_buff = malloct(filelist_sz + 1);
|
filelist_buff = malloct(filelist_sz + 1);
|
||||||
if (filelist_buff) {
|
if (filelist_buff == NULL) {
|
||||||
if (fread(filelist_buff, 1, filelist_sz, fp) != filelist_sz) {
|
filelist_err = "out of memory";
|
||||||
freet(filelist_buff);
|
} else if (fread(filelist_buff, 1, filelist_sz, fp) != filelist_sz) {
|
||||||
filelist_buff = NULL;
|
freet(filelist_buff);
|
||||||
} else {
|
filelist_err = "read error";
|
||||||
*(filelist_buff + filelist_sz) = '\0';
|
} else {
|
||||||
}
|
filelist_buff[filelist_sz] = '\0';
|
||||||
}
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filelist_buff) {
|
if (filelist_buff != NULL) {
|
||||||
int filelist_ptr = 0;
|
int filelist_ptr = 0;
|
||||||
int n = 0;
|
int n = 0;
|
||||||
char BIGSTK line[HTS_URLMAXSIZE * 2];
|
char BIGSTK line[HTS_URLMAXSIZE * 2];
|
||||||
@@ -780,8 +793,8 @@ int httpmirror(char *url1, httrackp * opt) {
|
|||||||
// Free buffer
|
// Free buffer
|
||||||
freet(filelist_buff);
|
freet(filelist_buff);
|
||||||
} else {
|
} else {
|
||||||
hts_log_print(opt, LOG_ERROR, "Could not include URL list: %s",
|
hts_log_print(opt, LOG_ERROR, "Could not include URL list \"%s\": %s",
|
||||||
StringBuff(opt->filelist));
|
StringBuff(opt->filelist), filelist_err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1835,9 +1848,10 @@ int httpmirror(char *url1, httrackp * opt) {
|
|||||||
a++; // sauter espace(s)
|
a++; // sauter espace(s)
|
||||||
if (strnotempty(a)) {
|
if (strnotempty(a)) {
|
||||||
#ifdef IGNORE_RESTRICTIVE_ROBOTS
|
#ifdef IGNORE_RESTRICTIVE_ROBOTS
|
||||||
if (strcmp(a, "/") != 0 || opt->robots >= 3)
|
if (strcmp(a, "/") != 0 ||
|
||||||
|
opt->robots >= HTS_ROBOTS_ALWAYS_STRICT)
|
||||||
#endif
|
#endif
|
||||||
{ /* ignoring disallow: / */
|
{ /* ignoring disallow: / */
|
||||||
if ((strlen(buff) + strlen(a) + 8) < sizeof(buff)) {
|
if ((strlen(buff) + strlen(a) + 8) < sizeof(buff)) {
|
||||||
strcatbuff(buff, a);
|
strcatbuff(buff, a);
|
||||||
strcatbuff(buff, "\n");
|
strcatbuff(buff, "\n");
|
||||||
@@ -1932,10 +1946,10 @@ int httpmirror(char *url1, httrackp * opt) {
|
|||||||
"Warning: store %s without scan: %s", r.contenttype,
|
"Warning: store %s without scan: %s", r.contenttype,
|
||||||
savename());
|
savename());
|
||||||
} else {
|
} else {
|
||||||
if ((opt->getmode & 2) != 0) { // ok autorisé
|
if ((opt->getmode & HTS_GETMODE_NONHTML) != 0) {
|
||||||
hts_log_print(opt, LOG_DEBUG, "Store %s: %s", r.contenttype,
|
hts_log_print(opt, LOG_DEBUG, "Store %s: %s", r.contenttype,
|
||||||
savename());
|
savename());
|
||||||
} else { // lien non autorisé! (ex: cgi-bin en html)
|
} else { // lien non autorisé! (ex: cgi-bin en html)
|
||||||
hts_log_print(opt, LOG_DEBUG,
|
hts_log_print(opt, LOG_DEBUG,
|
||||||
"non-html file ignored after upload at %s : %s",
|
"non-html file ignored after upload at %s : %s",
|
||||||
urladr(), urlfil());
|
urladr(), urlfil());
|
||||||
@@ -2052,7 +2066,7 @@ int httpmirror(char *url1, httrackp * opt) {
|
|||||||
ptr++;
|
ptr++;
|
||||||
|
|
||||||
// faut-il sauter le(s) lien(s) suivant(s)? (fichiers images à passer après les html)
|
// faut-il sauter le(s) lien(s) suivant(s)? (fichiers images à passer après les html)
|
||||||
if (opt->getmode & 4) { // sauver les non html après
|
if (opt->getmode & HTS_GETMODE_HTML_FIRST) {
|
||||||
// sauter les fichiers selon la passe
|
// sauter les fichiers selon la passe
|
||||||
if (!numero_passe) {
|
if (!numero_passe) {
|
||||||
while((ptr < opt->lien_tot) ? (heap(ptr)->pass2) : 0)
|
while((ptr < opt->lien_tot) ? (heap(ptr)->pass2) : 0)
|
||||||
@@ -2584,7 +2598,7 @@ static int mkdir_compat(const char *pathname) {
|
|||||||
|
|
||||||
/* path must end with "/" or with the finename (/tmp/bar/ or /tmp/bar/foo.zip) */
|
/* path must end with "/" or with the finename (/tmp/bar/ or /tmp/bar/foo.zip) */
|
||||||
/* Note: preserve errno */
|
/* Note: preserve errno */
|
||||||
HTSEXT_API int dir_exists(const char *path) {
|
HTSEXT_API hts_boolean dir_exists(const char *path) {
|
||||||
const int err = errno;
|
const int err = errno;
|
||||||
STRUCT_STAT st;
|
STRUCT_STAT st;
|
||||||
char BIGSTK file[HTS_URLMAXSIZE * 2];
|
char BIGSTK file[HTS_URLMAXSIZE * 2];
|
||||||
@@ -3341,7 +3355,8 @@ int back_fill(struct_back * sback, httrackp * opt, cache_back * cache,
|
|||||||
int ptr, int numero_passe) {
|
int ptr, int numero_passe) {
|
||||||
int n = back_pluggable_sockets(sback, opt);
|
int n = back_pluggable_sockets(sback, opt);
|
||||||
|
|
||||||
if (opt->savename_delayed == 2 && !opt->delayed_cached) /* cancel (always delayed) */
|
if (opt->savename_delayed == HTS_SAVENAME_DELAYED_HARD &&
|
||||||
|
!opt->delayed_cached) /* cancel (always delayed) */
|
||||||
return 0;
|
return 0;
|
||||||
if (n > 0) {
|
if (n > 0) {
|
||||||
int p;
|
int p;
|
||||||
@@ -3645,7 +3660,7 @@ HTSEXT_API int hts_setpause(httrackp * opt, int p) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ask for termination
|
// ask for termination
|
||||||
HTSEXT_API int hts_request_stop(httrackp * opt, int force) {
|
HTSEXT_API int hts_request_stop(httrackp *opt, hts_boolean force) {
|
||||||
if (opt != NULL) {
|
if (opt != NULL) {
|
||||||
hts_log_print(opt, LOG_ERROR, "Exit requested by shell or user");
|
hts_log_print(opt, LOG_ERROR, "Exit requested by shell or user");
|
||||||
hts_mutexlock(&opt->state.lock);
|
hts_mutexlock(&opt->state.lock);
|
||||||
@@ -3655,7 +3670,7 @@ HTSEXT_API int hts_request_stop(httrackp * opt, int force) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
HTSEXT_API int hts_has_stopped(httrackp * opt) {
|
HTSEXT_API hts_boolean hts_has_stopped(httrackp *opt) {
|
||||||
int ended;
|
int ended;
|
||||||
hts_mutexlock(&opt->state.lock);
|
hts_mutexlock(&opt->state.lock);
|
||||||
ended = opt->state.is_ended;
|
ended = opt->state.is_ended;
|
||||||
@@ -3677,12 +3692,12 @@ HTSEXT_API int hts_has_stopped(httrackp * opt) {
|
|||||||
//}
|
//}
|
||||||
// ajout d'URL
|
// ajout d'URL
|
||||||
// -1 : erreur
|
// -1 : erreur
|
||||||
HTSEXT_API int hts_addurl(httrackp * opt, char **url) {
|
HTSEXT_API hts_boolean hts_addurl(httrackp *opt, char **url) {
|
||||||
if (url)
|
if (url)
|
||||||
opt->state._hts_addurl = url;
|
opt->state._hts_addurl = url;
|
||||||
return (opt->state._hts_addurl != NULL);
|
return (opt->state._hts_addurl != NULL);
|
||||||
}
|
}
|
||||||
HTSEXT_API int hts_resetaddurl(httrackp * opt) {
|
HTSEXT_API hts_boolean hts_resetaddurl(httrackp *opt) {
|
||||||
opt->state._hts_addurl = NULL;
|
opt->state._hts_addurl = NULL;
|
||||||
return (opt->state._hts_addurl != NULL);
|
return (opt->state._hts_addurl != NULL);
|
||||||
}
|
}
|
||||||
@@ -3701,6 +3716,8 @@ HTSEXT_API int copy_htsopt(const httrackp * from, httrackp * to) {
|
|||||||
if (from->maxsoc > 0)
|
if (from->maxsoc > 0)
|
||||||
to->maxsoc = from->maxsoc;
|
to->maxsoc = from->maxsoc;
|
||||||
|
|
||||||
|
/* hts_tristate fields use HTS_DEFAULT (-1) for "unspecified": copy_htsopt
|
||||||
|
skips them so the target keeps its value. */
|
||||||
if (from->nearlink > -1)
|
if (from->nearlink > -1)
|
||||||
to->nearlink = from->nearlink;
|
to->nearlink = from->nearlink;
|
||||||
|
|
||||||
@@ -3722,6 +3739,9 @@ HTSEXT_API int copy_htsopt(const httrackp * from, httrackp * to) {
|
|||||||
if (StringNotEmpty(from->user_agent))
|
if (StringNotEmpty(from->user_agent))
|
||||||
StringCopyS(to->user_agent, from->user_agent);
|
StringCopyS(to->user_agent, from->user_agent);
|
||||||
|
|
||||||
|
if (StringNotEmpty(from->strip_query))
|
||||||
|
StringCopyS(to->strip_query, from->strip_query);
|
||||||
|
|
||||||
if (from->retry > -1)
|
if (from->retry > -1)
|
||||||
to->retry = from->retry;
|
to->retry = from->retry;
|
||||||
|
|
||||||
@@ -3736,10 +3756,10 @@ HTSEXT_API int copy_htsopt(const httrackp * from, httrackp * to) {
|
|||||||
|
|
||||||
// test all: bit 8 de travel
|
// test all: bit 8 de travel
|
||||||
if (from->travel > -1) {
|
if (from->travel > -1) {
|
||||||
if (from->travel & 256)
|
if (from->travel & HTS_TRAVEL_TEST_ALL)
|
||||||
to->travel |= 256;
|
to->travel |= HTS_TRAVEL_TEST_ALL;
|
||||||
else
|
else
|
||||||
to->travel &= 255;
|
to->travel &= HTS_TRAVEL_SCOPE_MASK;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -3843,7 +3863,7 @@ int htsAddLink(htsmoduleStruct * str, char *link) {
|
|||||||
a = opt->savename_type;
|
a = opt->savename_type;
|
||||||
b = opt->savename_83;
|
b = opt->savename_83;
|
||||||
opt->savename_type = 0;
|
opt->savename_type = 0;
|
||||||
opt->savename_83 = 0;
|
opt->savename_83 = HTS_SAVENAME_83_LONG;
|
||||||
// note: adr,fil peuvent être patchés
|
// note: adr,fil peuvent être patchés
|
||||||
r =
|
r =
|
||||||
url_savename(&afs, NULL, NULL, NULL, opt, sback, cache, hashptr, ptr, numero_passe,
|
url_savename(&afs, NULL, NULL, NULL, opt, sback, cache, hashptr, ptr, numero_passe,
|
||||||
|
|||||||
243
src/htscore.h
243
src/htscore.h
@@ -30,7 +30,9 @@ Please visit our Website: http://www.httrack.com
|
|||||||
/* Author: Xavier Roche */
|
/* Author: Xavier Roche */
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
|
||||||
// Fichier librairie .h
|
/* Core engine declarations. Not an installed header, but part of the de-facto
|
||||||
|
API surface: external consumers (e.g. httrack-android) read these structs and
|
||||||
|
constants and call functions declared here. */
|
||||||
#ifndef HTS_CORE_DEFH
|
#ifndef HTS_CORE_DEFH
|
||||||
#define HTS_CORE_DEFH
|
#define HTS_CORE_DEFH
|
||||||
|
|
||||||
@@ -38,7 +40,7 @@ Please visit our Website: http://www.httrack.com
|
|||||||
|
|
||||||
/* specific definitions */
|
/* specific definitions */
|
||||||
#include "htsbase.h"
|
#include "htsbase.h"
|
||||||
// Includes & définitions
|
/* Includes and definitions */
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@@ -83,45 +85,45 @@ typedef struct filecreate_params filecreate_params;
|
|||||||
// options
|
// options
|
||||||
#include "htsopt.h"
|
#include "htsopt.h"
|
||||||
|
|
||||||
// INCLUDES .H PARTIES DE CODE HTTRACK
|
// HTTrack engine sub-headers
|
||||||
|
|
||||||
// routine main
|
// main entry point
|
||||||
#include "htscoremain.h"
|
#include "htscoremain.h"
|
||||||
|
|
||||||
// core routines
|
// core routines
|
||||||
#include "htscore.h"
|
#include "htscore.h"
|
||||||
|
|
||||||
// divers outils pour httrack.c
|
// misc tools for httrack.c
|
||||||
#include "htstools.h"
|
#include "htstools.h"
|
||||||
|
|
||||||
// aide pour la version en ligne de commande
|
// command-line help
|
||||||
#include "htshelp.h"
|
#include "htshelp.h"
|
||||||
|
|
||||||
// génération du nom de fichier à sauver
|
// build the on-disk save filename
|
||||||
#include "htsname.h"
|
#include "htsname.h"
|
||||||
|
|
||||||
// gestion ftp
|
// FTP support
|
||||||
#include "htsftp.h"
|
#include "htsftp.h"
|
||||||
|
|
||||||
// gestion interception d'URL
|
// URL interception
|
||||||
#include "htscatchurl.h"
|
#include "htscatchurl.h"
|
||||||
|
|
||||||
// gestion robots.txt
|
// robots.txt handling
|
||||||
#include "htsrobots.h"
|
#include "htsrobots.h"
|
||||||
|
|
||||||
// routines d'acceptation de liens
|
// link-acceptance rules
|
||||||
#include "htswizard.h"
|
#include "htswizard.h"
|
||||||
|
|
||||||
// routines de regexp
|
// regexp/filter routines
|
||||||
#include "htsfilters.h"
|
#include "htsfilters.h"
|
||||||
|
|
||||||
// gestion backing
|
// download backing (the back[] slot ring)
|
||||||
#include "htsback.h"
|
#include "htsback.h"
|
||||||
|
|
||||||
// gestion cache
|
// cache handling
|
||||||
#include "htscache.h"
|
#include "htscache.h"
|
||||||
|
|
||||||
// gestion hashage
|
// hashing
|
||||||
#include "htshash.h"
|
#include "htshash.h"
|
||||||
#include "coucal.h"
|
#include "coucal.h"
|
||||||
|
|
||||||
@@ -129,87 +131,115 @@ typedef struct filecreate_params filecreate_params;
|
|||||||
|
|
||||||
#include "hts-indextmpl.h"
|
#include "hts-indextmpl.h"
|
||||||
|
|
||||||
// adr, fil
|
/** A remote URL split into host and path, each a fixed inline buffer
|
||||||
|
(HTS_URLMAXSIZE*2 bytes, NUL-terminated). */
|
||||||
#ifndef HTS_DEF_FWSTRUCT_lien_adrfil
|
#ifndef HTS_DEF_FWSTRUCT_lien_adrfil
|
||||||
#define HTS_DEF_FWSTRUCT_lien_adrfil
|
#define HTS_DEF_FWSTRUCT_lien_adrfil
|
||||||
typedef struct lien_adrfil lien_adrfil;
|
typedef struct lien_adrfil lien_adrfil;
|
||||||
#endif
|
#endif
|
||||||
struct lien_adrfil {
|
struct lien_adrfil {
|
||||||
char adr[HTS_URLMAXSIZE * 2]; // adresse
|
char adr[HTS_URLMAXSIZE * 2]; /**< host (address) */
|
||||||
char fil[HTS_URLMAXSIZE * 2]; // nom du fichier distant
|
char fil[HTS_URLMAXSIZE * 2]; /**< remote file path */
|
||||||
};
|
};
|
||||||
|
|
||||||
// adr, fil, save
|
/** A remote URL plus the local on-disk path it is saved to. */
|
||||||
#ifndef HTS_DEF_FWSTRUCT_lien_adrfilsave
|
#ifndef HTS_DEF_FWSTRUCT_lien_adrfilsave
|
||||||
#define HTS_DEF_FWSTRUCT_lien_adrfilsave
|
#define HTS_DEF_FWSTRUCT_lien_adrfilsave
|
||||||
typedef struct lien_adrfilsave lien_adrfilsave;
|
typedef struct lien_adrfilsave lien_adrfilsave;
|
||||||
#endif
|
#endif
|
||||||
struct lien_adrfilsave {
|
struct lien_adrfilsave {
|
||||||
lien_adrfil af;
|
lien_adrfil af;
|
||||||
char save[HTS_URLMAXSIZE * 2]; // nom à sauver sur disque (avec chemin éventuel)
|
char save[HTS_URLMAXSIZE * 2]; /**< local save path (with directory) */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Per-slot connect-fallback bookkeeping (parallel to struct_back.lnk).
|
||||||
|
Tracks which resolved address the slot is currently connecting to so a
|
||||||
|
stuck connect can be retried against the next one. */
|
||||||
|
typedef struct hts_connect_fallback {
|
||||||
|
int addr_index; /**< candidate being connected (0-based) */
|
||||||
|
int addr_count; /**< resolved addresses; -1 = not yet probed */
|
||||||
|
TStamp connect_start; /**< when the current candidate's connect began */
|
||||||
|
} hts_connect_fallback;
|
||||||
|
|
||||||
|
/** The download-slot ring: the set of concurrent transfers in flight.
|
||||||
|
Allocated/owned by the engine; consumers (status callbacks, the loop)
|
||||||
|
read it but do not resize or free it. */
|
||||||
#ifndef HTS_DEF_FWSTRUCT_struct_back
|
#ifndef HTS_DEF_FWSTRUCT_struct_back
|
||||||
#define HTS_DEF_FWSTRUCT_struct_back
|
#define HTS_DEF_FWSTRUCT_struct_back
|
||||||
typedef struct struct_back struct_back;
|
typedef struct struct_back struct_back;
|
||||||
#endif
|
#endif
|
||||||
struct struct_back {
|
struct struct_back {
|
||||||
lien_back *lnk;
|
lien_back *lnk; /**< slot array, valid indices [0..count-1]
|
||||||
int count;
|
(count+1 entries allocated); a slot is
|
||||||
coucal ready;
|
active iff lnk[i].status != STATUS_FREE.
|
||||||
LLint ready_size_bytes;
|
See struct lien_back in htsopt.h and the
|
||||||
|
STATUS_* codes in htsbasenet.h. */
|
||||||
|
int count; /**< number of usable slots (back_max) */
|
||||||
|
coucal ready; /**< index of slots whose transfer completed */
|
||||||
|
LLint ready_size_bytes; /**< total bytes buffered in completed slots */
|
||||||
|
hts_connect_fallback *connect_fallback; /**< per-slot, count+1 entries */
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct cache_back_zip_entry cache_back_zip_entry;
|
typedef struct cache_back_zip_entry cache_back_zip_entry;
|
||||||
|
|
||||||
// cache
|
/** Open handle to the mirror cache (the read-from-old / write-to-new state
|
||||||
|
used to resume and to avoid re-fetching unchanged files). Engine-owned. */
|
||||||
#ifndef HTS_DEF_FWSTRUCT_cache_back
|
#ifndef HTS_DEF_FWSTRUCT_cache_back
|
||||||
#define HTS_DEF_FWSTRUCT_cache_back
|
#define HTS_DEF_FWSTRUCT_cache_back
|
||||||
typedef struct cache_back cache_back;
|
typedef struct cache_back cache_back;
|
||||||
#endif
|
#endif
|
||||||
struct cache_back {
|
struct cache_back {
|
||||||
int version; // 0 ou 1
|
int version; /**< cache-file format version being read */
|
||||||
/* */
|
/* */
|
||||||
int type;
|
int type;
|
||||||
int ro;
|
int ro; /**< read-only: no new cache is written */
|
||||||
FILE *dat, *ndx, *olddat;
|
FILE *dat, *ndx, *olddat; /**< new data, new index, old data files */
|
||||||
char *use; // liste des adr+fil
|
char *use; /**< in-memory list of cached adr+fil keys */
|
||||||
FILE *lst; // liste des fichiers pour la "purge"
|
FILE *lst; /**< file list, used for purge */
|
||||||
FILE *txt; // liste des fichiers (info)
|
FILE *txt; /**< human-readable file list (info) */
|
||||||
char lastmodified[256];
|
char lastmodified[256];
|
||||||
// HASH
|
// HASH
|
||||||
coucal hashtable;
|
coucal hashtable;
|
||||||
// HASH for tests (naming subsystem)
|
// HASH for tests (naming subsystem)
|
||||||
coucal cached_tests;
|
coucal cached_tests;
|
||||||
// fichiers log optionnels
|
/* optional log files */
|
||||||
FILE *log;
|
FILE *log;
|
||||||
FILE *errlog;
|
FILE *errlog;
|
||||||
// variables
|
/* read-ahead cursors into the old cache */
|
||||||
int ptr_ant; // pointeur pour anticiper
|
int ptr_ant;
|
||||||
int ptr_last; // pointeur pour anticiper
|
int ptr_last;
|
||||||
//
|
/* ZIP-backed cache backend (newer format) */
|
||||||
void *zipInput;
|
void *zipInput;
|
||||||
void *zipOutput;
|
void *zipOutput;
|
||||||
cache_back_zip_entry *zipEntries;
|
cache_back_zip_entry *zipEntries;
|
||||||
int zipEntriesOffs;
|
int zipEntriesOffs;
|
||||||
int zipEntriesCapa;
|
int zipEntriesCapa;
|
||||||
|
hts_boolean
|
||||||
|
zipWriteFailed; /**< a cache write failed; stop touching the stream */
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef HTS_DEF_FWSTRUCT_hash_struct
|
#ifndef HTS_DEF_FWSTRUCT_hash_struct
|
||||||
#define HTS_DEF_FWSTRUCT_hash_struct
|
#define HTS_DEF_FWSTRUCT_hash_struct
|
||||||
typedef struct hash_struct hash_struct;
|
typedef struct hash_struct hash_struct;
|
||||||
#endif
|
#endif
|
||||||
|
/** Lookup indexes over the link heap: map save-name / URL back to a link, so a
|
||||||
|
URL seen twice resolves to one entry. The coucal tables index into liens;
|
||||||
|
they do not own the links. */
|
||||||
struct hash_struct {
|
struct hash_struct {
|
||||||
/* Links big array reference */
|
/* points at the engine's link array (opt->liens); not owned */
|
||||||
const lien_url *const*const*liens;
|
const lien_url *const*const*liens;
|
||||||
/* Savename (case insensitive ; lowercased) */
|
/* save-name -> link index (case-insensitive: keys lowercased) */
|
||||||
coucal sav;
|
coucal sav;
|
||||||
/* Address and path */
|
/* address+path -> link index */
|
||||||
coucal adrfil;
|
coucal adrfil;
|
||||||
/* Former address and path */
|
/* former address+path -> link index (renamed/moved entries) */
|
||||||
coucal former_adrfil;
|
coucal former_adrfil;
|
||||||
/** Buffers **/
|
/* effective urlhack sub-flags: www.==host / // collapse / query-arg sort */
|
||||||
int normalized;
|
hts_boolean norm_host;
|
||||||
|
hts_boolean norm_slash;
|
||||||
|
hts_boolean norm_query;
|
||||||
|
/* query-strip keys (not owned); set from opt->strip_query at hash_init */
|
||||||
|
const char *strip_query;
|
||||||
char normfil[HTS_URLMAXSIZE * 2];
|
char normfil[HTS_URLMAXSIZE * 2];
|
||||||
char normfil2[HTS_URLMAXSIZE * 2];
|
char normfil2[HTS_URLMAXSIZE * 2];
|
||||||
char catbuff[CATBUFF_SIZE];
|
char catbuff[CATBUFF_SIZE];
|
||||||
@@ -219,113 +249,194 @@ struct hash_struct {
|
|||||||
#define HTS_DEF_FWSTRUCT_filecreate_params
|
#define HTS_DEF_FWSTRUCT_filecreate_params
|
||||||
typedef struct filecreate_params filecreate_params;
|
typedef struct filecreate_params filecreate_params;
|
||||||
#endif
|
#endif
|
||||||
|
/** Parameters threaded through file-creation callbacks (filenote). */
|
||||||
struct filecreate_params {
|
struct filecreate_params {
|
||||||
FILE *lst;
|
FILE *lst; /**< open file list to append created paths to */
|
||||||
char path[HTS_URLMAXSIZE * 2];
|
char path[HTS_URLMAXSIZE * 2];
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Access macros. */
|
/* Convenience accessors over the link heap; assume `opt` (and where used,
|
||||||
|
`ptr`/`parent_relative`) are in scope. heap(N) is the Nth link;
|
||||||
|
heap_top_index() is the last recorded link's index. */
|
||||||
#define heap(N) (opt->liens[N])
|
#define heap(N) (opt->liens[N])
|
||||||
|
|
||||||
#define heap_top_index() (opt->lien_tot - 1)
|
#define heap_top_index() (opt->lien_tot - 1)
|
||||||
|
|
||||||
#define heap_top() (heap(heap_top_index()))
|
#define heap_top() (heap(heap_top_index()))
|
||||||
|
|
||||||
#define urladr() (heap(ptr)->adr)
|
#define urladr() (heap(ptr)->adr)
|
||||||
|
|
||||||
#define urlfil() (heap(ptr)->fil)
|
#define urlfil() (heap(ptr)->fil)
|
||||||
|
|
||||||
#define savename() (heap(ptr)->sav)
|
#define savename() (heap(ptr)->sav)
|
||||||
|
|
||||||
#define parenturladr() (heap(heap(ptr)->precedent)->adr)
|
#define parenturladr() (heap(heap(ptr)->precedent)->adr)
|
||||||
|
|
||||||
#define parenturlfil() (heap(heap(ptr)->precedent)->fil)
|
#define parenturlfil() (heap(heap(ptr)->precedent)->fil)
|
||||||
|
|
||||||
#define parentsavename() (heap(heap(ptr)->precedent)->sav)
|
#define parentsavename() (heap(heap(ptr)->precedent)->sav)
|
||||||
|
|
||||||
#define relativeurladr() ((!parent_relative)?urladr():parenturladr())
|
#define relativeurladr() ((!parent_relative)?urladr():parenturladr())
|
||||||
|
|
||||||
#define relativeurlfil() ((!parent_relative)?urlfil():parenturlfil())
|
#define relativeurlfil() ((!parent_relative)?urlfil():parenturlfil())
|
||||||
|
|
||||||
#define relativesavename() ((!parent_relative)?savename():parentsavename())
|
#define relativesavename() ((!parent_relative)?savename():parentsavename())
|
||||||
|
|
||||||
/* Library internal definictions */
|
/* Library-internal helpers (engine-only, HTS_INTERNAL_BYTECODE). */
|
||||||
#ifdef HTS_INTERNAL_BYTECODE
|
#ifdef HTS_INTERNAL_BYTECODE
|
||||||
|
|
||||||
|
/* True if a new cache is being written (plain or zip backend). */
|
||||||
HTS_STATIC int cache_writable(cache_back * cache) {
|
HTS_STATIC int cache_writable(cache_back * cache) {
|
||||||
return (cache != NULL && (cache->dat != NULL || cache->zipOutput != NULL));
|
return (cache != NULL && (cache->dat != NULL || cache->zipOutput != NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* True if an old cache is available to read (plain or zip backend). */
|
||||||
HTS_STATIC int cache_readable(cache_back * cache) {
|
HTS_STATIC int cache_readable(cache_back * cache) {
|
||||||
return (cache != NULL && (cache->olddat != NULL || cache->zipInput != NULL));
|
return (cache != NULL && (cache->olddat != NULL || cache->zipInput != NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Fonctions
|
// Functions
|
||||||
|
|
||||||
// INCLUDES .H PARTIES DE CODE HTTRACK
|
/* Library-internal only (engine TUs). */
|
||||||
|
|
||||||
/* Library internal definictions */
|
|
||||||
#ifdef HTS_INTERNAL_BYTECODE
|
#ifdef HTS_INTERNAL_BYTECODE
|
||||||
|
|
||||||
char *hts_cancel_file_pop(httrackp * opt);
|
char *hts_cancel_file_pop(httrackp * opt);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// add a link on the heap
|
/* Record a link on the heap. All strings are copied (caller keeps ownership).
|
||||||
|
Returns 1 on success, 0 if the link limit (opt->maxlink) is reached. */
|
||||||
int hts_record_link(httrackp * opt,
|
int hts_record_link(httrackp * opt,
|
||||||
const char *address, const char *file, const char *save,
|
const char *address, const char *file, const char *save,
|
||||||
const char *ref_address, const char *ref_file,
|
const char *ref_address, const char *ref_file,
|
||||||
const char *codebase);
|
const char *codebase);
|
||||||
|
|
||||||
// index of the latest added link
|
/* Index of the most recently recorded link. */
|
||||||
size_t hts_record_link_latest(httrackp *opt);
|
size_t hts_record_link_latest(httrackp *opt);
|
||||||
|
|
||||||
// invalidate an entry
|
/* Mark link at index lpos as not to be processed (sets pass2 = -1). */
|
||||||
void hts_invalidate_link(httrackp * opt, int lpos);
|
void hts_invalidate_link(httrackp * opt, int lpos);
|
||||||
|
|
||||||
// wipe all records
|
/* Reset / free the engine's link heap. */
|
||||||
void hts_record_init(httrackp *opt);
|
void hts_record_init(httrackp *opt);
|
||||||
|
|
||||||
void hts_record_free(httrackp *opt);
|
void hts_record_free(httrackp *opt);
|
||||||
|
|
||||||
//int httpmirror(char* url,int level,httrackp opt);
|
/* Run the mirror for the given start URL(s) under opt. Top-level engine entry.
|
||||||
|
*/
|
||||||
int httpmirror(char *url1, httrackp * opt);
|
int httpmirror(char *url1, httrackp * opt);
|
||||||
|
|
||||||
|
/* Write len bytes of adr to local path s. url_adr/url_fil (may be NULL) name
|
||||||
|
the source URL for logging/notification. */
|
||||||
int filesave(httrackp * opt, const char *adr, int len, const char *s,
|
int filesave(httrackp * opt, const char *adr, int len, const char *s,
|
||||||
const char *url_adr /* = NULL */ ,
|
const char *url_adr /* = NULL */ ,
|
||||||
const char *url_fil /* = NULL */ );
|
const char *url_fil /* = NULL */ );
|
||||||
|
|
||||||
char *hts_cancel_file_pop(httrackp * opt);
|
char *hts_cancel_file_pop(httrackp * opt);
|
||||||
|
|
||||||
int check_fatal_io_errno(void);
|
int check_fatal_io_errno(void);
|
||||||
|
|
||||||
int engine_stats(void);
|
int engine_stats(void);
|
||||||
|
|
||||||
void host_ban(httrackp * opt, int ptr, struct_back * sback, const char *host);
|
void host_ban(httrackp * opt, int ptr, struct_back * sback, const char *host);
|
||||||
|
|
||||||
|
/* Open local file s for writing (filecreate, truncate) or appending
|
||||||
|
(fileappend), creating parent directories as needed. Return an open FILE*
|
||||||
|
the caller must fclose(), or NULL on failure. */
|
||||||
FILE *filecreate(filenote_strc * strct, const char *s);
|
FILE *filecreate(filenote_strc * strct, const char *s);
|
||||||
|
|
||||||
FILE *fileappend(filenote_strc * strct, const char *s);
|
FILE *fileappend(filenote_strc * strct, const char *s);
|
||||||
|
|
||||||
|
/* Create an empty file, return 1 on success, 0 on failure. */
|
||||||
int filecreateempty(filenote_strc * strct, const char *filename);
|
int filecreateempty(filenote_strc * strct, const char *filename);
|
||||||
|
|
||||||
int filenote(filenote_strc * strct, const char *s, filecreate_params * params);
|
int filenote(filenote_strc * strct, const char *s, filecreate_params * params);
|
||||||
|
|
||||||
void file_notify(httrackp * opt, const char *adr, const char *fil,
|
void file_notify(httrackp * opt, const char *adr, const char *fil,
|
||||||
const char *save, int create, int modify, int wasupdated);
|
const char *save, int create, int modify, int wasupdated);
|
||||||
|
|
||||||
void usercommand(httrackp * opt, int exe, const char *cmd, const char *file,
|
void usercommand(httrackp * opt, int exe, const char *cmd, const char *file,
|
||||||
const char *adr, const char *fil);
|
const char *adr, const char *fil);
|
||||||
|
|
||||||
void usercommand_exe(const char *cmd, const char *file);
|
void usercommand_exe(const char *cmd, const char *file);
|
||||||
|
|
||||||
int filters_init(char ***ptrfilters, int maxfilter, int filterinc);
|
int filters_init(char ***ptrfilters, int maxfilter, int filterinc);
|
||||||
|
|
||||||
int fspc(httrackp * opt, FILE * fp, const char *type);
|
int fspc(httrackp * opt, FILE * fp, const char *type);
|
||||||
|
|
||||||
char *next_token(char *p, int flag);
|
char *next_token(char *p, int flag);
|
||||||
|
|
||||||
//
|
/* Like fil_normalized(), but first drops query keys in STRIP (comma-separated,
|
||||||
|
"*" = all); STRIP NULL/empty behaves exactly like fil_normalized(). */
|
||||||
|
char *fil_normalized_filtered(const char *source, char *dest,
|
||||||
|
const char *strip);
|
||||||
|
|
||||||
|
/* As fil_normalized_filtered(), but DO_SLASH/DO_QUERY gate the // collapse and
|
||||||
|
the query-argument sort independently (the urlhack sub-flags). */
|
||||||
|
char *fil_normalized_filtered_ex(const char *source, char *dest,
|
||||||
|
const char *strip, int do_slash, int do_query);
|
||||||
|
|
||||||
|
/* For URL ADR/FIL, return (in DEST) the comma keylist to strip from the
|
||||||
|
'\n'-separated "[pattern=]keys" RULES (patterns matched on host/path via
|
||||||
|
strjoker, last wins); NULL if none match. Feeds fil_normalized_filtered(). */
|
||||||
|
const char *hts_query_strip_keys(const char *rules, const char *adr,
|
||||||
|
const char *fil, char *dest, size_t destsize);
|
||||||
|
|
||||||
|
/* Read a whole file into a freshly malloc'd, NUL-terminated buffer; the caller
|
||||||
|
owns it and must release it with freet(). Return NULL on missing/unreadable
|
||||||
|
file (readfile_or substitutes defaultdata instead). The byte content is NOT
|
||||||
|
transcoded except readfile_utf8, which expects a UTF-8 path. readfile2
|
||||||
|
reports the byte size (excluding the NUL) via *size when non-NULL. */
|
||||||
char *readfile(const char *fil);
|
char *readfile(const char *fil);
|
||||||
|
|
||||||
char *readfile2(const char *fil, LLint * size);
|
char *readfile2(const char *fil, LLint * size);
|
||||||
|
|
||||||
char *readfile_utf8(const char *fil);
|
char *readfile_utf8(const char *fil);
|
||||||
|
|
||||||
char *readfile_or(const char *fil, const char *defaultdata);
|
char *readfile_or(const char *fil, const char *defaultdata);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
void check_rate(TStamp stat_timestart, int maxrate);
|
void check_rate(TStamp stat_timestart, int maxrate);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// liens
|
/* Backing (download-slot) scheduler. Operate on the back[] ring (struct_back).
|
||||||
int liens_record(char *adr, char *fil, char *save, char *former_adr,
|
Not thread-safe; call from the single crawl loop. */
|
||||||
char *former_fil, char *codebase);
|
|
||||||
|
|
||||||
// backing, routines externes
|
/* True if a connecting slot should give up on the current address and try the
|
||||||
|
next one: a fallback address remains (addr_index+1 < addr_count) and the
|
||||||
|
candidate has been connecting for at least its deadline, min(timeout, an
|
||||||
|
internal cap). elapsed/timeout in seconds. Exposed for the -#D self-test. */
|
||||||
|
int back_connect_fallback_due(int addr_index, int addr_count, int elapsed,
|
||||||
|
int timeout);
|
||||||
|
|
||||||
|
/* How many new sockets may be opened now, honoring maxsoc and the maxconn rate
|
||||||
|
limit (>=0). _strict ignores reserved-slot headroom; the plain form leaves
|
||||||
|
room for naming tests and stops at 0 when the stack is nearly full. */
|
||||||
int back_pluggable_sockets(struct_back * sback, httrackp * opt);
|
int back_pluggable_sockets(struct_back * sback, httrackp * opt);
|
||||||
|
|
||||||
int back_pluggable_sockets_strict(struct_back * sback, httrackp * opt);
|
int back_pluggable_sockets_strict(struct_back * sback, httrackp * opt);
|
||||||
|
|
||||||
|
/* Schedule more links from the heap into free slots. Returns the number queued,
|
||||||
|
or <=0 if none could be added (no free slot / paused / stopped). */
|
||||||
int back_fill(struct_back * sback, httrackp * opt, cache_back * cache,
|
int back_fill(struct_back * sback, httrackp * opt, cache_back * cache,
|
||||||
int ptr, int numero_passe);
|
int ptr, int numero_passe);
|
||||||
int backlinks_done(const struct_back * sback, lien_url ** liens,
|
|
||||||
int lien_tot, int ptr);
|
/* Count of links already finished (in background or served from cache). */
|
||||||
|
int backlinks_done(const struct_back *sback, lien_url **liens, int lien_tot,
|
||||||
|
int ptr);
|
||||||
|
|
||||||
|
/* Like back_fill, but a no-op (returns -1) when in-memory buffered data already
|
||||||
|
exceeds opt->maxcache. */
|
||||||
int back_fillmax(struct_back * sback, httrackp * opt, cache_back * cache,
|
int back_fillmax(struct_back * sback, httrackp * opt, cache_back * cache,
|
||||||
int ptr, int numero_passe);
|
int ptr, int numero_passe);
|
||||||
|
|
||||||
|
/* Interactive prompt: continue an interrupted mirror? Returns nonzero to go on.
|
||||||
|
*/
|
||||||
int ask_continue(httrackp * opt);
|
int ask_continue(httrackp * opt);
|
||||||
|
|
||||||
|
/* Number of decimal digits in n. */
|
||||||
int nombre_digit(int n);
|
int nombre_digit(int n);
|
||||||
|
|
||||||
// Java
|
// Java
|
||||||
@@ -336,17 +447,23 @@ int hts_add_file(char *file, int file_position);
|
|||||||
// Polling
|
// Polling
|
||||||
#if HTS_POLL
|
#if HTS_POLL
|
||||||
int check_flot(T_SOC s);
|
int check_flot(T_SOC s);
|
||||||
|
|
||||||
int check_stdin(void);
|
int check_stdin(void);
|
||||||
|
|
||||||
int read_stdin(char *s, int max);
|
int read_stdin(char *s, int max);
|
||||||
#endif
|
#endif
|
||||||
|
/* Socket readiness probes: nonzero if the socket has an error / has data. */
|
||||||
int check_sockerror(T_SOC s);
|
int check_sockerror(T_SOC s);
|
||||||
|
|
||||||
int check_sockdata(T_SOC s);
|
int check_sockdata(T_SOC s);
|
||||||
|
|
||||||
/* external modules */
|
/* external modules: register a link discovered by a parser plugin. */
|
||||||
int htsAddLink(htsmoduleStruct * str, char *link);
|
int htsAddLink(htsmoduleStruct * str, char *link);
|
||||||
|
|
||||||
// Void
|
/* No-op function (used as a do-nothing callback / to defeat optimizers). */
|
||||||
void voidf(void);
|
void voidf(void);
|
||||||
|
|
||||||
|
/* HTML marker comment marking where the top index is spliced. */
|
||||||
#define HTS_TOPINDEX "TOP_INDEX_HTTRACK"
|
#define HTS_TOPINDEX "TOP_INDEX_HTTRACK"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
279
src/htsdefines.h
279
src/htsdefines.h
@@ -30,11 +30,16 @@ Please visit our Website: http://www.httrack.com
|
|||||||
/* Author: Xavier Roche */
|
/* Author: Xavier Roche */
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
|
||||||
// Fichier librairie .h
|
/** @file htsdefines.h
|
||||||
|
* Public callback prototypes and the wrapper/plug-in interface: the function
|
||||||
|
* pointer types a parser or wrapper module implements, and the callback table
|
||||||
|
* the engine dispatches through. */
|
||||||
#ifndef HTS_DEFINES_DEFH
|
#ifndef HTS_DEFINES_DEFH
|
||||||
#define HTS_DEFINES_DEFH
|
#define HTS_DEFINES_DEFH
|
||||||
|
|
||||||
/* Forward definitions */
|
/* Forward declarations of engine structs, so this header is usable without
|
||||||
|
pulling in their full definitions. Each is guarded so multiple public
|
||||||
|
headers can repeat the typedef without clashing. */
|
||||||
#ifndef HTS_DEF_FWSTRUCT_httrackp
|
#ifndef HTS_DEF_FWSTRUCT_httrackp
|
||||||
#define HTS_DEF_FWSTRUCT_httrackp
|
#define HTS_DEF_FWSTRUCT_httrackp
|
||||||
typedef struct httrackp httrackp;
|
typedef struct httrackp httrackp;
|
||||||
@@ -64,7 +69,8 @@ typedef struct t_hts_callbackarg t_hts_callbackarg;
|
|||||||
typedef struct t_hts_callbackarg t_hts_callbackarg;
|
typedef struct t_hts_callbackarg t_hts_callbackarg;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* External callbacks */
|
/* Marks a symbol an external wrapper module exports back to the engine
|
||||||
|
(dllexport on Windows, nothing elsewhere). */
|
||||||
#ifndef EXTERNAL_FUNCTION
|
#ifndef EXTERNAL_FUNCTION
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define EXTERNAL_FUNCTION __declspec(dllexport)
|
#define EXTERNAL_FUNCTION __declspec(dllexport)
|
||||||
@@ -73,90 +79,153 @@ typedef struct t_hts_callbackarg t_hts_callbackarg;
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* --wrapper plug function prototype */
|
/* Entry points of a --wrapper plug-in: hts_plug(opt, argv) is called once to
|
||||||
|
install the wrapper (argv is the wrapper's argument string), hts_unplug(opt)
|
||||||
|
once to tear it down. Both return non-zero on success. */
|
||||||
|
typedef int (*t_hts_plug)(httrackp *opt, const char *argv);
|
||||||
|
|
||||||
typedef int (*t_hts_plug) (httrackp * opt, const char *argv);
|
typedef int (*t_hts_unplug)(httrackp *opt);
|
||||||
typedef int (*t_hts_unplug) (httrackp * opt);
|
|
||||||
|
|
||||||
/* htsopt function callbacks definitions */
|
/* Engine callback prototypes. Each is one hook the engine fires at a defined
|
||||||
|
point of a mirror; a wrapper installs the ones it cares about in the
|
||||||
|
callback table below. carg carries the user-defined argument chain; int
|
||||||
|
returns are 1 to continue/accept, 0 to abort/refuse unless noted. */
|
||||||
|
|
||||||
typedef void (*t_hts_htmlcheck_init) (t_hts_callbackarg * carg);
|
/* Called once when the wrapper is installed; allocate per-run state here. */
|
||||||
typedef void (*t_hts_htmlcheck_uninit) (t_hts_callbackarg * carg);
|
typedef void (*t_hts_htmlcheck_init)(t_hts_callbackarg *carg);
|
||||||
typedef int (*t_hts_htmlcheck_start) (t_hts_callbackarg * carg, httrackp * opt);
|
|
||||||
typedef int (*t_hts_htmlcheck_end) (t_hts_callbackarg * carg, httrackp * opt);
|
/* Called once when the wrapper is removed; release per-run state here. */
|
||||||
typedef int (*t_hts_htmlcheck_chopt) (t_hts_callbackarg * carg, httrackp * opt);
|
typedef void (*t_hts_htmlcheck_uninit)(t_hts_callbackarg *carg);
|
||||||
typedef int (*t_hts_htmlcheck_process) (t_hts_callbackarg * carg,
|
|
||||||
httrackp * opt, char **html, int *len,
|
/* Fired at the start of a mirror, after options are parsed. */
|
||||||
const char *url_adresse,
|
typedef int (*t_hts_htmlcheck_start)(t_hts_callbackarg *carg, httrackp *opt);
|
||||||
const char *url_fichier);
|
|
||||||
|
/* Fired at the end of a mirror. */
|
||||||
|
typedef int (*t_hts_htmlcheck_end)(t_hts_callbackarg *carg, httrackp *opt);
|
||||||
|
|
||||||
|
/* Fired while options are being changed, to validate or adjust them. */
|
||||||
|
typedef int (*t_hts_htmlcheck_chopt)(t_hts_callbackarg *carg, httrackp *opt);
|
||||||
|
|
||||||
|
/* Rewrite hook over an in-memory page: the html and len arguments point at the
|
||||||
|
buffer and its length (the callback may reallocate and resize it),
|
||||||
|
url_adresse and url_fichier name it. */
|
||||||
|
typedef int (*t_hts_htmlcheck_process)(t_hts_callbackarg *carg, httrackp *opt,
|
||||||
|
char **html, int *len,
|
||||||
|
const char *url_adresse,
|
||||||
|
const char *url_fichier);
|
||||||
|
|
||||||
|
/* Same shape as process, run before HTML parsing. */
|
||||||
typedef t_hts_htmlcheck_process t_hts_htmlcheck_preprocess;
|
typedef t_hts_htmlcheck_process t_hts_htmlcheck_preprocess;
|
||||||
typedef t_hts_htmlcheck_process t_hts_htmlcheck_postprocess;
|
|
||||||
typedef int (*t_hts_htmlcheck_check_html) (t_hts_callbackarg * carg,
|
|
||||||
httrackp * opt, char *html, int len,
|
|
||||||
const char *url_adresse,
|
|
||||||
const char *url_fichier);
|
|
||||||
typedef const char *(*t_hts_htmlcheck_query) (t_hts_callbackarg * carg,
|
|
||||||
httrackp * opt,
|
|
||||||
const char *question);
|
|
||||||
typedef const char *(*t_hts_htmlcheck_query2) (t_hts_callbackarg * carg,
|
|
||||||
httrackp * opt,
|
|
||||||
const char *question);
|
|
||||||
typedef const char *(*t_hts_htmlcheck_query3) (t_hts_callbackarg * carg,
|
|
||||||
httrackp * opt,
|
|
||||||
const char *question);
|
|
||||||
typedef int (*t_hts_htmlcheck_loop) (t_hts_callbackarg * carg, httrackp * opt,
|
|
||||||
lien_back * back, int back_max,
|
|
||||||
int back_index, int lien_tot,
|
|
||||||
int lien_ntot, int stat_time,
|
|
||||||
hts_stat_struct * stats);
|
|
||||||
typedef int (*t_hts_htmlcheck_check_link) (t_hts_callbackarg * carg,
|
|
||||||
httrackp * opt, const char *adr,
|
|
||||||
const char *fil, int status);
|
|
||||||
typedef int (*t_hts_htmlcheck_check_mime) (t_hts_callbackarg * carg,
|
|
||||||
httrackp * opt, const char *adr,
|
|
||||||
const char *fil, const char *mime,
|
|
||||||
int status);
|
|
||||||
typedef void (*t_hts_htmlcheck_pause) (t_hts_callbackarg * carg, httrackp * opt,
|
|
||||||
const char *lockfile);
|
|
||||||
typedef void (*t_hts_htmlcheck_filesave) (t_hts_callbackarg * carg,
|
|
||||||
httrackp * opt, const char *file);
|
|
||||||
typedef void (*t_hts_htmlcheck_filesave2) (t_hts_callbackarg * carg,
|
|
||||||
httrackp * opt, const char *hostname,
|
|
||||||
const char *filename,
|
|
||||||
const char *localfile, int is_new,
|
|
||||||
int is_modified, int not_updated);
|
|
||||||
typedef int (*t_hts_htmlcheck_linkdetected) (t_hts_callbackarg * carg,
|
|
||||||
httrackp * opt, char *link);
|
|
||||||
typedef int (*t_hts_htmlcheck_linkdetected2) (t_hts_callbackarg * carg,
|
|
||||||
httrackp * opt, char *link,
|
|
||||||
const char *tag_start);
|
|
||||||
typedef int (*t_hts_htmlcheck_xfrstatus) (t_hts_callbackarg * carg,
|
|
||||||
httrackp * opt, lien_back * back);
|
|
||||||
typedef int (*t_hts_htmlcheck_savename) (t_hts_callbackarg * carg,
|
|
||||||
httrackp * opt,
|
|
||||||
const char *adr_complete,
|
|
||||||
const char *fil_complete,
|
|
||||||
const char *referer_adr,
|
|
||||||
const char *referer_fil, char *save);
|
|
||||||
typedef t_hts_htmlcheck_savename t_hts_htmlcheck_extsavename;
|
|
||||||
typedef int (*t_hts_htmlcheck_sendhead) (t_hts_callbackarg * carg,
|
|
||||||
httrackp * opt, char *buff,
|
|
||||||
const char *adr, const char *fil,
|
|
||||||
const char *referer_adr,
|
|
||||||
const char *referer_fil,
|
|
||||||
htsblk * outgoing);
|
|
||||||
typedef int (*t_hts_htmlcheck_receivehead) (t_hts_callbackarg * carg,
|
|
||||||
httrackp * opt, char *buff,
|
|
||||||
const char *adr, const char *fil,
|
|
||||||
const char *referer_adr,
|
|
||||||
const char *referer_fil,
|
|
||||||
htsblk * incoming);
|
|
||||||
|
|
||||||
/* External additional parsing module(s) */
|
/* Same shape as process, run after HTML parsing. */
|
||||||
typedef int (*t_hts_htmlcheck_detect) (t_hts_callbackarg * carg, httrackp * opt,
|
typedef t_hts_htmlcheck_process t_hts_htmlcheck_postprocess;
|
||||||
htsmoduleStruct * str);
|
|
||||||
typedef int (*t_hts_htmlcheck_parse) (t_hts_callbackarg * carg, httrackp * opt,
|
/* Inspect a page (read-only html/len) without rewriting it. */
|
||||||
htsmoduleStruct * str);
|
typedef int (*t_hts_htmlcheck_check_html)(t_hts_callbackarg *carg,
|
||||||
|
httrackp *opt, char *html, int len,
|
||||||
|
const char *url_adresse,
|
||||||
|
const char *url_fichier);
|
||||||
|
|
||||||
|
/* Answer an engine query identified by 'question'; returns the answer string
|
||||||
|
(owned by the callback, must stay valid until the next call). */
|
||||||
|
typedef const char *(*t_hts_htmlcheck_query)(t_hts_callbackarg *carg,
|
||||||
|
httrackp *opt,
|
||||||
|
const char *question);
|
||||||
|
|
||||||
|
/* Second query channel, same contract as query. */
|
||||||
|
typedef const char *(*t_hts_htmlcheck_query2)(t_hts_callbackarg *carg,
|
||||||
|
httrackp *opt,
|
||||||
|
const char *question);
|
||||||
|
|
||||||
|
/* Third query channel, same contract as query. */
|
||||||
|
typedef const char *(*t_hts_htmlcheck_query3)(t_hts_callbackarg *carg,
|
||||||
|
httrackp *opt,
|
||||||
|
const char *question);
|
||||||
|
|
||||||
|
/* Per-tick progress hook: 'back' is the transfer slot array of 'back_max'
|
||||||
|
entries, back_index the active one; lien_tot/lien_ntot and stats report
|
||||||
|
queue size and running totals, stat_time the elapsed time. */
|
||||||
|
typedef int (*t_hts_htmlcheck_loop)(t_hts_callbackarg *carg, httrackp *opt,
|
||||||
|
lien_back *back, int back_max,
|
||||||
|
int back_index, int lien_tot, int lien_ntot,
|
||||||
|
int stat_time, hts_stat_struct *stats);
|
||||||
|
|
||||||
|
/* Veto a link (adr host, fil path) after its transfer; status is the result.
|
||||||
|
Return 0 to drop the link. */
|
||||||
|
typedef int (*t_hts_htmlcheck_check_link)(t_hts_callbackarg *carg,
|
||||||
|
httrackp *opt, const char *adr,
|
||||||
|
const char *fil, int status);
|
||||||
|
|
||||||
|
/* Veto a link by its MIME type before download; return 0 to skip it. */
|
||||||
|
typedef int (*t_hts_htmlcheck_check_mime)(t_hts_callbackarg *carg,
|
||||||
|
httrackp *opt, const char *adr,
|
||||||
|
const char *fil, const char *mime,
|
||||||
|
int status);
|
||||||
|
|
||||||
|
/* Fired when the mirror pauses, waiting on 'lockfile' to be removed. */
|
||||||
|
typedef void (*t_hts_htmlcheck_pause)(t_hts_callbackarg *carg, httrackp *opt,
|
||||||
|
const char *lockfile);
|
||||||
|
|
||||||
|
/* Fired after a file is written to disk; 'file' is the local path. */
|
||||||
|
typedef void (*t_hts_htmlcheck_filesave)(t_hts_callbackarg *carg, httrackp *opt,
|
||||||
|
const char *file);
|
||||||
|
|
||||||
|
/* Richer file-saved notification: source host/filename, local path, and flags
|
||||||
|
telling whether the file is new, modified, or left unchanged. */
|
||||||
|
typedef void (*t_hts_htmlcheck_filesave2)(t_hts_callbackarg *carg,
|
||||||
|
httrackp *opt, const char *hostname,
|
||||||
|
const char *filename,
|
||||||
|
const char *localfile, int is_new,
|
||||||
|
int is_modified, int not_updated);
|
||||||
|
|
||||||
|
/* Fired for each link parsed out of a page; 'link' may be edited in place. */
|
||||||
|
typedef int (*t_hts_htmlcheck_linkdetected)(t_hts_callbackarg *carg,
|
||||||
|
httrackp *opt, char *link);
|
||||||
|
|
||||||
|
/* As linkdetected, plus tag_start, the markup the link was found in. */
|
||||||
|
typedef int (*t_hts_htmlcheck_linkdetected2)(t_hts_callbackarg *carg,
|
||||||
|
httrackp *opt, char *link,
|
||||||
|
const char *tag_start);
|
||||||
|
|
||||||
|
/* Fired on each transfer-status change of slot 'back'. */
|
||||||
|
typedef int (*t_hts_htmlcheck_xfrstatus)(t_hts_callbackarg *carg, httrackp *opt,
|
||||||
|
lien_back *back);
|
||||||
|
|
||||||
|
/* Choose the local save path for a URL; write it into 'save'. adr/fil name the
|
||||||
|
target, referer_adr/referer_fil the page that linked it. */
|
||||||
|
typedef int (*t_hts_htmlcheck_savename)(t_hts_callbackarg *carg, httrackp *opt,
|
||||||
|
const char *adr_complete,
|
||||||
|
const char *fil_complete,
|
||||||
|
const char *referer_adr,
|
||||||
|
const char *referer_fil, char *save);
|
||||||
|
|
||||||
|
/* Extended save-name hook, same signature as savename. */
|
||||||
|
typedef t_hts_htmlcheck_savename t_hts_htmlcheck_extsavename;
|
||||||
|
|
||||||
|
/* Inspect or edit the outgoing request headers in 'buff' before they are sent.
|
||||||
|
*/
|
||||||
|
typedef int (*t_hts_htmlcheck_sendhead)(t_hts_callbackarg *carg, httrackp *opt,
|
||||||
|
char *buff, const char *adr,
|
||||||
|
const char *fil,
|
||||||
|
const char *referer_adr,
|
||||||
|
const char *referer_fil,
|
||||||
|
htsblk *outgoing);
|
||||||
|
|
||||||
|
/* Inspect the incoming response headers in 'buff' after they are received. */
|
||||||
|
typedef int (*t_hts_htmlcheck_receivehead)(t_hts_callbackarg *carg,
|
||||||
|
httrackp *opt, char *buff,
|
||||||
|
const char *adr, const char *fil,
|
||||||
|
const char *referer_adr,
|
||||||
|
const char *referer_fil,
|
||||||
|
htsblk *incoming);
|
||||||
|
|
||||||
|
/* External parser module hooks: detect claims a document type (return 1 to
|
||||||
|
take it), parse then extracts its links. 'str' carries the document. */
|
||||||
|
typedef int (*t_hts_htmlcheck_detect)(t_hts_callbackarg *carg, httrackp *opt,
|
||||||
|
htsmoduleStruct *str);
|
||||||
|
|
||||||
|
typedef int (*t_hts_htmlcheck_parse)(t_hts_callbackarg *carg, httrackp *opt,
|
||||||
|
htsmoduleStruct *str);
|
||||||
|
|
||||||
/* Callbacks */
|
/* Callbacks */
|
||||||
#ifndef HTS_DEF_FWSTRUCT_t_hts_htmlcheck_callbacks
|
#ifndef HTS_DEF_FWSTRUCT_t_hts_htmlcheck_callbacks
|
||||||
@@ -164,20 +233,24 @@ typedef int (*t_hts_htmlcheck_parse) (t_hts_callbackarg * carg, httrackp * opt,
|
|||||||
typedef struct t_hts_htmlcheck_callbacks t_hts_htmlcheck_callbacks;
|
typedef struct t_hts_htmlcheck_callbacks t_hts_htmlcheck_callbacks;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Callabck array */
|
/* Declares one named callback slot: its function pointer (typed
|
||||||
#define DEFCALLBACK(NAME) \
|
t_hts_htmlcheck_<NAME>) paired with the carg passed to it. */
|
||||||
struct NAME { \
|
#define DEFCALLBACK(NAME) \
|
||||||
t_hts_htmlcheck_ ##NAME fun; \
|
struct NAME { \
|
||||||
t_hts_callbackarg *carg; \
|
t_hts_htmlcheck_##NAME fun; \
|
||||||
|
t_hts_callbackarg *carg; \
|
||||||
} NAME
|
} NAME
|
||||||
|
|
||||||
/* Callback items */
|
/* Generic, type-erased callback slot used where the hook type is opaque. */
|
||||||
typedef void *t_hts_htmlcheck_t_hts_htmlcheck_callbacks_item;
|
typedef void *t_hts_htmlcheck_t_hts_htmlcheck_callbacks_item;
|
||||||
|
|
||||||
typedef DEFCALLBACK(t_hts_htmlcheck_callbacks_item);
|
typedef DEFCALLBACK(t_hts_htmlcheck_callbacks_item);
|
||||||
|
|
||||||
/* Linked list, which should be used for the 'arg' user-defined argument */
|
/* Per-callback argument node. Wrappers chain these so a new hook can wrap an
|
||||||
|
existing one: userdef is the wrapper's own data, prev points back to the
|
||||||
|
function and carg it displaced (call it to keep the previous behavior). */
|
||||||
struct t_hts_callbackarg {
|
struct t_hts_callbackarg {
|
||||||
/* User-defined agument for the called function */
|
/* User-defined argument for the called function */
|
||||||
void *userdef;
|
void *userdef;
|
||||||
|
|
||||||
/* Previous function, if any (fun != NULL) */
|
/* Previous function, if any (fun != NULL) */
|
||||||
@@ -187,7 +260,9 @@ struct t_hts_callbackarg {
|
|||||||
} prev;
|
} prev;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Callback structure */
|
/* The full callback table, one slot per hook; installed in httrackp options
|
||||||
|
and dispatched by the engine. The trailing comments mark the API version a
|
||||||
|
slot first appeared in. */
|
||||||
struct t_hts_htmlcheck_callbacks {
|
struct t_hts_htmlcheck_callbacks {
|
||||||
/* v3.41 */
|
/* v3.41 */
|
||||||
DEFCALLBACK(init);
|
DEFCALLBACK(init);
|
||||||
@@ -219,9 +294,11 @@ struct t_hts_htmlcheck_callbacks {
|
|||||||
DEFCALLBACK(extsavename);
|
DEFCALLBACK(extsavename);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Library internal definitions */
|
/* Library-internal helpers, compiled only inside the engine. */
|
||||||
#ifdef HTS_INTERNAL_BYTECODE
|
#ifdef HTS_INTERNAL_BYTECODE
|
||||||
|
|
||||||
|
/* Maps a callback slot's name to its byte offset in the callback table, so a
|
||||||
|
slot can be installed by name. */
|
||||||
#ifndef HTS_DEF_FWSTRUCT_t_hts_callback_ref
|
#ifndef HTS_DEF_FWSTRUCT_t_hts_callback_ref
|
||||||
#define HTS_DEF_FWSTRUCT_t_hts_callback_ref
|
#define HTS_DEF_FWSTRUCT_t_hts_callback_ref
|
||||||
typedef struct t_hts_callback_ref t_hts_callback_ref;
|
typedef struct t_hts_callback_ref t_hts_callback_ref;
|
||||||
@@ -235,20 +312,28 @@ struct t_hts_callback_ref {
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Default (no-op) callback table the engine starts from. */
|
||||||
extern const t_hts_htmlcheck_callbacks default_callbacks;
|
extern const t_hts_htmlcheck_callbacks default_callbacks;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define HT_PRINT(A) strcatbuff(opt->state.HTbuff,A);
|
/* Internal helpers for building an HTTP request/response into the engine's
|
||||||
#define HT_REQUEST_START opt->state.HTbuff[0]='\0';
|
scratch buffer (opt->state.HTbuff): START resets it, PRINT appends; the
|
||||||
|
PANIC variant records a fatal error message. */
|
||||||
|
#define HT_PRINT(A) strcatbuff(opt->state.HTbuff, A);
|
||||||
|
|
||||||
|
#define HT_REQUEST_START opt->state.HTbuff[0] = '\0';
|
||||||
|
|
||||||
#define HT_REQUEST_END
|
#define HT_REQUEST_END
|
||||||
#define HTT_REQUEST_START opt->state.HTbuff[0]='\0';
|
#define HTT_REQUEST_START opt->state.HTbuff[0] = '\0';
|
||||||
|
|
||||||
#define HTT_REQUEST_END
|
#define HTT_REQUEST_END
|
||||||
#define HTS_REQUEST_START opt->state.HTbuff[0]='\0';
|
#define HTS_REQUEST_START opt->state.HTbuff[0] = '\0';
|
||||||
|
|
||||||
#define HTS_REQUEST_END
|
#define HTS_REQUEST_END
|
||||||
#define HTS_PANIC_PRINTF(S) strcpybuff(opt->state._hts_errmsg,S);
|
#define HTS_PANIC_PRINTF(S) strcpybuff(opt->state._hts_errmsg, S);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
359
src/htsdns_selftest.c
Normal file
359
src/htsdns_selftest.c
Normal file
@@ -0,0 +1,359 @@
|
|||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/*
|
||||||
|
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: htsdns_selftest.c subroutines: */
|
||||||
|
/* in-process self-test for the DNS resolver and cache */
|
||||||
|
/* Author: Xavier Roche */
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
|
||||||
|
/* Routes the resolver through a scripted getaddrinfo (hts_resolver_backend)
|
||||||
|
instead of the network, so resolution and the DNS cache are testable for a
|
||||||
|
fixed set of scenarios (IPv4/IPv6/dual-stack, errors, family filter,
|
||||||
|
cache reuse) with no live DNS. */
|
||||||
|
|
||||||
|
#define HTS_INTERNAL_BYTECODE
|
||||||
|
|
||||||
|
#include "htsdns_selftest.h"
|
||||||
|
|
||||||
|
#include "htscore.h"
|
||||||
|
#include "htslib.h"
|
||||||
|
#include "htsnet.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#if HTS_INET6 != 0
|
||||||
|
|
||||||
|
/* IPV6_resolver: 0 = v4+v6, 1 = v4 only, 2 = v6 only (htscoremain -@i). */
|
||||||
|
extern int IPV6_resolver;
|
||||||
|
|
||||||
|
/* One scripted host: either a getaddrinfo error, or an ordered address list. */
|
||||||
|
typedef struct mock_addr {
|
||||||
|
int family; /* AF_INET / AF_INET6 */
|
||||||
|
unsigned char addr[16]; /* 4 (v4) or 16 (v6) meaningful bytes */
|
||||||
|
} mock_addr;
|
||||||
|
|
||||||
|
typedef struct mock_host {
|
||||||
|
const char *name;
|
||||||
|
int gai_err; /* non-zero: getaddrinfo returns this */
|
||||||
|
int naddr;
|
||||||
|
mock_addr addr[6];
|
||||||
|
int calls; /* times the backend resolved this host */
|
||||||
|
} mock_host;
|
||||||
|
|
||||||
|
static mock_host mock_hosts[] = {
|
||||||
|
{"v4only.test", 0, 1, {{AF_INET, {1, 2, 3, 4}}}, 0},
|
||||||
|
{"v6only.test", 0, 1, {{AF_INET6, {0x20, 0x01, 0x0d, 0xb8, [15] = 1}}}, 0},
|
||||||
|
/* dual stack, IPv6 first (RFC 6724 order) then IPv4 */
|
||||||
|
{"dual.test",
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
{{AF_INET6, {0x20, 0x01, 0x0d, 0xb8, [15] = 2}}, {AF_INET, {5, 6, 7, 8}}},
|
||||||
|
0},
|
||||||
|
/* dual stack, IPv4 first: distinguishes "keep the first address" from
|
||||||
|
"prefer a family", so the selection contract is actually pinned. */
|
||||||
|
{"dual4.test",
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
{{AF_INET, {9, 10, 11, 12}},
|
||||||
|
{AF_INET6, {0x20, 0x01, 0x0d, 0xb8, [15] = 3}}},
|
||||||
|
0},
|
||||||
|
/* more addresses than HTS_MAXADDRNUM: the list must clamp to the cap. */
|
||||||
|
{"many.test",
|
||||||
|
0,
|
||||||
|
6,
|
||||||
|
{{AF_INET, {10, 0, 0, 1}},
|
||||||
|
{AF_INET, {10, 0, 0, 2}},
|
||||||
|
{AF_INET, {10, 0, 0, 3}},
|
||||||
|
{AF_INET, {10, 0, 0, 4}},
|
||||||
|
{AF_INET, {10, 0, 0, 5}},
|
||||||
|
{AF_INET, {10, 0, 0, 6}}},
|
||||||
|
0},
|
||||||
|
{"nodns.test", EAI_NONAME, 0, {{0}}, 0},
|
||||||
|
};
|
||||||
|
|
||||||
|
static mock_host *mock_find(const char *name) {
|
||||||
|
for (size_t i = 0; i < sizeof(mock_hosts) / sizeof(mock_hosts[0]); i++) {
|
||||||
|
if (strcmp(mock_hosts[i].name, name) == 0)
|
||||||
|
return &mock_hosts[i];
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mock_reset_calls(void) {
|
||||||
|
for (size_t i = 0; i < sizeof(mock_hosts) / sizeof(mock_hosts[0]); i++)
|
||||||
|
mock_hosts[i].calls = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Build one addrinfo node owning its sockaddr (freed by mock_freeaddrinfo). */
|
||||||
|
static struct addrinfo *mock_mkai(const mock_addr *a) {
|
||||||
|
struct addrinfo *ai = calloct(1, sizeof(*ai));
|
||||||
|
|
||||||
|
ai->ai_family = a->family;
|
||||||
|
if (a->family == AF_INET) {
|
||||||
|
struct sockaddr_in *sin = calloct(1, sizeof(*sin));
|
||||||
|
|
||||||
|
sin->sin_family = AF_INET;
|
||||||
|
memcpy(&sin->sin_addr, a->addr, 4);
|
||||||
|
ai->ai_addr = (struct sockaddr *) sin;
|
||||||
|
ai->ai_addrlen = sizeof(*sin);
|
||||||
|
} else {
|
||||||
|
struct sockaddr_in6 *sin6 = calloct(1, sizeof(*sin6));
|
||||||
|
|
||||||
|
sin6->sin6_family = AF_INET6;
|
||||||
|
memcpy(&sin6->sin6_addr, a->addr, 16);
|
||||||
|
ai->ai_addr = (struct sockaddr *) sin6;
|
||||||
|
ai->ai_addrlen = sizeof(*sin6);
|
||||||
|
}
|
||||||
|
return ai;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int 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;
|
||||||
|
|
||||||
|
(void) service;
|
||||||
|
*res = NULL;
|
||||||
|
if (h == NULL)
|
||||||
|
return EAI_NONAME;
|
||||||
|
h->calls++; /* a real backend hit; a cached host skips this */
|
||||||
|
if (h->gai_err != 0)
|
||||||
|
return h->gai_err;
|
||||||
|
for (int i = 0; i < h->naddr; i++) {
|
||||||
|
if (want != PF_UNSPEC && want != h->addr[i].family)
|
||||||
|
continue; /* honor the requested family (v4/v6 only) */
|
||||||
|
struct addrinfo *const ai = mock_mkai(&h->addr[i]);
|
||||||
|
|
||||||
|
if (head == NULL)
|
||||||
|
head = ai;
|
||||||
|
else
|
||||||
|
tail->ai_next = ai;
|
||||||
|
tail = ai;
|
||||||
|
}
|
||||||
|
if (head == NULL)
|
||||||
|
return EAI_NONAME; /* filtered to empty, as the libc resolver does */
|
||||||
|
*res = head;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mock_freeaddrinfo(struct addrinfo *res) {
|
||||||
|
while (res != NULL) {
|
||||||
|
struct addrinfo *const next = res->ai_next;
|
||||||
|
|
||||||
|
freet(res->ai_addr);
|
||||||
|
freet(res);
|
||||||
|
res = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const hts_resolver_backend mock_backend = {mock_getaddrinfo,
|
||||||
|
mock_freeaddrinfo};
|
||||||
|
|
||||||
|
static int failures = 0;
|
||||||
|
|
||||||
|
#define CHECK(cond) \
|
||||||
|
do { \
|
||||||
|
if (!(cond)) { \
|
||||||
|
failures++; \
|
||||||
|
fprintf(stderr, "dns-selftest: FAIL at %s:%d: %s\n", __FILE__, __LINE__, \
|
||||||
|
#cond); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/* Resolve via the uncached entry point; return the address family, or
|
||||||
|
AF_UNSPEC if the host did not resolve. */
|
||||||
|
static int resolve_family_nocache(const char *host) {
|
||||||
|
SOCaddr addr;
|
||||||
|
const char *err = NULL;
|
||||||
|
|
||||||
|
if (hts_dns_resolve_nocache2(host, &addr, &err) == NULL)
|
||||||
|
return AF_UNSPEC;
|
||||||
|
return SOCaddr_sinfamily(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
int dns_selftests(httrackp *opt) {
|
||||||
|
failures = 0;
|
||||||
|
hts_dns_set_resolver_backend(&mock_backend);
|
||||||
|
|
||||||
|
/* IPv4-only / IPv6-only hosts map to the right family. */
|
||||||
|
IPV6_resolver = 0;
|
||||||
|
CHECK(resolve_family_nocache("v4only.test") == AF_INET);
|
||||||
|
CHECK(resolve_family_nocache("v6only.test") == AF_INET6);
|
||||||
|
|
||||||
|
/* Dual-stack: the single-address API returns the *first* resolved address.
|
||||||
|
Both orderings pin selection by position, not a family preference. The
|
||||||
|
multi-address API (resolve_all, below) exposes the whole list. */
|
||||||
|
CHECK(resolve_family_nocache("dual.test") == AF_INET6); /* v6 listed first */
|
||||||
|
CHECK(resolve_family_nocache("dual4.test") == AF_INET); /* v4 listed first */
|
||||||
|
|
||||||
|
/* Unknown host does not resolve. */
|
||||||
|
CHECK(resolve_family_nocache("nodns.test") == AF_UNSPEC);
|
||||||
|
|
||||||
|
/* Family filter (-@i4 / -@i6) selects v4 / v6 out of the dual-stack host. */
|
||||||
|
IPV6_resolver = 1;
|
||||||
|
CHECK(resolve_family_nocache("dual.test") == AF_INET);
|
||||||
|
IPV6_resolver = 2;
|
||||||
|
CHECK(resolve_family_nocache("dual.test") == AF_INET6);
|
||||||
|
IPV6_resolver = 0;
|
||||||
|
|
||||||
|
/* Cached driver resolves a host once and reuses the *same* address. */
|
||||||
|
mock_reset_calls();
|
||||||
|
{
|
||||||
|
SOCaddr a1, a2;
|
||||||
|
char ip1[64], ip2[64];
|
||||||
|
const char *err = NULL;
|
||||||
|
|
||||||
|
CHECK(hts_dns_resolve2(opt, "v4only.test", &a1, &err) != NULL);
|
||||||
|
CHECK(hts_dns_resolve2(opt, "v4only.test", &a2, &err) != NULL);
|
||||||
|
CHECK(mock_find("v4only.test")->calls == 1);
|
||||||
|
/* the cache returns the right address, not merely a hit for the key */
|
||||||
|
SOCaddr_inetntoa(ip1, sizeof(ip1), a1);
|
||||||
|
SOCaddr_inetntoa(ip2, sizeof(ip2), a2);
|
||||||
|
CHECK(strcmp(ip1, "1.2.3.4") == 0);
|
||||||
|
CHECK(strcmp(ip1, ip2) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* A negative result is cached too: a second lookup does not re-resolve. */
|
||||||
|
{
|
||||||
|
SOCaddr a1, a2;
|
||||||
|
const char *err = NULL;
|
||||||
|
|
||||||
|
CHECK(hts_dns_resolve2(opt, "nodns.test", &a1, &err) == NULL);
|
||||||
|
CHECK(hts_dns_resolve2(opt, "nodns.test", &a2, &err) == NULL);
|
||||||
|
CHECK(mock_find("nodns.test")->calls == 1); /* resolved once, then cached */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Multi-address resolution: count and order are the connect-fallback
|
||||||
|
contract. A dead first address is retried against the next, so both must be
|
||||||
|
exact. */
|
||||||
|
mock_reset_calls();
|
||||||
|
{
|
||||||
|
SOCaddr addrs[HTS_MAXADDRNUM];
|
||||||
|
char ip[64];
|
||||||
|
const char *err = NULL;
|
||||||
|
|
||||||
|
/* dual-stack, in resolver order: [0]=v6, [1]=v4 */
|
||||||
|
CHECK(hts_dns_resolve_all(opt, "dual.test", addrs, HTS_MAXADDRNUM, &err) ==
|
||||||
|
2);
|
||||||
|
CHECK(SOCaddr_sinfamily(addrs[0]) == AF_INET6);
|
||||||
|
CHECK(SOCaddr_sinfamily(addrs[1]) == AF_INET);
|
||||||
|
SOCaddr_inetntoa(ip, sizeof(ip), addrs[1]);
|
||||||
|
CHECK(strcmp(ip, "5.6.7.8") == 0);
|
||||||
|
CHECK(mock_find("dual.test")->calls ==
|
||||||
|
1); /* one backend hit for the list */
|
||||||
|
|
||||||
|
/* single-address host: count 1 */
|
||||||
|
CHECK(hts_dns_resolve_all(opt, "v4only.test", addrs, HTS_MAXADDRNUM,
|
||||||
|
&err) == 1);
|
||||||
|
SOCaddr_inetntoa(ip, sizeof(ip), addrs[0]);
|
||||||
|
CHECK(strcmp(ip, "1.2.3.4") == 0);
|
||||||
|
|
||||||
|
/* does-not-resolve: count 0 (negative), no addresses */
|
||||||
|
CHECK(hts_dns_resolve_all(opt, "nodns.test", addrs, HTS_MAXADDRNUM, &err) ==
|
||||||
|
0);
|
||||||
|
|
||||||
|
/* more than the cap: the kept list is clamped to HTS_MAXADDRNUM, keeping
|
||||||
|
the FIRST addresses in resolver order (not some other window) */
|
||||||
|
CHECK(hts_dns_resolve_all(opt, "many.test", addrs, HTS_MAXADDRNUM, &err) ==
|
||||||
|
HTS_MAXADDRNUM);
|
||||||
|
SOCaddr_inetntoa(ip, sizeof(ip), addrs[0]);
|
||||||
|
CHECK(strcmp(ip, "10.0.0.1") == 0);
|
||||||
|
SOCaddr_inetntoa(ip, sizeof(ip), addrs[HTS_MAXADDRNUM - 1]);
|
||||||
|
CHECK(strcmp(ip, "10.0.0.4") == 0);
|
||||||
|
|
||||||
|
/* family filter still applies through the list path */
|
||||||
|
IPV6_resolver = 1;
|
||||||
|
CHECK(hts_dns_resolve_all(opt, "dual4.test", addrs, HTS_MAXADDRNUM, &err) ==
|
||||||
|
1);
|
||||||
|
CHECK(SOCaddr_sinfamily(addrs[0]) == AF_INET);
|
||||||
|
IPV6_resolver = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* newhttp_addr() must connect to the addr_index-th address, not always the
|
||||||
|
first: this is what back_connect_next relies on to reach the fallback. */
|
||||||
|
{
|
||||||
|
htsblk r;
|
||||||
|
int count = -1;
|
||||||
|
T_SOC s;
|
||||||
|
|
||||||
|
hts_init_htsblk(&r);
|
||||||
|
s = newhttp_addr(opt, "dual.test", &r, 80, 0, 0, &count);
|
||||||
|
CHECK(count == 2);
|
||||||
|
CHECK(SOCaddr_sinfamily(r.address) == AF_INET6); /* index 0 = v6 */
|
||||||
|
if (s != INVALID_SOCKET)
|
||||||
|
deletesoc(s);
|
||||||
|
|
||||||
|
hts_init_htsblk(&r);
|
||||||
|
count = -1;
|
||||||
|
s = newhttp_addr(opt, "dual.test", &r, 80, 0, 1, &count);
|
||||||
|
CHECK(count == 2);
|
||||||
|
CHECK(SOCaddr_sinfamily(r.address) == AF_INET); /* index 1 = v4 */
|
||||||
|
if (s != INVALID_SOCKET)
|
||||||
|
deletesoc(s);
|
||||||
|
|
||||||
|
/* out-of-range index: no address selected (address stays unset) */
|
||||||
|
hts_init_htsblk(&r);
|
||||||
|
s = newhttp_addr(opt, "dual.test", &r, 80, 0, 2, NULL);
|
||||||
|
CHECK(s == INVALID_SOCKET);
|
||||||
|
if (s != INVALID_SOCKET)
|
||||||
|
deletesoc(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Connect-fallback decision (consumer of the multi-address list): when a
|
||||||
|
stuck connect should abandon the current address for the next one. */
|
||||||
|
{
|
||||||
|
/* no fallback for the last/only candidate, whatever the elapsed time */
|
||||||
|
CHECK(back_connect_fallback_due(0, 1, 9999, 120) == 0);
|
||||||
|
CHECK(back_connect_fallback_due(1, 2, 9999, 120) == 0);
|
||||||
|
CHECK(back_connect_fallback_due(3, 4, 9999, 120) == 0);
|
||||||
|
/* fallback available: wait the per-candidate deadline (cap 10s here) */
|
||||||
|
CHECK(back_connect_fallback_due(0, 2, 9, 120) == 0);
|
||||||
|
CHECK(back_connect_fallback_due(0, 2, 10, 120) == 1);
|
||||||
|
CHECK(back_connect_fallback_due(2, 4, 10, 120) == 1);
|
||||||
|
/* a shorter slot timeout shortens the deadline (min(timeout, cap)) */
|
||||||
|
CHECK(back_connect_fallback_due(0, 2, 4, 5) == 0);
|
||||||
|
CHECK(back_connect_fallback_due(0, 2, 5, 5) == 1);
|
||||||
|
/* no timeout management: never force a fallback */
|
||||||
|
CHECK(back_connect_fallback_due(0, 2, 9999, 0) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
hts_dns_set_resolver_backend(NULL);
|
||||||
|
return failures;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
int dns_selftests(httrackp *opt) {
|
||||||
|
(void) opt;
|
||||||
|
return 0; /* resolver seam only exists in the IPv6 build */
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
51
src/htsdns_selftest.h
Normal file
51
src/htsdns_selftest.h
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/*
|
||||||
|
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: htsdns_selftest.h */
|
||||||
|
/* Author: Xavier Roche */
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
|
||||||
|
#ifndef HTSDNS_SELFTEST_DEFH
|
||||||
|
#define HTSDNS_SELFTEST_DEFH
|
||||||
|
|
||||||
|
#ifdef HTS_INTERNAL_BYTECODE
|
||||||
|
|
||||||
|
#ifndef HTS_DEF_FWSTRUCT_httrackp
|
||||||
|
#define HTS_DEF_FWSTRUCT_httrackp
|
||||||
|
typedef struct httrackp httrackp;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Drive the DNS resolver and cache through a scripted (mock) getaddrinfo,
|
||||||
|
asserting address family, single-address selection, negative caching, the
|
||||||
|
IPv4/IPv6 family filter, and that a cached host is resolved only once.
|
||||||
|
Returns the number of failed checks (0 == success). */
|
||||||
|
int dns_selftests(httrackp *opt);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -33,43 +33,43 @@ EOF
|
|||||||
else
|
else
|
||||||
GET "${url}"
|
GET "${url}"
|
||||||
fi
|
fi
|
||||||
) \
|
) |
|
||||||
| grep -E '^<!ENTITY [a-zA-Z0-9_]' \
|
grep -E '^<!ENTITY [a-zA-Z0-9_]' |
|
||||||
| sed \
|
sed \
|
||||||
-e 's/<!ENTITY //' -e "s/[[:space:]][[:space:]]*/ /g" \
|
-e 's/<!ENTITY //' -e "s/[[:space:]][[:space:]]*/ /g" \
|
||||||
-e 's/-->$//' \
|
-e 's/-->$//' \
|
||||||
-e 's/\([^ ]*\) CDATA "&#\([^\"]*\);" -- \(.*\)/\1 \2 \3/'\
|
-e 's/\([^ ]*\) CDATA "&#\([^\"]*\);" -- \(.*\)/\1 \2 \3/' |
|
||||||
| ( \
|
(
|
||||||
read A
|
read -r A
|
||||||
while test -n "$A"; do
|
while test -n "$A"; do
|
||||||
ent="${A%% *}"
|
ent="${A%% *}"
|
||||||
code=$(echo "$A"|cut -f2 -d' ')
|
code=$(echo "$A" | cut -f2 -d' ')
|
||||||
# compute hash
|
# compute hash
|
||||||
hash=0
|
hash=0
|
||||||
i=0
|
i=0
|
||||||
a=1664525
|
a=1664525
|
||||||
c=1013904223
|
c=1013904223
|
||||||
m="$[1 << 32]"
|
m="$((1 << 32))"
|
||||||
while test "$i" -lt ${#ent}; do
|
while test "$i" -lt ${#ent}; do
|
||||||
d="$(echo -n "${ent:${i}:1}"|hexdump -v -e '/1 "%d"')"
|
d="$(echo -n "${ent:${i}:1}" | hexdump -v -e '/1 "%d"')"
|
||||||
hash="$[((${hash}*${a})%(${m})+${d}+${c})%(${m})]"
|
hash="$((((hash * a) % (m) + d + c) % (m)))"
|
||||||
i=$[${i}+1]
|
i=$((i + 1))
|
||||||
done
|
done
|
||||||
echo -e " /* $A */"
|
echo -e " /* $A */"
|
||||||
echo -e " case ${hash}u:"
|
echo -e " case ${hash}u:"
|
||||||
echo -e " if (len == ${#ent} /* && strncmp(ent, \"${ent}\") == 0 */) {"
|
echo -e " if (len == ${#ent} /* && strncmp(ent, \"${ent}\") == 0 */) {"
|
||||||
echo -e " return ${code};"
|
echo -e " return ${code};"
|
||||||
echo -e " }"
|
echo -e " }"
|
||||||
echo -e " break;"
|
echo -e " break;"
|
||||||
|
|
||||||
# next
|
# next
|
||||||
read A
|
read -r A
|
||||||
done
|
done
|
||||||
)
|
)
|
||||||
cat <<EOF
|
cat <<EOF
|
||||||
}
|
}
|
||||||
/* unknown */
|
/* unknown */
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
) > ${dest}
|
) >${dest}
|
||||||
|
|||||||
@@ -76,7 +76,8 @@ int fa_strjoker(int type, char **filters, int nfil, const char *nom, LLint * siz
|
|||||||
}
|
}
|
||||||
if (size)
|
if (size)
|
||||||
sz = *size;
|
sz = *size;
|
||||||
if (strjoker(nom, filters[i] + filteroffs, &sz, size_flag)) { // reconnu
|
/* size unknown (scan time): no size pointer => size tests stay neutral */
|
||||||
|
if (strjoker(nom, filters[i] + filteroffs, size ? &sz : NULL, size_flag)) {
|
||||||
if (size)
|
if (size)
|
||||||
if (sz != *size)
|
if (sz != *size)
|
||||||
sizelimit = sz;
|
sizelimit = sz;
|
||||||
|
|||||||
202
src/htsglobal.h
202
src/htsglobal.h
@@ -30,23 +30,30 @@ Please visit our Website: http://www.httrack.com
|
|||||||
/* Author: Xavier Roche */
|
/* Author: Xavier Roche */
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
|
||||||
// Fichier réunissant l'ensemble des defines
|
/** @file htsglobal.h
|
||||||
|
* Foundational portability layer included by every other public header:
|
||||||
|
* version strings, platform/feature switches, the HTSEXT_API export marker,
|
||||||
|
* the integer/time/socket typedefs (LLint, TStamp, INTsys, T_SOC), printf
|
||||||
|
* format helpers, and the file-access mode constants. */
|
||||||
|
|
||||||
#ifndef HTTRACK_GLOBAL_DEFH
|
#ifndef HTTRACK_GLOBAL_DEFH
|
||||||
#define HTTRACK_GLOBAL_DEFH
|
#define HTTRACK_GLOBAL_DEFH
|
||||||
|
|
||||||
// Version (also check external version information)
|
/* Package version strings (the library ABI version is VERSION_INFO in
|
||||||
#define HTTRACK_VERSION "3.49-8"
|
configure.ac, decoupled from these). VERSION is the display form, VERSIONID
|
||||||
#define HTTRACK_VERSIONID "3.49.8"
|
the dotted numeric form, AFF_VERSION the short form shown in footers,
|
||||||
#define HTTRACK_AFF_VERSION "3.x"
|
LIB_VERSION the data/cache format generation. */
|
||||||
#define HTTRACK_LIB_VERSION "2.0"
|
#define HTTRACK_VERSION "3.49-9"
|
||||||
|
#define HTTRACK_VERSIONID "3.49.9"
|
||||||
|
#define HTTRACK_AFF_VERSION "3.x"
|
||||||
|
#define HTTRACK_LIB_VERSION "2.0"
|
||||||
|
|
||||||
#ifndef HTS_NOINCLUDES
|
#ifndef HTS_NOINCLUDES
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Définition plate-forme
|
// Platform detection (sizes, feature macros)
|
||||||
#include "htsconfig.h"
|
#include "htsconfig.h"
|
||||||
|
|
||||||
// WIN32 types
|
// WIN32 types
|
||||||
@@ -57,12 +64,18 @@ Please visit our Website: http://www.httrack.com
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* GCC extension */
|
/* Compiler-attribute helpers, no-ops where unsupported.
|
||||||
|
HTS_UNUSED: suppress unused-symbol warnings. HTS_STATIC: an unused-safe
|
||||||
|
static. HTS_PRINTF_FUN(fmt, arg): mark a printf-like function so the
|
||||||
|
compiler type-checks the format string at argument index fmt against the
|
||||||
|
varargs starting at arg. */
|
||||||
#ifndef HTS_UNUSED
|
#ifndef HTS_UNUSED
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
#define HTS_UNUSED __attribute__ ((unused))
|
#define HTS_UNUSED __attribute__((unused))
|
||||||
#define HTS_STATIC static __attribute__ ((unused))
|
|
||||||
#define HTS_PRINTF_FUN(fmt, arg) __attribute__ ((format (printf, fmt, arg)))
|
#define HTS_STATIC static __attribute__((unused))
|
||||||
|
|
||||||
|
#define HTS_PRINTF_FUN(fmt, arg) __attribute__((format(printf, fmt, arg)))
|
||||||
#else
|
#else
|
||||||
#define HTS_UNUSED
|
#define HTS_UNUSED
|
||||||
#define HTS_STATIC static
|
#define HTS_STATIC static
|
||||||
@@ -86,6 +99,7 @@ Please visit our Website: http://www.httrack.com
|
|||||||
#endif
|
#endif
|
||||||
#ifndef S_ISREG
|
#ifndef S_ISREG
|
||||||
#define S_ISREG(m) ((m) & _S_IFREG)
|
#define S_ISREG(m) ((m) & _S_IFREG)
|
||||||
|
|
||||||
#define S_ISDIR(m) ((m) & _S_IFDIR)
|
#define S_ISDIR(m) ((m) & _S_IFDIR)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -99,7 +113,7 @@ Please visit our Website: http://www.httrack.com
|
|||||||
|
|
||||||
#ifndef HTS_LONGLONG
|
#ifndef HTS_LONGLONG
|
||||||
#ifdef SIZEOF_LONG_LONG
|
#ifdef SIZEOF_LONG_LONG
|
||||||
#if SIZEOF_LONG_LONG==8
|
#if SIZEOF_LONG_LONG == 8
|
||||||
#define HTS_LONGLONG 1
|
#define HTS_LONGLONG 1
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@@ -132,7 +146,7 @@ Please visit our Website: http://www.httrack.com
|
|||||||
#define BIGSTK
|
#define BIGSTK
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// compatibilité DOS
|
// DOS-style 8.3 filenames? 1 on Windows, 0 elsewhere
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define HTS_DOSNAME 1
|
#define HTS_DOSNAME 1
|
||||||
#else
|
#else
|
||||||
@@ -168,7 +182,10 @@ Please visit our Website: http://www.httrack.com
|
|||||||
#define __cdecl
|
#define __cdecl
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* rc file */
|
/* Install paths and config-file names. HTTRACKRC is the per-user rc filename,
|
||||||
|
HTTRACKCNF the system-wide config, HTTRACKDIR the shared data directory; the
|
||||||
|
ETC/BIN/LIB/PREFIX paths are the defaults these derive from when not set by
|
||||||
|
the build. */
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define HTS_HTTRACKRC "httrackrc"
|
#define HTS_HTTRACKRC "httrackrc"
|
||||||
#else
|
#else
|
||||||
@@ -187,19 +204,21 @@ Please visit our Website: http://www.httrack.com
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define HTS_HTTRACKRC ".httrackrc"
|
#define HTS_HTTRACKRC ".httrackrc"
|
||||||
#define HTS_HTTRACKCNF HTS_ETCPATH"/httrack.conf"
|
#define HTS_HTTRACKCNF HTS_ETCPATH "/httrack.conf"
|
||||||
|
|
||||||
#ifdef DATADIR
|
#ifdef DATADIR
|
||||||
#define HTS_HTTRACKDIR DATADIR"/httrack/"
|
#define HTS_HTTRACKDIR DATADIR "/httrack/"
|
||||||
#else
|
#else
|
||||||
#define HTS_HTTRACKDIR HTS_PREFIX"/share/httrack/"
|
#define HTS_HTTRACKDIR HTS_PREFIX "/share/httrack/"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Max URL length */
|
/* Maximum URL length, in bytes. Callers size URL/path string buffers to this;
|
||||||
|
anything longer is rejected. */
|
||||||
#define HTS_URLMAXSIZE 1024
|
#define HTS_URLMAXSIZE 1024
|
||||||
/* Max command-line length (>=HTS_URLMAXSIZE*2) */
|
/* Maximum command-line argument length, in bytes (kept >= HTS_URLMAXSIZE*2 so
|
||||||
|
an addr+path pair always fits). */
|
||||||
#define HTS_CDLMAXSIZE 1024
|
#define HTS_CDLMAXSIZE 1024
|
||||||
/* MIME-type buffer contract (htsblk.contenttype/charset/contentencoding); holds
|
/* MIME-type buffer contract (htsblk.contenttype/charset/contentencoding); holds
|
||||||
the longest registered MIME type, the Office OOXML ones reaching 73 chars */
|
the longest registered MIME type, the Office OOXML ones reaching 73 chars */
|
||||||
@@ -207,36 +226,66 @@ Please visit our Website: http://www.httrack.com
|
|||||||
|
|
||||||
/* Copyright (C) 1998 Xavier Roche and other contributors */
|
/* Copyright (C) 1998 Xavier Roche and other contributors */
|
||||||
#define HTTRACK_AFF_AUTHORS "[XR&CO'2014]"
|
#define HTTRACK_AFF_AUTHORS "[XR&CO'2014]"
|
||||||
#define HTS_DEFAULT_FOOTER "<!-- Mirrored from %s%s by HTTrack Website Copier/" HTTRACK_AFF_VERSION " " HTTRACK_AFF_AUTHORS ", %s -->"
|
#define HTS_DEFAULT_FOOTER \
|
||||||
|
"<!-- Mirrored from %s%s by HTTrack Website Copier/" HTTRACK_AFF_VERSION \
|
||||||
|
" " HTTRACK_AFF_AUTHORS ", %s -->"
|
||||||
#define HTTRACK_WEB "http://www.httrack.com"
|
#define HTTRACK_WEB "http://www.httrack.com"
|
||||||
#define HTS_UPDATE_WEBSITE "http://www.httrack.com/update.php3?Product=HTTrack&Version=" HTTRACK_VERSIONID "&VersionStr=" HTTRACK_VERSION "&Platform=%d&Language=%s"
|
#define HTS_UPDATE_WEBSITE \
|
||||||
|
"http://www.httrack.com/" \
|
||||||
|
"update.php3?Product=HTTrack&Version=" HTTRACK_VERSIONID \
|
||||||
|
"&VersionStr=" HTTRACK_VERSION "&Platform=%d&Language=%s"
|
||||||
|
|
||||||
#define H_CRLF "\x0d\x0a"
|
#define H_CRLF "\x0d\x0a"
|
||||||
#define CRLF "\x0d\x0a"
|
#define CRLF "\x0d\x0a"
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define LF "\x0d\x0a"
|
#define LF "\x0d\x0a"
|
||||||
#else
|
#else
|
||||||
#define LF "\x0a"
|
#define LF "\x0a"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* équivaut à "paramètre vide", par exemple -F (none) */
|
/* Sentinel meaning "empty parameter", e.g. -F (none) */
|
||||||
#define HTS_NOPARAM "(none)"
|
#define HTS_NOPARAM "(none)"
|
||||||
#define HTS_NOPARAM2 "\"(none)\""
|
#define HTS_NOPARAM2 "\"(none)\""
|
||||||
|
|
||||||
/* maximum et minimum */
|
/* Boolean flag for option fields and API yes/no returns. Int-backed, not an
|
||||||
#define maximum(A,B) ( (A) > (B) ? (A) : (B) )
|
enum: an enum makes C++ reject `field = 1` / `f(0)` on the exported fields
|
||||||
#define minimum(A,B) ( (A) < (B) ? (A) : (B) )
|
and params. Int-sized, so the httrackp layout and the ABI are unchanged. */
|
||||||
|
#ifndef HTS_DEF_DEFSTRUCT_hts_boolean
|
||||||
|
#define HTS_DEF_DEFSTRUCT_hts_boolean
|
||||||
|
|
||||||
/* chaine no empty ? (and not null) */
|
typedef int hts_boolean;
|
||||||
|
#define HTS_FALSE 0
|
||||||
|
#define HTS_TRUE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef HTS_DEF_DEFSTRUCT_hts_tristate
|
||||||
|
#define HTS_DEF_DEFSTRUCT_hts_tristate
|
||||||
|
/* Tri-state hts_boolean: HTS_DEFAULT (-1) = "unspecified" (copy_htsopt leaves
|
||||||
|
the target untouched); HTS_FALSE/HTS_TRUE = off/on. */
|
||||||
|
typedef int hts_tristate;
|
||||||
|
#define HTS_DEFAULT (-1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Larger/smaller of two values. Macros: arguments are evaluated twice. */
|
||||||
|
#define maximum(A, B) ((A) > (B) ? (A) : (B))
|
||||||
|
|
||||||
|
#define minimum(A, B) ((A) < (B) ? (A) : (B))
|
||||||
|
|
||||||
|
/* True when A is a non-NULL, non-empty string. */
|
||||||
#define strnotempty(A) (((A) != NULL && (A)[0] != '\0'))
|
#define strnotempty(A) (((A) != NULL && (A)[0] != '\0'))
|
||||||
|
|
||||||
/* optimisation inline si possible */
|
/* 'inline' where the dialect supports it (C++), nothing in plain C. */
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
#define HTS_INLINE inline
|
#define HTS_INLINE inline
|
||||||
#else
|
#else
|
||||||
#define HTS_INLINE
|
#define HTS_INLINE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Marks a symbol as part of the library's public ABI: exported from
|
||||||
|
libhttrack and visible to callers. Symbols without it stay internal (hidden
|
||||||
|
under -fvisibility=hidden). Expands to dllexport when building the library,
|
||||||
|
dllimport when consuming it, and the visibility("default") attribute on
|
||||||
|
ELF. */
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#ifdef LIBHTTRACK_EXPORTS
|
#ifdef LIBHTTRACK_EXPORTS
|
||||||
#define HTSEXT_API __declspec(dllexport)
|
#define HTSEXT_API __declspec(dllexport)
|
||||||
@@ -245,9 +294,10 @@ Please visit our Website: http://www.httrack.com
|
|||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
/* See <http://gcc.gnu.org/wiki/Visibility> */
|
/* See <http://gcc.gnu.org/wiki/Visibility> */
|
||||||
#if ( ( defined(__GNUC__) && ( __GNUC__ >= 4 ) ) \
|
#if ((defined(__GNUC__) && (__GNUC__ >= 4)) || \
|
||||||
|| ( defined(HAVE_VISIBILITY) && HAVE_VISIBILITY ) )
|
(defined(HAVE_VISIBILITY) && HAVE_VISIBILITY))
|
||||||
#define HTSEXT_API __attribute__ ((visibility ("default")))
|
|
||||||
|
#define HTSEXT_API __attribute__((visibility("default")))
|
||||||
#else
|
#else
|
||||||
#define HTSEXT_API
|
#define HTSEXT_API
|
||||||
#endif
|
#endif
|
||||||
@@ -260,10 +310,13 @@ Please visit our Website: http://www.httrack.com
|
|||||||
*/
|
*/
|
||||||
#if defined(__GNUC__) && \
|
#if defined(__GNUC__) && \
|
||||||
(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))
|
(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))
|
||||||
|
|
||||||
#define HTS_DEPRECATED(msg) __attribute__((deprecated(msg)))
|
#define HTS_DEPRECATED(msg) __attribute__((deprecated(msg)))
|
||||||
#elif defined(__GNUC__)
|
#elif defined(__GNUC__)
|
||||||
|
|
||||||
#define HTS_DEPRECATED(msg) __attribute__((deprecated))
|
#define HTS_DEPRECATED(msg) __attribute__((deprecated))
|
||||||
#elif defined(_MSC_VER) && (_MSC_VER >= 1400)
|
#elif defined(_MSC_VER) && (_MSC_VER >= 1400)
|
||||||
|
|
||||||
#define HTS_DEPRECATED(msg) __declspec(deprecated(msg))
|
#define HTS_DEPRECATED(msg) __declspec(deprecated(msg))
|
||||||
#else
|
#else
|
||||||
#define HTS_DEPRECATED(msg)
|
#define HTS_DEPRECATED(msg)
|
||||||
@@ -277,12 +330,16 @@ Please visit our Website: http://www.httrack.com
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// long long int? (or int)
|
/* Wide integer types, chosen per platform.
|
||||||
// (and int cast for system functions like malloc() )
|
LLint: signed 64-bit counter for byte counts and large sizes (falls back to
|
||||||
|
plain int where 64-bit is unavailable).
|
||||||
|
TStamp: timestamp/duration in the same width (a double in the no-64-bit
|
||||||
|
fallback).
|
||||||
|
LLintP: the printf conversion for an LLint. */
|
||||||
#if HTS_LONGLONG
|
#if HTS_LONGLONG
|
||||||
#ifdef LLINT_FORMAT
|
#ifdef LLINT_FORMAT
|
||||||
typedef LLINT_TYPE LLint;
|
typedef LLINT_TYPE LLint;
|
||||||
|
|
||||||
typedef LLINT_TYPE TStamp;
|
typedef LLINT_TYPE TStamp;
|
||||||
|
|
||||||
#define LLintP LLINT_FORMAT
|
#define LLintP LLINT_FORMAT
|
||||||
@@ -290,17 +347,21 @@ typedef LLINT_TYPE TStamp;
|
|||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
typedef __int64 LLint;
|
typedef __int64 LLint;
|
||||||
|
|
||||||
typedef __int64 TStamp;
|
typedef __int64 TStamp;
|
||||||
|
|
||||||
#define LLintP "%I64d"
|
#define LLintP "%I64d"
|
||||||
#elif (defined(_LP64) || defined(__x86_64__) \
|
#elif (defined(_LP64) || defined(__x86_64__) || defined(__powerpc64__) || \
|
||||||
|| defined(__powerpc64__) || defined(__64BIT__))
|
defined(__64BIT__))
|
||||||
|
|
||||||
typedef long int LLint;
|
typedef long int LLint;
|
||||||
|
|
||||||
typedef long int TStamp;
|
typedef long int TStamp;
|
||||||
|
|
||||||
#define LLintP "%ld"
|
#define LLintP "%ld"
|
||||||
#else
|
#else
|
||||||
typedef long long int LLint;
|
typedef long long int LLint;
|
||||||
|
|
||||||
typedef long long int TStamp;
|
typedef long long int TStamp;
|
||||||
|
|
||||||
#define LLintP "%lld"
|
#define LLintP "%lld"
|
||||||
@@ -315,6 +376,9 @@ typedef int LLint;
|
|||||||
typedef double TStamp;
|
typedef double TStamp;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* 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
|
#ifdef LFS_FLAG
|
||||||
typedef LLint INTsys;
|
typedef LLint INTsys;
|
||||||
|
|
||||||
@@ -328,8 +392,11 @@ typedef int INTsys;
|
|||||||
#define INTsysP "%d"
|
#define INTsysP "%d"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Socket-handle type. An unsigned integer wide enough for a Windows SOCKET;
|
||||||
|
a plain int file descriptor on POSIX. */
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#if defined(_WIN64)
|
#if defined(_WIN64)
|
||||||
|
|
||||||
typedef unsigned __int64 T_SOC;
|
typedef unsigned __int64 T_SOC;
|
||||||
#else
|
#else
|
||||||
typedef unsigned __int32 T_SOC;
|
typedef unsigned __int32 T_SOC;
|
||||||
@@ -338,25 +405,35 @@ typedef unsigned __int32 T_SOC;
|
|||||||
typedef int T_SOC;
|
typedef int T_SOC;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* IPV4, IPV6 and various unified structures */
|
/* Buffer size for a printed network address (IPv4 or IPv6, NUL included). */
|
||||||
#define HTS_MAXADDRLEN 64
|
#define HTS_MAXADDRLEN 64
|
||||||
|
|
||||||
|
/* Max resolved addresses kept per host for connect fallback (dead IPv6 etc.).
|
||||||
|
*/
|
||||||
|
#define HTS_MAXADDRNUM 4
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#else
|
#else
|
||||||
#define __cdecl
|
#define __cdecl
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* mode pour mkdir ET chmod (accès aux fichiers) */
|
/* Permission bits for created folders and files (mkdir and chmod).
|
||||||
#define HTS_PROTECT_FOLDER (S_IRUSR|S_IWUSR|S_IXUSR)
|
PROTECT_FOLDER is owner-only. With HTS_ACCESS set (the default) the ACCESS_
|
||||||
|
modes also grant group/other read; otherwise they stay owner-only. */
|
||||||
|
#define HTS_PROTECT_FOLDER (S_IRUSR | S_IWUSR | S_IXUSR)
|
||||||
|
|
||||||
#if HTS_ACCESS
|
#if HTS_ACCESS
|
||||||
#define HTS_ACCESS_FILE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)
|
#define HTS_ACCESS_FILE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
|
||||||
#define HTS_ACCESS_FOLDER (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH)
|
|
||||||
|
#define HTS_ACCESS_FOLDER \
|
||||||
|
(S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)
|
||||||
#else
|
#else
|
||||||
#define HTS_ACCESS_FILE (S_IRUSR|S_IWUSR)
|
#define HTS_ACCESS_FILE (S_IRUSR | S_IWUSR)
|
||||||
#define HTS_ACCESS_FOLDER (S_IRUSR|S_IWUSR|S_IXUSR)
|
|
||||||
|
#define HTS_ACCESS_FOLDER (S_IRUSR | S_IWUSR | S_IXUSR)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* vérifier la déclaration des variables préprocesseur */
|
/* Sanity-check that the required preprocessor switches are defined */
|
||||||
#ifndef HTS_DOSNAME
|
#ifndef HTS_DOSNAME
|
||||||
#error | HTS_DOSNAME Has not been defined.
|
#error | HTS_DOSNAME Has not been defined.
|
||||||
#error | Set it to 1 if you are under DOS, 0 under Unix.
|
#error | Set it to 1 if you are under DOS, 0 under Unix.
|
||||||
@@ -366,22 +443,26 @@ typedef int T_SOC;
|
|||||||
#error
|
#error
|
||||||
#endif
|
#endif
|
||||||
#ifndef HTS_ACCESS
|
#ifndef HTS_ACCESS
|
||||||
/* Par défaut, accès à tous les utilisateurs */
|
/* Default: files readable by all users */
|
||||||
#define HTS_ACCESS 1
|
#define HTS_ACCESS 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* fflush sur stdout */
|
/* fflush sur stdout */
|
||||||
#define io_flush { fflush(stdout); fflush(stdin); }
|
#define io_flush \
|
||||||
|
{ \
|
||||||
|
fflush(stdout); \
|
||||||
|
fflush(stdin); \
|
||||||
|
}
|
||||||
|
|
||||||
/* HTSLib */
|
/* HTSLib */
|
||||||
|
|
||||||
// Cache DNS, accélère les résolution d'adresses
|
// Enable the DNS cache (speeds up address resolution)
|
||||||
#define HTS_DNSCACHE 1
|
#define HTS_DNSCACHE 1
|
||||||
|
|
||||||
// ID d'une pseudo-socket locale pour les file://
|
// Pseudo-socket id standing in for a local file:// transfer
|
||||||
#define LOCAL_SOCKET_ID -2
|
#define LOCAL_SOCKET_ID -2
|
||||||
|
|
||||||
// taille de chaque buffer (10 sockets 650 ko)
|
// Per-connection transfer buffer size, in bytes
|
||||||
#define TAILLE_BUFFER 65536
|
#define TAILLE_BUFFER 65536
|
||||||
|
|
||||||
#ifdef HTS_DO_NOT_USE_PTHREAD
|
#ifdef HTS_DO_NOT_USE_PTHREAD
|
||||||
@@ -391,7 +472,7 @@ typedef int T_SOC;
|
|||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
// trace mallocs
|
// trace mallocs
|
||||||
//#define HTS_TRACE_MALLOC
|
// #define HTS_TRACE_MALLOC
|
||||||
#ifdef HTS_TRACE_MALLOC
|
#ifdef HTS_TRACE_MALLOC
|
||||||
typedef unsigned long int t_htsboundary;
|
typedef unsigned long int t_htsboundary;
|
||||||
|
|
||||||
@@ -405,6 +486,7 @@ struct mlink {
|
|||||||
int id;
|
int id;
|
||||||
struct mlink *next;
|
struct mlink *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const t_htsboundary htsboundary = 0xDEADBEEF;
|
static const t_htsboundary htsboundary = 0xDEADBEEF;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@@ -418,7 +500,7 @@ static const t_htsboundary htsboundary = 0xDEADBEEF;
|
|||||||
/* Debugging */
|
/* Debugging */
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
|
||||||
// débuggage types
|
// type-detection debug
|
||||||
#define DEBUG_SHOWTYPES 0
|
#define DEBUG_SHOWTYPES 0
|
||||||
// backing debug
|
// backing debug
|
||||||
#define BDEBUG 0
|
#define BDEBUG 0
|
||||||
@@ -436,28 +518,28 @@ static const t_htsboundary htsboundary = 0xDEADBEEF;
|
|||||||
#define DEBUG_ROBOTS 0
|
#define DEBUG_ROBOTS 0
|
||||||
// debug hash
|
// debug hash
|
||||||
#define DEBUG_HASH 0
|
#define DEBUG_HASH 0
|
||||||
// Vérification d'intégrité
|
// integrity-check debug
|
||||||
#define DEBUG_CHECKINT 0
|
#define DEBUG_CHECKINT 0
|
||||||
// nbr sockets debug
|
// nbr sockets debug
|
||||||
#define NSDEBUG 0
|
#define NSDEBUG 0
|
||||||
|
|
||||||
// débuggage HTSLib
|
// HTSLib debug
|
||||||
#define HDEBUG 0
|
#define HDEBUG 0
|
||||||
// surveillance de la connexion
|
// surveillance de la connexion
|
||||||
#define CNXDEBUG 0
|
#define CNXDEBUG 0
|
||||||
// debuggage cookies
|
// debuggage cookies
|
||||||
#define DEBUG_COOK 0
|
#define DEBUG_COOK 0
|
||||||
// débuggage hard..
|
// heavy/low-level debug
|
||||||
#define HTS_WIDE_DEBUG 0
|
#define HTS_WIDE_DEBUG 0
|
||||||
// debuggage deletehttp et cie
|
// debuggage deletehttp et cie
|
||||||
#define HTS_DEBUG_CLOSESOCK 0
|
#define HTS_DEBUG_CLOSESOCK 0
|
||||||
// debug tracage mémoire
|
// memory-tracing debug
|
||||||
#define MEMDEBUG 0
|
#define MEMDEBUG 0
|
||||||
|
|
||||||
// htsmain
|
// htsmain
|
||||||
#define DEBUG_STEPS 0
|
#define DEBUG_STEPS 0
|
||||||
|
|
||||||
// Débuggage de contrôle
|
// Derived debug control switches
|
||||||
#if HTS_DEBUG_CLOSESOCK
|
#if HTS_DEBUG_CLOSESOCK
|
||||||
#define _HTS_WIDE 1
|
#define _HTS_WIDE 1
|
||||||
#endif
|
#endif
|
||||||
@@ -467,7 +549,13 @@ static const t_htsboundary htsboundary = 0xDEADBEEF;
|
|||||||
#if _HTS_WIDE
|
#if _HTS_WIDE
|
||||||
extern FILE *DEBUG_fp;
|
extern FILE *DEBUG_fp;
|
||||||
|
|
||||||
#define DEBUG_W(A) { if (DEBUG_fp==NULL) DEBUG_fp=fopen("bug.out","wb"); fprintf(DEBUG_fp,":>"A); fflush(DEBUG_fp); }
|
#define DEBUG_W(A) \
|
||||||
|
{ \
|
||||||
|
if (DEBUG_fp == NULL) \
|
||||||
|
DEBUG_fp = fopen("bug.out", "wb"); \
|
||||||
|
fprintf(DEBUG_fp, ":>" A); \
|
||||||
|
fflush(DEBUG_fp); \
|
||||||
|
}
|
||||||
#undef _
|
#undef _
|
||||||
#define _ ,
|
#define _ ,
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -106,10 +106,10 @@ static coucal_hashkeys key_adrfil_hashes_generic(void *arg,
|
|||||||
const lien_url*const lien = (const lien_url*) value;
|
const lien_url*const lien = (const lien_url*) value;
|
||||||
const char *const adr = !former ? lien->adr : lien->former_adr;
|
const char *const adr = !former ? lien->adr : lien->former_adr;
|
||||||
const char *const fil = !former ? lien->fil : lien->former_fil;
|
const char *const fil = !former ? lien->fil : lien->former_fil;
|
||||||
const char *const adr_norm = adr != NULL ?
|
const char *const adr_norm =
|
||||||
( hash->normalized ? jump_normalized_const(adr)
|
adr != NULL ? (hash->norm_host ? jump_normalized_const(adr)
|
||||||
: jump_identification_const(adr) )
|
: jump_identification_const(adr))
|
||||||
: NULL;
|
: NULL;
|
||||||
|
|
||||||
// copy address
|
// copy address
|
||||||
assertf(adr_norm != NULL);
|
assertf(adr_norm != NULL);
|
||||||
@@ -117,10 +117,18 @@ static coucal_hashkeys key_adrfil_hashes_generic(void *arg,
|
|||||||
|
|
||||||
// copy link
|
// copy link
|
||||||
assertf(fil != NULL);
|
assertf(fil != NULL);
|
||||||
if (hash->normalized) {
|
{
|
||||||
fil_normalized(fil, &hash->normfil[strlen(hash->normfil)]);
|
/* resolve the per-URL strip keys; strip applies even when urlhack is off */
|
||||||
} else {
|
char BIGSTK keybuf[HTS_URLMAXSIZE];
|
||||||
strcpy(&hash->normfil[strlen(hash->normfil)], fil);
|
const char *const keys = hts_query_strip_keys(hash->strip_query, adr, fil,
|
||||||
|
keybuf, sizeof(keybuf));
|
||||||
|
|
||||||
|
if (hash->norm_slash || hash->norm_query || keys != NULL) {
|
||||||
|
fil_normalized_filtered_ex(fil, &hash->normfil[strlen(hash->normfil)],
|
||||||
|
keys, hash->norm_slash, hash->norm_query);
|
||||||
|
} else {
|
||||||
|
strcpy(&hash->normfil[strlen(hash->normfil)], fil);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// hash
|
// hash
|
||||||
@@ -132,8 +140,7 @@ static int key_adrfil_equals_generic(void *arg,
|
|||||||
coucal_key_const a_,
|
coucal_key_const a_,
|
||||||
coucal_key_const b_,
|
coucal_key_const b_,
|
||||||
const int former) {
|
const int former) {
|
||||||
hash_struct *const hash = (hash_struct*) arg;
|
hash_struct *const hash = (hash_struct *) arg;
|
||||||
const int normalized = hash->normalized;
|
|
||||||
const lien_url*const a = (const lien_url*) a_;
|
const lien_url*const a = (const lien_url*) a_;
|
||||||
const lien_url*const b = (const lien_url*) b_;
|
const lien_url*const b = (const lien_url*) b_;
|
||||||
const char *const a_adr = !former ? a->adr : a->former_adr;
|
const char *const a_adr = !former ? a->adr : a->former_adr;
|
||||||
@@ -150,10 +157,10 @@ static int key_adrfil_equals_generic(void *arg,
|
|||||||
assertf(b_fil != NULL);
|
assertf(b_fil != NULL);
|
||||||
|
|
||||||
// skip scheme and authentication to the domain (possibly without www.)
|
// skip scheme and authentication to the domain (possibly without www.)
|
||||||
ja = normalized
|
ja = hash->norm_host ? jump_normalized_const(a_adr)
|
||||||
? jump_normalized_const(a_adr) : jump_identification_const(a_adr);
|
: jump_identification_const(a_adr);
|
||||||
jb = normalized
|
jb = hash->norm_host ? jump_normalized_const(b_adr)
|
||||||
? jump_normalized_const(b_adr) : jump_identification_const(b_adr);
|
: jump_identification_const(b_adr);
|
||||||
assertf(ja != NULL);
|
assertf(ja != NULL);
|
||||||
assertf(jb != NULL);
|
assertf(jb != NULL);
|
||||||
if (strcasecmp(ja, jb) != 0) {
|
if (strcasecmp(ja, jb) != 0) {
|
||||||
@@ -161,12 +168,23 @@ static int key_adrfil_equals_generic(void *arg,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// now compare pathes
|
// now compare pathes
|
||||||
if (normalized) {
|
{
|
||||||
fil_normalized(a_fil, hash->normfil);
|
char BIGSTK ka[HTS_URLMAXSIZE], kb[HTS_URLMAXSIZE];
|
||||||
fil_normalized(b_fil, hash->normfil2);
|
const char *const keysa =
|
||||||
return strcmp(hash->normfil, hash->normfil2) == 0;
|
hts_query_strip_keys(hash->strip_query, a_adr, a_fil, ka, sizeof(ka));
|
||||||
} else {
|
const char *const keysb =
|
||||||
return strcmp(a_fil, b_fil) == 0;
|
hts_query_strip_keys(hash->strip_query, b_adr, b_fil, kb, sizeof(kb));
|
||||||
|
|
||||||
|
if (hash->norm_slash || hash->norm_query || keysa != NULL ||
|
||||||
|
keysb != NULL) {
|
||||||
|
fil_normalized_filtered_ex(a_fil, hash->normfil, keysa, hash->norm_slash,
|
||||||
|
hash->norm_query);
|
||||||
|
fil_normalized_filtered_ex(b_fil, hash->normfil2, keysb, hash->norm_slash,
|
||||||
|
hash->norm_query);
|
||||||
|
return strcmp(hash->normfil, hash->normfil2) == 0;
|
||||||
|
} else {
|
||||||
|
return strcmp(a_fil, b_fil) == 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -222,11 +240,17 @@ static int key_former_adrfil_equals(void *arg,
|
|||||||
return key_adrfil_equals_generic(arg, a, b, 1);
|
return key_adrfil_equals_generic(arg, a, b, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hash_init(httrackp *opt, hash_struct * hash, int normalized) {
|
void hash_init(httrackp *opt, hash_struct *hash, hts_boolean normalized) {
|
||||||
hash->sav = coucal_new(0);
|
hash->sav = coucal_new(0);
|
||||||
hash->adrfil = coucal_new(0);
|
hash->adrfil = coucal_new(0);
|
||||||
hash->former_adrfil = coucal_new(0);
|
hash->former_adrfil = coucal_new(0);
|
||||||
hash->normalized = normalized;
|
/* urlhack is the umbrella; per-feature negatives opt out of each part */
|
||||||
|
hash->norm_host = normalized && !opt->no_www_dedup;
|
||||||
|
hash->norm_slash = normalized && !opt->no_slash_dedup;
|
||||||
|
hash->norm_query = normalized && !opt->no_query_dedup;
|
||||||
|
/* snapshot the query-strip list (not owned; valid for the hash lifetime) */
|
||||||
|
hash->strip_query =
|
||||||
|
StringNotEmpty(opt->strip_query) ? StringBuff(opt->strip_query) : NULL;
|
||||||
|
|
||||||
hts_set_hash_handler(hash->sav, opt);
|
hts_set_hash_handler(hash->sav, opt);
|
||||||
hts_set_hash_handler(hash->adrfil, opt);
|
hts_set_hash_handler(hash->adrfil, opt);
|
||||||
@@ -282,6 +306,26 @@ void hash_free(hash_struct *hash) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Test helper: do the two URLs dedupe to the same key under opt's urlhack
|
||||||
|
flags? Exercises the live hash compare (norm_host/slash/query resolution). */
|
||||||
|
hts_boolean hash_url_equals(httrackp *opt, const char *adra, const char *fila,
|
||||||
|
const char *adrb, const char *filb) {
|
||||||
|
hash_struct hash;
|
||||||
|
lien_url la, lb;
|
||||||
|
hts_boolean eq;
|
||||||
|
|
||||||
|
memset(&la, 0, sizeof(la));
|
||||||
|
memset(&lb, 0, sizeof(lb));
|
||||||
|
la.adr = key_duphandler(NULL, adra);
|
||||||
|
la.fil = key_duphandler(NULL, fila);
|
||||||
|
lb.adr = key_duphandler(NULL, adrb);
|
||||||
|
lb.fil = key_duphandler(NULL, filb);
|
||||||
|
hash_init(opt, &hash, opt->urlhack);
|
||||||
|
eq = key_adrfil_equals(&hash, &la, &lb);
|
||||||
|
hash_free(&hash);
|
||||||
|
return eq;
|
||||||
|
}
|
||||||
|
|
||||||
// retour: position ou -1 si non trouvé
|
// retour: position ou -1 si non trouvé
|
||||||
int hash_read(const hash_struct * hash, const char *nom1, const char *nom2,
|
int hash_read(const hash_struct * hash, const char *nom1, const char *nom2,
|
||||||
hash_struct_type type) {
|
hash_struct_type type) {
|
||||||
|
|||||||
@@ -51,8 +51,12 @@ typedef enum hash_struct_type {
|
|||||||
} hash_struct_type;
|
} hash_struct_type;
|
||||||
|
|
||||||
// tables de hachage
|
// tables de hachage
|
||||||
void hash_init(httrackp *opt, hash_struct *hash, int normalized);
|
void hash_init(httrackp *opt, hash_struct *hash, hts_boolean normalized);
|
||||||
void hash_free(hash_struct *hash);
|
void hash_free(hash_struct *hash);
|
||||||
|
/* Test helper: HTS_TRUE if the two URLs dedupe together under opt's urlhack
|
||||||
|
flags. */
|
||||||
|
hts_boolean hash_url_equals(httrackp *opt, const char *adra, const char *fila,
|
||||||
|
const char *adrb, const char *filb);
|
||||||
int hash_read(const hash_struct * hash, const char *nom1, const char *nom2,
|
int hash_read(const hash_struct * hash, const char *nom1, const char *nom2,
|
||||||
hash_struct_type type);
|
hash_struct_type type);
|
||||||
void hash_write(hash_struct * hash, size_t lpos);
|
void hash_write(hash_struct * hash, size_t lpos);
|
||||||
|
|||||||
@@ -563,6 +563,7 @@ void help(const char *app, int more) {
|
|||||||
(" %x do not include any password for external password protected websites (%x0 include)");
|
(" %x do not include any password for external password protected websites (%x0 include)");
|
||||||
infomsg
|
infomsg
|
||||||
(" %q *include query string for local files (useless, for information purpose only) (%q0 don't include)");
|
(" %q *include query string for local files (useless, for information purpose only) (%q0 don't include)");
|
||||||
|
infomsg(" %g strip query keys for dedup ([host/pattern=]key1,key2,...)");
|
||||||
infomsg
|
infomsg
|
||||||
(" o *generate output html file in case of error (404..) (o0 don't generate)");
|
(" o *generate output html file in case of error (404..) (o0 don't generate)");
|
||||||
infomsg(" X *purge old files after update (X0 keep delete)");
|
infomsg(" X *purge old files after update (X0 keep delete)");
|
||||||
@@ -587,6 +588,9 @@ void help(const char *app, int more) {
|
|||||||
(" %s update hacks: various hacks to limit re-transfers when updating (identical size, bogus response..)");
|
(" %s update hacks: various hacks to limit re-transfers when updating (identical size, bogus response..)");
|
||||||
infomsg
|
infomsg
|
||||||
(" %u url hacks: various hacks to limit duplicate URLs (strip //, www.foo.com==foo.com..)");
|
(" %u url hacks: various hacks to limit duplicate URLs (strip //, www.foo.com==foo.com..)");
|
||||||
|
infomsg(" opt out of one url-hack part: --keep-www-prefix "
|
||||||
|
"(www.foo.com<>foo.com), --keep-double-slashes (//), "
|
||||||
|
"--keep-query-order (?b&a)");
|
||||||
infomsg
|
infomsg
|
||||||
(" %A assume that a type (cgi,asp..) is always linked with a mime type (-%A php3,cgi=text/html;dat,bin=application/x-zip)");
|
(" %A assume that a type (cgi,asp..) is always linked with a mime type (-%A php3,cgi=text/html;dat,bin=application/x-zip)");
|
||||||
infomsg(" shortcut: '--assume standard' is equivalent to -%A "
|
infomsg(" shortcut: '--assume standard' is equivalent to -%A "
|
||||||
@@ -646,9 +650,7 @@ void help(const char *app, int more) {
|
|||||||
infomsg("");
|
infomsg("");
|
||||||
infomsg("Guru options: (do NOT use if possible)");
|
infomsg("Guru options: (do NOT use if possible)");
|
||||||
infomsg(" #X *use optimized engine (limited memory boundary checks)");
|
infomsg(" #X *use optimized engine (limited memory boundary checks)");
|
||||||
infomsg(" #0 filter test (-#0 '*.gif' 'www.bar.com/foo.gif')");
|
infomsg(" #test list engine self-tests (run one with -#test=NAME [args])");
|
||||||
infomsg(" #1 simplify test (-#1 ./foo/bar/../foobar)");
|
|
||||||
infomsg(" #2 type test (-#2 /foo/bar.php)");
|
|
||||||
infomsg(" #C cache list (-#C '*.com/spider*.gif'");
|
infomsg(" #C cache list (-#C '*.com/spider*.gif'");
|
||||||
infomsg(" #R cache repair (damaged cache)");
|
infomsg(" #R cache repair (damaged cache)");
|
||||||
infomsg(" #d debug parser");
|
infomsg(" #d debug parser");
|
||||||
|
|||||||
1085
src/htslib.c
1085
src/htslib.c
File diff suppressed because it is too large
Load Diff
67
src/htslib.h
67
src/htslib.h
@@ -147,11 +147,13 @@ struct OLD_htsblk {
|
|||||||
#define HTS_DEF_FWSTRUCT_t_dnscache
|
#define HTS_DEF_FWSTRUCT_t_dnscache
|
||||||
typedef struct t_dnscache t_dnscache;
|
typedef struct t_dnscache t_dnscache;
|
||||||
#endif
|
#endif
|
||||||
|
// One DNS cache record, stored as a coucal value keyed by hostname.
|
||||||
struct t_dnscache {
|
struct t_dnscache {
|
||||||
struct t_dnscache *next;
|
// resolved addresses, in resolver (RFC 6724) order; host_count==0 means the
|
||||||
const char *iadr;
|
// name does not resolve (negative cache). host_count<=HTS_MAXADDRNUM.
|
||||||
size_t host_length; // length ; (4 or 16) ; 0 for error
|
int host_count;
|
||||||
char host_addr[HTS_MAXADDRLEN];
|
size_t host_length[HTS_MAXADDRNUM]; // sockaddr length of each (16 or 28)
|
||||||
|
char host_addr[HTS_MAXADDRNUM][HTS_MAXADDRLEN];
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Library internal definictions */
|
/* Library internal definictions */
|
||||||
@@ -182,10 +184,22 @@ int http_sendhead(httrackp * opt, t_cookie * cookie, int mode, const char *xsend
|
|||||||
const char *adr, const char *fil,
|
const char *adr, const char *fil,
|
||||||
const char *referer_adr, const char *referer_fil,
|
const char *referer_adr, const char *referer_fil,
|
||||||
htsblk * retour);
|
htsblk * retour);
|
||||||
|
/* Build the request "Cookie:" header line for stored cookies matching
|
||||||
|
domain/path into dst (NUL-terminated). Exposed for the -#Q self-test;
|
||||||
|
wraps the same logic http_sendhead() uses. Returns cookies emitted. */
|
||||||
|
int http_cookie_header_selftest(t_cookie *cookie, const char *domain,
|
||||||
|
const char *path, char *dst, size_t dst_size);
|
||||||
|
|
||||||
//int newhttp(char* iadr,char* err=NULL);
|
//int newhttp(char* iadr,char* err=NULL);
|
||||||
T_SOC newhttp(httrackp * opt, const char *iadr, htsblk * retour, int port,
|
T_SOC newhttp(httrackp * opt, const char *iadr, htsblk * retour, int port,
|
||||||
int waitconnect);
|
int waitconnect);
|
||||||
|
/* Like newhttp(), but connect to the addr_index-th resolved address of the host
|
||||||
|
(0-based) instead of always the first; *addr_count, if non-NULL, is set to
|
||||||
|
the total resolved addresses. newhttp() == newhttp_addr(...,0,NULL). Used by
|
||||||
|
the slot scheduler to try the next address when a connect fails (dead IPv6
|
||||||
|
etc.). */
|
||||||
|
T_SOC newhttp_addr(httrackp *opt, const char *iadr, htsblk *retour, int port,
|
||||||
|
int waitconnect, int addr_index, int *addr_count);
|
||||||
HTS_INLINE void deletehttp(htsblk * r);
|
HTS_INLINE void deletehttp(htsblk * r);
|
||||||
HTS_INLINE int deleteaddr(htsblk * r);
|
HTS_INLINE int deleteaddr(htsblk * r);
|
||||||
HTS_INLINE void deletesoc(T_SOC soc);
|
HTS_INLINE void deletesoc(T_SOC soc);
|
||||||
@@ -193,15 +207,31 @@ HTS_INLINE void deletesoc_r(htsblk * r);
|
|||||||
htsblk http_test(httrackp * opt, const char *adr, const char *fil, char *loc);
|
htsblk http_test(httrackp * opt, const char *adr, const char *fil, char *loc);
|
||||||
int check_readinput(htsblk * r);
|
int check_readinput(htsblk * r);
|
||||||
int check_readinput_t(T_SOC soc, int timeout);
|
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);
|
||||||
void treathead(t_cookie * cookie, const char *adr, const char *fil, htsblk * retour,
|
void treathead(t_cookie * cookie, const char *adr, const char *fil, htsblk * retour,
|
||||||
char *rcvd);
|
char *rcvd);
|
||||||
void treatfirstline(htsblk * retour, const char *rcvd);
|
void treatfirstline(htsblk * retour, const char *rcvd);
|
||||||
|
|
||||||
// sous-fonctions
|
// sous-fonctions
|
||||||
LLint http_xfread1(htsblk * r, int bufl);
|
LLint http_xfread1(htsblk * r, int bufl);
|
||||||
HTS_INLINE SOCaddr* hts_dns_resolve2(httrackp * opt, const char *iadr,
|
/* Cached resolver: fill out[0..count-1] with up to max addresses for iadr (in
|
||||||
SOCaddr *const addr,
|
resolver order), returning the count (0 = does not resolve, negative-cached).
|
||||||
const char **error);
|
Resolves once per host; later calls read the DNS cache. Must hold no lock
|
||||||
|
(brackets opt->state.lock itself). */
|
||||||
|
int hts_dns_resolve_all(httrackp *opt, const char *iadr, SOCaddr *out, int max,
|
||||||
|
const char **error);
|
||||||
|
HTS_INLINE SOCaddr *hts_dns_resolve2(httrackp *opt, const char *iadr,
|
||||||
|
SOCaddr *const addr, const char **error);
|
||||||
HTS_INLINE SOCaddr* hts_dns_resolve(httrackp * opt, const char *iadr,
|
HTS_INLINE SOCaddr* hts_dns_resolve(httrackp * opt, const char *iadr,
|
||||||
SOCaddr *const addr);
|
SOCaddr *const addr);
|
||||||
HTSEXT_API SOCaddr* hts_dns_resolve_nocache2(const char *const hostname,
|
HTSEXT_API SOCaddr* hts_dns_resolve_nocache2(const char *const hostname,
|
||||||
@@ -214,8 +244,9 @@ HTSEXT_API int check_hostname_dns(const char *const hostname);
|
|||||||
int ftp_available(void);
|
int ftp_available(void);
|
||||||
|
|
||||||
#if HTS_DNSCACHE
|
#if HTS_DNSCACHE
|
||||||
void hts_cache_free(t_dnscache *const cache);
|
/* Return opt's DNS cache hashtable (hostname -> t_dnscache record), creating it
|
||||||
t_dnscache *hts_cache(httrackp * opt);
|
on first use. Records are owned by the table and freed on coucal_delete. */
|
||||||
|
coucal hts_cache(httrackp *opt);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// outils divers
|
// outils divers
|
||||||
@@ -465,10 +496,22 @@ HTS_STATIC int strcmpnocase(const char *a, const char *b) {
|
|||||||
|
|
||||||
// is this MIME an hypertext MIME (text/html), html/js-style or other script/text type?
|
// is this MIME an hypertext MIME (text/html), html/js-style or other script/text type?
|
||||||
#define HTS_HYPERTEXT_DEFAULT_MIME "text/html"
|
#define HTS_HYPERTEXT_DEFAULT_MIME "text/html"
|
||||||
|
/* Sentinel stored when the server declared no Content-Type. It is html-ish
|
||||||
|
for every type test (so a typeless response still parses/stores as today),
|
||||||
|
but the naming code (wire_patches_ext) treats it as "no declared type" and
|
||||||
|
keeps the URL extension. It rides the cache, so updates name consistently. */
|
||||||
|
#define HTS_UNKNOWN_MIME "unknown/unknown"
|
||||||
|
/* Map the no-declared-type sentinel back to a real type for any header or
|
||||||
|
record we EMIT or PERSIST, so "unknown/unknown" never reaches a consumer
|
||||||
|
(a served Content-Type, a ProxyTrack .arc record, ...). */
|
||||||
|
#define hts_effective_mime(m) \
|
||||||
|
(strfield2((m), HTS_UNKNOWN_MIME) ? HTS_HYPERTEXT_DEFAULT_MIME : (m))
|
||||||
|
|
||||||
#define is_html_mime_type(a) \
|
#define is_html_mime_type(a) \
|
||||||
( (strfield2((a),"text/html")!=0)\
|
((strfield2((a), "text/html") != 0) || \
|
||||||
|| (strfield2((a),"application/xhtml+xml")!=0) \
|
(strfield2((a), "application/xhtml+xml") != 0) || \
|
||||||
|
(strfield2((a), HTS_UNKNOWN_MIME) != \
|
||||||
|
0) /* no declared type: treat as html */ \
|
||||||
)
|
)
|
||||||
#define is_hypertext_mime__(a) \
|
#define is_hypertext_mime__(a) \
|
||||||
( \
|
( \
|
||||||
|
|||||||
100
src/htsmodules.h
100
src/htsmodules.h
@@ -31,10 +31,15 @@ Please visit our Website: http://www.httrack.com
|
|||||||
/* Author: Xavier Roche */
|
/* Author: Xavier Roche */
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
|
||||||
|
/** @file htsmodules.h
|
||||||
|
Loadable-parser (external module) interface. The engine hands a downloaded
|
||||||
|
object to a module via htsmoduleStruct; the module reports discovered links
|
||||||
|
back through the addLink callback. */
|
||||||
|
|
||||||
#ifndef HTS_MODULES
|
#ifndef HTS_MODULES
|
||||||
#define HTS_MODULES
|
#define HTS_MODULES
|
||||||
|
|
||||||
/* Forware definitions */
|
/* Forward definitions */
|
||||||
#ifndef HTS_DEF_FWSTRUCT_lien_url
|
#ifndef HTS_DEF_FWSTRUCT_lien_url
|
||||||
#define HTS_DEF_FWSTRUCT_lien_url
|
#define HTS_DEF_FWSTRUCT_lien_url
|
||||||
typedef struct lien_url lien_url;
|
typedef struct lien_url lien_url;
|
||||||
@@ -56,49 +61,49 @@ typedef struct cache_back cache_back;
|
|||||||
typedef struct hash_struct hash_struct;
|
typedef struct hash_struct hash_struct;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Function type to add links inside the module
|
/** Callback a module invokes to report a discovered link.
|
||||||
link : link to add (absolute or relative)
|
str: the per-object context the module was called with.
|
||||||
str : structure defined below
|
link: link to add (absolute or relative); the engine copies it.
|
||||||
Returns 1 if the link was added, 0 if not
|
Returns 1 if the engine accepted/queued the link, 0 if it was rejected. */
|
||||||
*/
|
|
||||||
#ifndef HTS_DEF_FWSTRUCT_htsmoduleStruct
|
#ifndef HTS_DEF_FWSTRUCT_htsmoduleStruct
|
||||||
#define HTS_DEF_FWSTRUCT_htsmoduleStruct
|
#define HTS_DEF_FWSTRUCT_htsmoduleStruct
|
||||||
typedef struct htsmoduleStruct htsmoduleStruct;
|
typedef struct htsmoduleStruct htsmoduleStruct;
|
||||||
#endif
|
#endif
|
||||||
typedef int (*t_htsAddLink) (htsmoduleStruct * str, char *link);
|
typedef int (*t_htsAddLink)(htsmoduleStruct *str, char *link);
|
||||||
|
|
||||||
/* Structure passed to the module */
|
/** Per-object context passed to a parser module for one downloaded file.
|
||||||
|
Field access classes are noted; engine owns all pointers unless stated. */
|
||||||
struct htsmoduleStruct {
|
struct htsmoduleStruct {
|
||||||
/* Read-only elements */
|
/* Read-only elements */
|
||||||
const char *filename; /* filename (C:\My Web Sites\...) */
|
const char *filename; /* filename (C:\My Web Sites\...) */
|
||||||
int size; /* size of filename (should be > 0) */
|
int size; /* size of filename (should be > 0) */
|
||||||
const char *mime; /* MIME type of the object */
|
const char *mime; /* MIME type of the object */
|
||||||
const char *url_host; /* incoming hostname (www.foo.com) */
|
const char *url_host; /* incoming hostname (www.foo.com) */
|
||||||
const char *url_file; /* incoming filename (/bar/bar.gny) */
|
const char *url_file; /* incoming filename (/bar/bar.gny) */
|
||||||
|
|
||||||
/* Write-only */
|
/* Write-only */
|
||||||
const char *wrapper_name; /* name of wrapper (static string) */
|
const char *wrapper_name; /* name of wrapper (static string) */
|
||||||
char *err_msg; /* if an error occurred, the error message (max. 1KB) */
|
char *err_msg; /* if an error occurred, the error message (max. 1KB) */
|
||||||
|
|
||||||
/* Read/Write */
|
/* Read/Write */
|
||||||
int relativeToHtmlLink; /* set this to 1 if all urls you pass to addLink
|
int relativeToHtmlLink; /* set this to 1 if all urls you pass to addLink
|
||||||
are in fact relative to the html file where your
|
are in fact relative to the html file where your
|
||||||
module was originally */
|
module was originally */
|
||||||
|
|
||||||
/* Callbacks */
|
/* Callbacks */
|
||||||
t_htsAddLink addLink; /* call this function when links are
|
t_htsAddLink addLink; /* call this function when links are
|
||||||
being detected. it if not your responsability to decide
|
being detected. it if not your responsability to
|
||||||
if the engine will keep them, or not. */
|
decide if the engine will keep them, or not. */
|
||||||
|
|
||||||
/* Optional */
|
/* Optional */
|
||||||
char *localLink; /* if non null, the engine will write there the local
|
char *localLink; /* if non null, the engine will write there the local
|
||||||
relative filename of the link added by addLink(), or
|
relative filename of the link added by addLink(), or
|
||||||
the absolute path if the link was refused by the wizard */
|
the absolute path if the link was refused by the wizard */
|
||||||
int localLinkSize; /* size of the optionnal buffer */
|
int localLinkSize; /* size of the optionnal buffer */
|
||||||
|
|
||||||
/* User-defined */
|
/* User-defined */
|
||||||
void *userdef; /* can be used by callback routines
|
void *userdef; /* can be used by callback routines
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* The parser httrackp structure (may be used) */
|
/* The parser httrackp structure (may be used) */
|
||||||
httrackp *opt;
|
httrackp *opt;
|
||||||
@@ -112,28 +117,45 @@ struct htsmoduleStruct {
|
|||||||
int *ptr_;
|
int *ptr_;
|
||||||
const char *page_charset_;
|
const char *page_charset_;
|
||||||
/* Internal use - please don't touch */
|
/* Internal use - please don't touch */
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Used to wrap module initialization */
|
/** Module lifecycle hooks. Init/PlugInit return 1 on success, 0 on failure;
|
||||||
/* return 1 if init was ok */
|
Exit returns its own status (ignored by the engine). */
|
||||||
typedef int (*t_htsWrapperInit) (char *fn, char *args);
|
typedef int (*t_htsWrapperInit)(char *fn, char *args);
|
||||||
typedef int (*t_htsWrapperExit) (void);
|
|
||||||
typedef int (*t_htsWrapperPlugInit) (char *args);
|
typedef int (*t_htsWrapperExit)(void);
|
||||||
|
|
||||||
|
typedef int (*t_htsWrapperPlugInit)(char *args);
|
||||||
|
|
||||||
/* Library internal definictions */
|
/* Library internal definictions */
|
||||||
#ifdef HTS_INTERNAL_BYTECODE
|
#ifdef HTS_INTERNAL_BYTECODE
|
||||||
HTSEXT_API const char *hts_get_version_info(httrackp * opt);
|
|
||||||
HTSEXT_API const char *hts_is_available(void);
|
|
||||||
extern void htspe_init(void);
|
|
||||||
extern void htspe_uninit(void);
|
|
||||||
extern int hts_parse_externals(htsmoduleStruct * str);
|
|
||||||
|
|
||||||
/*extern int swf_is_available;*/
|
/** Capabilities string ("-noV6", "-nossl", ...) followed by "+name" for each
|
||||||
|
loaded module. Returned pointer aliases opt->state.HTbuff; do not free, and
|
||||||
|
it is overwritten by the next call. */
|
||||||
|
HTSEXT_API const char *hts_get_version_info(httrackp *opt);
|
||||||
|
|
||||||
|
/** Static capabilities string set by htspe_init(); valid for the process
|
||||||
|
lifetime, do not free. */
|
||||||
|
HTSEXT_API const char *hts_is_available(void);
|
||||||
|
|
||||||
|
/** Initialize the module subsystem (idempotent): builds the capabilities
|
||||||
|
string and, on Windows, hardens the DLL search path. */
|
||||||
|
extern void htspe_init(void);
|
||||||
|
|
||||||
|
/** Tear-down counterpart of htspe_init(); currently a no-op. */
|
||||||
|
extern void htspe_uninit(void);
|
||||||
|
|
||||||
|
/** Run the external-parser callbacks for the object described by str.
|
||||||
|
Returns the parse callback result (>=0) on a handled object, or -1 if no
|
||||||
|
module claimed it or its wrapper_name is blacklisted. */
|
||||||
|
extern int hts_parse_externals(htsmoduleStruct *str);
|
||||||
|
|
||||||
|
/** Nonzero if IPv6 support was compiled in (== HTS_INET6). */
|
||||||
extern int V6_is_available;
|
extern int V6_is_available;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
175
src/htsname.c
175
src/htsname.c
@@ -138,6 +138,35 @@ static void cleanEndingSpaceOrDot(char *s) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Should the wire Content-Type override the URL's own extension when naming the
|
||||||
|
saved file? True when the type is patchable (may_unknown2) and either the URL
|
||||||
|
extension implies no specific type or the server declared a disagreeing one.
|
||||||
|
A URL extension mapping to a specific non-HTML type is kept only when the
|
||||||
|
server declared NO type (the HTS_UNKNOWN_MIME sentinel; the #267 mangle
|
||||||
|
guard): a typeless .png stays .png, but a .pdf explicitly served as text/html
|
||||||
|
is named .html. The sentinel rides the cache, so updates stay consistent. */
|
||||||
|
static int wire_patches_ext(httrackp *opt, const char *wiremime,
|
||||||
|
const char *file) {
|
||||||
|
char urlmime[256];
|
||||||
|
|
||||||
|
if (may_unknown2(opt, wiremime, file))
|
||||||
|
return 0; /* type kept verbatim (keep-list / bogus-multiple) */
|
||||||
|
urlmime[0] = '\0';
|
||||||
|
/* type implied by the URL extension, only when confidently known (flag 0) */
|
||||||
|
if (!get_httptype_sized(opt, urlmime, sizeof(urlmime), file, 0))
|
||||||
|
return 1; /* URL ext implies no known type: trust the wire type */
|
||||||
|
if (strfield2(wiremime, urlmime))
|
||||||
|
return 0; /* wire agrees with the ext: keep it (no .htm->.html churn) */
|
||||||
|
/* wire disagrees with a specific non-HTML URL ext. Keep the ext only when
|
||||||
|
the server declared no type (the sentinel); an explicitly declared type,
|
||||||
|
even text/html, is trusted, so a binary-looking URL that really serves
|
||||||
|
HTML (login/error interstitial, soft-404) is named .html. */
|
||||||
|
if (!is_hypertext_mime(opt, urlmime, file) &&
|
||||||
|
strfield2(wiremime, HTS_UNKNOWN_MIME))
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
// forme le nom du fichier à sauver (save) à partir de fil et adr
|
// forme le nom du fichier à sauver (save) à partir de fil et adr
|
||||||
// système intelligent, qui renomme en cas de besoin (exemple: deux INDEX.HTML et index.html)
|
// système intelligent, qui renomme en cas de besoin (exemple: deux INDEX.HTML et index.html)
|
||||||
int url_savename(lien_adrfilsave *const afs,
|
int url_savename(lien_adrfilsave *const afs,
|
||||||
@@ -169,6 +198,13 @@ int url_savename(lien_adrfilsave *const afs,
|
|||||||
// copy of fil, used for lookups (see urlhack)
|
// copy of fil, used for lookups (see urlhack)
|
||||||
const char *normadr = adr;
|
const char *normadr = adr;
|
||||||
const char *normfil = fil_complete;
|
const char *normfil = fil_complete;
|
||||||
|
/* query keys to strip for this URL (NULL = none); decoupled from urlhack */
|
||||||
|
char BIGSTK stripkeys[HTS_URLMAXSIZE];
|
||||||
|
const char *const strip =
|
||||||
|
StringNotEmpty(opt->strip_query)
|
||||||
|
? hts_query_strip_keys(StringBuff(opt->strip_query), adr,
|
||||||
|
fil_complete, stripkeys, sizeof(stripkeys))
|
||||||
|
: NULL;
|
||||||
const char *const print_adr = jump_protocol_const(adr);
|
const char *const print_adr = jump_protocol_const(adr);
|
||||||
const char *start_pos = NULL, *nom_pos = NULL, *dot_pos = NULL; // Position nom et point
|
const char *start_pos = NULL, *nom_pos = NULL, *dot_pos = NULL; // Position nom et point
|
||||||
|
|
||||||
@@ -184,10 +220,11 @@ int url_savename(lien_adrfilsave *const afs,
|
|||||||
|
|
||||||
/* 8-3 ? */
|
/* 8-3 ? */
|
||||||
switch (opt->savename_83) {
|
switch (opt->savename_83) {
|
||||||
case 1: // 8-3
|
case HTS_SAVENAME_83_DOS: // 8-3
|
||||||
max_char = 8;
|
max_char = 8;
|
||||||
break;
|
break;
|
||||||
case 2: // Level 2 File names may be up to 31 characters.
|
case HTS_SAVENAME_83_ISO9660: // Level 2 File names may be up to 31
|
||||||
|
// characters.
|
||||||
max_char = 31;
|
max_char = 31;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -200,9 +237,13 @@ int url_savename(lien_adrfilsave *const afs,
|
|||||||
// www-42.foo.com -> foo.com
|
// www-42.foo.com -> foo.com
|
||||||
// foo.com/bar//foobar -> foo.com/bar/foobar
|
// foo.com/bar//foobar -> foo.com/bar/foobar
|
||||||
if (opt->urlhack) {
|
if (opt->urlhack) {
|
||||||
// copy of adr (without protocol), used for lookups (see urlhack)
|
// dedup-lookup key; honor the per-feature negatives like htshash.c so
|
||||||
normadr = adr_normalized_sized(adr, normadr_, sizeof(normadr_));
|
// distinct URLs keep distinct savenames (else keep normadr = adr)
|
||||||
normfil = fil_normalized(fil_complete, normfil_);
|
if (!opt->no_www_dedup)
|
||||||
|
normadr = adr_normalized_sized(adr, normadr_, sizeof(normadr_));
|
||||||
|
normfil =
|
||||||
|
fil_normalized_filtered_ex(fil_complete, normfil_, strip,
|
||||||
|
!opt->no_slash_dedup, !opt->no_query_dedup);
|
||||||
} else {
|
} else {
|
||||||
if (link_has_authority(adr_complete)) { // https or other protocols : in "http/" subfolder
|
if (link_has_authority(adr_complete)) { // https or other protocols : in "http/" subfolder
|
||||||
char *pos = strchr(adr_complete, ':');
|
char *pos = strchr(adr_complete, ':');
|
||||||
@@ -215,6 +256,11 @@ int url_savename(lien_adrfilsave *const afs,
|
|||||||
normadr = normadr_;
|
normadr = normadr_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// strip still applies with urlhack off (host left untouched); no // or
|
||||||
|
// query-sort here, to match the hash key (norm_slash/norm_query are 0 when
|
||||||
|
// urlhack is off) so a URL is looked up under the key it was stored with
|
||||||
|
if (strip != NULL)
|
||||||
|
normfil = fil_normalized_filtered_ex(fil_complete, normfil_, strip, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// à afficher sans ftp://
|
// à afficher sans ftp://
|
||||||
@@ -324,7 +370,10 @@ int url_savename(lien_adrfilsave *const afs,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* replace shtml to html.. */
|
/* replace shtml to html.. */
|
||||||
if (opt->savename_delayed == 2)
|
/* HARD delays every type, except one the user pinned with --assume: honor it
|
||||||
|
immediately (ishtml() consults the user type), no delayed name (#56) */
|
||||||
|
if (opt->savename_delayed == HTS_SAVENAME_DELAYED_HARD &&
|
||||||
|
!is_userknowntype(opt, fil))
|
||||||
is_html = -1; /* ALWAYS delay type */
|
is_html = -1; /* ALWAYS delay type */
|
||||||
else
|
else
|
||||||
is_html = ishtml(opt, fil);
|
is_html = ishtml(opt, fil);
|
||||||
@@ -363,7 +412,9 @@ int url_savename(lien_adrfilsave *const afs,
|
|||||||
) {
|
) {
|
||||||
// tester type avec requète HEAD si on ne connait pas le type du fichier
|
// tester type avec requète HEAD si on ne connait pas le type du fichier
|
||||||
if (!((opt->check_type == 1) && (fil[strlen(fil) - 1] == '/'))) // slash doit être html?
|
if (!((opt->check_type == 1) && (fil[strlen(fil) - 1] == '/'))) // slash doit être html?
|
||||||
if (opt->savename_delayed == 2 || (ishtest = ishtml(opt, fil)) < 0) { // on ne sait pas si c'est un html ou un fichier..
|
if (opt->savename_delayed == HTS_SAVENAME_DELAYED_HARD ||
|
||||||
|
(ishtest = ishtml(opt, fil)) <
|
||||||
|
0) { // unsure whether it's html or a file
|
||||||
// lire dans le cache
|
// lire dans le cache
|
||||||
htsblk r = cache_read_including_broken(opt, cache, adr, fil); // test uniquement
|
htsblk r = cache_read_including_broken(opt, cache, adr, fil); // test uniquement
|
||||||
|
|
||||||
@@ -377,7 +428,7 @@ int url_savename(lien_adrfilsave *const afs,
|
|||||||
if (strnotempty(r.cdispo)) { /* filename given */
|
if (strnotempty(r.cdispo)) { /* filename given */
|
||||||
ext_chg = 2; /* change filename */
|
ext_chg = 2; /* change filename */
|
||||||
strcpybuff(ext, r.cdispo);
|
strcpybuff(ext, r.cdispo);
|
||||||
} else if (!may_unknown2(opt, r.contenttype, fil)) { // on peut patcher à priori?
|
} else if (wire_patches_ext(opt, r.contenttype, fil)) {
|
||||||
if (give_mimext(s, sizeof(s),
|
if (give_mimext(s, sizeof(s),
|
||||||
r.contenttype)) { // recognized extension
|
r.contenttype)) { // recognized extension
|
||||||
ext_chg = 1;
|
ext_chg = 1;
|
||||||
@@ -393,11 +444,12 @@ int url_savename(lien_adrfilsave *const afs,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
//
|
//
|
||||||
} else if (opt->savename_delayed != 2 && is_userknowntype(opt, fil)) { /* PATCH BY BRIAN SCHRÖDER.
|
} else if (opt->savename_delayed != HTS_SAVENAME_DELAYED_HARD &&
|
||||||
Lookup mimetype not only by extension,
|
is_userknowntype(opt, fil)) { /* PATCH BY BRIAN SCHRÖDER.
|
||||||
but also by filename */
|
Lookup mimetype not only by extension,
|
||||||
/* Note: "foo.cgi => text/html" means that foo.cgi shall have the text/html MIME file type,
|
but also by filename */
|
||||||
that is, ".html" */
|
/* Note: "foo.cgi => text/html" means that foo.cgi shall have the
|
||||||
|
text/html MIME file type, that is, ".html" */
|
||||||
char BIGSTK mime[1024];
|
char BIGSTK mime[1024];
|
||||||
|
|
||||||
mime[0] = ext[0] = '\0';
|
mime[0] = ext[0] = '\0';
|
||||||
@@ -408,16 +460,21 @@ int url_savename(lien_adrfilsave *const afs,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// note: if savename_delayed is enabled, the naming will be temporary (and slightly invalid!)
|
// note: if savename_delayed is enabled, the naming will be temporary
|
||||||
// note: if we are about to stop (opt->state.stop), back_add() will fail later
|
// (and slightly invalid!)
|
||||||
else if (opt->savename_delayed != 0 && !opt->state.stop) {
|
//
|
||||||
|
// note: if we are about to stop (opt->state.stop), back_add() will
|
||||||
|
// fail later
|
||||||
|
else if (opt->savename_delayed != HTS_SAVENAME_DELAYED_NONE &&
|
||||||
|
!opt->state.stop) {
|
||||||
// Check if the file is ready in backing. We basically take the same logic as later.
|
// Check if the file is ready in backing. We basically take the same logic as later.
|
||||||
// FIXME: we should cleanup and factorize this unholy mess
|
// FIXME: we should cleanup and factorize this unholy mess
|
||||||
if (headers != NULL && headers->status >= 0 && !is_redirect) {
|
if (headers != NULL && headers->status >= 0 && !is_redirect) {
|
||||||
if (strnotempty(headers->r.cdispo)) { /* filename given */
|
if (strnotempty(headers->r.cdispo)) { /* filename given */
|
||||||
ext_chg = 2; /* change filename */
|
ext_chg = 2; /* change filename */
|
||||||
strcpybuff(ext, headers->r.cdispo);
|
strcpybuff(ext, headers->r.cdispo);
|
||||||
} else if (!may_unknown2(opt, headers->r.contenttype, headers->url_fil)) { // on peut patcher à priori? (pas interdit ou pas de type)
|
} else if (wire_patches_ext(opt, headers->r.contenttype,
|
||||||
|
headers->url_fil)) {
|
||||||
char s[16];
|
char s[16];
|
||||||
if (give_mimext(
|
if (give_mimext(
|
||||||
s, sizeof(s),
|
s, sizeof(s),
|
||||||
@@ -633,7 +690,8 @@ int url_savename(lien_adrfilsave *const afs,
|
|||||||
if (!has_been_moved) {
|
if (!has_been_moved) {
|
||||||
if (back[b].r.statuscode != -10) { // erreur
|
if (back[b].r.statuscode != -10) { // erreur
|
||||||
if (strnotempty(back[b].r.contenttype) == 0)
|
if (strnotempty(back[b].r.contenttype) == 0)
|
||||||
strcpybuff(back[b].r.contenttype, "text/html"); // message d'erreur en html
|
strcpybuff(back[b].r.contenttype,
|
||||||
|
HTS_UNKNOWN_MIME); // no declared type
|
||||||
// Finalement on, renvoie un erreur, pour ne toucher à rien dans le code
|
// Finalement on, renvoie un erreur, pour ne toucher à rien dans le code
|
||||||
// libérer emplacement backing
|
// libérer emplacement backing
|
||||||
}
|
}
|
||||||
@@ -645,7 +703,8 @@ int url_savename(lien_adrfilsave *const afs,
|
|||||||
if (strnotempty(back[b].r.cdispo)) { /* filename given */
|
if (strnotempty(back[b].r.cdispo)) { /* filename given */
|
||||||
ext_chg = 2; /* change filename */
|
ext_chg = 2; /* change filename */
|
||||||
strcpybuff(ext, back[b].r.cdispo);
|
strcpybuff(ext, back[b].r.cdispo);
|
||||||
} else if (!may_unknown2(opt, back[b].r.contenttype, back[b].url_fil)) { // on peut patcher à priori? (pas interdit ou pas de type)
|
} else if (wire_patches_ext(opt, back[b].r.contenttype,
|
||||||
|
back[b].url_fil)) {
|
||||||
if (give_mimext(
|
if (give_mimext(
|
||||||
s, sizeof(s),
|
s, sizeof(s),
|
||||||
back[b].r.contenttype)) { // recognized extension
|
back[b].r.contenttype)) { // recognized extension
|
||||||
@@ -698,7 +757,7 @@ int url_savename(lien_adrfilsave *const afs,
|
|||||||
}
|
}
|
||||||
// restaurer
|
// restaurer
|
||||||
opt->state._hts_in_html_parsing = hihp;
|
opt->state._hts_in_html_parsing = hihp;
|
||||||
} // caché?
|
} // caché?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -717,9 +776,9 @@ int url_savename(lien_adrfilsave *const afs,
|
|||||||
strcatbuff(fil, DEFAULT_HTML); // nommer page par défaut (à priori ici html depuis un proxy http)
|
strcatbuff(fil, DEFAULT_HTML); // nommer page par défaut (à priori ici html depuis un proxy http)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Changer extension?
|
// Change the extension? e.g. php3 saved as html, cgi as html or gif/xbm
|
||||||
// par exemple, php3 sera sauvé en html, cgi en html ou gif, xbm etc.. selon les cas
|
// depending on the resolved type.
|
||||||
if (ext_chg && !opt->no_type_change) { // changer ext
|
if (ext_chg && !opt->no_type_change) {
|
||||||
char *a = fil + strlen(fil) - 1;
|
char *a = fil + strlen(fil) - 1;
|
||||||
|
|
||||||
if ((opt->debug > 1) && (opt->log != NULL)) {
|
if ((opt->debug > 1) && (opt->log != NULL)) {
|
||||||
@@ -731,11 +790,19 @@ int url_savename(lien_adrfilsave *const afs,
|
|||||||
adr_complete, fil_complete, ext);
|
adr_complete, fil_complete, ext);
|
||||||
}
|
}
|
||||||
if (ext_chg == 1) {
|
if (ext_chg == 1) {
|
||||||
|
// Cut the old extension only when it is empty (a bare trailing dot), the
|
||||||
|
// new one, or a recognized one; an unknown trailing ".token" (e.g.
|
||||||
|
// /article-1.884291, #115) is part of the name, not an extension.
|
||||||
|
const char *const old_ext = get_ext(catbuff, sizeof(catbuff), fil);
|
||||||
|
const int known_ext = !*old_ext || strfield2(old_ext, ext) ||
|
||||||
|
is_knowntype(opt, fil) || is_dyntype(old_ext) ||
|
||||||
|
ishtml_ext(old_ext) != -1;
|
||||||
|
|
||||||
while((a > fil) && (*a != '.') && (*a != '/'))
|
while((a > fil) && (*a != '.') && (*a != '/'))
|
||||||
a--;
|
a--;
|
||||||
if (*a == '.')
|
if (*a == '.' && known_ext)
|
||||||
*a = '\0'; // couper
|
*a = '\0'; // cut
|
||||||
strcatbuff(fil, "."); // recopier point
|
strcatbuff(fil, "."); // re-add the dot
|
||||||
} else {
|
} else {
|
||||||
while((a > fil) && (*a != '/'))
|
while((a > fil) && (*a != '/'))
|
||||||
a--;
|
a--;
|
||||||
@@ -743,7 +810,7 @@ int url_savename(lien_adrfilsave *const afs,
|
|||||||
a++;
|
a++;
|
||||||
*a = '\0';
|
*a = '\0';
|
||||||
}
|
}
|
||||||
strcatbuff(fil, ext); // copier ext/nom
|
strcatbuff(fil, ext); // append ext/name
|
||||||
}
|
}
|
||||||
// Rechercher premier / et dernier .
|
// Rechercher premier / et dernier .
|
||||||
{
|
{
|
||||||
@@ -1190,7 +1257,8 @@ int url_savename(lien_adrfilsave *const afs,
|
|||||||
// Not used anymore unless non-delayed types.
|
// Not used anymore unless non-delayed types.
|
||||||
// de même en cas de manque d'extension on en place une de manière forcée..
|
// de même en cas de manque d'extension on en place une de manière forcée..
|
||||||
// cela évite les /chez/toto et les /chez/toto/index.html incompatibles
|
// cela évite les /chez/toto et les /chez/toto/index.html incompatibles
|
||||||
if (opt->savename_type != -1 && opt->savename_delayed != 2) {
|
if (opt->savename_type != -1 &&
|
||||||
|
opt->savename_delayed != HTS_SAVENAME_DELAYED_HARD) {
|
||||||
char *a = afs->save + strlen(afs->save) - 1;
|
char *a = afs->save + strlen(afs->save) - 1;
|
||||||
|
|
||||||
while((a > afs->save) && (*a != '.') && (*a != '/'))
|
while((a > afs->save) && (*a != '.') && (*a != '/'))
|
||||||
@@ -1236,31 +1304,21 @@ int url_savename(lien_adrfilsave *const afs,
|
|||||||
size_t i;
|
size_t i;
|
||||||
for(i = 0 ; afs->save[i] != '\0' ; i++) {
|
for(i = 0 ; afs->save[i] != '\0' ; i++) {
|
||||||
unsigned char c = (unsigned char) afs->save[i];
|
unsigned char c = (unsigned char) afs->save[i];
|
||||||
if (c < 32 // control
|
if (c < 32 // control
|
||||||
|| c == 127 // unwise
|
|| c == 127 // unwise
|
||||||
|| c == '~' // unix unwise
|
|| c == '~' // unix unwise
|
||||||
|| c == '\\' // windows separator
|
|| c == '\\' // windows separator
|
||||||
|| c == ':' // windows forbidden
|
|| c == ':' // windows forbidden
|
||||||
|| c == '*' // windows forbidden
|
|| c == '*' // windows forbidden
|
||||||
|| c == '?' // windows forbidden
|
|| c == '?' // windows forbidden
|
||||||
|| c == '\"' // windows forbidden
|
|| c == '\"' // windows forbidden
|
||||||
|| c == '<' // windows forbidden
|
|| c == '<' // windows forbidden
|
||||||
|| c == '>' // windows forbidden
|
|| c == '>' // windows forbidden
|
||||||
|| c == '|' // windows forbidden
|
|| c == '|' // windows forbidden
|
||||||
//|| c == '@' // ?
|
//|| c == '@' // ?
|
||||||
||
|
|| (opt->savename_83 == HTS_SAVENAME_83_ISO9660 // CDROM
|
||||||
(
|
&& (c == '-' || c == '=' || c == '+'))) {
|
||||||
opt->savename_83 == 2 // CDROM
|
afs->save[i] = '_';
|
||||||
&&
|
|
||||||
(
|
|
||||||
c == '-'
|
|
||||||
|| c == '='
|
|
||||||
|| c == '+'
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
afs->save[i] = '_';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1521,7 +1579,8 @@ int url_savename(lien_adrfilsave *const afs,
|
|||||||
char *a = afs->save + strlen(afs->save) - 1;
|
char *a = afs->save + strlen(afs->save) - 1;
|
||||||
char *b;
|
char *b;
|
||||||
int n = 2;
|
int n = 2;
|
||||||
char collisionSeparator = ((opt->savename_83 != 2) ? '-' : '_');
|
char collisionSeparator =
|
||||||
|
((opt->savename_83 != HTS_SAVENAME_83_ISO9660) ? '-' : '_');
|
||||||
|
|
||||||
tempo[0] = '\0';
|
tempo[0] = '\0';
|
||||||
|
|
||||||
@@ -1686,10 +1745,10 @@ char *url_savename_refname_fullpath(httrackp * opt, const char *adr,
|
|||||||
StringBuff(opt->path_log), digest_filename);
|
StringBuff(opt->path_log), digest_filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* remove refname if any */
|
/* remove refname if any; HTS_TRUE if it was removed */
|
||||||
void url_savename_refname_remove(httrackp * opt, const char *adr,
|
hts_boolean url_savename_refname_remove(httrackp *opt, const char *adr,
|
||||||
const char *fil) {
|
const char *fil) {
|
||||||
char *filename = url_savename_refname_fullpath(opt, adr, fil);
|
char *filename = url_savename_refname_fullpath(opt, adr, fil);
|
||||||
|
|
||||||
(void) UNLINK(filename);
|
return UNLINK(filename) == 0 ? HTS_TRUE : HTS_FALSE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,8 +104,9 @@ char *url_md5(char *digest_buffer, const char *fil_complete);
|
|||||||
void url_savename_refname(const char *adr, const char *fil, char *filename);
|
void url_savename_refname(const char *adr, const char *fil, char *filename);
|
||||||
char *url_savename_refname_fullpath(httrackp * opt, const char *adr,
|
char *url_savename_refname_fullpath(httrackp * opt, const char *adr,
|
||||||
const char *fil);
|
const char *fil);
|
||||||
void url_savename_refname_remove(httrackp * opt, const char *adr,
|
/* Remove the temp-ref for (adr,fil); HTS_TRUE if it was removed. */
|
||||||
const char *fil);
|
hts_boolean url_savename_refname_remove(httrackp *opt, const char *adr,
|
||||||
|
const char *fil);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
191
src/htsnet.h
191
src/htsnet.h
@@ -32,6 +32,11 @@ Please visit our Website: http://www.httrack.com
|
|||||||
/* Author: Xavier Roche */
|
/* Author: Xavier Roche */
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
|
||||||
|
/** @file htsnet.h
|
||||||
|
Socket/connection layer. Provides SOCaddr, an opaque IPv4/IPv6
|
||||||
|
socket-address wrapper, plus accessor macros so callers never branch on
|
||||||
|
address family. Builds on htsbasenet.h. */
|
||||||
|
|
||||||
#ifndef HTS_DEFNETH
|
#ifndef HTS_DEFNETH
|
||||||
#define HTS_DEFNETH
|
#define HTS_DEFNETH
|
||||||
|
|
||||||
@@ -43,32 +48,32 @@ Please visit our Website: http://www.httrack.com
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
// pour read
|
// for read
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
// pour FindFirstFile
|
// for FindFirstFile
|
||||||
#include <winbase.h>
|
#include <winbase.h>
|
||||||
typedef USHORT in_port_t;
|
typedef USHORT in_port_t;
|
||||||
|
|
||||||
typedef ADDRESS_FAMILY sa_family_t;
|
typedef ADDRESS_FAMILY sa_family_t;
|
||||||
#else
|
#else
|
||||||
//typedef int T_SOC;
|
|
||||||
#define INVALID_SOCKET -1
|
#define INVALID_SOCKET -1
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
/* Force for sun env. */
|
/* Force BSD_COMP for Sun environments. */
|
||||||
#ifndef BSD_COMP
|
#ifndef BSD_COMP
|
||||||
#define BSD_COMP
|
#define BSD_COMP
|
||||||
#endif
|
#endif
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
/* gethostname & co */
|
/* gethostname & co */
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
/* inet_addr */
|
/* inet_addr */
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
// pas la peine normalement..
|
/* normally not needed; provide in_addr_t where the platform lacks it */
|
||||||
#ifndef HTS_DO_NOT_REDEFINE_in_addr_t
|
#ifndef HTS_DO_NOT_REDEFINE_in_addr_t
|
||||||
typedef unsigned long in_addr_t;
|
typedef unsigned long in_addr_t;
|
||||||
#endif
|
#endif
|
||||||
@@ -78,14 +83,16 @@ typedef unsigned long in_addr_t;
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Ipv4 structures */
|
/** Raw IP address type: in6_addr when IPv6 is enabled, else in_addr. */
|
||||||
#if HTS_INET6 != 0
|
#if HTS_INET6 != 0
|
||||||
typedef struct in6_addr INaddr;
|
typedef struct in6_addr INaddr;
|
||||||
#else
|
#else
|
||||||
typedef struct in_addr INaddr;
|
typedef struct in_addr INaddr;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* This should handle all cases */
|
/** Opaque socket address holding either an IPv4 or IPv6 endpoint. Use the
|
||||||
|
SOCaddr_* accessors rather than touching m_addr; sa_family selects the
|
||||||
|
active union member. */
|
||||||
#ifndef HTS_DEF_FWSTRUCT_SOCaddr
|
#ifndef HTS_DEF_FWSTRUCT_SOCaddr
|
||||||
#define HTS_DEF_FWSTRUCT_SOCaddr
|
#define HTS_DEF_FWSTRUCT_SOCaddr
|
||||||
typedef struct SOCaddr SOCaddr;
|
typedef struct SOCaddr SOCaddr;
|
||||||
@@ -103,10 +110,12 @@ struct SOCaddr {
|
|||||||
} m_addr;
|
} m_addr;
|
||||||
};
|
};
|
||||||
|
|
||||||
static HTS_INLINE HTS_UNUSED in_port_t* SOCaddr_sinport_(SOCaddr *const addr,
|
/** Pointer to the port field (network byte order) for the active family.
|
||||||
const char *file, const int line) {
|
Asserts on NULL or an unset/unknown family. */
|
||||||
|
static HTS_INLINE HTS_UNUSED in_port_t *
|
||||||
|
SOCaddr_sinport_(SOCaddr *const addr, const char *file, const int line) {
|
||||||
assertf_(addr != NULL, file, line);
|
assertf_(addr != NULL, file, line);
|
||||||
switch(addr->m_addr.sa.sa_family) {
|
switch (addr->m_addr.sa.sa_family) {
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
return &addr->m_addr.in.sin_port;
|
return &addr->m_addr.in.sin_port;
|
||||||
break;
|
break;
|
||||||
@@ -116,16 +125,19 @@ static HTS_INLINE HTS_UNUSED in_port_t* SOCaddr_sinport_(SOCaddr *const addr,
|
|||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
assertf_(! "invalid structure", file, line);
|
assertf_(!"invalid structure", file, line);
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static HTS_INLINE HTS_UNUSED socklen_t SOCaddr_size_(const SOCaddr*const addr,
|
/** Length of the active sockaddr (sockaddr_in or sockaddr_in6), or 0 if the
|
||||||
const char *file, const int line) {
|
family is unset/unknown. The 0 case doubles as the "not valid" test. */
|
||||||
|
static HTS_INLINE HTS_UNUSED socklen_t SOCaddr_size_(const SOCaddr *const addr,
|
||||||
|
const char *file,
|
||||||
|
const int line) {
|
||||||
assertf_(addr != NULL, file, line);
|
assertf_(addr != NULL, file, line);
|
||||||
switch(addr->m_addr.sa.sa_family) {
|
switch (addr->m_addr.sa.sa_family) {
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
return sizeof(addr->m_addr.in);
|
return sizeof(addr->m_addr.in);
|
||||||
break;
|
break;
|
||||||
@@ -140,51 +152,77 @@ static HTS_INLINE HTS_UNUSED socklen_t SOCaddr_size_(const SOCaddr*const addr,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static HTS_INLINE HTS_UNUSED void SOCaddr_clear_(SOCaddr*const addr,
|
/** Reset to the unset state (family AF_UNSPEC), making the address invalid. */
|
||||||
const char *file, const int line) {
|
static HTS_INLINE HTS_UNUSED void
|
||||||
|
SOCaddr_clear_(SOCaddr *const addr, const char *file, const int line) {
|
||||||
assertf_(addr != NULL, file, line);
|
assertf_(addr != NULL, file, line);
|
||||||
addr->m_addr.sa.sa_family = AF_UNSPEC;
|
addr->m_addr.sa.sa_family = AF_UNSPEC;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ipv4/6 structure members */
|
/* SOCaddr accessors; server is an lvalue SOCaddr, not a pointer. */
|
||||||
#define SOCaddr_sinfamily(server) ((server).m_addr.sa.sa_family)
|
#define SOCaddr_sinfamily(server) \
|
||||||
#define SOCaddr_sinport(server) (*SOCaddr_sinport_(&(server), __FILE__, __LINE__))
|
((server).m_addr.sa.sa_family) /* AF_INET / AF_INET6 */
|
||||||
#define SOCaddr_size(server) (SOCaddr_size_(&(server), __FILE__, __LINE__))
|
|
||||||
#define SOCaddr_is_valid(server) (SOCaddr_size_(&(server), __FILE__, __LINE__) != 0 )
|
|
||||||
#define SOCaddr_clear(server) SOCaddr_clear_(&(server), __FILE__, __LINE__)
|
|
||||||
#define SOCaddr_sockaddr(server) ((server).m_addr.sa)
|
|
||||||
#define SOCaddr_capacity(server) sizeof((server).m_addr)
|
|
||||||
|
|
||||||
/* AF_xx */
|
#define SOCaddr_sinport(server) \
|
||||||
|
(*SOCaddr_sinport_(&(server), __FILE__, \
|
||||||
|
__LINE__)) /* port lvalue (network order) */
|
||||||
|
|
||||||
|
#define SOCaddr_size(server) \
|
||||||
|
(SOCaddr_size_(&(server), __FILE__, __LINE__)) /* active sockaddr length */
|
||||||
|
|
||||||
|
#define SOCaddr_is_valid(server) \
|
||||||
|
(SOCaddr_size_(&(server), __FILE__, __LINE__) != \
|
||||||
|
0) /* nonzero if family is set */
|
||||||
|
|
||||||
|
#define SOCaddr_clear(server) SOCaddr_clear_(&(server), __FILE__, __LINE__)
|
||||||
|
|
||||||
|
#define SOCaddr_sockaddr(server) \
|
||||||
|
((server).m_addr.sa) /* generic struct sockaddr view */
|
||||||
|
|
||||||
|
#define SOCaddr_capacity(server) \
|
||||||
|
sizeof((server).m_addr) /* full union size, for recvfrom() etc. */
|
||||||
|
|
||||||
|
/** Address family to bind/listen with: AF_INET6 when IPv6 is enabled (dual
|
||||||
|
stack), else AF_INET. */
|
||||||
#if HTS_INET6 != 0
|
#if HTS_INET6 != 0
|
||||||
#define AFinet AF_INET6
|
#define AFinet AF_INET6
|
||||||
#else
|
#else
|
||||||
#define AFinet AF_INET
|
#define AFinet AF_INET
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Set port to sockaddr structure */
|
/** Set the port (host-order argument, stored network-order) on the active
|
||||||
#define SOCaddr_initport(server, port) do { \
|
* family. */
|
||||||
SOCaddr_sinport(server) = htons((in_port_t) (port)); \
|
#define SOCaddr_initport(server, port) \
|
||||||
} while(0)
|
do { \
|
||||||
|
SOCaddr_sinport(server) = htons((in_port_t) (port)); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
static HTS_INLINE HTS_UNUSED socklen_t SOCaddr_initany_(SOCaddr*const addr,
|
/** Initialize as an all-zero IPv4 wildcard (INADDR_ANY) address; returns its
|
||||||
const char *file, const int line) {
|
sockaddr length. */
|
||||||
|
static HTS_INLINE HTS_UNUSED socklen_t SOCaddr_initany_(SOCaddr *const addr,
|
||||||
|
const char *file,
|
||||||
|
const int line) {
|
||||||
assertf_(addr != NULL, file, line);
|
assertf_(addr != NULL, file, line);
|
||||||
memset(&addr->m_addr.in, 0, sizeof(addr->m_addr.in));
|
memset(&addr->m_addr.in, 0, sizeof(addr->m_addr.in));
|
||||||
addr->m_addr.in.sin_family = AF_INET;
|
addr->m_addr.in.sin_family = AF_INET;
|
||||||
return SOCaddr_size_(addr, file, line);
|
return SOCaddr_size_(addr, file, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SOCaddr_initany(server) do { \
|
/** Initialize server as an IPv4 wildcard (INADDR_ANY) address. */
|
||||||
SOCaddr_initany_(&(server), __FILE__, __LINE__); \
|
#define SOCaddr_initany(server) \
|
||||||
} while(0)
|
do { \
|
||||||
|
SOCaddr_initany_(&(server), __FILE__, __LINE__); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
/*
|
/** Populate server from data. data_size selects the source form: a full
|
||||||
Copy sockaddr_in/sockaddr_in6/raw IPv4/raw IPv6 to our opaque SOCaddr
|
sockaddr_in / sockaddr_in6, or a raw 4-byte (IPv4) / 16-byte (IPv6) address
|
||||||
*/
|
with port zeroed. Any other size leaves an AF_INET shell. Returns the
|
||||||
static HTS_UNUSED socklen_t SOCaddr_copyaddr_(SOCaddr*const server,
|
resulting sockaddr length. */
|
||||||
const void *data, const size_t data_size,
|
static HTS_UNUSED socklen_t SOCaddr_copyaddr_(SOCaddr *const server,
|
||||||
const char *file, const int line) {
|
const void *data,
|
||||||
|
const size_t data_size,
|
||||||
|
const char *file,
|
||||||
|
const int line) {
|
||||||
assertf_(server != NULL, file, line);
|
assertf_(server != NULL, file, line);
|
||||||
assertf_(data != NULL, file, line);
|
assertf_(data != NULL, file, line);
|
||||||
|
|
||||||
@@ -214,30 +252,37 @@ static HTS_UNUSED socklen_t SOCaddr_copyaddr_(SOCaddr*const server,
|
|||||||
return SOCaddr_size_(server, file, line);
|
return SOCaddr_size_(server, file, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SOCaddr_copyaddr(server, server_len, hpaddr, hpsize) do { \
|
/** Copy hpaddr (length hpsize) into server, writing the result length into the
|
||||||
server_len = (int) SOCaddr_copyaddr_(&(server), hpaddr, hpsize, __FILE__, __LINE__); \
|
lvalue server_len (int). See SOCaddr_copyaddr_ for accepted forms. */
|
||||||
} while(0)
|
#define SOCaddr_copyaddr(server, server_len, hpaddr, hpsize) \
|
||||||
|
do { \
|
||||||
|
server_len = (int) SOCaddr_copyaddr_(&(server), hpaddr, hpsize, __FILE__, \
|
||||||
|
__LINE__); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#define SOCaddr_copyaddr2(server, hpaddr, hpsize) do { \
|
/** Like SOCaddr_copyaddr but discards the result length. */
|
||||||
(void) SOCaddr_copyaddr_(&(server), hpaddr, hpsize, __FILE__, __LINE__); \
|
#define SOCaddr_copyaddr2(server, hpaddr, hpsize) \
|
||||||
} while(0)
|
do { \
|
||||||
|
(void) SOCaddr_copyaddr_(&(server), hpaddr, hpsize, __FILE__, __LINE__); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#define SOCaddr_copy_SOCaddr(dest, src) do { \
|
/** Copy one SOCaddr (src) into another (dest), preserving family and port. */
|
||||||
SOCaddr_copyaddr_(&(dest), &(src).m_addr.sa, SOCaddr_size(src), __FILE__, __LINE__); \
|
#define SOCaddr_copy_SOCaddr(dest, src) \
|
||||||
} while(0)
|
do { \
|
||||||
|
SOCaddr_copyaddr_(&(dest), &(src).m_addr.sa, SOCaddr_size(src), __FILE__, \
|
||||||
|
__LINE__); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
/* Get dotted address */
|
/** Write the numeric (dotted/colon) host of ss into namebuf (capacity
|
||||||
|
namebuflen), scope id stripped. On failure namebuf becomes "". */
|
||||||
static HTS_UNUSED void SOCaddr_inetntoa_(char *namebuf, size_t namebuflen,
|
static HTS_UNUSED void SOCaddr_inetntoa_(char *namebuf, size_t namebuflen,
|
||||||
SOCaddr *const ss,
|
SOCaddr *const ss, const char *file,
|
||||||
const char *file, const int line) {
|
const int line) {
|
||||||
assertf_(namebuf != NULL, file, line);
|
assertf_(namebuf != NULL, file, line);
|
||||||
assertf_(ss != NULL, file, line);
|
assertf_(ss != NULL, file, line);
|
||||||
|
|
||||||
if (getnameinfo(&ss->m_addr.sa, sizeof(ss->m_addr),
|
if (getnameinfo(&ss->m_addr.sa, sizeof(ss->m_addr), namebuf, namebuflen, NULL,
|
||||||
namebuf, namebuflen,
|
0, NI_NUMERICHOST) == 0) {
|
||||||
NULL, 0,
|
|
||||||
NI_NUMERICHOST) == 0) {
|
|
||||||
/* remove scope id(s) */
|
/* remove scope id(s) */
|
||||||
char *const pos = strchr(namebuf, '%');
|
char *const pos = strchr(namebuf, '%');
|
||||||
if (pos != NULL) {
|
if (pos != NULL) {
|
||||||
@@ -248,15 +293,33 @@ static HTS_UNUSED void SOCaddr_inetntoa_(char *namebuf, size_t namebuflen,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SOCaddr_inetntoa(namebuf, namebuflen, ss) \
|
/** Numeric host of ss into namebuf (capacity namebuflen); "" on failure. */
|
||||||
|
#define SOCaddr_inetntoa(namebuf, namebuflen, ss) \
|
||||||
SOCaddr_inetntoa_(namebuf, namebuflen, &(ss), __FILE__, __LINE__)
|
SOCaddr_inetntoa_(namebuf, namebuflen, &(ss), __FILE__, __LINE__)
|
||||||
|
|
||||||
/* Get protocol ID */
|
/** Single-char family tag: '1' for IPv4, '2' otherwise (used in the cache). */
|
||||||
#define SOCaddr_getproto(ss) ( SOCaddr_size(ss) == sizeof(struct sockaddr_in) ? '1' : '2')
|
#define SOCaddr_getproto(ss) \
|
||||||
|
(SOCaddr_size(ss) == sizeof(struct sockaddr_in) ? '1' : '2')
|
||||||
|
|
||||||
/* Socket length type */
|
/** Length type for socket APIs (getsockname, accept, ...). */
|
||||||
typedef socklen_t SOClen;
|
typedef socklen_t SOClen;
|
||||||
|
|
||||||
|
#if HTS_INET6 != 0
|
||||||
|
/** Resolver backend: getaddrinfo/freeaddrinfo as a swappable pair, so the
|
||||||
|
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. */
|
||||||
|
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);
|
||||||
|
} hts_resolver_backend;
|
||||||
|
|
||||||
|
/** Install a resolver backend for the process; NULL restores the libc default.
|
||||||
|
Test-only seam, not thread-safe; callers must serialize against resolves. */
|
||||||
|
void hts_dns_set_resolver_backend(const hts_resolver_backend *backend);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
697
src/htsopt.h
697
src/htsopt.h
@@ -72,6 +72,7 @@ typedef struct String String;
|
|||||||
#endif
|
#endif
|
||||||
#ifndef HTS_DEF_STRUCT_String
|
#ifndef HTS_DEF_STRUCT_String
|
||||||
#define HTS_DEF_STRUCT_String
|
#define HTS_DEF_STRUCT_String
|
||||||
|
|
||||||
struct String {
|
struct String {
|
||||||
char *buffer_;
|
char *buffer_;
|
||||||
size_t length_;
|
size_t length_;
|
||||||
@@ -80,39 +81,42 @@ struct String {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Defines */
|
/* Defines */
|
||||||
#define CATBUFF_SIZE (STRING_SIZE*2*2)
|
#define CATBUFF_SIZE (STRING_SIZE * 2 * 2)
|
||||||
|
|
||||||
#define STRING_SIZE 2048
|
#define STRING_SIZE 2048
|
||||||
|
|
||||||
/* Proxy structure */
|
/* Proxy configuration. */
|
||||||
#ifndef HTS_DEF_FWSTRUCT_t_proxy
|
#ifndef HTS_DEF_FWSTRUCT_t_proxy
|
||||||
#define HTS_DEF_FWSTRUCT_t_proxy
|
#define HTS_DEF_FWSTRUCT_t_proxy
|
||||||
typedef struct t_proxy t_proxy;
|
typedef struct t_proxy t_proxy;
|
||||||
#endif
|
#endif
|
||||||
struct t_proxy {
|
struct t_proxy {
|
||||||
int active;
|
int active; /**< nonzero if a proxy is configured */
|
||||||
String name;
|
String name; /**< proxy host name */
|
||||||
int port;
|
int port; /**< proxy port */
|
||||||
String bindhost; // bind this host
|
String bindhost; /**< local address to bind the outgoing socket to */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Structure utile pour copier en bloc les paramètres */
|
/* Bundle of filter pointers, kept together for bulk copy. */
|
||||||
#ifndef HTS_DEF_FWSTRUCT_htsfilters
|
#ifndef HTS_DEF_FWSTRUCT_htsfilters
|
||||||
#define HTS_DEF_FWSTRUCT_htsfilters
|
#define HTS_DEF_FWSTRUCT_htsfilters
|
||||||
typedef struct htsfilters htsfilters;
|
typedef struct htsfilters htsfilters;
|
||||||
#endif
|
#endif
|
||||||
struct htsfilters {
|
struct htsfilters {
|
||||||
char ***filters;
|
char ***filters; /**< pointer to the +/-pattern filter array */
|
||||||
int *filptr;
|
int *filptr; /**< pointer to the current filter count */
|
||||||
//int* filter_max;
|
// int* filter_max;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* User callbacks chain */
|
/* User callbacks chain */
|
||||||
typedef int (*htscallbacksfncptr) (void);
|
typedef int (*htscallbacksfncptr)(void);
|
||||||
|
|
||||||
typedef struct htscallbacks htscallbacks;
|
typedef struct htscallbacks htscallbacks;
|
||||||
|
|
||||||
struct htscallbacks {
|
struct htscallbacks {
|
||||||
void *moduleHandle;
|
void *moduleHandle; /**< handle of the module that registered the callback */
|
||||||
htscallbacksfncptr exitFnc;
|
htscallbacksfncptr exitFnc; /**< function to run on engine exit */
|
||||||
htscallbacks *next;
|
htscallbacks *next; /**< next entry in the callback chain */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* filenote() internal file structure */
|
/* filenote() internal file structure */
|
||||||
@@ -176,6 +180,7 @@ typedef struct lien_url lien_url;
|
|||||||
|
|
||||||
#ifndef HTS_DEF_DEFSTRUCT_hts_log_type
|
#ifndef HTS_DEF_DEFSTRUCT_hts_log_type
|
||||||
#define HTS_DEF_DEFSTRUCT_hts_log_type
|
#define HTS_DEF_DEFSTRUCT_hts_log_type
|
||||||
|
|
||||||
typedef enum hts_log_type {
|
typedef enum hts_log_type {
|
||||||
LOG_PANIC,
|
LOG_PANIC,
|
||||||
LOG_ERROR,
|
LOG_ERROR,
|
||||||
@@ -188,14 +193,14 @@ typedef enum hts_log_type {
|
|||||||
} hts_log_type;
|
} hts_log_type;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Structure état du miroir */
|
/* Mirror cancellation list node. */
|
||||||
#ifndef HTS_DEF_FWSTRUCT_htsoptstatecancel
|
#ifndef HTS_DEF_FWSTRUCT_htsoptstatecancel
|
||||||
#define HTS_DEF_FWSTRUCT_htsoptstatecancel
|
#define HTS_DEF_FWSTRUCT_htsoptstatecancel
|
||||||
typedef struct htsoptstatecancel htsoptstatecancel;
|
typedef struct htsoptstatecancel htsoptstatecancel;
|
||||||
#endif
|
#endif
|
||||||
struct htsoptstatecancel {
|
struct htsoptstatecancel {
|
||||||
char *url;
|
char *url; /**< URL flagged to be cancelled */
|
||||||
htsoptstatecancel *next;
|
htsoptstatecancel *next; /**< next cancellation entry */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Mutexes */
|
/* Mutexes */
|
||||||
@@ -210,48 +215,48 @@ typedef struct htsmutex_s htsmutex_s, *htsmutex;
|
|||||||
typedef struct struct_coucal struct_coucal, *coucal;
|
typedef struct struct_coucal struct_coucal, *coucal;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Structure état du miroir */
|
/* Mirror runtime state (mutable engine state, not user options). */
|
||||||
#ifndef HTS_DEF_FWSTRUCT_htsoptstate
|
#ifndef HTS_DEF_FWSTRUCT_htsoptstate
|
||||||
#define HTS_DEF_FWSTRUCT_htsoptstate
|
#define HTS_DEF_FWSTRUCT_htsoptstate
|
||||||
typedef struct htsoptstate htsoptstate;
|
typedef struct htsoptstate htsoptstate;
|
||||||
#endif
|
#endif
|
||||||
struct htsoptstate {
|
struct htsoptstate {
|
||||||
htsmutex lock; /* 3.41 */
|
htsmutex lock; /**< guards this state block */
|
||||||
/* */
|
/* */
|
||||||
int stop;
|
int stop; /**< set to request the mirror to stop */
|
||||||
int exit_xh;
|
int exit_xh;
|
||||||
int back_add_stats;
|
int back_add_stats;
|
||||||
/* */
|
/* */
|
||||||
int mimehtml_created;
|
int mimehtml_created; /**< MIME/MHTML output already started */
|
||||||
String mimemid;
|
String mimemid; /**< MIME multipart boundary id */
|
||||||
FILE *mimefp;
|
FILE *mimefp; /**< MIME/MHTML output file */
|
||||||
int delayedId;
|
int delayedId; /**< counter for delayed-type-check ids */
|
||||||
/* */
|
/* */
|
||||||
filenote_strc strc;
|
filenote_strc strc; /**< filenote() listing state */
|
||||||
/* Functions context (avoir thread variables!) */
|
/* Per-call function contexts (thread-local scratch, avoids globals) */
|
||||||
htscallbacks callbacks;
|
htscallbacks callbacks; /**< user callback chain head */
|
||||||
concat_strc concat;
|
concat_strc concat; /**< concat() rotating buffers */
|
||||||
usercommand_strc usercmd;
|
usercommand_strc usercmd; /**< pending user shell command */
|
||||||
fspc_strc fspc;
|
fspc_strc fspc; /**< error/warning/info counters */
|
||||||
char *userhttptype;
|
char *userhttptype;
|
||||||
int verif_backblue_done;
|
int verif_backblue_done; /**< backblue.gif/fade.gif already emitted */
|
||||||
int verif_external_status;
|
int verif_external_status;
|
||||||
t_dnscache *dns_cache;
|
coucal dns_cache; /**< DNS resolution cache: hostname -> t_dnscache record */
|
||||||
int dns_cache_nthreads;
|
int dns_cache_nthreads; /**< number of in-flight DNS resolver threads */
|
||||||
/* HTML parsing state */
|
/* HTML parsing state */
|
||||||
char _hts_errmsg[HTS_CDLMAXSIZE + 256];
|
char _hts_errmsg[HTS_CDLMAXSIZE + 256]; /**< last engine error message */
|
||||||
int _hts_in_html_parsing;
|
int _hts_in_html_parsing;
|
||||||
int _hts_in_html_done;
|
int _hts_in_html_done;
|
||||||
int _hts_in_html_poll;
|
int _hts_in_html_poll;
|
||||||
int _hts_setpause;
|
int _hts_setpause;
|
||||||
int _hts_in_mirror;
|
int _hts_in_mirror; /**< nonzero while a mirror is running */
|
||||||
char **_hts_addurl;
|
char **_hts_addurl; /**< extra URLs to inject at runtime */
|
||||||
int _hts_cancel;
|
int _hts_cancel;
|
||||||
htsoptstatecancel *cancel; /* 3.41 */
|
htsoptstatecancel *cancel; /**< list of URLs flagged for cancellation */
|
||||||
char HTbuff[2048];
|
char HTbuff[2048];
|
||||||
unsigned int debug_state;
|
unsigned int debug_state;
|
||||||
unsigned int tmpnameid; /* 3.41 */
|
unsigned int tmpnameid; /**< counter for temporary file names */
|
||||||
int is_ended; /* 3.48-14 */
|
int is_ended; /**< mirror has finished */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Library handles */
|
/* Library handles */
|
||||||
@@ -264,198 +269,327 @@ typedef struct htslibhandles htslibhandles;
|
|||||||
typedef struct htslibhandle htslibhandle;
|
typedef struct htslibhandle htslibhandle;
|
||||||
#endif
|
#endif
|
||||||
struct htslibhandle {
|
struct htslibhandle {
|
||||||
char *moduleName;
|
char *moduleName; /**< name of a loaded external module */
|
||||||
void *handle;
|
void *handle; /**< dlopen() handle for it */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct htslibhandles {
|
struct htslibhandles {
|
||||||
int count;
|
int count; /**< number of loaded module handles */
|
||||||
htslibhandle *handles;
|
htslibhandle *handles; /**< array of loaded module handles */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Javascript parser flags */
|
/* Javascript parser flags */
|
||||||
typedef enum htsparsejava_flags {
|
typedef enum htsparsejava_flags {
|
||||||
HTSPARSE_NONE = 0, // don't parse
|
HTSPARSE_NONE = 0, // don't parse
|
||||||
HTSPARSE_DEFAULT = 1, // parse default (all)
|
HTSPARSE_DEFAULT = 1, // parse default (all)
|
||||||
HTSPARSE_NO_CLASS = 2, // don't parse .java
|
HTSPARSE_NO_CLASS = 2, // don't parse .java
|
||||||
HTSPARSE_NO_JAVASCRIPT = 4, // don't parse .js
|
HTSPARSE_NO_JAVASCRIPT = 4, // don't parse .js
|
||||||
HTSPARSE_NO_AGGRESSIVE = 8 // don't aggressively parse .js or .java
|
HTSPARSE_NO_AGGRESSIVE = 8 // don't aggressively parse .js or .java
|
||||||
} htsparsejava_flags;
|
} htsparsejava_flags;
|
||||||
|
|
||||||
|
/* Link-rewriting style for saved pages (opt->urlmode). */
|
||||||
|
#ifndef HTS_DEF_DEFSTRUCT_hts_urlmode
|
||||||
|
#define HTS_DEF_DEFSTRUCT_hts_urlmode
|
||||||
|
|
||||||
|
typedef enum hts_urlmode {
|
||||||
|
HTS_URLMODE_ABSOLUTE = 0, /**< absolute URL (http://host/path) everywhere */
|
||||||
|
HTS_URLMODE_ABSOLUTE_FILE = 1, /**< legacy file: form, unused */
|
||||||
|
HTS_URLMODE_RELATIVE = 2, /**< relative link (default) */
|
||||||
|
HTS_URLMODE_ABSOLUTE_URI = 3, /**< absolute URI from root (/path) */
|
||||||
|
HTS_URLMODE_KEEP_ORIGINAL = 4, /**< keep the original link, do not rewrite */
|
||||||
|
HTS_URLMODE_TRANSPARENT_PROXY = 5 /**< transparent-proxy URL */
|
||||||
|
} hts_urlmode;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Cache policy for updates and retries (opt->cache). */
|
||||||
|
#ifndef HTS_DEF_DEFSTRUCT_hts_cachemode
|
||||||
|
#define HTS_DEF_DEFSTRUCT_hts_cachemode
|
||||||
|
|
||||||
|
typedef enum hts_cachemode {
|
||||||
|
HTS_CACHE_NONE = 0, /**< no cache */
|
||||||
|
HTS_CACHE_PRIORITY = 1, /**< cache takes priority over the network */
|
||||||
|
HTS_CACHE_TEST_UPDATE = 2 /**< check for update before reuse (default) */
|
||||||
|
} hts_cachemode;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Interactive wizard level (opt->wizard). */
|
||||||
|
#ifndef HTS_DEF_DEFSTRUCT_hts_wizard
|
||||||
|
#define HTS_DEF_DEFSTRUCT_hts_wizard
|
||||||
|
|
||||||
|
typedef enum hts_wizard {
|
||||||
|
HTS_WIZARD_NONE = 0, /**< no wizard */
|
||||||
|
HTS_WIZARD_ASK = 1, /**< wizard asks questions */
|
||||||
|
HTS_WIZARD_AUTO = 2 /**< wizard runs without asking */
|
||||||
|
} hts_wizard;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* robots.txt / meta-robots obedience level (opt->robots). */
|
||||||
|
#ifndef HTS_DEF_DEFSTRUCT_hts_robots
|
||||||
|
#define HTS_DEF_DEFSTRUCT_hts_robots
|
||||||
|
|
||||||
|
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_ALWAYS_STRICT = 3 /**< obey even strict rules */
|
||||||
|
} hts_robots;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* What to fetch (opt->getmode bitmask). */
|
||||||
|
typedef enum hts_getmode {
|
||||||
|
HTS_GETMODE_HTML = 1 << 0, /**< save HTML files */
|
||||||
|
HTS_GETMODE_NONHTML = 1 << 1, /**< save non-HTML files */
|
||||||
|
HTS_GETMODE_HTML_FIRST = 1 << 2 /**< fetch HTML first, then the other files */
|
||||||
|
} hts_getmode;
|
||||||
|
|
||||||
|
/* Allowed directions in the directory tree (opt->seeker bitmask). */
|
||||||
|
typedef enum hts_seeker {
|
||||||
|
HTS_SEEKER_DOWN = 1 << 0, /**< may descend into subdirectories */
|
||||||
|
HTS_SEEKER_UP = 1 << 1 /**< may ascend to parent directories */
|
||||||
|
} hts_seeker;
|
||||||
|
|
||||||
|
/* opt->travel: link-following scope in the low byte, flags OR'd in above it. */
|
||||||
|
typedef enum hts_travel_scope {
|
||||||
|
HTS_TRAVEL_SAME_ADDRESS = 0, /**< stay on the same address (host) */
|
||||||
|
HTS_TRAVEL_SAME_DOMAIN = 1, /**< stay on the same principal domain */
|
||||||
|
HTS_TRAVEL_SAME_TLD = 2, /**< stay on the same TLD (e.g. .com) */
|
||||||
|
HTS_TRAVEL_EVERYWHERE = 7, /**< follow links anywhere on the web */
|
||||||
|
HTS_TRAVEL_TEST_ALL = 1 << 8 /**< also test forbidden URLs (-t) */
|
||||||
|
} hts_travel_scope;
|
||||||
|
|
||||||
|
/* Mask selecting the scope value out of opt->travel. */
|
||||||
|
#define HTS_TRAVEL_SCOPE_MASK 0xff
|
||||||
|
|
||||||
|
/* Text progress display detail (opt->verbosedisplay). */
|
||||||
|
typedef enum hts_verbosedisplay {
|
||||||
|
HTS_VERBOSE_NONE = 0, /**< no animated progress display (default) */
|
||||||
|
HTS_VERBOSE_SIMPLE = 1, /**< minimal single-line progress */
|
||||||
|
HTS_VERBOSE_FULL = 2 /**< full animated progress */
|
||||||
|
} hts_verbosedisplay;
|
||||||
|
|
||||||
|
/* Delayed file-type resolution policy (opt->savename_delayed). */
|
||||||
|
typedef enum hts_savename_delayed {
|
||||||
|
HTS_SAVENAME_DELAYED_NONE = 0, /**< resolve the type immediately */
|
||||||
|
HTS_SAVENAME_DELAYED_SOFT = 1, /**< delay the type check when unknown */
|
||||||
|
HTS_SAVENAME_DELAYED_HARD = 2 /**< always delay the type check (default) */
|
||||||
|
} hts_savename_delayed;
|
||||||
|
|
||||||
|
/* Saved-name length layout (opt->savename_83). */
|
||||||
|
typedef enum hts_savename_83 {
|
||||||
|
HTS_SAVENAME_83_LONG = 0, /**< long file names (default) */
|
||||||
|
HTS_SAVENAME_83_DOS = 1, /**< DOS 8.3 names (ISO9660 level 1) */
|
||||||
|
HTS_SAVENAME_83_ISO9660 = 2 /**< ISO9660 level 2 names (up to 31 chars) */
|
||||||
|
} hts_savename_83;
|
||||||
|
|
||||||
|
/* Host-banning triggers (opt->hostcontrol bitmask). */
|
||||||
|
typedef enum hts_hostcontrol {
|
||||||
|
HTS_HOSTCONTROL_BAN_TIMEOUT = 1 << 0, /**< ban a timing-out host */
|
||||||
|
HTS_HOSTCONTROL_BAN_SLOW = 1 << 1 /**< ban a too-slow host */
|
||||||
|
} hts_hostcontrol;
|
||||||
|
|
||||||
#ifndef HTS_DEF_FWSTRUCT_lien_buffers
|
#ifndef HTS_DEF_FWSTRUCT_lien_buffers
|
||||||
#define HTS_DEF_FWSTRUCT_lien_buffers
|
#define HTS_DEF_FWSTRUCT_lien_buffers
|
||||||
typedef struct lien_buffers lien_buffers;
|
typedef struct lien_buffers lien_buffers;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// paramètres httrack (options)
|
/*
|
||||||
|
* Per-mirror options and state block. This is the central HTTrack parameters
|
||||||
|
* structure: created by hts_create_opt(), it carries every tunable option for
|
||||||
|
* one mirror and embeds the live engine state, and is then consumed by
|
||||||
|
* hts_main2().
|
||||||
|
*
|
||||||
|
* Callers normally configure it through the command-line argv vector (the
|
||||||
|
* option parser), not by writing fields directly. The only fields real
|
||||||
|
* consumers poke directly are 'log' and 'errlog' (set either to NULL to
|
||||||
|
* silence logging).
|
||||||
|
*/
|
||||||
#ifndef HTS_DEF_FWSTRUCT_httrackp
|
#ifndef HTS_DEF_FWSTRUCT_httrackp
|
||||||
#define HTS_DEF_FWSTRUCT_httrackp
|
#define HTS_DEF_FWSTRUCT_httrackp
|
||||||
typedef struct httrackp httrackp;
|
typedef struct httrackp httrackp;
|
||||||
#endif
|
#endif
|
||||||
struct httrackp {
|
struct httrackp {
|
||||||
size_t size_httrackp; // size of this structure
|
size_t size_httrackp; /**< size of this structure (version/ABI guard) */
|
||||||
/* */
|
/* */
|
||||||
int wizard; // wizard aucun/grand/petit
|
hts_wizard wizard; /**< interactive wizard level (none/ask/auto) */
|
||||||
int flush; // fflush sur les fichiers log
|
hts_boolean flush; /**< fflush() log files after each write */
|
||||||
int travel; // type de déplacements (same domain etc)
|
int travel; /**< link-following scope (same domain, etc.) */
|
||||||
int seeker; // up & down
|
int seeker; /**< allowed direction: go up and/or down the tree */
|
||||||
int depth; // nombre de niveaux de récursion
|
int depth; /**< maximum recursion depth (-rN) */
|
||||||
int extdepth; // nombre de niveaux de récursion à l'éxtérieur
|
int extdepth; /**< maximum recursion depth outside the start domain */
|
||||||
int urlmode; // liens relatifs etc
|
hts_urlmode
|
||||||
int no_type_change; // do not change file type according to MIME
|
urlmode; /**< saved-link rewriting style (relative, absolute, etc.) */
|
||||||
int debug; // mode débug log
|
hts_boolean no_type_change; // do not change file type according to MIME
|
||||||
int getmode; // sauver html, images..
|
hts_log_type debug; /**< debug logging level */
|
||||||
FILE *log; // fichier log
|
int getmode; /**< what to fetch (HTML, images, ...) bitmask */
|
||||||
FILE *errlog; // et erreur
|
FILE *log; /**< informational log stream; NULL mutes it */
|
||||||
LLint maxsite; // taille max site
|
FILE *errlog; /**< error log stream; NULL mutes it */
|
||||||
LLint maxfile_nonhtml; // taille max non html
|
LLint maxsite; /**< max total bytes for the whole mirror */
|
||||||
LLint maxfile_html; // taille max html
|
LLint maxfile_nonhtml; /**< max bytes per non-HTML file */
|
||||||
int maxsoc; // nbre sockets
|
LLint maxfile_html; /**< max bytes per HTML file */
|
||||||
LLint fragment; // fragmentation d'un site
|
int maxsoc; /**< max simultaneous sockets (-cN) */
|
||||||
int nearlink; // prendre les images/data proche d'une page mais à l'extérieur
|
LLint fragment; /**< split site after this many bytes */
|
||||||
int makeindex; // faire un index
|
hts_tristate
|
||||||
int kindex; // et un index 'keyword'
|
nearlink; /**< also fetch images/data adjacent to a page but off-site */
|
||||||
int delete_old; // effacer anciens fichiers
|
hts_boolean makeindex; /**< build a top-level index.html */
|
||||||
int timeout; // nombre de secondes de timeout
|
hts_boolean kindex; /**< build a keyword index */
|
||||||
int rateout; // nombre d'octets minium pour le transfert
|
hts_tristate delete_old; /**< delete locally obsolete files after update */
|
||||||
int maxtime; // temps max en secondes
|
int timeout; /**< connection timeout in seconds */
|
||||||
int maxrate; // taux de transfert max
|
int rateout; /**< minimum transfer rate (bytes/s) before abort */
|
||||||
float maxconn; // nombre max de connexions/s
|
int maxtime; /**< max total mirror duration in seconds */
|
||||||
int waittime; // démarrage programmé
|
int maxrate; /**< max transfer rate cap (bytes/s) */
|
||||||
int cache; // génération d'un cache
|
float maxconn; /**< max connections per second */
|
||||||
//int aff_progress; // barre de progression
|
int waittime; /**< scheduled start time (wall-clock seconds) */
|
||||||
int shell; // gestion d'un shell par pipe stdin/stdout
|
hts_cachemode cache; /**< cache generation mode */
|
||||||
t_proxy proxy; // configuration du proxy
|
// int aff_progress; // progress bar
|
||||||
int savename_83; // conversion 8-3 pour les noms de fichiers
|
hts_boolean shell; /**< driven by a shell over stdin/stdout pipes */
|
||||||
int savename_type; // type de noms: structure originale/html-images en un seul niveau
|
t_proxy proxy; /**< proxy configuration */
|
||||||
String savename_userdef; // structure userdef (ex: %h%p/%n%q.%t)
|
hts_savename_83
|
||||||
int savename_delayed; // delayed type check
|
savename_83; /**< saved-name length layout (long/DOS/ISO9660) */
|
||||||
int delayed_cached; // delayed type check can be cached to speedup updates
|
int savename_type; /**< saved-name layout (original tree, flat, ...) */
|
||||||
int mimehtml; // MIME-html
|
String
|
||||||
int user_agent_send; // user agent (ex: httrack/1.0 [sun])
|
savename_userdef; /**< user-defined name template (e.g. %h%p/%n%q.%t) */
|
||||||
String user_agent; //
|
hts_savename_delayed savename_delayed; /**< delayed type-check policy */
|
||||||
String referer; // referer
|
hts_boolean
|
||||||
String from; // from
|
delayed_cached; // delayed type check can be cached to speedup updates
|
||||||
String path_log; // chemin pour cache et log
|
hts_boolean mimehtml; /**< produce a single MIME/MHTML archive */
|
||||||
String path_html; // chemin pour miroir
|
hts_boolean user_agent_send; /**< send a User-Agent header */
|
||||||
String path_html_utf8; // chemin pour miroir, UTF-8
|
String user_agent; /**< User-Agent value (e.g. httrack/1.0) */
|
||||||
String path_bin; // chemin pour templates
|
String referer; /**< Referer value to send */
|
||||||
int retry; // nombre d'essais supplémentaires en cas d'échec
|
String from; /**< From value to send */
|
||||||
int makestat; // mettre à jour un fichier log de statistiques de transfert
|
String path_log; /**< directory for cache and logs */
|
||||||
int maketrack; // mettre à jour un fichier log de statistiques d'opérations
|
String path_html; /**< output directory for the mirror */
|
||||||
int parsejava; // parsing des classes java pour récupérer les class, gif & cie ; see htsparsejava_flags
|
String path_html_utf8; /**< output directory for the mirror, UTF-8 form */
|
||||||
int hostcontrol; // abandon d'un host trop lent etc.
|
String path_bin; /**< directory for HTML templates */
|
||||||
int errpage; // générer une page d'erreur en cas de 404 etc.
|
int retry; /**< extra retries on a failed transfer */
|
||||||
int check_type; // si type inconnu (cgi,asp,/) alors tester lien (et gérer moved éventuellement)
|
hts_boolean makestat; /**< maintain a transfer-statistics log */
|
||||||
int all_in_cache; // tout mettre en cache!
|
hts_boolean maketrack; /**< maintain an operations-statistics log */
|
||||||
int robots; // traitement des robots
|
int parsejava; /**< Java/JS parsing mode; see htsparsejava_flags */
|
||||||
int external; // pages externes->pages d'erreur
|
int hostcontrol; /**< ban slow/timing-out hosts; see hts_hostcontrol bits */
|
||||||
int passprivacy; // pas de mot de pass dans les liens externes?
|
hts_tristate errpage; /**< generate an error page on 404 and similar */
|
||||||
int includequery; // include la query-string
|
hts_boolean
|
||||||
int mirror_first_page; // miroir des liens
|
check_type; /**< probe unknown-type links (cgi/asp/dir) and follow moves
|
||||||
String sys_com; // commande système
|
*/
|
||||||
int sys_com_exec; // executer commande
|
hts_boolean all_in_cache; /**< keep all retrieved data in the cache */
|
||||||
int accept_cookie; // gestion des cookies
|
hts_robots robots; /**< robots.txt handling level */
|
||||||
t_cookie *cookie;
|
hts_tristate external; /**< render external links as error pages */
|
||||||
int http10; // forcer http 1.0
|
hts_boolean passprivacy; /**< strip passwords from external links */
|
||||||
int nokeepalive; // pas de keep-alive
|
hts_boolean includequery; /**< include the query string in saved names */
|
||||||
int nocompression; // pas de compression
|
hts_boolean mirror_first_page; /**< only mirror the links of the first page */
|
||||||
int sizehack; // forcer réponse "mis à jour" si taille identique
|
String sys_com; /**< system command to run */
|
||||||
int urlhack; // force "url normalization" to avoid loops
|
hts_boolean sys_com_exec; /**< actually execute sys_com */
|
||||||
int tolerant; // accepter content-length incorrect
|
hts_boolean accept_cookie; /**< accept and send cookies */
|
||||||
int parseall; // essayer de tout parser (tags inconnus contenant des liens, par exemple)
|
t_cookie *cookie; /**< cookie store */
|
||||||
int parsedebug; // débugger parser (debug!)
|
hts_boolean http10; /**< force HTTP/1.0 */
|
||||||
int norecatch; // ne pas reprendre les fichiers effacés localement par l'utilisateur
|
hts_boolean nokeepalive; /**< disable keep-alive */
|
||||||
int verbosedisplay; // animation textuelle
|
hts_boolean nocompression; /**< disable content compression */
|
||||||
String footer; // ligne d'infos
|
hts_boolean sizehack; /**< treat same-size response as "updated" */
|
||||||
int maxcache; // maximum en mémoire au niveau du cache (backing)
|
hts_boolean urlhack; // force "url normalization" to avoid loops
|
||||||
//int maxcache_anticipate; // maximum de liens à anticiper (majorant)
|
hts_boolean tolerant; /**< accept an incorrect Content-Length */
|
||||||
int ftp_proxy; // proxy http pour ftp
|
hts_tristate
|
||||||
String filelist; // fichier liste URL à inclure
|
parseall; /**< parse aggressively, including unknown tags with links */
|
||||||
String urllist; // fichier liste de filtres à inclure
|
hts_boolean parsedebug; /**< parser debug mode */
|
||||||
htsfilters filters; // contient les pointeurs pour les filtres
|
hts_boolean norecatch; /**< do not re-fetch files the user deleted locally */
|
||||||
hash_struct *hash; // hash structure
|
hts_verbosedisplay verbosedisplay; /**< animated text progress display */
|
||||||
lien_url **liens; // links
|
String footer; /**< footer/info line injected into pages */
|
||||||
int lien_tot; // top index of "links" heap (always out-of-range)
|
int maxcache; /**< in-memory cache backing limit (bytes) */
|
||||||
lien_buffers *liensbuf; // links buffers
|
// int maxcache_anticipate; // maximum links to anticipate (upper bound)
|
||||||
robots_wizard *robotsptr; // robots ptr
|
hts_boolean ftp_proxy; /**< use the HTTP proxy for FTP too */
|
||||||
String lang_iso; // en, fr ..
|
String filelist; /**< file listing URLs to include */
|
||||||
String accept; // Accept:
|
String urllist; /**< file listing filters to include */
|
||||||
String headers; // Additional headers
|
htsfilters filters; /**< filter pointers (+/-pattern rules) */
|
||||||
String mimedefs; // ext1=mimetype1\next2=mimetype2..
|
hash_struct *hash; // hash structure
|
||||||
String mod_blacklist; // (3.41)
|
lien_url **liens; // links
|
||||||
int convert_utf8; // filenames UTF-8 conversion (3.46)
|
int lien_tot; // top index of "links" heap (always out-of-range)
|
||||||
|
lien_buffers *liensbuf; // links buffers
|
||||||
|
robots_wizard *robotsptr; // robots ptr
|
||||||
|
String lang_iso; /**< Accept-Language value (en, fr, ...) */
|
||||||
|
String accept; // Accept:
|
||||||
|
String headers; // Additional headers
|
||||||
|
String mimedefs; // ext1=mimetype1\next2=mimetype2..
|
||||||
|
String mod_blacklist; /**< blacklisted modules */
|
||||||
|
hts_boolean convert_utf8; // filenames UTF-8 conversion (3.46)
|
||||||
//
|
//
|
||||||
int maxlink; // nombre max de liens
|
int maxlink; /**< max number of links */
|
||||||
int maxfilter; // nombre max de filtres
|
int maxfilter; /**< max number of filters */
|
||||||
//
|
//
|
||||||
const char *exec; // adresse du nom de l'éxecutable
|
const char *exec; /**< path of the running executable */
|
||||||
//
|
//
|
||||||
int quiet; // poser des questions autres que wizard?
|
hts_boolean quiet; /**< suppress non-wizard questions */
|
||||||
int keyboard; // vérifier stdin
|
hts_boolean keyboard; /**< poll stdin for keyboard input */
|
||||||
int bypass_limits; // bypass built-in limits
|
hts_boolean bypass_limits; // bypass built-in limits
|
||||||
int background_on_suspend; // background process on suspend signal
|
hts_boolean background_on_suspend; // background process on suspend signal
|
||||||
//
|
//
|
||||||
int is_update; // c'est une update (afficher "File updated...")
|
hts_boolean is_update; /**< this run is an update (show "File updated...") */
|
||||||
int dir_topindex; // reconstruire top index par la suite
|
hts_boolean dir_topindex; /**< rebuild the top index afterwards */
|
||||||
//
|
//
|
||||||
// callbacks
|
// callbacks
|
||||||
t_hts_htmlcheck_callbacks *callbacks_fun;
|
t_hts_htmlcheck_callbacks
|
||||||
|
*callbacks_fun; /**< user HTML/parsing callback table */
|
||||||
// store library handles
|
// store library handles
|
||||||
htslibhandles libHandles;
|
htslibhandles libHandles; /**< loaded external module handles */
|
||||||
//
|
//
|
||||||
htsoptstate state; // state
|
htsoptstate state; /**< embedded live engine state */
|
||||||
|
String strip_query; /**< query keys to drop when deduping URLs (-strip-query);
|
||||||
|
appended at the tail to keep field offsets stable */
|
||||||
|
hts_boolean
|
||||||
|
no_www_dedup; /**< with urlhack, keep www.host distinct from host */
|
||||||
|
hts_boolean no_slash_dedup; /**< with urlhack, keep redundant // in paths */
|
||||||
|
hts_boolean no_query_dedup; /**< with urlhack, keep query-argument order */
|
||||||
};
|
};
|
||||||
|
|
||||||
// stats for httrack
|
/* Running statistics for a mirror. */
|
||||||
#ifndef HTS_DEF_FWSTRUCT_hts_stat_struct
|
#ifndef HTS_DEF_FWSTRUCT_hts_stat_struct
|
||||||
#define HTS_DEF_FWSTRUCT_hts_stat_struct
|
#define HTS_DEF_FWSTRUCT_hts_stat_struct
|
||||||
typedef struct hts_stat_struct hts_stat_struct;
|
typedef struct hts_stat_struct hts_stat_struct;
|
||||||
#endif
|
#endif
|
||||||
struct hts_stat_struct {
|
struct hts_stat_struct {
|
||||||
LLint HTS_TOTAL_RECV; // flux entrant reçu
|
LLint HTS_TOTAL_RECV; /**< total bytes received from the network */
|
||||||
LLint stat_bytes; // octets écrits sur disque
|
LLint stat_bytes; /**< total bytes written to disk */
|
||||||
// int HTS_TOTAL_RECV_STATE; // status: 0 tout va bien 1: ralentir un peu 2: ralentir 3: beaucoup
|
// int HTS_TOTAL_RECV_STATE; // status: 0 ok 1: slow down a little 2: slow
|
||||||
TStamp stat_timestart; // départ
|
// down 3: a lot
|
||||||
|
TStamp stat_timestart; /**< mirror start time */
|
||||||
//
|
//
|
||||||
LLint total_packed; // flux entrant compressé reçu
|
LLint total_packed; /**< compressed bytes received (on the wire) */
|
||||||
LLint total_unpacked; // flux entrant compressé reçu
|
LLint total_unpacked; /**< bytes after decompression */
|
||||||
int total_packedfiles; // fichiers compressés
|
int total_packedfiles; /**< number of compressed files */
|
||||||
//
|
//
|
||||||
TStamp istat_timestart[2]; // départ pour calcul instantanné
|
TStamp
|
||||||
LLint istat_bytes[2]; // calcul pour instantanné
|
istat_timestart[2]; /**< window start times for the instantaneous rate */
|
||||||
TStamp istat_reference01; // top départ donné par #0 à #1
|
LLint istat_bytes[2]; /**< window byte counts for the instantaneous rate */
|
||||||
int istat_idlasttimer; // id du timer qui a récemment donné une stat
|
TStamp
|
||||||
|
istat_reference01; /**< reference timestamp handed from window #0 to #1 */
|
||||||
|
int istat_idlasttimer; /**< id of the timer that last produced a stat */
|
||||||
//
|
//
|
||||||
int stat_files; // nombre de fichiers écrits
|
int stat_files; /**< number of files written */
|
||||||
int stat_updated_files; // nombre de fichiers mis à jour
|
int stat_updated_files; /**< number of files updated */
|
||||||
int stat_background; // nombre de fichiers écrits en arrière plan
|
int stat_background; /**< number of files written in the background */
|
||||||
//
|
//
|
||||||
int stat_nrequests; // nombre de requêtes sur socket
|
int stat_nrequests; /**< number of requests issued on sockets */
|
||||||
int stat_sockid; // nombre de sockets allouées au total
|
int stat_sockid; /**< total number of sockets ever allocated */
|
||||||
int stat_nsocket; // nombre de sockets
|
int stat_nsocket; /**< current number of open sockets */
|
||||||
int stat_errors; // nombre d'erreurs
|
int stat_errors; /**< number of errors */
|
||||||
int stat_errors_front; // idem, mais au tout premier niveau
|
int stat_errors_front; /**< errors at the very first level */
|
||||||
int stat_warnings; // '' warnings
|
int stat_warnings; /**< number of warnings */
|
||||||
int stat_infos; // '' infos
|
int stat_infos; /**< number of info messages */
|
||||||
int nbk; // fichiers anticipés en arrière plan et terminés
|
int nbk; /**< background-anticipated files now completed */
|
||||||
LLint nb; // données transférées actuellement (estimation)
|
LLint nb; /**< bytes currently being transferred (estimate) */
|
||||||
//
|
//
|
||||||
LLint rate;
|
LLint rate; /**< current transfer rate */
|
||||||
//
|
//
|
||||||
TStamp last_connect; // last connect() call
|
TStamp last_connect; /**< time of the last connect() call */
|
||||||
TStamp last_request; // last request issued
|
TStamp last_request; /**< time of the last request issued */
|
||||||
};
|
};
|
||||||
|
|
||||||
// structure pour paramètres supplémentaires lors de la requête
|
/* Extra per-request parameters (mirrors httrackp request options). */
|
||||||
#ifndef HTS_DEF_FWSTRUCT_htsrequest_proxy
|
#ifndef HTS_DEF_FWSTRUCT_htsrequest_proxy
|
||||||
#define HTS_DEF_FWSTRUCT_htsrequest_proxy
|
#define HTS_DEF_FWSTRUCT_htsrequest_proxy
|
||||||
typedef struct htsrequest_proxy htsrequest_proxy;
|
typedef struct htsrequest_proxy htsrequest_proxy;
|
||||||
#endif
|
#endif
|
||||||
struct htsrequest_proxy {
|
struct htsrequest_proxy {
|
||||||
int active;
|
int active; /**< nonzero if a proxy is used for this request */
|
||||||
const char* name;
|
const char *name; /**< proxy host name */
|
||||||
int port;
|
int port; /**< proxy port */
|
||||||
const char* bindhost; // bind this host
|
const char *bindhost; /**< local address to bind the outgoing socket to */
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef HTS_DEF_FWSTRUCT_htsrequest
|
#ifndef HTS_DEF_FWSTRUCT_htsrequest
|
||||||
@@ -463,93 +597,93 @@ struct htsrequest_proxy {
|
|||||||
typedef struct htsrequest htsrequest;
|
typedef struct htsrequest htsrequest;
|
||||||
#endif
|
#endif
|
||||||
struct htsrequest {
|
struct htsrequest {
|
||||||
short int user_agent_send; // user agent (ex: httrack/1.0 [sun])
|
short int user_agent_send; /**< send a User-Agent header */
|
||||||
short int http11; // l'en tête peut (doit) être signé HTTP/1.1 et non HTTP/1.0
|
short int http11; /**< sign the request as HTTP/1.1 rather than HTTP/1.0 */
|
||||||
short int nokeepalive; // pas de keep-alive
|
short int nokeepalive; /**< disable keep-alive */
|
||||||
short int range_used; // Range utilisé
|
short int range_used; /**< a Range header is in use */
|
||||||
short int nocompression; // Pas de compression
|
short int nocompression; /**< disable compression */
|
||||||
short int flush_garbage; // recycled
|
short int flush_garbage; // recycled
|
||||||
const char* user_agent;
|
const char *user_agent; /**< User-Agent value */
|
||||||
const char* referer;
|
const char *referer; /**< Referer value */
|
||||||
const char* from;
|
const char *from; /**< From value */
|
||||||
const char* lang_iso;
|
const char *lang_iso; /**< Accept-Language value */
|
||||||
const char* accept;
|
const char *accept; /**< Accept value */
|
||||||
const char* headers;
|
const char *headers; /**< extra request headers */
|
||||||
htsrequest_proxy proxy; // proxy
|
htsrequest_proxy proxy; /**< proxy for this request */
|
||||||
};
|
};
|
||||||
|
|
||||||
// structure pour retour d'une connexion/prise d'en tête
|
/* Result of a connection / header fetch. */
|
||||||
#ifndef HTS_DEF_FWSTRUCT_htsblk
|
#ifndef HTS_DEF_FWSTRUCT_htsblk
|
||||||
#define HTS_DEF_FWSTRUCT_htsblk
|
#define HTS_DEF_FWSTRUCT_htsblk
|
||||||
typedef struct htsblk htsblk;
|
typedef struct htsblk htsblk;
|
||||||
#endif
|
#endif
|
||||||
struct htsblk {
|
struct htsblk {
|
||||||
int statuscode; // status-code, -1=erreur, 200=OK,201=..etc (cf RFC1945)
|
int statuscode; /**< HTTP status code; -1=error, 200=OK, ... (RFC1945) */
|
||||||
short int notmodified; // page ou fichier NON modifié (transféré)
|
short int notmodified; /**< page/file was not modified (not transferred) */
|
||||||
short int is_write; // sortie sur disque (out) ou en mémoire (adr)
|
short int is_write; /**< output goes to disk (out) vs memory (adr) */
|
||||||
short int is_chunk; // mode chunk
|
short int is_chunk; /**< chunked transfer encoding */
|
||||||
short int compressed; // compressé?
|
short int compressed; /**< body is compressed */
|
||||||
short int empty; // vide?
|
short int empty; /**< body is empty */
|
||||||
short int keep_alive; // Keep-Alive?
|
short int keep_alive; /**< connection is keep-alive */
|
||||||
short int keep_alive_trailers; // ..with trailers extension
|
short int keep_alive_trailers; /**< keep-alive with trailers extension */
|
||||||
int keep_alive_t; // KA timeout
|
int keep_alive_t; /**< keep-alive timeout (seconds) */
|
||||||
int keep_alive_max; // KA number of requests
|
int keep_alive_max; /**< keep-alive max number of requests */
|
||||||
char *adr; // adresse du bloc de mémoire, NULL=vide
|
char *adr; /**< in-memory body buffer; NULL if empty */
|
||||||
char *headers; // adresse des en têtes si présents
|
char *headers; /**< received headers, if any */
|
||||||
FILE *out; // écriture directe sur disque (si is_write=1)
|
FILE *out; /**< destination file when is_write=1 */
|
||||||
LLint size; // taille fichier
|
LLint size; /**< body size */
|
||||||
char msg[80]; // message éventuel si échec ("\0"=non précisé)
|
char msg[80]; /**< failure message ("" if none) */
|
||||||
char contenttype[HTS_MIMETYPE_SIZE]; // content-type (e.g. "text/html")
|
char contenttype[HTS_MIMETYPE_SIZE]; // content-type (e.g. "text/html")
|
||||||
char charset[HTS_MIMETYPE_SIZE]; // charset (e.g. "iso-8859-1")
|
char charset[HTS_MIMETYPE_SIZE]; // charset (e.g. "iso-8859-1")
|
||||||
char contentencoding[HTS_MIMETYPE_SIZE]; // content-encoding (e.g. "gzip")
|
char contentencoding[HTS_MIMETYPE_SIZE]; // content-encoding (e.g. "gzip")
|
||||||
char *location; // on copie dedans éventuellement la véritable 'location'
|
char *location; /**< resolved Location target, if any */
|
||||||
LLint totalsize; // taille totale à télécharger (-1=inconnue)
|
LLint totalsize; /**< total size to download (-1=unknown) */
|
||||||
short int is_file; // ce n'est pas une socket mais un descripteur de fichier si 1
|
short int is_file; /**< 1 if a file descriptor rather than a socket */
|
||||||
T_SOC soc; // ID socket
|
T_SOC soc; /**< socket id */
|
||||||
SOCaddr address; // IP address
|
SOCaddr address; /**< peer IP address */
|
||||||
int address_size; // IP address structure length (unused internally)
|
int address_size; // IP address structure length (unused internally)
|
||||||
FILE *fp; // fichier pour file://
|
FILE *fp; /**< file handle for file:// */
|
||||||
#if HTS_USEOPENSSL
|
#if HTS_USEOPENSSL
|
||||||
short int ssl; // is this connection a SSL one? (https)
|
short int ssl; /**< nonzero if this is an SSL connection (https) */
|
||||||
// BIO* ssl_soc; // SSL structure
|
// BIO* ssl_soc; // SSL structure
|
||||||
SSL *ssl_con; // connection structure
|
SSL *ssl_con; /**< SSL connection structure */
|
||||||
#endif
|
#endif
|
||||||
char lastmodified[64]; // Last-Modified
|
char lastmodified[64]; /**< Last-Modified value */
|
||||||
char etag[256]; // Etag
|
char etag[256]; /**< ETag value */
|
||||||
char cdispo[256]; // Content-Disposition coupé
|
char cdispo[256]; /**< Content-Disposition filename (truncated) */
|
||||||
LLint crange; // Content-Range
|
LLint crange; /**< Content-Range length */
|
||||||
LLint crange_start; // Content-Range
|
LLint crange_start; /**< Content-Range start offset */
|
||||||
LLint crange_end; // Content-Range
|
LLint crange_end; /**< Content-Range end offset */
|
||||||
int debugid; // debug connection
|
int debugid; /**< connection debug id */
|
||||||
/* */
|
/* */
|
||||||
htsrequest req; // paramètres pour la requête
|
htsrequest req; /**< parameters used for the request */
|
||||||
/*char digest[32+2]; // digest md5 généré par le moteur ("" si non généré) */
|
/*char digest[32+2]; // md5 digest generated by the engine ("" if none) */
|
||||||
};
|
};
|
||||||
|
|
||||||
// structure d'un lien
|
/* A single link in the crawl. */
|
||||||
#ifndef HTS_DEF_FWSTRUCT_lien_url
|
#ifndef HTS_DEF_FWSTRUCT_lien_url
|
||||||
#define HTS_DEF_FWSTRUCT_lien_url
|
#define HTS_DEF_FWSTRUCT_lien_url
|
||||||
typedef struct lien_url lien_url;
|
typedef struct lien_url lien_url;
|
||||||
#endif
|
#endif
|
||||||
struct lien_url {
|
struct lien_url {
|
||||||
char *adr; // adresse
|
char *adr; /**< host/address part of the URL */
|
||||||
char *fil; // nom du fichier distant
|
char *fil; /**< remote file path */
|
||||||
char *sav; // nom à sauver sur disque (avec chemin éventuel)
|
char *sav; /**< local save name (with any path) */
|
||||||
char *cod; // chemin codebase éventuel si classe java
|
char *cod; /**< codebase path for a Java class, if any */
|
||||||
char *former_adr; // adresse initiale (avant éventuel moved), peut être nulle
|
char *former_adr; /**< original address before a move; may be NULL */
|
||||||
char *former_fil; // nom du fichier distant initial (avant éventuel moved), peut être nul
|
char *former_fil; /**< original remote file before a move; may be NULL */
|
||||||
|
|
||||||
int premier; // pointeur sur le premier lien qui a donné lieu aux autres liens du domaine
|
int premier; /**< index of the first link that seeded this domain */
|
||||||
int precedent; // pointeur sur le lien qui a donné lieu à ce lien précis
|
int precedent; /**< index of the link that referenced this one */
|
||||||
int depth; // profondeur autorisée lien ; >0 forte 0=faible
|
int depth; /**< remaining allowed depth; >0 strong, 0 weak */
|
||||||
int pass2; // traiter après les autres, seconde passe. si == -1, lien traité en background
|
int pass2; /**< second-pass marker; -1 means handled in background */
|
||||||
char link_import; // lien importé à la suite d'un moved - ne pas appliquer les règles classiques up/down
|
char link_import; /**< imported after a move; skip the usual up/down rules */
|
||||||
//int moved; // pointeur sur moved
|
// int moved; // pointer to moved
|
||||||
int retry; // nombre de retry restants
|
int retry; /**< remaining retries */
|
||||||
int testmode; // mode test uniquement, envoyer juste un head!
|
int testmode; /**< test only: send just a HEAD */
|
||||||
};
|
};
|
||||||
|
|
||||||
// chargement de fichiers en 'arrière plan'
|
/* A file being fetched in the background. */
|
||||||
#ifndef HTS_DEF_FWSTRUCT_lien_back
|
#ifndef HTS_DEF_FWSTRUCT_lien_back
|
||||||
#define HTS_DEF_FWSTRUCT_lien_back
|
#define HTS_DEF_FWSTRUCT_lien_back
|
||||||
typedef struct lien_back lien_back;
|
typedef struct lien_back lien_back;
|
||||||
@@ -558,43 +692,44 @@ struct lien_back {
|
|||||||
#if DEBUG_CHECKINT
|
#if DEBUG_CHECKINT
|
||||||
char magic;
|
char magic;
|
||||||
#endif
|
#endif
|
||||||
char url_adr[HTS_URLMAXSIZE * 2]; // adresse
|
char url_adr[HTS_URLMAXSIZE * 2]; /**< host/address part of the URL */
|
||||||
char url_fil[HTS_URLMAXSIZE * 2]; // nom du fichier distant
|
char url_fil[HTS_URLMAXSIZE * 2]; /**< remote file path */
|
||||||
char url_sav[HTS_URLMAXSIZE * 2]; // nom à sauver sur disque (avec chemin éventuel)
|
char url_sav[HTS_URLMAXSIZE * 2]; /**< local save name (with any path) */
|
||||||
char referer_adr[HTS_URLMAXSIZE * 2]; // adresse host page referer
|
char referer_adr[HTS_URLMAXSIZE * 2]; /**< referer page host/address */
|
||||||
char referer_fil[HTS_URLMAXSIZE * 2]; // fichier page referer
|
char referer_fil[HTS_URLMAXSIZE * 2]; /**< referer page file */
|
||||||
char location_buffer[HTS_URLMAXSIZE * 2]; // "location" en cas de "moved" (302,..)
|
char
|
||||||
char *tmpfile; // nom à sauver temporairement (compressé)
|
location_buffer[HTS_URLMAXSIZE * 2]; /**< Location on a move (302, ...) */
|
||||||
char tmpfile_buffer[HTS_URLMAXSIZE * 2]; // buffer pour le nom à sauver temporairement
|
char *tmpfile; /**< temporary save name (compressed) */
|
||||||
char send_too[1024]; // données à envoyer en même temps que le header
|
char tmpfile_buffer[HTS_URLMAXSIZE * 2]; /**< storage for tmpfile */
|
||||||
int status; // status (-1=non utilisé, 0: prêt, >0: opération en cours)
|
char send_too[1024]; /**< data to send together with the header */
|
||||||
int locked; // locked (to be used soon)
|
int status; /**< -1=unused, 0=ready, >0=operation in progress */
|
||||||
int testmode; // mode de test
|
int locked; /**< locked (reserved) */
|
||||||
int timeout; // gérer des timeouts? (!=0 : nombre de secondes)
|
int testmode; /**< test mode */
|
||||||
TStamp timeout_refresh; // si oui, time refresh
|
int timeout; /**< timeout in seconds (0=none) */
|
||||||
int rateout; // timeout refresh? (!=0 : taux minimum toléré en octets/s)
|
TStamp timeout_refresh; /**< last activity time, for timeout tracking */
|
||||||
TStamp rateout_time; // si oui, date de départ
|
int rateout; /**< minimum tolerated rate in bytes/s (0=none) */
|
||||||
LLint maxfile_nonhtml; // taille max d'un fichier non html
|
TStamp rateout_time; /**< start time for the rate window */
|
||||||
LLint maxfile_html; // idem pour un ficheir html
|
LLint maxfile_nonhtml; /**< max bytes for a non-HTML file */
|
||||||
htsblk r; // structure htsblk de chaque objet en background
|
LLint maxfile_html; /**< max bytes for an HTML file */
|
||||||
int is_update; // mode update
|
htsblk r; /**< per-object result block */
|
||||||
int head_request; // requète HEAD?
|
int is_update; /**< update mode */
|
||||||
LLint range_req_size; // range utilisé
|
int head_request; /**< this is a HEAD request */
|
||||||
TStamp ka_time_start; // refresh time for KA
|
LLint range_req_size; /**< Range request size used */
|
||||||
|
TStamp ka_time_start; /**< keep-alive refresh start time */
|
||||||
//
|
//
|
||||||
int http11; // L'en tête doit être signé HTTP/1.1 et non HTTP/1.0
|
int http11; /**< sign the request as HTTP/1.1 rather than HTTP/1.0 */
|
||||||
int is_chunk; // chunk?
|
int is_chunk; /**< chunked transfer */
|
||||||
char *chunk_adr; // adresse chunk en cours de chargement
|
char *chunk_adr; /**< buffer for the chunk being loaded */
|
||||||
LLint chunk_size; // taille chunk en cours de chargement
|
LLint chunk_size; /**< size of the chunk being loaded */
|
||||||
LLint chunk_blocksize; // taille data declaree par le chunk
|
LLint chunk_blocksize; /**< data size declared by the chunk */
|
||||||
LLint compressed_size; // taille compressés (stats uniquement)
|
LLint compressed_size; /**< compressed size (stats only) */
|
||||||
//
|
//
|
||||||
//int links_index; // to access liens[links_index]
|
// int links_index; // to access liens[links_index]
|
||||||
//
|
//
|
||||||
char info[256]; // éventuel status pour le ftp
|
char info[256]; /**< status text, e.g. for FTP */
|
||||||
int stop_ftp; // flag stop pour ftp
|
int stop_ftp; /**< stop flag for FTP */
|
||||||
int finalized; // finalized (optim memory)
|
int finalized; /**< finalized (memory optimization) */
|
||||||
int early_add; // was added before link heap saw it
|
int early_add; /**< was added before the link heap saw it */
|
||||||
#if DEBUG_CHECKINT
|
#if DEBUG_CHECKINT
|
||||||
char magic2;
|
char magic2;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
299
src/htsparse.c
299
src/htsparse.c
@@ -296,6 +296,48 @@ static const char *html_inline_safe(const char *src, char *dst, size_t size) {
|
|||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Byte before html, or a space sentinel at the buffer start where html[-1]
|
||||||
|
would underflow; space reads as the word boundary the guards want there. */
|
||||||
|
static HTS_INLINE char html_prevc(const char *html, const char *start) {
|
||||||
|
return html > start ? html[-1] : ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* True if [s, s+len) is exactly an HTTP method token (XHR.open's first
|
||||||
|
argument is a method, not a URL: #218). Case-insensitive. */
|
||||||
|
static int is_http_method(const char *s, size_t len) {
|
||||||
|
static const char *const methods[] = {"GET", "POST", "PUT",
|
||||||
|
"DELETE", "HEAD", "OPTIONS",
|
||||||
|
"PATCH", "TRACE", NULL};
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; methods[i] != NULL; i++) {
|
||||||
|
if (strlen(methods[i]) == len && strfield(s, methods[i]) == (int) len)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Percent-encode '(' and ')' in a link emitted into an unquoted url(...) (CSS
|
||||||
|
or JS): a literal ')' closes the token early and the UA mis-parses the value
|
||||||
|
(#163). The UA decodes %28/%29 back to the saved-on-disk name. */
|
||||||
|
static void escape_url_parens(char *const s, const size_t size) {
|
||||||
|
char BIGSTK buff[HTS_URLMAXSIZE * 2];
|
||||||
|
size_t i, j;
|
||||||
|
|
||||||
|
for (i = 0, j = 0; s[i] != '\0' && j + 3 < size && j + 3 < sizeof(buff);
|
||||||
|
i++) {
|
||||||
|
if (s[i] == '(' || s[i] == ')') {
|
||||||
|
buff[j++] = '%';
|
||||||
|
buff[j++] = '2';
|
||||||
|
buff[j++] = s[i] == '(' ? '8' : '9';
|
||||||
|
} else {
|
||||||
|
buff[j++] = s[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buff[j] = '\0';
|
||||||
|
strlcpybuff(s, buff, size);
|
||||||
|
}
|
||||||
|
|
||||||
/* Main parser */
|
/* Main parser */
|
||||||
int htsparse(htsmoduleStruct * str, htsmoduleStructExtended * stre) {
|
int htsparse(htsmoduleStruct * str, htsmoduleStructExtended * stre) {
|
||||||
char catbuff[CATBUFF_SIZE];
|
char catbuff[CATBUFF_SIZE];
|
||||||
@@ -349,7 +391,7 @@ int htsparse(htsmoduleStruct * str, htsmoduleStructExtended * stre) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Now, parsing
|
// Now, parsing
|
||||||
if ((opt->getmode & 1) && (ptr > 0)) { // récupérer les html sur disque
|
if ((opt->getmode & HTS_GETMODE_HTML) && (ptr > 0)) {
|
||||||
// créer le fichier html local
|
// créer le fichier html local
|
||||||
HT_ADD_FOP; // écrire peu à peu le fichier
|
HT_ADD_FOP; // écrire peu à peu le fichier
|
||||||
}
|
}
|
||||||
@@ -553,10 +595,10 @@ int htsparse(htsmoduleStruct * str, htsmoduleStructExtended * stre) {
|
|||||||
if (opt->depth == heap(ptr)->depth) { // on note toujours les premiers liens
|
if (opt->depth == heap(ptr)->depth) { // on note toujours les premiers liens
|
||||||
if (!in_media) {
|
if (!in_media) {
|
||||||
if (opt->makeindex && (ptr > 0)) {
|
if (opt->makeindex && (ptr > 0)) {
|
||||||
if (opt->getmode & 1) { // autorisation d'écrire
|
if (opt->getmode & HTS_GETMODE_HTML) {
|
||||||
p = strfield(html, "title");
|
p = strfield(html, "title");
|
||||||
if (p) {
|
if (p) {
|
||||||
if (*(html - 1) == '/')
|
if (html_prevc(html, r->adr) == '/')
|
||||||
p = 0; // /title
|
p = 0; // /title
|
||||||
} else {
|
} else {
|
||||||
if (strfield(html, "/html"))
|
if (strfield(html, "/html"))
|
||||||
@@ -704,7 +746,7 @@ int htsparse(htsmoduleStruct * str, htsmoduleStructExtended * stre) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt->getmode & 1) { // sauver html
|
if (opt->getmode & HTS_GETMODE_HTML) { // sauver html
|
||||||
p = 0;
|
p = 0;
|
||||||
switch (emited_footer) {
|
switch (emited_footer) {
|
||||||
case 0:
|
case 0:
|
||||||
@@ -740,7 +782,8 @@ int htsparse(htsmoduleStruct * str, htsmoduleStructExtended * stre) {
|
|||||||
|
|
||||||
if (strchr(r->adr, '\r'))
|
if (strchr(r->adr, '\r'))
|
||||||
eol = "\r\n";
|
eol = "\r\n";
|
||||||
if (StringNotEmpty(opt->footer) || opt->urlmode != 4) { /* != preserve */
|
if (StringNotEmpty(opt->footer) ||
|
||||||
|
opt->urlmode != HTS_URLMODE_KEEP_ORIGINAL) {
|
||||||
if (StringNotEmpty(opt->footer)) {
|
if (StringNotEmpty(opt->footer)) {
|
||||||
char BIGSTK tempo[1024 + HTS_URLMAXSIZE * 2];
|
char BIGSTK tempo[1024 + HTS_URLMAXSIZE * 2];
|
||||||
char gmttime[256];
|
char gmttime[256];
|
||||||
@@ -1340,6 +1383,11 @@ int htsparse(htsmoduleStruct * str, htsmoduleStructExtended * stre) {
|
|||||||
int can_avoid_quotes = 0;
|
int can_avoid_quotes = 0;
|
||||||
char quotes_replacement = '\0';
|
char quotes_replacement = '\0';
|
||||||
int ensure_not_mime = 0;
|
int ensure_not_mime = 0;
|
||||||
|
// .open(method,url): reject an HTTP-method first arg (#218)
|
||||||
|
int ensure_not_method = 0;
|
||||||
|
// @import: the quoted token is the URL; a trailing
|
||||||
|
// media/supports/layer condition is not part of it
|
||||||
|
int is_import = 0;
|
||||||
|
|
||||||
if (inscript_tag)
|
if (inscript_tag)
|
||||||
expected_end = ";\"\'"; // voir a href="javascript:doc.location='foo'"
|
expected_end = ";\"\'"; // voir a href="javascript:doc.location='foo'"
|
||||||
@@ -1356,9 +1404,8 @@ int htsparse(htsmoduleStruct * str, htsmoduleStructExtended * stre) {
|
|||||||
if (!nc)
|
if (!nc)
|
||||||
nc = strfield(html, ":location"); // javascript:location="doc"
|
nc = strfield(html, ":location"); // javascript:location="doc"
|
||||||
if (!nc) { // location="doc"
|
if (!nc) { // location="doc"
|
||||||
if ((nc = strfield(html, "location"))
|
if ((nc = strfield(html, "location")) &&
|
||||||
&& !isspace(*(html - 1))
|
!isspace(html_prevc(html, r->adr)))
|
||||||
)
|
|
||||||
nc = 0;
|
nc = 0;
|
||||||
}
|
}
|
||||||
if (!nc)
|
if (!nc)
|
||||||
@@ -1368,6 +1415,7 @@ int htsparse(htsmoduleStruct * str, htsmoduleStructExtended * stre) {
|
|||||||
expected = '('; // parenthèse
|
expected = '('; // parenthèse
|
||||||
expected_end = "),"; // fin: virgule ou parenthèse
|
expected_end = "),"; // fin: virgule ou parenthèse
|
||||||
ensure_not_mime = 1; //* ensure the url is not a mime type */
|
ensure_not_mime = 1; //* ensure the url is not a mime type */
|
||||||
|
ensure_not_method = 1; // xhr.open: don't grab method
|
||||||
}
|
}
|
||||||
if (!nc)
|
if (!nc)
|
||||||
if ((nc = strfield(html, ".replace"))) { // window.replace("url")
|
if ((nc = strfield(html, ".replace"))) { // window.replace("url")
|
||||||
@@ -1379,7 +1427,9 @@ int htsparse(htsmoduleStruct * str, htsmoduleStructExtended * stre) {
|
|||||||
expected = '('; // parenthèse
|
expected = '('; // parenthèse
|
||||||
expected_end = ")"; // fin: parenthèse
|
expected_end = ")"; // fin: parenthèse
|
||||||
}
|
}
|
||||||
if (!nc && (nc = strfield(html, "url")) && (!isalnum(*(html - 1))) && *(html - 1) != '_') { // url(url)
|
if (!nc && (nc = strfield(html, "url")) &&
|
||||||
|
(!isalnum(html_prevc(html, r->adr))) &&
|
||||||
|
html_prevc(html, r->adr) != '_') { // url(url)
|
||||||
expected = '('; // parenthèse
|
expected = '('; // parenthèse
|
||||||
expected_end = ")"; // fin: parenthèse
|
expected_end = ")"; // fin: parenthèse
|
||||||
can_avoid_quotes = 1;
|
can_avoid_quotes = 1;
|
||||||
@@ -1389,6 +1439,7 @@ int htsparse(htsmoduleStruct * str, htsmoduleStructExtended * stre) {
|
|||||||
if ((nc = strfield(html, "import"))) { // import "url"
|
if ((nc = strfield(html, "import"))) { // import "url"
|
||||||
if (is_space(*(html + nc))) {
|
if (is_space(*(html + nc))) {
|
||||||
expected = 0; // no char expected
|
expected = 0; // no char expected
|
||||||
|
is_import = 1;
|
||||||
} else
|
} else
|
||||||
nc = 0;
|
nc = 0;
|
||||||
}
|
}
|
||||||
@@ -1406,6 +1457,7 @@ int htsparse(htsmoduleStruct * str, htsmoduleStructExtended * stre) {
|
|||||||
if ((*a == 34) || (*a == '\'') || (can_avoid_quotes)) {
|
if ((*a == 34) || (*a == '\'') || (can_avoid_quotes)) {
|
||||||
const char *b, *c;
|
const char *b, *c;
|
||||||
int ndelim = 1;
|
int ndelim = 1;
|
||||||
|
int valid_url = 0;
|
||||||
|
|
||||||
if ((*a == 34) || (*a == '\''))
|
if ((*a == 34) || (*a == '\''))
|
||||||
a++;
|
a++;
|
||||||
@@ -1420,12 +1472,20 @@ int htsparse(htsmoduleStruct * str, htsmoduleStructExtended * stre) {
|
|||||||
b++;
|
b++;
|
||||||
}
|
}
|
||||||
c = b--;
|
c = b--;
|
||||||
c += ndelim;
|
// no closing delimiter here (truncated input):
|
||||||
while(*c == ' ')
|
// Don't scan past the buffer NUL or capture it.
|
||||||
c++;
|
if (*c != '\0') {
|
||||||
if ((strchr(expected_end, *c)) || (*c == '\n')
|
c += ndelim;
|
||||||
|| (*c == '\r')) {
|
while (*c == ' ')
|
||||||
c -= (ndelim + 1);
|
c++;
|
||||||
|
valid_url =
|
||||||
|
(strchr(expected_end, *c)) || (*c == '\n') ||
|
||||||
|
(*c == '\r') ||
|
||||||
|
(is_import && *(b + 1 + ndelim) == ' ');
|
||||||
|
}
|
||||||
|
if (valid_url) {
|
||||||
|
// URL end = last char (b), not the delimiter
|
||||||
|
c = b;
|
||||||
if ((int) (c - a + 1)) {
|
if ((int) (c - a + 1)) {
|
||||||
if (ensure_not_mime) {
|
if (ensure_not_mime) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
@@ -1441,6 +1501,11 @@ int htsparse(htsmoduleStruct * str, htsmoduleStructExtended * stre) {
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// XHR.open's "GET" etc. is a method, not a URL
|
||||||
|
if (a != NULL && ensure_not_method &&
|
||||||
|
is_http_method(a, (size_t) (c - a + 1))) {
|
||||||
|
a = NULL;
|
||||||
|
}
|
||||||
// Check for bogus links (Vasiliy)
|
// Check for bogus links (Vasiliy)
|
||||||
if (a != NULL) {
|
if (a != NULL) {
|
||||||
const size_t size = c - a + 1;
|
const size_t size = c - a + 1;
|
||||||
@@ -1484,7 +1549,6 @@ int htsparse(htsmoduleStruct * str, htsmoduleStructExtended * stre) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1691,6 +1755,24 @@ int htsparse(htsmoduleStruct * str, htsmoduleStructExtended * stre) {
|
|||||||
hts_nodetect[i -
|
hts_nodetect[i -
|
||||||
1]);
|
1]);
|
||||||
}
|
}
|
||||||
|
// xmlns / xmlns:prefix declare
|
||||||
|
// XML namespaces, not resources
|
||||||
|
// (#191)
|
||||||
|
else {
|
||||||
|
const int xl = strfield(
|
||||||
|
intag_startattr, "xmlns");
|
||||||
|
const char xc =
|
||||||
|
intag_startattr[xl];
|
||||||
|
if (xl &&
|
||||||
|
(xc == ':' || xc == '=' ||
|
||||||
|
is_space(xc))) {
|
||||||
|
url_ok = 0;
|
||||||
|
hts_log_print(
|
||||||
|
opt, LOG_DEBUG,
|
||||||
|
"dirty parsing: xmlns "
|
||||||
|
"namespace avoided");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1746,7 +1828,7 @@ int htsparse(htsmoduleStruct * str, htsmoduleStructExtended * stre) {
|
|||||||
|
|
||||||
// écrire codebase avant, flusher avant code
|
// écrire codebase avant, flusher avant code
|
||||||
if ((p_type == -1) || (p_type == -2)) {
|
if ((p_type == -1) || (p_type == -2)) {
|
||||||
if ((opt->getmode & 1) && (ptr > 0)) {
|
if ((opt->getmode & HTS_GETMODE_HTML) && (ptr > 0)) {
|
||||||
HT_add_adr; // refresh
|
HT_add_adr; // refresh
|
||||||
}
|
}
|
||||||
lastsaved = html; // dernier écrit+1
|
lastsaved = html; // dernier écrit+1
|
||||||
@@ -1837,7 +1919,7 @@ int htsparse(htsmoduleStruct * str, htsmoduleStructExtended * stre) {
|
|||||||
|
|
||||||
// ne pas flusher après code si on doit écrire le codebase avant!
|
// ne pas flusher après code si on doit écrire le codebase avant!
|
||||||
if ((p_type != -1) && (p_type != 2) && (p_type != -2)) {
|
if ((p_type != -1) && (p_type != 2) && (p_type != -2)) {
|
||||||
if ((opt->getmode & 1) && (ptr > 0)) {
|
if ((opt->getmode & HTS_GETMODE_HTML) && (ptr > 0)) {
|
||||||
HT_add_adr; // refresh
|
HT_add_adr; // refresh
|
||||||
}
|
}
|
||||||
lastsaved = html; // dernier écrit+1
|
lastsaved = html; // dernier écrit+1
|
||||||
@@ -1914,7 +1996,7 @@ int htsparse(htsmoduleStruct * str, htsmoduleStructExtended * stre) {
|
|||||||
if (*html != '#') { // Not empty+unique #
|
if (*html != '#') { // Not empty+unique #
|
||||||
if (eadr - html == 1) { // 1=link empty with delim (end_adr-start_adr)
|
if (eadr - html == 1) { // 1=link empty with delim (end_adr-start_adr)
|
||||||
if (quote) {
|
if (quote) {
|
||||||
if ((opt->getmode & 1) && (ptr > 0)) {
|
if ((opt->getmode & HTS_GETMODE_HTML) && (ptr > 0)) {
|
||||||
HT_ADD("#"); // We add this for a <href="">
|
HT_ADD("#"); // We add this for a <href="">
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2569,7 +2651,8 @@ int htsparse(htsmoduleStruct * str, htsmoduleStructExtended * stre) {
|
|||||||
if ((p_type == 2) || (p_type == -2)) { // base href ou codebase, pas un lien
|
if ((p_type == 2) || (p_type == -2)) { // base href ou codebase, pas un lien
|
||||||
hts_log_print(opt, LOG_DEBUG, "Code/Codebase: %s%s",
|
hts_log_print(opt, LOG_DEBUG, "Code/Codebase: %s%s",
|
||||||
afs.af.adr, afs.af.fil);
|
afs.af.adr, afs.af.fil);
|
||||||
} else if ((opt->getmode & 4) == 0) {
|
} else if ((opt->getmode & HTS_GETMODE_HTML_FIRST) ==
|
||||||
|
0) {
|
||||||
hts_log_print(opt, LOG_DEBUG, "Record: %s%s -> %s",
|
hts_log_print(opt, LOG_DEBUG, "Record: %s%s -> %s",
|
||||||
afs.af.adr, afs.af.fil, afs.save);
|
afs.af.adr, afs.af.fil, afs.save);
|
||||||
} else {
|
} else {
|
||||||
@@ -2592,8 +2675,8 @@ int htsparse(htsmoduleStruct * str, htsmoduleStructExtended * stre) {
|
|||||||
lastsaved = eadr - 1 + 1; // sauter "
|
lastsaved = eadr - 1 + 1; // sauter "
|
||||||
}
|
}
|
||||||
/* */
|
/* */
|
||||||
else if (opt->urlmode == 0) { // URL absolue dans tous les cas
|
else if (opt->urlmode == HTS_URLMODE_ABSOLUTE) {
|
||||||
if ((opt->getmode & 1) && (ptr > 0)) { // ecrire les html
|
if ((opt->getmode & HTS_GETMODE_HTML) && (ptr > 0)) {
|
||||||
if (!link_has_authority(afs.af.adr)) {
|
if (!link_has_authority(afs.af.adr)) {
|
||||||
HT_ADD("http://");
|
HT_ADD("http://");
|
||||||
} else {
|
} else {
|
||||||
@@ -2620,12 +2703,14 @@ int htsparse(htsmoduleStruct * str, htsmoduleStructExtended * stre) {
|
|||||||
}
|
}
|
||||||
lastsaved = eadr - 1; // dernier écrit+1 (enfin euh apres on fait un ++ alors hein)
|
lastsaved = eadr - 1; // dernier écrit+1 (enfin euh apres on fait un ++ alors hein)
|
||||||
/* */
|
/* */
|
||||||
} else if (opt->urlmode == 4) { // ne rien faire!
|
} else if (opt->urlmode == HTS_URLMODE_KEEP_ORIGINAL) {
|
||||||
/* */
|
/* */
|
||||||
/* leave the link 'as is' */
|
/* leave the link 'as is' */
|
||||||
/* Sinon, dépend de interne/externe */
|
/* Sinon, dépend de interne/externe */
|
||||||
} else if (forbidden_url == 1) { // le lien ne sera pas chargé, référence externe!
|
} else if (forbidden_url ==
|
||||||
if ((opt->getmode & 1) && (ptr > 0)) {
|
1) { // le lien ne sera pas chargé, référence
|
||||||
|
// externe!
|
||||||
|
if ((opt->getmode & HTS_GETMODE_HTML) && (ptr > 0)) {
|
||||||
if (p_type != -1) { // pas que le nom de fichier (pas classe java)
|
if (p_type != -1) { // pas que le nom de fichier (pas classe java)
|
||||||
if (!opt->external) {
|
if (!opt->external) {
|
||||||
if (!link_has_authority(afs.af.adr)) {
|
if (!link_has_authority(afs.af.adr)) {
|
||||||
@@ -2674,7 +2759,7 @@ int htsparse(htsmoduleStruct * str, htsmoduleStructExtended * stre) {
|
|||||||
'/') ? 1 : (ishtml(opt, afs.af.fil)))) {
|
'/') ? 1 : (ishtml(opt, afs.af.fil)))) {
|
||||||
case 1:
|
case 1:
|
||||||
case -2: // html ou répertoire
|
case -2: // html ou répertoire
|
||||||
if (opt->getmode & 1) { // sauver html
|
if (opt->getmode & HTS_GETMODE_HTML) {
|
||||||
patch_it = 1; // redirect
|
patch_it = 1; // redirect
|
||||||
add_url = 1; // avec link?
|
add_url = 1; // avec link?
|
||||||
cat_name = "external.html";
|
cat_name = "external.html";
|
||||||
@@ -2847,7 +2932,8 @@ int htsparse(htsmoduleStruct * str, htsmoduleStructExtended * stre) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// érire codebase="chemin"
|
// érire codebase="chemin"
|
||||||
if ((opt->getmode & 1) && (ptr > 0)) {
|
if ((opt->getmode & HTS_GETMODE_HTML) &&
|
||||||
|
(ptr > 0)) {
|
||||||
char BIGSTK tempo4[HTS_URLMAXSIZE * 2];
|
char BIGSTK tempo4[HTS_URLMAXSIZE * 2];
|
||||||
|
|
||||||
tempo4[0] = '\0';
|
tempo4[0] = '\0';
|
||||||
@@ -2875,9 +2961,11 @@ int htsparse(htsmoduleStruct * str, htsmoduleStructExtended * stre) {
|
|||||||
lastsaved = eadr - 1;
|
lastsaved = eadr - 1;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
else if (opt->urlmode==1) { // ABSOLU, c'est le cas le moins courant
|
else if (opt->urlmode==1) { // ABSOLU, c'est le cas le
|
||||||
|
moins courant
|
||||||
// NE FONCTIONNE PAS!! (et est inutile)
|
// NE FONCTIONNE PAS!! (et est inutile)
|
||||||
if ((opt->getmode & 1) && (ptr>0)) { // ecrire les html
|
if ((opt->getmode & 1) && (ptr>0)) { // ecrire les
|
||||||
|
html
|
||||||
// écrire le lien modifié, absolu
|
// écrire le lien modifié, absolu
|
||||||
HT_ADD("file:");
|
HT_ADD("file:");
|
||||||
if (*save=='/')
|
if (*save=='/')
|
||||||
@@ -2885,7 +2973,8 @@ int htsparse(htsmoduleStruct * str, htsmoduleStructExtended * stre) {
|
|||||||
else
|
else
|
||||||
HT_ADD(save)
|
HT_ADD(save)
|
||||||
}
|
}
|
||||||
lastsaved=eadr-1; // dernier écrit+1 (enfin euh apres on fait un ++ alors hein)
|
lastsaved=eadr-1; // dernier écrit+1 (enfin euh apres
|
||||||
|
on fait un ++ alors hein)
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
else if (opt->mimehtml) {
|
else if (opt->mimehtml) {
|
||||||
@@ -2895,18 +2984,18 @@ int htsparse(htsmoduleStruct * str, htsmoduleStructExtended * stre) {
|
|||||||
make_content_id(afs.af.adr, afs.af.fil, cid, sizeof(cid));
|
make_content_id(afs.af.adr, afs.af.fil, cid, sizeof(cid));
|
||||||
HT_ADD_HTMLESCAPED(cid);
|
HT_ADD_HTMLESCAPED(cid);
|
||||||
lastsaved = eadr - 1; // dernier écrit+1 (enfin euh apres on fait un ++ alors hein)
|
lastsaved = eadr - 1; // dernier écrit+1 (enfin euh apres on fait un ++ alors hein)
|
||||||
} else if (opt->urlmode == 3) { // URI absolue /
|
} else if (opt->urlmode == HTS_URLMODE_ABSOLUTE_URI) {
|
||||||
if ((opt->getmode & 1) && (ptr > 0)) { // ecrire les html
|
if ((opt->getmode & HTS_GETMODE_HTML) && (ptr > 0)) {
|
||||||
HT_ADD_HTMLESCAPED(afs.af.fil);
|
HT_ADD_HTMLESCAPED(afs.af.fil);
|
||||||
}
|
}
|
||||||
lastsaved = eadr - 1; // dernier écrit+1 (enfin euh apres on fait un ++ alors hein)
|
lastsaved = eadr - 1; // dernier écrit+1 (enfin euh apres on fait un ++ alors hein)
|
||||||
} else if (opt->urlmode == 5) { // transparent proxy URL
|
} else if (opt->urlmode == HTS_URLMODE_TRANSPARENT_PROXY) {
|
||||||
char BIGSTK tempo[HTS_URLMAXSIZE * 2];
|
char BIGSTK tempo[HTS_URLMAXSIZE * 2];
|
||||||
const char *uri;
|
const char *uri;
|
||||||
int i;
|
int i;
|
||||||
char *pos;
|
char *pos;
|
||||||
|
|
||||||
if ((opt->getmode & 1) && (ptr > 0)) { // ecrire les html
|
if ((opt->getmode & HTS_GETMODE_HTML) && (ptr > 0)) {
|
||||||
if (!link_has_authority(afs.af.adr)) {
|
if (!link_has_authority(afs.af.adr)) {
|
||||||
HT_ADD("http://");
|
HT_ADD("http://");
|
||||||
} else {
|
} else {
|
||||||
@@ -2947,7 +3036,7 @@ int htsparse(htsmoduleStruct * str, htsmoduleStructExtended * stre) {
|
|||||||
HT_ADD_HTMLESCAPED(tempo);
|
HT_ADD_HTMLESCAPED(tempo);
|
||||||
}
|
}
|
||||||
lastsaved = eadr - 1; // dernier écrit+1 (enfin euh apres on fait un ++ alors hein)
|
lastsaved = eadr - 1; // dernier écrit+1 (enfin euh apres on fait un ++ alors hein)
|
||||||
} else if (opt->urlmode == 2) { // RELATIF
|
} else if (opt->urlmode == HTS_URLMODE_RELATIVE) {
|
||||||
char BIGSTK tempo[HTS_URLMAXSIZE * 2];
|
char BIGSTK tempo[HTS_URLMAXSIZE * 2];
|
||||||
|
|
||||||
tempo[0] = '\0';
|
tempo[0] = '\0';
|
||||||
@@ -2959,6 +3048,10 @@ int htsparse(htsmoduleStruct * str, htsmoduleStructExtended * stre) {
|
|||||||
/* Never escape high-chars (we don't know the encoding!!) */
|
/* Never escape high-chars (we don't know the encoding!!) */
|
||||||
inplace_escape_uri_utf(tempo, sizeof(tempo));
|
inplace_escape_uri_utf(tempo, sizeof(tempo));
|
||||||
|
|
||||||
|
// unquoted url() (CSS/JS): keep parens escaped
|
||||||
|
if (ending_p == ')')
|
||||||
|
escape_url_parens(tempo, sizeof(tempo));
|
||||||
|
|
||||||
//if (!no_esc_utf)
|
//if (!no_esc_utf)
|
||||||
// escape_uri(tempo); // escape with %xx
|
// escape_uri(tempo); // escape with %xx
|
||||||
//else {
|
//else {
|
||||||
@@ -3009,7 +3102,8 @@ int htsparse(htsmoduleStruct * str, htsmoduleStructExtended * stre) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// érire codebase="chemin"
|
// érire codebase="chemin"
|
||||||
if ((opt->getmode & 1) && (ptr > 0)) {
|
if ((opt->getmode & HTS_GETMODE_HTML) &&
|
||||||
|
(ptr > 0)) {
|
||||||
char BIGSTK tempo4[HTS_URLMAXSIZE * 2];
|
char BIGSTK tempo4[HTS_URLMAXSIZE * 2];
|
||||||
|
|
||||||
tempo4[0] = '\0';
|
tempo4[0] = '\0';
|
||||||
@@ -3027,7 +3121,7 @@ int htsparse(htsmoduleStruct * str, htsmoduleStructExtended * stre) {
|
|||||||
//lastsaved=adr; // dernier écrit+1
|
//lastsaved=adr; // dernier écrit+1
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((opt->getmode & 1) && (ptr > 0)) {
|
if ((opt->getmode & HTS_GETMODE_HTML) && (ptr > 0)) {
|
||||||
// convert to local codepage - NOT, already converted into %NN, and passed to the remote server so we do not have anything to do
|
// convert to local codepage - NOT, already converted into %NN, and passed to the remote server so we do not have anything to do
|
||||||
//if (str->page_charset_ != NULL && *str->page_charset_ != '\0') {
|
//if (str->page_charset_ != NULL && *str->page_charset_ != '\0') {
|
||||||
// char *const local_save = hts_convertStringFromUTF8(tempo, strlen(tempo), str->page_charset_);
|
// char *const local_save = hts_convertStringFromUTF8(tempo, strlen(tempo), str->page_charset_);
|
||||||
@@ -3061,7 +3155,7 @@ int htsparse(htsmoduleStruct * str, htsmoduleStructExtended * stre) {
|
|||||||
"Error building relative link %s and %s",
|
"Error building relative link %s and %s",
|
||||||
afs.save, relativesavename());
|
afs.save, relativesavename());
|
||||||
}
|
}
|
||||||
} // sinon le lien sera écrit normalement
|
} // sinon le lien sera écrit normalement
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if (fexist(save)) { // le fichier existe..
|
if (fexist(save)) { // le fichier existe..
|
||||||
@@ -3089,7 +3183,7 @@ int htsparse(htsmoduleStruct * str, htsmoduleStructExtended * stre) {
|
|||||||
opt->maxlink);
|
opt->maxlink);
|
||||||
hts_log_print(opt, LOG_INFO,
|
hts_log_print(opt, LOG_INFO,
|
||||||
"To avoid that: use #L option for more links (example: -#L1000000)");
|
"To avoid that: use #L option for more links (example: -#L1000000)");
|
||||||
if ((opt->getmode & 1) && (ptr > 0)) {
|
if ((opt->getmode & HTS_GETMODE_HTML) && (ptr > 0)) {
|
||||||
if (fp) {
|
if (fp) {
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
fp = NULL;
|
fp = NULL;
|
||||||
@@ -3101,9 +3195,9 @@ int htsparse(htsmoduleStruct * str, htsmoduleStructExtended * stre) {
|
|||||||
int pass_fix, dejafait = 0;
|
int pass_fix, dejafait = 0;
|
||||||
|
|
||||||
// Calculer la priorité de ce lien
|
// Calculer la priorité de ce lien
|
||||||
if ((opt->getmode & 4) == 0) { // traiter html après
|
if ((opt->getmode & HTS_GETMODE_HTML_FIRST) == 0) {
|
||||||
pass_fix = 0;
|
pass_fix = 0;
|
||||||
} else { // vérifier que ce n'est pas un !html
|
} else { // vérifier que ce n'est pas un !html
|
||||||
if (!ishtml(opt, afs.af.fil))
|
if (!ishtml(opt, afs.af.fil))
|
||||||
pass_fix = 1; // priorité inférieure (traiter après)
|
pass_fix = 1; // priorité inférieure (traiter après)
|
||||||
else
|
else
|
||||||
@@ -3167,7 +3261,8 @@ int htsparse(htsmoduleStruct * str, htsmoduleStructExtended * stre) {
|
|||||||
if (checkrobots(_ROBOTS, afs.af.adr, "") == -1) { // robots.txt ?
|
if (checkrobots(_ROBOTS, afs.af.adr, "") == -1) { // robots.txt ?
|
||||||
// enregistrer robots.txt (MACRO)
|
// enregistrer robots.txt (MACRO)
|
||||||
if (!hts_record_link(opt, afs.af.adr, "/robots.txt", "", "", "", NULL)) {
|
if (!hts_record_link(opt, afs.af.adr, "/robots.txt", "", "", "", NULL)) {
|
||||||
if ((opt->getmode & 1) && (ptr > 0)) {
|
if ((opt->getmode & HTS_GETMODE_HTML) &&
|
||||||
|
(ptr > 0)) {
|
||||||
if (fp) {
|
if (fp) {
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
fp = NULL;
|
fp = NULL;
|
||||||
@@ -3206,7 +3301,8 @@ int htsparse(htsmoduleStruct * str, htsmoduleStructExtended * stre) {
|
|||||||
// enregistrer
|
// enregistrer
|
||||||
if (!hts_record_link(opt, afs.af.adr, afs.af.fil, afs.save,
|
if (!hts_record_link(opt, afs.af.adr, afs.af.fil, afs.save,
|
||||||
former.adr, former.fil, codebase)) {
|
former.adr, former.fil, codebase)) {
|
||||||
if ((opt->getmode & 1) && (ptr > 0)) {
|
if ((opt->getmode & HTS_GETMODE_HTML) &&
|
||||||
|
(ptr > 0)) {
|
||||||
if (fp) {
|
if (fp) {
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
fp = NULL;
|
fp = NULL;
|
||||||
@@ -3351,7 +3447,7 @@ int htsparse(htsmoduleStruct * str, htsmoduleStructExtended * stre) {
|
|||||||
}
|
}
|
||||||
// ----------
|
// ----------
|
||||||
// écrire peu à peu
|
// écrire peu à peu
|
||||||
if ((opt->getmode & 1) && (ptr > 0))
|
if ((opt->getmode & HTS_GETMODE_HTML) && (ptr > 0))
|
||||||
HT_add_adr;
|
HT_add_adr;
|
||||||
lastsaved = html; // dernier écrit+1
|
lastsaved = html; // dernier écrit+1
|
||||||
// ----------
|
// ----------
|
||||||
@@ -3411,7 +3507,7 @@ int htsparse(htsmoduleStruct * str, htsmoduleStructExtended * stre) {
|
|||||||
opt->state._hts_in_html_parsing = 0; // flag
|
opt->state._hts_in_html_parsing = 0; // flag
|
||||||
opt->state._hts_cancel = 0; // pas de cancel
|
opt->state._hts_cancel = 0; // pas de cancel
|
||||||
|
|
||||||
if ((opt->getmode & 1) && (ptr > 0)) {
|
if ((opt->getmode & HTS_GETMODE_HTML) && (ptr > 0)) {
|
||||||
{
|
{
|
||||||
char *cAddr = TypedArrayElts(output_buffer);
|
char *cAddr = TypedArrayElts(output_buffer);
|
||||||
int cSize = (int) TypedArraySize(output_buffer);
|
int cSize = (int) TypedArraySize(output_buffer);
|
||||||
@@ -3443,7 +3539,7 @@ int htsparse(htsmoduleStruct * str, htsmoduleStructExtended * stre) {
|
|||||||
//
|
//
|
||||||
} // if !error
|
} // if !error
|
||||||
|
|
||||||
if (opt->getmode & 1) {
|
if (opt->getmode & HTS_GETMODE_HTML) {
|
||||||
if (fp) {
|
if (fp) {
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
fp = NULL;
|
fp = NULL;
|
||||||
@@ -3506,16 +3602,28 @@ int hts_mirror_check_moved(htsmoduleStruct * str,
|
|||||||
ident_url_relatif(mov_url, urladr(), urlfil(), moved)) >= 0) {
|
ident_url_relatif(mov_url, urladr(), urlfil(), moved)) >= 0) {
|
||||||
int set_prio_to = 0; // pas de priotité fixéd par wizard
|
int set_prio_to = 0; // pas de priotité fixéd par wizard
|
||||||
|
|
||||||
// check whether URLHack is harmless or not
|
// check whether URLHack is harmless or not (per the effective
|
||||||
if (opt->urlhack) {
|
// sub-flags)
|
||||||
|
if (opt->urlhack && (!opt->no_www_dedup || !opt->no_slash_dedup ||
|
||||||
|
!opt->no_query_dedup)) {
|
||||||
|
const int norm_host = !opt->no_www_dedup;
|
||||||
|
const int norm_slash = !opt->no_slash_dedup;
|
||||||
|
const int norm_query = !opt->no_query_dedup;
|
||||||
char BIGSTK n_adr[HTS_URLMAXSIZE * 2], n_fil[HTS_URLMAXSIZE * 2];
|
char BIGSTK n_adr[HTS_URLMAXSIZE * 2], n_fil[HTS_URLMAXSIZE * 2];
|
||||||
char BIGSTK pn_adr[HTS_URLMAXSIZE * 2], pn_fil[HTS_URLMAXSIZE * 2];
|
char BIGSTK pn_adr[HTS_URLMAXSIZE * 2], pn_fil[HTS_URLMAXSIZE * 2];
|
||||||
|
|
||||||
n_adr[0] = n_fil[0] = '\0';
|
strlcpybuff(n_adr,
|
||||||
(void) adr_normalized_sized(moved->adr, n_adr, sizeof(n_adr));
|
norm_host ? jump_normalized_const(moved->adr)
|
||||||
(void) fil_normalized(moved->fil, n_fil);
|
: jump_identification_const(moved->adr),
|
||||||
(void) adr_normalized_sized(urladr(), pn_adr, sizeof(pn_adr));
|
sizeof(n_adr));
|
||||||
(void) fil_normalized(urlfil(), pn_fil);
|
strlcpybuff(pn_adr,
|
||||||
|
norm_host ? jump_normalized_const(urladr())
|
||||||
|
: jump_identification_const(urladr()),
|
||||||
|
sizeof(pn_adr));
|
||||||
|
fil_normalized_filtered_ex(moved->fil, n_fil, NULL, norm_slash,
|
||||||
|
norm_query);
|
||||||
|
fil_normalized_filtered_ex(urlfil(), pn_fil, NULL, norm_slash,
|
||||||
|
norm_query);
|
||||||
if (strcasecmp(n_adr, pn_adr) == 0
|
if (strcasecmp(n_adr, pn_adr) == 0
|
||||||
&& strcasecmp(n_fil, pn_fil) == 0) {
|
&& strcasecmp(n_fil, pn_fil) == 0) {
|
||||||
hts_log_print(opt, LOG_WARNING,
|
hts_log_print(opt, LOG_WARNING,
|
||||||
@@ -3653,44 +3761,60 @@ int hts_mirror_check_moved(htsmoduleStruct * str,
|
|||||||
|
|
||||||
} // bloc
|
} // bloc
|
||||||
// erreur HTTP (ex: 404, not found)
|
// erreur HTTP (ex: 404, not found)
|
||||||
} else if ((r->statuscode == HTTP_PRECONDITION_FAILED)
|
} else if ((r->statuscode == HTTP_PRECONDITION_FAILED) ||
|
||||||
|| (r->statuscode == HTTP_REQUESTED_RANGE_NOT_SATISFIABLE)
|
(r->statuscode == HTTP_REQUESTED_RANGE_NOT_SATISFIABLE)) {
|
||||||
) { // Precondition Failed, c'est à dire pour nous redemander TOUT le fichier
|
// 412/416: the resume partial is stale; re-get the whole file (#206)
|
||||||
if (fexist_utf8(heap(ptr)->sav)) {
|
lien_back *itemback = NULL;
|
||||||
remove(heap(ptr)->sav); // Eliminer
|
int had_partial = 0;
|
||||||
} else {
|
int ref_existed = 0;
|
||||||
hts_log_print(opt, LOG_WARNING,
|
int ref_gone;
|
||||||
"Unexpected 412/416 error (%s) for %s%s, '%s' could not be found on disk",
|
|
||||||
r->msg, urladr(), urlfil(),
|
// Drop the temp-ref, its partial, and heap->sav so the re-get carries no
|
||||||
heap(ptr)->sav != NULL ? heap(ptr)->sav : "");
|
// Range; else back_add rebuilds the same Range and loops.
|
||||||
|
if (back_unserialize_ref(opt, heap(ptr)->adr, heap(ptr)->fil,
|
||||||
|
&itemback) == 0) {
|
||||||
|
had_partial = 1;
|
||||||
|
ref_existed = 1;
|
||||||
|
// best-effort: an orphaned partial cannot re-Range once the ref is gone
|
||||||
|
if (fexist_utf8(itemback->url_sav))
|
||||||
|
(void) UNLINK(fconv(OPT_GET_BUFF(opt), OPT_GET_BUFF_SIZE(opt),
|
||||||
|
itemback->url_sav));
|
||||||
|
back_clear_entry(itemback);
|
||||||
|
freet(itemback);
|
||||||
}
|
}
|
||||||
if (!fexist_utf8(heap(ptr)->sav)) { // Bien éliminé? (sinon on boucle..)
|
// don't re-record if the ref survived (it would re-Range and loop)
|
||||||
#if HDEBUG
|
ref_gone =
|
||||||
printf("Partial content NOT up-to-date, reget all file for %s\n",
|
url_savename_refname_remove(opt, heap(ptr)->adr, heap(ptr)->fil) ||
|
||||||
heap(ptr)->sav);
|
!ref_existed;
|
||||||
#endif
|
if (fexist_utf8(heap(ptr)->sav)) {
|
||||||
|
had_partial = 1;
|
||||||
|
remove(heap(ptr)->sav);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Re-get once, only if a partial existed and both Range triggers are
|
||||||
|
// gone; a failed removal gives up rather than looping. range_used is
|
||||||
|
// unreliable (it does not survive the delayed-type two-pass).
|
||||||
|
if (had_partial && ref_gone && !fexist_utf8(heap(ptr)->sav)) {
|
||||||
hts_log_print(opt, LOG_DEBUG, "Partial file reget (%s) for %s%s",
|
hts_log_print(opt, LOG_DEBUG, "Partial file reget (%s) for %s%s",
|
||||||
r->msg, urladr(), urlfil());
|
r->msg, urladr(), urlfil());
|
||||||
// enregistrer le MEME lien
|
|
||||||
if (hts_record_link(opt, heap(ptr)->adr, heap(ptr)->fil, heap(ptr)->sav, "", "", NULL)) {
|
if (hts_record_link(opt, heap(ptr)->adr, heap(ptr)->fil, heap(ptr)->sav, "", "", NULL)) {
|
||||||
heap_top()->testmode = heap(ptr)->testmode; // mode test?
|
heap_top()->testmode = heap(ptr)->testmode;
|
||||||
heap_top()->link_import = 0; // pas mode import
|
heap_top()->link_import = 0;
|
||||||
heap_top()->depth = heap(ptr)->depth;
|
heap_top()->depth = heap(ptr)->depth;
|
||||||
heap_top()->pass2 = max(heap(ptr)->pass2, numero_passe);
|
heap_top()->pass2 = max(heap(ptr)->pass2, numero_passe);
|
||||||
heap_top()->retry = heap(ptr)->retry;
|
heap_top()->retry = heap(ptr)->retry;
|
||||||
heap_top()->premier = heap(ptr)->premier;
|
heap_top()->premier = heap(ptr)->premier;
|
||||||
heap_top()->precedent = ptr;
|
heap_top()->precedent = ptr;
|
||||||
//
|
|
||||||
// canceller lien actuel
|
|
||||||
error = 1;
|
error = 1;
|
||||||
hts_invalidate_link(opt, ptr); // invalidate hashtable entry
|
hts_invalidate_link(opt, ptr); // invalidate hashtable entry
|
||||||
//
|
} else { // out of memory
|
||||||
} else { // oups erreur, plus de mémoire!!
|
XH_uninit;
|
||||||
XH_uninit; // désallocation mémoire & buffers
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
hts_log_print(opt, LOG_ERROR, "Can not remove old file %s", urlfil());
|
hts_log_print(opt, LOG_WARNING,
|
||||||
|
"Giving up on partial reget (%s) for %s%s", r->msg,
|
||||||
|
urladr(), urlfil());
|
||||||
error = 1;
|
error = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3711,7 +3835,8 @@ int hts_mirror_check_moved(htsmoduleStruct * str,
|
|||||||
//case -1: can_retry=1; break;
|
//case -1: can_retry=1; break;
|
||||||
case STATUSCODE_TIMEOUT:
|
case STATUSCODE_TIMEOUT:
|
||||||
if (opt->hostcontrol) { // timeout et retry épuisés
|
if (opt->hostcontrol) { // timeout et retry épuisés
|
||||||
if ((opt->hostcontrol & 1) && (heap(ptr)->retry <= 0)) {
|
if ((opt->hostcontrol & HTS_HOSTCONTROL_BAN_TIMEOUT) &&
|
||||||
|
(heap(ptr)->retry <= 0)) {
|
||||||
hts_log_print(opt, LOG_DEBUG, "Link banned: %s%s", urladr(), urlfil());
|
hts_log_print(opt, LOG_DEBUG, "Link banned: %s%s", urladr(), urlfil());
|
||||||
host_ban(opt, ptr, sback, jump_identification_const(urladr()));
|
host_ban(opt, ptr, sback, jump_identification_const(urladr()));
|
||||||
hts_log_print(opt, LOG_DEBUG,
|
hts_log_print(opt, LOG_DEBUG,
|
||||||
@@ -3724,7 +3849,7 @@ int hts_mirror_check_moved(htsmoduleStruct * str,
|
|||||||
break;
|
break;
|
||||||
case STATUSCODE_SLOW:
|
case STATUSCODE_SLOW:
|
||||||
if ((opt->hostcontrol) && (heap(ptr)->retry <= 0)) { // too slow
|
if ((opt->hostcontrol) && (heap(ptr)->retry <= 0)) { // too slow
|
||||||
if (opt->hostcontrol & 2) {
|
if (opt->hostcontrol & HTS_HOSTCONTROL_BAN_SLOW) {
|
||||||
hts_log_print(opt, LOG_DEBUG, "Link banned: %s%s", urladr(), urlfil());
|
hts_log_print(opt, LOG_DEBUG, "Link banned: %s%s", urladr(), urlfil());
|
||||||
host_ban(opt, ptr, sback, jump_identification_const(urladr()));
|
host_ban(opt, ptr, sback, jump_identification_const(urladr()));
|
||||||
hts_log_print(opt, LOG_DEBUG,
|
hts_log_print(opt, LOG_DEBUG,
|
||||||
@@ -4250,10 +4375,10 @@ int hts_mirror_wait_for_next_file(htsmoduleStruct * str,
|
|||||||
char com[256];
|
char com[256];
|
||||||
|
|
||||||
linput(stdin, com, 200);
|
linput(stdin, com, 200);
|
||||||
if (opt->verbosedisplay == 2)
|
if (opt->verbosedisplay == HTS_VERBOSE_FULL)
|
||||||
opt->verbosedisplay = 1;
|
opt->verbosedisplay = HTS_VERBOSE_SIMPLE;
|
||||||
else
|
else
|
||||||
opt->verbosedisplay = 2;
|
opt->verbosedisplay = HTS_VERBOSE_FULL;
|
||||||
/* Info for wrappers */
|
/* Info for wrappers */
|
||||||
hts_log_print(opt, LOG_INFO, "engine: change-options");
|
hts_log_print(opt, LOG_INFO, "engine: change-options");
|
||||||
RUN_CALLBACK0(opt, chopt);
|
RUN_CALLBACK0(opt, chopt);
|
||||||
@@ -4363,7 +4488,7 @@ int hts_mirror_wait_for_next_file(htsmoduleStruct * str,
|
|||||||
printf("%c\x0d", ("/-\\|")[roll]);
|
printf("%c\x0d", ("/-\\|")[roll]);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
} else if (opt->verbosedisplay == 1) {
|
} else if (opt->verbosedisplay == HTS_VERBOSE_SIMPLE) {
|
||||||
if (b >= 0) {
|
if (b >= 0) {
|
||||||
if (back[b].r.statuscode == HTTP_OK)
|
if (back[b].r.statuscode == HTTP_OK)
|
||||||
printf("%d/%d: %s%s (" LLintP " bytes) - OK\33[K\r", ptr, opt->lien_tot,
|
printf("%d/%d: %s%s (" LLintP " bytes) - OK\33[K\r", ptr, opt->lien_tot,
|
||||||
@@ -4454,8 +4579,8 @@ int hts_wait_delayed(htsmoduleStruct * str, lien_adrfilsave *afs,
|
|||||||
char in_error_msg[32];
|
char in_error_msg[32];
|
||||||
|
|
||||||
// resolve unresolved type
|
// resolve unresolved type
|
||||||
if (opt->savename_delayed != 0 && *forbidden_url == 0 && IS_DELAYED_EXT(afs->save)
|
if (opt->savename_delayed != HTS_SAVENAME_DELAYED_NONE &&
|
||||||
&& !opt->state.stop) {
|
*forbidden_url == 0 && IS_DELAYED_EXT(afs->save) && !opt->state.stop) {
|
||||||
int loops;
|
int loops;
|
||||||
int continue_loop;
|
int continue_loop;
|
||||||
|
|
||||||
@@ -4839,7 +4964,7 @@ int hts_wait_delayed(htsmoduleStruct * str, lien_adrfilsave *afs,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // delayed type check ?
|
} // delayed type check ?
|
||||||
|
|
||||||
ENGINE_SAVE_CONTEXT_BASE();
|
ENGINE_SAVE_CONTEXT_BASE();
|
||||||
|
|
||||||
|
|||||||
263
src/htssafe.h
263
src/htssafe.h
@@ -48,7 +48,7 @@ Please visit our Website: http://www.httrack.com
|
|||||||
/** Assert error callback. **/
|
/** Assert error callback. **/
|
||||||
#ifndef HTS_DEF_FWSTRUCT_htsErrorCallback
|
#ifndef HTS_DEF_FWSTRUCT_htsErrorCallback
|
||||||
#define HTS_DEF_FWSTRUCT_htsErrorCallback
|
#define HTS_DEF_FWSTRUCT_htsErrorCallback
|
||||||
typedef void (*htsErrorCallback) (const char *msg, const char *file, int line);
|
typedef void (*htsErrorCallback)(const char *msg, const char *file, int line);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
@@ -58,12 +58,13 @@ HTSEXT_API htsErrorCallback hts_get_error_callback(void);
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define HTSSAFE_ABORT_FUNCTION(A,B,C) do { \
|
#define HTSSAFE_ABORT_FUNCTION(A, B, C) \
|
||||||
htsErrorCallback callback = hts_get_error_callback(); \
|
do { \
|
||||||
if (callback != NULL) { \
|
htsErrorCallback callback = hts_get_error_callback(); \
|
||||||
callback(A,B,C); \
|
if (callback != NULL) { \
|
||||||
} \
|
callback(A, B, C); \
|
||||||
} while(0)
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -75,7 +76,8 @@ HTSEXT_API htsErrorCallback hts_get_error_callback(void);
|
|||||||
/**
|
/**
|
||||||
* Fatal assertion check.
|
* Fatal assertion check.
|
||||||
*/
|
*/
|
||||||
#define assertf__(exp, sexp, file, line) (void) ( (exp) || (abortf_(sexp, file, line), 0) )
|
#define assertf__(exp, sexp, file, line) \
|
||||||
|
(void) ((exp) || (abortf_(sexp, file, line), 0))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fatal assertion check.
|
* Fatal assertion check.
|
||||||
@@ -104,13 +106,15 @@ static HTS_UNUSED void abortf_(const char *exp, const char *file, int line) {
|
|||||||
* Check whether 'VAR' is of type char[].
|
* Check whether 'VAR' is of type char[].
|
||||||
*/
|
*/
|
||||||
#if (defined(__GNUC__) && !defined(__cplusplus))
|
#if (defined(__GNUC__) && !defined(__cplusplus))
|
||||||
|
|
||||||
/* Note: char[] and const char[] are compatible */
|
/* Note: char[] and const char[] are compatible */
|
||||||
#define HTS_IS_CHAR_BUFFER(VAR) ( __builtin_types_compatible_p ( typeof (VAR), char[] ) )
|
#define HTS_IS_CHAR_BUFFER(VAR) \
|
||||||
|
(__builtin_types_compatible_p(typeof(VAR), char[]))
|
||||||
#else
|
#else
|
||||||
/* Note: a bit lame as char[8] won't be seen. */
|
/* Note: a bit lame as char[8] won't be seen. */
|
||||||
#define HTS_IS_CHAR_BUFFER(VAR) ( sizeof(VAR) != sizeof(char*) )
|
#define HTS_IS_CHAR_BUFFER(VAR) (sizeof(VAR) != sizeof(char *))
|
||||||
#endif
|
#endif
|
||||||
#define HTS_IS_NOT_CHAR_BUFFER(VAR) ( ! HTS_IS_CHAR_BUFFER(VAR) )
|
#define HTS_IS_NOT_CHAR_BUFFER(VAR) (!HTS_IS_CHAR_BUFFER(VAR))
|
||||||
|
|
||||||
/* Compile-time checks. */
|
/* Compile-time checks. */
|
||||||
static HTS_UNUSED void htssafe_compile_time_check_(void) {
|
static HTS_UNUSED void htssafe_compile_time_check_(void) {
|
||||||
@@ -139,8 +143,11 @@ static HTS_UNUSED void htssafe_compile_time_check_(void) {
|
|||||||
* (MSVC, ...) keep the previous behavior via the #else branches.
|
* (MSVC, ...) keep the previous behavior via the #else branches.
|
||||||
*/
|
*/
|
||||||
#if (defined(__GNUC__) && !defined(__cplusplus))
|
#if (defined(__GNUC__) && !defined(__cplusplus))
|
||||||
|
|
||||||
#if defined(__has_attribute)
|
#if defined(__has_attribute)
|
||||||
|
|
||||||
#if __has_attribute(warning)
|
#if __has_attribute(warning)
|
||||||
|
|
||||||
#define HTS_BUFF_PTR_ATTR(msg) __attribute__((unused, noinline, warning(msg)))
|
#define HTS_BUFF_PTR_ATTR(msg) __attribute__((unused, noinline, warning(msg)))
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@@ -152,90 +159,136 @@ static HTS_UNUSED void htssafe_compile_time_check_(void) {
|
|||||||
|
|
||||||
HTS_BUFF_PTR_ATTR("strcpybuff() destination is a pointer (capacity unknown): "
|
HTS_BUFF_PTR_ATTR("strcpybuff() destination is a pointer (capacity unknown): "
|
||||||
"NOT bounds-checked; use strlcpybuff(dst, src, size)")
|
"NOT bounds-checked; use strlcpybuff(dst, src, size)")
|
||||||
|
|
||||||
static char *strcpybuff_ptr_(char *dest, const char *src) {
|
static char *strcpybuff_ptr_(char *dest, const char *src) {
|
||||||
return strcpy(dest, src);
|
return strcpy(dest, src);
|
||||||
}
|
}
|
||||||
|
|
||||||
HTS_BUFF_PTR_ATTR("strcatbuff() destination is a pointer (capacity unknown): "
|
HTS_BUFF_PTR_ATTR("strcatbuff() destination is a pointer (capacity unknown): "
|
||||||
"NOT bounds-checked; use strlcatbuff(dst, src, size)")
|
"NOT bounds-checked; use strlcatbuff(dst, src, size)")
|
||||||
|
|
||||||
static char *strcatbuff_ptr_(char *dest, const char *src) {
|
static char *strcatbuff_ptr_(char *dest, const char *src) {
|
||||||
return strcat(dest, src);
|
return strcat(dest, src);
|
||||||
}
|
}
|
||||||
|
|
||||||
HTS_BUFF_PTR_ATTR("strncatbuff() destination is a pointer (capacity unknown): "
|
HTS_BUFF_PTR_ATTR("strncatbuff() destination is a pointer (capacity unknown): "
|
||||||
"NOT bounds-checked; use strlcatbuff(dst, src, size)")
|
"NOT bounds-checked; use strlcatbuff(dst, src, size)")
|
||||||
|
|
||||||
static char *strncatbuff_ptr_(char *dest, const char *src, size_t n) {
|
static char *strncatbuff_ptr_(char *dest, const char *src, size_t n) {
|
||||||
return strncat(dest, src, n);
|
return strncat(dest, src, n);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SIZE CONTRACT shared by strcpybuff/strcatbuff/strncatbuff (the "buff"
|
||||||
|
* family): the destination bound is taken from sizeof(A), so A MUST be a real
|
||||||
|
* char[] array in scope. The bound is the full array size in bytes, INCLUDING
|
||||||
|
* the terminating NUL. On overflow the *_safe_ helpers do NOT truncate: they
|
||||||
|
* abort() (assertf). On success the result is always NUL-terminated.
|
||||||
|
*
|
||||||
|
* CRITICAL CAVEAT: if A is a bare char* pointer (not an array), sizeof(A) is
|
||||||
|
* the pointer size, not the buffer capacity. There is no way to recover the
|
||||||
|
* real capacity, so these macros SILENTLY DEGRADE to the unbounded raw
|
||||||
|
* strcpy()/strcat()/strncat() while still looking like a checked call. The
|
||||||
|
* bound is lost. On GCC/Clang (C) the pointer case routes through the
|
||||||
|
* *_ptr_ stubs above, which carry a 'warning' attribute to flag the site at
|
||||||
|
* compile time; on other compilers it is silent. When the destination is a
|
||||||
|
* pointer of known capacity, call the explicit-size strlcpybuff/strlcatbuff
|
||||||
|
* (passing the capacity, NUL included) instead.
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Append at most N characters from "B" to "A".
|
* Append at most N characters from "B" to "A".
|
||||||
* If "A" is a char[] variable whose size is not sizeof(char*), then the size
|
* If "A" is a char[] variable whose size is not sizeof(char*), then the size
|
||||||
* is assumed to be the capacity of this array.
|
* is assumed to be the capacity of this array.
|
||||||
*/
|
*/
|
||||||
#if (defined(__GNUC__) && !defined(__cplusplus))
|
#if (defined(__GNUC__) && !defined(__cplusplus))
|
||||||
#define strncatbuff(A, B, N) __builtin_choose_expr( HTS_IS_CHAR_BUFFER(A), \
|
|
||||||
strncat_safe_(A, sizeof(A), B, \
|
#define strncatbuff(A, B, N) \
|
||||||
HTS_IS_NOT_CHAR_BUFFER(B) ? (size_t) -1 : sizeof(B), N, \
|
__builtin_choose_expr( \
|
||||||
"overflow while appending '" #B "' to '"#A"'", __FILE__, __LINE__), \
|
HTS_IS_CHAR_BUFFER(A), \
|
||||||
strncatbuff_ptr_((A), (B), (N)) )
|
strncat_safe_(A, sizeof(A), B, \
|
||||||
|
HTS_IS_NOT_CHAR_BUFFER(B) ? (size_t) -1 : sizeof(B), N, \
|
||||||
|
"overflow while appending '" #B "' to '" #A "'", __FILE__, \
|
||||||
|
__LINE__), \
|
||||||
|
strncatbuff_ptr_((A), (B), (N)))
|
||||||
#else
|
#else
|
||||||
#define strncatbuff(A, B, N) \
|
#define strncatbuff(A, B, N) \
|
||||||
( HTS_IS_NOT_CHAR_BUFFER(A) \
|
(HTS_IS_NOT_CHAR_BUFFER(A) \
|
||||||
? strncat(A, B, N) \
|
? strncat(A, B, N) \
|
||||||
: strncat_safe_(A, sizeof(A), B, \
|
: strncat_safe_(A, sizeof(A), B, \
|
||||||
HTS_IS_NOT_CHAR_BUFFER(B) ? (size_t) -1 : sizeof(B), N, \
|
HTS_IS_NOT_CHAR_BUFFER(B) ? (size_t) -1 : sizeof(B), N, \
|
||||||
"overflow while appending '" #B "' to '"#A"'", __FILE__, __LINE__) )
|
"overflow while appending '" #B "' to '" #A "'", \
|
||||||
|
__FILE__, __LINE__))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Append characters of "B" to "A".
|
* Append characters of "B" to "A".
|
||||||
* If "A" is a char[] variable whose size is not sizeof(char*), then the size
|
* If "A" is a char[] variable whose size is not sizeof(char*), then the size
|
||||||
* is assumed to be the capacity of this array.
|
* is assumed to be the capacity of this array.
|
||||||
*/
|
*/
|
||||||
#if (defined(__GNUC__) && !defined(__cplusplus))
|
#if (defined(__GNUC__) && !defined(__cplusplus))
|
||||||
#define strcatbuff(A, B) __builtin_choose_expr( HTS_IS_CHAR_BUFFER(A), \
|
|
||||||
strncat_safe_(A, sizeof(A), B, \
|
#define strcatbuff(A, B) \
|
||||||
HTS_IS_NOT_CHAR_BUFFER(B) ? (size_t) -1 : sizeof(B), (size_t) -1, \
|
__builtin_choose_expr( \
|
||||||
"overflow while appending '" #B "' to '"#A"'", __FILE__, __LINE__), \
|
HTS_IS_CHAR_BUFFER(A), \
|
||||||
strcatbuff_ptr_((A), (B)) )
|
strncat_safe_(A, sizeof(A), B, \
|
||||||
|
HTS_IS_NOT_CHAR_BUFFER(B) ? (size_t) -1 : sizeof(B), \
|
||||||
|
(size_t) -1, \
|
||||||
|
"overflow while appending '" #B "' to '" #A "'", __FILE__, \
|
||||||
|
__LINE__), \
|
||||||
|
strcatbuff_ptr_((A), (B)))
|
||||||
#else
|
#else
|
||||||
#define strcatbuff(A, B) \
|
#define strcatbuff(A, B) \
|
||||||
( HTS_IS_NOT_CHAR_BUFFER(A) \
|
(HTS_IS_NOT_CHAR_BUFFER(A) \
|
||||||
? strcat(A, B) \
|
? strcat(A, B) \
|
||||||
: strncat_safe_(A, sizeof(A), B, \
|
: strncat_safe_(A, sizeof(A), B, \
|
||||||
HTS_IS_NOT_CHAR_BUFFER(B) ? (size_t) -1 : sizeof(B), (size_t) -1, \
|
HTS_IS_NOT_CHAR_BUFFER(B) ? (size_t) -1 : sizeof(B), \
|
||||||
"overflow while appending '" #B "' to '"#A"'", __FILE__, __LINE__) )
|
(size_t) -1, \
|
||||||
|
"overflow while appending '" #B "' to '" #A "'", \
|
||||||
|
__FILE__, __LINE__))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy characters from "B" to "A".
|
* Copy characters from "B" to "A".
|
||||||
* If "A" is a char[] variable whose size is not sizeof(char*), then the size
|
* If "A" is a char[] variable whose size is not sizeof(char*), then the size
|
||||||
* is assumed to be the capacity of this array.
|
* is assumed to be the capacity of this array.
|
||||||
*/
|
*/
|
||||||
#if (defined(__GNUC__) && !defined(__cplusplus))
|
#if (defined(__GNUC__) && !defined(__cplusplus))
|
||||||
#define strcpybuff(A, B) __builtin_choose_expr( HTS_IS_CHAR_BUFFER(A), \
|
|
||||||
strcpy_safe_(A, sizeof(A), B, \
|
#define strcpybuff(A, B) \
|
||||||
HTS_IS_NOT_CHAR_BUFFER(B) ? (size_t) -1 : sizeof(B), \
|
__builtin_choose_expr( \
|
||||||
"overflow while copying '" #B "' to '"#A"'", __FILE__, __LINE__), \
|
HTS_IS_CHAR_BUFFER(A), \
|
||||||
strcpybuff_ptr_((A), (B)) )
|
strcpy_safe_(A, sizeof(A), B, \
|
||||||
|
HTS_IS_NOT_CHAR_BUFFER(B) ? (size_t) -1 : sizeof(B), \
|
||||||
|
"overflow while copying '" #B "' to '" #A "'", __FILE__, \
|
||||||
|
__LINE__), \
|
||||||
|
strcpybuff_ptr_((A), (B)))
|
||||||
#else
|
#else
|
||||||
#define strcpybuff(A, B) \
|
#define strcpybuff(A, B) \
|
||||||
( HTS_IS_NOT_CHAR_BUFFER(A) \
|
(HTS_IS_NOT_CHAR_BUFFER(A) \
|
||||||
? strcpy(A, B) \
|
? strcpy(A, B) \
|
||||||
: strcpy_safe_(A, sizeof(A), B, \
|
: strcpy_safe_(A, sizeof(A), B, \
|
||||||
HTS_IS_NOT_CHAR_BUFFER(B) ? (size_t) -1 : sizeof(B), \
|
HTS_IS_NOT_CHAR_BUFFER(B) ? (size_t) -1 : sizeof(B), \
|
||||||
"overflow while copying '" #B "' to '"#A"'", __FILE__, __LINE__) )
|
"overflow while copying '" #B "' to '" #A "'", __FILE__, \
|
||||||
|
__LINE__))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Explicit-size variants (strlcatbuff/strlncatbuff/strlcpybuff): the
|
||||||
|
* destination capacity is the caller-supplied S (total bytes, NUL included),
|
||||||
|
* NOT derived from sizeof(A). Use these when A is a pointer or its capacity is
|
||||||
|
* not its sizeof. Same abort-on-overflow, always-NUL-terminated contract; no
|
||||||
|
* silent pointer degradation since the bound is passed in.
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Append characters of "B" to "A", "A" having a maximum capacity of "S".
|
* Append characters of "B" to "A", "A" having a maximum capacity of "S".
|
||||||
*/
|
*/
|
||||||
#define strlcatbuff(A, B, S) \
|
#define strlcatbuff(A, B, S) \
|
||||||
strncat_safe_(A, S, B, \
|
strncat_safe_(A, S, B, HTS_IS_NOT_CHAR_BUFFER(B) ? (size_t) -1 : sizeof(B), \
|
||||||
HTS_IS_NOT_CHAR_BUFFER(B) ? (size_t) -1 : sizeof(B), (size_t) -1, \
|
(size_t) -1, "overflow while appending '" #B "' to '" #A "'", \
|
||||||
"overflow while appending '" #B "' to '"#A"'", __FILE__, __LINE__)
|
__FILE__, __LINE__)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Append at most "N" characters of "B" to "A", "A" having a maximum capacity
|
* Append at most "N" characters of "B" to "A", "A" having a maximum capacity
|
||||||
@@ -249,34 +302,46 @@ static char *strncatbuff_ptr_(char *dest, const char *src, size_t n) {
|
|||||||
/**
|
/**
|
||||||
* Copy characters of "B" to "A", "A" having a maximum capacity of "S".
|
* Copy characters of "B" to "A", "A" having a maximum capacity of "S".
|
||||||
*/
|
*/
|
||||||
#define strlcpybuff(A, B, S) \
|
#define strlcpybuff(A, B, S) \
|
||||||
strcpy_safe_(A, S, B, \
|
strcpy_safe_(A, S, B, HTS_IS_NOT_CHAR_BUFFER(B) ? (size_t) -1 : sizeof(B), \
|
||||||
HTS_IS_NOT_CHAR_BUFFER(B) ? (size_t) -1 : sizeof(B), \
|
"overflow while copying '" #B "' to '" #A "'", __FILE__, \
|
||||||
"overflow while copying '" #B "' to '"#A"'", __FILE__, __LINE__)
|
__LINE__)
|
||||||
|
|
||||||
/** strnlen replacement (autotools). **/
|
/** strnlen replacement (autotools). **/
|
||||||
#if ( ! defined(_WIN32) && ! defined(HAVE_STRNLEN) )
|
#if (!defined(_WIN32) && !defined(HAVE_STRNLEN))
|
||||||
|
|
||||||
static HTS_UNUSED size_t strnlen(const char *s, size_t maxlen) {
|
static HTS_UNUSED size_t strnlen(const char *s, size_t maxlen) {
|
||||||
size_t i;
|
size_t i;
|
||||||
for(i = 0 ; i < maxlen && s[i] != '\0' ; i++) ;
|
for (i = 0; i < maxlen && s[i] != '\0'; i++)
|
||||||
|
;
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static HTS_INLINE HTS_UNUSED size_t strlen_safe_(const char *source, const size_t sizeof_source,
|
/* strlen of source, but bounded by sizeof_source (its capacity, NUL included).
|
||||||
|
Aborts if source is NULL or has no NUL within that capacity. The sentinel
|
||||||
|
sizeof_source == (size_t)-1 means "capacity unknown", and falls back to the
|
||||||
|
unbounded strlen (used when the source is a pointer rather than an array). */
|
||||||
|
static HTS_INLINE HTS_UNUSED size_t strlen_safe_(const char *source,
|
||||||
|
const size_t sizeof_source,
|
||||||
const char *file, int line) {
|
const char *file, int line) {
|
||||||
size_t size;
|
size_t size;
|
||||||
assertf_( source != NULL, file, line );
|
assertf_(source != NULL, file, line);
|
||||||
size = sizeof_source != (size_t) -1
|
size = sizeof_source != (size_t) -1 ? strnlen(source, sizeof_source)
|
||||||
? strnlen(source, sizeof_source) : strlen(source);
|
: strlen(source);
|
||||||
assertf_( size < sizeof_source, file, line );
|
assertf_(size < sizeof_source, file, line);
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HTS_INLINE HTS_UNUSED char* strncat_safe_(char *const dest, const size_t sizeof_dest,
|
/* Core bounded append. Appends min(strlen(source), n) bytes of source onto
|
||||||
const char *const source, const size_t sizeof_source,
|
dest. sizeof_dest is dest's total capacity (NUL included); sizeof_source is
|
||||||
const size_t n,
|
source's capacity or (size_t)-1 if unknown. Aborts if the result (existing
|
||||||
const char *exp, const char *file, int line) {
|
dest length + appended bytes + NUL) would not fit sizeof_dest: this NEVER
|
||||||
|
truncates. Always NUL-terminates on success. */
|
||||||
|
static HTS_INLINE HTS_UNUSED char *
|
||||||
|
strncat_safe_(char *const dest, const size_t sizeof_dest,
|
||||||
|
const char *const source, const size_t sizeof_source,
|
||||||
|
const size_t n, const char *exp, const char *file, int line) {
|
||||||
const size_t source_len = strlen_safe_(source, sizeof_source, file, line);
|
const size_t source_len = strlen_safe_(source, sizeof_source, file, line);
|
||||||
const size_t dest_len = strlen_safe_(dest, sizeof_dest, file, line);
|
const size_t dest_len = strlen_safe_(dest, sizeof_dest, file, line);
|
||||||
/* note: "size_t is an unsigned integral type" ((size_t) -1 is positive) */
|
/* note: "size_t is an unsigned integral type" ((size_t) -1 is positive) */
|
||||||
@@ -288,12 +353,17 @@ static HTS_INLINE HTS_UNUSED char* strncat_safe_(char *const dest, const size_t
|
|||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HTS_INLINE HTS_UNUSED char* strcpy_safe_(char *const dest, const size_t sizeof_dest,
|
/* Core bounded copy: empties dest then appends all of source via
|
||||||
const char *const source, const size_t sizeof_source,
|
strncat_safe_. sizeof_dest is dest's total capacity (NUL included). Aborts
|
||||||
const char *exp, const char *file, int line) {
|
(no truncation) if source plus its NUL would not fit. */
|
||||||
|
static HTS_INLINE HTS_UNUSED char *
|
||||||
|
strcpy_safe_(char *const dest, const size_t sizeof_dest,
|
||||||
|
const char *const source, const size_t sizeof_source,
|
||||||
|
const char *exp, const char *file, int line) {
|
||||||
assertf_(sizeof_dest != 0, file, line);
|
assertf_(sizeof_dest != 0, file, line);
|
||||||
dest[0] = '\0';
|
dest[0] = '\0';
|
||||||
return strncat_safe_(dest, sizeof_dest, source, sizeof_source, (size_t) -1, exp, file, line);
|
return strncat_safe_(dest, sizeof_dest, source, sizeof_source, (size_t) -1,
|
||||||
|
exp, file, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -311,9 +381,9 @@ static HTS_INLINE HTS_UNUSED char* strcpy_safe_(char *const dest, const size_t s
|
|||||||
* htsbuff_ptr(). The buffer is kept NUL-terminated; htsbuff_str() returns it.
|
* htsbuff_ptr(). The buffer is kept NUL-terminated; htsbuff_str() returns it.
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char *buf; /* backing buffer (kept NUL-terminated) */
|
char *buf; /* backing buffer (kept NUL-terminated) */
|
||||||
size_t cap; /* total capacity of buf, including the NUL */
|
size_t cap; /* total capacity of buf, including the NUL */
|
||||||
size_t len; /* current length, excluding the NUL */
|
size_t len; /* current length, excluding the NUL */
|
||||||
} htsbuff;
|
} htsbuff;
|
||||||
|
|
||||||
static HTS_INLINE HTS_UNUSED htsbuff htsbuff_ptr_(char *buf, size_t cap) {
|
static HTS_INLINE HTS_UNUSED htsbuff htsbuff_ptr_(char *buf, size_t cap) {
|
||||||
@@ -333,23 +403,31 @@ static HTS_INLINE HTS_UNUSED htsbuff htsbuff_ptr_(char *buf, size_t cap) {
|
|||||||
* On other compilers there is no such guard, so pass only true arrays there.
|
* On other compilers there is no such guard, so pass only true arrays there.
|
||||||
*/
|
*/
|
||||||
#if (defined(__GNUC__) && !defined(__cplusplus))
|
#if (defined(__GNUC__) && !defined(__cplusplus))
|
||||||
|
|
||||||
/* 0 for an array, a -1 array-size compile error for a pointer. */
|
/* 0 for an array, a -1 array-size compile error for a pointer. */
|
||||||
#define htsbuff_must_be_array_(A) \
|
#define htsbuff_must_be_array_(A) \
|
||||||
(sizeof(char[1 - 2 * !!__builtin_types_compatible_p(typeof(A), typeof(&(A)[0]))]) - 1)
|
(sizeof(char[1 - 2 * !!__builtin_types_compatible_p(typeof(A), \
|
||||||
#define htsbuff_array(ARR) htsbuff_ptr_((ARR), sizeof(ARR) + htsbuff_must_be_array_(ARR))
|
typeof(&(A)[0]))]) - \
|
||||||
|
1)
|
||||||
|
|
||||||
|
#define htsbuff_array(ARR) \
|
||||||
|
htsbuff_ptr_((ARR), sizeof(ARR) + htsbuff_must_be_array_(ARR))
|
||||||
#else
|
#else
|
||||||
#define htsbuff_array(ARR) htsbuff_ptr_((ARR), sizeof(ARR))
|
#define htsbuff_array(ARR) htsbuff_ptr_((ARR), sizeof(ARR))
|
||||||
#endif
|
#endif
|
||||||
/** Builder over pointer P of known capacity N (N includes the NUL). */
|
/** Builder over pointer P of known capacity N (N includes the NUL). */
|
||||||
#define htsbuff_ptr(P, N) htsbuff_ptr_((P), (N))
|
#define htsbuff_ptr(P, N) htsbuff_ptr_((P), (N))
|
||||||
|
|
||||||
/** Append at most n characters of s (stopping at its NUL). Aborts on overflow. */
|
/** Append at most n characters of s (stopping at its NUL). Aborts on overflow.
|
||||||
static HTS_INLINE HTS_UNUSED void htsbuff_catn(htsbuff *b, const char *s, size_t n) {
|
*/
|
||||||
|
static HTS_INLINE HTS_UNUSED void htsbuff_catn(htsbuff *b, const char *s,
|
||||||
|
size_t n) {
|
||||||
const size_t add = strnlen(s, n);
|
const size_t add = strnlen(s, n);
|
||||||
/* Overflow-safe: keep the (potentially huge) 'add' alone on one side. The
|
/* Overflow-safe: keep the (potentially huge) 'add' alone on one side. The
|
||||||
maintained invariant len < cap makes 'cap - len' >= 1 (no underflow), so
|
maintained invariant len < cap makes 'cap - len' >= 1 (no underflow), so
|
||||||
'add < cap - len' cannot wrap the way 'len + add < cap' could. */
|
'add < cap - len' cannot wrap the way 'len + add < cap' could. */
|
||||||
assertf__(add < b->cap - b->len, "htsbuff append overflow", __FILE__, __LINE__);
|
assertf__(add < b->cap - b->len, "htsbuff append overflow", __FILE__,
|
||||||
|
__LINE__);
|
||||||
memcpy(b->buf + b->len, s, add);
|
memcpy(b->buf + b->len, s, add);
|
||||||
b->len += add;
|
b->len += add;
|
||||||
b->buf[b->len] = '\0';
|
b->buf[b->len] = '\0';
|
||||||
@@ -378,11 +456,26 @@ static HTS_INLINE HTS_UNUSED const char *htsbuff_str(const htsbuff *b) {
|
|||||||
return b->buf;
|
return b->buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define malloct(A) malloc(A)
|
/* Thin aliases over the libc allocator/memcpy (historical "t" suffix); no
|
||||||
#define calloct(A,B) calloc((A), (B))
|
added bounds checking. freet() also NULLs the freed pointer and tolerates
|
||||||
#define freet(A) do { if ((A) != NULL) { free(A); (A) = NULL; } } while(0)
|
NULL. memcpybuff() despite the name is a raw memcpy: the caller owns the
|
||||||
#define strdupt(A) strdup(A)
|
bounds. */
|
||||||
#define realloct(A,B) realloc(A, B)
|
#define malloct(A) malloc(A)
|
||||||
|
|
||||||
|
#define calloct(A, B) calloc((A), (B))
|
||||||
|
|
||||||
|
#define freet(A) \
|
||||||
|
do { \
|
||||||
|
if ((A) != NULL) { \
|
||||||
|
free(A); \
|
||||||
|
(A) = NULL; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define strdupt(A) strdup(A)
|
||||||
|
|
||||||
|
#define realloct(A, B) realloc(A, B)
|
||||||
|
|
||||||
#define memcpybuff(A, B, N) memcpy((A), (B), (N))
|
#define memcpybuff(A, B, N) memcpy((A), (B), (N))
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
1293
src/htsselftest.c
Normal file
1293
src/htsselftest.c
Normal file
File diff suppressed because it is too large
Load Diff
52
src/htsselftest.h
Normal file
52
src/htsselftest.h
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/*
|
||||||
|
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: htsselftest.h */
|
||||||
|
/* named dispatch for the hidden engine self-tests */
|
||||||
|
/* Author: Xavier Roche */
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
|
||||||
|
#ifndef HTSSELFTEST_DEFH
|
||||||
|
#define HTSSELFTEST_DEFH
|
||||||
|
|
||||||
|
#ifdef HTS_INTERNAL_BYTECODE
|
||||||
|
|
||||||
|
#ifndef HTS_DEF_FWSTRUCT_httrackp
|
||||||
|
#define HTS_DEF_FWSTRUCT_httrackp
|
||||||
|
typedef struct httrackp httrackp;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Run engine self-test `name` over the positional args argv[0..argc-1], or list
|
||||||
|
the available tests when name is NULL, empty, or "list". Prints the result;
|
||||||
|
returns the process exit code (0 == success). The caller owns option cleanup.
|
||||||
|
Reached through the hidden `httrack -#test[=NAME ...]` subcommand. */
|
||||||
|
int hts_selftest(httrackp *opt, const char *name, int argc, char **argv);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -129,7 +129,8 @@ HTS_UNUSED static int linputsoc_t(T_SOC soc, char *s, int max, int timeout);
|
|||||||
HTS_UNUSED static int linput(FILE * fp, char *s, int max);
|
HTS_UNUSED static int linput(FILE * fp, char *s, int max);
|
||||||
|
|
||||||
/* Language files */
|
/* Language files */
|
||||||
HTS_UNUSED static int htslang_load(char *limit_to, const char *apppath);
|
HTS_UNUSED static int htslang_load(char *limit_to, size_t limit_size,
|
||||||
|
const char *apppath);
|
||||||
HTS_UNUSED static void conv_printf(const char *from, char *to);
|
HTS_UNUSED static void conv_printf(const char *from, char *to);
|
||||||
HTS_UNUSED static void LANG_DELETE(void);
|
HTS_UNUSED static void LANG_DELETE(void);
|
||||||
HTS_UNUSED static void LANG_INIT(const char *path);
|
HTS_UNUSED static void LANG_INIT(const char *path);
|
||||||
@@ -325,7 +326,7 @@ int smallserver(T_SOC soc, char *url, char *method, char *data, char *path) {
|
|||||||
|
|
||||||
/* Load strings */
|
/* Load strings */
|
||||||
htslang_init();
|
htslang_init();
|
||||||
if (!htslang_load(NULL, path)) {
|
if (!htslang_load(NULL, 0, path)) {
|
||||||
fprintf(stderr, "unable to find lang.def and/or lang/ strings in %s\n",
|
fprintf(stderr, "unable to find lang.def and/or lang/ strings in %s\n",
|
||||||
path);
|
path);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -511,7 +512,7 @@ int smallserver(T_SOC soc, char *url, char *method, char *data, char *path) {
|
|||||||
char *s = buffer;
|
char *s = buffer;
|
||||||
char *e, *f;
|
char *e, *f;
|
||||||
|
|
||||||
strcatbuff(buffer, "&");
|
strlcatbuff(buffer, "&", buffer_size);
|
||||||
while(s && (e = strchr(s, '=')) && (f = strchr(s, '&'))) {
|
while(s && (e = strchr(s, '=')) && (f = strchr(s, '&'))) {
|
||||||
const char *ua;
|
const char *ua;
|
||||||
String sua = STRING_EMPTY;
|
String sua = STRING_EMPTY;
|
||||||
@@ -935,7 +936,7 @@ int smallserver(T_SOC soc, char *url, char *method, char *data, char *path) {
|
|||||||
int listDefault = 0;
|
int listDefault = 0;
|
||||||
|
|
||||||
name[0] = '\0';
|
name[0] = '\0';
|
||||||
strncatbuff(name, str, n);
|
strlncatbuff(name, str, sizeof(name_), n);
|
||||||
|
|
||||||
if (strncmp(name, "/*", 2) == 0) {
|
if (strncmp(name, "/*", 2) == 0) {
|
||||||
/* comments */
|
/* comments */
|
||||||
@@ -1490,7 +1491,7 @@ int smallserver_setkeyarr(const char *key, int id, const char *key2, const char
|
|||||||
return coucal_write(NewLangList, tmp, (intptr_t) strdup(value));
|
return coucal_write(NewLangList, tmp, (intptr_t) strdup(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int htslang_load(char *limit_to, const char *path) {
|
static int htslang_load(char *limit_to, size_t limit_size, const char *path) {
|
||||||
const char *hashname;
|
const char *hashname;
|
||||||
char catbuff[CATBUFF_SIZE];
|
char catbuff[CATBUFF_SIZE];
|
||||||
|
|
||||||
@@ -1545,7 +1546,7 @@ static int htslang_load(char *limit_to, const char *path) {
|
|||||||
char *const buff = (char *) malloc(len + 1);
|
char *const buff = (char *) malloc(len + 1);
|
||||||
|
|
||||||
if (buff) {
|
if (buff) {
|
||||||
strcpybuff(buff, intkey);
|
strlcpybuff(buff, intkey, len + 1);
|
||||||
coucal_add(NewLangStrKeys, key, (intptr_t) buff);
|
coucal_add(NewLangStrKeys, key, (intptr_t) buff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1568,9 +1569,9 @@ static int htslang_load(char *limit_to, const char *path) {
|
|||||||
/* Get only language name */
|
/* Get only language name */
|
||||||
if (limit_to) {
|
if (limit_to) {
|
||||||
if (hashname)
|
if (hashname)
|
||||||
strcpybuff(limit_to, hashname);
|
strlcpybuff(limit_to, hashname, limit_size);
|
||||||
else
|
else
|
||||||
strcpybuff(limit_to, "???");
|
strlcpybuff(limit_to, "???", limit_size);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1750,7 +1751,7 @@ static void LANG_INIT(const char *path) {
|
|||||||
static int LANG_T(const char *path, int l) {
|
static int LANG_T(const char *path, int l) {
|
||||||
if (l >= 0) {
|
if (l >= 0) {
|
||||||
QLANG_T(l);
|
QLANG_T(l);
|
||||||
htslang_load(NULL, path);
|
htslang_load(NULL, 0, path);
|
||||||
}
|
}
|
||||||
return QLANG_T(-1); // 0=default (english)
|
return QLANG_T(-1); // 0=default (english)
|
||||||
}
|
}
|
||||||
@@ -1764,7 +1765,7 @@ static int LANG_SEARCH(const char *path, const char *iso) {
|
|||||||
do {
|
do {
|
||||||
QLANG_T(i);
|
QLANG_T(i);
|
||||||
strcpybuff(lang_str, "LANGUAGE_ISO");
|
strcpybuff(lang_str, "LANGUAGE_ISO");
|
||||||
htslang_load(lang_str, path);
|
htslang_load(lang_str, sizeof(lang_str), path);
|
||||||
if (strfield(iso, lang_str)) {
|
if (strfield(iso, lang_str)) {
|
||||||
found = i;
|
found = i;
|
||||||
}
|
}
|
||||||
@@ -1782,11 +1783,11 @@ static int LANG_LIST(const char *path, char *buffer, size_t buffer_size) {
|
|||||||
buffer[0] = '\0';
|
buffer[0] = '\0';
|
||||||
do {
|
do {
|
||||||
QLANG_T(i);
|
QLANG_T(i);
|
||||||
strlcpybuff(lang_str, "LANGUAGE_NAME", buffer_size);
|
strlcpybuff(lang_str, "LANGUAGE_NAME", sizeof(lang_str));
|
||||||
htslang_load(lang_str, path);
|
htslang_load(lang_str, sizeof(lang_str), path);
|
||||||
if (strlen(lang_str) > 0) {
|
if (strlen(lang_str) > 0) {
|
||||||
if (buffer[0])
|
if (buffer[0])
|
||||||
strcatbuff(buffer, "\n");
|
strlcatbuff(buffer, "\n", buffer_size);
|
||||||
strlcatbuff(buffer, lang_str, buffer_size);
|
strlcatbuff(buffer, lang_str, buffer_size);
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
|
|||||||
394
src/htsstrings.h
394
src/htsstrings.h
@@ -41,9 +41,11 @@ Please visit our Website: http://www.httrack.com
|
|||||||
/* GCC extension */
|
/* GCC extension */
|
||||||
#ifndef HTS_UNUSED
|
#ifndef HTS_UNUSED
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
#define HTS_UNUSED __attribute__ ((unused))
|
#define HTS_UNUSED __attribute__((unused))
|
||||||
#define HTS_STATIC static __attribute__ ((unused))
|
|
||||||
#define HTS_PRINTF_FUN(fmt, arg) __attribute__ ((format (printf, fmt, arg)))
|
#define HTS_STATIC static __attribute__((unused))
|
||||||
|
|
||||||
|
#define HTS_PRINTF_FUN(fmt, arg) __attribute__((format(printf, fmt, arg)))
|
||||||
#else
|
#else
|
||||||
#define HTS_UNUSED
|
#define HTS_UNUSED
|
||||||
#define HTS_STATIC static
|
#define HTS_STATIC static
|
||||||
@@ -58,6 +60,24 @@ typedef struct String String;
|
|||||||
#endif
|
#endif
|
||||||
#ifndef HTS_DEF_STRUCT_String
|
#ifndef HTS_DEF_STRUCT_String
|
||||||
#define HTS_DEF_STRUCT_String
|
#define HTS_DEF_STRUCT_String
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Growable owned string.
|
||||||
|
*
|
||||||
|
* Ownership/lifetime: the String owns buffer_ and frees it (StringFree).
|
||||||
|
* buffer_ is allocated lazily, so a freshly STRING_EMPTY/StringInit'd String,
|
||||||
|
* or one just StringFree'd/StringAcquire'd, has buffer_ == NULL and
|
||||||
|
* length_ == capacity_ == 0. Any growing operation may realloc, so a pointer
|
||||||
|
* obtained from StringBuff/StringBuffRW is invalidated by the next append,
|
||||||
|
* copy, or room request; do not cache it across such calls.
|
||||||
|
*
|
||||||
|
* Invariants when buffer_ != NULL: length_ < capacity_, and buffer_[length_]
|
||||||
|
* is a NUL (the content is always NUL-terminated). length_ excludes that NUL;
|
||||||
|
* capacity_ counts it. The empty state (buffer_ == NULL) has no readable NUL,
|
||||||
|
* so callers must not treat StringBuff() of an untouched String as "".
|
||||||
|
*
|
||||||
|
* Direct field access is internal (trailing underscore); use the macros below.
|
||||||
|
*/
|
||||||
struct String {
|
struct String {
|
||||||
char *buffer_;
|
char *buffer_;
|
||||||
size_t length_;
|
size_t length_;
|
||||||
@@ -67,7 +87,8 @@ struct String {
|
|||||||
|
|
||||||
/** Allocator **/
|
/** Allocator **/
|
||||||
#ifndef STRING_REALLOC
|
#ifndef STRING_REALLOC
|
||||||
#define STRING_REALLOC(BUFF, SIZE) ( (char*) realloc(BUFF, SIZE) )
|
#define STRING_REALLOC(BUFF, SIZE) ((char *) realloc(BUFF, SIZE))
|
||||||
|
|
||||||
#define STRING_FREE(BUFF) free(BUFF)
|
#define STRING_FREE(BUFF) free(BUFF)
|
||||||
#endif
|
#endif
|
||||||
#ifndef STRING_ASSERT
|
#ifndef STRING_ASSERT
|
||||||
@@ -75,140 +96,172 @@ struct String {
|
|||||||
#define STRING_ASSERT(EXP) assert(EXP)
|
#define STRING_ASSERT(EXP) assert(EXP)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** An empty string **/
|
/** Initializer for an empty String (NULL buffer). Use to declare or reset. **/
|
||||||
#define STRING_EMPTY { (char*) NULL, 0, 0 }
|
#define STRING_EMPTY {(char *) NULL, 0, 0}
|
||||||
|
|
||||||
/** String buffer **/
|
/** Read-only buffer pointer. NULL until the String has been written to.
|
||||||
#define StringBuff(BLK) ( (const char*) ((BLK).buffer_) )
|
Invalidated by any subsequent growing operation. **/
|
||||||
|
#define StringBuff(BLK) ((const char *) ((BLK).buffer_))
|
||||||
|
|
||||||
/** String buffer (read/write) **/
|
/** Read/write buffer pointer. Same NULL/invalidation rules as StringBuff. **/
|
||||||
#define StringBuffRW(BLK) ((BLK).buffer_)
|
#define StringBuffRW(BLK) ((BLK).buffer_)
|
||||||
|
|
||||||
/** String length **/
|
/** Current length in bytes, excluding the terminating NUL. **/
|
||||||
#define StringLength(BLK) ((BLK).length_)
|
#define StringLength(BLK) ((BLK).length_)
|
||||||
|
|
||||||
/** String not empty ? **/
|
/** Non-zero if the String holds at least one byte. **/
|
||||||
#define StringNotEmpty(BLK) ( StringLength(BLK) > 0 )
|
#define StringNotEmpty(BLK) (StringLength(BLK) > 0)
|
||||||
|
|
||||||
/** String capacity **/
|
/** Allocated capacity in bytes, including room for the terminating NUL. **/
|
||||||
#define StringCapacity(BLK) ((BLK).capacity_)
|
#define StringCapacity(BLK) ((BLK).capacity_)
|
||||||
|
|
||||||
/** Subcharacter **/
|
/** Byte at POS (read). No bounds check; POS must be < StringLength. **/
|
||||||
#define StringSub(BLK, POS) ( StringBuff(BLK)[POS] )
|
#define StringSub(BLK, POS) (StringBuff(BLK)[POS])
|
||||||
|
|
||||||
|
/** Byte at POS (read/write). No bounds check; POS must be < StringLength. **/
|
||||||
|
#define StringSubRW(BLK, POS) (StringBuffRW(BLK)[POS])
|
||||||
|
|
||||||
/** Subcharacter (read/write) **/
|
/** Subcharacter (read/write) **/
|
||||||
#define StringSubRW(BLK, POS) ( StringBuffRW(BLK)[POS] )
|
#define StringSubRW(BLK, POS) (StringBuffRW(BLK)[POS])
|
||||||
|
|
||||||
/** Subcharacter (read/write) **/
|
/** Byte POS positions from the end (read). POS==1 is the last byte. **/
|
||||||
#define StringSubRW(BLK, POS) ( StringBuffRW(BLK)[POS] )
|
#define StringRight(BLK, POS) (StringBuff(BLK)[StringLength(BLK) - POS])
|
||||||
|
|
||||||
/** Right subcharacter **/
|
/** Byte POS positions from the end (read/write). POS==1 is the last byte. **/
|
||||||
#define StringRight(BLK, POS) ( StringBuff(BLK)[StringLength(BLK) - POS] )
|
#define StringRightRW(BLK, POS) (StringBuffRW(BLK)[StringLength(BLK) - POS])
|
||||||
|
|
||||||
/** Right subcharacter (read/write) **/
|
/** Drop the last byte and re-terminate. Undefined if the String is empty
|
||||||
#define StringRightRW(BLK, POS) ( StringBuffRW(BLK)[StringLength(BLK) - POS] )
|
(no length check; would underflow). **/
|
||||||
|
#define StringPopRight(BLK) \
|
||||||
|
do { \
|
||||||
|
StringBuffRW(BLK)[--StringLength(BLK)] = '\0'; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
/** Remove the utter right character from the string. **/
|
/** Grow so capacity_ >= CAPACITY (total bytes, including the NUL). May realloc
|
||||||
#define StringPopRight(BLK) do { \
|
(invalidating prior buffer pointers); aborts via STRING_ASSERT on OOM.
|
||||||
StringBuffRW(BLK)[--StringLength(BLK)] = '\0'; \
|
Never shrinks. **/
|
||||||
} while(0)
|
#define StringRoomTotal(BLK, CAPACITY) \
|
||||||
|
do { \
|
||||||
|
const size_t capacity_ = (size_t) (CAPACITY); \
|
||||||
|
while ((BLK).capacity_ < capacity_) { \
|
||||||
|
if ((BLK).capacity_ < 16) { \
|
||||||
|
(BLK).capacity_ = 16; \
|
||||||
|
} else { \
|
||||||
|
(BLK).capacity_ *= 2; \
|
||||||
|
} \
|
||||||
|
(BLK).buffer_ = STRING_REALLOC((BLK).buffer_, (BLK).capacity_); \
|
||||||
|
STRING_ASSERT((BLK).buffer_ != NULL); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
/** Ensure the string is large enough for exactly CAPACITY bytes overall (including \0). **/
|
/** Reserve room for SIZE more bytes beyond the current length (plus the NUL).
|
||||||
#define StringRoomTotal(BLK, CAPACITY) do { \
|
May realloc, invalidating prior buffer pointers. **/
|
||||||
const size_t capacity_ = (size_t) (CAPACITY); \
|
#define StringRoom(BLK, SIZE) \
|
||||||
while ((BLK).capacity_ < capacity_) { \
|
StringRoomTotal(BLK, StringLength(BLK) + (SIZE) + 1)
|
||||||
if ((BLK).capacity_ < 16) { \
|
|
||||||
(BLK).capacity_ = 16; \
|
|
||||||
} else { \
|
|
||||||
(BLK).capacity_ *= 2; \
|
|
||||||
} \
|
|
||||||
(BLK).buffer_ = STRING_REALLOC((BLK).buffer_, (BLK).capacity_); \
|
|
||||||
STRING_ASSERT((BLK).buffer_ != NULL); \
|
|
||||||
} \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
/** Ensure the string is large enough for exactly SIZE more characters (not including \0). **/
|
/** Reserve room for SIZE more bytes and return the (post-realloc) RW buffer,
|
||||||
#define StringRoom(BLK, SIZE) StringRoomTotal(BLK, StringLength(BLK) + (SIZE) + 1)
|
for appending in place. Does not update length_; the caller must. **/
|
||||||
|
|
||||||
/** Return the RW buffer for a strcat() operation of at most SIZE characters. **/
|
|
||||||
#define StringBuffN(BLK, SIZE) StringBuffN_(&(BLK), SIZE)
|
#define StringBuffN(BLK, SIZE) StringBuffN_(&(BLK), SIZE)
|
||||||
HTS_STATIC char *StringBuffN_(String * blk, int size) {
|
|
||||||
|
HTS_STATIC char *StringBuffN_(String *blk, int size) {
|
||||||
StringRoom(*blk, size);
|
StringRoom(*blk, size);
|
||||||
return StringBuffRW(*blk);
|
return StringBuffRW(*blk);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Initialize a string. **/
|
/** Zero the fields (NULL buffer, no allocation). Use on an uninitialized
|
||||||
#define StringInit(BLK) do { \
|
String only; does NOT free an existing buffer (use StringFree to reset
|
||||||
(BLK).buffer_ = NULL; \
|
an owned one), so calling it on a live String leaks. **/
|
||||||
(BLK).capacity_ = 0; \
|
#define StringInit(BLK) \
|
||||||
(BLK).length_ = 0; \
|
do { \
|
||||||
} while(0)
|
(BLK).buffer_ = NULL; \
|
||||||
|
(BLK).capacity_ = 0; \
|
||||||
|
(BLK).length_ = 0; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
/** Clear a string (set its length to 0) **/
|
/** Truncate to length 0, keeping the allocation. Forces a non-NULL buffer
|
||||||
#define StringClear(BLK) do { \
|
(allocates if empty) and writes the leading NUL, so StringBuff is "". **/
|
||||||
(BLK).length_ = 0; \
|
#define StringClear(BLK) \
|
||||||
StringRoom(BLK, 0); \
|
do { \
|
||||||
(BLK).buffer_[0] = '\0'; \
|
(BLK).length_ = 0; \
|
||||||
} while(0)
|
StringRoom(BLK, 0); \
|
||||||
|
(BLK).buffer_[0] = '\0'; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
/** Set the length of a string to 'SIZE'. If SIZE is negative, check the size using strlen(). **/
|
/** Set length_ to SIZE, or to strlen(buffer_) if SIZE is negative. Caller
|
||||||
#define StringSetLength(BLK, SIZE) do { \
|
asserts SIZE fits the existing content; does not (re)allocate. **/
|
||||||
if (SIZE >= 0) { \
|
#define StringSetLength(BLK, SIZE) \
|
||||||
(BLK).length_ = SIZE; \
|
do { \
|
||||||
} else { \
|
if (SIZE >= 0) { \
|
||||||
(BLK).length_ = strlen((BLK).buffer_); \
|
(BLK).length_ = SIZE; \
|
||||||
} \
|
} else { \
|
||||||
} while(0)
|
(BLK).length_ = strlen((BLK).buffer_); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
/** Free a string (release memory) **/
|
/** Release the owned buffer and reset to the empty state (NULL buffer).
|
||||||
#define StringFree(BLK) do { \
|
Idempotent; safe on an already-empty String. **/
|
||||||
if ((BLK).buffer_ != NULL) { \
|
#define StringFree(BLK) \
|
||||||
STRING_FREE((BLK).buffer_); \
|
do { \
|
||||||
(BLK).buffer_ = NULL; \
|
if ((BLK).buffer_ != NULL) { \
|
||||||
} \
|
STRING_FREE((BLK).buffer_); \
|
||||||
(BLK).capacity_ = 0; \
|
(BLK).buffer_ = NULL; \
|
||||||
(BLK).length_ = 0; \
|
} \
|
||||||
} while(0)
|
(BLK).capacity_ = 0; \
|
||||||
|
(BLK).length_ = 0; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
/** Assign an allocated pointer to a a string.
|
/** Take ownership of a NUL-terminated heap string STR (the String will free
|
||||||
The pointer _MUST_ be compatible with STRING_REALLOC() and STRING_FREE() **/
|
it). Frees any current buffer first. STR MUST have been allocated by an
|
||||||
#define StringSetBuffer(BLK, STR) do { \
|
allocator compatible with STRING_REALLOC()/STRING_FREE(), and must not be
|
||||||
size_t len__ = strlen( STR ); \
|
freed or used by the caller afterwards. length_/capacity_ are set to
|
||||||
StringFree(BLK); \
|
strlen(STR) (capacity_ here excludes the NUL, so the next append reallocs).
|
||||||
(BLK).buffer_ = ( STR ); \
|
**/
|
||||||
(BLK).capacity_ = len__; \
|
#define StringSetBuffer(BLK, STR) \
|
||||||
(BLK).length_ = len__; \
|
do { \
|
||||||
} while(0)
|
size_t len__ = strlen(STR); \
|
||||||
|
StringFree(BLK); \
|
||||||
|
(BLK).buffer_ = (STR); \
|
||||||
|
(BLK).capacity_ = len__; \
|
||||||
|
(BLK).length_ = len__; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
/** Append a memory block to a string **/
|
/** Append SIZE raw bytes from STR (NULs allowed as data). Grows as needed and
|
||||||
#define StringMemcat(BLK, STR, SIZE) do { \
|
re-terminates with a NUL after the appended bytes. STR must not alias
|
||||||
const char* str_mc_ = (STR); \
|
BLK's buffer (a realloc would invalidate it). **/
|
||||||
const size_t size_mc_ = (size_t) (SIZE); \
|
#define StringMemcat(BLK, STR, SIZE) \
|
||||||
StringRoom(BLK, size_mc_); \
|
do { \
|
||||||
if (size_mc_ > 0) { \
|
const char *str_mc_ = (STR); \
|
||||||
memcpy((BLK).buffer_ + (BLK).length_, str_mc_, size_mc_); \
|
const size_t size_mc_ = (size_t) (SIZE); \
|
||||||
(BLK).length_ += size_mc_; \
|
StringRoom(BLK, size_mc_); \
|
||||||
} \
|
if (size_mc_ > 0) { \
|
||||||
*((BLK).buffer_ + (BLK).length_) = '\0'; \
|
memcpy((BLK).buffer_ + (BLK).length_, str_mc_, size_mc_); \
|
||||||
} while(0)
|
(BLK).length_ += size_mc_; \
|
||||||
|
} \
|
||||||
|
*((BLK).buffer_ + (BLK).length_) = '\0'; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
/** Copy a memory block to a string **/
|
/** Replace content with SIZE raw bytes from STR (NULs allowed as data).
|
||||||
#define StringMemcpy(BLK, STR, SIZE) do { \
|
Same non-aliasing requirement as StringMemcat. **/
|
||||||
(BLK).length_ = 0; \
|
#define StringMemcpy(BLK, STR, SIZE) \
|
||||||
StringMemcat(BLK, STR, SIZE); \
|
do { \
|
||||||
} while(0)
|
(BLK).length_ = 0; \
|
||||||
|
StringMemcat(BLK, STR, SIZE); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
/** Add a character **/
|
/** Append one byte and re-terminate. Grows as needed. **/
|
||||||
#define StringAddchar(BLK, c) do { \
|
#define StringAddchar(BLK, c) \
|
||||||
String * const s__ = &(BLK); \
|
do { \
|
||||||
char c__ = (c); \
|
String *const s__ = &(BLK); \
|
||||||
StringRoom(*s__, 1); \
|
char c__ = (c); \
|
||||||
StringBuffRW(*s__)[StringLength(*s__)++] = c__; \
|
StringRoom(*s__, 1); \
|
||||||
StringBuffRW(*s__)[StringLength(*s__) ] = 0; \
|
StringBuffRW(*s__)[StringLength(*s__)++] = c__; \
|
||||||
} while(0)
|
StringBuffRW(*s__)[StringLength(*s__)] = 0; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
/** Acquire a string ; it's the client's responsability to free() it **/
|
/** Hand the buffer to the caller and reset the String to empty (NULL buffer).
|
||||||
HTS_STATIC char *StringAcquire(String * blk) {
|
The returned pointer is now owned by the caller, who must STRING_FREE() it.
|
||||||
|
Returns NULL if the String was empty. **/
|
||||||
|
HTS_STATIC char *StringAcquire(String *blk) {
|
||||||
char *buff = StringBuffRW(*blk);
|
char *buff = StringBuffRW(*blk);
|
||||||
|
|
||||||
StringBuffRW(*blk) = NULL;
|
StringBuffRW(*blk) = NULL;
|
||||||
@@ -217,16 +270,20 @@ HTS_STATIC char *StringAcquire(String * blk) {
|
|||||||
return buff;
|
return buff;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Clone a string. **/
|
/** Return an independent deep copy of *src (its own allocation). The caller
|
||||||
HTS_STATIC String StringDup(const String * src) {
|
owns the result and must StringFree it. **/
|
||||||
|
HTS_STATIC String StringDup(const String *src) {
|
||||||
String s = STRING_EMPTY;
|
String s = STRING_EMPTY;
|
||||||
|
|
||||||
StringMemcat(s, StringBuff(*src), StringLength(*src));
|
StringMemcat(s, StringBuff(*src), StringLength(*src));
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Attach a string using a pointer. **/
|
/** Take ownership of *str (a NUL-terminated heap string) and NULL it out, so
|
||||||
HTS_STATIC void StringAttach(String * blk, char **str) {
|
ownership transfers and the caller keeps no dangling alias. Frees any
|
||||||
|
current buffer first. *str MUST be allocator-compatible (see
|
||||||
|
StringSetBuffer). No-op if str or *str is NULL. **/
|
||||||
|
HTS_STATIC void StringAttach(String *blk, char **str) {
|
||||||
StringFree(*blk);
|
StringFree(*blk);
|
||||||
if (str != NULL && *str != NULL) {
|
if (str != NULL && *str != NULL) {
|
||||||
StringBuffRW(*blk) = *str;
|
StringBuffRW(*blk) = *str;
|
||||||
@@ -235,60 +292,75 @@ HTS_STATIC void StringAttach(String * blk, char **str) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Append a string to another one. **/
|
/** Append the C string STR (up to its NUL). No-op if STR is NULL. STR must not
|
||||||
#define StringCat(BLK, STR) do { \
|
alias BLK's buffer. **/
|
||||||
const char *const str__ = ( STR ); \
|
#define StringCat(BLK, STR) \
|
||||||
if (str__ != NULL) { \
|
do { \
|
||||||
const size_t size__ = strlen(str__); \
|
const char *const str__ = (STR); \
|
||||||
StringMemcat(BLK, str__, size__); \
|
if (str__ != NULL) { \
|
||||||
} \
|
const size_t size__ = strlen(str__); \
|
||||||
} while(0)
|
StringMemcat(BLK, str__, size__); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#define StringCatN(BLK, STR, SIZE) do { \
|
/** Append at most SIZE leading bytes of the C string STR. No-op if STR is
|
||||||
const char *str__ = ( STR ); \
|
NULL. STR must not alias BLK's buffer. **/
|
||||||
if (str__ != NULL) { \
|
#define StringCatN(BLK, STR, SIZE) \
|
||||||
size_t size__ = strlen(str__); \
|
do { \
|
||||||
if (size__ > (SIZE)) { \
|
const char *str__ = (STR); \
|
||||||
size__ = (SIZE); \
|
if (str__ != NULL) { \
|
||||||
} \
|
size_t size__ = strlen(str__); \
|
||||||
StringMemcat(BLK, str__, size__); \
|
if (size__ > (SIZE)) { \
|
||||||
} \
|
size__ = (SIZE); \
|
||||||
} while(0)
|
} \
|
||||||
|
StringMemcat(BLK, str__, size__); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#define StringCopyN(BLK, STR, SIZE) do { \
|
/** Replace content with at most SIZE leading bytes of the C string STR.
|
||||||
const char *str__ = ( STR ); \
|
If STR is NULL, clears to "". STR must not alias BLK's buffer. **/
|
||||||
const size_t usize__ = (SIZE); \
|
#define StringCopyN(BLK, STR, SIZE) \
|
||||||
(BLK).length_ = 0; \
|
do { \
|
||||||
if (str__ != NULL) { \
|
const char *str__ = (STR); \
|
||||||
size_t size__ = strlen(str__); \
|
const size_t usize__ = (SIZE); \
|
||||||
if (size__ > usize__ ) { \
|
(BLK).length_ = 0; \
|
||||||
size__ = usize__; \
|
if (str__ != NULL) { \
|
||||||
} \
|
size_t size__ = strlen(str__); \
|
||||||
StringMemcat(BLK, str__, size__); \
|
if (size__ > usize__) { \
|
||||||
} else { \
|
size__ = usize__; \
|
||||||
StringClear(BLK); \
|
} \
|
||||||
} \
|
StringMemcat(BLK, str__, size__); \
|
||||||
} while(0)
|
} else { \
|
||||||
|
StringClear(BLK); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/** Replace blk's content with a copy of String blk2. blk and blk2 must be
|
||||||
|
distinct Strings (use StringCopyOverlapped if they may be the same). **/
|
||||||
#define StringCopyS(blk, blk2) StringCopyN(blk, (blk2).buffer_, (blk2).length_)
|
#define StringCopyS(blk, blk2) StringCopyN(blk, (blk2).buffer_, (blk2).length_)
|
||||||
|
|
||||||
/** Copy a string to another one. **/
|
/** Replace content with a copy of the C string STR. If STR is NULL, clears to
|
||||||
#define StringCopy(BLK, STR) do { \
|
"". STR must not alias BLK's buffer (use StringCopyOverlapped if it might).
|
||||||
const char *str__ = ( STR ); \
|
**/
|
||||||
if (str__ != NULL) { \
|
#define StringCopy(BLK, STR) \
|
||||||
size_t size__ = strlen(str__); \
|
do { \
|
||||||
StringMemcpy(BLK, str__, size__); \
|
const char *str__ = (STR); \
|
||||||
} else { \
|
if (str__ != NULL) { \
|
||||||
StringClear(BLK); \
|
size_t size__ = strlen(str__); \
|
||||||
} \
|
StringMemcpy(BLK, str__, size__); \
|
||||||
} while(0)
|
} else { \
|
||||||
|
StringClear(BLK); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
/** Copy a (potentially overlapping) string to another one. **/
|
/** Like StringCopy but safe when STR aliases BLK's own buffer: copies via a
|
||||||
#define StringCopyOverlapped(BLK, STR) do { \
|
temporary, so a self-copy or overlap is well-defined. **/
|
||||||
String s__ = STRING_EMPTY; \
|
#define StringCopyOverlapped(BLK, STR) \
|
||||||
StringCopy(s__, STR); \
|
do { \
|
||||||
StringCopyS(BLK, s__); \
|
String s__ = STRING_EMPTY; \
|
||||||
StringFree(s__); \
|
StringCopy(s__, STR); \
|
||||||
} while(0)
|
StringCopyS(BLK, s__); \
|
||||||
|
StringFree(s__); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1213,7 +1213,7 @@ HTSEXT_API find_handle hts_findfirst(char *path) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
HTSEXT_API int hts_findnext(find_handle find) {
|
HTSEXT_API hts_boolean hts_findnext(find_handle find) {
|
||||||
if (find) {
|
if (find) {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if ((FindNextFileA(find->handle, &find->hdata)))
|
if ((FindNextFileA(find->handle, &find->hdata)))
|
||||||
@@ -1273,7 +1273,7 @@ HTSEXT_API int hts_findgetsize(find_handle find) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
HTSEXT_API int hts_findisdir(find_handle find) {
|
HTSEXT_API hts_boolean hts_findisdir(find_handle find) {
|
||||||
if (find) {
|
if (find) {
|
||||||
if (!hts_findissystem(find)) {
|
if (!hts_findissystem(find)) {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@@ -1287,7 +1287,7 @@ HTSEXT_API int hts_findisdir(find_handle find) {
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
HTSEXT_API int hts_findisfile(find_handle find) {
|
HTSEXT_API hts_boolean hts_findisfile(find_handle find) {
|
||||||
if (find) {
|
if (find) {
|
||||||
if (!hts_findissystem(find)) {
|
if (!hts_findissystem(find)) {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@@ -1301,7 +1301,7 @@ HTSEXT_API int hts_findisfile(find_handle find) {
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
HTSEXT_API int hts_findissystem(find_handle find) {
|
HTSEXT_API hts_boolean hts_findissystem(find_handle find) {
|
||||||
if (find) {
|
if (find) {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if (find->hdata.
|
if (find->hdata.
|
||||||
|
|||||||
@@ -108,15 +108,15 @@ HTSEXT_API int hts_buildtopindex(httrackp * opt, const char *path,
|
|||||||
// Portable directory find functions
|
// Portable directory find functions
|
||||||
// Directory find functions
|
// Directory find functions
|
||||||
HTSEXT_API find_handle hts_findfirst(char *path);
|
HTSEXT_API find_handle hts_findfirst(char *path);
|
||||||
HTSEXT_API int hts_findnext(find_handle find);
|
HTSEXT_API hts_boolean hts_findnext(find_handle find);
|
||||||
HTSEXT_API int hts_findclose(find_handle find);
|
HTSEXT_API int hts_findclose(find_handle find);
|
||||||
|
|
||||||
//
|
//
|
||||||
HTSEXT_API char *hts_findgetname(find_handle find);
|
HTSEXT_API char *hts_findgetname(find_handle find);
|
||||||
HTSEXT_API int hts_findgetsize(find_handle find);
|
HTSEXT_API int hts_findgetsize(find_handle find);
|
||||||
HTSEXT_API int hts_findisdir(find_handle find);
|
HTSEXT_API hts_boolean hts_findisdir(find_handle find);
|
||||||
HTSEXT_API int hts_findisfile(find_handle find);
|
HTSEXT_API hts_boolean hts_findisfile(find_handle find);
|
||||||
HTSEXT_API int hts_findissystem(find_handle find);
|
HTSEXT_API hts_boolean hts_findissystem(find_handle find);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
158
src/htswizard.c
158
src/htswizard.c
@@ -178,7 +178,7 @@ static int hts_acceptlink_(httrackp * opt, int ptr,
|
|||||||
// -------------------- PHASE 1 --------------------
|
// -------------------- PHASE 1 --------------------
|
||||||
|
|
||||||
/* Doit-on traiter les non html? */
|
/* Doit-on traiter les non html? */
|
||||||
if ((opt->getmode & 2) == 0) { // non on ne doit pas
|
if ((opt->getmode & HTS_GETMODE_NONHTML) == 0) { // non on ne doit pas
|
||||||
if (!ishtml(opt, fil)) { // non il ne faut pas
|
if (!ishtml(opt, fil)) { // non il ne faut pas
|
||||||
//adr[0]='\0'; // ne pas traiter ce lien, pas traiter
|
//adr[0]='\0'; // ne pas traiter ce lien, pas traiter
|
||||||
forbidden_url = 1; // interdire récupération du lien
|
forbidden_url = 1; // interdire récupération du lien
|
||||||
@@ -266,11 +266,11 @@ static int hts_acceptlink_(httrackp * opt, int ptr,
|
|||||||
test2 =
|
test2 =
|
||||||
(strchr(tempo2 + ((*tempo2 == '/') ? 1 : 0), '/') != NULL);
|
(strchr(tempo2 + ((*tempo2 == '/') ? 1 : 0), '/') != NULL);
|
||||||
if ((test1) && (test2)) { // on ne peut que descendre
|
if ((test1) && (test2)) { // on ne peut que descendre
|
||||||
if ((opt->seeker & 1) == 0) { // interdiction de descendre
|
if ((opt->seeker & HTS_SEEKER_DOWN) == 0) {
|
||||||
forbidden_url = 1;
|
forbidden_url = 1;
|
||||||
hts_log_print(opt, LOG_DEBUG, "lower link canceled: %s%s", adr,
|
hts_log_print(opt, LOG_DEBUG, "lower link canceled: %s%s", adr,
|
||||||
fil);
|
fil);
|
||||||
} else { // autorisé à priori - NEW
|
} else { // autorisé à priori - NEW
|
||||||
if (!heap(ptr)->link_import) { // ne résulte pas d'un 'moved'
|
if (!heap(ptr)->link_import) { // ne résulte pas d'un 'moved'
|
||||||
forbidden_url = 0;
|
forbidden_url = 0;
|
||||||
hts_log_print(opt, LOG_DEBUG, "lower link authorized: %s%s",
|
hts_log_print(opt, LOG_DEBUG, "lower link authorized: %s%s",
|
||||||
@@ -278,7 +278,7 @@ static int hts_acceptlink_(httrackp * opt, int ptr,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if ((test1) || (test2)) { // on peut descendre pour accéder au lien
|
} else if ((test1) || (test2)) { // on peut descendre pour accéder au lien
|
||||||
if ((opt->seeker & 1) != 0) { // on peut descendre - NEW
|
if ((opt->seeker & HTS_SEEKER_DOWN) != 0) {
|
||||||
if (!heap(ptr)->link_import) { // ne résulte pas d'un 'moved'
|
if (!heap(ptr)->link_import) { // ne résulte pas d'un 'moved'
|
||||||
forbidden_url = 0;
|
forbidden_url = 0;
|
||||||
hts_log_print(opt, LOG_DEBUG, "lower link authorized: %s%s",
|
hts_log_print(opt, LOG_DEBUG, "lower link authorized: %s%s",
|
||||||
@@ -290,11 +290,11 @@ static int hts_acceptlink_(httrackp * opt, int ptr,
|
|||||||
|
|
||||||
// up
|
// up
|
||||||
if ((!strncmp(tempo, "../", 3)) && (!strncmp(tempo2, "../", 3))) { // impossible sans monter
|
if ((!strncmp(tempo, "../", 3)) && (!strncmp(tempo2, "../", 3))) { // impossible sans monter
|
||||||
if ((opt->seeker & 2) == 0) { // interdiction de monter
|
if ((opt->seeker & HTS_SEEKER_UP) == 0) {
|
||||||
forbidden_url = 1;
|
forbidden_url = 1;
|
||||||
hts_log_print(opt, LOG_DEBUG, "upper link canceled: %s%s", adr,
|
hts_log_print(opt, LOG_DEBUG, "upper link canceled: %s%s", adr,
|
||||||
fil);
|
fil);
|
||||||
} else { // autorisé à monter - NEW
|
} else { // autorisé à monter - NEW
|
||||||
if (!heap(ptr)->link_import) { // ne résulte pas d'un 'moved'
|
if (!heap(ptr)->link_import) { // ne résulte pas d'un 'moved'
|
||||||
forbidden_url = 0;
|
forbidden_url = 0;
|
||||||
hts_log_print(opt, LOG_DEBUG, "upper link authorized: %s%s",
|
hts_log_print(opt, LOG_DEBUG, "upper link authorized: %s%s",
|
||||||
@@ -302,13 +302,13 @@ static int hts_acceptlink_(httrackp * opt, int ptr,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if ((!strncmp(tempo, "../", 3)) || (!strncmp(tempo2, "../", 3))) { // Possible en montant
|
} else if ((!strncmp(tempo, "../", 3)) || (!strncmp(tempo2, "../", 3))) { // Possible en montant
|
||||||
if ((opt->seeker & 2) != 0) { // autorisé à monter - NEW
|
if ((opt->seeker & HTS_SEEKER_UP) != 0) {
|
||||||
if (!heap(ptr)->link_import) { // ne résulte pas d'un 'moved'
|
if (!heap(ptr)->link_import) { // ne résulte pas d'un 'moved'
|
||||||
forbidden_url = 0;
|
forbidden_url = 0;
|
||||||
hts_log_print(opt, LOG_DEBUG, "upper link authorized: %s%s",
|
hts_log_print(opt, LOG_DEBUG, "upper link authorized: %s%s",
|
||||||
adr, fil);
|
adr, fil);
|
||||||
}
|
}
|
||||||
} // sinon autorisé en descente
|
} // sinon autorisé en descente
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@@ -345,83 +345,81 @@ static int hts_acceptlink_(httrackp * opt, int ptr,
|
|||||||
|
|
||||||
//if (!opt->wizard) { // mode non wizard
|
//if (!opt->wizard) { // mode non wizard
|
||||||
// doit-on traiter ce lien?.. vérifier droits de sortie
|
// doit-on traiter ce lien?.. vérifier droits de sortie
|
||||||
switch ((opt->travel & 255)) {
|
switch ((opt->travel & HTS_TRAVEL_SCOPE_MASK)) {
|
||||||
case 0:
|
case HTS_TRAVEL_SAME_ADDRESS:
|
||||||
if (!opt->wizard) // mode non wizard
|
if (!opt->wizard) // mode non wizard
|
||||||
forbidden_url = 1;
|
forbidden_url = 1;
|
||||||
break; // interdicton de sortir au dela de l'adresse
|
break; // interdicton de sortir au dela de l'adresse
|
||||||
case 1:{ // sortie sur le même dom.xxx
|
case HTS_TRAVEL_SAME_DOMAIN: {
|
||||||
size_t i = strlen(adr) - 1;
|
size_t i = strlen(adr) - 1;
|
||||||
size_t j = strlen(urladr()) - 1;
|
size_t j = strlen(urladr()) - 1;
|
||||||
|
|
||||||
if ((i > 0) && (j > 0)) {
|
if ((i > 0) && (j > 0)) {
|
||||||
while((i > 0) && (adr[i] != '.'))
|
while ((i > 0) && (adr[i] != '.'))
|
||||||
i--;
|
|
||||||
while((j > 0) && (urladr()[j] != '.'))
|
|
||||||
j--;
|
|
||||||
if ((i > 0) && (j > 0)) {
|
|
||||||
i--;
|
|
||||||
j--;
|
|
||||||
while((i > 0) && (adr[i] != '.'))
|
|
||||||
i--;
|
|
||||||
while((j > 0) && (urladr()[j] != '.'))
|
|
||||||
j--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((i > 0) && (j > 0)) {
|
|
||||||
if (!strfield2(adr + i, urladr() + j)) { // !=
|
|
||||||
if (!opt->wizard) { // mode non wizard
|
|
||||||
//printf("refused: %s\n",adr);
|
|
||||||
forbidden_url = 1; // pas même domaine
|
|
||||||
hts_log_print(opt, LOG_DEBUG,
|
|
||||||
"foreign domain link canceled: %s%s", adr, fil);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
if (opt->wizard) { // mode wizard
|
|
||||||
forbidden_url = 0; // même domaine
|
|
||||||
hts_log_print(opt, LOG_DEBUG, "same domain link authorized: %s%s",
|
|
||||||
adr, fil);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else
|
|
||||||
forbidden_url = 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 2:{ // sortie sur le même .xxx
|
|
||||||
size_t i = strlen(adr) - 1;
|
|
||||||
size_t j = strlen(urladr()) - 1;
|
|
||||||
|
|
||||||
while((i > 0) && (adr[i] != '.'))
|
|
||||||
i--;
|
i--;
|
||||||
while((j > 0) && (urladr()[j] != '.'))
|
while ((j > 0) && (urladr()[j] != '.'))
|
||||||
j--;
|
j--;
|
||||||
if ((i > 0) && (j > 0)) {
|
if ((i > 0) && (j > 0)) {
|
||||||
if (!strfield2(adr + i, urladr() + j)) { // !-
|
i--;
|
||||||
if (!opt->wizard) { // mode non wizard
|
j--;
|
||||||
//printf("refused: %s\n",adr);
|
while ((i > 0) && (adr[i] != '.'))
|
||||||
forbidden_url = 1; // pas même .xx
|
i--;
|
||||||
hts_log_print(opt, LOG_DEBUG,
|
while ((j > 0) && (urladr()[j] != '.'))
|
||||||
"foreign location link canceled: %s%s", adr, fil);
|
j--;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if (opt->wizard) { // mode wizard
|
|
||||||
forbidden_url = 0; // même domaine
|
|
||||||
hts_log_print(opt, LOG_DEBUG,
|
|
||||||
"same location link authorized: %s%s", adr, fil);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
forbidden_url = 1;
|
|
||||||
}
|
}
|
||||||
break;
|
if ((i > 0) && (j > 0)) {
|
||||||
case 7: // everywhere!!
|
if (!strfield2(adr + i, urladr() + j)) { // !=
|
||||||
|
if (!opt->wizard) { // mode non wizard
|
||||||
|
// printf("refused: %s\n",adr);
|
||||||
|
forbidden_url = 1; // pas même domaine
|
||||||
|
hts_log_print(opt, LOG_DEBUG, "foreign domain link canceled: %s%s",
|
||||||
|
adr, fil);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (opt->wizard) { // mode wizard
|
||||||
|
forbidden_url = 0; // même domaine
|
||||||
|
hts_log_print(opt, LOG_DEBUG, "same domain link authorized: %s%s",
|
||||||
|
adr, fil);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else
|
||||||
|
forbidden_url = 1;
|
||||||
|
} break;
|
||||||
|
case HTS_TRAVEL_SAME_TLD: {
|
||||||
|
size_t i = strlen(adr) - 1;
|
||||||
|
size_t j = strlen(urladr()) - 1;
|
||||||
|
|
||||||
|
while ((i > 0) && (adr[i] != '.'))
|
||||||
|
i--;
|
||||||
|
while ((j > 0) && (urladr()[j] != '.'))
|
||||||
|
j--;
|
||||||
|
if ((i > 0) && (j > 0)) {
|
||||||
|
if (!strfield2(adr + i, urladr() + j)) { // !-
|
||||||
|
if (!opt->wizard) { // mode non wizard
|
||||||
|
// printf("refused: %s\n",adr);
|
||||||
|
forbidden_url = 1; // pas même .xx
|
||||||
|
hts_log_print(opt, LOG_DEBUG,
|
||||||
|
"foreign location link canceled: %s%s", adr, fil);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (opt->wizard) { // mode wizard
|
||||||
|
forbidden_url = 0; // même domaine
|
||||||
|
hts_log_print(opt, LOG_DEBUG, "same location link authorized: %s%s",
|
||||||
|
adr, fil);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
forbidden_url = 1;
|
||||||
|
} break;
|
||||||
|
case HTS_TRAVEL_EVERYWHERE:
|
||||||
if (opt->wizard) { // mode wizard
|
if (opt->wizard) { // mode wizard
|
||||||
forbidden_url = 0;
|
forbidden_url = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} // switch
|
} // switch
|
||||||
|
|
||||||
// ANCIENNE POS -- récupérer les liens à côtés d'un lien (nearlink)
|
// ANCIENNE POS -- récupérer les liens à côtés d'un lien (nearlink)
|
||||||
|
|
||||||
@@ -583,7 +581,7 @@ static int hts_acceptlink_(httrackp * opt, int ptr,
|
|||||||
// on doit poser la question.. peut on la poser?
|
// on doit poser la question.. peut on la poser?
|
||||||
// (oui je sais quel preuve de délicatesse, merci merci)
|
// (oui je sais quel preuve de délicatesse, merci merci)
|
||||||
if ((question) && (ptr > 0) && (!force_mirror)) {
|
if ((question) && (ptr > 0) && (!force_mirror)) {
|
||||||
if (opt->wizard == 2) { // éliminer tous les liens non répertoriés comme autorisés (ou inconnus)
|
if (opt->wizard == HTS_WIZARD_AUTO) {
|
||||||
question = 0;
|
question = 0;
|
||||||
forbidden_url = 1;
|
forbidden_url = 1;
|
||||||
hts_log_print(opt, LOG_DEBUG,
|
hts_log_print(opt, LOG_DEBUG,
|
||||||
@@ -600,8 +598,8 @@ static int hts_acceptlink_(httrackp * opt, int ptr,
|
|||||||
printf("robots.txt forbidden: %s%s\n", adr, fil);
|
printf("robots.txt forbidden: %s%s\n", adr, fil);
|
||||||
#endif
|
#endif
|
||||||
// question résolue, par les filtres, et mode robot non strict
|
// question résolue, par les filtres, et mode robot non strict
|
||||||
if ((!question) && (filters_answer) && (opt->robots == 1)
|
if ((!question) && (filters_answer) &&
|
||||||
&& (forbidden_url != 1)) {
|
(opt->robots == HTS_ROBOTS_SOMETIMES) && (forbidden_url != 1)) {
|
||||||
r = 0; // annuler interdiction des robots
|
r = 0; // annuler interdiction des robots
|
||||||
if (!forbidden_url) {
|
if (!forbidden_url) {
|
||||||
hts_log_print(opt, LOG_DEBUG,
|
hts_log_print(opt, LOG_DEBUG,
|
||||||
@@ -685,7 +683,7 @@ static int hts_acceptlink_(httrackp * opt, int ptr,
|
|||||||
io_flush;
|
io_flush;
|
||||||
} else { // lien primaire: autoriser répertoire entier
|
} else { // lien primaire: autoriser répertoire entier
|
||||||
if (!force_mirror) {
|
if (!force_mirror) {
|
||||||
if ((opt->seeker & 1) == 0) { // interdiction de descendre
|
if ((opt->seeker & HTS_SEEKER_DOWN) == 0) {
|
||||||
n = 7;
|
n = 7;
|
||||||
} else {
|
} else {
|
||||||
n = 5; // autoriser miroir répertoires descendants (lien primaire)
|
n = 5; // autoriser miroir répertoires descendants (lien primaire)
|
||||||
@@ -712,7 +710,7 @@ static int hts_acceptlink_(httrackp * opt, int ptr,
|
|||||||
switch (n) {
|
switch (n) {
|
||||||
case -1: // sauter tout le reste
|
case -1: // sauter tout le reste
|
||||||
forbidden_url = 1;
|
forbidden_url = 1;
|
||||||
opt->wizard = 2; // sauter tout le reste
|
opt->wizard = HTS_WIZARD_AUTO; // sauter tout le reste
|
||||||
break;
|
break;
|
||||||
case 0: // forbid the same link: adr/fil
|
case 0: // forbid the same link: adr/fil
|
||||||
forbidden_url = 1;
|
forbidden_url = 1;
|
||||||
@@ -796,7 +794,7 @@ static int hts_acceptlink_(httrackp * opt, int ptr,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 5: // allow the whole directory and its children
|
case 5: // allow the whole directory and its children
|
||||||
if ((opt->seeker & 2) == 0) { // not allowed to go up
|
if ((opt->seeker & HTS_SEEKER_UP) == 0) { // not allowed to go up
|
||||||
size_t i = strlen(fil) - 1;
|
size_t i = strlen(fil) - 1;
|
||||||
|
|
||||||
while((fil[i] != '/') && (i > 0))
|
while((fil[i] != '/') && (i > 0))
|
||||||
@@ -872,7 +870,7 @@ static int hts_acceptlink_(httrackp * opt, int ptr,
|
|||||||
// lien non autorisé, peut-on juste le tester?
|
// lien non autorisé, peut-on juste le tester?
|
||||||
if (just_test_it) {
|
if (just_test_it) {
|
||||||
if (forbidden_url == 1) {
|
if (forbidden_url == 1) {
|
||||||
if (opt->travel & 256) { // tester tout de même
|
if (opt->travel & HTS_TRAVEL_TEST_ALL) { // tester tout de même
|
||||||
if (strfield(adr, "ftp://") == 0) { // PAS ftp!
|
if (strfield(adr, "ftp://") == 0) { // PAS ftp!
|
||||||
forbidden_url = 1; // oui oui toujours interdit (note: sert à rien car ==1 mais c pour comprendre)
|
forbidden_url = 1; // oui oui toujours interdit (note: sert à rien car ==1 mais c pour comprendre)
|
||||||
*just_test_it = 1; // mais on teste
|
*just_test_it = 1; // mais on teste
|
||||||
|
|||||||
@@ -31,6 +31,12 @@ Please visit our Website: http://www.httrack.com
|
|||||||
/* Author: Xavier Roche */
|
/* Author: Xavier Roche */
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
|
||||||
|
/** @file htswrap.h
|
||||||
|
Legacy entry points of the callback-wrapper subsystem. The live callback
|
||||||
|
registration API now lives on the httrackp options block (hts_set_callback);
|
||||||
|
only the no-op init/free stubs remain exported here for ABI compatibility.
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef HTSWRAP_DEFH
|
#ifndef HTSWRAP_DEFH
|
||||||
#define HTSWRAP_DEFH
|
#define HTSWRAP_DEFH
|
||||||
|
|
||||||
@@ -50,15 +56,18 @@ typedef struct httrackp httrackp;
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
HTSEXT_API int htswrap_init(void); // LEGACY
|
/** Legacy no-op retained for ABI compatibility; always returns 1. */
|
||||||
HTSEXT_API int htswrap_free(void); // LEGACY
|
HTSEXT_API int htswrap_init(void); // LEGACY
|
||||||
|
|
||||||
|
/** Legacy no-op retained for ABI compatibility; always returns 1. */
|
||||||
|
HTSEXT_API int htswrap_free(void); // LEGACY
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//HTSEXT_API int htswrap_add(httrackp * opt, const char *name, void *fct);
|
// HTSEXT_API int htswrap_add(httrackp * opt, const char *name, void *fct);
|
||||||
//HTSEXT_API uintptr_t htswrap_read(httrackp * opt, const char *name);
|
// HTSEXT_API uintptr_t htswrap_read(httrackp * opt, const char *name);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,25 @@ Please visit our Website: http://www.httrack.com
|
|||||||
/* Author: Xavier Roche */
|
/* Author: Xavier Roche */
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file httrack-library.h
|
||||||
|
* @brief Public C API for embedding the HTTrack mirroring engine.
|
||||||
|
*
|
||||||
|
* Two ways to drive the engine, both supported and used by real consumers:
|
||||||
|
* - argv path: build an argv vector and call hts_main()/hts_main2(), exactly
|
||||||
|
* as the command-line tool is configured.
|
||||||
|
* - struct/callback path: hts_create_opt(), install callbacks with
|
||||||
|
* CHAIN_FUNCTION(), then hts_main2(), then hts_free_opt().
|
||||||
|
*
|
||||||
|
* Typical lifecycle: hts_init() once per process, then per mirror
|
||||||
|
* hts_create_opt() -> CHAIN_FUNCTION() -> hts_main2() (blocking) ->
|
||||||
|
* hts_get_stats()/hts_errmsg() -> hts_free_opt().
|
||||||
|
*
|
||||||
|
* Threading: hts_main2() blocks the calling thread. hts_request_stop() and
|
||||||
|
* hts_has_stopped() are safe to call for the same opt from another thread while
|
||||||
|
* the mirror runs. hts_free_opt() must not run until hts_has_stopped() is true.
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef HTTRACK_DEFLIB
|
#ifndef HTTRACK_DEFLIB
|
||||||
#define HTTRACK_DEFLIB
|
#define HTTRACK_DEFLIB
|
||||||
|
|
||||||
@@ -54,15 +73,19 @@ typedef struct strc_int2bytes2 strc_int2bytes2;
|
|||||||
#endif
|
#endif
|
||||||
#ifndef HTS_DEF_DEFSTRUCT_hts_log_type
|
#ifndef HTS_DEF_DEFSTRUCT_hts_log_type
|
||||||
#define HTS_DEF_DEFSTRUCT_hts_log_type
|
#define HTS_DEF_DEFSTRUCT_hts_log_type
|
||||||
|
|
||||||
|
/** Log severity levels, most to least severe. A message is emitted only if its
|
||||||
|
level is <= opt->debug. LOG_ERRNO is a flag OR'd into the level to append
|
||||||
|
": <strerror(errno)>" to the message. */
|
||||||
typedef enum hts_log_type {
|
typedef enum hts_log_type {
|
||||||
LOG_PANIC,
|
LOG_PANIC, /**< Fatal condition. */
|
||||||
LOG_ERROR,
|
LOG_ERROR, /**< Error. */
|
||||||
LOG_WARNING,
|
LOG_WARNING, /**< Warning. */
|
||||||
LOG_NOTICE,
|
LOG_NOTICE, /**< Notice; the default opt->debug level. */
|
||||||
LOG_INFO,
|
LOG_INFO, /**< Informational. */
|
||||||
LOG_DEBUG,
|
LOG_DEBUG, /**< Debug detail. */
|
||||||
LOG_TRACE,
|
LOG_TRACE, /**< Most verbose tracing. */
|
||||||
LOG_ERRNO = 1 << 8
|
LOG_ERRNO = 1 << 8 /**< Flag: append strerror(errno) to the message. */
|
||||||
} hts_log_type;
|
} hts_log_type;
|
||||||
#endif
|
#endif
|
||||||
#ifndef HTS_DEF_FWSTRUCT_hts_stat_struct
|
#ifndef HTS_DEF_FWSTRUCT_hts_stat_struct
|
||||||
@@ -70,205 +93,588 @@ typedef enum hts_log_type {
|
|||||||
typedef struct hts_stat_struct hts_stat_struct;
|
typedef struct hts_stat_struct hts_stat_struct;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** Assert error callback. **/
|
/** Assertion/error handler. Receives the failed expression text, source file,
|
||||||
|
and line. The strings are valid only for the duration of the call; do not
|
||||||
|
retain them. */
|
||||||
#ifndef HTS_DEF_FWSTRUCT_htsErrorCallback
|
#ifndef HTS_DEF_FWSTRUCT_htsErrorCallback
|
||||||
#define HTS_DEF_FWSTRUCT_htsErrorCallback
|
#define HTS_DEF_FWSTRUCT_htsErrorCallback
|
||||||
typedef void (*htsErrorCallback) (const char *msg, const char *file, int line);
|
typedef void (*htsErrorCallback)(const char *msg, const char *file, int line);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Helpers for plugging callbacks
|
/* Helpers for plugging callbacks
|
||||||
requires: htsdefines.h */
|
requires: htsdefines.h */
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Add a function callback 'FUNCTION' to the option structure 'OPT' callback member 'MEMBER',
|
* Install callback FUNCTION into OPT->callbacks_fun->MEMBER, chaining it ahead
|
||||||
with an optional (may be NULL) argument 'ARGUMENT'
|
* of any callback already there (whose function and carg are saved for
|
||||||
*/
|
* CALLBACKARG_PREV_FUN/CALLBACKARG_PREV_CARG). ARGUMENT is an optional (may be
|
||||||
#define CHAIN_FUNCTION(OPT, MEMBER, FUNCTION, ARGUMENT) do { \
|
* NULL) user pointer, later read inside the callback with
|
||||||
t_hts_callbackarg *carg = (t_hts_callbackarg*) hts_malloc(sizeof(t_hts_callbackarg)); \
|
* CALLBACKARG_USERDEF(). Allocates a t_hts_callbackarg with hts_malloc (not
|
||||||
carg->userdef = ( ARGUMENT ); \
|
* checked for OOM); it is freed by hts_free_opt().
|
||||||
carg->prev.fun = (void*) ( OPT )->callbacks_fun-> MEMBER .fun; \
|
*/
|
||||||
carg->prev.carg = ( OPT )->callbacks_fun-> MEMBER .carg; \
|
#define CHAIN_FUNCTION(OPT, MEMBER, FUNCTION, ARGUMENT) \
|
||||||
( OPT )->callbacks_fun-> MEMBER .fun = ( FUNCTION ); \
|
do { \
|
||||||
( OPT )->callbacks_fun-> MEMBER .carg = carg; \
|
t_hts_callbackarg *carg = \
|
||||||
} while(0)
|
(t_hts_callbackarg *) hts_malloc(sizeof(t_hts_callbackarg)); \
|
||||||
|
carg->userdef = (ARGUMENT); \
|
||||||
|
carg->prev.fun = (void *) (OPT)->callbacks_fun->MEMBER.fun; \
|
||||||
|
carg->prev.carg = (OPT)->callbacks_fun->MEMBER.carg; \
|
||||||
|
(OPT)->callbacks_fun->MEMBER.fun = (FUNCTION); \
|
||||||
|
(OPT)->callbacks_fun->MEMBER.carg = carg; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
/* The following helpers are useful only if you know that an existing callback migh be existing before before the call to CHAIN_FUNCTION()
|
/* The following helpers are useful only if you know that an existing callback
|
||||||
If your functions were added just after hts_create_opt(), no need to make the previous function check */
|
migh be existing before before the call to CHAIN_FUNCTION() If your functions
|
||||||
|
were added just after hts_create_opt(), no need to make the previous function
|
||||||
|
check */
|
||||||
|
|
||||||
/* Get the user-defined pointer initially passed to CHAIN_FUNCTION(), given the callback's carg argument */
|
/** Inside a chained callback, return the ARGUMENT pointer originally passed to
|
||||||
#define CALLBACKARG_USERDEF(CARG) ( ( (CARG) != NULL ) ? (CARG)->userdef : NULL )
|
CHAIN_FUNCTION(), or NULL when CARG is NULL. */
|
||||||
|
#define CALLBACKARG_USERDEF(CARG) (((CARG) != NULL) ? (CARG)->userdef : NULL)
|
||||||
|
|
||||||
/* Get the previously existing function before the call to CHAIN_FUNCTION(), given the callback's carg argument */
|
/** Return the callback of type NAME that this one chained over, cast to its
|
||||||
#define CALLBACKARG_PREV_FUN(CARG, NAME) ( (t_hts_htmlcheck_ ##NAME) ( ( (CARG) != NULL ) ? (CARG)->prev.fun : NULL ) )
|
function-pointer type, or NULL. Call it to forward to the prior handler. */
|
||||||
|
#define CALLBACKARG_PREV_FUN(CARG, NAME) \
|
||||||
|
((t_hts_htmlcheck_##NAME)(((CARG) != NULL) ? (CARG)->prev.fun : NULL))
|
||||||
|
|
||||||
/* Get the previously existing function argument before the call to CHAIN_FUNCTION(), given the callback's carg argument */
|
/** Return the carg of the callback this one chained over (pass it when
|
||||||
#define CALLBACKARG_PREV_CARG(CARG) ( ( (CARG) != NULL ) ? (CARG)->prev.carg : NULL )
|
forwarding to the CALLBACKARG_PREV_FUN result), or NULL. */
|
||||||
|
#define CALLBACKARG_PREV_CARG(CARG) \
|
||||||
|
(((CARG) != NULL) ? (CARG)->prev.carg : NULL)
|
||||||
|
|
||||||
/* Functions */
|
/* Functions */
|
||||||
|
|
||||||
/* Initialization */
|
/* Initialization */
|
||||||
|
/** Initialize the engine (lazy, idempotent, process-global): threading, the
|
||||||
|
hashtable assert handler, modules, the MD5 self-test, and TLS when built
|
||||||
|
with it. Only the first call does work. Honors $HTS_LOG for the debug level.
|
||||||
|
Always returns 1. Call before hts_create_opt() or hts_main(). */
|
||||||
HTSEXT_API int hts_init(void);
|
HTSEXT_API int hts_init(void);
|
||||||
|
|
||||||
|
/** No-op kept for API compatibility. Frees nothing (the process-global mutexes
|
||||||
|
set up by hts_init() are never released) and always returns 1. */
|
||||||
HTSEXT_API int hts_uninit(void);
|
HTSEXT_API int hts_uninit(void);
|
||||||
|
|
||||||
|
/** Block until all background mirror threads have finished. No-op unless built
|
||||||
|
with threaded fetching. */
|
||||||
HTSEXT_API void htsthread_wait(void);
|
HTSEXT_API void htsthread_wait(void);
|
||||||
|
|
||||||
/* Main functions */
|
/* Main functions */
|
||||||
|
/** Run a full mirror from a command-line argv (argv[0] is ignored, as in
|
||||||
|
main()). Creates a fresh option set, runs the engine, and frees it. Returns
|
||||||
|
the engine exit code. Call hts_init() first. */
|
||||||
HTSEXT_API int hts_main(int argc, char **argv);
|
HTSEXT_API int hts_main(int argc, char **argv);
|
||||||
HTSEXT_API int hts_main2(int argc, char **argv, httrackp * opt);
|
|
||||||
|
/** Run a full mirror using a caller-supplied option set. Use this instead of
|
||||||
|
hts_main() to set options or plug callbacks on opt first. Blocks until the
|
||||||
|
mirror ends and returns the engine exit code. The caller keeps ownership of
|
||||||
|
opt and must release it with hts_free_opt(). */
|
||||||
|
HTSEXT_API int hts_main2(int argc, char **argv, httrackp *opt);
|
||||||
|
|
||||||
/* Options handling */
|
/* Options handling */
|
||||||
|
/** Allocate and default-initialize an option set, preloading the bundled parser
|
||||||
|
modules. Returns a heap object the caller owns and must release with
|
||||||
|
hts_free_opt(). Does not return NULL on allocation failure. */
|
||||||
HTSEXT_API httrackp *hts_create_opt(void);
|
HTSEXT_API httrackp *hts_create_opt(void);
|
||||||
HTSEXT_API void hts_free_opt(httrackp * opt);
|
|
||||||
|
/** Free an option set created by hts_create_opt() (callback chains, plugged
|
||||||
|
modules, DNS cache, owned strings, and the structure). NULL is accepted. The
|
||||||
|
pointer is invalid afterward. Do not call while a mirror is running on that
|
||||||
|
opt; wait until hts_has_stopped() is true. */
|
||||||
|
HTSEXT_API void hts_free_opt(httrackp *opt);
|
||||||
|
|
||||||
|
/** Return sizeof(httrackp) as the library sees it, for caller-vs-library struct
|
||||||
|
ABI mismatch checks. */
|
||||||
HTSEXT_API size_t hts_sizeof_opt(void);
|
HTSEXT_API size_t hts_sizeof_opt(void);
|
||||||
HTSEXT_API const hts_stat_struct* hts_get_stats(httrackp * opt);
|
|
||||||
HTSEXT_API void set_wrappers(httrackp * opt); /* LEGACY */
|
/** Snapshot opt's error/warning/info counters and return a pointer to them.
|
||||||
HTSEXT_API int plug_wrapper(httrackp * opt, const char *moduleName,
|
Returns NULL if opt is NULL. The result aliases a single process-global
|
||||||
|
static: it is not thread-safe and is overwritten by the next call, so copy
|
||||||
|
out the fields you need. */
|
||||||
|
HTSEXT_API const hts_stat_struct *hts_get_stats(httrackp *opt);
|
||||||
|
|
||||||
|
/** Legacy no-op retained for API compatibility. */
|
||||||
|
HTSEXT_API void set_wrappers(httrackp *opt); /* LEGACY */
|
||||||
|
|
||||||
|
/** Load a plugin shared library and run its hts_plug(opt, argv) entry point. On
|
||||||
|
success the handle is recorded in opt and unloaded by hts_free_opt().
|
||||||
|
@return 1 if loaded and hts_plug succeeded; 0 if loaded but hts_plug was
|
||||||
|
missing or refused; -1 if the library could not be loaded. */
|
||||||
|
HTSEXT_API int plug_wrapper(httrackp *opt, const char *moduleName,
|
||||||
const char *argv);
|
const char *argv);
|
||||||
|
|
||||||
|
/** Install the process-global assertion/error callback (NULL clears it). Not
|
||||||
|
per-opt, and not safe to change while a mirror runs. */
|
||||||
HTSEXT_API void hts_set_error_callback(htsErrorCallback handler);
|
HTSEXT_API void hts_set_error_callback(htsErrorCallback handler);
|
||||||
|
|
||||||
|
/** Return the current process-global error callback, or NULL. */
|
||||||
HTSEXT_API htsErrorCallback hts_get_error_callback(void);
|
HTSEXT_API htsErrorCallback hts_get_error_callback(void);
|
||||||
|
|
||||||
/* Logging */
|
/* Logging */
|
||||||
HTSEXT_API int hts_log(httrackp * opt, const char *prefix, const char *msg);
|
/** Legacy: write prefix then msg to opt->log. Returns 0 if written, 1 if
|
||||||
HTSEXT_API void hts_log_print(httrackp * opt, int type, const char *format,
|
opt->log is NULL. Prefer hts_log_print(). */
|
||||||
...) HTS_PRINTF_FUN(3, 4);
|
HTSEXT_API hts_boolean hts_log(httrackp *opt, const char *prefix,
|
||||||
HTSEXT_API void hts_log_vprint(httrackp * opt, int type, const char *format,
|
const char *msg);
|
||||||
|
|
||||||
|
/** printf-style log at level @p type (an hts_log_type, optionally |LOG_ERRNO).
|
||||||
|
Forwards to the registered log callback, and when the level is <= opt->debug
|
||||||
|
also to opt->log. @p format must be non-NULL. */
|
||||||
|
HTSEXT_API void hts_log_print(httrackp *opt, int type, const char *format, ...)
|
||||||
|
HTS_PRINTF_FUN(3, 4);
|
||||||
|
|
||||||
|
/** va_list form of hts_log_print(). @p opt may be NULL (only the callback
|
||||||
|
runs). Preserves errno. @p format must be non-NULL. */
|
||||||
|
HTSEXT_API void hts_log_vprint(httrackp *opt, int type, const char *format,
|
||||||
va_list args);
|
va_list args);
|
||||||
HTSEXT_API void hts_set_log_vprint_callback(void (*callback)(httrackp * opt,
|
|
||||||
int type,
|
/** Install the process-global log callback invoked by hts_log_vprint() for
|
||||||
const char *format, va_list args));
|
every message, regardless of opt->debug (NULL clears it). Not per-opt. */
|
||||||
|
HTSEXT_API void
|
||||||
|
hts_set_log_vprint_callback(void (*callback)(httrackp *opt, int type,
|
||||||
|
const char *format, va_list args));
|
||||||
|
|
||||||
/* Infos */
|
/* Infos */
|
||||||
HTSEXT_API const char *hts_get_version_info(httrackp * opt);
|
/** Human-readable build/feature string plus the names of plugged modules. The
|
||||||
|
result is written into and aliases a 2048-byte scratch buffer inside opt: it
|
||||||
|
is valid until that buffer is next used, and must not be freed. opt must be
|
||||||
|
non-NULL. */
|
||||||
|
HTSEXT_API const char *hts_get_version_info(httrackp *opt);
|
||||||
|
|
||||||
|
/** Static build-features string (TLS, zlib, ipv6, and so on). Process-global
|
||||||
|
storage; do not free or modify. */
|
||||||
HTSEXT_API const char *hts_is_available(void);
|
HTSEXT_API const char *hts_is_available(void);
|
||||||
HTSEXT_API const char* hts_version(void);
|
|
||||||
HTSEXT_API const hts_stat_struct* hts_get_stats(httrackp * opt);
|
/** HTTrack version id string. Static storage; do not free. */
|
||||||
|
HTSEXT_API const char *hts_version(void);
|
||||||
|
|
||||||
/* Wrapper functions */
|
/* Wrapper functions */
|
||||||
HTSEXT_API int htswrap_init(void); // DEPRECATED - DUMMY FUNCTION
|
HTSEXT_API int htswrap_init(void); // DEPRECATED - DUMMY FUNCTION
|
||||||
HTSEXT_API int htswrap_free(void); // DEPRECATED - DUMMY FUNCTION
|
|
||||||
HTSEXT_API int htswrap_add(httrackp * opt, const char *name, void *fct);
|
|
||||||
HTSEXT_API uintptr_t htswrap_read(httrackp * opt, const char *name);
|
|
||||||
HTSEXT_API int htswrap_set_userdef(httrackp * opt, void *userdef);
|
|
||||||
HTSEXT_API void *htswrap_get_userdef(httrackp * opt);
|
|
||||||
|
|
||||||
/* Internal library allocators, if a different libc is being used by the client */
|
HTSEXT_API int htswrap_free(void); // DEPRECATED - DUMMY FUNCTION
|
||||||
|
|
||||||
|
/** Register callback @p fct under @p name in opt's callback table (for example
|
||||||
|
"start", "check-html", "linkdetected"). Returns 1 on success, 0 if @p name
|
||||||
|
is not a known slot. Prefer CHAIN_FUNCTION(), which preserves any prior
|
||||||
|
callback. */
|
||||||
|
HTSEXT_API int htswrap_add(httrackp *opt, const char *name, void *fct);
|
||||||
|
|
||||||
|
/** Return the function pointer registered under @p name in opt as a uintptr_t,
|
||||||
|
or 0 if none or unknown. */
|
||||||
|
HTSEXT_API uintptr_t htswrap_read(httrackp *opt, const char *name);
|
||||||
|
|
||||||
|
/* Internal library allocators, if a different libc is being used by the client
|
||||||
|
*/
|
||||||
|
/** strdup() through the library allocator. Returns a heap copy freed with
|
||||||
|
hts_free(), or NULL on failure. */
|
||||||
HTSEXT_API char *hts_strdup(const char *string);
|
HTSEXT_API char *hts_strdup(const char *string);
|
||||||
|
|
||||||
|
/** malloc() through the library allocator. Free with hts_free(). NULL on OOM.
|
||||||
|
*/
|
||||||
HTSEXT_API void *hts_malloc(size_t size);
|
HTSEXT_API void *hts_malloc(size_t size);
|
||||||
|
|
||||||
|
/** realloc() through the library allocator. NULL on failure, leaving the
|
||||||
|
original block unchanged. */
|
||||||
HTSEXT_API void *hts_realloc(void *const data, const size_t size);
|
HTSEXT_API void *hts_realloc(void *const data, const size_t size);
|
||||||
|
|
||||||
|
/** free() through the library allocator. NULL is accepted. */
|
||||||
HTSEXT_API void hts_free(void *data);
|
HTSEXT_API void hts_free(void *data);
|
||||||
|
|
||||||
/* Other functions */
|
/* Other functions */
|
||||||
HTSEXT_API int hts_resetvar(void); // DEPRECATED - DUMMY FUNCTION
|
HTSEXT_API int hts_resetvar(void); // DEPRECATED - DUMMY FUNCTION
|
||||||
HTSEXT_API int hts_buildtopindex(httrackp * opt, const char *path,
|
|
||||||
|
/** (Re)build the top-level index.html aggregating every mirror project found
|
||||||
|
under @p path. @p binpath is the data root used to locate the
|
||||||
|
templates/topindex-*.html files, falling back to built-in templates. Writes
|
||||||
|
<path>/index.html. @return 1 on success, 0 on failure. */
|
||||||
|
HTSEXT_API int hts_buildtopindex(httrackp *opt, const char *path,
|
||||||
const char *binpath);
|
const char *binpath);
|
||||||
|
|
||||||
|
/** Scan every mirror project under @p path and return a CRLF-separated list:
|
||||||
|
@p type==1 gives the distinct category names, any other value gives the
|
||||||
|
project directory names. The result is heap-allocated and owned by the
|
||||||
|
caller (free with freet()); it may be NULL. Not UTF-8. @p path is modified in
|
||||||
|
place (a trailing '/' is stripped). */
|
||||||
HTSEXT_API char *hts_getcategories(char *path, int type);
|
HTSEXT_API char *hts_getcategories(char *path, int type);
|
||||||
|
|
||||||
|
/** Read the `category=` value from a winprofile.ini file. The result is
|
||||||
|
heap-allocated and owned by the caller (free with freet()), or NULL when the
|
||||||
|
file is missing or has no category line. Not UTF-8. */
|
||||||
HTSEXT_API char *hts_getcategory(const char *filename);
|
HTSEXT_API char *hts_getcategory(const char *filename);
|
||||||
|
|
||||||
/* Catch-URL */
|
/* Catch-URL */
|
||||||
|
/** Open a local capture socket (a mini-proxy), trying a list of standard ports
|
||||||
|
until one binds. Writes the chosen port to *port_prox and the local host
|
||||||
|
address into adr_prox (a caller buffer of at least 128 bytes), and returns
|
||||||
|
the listening socket. Returns INVALID_SOCKET if no port could be bound. */
|
||||||
HTSEXT_API T_SOC catch_url_init_std(int *port_prox, char *adr_prox);
|
HTSEXT_API T_SOC catch_url_init_std(int *port_prox, char *adr_prox);
|
||||||
|
|
||||||
|
/** Open a local capture socket bound to *port (0 picks a free port). Writes the
|
||||||
|
effective port back to *port and the local dotted address into @p adr (a
|
||||||
|
caller buffer of at least 128 bytes), and returns the listening socket.
|
||||||
|
Returns INVALID_SOCKET on failure. */
|
||||||
HTSEXT_API T_SOC catch_url_init(int *port, char *adr);
|
HTSEXT_API T_SOC catch_url_init(int *port, char *adr);
|
||||||
HTSEXT_API int catch_url(T_SOC soc, char *url, char *method, char *data);
|
|
||||||
|
/** Block on capture socket @p soc, accept one browser connection, and capture
|
||||||
|
the proxied HTTP request: write the absolute URL to @p url, the upper-cased
|
||||||
|
method to @p method, and the rebuilt request (request line, headers, and any
|
||||||
|
POST body) to @p data, then send a canned response and close.
|
||||||
|
@return 1 on success, 0 on error; on error @p url instead holds the peer's
|
||||||
|
"ip:port". The buffers are caller-allocated and not bounds-checked: @p data
|
||||||
|
must be CATCH_URL_DATA_SIZE bytes, and @p url / @p method must fit the
|
||||||
|
captured request line. */
|
||||||
|
HTSEXT_API hts_boolean catch_url(T_SOC soc, char *url, char *method,
|
||||||
|
char *data);
|
||||||
|
|
||||||
/* State */
|
/* State */
|
||||||
HTSEXT_API int hts_is_parsing(httrackp * opt, int flag);
|
/** Whether the engine is parsing HTML. Returns 0 if not, otherwise the percent
|
||||||
HTSEXT_API int hts_is_testing(httrackp * opt);
|
done (at least 1). @p flag >= 0 also requests a progress refresh; pass a
|
||||||
HTSEXT_API int hts_is_exiting(httrackp * opt);
|
negative value to query without side effects. */
|
||||||
|
HTSEXT_API int hts_is_parsing(httrackp *opt, int flag);
|
||||||
|
|
||||||
|
/** Current background phase: 0 none, 1 testing links, 2 purge, 3, 4 scheduling,
|
||||||
|
5 waiting for a slot. */
|
||||||
|
HTSEXT_API int hts_is_testing(httrackp *opt);
|
||||||
|
|
||||||
|
/** Nonzero once the engine has begun its exit sequence. */
|
||||||
|
HTSEXT_API int hts_is_exiting(httrackp *opt);
|
||||||
|
|
||||||
/*HTSEXT_API int hts_setopt(httrackp* opt); DEPRECATED ; see copy_htsopt() */
|
/*HTSEXT_API int hts_setopt(httrackp* opt); DEPRECATED ; see copy_htsopt() */
|
||||||
|
|
||||||
HTSEXT_API int hts_addurl(httrackp * opt, char **url);
|
/** Queue extra start URLs to inject into a running mirror. @p url is a
|
||||||
HTSEXT_API int hts_resetaddurl(httrackp * opt);
|
caller-owned, NULL-terminated array of strings; the engine stores the
|
||||||
HTSEXT_API int copy_htsopt(const httrackp * from, httrackp * to);
|
pointer without copying, so the array and its strings must stay valid until
|
||||||
HTSEXT_API char *hts_errmsg(httrackp * opt);
|
the engine consumes them. @return nonzero if a list is now set. */
|
||||||
HTSEXT_API int hts_setpause(httrackp * opt, int);
|
HTSEXT_API hts_boolean hts_addurl(httrackp *opt, char **url);
|
||||||
HTSEXT_API int hts_request_stop(httrackp * opt, int force);
|
|
||||||
HTSEXT_API int hts_cancel_file_push(httrackp * opt, const char *url);
|
/** Clear any pending add-URL list set by hts_addurl(). Always returns 0. */
|
||||||
HTSEXT_API void hts_cancel_test(httrackp * opt);
|
HTSEXT_API hts_boolean hts_resetaddurl(httrackp *opt);
|
||||||
HTSEXT_API void hts_cancel_parsing(httrackp * opt);
|
|
||||||
HTSEXT_API void hts_cancel_test(httrackp * opt);
|
/** Apply the runtime-tunable options from @p from onto @p to, to adjust a live
|
||||||
HTSEXT_API void hts_cancel_parsing(httrackp * opt);
|
mirror. Only fields set to a non-sentinel value are copied; the rest of @p
|
||||||
HTSEXT_API int hts_has_stopped(httrackp * opt);
|
to is left untouched. The user-agent string is deep-copied. @return 0. */
|
||||||
|
HTSEXT_API int copy_htsopt(const httrackp *from, httrackp *to);
|
||||||
|
|
||||||
|
/** Return the engine's last error message, or NULL. The string is owned by
|
||||||
|
@p opt; do not free it, and use it only while @p opt lives. */
|
||||||
|
HTSEXT_API char *hts_errmsg(httrackp *opt);
|
||||||
|
|
||||||
|
/** Get or set the transfer-pause flag. @p p >= 0 sets it (nonzero means
|
||||||
|
paused); a negative value queries. @return the current pause flag. */
|
||||||
|
HTSEXT_API int hts_setpause(httrackp *opt, int);
|
||||||
|
|
||||||
|
/** Ask the running mirror to terminate (sets the stop flag under the state
|
||||||
|
lock, so it is safe to call from another thread). @p force is currently
|
||||||
|
ignored.
|
||||||
|
@return 0; no-op if @p opt is NULL. */
|
||||||
|
HTSEXT_API int hts_request_stop(httrackp *opt, hts_boolean force);
|
||||||
|
|
||||||
|
/** Queue a single in-progress file, by URL, to be cancelled by the engine.
|
||||||
|
@p url is copied internally. Takes the state lock, so it is thread-safe.
|
||||||
|
@return the underlying push result. */
|
||||||
|
HTSEXT_API int hts_cancel_file_push(httrackp *opt, const char *url);
|
||||||
|
|
||||||
|
/** Cancel the in-progress link-testing phase. Effective only while a test runs.
|
||||||
|
*/
|
||||||
|
HTSEXT_API void hts_cancel_test(httrackp *opt);
|
||||||
|
|
||||||
|
/** Cancel the in-progress HTML parsing. Effective only while parsing is active.
|
||||||
|
*/
|
||||||
|
HTSEXT_API void hts_cancel_parsing(httrackp *opt);
|
||||||
|
|
||||||
|
/** Nonzero once the mirror has fully ended. Read under the engine state lock,
|
||||||
|
so safe to poll from another thread. Wait for this before hts_free_opt(). */
|
||||||
|
HTSEXT_API hts_boolean hts_has_stopped(httrackp *opt);
|
||||||
|
|
||||||
/* Tools */
|
/* Tools */
|
||||||
|
/** Ensure the directory chain leading to @p path exists, creating missing
|
||||||
|
directories. @p path ends either with '/' (a directory) or a filename (its
|
||||||
|
basename is ignored). A regular file blocking a needed directory is renamed
|
||||||
|
to "<name>.txt". @p path is NOT UTF-8. @return 0 on success or if it already
|
||||||
|
exists, -1 on error. */
|
||||||
HTSEXT_API int structcheck(const char *path);
|
HTSEXT_API int structcheck(const char *path);
|
||||||
|
|
||||||
|
/** Like structcheck() but @p path is UTF-8. @return 0 on success, -1 on error.
|
||||||
|
*/
|
||||||
HTSEXT_API int structcheck_utf8(const char *path);
|
HTSEXT_API int structcheck_utf8(const char *path);
|
||||||
HTSEXT_API int dir_exists(const char *path);
|
|
||||||
|
/** Whether the directory containing @p path exists. The basename is stripped
|
||||||
|
first, so passing a file path tests its parent directory. @return 1 if it is
|
||||||
|
a directory, 0 otherwise. */
|
||||||
|
HTSEXT_API hts_boolean dir_exists(const char *path);
|
||||||
|
|
||||||
|
/** Write the HTTP reason phrase for @p statuscode into @p msg, a caller buffer
|
||||||
|
of at least 64 bytes. For an unknown code a non-empty @p msg is kept,
|
||||||
|
otherwise it is set to "Unknown error". */
|
||||||
HTSEXT_API void infostatuscode(char *msg, int statuscode);
|
HTSEXT_API void infostatuscode(char *msg, int statuscode);
|
||||||
|
|
||||||
|
/** Return the static reason-phrase string for @p statuscode, or NULL if
|
||||||
|
unknown. The pointer is a string literal; do not free it. */
|
||||||
HTSEXT_API const char *infostatuscode_const(int statuscode);
|
HTSEXT_API const char *infostatuscode_const(int statuscode);
|
||||||
|
|
||||||
|
/** Current wall-clock time in milliseconds since the Unix epoch. */
|
||||||
HTSEXT_API TStamp mtime_local(void);
|
HTSEXT_API TStamp mtime_local(void);
|
||||||
|
|
||||||
|
/** Format a duration @p t (in seconds) into a compact string in @p st, for
|
||||||
|
example "3d,02h,04min05s". @p st is caller-allocated and not bounds-checked.
|
||||||
|
*/
|
||||||
HTSEXT_API void qsec2str(char *st, TStamp t);
|
HTSEXT_API void qsec2str(char *st, TStamp t);
|
||||||
HTSEXT_API char *int2char(strc_int2bytes2 * strc, int n);
|
|
||||||
HTSEXT_API char *int2bytes(strc_int2bytes2 * strc, LLint n);
|
/* The int2* helpers below write into the caller-supplied strc and return
|
||||||
HTSEXT_API char *int2bytessec(strc_int2bytes2 * strc, long int n);
|
pointers into it. No allocation happens; the result is valid only until strc
|
||||||
HTSEXT_API char **int2bytes2(strc_int2bytes2 * strc, LLint n);
|
is reused, and a given strc is not reentrant. Use one strc per
|
||||||
|
concurrently-live result. */
|
||||||
|
/** Format @p n as a decimal string into @p strc and return it. */
|
||||||
|
HTSEXT_API char *int2char(strc_int2bytes2 *strc, int n);
|
||||||
|
|
||||||
|
/** Format byte count @p n as "<num><unit>" (B/KiB/MiB/GiB and so on) into
|
||||||
|
@p strc and return it. */
|
||||||
|
HTSEXT_API char *int2bytes(strc_int2bytes2 *strc, LLint n);
|
||||||
|
|
||||||
|
/** Format a transfer rate @p n as "<num><unit>/s" into @p strc and return it.
|
||||||
|
*/
|
||||||
|
HTSEXT_API char *int2bytessec(strc_int2bytes2 *strc, long int n);
|
||||||
|
|
||||||
|
/** Split byte count @p n into number and unit, returning a 2-element array
|
||||||
|
{number, unit} stored inside @p strc. */
|
||||||
|
HTSEXT_API char **int2bytes2(strc_int2bytes2 *strc, LLint n);
|
||||||
|
|
||||||
|
/** Skip any "user[:pass]@" identification prefix in a URL, returning a pointer
|
||||||
|
into the argument past it (or past the protocol if none). The result aliases
|
||||||
|
the input string. */
|
||||||
HTSEXT_API char *jump_identification(char *);
|
HTSEXT_API char *jump_identification(char *);
|
||||||
|
|
||||||
HTSEXT_API const char *jump_identification_const(const char *);
|
HTSEXT_API const char *jump_identification_const(const char *);
|
||||||
|
|
||||||
|
/** Like jump_identification() and also strip a leading "www." host prefix,
|
||||||
|
returning a pointer into the input to the normalized host. */
|
||||||
HTSEXT_API char *jump_normalized(char *);
|
HTSEXT_API char *jump_normalized(char *);
|
||||||
|
|
||||||
HTSEXT_API const char *jump_normalized_const(const char *);
|
HTSEXT_API const char *jump_normalized_const(const char *);
|
||||||
|
|
||||||
|
/** Return a pointer (into the input) to the ":port" part of a URL host, or NULL
|
||||||
|
if there is no explicit port. Handles bracketed IPv6 literals. */
|
||||||
HTSEXT_API char *jump_toport(char *);
|
HTSEXT_API char *jump_toport(char *);
|
||||||
|
|
||||||
HTSEXT_API const char *jump_toport_const(const char *);
|
HTSEXT_API const char *jump_toport_const(const char *);
|
||||||
|
|
||||||
|
/** Canonicalize a URL path into @p dest: collapse duplicate '/' and sort the
|
||||||
|
query-string arguments, so "?b=2&a=1" and "?a=1&b=2" compare equal. Returns
|
||||||
|
@p dest, a caller buffer of at least strlen(source)+1 bytes (the output is
|
||||||
|
never longer than the input). */
|
||||||
HTSEXT_API char *fil_normalized(const char *source, char *dest);
|
HTSEXT_API char *fil_normalized(const char *source, char *dest);
|
||||||
|
|
||||||
|
/** Write the normalized host of @p source (identification and "www." stripped)
|
||||||
|
into @p dest, truncated to @p destsize. Returns @p dest. */
|
||||||
HTSEXT_API char *adr_normalized_sized(const char *source, char *dest,
|
HTSEXT_API char *adr_normalized_sized(const char *source, char *dest,
|
||||||
size_t destsize);
|
size_t destsize);
|
||||||
|
|
||||||
|
/** @deprecated Use adr_normalized_sized(). This form has no destination size
|
||||||
|
and assumes @p dest is the engine URL buffer of HTS_URLMAXSIZE*2 bytes; a
|
||||||
|
smaller buffer can overflow. */
|
||||||
HTS_DEPRECATED("use adr_normalized_sized(source, dest, destsize)")
|
HTS_DEPRECATED("use adr_normalized_sized(source, dest, destsize)")
|
||||||
|
|
||||||
HTSEXT_API char *adr_normalized(const char *source, char *dest);
|
HTSEXT_API char *adr_normalized(const char *source, char *dest);
|
||||||
|
|
||||||
|
/** Get or set the process executable root directory (with trailing '/'). The
|
||||||
|
first call with non-NULL @p file initializes it and returns NULL; later
|
||||||
|
initialization calls are ignored. Call with NULL to query: returns the
|
||||||
|
stored directory, or "" if never set. The result is a static internal buffer;
|
||||||
|
do not free it, and do not set it from multiple threads. */
|
||||||
HTSEXT_API const char *hts_rootdir(char *file);
|
HTSEXT_API const char *hts_rootdir(char *file);
|
||||||
|
|
||||||
/* Escaping URLs */
|
/* Escaping URLs */
|
||||||
|
/*
|
||||||
|
* Size contract shared by the escape/unescape family below.
|
||||||
|
* For the escape_* / append_escape_* / inplace_escape_* /
|
||||||
|
* escape_for_html_print* / make_content_id / x_escape_http functions, `size` is
|
||||||
|
* the total capacity of `dest` including the terminating NUL. The size_t return
|
||||||
|
* is the number of bytes written, NOT counting the NUL; on overflow it returns
|
||||||
|
* `size` and `dest` is still NUL-terminated (truncated). Passing sizeof(a
|
||||||
|
* pointer) as the size trips a runtime assert. The unescape_http* functions
|
||||||
|
* instead return `dest` (the catbuff pointer) and truncate to fit `size`.
|
||||||
|
*/
|
||||||
|
/** Decode HTML entities in @p s in place (for example "&" becomes "&"). */
|
||||||
HTSEXT_API void unescape_amp(char *s);
|
HTSEXT_API void unescape_amp(char *s);
|
||||||
|
|
||||||
HTSEXT_API size_t escape_spc_url(const char *const src, char *const dest, const size_t size);
|
/** Percent-escape only spaces (' ' becomes "%20"); copy everything else
|
||||||
HTSEXT_API size_t escape_in_url(const char *const src, char *const dest, const size_t size);
|
* verbatim. */
|
||||||
HTSEXT_API size_t escape_uri(const char *const src, char *const dest, const size_t size);
|
HTSEXT_API size_t escape_spc_url(const char *const src, char *const dest,
|
||||||
HTSEXT_API size_t escape_uri_utf(const char *const src, char *const dest, const size_t size);
|
const size_t size);
|
||||||
HTSEXT_API size_t escape_check_url(const char *const src, char *const dest, const size_t size);
|
|
||||||
|
|
||||||
HTSEXT_API size_t append_escape_spc_url(const char *const src, char *const dest, const size_t size);
|
/** Aggressively percent-escape @p src for use as a single URL path segment
|
||||||
HTSEXT_API size_t append_escape_in_url(const char *const src, char *const dest, const size_t size);
|
(reserved, delimiter, unwise, special, avoid and mark characters). */
|
||||||
HTSEXT_API size_t append_escape_uri(const char *const src, char *const dest, const size_t size);
|
HTSEXT_API size_t escape_in_url(const char *const src, char *const dest,
|
||||||
HTSEXT_API size_t append_escape_uri_utf(const char *const src, char *const dest, const size_t size);
|
const size_t size);
|
||||||
HTSEXT_API size_t append_escape_check_url(const char *const src, char *const dest, const size_t size);
|
|
||||||
|
|
||||||
|
/** Percent-escape @p src as a URI, escaping only what is necessary and keeping
|
||||||
|
'/' and other reserved characters. */
|
||||||
|
HTSEXT_API size_t escape_uri(const char *const src, char *const dest,
|
||||||
|
const size_t size);
|
||||||
|
|
||||||
|
/** Like escape_uri() for a UTF-8 URI: also escapes reserved characters other
|
||||||
|
than '/'. */
|
||||||
|
HTSEXT_API size_t escape_uri_utf(const char *const src, char *const dest,
|
||||||
|
const size_t size);
|
||||||
|
|
||||||
|
/** Minimal "make safe" escape: percent-escapes only '"', ' ' and control
|
||||||
|
characters, leaving an already-formed URL otherwise intact. */
|
||||||
|
HTSEXT_API size_t escape_check_url(const char *const src, char *const dest,
|
||||||
|
const size_t size);
|
||||||
|
|
||||||
|
/** Append-variant of escape_spc_url(): escapes @p src after the existing
|
||||||
|
NUL-terminated content of @p dest. Returns the bytes appended (excluding the
|
||||||
|
NUL). */
|
||||||
|
HTSEXT_API size_t append_escape_spc_url(const char *const src, char *const dest,
|
||||||
|
const size_t size);
|
||||||
|
|
||||||
|
/** Append-variant of escape_in_url(). See append_escape_spc_url(). */
|
||||||
|
HTSEXT_API size_t append_escape_in_url(const char *const src, char *const dest,
|
||||||
|
const size_t size);
|
||||||
|
|
||||||
|
/** Append-variant of escape_uri(). See append_escape_spc_url(). */
|
||||||
|
HTSEXT_API size_t append_escape_uri(const char *const src, char *const dest,
|
||||||
|
const size_t size);
|
||||||
|
|
||||||
|
/** Append-variant of escape_uri_utf(). See append_escape_spc_url(). */
|
||||||
|
HTSEXT_API size_t append_escape_uri_utf(const char *const src, char *const dest,
|
||||||
|
const size_t size);
|
||||||
|
|
||||||
|
/** Append-variant of escape_check_url(). See append_escape_spc_url(). */
|
||||||
|
HTSEXT_API size_t append_escape_check_url(const char *const src,
|
||||||
|
char *const dest, const size_t size);
|
||||||
|
|
||||||
|
/** In-place variant of escape_spc_url(): escapes the NUL-terminated string in
|
||||||
|
@p dest back into @p dest. */
|
||||||
HTSEXT_API size_t inplace_escape_spc_url(char *const dest, const size_t size);
|
HTSEXT_API size_t inplace_escape_spc_url(char *const dest, const size_t size);
|
||||||
|
|
||||||
|
/** In-place variant of escape_in_url(). See inplace_escape_spc_url(). */
|
||||||
HTSEXT_API size_t inplace_escape_in_url(char *const dest, const size_t size);
|
HTSEXT_API size_t inplace_escape_in_url(char *const dest, const size_t size);
|
||||||
|
|
||||||
|
/** In-place variant of escape_uri(). See inplace_escape_spc_url(). */
|
||||||
HTSEXT_API size_t inplace_escape_uri(char *const dest, const size_t size);
|
HTSEXT_API size_t inplace_escape_uri(char *const dest, const size_t size);
|
||||||
|
|
||||||
|
/** In-place variant of escape_uri_utf(). See inplace_escape_spc_url(). */
|
||||||
HTSEXT_API size_t inplace_escape_uri_utf(char *const dest, const size_t size);
|
HTSEXT_API size_t inplace_escape_uri_utf(char *const dest, const size_t size);
|
||||||
|
|
||||||
|
/** In-place variant of escape_check_url(). See inplace_escape_spc_url(). */
|
||||||
HTSEXT_API size_t inplace_escape_check_url(char *const dest, const size_t size);
|
HTSEXT_API size_t inplace_escape_check_url(char *const dest, const size_t size);
|
||||||
|
|
||||||
HTSEXT_API char *escape_check_url_addr(const char *const src, char *const dest, const size_t size);
|
/** Same escaping as escape_check_url() but returns @p dest instead of the byte
|
||||||
HTSEXT_API size_t make_content_id(const char *const adr, const char *const fil, char *const dest, const size_t size);
|
count. */
|
||||||
|
HTSEXT_API char *escape_check_url_addr(const char *const src, char *const dest,
|
||||||
|
const size_t size);
|
||||||
|
|
||||||
HTSEXT_API size_t x_escape_http(const char *const s, char *const dest, const size_t max_size, const int mode);
|
/** Build a MIME/MHTML content-id token in @p dest from @p adr and @p fil:
|
||||||
|
escape_in_url() both, then replace every '%' with 'X' so the result is one
|
||||||
|
opaque token. */
|
||||||
|
HTSEXT_API size_t make_content_id(const char *const adr, const char *const fil,
|
||||||
|
char *const dest, const size_t size);
|
||||||
|
|
||||||
|
/** Low-level percent-escaper backing the escape_* family. @p mode selects the
|
||||||
|
character class to escape: 0 check_url, 1 in_url, 2 spc_url, 3 uri,
|
||||||
|
30 uri_utf. @p max_size is the dest capacity including the NUL. */
|
||||||
|
HTSEXT_API size_t x_escape_http(const char *const s, char *const dest,
|
||||||
|
const size_t max_size, const int mode);
|
||||||
|
|
||||||
|
/** Strip all control characters (byte value < 32) from @p s in place. */
|
||||||
HTSEXT_API void escape_remove_control(char *const s);
|
HTSEXT_API void escape_remove_control(char *const s);
|
||||||
HTSEXT_API size_t escape_for_html_print(const char *const s, char *const dest, const size_t size);
|
|
||||||
HTSEXT_API size_t escape_for_html_print_full(const char *const s, char *const dest, const size_t size);
|
|
||||||
|
|
||||||
HTSEXT_API char *unescape_http(char *const catbuff, const size_t size, const char *const s);
|
/** HTML-escape for text output: rewrite '&' to "&" and pass every other
|
||||||
HTSEXT_API char *unescape_http_unharm(char *const catbuff, const size_t size, const char *s, const int no_high);
|
byte through unchanged. */
|
||||||
HTSEXT_API char *antislash_unescaped(char *catbuff, const char *s);
|
HTSEXT_API size_t escape_for_html_print(const char *const s, char *const dest,
|
||||||
|
const size_t size);
|
||||||
|
|
||||||
HTSEXT_API void escape_remove_control(char *s);
|
/** Like escape_for_html_print() but also convert every high byte (>= 128) to a
|
||||||
HTSEXT_API int get_httptype_sized(httrackp *opt, char *s, size_t ssize,
|
numeric entity "&#xNN;". */
|
||||||
const char *fil, int flag);
|
HTSEXT_API size_t escape_for_html_print_full(const char *const s,
|
||||||
|
char *const dest,
|
||||||
|
const size_t size);
|
||||||
|
|
||||||
|
/** Percent-decode @p s into @p catbuff (capacity @p size) and return @p
|
||||||
|
catbuff. Decodes every "%xx" hex escape. */
|
||||||
|
HTSEXT_API char *unescape_http(char *const catbuff, const size_t size,
|
||||||
|
const char *const s);
|
||||||
|
|
||||||
|
/** Percent-decode @p s into @p catbuff, but only the escapes that are safe to
|
||||||
|
decode while keeping a valid URI (reserved, delimiter, unwise, control and
|
||||||
|
must-avoid escapes are kept encoded, and %25 is never decoded). @p no_high &
|
||||||
|
1 also decodes high (>= 128) bytes; @p no_high & 2 also decodes an escaped
|
||||||
|
space. Returns @p catbuff. */
|
||||||
|
HTSEXT_API char *unescape_http_unharm(char *const catbuff, const size_t size,
|
||||||
|
const char *s, const hts_boolean no_high);
|
||||||
|
|
||||||
|
/** Determine the MIME type of local file name @p fil into @p s (capacity
|
||||||
|
@p ssize): user --assume rules, then ".html", then the built-in extension
|
||||||
|
table. @p flag != 0 forces a fallback type. @return 1 if a type was written,
|
||||||
|
0 otherwise. */
|
||||||
|
HTSEXT_API hts_boolean get_httptype_sized(httrackp *opt, char *s, size_t ssize,
|
||||||
|
const char *fil, hts_boolean flag);
|
||||||
|
|
||||||
|
/** @deprecated Use get_httptype_sized(). Assumes @p s has at least
|
||||||
|
HTS_MIMETYPE_SIZE capacity. */
|
||||||
HTS_DEPRECATED("use get_httptype_sized(opt, s, ssize, fil, flag)")
|
HTS_DEPRECATED("use get_httptype_sized(opt, s, ssize, fil, flag)")
|
||||||
HTSEXT_API void get_httptype(httrackp * opt, char *s, const char *fil,
|
|
||||||
int flag);
|
HTSEXT_API void get_httptype(httrackp *opt, char *s, const char *fil, int flag);
|
||||||
HTSEXT_API int is_knowntype(httrackp * opt, const char *fil);
|
|
||||||
HTSEXT_API int is_userknowntype(httrackp * opt, const char *fil);
|
/** Classify @p fil by its extension: 0 unknown, 1 known non-HTML, 2 known HTML.
|
||||||
HTSEXT_API int is_dyntype(const char *fil);
|
Consults the built-in table then user --assume rules. 0 for a NULL @p fil.
|
||||||
|
*/
|
||||||
|
HTSEXT_API int is_knowntype(httrackp *opt, const char *fil);
|
||||||
|
|
||||||
|
/** Like is_knowntype() but consults only the user --assume rules: 0 no rule,
|
||||||
|
1 non-HTML, 2 HTML. */
|
||||||
|
HTSEXT_API int is_userknowntype(httrackp *opt, const char *fil);
|
||||||
|
|
||||||
|
/** 1 if @p fil, an extension such as "asp" or "php" (not a full filename), is a
|
||||||
|
known dynamic-page type, else 0. */
|
||||||
|
HTSEXT_API hts_boolean is_dyntype(const char *fil);
|
||||||
|
|
||||||
|
/** Extract the extension of @p fil (text after the last '.', stopping at '?')
|
||||||
|
into caller scratch @p catbuff (capacity @p size) and return it. Returns ""
|
||||||
|
(a literal, not @p catbuff) when there is no extension or it does not fit.
|
||||||
|
*/
|
||||||
HTSEXT_API const char *get_ext(char *catbuff, size_t size, const char *fil);
|
HTSEXT_API const char *get_ext(char *catbuff, size_t size, const char *fil);
|
||||||
HTSEXT_API int may_unknown(httrackp * opt, const char *st);
|
|
||||||
HTSEXT_API int guess_httptype_sized(httrackp *opt, char *s, size_t ssize,
|
/** 1 if MIME type @p st must not be reclassified or renamed (hypertext types
|
||||||
const char *fil);
|
and a built-in keep-list of commonly mislabeled types), else 0. */
|
||||||
|
HTSEXT_API hts_boolean may_unknown(httrackp *opt, const char *st);
|
||||||
|
|
||||||
|
/** Guess the MIME type of local file @p fil into @p s (capacity @p ssize),
|
||||||
|
always producing a type. @return 1 if a type was written. */
|
||||||
|
HTSEXT_API hts_boolean guess_httptype_sized(httrackp *opt, char *s,
|
||||||
|
size_t ssize, const char *fil);
|
||||||
|
|
||||||
|
/** @deprecated Use guess_httptype_sized(). Assumes @p s has at least
|
||||||
|
HTS_MIMETYPE_SIZE capacity. */
|
||||||
HTS_DEPRECATED("use guess_httptype_sized(opt, s, ssize, fil)")
|
HTS_DEPRECATED("use guess_httptype_sized(opt, s, ssize, fil)")
|
||||||
HTSEXT_API void guess_httptype(httrackp * opt, char *s, const char *fil);
|
|
||||||
|
HTSEXT_API void guess_httptype(httrackp *opt, char *s, const char *fil);
|
||||||
|
|
||||||
/* Ugly string tools */
|
/* Ugly string tools */
|
||||||
HTSEXT_API char *concat(char *catbuff, size_t size, const char *a, const char *b);
|
/* These take a caller scratch buffer catbuff of capacity size and return it. On
|
||||||
HTSEXT_API char *fconcat(char *catbuff, size_t size, const char *a, const char *b);
|
overflow they stop without writing past size and return the truncated buffer.
|
||||||
|
size must be a real array sizeof (the macros below check this at compile
|
||||||
|
time), not a pointer. */
|
||||||
|
/** Concatenate @p a and @p b into @p catbuff (NULL or empty operands are
|
||||||
|
* skipped). */
|
||||||
|
HTSEXT_API char *concat(char *catbuff, size_t size, const char *a,
|
||||||
|
const char *b);
|
||||||
|
|
||||||
|
/** Like concat(a, b) but convert '/' to the platform path separator (Windows).
|
||||||
|
*/
|
||||||
|
HTSEXT_API char *fconcat(char *catbuff, size_t size, const char *a,
|
||||||
|
const char *b);
|
||||||
|
|
||||||
|
/** Copy @p a into @p catbuff, converting '/' to the platform path separator
|
||||||
|
(Windows). */
|
||||||
HTSEXT_API char *fconv(char *catbuff, size_t size, const char *a);
|
HTSEXT_API char *fconv(char *catbuff, size_t size, const char *a);
|
||||||
|
|
||||||
|
/** Copy @p a into @p catbuff, converting every '\\' to '/' on all platforms. */
|
||||||
HTSEXT_API char *fslash(char *catbuff, size_t size, const char *a);
|
HTSEXT_API char *fslash(char *catbuff, size_t size, const char *a);
|
||||||
|
|
||||||
/* Debugging */
|
/* Debugging */
|
||||||
|
/** Set the process-global debug verbosity (0 is off); higher levels log more to
|
||||||
|
stderr. Bit 0x80 redirects debug output to "hts-debug.txt". */
|
||||||
HTSEXT_API void hts_debug(int level);
|
HTSEXT_API void hts_debug(int level);
|
||||||
|
|
||||||
/* Portable directory API */
|
/* Portable directory API */
|
||||||
@@ -276,6 +682,7 @@ HTSEXT_API void hts_debug(int level);
|
|||||||
#ifndef HTS_DEF_FWSTRUCT_find_handle_struct
|
#ifndef HTS_DEF_FWSTRUCT_find_handle_struct
|
||||||
#define HTS_DEF_FWSTRUCT_find_handle_struct
|
#define HTS_DEF_FWSTRUCT_find_handle_struct
|
||||||
typedef struct find_handle_struct find_handle_struct;
|
typedef struct find_handle_struct find_handle_struct;
|
||||||
|
|
||||||
typedef find_handle_struct *find_handle;
|
typedef find_handle_struct *find_handle;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -283,22 +690,53 @@ typedef find_handle_struct *find_handle;
|
|||||||
#define HTS_DEF_FWSTRUCT_topindex_chain
|
#define HTS_DEF_FWSTRUCT_topindex_chain
|
||||||
typedef struct topindex_chain topindex_chain;
|
typedef struct topindex_chain topindex_chain;
|
||||||
#endif
|
#endif
|
||||||
|
/** One node of the index/category listing built when generating the top index.
|
||||||
|
*/
|
||||||
struct topindex_chain {
|
struct topindex_chain {
|
||||||
int level; /* sort level */
|
int level; /**< sort level */
|
||||||
char *category; /* category */
|
char *category; /**< category (heap string) */
|
||||||
char name[2048]; /* path */
|
char name[2048]; /**< path */
|
||||||
struct topindex_chain *next; /* next element */
|
struct topindex_chain *next; /**< next element */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Open directory @p path for iteration, positioned on the first entry. Returns
|
||||||
|
an opaque handle to free with hts_findclose(), or NULL on empty path or open
|
||||||
|
failure. */
|
||||||
HTSEXT_API find_handle hts_findfirst(char *path);
|
HTSEXT_API find_handle hts_findfirst(char *path);
|
||||||
HTSEXT_API int hts_findnext(find_handle find);
|
|
||||||
|
/** Advance to the next directory entry. Returns 1 if an entry is available, 0
|
||||||
|
at end of directory. */
|
||||||
|
HTSEXT_API hts_boolean hts_findnext(find_handle find);
|
||||||
|
|
||||||
|
/** Close the iteration and free @p find. Always returns 0; NULL is accepted. */
|
||||||
HTSEXT_API int hts_findclose(find_handle find);
|
HTSEXT_API int hts_findclose(find_handle find);
|
||||||
|
|
||||||
|
/** Name of the current entry, or NULL. Points into the handle's storage; valid
|
||||||
|
only until the next hts_findnext()/hts_findclose(). */
|
||||||
HTSEXT_API char *hts_findgetname(find_handle find);
|
HTSEXT_API char *hts_findgetname(find_handle find);
|
||||||
|
|
||||||
|
/** Size in bytes of the current entry, or -1. Truncated to int, so unreliable
|
||||||
|
for files larger than 2 GB. */
|
||||||
HTSEXT_API int hts_findgetsize(find_handle find);
|
HTSEXT_API int hts_findgetsize(find_handle find);
|
||||||
HTSEXT_API int hts_findisdir(find_handle find);
|
|
||||||
HTSEXT_API int hts_findisfile(find_handle find);
|
/** 1 if the current entry is a directory, else 0 (a system/special entry, see
|
||||||
HTSEXT_API int hts_findissystem(find_handle find);
|
hts_findissystem(), reports 0). */
|
||||||
|
HTSEXT_API hts_boolean hts_findisdir(find_handle find);
|
||||||
|
|
||||||
|
/** 1 if the current entry is a regular file, else 0 (a system/special entry,
|
||||||
|
see hts_findissystem(), reports 0). */
|
||||||
|
HTSEXT_API hts_boolean hts_findisfile(find_handle find);
|
||||||
|
|
||||||
|
/** 1 if the current entry is a special/system entry to skip: "." or "..", on
|
||||||
|
POSIX also device/fifo/socket nodes, on Windows also system, hidden or
|
||||||
|
temporary entries. Else 0. */
|
||||||
|
HTSEXT_API hts_boolean hts_findissystem(find_handle find);
|
||||||
|
|
||||||
/* UTF-8 aware FILE API */
|
/* UTF-8 aware FILE API */
|
||||||
|
/* On non-Windows these macros resolve directly to the POSIX calls. On Windows
|
||||||
|
they map to the hts_*_utf8 wrappers below, which convert the UTF-8 path to
|
||||||
|
UTF-16 and call the wide CRT, falling back to the narrow CRT if conversion
|
||||||
|
fails. Always pass UTF-8 paths through these. */
|
||||||
#ifndef HTS_DEF_FILEAPI
|
#ifndef HTS_DEF_FILEAPI
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define FOPEN hts_fopen_utf8
|
#define FOPEN hts_fopen_utf8
|
||||||
@@ -306,7 +744,8 @@ HTSEXT_API FILE *hts_fopen_utf8(const char *path, const char *mode);
|
|||||||
|
|
||||||
#define STAT hts_stat_utf8
|
#define STAT hts_stat_utf8
|
||||||
typedef struct _stat STRUCT_STAT;
|
typedef struct _stat STRUCT_STAT;
|
||||||
HTSEXT_API int hts_stat_utf8(const char *path, STRUCT_STAT * buf);
|
|
||||||
|
HTSEXT_API int hts_stat_utf8(const char *path, STRUCT_STAT *buf);
|
||||||
|
|
||||||
#define UNLINK hts_unlink_utf8
|
#define UNLINK hts_unlink_utf8
|
||||||
HTSEXT_API int hts_unlink_utf8(const char *pathname);
|
HTSEXT_API int hts_unlink_utf8(const char *pathname);
|
||||||
@@ -315,12 +754,15 @@ HTSEXT_API int hts_unlink_utf8(const char *pathname);
|
|||||||
HTSEXT_API int hts_rename_utf8(const char *oldpath, const char *newpath);
|
HTSEXT_API int hts_rename_utf8(const char *oldpath, const char *newpath);
|
||||||
|
|
||||||
#define MKDIR(F) hts_mkdir_utf8(F)
|
#define MKDIR(F) hts_mkdir_utf8(F)
|
||||||
|
|
||||||
HTSEXT_API int hts_mkdir_utf8(const char *pathname);
|
HTSEXT_API int hts_mkdir_utf8(const char *pathname);
|
||||||
|
|
||||||
#define UTIME(A,B) hts_utime_utf8(A,B)
|
#define UTIME(A, B) hts_utime_utf8(A, B)
|
||||||
|
|
||||||
typedef struct _utimbuf STRUCT_UTIMBUF;
|
typedef struct _utimbuf STRUCT_UTIMBUF;
|
||||||
|
|
||||||
HTSEXT_API int hts_utime_utf8(const char *filename,
|
HTSEXT_API int hts_utime_utf8(const char *filename,
|
||||||
const STRUCT_UTIMBUF * times);
|
const STRUCT_UTIMBUF *times);
|
||||||
#else
|
#else
|
||||||
#define FOPEN fopen
|
#define FOPEN fopen
|
||||||
#define STAT stat
|
#define STAT stat
|
||||||
@@ -329,27 +771,32 @@ typedef struct stat STRUCT_STAT;
|
|||||||
#define UNLINK unlink
|
#define UNLINK unlink
|
||||||
#define RENAME rename
|
#define RENAME rename
|
||||||
#define MKDIR(F) mkdir(F, HTS_ACCESS_FOLDER)
|
#define MKDIR(F) mkdir(F, HTS_ACCESS_FOLDER)
|
||||||
|
|
||||||
typedef struct utimbuf STRUCT_UTIMBUF;
|
typedef struct utimbuf STRUCT_UTIMBUF;
|
||||||
|
|
||||||
#define UTIME(A,B) utime(A,B)
|
#define UTIME(A, B) utime(A, B)
|
||||||
#endif
|
#endif
|
||||||
#define HTS_DEF_FILEAPI
|
#define HTS_DEF_FILEAPI
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** Macro aimed to break at build-time if a size is not a sizeof() strictly
|
/** Macro aimed to break at build-time if a size is not a sizeof() strictly
|
||||||
* greater than sizeof(char*). **/
|
* greater than sizeof(char*). **/
|
||||||
#undef COMPILE_TIME_CHECK_SIZE
|
#undef COMPILE_TIME_CHECK_SIZE
|
||||||
#define COMPILE_TIME_CHECK_SIZE(A) (void) ((void (*)(char[A - sizeof(char*) - 1])) NULL)
|
#define COMPILE_TIME_CHECK_SIZE(A) \
|
||||||
|
(void) ((void (*)(char[A - sizeof(char *) - 1])) NULL)
|
||||||
|
|
||||||
/** Macro aimed to break at compile-time if a size is not a sizeof() strictly
|
/** Macro aimed to break at compile-time if a size is not a sizeof() strictly
|
||||||
* greater than sizeof(char*). **/
|
* greater than sizeof(char*). **/
|
||||||
#undef RUNTIME_TIME_CHECK_SIZE
|
#undef RUNTIME_TIME_CHECK_SIZE
|
||||||
#define RUNTIME_TIME_CHECK_SIZE(A) assertf((A) != sizeof(void*))
|
#define RUNTIME_TIME_CHECK_SIZE(A) assertf((A) != sizeof(void *))
|
||||||
|
|
||||||
#define fconv(A,B,C) (COMPILE_TIME_CHECK_SIZE(B), fconv(A,B,C))
|
#define fconv(A, B, C) (COMPILE_TIME_CHECK_SIZE(B), fconv(A, B, C))
|
||||||
#define concat(A,B,C,D) (COMPILE_TIME_CHECK_SIZE(B), concat(A,B,C,D))
|
|
||||||
#define fconcat(A,B,C,D) (COMPILE_TIME_CHECK_SIZE(B), fconcat(A,B,C,D))
|
#define concat(A, B, C, D) (COMPILE_TIME_CHECK_SIZE(B), concat(A, B, C, D))
|
||||||
#define fslash(A,B,C) (COMPILE_TIME_CHECK_SIZE(B), fslash(A,B,C))
|
|
||||||
|
#define fconcat(A, B, C, D) (COMPILE_TIME_CHECK_SIZE(B), fconcat(A, B, C, D))
|
||||||
|
|
||||||
|
#define fslash(A, B, C) (COMPILE_TIME_CHECK_SIZE(B), fslash(A, B, C))
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -288,7 +288,7 @@ static void __cdecl htsshow_uninit(t_hts_callbackarg * carg) {
|
|||||||
}
|
}
|
||||||
static int __cdecl htsshow_start(t_hts_callbackarg * carg, httrackp * opt) {
|
static int __cdecl htsshow_start(t_hts_callbackarg * carg, httrackp * opt) {
|
||||||
use_show = 0;
|
use_show = 0;
|
||||||
if (opt->verbosedisplay == 2) {
|
if (opt->verbosedisplay == HTS_VERBOSE_FULL) {
|
||||||
use_show = 1;
|
use_show = 1;
|
||||||
vt_clear();
|
vt_clear();
|
||||||
}
|
}
|
||||||
@@ -852,7 +852,7 @@ static void sig_doback(int blind) { // mettre en backing
|
|||||||
if (global_opt != NULL) {
|
if (global_opt != NULL) {
|
||||||
// suppress logging and asking lousy questions
|
// suppress logging and asking lousy questions
|
||||||
global_opt->quiet = 1;
|
global_opt->quiet = 1;
|
||||||
global_opt->verbosedisplay = 0;
|
global_opt->verbosedisplay = HTS_VERBOSE_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!blind)
|
if (!blind)
|
||||||
|
|||||||
@@ -1176,11 +1176,15 @@ static void proxytrack_process_HTTP(PT_Indexes indexes, T_SOC soc_c) {
|
|||||||
if (element != NULL) {
|
if (element != NULL) {
|
||||||
msgCode = element->statuscode;
|
msgCode = element->statuscode;
|
||||||
StringRoom(headers, 8192);
|
StringRoom(headers, 8192);
|
||||||
sprintf(StringBuffRW(headers), "HTTP/1.1 %d %s\r\n"
|
sprintf(StringBuffRW(headers),
|
||||||
|
"HTTP/1.1 %d %s\r\n"
|
||||||
#ifndef NO_WEBDAV
|
#ifndef NO_WEBDAV
|
||||||
"%s"
|
"%s"
|
||||||
#endif
|
#endif
|
||||||
"Content-Type: %s%s%s%s\r\n" "%s%s%s" "%s%s%s" "%s%s%s",
|
"Content-Type: %s%s%s%s\r\n"
|
||||||
|
"%s%s%s"
|
||||||
|
"%s%s%s"
|
||||||
|
"%s%s%s",
|
||||||
/* */
|
/* */
|
||||||
msgCode, element->msg,
|
msgCode, element->msg,
|
||||||
#ifndef NO_WEBDAV
|
#ifndef NO_WEBDAV
|
||||||
@@ -1188,16 +1192,18 @@ static void proxytrack_process_HTTP(PT_Indexes indexes, T_SOC soc_c) {
|
|||||||
StringBuff(davHeaders),
|
StringBuff(davHeaders),
|
||||||
#endif
|
#endif
|
||||||
/* Content-type: foo; [ charset=bar ] */
|
/* Content-type: foo; [ charset=bar ] */
|
||||||
element->contenttype,
|
hts_effective_mime(element->contenttype),
|
||||||
((element->charset[0]) ? "; charset=\"" : ""),
|
((element->charset[0]) ? "; charset=\"" : ""),
|
||||||
element->charset, ((element->charset[0]) ? "\"" : ""),
|
element->charset, ((element->charset[0]) ? "\"" : ""),
|
||||||
/* location */
|
/* location */
|
||||||
((element->location != NULL
|
((element->location != NULL && element->location[0])
|
||||||
&& element->location[0]) ? "Location: " : ""),
|
? "Location: "
|
||||||
((element->location != NULL
|
: ""),
|
||||||
&& element->location[0]) ? element->location : ""),
|
((element->location != NULL && element->location[0])
|
||||||
((element->location != NULL
|
? element->location
|
||||||
&& element->location[0]) ? "\r\n" : ""),
|
: ""),
|
||||||
|
((element->location != NULL && element->location[0]) ? "\r\n"
|
||||||
|
: ""),
|
||||||
/* last-modified */
|
/* last-modified */
|
||||||
((element->lastmodified[0]) ? "Last-Modified: " : ""),
|
((element->lastmodified[0]) ? "Last-Modified: " : ""),
|
||||||
((element->lastmodified[0]) ? element->lastmodified : ""),
|
((element->lastmodified[0]) ? element->lastmodified : ""),
|
||||||
@@ -1205,8 +1211,7 @@ static void proxytrack_process_HTTP(PT_Indexes indexes, T_SOC soc_c) {
|
|||||||
/* etag */
|
/* etag */
|
||||||
((element->etag[0]) ? "ETag: " : ""),
|
((element->etag[0]) ? "ETag: " : ""),
|
||||||
((element->etag[0]) ? element->etag : ""),
|
((element->etag[0]) ? element->etag : ""),
|
||||||
((element->etag[0]) ? "\r\n" : "")
|
((element->etag[0]) ? "\r\n" : ""));
|
||||||
);
|
|
||||||
StringLength(headers) = (int) strlen(StringBuff(headers));
|
StringLength(headers) = (int) strlen(StringBuff(headers));
|
||||||
} else {
|
} else {
|
||||||
/* No query string, no ending / : check the the <url>/ page */
|
/* No query string, no ending / : check the the <url>/ page */
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ Please visit our Website: http://www.httrack.com
|
|||||||
|
|
||||||
#include "htscore.h"
|
#include "htscore.h"
|
||||||
#include "htsback.h"
|
#include "htsback.h"
|
||||||
|
#include "htslib.h" /* hts_effective_mime */
|
||||||
|
|
||||||
#include "store.h"
|
#include "store.h"
|
||||||
#include "proxystrings.h"
|
#include "proxystrings.h"
|
||||||
@@ -2289,10 +2290,17 @@ static int PT_SaveCache__Arc_Fun(void *arg, const char *url, PT_Element element)
|
|||||||
int size_headers;
|
int size_headers;
|
||||||
|
|
||||||
sprintf(st->headers,
|
sprintf(st->headers,
|
||||||
"HTTP/1.0 %d %s" "\r\n" "X-Server: ProxyTrack " PROXYTRACK_VERSION
|
"HTTP/1.0 %d %s"
|
||||||
"\r\n" "Content-type: %s%s%s%s" "\r\n" "Last-modified: %s" "\r\n"
|
"\r\n"
|
||||||
"Content-length: %d" "\r\n", element->statuscode, element->msg,
|
"X-Server: ProxyTrack " PROXYTRACK_VERSION "\r\n"
|
||||||
/**/ element->contenttype,
|
"Content-type: %s%s%s%s"
|
||||||
|
"\r\n"
|
||||||
|
"Last-modified: %s"
|
||||||
|
"\r\n"
|
||||||
|
"Content-length: %d"
|
||||||
|
"\r\n",
|
||||||
|
element->statuscode, element->msg,
|
||||||
|
/**/ hts_effective_mime(element->contenttype),
|
||||||
(element->charset[0] ? "; charset=\"" : ""),
|
(element->charset[0] ? "; charset=\"" : ""),
|
||||||
(element->charset[0] ? element->charset : ""),
|
(element->charset[0] ? element->charset : ""),
|
||||||
(element->charset[0] ? "\"" : ""), /**/ element->lastmodified,
|
(element->charset[0] ? "\"" : ""), /**/ element->lastmodified,
|
||||||
@@ -2328,10 +2336,10 @@ static int PT_SaveCache__Arc_Fun(void *arg, const char *url, PT_Element element)
|
|||||||
/* args */
|
/* args */
|
||||||
(link_has_authority(url) ? "" : "http://"), url, "0.0.0.0",
|
(link_has_authority(url) ? "" : "http://"), url, "0.0.0.0",
|
||||||
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour,
|
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour,
|
||||||
tm->tm_min, tm->tm_sec, element->contenttype, element->statuscode,
|
tm->tm_min, tm->tm_sec, hts_effective_mime(element->contenttype),
|
||||||
st->md5, (element->location ? element->location : "-"),
|
element->statuscode, st->md5,
|
||||||
(long int) ftell(fp), st->filename,
|
(element->location ? element->location : "-"), (long int) ftell(fp),
|
||||||
(long int) (size_headers + element->size));
|
st->filename, (long int) (size_headers + element->size));
|
||||||
/* network_doc */
|
/* network_doc */
|
||||||
if (fwrite(st->headers, 1, size_headers, fp) != size_headers
|
if (fwrite(st->headers, 1, size_headers, fp) != size_headers
|
||||||
|| (element->size > 0
|
|| (element->size > 0
|
||||||
|
|||||||
149
src/webhttrack
149
src/webhttrack
@@ -4,131 +4,140 @@
|
|||||||
# Initializes the htsserver GUI frontend and launch the default browser
|
# Initializes the htsserver GUI frontend and launch the default browser
|
||||||
|
|
||||||
BROWSEREXE=
|
BROWSEREXE=
|
||||||
SRCHBROWSEREXE="x-www-browser www-browser iceape mozilla firefox-developer-edition firefox icecat iceweasel abrowser firebird galeon konqueror midori opera google-chrome chrome chromium chromium-browser netscape firefox-developer-edition"
|
SRCHBROWSEREXE=(x-www-browser www-browser iceape mozilla firefox-developer-edition firefox icecat iceweasel abrowser firebird galeon konqueror midori opera google-chrome chrome chromium chromium-browser netscape firefox-developer-edition)
|
||||||
|
# shellcheck disable=SC2153 # BROWSER is the standard freedesktop env var, not a typo
|
||||||
if test -n "${BROWSER}"; then
|
if test -n "${BROWSER}"; then
|
||||||
# sensible-browser will f up if BROWSER is not set
|
# sensible-browser will f up if BROWSER is not set
|
||||||
SRCHBROWSEREXE="xdg-open sensible-browser ${SRCHBROWSEREXE}"
|
SRCHBROWSEREXE=(xdg-open sensible-browser "${SRCHBROWSEREXE[@]}")
|
||||||
fi
|
fi
|
||||||
# Patch for Darwin/Mac by Ross Williams
|
# Patch for Darwin/Mac by Ross Williams
|
||||||
if test "`uname -s`" == "Darwin"; then
|
if test "$(uname -s)" == "Darwin"; then
|
||||||
# Darwin/Mac OS X uses a system 'open' command to find
|
# Darwin/Mac OS X uses a system 'open' command to find
|
||||||
# the default browser. The -W flag causes it to wait for
|
# the default browser. The -W flag causes it to wait for
|
||||||
# the browser to exit
|
# the browser to exit
|
||||||
BROWSEREXE="/usr/bin/open -W"
|
BROWSEREXE="/usr/bin/open -W"
|
||||||
fi
|
fi
|
||||||
BINWD=`dirname "$0"`
|
BINWD=$(dirname "$0")
|
||||||
SRCHPATH="$BINWD /usr/local/bin /usr/share/bin /usr/bin /usr/lib/httrack /usr/local/lib/httrack /usr/local/share/httrack /opt/local/bin /sw/bin ${HOME}/usr/bin ${HOME}/bin"
|
SRCHPATH=("$BINWD" /usr/local/bin /usr/share/bin /usr/bin /usr/lib/httrack /usr/local/lib/httrack /usr/local/share/httrack /opt/local/bin /sw/bin "${HOME}/usr/bin" "${HOME}/bin")
|
||||||
SRCHPATH="$SRCHPATH "`echo $PATH | tr ":" " "`
|
IFS=':' read -ra pathdirs <<<"$PATH"
|
||||||
SRCHDISTPATH="$BINWD/../share $BINWD/.. /usr/share /usr/local /usr /local /usr/local/share ${HOME}/usr ${HOME}/usr/share /opt/local/share /sw ${HOME}/usr/local ${HOME}/usr/share"
|
for d in "${pathdirs[@]}"; do
|
||||||
|
# drop empty PATH fields, matching the old echo|tr word-split
|
||||||
|
test -n "$d" && SRCHPATH+=("$d")
|
||||||
|
done
|
||||||
|
SRCHDISTPATH=("$BINWD/../share" "$BINWD/.." /usr/share /usr/local /usr /local /usr/local/share "${HOME}/usr" "${HOME}/usr/share" /opt/local/share /sw "${HOME}/usr/local" "${HOME}/usr/share")
|
||||||
|
|
||||||
###
|
###
|
||||||
# And now some famous cuisine
|
# And now some famous cuisine
|
||||||
|
|
||||||
function log {
|
function log {
|
||||||
echo "$0($$): $@" >&2
|
echo "$0($$): $*" >&2
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
function launch_browser {
|
function launch_browser {
|
||||||
log "Launching $1"
|
log "Launching $1"
|
||||||
browser=$1
|
browser=$1
|
||||||
url=$2
|
url=$2
|
||||||
log "Spawning browser.."
|
log "Spawning browser.."
|
||||||
${browser} "${url}"
|
${browser} "${url}"
|
||||||
# note: browser can hiddenly use the -remote feature of
|
# note: browser can hiddenly use the -remote feature of
|
||||||
# mozilla and therefore return immediately
|
# mozilla and therefore return immediately
|
||||||
log "Browser (or helper) exited"
|
log "Browser (or helper) exited"
|
||||||
}
|
}
|
||||||
|
|
||||||
# First ensure that we can launch the server
|
# First ensure that we can launch the server
|
||||||
BINPATH=
|
BINPATH=
|
||||||
for i in ${SRCHPATH}; do
|
for i in "${SRCHPATH[@]}"; do
|
||||||
! test -n "${BINPATH}" && test -x ${i}/htsserver && BINPATH=${i}
|
! test -n "${BINPATH}" && test -x "${i}/htsserver" && BINPATH="${i}"
|
||||||
done
|
done
|
||||||
for i in ${SRCHDISTPATH}; do
|
for i in "${SRCHDISTPATH[@]}"; do
|
||||||
! test -n "${DISTPATH}" && test -f "${i}/httrack/lang.def" && DISTPATH="${i}/httrack"
|
! test -n "${DISTPATH}" && test -f "${i}/httrack/lang.def" && DISTPATH="${i}/httrack"
|
||||||
done
|
done
|
||||||
test -n "${BINPATH}" || ! log "Could not find htsserver" || exit 1
|
test -n "${BINPATH}" || ! log "Could not find htsserver" || exit 1
|
||||||
test -n "${DISTPATH}" || ! log "Could not find httrack directory" || exit 1
|
test -n "${DISTPATH}" || ! log "Could not find httrack directory" || exit 1
|
||||||
test -f ${DISTPATH}/lang.def || ! log "Could not find ${DISTPATH}/lang.def" || exit 1
|
test -f "${DISTPATH}/lang.def" || ! log "Could not find ${DISTPATH}/lang.def" || exit 1
|
||||||
test -f ${DISTPATH}/lang.indexes || ! log "Could not find ${DISTPATH}/lang.indexes" || exit 1
|
test -f "${DISTPATH}/lang.indexes" || ! log "Could not find ${DISTPATH}/lang.indexes" || exit 1
|
||||||
test -d ${DISTPATH}/lang || ! log "Could not find ${DISTPATH}/lang" || exit 1
|
test -d "${DISTPATH}/lang" || ! log "Could not find ${DISTPATH}/lang" || exit 1
|
||||||
test -d ${DISTPATH}/html || ! log "Could not find ${DISTPATH}/html" || exit 1
|
test -d "${DISTPATH}/html" || ! log "Could not find ${DISTPATH}/html" || exit 1
|
||||||
|
|
||||||
# Locale
|
# Locale
|
||||||
HTSLANG="${LC_MESSAGES}"
|
HTSLANG="${LC_MESSAGES}"
|
||||||
! test -n "${HTSLANG}" && HTSLANG="${LC_ALL}"
|
! test -n "${HTSLANG}" && HTSLANG="${LC_ALL}"
|
||||||
! test -n "${HTSLANG}" && HTSLANG="${LANG}"
|
! test -n "${HTSLANG}" && HTSLANG="${LANG}"
|
||||||
HTSLANG="`echo $LANG | cut -f1 -d'.' | cut -f1 -d'_'`"
|
HTSLANG="$(echo "$LANG" | cut -f1 -d'.' | cut -f1 -d'_')"
|
||||||
LANGN=`grep -E "^${HTSLANG}:" ${DISTPATH}/lang.indexes | cut -f2 -d':'`
|
LANGN=$(grep -E "^${HTSLANG}:" "${DISTPATH}/lang.indexes" | cut -f2 -d':')
|
||||||
! test -n "${LANGN}" && LANGN=1
|
! test -n "${LANGN}" && LANGN=1
|
||||||
|
|
||||||
# Find the browser
|
# Find the browser
|
||||||
# note: not all systems have sensible-browser or www-browser alternative
|
# note: not all systems have sensible-browser or www-browser alternative
|
||||||
# thefeore, we have to find a bit more if sensible-browser could not be found
|
# thefeore, we have to find a bit more if sensible-browser could not be found
|
||||||
|
|
||||||
for i in ${SRCHBROWSEREXE}; do
|
for i in "${SRCHBROWSEREXE[@]}"; do
|
||||||
for j in ${SRCHPATH}; do
|
for j in "${SRCHPATH[@]}"; do
|
||||||
if test -x ${j}/${i}; then
|
if test -x "${j}/${i}"; then
|
||||||
BROWSEREXE=${j}/${i}
|
BROWSEREXE="${j}/${i}"
|
||||||
fi
|
fi
|
||||||
test -n "$BROWSEREXE" && break
|
test -n "$BROWSEREXE" && break
|
||||||
done
|
done
|
||||||
test -n "$BROWSEREXE" && break
|
test -n "$BROWSEREXE" && break
|
||||||
done
|
done
|
||||||
test -n "$BROWSEREXE" || ! log "Could not find any suitable browser" || exit 1
|
test -n "$BROWSEREXE" || ! log "Could not find any suitable browser" || exit 1
|
||||||
|
|
||||||
# "browse" command
|
# "browse" command
|
||||||
if test "$1" = "browse"; then
|
if test "$1" = "browse"; then
|
||||||
if test -f "${HOME}/.httrack.ini"; then
|
if test -f "${HOME}/.httrack.ini"; then
|
||||||
INDEXF=`cat ${HOME}/.httrack.ini | tr '\r' '\n' | grep -E "^path=" | cut -f2- -d'='`
|
INDEXF=$(tr '\r' '\n' <"${HOME}/.httrack.ini" | grep -E "^path=" | cut -f2- -d'=')
|
||||||
if test -n "${INDEXF}" -a -d "${INDEXF}" -a -f "${INDEXF}/index.html"; then
|
if test -n "${INDEXF}" -a -d "${INDEXF}" -a -f "${INDEXF}/index.html"; then
|
||||||
INDEXF="${INDEXF}/index.html"
|
INDEXF="${INDEXF}/index.html"
|
||||||
else
|
else
|
||||||
INDEXF=""
|
INDEXF=""
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
if ! test -n "$INDEXF"; then
|
if ! test -n "$INDEXF"; then
|
||||||
INDEXF="${HOME}/websites/index.html"
|
INDEXF="${HOME}/websites/index.html"
|
||||||
fi
|
fi
|
||||||
launch_browser "${BROWSEREXE}" "file://${INDEXF}"
|
launch_browser "${BROWSEREXE}" "file://${INDEXF}"
|
||||||
exit $?
|
exit $?
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Create a temporary filename
|
# Create a temporary filename
|
||||||
TMPSRVFILE="$(mktemp ${TMPDIR:-/tmp}/.webhttrack.XXXXXXXX)" || ! log "Could not create the temporary file ${TMPSRVFILE}" || exit 1
|
TMPSRVFILE="$(mktemp "${TMPDIR:-/tmp}/.webhttrack.XXXXXXXX")" || ! log "Could not create the temporary file ${TMPSRVFILE}" || exit 1
|
||||||
# Launch htsserver binary and setup the server
|
# Launch htsserver binary and setup the server
|
||||||
(${BINPATH}/htsserver "${DISTPATH}/" --ppid "$$" path "${HOME}/websites" lang "${LANGN}" $@; echo SRVURL=error) > ${TMPSRVFILE}&
|
(
|
||||||
|
"${BINPATH}/htsserver" "${DISTPATH}/" --ppid "$$" path "${HOME}/websites" lang "${LANGN}" "$@"
|
||||||
|
echo SRVURL=error
|
||||||
|
) >"${TMPSRVFILE}" &
|
||||||
# Find the generated SRVURL
|
# Find the generated SRVURL
|
||||||
SRVURL=
|
SRVURL=
|
||||||
MAXCOUNT=60
|
MAXCOUNT=60
|
||||||
while ! test -n "$SRVURL"; do
|
while ! test -n "$SRVURL"; do
|
||||||
MAXCOUNT=$[$MAXCOUNT - 1]
|
MAXCOUNT=$((MAXCOUNT - 1))
|
||||||
test $MAXCOUNT -gt 0 || exit 1
|
test $MAXCOUNT -gt 0 || exit 1
|
||||||
test $MAXCOUNT -lt 50 && echo "waiting for server to reply.."
|
test $MAXCOUNT -lt 50 && echo "waiting for server to reply.."
|
||||||
SRVURL=`grep -E URL= ${TMPSRVFILE} | cut -f2- -d=`
|
SRVURL=$(grep -E URL= "${TMPSRVFILE}" | cut -f2- -d=)
|
||||||
test ! "$SRVURL" = "error" || ! log "Could not spawn htsserver" || exit 1
|
test ! "$SRVURL" = "error" || ! log "Could not spawn htsserver" || exit 1
|
||||||
test -n "$SRVURL" || sleep 1
|
test -n "$SRVURL" || sleep 1
|
||||||
done
|
done
|
||||||
|
|
||||||
# Cleanup function
|
# Cleanup function
|
||||||
|
# shellcheck disable=SC2120 # $1 is an optional "signal caught" marker; bare calls are intentional
|
||||||
function cleanup {
|
function cleanup {
|
||||||
test -n "$1" && log "Nasty signal caught, cleaning up.."
|
test -n "$1" && log "Nasty signal caught, cleaning up.."
|
||||||
# Do not kill if browser exited (chrome bug issue) ; server will die itself
|
# Do not kill if browser exited (chrome bug issue) ; server will die itself
|
||||||
test -n "$1" && test -f ${TMPSRVFILE} && SRVPID=`grep -E PID= ${TMPSRVFILE} | cut -f2- -d=`
|
test -n "$1" && test -f "${TMPSRVFILE}" && SRVPID=$(grep -E PID= "${TMPSRVFILE}" | cut -f2- -d=)
|
||||||
test -n "${SRVPID}" && kill -9 ${SRVPID}
|
test -n "${SRVPID}" && kill -9 "${SRVPID}"
|
||||||
test -f ${TMPSRVFILE} && rm ${TMPSRVFILE}
|
test -f "${TMPSRVFILE}" && rm "${TMPSRVFILE}"
|
||||||
test -n "$1" && log "..Done"
|
test -n "$1" && log "..Done"
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
# Cleanup in case of emergency
|
# Cleanup in case of emergency
|
||||||
trap "cleanup now; exit" 1 2 3 4 5 6 7 8 9 11 13 14 15 16 19 24 25
|
trap "cleanup now; exit" HUP INT QUIT ILL TRAP ABRT BUS FPE SEGV PIPE ALRM TERM STKFLT XCPU XFSZ
|
||||||
|
|
||||||
# Got SRVURL, launch browser
|
# Got SRVURL, launch browser
|
||||||
launch_browser "${BROWSEREXE}" "${SRVURL}"
|
launch_browser "${BROWSEREXE}" "${SRVURL}"
|
||||||
|
|
||||||
# That's all, folks!
|
# That's all, folks!
|
||||||
trap "" 1 2 3 4 5 6 7 8 9 11 13 14 15 16 19 24 25
|
trap "" HUP INT QUIT ILL TRAP ABRT BUS FPE SEGV PIPE ALRM TERM STKFLT XCPU XFSZ
|
||||||
cleanup
|
cleanup
|
||||||
exit 0
|
exit 0
|
||||||
|
|||||||
@@ -1,535 +0,0 @@
|
|||||||
# Makefile.in generated by automake 1.17 from Makefile.am.
|
|
||||||
# @configure_input@
|
|
||||||
|
|
||||||
# Copyright (C) 1994-2024 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
# This Makefile.in is free software; the Free Software Foundation
|
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
|
||||||
# with or without modifications, as long as this notice is preserved.
|
|
||||||
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
|
||||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
|
||||||
# PARTICULAR PURPOSE.
|
|
||||||
|
|
||||||
@SET_MAKE@
|
|
||||||
|
|
||||||
VPATH = @srcdir@
|
|
||||||
am__is_gnu_make = { \
|
|
||||||
if test -z '$(MAKELEVEL)'; then \
|
|
||||||
false; \
|
|
||||||
elif test -n '$(MAKE_HOST)'; then \
|
|
||||||
true; \
|
|
||||||
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
|
|
||||||
true; \
|
|
||||||
else \
|
|
||||||
false; \
|
|
||||||
fi; \
|
|
||||||
}
|
|
||||||
am__make_running_with_option = \
|
|
||||||
case $${target_option-} in \
|
|
||||||
?) ;; \
|
|
||||||
*) echo "am__make_running_with_option: internal error: invalid" \
|
|
||||||
"target option '$${target_option-}' specified" >&2; \
|
|
||||||
exit 1;; \
|
|
||||||
esac; \
|
|
||||||
has_opt=no; \
|
|
||||||
sane_makeflags=$$MAKEFLAGS; \
|
|
||||||
if $(am__is_gnu_make); then \
|
|
||||||
sane_makeflags=$$MFLAGS; \
|
|
||||||
else \
|
|
||||||
case $$MAKEFLAGS in \
|
|
||||||
*\\[\ \ ]*) \
|
|
||||||
bs=\\; \
|
|
||||||
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
|
|
||||||
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
|
|
||||||
esac; \
|
|
||||||
fi; \
|
|
||||||
skip_next=no; \
|
|
||||||
strip_trailopt () \
|
|
||||||
{ \
|
|
||||||
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
|
|
||||||
}; \
|
|
||||||
for flg in $$sane_makeflags; do \
|
|
||||||
test $$skip_next = yes && { skip_next=no; continue; }; \
|
|
||||||
case $$flg in \
|
|
||||||
*=*|--*) continue;; \
|
|
||||||
-*I) strip_trailopt 'I'; skip_next=yes;; \
|
|
||||||
-*I?*) strip_trailopt 'I';; \
|
|
||||||
-*O) strip_trailopt 'O'; skip_next=yes;; \
|
|
||||||
-*O?*) strip_trailopt 'O';; \
|
|
||||||
-*l) strip_trailopt 'l'; skip_next=yes;; \
|
|
||||||
-*l?*) strip_trailopt 'l';; \
|
|
||||||
-[dEDm]) skip_next=yes;; \
|
|
||||||
-[JT]) skip_next=yes;; \
|
|
||||||
esac; \
|
|
||||||
case $$flg in \
|
|
||||||
*$$target_option*) has_opt=yes; break;; \
|
|
||||||
esac; \
|
|
||||||
done; \
|
|
||||||
test $$has_opt = yes
|
|
||||||
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
|
|
||||||
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
|
|
||||||
am__rm_f = rm -f $(am__rm_f_notfound)
|
|
||||||
am__rm_rf = rm -rf $(am__rm_f_notfound)
|
|
||||||
pkgdatadir = $(datadir)/@PACKAGE@
|
|
||||||
pkgincludedir = $(includedir)/@PACKAGE@
|
|
||||||
pkglibdir = $(libdir)/@PACKAGE@
|
|
||||||
pkglibexecdir = $(libexecdir)/@PACKAGE@
|
|
||||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
|
||||||
install_sh_DATA = $(install_sh) -c -m 644
|
|
||||||
install_sh_PROGRAM = $(install_sh) -c
|
|
||||||
install_sh_SCRIPT = $(install_sh) -c
|
|
||||||
INSTALL_HEADER = $(INSTALL_DATA)
|
|
||||||
transform = $(program_transform_name)
|
|
||||||
NORMAL_INSTALL = :
|
|
||||||
PRE_INSTALL = :
|
|
||||||
POST_INSTALL = :
|
|
||||||
NORMAL_UNINSTALL = :
|
|
||||||
PRE_UNINSTALL = :
|
|
||||||
POST_UNINSTALL = :
|
|
||||||
build_triplet = @build@
|
|
||||||
host_triplet = @host@
|
|
||||||
subdir = templates
|
|
||||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
|
||||||
am__aclocal_m4_deps = $(top_srcdir)/m4/check_zlib.m4 \
|
|
||||||
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
|
|
||||||
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
|
|
||||||
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/snprintf.m4 \
|
|
||||||
$(top_srcdir)/m4/visibility.m4 $(top_srcdir)/configure.ac
|
|
||||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
|
||||||
$(ACLOCAL_M4)
|
|
||||||
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
|
|
||||||
mkinstalldirs = $(install_sh) -d
|
|
||||||
CONFIG_HEADER = $(top_builddir)/config.h
|
|
||||||
CONFIG_CLEAN_FILES =
|
|
||||||
CONFIG_CLEAN_VPATH_FILES =
|
|
||||||
AM_V_P = $(am__v_P_@AM_V@)
|
|
||||||
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
|
|
||||||
am__v_P_0 = false
|
|
||||||
am__v_P_1 = :
|
|
||||||
AM_V_GEN = $(am__v_GEN_@AM_V@)
|
|
||||||
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
|
|
||||||
am__v_GEN_0 = @echo " GEN " $@;
|
|
||||||
am__v_GEN_1 =
|
|
||||||
AM_V_at = $(am__v_at_@AM_V@)
|
|
||||||
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
|
|
||||||
am__v_at_0 = @
|
|
||||||
am__v_at_1 =
|
|
||||||
SOURCES =
|
|
||||||
DIST_SOURCES =
|
|
||||||
am__can_run_installinfo = \
|
|
||||||
case $$AM_UPDATE_INFO_DIR in \
|
|
||||||
n|no|NO) false;; \
|
|
||||||
*) (install-info --version) >/dev/null 2>&1;; \
|
|
||||||
esac
|
|
||||||
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
|
|
||||||
am__vpath_adj = case $$p in \
|
|
||||||
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
|
|
||||||
*) f=$$p;; \
|
|
||||||
esac;
|
|
||||||
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
|
|
||||||
am__install_max = 40
|
|
||||||
am__nobase_strip_setup = \
|
|
||||||
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
|
|
||||||
am__nobase_strip = \
|
|
||||||
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
|
|
||||||
am__nobase_list = $(am__nobase_strip_setup); \
|
|
||||||
for p in $$list; do echo "$$p $$p"; done | \
|
|
||||||
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
|
|
||||||
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
|
|
||||||
if (++n[$$2] == $(am__install_max)) \
|
|
||||||
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
|
|
||||||
END { for (dir in files) print dir, files[dir] }'
|
|
||||||
am__base_list = \
|
|
||||||
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
|
|
||||||
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
|
|
||||||
am__uninstall_files_from_dir = { \
|
|
||||||
{ test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|
|
||||||
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
|
|
||||||
$(am__cd) "$$dir" && echo $$files | $(am__xargs_n) 40 $(am__rm_f); }; \
|
|
||||||
}
|
|
||||||
am__installdirs = "$(DESTDIR)$(templatesdir)"
|
|
||||||
DATA = $(templates_DATA)
|
|
||||||
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
|
|
||||||
am__DIST_COMMON = $(srcdir)/Makefile.in
|
|
||||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
|
||||||
ACLOCAL = @ACLOCAL@
|
|
||||||
AMTAR = @AMTAR@
|
|
||||||
AM_CFLAGS = @AM_CFLAGS@
|
|
||||||
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
|
|
||||||
AR = @AR@
|
|
||||||
AUTOCONF = @AUTOCONF@
|
|
||||||
AUTOHEADER = @AUTOHEADER@
|
|
||||||
AUTOMAKE = @AUTOMAKE@
|
|
||||||
AWK = @AWK@
|
|
||||||
BASH = @BASH@
|
|
||||||
CC = @CC@
|
|
||||||
CCDEPMODE = @CCDEPMODE@
|
|
||||||
CFLAGS = @CFLAGS@
|
|
||||||
CFLAGS_PIE = @CFLAGS_PIE@
|
|
||||||
CFLAG_VISIBILITY = @CFLAG_VISIBILITY@
|
|
||||||
CPPFLAGS = @CPPFLAGS@
|
|
||||||
CSCOPE = @CSCOPE@
|
|
||||||
CTAGS = @CTAGS@
|
|
||||||
CYGPATH_W = @CYGPATH_W@
|
|
||||||
DEFAULT_CFLAGS = @DEFAULT_CFLAGS@
|
|
||||||
DEFAULT_LDFLAGS = @DEFAULT_LDFLAGS@
|
|
||||||
DEFS = @DEFS@
|
|
||||||
DEPDIR = @DEPDIR@
|
|
||||||
DLLTOOL = @DLLTOOL@
|
|
||||||
DL_LIBS = @DL_LIBS@
|
|
||||||
DSYMUTIL = @DSYMUTIL@
|
|
||||||
DUMPBIN = @DUMPBIN@
|
|
||||||
ECHO_C = @ECHO_C@
|
|
||||||
ECHO_N = @ECHO_N@
|
|
||||||
ECHO_T = @ECHO_T@
|
|
||||||
EGREP = @EGREP@
|
|
||||||
ETAGS = @ETAGS@
|
|
||||||
EXEEXT = @EXEEXT@
|
|
||||||
FGREP = @FGREP@
|
|
||||||
FILECMD = @FILECMD@
|
|
||||||
GREP = @GREP@
|
|
||||||
HAVE_VISIBILITY = @HAVE_VISIBILITY@
|
|
||||||
HTTPS_SUPPORT = @HTTPS_SUPPORT@
|
|
||||||
ICONV_LIBS = @ICONV_LIBS@
|
|
||||||
INSTALL = @INSTALL@
|
|
||||||
INSTALL_DATA = @INSTALL_DATA@
|
|
||||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
|
||||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
|
||||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
|
||||||
LD = @LD@
|
|
||||||
LDFLAGS = @LDFLAGS@
|
|
||||||
LDFLAGS_PIE = @LDFLAGS_PIE@
|
|
||||||
LFS_FLAG = @LFS_FLAG@
|
|
||||||
LIBC_FORCE_LINK = @LIBC_FORCE_LINK@
|
|
||||||
LIBOBJS = @LIBOBJS@
|
|
||||||
LIBS = @LIBS@
|
|
||||||
LIBTOOL = @LIBTOOL@
|
|
||||||
LIPO = @LIPO@
|
|
||||||
LN_S = @LN_S@
|
|
||||||
LTLIBOBJS = @LTLIBOBJS@
|
|
||||||
LT_CV_OBJDIR = @LT_CV_OBJDIR@
|
|
||||||
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
|
|
||||||
MAINT = @MAINT@
|
|
||||||
MAKEINFO = @MAKEINFO@
|
|
||||||
MANIFEST_TOOL = @MANIFEST_TOOL@
|
|
||||||
MKDIR_P = @MKDIR_P@
|
|
||||||
NM = @NM@
|
|
||||||
NMEDIT = @NMEDIT@
|
|
||||||
OBJDUMP = @OBJDUMP@
|
|
||||||
OBJEXT = @OBJEXT@
|
|
||||||
ONLINE_UNIT_TESTS = @ONLINE_UNIT_TESTS@
|
|
||||||
OPENSSL_LIBS = @OPENSSL_LIBS@
|
|
||||||
OTOOL = @OTOOL@
|
|
||||||
OTOOL64 = @OTOOL64@
|
|
||||||
PACKAGE = @PACKAGE@
|
|
||||||
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
|
||||||
PACKAGE_NAME = @PACKAGE_NAME@
|
|
||||||
PACKAGE_STRING = @PACKAGE_STRING@
|
|
||||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
|
||||||
PACKAGE_URL = @PACKAGE_URL@
|
|
||||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
|
||||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
|
||||||
RANLIB = @RANLIB@
|
|
||||||
SED = @SED@
|
|
||||||
SET_MAKE = @SET_MAKE@
|
|
||||||
SHELL = @SHELL@
|
|
||||||
SHLIBPATH_VAR = @SHLIBPATH_VAR@
|
|
||||||
SOCKET_LIBS = @SOCKET_LIBS@
|
|
||||||
STRIP = @STRIP@
|
|
||||||
THREADS_CFLAGS = @THREADS_CFLAGS@
|
|
||||||
THREADS_LIBS = @THREADS_LIBS@
|
|
||||||
V6_FLAG = @V6_FLAG@
|
|
||||||
VERSION = @VERSION@
|
|
||||||
VERSION_INFO = @VERSION_INFO@
|
|
||||||
abs_builddir = @abs_builddir@
|
|
||||||
abs_srcdir = @abs_srcdir@
|
|
||||||
abs_top_builddir = @abs_top_builddir@
|
|
||||||
abs_top_srcdir = @abs_top_srcdir@
|
|
||||||
ac_ct_AR = @ac_ct_AR@
|
|
||||||
ac_ct_CC = @ac_ct_CC@
|
|
||||||
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
|
|
||||||
am__include = @am__include@
|
|
||||||
am__leading_dot = @am__leading_dot@
|
|
||||||
am__quote = @am__quote@
|
|
||||||
am__rm_f_notfound = @am__rm_f_notfound@
|
|
||||||
am__tar = @am__tar@
|
|
||||||
am__untar = @am__untar@
|
|
||||||
am__xargs_n = @am__xargs_n@
|
|
||||||
bindir = @bindir@
|
|
||||||
build = @build@
|
|
||||||
build_alias = @build_alias@
|
|
||||||
build_cpu = @build_cpu@
|
|
||||||
build_os = @build_os@
|
|
||||||
build_vendor = @build_vendor@
|
|
||||||
builddir = @builddir@
|
|
||||||
datadir = @datadir@
|
|
||||||
datarootdir = @datarootdir@
|
|
||||||
docdir = @docdir@
|
|
||||||
dvidir = @dvidir@
|
|
||||||
exec_prefix = @exec_prefix@
|
|
||||||
host = @host@
|
|
||||||
host_alias = @host_alias@
|
|
||||||
host_cpu = @host_cpu@
|
|
||||||
host_os = @host_os@
|
|
||||||
host_vendor = @host_vendor@
|
|
||||||
htmldir = @htmldir@
|
|
||||||
includedir = @includedir@
|
|
||||||
infodir = @infodir@
|
|
||||||
install_sh = @install_sh@
|
|
||||||
libdir = @libdir@
|
|
||||||
libexecdir = @libexecdir@
|
|
||||||
localedir = @localedir@
|
|
||||||
localstatedir = @localstatedir@
|
|
||||||
mandir = @mandir@
|
|
||||||
mkdir_p = @mkdir_p@
|
|
||||||
oldincludedir = @oldincludedir@
|
|
||||||
pdfdir = @pdfdir@
|
|
||||||
prefix = @prefix@
|
|
||||||
program_transform_name = @program_transform_name@
|
|
||||||
psdir = @psdir@
|
|
||||||
runstatedir = @runstatedir@
|
|
||||||
sbindir = @sbindir@
|
|
||||||
sharedstatedir = @sharedstatedir@
|
|
||||||
srcdir = @srcdir@
|
|
||||||
sysconfdir = @sysconfdir@
|
|
||||||
target_alias = @target_alias@
|
|
||||||
top_build_prefix = @top_build_prefix@
|
|
||||||
top_builddir = @top_builddir@
|
|
||||||
top_srcdir = @top_srcdir@
|
|
||||||
templatesdir = $(datadir)/httrack/templates
|
|
||||||
templates_DATA = index-body.html index-header.html topindex-footer.html \
|
|
||||||
index-footer.html topindex-body.html topindex-header.html \
|
|
||||||
topindex-bodycat.html
|
|
||||||
|
|
||||||
EXTRA_DIST = $(templates_DATA)
|
|
||||||
all: all-am
|
|
||||||
|
|
||||||
.SUFFIXES:
|
|
||||||
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
|
|
||||||
@for dep in $?; do \
|
|
||||||
case '$(am__configure_deps)' in \
|
|
||||||
*$$dep*) \
|
|
||||||
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
|
|
||||||
&& { if test -f $@; then exit 0; else break; fi; }; \
|
|
||||||
exit 1;; \
|
|
||||||
esac; \
|
|
||||||
done; \
|
|
||||||
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu templates/Makefile'; \
|
|
||||||
$(am__cd) $(top_srcdir) && \
|
|
||||||
$(AUTOMAKE) --gnu templates/Makefile
|
|
||||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
|
||||||
@case '$?' in \
|
|
||||||
*config.status*) \
|
|
||||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
|
|
||||||
*) \
|
|
||||||
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
|
|
||||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
|
|
||||||
esac;
|
|
||||||
|
|
||||||
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
|
||||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
|
||||||
|
|
||||||
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
|
|
||||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
|
||||||
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
|
|
||||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
|
||||||
$(am__aclocal_m4_deps):
|
|
||||||
|
|
||||||
mostlyclean-libtool:
|
|
||||||
-rm -f *.lo
|
|
||||||
|
|
||||||
clean-libtool:
|
|
||||||
-rm -rf .libs _libs
|
|
||||||
install-templatesDATA: $(templates_DATA)
|
|
||||||
@$(NORMAL_INSTALL)
|
|
||||||
@list='$(templates_DATA)'; test -n "$(templatesdir)" || list=; \
|
|
||||||
if test -n "$$list"; then \
|
|
||||||
echo " $(MKDIR_P) '$(DESTDIR)$(templatesdir)'"; \
|
|
||||||
$(MKDIR_P) "$(DESTDIR)$(templatesdir)" || exit 1; \
|
|
||||||
fi; \
|
|
||||||
for p in $$list; do \
|
|
||||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
|
||||||
echo "$$d$$p"; \
|
|
||||||
done | $(am__base_list) | \
|
|
||||||
while read files; do \
|
|
||||||
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(templatesdir)'"; \
|
|
||||||
$(INSTALL_DATA) $$files "$(DESTDIR)$(templatesdir)" || exit $$?; \
|
|
||||||
done
|
|
||||||
|
|
||||||
uninstall-templatesDATA:
|
|
||||||
@$(NORMAL_UNINSTALL)
|
|
||||||
@list='$(templates_DATA)'; test -n "$(templatesdir)" || list=; \
|
|
||||||
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
|
|
||||||
dir='$(DESTDIR)$(templatesdir)'; $(am__uninstall_files_from_dir)
|
|
||||||
tags TAGS:
|
|
||||||
|
|
||||||
ctags CTAGS:
|
|
||||||
|
|
||||||
cscope cscopelist:
|
|
||||||
|
|
||||||
distdir: $(BUILT_SOURCES)
|
|
||||||
$(MAKE) $(AM_MAKEFLAGS) distdir-am
|
|
||||||
|
|
||||||
distdir-am: $(DISTFILES)
|
|
||||||
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
|
||||||
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
|
||||||
list='$(DISTFILES)'; \
|
|
||||||
dist_files=`for file in $$list; do echo $$file; done | \
|
|
||||||
sed -e "s|^$$srcdirstrip/||;t" \
|
|
||||||
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
|
|
||||||
case $$dist_files in \
|
|
||||||
*/*) $(MKDIR_P) `echo "$$dist_files" | \
|
|
||||||
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
|
|
||||||
sort -u` ;; \
|
|
||||||
esac; \
|
|
||||||
for file in $$dist_files; do \
|
|
||||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
|
||||||
if test -d $$d/$$file; then \
|
|
||||||
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
|
|
||||||
if test -d "$(distdir)/$$file"; then \
|
|
||||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
|
||||||
fi; \
|
|
||||||
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
|
||||||
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
|
|
||||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
|
||||||
fi; \
|
|
||||||
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
|
|
||||||
else \
|
|
||||||
test -f "$(distdir)/$$file" \
|
|
||||||
|| cp -p $$d/$$file "$(distdir)/$$file" \
|
|
||||||
|| exit 1; \
|
|
||||||
fi; \
|
|
||||||
done
|
|
||||||
check-am: all-am
|
|
||||||
check: check-am
|
|
||||||
all-am: Makefile $(DATA)
|
|
||||||
installdirs:
|
|
||||||
for dir in "$(DESTDIR)$(templatesdir)"; do \
|
|
||||||
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
|
|
||||||
done
|
|
||||||
install: install-am
|
|
||||||
install-exec: install-exec-am
|
|
||||||
install-data: install-data-am
|
|
||||||
uninstall: uninstall-am
|
|
||||||
|
|
||||||
install-am: all-am
|
|
||||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
|
||||||
|
|
||||||
installcheck: installcheck-am
|
|
||||||
install-strip:
|
|
||||||
if test -z '$(STRIP)'; then \
|
|
||||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
|
||||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
|
||||||
install; \
|
|
||||||
else \
|
|
||||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
|
||||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
|
||||||
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
|
|
||||||
fi
|
|
||||||
mostlyclean-generic:
|
|
||||||
|
|
||||||
clean-generic:
|
|
||||||
|
|
||||||
distclean-generic:
|
|
||||||
-$(am__rm_f) $(CONFIG_CLEAN_FILES)
|
|
||||||
-test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES)
|
|
||||||
|
|
||||||
maintainer-clean-generic:
|
|
||||||
@echo "This command is intended for maintainers to use"
|
|
||||||
@echo "it deletes files that may require special tools to rebuild."
|
|
||||||
clean: clean-am
|
|
||||||
|
|
||||||
clean-am: clean-generic clean-libtool mostlyclean-am
|
|
||||||
|
|
||||||
distclean: distclean-am
|
|
||||||
-rm -f Makefile
|
|
||||||
distclean-am: clean-am distclean-generic
|
|
||||||
|
|
||||||
dvi: dvi-am
|
|
||||||
|
|
||||||
dvi-am:
|
|
||||||
|
|
||||||
html: html-am
|
|
||||||
|
|
||||||
html-am:
|
|
||||||
|
|
||||||
info: info-am
|
|
||||||
|
|
||||||
info-am:
|
|
||||||
|
|
||||||
install-data-am: install-templatesDATA
|
|
||||||
|
|
||||||
install-dvi: install-dvi-am
|
|
||||||
|
|
||||||
install-dvi-am:
|
|
||||||
|
|
||||||
install-exec-am:
|
|
||||||
|
|
||||||
install-html: install-html-am
|
|
||||||
|
|
||||||
install-html-am:
|
|
||||||
|
|
||||||
install-info: install-info-am
|
|
||||||
|
|
||||||
install-info-am:
|
|
||||||
|
|
||||||
install-man:
|
|
||||||
|
|
||||||
install-pdf: install-pdf-am
|
|
||||||
|
|
||||||
install-pdf-am:
|
|
||||||
|
|
||||||
install-ps: install-ps-am
|
|
||||||
|
|
||||||
install-ps-am:
|
|
||||||
|
|
||||||
installcheck-am:
|
|
||||||
|
|
||||||
maintainer-clean: maintainer-clean-am
|
|
||||||
-rm -f Makefile
|
|
||||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
|
||||||
|
|
||||||
mostlyclean: mostlyclean-am
|
|
||||||
|
|
||||||
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
|
|
||||||
|
|
||||||
pdf: pdf-am
|
|
||||||
|
|
||||||
pdf-am:
|
|
||||||
|
|
||||||
ps: ps-am
|
|
||||||
|
|
||||||
ps-am:
|
|
||||||
|
|
||||||
uninstall-am: uninstall-templatesDATA
|
|
||||||
|
|
||||||
.MAKE: install-am install-strip
|
|
||||||
|
|
||||||
.PHONY: all all-am check check-am clean clean-generic clean-libtool \
|
|
||||||
cscopelist-am ctags-am distclean distclean-generic \
|
|
||||||
distclean-libtool distdir dvi dvi-am html html-am info info-am \
|
|
||||||
install install-am install-data install-data-am install-dvi \
|
|
||||||
install-dvi-am install-exec install-exec-am install-html \
|
|
||||||
install-html-am install-info install-info-am install-man \
|
|
||||||
install-pdf install-pdf-am install-ps install-ps-am \
|
|
||||||
install-strip install-templatesDATA installcheck \
|
|
||||||
installcheck-am installdirs maintainer-clean \
|
|
||||||
maintainer-clean-generic mostlyclean mostlyclean-generic \
|
|
||||||
mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \
|
|
||||||
uninstall-am uninstall-templatesDATA
|
|
||||||
|
|
||||||
.PRECIOUS: Makefile
|
|
||||||
|
|
||||||
|
|
||||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
|
||||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
|
||||||
.NOEXPORT:
|
|
||||||
|
|
||||||
# Tell GNU make to disable its built-in pattern rules.
|
|
||||||
%:: %,v
|
|
||||||
%:: RCS/%,v
|
|
||||||
%:: RCS/%
|
|
||||||
%:: s.%
|
|
||||||
%:: SCCS/s.%
|
|
||||||
160
test-driver
160
test-driver
@@ -1,160 +0,0 @@
|
|||||||
#! /bin/sh
|
|
||||||
# test-driver - basic testsuite driver script.
|
|
||||||
|
|
||||||
scriptversion=2024-06-19.01; # UTC
|
|
||||||
|
|
||||||
# Copyright (C) 2011-2024 Free Software Foundation, Inc.
|
|
||||||
#
|
|
||||||
# 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 2, 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 <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
# As a special exception to the GNU General Public License, if you
|
|
||||||
# distribute this file as part of a program that contains a
|
|
||||||
# configuration script generated by Autoconf, you may include it under
|
|
||||||
# the same distribution terms that you use for the rest of that program.
|
|
||||||
|
|
||||||
# This file is maintained in Automake, please report
|
|
||||||
# bugs to <bug-automake@gnu.org> or send patches to
|
|
||||||
# <automake-patches@gnu.org>.
|
|
||||||
|
|
||||||
# Make unconditional expansion of undefined variables an error. This
|
|
||||||
# helps a lot in preventing typo-related bugs.
|
|
||||||
set -u
|
|
||||||
|
|
||||||
usage_error ()
|
|
||||||
{
|
|
||||||
echo "$0: $*" >&2
|
|
||||||
print_usage >&2
|
|
||||||
exit 2
|
|
||||||
}
|
|
||||||
|
|
||||||
print_usage ()
|
|
||||||
{
|
|
||||||
cat <<END
|
|
||||||
Usage:
|
|
||||||
test-driver --test-name NAME --log-file PATH --trs-file PATH
|
|
||||||
[--expect-failure {yes|no}] [--color-tests {yes|no}]
|
|
||||||
[--collect-skipped-logs {yes|no}]
|
|
||||||
[--enable-hard-errors {yes|no}] [--]
|
|
||||||
TEST-SCRIPT [TEST-SCRIPT-ARGUMENTS]
|
|
||||||
|
|
||||||
The '--test-name', '--log-file' and '--trs-file' options are mandatory.
|
|
||||||
See the GNU Automake documentation for information.
|
|
||||||
|
|
||||||
Report bugs to <bug-automake@gnu.org>.
|
|
||||||
GNU Automake home page: <https://www.gnu.org/software/automake/>.
|
|
||||||
General help using GNU software: <https://www.gnu.org/gethelp/>.
|
|
||||||
END
|
|
||||||
}
|
|
||||||
|
|
||||||
test_name= # Used for reporting.
|
|
||||||
log_file= # Where to save the output of the test script.
|
|
||||||
trs_file= # Where to save the metadata of the test run.
|
|
||||||
expect_failure=no
|
|
||||||
color_tests=no
|
|
||||||
collect_skipped_logs=yes
|
|
||||||
enable_hard_errors=yes
|
|
||||||
while test $# -gt 0; do
|
|
||||||
case $1 in
|
|
||||||
--help) print_usage; exit $?;;
|
|
||||||
--version) echo "test-driver (GNU Automake) $scriptversion"; exit $?;;
|
|
||||||
--test-name) test_name=$2; shift;;
|
|
||||||
--log-file) log_file=$2; shift;;
|
|
||||||
--trs-file) trs_file=$2; shift;;
|
|
||||||
--color-tests) color_tests=$2; shift;;
|
|
||||||
--collect-skipped-logs) collect_skipped_logs=$2; shift;;
|
|
||||||
--expect-failure) expect_failure=$2; shift;;
|
|
||||||
--enable-hard-errors) enable_hard_errors=$2; shift;;
|
|
||||||
--) shift; break;;
|
|
||||||
-*) usage_error "invalid option: '$1'";;
|
|
||||||
*) break;;
|
|
||||||
esac
|
|
||||||
shift
|
|
||||||
done
|
|
||||||
|
|
||||||
missing_opts=
|
|
||||||
test x"$test_name" = x && missing_opts="$missing_opts --test-name"
|
|
||||||
test x"$log_file" = x && missing_opts="$missing_opts --log-file"
|
|
||||||
test x"$trs_file" = x && missing_opts="$missing_opts --trs-file"
|
|
||||||
if test x"$missing_opts" != x; then
|
|
||||||
usage_error "the following mandatory options are missing:$missing_opts"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test $# -eq 0; then
|
|
||||||
usage_error "missing argument"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test $color_tests = yes; then
|
|
||||||
# Keep this in sync with 'lib/am/check.am:$(am__tty_colors)'.
|
|
||||||
red='[0;31m' # Red.
|
|
||||||
grn='[0;32m' # Green.
|
|
||||||
lgn='[1;32m' # Light green.
|
|
||||||
blu='[1;34m' # Blue.
|
|
||||||
mgn='[0;35m' # Magenta.
|
|
||||||
std='[m' # No color.
|
|
||||||
else
|
|
||||||
red= grn= lgn= blu= mgn= std=
|
|
||||||
fi
|
|
||||||
|
|
||||||
do_exit='rm -f $log_file $trs_file; (exit $st); exit $st'
|
|
||||||
trap "st=129; $do_exit" 1
|
|
||||||
trap "st=130; $do_exit" 2
|
|
||||||
trap "st=141; $do_exit" 13
|
|
||||||
trap "st=143; $do_exit" 15
|
|
||||||
|
|
||||||
# Test script is run here. We create the file first, then append to it,
|
|
||||||
# to ameliorate tests themselves also writing to the log file. Our tests
|
|
||||||
# don't, but others can (automake bug#35762).
|
|
||||||
: >"$log_file"
|
|
||||||
"$@" >>"$log_file" 2>&1
|
|
||||||
estatus=$?
|
|
||||||
|
|
||||||
if test $enable_hard_errors = no && test $estatus -eq 99; then
|
|
||||||
tweaked_estatus=1
|
|
||||||
else
|
|
||||||
tweaked_estatus=$estatus
|
|
||||||
fi
|
|
||||||
|
|
||||||
case $tweaked_estatus:$expect_failure in
|
|
||||||
0:yes) col=$red res=XPASS recheck=yes gcopy=yes;;
|
|
||||||
0:*) col=$grn res=PASS recheck=no gcopy=no;;
|
|
||||||
77:*) col=$blu res=SKIP recheck=no gcopy=$collect_skipped_logs;;
|
|
||||||
99:*) col=$mgn res=ERROR recheck=yes gcopy=yes;;
|
|
||||||
*:yes) col=$lgn res=XFAIL recheck=no gcopy=yes;;
|
|
||||||
*:*) col=$red res=FAIL recheck=yes gcopy=yes;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
# Report the test outcome and exit status in the logs, so that one can
|
|
||||||
# know whether the test passed or failed simply by looking at the '.log'
|
|
||||||
# file, without the need of also peaking into the corresponding '.trs'
|
|
||||||
# file (automake bug#11814).
|
|
||||||
echo "$res $test_name (exit status: $estatus)" >>"$log_file"
|
|
||||||
|
|
||||||
# Report outcome to console.
|
|
||||||
echo "${col}${res}${std}: $test_name"
|
|
||||||
|
|
||||||
# Register the test result, and other relevant metadata.
|
|
||||||
echo ":test-result: $res" > $trs_file
|
|
||||||
echo ":global-test-result: $res" >> $trs_file
|
|
||||||
echo ":recheck: $recheck" >> $trs_file
|
|
||||||
echo ":copy-in-global-log: $gcopy" >> $trs_file
|
|
||||||
|
|
||||||
# Local Variables:
|
|
||||||
# mode: shell-script
|
|
||||||
# sh-indentation: 2
|
|
||||||
# eval: (add-hook 'before-save-hook 'time-stamp)
|
|
||||||
# time-stamp-start: "scriptversion="
|
|
||||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
|
||||||
# time-stamp-time-zone: "UTC0"
|
|
||||||
# time-stamp-end: "; # UTC"
|
|
||||||
# End:
|
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
#
|
#
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
# check that httrack starts
|
# check that httrack starts
|
||||||
httrack --version >/dev/null
|
httrack --version >/dev/null
|
||||||
|
|||||||
48
tests/01_engine-cache-golden.test
Normal file
48
tests/01_engine-cache-golden.test
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# Keep this POSIX-portable: the harness runs it via $(BASH), which is a plain
|
||||||
|
# POSIX /bin/sh on some platforms (e.g. macOS), so avoid bashisms and GNU-only
|
||||||
|
# tool flags despite the #!/bin/bash above.
|
||||||
|
|
||||||
|
# Golden cache-format regression test (driven by 'httrack -#test=cache-golden <dir>').
|
||||||
|
#
|
||||||
|
# 01_engine-cache.test writes the cache with the same build it reads back (a
|
||||||
|
# round-trip), so it cannot catch a read-path or ZIP-format regression where
|
||||||
|
# writer and reader drift together. This reads a *committed* cache frozen by an
|
||||||
|
# earlier build and asserts a fixed set of entries still decodes field- and
|
||||||
|
# byte-exact.
|
||||||
|
#
|
||||||
|
# Regenerate the fixture after a deliberate format change with
|
||||||
|
# 'httrack -#test=cache-golden <dir> regen', then copy <dir>/hts-cache/new.zip over the
|
||||||
|
# committed file.
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
: "${top_srcdir:=..}"
|
||||||
|
fixture="$top_srcdir/tests/fixtures/cache-golden"
|
||||||
|
|
||||||
|
test -e "$fixture/hts-cache/new.zip" || {
|
||||||
|
echo "missing committed cache fixture: $fixture/hts-cache/new.zip" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
dir=$(mktemp -d)
|
||||||
|
trap 'rm -rf "$dir"' EXIT
|
||||||
|
|
||||||
|
# Read against a private copy so the source tree is never touched (a read
|
||||||
|
# session does not write, but copying keeps the test hermetic). Create the dir
|
||||||
|
# with mkdir so it is writable for the cleanup trap: under "make distcheck" the
|
||||||
|
# srcdir is read-only, and "cp -r" of that directory would carry its read-only
|
||||||
|
# mode over and defeat the rm -rf.
|
||||||
|
mkdir -p "$dir/hts-cache"
|
||||||
|
cp "$fixture/hts-cache/new.zip" "$dir/hts-cache/new.zip"
|
||||||
|
|
||||||
|
out=$(httrack -#test=cache-golden "$dir")
|
||||||
|
|
||||||
|
# Match the exact success line: the read must have found and verified every
|
||||||
|
# entry, not merely failed to enter the mode (a renamed/removed test prints the
|
||||||
|
# registry to stderr, which also exits non-zero but never prints this).
|
||||||
|
test "$out" = "cache-golden: OK" || {
|
||||||
|
echo "expected 'cache-golden: OK', got: $out" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
24
tests/01_engine-cache-writefail.test
Normal file
24
tests/01_engine-cache-writefail.test
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# Keep this POSIX-portable: the harness runs it via $(BASH), which is a plain
|
||||||
|
# POSIX /bin/sh on some platforms (e.g. macOS), so avoid bashisms and GNU-only
|
||||||
|
# tool flags despite the #!/bin/bash above.
|
||||||
|
|
||||||
|
# Cache write-failure handling (httrack -#test=cache-writefail <dir>). #174/#219.
|
||||||
|
# A failing new.zip write (disk full) used to crash the process via assertf; it
|
||||||
|
# must instead stop the mirror with a fatal error (exit_xh=-1), no crash. The
|
||||||
|
# self-test asserts that; reverting the fix makes -#test=cache-writefail abort (SIGABRT) and fail.
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
dir=$(mktemp -d)
|
||||||
|
trap 'rm -rf "$dir"' EXIT
|
||||||
|
|
||||||
|
out=$(httrack -#test=cache-writefail "$dir")
|
||||||
|
|
||||||
|
# Match the exact success line (error logs also go to stdout); a renamed/removed
|
||||||
|
# test prints the registry to stderr, which exits non-zero but never prints this.
|
||||||
|
printf '%s\n' "$out" | grep -qx "cache-writefail: OK" || {
|
||||||
|
echo "expected 'cache-writefail: OK', got: $out" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
# POSIX /bin/sh on some platforms (e.g. macOS), so avoid bashisms and GNU-only
|
# POSIX /bin/sh on some platforms (e.g. macOS), so avoid bashisms and GNU-only
|
||||||
# tool flags despite the #!/bin/bash above.
|
# tool flags despite the #!/bin/bash above.
|
||||||
|
|
||||||
# Cache create/read/update logic (driven by 'httrack -#A <dir>').
|
# Cache create/read/update logic (driven by 'httrack -#test=cache <dir>').
|
||||||
#
|
#
|
||||||
# The in-process self-test stores several hand-crafted edge entries (normal
|
# The in-process self-test stores several hand-crafted edge entries (normal
|
||||||
# HTML, an empty redirect with a near-limit location, a non-HTML body kept via
|
# HTML, an empty redirect with a near-limit location, a non-HTML body kept via
|
||||||
@@ -20,13 +20,13 @@ set -eu
|
|||||||
dir=$(mktemp -d)
|
dir=$(mktemp -d)
|
||||||
trap 'rm -rf "$dir"' EXIT
|
trap 'rm -rf "$dir"' EXIT
|
||||||
|
|
||||||
# Like the other -# debug modes, a trailing token (the working directory) is
|
# The working directory is a required argument; without it the test prints a
|
||||||
# required; a bare '-#A' falls through to the usage screen.
|
# usage line to stderr and returns non-zero.
|
||||||
out=$(httrack -#A "$dir")
|
out=$(httrack -#test=cache "$dir")
|
||||||
|
|
||||||
# Match the exact success line, so the test cannot pass for an unrelated reason
|
# Match the exact success line, so the test cannot pass for an unrelated reason
|
||||||
# (e.g. the -#A mode being gone and falling through to the usage screen, which
|
# (e.g. the cache test being gone, which prints the registry to stderr but
|
||||||
# also exits non-zero but never prints this).
|
# never prints this line).
|
||||||
test "$out" = "cache-selftest: OK" || {
|
test "$out" = "cache-selftest: OK" || {
|
||||||
echo "expected 'cache-selftest: OK', got: $out" >&2
|
echo "expected 'cache-selftest: OK', got: $out" >&2
|
||||||
exit 1
|
exit 1
|
||||||
|
|||||||
@@ -1,14 +1,16 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
#
|
#
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
# charset -> UTF-8 conversion (hts_convertStringToUTF8).
|
# charset -> UTF-8 conversion (hts_convertStringToUTF8).
|
||||||
# -#3 <charset> <string> prints the string re-decoded from <charset> as UTF-8.
|
# -#test=charset <charset> <string> prints the string re-decoded from <charset> as UTF-8.
|
||||||
conv() {
|
conv() {
|
||||||
test "$(httrack -O /dev/null -#3 "$1" "$2")" == "$3" || exit 1
|
test "$(httrack -O /dev/null -#test=charset "$1" "$2")" == "$3" || exit 1
|
||||||
}
|
}
|
||||||
# crash probe: malformed input must exit cleanly, not abort.
|
# crash probe: malformed input must exit cleanly, not abort.
|
||||||
runs() {
|
runs() {
|
||||||
httrack -O /dev/null -#3 "$1" "$2" >/dev/null 2>&1 || exit 1
|
httrack -O /dev/null -#test=charset "$1" "$2" >/dev/null 2>&1 || exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
# the source bytes below are UTF-8 (this file is UTF-8); "café" is 0x63 61 66 C3 A9.
|
# the source bytes below are UTF-8 (this file is UTF-8); "café" is 0x63 61 66 C3 A9.
|
||||||
@@ -29,7 +31,7 @@ conv 'us-ascii' 'hello' 'hello'
|
|||||||
# unknown charset: ASCII passes through unchanged, but non-ASCII input cannot be
|
# unknown charset: ASCII passes through unchanged, but non-ASCII input cannot be
|
||||||
# decoded and yields empty output (an error is printed to stderr).
|
# decoded and yields empty output (an error is printed to stderr).
|
||||||
conv 'no-such-charset-xyz' 'abc' 'abc'
|
conv 'no-such-charset-xyz' 'abc' 'abc'
|
||||||
test "$(httrack -O /dev/null -#3 'no-such-charset-xyz' 'café' 2>/dev/null)" == "" || exit 1
|
test "$(httrack -O /dev/null -#test=charset 'no-such-charset-xyz' 'café' 2>/dev/null)" == "" || exit 1
|
||||||
|
|
||||||
# malformed UTF-8 (lone continuation byte, truncated lead byte) must not crash
|
# malformed UTF-8 (lone continuation byte, truncated lead byte) must not crash
|
||||||
runs 'utf-8' $'\x80'
|
runs 'utf-8' $'\x80'
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
# --headers) forms, and an over-cap value is refused cleanly rather than
|
# --headers) forms, and an over-cap value is refused cleanly rather than
|
||||||
# overrunning a fixed scratch buffer.
|
# overrunning a fixed scratch buffer.
|
||||||
|
|
||||||
set -u
|
set -euo pipefail
|
||||||
|
|
||||||
tmp=$(mktemp -d "${TMPDIR:-/tmp}/httrack_cmdline.XXXXXX") || exit 1
|
tmp=$(mktemp -d "${TMPDIR:-/tmp}/httrack_cmdline.XXXXXX") || exit 1
|
||||||
trap 'rm -rf "$tmp"' EXIT HUP INT QUIT PIPE TERM
|
trap 'rm -rf "$tmp"' EXIT HUP INT QUIT PIPE TERM
|
||||||
@@ -26,8 +26,8 @@ run() {
|
|||||||
shift
|
shift
|
||||||
rm -rf "$out"
|
rm -rf "$out"
|
||||||
mkdir -p "$out"
|
mkdir -p "$out"
|
||||||
httrack "file://$tmp/index.html" -O "$out" --quiet -n "$@" >"$out/.log" 2>&1
|
RC=0
|
||||||
RC=$?
|
httrack "file://$tmp/index.html" -O "$out" --quiet -n "$@" >"$out/.log" 2>&1 || RC=$?
|
||||||
}
|
}
|
||||||
|
|
||||||
# crawl using exactly the given args as the only URL(s), no implicit primary URL;
|
# crawl using exactly the given args as the only URL(s), no implicit primary URL;
|
||||||
@@ -37,8 +37,8 @@ run_only() {
|
|||||||
shift
|
shift
|
||||||
rm -rf "$out"
|
rm -rf "$out"
|
||||||
mkdir -p "$out"
|
mkdir -p "$out"
|
||||||
httrack -O "$out" --quiet -n "$@" >"$out/.log" 2>&1
|
RC=0
|
||||||
RC=$?
|
httrack -O "$out" --quiet -n "$@" >"$out/.log" 2>&1 || RC=$?
|
||||||
}
|
}
|
||||||
|
|
||||||
# assert the value was accepted: clean exit and the fixture was mirrored
|
# assert the value was accepted: clean exit and the fixture was mirrored
|
||||||
|
|||||||
16
tests/01_engine-cookies.test
Executable file
16
tests/01_engine-cookies.test
Executable file
@@ -0,0 +1,16 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# Issue #151 guard: the request Cookie header must be bare RFC 6265 name=value
|
||||||
|
# pairs, no $Version/$Path attributes. Driven by the 'httrack -#test=cookies' selftest.
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
# 'run' is an ignored placeholder argument.
|
||||||
|
out=$(httrack -#test=cookies run)
|
||||||
|
|
||||||
|
# Exact-match the success line so a renamed/removed test (it prints the registry
|
||||||
|
# to stderr) can't pass.
|
||||||
|
test "$out" = "cookie-header: OK" || {
|
||||||
|
echo "expected 'cookie-header: OK', got: $out" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
18
tests/01_engine-copyopt.test
Executable file
18
tests/01_engine-copyopt.test
Executable file
@@ -0,0 +1,18 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# Regression guard for the unsigned-enum sentinel trap: copy_htsopt's
|
||||||
|
# `if (from->X > -1)` guard is always false for unsigned hts_boolean fields, so
|
||||||
|
# they silently stop being copied. Driven by the in-process 'httrack -#test=copyopt' test.
|
||||||
|
# Keep POSIX-portable (harness runs it via $(BASH), a plain /bin/sh on macOS).
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
# 'run' is an ignored placeholder argument.
|
||||||
|
out=$(httrack -#test=copyopt run)
|
||||||
|
|
||||||
|
# Exact-match the success line so a renamed/removed test (it prints the registry
|
||||||
|
# to stderr) can't pass.
|
||||||
|
test "$out" = "copy-htsopt: OK" || {
|
||||||
|
echo "expected 'copy-htsopt: OK', got: $out" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
14
tests/01_engine-dns.test
Normal file
14
tests/01_engine-dns.test
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# DNS resolver/cache self-test: a mock getaddrinfo (no network) checks address
|
||||||
|
# family, single-address selection, the -@i4/-@i6 family filter, and cache reuse.
|
||||||
|
# 'run' is an ignored placeholder argument.
|
||||||
|
out=$(httrack -#test=dns run)
|
||||||
|
|
||||||
|
test "$out" = "dns-selftest: OK" || {
|
||||||
|
echo "expected 'dns-selftest: OK', got: $out" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user