mirror of
https://github.com/xroche/httrack.git
synced 2026-06-23 10:37:50 +03:00
Compare commits
3 Commits
dns-multia
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
594cf0da39 | ||
|
|
3845cd1fb3 | ||
|
|
94bffb0804 |
32
.github/workflows/ci.yml
vendored
32
.github/workflows/ci.yml
vendored
@@ -232,30 +232,42 @@ jobs:
|
||||
deb:
|
||||
name: deb package (lintian)
|
||||
runs-on: ubuntu-24.04
|
||||
# Build and gate inside Debian sid, the upload target. A Debian dpkg-deb
|
||||
# produces archive-legal xz members (an Ubuntu host defaults to zstd, which
|
||||
# the archive's lintian rejects), and sid's lintian carries the same
|
||||
# data-driven checks (embedded-lib fingerprints and the like) the buildds and
|
||||
# UDD apply -- so issues surface here instead of after upload.
|
||||
container: debian:sid
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Install packaging toolchain
|
||||
run: |
|
||||
set -euo pipefail
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
apt-get update
|
||||
apt-get install -y --no-install-recommends \
|
||||
ca-certificates git \
|
||||
build-essential autoconf automake libtool autoconf-archive \
|
||||
zlib1g-dev libssl-dev \
|
||||
debhelper devscripts lintian fakeroot
|
||||
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
# --unsigned: CI has no GPG key (also skips the release sig/checksums).
|
||||
# debuild builds every package, then lintian gates on errors.
|
||||
# mkdeb builds every package then runs the lintian gate (--fail-on=error,
|
||||
# warning); debuild runs the packaged test pass.
|
||||
#
|
||||
# DEB_BUILD_OPTIONS trims work CI does not need (release builds via
|
||||
# mkdeb.sh are untouched): noautodbgsym drops the -dbgsym packages whose
|
||||
# LTO payloads are slow to compress and that CI never ships; parallel uses
|
||||
# every core. We let debuild run its test pass -- the only one now that
|
||||
# mkdeb no longer runs its own -- so CI exercises the packaged tests.
|
||||
- name: Build Debian packages
|
||||
# every core.
|
||||
- name: Build and lint Debian packages
|
||||
run: |
|
||||
set -euo pipefail
|
||||
# The workspace volume is owned by the host runner uid, but the
|
||||
# container runs as root, so mkdeb's git calls (superproject and the
|
||||
# coucal submodule) trip "dubious ownership"; mark them all safe.
|
||||
git config --global --add safe.directory "*"
|
||||
export DEB_BUILD_OPTIONS="noautodbgsym parallel=$(nproc)"
|
||||
bash tools/mkdeb.sh --unsigned --no-release-artifacts
|
||||
|
||||
|
||||
5
debian/libhttrack3.lintian-overrides
vendored
5
debian/libhttrack3.lintian-overrides
vendored
@@ -1,3 +1,8 @@
|
||||
# The shared libraries ship without a versioned symbols control file (ABI is
|
||||
# tracked via the SONAME plus a >= upstream-version dependency, see debian/rules).
|
||||
libhttrack3: no-symbols-control-file usr/lib/*
|
||||
|
||||
# Bundled, locally patched minizip (src/minizip): it adds a zipFlush() API the
|
||||
# system libminizip lacks (htscache.c flushes the cache .zip so an interrupted
|
||||
# crawl leaves a valid archive), plus Android/old-zlib portability fixes.
|
||||
libhttrack3: embedded-library *libminizip*
|
||||
|
||||
3
debian/proxytrack.lintian-overrides
vendored
Normal file
3
debian/proxytrack.lintian-overrides
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
# Statically linked against httrack's bundled, patched minizip (see src/minizip
|
||||
# and libhttrack3's override): the zipFlush() API is absent from the system one.
|
||||
proxytrack: embedded-library *libminizip*
|
||||
104
src/htslib.c
104
src/htslib.c
@@ -4766,64 +4766,51 @@ int hts_read(htsblk * r, char *buff, int size) {
|
||||
// -- Gestion cache DNS --
|
||||
// 'RX98
|
||||
|
||||
// 'capsule' contenant uniquement le cache
|
||||
t_dnscache *hts_cache(httrackp * opt) {
|
||||
// Free a DNS cache record (coucal value handler).
|
||||
static void hts_cache_value_free(coucal_opaque arg, coucal_value value) {
|
||||
void *record = value.ptr;
|
||||
|
||||
(void) arg;
|
||||
freet(record);
|
||||
}
|
||||
|
||||
// opt's DNS cache hashtable, created on first use. Records (t_dnscache*) are
|
||||
// owned by the table and freed by hts_cache_value_free on coucal_delete.
|
||||
coucal hts_cache(httrackp *opt) {
|
||||
assertf(opt != NULL);
|
||||
if (opt->state.dns_cache == NULL) {
|
||||
opt->state.dns_cache = (t_dnscache *) malloct(sizeof(t_dnscache));
|
||||
memset(opt->state.dns_cache, 0, sizeof(t_dnscache));
|
||||
coucal cache = coucal_new(0);
|
||||
|
||||
coucal_set_name(cache, "dns_cache");
|
||||
coucal_value_set_value_handler(cache, hts_cache_value_free, NULL);
|
||||
opt->state.dns_cache = cache;
|
||||
}
|
||||
assertf(opt->state.dns_cache != NULL);
|
||||
/* first entry is NULL */
|
||||
assertf(opt->state.dns_cache->iadr == NULL);
|
||||
return opt->state.dns_cache;
|
||||
}
|
||||
|
||||
// Free DNS cache.
|
||||
void hts_cache_free(t_dnscache *const root) {
|
||||
if (root != NULL) {
|
||||
t_dnscache *cache;
|
||||
for(cache = root; cache != NULL; ) {
|
||||
t_dnscache *const next = cache->next;
|
||||
cache->next = NULL;
|
||||
freet(cache);
|
||||
cache = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// lock le cache dns pour tout opération d'ajout
|
||||
// plus prudent quand plusieurs threads peuvent écrire dedans..
|
||||
// -1: status? 0: libérer 1:locker
|
||||
|
||||
// MUST BE LOCKED
|
||||
// MUST BE LOCKED (coucal is not internally serialized vs FTP/web threads)
|
||||
// Look up iadr in the DNS cache, filling out[0..min(count,max)-1].
|
||||
// Returns: -1 not yet tested; 0 negative-cached (not in DNS); >0 address count.
|
||||
static int hts_ghbn_all(const t_dnscache *cache, const char *const iadr,
|
||||
static int hts_ghbn_all(coucal cache, const char *const iadr,
|
||||
SOCaddr *const out, const int max) {
|
||||
void *ptr;
|
||||
|
||||
assertf(out != NULL);
|
||||
assertf(iadr != NULL);
|
||||
if (*iadr == '\0') {
|
||||
return -1;
|
||||
}
|
||||
/* first entry is empty */
|
||||
if (cache->iadr == NULL) {
|
||||
cache = cache->next;
|
||||
}
|
||||
for(; cache != NULL; cache = cache->next) {
|
||||
assertf(cache != NULL);
|
||||
assertf(cache->iadr != NULL);
|
||||
assertf(cache->iadr == (const char*) cache + sizeof(t_dnscache));
|
||||
if (strcmp(cache->iadr, iadr) == 0) { // ok trouvé
|
||||
int i;
|
||||
if (coucal_read_pvoid(cache, iadr, &ptr)) { // ok trouvé
|
||||
const t_dnscache *const record = (const t_dnscache *) ptr;
|
||||
int i;
|
||||
|
||||
assertf(cache->host_count <= HTS_MAXADDRNUM);
|
||||
for (i = 0; i < cache->host_count && i < max; i++) {
|
||||
assertf(cache->host_length[i] <= sizeof(cache->host_addr[i]));
|
||||
SOCaddr_copyaddr2(out[i], cache->host_addr[i], cache->host_length[i]);
|
||||
}
|
||||
return cache->host_count;
|
||||
assertf(record->host_count <= HTS_MAXADDRNUM);
|
||||
for (i = 0; i < record->host_count && i < max; i++) {
|
||||
assertf(record->host_length[i] <= sizeof(record->host_addr[i]));
|
||||
SOCaddr_copyaddr2(out[i], record->host_addr[i], record->host_length[i]);
|
||||
}
|
||||
return record->host_count;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@@ -5088,7 +5075,7 @@ static int hts_dns_resolve_list_(httrackp *opt, const char *_iadr,
|
||||
SOCaddr *const out, const int max,
|
||||
const char **error) {
|
||||
char BIGSTK iadr[HTS_URLMAXSIZE * 2];
|
||||
t_dnscache *cache = hts_cache(opt); // adresse du cache
|
||||
coucal cache = hts_cache(opt); // le cache dns
|
||||
int count;
|
||||
|
||||
assertf(opt != NULL);
|
||||
@@ -5109,13 +5096,10 @@ static int hts_dns_resolve_list_(httrackp *opt, const char *_iadr,
|
||||
if (count >= 0) { // cache hit (0 == negative-cached)
|
||||
return count;
|
||||
} else { // non présent dans le cache dns, tester
|
||||
const size_t iadr_len = strlen(iadr) + 1;
|
||||
SOCaddr resolved[HTS_MAXADDRNUM];
|
||||
t_dnscache *record;
|
||||
int i;
|
||||
|
||||
// find queue
|
||||
for(; cache->next != NULL; cache = cache->next) ;
|
||||
|
||||
#if DEBUGDNS
|
||||
printf("resolving (not cached) %s\n", iadr);
|
||||
#endif
|
||||
@@ -5126,22 +5110,18 @@ static int hts_dns_resolve_list_(httrackp *opt, const char *_iadr,
|
||||
DEBUG_W("gethostbyname done\n");
|
||||
#endif
|
||||
|
||||
/* attempt to store new entry */
|
||||
cache->next = malloct(sizeof(t_dnscache) + iadr_len);
|
||||
if (cache->next != NULL) {
|
||||
t_dnscache *const next = cache->next;
|
||||
char *const block = (char*) cache->next;
|
||||
char *const str = block + sizeof(t_dnscache);
|
||||
memcpy(str, iadr, iadr_len);
|
||||
next->iadr = str;
|
||||
next->host_count = count;
|
||||
/* attempt to store new entry (coucal owns it and dups the host key) */
|
||||
record = malloct(sizeof(t_dnscache));
|
||||
if (record != NULL) {
|
||||
memset(record, 0, sizeof(*record));
|
||||
record->host_count = count;
|
||||
for (i = 0; i < count; i++) {
|
||||
next->host_length[i] = SOCaddr_size(resolved[i]);
|
||||
assertf(next->host_length[i] <= sizeof(next->host_addr[i]));
|
||||
memcpy(next->host_addr[i], &SOCaddr_sockaddr(resolved[i]),
|
||||
next->host_length[i]);
|
||||
record->host_length[i] = SOCaddr_size(resolved[i]);
|
||||
assertf(record->host_length[i] <= sizeof(record->host_addr[i]));
|
||||
memcpy(record->host_addr[i], &SOCaddr_sockaddr(resolved[i]),
|
||||
record->host_length[i]);
|
||||
}
|
||||
next->next = NULL;
|
||||
coucal_add_pvoid(cache, iadr, record);
|
||||
}
|
||||
|
||||
/* copy result to caller (cache store may have failed; result still valid)
|
||||
@@ -6012,14 +5992,14 @@ HTSEXT_API void hts_free_opt(httrackp * opt) {
|
||||
|
||||
/* Cache */
|
||||
if (opt->state.dns_cache != NULL) {
|
||||
t_dnscache *root;
|
||||
coucal root;
|
||||
|
||||
hts_mutexlock(&opt->state.lock);
|
||||
root = opt->state.dns_cache;
|
||||
opt->state.dns_cache = NULL;
|
||||
hts_mutexrelease(&opt->state.lock);
|
||||
|
||||
hts_cache_free(root);
|
||||
coucal_delete(&root); // frees records via hts_cache_value_free
|
||||
}
|
||||
|
||||
/* Cancel chain */
|
||||
|
||||
@@ -147,9 +147,8 @@ struct OLD_htsblk {
|
||||
#define HTS_DEF_FWSTRUCT_t_dnscache
|
||||
typedef struct t_dnscache t_dnscache;
|
||||
#endif
|
||||
// One DNS cache record, stored as a coucal value keyed by hostname.
|
||||
struct t_dnscache {
|
||||
struct t_dnscache *next;
|
||||
const char *iadr;
|
||||
// resolved addresses, in resolver (RFC 6724) order; host_count==0 means the
|
||||
// name does not resolve (negative cache). host_count<=HTS_MAXADDRNUM.
|
||||
int host_count;
|
||||
@@ -245,8 +244,9 @@ HTSEXT_API int check_hostname_dns(const char *const hostname);
|
||||
int ftp_available(void);
|
||||
|
||||
#if HTS_DNSCACHE
|
||||
void hts_cache_free(t_dnscache *const cache);
|
||||
t_dnscache *hts_cache(httrackp * opt);
|
||||
/* Return opt's DNS cache hashtable (hostname -> t_dnscache record), creating it
|
||||
on first use. Records are owned by the table and freed on coucal_delete. */
|
||||
coucal hts_cache(httrackp *opt);
|
||||
#endif
|
||||
|
||||
// outils divers
|
||||
|
||||
@@ -241,7 +241,7 @@ struct htsoptstate {
|
||||
char *userhttptype;
|
||||
int verif_backblue_done; /**< backblue.gif/fade.gif already emitted */
|
||||
int verif_external_status;
|
||||
t_dnscache *dns_cache; /**< DNS resolution cache */
|
||||
coucal dns_cache; /**< DNS resolution cache: hostname -> t_dnscache record */
|
||||
int dns_cache_nthreads; /**< number of in-flight DNS resolver threads */
|
||||
/* HTML parsing state */
|
||||
char _hts_errmsg[HTS_CDLMAXSIZE + 256]; /**< last engine error message */
|
||||
|
||||
Reference in New Issue
Block a user