/src/httrack/src/htscore.h
Line | Count | Source |
1 | | /* ------------------------------------------------------------ */ |
2 | | /* |
3 | | HTTrack Website Copier, Offline Browser for Windows and Unix |
4 | | Copyright (C) 1998 Xavier Roche and other contributors |
5 | | |
6 | | SPDX-License-Identifier: GPL-3.0-or-later |
7 | | |
8 | | This program is free software: you can redistribute it and/or modify |
9 | | it under the terms of the GNU General Public License as published by |
10 | | the Free Software Foundation, either version 3 of the License, or |
11 | | (at your option) any later version. |
12 | | |
13 | | This program is distributed in the hope that it will be useful, |
14 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | | GNU General Public License for more details. |
17 | | |
18 | | You should have received a copy of the GNU General Public License |
19 | | along with this program. If not, see <http://www.gnu.org/licenses/>. |
20 | | |
21 | | Ethical use: we kindly ask that you NOT use this software to harvest email |
22 | | addresses or to collect any other private information about people. Doing so |
23 | | would dishonor our work and waste the many hours we have spent on it. |
24 | | |
25 | | Please visit our Website: http://www.httrack.com |
26 | | */ |
27 | | |
28 | | /* ------------------------------------------------------------ */ |
29 | | /* File: Main file .h */ |
30 | | /* Author: Xavier Roche */ |
31 | | /* ------------------------------------------------------------ */ |
32 | | |
33 | | /* Core engine declarations. Not an installed header, but part of the de-facto |
34 | | API surface: external consumers (e.g. httrack-android) read these structs and |
35 | | constants and call functions declared here. */ |
36 | | #ifndef HTS_CORE_DEFH |
37 | | #define HTS_CORE_DEFH |
38 | | |
39 | | #include "htsglobal.h" |
40 | | |
41 | | /* specific definitions */ |
42 | | #include "htsbase.h" |
43 | | /* Includes and definitions */ |
44 | | #include <sys/types.h> |
45 | | #include <sys/stat.h> |
46 | | #ifdef _WIN32 |
47 | | #include <conio.h> |
48 | | #include <direct.h> |
49 | | #else |
50 | | #ifndef _WIN32 |
51 | | #include <unistd.h> |
52 | | #endif |
53 | | #endif |
54 | | /* END specific definitions */ |
55 | | |
56 | | /* Forward definitions */ |
57 | | #ifndef HTS_DEF_FWSTRUCT_lien_url |
58 | | #define HTS_DEF_FWSTRUCT_lien_url |
59 | | typedef struct lien_url lien_url; |
60 | | #endif |
61 | | #ifndef HTS_DEF_FWSTRUCT_lien_back |
62 | | #define HTS_DEF_FWSTRUCT_lien_back |
63 | | typedef struct lien_back lien_back; |
64 | | #endif |
65 | | #ifndef HTS_DEF_FWSTRUCT_struct_back |
66 | | #define HTS_DEF_FWSTRUCT_struct_back |
67 | | typedef struct struct_back struct_back; |
68 | | #endif |
69 | | #ifndef HTS_DEF_FWSTRUCT_cache_back |
70 | | #define HTS_DEF_FWSTRUCT_cache_back |
71 | | typedef struct cache_back cache_back; |
72 | | #endif |
73 | | #ifndef HTS_DEF_FWSTRUCT_hash_struct |
74 | | #define HTS_DEF_FWSTRUCT_hash_struct |
75 | | typedef struct hash_struct hash_struct; |
76 | | #endif |
77 | | #ifndef HTS_DEF_FWSTRUCT_filecreate_params |
78 | | #define HTS_DEF_FWSTRUCT_filecreate_params |
79 | | typedef struct filecreate_params filecreate_params; |
80 | | #endif |
81 | | |
82 | | // Include htslib.h for all types |
83 | | #include "htslib.h" |
84 | | |
85 | | // options |
86 | | #include "htsopt.h" |
87 | | |
88 | | // HTTrack engine sub-headers |
89 | | |
90 | | // main entry point |
91 | | #include "htscoremain.h" |
92 | | |
93 | | // core routines |
94 | | #include "htscore.h" |
95 | | |
96 | | // misc tools for httrack.c |
97 | | #include "htstools.h" |
98 | | |
99 | | // command-line help |
100 | | #include "htshelp.h" |
101 | | |
102 | | // build the on-disk save filename |
103 | | #include "htsname.h" |
104 | | |
105 | | // FTP support |
106 | | #include "htsftp.h" |
107 | | |
108 | | // URL interception |
109 | | #include "htscatchurl.h" |
110 | | |
111 | | // robots.txt handling |
112 | | #include "htsrobots.h" |
113 | | |
114 | | // link-acceptance rules |
115 | | #include "htswizard.h" |
116 | | |
117 | | // regexp/filter routines |
118 | | #include "htsfilters.h" |
119 | | |
120 | | // download backing (the back[] slot ring) |
121 | | #include "htsback.h" |
122 | | |
123 | | // cache handling |
124 | | #include "htscache.h" |
125 | | |
126 | | // hashing |
127 | | #include "htshash.h" |
128 | | #include "coucal.h" |
129 | | |
130 | | #include "htsdefines.h" |
131 | | |
132 | | #include "hts-indextmpl.h" |
133 | | |
134 | | /** A remote URL split into host and path, each a fixed inline buffer |
135 | | (HTS_URLMAXSIZE*2 bytes, NUL-terminated). */ |
136 | | #ifndef HTS_DEF_FWSTRUCT_lien_adrfil |
137 | | #define HTS_DEF_FWSTRUCT_lien_adrfil |
138 | | typedef struct lien_adrfil lien_adrfil; |
139 | | #endif |
140 | | struct lien_adrfil { |
141 | | char adr[HTS_URLMAXSIZE * 2]; /**< host (address) */ |
142 | | char fil[HTS_URLMAXSIZE * 2]; /**< remote file path */ |
143 | | }; |
144 | | |
145 | | /** A remote URL plus the local on-disk path it is saved to. */ |
146 | | #ifndef HTS_DEF_FWSTRUCT_lien_adrfilsave |
147 | | #define HTS_DEF_FWSTRUCT_lien_adrfilsave |
148 | | typedef struct lien_adrfilsave lien_adrfilsave; |
149 | | #endif |
150 | | struct lien_adrfilsave { |
151 | | lien_adrfil af; |
152 | | char save[HTS_URLMAXSIZE * 2]; /**< local save path (with directory) */ |
153 | | }; |
154 | | |
155 | | /** Per-slot connect-fallback bookkeeping (parallel to struct_back.lnk). |
156 | | Tracks which resolved address the slot is currently connecting to so a |
157 | | stuck connect can be retried against the next one. */ |
158 | | typedef struct hts_connect_fallback { |
159 | | int addr_index; /**< candidate being connected (0-based) */ |
160 | | int addr_count; /**< resolved addresses; -1 = not yet probed */ |
161 | | TStamp connect_start; /**< when the current candidate's connect began */ |
162 | | } hts_connect_fallback; |
163 | | |
164 | | /** The download-slot ring: the set of concurrent transfers in flight. |
165 | | Allocated/owned by the engine; consumers (status callbacks, the loop) |
166 | | read it but do not resize or free it. */ |
167 | | #ifndef HTS_DEF_FWSTRUCT_struct_back |
168 | | #define HTS_DEF_FWSTRUCT_struct_back |
169 | | typedef struct struct_back struct_back; |
170 | | #endif |
171 | | struct struct_back { |
172 | | lien_back *lnk; /**< slot array, valid indices [0..count-1] |
173 | | (count+1 entries allocated); a slot is |
174 | | active iff lnk[i].status != STATUS_FREE. |
175 | | See struct lien_back in htsopt.h and the |
176 | | STATUS_* codes in htsbasenet.h. */ |
177 | | int count; /**< number of usable slots (back_max) */ |
178 | | coucal ready; /**< index of slots whose transfer completed */ |
179 | | LLint ready_size_bytes; /**< total bytes buffered in completed slots */ |
180 | | hts_connect_fallback *connect_fallback; /**< per-slot, count+1 entries */ |
181 | | }; |
182 | | |
183 | | /** Open handle to the mirror cache (the read-from-old / write-to-new state |
184 | | used to resume and to avoid re-fetching unchanged files). Engine-owned. */ |
185 | | #ifndef HTS_DEF_FWSTRUCT_cache_back |
186 | | #define HTS_DEF_FWSTRUCT_cache_back |
187 | | typedef struct cache_back cache_back; |
188 | | #endif |
189 | | struct cache_back { |
190 | | int version; /**< cache-file format version being read */ |
191 | | /* */ |
192 | | int type; |
193 | | int ro; /**< read-only: no new cache is written */ |
194 | | |
195 | | FILE *lst; /**< file list, used for purge */ |
196 | | FILE *txt; /**< human-readable file list (info) */ |
197 | | char lastmodified[256]; |
198 | | // HASH |
199 | | coucal hashtable; |
200 | | // HASH for tests (naming subsystem) |
201 | | coucal cached_tests; |
202 | | /** URLs whose previous entry this run already carried forward (#1421), so a |
203 | | retry of the same link does not store it again. */ |
204 | | coucal kept; |
205 | | /* optional log files */ |
206 | | FILE *log; |
207 | | FILE *errlog; |
208 | | /* read-ahead cursors into the old cache */ |
209 | | int ptr_ant; |
210 | | int ptr_last; |
211 | | /* ZIP-backed cache backend (newer format) */ |
212 | | void *zipInput; |
213 | | void *zipOutput; |
214 | | hts_boolean |
215 | | zipWriteFailed; /**< a cache write failed; stop touching the stream */ |
216 | | int zipWriteFailures; /**< consecutive entry write failures; reset on store */ |
217 | | }; |
218 | | |
219 | | #ifndef HTS_DEF_FWSTRUCT_hash_struct |
220 | | #define HTS_DEF_FWSTRUCT_hash_struct |
221 | | typedef struct hash_struct hash_struct; |
222 | | #endif |
223 | | /** Lookup indexes over the link heap: map save-name / URL back to a link, so a |
224 | | URL seen twice resolves to one entry. The coucal tables index into liens; |
225 | | they do not own the links. */ |
226 | | struct hash_struct { |
227 | | /* points at the engine's link array (opt->liens); not owned */ |
228 | | const lien_url *const*const*liens; |
229 | | /* save-name -> link index (case-insensitive: keys lowercased) */ |
230 | | coucal sav; |
231 | | /* address+path -> link index */ |
232 | | coucal adrfil; |
233 | | /* former address+path -> link index (renamed/moved entries) */ |
234 | | coucal former_adrfil; |
235 | | /* effective urlhack sub-flags: www.==host / // collapse / query-arg sort */ |
236 | | hts_boolean norm_host; |
237 | | hts_boolean norm_slash; |
238 | | hts_boolean norm_query; |
239 | | /* query-strip keys (not owned); set from opt->strip_query at hash_init */ |
240 | | const char *strip_query; |
241 | | /* host-alias rules (not owned); set from opt->host_alias at hash_init */ |
242 | | const char *host_alias; |
243 | | /* scratch: the hash key is a host plus a path, the compare one a path */ |
244 | | char normfil[HTS_URLMAXSIZE * 4]; |
245 | | char normfil2[HTS_URLMAXSIZE * 2]; |
246 | | char catbuff[CATBUFF_SIZE]; |
247 | | }; |
248 | | |
249 | | #ifndef HTS_DEF_FWSTRUCT_filecreate_params |
250 | | #define HTS_DEF_FWSTRUCT_filecreate_params |
251 | | typedef struct filecreate_params filecreate_params; |
252 | | #endif |
253 | | /** Parameters threaded through file-creation callbacks (filenote). */ |
254 | | struct filecreate_params { |
255 | | FILE *lst; /**< open file list to append created paths to */ |
256 | | char path[HTS_URLMAXSIZE * 2]; |
257 | | }; |
258 | | |
259 | | /* Convenience accessors over the link heap; assume `opt` (and where used, |
260 | | `ptr`/`parent_relative`) are in scope. heap(N) is the Nth link; |
261 | | heap_top_index() is the last recorded link's index. */ |
262 | 0 | #define heap(N) (opt->liens[N]) |
263 | | |
264 | 0 | #define heap_top_index() (opt->lien_tot - 1) |
265 | | |
266 | 0 | #define heap_top() (heap(heap_top_index())) |
267 | | |
268 | 0 | #define urladr() (heap(ptr)->adr) |
269 | | |
270 | 0 | #define urlfil() (heap(ptr)->fil) |
271 | | |
272 | 0 | #define savename() (heap(ptr)->sav) |
273 | | |
274 | 0 | #define parenturladr() (heap(heap(ptr)->precedent)->adr) |
275 | | |
276 | 0 | #define parenturlfil() (heap(heap(ptr)->precedent)->fil) |
277 | | |
278 | 0 | #define parentsavename() (heap(heap(ptr)->precedent)->sav) |
279 | | |
280 | 0 | #define relativeurladr() ((!parent_relative)?urladr():parenturladr()) |
281 | | |
282 | 0 | #define relativeurlfil() ((!parent_relative)?urlfil():parenturlfil()) |
283 | | |
284 | 0 | #define relativesavename() ((!parent_relative)?savename():parentsavename()) |
285 | | |
286 | | /* Library-internal helpers (engine-only, HTS_INTERNAL_BYTECODE). */ |
287 | | #ifdef HTS_INTERNAL_BYTECODE |
288 | | |
289 | | /* True if a new cache is being written (plain or zip backend). */ |
290 | 0 | HTS_STATIC int cache_writable(cache_back * cache) { |
291 | 0 | return (cache != NULL && cache->zipOutput != NULL); |
292 | 0 | } Unexecuted instantiation: fuzz-url.c:cache_writable Unexecuted instantiation: htslib.c:cache_writable Unexecuted instantiation: htscore.c:cache_writable Unexecuted instantiation: htshash.c:cache_writable Unexecuted instantiation: htscache.c:cache_writable Unexecuted instantiation: htsback.c:cache_writable Unexecuted instantiation: htsftp.c:cache_writable Unexecuted instantiation: htsparse.c:cache_writable Unexecuted instantiation: htsname.c:cache_writable Unexecuted instantiation: htsrobots.c:cache_writable Unexecuted instantiation: htstools.c:cache_writable Unexecuted instantiation: htswizard.c:cache_writable Unexecuted instantiation: htsbauth.c:cache_writable Unexecuted instantiation: htscodec.c:cache_writable Unexecuted instantiation: htswarc.c:cache_writable Unexecuted instantiation: htschanges.c:cache_writable Unexecuted instantiation: htssinglefile.c:cache_writable Unexecuted instantiation: htssitemap.c:cache_writable Unexecuted instantiation: htsproxy.c:cache_writable Unexecuted instantiation: htszlib.c:cache_writable |
293 | | |
294 | | /* True if an old cache is available to read (plain or zip backend). */ |
295 | 0 | HTS_STATIC int cache_readable(cache_back * cache) { |
296 | 0 | return (cache != NULL && cache->zipInput != NULL); |
297 | 0 | } Unexecuted instantiation: fuzz-url.c:cache_readable Unexecuted instantiation: htslib.c:cache_readable Unexecuted instantiation: htscore.c:cache_readable Unexecuted instantiation: htshash.c:cache_readable Unexecuted instantiation: htscache.c:cache_readable Unexecuted instantiation: htsback.c:cache_readable Unexecuted instantiation: htsftp.c:cache_readable Unexecuted instantiation: htsparse.c:cache_readable Unexecuted instantiation: htsname.c:cache_readable Unexecuted instantiation: htsrobots.c:cache_readable Unexecuted instantiation: htstools.c:cache_readable Unexecuted instantiation: htswizard.c:cache_readable Unexecuted instantiation: htsbauth.c:cache_readable Unexecuted instantiation: htscodec.c:cache_readable Unexecuted instantiation: htswarc.c:cache_readable Unexecuted instantiation: htschanges.c:cache_readable Unexecuted instantiation: htssinglefile.c:cache_readable Unexecuted instantiation: htssitemap.c:cache_readable Unexecuted instantiation: htsproxy.c:cache_readable Unexecuted instantiation: htszlib.c:cache_readable |
298 | | |
299 | | #endif |
300 | | |
301 | | // Functions |
302 | | |
303 | | /* Library-internal only (engine TUs). */ |
304 | | #ifdef HTS_INTERNAL_BYTECODE |
305 | | |
306 | | char *hts_cancel_file_pop(httrackp * opt); |
307 | | |
308 | | /* Detach the pending hts_addurl() list and give the caller ownership; NULL |
309 | | when none is pending. Free it with hts_addurl_free(). */ |
310 | | char **hts_addurl_take(httrackp *opt); |
311 | | |
312 | | /* Free a list taken with hts_addurl_take(), strings included. */ |
313 | | void hts_addurl_free(char **url); |
314 | | |
315 | | #endif |
316 | | |
317 | | /* Record a link on the heap. All strings are copied (caller keeps ownership). |
318 | | Returns 1 on success, 0 if the link limit (opt->maxlink) is reached. */ |
319 | | int hts_record_link(httrackp * opt, |
320 | | const char *address, const char *file, const char *save, |
321 | | const char *ref_address, const char *ref_file, |
322 | | const char *codebase); |
323 | | |
324 | | /* Index of the most recently recorded link. */ |
325 | | size_t hts_record_link_latest(httrackp *opt); |
326 | | |
327 | | /* Mark link at index lpos as not to be processed (sets pass2 = -1). */ |
328 | | void hts_invalidate_link(httrackp * opt, int lpos); |
329 | | |
330 | | /* Reset / free the engine's link heap. */ |
331 | | void hts_record_init(httrackp *opt); |
332 | | |
333 | | void hts_record_free(httrackp *opt); |
334 | | |
335 | | /* Run the mirror for the given start URL(s) under opt. Top-level engine entry. |
336 | | Returns 1 once the crawl loop ran, 0 or -1 for a bailout. *completed says |
337 | | whether it reached the end: false for a bailout, and for any stop that cut it |
338 | | short, however it arrived (state.stop or exit_xh). */ |
339 | | int httpmirror(char *url1, httrackp *opt, hts_boolean *completed); |
340 | | |
341 | | /* Write len bytes of adr to local path s. url_adr/url_fil (may be NULL) name |
342 | | the source URL for logging/notification. */ |
343 | | int filesave(httrackp * opt, const char *adr, int len, const char *s, |
344 | | const char *url_adr /* = NULL */ , |
345 | | const char *url_fil /* = NULL */ ); |
346 | | |
347 | | char *hts_cancel_file_pop(httrackp * opt); |
348 | | |
349 | | int check_fatal_io_errno(void); |
350 | | |
351 | | int engine_stats(void); |
352 | | |
353 | | void host_ban(httrackp * opt, int ptr, struct_back * sback, const char *host); |
354 | | |
355 | | /* Open local file s for writing (filecreate, truncate) or appending |
356 | | (fileappend), creating parent directories as needed. Return an open FILE* |
357 | | the caller must fclose(), or NULL on failure. */ |
358 | | FILE *filecreate(filenote_strc * strct, const char *s); |
359 | | |
360 | | FILE *fileappend(filenote_strc * strct, const char *s); |
361 | | |
362 | | /* Create an empty file, return 1 on success, 0 on failure. */ |
363 | | int filecreateempty(filenote_strc * strct, const char *filename); |
364 | | |
365 | | int filenote(filenote_strc * strct, const char *s, filecreate_params * params); |
366 | | |
367 | | /* Copy into dest (destsize bytes) the form under which the local path s is |
368 | | listed in new.lst: forward slashes, with the mirror `root` stripped when s |
369 | | sits under it. Also the change report's key, so the two must not drift. */ |
370 | | void hts_savename_listed(const char *root, const char *s, char *dest, |
371 | | size_t destsize); |
372 | | |
373 | | /* Copy the whitespace-delimited token at *ptr into dest (destsize bytes, NUL |
374 | | included) and advance *ptr past it and the whitespace after it. HTS_FALSE |
375 | | when the token was longer, dest then holding what fit. A caller reading a |
376 | | filter must refuse it: a cut pattern authorizes something else. */ |
377 | | hts_boolean hts_scan_token(char **ptr, char *dest, size_t destsize); |
378 | | |
379 | | void file_notify(httrackp * opt, const char *adr, const char *fil, |
380 | | const char *save, int create, int modify, int wasupdated); |
381 | | |
382 | | void usercommand(httrackp * opt, int exe, const char *cmd, const char *file, |
383 | | const char *adr, const char *fil); |
384 | | |
385 | | void usercommand_exe(const char *cmd, const char *file); |
386 | | |
387 | | // Finish the makeindex index.html (footer + refresh meta), run usercommand. |
388 | | // Updates *makeindex_done/*makeindex_fp in place; adr/fil are the mode strings. |
389 | | void hts_finish_makeindex(httrackp *opt, int *makeindex_done, |
390 | | FILE **makeindex_fp, int makeindex_links, |
391 | | const char *makeindex_firstlink, |
392 | | const char *template_footer, const char *adr, |
393 | | const char *fil); |
394 | | |
395 | | // Flush ht_buff[0..ht_len] to save on disk; *fp closed+NULLed on write. |
396 | | // Precondition: ht_len>0. |
397 | | void hts_finish_html_file(httrackp *opt, cache_back *cache, htsblk *r, |
398 | | FILE **fp, const char *ht_buff, size_t ht_len, |
399 | | const char *adr, const char *fil, const char *save); |
400 | | |
401 | | /* Longest suffix a rule builder appends after the path (the wizard's |
402 | | "*[file]"), NUL included; asserted against in htswizard.c. */ |
403 | 0 | #define HTS_FILTER_SUFFIX_MAX 8 |
404 | | |
405 | | /* Per-slot capacity of the filters array; filters_init() strides the slots by |
406 | | it. Holds the longest rule any builder emits, because truncating one changes |
407 | | what it matches. */ |
408 | | #define HTS_FILTER_SLOT_SIZE \ |
409 | 0 | (1 + (HTS_URLMAXSIZE * 2 - 1) + 1 + (HTS_URLMAXSIZE * 2 - 1) + \ |
410 | 0 | HTS_FILTER_SUFFIX_MAX) |
411 | | |
412 | | int filters_init(char ***ptrfilters, int maxfilter, int filterinc); |
413 | | |
414 | | /* Binds this crawl's filter array to `opt`, and empties the wizard block with |
415 | | it: opt->wizard_filters indexes into that array and outlives no crawl. */ |
416 | | void filters_bind(httrackp *opt, char ***ptrfilters, int *filptr); |
417 | | |
418 | | /* Longest rule a slot holds and the matcher still looks at. */ |
419 | | #define HTS_FILTER_MAXLEN \ |
420 | 0 | (HTS_FILTER_SLOT_SIZE - 1 < STRJOKER_MAXLEN ? HTS_FILTER_SLOT_SIZE - 1 \ |
421 | 0 | : STRJOKER_MAXLEN) |
422 | | |
423 | | /* Stores `pattern` at `pos`, shifting the rules from there up a slot; the |
424 | | caller has ensured there is room. The one door into the array: a rule past |
425 | | HTS_FILTER_MAXLEN warns and returns HTS_FALSE, never stored dead (#1270). */ |
426 | | hts_boolean filters_insert(httrackp *opt, int pos, const char *pattern); |
427 | | |
428 | | int fspc(httrackp * opt, FILE * fp, const char *type); |
429 | | |
430 | | char *next_token(char *p, int flag); |
431 | | |
432 | | /* Like fil_normalized(), but first drops query keys in STRIP (comma-separated, |
433 | | "*" = all); STRIP NULL/empty behaves exactly like fil_normalized(). */ |
434 | | char *fil_normalized_filtered(const char *source, char *dest, |
435 | | const char *strip); |
436 | | |
437 | | /* As fil_normalized_filtered(), but DO_SLASH/DO_QUERY gate the // collapse and |
438 | | the query-argument sort independently (the urlhack sub-flags). */ |
439 | | char *fil_normalized_filtered_ex(const char *source, char *dest, |
440 | | const char *strip, int do_slash, int do_query); |
441 | | |
442 | | /* For URL ADR/FIL, return (in DEST) the comma keylist to strip from the |
443 | | '\n'-separated "[pattern=]keys" RULES (patterns matched on host/path via |
444 | | strjoker, last wins); NULL if none match. Feeds fil_normalized_filtered(). */ |
445 | | const char *hts_query_strip_keys(const char *rules, const char *adr, |
446 | | const char *fil, char *dest, size_t destsize); |
447 | | |
448 | | /* The --host-alias rules of OPT, or NULL when the option was not given. */ |
449 | | const char *hts_host_alias_rules(httrackp *opt); |
450 | | |
451 | | /* ADR with its host replaced by the canonical one, from the '\n'-separated |
452 | | "alias[,alias...]=canonical" RULES (aliases matched with strjoker, last |
453 | | wins). NOWWW matches the host with its www. prefix collapsed, as -%u keys it. |
454 | | Chains are followed to their end, so the result is a fixpoint. Scheme and |
455 | | credentials are kept. NULL when no rule applies, the mapping is a no-op, the |
456 | | rules loop, or the result would not fit DEST. */ |
457 | | const char *hts_host_alias(const char *rules, const char *adr, |
458 | | hts_boolean collapse_www, char *dest, |
459 | | size_t destsize); |
460 | | |
461 | | /* HTS_TRUE when OPT's url hacks collapse www.host onto host. */ |
462 | | hts_boolean hts_host_alias_collapse_www(httrackp *opt); |
463 | | |
464 | | /* Rewrite AF's host to its --host-alias canonical form, in place, and return |
465 | | it. Idempotent; returns af->adr unchanged when no rule applies. */ |
466 | | const char *hts_host_alias_fold(httrackp *opt, lien_adrfil *af); |
467 | | |
468 | | /* HTS_TRUE if ADRA and ADRB name the same host once RULES are applied. */ |
469 | | hts_boolean hts_host_same_alias(const char *rules, const char *adra, |
470 | | const char *adrb, hts_boolean collapse_www); |
471 | | |
472 | | /* First canonical host in RULES whose chain never ends ("a=b" plus "b=a"), |
473 | | copied into DEST, or NULL if every chain settles. Those hosts are left |
474 | | unaliased, so the engine reports them rather than picking a hop. */ |
475 | | const char *hts_host_alias_looping(const char *rules, hts_boolean collapse_www, |
476 | | char *dest, size_t destsize); |
477 | | |
478 | | /* Read a whole file into a freshly malloc'd, NUL-terminated buffer; the caller |
479 | | owns it and must release it with freet(). Return NULL on missing/unreadable |
480 | | file (readfile_or substitutes defaultdata instead). The byte content is NOT |
481 | | transcoded except readfile_utf8, which expects a UTF-8 path. readfile2 |
482 | | reports the byte size (excluding the NUL) via *size when non-NULL. */ |
483 | | char *readfile(const char *fil); |
484 | | |
485 | | char *readfile2(const char *fil, LLint * size); |
486 | | |
487 | | /* readfile2() refusing a body too large for the int indexes downstream, on the |
488 | | same stat that sizes the read: a caller checking the size itself would leave |
489 | | a window for the file to grow. NULL when it does not fit. */ |
490 | | char *readfile2_inmem(const char *fil, LLint *size); |
491 | | |
492 | | char *readfile_utf8(const char *fil); |
493 | | |
494 | | char *readfile2_utf8(const char *fil, LLint *size); |
495 | | |
496 | | char *readfile_or(const char *fil, const char *defaultdata); |
497 | | |
498 | | /* Backing (download-slot) scheduler. Operate on the back[] ring (struct_back). |
499 | | Not thread-safe; call from the single crawl loop. */ |
500 | | |
501 | | /* True if a connecting slot should give up on the current address and try the |
502 | | next one: a fallback address remains (addr_index+1 < addr_count) and the |
503 | | candidate has been connecting for at least its deadline, min(timeout, an |
504 | | internal cap). elapsed/timeout in seconds. Exposed for the -#D self-test. */ |
505 | | int back_connect_fallback_due(int addr_index, int addr_count, int elapsed, |
506 | | int timeout); |
507 | | |
508 | | /* How many new sockets may be opened now, honoring maxsoc and the maxconn rate |
509 | | limit (>=0). _strict ignores reserved-slot headroom; the plain form leaves |
510 | | room for naming tests and stops at 0 when the stack is nearly full. */ |
511 | | int back_pluggable_sockets(struct_back * sback, httrackp * opt); |
512 | | |
513 | | int back_pluggable_sockets_strict(struct_back * sback, httrackp * opt); |
514 | | |
515 | | /* One engine-loop tick: refresh the transfer stats and run the loop callback |
516 | | for slot b (-1 = none). HTS_FALSE = the callback requested an abort. */ |
517 | | hts_boolean hts_loop_tick(struct_back *sback, httrackp *opt, int b, int ptr); |
518 | | |
519 | | /* Wait until a test socket can be plugged, pumping transfers, stats and the |
520 | | loop callback; gives up past the -E deadline. HTS_FALSE = callback abort. */ |
521 | | hts_boolean hts_wait_available_socket(struct_back *sback, httrackp *opt, |
522 | | cache_back *cache, int ptr); |
523 | | |
524 | | /* Randomized inter-file pause target in [min_ms,max_ms] (#185), derived from a |
525 | | timestamp seed so it is stable within one gap and rerolls per launch. */ |
526 | | int hts_pause_target_ms(TStamp seed, int min_ms, int max_ms); |
527 | | |
528 | | /* Schedule more links from the heap into free slots. Returns the number queued, |
529 | | or <=0 if none could be added (no free slot / paused / stopped). */ |
530 | | int back_fill(struct_back * sback, httrackp * opt, cache_back * cache, |
531 | | int ptr, int numero_passe); |
532 | | |
533 | | /* Count of links already finished (in background or served from cache). */ |
534 | | int backlinks_done(const struct_back *sback, lien_url **liens, int lien_tot, |
535 | | int ptr); |
536 | | |
537 | | /* Like back_fill, but a no-op (returns -1) when in-memory buffered data already |
538 | | exceeds opt->maxcache. */ |
539 | | int back_fillmax(struct_back * sback, httrackp * opt, cache_back * cache, |
540 | | int ptr, int numero_passe); |
541 | | |
542 | | /* Interactive prompt: continue an interrupted mirror? Returns nonzero to go on. |
543 | | */ |
544 | | int ask_continue(httrackp * opt); |
545 | | |
546 | | /* Number of decimal digits in n. */ |
547 | | int nombre_digit(int n); |
548 | | |
549 | | // Polling |
550 | | #if HTS_POLL |
551 | | int check_flot(T_SOC s); |
552 | | |
553 | | int check_stdin(void); |
554 | | #endif |
555 | | /* Nonzero if the socket has a pending error. */ |
556 | | int check_sockerror(T_SOC s); |
557 | | |
558 | | /* external modules: register a link discovered by a parser plugin. */ |
559 | | int htsAddLink(htsmoduleStruct * str, char *link); |
560 | | |
561 | | /* Worst-case byte expansion HT_ADD_HTMLESCAPED* must reserve per escaper. */ |
562 | 0 | #define HTS_HTMLESCAPE_MAXEXP 5 /* escape_for_html_print: '&'->"&" */ |
563 | 0 | #define HTS_HTMLESCAPE_FULL_MAXEXP 6 /* _full: high byte->"&#xHH;" */ |
564 | | |
565 | | #endif |