... | ... |
@@ -338,6 +338,9 @@ int main(int argc, char **argv) |
338 | 338 |
break; |
339 | 339 |
} |
340 | 340 |
|
341 |
+ if (optget(opts, "disable-cache")->enabled) |
|
342 |
+ cl_engine_set_num(engine, CL_ENGINE_DISABLE_CACHE, 1); |
|
343 |
+ |
|
341 | 344 |
/* load the database(s) */ |
342 | 345 |
dbdir = optget(opts, "DatabaseDirectory")->strarg; |
343 | 346 |
logg("#Reading databases from %s\n", dbdir); |
... | ... |
@@ -567,6 +567,9 @@ int scanmanager(const struct optstruct *opts) |
567 | 567 |
return 2; |
568 | 568 |
} |
569 | 569 |
|
570 |
+ if (optget(opts, "disable-cache")->enabled) |
|
571 |
+ cl_engine_set_num(engine, CL_ENGINE_DISABLE_CACHE, 1); |
|
572 |
+ |
|
570 | 573 |
if(optget(opts, "detect-pua")->enabled) { |
571 | 574 |
dboptions |= CL_DB_PUA; |
572 | 575 |
if((opt = optget(opts, "exclude-pua"))->enabled) { |
... | ... |
@@ -246,6 +246,13 @@ Example |
246 | 246 |
# when the LeaveTemporaryFiles option is enabled. |
247 | 247 |
#ForceToDisk yes |
248 | 248 |
|
249 |
+# This option allows you to disable the caching feature of the engine. By |
|
250 |
+# default, the engine will store an MD5 in a cache of any files that are |
|
251 |
+# not flagged as virus or that hit limits checks. Disabling the cache will |
|
252 |
+# have a negative performance impact on large scans. |
|
253 |
+# Default: no |
|
254 |
+#DisableCache yes |
|
255 |
+ |
|
249 | 256 |
## |
250 | 257 |
## Executable files |
251 | 258 |
## |
... | ... |
@@ -743,6 +743,11 @@ int cli_cache_init(struct cl_engine *engine) { |
743 | 743 |
struct CACHE *cache; |
744 | 744 |
unsigned int i, j; |
745 | 745 |
|
746 |
+ if (engine->engine_options & ENGINE_OPTIONS_DISABLE_CACHE) { |
|
747 |
+ cli_dbgmsg("cli_cache_init: Caching disabled.\n"); |
|
748 |
+ return 0; |
|
749 |
+ } |
|
750 |
+ |
|
746 | 751 |
if(!engine) { |
747 | 752 |
cli_errmsg("cli_cache_init: mpool malloc fail\n"); |
748 | 753 |
return 1; |
... | ... |
@@ -777,6 +782,10 @@ void cli_cache_destroy(struct cl_engine *engine) { |
777 | 777 |
struct CACHE *cache; |
778 | 778 |
unsigned int i; |
779 | 779 |
|
780 |
+ if (engine->engine_options & ENGINE_OPTIONS_DISABLE_CACHE) { |
|
781 |
+ return; |
|
782 |
+ } |
|
783 |
+ |
|
780 | 784 |
if(!engine || !(cache = engine->cache)) |
781 | 785 |
return; |
782 | 786 |
|
... | ... |
@@ -813,6 +822,11 @@ void cache_add(unsigned char *md5, size_t size, cli_ctx *ctx) { |
813 | 813 |
uint32_t level; |
814 | 814 |
struct CACHE *c; |
815 | 815 |
|
816 |
+ if (ctx->engine->engine_options & ENGINE_OPTIONS_DISABLE_CACHE) { |
|
817 |
+ cli_dbgmsg("cache_add: Caching disabled. Not adding sample to cache.\n"); |
|
818 |
+ return; |
|
819 |
+ } |
|
820 |
+ |
|
816 | 821 |
if(!ctx || !ctx->engine || !ctx->engine->cache) |
817 | 822 |
return; |
818 | 823 |
|
... | ... |
@@ -851,6 +865,11 @@ void cache_remove(unsigned char *md5, size_t size, const struct cl_engine *engin |
851 | 851 |
unsigned int key = getkey(md5); |
852 | 852 |
struct CACHE *c; |
853 | 853 |
|
854 |
+ if (engine->engine_options & ENGINE_OPTIONS_DISABLE_CACHE) { |
|
855 |
+ cli_dbgmsg("cache_remove: Caching disabled.\n"); |
|
856 |
+ return; |
|
857 |
+ } |
|
858 |
+ |
|
854 | 859 |
if(!engine || !engine->cache) |
855 | 860 |
return; |
856 | 861 |
|
... | ... |
@@ -886,6 +905,11 @@ int cache_check(unsigned char *hash, cli_ctx *ctx) { |
886 | 886 |
cli_md5_ctx md5; |
887 | 887 |
int ret; |
888 | 888 |
|
889 |
+ if (ctx->engine->engine_options & ENGINE_OPTIONS_DISABLE_CACHE) { |
|
890 |
+ cli_dbgmsg("cache_check: Caching disabled. Returning CL_VIRUS.\n"); |
|
891 |
+ return CL_VIRUS; |
|
892 |
+ } |
|
893 |
+ |
|
889 | 894 |
if(!ctx || !ctx->engine || !ctx->engine->cache) |
890 | 895 |
return CL_VIRUS; |
891 | 896 |
|
... | ... |
@@ -194,7 +194,8 @@ enum cl_engine_field { |
194 | 194 |
CL_ENGINE_MAX_HTMLNOTAGS, /* uint64_t */ |
195 | 195 |
CL_ENGINE_MAX_SCRIPTNORMALIZE, /* uint64_t */ |
196 | 196 |
CL_ENGINE_MAX_ZIPTYPERCG, /* uint64_t */ |
197 |
- CL_ENGINE_FORCETODISK /* uint32_t */ |
|
197 |
+ CL_ENGINE_FORCETODISK, /* uint32_t */ |
|
198 |
+ CL_ENGINE_DISABLE_CACHE /* uint32_t */ |
|
198 | 199 |
}; |
199 | 200 |
|
200 | 201 |
enum bytecode_security { |
... | ... |
@@ -232,6 +233,13 @@ extern int cl_engine_addref(struct cl_engine *engine); |
232 | 232 |
|
233 | 233 |
extern int cl_engine_free(struct cl_engine *engine); |
234 | 234 |
|
235 |
+extern void cli_cache_disable(void); |
|
236 |
+ |
|
237 |
+extern int cli_cache_enable(struct cl_engine *engine); |
|
238 |
+ |
|
239 |
+/* For the new engine_options bit field in the engine */ |
|
240 |
+#define ENGINE_OPTIONS_NONE 0 |
|
241 |
+#define ENGINE_OPTIONS_DISABLE_CACHE 1 |
|
235 | 242 |
|
236 | 243 |
/* CALLBACKS */ |
237 | 244 |
|
... | ... |
@@ -490,6 +490,15 @@ int cl_engine_set_num(struct cl_engine *engine, enum cl_engine_field field, long |
490 | 490 |
if (num == CL_BYTECODE_MODE_TEST) |
491 | 491 |
cli_infomsg(NULL, "bytecode engine in test mode\n"); |
492 | 492 |
break; |
493 |
+ case CL_ENGINE_DISABLE_CACHE: |
|
494 |
+ if (num) { |
|
495 |
+ engine->engine_options |= ENGINE_OPTIONS_DISABLE_CACHE; |
|
496 |
+ } else { |
|
497 |
+ engine->engine_options &= ~(ENGINE_OPTIONS_DISABLE_CACHE); |
|
498 |
+ if (!(engine->cache)) |
|
499 |
+ cli_cache_init(engine); |
|
500 |
+ } |
|
501 |
+ break; |
|
493 | 502 |
default: |
494 | 503 |
cli_errmsg("cl_engine_set_num: Incorrect field number\n"); |
495 | 504 |
return CL_EARG; |
... | ... |
@@ -193,6 +193,7 @@ struct cl_engine { |
193 | 193 |
uint32_t ac_maxdepth; |
194 | 194 |
char *tmpdir; |
195 | 195 |
uint32_t keeptmp; |
196 |
+ uint64_t engine_options; |
|
196 | 197 |
|
197 | 198 |
/* Limits */ |
198 | 199 |
uint64_t maxscansize; /* during the scanning of archives this size |
... | ... |
@@ -307,6 +308,7 @@ struct cl_settings { |
307 | 307 |
uint32_t bytecode_timeout; |
308 | 308 |
enum bytecode_mode bytecode_mode; |
309 | 309 |
char *pua_cats; |
310 |
+ uint64_t engine_options; |
|
310 | 311 |
|
311 | 312 |
/* callbacks */ |
312 | 313 |
clcb_pre_cache cb_pre_cache; |
... | ... |
@@ -253,6 +253,8 @@ const struct clam_option __clam_options[] = { |
253 | 253 |
|
254 | 254 |
{ "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" }, |
255 | 255 |
|
256 |
+ { "DisableCache", "disable-cache", 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "This option allows you to disable clamd's caching feature.", "no" }, |
|
257 |
+ |
|
256 | 258 |
{ "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" }, |
257 | 259 |
|
258 | 260 |
{ "ExitOnOOM", NULL, 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMD, "Stop the daemon when libclamav reports an out of memory condition.", "yes" }, |