Coverage Report

Created: 2024-03-08 06:32

/src/wget2/libwget/init.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (c) 2013 Tim Ruehsen
3
 * Copyright (c) 2015-2024 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
 * Memory allocation routines
22
 *
23
 * Changelog
24
 * 18.01.2013  Tim Ruehsen  created
25
 *
26
 */
27
28
#include <config.h>
29
30
#include <stdarg.h>
31
32
#include <wget.h>
33
#include "private.h"
34
35
static struct config {
36
  char
37
    *cookie_file;
38
  wget_cookie_db
39
    *cookie_db;
40
  bool
41
    cookies_enabled,
42
    keep_session_cookies;
43
} config = {
44
  .cookies_enabled = 0
45
};
46
47
static wget_dns_cache *dns_cache;
48
49
static int global_initialized;
50
static wget_thread_mutex _mutex;
51
static bool initialized;
52
53
static void global_exit(void)
54
9.59k
{
55
9.59k
  if (initialized) {
56
1
    wget_thread_mutex_destroy(&_mutex);
57
1
    initialized = false;
58
1
  }
59
9.59k
}
60
INITIALIZER(global_init)
61
2
{
62
2
  if (!initialized) {
63
2
    wget_thread_mutex_init(&_mutex);
64
2
    initialized = true;
65
2
    atexit(global_exit);
66
2
  }
67
2
}
68
69
/**
70
 * Global library initialization, allocating/preparing all resources.
71
 *
72
 * This function is not thread-safe on systems without automatic library
73
 * initialization.
74
 */
75
void wget_global_init(int first_key, ...)
76
0
{
77
0
  va_list args;
78
0
  int key, rc, caching;
79
0
  const char *psl_file = NULL;
80
0
  wget_logger_func *func; // intermediate var to satisfy MSVC
81
82
  // just in case that automatic initializers didn't work,
83
  // e.g. maybe a static build
84
0
  global_init();
85
86
0
  wget_thread_mutex_lock(_mutex);
87
88
0
  if (global_initialized++) {
89
0
    wget_thread_mutex_unlock(_mutex);
90
0
    return;
91
0
  }
92
93
0
  wget_console_init();
94
0
  wget_random_init();
95
0
  wget_http_init();
96
97
0
  va_start (args, first_key);
98
0
  for (key = first_key; key; key = va_arg(args, int)) {
99
0
    switch (key) {
100
0
    case WGET_DEBUG_STREAM:
101
0
      wget_logger_set_stream(wget_get_logger(WGET_LOGGER_DEBUG), va_arg(args, FILE *));
102
0
      break;
103
0
    case WGET_DEBUG_FUNC:
104
0
      func = va_arg(args, wget_logger_func *);
105
0
      wget_logger_set_func(wget_get_logger(WGET_LOGGER_DEBUG), func);
106
0
      break;
107
0
    case WGET_DEBUG_FILE:
108
0
      wget_logger_set_file(wget_get_logger(WGET_LOGGER_DEBUG), va_arg(args, const char *));
109
0
      break;
110
0
    case WGET_ERROR_STREAM:
111
0
      wget_logger_set_stream(wget_get_logger(WGET_LOGGER_ERROR), va_arg(args, FILE *));
112
0
      break;
113
0
    case WGET_ERROR_FUNC:
114
0
      func = va_arg(args, wget_logger_func *);
115
0
      wget_logger_set_func(wget_get_logger(WGET_LOGGER_ERROR), func);
116
0
      break;
117
0
    case WGET_ERROR_FILE:
118
0
      wget_logger_set_file(wget_get_logger(WGET_LOGGER_ERROR), va_arg(args, const char *));
119
0
      break;
120
0
    case WGET_INFO_STREAM:
121
0
      wget_logger_set_stream(wget_get_logger(WGET_LOGGER_INFO), va_arg(args, FILE *));
122
0
      break;
123
0
    case WGET_INFO_FUNC:
124
0
      func = va_arg(args, wget_logger_func *);
125
0
      wget_logger_set_func(wget_get_logger(WGET_LOGGER_INFO), func);
126
0
      break;
127
0
    case WGET_INFO_FILE:
128
0
      wget_logger_set_file(wget_get_logger(WGET_LOGGER_INFO), va_arg(args, const char *));
129
0
      break;
130
0
    case WGET_DNS_CACHING:
131
0
      caching = va_arg(args, int);
132
0
      if (caching) {
133
0
        if ((rc = wget_dns_cache_init(&dns_cache)) == WGET_E_SUCCESS)
134
0
          wget_dns_set_cache(NULL, dns_cache);
135
0
        else
136
0
          wget_error_printf(_("Failed to init DNS cache (%d)"), rc);
137
0
      }
138
0
      break;
139
0
    case WGET_TCP_FASTFORWARD:
140
0
      wget_tcp_set_tcp_fastopen(NULL, va_arg(args, int) != 0);
141
0
      break;
142
0
    case WGET_COOKIE_SUFFIXES:
143
0
      psl_file = va_arg(args, const char *);
144
0
      config.cookies_enabled = 1;
145
0
      break;
146
0
    case WGET_COOKIES_ENABLED:
147
0
      config.cookies_enabled = va_arg(args, int) != 0;
148
0
      break;
149
0
    case WGET_COOKIE_FILE:
150
      // load cookie-store
151
0
      config.cookies_enabled = 1;
152
0
      config.cookie_file = va_arg(args, char *);
153
0
      break;
154
0
    case WGET_COOKIE_KEEPSESSIONCOOKIES:
155
0
      config.keep_session_cookies = va_arg(args, int) != 0;
156
0
      break;
157
0
    case WGET_BIND_ADDRESS:
158
0
      wget_tcp_set_bind_address(NULL, va_arg(args, const char *));
159
0
      break;
160
0
    case WGET_NET_FAMILY_EXCLUSIVE:
161
0
      wget_tcp_set_family(NULL, va_arg(args, int));
162
0
      break;
163
0
    case WGET_NET_FAMILY_PREFERRED:
164
0
      wget_tcp_set_preferred_family(NULL, va_arg(args, int));
165
0
      break;
166
0
    case WGET_BIND_INTERFACE:
167
0
      wget_tcp_set_bind_interface(NULL, va_arg(args, const char *));
168
0
      break;
169
0
    default:
170
0
      wget_thread_mutex_unlock(_mutex);
171
0
      wget_error_printf(_("%s: Unknown option %d"), __func__, key);
172
0
      va_end(args);
173
0
      return;
174
0
    }
175
0
  }
176
0
  va_end(args);
177
178
0
  if (config.cookies_enabled && config.cookie_file) {
179
0
    config.cookie_db = wget_cookie_db_init(NULL);
180
0
    wget_cookie_set_keep_session_cookies(config.cookie_db, config.keep_session_cookies);
181
0
    wget_cookie_db_load(config.cookie_db, config.cookie_file);
182
0
    wget_cookie_db_load_psl(config.cookie_db, psl_file);
183
0
  }
184
185
0
  rc = wget_net_init();
186
187
0
  wget_thread_mutex_unlock(_mutex);
188
189
0
  if (rc)
190
0
    wget_error_printf_exit(_("%s: Failed to init networking (%d)"), __func__, rc);
191
0
}
192
193
/**
194
 * Global library deinitialization, free'ing all allocated resources.
195
 *
196
 * This function is not thread-safe.
197
 */
198
void wget_global_deinit(void)
199
9.59k
{
200
9.59k
  int rc = 0;
201
202
  // we need to lock a static mutex here
203
204
9.59k
  if (global_initialized == 1) {
205
    // free resources here
206
0
    if (config.cookie_db && config.cookies_enabled && config.cookie_file) {
207
0
      wget_cookie_db_save(config.cookie_db, config.cookie_file);
208
0
      wget_cookie_db_free(&config.cookie_db);
209
0
    }
210
0
    wget_tcp_set_bind_address(NULL, NULL);
211
212
0
    wget_dns_cache_free(&dns_cache);
213
214
0
    rc = wget_net_deinit();
215
0
    wget_ssl_deinit();
216
0
    wget_http_set_http_proxy(NULL, NULL);
217
0
    wget_http_set_https_proxy(NULL, NULL);
218
0
    wget_http_set_no_proxy(NULL, NULL);
219
0
  }
220
221
9.59k
  if (global_initialized > 0) global_initialized--;
222
223
9.59k
  global_exit();
224
225
  // we need to unlock a static mutex here
226
227
9.59k
  if (rc)
228
0
    wget_error_printf(_("%s: Failed to deinit networking (%d)"), __func__, rc);
229
230
9.59k
  wget_console_deinit();
231
9.59k
}
232
233
int wget_global_get_int(int key)
234
0
{
235
0
  switch (key) {
236
0
  case WGET_COOKIES_ENABLED:
237
0
    return config.cookies_enabled;
238
0
  case WGET_COOKIE_KEEPSESSIONCOOKIES:
239
0
    return config.keep_session_cookies;
240
0
  case WGET_NET_FAMILY_EXCLUSIVE:
241
0
    return wget_tcp_get_family(NULL);
242
0
  case WGET_NET_FAMILY_PREFERRED:
243
0
    return wget_tcp_get_preferred_family(NULL);
244
0
  default:
245
0
    wget_error_printf(_("%s: Unknown option %d"), __func__, key);
246
0
    return 0;
247
0
  }
248
0
}
249
250
const void *wget_global_get_ptr(int key)
251
0
{
252
0
  switch (key) {
253
0
  case WGET_DEBUG_STREAM:
254
0
    return wget_logger_get_stream(wget_get_logger(WGET_LOGGER_DEBUG));
255
0
  case WGET_DEBUG_FILE:
256
0
    return wget_logger_get_file(wget_get_logger(WGET_LOGGER_DEBUG));
257
0
  case WGET_ERROR_STREAM:
258
0
    return wget_logger_get_stream(wget_get_logger(WGET_LOGGER_ERROR));
259
0
  case WGET_ERROR_FILE:
260
0
    return wget_logger_get_file(wget_get_logger(WGET_LOGGER_ERROR));
261
0
  case WGET_INFO_STREAM:
262
0
    return wget_logger_get_stream(wget_get_logger(WGET_LOGGER_INFO));
263
0
  case WGET_INFO_FILE:
264
0
    return wget_logger_get_file(wget_get_logger(WGET_LOGGER_INFO));
265
0
  case WGET_COOKIE_FILE:
266
0
    return config.cookie_file;
267
0
  case WGET_COOKIE_DB:
268
0
    return config.cookie_db;
269
0
  default:
270
0
    wget_error_printf(_("%s: Unknown option %d"), __func__, key);
271
0
    return NULL;
272
0
  }
273
0
}
274
275
wget_global_func *wget_global_get_func(int key)
276
0
{
277
0
  switch (key) {
278
0
  case WGET_DEBUG_FUNC:
279
0
    return wget_logger_get_func(wget_get_logger(WGET_LOGGER_DEBUG));
280
0
  case WGET_ERROR_FUNC:
281
0
    return wget_logger_get_func(wget_get_logger(WGET_LOGGER_ERROR));
282
0
  case WGET_INFO_FUNC:
283
0
    return wget_logger_get_func(wget_get_logger(WGET_LOGGER_INFO));
284
0
  default:
285
0
    wget_error_printf(_("%s: Unknown option %d"), __func__, key);
286
0
    return NULL;
287
0
  }
288
0
}