... | ... |
@@ -1,3 +1,7 @@ |
1 |
+Wed Aug 5 16:27:06 CEST 2009 (tk) |
|
2 |
+---------------------------------- |
|
3 |
+ * clamd, clamscan: add support for CrossFilesystems/--cross-fs (bb#1607) |
|
4 |
+ |
|
1 | 5 |
Tue Aug 4 23:15:26 CEST 2009 (tk) |
2 | 6 |
---------------------------------- |
3 | 7 |
* configure, libclamav: fix compile issues on IRIX (bb#1532) |
... | ... |
@@ -237,17 +237,29 @@ int scan_pathchk(const char *path, struct cli_ftw_cbdata *data) |
237 | 237 |
{ |
238 | 238 |
struct scan_cb_data *scandata = data->data; |
239 | 239 |
const struct optstruct *opt; |
240 |
+ struct stat statbuf; |
|
240 | 241 |
|
241 | 242 |
if((opt = optget(scandata->opts, "ExcludePath"))->enabled) { |
242 | 243 |
while(opt) { |
243 | 244 |
if(match_regex(path, opt->strarg) == 1) { |
244 | 245 |
if(scandata->type != TYPE_MULTISCAN) |
245 | 246 |
conn_reply_single(scandata->conn, path, "Excluded"); |
246 |
- return 1; |
|
247 |
+ return 1; |
|
247 | 248 |
} |
248 | 249 |
opt = (const struct optstruct *) opt->nextarg; |
249 | 250 |
} |
250 | 251 |
} |
252 |
+ |
|
253 |
+ if(!optget(scandata->opts, "CrossFilesystems")->enabled) { |
|
254 |
+ if(stat(path, &statbuf) == 0) { |
|
255 |
+ if(statbuf.st_dev != scandata->dev) { |
|
256 |
+ if(scandata->type != TYPE_MULTISCAN) |
|
257 |
+ conn_reply_single(scandata->conn, path, "Excluded (another filesystem)"); |
|
258 |
+ return 1; |
|
259 |
+ } |
|
260 |
+ } |
|
261 |
+ } |
|
262 |
+ |
|
251 | 263 |
return 0; |
252 | 264 |
} |
253 | 265 |
|
... | ... |
@@ -25,6 +25,8 @@ |
25 | 25 |
#define TYPE_CONTSCAN 1 |
26 | 26 |
#define TYPE_MULTISCAN 2 |
27 | 27 |
|
28 |
+#include <sys/types.h> |
|
29 |
+ |
|
28 | 30 |
#include "libclamav/clamav.h" |
29 | 31 |
#include "shared/optparser.h" |
30 | 32 |
#include "thrmgr.h" |
... | ... |
@@ -46,6 +48,7 @@ struct scan_cb_data { |
46 | 46 |
const struct optstruct *opts; |
47 | 47 |
threadpool_t *thr_pool; |
48 | 48 |
jobgroup_t *group; |
49 |
+ dev_t dev; |
|
49 | 50 |
}; |
50 | 51 |
|
51 | 52 |
int scanfd(const int fd, const client_conn_t *conn, unsigned long int *scanned, const struct cl_engine *engine, unsigned int options, const struct optstruct *opts, int odesc, int stream); |
... | ... |
@@ -192,6 +192,7 @@ int command(client_conn_t *conn, int *virus) |
192 | 192 |
struct scan_cb_data scandata; |
193 | 193 |
struct cli_ftw_cbdata data; |
194 | 194 |
unsigned ok, error, total; |
195 |
+ struct stat sb; |
|
195 | 196 |
jobgroup_t *group = NULL; |
196 | 197 |
|
197 | 198 |
if (thrmgr_group_need_terminate(conn->group)) { |
... | ... |
@@ -316,6 +317,11 @@ int command(client_conn_t *conn, int *virus) |
316 | 316 |
flags |= CLI_FTW_FOLLOW_DIR_SYMLINK; |
317 | 317 |
if (optget(opts, "FollowFileSymlinks")->enabled) |
318 | 318 |
flags |= CLI_FTW_FOLLOW_FILE_SYMLINK; |
319 |
+ |
|
320 |
+ if(!optget(opts, "CrossFilesystems")->enabled) |
|
321 |
+ if(stat(conn->filename, &sb) == 0) |
|
322 |
+ scandata.dev = sb.st_dev; |
|
323 |
+ |
|
319 | 324 |
ret = cli_ftw(conn->filename, flags, maxdirrec ? maxdirrec : INT_MAX, scan_callback, &data, scan_pathchk); |
320 | 325 |
if (ret == CL_EMEM) |
321 | 326 |
if(optget(opts, "ExitOnOOM")->enabled) |
... | ... |
@@ -238,6 +238,7 @@ void help(void) |
238 | 238 |
mprintf(" all supported db files from DIR\n"); |
239 | 239 |
mprintf(" --log=FILE -l FILE Save scan report to FILE\n"); |
240 | 240 |
mprintf(" --recursive[=yes/no(*)] -r Scan subdirectories recursively\n"); |
241 |
+ mprintf(" --cross-fs[=yes(*)/no] Scan files and directories on other filesystems\n"); |
|
241 | 242 |
mprintf(" --file-list=FILE -f FILE Scan files from FILE\n"); |
242 | 243 |
mprintf(" --remove[=yes/no(*)] Remove infected files. Be careful!\n"); |
243 | 244 |
mprintf(" --move=DIRECTORY Move infected files into DIRECTORY\n"); |
... | ... |
@@ -169,7 +169,7 @@ static int scanfile(const char *filename, struct cl_engine *engine, const struct |
169 | 169 |
return ret; |
170 | 170 |
} |
171 | 171 |
|
172 |
-static int scandirs(const char *dirname, struct cl_engine *engine, const struct optstruct *opts, unsigned int options, unsigned int depth) |
|
172 |
+static int scandirs(const char *dirname, struct cl_engine *engine, const struct optstruct *opts, unsigned int options, unsigned int depth, dev_t dev) |
|
173 | 173 |
{ |
174 | 174 |
DIR *dd; |
175 | 175 |
struct dirent *dent; |
... | ... |
@@ -228,8 +228,16 @@ static int scandirs(const char *dirname, struct cl_engine *engine, const struct |
228 | 228 |
|
229 | 229 |
/* stat the file */ |
230 | 230 |
if(lstat(fname, &statbuf) != -1) { |
231 |
+ if(!optget(opts, "cross-fs")->enabled) { |
|
232 |
+ if(statbuf.st_dev != dev) { |
|
233 |
+ if(!printinfected) |
|
234 |
+ logg("~%s: Excluded\n", fname); |
|
235 |
+ free(fname); |
|
236 |
+ continue; |
|
237 |
+ } |
|
238 |
+ } |
|
231 | 239 |
if(S_ISDIR(statbuf.st_mode) && !S_ISLNK(statbuf.st_mode) && recursion) { |
232 |
- if(scandirs(fname, engine, opts, options, depth) == 1) |
|
240 |
+ if(scandirs(fname, engine, opts, options, depth, dev) == 1) |
|
233 | 241 |
scanret++; |
234 | 242 |
} else { |
235 | 243 |
if(S_ISREG(statbuf.st_mode)) |
... | ... |
@@ -593,8 +601,10 @@ int scanmanager(const struct optstruct *opts) |
593 | 593 |
if(!getcwd(cwd, sizeof(cwd))) { |
594 | 594 |
logg("!Can't get absolute pathname of current working directory\n"); |
595 | 595 |
ret = 57; |
596 |
- } else |
|
597 |
- ret = scandirs(cwd, engine, opts, options, 1); |
|
596 |
+ } else { |
|
597 |
+ stat(cwd, &sb); |
|
598 |
+ ret = scandirs(cwd, engine, opts, options, 1, sb.st_dev); |
|
599 |
+ } |
|
598 | 600 |
|
599 | 601 |
} else if(opts->filename && !optget(opts, "file-list")->enabled && !strcmp(opts->filename[0], "-")) { /* read data from stdin */ |
600 | 602 |
ret = scanstdin(engine, opts, options); |
... | ... |
@@ -624,7 +634,8 @@ int scanmanager(const struct optstruct *opts) |
624 | 624 |
break; |
625 | 625 |
|
626 | 626 |
case S_IFDIR: |
627 |
- ret = scandirs(file, engine, opts, options, 1); |
|
627 |
+ stat(file, &sb); |
|
628 |
+ ret = scandirs(file, engine, opts, options, 1, sb.st_dev); |
|
628 | 629 |
break; |
629 | 630 |
|
630 | 631 |
default: |
... | ... |
@@ -162,6 +162,11 @@ Follow directory symlinks. |
162 | 162 |
.br |
163 | 163 |
Default: no |
164 | 164 |
.TP |
165 |
+\fBCrossFilesystems BOOL\fR |
|
166 |
+Scan files and directories on other filesystems. |
|
167 |
+.br |
|
168 |
+Default: yes |
|
169 |
+.TP |
|
165 | 170 |
\fBFollowFileSymlinks BOOL\fR |
166 | 171 |
Follow regular file symlinks. |
167 | 172 |
.br |
... | ... |
@@ -48,6 +48,9 @@ Scan files listed line by line in FILE. |
48 | 48 |
\fB\-r, \-\-recursive\fR |
49 | 49 |
Scan directories recursively. All the subdirectories in the given directory will be scanned. |
50 | 50 |
.TP |
51 |
+\fB\-\-cross\-fs=[yes(*)/no]\fR |
|
52 |
+Scan files and directories on other filesystems. |
|
53 |
+.TP |
|
51 | 54 |
\fB\-\-bell\fR |
52 | 55 |
Sound bell on virus detection. |
53 | 56 |
.TP |
... | ... |
@@ -156,6 +156,10 @@ LocalSocket /tmp/clamd.socket |
156 | 156 |
# Default: no |
157 | 157 |
#FollowFileSymlinks yes |
158 | 158 |
|
159 |
+# Scan files and directories on other filesystems. |
|
160 |
+# Default: yes |
|
161 |
+#CrossFilesystems yes |
|
162 |
+ |
|
159 | 163 |
# Perform a database check. |
160 | 164 |
# Default: 600 (10 min) |
161 | 165 |
#SelfCheck 600 |
... | ... |
@@ -211,6 +211,8 @@ const struct clam_option clam_options[] = { |
211 | 211 |
|
212 | 212 |
{ "FollowFileSymlinks", NULL, 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMD, "Follow symlinks to regular files.", "no" }, |
213 | 213 |
|
214 |
+ { "CrossFilesystems", "cross-fs", 0, TYPE_BOOL, MATCH_BOOL, 1, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "Scan files and directories on other filesystems.", "yes" }, |
|
215 |
+ |
|
214 | 216 |
{ "SelfCheck", NULL, 0, TYPE_NUMBER, MATCH_NUMBER, 600, NULL, 0, OPT_CLAMD, "This option specifies the time intervals (in seconds) in which clamd\nshould perform a database check.", "600" }, |
215 | 217 |
|
216 | 218 |
{ "VirusEvent", NULL, 0, TYPE_STRING, NULL, -1, NULL, 0, OPT_CLAMD, "Execute a command when a virus is found. In the command string %v will be\nreplaced with the virus name. Additionally, two environment variables will\nbe defined: $CLAM_VIRUSEVENT_FILENAME and $CLAM_VIRUSEVENT_VIRUSNAME.", "/usr/bin/mailx -s \"ClamAV VIRUS ALERT: %v\" alert < /dev/null" }, |