git-svn: trunk@3888
Tomasz Kojm authored on 2008/06/11 01:59:19... | ... |
@@ -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). |