Compare commits

..

72 Commits

Author SHA1 Message Date
Xavier Roche
74705a6b4f Fix the stale connection defaults the help and man page advertise
--help (and the manual page generated from it) claimed the default socket
count is 8 and the default new-connections-per-second is 10. The engine
actually defaults to 4 sockets (htslib.c) and 5 connections/second, which
is also the -%c ceiling. The 8 in the old text is the -c clamp, not the
default, so the line conflated the two.

Correct the two markers to (*c4) and (*%c5) in htshelp.c and regenerate
man/httrack.1 via man/makeman.sh. html/httrack.man.html carries the same
two-token fix applied directly, since regenerating it needs groff's html
device (Debian: full groff, not groff-base); a later full regen on such a
host reproduces the identical output.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>
2026-07-21 19:56:22 +02:00
Xavier Roche
1d0e2222d4 Restore the command-line documentation to the navigation (#648)
The command-line documentation (cmddoc.html, options.html, and the generated httrack.man.html) was unreachable from the documentation index; they only linked each other. Link cmddoc.html into the "How to Use" list so the whole set is reachable, and replace options.html's stale ~2007 option list with a pointer to the generated man page.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>
2026-07-21 19:09:14 +02:00
Xavier Roche
4166200465 Add an Android help page to the offline documentation (#646)
Adds html/android.html, a step-by-step guide for the HTTrack Android app (install, project, address, options, run, browse, storage), with screenshots of the shipped app and an options section covering all eleven tabs and the settings that are missing or fixed on Android. Linked from the documentation index between the WinHTTrack/WebHTTrack and Fred Cohen entries.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>
2026-07-21 18:45:39 +02:00
Xavier Roche
2382ca3aa0 Refresh the documentation copyright year to 1998-2026 (#647)
Bumps the copyright year in the html/ documentation footers (and the inline notice in contact.html) from 2007 to 1998-2026. Footer text only, no content changes; fcguide.html (Fred Cohen, upstream) is left untouched.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>
2026-07-21 18:43:10 +02:00
Xavier Roche
68a9a247d6 Correct stale facts in the HTML help pages (#645)
Four factual bugs in the shipped html/ help pages: the FAQ's stale "SOCKS? Not yet!" answer (SOCKS5 and HTTP CONNECT proxies have shipped), cache.html's false ">4GiB ZIP64 not supported" claim, two -mime:video/* example rows in filters.html mislabeled "application/", and a compile-breaking fprintf(stder, ...) in plug.html's sample module.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>
2026-07-21 18:06:23 +02:00
dependabot[bot]
86bc02d8da Bump github.com/microsoft/vcpkg from master to 2026.06.24 in /src (#644)
Bumps [github.com/microsoft/vcpkg](https://github.com/microsoft/vcpkg) from master to 2026.06.24. This release includes the previously tagged commit.
- [Release notes](https://github.com/microsoft/vcpkg/releases)
- [Commits](4bca8fd865...cd61e1e26a)

---
updated-dependencies:
- dependency-name: github.com/microsoft/vcpkg
  dependency-version: 2026.06.24
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-21 08:25:34 +02:00
Xavier Roche
e675d60301 Pin vcpkg builtin-baseline so shipped OpenSSL is reproducible (#643)
src/vcpkg.json had no builtin-baseline, so vcpkg resolved OpenSSL/zlib/brotli/zstd in Classic mode from whatever ports tree the build runner happened to sit at: the crypto shipped next to libhttrack.dll was a property of the runner image, not of any commit. Pin the baseline (resolves OpenSSL 3.6.3, zlib 1.3.2#1, what the Windows build already ships) so it becomes deterministic, and add a Dependabot vcpkg entry so the baseline advances on a schedule instead of freezing into a stale, CVE-bearing OpenSSL. The Windows workflow now fetches the pinned baseline before building, read back from the manifest so Dependabot bumps need no workflow edit.

Closes #642

Signed-off-by: Xavier Roche <xroche@gmail.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 07:43:59 +02:00
Xavier Roche
1c8b93d9e7 Document httrack C conventions and test-harness gotchas in AGENTS.md (#641)
Fold repo-specific conventions from private notes into the tracked
guide: a C conventions section (htssafe.h *t allocators, HTSEXT_API as
the exported ABI surface, Windows-breakable/POSIX-stable ABI split),
the concrete Latin-1 file list behind the byte-safe-edits rule, and
three test gotchas (register NN_*.test in TESTS, installed-binary PATH
shadowing, set -e in new .test scripts).

Signed-off-by: Xavier Roche <roche@httrack.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-20 19:37:11 +02:00
Xavier Roche
d267aaf1bf Interrupted mirror loses a file when a repaired cache meets an unusable 206 resume (#581)
#581 reports a Windows-only data loss: an interrupted mirror that resumes into an unusable Content-Range 206 drops its partial and never refetches, where the same sequence recovers the file whole on Linux. The trigger is the damaged cache a hard TerminateProcess leaves behind (MSYS can't signal a native exe), which pass 2 has to repair before resuming.

This does not fix the engine. I couldn't reproduce the failure on Linux, so an engine change would be guesswork. What it adds is a deterministic test that drives the damaged-cache regime, plus an analysis of where the two platforms part.

Test 71 leaves a partial and a temp-ref in pass 1, truncates `new.zip` past its last local entry so the central directory a hard kill never wrote is gone and the repair path runs, then resumes into the hostile 206. On Linux that fires the repair, takes the "unusable range -> restart whole" branch, and recovers the file whole every time, across every damage severity I tried, including a repair that recovers zero entries or fails outright. So the cache repair and the restart-whole logic are not themselves where Linux and Windows differ.

Root cause, as far as I can pin it from Linux: restart-whole doesn't refetch. It removes the partial and the temp-ref, flags `STATUSCODE_NON_FATAL`, and leans on the ordinary retry to requeue the URL. The requeued attempt rebuilds the request from the cache, then the temp-ref, then the on-disk partial. On Linux the removals leave none of those, so the retry is a clean whole-file GET and it succeeds. For the file to be lost, the retried attempt has to send a Range again: a second unusable 206, a second -5, and once the retry budget is spent the partial is already gone. That second Range can only come from a temp-ref or partial that outlived the restart-whole removal, which points at a Windows-specific removal or path effect I can't confirm from here.

For the maintainer: the fragile hinge is that restart-whole depends on a budget-consuming retry that re-derives its Range state from disk. A sturdier fix would make the retried attempt refuse to resume, via a per-link "refetch whole, no Range" flag the request builder honors, so a leftover temp-ref or partial can't re-enter the 206 loop whatever the removal quirk turns out to be. Checking that `UNLINK` and `url_savename_refname_remove` actually succeed on Windows would confirm the mechanism first.

Test 71 carries the same Windows skip as test 48. Lifting that skip should reproduce the failure, and turn the test into the fix's verification.

Refs #581.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-18 10:23:39 +02:00
Xavier Roche
226702fcab webhttrack passes the engine form-charset argv instead of UTF-8
webhttrack splits the raw HTTP POST body into argv and calls hts_main2 directly, but that body is in the web form's declared charset (LANGUAGE_CHARSET: ISO-8859-1, windows-125x, BIG5, gb2312, shift-jis, depending on the language), not UTF-8. The httrack CLI and WinHTTrack both hand the engine UTF-8, which htsname's path budget and htscache's format detection now assume, so a non-ASCII output path or URL from the web UI reached the engine as raw form-charset bytes and put the mirror in a mojibake directory instead of the one the user named.

The command line is now converted from the current LANGUAGE_CHARSET to UTF-8 before the crawl starts, in htsserver.c right before webhttrack_main() where that charset is known via LANGSEL. ASCII and already-UTF-8 input pass through untouched. webhttrack's own argv also gets the Windows hts_argv_utf8 treatment the CLI already has.

This exports hts_convertStringToUTF8 so htsserver (which links the shared library) can reach it: an additive ABI change, new symbol, soname unchanged, alongside the already-exported hts_convertStringSystemToUTF8. Flagging it since it touches the public export set.

Test 68 drives the real htsserver over HTTP, posts a start command whose -O dir is café in ISO-8859-1, and checks the mirror lands under the UTF-8 café directory, not the ISO-8859-1 twin. It fails on master and passes with the fix.

Closes #629

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-18 10:02:02 +02:00
Xavier Roche
491774abda Signed-shift UB in zip-repair local-header read (#640)
unzRepair parses the local file header of a damaged cache zip during
repair. READ_32 combined two int-typed READ_16 halves as
READ_16(adr) | (READ_16((adr)+2) << 16); when the high half has bit 15
set (>= 0x8000), shifting it left by 16 exceeds INT_MAX, which is signed
overflow. UBSan aborts on the CRC/size fields of a header whose high
16-bit word has that bit set. Repair runs on hostile input (a corrupt or
foreign new.zip). Cast the halves to uLong before the shift, matching the
sibling minizip readers in unzip.c and zip.c.

Closes #639

Signed-off-by: Xavier Roche <roche@httrack.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-18 09:41:30 +02:00
Xavier Roche
dbad05fcf0 Non-ASCII single -O drops hts-log.txt into a mangled twin directory on Windows
A single `-O` sets both `path_html` and `path_log`, so `httrack -O café url` sends the logs through `path_log` too. argv is UTF-8, so `path_log` holds UTF-8 bytes, but the two-file log branch in `hts_main_internal()` still created its directory and opened `hts-log.txt`/`hts-err.txt` through the ANSI `structcheck()`/`fopen()`. On Windows those read the bytes as the codepage and dropped the logs into a second, mangled `caf<mojibake>/` directory beside the mirror. This routes that branch through the same UTF-8 wrappers #628 used for the mirror root (`structcheck_utf8`/`FOPEN`/`UNLINK`/`fexist_utf8`), so the logs land under `café/` with the mirror. On a UTF-8 filesystem the wrappers resolve to the same calls, so only Windows changes.

This is the log half of #630. I left the cache half out on purpose: relocating `hts-cache` is a much larger, coupled change, because the cache is written through minizip's own ANSI `fopen` and cleaned up through an ANSI `opendir`, so half-converting it would split or break the cache rather than move it. That wants its own PR, and #630 should stay open for it.

Test 69 mirrors into a single non-ASCII `-O` and asserts the audits read `hts-log.txt` from that directory. Like test 64 it only bites on the Windows CI leg, where the two encodings differ; on Linux the change is a no-op and the whole suite stays green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-18 08:37:06 +02:00
Xavier Roche
db19089448 A path-ceiling truncation drops the .delayed marker and loses the file
HTTrack gives a file a temporary `.delayed` placeholder name while it can't resolve the file type yet, then renames the placeholder once the type is known. The problem is that url_savename appends that marker before it enforces the 236-char path ceiling, and the ceiling cuts the tail of the last path segment, which is exactly where the marker lives. Once the trailing `.delayed` is gone the name no longer matches `IS_DELAYED_EXT`, so back_delayed_rename bails out ("nothing bound to the placeholder name") and the downloaded file is never moved to its final name. It is reachable through #133-style deep paths whose final segment is a long hashed filename.

The fix reserves the trailing `.<id>.delayed` in the last-segment copy loop and trims the head of the segment instead, so the result still fits under the ceiling. The hex-id scan stops at its dot separator, so a wholly-hex hashed base is never mistaken for the collision tag and pulled into the marker.

Test 67 drives the naming path over a deep, over-long delayed URL and checks that the marker survives the cut. It fails on master and passes with the fix.

Closes #623

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-18 08:17:44 +02:00
Xavier Roche
eb9e353f0b Fix SIGPIPE flake in 01_engine-xfread under pipefail (#637)
The test matched engine output with `echo "$out" | grep -q PATTERN`. Under
`set -o pipefail`, grep -q exits the moment it matches, so echo takes a SIGPIPE
writing the rest and the pipeline reports failure even though the pattern was
found. The `|| { echo FAIL; exit 1; }` guard then fired on a passing case,
turning it into an intermittent, output-size-dependent failure (seen on the
Debian buildd leg of #632).

Match with here-strings instead, dropping the pipe and the race entirely.

Signed-off-by: Xavier Roche <roche@httrack.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-18 08:05:23 +02:00
Xavier Roche
8a8fd7f9c0 Stripping a default :80 with leading zeros mangled the host (#632)
The link-rewrite step that drops a redundant :80 read the port with a
hand-rolled digit accumulator, then skipped a hardcoded 3 chars (":80")
when the value equaled 80. Any longer spelling that still evaluates to
80 lost only its first 3 chars and glued the rest onto the host:
http://127.0.0.1:080/x became 127.0.0.10/x, :0080 became 127.0.0.180.
The accumulator was also unchecked, so :4294967376 wrapped to 80 and
took the same path (#614 shape).

Extract the strip into hts_strip_default_port() and parse the matched
digits with the range-checked hts_parse_url_port(): a wrapped or
out-of-range value no longer aliases 80, and a genuine default is
dropped by its full matched length instead of 3. Covered by the
"stripport" engine self-test (tests/66_engine-port80-strip.test).

Closes #627

Signed-off-by: Xavier Roche <roche@httrack.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-18 07:54:27 +02:00
Xavier Roche
1c1c0b1267 Release 3.49.13 (#631)
Bump the version in configure.ac, htsglobal.h and the Windows version
resource, and move VERSION_INFO to 3:5:0. The installed struct layouts and
the exported symbol set are unchanged since 3.49.12, so the soname stays
libhttrack.so.3 and no Debian package rename is needed.

The release is a large one: SOCKS5 and CONNECT proxy support, brotli and
zstd content decoding, a family of --update data-loss fixes, 2 GB+ file
handling on Windows and 32-bit builds, and the Windows toolchain port to
VS2022 with its own CI test suite.

Signed-off-by: Xavier Roche <roche@httrack.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-18 07:26:15 +02:00
Xavier Roche
fe685d4117 The listen ports and the ftp:// port take a port sscanf never range-checked (#626)
* Range-check the listen and ftp:// ports, not just the crawled-URL one

The --port listen port, proxytrack's host:port arguments and an ftp:// URL
port all took their value from sscanf("%d"), which range-checks nothing and
is undefined past INT_MAX (glibc wraps). "--port 4295009395" listened on
42099, and proxytrack, which had no range check at all, listened on port 80
for ":65616".

Reuse hts_parse_url_port rather than range-check after the fact. It moves to
its own file: htsserver cannot see a hidden libhttrack symbol and proxytrack
does not link the library at all, so neither could reach it in htslib.c.

htsweb's --port and proxytrack's arguments are operator input for a listen
socket, so both refuse a bad value at startup through the error path each
already had, rather than falling back to a default: silently listening
somewhere the operator did not name is the bug, and a default would keep the
same wrong behavior. The ftp:// port is a URL port and follows the
crawled-URL policy, refusing the link.

--port 0 (which asked for the auto-pick) and 65535 (refused by an off-by-one
">= 65535") both now mean what they say.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* Wire htsurlport into the MSVC projects and make test 64 portable

The new htsurlport.c was added to the autotools targets but not the MSVC
projects, so libhttrack.dll, proxytrack.exe and webhttrack.exe failed to
link on Windows with hts_parse_url_port unresolved. Add it to the three
.vcxproj that compile a caller, mirroring the autotools split.

Test 64 drove the listen servers with timeout(1), which is absent on macOS,
so every assertion tripped over a missing command. Source testlib.sh and use
its run_with_timeout instead, the same helper the other blocking-server
tests use. The htsserver and proxytrack listeners block once a port is
accepted, so both need the bound regardless.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

---------

Signed-off-by: Xavier Roche <roche@httrack.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-18 02:01:54 +02:00
Xavier Roche
f12d5e7434 Non-ASCII -O path is double-encoded on Windows now that argv is UTF-8 (#628)
Since argv became UTF-8 through hts_argv_utf8(), opt->path_html is already
UTF-8, but hts_main_internal() still re-encoded it with
hts_convertStringSystemToUTF8(), reinterpreting the bytes as the ANSI codepage.
path_html_utf8 prefixes every saved file, so a non-ASCII -O path sent the whole
mirror into a double-encoded directory. Collapse the Windows branch to the
plain UTF-8 copy the POSIX side already used, and create the mirror root with
structcheck_utf8() so the pre-created directory matches where files are written.
On a UTF-8 filesystem both resolve to the same mkdir, so only Windows changes.
This fixes the CLI and the WinHTTrack GUI, which both hand the engine UTF-8 argv.

A local-crawl test mirrors into a non-ASCII -O directory and asserts the files
land there; it runs on the Windows CI leg where the bug is reachable.

Two adjacent gaps stay open with their own issues: a single-directory -O still
leaves a mangled path_log twin holding logs and cache (#630), and webhttrack
never converts its argv to UTF-8 (#629).

Closes #621

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-17 18:57:03 +02:00
Xavier Roche
e01e1b34de An empty $HOME sends webhttrack's base path and httrack.ini to the root (#625)
PR #619 fixed hts_gethome() for an exported-but-empty $HOME, where getenv()
returns "" rather than NULL and the old NULL-only check let "~/foo" collapse
into the absolute "/foo". The same shape lives in two static clones that the
fix missed; htsserver's is live.

With HOME= exported, htsserver renders /websites as the default base path,
reads /.httrack.ini on the first request of every session, and writes
/.httrack.ini when a mirror starts. Running as root that last one lands a file
at the filesystem root; otherwise it silently fails on EACCES.

The clones cannot just call hts_gethome(): it is hidden by -fvisibility=hidden
(nm reports it as a local "t" in libhttrack.so), so htsserver cannot reach it
even though it links the library, and proxytrack does not link libhttrack at
all. Exporting it would grow the public ABI for no other caller, so each copy
keeps its own body. proxytrack's is dead today and fixed anyway: this bug got a
second round precisely because one copy kept the old shape.

Test 63 drives htsserver and reads the base path back out of the rendered UI,
since a static in htsserver.h is out of reach of the -#test registry. It pins a
real HOME too, or the empty case would also pass against a gethomedir() that
ignored the environment and always answered ".".

Signed-off-by: Xavier Roche <roche@httrack.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-17 18:24:38 +02:00
Xavier Roche
a67eb57def Top-index gifs land in a mangled directory for non-ASCII Windows projects (#624)
hts_buildtopindex() works in the system charset, but verif_backblue(), which
writes backblue.gif and fade.gif, expects UTF-8, and every other caller already
hands it the UTF-8 path. Only this one passed a system-charset path, so on
Windows the gifs were written into a mangled twin directory instead of the
project. Convert at the call site, guarded by _WIN32 since the converter is
Windows-only and the system charset is UTF-8 everywhere else.

Adds a topindex self-test (driven from the offline suite, so it runs on the
Windows leg where the bug is reachable) that asserts the gifs land in the
project directory. It failed on both Windows legs before the fix.

Sibling #216, the mojibake project name in the generated index, is a separate
leak in the same function and is not addressed here.

Closes #217
Refs #216

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-17 17:39:11 +02:00
Xavier Roche
6634d48c21 An out-of-range port in a crawled URL silently connects to a different port (#620)
* Refuse a URL whose port is outside 1..65535

newhttp_addr() parsed a crawled URL's port with sscanf("%d") and validated it
with "i != -1", then cast it to unsigned short. An out-of-range port therefore
folded into 0..65535 and httrack connected there: http://host:105579/ mirrored
off port 40043, storing the result under host_105579 while the bytes came from
somewhere else. A value past INT_MAX is also UB, and wraps on glibc.

What carries the weight is that a user's port exclusion filter stops describing
the port httrack opens, since the filter sees the literal spelling and the
connect uses the folded one.

Parse it with hts_parse_url_port() instead, factored out of #610's
parse_proxy_port(), and refuse the link through newhttp_addr()'s existing
"msg + INVALID_SOCKET" path. A proxy port can fall back to the scheme default;
a URL port cannot, because the URL named one and named a nonsense one.

socks5_handshake_stream() had the same shape, range-checking only after the
sscanf had already wrapped a huge value into a plausible port; it now shares
the parser and its existing socks5_fail() rejection.

Covered by the dns self-test, which drives newhttp_addr() through the mocked
resolver: *addr_count separates a refused port (0, no resolve) from one merely
truncated or defaulted (2), so a "fall back to 80" fix would not pass.

Closes #614

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* Keep accepting an empty "host:" port, which means the default

WHATWG and curl both treat an empty port as valid and meaning the scheme
default, and httrack's URL parser hands "http://host:/x" to newhttp_addr() as
adr="host:", so refusing it as an unparseable port would drop a legal link that
master crawls today.

Guard the parse on a non-empty port text, and move the case to the accepted
side of the self-test. Removing the guard fails that test, so the case is
covered rather than merely asserted.

The SOCKS5 origin path already refused an empty port before this series and
still does; that predates #614 and is left alone.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* Cover the SOCKS5 origin port in the self-test, and trim comments

Reverting htsproxy.c alone to the wrap-then-check version passed the whole
suite, so nothing pinned that half of the fix and a later refactor could have
dropped it silently. The scripted SOCKS5 harness now asserts a bad origin port
is refused with no byte sent.

65616 would not have tested anything: it fits an int, so the old range check
already caught it. The case the old check could not see is 4294967376, which
overflowed the sscanf("%d") into a plausible 80 and passed; the trailing-junk
and signed spellings sscanf also accepted are covered alongside it. Against
master's htsproxy.c the new assertion fails.

Also note at the SOCKS5 call site that an empty "host:" stays refused there
while the direct path accepts it, so the asymmetry reads as intended rather
than as an oversight, and halve two comments.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

---------

Signed-off-by: Xavier Roche <roche@httrack.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-17 17:24:42 +02:00
Xavier Roche
a2c75b5316 SOCKS5 test server never checked the RFC 1929 version byte (#622)
The SOCKS5 test server read the sub-negotiation version byte and dropped it. That byte must be 0x01, RFC 1929's own version, not the 0x05 of the SOCKS5 greeting. `htsproxy.c` gets it right and even comments the trap, but since the server never looked, a client that regressed to 0x05 would have kept `52_local-socks5.test` green forever while every real proxy rejected the handshake.

The server now rejects a mismatch the way a real proxy does, and the test names it, so a bad version byte reads as itself rather than as the vaguer "origin not downloaded".

This turned up while checking the proxy client against implementations we didn't write (microsocks, squid, tinyproxy, tor) over the live site. The client is correct on every leg, but this test could not have told us that. Verified by mutation: with `htsproxy.c` patched to send 0x05, master's test passes and the fixed one fails.

Signed-off-by: Xavier Roche <xroche@gmail.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-17 17:00:03 +02:00
Xavier Roche
6aabb3ba09 ~/ in the -O base path has never been expanded (#619)
* Restore ~/ expansion in the -O base path

expand_home() has never fired since 660b569 (3.41.2) refactored it from char*
to String: the correct str[0] == '~' became StringSub(*str, 1) == '~', but the
body still skips a single leading character. "~/foo"[1] is '/', so the guard
never matches, while any path whose *second* char is '~' silently lost its
first character and gained $HOME ("a~/x" -> "/home/smith~/x").

Index from 0 and gate on a following '/' so ~user/ is left alone rather than
mangled into $HOME + "user/" -- resolving it needs getpwnam, which this does
not do. An empty $HOME now falls back to '.' like an unset one, so ~/foo can
no longer expand to the absolute /foo, and an oversized $HOME leaves the path
untouched instead of aborting inside strcatbuff.

Signed-off-by: Xavier Roche <xroche@gmail.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* Pin the expandhome test to a $HOME that MSYS leaves alone

The Win32 leg spawns a native httrack.exe, and MSYS rewrites a POSIX absolute
$HOME into a Windows path on the way in, so the engine read
C:\Program Files\Git\home\smith and the pinned /home/smith never matched. A
$HOME with no leading '/' is passed through verbatim; expand_home only
concatenates, so the sentinel exercises the same code.

Signed-off-by: Xavier Roche <xroche@gmail.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* Restore the clang-format run over the gate condition

Signed-off-by: Xavier Roche <xroche@gmail.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* Ask the engine for $HOME rather than pinning it in the expandhome test

MSYS rewrites $HOME into a cwd-relative Windows path before the native
httrack.exe reads it (HTSHOME became D:\a\httrack\httrack\tests\HTSHOME), so
no pinned value survives the Win32 leg. Take the expansion of a bare '~' as
the reference instead, and assert it moved off '~' so the derived cases cannot
go vacuous. The ~user/ and a~/ negatives are literals and stay exact.

Signed-off-by: Xavier Roche <xroche@gmail.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* Pin what the expandhome test could not distinguish

A hts_gethome() that ignored $HOME and always returned the fallback passed
the whole suite: the empty-HOME cases expect ./foo, which a constant "."
satisfies. That is the same silent no-op the fix exists to remove. Also cover
the oversized-$HOME bail, which had no coverage at all.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* Keep the oversized-$HOME case inside Windows' environment limit

70000 chars cannot be set as an environment variable on Windows, so the case
failed the MSVC legs, and $(seq 1 70000) flooded the -x log. The buffer is
2 * HTS_URLMAXSIZE, so 4096 clears it and still kills the no-guard mutant.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* Run the oversized-$HOME case only where HOME survives the shell

MSYS rewrites HOME into a path of its own, so the engine never saw the long
value: it expanded ~/foo against the build directory instead of bailing. Gate
the case on the engine reporting the HOME we set; it still runs, and still
fails without the guard, on every platform that passes HOME through.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

---------

Signed-off-by: Xavier Roche <xroche@gmail.com>
Signed-off-by: Xavier Roche <roche@httrack.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-17 09:19:52 +02:00
Xavier Roche
088f0711b8 Three lang/ msgids never resolve, and nothing checks the msgid pairing (#617)
* Fix three broken msgids in lang/ and assert the pairing in a test

lang/*.txt are consecutive line pairs, an English msgid then its translation,
and nothing validates that shape. Finnish.txt had ended with a blank line since
2012, which was harmless while it was the last line; #588 appended new strings
after it, so the blank became an interior line and knocked every pair past it
out of phase. All 14 strings #588 added to Finnish, plus the CONNECT proxy one
from 938a873, were keyed off a translation instead of an msgid and rendered as
English. Drop the blank.

Italiano and Portugues-Brasil each carry one msgid that matches nothing in
English.txt ("ISO 9660" for "ISO9660", "Relative URL" for "Relative URI"), so
those two entries never resolved either.

The test is the point: it rebuilds the msgid set from English.txt and checks
every file pairs against it, byte-wise, since each file is in its own legacy
charset. It also checks lang.def's English values, which are the join key into
the msgids. It fails on all three defects before this change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* Renumber the lang integrity test to 62

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* Note the test's physical-line assumption

The engine continues a msgid ending in \ onto the next line; the test does
not. Latent today: no lang line ends in one.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

---------

Signed-off-by: Xavier Roche <roche@httrack.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-17 07:44:19 +02:00
Xavier Roche
ce481efeca webhttrack ignores LC_ALL/LC_MESSAGES and picks the wrong Chinese and Portuguese (#616)
* Fix webhttrack picking the wrong language from the locale

The launcher resolved LC_MESSAGES/LC_ALL/LANG into HTSLANG, then immediately
overwrote it with a value recomputed from $LANG alone, so LC_ALL and
LC_MESSAGES were ignored: a user with only LC_ALL=fr_FR.UTF-8 set got English.
That same line cut the region off with "cut -f1 -d'_'", leaving the zh_tw and
pt_br entries of lang.indexes unreachable, so Traditional Chinese fell back to
Simplified and Brazilian Portuguese to European Portuguese.

Resolve the locale in POSIX precedence order and look the tag up region-first,
falling back to the bare language. Also fix Slovenian's ISO 639-1 code, which
was "si" (Sinhala) in both lang.indexes and Slovenian.txt: sl_SI users got
English, and the served pages claimed lang="si".

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* Trim the locale test's comments

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* Anchor the locale test's lift so it cannot silently stop testing

The lift ended at the first blank line, so a blank line grown inside the
locale block would truncate it: reinstating the old LANG-only bug below one
left the test passing 14/14 while the launcher returned English. Anchor on
the next section instead, and pin exported-empty as unset, which lang_of
cannot express.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

---------

Signed-off-by: Xavier Roche <roche@httrack.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-17 07:24:05 +02:00
Xavier Roche
7b68d7dc96 A crawl killed by the Windows test watchdog leaves nothing to diagnose it with (#612)
* Salvage a killed crawl's logs into the Windows test artifact

A test the suite watchdog kills at 600s left nothing to diagnose it with.
local-crawl.sh sends the crawl's output to its tmpdir and hts-log.txt lives
there too, but the artifact only uploads tests/*.log, so the killed test's
entry was a single truncated line. The hard kill also skips local-crawl.sh's
cleanup trap, so the tmpdir survives on the runner and is then discarded.

Dump those logs into the test's own .log on a timeout, and clear the tmpdir so
a later timeout cannot re-report it. hts-log.txt is where "More than N seconds
passed.. giving up" lands, which is the question #605 asks of a wedge.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* Never let the log salvage's cleanup fail the test

dump_crawl_logs runs on the timeout path, where the caller is already
handling a failure: rm -rf can fail on Windows while the killed httrack
still holds a file, and under set -e that would abort the branch whose
whole job is to salvage the evidence.

Renumber the test to 60: #611 adds a 59 too.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

---------

Signed-off-by: Xavier Roche <roche@httrack.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-17 07:06:10 +02:00
Xavier Roche
a47b7bee4d Do not mistake -%i and -@i for the -i continue flag (#618)
* Do not mistake -%i and -@i for the -i continue flag

The pass that counts URLs also detects -i (continue), and for anything
cmdl_opt() calls an option it looked for a bare 'i' with strchr(). That runs
after optalias_check() has expanded the long aliases, so --build-top-index
(-%i) and --protocol N (-@iN) matched too: they wiped the URL list and left
the run on the usage screen, exit 255. The neighbouring 'q' test had the same
flaw, with -%q silently forcing quiet mode.

Look for the flag in plain short-option clusters only, so -i, -iC1, -iC2 and
--continue keep forcing continue mode while prefixed options stay distinct.

Closes #615

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* Walk the option cluster the way the parser does

The helper tested the second character only, which disagreed with the parser
in both directions: it dropped continue mode for -%qi and -%Mi, where the
trailing i does reach the main set, and it still mistook the i of -q%i for
-i, leaving that spelling on the usage screen.

Walk the cluster instead, letting %, &, @ and # take the letter after them
into another set wherever they sit. & matters because the -& to -% rewrite
only fires at position 0, so -q&i reaches the parser as-is.

None of this is reachable through a documented option or an alias, which all
place the prefix first; it keeps the helper honest against hand-written
clusters.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

---------

Signed-off-by: Xavier Roche <roche@httrack.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-17 06:46:56 +02:00
Xavier Roche
7be61d3111 Synchronous DNS resolution can wedge a crawl past --max-time (#613)
* Bound DNS resolution so a slow resolver cannot outlast --max-time

host_wait() is a stub returning 1, so a STATUS_WAIT_DNS slot resolves
synchronously through hts_dns_resolve_all() -> getaddrinfo() on the engine
thread. Nothing bounded that call, and it ran holding opt->state.lock, so a
black-hole resolver stalled the crawl past --max-time and --timeout and blocked
hts_request_stop()/hts_has_stopped() with it. resolv.conf caps getaddrinfo on
POSIX and hides this most of the time; Windows has no equivalent.

Resolve a cache miss on a worker thread and wait at most opt->timeout for it,
with the lock held only for the cache lookup and the store. A timed-out resolve
is abandoned rather than cancelled (getaddrinfo has no portable cancellation),
so the job is refcounted and the worker touches nothing but it. A timeout is
reported as "does not resolve" but never cached, so the host is retried instead
of written off for the rest of the crawl.

This bounds the wedge; it does not make resolution asynchronous. The engine
thread still stalls other slots for up to --timeout per resolve, which only
driving STATUS_WAIT_DNS from the poll loop would fix.

New -#test=dnstimeout self-test drives a mock resolver that blocks for 3s past
a 1s --timeout; all five of its checks fail on master.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* Derive the DNS timeout assertion from the spec, and join the mock workers

The self-test's ceiling came from the mock's sleep (MOCK_SLOW_MS - 500), not
from opt->timeout: a resolve using a hardcoded 2400ms deadline that ignored
opt->timeout entirely still passed it. Derive the bound from opt->timeout so
the assertion tests the contract instead of the fixture.

The scaffolding also raced its own abandoned workers. mock_host.calls was read
while a worker was still writing it, and tearing the backend down at the end
raced the worker's freeaddrinfo read, ordered only by a sleep. Serialize the
counters under a mutex, wait for the backend calls to actually return instead
of guessing, and leave the backend installed, since an abandoned worker still
reads it. Drops the drain sleep: 6.0s -> 4.0s.

Also: --timeout now bounds resolution, so say so in the help text (the man page
is generated from it), and factor the three address-copy loops into a helper.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

---------

Signed-off-by: Xavier Roche <roche@httrack.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-17 06:43:47 +02:00
Xavier Roche
3cc49b79c3 Stalled TLS handshake ignores --timeout (#611)
* Reap a stalled TLS handshake with the per-slot --timeout

back_wait only runs its per-slot timeout check when the local gestion_timeout
flag is armed. The CONNECTING, WAIT_DNS and receiving handlers arm it, but the
STATUS_SSL_WAIT_HANDSHAKE handler did not, so a peer that completes the TCP
connect and never speaks TLS left SSL_connect returning WANT_READ until
--max-time fired, ignoring --timeout entirely.

Arm the flag in the handshake handler and start a fresh timeout window when the
slot enters the handshake, so it is measured from there rather than from the
connect. The generic check already reaps any status > 0 slot once armed; give it
a distinct message instead of the generic "Receive Time Out".

Test 59 crawls a server that accepts the connect and stays silent: it ends in
--timeout seconds with the fix, and hangs until the kill guard without it.

Closes #607

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* Cover the handshake timeout window, and share the ephemeral-bind helper

Test 59 only bounded the crawl from above, so an engine that reaped every
handshake instantly passed it, and nothing exercised the timeout_refresh at the
handshake entry: on loopback the connect is instant, so the handshake's own
window is indistinguishable from the connect's.

Add a floor to the first case, and a second one behind a proxy that takes 4s to
answer CONNECT. The handshake must still get its full --timeout=5 from there
(~9s); sharing the connect's clock reaps at ~5s. Dropping the refresh now fails
the test, as does collapsing the window to zero.

The stall server grows a proxy mode for that, and takes its listening socket
from a new proxytestlib bind_ephemeral(), which replaces the same boilerplate
in the socks5 and proxy servers.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

---------

Signed-off-by: Xavier Roche <roche@httrack.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-17 06:39:11 +02:00
Xavier Roche
959deb0afb An out-of-range -P proxy port parses to a garbage port instead of being rejected (#610)
* Reject an out-of-range -P proxy port instead of wrapping it

hts_parse_proxy read the port with sscanf(a, "%d", &p), which is signed
overflow UB past INT_MAX. glibc wraps rather than fails, so a garbage
port got through: -P 'http://host:99999999999999' parsed to port
276447231, while 'http://host:4294967296' happened to fail and fall back
to the default. 65536 was accepted as-is.

Parse with strtol and range-check to *DIGIT in 1..65535 (RFC 3986); an
out-of-range or malformed port now falls back to proxy_default_port,
exactly as an unparsable one already did.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* Attribute the proxy port range to TCP, not RFC 3986

RFC 3986 defines port as *DIGIT with no range; the 1..65535 bound comes from
TCP's 16-bit port field.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

---------

Signed-off-by: Xavier Roche <roche@httrack.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-17 06:37:58 +02:00
Xavier Roche
18bdc24d15 Document that PRs are squash-merged, not merged (#609)
Both files still describe the pre-July policy and tell contributors to polish
each commit message because the branch lands on master as-is. Under squash only
the PR title and description survive, so the advice pointed at the wrong thing.

Signed-off-by: Xavier Roche <roche@httrack.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-16 18:42:06 +02:00
Xavier Roche
0b772ec6ba Untrack the local CLAUDE.local.md symlink (#608)
It points at a path under my home directory and was committed by accident
in #556, so a fresh clone gets a dangling symlink. The file's own preamble
calls it untracked guidance for one checkout; ignore it like coucal and
httrack-windows already do.

Signed-off-by: Xavier Roche <roche@httrack.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-16 18:41:53 +02:00
Xavier Roche
a0f2f89ec3 Cover the SOCKS5 IPv6-literal origin reject (#601)
The CONNECT request is always ATYP=domain, so socks5_handshake_stream rejects a
bracketed origin rather than send the brackets as a domain name the proxy could
never resolve. Nothing pinned that branch: stub the reject out and the suite
still passed.

The message check keeps the assertion tied to the IPv6 case. Asserting only the
failure and an empty sent buffer is a weak signal that many bugs satisfy: a
stricter host validator would reject these too, for the wrong reason, and pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-16 18:20:33 +02:00
Xavier Roche
93ec06f404 Make the test servers' proxytestlib import survive python3 -P
The three test servers import proxytestlib from their own directory, which works because Python puts the running script's directory on sys.path. PYTHONSAFEPATH (python3 -P) drops it and the import fails. Nothing in the harness or CI sets it, and the failure is loud rather than a silent skip, so this is belt-and-braces for anyone running a server by hand under -P.

Each server now inserts its own directory before the import. Verified by reproducing the ModuleNotFoundError first, then confirming all three announce ready under -P afterwards. No file in tests/ shadows a stdlib module, so the extra sys.path entry is inert in the normal case.
2026-07-16 18:01:30 +02:00
Xavier Roche
bc67e74dea Gate INTsys on HTS_LFS, not the never-defined LFS_FLAG (#600)
LFS_FLAG is an AC_SUBST make variable holding the -D large-file flags; it is
never itself a preprocessor macro, so "#ifdef LFS_FLAG" was always false and
INTsys stayed int on POSIX. HTS_LFS is the AC_DEFINE that config.h carries, and
htsglobal.h already includes config.h well above this point.

Mostly a wart, but not a pure no-op: htsindex.c casts fread's return to INTsys
and compares it against an LLint file size, so a temp index of 2 GB or more
truncated to a mismatch and the index was silently not rebuilt; and a tampered
cache length wrapping mod 2^32 used to be accepted where it now fails the
32768 guard. Neither comes from a legitimate writer, but the new behavior is
the safer one.

INTsys is in no struct field and no exported signature: the exported symbol set
and every installed struct layout are unchanged, so no soname bump. INTsysP
tracks the typedef, so the cache text stays identical decimal digits.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-16 17:41:33 +02:00
Xavier Roche
c7fcdebe46 Stop the -P port scan at an IPv6 literal's closing bracket (#599)
hts_parse_proxy scanned backward for the port ':' and stopped only at the
authority start or a userinfo '@'. A bracketed IPv6 literal carries colons of
its own, so a portless -P 'http://[2001:db8::1]' split on one of them, giving
name='http://[2001:db8:' and port 1. An explicit port hid it, which is why the
usual form worked.

Predates the socks5 work: the old inline parser in htscoremain.c had the same
scan, and #566 kept its shape when factoring out hts_parse_proxy.

Closes #598

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-16 17:35:46 +02:00
Xavier Roche
eb46d8d469 Reap the native process tree when a Windows test hangs (#595)
The Windows x64 CI leg intermittently died with "the hosted runner lost communication with the server": a crawl wedged and the per-test timeout(1) watchdog could not kill it. MSYS signals do not reach a native httrack.exe, so timeout reaped only the outer bash and left the engine spinning until the runner starved.

run_with_timeout/kill_tree in testlib.sh replace timeout(1): poll for the deadline, then on Windows end the whole tree by Windows PID with taskkill /T (single-slash, since the workflow passes args verbatim so //T would be rejected); on POSIX run the job in its own process group and signal the group. 58_watchdog.test verifies it end-to-end with positive controls so the reap checks cannot pass vacuously.
2026-07-16 17:33:18 +02:00
Xavier Roche
9bc53d40d2 Share the proxy test servers' duplicated code in proxytestlib.py
proxy-https-server.py (#85) and proxy-connect-server.py (#564) were ~90% identical: the CONNECT proxy, the relay and the origin were copies, differing only in the origin body, the TLS wrap and the argv shape. The common half moves to tests/proxytestlib.py, leaving each server as a docstring plus a serve() call (153 and 152 lines become 32 and 33). socks5-server.py reuses the relay too, but keeps its own origin, which is specialized for keep-alive reuse and subpages.

Behavior-preserving except that the shared origin always logs the request line, which previously only proxy-connect-server.py did. That is harmless for #85, whose origin-log assertion only checks that no Proxy-Authorization arrives. Tests 13, 52 and 57 pass unchanged, the full suite is identical at 101 pass / 7 skip, and the new module ships in the release tarball.
2026-07-16 17:30:41 +02:00
Xavier Roche
938a873e19 Tunnel plain HTTP through a CONNECT-only proxy (connect:// scheme)
HTTPS already reaches the origin through a CONNECT tunnel (#85), but plain HTTP still used the absolute-URI request form, which a CONNECT-only proxy like Tor's HTTPTunnelPort rejects. Adds a `connect://` proxy scheme (`-P connect://host:port`) that drives the proxy with CONNECT for every request: httrack opens a tunnel to the origin (port 80 for http, 443 for https), then sends the request origin-form with no Proxy-Authorization, the same way https does.

It can't be the default (CONNECT-to-:80 breaks proxies that only allow CONNECT on 443) and auto-detection is ruled out, so the mode rides the proxy scheme like socks5:// does. That keeps it ABI- and cache-safe (the scheme lives in proxy.name, no new struct field) and drops into the webhttrack GUI as one more entry beside HTTP and SOCKS5. The tooltip was reworded and retranslated across the lang/*.txt files.

Test 57 fronts a plain-http origin with a CONNECT-only proxy (it 501s anything but CONNECT) and checks the request arrives origin-form, that dropping connect:// gets the classic form refused, that credentials ride the CONNECT and never reach the origin, that a portless origin tunnels to :80, and that a flooding proxy does not hang.

Closes #564.
2026-07-16 09:22:18 +02:00
Xavier Roche
ed05faaaa8 Add native title tooltips to the webhttrack option pages (#594)
The web GUI carried per-control help via onMouseOver="info(...)", which
only wrote window.status. Browsers stopped honoring scripted window.status
writes years ago, so those hints render nowhere.

Emit each hint as a native title='...' attribute alongside the existing
handler, reusing the same ${html:LANG_*} string. Single-quoted so the
filter's ' -> &#39; (and <>&) escaping keeps the attribute well-formed; a
literal " is harmless inside single quotes. The window.status calls stay
(inert) to keep the diff to added attributes.

The webhttrack smoke test now also fetches an option page and requires a
rendered title=' tooltip.

Signed-off-by: Xavier Roche <roche@httrack.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 22:26:53 +02:00
Xavier Roche
5e56a913a5 Don't resolve or dial the origin ourselves when a proxy is set (#592)
The connect-fallback probe resolved the origin locally and, on a proxy-connect
failure, fell back to dialing the origin direct — bypassing the proxy, leaking
the origin's DNS query, and sending it the request (with the full absolute URI)
over a direct connection. Under a proxy the socket dials the proxy, not the
origin, so an origin-address list is meaningless here; gate the probe on
!proxy.active. A dead proxy now fails cleanly instead of falling open to the
origin.

Test 55 drives a crawl through a dead proxy at a two-address origin decoy and
asserts the decoy is never contacted; it fails on the pre-fix engine.

Signed-off-by: Xavier Roche <roche@httrack.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 22:21:53 +02:00
Xavier Roche
29e868b2ca Cap the chunked-transfer buffer at 2GB before realloc (#593)
* Cap the chunked-transfer buffer at 2GB before realloc

In the chunked-transfer automaton, back[i].r.totalsize is a 64-bit signed value
that accumulates the attacker-declared size of each chunk, and the in-memory
branch reallocs to (size_t) totalsize + 1 before the chunk body arrives. With no
upper bound the sum can exceed 2GB across chunks; cast to a 32-bit size_t that
truncates and under-allocates the buffer, so the following chunk data overflows
the heap. The sibling in-memory Content-Length path already caps at INT32_MAX;
apply the same bound here and abort the transfer (refetchable) when it trips.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* tests: mirror a chunked response (regression for the 2GB cap)

Add a Transfer-Encoding: chunked route to the test server and a crawl test that
mirrors it, asserting the chunk automaton joins the bodies (no leftover chunk
framing) and the new 2GB in-RAM cap stays quiet on ordinary traffic. The cap's
overflow threshold isn't reachable at test scale (it needs gigabytes on the
wire), so this pins the non-regression side; the abort path was verified by
hand with a lowered cap.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* Route the too-large chunk through the invalid-chunk teardown

Review found the first cut hand-rolled the abort (statuscode/status/finished)
and then fell through into the shared chunk dispatch, which re-ran finalize and
stomped the message; it was only safe by accident. Set chunk_size = -1 instead
and let the existing chunk_size < 0 path tear the transfer down (deletehttp +
deleteaddr + STATUSCODE_INVALID), matching the sibling error handling. Verified
by hand with a lowered cap: the resource is rejected as "Invalid chunk", the
socket is closed, and no partial file is written.

Also fix the test's decoded-vs-raw discriminator: '^40$' never matched the
CRLF-framed size line, and '</body></html>' is split by HTTrack's mirror
comment. Assert no CR (framing decoded) and '</body>' (no truncation).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

---------

Signed-off-by: Xavier Roche <roche@httrack.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 21:58:23 +02:00
Xavier Roche
f1418bac3c CodeQL: exclude libtest demos and src/proxy from scanning (#591)
libtest/ holds demo callback samples that aren't part of libhttrack, and
src/proxy/ is ProxyTrack, a separate legacy binary with no auth surface whose
recv/cache-parse code trips the taint queries by design. Together they account
for ~26 alerts that are false-positive or by-design. Exclude both so the
dashboard tracks the engine, where the queries earn their keep.

Genuine bugs found in that code are fixed on their own, independent of scanning.

Signed-off-by: Xavier Roche <roche@httrack.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 21:26:33 +02:00
Xavier Roche
092a557305 Bound strjoker's work budget across the depth cap (fuzz-filters timeout, OSS-Fuzz 535114376) (#590)
strjoker_rec charged its work budget only after the depth-cap early-return, so depth-capped recursive calls cost nothing. A class pattern like *[a]*[a]... drives recursion to STRJOKER_MAXDEPTH, sets the sticky cut flag (disabling the failure memo), and the band below the cap then re-explores exponentially without ever tripping the budget — a ~2KB filter ran ~80s under ASan. Moving the increment ahead of the depth-cap return makes every call count, bounding total work; the match fails safe. Behavior is unchanged for real filters. Adds a fuzzer corpus regression seed and a class-branch lower-bound pin to the filterbounds self-test.
2026-07-15 20:32:56 +02:00
Xavier Roche
cfe7c7e68f Expose post-3.49-2 engine options in webhttrack (#589)
The web GUI was frozen before the engine gained SOCKS5 proxying, --cookies-file,
--pause, --strip-query, and the three --keep-* URL-hack opt-outs. Wire each into
the option tabs, the generated httrack command, the winprofile.ini persistence,
and the reload remap so they reach parity with WinHTTrack (xroche/httrack-windows#31).

The SOCKS5 selector reuses the single proxy field and prepends socks5:// to -P;
it is gated on a non-empty host so a SOCKS5-selected-but-blank config can't emit a
stray scheme token. winprofile.ini key names match WinHTTrack so projects round-trip
across both GUIs. Labels/tooltips reuse the LANG_ strings already added in #588.

Signed-off-by: Xavier Roche <roche@httrack.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 20:17:03 +02:00
Xavier Roche
89b1e485d7 Add and translate the new WinHTTrack GUI option strings (#588)
Add 14 new LANG_ keys (proxy type, cookies-file, pause-between-files, keep-www / keep-double-slashes / keep-query-order, strip-query, each with a tooltip) to lang.def and English.txt, and translate them across all 30 language files. Purely additive; each file keeps its own legacy on-disk charset and line endings (Svenska stores Latin-1 despite its ISO-8859-2 header; Chinese-BIG5 is cp950; Uzbek is Latin-script and LF-terminated). Windows libhttrack checks were red on an unrelated vcpkg download.qt.io network flake.
2026-07-15 19:19:03 +02:00
Xavier Roche
08481464bd Fuzz the real HTML parser (htsparse) with a mocked engine (#586)
Adds fuzz-htsparse, a libFuzzer harness driving the real htsparse() over a
mocked engine: the tag/attribute/JS-inscript scanner, the link rewriter, and
the accept -> url_savename -> hts_record_link path that runs on every crawled
page, previously reached only by slow full-crawl tests. The parser's coupling
is state, not network, so the harness builds the minimal crawl state
httpmirror() sets up (opt, cache, hash, filters, robots, backing, a seeded
link heap with ptr=1) and walks a NUL-terminated page through the parser, then
discards it. Four seeds cover links, srcset, base/meta/usemap, a
document.write body, and malformed tags. Clean under ASan+UBSan+LeakSanitizer.

Bundles the src/coucal bump to ab59c6a (coucal#13): this harness is the first
fuzzer to hash keys through coucal under UBSan, which tripped a pre-existing
getblock32 pointer-overflow.

Merged past a transient arm64 apt-mirror outage; every code-exercising check
(fuzz, sanitize, msan, distcheck, all non-arm64 builds) passed.

Signed-off-by: Xavier Roche <roche@httrack.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 19:18:59 +02:00
Xavier Roche
3e7b9f91ee Free opt->accept and opt->headers in hts_free_opt (#585)
hts_free_opt frees about twenty of the option struct's String fields but omits
opt->accept and opt->headers, both allocated in hts_create_opt. Every opt
create/free cycle leaks the two. Harmless for the CLI but real, and it makes
LeakSanitizer noisy: the fuzz job runs detect_leaks=1, so any harness that
builds an opt trips on it.

Signed-off-by: Xavier Roche <roche@httrack.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 18:53:14 +02:00
Xavier Roche
800d498893 Keep the mirrored file when an --update re-fetch comes in short (#584)
* Keep the mirrored file when an --update re-fetch comes in short (#562)

An --update re-fetch that arrives incomplete (server declares a Content-Length
it does not deliver, or the connection drops mid-body) is correctly refused:
httrack logs "incomplete transfer ... will be retried on the next update" and
does not store the partial body. But the incomplete-transfer branch in
back_finalize() returned without noting the surviving copy, so the URL never
reached new.lst and the end-of-update purge deleted the good file it had just
declined to overwrite.

filenote() the previous copy when it still exists on disk, mirroring the
decode-failure path added in #560. Not compression-specific and needs no abort:
a plain HTML page reproduces it, so it is broader than #521 (abort) and #557
(decode failure).

Closes #562

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* Reflow the #562 comment to satisfy clang-format

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* tests: share one fetch-pass counter across the update-refetch routes

The #562 /uptrunc/ routes copied upcodec's per-path body-fetch counter verbatim. Fold both onto one refetch_pass() helper and one dict.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

---------

Signed-off-by: Xavier Roche <roche@httrack.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 17:26:30 +02:00
Xavier Roche
991d259981 tests: run the connect-fallback crawl on Windows now that #580 landed (#583)
#580 fixed the Winsock connect fallback (closed #579), so 19_local-connect-fallback
can exercise the real path on Windows. Drop its Windows skip and remove it from
the workflow's expected-skips.

Signed-off-by: Xavier Roche <roche@httrack.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 08:43:58 +02:00
Xavier Roche
d1bf4f7a25 Export hts_convertStringSystemToUTF8 from the DLL (#582)
Mark the CP_ACP->UTF-8 converter HTSEXT_API, matching hts_argv_utf8 next
to it, so WinHTTrack can call the engine's converter instead of keeping a
private copy. Windows-only (inside the _WIN32 block), so no POSIX ABI
change and no soname bump.

Signed-off-by: Xavier Roche <roche@httrack.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 08:15:07 +02:00
Xavier Roche
86e145fc1c Run the loopback crawl tests on Windows (#578)
* tests: run the loopback crawl suite on Windows

The ~40 *_local-* tests crawl the bundled Python server: the real TLS
handshake, cache, and file writer, none of which any Windows check covered.
Three things stopped them running there. python3 is python.exe on Windows;
MSYS hands out /d/a/... paths a native python.exe cannot resolve (and arg
rewriting is off, so nothing fixes them up); and Python's text layer turns the
"PORT <n>" discovery line into CRLF, so the \r landed in the parsed port.

Factor the python lookup and the path conversion into tests/testlib.sh, fix the
newline at the source in the three servers, and skip the --file-mode assertion
on Windows, where the engine does not chmod. Behaviour on POSIX is unchanged:
the full suite still passes 97/0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* tests: share the server shutdown, and make a skip fail the Windows run

stop_server moves to testlib.sh: the MSYS "a signal cannot reach a native
python.exe, only -9 lands" knowledge was in one of the nine places that kill a
python server. Every step is "|| true" because the callers run under set -e and
reaping a server we just signalled makes wait return 143.

Nothing is expected to skip on Windows, so treat a skip as a failure: the pass
floor alone left slack for exactly the tests that can silently gate themselves
off (TLS, the content codings, socks5, connect-fallback). Add the local proxy
crawl, which the glob was missing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* tests: resolve the server path before backgrounding the server

The port-discovery poll raced the server it had just started: the native path
conversion sat inside the backgrounded command, so the child ran two forks
(command -v cygpath, cygpath) before applying its ">server.log" redirect, and
on Windows the parent's first "head" reached the file first. head then failed,
and under set -e that killed the test silently.

Resolve the paths in the parent, and create the log before the launch so the
first poll cannot lose the race. nativepath keys off the platform, not off
cygpath happening to be on PATH.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* tests: skip the connect-fallback crawl on Windows

19_local-connect-fallback fails there because the engine never falls back to
the next address: Winsock reports a failed connect in select()'s exception set
rather than as writable, and the exception loop fails the slot before
back_connect_next() is reached. Skip it pending the engine fix (#579).

Pin the expected skips instead of counting them, so a gate that silently turns
some other test off still fails the run.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* tests: trim the comments added by the Windows port

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* tests: say why the crange resume lost its file

48_local-crange-memresume fails on Windows with a bare "blob.bin missing", and
the crawl log it would have to explain that lives in the tmpdir the test wipes.
Dump the engine's errors and the mirror on that branch.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* tests: dump the crawl log when the crange resume loses its file

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* tests: check the resume pass survived, don't assume it

48_local-crange-memresume ran pass 2 and printed "terminated" whatever came
back, so a crashed engine read as a clean run. It fails on Windows with an
empty log and an empty mirror, which is what that blind spot looks like.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* tests: dump both passes' state for the Windows crange failure

Temporary: pass-1 mirror + log and pass-2 log/mirror, to see why the resume
mirrors and logs nothing on Windows.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* tests: skip the crange memory-resume crawl on Windows

48_local-crange-memresume needs a graceful pass-1 interrupt so the cache is
clean when pass 2 resumes; MSYS can only hard-kill a native exe, and the
engine's restart-whole path after an unusable 206 then fails on the repaired
cache (#581). Skip on Windows pending that fix.

Keep the pass-2 exit-code check the investigation added: the test printed
"terminated" whatever came back, so a crashed engine read as a clean run.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

---------

Signed-off-by: Xavier Roche <roche@httrack.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 07:41:41 +02:00
Xavier Roche
d9ff780d0f Let a failed connect fall back to the next address on Windows (#580)
Winsock reports a failed non-blocking connect in select()'s exception set,
not as writable. The exception loop in back_wait runs before the connect
handler and finished the slot with STATUSCODE_CONNERROR, so back_connect_next
never got a chance and a multi-homed host with one dead address failed the
whole fetch.

Skip connecting slots in that loop and treat their presence in the exception
set as "the connect finished": SO_ERROR is probed as on POSIX, and the next
resolved address is dialed.

Signed-off-by: Xavier Roche <roche@httrack.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 07:20:44 +02:00
Xavier Roche
b026c80bb6 Run the engine test suite on Windows (#577)
* Cap the wildcard matcher's recursion depth (#574)

strjoker() recursed once per pattern segment, bounded only by the length
cap: a hostile filter of 1023 stars reached 2046 frames, ~900KB of stack.
That fits Linux's 8MB but not the 1MB a Windows thread gets, so
-#test=filterbounds died silently on MSVC x64 and Win32 instead of
rejecting the pattern it is meant to reject.

Cap the depth at 256 (real filters use fewer than ten). A cut branch does
not memoize its failure: the same pair may still match when reached at a
shallower depth.

The self-test now asserts the depth reached equals the cap, and the .test
re-runs it under a 512K stack, which segfaults without the cap.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* Take argv as UTF-8 on Windows, not the ANSI codepage (#573)

httrack.exe is an MBCS build, so the CRT transcodes the UTF-16 command
line down to the machine's ANSI codepage before handing us char **argv.
Non-ASCII arguments are lossy, and anything outside that codepage is
destroyed: a Cyrillic or CJK URL on a Western-codepage box becomes '?'.

Everything else in the engine already treats char* as UTF-8 on Windows -
FOPEN, STAT, UNLINK are hts_*_utf8 wrappers converting to UTF-16 at the
syscall boundary. argv is the one thing that never got the memo.

Decode the real UTF-16 command line at the entry point instead. The
manifest's activeCodePage would fix it in one line, but it needs Windows
10 1903+ and is silently ignored below that, which is precisely the
population running the codepages that mangle non-Latin URLs today.

Windows-only, so no POSIX symbol and no soname change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* Make the engine tests pass on Windows

Three of them could never pass there, and none of the three was an engine
bug:

- rcfile wrote .httrackrc, but HTS_HTTRACKRC is "httrackrc" on Windows,
  so the engine never found it. Write both names.
- filelist made a file unreadable with chmod 000, which Windows ignores.
  Probe whether the mode is enforced instead of assuming, which also
  subsumes the root special-case.
- ftp-line was #ifndef _WIN32 for its socketpair(), though get_ftp_line()
  itself is portable. Pair over loopback TCP and register it everywhere.

The charset self-tests fed raw non-UTF-8 bytes through argv to probe the
decoders. Those bytes cannot survive any Windows command line, whatever
argv does, so take them as hex - the convention the sniff self-test
already uses - and keep the coverage on every platform.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* Run the engine test suite on Windows CI

The ~90 tests only ever ran on Linux and macOS, so a Windows-only
regression was invisible until a user hit it - and the first run of the
offline ones found a third of them failing.

Drive them from Git Bash against the native MSVC httrack.exe. Two things
that silently ruin the run: MSYS rewrites any argument shaped like a POSIX
path, and a URL path is shaped exactly like one, so "-#test=mime /a/b.html"
reached the engine as "C:/Program Files/Git/a/b.html"; and a suite that
degrades to all-skipped would report green having tested nothing, hence
the floor on tests actually passed.

This subsumes the codec and cache self-tests the workflow ran inline. The
.gitattributes pins the test scripts to LF: a converting checkout rewrites
them to CRLF and bash then dies on $'\r' on every line.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* Log the launch banner argv without re-encoding it

The banner ran hts_convertStringSystemToUTF8() over each argv element on
Windows, which was right when argv came in the ANSI codepage. argv is
UTF-8 on every platform now, so that pass double-encoded a non-ASCII
argument into mojibake in hts-log.txt. Log the bytes as they are.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* Fix the Win32 CLI build: include htscharset.h after winsock2.h

htscharset.h pulls in <windows.h>, which drags in the legacy <winsock.h>
unless <winsock2.h> was included first. In httrack.c it sat ahead of the
net headers, so the x86 build redefined every sockaddr/winsock symbol
(C2011). Move it below htslib.h, where winsock2.h is already in.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* Fix two more tests the Win32 CI leg exposed

Both are test bugs surfaced by running on 32-bit Windows for the first
time, not engine bugs:

- strsafe drove its overflow through a char[4]. On a 32-bit build that
  equals sizeof(char*), so htssafe's array-vs-pointer heuristic
  (sizeof(A) != sizeof(char*), the MSVC path) reads the array as a
  pointer and skips the bound: the copy then genuinely overflows and
  crashes instead of aborting cleanly. Size the buffer off the pointer
  width so the checked path runs everywhere.

- idna's malformed-UTF-8 rejection case passed the bad bytes through
  argv. They cannot survive a Windows command line: the UTF-16 round-trip
  turns them into valid U+FFFD, which the encoder then accepts. Feed them
  as hex so the exact bytes reach the bundled punycode encoder, which
  rejects them identically on every platform.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

---------

Signed-off-by: Xavier Roche <roche@httrack.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 20:03:40 +02:00
Xavier Roche
e0648beff9 Cap the wildcard matcher's recursion depth (#575)
* Cap the wildcard matcher's recursion depth (#574)

strjoker() recursed once per pattern segment, bounded only by the length
cap: a hostile filter of 1023 stars reached 2046 frames, ~900KB of stack.
That fits Linux's 8MB but not the 1MB a Windows thread gets, so
-#test=filterbounds died silently on MSVC x64 and Win32 instead of
rejecting the pattern it is meant to reject.

Cap the depth at 256 (real filters use fewer than ten). A cut branch does
not memoize its failure: the same pair may still match when reached at a
shallower depth.

The self-test now asserts the depth reached equals the cap, and the .test
re-runs it under a 512K stack, which segfaults without the cap.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* Pin the matcher depth cap from below in the self-test

The self-test asserted the cap is reached, which a cap set absurdly low
would also satisfy: real filters use fewer than ten segments, so a cap of
5 would break them and still ship green. Assert a 32-segment pattern still
matches, so the cap cannot be lowered past real use unnoticed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

---------

Signed-off-by: Xavier Roche <roche@httrack.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 19:49:39 +02:00
Xavier Roche
ee1aebd935 Harden the ProxyTrack cache readers against corrupt input (#572)
proxy/store.c carried its own copy of htscache.c's old-format (.dat/.ndx) cache readers without the bounds hardening the engine copy got in #568. cache_brstr/cache_rstr trusted a length prefix from the cache file and wrote it into fixed buffers unbounded, and cache_rint/cache_rLLint used an unchecked sscanf result as a size or offset, so a crafted cache overflowed firstline[256] and the PT_Element fields and could wrap a malloc(size+1).

Ports the engine's discipline into the proxy copy: thread the destination capacity through the readers and clamp while consuming the declared length, check every sscanf, allocate the body through a bounded helper, fix an index[index_id] off-by-one, and bound the startUrl/previous_save concatenations. Also casts the coucal void* key at the %s snprintf. The .dat/.ndx format is dead (zip only now), so this is defense-in-depth on the legacy reader; a corrupt-cache test guards it under the sanitizer CI.
2026-07-14 17:58:39 +02:00
Xavier Roche
b4957f0625 Extract the proxy tunneling code into its own module (#571)
* Extract the proxy tunneling code into htsproxy.c

htslib.c is the engine's catch-all "subroutines" file; the two proxy
tunnels living in it (HTTP CONNECT and the SOCKS5 handshake) are one
coherent thing: blocking raw-socket negotiation with the proxy, run from
the same back_wait callsite before TLS. Move both, plus proxy_getline and
the socks5 statics, into htsproxy.c/.h, which also gives the socks5_test_io
self-test seam a home away from the public-ish htslib.h.

Pure code motion: the moved bytes are identical, and hts_proxy_is_socks
stays in htslib.c next to hts_parse_proxy and jump_protocol_const, being a
URL-scheme predicate rather than handshake logic.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* Keep the vcxproj source list alphabetical

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

---------

Signed-off-by: Xavier Roche <roche@httrack.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 16:21:51 +02:00
Xavier Roche
c9d36c82c7 Files of 2 GB or more are mishandled on Windows, and on any 32-bit build (#568)
* Report file sizes as 64-bit, so Windows stops mishandling files past 2GB

MSVC's off_t is a 32-bit long in x64 builds as well as Win32, and struct
_stat expands to _stat64i32, whose st_size is that same 32-bit long. So
fsize(), fsize_utf8() and fpsize() truncated twice over: once in the stat,
once in their own return type. A mirrored file of 2GB or more got a wrapped,
often negative size, which fed resume/206 handling, the cache body-size
reads, and readfile2()'s allocation.

Use the 64-bit _stat64 family on Windows and return LLint from the three
size helpers, widening the callers' locals to match. INTsys and HTS_FSEEKO
now cover MSVC too, so readfile2() and fpsize() reach the _fseeki64/_ftelli64
aliases htslib.h already declared. htsback.c's two 'not (off_t)' comments
described this trap but the value feeding that path was still 32-bit.

STRUCT_STAT is in an installed header, so hts_stat_utf8()'s signature changes:
a deliberate Windows-only ABI break, agreed with Xavier. The DLL ships next to
the exe with no soname contract. POSIX is untouched, where off_t is already
64-bit under LFS.

The new -#test=fsize self-test builds a 3GB sparse file and asserts both the
reported size and the 8-byte return width. Forcing the helpers back to a
32-bit return reproduces the Windows failure exactly (-1073741824) and the
test catches it.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* Report errno when the fsize self-test cannot create or reopen its file

The linux i386 leg fails with 'fpsize is -1', which only says the reopen
returned NULL. Print strerror(errno) on both the create and the reopen path,
and check fclose() so a failed flush stops being silent.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* Size files with fseeko/ftello, never ftell: ftell is 32-bit on i386

fpsize() gated fseeko/ftello behind HTS_FSEEKO, which is defined from
'#ifdef LFS_FLAG'. LFS_FLAG is a configure make variable carrying the
-D_FILE_OFFSET_BITS=64 flags, never a C macro, so that test is dead and the
fallback ftell/fseek branch is the one every autotools build compiled. ftell
returns long: 64-bit on x86-64, which hid the bug, but 32-bit on i386, where
it fails with EOVERFLOW past 2GB and fpsize() returns -1.

Call fseeko/ftello unconditionally, as htsback.c already does; MSVC gets them
via the _fseeki64/_ftelli64 aliases in htslib.h. HTS_FSEEKO had no other user.

The dead LFS_FLAG test also leaves INTsys as int on POSIX, capping readfile2()
at 2GB. Widening it changes a typedef in an installed header, so that is left
for a separate change; the FIXME records it.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* Fix the INTsys widening's fallout, and make the fsize test bite

Widening INTsys to 64-bit on MSVC broke two call sites that assumed it was
an int, both found by an adversarial review of this branch:

- proxy/store.c's cache_rstr_addr() parsed it with sscanf("%d"), writing 4
  bytes into an 8-byte object and leaving the high word indeterminate; that
  value then sized a malloc() and an fread(). Its sibling cache_rstr() already
  used INTsysP. proxytrack.vcxproj builds this file, so it was live on MSVC.
- readfile2()/readfile_utf8() fed a now-64-bit length to malloct() and fread(),
  which take size_t: 32-bit on Win32 and i386. The two truncate independently,
  so a file of 4GiB-1 gave malloc(0) with a 4GiB read into it. Route the size
  through llint_to_size_t() and fail closed when it does not fit.

The self-test only exercised fsize_utf8(), so reverting fsize()'s _stat64 hunk
left it green, and fsize() is what sizes file:// bodies and --list. It now
checks both variants, the absent-file -1 contract, and uses 5GB rather than
3GB: a 32-bit truncation of 3GB is negative and obvious, of 5GB it is
1073741824, a plausible size. NTFS needs FSCTL_SET_SPARSE to leave the hole
unallocated; POSIX gives it for free.

Windows CI now runs the cache, cache-corrupt and fsize self-tests. The cache
fixes in #567 cannot be verified on POSIX at all, where fconv() is a no-op.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* Check the sscanf return in proxytrack's cache reader

cache_rstr() and cache_rstr_addr() declared an uninitialized INTsys and never
checked whether sscanf matched. On a truncated or malformed cache entry the
length stays indeterminate, and it then sizes an fread() and, in the addr
case, a malloc(). Initialize it and require a match, so a bad entry reads as
length 0.

Flagged by CodeQL (cpp/missing-check-scanf) once the widening touched that
line; the alert predates it on master, and its sibling had the same hole.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

---------

Signed-off-by: Xavier Roche <roche@httrack.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 15:49:59 +02:00
Xavier Roche
1fa0184468 SOCKS5 proxy support (#570)
* Tunnel crawls through a SOCKS5 proxy (RFC 1928/1929)

-P socks5://[user:pass@]host[:port] now negotiates a SOCKS5 tunnel to the
origin instead of speaking HTTP to the proxy. The handshake runs on the raw
socket right after connect, so it covers plain http as well as https (TLS then
runs end-to-end over the tunnel, no CONNECT); the origin request stays
origin-form, and the proxy credentials ride the RFC 1929 sub-negotiation rather
than a Proxy-Authorization header.

The origin hostname is sent as-is (ATYP=domain): the proxy resolves it, like
curl's socks5h, which is what makes .onion and split-horizon names work and
keeps the crawl from leaking DNS. ftp:// links fail under a socks proxy rather
than silently dial the origin direct.

Reply frames are drained exactly per ATYP, since the socket is shared with the
origin stream: one byte too few and the leftovers corrupt the first TLS record.
-#test=socks5 asserts that byte count against scripted replies, plus the
truncated/hostile cases; 52_local-socks5.test crawls http and https through a
local SOCKS5 server that only answers for a .invalid name, so a locally-resolved
origin could not reach it.

Closes #563

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* Don't re-run the SOCKS5 handshake on a reused keep-alive socket

back_wait re-enters the connect-completed block for a keep-alive socket
revived by back_trylive (plain http; https is covered by the ssl_con guard).
The socket is already tunneled, so re-sending the SOCKS greeting injected
\x05\x01\x00... into the established origin stream and corrupted every request
after the first. Gate the handshake on !keep_alive, which back_connxfr carries
onto the revived slot and which is zero on a fresh connect.

52_local-socks5.test now crawls a keep-alive origin (advertising max>1) with
-c1: the whole plain-http crawl rides one tunnel, exactly one handshake, every
subpage intact. Without the gate the reused stream desyncs and the crawl hangs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* Use scheme-less origins in the SOCKS5 self-test (CodeQL cpp/non-https-url)

The scripted handshake strips the scheme and takes the TLS flag as a parameter,
so the "http://origin.test" fixtures were inert cleartext-URL literals that
tripped CodeQL. Pass the bare authority instead; the parsing is identical and
the real scheme handling is covered end-to-end by 52_local-socks5.test.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

---------

Signed-off-by: Xavier Roche <roche@httrack.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 15:38:47 +02:00
Xavier Roche
79e46eeceb Store the cache self-tests' X-Save verbatim, and feed the sniff BOM as hex (#567)
The cache self-tests built the X-Save path with fconcat(), which rewrites
every '/' to '\' on Windows -- including the path_html_utf8 prefix the
reader matches on. cache_readex then took the pre-3.40 compat branch and
re-rooted the name into a path that does not exist, so -#test=cache's
disk-fallback read and -#test=cache-corrupt's headers-only and in-memory
cases all failed on MSVC builds. The engine keeps save names in '/' form and
DOS-ifies only at the syscall boundary; the self-tests now do the same.

The sniff test passed a UTF-8 BOM as raw bytes through argv, where Windows
routes it via the ANSI codepage and U+FEFF has no mapping, so it arrived as
'?'. Use the hex: body form the self-test already accepts.

Both are self-test bugs: neither path is reachable from the crawler, which
never sniffs argv and never DOS-ifies a stored save name.

Signed-off-by: Xavier Roche <roche@httrack.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 14:29:12 +02:00
Xavier Roche
436ac53793 Parse -P proxy URLs scheme-aware, recognize socks5 schemes (#566)
* Parse -P proxy URLs scheme-aware, and recognize socks5 schemes

The -P argument parser scanned backward for the port ':' from the end of the
string with no notion of a scheme, so a scheme-prefixed proxy with no explicit
port ("-P http://proxy") mistook the scheme's own colon for a port separator:
the name came out as "http" with a garbage port. A port or a "user:pass@" prefix
happened to shield the scan, so this only bit the no-port case.

Extract the parse into hts_parse_proxy(), which skips any "scheme://" before
hunting the port, so the scheme colon is never read as a port. Teach
jump_protocol_const the socks5/socks5h schemes (so the proxy host resolves with
the scheme stripped) and default the port by scheme (1080 for socks, 8080
otherwise). This is the parsing groundwork for SOCKS5 support (#563); the
handshake lands separately.

Add a -#test=proxyurl self-test and tests/01_engine-proxyurl.test covering bare
hosts, user:pass, the scheme-colon regression, and the socks defaults.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* hts_parse_proxy: scan from one-past-end, avoid forming arg-1

The backward port scan started at arg+strlen(arg)-1 and decremented while
a >= authority, so on any argument with no ':' or '@' in the authority (every
bare-host proxy, and -P "") it stepped a to arg-1: a pointer formed before the
string, which is undefined behavior. It is not a memory-safety bug (never
dereferenced, no wrap, so UBSan stays green), but it is latent UB reachable from
-P.

Scan from one-past-end and test a[-1] with a > authority instead, so no pointer
below the string is ever formed. Guard name_size == 0 against a future
small-buffer caller (the name_size - 1 truncation would otherwise underflow).

Add a userinfo-free socks explicit-port case and a lone ':' boundary case to the
self-test.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* proxyurl test: percent-encoded specials and UTF-8

Pin that the host/port split is byte-transparent: a percent-encoded '@' (%40) or
':' (%3A) in the userinfo stays encoded and never mis-splits host or port, a
second raw '@' is handled by the last-'@' host rule, and UTF-8 bytes in the
username and host label pass through intact. Decoding happens later at auth time,
not in the parser. Raw UTF-8 CLI args match the existing 01_engine-idna.test.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

---------

Signed-off-by: Xavier Roche <roche@httrack.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 14:11:57 +02:00
Xavier Roche
bc4b2c7b8e Keep the mirrored file when a coded re-fetch fails to decode (#560)
* Keep the mirrored file when a coded re-fetch fails to decode

An --update re-fetch of a content-coded URL decoded straight into url_sav: the
live mirror was truncated (filecreateempty) before the decode was even attempted,
so a truncated gzip, a corrupt br/zstd stream, a decode-size overrun or a coding
we have no decoder for destroyed the good copy we were merely refreshing. The
uncompressed path has been rollback-safe since #522, but its backup is explicitly
skipped for coded bodies, so nothing covered them.

Decode into a temporary file instead and only commit it over the mirror once the
decode succeeded; on failure url_sav is never touched. The failure path also has
to filenote() the surviving copy, or the end-of-update purge (in old.lst, absent
from new.lst) would delete the very file the decode took care not to overwrite.

Closes #557

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* Never drop the decoded body when the mirror replace fails, and probe the good path

replace_file() unlinks the destination and retries when the first rename is
refused (Windows never clobbers). If that retry also fails, the previous copy is
gone, so deleting the decoded temp as well destroyed the last copy of the body:
keep it and log where it went, the way the backup restore does. That restore is
the same remove-then-rename, so it now shares the helper.

The test grew the missing positive control: freshdisk.bin decodes on both passes
on the direct-to-disk path, so the update pass renames a decoded temp over an
existing mirror file, which no case exercised. The leftover-temporaries sweep in
local-crawl.sh now covers the .z/.u decode temps for every crawl test, not just
the three names this one asserted.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* Restore the 0644 mode on a decoded direct-to-disk file

Committing the decode by renaming the temp bypassed filecreate(), which is what
chmods the mirrored file to HTS_ACCESS_FILE. Under a restrictive umask a coded
binary landed 0600 while every other mirrored file stayed 0644, so a mirror
served from a web root or shared with a group silently lost read access. chmod
it at the rename, as the plain direct-to-disk path already does.

The test now crawls under umask 077 and asserts the mode, via a --file-mode
assertion in local-crawl.sh; without the chmod it fails with 0600.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* Pin the codec-update assertions to the URLs and to fresh content

The exact error count did not say which links failed: an engine that logged one
URL twice while another failed silently still counted three and passed. Match the
three decode errors per URL instead. The content checks only looked for the new
marker, so a fix that appended the decoded body to the old file rather than
replacing it would pass too; assert the pass-1 marker is gone. Also assert the
mode on a kept file, not just on the two rewritten ones.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

---------

Signed-off-by: Xavier Roche <roche@httrack.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 13:10:28 +02:00
Xavier Roche
4fafe283b4 Store the .rc blobs LF-normalized, as .gitattributes declares (#561)
.gitattributes marks *.rc as "text eol=crlf": the blob is LF, the checkout is
CRLF. The two resource scripts added in #558 went in with CRLF blobs, so git
renormalizes them on every add and every checkout reports them as modified.
Renormalized with git add --renormalize; version.rc was already correct. The
working-tree files stay CRLF, which is what the Windows toolchain reads.

Signed-off-by: Xavier Roche <roche@httrack.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 12:42:19 +02:00
Xavier Roche
9ec5a3a067 Decode brotli and zstd content codings (#556)
* Decode the br and zstd content codings, and bound every decode

httrack advertised gzip and deflate only, so it took the oldest coding on
offer while every browser negotiates brotli (46% of CDN traffic) or zstd.
Worse, the response side had no codec identity at all: Content-Encoding was
collapsed into a boolean and hts_zunpack guessed the framing from the body
bytes, so a br or zstd body sent unsolicited (mis-keyed Vary caches do this)
fell through the identity path and was saved as the page, coded bytes and all.

Content-Encoding now maps to a codec (htscodec.c), and the decode dispatches on
it: brotli and zstd get streaming decoders, a known coding we cannot undo fails
the fetch instead of saving garbage, and an unrecognized token still means
identity, because servers do put charsets in that header. br and zstd are
advertised over TLS only, as browsers do.

On any decompression failure the undecoded body is now dropped rather than left
in memory for the writer to commit as the page. That closes the coded-bytes-as-
page hole for the new unsupported-coding path, and with it a latent leak on the
gzip path, where a body that failed to inflate (a truncated stream) was written
to disk verbatim.

Every decode is now bounded: 4096x the coded body, floor 1 MiB, ceiling INT_MAX.
Nothing capped the decoded size before, which was survivable while deflate was
the only codec (it cannot pass 1032x) but not with brotli and zstd, which reach
a million to one. The zlib accumulator also moves to LLint, so a body over 2 GiB
fails instead of overflowing an int.

libbrotlidec and libzstd are optional at configure time and required on Windows,
where libhttrack.dll links them from vcpkg and CI runs the self-tests to prove
the decoders are in.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* Fix copyright year on the new codec files (2026, not 1998)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* tests: probe the direct-to-disk decode-failure discard, and assert absence

The wire test only exercised the in-memory discard path (bad.html is HTML).
Add a non-HTML body under an unsupported coding (bin.dat) so the is_write
branch is covered too, and assert both are absent from the mirror rather than
grepping a file that the fix now removes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* Factor the budget-enforced write shared by the brotli and zstd decoders

The two streaming decoders duplicated the decoded-size budget check, the
security-critical part of each loop. Pull it into one codec_sink helper so the
bomb ceiling lives in a single place. Behavior-preserving; the codec self-test
(exact decoded bytes, truncation and bomb rejection) proves equivalence.

Also compile the streaming-decode body only when a streaming codec is built,
which drops an unused-variable warning in the --without-brotli --without-zstd
build.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

---------

Signed-off-by: Xavier Roche <roche@httrack.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 08:26:20 +02:00
Xavier Roche
cd38e6e68d Merge pull request #559 from xroche/fix/robots-default-comment
Put the robots.txt "(default)" label on the option that is the default
2026-07-13 20:51:23 +02:00
Xavier Roche
e692e56592 Put the robots.txt "(default)" label on the option that is the default
The enum said HTS_ROBOTS_SOMETIMES was the default. It is not: hts_init_opt
sets opt->robots = HTS_ROBOTS_ALWAYS (htslib.c:5990), and SOMETIMES is what
the -s option selects when the user asks for it (htscoremain.c:1234).

So HTTrack obeys robots.txt fully by default, and the header said the opposite.
Anyone reading it to answer "does this crawler respect robots.txt" got the
wrong answer from the one place they would look.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>
2026-07-13 20:37:03 +02:00
Xavier Roche
7d9d4ed890 Give the Windows binaries a version resource (#558)
libhttrack.dll and httrack.exe have never carried a VERSIONINFO: no product
name, no version, nothing. Right-click either one on Windows and Properties
has no Details worth reading.

That becomes a hard problem now that we are signing them. SignPath enforce
file metadata restrictions: every binary in a release must name the same
product and the same product version, and a binary that names nothing cannot
satisfy the rule. It fails the signing request, on release day, rather than
the build.

So add src/version.rc, and two wrappers that set the parts which differ per
binary. The version is spelled out there as numbers, because a VERSIONINFO
needs 3,49,12,0 and cannot take a string apart, and because htsglobal.h drags
in C declarations that a resource compiler has no business parsing.

That leaves the version written twice, which is how a version resource quietly
starts lying about which release it is. tests/01_engine-version-macros.test
fails the build if version.rc and htsglobal.h ever disagree, on any of the four
values, and on the product name too. I checked that it fires rather than
assuming: drift the numbers and it fails, restore them and it passes.

The product name is HTTrack Website Copier, on all of them. WinHTTrack is the
name of the Windows GUI, not of the command line program or of the engine.

Signed-off-by: Xavier Roche <roche@httrack.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-13 20:20:02 +02:00
Xavier Roche
573167e8dd Port the CLI, webhttrack and proxytrack to VS2022, and retire the VS2008 project files (#555)
Follow-up to #554, which ported libhttrack. The CLI, webhttrack and proxytrack were still VS2008 .vcproj, which v143 cannot open, so WinHTTrack.sln still could not be opened as a whole. They are recreated as v143 .vcxproj (x86+x64, /MD, vcpkg, no hardcoded C:\Dev paths), and the legacy .vcproj retire along with the VC6-era .dsp/.dsw beside them. EXTRA_DIST now ships the .vcxproj and vcpkg.json, which #554 had missed, so the tarball no longer carries a project file with no manifest beside it.

Building them turned up two more bugs no Windows compiler had seen. httrack.c's main() calls WSAStartup and WSACleanup itself, so the CLI needs Ws2_32 of its own. proxytrack's getGMT reads the POSIX global timezone, which the UCRT only exposes as _timezone; the existing BSD branch grew an MSVC arm rather than switching to timegm, which would have changed the date arithmetic.

CI builds all four projects and checks the binaries land where WinHTTrack expects. It also asserts, through dumpbin, that libhttrack.dll and httrack.exe import the same vcruntime140.dll and are built for the expected machine: a CRT split across that boundary links cleanly and only crashes later, on the first cross-heap free. The assertion runs against cmd.exe first, which links the old msvcrt, so a detector that matched anything would fail the job instead of quietly blessing a mismatch. A malformed project file is now caught by an XML check in the Linux lint job rather than by a Windows runner minutes in.

Signed-off-by: Xavier Roche <roche@httrack.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-13 10:50:23 +02:00
Xavier Roche
e26a5f5c6a Build libhttrack on VS2022 with OpenSSL 3.x from vcpkg (#554)
The MSVC build had no CI and had rotted: libhttrack.vcproj is a VS2008 file that v143 cannot open, pinning OpenSSL 1.0.1j and zlib from hardcoded C:\Dev paths. WinHTTrack, ported to VS2022, links libhttrack.dll and takes OpenSSL and zlib through it, so the GUI could not link at all: nothing produced a modern libhttrack.lib.

Adds src/libhttrack.vcxproj (v143, x86+x64, /MD dynamic CRT, DLL) beside the legacy .vcproj, which stays until the CLI, webhttrack and proxytrack are ported. OpenSSL 3.x and zlib come from vcpkg on dynamic triplets, so an OpenSSL CVE is a DLL swap rather than a rebuild. The source list comes from libhttrack_la_SOURCES rather than the old .vcproj, which predated htssniff.c and the selftest files and pulled in httrack.c, the CLI main(). Also adds a Windows CI job, which the repo never had; that gap is how the project file drifted this far.

The C needed no OpenSSL port, but the build did surface three bugs no Windows compiler had ever seen:

- MSVC has no fseeko/ftello/timegm. They are aliased to _fseeki64/_ftelli64/_mkgmtime in htslib.h, which is not an installed header: an object-like macro of that name in an installed one would rewrite the identifier in a consumer's own declarations and C++ member names.
- Winsock's getaddrinfo/freeaddrinfo are __stdcall, while hts_resolver_backend declared its function pointers plain. That compiles on x64, which has a single calling convention, and fails on x86. All three backends now carry HTS_RESOLVER_CALL. hts_dns_set_resolver_backend is not exported (hidden visibility), so despite htsnet.h being installed this is not an ABI change and owes no soname bump.
- The --continue resume path cast a 64-bit offset to off_t, which is 32-bit on MSVC, for both the truncate and the seek. A resume past 2GB wrapped, and _chsize_s then destroyed the partial file.

Signed-off-by: Xavier Roche <roche@httrack.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-13 00:00:39 +02:00
Xavier Roche
627ae2b043 tests: assert the strjoker budget fired, not just that work stayed bounded (#553)
The filterbounds self-test added in #551 asserted `steps < 10*maxsteps`, which
catches a budget whose enforcement is dropped (the counter still climbs to
~1.26e9). But the counter and the enforcement are the same statement, so
deleting the budget line outright leaves steps at 0: `0 < 10*maxsteps` holds and
the probe passes. Only the trailing strjokerfind call then catches it, by
hanging into a harness timeout, which is exactly what #551 set out to remove.

Add the floor `steps > maxsteps`: the budget must push the counter past the cap.
Deleting the budget now aborts the test in milliseconds instead of timing out.
Verified both regressions (line deleted; enforcement dropped) trip an assertion.

Signed-off-by: Xavier Roche <roche@httrack.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 18:10:57 +02:00
Xavier Roche
71ab3574ef Remove the obsolete Java-applet parser and dead SWF module remnants (#552)
* Remove the obsolete Java-applet .class parser and dead SWF vestiges

Java applets stopped running in every mainstream browser years ago (NPAPI
dropped by Chrome in 2015 and Firefox in 2017; the JDK browser plugin gone
since JDK 11), so htsjava -- a hand-rolled parser of hostile .class bytecode
fetched off the network -- chased dependencies no live site serves while
carrying real attack surface for no functional gain. The SWF module was
already gone; only vestiges remained (a dead libhtsswf.so.1 dlopen entry and
help-text examples).

htsjava was a dlopen plugin, never linked into libhttrack, so its removal
leaves libhttrack's ABI untouched: libhttrack.so.3 is unchanged and the
libhttrack3/-dev packages just stop shipping libhtsjava.so.3*. That is a
plain file drop dpkg removes on upgrade -- no package rename, no
Replaces/Breaks, and nothing ever linked the library (it was dlopened), so
there are no reverse dependencies. The parsejava/-j option stays; it also
gates JavaScript parsing.

Drops the plugin sources, the build/config/vcproj wiring, the java self-test
and its two engine tests, and the now-unused hts_count_fits helper (whose
only caller was the plugin), and regenerates the man page. The <applet> URL
rewriting in the HTML parser and the .class codebase bookkeeping are left
intact, so applet pages are still mirrored as plain files.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* Scrub the removed java/swf modules from the shipped HTML docs

Follow-up to the htsjava/SWF removal: the pre-generated docs in html/ (shipped
in httrack-doc) still named the gone modules. Update the two stale --help
mirrors in httrack.man.html by hand (a full groff regen would rewrite the whole
file under a newer groff) and drop the htsjava.c plugin-example reference from
plug.html.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* Finish scrubbing the java-class docs across the guides and man source

The -j option still exists (it drives JavaScript parsing), so every "parse
Java Classes" summary in the HTML guides becomes "parse scripts", and the
obsolete .class-parsing descriptions and java-applet troubleshooting entries
are reworded to drop the removed capability. The "Some java classes may not
find..." engine-limit line is dropped at its source (README, from which
makeman.sh regenerates the man LIMITS section), and httrack.1 regenerated.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

---------

Signed-off-by: Xavier Roche <roche@httrack.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 18:09:56 +02:00
Xavier Roche
076127ddea tests: make the strjoker work-budget test deterministic, not timeout-reliant (#551)
The filterbounds self-test's step-budget case (900 stars, subject cut to 900)
stayed under the 2,000,000-step budget: the #501 failure memo alone bounded it,
so the budget never fired and the `== NULL` assertion held with or without it.
Only a harness timeout would have caught the budget's removal.

Size the star-heavy dead-end to the length cap (1023 stars, 2048-char subject),
where the memoized matcher runs ~1.26e9 steps (~6s) unbounded, and assert
through a new test-only strjoker_steps() that the work stays near the cap.
Deleting the budget now trips the assertion in milliseconds instead of timing
the suite out.

Signed-off-by: Xavier Roche <roche@httrack.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 15:59:38 +02:00
242 changed files with 8830 additions and 5833 deletions

8
.gitattributes vendored Normal file
View File

@@ -0,0 +1,8 @@
# Resource scripts are Windows tooling input and must stay CRLF: the engine has no
# encoding guard, so an autocrlf checkout could otherwise flatten them silently.
*.rc text eol=crlf
# The test scripts run under Git Bash on the Windows CI; a CRLF checkout makes
# bash die on $'\r' on every line of them.
*.test text eol=lf
*.sh text eol=lf

8
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,8 @@
version: 2
updates:
# Bumps builtin-baseline in src/vcpkg.json so the pinned OpenSSL/zlib can't rot.
# windows-build.yml validates each bump; the pin makes what ships reproducible.
- package-ecosystem: vcpkg
directory: /src
schedule:
interval: weekly

View File

@@ -41,7 +41,7 @@ jobs:
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
build-essential clang autoconf automake libtool autoconf-archive \
zlib1g-dev libssl-dev
zlib1g-dev libssl-dev libbrotli-dev libzstd-dev
- name: Configure
run: |
@@ -50,6 +50,9 @@ jobs:
# committed generated files already let a plain checkout build.
autoreconf -fi
./configure
# a missing decoder would silently drop the coding from Accept-Encoding
grep -q "define HTS_USEBROTLI 1" config.h
grep -q "define HTS_USEZSTD 1" config.h
- name: Build
run: make -j"$(nproc)"
@@ -82,7 +85,7 @@ jobs:
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
build-essential autoconf automake libtool autoconf-archive \
zlib1g-dev libssl-dev
zlib1g-dev libssl-dev libbrotli-dev libzstd-dev
- name: Configure
run: |
@@ -123,14 +126,18 @@ jobs:
- name: Install build dependencies
run: |
set -euo pipefail
brew install autoconf automake libtool autoconf-archive
brew install autoconf automake libtool autoconf-archive brotli zstd
- name: Configure
run: |
set -euo pipefail
ssl="$(brew --prefix openssl@3)"
brewp="$(brew --prefix)"
autoreconf -fi
./configure CPPFLAGS="-I${ssl}/include" LDFLAGS="-L${ssl}/lib"
./configure CPPFLAGS="-I${ssl}/include -I${brewp}/include" \
LDFLAGS="-L${ssl}/lib -L${brewp}/lib"
grep -q "define HTS_USEBROTLI 1" config.h
grep -q "define HTS_USEZSTD 1" config.h
- name: Build
run: make -j"$(sysctl -n hw.ncpu)"
@@ -166,14 +173,16 @@ jobs:
- name: Install build dependencies
run: |
set -euo pipefail
brew install autoconf automake libtool autoconf-archive
brew install autoconf automake libtool autoconf-archive brotli zstd
- name: Build and install into a temp prefix
run: |
set -euo pipefail
ssl="$(brew --prefix openssl@3)"
brewp="$(brew --prefix)"
autoreconf -fi
./configure CPPFLAGS="-I${ssl}/include" LDFLAGS="-L${ssl}/lib" \
./configure CPPFLAGS="-I${ssl}/include -I${brewp}/include" \
LDFLAGS="-L${ssl}/lib -L${brewp}/lib" \
--prefix="$RUNNER_TEMP/inst"
make -j"$(sysctl -n hw.ncpu)"
make install
@@ -201,7 +210,8 @@ jobs:
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
build-essential gcc-multilib autoconf automake libtool \
autoconf-archive zlib1g-dev:i386 libssl-dev:i386
autoconf-archive zlib1g-dev:i386 libssl-dev:i386 \
libbrotli-dev:i386 libzstd-dev:i386
- name: Configure
run: |
@@ -242,7 +252,7 @@ jobs:
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
build-essential autoconf automake libtool autoconf-archive \
zlib1g-dev libssl-dev
zlib1g-dev libssl-dev libbrotli-dev libzstd-dev
- name: Configure (sanitized)
run: |
@@ -344,7 +354,7 @@ jobs:
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
build-essential clang autoconf automake libtool autoconf-archive \
zlib1g-dev libssl-dev
zlib1g-dev libssl-dev libbrotli-dev libzstd-dev
- name: Configure (fuzzers, static)
run: |
@@ -424,7 +434,7 @@ jobs:
apt-get install -y --no-install-recommends \
ca-certificates git \
build-essential autoconf automake libtool autoconf-archive \
zlib1g-dev libssl-dev \
zlib1g-dev libssl-dev libbrotli-dev libzstd-dev \
debhelper devscripts lintian fakeroot
- uses: actions/checkout@v6
@@ -468,7 +478,7 @@ jobs:
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
build-essential autoconf automake libtool autoconf-archive \
zlib1g-dev libssl-dev
zlib1g-dev libssl-dev libbrotli-dev libzstd-dev
- name: distcheck
run: |
@@ -544,6 +554,16 @@ jobs:
- name: shfmt
run: shfmt -d -i 4 $SHELL_SCRIPTS
# MSBuild rejects a malformed .vcxproj with a bare MSB4025 and no build, so
# catch it here in seconds rather than on a Windows runner minutes in.
- name: XML well-formedness (MSBuild project files)
run: |
set -euo pipefail
for f in src/*.vcxproj; do
python3 -c "import sys,xml.dom.minidom; xml.dom.minidom.parse(sys.argv[1])" "$f"
echo "ok $f"
done
# Check clang-format on CHANGED LINES ONLY. The engine predates clang-format
# (it was shaped by an old Visual Studio formatter) and does not round-trip,
# so we never reformat the whole tree -- only the lines a PR touches.

View File

@@ -46,6 +46,12 @@ jobs:
# fopen's umask-controlled 0666 is intended for mirror/cache/log
# output; the one credential file (cookies.txt) is kept 0600 on Unix.
config: |
paths-ignore:
# Demo callback samples, not part of libhttrack.
- libtest
# ProxyTrack: a separate legacy binary with no auth surface; its
# recv/cache-parse code trips taint queries by design.
- src/proxy
query-filters:
- exclude:
id: cpp/world-writable-file-creation

224
.github/workflows/windows-build.yml vendored Normal file
View File

@@ -0,0 +1,224 @@
# Windows build of the engine (VS2022 v143 + vcpkg): libhttrack, the CLI,
# webhttrack, proxytrack.
#
# The autotools CI covers the unix builds; this covers the MSVC one, which had
# no coverage at all and had drifted (the old .vcproj pinned OpenSSL 1.0.1j).
# libhttrack.dll is what the WinHTTrack GUI links against.
name: windows-build
on:
push:
branches: [master]
pull_request:
workflow_dispatch:
permissions:
contents: read
jobs:
libhttrack:
runs-on: windows-2022
strategy:
fail-fast: false
matrix:
platform: [x64, Win32]
configuration: [Release]
steps:
- uses: actions/checkout@v4
with:
submodules: recursive # coucal lives in src/coucal
# Located through vswhere rather than microsoft/setup-msbuild: the repo
# only allows GitHub-owned actions.
- name: Find MSBuild
shell: pwsh
run: |
$vswhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe"
$msbuild = & $vswhere -latest -products * -requires Microsoft.Component.MSBuild `
-find MSBuild\**\Bin\MSBuild.exe | Select-Object -First 1
if (-not $msbuild) { throw "MSBuild not found" }
Write-Host "MSBuild: $msbuild"
"MSBUILD=$msbuild" | Out-File -FilePath $env:GITHUB_ENV -Append
- name: Enable vcpkg MSBuild integration
shell: pwsh
run: vcpkg integrate install
# The runner image's vcpkg checkout is pinned to some commit; our manifest's
# builtin-baseline is usually newer, so `git show <baseline>:versions/...`
# fails until that commit is local. Fetch exactly the pinned baseline (read
# from the manifest, so Dependabot bumps need no workflow edit).
- name: Fetch the pinned vcpkg baseline
shell: pwsh
run: |
$ErrorActionPreference = "Stop"
$root = if ($env:VCPKG_INSTALLATION_ROOT) { $env:VCPKG_INSTALLATION_ROOT } else { "C:\vcpkg" }
$baseline = (Get-Content src/vcpkg.json -Raw | ConvertFrom-Json).'builtin-baseline'
if (-not $baseline) { throw "no builtin-baseline in src/vcpkg.json" }
git -C $root fetch --no-tags origin $baseline
if ($LASTEXITCODE -ne 0) { throw "could not fetch vcpkg baseline $baseline" }
# httrack and webhttrack carry a ProjectReference to libhttrack, so building
# them builds it first; proxytrack is standalone.
- name: Build
shell: pwsh
run: |
foreach ($proj in @("libhttrack", "httrack", "webhttrack", "proxytrack")) {
& $env:MSBUILD "src\$proj.vcxproj" `
/m `
/p:Configuration=${{ matrix.configuration }} `
/p:Platform=${{ matrix.platform }} `
/p:VcpkgEnableManifest=true `
/flp:LogFile=msbuild-$proj.log`;Verbosity=normal
if ($LASTEXITCODE -ne 0) { throw "$proj failed" }
}
# WinHTTrack links src\$(Platform)\$(Configuration)\libhttrack.lib, so the
# import lib and the DLL both have to land there under that exact name.
- name: Check the binaries landed where they are expected
shell: pwsh
run: |
$dir = "src\${{ matrix.platform }}\${{ matrix.configuration }}"
$want = @("libhttrack.dll", "libhttrack.lib", "httrack.exe",
"webhttrack.exe", "proxytrack.exe")
foreach ($f in $want) {
if (-not (Test-Path "$dir\$f")) { throw "missing $dir\$f" }
Write-Host "found $dir\$f"
}
# A CRT split across the exe/DLL boundary links fine and crashes on the
# first cross-heap free, so assert both sides import the *same* vcruntime.
# Also assert the machine type: Test-Path alone would accept an x64 binary
# sitting in the Win32 output dir.
- name: Check the CRT is shared across the boundary
shell: pwsh
run: |
$ErrorActionPreference = "Stop"
$dir = "src\${{ matrix.platform }}\${{ matrix.configuration }}"
$dumpbin = & "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" `
-latest -find VC\Tools\MSVC\**\bin\Host*\*\dumpbin.exe | Select-Object -First 1
if (-not $dumpbin) { throw "dumpbin not found" }
$wantMachine = if ("${{ matrix.platform }}" -eq "x64") { "x64" } else { "x86" }
function Get-Crt($path) {
$out = & $dumpbin /dependents /headers $path
if ($LASTEXITCODE -ne 0) { throw "dumpbin failed on $path" }
,@($out | Select-String -Pattern '^\s*(vcruntime\d+d?\.dll)$' |
ForEach-Object { $_.Matches[0].Groups[1].Value.ToLower() })
}
# Negative control: cmd.exe links the old msvcrt, not vcruntime140. If
# this came back non-empty the detector would match anything, and the
# assertion below would pass on a mismatched CRT too.
if ((Get-Crt "$env:SystemRoot\System32\cmd.exe").Count -ne 0) {
throw "negative control failed: the vcruntime detector matches anything"
}
$crts = @{}
foreach ($f in @("libhttrack.dll", "httrack.exe")) {
$crt = Get-Crt "$dir\$f"
if ($crt.Count -eq 0) { throw "$f imports no vcruntime: static or mismatched CRT" }
$crts[$f] = $crt
$hdr = & $dumpbin /headers "$dir\$f"
if (-not ($hdr | Select-String -SimpleMatch "machine ($wantMachine)")) {
throw "$f is not $wantMachine"
}
Write-Host "$f -> $($crt -join ',') ($wantMachine)"
}
$a = $crts["libhttrack.dll"] | Sort-Object
$b = $crts["httrack.exe"] | Sort-Object
if (Compare-Object $a $b) {
throw "CRT mismatch across the boundary: libhttrack.dll=$a httrack.exe=$b"
}
# The engine ships ~90 tests and none had ever run on Windows: "make check"
# is Linux/macOS only. These are the offline ones, driven from Git Bash
# against the native httrack.exe. They subsume the self-tests this step
# used to run inline (codecs, cache, fsize).
# The *_local-* ones crawl the bundled Python server over loopback: the real
# TLS handshake, cache and file writer, which nothing else on Windows covers.
- name: Run the engine test suite (offline tests)
shell: bash
working-directory: tests
timeout-minutes: 45
run: |
set -u
bin="$(cygpath -u "$GITHUB_WORKSPACE")/src/${{ matrix.platform }}/${{ matrix.configuration }}"
export PATH="$bin:$PATH"
command -v httrack >/dev/null || { echo "::error::no httrack.exe in $bin"; exit 1; }
# httrack.exe is native, so MSYS rewrites any argument shaped like a
# POSIX path, and a URL path is shaped exactly like one: "/a/b.html"
# reached the engine as "C:/Program Files/Git/a/b.html". Switch that
# off, and hand the tests a TMPDIR that is already a Windows path.
export MSYS_NO_PATHCONV=1
export MSYS2_ARG_CONV_EXCL='*'
TMPDIR="$(cygpath -m "$RUNNER_TEMP")"
export TMPDIR
# Mirror what configure hands the suite. LC_ALL sets the codeset MSYS maps
# a UTF-8 mirror name onto UTF-16 with, which the intl crawls "test -f".
export HTTPS_SUPPORT=yes BROTLI_ENABLED=yes ZSTD_ENABLED=yes
export LC_ALL=C.UTF-8
# A wedged crawl must not eat the job's timeout budget. timeout(1)'s
# signals can't reap a native httrack.exe (MSYS signals don't reach it),
# so a hang orphaned processes that starved the runner; run_with_timeout
# TerminateProcess-es the whole tree. 600s clears the slowest multi-pass
# crawl (a few passes at --max-time=120 each).
. ./testlib.sh
pass=0 fail=0 skip=0 failed="" skipped=""
for t in 00_runnable.test 01_engine-*.test 01_zlib-*.test \
*_local-*.test 13_crawl_proxy_https.test 58_watchdog.test \
60_crawl-log-salvage.test; do
rc=0
run_with_timeout 600 bash "$t" >"$t.log" 2>&1 || rc=$?
case "$rc" in
0) pass=$((pass + 1)); echo "PASS $t" ;;
77) skip=$((skip + 1)) skipped="$skipped $t"; echo "SKIP $t" ;;
124)
fail=$((fail + 1)) failed="$failed $t"
echo "FAIL $t (timed out, tree killed)"
# Re-running a wedge traced would just hang again: salvage the
# killed crawl's own logs into the artifact instead.
dump_crawl_logs >>"$t.log"
tail -n 25 "$t.log" | sed 's/^/ /'
;;
*)
fail=$((fail + 1)) failed="$failed $t"
echo "FAIL $t (exit $rc)"
# These assert with `test "$(...)" == "..." || exit 1`, which
# says nothing at all on failure. Re-run traced, still bounded.
run_with_timeout 600 bash -x "$t" >>"$t.log" 2>&1 || true
tail -n 25 "$t.log" | sed 's/^/ /'
;;
esac
done
echo "ran=$((pass + fail + skip)) pass=$pass fail=$fail skip=$skip" |
tee -a "$GITHUB_STEP_SUMMARY"
# Every gate here exits 77, so an all-skipped suite would report green having
# tested nothing: pin the skips, and floor the passes in case the glob empties.
expected_skips=" 48_local-crange-memresume.test 71_local-crange-repaircache.test" # pending #581
[ "$pass" -ge 90 ] || { echo "::error::only $pass tests passed ($skip skipped)"; exit 1; }
[ "$skipped" = "$expected_skips" ] || { echo "::error::unexpected skips:$skipped"; exit 1; }
[ "$fail" -eq 0 ] || { echo "::error::failing:$failed"; exit 1; }
- name: Upload the test logs
if: always()
uses: actions/upload-artifact@v4
with:
name: engine-tests-${{ matrix.platform }}-${{ matrix.configuration }}
path: tests/*.log
if-no-files-found: warn
- name: Upload MSBuild logs
if: always()
uses: actions/upload-artifact@v4
with:
name: msbuild-${{ matrix.platform }}-${{ matrix.configuration }}
path: msbuild-*.log
if-no-files-found: ignore

3
.gitignore vendored
View File

@@ -43,3 +43,6 @@ Makefile
# Python bytecode (tests/local-server.py).
__pycache__/
# Per-checkout Claude Code rules (symlink into a local sandbox).
/CLAUDE.local.md

View File

@@ -19,6 +19,13 @@ the operational checklist: toolchain, invariants, and how to ship a change.
(`request_queue_size`) so macOS/BSD don't drop connections under a parallel
`-c16` bigcrawl the way Python's default backlog of 5 did.
Or run `sh build.sh` to do bootstrap + configure + make in one shot.
- A `tests/NN_*.test` runs only if listed in `tests/Makefile.am`'s `TESTS`; an
unregistered file is silently skipped.
- `make check` prepends the build's `src/` to `PATH`, but a hand-run `.test` does
not — an installed `/usr/bin/httrack` then shadows your build. Run via `make
check`, or `PATH="<bld>/src:$PATH"` for a manual run.
- Give new `.test` scripts `set -e`: the older ones predate the rule, so several
`local-crawl.sh` calls with no `set -e` report PASS on any non-last failure.
## Hard invariants
- **Generated autotools files are NOT in git.** `configure`, every
@@ -31,15 +38,32 @@ the operational checklist: toolchain, invariants, and how to ship a change.
- **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
round-trip.
- **Byte-safe edits.** Files with raw high bytes are ISO-8859-1 (French
comments). Edit them byte-wise (`perl -0pi`, `sed`), not through a tool that
re-encodes to UTF-8 and corrupts them.
- **Byte-safe edits.** A few tracked files carry raw ISO-8859-1 high bytes
(French comments): `src/htsconcat.c`, `lang/*.txt`, `html/contact.html`, and
the `fuzz/corpus/*` vectors. Edit those byte-wise (`perl -0pi`, `sed`), not
through a tool that re-encodes to UTF-8 and corrupts them. The rest of the tree
is UTF-8 and safe to edit normally.
## Security (HTTrack parses hostile input off the network)
- Bounds-check every copy. Overflow-safe form: put the untrusted value alone,
`untrusted < limit - controlled` — never `controlled + untrusted < limit`,
which can wrap and pass.
## C conventions
- **Use the `*t` allocator wrappers, never raw libc** (`htssafe.h`):
`malloct`/`calloct`/`realloct`/`freet`/`strdupt`, in test and selftest code
too. `freet` NULLs its (lvalue) argument and tolerates NULL; `calloct(n, sz)`
keeps calloc's arg order. Only exception: storing or calling a libc symbol
itself (e.g. a resolver-backend function pointer).
- **Exported API is `HTSEXT_API`.** Everything else is hidden by
`-fvisibility=hidden` and free to change (check with `nm -D --defined-only
libhttrack.so`). Touching an installed-header struct (see `DevIncludes_DATA` in
`src/Makefile.am`) or an exported signature is an ABI break — flag and discuss,
bump the soname, and prefer keeping the old entry point beside a new one.
- **Windows ABI is free to break, POSIX is not.** The Windows DLL ships next to
the exe with no soname contract, so a `_WIN32`-only ABI change needs no
deprecation dance; POSIX/ELF keeps the flag-discuss-bump rules.
## Code & prose
- 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
@@ -67,8 +91,9 @@ Before pushing, and when reviewing others, don't skim for bugs:
- **Co-Authored-By is mandatory for AI-assisted commits.** Carry a
`Co-Authored-By:` trailer naming the assistant. Attribute there, never in a
PR-body footer.
- PRs land as a merge commit; every commit on the branch goes onto master, so
keep each commit message clean and meaningful.
- PRs are squash-merged: one commit per PR lands on master, built from the PR
title and description, so those are what the history keeps. The branch's
intermediate commits are not preserved.
## PR descriptions
- Plain concise prose; lead with what changed and why. No What/Why/How template.

View File

@@ -6,8 +6,8 @@ with an AI assistant? The operational checklist is [AGENTS.md](AGENTS.md).
## Pull requests
- One change per PR. Small diffs merge fast.
- PRs land as a merge commit, so the branch's commits go onto master as-is: keep
each commit message clean and explain *why*.
- PRs are squash-merged: one commit per PR goes onto master, built from the PR
title and description, so those are the history. Explain *why* there.
- Be terse in the PR title and description: name the problem, not the fix, don't
restate the diff, and calibrate length to the change.
- Add or update tests for engine changes (`tests/`), and keep CI green.

View File

@@ -1,6 +1,6 @@
AC_PREREQ([2.71])
AC_INIT([httrack], [3.49.12], [roche+packaging@httrack.com], [httrack], [http://www.httrack.com/])
AC_INIT([httrack], [3.49.13], [roche+packaging@httrack.com], [httrack], [http://www.httrack.com/])
AC_COPYRIGHT([
HTTrack Website Copier, Offline Browser for Windows and Unix
Copyright (C) 1998-2015 Xavier Roche and other contributors
@@ -29,11 +29,13 @@ AC_CONFIG_SRCDIR(src/httrack.c)
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_HEADERS(config.h)
AM_INIT_AUTOMAKE([subdir-objects])
# 3:4:0: 3.49.12 tail-appends one field (why_url) to httrackp and otherwise only
# deletes dead comments; no struct layout or exported signature broke vs 3.49.11,
# so it stays soname .so.3; bump revision.
# 3:5:0: 3.49.13 leaves every installed struct layout and the exported symbol set
# untouched vs 3.49.12; the 2 GB (_stat64) and UTF-8 export widenings are _WIN32-only,
# and INTsys widened on POSIX (#600) but sits in no installed struct. Stays soname
# .so.3; bump revision. x32 alone changes layout (LLint was 4 bytes there, #524), and
# is not a release architecture.
# (3:0:0 was the htsblk mime-buffer widening, the ABI break that moved .so.2 -> .so.3.)
VERSION_INFO="3:4:0"
VERSION_INFO="3:5:0"
AM_MAINTAINER_MODE
AC_USE_SYSTEM_EXTENSIONS
@@ -173,6 +175,10 @@ AC_CHECK_HEADERS([execinfo.h])
### zlib
CHECK_ZLIB()
### brotli and zstd content codings (optional)
CHECK_BROTLI()
CHECK_ZSTD()
### OpenSSL is explicitly enabled/disabled ?
AC_MSG_CHECKING(whether to enable https support)
AC_ARG_ENABLE([https],

15
debian/changelog vendored
View File

@@ -1,3 +1,18 @@
httrack (3.49.13-1) unstable; urgency=medium
* New upstream release: SOCKS5 and CONNECT proxy support, brotli and zstd
content decoding, --update data-loss fixes, and hardening of several
network-facing parsers; full list in history.txt.
* Add libbrotli-dev and libzstd-dev to Build-Depends for the new content
codings.
* libhttrack3 and libhttrack-dev no longer ship libhtsjava.so.3*: the
obsolete Java-applet parser was removed upstream. It was a dlopen plugin
with no reverse dependencies, so this is a plain file drop on upgrade;
libhttrack.so.3 itself is unchanged and needs no rename.
* Drop the htsjava attribution from debian/copyright.
-- Xavier Roche <xavier@debian.org> Fri, 17 Jul 2026 10:49:52 +0200
httrack (3.49.12-1) unstable; urgency=medium
* New upstream release: security and crawl-correctness fixes (remote stack

2
debian/control vendored
View File

@@ -2,7 +2,7 @@ Source: httrack
Section: web
Maintainer: Xavier Roche <roche@httrack.com>
Standards-Version: 4.7.4
Build-Depends: debhelper-compat (= 14), autoconf, autoconf-archive, automake, libtool, zlib1g-dev, libssl-dev
Build-Depends: debhelper-compat (= 14), autoconf, autoconf-archive, automake, libtool, zlib1g-dev, libssl-dev, libbrotli-dev, libzstd-dev
Rules-Requires-Root: no
Homepage: http://www.httrack.com
Vcs-Git: https://github.com/xroche/httrack.git

View File

@@ -1,7 +1,8 @@
# libFuzzer harnesses; built only with --enable-fuzzers (requires clang).
if FUZZERS
noinst_PROGRAMS = fuzz-charset fuzz-meta fuzz-idna fuzz-entities \
fuzz-unescape fuzz-filters fuzz-url fuzz-header fuzz-cachendx
fuzz-unescape fuzz-filters fuzz-url fuzz-header fuzz-cachendx \
fuzz-htsparse
endif
AM_CPPFLAGS = \
@@ -25,6 +26,7 @@ fuzz_filters_SOURCES = fuzz-filters.c fuzz.h
fuzz_url_SOURCES = fuzz-url.c fuzz.h
fuzz_header_SOURCES = fuzz-header.c fuzz.h
fuzz_cachendx_SOURCES = fuzz-cachendx.c fuzz.h
fuzz_htsparse_SOURCES = fuzz-htsparse.c fuzz.h
# List corpus files explicitly: automake does not expand EXTRA_DIST globs.
EXTRA_DIST = README.md run-fuzzers.sh \
@@ -37,9 +39,12 @@ EXTRA_DIST = README.md run-fuzzers.sh \
corpus/filters/filter.bin corpus/filters/filter-size.bin \
corpus/filters/regress-empty-subject-unique.bin \
corpus/filters/redos-star-classes.bin \
corpus/filters/regress-classdepth-timeout.bin \
corpus/url/http-url.txt corpus/url/relative-path.txt \
corpus/url/regress-file-empty-path.txt corpus/url/regress-long-path-abort.txt \
corpus/header/full-response.txt corpus/header/redirect.txt \
corpus/cachendx/new-format.txt corpus/cachendx/old-format.txt \
corpus/cachendx/regress-overadvance.bin \
corpus/cachendx/regress-truncated-entry.bin
corpus/cachendx/regress-truncated-entry.bin \
corpus/htsparse/basic.html corpus/htsparse/script-inscript.html \
corpus/htsparse/meta-usemap.html corpus/htsparse/malformed.html

Binary file not shown.

View File

@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html><head>
<meta charset="utf-8">
<base href="http://example.com/dir/">
<title>Seed</title>
<link rel="stylesheet" href="style.css">
<script src="app.js"></script>
</head><body>
<h1>Hi</h1>
<a href="page2.html">next</a>
<a href="http://other.example.org/x?y=1#frag">abs</a>
<img src="pic.png" srcset="a.png 1x, b.png 2x">
<script>var u="inline.html"; document.write('<a href="gen.html">g</a>');</script>
<form action="/cgi/submit"><input name="q"></form>
</body></html>

View File

@@ -0,0 +1,8 @@
<a href="unclosed.html
<img src='mix"ed.png>
<a href=noquote.html >bare</a>
<!-- comment <a href="incomment.html"> -->
<a href="tab newline
.html">wsp</a>
<script>unterminated "string and <a href=
<a href=

View File

@@ -0,0 +1,11 @@
<html><head>
<meta http-equiv="refresh" content="0; url=redir.html">
<base href="http://h/b/">
<link rel="alternate" href="feed.xml">
</head><body background="page-bg.jpg">
<img src="map.png" usemap="#m">
<map name="m"><area href="area1.html" coords="0,0,10,10"></map>
<applet code="A.class" codebase="applets/"><param name="src" value="p.dat"></applet>
<object data="o.swf"><embed src="e.svg"></object>
<a href="&#104;ttp://ent/e.html">entity</a>
</body></html>

View File

@@ -0,0 +1,13 @@
<html><body>
<script type="text/javascript">
var a = "http://x/1.html", b = 'q\'uote', c = "/*not*/comment";
// line "with" quotes and http://y/2.html
/* block 'with' <a href="notparsed"> */
var re = /a\/b\//g;
document.write('<img src="w1.png">');
document.writeln("<a href='w2.html'>k</a>");
element.onclick = "location='onh.html'";
</script>
<a href="after.html" onmouseover="go('ev.html')">x</a>
<div style="background:url(bg.png)">z</div>
</body></html>

175
fuzz/fuzz-htsparse.c Normal file
View File

@@ -0,0 +1,175 @@
/* ------------------------------------------------------------ */
/*
HTTrack Website Copier, Offline Browser for Windows and Unix
Copyright (C) 2026 Xavier Roche and other contributors
SPDX-License-Identifier: GPL-3.0-or-later
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Please visit our Website: http://www.httrack.com
*/
/* Fuzz the real htsparse() over a mocked engine: the minimal crawl state
httpmirror() builds, then a page walked through the parser and discarded. The
str/stre wiring below mirrors htsparse()'s call site in htscore.c; update it
in lockstep if those structs gain a field the parser reads. */
#include "fuzz.h"
#include "httrack-library.h"
#include "htscore.h"
#include "htsback.h"
#include "htshash.h"
#include "htsrobots.h"
#include "htsparse.h"
#include "htsmodules.h"
#include "coucal.h"
/* htsparse ignores str.addLink on the internal parse; stub it. */
static int fuzz_addlink(htsmoduleStruct *str, char *link) {
(void) str;
(void) link;
return 0;
}
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
static int inited = 0;
httrackp *opt;
cache_back cache;
hash_struct hash;
robots_wizard robots;
struct_back *sback;
char **filters = NULL;
int filptr = 0;
htsblk r;
htsmoduleStruct str;
htsmoduleStructExtended stre;
int ptr, error = 0, store_errpage = 0;
int makeindex_done = 0, makeindex_links = 0;
FILE *makeindex_fp = NULL;
char makeindex_firstlink[HTS_URLMAXSIZE * 2] = "";
LLint stat_fragment = 0, makestat_total = 0;
int makestat_lnk = 0;
char base[HTS_URLMAXSIZE * 2] = "";
char codebase[HTS_URLMAXSIZE * 2] = "";
char err_msg[1024] = "";
if (!inited) {
hts_init();
inited = 1;
}
opt = hts_create_opt();
opt->log = opt->errlog = NULL;
opt->robots = 0;
memset(&cache, 0, sizeof(cache));
cache.type = 0; /* no on-disk cache */
cache.hashtable = coucal_new(0);
cache.cached_tests = coucal_new(0);
coucal_value_is_malloc(cache.cached_tests, 1);
memset(&robots, 0, sizeof(robots));
strcpybuff(robots.adr, "!");
opt->robotsptr = &robots;
opt->maxfilter = maximum(opt->maxfilter, 128);
filters_init(&filters, opt->maxfilter, 0);
opt->filters.filters = &filters;
opt->filters.filptr = &filptr;
opt->hash = &hash;
hts_record_init(opt);
hash_init(opt, &hash, opt->urlhack);
hash.liens = (const lien_url *const *const *) &opt->liens;
sback = back_new(opt, opt->maxsoc * 32 + 1024);
/* ptr=1 (index 1 is the parsed page) selects full HTML parsing + the
rewriter; urladr()/urlfil()/savename() alias heap(ptr), save=/dev/null. */
hts_record_link(opt, "example.com", "/", "/dev/null", "", "", NULL);
hts_record_link(opt, "example.com", "/index.html", "/dev/null", "", "", NULL);
ptr = 1;
/* NUL-terminated in a size+1 alloc: htsparse one-past-reads onto the NUL. */
hts_init_htsblk(&r);
r.statuscode = 200;
r.size = (LLint) size;
r.adr = malloct(size + 1);
if (size)
memcpy(r.adr, data, size);
r.adr[size] = '\0';
strcpybuff(r.contenttype, "text/html");
memset(&str, 0, sizeof(str));
memset(&stre, 0, sizeof(stre));
str.err_msg = err_msg;
str.filename = heap(ptr)->sav;
str.mime = r.contenttype;
str.url_host = heap(ptr)->adr;
str.url_file = heap(ptr)->fil;
str.size = (int) r.size;
str.addLink = fuzz_addlink;
str.opt = opt;
str.sback = sback;
str.cache = &cache;
str.hashptr = &hash;
str.numero_passe = 0;
str.ptr_ = &ptr;
str.page_charset_ = NULL;
stre.r_ = &r;
stre.error_ = &error;
stre.exit_xh_ = &opt->state.exit_xh;
stre.store_errpage_ = &store_errpage;
stre.base = base;
stre.codebase = codebase;
stre.filters_ = &filters;
stre.filptr_ = &filptr;
stre.robots_ = &robots;
stre.hash_ = &hash;
stre.makeindex_done_ = &makeindex_done;
stre.makeindex_fp_ = &makeindex_fp;
stre.makeindex_links_ = &makeindex_links;
stre.makeindex_firstlink_ = makeindex_firstlink;
stre.template_header_ = "";
stre.template_body_ = "";
stre.template_footer_ = "";
stre.stat_fragment_ = &stat_fragment;
stre.makestat_time = 0;
stre.makestat_fp = NULL;
stre.makestat_total_ = &makestat_total;
stre.makestat_lnk_ = &makestat_lnk;
stre.maketrack_fp = NULL;
(void) htsparse(&str, &stre);
freet(r.adr);
back_delete_all(opt, &cache, sback);
back_free(&sback);
hash_free(&hash);
coucal_delete(&cache.hashtable);
coucal_delete(&cache.cached_tests);
checkrobots_free(&robots);
if (filters != NULL) {
if (filters[0] != NULL)
freet(filters[0]);
freet(filters);
}
hts_record_free(opt);
hts_free_opt(opt);
return 0;
}

View File

@@ -4,6 +4,31 @@ HTTrack Website Copier release history:
This file lists all changes and fixes that have been made for HTTrack
3.49-13
+ New: SOCKS5 proxy support, with scheme-aware -P URLs (socks5://, socks5h://, connect://) and plain HTTP tunneled through a CONNECT-only proxy (#563, #564)
+ New: decode brotli and zstd content codings, advertised over TLS only as browsers do (#556)
+ New: webhttrack exposes the engine options added since 3.49-2, among them --cookies-file, --pause and --strip-query (#587)
+ Fixed: files of 2 GB or more were mishandled on Windows and on every 32-bit build (#569)
+ Fixed: --update destroyed a good local copy when the re-fetch returned an HTTP error, was aborted by -M/-E, failed to decode, or came in short (#176, #521, #557, #562)
+ Fixed: a self-redirect cookie wall was dropped instead of being re-fetched with the cookie (#15)
+ Fixed: a stalled TLS handshake ignored --timeout, and synchronous DNS resolution could wedge a crawl past --max-time (#607, #613)
+ Fixed: -M metered saved bytes rather than received volume, and overshot its cap under a slow server (#77, #520)
+ Fixed: several network-facing overflows and denial-of-service paths in the Content-Range, chunked-transfer, cookie, filter and ProxyTrack cache parsers
+ Fixed: a failed connect did not fall back to the next address on Windows (#579)
+ Fixed: -P took an out-of-range port as a garbage port, and scanned past an IPv6 literal's closing bracket (#598, #602)
+ Fixed: reject a port outside 1..65535 wherever one is parsed (a crawled URL, the htsserver and proxytrack listen arguments, an ftp:// URL), instead of letting a bare sscanf wrap a huge value into a plausible port and silently use it (#614, #626)
+ Fixed: a configured proxy still resolved and dialed the origin itself (#592)
+ Fixed: ~/ in the -O base path was never expanded (#270)
+ Fixed: a non-ASCII -O output path was double-encoded on Windows once argv became UTF-8 (#621)
+ Fixed: files under a non-ASCII project path were saved to a mangled directory on Windows (#217)
+ Fixed: --build-top-index (-%i) and --protocol (-@i) were taken for the -i continue flag, wiping the URL list and exiting on the usage screen (#615)
+ Fixed: webhttrack ignored LC_ALL/LC_MESSAGES and picked the wrong Chinese and Portuguese (#95)
+ Fixed: webhttrack wrote its base path and httrack.ini to the filesystem root when $HOME was empty (#625)
+ Fixed: crawls on a non-default port were slowed by a per-request pre-resolve (#181)
+ Changed: Windows builds moved to Visual Studio 2022 and OpenSSL 3.x, the VS2008 project files are retired, and the binaries carry a version resource
+ Changed: removed the obsolete Java-applet (.class) parser and the dead SWF module remnants
+ Changed: multiple internal hardening, test and CI improvements (Windows and macOS crawl suites, HTML-parser fuzzing, parallel make check)
3.49-12
+ New: --why explains which filter rule accepts or rejects a given URL, then exits (#505)
+ Fixed: links carrying raw UTF-8 bytes were fetched double-encoded and 404'd (#516)

View File

@@ -579,7 +579,7 @@ And then, put the email address in your pages through:
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
<td id="footer"><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
</tr>
</table>

View File

@@ -144,7 +144,7 @@ h4 { margin: 0; font-weight: bold; font-size: 1.18em; }
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
<td id="footer"><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
</tr>
</table>

223
html/android.html Normal file
View File

@@ -0,0 +1,223 @@
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<meta name="description" content="How to mirror a website with HTTrack on Android: install the app, create a project, enter the address, run the mirror, and browse the result on your device." />
<meta name="keywords" content="httrack, HTTrack, android, offline browser, web mirror utility, website mirroring, mobile, Google Play" />
<title>HTTrack on Android</title>
<style type="text/css">
<!--
body {
margin: 0; padding: 0; margin-bottom: 15px; margin-top: 8px;
background: #77b;
}
body, td {
font: 14px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif;
}
#subTitle {
background: #000; color: #fff; padding: 4px; font-weight: bold;
}
#siteNavigation a, #siteNavigation .current {
font-weight: bold; color: #448;
}
#siteNavigation a:link { text-decoration: none; }
#siteNavigation a:visited { text-decoration: none; }
#siteNavigation .current { background-color: #ccd; }
#siteNavigation a:hover { text-decoration: none; background-color: #fff; color: #000; }
#siteNavigation a:active { text-decoration: none; background-color: #ccc; }
a:link { text-decoration: underline; color: #00f; }
a:visited { text-decoration: underline; color: #000; }
a:hover { text-decoration: underline; color: #c00; }
a:active { text-decoration: underline; }
#pageContent {
clear: both;
border-bottom: 6px solid #000;
padding: 10px; padding-top: 20px;
line-height: 1.65em;
background-image: url(images/bg_rings.gif);
background-repeat: no-repeat;
background-position: top right;
}
#pageContent, #siteNavigation {
background-color: #ccd;
}
.imgLeft { float: left; margin-right: 10px; margin-bottom: 10px; }
.imgRight { float: right; margin-left: 10px; margin-bottom: 10px; }
hr { height: 1px; color: #000; background-color: #000; margin-bottom: 15px; }
h1 { margin: 0; font-weight: bold; font-size: 2em; }
h2 { margin: 0; font-weight: bold; font-size: 1.6em; }
h3 { margin: 0; font-weight: bold; font-size: 1.3em; }
h4 { margin: 0; font-weight: bold; font-size: 1.18em; }
.blak { background-color: #000; }
.hide { display: none; }
.tableWidth { min-width: 400px; }
.tblRegular { border-collapse: collapse; }
.tblRegular td { padding: 6px; background-image: url(fade.gif); border: 2px solid #99c; }
.tblHeaderColor, .tblHeaderColor td { background: #99c; }
.tblNoBorder td { border: 0; }
// -->
</style>
</head>
<table width="76%" border="0" align="center" cellspacing="0" cellpadding="0" class="tableWidth">
<tr>
<td><img src="images/header_title_4.gif" width="400" height="34" alt="HTTrack Website Copier" title="" border="0" id="title" /></td>
</tr>
</table>
<table width="76%" border="0" align="center" cellspacing="0" cellpadding="3" class="tableWidth">
<tr>
<td id="subTitle">Open Source offline browser</td>
</tr>
</table>
<table width="76%" border="0" align="center" cellspacing="0" cellpadding="0" class="tableWidth">
<tr class="blak">
<td>
<table width="100%" border="0" align="center" cellspacing="1" cellpadding="0">
<tr>
<td colspan="6">
<table width="100%" border="0" align="center" cellspacing="0" cellpadding="10">
<tr>
<td id="pageContent">
<!-- ==================== End prologue ==================== -->
<h2 align="center"><em>HTTrack on Android</em></h2>
<br>
<p>HTTrack downloads a website to your device so you can read it offline. The
Android app runs the same mirroring engine as the desktop version behind a touch
interface. It needs Android 7.0 or later, and is available on
<a href="https://play.google.com/store/apps/details?id=com.httrack.android">Google Play</a>.</p>
<p>The steps below follow one mirror from start to finish.</p>
<br>
<ol>
<li><b>Grant storage access</b></li>
<br><small>On first launch the app asks for permission to store mirrors on your
device. The prompt reads <em>"Allow HTTrack Website Copier to access photos,
media, and files on your device?"</em>. Tap <b>ALLOW</b>: without it the app
cannot save the downloaded files.</small>
<br><br><center><img src="img/android_permission.png" width="320" alt="First-run storage permission dialog" border="0"></center>
<br><small>If you have used an older release, a second prompt offers to bring its
mirrors into the app. Tap <b>Import</b> to move them, or <b>Not now</b> to
skip.</small>
<br><br><center><img src="img/android_import.png" width="320" alt="Import mirrors from an older version" border="0"></center>
<br><br>
<li><b>Start</b></li>
<br><small>The welcome screen shows the engine version at the bottom. Tap
<b>Next</b> to create a project, or <b>Browse sites</b> to open a mirror you
already made.</small>
<br><br><center><img src="img/android_startup.png" width="320" alt="Welcome screen" border="0"></center>
<br><br>
<li><b>Name the project</b></li>
<br><small>Give the project a name, and optionally a category to group related
mirrors. <b>Base path</b> shows where the files will be written. Tap
<b>Next</b>.</small>
<br><br><center><img src="img/android_project.png" width="320" alt="Project name, category, and base path" border="0"></center>
<br><br>
<li><b>Enter the address</b></li>
<br><small>Type the site address. If a project of the same name already exists,
pick <b>Continue interrupted download</b> or <b>Update existing download</b>.
Tap <b>Options</b> to adjust the crawl, or <b>Start</b> to begin.</small>
<br><br><center><img src="img/android_url.png" width="320" alt="Web address and download action" border="0"></center>
<br><br>
<li><b>Options (optional)</b></li>
<br><small>The <b>Options</b> screen holds the crawl settings, grouped into
eleven tabs. It uses the same profile format as the desktop version, so a tab you
know from WinHTTrack behaves the same way here.</small>
<br><br><center><img src="img/android_options.png" width="320" alt="Options tab list" border="0"></center>
<br><small>The tabs are:</small>
<ul>
<li><small><b>Scan Rules</b>: wildcard filters for the addresses to keep or skip.</small></li>
<li><small><b>Limits</b>: caps on depth, size, time, speed, and number of connections.</small></li>
<li><small><b>Flow Control</b>: simultaneous connections, timeouts, and retries.</small></li>
<li><small><b>Links</b>: how far to follow links, and which extra files to fetch.</small></li>
<li><small><b>Build</b>: how the saved files and folders are named.</small></li>
<li><small><b>Browser ID</b>: the user-agent, language, and headers sent to servers.</small></li>
<li><small><b>Spider</b>: cookies, robots.txt handling, and request behavior.</small></li>
<li><small><b>Proxy address</b>: proxy host and port.</small></li>
<li><small><b>Log, Index, Cache</b>: log files, the search index, and the update cache.</small></li>
<li><small><b>Type/MIME associations</b>: map file extensions to MIME types.</small></li>
<li><small><b>Experts Only</b>: scan mode, how far the crawl may travel, and link rewriting.</small></li>
</ul>
<br><center><img src="img/android_scanrules.png" width="320" alt="Scan Rules tab" border="0"></center>
<br><center><img src="img/android_experts.png" width="320" alt="Experts Only tab" border="0"></center>
<br><small>The <a href="step9.html">desktop option reference</a> describes every
setting in full. A few desktop options are missing or fixed on Android: the proxy
tab has a host and port but no login and password, the download folder is fixed
inside the app's storage so there is no output-path setting, and the MIME table
holds up to eight entries.</small>
<br><br>
<li><b>Run the mirror</b></li>
<br><small>HTTrack downloads the site and reports live figures: bytes saved,
links scanned, transfer rate, and errors. Tap <b>Abort</b> to stop early; a
partial mirror can be resumed later.</small>
<br><br><center><img src="img/android_progress.png" width="320" alt="Crawl in progress with live statistics" border="0"></center>
<br><br>
<li><b>Browse the result</b></li>
<br><small>When the crawl finishes the app reports <b>Success</b> and the mirror
location. Tap <b>Browse Mirrored Website</b> to read the copy in your browser,
<b>View log</b> to see what happened, or <b>New project</b> to start
again.</small>
<br><br><center><img src="img/android_finished.png" width="320" alt="Mirror finished, success" border="0"></center>
<br><br>
<li><b>Where the files are</b></li>
<br><small>Mirrors are written under <tt>/storage/emulated/0/HTTrack/Websites</tt>,
in a folder named after the project. That folder lives in your device's shared
storage, so a file manager or a USB connection can reach it. Opening
<tt>index.html</tt> there browses a mirror without the app.</small>
</ol>
<br><br><br><br>
<p align="right">Back to <a href="index.html">Home</a></p>
<!-- ==================== Start epilogue ==================== -->
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</table>
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
</tr>
</table>
</body>
</html>

View File

@@ -173,7 +173,7 @@ There are also specific issues regarding this format:
<ul>
<li>The data in the central directory (such as CD extra field, and CD comments) are not used</li>
<li>The ZIP archive is allowed to contains more than 2^16 files (65535) ; in such case the total number of entries in the 32-bit central directory is 65536 (0xffff), but the presence of the 64-bit central directory is not mandatory</li>
<li>The ZIP archive is allowed to contains more than 2^32 bytes (4GiB) ; in such case the 64-bit central directory must be present <b>(not currently supported)</b></li>
<li>The ZIP archive is allowed to contains more than 2^32 bytes (4GiB) ; in such case the 64-bit central directory is emitted automatically (a single stored entry of 4GiB or more is not supported)</li>
</ul>
<br />
@@ -282,7 +282,7 @@ Libraries should generally handle this peculiar format, however.
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
<td id="footer"><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
</tr>
</table>

View File

@@ -145,7 +145,7 @@ The command-line version
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
<td id="footer"><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
</tr>
</table>

View File

@@ -243,7 +243,7 @@ roche at httrack dot com (Xavier ROCHE)<br>
<br><hr><br>
<br>
This program is covered by the GNU General Public License.<br>
HTTrack/HTTrack Website Copier is Copyright (C) 1998-2007 Xavier Roche and other contributors
HTTrack/HTTrack Website Copier is Copyright (C) 1998-2026 Xavier Roche and other contributors
<br>
<!-- ==================== Start epilogue ==================== -->
@@ -259,7 +259,7 @@ roche at httrack dot com (Xavier ROCHE)<br>
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
<td id="footer"><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
</tr>
</table>

View File

@@ -147,7 +147,7 @@ This page describes the HTTrack cache format.
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
<td id="footer"><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
</tr>
</table>

View File

@@ -263,7 +263,7 @@ clear language!
<li><a href="#QM8">Can HTTrack generates HP-UX or ISO9660 compatible files?</a><br></li>
<li><a href="#QM9">If there any SOCKS support?</a><br></li>
<li><a href="#QM9">Is there any SOCKS support?</a><br></li>
<li><a href="#QM10">What's this hts-cache directory? Can I remove it?</a><br></li>
@@ -835,8 +835,8 @@ A: <em>Yes. Use user:password@your_proxy_name as your proxy name (example: <tt>s
<br><br><a NAME="QM8">Q: <strong>Can HTTrack generates HP-UX or ISO9660 compatible files?</strong></a><br>
A: <em>Yes. See the build options (-N, or see the WinHTTrack options)</em>
<br><br><a NAME="QM9">Q: <strong>If there any SOCKS support?</strong></a><br>
A: <em>Not yet!</em>
<br><br><a NAME="QM9">Q: <strong>Is there any SOCKS support?</strong></a><br>
A: <em>Yes. HTTrack supports SOCKS5 and HTTP CONNECT proxies: give the proxy with a scheme prefix, e.g. <tt>-P socks5://host:port</tt> or <tt>-P connect://host:port</tt> (prefix <tt>user:pass@</tt> before the host for authenticated proxies).</em>
<br><br><a NAME="QM10">Q: <strong>What's this hts-cache directory? Can I remove it?</strong></a><br>
A: <em>NO if you want to update the site, because this directory is used by HTTrack for this purpose.
@@ -931,7 +931,7 @@ A: <em>Feel free to <a href="contact.html">contact us</a>!
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
<td id="footer"><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
</tr>
</table>

View File

@@ -189,7 +189,7 @@ See also: The <a href="faq.html#VF1">FAQ</a><br>
<br>
Filters are analyzed by HTTrack from the first filter to the last one. The complete URL
name is compared to filters defined by the user or added automatically by HTTrack. <br><br>
A scan rule has an higher priority is it is declared later - hierarchy is important: <br>
A scan rule has a higher priority if it is declared later - hierarchy is important: <br>
<br>
<table BORDER="1" CELLPADDING="2">
@@ -307,7 +307,7 @@ See also: The <a href="faq.html#VF1">FAQ</a><br>
<br>
Filters are analyzed by HTTrack from the first filter to the last one. The sizes
are compared against scan rules defined by the user.<br><br>
A scan rule has an higher priority is it is declared later - hierarchy is important.<br>
A scan rule has a higher priority if it is declared later - hierarchy is important.<br>
Note: scan rules based on size can be mixed with regular URL patterns<br>
@@ -361,7 +361,7 @@ See also: The <a href="faq.html#VF1">FAQ</a><br>
<br>
Filters are analyzed by HTTrack from the first filter to the last one. The complete MIME
type is compared against scan rules defined by the user.<br><br>
A scan rule has an higher priority is it is declared later - hierarchy is important<br>
A scan rule has a higher priority if it is declared later - hierarchy is important<br>
Note: scan rules based on MIME types can <b>NOT</b> be mixed with regular URL patterns or size patterns within the same rule, but you can use both of them in distinct ones<br>
@@ -387,12 +387,12 @@ See also: The <a href="faq.html#VF1">FAQ</a><br>
<tr>
<td nowrap><tt>-mime:video/*</tt></td>
<td>This will refuse all video links that were already scheduled for download
(i.e. all other 'application/' link download will be aborted)</td>
(i.e. the download will be aborted)</td>
</tr>
<tr>
<td nowrap><tt>-mime:video/* -mime:audio/*</tt></td>
<td>This will refuse all audio and video links that were already scheduled for download
(i.e. all other 'application/' link download will be aborted)</td>
(i.e. the download will be aborted)</td>
</tr>
<tr>
<td nowrap><tt>-mime:*/* +mime:text/html +mime:image/*</tt></td>
@@ -466,7 +466,7 @@ See also: The <a href="faq.html#VF1">FAQ</a><br>
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
<td id="footer"><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
</tr>
</table>

View File

@@ -396,7 +396,7 @@ hour) (--max-time[=N])</p></td></tr>
<td width="78%">
<p>maximum number of connections/seconds (*%c10)
<p>maximum number of connections/seconds (*%c5)
(--connection-per-second[=N])</p> </td></tr>
<tr valign="top" align="left">
<td width="11%"></td>
@@ -428,7 +428,7 @@ control:</b></p>
<p style="margin-top: 1em">number of multiple connections
(*c8) (--sockets[=N])</p></td></tr>
(*c4) (--sockets[=N])</p></td></tr>
<tr valign="top" align="left">
<td width="11%"></td>
<td width="4%">

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

BIN
html/img/android_import.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

BIN
html/img/android_url.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

View File

@@ -111,6 +111,12 @@ h4 { margin: 0; font-weight: bold; font-size: 1.18em; }
<li><a href="shelldoc.html">WinHTTrack/WebHTTrack (GUI version for Windows or Linux/Unix)</a></li>
<br>HTTrack GUI documentation, with step-by-step example, for the Windows release (WinHTTrack) and the Linux/Unix relese (WebHTTrack)<br>
<br>
<li><a href="android.html">HTTrack on Android</a></li>
<br>Step-by-step guide for the Android app<br>
<br>
<li><a href="cmddoc.html">Command-line version</a></li>
<br>How to run HTTrack from the command line, and where to find every option<br>
<br>
<li><a href="fcguide.html">HTTrack Users Guide By Fred Cohen</a></li>
<br>A tutorial that describes all command-line options, for Linux and Windows users<br>
<br>
@@ -142,7 +148,7 @@ h4 { margin: 0; font-weight: bold; font-size: 1.18em; }
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
<td id="footer"><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
</tr>
</table>

View File

@@ -125,7 +125,7 @@ You may also want to check the <tt>httrack.c</tt> and <tt>httrack.h<tt> files to
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
<td id="footer"><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
</tr>
</table>

View File

@@ -105,238 +105,14 @@ h4 { margin: 0; font-weight: bold; font-size: 1.18em; }
<li>Filters: <a href="filters.html">how to use them</a></li>
<br><small>Here you can find informations on filters: how to accept all gif files in a mirror, for example</small>
<br><br>
<li>List of options</li>
</ul>
</ul>
<tt>
<pre>
<p>The complete, current list of command-line options is generated from the
program itself, in <a href="httrack.man.html">the httrack manual page</a>.</p>
w mirror with automatic wizard
This is the default scanning option, the engine automatically scans links according to the default options, and filters defined. It does not prompt a message when a "foreign" link is reached.
<p>WinHTTrack and WebHTTrack offer the same options through their graphical option
panels, described in the <a href="step9.html">step-by-step guide</a>.</p>
W semi-automatic mirror with help-wizard (asks questions)
This option lets the engine ask the user if a link must be mirrored or not, when a new web has been found.
g just get files (saved in the current directory)
This option forces the engine not to scan the files indicated - i.e. the engine only gets the files indicated.
i continue an interrupted mirror using the cache
This option indicates to the engine that a mirror must be updated or continued.
rN recurse get with limited link depth of N
This option sets the maximum recurse level. Default is infinite (the engine "knows" that it should not go out of current domain)
a stay on the same address
This is the default primary scanning option, the engine does not go out of domains without permissions (filters, for example)
d stay on the same principal domain
This option lets the engine go on all sites that exist on the same principal domain.
Example: a link located at www.example.com that goes to members.example.com will be followed.
l stay on the same location (.com, etc.)
This option lets the engine go on all sites that exist on the same location.
Example: a link located at www.example.com that goes to www.anyotherweb.com will be followed.
Warning: this is a potentially dangerous option, limit the recurse depth with r option.
e go everywhere on the web
This option lets the engine go on any sites.
Example: a link located at www.example.com that goes to www.anyotherweb.org will be followed.
Warning: this is a potentially dangerous option, limit the recurse depth with r option.
n get non-html files 'near' an html file (ex: an image located outside)
This option lets the engine catch all files that have references on a page, but that exist outside the web site.
Example: List of ZIP files links on a page.
t test all URLs (even forbidden ones)
This option lets the engine test all links that are not caught.
Example: to test broken links in a site
x replace external html links by error pages
This option tells the engine to rewrite all links not taken into warning pages.
Example: to browse offline a site, and to warn people that they must be online if they click to external links.
sN follow robots.txt and meta robots tags
This option sets the way the engine treats "robots.txt" files. This file is often set by webmasters to avoir cgi-bin directories, or other irrevelant pages.
Values:
s0 Do not take robots.txt rules
s1 Follow rules, if compatible with internal filters
s2 Always follow site's rules
bN accept cookies in cookies.txt
This option activates or unactivates the cookie
b0 do not accept cookies
b1 accept cookies
S stay on the same directory
This option asks the engine to stay on the same folder level.
Example: A link in /index.html that points to /sub/other.html will not be followed
D can only go down into subdirs
This is the default option, the engine can go everywhere on the same directoy, or in lower structures
U can only go to upper directories
This option asks the engine to stay on the same folder level or in upper structures
B can both go up&down into the directory structure
This option lets the engine to go in any directory level
Y mirror ALL links located in the first level pages (mirror links)
This option is activated for the links typed in the command line
Example: if you have a list of web sites in www.asitelist.com/index.html, then all these sites will be mirrored
NN name conversion type (0 *original structure 1,2,3 html/data in one directory)
N0 Site-structure (default)
N1 Html in web/, images/other files in web/images/
N2 Html in web/html, images/other in web/images
N3 Html in web/, images/other in web/
N4 Html in web/, images/other in web/xxx, where xxx is the file extension (all gif will be placed onto web/gif, for example)
N5 Images/other in web/xxx and Html in web/html
N99 All files in web/, with random names (gadget !)
N100 Site-structure, without www.domain.xxx/
N101 Identical to N1 except that "web" is replaced by the site's name
N102 Identical to N2 except that "web" is replaced by the site's name
N103 Identical to N3 except that "web" is replaced by the site's name
N104 Identical to N4 except that "web" is replaced by the site's name
N105 Identical to N5 except that "web" is replaced by the site's name
N199 Identical to N99 except that "web" is replaced by the site's name
N1001 Identical to N1 except that there is no "web" directory
N1002 Identical to N2 except that there is no "web" directory
N1003 Identical to N3 except that there is no "web" directory (option set for g option)
N1004 Identical to N4 except that there is no "web" directory
N1005 Identical to N5 except that there is no "web" directory
N1099 Identical to N99 except that there is no "web" directory
LN long names
L0 Filenames and directory names are limited to 8 characters + 3 for extension
L1 No restrictions (default)
K keep original links (e.g. http://www.adr/link) (K0 *relative link)
This option has only been kept for compatibility reasons
pN priority mode:
p0 just scan, don't save anything (for checking links)
p1 save only html files
p2 save only non html files
p3 save all files
p7 get html files before, then treat other files
cN number of multiple connections (*c8)
Set the numer of multiple simultaneous connections
O path for mirror/logfiles+cache (-O path_mirror[,path_cache_and_logfiles])
This option define the path for mirror and log files
Example: -P "/user/webs","/user/logs"
P proxy use (-P proxy:port or -P user:pass@proxy:port)
This option define the proxy used in this mirror
Example: -P proxy.myhost.com:8080
F user-agent field (-F \"user-agent name\
This option define the user-agent field
Example: -F "Mozilla/4.5 (compatible; HTTrack 1.2x; Windows 98)"
mN maximum file length for a non-html file
This option define the maximum size for non-html files
Example: -m100000
mN,N' for non html (N) and html (N')
This option define the maximum size for non-html files and html-files
Example: -m100000,250000
MN maximum overall size that can be uploaded/scanned
This option define the maximum amount of bytes that can be downloaded
Example: -M1000000
EN maximum mirror time in seconds (60=1 minute, 3600=1 hour)
This option define the maximum time that the mirror can last
Example: -E3600
AN maximum transfer rate in bytes/seconds (1000=1kb/s max)
This option define the maximum transfer rate
Example: -A2000
GN pause transfer if N bytes reached, and wait until lock file is deleted
This option asks the engine to pause every time N bytes have been transferred, and restarts when the lock file "hts-pause.lock" is being deleted
Example: -G20000000
u check document type if unknown (cgi,asp..)
This option define the way the engine checks the file type
u0 do not check
u1 check but /
u2 check always
RN number of retries, in case of timeout or non-fatal errors (*R0)
This option sets the maximum number of tries that can be processed for a file
o *generate output html file in case of error (404..) (o0 don't generate)
This option define whether the engine has to generate html output file or not if an error occurred
TN timeout, number of seconds after a non-responding link is shutdown
This option define the timeout
Example: -T120
JN traffic jam control, minimum transfert rate (bytes/seconds) tolerated for a link
This option define the minimum transfer rate
Example: -J200
HN host is abandoned if: 0=never, 1=timeout, 2=slow, 3=timeout or slow
This option define whether the engine has to abandon a host if a timeout/"too slow" error occurred
&P extended parsing, attempt to parse all links (even in unknown tags or Javascript)
This option activates the extended parsing, that attempt to find links in unknown Html code/javascript
j *parse scripts (j0 don't parse)
This option defines whether the engine has to parse scripts or not to catch included files
I *make an index (I0 don't make)
This option define whether the engine has to generate an index.html on the top directory
X *delete old files after update (X0 keep delete)
This option define whether the engine has to delete locally, after an update, files that have been deleted in the remote mirror, or that have been excluded
C *create/use a cache for updates and retries (C0 no cache)
This option define whether the engine has to generate a cache for retries and updates or not
k store all files in cache (not useful if files on disk)
This option define whether the engine has to store all files in cache or not
V execute system command after each files ($0 is the filename: -V \"rm \\$0\
This option lets the engine execute a command for each file saved on disk
q quiet mode (no questions)
Do not ask questions (for example, for confirm an option)
Q log quiet mode (no log)
Do not generate log files
v verbose screen mode
Log files are printed in the screen
f *log file mode
Log files are generated into two log files
z extra infos log
Add more informations on log files
Z debug log
Add debug informations on log files
--mirror <URLs> *make a mirror of site(s)
--get <URLs> get the files indicated, do not seek other URLs
--mirrorlinks <URLs> test links in pages (identical to -Y)
--testlinks <URLs> test links in pages
--spider <URLs> spider site(s), to test links (reports Errors & Warnings)
--update <URLs> update a mirror, without confirmation
--skeleton<URLs> make a mirror, but gets only html files
--http10 force http/1.0 requests when possible
</pre>
</tt>
<!-- ==================== Start epilogue ==================== -->
@@ -352,7 +128,7 @@ Add debug informations on log files
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
<td id="footer"><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
</tr>
</table>

View File

@@ -145,7 +145,7 @@ downloads. HTTrack is fully configurable, and has an integrated help system.
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
<td id="footer"><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
</tr>
</table>

View File

@@ -286,7 +286,7 @@ module exit point
the function name and prototype MUST match this prototype
*/
EXTERNAL_FUNCTION int hts_unplug(httrackp *opt) {
fprintf(stder, "Module unplugged");
fprintf(stderr, "Module unplugged");
return 1; /* success */
}
@@ -331,7 +331,7 @@ httrack --wrapper mylibrary,myparameter-string http://www.example.com
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
<td id="footer"><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
</tr>
</table>

View File

@@ -204,7 +204,7 @@ Below additional function names that can be defined inside the optional libhttra
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
<td id="footer"><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
</tr>
</table>

View File

@@ -250,7 +250,7 @@ Script example:
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
<td id="footer"><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
</tr>
</table>

View File

@@ -69,7 +69,7 @@ ${LANG_K3} : ${HTTRACK_WEB}
<form>
<input type="button" value="OK" onClick="window.close();"
onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPOK}' onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</form>
@@ -92,7 +92,7 @@ ${LANG_K3} : ${HTTRACK_WEB}
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></small></td>
<td id="footer"><small><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></small></td>
</tr>
</table>

View File

@@ -73,7 +73,7 @@ function info(str) {
<td id="subTitle" align="right">
<a href="/server/file.html" target="_blank"
onClick="window.open('/server/file.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
onMouseOver="info('${html:LANG_O1}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_O1}' onMouseOver="info('${html:LANG_O1}'); return true" onMouseOut="info('&nbsp;'); return true"
style="color:#FFFFFF"
>
${LANG_O1}
@@ -85,7 +85,7 @@ ${do:if-file-exists:html/index.html}
<td id="subTitle" align="right">
<a href="/index.html" target="_blank"
onClick="window.open('/server/help.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPHELP}' onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info('&nbsp;'); return true"
style="color:#FFFFFF"
>
${LANG_O5}
@@ -118,20 +118,20 @@ ${do:end-if}
<form action="${thisfile}" name="form">
<table width="100%">
<tr><td>${LANG_T2}</td><td>http://<input name="urladr"
onMouseOver="info('${html:LANG_T10}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_T10}' onMouseOver="info('${html:LANG_T10}'); return true" onMouseOut="info('&nbsp;'); return true"
></td></tr>
<tr><td colspan=2>
<table width="100%">
<th>${LANG_T4}</th>
<tr><td>${LANG_T5}:</td><td><input name="urllogin"
onMouseOver="info('${html:LANG_T12}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_T12}' onMouseOver="info('${html:LANG_T12}'); return true" onMouseOut="info('&nbsp;'); return true"
></td></tr>
<tr><td>${LANG_T6}:</td><td><input name="urlpass"
onMouseOver="info('${html:LANG_T13}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_T13}' onMouseOver="info('${html:LANG_T13}'); return true" onMouseOut="info('&nbsp;'); return true"
></td></tr>
<tr><td>${LANG_T7}:</td><td><input type="button" value="${LANG_T8}" onClick="alert('not yet implemented!')"
onMouseOver="info('${html:LANG_T14}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_T14}' onMouseOver="info('${html:LANG_T14}'); return true" onMouseOut="info('&nbsp;'); return true"
></td></tr>
</table>
@@ -139,7 +139,7 @@ ${do:end-if}
<tr><td>
<input type="button" value="OK" onClick="if (do_add()) { window.close(); }"
onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPOK}' onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td></tr>
@@ -159,7 +159,7 @@ ${do:end-if}
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></small></td>
<td id="footer"><small><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></small></td>
</tr>
</table>

View File

@@ -72,7 +72,7 @@ ${error}
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></small></td>
<td id="footer"><small><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></small></td>
</tr>
</table>

View File

@@ -96,7 +96,7 @@ ${do:loadhash}
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></small></td>
<td id="footer"><small><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></small></td>
</tr>
</table>

View File

@@ -36,7 +36,7 @@ function info(str) {
<td id="subTitle" align="right">
<a href="/server/file.html" target="_blank"
onClick="window.open('/server/file.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
onMouseOver="info('${html:LANG_O1}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_O1}' onMouseOver="info('${html:LANG_O1}'); return true" onMouseOut="info('&nbsp;'); return true"
style="color:#FFFFFF"
>
${LANG_O1}
@@ -48,7 +48,7 @@ ${do:if-file-exists:html/index.html}
<td id="subTitle" align="right">
<a href="/index.html" target="_blank"
onClick="window.open('/server/help.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPHELP}' onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info('&nbsp;'); return true"
style="color:#FFFFFF"
>
${LANG_O5}
@@ -143,7 +143,7 @@ ${path}/${projname}
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></small></td>
<td id="footer"><small><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></small></td>
</tr>
</table>

View File

@@ -58,7 +58,7 @@ function info(str) {
<table class="tableWidth" border="0" width="100%" cellspacing="0">
<tr><td class="tabCtrl" align="left">
<a style="background:black;color: white" href="about.html" target="_new"
onMouseOver="info('${html:LANG_G21}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_G21}' onMouseOver="info('${html:LANG_G21}'); return true" onMouseOut="info('&nbsp;'); return true"
>
${LANG_O16}...
</a>
@@ -67,7 +67,7 @@ ${LANG_O16}...
<tr><td class="tabCtrl" align="left">
<a style="background:black;color: white"
href="http://www.httrack.com/update.php3?Product=HTTrack&Version=${HTTRACK_VERSIONID}&VersionStr=${HTTRACK_VERSION}&Platform=${HTS_PLATFORM}&LanguageId=${lang}" target="_new"
onMouseOver="info('${html:LANG_O17}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_O17}' onMouseOver="info('${html:LANG_O17}'); return true" onMouseOut="info('&nbsp;'); return true"
>
${LANG_O17}...
</a>
@@ -78,7 +78,7 @@ ${do:if-file-exists:html/index.html}
<tr><td class="tabCtrl" align="left">
<a style="background:black;color: white"
href="/index.html" target="_new"
onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPHELP}' onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info('&nbsp;'); return true"
>
${LANG_P16}
</a>
@@ -103,7 +103,7 @@ ${do:end-if}
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></small></td>
<td id="footer"><small><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></small></td>
</tr>
</table>

View File

@@ -43,7 +43,7 @@ function info(str) {
<td id="subTitle" align="right">
<a href="/server/file.html" target="_blank"
onClick="window.open('/server/file.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
onMouseOver="info('${html:LANG_O1}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_O1}' onMouseOver="info('${html:LANG_O1}'); return true" onMouseOut="info('&nbsp;'); return true"
style="color:#FFFFFF"
>
${LANG_O1}
@@ -55,7 +55,7 @@ ${do:if-file-exists:html/index.html}
<td id="subTitle" align="right">
<a href="/index.html" target="_blank"
onClick="window.open('/server/help.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPHELP}' onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info('&nbsp;'); return true"
style="color:#FFFFFF"
>
${LANG_O5}
@@ -113,7 +113,7 @@ ${LANG_THANKYOU}!
<tr><td align="right">
<input name="nextBtn" type="submit" value=" ${LANG_NEXT} >> "
onMouseOver="info('${html:LANG_TIPNEXT}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPNEXT}' onMouseOver="info('${html:LANG_TIPNEXT}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td></tr>
</table>
@@ -133,7 +133,7 @@ ${LANG_THANKYOU}!
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></small></td>
<td id="footer"><small><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></small></td>
</tr>
</table>

View File

@@ -60,7 +60,7 @@ ${do:if-file-exists:html/index.html}
<td>
<a href="/step9_opt1.html" target="_blank"
onClick="window.open('/step9_opt1.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPHELP}' onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info('&nbsp;'); return true"
>${LANG_TIPHELP}</a>
</td>
${do:end-if}
@@ -71,18 +71,18 @@ ${do:end-if}
<table class="tableWidth" border="0" width="100%" cellspacing="0">
<tr>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option1.html" onClick="form.redirect.value='option1.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT1}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT1}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option2.html" onClick="form.redirect.value='option2.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT2}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT2}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option3.html" onClick="form.redirect.value='option3.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT3}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT3}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option4.html" onClick="form.redirect.value='option4.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT4}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT4}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option5.html" onClick="form.redirect.value='option5.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT5}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT5}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option11.html" onClick="form.redirect.value='option11.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT11}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT11}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option1.html" onClick="form.redirect.value='option1.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT1}' onMouseOver="info('${html:LANG_IOPT1}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT1}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option2.html" onClick="form.redirect.value='option2.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT2}' onMouseOver="info('${html:LANG_IOPT2}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT2}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option3.html" onClick="form.redirect.value='option3.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT3}' onMouseOver="info('${html:LANG_IOPT3}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT3}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option4.html" onClick="form.redirect.value='option4.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT4}' onMouseOver="info('${html:LANG_IOPT4}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT4}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option5.html" onClick="form.redirect.value='option5.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT5}' onMouseOver="info('${html:LANG_IOPT5}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT5}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option11.html" onClick="form.redirect.value='option11.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT11}' onMouseOver="info('${html:LANG_IOPT11}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT11}</a></td>
</tr><tr>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option6.html" onClick="form.redirect.value='option6.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT6}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT6}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option7.html" onClick="form.redirect.value='option7.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT7}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT7}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option8.html" onClick="form.redirect.value='option8.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT8}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT8}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option9.html" onClick="form.redirect.value='option9.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT9}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT9}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option10.html" onClick="form.redirect.value='option10.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT10}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT10}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option6.html" onClick="form.redirect.value='option6.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT6}' onMouseOver="info('${html:LANG_IOPT6}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT6}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option7.html" onClick="form.redirect.value='option7.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT7}' onMouseOver="info('${html:LANG_IOPT7}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT7}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option8.html" onClick="form.redirect.value='option8.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT8}' onMouseOver="info('${html:LANG_IOPT8}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT8}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option9.html" onClick="form.redirect.value='option9.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT9}' onMouseOver="info('${html:LANG_IOPT9}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT9}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option10.html" onClick="form.redirect.value='option10.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT10}' onMouseOver="info('${html:LANG_IOPT10}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT10}</a></td>
<td class="tabCtrl" align="center">&nbsp;</td>
</tr>
@@ -107,16 +107,16 @@ ${do:end-if}
<!-- checkboxes -->
<table border="0" width="100%" cellspacing="0">
<tr><td><input type="checkbox" name="parseall" ${checked:parseall}
onMouseOver="info('${html:LANG_I1}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_I1}' onMouseOver="info('${html:LANG_I1}'); return true" onMouseOut="info('&nbsp;'); return true"
> ${LANG_I31}</td></tr>
<tr><td><input type="checkbox" name="link" ${checked:link}
onMouseOver="info('${html:LANG_I2}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_I2}' onMouseOver="info('${html:LANG_I2}'); return true" onMouseOut="info('&nbsp;'); return true"
> ${LANG_I32}</td></tr>
<tr><td><input type="checkbox" name="testall" ${checked:testall}
onMouseOver="info('${html:LANG_I2b}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_I2b}' onMouseOver="info('${html:LANG_I2b}'); return true" onMouseOut="info('&nbsp;'); return true"
> ${LANG_I32b}</td></tr>
<tr><td><input type="checkbox" name="htmlfirst" ${checked:htmlfirst}
onMouseOver="info('${html:LANG_I2c}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_I2c}' onMouseOver="info('${html:LANG_I2c}'); return true" onMouseOut="info('&nbsp;'); return true"
> ${LANG_I32c}</td></tr>
</table>
@@ -125,12 +125,12 @@ ${do:end-if}
<tr><td align="left">
<input type="submit" value="${LANG_OK}"
onClick="form.closeme.value=1; form.submit(); return false;"
onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPOK}' onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td><td align="right">
<input type="button" value="${LANG_CANCEL}"
onClick="window.close();"
onMouseOver="info('${html:LANG_TIPCANCEL}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPCANCEL}' onMouseOver="info('${html:LANG_TIPCANCEL}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td></tr>
</table>
@@ -158,7 +158,7 @@ ${do:end-if}
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></small></td>
<td id="footer"><small><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></small></td>
</tr>
</table>

View File

@@ -60,7 +60,7 @@ ${do:if-file-exists:html/index.html}
<td>
<a href="/step9_opt7.html" target="_blank"
onClick="window.open('/step9_opt7.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPHELP}' onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info('&nbsp;'); return true"
>${LANG_TIPHELP}</a>
</td>
${do:end-if}
@@ -71,18 +71,18 @@ ${do:end-if}
<table class="tableWidth" border="0" width="100%" cellspacing="0">
<tr>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option1.html" onClick="form.redirect.value='option1.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT1}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT1}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option2.html" onClick="form.redirect.value='option2.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT2}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT2}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option3.html" onClick="form.redirect.value='option3.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT3}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT3}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option4.html" onClick="form.redirect.value='option4.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT4}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT4}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option5.html" onClick="form.redirect.value='option5.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT5}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT5}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option11.html" onClick="form.redirect.value='option11.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT11}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT11}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option1.html" onClick="form.redirect.value='option1.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT1}' onMouseOver="info('${html:LANG_IOPT1}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT1}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option2.html" onClick="form.redirect.value='option2.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT2}' onMouseOver="info('${html:LANG_IOPT2}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT2}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option3.html" onClick="form.redirect.value='option3.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT3}' onMouseOver="info('${html:LANG_IOPT3}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT3}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option4.html" onClick="form.redirect.value='option4.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT4}' onMouseOver="info('${html:LANG_IOPT4}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT4}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option5.html" onClick="form.redirect.value='option5.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT5}' onMouseOver="info('${html:LANG_IOPT5}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT5}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option11.html" onClick="form.redirect.value='option11.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT11}' onMouseOver="info('${html:LANG_IOPT11}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT11}</a></td>
</tr><tr>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option6.html" onClick="form.redirect.value='option6.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT6}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT6}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option7.html" onClick="form.redirect.value='option7.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT7}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT7}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option8.html" onClick="form.redirect.value='option8.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT8}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT8}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option9.html" onClick="form.redirect.value='option9.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT9}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT9}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option10.html" onClick="form.redirect.value='option10.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT10}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT10}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option6.html" onClick="form.redirect.value='option6.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT6}' onMouseOver="info('${html:LANG_IOPT6}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT6}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option7.html" onClick="form.redirect.value='option7.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT7}' onMouseOver="info('${html:LANG_IOPT7}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT7}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option8.html" onClick="form.redirect.value='option8.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT8}' onMouseOver="info('${html:LANG_IOPT8}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT8}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option9.html" onClick="form.redirect.value='option9.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT9}' onMouseOver="info('${html:LANG_IOPT9}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT9}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option10.html" onClick="form.redirect.value='option10.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT10}' onMouseOver="info('${html:LANG_IOPT10}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT10}</a></td>
<td class="tabCtrl" align="center">&nbsp;</td>
</tr>
@@ -98,17 +98,27 @@ ${do:end-if}
<input type="hidden" name="redirect" value="">
<input type="hidden" name="closeme" value="">
${LANG_IOPT10}:
${LANG_PROXYTYPE}
<select name="proxytype"
title='${html:LANG_PROXYTYPETIP}' onMouseOver="info('${html:LANG_PROXYTYPETIP}'); return true" onMouseOut="info('&nbsp;'); return true"
>
<option value=""${ztest:proxytype: selected:}>HTTP</option>
<option value="2"${test:proxytype::: selected}>HTTP (CONNECT tunnel)</option>
<option value="1"${test:proxytype:: selected}>SOCKS5</option>
</select>
<br><br>
${LANG_IOPT10}:
<input name="prox" value="${prox}" size="32"
onMouseOver="info('${html:LANG_G14}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_G14}' onMouseOver="info('${html:LANG_G14}'); return true" onMouseOut="info('&nbsp;'); return true"
>:
<input name="portprox" value="${portprox}" size="4"
onMouseOver="info('${html:LANG_G15}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_G15}' onMouseOver="info('${html:LANG_G15}'); return true" onMouseOut="info('&nbsp;'); return true"
>
<br>
<input type="checkbox" name="ftpprox" ${checked:ftpprox}
onMouseOver="info('${html:LANG_G15c}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_G15c}' onMouseOver="info('${html:LANG_G15c}'); return true" onMouseOut="info('&nbsp;'); return true"
> ${LANG_I47c}
<br><br>
@@ -117,12 +127,12 @@ ${LANG_IOPT10}:
<tr><td align="left">
<input type="submit" value="${LANG_OK}"
onClick="form.closeme.value=1; form.submit(); return false;"
onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPOK}' onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td><td align="right">
<input type="button" value="${LANG_CANCEL}"
onClick="window.close();"
onMouseOver="info('${html:LANG_TIPCANCEL}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPCANCEL}' onMouseOver="info('${html:LANG_TIPCANCEL}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td></tr>
</table>
@@ -150,7 +160,7 @@ ${LANG_IOPT10}:
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></small></td>
<td id="footer"><small><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></small></td>
</tr>
</table>

View File

@@ -60,7 +60,7 @@ ${do:if-file-exists:html/index.html}
<td>
<a href="/step9_opt9.html" target="_blank"
onClick="window.open('/step9_opt9.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPHELP}' onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info('&nbsp;'); return true"
>${LANG_TIPHELP}</a>
</td>
${do:end-if}
@@ -71,18 +71,18 @@ ${do:end-if}
<table class="tableWidth" border="0" width="100%" cellspacing="0">
<tr>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option1.html" onClick="form.redirect.value='option1.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT1}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT1}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option2.html" onClick="form.redirect.value='option2.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT2}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT2}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option3.html" onClick="form.redirect.value='option3.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT3}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT3}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option4.html" onClick="form.redirect.value='option4.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT4}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT4}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option5.html" onClick="form.redirect.value='option5.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT5}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT5}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option11.html" onClick="form.redirect.value='option11.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT11}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT11}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option1.html" onClick="form.redirect.value='option1.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT1}' onMouseOver="info('${html:LANG_IOPT1}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT1}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option2.html" onClick="form.redirect.value='option2.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT2}' onMouseOver="info('${html:LANG_IOPT2}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT2}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option3.html" onClick="form.redirect.value='option3.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT3}' onMouseOver="info('${html:LANG_IOPT3}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT3}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option4.html" onClick="form.redirect.value='option4.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT4}' onMouseOver="info('${html:LANG_IOPT4}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT4}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option5.html" onClick="form.redirect.value='option5.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT5}' onMouseOver="info('${html:LANG_IOPT5}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT5}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option11.html" onClick="form.redirect.value='option11.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT11}' onMouseOver="info('${html:LANG_IOPT11}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT11}</a></td>
</tr><tr>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option6.html" onClick="form.redirect.value='option6.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT6}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT6}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option7.html" onClick="form.redirect.value='option7.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT7}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT7}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option8.html" onClick="form.redirect.value='option8.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT8}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT8}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option9.html" onClick="form.redirect.value='option9.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT9}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT9}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option10.html" onClick="form.redirect.value='option10.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT10}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT10}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option6.html" onClick="form.redirect.value='option6.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT6}' onMouseOver="info('${html:LANG_IOPT6}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT6}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option7.html" onClick="form.redirect.value='option7.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT7}' onMouseOver="info('${html:LANG_IOPT7}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT7}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option8.html" onClick="form.redirect.value='option8.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT8}' onMouseOver="info('${html:LANG_IOPT8}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT8}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option9.html" onClick="form.redirect.value='option9.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT9}' onMouseOver="info('${html:LANG_IOPT9}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT9}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option10.html" onClick="form.redirect.value='option10.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT10}' onMouseOver="info('${html:LANG_IOPT10}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT10}</a></td>
<td class="tabCtrl" align="center">&nbsp;</td>
</tr>
@@ -112,97 +112,97 @@ ${LANG_W3}
<td align="left">
<input name="ext1" value="${ext1}"
onMouseOver="info('${html:LANG_W4}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_W4}' onMouseOver="info('${html:LANG_W4}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td><td align="left">
&#x21d4;
</td><td align="left">
<input name="mime1" value="${mime1}"
onMouseOver="info('${html:LANG_W5}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_W5}' onMouseOver="info('${html:LANG_W5}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td></tr>
<!-- -->
<td align="left">
<input name="ext2" value="${ext2}"
onMouseOver="info('${html:LANG_W4}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_W4}' onMouseOver="info('${html:LANG_W4}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td><td align="left">
&#x21d4;
</td><td align="left">
<input name="mime2" value="${mime2}"
onMouseOver="info('${html:LANG_W5}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_W5}' onMouseOver="info('${html:LANG_W5}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td></tr>
<!-- -->
<td align="left">
<input name="ext3" value="${ext3}"
onMouseOver="info('${html:LANG_W4}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_W4}' onMouseOver="info('${html:LANG_W4}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td><td align="left">
&#x21d4;
</td><td align="left">
<input name="mime3" value="${mime3}"
onMouseOver="info('${html:LANG_W5}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_W5}' onMouseOver="info('${html:LANG_W5}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td></tr>
<!-- -->
<td align="left">
<input name="ext4" value="${ext4}"
onMouseOver="info('${html:LANG_W4}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_W4}' onMouseOver="info('${html:LANG_W4}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td><td align="left">
&#x21d4;
</td><td align="left">
<input name="mime4" value="${mime4}"
onMouseOver="info('${html:LANG_W5}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_W5}' onMouseOver="info('${html:LANG_W5}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td></tr>
<!-- -->
<td align="left">
<input name="ext5" value="${ext5}"
onMouseOver="info('${html:LANG_W4}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_W4}' onMouseOver="info('${html:LANG_W4}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td><td align="left">
&#x21d4;
</td><td align="left">
<input name="mime5" value="${mime5}"
onMouseOver="info('${html:LANG_W5}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_W5}' onMouseOver="info('${html:LANG_W5}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td></tr>
<!-- -->
<td align="left">
<input name="ext6" value="${ext6}"
onMouseOver="info('${html:LANG_W4}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_W4}' onMouseOver="info('${html:LANG_W4}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td><td align="left">
&#x21d4;
</td><td align="left">
<input name="mime6" value="${mime6}"
onMouseOver="info('${html:LANG_W5}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_W5}' onMouseOver="info('${html:LANG_W5}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td></tr>
<!-- -->
<td align="left">
<input name="ext7" value="${ext7}"
onMouseOver="info('${html:LANG_W4}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_W4}' onMouseOver="info('${html:LANG_W4}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td><td align="left">
&#x21d4;
</td><td align="left">
<input name="mime7" value="${mime7}"
onMouseOver="info('${html:LANG_W5}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_W5}' onMouseOver="info('${html:LANG_W5}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td></tr>
<!-- -->
<td align="left">
<input name="ext8" value="${ext8}"
onMouseOver="info('${html:LANG_W4}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_W4}' onMouseOver="info('${html:LANG_W4}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td><td align="left">
&#x21d4;
</td><td align="left">
<input name="mime8" value="${mime8}"
onMouseOver="info('${html:LANG_W5}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_W5}' onMouseOver="info('${html:LANG_W5}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td></tr>
<!-- -->
@@ -217,12 +217,12 @@ ${LANG_W3}
<tr><td align="left">
<input type="submit" value="${LANG_OK}"
onClick="form.closeme.value=1; form.submit(); return false;"
onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPOK}' onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td><td align="right">
<input type="button" value="${LANG_CANCEL}"
onClick="window.close();"
onMouseOver="info('${html:LANG_TIPCANCEL}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPCANCEL}' onMouseOver="info('${html:LANG_TIPCANCEL}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td></tr>
</table>
@@ -250,7 +250,7 @@ ${LANG_W3}
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></small></td>
<td id="footer"><small><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></small></td>
</tr>
</table>

View File

@@ -60,7 +60,7 @@ ${do:if-file-exists:html/index.html}
<td>
<a href="/step9_opt5.html" target="_blank"
onClick="window.open('/step9_opt5.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPHELP}' onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info('&nbsp;'); return true"
>${LANG_TIPHELP}</a>
</td>
${do:end-if}
@@ -71,18 +71,18 @@ ${do:end-if}
<table class="tableWidth" border="0" width="100%" cellspacing="0">
<tr>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option1.html" onClick="form.redirect.value='option1.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT1}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT1}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option2.html" onClick="form.redirect.value='option2.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT2}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT2}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option3.html" onClick="form.redirect.value='option3.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT3}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT3}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option4.html" onClick="form.redirect.value='option4.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT4}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT4}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option5.html" onClick="form.redirect.value='option5.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT5}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT5}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option11.html" onClick="form.redirect.value='option11.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT11}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT11}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option1.html" onClick="form.redirect.value='option1.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT1}' onMouseOver="info('${html:LANG_IOPT1}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT1}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option2.html" onClick="form.redirect.value='option2.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT2}' onMouseOver="info('${html:LANG_IOPT2}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT2}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option3.html" onClick="form.redirect.value='option3.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT3}' onMouseOver="info('${html:LANG_IOPT3}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT3}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option4.html" onClick="form.redirect.value='option4.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT4}' onMouseOver="info('${html:LANG_IOPT4}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT4}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option5.html" onClick="form.redirect.value='option5.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT5}' onMouseOver="info('${html:LANG_IOPT5}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT5}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option11.html" onClick="form.redirect.value='option11.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT11}' onMouseOver="info('${html:LANG_IOPT11}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT11}</a></td>
</tr><tr>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option6.html" onClick="form.redirect.value='option6.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT6}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT6}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option7.html" onClick="form.redirect.value='option7.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT7}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT7}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option8.html" onClick="form.redirect.value='option8.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT8}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT8}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option9.html" onClick="form.redirect.value='option9.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT9}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT9}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option10.html" onClick="form.redirect.value='option10.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT10}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT10}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option6.html" onClick="form.redirect.value='option6.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT6}' onMouseOver="info('${html:LANG_IOPT6}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT6}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option7.html" onClick="form.redirect.value='option7.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT7}' onMouseOver="info('${html:LANG_IOPT7}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT7}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option8.html" onClick="form.redirect.value='option8.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT8}' onMouseOver="info('${html:LANG_IOPT8}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT8}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option9.html" onClick="form.redirect.value='option9.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT9}' onMouseOver="info('${html:LANG_IOPT9}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT9}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option10.html" onClick="form.redirect.value='option10.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT10}' onMouseOver="info('${html:LANG_IOPT10}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT10}</a></td>
<td class="tabCtrl" align="center">&nbsp;</td>
</tr>
@@ -101,20 +101,20 @@ ${do:end-if}
${LANG_I33}
<br>
<select name="build"
onMouseOver="info('${html:LANG_I3}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_I3}' onMouseOver="info('${html:LANG_I3}'); return true" onMouseOut="info('&nbsp;'); return true"
>
${listid:build:LISTDEF_3}
</select>
<input type="button" value="${LANG_O2}"
onClick="form.build.selectedIndex=14; window.open('option2b.html', 'option2b', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480').wparent=document; form.submit();"
onMouseOver="info('${html:LANG_I4}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_I4}' onMouseOver="info('${html:LANG_I4}'); return true" onMouseOut="info('&nbsp;'); return true"
>
<!-- checkboxes -->
<table border="0" width="100%" cellspacing="0">
<tr><td>
<select name="dos"
onMouseOver="info('${html:LANG_I8}\r\n${LANG_I8b}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_I8} ${html:LANG_I8b}' onMouseOver="info('${html:LANG_I8}\r\n${LANG_I8b}'); return true" onMouseOut="info('&nbsp;'); return true"
>
<option value="0"${ztest:dos: selected::}>&nbsp;</option>
<option value="1"${ztest:dos:: selected:}>${LANG_I37}</option>
@@ -122,19 +122,19 @@ ${listid:build:LISTDEF_3}
</select>
</td></tr>
<tr><td><input type="checkbox" name="errpage" ${checked:errpage}
onMouseOver="info('${html:LANG_I9}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_I9}' onMouseOver="info('${html:LANG_I9}'); return true" onMouseOut="info('&nbsp;'); return true"
> ${LANG_I38}</td></tr>
<tr><td><input type="checkbox" name="external" ${checked:external}
onMouseOver="info('${html:LANG_I29}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_I29}' onMouseOver="info('${html:LANG_I29}'); return true" onMouseOut="info('&nbsp;'); return true"
> ${LANG_I56}</td></tr>
<tr><td><input type="checkbox" name="hidepwd" ${checked:hidepwd}
onMouseOver="info('${html:LANG_I30}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_I30}' onMouseOver="info('${html:LANG_I30}'); return true" onMouseOut="info('&nbsp;'); return true"
> ${LANG_I66}</td></tr>
<tr><td><input type="checkbox" name="hidequery" ${checked:hidequery}
onMouseOver="info('${html:LANG_I30b}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_I30b}' onMouseOver="info('${html:LANG_I30b}'); return true" onMouseOut="info('&nbsp;'); return true"
> ${LANG_I67}</td></tr>
<tr><td><input type="checkbox" name="nopurge" ${checked:nopurge}
onMouseOver="info('${html:LANG_I1a}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_I1a}' onMouseOver="info('${html:LANG_I1a}'); return true" onMouseOut="info('&nbsp;'); return true"
> ${LANG_I57}</td></tr>
</table>
@@ -143,12 +143,12 @@ ${listid:build:LISTDEF_3}
<tr><td align="left">
<input type="submit" value="${LANG_OK}"
onClick="form.closeme.value=1; form.submit(); return false;"
onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPOK}' onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td><td align="right">
<input type="button" value="${LANG_CANCEL}"
onClick="window.close();"
onMouseOver="info('${html:LANG_TIPCANCEL}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPCANCEL}' onMouseOver="info('${html:LANG_TIPCANCEL}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td></tr>
</table>
@@ -176,7 +176,7 @@ ${listid:build:LISTDEF_3}
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></small></td>
<td id="footer"><small><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></small></td>
</tr>
</table>

View File

@@ -70,7 +70,7 @@ ${do:if-file-exists:html/index.html}
<td>
<a href="/step9_opt5.html" target="_blank"
onClick="window.open('/step9_opt5.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPHELP}' onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info('&nbsp;'); return true"
>${LANG_TIPHELP}</a>
</td>
${do:end-if}
@@ -107,12 +107,12 @@ ${LANG_Q3}
${do:output-mode:html-urlescaped}
onClick="if (confirm(str_replace(str_replace('${LANG_DIAL7}', '%20', ' '), '%0a', ' '))) { form.closeme.value=1; form.submit(); } return false;"
${do:output-mode:}
onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPOK}' onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td><td align="right">
<input type="button" value="${LANG_CANCEL}"
onClick="window.close();"
onMouseOver="info('${html:LANG_TIPCANCEL}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPCANCEL}' onMouseOver="info('${html:LANG_TIPCANCEL}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td></tr>
</table>
@@ -140,7 +140,7 @@ ${do:output-mode:}
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></small></td>
<td id="footer"><small><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></small></td>
</tr>
</table>

View File

@@ -60,7 +60,7 @@ ${do:if-file-exists:html/index.html}
<td>
<a href="/step9_opt10.html" target="_blank"
onClick="window.open('/step9_opt10.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPHELP}' onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info('&nbsp;'); return true"
>${LANG_TIPHELP}</a>
</td>
${do:end-if}
@@ -71,18 +71,18 @@ ${do:end-if}
<table class="tableWidth" border="0" width="100%" cellspacing="0">
<tr>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option1.html" onClick="form.redirect.value='option1.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT1}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT1}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option2.html" onClick="form.redirect.value='option2.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT2}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT2}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option3.html" onClick="form.redirect.value='option3.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT3}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT3}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option4.html" onClick="form.redirect.value='option4.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT4}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT4}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option5.html" onClick="form.redirect.value='option5.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT5}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT5}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option11.html" onClick="form.redirect.value='option11.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT11}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT11}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option1.html" onClick="form.redirect.value='option1.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT1}' onMouseOver="info('${html:LANG_IOPT1}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT1}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option2.html" onClick="form.redirect.value='option2.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT2}' onMouseOver="info('${html:LANG_IOPT2}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT2}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option3.html" onClick="form.redirect.value='option3.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT3}' onMouseOver="info('${html:LANG_IOPT3}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT3}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option4.html" onClick="form.redirect.value='option4.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT4}' onMouseOver="info('${html:LANG_IOPT4}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT4}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option5.html" onClick="form.redirect.value='option5.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT5}' onMouseOver="info('${html:LANG_IOPT5}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT5}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option11.html" onClick="form.redirect.value='option11.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT11}' onMouseOver="info('${html:LANG_IOPT11}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT11}</a></td>
</tr><tr>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option6.html" onClick="form.redirect.value='option6.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT6}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT6}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option7.html" onClick="form.redirect.value='option7.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT7}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT7}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option8.html" onClick="form.redirect.value='option8.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT8}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT8}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option9.html" onClick="form.redirect.value='option9.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT9}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT9}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option10.html" onClick="form.redirect.value='option10.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT10}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT10}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option6.html" onClick="form.redirect.value='option6.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT6}' onMouseOver="info('${html:LANG_IOPT6}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT6}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option7.html" onClick="form.redirect.value='option7.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT7}' onMouseOver="info('${html:LANG_IOPT7}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT7}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option8.html" onClick="form.redirect.value='option8.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT8}' onMouseOver="info('${html:LANG_IOPT8}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT8}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option9.html" onClick="form.redirect.value='option9.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT9}' onMouseOver="info('${html:LANG_IOPT9}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT9}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option10.html" onClick="form.redirect.value='option10.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT10}' onMouseOver="info('${html:LANG_IOPT10}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT10}</a></td>
<td class="tabCtrl" align="center">&nbsp;</td>
</tr>
@@ -104,7 +104,7 @@ ${LANG_I40c}
<!-- checkboxes -->
<table border="0" width="100%" cellspacing="0">
<tr><td><input type="checkbox" name="cache" ${checked:cache}
onMouseOver="info('${html:LANG_I5}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_I5}' onMouseOver="info('${html:LANG_I5}'); return true" onMouseOut="info('&nbsp;'); return true"
> ${LANG_I34}</td></tr>
</table>
<br>
@@ -112,7 +112,7 @@ ${LANG_I40c}
${LANG_I39}
<br>
<select name="filter"
onMouseOver="info('${html:LANG_I29}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_I29}' onMouseOver="info('${html:LANG_I29}'); return true" onMouseOut="info('&nbsp;'); return true"
>
${listid:filter:LISTDEF_4}
</select>
@@ -121,7 +121,7 @@ ${listid:filter:LISTDEF_4}
${LANG_I40}
<br>
<select name="travel"
onMouseOver="info('${html:LANG_I11}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_I11}' onMouseOver="info('${html:LANG_I11}'); return true" onMouseOut="info('&nbsp;'); return true"
>
${listid:travel:LISTDEF_5}
</select>
@@ -130,7 +130,7 @@ ${listid:travel:LISTDEF_5}
${LANG_I40b}
<br>
<select name="travel2"
onMouseOver="info('${html:LANG_I11b}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_I11b}' onMouseOver="info('${html:LANG_I11b}'); return true" onMouseOut="info('&nbsp;'); return true"
>
${listid:travel2:LISTDEF_6}
</select>
@@ -139,7 +139,7 @@ ${listid:travel2:LISTDEF_6}
${LANG_I40e}
<br>
<select name="travel3"
onMouseOver="info('${html:LANG_I11c}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_I11c}' onMouseOver="info('${html:LANG_I11c}'); return true" onMouseOut="info('&nbsp;'); return true"
>
${listid:travel3:LISTDEF_11}
</select>
@@ -148,7 +148,7 @@ ${listid:travel3:LISTDEF_11}
<!-- checkboxes -->
<table border="0" width="100%" cellspacing="0">
<tr><td><input type="checkbox" name="windebug" ${checked:windebug}
onMouseOver="info('${html:LANG_I1h}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_I1h}' onMouseOver="info('${html:LANG_I1h}'); return true" onMouseOut="info('&nbsp;'); return true"
> ${LANG_I40d}</td></tr>
</table>
<br>
@@ -158,12 +158,12 @@ ${listid:travel3:LISTDEF_11}
<tr><td align="left">
<input type="submit" value="${LANG_OK}"
onClick="form.closeme.value=1; form.submit(); return false;"
onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPOK}' onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td><td align="right">
<input type="button" value="${LANG_CANCEL}"
onClick="window.close();"
onMouseOver="info('${html:LANG_TIPCANCEL}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPCANCEL}' onMouseOver="info('${html:LANG_TIPCANCEL}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td></tr>
</table>
@@ -191,7 +191,7 @@ ${listid:travel3:LISTDEF_11}
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></small></td>
<td id="footer"><small><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></small></td>
</tr>
</table>

View File

@@ -60,7 +60,7 @@ ${do:if-file-exists:html/index.html}
<td>
<a href="/step9_opt3.html" target="_blank"
onClick="window.open('/step9_opt3.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPHELP}' onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info('&nbsp;'); return true"
>${LANG_TIPHELP}</a>
</td>
${do:end-if}
@@ -71,18 +71,18 @@ ${do:end-if}
<table class="tableWidth" border="0" width="100%" cellspacing="0">
<tr>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option1.html" onClick="form.redirect.value='option1.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT1}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT1}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option2.html" onClick="form.redirect.value='option2.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT2}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT2}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option3.html" onClick="form.redirect.value='option3.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT3}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT3}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option4.html" onClick="form.redirect.value='option4.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT4}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT4}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option5.html" onClick="form.redirect.value='option5.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT5}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT5}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option11.html" onClick="form.redirect.value='option11.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT11}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT11}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option1.html" onClick="form.redirect.value='option1.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT1}' onMouseOver="info('${html:LANG_IOPT1}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT1}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option2.html" onClick="form.redirect.value='option2.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT2}' onMouseOver="info('${html:LANG_IOPT2}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT2}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option3.html" onClick="form.redirect.value='option3.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT3}' onMouseOver="info('${html:LANG_IOPT3}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT3}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option4.html" onClick="form.redirect.value='option4.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT4}' onMouseOver="info('${html:LANG_IOPT4}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT4}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option5.html" onClick="form.redirect.value='option5.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT5}' onMouseOver="info('${html:LANG_IOPT5}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT5}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option11.html" onClick="form.redirect.value='option11.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT11}' onMouseOver="info('${html:LANG_IOPT11}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT11}</a></td>
</tr><tr>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option6.html" onClick="form.redirect.value='option6.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT6}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT6}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option7.html" onClick="form.redirect.value='option7.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT7}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT7}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option8.html" onClick="form.redirect.value='option8.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT8}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT8}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option9.html" onClick="form.redirect.value='option9.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT9}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT9}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option10.html" onClick="form.redirect.value='option10.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT10}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT10}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option6.html" onClick="form.redirect.value='option6.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT6}' onMouseOver="info('${html:LANG_IOPT6}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT6}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option7.html" onClick="form.redirect.value='option7.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT7}' onMouseOver="info('${html:LANG_IOPT7}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT7}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option8.html" onClick="form.redirect.value='option8.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT8}' onMouseOver="info('${html:LANG_IOPT8}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT8}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option9.html" onClick="form.redirect.value='option9.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT9}' onMouseOver="info('${html:LANG_IOPT9}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT9}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option10.html" onClick="form.redirect.value='option10.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT10}' onMouseOver="info('${html:LANG_IOPT10}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT10}</a></td>
<td class="tabCtrl" align="center">&nbsp;</td>
</tr>
@@ -104,11 +104,11 @@ ${do:end-if}
${LANG_I44}
</td><td>
<input name="connexion" value="${connexion}" size="4"
onMouseOver="info('${html:LANG_I12}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_I12}' onMouseOver="info('${html:LANG_I12}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td></tr><tr><td></td><td>
<input type="checkbox" name="ka" ${checked:ka}
onMouseOver="info('${html:LANG_I47f}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_I47f}' onMouseOver="info('${html:LANG_I47f}'); return true" onMouseOut="info('&nbsp;'); return true"
> ${LANG_I47e}
</td></tr>
@@ -116,11 +116,11 @@ ${LANG_I44}
${LANG_I47d}
</td><td>
<input name="timeout" value="${timeout}" size="4"
onMouseOver="info('${html:LANG_I13}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_I13}' onMouseOver="info('${html:LANG_I13}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td></tr><tr><td></td><td>
<input type="checkbox" name="remt" ${checked:remt}
onMouseOver="info('${html:LANG_I14}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_I14}' onMouseOver="info('${html:LANG_I14}'); return true" onMouseOut="info('&nbsp;'); return true"
> ${LANG_I45}
</td></tr>
@@ -128,7 +128,7 @@ ${LANG_I47d}
${LANG_I48}
</td><td>
<input name="retry" value="${retry}" size="4"
onMouseOver="info('${html:LANG_I17}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_I17}' onMouseOver="info('${html:LANG_I17}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td></tr>
@@ -136,11 +136,11 @@ ${LANG_I48}
${LANG_I46}
</td><td>
<input name="rate" value="${rate}" size="4"
onMouseOver="info('${html:LANG_I15}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_I15}' onMouseOver="info('${html:LANG_I15}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td></tr><tr><td></td><td>
<input type="checkbox" name="rems" ${checked:rems}
onMouseOver="info('${html:LANG_I16}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_I16}' onMouseOver="info('${html:LANG_I16}'); return true" onMouseOut="info('&nbsp;'); return true"
> ${LANG_I47}
</td></tr>
@@ -151,12 +151,12 @@ ${LANG_I46}
<tr><td align="left">
<input type="submit" value="${LANG_OK}"
onClick="form.closeme.value=1; form.submit(); return false;"
onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPOK}' onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td><td align="right">
<input type="button" value="${LANG_CANCEL}"
onClick="window.close();"
onMouseOver="info('${html:LANG_TIPCANCEL}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPCANCEL}' onMouseOver="info('${html:LANG_TIPCANCEL}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td></tr>
</table>
@@ -184,7 +184,7 @@ ${LANG_I46}
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></small></td>
<td id="footer"><small><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></small></td>
</tr>
</table>

View File

@@ -60,7 +60,7 @@ ${do:if-file-exists:html/index.html}
<td>
<a href="/step9_opt2.html" target="_blank"
onClick="window.open('/step9_opt2.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPHELP}' onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info('&nbsp;'); return true"
>${LANG_TIPHELP}</a>
</td>
${do:end-if}
@@ -71,18 +71,18 @@ ${do:end-if}
<table class="tableWidth" border="0" width="100%" cellspacing="0">
<tr>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option1.html" onClick="form.redirect.value='option1.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT1}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT1}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option2.html" onClick="form.redirect.value='option2.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT2}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT2}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option3.html" onClick="form.redirect.value='option3.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT3}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT3}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option4.html" onClick="form.redirect.value='option4.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT4}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT4}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option5.html" onClick="form.redirect.value='option5.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT5}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT5}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option11.html" onClick="form.redirect.value='option11.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT11}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT11}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option1.html" onClick="form.redirect.value='option1.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT1}' onMouseOver="info('${html:LANG_IOPT1}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT1}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option2.html" onClick="form.redirect.value='option2.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT2}' onMouseOver="info('${html:LANG_IOPT2}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT2}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option3.html" onClick="form.redirect.value='option3.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT3}' onMouseOver="info('${html:LANG_IOPT3}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT3}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option4.html" onClick="form.redirect.value='option4.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT4}' onMouseOver="info('${html:LANG_IOPT4}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT4}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option5.html" onClick="form.redirect.value='option5.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT5}' onMouseOver="info('${html:LANG_IOPT5}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT5}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option11.html" onClick="form.redirect.value='option11.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT11}' onMouseOver="info('${html:LANG_IOPT11}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT11}</a></td>
</tr><tr>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option6.html" onClick="form.redirect.value='option6.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT6}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT6}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option7.html" onClick="form.redirect.value='option7.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT7}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT7}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option8.html" onClick="form.redirect.value='option8.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT8}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT8}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option9.html" onClick="form.redirect.value='option9.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT9}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT9}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option10.html" onClick="form.redirect.value='option10.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT10}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT10}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option6.html" onClick="form.redirect.value='option6.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT6}' onMouseOver="info('${html:LANG_IOPT6}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT6}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option7.html" onClick="form.redirect.value='option7.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT7}' onMouseOver="info('${html:LANG_IOPT7}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT7}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option8.html" onClick="form.redirect.value='option8.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT8}' onMouseOver="info('${html:LANG_IOPT8}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT8}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option9.html" onClick="form.redirect.value='option9.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT9}' onMouseOver="info('${html:LANG_IOPT9}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT9}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option10.html" onClick="form.redirect.value='option10.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT10}' onMouseOver="info('${html:LANG_IOPT10}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT10}</a></td>
<td class="tabCtrl" align="center">&nbsp;</td>
</tr>
@@ -104,7 +104,7 @@ ${do:end-if}
${LANG_G32}
</td><td>
<input name="depth" value="${depth}" size="4"
onMouseOver="info('${html:LANG_I1g}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_I1g}' onMouseOver="info('${html:LANG_I1g}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td></tr>
@@ -112,7 +112,7 @@ ${LANG_G32}
${LANG_G32b}
</td><td>
<input name="depth2" value="${depth2}" size="4"
onMouseOver="info('${html:LANG_I1g2}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_I1g2}' onMouseOver="info('${html:LANG_I1g2}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td></tr>
@@ -120,7 +120,7 @@ ${LANG_G32b}
${LANG_I50}
</td><td>
<input name="maxhtml" value="${maxhtml}" size="4"
onMouseOver="info('${html:LANG_I18}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_I18}' onMouseOver="info('${html:LANG_I18}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td></tr>
@@ -128,7 +128,7 @@ ${LANG_I50}
${LANG_I50b}
</td><td>
<input name="othermax" value="${othermax}" size="4"
onMouseOver="info('${html:LANG_I19}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_I19}' onMouseOver="info('${html:LANG_I19}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td></tr>
@@ -136,7 +136,7 @@ ${LANG_I50b}
${LANG_I51}
</td><td>
<input name="sizemax" value="${sizemax}" size="4"
onMouseOver="info('${html:LANG_I20}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_I20}' onMouseOver="info('${html:LANG_I20}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td></tr>
@@ -144,7 +144,15 @@ ${LANG_I51}
${LANG_I65}
</td><td>
<input name="pausebytes" value="${pausebytes}" size="4"
onMouseOver="info('${html:LANG_I20b}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_I20b}' onMouseOver="info('${html:LANG_I20b}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td></tr>
<tr><td>
${LANG_PAUSEFILES}
</td><td>
<input name="pausefiles" value="${pausefiles}" size="8"
title='${html:LANG_PAUSEFILESTIP}' onMouseOver="info('${html:LANG_PAUSEFILESTIP}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td></tr>
@@ -152,7 +160,7 @@ ${LANG_I65}
${LANG_I52}
</td><td>
<input name="maxtime" value="${maxtime}" size="4"
onMouseOver="info('${html:LANG_I21}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_I21}' onMouseOver="info('${html:LANG_I21}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td></tr>
@@ -160,7 +168,7 @@ ${LANG_I52}
${LANG_I54}
</td><td>
<input name="maxrate" value="${maxrate}" size="4"
onMouseOver="info('${html:LANG_I22}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_I22}' onMouseOver="info('${html:LANG_I22}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td></tr>
@@ -168,7 +176,7 @@ ${LANG_I54}
${LANG_I64}
</td><td>
<input name="maxconn" value="${maxconn}" size="4"
onMouseOver="info('${html:LANG_I22b}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_I22b}' onMouseOver="info('${html:LANG_I22b}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td></tr>
@@ -176,7 +184,7 @@ ${LANG_I64}
${LANG_I64b}
</td><td>
<input name="maxlinks" value="${maxlinks}" size="4"
onMouseOver="info('${html:LANG_I22c}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_I22c}' onMouseOver="info('${html:LANG_I22c}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td></tr>
@@ -185,12 +193,12 @@ ${LANG_I64b}
<tr><td align="left">
<input type="submit" value="${LANG_OK}"
onClick="form.closeme.value=1; form.submit(); return false;"
onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPOK}' onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td><td align="right">
<input type="button" value="${LANG_CANCEL}"
onClick="window.close();"
onMouseOver="info('${html:LANG_TIPCANCEL}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPCANCEL}' onMouseOver="info('${html:LANG_TIPCANCEL}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td></tr>
</table>
@@ -220,7 +228,7 @@ ${LANG_I64b}
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></small></td>
<td id="footer"><small><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></small></td>
</tr>
</table>

View File

@@ -60,7 +60,7 @@ ${do:if-file-exists:html/index.html}
<td>
<a href="/step9_opt8.html" target="_blank"
onClick="window.open('/step9_opt8.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPHELP}' onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info('&nbsp;'); return true"
>${LANG_TIPHELP}</a>
</td>
${do:end-if}
@@ -71,18 +71,18 @@ ${do:end-if}
<table class="tableWidth" border="0" width="100%" cellspacing="0">
<tr>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option1.html" onClick="form.redirect.value='option1.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT1}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT1}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option2.html" onClick="form.redirect.value='option2.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT2}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT2}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option3.html" onClick="form.redirect.value='option3.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT3}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT3}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option4.html" onClick="form.redirect.value='option4.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT4}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT4}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option5.html" onClick="form.redirect.value='option5.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT5}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT5}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option11.html" onClick="form.redirect.value='option11.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT11}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT11}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option1.html" onClick="form.redirect.value='option1.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT1}' onMouseOver="info('${html:LANG_IOPT1}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT1}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option2.html" onClick="form.redirect.value='option2.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT2}' onMouseOver="info('${html:LANG_IOPT2}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT2}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option3.html" onClick="form.redirect.value='option3.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT3}' onMouseOver="info('${html:LANG_IOPT3}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT3}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option4.html" onClick="form.redirect.value='option4.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT4}' onMouseOver="info('${html:LANG_IOPT4}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT4}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option5.html" onClick="form.redirect.value='option5.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT5}' onMouseOver="info('${html:LANG_IOPT5}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT5}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option11.html" onClick="form.redirect.value='option11.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT11}' onMouseOver="info('${html:LANG_IOPT11}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT11}</a></td>
</tr><tr>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option6.html" onClick="form.redirect.value='option6.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT6}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT6}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option7.html" onClick="form.redirect.value='option7.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT7}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT7}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option8.html" onClick="form.redirect.value='option8.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT8}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT8}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option9.html" onClick="form.redirect.value='option9.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT9}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT9}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option10.html" onClick="form.redirect.value='option10.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT10}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT10}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option6.html" onClick="form.redirect.value='option6.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT6}' onMouseOver="info('${html:LANG_IOPT6}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT6}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option7.html" onClick="form.redirect.value='option7.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT7}' onMouseOver="info('${html:LANG_IOPT7}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT7}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option8.html" onClick="form.redirect.value='option8.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT8}' onMouseOver="info('${html:LANG_IOPT8}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT8}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option9.html" onClick="form.redirect.value='option9.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT9}' onMouseOver="info('${html:LANG_IOPT9}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT9}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option10.html" onClick="form.redirect.value='option10.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT10}' onMouseOver="info('${html:LANG_IOPT10}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT10}</a></td>
<td class="tabCtrl" align="center">&nbsp;</td>
</tr>
@@ -104,7 +104,7 @@ ${do:end-if}
${LANG_I43}
</td><td>
<input name="user" value="${user}" size="60"
onMouseOver="info('${html:LANG_I23}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_I23}' onMouseOver="info('${html:LANG_I23}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td></tr>
@@ -112,7 +112,7 @@ ${LANG_I43}
${LANG_I43b}
</td><td>
<input name="footer" value="${footer}" size="60"
onMouseOver="info('${html:LANG_I23b}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_I23b}' onMouseOver="info('${html:LANG_I23b}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td></tr>
@@ -123,12 +123,12 @@ ${LANG_I43b}
<tr><td align="left">
<input type="submit" value="${LANG_OK}"
onClick="form.closeme.value=1; form.submit(); return false;"
onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPOK}' onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td><td align="right">
<input type="button" value="${LANG_CANCEL}"
onClick="window.close();"
onMouseOver="info('${html:LANG_TIPCANCEL}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPCANCEL}' onMouseOver="info('${html:LANG_TIPCANCEL}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td></tr>
</table>
@@ -156,7 +156,7 @@ ${LANG_I43b}
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></small></td>
<td id="footer"><small><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></small></td>
</tr>
</table>

View File

@@ -60,7 +60,7 @@ ${do:if-file-exists:html/index.html}
<td>
<a href="/step9_opt4.html" target="_blank"
onClick="window.open('/step9_opt4.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPHELP}' onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info('&nbsp;'); return true"
>${LANG_TIPHELP}</a>
</td>
${do:end-if}
@@ -71,18 +71,18 @@ ${do:end-if}
<table class="tableWidth" border="0" width="100%" cellspacing="0">
<tr>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option1.html" onClick="form.redirect.value='option1.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT1}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT1}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option2.html" onClick="form.redirect.value='option2.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT2}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT2}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option3.html" onClick="form.redirect.value='option3.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT3}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT3}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option4.html" onClick="form.redirect.value='option4.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT4}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT4}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option5.html" onClick="form.redirect.value='option5.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT5}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT5}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option11.html" onClick="form.redirect.value='option11.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT11}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT11}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option1.html" onClick="form.redirect.value='option1.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT1}' onMouseOver="info('${html:LANG_IOPT1}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT1}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option2.html" onClick="form.redirect.value='option2.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT2}' onMouseOver="info('${html:LANG_IOPT2}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT2}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option3.html" onClick="form.redirect.value='option3.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT3}' onMouseOver="info('${html:LANG_IOPT3}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT3}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option4.html" onClick="form.redirect.value='option4.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT4}' onMouseOver="info('${html:LANG_IOPT4}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT4}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option5.html" onClick="form.redirect.value='option5.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT5}' onMouseOver="info('${html:LANG_IOPT5}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT5}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option11.html" onClick="form.redirect.value='option11.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT11}' onMouseOver="info('${html:LANG_IOPT11}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT11}</a></td>
</tr><tr>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option6.html" onClick="form.redirect.value='option6.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT6}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT6}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option7.html" onClick="form.redirect.value='option7.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT7}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT7}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option8.html" onClick="form.redirect.value='option8.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT8}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT8}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option9.html" onClick="form.redirect.value='option9.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT9}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT9}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option10.html" onClick="form.redirect.value='option10.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT10}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT10}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option6.html" onClick="form.redirect.value='option6.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT6}' onMouseOver="info('${html:LANG_IOPT6}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT6}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option7.html" onClick="form.redirect.value='option7.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT7}' onMouseOver="info('${html:LANG_IOPT7}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT7}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option8.html" onClick="form.redirect.value='option8.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT8}' onMouseOver="info('${html:LANG_IOPT8}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT8}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option9.html" onClick="form.redirect.value='option9.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT9}' onMouseOver="info('${html:LANG_IOPT9}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT9}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option10.html" onClick="form.redirect.value='option10.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT10}' onMouseOver="info('${html:LANG_IOPT10}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT10}</a></td>
<td class="tabCtrl" align="center">&nbsp;</td>
</tr>
@@ -102,7 +102,7 @@ ${do:end-if}
${LANG_B10}
</tt>
<textarea name="url2" cols="60" rows="8"
onMouseOver="info('${html:LANG_C3}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_C3}' onMouseOver="info('${html:LANG_C3}'); return true" onMouseOut="info('&nbsp;'); return true"
>${url2}</textarea>
<br>
@@ -115,12 +115,12 @@ ${LANG_B13}
<tr><td align="left">
<input type="submit" value="${LANG_OK}"
onClick="form.closeme.value=1; form.submit(); return false;"
onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPOK}' onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td><td align="right">
<input type="button" value="${LANG_CANCEL}"
onClick="window.close();"
onMouseOver="info('${html:LANG_TIPCANCEL}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPCANCEL}' onMouseOver="info('${html:LANG_TIPCANCEL}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td></tr>
</table>
@@ -148,7 +148,7 @@ ${LANG_B13}
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></small></td>
<td id="footer"><small><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></small></td>
</tr>
</table>

View File

@@ -60,7 +60,7 @@ ${do:if-file-exists:html/index.html}
<td>
<a href="/step9_opt6.html" target="_blank"
onClick="window.open('/step9_opt6.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPHELP}' onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info('&nbsp;'); return true"
>${LANG_TIPHELP}</a>
</td>
${do:end-if}
@@ -71,18 +71,18 @@ ${do:end-if}
<table class="tableWidth" border="0" width="100%" cellspacing="0">
<tr>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option1.html" onClick="form.redirect.value='option1.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT1}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT1}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option2.html" onClick="form.redirect.value='option2.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT2}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT2}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option3.html" onClick="form.redirect.value='option3.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT3}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT3}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option4.html" onClick="form.redirect.value='option4.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT4}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT4}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option5.html" onClick="form.redirect.value='option5.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT5}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT5}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option11.html" onClick="form.redirect.value='option11.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT11}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT11}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option1.html" onClick="form.redirect.value='option1.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT1}' onMouseOver="info('${html:LANG_IOPT1}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT1}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option2.html" onClick="form.redirect.value='option2.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT2}' onMouseOver="info('${html:LANG_IOPT2}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT2}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option3.html" onClick="form.redirect.value='option3.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT3}' onMouseOver="info('${html:LANG_IOPT3}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT3}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option4.html" onClick="form.redirect.value='option4.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT4}' onMouseOver="info('${html:LANG_IOPT4}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT4}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option5.html" onClick="form.redirect.value='option5.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT5}' onMouseOver="info('${html:LANG_IOPT5}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT5}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option11.html" onClick="form.redirect.value='option11.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT11}' onMouseOver="info('${html:LANG_IOPT11}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT11}</a></td>
</tr><tr>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option6.html" onClick="form.redirect.value='option6.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT6}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT6}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option7.html" onClick="form.redirect.value='option7.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT7}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT7}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option8.html" onClick="form.redirect.value='option8.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT8}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT8}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option9.html" onClick="form.redirect.value='option9.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT9}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT9}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option10.html" onClick="form.redirect.value='option10.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT10}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT10}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option6.html" onClick="form.redirect.value='option6.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT6}' onMouseOver="info('${html:LANG_IOPT6}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT6}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option7.html" onClick="form.redirect.value='option7.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT7}' onMouseOver="info('${html:LANG_IOPT7}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT7}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option8.html" onClick="form.redirect.value='option8.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT8}' onMouseOver="info('${html:LANG_IOPT8}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT8}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option9.html" onClick="form.redirect.value='option9.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT9}' onMouseOver="info('${html:LANG_IOPT9}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT9}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option10.html" onClick="form.redirect.value='option10.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT10}' onMouseOver="info('${html:LANG_IOPT10}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT10}</a></td>
<td class="tabCtrl" align="center">&nbsp;</td>
</tr>
@@ -99,50 +99,77 @@ ${do:end-if}
<input type="hidden" name="closeme" value="">
<input type="checkbox" name="cookies" ${checked:cookies}
onMouseOver="info('${html:LANG_I1b}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_I1b}' onMouseOver="info('${html:LANG_I1b}'); return true" onMouseOut="info('&nbsp;'); return true"
> ${LANG_I58}
<br><br>
${LANG_COOKIEFILE}
<input name="cookiesfile" value="${cookiesfile}" size="40"
title='${html:LANG_COOKIEFILETIP}' onMouseOver="info('${html:LANG_COOKIEFILETIP}'); return true" onMouseOut="info('&nbsp;'); return true"
>
<br><br>
${LANG_I59}
<br>
<select name="checktype"
onMouseOver="info('${html:LANG_I1c}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_I1c}' onMouseOver="info('${html:LANG_I1c}'); return true" onMouseOut="info('&nbsp;'); return true"
>
${listid:checktype:LISTDEF_7}
</select>
<br><br>
<input type="checkbox" name="parsejava" ${checked:parsejava}
onMouseOver="info('${html:LANG_I1d}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_I1d}' onMouseOver="info('${html:LANG_I1d}'); return true" onMouseOut="info('&nbsp;'); return true"
> ${LANG_I60}
<br><br>
${LANG_I55}
<br>
<select name="robots"
onMouseOver="info('${html:LANG_I28}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_I28}' onMouseOver="info('${html:LANG_I28}'); return true" onMouseOut="info('&nbsp;'); return true"
>
${listid:robots:LISTDEF_8}
</select>
<br><br>
<input type="checkbox" name="updhack" ${checked:updhack}
onMouseOver="info('${html:LANG_I1k}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_I1k}' onMouseOver="info('${html:LANG_I1k}'); return true" onMouseOut="info('&nbsp;'); return true"
> ${LANG_I62b}
<br><br>
<input type="checkbox" name="urlhack" ${checked:urlhack}
onMouseOver="info('${html:LANG_I1k2}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_I1k2}' onMouseOver="info('${html:LANG_I1k2}'); return true" onMouseOut="info('&nbsp;'); return true"
> ${LANG_I62b2}
<br><br>
<input type="checkbox" name="keepwww" ${checked:keepwww}
title='${html:LANG_KEEPWWWTIP}' onMouseOver="info('${html:LANG_KEEPWWWTIP}'); return true" onMouseOut="info('&nbsp;'); return true"
> ${LANG_KEEPWWW}
<br><br>
<input type="checkbox" name="keepslashes" ${checked:keepslashes}
title='${html:LANG_KEEPSLASHESTIP}' onMouseOver="info('${html:LANG_KEEPSLASHESTIP}'); return true" onMouseOut="info('&nbsp;'); return true"
> ${LANG_KEEPSLASHES}
<br><br>
<input type="checkbox" name="keepqueryorder" ${checked:keepqueryorder}
title='${html:LANG_KEEPQUERYORDERTIP}' onMouseOver="info('${html:LANG_KEEPQUERYORDERTIP}'); return true" onMouseOut="info('&nbsp;'); return true"
> ${LANG_KEEPQUERYORDER}
<br><br>
${LANG_STRIPQUERY}
<input name="stripquery" value="${stripquery}" size="40"
title='${html:LANG_STRIPQUERYTIP}' onMouseOver="info('${html:LANG_STRIPQUERYTIP}'); return true" onMouseOut="info('&nbsp;'); return true"
>
<br><br>
<input type="checkbox" name="toler" ${checked:toler}
onMouseOver="info('${html:LANG_I1i}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_I1i}' onMouseOver="info('${html:LANG_I1i}'); return true" onMouseOut="info('&nbsp;'); return true"
> ${LANG_I62}
<br><br>
<input type="checkbox" name="http10" ${checked:http10}
onMouseOver="info('${html:LANG_I1j}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_I1j}' onMouseOver="info('${html:LANG_I1j}'); return true" onMouseOut="info('&nbsp;'); return true"
> ${LANG_I63}
<br><br>
@@ -152,12 +179,12 @@ ${listid:robots:LISTDEF_8}
<tr><td align="left">
<input type="submit" value="${LANG_OK}"
onClick="form.closeme.value=1; form.submit(); return false;"
onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPOK}' onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td><td align="right">
<input type="button" value="${LANG_CANCEL}"
onClick="window.close();"
onMouseOver="info('${html:LANG_TIPCANCEL}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPCANCEL}' onMouseOver="info('${html:LANG_TIPCANCEL}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td></tr>
</table>
@@ -185,7 +212,7 @@ ${listid:robots:LISTDEF_8}
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></small></td>
<td id="footer"><small><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></small></td>
</tr>
</table>

View File

@@ -60,7 +60,7 @@ ${do:if-file-exists:html/index.html}
<td>
<a href="/step9_opt9.html" target="_blank"
onClick="window.open('/step9_opt9.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPHELP}' onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info('&nbsp;'); return true"
>${LANG_TIPHELP}</a>
</td>
${do:end-if}
@@ -71,18 +71,18 @@ ${do:end-if}
<table class="tableWidth" border="0" width="100%" cellspacing="0">
<tr>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option1.html" onClick="form.redirect.value='option1.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT1}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT1}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option2.html" onClick="form.redirect.value='option2.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT2}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT2}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option3.html" onClick="form.redirect.value='option3.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT3}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT3}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option4.html" onClick="form.redirect.value='option4.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT4}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT4}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option5.html" onClick="form.redirect.value='option5.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT5}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT5}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option11.html" onClick="form.redirect.value='option11.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT11}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT11}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option1.html" onClick="form.redirect.value='option1.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT1}' onMouseOver="info('${html:LANG_IOPT1}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT1}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option2.html" onClick="form.redirect.value='option2.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT2}' onMouseOver="info('${html:LANG_IOPT2}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT2}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option3.html" onClick="form.redirect.value='option3.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT3}' onMouseOver="info('${html:LANG_IOPT3}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT3}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option4.html" onClick="form.redirect.value='option4.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT4}' onMouseOver="info('${html:LANG_IOPT4}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT4}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option5.html" onClick="form.redirect.value='option5.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT5}' onMouseOver="info('${html:LANG_IOPT5}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT5}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option11.html" onClick="form.redirect.value='option11.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT11}' onMouseOver="info('${html:LANG_IOPT11}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT11}</a></td>
</tr><tr>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option6.html" onClick="form.redirect.value='option6.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT6}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT6}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option7.html" onClick="form.redirect.value='option7.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT7}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT7}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option8.html" onClick="form.redirect.value='option8.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT8}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT8}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option9.html" onClick="form.redirect.value='option9.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT9}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT9}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option10.html" onClick="form.redirect.value='option10.html'; form.submit(); return false;" align="center" onMouseOver="info('${html:LANG_IOPT10}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT10}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option6.html" onClick="form.redirect.value='option6.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT6}' onMouseOver="info('${html:LANG_IOPT6}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT6}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option7.html" onClick="form.redirect.value='option7.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT7}' onMouseOver="info('${html:LANG_IOPT7}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT7}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option8.html" onClick="form.redirect.value='option8.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT8}' onMouseOver="info('${html:LANG_IOPT8}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT8}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option9.html" onClick="form.redirect.value='option9.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT9}' onMouseOver="info('${html:LANG_IOPT9}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT9}</a></td>
<td class="tabCtrl" align="center"><a style="background:black;color: white" href="option10.html" onClick="form.redirect.value='option10.html'; form.submit(); return false;" align="center" title='${html:LANG_IOPT10}' onMouseOver="info('${html:LANG_IOPT10}'); return true" onMouseOut="info('&nbsp;'); return true">${LANG_IOPT10}</a></td>
<td class="tabCtrl" align="center">&nbsp;</td>
</tr>
@@ -99,32 +99,32 @@ ${do:end-if}
<input type="hidden" name="closeme" value="">
<input type="checkbox" name="cache2" ${checked:cache2}
onMouseOver="info('${html:LANG_I1e}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_I1e}' onMouseOver="info('${html:LANG_I1e}'); return true" onMouseOut="info('&nbsp;'); return true"
> ${LANG_I61}
<br><br>
<input type="checkbox" name="norecatch" ${checked:norecatch}
onMouseOver="info('${html:LANG_I5b}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_I5b}' onMouseOver="info('${html:LANG_I5b}'); return true" onMouseOut="info('&nbsp;'); return true"
> ${LANG_I34b}
<br><br>
<input type="checkbox" name="logf" ${checked:logf}
onMouseOver="info('${html:LANG_I7}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_I7}' onMouseOver="info('${html:LANG_I7}'); return true" onMouseOut="info('&nbsp;'); return true"
> ${LANG_I36}
<select name="logtype"
onMouseOver="info('${html:LANG_I1f}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_I1f}' onMouseOver="info('${html:LANG_I1f}'); return true" onMouseOut="info('&nbsp;'); return true"
>
${listid:logtype:LISTDEF_9}
</select>
<br><br>
<input type="checkbox" name="index" ${checked:index}
onMouseOver="info('${html:LANG_I6}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_I6}' onMouseOver="info('${html:LANG_I6}'); return true" onMouseOut="info('&nbsp;'); return true"
> ${LANG_I35}
<br><br>
<input type="checkbox" name="index2" ${checked:index2}
onMouseOver="info('${html:LANG_I6b}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_I6b}' onMouseOver="info('${html:LANG_I6b}'); return true" onMouseOut="info('&nbsp;'); return true"
> ${LANG_I35b}
<br><br>
@@ -133,12 +133,12 @@ ${listid:logtype:LISTDEF_9}
<tr><td align="left">
<input type="submit" value="${LANG_OK}"
onClick="form.closeme.value=1; form.submit(); return false;"
onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPOK}' onMouseOver="info('${html:LANG_TIPOK}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td><td align="right">
<input type="button" value="${LANG_CANCEL}"
onClick="window.close();"
onMouseOver="info('${html:LANG_TIPCANCEL}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPCANCEL}' onMouseOver="info('${html:LANG_TIPCANCEL}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td></tr>
</table>
@@ -166,7 +166,7 @@ ${listid:logtype:LISTDEF_9}
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></small></td>
<td id="footer"><small><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></small></td>
</tr>
</table>

View File

@@ -73,7 +73,7 @@ function no_refresh() {
<td id="subTitle" align="right">
<a href="/server/file.html" target="_blank"
onClick="window.open('/server/file.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
onMouseOver="info('${html:LANG_O1}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_O1}' onMouseOver="info('${html:LANG_O1}'); return true" onMouseOut="info('&nbsp;'); return true"
style="color:#FFFFFF"
>
${LANG_O1}
@@ -85,7 +85,7 @@ ${do:if-file-exists:html/index.html}
<td id="subTitle" align="right">
<a href="/index.html" target="_blank"
onClick="window.open('/server/help.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPHELP}' onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info('&nbsp;'); return true"
style="color:#FFFFFF"
>
${LANG_O5}
@@ -152,20 +152,20 @@ ${LANG_H20} ${info.currentjob}
<table border="0" width="100%">
<tr><td>${info.state[0]}</td><td>${info.name[0]}</td><td>${info.file[0]}</td><td>${info.size[0]}/${info.sizetot[0]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[0]}'; form.submit()" onMouseOver="info('${html:LANG_H6}'); return true" onMouseOut="info('&nbsp;'); return true"></td></tr>
<tr><td>${info.state[1]}</td><td>${info.name[1]}</td><td>${info.file[1]}</td><td>${info.size[1]}/${info.sizetot[1]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[1]}'; form.submit()" onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info('&nbsp;'); return true"></td></tr>
<tr><td>${info.state[2]}</td><td>${info.name[2]}</td><td>${info.file[2]}</td><td>${info.size[2]}/${info.sizetot[2]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[2]}'; form.submit()" onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info('&nbsp;'); return true"></td></tr>
<tr><td>${info.state[3]}</td><td>${info.name[3]}</td><td>${info.file[3]}</td><td>${info.size[3]}/${info.sizetot[3]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[3]}'; form.submit()" onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info('&nbsp;'); return true"></td></tr>
<tr><td>${info.state[4]}</td><td>${info.name[4]}</td><td>${info.file[4]}</td><td>${info.size[4]}/${info.sizetot[4]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[4]}'; form.submit()" onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info('&nbsp;'); return true"></td></tr>
<tr><td>${info.state[5]}</td><td>${info.name[5]}</td><td>${info.file[5]}</td><td>${info.size[5]}/${info.sizetot[5]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[5]}'; form.submit()" onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info('&nbsp;'); return true"></td></tr>
<tr><td>${info.state[6]}</td><td>${info.name[6]}</td><td>${info.file[6]}</td><td>${info.size[6]}/${info.sizetot[6]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[6]}'; form.submit()" onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info('&nbsp;'); return true"></td></tr>
<tr><td>${info.state[7]}</td><td>${info.name[7]}</td><td>${info.file[7]}</td><td>${info.size[7]}/${info.sizetot[7]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[7]}'; form.submit()" onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info('&nbsp;'); return true"></td></tr>
<tr><td>${info.state[8]}</td><td>${info.name[8]}</td><td>${info.file[8]}</td><td>${info.size[8]}/${info.sizetot[8]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[8]}'; form.submit()" onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info('&nbsp;'); return true"></td></tr>
<tr><td>${info.state[9]}</td><td>${info.name[9]}</td><td>${info.file[9]}</td><td>${info.size[9]}/${info.sizetot[9]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[9]}'; form.submit()" onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info('&nbsp;'); return true"></td></tr>
<tr><td>${info.state[10]}</td><td>${info.name[10]}</td><td>${info.file[10]}</td><td>${info.size[10]}/${info.sizetot[10]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[10]}'; form.submit()" onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info('&nbsp;'); return true"></td></tr>
<tr><td>${info.state[11]}</td><td>${info.name[11]}</td><td>${info.file[11]}</td><td>${info.size[11]}/${info.sizetot[11]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[11]}'; form.submit()" onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info('&nbsp;'); return true"></td></tr>
<tr><td>${info.state[12]}</td><td>${info.name[12]}</td><td>${info.file[12]}</td><td>${info.size[12]}/${info.sizetot[12]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[12]}'; form.submit()" onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info('&nbsp;'); return true"></td></tr>
<tr><td>${info.state[13]}</td><td>${info.name[13]}</td><td>${info.file[13]}</td><td>${info.size[13]}/${info.sizetot[13]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[13]}'; form.submit()" onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info('&nbsp;'); return true"></td></tr>
<tr><td>${info.state[0]}</td><td>${info.name[0]}</td><td>${info.file[0]}</td><td>${info.size[0]}/${info.sizetot[0]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[0]}'; form.submit()" title='${html:LANG_H6}' onMouseOver="info('${html:LANG_H6}'); return true" onMouseOut="info('&nbsp;'); return true"></td></tr>
<tr><td>${info.state[1]}</td><td>${info.name[1]}</td><td>${info.file[1]}</td><td>${info.size[1]}/${info.sizetot[1]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[1]}'; form.submit()" title='${html:LANG_H7}' onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info('&nbsp;'); return true"></td></tr>
<tr><td>${info.state[2]}</td><td>${info.name[2]}</td><td>${info.file[2]}</td><td>${info.size[2]}/${info.sizetot[2]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[2]}'; form.submit()" title='${html:LANG_H7}' onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info('&nbsp;'); return true"></td></tr>
<tr><td>${info.state[3]}</td><td>${info.name[3]}</td><td>${info.file[3]}</td><td>${info.size[3]}/${info.sizetot[3]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[3]}'; form.submit()" title='${html:LANG_H7}' onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info('&nbsp;'); return true"></td></tr>
<tr><td>${info.state[4]}</td><td>${info.name[4]}</td><td>${info.file[4]}</td><td>${info.size[4]}/${info.sizetot[4]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[4]}'; form.submit()" title='${html:LANG_H7}' onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info('&nbsp;'); return true"></td></tr>
<tr><td>${info.state[5]}</td><td>${info.name[5]}</td><td>${info.file[5]}</td><td>${info.size[5]}/${info.sizetot[5]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[5]}'; form.submit()" title='${html:LANG_H7}' onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info('&nbsp;'); return true"></td></tr>
<tr><td>${info.state[6]}</td><td>${info.name[6]}</td><td>${info.file[6]}</td><td>${info.size[6]}/${info.sizetot[6]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[6]}'; form.submit()" title='${html:LANG_H7}' onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info('&nbsp;'); return true"></td></tr>
<tr><td>${info.state[7]}</td><td>${info.name[7]}</td><td>${info.file[7]}</td><td>${info.size[7]}/${info.sizetot[7]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[7]}'; form.submit()" title='${html:LANG_H7}' onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info('&nbsp;'); return true"></td></tr>
<tr><td>${info.state[8]}</td><td>${info.name[8]}</td><td>${info.file[8]}</td><td>${info.size[8]}/${info.sizetot[8]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[8]}'; form.submit()" title='${html:LANG_H7}' onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info('&nbsp;'); return true"></td></tr>
<tr><td>${info.state[9]}</td><td>${info.name[9]}</td><td>${info.file[9]}</td><td>${info.size[9]}/${info.sizetot[9]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[9]}'; form.submit()" title='${html:LANG_H7}' onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info('&nbsp;'); return true"></td></tr>
<tr><td>${info.state[10]}</td><td>${info.name[10]}</td><td>${info.file[10]}</td><td>${info.size[10]}/${info.sizetot[10]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[10]}'; form.submit()" title='${html:LANG_H7}' onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info('&nbsp;'); return true"></td></tr>
<tr><td>${info.state[11]}</td><td>${info.name[11]}</td><td>${info.file[11]}</td><td>${info.size[11]}/${info.sizetot[11]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[11]}'; form.submit()" title='${html:LANG_H7}' onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info('&nbsp;'); return true"></td></tr>
<tr><td>${info.state[12]}</td><td>${info.name[12]}</td><td>${info.file[12]}</td><td>${info.size[12]}/${info.sizetot[12]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[12]}'; form.submit()" title='${html:LANG_H7}' onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info('&nbsp;'); return true"></td></tr>
<tr><td>${info.state[13]}</td><td>${info.name[13]}</td><td>${info.file[13]}</td><td>${info.size[13]}/${info.sizetot[13]}</td><td><input type="submit" value="${LANG_H15}" onClick="form.command.value='cancel-file=${info.url_sav[13]}'; form.submit()" title='${html:LANG_H7}' onMouseOver="info('${html:LANG_H7}'); return true" onMouseOut="info('&nbsp;'); return true"></td></tr>
</table>
@@ -180,7 +180,7 @@ ${LANG_H20} ${info.currentjob}
&nbsp;
</td><td align="right">
<input type="submit" value=" ${LANG_V4} "
onMouseOver="disable_timer(); info('${LANG_D3}'); return true"
title='${html:LANG_D3}' onMouseOver="disable_timer(); info('${LANG_D3}'); return true"
onMouseOut="info('&nbsp;'); enable_timer(); return true"
onClick="if (do_confirm('${LANG_G1}')) { form.command.value='cancel'; form.submit(); } return false"
>
@@ -204,7 +204,7 @@ ${LANG_H20} ${info.currentjob}
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></small></td>
<td id="footer"><small><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></small></td>
</tr>
</table>

View File

@@ -52,7 +52,7 @@ function info(str) {
<td id="subTitle" align="right">
<a href="/server/file.html" target="_blank"
onClick="window.open('/server/file.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
onMouseOver="info('${html:html:LANG_O1}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_O1}' onMouseOver="info('${html:html:LANG_O1}'); return true" onMouseOut="info('&nbsp;'); return true"
style="color:#FFFFFF"
>
${LANG_O1}
@@ -64,7 +64,7 @@ ${do:if-file-exists:html/index.html}
<td id="subTitle" align="right">
<a href="/index.html" target="_blank"
onClick="window.open('/server/help.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
onMouseOver="info('${html:html:LANG_TIPHELP}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPHELP}' onMouseOver="info('${html:html:LANG_TIPHELP}'); return true" onMouseOut="info('&nbsp;'); return true"
style="color:#FFFFFF"
>
${LANG_O5}
@@ -93,7 +93,7 @@ ${do:if-file-exists:html/index.html}
<td>
<a href="/step1.html" target="_blank"
onClick="window.open('/step1.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
onMouseOver="info('${html:html:LANG_TIPHELP}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPHELP}' onMouseOver="info('${html:html:LANG_TIPHELP}'); return true" onMouseOut="info('&nbsp;'); return true"
>${LANG_TIPHELP}</a>
</td>
${do:end-if}
@@ -129,15 +129,21 @@ ${do:copy:NoPwdInPages:hidepwd}
${do:copy:NoQueryStrings:hidequery}
${do:copy:NoPurgeOldFiles:nopurge}
${do:copy:Cookies:cookies}
${do:copy:CookiesFile:cookiesfile}
${do:copy:CheckType:checktype}
${do:copy:ParseJava:parsejava}
${do:copy:HTTP10:http10}
${do:copy:TolerantRequests:toler}
${do:copy:UpdateHack:updhack}
${do:copy:URLHack:urlhack}
${do:copy:KeepWww:keepwww}
${do:copy:KeepSlashes:keepslashes}
${do:copy:KeepQueryOrder:keepqueryorder}
${do:copy:StripQuery:stripquery}
${do:copy:StoreAllInCache:cache2}
${do:copy:LogType:logtype}
${do:copy:UseHTTPProxyForFTP:ftpprox}
${do:copy:ProxyType:proxytype}
${do:copy:Build:build}
${do:copy:PrimaryScan:filter}
${do:copy:Travel:travel}
@@ -148,6 +154,7 @@ ${do:copy:MaxHtml:maxhtml}
${do:copy:MaxOther:othermax}
${do:copy:MaxAll:sizemax}
${do:copy:MaxWait:pausebytes}
${do:copy:PauseFiles:pausefiles}
${do:copy:Sockets:connexion}
${do:copy:Retry:retry}
${do:copy:MaxTime:maxtime}
@@ -211,7 +218,7 @@ ${do:loadhash}
${LANG_S11}
<input name="projname" value="${projname}"
onMouseOver="info('${html:html:LANG_S1}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_S1}' onMouseOver="info('${html:html:LANG_S1}'); return true" onMouseOut="info('&nbsp;'); return true"
>
<br>
@@ -226,7 +233,7 @@ ${do:loadhash}
</select>
</td><td>
<input name="projcateg" value="${projcateg}"
onMouseOver="info('${html:html:LANG_S5}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_S5}' onMouseOver="info('${html:html:LANG_S5}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td></tr></table>
@@ -234,7 +241,7 @@ ${do:loadhash}
<br>
${LANG_S12}
<input name="path" value="${path}"
onMouseOver="info('${html:html:LANG_S2}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_S2}' onMouseOver="info('${html:html:LANG_S2}'); return true" onMouseOut="info('&nbsp;'); return true"
>
<input type="button" value="refresh" onClick="form.redirect.value='step2.html'; form.submit()">
@@ -243,11 +250,11 @@ ${do:loadhash}
<tr><td>
<table width="100%" border="0"><tr><td align="left">
<input type="submit" value=" << ${LANG_PREVIOUS} " onClick="form.redirect.value='index.html'; form.submit()"
onMouseOver="info('${html:html:LANG_TIPPREV}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPPREV}' onMouseOver="info('${html:html:LANG_TIPPREV}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td><td align="right">
<input name="nextBtn" type="submit" value=" ${LANG_NEXT} >> " onClick="return checkname();" default
onMouseOver="info('${html:html:LANG_TIPNEXT}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPNEXT}' onMouseOver="info('${html:html:LANG_TIPNEXT}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td></tr></table>
@@ -276,7 +283,7 @@ ${do:end-if:}
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></small></td>
<td id="footer"><small><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></small></td>
</tr>
</table>

View File

@@ -61,7 +61,7 @@ function do_check_child() {
<td id="subTitle" align="right">
<a href="/server/file.html" target="_blank"
onClick="window.open('/server/file.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
onMouseOver="info('${html:LANG_O1}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_O1}' onMouseOver="info('${html:LANG_O1}'); return true" onMouseOut="info('&nbsp;'); return true"
style="color:#FFFFFF"
>
${LANG_O1}
@@ -73,7 +73,7 @@ ${do:if-file-exists:html/index.html}
<td id="subTitle" align="right">
<a href="/index.html" target="_blank"
onClick="window.open('/server/help.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPHELP}' onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info('&nbsp;'); return true"
style="color:#FFFFFF"
>
${LANG_O5}
@@ -102,7 +102,7 @@ ${do:if-file-exists:html/index.html}
<td>
<a href="/step2.html" target="_blank"
onClick="window.open('/step2.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPHELP}' onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info('&nbsp;'); return true"
>${LANG_TIPHELP}</a>
</td>
${do:end-if}
@@ -118,7 +118,7 @@ ${do:end-if}
<tr><td>
${LANG_G31}
<select name="todo"
onMouseOver="info('${html:LANG_G9}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_G9}' onMouseOver="info('${html:LANG_G9}'); return true" onMouseOut="info('&nbsp;'); return true"
>
${listid:todo:LISTDEF_10}
</select>
@@ -131,12 +131,12 @@ ${do:end-if}
</td><td>
<input type="button" value="${LANG_G43}"
onClick="doOpenWindow()"
onMouseOver="info('${html:LANG_G24b}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_G24b}' onMouseOver="info('${html:LANG_G24b}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td></tr></table>
<br>
<textarea name="urls" cols="50" rows="8"
onMouseOver="info('${html:LANG_G11}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_G11}' onMouseOver="info('${html:LANG_G11}'); return true" onMouseOut="info('&nbsp;'); return true"
>
${do:output-mode:html}
${urls}
@@ -150,7 +150,7 @@ ${do:output-mode:}
${LANG_URLLIST}:
</td><td>
<input name="filelist" value="${filelist}" size="40"
onMouseOver="info('${html:LANG_G24c}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_G24c}' onMouseOver="info('${html:LANG_G24c}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td></tr></table>
@@ -161,7 +161,7 @@ ${do:output-mode:}
${LANG_G41}
</td><td>
<input type="button" value="${LANG_G40}" onClick="window.open('option1.html', 'option1', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
onMouseOver="info('${html:LANG_G24}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_G24}' onMouseOver="info('${html:LANG_G24}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td></tr></table>
@@ -170,11 +170,11 @@ ${do:output-mode:}
<tr><td align="right">
<table width="100%" border="0"><tr><td align="left">
<input type="submit" value=" << ${LANG_PREVIOUS} " onClick="form.redirect.value='step2.html'; form.submit()"
onMouseOver="info('${html:LANG_TIPPREV}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPPREV}' onMouseOver="info('${html:LANG_TIPPREV}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td><td align="right">
<input name="nextBtn" type="submit" value=" ${LANG_NEXT} >> "
onMouseOver="info('${html:LANG_TIPNEXT}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPNEXT}' onMouseOver="info('${html:LANG_TIPNEXT}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td></tr></table>
@@ -196,7 +196,7 @@ ${do:output-mode:}
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></small></td>
<td id="footer"><small><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></small></td>
</tr>
</table>

View File

@@ -43,7 +43,7 @@ function info(str) {
<td id="subTitle" align="right">
<a href="/server/file.html" target="_blank"
onClick="window.open('/server/file.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
onMouseOver="info('${html:LANG_O1}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_O1}' onMouseOver="info('${html:LANG_O1}'); return true" onMouseOut="info('&nbsp;'); return true"
style="color:#FFFFFF"
>
${LANG_O1}
@@ -55,7 +55,7 @@ ${do:if-file-exists:html/index.html}
<td id="subTitle" align="right">
<a href="/index.html" target="_blank"
onClick="window.open('/server/help.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPHELP}' onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info('&nbsp;'); return true"
style="color:#FFFFFF"
>
${LANG_O5}
@@ -84,7 +84,7 @@ ${do:if-file-exists:html/index.html}
<td>
<a href="/step3.html" target="_blank"
onClick="window.open('/step3.html', 'help', 'toolbar=no, location=no, directories=no, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=640, height=480'); return false"
onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPHELP}' onMouseOver="info('${html:LANG_TIPHELP}'); return true" onMouseOut="info('&nbsp;'); return true"
>${LANG_TIPHELP}</a>
</td>
${do:end-if}
@@ -178,6 +178,12 @@ ${do:end-if}
${test:parsejava:--parse-java=0:}
${test:updhack:--updatehack}
${test:urlhack:--urlhack=0:--urlhack}
${test:keepwww:--keep-www-prefix}
${test:keepslashes:--keep-double-slashes}
${test:keepqueryorder:--keep-query-order}
${test:cookiesfile:--cookies-file "}${html:cookiesfile}${test:cookiesfile:"}
${test:pausefiles:--pause "}${pausefiles}${test:pausefiles:"}
${test:stripquery:--strip-query "}${html:stripquery}${test:stripquery:"}
${test:toler:--tolerant}
${test:http10:--http-10}
${test:cache2:--store-all-in-cache}
@@ -186,7 +192,7 @@ ${do:end-if}
${test:logtype:::--extra-log:--debug-log}
${test:index:--index=0:}
${test:index2:--search-index=0:--search-index}
${test:prox:--proxy "}${prox}${test:prox:\3A}${portprox}${test:prox:"}
${test:prox:--proxy "}${do:if-not-empty:prox}${test:proxytype::socks5:connect}${test:proxytype:\3A//}${do:end-if}${do:output-mode:html}${prox}${test:prox:\3A}${portprox}${test:prox:"}
${test:ftpprox:--httpproxy-ftp=0:--httpproxy-ftp}
</textarea>
@@ -219,15 +225,21 @@ NoPwdInPages=${ztest:hidepwd:0:1}
NoQueryStrings=${ztest:hidequery:0:1}
NoPurgeOldFiles=${ztest:nopurge:0:1}
Cookies=${ztest:cookies:0:1}
CookiesFile=${cookiesfile}
CheckType=${ztest:checktype:0:1:2}
ParseJava=${ztest:parsejava:0:1}
HTTP10=${ztest:http10:0:1}
TolerantRequests=${ztest:toler:0:1}
UpdateHack=${ztest:updhack:0:1}
URLHack=${ztest:urlhack:0:1}
KeepWww=${ztest:keepwww:0:1}
KeepSlashes=${ztest:keepslashes:0:1}
KeepQueryOrder=${ztest:keepqueryorder:0:1}
StripQuery=${stripquery}
StoreAllInCache=${ztest:cache2:0:1}
LogType=${logtype}
UseHTTPProxyForFTP=${ztest:ftpprox:0:1}
ProxyType=${proxytype}
Build=${build}
PrimaryScan=${filter}
Travel=${travel}
@@ -238,6 +250,7 @@ MaxHtml=${maxhtml}
MaxOther=${othermax}
MaxAll=${sizemax}
MaxWait=${pausebytes}
PauseFiles=${pausefiles}
Sockets=${connexion}
Retry=${retry}
MaxTime=${maxtime}
@@ -285,11 +298,11 @@ ${do:output-mode:}
</td></tr><tr><td>
<table width="100%" border="0"><tr><td align="left">
<input type="submit" value=" << ${LANG_PREVIOUS} " onClick="form.command.value=''; form.redirect.value='step3.html'; form.submit()"
onMouseOver="info('${html:LANG_TIPPREV}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPPREV}' onMouseOver="info('${html:LANG_TIPPREV}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td><td align="right">
<input name="nextBtn" type="submit" value=" ${LANG_J9} >> "
onMouseOver="info('${html:LANG_TIPNEXT}'); return true" onMouseOut="info('&nbsp;'); return true"
title='${html:LANG_TIPNEXT}' onMouseOver="info('${html:LANG_TIPNEXT}'); return true" onMouseOut="info('&nbsp;'); return true"
>
</td></tr></table>
@@ -311,7 +324,7 @@ ${do:output-mode:}
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></small></td>
<td id="footer"><small><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></small></td>
</tr>
</table>

View File

@@ -141,7 +141,7 @@ You may encounter minor differences (in the display, or in various options) betw
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
<td id="footer"><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
</tr>
</table>

View File

@@ -128,7 +128,7 @@ h4 { margin: 0; font-weight: bold; font-size: 1.18em; }
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
<td id="footer"><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
</tr>
</table>

View File

@@ -143,7 +143,7 @@ h4 { margin: 0; font-weight: bold; font-size: 1.18em; }
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
<td id="footer"><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
</tr>
</table>

View File

@@ -157,7 +157,7 @@ h4 { margin: 0; font-weight: bold; font-size: 1.18em; }
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
<td id="footer"><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
</tr>
</table>

View File

@@ -151,7 +151,7 @@ h4 { margin: 0; font-weight: bold; font-size: 1.18em; }
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
<td id="footer"><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
</tr>
</table>

View File

@@ -128,7 +128,7 @@ h4 { margin: 0; font-weight: bold; font-size: 1.18em; }
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
<td id="footer"><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
</tr>
</table>

View File

@@ -127,7 +127,7 @@ h4 { margin: 0; font-weight: bold; font-size: 1.18em; }
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
<td id="footer"><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
</tr>
</table>

View File

@@ -144,7 +144,7 @@ h4 { margin: 0; font-weight: bold; font-size: 1.18em; }
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
<td id="footer"><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
</tr>
</table>

View File

@@ -145,7 +145,7 @@ h4 { margin: 0; font-weight: bold; font-size: 1.18em; }
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
<td id="footer"><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
</tr>
</table>

View File

@@ -150,7 +150,7 @@ h4 { margin: 0; font-weight: bold; font-size: 1.18em; }
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
<td id="footer"><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
</tr>
</table>

View File

@@ -182,7 +182,7 @@ In this case, HTTrack won't check the type, because it has learned that "foo" is
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
<td id="footer"><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
</tr>
</table>

View File

@@ -181,7 +181,7 @@ h4 { margin: 0; font-weight: bold; font-size: 1.18em; }
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
<td id="footer"><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
</tr>
</table>

View File

@@ -145,7 +145,7 @@ h4 { margin: 0; font-weight: bold; font-size: 1.18em; }
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
<td id="footer"><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
</tr>
</table>

View File

@@ -176,7 +176,7 @@ h4 { margin: 0; font-weight: bold; font-size: 1.18em; }
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
<td id="footer"><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
</tr>
</table>

View File

@@ -165,7 +165,7 @@ h4 { margin: 0; font-weight: bold; font-size: 1.18em; }
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
<td id="footer"><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
</tr>
</table>

View File

@@ -162,7 +162,7 @@ h4 { margin: 0; font-weight: bold; font-size: 1.18em; }
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
<td id="footer"><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
</tr>
</table>

View File

@@ -151,7 +151,7 @@ h4 { margin: 0; font-weight: bold; font-size: 1.18em; }
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
<td id="footer"><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
</tr>
</table>

View File

@@ -141,7 +141,7 @@ h4 { margin: 0; font-weight: bold; font-size: 1.18em; }
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
<td id="footer"><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
</tr>
</table>

View File

@@ -156,7 +156,7 @@ h4 { margin: 0; font-weight: bold; font-size: 1.18em; }
<table width="76%" border="0" align="center" valign="bottom" cellspacing="0" cellpadding="0">
<tr>
<td id="footer"><small>&copy; 2007 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
<td id="footer"><small>&copy; 1998-2026 Xavier Roche & other contributors - Web Design: Leto Kauler.</small></td>
</tr>
</table>

View File

@@ -1006,3 +1006,31 @@ LANG_SERVEND
Server terminated
LANG_FATALERR
A fatal error has occurred during this mirror
LANG_PROXYTYPE
Proxy type:
LANG_PROXYTYPETIP
Proxy protocol. HTTP: standard proxy. HTTP (CONNECT tunnel): sends every request through a CONNECT tunnel, for CONNECT-only proxies like Tor's HTTPTunnelPort. SOCKS5: default port 1080.
LANG_COOKIEFILE
Load cookies from file:
LANG_COOKIEFILETIP
Preload cookies from a Netscape cookies.txt file before crawling.
LANG_PAUSEFILES
Pause between files:
LANG_PAUSEFILESTIP
Random delay between file downloads, in seconds. Use MIN:MAX for a random range (e.g. 2:8).
LANG_KEEPWWW
Keep the www. prefix (do not merge www.host with host)
LANG_KEEPWWWTIP
Do not treat www.host and host as the same site.
LANG_KEEPSLASHES
Keep double slashes in URLs
LANG_KEEPSLASHESTIP
Do not collapse duplicate slashes in URLs.
LANG_KEEPQUERYORDER
Keep the original query-string order
LANG_KEEPQUERYORDERTIP
Do not reorder query-string parameters when deduplicating URLs.
LANG_STRIPQUERY
Strip query keys:
LANG_STRIPQUERYTIP
Comma-separated query keys to drop from the saved-file naming (e.g. sid,utm_source).

View File

@@ -23,7 +23,7 @@ pt:7
ro:25
ru:8
sk:20
si:24
sl:24
sv:17
tr:10
uk:22

View File

@@ -928,3 +928,31 @@ Server terminated
Ñúðâúðúò íå îòãîâàðÿ
A fatal error has occurred during this mirror
Ôàòàëíà ãðåøêà ïðè ñúçäàâàíåòî íà òîçè îãëåäàëåí ñàéò
Proxy type:
Òèï íà ïðîêñè:
Proxy protocol. HTTP: standard proxy. HTTP (CONNECT tunnel): sends every request through a CONNECT tunnel, for CONNECT-only proxies like Tor's HTTPTunnelPort. SOCKS5: default port 1080.
Ïðîòîêîë íà ïðîêñè. HTTP: ñòàíäàðòíî ïðîêñè. HTTP (CONNECT òóíåë): èçïðàùà âñÿêà çàÿâêà ïðåç CONNECT òóíåë, çà ïðîêñè ïîääúðæàùè ñàìî CONNECT êàòî HTTPTunnelPort íà Tor. SOCKS5: ïîðò ïî ïîäðàçáèðàíå 1080.
Load cookies from file:
Çàðåæäàíå íà 'áèñêâèòêè' îò ôàéë:
Preload cookies from a Netscape cookies.txt file before crawling.
Ïðåäâàðèòåëíî çàðåæäàíå íà 'áèñêâèòêè' îò ôàéë Netscape cookies.txt ïðåäè îáõîæäàíåòî.
Pause between files:
Ïàóçà ìåæäó ôàéëîâåòå:
Random delay between file downloads, in seconds. Use MIN:MAX for a random range (e.g. 2:8).
Ñëó÷àéíî çàáàâÿíå ìåæäó èçòåãëÿíèÿòà íà ôàéëîâå, â ñåêóíäè. Èçïîëçâàéòå MIN:MAX çà ñëó÷àåí äèàïàçîí (íàïðèìåð 2:8).
Keep the www. prefix (do not merge www.host with host)
Çàïàçâàíå íà ïðåôèêñà www. (áåç ñëèâàíå íà www.host ñ host)
Do not treat www.host and host as the same site.
www.host è host äà íå ñå òðåòèðàò êàòî åäèí è ñúù ñàéò.
Keep double slashes in URLs
Çàïàçâàíå íà äâîéíèòå íàêëîíåíè ÷åðòè â URL
Do not collapse duplicate slashes in URLs.
Áåç ïðåìàõâàíå íà ïîâòàðÿùèòå ñå íàêëîíåíè ÷åðòè â URL.
Keep the original query-string order
Çàïàçâàíå íà îðèãèíàëíèÿ ðåä íà ïàðàìåòðèòå â çàÿâêàòà
Do not reorder query-string parameters when deduplicating URLs.
Áåç ïðåíàðåæäàíå íà ïàðàìåòðèòå íà çàÿâêàòà ïðè ïðåìàõâàíå íà äóáëèðàíè URL.
Strip query keys:
Ïðåìàõâàíå íà êëþ÷îâå îò çàÿâêàòà:
Comma-separated query keys to drop from the saved-file naming (e.g. sid,utm_source).
Êëþ÷îâå îò çàÿâêàòà, ðàçäåëåíè ñúñ çàïåòàÿ, êîèòî äà ñå ïðåìàõíàò îò èìåòî íà çàïèñàíèÿ ôàéë (íàïðèìåð sid,utm_source).

View File

@@ -928,3 +928,31 @@ Server terminated
Servidor desconectado
A fatal error has occurred during this mirror
Ha ocurrido un error fatal durante esta copia
Proxy type:
Tipo de proxy:
Proxy protocol. HTTP: standard proxy. HTTP (CONNECT tunnel): sends every request through a CONNECT tunnel, for CONNECT-only proxies like Tor's HTTPTunnelPort. SOCKS5: default port 1080.
Protocolo del proxy. HTTP: proxy estándar. HTTP (túnel CONNECT): envía cada petición a través de un túnel CONNECT, para proxys que solo admiten CONNECT como el HTTPTunnelPort de Tor. SOCKS5: puerto predeterminado 1080.
Load cookies from file:
Cargar cookies desde un archivo:
Preload cookies from a Netscape cookies.txt file before crawling.
Precargar cookies desde un archivo Netscape cookies.txt antes de comenzar la descarga.
Pause between files:
Pausa entre archivos:
Random delay between file downloads, in seconds. Use MIN:MAX for a random range (e.g. 2:8).
Retardo aleatorio entre descargas de archivos, en segundos. Use MIN:MAX para un rango aleatorio (p. ej. 2:8).
Keep the www. prefix (do not merge www.host with host)
Mantener el prefijo www. (no combinar www.host con host)
Do not treat www.host and host as the same site.
No tratar www.host y host como el mismo sitio.
Keep double slashes in URLs
Mantener las barras dobles en las URL
Do not collapse duplicate slashes in URLs.
No colapsar las barras duplicadas en las URL.
Keep the original query-string order
Mantener el orden original de la query string
Do not reorder query-string parameters when deduplicating URLs.
No reordenar los parámetros de la query string al deduplicar las URL.
Strip query keys:
Eliminar claves de query string:
Comma-separated query keys to drop from the saved-file naming (e.g. sid,utm_source).
Claves de query string, separadas por comas, que se eliminarán del nombre de los archivos guardados (p. ej. sid,utm_source).

View File

@@ -928,3 +928,31 @@ Server terminated
A fatal error has occurred during this mirror
Proxy type:
Typ proxy:
Proxy protocol. HTTP: standard proxy. HTTP (CONNECT tunnel): sends every request through a CONNECT tunnel, for CONNECT-only proxies like Tor's HTTPTunnelPort. SOCKS5: default port 1080.
Protokol proxy. HTTP: standardní proxy. HTTP (tunel CONNECT): odešle každý požadavek pøes tunel CONNECT, pro proxy podporující jen CONNECT jako HTTPTunnelPort v Toru. SOCKS5: výchozí port 1080.
Load cookies from file:
Naèíst cookies ze souboru:
Preload cookies from a Netscape cookies.txt file before crawling.
Naèíst cookies ze souboru Netscape cookies.txt pøed zahájením stahování.
Pause between files:
Prodleva mezi soubory:
Random delay between file downloads, in seconds. Use MIN:MAX for a random range (e.g. 2:8).
Náhodná prodleva mezi stahováním souborù, v sekundách. Pro náhodný rozsah použijte MIN:MAX (napø. 2:8).
Keep the www. prefix (do not merge www.host with host)
Zachovat pøedponu www. (nesluèovat www.host s host)
Do not treat www.host and host as the same site.
Nepovažovat www.host a host za stejný web.
Keep double slashes in URLs
Zachovat dvojitá lomítka v URL
Do not collapse duplicate slashes in URLs.
Nesluèovat opakovaná lomítka v URL.
Keep the original query-string order
Zachovat pùvodní poøadí øetìzce dotazu
Do not reorder query-string parameters when deduplicating URLs.
Nemìnit poøadí parametrù øetìzce dotazu pøi odstraòování duplicitních URL.
Strip query keys:
Odebrat klíèe dotazu:
Comma-separated query keys to drop from the saved-file naming (e.g. sid,utm_source).
Klíèe dotazu oddìlené èárkami, které se vynechají z pojmenování ukládaných souborù (napø. sid,utm_source).

View File

@@ -928,3 +928,31 @@ Server terminated
伺服器已終止
A fatal error has occurred during this mirror
這鏡像發生了不可回復的錯誤
Proxy type:
proxy 類型:
Proxy protocol. HTTP: standard proxy. HTTP (CONNECT tunnel): sends every request through a CONNECT tunnel, for CONNECT-only proxies like Tor's HTTPTunnelPort. SOCKS5: default port 1080.
代理協定。HTTP標準代理。HTTPCONNECT 隧道):透過 CONNECT 隧道傳送每個請求,用於僅支援 CONNECT 的代理,例如 Tor 的 HTTPTunnelPort。SOCKS5預設連接埠 1080。
Load cookies from file:
從檔案載入 cookies:
Preload cookies from a Netscape cookies.txt file before crawling.
在抓取前從 Netscape 格式的 cookies.txt 檔案預先載入 cookies。
Pause between files:
檔案之間暫停:
Random delay between file downloads, in seconds. Use MIN:MAX for a random range (e.g. 2:8).
檔案下載之間的隨機延遲(秒)。使用 MIN:MAX 指定隨機範圍 (例如 2:8)。
Keep the www. prefix (do not merge www.host with host)
保留 www. 前綴 (不將 www.host 與 host 合併)
Do not treat www.host and host as the same site.
不將 www.host 與 host 視為同一站點。
Keep double slashes in URLs
保留 URL 中的雙斜線
Do not collapse duplicate slashes in URLs.
不合併 URL 中重複的斜線。
Keep the original query-string order
保留查詢字串的原始順序
Do not reorder query-string parameters when deduplicating URLs.
在對 URL 去重時不重新排列查詢字串參數。
Strip query keys:
移除查詢鍵:
Comma-separated query keys to drop from the saved-file naming (e.g. sid,utm_source).
以逗號分隔的查詢鍵,將其從儲存檔案的命名中移除 (例如 sid,utm_source)。

View File

@@ -928,3 +928,31 @@ Server terminated
A fatal error has occurred during this mirror
Proxy type:
代理类型:
Proxy protocol. HTTP: standard proxy. HTTP (CONNECT tunnel): sends every request through a CONNECT tunnel, for CONNECT-only proxies like Tor's HTTPTunnelPort. SOCKS5: default port 1080.
代理协议。HTTP标准代理。HTTPCONNECT 隧道):通过 CONNECT 隧道发送每个请求,用于仅支持 CONNECT 的代理,例如 Tor 的 HTTPTunnelPort。SOCKS5默认端口 1080。
Load cookies from file:
从文件加载 cookies:
Preload cookies from a Netscape cookies.txt file before crawling.
在抓取前从 Netscape 格式的 cookies.txt 文件预加载 cookies。
Pause between files:
文件间暂停:
Random delay between file downloads, in seconds. Use MIN:MAX for a random range (e.g. 2:8).
文件下载之间的随机延迟(秒)。使用 MIN:MAX 指定随机范围 (例如 2:8)。
Keep the www. prefix (do not merge www.host with host)
保留 www. 前缀 (不将 www.host 与 host 合并)
Do not treat www.host and host as the same site.
不把 www.host 和 host 视为同一站点。
Keep double slashes in URLs
保留 URL 中的双斜杠
Do not collapse duplicate slashes in URLs.
不合并 URL 中重复的斜杠。
Keep the original query-string order
保留查询字符串的原始顺序
Do not reorder query-string parameters when deduplicating URLs.
在对 URL 去重时不重新排列查询字符串参数。
Strip query keys:
剥离查询键:
Comma-separated query keys to drop from the saved-file naming (e.g. sid,utm_source).
用逗号分隔的查询键,将其从保存文件的命名中删除 (例如 sid,utm_source)。

View File

@@ -930,3 +930,31 @@ Server terminated
Poslužitelj je razriješen
A fatal error has occurred during this mirror
Tijekom ovog zrcaljenja je nastala fatalna pogreška
Proxy type:
Vrsta posrednika:
Proxy protocol. HTTP: standard proxy. HTTP (CONNECT tunnel): sends every request through a CONNECT tunnel, for CONNECT-only proxies like Tor's HTTPTunnelPort. SOCKS5: default port 1080.
Protokol posrednika. HTTP: standardni posrednik. HTTP (CONNECT tunel): ¹alje svaki zahtjev kroz CONNECT tunel, za posrednike koji podr¾avaju samo CONNECT poput Torovog HTTPTunnelPorta. SOCKS5: zadani port 1080.
Load cookies from file:
Uèitati kolaèiæe iz datoteke:
Preload cookies from a Netscape cookies.txt file before crawling.
Prije zrcaljenja uèitati kolaèiæe iz datoteke Netscape cookies.txt.
Pause between files:
Stanka izmeðu datoteka:
Random delay between file downloads, in seconds. Use MIN:MAX for a random range (e.g. 2:8).
Nasumièna odgoda izmeðu preuzimanja datoteka, u sekundama. Za nasumièni raspon koristiti MIN:MAX (npr. 2:8).
Keep the www. prefix (do not merge www.host with host)
Zadr¾ati www. predmetak (ne spajati www.host s host)
Do not treat www.host and host as the same site.
www.host i host ne smatrati istim web-mjestom.
Keep double slashes in URLs
Zadr¾ati dvostruke kose crte u URL-ovima
Do not collapse duplicate slashes in URLs.
Ne sa¾imati ponovljene kose crte u URL-ovima.
Keep the original query-string order
Zadr¾ati izvorni redoslijed teksta za upite
Do not reorder query-string parameters when deduplicating URLs.
Ne mijenjati redoslijed parametara teksta za upite pri uklanjanju dvostrukih URL-ova.
Strip query keys:
Ukloniti kljuèeve upita:
Comma-separated query keys to drop from the saved-file naming (e.g. sid,utm_source).
Zarezom odvojeni kljuèevi upita koji se izostavljaju iz naziva spremljenih datoteka (npr. sid,utm_source).

View File

@@ -976,3 +976,31 @@ Click on this notification to restart the interrupted mirror
Klik på denne notifikation for at genstarte den afbrudte spejlkopiering
HTTrack: could not save profile for '%s'!
HTTrack: kunne ikke gemme profil for '%s'!
Proxy type:
Proxytype:
Proxy protocol. HTTP: standard proxy. HTTP (CONNECT tunnel): sends every request through a CONNECT tunnel, for CONNECT-only proxies like Tor's HTTPTunnelPort. SOCKS5: default port 1080.
Proxyprotokol. HTTP: standardproxy. HTTP (CONNECT-tunnel): sender hver forespørgsel gennem en CONNECT-tunnel, til proxyer der kun understøtter CONNECT som Tors HTTPTunnelPort. SOCKS5: standardport 1080.
Load cookies from file:
Indlæs cookies fra fil:
Preload cookies from a Netscape cookies.txt file before crawling.
Indlæs cookies fra en Netscape cookies.txt-fil, før crawlingen starter.
Pause between files:
Pause mellem filer:
Random delay between file downloads, in seconds. Use MIN:MAX for a random range (e.g. 2:8).
Tilfældig forsinkelse mellem filoverførsler, i sekunder. Brug MIN:MAX for et tilfældigt interval (f.eks. 2:8).
Keep the www. prefix (do not merge www.host with host)
Behold www.-præfikset (sammenlæg ikke www.host med host)
Do not treat www.host and host as the same site.
Behandl ikke www.host og host som det samme websted.
Keep double slashes in URLs
Behold dobbelte skråstreger i URL'er
Do not collapse duplicate slashes in URLs.
Sammenfold ikke gentagne skråstreger i URL'er.
Keep the original query-string order
Behold den oprindelige rækkefølge i forespørgselsstrengen
Do not reorder query-string parameters when deduplicating URLs.
Omorden ikke forespørgselsstrengens parametre, når dublerede URL'er fjernes.
Strip query keys:
Fjern forespørgselsnøgler:
Comma-separated query keys to drop from the saved-file naming (e.g. sid,utm_source).
Kommaseparerede forespørgselsnøgler, der udelades i navngivningen af gemte filer (f.eks. sid,utm_source).

View File

@@ -928,3 +928,31 @@ Server terminated
Der Server wurde beendet
A fatal error has occurred during this mirror
Fataler Fehler während der Webseiten-Kopie
Proxy type:
Proxy-Typ:
Proxy protocol. HTTP: standard proxy. HTTP (CONNECT tunnel): sends every request through a CONNECT tunnel, for CONNECT-only proxies like Tor's HTTPTunnelPort. SOCKS5: default port 1080.
Proxy-Protokoll. HTTP: normaler Proxy. HTTP (CONNECT-Tunnel): sendet jede Anfrage durch einen CONNECT-Tunnel, für Proxys, die nur CONNECT unterstützen, wie Tors HTTPTunnelPort. SOCKS5: Standardport 1080.
Load cookies from file:
Cookies aus Datei laden:
Preload cookies from a Netscape cookies.txt file before crawling.
Cookies aus einer Netscape-cookies.txt-Datei laden, bevor das Crawlen beginnt.
Pause between files:
Pause zwischen Dateien:
Random delay between file downloads, in seconds. Use MIN:MAX for a random range (e.g. 2:8).
Zufällige Verzögerung zwischen Datei-Downloads, in Sekunden. MIN:MAX für einen Zufallsbereich verwenden (z. B. 2:8).
Keep the www. prefix (do not merge www.host with host)
www.-Präfix beibehalten (www.host nicht mit host zusammenführen)
Do not treat www.host and host as the same site.
www.host und host nicht als dieselbe Website behandeln.
Keep double slashes in URLs
Doppelte Schrägstriche in URLs beibehalten
Do not collapse duplicate slashes in URLs.
Doppelte Schrägstriche in URLs nicht zusammenführen.
Keep the original query-string order
Ursprüngliche Reihenfolge des Query-Strings beibehalten
Do not reorder query-string parameters when deduplicating URLs.
Query-String-Parameter beim Entfernen doppelter URLs nicht neu anordnen.
Strip query keys:
Query-Schlüssel entfernen:
Comma-separated query keys to drop from the saved-file naming (e.g. sid,utm_source).
Kommagetrennte Query-Schlüssel, die bei der Benennung gespeicherter Dateien entfallen (z. B. sid,utm_source).

View File

@@ -928,3 +928,31 @@ Server terminated
A fatal error has occurred during this mirror
Proxy type:
Proxy tüüp:
Proxy protocol. HTTP: standard proxy. HTTP (CONNECT tunnel): sends every request through a CONNECT tunnel, for CONNECT-only proxies like Tor's HTTPTunnelPort. SOCKS5: default port 1080.
Puhverserveri protokoll. HTTP: tavaline puhverserver. HTTP (CONNECT-tunnel): saadab iga päringu läbi CONNECT-tunneli, ainult CONNECT-it toetavate puhverserverite jaoks nagu Tori HTTPTunnelPort. SOCKS5: vaikeport 1080.
Load cookies from file:
Lae küpsised failist:
Preload cookies from a Netscape cookies.txt file before crawling.
Lae küpsised eelnevalt Netscape cookies.txt failist enne kopeerimist.
Pause between files:
Paus failide vahel:
Random delay between file downloads, in seconds. Use MIN:MAX for a random range (e.g. 2:8).
Juhuslik viivitus failide allalaadimiste vahel, sekundites. Juhusliku vahemiku jaoks kasuta MIN:MAX (nt 2:8).
Keep the www. prefix (do not merge www.host with host)
Säilita www. eesliide (ära ühenda www.host ja host)
Do not treat www.host and host as the same site.
Ära käsitle www.host ja host sama saidina.
Keep double slashes in URLs
Säilita topeltkaldkriipsud URL-ides
Do not collapse duplicate slashes in URLs.
Ära ühenda korduvaid kaldkriipse URL-ides.
Keep the original query-string order
Säilita päringustringi algne järjekord
Do not reorder query-string parameters when deduplicating URLs.
Ära järjesta päringustringi parameetreid ümber URL-ide korduste eemaldamisel.
Strip query keys:
Eemalda päringuvõtmed:
Comma-separated query keys to drop from the saved-file naming (e.g. sid,utm_source).
Komadega eraldatud päringuvõtmed, mis jäetakse salvestatud faili nimest välja (nt sid,utm_source).

View File

@@ -976,3 +976,31 @@ Click on this notification to restart the interrupted mirror
Click on this notification to restart the interrupted mirror
HTTrack: could not save profile for '%s'!
HTTrack: could not save profile for '%s'!
Proxy type:
Proxy type:
Proxy protocol. HTTP: standard proxy. HTTP (CONNECT tunnel): sends every request through a CONNECT tunnel, for CONNECT-only proxies like Tor's HTTPTunnelPort. SOCKS5: default port 1080.
Proxy protocol. HTTP: standard proxy. HTTP (CONNECT tunnel): sends every request through a CONNECT tunnel, for CONNECT-only proxies like Tor's HTTPTunnelPort. SOCKS5: default port 1080.
Load cookies from file:
Load cookies from file:
Preload cookies from a Netscape cookies.txt file before crawling.
Preload cookies from a Netscape cookies.txt file before crawling.
Pause between files:
Pause between files:
Random delay between file downloads, in seconds. Use MIN:MAX for a random range (e.g. 2:8).
Random delay between file downloads, in seconds. Use MIN:MAX for a random range (e.g. 2:8).
Keep the www. prefix (do not merge www.host with host)
Keep the www. prefix (do not merge www.host with host)
Do not treat www.host and host as the same site.
Do not treat www.host and host as the same site.
Keep double slashes in URLs
Keep double slashes in URLs
Do not collapse duplicate slashes in URLs.
Do not collapse duplicate slashes in URLs.
Keep the original query-string order
Keep the original query-string order
Do not reorder query-string parameters when deduplicating URLs.
Do not reorder query-string parameters when deduplicating URLs.
Strip query keys:
Strip query keys:
Comma-separated query keys to drop from the saved-file naming (e.g. sid,utm_source).
Comma-separated query keys to drop from the saved-file naming (e.g. sid,utm_source).

Some files were not shown because too many files have changed in this diff Show More