Browse code

clamscan, clamd: use the new API; drop the hardcoded default limits and use the ones set in cl_engine_new()

git-svn-id: file:///var/lib/svn/clamav-devel/branches/newapi@4384 77e5149b-7576-45b1-b177-96237e5ba77b

Tomasz Kojm authored on 2008/11/13 01:19:43
Showing 12 changed files
... ...
@@ -96,7 +96,7 @@ int main(int argc, char **argv)
96 96
         struct passwd *user = NULL;
97 97
 #endif
98 98
 	time_t currtime;
99
-	struct cl_engine *engine = NULL;
99
+	struct cl_engine *engine;
100 100
 	const char *dbdir, *cfgfile;
101 101
 	char *pua_cats = NULL;
102 102
 	int ret, tcpsock = 0, localsock = 0, i;
... ...
@@ -223,9 +223,6 @@ int main(int argc, char **argv)
223 223
     logg_size = cfgopt(copt, "LogFileMaxSize")->numarg;
224 224
     logg_verbose = mprintf_verbose = cfgopt(copt, "LogVerbose")->enabled;
225 225
 
226
-    if(cfgopt(copt, "Debug")->enabled) /* enable debug messages in libclamav */
227
-	cl_debug();
228
-
229 226
     if((cpt = cfgopt(copt, "LogFile"))->enabled) {
230 227
 	char timestr[32];
231 228
 	logg_file = cpt->strarg;
... ...
@@ -245,6 +242,16 @@ int main(int argc, char **argv)
245 245
     } else
246 246
 	logg_file = NULL;
247 247
 
248
+    if((ret = cl_init(CL_INIT_DEFAULT))) {
249
+	logg("!Can't initialize libclamav: %s\n", cl_strerror(ret));
250
+	logg_close();
251
+	freecfg(copt);
252
+	return 1;
253
+    }
254
+
255
+    if(cfgopt(copt, "Debug")->enabled) /* enable debug messages in libclamav */
256
+	cl_debug();
257
+
248 258
 #if defined(USE_SYSLOG) && !defined(C_AIX)
249 259
     if(cfgopt(copt, "LogSyslog")->enabled) {
250 260
 	    int fac = LOG_LOCAL6;
... ...
@@ -302,6 +309,13 @@ int main(int argc, char **argv)
302 302
     else
303 303
 	logg("#Log file size limit disabled.\n");
304 304
 
305
+    if(!(engine = cl_engine_new(CL_ENGINE_DEFAULT))) {
306
+	logg("!Can't initialize antivirus engine\n");
307
+	logg_close();
308
+	freecfg(copt);
309
+	return 1;
310
+    }
311
+
305 312
     /* load the database(s) */
306 313
     dbdir = cfgopt(copt, "DatabaseDirectory")->strarg;
307 314
     logg("#Reading databases from %s\n", dbdir);
... ...
@@ -318,6 +332,7 @@ int main(int argc, char **argv)
318 318
 		    logg("!Can't allocate memory for pua_cats\n");
319 319
 		    logg_close();
320 320
 		    freecfg(copt);
321
+		    cl_engine_free(engine);
321 322
 		    return 1;
322 323
 		}
323 324
 		logg("# %s", cpt->strarg);
... ...
@@ -337,6 +352,7 @@ int main(int argc, char **argv)
337 337
 		logg_close();
338 338
 		freecfg(copt);
339 339
 		free(pua_cats);
340
+		cl_engine_free(engine);
340 341
 		return 1;
341 342
 	    }
342 343
 	    dboptions |= CL_DB_PUA_INCLUDE;
... ...
@@ -361,15 +377,15 @@ int main(int argc, char **argv)
361 361
 	}
362 362
 
363 363
 	if(pua_cats) {
364
-	    /* FIXME with the new API */
365
-	    if((ret = cli_initengine(&engine, dboptions))) {
366
-		logg("!cli_initengine() failed: %s\n", cl_strerror(ret));
364
+	    if((ret = cl_engine_set(engine, CL_ENGINE_PUA_CATEGORIES, pua_cats))) {
365
+		logg("!cli_engine_set(CL_ENGINE_PUA_CATEGORIES) failed: %s\n", cl_strerror(ret));
367 366
 		logg_close();
368 367
 		freecfg(copt);
369 368
 		free(pua_cats);
369
+		cl_engine_free(engine);
370 370
 		return 1;
371 371
 	    }
372
-	    engine->pua_cats = pua_cats;
372
+	    free(pua_cats);
373 373
 	}
374 374
     } else {
375 375
 	logg("#Not loading PUA signatures.\n");
... ...
@@ -395,25 +411,20 @@ int main(int argc, char **argv)
395 395
 	logg("#Max A-C depth set to %u\n", cpt->numarg);
396 396
     }
397 397
 
398
-    if((ret = cl_load(dbdir, &engine, &sigs, dboptions))) {
398
+    if((ret = cl_load(dbdir, engine, &sigs, dboptions))) {
399 399
 	logg("!%s\n", cl_strerror(ret));
400 400
 	logg_close();
401 401
 	freecfg(copt);
402
-	return 1;
403
-    }
404
-
405
-    if(!engine) {
406
-	logg("!Database initialization error.\n");
407
-	logg_close();
408
-	freecfg(copt);
402
+	cl_engine_free(engine);
409 403
 	return 1;
410 404
     }
411 405
 
412 406
     logg("#Loaded %u signatures.\n", sigs);
413
-    if((ret = cl_build(engine)) != 0) {
414
-	logg("!Database initialization error: %s\n", cl_strerror(ret));;
407
+    if((ret = cl_engine_compile(engine)) != 0) {
408
+	logg("!Database initialization error: %s\n", cl_strerror(ret));
415 409
 	logg_close();
416 410
 	freecfg(copt);
411
+	cl_engine_free(engine);
417 412
 	return 1;
418 413
     }
419 414
 
... ...
@@ -425,6 +436,7 @@ int main(int argc, char **argv)
425 425
 	    logg("!Error at WSAStartup(): %d\n", WSAGetLastError());
426 426
 	    logg_close();
427 427
 	    freecfg(copt);
428
+	    cl_engine_free(engine);
428 429
 	    return 1;
429 430
 	}
430 431
 #endif
... ...
@@ -432,6 +444,7 @@ int main(int argc, char **argv)
432 432
 	if(lsockets[nlsockets] == -1) {
433 433
 	    logg_close();
434 434
 	    freecfg(copt);
435
+	    cl_engine_free(engine);
435 436
 	    return 1;
436 437
 	}
437 438
 	nlsockets++;
... ...
@@ -444,6 +457,7 @@ int main(int argc, char **argv)
444 444
 	    freecfg(copt);
445 445
 	    if(tcpsock)
446 446
 		closesocket(lsockets[0]);
447
+	    cl_engine_free(engine);
447 448
 	    return 1;
448 449
 	}
449 450
 	nlsockets++;
... ...
@@ -461,6 +475,7 @@ int main(int argc, char **argv)
461 461
 	    logg("!daemonize() failed\n");
462 462
 	    logg_close();
463 463
 	    freecfg(copt);
464
+	    cl_engine_free(engine);
464 465
 	    return 1;
465 466
 	}
466 467
 #ifdef C_BSD
... ...
@@ -175,7 +175,7 @@ void *clamukoth(void *arg)
175 175
 		}
176 176
 	    }
177 177
 
178
-	    if(scan && cl_scanfile(acc->filename, &virname, NULL, tharg->engine, tharg->limits, tharg->options) == CL_VIRUS) {
178
+	    if(scan && cl_scanfile(acc->filename, &virname, NULL, tharg->engine, tharg->options) == CL_VIRUS) {
179 179
 		logg("Clamuko: %s: %s FOUND\n", acc->filename, virname);
180 180
 		virusaction(acc->filename, virname, tharg->copt);
181 181
 		acc->deny = 1;
... ...
@@ -82,7 +82,6 @@ struct multi_tag {
82 82
     const struct cfgstruct *copt;
83 83
     char *fname;
84 84
     const struct cl_engine *engine;
85
-    const struct cl_limits *limits;
86 85
 };
87 86
 
88 87
 static int checksymlink(const char *path)
... ...
@@ -101,7 +100,7 @@ static int checksymlink(const char *path)
101 101
     return 0;
102 102
 }
103 103
 
104
-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)
104
+static int dirscan(const char *dirname, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, unsigned int options, const struct cfgstruct *copt, int odesc, unsigned int *reclev, unsigned int type, threadpool_t *multi_pool)
105 105
 {
106 106
 	DIR *dd;
107 107
 	struct dirent *dent;
... ...
@@ -174,7 +173,7 @@ static int dirscan(const char *dirname, const char **virname, unsigned long int
174 174
 		    /* stat the file */
175 175
 		    if(lstat(fname, &statbuf) != -1) {
176 176
 			if((S_ISDIR(statbuf.st_mode) && !S_ISLNK(statbuf.st_mode)) || (S_ISLNK(statbuf.st_mode) && (checksymlink(fname) == 1) && cfgopt(copt, "FollowDirectorySymlinks")->enabled)) {
177
-			    if(dirscan(fname, virname, scanned, engine, limits, options, copt, odesc, reclev, type, multi_pool) == 1) {
177
+			    if(dirscan(fname, virname, scanned, engine, options, copt, odesc, reclev, type, multi_pool) == 1) {
178 178
 				free(fname);
179 179
 				closedir(dd);
180 180
 				return 1;
... ...
@@ -203,7 +202,6 @@ static int dirscan(const char *dirname, const char **virname, unsigned long int
203 203
 					scandata->copt = copt;
204 204
 					scandata->fname = fname;
205 205
 					scandata->engine = engine;
206
-					scandata->limits = limits;
207 206
 					if(!thrmgr_dispatch(multi_pool, scandata)) {
208 207
 					    logg("!thread dispatch failed for multi_pool (file %s)\n", fname);
209 208
 					    mdprintf(odesc, "ERROR: Can't scan file %s\n", fname);
... ...
@@ -221,7 +219,7 @@ static int dirscan(const char *dirname, const char **virname, unsigned long int
221 221
 
222 222
 				    } else { /* CONTSCAN, SCAN */
223 223
 					thrmgr_setactivetask(fname, NULL);
224
-					scanret = cl_scanfile(fname, virname, scanned, engine, limits, options);
224
+					scanret = cl_scanfile(fname, virname, scanned, engine, options);
225 225
 					thrmgr_setactivetask(NULL, NULL);
226 226
 
227 227
 					if(scanret == CL_VIRUS) {
... ...
@@ -288,7 +286,7 @@ static void multiscanfile(void *arg)
288 288
 #endif
289 289
 
290 290
     thrmgr_setactivetask(tag->fname, "MULTISCANFILE");
291
-    ret = cl_scanfile(tag->fname, &virname, NULL, tag->engine, tag->limits, tag->options);
291
+    ret = cl_scanfile(tag->fname, &virname, NULL, tag->engine, tag->options);
292 292
     thrmgr_setactivetask(NULL, NULL);
293 293
 
294 294
     if(ret == CL_VIRUS) {
... ...
@@ -307,7 +305,7 @@ static void multiscanfile(void *arg)
307 307
     return;
308 308
 }
309 309
 
310
-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)
310
+int scan(const char *filename, unsigned long int *scanned, const struct cl_engine *engine, unsigned int options, const struct cfgstruct *copt, int odesc, unsigned int type)
311 311
 {
312 312
 	struct stat sb;
313 313
 	int ret = 0;
... ...
@@ -355,7 +353,7 @@ int scan(const char *filename, unsigned long int *scanned, const struct cl_engin
355 355
 #endif
356 356
 	    {
357 357
 		thrmgr_setactivetask(filename, NULL);
358
-		ret = cl_scanfile(filename, &virname, scanned, engine, limits, options);
358
+		ret = cl_scanfile(filename, &virname, scanned, engine, options);
359 359
 		thrmgr_setactivetask(NULL, NULL);
360 360
 	    }
361 361
 
... ...
@@ -384,7 +382,7 @@ int scan(const char *filename, unsigned long int *scanned, const struct cl_engin
384 384
 		}
385 385
 	    }
386 386
 
387
-	    ret = dirscan(filename, &virname, scanned, engine, limits, options, copt, odesc, &reclev, type, multi_pool);
387
+	    ret = dirscan(filename, &virname, scanned, engine, options, copt, odesc, &reclev, type, multi_pool);
388 388
 
389 389
 	    if(multi_pool)
390 390
 		thrmgr_destroy(multi_pool);
... ...
@@ -407,7 +405,7 @@ int scan(const char *filename, unsigned long int *scanned, const struct cl_engin
407 407
  * why it is so nicely formatted.
408 408
  */
409 409
 int scanfd(const int fd, unsigned long int *scanned,
410
-    const struct cl_engine *engine, const struct cl_limits *limits,
410
+    const struct cl_engine *engine,
411 411
     unsigned int options, const struct cfgstruct *copt, int odesc)  
412 412
 {
413 413
 	int ret;
... ...
@@ -425,7 +423,7 @@ int scanfd(const int fd, unsigned long int *scanned,
425 425
 	snprintf(fdstr, sizeof(fdstr), "fd[%d]", fd);
426 426
 
427 427
 	thrmgr_setactivetask(fdstr, NULL);
428
-	ret = cl_scandesc(fd, &virname, scanned, engine, limits, options);
428
+	ret = cl_scandesc(fd, &virname, scanned, engine, options);
429 429
 	thrmgr_setactivetask(NULL, NULL);
430 430
 
431 431
 	if(ret == CL_VIRUS) {
... ...
@@ -443,7 +441,7 @@ int scanfd(const int fd, unsigned long int *scanned,
443 443
 	return ret;
444 444
 }
445 445
 
446
-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)
446
+int scanstream(int odesc, unsigned long int *scanned, const struct cl_engine *engine, unsigned int options, const struct cfgstruct *copt)
447 447
 {
448 448
 	int ret, sockfd, acceptd;
449 449
 	int tmpd, bread, retval, timeout, btread;
... ...
@@ -604,7 +602,7 @@ int scanstream(int odesc, unsigned long int *scanned, const struct cl_engine *en
604 604
     if(retval == 1) {
605 605
 	lseek(tmpd, 0, SEEK_SET);
606 606
 	thrmgr_setactivetask(peer_addr, NULL);
607
-	ret = cl_scandesc(tmpd, &virname, scanned, engine, limits, options);
607
+	ret = cl_scandesc(tmpd, &virname, scanned, engine, options);
608 608
 	thrmgr_setactivetask(NULL, NULL);
609 609
     } else {
610 610
     	ret = -1;
... ...
@@ -26,10 +26,10 @@
26 26
 #include "libclamav/clamav.h"
27 27
 #include "shared/cfgparser.h"
28 28
 
29
-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
+int scan(const char *filename, unsigned long int *scanned, const struct cl_engine *engine, unsigned int options, const struct cfgstruct *copt, int odesc, unsigned int type);
30 30
 
31
-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
+int scanfd(const int fd, unsigned long int *scanned, const struct cl_engine *engine, unsigned int options, const struct cfgstruct *copt, int odesc);
32 32
 
33
-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
+int scanstream(int odesc, unsigned long int *scanned, const struct cl_engine *engine, unsigned int options, const struct cfgstruct *copt);
34 34
 
35 35
 #endif
... ...
@@ -54,6 +54,7 @@
54 54
 #include "shared.h"
55 55
 #include "libclamav/others.h"
56 56
 #include "libclamav/readdb.h"
57
+#include "libclamav/cltypes.h"
57 58
 
58 59
 #ifndef	C_WINDOWS
59 60
 #define	closesocket(s)	close(s)
... ...
@@ -81,7 +82,6 @@ typedef struct client_conn_tag {
81 81
     const struct cfgstruct *copt;
82 82
     struct cl_engine *engine;
83 83
     time_t engine_timestamp;
84
-    const struct cl_limits *limits;
85 84
     int *socketds;
86 85
     int nsockets;
87 86
 } client_conn_t;
... ...
@@ -114,7 +114,7 @@ static void scanner_thread(void *arg)
114 114
     	timeout = -1;
115 115
 
116 116
     do {
117
-    	ret = command(conn->sd, conn->engine, conn->limits, conn->options, conn->copt, timeout);
117
+    	ret = command(conn->sd, conn->engine, conn->options, conn->copt, timeout);
118 118
 	if (ret < 0) {
119 119
 		break;
120 120
 	}
... ...
@@ -161,7 +161,7 @@ static void scanner_thread(void *arg)
161 161
     shutdown(conn->sd, 2);
162 162
     closesocket(conn->sd);
163 163
     thrmgr_setactiveengine(NULL);
164
-    cl_free(conn->engine);
164
+    cl_engine_free(conn->engine);
165 165
     free(conn);
166 166
     return;
167 167
 }
... ...
@@ -196,8 +196,9 @@ static struct cl_engine *reload_db(struct cl_engine *engine, unsigned int dbopti
196 196
 	const char *dbdir;
197 197
 	int retval;
198 198
 	unsigned int sigs = 0;
199
-	char *pua_cats = NULL;
199
+	char pua_cats[128];
200 200
 
201
+    pua_cats[0] = 0;
201 202
     *ret = 0;
202 203
     if(do_check) {
203 204
 	if(dbstat == NULL) {
... ...
@@ -237,45 +238,38 @@ static struct cl_engine *reload_db(struct cl_engine *engine, unsigned int dbopti
237 237
 
238 238
     /* release old structure */
239 239
     if(engine) {
240
-	if(engine->pua_cats)
241
-	    if(!(pua_cats = strdup(engine->pua_cats)))
240
+	if(dboptions & (CL_DB_PUA_INCLUDE | CL_DB_PUA_EXCLUDE))
241
+	    if(cl_engine_get(engine, CL_ENGINE_PUA_CATEGORIES, pua_cats))
242 242
 		logg("^Can't make a copy of pua_cats\n");
243 243
 
244 244
 	thrmgr_setactiveengine(NULL);
245
-	cl_free(engine);
246
-	engine = NULL;
245
+	cl_engine_free(engine);
247 246
     }
248 247
 
249
-    if(pua_cats) {
250
-	if((retval = cli_initengine(&engine, dboptions))) {
251
-	    logg("!cli_initengine() failed: %s\n", cl_strerror(retval));
252
-	    *ret = 1;
253
-	    free(pua_cats);
254
-	    return NULL;
255
-	}
256
-	engine->pua_cats = pua_cats;
257
-    }
258
-
259
-    if((retval = cl_load(dbdir, &engine, &sigs, dboptions))) {
260
-	logg("!reload db failed: %s\n", cl_strerror(retval));
248
+    if(!(engine = cl_engine_new(CL_ENGINE_DEFAULT))) {
249
+	logg("!Can't initialize antivirus engine\n");
261 250
 	*ret = 1;
262 251
 	return NULL;
263 252
     }
264 253
 
265
-    if(retval) {
266
-	logg("!reload db failed: %s\n", cl_strerror(retval));
254
+    if(strlen(pua_cats)) {
255
+	if((retval = cl_engine_set(engine, CL_ENGINE_PUA_CATEGORIES, pua_cats)))
256
+	    logg("!cl_engine_set(CL_ENGINE_PUA_CATEGORIES): %s\n", cl_strerror(retval));
257
+	cl_engine_free(engine);
267 258
 	*ret = 1;
268 259
 	return NULL;
269 260
     }
270 261
 
271
-    if(!engine) {
262
+    if((retval = cl_load(dbdir, engine, &sigs, dboptions))) {
272 263
 	logg("!reload db failed: %s\n", cl_strerror(retval));
264
+	cl_engine_free(engine);
273 265
 	*ret = 1;
274 266
 	return NULL;
275 267
     }
276 268
 
277
-    if((retval = cl_build(engine)) != 0) {
278
-	logg("!Database initialization error: can't build engine: %s\n", cl_strerror(retval));
269
+    if((retval = cl_engine_compile(engine)) != 0) {
270
+	logg("!Database initialization error: can't compile engine: %s\n", cl_strerror(retval));
271
+	cl_engine_free(engine);
279 272
 	*ret = 1;
280 273
 	return NULL;
281 274
     }
... ...
@@ -297,7 +291,6 @@ int acceptloop_th(int *socketds, int nsockets, struct cl_engine *engine, unsigne
297 297
 	struct rlimit rlim;
298 298
 #endif
299 299
 	mode_t old_umask;
300
-	struct cl_limits limits;
301 300
 	client_conn_t *client_conn;
302 301
 	const struct cfgstruct *cpt;
303 302
 #ifdef HAVE_STRERROR_R
... ...
@@ -307,6 +300,8 @@ int acceptloop_th(int *socketds, int nsockets, struct cl_engine *engine, unsigne
307 307
 	time_t start_time, current_time;
308 308
 	pid_t mainpid;
309 309
 	int idletimeout;
310
+	uint32_t val32;
311
+	uint64_t val64;
310 312
 
311 313
 #ifdef CLAMUKO
312 314
 	pthread_t clamuko_pid;
... ...
@@ -318,73 +313,81 @@ int acceptloop_th(int *socketds, int nsockets, struct cl_engine *engine, unsigne
318 318
 	memset(&sigact, 0, sizeof(struct sigaction));
319 319
 #endif
320 320
 
321
-    /* save the PID */
322
-    mainpid = getpid();
323
-    if((cpt = cfgopt(copt, "PidFile"))->enabled) {
324
-	    FILE *fd;
325
-	old_umask = umask(0006);
326
-	if((fd = fopen(cpt->strarg, "w")) == NULL) {
327
-	    logg("!Can't save PID in file %s\n", cpt->strarg);
328
-	} else {
329
-	    if (fprintf(fd, "%u", (unsigned int) mainpid)<0) {
330
-	    	logg("!Can't save PID in file %s\n", cpt->strarg);
331
-	    }
332
-	    fclose(fd);
321
+    /* set up limits */
322
+    if((cpt = cfgopt(copt, "MaxScanSize"))->enabled) {
323
+	val64 = cpt->numarg;
324
+	if((ret = cl_engine_set(engine, CL_ENGINE_MAX_SCANSIZE, &val64))) {
325
+	    logg("!cli_engine_set(CL_ENGINE_MAX_SCANSIZE) failed: %s\n", cl_strerror(ret));
326
+	    cl_engine_free(engine);
327
+	    return 1;
333 328
 	}
334
-	umask(old_umask);
335 329
     }
336
-
337
-    logg("*Listening daemon: PID: %u\n", (unsigned int) mainpid);
338
-    max_threads = cfgopt(copt, "MaxThreads")->numarg;
339
-
340
-
341
-    memset(&limits, 0, sizeof(struct cl_limits));
342
-
343
-    if((limits.maxscansize = cfgopt(copt, "MaxScanSize")->numarg)) {
344
-    	logg("Limits: Global size limit set to %lu bytes.\n", limits.maxscansize);
345
-    } else {
330
+    cl_engine_get(engine, CL_ENGINE_MAX_SCANSIZE, &val64);
331
+    if(val64)
332
+    	logg("Limits: Global size limit set to %llu bytes.\n", (unsigned long long) val64);
333
+    else
346 334
     	logg("^Limits: Global size limit protection disabled.\n");
347
-    }
348 335
 
349
-    if((limits.maxfilesize = cfgopt(copt, "MaxFileSize")->numarg)) {
350
-    	logg("Limits: File size limit set to %lu bytes.\n", limits.maxfilesize);
351
-    } else {
352
-	logg("^Limits: File size limit protection disabled.\n");
336
+    if((cpt = cfgopt(copt, "MaxFileSize"))->enabled) {
337
+	val64 = cpt->numarg;
338
+	if((ret = cl_engine_set(engine, CL_ENGINE_MAX_FILESIZE, &val64))) {
339
+	    logg("!cli_engine_set(CL_ENGINE_MAX_FILESIZE) failed: %s\n", cl_strerror(ret));
340
+	    cl_engine_free(engine);
341
+	    return 1;
342
+	}
353 343
     }
344
+    cl_engine_get(engine, CL_ENGINE_MAX_FILESIZE, &val64);
345
+    if(val64)
346
+    	logg("Limits: File size limit set to %llu bytes.\n", (unsigned long long) val64);
347
+    else
348
+    	logg("^Limits: File size limit protection disabled.\n");
354 349
 
355 350
 #ifndef C_WINDOWS
356 351
     if(getrlimit(RLIMIT_FSIZE, &rlim) == 0) {
357
-	if((rlim.rlim_max < limits.maxfilesize) || (rlim.rlim_max < limits.maxscansize))
358
-	    logg("^System limit for file size is lower than maxfilesize or maxscansize\n");
352
+	cl_engine_get(engine, CL_ENGINE_MAX_FILESIZE, &val64);
353
+	if(rlim.rlim_max < val64)
354
+	    logg("^System limit for file size is lower than engine->maxfilesize\n");
355
+	cl_engine_get(engine, CL_ENGINE_MAX_SCANSIZE, &val64);
356
+	if(rlim.rlim_max < val64)
357
+	    logg("^System limit for file size is lower than engine->maxscansize\n");
359 358
     } else {
360 359
 	logg("^Cannot obtain resource limits for file size\n");
361 360
     }
362 361
 #endif
363 362
 
364
-    if((limits.maxreclevel = cfgopt(copt, "MaxRecursion")->numarg)) {
365
-        logg("Limits: Recursion level limit set to %u.\n", limits.maxreclevel);
366
-    } else {
367
-        logg("^Limits: Recursion level limit protection disabled.\n");
363
+    if((cpt = cfgopt(copt, "MaxRecursion"))->enabled) {
364
+	val32 = cpt->numarg;
365
+	if((ret = cl_engine_set(engine, CL_ENGINE_MAX_RECURSION, &val32))) {
366
+	    logg("!cli_engine_set(CL_ENGINE_MAX_RECURSION) failed: %s\n", cl_strerror(ret));
367
+	    cl_engine_free(engine);
368
+	    return 1;
369
+	}
368 370
     }
369
-
370
-    if((limits.maxfiles = cfgopt(copt, "MaxFiles")->numarg)) {
371
-        logg("Limits: Files limit set to %u.\n", limits.maxfiles);
372
-    } else {
373
-        logg("^Limits: Files limit protection disabled.\n");
371
+    cl_engine_get(engine, CL_ENGINE_MAX_RECURSION, &val32);
372
+    if(val32)
373
+    	logg("Limits: Recursion level limit set to %u.\n", (unsigned int) val32);
374
+    else
375
+    	logg("^Limits: Recursion level limit protection disabled.\n");
376
+
377
+    if((cpt = cfgopt(copt, "MaxFiles"))->enabled) {
378
+	val32 = cpt->numarg;
379
+	if((ret = cl_engine_set(engine, CL_ENGINE_MAX_FILES, &val32))) {
380
+	    logg("!cli_engine_set(CL_ENGINE_MAX_FILES) failed: %s\n", cl_strerror(ret));
381
+	    cl_engine_free(engine);
382
+	    return 1;
383
+	}
374 384
     }
385
+    cl_engine_get(engine, CL_ENGINE_MAX_FILES, &val32);
386
+    if(val32)
387
+    	logg("Limits: Files limit set to %u.\n", (unsigned int) val32);
388
+    else
389
+    	logg("^Limits: Files limit protection disabled.\n");
375 390
 
376
-    if(cfgopt(copt, "ScanArchive")->enabled) {
377 391
 
392
+    if(cfgopt(copt, "ScanArchive")->enabled) {
378 393
 	logg("Archive support enabled.\n");
379 394
 	options |= CL_SCAN_ARCHIVE;
380 395
 
381
-	if(cfgopt(copt, "ArchiveLimitMemoryUsage")->enabled) {
382
-	    limits.archivememlim = 1;
383
-	    logg("Archive: Limited memory usage.\n");
384
-	} else {
385
-	    limits.archivememlim = 0;
386
-	}
387
-
388 396
 	if(cfgopt(copt, "ArchiveBlockEncrypted")->enabled) {
389 397
 	    logg("Archive: Blocking encrypted archives.\n");
390 398
 	    options |= CL_SCAN_BLOCKENCRYPTED;
... ...
@@ -482,11 +485,27 @@ int acceptloop_th(int *socketds, int nsockets, struct cl_engine *engine, unsigne
482 482
     if(cfgopt(copt, "StructuredDataDetection")->enabled) {
483 483
         options |= CL_SCAN_STRUCTURED;
484 484
 
485
-        limits.min_cc_count = cfgopt(copt, "StructuredMinCreditCardCount")->numarg;
486
-        logg("Structured: Minimum Credit Card Number Count set to %u\n", limits.min_cc_count);
487
-
488
-        limits.min_ssn_count = cfgopt(copt, "StructuredMinSSNCount")->numarg;
489
-        logg("Structured: Minimum Social Security Number Count set to %u\n", limits.min_ssn_count);
485
+	if((cpt = cfgopt(copt, "StructuredMinCreditCardCount"))->enabled) {
486
+	    val32 = cpt->numarg;
487
+	    if((ret = cl_engine_set(engine, CL_ENGINE_MIN_CC_COUNT, &val32))) {
488
+		logg("!cli_engine_set(CL_ENGINE_MIN_CC_COUNT) failed: %s\n", cl_strerror(ret));
489
+		cl_engine_free(engine);
490
+		return 1;
491
+	    }
492
+	}
493
+	cl_engine_get(engine, CL_ENGINE_MIN_CC_COUNT, &val32);
494
+	logg("Structured: Minimum Credit Card Number Count set to %u\n", (unsigned int) val32);
495
+
496
+	if((cpt = cfgopt(copt, "StructuredMinSSNCount"))->enabled) {
497
+	    val32 = cpt->numarg;
498
+	    if((ret = cl_engine_set(engine, CL_ENGINE_MIN_SSN_COUNT, &val32))) {
499
+		logg("!cli_engine_set(CL_ENGINE_MIN_SSN_COUNT) failed: %s\n", cl_strerror(ret));
500
+		cl_engine_free(engine);
501
+		return 1;
502
+	    }
503
+	}
504
+	cl_engine_get(engine, CL_ENGINE_MIN_SSN_COUNT, &val32);
505
+        logg("Structured: Minimum Social Security Number Count set to %u\n", (unsigned int) val32);
490 506
 
491 507
         if(cfgopt(copt, "StructuredSSNFormatNormal")->enabled)
492 508
             options |= CL_SCAN_STRUCTURED_SSN_NORMAL;
... ...
@@ -502,6 +521,25 @@ int acceptloop_th(int *socketds, int nsockets, struct cl_engine *engine, unsigne
502 502
 	logg("Self checking every %u seconds.\n", selfchk);
503 503
     }
504 504
 
505
+    /* save the PID */
506
+    mainpid = getpid();
507
+    if((cpt = cfgopt(copt, "PidFile"))->enabled) {
508
+	    FILE *fd;
509
+	old_umask = umask(0006);
510
+	if((fd = fopen(cpt->strarg, "w")) == NULL) {
511
+	    logg("!Can't save PID in file %s\n", cpt->strarg);
512
+	} else {
513
+	    if (fprintf(fd, "%u", (unsigned int) mainpid)<0) {
514
+	    	logg("!Can't save PID in file %s\n", cpt->strarg);
515
+	    }
516
+	    fclose(fd);
517
+	}
518
+	umask(old_umask);
519
+    }
520
+
521
+    logg("*Listening daemon: PID: %u\n", (unsigned int) mainpid);
522
+    max_threads = cfgopt(copt, "MaxThreads")->numarg;
523
+
505 524
     if(cfgopt(copt, "ClamukoScanOnAccess")->enabled)
506 525
 #ifdef CLAMUKO
507 526
     {
... ...
@@ -511,7 +549,6 @@ int acceptloop_th(int *socketds, int nsockets, struct cl_engine *engine, unsigne
511 511
 	    if(!(tharg = (struct thrarg *) malloc(sizeof(struct thrarg)))) break;
512 512
 	    tharg->copt = copt;
513 513
 	    tharg->engine = engine;
514
-	    tharg->limits = &limits;
515 514
 	    tharg->options = options;
516 515
 	    if(!pthread_create(&clamuko_pid, &clamuko_attr, clamukoth, tharg)) break;
517 516
 	    free(tharg);
... ...
@@ -625,9 +662,8 @@ int acceptloop_th(int *socketds, int nsockets, struct cl_engine *engine, unsigne
625 625
 		    client_conn->sd = new_sd;
626 626
 		    client_conn->options = options;
627 627
 		    client_conn->copt = copt;
628
-		    client_conn->engine = cl_dup(engine);
628
+		    client_conn->engine = cl_engine_dup(engine);
629 629
 		    client_conn->engine_timestamp = reloaded_time;
630
-		    client_conn->limits = &limits;
631 630
 		    client_conn->socketds = socketds;
632 631
 		    client_conn->nsockets = nsockets;
633 632
 		    if(!thrmgr_dispatch(thr_pool, client_conn)) {
... ...
@@ -717,7 +753,7 @@ int acceptloop_th(int *socketds, int nsockets, struct cl_engine *engine, unsigne
717 717
 #endif
718 718
     if(engine) {
719 719
 	thrmgr_setactiveengine(NULL);
720
-	cl_free(engine);
720
+	cl_engine_free(engine);
721 721
     }
722 722
 
723 723
     if(dbstat)
... ...
@@ -68,7 +68,7 @@
68 68
 #include "thrmgr.h"
69 69
 
70 70
 #ifdef HAVE_FD_PASSING
71
-static int recvfd_and_scan(int desc, const struct cl_engine *engine, const struct cl_limits *limits, unsigned int options, const struct cfgstruct *copt)
71
+static int recvfd_and_scan(int desc, const struct cl_engine *engine, unsigned int options, const struct cfgstruct *copt)
72 72
 {
73 73
 	struct msghdr msg;
74 74
 	struct cmsghdr *cmsg;
... ...
@@ -99,7 +99,7 @@ static int recvfd_and_scan(int desc, const struct cl_engine *engine, const struc
99 99
 		    cmsg->cmsg_level == SOL_SOCKET &&
100 100
 		    cmsg->cmsg_type == SCM_RIGHTS) {
101 101
 			int fd = *(int *)CMSG_DATA(cmsg);
102
-			ret = scanfd(fd, NULL, engine, limits, options, copt, desc);
102
+			ret = scanfd(fd, NULL, engine, options, copt, desc);
103 103
 			close(fd);
104 104
 		}
105 105
 	}
... ...
@@ -107,14 +107,14 @@ static int recvfd_and_scan(int desc, const struct cl_engine *engine, const struc
107 107
 }
108 108
 
109 109
 #else
110
-static int recvfd_and_scan(int desc, const struct cl_engine *engine, const struct cl_limits *limits, unsigned int options, const struct cfgstruct *copt)
110
+static int recvfd_and_scan(int desc, const struct cl_engine *engine, unsigned int options, const struct cfgstruct *copt)
111 111
 {
112 112
 	mdprintf(desc, "ERROR: FILDES support not compiled in\n");
113 113
 	return -1;
114 114
 }
115 115
 #endif
116 116
 
117
-int command(int desc, const struct cl_engine *engine, const struct cl_limits *limits, unsigned int options, const struct cfgstruct *copt, int timeout)
117
+int command(int desc, const struct cl_engine *engine, unsigned int options, const struct cfgstruct *copt, int timeout)
118 118
 {
119 119
 	char buff[1025];
120 120
 	int bread;
... ...
@@ -136,7 +136,7 @@ int command(int desc, const struct cl_engine *engine, const struct cl_limits *li
136 136
 
137 137
     if(!strncmp(buff, CMD1, strlen(CMD1))) { /* SCAN */
138 138
 	thrmgr_setactivetask(NULL, CMD1);
139
-	if(scan(buff + strlen(CMD1) + 1, NULL, engine, limits, options, copt, desc, TYPE_SCAN) == -2)
139
+	if(scan(buff + strlen(CMD1) + 1, NULL, engine, options, copt, desc, TYPE_SCAN) == -2)
140 140
 	    if(cfgopt(copt, "ExitOnOOM")->enabled)
141 141
 		return COMMAND_SHUTDOWN;
142 142
 
... ...
@@ -159,24 +159,28 @@ int command(int desc, const struct cl_engine *engine, const struct cl_limits *li
159 159
 
160 160
     } else if(!strncmp(buff, CMD6, strlen(CMD6))) { /* CONTSCAN */
161 161
 	thrmgr_setactivetask(NULL, CMD6);
162
-	if(scan(buff + strlen(CMD6) + 1, NULL, engine, limits, options, copt, desc, TYPE_CONTSCAN) == -2)
162
+	if(scan(buff + strlen(CMD6) + 1, NULL, engine, options, copt, desc, TYPE_CONTSCAN) == -2)
163 163
 	    if(cfgopt(copt, "ExitOnOOM")->enabled)
164 164
 		return COMMAND_SHUTDOWN;
165 165
 
166 166
     } else if(!strncmp(buff, CMD7, strlen(CMD7))) { /* VERSION */
167
+	    uint32_t ver;
168
+
167 169
 	thrmgr_setactivetask(NULL, CMD7);
168
-	if(engine->dbversion[0]) {
170
+	cl_engine_get(engine, CL_ENGINE_DB_VERSION, &ver);
171
+	if(ver) {
169 172
 		char timestr[32];
170
-		time_t t = (time_t) engine->dbversion[1];
173
+		time_t t;
171 174
 
172
-	    mdprintf(desc, "ClamAV %s/%d/%s", get_version(), engine->dbversion[0], cli_ctime(&t, timestr, sizeof(timestr)));
175
+	    cl_engine_get(engine, CL_ENGINE_DB_TIME, &t);
176
+	    mdprintf(desc, "ClamAV %s/%u/%s", get_version(), (unsigned int) ver, cli_ctime(&t, timestr, sizeof(timestr)));
173 177
 	} else {
174 178
 	    mdprintf(desc, "ClamAV %s\n", get_version());
175 179
 	}
176 180
 
177 181
     } else if(!strncmp(buff, CMD8, strlen(CMD8))) { /* STREAM */
178 182
 	thrmgr_setactivetask(NULL, CMD8);
179
-	if(scanstream(desc, NULL, engine, limits, options, copt) == CL_EMEM)
183
+	if(scanstream(desc, NULL, engine, options, copt) == CL_EMEM)
180 184
 	    if(cfgopt(copt, "ExitOnOOM")->enabled)
181 185
 		return COMMAND_SHUTDOWN;
182 186
 
... ...
@@ -194,13 +198,13 @@ int command(int desc, const struct cl_engine *engine, const struct cl_limits *li
194 194
 
195 195
     } else if(!strncmp(buff, CMD13, strlen(CMD13))) { /* MULTISCAN */
196 196
 	thrmgr_setactivetask(buff+strlen(CMD13)+1, CMD13);
197
-	if(scan(buff + strlen(CMD13) + 1, NULL, engine, limits, options, copt, desc, TYPE_MULTISCAN) == -2)
197
+	if(scan(buff + strlen(CMD13) + 1, NULL, engine, options, copt, desc, TYPE_MULTISCAN) == -2)
198 198
 	    if(cfgopt(copt, "ExitOnOOM")->enabled)
199 199
 		return COMMAND_SHUTDOWN;
200 200
 
201 201
     } else if(!strncmp(buff, CMD14, strlen(CMD14))) { /* FILDES */
202 202
 	thrmgr_setactivetask(NULL, CMD14);
203
-	if(recvfd_and_scan(desc, engine, limits, options, copt) == -2)
203
+	if(recvfd_and_scan(desc, engine, options, copt) == -2)
204 204
 	    if(cfgopt(copt, "ExitOnOOM")->enabled)
205 205
 		return COMMAND_SHUTDOWN;
206 206
     } else if(!strncmp(buff, CMD15, strlen(CMD15))) { /* STATS */
... ...
@@ -43,6 +43,6 @@
43 43
 #include "libclamav/clamav.h"
44 44
 #include "shared/cfgparser.h"
45 45
 
46
-int command(int desc, const struct cl_engine *engine, const struct cl_limits *limits, unsigned int options, const struct cfgstruct *copt, int timeout);
46
+int command(int desc, const struct cl_engine *engine, unsigned int options, const struct cfgstruct *copt, int timeout);
47 47
 
48 48
 #endif
... ...
@@ -60,6 +60,7 @@
60 60
 #include "libclamav/matcher-ac.h"
61 61
 #include "libclamav/str.h"
62 62
 #include "libclamav/readdb.h"
63
+#include "libclamav/cltypes.h"
63 64
 
64 65
 #ifdef C_LINUX
65 66
 dev_t procdev;
... ...
@@ -76,7 +77,7 @@ dev_t procdev;
76 76
 
77 77
 static void move_infected(const char *filename, const struct optstruct *opt);
78 78
 
79
-static int scanfile(const char *filename, struct cl_engine *engine, const struct optstruct *opt, const struct cl_limits *limits, unsigned int options)
79
+static int scanfile(const char *filename, struct cl_engine *engine, const struct optstruct *opt, unsigned int options)
80 80
 {
81 81
 	int ret = 0, fd, included, printclean = 1;
82 82
 	const struct optnode *optnode;
... ...
@@ -149,7 +150,7 @@ static int scanfile(const char *filename, struct cl_engine *engine, const struct
149 149
 
150 150
     info.files++;
151 151
 
152
-    if((ret = cl_scandesc(fd, &virname, &info.blocks, engine, limits, options)) == CL_VIRUS) {
152
+    if((ret = cl_scandesc(fd, &virname, &info.blocks, engine, options)) == CL_VIRUS) {
153 153
 	logg("~%s: %s FOUND\n", filename, virname);
154 154
 	info.ifiles++;
155 155
 
... ...
@@ -180,7 +181,7 @@ static int scanfile(const char *filename, struct cl_engine *engine, const struct
180 180
     return ret;
181 181
 }
182 182
 
183
-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)
183
+static int scandirs(const char *dirname, struct cl_engine *engine, const struct optstruct *opt, unsigned int options, unsigned int depth)
184 184
 {
185 185
 	DIR *dd;
186 186
 	struct dirent *dent;
... ...
@@ -250,11 +251,11 @@ static int scandirs(const char *dirname, struct cl_engine *engine, const struct
250 250
 		    /* stat the file */
251 251
 		    if(lstat(fname, &statbuf) != -1) {
252 252
 			if(S_ISDIR(statbuf.st_mode) && !S_ISLNK(statbuf.st_mode) && recursion) {
253
-			    if(scandirs(fname, engine, opt, limits, options, depth) == 1)
253
+			    if(scandirs(fname, engine, opt, options, depth) == 1)
254 254
 				scanret++;
255 255
 			} else {
256 256
 			    if(S_ISREG(statbuf.st_mode))
257
-				scanret += scanfile(fname, engine, opt, limits, options);
257
+				scanret += scanfile(fname, engine, opt, options);
258 258
 			}
259 259
 		    }
260 260
 		    free(fname);
... ...
@@ -277,7 +278,7 @@ static int scandirs(const char *dirname, struct cl_engine *engine, const struct
277 277
 
278 278
 }
279 279
 
280
-static int scanstdin(const struct cl_engine *engine, const struct cl_limits *limits, int options)
280
+static int scanstdin(const struct cl_engine *engine, int options)
281 281
 {
282 282
 	int ret;
283 283
 	const char *virname, *tmpdir;
... ...
@@ -321,7 +322,7 @@ static int scanstdin(const struct cl_engine *engine, const struct cl_limits *lim
321 321
     logg("*Checking %s\n", file);
322 322
     info.files++;
323 323
 
324
-    if((ret = cl_scanfile(file, &virname, &info.blocks, engine, limits, options)) == CL_VIRUS) {
324
+    if((ret = cl_scanfile(file, &virname, &info.blocks, engine, options)) == CL_VIRUS) {
325 325
 	logg("stdin: %s FOUND\n", virname);
326 326
 	info.ifiles++;
327 327
 
... ...
@@ -345,15 +346,15 @@ int scanmanager(const struct optstruct *opt)
345 345
 	mode_t fmode;
346 346
 	int ret = 0, fmodeint, i, x;
347 347
 	unsigned int options = 0, dboptions = 0;
348
-	struct cl_engine *engine = NULL;
349
-	struct cl_limits limits;
348
+	struct cl_engine *engine;
350 349
 	struct stat sb;
351 350
 	char *file, cwd[1024], *pua_cats = NULL, *argument;
352 351
 	const struct optnode *optnode;
353 352
 #ifndef C_WINDOWS
354 353
 	struct rlimit rlim;
355 354
 #endif
356
-
355
+	uint64_t val64;
356
+	uint32_t val32;
357 357
 
358 358
     if(!opt_check(opt, "no-phishing-sigs"))
359 359
 	dboptions |= CL_DB_PHISHING;
... ...
@@ -376,6 +377,16 @@ int scanmanager(const struct optstruct *opt)
376 376
     if(opt_check(opt, "dev-ac-depth"))
377 377
 	cli_ac_setdepth(AC_DEFAULT_MIN_DEPTH, atoi(opt_arg(opt, "dev-ac-depth")));
378 378
 
379
+    if((ret = cl_init(CL_INIT_DEFAULT))) {
380
+	logg("!Can't initialize libclamav: %s\n", cl_strerror(ret));
381
+	return 50;
382
+    }
383
+
384
+    if(!(engine = cl_engine_new(CL_ENGINE_DEFAULT))) {
385
+	logg("!Can't initialize antivirus engine\n");
386
+	return 50;
387
+    }
388
+
379 389
     if(opt_check(opt, "detect-pua")) {
380 390
 	dboptions |= CL_DB_PUA;
381 391
 
... ...
@@ -386,6 +397,7 @@ int scanmanager(const struct optstruct *opt)
386 386
 	    while(argument) {
387 387
 		if(!(pua_cats = realloc(pua_cats, i + strlen(argument) + 3))) {
388 388
 		    logg("!Can't allocate memory for pua_cats\n");
389
+		    cl_engine_free(engine);
389 390
 		    return 70;
390 391
 		}
391 392
 		sprintf(pua_cats + i, ".%s", argument);
... ...
@@ -400,6 +412,7 @@ int scanmanager(const struct optstruct *opt)
400 400
 	if(opt_check(opt, "include-pua")) {
401 401
 	    if(pua_cats) {
402 402
 		logg("!--exclude-pua and --include-pua cannot be used at the same time\n");
403
+		cl_engine_free(engine);
403 404
 		free(pua_cats);
404 405
 		return 40;
405 406
 	    }
... ...
@@ -421,45 +434,42 @@ int scanmanager(const struct optstruct *opt)
421 421
 	}
422 422
 
423 423
 	if(pua_cats) {
424
-	    /* FIXME with the new API */
425
-	    if((ret = cli_initengine(&engine, dboptions))) {
426
-		logg("!cli_initengine() failed: %s\n", cl_strerror(ret));
424
+	    if((ret = cl_engine_set(engine, CL_ENGINE_PUA_CATEGORIES, pua_cats))) {
425
+		logg("!cli_engine_set(CL_ENGINE_PUA_CATEGORIES) failed: %s\n", cl_strerror(ret));
427 426
 		free(pua_cats);
427
+		cl_engine_free(engine);
428 428
 		return 50;
429 429
 	    }
430
-	    engine->pua_cats = pua_cats;
430
+	    free(pua_cats);
431 431
 	}
432 432
     }
433 433
 
434 434
     if(opt_check(opt, "database")) {
435
-	if((ret = cl_load(opt_arg(opt, "database"), &engine, &info.sigs, dboptions))) {
435
+	if((ret = cl_load(opt_arg(opt, "database"), engine, &info.sigs, dboptions))) {
436 436
 	    logg("!%s\n", cl_strerror(ret));
437
+	    cl_engine_free(engine);
437 438
 	    return 50;
438 439
 	}
439 440
 
440 441
     } else {
441 442
 	    char *dbdir = freshdbdir();
442 443
 
443
-	if((ret = cl_load(dbdir, &engine, &info.sigs, dboptions))) {
444
+	if((ret = cl_load(dbdir, engine, &info.sigs, dboptions))) {
444 445
 	    logg("!%s\n", cl_strerror(ret));
445 446
 	    free(dbdir);
447
+	    cl_engine_free(engine);
446 448
 	    return 50;
447 449
 	}
448 450
 	free(dbdir);
449 451
     }
450 452
 
451
-    if(!engine) {
452
-	logg("!Can't initialize the virus database\n");
453
-	return 50;
454
-    }
455
-
456
-    if((ret = cl_build(engine)) != 0) {
453
+    if((ret = cl_engine_compile(engine)) != 0) {
457 454
 	logg("!Database initialization error: %s\n", cl_strerror(ret));;
455
+	cl_engine_free(engine);
458 456
 	return 50;
459 457
     }
460 458
 
461 459
     /* set limits */
462
-    memset(&limits, 0, sizeof(struct cl_limits));
463 460
 
464 461
     if(opt_check(opt, "max-scansize")) {
465 462
 	char *cpy, *ptr;
... ...
@@ -468,12 +478,17 @@ int scanmanager(const struct optstruct *opt)
468 468
 	    cpy = calloc(strlen(ptr), 1);
469 469
 	    strncpy(cpy, ptr, strlen(ptr) - 1);
470 470
 	    cpy[strlen(ptr)-1]='\0';
471
-	    limits.maxscansize = atoi(cpy) * 1024 * 1024;
471
+	    val64 = atoi(cpy) * 1024 * 1024;
472 472
 	    free(cpy);
473 473
 	} else
474
-	    limits.maxscansize = atoi(ptr) * 1024;
475
-    } else
476
-	limits.maxscansize = 104857600;
474
+	    val64 = atoi(ptr) * 1024;
475
+
476
+	if((ret = cl_engine_set(engine, CL_ENGINE_MAX_SCANSIZE, &val64))) {
477
+	    logg("!cli_engine_set(CL_ENGINE_MAX_SCANSIZE) failed: %s\n", cl_strerror(ret));
478
+	    cl_engine_free(engine);
479
+	    return 50;
480
+	}
481
+    }
477 482
 
478 483
     if(opt_check(opt, "max-filesize")) {
479 484
 	char *cpy, *ptr;
... ...
@@ -482,31 +497,48 @@ int scanmanager(const struct optstruct *opt)
482 482
 	    cpy = calloc(strlen(ptr), 1);
483 483
 	    strncpy(cpy, ptr, strlen(ptr) - 1);
484 484
 	    cpy[strlen(ptr)-1]='\0';
485
-	    limits.maxfilesize = atoi(cpy) * 1024 * 1024;
485
+	    val64 = atoi(cpy) * 1024 * 1024;
486 486
 	    free(cpy);
487 487
 	} else
488
-	    limits.maxfilesize = atoi(ptr) * 1024;
489
-    } else
490
-	limits.maxfilesize = 26214400;
488
+	    val64 = atoi(ptr) * 1024;
489
+
490
+	if((ret = cl_engine_set(engine, CL_ENGINE_MAX_FILESIZE, &val64))) {
491
+	    logg("!cli_engine_set(CL_ENGINE_MAX_FILESIZE) failed: %s\n", cl_strerror(ret));
492
+	    cl_engine_free(engine);
493
+	    return 50;
494
+	}
495
+    }
491 496
 
492 497
 #ifndef C_WINDOWS
493 498
     if(getrlimit(RLIMIT_FSIZE, &rlim) == 0) {
494
-	if((rlim.rlim_max < limits.maxfilesize) || (rlim.rlim_max < limits.maxscansize))
495
-	    logg("^System limit for file size is lower than maxfilesize or maxscansize\n");
499
+	cl_engine_get(engine, CL_ENGINE_MAX_FILESIZE, &val64);
500
+	if(rlim.rlim_max < val64)
501
+	    logg("^System limit for file size is lower than engine->maxfilesize\n");
502
+	cl_engine_get(engine, CL_ENGINE_MAX_SCANSIZE, &val64);
503
+	if(rlim.rlim_max < val64)
504
+	    logg("^System limit for file size is lower than engine->maxscansize\n");
496 505
     } else {
497 506
 	logg("^Cannot obtain resource limits for file size\n");
498 507
     }
499 508
 #endif
500 509
 
501
-    if(opt_check(opt, "max-files"))
502
-	limits.maxfiles = atoi(opt_arg(opt, "max-files"));
503
-    else
504
-        limits.maxfiles = 10000;
510
+    if(opt_check(opt, "max-files")) {
511
+	val32 = atoi(opt_arg(opt, "max-files"));
512
+	if((ret = cl_engine_set(engine, CL_ENGINE_MAX_FILES, &val32))) {
513
+	    logg("!cli_engine_set(CL_ENGINE_MAX_FILES) failed: %s\n", cl_strerror(ret));
514
+	    cl_engine_free(engine);
515
+	    return 50;
516
+	}
517
+    }
505 518
 
506
-    if(opt_check(opt, "max-recursion"))
507
-        limits.maxreclevel = atoi(opt_arg(opt, "max-recursion"));
508
-    else
509
-        limits.maxreclevel = 16;
519
+    if(opt_check(opt, "max-recursion")) {
520
+	val32 = atoi(opt_arg(opt, "max-recursion"));
521
+	if((ret = cl_engine_set(engine, CL_ENGINE_MAX_RECURSION, &val32))) {
522
+	    logg("!cli_engine_set(CL_ENGINE_MAX_RECURSION) failed: %s\n", cl_strerror(ret));
523
+	    cl_engine_free(engine);
524
+	    return 50;
525
+	}
526
+    }
510 527
 
511 528
     /* set options */
512 529
 
... ...
@@ -582,20 +614,27 @@ int scanmanager(const struct optstruct *opt)
582 582
 	    options |= CL_SCAN_STRUCTURED_SSN_NORMAL;
583 583
 	}
584 584
 
585
-	if(opt_check(opt, "structured-ssn-count"))
586
-	    limits.min_ssn_count = atoi(opt_arg(opt, "structured-ssn-count"));
587
-	else
588
-	    limits.min_ssn_count = 3;
585
+	if(opt_check(opt, "structured-ssn-count")) {
586
+	    val32 = atoi(opt_arg(opt, "structured-ssn-count"));
587
+	    if((ret = cl_engine_set(engine, CL_ENGINE_MIN_SSN_COUNT, &val32))) {
588
+		logg("!cli_engine_set(CL_ENGINE_MIN_SSN_COUNT) failed: %s\n", cl_strerror(ret));
589
+		cl_engine_free(engine);
590
+		return 50;
591
+	    }
592
+	}
589 593
 
590
-	if(opt_check(opt, "structured-cc-count"))
591
-	    limits.min_cc_count = atoi(opt_arg(opt, "structured-cc-count"));
592
-	else
593
-	    limits.min_cc_count = 3;
594
+	if(opt_check(opt, "structured-cc-count")) {
595
+	    val32 = atoi(opt_arg(opt, "structured-cc-count"));
596
+	    if((ret = cl_engine_set(engine, CL_ENGINE_MIN_CC_COUNT, &val32))) {
597
+		logg("!cli_engine_set(CL_ENGINE_MIN_CC_COUNT) failed: %s\n", cl_strerror(ret));
598
+		cl_engine_free(engine);
599
+		return 50;
600
+	    }
601
+	}
594 602
 
595 603
     } else
596 604
 	options &= ~CL_SCAN_STRUCTURED;
597 605
 
598
-
599 606
 #ifdef C_LINUX
600 607
     procdev = (dev_t) 0;
601 608
     if(stat("/proc", &sb) != -1 && !sb.st_size)
... ...
@@ -610,10 +649,10 @@ int scanmanager(const struct optstruct *opt)
610 610
 	    logg("!Can't get absolute pathname of current working directory\n");
611 611
 	    ret = 57;
612 612
 	} else
613
-	    ret = scandirs(cwd, engine, opt, &limits, options, 1);
613
+	    ret = scandirs(cwd, engine, opt, options, 1);
614 614
 
615 615
     } else if(!strcmp(opt->filename, "-")) { /* read data from stdin */
616
-	ret = scanstdin(engine, &limits, options);
616
+	ret = scanstdin(engine, options);
617 617
 
618 618
     } else {
619 619
 	for (x = 0; (file = cli_strtok(opt->filename, x, "\t")) != NULL; x++) {
... ...
@@ -633,11 +672,11 @@ int scanmanager(const struct optstruct *opt)
633 633
 
634 634
 		switch(fmode & S_IFMT) {
635 635
 		    case S_IFREG:
636
-			ret = scanfile(file, engine, opt, &limits, options);
636
+			ret = scanfile(file, engine, opt, options);
637 637
 			break;
638 638
 
639 639
 		    case S_IFDIR:
640
-			ret = scandirs(file, engine, opt, &limits, options, 1);
640
+			ret = scandirs(file, engine, opt, options, 1);
641 641
 			break;
642 642
 
643 643
 		    default:
... ...
@@ -650,7 +689,7 @@ int scanmanager(const struct optstruct *opt)
650 650
     }
651 651
 
652 652
     /* free the engine */
653
-    cl_free(engine);
653
+    cl_engine_free(engine);
654 654
 
655 655
     /* overwrite return code */
656 656
     if(info.ifiles)
... ...
@@ -122,12 +122,14 @@ enum cl_engine_field {
122 122
     CL_ENGINE_MAX_FILES,	    /* uint32_t */
123 123
     CL_ENGINE_MIN_CC_COUNT,	    /* uint32_t */
124 124
     CL_ENGINE_MIN_SSN_COUNT,	    /* uint32_t */
125
-    CL_ENGINE_PUA_CATEGORIES	    /* (char *) */
125
+    CL_ENGINE_PUA_CATEGORIES,	    /* (char *) */
126
+    CL_ENGINE_DB_VERSION,	    /* uint32_t */
127
+    CL_ENGINE_DB_TIME		    /* uint32_t */
126 128
 };
127 129
 
128 130
 extern int cl_engine_set(struct cl_engine *engine, enum cl_engine_field field, const void *val);
129 131
 
130
-extern int cl_engine_get(struct cl_engine *engine, enum cl_engine_field field, const void *val);
132
+extern int cl_engine_get(const struct cl_engine *engine, enum cl_engine_field field, void *val);
131 133
 
132 134
 extern int cl_engine_compile(struct cl_engine *engine);
133 135
 
... ...
@@ -264,28 +264,32 @@ int cl_engine_set(struct cl_engine *engine, enum cl_engine_field field, const vo
264 264
 
265 265
     switch(field) {
266 266
 	case CL_ENGINE_MAX_SCANSIZE:
267
-	    engine->maxscansize = *((uint64_t *) val);
267
+	    engine->maxscansize = *((const uint64_t *) val);
268 268
 	    break;
269 269
 	case CL_ENGINE_MAX_FILESIZE:
270
-	    engine->maxfilesize = *((uint64_t *) val);
270
+	    engine->maxfilesize = *((const uint64_t *) val);
271 271
 	    break;
272 272
 	case CL_ENGINE_MAX_RECURSION:
273
-	    engine->maxreclevel = *((uint32_t *) val);
273
+	    engine->maxreclevel = *((const uint32_t *) val);
274 274
 	    break;
275 275
 	case CL_ENGINE_MAX_FILES:
276
-	    engine->maxfiles = *((uint32_t *) val);
276
+	    engine->maxfiles = *((const uint32_t *) val);
277 277
 	    break;
278 278
 	case CL_ENGINE_MIN_CC_COUNT:
279
-	    engine->min_cc_count = *((uint32_t *) val);
279
+	    engine->min_cc_count = *((const uint32_t *) val);
280 280
 	    break;
281 281
 	case CL_ENGINE_MIN_SSN_COUNT:
282
-	    engine->min_ssn_count = *((uint32_t *) val);
282
+	    engine->min_ssn_count = *((const uint32_t *) val);
283 283
 	    break;
284 284
 	case CL_ENGINE_PUA_CATEGORIES:
285
-	    engine->pua_cats = cli_mp_strdup(engine->mempool, (char *) val);
285
+	    engine->pua_cats = cli_mp_strdup(engine->mempool, (const char *) val);
286 286
 	    if(!engine->pua_cats)
287 287
 		return CL_EMEM;
288 288
 	    break;
289
+	case CL_ENGINE_DB_VERSION:
290
+	case CL_ENGINE_DB_TIME:
291
+	    cli_warnmsg("cl_engine_set: The field is read only\n");
292
+	    return CL_SUCCESS;
289 293
 	default:
290 294
 	    cli_errmsg("cl_engine_set: Incorrect field number\n");
291 295
 	    return CL_ENULLARG; /* FIXME */
... ...
@@ -294,7 +298,7 @@ int cl_engine_set(struct cl_engine *engine, enum cl_engine_field field, const vo
294 294
     return CL_SUCCESS;
295 295
 }
296 296
 
297
-int cl_engine_get(struct cl_engine *engine, enum cl_engine_field field, const void *val)
297
+int cl_engine_get(const struct cl_engine *engine, enum cl_engine_field field, void *val)
298 298
 {
299 299
     if(!engine || !val)
300 300
 	return CL_ENULLARG;
... ...
@@ -319,7 +323,14 @@ int cl_engine_get(struct cl_engine *engine, enum cl_engine_field field, const vo
319 319
 	    *((uint32_t *) val) = engine->min_ssn_count;
320 320
 	    break;
321 321
 	case CL_ENGINE_PUA_CATEGORIES:
322
-	    strncpy((char *) val, engine->pua_cats, 128);
322
+	    if(engine->pua_cats)
323
+		strncpy((char *) val, engine->pua_cats, 128);
324
+	    break;
325
+	case CL_ENGINE_DB_VERSION:
326
+	    *((uint32_t *) val) = engine->dbversion[0];
327
+	    break;
328
+	case CL_ENGINE_DB_TIME:
329
+	    *((uint32_t *) val) = engine->dbversion[1];
323 330
 	    break;
324 331
 	default:
325 332
 	    cli_errmsg("cl_engine_get: Incorrect field number\n");
... ...
@@ -71,11 +71,10 @@ struct cfgoption cfg_options[] = {
71 71
     {"ScanOLE2", OPT_BOOL, 1, NULL, 0, OPT_CLAMD},
72 72
     {"ScanPDF", OPT_BOOL, 1, NULL, 0, OPT_CLAMD},
73 73
     {"ScanArchive", OPT_BOOL, 1, NULL, 0, OPT_CLAMD},
74
-    {"MaxScanSize", OPT_COMPSIZE, 104857600, NULL, 0, OPT_CLAMD},
75
-    {"MaxFileSize", OPT_COMPSIZE, 26214400, NULL, 0, OPT_CLAMD},
76
-    {"MaxRecursion", OPT_NUM, 16, NULL, 0, OPT_CLAMD},
77
-    {"MaxFiles", OPT_NUM, 10000, NULL, 0, OPT_CLAMD},
78
-    {"ArchiveLimitMemoryUsage", OPT_BOOL, 0, NULL, 0, OPT_CLAMD},
74
+    {"MaxScanSize", OPT_COMPSIZE, -1, NULL, 0, OPT_CLAMD},
75
+    {"MaxFileSize", OPT_COMPSIZE, -1, NULL, 0, OPT_CLAMD},
76
+    {"MaxRecursion", OPT_NUM, -1, NULL, 0, OPT_CLAMD},
77
+    {"MaxFiles", OPT_NUM, -1, NULL, 0, OPT_CLAMD},
79 78
     {"ArchiveBlockEncrypted", OPT_BOOL, 0, NULL, 0, OPT_CLAMD},
80 79
     {"DatabaseDirectory", OPT_QUOTESTR, -1, DATADIR, 0, OPT_CLAMD | OPT_FRESHCLAM},
81 80
     {"TCPAddr", OPT_QUOTESTR, -1, NULL, 0, OPT_CLAMD},
... ...
@@ -141,6 +140,7 @@ struct cfgoption cfg_options[] = {
141 141
     {"ArchiveMaxFiles", OPT_NUM, 1000, NULL, 0, OPT_CLAMD | OPT_DEPRECATED},
142 142
     {"ArchiveMaxCompressionRatio", OPT_NUM, 250, NULL, 0, OPT_CLAMD | OPT_DEPRECATED},
143 143
     {"ArchiveBlockMax", OPT_BOOL, 0, NULL, 0, OPT_CLAMD | OPT_DEPRECATED},
144
+    {"ArchiveLimitMemoryUsage", OPT_BOOL, 0, NULL, 0, OPT_CLAMD | OPT_DEPRECATED },
144 145
 
145 146
     {NULL, 0, 0, NULL, 0, 0}
146 147
 };
... ...
@@ -540,7 +540,7 @@ static int build(struct optstruct *opt)
540 540
 	unsigned char buffer[FILEBUFF];
541 541
 	char *tarfile, header[513], smbuff[32], builder[32], *pt, olddb[512], patch[32], broken[32];
542 542
 	const char *dbname, *newcvd;
543
-        struct cl_engine *engine = NULL;
543
+        struct cl_engine *engine;
544 544
 	FILE *cvd, *fh;
545 545
 	gzFile *tar;
546 546
 	time_t timet;
... ...
@@ -560,12 +560,17 @@ static int build(struct optstruct *opt)
560 560
 
561 561
     dbname = strstr(opt_arg(opt, "build"), "main") ? "main" : "daily";
562 562
 
563
-    if((ret = cl_load(".", &engine, &sigs, CL_DB_STDOPT | CL_DB_PUA))) {
563
+    if(!(engine = cl_engine_new(CL_ENGINE_DEFAULT))) {
564
+	mprintf("!build: Can't initialize antivirus engine\n");
565
+	return 50;
566
+    }
567
+
568
+    if((ret = cl_load(".", engine, &sigs, CL_DB_STDOPT | CL_DB_PUA))) {
564 569
 	mprintf("!build: Can't load database: %s\n", cl_strerror(ret));
570
+	cl_engine_free(engine);
565 571
 	return -1;
566
-    } else {
567
-	cl_free(engine);
568 572
     }
573
+    cl_engine_free(engine);
569 574
 
570 575
     if(!sigs) {
571 576
 	mprintf("!build: There are no signatures in database files\n");