Browse code

libclamav: drop cl_settempdir(); use cl_engine_set() with CL_ENGINE_TMPDIR and CL_ENGINE_KEEPTMP instead

git-svn: trunk@4416

Tomasz Kojm authored on 2008/11/15 07:23:39
Showing 30 changed files
... ...
@@ -1,3 +1,8 @@
1
+Fri Nov 14 22:24:44 CET 2008 (tk)
2
+---------------------------------
3
+ * libclamav: drop cl_settempdir(); use cl_engine_set() with CL_ENGINE_TMPDIR
4
+	      and CL_ENGINE_KEEPTMP instead
5
+
1 6
 Fri Nov 14 18:40:50 EET 2008 (edwin)
2 7
 ------------------------------------
3 8
  * libclamunrar/unrar.c: avoid rar_malloc warnings on damaged files
... ...
@@ -1815,7 +1815,13 @@ main(int argc, char **argv)
1815 1815
 		/* set the temporary dir */
1816 1816
 		if((cpt = cfgopt(copt, "TemporaryDirectory")) && cpt->enabled) {
1817 1817
 			tmpdir = cpt->strarg;
1818
-			cl_settempdir(tmpdir, (short)(cfgopt(copt, "LeaveTemporaryFiles")->enabled));
1818
+			/*
1819
+			 * FIXME: replace this:
1820
+			  cl_settempdir(tmpdir, (short)(cfgopt(copt, "LeaveTemporaryFiles")->enabled)); *
1821
+			 * with:
1822
+			 * cl_engine_set(engine, CL_ENGINE_TMPDIR, cpt->strarg);
1823
+			 * somewhere...
1824
+			 */
1819 1825
 		} else if((tmpdir = getenv("TMPDIR")) == (char *)NULL)
1820 1826
 			if((tmpdir = getenv("TMP")) == (char *)NULL)
1821 1827
 				if((tmpdir = getenv("TEMP")) == (char *)NULL)
... ...
@@ -5809,7 +5815,7 @@ quit(void)
5809 5809
 #endif
5810 5810
 	}
5811 5811
 
5812
-	if(tmpdir && !cli_leavetemps_flag)
5812
+	if(tmpdir)
5813 5813
 		if(rmdir(tmpdir) < 0)
5814 5814
 			perror(tmpdir);
5815 5815
 
... ...
@@ -293,13 +293,6 @@ int main(int argc, char **argv)
293 293
 	return 1;
294 294
     }
295 295
 
296
-    /* set the temporary dir */
297
-    if((cpt = cfgopt(copt, "TemporaryDirectory"))->enabled)
298
-	cl_settempdir(cpt->strarg, 0);
299
-
300
-    if(cfgopt(copt, "LeaveTemporaryFiles")->enabled)
301
-	cl_settempdir(NULL, 1);
302
-
303 296
     logg("#clamd daemon %s (OS: "TARGET_OS_TYPE", ARCH: "TARGET_ARCH_TYPE", CPU: "TARGET_CPU_TYPE")\n", get_version());
304 297
 
305 298
 #ifndef C_WINDOWS
... ...
@@ -395,6 +388,22 @@ int main(int argc, char **argv)
395 395
 	logg("#Not loading PUA signatures.\n");
396 396
     }
397 397
 
398
+    /* set the temporary dir */
399
+    if((cpt = cfgopt(copt, "TemporaryDirectory"))->enabled) {
400
+	if((ret = cl_engine_set(engine, CL_ENGINE_TMPDIR, cpt->strarg))) {
401
+	    logg("!cli_engine_set(CL_ENGINE_TMPDIR) failed: %s\n", cl_strerror(ret));
402
+	    logg_close();
403
+	    freecfg(copt);
404
+	    cl_engine_free(engine);
405
+	    return 1;
406
+	}
407
+    }
408
+
409
+    if(cfgopt(copt, "LeaveTemporaryFiles")->enabled) {
410
+	val32 = 1;
411
+	cl_engine_set(engine, CL_ENGINE_KEEPTMP, &val32);
412
+    }
413
+
398 414
     if(cfgopt(copt, "PhishingSignatures")->enabled)
399 415
 	dboptions |= CL_DB_PHISHING;
400 416
     else
... ...
@@ -546,7 +546,7 @@ int scanstream(int odesc, unsigned long int *scanned, const struct cl_engine *en
546 546
     snprintf(peer_addr, sizeof(peer_addr), "%s", inet_ntoa(peer.sin_addr));
547 547
     logg("*Accepted connection from %s on port %u, fd %d\n", peer_addr, port, acceptd);
548 548
 
549
-    if(cli_gentempfd(NULL, &tmpname, &tmpd)) {
549
+    if(cli_gentempfd(cfgopt(copt, "TemporaryDirectory")->strarg, &tmpname, &tmpd)) {
550 550
 	shutdown(sockfd, 2);
551 551
 	closesocket(sockfd);
552 552
 	closesocket(acceptd);
... ...
@@ -135,12 +135,6 @@ int main(int argc, char **argv)
135 135
     if(opt_check(opt, "bell"))
136 136
 	bell = 1;
137 137
 
138
-    if(opt_check(opt, "tempdir"))
139
-	cl_settempdir(opt_arg(opt, "tempdir"), 0);
140
-
141
-    if(opt_check(opt, "leave-temps"))
142
-	cl_settempdir(NULL, 1);
143
-
144 138
     /* initialize logger */
145 139
     if(opt_check(opt, "log")) {
146 140
 	logg_file = opt_arg(opt, "log");
... ...
@@ -278,7 +278,7 @@ static int scandirs(const char *dirname, struct cl_engine *engine, const struct
278 278
 
279 279
 }
280 280
 
281
-static int scanstdin(const struct cl_engine *engine, int options)
281
+static int scanstdin(const struct cl_engine *engine, const struct optstruct *opt, int options)
282 282
 {
283 283
 	int ret;
284 284
 	const char *virname, *tmpdir;
... ...
@@ -286,16 +286,19 @@ static int scanstdin(const struct cl_engine *engine, int options)
286 286
 	size_t bread;
287 287
 	FILE *fs;
288 288
 
289
+    if(opt_check(opt, "tempdir")) {
290
+	tmpdir = opt_arg(opt, "tempdir");
291
+    } else {
292
+	/* check write access */
293
+	tmpdir = getenv("TMPDIR");
289 294
 
290
-    /* check write access */
291
-    tmpdir = getenv("TMPDIR");
292
-
293
-    if(tmpdir == NULL)
295
+	if(tmpdir == NULL)
294 296
 #ifdef P_tmpdir
295
-	tmpdir = P_tmpdir;
297
+	    tmpdir = P_tmpdir;
296 298
 #else
297
-	tmpdir = "/tmp";
299
+	    tmpdir = "/tmp";
298 300
 #endif
301
+    }
299 302
 
300 303
     if(checkaccess(tmpdir, CLAMAVUSER, W_OK) != 1) {
301 304
 	logg("!Can't write to temporary directory\n");
... ...
@@ -349,6 +352,7 @@ int scanmanager(const struct optstruct *opt)
349 349
 	struct cl_engine *engine;
350 350
 	struct stat sb;
351 351
 	char *file, cwd[1024], *pua_cats = NULL, *argument;
352
+	const char *pt;
352 353
 	const struct optnode *optnode;
353 354
 #ifndef C_WINDOWS
354 355
 	struct rlimit rlim;
... ...
@@ -448,6 +452,20 @@ int scanmanager(const struct optstruct *opt)
448 448
 	cl_engine_set(engine, CL_ENGINE_AC_MAXDEPTH, &val32);
449 449
     }
450 450
 
451
+    if(opt_check(opt, "leave-temps")) {
452
+	val32 = 1;
453
+	cl_engine_set(engine, CL_ENGINE_KEEPTMP, &val32);
454
+    }
455
+
456
+    if(opt_check(opt, "tempdir")) {
457
+	pt = opt_arg(opt, "tempdir");
458
+	if((ret = cl_engine_set(engine, CL_ENGINE_TMPDIR, pt))) {
459
+	    logg("!cli_engine_set(CL_ENGINE_TMPDIR) failed: %s\n", cl_strerror(ret));
460
+	    cl_engine_free(engine);
461
+	    return 50;
462
+	}
463
+    }
464
+
451 465
     if(opt_check(opt, "database")) {
452 466
 	if((ret = cl_load(opt_arg(opt, "database"), engine, &info.sigs, dboptions))) {
453 467
 	    logg("!%s\n", cl_strerror(ret));
... ...
@@ -656,7 +674,7 @@ int scanmanager(const struct optstruct *opt)
656 656
 	    ret = scandirs(cwd, engine, opt, options, 1);
657 657
 
658 658
     } else if(!strcmp(opt->filename, "-")) { /* read data from stdin */
659
-	ret = scanstdin(engine, options);
659
+	ret = scanstdin(engine, opt, options);
660 660
 
661 661
     } else {
662 662
 	for (x = 0; (file = cli_strtok(opt->filename, x, "\t")) != NULL; x++) {
... ...
@@ -367,19 +367,19 @@ static int ea05(int desc, cli_ctx *ctx, char *tmpd) {
367 367
       return CL_EIO;
368 368
     }
369 369
     free(UNP.outputbuf);
370
-    if(cli_leavetemps_flag)
370
+    if(ctx->engine->keeptmp)
371 371
       cli_dbgmsg("autoit: file extracted to %s\n", tempfile);
372 372
     else 
373 373
       cli_dbgmsg("autoit: file successfully extracted\n");
374 374
     lseek(i, 0, SEEK_SET);
375 375
     if(cli_magic_scandesc(i, ctx) == CL_VIRUS) {
376 376
       close(i);
377
-      if(!cli_leavetemps_flag)
377
+      if(!ctx->engine->keeptmp)
378 378
         if(cli_unlink(tempfile)) return CL_EIO;
379 379
       return CL_VIRUS;
380 380
     }
381 381
     close(i);
382
-    if(!cli_leavetemps_flag) 
382
+    if(!ctx->engine->keeptmp) 
383 383
       if (cli_unlink(tempfile)) return CL_EIO;
384 384
   }
385 385
   return ret;
... ...
@@ -877,19 +877,19 @@ static int ea06(int desc, cli_ctx *ctx, char *tmpd) {
877 877
       return CL_EIO;
878 878
     }
879 879
     free(buf);
880
-    if(cli_leavetemps_flag)
880
+    if(ctx->engine->keeptmp)
881 881
       cli_dbgmsg("autoit: %s extracted to %s\n", (script)?"script":"file", tempfile);
882 882
     else 
883 883
       cli_dbgmsg("autoit: %s successfully extracted\n", (script)?"script":"file");
884 884
     lseek(i, 0, SEEK_SET);
885 885
     if(cli_magic_scandesc(i, ctx) == CL_VIRUS) {
886 886
       close(i);
887
-      if(!cli_leavetemps_flag) 
887
+      if(!ctx->engine->keeptmp) 
888 888
         if (cli_unlink(tempfile)) return CL_EIO;
889 889
       return CL_VIRUS;
890 890
     }
891 891
     close(i);
892
-    if(!cli_leavetemps_flag)
892
+    if(!ctx->engine->keeptmp)
893 893
       if (cli_unlink(tempfile)) return CL_EIO;
894 894
   }
895 895
   return ret;
... ...
@@ -912,14 +912,14 @@ int cli_scanautoit(int desc, cli_ctx *ctx, off_t offset) {
912 912
 
913 913
   cli_dbgmsg("in scanautoit()\n");
914 914
 
915
-  if (!(tmpd = cli_gentemp(NULL)))    
915
+  if (!(tmpd = cli_gentemp(ctx->engine->tmpdir)))    
916 916
     return CL_ETMPDIR;
917 917
   if (mkdir(tmpd, 0700)) {
918 918
     cli_dbgmsg("autoit: Can't create temporary directory %s\n", tmpd);
919 919
     free(tmpd);
920 920
     return CL_ETMPDIR;
921 921
   }
922
-  if (cli_leavetemps_flag)
922
+  if (ctx->engine->keeptmp)
923 923
     cli_dbgmsg("autoit: Extracting files to %s\n", tmpd);
924 924
 
925 925
   switch(version) {
... ...
@@ -940,7 +940,7 @@ int cli_scanautoit(int desc, cli_ctx *ctx, off_t offset) {
940 940
     r = CL_CLEAN;
941 941
   }
942 942
 
943
-  if (!cli_leavetemps_flag)
943
+  if (!ctx->engine->keeptmp)
944 944
     cli_rmdirs(tmpd);
945 945
 
946 946
   free(tmpd);
... ...
@@ -407,7 +407,7 @@ fileblobCreate(void)
407 407
 int
408 408
 fileblobScanAndDestroy(fileblob *fb)
409 409
 {
410
-	if(cli_leavetemps_flag) {
410
+	if(fb->ctx && fb->ctx->engine->keeptmp) {
411 411
 		/* Can't remove the file, the caller must scan */
412 412
 		fileblobDestroy(fb);
413 413
 		return CL_CLEAN;
... ...
@@ -509,7 +509,7 @@ fileblobPartialSet(fileblob *fb, const char *fullname, const char *arg)
509 509
 		close(fb->fd);
510 510
 		return;
511 511
 	}
512
-	blobSetFilename(&fb->b, NULL, fullname);
512
+	blobSetFilename(&fb->b, fb->ctx ? fb->ctx->engine->tmpdir : NULL, fullname);
513 513
 	if(fb->b.data)
514 514
 		if(fileblobAddData(fb, fb->b.data, fb->b.len) == 0) {
515 515
 			free(fb->b.data);
... ...
@@ -122,7 +122,9 @@ enum cl_engine_field {
122 122
     CL_ENGINE_DB_TIME,		    /* uint32_t */
123 123
     CL_ENGINE_AC_ONLY,		    /* uint32_t */
124 124
     CL_ENGINE_AC_MINDEPTH,	    /* uint32_t */
125
-    CL_ENGINE_AC_MAXDEPTH	    /* uint32_t */
125
+    CL_ENGINE_AC_MAXDEPTH,	    /* uint32_t */
126
+    CL_ENGINE_TMPDIR,		    /* (char *) */
127
+    CL_ENGINE_KEEPTMP		    /* 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);
... ...
@@ -184,7 +186,6 @@ extern unsigned int cl_retflevel(void);
184 184
 extern const char *cl_retver(void);
185 185
 
186 186
 /* others */
187
-extern void cl_settempdir(const char *dir, short leavetemps);
188 187
 extern const char *cl_strerror(int clerror);
189 188
 
190 189
 #ifdef __cplusplus
... ...
@@ -554,7 +554,7 @@ int cli_cvdload(FILE *fs, struct cl_engine *engine, unsigned int *signo, unsigne
554 554
 
555 555
     } else {
556 556
 
557
-	if(!(dir = cli_gentemp(NULL)))
557
+	if(!(dir = cli_gentemp(engine->tmpdir)))
558 558
 	    return CL_EMEM;
559 559
 
560 560
 	if(mkdir(dir, 0700)) {
... ...
@@ -18,7 +18,6 @@ CLAMAV_PUBLIC {
18 18
     cl_retver;
19 19
     cl_scandesc;
20 20
     cl_scanfile;
21
-    cl_settempdir;
22 21
     cl_statchkdir;
23 22
     cl_statfree;
24 23
     cl_statinidir;
... ...
@@ -3870,7 +3870,7 @@ rfc1341(message *m, const char *dir)
3870 3870
 
3871 3871
 					if(!dentry_idpart ||
3872 3872
 							strcmp(filename, dentry_idpart) != 0) {
3873
-						if(!cli_leavetemps_flag)
3873
+						if(!m->ctx->engine->keeptmp)
3874 3874
 							continue;
3875 3875
 						if(stat(fullname, &statb) < 0)
3876 3876
 							continue;
... ...
@@ -3925,7 +3925,7 @@ rfc1341(message *m, const char *dir)
3925 3925
 					fclose(fin);
3926 3926
 
3927 3927
 					/* don't unlink if leave temps */
3928
-					if(!cli_leavetemps_flag) {
3928
+					if(!m->ctx->engine->keeptmp) {
3929 3929
 						if(cli_unlink(fullname)) {
3930 3930
 							fclose(fout);
3931 3931
 							cli_unlink(outname);
... ...
@@ -537,7 +537,7 @@ int cli_scannulsft(int desc, cli_ctx *ctx, off_t offset) {
537 537
 
538 538
     nsist.ifd = desc;
539 539
     nsist.off = offset;
540
-    if (!(nsist.dir = cli_gentemp(NULL)))
540
+    if (!(nsist.dir = cli_gentemp(ctx->engine->tmpdir)))
541 541
         return CL_ETMPDIR;
542 542
     if(mkdir(nsist.dir, 0700)) {
543 543
 	cli_dbgmsg("NSIS: Can't create temporary directory %s\n", nsist.dir);
... ...
@@ -545,7 +545,7 @@ int cli_scannulsft(int desc, cli_ctx *ctx, off_t offset) {
545 545
 	return CL_ETMPDIR;
546 546
     }
547 547
 
548
-    if(cli_leavetemps_flag) cli_dbgmsg("NSIS: Extracting files to %s\n", nsist.dir);
548
+    if(ctx->engine->keeptmp) cli_dbgmsg("NSIS: Extracting files to %s\n", nsist.dir);
549 549
 
550 550
     do {
551 551
         ret = cli_nsis_unpack(&nsist, ctx);
... ...
@@ -557,7 +557,7 @@ int cli_scannulsft(int desc, cli_ctx *ctx, off_t offset) {
557 557
 	  else
558 558
 	    ret=cli_magic_scandesc(nsist.ofd, ctx);
559 559
 	  close(nsist.ofd);
560
-	  if(!cli_leavetemps_flag)
560
+	  if(!ctx->engine->keeptmp)
561 561
 	    if(cli_unlink(nsist.ofn)) ret = CL_EIO;
562 562
 	} else if(ret == CL_EMAXSIZE) {
563 563
 	    ret = nsist.solid ? CL_BREAK : CL_SUCCESS;
... ...
@@ -569,7 +569,7 @@ int cli_scannulsft(int desc, cli_ctx *ctx, off_t offset) {
569 569
 
570 570
     cli_nsis_free(&nsist);
571 571
 
572
-    if(!cli_leavetemps_flag)
572
+    if(!ctx->engine->keeptmp)
573 573
         cli_rmdirs(nsist.dir);
574 574
 
575 575
     free(nsist.dir);
... ...
@@ -715,7 +715,7 @@ static int handler_otf(int fd, ole2_header_t *hdr, property_t *prop, const char
715 715
 
716 716
   print_ole2_property(prop);
717 717
 
718
-  if(!(tempfile = cli_gentemp(NULL)))
718
+  if(!(tempfile = cli_gentemp(ctx ? ctx->engine->tmpdir : NULL)))
719 719
     return CL_EMEM;
720 720
 
721 721
   if((ofd = open(tempfile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IRWXU)) < 0) {
... ...
@@ -813,7 +813,7 @@ static int handler_otf(int fd, ole2_header_t *hdr, property_t *prop, const char
813 813
   close(ofd);
814 814
   free(buff);
815 815
   cli_bitset_free(blk_bitset);
816
-  if(!cli_leavetemps_flag) {
816
+  if(ctx && !ctx->engine->keeptmp) {
817 817
     if (cli_unlink(tempfile)) {
818 818
       free(tempfile);
819 819
       return CL_EIO;
... ...
@@ -94,7 +94,7 @@ static pthread_mutex_t cli_ctime_mutex = PTHREAD_MUTEX_INITIALIZER;
94 94
 
95 95
 #define CL_FLEVEL 37 /* don't touch it */
96 96
 
97
-uint8_t cli_debug_flag = 0, cli_leavetemps_flag = 0;
97
+uint8_t cli_debug_flag = 0;
98 98
 
99 99
 #ifndef CLI_MEMFUNSONLY
100 100
 static unsigned char name_salt[16] = { 16, 38, 97, 12, 8, 4, 72, 196, 217, 144, 33, 124, 18, 11, 17, 253 };
... ...
@@ -337,6 +337,14 @@ int cl_engine_set(struct cl_engine *engine, enum cl_engine_field field, const vo
337 337
 	case CL_ENGINE_AC_MAXDEPTH:
338 338
 	    engine->ac_maxdepth = *((const uint32_t *) val);
339 339
 	    break;
340
+	case CL_ENGINE_TMPDIR:
341
+	    engine->tmpdir = cli_mp_strdup(engine->mempool, (const char *) val);
342
+	    if(!engine->tmpdir)
343
+		return CL_EMEM;
344
+	    break;
345
+	case CL_ENGINE_KEEPTMP:
346
+	    engine->keeptmp = *((const uint32_t *) val);
347
+	    break;
340 348
 	default:
341 349
 	    cli_errmsg("cl_engine_set: Incorrect field number\n");
342 350
 	    return CL_ENULLARG; /* FIXME */
... ...
@@ -388,6 +396,13 @@ int cl_engine_get(const struct cl_engine *engine, enum cl_engine_field field, vo
388 388
 	case CL_ENGINE_AC_MAXDEPTH:
389 389
 	    *((uint32_t *) val) = engine->ac_maxdepth;
390 390
 	    break;
391
+	case CL_ENGINE_TMPDIR:
392
+	    if(engine->tmpdir)
393
+		strncpy((char *) val, engine->tmpdir, 128);
394
+	    break;
395
+	case CL_ENGINE_KEEPTMP:
396
+	    *((uint32_t *) val) = engine->keeptmp;
397
+	    break;
391 398
 	default:
392 399
 	    cli_errmsg("cl_engine_get: Incorrect field number\n");
393 400
 	    return CL_ENULLARG; /* FIXME */
... ...
@@ -661,24 +676,6 @@ unsigned int cli_rndnum(unsigned int max)
661 661
     return 1 + (unsigned int) (max * (rand() / (1.0 + RAND_MAX)));
662 662
 }
663 663
 
664
-void cl_settempdir(const char *dir, short leavetemps)
665
-{
666
-	char *var;
667
-
668
-    if(dir) {
669
-	var = (char *) cli_malloc(8 + strlen(dir));
670
-	sprintf(var, "TMPDIR=%s", dir);
671
-	if(!putenv(var))
672
-	    cli_dbgmsg("Setting %s as global temporary directory\n", dir);
673
-	else
674
-	    cli_warnmsg("Can't set TMPDIR variable - insufficient space in the environment.\n");
675
-
676
-	/* WARNING: var must not be released - see putenv(3) */
677
-    }
678
-
679
-    cli_leavetemps_flag = leavetemps;
680
-}
681
-
682 664
 char *cli_gentemp(const char *dir)
683 665
 {
684 666
 	char *name, *tmp;
... ...
@@ -35,7 +35,7 @@
35 35
 #include "dconf.h"
36 36
 #include "libclamunrar_iface/unrar_iface.h"
37 37
 
38
-extern uint8_t cli_debug_flag, cli_leavetemps_flag;
38
+extern uint8_t cli_debug_flag;
39 39
 
40 40
 /*
41 41
  * CLI_ISCONTAINED(buf1, size1, buf2, size2) checks if buf2 is contained
... ...
@@ -100,6 +100,8 @@ struct cl_engine {
100 100
     uint32_t ac_only;
101 101
     uint32_t ac_mindepth;
102 102
     uint32_t ac_maxdepth;
103
+    char *tmpdir;
104
+    uint32_t keeptmp;
103 105
 
104 106
     /* Limits */
105 107
     uint64_t maxscansize;  /* during the scanning of archives this size
... ...
@@ -544,7 +544,7 @@ cli_pdf(const char *dir, int desc, cli_ctx *ctx, off_t offset)
544 544
 			rc = cli_magic_scandesc(fout, ctx);
545 545
 		}
546 546
 		close(fout);
547
-		if(!cli_leavetemps_flag)
547
+		if(!ctx->engine->keeptmp)
548 548
 			if (cli_unlink(fullname)) rc = CL_EIO;
549 549
 		if(rc != CL_CLEAN) break;
550 550
 	}
... ...
@@ -91,7 +91,7 @@ if(cli_checklimits(NAME, ctx, (CHK), 0, 0)!=CL_CLEAN) {	\
91 91
 }
92 92
 
93 93
 #define CLI_UNPTEMP(NAME,FREEME) \
94
-if(!(tempfile = cli_gentemp(NULL))) { \
94
+if(!(tempfile = cli_gentemp(ctx->engine->tmpdir))) { \
95 95
     cli_multifree FREEME; \
96 96
     return CL_EMEM; \
97 97
 } \
... ...
@@ -102,7 +102,7 @@ if((ndesc = open(tempfile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IRWXU)) < 0) { \
102 102
     return CL_EIO; \
103 103
 }
104 104
 
105
-#define CLI_TMPUNLK() if(!cli_leavetemps_flag) { \
105
+#define CLI_TMPUNLK() if(!ctx->engine->keeptmp) { \
106 106
     if (cli_unlink(tempfile)) { \
107 107
 	free(tempfile); \
108 108
 	return CL_EIO; \
... ...
@@ -141,7 +141,7 @@ if((ndesc = open(tempfile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IRWXU)) < 0) { \
141 141
 #define CLI_UNPRESULTS_(NAME,FSGSTUFF,EXPR,GOOD,FREEME) \
142 142
     switch(EXPR) { \
143 143
     case GOOD: /* Unpacked and rebuilt */ \
144
-	if(cli_leavetemps_flag) \
144
+	if(ctx->engine->keeptmp) \
145 145
 	    cli_dbgmsg(NAME": Unpacked and rebuilt executable saved in %s\n", tempfile); \
146 146
 	else \
147 147
 	    cli_dbgmsg(NAME": Unpacked and rebuilt executable\n"); \
... ...
@@ -1788,7 +1788,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
1788 1788
 	free(dest);
1789 1789
 	lseek(ndesc, 0, SEEK_SET);
1790 1790
 
1791
-	if(cli_leavetemps_flag)
1791
+	if(ctx->engine->keeptmp)
1792 1792
 	    cli_dbgmsg("UPX/FSG: Decompressed data saved in %s\n", tempfile);
1793 1793
 
1794 1794
 	cli_dbgmsg("***** Scanning decompressed file *****\n");
... ...
@@ -1981,6 +1981,9 @@ int cl_engine_free(struct cl_engine *engine)
1981 1981
     if(engine->pua_cats)
1982 1982
 	mp_free(engine->mempool, engine->pua_cats);
1983 1983
 
1984
+    if(engine->tmpdir)
1985
+	mp_free(engine->mempool, engine->tmpdir);
1986
+
1984 1987
     cli_ftfree(engine);
1985 1988
     cli_freeign(engine);
1986 1989
 #ifdef USE_MPOOL
... ...
@@ -246,7 +246,7 @@ static int decode_and_scan(struct rtf_object_data* data, cli_ctx* ctx)
246 246
 	close(data->fd);
247 247
 	data->fd = -1;
248 248
 	if(data->name) {
249
-		if(!cli_leavetemps_flag)
249
+		if(!ctx->engine->keeptmp)
250 250
 			if(cli_unlink(data->name)) ret = CL_EIO;
251 251
 		free(data->name);
252 252
 		data->name = NULL;
... ...
@@ -494,7 +494,7 @@ static void cleanup_stack(struct stack* stack,struct rtf_state* state,cli_ctx* c
494 494
 	tableDestroy(actiontable);\
495 495
 	cleanup_stack(&stack,&state,ctx);\
496 496
 	free(buff);\
497
-        if(!cli_leavetemps_flag)\
497
+        if(!ctx->engine->keeptmp)\
498 498
 		cli_rmdirs(tempname);\
499 499
 	free(tempname);\
500 500
 	free(stack.states);
... ...
@@ -534,7 +534,7 @@ int cli_scanrtf(int desc, cli_ctx *ctx)
534 534
 		return CL_EMEM;
535 535
 	}
536 536
 
537
-	if(!(tempname = cli_gentemp(NULL)))
537
+	if(!(tempname = cli_gentemp(ctx->engine->tmpdir)))
538 538
 	    return CL_EMEM;
539 539
 
540 540
 	if(mkdir(tempname, 0700)) {
... ...
@@ -550,7 +550,7 @@ int cli_scanrtf(int desc, cli_ctx *ctx)
550 550
 		cli_dbgmsg("RTF: Unable to load rtf action table\n");
551 551
 		free(stack.states);
552 552
 		free(buff);
553
-		if(!cli_leavetemps_flag)
553
+		if(!ctx->engine->keeptmp)
554 554
 			cli_rmdirs(tempname);
555 555
 		free(tempname);
556 556
 		tableDestroy(actiontable);
... ...
@@ -274,7 +274,7 @@ static int cli_scanrar(int desc, cli_ctx *ctx, off_t sfx_offset, uint32_t *sfx_c
274 274
 	    return CL_EIO;
275 275
 
276 276
     /* generate the temporary directory */
277
-    if(!(dir = cli_gentemp(NULL)))
277
+    if(!(dir = cli_gentemp(ctx->engine->tmpdir)))
278 278
 	return CL_EMEM;
279 279
 
280 280
     if(mkdir(dir, 0700)) {
... ...
@@ -284,7 +284,7 @@ static int cli_scanrar(int desc, cli_ctx *ctx, off_t sfx_offset, uint32_t *sfx_c
284 284
     }
285 285
 
286 286
     if((ret = cli_unrar_open(desc, dir, &rar_state)) != UNRAR_OK) {
287
-	if(!cli_leavetemps_flag)
287
+	if(!ctx->engine->keeptmp)
288 288
 	    cli_rmdirs(dir);
289 289
 	free(dir);
290 290
 	if(ret == UNRAR_PASSWD) {
... ...
@@ -335,7 +335,7 @@ static int cli_scanrar(int desc, cli_ctx *ctx, off_t sfx_offset, uint32_t *sfx_c
335 335
 	    lseek(rar_state.ofd,0,SEEK_SET);
336 336
 	    rc = cli_magic_scandesc(rar_state.ofd,ctx);
337 337
 	    close(rar_state.ofd);
338
-	    if(!cli_leavetemps_flag) 
338
+	    if(!ctx->engine->keeptmp) 
339 339
 		if (cli_unlink(rar_state.filename)) ret = CL_EIO;
340 340
 	    if(rc == CL_VIRUS ) {
341 341
 		cli_dbgmsg("RAR: infected with %s\n",*ctx->virname);
... ...
@@ -359,7 +359,7 @@ static int cli_scanrar(int desc, cli_ctx *ctx, off_t sfx_offset, uint32_t *sfx_c
359 359
 
360 360
     cli_unrar_close(&rar_state);
361 361
 
362
-    if(!cli_leavetemps_flag)
362
+    if(!ctx->engine->keeptmp)
363 363
         cli_rmdirs(dir);
364 364
 
365 365
     free(dir);
... ...
@@ -385,7 +385,7 @@ static int cli_scanarj(int desc, cli_ctx *ctx, off_t sfx_offset, uint32_t *sfx_c
385 385
     cli_dbgmsg("in cli_scanarj()\n");
386 386
 
387 387
      /* generate the temporary directory */
388
-    if(!(dir = cli_gentemp(NULL)))
388
+    if(!(dir = cli_gentemp(ctx->engine->tmpdir)))
389 389
 	return CL_EMEM;
390 390
 
391 391
     if(mkdir(dir, 0700)) {
... ...
@@ -399,7 +399,7 @@ static int cli_scanarj(int desc, cli_ctx *ctx, off_t sfx_offset, uint32_t *sfx_c
399 399
 
400 400
     ret = cli_unarj_open(desc, dir);
401 401
     if (ret != CL_SUCCESS) {
402
-	if(!cli_leavetemps_flag)
402
+	if(!ctx->engine->keeptmp)
403 403
 	    cli_rmdirs(dir);
404 404
 	free(dir);
405 405
 	cli_dbgmsg("ARJ: Error: %s\n", cl_strerror(ret));
... ...
@@ -435,7 +435,7 @@ static int cli_scanarj(int desc, cli_ctx *ctx, off_t sfx_offset, uint32_t *sfx_c
435 435
 
436 436
     } while(ret == CL_SUCCESS);
437 437
     
438
-    if(!cli_leavetemps_flag)
438
+    if(!ctx->engine->keeptmp)
439 439
 	cli_rmdirs(dir);
440 440
 
441 441
     free(dir);
... ...
@@ -466,7 +466,7 @@ static int cli_scangzip(int desc, cli_ctx *ctx)
466 466
 	return CL_EGZIP;
467 467
     }
468 468
 
469
-    if((ret = cli_gentempfd(NULL, &tmpname, &fd))) {
469
+    if((ret = cli_gentempfd(ctx->engine->tmpdir, &tmpname, &fd))) {
470 470
 	cli_dbgmsg("GZip: Can't generate temporary file.\n");
471 471
 	gzclose(gd);
472 472
 	return ret;
... ...
@@ -476,7 +476,7 @@ static int cli_scangzip(int desc, cli_ctx *ctx)
476 476
 	cli_dbgmsg("GZip: Unable to malloc %u bytes.\n", FILEBUFF);
477 477
 	gzclose(gd);
478 478
 	close(fd);
479
-	if(!cli_leavetemps_flag) {
479
+	if(!ctx->engine->keeptmp) {
480 480
 	    if(cli_unlink(tmpname)) {
481 481
 	    	free(tmpname);
482 482
 		return CL_EIO;
... ...
@@ -494,7 +494,7 @@ static int cli_scangzip(int desc, cli_ctx *ctx)
494 494
 	if(cli_writen(fd, buff, bytes) != bytes) {
495 495
 	    cli_dbgmsg("GZip: Can't write to file.\n");
496 496
 	    close(fd);
497
-	    if(!cli_leavetemps_flag) {
497
+	    if(!ctx->engine->keeptmp) {
498 498
 	    	if (cli_unlink(tmpname)) {
499 499
 		    free(tmpname);
500 500
 		    gzclose(gd);
... ...
@@ -514,7 +514,7 @@ static int cli_scangzip(int desc, cli_ctx *ctx)
514 514
 
515 515
     if(ret == CL_VIRUS) {
516 516
 	close(fd);
517
-	if(!cli_leavetemps_flag)
517
+	if(!ctx->engine->keeptmp)
518 518
 	    if (cli_unlink(tmpname)) ret = CL_EIO;
519 519
 	free(tmpname);	
520 520
 	return ret;
... ...
@@ -524,7 +524,7 @@ static int cli_scangzip(int desc, cli_ctx *ctx)
524 524
     if((ret = cli_magic_scandesc(fd, ctx)) == CL_VIRUS ) {
525 525
 	cli_dbgmsg("GZip: Infected with %s\n", *ctx->virname);
526 526
 	close(fd);
527
-	if(!cli_leavetemps_flag) {
527
+	if(!ctx->engine->keeptmp) {
528 528
 	    if (cli_unlink(tmpname)) {
529 529
 	    	free(tmpname);
530 530
 		return CL_EIO;
... ...
@@ -534,7 +534,7 @@ static int cli_scangzip(int desc, cli_ctx *ctx)
534 534
 	return CL_VIRUS;
535 535
     }
536 536
     close(fd);
537
-    if(!cli_leavetemps_flag)
537
+    if(!ctx->engine->keeptmp)
538 538
 	if (cli_unlink(tmpname)) ret = CL_EIO;
539 539
     free(tmpname);	
540 540
 
... ...
@@ -577,7 +577,7 @@ static int cli_scanbzip(int desc, cli_ctx *ctx)
577 577
 	return CL_EBZIP;
578 578
     }
579 579
 
580
-    if((ret = cli_gentempfd(NULL, &tmpname, &fd))) {
580
+    if((ret = cli_gentempfd(ctx->engine->tmpdir, &tmpname, &fd))) {
581 581
 	cli_dbgmsg("Bzip: Can't generate temporary file.\n");
582 582
 	BZ2_bzReadClose(&bzerror, bfd);
583 583
 	fclose(fs);
... ...
@@ -587,7 +587,7 @@ static int cli_scanbzip(int desc, cli_ctx *ctx)
587 587
     if(!(buff = (char *) cli_malloc(FILEBUFF))) {
588 588
 	cli_dbgmsg("Bzip: Unable to malloc %u bytes.\n", FILEBUFF);
589 589
 	close(fd);
590
-	if(!cli_leavetemps_flag) {
590
+	if(!ctx->engine->keeptmp) {
591 591
 	    if (cli_unlink(tmpname)) {
592 592
 	    	free(tmpname);
593 593
 		fclose(fs);
... ...
@@ -611,7 +611,7 @@ static int cli_scanbzip(int desc, cli_ctx *ctx)
611 611
 	    cli_dbgmsg("Bzip: Can't write to file.\n");
612 612
 	    BZ2_bzReadClose(&bzerror, bfd);
613 613
 	    close(fd);
614
-	    if(!cli_leavetemps_flag) {
614
+	    if(!ctx->engine->keeptmp) {
615 615
 		if (cli_unlink(tmpname)) {
616 616
 		    free(tmpname);
617 617
 		    free(buff);
... ...
@@ -631,7 +631,7 @@ static int cli_scanbzip(int desc, cli_ctx *ctx)
631 631
 
632 632
     if(ret == CL_VIRUS) {
633 633
 	close(fd);
634
-	if(!cli_leavetemps_flag)
634
+	if(!ctx->engine->keeptmp)
635 635
 	    if (cli_unlink(tmpname)) ret = CL_EIO;
636 636
 	free(tmpname);	
637 637
 	fclose(fs);
... ...
@@ -643,7 +643,7 @@ static int cli_scanbzip(int desc, cli_ctx *ctx)
643 643
 	cli_dbgmsg("Bzip: Infected with %s\n", *ctx->virname);
644 644
     }
645 645
     close(fd);
646
-    if(!cli_leavetemps_flag)
646
+    if(!ctx->engine->keeptmp)
647 647
 	if (cli_unlink(tmpname)) ret = CL_EIO;
648 648
     free(tmpname);	
649 649
     fclose(fs);
... ...
@@ -660,7 +660,7 @@ static int cli_scanszdd(int desc, cli_ctx *ctx)
660 660
 
661 661
     cli_dbgmsg("in cli_scanszdd()\n");
662 662
 
663
-    if((ret = cli_gentempfd(NULL, &tmpname, &ofd))) {
663
+    if((ret = cli_gentempfd(ctx->engine->tmpdir, &tmpname, &ofd))) {
664 664
 	cli_dbgmsg("MSEXPAND: Can't generate temporary file/descriptor\n");
665 665
 	return ret;
666 666
     }
... ...
@@ -670,7 +670,7 @@ static int cli_scanszdd(int desc, cli_ctx *ctx)
670 670
 
671 671
     if(ret != CL_SUCCESS) { /* CL_VIRUS or some error */
672 672
 	close(ofd);
673
-	if(!cli_leavetemps_flag)
673
+	if(!ctx->engine->keeptmp)
674 674
 	    if (cli_unlink(tmpname)) ret = CL_EIO;
675 675
 	free(tmpname);	
676 676
 	return ret;
... ...
@@ -680,7 +680,7 @@ static int cli_scanszdd(int desc, cli_ctx *ctx)
680 680
     lseek(ofd, 0, SEEK_SET);
681 681
     ret = cli_magic_scandesc(ofd, ctx);
682 682
     close(ofd);
683
-    if(!cli_leavetemps_flag)
683
+    if(!ctx->engine->keeptmp)
684 684
 	if (cli_unlink(tmpname)) ret = CL_EIO;
685 685
     free(tmpname);	
686 686
 
... ...
@@ -707,7 +707,7 @@ static int cli_scanmscab(int desc, cli_ctx *ctx, off_t sfx_offset)
707 707
 	if(cli_checklimits("CAB", ctx, file->length, 0, 0)!=CL_CLEAN)
708 708
 	    continue;
709 709
 
710
-	if(!(tempname = cli_gentemp(NULL))) {
710
+	if(!(tempname = cli_gentemp(ctx->engine->tmpdir))) {
711 711
 	    ret = CL_EMEM;
712 712
 	    break;
713 713
 	}
... ...
@@ -717,7 +717,7 @@ static int cli_scanmscab(int desc, cli_ctx *ctx, off_t sfx_offset)
717 717
 	else
718 718
 	    ret = cli_scanfile(tempname, ctx);
719 719
 
720
-	if(!cli_leavetemps_flag) {
720
+	if(!ctx->engine->keeptmp) {
721 721
 	    if (cli_unlink(tempname)) {
722 722
 	    	free(tempname);
723 723
 		ret = CL_EIO;
... ...
@@ -797,11 +797,11 @@ static int cli_vba_scandir(const char *dirname, cli_ctx *ctx, struct uniq *U)
797 797
 	    vbaname[sizeof(vbaname)-1] = '\0';
798 798
 	    fd = open(vbaname, O_RDONLY|O_BINARY);
799 799
 	    if (fd == -1) continue;
800
-	    if ((fullname = cli_ppt_vba_read(fd))) {
800
+	    if ((fullname = cli_ppt_vba_read(fd, ctx))) {
801 801
 		if(cli_scandir(fullname, ctx, 0) == CL_VIRUS) {
802 802
 		    ret = CL_VIRUS;
803 803
 		}
804
-		if(!cli_leavetemps_flag)
804
+		if(!ctx->engine->keeptmp)
805 805
 		    cli_rmdirs(fullname);
806 806
 		free(fullname);
807 807
 	    }
... ...
@@ -940,7 +940,7 @@ static int cli_scanhtml(int desc, cli_ctx *ctx)
940 940
 	return CL_CLEAN;
941 941
     }
942 942
 
943
-    if(!(tempname = cli_gentemp(NULL)))
943
+    if(!(tempname = cli_gentemp(ctx->engine->tmpdir)))
944 944
 	return CL_EMEM;
945 945
 
946 946
     if(mkdir(tempname, 0700)) {
... ...
@@ -988,7 +988,7 @@ static int cli_scanhtml(int desc, cli_ctx *ctx)
988 988
 	ret = cli_scandir(fullname, ctx, 0);
989 989
     }
990 990
 
991
-    if(!cli_leavetemps_flag)
991
+    if(!ctx->engine->keeptmp)
992 992
         cli_rmdirs(tempname);
993 993
 
994 994
     free(tempname);
... ...
@@ -1022,8 +1022,8 @@ static int cli_scanscript(int desc, cli_ctx *ctx)
1022 1022
 
1023 1023
 	/* dump to disk only if explicitly asked to,
1024 1024
 	 * otherwise we can process just in-memory */
1025
-	if(cli_leavetemps_flag) {
1026
-		if((ret = cli_gentempfd(NULL, &tmpname, &ofd))) {
1025
+	if(ctx->engine->keeptmp) {
1026
+		if((ret = cli_gentempfd(ctx->engine->tmpdir, &tmpname, &ofd))) {
1027 1027
 			cli_dbgmsg("cli_scanscript: Can't generate temporary file/descriptor\n");
1028 1028
 			return ret;
1029 1029
 		}
... ...
@@ -1065,7 +1065,7 @@ static int cli_scanscript(int desc, cli_ctx *ctx)
1065 1065
 		 * and using while(){} loop would mean code duplication */
1066 1066
 	} while (nread > 0);
1067 1067
 
1068
-	if(cli_leavetemps_flag) {
1068
+	if(ctx->engine->keeptmp) {
1069 1069
 		free(tmpname);
1070 1070
 		close(ofd);
1071 1071
 	}
... ...
@@ -1082,7 +1082,7 @@ static int cli_scanhtml_utf16(int desc, cli_ctx *ctx)
1082 1082
 
1083 1083
     cli_dbgmsg("in cli_scanhtml_utf16()\n");
1084 1084
 
1085
-    if(!(tempname = cli_gentemp(NULL)))
1085
+    if(!(tempname = cli_gentemp(ctx->engine->tmpdir)))
1086 1086
 	return CL_EMEM;
1087 1087
 
1088 1088
     if((fd = open(tempname, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IRWXU)) < 0) {
... ...
@@ -1112,7 +1112,7 @@ static int cli_scanhtml_utf16(int desc, cli_ctx *ctx)
1112 1112
     ret = cli_scanhtml(fd, ctx);
1113 1113
     close(fd);
1114 1114
 
1115
-    if(!cli_leavetemps_flag) {
1115
+    if(!ctx->engine->keeptmp) {
1116 1116
 	if (cli_unlink(tempname)) ret = CL_EIO;
1117 1117
     } else
1118 1118
 	cli_dbgmsg("cli_scanhtml_utf16: Decoded HTML data saved in %s\n", tempname);
... ...
@@ -1133,7 +1133,7 @@ static int cli_scanole2(int desc, cli_ctx *ctx)
1133 1133
         return CL_EMAXREC;
1134 1134
 
1135 1135
     /* generate the temporary directory */
1136
-    if(!(dir = cli_gentemp(NULL)))
1136
+    if(!(dir = cli_gentemp(ctx->engine->tmpdir)))
1137 1137
 	return CL_EMEM;
1138 1138
 
1139 1139
     if(mkdir(dir, 0700)) {
... ...
@@ -1145,7 +1145,7 @@ static int cli_scanole2(int desc, cli_ctx *ctx)
1145 1145
     ret = cli_ole2_extract(desc, dir, ctx, &vba);
1146 1146
     if(ret!=CL_CLEAN && ret!=CL_VIRUS) {
1147 1147
 	cli_dbgmsg("OLE2: %s\n", cl_strerror(ret));
1148
-	if(!cli_leavetemps_flag)
1148
+	if(!ctx->engine->keeptmp)
1149 1149
 	    cli_rmdirs(dir);
1150 1150
 	free(dir);
1151 1151
 	return ret;
... ...
@@ -1162,7 +1162,7 @@ static int cli_scanole2(int desc, cli_ctx *ctx)
1162 1162
 	ctx->recursion--;
1163 1163
     }
1164 1164
 
1165
-    if(!cli_leavetemps_flag)
1165
+    if(!ctx->engine->keeptmp)
1166 1166
 	cli_rmdirs(dir);
1167 1167
     free(dir);
1168 1168
     return ret;
... ...
@@ -1177,7 +1177,7 @@ static int cli_scantar(int desc, cli_ctx *ctx, unsigned int posix)
1177 1177
     cli_dbgmsg("in cli_scantar()\n");
1178 1178
 
1179 1179
     /* generate temporary directory */
1180
-    if(!(dir = cli_gentemp(NULL)))
1180
+    if(!(dir = cli_gentemp(ctx->engine->tmpdir)))
1181 1181
 	return CL_EMEM;
1182 1182
 
1183 1183
     if(mkdir(dir, 0700)) {
... ...
@@ -1188,7 +1188,7 @@ static int cli_scantar(int desc, cli_ctx *ctx, unsigned int posix)
1188 1188
 
1189 1189
     ret = cli_untar(dir, desc, posix, ctx);
1190 1190
 
1191
-    if(!cli_leavetemps_flag)
1191
+    if(!ctx->engine->keeptmp)
1192 1192
 	cli_rmdirs(dir);
1193 1193
 
1194 1194
     free(dir);
... ...
@@ -1204,7 +1204,7 @@ static int cli_scanbinhex(int desc, cli_ctx *ctx)
1204 1204
     cli_dbgmsg("in cli_scanbinhex()\n");
1205 1205
 
1206 1206
     /* generate temporary directory */
1207
-    if(!(dir = cli_gentemp(NULL)))
1207
+    if(!(dir = cli_gentemp(ctx->engine->tmpdir)))
1208 1208
 	return CL_EMEM;
1209 1209
 
1210 1210
     if(mkdir(dir, 0700)) {
... ...
@@ -1218,7 +1218,7 @@ static int cli_scanbinhex(int desc, cli_ctx *ctx)
1218 1218
     else
1219 1219
 	ret = cli_scandir(dir, ctx, 0);
1220 1220
 
1221
-    if(!cli_leavetemps_flag)
1221
+    if(!ctx->engine->keeptmp)
1222 1222
 	cli_rmdirs(dir);
1223 1223
 
1224 1224
     free(dir);
... ...
@@ -1234,7 +1234,7 @@ static int cli_scanmschm(int desc, cli_ctx *ctx)
1234 1234
     cli_dbgmsg("in cli_scanmschm()\n");
1235 1235
 
1236 1236
      /* generate the temporary directory */
1237
-    if(!(dir = cli_gentemp(NULL)))
1237
+    if(!(dir = cli_gentemp(ctx->engine->tmpdir)))
1238 1238
 	return CL_EMEM;
1239 1239
 
1240 1240
     if(mkdir(dir, 0700)) {
... ...
@@ -1245,7 +1245,7 @@ static int cli_scanmschm(int desc, cli_ctx *ctx)
1245 1245
 
1246 1246
     ret = cli_chm_open(desc, dir, &metadata);
1247 1247
     if (ret != CL_SUCCESS) {
1248
-	if(!cli_leavetemps_flag)
1248
+	if(!ctx->engine->keeptmp)
1249 1249
 	    cli_rmdirs(dir);
1250 1250
 	free(dir);
1251 1251
 	cli_dbgmsg("CHM: Error: %s\n", cl_strerror(ret));
... ...
@@ -1273,7 +1273,7 @@ static int cli_scanmschm(int desc, cli_ctx *ctx)
1273 1273
 
1274 1274
     cli_chm_close(&metadata);
1275 1275
    
1276
-    if(!cli_leavetemps_flag)
1276
+    if(!ctx->engine->keeptmp)
1277 1277
 	cli_rmdirs(dir);
1278 1278
 
1279 1279
     free(dir);
... ...
@@ -1292,7 +1292,7 @@ static int cli_scanscrenc(int desc, cli_ctx *ctx)
1292 1292
 
1293 1293
     cli_dbgmsg("in cli_scanscrenc()\n");
1294 1294
 
1295
-    if(!(tempname = cli_gentemp(NULL)))
1295
+    if(!(tempname = cli_gentemp(ctx->engine->tmpdir)))
1296 1296
 	return CL_EMEM;
1297 1297
 
1298 1298
     if(mkdir(tempname, 0700)) {
... ...
@@ -1304,7 +1304,7 @@ static int cli_scanscrenc(int desc, cli_ctx *ctx)
1304 1304
     if (html_screnc_decode(desc, tempname))
1305 1305
 	ret = cli_scandir(tempname, ctx, 0);
1306 1306
 
1307
-    if(!cli_leavetemps_flag)
1307
+    if(!ctx->engine->keeptmp)
1308 1308
 	cli_rmdirs(tempname);
1309 1309
 
1310 1310
     free(tempname);
... ...
@@ -1380,7 +1380,7 @@ static int cli_scancryptff(int desc, cli_ctx *ctx)
1380 1380
 
1381 1381
     free(src);
1382 1382
 
1383
-    if(!(tempfile = cli_gentemp(NULL))) {
1383
+    if(!(tempfile = cli_gentemp(ctx->engine->tmpdir))) {
1384 1384
 	free(dest);
1385 1385
 	return CL_EMEM;
1386 1386
     }
... ...
@@ -1411,7 +1411,7 @@ static int cli_scancryptff(int desc, cli_ctx *ctx)
1411 1411
 
1412 1412
     close(ndesc);
1413 1413
 
1414
-    if(cli_leavetemps_flag)
1414
+    if(ctx->engine->keeptmp)
1415 1415
 	cli_dbgmsg("CryptFF: Decompressed data saved in %s\n", tempfile);
1416 1416
     else
1417 1417
 	if (cli_unlink(tempfile)) ret = CL_EIO;
... ...
@@ -1423,7 +1423,7 @@ static int cli_scancryptff(int desc, cli_ctx *ctx)
1423 1423
 static int cli_scanpdf(int desc, cli_ctx *ctx, off_t offset)
1424 1424
 {
1425 1425
 	int ret;
1426
-	char *dir = cli_gentemp(NULL);
1426
+	char *dir = cli_gentemp(ctx->engine->tmpdir);
1427 1427
 
1428 1428
     if(!dir)
1429 1429
 	return CL_EMEM;
... ...
@@ -1436,7 +1436,7 @@ static int cli_scanpdf(int desc, cli_ctx *ctx, off_t offset)
1436 1436
 
1437 1437
     ret = cli_pdf(dir, desc, ctx, offset);
1438 1438
 
1439
-    if(!cli_leavetemps_flag)
1439
+    if(!ctx->engine->keeptmp)
1440 1440
 	cli_rmdirs(dir);
1441 1441
 
1442 1442
     free(dir);
... ...
@@ -1446,7 +1446,7 @@ static int cli_scanpdf(int desc, cli_ctx *ctx, off_t offset)
1446 1446
 static int cli_scantnef(int desc, cli_ctx *ctx)
1447 1447
 {
1448 1448
 	int ret;
1449
-	char *dir = cli_gentemp(NULL);
1449
+	char *dir = cli_gentemp(ctx->engine->tmpdir);
1450 1450
 
1451 1451
     if(!dir)
1452 1452
 	return CL_EMEM;
... ...
@@ -1457,12 +1457,12 @@ static int cli_scantnef(int desc, cli_ctx *ctx)
1457 1457
 	return CL_ETMPDIR;
1458 1458
     }
1459 1459
 
1460
-    ret = cli_tnef(dir, desc);
1460
+    ret = cli_tnef(dir, desc, ctx);
1461 1461
 
1462 1462
     if(ret == CL_CLEAN)
1463 1463
 	ret = cli_scandir(dir, ctx, 0);
1464 1464
 
1465
-    if(!cli_leavetemps_flag)
1465
+    if(!ctx->engine->keeptmp)
1466 1466
 	cli_rmdirs(dir);
1467 1467
 
1468 1468
     free(dir);
... ...
@@ -1472,7 +1472,7 @@ static int cli_scantnef(int desc, cli_ctx *ctx)
1472 1472
 static int cli_scanuuencoded(int desc, cli_ctx *ctx)
1473 1473
 {
1474 1474
 	int ret;
1475
-	char *dir = cli_gentemp(NULL);
1475
+	char *dir = cli_gentemp(ctx->engine->tmpdir);
1476 1476
 
1477 1477
     if(!dir)
1478 1478
 	return CL_EMEM;
... ...
@@ -1488,7 +1488,7 @@ static int cli_scanuuencoded(int desc, cli_ctx *ctx)
1488 1488
     if(ret == CL_CLEAN)
1489 1489
 	ret = cli_scandir(dir, ctx, 0);
1490 1490
 
1491
-    if(!cli_leavetemps_flag)
1491
+    if(!ctx->engine->keeptmp)
1492 1492
 	cli_rmdirs(dir);
1493 1493
 
1494 1494
     free(dir);
... ...
@@ -1504,7 +1504,7 @@ static int cli_scanmail(int desc, cli_ctx *ctx)
1504 1504
     cli_dbgmsg("Starting cli_scanmail(), recursion = %u\n", ctx->recursion);
1505 1505
 
1506 1506
     /* generate the temporary directory */
1507
-    if(!(dir = cli_gentemp(NULL)))
1507
+    if(!(dir = cli_gentemp(ctx->engine->tmpdir)))
1508 1508
 	return CL_EMEM;
1509 1509
 
1510 1510
     if(mkdir(dir, 0700)) {
... ...
@@ -1517,7 +1517,7 @@ static int cli_scanmail(int desc, cli_ctx *ctx)
1517 1517
      * Extract the attachments into the temporary directory
1518 1518
      */
1519 1519
     if((ret = cli_mbox(dir, desc, ctx))) {
1520
-	if(!cli_leavetemps_flag)
1520
+	if(!ctx->engine->keeptmp)
1521 1521
 	    cli_rmdirs(dir);
1522 1522
 	free(dir);
1523 1523
 	return ret;
... ...
@@ -1525,7 +1525,7 @@ static int cli_scanmail(int desc, cli_ctx *ctx)
1525 1525
 
1526 1526
     ret = cli_scandir(dir, ctx, CL_TYPE_MAIL);
1527 1527
 
1528
-    if(!cli_leavetemps_flag)
1528
+    if(!ctx->engine->keeptmp)
1529 1529
 	cli_rmdirs(dir);
1530 1530
 
1531 1531
     free(dir);
... ...
@@ -1609,7 +1609,7 @@ static int cli_scanembpe(int desc, cli_ctx *ctx)
1609 1609
 	char *tmpname;
1610 1610
 
1611 1611
 
1612
-    tmpname = cli_gentemp(NULL);
1612
+    tmpname = cli_gentemp(ctx->engine->tmpdir);
1613 1613
     if(!tmpname)
1614 1614
 	return CL_EMEM;
1615 1615
 
... ...
@@ -1628,7 +1628,7 @@ static int cli_scanembpe(int desc, cli_ctx *ctx)
1628 1628
 	if(cli_writen(fd, buff, bytes) != bytes) {
1629 1629
 	    cli_dbgmsg("cli_scanembpe: Can't write to temporary file\n");
1630 1630
 	    close(fd);
1631
-	    if(!cli_leavetemps_flag) {
1631
+	    if(!ctx->engine->keeptmp) {
1632 1632
 		if (cli_unlink(tmpname)) {
1633 1633
 		    free(tmpname);
1634 1634
 		    return CL_EIO;
... ...
@@ -1644,7 +1644,7 @@ static int cli_scanembpe(int desc, cli_ctx *ctx)
1644 1644
     if((ret = cli_magic_scandesc(fd, ctx)) == CL_VIRUS) {
1645 1645
 	cli_dbgmsg("cli_scanembpe: Infected with %s\n", *ctx->virname);
1646 1646
 	close(fd);
1647
-	if(!cli_leavetemps_flag) {
1647
+	if(!ctx->engine->keeptmp) {
1648 1648
 	    if (cli_unlink(tmpname)) {
1649 1649
 	    	free(tmpname);
1650 1650
 		return CL_EIO;
... ...
@@ -1656,7 +1656,7 @@ static int cli_scanembpe(int desc, cli_ctx *ctx)
1656 1656
     ctx->recursion--;
1657 1657
 
1658 1658
     close(fd);
1659
-    if(!cli_leavetemps_flag) {
1659
+    if(!ctx->engine->keeptmp) {
1660 1660
 	if (cli_unlink(tmpname)) {
1661 1661
 	    free(tmpname);
1662 1662
 	    return CL_EIO;
... ...
@@ -67,14 +67,14 @@ int cli_scansis(int desc, cli_ctx *ctx) {
67 67
 
68 68
   cli_dbgmsg("in scansis()\n");
69 69
 
70
-  if (!(tmpd = cli_gentemp(NULL)))    
70
+  if (!(tmpd = cli_gentemp(ctx->engine->tmpdir)))    
71 71
     return CL_ETMPDIR;
72 72
   if (mkdir(tmpd, 0700)) {
73 73
     cli_dbgmsg("SIS: Can't create temporary directory %s\n", tmpd);
74 74
     free(tmpd);
75 75
     return CL_ETMPDIR;
76 76
   }
77
-  if (cli_leavetemps_flag)
77
+  if (ctx->engine->keeptmp)
78 78
     cli_dbgmsg("SIS: Extracting files to %s\n", tmpd);
79 79
 
80 80
   if ((i=dup(desc))==-1) {
... ...
@@ -106,7 +106,7 @@ int cli_scansis(int desc, cli_ctx *ctx) {
106 106
     i=real_scansis9x(f, ctx, tmpd);
107 107
   }
108 108
 
109
-  if (!cli_leavetemps_flag)
109
+  if (!ctx->engine->keeptmp)
110 110
     cli_rmdirs(tmpd);
111 111
 
112 112
   free(tmpd);
... ...
@@ -61,7 +61,7 @@ static	int	tnef_header(FILE *fp, uint8_t *part, uint16_t *type, uint16_t *tag, i
61 61
 #define	MIN_SIZE	(sizeof(uint32_t) + sizeof(uint16_t))
62 62
 
63 63
 int
64
-cli_tnef(const char *dir, int desc)
64
+cli_tnef(const char *dir, int desc, cli_ctx *ctx)
65 65
 {
66 66
 	uint32_t i32;
67 67
 	uint16_t i16;
... ...
@@ -179,7 +179,7 @@ cli_tnef(const char *dir, int desc)
179 179
 				 */
180 180
 				if(cli_debug_flag) {
181 181
 					int fout = -1;
182
-					char *filename = cli_gentemp(NULL);
182
+					char *filename = cli_gentemp(ctx->engine->tmpdir);
183 183
 					char buffer[BUFSIZ];
184 184
 
185 185
 					if(filename)
... ...
@@ -21,6 +21,8 @@
21 21
 #ifndef __TNEF_H
22 22
 #define __TNEF_H
23 23
 
24
-int cli_tnef(const char *dir, int desc);
24
+#include "others.h"
25
+
26
+int cli_tnef(const char *dir, int desc, cli_ctx *ctx);
25 27
 
26 28
 #endif
... ...
@@ -92,7 +92,7 @@ cli_untar(const char *dir, int desc, unsigned int posix, cli_ctx *ctx)
92 92
 				lseek(fout, 0, SEEK_SET);
93 93
 				ret = cli_magic_scandesc(fout, ctx);
94 94
 				close(fout);
95
-				if (!cli_leavetemps_flag)
95
+				if (!ctx->engine->keeptmp)
96 96
 					if (cli_unlink(fullname)) return CL_EIO;
97 97
 				if (ret==CL_VIRUS)
98 98
 					return CL_VIRUS;
... ...
@@ -211,7 +211,7 @@ cli_untar(const char *dir, int desc, unsigned int posix, cli_ctx *ctx)
211 211
 		lseek(fout, 0, SEEK_SET);
212 212
 		ret = cli_magic_scandesc(fout, ctx);
213 213
 		close(fout);
214
-		if (!cli_leavetemps_flag)
214
+		if (!ctx->engine->keeptmp)
215 215
 			if (cli_unlink(fullname)) return CL_EIO;
216 216
 		if (ret==CL_VIRUS)
217 217
 			return CL_VIRUS;
... ...
@@ -86,7 +86,7 @@ static int unz(uint8_t *src, uint32_t csize, uint32_t usize, uint16_t method, ui
86 86
     snprintf(name, sizeof(name), "%s/zip.%03u", tmpd, *fu);
87 87
     name[sizeof(name)-1]='\0';
88 88
   } else {
89
-    if(!(tempfile = cli_gentemp(NULL))) return CL_EMEM;
89
+    if(!(tempfile = cli_gentemp(ctx->engine->tmpdir))) return CL_EMEM;
90 90
   }
91 91
   if((of = open(tempfile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IRUSR|S_IWUSR))==-1) {
92 92
     cli_warnmsg("cli_unzip: failed to create temporary file %s\n", tempfile);
... ...
@@ -303,14 +303,14 @@ static int unz(uint8_t *src, uint32_t csize, uint32_t usize, uint16_t method, ui
303 303
     lseek(of, 0, SEEK_SET);
304 304
     ret = cli_magic_scandesc(of, ctx);
305 305
     close(of);
306
-    if(!cli_leavetemps_flag)
306
+    if(!ctx->engine->keeptmp)
307 307
       if(cli_unlink(tempfile)) ret = CL_EIO;
308 308
     if(!tmpd) free(tempfile);
309 309
     return ret;
310 310
   }
311 311
 
312 312
   close(of);
313
-  if(!cli_leavetemps_flag)
313
+  if(!ctx->engine->keeptmp)
314 314
     if(cli_unlink(tempfile)) ret = CL_EIO;
315 315
   if(!tmpd) free(tempfile);
316 316
   cli_dbgmsg("cli_unzip: extraction failed\n");
... ...
@@ -513,7 +513,7 @@ int cli_unzip(int f, cli_ctx *ctx) {
513 513
   }
514 514
 #endif
515 515
 
516
-  if (!(tmpd = cli_gentemp(NULL))) {
516
+  if (!(tmpd = cli_gentemp(ctx->engine->tmpdir))) {
517 517
     destroy_map(map, fsize);
518 518
     return CL_ETMPDIR;
519 519
   }
... ...
@@ -556,7 +556,7 @@ int cli_unzip(int f, cli_ctx *ctx) {
556 556
   }
557 557
 
558 558
   destroy_map(map, fsize);
559
-  if (!cli_leavetemps_flag) cli_rmdirs(tmpd);
559
+  if (!ctx->engine->keeptmp) cli_rmdirs(tmpd);
560 560
   free(tmpd);
561 561
 
562 562
   return ret;
... ...
@@ -588,7 +588,7 @@ cli_scan_ole10(int fd, cli_ctx *ctx)
588 588
 		if(!read_uint32(fd, &object_size, FALSE))
589 589
 			return CL_CLEAN;
590 590
 	}
591
-	if(!(fullname = cli_gentemp(NULL))) {
591
+	if(!(fullname = cli_gentemp(ctx ? ctx->engine->tmpdir : NULL))) {
592 592
 		return CL_EMEM;
593 593
 	}
594 594
 	ofd = open(fullname, O_RDWR|O_CREAT|O_TRUNC|O_BINARY|O_EXCL,
... ...
@@ -603,7 +603,7 @@ cli_scan_ole10(int fd, cli_ctx *ctx)
603 603
 	lseek(ofd, 0, SEEK_SET);
604 604
 	ret = cli_magic_scandesc(ofd, ctx);
605 605
 	close(ofd);
606
-	if(!cli_leavetemps_flag)
606
+	if(ctx && !ctx->engine->keeptmp)
607 607
 	  if (cli_unlink(fullname))
608 608
 	    ret = CL_EIO;
609 609
 	free(fullname);
... ...
@@ -760,13 +760,13 @@ ppt_stream_iter(int fd, const char *dir)
760 760
 }
761 761
 
762 762
 char *
763
-cli_ppt_vba_read(int ifd)
763
+cli_ppt_vba_read(int ifd, cli_ctx *ctx)
764 764
 {
765 765
 	char *dir;
766 766
 	const char *ret;
767 767
 
768 768
 	/* Create a directory to store the extracted OLE2 objects */
769
-	dir = cli_gentemp(NULL);
769
+	dir = cli_gentemp(ctx ? ctx->engine->tmpdir : NULL);
770 770
 	if(dir == NULL)
771 771
 		return NULL;
772 772
 	if(mkdir(dir, 0700)) {
... ...
@@ -42,7 +42,7 @@ vba_project_t	*cli_vba_readdir(const char *dir, struct uniq *U, uint32_t which);
42 42
 vba_project_t	*cli_wm_readdir(int fd);
43 43
 unsigned char	*cli_vba_inflate(int fd, off_t offset, int *size);
44 44
 int	cli_scan_ole10(int fd, cli_ctx *ctx);
45
-char	*cli_ppt_vba_read(int fd);
45
+char	*cli_ppt_vba_read(int fd, cli_ctx *ctx);
46 46
 unsigned char	*cli_wm_decrypt_macro(int fd, off_t offset, uint32_t len,
47 47
 					unsigned char key);
48 48
 
... ...
@@ -46,8 +46,8 @@ struct cfgstruct {
46 46
     char *optname;
47 47
     char *strarg;
48 48
     int numarg;
49
-    short enabled;
50
-    short multiple;
49
+    unsigned int enabled;
50
+    unsigned int multiple;
51 51
     struct cfgstruct *nextarg;
52 52
     struct cfgstruct *next;
53 53
 };
... ...
@@ -1084,7 +1084,7 @@ int sigtool_vba_scandir (const char *dirname, int hex_output, struct uniq *U)
1084 1084
 	    vbaname[sizeof(vbaname)-1] = '\0';
1085 1085
 	    fd = open(vbaname, O_RDONLY|O_BINARY);
1086 1086
 	    if (fd == -1) continue;
1087
-	    if ((fullname = cli_ppt_vba_read(fd))) {
1087
+	    if ((fullname = cli_ppt_vba_read(fd, NULL))) {
1088 1088
 	      sigtool_scandir(fullname, hex_output);
1089 1089
 	      cli_rmdirs(fullname);
1090 1090
 	      free(fullname);