Some users have scripts set up from long ago to delete mirrors.dat if
FreshClam failed. We used to recommend this if people had technical
issues because mirrors.dat would store a bunch of entries indicating
that all of their regional mirrors were failing and then FreshClam would
give up.
The new freshclam DAT file no longer stores that kind of information.
Deleting the DAT file is no longer sound advice.
We very much want the UUID, which is generated when creating the DAT
file, to persist between runs. So unless people go and change the
scripts to delete freshclam.dat instead, this commit should resolve the
concern.
... | ... |
@@ -250,12 +250,12 @@ fc_error_t fc_initialize(fc_config *fcConfig) |
250 | 250 |
|
251 | 251 |
g_bCompressLocalDatabase = fcConfig->bCompressLocalDatabase; |
252 | 252 |
|
253 |
- /* Load or create mirrors.dat */ |
|
254 |
- if (FC_SUCCESS != load_mirrors_dat()) { |
|
255 |
- logg("*Failed to load mirrors.dat; will create a new mirrors.dat\n"); |
|
253 |
+ /* Load or create freshclam.dat */ |
|
254 |
+ if (FC_SUCCESS != load_freshclam_dat()) { |
|
255 |
+ logg("*Failed to load freshclam.dat; will create a new freshclam.dat\n"); |
|
256 | 256 |
|
257 |
- if (FC_SUCCESS != new_mirrors_dat()) { |
|
258 |
- logg("^Failed to create a new mirrors.dat!\n"); |
|
257 |
+ if (FC_SUCCESS != new_freshclam_dat()) { |
|
258 |
+ logg("^Failed to create a new freshclam.dat!\n"); |
|
259 | 259 |
status = FC_EINIT; |
260 | 260 |
goto done; |
261 | 261 |
} |
... | ... |
@@ -308,9 +308,9 @@ void fc_cleanup(void) |
308 | 308 |
free(g_tempDirectory); |
309 | 309 |
g_tempDirectory = NULL; |
310 | 310 |
} |
311 |
- if (NULL != g_mirrorsDat) { |
|
312 |
- free(g_mirrorsDat); |
|
313 |
- g_mirrorsDat = NULL; |
|
311 |
+ if (NULL != g_freshclamDat) { |
|
312 |
+ free(g_freshclamDat); |
|
313 |
+ g_freshclamDat = NULL; |
|
314 | 314 |
} |
315 | 315 |
} |
316 | 316 |
|
... | ... |
@@ -683,7 +683,7 @@ fc_error_t fc_update_database( |
683 | 683 |
case FC_ERETRYLATER: { |
684 | 684 |
char retry_after_string[26]; |
685 | 685 |
struct tm *tm_info; |
686 |
- tm_info = localtime(&g_mirrorsDat->retry_after); |
|
686 |
+ tm_info = localtime(&g_freshclamDat->retry_after); |
|
687 | 687 |
if (NULL == tm_info) { |
688 | 688 |
logg("!Failed to query the local time for the retry-after date!\n"); |
689 | 689 |
status = FC_ERROR; |
... | ... |
@@ -750,12 +750,12 @@ fc_error_t fc_update_databases( |
750 | 750 |
|
751 | 751 |
*nUpdated = 0; |
752 | 752 |
|
753 |
- if (g_mirrorsDat->retry_after > 0) { |
|
754 |
- if (g_mirrorsDat->retry_after > time(NULL)) { |
|
753 |
+ if (g_freshclamDat->retry_after > 0) { |
|
754 |
+ if (g_freshclamDat->retry_after > time(NULL)) { |
|
755 | 755 |
/* We're on cool-down, try again later. */ |
756 | 756 |
char retry_after_string[26]; |
757 | 757 |
struct tm *tm_info; |
758 |
- tm_info = localtime(&g_mirrorsDat->retry_after); |
|
758 |
+ tm_info = localtime(&g_freshclamDat->retry_after); |
|
759 | 759 |
if (NULL == tm_info) { |
760 | 760 |
logg("!Failed to query the local time for the retry-after date!\n"); |
761 | 761 |
status = FC_ERROR; |
... | ... |
@@ -776,9 +776,9 @@ fc_error_t fc_update_databases( |
776 | 776 |
status = FC_SUCCESS; |
777 | 777 |
goto done; |
778 | 778 |
} else { |
779 |
- g_mirrorsDat->retry_after = 0; |
|
779 |
+ g_freshclamDat->retry_after = 0; |
|
780 | 780 |
logg("^Cool-down expired, ok to try again.\n"); |
781 |
- save_mirrors_dat(); |
|
781 |
+ save_freshclam_dat(); |
|
782 | 782 |
} |
783 | 783 |
} |
784 | 784 |
|
... | ... |
@@ -889,7 +889,7 @@ fc_error_t fc_download_url_database( |
889 | 889 |
case FC_ERETRYLATER: { |
890 | 890 |
char retry_after_string[26]; |
891 | 891 |
struct tm *tm_info; |
892 |
- tm_info = localtime(&g_mirrorsDat->retry_after); |
|
892 |
+ tm_info = localtime(&g_freshclamDat->retry_after); |
|
893 | 893 |
if (NULL == tm_info) { |
894 | 894 |
logg("!Failed to query the local time for the retry-after date!\n"); |
895 | 895 |
status = FC_ERROR; |
... | ... |
@@ -116,7 +116,7 @@ uint32_t g_requestTimeout = 0; |
116 | 116 |
|
117 | 117 |
uint32_t g_bCompressLocalDatabase = 0; |
118 | 118 |
|
119 |
-mirrors_dat_v1_t *g_mirrorsDat = NULL; |
|
119 |
+freshclam_dat_v1_t *g_freshclamDat = NULL; |
|
120 | 120 |
|
121 | 121 |
/** @brief Generate a Version 4 UUID according to RFC-4122 |
122 | 122 |
* |
... | ... |
@@ -164,12 +164,12 @@ static void uuid_v4_gen(char *buffer) |
164 | 164 |
return; |
165 | 165 |
} |
166 | 166 |
|
167 |
-fc_error_t load_mirrors_dat(void) |
|
167 |
+fc_error_t load_freshclam_dat(void) |
|
168 | 168 |
{ |
169 | 169 |
fc_error_t status = FC_EINIT; |
170 | 170 |
int handle = -1; |
171 | 171 |
ssize_t bread = 0; |
172 |
- mirrors_dat_v1_t *mdat = NULL; |
|
172 |
+ freshclam_dat_v1_t *mdat = NULL; |
|
173 | 173 |
uint32_t version = 0; |
174 | 174 |
char magic[13] = {0}; |
175 | 175 |
|
... | ... |
@@ -181,13 +181,13 @@ fc_error_t load_mirrors_dat(void) |
181 | 181 |
} |
182 | 182 |
logg("*Current working dir is %s\n", g_databaseDirectory); |
183 | 183 |
|
184 |
- if (-1 == (handle = open("mirrors.dat", O_RDONLY | O_BINARY))) { |
|
184 |
+ if (-1 == (handle = open("freshclam.dat", O_RDONLY | O_BINARY))) { |
|
185 | 185 |
char currdir[PATH_MAX]; |
186 | 186 |
|
187 | 187 |
if (getcwd(currdir, sizeof(currdir))) |
188 |
- logg("*Can't open mirrors.dat in %s\n", currdir); |
|
188 |
+ logg("*Can't open freshclam.dat in %s\n", currdir); |
|
189 | 189 |
else |
190 |
- logg("*Can't open mirrors.dat in the current directory\n"); |
|
190 |
+ logg("*Can't open freshclam.dat in the current directory\n"); |
|
191 | 191 |
|
192 | 192 |
logg("*It probably doesn't exist yet. That's ok.\n"); |
193 | 193 |
status = FC_EFILE; |
... | ... |
@@ -197,18 +197,18 @@ fc_error_t load_mirrors_dat(void) |
197 | 197 |
if (strlen(MIRRORS_DAT_MAGIC) != (bread = read(handle, &magic, strlen(MIRRORS_DAT_MAGIC)))) { |
198 | 198 |
char error_message[260]; |
199 | 199 |
cli_strerror(errno, error_message, 260); |
200 |
- logg("!Can't read magic from mirrors.dat. Bytes read: %zi, error: %s\n", bread, error_message); |
|
200 |
+ logg("!Can't read magic from freshclam.dat. Bytes read: %zi, error: %s\n", bread, error_message); |
|
201 | 201 |
goto done; |
202 | 202 |
} |
203 | 203 |
if (0 != strncmp(magic, MIRRORS_DAT_MAGIC, strlen(MIRRORS_DAT_MAGIC))) { |
204 |
- logg("*Magic bytes for mirrors.dat did not match expectations.\n"); |
|
204 |
+ logg("*Magic bytes for freshclam.dat did not match expectations.\n"); |
|
205 | 205 |
goto done; |
206 | 206 |
} |
207 | 207 |
|
208 | 208 |
if (sizeof(uint32_t) != (bread = read(handle, &version, sizeof(uint32_t)))) { |
209 | 209 |
char error_message[260]; |
210 | 210 |
cli_strerror(errno, error_message, 260); |
211 |
- logg("!Can't read version from mirrors.dat. Bytes read: %zi, error: %s\n", bread, error_message); |
|
211 |
+ logg("!Can't read version from freshclam.dat. Bytes read: %zi, error: %s\n", bread, error_message); |
|
212 | 212 |
goto done; |
213 | 213 |
} |
214 | 214 |
|
... | ... |
@@ -217,25 +217,25 @@ fc_error_t load_mirrors_dat(void) |
217 | 217 |
/* Verify that file size is as expected. */ |
218 | 218 |
off_t file_size = lseek(handle, 0L, SEEK_END); |
219 | 219 |
|
220 |
- if (strlen(MIRRORS_DAT_MAGIC) + sizeof(mirrors_dat_v1_t) != (size_t)file_size) { |
|
221 |
- logg("*mirrors.dat is bigger than expected: %zu != %ld\n", sizeof(mirrors_dat_v1_t), file_size); |
|
220 |
+ if (strlen(MIRRORS_DAT_MAGIC) + sizeof(freshclam_dat_v1_t) != (size_t)file_size) { |
|
221 |
+ logg("*freshclam.dat is bigger than expected: %zu != %ld\n", sizeof(freshclam_dat_v1_t), file_size); |
|
222 | 222 |
goto done; |
223 | 223 |
} |
224 | 224 |
|
225 | 225 |
/* Rewind to just after the magic bytes and read data struct */ |
226 | 226 |
lseek(handle, strlen(MIRRORS_DAT_MAGIC), SEEK_SET); |
227 | 227 |
|
228 |
- mdat = malloc(sizeof(mirrors_dat_v1_t)); |
|
228 |
+ mdat = malloc(sizeof(freshclam_dat_v1_t)); |
|
229 | 229 |
if (NULL == mdat) { |
230 |
- logg("!Failed to allocate memory for mirrors.dat\n"); |
|
230 |
+ logg("!Failed to allocate memory for freshclam.dat\n"); |
|
231 | 231 |
status = FC_EMEM; |
232 | 232 |
goto done; |
233 | 233 |
} |
234 | 234 |
|
235 |
- if (sizeof(mirrors_dat_v1_t) != (bread = read(handle, mdat, sizeof(mirrors_dat_v1_t)))) { |
|
235 |
+ if (sizeof(freshclam_dat_v1_t) != (bread = read(handle, mdat, sizeof(freshclam_dat_v1_t)))) { |
|
236 | 236 |
char error_message[260]; |
237 | 237 |
cli_strerror(errno, error_message, 260); |
238 |
- logg("!Can't read from mirrors.dat. Bytes read: %zi, error: %s\n", bread, error_message); |
|
238 |
+ logg("!Can't read from freshclam.dat. Bytes read: %zi, error: %s\n", bread, error_message); |
|
239 | 239 |
goto done; |
240 | 240 |
} |
241 | 241 |
|
... | ... |
@@ -245,27 +245,27 @@ fc_error_t load_mirrors_dat(void) |
245 | 245 |
|
246 | 246 |
/* This is the latest version. |
247 | 247 |
If we change the format in the future, we may wish to create a new |
248 |
- mirrors dat struct, import the relevant bits to the new format, |
|
249 |
- and then save (overwrite) mirrors.dat with the new data. */ |
|
250 |
- if (NULL != g_mirrorsDat) { |
|
251 |
- free(g_mirrorsDat); |
|
248 |
+ freshclam.dat struct, import the relevant bits to the new format, |
|
249 |
+ and then save (overwrite) freshclam.dat with the new data. */ |
|
250 |
+ if (NULL != g_freshclamDat) { |
|
251 |
+ free(g_freshclamDat); |
|
252 | 252 |
} |
253 |
- g_mirrorsDat = mdat; |
|
253 |
+ g_freshclamDat = mdat; |
|
254 | 254 |
mdat = NULL; |
255 | 255 |
break; |
256 | 256 |
} |
257 | 257 |
default: { |
258 |
- logg("*mirrors.dat version is different than expected: %u != %u\n", 1, version); |
|
258 |
+ logg("*freshclam.dat version is different than expected: %u != %u\n", 1, version); |
|
259 | 259 |
goto done; |
260 | 260 |
} |
261 | 261 |
} |
262 | 262 |
|
263 |
- logg("*Loaded mirrors.dat:\n"); |
|
264 |
- logg("* version: %d\n", g_mirrorsDat->version); |
|
265 |
- logg("* uuid: %s\n", g_mirrorsDat->uuid); |
|
266 |
- if (g_mirrorsDat->retry_after > 0) { |
|
263 |
+ logg("*Loaded freshclam.dat:\n"); |
|
264 |
+ logg("* version: %d\n", g_freshclamDat->version); |
|
265 |
+ logg("* uuid: %s\n", g_freshclamDat->uuid); |
|
266 |
+ if (g_freshclamDat->retry_after > 0) { |
|
267 | 267 |
char retry_after_string[26]; |
268 |
- struct tm *tm_info = localtime(&g_mirrorsDat->retry_after); |
|
268 |
+ struct tm *tm_info = localtime(&g_freshclamDat->retry_after); |
|
269 | 269 |
if (NULL == tm_info) { |
270 | 270 |
logg("!Failed to query the local time for the retry-after date!\n"); |
271 | 271 |
goto done; |
... | ... |
@@ -284,45 +284,45 @@ done: |
284 | 284 |
if (NULL != mdat) { |
285 | 285 |
free(mdat); |
286 | 286 |
} |
287 |
- if (NULL != g_mirrorsDat) { |
|
288 |
- free(g_mirrorsDat); |
|
289 |
- g_mirrorsDat = NULL; |
|
287 |
+ if (NULL != g_freshclamDat) { |
|
288 |
+ free(g_freshclamDat); |
|
289 |
+ g_freshclamDat = NULL; |
|
290 | 290 |
} |
291 | 291 |
} |
292 | 292 |
|
293 | 293 |
return status; |
294 | 294 |
} |
295 | 295 |
|
296 |
-fc_error_t save_mirrors_dat(void) |
|
296 |
+fc_error_t save_freshclam_dat(void) |
|
297 | 297 |
{ |
298 | 298 |
fc_error_t status = FC_EINIT; |
299 | 299 |
int handle = -1; |
300 | 300 |
|
301 |
- if (NULL == g_mirrorsDat) { |
|
302 |
- logg("!Attempted to save mirrors data to mirrors.dat before initializing it!\n"); |
|
301 |
+ if (NULL == g_freshclamDat) { |
|
302 |
+ logg("!Attempted to save freshclam.dat before initializing data struct!\n"); |
|
303 | 303 |
goto done; |
304 | 304 |
} |
305 | 305 |
|
306 |
- if (-1 == (handle = open("mirrors.dat", O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644))) { |
|
306 |
+ if (-1 == (handle = open("freshclam.dat", O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644))) { |
|
307 | 307 |
char currdir[PATH_MAX]; |
308 | 308 |
|
309 | 309 |
if (getcwd(currdir, sizeof(currdir))) |
310 |
- logg("!Can't create mirrors.dat in %s\n", currdir); |
|
310 |
+ logg("!Can't create freshclam.dat in %s\n", currdir); |
|
311 | 311 |
else |
312 |
- logg("!Can't create mirrors.dat in the current directory\n"); |
|
312 |
+ logg("!Can't create freshclam.dat in the current directory\n"); |
|
313 | 313 |
|
314 | 314 |
logg("Hint: The database directory must be writable for UID %d or GID %d\n", getuid(), getgid()); |
315 | 315 |
status = FC_EDBDIRACCESS; |
316 | 316 |
goto done; |
317 | 317 |
} |
318 | 318 |
if (-1 == write(handle, MIRRORS_DAT_MAGIC, strlen(MIRRORS_DAT_MAGIC))) { |
319 |
- logg("!Can't write to mirrors.dat\n"); |
|
319 |
+ logg("!Can't write to freshclam.dat\n"); |
|
320 | 320 |
} |
321 |
- if (-1 == write(handle, g_mirrorsDat, sizeof(mirrors_dat_v1_t))) { |
|
322 |
- logg("!Can't write to mirrors.dat\n"); |
|
321 |
+ if (-1 == write(handle, g_freshclamDat, sizeof(freshclam_dat_v1_t))) { |
|
322 |
+ logg("!Can't write to freshclam.dat\n"); |
|
323 | 323 |
} |
324 | 324 |
|
325 |
- logg("*Saved mirrors.dat\n"); |
|
325 |
+ logg("*Saved freshclam.dat\n"); |
|
326 | 326 |
|
327 | 327 |
status = FC_SUCCESS; |
328 | 328 |
done: |
... | ... |
@@ -333,13 +333,13 @@ done: |
333 | 333 |
return status; |
334 | 334 |
} |
335 | 335 |
|
336 |
-fc_error_t new_mirrors_dat(void) |
|
336 |
+fc_error_t new_freshclam_dat(void) |
|
337 | 337 |
{ |
338 | 338 |
fc_error_t status = FC_EINIT; |
339 | 339 |
|
340 |
- mirrors_dat_v1_t *mdat = calloc(1, sizeof(mirrors_dat_v1_t)); |
|
340 |
+ freshclam_dat_v1_t *mdat = calloc(1, sizeof(freshclam_dat_v1_t)); |
|
341 | 341 |
if (NULL == mdat) { |
342 |
- logg("!Failed to allocate memory for mirrors.dat\n"); |
|
342 |
+ logg("!Failed to allocate memory for freshclam.dat\n"); |
|
343 | 343 |
status = FC_EMEM; |
344 | 344 |
goto done; |
345 | 345 |
} |
... | ... |
@@ -348,15 +348,15 @@ fc_error_t new_mirrors_dat(void) |
348 | 348 |
mdat->retry_after = 0; |
349 | 349 |
uuid_v4_gen(mdat->uuid); |
350 | 350 |
|
351 |
- if (NULL != g_mirrorsDat) { |
|
352 |
- free(g_mirrorsDat); |
|
351 |
+ if (NULL != g_freshclamDat) { |
|
352 |
+ free(g_freshclamDat); |
|
353 | 353 |
} |
354 |
- g_mirrorsDat = mdat; |
|
354 |
+ g_freshclamDat = mdat; |
|
355 | 355 |
|
356 |
- logg("*Creating new mirrors.dat\n"); |
|
356 |
+ logg("*Creating new freshclam.dat\n"); |
|
357 | 357 |
|
358 |
- if (FC_SUCCESS != save_mirrors_dat()) { |
|
359 |
- logg("!Failed to save mirrors.dat!\n"); |
|
358 |
+ if (FC_SUCCESS != save_freshclam_dat()) { |
|
359 |
+ logg("!Failed to save freshclam.dat!\n"); |
|
360 | 360 |
status = FC_EFILE; |
361 | 361 |
goto done; |
362 | 362 |
} |
... | ... |
@@ -368,7 +368,7 @@ done: |
368 | 368 |
if (NULL != mdat) { |
369 | 369 |
free(mdat); |
370 | 370 |
} |
371 |
- g_mirrorsDat = NULL; |
|
371 |
+ g_freshclamDat = NULL; |
|
372 | 372 |
} |
373 | 373 |
return status; |
374 | 374 |
} |
... | ... |
@@ -597,7 +597,7 @@ static fc_error_t create_curl_handle( |
597 | 597 |
snprintf(userAgent, sizeof(userAgent), |
598 | 598 |
PACKAGE "/%s (OS: " TARGET_OS_TYPE ", ARCH: " TARGET_ARCH_TYPE ", CPU: " TARGET_CPU_TYPE ", UUID: %s)", |
599 | 599 |
get_version(), |
600 |
- g_mirrorsDat->uuid); |
|
600 |
+ g_freshclamDat->uuid); |
|
601 | 601 |
} |
602 | 602 |
userAgent[sizeof(userAgent) - 1] = 0; |
603 | 603 |
|
... | ... |
@@ -1013,13 +1013,13 @@ static fc_error_t remote_cvdhead( |
1013 | 1013 |
|
1014 | 1014 |
if (retry_after > 0) { |
1015 | 1015 |
/* The response gave us a Retry-After date. Use that. */ |
1016 |
- g_mirrorsDat->retry_after = time(NULL) + (time_t)retry_after; |
|
1016 |
+ g_freshclamDat->retry_after = time(NULL) + (time_t)retry_after; |
|
1017 | 1017 |
} else { |
1018 | 1018 |
/* Try again in no less than 4 hours if the response didn't specify |
1019 | 1019 |
or if CURLINFO_RETRY_AFTER is not supported. */ |
1020 |
- g_mirrorsDat->retry_after = time(NULL) + 60 * 60 * 4; |
|
1020 |
+ g_freshclamDat->retry_after = time(NULL) + 60 * 60 * 4; |
|
1021 | 1021 |
} |
1022 |
- (void)save_mirrors_dat(); |
|
1022 |
+ (void)save_freshclam_dat(); |
|
1023 | 1023 |
|
1024 | 1024 |
break; |
1025 | 1025 |
} |
... | ... |
@@ -1309,13 +1309,13 @@ static fc_error_t downloadFile( |
1309 | 1309 |
|
1310 | 1310 |
if (retry_after > 0) { |
1311 | 1311 |
/* The response gave us a Retry-After date. Use that. */ |
1312 |
- g_mirrorsDat->retry_after = time(NULL) + (time_t)retry_after; |
|
1312 |
+ g_freshclamDat->retry_after = time(NULL) + (time_t)retry_after; |
|
1313 | 1313 |
} else { |
1314 | 1314 |
/* Try again in no less than 4 hours if the response didn't specify |
1315 | 1315 |
or if CURLINFO_RETRY_AFTER is not supported. */ |
1316 |
- g_mirrorsDat->retry_after = time(NULL) + 60 * 60 * 4; |
|
1316 |
+ g_freshclamDat->retry_after = time(NULL) + 60 * 60 * 4; |
|
1317 | 1317 |
} |
1318 |
- (void)save_mirrors_dat(); |
|
1318 |
+ (void)save_freshclam_dat(); |
|
1319 | 1319 |
|
1320 | 1320 |
break; |
1321 | 1321 |
} |
... | ... |
@@ -33,12 +33,12 @@ |
33 | 33 |
// clang-format on |
34 | 34 |
|
35 | 35 |
#define SIZEOF_UUID_V4 37 /** For uuid_v4_gen(), includes NULL byte */ |
36 |
-#define MIRRORS_DAT_MAGIC "FreshClamData" /** Magic bytes for mirrors.dat found before mirrors_dat_v1_t */ |
|
37 |
-typedef struct _mirrors_dat_v1 { |
|
36 |
+#define MIRRORS_DAT_MAGIC "FreshClamData" /** Magic bytes for freshclam.dat found before freshclam_dat_v1_t */ |
|
37 |
+typedef struct _freshclam_dat_v1 { |
|
38 | 38 |
uint32_t version; /** version of this dat format */ |
39 | 39 |
char uuid[SIZEOF_UUID_V4]; /** uuid to be used in user-agent */ |
40 | 40 |
time_t retry_after; /** retry date. If > 0, don't update until after this date */ |
41 |
-} mirrors_dat_v1_t; |
|
41 |
+} freshclam_dat_v1_t; |
|
42 | 42 |
|
43 | 43 |
/* ---------------------------------------------------------------------------- |
44 | 44 |
* Internal libfreshclam globals |
... | ... |
@@ -63,11 +63,11 @@ extern uint32_t g_requestTimeout; |
63 | 63 |
|
64 | 64 |
extern uint32_t g_bCompressLocalDatabase; |
65 | 65 |
|
66 |
-extern mirrors_dat_v1_t *g_mirrorsDat; |
|
66 |
+extern freshclam_dat_v1_t *g_freshclamDat; |
|
67 | 67 |
|
68 |
-fc_error_t load_mirrors_dat(void); |
|
69 |
-fc_error_t save_mirrors_dat(void); |
|
70 |
-fc_error_t new_mirrors_dat(void); |
|
68 |
+fc_error_t load_freshclam_dat(void); |
|
69 |
+fc_error_t save_freshclam_dat(void); |
|
70 |
+fc_error_t new_freshclam_dat(void); |
|
71 | 71 |
|
72 | 72 |
fc_error_t updatedb( |
73 | 73 |
const char *database, |