Browse code

libclamav: introduce cl_engine_settings_* API calls for copying settings between engines clamd/server-th.c: respect original engine settings after db reload (bb#1380)

git-svn: trunk@4885

Tomasz Kojm authored on 2009/03/03 03:56:03
Showing 6 changed files
... ...
@@ -1,3 +1,9 @@
1
+Mon Mar  2 19:54:41 CET 2009 (tk)
2
+---------------------------------
3
+ * libclamav: introduce cl_engine_settings_* API calls for copying settings
4
+	      between engines
5
+ * clamd/server-th.c: respect original engine settings after db reload (bb#1380)
6
+
1 7
 Mon Mar  2 17:37:15 CET 2009 (acab)
2 8
 -----------------------------------
3 9
  * build system: update to autoconf 2.63 (bb#1443)
... ...
@@ -171,9 +171,8 @@ static struct cl_engine *reload_db(struct cl_engine *engine, unsigned int dbopti
171 171
 	const char *dbdir;
172 172
 	int retval;
173 173
 	unsigned int sigs = 0;
174
-	char pua_cats[128];
174
+	struct cl_settings *settings = NULL;
175 175
 
176
-    pua_cats[0] = 0;
177 176
     *ret = 0;
178 177
     if(do_check) {
179 178
 	if(!dbstat.entries) {
... ...
@@ -192,9 +191,10 @@ static struct cl_engine *reload_db(struct cl_engine *engine, unsigned int dbopti
192 192
 
193 193
     /* release old structure */
194 194
     if(engine) {
195
-	if(dboptions & (CL_DB_PUA_INCLUDE | CL_DB_PUA_EXCLUDE))
196
-	    if(cl_engine_get(engine, CL_ENGINE_PUA_CATEGORIES, pua_cats))
197
-		logg("^Can't make a copy of pua_cats\n");
195
+	/* copy current settings */
196
+	settings = cl_engine_settings_copy(engine);
197
+	if(!settings)
198
+	    logg("^Can't make a copy of the current engine settings\n");
198 199
 
199 200
 	thrmgr_setactiveengine(NULL);
200 201
 	cl_engine_free(engine);
... ...
@@ -210,22 +210,26 @@ static struct cl_engine *reload_db(struct cl_engine *engine, unsigned int dbopti
210 210
     if((retval = cl_statinidir(dbdir, &dbstat))) {
211 211
 	logg("!cl_statinidir() failed: %s\n", cl_strerror(retval));
212 212
 	*ret = 1;
213
+	if(settings)
214
+	    cl_engine_settings_free(settings);
213 215
 	return NULL;
214 216
     }
215 217
 
216 218
     if(!(engine = cl_engine_new())) {
217 219
 	logg("!Can't initialize antivirus engine\n");
218 220
 	*ret = 1;
221
+	if(settings)
222
+	    cl_engine_settings_free(settings);
219 223
 	return NULL;
220 224
     }
221 225
 
222
-    if(strlen(pua_cats)) {
223
-	if((retval = cl_engine_set(engine, CL_ENGINE_PUA_CATEGORIES, pua_cats))) {
224
-	    logg("!cl_engine_set(CL_ENGINE_PUA_CATEGORIES): %s\n", cl_strerror(retval));
225
-	    cl_engine_free(engine);
226
-	    *ret = 1;
227
-	    return NULL;
226
+    if(settings) {
227
+	retval = cl_engine_settings_apply(engine, settings);
228
+	if(retval != CL_SUCCESS) {
229
+	    logg("^Can't apply previous engine settings: %s\n", cl_strerror(retval));
230
+	    logg("^Using default engine settings\n");
228 231
 	}
232
+	cl_engine_settings_free(settings);
229 233
     }
230 234
 
231 235
     if((retval = cl_load(dbdir, engine, &sigs, dboptions))) {
... ...
@@ -107,6 +107,7 @@ typedef enum {
107 107
 #define CL_SCAN_STDOPT		(CL_SCAN_ARCHIVE | CL_SCAN_MAIL | CL_SCAN_OLE2 | CL_SCAN_PDF | CL_SCAN_HTML | CL_SCAN_PE | CL_SCAN_ALGORITHMIC | CL_SCAN_ELF)
108 108
 
109 109
 struct cl_engine;
110
+struct cl_settings;
110 111
 
111 112
 #define CL_INIT_DEFAULT	0x0
112 113
 extern int cl_init(unsigned int options);
... ...
@@ -134,6 +135,12 @@ extern int cl_engine_set(struct cl_engine *engine, enum cl_engine_field field, c
134 134
 
135 135
 extern int cl_engine_get(const struct cl_engine *engine, enum cl_engine_field field, void *val);
136 136
 
137
+extern struct cl_settings *cl_engine_settings_copy(const struct cl_engine *engine);
138
+
139
+extern int cl_engine_settings_apply(struct cl_engine *engine, const struct cl_settings *settings);
140
+
141
+extern int cl_engine_settings_free(struct cl_settings *settings);
142
+
137 143
 extern int cl_engine_compile(struct cl_engine *engine);
138 144
 
139 145
 extern int cl_engine_addref(struct cl_engine *engine);
... ...
@@ -9,6 +9,9 @@ CLAMAV_PUBLIC {
9 9
     cl_engine_new;
10 10
     cl_engine_set;
11 11
     cl_engine_get;
12
+    cl_engine_settings_copy;
13
+    cl_engine_settings_apply;
14
+    cl_engine_settings_free;
12 15
     cl_engine_compile;
13 16
     cl_engine_addref;
14 17
     cl_engine_free;
... ...
@@ -377,6 +377,77 @@ int cl_engine_get(const struct cl_engine *engine, enum cl_engine_field field, vo
377 377
     return CL_SUCCESS;
378 378
 }
379 379
 
380
+struct cl_settings *cl_engine_settings_copy(const struct cl_engine *engine)
381
+{
382
+	struct cl_settings *settings;
383
+
384
+    settings = (struct cl_settings *) malloc(sizeof(struct cl_settings));
385
+    if(!settings)
386
+	return NULL;
387
+
388
+    settings->ac_only = engine->ac_only;
389
+    settings->ac_mindepth = engine->ac_mindepth;
390
+    settings->ac_maxdepth = engine->ac_maxdepth;
391
+    settings->tmpdir = engine->tmpdir ? strdup(engine->tmpdir) : NULL;
392
+    settings->keeptmp = engine->keeptmp;
393
+    settings->maxscansize = engine->maxscansize;
394
+    settings->maxfilesize = engine->maxfilesize;
395
+    settings->maxreclevel = engine->maxreclevel;
396
+    settings->maxfiles = engine->maxfiles;
397
+    settings->min_cc_count = engine->min_cc_count;
398
+    settings->min_ssn_count = engine->min_ssn_count;
399
+    settings->pua_cats = engine->pua_cats ? strdup(engine->pua_cats) : NULL;
400
+
401
+    return settings;
402
+}
403
+
404
+int cl_engine_settings_apply(struct cl_engine *engine, const struct cl_settings *settings)
405
+{
406
+    engine->ac_only = settings->ac_only;
407
+    engine->ac_mindepth = settings->ac_mindepth;
408
+    engine->ac_maxdepth = settings->ac_maxdepth;
409
+    engine->keeptmp = settings->keeptmp;
410
+    engine->maxscansize = settings->maxscansize;
411
+    engine->maxfilesize = settings->maxfilesize;
412
+    engine->maxreclevel = settings->maxreclevel;
413
+    engine->maxfiles = settings->maxfiles;
414
+    engine->min_cc_count = settings->min_cc_count;
415
+    engine->min_ssn_count = settings->min_ssn_count;
416
+
417
+    if(engine->tmpdir)
418
+	mpool_free(engine->mempool, engine->tmpdir);
419
+    if(settings->tmpdir) {
420
+	engine->tmpdir = cli_mpool_strdup(engine->mempool, settings->tmpdir);
421
+	if(!engine->tmpdir)
422
+	    return CL_EMEM;
423
+    } else {
424
+	engine->tmpdir = NULL;
425
+    }
426
+
427
+    if(engine->pua_cats)
428
+	mpool_free(engine->mempool, engine->pua_cats);
429
+    if(settings->pua_cats) {
430
+	engine->pua_cats = cli_mpool_strdup(engine->mempool, settings->pua_cats);
431
+	if(!engine->pua_cats)
432
+	    return CL_EMEM;
433
+    } else {
434
+	engine->pua_cats = NULL;
435
+    }
436
+
437
+    return CL_SUCCESS;
438
+}
439
+
440
+int cl_engine_settings_free(struct cl_settings *settings)
441
+{
442
+    if(!settings)
443
+	return CL_ENULLARG;
444
+
445
+    free(settings->tmpdir);
446
+    free(settings->pua_cats);
447
+    free(settings);
448
+    return CL_SUCCESS;
449
+}
450
+
380 451
 int cli_checklimits(const char *who, cli_ctx *ctx, unsigned long need1, unsigned long need2, unsigned long need3) {
381 452
     int ret = CL_SUCCESS;
382 453
     unsigned long needed;
... ...
@@ -172,6 +172,25 @@ struct cl_engine {
172 172
     mpool_t *mempool;
173 173
 };
174 174
 
175
+struct cl_settings {
176
+    /* don't store dboptions here; it needs to be provided to cl_load() and
177
+     * can be optionally obtained with cl_engine_get() or from the original
178
+     * settings stored by the application
179
+     */
180
+    uint32_t ac_only;
181
+    uint32_t ac_mindepth;
182
+    uint32_t ac_maxdepth;
183
+    char *tmpdir;
184
+    uint32_t keeptmp;
185
+    uint64_t maxscansize;
186
+    uint64_t maxfilesize;
187
+    uint32_t maxreclevel;
188
+    uint32_t maxfiles;
189
+    uint32_t min_cc_count;
190
+    uint32_t min_ssn_count;
191
+    char *pua_cats;
192
+};
193
+
175 194
 extern int (*cli_unrar_open)(int fd, const char *dirname, unrar_state_t *state);
176 195
 extern int (*cli_unrar_extract_next_prepare)(unrar_state_t *state, const char *dirname);
177 196
 extern int (*cli_unrar_extract_next)(unrar_state_t *state, const char *dirname);