... | ... |
@@ -63,15 +63,10 @@ Example |
63 | 63 |
# Default: current.cvd.clamav.net |
64 | 64 |
#DNSDatabaseInfo current.cvd.clamav.net |
65 | 65 |
|
66 |
-# Uncomment the following line and replace XY with your country |
|
67 |
-# code. See https://www.iana.org/domains/root/db for the full list. |
|
68 |
-# You can use db.XY.ipv6.clamav.net for IPv6 connections. |
|
69 |
-#DatabaseMirror db.XY.clamav.net |
|
70 |
- |
|
71 |
-# database.clamav.net is a round-robin record which points to our most |
|
72 |
-# reliable mirrors. It's used as a fall back in case db.XY.clamav.net is |
|
73 |
-# not working. DO NOT TOUCH the following line unless you know what you |
|
74 |
-# are doing. |
|
66 |
+# database.clamav.net is now the primary domain name to be used world-wide. |
|
67 |
+# Now that CloudFlare is being used as our Content Delivery Network (CDN), |
|
68 |
+# this one domain name works world-wide to direct freshclam to the closest |
|
69 |
+# geographic endpoint. |
|
75 | 70 |
DatabaseMirror database.clamav.net |
76 | 71 |
|
77 | 72 |
# How many attempts to make before giving up. |
... | ... |
@@ -186,9 +186,13 @@ help (void) |
186 | 186 |
static int |
187 | 187 |
download (const struct optstruct *opts, const char *cfgfile) |
188 | 188 |
{ |
189 |
+ time_t currtime; |
|
189 | 190 |
int ret = 0, try = 1, maxattempts = 0; |
190 | 191 |
const struct optstruct *opt; |
191 | 192 |
|
193 |
+ time(&currtime); |
|
194 |
+ logg("ClamAV update process started at %s", ctime(&currtime)); |
|
195 |
+ logg("*Using IPv6 aware code\n"); |
|
192 | 196 |
|
193 | 197 |
maxattempts = optget (opts, "MaxAttempts")->numarg; |
194 | 198 |
logg ("*Max retries == %d\n", maxattempts); |
... | ... |
@@ -225,6 +229,7 @@ download (const struct optstruct *opts, const char *cfgfile) |
225 | 225 |
{ |
226 | 226 |
logg ("Update failed. Your network may be down or none of the mirrors listed in %s is working. Check https://www.clamav.net/documents/official-mirror-faq for possible reasons.\n", cfgfile); |
227 | 227 |
} |
228 |
+ try = 1; |
|
228 | 229 |
} |
229 | 230 |
|
230 | 231 |
} |
... | ... |
@@ -299,7 +304,7 @@ main (int argc, char **argv) |
299 | 299 |
{ |
300 | 300 |
help (); |
301 | 301 |
optfree (opts); |
302 |
- return 0; |
|
302 |
+ return FC_SUCCESS; |
|
303 | 303 |
} |
304 | 304 |
|
305 | 305 |
/* check foreground option from command line to override config file */ |
... | ... |
@@ -337,7 +342,7 @@ main (int argc, char **argv) |
337 | 337 |
{ |
338 | 338 |
print_version (optget (opts, "DatabaseDirectory")->strarg); |
339 | 339 |
optfree (opts); |
340 |
- return 0; |
|
340 |
+ return FC_SUCCESS; |
|
341 | 341 |
} |
342 | 342 |
|
343 | 343 |
if (optget (opts, "HTTPProxyPassword")->enabled) |
... | ... |
@@ -492,7 +497,7 @@ main (int argc, char **argv) |
492 | 492 |
|
493 | 493 |
if (optget (opts, "list-mirrors")->enabled) |
494 | 494 |
{ |
495 |
- if (mirman_read ("mirrors.dat", &mdat, 1) == -1) |
|
495 |
+ if (mirman_read("mirrors.dat", &mdat, 1) != FC_SUCCESS) |
|
496 | 496 |
{ |
497 | 497 |
printf ("Can't read mirrors.dat\n"); |
498 | 498 |
optfree (opts); |
... | ... |
@@ -501,7 +506,7 @@ main (int argc, char **argv) |
501 | 501 |
mirman_list (&mdat); |
502 | 502 |
mirman_free (&mdat); |
503 | 503 |
optfree (opts); |
504 |
- return 0; |
|
504 |
+ return FC_SUCCESS; |
|
505 | 505 |
} |
506 | 506 |
|
507 | 507 |
if ((opt = optget (opts, "PrivateMirror"))->enabled) |
... | ... |
@@ -20,29 +20,34 @@ |
20 | 20 |
#ifndef __FRESHCLAMCODES_H |
21 | 21 |
#define __FRESHCLAMCODES_H |
22 | 22 |
|
23 |
-#define FC_UPTODATE 1 |
|
23 |
+typedef enum fc_error_tag { |
|
24 |
+ FC_SUCCESS = 0, |
|
25 |
+ FC_UPTODATE = 1, |
|
24 | 26 |
|
25 |
-#define FCE_INIT 40 |
|
26 |
-#define FCE_CHECKS 41 |
|
27 |
-#define FCE_PRIVATEMIRROR 45 |
|
27 |
+ FCE_INIT = 40, |
|
28 |
+ FCE_CHECKS = 41, |
|
29 |
+ FCE_PRIVATEMIRROR = 45, |
|
28 | 30 |
|
29 |
-#define FCE_DIRECTORY 50 |
|
30 |
-#define FCE_CONNECTION 52 |
|
31 |
-#define FCE_EMPTYFILE 53 |
|
32 |
-#define FCE_BADCVD 54 |
|
33 |
-#define FCE_FILE 55 |
|
31 |
+ FCE_DIRECTORY = 50, |
|
32 |
+ FCE_CONNECTION = 52, |
|
33 |
+ FCE_EMPTYFILE = 53, |
|
34 |
+ FCE_BADCVD = 54, |
|
35 |
+ FCE_FILE = 55, |
|
34 | 36 |
/* TESTFAIL is also 55, consider moving to new value */ |
35 |
-#define FCE_TESTFAIL 55 |
|
36 |
-#define FCE_CONFIG 56 |
|
37 |
-#define FCE_DBDIRACCESS 57 |
|
38 |
-#define FCE_FAILEDGET 58 |
|
39 |
-#define FCE_MIRRORNOTSYNC 59 |
|
37 |
+ FCE_TESTFAIL = 55, |
|
38 |
+ FCE_CONFIG = 56, |
|
39 |
+ FCE_DBDIRACCESS = 57, |
|
40 |
+ FCE_FAILEDGET = 58, |
|
41 |
+ FCE_MIRRORNOTSYNC = 59, |
|
40 | 42 |
|
41 |
-#define FCE_USERINFO 60 |
|
42 |
-#define FCE_USERORGROUP 61 |
|
43 |
-#define FCE_LOGGING 62 |
|
43 |
+ FCE_USERINFO = 60, |
|
44 |
+ FCE_USERORGROUP = 61, |
|
45 |
+ FCE_LOGGING = 62, |
|
44 | 46 |
|
45 |
-#define FCE_FAILEDUPDATE 70 |
|
46 |
-#define FCE_MEM 75 |
|
47 |
+ FCE_FAILEDUPDATE = 70, |
|
48 |
+ FCE_MEM = 75, |
|
49 |
+ FCE_ARG = 76, |
|
50 |
+ FCE_OPEN = 77 |
|
51 |
+} fc_error_t; |
|
47 | 52 |
|
48 | 53 |
#endif |
... | ... |
@@ -186,6 +186,7 @@ wwwconnect (const char *server, const char *proxy, int pport, char *ip, |
186 | 186 |
const char *localip, int ctimeout, struct mirdat *mdat, |
187 | 187 |
int logerr, unsigned int can_whitelist, unsigned int attempt) |
188 | 188 |
{ |
189 |
+ mir_status_t mirror_status = MIRROR_OK; |
|
189 | 190 |
int socketfd, port, ret; |
190 | 191 |
unsigned int ips = 0, ignored = 0, i; |
191 | 192 |
struct addrinfo hints, *res = NULL, *rp, *loadbal_rp = NULL, *addrs[128]; |
... | ... |
@@ -193,7 +194,7 @@ wwwconnect (const char *server, const char *proxy, int pport, char *ip, |
193 | 193 |
uint32_t loadbal = 1, minsucc = 0xffffffff, minfail = |
194 | 194 |
0xffffffff, addrnum = 0; |
195 | 195 |
int ipv4start = -1, ipv4end = -1; |
196 |
- struct mirdat_ip *md; |
|
196 |
+ struct mirdat_ip *md = NULL; |
|
197 | 197 |
char ipaddr[46]; |
198 | 198 |
const char *hostpt; |
199 | 199 |
|
... | ... |
@@ -288,25 +289,32 @@ wwwconnect (const char *server, const char *proxy, int pport, char *ip, |
288 | 288 |
return -1; |
289 | 289 |
} |
290 | 290 |
|
291 |
- if (mdat && (ret = mirman_check (addr, rp->ai_family, mdat, &md))) |
|
291 |
+ if (mdat) |
|
292 | 292 |
{ |
293 |
- if (ret == 1) |
|
294 |
- logg ("*Ignoring mirror %s (due to previous errors)\n", |
|
295 |
- ipaddr); |
|
296 |
- else |
|
297 |
- logg ("*Ignoring mirror %s (has connected too many times with an outdated version)\n", ipaddr); |
|
298 |
- |
|
299 |
- ignored++; |
|
300 |
- if (!loadbal || i + 1 < addrnum) |
|
293 |
+ if (FC_SUCCESS != (ret = mirman_check (addr, rp->ai_family, mdat, &md, &mirror_status))) |
|
301 | 294 |
{ |
302 |
- i++; |
|
303 |
- continue; |
|
295 |
+ logg ("!Failed to check mirrors.dat!\n"); |
|
296 |
+ return -1; |
|
297 |
+ } |
|
298 |
+ else if (MIRROR_OK != mirror_status) |
|
299 |
+ { |
|
300 |
+ if (MIRROR_IGNORE__PREV_ERRS == mirror_status) |
|
301 |
+ logg ("*Ignoring mirror %s (due to previous errors)\n", ipaddr); |
|
302 |
+ else if (MIRROR_IGNORE__OUTDATED_VERSION == mirror_status) |
|
303 |
+ logg ("*Ignoring mirror %s (has connected too many times with an outdated version)\n", ipaddr); |
|
304 |
+ |
|
305 |
+ ignored++; |
|
306 |
+ if (!loadbal || i + 1 < addrnum) |
|
307 |
+ { |
|
308 |
+ i++; |
|
309 |
+ continue; |
|
310 |
+ } |
|
304 | 311 |
} |
305 | 312 |
} |
306 | 313 |
|
307 | 314 |
if (mdat && loadbal) |
308 | 315 |
{ |
309 |
- if (!ret) |
|
316 |
+ if (MIRROR_OK == mirror_status) |
|
310 | 317 |
{ |
311 | 318 |
if (!md) |
312 | 319 |
{ |
... | ... |
@@ -387,7 +395,7 @@ wwwconnect (const char *server, const char *proxy, int pport, char *ip, |
387 | 387 |
else |
388 | 388 |
i++; |
389 | 389 |
if (mdat) |
390 |
- mirman_update (addr, rp->ai_family, mdat, 2); |
|
390 |
+ mirman_update (addr, rp->ai_family, mdat, FCE_CONNECTION); |
|
391 | 391 |
continue; |
392 | 392 |
} |
393 | 393 |
else |
... | ... |
@@ -647,7 +655,7 @@ remote_cvdhead (const char *cvdfile, const char *localfile, |
647 | 647 |
{ |
648 | 648 |
logg ("%cremote_cvdhead: Error while reading CVD header from %s\n", |
649 | 649 |
logerr ? '!' : '^', hostname); |
650 |
- mirman_update (mdat->currip, mdat->af, mdat, 1); |
|
650 |
+ mirman_update (mdat->currip, mdat->af, mdat, FCE_FAILEDGET); |
|
651 | 651 |
return NULL; |
652 | 652 |
} |
653 | 653 |
|
... | ... |
@@ -656,7 +664,7 @@ remote_cvdhead (const char *cvdfile, const char *localfile, |
656 | 656 |
{ |
657 | 657 |
logg ("%c%s not found on remote server\n", logerr ? '!' : '^', |
658 | 658 |
cvdfile); |
659 |
- mirman_update (mdat->currip, mdat->af, mdat, 2); |
|
659 |
+ mirman_update (mdat->currip, mdat->af, mdat, FCE_FAILEDGET); |
|
660 | 660 |
return NULL; |
661 | 661 |
} |
662 | 662 |
|
... | ... |
@@ -667,7 +675,7 @@ remote_cvdhead (const char *cvdfile, const char *localfile, |
667 | 667 |
/* mirror status: up to date */ |
668 | 668 |
*ims = 0; |
669 | 669 |
logg ("OK (IMS)\n"); |
670 |
- mirman_update (mdat->currip, mdat->af, mdat, 0); |
|
670 |
+ mirman_update (mdat->currip, mdat->af, mdat, FC_SUCCESS); |
|
671 | 671 |
return NULL; |
672 | 672 |
} |
673 | 673 |
else |
... | ... |
@@ -680,8 +688,18 @@ remote_cvdhead (const char *cvdfile, const char *localfile, |
680 | 680 |
&& !strstr (buffer, "HTTP/1.1 206") |
681 | 681 |
&& !strstr (buffer, "HTTP/1.0 206")) |
682 | 682 |
{ |
683 |
- logg ("%cUnknown response from remote server\n", logerr ? '!' : '^'); |
|
684 |
- mirman_update (mdat->currip, mdat->af, mdat, 1); |
|
683 |
+ char * respcode = NULL; |
|
684 |
+ if ((NULL != (respcode = strstr (buffer, "HTTP/1.0 "))) || |
|
685 |
+ (NULL != (respcode = strstr (buffer, "HTTP/1.1 ")))) { |
|
686 |
+ /* There was some sort of response code...*/ |
|
687 |
+ char * httpcode = calloc(MIN(FILEBUFF - (size_t)(respcode - buffer), 13) + 1, 1); |
|
688 |
+ memcpy(httpcode, respcode, MIN(FILEBUFF - (size_t)(respcode - buffer), 13)); |
|
689 |
+ logg ("%cremote_cvdhead: Unknown response from %s (IP: %s): %s\n", logerr ? '!' : '^', hostname, ipaddr, httpcode); |
|
690 |
+ free (httpcode); |
|
691 |
+ } else { |
|
692 |
+ logg ("%cremote_cvdhead: Unknown response from %s (IP: %s)\n", logerr ? '!' : '^', hostname, ipaddr); |
|
693 |
+ } |
|
694 |
+ mirman_update (mdat->currip, mdat->af, mdat, FCE_FAILEDGET); |
|
685 | 695 |
return NULL; |
686 | 696 |
} |
687 | 697 |
|
... | ... |
@@ -704,7 +722,7 @@ remote_cvdhead (const char *cvdfile, const char *localfile, |
704 | 704 |
{ |
705 | 705 |
logg ("%cremote_cvdhead: Malformed CVD header (too short)\n", |
706 | 706 |
logerr ? '!' : '^'); |
707 |
- mirman_update (mdat->currip, mdat->af, mdat, 1); |
|
707 |
+ mirman_update (mdat->currip, mdat->af, mdat, FCE_BADCVD); |
|
708 | 708 |
return NULL; |
709 | 709 |
} |
710 | 710 |
|
... | ... |
@@ -716,7 +734,7 @@ remote_cvdhead (const char *cvdfile, const char *localfile, |
716 | 716 |
{ |
717 | 717 |
logg ("%cremote_cvdhead: Malformed CVD header (bad chars)\n", |
718 | 718 |
logerr ? '!' : '^'); |
719 |
- mirman_update (mdat->currip, mdat->af, mdat, 1); |
|
719 |
+ mirman_update (mdat->currip, mdat->af, mdat, FCE_BADCVD); |
|
720 | 720 |
return NULL; |
721 | 721 |
} |
722 | 722 |
head[j] = ch[j]; |
... | ... |
@@ -726,18 +744,18 @@ remote_cvdhead (const char *cvdfile, const char *localfile, |
726 | 726 |
{ |
727 | 727 |
logg ("%cremote_cvdhead: Malformed CVD header (can't parse)\n", |
728 | 728 |
logerr ? '!' : '^'); |
729 |
- mirman_update (mdat->currip, mdat->af, mdat, 1); |
|
729 |
+ mirman_update (mdat->currip, mdat->af, mdat, FCE_BADCVD); |
|
730 | 730 |
} |
731 | 731 |
else |
732 | 732 |
{ |
733 | 733 |
logg ("OK\n"); |
734 |
- mirman_update (mdat->currip, mdat->af, mdat, 0); |
|
734 |
+ mirman_update (mdat->currip, mdat->af, mdat, FC_SUCCESS); |
|
735 | 735 |
} |
736 | 736 |
|
737 | 737 |
return cvd; |
738 | 738 |
} |
739 | 739 |
|
740 |
-static int |
|
740 |
+static fc_error_t |
|
741 | 741 |
getfile_mirman (const char *srcfile, const char *destfile, |
742 | 742 |
const char *hostname, char *ip, const char *localip, |
743 | 743 |
const char *proxy, int port, const char *user, |
... | ... |
@@ -757,6 +775,8 @@ getfile_mirman (const char *srcfile, const char *destfile, |
757 | 757 |
UNUSEDPARAM(ctimeout); |
758 | 758 |
UNUSEDPARAM(can_whitelist); |
759 | 759 |
|
760 |
+ memset (buffer, 0, sizeof(FILEBUFF)); |
|
761 |
+ |
|
760 | 762 |
if (proxy) |
761 | 763 |
{ |
762 | 764 |
remotename = malloc (strlen (hostname) + 8); |
... | ... |
@@ -842,7 +862,7 @@ getfile_mirman (const char *srcfile, const char *destfile, |
842 | 842 |
else |
843 | 843 |
logg ("%cgetfile: Error while reading database from %s (IP: %s): %s\n", logerr ? '!' : '^', hostname, ipaddr, strerror (errno)); |
844 | 844 |
if (mdat) |
845 |
- mirman_update (mdat->currip, mdat->af, mdat, 1); |
|
845 |
+ mirman_update (mdat->currip, mdat->af, mdat, FCE_FAILEDGET); |
|
846 | 846 |
return FCE_CONNECTION; |
847 | 847 |
} |
848 | 848 |
|
... | ... |
@@ -869,7 +889,7 @@ getfile_mirman (const char *srcfile, const char *destfile, |
869 | 869 |
ipaddr); |
870 | 870 |
|
871 | 871 |
if (mdat) |
872 |
- mirman_update (mdat->currip, mdat->af, mdat, 2); |
|
872 |
+ mirman_update (mdat->currip, mdat->af, mdat, FCE_FAILEDGET); |
|
873 | 873 |
return FCE_FAILEDGET; |
874 | 874 |
} |
875 | 875 |
|
... | ... |
@@ -877,7 +897,7 @@ getfile_mirman (const char *srcfile, const char *destfile, |
877 | 877 |
if (strstr (buffer, "HTTP/1.1 304") || strstr (buffer, "HTTP/1.0 304")) |
878 | 878 |
{ |
879 | 879 |
if (mdat) |
880 |
- mirman_update (mdat->currip, mdat->af, mdat, 0); |
|
880 |
+ mirman_update (mdat->currip, mdat->af, mdat, FC_SUCCESS); |
|
881 | 881 |
return FC_UPTODATE; |
882 | 882 |
} |
883 | 883 |
|
... | ... |
@@ -885,14 +905,30 @@ getfile_mirman (const char *srcfile, const char *destfile, |
885 | 885 |
&& !strstr (buffer, "HTTP/1.1 206") |
886 | 886 |
&& !strstr (buffer, "HTTP/1.0 206")) |
887 | 887 |
{ |
888 |
- if (proxy) |
|
889 |
- logg ("%cgetfile: Unknown response from %s\n", |
|
890 |
- logerr ? '!' : '^', hostname); |
|
891 |
- else |
|
892 |
- logg ("%cgetfile: Unknown response from %s (IP: %s)\n", |
|
893 |
- logerr ? '!' : '^', hostname, ipaddr); |
|
888 |
+ char * respcode = NULL; |
|
889 |
+ if ((NULL != (respcode = strstr (buffer, "HTTP/1.0 "))) || |
|
890 |
+ (NULL != (respcode = strstr (buffer, "HTTP/1.1 ")))) { |
|
891 |
+ /* There was some sort of response code...*/ |
|
892 |
+ char * httpcode = calloc(MIN(FILEBUFF - (size_t)(respcode - buffer), 13) + 1, 1); |
|
893 |
+ memcpy(httpcode, respcode, MIN(FILEBUFF - (size_t)(respcode - buffer), 13)); |
|
894 |
+ if (proxy) |
|
895 |
+ logg ("%cgetfile: Unknown response from %s: %s\n", |
|
896 |
+ logerr ? '!' : '^', hostname, httpcode); |
|
897 |
+ else |
|
898 |
+ logg ("%cgetfile: Unknown response from %s (IP: %s): %s\n", |
|
899 |
+ logerr ? '!' : '^', hostname, ipaddr, httpcode); |
|
900 |
+ free (httpcode); |
|
901 |
+ } |
|
902 |
+ else { |
|
903 |
+ if (proxy) |
|
904 |
+ logg ("%cgetfile: Unknown response from %s\n", |
|
905 |
+ logerr ? '!' : '^', hostname); |
|
906 |
+ else |
|
907 |
+ logg ("%cgetfile: Unknown response from %s (IP: %s)\n", |
|
908 |
+ logerr ? '!' : '^', hostname, ipaddr); |
|
909 |
+ } |
|
894 | 910 |
if (mdat) |
895 |
- mirman_update (mdat->currip, mdat->af, mdat, 1); |
|
911 |
+ mirman_update (mdat->currip, mdat->af, mdat, FCE_FAILEDGET); |
|
896 | 912 |
return FCE_FAILEDGET; |
897 | 913 |
} |
898 | 914 |
|
... | ... |
@@ -983,7 +1019,7 @@ getfile_mirman (const char *srcfile, const char *destfile, |
983 | 983 |
logg ("%cgetfile: Download interrupted: %s (IP: %s)\n", |
984 | 984 |
logerr ? '!' : '^', strerror (errno), ipaddr); |
985 | 985 |
if (mdat) |
986 |
- mirman_update (mdat->currip, mdat->af, mdat, 2); |
|
986 |
+ mirman_update (mdat->currip, mdat->af, mdat, FCE_CONNECTION); |
|
987 | 987 |
return FCE_CONNECTION; |
988 | 988 |
} |
989 | 989 |
|
... | ... |
@@ -996,8 +1032,8 @@ getfile_mirman (const char *srcfile, const char *destfile, |
996 | 996 |
logg ("Downloading %s [*]\n", fname); |
997 | 997 |
|
998 | 998 |
if (mdat) |
999 |
- mirman_update (mdat->currip, mdat->af, mdat, 0); |
|
1000 |
- return 0; |
|
999 |
+ mirman_update (mdat->currip, mdat->af, mdat, FC_SUCCESS); |
|
1000 |
+ return FC_SUCCESS; |
|
1001 | 1001 |
} |
1002 | 1002 |
|
1003 | 1003 |
static int |
... | ... |
@@ -1024,23 +1060,13 @@ getfile (const char *srcfile, const char *destfile, const char *hostname, |
1024 | 1024 |
if (sd < 0) |
1025 | 1025 |
return FCE_CONNECTION; |
1026 | 1026 |
|
1027 |
- if (mdat) |
|
1028 |
- { |
|
1029 |
- mirman_update_sf (mdat->currip, mdat->af, mdat, 0, 1); |
|
1030 |
- mirman_write ("mirrors.dat", dbdir, mdat); |
|
1031 |
- } |
|
1032 |
- |
|
1033 |
- ret = |
|
1034 |
- getfile_mirman (srcfile, destfile, hostname, ip, localip, proxy, port, |
|
1027 |
+ ret = getfile_mirman (srcfile, destfile, hostname, ip, localip, proxy, port, |
|
1035 | 1028 |
user, pass, uas, ctimeout, rtimeout, mdat, logerr, |
1036 | 1029 |
can_whitelist, ims, ipaddr, sd); |
1037 | 1030 |
closesocket (sd); |
1038 | 1031 |
|
1039 |
- if (mdat) |
|
1040 |
- { |
|
1041 |
- mirman_update_sf (mdat->currip, mdat->af, mdat, 0, -1); |
|
1042 |
- mirman_write ("mirrors.dat", dbdir, mdat); |
|
1043 |
- } |
|
1032 |
+ /* Update mirrors.dat */ |
|
1033 |
+ (void) mirman_write ("mirrors.dat", dbdir, mdat); |
|
1044 | 1034 |
|
1045 | 1035 |
return ret; |
1046 | 1036 |
} |
... | ... |
@@ -1118,14 +1144,21 @@ getcvd (const char *cvdfile, const char *newfile, const char *hostname, |
1118 | 1118 |
if (cvd->version < newver) |
1119 | 1119 |
{ |
1120 | 1120 |
logg ("^Mirror %s is not synchronized.\n", ip); |
1121 |
- mirman_update (mdat->currip, mdat->af, mdat, 2); |
|
1122 |
- cl_cvdfree (cvd); |
|
1123 | 1121 |
unlink (newfile); |
1124 |
- return FCE_MIRRORNOTSYNC; |
|
1122 |
+ if (cvd->version < newver - 1) |
|
1123 |
+ { |
|
1124 |
+ logg ("^Mirror is more than 1 version out of date. Recording mirror failure.\n"); |
|
1125 |
+ mirman_update (mdat->currip, mdat->af, mdat, FCE_MIRRORNOTSYNC); |
|
1126 |
+ cl_cvdfree (cvd); |
|
1127 |
+ return FCE_MIRRORNOTSYNC; |
|
1128 |
+ } |
|
1129 |
+ |
|
1130 |
+ cl_cvdfree (cvd); |
|
1131 |
+ return FC_UPTODATE; |
|
1125 | 1132 |
} |
1126 | 1133 |
|
1127 | 1134 |
cl_cvdfree (cvd); |
1128 |
- return 0; |
|
1135 |
+ return FC_SUCCESS; |
|
1129 | 1136 |
} |
1130 | 1137 |
|
1131 | 1138 |
static int |
... | ... |
@@ -1251,7 +1284,7 @@ getpatch (const char *dbname, const char *tmpdir, int version, |
1251 | 1251 |
logg ("!getpatch: Can't chdir to %s\n", olddir); |
1252 | 1252 |
return FCE_DIRECTORY; |
1253 | 1253 |
} |
1254 |
- return 0; |
|
1254 |
+ return FC_SUCCESS; |
|
1255 | 1255 |
} |
1256 | 1256 |
|
1257 | 1257 |
static struct cl_cvd * |
... | ... |
@@ -1508,7 +1541,7 @@ test_database (const char *newfile, const char *newdb, int bytecode) |
1508 | 1508 |
&& engine->domainlist_matcher->sha256_pfx_set.keys) |
1509 | 1509 |
cli_hashset_destroy (&engine->domainlist_matcher->sha256_pfx_set); |
1510 | 1510 |
cl_engine_free (engine); |
1511 |
- return 0; |
|
1511 |
+ return FC_SUCCESS; |
|
1512 | 1512 |
} |
1513 | 1513 |
|
1514 | 1514 |
#ifndef WIN32 |
... | ... |
@@ -1582,7 +1615,7 @@ test_database_wrap (const char *file, const char *newdb, int bytecode) |
1582 | 1582 |
} |
1583 | 1583 |
if (firstline[0]) |
1584 | 1584 |
logg ("^Database successfully loaded, but there is stderr output\n"); |
1585 |
- return 0; |
|
1585 |
+ return FC_SUCCESS; |
|
1586 | 1586 |
} |
1587 | 1587 |
if (WIFSIGNALED (status)) |
1588 | 1588 |
{ |
... | ... |
@@ -2260,7 +2293,7 @@ updatedb (const char *dbname, const char *hostname, char *ip, int *signo, |
2260 | 2260 |
} |
2261 | 2261 |
#endif |
2262 | 2262 |
cl_cvdfree (current); |
2263 |
- return 0; |
|
2263 |
+ return FC_SUCCESS; |
|
2264 | 2264 |
} |
2265 | 2265 |
|
2266 | 2266 |
static int |
... | ... |
@@ -2480,14 +2513,13 @@ updatecustomdb (const char *url, int *signo, const struct optstruct *opts, |
2480 | 2480 |
|
2481 | 2481 |
logg ("%s updated (version: custom database, sigs: %u)\n", dbname, sigs); |
2482 | 2482 |
*signo += sigs; |
2483 |
- return 0; |
|
2483 |
+ return FC_SUCCESS; |
|
2484 | 2484 |
} |
2485 | 2485 |
|
2486 | 2486 |
int |
2487 | 2487 |
downloadmanager (const struct optstruct *opts, const char *hostname, |
2488 | 2488 |
unsigned int attempt) |
2489 | 2489 |
{ |
2490 |
- time_t currtime; |
|
2491 | 2490 |
int ret, custret = 0, updated = 0, outdated = 0, signo = 0, logerr; |
2492 | 2491 |
unsigned int ttl; |
2493 | 2492 |
char ipaddr[46], *dnsreply = NULL, *pt, *localip = NULL, *newver = NULL; |
... | ... |
@@ -2512,10 +2544,6 @@ downloadmanager (const struct optstruct *opts, const char *hostname, |
2512 | 2512 |
return FCE_DBDIRACCESS; |
2513 | 2513 |
} |
2514 | 2514 |
|
2515 |
- time (&currtime); |
|
2516 |
- logg ("ClamAV update process started at %s", ctime (&currtime)); |
|
2517 |
- logg ("*Using IPv6 aware code\n"); |
|
2518 |
- |
|
2519 | 2515 |
#ifdef HAVE_RESOLV_H |
2520 | 2516 |
dnsdbinfo = optget (opts, "DNSDatabaseInfo")->strarg; |
2521 | 2517 |
|
... | ... |
@@ -2635,7 +2663,7 @@ downloadmanager (const struct optstruct *opts, const char *hostname, |
2635 | 2635 |
} |
2636 | 2636 |
free (dnsreply); |
2637 | 2637 |
free (newver); |
2638 |
- mirman_write ("mirrors.dat", dbdir, &mdat); |
|
2638 |
+ (void) mirman_write ("mirrors.dat", dbdir, &mdat); |
|
2639 | 2639 |
mirman_free (&mdat); |
2640 | 2640 |
cli_rmdirs (updtmpdir); |
2641 | 2641 |
return custret; |
... | ... |
@@ -2663,7 +2691,7 @@ downloadmanager (const struct optstruct *opts, const char *hostname, |
2663 | 2663 |
free (dnsreply); |
2664 | 2664 |
if (newver) |
2665 | 2665 |
free (newver); |
2666 |
- mirman_write ("mirrors.dat", dbdir, &mdat); |
|
2666 |
+ (void) mirman_write ("mirrors.dat", dbdir, &mdat); |
|
2667 | 2667 |
mirman_free (&mdat); |
2668 | 2668 |
cli_rmdirs (updtmpdir); |
2669 | 2669 |
return ret; |
... | ... |
@@ -2685,7 +2713,7 @@ downloadmanager (const struct optstruct *opts, const char *hostname, |
2685 | 2685 |
free (dnsreply); |
2686 | 2686 |
if (newver) |
2687 | 2687 |
free (newver); |
2688 |
- mirman_write ("mirrors.dat", dbdir, &mdat); |
|
2688 |
+ (void) mirman_write ("mirrors.dat", dbdir, &mdat); |
|
2689 | 2689 |
mirman_free (&mdat); |
2690 | 2690 |
cli_rmdirs (updtmpdir); |
2691 | 2691 |
return ret; |
... | ... |
@@ -2702,7 +2730,7 @@ downloadmanager (const struct optstruct *opts, const char *hostname, |
2702 | 2702 |
free (dnsreply); |
2703 | 2703 |
if (newver) |
2704 | 2704 |
free (newver); |
2705 |
- mirman_write ("mirrors.dat", dbdir, &mdat); |
|
2705 |
+ (void) mirman_write ("mirrors.dat", dbdir, &mdat); |
|
2706 | 2706 |
mirman_free (&mdat); |
2707 | 2707 |
cli_rmdirs (updtmpdir); |
2708 | 2708 |
return ret; |
... | ... |
@@ -2736,7 +2764,7 @@ downloadmanager (const struct optstruct *opts, const char *hostname, |
2736 | 2736 |
free (dnsreply); |
2737 | 2737 |
if (newver) |
2738 | 2738 |
free (newver); |
2739 |
- mirman_write ("mirrors.dat", dbdir, &mdat); |
|
2739 |
+ (void) mirman_write ("mirrors.dat", dbdir, &mdat); |
|
2740 | 2740 |
mirman_free (&mdat); |
2741 | 2741 |
cli_rmdirs (updtmpdir); |
2742 | 2742 |
return ret; |
... | ... |
@@ -2771,7 +2799,7 @@ downloadmanager (const struct optstruct *opts, const char *hostname, |
2771 | 2771 |
free (dnsreply); |
2772 | 2772 |
if (newver) |
2773 | 2773 |
free (newver); |
2774 |
- mirman_write ("mirrors.dat", dbdir, &mdat); |
|
2774 |
+ (void) mirman_write ("mirrors.dat", dbdir, &mdat); |
|
2775 | 2775 |
mirman_free (&mdat); |
2776 | 2776 |
cli_rmdirs (updtmpdir); |
2777 | 2777 |
return ret; |
... | ... |
@@ -2793,7 +2821,7 @@ downloadmanager (const struct optstruct *opts, const char *hostname, |
2793 | 2793 |
free (dnsreply); |
2794 | 2794 |
if (newver) |
2795 | 2795 |
free (newver); |
2796 |
- mirman_write ("mirrors.dat", dbdir, &mdat); |
|
2796 |
+ (void) mirman_write ("mirrors.dat", dbdir, &mdat); |
|
2797 | 2797 |
mirman_free (&mdat); |
2798 | 2798 |
cli_rmdirs (updtmpdir); |
2799 | 2799 |
return ret; |
... | ... |
@@ -2808,7 +2836,7 @@ downloadmanager (const struct optstruct *opts, const char *hostname, |
2808 | 2808 |
if (dnsreply) |
2809 | 2809 |
free (dnsreply); |
2810 | 2810 |
|
2811 |
- mirman_write ("mirrors.dat", dbdir, &mdat); |
|
2811 |
+ (void) mirman_write ("mirrors.dat", dbdir, &mdat); |
|
2812 | 2812 |
mirman_free (&mdat); |
2813 | 2813 |
|
2814 | 2814 |
cli_rmdirs (updtmpdir); |
... | ... |
@@ -50,11 +50,11 @@ |
50 | 50 |
#endif |
51 | 51 |
#endif |
52 | 52 |
|
53 |
-#define IGNORE_LONG 3 * 86400 |
|
54 |
-#define IGNORE_SHORT 6 * 3600 |
|
53 |
+#define IGNORE_SHORT (3600) /* 1 hour */ |
|
54 |
+#define IGNORE_LONG (6 * IGNORE_SHORT) /* 6 hours */ |
|
55 | 55 |
|
56 | 56 |
void |
57 |
-mirman_free (struct mirdat *mdat) |
|
57 |
+mirman_free(struct mirdat *mdat) |
|
58 | 58 |
{ |
59 | 59 |
if (mdat && mdat->num) |
60 | 60 |
{ |
... | ... |
@@ -63,34 +63,32 @@ mirman_free (struct mirdat *mdat) |
63 | 63 |
} |
64 | 64 |
} |
65 | 65 |
|
66 |
-int |
|
67 |
-mirman_read (const char *file, struct mirdat *mdat, uint8_t active) |
|
66 |
+fc_error_t mirman_read(const char *file, struct mirdat *mdat, uint8_t active) |
|
68 | 67 |
{ |
69 | 68 |
struct mirdat_ip mip; |
70 | 69 |
int fd, bread; |
71 | 70 |
|
72 |
- |
|
73 |
- memset (mdat, 0, sizeof (struct mirdat)); |
|
71 |
+ memset (mdat, 0, sizeof(struct mirdat)); |
|
74 | 72 |
|
75 | 73 |
if (!(mdat->active = active)) |
76 |
- return 0; |
|
74 |
+ return FC_SUCCESS; |
|
77 | 75 |
|
78 | 76 |
if ((fd = open (file, O_RDONLY | O_BINARY)) == -1) |
79 |
- return -1; |
|
77 |
+ return FCE_OPEN; |
|
80 | 78 |
|
81 |
- while ((bread = read (fd, &mip, sizeof (mip))) == sizeof (mip)) |
|
79 |
+ while ((bread = read (fd, &mip, sizeof(mip))) == sizeof(mip)) |
|
82 | 80 |
{ |
83 | 81 |
mdat->mirtab = |
84 | 82 |
(struct mirdat_ip *) realloc (mdat->mirtab, |
85 |
- (mdat->num + 1) * sizeof (mip)); |
|
83 |
+ (mdat->num + 1) * sizeof(mip)); |
|
86 | 84 |
if (!mdat->mirtab) |
87 | 85 |
{ |
88 |
- logg ("!Can't allocate memory for mdat->mirtab\n"); |
|
86 |
+ logg("!Can't allocate memory for mdat->mirtab\n"); |
|
89 | 87 |
mirman_free (mdat); |
90 | 88 |
close (fd); |
91 |
- return -1; |
|
89 |
+ return FCE_MEM; |
|
92 | 90 |
} |
93 |
- memcpy (&mdat->mirtab[mdat->num], &mip, sizeof (mip)); |
|
91 |
+ memcpy (&mdat->mirtab[mdat->num], &mip, sizeof(mip)); |
|
94 | 92 |
mdat->num++; |
95 | 93 |
} |
96 | 94 |
|
... | ... |
@@ -98,156 +96,136 @@ mirman_read (const char *file, struct mirdat *mdat, uint8_t active) |
98 | 98 |
|
99 | 99 |
if (bread) |
100 | 100 |
{ |
101 |
- logg ("^Removing broken %s file.\n", file); |
|
101 |
+ logg("^Removing broken %s file.\n", file); |
|
102 | 102 |
unlink (file); |
103 | 103 |
mirman_free (mdat); |
104 |
- return -1; |
|
104 |
+ return FCE_FILE; |
|
105 | 105 |
} |
106 | 106 |
|
107 |
- return 0; |
|
107 |
+ return FC_SUCCESS; |
|
108 | 108 |
} |
109 | 109 |
|
110 |
-int |
|
111 |
-mirman_check (uint32_t * ip, int af, struct mirdat *mdat, |
|
112 |
- struct mirdat_ip **md) |
|
110 |
+fc_error_t mirman_check(uint32_t * ip, int af, struct mirdat *mdat, |
|
111 |
+ struct mirdat_ip **md, mir_status_t *mirror_status) |
|
113 | 112 |
{ |
114 |
- unsigned int i, flevel = cl_retflevel (); |
|
113 |
+ fc_error_t status = FC_SUCCESS; |
|
114 |
+ unsigned int i; |
|
115 |
+ unsigned int flevel = cl_retflevel (); |
|
115 | 116 |
|
117 |
+ if (NULL == md || NULL == mdat || NULL == ip) { |
|
118 |
+ logg("!mirman_check: Invalid arguments.\n"); |
|
119 |
+ status = FCE_ARG; |
|
120 |
+ goto done; |
|
121 |
+ } |
|
116 | 122 |
|
117 |
- if (md) |
|
118 |
- *md = NULL; |
|
123 |
+ *md = NULL; |
|
119 | 124 |
|
120 | 125 |
if (!mdat->active) |
121 |
- return 0; |
|
126 |
+ { |
|
127 |
+ *mirror_status = MIRROR_OK; |
|
128 |
+ goto done; |
|
129 |
+ } |
|
122 | 130 |
|
123 | 131 |
for (i = 0; i < mdat->num; i++) |
124 | 132 |
{ |
125 |
- |
|
126 |
- if ((af == AF_INET && mdat->mirtab[i].ip4 == *ip) |
|
127 |
- || (af == AF_INET6 |
|
128 |
- && !memcmp (mdat->mirtab[i].ip6, ip, 4 * sizeof (uint32_t)))) |
|
133 |
+ if ((af == AF_INET && mdat->mirtab[i].ip4 == *ip) || |
|
134 |
+ ((af == AF_INET6) && (!memcmp (mdat->mirtab[i].ip6, ip, 4 * sizeof(uint32_t))))) |
|
129 | 135 |
{ |
136 |
+ /* |
|
137 |
+ * Mirror found in mirror table. |
|
138 |
+ */ |
|
130 | 139 |
|
131 |
- if (!mdat->mirtab[i].atime && !mdat->mirtab[i].ignore) |
|
140 |
+ if (mdat->dbflevel && (mdat->dbflevel > flevel) && (mdat->dbflevel - flevel > 3)) |
|
132 | 141 |
{ |
133 |
- if (md) |
|
134 |
- *md = &mdat->mirtab[i]; |
|
135 |
- return 0; |
|
142 |
+ /* Functionality level of database is lower than |
|
143 |
+ * level of the database we already have */ |
|
144 |
+ if (difftime(time(NULL), mdat->mirtab[i].atime) < (mdat->dbflevel - flevel) * 3600) |
|
145 |
+ { |
|
146 |
+ *mirror_status = MIRROR_IGNORE__OUTDATED_VERSION; |
|
147 |
+ goto done; |
|
148 |
+ } |
|
136 | 149 |
} |
137 | 150 |
|
138 |
- if (mdat->dbflevel && (mdat->dbflevel > flevel) |
|
139 |
- && (mdat->dbflevel - flevel > 3)) |
|
140 |
- if (time (NULL) - mdat->mirtab[i].atime < |
|
141 |
- (mdat->dbflevel - flevel) * 3600) |
|
142 |
- return 2; |
|
143 |
- |
|
144 |
- if (mdat->mirtab[i].ignore) |
|
151 |
+ if ((mdat->mirtab[i].atime > 0) && |
|
152 |
+ (IGNORE_NO != mdat->mirtab[i].ignore)) |
|
145 | 153 |
{ |
146 |
- if (!mdat->mirtab[i].atime) |
|
147 |
- return 1; |
|
148 |
- |
|
149 |
- if (time (NULL) - mdat->mirtab[i].atime > IGNORE_LONG) |
|
154 |
+ /* |
|
155 |
+ * Found, but the ignore flag is set. |
|
156 |
+ */ |
|
157 |
+ if (difftime(time(NULL), mdat->mirtab[i].atime) > IGNORE_LONG) |
|
150 | 158 |
{ |
151 |
- mdat->mirtab[i].ignore = 0; |
|
152 |
- if (md) |
|
153 |
- *md = &mdat->mirtab[i]; |
|
154 |
- return 0; |
|
159 |
+ /* Long-Ignore timeout expired, |
|
160 |
+ * the mirror can be attempted again */ |
|
161 |
+ mdat->mirtab[i].ignore = IGNORE_NO; |
|
162 |
+ } |
|
163 |
+ else if ((mdat->mirtab[i].ignore == IGNORE_SHORTTERM) && |
|
164 |
+ (difftime(time(NULL), mdat->mirtab[i].atime) > IGNORE_SHORT)) |
|
165 |
+ { |
|
166 |
+ /* Mirror was only set to Short-Term ignore... |
|
167 |
+ * the Short-Ignore timeout expired, |
|
168 |
+ * the mirror can be attempted again */ |
|
169 |
+ mdat->mirtab[i].ignore = IGNORE_NO; |
|
155 | 170 |
} |
156 | 171 |
else |
157 | 172 |
{ |
158 |
- if (mdat->mirtab[i].ignore == 2 |
|
159 |
- && (time (NULL) - mdat->mirtab[i].atime > |
|
160 |
- IGNORE_SHORT)) |
|
161 |
- { |
|
162 |
- if (md) |
|
163 |
- *md = &mdat->mirtab[i]; |
|
164 |
- return 0; |
|
165 |
- } |
|
166 |
- return 1; |
|
173 |
+ *mirror_status = MIRROR_IGNORE__PREV_ERRS; |
|
174 |
+ goto done; |
|
167 | 175 |
} |
168 | 176 |
} |
169 | 177 |
|
170 |
- if (md) |
|
171 |
- *md = &mdat->mirtab[i]; |
|
172 |
- return 0; |
|
178 |
+ /* Mirror found, and is ok to try. */ |
|
179 |
+ *md = &mdat->mirtab[i]; |
|
180 |
+ *mirror_status = MIRROR_OK; |
|
181 |
+ goto done; |
|
173 | 182 |
} |
174 | 183 |
} |
175 | 184 |
|
176 |
- return 0; |
|
185 |
+ /* Mirror wasn't in mirror table. */ |
|
186 |
+ *mirror_status = MIRROR_OK; |
|
187 |
+ |
|
188 |
+done: |
|
189 |
+ |
|
190 |
+ return status; |
|
177 | 191 |
} |
178 | 192 |
|
179 |
-static int |
|
180 |
-mirman_update_int (uint32_t * ip, int af, struct mirdat *mdat, uint8_t broken, |
|
181 |
- int succ, int fail) |
|
193 |
+fc_error_t mirman_update(uint32_t * ip, int af, struct mirdat *mdat, fc_error_t error) |
|
182 | 194 |
{ |
183 |
- unsigned int i, found = 0; |
|
184 |
- |
|
195 |
+ fc_error_t status = FCE_ARG; |
|
196 |
+ unsigned int i = 0; |
|
197 |
+ struct mirdat_ip *mirror = NULL; |
|
185 | 198 |
|
186 |
- if (!mdat->active) |
|
187 |
- return 0; |
|
199 |
+ if (!mdat->active) { |
|
200 |
+ /* Disable mirrors.dat management when using a proxy. */ |
|
201 |
+ return FC_SUCCESS; |
|
202 |
+ } |
|
188 | 203 |
|
204 |
+ /* |
|
205 |
+ * Attempt to find the ip in the mirror table. |
|
206 |
+ */ |
|
189 | 207 |
for (i = 0; i < mdat->num; i++) |
190 | 208 |
{ |
191 |
- if ((af == AF_INET && mdat->mirtab[i].ip4 == *ip) |
|
192 |
- || (af == AF_INET6 |
|
193 |
- && !memcmp (mdat->mirtab[i].ip6, ip, 4 * sizeof (uint32_t)))) |
|
209 |
+ if (((af == AF_INET) && (mdat->mirtab[i].ip4 == *ip)) || |
|
210 |
+ ((af == AF_INET6) && (!memcmp(mdat->mirtab[i].ip6, ip, 4 * sizeof(uint32_t))))) |
|
194 | 211 |
{ |
195 |
- found = 1; |
|
212 |
+ mirror = &mdat->mirtab[i]; |
|
196 | 213 |
break; |
197 | 214 |
} |
198 | 215 |
} |
199 | 216 |
|
200 |
- if (found) |
|
201 |
- { |
|
202 |
- mdat->mirtab[i].atime = 0; /* will be updated in mirman_write() */ |
|
203 |
- if (succ || fail) |
|
204 |
- { |
|
205 |
- if ((int) mdat->mirtab[i].fail + fail < 0) |
|
206 |
- mdat->mirtab[i].fail = 0; |
|
207 |
- else |
|
208 |
- mdat->mirtab[i].fail += fail; |
|
209 |
- |
|
210 |
- if ((int) mdat->mirtab[i].succ + succ < 0) |
|
211 |
- mdat->mirtab[i].succ = 0; |
|
212 |
- else |
|
213 |
- mdat->mirtab[i].succ += succ; |
|
214 |
- } |
|
215 |
- else |
|
216 |
- { |
|
217 |
- if (broken) |
|
218 |
- mdat->mirtab[i].fail++; |
|
219 |
- else |
|
220 |
- mdat->mirtab[i].succ++; |
|
221 |
- |
|
222 |
- if (broken == 2) |
|
223 |
- { |
|
224 |
- mdat->mirtab[i].ignore = 2; |
|
225 |
- } |
|
226 |
- else |
|
227 |
- { |
|
228 |
- /* |
|
229 |
- * If the total number of failures is less than 3 then never |
|
230 |
- * mark a permanent failure, in other case use the real status. |
|
231 |
- */ |
|
232 |
- if (mdat->mirtab[i].fail < 3) |
|
233 |
- mdat->mirtab[i].ignore = 0; |
|
234 |
- else |
|
235 |
- mdat->mirtab[i].ignore = broken; |
|
236 |
- } |
|
237 |
- } |
|
238 |
- } |
|
239 |
- else |
|
217 |
+ if (NULL == mirror) |
|
240 | 218 |
{ |
219 |
+ /* |
|
220 |
+ * Allocate space in the mirror table for the new mirror IP |
|
221 |
+ */ |
|
241 | 222 |
mdat->mirtab = |
242 |
- (struct mirdat_ip *) realloc (mdat->mirtab, |
|
243 |
- (mdat->num + |
|
244 |
- 1) * sizeof (struct mirdat_ip)); |
|
223 |
+ (struct mirdat_ip *) realloc(mdat->mirtab, |
|
224 |
+ (mdat->num + 1) * sizeof(struct mirdat_ip)); |
|
245 | 225 |
if (!mdat->mirtab) |
246 | 226 |
{ |
247 |
- logg ("!Can't allocate memory for new element in mdat->mirtab\n"); |
|
248 |
- return -1; |
|
227 |
+ logg("!Can't allocate memory for new element in mdat->mirtab\n"); |
|
228 |
+ return FCE_MEM; |
|
249 | 229 |
} |
250 |
- memset (&mdat->mirtab[mdat->num], 0, sizeof (struct mirdat_ip)); |
|
230 |
+ memset (&mdat->mirtab[mdat->num], 0, sizeof(struct mirdat_ip)); |
|
251 | 231 |
if (af == AF_INET) |
252 | 232 |
{ |
253 | 233 |
mdat->mirtab[mdat->num].ip4 = *ip; |
... | ... |
@@ -255,116 +233,163 @@ mirman_update_int (uint32_t * ip, int af, struct mirdat *mdat, uint8_t broken, |
255 | 255 |
else |
256 | 256 |
{ |
257 | 257 |
mdat->mirtab[mdat->num].ip4 = 0; |
258 |
- memcpy (mdat->mirtab[mdat->num].ip6, ip, 4 * sizeof (uint32_t)); |
|
258 |
+ memcpy (mdat->mirtab[mdat->num].ip6, ip, 4 * sizeof(uint32_t)); |
|
259 | 259 |
} |
260 | 260 |
mdat->mirtab[mdat->num].atime = 0; |
261 |
- mdat->mirtab[mdat->num].succ = (succ > 0) ? succ : 0; |
|
262 |
- mdat->mirtab[mdat->num].fail = (fail > 0) ? fail : 0; |
|
263 |
- mdat->mirtab[mdat->num].ignore = (broken == 2) ? 2 : 0; |
|
264 |
- if (!succ && !fail) |
|
265 |
- { |
|
266 |
- if (broken) |
|
267 |
- mdat->mirtab[mdat->num].fail++; |
|
268 |
- else |
|
269 |
- mdat->mirtab[mdat->num].succ++; |
|
270 |
- } |
|
261 |
+ mdat->mirtab[mdat->num].succ = 0; |
|
262 |
+ mdat->mirtab[mdat->num].fail = 0; |
|
263 |
+ mdat->mirtab[mdat->num].ignore = 0; |
|
264 |
+ |
|
265 |
+ mirror = &mdat->mirtab[mdat->num]; |
|
271 | 266 |
mdat->num++; |
272 | 267 |
} |
273 | 268 |
|
274 |
- return 0; |
|
275 |
-} |
|
269 |
+ mirror->atime = 0; /* will be updated in mirman_write() */ |
|
276 | 270 |
|
277 |
-int |
|
278 |
-mirman_update (uint32_t * ip, int af, struct mirdat *mdat, uint8_t broken) |
|
279 |
-{ |
|
280 |
- return mirman_update_int (ip, af, mdat, broken, 0, 0); |
|
281 |
-} |
|
271 |
+ if (FC_SUCCESS == error) { |
|
272 |
+ mirror->succ++; |
|
273 |
+ mirror->fail = 0; |
|
274 |
+ } |
|
275 |
+ else |
|
276 |
+ { |
|
277 |
+ mirror->succ = 0; |
|
278 |
+ mirror->fail++; |
|
279 |
+ } |
|
282 | 280 |
|
283 |
-int |
|
284 |
-mirman_update_sf (uint32_t * ip, int af, struct mirdat *mdat, int succ, |
|
285 |
- int fail) |
|
286 |
-{ |
|
287 |
- return mirman_update_int (ip, af, mdat, 0, succ, fail); |
|
281 |
+ if (mirror->fail >= 6) |
|
282 |
+ { |
|
283 |
+ mirror->ignore = IGNORE_LONGTERM; |
|
284 |
+ } |
|
285 |
+ else if (mirror->fail >= 3) |
|
286 |
+ { |
|
287 |
+ mirror->ignore = IGNORE_SHORTTERM; |
|
288 |
+ } |
|
289 |
+ else |
|
290 |
+ { |
|
291 |
+ mirror->ignore = IGNORE_NO; |
|
292 |
+ } |
|
293 |
+ |
|
294 |
+ return FC_SUCCESS; |
|
288 | 295 |
} |
289 | 296 |
|
290 |
-void |
|
291 |
-mirman_list (const struct mirdat *mdat) |
|
297 |
+void mirman_list(const struct mirdat *mdat) |
|
292 | 298 |
{ |
293 | 299 |
unsigned int i; |
294 | 300 |
time_t tm; |
295 | 301 |
char ip[46]; |
296 | 302 |
|
297 |
- |
|
298 | 303 |
for (i = 0; i < mdat->num; i++) |
299 | 304 |
{ |
300 |
- printf ("Mirror #%u\n", i + 1); |
|
305 |
+ printf("Mirror #%u\n", i + 1); |
|
301 | 306 |
#ifdef HAVE_GETADDRINFO |
302 | 307 |
if (mdat->mirtab[i].ip4) |
303 |
- printf ("IP: %s\n", |
|
304 |
- inet_ntop (AF_INET, &mdat->mirtab[i].ip4, ip, |
|
305 |
- sizeof (ip))); |
|
308 |
+ printf("IP: %s\n", |
|
309 |
+ inet_ntop(AF_INET, &mdat->mirtab[i].ip4, ip, sizeof(ip))); |
|
306 | 310 |
else |
307 |
- printf ("IP: %s\n", |
|
308 |
- inet_ntop (AF_INET6, mdat->mirtab[i].ip6, ip, |
|
309 |
- sizeof (ip))); |
|
311 |
+ printf("IP: %s\n", |
|
312 |
+ inet_ntop(AF_INET6, mdat->mirtab[i].ip6, ip, sizeof(ip))); |
|
310 | 313 |
#else |
311 | 314 |
if (mdat->mirtab[i].ip4) |
312 |
- printf ("IP: %s\n", |
|
313 |
- inet_ntoa (*(struct in_addr *) &mdat->mirtab[i].ip4)); |
|
315 |
+ printf("IP: %s\n", |
|
316 |
+ inet_ntoa(*(struct in_addr *)&mdat->mirtab[i].ip4)); |
|
314 | 317 |
#endif |
315 |
- printf ("Successes: %u\n", mdat->mirtab[i].succ); |
|
316 |
- printf ("Failures: %u\n", mdat->mirtab[i].fail); |
|
318 |
+ printf("Successes: %u\n", mdat->mirtab[i].succ); |
|
319 |
+ printf("Failures: %u\n", mdat->mirtab[i].fail); |
|
317 | 320 |
tm = mdat->mirtab[i].atime; |
318 |
- printf ("Last access: %s", ctime ((const time_t *) &tm)); |
|
319 |
- printf ("Ignore: %s\n", mdat->mirtab[i].ignore ? "Yes" : "No"); |
|
321 |
+ printf("Last access: %s", ctime((const time_t *) &tm)); |
|
322 |
+ if (mdat->mirtab[i].ignore) { |
|
323 |
+ time_t ignore_expires = tm + ((mdat->mirtab[i].ignore == IGNORE_LONGTERM) ? IGNORE_LONG |
|
324 |
+ : IGNORE_SHORT); |
|
325 |
+ double difference = difftime(ignore_expires, time(NULL)); |
|
326 |
+ if (difference > 0) { |
|
327 |
+ uint32_t remaining = difference; |
|
328 |
+ uint32_t seconds, minutes, hours; |
|
329 |
+ seconds = remaining % 60; |
|
330 |
+ remaining = remaining / 60; |
|
331 |
+ minutes = remaining % 60; |
|
332 |
+ remaining = remaining / 60; |
|
333 |
+ hours = remaining % 60; |
|
334 |
+ |
|
335 |
+ printf("Ignore: Yes, %d hours %d minutes %d seconds remaining.\n", |
|
336 |
+ hours, minutes, seconds); |
|
337 |
+ } else { |
|
338 |
+ printf("Ignore: No\n"); |
|
339 |
+ } |
|
340 |
+ } else { |
|
341 |
+ printf("Ignore: No\n"); |
|
342 |
+ } |
|
320 | 343 |
if (i != mdat->num - 1) |
321 |
- printf ("-------------------------------------\n"); |
|
344 |
+ printf("-------------------------------------\n"); |
|
322 | 345 |
} |
323 | 346 |
} |
324 | 347 |
|
325 |
-void |
|
326 |
-mirman_whitelist (struct mirdat *mdat, unsigned int mode) |
|
348 |
+void mirman_whitelist(struct mirdat *mdat, unsigned int mode) |
|
327 | 349 |
{ |
328 | 350 |
unsigned int i; |
329 | 351 |
|
330 |
- logg ("*Whitelisting %s blacklisted mirrors\n", |
|
331 |
- mode == 1 ? "all" : "short-term"); |
|
352 |
+ if (NULL == mdat) { |
|
353 |
+ logg("!mirman_whitelist: Invalid arguments!\n"); |
|
354 |
+ return; |
|
355 |
+ } |
|
356 |
+ |
|
357 |
+ switch (mode) |
|
358 |
+ { |
|
359 |
+ case 1: |
|
360 |
+ logg("*Whitelisting all blacklisted mirrors\n"); |
|
361 |
+ break; |
|
362 |
+ case 2: |
|
363 |
+ logg("*Whitelisting short-term blacklisted mirrors\n"); |
|
364 |
+ break; |
|
365 |
+ default: |
|
366 |
+ logg("!mirman_whitelist: Unexpected mode argument: %u\n", mode); |
|
367 |
+ return; |
|
368 |
+ } |
|
369 |
+ |
|
332 | 370 |
for (i = 0; i < mdat->num; i++) |
333 |
- if (mode == 1 || (mode == 2 && mdat->mirtab[i].ignore == 2)) |
|
334 |
- mdat->mirtab[i].ignore = 0; |
|
371 |
+ { |
|
372 |
+ if (mode == 1) |
|
373 |
+ { |
|
374 |
+ mdat->mirtab[i].ignore = IGNORE_NO; |
|
375 |
+ } |
|
376 |
+ else if ((mode == 2) && (IGNORE_SHORTTERM == mdat->mirtab[i].ignore)) |
|
377 |
+ { |
|
378 |
+ mdat->mirtab[i].ignore = IGNORE_NO; |
|
379 |
+ } |
|
380 |
+ } |
|
381 |
+ |
|
382 |
+ return; |
|
335 | 383 |
} |
336 | 384 |
|
337 |
-int |
|
338 |
-mirman_write (const char *file, const char *dir, struct mirdat *mdat) |
|
385 |
+fc_error_t mirman_write(const char *file, const char *dir, struct mirdat *mdat) |
|
339 | 386 |
{ |
340 | 387 |
int fd; |
341 | 388 |
unsigned int i; |
342 | 389 |
char path[512]; |
343 | 390 |
|
344 |
- snprintf (path, sizeof (path), "%s/%s", dir, file); |
|
345 |
- path[sizeof (path) - 1] = 0; |
|
391 |
+ snprintf(path, sizeof(path), "%s/%s", dir, file); |
|
392 |
+ path[sizeof(path) - 1] = 0; |
|
346 | 393 |
|
347 | 394 |
if (!mdat->num) |
348 |
- return 0; |
|
395 |
+ return FC_SUCCESS; |
|
349 | 396 |
|
350 | 397 |
if ((fd = |
351 |
- open (path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0600)) == -1) |
|
398 |
+ open(path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0600)) == -1) |
|
352 | 399 |
{ |
353 |
- logg ("!Can't open %s for writing\n", path); |
|
354 |
- return -1; |
|
400 |
+ logg("!Can't open %s for writing\n", path); |
|
401 |
+ return FCE_OPEN; |
|
355 | 402 |
} |
356 | 403 |
|
357 | 404 |
for (i = 0; i < mdat->num; i++) |
358 | 405 |
if (!mdat->mirtab[i].atime) |
359 |
- mdat->mirtab[i].atime = (uint32_t) time (NULL); |
|
406 |
+ mdat->mirtab[i].atime = (uint32_t) time(NULL); |
|
360 | 407 |
|
361 |
- if (write (fd, mdat->mirtab, mdat->num * sizeof (struct mirdat_ip)) == -1) |
|
408 |
+ if (write(fd, mdat->mirtab, mdat->num * sizeof(struct mirdat_ip)) == -1) |
|
362 | 409 |
{ |
363 |
- logg ("!Can't write to %s\n", path); |
|
364 |
- close (fd); |
|
365 |
- return -1; |
|
410 |
+ logg("!Can't write to %s\n", path); |
|
411 |
+ close(fd); |
|
412 |
+ return FCE_FILE; |
|
366 | 413 |
} |
367 | 414 |
|
368 |
- close (fd); |
|
369 |
- return 0; |
|
415 |
+ close(fd); |
|
416 |
+ return FC_SUCCESS; |
|
370 | 417 |
} |
... | ... |
@@ -20,11 +20,25 @@ |
20 | 20 |
#define __MIRMAN_H |
21 | 21 |
|
22 | 22 |
#include "libclamav/cltypes.h" |
23 |
+#include "freshclamcodes.h" |
|
24 |
+ |
|
25 |
+typedef enum mir_status_tag { |
|
26 |
+ MIRROR_OK=0, |
|
27 |
+ MIRROR_FAILURE, |
|
28 |
+ MIRROR_IGNORE__PREV_ERRS, |
|
29 |
+ MIRROR_IGNORE__OUTDATED_VERSION |
|
30 |
+} mir_status_t; |
|
31 |
+ |
|
32 |
+typedef enum mir_ignore_tag { |
|
33 |
+ IGNORE_NO=0, |
|
34 |
+ IGNORE_LONGTERM, |
|
35 |
+ IGNORE_SHORTTERM |
|
36 |
+} mir_ignore_t; |
|
23 | 37 |
|
24 | 38 |
struct mirdat_ip |
25 | 39 |
{ |
26 | 40 |
uint32_t ip4; /* IPv4 address */ |
27 |
- uint32_t atime; /* last access time */ |
|
41 |
+ time_t atime; /* last access time */ |
|
28 | 42 |
uint32_t succ; /* number of successful downloads from this ip */ |
29 | 43 |
uint32_t fail; /* number of failures */ |
30 | 44 |
uint8_t ignore; /* ignore flag */ |
... | ... |
@@ -34,24 +48,85 @@ struct mirdat_ip |
34 | 34 |
|
35 | 35 |
struct mirdat |
36 | 36 |
{ |
37 |
- uint8_t active; |
|
38 |
- unsigned int num; |
|
39 |
- uint32_t currip[4]; |
|
40 |
- uint32_t af; |
|
41 |
- uint32_t dbflevel; |
|
42 |
- struct mirdat_ip *mirtab; |
|
37 |
+ uint8_t active; /* 1 if active, 2 if disabled */ |
|
38 |
+ unsigned int num; /* number of mirrors */ |
|
39 |
+ uint32_t currip[4]; /* IP currently attempting */ |
|
40 |
+ uint32_t af; /* AF_INET or AF_INET6 for current IP */ |
|
41 |
+ uint32_t dbflevel; /* functionality level of current database */ |
|
42 |
+ struct mirdat_ip *mirtab; /* mirror table of known mirror IP addresses */ |
|
43 | 43 |
}; |
44 | 44 |
|
45 |
-int mirman_read (const char *file, struct mirdat *mdat, uint8_t active); |
|
46 |
-int mirman_check (uint32_t * ip, int af, struct mirdat *mdat, |
|
47 |
- struct mirdat_ip **md); |
|
48 |
-int mirman_update (uint32_t * ip, int af, struct mirdat *mdat, |
|
49 |
- uint8_t broken); |
|
50 |
-int mirman_update_sf (uint32_t * ip, int af, struct mirdat *mdat, int succ, |
|
51 |
- int fail); |
|
52 |
-void mirman_list (const struct mirdat *mdat); |
|
53 |
-void mirman_whitelist (struct mirdat *mdat, unsigned int mode); |
|
54 |
-int mirman_write (const char *file, const char *dir, struct mirdat *mdat); |
|
55 |
-void mirman_free (struct mirdat *mdat); |
|
45 |
+/** |
|
46 |
+ * @brief Read mirrors.dat into an existing mirdat structur. |
|
47 |
+ * |
|
48 |
+ * @param file The filename (probably mirrors.dat). |
|
49 |
+ * @param mdat An existing mirdat structure. Must not be NULL. |
|
50 |
+ * @param active 1 - active, 0 - inactive (e.g. when using private mirrors or proxies). |
|
51 |
+ * @return fc_error_t FC_SUCCESS or an error code. |
|
52 |
+ */ |
|
53 |
+fc_error_t mirman_read(const char *file, struct mirdat *mdat, uint8_t active); |
|
54 |
+ |
|
55 |
+/** |
|
56 |
+ * @brief Check if a mirror is should be ignored, if it's in the mirror table. |
|
57 |
+ * |
|
58 |
+ * Will add the mirror to the table if it isn't in the table. |
|
59 |
+ * |
|
60 |
+ * @param ip The mirror in question. |
|
61 |
+ * @param af AF_INET or AF_INET6. |
|
62 |
+ * @param mdat The mirrors.dat structure. |
|
63 |
+ * @param[out] md A pointer to the mirror in mdat |
|
64 |
+ * @param[out] mirror_status MIRROR_OK or an ignore reason, such as: |
|
65 |
+ * MIRROR_IGNORE__PREV_ERRS or |
|
66 |
+ * MIRROR_IGNORE__OUTDATED_VERSION |
|
67 |
+ * @return fc_error_t FC_SUCCESS or an FCE error code. |
|
68 |
+ */ |
|
69 |
+fc_error_t mirman_check(uint32_t * ip, int af, struct mirdat *mdat, |
|
70 |
+ struct mirdat_ip **md, mir_status_t *mirror_status); |
|
71 |
+ |
|
72 |
+/** |
|
73 |
+ * @brief Update the mirdat structure with the current mirror status |
|
74 |
+ * |
|
75 |
+ * @param ip IP of current mirror. |
|
76 |
+ * @param af AF_INET or AF_INET6. |
|
77 |
+ * @param mdat The mirrors.dat structure. |
|
78 |
+ * @param error FC_SUCCESS or an FCE error code. |
|
79 |
+ * @return fc_error_t FC_SUCCESS or an FCE error code. |
|
80 |
+ */ |
|
81 |
+fc_error_t mirman_update(uint32_t * ip, int af, struct mirdat *mdat, fc_error_t mirror_status); |
|
82 |
+ |
|
83 |
+/** |
|
84 |
+ * @brief Print out the mirror info. |
|
85 |
+ * |
|
86 |
+ * @param mdat The mirdat struct. |
|
87 |
+ */ |
|
88 |
+void mirman_list(const struct mirdat *mdat); |
|
89 |
+ |
|
90 |
+/** |
|
91 |
+ * @brief Remove "ignore" flag on mirrors. |
|
92 |
+ * |
|
93 |
+ * @param mdat Structure |
|
94 |
+ * @param mode 1: Whitelist _all_ mirrors. |
|
95 |
+ * 2: Whitelist only mirrors that were in Short-Term ignore. |
|
96 |
+ */ |
|
97 |
+void mirman_whitelist(struct mirdat *mdat, unsigned int mode); |
|
98 |
+ |
|
99 |
+/** |
|
100 |
+ * @brief Update mirrors.dat with the current mirdat struct info. |
|
101 |
+ * |
|
102 |
+ * @param file The filename to write to (probably "mirrors.dat") |
|
103 |
+ * @param dir The database directory to store the file in. |
|
104 |
+ * @param mdat The mirdat struct to write to disk. |
|
105 |
+ * @return fc_error_t FC_SUCCESS or an error code. |
|
106 |
+ */ |
|
107 |
+fc_error_t mirman_write(const char *file, const char *dir, struct mirdat *mdat); |
|
108 |
+ |
|
109 |
+/** |
|
110 |
+ * @brief Free up the mirror table in the mirdat structure. |
|
111 |
+ * |
|
112 |
+ * Does not attempt to free mdat itself. |
|
113 |
+ * |
|
114 |
+ * @param mdat The mirdat structure. |
|
115 |
+ */ |
|
116 |
+void mirman_free(struct mirdat *mdat); |
|
56 | 117 |
|
57 | 118 |
#endif |