git-svn: trunk@2821
Tomasz Kojm authored on 2007/02/21 06:19:04... | ... |
@@ -1,3 +1,7 @@ |
1 |
+Tue Feb 20 20:19:04 CET 2007 (tk) |
|
2 |
+--------------------------------- |
|
3 |
+ * clamd: merge multiscan() with dirscan() (also closes bb#302) |
|
4 |
+ |
|
1 | 5 |
Tue Feb 20 16:43:27 CET 2007 (tk) |
2 | 6 |
--------------------------------- |
3 | 7 |
* libclamav/others.c: increase f-level to activate RTF extractor |
... | ... |
@@ -1,5 +1,5 @@ |
1 | 1 |
/* |
2 |
- * Copyright (C) 2002 - 2005 Tomasz Kojm <tkojm@clamav.net> |
|
2 |
+ * Copyright (C) 2002 - 2007 Tomasz Kojm <tkojm@clamav.net> |
|
3 | 3 |
* |
4 | 4 |
* This program is free software; you can redistribute it and/or modify |
5 | 5 |
* it under the terms of the GNU General Public License as published by |
... | ... |
@@ -63,16 +63,28 @@ |
63 | 63 |
#include "scanner.h" |
64 | 64 |
#include "shared.h" |
65 | 65 |
#include "network.h" |
66 |
+#include "thrmgr.h" |
|
66 | 67 |
|
67 | 68 |
#ifdef C_LINUX |
68 | 69 |
dev_t procdev; /* /proc device */ |
69 | 70 |
#endif |
70 | 71 |
|
72 |
+extern int progexit; |
|
73 |
+ |
|
71 | 74 |
#ifndef C_WINDOWS |
72 | 75 |
#define closesocket(s) close(s) |
73 | 76 |
#endif |
74 | 77 |
|
75 |
-int checksymlink(const char *path) |
|
78 |
+struct multi_tag { |
|
79 |
+ int sd; |
|
80 |
+ unsigned int options; |
|
81 |
+ const struct cfgstruct *copt; |
|
82 |
+ char *fname; |
|
83 |
+ const struct cl_engine *engine; |
|
84 |
+ const struct cl_limits *limits; |
|
85 |
+}; |
|
86 |
+ |
|
87 |
+static int checksymlink(const char *path) |
|
76 | 88 |
{ |
77 | 89 |
struct stat statbuf; |
78 | 90 |
|
... | ... |
@@ -88,8 +100,7 @@ int checksymlink(const char *path) |
88 | 88 |
return 0; |
89 | 89 |
} |
90 | 90 |
|
91 |
-/* :set nowrap, if you don't like this style ;)) */ |
|
92 |
-int dirscan(const char *dirname, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, const struct cl_limits *limits, unsigned int options, const struct cfgstruct *copt, int odesc, unsigned int *reclev, short contscan) |
|
91 |
+static int dirscan(const char *dirname, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, const struct cl_limits *limits, unsigned int options, const struct cfgstruct *copt, int odesc, unsigned int *reclev, unsigned int type, threadpool_t *multi_pool) |
|
93 | 92 |
{ |
94 | 93 |
DIR *dd; |
95 | 94 |
struct dirent *dent; |
... | ... |
@@ -103,6 +114,7 @@ int dirscan(const char *dirname, const char **virname, unsigned long int *scanne |
103 | 103 |
char *fname; |
104 | 104 |
int ret = 0, scanret = 0; |
105 | 105 |
unsigned int maxdirrec = 0; |
106 |
+ struct multi_tag *scandata; |
|
106 | 107 |
|
107 | 108 |
|
108 | 109 |
maxdirrec = cfgopt(copt, "MaxDirectoryRecursion")->numarg; |
... | ... |
@@ -127,6 +139,12 @@ int dirscan(const char *dirname, const char **virname, unsigned long int *scanne |
127 | 127 |
closedir(dd); |
128 | 128 |
return 1; |
129 | 129 |
} |
130 |
+ |
|
131 |
+ if(progexit) { |
|
132 |
+ closedir(dd); |
|
133 |
+ return 1; |
|
134 |
+ } |
|
135 |
+ |
|
130 | 136 |
#if (!defined(C_INTERIX)) && (!defined(C_WINDOWS)) && (!defined(C_CYGWIN)) |
131 | 137 |
if(dent->d_ino) |
132 | 138 |
#endif |
... | ... |
@@ -134,55 +152,98 @@ int dirscan(const char *dirname, const char **virname, unsigned long int *scanne |
134 | 134 |
if(strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..")) { |
135 | 135 |
/* build the full name */ |
136 | 136 |
fname = (char *) mcalloc(strlen(dirname) + strlen(dent->d_name) + 2, sizeof(char)); |
137 |
+ if(!fname) { |
|
138 |
+ logg("!Can't allocate memory for fname\n"); |
|
139 |
+ closedir(dd); |
|
140 |
+ return -2; |
|
141 |
+ } |
|
137 | 142 |
sprintf(fname, "%s/%s", dirname, dent->d_name); |
138 | 143 |
|
139 | 144 |
/* stat the file */ |
140 | 145 |
if(lstat(fname, &statbuf) != -1) { |
141 | 146 |
if((S_ISDIR(statbuf.st_mode) && !S_ISLNK(statbuf.st_mode)) || (S_ISLNK(statbuf.st_mode) && (checksymlink(fname) == 1) && cfgopt(copt, "FollowDirectorySymlinks")->enabled)) { |
142 |
- if(dirscan(fname, virname, scanned, engine, limits, options, copt, odesc, reclev, contscan) == 1) { |
|
147 |
+ if(dirscan(fname, virname, scanned, engine, limits, options, copt, odesc, reclev, type, multi_pool) == 1) { |
|
143 | 148 |
free(fname); |
144 | 149 |
closedir(dd); |
145 | 150 |
return 1; |
146 | 151 |
} |
152 |
+ free(fname); |
|
147 | 153 |
} else { |
148 | 154 |
if(S_ISREG(statbuf.st_mode) || (S_ISLNK(statbuf.st_mode) && (checksymlink(fname) == 2) && cfgopt(copt, "FollowFileSymlinks")->enabled)) { |
149 | 155 |
|
150 | 156 |
#ifdef C_LINUX |
151 | 157 |
if(procdev && (statbuf.st_dev == procdev)) |
152 |
- scanret = CL_CLEAN; |
|
158 |
+ free(fname); |
|
153 | 159 |
else |
154 | 160 |
#endif |
155 |
- scanret = cl_scanfile(fname, virname, scanned, engine, limits, options); |
|
156 |
- |
|
157 |
- if(scanret == CL_VIRUS) { |
|
161 |
+ { |
|
162 |
+ if(type == TYPE_MULTISCAN) { |
|
163 |
+ |
|
164 |
+ scandata = (struct multi_tag *) mmalloc(sizeof(struct multi_tag)); |
|
165 |
+ if(!scandata) { |
|
166 |
+ logg("!Can't allocate memory for scandata\n"); |
|
167 |
+ free(fname); |
|
168 |
+ closedir(dd); |
|
169 |
+ return -2; |
|
170 |
+ } |
|
171 |
+ scandata->sd = odesc; |
|
172 |
+ scandata->options = options; |
|
173 |
+ scandata->copt = copt; |
|
174 |
+ scandata->fname = fname; |
|
175 |
+ scandata->engine = engine; |
|
176 |
+ scandata->limits = limits; |
|
177 |
+ if(!thrmgr_dispatch(multi_pool, scandata)) { |
|
178 |
+ logg("!thread dispatch failed for multi_pool (file %s)\n", fname); |
|
179 |
+ mdprintf(odesc, "ERROR: Can't scan file %s\n", fname); |
|
180 |
+ free(fname); |
|
181 |
+ free(scandata); |
|
182 |
+ closedir(dd); |
|
183 |
+ return 1; |
|
184 |
+ } |
|
185 |
+ |
|
186 |
+ while(!multi_pool->thr_idle) /* non-critical */ |
|
187 |
+#ifdef C_WINDOWS |
|
188 |
+ Sleep(1); |
|
189 |
+#else |
|
190 |
+ usleep(200); |
|
191 |
+#endif |
|
158 | 192 |
|
159 |
- mdprintf(odesc, "%s: %s FOUND\n", fname, *virname); |
|
160 |
- logg("%s: %s FOUND\n", fname, *virname); |
|
161 |
- virusaction(fname, *virname, copt); |
|
162 |
- if(!contscan) { |
|
163 |
- closedir(dd); |
|
193 |
+ } else { /* CONTSCAN, SCAN */ |
|
194 |
+ |
|
195 |
+ scanret = cl_scanfile(fname, virname, scanned, engine, limits, options); |
|
196 |
+ |
|
197 |
+ if(scanret == CL_VIRUS) { |
|
198 |
+ |
|
199 |
+ mdprintf(odesc, "%s: %s FOUND\n", fname, *virname); |
|
200 |
+ logg("%s: %s FOUND\n", fname, *virname); |
|
201 |
+ virusaction(fname, *virname, copt); |
|
202 |
+ if(type == TYPE_SCAN) { |
|
203 |
+ closedir(dd); |
|
204 |
+ free(fname); |
|
205 |
+ return 1; |
|
206 |
+ } else /* CONTSCAN */ |
|
207 |
+ ret = 2; |
|
208 |
+ |
|
209 |
+ } else if(scanret != CL_CLEAN) { |
|
210 |
+ mdprintf(odesc, "%s: %s ERROR\n", fname, cl_strerror(scanret)); |
|
211 |
+ logg("%s: %s ERROR\n", fname, cl_strerror(scanret)); |
|
212 |
+ if(scanret == CL_EMEM) { |
|
213 |
+ closedir(dd); |
|
214 |
+ free(fname); |
|
215 |
+ return -2; |
|
216 |
+ } |
|
217 |
+ |
|
218 |
+ } else if(logok) { |
|
219 |
+ logg("%s: OK\n", fname); |
|
220 |
+ } |
|
164 | 221 |
free(fname); |
165 |
- return 1; |
|
166 |
- } else |
|
167 |
- ret = 2; |
|
168 |
- |
|
169 |
- } else if(scanret != CL_CLEAN) { |
|
170 |
- mdprintf(odesc, "%s: %s ERROR\n", fname, cl_strerror(scanret)); |
|
171 |
- logg("%s: %s ERROR\n", fname, cl_strerror(scanret)); |
|
172 |
- if(scanret == CL_EMEM) { |
|
173 |
- closedir(dd); |
|
174 |
- free(fname); |
|
175 |
- return -2; |
|
176 | 222 |
} |
177 |
- |
|
178 |
- } else if(logok) { |
|
179 |
- logg("%s: OK\n", fname); |
|
180 | 223 |
} |
181 | 224 |
} |
182 | 225 |
} |
226 |
+ } else { |
|
227 |
+ free(fname); |
|
183 | 228 |
} |
184 |
- |
|
185 |
- free(fname); |
|
186 | 229 |
} |
187 | 230 |
} |
188 | 231 |
} |
... | ... |
@@ -193,15 +254,49 @@ int dirscan(const char *dirname, const char **virname, unsigned long int *scanne |
193 | 193 |
|
194 | 194 |
(*reclev)--; |
195 | 195 |
return ret; |
196 |
+} |
|
197 |
+ |
|
198 |
+static void multiscanfile(void *arg) |
|
199 |
+{ |
|
200 |
+ struct multi_tag *tag = (struct multi_tag *) arg; |
|
201 |
+ const char *virname; |
|
202 |
+#ifndef C_WINDOWS |
|
203 |
+ sigset_t sigset; |
|
204 |
+#endif |
|
205 |
+ int ret; |
|
196 | 206 |
|
207 |
+ |
|
208 |
+#ifndef C_WINDOWS |
|
209 |
+ /* ignore all signals */ |
|
210 |
+ sigfillset(&sigset); |
|
211 |
+ pthread_sigmask(SIG_SETMASK, &sigset, NULL); |
|
212 |
+#endif |
|
213 |
+ |
|
214 |
+ ret = cl_scanfile(tag->fname, &virname, NULL, tag->engine, tag->limits, tag->options); |
|
215 |
+ |
|
216 |
+ if(ret == CL_VIRUS) { |
|
217 |
+ mdprintf(tag->sd, "%s: %s FOUND\n", tag->fname, virname); |
|
218 |
+ logg("%s: %s FOUND\n", tag->fname, virname); |
|
219 |
+ virusaction(tag->fname, virname, tag->copt); |
|
220 |
+ } else if(ret != CL_CLEAN) { |
|
221 |
+ mdprintf(tag->sd, "%s: %s ERROR\n", tag->fname, cl_strerror(ret)); |
|
222 |
+ logg("%s: %s ERROR\n", tag->fname, cl_strerror(ret)); |
|
223 |
+ } else if(logok) { |
|
224 |
+ logg("%s: OK\n", tag->fname); |
|
225 |
+ } |
|
226 |
+ |
|
227 |
+ free(tag->fname); |
|
228 |
+ free(tag); |
|
229 |
+ return; |
|
197 | 230 |
} |
198 | 231 |
|
199 |
-int scan(const char *filename, unsigned long int *scanned, const struct cl_engine *engine, const struct cl_limits *limits, unsigned int options, const struct cfgstruct *copt, int odesc, short contscan) |
|
232 |
+int scan(const char *filename, unsigned long int *scanned, const struct cl_engine *engine, const struct cl_limits *limits, unsigned int options, const struct cfgstruct *copt, int odesc, unsigned int type) |
|
200 | 233 |
{ |
201 | 234 |
struct stat sb; |
202 | 235 |
int ret = 0; |
203 | 236 |
unsigned int reclev = 0; |
204 | 237 |
const char *virname; |
238 |
+ threadpool_t *multi_pool = NULL; |
|
205 | 239 |
|
206 | 240 |
|
207 | 241 |
/* stat file */ |
... | ... |
@@ -249,7 +344,22 @@ int scan(const char *filename, unsigned long int *scanned, const struct cl_engin |
249 | 249 |
} |
250 | 250 |
break; |
251 | 251 |
case S_IFDIR: |
252 |
- ret = dirscan(filename, &virname, scanned, engine, limits, options, copt, odesc, &reclev, contscan); |
|
252 |
+ if(type == TYPE_MULTISCAN) { |
|
253 |
+ int idletimeout = cfgopt(copt, "IdleTimeout")->numarg; |
|
254 |
+ int max_threads = cfgopt(copt, "MaxThreads")->numarg; |
|
255 |
+ |
|
256 |
+ if((multi_pool = thrmgr_new(max_threads, idletimeout, multiscanfile)) == NULL) { |
|
257 |
+ logg("!thrmgr_new failed for multi_pool\n"); |
|
258 |
+ mdprintf(odesc, "thrmgr_new failed for multi_pool ERROR\n"); |
|
259 |
+ return -1; |
|
260 |
+ } |
|
261 |
+ } |
|
262 |
+ |
|
263 |
+ ret = dirscan(filename, &virname, scanned, engine, limits, options, copt, odesc, &reclev, type, multi_pool); |
|
264 |
+ |
|
265 |
+ if(multi_pool) |
|
266 |
+ thrmgr_destroy(multi_pool); |
|
267 |
+ |
|
253 | 268 |
break; |
254 | 269 |
default: |
255 | 270 |
mdprintf(odesc, "%s: Not supported file type. ERROR\n", filename); |
... | ... |
@@ -1,5 +1,5 @@ |
1 | 1 |
/* |
2 |
- * Copyright (C) 2002 Tomasz Kojm <tkojm@clamav.net> |
|
2 |
+ * Copyright (C) 2002 - 2007 Tomasz Kojm <tkojm@clamav.net> |
|
3 | 3 |
* |
4 | 4 |
* This program is free software; you can redistribute it and/or modify |
5 | 5 |
* it under the terms of the GNU General Public License as published by |
... | ... |
@@ -20,17 +20,17 @@ |
20 | 20 |
#ifndef __SCANNER_H |
21 | 21 |
#define __SCANNER_H |
22 | 22 |
|
23 |
+#define TYPE_SCAN 0 |
|
24 |
+#define TYPE_CONTSCAN 1 |
|
25 |
+#define TYPE_MULTISCAN 2 |
|
26 |
+ |
|
23 | 27 |
#include "libclamav/clamav.h" |
24 | 28 |
#include "shared/cfgparser.h" |
25 | 29 |
|
26 |
-int dirscan(const char *dirname, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, const struct cl_limits *limits, unsigned int options, const struct cfgstruct *copt, int odesc, unsigned int *reclev, short contscan); |
|
27 |
- |
|
28 |
-int scan(const char *filename, unsigned long int *scanned, const struct cl_engine *engine, const struct cl_limits *limits, unsigned int options, const struct cfgstruct *copt, int odesc, short contscan); |
|
30 |
+int scan(const char *filename, unsigned long int *scanned, const struct cl_engine *engine, const struct cl_limits *limits, unsigned int options, const struct cfgstruct *copt, int odesc, unsigned int type); |
|
29 | 31 |
|
30 | 32 |
int scanfd(const int fd, unsigned long int *scanned, const struct cl_engine *engine, const struct cl_limits *limits, unsigned int options, const struct cfgstruct *copt, int odesc); |
31 | 33 |
|
32 | 34 |
int scanstream(int odesc, unsigned long int *scanned, const struct cl_engine *engine, const struct cl_limits *limits, unsigned int options, const struct cfgstruct *copt); |
33 | 35 |
|
34 |
-int checksymlink(const char *path); |
|
35 |
- |
|
36 | 36 |
#endif |
... | ... |
@@ -1,5 +1,5 @@ |
1 | 1 |
/* |
2 |
- * Copyright (C) 2002 - 2005 Tomasz Kojm <tkojm@clamav.net> |
|
2 |
+ * Copyright (C) 2002 - 2007 Tomasz Kojm <tkojm@clamav.net> |
|
3 | 3 |
* |
4 | 4 |
* This program is free software; you can redistribute it and/or modify |
5 | 5 |
* it under the terms of the GNU General Public License as published by |
... | ... |
@@ -54,179 +54,9 @@ |
54 | 54 |
#include "others.h" |
55 | 55 |
#include "scanner.h" |
56 | 56 |
#include "server.h" |
57 |
-#include "clamuko.h" |
|
58 | 57 |
#include "session.h" |
59 |
-#include "thrmgr.h" |
|
60 |
-#include "shared.h" |
|
61 | 58 |
|
62 | 59 |
static pthread_mutex_t ctime_mutex = PTHREAD_MUTEX_INITIALIZER; |
63 |
-extern int progexit; |
|
64 |
- |
|
65 |
-struct multi_tag { |
|
66 |
- int sd; |
|
67 |
- unsigned int options; |
|
68 |
- const struct cfgstruct *copt; |
|
69 |
- char *fname; |
|
70 |
- const struct cl_engine *engine; |
|
71 |
- const struct cl_limits *limits; |
|
72 |
-}; |
|
73 |
- |
|
74 |
-static void multiscanfile(void *arg) |
|
75 |
-{ |
|
76 |
- struct multi_tag *tag = (struct multi_tag *) arg; |
|
77 |
- const char *virname; |
|
78 |
-#ifndef C_WINDOWS |
|
79 |
- sigset_t sigset; |
|
80 |
-#endif |
|
81 |
- int ret; |
|
82 |
- |
|
83 |
- |
|
84 |
-#ifndef C_WINDOWS |
|
85 |
- /* ignore all signals */ |
|
86 |
- sigfillset(&sigset); |
|
87 |
- pthread_sigmask(SIG_SETMASK, &sigset, NULL); |
|
88 |
-#endif |
|
89 |
- |
|
90 |
- ret = cl_scanfile(tag->fname, &virname, NULL, tag->engine, tag->limits, tag->options); |
|
91 |
- |
|
92 |
- if(ret == CL_VIRUS) { |
|
93 |
- mdprintf(tag->sd, "%s: %s FOUND\n", tag->fname, virname); |
|
94 |
- logg("%s: %s FOUND\n", tag->fname, virname); |
|
95 |
- virusaction(tag->fname, virname, tag->copt); |
|
96 |
- } else if(ret != CL_CLEAN) { |
|
97 |
- mdprintf(tag->sd, "%s: %s ERROR\n", tag->fname, cl_strerror(ret)); |
|
98 |
- logg("%s: %s ERROR\n", tag->fname, cl_strerror(ret)); |
|
99 |
- } else if(logok) { |
|
100 |
- logg("%s: OK\n", tag->fname); |
|
101 |
- } |
|
102 |
- |
|
103 |
- free(tag->fname); |
|
104 |
- free(tag); |
|
105 |
- return; |
|
106 |
-} |
|
107 |
- |
|
108 |
-static int multiscan(const char *dirname, const struct cl_engine *engine, const struct cl_limits *limits, unsigned int options, const struct cfgstruct *copt, int odesc, unsigned int *reclev, threadpool_t *multi_pool) |
|
109 |
-{ |
|
110 |
- DIR *dd; |
|
111 |
- struct dirent *dent; |
|
112 |
-#if defined(HAVE_READDIR_R_3) || defined(HAVE_READDIR_R_2) |
|
113 |
- union { |
|
114 |
- struct dirent d; |
|
115 |
- char b[offsetof(struct dirent, d_name) + NAME_MAX + 1]; |
|
116 |
- } result; |
|
117 |
-#endif |
|
118 |
- struct stat statbuf; |
|
119 |
- char *fname; |
|
120 |
- int scanret = 0; |
|
121 |
- unsigned int maxdirrec = 0; |
|
122 |
- struct multi_tag *scandata; |
|
123 |
- |
|
124 |
- |
|
125 |
- maxdirrec = cfgopt(copt, "MaxDirectoryRecursion")->numarg; |
|
126 |
- if(maxdirrec) { |
|
127 |
- if(*reclev > maxdirrec) { |
|
128 |
- logg("*multiscan: Directory recursion limit exceeded at %s\n", dirname); |
|
129 |
- return 0; |
|
130 |
- } |
|
131 |
- (*reclev)++; |
|
132 |
- } |
|
133 |
- |
|
134 |
- if((dd = opendir(dirname)) != NULL) { |
|
135 |
-#ifdef HAVE_READDIR_R_3 |
|
136 |
- while(!readdir_r(dd, &result.d, &dent) && dent) { |
|
137 |
-#elif defined(HAVE_READDIR_R_2) |
|
138 |
- while((dent = (struct dirent *) readdir_r(dd, &result.d))) { |
|
139 |
-#else |
|
140 |
- while((dent = readdir(dd))) { |
|
141 |
-#endif |
|
142 |
- if (!is_fd_connected(odesc)) { |
|
143 |
- logg("multiscan: Client disconnected\n"); |
|
144 |
- closedir(dd); |
|
145 |
- return -1; |
|
146 |
- } |
|
147 |
- |
|
148 |
- if(progexit) { |
|
149 |
- closedir(dd); |
|
150 |
- return -1; |
|
151 |
- } |
|
152 |
- |
|
153 |
-#if (!defined(C_INTERIX)) && (!defined(C_WINDOWS)) && (!defined(C_CYGWIN)) |
|
154 |
- if(dent->d_ino) |
|
155 |
-#endif |
|
156 |
- { |
|
157 |
- if(strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..")) { |
|
158 |
- /* build the full name */ |
|
159 |
- fname = (char *) mcalloc(strlen(dirname) + strlen(dent->d_name) + 2, sizeof(char)); |
|
160 |
- if(!fname) { |
|
161 |
- logg("!multiscan: Can't allocate memory for fname\n"); |
|
162 |
- closedir(dd); |
|
163 |
- return -1; |
|
164 |
- } |
|
165 |
- sprintf(fname, "%s/%s", dirname, dent->d_name); |
|
166 |
- |
|
167 |
- /* stat the file */ |
|
168 |
- if(lstat(fname, &statbuf) != -1) { |
|
169 |
- if((S_ISDIR(statbuf.st_mode) && !S_ISLNK(statbuf.st_mode)) || (S_ISLNK(statbuf.st_mode) && (checksymlink(fname) == 1) && cfgopt(copt, "FollowDirectorySymlinks")->enabled)) { |
|
170 |
- if(multiscan(fname, engine, limits, options, copt, odesc, reclev, multi_pool) == -1) { |
|
171 |
- free(fname); |
|
172 |
- closedir(dd); |
|
173 |
- return -1; |
|
174 |
- } |
|
175 |
- free(fname); |
|
176 |
- } else { |
|
177 |
- if(S_ISREG(statbuf.st_mode) || (S_ISLNK(statbuf.st_mode) && (checksymlink(fname) == 2) && cfgopt(copt, "FollowFileSymlinks")->enabled)) { |
|
178 |
- |
|
179 |
-#ifdef C_LINUX |
|
180 |
- if(procdev && (statbuf.st_dev == procdev)) |
|
181 |
- scanret = CL_CLEAN; |
|
182 |
- else |
|
183 |
-#endif |
|
184 |
- { |
|
185 |
- scandata = (struct multi_tag *) mmalloc(sizeof(struct multi_tag)); |
|
186 |
- if(!scandata) { |
|
187 |
- logg("!multiscan: Can't allocate memory for scandata\n"); |
|
188 |
- free(fname); |
|
189 |
- closedir(dd); |
|
190 |
- return -1; |
|
191 |
- } |
|
192 |
- scandata->sd = odesc; |
|
193 |
- scandata->options = options; |
|
194 |
- scandata->copt = copt; |
|
195 |
- scandata->fname = fname; |
|
196 |
- scandata->engine = engine; |
|
197 |
- scandata->limits = limits; |
|
198 |
- if(!thrmgr_dispatch(multi_pool, scandata)) { |
|
199 |
- logg("!multiscan: thread dispatch failed for multi_pool (file %s)\n", fname); |
|
200 |
- mdprintf(odesc, "ERROR: Can't scan file %s\n", fname); |
|
201 |
- free(fname); |
|
202 |
- free(scandata); |
|
203 |
- closedir(dd); |
|
204 |
- return -1; |
|
205 |
- } |
|
206 |
- |
|
207 |
- while(!multi_pool->thr_idle) /* non-critical */ |
|
208 |
-#ifdef C_WINDOWS |
|
209 |
- Sleep(1); |
|
210 |
-#else |
|
211 |
- usleep(200); |
|
212 |
-#endif |
|
213 |
- } |
|
214 |
- } |
|
215 |
- } |
|
216 |
- } else { |
|
217 |
- free(fname); |
|
218 |
- } |
|
219 |
- } |
|
220 |
- } |
|
221 |
- } |
|
222 |
- closedir(dd); |
|
223 |
- } else { |
|
224 |
- return -2; |
|
225 |
- } |
|
226 |
- |
|
227 |
- (*reclev)--; |
|
228 |
- return 0; |
|
229 |
-} |
|
230 | 60 |
|
231 | 61 |
int command(int desc, const struct cl_engine *engine, const struct cl_limits *limits, unsigned int options, const struct cfgstruct *copt, int timeout) |
232 | 62 |
{ |
... | ... |
@@ -249,13 +79,13 @@ int command(int desc, const struct cl_engine *engine, const struct cl_limits *li |
249 | 249 |
cli_chomp(buff); |
250 | 250 |
|
251 | 251 |
if(!strncmp(buff, CMD1, strlen(CMD1))) { /* SCAN */ |
252 |
- if(scan(buff + strlen(CMD1) + 1, NULL, engine, limits, options, copt, desc, 0) == -2) |
|
252 |
+ if(scan(buff + strlen(CMD1) + 1, NULL, engine, limits, options, copt, desc, TYPE_SCAN) == -2) |
|
253 | 253 |
if(cfgopt(copt, "ExitOnOOM")->enabled) |
254 | 254 |
return COMMAND_SHUTDOWN; |
255 | 255 |
|
256 | 256 |
} else if(!strncmp(buff, CMD2, strlen(CMD2))) { /* RAWSCAN */ |
257 | 257 |
opt = options & ~CL_SCAN_ARCHIVE; |
258 |
- if(scan(buff + strlen(CMD2) + 1, NULL, engine, NULL, opt, copt, desc, 0) == -2) |
|
258 |
+ if(scan(buff + strlen(CMD2) + 1, NULL, engine, NULL, opt, copt, desc, TYPE_SCAN) == -2) |
|
259 | 259 |
if(cfgopt(copt, "ExitOnOOM")->enabled) |
260 | 260 |
return COMMAND_SHUTDOWN; |
261 | 261 |
|
... | ... |
@@ -270,7 +100,7 @@ int command(int desc, const struct cl_engine *engine, const struct cl_limits *li |
270 | 270 |
mdprintf(desc, "PONG\n"); |
271 | 271 |
|
272 | 272 |
} else if(!strncmp(buff, CMD6, strlen(CMD6))) { /* CONTSCAN */ |
273 |
- if(scan(buff + strlen(CMD6) + 1, NULL, engine, limits, options, copt, desc, 1) == -2) |
|
273 |
+ if(scan(buff + strlen(CMD6) + 1, NULL, engine, limits, options, copt, desc, TYPE_CONTSCAN) == -2) |
|
274 | 274 |
if(cfgopt(copt, "ExitOnOOM")->enabled) |
275 | 275 |
return COMMAND_SHUTDOWN; |
276 | 276 |
|
... | ... |
@@ -324,49 +154,9 @@ int command(int desc, const struct cl_engine *engine, const struct cl_limits *li |
324 | 324 |
close(fd); /* FIXME: should we close it here? */ |
325 | 325 |
|
326 | 326 |
} else if(!strncmp(buff, CMD13, strlen(CMD13))) { /* MULTISCAN */ |
327 |
- threadpool_t *multi_pool; |
|
328 |
- int idletimeout = cfgopt(copt, "IdleTimeout")->numarg; |
|
329 |
- int max_threads = cfgopt(copt, "MaxThreads")->numarg; |
|
330 |
- int ret; |
|
331 |
- unsigned int reclev = 0; |
|
332 |
- const char *path = buff + strlen(CMD13) + 1; |
|
333 |
- const char *virname; |
|
334 |
- struct stat sb; |
|
335 |
- |
|
336 |
- if(stat(path, &sb) == -1) { |
|
337 |
- mdprintf(desc, "Can't stat file %s\n", path); |
|
338 |
- return -1; |
|
339 |
- } |
|
340 |
- |
|
341 |
- if(S_ISDIR(sb.st_mode)) { |
|
342 |
- if((multi_pool = thrmgr_new(max_threads, idletimeout, multiscanfile)) == NULL) { |
|
343 |
- logg("!thrmgr_new failed for multi_pool\n"); |
|
344 |
- mdprintf(desc, "ERROR: thrmgr_new failed for multi_pool\n"); |
|
345 |
- return -1; |
|
346 |
- } |
|
347 |
- |
|
348 |
- ret = multiscan(path, engine, limits, options, copt, desc, &reclev, multi_pool); |
|
349 |
- thrmgr_destroy(multi_pool); |
|
350 |
- |
|
351 |
- if(ret < 0) |
|
352 |
- return -1; |
|
353 |
- |
|
354 |
- } else { |
|
355 |
- ret = cl_scanfile(path, &virname, NULL, engine, limits, options); |
|
356 |
- |
|
357 |
- if(ret == CL_VIRUS) { |
|
358 |
- mdprintf(desc, "%s: %s FOUND\n", path, virname); |
|
359 |
- logg("%s: %s FOUND\n", path, virname); |
|
360 |
- virusaction(path, virname, copt); |
|
361 |
- } else if(ret != CL_CLEAN) { |
|
362 |
- mdprintf(desc, "%s: %s ERROR\n", path, cl_strerror(ret)); |
|
363 |
- logg("%s: %s ERROR\n", path, cl_strerror(ret)); |
|
364 |
- } else { |
|
365 |
- mdprintf(desc, "%s: OK\n", path); |
|
366 |
- if(logok) |
|
367 |
- logg("%s: OK\n", path); |
|
368 |
- } |
|
369 |
- } |
|
327 |
+ if(scan(buff + strlen(CMD13) + 1, NULL, engine, limits, options, copt, desc, TYPE_MULTISCAN) == -2) |
|
328 |
+ if(cfgopt(copt, "ExitOnOOM")->enabled) |
|
329 |
+ return COMMAND_SHUTDOWN; |
|
370 | 330 |
|
371 | 331 |
} else { |
372 | 332 |
mdprintf(desc, "UNKNOWN COMMAND\n"); |