Browse code

clamdscan: fix error logic once again

Tomasz Kojm authored on 2010/02/04 02:23:30
Showing 6 changed files
... ...
@@ -1,3 +1,7 @@
1
+Wed Feb  3 18:23:08 CET 2010 (tk)
2
+---------------------------------
3
+ * clamdscan: fix error logic once again
4
+
1 5
 Wed Feb  3 01:38:50 CET 2010 (acab)
2 6
 -----------------------------------
3 7
  * win32: workaround HUP reset in poll, set stdin to binary mode
... ...
@@ -55,7 +55,7 @@ static void print_server_version(const struct optstruct *opt)
55 55
 
56 56
 int main(int argc, char **argv)
57 57
 {
58
-	int ds, dms, ret, infected = 0;
58
+	int ds, dms, ret, infected = 0, err = 0;
59 59
 	struct timeval t1, t2;
60 60
 	time_t starttime;
61 61
         struct optstruct *opts;
... ...
@@ -133,10 +133,10 @@ int main(int argc, char **argv)
133 133
 
134 134
     gettimeofday(&t1, NULL);
135 135
 
136
-    ret = client(opts, &infected);
136
+    ret = client(opts, &infected, &err);
137 137
 
138 138
     /* TODO: Implement STATUS in clamd */
139
-    if((infected || ret != 2) && !optget(opts, "no-summary")->enabled) {
139
+    if(!optget(opts, "no-summary")->enabled) {
140 140
 	gettimeofday(&t2, NULL);
141 141
 	ds = t2.tv_sec - t1.tv_sec;
142 142
 	dms = t2.tv_usec - t1.tv_usec;
... ...
@@ -144,6 +144,8 @@ int main(int argc, char **argv)
144 144
 	dms += (dms < 0) ? (1000000):(0);
145 145
 	logg("\n----------- SCAN SUMMARY -----------\n");
146 146
 	logg("Infected files: %d\n", infected);
147
+	if(err)
148
+	    logg("Errors: %d\n", err);
147 149
 	if(notremoved) {
148 150
 	    logg("Not removed: %d\n", notremoved);
149 151
 	}
... ...
@@ -151,16 +151,16 @@ static char *makeabs(const char *basepath) {
151 151
 
152 152
 /* Recursively scans a path with the given scantype
153 153
  * Returns non zero for serious errors, zero otherwise */
154
-static int client_scan(const char *file, int scantype, int *infected, int maxlevel, int session, int flags) {
154
+static int client_scan(const char *file, int scantype, int *infected, int *err, int maxlevel, int session, int flags) {
155 155
     int ret;
156 156
     char *fullpath = makeabs(file);
157 157
 
158 158
     if(!fullpath)
159 159
 	return 0;
160 160
     if (!session)
161
-	ret = serial_client_scan(fullpath, scantype, infected, maxlevel, flags);
161
+	ret = serial_client_scan(fullpath, scantype, infected, err, maxlevel, flags);
162 162
     else
163
-	ret = parallel_client_scan(fullpath, scantype, infected, maxlevel, flags);
163
+	ret = parallel_client_scan(fullpath, scantype, infected, err, maxlevel, flags);
164 164
     free(fullpath);
165 165
     return ret;
166 166
 }
... ...
@@ -218,7 +218,7 @@ int reload_clamd_database(const struct optstruct *opts)
218 218
     return 0;
219 219
 }
220 220
 
221
-int client(const struct optstruct *opts, int *infected)
221
+int client(const struct optstruct *opts, int *infected, int *err)
222 222
 {
223 223
 	const char *clamd_conf = optget(opts, "config-file")->strarg;
224 224
 	struct optstruct *clamdopts;
... ...
@@ -265,7 +265,7 @@ int client(const struct optstruct *opts, int *infected)
265 265
 	struct stat sb;
266 266
 	fstat(0, &sb);
267 267
 	if((sb.st_mode & S_IFMT) != S_IFREG) scantype = STREAM;
268
-	if((sockd = dconnect()) >= 0 && (ret = dsresult(sockd, scantype, NULL, &ret, NULL, NULL)) >= 0)
268
+	if((sockd = dconnect()) >= 0 && (ret = dsresult(sockd, scantype, NULL, &ret, NULL)) >= 0)
269 269
 	    *infected = ret;
270 270
 	else
271 271
 	    errors = 1;
... ...
@@ -274,15 +274,21 @@ int client(const struct optstruct *opts, int *infected)
274 274
 	if(opts->filename && optget(opts, "file-list")->enabled)
275 275
 	    logg("^Only scanning files from --file-list (files passed at cmdline are ignored)\n");
276 276
 
277
-	while(!errors && (fname = filelist(opts, NULL))) {
277
+	while((fname = filelist(opts, NULL))) {
278 278
 	    if(!strcmp(fname, "-")) {
279 279
 		logg("!Scanning from standard input requires \"-\" to be the only file argument\n");
280 280
 		continue;
281 281
 	    }
282
-	    errors = client_scan(fname, scantype, infected, maxrec, session, flags);
282
+	    errors += client_scan(fname, scantype, infected, err, maxrec, session, flags);
283
+	    /* this may be too strict
284
+	    if(errors >= 10) {
285
+		logg("!Too many errors\n");
286
+		break;
287
+	    }
288
+	    */
283 289
 	}
284 290
     } else {
285
-	errors = client_scan("", scantype, infected, maxrec, session, flags);
291
+	errors = client_scan("", scantype, infected, err, maxrec, session, flags);
286 292
     }
287 293
     return *infected ? 1 : (errors ? 2 : 0);
288 294
 }
... ...
@@ -30,7 +30,7 @@ enum {
30 30
     FILDES
31 31
 };
32 32
 
33
-int client(const struct optstruct *opts, int *infected);
33
+int client(const struct optstruct *opts, int *infected, int *err);
34 34
 int get_clamd_version(const struct optstruct *opts);
35 35
 int reload_clamd_database(const struct optstruct *opts);
36 36
 
... ...
@@ -247,7 +247,7 @@ static int send_fdpass(int sockd, const char *filename) {
247 247
 /* Sends a proper scan request to clamd and parses its replies
248 248
  * This is used only in non IDSESSION mode
249 249
  * Returns the number of infected files or -1 on error */
250
-int dsresult(int sockd, int scantype, const char *filename, int *printok, int *files, int *errors) {
250
+int dsresult(int sockd, int scantype, const char *filename, int *printok, int *errors) {
251 251
     int infected = 0, len, beenthere = 0;
252 252
     char *bol, *eol;
253 253
     struct RCVLN rcv;
... ...
@@ -288,8 +288,6 @@ int dsresult(int sockd, int scantype, const char *filename, int *printok, int *f
288 288
     while((len = recvln(&rcv, &bol, &eol))) {
289 289
 	if(len == -1) return -1;
290 290
 	beenthere = 1;
291
-	if(files)
292
-	    (*files)++;
293 291
 	if(!filename) logg("~%s\n", bol);
294 292
 	if(len > 7) {
295 293
 	    char *colon = strrchr(bol, ':');
... ...
@@ -351,9 +349,11 @@ static int serial_callback(struct stat *sb, char *filename, const char *path, en
351 351
     int sockd, ret;
352 352
     const char *f = filename;
353 353
 
354
+    c->files++;
354 355
     switch(reason) {
355 356
     case error_stat:
356 357
 	logg("!Can't access file %s\n", path);
358
+	c->errors++;
357 359
 	return CL_SUCCESS;
358 360
     case error_mem:
359 361
 	logg("!Memory allocation failed in ftw\n");
... ...
@@ -378,12 +378,16 @@ static int serial_callback(struct stat *sb, char *filename, const char *path, en
378 378
 
379 379
     if((sockd = dconnect()) < 0) {
380 380
 	if(filename) free(filename);
381
+	c->errors++;
381 382
 	return CL_EOPEN;
382 383
     }
383
-    ret = dsresult(sockd, c->scantype, f, &c->printok, &c->files, &c->errors);
384
+    ret = dsresult(sockd, c->scantype, f, &c->printok, &c->errors);
384 385
     if(filename) free(filename);
385 386
     closesocket(sockd);
386
-    if(ret < 0) return CL_EOPEN;
387
+    if(ret < 0) {
388
+	c->errors++;
389
+	return CL_EOPEN;
390
+    }
387 391
     c->infected += ret;
388 392
     if(reason == visit_directory_toplev)
389 393
 	return CL_BREAK;
... ...
@@ -392,7 +396,7 @@ static int serial_callback(struct stat *sb, char *filename, const char *path, en
392 392
 
393 393
 /* Non-IDSESSION handler
394 394
  * Returns non zero for serious errors, zero otherwise */
395
-int serial_client_scan(char *file, int scantype, int *infected, int maxlevel, int flags) {
395
+int serial_client_scan(char *file, int scantype, int *infected, int *err, int maxlevel, int flags) {
396 396
     struct cli_ftw_cbdata data;
397 397
     struct client_serial_data cdata;
398 398
     int ftw;
... ...
@@ -406,8 +410,9 @@ int serial_client_scan(char *file, int scantype, int *infected, int maxlevel, in
406 406
 
407 407
     ftw = cli_ftw(file, flags, maxlevel ? maxlevel : INT_MAX, serial_callback, &data, NULL);
408 408
     *infected += cdata.infected;
409
+    *err += cdata.errors;
409 410
 
410
-    if((cdata.errors < cdata.files) && (ftw == CL_SUCCESS || ftw == CL_BREAK)) {
411
+    if(!cdata.errors && (ftw == CL_SUCCESS || ftw == CL_BREAK)) {
411 412
 	if(cdata.printok)
412 413
 	    logg("~%s: OK\n", file);
413 414
 	return 0;
... ...
@@ -496,9 +501,11 @@ static int parallel_callback(struct stat *sb, char *filename, const char *path,
496 496
     struct SCANID *cid;
497 497
     int res;
498 498
 
499
+    c->files++;
499 500
     switch(reason) {
500 501
     case error_stat:
501 502
 	logg("!Can't access file %s\n", path);
503
+	c->errors++;
502 504
 	return CL_SUCCESS;
503 505
     case error_mem:
504 506
 	logg("!Memory allocation failed in ftw\n");
... ...
@@ -551,7 +558,6 @@ static int parallel_callback(struct stat *sb, char *filename, const char *path,
551 551
     cid->file = filename;
552 552
     cid->next = c->ids;
553 553
     c->ids = cid;
554
-    c->files++;
555 554
 
556 555
     switch(c->scantype) {
557 556
 #ifdef HAVE_FD_PASSING
... ...
@@ -577,7 +583,7 @@ static int parallel_callback(struct stat *sb, char *filename, const char *path,
577 577
 
578 578
 /* IDSESSION handler
579 579
  * Returns non zero for serious errors, zero otherwise */
580
-int parallel_client_scan(char *file, int scantype, int *infected, int maxlevel, int flags) {
580
+int parallel_client_scan(char *file, int scantype, int *infected, int *err, int maxlevel, int flags) {
581 581
     struct cli_ftw_cbdata data;
582 582
     struct client_parallel_data cdata;
583 583
     int ftw;
... ...
@@ -602,6 +608,7 @@ int parallel_client_scan(char *file, int scantype, int *infected, int maxlevel,
602 602
     ftw = cli_ftw(file, flags, maxlevel ? maxlevel : INT_MAX, parallel_callback, &data, NULL);
603 603
 
604 604
     if(ftw != CL_SUCCESS) {
605
+	*err += cdata.errors;
605 606
 	*infected += cdata.infected;
606 607
 	closesocket(cdata.sockd);
607 608
 	return 1;
... ...
@@ -612,15 +619,18 @@ int parallel_client_scan(char *file, int scantype, int *infected, int maxlevel,
612 612
     closesocket(cdata.sockd);
613 613
 
614 614
     *infected += cdata.infected;
615
+    *err += cdata.errors;
615 616
 
616 617
     if(cdata.ids) {
617 618
 	logg("!Clamd closed the connection before scanning all files.\n");
618 619
 	return 1;
619 620
     }
621
+    if(cdata.errors)
622
+	return 1;
623
+
620 624
     if(!cdata.files)
621 625
 	return 0;
622
-    if(cdata.errors == cdata.files)
623
-	return 1;
626
+
624 627
     if(cdata.printok)
625 628
 	logg("~%s: OK\n", file);
626 629
     return 0;
... ...
@@ -34,7 +34,7 @@ int dconnect(void);
34 34
 int sendln(int sockd, const char *line, unsigned int len);
35 35
 void recvlninit(struct RCVLN *s, int sockd);
36 36
 int recvln(struct RCVLN *s, char **rbol, char **reol);
37
-int serial_client_scan(char *file, int scantype, int *infected, int maxlevel, int flags);
38
-int parallel_client_scan(char *file, int scantype, int *infected, int maxlevel, int flags);
39
-int dsresult(int sockd, int scantype, const char *filename, int *printok, int *files, int *errors);
37
+int serial_client_scan(char *file, int scantype, int *infected, int *err, int maxlevel, int flags);
38
+int parallel_client_scan(char *file, int scantype, int *infected, int *err, int maxlevel, int flags);
39
+int dsresult(int sockd, int scantype, const char *filename, int *printok, int *errors);
40 40
 #endif