Browse code

respect --exclude/include when entering directories

git-svn-id: file:///var/lib/svn/clamav-devel/trunk/clamav-devel@1362 77e5149b-7576-45b1-b177-96237e5ba77b

Tomasz Kojm authored on 2005/03/01 10:19:48
Showing 5 changed files
... ...
@@ -1,3 +1,8 @@
1
+Tue Mar  1 02:16:15 CET 2005 (tk)
2
+---------------------------------
3
+  * clamscan: respect --exclude/include when entering directories (requested
4
+	      by Dean Plant <dean.plant*roke.co.uk>)
5
+
1 6
 Tue Mar  1 01:51:53 CET 2005 (tk)
2 7
 ---------------------------------
3 8
   * clamscan: add "Engine version" to summary (requested by Robert
... ...
@@ -39,10 +39,6 @@
39 39
 #include <clamav.h>
40 40
 #include <errno.h>
41 41
 
42
-#ifdef HAVE_REGEX_H
43
-#include <regex.h>
44
-#endif
45
-
46 42
 #include "defaults.h"
47 43
 #include "others.h"
48 44
 #include "options.h"
... ...
@@ -76,7 +72,7 @@ int scanmanager(const struct optstruct *opt)
76 76
 #if !defined(C_CYGWIN) && !defined(C_OS2) && !defined(C_BEOS)
77 77
     if(!geteuid()) {
78 78
 	if((user = getpwnam(UNPUSER)) == NULL) {
79
-	    mprintf("@Can't get information about user "UNPUSER".\n");
79
+	    mprintf("@Can't get information about user "UNPUSER"\n");
80 80
 	    exit(60); /* this is critical problem, so we just exit here */
81 81
 	}
82 82
     }
... ...
@@ -122,7 +118,7 @@ int scanmanager(const struct optstruct *opt)
122 122
     }
123 123
 
124 124
     if(!trie) {
125
-	mprintf("@Can't initialize the virus database.\n");
125
+	mprintf("@Can't initialize the virus database\n");
126 126
 	return 50;
127 127
     }
128 128
 
... ...
@@ -214,7 +210,7 @@ int scanmanager(const struct optstruct *opt)
214 214
 
215 215
 	/* we need full path for some reasons (eg. archive handling) */
216 216
 	if(!getcwd(cwd, sizeof(cwd))) {
217
-	    mprintf("@Can't get absolute pathname of current working directory.\n");
217
+	    mprintf("@Can't get absolute pathname of current working directory\n");
218 218
 	    ret = 57;
219 219
 	} else
220 220
 	    ret = scandirs(cwd, trie, user, opt, limits, options);
... ...
@@ -243,7 +239,7 @@ int scanmanager(const struct optstruct *opt)
243 243
 		if(compression && (thefilename[0] != '/' && thefilename[0] != '\\' && thefilename[1] != ':')) {
244 244
 		    /* we need to complete the path */
245 245
 		    if(!getcwd(cwd, sizeof(cwd))) {
246
-			mprintf("@Can't get absolute pathname of current working directory.\n");
246
+			mprintf("@Can't get absolute pathname of current working directory\n");
247 247
 			free(limits);
248 248
 			return 57;
249 249
 		    } else {
... ...
@@ -295,29 +291,6 @@ int scanmanager(const struct optstruct *opt)
295 295
     return ret;
296 296
 }
297 297
 
298
-int match_regex(const char *filename, const char *pattern)
299
-{
300
-#ifdef HAVE_REGEX_H
301
-	regex_t reg;
302
-	int match, flags;
303
-#if !defined(C_CYGWIN) && !defined(C_OS2)
304
-	flags = 0;
305
-#else
306
-	flags = REG_ICASE; /* case insensitive on Windows */
307
-#endif	
308
-	if(regcomp(&reg, pattern, flags) != 0) {
309
-	    mprintf("!%s: Could not parse regular expression %s.\n", filename, pattern);
310
-	    logg("!%s: Could not parse regular expression %s.\n", filename, pattern);
311
-		return 2;
312
-	}
313
-	match = (regexec(&reg, filename, 0, NULL, 0) == REG_NOMATCH) ? 0 : 1;
314
-	regfree(&reg);
315
-	return match;
316
-#else /* HAVE_REGEX_H */
317
-	return strstr(filename, pattern) ? 1 : 0;
318
-#endif
319
-}
320
-
321 298
 int scanfile(const char *filename, struct cl_node *root, const struct passwd *user, const struct optstruct *opt, const struct cl_limits *limits, int options)
322 299
 {
323 300
 	int ret, included;
... ...
@@ -331,50 +304,51 @@ int scanfile(const char *filename, struct cl_node *root, const struct passwd *us
331 331
 	if(stat(filename, &sb) != -1)
332 332
 	    if(sb.st_dev == procdev) {
333 333
 		if(!printinfected)
334
-		    mprintf("%s: Excluded (/proc).\n", filename);
334
+		    mprintf("%s: Excluded (/proc)\n", filename);
335 335
 		return 0;
336 336
 	    }
337 337
 #endif    
338
-    
338
+
339 339
     if(optl(opt, "exclude")) {
340 340
 	argument = getfirstargl(opt, "exclude", &optnode);
341
-	while (argument) {
341
+	while(argument) {
342 342
 	    if(match_regex(filename, argument) == 1) {
343 343
 		if(!printinfected)
344
-		    mprintf("%s: Excluded.\n", filename);
344
+		    mprintf("%s: Excluded\n", filename);
345 345
 		return 0;
346 346
 	    }
347 347
 	    argument = getnextargl(&optnode, "exclude");
348 348
 	}
349 349
     }
350
-     
350
+
351 351
    if(optl(opt, "include")) {
352 352
 	included = 0;
353
-	argument = getfirstargl(opt, "include",&optnode);
354
-	while (argument && !included) {
355
-	    if(match_regex(filename, argument) == 1)
353
+	argument = getfirstargl(opt, "include", &optnode);
354
+	while(argument && !included) {
355
+	    if(match_regex(filename, argument) == 1) {
356 356
 		included = 1;
357
+		break;
358
+	    }
357 359
 	    argument = getnextargl(&optnode, "include");
358 360
 	}
359 361
 
360
-	if (!included) {
362
+	if(!included) {
361 363
 	    if(!printinfected)
362
-		mprintf("%s: Excluded.\n", filename);
364
+		mprintf("%s: Excluded\n", filename);
363 365
 	    return 0;
364 366
 	}
365
-	
366 367
     }
367 368
 
368 369
     if(fileinfo(filename, 1) == 0) {
369 370
 	if(!printinfected)
370
-	    mprintf("%s: Empty file.\n", filename);
371
+	    mprintf("%s: Empty file\n", filename);
371 372
 	return 0;
372 373
     }
373 374
 
374 375
     if(geteuid())
375 376
 	if(checkaccess(filename, NULL, R_OK) != 1) {
376 377
 	    if(!printinfected)
377
-		mprintf("%s: Access denied.\n", filename);
378
+		mprintf("%s: Access denied\n", filename);
378 379
 	    return 0;
379 380
 	}
380 381
 
... ...
@@ -392,12 +366,12 @@ int scanfile(const char *filename, struct cl_node *root, const struct passwd *us
392 392
 	if((ret = checkfile(filename, root, limits, options)) == CL_VIRUS) {
393 393
 	    if(optl(opt, "remove")) {
394 394
 		if(unlink(filename)) {
395
-		    mprintf("%s: Can't remove.\n", filename);
396
-		    logg("%s: Can't remove.\n", filename);
395
+		    mprintf("%s: Can't remove\n", filename);
396
+		    logg("%s: Can't remove\n", filename);
397 397
 		    claminfo.notremoved++;
398 398
 		} else {
399
-		    mprintf("%s: Removed.\n", filename);
400
-		    logg("%s: Removed.\n", filename);
399
+		    mprintf("%s: Removed\n", filename);
400
+		    logg("%s: Removed\n", filename);
401 401
 		}
402 402
 	    } else if (optl(opt, "move"))
403 403
 		move_infected(filename, opt);
... ...
@@ -428,21 +402,21 @@ int scanfile(const char *filename, struct cl_node *root, const struct passwd *us
428 428
 	/* check permissions */
429 429
 	switch(checkaccess(filename, UNPUSER, R_OK)) {
430 430
 	    case -1:
431
-		mprintf("@Can't get information about user "UNPUSER".\n");
431
+		mprintf("@Can't get information about user "UNPUSER"\n");
432 432
 		exit(60); /* this is a critical problem so we just exit here */
433 433
 	    case -2:
434
-		mprintf("@Can't fork.\n");
434
+		mprintf("@Can't fork\n");
435 435
 		exit(61);
436 436
 	    case 0: /* read access denied */
437 437
 		if(geteuid()) {
438 438
 		    if(!printinfected)
439
-			mprintf("%s: Access denied to archive.\n", filename);
439
+			mprintf("%s: Access denied to archive\n", filename);
440 440
 		} else {
441 441
 
442 442
 		    if(limits && limits->maxfilesize)
443 443
 			if(fileinfo(filename, 1) / 1024 > limits->maxfilesize) {
444 444
 			    if(!printinfected)
445
-				mprintf("%s: Archive too big.\n", filename);
445
+				mprintf("%s: Archive too big\n", filename);
446 446
 			    return 0;
447 447
 			}
448 448
 
... ...
@@ -458,12 +432,12 @@ int scanfile(const char *filename, struct cl_node *root, const struct passwd *us
458 458
     if((ret = checkfile(filename, root, limits, options)) == CL_VIRUS) {
459 459
 	if(optl(opt, "remove")) {
460 460
 	    if(unlink(filename)) {
461
-		mprintf("%s: Can't remove.\n", filename);
462
-		logg("%s: Can't remove.\n", filename);
461
+		mprintf("%s: Can't remove\n", filename);
462
+		logg("%s: Can't remove\n", filename);
463 463
 		claminfo.notremoved++;
464 464
 	    } else {
465
-		mprintf("%s: Removed.\n", filename);
466
-		logg("%s: Removed.\n", filename);
465
+		mprintf("%s: Removed\n", filename);
466
+		logg("%s: Removed\n", filename);
467 467
 	    }
468 468
 	} else if (optl(opt, "move"))
469 469
             move_infected(filename, opt);
... ...
@@ -481,7 +455,7 @@ int scancompressed(const char *filename, struct cl_node *root, const struct pass
481 481
     stat(filename, &statbuf);
482 482
 
483 483
     if(!S_ISREG(statbuf.st_mode)) {
484
-	mprintf("^Suspected archive %s is not a regular file.\n", filename);
484
+	mprintf("^Suspected archive %s is not a regular file\n", filename);
485 485
 	return 0; /* hmm ? */
486 486
     }
487 487
 
... ...
@@ -497,7 +471,7 @@ int scancompressed(const char *filename, struct cl_node *root, const struct pass
497 497
 #endif
498 498
 
499 499
     if(checkaccess(tmpdir, UNPUSER, W_OK) != 1) {
500
-	mprintf("@Can't write to the temporary directory.\n");
500
+	mprintf("@Can't write to the temporary directory\n");
501 501
 	exit(64);
502 502
     }
503 503
 
... ...
@@ -606,10 +580,10 @@ int scancompressed(const char *filename, struct cl_node *root, const struct pass
606 606
 
607 607
     switch(ret) {
608 608
 	case -1:
609
-	    mprintf("@Can't fork().\n");
609
+	    mprintf("@Can't fork()\n");
610 610
 	    exit(61); /* this is critical problem, so we just exit here */
611 611
 	case -2:
612
-	    mprintf("@Can't execute some unpacker. Check paths and permissions on the temporary directory.\n");
612
+	    mprintf("@Can't execute some unpacker. Check paths and permissions on the temporary directory\n");
613 613
 	    /* This is no longer a critical error (since 0.24). We scan
614 614
 	     * raw archive.
615 615
 	     */
... ...
@@ -619,12 +593,12 @@ int scancompressed(const char *filename, struct cl_node *root, const struct pass
619 619
 	    if((ret = checkfile(filename, root, limits, 0)) == CL_VIRUS) {
620 620
 		if(optl(opt, "remove")) {
621 621
 		    if(unlink(filename)) {
622
-			mprintf("%s: Can't remove.\n", filename);
623
-			logg("%s: Can't remove.\n", filename);
622
+			mprintf("%s: Can't remove\n", filename);
623
+			logg("%s: Can't remove\n", filename);
624 624
 			claminfo.notremoved++;
625 625
 		    } else {
626
-			mprintf("%s: Removed.\n", filename);
627
-			logg("%s: Removed.\n", filename);
626
+			mprintf("%s: Removed\n", filename);
627
+			logg("%s: Removed\n", filename);
628 628
 		    }
629 629
 		} else if (optl(opt, "move"))
630 630
 		    move_infected(filename, opt);
... ...
@@ -642,12 +616,12 @@ int scancompressed(const char *filename, struct cl_node *root, const struct pass
642 642
 	    if((ret = checkfile(filename, root, limits, 0)) == CL_VIRUS) {
643 643
 		if(optl(opt, "remove")) {
644 644
 		    if(unlink(filename)) {
645
-			mprintf("%s: Can't remove.\n", filename);
646
-			logg("%s: Can't remove.\n", filename);
645
+			mprintf("%s: Can't remove\n", filename);
646
+			logg("%s: Can't remove\n", filename);
647 647
 			claminfo.notremoved++;
648 648
 		    } else {
649
-			mprintf("%s: Removed.\n", filename);
650
-			logg("%s: Removed.\n", filename);
649
+			mprintf("%s: Removed\n", filename);
650
+			logg("%s: Removed\n", filename);
651 651
 		    }
652 652
 		} else if (optl(opt, "move"))
653 653
 		    move_infected(filename, opt);
... ...
@@ -662,12 +636,12 @@ int scancompressed(const char *filename, struct cl_node *root, const struct pass
662 662
 
663 663
 	    if(optl(opt, "remove")) {
664 664
 		if(unlink(filename)) {
665
-		    mprintf("%s: Can't remove.\n", filename);
666
-		    logg("%s: Can't remove.\n", filename);
665
+		    mprintf("%s: Can't remove\n", filename);
666
+		    logg("%s: Can't remove\n", filename);
667 667
 		    claminfo.notremoved++;
668 668
 		} else {
669
-		    mprintf("%s: Removed.\n", filename);
670
-		    logg("%s: Removed.\n", filename);
669
+		    mprintf("%s: Removed\n", filename);
670
+		    logg("%s: Removed\n", filename);
671 671
 		}
672 672
 	    } else if (optl(opt, "move"))
673 673
 		move_infected(filename, opt);
... ...
@@ -687,7 +661,7 @@ int scandenied(const char *filename, struct cl_node *root, const struct passwd *
687 687
 
688 688
     stat(filename, &statbuf);
689 689
     if(!S_ISREG(statbuf.st_mode)) {
690
-	mprintf("^Suspected archive %s is not a regular file.\n", filename);
690
+	mprintf("^Suspected archive %s is not a regular file\n", filename);
691 691
 	return 0;
692 692
     }
693 693
 
... ...
@@ -704,7 +678,7 @@ int scandenied(const char *filename, struct cl_node *root, const struct passwd *
704 704
 
705 705
 
706 706
     if(checkaccess(tmpdir, UNPUSER, W_OK) != 1) {
707
-	mprintf("@Can't write to the temporary directory %s.\n", tmpdir);
707
+	mprintf("@Can't write to the temporary directory %s\n", tmpdir);
708 708
 	exit(64);
709 709
     }
710 710
 
... ...
@@ -725,7 +699,7 @@ int scandenied(const char *filename, struct cl_node *root, const struct passwd *
725 725
     sprintf(tmpfile, "%s/%s", gendir, pt);
726 726
 
727 727
     if(filecopy(filename, tmpfile) == -1) {
728
-	mprintf("!I/O error.\n");
728
+	mprintf("!I/O error\n");
729 729
 	perror("copyfile()");
730 730
 	exit(58);
731 731
     }
... ...
@@ -745,12 +719,12 @@ int scandenied(const char *filename, struct cl_node *root, const struct passwd *
745 745
 
746 746
 	if(optl(opt, "remove")) {
747 747
 	    if(unlink(filename)) {
748
-		mprintf("%s: Can't remove.\n", filename);
749
-		logg("%s: Can't remove.\n", filename);
748
+		mprintf("%s: Can't remove\n", filename);
749
+		logg("%s: Can't remove\n", filename);
750 750
 		claminfo.notremoved++;
751 751
 	    } else {
752
-	        mprintf("%s: Removed.\n", filename);
753
-	        logg("%s: Removed.\n", filename);
752
+	        mprintf("%s: Removed\n", filename);
753
+	        logg("%s: Removed\n", filename);
754 754
 	    }
755 755
 	} else if (optl(opt, "move"))
756 756
 	    move_infected(filename, opt);
... ...
@@ -821,7 +795,7 @@ int checkstdin(const struct cl_node *root, const struct cl_limits *limits, int o
821 821
 #endif
822 822
 
823 823
     if(checkaccess(tmpdir, UNPUSER, W_OK) != 1) {
824
-	mprintf("@Can't write to temporary directory.\n");
824
+	mprintf("@Can't write to temporary directory\n");
825 825
 	return 64;
826 826
     }
827 827
 
... ...
@@ -901,18 +875,18 @@ int clamav_unpack(const char *prog, char **args, const char *tmpdir, const struc
901 901
 
902 902
 #ifdef HAVE_SETGROUPS
903 903
 		if(setgroups(1, &user->pw_gid)) {
904
-		    fprintf(stderr, "ERROR: setgroups() failed.\n");
904
+		    fprintf(stderr, "ERROR: setgroups() failed\n");
905 905
 		    exit(1);
906 906
 		}
907 907
 #endif
908 908
 
909 909
 		if(setgid(user->pw_gid)) {
910
-		    fprintf(stderr, "ERROR: setgid(%d) failed.\n", (int) user->pw_gid);
910
+		    fprintf(stderr, "ERROR: setgid(%d) failed\n", (int) user->pw_gid);
911 911
 		    exit(1);
912 912
 		}
913 913
 
914 914
 		if(setuid(user->pw_uid)) {
915
-		    fprintf(stderr, "ERROR: setuid(%d) failed.\n", (int) user->pw_uid);
915
+		    fprintf(stderr, "ERROR: setuid(%d) failed\n", (int) user->pw_uid);
916 916
 		    exit(1);
917 917
 		}
918 918
 	    }
... ...
@@ -957,7 +931,7 @@ int clamav_unpack(const char *prog, char **args, const char *tmpdir, const struc
957 957
 		switch(WTERMSIG(status)) {
958 958
 
959 959
 		    case 9:
960
-			mprintf("\nUnpacker process %d stopped due to exceeded limits.\n", pid);
960
+			mprintf("\nUnpacker process %d stopped due to exceeded limits\n", pid);
961 961
 			return 0;
962 962
 		    case 6: /* abort */
963 963
 			mprintf("@Can't run %s\n", prog);
... ...
@@ -40,6 +40,10 @@
40 40
 #include <signal.h>
41 41
 #include <target.h>
42 42
 
43
+#ifdef HAVE_REGEX_H
44
+#include <regex.h>
45
+#endif
46
+
43 47
 #include "output.h"
44 48
 #include "others.h"
45 49
 
... ...
@@ -123,3 +127,26 @@ int isnumb(const char *str)
123 123
 
124 124
     return 1;
125 125
 }
126
+
127
+int match_regex(const char *filename, const char *pattern)
128
+{
129
+#ifdef HAVE_REGEX_H
130
+	regex_t reg;
131
+	int match, flags;
132
+#if !defined(C_CYGWIN) && !defined(C_OS2)
133
+	flags = 0;
134
+#else
135
+	flags = REG_ICASE; /* case insensitive on Windows */
136
+#endif	
137
+	if(regcomp(&reg, pattern, flags) != 0) {
138
+	    mprintf("!%s: Could not parse regular expression %s.\n", filename, pattern);
139
+	    logg("!%s: Could not parse regular expression %s.\n", filename, pattern);
140
+		return 2;
141
+	}
142
+	match = (regexec(&reg, filename, 0, NULL, 0) == REG_NOMATCH) ? 0 : 1;
143
+	regfree(&reg);
144
+	return match;
145
+#else /* HAVE_REGEX_H */
146
+	return strstr(filename, pattern) ? 1 : 0;
147
+#endif
148
+}
... ...
@@ -22,5 +22,6 @@
22 22
 int fileinfo(const char *filename, short i);
23 23
 int checkaccess(const char *path, const char *username, int mode);
24 24
 int isnumb(const char *str);
25
+int match_regex(const char *filename, const char *pattern);
25 26
 
26 27
 #endif
... ...
@@ -51,7 +51,40 @@ int treewalk(const char *dirname, struct cl_node *root, const struct passwd *use
51 51
 	struct dirent *dent;
52 52
 	struct stat statbuf;
53 53
 	char *fname;
54
-	int scanret = 0;
54
+	int scanret = 0, included;
55
+	struct optnode *optnode;
56
+	char *argument;
57
+
58
+
59
+    if(optl(opt, "exclude")) {
60
+	argument = getfirstargl(opt, "exclude", &optnode);
61
+	while(argument) {
62
+	    if(match_regex(dirname, argument) == 1) {
63
+		if(!printinfected)
64
+		    mprintf("%s: Excluded\n", dirname);
65
+		return 0;
66
+	    }
67
+	    argument = getnextargl(&optnode, "exclude");
68
+	}
69
+    }
70
+
71
+   if(optl(opt, "include")) {
72
+	included = 0;
73
+	argument = getfirstargl(opt, "include", &optnode);
74
+	while(argument && !included) {
75
+	    if(match_regex(dirname, argument) == 1) {
76
+		included = 1;
77
+		break;
78
+	    }
79
+	    argument = getnextargl(&optnode, "include");
80
+	}
81
+
82
+	if(!included) {
83
+	    if(!printinfected)
84
+		mprintf("%s: Excluded\n", dirname);
85
+	    return 0;
86
+	}
87
+    }
55 88
 
56 89
     claminfo.dirs++;
57 90