Browse code

drop support for external unpackers (bb#1052)

git-svn: trunk@3888

Tomasz Kojm authored on 2008/06/11 01:59:19
Showing 11 changed files
... ...
@@ -1,3 +1,7 @@
1
+Tue Jun 10 18:18:42 CEST 2008 (tk)
2
+----------------------------------
3
+  * clamscan: drop support for external unpackers (bb#1052)
4
+
1 5
 Mon Jun  9 20:31:50 CEST 2008 (tk)
2 6
 ----------------------------------
3 7
   * sync with 0.93.1
... ...
@@ -36,9 +36,7 @@ clamscan_SOURCES = \
36 36
     others.h \
37 37
     global.h \
38 38
     manager.c \
39
-    manager.h \
40
-    treewalk.c \
41
-    treewalk.h
39
+    manager.h
42 40
 
43 41
 DEFS = @DEFS@ -DCL_NOTHREADS
44 42
 LIBS = $(top_builddir)/libclamav/libclamav.la @THREAD_LIBS@
... ...
@@ -69,8 +69,7 @@ binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
69 69
 PROGRAMS = $(bin_PROGRAMS)
70 70
 am_clamscan_OBJECTS = output.$(OBJEXT) getopt.$(OBJEXT) \
71 71
 	cfgparser.$(OBJEXT) misc.$(OBJEXT) options.$(OBJEXT) \
72
-	clamscan.$(OBJEXT) others.$(OBJEXT) manager.$(OBJEXT) \
73
-	treewalk.$(OBJEXT)
72
+	clamscan.$(OBJEXT) others.$(OBJEXT) manager.$(OBJEXT)
74 73
 clamscan_OBJECTS = $(am_clamscan_OBJECTS)
75 74
 clamscan_LDADD = $(LDADD)
76 75
 DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
... ...
@@ -234,9 +233,7 @@ clamscan_SOURCES = \
234 234
     others.h \
235 235
     global.h \
236 236
     manager.c \
237
-    manager.h \
238
-    treewalk.c \
239
-    treewalk.h
237
+    manager.h
240 238
 
241 239
 AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/shared -I$(top_srcdir)/libclamav
242 240
 all: all-am
... ...
@@ -318,7 +315,6 @@ distclean-compile:
318 318
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/options.Po@am__quote@
319 319
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/others.Po@am__quote@
320 320
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/output.Po@am__quote@
321
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/treewalk.Po@am__quote@
322 321
 
323 322
 .c.o:
324 323
 @am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
... ...
@@ -40,13 +40,13 @@
40 40
 #include "others.h"
41 41
 #include "global.h"
42 42
 #include "manager.h"
43
-#include "treewalk.h"
44 43
 
45 44
 #include "shared/misc.h"
46 45
 #include "shared/output.h"
47 46
 #include "shared/options.h"
48 47
 
49 48
 #include "libclamav/str.h"
49
+#include "libclamav/clamav.h"
50 50
 
51 51
 void help(void);
52 52
 
... ...
@@ -322,7 +322,7 @@ void help(void)
322 322
     mprintf("    --no-ole2                            Disable OLE2 support\n");
323 323
     mprintf("    --no-pdf                             Disable PDF support\n");
324 324
     mprintf("    --no-html                            Disable HTML support\n");
325
-    mprintf("    --no-archive                         Disable libclamav archive support\n");
325
+    mprintf("    --no-archive                         Disable archive support\n");
326 326
     mprintf("    --detect-broken                      Try to detect broken executable files\n");
327 327
     mprintf("    --block-encrypted                    Block encrypted archives\n");
328 328
     mprintf("    --mail-follow-urls                   Download and scan URLs\n");
... ...
@@ -332,15 +332,8 @@ void help(void)
332 332
     mprintf("    --max-files=#n                       The maximum number of files to scan for each container file (*)\n");
333 333
     mprintf("    --max-recursion=#n                   Maximum archive recursion level for container file (*)\n");
334 334
     mprintf("    --max-dir-recursion=#n               Maximum directory recursion level\n");
335
-    mprintf("    --unzip[=FULLPATH]                   Enable support for .zip files\n");
336
-    mprintf("    --unrar[=FULLPATH]                   Enable support for .rar files\n");
337
-    mprintf("    --arj[=FULLPATH]                     Enable support for .arj files\n");
338
-    mprintf("    --unzoo[=FULLPATH]                   Enable support for .zoo files\n");
339
-    mprintf("    --lha[=FULLPATH]                     Enable support for .lha files\n");
340
-    mprintf("    --jar[=FULLPATH]                     Enable support for .jar files\n");
341
-    mprintf("    --tar[=FULLPATH]                     Enable support for .tar files\n");
342
-    mprintf("    --deb[=FULLPATH to ar]               Enable support for .deb files\n");
343
-    mprintf("    --tgz[=FULLPATH]                     Enable support for .tar.gz, .tgz files\n\n");
344
-    mprintf("(*) Certain files (e.g. documents, archives, etc.) may in turn contain other files inside.\n");
345
-    mprintf("    The above options ensure safe processing of this kind of data.\n\n");
335
+
336
+    mprintf("\n");
337
+    mprintf("(*) Certain files (e.g. documents, archives, etc.) may in turn contain other\n");
338
+    mprintf("    files inside. The above options ensure safe processing of this kind of data.\n\n");
346 339
 }
... ...
@@ -80,15 +80,6 @@ static struct option clamscan_longopt[] = {
80 80
     {"phishing-ssl", 0, 0, 0},
81 81
     {"phishing-cloak", 0, 0, 0},
82 82
     {"no-algorithmic", 0, 0, 0},
83
-    {"unzip", 2, 0, 0},
84
-    {"unrar", 2, 0, 0},
85
-    {"arj", 2, 0, 0},
86
-    {"unzoo", 2, 0, 0},
87
-    {"lha", 2, 0, 0},
88
-    {"jar", 2, 0, 0},
89
-    {"tar", 2, 0, 0},
90
-    {"tgz", 2, 0, 0},
91
-    {"deb", 2, 0, 0},
92 83
 
93 84
     /* developers only */
94 85
     {"dev-ac-only", 0, 0, 0},
... ...
@@ -34,11 +34,8 @@
34 34
 #include <sys/wait.h>
35 35
 #include <utime.h>
36 36
 #endif
37
-#ifdef HAVE_GRP_H
38
-#include <grp.h>
39
-#endif
40
-#ifdef HAVE_PWD_H
41
-#include <pwd.h>
37
+#ifndef C_WINDOWS
38
+#include <dirent.h>
42 39
 #endif
43 40
 #include <fcntl.h>
44 41
 #ifdef	HAVE_UNISTD_H
... ...
@@ -50,7 +47,6 @@
50 50
 
51 51
 #include "manager.h"
52 52
 #include "others.h"
53
-#include "treewalk.h"
54 53
 #include "global.h"
55 54
 
56 55
 #include "shared/options.h"
... ...
@@ -75,9 +71,204 @@ dev_t procdev;
75 75
 #define	O_BINARY    0
76 76
 #endif
77 77
 
78
-static int scandirs(const char *dirname, struct cl_engine *engine, const struct passwd *user, const struct optstruct *opt, const struct cl_limits *limits, int options)
78
+static void move_infected(const char *filename, const struct optstruct *opt);
79
+
80
+static int scanfile(const char *filename, struct cl_engine *engine, const struct optstruct *opt, const struct cl_limits *limits, unsigned int options)
79 81
 {
80
-    return treewalk(dirname, engine, user, opt, limits, options, 1);
82
+	int ret = 0, fd, included, printclean = 1;
83
+	const struct optnode *optnode;
84
+	char *argument;
85
+	const char *virname;
86
+#ifdef C_LINUX
87
+	struct stat sb;
88
+
89
+    /* argh, don't scan /proc files */
90
+    if(procdev)
91
+	if(stat(filename, &sb) != -1)
92
+	    if(sb.st_dev == procdev) {
93
+		if(!printinfected)
94
+		    logg("~%s: Excluded (/proc)\n", filename);
95
+		return 0;
96
+	    }
97
+#endif    
98
+
99
+    if(opt_check(opt, "exclude")) {
100
+	argument = opt_firstarg(opt, "exclude", &optnode);
101
+	while(argument) {
102
+	    if(match_regex(filename, argument) == 1) {
103
+		if(!printinfected)
104
+		    logg("~%s: Excluded\n", filename);
105
+		return 0;
106
+	    }
107
+	    argument = opt_nextarg(&optnode, "exclude");
108
+	}
109
+    }
110
+
111
+   if(opt_check(opt, "include")) {
112
+	included = 0;
113
+	argument = opt_firstarg(opt, "include", &optnode);
114
+	while(argument && !included) {
115
+	    if(match_regex(filename, argument) == 1) {
116
+		included = 1;
117
+		break;
118
+	    }
119
+	    argument = opt_nextarg(&optnode, "include");
120
+	}
121
+
122
+	if(!included) {
123
+	    if(!printinfected)
124
+		logg("~%s: Excluded\n", filename);
125
+	    return 0;
126
+	}
127
+    }
128
+
129
+    if(fileinfo(filename, 1) == 0) {
130
+	if(!printinfected)
131
+	    logg("~%s: Empty file\n", filename);
132
+	return 0;
133
+    }
134
+
135
+#ifndef C_WINDOWS
136
+    if(geteuid())
137
+	if(checkaccess(filename, NULL, R_OK) != 1) {
138
+	    if(!printinfected)
139
+		logg("~%s: Access denied\n", filename);
140
+	    return 0;
141
+	}
142
+#endif
143
+
144
+    logg("*Scanning %s\n", filename);
145
+
146
+    if((fd = open(filename, O_RDONLY|O_BINARY)) == -1) {
147
+	logg("^Can't open file %s\n", filename);
148
+	return 54;
149
+    }
150
+
151
+    info.files++;
152
+
153
+    if((ret = cl_scandesc(fd, &virname, &info.blocks, engine, limits, options)) == CL_VIRUS) {
154
+	logg("~%s: %s FOUND\n", filename, virname);
155
+	info.ifiles++;
156
+
157
+	if(bell)
158
+	    fprintf(stderr, "\007");
159
+
160
+    } else if(ret == CL_CLEAN) {
161
+	if(!printinfected && printclean)
162
+	    mprintf("~%s: OK\n", filename);
163
+    } else
164
+	if(!printinfected)
165
+	    logg("~%s: %s\n", filename, cl_strerror(ret));
166
+
167
+    close(fd);
168
+
169
+    if(ret == CL_VIRUS) {
170
+	if(opt_check(opt, "remove")) {
171
+	    if(unlink(filename)) {
172
+		logg("^%s: Can't remove\n", filename);
173
+		info.notremoved++;
174
+	    } else {
175
+		logg("~%s: Removed\n", filename);
176
+	    }
177
+	} else if(opt_check(opt, "move") || opt_check(opt, "copy"))
178
+            move_infected(filename, opt);
179
+    }
180
+
181
+    return ret;
182
+}
183
+
184
+static int scandirs(const char *dirname, struct cl_engine *engine, const struct optstruct *opt, const struct cl_limits *limits, unsigned int options, unsigned int depth)
185
+{
186
+	DIR *dd;
187
+	struct dirent *dent;
188
+	struct stat statbuf;
189
+	char *fname;
190
+	int scanret = 0, included;
191
+	unsigned int maxdepth;
192
+	const struct optnode *optnode;
193
+	char *argument;
194
+
195
+
196
+    if(opt_check(opt, "exclude-dir")) {
197
+	argument = opt_firstarg(opt, "exclude-dir", &optnode);
198
+	while(argument) {
199
+	    if(match_regex(dirname, argument) == 1) {
200
+		if(!printinfected)
201
+		    logg("~%s: Excluded\n", dirname);
202
+		return 0;
203
+	    }
204
+	    argument = opt_nextarg(&optnode, "exclude-dir");
205
+	}
206
+    }
207
+
208
+   if(opt_check(opt, "include-dir")) {
209
+	included = 0;
210
+	argument = opt_firstarg(opt, "include-dir", &optnode);
211
+	while(argument && !included) {
212
+	    if(match_regex(dirname, argument) == 1) {
213
+		included = 1;
214
+		break;
215
+	    }
216
+	    argument = opt_nextarg(&optnode, "include-dir");
217
+	}
218
+
219
+	if(!included) {
220
+	    if(!printinfected)
221
+		logg("~%s: Excluded\n", dirname);
222
+	    return 0;
223
+	}
224
+    }
225
+
226
+    if(opt_check(opt, "max-dir-recursion"))
227
+        maxdepth = atoi(opt_arg(opt, "max-dir-recursion"));
228
+    else
229
+        maxdepth = 15;
230
+
231
+    if(depth > maxdepth)
232
+	return 0;
233
+
234
+    info.dirs++;
235
+    depth++;
236
+
237
+    if((dd = opendir(dirname)) != NULL) {
238
+	while((dent = readdir(dd))) {
239
+#if !defined(C_INTERIX) && !defined(C_WINDOWS) && !defined(C_CYGWIN)
240
+	    if(dent->d_ino)
241
+#endif
242
+	    {
243
+		if(strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..")) {
244
+		    /* build the full name */
245
+		    fname = malloc(strlen(dirname) + strlen(dent->d_name) + 2);
246
+		    sprintf(fname, "%s/%s", dirname, dent->d_name);
247
+
248
+		    /* stat the file */
249
+		    if(lstat(fname, &statbuf) != -1) {
250
+			if(S_ISDIR(statbuf.st_mode) && !S_ISLNK(statbuf.st_mode) && recursion) {
251
+			    if(scandirs(fname, engine, opt, limits, options, depth) == 1)
252
+				scanret++;
253
+			} else {
254
+			    if(S_ISREG(statbuf.st_mode))
255
+				scanret += scanfile(fname, engine, opt, limits, options);
256
+			}
257
+		    }
258
+		    free(fname);
259
+		}
260
+
261
+	    }
262
+	}
263
+    } else {
264
+	if(!printinfected)
265
+	    logg("~%s: Can't open directory.\n", dirname);
266
+	return 53;
267
+    }
268
+
269
+    closedir(dd);
270
+
271
+    if(scanret)
272
+	return 1;
273
+    else
274
+	return 0;
275
+
81 276
 }
82 277
 
83 278
 static int scanstdin(const struct cl_engine *engine, const struct cl_limits *limits, int options)
... ...
@@ -85,6 +276,7 @@ static int scanstdin(const struct cl_engine *engine, const struct cl_limits *lim
85 85
 	int ret;
86 86
 	const char *virname, *tmpdir;
87 87
 	char *file, buff[FILEBUFF];
88
+	size_t bread;
88 89
 	FILE *fs;
89 90
 
90 91
 
... ...
@@ -111,8 +303,8 @@ static int scanstdin(const struct cl_engine *engine, const struct cl_limits *lim
111 111
 	return 63;
112 112
     }
113 113
 
114
-    while((ret = fread(buff, 1, FILEBUFF, stdin)))
115
-	if(fwrite(buff, 1, ret, fs) < ret) {
114
+    while((bread = fread(buff, 1, FILEBUFF, stdin)))
115
+	if(fwrite(buff, 1, bread, fs) < bread) {
116 116
 	    logg("!Can't write to %s\n", file);
117 117
 	    free(file);
118 118
 	    return 58;
... ...
@@ -145,29 +337,13 @@ static int scanstdin(const struct cl_engine *engine, const struct cl_limits *lim
145 145
 int scanmanager(const struct optstruct *opt)
146 146
 {
147 147
 	mode_t fmode;
148
-	int ret = 0, extunpacker = 0, fmodeint, i, x;
148
+	int ret = 0, fmodeint, i, x;
149 149
 	unsigned int options = 0, dboptions = 0;
150 150
 	struct cl_engine *engine = NULL;
151 151
 	struct cl_limits limits;
152
-	struct passwd *user = NULL;
153 152
 	struct stat sb;
154
-	char *fullpath = NULL, cwd[1024];
155
-
153
+	char *file, cwd[1024];
156 154
 
157
-    if(opt_check(opt, "unzip") || opt_check(opt, "unrar") || opt_check(opt, "arj") ||
158
-       opt_check(opt, "unzoo") || opt_check(opt, "jar") || opt_check(opt, "lha") ||
159
-       opt_check(opt, "tar") || opt_check(opt, "tgz") || opt_check(opt, "deb"))
160
-	    extunpacker = 1;
161
-
162
-/* njh@bandsman.co.uk: BeOS */
163
-#if !defined(C_CYGWIN) && !defined(C_OS2) && !defined(C_BEOS) && !defined(C_WINDOWS)
164
-    if(extunpacker && !geteuid()) {
165
-	if((user = getpwnam(CLAMAVUSER)) == NULL) {
166
-	    logg("!Can't get information about user "CLAMAVUSER" (required to run external unpackers)\n");
167
-	    exit(60); /* this is critical problem, so we just exit here */
168
-	}
169
-    }
170
-#endif
171 155
 
172 156
     if(!opt_check(opt, "no-phishing-sigs"))
173 157
 	dboptions |= CL_DB_PHISHING;
... ...
@@ -360,66 +536,43 @@ int scanmanager(const struct optstruct *opt)
360 360
 	    logg("!Can't get absolute pathname of current working directory\n");
361 361
 	    ret = 57;
362 362
 	} else
363
-	    ret = scandirs(cwd, engine, user, opt, &limits, options);
363
+	    ret = scandirs(cwd, engine, opt, &limits, options, 1);
364 364
 
365 365
     } else if(!strcmp(opt->filename, "-")) { /* read data from stdin */
366 366
 	ret = scanstdin(engine, &limits, options);
367 367
 
368 368
     } else {
369
-	char *thefilename;
370
-	for (x = 0; (thefilename = cli_strtok(opt->filename, x, "\t")) != NULL; x++) {
371
-	    if((fmodeint = fileinfo(thefilename, 2)) == -1) {
372
-		logg("^Can't access file %s\n", thefilename);
373
-		perror(thefilename);
369
+	for (x = 0; (file = cli_strtok(opt->filename, x, "\t")) != NULL; x++) {
370
+	    if((fmodeint = fileinfo(file, 2)) == -1) {
371
+		logg("^Can't access file %s\n", file);
372
+		perror(file);
374 373
 		ret = 56;
375 374
 	    } else {
376 375
 		int slash = 1;
377
-		for(i = strlen(thefilename) - 1; i > 0 && slash; i--) {
378
-		    if(thefilename[i] == '/')
379
-			thefilename[i] = 0;
376
+		for(i = strlen(file) - 1; i > 0 && slash; i--) {
377
+		    if(file[i] == '/')
378
+			file[i] = 0;
380 379
 		    else
381 380
 			slash = 0;
382 381
 		}
383 382
 
384 383
 		fmode = (mode_t) fmodeint;
385 384
 
386
-		if(extunpacker && (thefilename[0] != '/' && thefilename[0] != '\\' && thefilename[1] != ':')) {
387
-		    /* we need to complete the path */
388
-		    if(!getcwd(cwd, sizeof(cwd))) {
389
-			logg("!Can't get absolute pathname of current working directory\n");
390
-			return 57;
391
-		    } else {
392
-			fullpath = malloc(512);
393
-#ifdef NO_SNPRINTF
394
-			sprintf(fullpath, "%s/%s", cwd, thefilename);
395
-#else
396
-			snprintf(fullpath, 512, "%s/%s", cwd, thefilename);
397
-#endif
398
-			logg("*Full path: %s\n", fullpath);
399
-		    }
400
-		} else
401
-		    fullpath = thefilename;
402
-
403 385
 		switch(fmode & S_IFMT) {
404 386
 		    case S_IFREG:
405
-			ret = scanfile(fullpath, engine, user, opt, &limits, options);
387
+			ret = scanfile(file, engine, opt, &limits, options);
406 388
 			break;
407 389
 
408 390
 		    case S_IFDIR:
409
-			ret = scandirs(fullpath, engine, user, opt, &limits, options);
391
+			ret = scandirs(file, engine, opt, &limits, options, 1);
410 392
 			break;
411 393
 
412 394
 		    default:
413
-			logg("!Not supported file type (%s)\n", thefilename);
395
+			logg("!Not supported file type (%s)\n", file);
414 396
 			ret = 52;
415 397
 		}
416
-
417
-		if(extunpacker && (thefilename[0] != '/' && thefilename[0] != '\\' && thefilename[1] != ':')) {
418
-		    free(fullpath);
419
-		    fullpath = NULL;
420
-		}
421 398
 	    }
422
-	    free(thefilename);
399
+	    free(file);
423 400
 	}
424 401
     }
425 402
 
... ...
@@ -435,133 +588,6 @@ int scanmanager(const struct optstruct *opt)
435 435
     return ret;
436 436
 }
437 437
 
438
-/*
439
- * -1 -> can't fork
440
- * -2 -> can't execute
441
- * -3 -> external signal
442
- * 0 -> OK
443
- */
444
-
445
-#ifdef C_WINDOWS
446
-static int clamav_unpack(const char *prog, const char **args, const char *tmpdir, const struct passwd *user, const struct optstruct *opt)
447
-{
448
-    /* TODO: use spamvp(P_WAIT, prog, args); */
449
-    cli_errmsg("clamav_unpack is not supported under Windows yet\n");
450
-    return -1;
451
-}
452
-#else
453
-static int clamav_unpack(const char *prog, const char **args, const char *tmpdir, const struct passwd *user, const struct optstruct *opt)
454
-{
455
-	pid_t pid;
456
-	int status, wret, fdevnull;
457
-	unsigned int maxfiles, maxscansize;
458
-	struct s_du n;
459
-
460
-
461
-    if(opt_check(opt, "max-files"))
462
-	maxfiles = atoi(opt_arg(opt, "max-files"));
463
-    else
464
-	maxfiles = 10000;
465
-
466
-    if(opt_check(opt, "max-scansize")) {
467
-	    char *cpy, *ptr;
468
-	ptr = opt_arg(opt, "max-scansize");
469
-	if(tolower(ptr[strlen(ptr) - 1]) == 'm') { /* megabytes */
470
-	    cpy = calloc(strlen(ptr), 1);
471
-	    strncpy(cpy, ptr, strlen(ptr) - 1);
472
-	    cpy[strlen(ptr)-1]='\0';
473
-	    maxscansize = atoi(cpy) * 1024;
474
-	    free(cpy);
475
-	} else /* default - kilobytes */
476
-	    maxscansize = atoi(ptr);
477
-    } else
478
-	maxscansize = 104857600;
479
-
480
-    switch(pid = fork()) {
481
-	case -1:
482
-	    return -1;
483
-	case 0:
484
-#ifndef C_CYGWIN
485
-	    if(!geteuid() && user) {
486
-
487
-#ifdef HAVE_SETGROUPS
488
-		if(setgroups(1, &user->pw_gid)) {
489
-		    fprintf(stderr, "ERROR: setgroups() failed\n");
490
-		    exit(1);
491
-		}
492
-#endif
493
-
494
-		if(setgid(user->pw_gid)) {
495
-		    fprintf(stderr, "ERROR: setgid(%d) failed\n", (int) user->pw_gid);
496
-		    exit(1);
497
-		}
498
-
499
-		if(setuid(user->pw_uid)) {
500
-		    fprintf(stderr, "ERROR: setuid(%d) failed\n", (int) user->pw_uid);
501
-		    exit(1);
502
-		}
503
-	    }
504
-#endif
505
-	    if(chdir(tmpdir) == -1) {
506
-		fprintf(stderr, "ERROR: chdir(%s) failed\n", tmpdir);
507
-		exit(1);
508
-	    }
509
-
510
-	    if(printinfected) {
511
-  	        fdevnull = open("/dev/null", O_WRONLY);
512
-		if(fdevnull == -1) {
513
-		    logg("Non fatal error: cannot open /dev/null. Continuing with full output\n");
514
-		    printinfected = 0;
515
-		} else {
516
-		    dup2(fdevnull,1);
517
-		    dup2(fdevnull,2);
518
-		}
519
-	    }
520
-
521
-	    if(strchr(prog, '/')) /* we have full path */
522
-		execv(prog, args);
523
-	    else
524
-		execvp(prog, args);
525
-	    perror("execv(p)");
526
-	    abort();
527
-	    break;
528
-	default:
529
-
530
-	    if(maxscansize || maxfiles) {
531
-		while(!(wret = waitpid(pid, &status, WNOHANG))) {
532
-		    memset(&n, 0, sizeof(struct s_du));
533
-
534
-		    if(!du(tmpdir, &n))
535
-			if((maxfiles && n.files > maxfiles) || (maxscansize && n.space > maxscansize)) {
536
-			    logg("*n.files: %u, n.space: %lu\n", n.files, n.space);
537
-			    kill(pid, 9); /* stop it immediately */
538
-			}
539
-		}
540
-	    } else
541
-		waitpid(pid, &status, 0);
542
-
543
-
544
-	    if(WIFSIGNALED(status)) {
545
-		switch(WTERMSIG(status)) {
546
-
547
-		    case 9:
548
-			logg("\nUnpacker process %d stopped due to exceeded limits\n", pid);
549
-			return 0;
550
-		    case 6: /* abort */
551
-			logg("^Can't run %s\n", prog);
552
-			return -2;
553
-		    default:
554
-			logg("^\nUnpacker stopped with external signal %d\n", WTERMSIG(status));
555
-			return -3;
556
-		}
557
-	    } else if(WIFEXITED(status))
558
-		return 0;
559
-    }
560
-
561
-    return 0;
562
-}
563
-#endif
564
-
565 438
 static void move_infected(const char *filename, const struct optstruct *opt)
566 439
 {
567 440
 	char *movedir, *movefilename, numext[4 + 1];
... ...
@@ -669,474 +695,3 @@ static void move_infected(const char *filename, const struct optstruct *opt)
669 669
     free(movefilename);
670 670
 }
671 671
 
672
-static int checkfile(const char *filename, const struct cl_engine *engine, const struct cl_limits *limits, int options, short printclean)
673
-{
674
-	int fd, ret;
675
-	const char *virname;
676
-
677
-
678
-    logg("*Scanning %s\n", filename);
679
-
680
-    if((fd = open(filename, O_RDONLY|O_BINARY)) == -1) {
681
-	logg("^Can't open file %s\n", filename);
682
-	return 54;
683
-    }
684
-
685
-    if((ret = cl_scandesc(fd, &virname, &info.blocks, engine, limits, options)) == CL_VIRUS) {
686
-	logg("~%s: %s FOUND\n", filename, virname);
687
-	info.ifiles++;
688
-
689
-	if(bell)
690
-	    fprintf(stderr, "\007");
691
-
692
-    } else if(ret == CL_CLEAN) {
693
-	if(!printinfected && printclean)
694
-	    mprintf("~%s: OK\n", filename);
695
-    } else
696
-	if(!printinfected)
697
-	    logg("~%s: %s\n", filename, cl_strerror(ret));
698
-
699
-    close(fd);
700
-    return ret;
701
-}
702
-
703
-static int scancompressed(const char *filename, struct cl_engine *engine, const struct passwd *user, const struct optstruct *opt, const struct cl_limits *limits, int options)
704
-{
705
-	int ret = 0;
706
-	char *gendir, *userprg;
707
-	const char *tmpdir;
708
-	struct stat statbuf;
709
-
710
-
711
-    stat(filename, &statbuf);
712
-
713
-    if(!S_ISREG(statbuf.st_mode)) {
714
-	logg("^Suspect archive %s (not a regular file)\n", filename);
715
-	return 0; /* hmm ? */
716
-    }
717
-
718
-    /* check write access */
719
-
720
-    tmpdir = getenv("TMPDIR");
721
-
722
-    if(tmpdir == NULL)
723
-#ifdef P_tmpdir
724
-	tmpdir = P_tmpdir;
725
-#else
726
-	tmpdir = "/tmp";
727
-#endif
728
-
729
-    if(checkaccess(tmpdir, CLAMAVUSER, W_OK) != 1) {
730
-	logg("!Can't write to the temporary directory\n");
731
-	exit(64);
732
-    }
733
-
734
-    /* generate the temporary directory */
735
-
736
-    gendir = cli_gentemp(tmpdir);
737
-    if(mkdir(gendir, 0700)) {
738
-	logg("!Can't create the temporary directory %s\n", gendir);
739
-	exit(63); /* critical */
740
-    }
741
-
742
-#if !defined(C_OS2) && !defined(C_WINDOWS)
743
-    /* FIXME: do the correct native windows way */
744
-    if(user)
745
-	chown(gendir, user->pw_uid, user->pw_gid);
746
-#endif
747
-
748
-    /* unpack file  - as unprivileged user */
749
-    if(cli_strbcasestr(filename, ".zip")) {
750
-	const char *args[] = { "unzip", "-P", "clam", "-o", NULL, NULL };
751
-	/* Sun's SUNWspro C compiler doesn't allow direct initialisation
752
-	 * with a variable
753
-	 */
754
-	args[4] = filename;
755
-
756
-	if((userprg = opt_arg(opt, "unzip")))
757
-	    ret = clamav_unpack(userprg, args, gendir, user, opt);
758
-	else
759
-	    ret = clamav_unpack("unzip", args, gendir, user, opt);
760
-
761
-    } else if(cli_strbcasestr(filename, ".rar")) { 
762
-	const char *args[] = { "unrar", "x", "-p-", "-y", NULL, NULL };
763
-	args[4] = filename;
764
-	if((userprg = opt_arg(opt, "unrar")))
765
-	    ret = clamav_unpack(userprg, args, gendir, user, opt);
766
-	else
767
-	    ret = clamav_unpack("unrar", args, gendir, user, opt);
768
-
769
-    } else if(cli_strbcasestr(filename, ".arj")) { 
770
-        const char *args[] = { "arj", "x","-y", NULL, NULL };
771
-	args[3] = filename;
772
-        if((userprg = opt_arg(opt, "arj")))
773
-	    ret = clamav_unpack(userprg, args, gendir, user, opt);
774
-	else
775
-	    ret = clamav_unpack("arj", args, gendir, user, opt);
776
-
777
-    } else if(cli_strbcasestr(filename, ".zoo")) { 
778
-	const char *args[] = { "unzoo", "-x","-j","./", NULL, NULL };
779
-	args[4] = filename;
780
-	if((userprg = opt_arg(opt, "unzoo")))
781
-	    ret = clamav_unpack(userprg, args, gendir, user, opt);
782
-	else
783
-	    ret = clamav_unpack("unzoo", args, gendir, user, opt);
784
-
785
-    } else if(cli_strbcasestr(filename, ".jar")) { 
786
-	const char *args[] = { "unzip", "-P", "clam", "-o", NULL, NULL };
787
-	args[4] = filename;
788
-	if((userprg = opt_arg(opt, "jar")))
789
-	    ret = clamav_unpack(userprg, args, gendir, user, opt);
790
-	else
791
-	    ret = clamav_unpack("unzip", args, gendir, user, opt);
792
-
793
-    } else if(cli_strbcasestr(filename, ".lzh")) { 
794
-	const char *args[] = { "lha", "xf", NULL, NULL };
795
-	args[2] = filename;
796
-	if((userprg = opt_arg(opt, "lha")))
797
-	    ret = clamav_unpack(userprg, args, gendir, user, opt);
798
-	else
799
-	    ret = clamav_unpack("lha", args, gendir, user, opt);
800
-
801
-    } else if(cli_strbcasestr(filename, ".tar")) { 
802
-	const char *args[] = { "tar", "-xpvf", NULL, NULL };
803
-	args[2] = filename;
804
-	if((userprg = opt_arg(opt, "tar")))
805
-	    ret = clamav_unpack(userprg, args, gendir, user, opt);
806
-	else
807
-	    ret = clamav_unpack("tar", args, gendir, user, opt);
808
-
809
-    } else if(cli_strbcasestr(filename, ".deb")) { 
810
-	const char *args[] = { "ar", "x", NULL, NULL };
811
-	args[2] = filename;
812
-	if((userprg = opt_arg(opt, "deb")))
813
-	    ret = clamav_unpack(userprg, args, gendir, user, opt);
814
-	else
815
-	    ret = clamav_unpack("ar", args, gendir, user, opt);
816
-
817
-    } else if((cli_strbcasestr(filename, ".tar.gz") || cli_strbcasestr(filename, ".tgz"))) {
818
-	const char *args[] = { "tar", "-zxpvf", NULL, NULL };
819
-	args[2] = filename;
820
-	if((userprg = opt_arg(opt, "tgz")))
821
-	    ret = clamav_unpack(userprg, args, gendir, user, opt);
822
-	else
823
-	    ret = clamav_unpack("tar", args, gendir, user, opt);
824
-    }
825
-
826
-    /* fix permissions of extracted files */
827
-    fixperms(gendir);
828
-
829
-    if(!ret) { /* execute successful */
830
-	    short oldrec = recursion;
831
-
832
-	recursion = 1;
833
-	ret = treewalk(gendir, engine, user, opt, limits, options, 1);
834
-	recursion = oldrec;
835
-    }
836
-
837
-    /* remove the directory  - as clamav */
838
-    if(!opt_check(opt, "leave-temps"))
839
-	clamav_rmdirs(gendir);
840
-
841
-    /* free gendir - it's not necessary now */
842
-    free(gendir);
843
-
844
-    switch(ret) {
845
-	case -1:
846
-	    logg("!Can't fork()\n");
847
-	    exit(61); /* this is critical problem, so we just exit here */
848
-	case -2:
849
-	    logg("^Can't execute some unpacker. Check paths and permissions on the temporary directory\n");
850
-	    /* This is no longer a critical error (since 0.24). We scan
851
-	     * raw archive.
852
-	     */
853
-	    if((ret = checkfile(filename, engine, limits, 0, 0)) == CL_VIRUS) {
854
-		if(opt_check(opt, "remove")) {
855
-		    if(unlink(filename)) {
856
-			logg("^%s: Can't remove\n", filename);
857
-			info.notremoved++;
858
-		    } else {
859
-			logg("~%s: Removed\n", filename);
860
-		    }
861
-		} else if (opt_check(opt, "move") || opt_check(opt, "copy"))
862
-		    move_infected(filename, opt);
863
-	    }
864
-	    return ret;
865
-	case -3:
866
-	    return 0;
867
-	case 0:
868
-	    /* no viruses found in archive, we scan just in case a raw file
869
-	     */
870
-	    if((ret = checkfile(filename, engine, limits, 0, 1)) == CL_VIRUS) {
871
-		if(opt_check(opt, "remove")) {
872
-		    if(unlink(filename)) {
873
-			logg("^%s: Can't remove\n", filename);
874
-			info.notremoved++;
875
-		    } else {
876
-			logg("~%s: Removed\n", filename);
877
-		    }
878
-		} else if (opt_check(opt, "move") || opt_check(opt, "copy"))
879
-		    move_infected(filename, opt);
880
-	    }
881
-	    return ret;
882
-	case 1:
883
-	    logg("~%s: Infected.Archive FOUND\n", filename);
884
-
885
-	    if(bell)
886
-		fprintf(stderr, "\007");
887
-
888
-	    if(opt_check(opt, "remove")) {
889
-		if(unlink(filename)) {
890
-		    logg("^%s: Can't remove\n", filename);
891
-		    info.notremoved++;
892
-		} else {
893
-		    logg("~%s: Removed\n", filename);
894
-		}
895
-	    } else if (opt_check(opt, "move") || opt_check(opt, "copy"))
896
-		move_infected(filename, opt);
897
-
898
-	    return 1;
899
-	default:
900
-	    logg("^Strange value (%d) returned in scancompressed()\n", ret);
901
-	    return 0;
902
-    }
903
-}
904
-
905
-static int scandenied(const char *filename, struct cl_engine *engine, const struct passwd *user, const struct optstruct *opt, const struct cl_limits *limits, int options)
906
-{
907
-	char *gendir, *tmp_file;
908
-	const char *tmpdir, *pt;
909
-	struct stat statbuf;
910
-	int ret;
911
-
912
-    stat(filename, &statbuf);
913
-    if(!S_ISREG(statbuf.st_mode)) {
914
-	logg("^Suspect archive %s (not a regular file)\n", filename);
915
-	return 0;
916
-    }
917
-
918
-    /* check write access */
919
-
920
-    tmpdir = getenv("TMPDIR");
921
-
922
-    if(tmpdir == NULL)
923
-#ifdef P_tmpdir
924
-	tmpdir = P_tmpdir;
925
-#else
926
-	tmpdir = "/tmp";
927
-#endif
928
-
929
-
930
-    if(checkaccess(tmpdir, CLAMAVUSER, W_OK) != 1) {
931
-	logg("!Can't write to the temporary directory %s\n", tmpdir);
932
-	exit(64);
933
-    }
934
-
935
-    /* generate the temporary directory */
936
-    gendir = cli_gentemp(tmpdir);
937
-    if(mkdir(gendir, 0700)) {
938
-	logg("^Can't create the temporary directory %s\n", gendir);
939
-	exit(63); /* critical */
940
-    }
941
-
942
-    tmp_file = (char *) malloc(strlen(gendir) + strlen(filename) + 10);
943
-    pt = strrchr(filename, '/');
944
-    if(!pt)
945
-	pt = filename;
946
-    else
947
-	pt += 1;
948
-
949
-    sprintf(tmp_file, "%s/%s", gendir, pt);
950
-
951
-    if(filecopy(filename, tmp_file) == -1) {
952
-	logg("!I/O error\n");
953
-	perror("copyfile()");
954
-	exit(58);
955
-    }
956
-
957
-    fixperms(gendir);
958
-
959
-#if !defined(C_OS2) && !defined(C_WINDOWS)
960
-    if(user) {
961
-	chown(gendir, user->pw_uid, user->pw_gid);
962
-	chown(tmp_file, user->pw_uid, user->pw_gid);
963
-    }
964
-#endif
965
-
966
-    if((ret = treewalk(gendir, engine, user, opt, limits, options, 1)) == 1) {
967
-	logg("(Real infected archive: %s)\n", filename);
968
-
969
-	if(opt_check(opt, "remove")) {
970
-	    if(unlink(filename)) {
971
-		logg("^%s: Can't remove\n", filename);
972
-		info.notremoved++;
973
-	    } else {
974
-	        logg("~%s: Removed\n", filename);
975
-	    }
976
-	} else if (opt_check(opt, "move") || opt_check(opt, "copy"))
977
-	    move_infected(filename, opt);
978
-    }
979
-
980
-    /* remove the directory  - as clamav */
981
-    clamav_rmdirs(gendir);
982
-
983
-    free(gendir);
984
-    free(tmp_file);
985
-
986
-    return ret;
987
-}
988
-
989
-int scanfile(const char *filename, struct cl_engine *engine, const struct passwd *user, const struct optstruct *opt, const struct cl_limits *limits, unsigned int options)
990
-{
991
-	int ret = 0, included, printclean = 1;
992
-	const struct optnode *optnode;
993
-	char *argument;
994
-#ifdef C_LINUX
995
-	struct stat sb;
996
-
997
-    /* argh, don't scan /proc files */
998
-    if(procdev)
999
-	if(stat(filename, &sb) != -1)
1000
-	    if(sb.st_dev == procdev) {
1001
-		if(!printinfected)
1002
-		    logg("~%s: Excluded (/proc)\n", filename);
1003
-		return 0;
1004
-	    }
1005
-#endif    
1006
-
1007
-    if(opt_check(opt, "exclude")) {
1008
-	argument = opt_firstarg(opt, "exclude", &optnode);
1009
-	while(argument) {
1010
-	    if(match_regex(filename, argument) == 1) {
1011
-		if(!printinfected)
1012
-		    logg("~%s: Excluded\n", filename);
1013
-		return 0;
1014
-	    }
1015
-	    argument = opt_nextarg(&optnode, "exclude");
1016
-	}
1017
-    }
1018
-
1019
-   if(opt_check(opt, "include")) {
1020
-	included = 0;
1021
-	argument = opt_firstarg(opt, "include", &optnode);
1022
-	while(argument && !included) {
1023
-	    if(match_regex(filename, argument) == 1) {
1024
-		included = 1;
1025
-		break;
1026
-	    }
1027
-	    argument = opt_nextarg(&optnode, "include");
1028
-	}
1029
-
1030
-	if(!included) {
1031
-	    if(!printinfected)
1032
-		logg("~%s: Excluded\n", filename);
1033
-	    return 0;
1034
-	}
1035
-    }
1036
-
1037
-    if(fileinfo(filename, 1) == 0) {
1038
-	if(!printinfected)
1039
-	    logg("~%s: Empty file\n", filename);
1040
-	return 0;
1041
-    }
1042
-
1043
-#ifndef C_WINDOWS
1044
-    if(geteuid())
1045
-	if(checkaccess(filename, NULL, R_OK) != 1) {
1046
-	    if(!printinfected)
1047
-		logg("~%s: Access denied\n", filename);
1048
-	    return 0;
1049
-	}
1050
-#endif
1051
-
1052
-    info.files++;
1053
-
1054
-    /* 
1055
-     * check the extension  - this is a special case, normally we don't need to
1056
-     * do this (libclamav detects archive by its magic string), but here we
1057
-     * want to know the exit code from internal unpacker and try to use
1058
-     * external (if provided) when internal cannot extract data.
1059
-     */
1060
-
1061
-    if((cli_strbcasestr(filename, ".zip") || cli_strbcasestr(filename, ".rar")) && (options & CL_SCAN_ARCHIVE)) {
1062
-
1063
-#ifndef ENABLE_UNRAR
1064
-      if(cli_strbcasestr(filename, ".zip"))
1065
-#endif
1066
-	/* try to use internal archivers */
1067
-	if((ret = checkfile(filename, engine, limits, options, 1)) == CL_VIRUS) {
1068
-	    if(opt_check(opt, "remove")) {
1069
-		if(unlink(filename)) {
1070
-		    logg("^%s: Can't remove\n", filename);
1071
-		    info.notremoved++;
1072
-		} else {
1073
-		    logg("~%s: Removed\n", filename);
1074
-		}
1075
-	    } else if (opt_check(opt, "move") || opt_check(opt, "copy"))
1076
-		move_infected(filename, opt);
1077
-
1078
-	    return 1;
1079
-
1080
-	} else if(ret == CL_CLEAN) {
1081
-	    return 0;
1082
-	} else if(ret == 54) {
1083
-	    return ret;
1084
-	}
1085
-
1086
-	/* in other case try to continue with external archivers */
1087
-	options &= ~CL_SCAN_ARCHIVE; /* and disable decompression for the checkfile() below */
1088
-    }
1089
-
1090
-    if((cli_strbcasestr(filename, ".zip") && opt_check(opt, "unzip"))
1091
-    || (cli_strbcasestr(filename, ".rar") && opt_check(opt, "unrar"))
1092
-    || (cli_strbcasestr(filename, ".arj") && opt_check(opt, "arj"))
1093
-    || (cli_strbcasestr(filename, ".zoo") && opt_check(opt, "unzoo"))
1094
-    || (cli_strbcasestr(filename, ".jar") && opt_check(opt, "jar"))
1095
-    || (cli_strbcasestr(filename, ".lzh") && opt_check(opt, "lha"))
1096
-    || (cli_strbcasestr(filename, ".tar") && opt_check(opt, "tar"))
1097
-    || (cli_strbcasestr(filename, ".deb") && opt_check(opt, "deb"))
1098
-    || ((cli_strbcasestr(filename, ".tar.gz") || cli_strbcasestr(filename, ".tgz")) 
1099
-	 && (opt_check(opt, "tgz") || opt_check(opt, "deb"))) ) {
1100
-
1101
-	/* check permissions */
1102
-	switch(checkaccess(filename, CLAMAVUSER, R_OK)) {
1103
-	    case -1:
1104
-		logg("^Can't get information about user "CLAMAVUSER"\n");
1105
-		exit(60); /* this is a critical problem so we just exit here */
1106
-	    case -2:
1107
-		logg("^Can't fork\n");
1108
-		exit(61);
1109
-	    case 0: /* read access denied */
1110
-		if(geteuid()) {
1111
-		    if(!printinfected)
1112
-			logg("^%s: Access denied to archive\n", filename);
1113
-		} else {
1114
-
1115
-		    if(limits && limits->maxfilesize)
1116
-			if((unsigned int) fileinfo(filename, 1) / 1024 > limits->maxfilesize) {
1117
-			    if(!printinfected)
1118
-				logg("^%s: Archive too big\n", filename);
1119
-			    return 0;
1120
-			}
1121
-
1122
-		    return(scandenied(filename, engine, user, opt, limits, options));
1123
-		}
1124
-		return 0;
1125
-	    case 1:
1126
-		return(scancompressed(filename, engine, user, opt, limits, options));
1127
-	}
1128
-    }
1129
-
1130
-    if((ret = checkfile(filename, engine, limits, options, printclean)) == CL_VIRUS) {
1131
-	if(opt_check(opt, "remove")) {
1132
-	    if(unlink(filename)) {
1133
-		logg("^%s: Can't remove\n", filename);
1134
-		info.notremoved++;
1135
-	    } else {
1136
-		logg("~%s: Removed\n", filename);
1137
-	    }
1138
-	} else if (opt_check(opt, "move") || opt_check(opt, "copy"))
1139
-            move_infected(filename, opt);
1140
-    }
1141
-    return ret;
1142
-}
... ...
@@ -19,19 +19,8 @@
19 19
 #ifndef __MANAGER_H
20 20
 #define __MANAGER_H
21 21
 
22
-#if HAVE_CONFIG_H
23
-#include "clamav-config.h"
24
-#endif
25
-
26
-#ifdef HAVE_PWD_H
27
-#include <pwd.h>
28
-#endif
29
-
30
-#include "libclamav/clamav.h"
31 22
 #include "shared/options.h"
32 23
 
33 24
 int scanmanager(const struct optstruct *opt);
34 25
 
35
-int scanfile(const char *filename, struct cl_engine *engine, const struct passwd *user, const struct optstruct *opt, const struct cl_limits *limits, unsigned int options);
36
-
37 26
 #endif
... ...
@@ -131,7 +131,9 @@ int match_regex(const char *filename, const char *pattern)
131 131
 	regex_t reg;
132 132
 	int match, flags;
133 133
 	char fname[513];
134
+#if defined(C_CYGWIN) || defined(C_OS2) || defined(C_WINDOWS)
134 135
 	size_t len;
136
+#endif
135 137
 
136 138
 #if !defined(C_CYGWIN) && !defined(C_OS2) && !defined(C_WINDOWS)
137 139
 	flags = REG_EXTENDED;
138 140
deleted file mode 100644
... ...
@@ -1,295 +0,0 @@
1
-/*
2
- *  Copyright (C) 2002 - 2007 Tomasz Kojm <tkojm@clamav.net>
3
- *
4
- *  This program is free software; you can redistribute it and/or modify
5
- *  it under the terms of the GNU General Public License version 2 as
6
- *  published by the Free Software Foundation.
7
- *
8
- *  This program is distributed in the hope that it will be useful,
9
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
10
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
- *  GNU General Public License for more details.
12
- *
13
- *  You should have received a copy of the GNU General Public License
14
- *  along with this program; if not, write to the Free Software
15
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
16
- *  MA 02110-1301, USA.
17
- */
18
-
19
-#if HAVE_CONFIG_H
20
-#include "clamav-config.h"
21
-#endif
22
-
23
-#include <stdio.h>
24
-#include <stdlib.h>
25
-#include <string.h>
26
-#ifdef	HAVE_UNISTD_H
27
-#include <unistd.h>
28
-#endif
29
-#include <sys/stat.h>
30
-#include <sys/types.h>
31
-#ifndef C_WINDOWS
32
-#include <sys/wait.h>
33
-#endif
34
-#ifdef HAVE_PWD_H
35
-#include <pwd.h>
36
-#endif
37
-#ifdef HAVE_GRP_H
38
-#include <grp.h>
39
-#endif
40
-#ifndef C_WINDOWS
41
-#include <dirent.h>
42
-#endif
43
-#include <errno.h>
44
-
45
-#include "global.h"
46
-#include "manager.h"
47
-#include "others.h"
48
-#include "treewalk.h"
49
-
50
-#include "shared/options.h"
51
-#include "shared/output.h"
52
-#include "shared/misc.h"
53
-
54
-#include "libclamav/clamav.h"
55
-#include "libclamav/others.h"
56
-
57
-int treewalk(const char *dirname, struct cl_engine *engine, const struct passwd *user, const struct optstruct *opt, const struct cl_limits *limits, unsigned int options, unsigned int depth)
58
-{
59
-	DIR *dd;
60
-	struct dirent *dent;
61
-	struct stat statbuf;
62
-	char *fname;
63
-	int scanret = 0, included;
64
-	unsigned int maxdepth;
65
-	const struct optnode *optnode;
66
-	char *argument;
67
-
68
-
69
-    if(opt_check(opt, "exclude-dir")) {
70
-	argument = opt_firstarg(opt, "exclude-dir", &optnode);
71
-	while(argument) {
72
-	    if(match_regex(dirname, argument) == 1) {
73
-		if(!printinfected)
74
-		    logg("~%s: Excluded\n", dirname);
75
-		return 0;
76
-	    }
77
-	    argument = opt_nextarg(&optnode, "exclude-dir");
78
-	}
79
-    }
80
-
81
-   if(opt_check(opt, "include-dir")) {
82
-	included = 0;
83
-	argument = opt_firstarg(opt, "include-dir", &optnode);
84
-	while(argument && !included) {
85
-	    if(match_regex(dirname, argument) == 1) {
86
-		included = 1;
87
-		break;
88
-	    }
89
-	    argument = opt_nextarg(&optnode, "include-dir");
90
-	}
91
-
92
-	if(!included) {
93
-	    if(!printinfected)
94
-		logg("~%s: Excluded\n", dirname);
95
-	    return 0;
96
-	}
97
-    }
98
-
99
-    if(opt_check(opt, "max-dir-recursion"))
100
-        maxdepth = atoi(opt_arg(opt, "max-dir-recursion"));
101
-    else
102
-        maxdepth = 15;
103
-
104
-    if(depth > maxdepth)
105
-	return 0;
106
-
107
-    info.dirs++;
108
-    depth++;
109
-
110
-    if((dd = opendir(dirname)) != NULL) {
111
-	while((dent = readdir(dd))) {
112
-#if !defined(C_INTERIX) && !defined(C_WINDOWS) && !defined(C_CYGWIN)
113
-	    if(dent->d_ino)
114
-#endif
115
-	    {
116
-		if(strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..")) {
117
-		    /* build the full name */
118
-		    fname = malloc(strlen(dirname) + strlen(dent->d_name) + 2);
119
-		    sprintf(fname, "%s/%s", dirname, dent->d_name);
120
-
121
-		    /* stat the file */
122
-		    if(lstat(fname, &statbuf) != -1) {
123
-			if(S_ISDIR(statbuf.st_mode) && !S_ISLNK(statbuf.st_mode) && recursion) {
124
-			    if(treewalk(fname, engine, user, opt, limits, options, depth) == 1)
125
-				scanret++;
126
-			} else {
127
-			    if(S_ISREG(statbuf.st_mode))
128
-				scanret += scanfile(fname, engine, user, opt, limits, options);
129
-			}
130
-		    }
131
-		    free(fname);
132
-		}
133
-
134
-	    }
135
-	}
136
-    } else {
137
-	if(!printinfected)
138
-	    logg("~%s: Can't open directory.\n", dirname);
139
-	return 53;
140
-    }
141
-
142
-    closedir(dd);
143
-
144
-    if(scanret)
145
-	return 1;
146
-    else
147
-	return 0;
148
-
149
-}
150
-
151
-#ifdef C_WINDOWS
152
-int clamav_rmdirs(const char *dir)
153
-{
154
-    return cli_rmdirs(dir);
155
-}
156
-#else
157
-int clamav_rmdirs(const char *dir)
158
-{
159
-#ifndef C_CYGWIN
160
-	struct passwd *user;
161
-#endif
162
-	pid_t pid;
163
-	int status;
164
-
165
-
166
-    switch(pid = fork()) {
167
-	case -1:
168
-	    return -1;
169
-	case 0:
170
-#ifndef C_CYGWIN
171
-	    if(!geteuid()) { 
172
-		if((user = getpwnam(CLAMAVUSER)) == NULL)
173
-		    return -3;
174
-
175
-#ifdef HAVE_SETGROUPS
176
-		if(setgroups(1, &user->pw_gid)) {
177
-		    fprintf(stderr, "ERROR: setgroups() failed.\n");
178
-		    return -3;
179
-		}
180
-#endif
181
-
182
-		if(setgid(user->pw_gid)) {
183
-		    fprintf(stderr, "ERROR: setgid(%d) failed.\n", (int) user->pw_gid);
184
-		    return -3;
185
-		}
186
-
187
-		if(setuid(user->pw_uid)) {
188
-		    fprintf(stderr, "ERROR: setuid(%d) failed.\n", (int) user->pw_uid);
189
-		    return -3;
190
-		}
191
-	    }
192
-#endif
193
-	    cli_rmdirs(dir);
194
-	    exit(0);
195
-	    break;
196
-	default:
197
-	    waitpid(pid, &status, 0);
198
-	    if(WIFEXITED(status))
199
-		return 0;
200
-	    else
201
-		return -2;
202
-    }
203
-}
204
-#endif
205
-
206
-int fixperms(const char *dirname)
207
-{
208
-	DIR *dd;
209
-	struct dirent *dent;
210
-	struct stat statbuf;
211
-	char *fname;
212
-	int scanret = 0;
213
-
214
-    if((dd = opendir(dirname)) != NULL) {
215
-	while((dent = readdir(dd))) {
216
-#if !defined(C_INTERIX) && !defined(C_WINDOWS) && !defined(C_CYGWIN)
217
-	    if(dent->d_ino)
218
-#endif
219
-	    {
220
-		if(strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..")) {
221
-		    /* build full name */
222
-		    fname = malloc(strlen(dirname) + strlen(dent->d_name) + 2);
223
-		    sprintf(fname, "%s/%s", dirname, dent->d_name);
224
-
225
-		    /* stat the file */
226
-		    if(lstat(fname, &statbuf) != -1) {
227
-			if(S_ISDIR(statbuf.st_mode) && !S_ISLNK(statbuf.st_mode)) {
228
-			    chmod(fname, 0700);
229
-			    fixperms(fname);
230
-			} else if(S_ISREG(statbuf.st_mode))
231
-			    chmod(fname, 0700);
232
-		    }
233
-
234
-		    free(fname);
235
-		}
236
-	    }
237
-	}
238
-    } else {
239
-	if(!printinfected)
240
-	    logg("~%s: Can't open directory.\n", dirname);
241
-	return 53;
242
-    }
243
-
244
-    closedir(dd);
245
-
246
-    if(scanret)
247
-	return 1;
248
-    else
249
-	return 0;
250
-
251
-}
252
-
253
-int du(const char *dirname, struct s_du *n)
254
-{
255
-	DIR *dd;
256
-	struct dirent *dent;
257
-	struct stat statbuf;
258
-	char *fname;
259
-
260
-    if((dd = opendir(dirname)) != NULL) {
261
-	while((dent = readdir(dd))) {
262
-#if !defined(C_INTERIX) && !defined(C_WINDOWS) && !defined(C_CYGWIN)
263
-	    if(dent->d_ino)
264
-#endif
265
-	    {
266
-		if(strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..")) {
267
-		    n->files++;
268
-
269
-		    /* build the full name */
270
-		    fname = malloc(strlen(dirname) + strlen(dent->d_name) + 2);
271
-		    sprintf(fname, "%s/%s", dirname, dent->d_name);
272
-
273
-		    /* stat the file */
274
-		    if(lstat(fname, &statbuf) != -1) {
275
-			if(S_ISDIR(statbuf.st_mode) && !S_ISLNK(statbuf.st_mode)) {
276
-			    du(fname, n);
277
-			} else {
278
-			    n->space += statbuf.st_size / 1024;
279
-			}
280
-		    }
281
-
282
-		    free(fname);
283
-		}
284
-	    }
285
-	}
286
-    } else {
287
-	if(!printinfected)
288
-	    logg("~%s: Can't open directory.\n", dirname);
289
-	return 53;
290
-    }
291
-
292
-    closedir(dd);
293
-
294
-    return 0;
295
-}
296 1
deleted file mode 100644
... ...
@@ -1,44 +0,0 @@
1
-/*
2
- *  Copyright (C) 2002, 2003 Tomasz Kojm <tkojm@clamav.net>
3
- *
4
- *  This program is free software; you can redistribute it and/or modify
5
- *  it under the terms of the GNU General Public License version 2 as
6
- *  published by the Free Software Foundation.
7
- *
8
- *  This program is distributed in the hope that it will be useful,
9
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
10
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
- *  GNU General Public License for more details.
12
- *
13
- *  You should have received a copy of the GNU General Public License
14
- *  along with this program; if not, write to the Free Software
15
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
16
- *  MA 02110-1301, USA.
17
- */
18
-
19
-#ifndef __TREEWALK_H
20
-#define __TREEWALK_H
21
-
22
-#if HAVE_CONFIG_H
23
-#include "clamav-config.h"
24
-#endif
25
-
26
-#ifdef HAVE_PWD_H
27
-#include <pwd.h>
28
-#endif
29
-
30
-#include "libclamav/clamav.h"
31
-#include "shared/options.h"
32
-
33
-struct s_du {
34
-    unsigned int files;
35
-    unsigned long int space; /* in kilobytes */
36
-};
37
-
38
-int treewalk(const char *dirname, struct cl_engine *engine, const struct passwd *user, const struct optstruct *opt, const struct cl_limits *limits, unsigned int options, unsigned int depth);
39
-
40
-int clamav_rmdirs(const char *dir);
41
-int fixperms(const char *dirname);
42
-int du(const char *dirname, struct s_du *n);
43
-
44
-#endif
... ...
@@ -146,33 +146,6 @@ Set archive recursion level limit. This option protects your system against DoS
146 146
 .TP 
147 147
 \fB\-\-max\-dir\-recursion=#n\fR
148 148
 Maximum depth directories are scanned at (default: 15).
149
-.TP 
150
-\fB\-\-unzip[=FULLPATH]\fR
151
-In most cases you don't need this option \- the built\-in unarchiver will extract Zip archives. However, this option may be used as a backup for internal unpacker \- see the full documentation for more information. When enabled without an argument, unzip program will be searched in $PATH. If unzip cannot be found in $PATH, you must force it with =pathname. Remember about '=' between the option and the argument.
152
-.TP 
153
-\fB\-\-unrar[=FULLPATH]\fR
154
-Scan .rar files. In most cases the unpacker built into libclamav is enough.
155
-.TP 
156
-\fB\-\-arj[=FULLPATH]\fR
157
-Scan .arj files.
158
-.TP 
159
-\fB\-\-unzoo[=FULLPATH]\fR
160
-Scan .zoo files.
161
-.TP 
162
-\fB\-\-lha[=FULLPATH]\fR
163
-Scan .lzh files.
164
-.TP 
165
-\fB\-\-jar[=FULLPATH]\fR
166
-clamscan uses unzip for .jar files, so in some cases you may need to pass a full path to unzip. In most cases the unpacker built into libclamav is enough.
167
-.TP 
168
-\fB\-\-deb[=FULLPATH]\fR
169
-This option supports debian binary packages. Implies \-\-tgz, but doesn't conflict with \-\-tgz=FULLPATH. It requires ar utility.
170
-.TP 
171
-\fB\-\-tar[=FULLPATH]\fR
172
-This option supports non\-compressed tar archives. In most cases the unpacker built into libclamav is enough.
173
-.TP 
174
-\fB\-\-tgz[=FULLPATH]\fR
175
-This option supports tar.gz and .tgz files. You need GNU tar, on non\-Linux system you probably have it installed as gtar. If it's in $PATH, please use \-\-tgz=gtar in other case please pass a full path. In most cases the unpacker built into libclamav is enough.
176 149
 .SH "EXAMPLES"
177 150
 .LP 
178 151
 .TP 
... ...
@@ -225,12 +198,6 @@ Note: some return codes may only appear in a single file mode (when clamscan is
225 225
 .TP 
226 226
 58: I/O error, please check your file system.
227 227
 .TP 
228
-59: Can't get information about current user from /etc/passwd.
229
-.TP 
230
-60: Can't get information about user '@CLAMAVUSER@' from /etc/passwd.
231
-.TP 
232
-61: Can't fork.
233
-.TP 
234 228
 62: Can't initialize logger.
235 229
 .TP 
236 230
 63: Can't create temporary files/directories (check permissions).