1 /*
2  * Copyright (c) 2012-2015 Tim Ruehsen
3  * Copyright (c) 2015-2021 Free Software Foundation, Inc.
4  *
5  * This file is part of libwget.
6  *
7  * Libwget is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU Lesser General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * Libwget is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with libwget.  If not, see <https://www.gnu.org/licenses/>.
19  *
20  *
21  * Header file for libwget library routines
22  *
23  * Changelog
24  * 28.12.2012  Tim Ruehsen  created (moved wget.h and list.h and into here)
25  *
26  */
27 
28 #ifndef WGET_WGET_H
29 #define WGET_WGET_H
30 
31 #include <stddef.h> // size_t
32 #include <sys/types.h>
33 #include <unistd.h>
34 #include <stdarg.h> // va_list
35 #include <stdio.h> // FILE
36 #include <stdlib.h>
37 #include <stdbool.h> // bool
38 #include <stdint.h> // int64_t
39 
40 #ifdef WGETVER_FILE
41 #   include WGETVER_FILE
42 #else //not WGETVER_FILE
43 #   include "wgetver.h"
44 #endif //WGETVER_FILE
45 
46 // see https://www.gnu.org/software/gnulib/manual/html_node/Exported-Symbols-of-Shared-Libraries.html
47 #if defined BUILDING_LIBWGET && HAVE_VISIBILITY
48 #	define WGETAPI __attribute__ ((__visibility__("default")))
49 #elif defined BUILDING_LIBWGET && defined _MSC_VER && !defined LIBWGET_STATIC
50 #	define WGETAPI __declspec(dllexport)
51 #elif defined _MSC_VER && !defined LIBWGET_STATIC
52 #	define WGETAPI __declspec(dllimport)
53 #else
54 #	define WGETAPI
55 #endif
56 
57 /*
58  * Attribute defines specific for clang (especially for improving clang analyzer)
59  * Using G_GNU_ as prefix to let gtk-doc recognize the attributes.
60  */
61 
62 /*
63  * Attribute defines for GCC and compatible compilers
64  * Using G_GNU_ as prefix to let gtk-doc recognize the attributes.
65  *
66  * Clang also defines __GNUC__. It promotes a GCC version of 4.2.1.
67  */
68 
69 #if defined __GNUC__ && defined __GNUC_MINOR__
70 #	define GCC_VERSION_AT_LEAST(major, minor) ((__GNUC__ > (major)) || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor)))
71 #else
72 #	define GCC_VERSION_AT_LEAST(major, minor) 0
73 #endif
74 
75 #if defined __clang_major__ && defined __clang_minor__
76 #	define CLANG_VERSION_AT_LEAST(major, minor) ((__clang_major__ > (major)) || (__clang_major__ == (major) && __clang_minor__ >= (minor)))
77 #else
78 #	define CLANG_VERSION_AT_LEAST(major, minor) 0
79 #endif
80 
81 #if GCC_VERSION_AT_LEAST(2,5)
82 #	define WGET_GCC_CONST __attribute__ ((const))
83 #else
84 #	define WGET_GCC_CONST
85 #endif
86 
87 #define WGET_GCC_NORETURN_FUNCPTR
88 #if GCC_VERSION_AT_LEAST(2,8) || __SUNPRO_C >= 0x5110
89 #	define WGET_GCC_NORETURN __attribute__ ((__noreturn__))
90 #	undef WGET_GCC_NORETURN_FUNCPTR
91 #	define G_GNUC_NORETURN_FUNCPTR WGET_GCC_NORETURN
92 #elif _MSC_VER >= 1200
93 #	define WGET_GCC_NORETURN __declspec (noreturn)
94 #elif __STDC_VERSION__ >= 201112
95 #	define WGET_GCC_NORETURN _Noreturn
96 #else
97 #	define WGET_GCC_NORETURN
98 #endif
99 
100 #if GCC_VERSION_AT_LEAST(2,95)
101 #	define WGET_GCC_PRINTF_FORMAT(a, b) __attribute__ ((format (printf, a, b)))
102 #	define WGET_GCC_UNUSED __attribute__ ((unused))
103 #else
104 #	define WGET_GCC_PRINTF_FORMAT(a, b)
105 #	define WGET_GCC_UNUSED
106 #endif
107 
108 #if GCC_VERSION_AT_LEAST(2,96)
109 #	define WGET_GCC_PURE __attribute__ ((pure))
110 #else
111 #	define WGET_GCC_PURE
112 #endif
113 
114 #if GCC_VERSION_AT_LEAST(3,0)
115 #	define WGET_GCC_MALLOC __attribute__ ((malloc))
116 #	define unlikely(expr) __builtin_expect(!!(expr), 0)
117 #	define likely(expr) __builtin_expect(!!(expr), 1)
118 #else
119 #	define WGET_GCC_MALLOC
120 #	define unlikely(expr) expr
121 #	define likely(expr) expr
122 #endif
123 
124 #if GCC_VERSION_AT_LEAST(3,1)
125 #	define WGET_GCC_ALWAYS_INLINE __attribute__ ((always_inline))
126 #   define WGET_GCC_FLATTEN __attribute__ ((flatten))
127 #   define WGET_GCC_DEPRECATED __attribute__ ((deprecated))
128 #else
129 #	define WGET_GCC_ALWAYS_INLINE
130 #	define WGET_GCC_FLATTEN
131 #	define WGET_GCC_DEPRECATED
132 #endif
133 
134 // nonnull is dangerous to use with current gcc <= 4.7.1.
135 // see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=17308
136 // we have to use e.g. the clang analyzer if we want NONNULL.
137 // but even clang is not perfect - don't use nonnull in production
138 #if GCC_VERSION_AT_LEAST(3,3)
139 #	define WGET_GCC_NONNULL_ALL __attribute__ ((nonnull))
140 #	define WGET_GCC_NONNULL(a) __attribute__ ((nonnull a))
141 #else
142 #	define WGET_GCC_NONNULL_ALL
143 #	define WGET_GCC_NONNULL(a)
144 #endif
145 
146 #if GCC_VERSION_AT_LEAST(3,4)
147 #	define WGET_GCC_UNUSED_RESULT __attribute__ ((warn_unused_result))
148 #else
149 #	define WGET_GCC_UNUSED_RESULT
150 #endif
151 
152 #if GCC_VERSION_AT_LEAST(4,0)
153 #	define WGET_GCC_NULL_TERMINATED __attribute__((__sentinel__))
154 #else
155 #	define WGET_GCC_NULL_TERMINATED
156 #endif
157 
158 #if GCC_VERSION_AT_LEAST(4,9) || CLANG_VERSION_AT_LEAST(7,0)
159 #	define WGET_GCC_RETURNS_NONNULL __attribute__((returns_nonnull))
160 #else
161 #	define WGET_GCC_RETURNS_NONNULL
162 #endif
163 
164 #if GCC_VERSION_AT_LEAST(4,3) || CLANG_VERSION_AT_LEAST(6,0)
165 #	define WGET_GCC_ALLOC_SIZE(a) __attribute__ ((__alloc_size__(a)))
166 #	define WGET_GCC_ALLOC_SIZE2(a, b) __attribute__ ((__alloc_size__(a, b)))
167 #else
168 #	define WGET_GCC_ALLOC_SIZE(a)
169 #	define WGET_GCC_ALLOC_SIZE2(a, b)
170 #endif
171 
172 #ifdef BUILDING_LIBWGET
173 #	define LIBWGET_WARN_UNUSED_RESULT WGET_GCC_UNUSED_RESULT
174 #else
175 #	define LIBWGET_WARN_UNUSED_RESULT
176 #endif
177 
178 // Let C++ include C headers
179 #ifdef  __cplusplus
180 #	define WGET_BEGIN_DECLS  extern "C" {
181 #	define WGET_END_DECLS    }
182 #else
183 #	define WGET_BEGIN_DECLS
184 #	define WGET_END_DECLS
185 #endif
186 
187 /// define MALLOC_RETURNS_NONNULL when using appropriate implementations of the alloc functions
188 #ifdef MALLOC_RETURNS_NONNULL
189 #  define RETURNS_NONNULL WGET_GCC_RETURNS_NONNULL
190 #  define NULLABLE
191 #else
192 #  define RETURNS_NONNULL
193 #  if defined __clang_major__ && defined WGET_MANYWARNINGS
194 #    define NULLABLE _Nullable
195 #  else
196 #    define NULLABLE
197 #  endif
198 #endif
199 
200 #undef GCC_VERSION_AT_LEAST
201 #undef CLANG_VERSION_AT_LEAST
202 
203 WGET_BEGIN_DECLS
204 
205 /*
206  * Library initialization functions
207  */
208 
209 // Why not using enum ? Might result in different values if one entry is inserted.
210 // And that might break the ABI.
211 #define WGET_DEBUG_STREAM 1000
212 #define WGET_DEBUG_FUNC   1001
213 #define WGET_DEBUG_FILE   1002
214 #define WGET_ERROR_STREAM 1003
215 #define WGET_ERROR_FUNC   1004
216 #define WGET_ERROR_FILE   1005
217 #define WGET_INFO_STREAM  1006
218 #define WGET_INFO_FUNC    1007
219 #define WGET_INFO_FILE    1008
220 #define WGET_DNS_CACHING  1009
221 #define WGET_COOKIE_SUFFIXES 1010
222 #define WGET_COOKIES_ENABLED 1011
223 #define WGET_COOKIE_FILE 1012
224 #define WGET_COOKIE_DB 1013
225 #define WGET_COOKIE_KEEPSESSIONCOOKIES 1014
226 #define WGET_BIND_ADDRESS 1015
227 #define WGET_NET_FAMILY_EXCLUSIVE 1016
228 #define WGET_NET_FAMILY_PREFERRED 1017
229 #define WGET_TCP_FASTFORWARD  1018
230 #define WGET_BIND_INTERFACE  1019
231 
232 #define WGET_HTTP_URL                   2000
233 #define WGET_HTTP_URL_ENCODING          2001
234 #define WGET_HTTP_URI                   2002
235 #define WGET_HTTP_COOKIE_STORE          2003
236 #define WGET_HTTP_HEADER_ADD            2004
237 //#define WGET_HTTP_HEADER_DEL          2005
238 //#define WGET_HTTP_HEADER_SET          2006
239 //#define WGET_HTTP_BIND_ADDRESS        2007
240 #define WGET_HTTP_CONNECTION_PTR        2008
241 #define WGET_HTTP_RESPONSE_KEEPHEADER   2009
242 #define WGET_HTTP_MAX_REDIRECTIONS      2010
243 #define WGET_HTTP_BODY_SAVEAS_STREAM    2011
244 #define WGET_HTTP_BODY_SAVEAS_FILE      2012
245 #define WGET_HTTP_BODY_SAVEAS_FD        2013
246 #define WGET_HTTP_BODY_SAVEAS_FUNC      2014
247 #define WGET_HTTP_HEADER_FUNC           2015
248 #define WGET_HTTP_SCHEME                2016
249 #define WGET_HTTP_BODY                  2017
250 #define WGET_HTTP_BODY_SAVEAS           2018
251 #define WGET_HTTP_USER_DATA             2019
252 #define WGET_HTTP_RESPONSE_IGNORELENGTH 2020
253 
254 // definition of error conditions
255 typedef enum {
256 	WGET_E_SUCCESS = 0, /* OK */
257 	WGET_E_UNKNOWN = -1, /* general error if nothing else appropriate */
258 	WGET_E_MEMORY = -2, /* memory allocation failure */
259 	WGET_E_INVALID = -3, /* invalid value to function */
260 	WGET_E_TIMEOUT = -4, /* timeout condition */
261 	WGET_E_CONNECT = -5, /* connect failure */
262 	WGET_E_HANDSHAKE = -6, /* general TLS handshake failure */
263 	WGET_E_CERTIFICATE = -7, /* general TLS certificate failure */
264 	WGET_E_TLS_DISABLED = -8, /* TLS was not enabled at compile time */
265 	WGET_E_XML_PARSE_ERR = -9, /* XML parsing failed */
266 	WGET_E_OPEN = -10, /* Failed to open file */
267 	WGET_E_IO = -11, /* General I/O error (read/write/stat/...) */
268 	WGET_E_UNSUPPORTED = -12, /* Unsupported function */
269 } wget_error;
270 
271 WGETAPI const char *
272 	wget_strerror(wget_error err);
273 
274 typedef void wget_global_func(const char *, size_t);
275 
276 WGETAPI void
277 	wget_global_init(int key, ...);
278 WGETAPI void
279 	wget_global_deinit(void);
280 WGETAPI const void * NULLABLE
281 	wget_global_get_ptr(int key);
282 WGETAPI int
283 	wget_global_get_int(int key);
284 WGETAPI wget_global_func *
285 	wget_global_get_func(int key);
286 
287 /*
288  * Utility functions
289  */
290 
291 /**
292  * WGET_UTILITY:
293  *
294  * General utility functions
295  */
296 
297 // <mode> values for wget_ready_to_transfer()
298 #define WGET_IO_READABLE 1
299 #define WGET_IO_WRITABLE 2
300 
301 // types for --restrict-file-names / wget_restrict_file_name()
302 #define WGET_RESTRICT_NAMES_NONE          0
303 #define WGET_RESTRICT_NAMES_UNIX       1<<0
304 #define WGET_RESTRICT_NAMES_WINDOWS    1<<1
305 #define WGET_RESTRICT_NAMES_NOCONTROL  1<<2
306 #define WGET_RESTRICT_NAMES_ASCII      1<<3
307 #define WGET_RESTRICT_NAMES_UPPERCASE  1<<4
308 #define WGET_RESTRICT_NAMES_LOWERCASE  1<<5
309 
310 typedef int wget_update_load_fn(void *, FILE *fp);
311 typedef int wget_update_save_fn(void *, FILE *fp);
312 
313 WGETAPI int
314 	wget_ready_2_read(int fd, int timeout);
315 WGETAPI int
316 	wget_ready_2_write(int fd, int timeout);
317 WGETAPI int
318 	wget_ready_2_transfer(int fd, int timeout, int mode);
319 WGETAPI int
320 	wget_strcmp(const char *s1, const char *s2) WGET_GCC_PURE;
321 WGETAPI int
322 	wget_strcasecmp(const char *s1, const char *s2) WGET_GCC_PURE;
323 WGETAPI int
324 	wget_strcasecmp_ascii(const char *s1, const char *s2) WGET_GCC_PURE;
325 WGETAPI int
326 	wget_strncasecmp_ascii(const char *s1, const char *s2, size_t n) WGET_GCC_PURE;
327 WGETAPI char *
328 	wget_strtolower(char *s);
329 WGETAPI int
330 	wget_strncmp(const char *s1, const char *s2, size_t n) WGET_GCC_PURE;
331 WGETAPI int
332 	wget_strncasecmp(const char *s1, const char *s2, size_t n) WGET_GCC_PURE;
333 WGETAPI void
334 	wget_memtohex(const unsigned char * restrict src, size_t src_len, char * restrict dst, size_t dst_size);
335 WGETAPI void
336 	wget_millisleep(int ms);
337 WGETAPI long long
338 	wget_get_timemillis(void);
339 WGETAPI int
340 	wget_percent_unescape(char *src);
341 WGETAPI int
342 	wget_match_tail(const char *s, const char *tail) WGET_GCC_PURE WGET_GCC_NONNULL_ALL;
343 WGETAPI int
344 	wget_match_tail_nocase(const char *s, const char *tail) WGET_GCC_PURE WGET_GCC_NONNULL_ALL;
345 WGETAPI char * NULLABLE
346 	wget_strnglob(const char *str, size_t n, int flags) WGET_GCC_PURE;
347 WGETAPI char *
348 	wget_human_readable(char *buf, size_t bufsize, uint64_t n);
349 WGETAPI int
350 	wget_get_screen_size(int *width, int *height);
351 WGETAPI ssize_t
352 	wget_fdgetline(char **buf, size_t *bufsize, int fd);
353 WGETAPI ssize_t
354 	wget_getline(char **buf, size_t *bufsize, FILE *fp);
355 WGETAPI FILE * NULLABLE
356 	wget_vpopenf(const char *type, const char *restrict fmt, va_list args) WGET_GCC_PRINTF_FORMAT(2,0);
357 WGETAPI FILE * NULLABLE
358 	wget_popenf(const char *type, const char *restrict fmt, ...) WGET_GCC_PRINTF_FORMAT(2,3);
359 WGETAPI FILE * NULLABLE
360 	wget_popen2f(FILE **fpin, FILE **fpout, const char *restrict fmt, ...) WGET_GCC_PRINTF_FORMAT(3,4);
361 WGETAPI pid_t
362 	wget_fd_popen3(int *fdin, int *fdout, int *fderr, const char *const *argv);
363 WGETAPI pid_t
364 	wget_popen3(FILE **fpin, FILE **fpout, FILE **fperr, const char *const *argv);
365 WGETAPI char * NULLABLE
366 	wget_read_file(const char *fname, size_t *size) WGET_GCC_MALLOC;
367 WGETAPI int
368 	wget_update_file(const char *fname, wget_update_load_fn *load_func, wget_update_save_fn *save_func, void *context);
369 WGETAPI int
370 	wget_truncate(const char *path, off_t length);
371 WGETAPI const char *
372 	wget_local_charset_encoding(void);
373 WGETAPI int
374 	wget_memiconv(const char *src_encoding, const void *src, size_t srclen, const char *dst_encoding, char **out, size_t *outlen);
375 WGETAPI char * NULLABLE
376 	wget_striconv(const char *src, const char *src_encoding, const char *dst_encoding) WGET_GCC_MALLOC;
377 WGETAPI bool
378 	wget_str_needs_encoding(const char *s) WGET_GCC_PURE;
379 WGETAPI bool
380 	wget_str_is_valid_utf8(const char *utf8) WGET_GCC_PURE;
381 WGETAPI char * NULLABLE
382 	wget_str_to_utf8(const char *src, const char *encoding) WGET_GCC_MALLOC;
383 WGETAPI char * NULLABLE
384 	wget_utf8_to_str(const char *src, const char *encoding) WGET_GCC_MALLOC;
385 WGETAPI const char *
386 	wget_str_to_ascii(const char *src);
387 
388 /**
389  * WGET_COMPATIBILITY:
390  *
391  * General compatibility functions
392  */
393 
394 WGETAPI size_t
395 	wget_strlcpy(char *restrict dst, const char *restrict src, size_t size);
396 WGETAPI ssize_t
397 	wget_strscpy(char *restrict dst, const char *restrict src, size_t size);
398 
399 /**
400  * \ingroup libwget-list
401  *
402  * Type for double linked lists and list entries.
403  */
404 typedef struct wget_list_st wget_list;
405 typedef int wget_list_browse_fn(void *context, void *elem);
406 
407 WGETAPI void * NULLABLE
408 	wget_list_append(wget_list **list, const void *data, size_t size) WGET_GCC_NONNULL_ALL;
409 WGETAPI void * NULLABLE
410 	wget_list_prepend(wget_list **list, const void *data, size_t size) WGET_GCC_NONNULL_ALL;
411 WGETAPI void * NULLABLE
412 	wget_list_getfirst(const wget_list *list) WGET_GCC_CONST;
413 WGETAPI void * NULLABLE
414 	wget_list_getlast(const wget_list *list) WGET_GCC_PURE;
415 WGETAPI void * NULLABLE
416 	wget_list_getnext(const void *elem) WGET_GCC_PURE;
417 WGETAPI void
418 	wget_list_remove(wget_list **list, void *elem) WGET_GCC_NONNULL_ALL;
419 WGETAPI void
420 	wget_list_free(wget_list **list) WGET_GCC_NONNULL_ALL;
421 WGETAPI int
422 	wget_list_browse(const wget_list *list, wget_list_browse_fn *browse, void *context) WGET_GCC_NONNULL((2));
423 
424 /**
425  * \ingroup libwget-xalloc
426  *
427  * Memory allocation function pointers
428  * @{
429  */
430 
431 // Don't leave freed pointers hanging around
432 #define wget_xfree(a) do { if (a) { wget_free((void *)(a)); a=NULL; } } while (0)
433 
434 /// Type of malloc() function
435 typedef void *wget_malloc_function(size_t);
436 
437 /// Type of calloc() function
438 typedef void *wget_calloc_function(size_t, size_t);
439 
440 /// Type of realloc() function
441 typedef void *wget_realloc_function(void *, size_t);
442 
443 /// Type of free() function
444 typedef void wget_free_function(void *);
445 
446 /* For use in callbacks */
447 extern WGETAPI wget_malloc_function *wget_malloc_fn;
448 extern WGETAPI wget_calloc_function *wget_calloc_fn;
449 extern WGETAPI wget_realloc_function *wget_realloc_fn;
450 extern WGETAPI wget_free_function *wget_free;
451 
452 // we use (inline) functions here to apply function attributes
453 RETURNS_NONNULL LIBWGET_WARN_UNUSED_RESULT WGET_GCC_ALLOC_SIZE(1) WGET_GCC_MALLOC
wget_malloc(size_t size)454 static inline void * NULLABLE wget_malloc(size_t size)
455 {
456 	return wget_malloc_fn(size);
457 }
458 
459 RETURNS_NONNULL LIBWGET_WARN_UNUSED_RESULT WGET_GCC_ALLOC_SIZE2(1,2) WGET_GCC_MALLOC
wget_calloc(size_t nmemb,size_t size)460 static inline void * NULLABLE wget_calloc(size_t nmemb, size_t size)
461 {
462 	return wget_calloc_fn(nmemb, size);
463 }
464 
465 RETURNS_NONNULL LIBWGET_WARN_UNUSED_RESULT WGET_GCC_ALLOC_SIZE(2)
wget_realloc(void * ptr,size_t size)466 static inline void * NULLABLE wget_realloc(void *ptr, size_t size)
467 {
468 	return wget_realloc_fn(ptr, size);
469 }
470 
471 /** @} */
472 
473 /*
474  * String/Memory routines, slightly different than standard functions
475  */
476 
477 LIBWGET_WARN_UNUSED_RESULT WGET_GCC_ALLOC_SIZE(2)
478 WGETAPI void * NULLABLE
479 	wget_memdup(const void *m, size_t n);
480 
481 LIBWGET_WARN_UNUSED_RESULT WGET_GCC_MALLOC
482 WGETAPI char * NULLABLE
483 	wget_strdup(const char *s);
484 
485 LIBWGET_WARN_UNUSED_RESULT WGET_GCC_ALLOC_SIZE(2)
486 WGETAPI char * NULLABLE
487 	wget_strmemdup(const void *m, size_t n);
488 
489 WGETAPI size_t
490 	wget_strmemcpy(char *restrict s, size_t ssize, const void *restrict m, size_t n);
491 
492 LIBWGET_WARN_UNUSED_RESULT WGET_GCC_NONNULL_ALL
493 WGETAPI void * NULLABLE
494 	wget_strmemcpy_a(char *s, size_t ssize, const void *m, size_t n);
495 
496 /*
497  * Base64 routines
498  */
499 
500 WGETAPI bool
501 	wget_base64_is_string(const char *src) WGET_GCC_PURE;
502 WGETAPI size_t
503 	wget_base64_get_decoded_length(size_t len) WGET_GCC_PURE;
504 WGETAPI size_t
505 	wget_base64_get_encoded_length(size_t len) WGET_GCC_PURE;
506 WGETAPI size_t
507 	wget_base64_decode(char *restrict dst, const char *restrict src, size_t n) WGET_GCC_NONNULL_ALL;
508 WGETAPI size_t
509 	wget_base64_encode(char *restrict dst, const char *restrict src, size_t n) WGET_GCC_NONNULL_ALL;
510 WGETAPI size_t
511 	wget_base64_urlencode(char *restrict dst, const char *restrict src, size_t n) WGET_GCC_NONNULL_ALL;
512 WGETAPI char * NULLABLE
513 	wget_base64_decode_alloc(const char *src, size_t n, size_t *outlen) WGET_GCC_NONNULL((1));
514 WGETAPI char * NULLABLE
515 	wget_base64_encode_alloc(const char *src, size_t n) WGET_GCC_NONNULL_ALL;
516 WGETAPI char * NULLABLE
517 	wget_base64_encode_vprintf_alloc(const char *restrict fmt, va_list args) WGET_GCC_PRINTF_FORMAT(1,0) WGET_GCC_NONNULL_ALL;
518 WGETAPI char * NULLABLE
519 	wget_base64_encode_printf_alloc(const char *restrict fmt, ...) WGET_GCC_PRINTF_FORMAT(1,2) WGET_GCC_NONNULL_ALL;
520 
521 /*
522  * Bitmap routines
523  */
524 
525 typedef struct wget_bitmap_st wget_bitmap;
526 
527 WGETAPI int
528 	wget_bitmap_init(wget_bitmap **bitmap, unsigned bits);
529 WGETAPI void
530 	wget_bitmap_free(wget_bitmap **bitmap);
531 WGETAPI void
532 	wget_bitmap_set(wget_bitmap *bitmap, unsigned n); // n is the index
533 WGETAPI void
534 	wget_bitmap_clear(wget_bitmap *bitmap, unsigned n);
535 WGETAPI bool
536 	wget_bitmap_get(const wget_bitmap *bitmap, unsigned n);
537 
538 /*
539  * Buffer routines
540  */
541 
542 typedef struct {
543 	char *
544 		data; //!< pointer to internal memory
545 	size_t
546 		length; //!< number of bytes in 'data'
547 	size_t
548 		size; //!< capacity of 'data' (terminating 0 byte doesn't count here)
549 	bool
550 		release_data : 1, //!< 'data' has been malloc'ed and must be freed
551 		release_buf : 1, //!< wget_buffer structure has been malloc'ed and must be freed
552 		error : 1; //!< a memory failure occurred, the result in 'data' is likely erroneous
553 } wget_buffer;
554 
555 WGETAPI int
556 	wget_buffer_init(wget_buffer *buf, char *data, size_t size) WGET_GCC_NONNULL((1));
557 WGETAPI wget_buffer *
558 	wget_buffer_alloc(size_t size) WGET_GCC_MALLOC WGET_GCC_ALLOC_SIZE(1) RETURNS_NONNULL LIBWGET_WARN_UNUSED_RESULT;
559 WGETAPI int
560 	wget_buffer_ensure_capacity(wget_buffer *buf, size_t size) LIBWGET_WARN_UNUSED_RESULT;
561 WGETAPI void
562 	wget_buffer_deinit(wget_buffer *buf) WGET_GCC_NONNULL((1));
563 WGETAPI void
564 	wget_buffer_free(wget_buffer **buf);
565 WGETAPI void
566 	wget_buffer_free_data(wget_buffer *buf);
567 WGETAPI void
568 	wget_buffer_reset(wget_buffer *buf);
569 WGETAPI size_t
570 	wget_buffer_memcpy(wget_buffer *buf, const void *data, size_t length);
571 WGETAPI size_t
572 	wget_buffer_memcat(wget_buffer *buf, const void *data, size_t length);
573 WGETAPI size_t
574 	wget_buffer_strcpy(wget_buffer *buf, const char *s);
575 WGETAPI size_t
576 	wget_buffer_strcat(wget_buffer *buf, const char *s);
577 WGETAPI size_t
578 	wget_buffer_bufcpy(wget_buffer *buf, wget_buffer *src);
579 WGETAPI size_t
580 	wget_buffer_bufcat(wget_buffer *buf, wget_buffer *src);
581 WGETAPI size_t
582 	wget_buffer_memset(wget_buffer *buf, char c, size_t length);
583 WGETAPI size_t
584 	wget_buffer_memset_append(wget_buffer *buf, char c, size_t length);
585 WGETAPI char *
586 	wget_buffer_trim(wget_buffer *buf);
587 WGETAPI size_t
588 	wget_buffer_vprintf_append(wget_buffer *buf, const char *restrict fmt, va_list args) WGET_GCC_PRINTF_FORMAT(2,0);
589 WGETAPI size_t
590 	wget_buffer_printf_append(wget_buffer *buf, const char *restrict fmt, ...) WGET_GCC_PRINTF_FORMAT(2,3);
591 WGETAPI size_t
592 	wget_buffer_vprintf(wget_buffer *buf, const char *restrict fmt, va_list args) WGET_GCC_PRINTF_FORMAT(2,0);
593 WGETAPI size_t
594 	wget_buffer_printf(wget_buffer *buf, const char *restrict fmt, ...) WGET_GCC_PRINTF_FORMAT(2,3);
595 
596 /*
597  * Printf-style routines
598  */
599 
600 WGETAPI size_t
601 	wget_vasprintf(char **restrict strp, const char *restrict fmt, va_list args) WGET_GCC_PRINTF_FORMAT(2,0);
602 WGETAPI size_t
603 	wget_asprintf(char **restrict strp, const char *restrict fmt, ...) WGET_GCC_PRINTF_FORMAT(2,3);
604 WGETAPI char * NULLABLE
605 	wget_vaprintf(const char *restrict fmt, va_list args) WGET_GCC_PRINTF_FORMAT(1,0);
606 WGETAPI char * NULLABLE
607 	wget_aprintf(const char *restrict fmt, ...) WGET_GCC_PRINTF_FORMAT(1,2);
608 WGETAPI size_t
609 	wget_vfprintf(FILE *restrict fp, const char *restrict fmt, va_list args) WGET_GCC_PRINTF_FORMAT(2,0);
610 WGETAPI size_t
611 	wget_fprintf(FILE *restrict fp, const char *restrict fmt, ...) WGET_GCC_PRINTF_FORMAT(2,3);
612 WGETAPI size_t
613 	wget_printf(const char *restrict fmt, ...) WGET_GCC_PRINTF_FORMAT(1,2);
614 WGETAPI size_t
615 	wget_vsnprintf(char *restrict str, size_t size, const char *restrict fmt, va_list args) WGET_GCC_PRINTF_FORMAT(3,0);
616 WGETAPI size_t
617 	wget_snprintf(char *restrict str, size_t size, const char *restrict fmt, ...) WGET_GCC_PRINTF_FORMAT(3,4);
618 
619 /*
620  * Logger routines
621  */
622 
623 typedef struct wget_logger_st wget_logger;
624 typedef void wget_logger_func(const char *buf , size_t len) WGET_GCC_NONNULL_ALL;
625 
626 WGETAPI void
627 	wget_logger_set_func(wget_logger *logger, wget_logger_func *func);
628 WGETAPI void
629 	wget_logger_set_stream(wget_logger *logger, FILE *fp);
630 WGETAPI void
631 	wget_logger_set_file(wget_logger *logger, const char *fname);
632 WGETAPI wget_logger_func * NULLABLE
633 	wget_logger_get_func(wget_logger *logger) WGET_GCC_PURE;
634 WGETAPI FILE * NULLABLE
635 	wget_logger_get_stream(wget_logger *logger) WGET_GCC_PURE;
636 WGETAPI const char * NULLABLE
637 	wget_logger_get_file(wget_logger *logger) WGET_GCC_PURE;
638 WGETAPI bool
639 	wget_logger_is_active(wget_logger *logger) WGET_GCC_PURE;
640 
641 /*
642  * Logging routines
643  */
644 
645 #define WGET_LOGGER_INFO   1
646 #define WGET_LOGGER_ERROR  2
647 #define WGET_LOGGER_DEBUG  3
648 
649 WGETAPI void
650 	wget_info_vprintf(const char *restrict fmt, va_list args) WGET_GCC_NONNULL_ALL WGET_GCC_PRINTF_FORMAT(1,0);
651 WGETAPI void
652 	wget_info_printf(const char *restrict fmt, ...) WGET_GCC_NONNULL((1)) WGET_GCC_PRINTF_FORMAT(1,2);
653 WGETAPI void
654 	wget_error_vprintf(const char *restrict fmt, va_list args) WGET_GCC_NONNULL_ALL WGET_GCC_PRINTF_FORMAT(1,0);
655 WGETAPI void
656 	wget_error_printf(const char *restrict fmt, ...) WGET_GCC_NONNULL((1)) WGET_GCC_PRINTF_FORMAT(1,2);
657 WGETAPI void WGET_GCC_NONNULL((1)) WGET_GCC_NORETURN WGET_GCC_PRINTF_FORMAT(1,2)
658 	wget_error_printf_exit(const char *restrict fmt, ...);
659 WGETAPI void
660 	wget_debug_vprintf(const char *restrict fmt, va_list args) WGET_GCC_NONNULL_ALL WGET_GCC_PRINTF_FORMAT(1,0);
661 WGETAPI void
662 	wget_debug_printf(const char *restrict fmt, ...) WGET_GCC_NONNULL((1)) WGET_GCC_PRINTF_FORMAT(1,2);
663 WGETAPI void
664 	wget_debug_write(const char *buf, size_t len) WGET_GCC_NONNULL_ALL;
665 WGETAPI wget_logger *
666 	wget_get_logger(int id) WGET_GCC_CONST;
667 
668 /*
669  * Vector datatype routines
670  */
671 
672 typedef struct wget_vector_st wget_vector;
673 typedef int wget_vector_compare_fn(const void *elem1, const void *elem2);
674 typedef int wget_vector_find_fn(void *elem);
675 typedef int wget_vector_browse_fn(void *ctx, void *elem);
676 typedef void wget_vector_destructor(void *elem);
677 
678 WGETAPI wget_vector * NULLABLE
679 	wget_vector_create(int max, wget_vector_compare_fn *cmp) WGET_GCC_MALLOC;
680 WGETAPI void
681 	wget_vector_set_resize_factor(wget_vector *v, float off);
682 WGETAPI int
683 	wget_vector_find(const wget_vector *v, const void *elem) WGET_GCC_NONNULL((2));
684 WGETAPI int
685 	wget_vector_findext(const wget_vector *v, int start, int direction, wget_vector_find_fn *find) WGET_GCC_NONNULL((4));
686 WGETAPI bool
687 	wget_vector_contains(const wget_vector *v, const void *elem) WGET_GCC_NONNULL((2));
688 WGETAPI int
689 	wget_vector_insert(wget_vector *v, const void *elem, int pos) WGET_GCC_NONNULL((2));
690 WGETAPI int
691 	wget_vector_insert_sorted(wget_vector *v, const void *elem) WGET_GCC_NONNULL((2));
692 WGETAPI int
693 	wget_vector_add_memdup(wget_vector *v, const void *elem, size_t size) WGET_GCC_NONNULL((2));
694 WGETAPI int
695 	wget_vector_add(wget_vector *v, const void *elem) WGET_GCC_NONNULL((2));
696 WGETAPI int
697 	wget_vector_add_vprintf(wget_vector *v, const char *restrict fmt, va_list args) WGET_GCC_PRINTF_FORMAT(2,0);
698 WGETAPI int
699 	wget_vector_add_printf(wget_vector *v, const char *restrict fmt, ...) WGET_GCC_PRINTF_FORMAT(2,3);
700 WGETAPI int
701 	wget_vector_replace(wget_vector *v, const void *elem, int pos) WGET_GCC_NONNULL((2));
702 WGETAPI int
703 	wget_vector_move(wget_vector *v, int old_pos, int new_pos);
704 WGETAPI int
705 	wget_vector_swap(wget_vector *v, int pos1, int pos2);
706 WGETAPI int
707 	wget_vector_remove(wget_vector *v, int pos);
708 WGETAPI int
709 	wget_vector_remove_nofree(wget_vector *v, int pos);
710 WGETAPI int
711 	wget_vector_size(const wget_vector *v) WGET_GCC_PURE;
712 WGETAPI int
713 	wget_vector_browse(const wget_vector *v, wget_vector_browse_fn *browse, void *ctx) WGET_GCC_NONNULL((2));
714 WGETAPI void
715 	wget_vector_free(wget_vector **v);
716 WGETAPI void
717 	wget_vector_clear(wget_vector *v);
718 WGETAPI void
719 	wget_vector_clear_nofree(wget_vector *v);
720 WGETAPI void * NULLABLE
721 	wget_vector_get(const wget_vector *v, int pos) WGET_GCC_PURE;
722 WGETAPI void
723 	wget_vector_setcmpfunc(wget_vector *v, wget_vector_compare_fn *cmp) WGET_GCC_NONNULL((2));
724 WGETAPI void
725 	wget_vector_set_destructor(wget_vector *v, wget_vector_destructor *destructor);
726 WGETAPI void
727 	wget_vector_sort(wget_vector *v);
728 
729 /**
730  * \ingroup libwget-hashmap
731  *
732  * @{
733  */
734 
735 /// Type of the hashmap
736 typedef struct wget_hashmap_st wget_hashmap;
737 
738 /// Type of the hashmap compare function
739 typedef int wget_hashmap_compare_fn(const void *key1, const void *key2);
740 
741 /// Type of the hashmap hash function
742 typedef unsigned int wget_hashmap_hash_fn(const void *key);
743 
744 /// Type of the hashmap browse callback function
745 typedef int wget_hashmap_browse_fn(void *ctx, const void *key, void *value);
746 
747 /// Type of the hashmap key destructor function
748 typedef void wget_hashmap_key_destructor(void *key);
749 
750 /// Type of the hashmap value destructor function
751 typedef void wget_hashmap_value_destructor(void *value);
752 /** @} */
753 
754 WGETAPI wget_hashmap * NULLABLE
755 	wget_hashmap_create(int max, wget_hashmap_hash_fn *hash, wget_hashmap_compare_fn *cmp) WGET_GCC_MALLOC;
756 WGETAPI void
757 	wget_hashmap_set_resize_factor(wget_hashmap *h, float factor);
758 WGETAPI int
759 	wget_hashmap_put(wget_hashmap *h, const void *key, const void *value);
760 WGETAPI int
761 	wget_hashmap_size(const wget_hashmap *h) WGET_GCC_PURE;
762 WGETAPI int
763 	wget_hashmap_browse(const wget_hashmap *h, wget_hashmap_browse_fn *browse, void *ctx);
764 WGETAPI void
765 	wget_hashmap_free(wget_hashmap **h);
766 WGETAPI void
767 	wget_hashmap_clear(wget_hashmap *h);
768 WGETAPI int
769 	wget_hashmap_get(const wget_hashmap *h, const void *key, void **value) WGET_GCC_UNUSED_RESULT;
770 #define wget_hashmap_get(a, b, c) wget_hashmap_get((a), (b), (void **)(c))
771 WGETAPI int
772 	wget_hashmap_contains(const wget_hashmap *h, const void *key);
773 WGETAPI int
774 	wget_hashmap_remove(wget_hashmap *h, const void *key);
775 WGETAPI int
776 	wget_hashmap_remove_nofree(wget_hashmap *h, const void *key);
777 WGETAPI void
778 	wget_hashmap_setcmpfunc(wget_hashmap *h, wget_hashmap_compare_fn *cmp);
779 WGETAPI int
780 	wget_hashmap_sethashfunc(wget_hashmap *h, wget_hashmap_hash_fn *hash);
781 WGETAPI void
782 	wget_hashmap_set_key_destructor(wget_hashmap *h, wget_hashmap_key_destructor *destructor);
783 WGETAPI void
784 	wget_hashmap_set_value_destructor(wget_hashmap *h, wget_hashmap_value_destructor *destructor);
785 WGETAPI void
786 	wget_hashmap_set_load_factor(wget_hashmap *h, float factor);
787 
788 /// Type of the hashmap iterator
789 typedef struct wget_hashmap_iterator_st wget_hashmap_iterator;
790 
791 WGETAPI wget_hashmap_iterator * NULLABLE
792 	wget_hashmap_iterator_alloc(wget_hashmap *h) WGET_GCC_MALLOC;
793 WGETAPI void
794 	wget_hashmap_iterator_free(wget_hashmap_iterator **iter);
795 WGETAPI void * NULLABLE
796 	wget_hashmap_iterator_next(wget_hashmap_iterator *iter, void **value);
797 
798 /**
799  * \ingroup libwget-stringmap
800  *
801  * @{
802  */
803 
804 /// Type of the stringmap
805 typedef wget_hashmap wget_stringmap;
806 
807 /// Type of the stringmap compare function
808 typedef int wget_stringmap_compare_fn(const char *key1, const char *key2);
809 
810 /// Type of the stringmap hash function
811 typedef unsigned int wget_stringmap_hash_fn(const char *key);
812 
813 /// Type of the stringmap browse callback function
814 typedef int wget_stringmap_browse_fn(void *ctx, const char *key, void *value);
815 
816 /// Type of the stringmap key destructor function
817 typedef void wget_stringmap_key_destructor(char *key);
818 
819 /// Type of the stringmap value destructor function
820 typedef void wget_stringmap_value_destructor(void *value);
821 
822 /// Type of the stringmap iterator
823 typedef wget_hashmap_iterator wget_stringmap_iterator;
824 
825 /// Wrapper around wget_hashmap_iterator_alloc().
826 #define wget_stringmap_iterator_alloc wget_hashmap_iterator_alloc
827 /// Wrapper around wget_hashmap_iterator_free().
828 #define wget_stringmap_iterator_free wget_hashmap_iterator_free
829 
830 WGETAPI wget_stringmap * NULLABLE
831 	wget_stringmap_create(int max) WGET_GCC_MALLOC;
832 WGETAPI wget_stringmap * NULLABLE
833 	wget_stringmap_create_nocase(int max) WGET_GCC_MALLOC;
834 /** @} */
835 
836 /**
837  * \ingroup libwget-stringmap
838  *
839  * @{
840  */
841 
842 /**
843  * \param[in] h Stringmap to put data into
844  * \param[in] key Key to insert into \p h
845  * \param[in] value Value to insert into \p h
846  * \return 0 if inserted a new entry, 1 if entry existed
847  *
848  * Insert a key/value pair into stringmap \p h.
849  *
850  * \p key and \p value are *not* cloned, the stringmap takes 'ownership' of both.
851  *
852  * If \p key already exists and the pointer values the old and the new key differ,
853  * the old key will be destroyed by calling the key destructor function (default is free()).
854  *
855  * To realize a hashset (just keys without values), \p value may be %NULL.
856  *
857  * Neither \p h nor \p key must be %NULL.
858  */
859 static inline
wget_stringmap_put(wget_stringmap * h,const char * key,const void * value)860 int wget_stringmap_put(wget_stringmap *h, const char *key, const void *value)
861 {
862 	return wget_hashmap_put(h, key, value);
863 }
864 
865 /**
866  * \param[in] h Stringmap
867  * \param[in] key Key to search for
868  * \param[out] value Value to be returned
869  * \return 1 if \p key has been found, 0 if not found
870  *
871  * Get the value for a given key.
872  *
873  * Neither \p h nor \p key must be %NULL.
874  */
875 static inline WGET_GCC_UNUSED_RESULT
wget_stringmap_get(const wget_stringmap * h,const char * key,void ** value)876 int wget_stringmap_get(const wget_stringmap *h, const char *key, void **value)
877 {
878 	return wget_hashmap_get(h, key, value);
879 }
880 #define wget_stringmap_get(h, k, v) wget_stringmap_get((h), (k), (void **)(v))
881 
882 /**
883  * \param[in] h Stringmap
884  * \param[in] key Key to search for
885  * \return 1 if \p key has been found, 0 if not found
886  *
887  * Check if \p key exists in \p h.
888  */
889 static inline
wget_stringmap_contains(const wget_stringmap * h,const char * key)890 int wget_stringmap_contains(const wget_stringmap *h, const char *key)
891 {
892 	return wget_hashmap_contains(h, key);
893 }
894 
895 /**
896  * \param[in] h Stringmap
897  * \param[in] key Key to be removed
898  * \return 1 if \p key has been removed, 0 if not found
899  *
900  * Remove \p key from stringmap \p h.
901  *
902  * If \p key is found, the key and value destructor functions are called
903  * when removing the entry from the stringmap.
904  */
905 static inline
wget_stringmap_remove(wget_stringmap * h,const char * key)906 int wget_stringmap_remove(wget_stringmap *h, const char *key)
907 {
908 	return wget_hashmap_remove(h, key);
909 }
910 
911 /**
912  * \param[in] h Stringmap
913  * \param[in] key Key to be removed
914  * \return 1 if \p key has been removed, 0 if not found
915  *
916  * Remove \p key from stringmap \p h.
917  *
918  * Key and value destructor functions are *not* called when removing the entry from the stringmap.
919  */
920 static inline
wget_stringmap_remove_nofree(wget_stringmap * h,const char * key)921 int wget_stringmap_remove_nofree(wget_stringmap *h, const char *key)
922 {
923 	return wget_hashmap_remove_nofree(h, key);
924 }
925 
926 /**
927  * \param[in] h Stringmap to be free'd
928  *
929  * Remove all entries from stringmap \p h and free the stringmap instance.
930  *
931  * Key and value destructor functions are called for each entry in the stringmap.
932  */
933 static inline
wget_stringmap_free(wget_stringmap ** h)934 void wget_stringmap_free(wget_stringmap **h)
935 {
936 	wget_hashmap_free(h);
937 }
938 
939 /**
940  * \param[in] h Stringmap to be cleared
941  *
942  * Remove all entries from stringmap \p h.
943  *
944  * Key and value destructor functions are called for each entry in the stringmap.
945  */
946 static inline
wget_stringmap_clear(wget_stringmap * h)947 void wget_stringmap_clear(wget_stringmap *h)
948 {
949 	wget_hashmap_clear(h);
950 }
951 
952 /**
953  * \param[in] h Stringmap
954  * \return Number of entries in stringmap \p h
955  *
956  * Return the number of entries in the stringmap \p h.
957  */
958 static inline
wget_stringmap_size(const wget_stringmap * h)959 int wget_stringmap_size(const wget_stringmap *h)
960 {
961 	return wget_hashmap_size(h);
962 }
963 
964 /**
965  * \param[in] h Stringmap
966  * \param[in] browse Function to be called for each element of \p h
967  * \param[in] ctx Context variable use as param to \p browse
968  * \return Return value of the last call to \p browse
969  *
970  * Call function \p browse for each element of stringmap \p h or until \p browse
971  * returns a value not equal to zero.
972  *
973  * \p browse is called with \p ctx and the pointer to the current element.
974  *
975  * The return value of the last call to \p browse is returned or 0 if either \p h or \p browse is %NULL.
976  */
977 static inline
wget_stringmap_browse(const wget_stringmap * h,wget_stringmap_browse_fn * browse,void * ctx)978 int wget_stringmap_browse(const wget_stringmap *h, wget_stringmap_browse_fn *browse, void *ctx)
979 {
980 	return wget_hashmap_browse(h, (wget_hashmap_browse_fn *) browse, ctx);
981 }
982 
983 /**
984  * \param[in] h Stringmap
985  * \param[in] cmp Comparison function used to find keys
986  *
987  * Set the comparison function.
988  */
989 static inline
wget_stringmap_setcmpfunc(wget_stringmap * h,wget_stringmap_compare_fn * cmp)990 void wget_stringmap_setcmpfunc(wget_stringmap *h, wget_stringmap_compare_fn *cmp)
991 {
992 	wget_hashmap_setcmpfunc(h, (wget_hashmap_compare_fn *) cmp);
993 }
994 
995 /**
996  * \param[in] h Stringmap
997  * \param[in] hash Hash function used to hash keys
998  *
999  * Set the key hash function.
1000  *
1001  * The keys of all entries in the stringmap will be hashed again.
1002  */
1003 static inline
wget_stringmap_sethashfunc(wget_stringmap * h,wget_stringmap_hash_fn * hash)1004 int wget_stringmap_sethashfunc(wget_stringmap *h, wget_stringmap_hash_fn *hash)
1005 {
1006 	return wget_hashmap_sethashfunc(h, (wget_hashmap_hash_fn *) hash);
1007 }
1008 
1009 /**
1010  * \param[in] h Stringmap
1011  * \param[in] destructor Destructor function for keys
1012  *
1013  * Set the key destructor function.
1014  *
1015  * Default is free().
1016  */
1017 static inline
wget_stringmap_set_key_destructor(wget_hashmap * h,wget_stringmap_key_destructor * destructor)1018 void wget_stringmap_set_key_destructor(wget_hashmap *h, wget_stringmap_key_destructor *destructor)
1019 {
1020 	wget_hashmap_set_key_destructor(h, (wget_hashmap_key_destructor *) destructor);
1021 }
1022 
1023 /**
1024  * \param[in] h Stringmap
1025  * \param[in] destructor Destructor function for values
1026  *
1027  * Set the value destructor function.
1028  *
1029  * Default is free().
1030  */
1031 static inline
wget_stringmap_set_value_destructor(wget_hashmap * h,wget_stringmap_value_destructor * destructor)1032 void wget_stringmap_set_value_destructor(wget_hashmap *h, wget_stringmap_value_destructor *destructor)
1033 {
1034 	wget_hashmap_set_value_destructor(h, (wget_hashmap_value_destructor *) destructor);
1035 }
1036 
1037 /**
1038  * \param[in] h Stringmap
1039  * \param[in] factor The load factor
1040  *
1041  * Set the load factor function.
1042  *
1043  * The load factor is determines when to resize the internal memory.
1044  * 0.75 means "resize if 75% or more of all slots are used".
1045  *
1046  * The resize strategy is set by wget_stringmap_set_growth_policy().
1047  *
1048  * The resize (and rehashing) occurs earliest on the next insertion of a new key.
1049  *
1050  * Default is 0.75.
1051  */
1052 static inline
wget_stringmap_set_load_factor(wget_stringmap * h,float factor)1053 void wget_stringmap_set_load_factor(wget_stringmap *h, float factor)
1054 {
1055 	wget_hashmap_set_load_factor(h, factor);
1056 }
1057 
1058 /**
1059  * \param[in] h Stringmap
1060  * \param[in] off Stringmap growth factor
1061  *
1062  * Set the factor for resizing the stringmap when it's load factor is reached.
1063  *
1064  * The new size is 'factor * oldsize'. If the new size is less or equal 0,
1065  * the involved put function will do nothing and the internal state of
1066  * the stringmap will not change.
1067  *
1068  * Default is 2.
1069  */
1070 static inline
wget_stringmap_set_resize_factor(wget_stringmap * h,float factor)1071 void wget_stringmap_set_resize_factor(wget_stringmap *h, float factor)
1072 {
1073 	wget_hashmap_set_resize_factor(h, factor);
1074 }
1075 
1076 /**
1077  * \param[in] iter Stringmap iterator
1078  * \param[out] value Pointer to the value belonging to the returned key
1079  * \return Pointer to the key or NULL if no more elements left
1080  *
1081  * Returns the next key / value in the stringmap. If all key/value pairs have been
1082  * iterated over the function returns NULL and \p value is untouched.
1083  *
1084  * When iterating over a stringmap, the order of returned key/value pairs is not defined.
1085  */
1086 static inline
wget_stringmap_iterator_next(wget_stringmap_iterator * h,void ** value)1087 void * NULLABLE wget_stringmap_iterator_next(wget_stringmap_iterator *h, void **value)
1088 {
1089 	return wget_hashmap_iterator_next(h, (void **) value);
1090 }
1091 
1092 /** @} */
1093 
1094 /*
1095  * Thread wrapper routines
1096  */
1097 
1098 typedef unsigned long wget_thread_id;
1099 typedef struct wget_thread_st *wget_thread;
1100 typedef struct wget_thread_mutex_st *wget_thread_mutex;
1101 typedef struct wget_thread_cond_st *wget_thread_cond;
1102 
1103 WGETAPI int
1104 	wget_thread_start(wget_thread *thread, void *(*start_routine)(void *), void *arg, int flags);
1105 WGETAPI int
1106 	wget_thread_mutex_init(wget_thread_mutex *mutex);
1107 WGETAPI int
1108 	wget_thread_mutex_destroy(wget_thread_mutex *mutex);
1109 WGETAPI void
1110 	wget_thread_mutex_lock(wget_thread_mutex mutex);
1111 WGETAPI void
1112 	wget_thread_mutex_unlock(wget_thread_mutex mutex);
1113 WGETAPI int
1114 	wget_thread_kill(wget_thread thread, int sig);
1115 WGETAPI int
1116 	wget_thread_cancel(wget_thread thread);
1117 WGETAPI int
1118 	wget_thread_join(wget_thread *thread);
1119 WGETAPI int
1120 	wget_thread_cond_init(wget_thread_cond *cond);
1121 WGETAPI int
1122 	wget_thread_cond_destroy(wget_thread_cond *cond);
1123 WGETAPI int
1124 	wget_thread_cond_signal(wget_thread_cond cond);
1125 WGETAPI int
1126 	wget_thread_cond_wait(wget_thread_cond cond, wget_thread_mutex mutex, long long ms);
1127 WGETAPI wget_thread_id
1128 	wget_thread_self(void) WGET_GCC_CONST;
1129 WGETAPI bool
1130 	wget_thread_support(void) WGET_GCC_CONST;
1131 
1132 /*
1133  * Decompressor routines
1134  */
1135 
1136 typedef struct wget_decompressor_st wget_decompressor;
1137 typedef int wget_decompressor_sink_fn(void *context, const char *data, size_t length);
1138 typedef int wget_decompressor_error_handler(wget_decompressor *dc, int err);
1139 
1140 typedef enum {
1141 	wget_content_encoding_unknown = -1,
1142 	wget_content_encoding_identity = 0,
1143 	wget_content_encoding_gzip = 1,
1144 	wget_content_encoding_deflate = 2,
1145 	wget_content_encoding_xz = 3,
1146 	wget_content_encoding_lzma = 4,
1147 	wget_content_encoding_bzip2 = 5,
1148 	wget_content_encoding_brotli = 6,
1149 	wget_content_encoding_zstd = 7,
1150 	wget_content_encoding_lzip = 8,
1151 	wget_content_encoding_max = 9
1152 } wget_content_encoding;
1153 
1154 WGETAPI WGET_GCC_PURE wget_content_encoding
1155 	wget_content_encoding_by_name(const char *name);
1156 WGETAPI WGET_GCC_PURE const char * NULLABLE
1157 	wget_content_encoding_to_name(wget_content_encoding type);
1158 WGETAPI wget_decompressor * NULLABLE
1159 	wget_decompress_open(wget_content_encoding encoding, wget_decompressor_sink_fn *data_sink, void *context);
1160 WGETAPI void
1161 	wget_decompress_close(wget_decompressor *dc);
1162 WGETAPI int
1163 	wget_decompress(wget_decompressor *dc, const char *src, size_t srclen);
1164 WGETAPI void
1165 	wget_decompress_set_error_handler(wget_decompressor *dc, wget_decompressor_error_handler *error_handler);
1166 WGETAPI void * NULLABLE
1167 	wget_decompress_get_context(wget_decompressor *dc);
1168 
1169 /*
1170  * URI/IRI routines
1171  */
1172 
1173 typedef enum {
1174 	WGET_IRI_SCHEME_HTTP = 0,
1175 	WGET_IRI_SCHEME_HTTPS = 1
1176 } wget_iri_scheme;
1177 
1178 // flags for wget_iri_get_basename()
1179 #define WGET_IRI_WITH_QUERY  1
1180 
1181 /**
1182  * \ingroup libwget-iri
1183  *
1184  * @{
1185  *
1186  * Internal representation of a URI/IRI.
1187  */
1188 struct wget_iri_st {
1189 	/**
1190 	 * Pointer to the original URI string, unescaped and converted to UTF-8.
1191 	 */
1192 	const char *
1193 		uri;
1194 	/**
1195 	 * Display part, if present.
1196 	 */
1197 	const char *
1198 		display;
1199 	/**
1200 	 * Username, if present.
1201 	 */
1202 	const char *
1203 		userinfo;
1204 	/**
1205 	 * Password, if present.
1206 	 */
1207 	const char *
1208 		password;
1209 	/**
1210 	 * Hostname (or literal IP address). Lowercase and unescaped.
1211 	 */
1212 	const char *
1213 		host;
1214 	/**
1215 	 * Path, if present. Unescaped.
1216 	 */
1217 	const char *
1218 		path;
1219 	/**
1220 	 * Query part, if present. Unescaped.
1221 	 */
1222 	const char *
1223 		query;
1224 	/**
1225 	 * Fragment part, if present. Unescaped.
1226 	 */
1227 	const char *
1228 		fragment;
1229 	/**
1230 	 * Connection part. This is not specified by the spec, it's just a helper.
1231 	 *
1232 	 * The connection part is formed by the scheme, the hostname and the port together. Example:
1233 	 *
1234 	 *     https://www.example.com:8080
1235 	 *
1236 	 */
1237 	const char *
1238 		connection_part;
1239 	/**
1240 	 * Length of the directory part in `path`.
1241 	 *
1242 	 * This is the length from the beginning up to the last slash (`/`).
1243 	 */
1244 	size_t
1245 		dirlen;
1246 	/// size of memory to hold the parsed URI, it contains 0 bytes
1247 	size_t
1248 		msize;
1249 	/// Port number
1250 	uint16_t
1251 		port;
1252 	/// URI/IRI scheme (`http` or `https`).
1253 	wget_iri_scheme
1254 		scheme;
1255 	/// If set, port was explicitly given
1256 	bool
1257 		port_given : 1;
1258 	/// If set, free uri in iri_free()
1259 	bool
1260 		uri_allocated : 1;
1261 	/// If set, free host in iri_free()
1262 	bool
1263 		host_allocated : 1;
1264 	/// If set, free path in iri_free()
1265 	bool
1266 		path_allocated : 1;
1267 	/// If set, free query in iri_free()
1268 	bool
1269 		query_allocated : 1;
1270 	/// If set, free fragment in iri_free()
1271 	bool
1272 		fragment_allocated : 1;
1273 	/// If set, the hostname part is a literal IPv4/IPv6 address
1274 	bool
1275 		is_ip_address : 1;
1276 };
1277 
1278 typedef struct wget_iri_st wget_iri;
1279 /** @} */
1280 
1281 WGETAPI void
1282 	wget_iri_test(void);
1283 WGETAPI void
1284 	wget_iri_free(wget_iri **iri);
1285 WGETAPI void
1286 	wget_iri_free_content(wget_iri *iri);
1287 WGETAPI void
1288 	wget_iri_set_defaultpage(const char *page);
1289 WGETAPI int
1290 	wget_iri_set_defaultport(wget_iri_scheme scheme, unsigned short port);
1291 WGETAPI bool
1292 	wget_iri_supported(const wget_iri *iri) WGET_GCC_PURE WGET_GCC_NONNULL_ALL;
1293 WGETAPI bool
1294 	wget_iri_isgendelim(char c) WGET_GCC_CONST;
1295 WGETAPI bool
1296 	wget_iri_issubdelim(char c) WGET_GCC_CONST;
1297 WGETAPI bool
1298 	wget_iri_isreserved(char c) WGET_GCC_CONST;
1299 WGETAPI bool
1300 	wget_iri_isunreserved(char c) WGET_GCC_CONST;
1301 WGETAPI int
1302 	wget_iri_compare(wget_iri *iri1, wget_iri *iri2) WGET_GCC_PURE;
1303 WGETAPI char *
1304 	wget_iri_unescape_inline(char *src) WGET_GCC_NONNULL_ALL;
1305 WGETAPI char *
1306 	wget_iri_unescape_url_inline(char *src) WGET_GCC_NONNULL_ALL;
1307 WGETAPI wget_iri *
1308 	wget_iri_parse(const char *uri, const char *encoding);
1309 WGETAPI wget_iri * NULLABLE
1310 	wget_iri_parse_base(const wget_iri *base, const char *url, const char *encoding);
1311 WGETAPI wget_iri * NULLABLE
1312 	wget_iri_clone(const wget_iri *iri);
1313 WGETAPI const char * NULLABLE
1314 	wget_iri_get_connection_part(const wget_iri *iri, wget_buffer *buf);
1315 WGETAPI const char *
1316 	wget_iri_relative_to_abs(const wget_iri *base, const char *val, size_t len, wget_buffer *buf);
1317 WGETAPI const char *
1318 	wget_iri_escape(const char *src, wget_buffer *buf);
1319 WGETAPI const char *
1320 	wget_iri_escape_path(const char *src, wget_buffer *buf) WGET_GCC_NONNULL_ALL;
1321 WGETAPI const char *
1322 	wget_iri_escape_query(const char *src, wget_buffer *buf) WGET_GCC_NONNULL_ALL;
1323 WGETAPI const char *
1324 	wget_iri_get_escaped_host(const wget_iri *iri, wget_buffer *buf) WGET_GCC_NONNULL_ALL;
1325 WGETAPI const char *
1326 	wget_iri_get_escaped_resource(const wget_iri *iri, wget_buffer *buf) WGET_GCC_NONNULL_ALL;
1327 WGETAPI char *
1328 	wget_iri_get_path(const wget_iri *iri, wget_buffer *buf, const char *encoding) WGET_GCC_NONNULL((1,2));
1329 WGETAPI char *
1330 	wget_iri_get_query_as_filename(const wget_iri *iri, wget_buffer *buf, const char *encoding) WGET_GCC_NONNULL((1,2));
1331 WGETAPI char *
1332 	wget_iri_get_basename(const wget_iri *iri, wget_buffer *buf, const char *encoding, int flags) WGET_GCC_NONNULL((1,2));
1333 WGETAPI wget_iri_scheme
1334 	wget_iri_set_scheme(wget_iri *iri, wget_iri_scheme scheme);
1335 WGETAPI const char * NULLABLE
1336 	wget_iri_scheme_get_name(wget_iri_scheme scheme);
1337 
1338 /*
1339  * Cookie routines
1340  */
1341 
1342 // typedef for cookie database
1343 typedef struct wget_cookie_db_st wget_cookie_db;
1344 
1345 // typedef for cookie
1346 typedef struct wget_cookie_st wget_cookie;
1347 
1348 WGETAPI wget_cookie * NULLABLE
1349 	wget_cookie_init(wget_cookie *cookie);
1350 WGETAPI void
1351 	wget_cookie_deinit(wget_cookie *cookie);
1352 WGETAPI void
1353 	wget_cookie_free(wget_cookie **cookie);
1354 WGETAPI char *
1355 	wget_cookie_to_setcookie(wget_cookie *cookie);
1356 WGETAPI const char *
1357 	wget_cookie_parse_setcookie(const char *s, wget_cookie **cookie) WGET_GCC_NONNULL((1));
1358 WGETAPI void
1359 	wget_cookie_normalize_cookies(const wget_iri *iri, const wget_vector *cookies);
1360 WGETAPI int
1361 	wget_cookie_store_cookie(wget_cookie_db *cookie_db, wget_cookie *cookie);
1362 WGETAPI void
1363 	wget_cookie_store_cookies(wget_cookie_db *cookie_db, wget_vector *cookies);
1364 WGETAPI int
1365 	wget_cookie_normalize(const wget_iri *iri, wget_cookie *cookie);
1366 WGETAPI int
1367 	wget_cookie_check_psl(const wget_cookie_db *cookie_db, const wget_cookie *cookie);
1368 WGETAPI wget_cookie_db * NULLABLE
1369 	wget_cookie_db_init(wget_cookie_db *cookie_db);
1370 WGETAPI void
1371 	wget_cookie_db_deinit(wget_cookie_db *cookie_db);
1372 WGETAPI void
1373 	wget_cookie_db_free(wget_cookie_db **cookie_db);
1374 WGETAPI void
1375 	wget_cookie_set_keep_session_cookies(wget_cookie_db *cookie_db, bool keep);
1376 WGETAPI int
1377 	wget_cookie_db_save(wget_cookie_db *cookie_db, const char *fname);
1378 WGETAPI int
1379 	wget_cookie_db_load(wget_cookie_db *cookie_db, const char *fname);
1380 WGETAPI int
1381 	wget_cookie_db_load_psl(wget_cookie_db *cookie_db, const char *fname);
1382 WGETAPI char *
1383 	wget_cookie_create_request_header(wget_cookie_db *cookie_db, const wget_iri *iri);
1384 
1385 /*
1386  * HTTP Strict Transport Security (HSTS) routines
1387  */
1388 
1389 /**
1390  * \ingroup libwget-hsts
1391  *
1392  * Structure representing HSTS database for storing HTTP Strict Transport Security (HSTS) entries
1393  */
1394 typedef struct wget_hsts_db_st wget_hsts_db;
1395 
1396 /**
1397  * \ingroup libwget-hsts
1398  *
1399  * It is possible to implement a custom HSTS database as a plugin.
1400  * See tests/test-plugin-dummy.c and tests/Makefile.am for details.
1401  */
1402 
1403 typedef int wget_hsts_host_match_fn(const wget_hsts_db *hsts_db, const char *host, uint16_t port);
1404 typedef wget_hsts_db *wget_hsts_db_init_fn(wget_hsts_db *hsts_db, const char *fname);
1405 typedef void wget_hsts_db_deinit_fn(wget_hsts_db *hsts_db);
1406 typedef void wget_hsts_db_free_fn(wget_hsts_db **hsts_db);
1407 typedef void wget_hsts_db_add_fn(wget_hsts_db *hsts_db, const char *host, uint16_t port, int64_t maxage, bool include_subdomains);
1408 typedef int wget_hsts_db_save_fn(wget_hsts_db *hsts_db);
1409 typedef int wget_hsts_db_load_fn(wget_hsts_db *hsts_db);
1410 typedef void wget_hsts_db_set_fname_fn(wget_hsts_db *hsts_db, const char *fname);
1411 
1412 typedef struct {
1413 	/// Callback replacing wget_hsts_host_match()
1414 	wget_hsts_host_match_fn *host_match;
1415 	/// Callback replacing wget_hsts_db_init()
1416 	wget_hsts_db_init_fn *init;
1417 	/// Callback replacing wget_hsts_db_deinit()
1418 	wget_hsts_db_deinit_fn *deinit;
1419 	/// Callback replacing wget_hsts_db_free()
1420 	wget_hsts_db_free_fn *free;
1421 	/// Callback replacing wget_hsts_db_add()
1422 	wget_hsts_db_add_fn *add;
1423 	/// Callback replacing wget_hsts_db_load()
1424 	wget_hsts_db_load_fn *load;
1425 	/// Callback replacing wget_hsts_db_save()
1426 	wget_hsts_db_save_fn *save;
1427 } wget_hsts_db_vtable;
1428 
1429 WGETAPI wget_hsts_host_match_fn wget_hsts_host_match;
1430 WGETAPI wget_hsts_db_init_fn wget_hsts_db_init;
1431 WGETAPI wget_hsts_db_deinit_fn wget_hsts_db_deinit;
1432 WGETAPI wget_hsts_db_free_fn wget_hsts_db_free;
1433 WGETAPI wget_hsts_db_add_fn wget_hsts_db_add;
1434 WGETAPI wget_hsts_db_load_fn wget_hsts_db_load;
1435 WGETAPI wget_hsts_db_save_fn wget_hsts_db_save;
1436 WGETAPI void
1437 	wget_hsts_db_set_fname(wget_hsts_db *hsts_db, const char *fname);
1438 WGETAPI void
1439 	wget_hsts_set_plugin(const wget_hsts_db_vtable *vtable);
1440 
1441 /*
1442  * HTTP Public Key Pinning (HPKP)
1443  */
1444 
1445 /**
1446  * \ingroup libwget-hpkp
1447  *
1448  * HPKP database for storing HTTP Public Key Pinning (HPKP) entries
1449  */
1450 typedef struct wget_hpkp_db_st wget_hpkp_db;
1451 
1452 /**
1453  * \ingroup libwget-hpkp
1454  *
1455  * HPKP database entry. Corresponds to one 'Public-Key-Pins' HTTP response header.
1456  */
1457 typedef struct wget_hpkp_st wget_hpkp;
1458 
1459 /* FIXME: the following entries are not used. review the hpkp function return values ! */
1460 /**
1461  * \addtogroup libwget-hpkp
1462  *
1463  * @{
1464  */
1465 /// Success
1466 #define WGET_HPKP_OK			 0
1467 /// General error
1468 #define WGET_HPKP_ERROR			-1
1469 /// The HPKP entry is expired
1470 #define WGET_HPKP_ENTRY_EXPIRED		-2
1471 /// The HPKP entry was deleted
1472 #define WGET_HPKP_WAS_DELETED		-3
1473 /// The entry doesn't have enough PINs
1474 #define WGET_HPKP_NOT_ENOUGH_PINS	-4
1475 /// The entry already exists
1476 #define WGET_HPKP_ENTRY_EXISTS		-5
1477 /// Failed to open a file
1478 #define WGET_HPKP_ERROR_FILE_OPEN	-6
1479 /** @} */
1480 
1481 /**
1482  * \ingroup libwget-hpkp
1483  *
1484  * It is possible to implement a custom HPKP database as a plugin.
1485  * See tests/test-plugin-dummy.c and tests/Makefile.am for details.
1486  */
1487 
1488 typedef wget_hpkp_db *wget_hpkp_db_init_fn(wget_hpkp_db *hpkp_db, const char *fname);
1489 typedef void wget_hpkp_db_deinit_fn(wget_hpkp_db *hpkp_db);
1490 typedef void wget_hpkp_db_free_fn(wget_hpkp_db **hpkp_db);
1491 typedef int wget_hpkp_db_check_pubkey_fn(wget_hpkp_db *hpkp_db, const char *host, const void *pubkey, size_t pubkeysize);
1492 typedef void wget_hpkp_db_add_fn(wget_hpkp_db *hpkp_db, wget_hpkp **hpkp);
1493 typedef int wget_hpkp_db_load_fn(wget_hpkp_db *hpkp_db);
1494 typedef int wget_hpkp_db_save_fn(wget_hpkp_db *hpkp_db);
1495 
1496 typedef struct {
1497 	/// Callback replacing \ref wget_hpkp_db_free "wget_hpkp_db_free()"
1498 	wget_hpkp_db_init_fn *init;
1499 	/// Callback replacing \ref wget_hpkp_db_free "wget_hpkp_db_free()"
1500 	wget_hpkp_db_deinit_fn *deinit;
1501 	/// Callback replacing \ref wget_hpkp_db_free "wget_hpkp_db_free()"
1502 	wget_hpkp_db_free_fn *free;
1503 	/// Callback replacing \ref wget_hpkp_db_check_pubkey "wget_hpkp_db_check_pubkey()"
1504 	wget_hpkp_db_check_pubkey_fn *check_pubkey;
1505 	/// Callback replacing \ref wget_hpkp_db_add "wget_hpkp_db_add()"
1506 	wget_hpkp_db_add_fn *add;
1507 	/// Callback replacing \ref wget_hpkp_db_load "wget_hpkp_db_load()"
1508 	wget_hpkp_db_load_fn *load;
1509 	/// Callback replacing \ref wget_hpkp_db_save "wget_hpkp_db_save()"
1510 	wget_hpkp_db_save_fn *save;
1511 } wget_hpkp_db_vtable;
1512 
1513 WGETAPI wget_hpkp * NULLABLE
1514 	wget_hpkp_new(void);
1515 WGETAPI void
1516 	wget_hpkp_free(wget_hpkp *hpkp);
1517 WGETAPI void
1518 	wget_hpkp_pin_add(wget_hpkp *hpkp, const char *pin_type, const char *pin_b64);
1519 WGETAPI void
1520 	wget_hpkp_set_host(wget_hpkp *hpkp, const char *host);
1521 WGETAPI void
1522 	wget_hpkp_set_maxage(wget_hpkp *hpkp, int64_t maxage);
1523 WGETAPI void
1524 	wget_hpkp_set_include_subdomains(wget_hpkp *hpkp, bool include_subdomains);
1525 WGETAPI int
1526 	wget_hpkp_get_n_pins(wget_hpkp *hpkp);
1527 WGETAPI void
1528 	wget_hpkp_get_pins_b64(wget_hpkp *hpkp, const char **pin_types, const char **pins_b64);
1529 WGETAPI void
1530 	wget_hpkp_get_pins(wget_hpkp *hpkp, const char **pin_types, size_t *sizes, const void **pins);
1531 WGETAPI const char *
1532 	wget_hpkp_get_host(wget_hpkp *hpkp);
1533 WGETAPI int64_t
1534 	wget_hpkp_get_maxage(wget_hpkp *hpkp);
1535 WGETAPI bool
1536 	wget_hpkp_get_include_subdomains(wget_hpkp *hpkp);
1537 
1538 WGETAPI wget_hpkp_db_init_fn wget_hpkp_db_init;
1539 WGETAPI wget_hpkp_db_deinit_fn wget_hpkp_db_deinit;
1540 WGETAPI wget_hpkp_db_free_fn wget_hpkp_db_free;
1541 WGETAPI wget_hpkp_db_check_pubkey_fn wget_hpkp_db_check_pubkey;
1542 WGETAPI wget_hpkp_db_add_fn wget_hpkp_db_add;
1543 WGETAPI wget_hpkp_db_load_fn wget_hpkp_db_load;
1544 WGETAPI wget_hpkp_db_save_fn wget_hpkp_db_save;
1545 WGETAPI void
1546 	wget_hpkp_db_set_fname(wget_hpkp_db *hpkp_db, const char *fname);
1547 WGETAPI void
1548 	wget_hpkp_set_plugin(const wget_hpkp_db_vtable *vtable);
1549 
1550 /*
1551  * TLS session resumption
1552  */
1553 
1554 // structure for TLS resumption cache entries
1555 typedef struct wget_tls_session_st wget_tls_session;
1556 typedef struct wget_tls_session_db_st wget_tls_session_db;
1557 
1558 WGETAPI wget_tls_session * NULLABLE
1559 	wget_tls_session_init(wget_tls_session *tls_session);
1560 WGETAPI void
1561 	wget_tls_session_deinit(wget_tls_session *tls_session);
1562 WGETAPI void
1563 	wget_tls_session_free(wget_tls_session *tls_session);
1564 WGETAPI wget_tls_session * NULLABLE
1565 	wget_tls_session_new(const char *host, int64_t maxage, const void *data, size_t data_size);
1566 WGETAPI int
1567 	wget_tls_session_get(const wget_tls_session_db *tls_session_db, const char *host, void **data, size_t *size);
1568 WGETAPI wget_tls_session_db * NULLABLE
1569 	wget_tls_session_db_init(wget_tls_session_db *tls_session_db);
1570 WGETAPI void
1571 	wget_tls_session_db_deinit(wget_tls_session_db *tls_session_db);
1572 WGETAPI void
1573 	wget_tls_session_db_free(wget_tls_session_db **tls_session_db);
1574 WGETAPI void
1575 	wget_tls_session_db_add(wget_tls_session_db *tls_session_db, wget_tls_session *tls_session);
1576 WGETAPI int
1577 	wget_tls_session_db_save(wget_tls_session_db *tls_session_db, const char *fname);
1578 WGETAPI int
1579 	wget_tls_session_db_load(wget_tls_session_db *tls_session_db, const char *fname);
1580 WGETAPI int
1581 	wget_tls_session_db_changed(wget_tls_session_db *tls_session_db) WGET_GCC_PURE;
1582 
1583 /*
1584  * Online Certificate Status Protocol (OCSP) routines
1585  */
1586 
1587 /**
1588  * \ingroup libwget-ocsp
1589  *
1590  * structure for Online Certificate Status Protocol (OCSP) entries
1591  */
1592 typedef struct wget_ocsp_db_st wget_ocsp_db;
1593 
1594 /**
1595  * \ingroup libwget-ocsp
1596  *
1597  * It is possible to implement a custom OCSP database as a plugin.
1598  * See tests/test-plugin-dummy.c and tests/Makefile.am for details.
1599  */
1600 
1601 typedef wget_ocsp_db *wget_ocsp_db_init_fn(wget_ocsp_db *ocsp_db, const char *fname);
1602 typedef void wget_ocsp_db_deinit_fn(wget_ocsp_db *ocsp_db);
1603 typedef void wget_ocsp_db_free_fn(wget_ocsp_db **ocsp_db);
1604 typedef bool wget_ocsp_fingerprint_in_cache_fn(const wget_ocsp_db *ocsp_db, const char *fingerprint, int *valid);
1605 typedef bool wget_ocsp_hostname_is_valid_fn(const wget_ocsp_db *ocsp_db, const char *hostname);
1606 typedef void wget_ocsp_db_add_fingerprint_fn(wget_ocsp_db *ocsp_db, const char *fingerprint, int64_t maxage, bool valid);
1607 typedef void wget_ocsp_db_add_host_fn(wget_ocsp_db *ocsp_db, const char *host, int64_t maxage);
1608 typedef int wget_ocsp_db_save_fn(wget_ocsp_db *ocsp_db);
1609 typedef int wget_ocsp_db_load_fn(wget_ocsp_db *ocsp_db);
1610 
1611 typedef struct {
1612 	/// Callback replacing wget_ocsp_db_free()
1613 	wget_ocsp_db_init_fn *init;
1614 	/// Callback replacing wget_ocsp_db_free()
1615 	wget_ocsp_db_deinit_fn *deinit;
1616 	/// Callback replacing wget_ocsp_db_free()
1617 	wget_ocsp_db_free_fn *free;
1618 	/// Callback replacing wget_ocsp_db_fingerprint_in_cache()
1619 	wget_ocsp_fingerprint_in_cache_fn *fingerprint_in_cache;
1620 	/// Callback replacing wget_ocsp_db_hostname_is_valid()
1621 	wget_ocsp_hostname_is_valid_fn *hostname_is_valid;
1622 	/// Callback replacing wget_ocsp_db_add_fingerprint()
1623 	wget_ocsp_db_add_fingerprint_fn *add_fingerprint;
1624 	/// Callback replacing wget_ocsp_db_add_host()
1625 	wget_ocsp_db_add_host_fn *add_host;
1626 	/// Callback replacing wget_ocsp_db_load()
1627 	wget_ocsp_db_save_fn *load;
1628 	/// Callback replacing wget_ocsp_db_save()
1629 	wget_ocsp_db_load_fn *save;
1630 } wget_ocsp_db_vtable;
1631 
1632 WGETAPI wget_ocsp_db_init_fn wget_ocsp_db_init;
1633 WGETAPI wget_ocsp_db_deinit_fn wget_ocsp_db_deinit;
1634 WGETAPI wget_ocsp_db_free_fn wget_ocsp_db_free;
1635 WGETAPI wget_ocsp_fingerprint_in_cache_fn wget_ocsp_fingerprint_in_cache;
1636 WGETAPI wget_ocsp_hostname_is_valid_fn wget_ocsp_hostname_is_valid;
1637 WGETAPI wget_ocsp_db_add_fingerprint_fn wget_ocsp_db_add_fingerprint;
1638 WGETAPI wget_ocsp_db_add_host_fn wget_ocsp_db_add_host;
1639 WGETAPI wget_ocsp_db_save_fn wget_ocsp_db_save;
1640 WGETAPI wget_ocsp_db_load_fn wget_ocsp_db_load;
1641 WGETAPI void
1642 	wget_ocsp_db_set_fname(wget_ocsp_db *ocsp_db, const char *fname);
1643 WGETAPI void
1644 	wget_ocsp_set_plugin(const wget_ocsp_db_vtable *vtable);
1645 
1646 /*
1647  * .netrc routines
1648  */
1649 
1650 /**
1651  *  container for .netrc entries
1652  */
1653 typedef struct wget_netrc_db_st wget_netrc_db;
1654 
1655 /**
1656  *  structure for a single .netrc entry
1657  *
1658  * The GNU extensions are described at
1659  *   https://www.gnu.org/software/emacs/manual/html_node/gnus/NNTP.html.
1660  */
1661 struct wget_netrc_st {
1662 	const char *
1663 		host;      //!< hostname/domain/ip
1664 	const char *
1665 		login;     //!< login/username for the host
1666 	const char *
1667 		password;  //!< password for the host
1668 	uint16_t
1669 		port;      //!< GNU extension: port number
1670 	bool
1671 		force : 1; //!< GNU extension: unused
1672 };
1673 typedef struct wget_netrc_st wget_netrc;
1674 
1675 WGETAPI wget_netrc * NULLABLE
1676 	wget_netrc_init(wget_netrc *netrc);
1677 WGETAPI void
1678 	wget_netrc_deinit(wget_netrc *netrc);
1679 WGETAPI void
1680 	wget_netrc_free(wget_netrc *netrc);
1681 WGETAPI wget_netrc * NULLABLE
1682 	wget_netrc_new(const char *machine, const char *login, const char *password);
1683 WGETAPI wget_netrc_db *
1684 	wget_netrc_db_init(wget_netrc_db *netrc_db);
1685 WGETAPI void
1686 	wget_netrc_db_deinit(wget_netrc_db *netrc_db);
1687 WGETAPI void
1688 	wget_netrc_db_free(wget_netrc_db **netrc_db);
1689 WGETAPI void
1690 	wget_netrc_db_add(wget_netrc_db *netrc_db, wget_netrc *netrc);
1691 WGETAPI wget_netrc * NULLABLE
1692 	wget_netrc_get(const wget_netrc_db *netrc_db, const char *host);
1693 WGETAPI int
1694 	wget_netrc_db_load(wget_netrc_db *netrc_db, const char *fname);
1695 
1696 /*
1697  * CSS parsing routines
1698  */
1699 
1700 struct wget_css_parsed_url_st {
1701 	size_t
1702 		len; //!< length of found URL
1703 	size_t
1704 		pos; //!< position of found URL within the scanned CSS data
1705 	const char *
1706 		url; //!< zero-terminated copy the found URL
1707 	const char *
1708 		abs_url; //!< the found URL converted into an absolute URL
1709 };
1710 typedef struct wget_css_parsed_url_st wget_css_parsed_url;
1711 
1712 typedef void wget_css_parse_uri_callback(void *user_ctx, const char *url, size_t len, size_t pos);
1713 typedef void wget_css_parse_encoding_callback(void *user_ctx, const char *url, size_t len);
1714 
1715 WGETAPI void
1716 	wget_css_parse_buffer(
1717 		const char *buf,
1718 		size_t len,
1719 		wget_css_parse_uri_callback *callback_uri,
1720 		wget_css_parse_encoding_callback *callback_encoding,
1721 		void *user_ctx) WGET_GCC_NONNULL((1));
1722 WGETAPI void
1723 	wget_css_parse_file(
1724 		const char *fname,
1725 		wget_css_parse_uri_callback *callback_uri,
1726 		wget_css_parse_encoding_callback *callback_encoding,
1727 		void *user_ctx) WGET_GCC_NONNULL((1));
1728 WGETAPI wget_vector *
1729 	wget_css_get_urls(
1730 		const char *css,
1731 		size_t len,
1732 		wget_iri *base,
1733 		const char **encoding) WGET_GCC_NONNULL((1));
1734 WGETAPI wget_vector *
1735 	wget_css_get_urls_from_localfile(
1736 		const char *fname,
1737 		wget_iri *base,
1738 		const char **encoding) WGET_GCC_NONNULL((1));
1739 
1740 typedef struct {
1741 	const char
1742 		*p; //!< pointer to memory region
1743 	size_t
1744 		len; //!< length of memory region
1745 } wget_string;
1746 
1747 typedef struct {
1748 	wget_string
1749 		url; //!< URL within the parsed document (pointer and length)
1750 	wget_string
1751 		download; //!< Value of additional 'download' attribute, the name to be saved to disk
1752 	char
1753 		attr[16]; //!< name of the attribute containing the URL, e.g. 'href'
1754 	char
1755 		tag[16]; //!< name of the HTML tag containing the URL, e.g. 'a'
1756 	bool
1757 		link_inline : 1; //!< 1 = rel was 'stylesheet' or 'shortcut icon'
1758 } wget_html_parsed_url;
1759 
1760 typedef struct {
1761 	wget_vector
1762 		*uris; //!< list of found URLs (entries: wget_html_parsed_url)
1763 	const char *
1764 		encoding; //!< the charset encoding set by the parsed document or NULL if none
1765 	wget_string
1766 		base; //!< the BASE set in the document or NULL if none
1767 	bool
1768 		follow : 1; //!< if the 'follow' attribute was found in a META tag
1769 } wget_html_parsed_result;
1770 
1771 /**
1772  * HTML tag consisting of name and an optional attribute
1773  */
1774 typedef struct {
1775 	const char *
1776 		name; //!< name of HTML tag
1777 	const char *
1778 		attribute; //!< attribute of the HTML tag
1779 } wget_html_tag;
1780 
1781 WGETAPI wget_html_parsed_result * NULLABLE
1782 	wget_html_get_urls_inline(const char *html, wget_vector *additional_tags, wget_vector *ignore_tags);
1783 WGETAPI void
1784 	wget_html_free_urls_inline(wget_html_parsed_result **res);
1785 WGETAPI void
1786 	wget_sitemap_get_urls_inline(const char *sitemap, wget_vector **urls, wget_vector **sitemap_urls);
1787 WGETAPI void
1788 	wget_atom_get_urls_inline(const char *atom, wget_vector **urls);
1789 WGETAPI void
1790 	wget_rss_get_urls_inline(const char *rss, wget_vector **urls);
1791 
1792 /*
1793  * XML and HTML parsing routines
1794  */
1795 
1796 #define XML_FLG_BEGIN      (1<<0) // <
1797 #define XML_FLG_CLOSE      (1<<1) // >
1798 #define XML_FLG_END        (1<<2) // </elem>
1799 #define XML_FLG_ATTRIBUTE  (1<<3) // attr="value"
1800 #define XML_FLG_CONTENT    (1<<4)
1801 #define XML_FLG_COMMENT    (1<<5) // <!-- ... -->
1802 //#define XML_FLG_CDATA      (1<<6) // <![CDATA[...]]>, now same handling as 'special'
1803 #define XML_FLG_PROCESSING (1<<7) // e.g. <? ... ?>
1804 #define XML_FLG_SPECIAL    (1<<8) // e.g. <!DOCTYPE ...>
1805 
1806 #define XML_HINT_REMOVE_EMPTY_CONTENT (1<<0) // merge spaces, remove empty content
1807 #define XML_HINT_HTML                 (1<<1) // parse HTML instead of XML
1808 
1809 #define HTML_HINT_REMOVE_EMPTY_CONTENT XML_HINT_REMOVE_EMPTY_CONTENT
1810 
1811 typedef void wget_xml_callback(void *, int, const char *, const char *, const char *, size_t, size_t);
1812 
1813 WGETAPI int
1814 	wget_xml_parse_buffer(
1815 		const char *buf,
1816 		wget_xml_callback *callback,
1817 		void *user_ctx,
1818 		int hints) WGET_GCC_NONNULL((1));
1819 WGETAPI void
1820 	wget_xml_parse_file(
1821 		const char *fname,
1822 		wget_xml_callback *callback,
1823 		void *user_ctx,
1824 		int hints) WGET_GCC_NONNULL((1));
1825 WGETAPI void
1826 	wget_html_parse_buffer(
1827 		const char *buf,
1828 		wget_xml_callback *callback,
1829 		void *user_ctx,
1830 		int hints) WGET_GCC_NONNULL((1));
1831 WGETAPI void
1832 	wget_html_parse_file(
1833 		const char *fname,
1834 		wget_xml_callback *callback,
1835 		void *user_ctx,
1836 		int hints) WGET_GCC_NONNULL((1));
1837 
1838 /*
1839  * DNS caching routines
1840  */
1841 
1842 typedef struct wget_dns_cache_st wget_dns_cache;
1843 
1844 WGETAPI int
1845 	wget_dns_cache_init(wget_dns_cache **cache);
1846 WGETAPI void
1847 	wget_dns_cache_free(wget_dns_cache **cache);
1848 WGETAPI struct addrinfo * NULLABLE
1849 	wget_dns_cache_get(wget_dns_cache *cache, const char *host, uint16_t port);
1850 WGETAPI int
1851 	wget_dns_cache_add(wget_dns_cache *cache, const char *host, uint16_t port, struct addrinfo **addrinfo);
1852 
1853 /*
1854  * DNS resolving routines
1855  */
1856 
1857 typedef struct wget_dns_st wget_dns;
1858 
1859 WGETAPI int
1860 	wget_dns_init(wget_dns **dns);
1861 WGETAPI void
1862 	wget_dns_free(wget_dns **dns);
1863 WGETAPI void
1864 	wget_dns_set_timeout(wget_dns *dns, int timeout);
1865 WGETAPI void
1866 	wget_dns_set_cache(wget_dns *dns, wget_dns_cache *cache);
1867 WGETAPI wget_dns_cache * NULLABLE
1868 	wget_dns_get_cache(wget_dns *dns) WGET_GCC_PURE;
1869 WGETAPI struct addrinfo * NULLABLE
1870 	wget_dns_resolve(wget_dns *dns, const char *host, uint16_t port, int family, int preferred_family);
1871 WGETAPI void
1872 	wget_dns_freeaddrinfo(wget_dns *dns, struct addrinfo **addrinfo);
1873 WGETAPI int
1874 	wget_dns_cache_ip(wget_dns *dns, const char *ip, const char *name, uint16_t port);
1875 
1876 /*
1877  * TCP network routines
1878  */
1879 
1880 #define WGET_NET_FAMILY_ANY  0
1881 #define WGET_NET_FAMILY_IPV4 1
1882 #define WGET_NET_FAMILY_IPV6 2
1883 
1884 #define WGET_PROTOCOL_HTTP_1_1  0
1885 #define WGET_PROTOCOL_HTTP_2_0  1
1886 
1887 typedef struct wget_tcp_st wget_tcp;
1888 
1889 WGETAPI int
1890 	wget_net_init(void);
1891 WGETAPI int
1892 	wget_net_deinit(void);
1893 WGETAPI wget_tcp * NULLABLE
1894 	wget_tcp_init(void);
1895 WGETAPI void
1896 	wget_tcp_deinit(wget_tcp **tcp);
1897 WGETAPI void
1898 	wget_tcp_close(wget_tcp *tcp);
1899 WGETAPI void
1900 	wget_tcp_set_dns(wget_tcp *tcp, wget_dns *dns);
1901 WGETAPI void
1902 	wget_tcp_set_timeout(wget_tcp *tcp, int timeout);
1903 WGETAPI int
1904 	wget_tcp_get_timeout(wget_tcp *tcp) WGET_GCC_PURE;
1905 WGETAPI void
1906 	wget_tcp_set_connect_timeout(wget_tcp *tcp, int timeout);
1907 WGETAPI void
1908 	wget_tcp_set_tcp_fastopen(wget_tcp *tcp, bool tcp_fastopen);
1909 WGETAPI void
1910 	wget_tcp_set_tls_false_start(wget_tcp *tcp, bool false_start);
1911 WGETAPI void
1912 	wget_tcp_set_ssl(wget_tcp *tcp, bool ssl);
1913 WGETAPI bool
1914 	wget_tcp_get_ssl(wget_tcp *tcp) WGET_GCC_PURE;
1915 WGETAPI const char * NULLABLE
1916 	wget_tcp_get_ip(wget_tcp *tcp) WGET_GCC_PURE;
1917 WGETAPI void
1918 	wget_tcp_set_ssl_hostname(wget_tcp *tcp, const char *hostname);
1919 WGETAPI const char *
1920 	wget_tcp_get_ssl_hostname(wget_tcp *tcp) WGET_GCC_PURE;
1921 WGETAPI void
1922 	wget_tcp_set_ssl_ca_file(wget_tcp *tcp, const char *cafile);
1923 WGETAPI void
1924 	wget_tcp_set_ssl_key_file(wget_tcp *tcp, const char *certfile, const char *keyfile);
1925 WGETAPI bool
1926 	wget_tcp_get_tcp_fastopen(wget_tcp *tcp) WGET_GCC_PURE;
1927 WGETAPI bool
1928 	wget_tcp_get_tls_false_start(wget_tcp *tcp) WGET_GCC_PURE;
1929 WGETAPI int
1930 	wget_tcp_get_family(wget_tcp *tcp) WGET_GCC_PURE;
1931 WGETAPI int
1932 	wget_tcp_get_preferred_family(wget_tcp *tcp) WGET_GCC_PURE;
1933 WGETAPI int
1934 	wget_tcp_get_protocol(wget_tcp *tcp) WGET_GCC_PURE;
1935 WGETAPI int
1936 	wget_tcp_get_local_port(wget_tcp *tcp);
1937 WGETAPI void
1938 	wget_tcp_set_debug(wget_tcp *tcp, int debug);
1939 WGETAPI void
1940 	wget_tcp_set_family(wget_tcp *tcp, int family);
1941 WGETAPI void
1942 	wget_tcp_set_preferred_family(wget_tcp *tcp, int family);
1943 WGETAPI void
1944 	wget_tcp_set_protocol(wget_tcp *tcp, int protocol);
1945 WGETAPI void
1946 	wget_tcp_set_bind_address(wget_tcp *tcp, const char *bind_address);
1947 WGETAPI void
1948 	wget_tcp_set_bind_interface(wget_tcp *tcp, const char *bind_interface);
1949 WGETAPI int
1950 	wget_tcp_connect(wget_tcp *tcp, const char *host, uint16_t port);
1951 WGETAPI int
1952 	wget_tcp_tls_start(wget_tcp *tcp);
1953 WGETAPI void
1954 	wget_tcp_tls_stop(wget_tcp *tcp);
1955 WGETAPI ssize_t
1956 	wget_tcp_vprintf(wget_tcp *tcp, const char *restrict fmt, va_list args) WGET_GCC_PRINTF_FORMAT(2,0);
1957 WGETAPI ssize_t
1958 	wget_tcp_printf(wget_tcp *tcp, const char *restrict fmt, ...) WGET_GCC_PRINTF_FORMAT(2,3);
1959 WGETAPI ssize_t
1960 	wget_tcp_write(wget_tcp *tcp, const char *buf, size_t count);
1961 WGETAPI ssize_t
1962 	wget_tcp_read(wget_tcp *tcp, char *buf, size_t count);
1963 WGETAPI int
1964 	wget_tcp_ready_2_transfer(wget_tcp *tcp, int flags);
1965 
1966 WGETAPI bool
1967 	wget_ip_is_family(const char *host, int family) WGET_GCC_PURE;
1968 
1969 /*
1970  * SSL routines
1971  */
1972 
1973 #define WGET_SSL_X509_FMT_PEM 0
1974 #define WGET_SSL_X509_FMT_DER 1
1975 
1976 #define WGET_SSL_SECURE_PROTOCOL   1
1977 #define WGET_SSL_CA_DIRECTORY      2
1978 #define WGET_SSL_CA_FILE           3
1979 #define WGET_SSL_CERT_FILE         4
1980 #define WGET_SSL_KEY_FILE          5
1981 #define WGET_SSL_CA_TYPE           6
1982 #define WGET_SSL_CERT_TYPE         7
1983 #define WGET_SSL_KEY_TYPE          8
1984 #define WGET_SSL_CHECK_CERTIFICATE 9
1985 #define WGET_SSL_CHECK_HOSTNAME    10
1986 #define WGET_SSL_PRINT_INFO        11
1987 #define WGET_SSL_CRL_FILE          13
1988 #define WGET_SSL_OCSP_STAPLING     14
1989 #define WGET_SSL_OCSP_SERVER       15
1990 #define WGET_SSL_OCSP              16
1991 #define WGET_SSL_OCSP_CACHE        17
1992 #define WGET_SSL_ALPN              18
1993 #define WGET_SSL_SESSION_CACHE     19
1994 #define WGET_SSL_HPKP_CACHE     20
1995 #define WGET_SSL_OCSP_NONCE     21
1996 #define WGET_SSL_OCSP_DATE      22
1997 
1998 WGETAPI void
1999 	wget_ssl_init(void);
2000 WGETAPI void
2001 	wget_ssl_deinit(void);
2002 WGETAPI void
2003 	wget_ssl_set_config_string(int key, const char *value);
2004 WGETAPI void
2005 	wget_ssl_set_config_object(int key, void *value);
2006 WGETAPI void
2007 	wget_ssl_set_config_int(int key, int value);
2008 //WGETAPI void *
2009 //	wget_ssl_open(int sockfd, const char *hostname, int connect_timeout) G_GNUC_WGET_NONNULL((2));
2010 WGETAPI int
2011 	wget_ssl_open(wget_tcp *tcp);
2012 WGETAPI void
2013 	wget_ssl_close(void **session);
2014 WGETAPI void
2015 	wget_ssl_set_check_certificate(char value);
2016 WGETAPI ssize_t
2017 	wget_ssl_read_timeout(void *session, char *buf, size_t count, int timeout) WGET_GCC_NONNULL_ALL;
2018 WGETAPI ssize_t
2019 	wget_ssl_write_timeout(void *session, const char *buf, size_t count, int timeout) WGET_GCC_NONNULL_ALL;
2020 
2021 /*
2022  * HTTP routines
2023  */
2024 
2025 /**
2026  * Parsed name/value pair as often found in HTTP headers
2027  */
2028 typedef struct {
2029 	const char *
2030 		name; //!< name of the param
2031 	const char *
2032 		value; //!< value of the param (might be NULL)
2033 } wget_http_header_param;
2034 
2035 /**
2036  * Parsed Link HTTP header
2037  */
2038 typedef struct {
2039 	const char *
2040 		uri; //!< URI reference
2041 	const char *
2042 		type; //!< value of type param or NULL
2043 	int
2044 		pri; //!< value of pri param
2045 	enum {
2046 		link_rel_none = 0,
2047 		link_rel_describedby,
2048 		link_rel_duplicate
2049 	} rel; //!< value of 'rel' param, either none (if not found), 'describedby' or 'duplicate'
2050 } wget_http_link;
2051 
2052 /**
2053  * Parsed Digest HTTP header (RFC 3230)
2054  */
2055 typedef struct {
2056 	const char *
2057 		algorithm; //!< name of the digest, e.g. 'md5'
2058 	const char *
2059 		encoded_digest; //!< value of the digest
2060 } wget_http_digest;
2061 
2062 /**
2063  * Parsed WWW-Authenticate or Proxy-Authenticate HTTP header
2064  */
2065 typedef struct {
2066 	const char *
2067 		auth_scheme; //!< name of the challenge, e.g. 'basic' or 'digest'
2068 	wget_stringmap *
2069 		params; //!< name/value pairs of the challenge
2070 } wget_http_challenge;
2071 
2072 typedef enum {
2073 	wget_transfer_encoding_identity = 0,
2074 	wget_transfer_encoding_chunked = 1
2075 } wget_transfer_encoding;
2076 
2077 typedef struct wget_http_response_st wget_http_response;
2078 typedef int wget_http_header_callback(wget_http_response *, void *);
2079 typedef int wget_http_body_callback(wget_http_response *, void *, const char *, size_t);
2080 
2081 /**
2082  * HTTP request data
2083  */
2084 typedef struct {
2085 	wget_vector *
2086 		headers; //!< list of HTTP headers
2087 	const char *
2088 		body; //!< body data to be sent or NULL
2089 	wget_http_header_callback
2090 		*header_callback; //!< called after HTTP header has been received
2091 	wget_http_body_callback
2092 		*body_callback; //!< called for each body data packet received
2093 	void *
2094 		user_data; //!< user data for the request (used by async application code)
2095 	void *
2096 		header_user_data; //!< meant to be used in header callback function
2097 	void *
2098 		body_user_data; //!< meant to be used in body callback function
2099 	wget_buffer
2100 		esc_resource; //!< URI escaped resource
2101 	wget_buffer
2102 		esc_host; //!< URI escaped host
2103 	size_t
2104 		body_length; //!< length of the body data
2105 	int32_t
2106 		stream_id; //!< HTTP2 stream id
2107 	wget_iri_scheme
2108 		scheme; //!< scheme of the request for proxied connections
2109 	char
2110 		esc_resource_buf[256]; //!< static buffer used by esc_resource (avoids mallocs)
2111 	char
2112 		esc_host_buf[64]; //!< static buffer used by esc_host (avoids mallocs)
2113 	char
2114 		method[8]; //!< currently we just need HEAD, GET and POST
2115 	bool
2116 		response_keepheader : 1; //!< the application wants the response header data
2117 	bool
2118 		response_ignorelength : 1; //!< ignore the Content-Length in the response header
2119 	bool
2120 		debug_skip_body : 1; //!< if set, do not print the request body (e.g. because it's binary)
2121 	long long
2122 		request_start; //!< When this request was sent out
2123 	long long
2124 		first_response_start; //!< The time we read the first bytes back
2125 
2126 } wget_http_request;
2127 
2128 /**
2129  * HTTP response data
2130  */
2131 struct wget_http_response_st {
2132 	wget_http_request *
2133 		req;
2134 	wget_vector *
2135 		links;
2136 	wget_vector *
2137 		digests;
2138 	wget_vector *
2139 		cookies;
2140 	wget_vector *
2141 		challenges;
2142 	wget_hpkp *
2143 		hpkp;
2144 	const char *
2145 		content_type;
2146 	const char *
2147 		content_type_encoding;
2148 	const char *
2149 		content_filename;
2150 	const char *
2151 		location;
2152 	const char *
2153 		etag; //!< ETag value
2154 	wget_buffer *
2155 		header; //!< the raw header data if requested by the application
2156 	wget_buffer *
2157 		body; //!< the body data
2158 	long long
2159 		response_end; //!< when this response was received
2160 	size_t
2161 		content_length; //!< length of the body data
2162 	size_t
2163 		cur_downloaded,
2164 		accounted_for;	// reported to bar
2165 	int64_t
2166 		last_modified;
2167 	int64_t
2168 		hsts_maxage;
2169 	char
2170 		reason[32]; //!< reason string after the status code
2171 	int
2172 		icy_metaint; //!< value of the SHOUTCAST header 'icy-metaint'
2173 	short
2174 		major; //!< HTTP major version
2175 	short
2176 		minor; //!< HTTP minor version
2177 	short
2178 		code; //!< request only status code
2179 	wget_transfer_encoding
2180 		transfer_encoding;
2181 	char
2182 		content_encoding;
2183 	bool
2184 		hsts_include_subdomains,
2185 		keep_alive;
2186 	bool
2187 		content_length_valid : 1,
2188 		length_inconsistent : 1, //!< set when length of data received is not same as Content-Length
2189 		hsts : 1, //!< if hsts_maxage and hsts_include_subdomains are valid
2190 		csp : 1;
2191 };
2192 
2193 typedef struct wget_http_connection_st wget_http_connection;
2194 
2195 WGETAPI const char *
2196 	wget_http_get_host(const wget_http_connection *conn) WGET_GCC_NONNULL_ALL;
2197 WGETAPI uint16_t
2198 	wget_http_get_port(const wget_http_connection *conn) WGET_GCC_NONNULL_ALL;
2199 WGETAPI wget_iri_scheme
2200 	wget_http_get_scheme(const wget_http_connection *conn) WGET_GCC_NONNULL_ALL;
2201 WGETAPI int
2202 	wget_http_get_protocol(const wget_http_connection *conn) WGET_GCC_NONNULL_ALL;
2203 
2204 WGETAPI bool
2205 	wget_http_isseparator(char c) WGET_GCC_CONST;
2206 WGETAPI bool
2207 	wget_http_istoken(char c) WGET_GCC_CONST;
2208 
2209 WGETAPI const char *
2210 	wget_http_parse_token(const char *s, const char **token) WGET_GCC_NONNULL_ALL;
2211 WGETAPI const char *
2212 	wget_http_parse_quoted_string(const char *s, const char **qstring) WGET_GCC_NONNULL_ALL;
2213 WGETAPI const char *
2214 	wget_http_parse_param(const char *s, const char **param, const char **value) WGET_GCC_NONNULL_ALL;
2215 WGETAPI const char *
2216 	wget_http_parse_name(const char *s, const char **name) WGET_GCC_NONNULL_ALL;
2217 WGETAPI const char *
2218 	wget_parse_name_fixed(const char *s, const char **name, size_t *namelen) WGET_GCC_NONNULL_ALL;
2219 WGETAPI int64_t
2220 	wget_http_parse_full_date(const char *s) WGET_GCC_NONNULL_ALL;
2221 WGETAPI const char *
2222 	wget_http_parse_link(const char *s, wget_http_link *link) WGET_GCC_NONNULL_ALL;
2223 WGETAPI const char *
2224 	wget_http_parse_digest(const char *s, wget_http_digest *digest) WGET_GCC_NONNULL_ALL;
2225 WGETAPI const char *
2226 	wget_http_parse_challenge(const char *s, wget_http_challenge *challenge) WGET_GCC_NONNULL_ALL;
2227 WGETAPI const char *
2228 	wget_http_parse_challenges(const char *s, wget_vector *challenges) WGET_GCC_NONNULL_ALL;
2229 WGETAPI const char *
2230 	wget_http_parse_location(const char *s, const char **location) WGET_GCC_NONNULL_ALL;
2231 WGETAPI const char *
2232 	wget_http_parse_transfer_encoding(const char *s, wget_transfer_encoding *transfer_encoding) WGET_GCC_NONNULL_ALL;
2233 WGETAPI const char *
2234 	wget_http_parse_content_type(const char *s, const char **content_type, const char **charset) WGET_GCC_NONNULL((1));
2235 WGETAPI const char *
2236 	wget_http_parse_content_encoding(const char *s, char *content_encoding) WGET_GCC_NONNULL_ALL;
2237 WGETAPI const char *
2238 	wget_http_parse_content_disposition(const char *s, const char **filename) WGET_GCC_NONNULL((1));
2239 WGETAPI const char *
2240 	wget_http_parse_strict_transport_security(const char *s, int64_t *maxage, bool *include_subdomains) WGET_GCC_NONNULL_ALL;
2241 WGETAPI const char *
2242 	wget_http_parse_public_key_pins(const char *s, wget_hpkp *hpkp) WGET_GCC_NONNULL((1));
2243 WGETAPI const char *
2244 	wget_http_parse_connection(const char *s, bool *keep_alive) WGET_GCC_NONNULL_ALL;
2245 WGETAPI const char *
2246 	wget_http_parse_setcookie(const char *s, wget_cookie **cookie) WGET_GCC_NONNULL((1));
2247 WGETAPI const char *
2248 	wget_http_parse_etag(const char *s, const char **etag) WGET_GCC_NONNULL((1));
2249 
2250 WGETAPI char *
2251 	wget_http_print_date(int64_t t, char *buf, size_t bufsize) WGET_GCC_NONNULL_ALL;
2252 
2253 WGETAPI void
2254 	wget_http_add_param(wget_vector **params, wget_http_header_param *param) WGET_GCC_NONNULL_ALL;
2255 WGETAPI int
2256 	wget_http_add_header_vprintf(wget_http_request *req, const char *name, const char *restrict fmt, va_list args) WGET_GCC_PRINTF_FORMAT(3,0) WGET_GCC_NONNULL_ALL;
2257 WGETAPI int
2258 	wget_http_add_header_printf(wget_http_request *req, const char *name, const char *restrict fmt, ...) WGET_GCC_PRINTF_FORMAT(3,4) WGET_GCC_NONNULL((1,2,3));
2259 WGETAPI int
2260 	wget_http_add_header(wget_http_request *req, const char *name, const char *value) WGET_GCC_NONNULL_ALL;
2261 WGETAPI int
2262 	wget_http_add_header_param(wget_http_request *req, wget_http_header_param *param) WGET_GCC_NONNULL((1));
2263 WGETAPI void
2264 	wget_http_add_credentials(wget_http_request *req, wget_http_challenge *challenge, const char *username, const char *password, int proxied) WGET_GCC_NONNULL((1));
2265 WGETAPI int
2266 	wget_http_set_http_proxy(const char *proxy, const char *encoding);
2267 WGETAPI int
2268 	wget_http_set_https_proxy(const char *proxy, const char *encoding);
2269 WGETAPI int
2270 	wget_http_set_no_proxy(const char *no_proxy, const char *encoding);
2271 WGETAPI int
2272 	wget_http_match_no_proxy(wget_vector *no_proxies, const char *host);
2273 WGETAPI void
2274 	wget_http_abort_connection(wget_http_connection *conn);
2275 
2276 WGETAPI void
2277 	wget_http_free_param(wget_http_header_param *param);
2278 WGETAPI void
2279 	wget_http_free_cookie(wget_cookie *cookie);
2280 WGETAPI void
2281 	wget_http_free_digest(wget_http_digest *digest);
2282 WGETAPI void
2283 	wget_http_free_challenge(wget_http_challenge *challenge);
2284 WGETAPI void
2285 	wget_http_free_link(wget_http_link *link);
2286 
2287 WGETAPI void
2288 	wget_http_free_cookies(wget_vector **cookies);
2289 WGETAPI void
2290 	wget_http_free_hpkp_entries(wget_hpkp **hpkp);
2291 WGETAPI void
2292 	wget_http_free_digests(wget_vector **digests);
2293 WGETAPI void
2294 	wget_http_free_challenges(wget_vector **challenges);
2295 WGETAPI void
2296 	wget_http_free_links(wget_vector **links);
2297 //WGETAPI void
2298 //	wget_http_free_header(HTTP_HEADER **header);
2299 WGETAPI void
2300 	wget_http_free_request(wget_http_request **req);
2301 WGETAPI void
2302 	wget_http_free_response(wget_http_response **resp);
2303 
2304 WGETAPI int
2305 	wget_http_parse_header_line(wget_http_response *resp, const char *name, size_t namelen, const char *value, size_t valuelen);
2306 WGETAPI wget_http_response * NULLABLE
2307 	wget_http_parse_response_header(char *buf) WGET_GCC_NONNULL_ALL;
2308 WGETAPI wget_http_response * NULLABLE
2309 	wget_http_get_response_cb(wget_http_connection *conn) WGET_GCC_NONNULL((1));
2310 //WGETAPI HTTP_RESPONSE *
2311 //	http_get_response_mem(HTTP_CONNECTION *conn, HTTP_REQUEST *req) NONNULL_ALL;
2312 WGETAPI wget_http_response * NULLABLE
2313 	wget_http_get_response(wget_http_connection *conn) WGET_GCC_NONNULL((1));
2314 
2315 WGETAPI void
2316 	wget_http_init(void);
2317 WGETAPI void
2318 	wget_http_exit(void);
2319 WGETAPI int
2320 	wget_http_open(wget_http_connection **_conn, const wget_iri *iri);
2321 WGETAPI wget_http_request * NULLABLE
2322 	wget_http_create_request(const wget_iri *iri, const char *method) WGET_GCC_NONNULL_ALL;
2323 WGETAPI void
2324 	wget_http_close(wget_http_connection **conn) WGET_GCC_NONNULL_ALL;
2325 WGETAPI void
2326 	wget_http_request_set_header_cb(wget_http_request *req, wget_http_header_callback *cb, void *user_data) WGET_GCC_NONNULL((1));
2327 WGETAPI void
2328 	wget_http_request_set_body_cb(wget_http_request *req, wget_http_body_callback *cb, void *user_data) WGET_GCC_NONNULL((1));
2329 WGETAPI void
2330 	wget_http_request_set_int(wget_http_request *req, int key, int value) WGET_GCC_NONNULL((1));
2331 WGETAPI int
2332 	wget_http_request_get_int(wget_http_request *req, int key) WGET_GCC_NONNULL((1));
2333 WGETAPI void
2334 	wget_http_request_set_ptr(wget_http_request *req, int key, void *value) WGET_GCC_NONNULL((1));
2335 WGETAPI void *
2336 	wget_http_request_get_ptr(wget_http_request *req, int key) WGET_GCC_NONNULL((1));
2337 WGETAPI void
2338 	wget_http_request_set_body(wget_http_request *req, const char *mimetype, char *body, size_t length) WGET_GCC_NONNULL((1));
2339 WGETAPI int
2340 	wget_http_send_request(wget_http_connection *conn, wget_http_request *req) WGET_GCC_NONNULL_ALL;
2341 WGETAPI ssize_t
2342 	wget_http_request_to_buffer(wget_http_request *req, wget_buffer *buf, int proxied) WGET_GCC_NONNULL_ALL;
2343 
2344 /*
2345  * Highlevel HTTP routines
2346  */
2347 
2348 WGETAPI wget_http_response *
2349 	wget_http_get(int first_key, ...);
2350 
2351 
2352 /*
2353  * random routines
2354  */
2355 
2356 WGETAPI void
2357 	wget_random_init(void);
2358 WGETAPI void
2359 	wget_random_exit(void);
2360 WGETAPI int
2361 	wget_random(void);
2362 WGETAPI void
2363 	wget_srandom(unsigned int seed);
2364 
2365 
2366 /**
2367  * \ingroup libwget-hash
2368  * \brief Type for hash / digest routines
2369  */
2370 	typedef struct wget_hash_hd_st wget_hash_hd;
2371 
2372 /**
2373  * \ingroup libwget-hash
2374  * \brief Enumeration of different hash digest algorithms
2375  */
2376 typedef enum {
2377 	WGET_DIGTYPE_UNKNOWN = 0, /**< Indicates 'Unknown hash algorithm', returned by wget_hash_get_algorithm() */
2378 	WGET_DIGTYPE_MD5,     /**< Type 'MD5' digest */
2379 	WGET_DIGTYPE_SHA1,    /**< Type SHA1 digest */
2380 	WGET_DIGTYPE_RMD160,  /**< Type RMD160 digest */
2381 	WGET_DIGTYPE_MD2,     /**< Type 'MD2' digest */
2382 	WGET_DIGTYPE_SHA256,  /**< Type 'SHA256' digest */
2383 	WGET_DIGTYPE_SHA384,  /**< Type 'SHA384' digest */
2384 	WGET_DIGTYPE_SHA512,  /**< Type 'SHA512' digest */
2385 	WGET_DIGTYPE_SHA224,  /**< Type 'SHA224' digest */
2386 	WGET_DIGTYPE_MAX      /**< Number of digest types */
2387 } wget_digest_algorithm;
2388 
2389 WGETAPI wget_digest_algorithm
2390 	wget_hash_get_algorithm(const char *hashname);
2391 WGETAPI int
2392 	wget_hash_fast(wget_digest_algorithm algorithm, const void *text, size_t textlen, void *digest);
2393 WGETAPI int
2394 	wget_hash_get_len(wget_digest_algorithm algorithm) WGET_GCC_CONST;
2395 WGETAPI int
2396 	wget_hash_init(wget_hash_hd **dig, wget_digest_algorithm algorithm);
2397 WGETAPI int
2398 	wget_hash(wget_hash_hd *handle, const void *text, size_t textlen);
2399 WGETAPI int
2400 	wget_hash_deinit(wget_hash_hd **handle, void *digest);
2401 
2402 /*
2403  * Hash file routines
2404  */
2405 
2406 WGETAPI int
2407 	wget_hash_file_fd(const char *hashname, int fd, char *digest_hex, size_t digest_hex_size, off_t offset, off_t length) WGET_GCC_NONNULL_ALL;
2408 WGETAPI int
2409 	wget_hash_file_offset(const char *hashname, const char *fname, char *digest_hex, size_t digest_hex_size, off_t offset, off_t length) WGET_GCC_NONNULL_ALL;
2410 WGETAPI int
2411 	wget_hash_file(const char *hashname, const char *fname, char *digest_hex, size_t digest_hex_size) WGET_GCC_NONNULL_ALL;
2412 
2413 /*
2414  * Hash convenience routines
2415  */
2416 
2417 // don't use 'restrict' here as out, fmt and argument pointers may overlap
2418 WGETAPI void WGET_GCC_PRINTF_FORMAT(4,5) WGET_GCC_NONNULL_ALL
2419 	wget_hash_printf_hex(wget_digest_algorithm algorithm, char *out, size_t outsize, const char *fmt, ...);
2420 
2421 
2422 /*
2423  * Metalink types and routines
2424  */
2425 
2426 typedef struct {
2427 	const wget_iri
2428 		*iri;        //!< parsed URL of the mirror
2429 	int
2430 		priority;    //!< priority of the mirror
2431 	char
2432 		location[8]; //!< location of the mirror, e.g. 'de', 'fr' or 'jp'
2433 } wget_metalink_mirror;
2434 
2435 typedef struct {
2436 	char
2437 		type[16],        //!< type of hash, e.g. 'MD5' or 'SHA-256'
2438 		hash_hex[128+1]; //!< hash value as HEX string
2439 } wget_metalink_hash;
2440 
2441 // Metalink piece, for checksumming after download
2442 typedef struct {
2443 	wget_metalink_hash
2444 		hash;     //!< hash of the data chunk
2445 	off_t
2446 		position; //!< start position of the data chunk in the file
2447 	off_t
2448 		length;   //!< length of the data chunk
2449 } wget_metalink_piece;
2450 
2451 typedef struct {
2452 	const char
2453 		*name;    //!< filename
2454 	wget_vector
2455 		*mirrors, //!< mirrors that provide the file (element: wget_metalink_mirror)
2456 		*hashes,  //!< checksums of complete file (element: wget_metalink_hash)
2457 		*pieces;  //!< checksums of smaller pieces of the file (element: wget_metalink_piece)
2458 	off_t
2459 		size;     //!< total size of the file
2460 } wget_metalink;
2461 
2462 WGETAPI wget_metalink * NULLABLE
2463 	wget_metalink_parse(const char *xml);
2464 WGETAPI void
2465 	wget_metalink_free(wget_metalink **metalink);
2466 WGETAPI void
2467 	wget_metalink_sort_mirrors(wget_metalink *metalink);
2468 
2469 /*
2470  * Robots types and routines
2471  */
2472 
2473 typedef struct wget_robots_st wget_robots;
2474 
2475 WGETAPI int
2476 	wget_robots_parse(wget_robots **robots, const char *data, const char *client);
2477 WGETAPI void
2478 	wget_robots_free(wget_robots **robots);
2479 WGETAPI int
2480 	wget_robots_get_path_count(wget_robots *robots);
2481 WGETAPI wget_string * NULLABLE
2482 	wget_robots_get_path(wget_robots *robots, int index);
2483 WGETAPI int
2484 	wget_robots_get_sitemap_count(wget_robots *robots);
2485 WGETAPI const char * NULLABLE
2486 	wget_robots_get_sitemap(wget_robots *robots, int index);
2487 
2488 /*
2489  * Progress bar routines
2490  */
2491 
2492 // values for --report-speed and wget_bar_set_speed_type()
2493 typedef enum {
2494 	WGET_REPORT_SPEED_BYTES,
2495 	WGET_REPORT_SPEED_BITS
2496 } wget_report_speed;
2497 
2498 typedef struct wget_bar_st wget_bar;
2499 
2500 WGETAPI wget_bar * NULLABLE
2501 	wget_bar_init(wget_bar *bar, int nslots);
2502 WGETAPI void
2503 	wget_bar_deinit(wget_bar *bar);
2504 WGETAPI void
2505 	wget_bar_free(wget_bar **bar);
2506 WGETAPI void
2507 	wget_bar_print(wget_bar *bar, int slot, const char *s);
2508 WGETAPI void
2509 	wget_bar_vprintf(wget_bar *bar, int slot, const char *restrict fmt, va_list args) WGET_GCC_PRINTF_FORMAT(3,0) WGET_GCC_NONNULL_ALL;
2510 WGETAPI void
2511 	wget_bar_printf(wget_bar *bar, int slot, const char *restrict fmt, ...) WGET_GCC_PRINTF_FORMAT(3,4) WGET_GCC_NONNULL_ALL;
2512 WGETAPI void
2513 	wget_bar_slot_begin(wget_bar *bar, int slot, const char *filename, int new_file, ssize_t filesize) WGET_GCC_NONNULL((1));
2514 WGETAPI void
2515 	wget_bar_slot_downloaded(wget_bar *bar, int slot, size_t nbytes);
2516 WGETAPI void
2517 	wget_bar_slot_deregister(wget_bar *bar, int slot) WGET_GCC_NONNULL_ALL;
2518 WGETAPI void
2519 	wget_bar_update(wget_bar *bar) WGET_GCC_NONNULL_ALL;
2520 WGETAPI void
2521 	wget_bar_set_slots(wget_bar *bar, int nslots) WGET_GCC_NONNULL_ALL;
2522 WGETAPI void
2523 	wget_bar_screen_resized(void);
2524 WGETAPI void
2525 	wget_bar_write_line(wget_bar *bar, const char *buf, size_t len) WGET_GCC_NONNULL_ALL;
2526 WGETAPI void
2527 	wget_bar_set_speed_type(wget_report_speed type);
2528 
2529 /*
2530  * Console routines
2531  */
2532 
2533 // console color definitions
2534 typedef enum {
2535 	WGET_CONSOLE_COLOR_RESET = 0,
2536 	WGET_CONSOLE_COLOR_WHITE = 1,
2537 	WGET_CONSOLE_COLOR_BLUE = 2,
2538 	WGET_CONSOLE_COLOR_GREEN = 3,
2539 	WGET_CONSOLE_COLOR_RED = 4,
2540 	WGET_CONSOLE_COLOR_MAGENTA = 5
2541 } wget_console_color;
2542 
2543 WGETAPI int
2544 	wget_console_init(void);
2545 WGETAPI int
2546 	wget_console_deinit(void);
2547 WGETAPI void
2548 	wget_console_set_fg_color(wget_console_color colorid);
2549 WGETAPI void
2550 	wget_console_reset_fg_color(void);
2551 
2552 /*
2553  * Plugin support
2554  */
2555 
2556 /**
2557  * \ingroup libwget-plugin
2558  *
2559  * Mark a function to be exported.
2560  * A common use for this is to mark the `wget_plugin_initializer()` function for plugin initialization.
2561  *
2562  *     WGET_EXPORT void wget_plugin_initializer(wget_plugin *plugin);
2563  */
2564 #ifdef _WIN32
2565 #	define WGET_EXPORT __declspec(dllexport)
2566 #elif __GNUC__ > 4
2567 #	define WGET_EXPORT __attribute__ ((__visibility__("default")))
2568 #else
2569 #	define WGET_EXPORT
2570 #endif
2571 
2572 struct wget_plugin_vtable;
2573 
2574 /**
2575  * \ingroup libwget-plugin
2576  *
2577  * A handle used to identify the plugin.
2578  *
2579  * Only two members shown here are public, and only plugin_data is writable.
2580  */
2581 struct wget_plugin_st
2582 {
2583 	/// Plugin specific data. Plugins are free to assign any value to this.
2584 	void *plugin_data;
2585 
2586 	/// Pointer to the vtable. Used by wget to implement functions.
2587 	struct wget_plugin_vtable *vtable;
2588 };
2589 
2590 typedef struct wget_plugin_st wget_plugin;
2591 
2592 /**
2593  * \ingroup libwget-plugin
2594  *
2595  * Prototype for the initializer function.
2596  *
2597  * \param[in] plugin The plugin handle
2598  * \return Should return 0 if initialization succeeded, or any other value to indicate failure.
2599  *         On failure, wget2 will continue without the plugin
2600  *         and will not call the finalizer function even if registered.
2601  */
2602 typedef int wget_plugin_initializer_fn(wget_plugin *plugin);
2603 
2604 /**
2605  * \ingroup libwget-plugin
2606  *
2607  * Prototype of the finalizer function.
2608  *
2609  * \param[in] plugin The plugin handle
2610  * \param[in] exit_status The exit status wget will exit with
2611  */
2612 typedef void wget_plugin_finalizer_fn(wget_plugin *plugin, int exit_status);
2613 
2614 // Gets the name the plugin is known as.
2615 WGETAPI const char *
2616 	wget_plugin_get_name(wget_plugin *plugin) WGET_GCC_NONNULL_ALL;
2617 
2618 // Registers a function to be called when wget exits.
2619 WGETAPI void
2620 	wget_plugin_register_finalizer(wget_plugin *plugin, wget_plugin_finalizer_fn *fn) WGET_GCC_NONNULL((1));
2621 
2622 /**
2623  * \ingroup libwget-plugin
2624  *
2625  * Prototype for the function that will accept forwarded command line arguments.
2626  *
2627  * \param[in] plugin The plugin handle
2628  * \param[in] option Option name. If the option is "help", a help message must be printed to stdout.
2629  * \param[in] value  The value of the option if provided, or NULL
2630  * \return Must return 0 if option and its value is valid, or any other value if invalid. In that case wget will exit.
2631  */
2632 typedef int wget_plugin_option_callback(wget_plugin *plugin, const char *option, const char *value);
2633 
2634 // Registers a function for command line option forwarding.
2635 WGETAPI void
2636 	wget_plugin_register_option_callback(wget_plugin *plugin, wget_plugin_option_callback *fn) WGET_GCC_NONNULL((1));
2637 
2638 /**
2639  * \ingroup libwget-plugin
2640  *
2641  * Stores any action taken by the plugin
2642  */
2643 typedef struct {
2644 	struct wget_plugin_vtable *vtable;
2645 } wget_intercept_action;
2646 
2647 // Marks the URL to be rejected.
2648 WGETAPI void
2649 	wget_intercept_action_reject(wget_intercept_action *action) WGET_GCC_NONNULL_ALL;
2650 
2651 // Marks the URL to be accepted.
2652 WGETAPI void
2653 	wget_intercept_action_accept(wget_intercept_action *action) WGET_GCC_NONNULL_ALL;
2654 
2655 // Specifies an alternative URL to be fetched instead.
2656 WGETAPI void
2657 	wget_intercept_action_set_alt_url(wget_intercept_action *action, const wget_iri *iri) WGET_GCC_NONNULL((1));
2658 
2659 // Specifies that the fetched data should be written to an alternative file.
2660 WGETAPI void
2661 	wget_intercept_action_set_local_filename(wget_intercept_action *action, const char *local_filename) WGET_GCC_NONNULL((1));
2662 
2663 /**
2664  * \ingroup libwget-plugin
2665  *
2666  * Prototype for the function for intercepting URLs
2667  * The function must be thread-safe.
2668  *
2669  * \param[in] plugin The plugin handle
2670  * \param[in] iri The URL about to be fetched
2671  * \param[in] action Output the action to be taken
2672  */
2673 typedef void wget_plugin_url_filter_callback(wget_plugin *plugin, const wget_iri *iri, wget_intercept_action *action);
2674 
2675 // Registers a plugin function for intercepting URLs
2676 WGETAPI void
2677 	wget_plugin_register_url_filter_callback(wget_plugin *plugin, wget_plugin_url_filter_callback *filter_fn);
2678 
2679 /**
2680  * \ingroup libwget-plugin
2681  *
2682  * Handle that represents a downloaded file.
2683  */
2684 typedef struct {
2685 	struct wget_plugin_vtable *vtable;
2686 } wget_downloaded_file;
2687 
2688 // Gets the source address the file was downloaded from.
2689 WGETAPI const wget_iri *
2690 	wget_downloaded_file_get_source_url(wget_downloaded_file *file);
2691 
2692 // Gets the file name the downloaded file was written to.
2693 WGETAPI const char *
2694 	wget_downloaded_file_get_local_filename(wget_downloaded_file *file);
2695 
2696 // Gets the size of the downloaded file.
2697 WGETAPI uint64_t
2698 	wget_downloaded_file_get_size(wget_downloaded_file *file);
2699 
2700 // Reads the downloaded file into memory.
2701 WGETAPI int
2702 	wget_downloaded_file_get_contents(wget_downloaded_file *file, const void **data, size_t *size);
2703 
2704 // Opens the downloaded file as a new stream.
2705 WGETAPI FILE *
2706 	wget_downloaded_file_open_stream(wget_downloaded_file *file);
2707 
2708 // Gets whether the file should be scanned for more URLs.
2709 WGETAPI bool
2710 	wget_downloaded_file_get_recurse(wget_downloaded_file *file);
2711 
2712 // Adds a URL for recursive downloading.
2713 WGETAPI void
2714 	wget_downloaded_file_add_recurse_url(wget_downloaded_file *file, const wget_iri *iri);
2715 
2716 /**
2717  * \ingroup libwget-plugin
2718  *
2719  * Prototype of the function for intercepting downloaded files. The function must be thread-safe.
2720  *
2721  * \param[in] plugin The plugin handle
2722  * \param[in] file Downloaded file handle
2723  * \return 0 if further postprocessing of downloaded files should be stopped.
2724  */
2725 typedef int wget_plugin_post_processor(wget_plugin *plugin, wget_downloaded_file *file);
2726 
2727 // Registers a plugin function for intercepting downloaded files.
2728 WGETAPI void
2729 	wget_plugin_register_post_processor(wget_plugin *plugin, wget_plugin_post_processor *fn);
2730 
2731 /**
2732  * \ingroup libwget-plugin
2733  *
2734  * vtable for implementing plugin API in wget
2735 */
2736 struct wget_plugin_vtable
2737 {
2738 	const char * (* get_name)(wget_plugin *);
2739 	void (* register_finalizer)(wget_plugin *, wget_plugin_finalizer_fn *);
2740 	void (* register_argp)(wget_plugin *, wget_plugin_option_callback *);
2741 
2742 	void (* action_reject)(wget_intercept_action *);
2743 	void (* action_accept)(wget_intercept_action *);
2744 	void (* action_set_alt_url)(wget_intercept_action *, const wget_iri *);
2745 	void (* action_set_local_filename)(wget_intercept_action *, const char *);
2746 	void (* register_url_filter)(wget_plugin *, wget_plugin_url_filter_callback *);
2747 
2748 	const wget_iri *(*file_get_source_url)(wget_downloaded_file *);
2749 	const char *(*file_get_local_filename)(wget_downloaded_file *);
2750 	uint64_t (*file_get_size)(wget_downloaded_file *);
2751 	int (*file_get_contents)(wget_downloaded_file *, const void **data, size_t *size);
2752 	FILE *(*file_open_stream)(wget_downloaded_file *);
2753 	bool (*file_get_recurse)(wget_downloaded_file *);
2754 	void (*file_add_recurse_url)(wget_downloaded_file *, const wget_iri *);
2755 	void (*register_post_processor)(wget_plugin *, wget_plugin_post_processor *);
2756 };
2757 
2758 /**
2759  * \ingroup libwget-dns
2760  *
2761  * DNS statistics data
2762  *
2763  * @{
2764  */
2765 typedef struct
2766 {
2767 	const char
2768 		*hostname, //!< hostname/domain to be resolved
2769 		*ip; //!< resulting IP string
2770 	uint16_t
2771 		port; //!< port to be resolved
2772 	long long
2773 		dns_secs; //!< milliseconds it took to resolve
2774 } wget_dns_stats_data;
2775 
2776 typedef void
2777 	wget_dns_stats_callback(wget_dns *dns, wget_dns_stats_data *stats, void *ctx);
2778 
2779 WGETAPI void
2780 	wget_dns_set_stats_callback(wget_dns *dns, wget_dns_stats_callback *fn, void *ctx);
2781 
2782 /**
2783  * \ingroup libwget-ssl
2784  *
2785  * TLS statistics data
2786  *
2787  * @{
2788  */
2789 typedef struct
2790 {
2791 	const char
2792 		*hostname;
2793 	int
2794 		nvalid,
2795 		nrevoked,
2796 		nignored,
2797 		stapling;
2798 } wget_ocsp_stats_data;
2799 
2800 typedef void
2801 	wget_ocsp_stats_callback(wget_ocsp_stats_data *stats, void *ctx);
2802 
2803 WGETAPI void
2804 	wget_ssl_set_stats_callback_ocsp(wget_ocsp_stats_callback *fn, void *ctx);
2805 /** @} */
2806 
2807 /**
2808  * \ingroup libwget-ssl
2809  *
2810  * OCSP statistics data
2811  *
2812  * @{
2813  */
2814 typedef struct
2815 {
2816 	const char
2817 		*hostname,
2818 		*alpn_protocol;
2819 	long long
2820 		tls_secs; //milliseconds
2821 	int
2822 		version,
2823 		cert_chain_size;
2824 	char
2825 		http_protocol;
2826 	bool
2827 		false_start,
2828 		tfo,
2829 		tls_con,
2830 		resumed;
2831 } wget_tls_stats_data;
2832 
2833 typedef void
2834 	wget_tls_stats_callback(wget_tls_stats_data *stats, void *ctx);
2835 
2836 WGETAPI void
2837 	wget_ssl_set_stats_callback_tls(wget_tls_stats_callback *fn, void *ctx);
2838 /** @} */
2839 
2840 typedef enum {
2841 	WGET_STATS_HPKP_NO = 0,
2842 	WGET_STATS_HPKP_MATCH = 1,
2843 	WGET_STATS_HPKP_NOMATCH = 2,
2844 	WGET_STATS_HPKP_ERROR = 3
2845 } wget_hpkp_stats_result;
2846 
2847 typedef void
2848 	wget_server_stats_callback(wget_http_connection *conn, wget_http_response *resp);
2849 
2850 WGETAPI void
2851 	wget_server_set_stats_callback(wget_server_stats_callback *fn);
2852 
2853 typedef enum {
2854 	WGET_STATS_FORMAT_HUMAN = 0,
2855 	WGET_STATS_FORMAT_CSV = 1,
2856 } wget_stats_format;
2857 
2858 WGET_END_DECLS
2859 
2860 /*
2861  * Regex Types
2862  */
2863 
2864 #define WGET_REGEX_TYPE_POSIX 0
2865 #define WGET_REGEX_TYPE_PCRE 1
2866 
2867 #undef RETURNS_NONNULL
2868 
2869 #endif /* WGET_WGET_H */
2870