80
85
#define closesocket(s) close(s)
83
static int getclientsock(const char *localip)
88
#define CHDIR_ERR(x) \
90
logg("!Can't chdir to %s\n", x);
93
static const char *ghbn_err(int err) /* hstrerror() */
97
return "Host not found";
100
return "No IP address";
103
return "Unrecoverable DNS error";
106
return "Temporary DNS error";
109
return "Unknown error";
114
static int getclientsock(const char *localip, int prot)
85
116
int socketfd = -1;
120
socketfd = socket(PF_INET6, SOCK_STREAM, 0);
122
socketfd = socket(PF_INET, SOCK_STREAM, 0);
88
124
socketfd = socket(PF_INET, SOCK_STREAM, 0);
90
socketfd = socket(AF_INET, SOCK_STREAM, 0);
93
127
if(socketfd < 0) {
101
if((he = gethostbyname(localip)) == NULL) {
105
herr = "Host not found";
109
herr = "No IP address";
113
herr = "Unrecoverable DNS error";
117
herr = "Temporary DNS error";
121
herr = "Unknown error";
134
struct addrinfo *res;
137
ret = getaddrinfo(localip, NULL, NULL, &res);
139
logg("!Could not resolve local ip address '%s': %s\n", localip, gai_strerror(ret));
140
logg("^Using standard local ip address and port for fetching.\n");
144
if(bind(socketfd, res->ai_addr, res->ai_addrlen) != 0) {
145
logg("!Could not bind to local ip address '%s': %s\n", localip, strerror(errno));
146
logg("^Using default client ip.\n");
150
if(res->ai_family == AF_INET6)
151
addr = &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr;
153
addr = &((struct sockaddr_in *) res->ai_addr)->sin_addr;
155
if(inet_ntop(res->ai_family, addr, ipaddr, sizeof(ipaddr)))
156
logg("*Using ip '%s' for fetching.\n", ipaddr);
124
logg("!Could not resolve local ip address '%s': %s\n", localip, herr);
164
if(!(he = gethostbyname(localip))) {
165
logg("!Could not resolve local ip address '%s': %s\n", localip, ghbn_err(h_errno));
125
166
logg("^Using standard local ip address and port for fetching.\n");
127
struct sockaddr_in client;
168
struct sockaddr_in client;
131
memset ((char *) &client, 0, sizeof(struct sockaddr_in));
172
memset((char *) &client, 0, sizeof(client));
132
173
client.sin_family = AF_INET;
133
174
client.sin_addr = *(struct in_addr *) he->h_addr_list[0];
134
if (bind(socketfd, (struct sockaddr *) &client, sizeof(struct sockaddr_in)) != 0) {
175
if(bind(socketfd, (struct sockaddr *) &client, sizeof(struct sockaddr_in)) != 0) {
135
176
logg("!Could not bind to local ip address '%s': %s\n", localip, strerror(errno));
136
177
logg("^Using default client ip.\n");
140
181
logg("*Using ip '%s' for fetching.\n", ipaddr);
148
static int wwwconnect(const char *server, const char *proxy, int pport, char *ip, const char *localip, int ctimeout, struct mirdat *mdat, int logerr)
190
static int wwwconnect(const char *server, const char *proxy, int pport, char *ip, const char *localip, int ctimeout, struct mirdat *mdat, int logerr, unsigned int can_whitelist)
150
int socketfd = -1, port, i, ret;
192
int socketfd, port, ret;
193
unsigned int ips = 0, ignored = 0;
195
struct addrinfo hints, *res = NULL, *rp, *loadbal_rp = NULL;
196
char port_s[6], loadbal_ipaddr[46];
197
uint32_t loadbal = 1, minsucc = 0xffffffff, minfail = 0xffffffff;
198
struct mirdat_ip *md;
151
200
struct sockaddr_in name;
152
201
struct hostent *host;
154
202
unsigned char *ia;
155
206
const char *hostpt;
158
209
strcpy(ip, "???");
160
socketfd = getclientsock(localip);
164
name.sin_family = AF_INET;
169
214
if(!(port = pport)) {
171
215
const struct servent *webcache = getservbyname("webcache", "TCP");
233
memset(&hints, 0, sizeof(hints));
234
hints.ai_family = AF_UNSPEC;
235
hints.ai_socktype = SOCK_STREAM;
236
snprintf(port_s, sizeof(port_s), "%d", port);
237
port_s[sizeof(port_s) - 1] = 0;
238
ret = getaddrinfo(hostpt, port_s, &hints, &res);
240
logg("%cCan't get information about %s: %s\n", logerr ? '!' : '^', hostpt, gai_strerror(ret));
244
for(rp = res; rp; rp = rp->ai_next) {
248
if(rp->ai_family == AF_INET6)
249
addr = &((struct sockaddr_in6 *) rp->ai_addr)->sin6_addr;
251
addr = &((struct sockaddr_in *) rp->ai_addr)->sin_addr;
253
if(!inet_ntop(rp->ai_family, addr, ipaddr, sizeof(ipaddr))) {
254
logg("%cinet_ntop() failed\n", logerr ? '!' : '^');
259
if((ret = mirman_check(addr, rp->ai_family, mdat, &md))) {
261
logg("Ignoring mirror %s (due to previous errors)\n", ipaddr);
263
logg("Ignoring mirror %s (has connected too many times with an outdated version)\n", ipaddr);
266
if(!loadbal || rp->ai_next)
274
strncpy(loadbal_ipaddr, ipaddr, sizeof(loadbal_ipaddr));
276
if(md->succ < minsucc && md->fail <= minfail) {
280
strncpy(loadbal_ipaddr, ipaddr, sizeof(loadbal_ipaddr));
295
strncpy(ipaddr, loadbal_ipaddr, sizeof(ipaddr));
297
} else if(loadbal_rp == rp) {
305
logg("Trying host %s (%s)...\n", hostpt, ipaddr);
307
socketfd = getclientsock(localip, rp->ai_family);
314
if(wait_connect(socketfd, rp->ai_addr, rp->ai_addrlen, ctimeout) == -1) {
316
if(connect(socketfd, rp->ai_addr, rp->ai_addrlen) == -1) {
318
logg("Can't connect to port %d of host %s (IP: %s)\n", port, hostpt, ipaddr);
319
closesocket(socketfd);
326
if(rp->ai_family == AF_INET)
327
mdat->currip[0] = *((uint32_t *) addr);
329
memcpy(mdat->currip, addr, 4 * sizeof(uint32_t));
330
mdat->af = rp->ai_family;
191
339
if((host = gethostbyname(hostpt)) == NULL) {
195
herr = "Host not found";
199
herr = "No IP address";
203
herr = "Unrecoverable DNS error";
207
herr = "Temporary DNS error";
211
herr = "Unknown error";
214
logg("%cCan't get information about %s: %s\n", logerr ? '!' : '^', hostpt, herr);
340
logg("%cCan't get information about %s: %s\n", logerr ? '!' : '^', hostpt, ghbn_err(h_errno));
221
346
ia = (unsigned char *) host->h_addr_list[i];
222
347
sprintf(ipaddr, "%u.%u.%u.%u", ia[0], ia[1], ia[2], ia[3]);
224
if((ret = mirman_check(((struct in_addr *) ia)->s_addr, mdat))) {
350
if((ret = mirman_check(&((struct in_addr *) ia)->s_addr, AF_INET, mdat, NULL))) {
226
352
logg("Ignoring mirror %s (due to previous errors)\n", ipaddr);
228
354
logg("Ignoring mirror %s (has connected too many times with an outdated version)\n", ipaddr);
236
363
logg("Trying host %s (%s)...\n", hostpt, ipaddr);
365
memset ((char *) &name, 0, sizeof(name));
366
name.sin_family = AF_INET;
238
367
name.sin_addr = *((struct in_addr *) host->h_addr_list[i]);
239
368
name.sin_port = htons(port);
370
socketfd = getclientsock(localip, AF_INET);
242
375
if(wait_connect(socketfd, (struct sockaddr *) &name, sizeof(struct sockaddr_in), ctimeout) == -1) {
244
377
if(connect(socketfd, (struct sockaddr *) &name, sizeof(struct sockaddr_in)) == -1) {
246
379
logg("Can't connect to port %d of host %s (IP: %s)\n", port, hostpt, ipaddr);
248
if((socketfd = getclientsock(localip)) == -1)
380
closesocket(socketfd);
253
mdat->currip = ((struct in_addr *) ia)->s_addr;
383
mdat->currip[0] = ((struct in_addr *) ia)->s_addr;
390
if(can_whitelist && ips && (ips == ignored))
391
mirman_whitelist(mdat);
338
static struct cl_cvd *remote_cvdhead(const char *file, const char *hostname, char *ip, const char *localip, const char *proxy, int port, const char *user, const char *pass, const char *uas, int *ims, int ctimeout, int rtimeout, struct mirdat *mdat, int logerr)
473
static struct cl_cvd *remote_cvdhead(const char *file, const char *hostname, char *ip, const char *localip, const char *proxy, int port, const char *user, const char *pass, const char *uas, int *ims, int ctimeout, int rtimeout, struct mirdat *mdat, int logerr, unsigned int can_whitelist)
340
char cmd[512], head[513], buffer[FILEBUFF], ipaddr[16], *ch, *tmp;
475
char cmd[512], head[513], buffer[FILEBUFF], ipaddr[46], *ch, *tmp;
341
476
int bread, cnt, sd;
342
477
unsigned int i, j;
343
478
char *remotename = NULL, *authorization = NULL;
345
479
struct cl_cvd *cvd;
346
char last_modified[36];
480
char last_modified[36], uastr[128];
376
512
logg("Reading CVD header (%s): ", file);
515
strncpy(uastr, uas, sizeof(uastr));
381
#ifdef CL_EXPERIMENTAL
382
agent = PACKAGE"/"VERSION"-exp";
384
agent = PACKAGE"/"VERSION;
517
snprintf(uastr, sizeof(uastr), PACKAGE"/%s (OS: "TARGET_OS_TYPE", ARCH: "TARGET_ARCH_TYPE", CPU: "TARGET_CPU_TYPE")", get_version());
518
uastr[sizeof(uastr) - 1] = 0;
387
520
snprintf(cmd, sizeof(cmd),
388
521
"GET %s/%s HTTP/1.0\r\n"
391
524
"Connection: close\r\n"
392
525
"Range: bytes=0-511\r\n"
393
526
"If-Modified-Since: %s\r\n"
394
"\r\n", (remotename != NULL) ? remotename : "", file, hostname, (authorization != NULL) ? authorization : "", agent, last_modified);
527
"\r\n", (remotename != NULL) ? remotename : "", file, hostname, (authorization != NULL) ? authorization : "", uastr, last_modified);
396
529
free(remotename);
397
530
free(authorization);
399
532
memset(ipaddr, 0, sizeof(ipaddr));
401
534
if(ip[0]) /* use ip to connect */
402
sd = wwwconnect(ip, proxy, port, ipaddr, localip, ctimeout, mdat, logerr);
535
sd = wwwconnect(ip, proxy, port, ipaddr, localip, ctimeout, mdat, logerr, can_whitelist);
404
sd = wwwconnect(hostname, proxy, port, ipaddr, localip, ctimeout, mdat, logerr);
537
sd = wwwconnect(hostname, proxy, port, ipaddr, localip, ctimeout, mdat, logerr, can_whitelist);
458
591
if(!strstr(buffer, "HTTP/1.1 200") && !strstr(buffer, "HTTP/1.0 200") &&
459
592
!strstr(buffer, "HTTP/1.1 206") && !strstr(buffer, "HTTP/1.0 206")) {
460
593
logg("%cUnknown response from remote server\n", logerr ? '!' : '^');
461
mirman_update(mdat->currip, mdat, 1);
594
mirman_update(mdat->currip, mdat->af, mdat, 1);
494
627
if(!(cvd = cl_cvdparse(head))) {
495
628
logg("%cremote_cvdhead: Malformed CVD header (can't parse)\n", logerr ? '!' : '^');
496
mirman_update(mdat->currip, mdat, 1);
629
mirman_update(mdat->currip, mdat->af, mdat, 1);
499
mirman_update(mdat->currip, mdat, 0);
632
mirman_update(mdat->currip, mdat->af, mdat, 0);
505
static int getfile(const char *srcfile, const char *destfile, const char *hostname, char *ip, const char *localip, const char *proxy, int port, const char *user, const char *pass, const char *uas, int ctimeout, int rtimeout, struct mirdat *mdat, int logerr)
638
static int getfile(const char *srcfile, const char *destfile, const char *hostname, char *ip, const char *localip, const char *proxy, int port, const char *user, const char *pass, const char *uas, int ctimeout, int rtimeout, struct mirdat *mdat, int logerr, unsigned int can_whitelist)
507
char cmd[512], buffer[FILEBUFF], *ch;
640
char cmd[512], uastr[128], buffer[FILEBUFF], *ch;
508
641
int bread, fd, totalsize = 0, rot = 0, totaldownloaded = 0,
509
642
percentage = 0, sd;
511
char *remotename = NULL, *authorization = NULL, *headerline, ipaddr[16];
512
const char *rotation = "|/-\\", *agent;
644
char *remotename = NULL, *authorization = NULL, *headerline, ipaddr[46];
645
const char *rotation = "|/-\\";
524
657
authorization = proxyauth(user, pass);
526
660
return 75; /* FIXME */
666
strncpy(uastr, uas, sizeof(uastr));
533
#ifdef CL_EXPERIMENTAL
534
agent = PACKAGE"/"VERSION"-exp";
536
agent = PACKAGE"/"VERSION;
668
snprintf(uastr, sizeof(uastr), PACKAGE"/%s (OS: "TARGET_OS_TYPE", ARCH: "TARGET_ARCH_TYPE", CPU: "TARGET_CPU_TYPE")", get_version());
669
uastr[sizeof(uastr) - 1] = 0;
539
671
snprintf(cmd, sizeof(cmd),
540
672
"GET %s/%s HTTP/1.0\r\n"
544
676
"Cache-Control: no-cache\r\n"
546
678
"Connection: close\r\n"
547
"\r\n", (remotename != NULL) ? remotename : "", srcfile, hostname, (authorization != NULL) ? authorization : "", agent);
549
memset(ipaddr, 0, sizeof(ipaddr));
551
if(ip[0]) /* use ip to connect */
552
sd = wwwconnect(ip, proxy, port, ipaddr, localip, ctimeout, mdat, logerr);
554
sd = wwwconnect(hostname, proxy, port, ipaddr, localip, ctimeout, mdat, logerr);
559
logg("*Trying to download http://%s/%s (IP: %s)\n", hostname, srcfile, ipaddr);
565
if(send(sd, cmd, strlen(cmd), 0) < 0) {
566
logg("%cgetfile: Can't write to socket\n", logerr ? '!' : '^');
679
"\r\n", (remotename != NULL) ? remotename : "", srcfile, hostname, (authorization != NULL) ? authorization : "", uastr);
572
682
free(remotename);
574
684
if(authorization)
575
685
free(authorization);
687
memset(ipaddr, 0, sizeof(ipaddr));
688
if(ip[0]) /* use ip to connect */
689
sd = wwwconnect(ip, proxy, port, ipaddr, localip, ctimeout, mdat, logerr, can_whitelist);
691
sd = wwwconnect(hostname, proxy, port, ipaddr, localip, ctimeout, mdat, logerr, can_whitelist);
696
logg("*Trying to download http://%s/%s (IP: %s)\n", hostname, srcfile, ipaddr);
702
if(send(sd, cmd, strlen(cmd), 0) < 0) {
703
logg("%cgetfile: Can't write to socket\n", logerr ? '!' : '^');
577
708
/* read http headers */
585
716
if((i >= sizeof(buffer) - 1) || recv(sd, buffer + i, 1, 0) == -1) {
587
718
logg("%cgetfile: Error while reading database from %s (IP: %s)\n", logerr ? '!' : '^', hostname, ipaddr);
588
mirman_update(mdat->currip, mdat, 1);
719
mirman_update(mdat->currip, mdat->af, mdat, 1);
611
742
if(!strstr(buffer, "HTTP/1.1 200") && !strstr(buffer, "HTTP/1.0 200") &&
612
743
!strstr(buffer, "HTTP/1.1 206") && !strstr(buffer, "HTTP/1.0 206")) {
613
744
logg("%cgetfile: Unknown response from remote server (IP: %s)\n", logerr ? '!' : '^', ipaddr);
614
mirman_update(mdat->currip, mdat, 1);
745
mirman_update(mdat->currip, mdat->af, mdat, 1);
632
763
if((fd = open(destfile, O_WRONLY|O_CREAT|O_EXCL|O_BINARY, 0644)) == -1) {
633
764
char currdir[512];
635
getcwd(currdir, sizeof(currdir));
636
logg("!getfile: Can't create new file %s in %s\n", destfile, currdir);
766
if(getcwd(currdir, sizeof(currdir)))
767
logg("!getfile: Can't create new file %s in %s\n", destfile, currdir);
769
logg("!getfile: Can't create new file %s in the current directory\n", destfile);
637
771
logg("Hint: The database directory must be writable for UID %d or GID %d\n", getuid(), getgid());
677
811
logg("Downloading %s [*]\n", srcfile);
679
mirman_update(mdat->currip, mdat, 0);
813
mirman_update(mdat->currip, mdat->af, mdat, 0);
683
static int getcvd(const char *cvdfile, const char *newfile, const char *hostname, char *ip, const char *localip, const char *proxy, int port, const char *user, const char *pass, const char *uas, int nodb, unsigned int newver, int ctimeout, int rtimeout, struct mirdat *mdat, int logerr)
817
static int getcvd(const char *cvdfile, const char *newfile, const char *hostname, char *ip, const char *localip, const char *proxy, int port, const char *user, const char *pass, const char *uas, int nodb, unsigned int newver, int ctimeout, int rtimeout, struct mirdat *mdat, int logerr, unsigned int can_whitelist)
685
819
struct cl_cvd *cvd;
689
823
logg("*Retrieving http://%s/%s\n", hostname, cvdfile);
690
if((ret = getfile(cvdfile, newfile, hostname, ip, localip, proxy, port, user, pass, uas, ctimeout, rtimeout, mdat, logerr))) {
824
if((ret = getfile(cvdfile, newfile, hostname, ip, localip, proxy, port, user, pass, uas, ctimeout, rtimeout, mdat, logerr, can_whitelist))) {
691
825
logg("%cCan't download %s from %s\n", logerr ? '!' : '^', cvdfile, hostname);
754
static int getpatch(const char *dbname, const char *tmpdir, int version, const char *hostname, char *ip, const char *localip, const char *proxy, int port, const char *user, const char *pass, const char *uas, int ctimeout, int rtimeout, struct mirdat *mdat, int logerr)
888
static int getpatch(const char *dbname, const char *tmpdir, int version, const char *hostname, char *ip, const char *localip, const char *proxy, int port, const char *user, const char *pass, const char *uas, int ctimeout, int rtimeout, struct mirdat *mdat, int logerr, unsigned int can_whitelist)
756
890
char *tempname, patch[32], olddir[512];
769
903
snprintf(patch, sizeof(patch), "%s-%d.cdiff", dbname, version);
771
905
logg("*Retrieving http://%s/%s\n", hostname, patch);
772
if((ret = getfile(patch, tempname, hostname, ip, localip, proxy, port, user, pass, uas, ctimeout, rtimeout, mdat, logerr))) {
906
if((ret = getfile(patch, tempname, hostname, ip, localip, proxy, port, user, pass, uas, ctimeout, rtimeout, mdat, logerr, can_whitelist))) {
773
907
logg("%cgetpatch: Can't download %s from %s\n", logerr ? '!' : '^', patch, hostname);
774
908
unlink(tempname);
826
963
static int buildcld(const char *tmpdir, const char *dbname, const char *newfile, unsigned int compr)
829
char cwd[512], info[32], buff[512], *pt;
966
char cwd[512], info[32], buff[513], *pt;
830
967
struct dirent *dent;
832
969
gzFile *gzs = NULL;
971
if(!getcwd(cwd, sizeof(cwd))) {
972
logg("!buildcld: Can't get path of current working directory\n");
835
getcwd(cwd, sizeof(cwd));
836
976
if(chdir(tmpdir) == -1) {
837
977
logg("!buildcld: Can't access directory %s\n", tmpdir);
841
981
snprintf(info, sizeof(info), "%s.info", dbname);
842
982
if((fd = open(info, O_RDONLY|O_BINARY)) == -1) {
843
983
logg("!buildcld: Can't open %s\n", info);
848
988
if(read(fd, buff, 512) == -1) {
849
989
logg("!buildcld: Can't read %s\n", info);
856
997
if(!(pt = strchr(buff, '\n'))) {
857
998
logg("!buildcld: Bad format of %s\n", info);
861
1002
memset(pt, ' ', 512 + buff - pt);
863
1004
if((fd = open(newfile, O_WRONLY|O_CREAT|O_EXCL|O_BINARY, 0644)) == -1) {
864
1005
logg("!buildcld: Can't open %s for writing\n", newfile);
868
1009
if(write(fd, buff, 512) != 512) {
869
1010
logg("!buildcld: Can't write to %s\n", newfile);
871
1012
unlink(newfile);
972
1113
int ret, ims = -1;
973
1114
char *pt, cvdfile[32], localname[32], *tmpdir = NULL, *newfile, newdb[32], cwd[512];
974
1115
const char *proxy = NULL, *user = NULL, *pass = NULL, *uas = NULL;
975
unsigned int flevel = cl_retflevel(), maxattempts;
1116
unsigned int flevel = cl_retflevel(), remote_flevel = 0, maxattempts;
1117
unsigned int can_whitelist = 0;
976
1118
int ctimeout, rtimeout;
1043
1194
if(!nodb && !newver) {
1045
remote = remote_cvdhead(cvdfile, hostname, ip, localip, proxy, port, user, pass, uas, &ims, ctimeout, rtimeout, mdat, logerr);
1196
remote = remote_cvdhead(cvdfile, hostname, ip, localip, proxy, port, user, pass, uas, &ims, ctimeout, rtimeout, mdat, logerr, can_whitelist);
1047
1198
if(!nodb && !ims) {
1048
1199
logg("%s is up to date (version: %d, sigs: %d, f-level: %d, builder: %s)\n", localname, current->version, current->sigs, current->fl, current->builder);
1103
1254
if(!cfgopt(copt, "ScriptedUpdates")->enabled)
1106
getcwd(cwd, sizeof(cwd));
1257
if(!getcwd(cwd, sizeof(cwd))) {
1258
logg("!updatedb: Can't get path of current working directory\n");
1259
return 50; /* FIXME */
1107
1261
newfile = cli_gentemp(cwd);
1110
ret = getcvd(cvdfile, newfile, hostname, ip, localip, proxy, port, user, pass, uas, nodb, newver, ctimeout, rtimeout, mdat, logerr);
1264
ret = getcvd(cvdfile, newfile, hostname, ip, localip, proxy, port, user, pass, uas, nodb, newver, ctimeout, rtimeout, mdat, logerr, can_whitelist);
1112
1266
memset(ip, 0, 16);
1125
1279
int llogerr = logerr;
1127
1281
llogerr = (j == maxattempts - 1);
1128
ret = getpatch(dbname, tmpdir, i, hostname, ip, localip, proxy, port, user, pass, uas, ctimeout, rtimeout, mdat, llogerr);
1282
ret = getpatch(dbname, tmpdir, i, hostname, ip, localip, proxy, port, user, pass, uas, ctimeout, rtimeout, mdat, llogerr, can_whitelist);
1129
1283
if(ret == 52 || ret == 58) {
1130
1284
memset(ip, 0, 16);
1141
1295
cli_rmdirs(tmpdir);
1143
1297
logg("^Incremental update failed, trying to download %s\n", cvdfile);
1144
ret = getcvd(cvdfile, newfile, hostname, ip, localip, proxy, port, user, pass, uas, 1, newver, ctimeout, rtimeout, mdat, logerr);
1298
ret = getcvd(cvdfile, newfile, hostname, ip, localip, proxy, port, user, pass, uas, 1, newver, ctimeout, rtimeout, mdat, logerr, can_whitelist);
1201
1364
time_t currtime;
1202
1365
int ret, updated = 0, outdated = 0, signo = 0;
1203
1366
unsigned int ttl;
1204
char ipaddr[16], *dnsreply = NULL, *pt, *localip = NULL, *newver = NULL;
1367
char ipaddr[46], *dnsreply = NULL, *pt, *localip = NULL, *newver = NULL;
1205
1368
const char *arg = NULL;
1206
1369
const struct cfgstruct *cpt;
1207
1370
struct mirdat mdat;
1259
1425
logg("*Software version from DNS: %s\n", newver);
1261
if(vwarning && !strstr(cl_retver(), "devel") && !strstr(cl_retver(), "rc")) {
1262
if(strcmp(cl_retver(), newver)) {
1427
if(vwarning && !strstr(get_version(), "devel") && !strstr(get_version(), "rc")) {
1428
if(strcmp(get_version(), newver)) {
1263
1429
logg("^Your ClamAV installation is OUTDATED!\n");
1264
logg("^Local version: %s Recommended version: %s\n", cl_retver(), newver);
1430
logg("^Local version: %s Recommended version: %s\n", get_version(), newver);
1265
1431
logg("DON'T PANIC! Read http://www.clamav.net/support/faq\n");
1351
1512
else if((cpt = cfgopt(copt, "OnUpdateExecute"))->enabled)
1352
1513
arg = cpt->strarg;
1355
if(opt_check(opt, "daemon"))
1356
execute("OnUpdateExecute", arg);
1357
else if(system(arg) == -1)
1358
logg("!system(%s) failed\n", arg);
1516
execute("OnUpdateExecute", arg, opt);