Browse code

Merge branch 'master' into bytecode

* master: (60 commits)
Fix build when git is not installed and using BSD make.
Only use -fno-strict-aliasing for gcc-4.3+, to avoid bugs with older compilers (bb #1581).
libclamav/matcher-bm.c: fix cli_bm_freeoff() (bb#1710)
bb#1708
implove poolsize.pl
win32: s/C_WINDOWS/_WIN32/ in clamd, shared
libclamav/matcher-ac.c: fix matching of logical sigs (bb#1707)
libclamav/readdb.c: fix handling of broken .ldb sigs (bb#1701)
libclamav: new signature blacklisting format (bb#1625)
killclamd must always succeed (except when there's a stuck clamd).
Fix typo.
Better error message when clamd gets killed
merge win32 patches from sherpya
remove bogus debug printf
libclamav/matcher-ac.c: add support for line marker (L) (matches CR, CRLF and boundaries)
fix EOL in platform.h
sis.c: fix size check
fix several problems introduced by the win32 commits
fix in cli_is_abspath
win32#3
...

Conflicts:
.gitignore
Makefile.am
configure
configure.in
libclamav/readdb.c

Török Edvin authored on 2009/10/02 16:04:37
Showing 131 changed files
... ...
@@ -1,20 +1,21 @@
1
-*.[oa]
2
-*.l[oa]
3 1
 *~
4
-*.swp
5
-*.gcno
6
-*.gcda
7
-TAGS
8
-Makefile
2
+autom4te.cache/*
3
+clamav-config
4
+clamav-config.h
5
+config.log
6
+config.status
9 7
 .deps
8
+*.gcda
9
+*.gcno
10
+libclamav.pc
10 11
 .libs
11
-clamav-config*
12 12
 libtool
13
+*.l[oa]
14
+Makefile
15
+*.[oa]
16
+platform.h
13 17
 stamp-h1
18
+*.swp
19
+TAGS
14 20
 target.h
15
-config.log
16
-config.status
17
-libclamav.pc
18
-unit_tests/*
19
-autom4te.cache/*
20 21
 libclamav/c++/autom4te.cache/*
... ...
@@ -1,3 +1,159 @@
1
+Wed Sep 30 19:41:43 EEST 2009 (edwin)
2
+-------------------------------------
3
+ * configure{.in,}: Only use -fno-strict-aliasing for gcc-4.3+ to avoid bugs
4
+    with older compilers (bb #1581)
5
+
6
+Wed Sep 30 17:15:05 CEST 2009 (tk)
7
+----------------------------------
8
+ * libclamav/matcher-bm.c: fix cli_bm_freeoff() (bb#1710)
9
+
10
+Wed Sep 30 12:40:50 CEST 2009 (acab)
11
+------------------------------------
12
+ * clamdscan/clamdscan.c: properly init variable (bb#1708)
13
+
14
+Wed Sep 30 00:51:19 CEST 2009 (acab)
15
+------------------------------------
16
+ * clamd, shared: merge a set of win32 patches from
17
+		Gianluigi Tiesi <sherpya*netfarm.it>
18
+
19
+Tue Sep 29 21:40:29 CEST 2009 (tk)
20
+----------------------------------
21
+ * libclamav/matcher-ac.c: fix matching of logical sigs (bb#1707)
22
+			   Reported by Thiyaga <mthiyaga*corp.untd.com>
23
+
24
+Mon Sep 28 21:41:47 CEST 2009 (tk)
25
+----------------------------------
26
+ * libclamav/readdb.c: fix handling of broken .ldb sigs (bb#1701)
27
+		       Thanks Luca&Edwin
28
+
29
+Mon Sep 28 19:29:32 CEST 2009 (tk)
30
+----------------------------------
31
+ * libclamav: new signature blacklisting format (bb#1625)
32
+ * libclamav: allow arbitrary names for .ign/.ign2 files (bb#1683)
33
+
34
+Fri Sep 25 15:13:25 CEST 2009 (acab)
35
+------------------------------------
36
+ * sigtool/vba.c: s/cli_errmsg/logg/
37
+ * shared/misc.h: in_addr_t is now already declared
38
+ * libclamav/special.c: do not include netinet/in.h on win32
39
+ All the patches from Gianluigi Tiesi <sherpya*netfarm.it>
40
+
41
+Fri Sep 25 15:09:02 CEST 2009 (acab)
42
+------------------------------------
43
+ * clamav-milter/clamav.milter.c: remove debug printf
44
+
45
+Fri Sep 25 10:36:48 CEST 2009 (tk)
46
+----------------------------------
47
+ * libclamav/matcher-ac.c: add support for line marker (L) (matches CR,
48
+			   CRLF and boundaries)
49
+
50
+Fri Sep 25 00:35:56 CEST 2009 (acab)
51
+------------------------------------
52
+ * libclamav/sis.c: size check fix, thanks Tomasz
53
+
54
+Fri Sep 25 00:31:29 CEST 2009 (acab)
55
+------------------------------------
56
+ * fix several problems introduced by the win32 commits
57
+   many thanks edwin and sherpya
58
+
59
+Thu Sep 24 19:43:50 CEST 2009 (acab)
60
+------------------------------------
61
+ * libclamav/others_common.c: Accept "/" as an absolute path
62
+
63
+Thu Sep 24 19:22:24 CEST 2009 (acab)
64
+------------------------------------
65
+ * merge a set of win32 patches from Gianluigi Tiesi <sherpya*netfarm.it>
66
+
67
+Thu Sep 24 19:09:38 CEST 2009 (acab)
68
+------------------------------------
69
+ * drop OS/2 "support"
70
+
71
+Thu Sep 24 19:07:59 CEST 2009 (acab)
72
+------------------------------------
73
+ * clamd, libclamav: drop INTERIX "support"
74
+
75
+Thu Sep 24 19:05:06 CEST 2009 (acab)
76
+------------------------------------
77
+ * win32 paths handling
78
+
79
+Thu Sep 24 16:22:25 CEST 2009 (acab)
80
+------------------------------------
81
+ * merge initial set of win32 patches from Gianluigi Tiesi <sherpya*netfarm.it>
82
+
83
+Thu Sep 24 01:14:50 CEST 2009 (acab)
84
+------------------------------------
85
+ * clamav-milter: Add option ReportHostname to mangle the host name in X headers
86
+
87
+Wed Sep 23 03:19:53 CEST 2009 (acab)
88
+------------------------------------
89
+ * libclamav/mpool.c: update frag sizes, small cleanup
90
+
91
+Mon Sep 21 22:05:38 CEST 2009 (tk)
92
+----------------------------------
93
+ * clamd: add support for DazukoFS (bb#1691)
94
+	  Patch from John Ogness <dazukocode*ogness.net>
95
+
96
+Fri Sep 18 20:02:06 CEST 2009 (tk)
97
+----------------------------------
98
+ * libclamav/matcher-bm.c: use mpool in BM's offset mode
99
+
100
+Thu Sep 17 22:36:30 CEST 2009 (tk)
101
+----------------------------------
102
+ * libclamav/matcher-ac.c: implement word delimiter (B) as requested in bb#1631
103
+
104
+Mon Sep 14 19:52:01 CEST 2009 (tk)
105
+----------------------------------
106
+ * freshclam: return 0 instead of 1 when database is up-to-date (bb#1312)
107
+
108
+Mon Sep 14 13:56:42 CEST 2009 (tk)
109
+----------------------------------
110
+ * clamd/server-th.c: fix possible race condition when restarting clamuko
111
+		      (bb#1692), patch from John Ogness
112
+
113
+Fri Sep 11 16:05:00 CEST 2009 (tk)
114
+----------------------------------
115
+ * libclamav/matcher-ac.c: initial limited support for word boundary (bb#1631)
116
+
117
+Thu Sep 10 20:16:45 CEST 2009 (tk)
118
+----------------------------------
119
+ * libclamav/matcher-ac.c: alternatives can now be negated: !(aa|bb|cc)
120
+
121
+Mon Sep  7 15:03:11 CEST 2009 (tk)
122
+----------------------------------
123
+ * libclamav/matcher-bm.c: fix uninitialized value warning
124
+
125
+Mon Sep  7 03:45:18 CEST 2009 (acab)
126
+------------------------------------
127
+ * libclamav/scanners.c: properly scan text files with a mail container
128
+
129
+Thu Sep  3 15:09:57 CEST 2009 (tk)
130
+----------------------------------
131
+ * freshclam/mirman.c: make backoff time proportional to FLEVEL (bb#1687)
132
+
133
+Tue Sep  1 20:50:12 CEST 2009 (tk)
134
+----------------------------------
135
+ * libclamav: use BM matcher in offset mode for PE files larger than 256kB
136
+	      (10% speedup on average; 30-40% for large executables)
137
+
138
+Tue Sep  1 11:11:43 CEST 2009 (tk)
139
+----------------------------------
140
+ * libclamav: in bm_offmode only load sigs with non-floating absolute and
141
+	      relative offsets into BM matcher (load other ones into AC)
142
+	      and use per-file computed offset table to pick up best shifts
143
+	      (not enabled by default, bb#1300)
144
+
145
+Sun Aug 30 23:56:49 CEST 2009 (acab)
146
+------------------------------------
147
+ * libclamav: unify CL_TYPE_MAIL scanning
148
+
149
+Wed Aug 26 23:37:04 CEST 2009 (tk)
150
+----------------------------------
151
+ * libclamav/matcher-ac.c: improve handling of signature offsets
152
+
153
+Mon Aug 24 22:09:12 CEST 2009 (tk)
154
+----------------------------------
155
+ * libclamav: improve handling of PDF files (bb#1682)
156
+
1 157
 Fri Aug 21 15:53:35 CEST 2009 (tk)
2 158
 ----------------------------------
3 159
  * libclamav: handle relative offsets with cli_ac_data; fix offset logic
... ...
@@ -19,8 +19,7 @@
19 19
 ACLOCAL_AMFLAGS=-I m4
20 20
 
21 21
 SUBDIRS = libltdl libclamav clamscan clamd clamdscan freshclam sigtool clamconf database docs etc clamav-milter test unit_tests clamdtop clambc
22
-
23
-EXTRA_DIST = FAQ examples BUGS shared libclamav.pc.in libclamunrar_iface/Makefile.am libclamunrar_iface/Makefile.in UPGRADE COPYING.bzip2 COPYING.lzma COPYING.unrar COPYING.LGPL COPYING.file COPYING.zlib COPYING.getopt COPYING.regex COPYING.sha256
22
+EXTRA_DIST = FAQ examples BUGS shared libclamav.pc.in libclamunrar_iface/Makefile.am libclamunrar_iface/Makefile.in UPGRADE COPYING.bzip2 COPYING.lzma COPYING.unrar COPYING.LGPL COPYING.file COPYING.zlib COPYING.getopt COPYING.regex COPYING.sha256 platform.h.in
24 23
 
25 24
 bin_SCRIPTS=clamav-config
26 25
 
... ...
@@ -58,7 +58,7 @@ subdir = .
58 58
 DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
59 59
 	$(srcdir)/Makefile.in $(srcdir)/clamav-config.h.in \
60 60
 	$(srcdir)/clamav-config.in $(srcdir)/libclamav.pc.in \
61
-	$(top_srcdir)/configure \
61
+	$(srcdir)/platform.h.in $(top_srcdir)/configure \
62 62
 	$(top_srcdir)/docs/man/clamav-milter.8.in \
63 63
 	$(top_srcdir)/docs/man/clamconf.1.in \
64 64
 	$(top_srcdir)/docs/man/clamd.8.in \
... ...
@@ -88,7 +88,7 @@ am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
88 88
  configure.lineno config.status.lineno
89 89
 mkinstalldirs = $(install_sh) -d
90 90
 CONFIG_HEADER = clamav-config.h
91
-CONFIG_CLEAN_FILES = clamav-config libclamav.pc \
91
+CONFIG_CLEAN_FILES = clamav-config libclamav.pc platform.h \
92 92
 	docs/man/clamav-milter.8 docs/man/clamconf.1 docs/man/clamd.8 \
93 93
 	docs/man/clamd.conf.5 docs/man/clamdscan.1 docs/man/clamscan.1 \
94 94
 	docs/man/freshclam.1 docs/man/freshclam.conf.5 \
... ...
@@ -336,7 +336,7 @@ top_builddir = @top_builddir@
336 336
 top_srcdir = @top_srcdir@
337 337
 ACLOCAL_AMFLAGS = -I m4
338 338
 SUBDIRS = libltdl libclamav clamscan clamd clamdscan freshclam sigtool clamconf database docs etc clamav-milter test unit_tests clamdtop clambc
339
-EXTRA_DIST = FAQ examples BUGS shared libclamav.pc.in libclamunrar_iface/Makefile.am libclamunrar_iface/Makefile.in UPGRADE COPYING.bzip2 COPYING.lzma COPYING.unrar COPYING.LGPL COPYING.file COPYING.zlib COPYING.getopt COPYING.regex COPYING.sha256
339
+EXTRA_DIST = FAQ examples BUGS shared libclamav.pc.in libclamunrar_iface/Makefile.am libclamunrar_iface/Makefile.in UPGRADE COPYING.bzip2 COPYING.lzma COPYING.unrar COPYING.LGPL COPYING.file COPYING.zlib COPYING.getopt COPYING.regex COPYING.sha256 platform.h.in
340 340
 bin_SCRIPTS = clamav-config
341 341
 pkgconfigdir = $(libdir)/pkgconfig
342 342
 pkgconfig_DATA = libclamav.pc
... ...
@@ -447,6 +447,8 @@ clamav-config: $(top_builddir)/config.status $(srcdir)/clamav-config.in
447 447
 	cd $(top_builddir) && $(SHELL) ./config.status $@
448 448
 libclamav.pc: $(top_builddir)/config.status $(srcdir)/libclamav.pc.in
449 449
 	cd $(top_builddir) && $(SHELL) ./config.status $@
450
+platform.h: $(top_builddir)/config.status $(srcdir)/platform.h.in
451
+	cd $(top_builddir) && $(SHELL) ./config.status $@
450 452
 docs/man/clamav-milter.8: $(top_builddir)/config.status $(top_srcdir)/docs/man/clamav-milter.8.in
451 453
 	cd $(top_builddir) && $(SHELL) ./config.status $@
452 454
 docs/man/clamconf.1: $(top_builddir)/config.status $(top_srcdir)/docs/man/clamconf.1.in
... ...
@@ -563,3 +563,5 @@
563 563
 
564 564
 /* Define to "int" if <sys/socket.h> does not define. */
565 565
 #undef socklen_t
566
+
567
+#include "platform.h"
... ...
@@ -162,7 +162,7 @@ int main(int argc, char **argv) {
162 162
 
163 163
     if((opt = optget(opts, "LogFile"))->enabled) {
164 164
 	logg_file = opt->strarg;
165
-	if(strlen(logg_file) < 2 || logg_file[0] != '/') {
165
+	if(!cli_is_abspath(logg_file)) {
166 166
 	    fprintf(stderr, "ERROR: LogFile requires full path.\n");
167 167
 	    logg_close();
168 168
 	    optfree(opts);
... ...
@@ -223,14 +223,12 @@ int main(int argc, char **argv) {
223 223
     if(strcasecmp(pt, "No")) {
224 224
 	char myname[255];
225 225
 
226
-	if(!gethostname(myname, sizeof(myname))) {
226
+	if(((opt = optget(opts, "ReportHostname"))->enabled && strncpy(myname, opt->strarg, sizeof(myname))) || !gethostname(myname, sizeof(myname))) {
227 227
 	    myname[sizeof(myname)-1] = '\0';
228 228
 	    snprintf(xvirushdr, sizeof(xvirushdr), "clamav-milter %s at %s", get_version(), myname);
229
-	    xvirushdr[sizeof(xvirushdr)-1] = '\0';
230
-	} else {
229
+	} else
231 230
 	    snprintf(xvirushdr, sizeof(xvirushdr), "clamav-milter %s", get_version());
232
-	    xvirushdr[sizeof(xvirushdr)-1] = '\0';
233
-	}
231
+	xvirushdr[sizeof(xvirushdr)-1] = '\0';
234 232
 
235 233
 	descr.xxfi_flags |= SMFIF_ADDHDRS;
236 234
 
... ...
@@ -37,6 +37,7 @@
37 37
 
38 38
 #include "shared/optparser.h"
39 39
 #include "shared/output.h"
40
+#include "shared/misc.h"
40 41
 
41 42
 #include "connpool.h"
42 43
 #include "netcode.h"
... ...
@@ -59,7 +60,7 @@ static int cpool_addunix(char *path) {
59 59
     struct sockaddr_un *srv;
60 60
     struct CP_ENTRY *cpe = &cp->pool[cp->entries-1];
61 61
 
62
-    if(strlen(path)<2 || *path!='/') {
62
+    if(!cli_is_abspath(path)) {
63 63
 	logg("!Unix clamd socket must be an absolute path\n");
64 64
 	return 1;
65 65
     }
... ...
@@ -486,7 +486,7 @@ int localnets_init(struct optstruct *opts) {
486 486
 	while(opt) {
487 487
 	    char *lnetname = opt->strarg;
488 488
 	    struct LOCALNET *l;
489
-	    char *mask = strrchr(lnetname, '/');
489
+	    char *mask = strrchr(lnetname, *PATHSEP);
490 490
 
491 491
 	    if(mask) {
492 492
 		*mask='\0';
... ...
@@ -238,7 +238,7 @@ int main(int argc, char **argv)
238 238
     dir = optget(opts, "config-dir")->strarg;
239 239
     printf("Checking configuration files in %s\n", dir);
240 240
     for(i = 0; cfgfile[i].name; i++) {
241
-	snprintf(path, sizeof(path), "%s/%s", dir, cfgfile[i].name);
241
+	snprintf(path, sizeof(path), "%s"PATHSEP"%s", dir, cfgfile[i].name);
242 242
 	path[511] = 0;
243 243
 	if(access(path, R_OK)) {
244 244
 	    printf("\n%s not found\n", cfgfile[i].name);
... ...
@@ -307,7 +307,7 @@ int main(int argc, char **argv)
307 307
     printf("Database directory: %s\n", dbdir);
308 308
     flevel = cl_retflevel();
309 309
     for(i = 0; dbnames[i]; i++) {
310
-	snprintf(path, sizeof(path), "%s/%s", dbdir, dbnames[i]);
310
+	snprintf(path, sizeof(path), "%s"PATHSEP"%s", dbdir, dbnames[i]);
311 311
 	path[511] = 0;
312 312
 	if(!access(path, R_OK)) {
313 313
 	    cvd = cl_cvdhead(path);
... ...
@@ -48,12 +48,16 @@ clamd_SOURCES = \
48 48
     others.h \
49 49
     clamuko.c \
50 50
     clamuko.h \
51
+    clamukofs.c \
52
+    clamukofs.h \
51 53
     dazukoio_compat12.c \
52 54
     dazukoio_compat12.h \
53 55
     dazukoio.c \
54 56
     dazukoio.h \
55 57
     dazuko_xp.h \
56 58
     dazukoio_xp.h \
59
+    dazukofs.c \
60
+    dazukofs.h \
57 61
     shared.h
58 62
 
59 63
 endif
... ...
@@ -82,9 +82,9 @@ am__clamd_SOURCES_DIST = $(top_srcdir)/shared/output.c \
82 82
 	$(top_srcdir)/shared/network.h clamd.c tcpserver.c tcpserver.h \
83 83
 	localserver.c localserver.h session.c session.h thrmgr.c \
84 84
 	thrmgr.h server-th.c server.h scanner.c scanner.h others.c \
85
-	others.h clamuko.c clamuko.h dazukoio_compat12.c \
86
-	dazukoio_compat12.h dazukoio.c dazukoio.h dazuko_xp.h \
87
-	dazukoio_xp.h shared.h
85
+	others.h clamuko.c clamuko.h clamukofs.c clamukofs.h \
86
+	dazukoio_compat12.c dazukoio_compat12.h dazukoio.c dazukoio.h \
87
+	dazuko_xp.h dazukoio_xp.h dazukofs.c dazukofs.h shared.h
88 88
 @BUILD_CLAMD_TRUE@am_clamd_OBJECTS = output.$(OBJEXT) \
89 89
 @BUILD_CLAMD_TRUE@	optparser.$(OBJEXT) getopt.$(OBJEXT) \
90 90
 @BUILD_CLAMD_TRUE@	misc.$(OBJEXT) network.$(OBJEXT) \
... ...
@@ -92,9 +92,9 @@ am__clamd_SOURCES_DIST = $(top_srcdir)/shared/output.c \
92 92
 @BUILD_CLAMD_TRUE@	localserver.$(OBJEXT) session.$(OBJEXT) \
93 93
 @BUILD_CLAMD_TRUE@	thrmgr.$(OBJEXT) server-th.$(OBJEXT) \
94 94
 @BUILD_CLAMD_TRUE@	scanner.$(OBJEXT) others.$(OBJEXT) \
95
-@BUILD_CLAMD_TRUE@	clamuko.$(OBJEXT) \
95
+@BUILD_CLAMD_TRUE@	clamuko.$(OBJEXT) clamukofs.$(OBJEXT) \
96 96
 @BUILD_CLAMD_TRUE@	dazukoio_compat12.$(OBJEXT) \
97
-@BUILD_CLAMD_TRUE@	dazukoio.$(OBJEXT)
97
+@BUILD_CLAMD_TRUE@	dazukoio.$(OBJEXT) dazukofs.$(OBJEXT)
98 98
 clamd_OBJECTS = $(am_clamd_OBJECTS)
99 99
 clamd_LDADD = $(LDADD)
100 100
 AM_V_lt = $(am__v_lt_$(V))
... ...
@@ -317,12 +317,16 @@ top_srcdir = @top_srcdir@
317 317
 @BUILD_CLAMD_TRUE@    others.h \
318 318
 @BUILD_CLAMD_TRUE@    clamuko.c \
319 319
 @BUILD_CLAMD_TRUE@    clamuko.h \
320
+@BUILD_CLAMD_TRUE@    clamukofs.c \
321
+@BUILD_CLAMD_TRUE@    clamukofs.h \
320 322
 @BUILD_CLAMD_TRUE@    dazukoio_compat12.c \
321 323
 @BUILD_CLAMD_TRUE@    dazukoio_compat12.h \
322 324
 @BUILD_CLAMD_TRUE@    dazukoio.c \
323 325
 @BUILD_CLAMD_TRUE@    dazukoio.h \
324 326
 @BUILD_CLAMD_TRUE@    dazuko_xp.h \
325 327
 @BUILD_CLAMD_TRUE@    dazukoio_xp.h \
328
+@BUILD_CLAMD_TRUE@    dazukofs.c \
329
+@BUILD_CLAMD_TRUE@    dazukofs.h \
326 330
 @BUILD_CLAMD_TRUE@    shared.h
327 331
 
328 332
 AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/shared -I$(top_srcdir)/libclamav
... ...
@@ -436,6 +440,8 @@ distclean-compile:
436 436
 
437 437
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clamd.Po@am__quote@
438 438
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clamuko.Po@am__quote@
439
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clamukofs.Po@am__quote@
440
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dazukofs.Po@am__quote@
439 441
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dazukoio.Po@am__quote@
440 442
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dazukoio_compat12.Po@am__quote@
441 443
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt.Po@am__quote@
... ...
@@ -18,10 +18,6 @@
18 18
  *  MA 02110-1301, USA.
19 19
  */
20 20
 
21
-#ifdef	_MSC_VER
22
-#include <winsock.h>
23
-#endif
24
-
25 21
 #if HAVE_CONFIG_H
26 22
 #include "clamav-config.h"
27 23
 #endif
... ...
@@ -31,16 +27,18 @@
31 31
 #include <string.h>
32 32
 #ifdef HAVE_UNISTD_H
33 33
 #include <unistd.h>
34
+#endif
35
+#ifndef _WIN32
34 36
 #include <sys/time.h>
35 37
 #endif
36 38
 #include <sys/types.h>
37 39
 #include <sys/stat.h>
38 40
 #include <fcntl.h>
39 41
 #include <time.h>
40
-#ifdef C_WINDOWS
41
-#include <direct.h>	/* for chdir */
42
-#else
42
+#ifdef HAVE_PWD_H
43 43
 #include <pwd.h>
44
+#endif
45
+#ifdef HAVE_GRP_H
44 46
 #include <grp.h>
45 47
 #endif
46 48
 #include <signal.h>
... ...
@@ -70,10 +68,6 @@
70 70
 #include "others.h"
71 71
 #include "shared.h"
72 72
 
73
-#ifndef C_WINDOWS
74
-#define	closesocket(s)	close(s)
75
-#endif
76
-
77 73
 short debug_mode = 0, logok = 0;
78 74
 short foreground = 0;
79 75
 
... ...
@@ -112,12 +106,7 @@ int main(int argc, char **argv)
112 112
 	struct stat sb;
113 113
 #endif
114 114
 
115
-#ifdef C_WINDOWS
116
-    if(!pthread_win32_process_attach_np()) {
117
-	mprintf("!Can't start the win32 pthreads layer\n");
118
-        return 1;
119
-    }
120
-#else
115
+#ifndef _WIN32
121 116
     memset(&sa, 0, sizeof(sa));
122 117
     sa.sa_handler = SIG_IGN;
123 118
     sigaction(SIGHUP, &sa, NULL);
... ...
@@ -166,7 +155,7 @@ int main(int argc, char **argv)
166 166
     umask(0);
167 167
 
168 168
     /* drop privileges */
169
-#if (!defined(C_OS2)) && (!defined(C_WINDOWS))
169
+#ifndef _WIN32
170 170
     if(geteuid() == 0 && (opt = optget(opts, "User"))->enabled) {
171 171
 	if((user = getpwnam(opt->strarg)) == NULL) {
172 172
 	    fprintf(stderr, "ERROR: Can't get information about user %s.\n", opt->strarg);
... ...
@@ -223,7 +212,7 @@ int main(int argc, char **argv)
223 223
     if((opt = optget(opts, "LogFile"))->enabled) {
224 224
 	char timestr[32];
225 225
 	logg_file = opt->strarg;
226
-	if(strlen(logg_file) < 2 || (logg_file[0] != '/' && logg_file[0] != '\\' && logg_file[1] != ':')) {
226
+	if(!cli_is_abspath(logg_file)) {
227 227
 	    fprintf(stderr, "ERROR: LogFile requires full path.\n");
228 228
 	    ret = 1;
229 229
 	    break;
... ...
@@ -286,7 +275,7 @@ int main(int argc, char **argv)
286 286
 
287 287
     logg("#clamd daemon %s (OS: "TARGET_OS_TYPE", ARCH: "TARGET_ARCH_TYPE", CPU: "TARGET_CPU_TYPE")\n", get_version());
288 288
 
289
-#ifndef C_WINDOWS
289
+#ifndef _WIN32
290 290
     if(user)
291 291
 	logg("#Running as user %s (UID %u, GID %u)\n", user->pw_name, user->pw_uid, user->pw_gid);
292 292
 #endif
... ...
@@ -432,22 +421,13 @@ int main(int argc, char **argv)
432 432
     }
433 433
 
434 434
     if(tcpsock) {
435
-#ifdef C_WINDOWS
436
-	    WSADATA wsaData;
437
-
438
-	if(WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) {
439
-	    logg("!Error at WSAStartup(): %d\n", WSAGetLastError());
440
-	    ret = 1;
441
-	    break;
442
-	}
443
-#endif
444 435
 	if ((lsockets[nlsockets] = tcpserver(opts)) == -1) {
445 436
 	    ret = 1;
446 437
 	    break;
447 438
 	}
448 439
 	nlsockets++;
449 440
     }
450
-
441
+#ifndef _WIN32
451 442
     if(localsock) {
452 443
 	if ((lsockets[nlsockets] = localserver(opts)) == -1) {
453 444
 	    ret = 1;
... ...
@@ -480,6 +460,7 @@ int main(int argc, char **argv)
480 480
 
481 481
     } else
482 482
         foreground = 1;
483
+#endif
483 484
 
484 485
     ret = recvloop_th(lsockets, nlsockets, engine, dboptions, opts);
485 486
 
... ...
@@ -491,7 +472,7 @@ int main(int argc, char **argv)
491 491
 	closesocket(lsockets[i]);
492 492
     }
493 493
 
494
-#ifndef C_OS2
494
+#ifndef _WIN32
495 495
     if(nlsockets && localsock) {
496 496
 	opt = optget(opts, "LocalSocket");
497 497
 	if(unlink(opt->strarg) == -1)
... ...
@@ -501,18 +482,6 @@ int main(int argc, char **argv)
501 501
     }
502 502
 #endif
503 503
 
504
-#ifdef C_WINDOWS
505
-    if(tcpsock)
506
-	WSACleanup();
507
-
508
-    if(!pthread_win32_process_detach_np()) {
509
-	logg("!Can't stop the win32 pthreads layer\n");
510
-	logg_close();
511
-	optfree(opts);
512
-	return 1;
513
-    }
514
-#endif
515
-
516 504
     logg_close();
517 505
     optfree(opts);
518 506
 
... ...
@@ -39,6 +39,7 @@
39 39
 #include "server.h"
40 40
 #include "others.h"
41 41
 #include "dazukoio.h"
42
+#include "clamukofs.h"
42 43
 #include "clamuko.h"
43 44
 
44 45
 struct dazuko_access *acc;
... ...
@@ -62,7 +63,7 @@ static void clamuko_exit(int sig)
62 62
     pthread_exit(NULL);
63 63
 }
64 64
 
65
-void *clamukoth(void *arg)
65
+static void *clamukolegacyth(void *arg)
66 66
 {
67 67
 	struct thrarg *tharg = (struct thrarg *) arg;
68 68
 	sigset_t sigset;
... ...
@@ -200,4 +201,15 @@ void *clamukoth(void *arg)
200 200
     return NULL;
201 201
 }
202 202
 
203
+void *clamukoth(void *arg)
204
+{
205
+	struct stat s;
206
+
207
+    /* we use DazukoFS if /dev/dazukofs.ctrl exists and it is a
208
+     * character device, otherwise we use Dazuko */
209
+    if(stat("/dev/dazukofs.ctrl", &s) != 0) return clamukolegacyth(arg);
210
+    if(!S_ISCHR(s.st_mode)) return clamukolegacyth(arg);
211
+    return clamukofsth(arg);
212
+}
213
+
203 214
 #endif
204 215
new file mode 100644
... ...
@@ -0,0 +1,249 @@
0
+/*
1
+ *  Copyright (C) 2007-2009 Sourcefire, Inc.
2
+ *    Author: Tomasz Kojm
3
+ *    Author: John Ogness <dazukocode@ogness.net>
4
+ *
5
+ *  This program is free software; you can redistribute it and/or modify
6
+ *  it under the terms of the GNU General Public License version 2 as
7
+ *  published by the Free Software Foundation.
8
+ *
9
+ *  This program is distributed in the hope that it will be useful,
10
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
+ *  GNU General Public License for more details.
13
+ *
14
+ *  You should have received a copy of the GNU General Public License
15
+ *  along with this program; if not, write to the Free Software
16
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17
+ *  MA 02110-1301, USA.
18
+ */
19
+
20
+#if HAVE_CONFIG_H
21
+#include "clamav-config.h"
22
+#endif
23
+
24
+#ifdef CLAMUKO
25
+
26
+#include <stdio.h>
27
+#include <unistd.h>
28
+#include <sys/types.h>
29
+#include <sys/stat.h>
30
+#include <signal.h>
31
+#include <pthread.h>
32
+
33
+#include "libclamav/clamav.h"
34
+
35
+#include "shared/optparser.h"
36
+#include "shared/output.h"
37
+
38
+#include "server.h"
39
+#include "others.h"
40
+#include "dazukofs.h"
41
+#include "clamuko.h"
42
+
43
+static pthread_mutex_t running_mutex = PTHREAD_MUTEX_INITIALIZER;
44
+static dazukofs_handle_t shutdown_hndl;
45
+static pthread_cond_t shutdown_cond;
46
+
47
+static void clamuko_exit(int sig)
48
+{
49
+    pthread_cond_signal(&shutdown_cond);
50
+}
51
+
52
+static int setup_shutdown_handle(const char *groupname)
53
+{
54
+    /* is another server thread is already running? */
55
+    if(shutdown_hndl) return -1;
56
+
57
+    if(pthread_cond_init(&shutdown_cond, NULL)) return -1;
58
+
59
+    /* handle used for shutdown by signal */
60
+    shutdown_hndl = dazukofs_open(groupname, DAZUKOFS_TRACK_GROUP);
61
+    if(!shutdown_hndl) {
62
+	logg("!Clamuko: Can't register with DazukoFS\n");
63
+	return -1;
64
+    }
65
+    return 0;
66
+}
67
+
68
+static void shutdown_clamuko(void)
69
+{
70
+	dazukofs_handle_t hndl = shutdown_hndl;
71
+
72
+    /* Set shutdown_hndl before closing because the close will
73
+     * immediately cause the scan threads to be interrupted.
74
+     * But they will only abort if shutdown_hndl is NULL. */
75
+    shutdown_hndl = NULL;
76
+
77
+    if(hndl) dazukofs_close(hndl, DAZUKOFS_REMOVE_GROUP);
78
+}
79
+
80
+static void *clamuko_scanth(void *arg)
81
+{
82
+	struct thrarg *tharg = (struct thrarg *) arg;
83
+	sigset_t sigset;
84
+	short int scan;
85
+	unsigned int sizelimit = 0;
86
+	struct stat sb;
87
+	dazukofs_handle_t scan_hndl;
88
+	struct dazukofs_access acc;
89
+	const char *groupname = "ClamAV";
90
+	int skip_scan = 0;
91
+	const char *virname;
92
+	char filename[4096];
93
+
94
+    /* ignore all signals */
95
+    sigfillset(&sigset);
96
+    /* The behavior of a process is undefined after it ignores a
97
+     * SIGFPE, SIGILL, SIGSEGV, or SIGBUS signal */
98
+    sigdelset(&sigset, SIGFPE);
99
+    sigdelset(&sigset, SIGILL);
100
+    sigdelset(&sigset, SIGSEGV);
101
+#ifdef SIGBUS
102
+    sigdelset(&sigset, SIGBUS);
103
+#endif
104
+    pthread_sigmask(SIG_SETMASK, &sigset, NULL);
105
+
106
+    /* register */
107
+    scan_hndl = dazukofs_open(groupname, DAZUKOFS_TRACK_GROUP);
108
+    if(!scan_hndl) {
109
+	logg("!Clamuko: Can't register with DazukoFS\n");
110
+	return NULL;
111
+    } else {
112
+	logg("Clamuko: Correctly registered with DazukoFS.\n");
113
+    }
114
+
115
+    /* access mask (not used by DazukoFS) */
116
+    if(optget(tharg->opts, "ClamukoScanOnOpen")->enabled)
117
+	logg("!Clamuko: ClamukoScanOnOpen ignored when using DazukoFS.\n");
118
+    if(optget(tharg->opts, "ClamukoScanOnClose")->enabled)
119
+	logg("!Clamuko: ClamukoScanOnClose ignored when using DazukoFS.\n");
120
+    if(optget(tharg->opts, "ClamukoScanOnExec")->enabled)
121
+	logg("!Clamuko: ClamukoScanOnExec ignored when using DazukoFS.\n");
122
+    if(optget(tharg->opts, "ClamukoIncludePath")->enabled)
123
+	logg("!Clamuko: ClamukoIncludePath ignored when using DazukoFS.\n");
124
+    if(optget(tharg->opts, "ClamukoExcludePath")->enabled)
125
+	logg("!Clamuko: ClamukoExcludePath ignored when using DazukoFS.\n");
126
+
127
+    sizelimit = optget(tharg->opts, "ClamukoMaxFileSize")->numarg;
128
+    if(sizelimit)
129
+	logg("Clamuko: Max file size limited to %u bytes.\n", sizelimit);
130
+    else
131
+	logg("Clamuko: File size limit disabled.\n");
132
+
133
+    while(1) {
134
+	if(dazukofs_get_access(scan_hndl, &acc)) {
135
+	    if(!shutdown_hndl)
136
+		break;
137
+	    continue;
138
+	}
139
+
140
+	if(!fstat(acc.fd, &sb)) {
141
+	    if(S_ISDIR(sb.st_mode)) {
142
+		/* don't try to scan directories */
143
+		skip_scan = 1;
144
+	    } else if(sb.st_size > sizelimit) {
145
+		dazukofs_get_filename(&acc, filename, sizeof(filename));
146
+		logg("*Clamuko: %s skipped (too big)\n", filename);
147
+		skip_scan = 1;
148
+	    }
149
+	}
150
+
151
+	if(skip_scan) {
152
+	    acc.deny = 0;
153
+	    /* reset skip flag */
154
+	    skip_scan = 0;
155
+	} else if(cl_scandesc(acc.fd, &virname, NULL, tharg->engine,
156
+			      tharg->options) == CL_VIRUS) {
157
+	    dazukofs_get_filename(&acc, filename, sizeof(filename));
158
+	    logg("Clamuko: %s: %s FOUND\n", filename, virname);
159
+	    /* we can not perform any special action because it will
160
+	     * trigger DazukoFS recursively */
161
+	    acc.deny = 1;
162
+	} else {
163
+	    acc.deny = 0;
164
+	}
165
+
166
+	if(dazukofs_return_access(scan_hndl, &acc)) {
167
+	    if(shutdown_hndl)
168
+	        logg("!Clamuko: Can't return access to DazukoFS.\n");
169
+	    break;
170
+	}
171
+    }
172
+
173
+    dazukofs_close(scan_hndl, 0);
174
+
175
+    if(shutdown_hndl)
176
+        logg("!Clamuko: A scanner thread has unexpectedly shutdown.\n");
177
+
178
+    return NULL;
179
+}
180
+
181
+void *clamukofsth(void *arg)
182
+{
183
+	struct thrarg *tharg = (struct thrarg *) arg;
184
+	sigset_t sigset;
185
+        struct sigaction act;
186
+	pthread_t *clamuko_pids = NULL;
187
+	const char *groupname = "ClamAV";
188
+	int count;
189
+	int started;
190
+
191
+    /* is another server thread already working? */
192
+    if(pthread_mutex_trylock(&running_mutex))
193
+	return NULL;
194
+
195
+    /* ignore all signals except SIGUSR1 */
196
+    sigfillset(&sigset);
197
+    sigdelset(&sigset, SIGUSR1);
198
+    /* The behavior of a process is undefined after it ignores a
199
+     * SIGFPE, SIGILL, SIGSEGV, or SIGBUS signal */
200
+    sigdelset(&sigset, SIGFPE);
201
+    sigdelset(&sigset, SIGILL);
202
+    sigdelset(&sigset, SIGSEGV);
203
+#ifdef SIGBUS
204
+    sigdelset(&sigset, SIGBUS);
205
+#endif
206
+    pthread_sigmask(SIG_SETMASK, &sigset, NULL);
207
+
208
+    count = optget(tharg->opts, "ClamukoScannerCount")->numarg;
209
+    if(count < 1) goto out;
210
+
211
+    clamuko_pids = calloc(count, sizeof(pthread_t));
212
+    if(!clamuko_pids) goto out;
213
+
214
+    if(setup_shutdown_handle(groupname)) goto out;
215
+
216
+    act.sa_handler = clamuko_exit;
217
+    sigfillset(&(act.sa_mask));
218
+    sigaction(SIGUSR1, &act, NULL);
219
+    sigaction(SIGSEGV, &act, NULL);
220
+
221
+    for(started = 0; started < count; started++) {
222
+	pthread_attr_t clamuko_attr;
223
+
224
+	if(pthread_attr_init(&clamuko_attr)) break;
225
+	pthread_attr_setdetachstate(&clamuko_attr, PTHREAD_CREATE_JOINABLE);
226
+	if(pthread_create(&clamuko_pids[started], &clamuko_attr,
227
+			  clamuko_scanth, tharg)) break;
228
+	logg("Clamuko: Started scanner thread %d.\n", started);
229
+    }
230
+
231
+    pthread_cond_wait(&shutdown_cond, &running_mutex);
232
+    logg("Clamuko: Stop signal received.\n");
233
+
234
+    shutdown_clamuko();
235
+
236
+    for(started-- ; started >= 0; started--) {
237
+	logg("Clamuko: Waiting for scanner thread %d to finish.\n", started);
238
+	pthread_join(clamuko_pids[started], NULL);
239
+    }
240
+
241
+    logg("Clamuko: Stopped.\n");
242
+out:
243
+    if(clamuko_pids) free(clamuko_pids);
244
+    pthread_mutex_unlock(&running_mutex);
245
+    return NULL;
246
+}
247
+
248
+#endif
0 249
new file mode 100644
... ...
@@ -0,0 +1,28 @@
0
+/*
1
+ *  Copyright (C) 2009 Sourcefire, Inc.
2
+ *    Author: John Ogness <dazukocode@ogness.net>
3
+ *
4
+ *  This program is free software; you can redistribute it and/or modify
5
+ *  it under the terms of the GNU General Public License version 2 as
6
+ *  published by the Free Software Foundation.
7
+ *
8
+ *  This program is distributed in the hope that it will be useful,
9
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
+ *  GNU General Public License for more details.
12
+ *
13
+ *  You should have received a copy of the GNU General Public License
14
+ *  along with this program; if not, write to the Free Software
15
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
16
+ *  MA 02110-1301, USA.
17
+ */
18
+
19
+#ifdef CLAMUKO
20
+
21
+#ifndef __CLAMUKO_H
22
+#define __CLAMUKO_H
23
+
24
+extern void *clamukofsth(void *arg);
25
+
26
+#endif
27
+#endif
0 28
new file mode 100644
... ...
@@ -0,0 +1,238 @@
0
+/* userspace library to interface with dazukofs
1
+
2
+   Copyright (C) 2008-2009 John Ogness
3
+     Author: John Ogness <dazukocode@ogness.net>
4
+
5
+   This library is free software; you can redistribute it and/or
6
+   modify it under the terms of the GNU Lesser General Public
7
+   License as published by the Free Software Foundation; either
8
+   version 2.1 of the License, or (at your option) any later version.
9
+
10
+   This library is distributed in the hope that it will be useful,
11
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
+   GNU Lesser General Public License for more details.
14
+
15
+   You should have received a copy of the GNU Lesser General Public
16
+   License along with this library; if not, write to the Free Software
17
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18
+*/
19
+
20
+#include <stdio.h>
21
+#include <stdlib.h>
22
+#include <string.h>
23
+#include <fcntl.h>
24
+#include <unistd.h>
25
+
26
+#include <sys/types.h>
27
+#include <sys/stat.h>
28
+
29
+#include "dazukofs.h"
30
+
31
+struct dazukofs_handle
32
+{
33
+	int dev_fd;
34
+	unsigned long event_id;
35
+	char *group_name;
36
+};
37
+
38
+#define DAZUKOFS_ALLOWED_GROUPCHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-"
39
+static int check_group_name(const char *gname)
40
+{
41
+	size_t len = strlen(gname);
42
+	const char *p;
43
+
44
+	if (len > 20)
45
+		return -1;
46
+
47
+	for (p = gname; *p; p++) {
48
+		if (strchr(DAZUKOFS_ALLOWED_GROUPCHARS, *p) == NULL)
49
+			return -1;
50
+	}
51
+
52
+	return 0;
53
+}
54
+
55
+dazukofs_handle_t dazukofs_open(const char *gname, int flags)
56
+{
57
+	struct dazukofs_handle *hndl = NULL;
58
+	char key[25];
59
+	char buf[256];
60
+	char *p;
61
+	int gid;
62
+	int fd;
63
+
64
+	if (check_group_name(gname) != 0)
65
+		goto error_out;
66
+
67
+	fd = open("/dev/dazukofs.ctrl", O_RDWR);
68
+	if (fd == -1) {
69
+		/* try to read at least
70
+		 * (maybe the group already exists) */
71
+		fd = open("/dev/dazukofs.ctrl", O_RDONLY);
72
+		if (fd == -1)
73
+			goto error_out;
74
+	} else {
75
+		memset(buf, 0, sizeof(buf));
76
+
77
+		if (flags & DAZUKOFS_TRACK_GROUP)
78
+			snprintf(buf, sizeof(buf) - 1, "addtrack=%s", gname);
79
+		else
80
+			snprintf(buf, sizeof(buf) - 1, "add=%s", gname);
81
+
82
+		if (write(fd, buf, strlen(buf)) == -1)
83
+			goto error_out_close;
84
+
85
+		lseek(fd, 0, SEEK_SET);
86
+	}
87
+
88
+	memset(buf, 0, sizeof(buf));
89
+	if (read(fd, buf, sizeof(buf)-1) == -1)
90
+		goto error_out_close;
91
+
92
+	memset(key, 0, sizeof(key));
93
+	snprintf(key, sizeof(key) - 1, ":%s\n", gname);
94
+
95
+	p = strstr(buf, key);
96
+	if (!p || p == buf)
97
+		goto error_out_close;
98
+
99
+	p--;
100
+	gid = *p - '0';
101
+	if (gid < 0 || gid > 9)
102
+		goto error_out_close;
103
+
104
+	hndl = malloc(sizeof(struct dazukofs_handle));
105
+	if (!hndl)
106
+		goto error_out_close;
107
+	memset(hndl, 0, sizeof(struct dazukofs_handle));
108
+
109
+	hndl->group_name = strdup(gname);
110
+	if (!hndl->group_name)
111
+		goto error_out_free;
112
+
113
+	memset(key, 0, sizeof(key));
114
+	snprintf(key, sizeof(key) - 1, "/dev/dazukofs.%d", gid);
115
+
116
+	hndl->dev_fd = open(key, O_RDWR);
117
+	if (hndl->dev_fd == -1)
118
+		goto error_out_free;
119
+
120
+	close(fd);
121
+
122
+	return hndl;
123
+
124
+error_out_free:
125
+	if (hndl->group_name)
126
+		free(hndl->group_name);
127
+	free(hndl);
128
+	hndl = NULL;
129
+error_out_close:
130
+	close(fd);
131
+error_out:
132
+	return hndl;
133
+}
134
+
135
+int dazukofs_close(dazukofs_handle_t hndl, int flags)
136
+{
137
+	char buf[48];
138
+	int fd;
139
+	int ret = -1;
140
+
141
+	if (flags & DAZUKOFS_REMOVE_GROUP) {
142
+		fd = open("/dev/dazukofs.ctrl", O_WRONLY);
143
+		if (fd == -1)
144
+			goto error_out;
145
+
146
+		memset(buf, 0, sizeof(buf));
147
+		snprintf(buf, sizeof(buf) - 1, "del=%s", hndl->group_name);
148
+
149
+		if (write(fd, buf, strlen(buf)) == -1) {
150
+			close(fd);
151
+			goto error_out;
152
+		}
153
+
154
+		close(fd);
155
+	}
156
+
157
+	ret = close(hndl->dev_fd);
158
+	if (ret != 0)
159
+		goto error_out;
160
+
161
+	free(hndl->group_name);
162
+	free(hndl);
163
+
164
+	return 0;
165
+
166
+error_out:
167
+	return ret;
168
+}
169
+
170
+int dazukofs_get_access(dazukofs_handle_t hndl, struct dazukofs_access *acc)
171
+{
172
+	char buf[48];
173
+	char *p;
174
+	int err = -1;
175
+
176
+	memset(buf, 0, sizeof(buf));
177
+	if (read(hndl->dev_fd, buf, sizeof(buf)-1) == -1)
178
+		goto out;
179
+
180
+	p = strstr(buf, "id=");
181
+	if (!p)
182
+		goto out;
183
+	p += 3;
184
+	hndl->event_id = strtoul(p, &p, 10);
185
+
186
+	p = strstr(p, "fd=");
187
+	if (!p)
188
+		goto out;
189
+	p += 3;
190
+	acc->fd = (int)strtol(p, &p, 10);
191
+
192
+	p = strstr(p, "pid=");
193
+	if (!p)
194
+		goto out;
195
+	p += 4;
196
+	acc->pid = strtoul(p, NULL, 10);
197
+
198
+	acc->deny = 0;
199
+
200
+	err = 0;
201
+out:
202
+	return err;
203
+}
204
+
205
+int dazukofs_return_access(dazukofs_handle_t hndl, struct dazukofs_access *acc)
206
+{
207
+	char buf[48];
208
+	int err = -1;
209
+
210
+	if (close(acc->fd) != 0)
211
+		goto out;
212
+	snprintf(buf, sizeof(buf)-1, "id=%lu r=%d", hndl->event_id,
213
+		 acc->deny ? 1 : 0);
214
+	buf[sizeof(buf)-1] = 0;
215
+
216
+	if (write(hndl->dev_fd, buf, strlen(buf)) == -1)
217
+		goto out;
218
+	lseek(hndl->dev_fd, 0, SEEK_SET);
219
+	err = 0;
220
+out:
221
+	return err;
222
+}
223
+
224
+int dazukofs_get_filename(struct dazukofs_access *acc, char *buf, size_t bufsiz)
225
+{
226
+	char proc[48];
227
+	int ret;
228
+
229
+	memset(proc, 0, sizeof(proc));
230
+	snprintf(proc, sizeof(proc) - 1, "/proc/self/fd/%d", acc->fd);
231
+	ret = readlink(proc, buf, bufsiz - 1);
232
+	buf[bufsiz - 1] = 0;
233
+	if (ret > 0)
234
+		buf[ret] = 0;
235
+
236
+	return ret;
237
+}
0 238
new file mode 100644
... ...
@@ -0,0 +1,48 @@
0
+/* userspace library to interface with dazukofs
1
+
2
+   Copyright (C) 2008 John Ogness
3
+     Author: John Ogness <dazukocode@ogness.net>
4
+
5
+   This library is free software; you can redistribute it and/or
6
+   modify it under the terms of the GNU Lesser General Public
7
+   License as published by the Free Software Foundation; either
8
+   version 2.1 of the License, or (at your option) any later version.
9
+
10
+   This library is distributed in the hope that it will be useful,
11
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
+   GNU Lesser General Public License for more details.
14
+
15
+   You should have received a copy of the GNU Lesser General Public
16
+   License along with this library; if not, write to the Free Software
17
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18
+*/
19
+
20
+#ifndef __DAZUKOFS_H
21
+#define __DAZUKOFS_H
22
+
23
+#include <stdio.h>
24
+
25
+/* dazukofs_open() flags */
26
+#define DAZUKOFS_TRACK_GROUP 1
27
+
28
+/* dazukofs_close() flags */
29
+#define DAZUKOFS_REMOVE_GROUP 1
30
+
31
+struct dazukofs_handle;
32
+typedef struct dazukofs_handle * dazukofs_handle_t;
33
+
34
+struct dazukofs_access
35
+{
36
+	int fd;
37
+	int deny;
38
+	unsigned long pid;
39
+};
40
+
41
+dazukofs_handle_t dazukofs_open(const char *gname, int flags);
42
+int dazukofs_get_access(dazukofs_handle_t hndl, struct dazukofs_access *acc);
43
+int dazukofs_return_access(dazukofs_handle_t hndl, struct dazukofs_access *acc);
44
+int dazukofs_close(dazukofs_handle_t hndl, int flags);
45
+int dazukofs_get_filename(struct dazukofs_access *acc, char *buf, size_t bufsiz);
46
+
47
+#endif /* __DAZUKOFS_H */
... ...
@@ -18,10 +18,6 @@
18 18
  *  MA 02110-1301, USA.
19 19
  */
20 20
 
21
-#ifdef	_MSC_VER
22
-#include <winsock.h>
23
-#endif
24
-
25 21
 #if HAVE_CONFIG_H
26 22
 #include "clamav-config.h"
27 23
 #endif
... ...
@@ -39,20 +35,17 @@
39 39
 #include <time.h>
40 40
 #include <sys/stat.h>
41 41
 #include <errno.h>
42
-#ifndef	C_WINDOWS
42
+#ifndef	_WIN32
43 43
 #include <sys/time.h>
44 44
 #include <sys/wait.h>
45
+#include <sys/socket.h>
46
+#include <sys/ioctl.h>
45 47
 #endif
46 48
 
47 49
 #if HAVE_SYS_PARAM_H
48 50
 #include <sys/param.h>
49 51
 #endif
50 52
 
51
-#ifndef	C_WINDOWS
52
-#include <sys/socket.h>
53
-#include <sys/ioctl.h>
54
-#endif
55
-
56 53
 #ifdef HAVE_SYS_TYPES_H
57 54
 #include <sys/types.h>
58 55
 #endif
... ...
@@ -61,11 +54,6 @@
61 61
 #endif
62 62
 
63 63
 #include <pthread.h>
64
-/* submitted by breiter@wolfereiter.com: do not use poll(2) on Interix */
65
-#ifdef C_INTERIX
66
-#undef HAVE_POLL
67
-#undef HAVE_POLL_H
68
-#endif
69 64
 
70 65
 #if HAVE_POLL
71 66
 #if HAVE_POLL_H
... ...
@@ -87,7 +75,7 @@
87 87
 #include "others.h"
88 88
 #include "misc.h"
89 89
 
90
-#ifdef	C_WINDOWS
90
+#ifdef	_WIN32
91 91
 void virusaction(const char *filename, const char *virname, const struct optstruct *opts)
92 92
 {
93 93
     if(optget(opts, "VirusEvent")->enabled)
... ...
@@ -166,7 +154,7 @@ void virusaction(const char *filename, const char *virname, const struct optstru
166 166
 	free(buffer_file);
167 167
 	free(buffer_vir);
168 168
 }
169
-#endif /* C_WINDOWS */
169
+#endif /* _WIN32 */
170 170
 
171 171
 /* Function: writen
172 172
 	Try hard to write the specified number of bytes
... ...
@@ -421,9 +409,6 @@ void fds_remove(struct fd_data *data, int fd)
421 421
     fds_unlock(data);
422 422
 }
423 423
 
424
-#ifndef	C_WINDOWS
425
-#define	closesocket(s)	close(s)
426
-#endif
427 424
 #define BUFFSIZE 1024
428 425
 /* Wait till data is available to be read on any of the fds,
429 426
  * read available data on all fds, and mark them as appropriate.
... ...
@@ -18,10 +18,6 @@
18 18
  *  MA 02110-1301, USA.
19 19
  */
20 20
 
21
-#ifdef	_MSC_VER
22
-#include <winsock.h>
23
-#endif
24
-
25 21
 #if HAVE_CONFIG_H
26 22
 #include "clamav-config.h"
27 23
 #endif
... ...
@@ -35,12 +31,12 @@
35 35
 #include <errno.h>
36 36
 #include <sys/stat.h>
37 37
 #include <sys/types.h>
38
-#ifndef	C_WINDOWS
38
+#include <dirent.h>
39
+#ifndef	_WIN32
39 40
 #include <sys/time.h>
40 41
 #include <sys/wait.h>
41 42
 #include <sys/param.h>
42 43
 #include <signal.h>
43
-#include <dirent.h>
44 44
 #include <sys/socket.h>
45 45
 #include <netinet/in.h>
46 46
 #include <arpa/inet.h>
... ...
@@ -71,10 +67,6 @@
71 71
 dev_t procdev; /* /proc device */
72 72
 #endif
73 73
 
74
-#ifndef	C_WINDOWS
75
-#define	closesocket(s)	close(s)
76
-#endif
77
-
78 74
 extern int progexit;
79 75
 extern time_t reloaded_time;
80 76
 extern pthread_mutex_t reload_mutex;
... ...
@@ -19,10 +19,6 @@
19 19
  *  MA 02110-1301, USA.
20 20
  */
21 21
 
22
-#ifdef	_MSC_VER
23
-#include <winsock.h>
24
-#endif
25
-
26 22
 #if HAVE_CONFIG_H
27 23
 #include "clamav-config.h"
28 24
 #endif
... ...
@@ -34,17 +30,17 @@
34 34
 #include <string.h>
35 35
 #include <time.h>
36 36
 #include <sys/types.h>
37
-#ifndef	C_WINDOWS
37
+#ifndef	_WIN32
38 38
 #include <sys/socket.h>
39 39
 #include <sys/time.h>
40 40
 #include <sys/resource.h>
41
+#include <arpa/inet.h>
41 42
 #endif
42 43
 #ifdef	HAVE_UNISTD_H
43 44
 #include <unistd.h>
44 45
 #endif
45 46
 
46 47
 #include <fcntl.h>
47
-#include <arpa/inet.h>
48 48
 #include "libclamav/clamav.h"
49 49
 
50 50
 #include "shared/output.h"
... ...
@@ -60,17 +56,7 @@
60 60
 #include "libclamav/readdb.h"
61 61
 #include "libclamav/cltypes.h"
62 62
 
63
-#ifndef	C_WINDOWS
64
-#define	closesocket(s)	close(s)
65
-#endif
66
-
67 63
 #define BUFFSIZE 1024
68
-#ifndef	FALSE
69
-#define FALSE (0)
70
-#endif
71
-#ifndef	TRUE
72
-#define TRUE (1)
73
-#endif
74 64
 
75 65
 int progexit = 0;
76 66
 pthread_mutex_t exit_mutex = PTHREAD_MUTEX_INITIALIZER;
... ...
@@ -83,13 +69,13 @@ static struct cl_stat dbstat;
83 83
 static void scanner_thread(void *arg)
84 84
 {
85 85
 	client_conn_t *conn = (client_conn_t *) arg;
86
-#ifndef	C_WINDOWS
86
+#ifndef	_WIN32
87 87
 	sigset_t sigset;
88 88
 #endif
89 89
 	int ret;
90 90
 	unsigned virus=0, errors = 0;
91 91
 
92
-#ifndef	C_WINDOWS
92
+#ifndef	_WIN32
93 93
     /* ignore all signals */
94 94
     sigfillset(&sigset);
95 95
     /* The behavior of a process is undefined after it ignores a 
... ...
@@ -686,7 +672,7 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
686 686
 	int max_threads, max_queue, readtimeout, ret = 0;
687 687
 	unsigned int options = 0;
688 688
 	char timestr[32];
689
-#ifndef	C_WINDOWS
689
+#ifndef	_WIN32
690 690
 	struct sigaction sigact;
691 691
 	sigset_t sigset;
692 692
 	struct rlimit rlim;
... ...
@@ -713,7 +699,7 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
713 713
 	struct thrarg *tharg = NULL; /* shut up gcc */
714 714
 #endif
715 715
 
716
-#ifndef	C_WINDOWS
716
+#ifndef	_WIN32
717 717
 	memset(&sigact, 0, sizeof(struct sigaction));
718 718
 #endif
719 719
 
... ...
@@ -744,7 +730,7 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
744 744
     else
745 745
     	logg("^Limits: File size limit protection disabled.\n");
746 746
 
747
-#ifndef C_WINDOWS
747
+#ifndef _WIN32
748 748
     if(getrlimit(RLIMIT_FSIZE, &rlim) == 0) {
749 749
 	if(rlim.rlim_cur < (rlim_t) cl_engine_get_num(engine, CL_ENGINE_MAX_FILESIZE, NULL))
750 750
 	    logg("^System limit for file size is lower than engine->maxfilesize\n");
... ...
@@ -781,7 +767,7 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
781 781
     else
782 782
     	logg("^Limits: Files limit protection disabled.\n");
783 783
 
784
-#if !defined(C_WINDOWS)
784
+#ifndef _WIN32
785 785
     if (getrlimit(RLIMIT_CORE, &rlim) == 0) {
786 786
 	logg("*Limits: Core-dump limit is %lu.\n", (unsigned long)rlim.rlim_cur);
787 787
     }
... ...
@@ -940,7 +926,7 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
940 940
     acceptdata.commandtimeout = optget(opts, "CommandReadTimeout")->numarg;
941 941
     readtimeout = optget(opts, "ReadTimeout")->numarg;
942 942
 
943
-#if !defined(C_WINDOWS) && defined(RLIMIT_NOFILE)
943
+#if !defined(_WIN32) && defined(RLIMIT_NOFILE)
944 944
     if (getrlimit(RLIMIT_NOFILE, &rlim) == 0) {
945 945
 	/* don't warn if default value is too high, silently fix it */
946 946
 	unsigned maxrec;
... ...
@@ -1000,7 +986,7 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
1000 1000
 	logg("Clamuko is not available.\n");
1001 1001
 #endif
1002 1002
 
1003
-#ifndef	C_WINDOWS
1003
+#ifndef	_WIN32
1004 1004
     /* set up signal handling */
1005 1005
     sigfillset(&sigset);
1006 1006
     sigdelset(&sigset, SIGINT);
... ...
@@ -1253,6 +1239,13 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
1253 1253
 	pthread_mutex_lock(&reload_mutex);
1254 1254
 	if(reload) {
1255 1255
 	    pthread_mutex_unlock(&reload_mutex);
1256
+#ifdef CLAMUKO
1257
+	    if(optget(opts, "ClamukoScanOnAccess")->enabled && tharg) {
1258
+		logg("Stopping and restarting Clamuko.\n");
1259
+		pthread_kill(clamuko_pid, SIGUSR1);
1260
+		pthread_join(clamuko_pid, NULL);
1261
+	    }
1262
+#endif
1256 1263
 	    engine = reload_db(engine, dboptions, opts, FALSE, &ret);
1257 1264
 	    if(ret) {
1258 1265
 		logg("Terminating because of a fatal error.\n");
... ...
@@ -1267,9 +1260,6 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
1267 1267
 	    pthread_mutex_unlock(&reload_mutex);
1268 1268
 #ifdef CLAMUKO
1269 1269
 	    if(optget(opts, "ClamukoScanOnAccess")->enabled && tharg) {
1270
-		logg("Stopping and restarting Clamuko.\n");
1271
-		pthread_kill(clamuko_pid, SIGUSR1);
1272
-		pthread_join(clamuko_pid, NULL);
1273 1270
 		tharg->engine = engine;
1274 1271
 		pthread_create(&clamuko_pid, &clamuko_attr, clamukoth, tharg);
1275 1272
 	    }
... ...
@@ -18,10 +18,6 @@
18 18
  *  MA 02110-1301, USA.
19 19
  */
20 20
 
21
-#ifdef	_MSC_VER
22
-#include <winsock.h>
23
-#endif
24
-
25 21
 #if HAVE_CONFIG_H
26 22
 #include "clamav-config.h"
27 23
 #endif
... ...
@@ -33,12 +29,12 @@
33 33
 #include <unistd.h>
34 34
 #endif
35 35
 #include <sys/types.h>
36
-#ifndef	C_WINDOWS
37 36
 #include <dirent.h>
37
+#ifndef	_WIN32
38
+#include <sys/socket.h>
38 39
 #ifdef HAVE_SYS_SELECT_H
39 40
 #include <sys/select.h>
40 41
 #endif
41
-#include <sys/socket.h>
42 42
 #ifdef HAVE_FD_PASSING
43 43
 #ifdef HAVE_SYS_UIO_H
44 44
 #include <sys/uio.h>
... ...
@@ -18,10 +18,6 @@
18 18
  *  MA 02110-1301, USA.
19 19
  */
20 20
 
21
-#ifdef	_MSC_VER
22
-#include <winsock.h>
23
-#endif
24
-
25 21
 #if HAVE_CONFIG_H
26 22
 #include "clamav-config.h"
27 23
 #endif
... ...
@@ -32,15 +28,13 @@
32 32
 #ifdef HAVE_UNISTD_H
33 33
 #include <unistd.h>
34 34
 #endif
35
-#ifndef	C_WINDOWS
35
+#ifndef	_WIN32
36 36
 #include <sys/socket.h>
37 37
 #include <netinet/in.h>
38 38
 #include <arpa/inet.h>
39
-#endif
40
-#include <errno.h>
41
-#ifndef	C_WINDOWS
42 39
 #include <netdb.h>
43 40
 #endif
41
+#include <errno.h>
44 42
 
45 43
 #include "libclamav/clamav.h"
46 44
 
... ...
@@ -52,9 +46,6 @@
52 52
 #include "server.h"
53 53
 #include "tcpserver.h"
54 54
 #include "misc.h"
55
-#ifndef	C_WINDOWS
56
-#define	closesocket(s)	close(s)
57
-#endif
58 55
 
59 56
 int tcpserver(const struct optstruct *opts)
60 57
 {
... ...
@@ -40,9 +40,6 @@
40 40
 #include <malloc.h>
41 41
 #endif
42 42
 
43
-#define FALSE (0)
44
-#define TRUE (1)
45
-
46 43
 /* BSD and HP-UX need a bigger stacksize than the system default */
47 44
 #if defined (C_BSD) || defined (C_HPUX) || defined(C_AIX)
48 45
 #define C_BIGSTACK 1
... ...
@@ -455,7 +452,7 @@ threadpool_t *thrmgr_new(int max_threads, int idle_timeout, int max_queue, void
455 455
 	pthread_attr_getstacksize(&(threadpool->pool_attr), &stacksize);
456 456
 	stacksize = stacksize + 64 * 1024;
457 457
 	if (stacksize < 1048576) stacksize = 1048576; /* at least 1MB please */
458
-	logg("Set stacksize to %u\n", stacksize);
458
+	logg("Set stacksize to %lu\n", (unsigned long int) stacksize);
459 459
 	pthread_attr_setstacksize(&(threadpool->pool_attr), stacksize);
460 460
 #endif
461 461
 	threadpool->state = POOL_VALID;
... ...
@@ -24,7 +24,7 @@
24 24
 
25 25
 #include <pthread.h>
26 26
 
27
-#ifndef C_WINDOWS
27
+#ifndef _WIN32
28 28
 #include <sys/time.h>
29 29
 #endif
30 30
 
... ...
@@ -26,7 +26,9 @@
26 26
 #include <string.h>
27 27
 #include <stdlib.h>
28 28
 #include <unistd.h>
29
+#ifndef _WIN32
29 30
 #include <sys/time.h>
31
+#endif
30 32
 #include <time.h>
31 33
 #include <signal.h>
32 34
 
... ...
@@ -51,7 +53,7 @@ static void print_server_version(const struct optstruct *opt)
51 51
 
52 52
 int main(int argc, char **argv)
53 53
 {
54
-	int ds, dms, ret, infected;
54
+	int ds, dms, ret, infected = 0;
55 55
 	struct timeval t1, t2;
56 56
 	struct timezone tz;
57 57
 	time_t starttime;
... ...
@@ -30,16 +30,20 @@
30 30
 #include <string.h>
31 31
 #include <sys/types.h>
32 32
 #include <sys/stat.h>
33
-#include <sys/socket.h>
34 33
 #ifdef HAVE_SYS_LIMITS_H
35 34
 #include <sys/limits.h>
36 35
 #endif
36
+#ifdef HAVE_SYS_SELECT_H
37 37
 #include <sys/select.h>
38
+#endif
39
+#ifndef _WIN32
40
+#include <sys/socket.h>
38 41
 #include <sys/un.h>
39 42
 #include <netinet/in.h>
40 43
 #include <arpa/inet.h>
41 44
 #include <netdb.h>
42 45
 #include <utime.h>
46
+#endif
43 47
 #include <errno.h>
44 48
 #include <dirent.h>
45 49
 #include <fcntl.h>
... ...
@@ -65,7 +69,9 @@
65 65
 struct sockaddr *mainsa = NULL;
66 66
 int mainsasz;
67 67
 unsigned long int maxstream;
68
+#ifndef _WIN32
68 69
 static struct sockaddr_un nixsock;
70
+#endif
69 71
 static struct sockaddr_in tcpsock;
70 72
 
71 73
 
... ...
@@ -82,6 +88,7 @@ static int isremote(const struct optstruct *opts) {
82 82
 	logg("!Can't parse clamd configuration file %s\n", clamd_conf);
83 83
 	return 0;
84 84
     }
85
+#ifndef _WIN32
85 86
     if((opt = optget(clamdopts, "LocalSocket"))->enabled) {
86 87
 	memset((void *)&nixsock, 0, sizeof(nixsock));
87 88
 	nixsock.sun_family = AF_UNIX;
... ...
@@ -92,6 +99,7 @@ static int isremote(const struct optstruct *opts) {
92 92
 	optfree(clamdopts);
93 93
 	return 0;
94 94
     }
95
+#endif
95 96
     if(!(opt = optget(clamdopts, "TCPSocket"))->enabled) {
96 97
 	optfree(clamdopts);
97 98
 	return 0;
... ...
@@ -110,7 +118,7 @@ static int isremote(const struct optstruct *opts) {
110 110
     testsock.sin_port = htons(INADDR_ANY);
111 111
     if(!(s = socket(testsock.sin_family, SOCK_STREAM, 0))) return 0;
112 112
     ret = (bind(s, (struct sockaddr *)&testsock, sizeof(testsock)) != 0);
113
-    close(s);
113
+    closesocket(s);
114 114
     return ret;
115 115
 }
116 116
 
... ...
@@ -126,14 +134,14 @@ static char *makeabs(const char *basepath) {
126 126
 	logg("^Can't make room for fullpath.\n");
127 127
 	return NULL;
128 128
     }
129
-    if(*basepath != '/') { /* FIXME: to be unified */
129
+    if(!cli_is_abspath(basepath)) {
130 130
 	if(!getcwd(ret, PATH_MAX)) {
131 131
 	    logg("^Can't get absolute pathname of current working directory.\n");
132 132
 	    free(ret);
133 133
 	    return NULL;
134 134
 	}
135 135
 	namelen = strlen(ret);
136
-	snprintf(&ret[namelen], PATH_MAX - namelen, "/%s", basepath);
136
+	snprintf(&ret[namelen], PATH_MAX - namelen, PATHSEP"%s", basepath);
137 137
     } else {
138 138
 	strncpy(ret, basepath, PATH_MAX);
139 139
     }
... ...
@@ -169,7 +177,7 @@ int get_clamd_version(const struct optstruct *opts)
169 169
     recvlninit(&rcv, sockd);
170 170
 
171 171
     if(sendln(sockd, "zVERSION", 9)) {
172
-	close(sockd);
172
+	closesocket(sockd);
173 173
 	return 2;
174 174
     }
175 175
 
... ...
@@ -181,7 +189,7 @@ int get_clamd_version(const struct optstruct *opts)
181 181
 	printf("%s\n", buff);
182 182
     }
183 183
 
184
-    close(sockd);
184
+    closesocket(sockd);
185 185
     return 0;
186 186
 }
187 187
 
... ...
@@ -197,16 +205,16 @@ int reload_clamd_database(const struct optstruct *opts)
197 197
     recvlninit(&rcv, sockd);
198 198
 
199 199
     if(sendln(sockd, "zRELOAD", 8)) {
200
-	close(sockd);
200
+	closesocket(sockd);
201 201
 	return 2;
202 202
     }
203 203
 
204 204
     if(!(len = recvln(&rcv, &buff, NULL)) || len < 10 || memcmp(buff, "RELOADING", 9)) {
205 205
 	logg("!Clamd did not reload the database\n");
206
-	close(sockd);
206
+	closesocket(sockd);
207 207
 	return 2;
208 208
     }
209
-    close(sockd);
209
+    closesocket(sockd);
210 210
     return 0;
211 211
 }
212 212
 
... ...
@@ -261,7 +269,7 @@ int client(const struct optstruct *opts, int *infected)
261 261
 	    *infected = ret;
262 262
 	else
263 263
 	    errors = 1;
264
-	if(sockd >= 0) close(sockd);
264
+	if(sockd >= 0) closesocket(sockd);
265 265
     } else if(opts->filename || optget(opts, "file-list")->enabled) {
266 266
 	if(opts->filename && optget(opts, "file-list")->enabled)
267 267
 	    logg("^Only scanning files from --file-list (files passed at cmdline are ignored)\n");
... ...
@@ -25,7 +25,9 @@
25 25
 /* must be first because it may define _XOPEN_SOURCE */
26 26
 #include "shared/fdpassing.h"
27 27
 #include <stdio.h>
28
+#ifdef HAVE_UNISTD_H
28 29
 #include <unistd.h>
30
+#endif
29 31
 #include <string.h>
30 32
 #include <errno.h>
31 33
 #include <stdlib.h>
... ...
@@ -33,9 +35,13 @@
33 33
 #include <sys/stat.h>
34 34
 #include <fcntl.h>
35 35
 #include <sys/types.h>
36
-#include <sys/socket.h>
36
+#ifdef HAVE_SYS_SELECT_H
37 37
 #include <sys/select.h>
38
+#endif
39
+#ifndef _WIN32
38 40
 #include <arpa/inet.h>
41
+#include <sys/socket.h>
42
+#endif
39 43
 
40 44
 #include "libclamav/others.h"
41 45
 #include "shared/actions.h"
... ...
@@ -62,7 +68,7 @@ int dconnect() {
62 62
     }
63 63
 
64 64
     if(connect(sockd, (struct sockaddr *)mainsa, mainsasz) < 0) {
65
-	close(sockd);
65
+	closesocket(sockd);
66 66
 	logg("!Can't connect to clamd: %s\n", strerror(errno));
67 67
 	return -1;
68 68
     }
... ...
@@ -160,7 +166,7 @@ static int send_stream(int sockd, const char *filename) {
160 160
     unsigned long int todo = maxstream;
161 161
 
162 162
     if(filename) {
163
-	if((fd = open(filename, O_RDONLY))<0) {
163
+	if((fd = open(filename, O_RDONLY | O_BINARY))<0) {
164 164
 	    logg("~%s: Access denied. ERROR\n", filename);
165 165
 	    return 0;
166 166
 	}
... ...
@@ -359,7 +365,7 @@ static int serial_callback(struct stat *sb, char *filename, const char *path, en
359 359
     }
360 360
     ret = dsresult(sockd, c->scantype, f, &c->printok);
361 361
     if(filename) free(filename);
362
-    close(sockd);
362
+    closesocket(sockd);
363 363
     if(ret < 0) return CL_EOPEN;
364 364
     c->infected += ret;
365 365
     if(reason == visit_directory_toplev)
... ...
@@ -551,7 +557,7 @@ int parallel_client_scan(char *file, int scantype, int *infected, int maxlevel,
551 551
 	return 1;
552 552
 
553 553
     if(sendln(cdata.sockd, "zIDSESSION", 11)) {
554
-	close(cdata.sockd);
554
+	closesocket(cdata.sockd);
555 555
 	return 1;
556 556
     }
557 557
 
... ...
@@ -566,13 +572,13 @@ int parallel_client_scan(char *file, int scantype, int *infected, int maxlevel,
566 566
 
567 567
     if(ftw != CL_SUCCESS) {
568 568
 	*infected += cdata.infected;
569
-	close(cdata.sockd);
569
+	closesocket(cdata.sockd);
570 570
 	return 1;
571 571
     }
572 572
 
573 573
     sendln(cdata.sockd, "zEND", 5);
574 574
     while(cdata.ids && !dspresult(&cdata));
575
-    close(cdata.sockd);
575
+    closesocket(cdata.sockd);
576 576
 
577 577
     *infected += cdata.infected;
578 578
 
... ...
@@ -510,7 +510,7 @@ static int make_connection_real(const char *soname, conn_t *conn)
510 510
 #ifdef _WIN32
511 511
     {
512 512
 #else
513
-	if(soname[0] == '/' || (access(soname, F_OK) == 0)) {
513
+	if(cli_is_abspath(soname) || (access(soname, F_OK) == 0)) {
514 514
 		struct sockaddr_un addr;
515 515
 		s = socket(AF_UNIX, SOCK_STREAM, 0);
516 516
 		if(s < 0) {
... ...
@@ -30,9 +30,7 @@
30 30
 #ifdef	HAVE_UNISTD_H
31 31
 #include <unistd.h>
32 32
 #endif
33
-#ifdef	C_WINDOWS
34
-#include <fcntl.h>
35
-#else
33
+#ifndef _WIN32
36 34
 #include <sys/time.h>
37 35
 #endif
38 36
 #include <time.h>
... ...
@@ -54,10 +52,6 @@
54 54
 
55 55
 void help(void);
56 56
 
57
-#if defined(C_WINDOWS) && defined(CL_DEBUG)
58
-#include <crtdbg.h>
59
-#endif
60
-
61 57
 struct s_info info;
62 58
 short recursion = 0, printinfected = 0, bell = 0;
63 59
 
... ...
@@ -66,21 +60,14 @@ int main(int argc, char **argv)
66 66
 	int ds, dms, ret;
67 67
 	double mb, rmb;
68 68
 	struct timeval t1, t2;
69
-#ifndef C_WINDOWS
70 69
 	struct timezone tz;
70
+#ifndef _WIN32
71 71
 	sigset_t sigset;
72 72
 #endif
73 73
 	struct optstruct *opts;
74 74
 	const struct optstruct *opt;
75 75
 
76
-#if defined(C_WINDOWS) && defined(CL_THREAD_SAFE)
77
-    if(!pthread_win32_process_attach_np()) {
78
-	mprintf("!Can't start the win32 pthreads layer\n");
79
-	return 72;
80
-    }
81
-#endif
82
-
83
-#if !defined(C_WINDOWS) && !defined(C_BEOS)
76
+#if !defined(_WIN32) && !defined(C_BEOS)
84 77
     sigemptyset(&sigset);
85 78
     sigaddset(&sigset, SIGXFSZ);
86 79
     sigprocmask(SIG_SETMASK, &sigset, NULL);
... ...
@@ -156,28 +143,14 @@ int main(int argc, char **argv)
156 156
 
157 157
     memset(&info, 0, sizeof(struct s_info));
158 158
 
159
-#ifdef C_WINDOWS
160
-    _set_fmode(_O_BINARY);
161
-#ifdef CL_DEBUG
162
-    {
163
-	_CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
164
-	_CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
165
-    }
166
-#endif	
167
-    gettimeofday(&t1, NULL);
168
-#else
169 159
     gettimeofday(&t1, &tz);
170
-#endif
171 160
 
172 161
     ret = scanmanager(opts);
173 162
 
174 163
     if(!optget(opts, "no-summary")->enabled) {
175
-#ifdef C_WINDOWS
176
-	gettimeofday(&t2, NULL);
177
-#else
178 164
 	gettimeofday(&t2, &tz);
179
-#endif
180
-	ds = t2.tv_sec - t1.tv_sec;
165
+
166
+    ds = t2.tv_sec - t1.tv_sec;
181 167
 	dms = t2.tv_usec - t1.tv_usec;
182 168
 	ds -= (dms < 0) ? (1):(0);
183 169
 	dms += (dms < 0) ? (1000000):(0);
... ...
@@ -202,13 +175,6 @@ int main(int argc, char **argv)
202 202
 
203 203
     optfree(opts);
204 204
 
205
-#if defined(C_WINDOWS) && defined(CL_THREAD_SAFE)
206
-    if(!pthread_win32_process_detach_np()) {
207
-	logg("!Can't stop the win32 pthreads layer\n");
208
-	return 72;
209
-    }
210
-#endif
211
-
212 205
     return ret;
213 206
 }
214 207
 
... ...
@@ -29,14 +29,10 @@
29 29
 #include <ctype.h>
30 30
 #include <sys/stat.h>
31 31
 #include <sys/types.h>
32
-#ifdef C_WINDOWS
33
-#include <sys/utime.h>
34
-#else
32
+#include <dirent.h>
33
+#ifndef _WIN32
35 34
 #include <sys/wait.h>
36 35
 #include <utime.h>
37
-#endif
38
-#ifndef C_WINDOWS
39
-#include <dirent.h>
40 36
 #include <sys/time.h>
41 37
 #include <sys/resource.h>
42 38
 #endif
... ...
@@ -68,15 +64,6 @@
68 68
 dev_t procdev;
69 69
 #endif
70 70
 
71
-#ifdef C_WINDOWS
72
-#undef P_tmpdir
73
-#define P_tmpdir    "C:\\WINDOWS\\TEMP"
74
-#endif
75
-
76
-#ifndef	O_BINARY
77
-#define	O_BINARY    0
78
-#endif
79
-
80 71
 static int scanfile(const char *filename, struct cl_engine *engine, const struct optstruct *opts, unsigned int options)
81 72
 {
82 73
   int ret = 0, fd, included, printclean = 1, fsize;
... ...
@@ -129,7 +116,7 @@ static int scanfile(const char *filename, struct cl_engine *engine, const struct
129 129
 	return 0;
130 130
     }
131 131
     info.rblocks += fsize / CL_COUNT_PRECISION;
132
-#ifndef C_WINDOWS
132
+#ifndef _WIN32
133 133
     if(geteuid())
134 134
 	if(checkaccess(filename, NULL, R_OK) != 1) {
135 135
 	    if(!printinfected)
... ...
@@ -141,7 +128,7 @@ static int scanfile(const char *filename, struct cl_engine *engine, const struct
141 141
     logg("*Scanning %s\n", filename);
142 142
 
143 143
     if((fd = open(filename, O_RDONLY|O_BINARY)) == -1) {
144
-	logg("^Can't open file %s\n", filename);
144
+	logg("^Can't open file %s: %s\n", filename, strerror(errno));
145 145
 	return 54;
146 146
     }
147 147
 
... ...
@@ -214,17 +201,15 @@ static int scandirs(const char *dirname, struct cl_engine *engine, const struct
214 214
 
215 215
     if((dd = opendir(dirname)) != NULL) {
216 216
 	while((dent = readdir(dd))) {
217
-#if !defined(C_INTERIX) && !defined(C_WINDOWS)
218 217
 	    if(dent->d_ino)
219
-#endif
220 218
 	    {
221 219
 		if(strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..")) {
222 220
 		    /* build the full name */
223 221
 		    fname = malloc(strlen(dirname) + strlen(dent->d_name) + 2);
224
-		    if(!strcmp(dirname, "/"))
225
-			sprintf(fname, "/%s", dent->d_name);
222
+		    if(!strcmp(dirname, PATHSEP))
223
+			sprintf(fname, PATHSEP"%s", dent->d_name);
226 224
 		    else
227
-			sprintf(fname, "%s/%s", dirname, dent->d_name);
225
+			sprintf(fname, "%s"PATHSEP"%s", dirname, dent->d_name);
228 226
 
229 227
 		    /* stat the file */
230 228
 		    if(lstat(fname, &statbuf) != -1) {
... ...
@@ -274,17 +259,9 @@ static int scanstdin(const struct cl_engine *engine, const struct optstruct *opt
274 274
 
275 275
     if(optget(opts, "tempdir")->enabled) {
276 276
 	tmpdir = optget(opts, "tempdir")->strarg;
277
-    } else {
277
+    } else
278 278
 	/* check write access */
279
-	tmpdir = getenv("TMPDIR");
280
-
281
-	if(tmpdir == NULL)
282
-#ifdef P_tmpdir
283
-	    tmpdir = P_tmpdir;
284
-#else
285
-	    tmpdir = "/tmp";
286
-#endif
287
-    }
279
+	tmpdir = cli_gettmpdir();
288 280
 
289 281
     if(checkaccess(tmpdir, CLAMAVUSER, W_OK) != 1) {
290 282
 	logg("!Can't write to temporary directory\n");
... ...
@@ -342,7 +319,7 @@ int scanmanager(const struct optstruct *opts)
342 342
 	char *file, cwd[1024], *pua_cats = NULL;
343 343
 	const char *filename;
344 344
 	const struct optstruct *opt;
345
-#ifndef C_WINDOWS
345
+#ifndef _WIN32
346 346
 	struct rlimit rlim;
347 347
 #endif
348 348
 
... ...
@@ -479,7 +456,7 @@ int scanmanager(const struct optstruct *opts)
479 479
 	}
480 480
     }
481 481
 
482
-#ifndef C_WINDOWS
482
+#ifndef _WIN32
483 483
     if(getrlimit(RLIMIT_FSIZE, &rlim) == 0) {
484 484
 	if(rlim.rlim_cur < (rlim_t) cl_engine_get_num(engine, CL_ENGINE_MAX_FILESIZE, NULL))
485 485
 	    logg("^System limit for file size is lower than engine->maxfilesize\n");
... ...
@@ -619,7 +596,7 @@ int scanmanager(const struct optstruct *opts)
619 619
 		ret = 56;
620 620
 	    } else {
621 621
 		for(i = strlen(file) - 1; i > 0; i--) {
622
-		    if(file[i] == '/')
622
+		    if(file[i] == *PATHSEP)
623 623
 			file[i] = 0;
624 624
 		    else
625 625
 			break;
... ...
@@ -36,7 +36,7 @@
36 36
 #endif
37 37
 #include <sys/types.h>
38 38
 #include <sys/stat.h>
39
-#ifndef C_WINDOWS
39
+#ifndef _WIN32
40 40
 #include <sys/wait.h>
41 41
 #include <sys/time.h>
42 42
 #endif
... ...
@@ -73,7 +73,7 @@ int fileinfo(const char *filename, short i)
73 73
     }
74 74
 }
75 75
 
76
-#ifdef C_WINDOWS
76
+#ifdef _WIN32
77 77
 /* FIXME: Handle users correctly */
78 78
 int checkaccess(const char *path, const char *username, int mode)
79 79
 {
... ...
@@ -2570,6 +2570,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
2570 2570
 
2571 2571
 
2572 2572
 
2573
+
2573 2574
 ac_aux_dir=
2574 2575
 for ac_dir in config "$srcdir"/config; do
2575 2576
   for ac_t in install-sh install.sh shtool; do
... ...
@@ -3361,11 +3362,11 @@ MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
3361 3361
 AMTAR=${AMTAR-"${am_missing_run}tar"}
3362 3362
 
3363 3363
 
3364
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to create a pax tar archive" >&5
3365
-$as_echo_n "checking how to create a pax tar archive... " >&6; }
3364
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to create a ustar tar archive" >&5
3365
+$as_echo_n "checking how to create a ustar tar archive... " >&6; }
3366 3366
 # Loop over all known methods to create a tar archive until one works.
3367
-_am_tools='gnutar  pax cpio none'
3368
-_am_tools=${am_cv_prog_tar_pax-$_am_tools}
3367
+_am_tools='gnutar plaintar pax cpio none'
3368
+_am_tools=${am_cv_prog_tar_ustar-$_am_tools}
3369 3369
 # Do not fold the above two line into one, because Tru64 sh and
3370 3370
 # Solaris sh will not grok spaces in the rhs of `-'.
3371 3371
 for _am_tool in $_am_tools
... ...
@@ -3380,8 +3381,8 @@ do
3380 3380
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
3381 3381
    (exit $ac_status); } && break
3382 3382
     done
3383
-    am__tar="$_am_tar --format=posix -chf - "'"$$tardir"'
3384
-    am__tar_="$_am_tar --format=posix -chf - "'"$tardir"'
3383
+    am__tar="$_am_tar --format=ustar -chf - "'"$$tardir"'
3384
+    am__tar_="$_am_tar --format=ustar -chf - "'"$tardir"'
3385 3385
     am__untar="$_am_tar -xf -"
3386 3386
     ;;
3387 3387
   plaintar)
... ...
@@ -3393,14 +3394,14 @@ do
3393 3393
     am__untar='tar xf -'
3394 3394
     ;;
3395 3395
   pax)
3396
-    am__tar='pax -L -x pax -w "$$tardir"'
3397
-    am__tar_='pax -L -x pax -w "$tardir"'
3396
+    am__tar='pax -L -x ustar -w "$$tardir"'
3397
+    am__tar_='pax -L -x ustar -w "$tardir"'
3398 3398
     am__untar='pax -r'
3399 3399
     ;;
3400 3400
   cpio)
3401
-    am__tar='find "$$tardir" -print | cpio -o -H pax -L'
3402
-    am__tar_='find "$tardir" -print | cpio -o -H pax -L'
3403
-    am__untar='cpio -i -H pax -d'
3401
+    am__tar='find "$$tardir" -print | cpio -o -H ustar -L'
3402
+    am__tar_='find "$tardir" -print | cpio -o -H ustar -L'
3403
+    am__untar='cpio -i -H ustar -d'
3404 3404
     ;;
3405 3405
   none)
3406 3406
     am__tar=false
... ...
@@ -3411,7 +3412,7 @@ do
3411 3411
 
3412 3412
   # If the value was cached, stop now.  We just wanted to have am__tar
3413 3413
   # and am__untar set.
3414
-  test -n "${am_cv_prog_tar_pax}" && break
3414
+  test -n "${am_cv_prog_tar_ustar}" && break
3415 3415
 
3416 3416
   # tar/untar a dummy directory, and stop if the command works
3417 3417
   rm -rf conftest.dir
... ...
@@ -3434,14 +3435,14 @@ do
3434 3434
 done
3435 3435
 rm -rf conftest.dir
3436 3436
 
3437
-if test "${am_cv_prog_tar_pax+set}" = set; then :
3437
+if test "${am_cv_prog_tar_ustar+set}" = set; then :
3438 3438
   $as_echo_n "(cached) " >&6
3439 3439
 else
3440
-  am_cv_prog_tar_pax=$_am_tool
3440
+  am_cv_prog_tar_ustar=$_am_tool
3441 3441
 fi
3442 3442
 
3443
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_tar_pax" >&5
3444
-$as_echo "$am_cv_prog_tar_pax" >&6; }
3443
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_tar_ustar" >&5
3444
+$as_echo "$am_cv_prog_tar_ustar" >&6; }
3445 3445
 
3446 3446
 
3447 3447
 
... ...
@@ -5136,13 +5137,13 @@ if test "${lt_cv_nm_interface+set}" = set; then :
5136 5136
 else
5137 5137
   lt_cv_nm_interface="BSD nm"
5138 5138
   echo "int some_variable = 0;" > conftest.$ac_ext
5139
-  (eval echo "\"\$as_me:5139: $ac_compile\"" >&5)
5139
+  (eval echo "\"\$as_me:5140: $ac_compile\"" >&5)
5140 5140
   (eval "$ac_compile" 2>conftest.err)
5141 5141
   cat conftest.err >&5
5142
-  (eval echo "\"\$as_me:5142: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
5142
+  (eval echo "\"\$as_me:5143: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
5143 5143
   (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
5144 5144
   cat conftest.err >&5
5145
-  (eval echo "\"\$as_me:5145: output\"" >&5)
5145
+  (eval echo "\"\$as_me:5146: output\"" >&5)
5146 5146
   cat conftest.out >&5
5147 5147
   if $GREP 'External.*some_variable' conftest.out > /dev/null; then
5148 5148
     lt_cv_nm_interface="MS dumpbin"
... ...
@@ -6337,7 +6338,7 @@ ia64-*-hpux*)
6337 6337
   ;;
6338 6338
 *-*-irix6*)
6339 6339
   # Find out which ABI we are using.
6340
-  echo '#line 6340 "configure"' > conftest.$ac_ext
6340
+  echo '#line 6341 "configure"' > conftest.$ac_ext
6341 6341
   if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
6342 6342
   (eval $ac_compile) 2>&5
6343 6343
   ac_status=$?
... ...
@@ -7865,11 +7866,11 @@ else
7865 7865
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
7866 7866
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
7867 7867
    -e 's:$: $lt_compiler_flag:'`
7868
-   (eval echo "\"\$as_me:7868: $lt_compile\"" >&5)
7868
+   (eval echo "\"\$as_me:7869: $lt_compile\"" >&5)
7869 7869
    (eval "$lt_compile" 2>conftest.err)
7870 7870
    ac_status=$?
7871 7871
    cat conftest.err >&5
7872
-   echo "$as_me:7872: \$? = $ac_status" >&5
7872
+   echo "$as_me:7873: \$? = $ac_status" >&5
7873 7873
    if (exit $ac_status) && test -s "$ac_outfile"; then
7874 7874
      # The compiler can only warn and ignore the option if not recognized
7875 7875
      # So say no if there are warnings other than the usual output.
... ...
@@ -8204,11 +8205,11 @@ else
8204 8204
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
8205 8205
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
8206 8206
    -e 's:$: $lt_compiler_flag:'`
8207
-   (eval echo "\"\$as_me:8207: $lt_compile\"" >&5)
8207
+   (eval echo "\"\$as_me:8208: $lt_compile\"" >&5)
8208 8208
    (eval "$lt_compile" 2>conftest.err)
8209 8209
    ac_status=$?
8210 8210
    cat conftest.err >&5
8211
-   echo "$as_me:8211: \$? = $ac_status" >&5
8211
+   echo "$as_me:8212: \$? = $ac_status" >&5
8212 8212
    if (exit $ac_status) && test -s "$ac_outfile"; then
8213 8213
      # The compiler can only warn and ignore the option if not recognized
8214 8214
      # So say no if there are warnings other than the usual output.
... ...
@@ -8309,11 +8310,11 @@ else
8309 8309
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
8310 8310
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
8311 8311
    -e 's:$: $lt_compiler_flag:'`
8312
-   (eval echo "\"\$as_me:8312: $lt_compile\"" >&5)
8312
+   (eval echo "\"\$as_me:8313: $lt_compile\"" >&5)
8313 8313
    (eval "$lt_compile" 2>out/conftest.err)
8314 8314
    ac_status=$?
8315 8315
    cat out/conftest.err >&5
8316
-   echo "$as_me:8316: \$? = $ac_status" >&5
8316
+   echo "$as_me:8317: \$? = $ac_status" >&5
8317 8317
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
8318 8318
    then
8319 8319
      # The compiler can only warn and ignore the option if not recognized
... ...
@@ -8364,11 +8365,11 @@ else
8364 8364
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
8365 8365
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
8366 8366
    -e 's:$: $lt_compiler_flag:'`
8367
-   (eval echo "\"\$as_me:8367: $lt_compile\"" >&5)
8367
+   (eval echo "\"\$as_me:8368: $lt_compile\"" >&5)
8368 8368
    (eval "$lt_compile" 2>out/conftest.err)
8369 8369
    ac_status=$?
8370 8370
    cat out/conftest.err >&5
8371
-   echo "$as_me:8371: \$? = $ac_status" >&5
8371
+   echo "$as_me:8372: \$? = $ac_status" >&5
8372 8372
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
8373 8373
    then
8374 8374
      # The compiler can only warn and ignore the option if not recognized
... ...
@@ -10747,7 +10748,7 @@ else
10747 10747
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
10748 10748
   lt_status=$lt_dlunknown
10749 10749
   cat > conftest.$ac_ext <<_LT_EOF
10750
-#line 10750 "configure"
10750
+#line 10751 "configure"
10751 10751
 #include "confdefs.h"
10752 10752
 
10753 10753
 #if HAVE_DLFCN_H
... ...
@@ -10843,7 +10844,7 @@ else
10843 10843
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
10844 10844
   lt_status=$lt_dlunknown
10845 10845
   cat > conftest.$ac_ext <<_LT_EOF
10846
-#line 10846 "configure"
10846
+#line 10847 "configure"
10847 10847
 #include "confdefs.h"
10848 10848
 
10849 10849
 #if HAVE_DLFCN_H
... ...
@@ -11515,7 +11516,7 @@ else
11515 11515
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
11516 11516
   lt_status=$lt_dlunknown
11517 11517
   cat > conftest.$ac_ext <<_LT_EOF
11518
-#line 11518 "configure"
11518
+#line 11519 "configure"
11519 11519
 #include "confdefs.h"
11520 11520
 
11521 11521
 #if HAVE_DLFCN_H
... ...
@@ -12762,9 +12763,15 @@ $as_echo "no (${gcc_version})" >&6; }
12762 12762
 $as_echo "ok (${gcc_version})" >&6; }
12763 12763
 				;;
12764 12764
 		esac
12765
-		# bb #1581 - temporarely add -fno-strict-aliasing so gcc 4.4.0
12766
-		# works correctly
12767
-		CFLAGS="$CFLAGS -fno-strict-aliasing"
12765
+		case "${gcc_version}" in
12766
+		    [56789].* | 4.[3456789].*)
12767
+			# bb #1581 - temporarely add -fno-strict-aliasing so gcc 4.4.0
12768
+			# works correctly
12769
+			CFLAGS="$CFLAGS -fno-strict-aliasing"
12770
+			;;
12771
+		    *)
12772
+			;;
12773
+		esac
12768 12774
 	fi
12769 12775
 else
12770 12776
 	CFLAGS="$CFLAGS -O0"
... ...
@@ -19782,7 +19789,7 @@ subdirs="$subdirs libclamav/c++"
19782 19782
 
19783 19783
 fi
19784 19784
 
19785
-ac_config_files="$ac_config_files clamscan/Makefile database/Makefile docs/Makefile clamd/Makefile clamdscan/Makefile clamav-milter/Makefile freshclam/Makefile sigtool/Makefile clamconf/Makefile etc/Makefile test/Makefile unit_tests/Makefile clamdtop/Makefile clambc/Makefile Makefile clamav-config libclamav.pc docs/man/clamav-milter.8 docs/man/clamconf.1 docs/man/clamd.8 docs/man/clamd.conf.5 docs/man/clamdscan.1 docs/man/clamscan.1 docs/man/freshclam.1 docs/man/freshclam.conf.5 docs/man/sigtool.1 docs/man/clamdtop.1"
19785
+ac_config_files="$ac_config_files clamscan/Makefile database/Makefile docs/Makefile clamd/Makefile clamdscan/Makefile clamav-milter/Makefile freshclam/Makefile sigtool/Makefile clamconf/Makefile etc/Makefile test/Makefile unit_tests/Makefile clamdtop/Makefile clambc/Makefile Makefile clamav-config libclamav.pc platform.h docs/man/clamav-milter.8 docs/man/clamconf.1 docs/man/clamd.8 docs/man/clamd.conf.5 docs/man/clamdscan.1 docs/man/clamscan.1 docs/man/freshclam.1 docs/man/freshclam.conf.5 docs/man/sigtool.1 docs/man/clamdtop.1"
19786 19786
 
19787 19787
 cat >confcache <<\_ACEOF
19788 19788
 # This file is a shell script that caches the results of configure
... ...
@@ -20833,6 +20840,7 @@ do
20833 20833
     "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
20834 20834
     "clamav-config") CONFIG_FILES="$CONFIG_FILES clamav-config" ;;
20835 20835
     "libclamav.pc") CONFIG_FILES="$CONFIG_FILES libclamav.pc" ;;
20836
+    "platform.h") CONFIG_FILES="$CONFIG_FILES platform.h" ;;
20836 20837
     "docs/man/clamav-milter.8") CONFIG_FILES="$CONFIG_FILES docs/man/clamav-milter.8" ;;
20837 20838
     "docs/man/clamconf.1") CONFIG_FILES="$CONFIG_FILES docs/man/clamconf.1" ;;
20838 20839
     "docs/man/clamd.8") CONFIG_FILES="$CONFIG_FILES docs/man/clamd.8" ;;
... ...
@@ -23416,6 +23424,7 @@ do
23416 23416
     "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
23417 23417
     "clamav-config") CONFIG_FILES="$CONFIG_FILES clamav-config" ;;
23418 23418
     "libclamav.pc") CONFIG_FILES="$CONFIG_FILES libclamav.pc" ;;
23419
+    "platform.h") CONFIG_FILES="$CONFIG_FILES platform.h" ;;
23419 23420
     "docs/man/clamav-milter.8") CONFIG_FILES="$CONFIG_FILES docs/man/clamav-milter.8" ;;
23420 23421
     "docs/man/clamconf.1") CONFIG_FILES="$CONFIG_FILES docs/man/clamconf.1" ;;
23421 23422
     "docs/man/clamd.8") CONFIG_FILES="$CONFIG_FILES docs/man/clamd.8" ;;
... ...
@@ -22,6 +22,7 @@ dnl For a release change [devel] to the real version [0.xy]
22 22
 dnl also change VERSION below
23 23
 AC_INIT([ClamAV], [devel], [http://bugs.clamav.net/], [clamav], [http://www.clamav.net/])
24 24
 
25
+AH_BOTTOM([#include "platform.h"])
25 26
 dnl put configure auxiliary into config
26 27
 AC_CONFIG_AUX_DIR([config])
27 28
 AC_CONFIG_HEADER([clamav-config.h])
... ...
@@ -33,7 +34,7 @@ AC_CREATE_TARGET_H([target.h])
33 33
 
34 34
 dnl -Wall and -Werror here are NOT CFLAGS, they refer to automake warnings
35 35
 dnl enable stealth builds and psychedelic tests
36
-AM_INIT_AUTOMAKE([1.9 -Wall -Wportability -Wno-override -Werror std-options foreign dist-bzip2 no-define color-tests tar-pax])
36
+AM_INIT_AUTOMAKE([1.11 -Wall -Wportability -Wno-override -Werror std-options foreign dist-bzip2 no-define color-tests parallel-tests tar-ustar])
37 37
 AM_SILENT_RULES([yes])
38 38
 
39 39
 dnl we told automake to not define these, since we want to include
... ...
@@ -101,9 +102,15 @@ if test "$gcc_check" = "yes"; then
101 101
 				AC_MSG_RESULT([ok (${gcc_version})])
102 102
 				;;
103 103
 		esac
104
-		# bb #1581 - temporarely add -fno-strict-aliasing so gcc 4.4.0
105
-		# works correctly
106
-		CFLAGS="$CFLAGS -fno-strict-aliasing"
104
+		case "${gcc_version}" in
105
+		    [[56789]].* | 4.[[3456789]].*)
106
+			# bb #1581 - temporarely add -fno-strict-aliasing so gcc 4.4.0
107
+			# works correctly
108
+			CFLAGS="$CFLAGS -fno-strict-aliasing"
109
+			;;
110
+		    *)
111
+			;;
112
+		esac
107 113
 	fi
108 114
 else
109 115
 	CFLAGS="$CFLAGS -O0"
... ...
@@ -1607,6 +1614,7 @@ clambc/Makefile
1607 1607
 Makefile
1608 1608
 clamav-config
1609 1609
 libclamav.pc
1610
+platform.h
1610 1611
 docs/man/clamav-milter.8
1611 1612
 docs/man/clamconf.1
1612 1613
 docs/man/clamd.8
1613 1614
new file mode 100644
... ...
@@ -0,0 +1,134 @@
0
+#!/usr/bin/perl
1
+
2
+use strict;
3
+use warnings;
4
+
5
+use constant PERM => 0;
6
+use constant TEMP => 1;
7
+use constant MAXA => 2;
8
+use constant REAS => 3;
9
+
10
+use constant TAKE => PERM;
11
+
12
+# usage poolsize.pl < mpool_allocfile
13
+
14
+my $sizeof_void_ptr;
15
+my $overhead = 0;
16
+
17
+my %ptrs;
18
+my %sizes;
19
+my %maxes;
20
+
21
+my $maxsz = 0;
22
+
23
+print STDERR "Parsing allocations...\n";
24
+while(<>) {
25
+    if(/malloc @(0x[0-9a-z]+) size (\d+) \((.*)\)/) {
26
+	die "ptr $1 re-malloc" if defined $ptrs{$1};
27
+	$ptrs{$1} = $2;
28
+	$sizes{$ptrs{$1}} = [0, 0, 0, 'UNUSED'] unless defined $sizes{$ptrs{$1}};
29
+	$maxes{$ptrs{$1}} = [0, 0] unless defined $maxes{$ptrs{$1}};
30
+	$maxes{$ptrs{$1}}[0]++;
31
+	$maxes{$ptrs{$1}}[1] = $maxes{$ptrs{$1}}[0] unless $maxes{$ptrs{$1}}[1] >= $maxes{$ptrs{$1}}[0];
32
+	$maxsz = $2 unless $maxsz >= $2;
33
+	$overhead++ if $3 eq 'new map';
34
+	next;
35
+    }
36
+    if(/free @(0x[0-9a-z]+)/) {
37
+	die "ptr $1 invalid free" unless defined $ptrs{$1};
38
+	$sizes{$ptrs{$1}}[TEMP]++;
39
+	$maxes{$ptrs{$1}}[0]--;
40
+	delete $ptrs{$1};
41
+	next;
42
+    }
43
+    if(/Map created @.*voidptr=(\d+)/) {
44
+	$sizeof_void_ptr = $1;
45
+	next;
46
+    }
47
+    chomp;
48
+    print STDERR "warning bogus line:\n$_\n";
49
+}
50
+
51
+$overhead *= $sizeof_void_ptr;
52
+print STDERR "Parsing complete (size overhead = $overhead)\n";
53
+
54
+$sizes{$ptrs{$_}}[PERM]++ foreach (keys %ptrs);
55
+undef %ptrs;
56
+
57
+$sizes{$_}[MAXA] = $maxes{$_}[1] foreach (keys %maxes);
58
+undef %maxes;
59
+
60
+$maxsz |= $maxsz>>16;
61
+$maxsz |= $maxsz>>8;
62
+$maxsz |= $maxsz>>4;
63
+$maxsz |= $maxsz>>2;
64
+$maxsz |= $maxsz>>1;
65
+$maxsz++;
66
+
67
+while($maxsz) {
68
+    my $nextsz = $maxsz>>1;
69
+    if(defined $sizes{$maxsz}) {
70
+	$sizes{$maxsz}[REAS] = 'POW2';
71
+    } else {
72
+	$sizes{$maxsz} = [0, 0, 0, 'POW2'];
73
+    }
74
+    my $nextpow2 = $nextsz;
75
+    while(1) {
76
+	my $refsz = $maxsz;
77
+	my @group;
78
+	foreach (sort { $b <=> $a } keys %sizes) {
79
+	    next unless $_ > $nextpow2;
80
+	    next unless $_ <= $maxsz;
81
+	    next unless ($sizes{$_}[TAKE] > 0 || $_ == $maxsz);
82
+	    $nextsz = $_;
83
+	    last unless ($refsz - $_) * $sizes{$_}[TAKE] <= $overhead;
84
+	    $refsz = $_;
85
+	    push @group, $_;
86
+	}
87
+	while($#group >= 23) {
88
+	    my $items = $#group / 2;
89
+	    $nextsz = $group[$items + 1];
90
+	    @group = @group[0..$items];
91
+	}
92
+	print STDERR "Processing group $maxsz -> $nextsz (count ".($#group + 1).")\n";
93
+	my @topscore; # 0 => score | 1 => used bits | origbits
94
+	for(my $origbits = 0; $origbits < 1<<$#group ; $origbits++) {
95
+	    my $bits = $origbits;
96
+	    my $bitcnt = 0;
97
+	    my $score = $overhead;
98
+	    my $grp_size = $maxsz;
99
+
100
+	    printf STDERR "%3i%%\r", $origbits * 100 / (1<<$#group) unless ($origbits & 1);
101
+	    for (my $i = 1; $i<= $#group; $i++) {
102
+		if($bits & 1) {
103
+		    $score +=  $overhead + $sizes{$group[$i]}[TAKE] * $group[$i];
104
+		    $bitcnt++;
105
+		    $grp_size = $group[$i];
106
+		} else {
107
+		    $score += $sizes{$group[$i]}[TAKE] * $grp_size;
108
+		}
109
+		$bits>>=1;
110
+	    }
111
+	    if(!defined $topscore[0] || $score < $topscore[0] || ($score == $topscore[0] && $bitcnt > $topscore[1])) {
112
+		@topscore = ($score, $bitcnt, $origbits);
113
+	    }
114
+	}
115
+	my $bits = ($topscore[2]<<1) | 1;
116
+	for (my $i = 0; $i<=$#group; $i++) {
117
+	    if ($bits & 1) {
118
+		$sizes{$group[$i]}[REAS] = "USE";
119
+	    } else {
120
+		$sizes{$group[$i]}[REAS] = "GROUP";
121
+	    }
122
+	    $bits>>=1;
123
+	}
124
+	last unless $nextsz < $maxsz;
125
+	$maxsz = $nextsz;
126
+    }
127
+    $maxsz = $nextpow2;
128
+}
129
+
130
+print "/* SIZE        PERM    TEMP     MAX    ACT! */\n";
131
+foreach (sort { $a <=> $b } keys %sizes) {
132
+    printf "%7u, /* %7u %7u %7u %8s */\n", $_, $sizes{$_}[PERM], $sizes{$_}[TEMP], $sizes{$_}[MAXA], $sizes{$_}[REAS];
133
+}
... ...
@@ -87,9 +87,7 @@ Upload detection statistics to the ClamAV Project (see freshclam.conf(5):SubmitD
87 87
 .SH "RETURN CODES"
88 88
 Some return codes of freshclam can be overwritten with a built-in command EXIT_n which can be passed to \-\-on\-*\-execute, eg. \-\-on\-update\-execute=EXIT_1 will force freshclam to always return 1 after successful database update.
89 89
 .TP
90
-0 : Database successfully updated.
91
-.TP 
92
-1 : Database is up\-to\-date.
90
+0 : Database is up\-to\-date or successfully updated.
93 91
 .TP 
94 92
 40: Unknown option passed.
95 93
 .TP 
96 94
Binary files a/docs/signatures.pdf and b/docs/signatures.pdf differ
... ...
@@ -121,6 +121,8 @@ How do I look in hex?
121 121
 	Match between $n$ and $m$ bytes ($m > n$).
122 122
 	\item \verb+(aa|bb|cc|..)+\\
123 123
 	Match aa or bb or cc..
124
+	\item \verb+!(aa|bb|cc|..)+\\
125
+	Match any byte except aa and bb and cc..
124 126
 	\item \verb+HEXSIG[x-y]aa+ or \verb+aa[x-y]HEXSIG+\\
125 127
 	Match aa anchored to a hex-signature, see
126 128
 	\url{https://wwws.clamav.net/bugzilla/show_bug.cgi?id=776} for
... ...
@@ -169,6 +169,11 @@ Example
169 169
 # Default: no
170 170
 #AddHeader Replace
171 171
 
172
+# When AddHeader is in use, this option allows to arbitrary set the reported
173
+# hostname. This may be desirable in order to avoid leaking internal names.
174
+# If unset the real machine name is used.
175
+# Default: disabled
176
+#ReportHostname my.mail.server.name
172 177
 
173 178
 ##
174 179
 ## Logging options
... ...
@@ -403,15 +403,26 @@ LocalSocket /tmp/clamd.socket
403 403
 
404 404
 ##
405 405
 ## Clamuko settings
406
-## WARNING: This is experimental software. It is very likely it will hang
407
-##	    up your system!!!
408 406
 ##
409 407
 
410
-# Enable Clamuko. Dazuko (/dev/dazuko) must be configured and running.
408
+# Enable Clamuko. Dazuko must be configured and running. Clamuko supports
409
+# both Dazuko (/dev/dazuko) and DazukoFS (/dev/dazukofs.ctrl). DazukoFS
410
+# is the preferred option. For more information please visit www.dazuko.org
411 411
 # Default: no
412 412
 #ClamukoScanOnAccess yes
413 413
 
414
-# Set access mask for Clamuko.
414
+# The number of scanner threads that will be started (DazukoFS only).
415
+# Having multiple scanner threads allows Clamuko to serve multiple
416
+# processes simultaneously. This is particularly beneficial on SMP machines.
417
+# Default: 3
418
+#ClamukoScannerCount 3
419
+
420
+# Don't scan files larger than ClamukoMaxFileSize
421
+# Value of 0 disables the limit.
422
+# Default: 5M
423
+#ClamukoMaxFileSize 10M
424
+
425
+# Set access mask for Clamuko (Dazuko only).
415 426
 # Default: no
416 427
 #ClamukoScanOnOpen yes
417 428
 #ClamukoScanOnClose yes
... ...
@@ -419,16 +430,11 @@ LocalSocket /tmp/clamd.socket
419 419
 
420 420
 # Set the include paths (all files inside them will be scanned). You can have
421 421
 # multiple ClamukoIncludePath directives but each directory must be added
422
-# in a seperate line.
422
+# in a seperate line. (Dazuko only)
423 423
 # Default: disabled
424 424
 #ClamukoIncludePath /home
425 425
 #ClamukoIncludePath /students
426 426
 
427
-# Set the exclude paths. All subdirectories are also excluded.
427
+# Set the exclude paths. All subdirectories are also excluded. (Dazuko only)
428 428
 # Default: disabled
429 429
 #ClamukoExcludePath /home/bofh
430
-
431
-# Don't scan files larger than ClamukoMaxFileSize
432
-# Value of 0 disables the limit.
433
-# Default: 5M
434
-#ClamukoMaxFileSize 10M
... ...
@@ -28,9 +28,6 @@
28 28
 #endif
29 29
 #include <string.h>
30 30
 #include <errno.h>
31
-#ifdef	C_WINDOWS
32
-#include <process.h>
33
-#endif
34 31
 
35 32
 #include "shared/output.h"
36 33
 #include "shared/optparser.h"
... ...
@@ -43,9 +40,6 @@ int active_children;
43 43
 void execute( const char *type, const char *text, const struct optstruct *opts )
44 44
 {
45 45
 	int ret;
46
-#ifndef C_WINDOWS
47
-	pid_t pid;
48
-#endif
49 46
 
50 47
     if(!optget(opts, "daemon")->enabled) {
51 48
 	if(sscanf(text, "EXIT_%d", &ret) == 1) {
... ...
@@ -58,7 +52,7 @@ void execute( const char *type, const char *text, const struct optstruct *opts )
58 58
 	return;
59 59
     }
60 60
 
61
-#ifdef        C_WINDOWS
61
+#ifdef _WIN32
62 62
 	if(active_children < MAX_CHILDREN) {
63 63
 		if(spawnlp(P_DETACH, text, text, NULL) == -1) {
64 64
 			logg("^%s: couldn't execute \"%s\".\n", type, text);
... ...
@@ -68,7 +62,8 @@ void execute( const char *type, const char *text, const struct optstruct *opts )
68 68
 	} else
69 69
 		logg("^%s: already %d processes active.\n", type, active_children);
70 70
 #else
71
-	if ( active_children<MAX_CHILDREN )
71
+    if ( active_children<MAX_CHILDREN ) {
72
+	pid_t pid;
72 73
 	switch( pid=fork() ) {
73 74
 	case 0:
74 75
 		if ( -1==system(text) )
... ...
@@ -82,9 +77,8 @@ void execute( const char *type, const char *text, const struct optstruct *opts )
82 82
 	default:
83 83
 		active_children++;
84 84
 	}
85
-	else
86
-	{
85
+    } else {
87 86
 		logg("^%s: already %d processes active.\n", type, active_children);
88
-	}
87
+    }
89 88
 #endif
90 89
 }
... ...
@@ -15,9 +15,6 @@
15 15
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
16 16
  *  MA 02110-1301, USA.
17 17
  */
18
-#ifdef	_MSC_VER
19
-#include <winsock.h>
20
-#endif
21 18
 
22 19
 #if HAVE_CONFIG_H
23 20
 #include "clamav-config.h"
... ...
@@ -33,13 +30,15 @@
33 33
 #include <signal.h>
34 34
 #include <time.h>
35 35
 #include <sys/types.h>
36
-#ifndef	C_WINDOWS
36
+#ifndef	_WIN32
37 37
 #include <sys/wait.h>
38 38
 #endif
39 39
 #include <sys/stat.h>
40 40
 #include <fcntl.h>
41
-#ifndef	C_WINDOWS
41
+#ifdef	HAVE_PWD_H
42 42
 #include <pwd.h>
43
+#endif
44
+#ifdef HAVE_GRP_H
43 45
 #include <grp.h>
44 46
 #endif
45 47
 
... ...
@@ -131,9 +130,11 @@ static void help(void)
131 131
     mprintf("\n");
132 132
     mprintf("    --config-file=FILE                   read configuration from FILE.\n");
133 133
     mprintf("    --log=FILE           -l FILE         log into FILE\n");
134
+#ifndef _WIN32
134 135
     mprintf("    --daemon             -d              run in daemon mode\n");
135 136
     mprintf("    --pid=FILE           -p FILE         save daemon's pid in FILE\n");
136 137
     mprintf("    --user=USER          -u USER         run as USER\n");
138
+#endif
137 139
     mprintf("    --no-dns                             force old non-DNS verification method\n");
138 140
     mprintf("    --checks=#n          -c #n           number of checks per day, 1 <= n <= 50\n");
139 141
     mprintf("    --datadir=DIRECTORY                  download new databases into DIRECTORY\n");
... ...
@@ -202,7 +203,7 @@ int main(int argc, char **argv)
202 202
 	struct sigaction sigact;
203 203
 	struct sigaction oldact;
204 204
 #endif
205
-#if !defined(C_OS2) && !defined(C_WINDOWS)
205
+#ifdef HAVE_PWD_H
206 206
 	const char *dbowner;
207 207
 	struct passwd *user;
208 208
 #endif
... ...
@@ -212,7 +213,7 @@ int main(int argc, char **argv)
212 212
 
213 213
     if((opts = optparse(NULL, argc, argv, 1, OPT_FRESHCLAM, 0, NULL)) == NULL) {
214 214
 	mprintf("!Can't parse command line options\n");
215
-	return 1;
215
+	return 40;
216 216
     }
217 217
 
218 218
     if(optget(opts, "help")->enabled) {
... ...
@@ -227,7 +228,7 @@ int main(int argc, char **argv)
227 227
     if((opts = optparse(cfgfile, 0, NULL, 1, OPT_FRESHCLAM, 0, opts)) == NULL) {
228 228
 	fprintf(stderr, "ERROR: Can't open/parse the config file %s\n", pt);
229 229
 	free(pt);
230
-	return 1;
230
+	return 40;
231 231
     }
232 232
     free(pt);
233 233
 
... ...
@@ -239,14 +240,6 @@ int main(int argc, char **argv)
239 239
 	return 0;
240 240
     }
241 241
 
242
-#ifdef C_WINDOWS
243
-    if(!pthread_win32_process_attach_np()) {
244
-	mprintf("!Can't start the win32 pthreads layer\n");
245
-	optfree(opts);
246
-	return 63;
247
-    }
248
-#endif
249
-
250 242
     if(optget(opts, "HTTPProxyPassword")->enabled) {
251 243
 	if(stat(cfgfile, &statbuf) == -1) {
252 244
 	    logg("^Can't stat %s (critical error)\n", cfgfile);
... ...
@@ -254,7 +247,7 @@ int main(int argc, char **argv)
254 254
 	    return 56;
255 255
 	}
256 256
 
257
-#ifndef C_WINDOWS
257
+#ifndef _WIN32
258 258
 	if(statbuf.st_mode & (S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH)) {
259 259
 	    logg("^Insecure permissions (for HTTPProxyPassword): %s must have no more than 0700 permissions.\n", cfgfile);
260 260
 	    optfree(opts);
... ...
@@ -263,7 +256,7 @@ int main(int argc, char **argv)
263 263
 #endif
264 264
     }
265 265
 
266
-#if !defined(C_OS2) && !defined(C_WINDOWS)
266
+#ifdef HAVE_PWD_H
267 267
     /* freshclam shouldn't work with root privileges */
268 268
     dbowner = optget(opts, "DatabaseOwner")->strarg;
269 269
 
... ...
@@ -378,18 +371,6 @@ int main(int argc, char **argv)
378 378
 	return 0;
379 379
     }
380 380
 
381
-#ifdef	C_WINDOWS
382
-    {
383
-	    WSADATA wsaData;
384
-
385
-	if(WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) {
386
-	    logg("!Error at WSAStartup(): %d\n", WSAGetLastError());
387
-	    optfree(opts);
388
-	    return 1;
389
-	}
390
-    }
391
-#endif
392
-
393 381
     if(optget(opts, "daemon")->enabled) {
394 382
 	    int bigsleep, checks;
395 383
 #ifndef	C_WINDOWS
... ...
@@ -417,7 +398,7 @@ int main(int argc, char **argv)
417 417
 
418 418
 	bigsleep = 24 * 3600 / checks;
419 419
 
420
-#if !defined(C_OS2) && !defined(C_WINDOWS)
420
+#ifndef _WIN32
421 421
 	if(!optget(opts, "Foreground")->enabled) {
422 422
 	    if(daemonize() == -1) {
423 423
 		logg("!daemonize() failed\n");
... ...
@@ -438,7 +419,7 @@ int main(int argc, char **argv)
438 438
 
439 439
 	logg("#freshclam daemon %s (OS: "TARGET_OS_TYPE", ARCH: "TARGET_ARCH_TYPE", CPU: "TARGET_CPU_TYPE")\n", get_version());
440 440
 
441
-#ifdef	C_WINDOWS
441
+#ifdef _WIN32
442 442
 	signal(SIGINT, daemon_sighandler);
443 443
 	terminate = 0;
444 444
 #else
... ...
@@ -472,7 +453,7 @@ int main(int argc, char **argv)
472 472
 	    sigaction(SIGUSR1, &sigact, &oldact);
473 473
 #endif
474 474
 
475
-#ifdef	C_WINDOWS
475
+#ifdef	_WIN32
476 476
 	    sleep(bigsleep);
477 477
 #else   
478 478
 	    time(&wakeup);
... ...
@@ -525,14 +506,5 @@ int main(int argc, char **argv)
525 525
 
526 526
     optfree(opts);
527 527
 
528
-#ifdef C_WINDOWS
529
-    WSACleanup();
530
-
531
-    if(!pthread_win32_process_detach_np()) {
532
-	mprintf("!Can't stop the win32 pthreads layer\n");
533
-	return 63;
534
-    }
535
-#endif
536
-
537 528
     return(ret);
538 529
 }
... ...
@@ -22,9 +22,6 @@
22 22
  *  MA 02110-1301, USA.
23 23
  */
24 24
  
25
-#ifdef	_MSC_VER
26
-#include <winsock.h>	/* only needed in CL_EXPERIMENTAL */
27
-#endif
28 25
 #if HAVE_CONFIG_H
29 26
 #include "clamav-config.h"
30 27
 #endif
... ...
@@ -46,22 +43,18 @@
46 46
 #include <strings.h>
47 47
 #endif
48 48
 #include <ctype.h>
49
-#ifndef C_WINDOWS
49
+#ifndef _WIN32
50 50
 #include <netinet/in.h>
51 51
 #include <netdb.h>
52 52
 #include <arpa/inet.h>
53
-#endif
54
-#include <sys/types.h>
55
-#ifndef C_WINDOWS
56 53
 #include <sys/socket.h>
57 54
 #include <sys/time.h>
58 55
 #endif
56
+#include <sys/types.h>
59 57
 #include <time.h>
60 58
 #include <fcntl.h>
61 59
 #include <sys/stat.h>
62
-#ifndef C_WINDOWS
63 60
 #include <dirent.h>
64
-#endif
65 61
 #include <errno.h>
66 62
 #include <zlib.h>
67 63
 
... ...
@@ -85,14 +78,6 @@
85 85
 #include "libclamav/str.h"
86 86
 #include "libclamav/cvd.h"
87 87
 
88
-#ifndef	O_BINARY
89
-#define	O_BINARY	0
90
-#endif
91
-
92
-#ifndef C_WINDOWS
93
-#define	closesocket(s)	close(s)
94
-#endif
95
-
96 88
 #define CHDIR_ERR(x)				\
97 89
 	if(chdir(x) == -1)			\
98 90
 	    logg("!Can't chdir to %s\n", x);
... ...
@@ -688,11 +673,7 @@ int submitstats(const char *clamdcfg, const struct optstruct *opts)
688 688
 	*pt2 = 0;
689 689
 	pt2 += 2;
690 690
 
691
-#ifdef C_WINDOWS
692
-	if((pt = strrchr(pt, '\\')))
693
-#else
694
-	if((pt = strrchr(pt, '/')))
695
-#endif
691
+	if((pt = strrchr(pt, *PATHSEP)))
696 692
 	    *pt++ = 0;
697 693
 	if(!pt)
698 694
 	    pt = (char*) "NOFNAME";
... ...
@@ -1419,9 +1400,7 @@ static int buildcld(const char *tmpdir, const char *dbname, const char *newfile,
1419 1419
     }
1420 1420
 
1421 1421
     while((dent = readdir(dir))) {
1422
-#if !defined(C_INTERIX) && !defined(C_WINDOWS)
1423 1422
 	if(dent->d_ino)
1424
-#endif
1425 1423
 	{
1426 1424
 	    if(!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, "..") || !strcmp(dent->d_name, "COPYING") || !strcmp(dent->d_name, "daily.cfg"))
1427 1425
 		continue;
... ...
@@ -1683,7 +1662,7 @@ static int updatedb(const char *dbname, const char *hostname, char *ip, int *sig
1683 1683
 	return 55; /* FIXME */
1684 1684
     }
1685 1685
 
1686
-#ifdef C_WINDOWS
1686
+#ifdef _WIN32
1687 1687
     if(!access(newdb, R_OK) && unlink(newdb)) {
1688 1688
 	logg("!Can't unlink %s. Please fix the problem manually and try again.\n", newdb);
1689 1689
 	unlink(newfile);
... ...
@@ -1932,5 +1911,5 @@ int downloadmanager(const struct optstruct *opts, const char *hostname, const ch
1932 1932
     if(newver)
1933 1933
 	free(newver);
1934 1934
 
1935
-    return updated ? 0 : 1;
1935
+    return 0;
1936 1936
 }
... ...
@@ -16,18 +16,10 @@
16 16
  *  MA 02110-1301, USA.
17 17
  */
18 18
 
19
-#ifdef	_MSC_VER
20
-#include <winsock.h>
21
-#endif
22
-
23 19
 #if HAVE_CONFIG_H
24 20
 #include "clamav-config.h"
25 21
 #endif
26 22
 
27
-#ifdef	C_WINDOWS
28
-#define	_USE_32BIT_TIME_T	/* FIXME: mirdat.atime assumes 32bit time_t */
29
-#endif
30
-
31 23
 #include <stdio.h>
32 24
 #include <string.h>
33 25
 #include <stdlib.h>
... ...
@@ -39,7 +31,7 @@
39 39
 #include <fcntl.h>
40 40
 #include <time.h>
41 41
 
42
-#ifndef C_WINDOWS
42
+#ifndef _WIN32
43 43
 #include <sys/socket.h>
44 44
 #include <netinet/in.h>
45 45
 #include <arpa/inet.h>
... ...
@@ -52,10 +44,6 @@
52 52
 
53 53
 #include "shared/output.h"
54 54
 
55
-#ifndef O_BINARY
56
-#define O_BINARY    0
57
-#endif
58
-
59 55
 #ifndef HAVE_GETADDRINFO
60 56
 #ifndef AF_INET6
61 57
 #define AF_INET6    0xbeef  /* foo */
... ...
@@ -133,7 +121,7 @@ int mirman_check(uint32_t *ip, int af, struct mirdat *mdat, struct mirdat_ip **m
133 133
 	    }
134 134
 
135 135
 	    if(mdat->dbflevel && (mdat->dbflevel > flevel) && (mdat->dbflevel - flevel > 3))
136
-		if(time(NULL) - mdat->mirtab[i].atime < 4 * 3600)
136
+		if(time(NULL) - mdat->mirtab[i].atime < (mdat->dbflevel - flevel) * 3600)
137 137
 		    return 2;
138 138
 
139 139
 	    if(mdat->mirtab[i].ignore) {
... ...
@@ -15,9 +15,6 @@
15 15
  *  along with this program; if not, write to the Free Software
16 16
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 17
  */
18
-#ifdef	_MSC_VER
19
-#include <winsock.h>
20
-#endif
21 18
 
22 19
 #if HAVE_CONFIG_H
23 20
 #include "clamav-config.h"
... ...
@@ -32,15 +29,13 @@
32 32
 #endif
33 33
 #include <string.h>
34 34
 #include <ctype.h>
35
-#ifndef	C_WINDOWS
35
+#ifndef	_WIN32
36 36
 #include <netinet/in.h>
37 37
 #include <netdb.h>
38
-#endif
39
-#include <sys/types.h>
40
-#ifndef	C_WINDOWS
41 38
 #include <sys/socket.h>
42 39
 #include <sys/time.h>
43 40
 #endif
41
+#include <sys/types.h>
44 42
 #include <time.h>
45 43
 #include <fcntl.h>
46 44
 #include <sys/stat.h>
... ...
@@ -49,16 +44,6 @@
49 49
 #include "shared/output.h"
50 50
 #include "libclamav/clamav.h"
51 51
 
52
-#if	(!defined(EALREADY)) && (defined(WSAEALREADY))
53
-#define EALREADY	WSAEALREADY
54
-#endif
55
-#if	(!defined(EINPROGRESS)) && (defined(WSAEINPROGRESS))
56
-#define EINPROGRESS	WSAEINPROGRESS
57
-#endif
58
-#if	(!defined(EISCONN)) && (defined(WSAEISCONN))
59
-#define EISCONN	WSAEISCONN
60
-#endif
61
-
62 52
 #ifdef SO_ERROR
63 53
 
64 54
 #ifndef timercmp
... ...
@@ -24,7 +24,7 @@
24 24
 #endif
25 25
 
26 26
 #include <sys/types.h>
27
-#ifndef	C_WINDOWS
27
+#ifndef	_WIN32
28 28
 #include <sys/socket.h>
29 29
 #endif
30 30
 
... ...
@@ -15,11 +15,6 @@
15 15
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
16 16
  *  MA 02110-1301, USA.
17 17
  */
18
-#ifdef        _MSC_VER
19
-#include <windows.h>
20
-#include <winsock.h>
21
-#endif
22
-
23 18
 
24 19
 #if HAVE_CONFIG_H
25 20
 #include "clamav-config.h"
... ...
@@ -32,7 +27,7 @@
32 32
 #include <unistd.h>
33 33
 #endif
34 34
 #include <sys/types.h>
35
-#ifndef	C_WINDOWS
35
+#ifndef	_WIN32
36 36
 #include <sys/socket.h>
37 37
 #include <sys/un.h>
38 38
 #include <netinet/in.h>
... ...
@@ -45,14 +40,10 @@
45 45
 #include "shared/output.h"
46 46
 #include "notify.h"
47 47
 
48
-#ifndef	C_WINDOWS
49
-#define	closesocket(s)	close(s)
50
-#endif
51
-
52 48
 int notify(const char *cfgfile)
53 49
 {
54 50
 	char buff[20];
55
-#ifndef	C_WINDOWS
51
+#ifndef	_WIN32
56 52
 	struct sockaddr_un server;
57 53
 #endif
58 54
 #ifdef HAVE_GETADDRINFO
... ...
@@ -75,7 +66,7 @@ int notify(const char *cfgfile)
75 75
 	return 1;
76 76
     }
77 77
 
78
-#ifndef	C_WINDOWS
78
+#ifndef	_WIN32
79 79
     if((opt = optget(opts, "LocalSocket"))->enabled) {
80 80
 	socktype = "UNIX";
81 81
 	server.sun_family = AF_UNIX;
... ...
@@ -37,10 +37,6 @@
37 37
 #include "7z/Archive/7z/7zIn.h"
38 38
 #include "7z/Archive/7z/7zExtract.h"
39 39
 
40
-#ifndef O_BINARY
41
-#define O_BINARY 0
42
-#endif
43
-
44 40
 static ISzAlloc allocImp = { __lzma_wrap_alloc, __lzma_wrap_free}, allocTempImp = { __lzma_wrap_alloc, __lzma_wrap_free};
45 41
 
46 42
 int cli_7unz (int fd, cli_ctx *ctx) {
... ...
@@ -356,8 +356,8 @@ version.h: version.h.tmp
356 356
 version.h.tmp:
357 357
 	@test -f version.h || touch version.h;\
358 358
 	rm -f $@;\
359
-	REVISION="$$(LANG=C cd "$(top_srcdir)"; git describe --always 2>/dev/null)";\
360
-	if test $$? -ne 0; then\
359
+	REVISION="$$(LANG=C cd "$(top_srcdir)"; git describe --always 2>/dev/null || echo "exported")";\
360
+	if test "$$REVISION" = "exported"; then\
361 361
 	   REVISION="r$$(LANG=C svnversion "$(top_srcdir)" 2>/dev/null || echo exported)";\
362 362
 	   if test "$$REVISION" = "rexported"; then\
363 363
 	    REVISION="";\
... ...
@@ -2200,8 +2200,8 @@ version.h: version.h.tmp
2200 2200
 version.h.tmp:
2201 2201
 	@test -f version.h || touch version.h;\
2202 2202
 	rm -f $@;\
2203
-	REVISION="$$(LANG=C cd "$(top_srcdir)"; git describe --always 2>/dev/null)";\
2204
-	if test $$? -ne 0; then\
2203
+	REVISION="$$(LANG=C cd "$(top_srcdir)"; git describe --always 2>/dev/null || echo "exported")";\
2204
+	if test "$$REVISION" = "exported"; then\
2205 2205
 	   REVISION="r$$(LANG=C svnversion "$(top_srcdir)" 2>/dev/null || echo exported)";\
2206 2206
 	   if test "$$REVISION" = "rexported"; then\
2207 2207
 	    REVISION="";\
... ...
@@ -35,10 +35,6 @@
35 35
 #include <unistd.h>
36 36
 #endif
37 37
 
38
-#ifndef O_BINARY
39
-#define O_BINARY        0
40
-#endif
41
-
42 38
 #include "others.h"
43 39
 #include "scanners.h"
44 40
 #include "autoit.h"
... ...
@@ -353,7 +349,7 @@ static int ea05(int desc, cli_ctx *ctx, char *tmpd) {
353 353
     /* FIXME: REGRESSION NEEDED! */
354 354
     /* UNP.usize = u2a(UNP.outputbuf, UNP.usize); */
355 355
 
356
-    snprintf(tempfile, 1023, "%s/autoit.%.3u", tmpd, files);
356
+    snprintf(tempfile, 1023, "%s"PATHSEP"autoit.%.3u", tmpd, files);
357 357
     tempfile[1023]='\0';
358 358
     if((i = open(tempfile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IRWXU)) < 0) {
359 359
       cli_dbgmsg("autoit: Can't create file %s\n", tempfile);
... ...
@@ -704,7 +700,7 @@ static int ea06(int desc, cli_ctx *ctx, char *tmpd) {
704 704
 	    val = (uint64_t)cli_readint32((char *)&UNP.outputbuf[UNP.cur_input+4]);
705 705
 	    val <<=32;
706 706
 	    val += (uint64_t)cli_readint32((char *)&UNP.outputbuf[UNP.cur_input]);
707
-	    snprintf((char *)&buf[UNP.cur_output], 20, "0x%016lx ", val);
707
+	    snprintf((char *)&buf[UNP.cur_output], 20, "0x%016lx ", (unsigned long int) val);
708 708
 	    UNP.cur_output += 19;
709 709
 	    UNP.cur_input += 8;
710 710
 	    break;
... ...
@@ -863,7 +859,7 @@ static int ea06(int desc, cli_ctx *ctx, char *tmpd) {
863 863
       UNP.cur_output = UNP.usize ;
864 864
     }
865 865
 
866
-    snprintf(tempfile, 1023, "%s/autoit.%.3u", tmpd, files);
866
+    snprintf(tempfile, 1023, "%s"PATHSEP"autoit.%.3u", tmpd, files);
867 867
     tempfile[1023]='\0';
868 868
     if((i = open(tempfile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IRWXU)) < 0) {
869 869
       cli_dbgmsg("autoit: Can't create file %s\n", tempfile);
... ...
@@ -13,6 +13,10 @@
13 13
  * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
14 14
  */
15 15
 
16
+#if HAVE_CONFIG_H
17
+#include "clamav-config.h"
18
+#endif
19
+
16 20
 /* Start: bn_error.c */
17 21
 #include <bignum.h>
18 22
 #include "others.h"
... ...
@@ -44,14 +44,6 @@
44 44
 #define LTM_ALL /* FIXME: tk: limit to the above class */
45 45
 #include "bignum_class.h"
46 46
 
47
-#ifndef MIN
48
-   #define MIN(x,y) ((x)<(y)?(x):(y))
49
-#endif
50
-
51
-#ifndef MAX
52
-   #define MAX(x,y) ((x)>(y)?(x):(y))
53
-#endif
54
-
55 47
 #ifdef __cplusplus
56 48
 extern "C" {
57 49
 
... ...
@@ -100,19 +100,14 @@ static	char	const	rcsid[] = "$Id: binhex.c,v 1.23 2007/02/12 20:46:08 njh Exp $"
100 100
 #endif
101 101
 #endif
102 102
 
103
-#ifdef	HAVE_MMAP
104
-#if HAVE_SYS_MMAN_H
105
-#include <sys/mman.h>
106
-#else /* HAVE_SYS_MMAN_H */
107
-#undef HAVE_MMAP
108
-#endif
109
-#endif
110
-
111 103
 #include <stdio.h>
112 104
 #include <memory.h>
113 105
 #include <sys/stat.h>
114
-#include "others.h"
106
+#if defined(HAVE_MMAP) && defined(HAVE_SYS_MMAN_H)
107
+#include <sys/mman.h>
108
+#endif
115 109
 
110
+#include "others.h"
116 111
 #include "mbox.h"
117 112
 #include "binhex.h"
118 113
 
... ...
@@ -24,11 +24,6 @@ static	char	const	rcsid[] = "$Id: blob.c,v 1.64 2007/02/12 22:25:14 njh Exp $";
24 24
 #include "clamav-config.h"
25 25
 #endif
26 26
 
27
-#ifdef	C_WINDOWS
28
-#include "stdafx.h"
29
-#include <io.h>
30
-#endif
31
-
32 27
 #include <stdio.h>
33 28
 #include <stdlib.h>
34 29
 #include <string.h>
... ...
@@ -53,16 +48,8 @@ static	char	const	rcsid[] = "$Id: blob.c,v 1.64 2007/02/12 22:25:14 njh Exp $";
53 53
 #include "scanners.h"
54 54
 #include "filetypes.h"
55 55
 
56
-#ifndef	O_BINARY
57
-#define	O_BINARY	0
58
-#endif
59
-
60 56
 #include <assert.h>
61 57
 
62
-#if	defined(C_MINGW) || defined(C_WINDOWS)
63
-#include <windows.h>
64
-#endif
65
-
66 58
 /* Scehduled for rewite in 0.94 (bb#804). Disabling for now */
67 59
 /* #define	MAX_SCAN_SIZE	20*1024	/\* */
68 60
 /* 				 * The performance benefit of scanning */
... ...
@@ -648,16 +635,10 @@ fileblobScan(const fileblob *fb)
648 648
 
649 649
 	fflush(fb->fp);
650 650
 	lseek(fb->fd, 0, SEEK_SET);
651
-	rc = cli_magic_scandesc(fb->fd, fb->ctx);
652 651
 
653
-	if(rc == CL_CLEAN) {
654
-		lseek(fb->fd, 0, SEEK_SET);
655
-		ftype = cli_filetype2(fb->fd, fb->ctx->engine);
656
-		if(ftype >= CL_TYPE_TEXT_ASCII && ftype <= CL_TYPE_TEXT_UTF16BE) {
657
-			lseek(fb->fd, 0, SEEK_SET);
658
-			rc = cli_scandesc(fb->fd, fb->ctx, CL_TYPE_MAIL, 0, NULL, AC_SCAN_VIR);
659
-		}
660
-	}
652
+	fb->ctx->container_type = CL_TYPE_MAIL;
653
+	rc = cli_magic_scandesc(fb->fd, fb->ctx);
654
+	fb->ctx->container_type = 0;
661 655
 
662 656
 	if(rc == CL_VIRUS) {
663 657
 		cli_dbgmsg("%s is infected\n", fb->fullname);
... ...
@@ -685,21 +666,9 @@ fileblobInfected(const fileblob *fb)
685 685
 void
686 686
 sanitiseName(char *name)
687 687
 {
688
-	while(*name) {
689
-#ifdef	C_DARWIN
690
-		*name &= '\177';
691
-#endif
692
-#if	defined(MSDOS) || defined(C_OS2)
693
-		/*
694
-		 * Don't take it from this that ClamAV supports DOS, it doesn't
695
-		 * I don't know if spaces are legal in OS/2.
696
-		 */
697
-		if(strchr("%/*?<>|\\\"+=,;:\t ~", *name))
698
-#elif defined(C_WINDOWS)
699
-		if(strchr("%/*?<>|\\\"+=,;:\t~", *name))
700
-#else
701
-		if(*name == '/')
702
-#endif
688
+	char c;
689
+	while((c = *name)) {
690
+		if(c!='.' && c!='_' && (c>'z' || c<'0' || (c>'9' && c<'A') || (c>'Z' && c<'a')))
703 691
 			*name = '_';
704 692
 		name++;
705 693
 	}
... ...
@@ -40,10 +40,6 @@
40 40
 #define EC32(x) le32_to_host(x) /* Convert little endian to host */
41 41
 #define EC16(x) le16_to_host(x)
42 42
 
43
-#ifndef O_BINARY
44
-#define O_BINARY        0
45
-#endif
46
-
47 43
 /* hard limits */
48 44
 #define CAB_FOLDER_LIMIT    5000
49 45
 #define CAB_FILE_LIMIT	    5000
... ...
@@ -31,19 +31,10 @@
31 31
 #ifdef	HAVE_UNISTD_H
32 32
 #include <unistd.h>
33 33
 #endif
34
-#include <string.h>
35
-
36
-#if defined(HAVE_ATTRIB_PACKED) || defined(HAVE_PRAGMA_PACK) || defined(HAVE_PRAGMA_PACK_HPPA)
37
-#if HAVE_MMAP
38
-#if HAVE_SYS_MMAN_H
34
+#if defined(HAVE_MMAP) && defined(HAVE_SYS_MMAN_H)
39 35
 #include <sys/mman.h>
40
-#else /* HAVE_SYS_MMAN_H */
41
-#undef HAVE_MMAP
42
-#endif /* HAVE_SYS_MMAN_H */
43
-#endif /* HAVE_MMAP */
44
-#else/* PACKED */
45
-#undef HAVE_MMAP
46 36
 #endif
37
+#include <string.h>
47 38
 
48 39
 #include "others.h"
49 40
 #include "mspack.h"
... ...
@@ -63,10 +54,6 @@
63 63
 #pragma pack 1
64 64
 #endif
65 65
 
66
-#ifndef	O_BINARY
67
-#define	O_BINARY	0
68
-#endif
69
-
70 66
 #define CHM_CHUNK_HDR_LEN (0x14)
71 67
 
72 68
 #define CHM_CONTROL_LEN (0x18)
... ...
@@ -693,7 +680,7 @@ static int chm_decompress_stream(int fd, chm_metadata_t *metadata, const char *d
693 693
 	char filename[1024];
694 694
 	struct cab_file file;
695 695
 	
696
-	snprintf(filename, 1024, "%s/clamav-unchm.bin", dirname);
696
+	snprintf(filename, 1024, "%s"PATHSEP"clamav-unchm.bin", dirname);
697 697
 	tmpfd = open(filename, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IRWXU);
698 698
 	if (tmpfd<0) {
699 699
 		cli_dbgmsg("open failed for %s\n", filename);
... ...
@@ -769,7 +756,7 @@ static int chm_decompress_stream(int fd, chm_metadata_t *metadata, const char *d
769 769
 	lzx_decompress(stream, length);
770 770
 	lzx_free(stream);
771 771
 	
772
-#ifndef C_WINDOWS
772
+#ifndef _WIN32
773 773
 	/* Delete the file */
774 774
 	if(cli_unlink(filename))
775 775
 		retval = -1;
... ...
@@ -826,7 +813,7 @@ int cli_chm_extract_file(int fd, char *dirname, chm_metadata_t *metadata, cli_ct
826 826
 		cli_dbgmsg("seek in uncompressed stream failed\n");
827 827
 		return CL_EFORMAT;
828 828
 	}
829
-	snprintf(filename, 1024, "%s/%lu.chm", dirname, (unsigned long int) metadata->file_offset);
829
+	snprintf(filename, 1024, "%s"PATHSEP"%lu.chm", dirname, (unsigned long int) metadata->file_offset);
830 830
 	metadata->ofd = open(filename, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IRWXU);
831 831
 	if (metadata->ofd < 0) {
832 832
 		return CL_ECREAT;
... ...
@@ -45,10 +45,6 @@
45 45
 
46 46
 #define TAR_BLOCKSIZE 512
47 47
 
48
-#ifndef	O_BINARY
49
-#define	O_BINARY	0
50
-#endif
51
-
52 48
 static int cli_untgz(int fd, const char *destdir)
53 49
 {
54 50
 	char *path, osize[13], name[101], type;
... ...
@@ -109,7 +105,7 @@ static int cli_untgz(int fd, const char *destdir)
109 109
 		return -1;
110 110
 	    }
111 111
 
112
-	    snprintf(path, pathlen, "%s/%s", destdir, name);
112
+	    snprintf(path, pathlen, "%s"PATHSEP"%s", destdir, name);
113 113
 	    cli_dbgmsg("cli_untgz: Unpacking %s\n", path);
114 114
 	    type = block[156];
115 115
 
... ...
@@ -25,14 +25,11 @@
25 25
 #define CLI_DEFAULT_AC_MAXDEPTH	    3
26 26
 #define CLI_DEFAULT_AC_TRACKLEN	    8
27 27
 
28
-#define CLI_DEFAULT_MOVETOAC_LEN    8 /* all static sigs shorter than
29
-				       * this value will automatically
30
-				       * go to AC instead of BM
31
-				       */
32
-
33 28
 #define CLI_DEFAULT_LSIG_BUFSIZE    32768
34 29
 #define CLI_DEFAULT_DBIO_BUFSIZE    CLI_DEFAULT_LSIG_BUFSIZE + 1
35 30
 
31
+#define CLI_DEFAULT_BM_OFFMODE_FSIZE	262144
32
+
36 33
 #define CLI_DEFAULT_MAXSCANSIZE	    104857600
37 34
 #define CLI_DEFAULT_MAXFILESIZE	    26214400
38 35
 #define CLI_DEFAULT_MAXRECLEVEL	    16
... ...
@@ -39,13 +39,8 @@
39 39
 #include <errno.h>
40 40
 #include <stdio.h>
41 41
 #include <ctype.h>
42
-
43
-#if HAVE_MMAP
44
-#if HAVE_SYS_MMAN_H
42
+#if defined(HAVE_MMAP) && defined(HAVE_SYS_MMAN_H)
45 43
 #include <sys/mman.h>
46
-#else /* HAVE_SYS_MMAN_H */
47
-#undef HAVE_MMAP
48
-#endif
49 44
 #endif
50 45
 
51 46
 #include "others.h"
... ...
@@ -653,7 +648,7 @@ static int cli_html_normalise(int fd, m_area_t *m_area, const char *dirname, tag
653 653
 	tag_args.value = NULL;
654 654
 	tag_args.contents = NULL;
655 655
 	if (dirname) {
656
-		snprintf(filename, 1024, "%s/rfc2397", dirname);
656
+		snprintf(filename, 1024, "%s"PATHSEP"rfc2397", dirname);
657 657
 		if (mkdir(filename, 0700) && errno != EEXIST) {
658 658
 			file_buff_o2 = file_buff_text = NULL;
659 659
 			goto abort;
... ...
@@ -666,7 +661,7 @@ static int cli_html_normalise(int fd, m_area_t *m_area, const char *dirname, tag
666 666
 		}
667 667
 
668 668
 		/* this will still contains scripts that are inside comments */
669
-		snprintf(filename, 1024, "%s/nocomment.html", dirname);
669
+		snprintf(filename, 1024, "%s"PATHSEP"nocomment.html", dirname);
670 670
 		file_buff_o2->fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, S_IWUSR|S_IRUSR);
671 671
 		if (file_buff_o2->fd == -1) {
672 672
 			cli_dbgmsg("open failed: %s\n", filename);
... ...
@@ -683,7 +678,7 @@ static int cli_html_normalise(int fd, m_area_t *m_area, const char *dirname, tag
683 683
 			goto abort;
684 684
 		}
685 685
 
686
-		snprintf(filename, 1024, "%s/notags.html", dirname);
686
+		snprintf(filename, 1024, "%s"PATHSEP"notags.html", dirname);
687 687
 		file_buff_text->fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, S_IWUSR|S_IRUSR);
688 688
 		if(file_buff_text->fd == -1) {
689 689
 			cli_dbgmsg("open failed: %s\n", filename);
... ...
@@ -1482,7 +1477,7 @@ static int cli_html_normalise(int fd, m_area_t *m_area, const char *dirname, tag
1482 1482
 					if (!file_tmp_o1) {
1483 1483
 						goto abort;
1484 1484
 					}
1485
-					snprintf(filename, 1024, "%s/rfc2397", dirname);
1485
+					snprintf(filename, 1024, "%s"PATHSEP"rfc2397", dirname);
1486 1486
 					tmp_file = cli_gentemp(filename);
1487 1487
 					if(!tmp_file) {
1488 1488
 						goto abort;
... ...
@@ -1755,7 +1750,7 @@ int html_screnc_decode(int fd, const char *dirname)
1755 1755
 		return FALSE;
1756 1756
 	}
1757 1757
 
1758
-	snprintf((char*)filename, 1024, "%s/screnc.html", dirname);
1758
+	snprintf((char*)filename, 1024, "%s"PATHSEP"screnc.html", dirname);
1759 1759
 	ofd = open((const char*)filename, O_WRONLY|O_CREAT|O_TRUNC, S_IWUSR|S_IRUSR);
1760 1760
 
1761 1761
 	if (ofd < 0) {
... ...
@@ -32,11 +32,6 @@
32 32
 #ifdef	HAVE_UNISTD_H
33 33
 #include <unistd.h>
34 34
 #endif
35
-#if HAVE_MMAP
36
-#ifdef HAVE_SYS_MMAN_H
37
-#include <sys/mman.h>
38
-#endif
39
-#endif /* HAVE_MMAP */
40 35
 #if HAVE_STRING_H
41 36
 #include <string.h>
42 37
 #endif
... ...
@@ -44,6 +39,9 @@
44 44
 #if HAVE_STRINGS_H
45 45
 #include <strings.h>
46 46
 #endif
47
+#if defined(HAVE_MMAP) && defined(HAVE_SYS_MMAN_H)
48
+#include <sys/mman.h>
49
+#endif
47 50
 #include <zlib.h>
48 51
 
49 52
 #include "scanners.h"
... ...
@@ -51,10 +49,6 @@
51 51
 #include "others.h"
52 52
 #include "ishield.h"
53 53
 
54
-#ifndef O_BINARY
55
-#define O_BINARY 0
56
-#endif
57
-
58 54
 #ifndef LONG_MAX
59 55
 #define LONG_MAX ((-1UL)>>1)
60 56
 #endif
... ...
@@ -225,7 +219,7 @@ int cli_scanishield_msi(int desc, cli_ctx *ctx, off_t off) {
225 225
 	csize = le64_to_host(fb.csize);
226 226
 
227 227
 	if(ctx->engine->maxfilesize && csize > ctx->engine->maxfilesize) {
228
-	    cli_dbgmsg("ishield-msi: skipping stream due to size limits (%lu vs %lu)\n", csize, ctx->engine->maxfilesize);
228
+	    cli_dbgmsg("ishield-msi: skipping stream due to size limits (%lu vs %lu)\n", (unsigned long int) csize, (unsigned long int) ctx->engine->maxfilesize);
229 229
 	    lseek(desc, csize, SEEK_CUR);
230 230
 	    continue;
231 231
 	}
... ...
@@ -278,7 +272,7 @@ int cli_scanishield_msi(int desc, cli_ctx *ctx, off_t off) {
278 278
 		    break;
279 279
 		}
280 280
 		if(ctx->engine->maxfilesize && z.total_out > ctx->engine->maxfilesize) {
281
-		    cli_dbgmsg("ishield-msi: trimming output file due to size limits (%lu vs %lu)\n", z.total_out, ctx->engine->maxfilesize);
281
+		    cli_dbgmsg("ishield-msi: trimming output file due to size limits (%lu vs %lu)\n", z.total_out, (unsigned long int) ctx->engine->maxfilesize);
282 282
 		    lseek(desc, csize, SEEK_CUR);
283 283
 		    csize = 0;
284 284
 		    break;
... ...
@@ -371,7 +365,7 @@ int cli_scanishield(int desc, cli_ctx *ctx, off_t off, size_t sz) {
371 371
 	   data - buf >= sz - fsize
372 372
 	) break;
373 373
 
374
-	cli_dbgmsg("ishield: @%lx found file %s (%s) - version %s - size %lu\n", coff, fname, path, version, fsize);
374
+	cli_dbgmsg("ishield: @%lx found file %s (%s) - version %s - size %lu\n", (unsigned long int) coff, fname, path, version, (unsigned long int) fsize);
375 375
 	sz -= (data - buf) + fsize;
376 376
 	coff += (data - buf);
377 377
 	if(!strncasecmp(fname, "data", 4)) {
... ...
@@ -636,7 +630,7 @@ static int is_parse_hdr(int desc, cli_ctx *ctx, struct IS_CABSTUFF *c) {
636 636
 			int cabret = CL_CLEAN;
637 637
 
638 638
 			if(ctx->engine->maxfilesize && file_csize > ctx->engine->maxfilesize) {
639
-			    cli_dbgmsg("is_parse_hdr: skipping file due to size limits (%lu vs %lu)\n", file_csize, ctx->engine->maxfilesize);
639
+			    cli_dbgmsg("is_parse_hdr: skipping file due to size limits (%lu vs %lu)\n", (unsigned long int) file_csize, (unsigned long int) ctx->engine->maxfilesize);
640 640
 			    break;
641 641
 			}
642 642
 
... ...
@@ -797,7 +791,7 @@ static int is_extract_cab(int desc, cli_ctx *ctx, uint64_t off, uint64_t size, u
797 797
 		    break;
798 798
 		}
799 799
 		if(ctx->engine->maxfilesize && z.total_out > ctx->engine->maxfilesize) {
800
-		    cli_dbgmsg("ishield_extract_cab: trimming output file due to size limits (%lu vs %lu)\n", z.total_out, ctx->engine->maxfilesize);
800
+		    cli_dbgmsg("ishield_extract_cab: trimming output file due to size limits (%lu vs %lu)\n", z.total_out, (unsigned long int) ctx->engine->maxfilesize);
801 801
 		    success = 1;
802 802
 		    outsz = size;
803 803
 		    break;
... ...
@@ -495,11 +495,6 @@ static int match_parameters(const yystype *tokens, const char ** param_names, si
495 495
 static const char *de_packer_3[] = {"p","a","c","k","e","r"};
496 496
 static const char *de_packer_2[] = {"p","a","c","k","e","d"};
497 497
 
498
-
499
-#ifndef MAX
500
-#define MAX(a, b) ((a)>(b) ? (a) : (b))
501
-#endif
502
-
503 498
 static inline char *textbuffer_done(yyscan_t scanner)
504 499
 {
505 500
 	/* free unusued memory */
... ...
@@ -902,7 +897,7 @@ void cli_js_output(struct parser_state *state, const char *tempdir)
902 902
 	char lastchar = '\0';
903 903
 	char filename[1024];
904 904
 
905
-	snprintf(filename, 1024, "%s/javascript", tempdir);
905
+	snprintf(filename, 1024, "%s"PATHSEP"javascript", tempdir);
906 906
 
907 907
 	buf.pos = 0;
908 908
 	buf.outfd = open(filename, O_CREAT | O_WRONLY, 0600);
... ...
@@ -1390,10 +1385,6 @@ static inline int parseId(YYSTYPE *lvalp, yyscan_t scanner)
1390 1390
 	return 0;
1391 1391
 }
1392 1392
 
1393
-#ifndef MIN
1394
-#define MIN(a,b) ((a)<(b) ? (a):(b))
1395
-#endif
1396
-
1397 1393
 static int parseOperator(YYSTYPE *lvalp, yyscan_t scanner)
1398 1394
 {
1399 1395
 	size_t len = MIN(5, scanner->insize - scanner->pos);
... ...
@@ -32,6 +32,7 @@ CLAMAV_PUBLIC {
32 32
 };
33 33
 CLAMAV_PRIVATE {
34 34
   global:
35
+    cli_gettmpdir;
35 36
     cli_strtok;
36 37
     cli_strtokenize;
37 38
     cli_cvdunpack;
... ...
@@ -26,6 +26,7 @@
26 26
 #include <string.h>
27 27
 #include <stdlib.h>
28 28
 #include <ctype.h>
29
+#include <sys/stat.h>
29 30
 
30 31
 #include <assert.h>
31 32
 #ifdef	HAVE_UNISTD_H
... ...
@@ -44,12 +45,45 @@
44 44
 
45 45
 #include "mpool.h"
46 46
 
47
+#define AC_SPECIAL_ALT_CHAR	1
48
+#define AC_SPECIAL_ALT_STR	2
49
+#define AC_SPECIAL_LINE_MARKER	3
50
+#define AC_SPECIAL_BOUNDARY	4
51
+
52
+#define AC_BOUNDARY_LEFT		1
53
+#define AC_BOUNDARY_LEFT_NEGATIVE	2
54
+#define AC_BOUNDARY_RIGHT		4
55
+#define AC_BOUNDARY_RIGHT_NEGATIVE	8
56
+#define AC_LINE_MARKER_LEFT		16
57
+#define AC_LINE_MARKER_LEFT_NEGATIVE	32
58
+#define AC_LINE_MARKER_RIGHT		64
59
+#define AC_LINE_MARKER_RIGHT_NEGATIVE	128
60
+
61
+static char boundary[256] = {
62
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 
63
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
64
+    3, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 3, 1, 3, 
65
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 
66
+    1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
67
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 
68
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
69
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
70
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
71
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
72
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
73
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
74
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
75
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
76
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
77
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
78
+};
79
+
47 80
 int cli_ac_addpatt(struct cli_matcher *root, struct cli_ac_patt *pattern)
48 81
 {
49 82
 	struct cli_ac_node *pt, *next;
50 83
 	struct cli_ac_patt *ph;
51 84
 	void *newtable;
52
-	struct cli_ac_alt *a1, *a2;
85
+	struct cli_ac_special *a1, *a2;
53 86
 	uint8_t i, match;
54 87
 	uint16_t len = MIN(root->ac_maxdepth, pattern->length);
55 88
 
... ...
@@ -130,27 +164,31 @@ int cli_ac_addpatt(struct cli_matcher *root, struct cli_ac_patt *pattern)
130 130
     while(ph) {
131 131
 	if((ph->length == pattern->length) && (ph->prefix_length == pattern->prefix_length) && (ph->ch[0] == pattern->ch[0]) && (ph->ch[1] == pattern->ch[1])) {
132 132
 	    if(!memcmp(ph->pattern, pattern->pattern, ph->length * sizeof(uint16_t)) && !memcmp(ph->prefix, pattern->prefix, ph->prefix_length * sizeof(uint16_t))) {
133
-		if(!ph->alt && !pattern->alt) {
133
+		if(!ph->special && !pattern->special) {
134 134
 		    match = 1;
135
-		} else if(ph->alt == pattern->alt) {
135
+		} else if(ph->special == pattern->special) {
136 136
 		    match = 1;
137
-		    for(i = 0; i < ph->alt; i++) {
138
-			a1 = ph->alttable[i];
139
-			a2 = pattern->alttable[i];
137
+		    for(i = 0; i < ph->special; i++) {
138
+			a1 = ph->special_table[i];
139
+			a2 = pattern->special_table[i];
140 140
 
141 141
 			if(a1->num != a2->num) {
142 142
 			    match = 0;
143 143
 			    break;
144 144
 			}
145
-			if(a1->chmode != a2->chmode) {
145
+			if(a1->negative != a2->negative) {
146
+			    match = 0;
147
+			    break;
148
+			}
149
+			if(a1->type != a2->type) {
146 150
 			    match = 0;
147 151
 			    break;
148
-			} else if(a1->chmode) {
152
+			} else if(a1->type == AC_SPECIAL_ALT_CHAR) {
149 153
 			    if(memcmp(a1->str, a2->str, a1->num)) {
150 154
 				match = 0;
151 155
 				break;
152 156
 			    }
153
-			} else {
157
+			} else if(a1->type == AC_SPECIAL_ALT_STR) {
154 158
 			    while(a1 && a2) {
155 159
 				if((a1->len != a2->len) || memcmp(a1->str, a2->str, a1->len))
156 160
 				    break;
... ...
@@ -349,22 +387,22 @@ int cli_ac_init(struct cli_matcher *root, uint8_t mindepth, uint8_t maxdepth)
349 349
 }
350 350
 
351 351
 #ifdef USE_MPOOL
352
-#define mpool_ac_free_alt(a, b) ac_free_alt(a, b)
353
-static void ac_free_alt(mpool_t *mempool, struct cli_ac_patt *p)
352
+#define mpool_ac_free_special(a, b) ac_free_special(a, b)
353
+static void ac_free_special(mpool_t *mempool, struct cli_ac_patt *p)
354 354
 #else
355
-#define mpool_ac_free_alt(a, b) ac_free_alt(b)
356
-static void ac_free_alt(struct cli_ac_patt *p)
355
+#define mpool_ac_free_special(a, b) ac_free_special(b)
356
+static void ac_free_special(struct cli_ac_patt *p)
357 357
 #endif
358 358
 {
359
-	uint16_t i;
360
-	struct cli_ac_alt *a1, *a2;
359
+	unsigned int i;
360
+	struct cli_ac_special *a1, *a2;
361 361
 
362 362
 
363
-    if(!p->alt)
363
+    if(!p->special)
364 364
 	return;
365 365
 
366
-    for(i = 0; i < p->alt; i++) {
367
-	a1 = p->alttable[i];
366
+    for(i = 0; i < p->special; i++) {
367
+	a1 = p->special_table[i];
368 368
 	while(a1) {
369 369
 	    a2 = a1;
370 370
 	    a1 = a1->next;
... ...
@@ -373,7 +411,7 @@ static void ac_free_alt(struct cli_ac_patt *p)
373 373
 	    mpool_free(mempool, a2);
374 374
 	}
375 375
     }
376
-    mpool_free(mempool, p->alttable);
376
+    mpool_free(mempool, p->special_table);
377 377
 }
378 378
 
379 379
 void cli_ac_free(struct cli_matcher *root)
... ...
@@ -386,8 +424,8 @@ void cli_ac_free(struct cli_matcher *root)
386 386
 	patt = root->ac_pattable[i];
387 387
 	mpool_free(root->mempool, patt->prefix ? patt->prefix : patt->pattern);
388 388
 	mpool_free(root->mempool, patt->virname);
389
-	if(patt->alt)
390
-	    mpool_ac_free_alt(root->mempool, patt);
389
+	if(patt->special)
390
+	    mpool_ac_free_special(root->mempool, patt);
391 391
 	mpool_free(root->mempool, patt);
392 392
     }
393 393
     if(root->ac_pattable)
... ...
@@ -649,61 +687,84 @@ int cli_ac_chklsig(const char *expr, const char *end, uint32_t *lsigcnt, unsigne
649 649
  *        more than one of them can match at the current position.
650 650
  */
651 651
 
652
-#define AC_MATCH_CHAR(p,b)						\
653
-    switch(wc = p & CLI_MATCH_WILDCARD) {				\
654
-	case CLI_MATCH_CHAR:						\
655
-	    if((unsigned char) p != b)					\
656
-		match = 0;						\
657
-	    break;							\
658
-									\
659
-	case CLI_MATCH_IGNORE:						\
660
-	    break;							\
661
-									\
662
-	case CLI_MATCH_ALTERNATIVE:					\
663
-	    match = 0;							\
664
-	    alt = pattern->alttable[altcnt];				\
665
-	    if(alt->chmode) {						\
666
-		for(j = 0; j < alt->num; j++) {				\
667
-		    if(alt->str[j] == b) {				\
668
-			match = 1;					\
669
-			break;						\
670
-		    }							\
671
-		}							\
672
-	    } else {							\
673
-		while(alt) {						\
674
-		    if(bp + alt->len <= length) {			\
675
-			if(!memcmp(&buffer[bp], alt->str, alt->len)) {	\
676
-			    match = 1;					\
677
-			    bp += alt->len - 1;				\
678
-			    break;					\
679
-			}						\
680
-		    }							\
681
-		    alt = alt->next;					\
682
-		}							\
683
-	    }								\
684
-	    altcnt++;							\
685
-	    break;							\
686
-									\
687
-	case CLI_MATCH_NIBBLE_HIGH:					\
688
-	    if((unsigned char) (p & 0x00f0) != (b & 0xf0))		\
689
-		match = 0;						\
690
-	    break;							\
691
-									\
692
-	case CLI_MATCH_NIBBLE_LOW:					\
693
-	    if((unsigned char) (p & 0x000f) != (b & 0x0f))		\
694
-		match = 0;						\
695
-	    break;							\
696
-									\
697
-	default:							\
698
-	    cli_errmsg("ac_findmatch: Unknown wildcard 0x%x\n", wc);	\
699
-	    match = 0;							\
652
+#define AC_MATCH_CHAR(p,b)								\
653
+    switch(wc = p & CLI_MATCH_WILDCARD) {						\
654
+	case CLI_MATCH_CHAR:								\
655
+	    if((unsigned char) p != b)							\
656
+		match = 0;								\
657
+	    break;									\
658
+											\
659
+	case CLI_MATCH_IGNORE:								\
660
+	    break;									\
661
+											\
662
+	case CLI_MATCH_SPECIAL:								\
663
+	    special = pattern->special_table[specialcnt];				\
664
+	    match = special->negative;							\
665
+	    switch(special->type) {							\
666
+		case AC_SPECIAL_ALT_CHAR:						\
667
+		    for(j = 0; j < special->num; j++) {					\
668
+			if(special->str[j] == b) {					\
669
+			    match = !special->negative;					\
670
+			    break;							\
671
+			} else if(special->str[j] > b)					\
672
+			    break;							\
673
+		    }									\
674
+		    break;								\
675
+											\
676
+		case AC_SPECIAL_ALT_STR:						\
677
+		    while(special) {							\
678
+			if(bp + special->len <= length) {				\
679
+			    if(!memcmp(&buffer[bp], special->str, special->len)) {	\
680
+				match = !special->negative;				\
681
+				bp += special->len - 1;					\
682
+				break;							\
683
+			    }								\
684
+			}								\
685
+			special = special->next;					\
686
+		    }									\
687
+		    break;								\
688
+											\
689
+		case AC_SPECIAL_LINE_MARKER:						\
690
+		    if(b == '\n') {							\
691
+			match = !special->negative;					\
692
+		    } else if(b == '\r' && (bp + 1 < length && buffer[bp + 1] == '\n')) {   \
693
+			bp++;								\
694
+			match = !special->negative;					\
695
+		    }									\
696
+		    break;								\
697
+											\
698
+		case AC_SPECIAL_BOUNDARY:						\
699
+		    if(boundary[b])							\
700
+			match = !special->negative;					\
701
+		    break;								\
702
+											\
703
+		default:								\
704
+		    cli_errmsg("ac_findmatch: Unknown special\n");			\
705
+		    match = 0;								\
706
+	    }										\
707
+	    specialcnt++;								\
708
+	    break;									\
709
+											\
710
+	case CLI_MATCH_NIBBLE_HIGH:							\
711
+	    if((unsigned char) (p & 0x00f0) != (b & 0xf0))				\
712
+		match = 0;								\
713
+	    break;									\
714
+											\
715
+	case CLI_MATCH_NIBBLE_LOW:							\
716
+	    if((unsigned char) (p & 0x000f) != (b & 0x0f))				\
717
+		match = 0;								\
718
+	    break;									\
719
+											\
720
+	default:									\
721
+	    cli_errmsg("ac_findmatch: Unknown wildcard 0x%x\n", wc);			\
722
+	    match = 0;									\
700 723
     }
701 724
 
702
-inline static int ac_findmatch(const unsigned char *buffer, uint32_t offset, uint32_t length, const struct cli_ac_patt *pattern, uint32_t *end)
725
+inline static int ac_findmatch(const unsigned char *buffer, uint32_t offset, uint32_t fileoffset, uint32_t length, const struct cli_ac_patt *pattern, uint32_t *end)
703 726
 {
704 727
 	uint32_t bp, match;
705
-	uint16_t wc, i, j, altcnt = pattern->alt_pattern;
706
-	struct cli_ac_alt *alt;
728
+	uint16_t wc, i, j, specialcnt = pattern->special_pattern;
729
+	struct cli_ac_special *special;
707 730
 
708 731
 
709 732
     if((offset + pattern->length > length) || (pattern->prefix_length > offset))
... ...
@@ -720,6 +781,38 @@ inline static int ac_findmatch(const unsigned char *buffer, uint32_t offset, uin
720 720
     }
721 721
     *end = bp;
722 722
 
723
+    if(pattern->boundary & AC_BOUNDARY_LEFT) {
724
+	match = !!(pattern->boundary & AC_BOUNDARY_LEFT_NEGATIVE);
725
+	if(!fileoffset || (offset && (boundary[buffer[offset - 1]] == 1 || boundary[buffer[offset - 1]] == 3)))
726
+	    match = !match;
727
+	if(!match)
728
+	    return 0;
729
+    }
730
+
731
+    if(pattern->boundary & AC_BOUNDARY_RIGHT) {
732
+	match = !!(pattern->boundary & AC_BOUNDARY_RIGHT_NEGATIVE);
733
+	if((length <= SCANBUFF) && (bp == length || boundary[buffer[bp]] >= 2))
734
+	    match = !match;
735
+	if(!match)
736
+	    return 0;
737
+    }
738
+
739
+    if(pattern->boundary & AC_LINE_MARKER_LEFT) {
740
+	match = !!(pattern->boundary & AC_LINE_MARKER_LEFT_NEGATIVE);
741
+	if(!fileoffset || (offset && (buffer[offset - 1] == '\n')))
742
+	    match = !match;
743
+	if(!match)
744
+	    return 0;
745
+    }
746
+
747
+    if(pattern->boundary & AC_LINE_MARKER_RIGHT) {
748
+	match = !!(pattern->boundary & AC_LINE_MARKER_RIGHT_NEGATIVE);
749
+	if((length <= SCANBUFF) && (bp == length || buffer[bp] == '\n' || (buffer[bp] == '\r' && bp + 1 < length && buffer[bp + 1] == '\n')))
750
+	    match = !match;
751
+	if(!match)
752
+	    return 0;
753
+    }
754
+
723 755
     if(!(pattern->ch[1] & CLI_MATCH_IGNORE)) {
724 756
 	bp += pattern->ch_mindist[1];
725 757
 	for(i = pattern->ch_mindist[1]; i <= pattern->ch_maxdist[1]; i++) {
... ...
@@ -736,7 +829,7 @@ inline static int ac_findmatch(const unsigned char *buffer, uint32_t offset, uin
736 736
     }
737 737
 
738 738
     if(pattern->prefix) {
739
-	altcnt = 0;
739
+	specialcnt = 0;
740 740
 	bp = offset - pattern->prefix_length;
741 741
 	match = 1;
742 742
 	for(i = 0; i < pattern->prefix_length; i++) {
... ...
@@ -835,8 +928,17 @@ int cli_ac_caloff(const struct cli_matcher *root, struct cli_ac_data *data, int
835 835
 	unsigned int i;
836 836
 	struct cli_ac_patt *patt;
837 837
 	struct cli_target_info info;
838
+	struct stat sb;
839
+
840
+    if(fd != -1) {
841
+	memset(&info, 0, sizeof(info));
842
+	if(fstat(fd, &sb) == -1) {
843
+	    cli_errmsg("cli_ac_caloff: fstat(%d) failed\n", fd);
844
+	    return CL_ESTAT;
845
+	}
846
+	info.fsize = sb.st_size;
847
+    }
838 848
 
839
-    memset(&info, 0, sizeof(info));
840 849
     for(i = 0; i < root->ac_reloff_num; i++) {
841 850
 	patt = root->ac_reloff[i];
842 851
 	if(fd == -1) {
... ...
@@ -846,9 +948,11 @@ int cli_ac_caloff(const struct cli_matcher *root, struct cli_ac_data *data, int
846 846
 	    if(info.exeinfo.section)
847 847
 		free(info.exeinfo.section);
848 848
 	    return ret;
849
+	} else if((data->offset[patt->offset_min] != CLI_OFF_NONE) && (data->offset[patt->offset_min] + patt->length > info.fsize)) {
850
+	    data->offset[patt->offset_min] = CLI_OFF_NONE;
849 851
 	}
850 852
     }
851
-    if(info.exeinfo.section)
853
+    if(fd != -1 && info.exeinfo.section)
852 854
 	free(info.exeinfo.section);
853 855
 
854 856
     return CL_SUCCESS;
... ...
@@ -928,7 +1032,7 @@ int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **v
928 928
     if(!root->ac_root)
929 929
 	return CL_CLEAN;
930 930
 
931
-    if(!mdata) {
931
+    if(!mdata && (root->ac_partsigs || root->ac_lsigs || root->ac_reloff_num)) {
932 932
 	cli_errmsg("cli_ac_scanbuff: mdata == NULL\n");
933 933
 	return CL_ENULLARG;
934 934
     }
... ...
@@ -946,39 +1050,37 @@ int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **v
946 946
 	    patt = current->list;
947 947
 	    while(patt) {
948 948
 		bp = i + 1 - patt->depth;
949
-		pt = patt;
950
-	 	/*
951
-		while(pt) {
952
-		    if((pt->type && !(mode & AC_SCAN_FT)) || (!pt->type && !(mode & AC_SCAN_VIR))) {
953
-			pt = pt->next_same;
954
-			continue;
955
-		    }
956
-		    if(pt->offset_min == CLI_OFF_NONE) {
957
-			pt = pt->next_same;
949
+		if(!patt->next_same && (patt->offset_min != CLI_OFF_ANY) && (!patt->sigid || patt->partno == 1)) {
950
+		    if(patt->offset_min == CLI_OFF_NONE) {
951
+			patt = patt->next;
958 952
 			continue;
959 953
 		    }
960
-		    realoff = offset + bp - pt->prefix_length;
961
-		    if(pt->offset_min != CLI_OFF_ANY && (!pt->sigid || pt->partno == 1)) {
962
-			if(pt->offset_max > realoff || pt->offset_min < realoff) {
963
-			    pt = pt->next_same;
954
+		    realoff = offset + bp - patt->prefix_length;
955
+		    if(patt->offdata[0] == CLI_OFF_ABSOLUTE) {
956
+			if(patt->offset_max < realoff || patt->offset_min > realoff) {
957
+			    patt = patt->next;
958
+			    continue;
959
+			}
960
+		    } else {
961
+			if(mdata->offset[patt->offset_min] == CLI_OFF_NONE || mdata->offset[patt->offset_max] < realoff || mdata->offset[patt->offset_min] > realoff) {
962
+			    patt = patt->next;
964 963
 			    continue;
965 964
 			}
966 965
 		    }
967
-		    break;
968 966
 		}
969
-		*/
970
-		if(pt && ac_findmatch(buffer, bp, length, patt, &matchend)) {
967
+		pt = patt;
968
+		if(ac_findmatch(buffer, bp, offset + bp - patt->prefix_length, length, patt, &matchend)) {
971 969
 		    while(pt) {
972 970
 			if((pt->type && !(mode & AC_SCAN_FT)) || (!pt->type && !(mode & AC_SCAN_VIR))) {
973 971
 			    pt = pt->next_same;
974 972
 			    continue;
975 973
 			}
976
-			if(pt->offset_min == CLI_OFF_NONE) {
977
-			    pt = pt->next_same;
978
-			    continue;
979
-			}
980 974
 			realoff = offset + bp - pt->prefix_length;
981 975
 			if(pt->offset_min != CLI_OFF_ANY && (!pt->sigid || pt->partno == 1)) {
976
+			    if(pt->offset_min == CLI_OFF_NONE) {
977
+				pt = pt->next_same;
978
+				continue;
979
+			    }
982 980
 			    if(pt->offdata[0] == CLI_OFF_ABSOLUTE) {
983 981
 				if(pt->offset_max < realoff || pt->offset_min > realoff) {
984 982
 				    pt = pt->next_same;
... ...
@@ -1069,7 +1171,7 @@ int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **v
1069 1069
 				} else { /* !pt->type */
1070 1070
 				    if(pt->lsigid[0]) {
1071 1071
 					mdata->lsigcnt[pt->lsigid[1]][pt->lsigid[2]]++;
1072
-					pt = pt->next;
1072
+					pt = pt->next_same;
1073 1073
 					continue;
1074 1074
 				    }
1075 1075
 
... ...
@@ -1082,7 +1184,7 @@ int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **v
1082 1082
 					newres->next = *res;
1083 1083
 					*res = newres;
1084 1084
 
1085
-					pt = pt->next;
1085
+					pt = pt->next_same;
1086 1086
 					continue;
1087 1087
 				    } else {
1088 1088
 					if(virname)
... ...
@@ -1111,7 +1213,7 @@ int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **v
1111 1111
 			    } else {
1112 1112
 				if(pt->lsigid[0]) {
1113 1113
 				    mdata->lsigcnt[pt->lsigid[1]][pt->lsigid[2]]++;
1114
-				    pt = pt->next;
1114
+				    pt = pt->next_same;
1115 1115
 				    continue;
1116 1116
 				}
1117 1117
 
... ...
@@ -1124,7 +1226,7 @@ int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **v
1124 1124
 				    newres->next = *res;
1125 1125
 				    *res = newres;
1126 1126
 
1127
-				    pt = pt->next;
1127
+				    pt = pt->next_same;
1128 1128
 				    continue;
1129 1129
 				} else {
1130 1130
 				    if(virname)
... ...
@@ -1146,6 +1248,11 @@ int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **v
1146 1146
     return (mode & AC_SCAN_FT) ? type : CL_CLEAN;
1147 1147
 }
1148 1148
 
1149
+static int qcompare(const void *a, const void *b)
1150
+{
1151
+    return *(unsigned char *)a - *(unsigned char *)b;
1152
+}
1153
+
1149 1154
 /* FIXME: clean up the code */
1150 1155
 int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hexsig, uint32_t sigid, uint16_t parts, uint16_t partno, uint16_t rtype, uint16_t type, uint32_t mindist, uint32_t maxdist, const char *offset, const uint32_t *lsigid, unsigned int options)
1151 1156
 {
... ...
@@ -1153,7 +1260,7 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex
1153 1153
 	char *pt, *pt2, *hex = NULL, *hexcpy = NULL;
1154 1154
 	uint16_t i, j, ppos = 0, pend, *dec, nzpos = 0;
1155 1155
 	uint8_t wprefix = 0, zprefix = 1, plen = 0, nzplen = 0;
1156
-	struct cli_ac_alt *newalt, *altpt, **newtable;
1156
+	struct cli_ac_special *newspecial, *specialpt, **newtable;
1157 1157
 	int ret, error = CL_SUCCESS;
1158 1158
 
1159 1159
 
... ...
@@ -1288,99 +1395,149 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex
1288 1288
 		error = CL_EMALFDB;
1289 1289
 		break;
1290 1290
 	    }
1291
-
1291
+	    newspecial = (struct cli_ac_special *) mpool_calloc(root->mempool, 1, sizeof(struct cli_ac_special));
1292
+	    if(!newspecial) {
1293
+		cli_errmsg("cli_ac_addsig: Can't allocate newspecial\n");
1294
+		error = CL_EMEM;
1295
+		break;
1296
+	    }
1297
+	    if(pt >= hexcpy + 2) {
1298
+		if(pt[-2] == '!') {
1299
+		    newspecial->negative = 1;
1300
+		    pt[-2] = 0;
1301
+		}
1302
+	    }
1292 1303
 	    strcat(hexnew, start);
1293
-	    strcat(hexnew, "()");
1294 1304
 
1295 1305
 	    if(!(start = strchr(pt, ')'))) {
1306
+		mpool_free(root->mempool, newspecial);
1296 1307
 		error = CL_EMALFDB;
1297 1308
 		break;
1298 1309
 	    }
1299 1310
 	    *start++ = 0;
1300
-
1301
-	    newalt = (struct cli_ac_alt *) mpool_calloc(root->mempool, 1, sizeof(struct cli_ac_alt));
1302
-	    if(!newalt) {
1303
-		cli_errmsg("cli_ac_addsig: Can't allocate newalt\n");
1304
-		error = CL_EMEM;
1311
+	    if(!strlen(pt)) {
1312
+		cli_errmsg("cli_ac_addsig: Empty block\n");
1313
+		error = CL_EMALFDB;
1305 1314
 		break;
1306 1315
 	    }
1307 1316
 
1308
-	    new->alt++;
1309
-
1310
-	    newtable = (struct cli_ac_alt **) mpool_realloc(root->mempool, new->alttable, new->alt * sizeof(struct cli_ac_alt *));
1317
+	    if(!strcmp(pt, "B")) {
1318
+		if(!*start) {
1319
+		    new->boundary |= AC_BOUNDARY_RIGHT;
1320
+		    if(newspecial->negative)
1321
+			new->boundary |= AC_BOUNDARY_RIGHT_NEGATIVE;
1322
+		    mpool_free(root->mempool, newspecial);
1323
+		    continue;
1324
+		} else if(pt - 1 == hexcpy) {
1325
+		    new->boundary |= AC_BOUNDARY_LEFT;
1326
+		    if(newspecial->negative)
1327
+			new->boundary |= AC_BOUNDARY_LEFT_NEGATIVE;
1328
+		    mpool_free(root->mempool, newspecial);
1329
+		    continue;
1330
+		}
1331
+	    } else if(!strcmp(pt, "L")) {
1332
+		if(!*start) {
1333
+		    new->boundary |= AC_LINE_MARKER_RIGHT;
1334
+		    if(newspecial->negative)
1335
+			new->boundary |= AC_LINE_MARKER_RIGHT_NEGATIVE;
1336
+		    mpool_free(root->mempool, newspecial);
1337
+		    continue;
1338
+		} else if(pt - 1 == hexcpy) {
1339
+		    new->boundary |= AC_LINE_MARKER_LEFT;
1340
+		    if(newspecial->negative)
1341
+			new->boundary |= AC_LINE_MARKER_LEFT_NEGATIVE;
1342
+		    mpool_free(root->mempool, newspecial);
1343
+		    continue;
1344
+		}
1345
+	    }
1346
+	    strcat(hexnew, "()");
1347
+	    new->special++;
1348
+	    newtable = (struct cli_ac_special **) mpool_realloc(root->mempool, new->special_table, new->special * sizeof(struct cli_ac_special *));
1311 1349
 	    if(!newtable) {
1312
-		new->alt--;
1313
-		mpool_free(root->mempool, newalt);
1314
-		cli_errmsg("cli_ac_addsig: Can't realloc new->alttable\n");
1350
+		new->special--;
1351
+		mpool_free(root->mempool, newspecial);
1352
+		cli_errmsg("cli_ac_addsig: Can't realloc new->special_table\n");
1315 1353
 		error = CL_EMEM;
1316 1354
 		break;
1317 1355
 	    }
1318
-	    newtable[new->alt - 1] = newalt;
1319
-	    new->alttable = newtable;
1320
-
1321
-	    for(i = 0; i < strlen(pt); i++)
1322
-		if(pt[i] == '|')
1323
-		    newalt->num++;
1324
-
1325
-            if(!newalt->num) {
1326
-                error = CL_EMALFDB;
1327
-                break;
1328
-            } else
1329
-                newalt->num++;
1330
-
1331
-	    if(3 * newalt->num - 1 == (uint16_t) strlen(pt)) {
1332
-		newalt->chmode = 1;
1333
-		newalt->str = (unsigned char *) mpool_malloc(root->mempool, newalt->num);
1334
-		if(!newalt->str) {
1335
-		    cli_errmsg("cli_ac_addsig: Can't allocate newalt->str\n");
1336
-		    error = CL_EMEM;
1337
-		    break;
1338
-		}
1339
-	    }
1356
+	    newtable[new->special - 1] = newspecial;
1357
+	    new->special_table = newtable;
1358
+
1359
+	    if(!strcmp(pt, "B")) {
1360
+		newspecial->type = AC_SPECIAL_BOUNDARY;
1361
+	    } else if(!strcmp(pt, "L")) {
1362
+		newspecial->type = AC_SPECIAL_LINE_MARKER;
1363
+	    /*
1364
+	    } else if(strcmp(pt, "W")) {
1365
+		newspecial->type = AC_SPECIAL_WHITE;
1366
+	    */
1367
+	    } else {
1368
+		for(i = 0; i < strlen(pt); i++)
1369
+		    if(pt[i] == '|')
1370
+			newspecial->num++;
1340 1371
 
1341
-	    for(i = 0; i < newalt->num; i++) {
1342
-		if(!(h = cli_strtok(pt, i, "|"))) {
1372
+		if(!newspecial->num) {
1343 1373
 		    error = CL_EMALFDB;
1344 1374
 		    break;
1375
+		} else
1376
+		    newspecial->num++;
1377
+
1378
+		if(3 * newspecial->num - 1 == (uint16_t) strlen(pt)) {
1379
+		    newspecial->type = AC_SPECIAL_ALT_CHAR;
1380
+		    newspecial->str = (unsigned char *) mpool_malloc(root->mempool, newspecial->num);
1381
+		    if(!newspecial->str) {
1382
+			cli_errmsg("cli_ac_addsig: Can't allocate newspecial->str\n");
1383
+			error = CL_EMEM;
1384
+			break;
1385
+		    }
1386
+		} else {
1387
+		    newspecial->type = AC_SPECIAL_ALT_STR;
1345 1388
 		}
1346 1389
 
1347
-		if(!(c = cli_mpool_hex2str(root->mempool, h))) {
1348
-		    free(h);
1349
-		    error = CL_EMALFDB;
1350
-		    break;
1351
-		}
1390
+		for(i = 0; i < newspecial->num; i++) {
1391
+		    if(!(h = cli_strtok(pt, i, "|"))) {
1392
+			error = CL_EMALFDB;
1393
+			break;
1394
+		    }
1352 1395
 
1353
-		if(newalt->chmode) {
1354
-		    newalt->str[i] = *c;
1355
-		    mpool_free(root->mempool, c);
1356
-		} else {
1357
-		    if(i) {
1358
-			altpt = newalt;
1359
-			while(altpt->next)
1360
-			    altpt = altpt->next;
1361
-
1362
-			altpt->next = (struct cli_ac_alt *) mpool_calloc(root->mempool, 1, sizeof(struct cli_ac_alt));
1363
-			if(!altpt->next) {
1364
-			    cli_errmsg("cli_ac_addsig: Can't allocate altpt->next\n");
1365
-			    error = CL_EMEM;
1366
-			    free(c);
1367
-			    free(h);
1368
-			    break;
1369
-			}
1396
+		    if(!(c = cli_mpool_hex2str(root->mempool, h))) {
1397
+			free(h);
1398
+			error = CL_EMALFDB;
1399
+			break;
1400
+		    }
1370 1401
 
1371
-			altpt->next->str = (unsigned char *) c;
1372
-			altpt->next->len = strlen(h) / 2;
1402
+		    if(newspecial->type == AC_SPECIAL_ALT_CHAR) {
1403
+			newspecial->str[i] = *c;
1404
+			mpool_free(root->mempool, c);
1373 1405
 		    } else {
1374
-			newalt->str = (unsigned char *) c;
1375
-			newalt->len = strlen(h) / 2;
1406
+			if(i) {
1407
+			    specialpt = newspecial;
1408
+			    while(specialpt->next)
1409
+				specialpt = specialpt->next;
1410
+
1411
+			    specialpt->next = (struct cli_ac_special *) mpool_calloc(root->mempool, 1, sizeof(struct cli_ac_special));
1412
+			    if(!specialpt->next) {
1413
+				cli_errmsg("cli_ac_addsig: Can't allocate specialpt->next\n");
1414
+				error = CL_EMEM;
1415
+				free(c);
1416
+				free(h);
1417
+				break;
1418
+			    }
1419
+			    specialpt->next->str = (unsigned char *) c;
1420
+			    specialpt->next->len = strlen(h) / 2;
1421
+			} else {
1422
+			    newspecial->str = (unsigned char *) c;
1423
+			    newspecial->len = strlen(h) / 2;
1424
+			}
1376 1425
 		    }
1426
+		    free(h);
1377 1427
 		}
1428
+		if(newspecial->type == AC_SPECIAL_ALT_CHAR)
1429
+		    cli_qsort(newspecial->str, newspecial->num, sizeof(unsigned char), qcompare);
1378 1430
 
1379
-		free(h);
1431
+		if(error)
1432
+		    break;
1380 1433
 	    }
1381
-
1382
-	    if(error)
1383
-		break;
1384 1434
 	}
1385 1435
 
1386 1436
 	if(start)
... ...
@@ -1390,9 +1547,9 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex
1390 1390
 	free(hexcpy);
1391 1391
 
1392 1392
 	if(error) {
1393
-	    if(new->alt) {
1393
+	    if(new->special) {
1394 1394
 		free(hex);
1395
-		mpool_ac_free_alt(root->mempool, new);
1395
+		mpool_ac_free_special(root->mempool, new);
1396 1396
 	    }
1397 1397
 	    mpool_free(root->mempool, new);
1398 1398
 	    return error;
... ...
@@ -1401,8 +1558,8 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex
1401 1401
 
1402 1402
     new->pattern = cli_mpool_hex2ui(root->mempool, hex ? hex : hexsig);
1403 1403
     if(new->pattern == NULL) {
1404
-	if(new->alt)
1405
-	    mpool_ac_free_alt(root->mempool, new);
1404
+	if(new->special)
1405
+	    mpool_ac_free_special(root->mempool, new);
1406 1406
 	mpool_free(root->mempool, new);
1407 1407
 	free(hex);
1408 1408
 	return CL_EMALFDB;
... ...
@@ -1451,7 +1608,7 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex
1451 1451
 
1452 1452
 	if(plen < root->ac_mindepth) {
1453 1453
 	    cli_errmsg("cli_ac_addsig: Can't find a static subpattern of length %u\n", root->ac_mindepth);
1454
-	    mpool_ac_free_alt(root->mempool, new);
1454
+	    mpool_ac_free_special(root->mempool, new);
1455 1455
 	    mpool_free(root->mempool, new->pattern);
1456 1456
 	    mpool_free(root->mempool, new);
1457 1457
 	    return CL_EMALFDB;
... ...
@@ -1463,8 +1620,8 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex
1463 1463
 	new->length -= ppos;
1464 1464
 
1465 1465
 	for(i = 0; i < new->prefix_length; i++)
1466
-	    if((new->prefix[i] & CLI_MATCH_WILDCARD) == CLI_MATCH_ALTERNATIVE)
1467
-		new->alt_pattern++;
1466
+	    if((new->prefix[i] & CLI_MATCH_WILDCARD) == CLI_MATCH_SPECIAL)
1467
+		new->special_pattern++;
1468 1468
     }
1469 1469
 
1470 1470
     if(new->length > root->maxpatlen)
... ...
@@ -1473,7 +1630,7 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex
1473 1473
     new->virname = cli_mpool_virname(root->mempool, (char *) virname, options & CL_DB_OFFICIAL);
1474 1474
     if(!new->virname) {
1475 1475
 	mpool_free(root->mempool, new->prefix ? new->prefix : new->pattern);
1476
-	mpool_ac_free_alt(root->mempool, new);
1476
+	mpool_ac_free_special(root->mempool, new);
1477 1477
 	mpool_free(root->mempool, new);
1478 1478
 	return CL_EMEM;
1479 1479
     }
... ...
@@ -1484,7 +1641,7 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex
1484 1484
     ret = cli_caloff(offset, NULL, -1, root->type, new->offdata, &new->offset_min, &new->offset_max);
1485 1485
     if(ret != CL_SUCCESS) {
1486 1486
 	mpool_free(root->mempool, new->prefix ? new->prefix : new->pattern);
1487
-	mpool_ac_free_alt(root->mempool, new);
1487
+	mpool_ac_free_special(root->mempool, new);
1488 1488
 	mpool_free(root->mempool, new->virname);
1489 1489
 	mpool_free(root->mempool, new);
1490 1490
 	return ret;
... ...
@@ -1493,7 +1650,7 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex
1493 1493
     if((ret = cli_ac_addpatt(root, new))) {
1494 1494
 	mpool_free(root->mempool, new->prefix ? new->prefix : new->pattern);
1495 1495
 	mpool_free(root->mempool, new->virname);
1496
-	mpool_ac_free_alt(root->mempool, new);
1496
+	mpool_ac_free_special(root->mempool, new);
1497 1497
 	mpool_free(root->mempool, new);
1498 1498
 	return ret;
1499 1499
     }
... ...
@@ -38,11 +38,11 @@ struct cli_ac_data {
38 38
     uint32_t *offset;
39 39
 };
40 40
 
41
-struct cli_ac_alt {
41
+struct cli_ac_special {
42 42
     unsigned char *str;
43
-    struct cli_ac_alt *next;
43
+    struct cli_ac_special *next;
44 44
     uint16_t len, num;
45
-    uint8_t chmode;
45
+    uint8_t type, negative;
46 46
 };
47 47
 
48 48
 struct cli_ac_patt {
... ...
@@ -55,12 +55,13 @@ struct cli_ac_patt {
55 55
     void *customdata;
56 56
     uint16_t ch_mindist[2];
57 57
     uint16_t ch_maxdist[2];
58
-    uint16_t parts, partno, alt, alt_pattern;
59
-    struct cli_ac_alt **alttable;
58
+    uint16_t parts, partno, special, special_pattern;
59
+    struct cli_ac_special **special_table;
60 60
     struct cli_ac_patt *next, *next_same;
61 61
     uint8_t depth;
62 62
     uint16_t rtype, type;
63 63
     uint32_t offdata[4], offset_min, offset_max;
64
+    uint32_t boundary;
64 65
 };
65 66
 
66 67
 struct cli_ac_node {
... ...
@@ -104,6 +104,17 @@ int cli_bm_addpatt(struct cli_matcher *root, struct cli_bm_patt *pattern, const
104 104
     pattern->pattern0 = pattern->pattern[0];
105 105
     root->bm_suffix[idx]->cnt++;
106 106
 
107
+    if(root->bm_offmode) {
108
+	root->bm_pattab = (struct cli_bm_patt **) mpool_realloc2(root->mempool, root->bm_pattab, (root->bm_patterns + 1) * sizeof(struct cli_bm_patt *));
109
+	if(!root->bm_pattab) {
110
+	    cli_errmsg("cli_bm_addpatt: Can't allocate memory for root->bm_pattab\n");
111
+	    return CL_EMEM;
112
+	}
113
+	root->bm_pattab[root->bm_patterns] = pattern;
114
+	if(pattern->offdata[0] != CLI_OFF_ABSOLUTE)
115
+	    pattern->offset_min = root->bm_patterns;
116
+    }
117
+
107 118
     root->bm_patterns++;
108 119
     return CL_SUCCESS;
109 120
 }
... ...
@@ -114,6 +125,7 @@ int cli_bm_init(struct cli_matcher *root)
114 114
 #ifdef USE_MPOOL
115 115
     assert (root->mempool && "mempool must be initialized");
116 116
 #endif
117
+
117 118
     if(!(root->bm_shift = (uint8_t *) mpool_calloc(root->mempool, size, sizeof(uint8_t))))
118 119
 	return CL_EMEM;
119 120
 
... ...
@@ -128,6 +140,80 @@ int cli_bm_init(struct cli_matcher *root)
128 128
     return CL_SUCCESS;
129 129
 }
130 130
 
131
+static int qcompare(const void *a, const void *b)
132
+{
133
+    return *(const uint32_t *)a - *(const uint32_t *)b;
134
+}
135
+
136
+int cli_bm_initoff(const struct cli_matcher *root, struct cli_bm_off *data, int fd)
137
+{
138
+	int ret;
139
+	unsigned int i;
140
+	struct cli_bm_patt *patt;
141
+	struct cli_target_info info;
142
+	struct stat sb;
143
+
144
+
145
+    if(!root->bm_patterns) {
146
+	data->offtab = data->offset = NULL;
147
+	data->cnt = data->pos = 0;
148
+	return CL_SUCCESS;
149
+    }
150
+    memset(&info, 0, sizeof(info));
151
+    if(fstat(fd, &sb) == -1) {
152
+	cli_errmsg("cli_bm_initoff: fstat(%d) failed\n", fd);
153
+	return CL_ESTAT;
154
+    }
155
+    info.fsize = sb.st_size;
156
+
157
+    data->cnt = data->pos = 0;
158
+    data->offtab = (uint32_t *) mpool_malloc(root->mempool, root->bm_patterns * sizeof(uint32_t));
159
+    if(!data->offtab) {
160
+	cli_errmsg("cli_bm_initoff: Can't allocate memory for data->offtab\n");
161
+	return CL_EMEM;
162
+    }
163
+    data->offset = (uint32_t *) mpool_malloc(root->mempool, root->bm_patterns * sizeof(uint32_t));
164
+    if(!data->offset) {
165
+	cli_errmsg("cli_bm_initoff: Can't allocate memory for data->offset\n");
166
+	mpool_free(root->mempool, data->offtab);
167
+	return CL_EMEM;
168
+    }
169
+    for(i = 0; i < root->bm_patterns; i++) {
170
+	patt = root->bm_pattab[i];
171
+	if(patt->offdata[0] == CLI_OFF_ABSOLUTE) {
172
+	    data->offtab[data->cnt] = patt->offset_min + patt->prefix_length;
173
+	    data->cnt++;
174
+	} else if((ret = cli_caloff(NULL, &info, fd, root->type, patt->offdata, &data->offset[patt->offset_min], NULL))) {
175
+	    cli_errmsg("cli_bm_initoff: Can't calculate relative offset in signature for %s\n", patt->virname);
176
+	    if(info.exeinfo.section)
177
+		free(info.exeinfo.section);
178
+	    mpool_free(root->mempool, data->offtab);
179
+	    mpool_free(root->mempool, data->offset);
180
+	    return ret;
181
+	} else if((data->offset[patt->offset_min] != CLI_OFF_NONE) && (data->offset[patt->offset_min] + patt->length <= info.fsize)) {
182
+	    if(!data->cnt || (data->offset[patt->offset_min] != data->offtab[data->cnt - 1])) {
183
+		data->offtab[data->cnt] = data->offset[patt->offset_min] + patt->prefix_length;
184
+		data->cnt++;
185
+	    }
186
+	}
187
+    }
188
+    if(info.exeinfo.section)
189
+	free(info.exeinfo.section);
190
+
191
+    cli_qsort(data->offtab, data->cnt, sizeof(uint32_t), qcompare);
192
+    return CL_SUCCESS;
193
+}
194
+
195
+void cli_bm_freeoff(struct cli_bm_off *data, const struct cli_matcher *root)
196
+{
197
+    if(data->offset) {
198
+	mpool_free(root->mempool, data->offset);
199
+	data->offset = NULL;
200
+	mpool_free(root->mempool, data->offtab);
201
+	data->offtab = NULL;
202
+    }
203
+}
204
+
131 205
 void cli_bm_free(struct cli_matcher *root)
132 206
 {
133 207
 	struct cli_bm_patt *patt, *prev;
... ...
@@ -137,6 +223,9 @@ void cli_bm_free(struct cli_matcher *root)
137 137
     if(root->bm_shift)
138 138
 	mpool_free(root->mempool, root->bm_shift);
139 139
 
140
+    if(root->bm_pattab)
141
+	mpool_free(root->mempool, root->bm_pattab);
142
+
140 143
     if(root->bm_suffix) {
141 144
 	for(i = 0; i < size; i++) {
142 145
 	    patt = root->bm_suffix[i];
... ...
@@ -156,7 +245,7 @@ void cli_bm_free(struct cli_matcher *root)
156 156
     }
157 157
 }
158 158
 
159
-int cli_bm_scanbuff(const unsigned char *buffer, uint32_t length, const char **virname, const struct cli_matcher *root, uint32_t offset, int fd)
159
+int cli_bm_scanbuff(const unsigned char *buffer, uint32_t length, const char **virname, const struct cli_matcher *root, uint32_t offset, int fd, struct cli_bm_off *offdata)
160 160
 {
161 161
 	uint32_t i, j, off, off_min, off_max;
162 162
 	uint8_t found, pchain, shift;
... ...
@@ -174,7 +263,13 @@ int cli_bm_scanbuff(const unsigned char *buffer, uint32_t length, const char **v
174 174
 	return CL_CLEAN;
175 175
 
176 176
     memset(&info, 0, sizeof(info));
177
-    for(i = BM_MIN_LENGTH - BM_BLOCK_SIZE; i < length - BM_BLOCK_SIZE + 1; ) {
177
+    i = BM_MIN_LENGTH - BM_BLOCK_SIZE;
178
+    if(offdata) {
179
+	if(offdata->pos == offdata->cnt)
180
+	    return CL_CLEAN;
181
+	i += offdata->offtab[offdata->pos] - offset;
182
+    }
183
+    for(; i < length - BM_BLOCK_SIZE + 1; ) {
178 184
 	idx = HASH(buffer[i], buffer[i + 1], buffer[i + 2]);
179 185
 	shift = root->bm_shift[idx];
180 186
 
... ...
@@ -182,7 +277,15 @@ int cli_bm_scanbuff(const unsigned char *buffer, uint32_t length, const char **v
182 182
 	    prefix = buffer[i - BM_MIN_LENGTH + BM_BLOCK_SIZE];
183 183
 	    p = root->bm_suffix[idx];
184 184
 	    if(p && p->cnt == 1 && p->pattern0 != prefix) {
185
-		i++;
185
+		if(offdata) {
186
+		    off = offset + i - BM_MIN_LENGTH + BM_BLOCK_SIZE;
187
+		    for(; offdata->pos < offdata->cnt && off >= offdata->offtab[offdata->pos]; offdata->pos++);
188
+		    if(offdata->pos == offdata->cnt || off >= offdata->offtab[offdata->pos])
189
+			return CL_CLEAN;
190
+		    i += offdata->offtab[offdata->pos] - off;
191
+		} else {
192
+		    i++;
193
+		}
186 194
 		continue;
187 195
 	    }
188 196
 	    pchain = 0;
... ...
@@ -202,6 +305,18 @@ int cli_bm_scanbuff(const unsigned char *buffer, uint32_t length, const char **v
202 202
 		    continue;
203 203
 		}
204 204
 
205
+		if(offdata) {
206
+		    if(p->offdata[0] == CLI_OFF_ABSOLUTE) {
207
+			if(p->offset_min != offset + off - p->prefix_length) {
208
+			    p = p->next;
209
+			    continue;
210
+			}
211
+		    } else if((offdata->offset[p->offset_min] == CLI_OFF_NONE) || (offdata->offset[p->offset_min] != offset + off - p->prefix_length)) {
212
+			p = p->next;
213
+			continue;
214
+		    }
215
+		}
216
+
205 217
 		idxchk = MIN(p->length, length - off) - 1;
206 218
 		if(idxchk) {
207 219
 		    if((bp[idxchk] != p->pattern[idxchk]) ||  (bp[idxchk / 2] != p->pattern[idxchk / 2])) {
... ...
@@ -226,8 +341,15 @@ int cli_bm_scanbuff(const unsigned char *buffer, uint32_t length, const char **v
226 226
 		    }
227 227
 		}
228 228
 
229
+		if(found && (p->boundary & BM_BOUNDARY_EOL)) {
230
+		    if(off != length) {
231
+			p = p->next;
232
+			continue;
233
+		    }
234
+		}
235
+
229 236
 		if(found && p->length + p->prefix_length == j) {
230
-		    if(p->offset_min != CLI_OFF_ANY) {
237
+		    if(!offdata && (p->offset_min != CLI_OFF_ANY)) {
231 238
 			if(p->offdata[0] != CLI_OFF_ABSOLUTE) {
232 239
 			    ret = cli_caloff(NULL, &info, fd, root->type, p->offdata, &off_min, &off_max);
233 240
 			    if(ret != CL_SUCCESS) {
... ...
@@ -252,14 +374,21 @@ int cli_bm_scanbuff(const unsigned char *buffer, uint32_t length, const char **v
252 252
 			free(info.exeinfo.section);
253 253
 		    return CL_VIRUS;
254 254
 		}
255
-
256 255
 		p = p->next;
257 256
 	    }
258
-
259 257
 	    shift = 1;
260 258
 	}
261 259
 
262
-	i += shift;
260
+	if(offdata) {
261
+	    off = offset + i - BM_MIN_LENGTH + BM_BLOCK_SIZE;
262
+	    for(; offdata->pos < offdata->cnt && off >= offdata->offtab[offdata->pos]; offdata->pos++);
263
+	    if(offdata->pos == offdata->cnt || off >= offdata->offtab[offdata->pos])
264
+		return CL_CLEAN;
265
+	    i += offdata->offtab[offdata->pos] - off;
266
+	} else {
267
+	    i += shift;
268
+	}
269
+
263 270
     }
264 271
 
265 272
     if(info.exeinfo.section)
... ...
@@ -25,6 +25,8 @@
25 25
 #include "filetypes.h"
26 26
 #include "cltypes.h"
27 27
 
28
+#define BM_BOUNDARY_EOL	1
29
+
28 30
 struct cli_bm_patt {
29 31
     unsigned char *pattern, *prefix;
30 32
     char *virname;
... ...
@@ -33,11 +35,18 @@ struct cli_bm_patt {
33 33
     uint16_t length, prefix_length;
34 34
     uint16_t cnt;
35 35
     unsigned char pattern0;
36
+    uint32_t boundary;
37
+};
38
+
39
+struct cli_bm_off {
40
+    uint32_t *offset, *offtab, cnt, pos;
36 41
 };
37 42
 
38 43
 int cli_bm_addpatt(struct cli_matcher *root, struct cli_bm_patt *pattern, const char *offset);
39 44
 int cli_bm_init(struct cli_matcher *root);
40
-int cli_bm_scanbuff(const unsigned char *buffer, uint32_t length, const char **virname, const struct cli_matcher *root, uint32_t offset, int fd);
45
+int cli_bm_initoff(const struct cli_matcher *root, struct cli_bm_off *data, int fd);
46
+void cli_bm_freeoff(struct cli_bm_off *data, const struct cli_matcher *root);
47
+int cli_bm_scanbuff(const unsigned char *buffer, uint32_t length, const char **virname, const struct cli_matcher *root, uint32_t offset, int fd, struct cli_bm_off *offdata);
41 48
 void cli_bm_free(struct cli_matcher *root);
42 49
 
43 50
 #endif
... ...
@@ -76,7 +76,7 @@ int cli_scanbuff(const unsigned char *buffer, uint32_t length, uint32_t offset,
76 76
 	if(!acdata && (ret = cli_ac_initdata(&mdata, troot->ac_partsigs, troot->ac_lsigs, troot->ac_reloff_num, CLI_DEFAULT_AC_TRACKLEN)))
77 77
 	    return ret;
78 78
 
79
-	if(troot->ac_only || (ret = cli_bm_scanbuff(buffer, length, virname, troot, offset, -1)) != CL_VIRUS)
79
+	if(troot->ac_only || (ret = cli_bm_scanbuff(buffer, length, virname, troot, offset, -1, NULL)) != CL_VIRUS)
80 80
 	    ret = cli_ac_scanbuff(buffer, length, virname, NULL, NULL, troot, acdata ? (acdata[0]) : (&mdata), offset, ftype, NULL, AC_SCAN_VIR, NULL);
81 81
 
82 82
 	if(!acdata)
... ...
@@ -89,7 +89,7 @@ int cli_scanbuff(const unsigned char *buffer, uint32_t length, uint32_t offset,
89 89
     if(!acdata && (ret = cli_ac_initdata(&mdata, groot->ac_partsigs, groot->ac_lsigs, groot->ac_reloff_num, CLI_DEFAULT_AC_TRACKLEN)))
90 90
 	return ret;
91 91
 
92
-    if(groot->ac_only || (ret = cli_bm_scanbuff(buffer, length, virname, groot, offset, -1)) != CL_VIRUS)
92
+    if(groot->ac_only || (ret = cli_bm_scanbuff(buffer, length, virname, groot, offset, -1, NULL)) != CL_VIRUS)
93 93
 	ret = cli_ac_scanbuff(buffer, length, virname, NULL, NULL, groot, acdata ? (acdata[1]) : (&mdata), offset, ftype, NULL, AC_SCAN_VIR, NULL);
94 94
 
95 95
     if(!acdata)
... ...
@@ -201,7 +201,9 @@ int cli_caloff(const char *offstr, struct cli_target_info *info, int fd, unsigne
201 201
     } else {
202 202
 	/* calculate relative offsets */
203 203
 	if(info->status == -1) {
204
-	    *offset_min = *offset_max = 0;
204
+	    *offset_min = CLI_OFF_NONE;
205
+	    if(offset_max)
206
+		*offset_max = CLI_OFF_NONE;
205 207
 	    return CL_SUCCESS;
206 208
 	}
207 209
 
... ...
@@ -237,7 +239,9 @@ int cli_caloff(const char *offstr, struct cli_target_info *info, int fd, unsigne
237 237
 		/* einfo *may* fail */
238 238
 		lseek(fd, pos, SEEK_SET);
239 239
 		info->status = -1;
240
-		*offset_min = *offset_max = 0;
240
+		*offset_min = CLI_OFF_NONE;
241
+		if(offset_max)
242
+		    *offset_max = CLI_OFF_NONE;
241 243
 		return CL_SUCCESS;
242 244
 	    }
243 245
 	    lseek(fd, pos, SEEK_SET);
... ...
@@ -263,7 +267,7 @@ int cli_caloff(const char *offstr, struct cli_target_info *info, int fd, unsigne
263 263
 
264 264
 	    case CLI_OFF_SX_PLUS:
265 265
 		if(offdata[3] >= info->exeinfo.nsections)
266
-		    *offset_min = 0;
266
+		    *offset_min = CLI_OFF_NONE;
267 267
 		else
268 268
 		    *offset_min = info->exeinfo.section[offdata[3]].raw + offdata[1];
269 269
 		break;
... ...
@@ -273,9 +277,7 @@ int cli_caloff(const char *offstr, struct cli_target_info *info, int fd, unsigne
273 273
 		return CL_EARG;
274 274
 	}
275 275
 
276
-	if(!*offset_min)
277
-	    *offset_max = 0;
278
-	else
276
+	if(offset_max && *offset_min != CLI_OFF_NONE)
279 277
 	    *offset_max = *offset_min + offdata[2];
280 278
     }
281 279
 
... ...
@@ -303,7 +305,7 @@ int cli_checkfp(int fd, cli_ctx *ctx)
303 303
 	    return 0;
304 304
 	}
305 305
 
306
-	if(cli_bm_scanbuff(digest, 16, &virname, ctx->engine->md5_fp, 0, -1) == CL_VIRUS) {
306
+	if(cli_bm_scanbuff(digest, 16, &virname, ctx->engine->md5_fp, 0, -1, NULL) == CL_VIRUS) {
307 307
 	    cli_dbgmsg("cli_checkfp(): Found false positive detection (fp sig: %s)\n", virname);
308 308
 	    free(digest);
309 309
 	    lseek(fd, pos, SEEK_SET);
... ...
@@ -320,13 +322,15 @@ int cli_scandesc(int desc, cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struc
320 320
 {
321 321
         unsigned char *buffer, *buff, *endbl, *upt;
322 322
 	int ret = CL_CLEAN, type = CL_CLEAN, bytes;
323
-	unsigned int i, evalcnt;
323
+	unsigned int i, evalcnt, bm_offmode = 0;
324 324
 	uint32_t buffersize, length, maxpatlen, shift = 0, offset = 0;
325 325
 	uint64_t evalids;
326 326
 	struct cli_ac_data gdata, tdata;
327
+	struct cli_bm_off toff;
327 328
 	cli_md5_ctx md5ctx;
328 329
 	unsigned char digest[16];
329 330
 	struct cli_matcher *groot = NULL, *troot = NULL;
331
+	struct stat sb;
330 332
 
331 333
 
332 334
     if(!ctx->engine) {
... ...
@@ -375,6 +379,19 @@ int cli_scandesc(int desc, cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struc
375 375
 		cli_ac_freedata(&gdata);
376 376
 	    return ret;
377 377
 	}
378
+	if(troot->bm_offmode) {
379
+	    if(fstat(desc, &sb) != -1) {
380
+		if(sb.st_size >= CLI_DEFAULT_BM_OFFMODE_FSIZE) {
381
+		    if((ret = cli_bm_initoff(troot, &toff, desc))) {
382
+			if(!ftonly)
383
+			    cli_ac_freedata(&gdata);
384
+			cli_ac_freedata(&tdata);
385
+			return ret;
386
+		    }
387
+		    bm_offmode = 1;
388
+		}
389
+	    }
390
+	}
378 391
     }
379 392
 
380 393
     if(!ftonly && ctx->engine->md5_hdb)
... ...
@@ -397,7 +414,7 @@ int cli_scandesc(int desc, cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struc
397 397
 	    length += maxpatlen;
398 398
 
399 399
 	if(troot) {
400
-	    if(troot->ac_only || (ret = cli_bm_scanbuff(upt, length, ctx->virname, troot, offset, desc)) != CL_VIRUS)
400
+	    if(troot->ac_only || (ret = cli_bm_scanbuff(upt, length, ctx->virname, troot, offset, desc, bm_offmode ? &toff : NULL)) != CL_VIRUS)
401 401
 		ret = cli_ac_scanbuff(upt, length, ctx->virname, NULL, NULL, troot, &tdata, offset, ftype, ftoffset, acmode, NULL);
402 402
 
403 403
 	    if(ret == CL_VIRUS) {
... ...
@@ -405,6 +422,8 @@ int cli_scandesc(int desc, cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struc
405 405
 		if(!ftonly)
406 406
 		    cli_ac_freedata(&gdata);
407 407
 		cli_ac_freedata(&tdata);
408
+		if(bm_offmode)
409
+		    cli_bm_freeoff(&toff, troot);
408 410
 
409 411
 		if(cli_checkfp(desc, ctx))
410 412
 		    return CL_CLEAN;
... ...
@@ -414,14 +433,17 @@ int cli_scandesc(int desc, cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struc
414 414
 	}
415 415
 
416 416
 	if(!ftonly) {
417
-	    if(groot->ac_only || (ret = cli_bm_scanbuff(upt, length, ctx->virname, groot, offset, desc)) != CL_VIRUS)
417
+	    if(groot->ac_only || (ret = cli_bm_scanbuff(upt, length, ctx->virname, groot, offset, desc, NULL)) != CL_VIRUS)
418 418
 		ret = cli_ac_scanbuff(upt, length, ctx->virname, NULL, NULL, groot, &gdata, offset, ftype, ftoffset, acmode, NULL);
419 419
 
420 420
 	    if(ret == CL_VIRUS) {
421 421
 		free(buffer);
422 422
 		cli_ac_freedata(&gdata);
423
-		if(troot)
423
+		if(troot) {
424 424
 		    cli_ac_freedata(&tdata);
425
+		    if(bm_offmode)
426
+			cli_bm_freeoff(&toff, troot);
427
+		}
425 428
 		if(cli_checkfp(desc, ctx))
426 429
 		    return CL_CLEAN;
427 430
 		else
... ...
@@ -472,6 +494,8 @@ int cli_scandesc(int desc, cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struc
472 472
 	    }
473 473
 	}
474 474
 	cli_ac_freedata(&tdata);
475
+	if(bm_offmode)
476
+	    cli_bm_freeoff(&toff, troot);
475 477
     }
476 478
 
477 479
     if(groot) {
... ...
@@ -504,7 +528,7 @@ int cli_scandesc(int desc, cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struc
504 504
 
505 505
     if(!ftonly && ctx->engine->md5_hdb) {
506 506
 	cli_md5_final(digest, &md5ctx);
507
-	if(cli_bm_scanbuff(digest, 16, ctx->virname, ctx->engine->md5_hdb, 0, -1) == CL_VIRUS && (cli_bm_scanbuff(digest, 16, NULL, ctx->engine->md5_fp, 0, -1) != CL_VIRUS))
507
+	if(cli_bm_scanbuff(digest, 16, ctx->virname, ctx->engine->md5_hdb, 0, -1, NULL) == CL_VIRUS && (cli_bm_scanbuff(digest, 16, NULL, ctx->engine->md5_fp, 0, -1, NULL) != CL_VIRUS))
508 508
 	    return CL_VIRUS;
509 509
     }
510 510
 
... ...
@@ -39,7 +39,7 @@
39 39
 #define CLI_MATCH_WILDCARD	0xff00
40 40
 #define CLI_MATCH_CHAR		0x0000
41 41
 #define CLI_MATCH_IGNORE	0x0100
42
-#define CLI_MATCH_ALTERNATIVE	0x0200
42
+#define CLI_MATCH_SPECIAL	0x0200
43 43
 #define CLI_MATCH_NIBBLE_HIGH	0x0300
44 44
 #define CLI_MATCH_NIBBLE_LOW	0x0400
45 45
 
... ...
@@ -75,10 +75,10 @@ struct cli_matcher {
75 75
 
76 76
     /* Extended Boyer-Moore */
77 77
     uint8_t *bm_shift;
78
-    struct cli_bm_patt **bm_suffix;
78
+    struct cli_bm_patt **bm_suffix, **bm_pattab;
79 79
     struct cli_hashset md5_sizes_hs;
80 80
     uint32_t *soff, soff_len; /* for PE section sigs */
81
-    uint32_t bm_patterns, bm_reloff_num, bm_absoff_num;
81
+    uint32_t bm_offmode, bm_patterns, bm_reloff_num, bm_absoff_num;
82 82
 
83 83
     /* Extended Aho-Corasick */
84 84
     uint32_t ac_partsigs, ac_nodes, ac_patterns, ac_lsigs;
... ...
@@ -20,10 +20,6 @@
20 20
 
21 21
 static	char	const	rcsid[] = "$Id: mbox.c,v 1.381 2007/02/15 12:26:44 njh Exp $";
22 22
 
23
-#ifdef	_MSC_VER
24
-#include <winsock.h>	/* only needed in CL_EXPERIMENTAL */
25
-#endif
26
-
27 23
 #if HAVE_CONFIG_H
28 24
 #include "clamav-config.h"
29 25
 #endif
... ...
@@ -54,9 +50,7 @@ static	char	const	rcsid[] = "$Id: mbox.c,v 1.381 2007/02/15 12:26:44 njh Exp $";
54 54
 #include <sys/param.h>
55 55
 #endif
56 56
 #include "clamav.h"
57
-#ifndef	C_WINDOWS
58 57
 #include <dirent.h>
59
-#endif
60 58
 #include <limits.h>
61 59
 #include <signal.h>
62 60
 
... ...
@@ -141,7 +135,8 @@ typedef	enum {
141 141
 
142 142
 #include "phishcheck.h"
143 143
 
144
-#ifndef	C_WINDOWS
144
+#ifndef	_WIN32
145
+#include <sys/time.h>
145 146
 #include <netdb.h>
146 147
 #include <sys/socket.h>
147 148
 #include <netinet/in.h>
... ...
@@ -151,33 +146,7 @@ typedef	enum {
151 151
 #endif
152 152
 #endif
153 153
 
154
-#ifndef	C_WINDOWS
155
-#define	closesocket(s)	close(s)
156
-#define	SOCKET	int
157
-#endif
158
-
159 154
 #include <fcntl.h>
160
-#ifndef	C_WINDOWS
161
-#include <sys/time.h>
162
-#endif
163
-
164
-#ifndef HAVE_IN_PORT_T
165
-typedef	unsigned	short	in_port_t;
166
-#endif
167
-
168
-#ifndef HAVE_IN_ADDR_T
169
-typedef	unsigned	int	in_addr_t;
170
-#endif
171
-
172
-#if	(!defined(EALREADY)) && (defined(WSAEALREADY))
173
-#define EALREADY	WSAEALREADY
174
-#endif
175
-#if	(!defined(EINPROGRESS)) && (defined(WSAEINPROGRESS))
176
-#define EINPROGRESS	WSAEINPROGRESS
177
-#endif
178
-#if	(!defined(EISCONN)) && (defined(WSAEISCONN))
179
-#define EISCONN	WSAEISCONN
180
-#endif
181 155
 
182 156
 /*
183 157
  * Use CL_SCAN_PARTIAL_MESSAGE to handle messages covered by section 7.3.2 of RFC1341.
... ...
@@ -331,25 +300,9 @@ static	const	struct tableinit {
331 331
 static	pthread_mutex_t	tables_mutex = PTHREAD_MUTEX_INITIALIZER;
332 332
 #endif
333 333
 
334
-#ifndef	O_BINARY
335
-#define	O_BINARY	0
336
-#endif
337
-
338 334
 #ifdef	NEW_WORLD
339
-
340 335
 #include "matcher.h"
341
-
342 336
 #undef	PARTIAL_DIR
343
-
344
-#if HAVE_MMAP
345
-#if HAVE_SYS_MMAN_H
346
-#include <sys/mman.h>
347
-#else /* HAVE_SYS_MMAN_H */
348
-#undef HAVE_MMAP
349
-#endif
350
-#else	/*HAVE_MMAP*/
351
-#undef	NEW_WORLD
352
-#endif
353 337
 #endif
354 338
 
355 339
 #ifdef	NEW_WORLD
... ...
@@ -3686,24 +3639,9 @@ rfc1341(message *m, const char *dir)
3686 3686
 	if(id == NULL)
3687 3687
 		return -1;
3688 3688
 
3689
-/* do we need this for C_WINDOWS?
3690
-#ifdef  C_CYGWIN
3691
-	if((tmpdir = getenv("TEMP")) == (char *)NULL)
3692
-		if((tmpdir = getenv("TMP")) == (char *)NULL)
3693
-			if((tmpdir = getenv("TMPDIR")) == (char *)NULL)
3694
-				tmpdir = "C:\\";
3695
-#else
3696
-*/
3697
-	if((tmpdir = getenv("TMPDIR")) == (char *)NULL)
3698
-		if((tmpdir = getenv("TMP")) == (char *)NULL)
3699
-			if((tmpdir = getenv("TEMP")) == (char *)NULL)
3700
-#ifdef	P_tmpdir
3701
-				tmpdir = P_tmpdir;
3702
-#else
3703
-				tmpdir = "/tmp";
3704
-#endif
3689
+	tmpdir = cli_gettmpdir();
3705 3690
 
3706
-	snprintf(pdir, sizeof(pdir) - 1, "%s/clamav-partial", tmpdir);
3691
+	snprintf(pdir, sizeof(pdir) - 1, "%s"PATHSEP"clamav-partial", tmpdir);
3707 3692
 
3708 3693
 	if((mkdir(pdir, S_IRWXU) < 0) && (errno != EEXIST)) {
3709 3694
 		cli_errmsg("Can't create the directory '%s'\n", pdir);
... ...
@@ -3787,7 +3725,7 @@ rfc1341(message *m, const char *dir)
3787 3787
 
3788 3788
 			sanitiseName(id);
3789 3789
 
3790
-			snprintf(outname, sizeof(outname) - 1, "%s/%s", dir, id);
3790
+			snprintf(outname, sizeof(outname) - 1, "%s"PATHSEP"%s", dir, id);
3791 3791
 
3792 3792
 			cli_dbgmsg("outname: %s\n", outname);
3793 3793
 
... ...
@@ -3826,16 +3764,15 @@ rfc1341(message *m, const char *dir)
3826 3826
 					int nblanks;
3827 3827
 					struct stat statb;
3828 3828
 					const char *dentry_idpart;
3829
-#ifndef C_WINDOWS
3829
+
3830 3830
 					if(dent->d_ino == 0)
3831 3831
 						continue;
3832
-#endif
3833 3832
 
3834 3833
 					if(!strcmp(".",dent->d_name) ||
3835 3834
 							!strcmp("..", dent->d_name))
3836 3835
 						continue;
3837 3836
 					snprintf(fullname, sizeof(fullname) - 1,
3838
-						"%s/%s", pdir, dent->d_name);
3837
+						"%s"PATHSEP"%s", pdir, dent->d_name);
3839 3838
 					dentry_idpart = strchr(dent->d_name, '_');
3840 3839
 
3841 3840
 					if(!dentry_idpart ||
... ...
@@ -18,6 +18,9 @@
18 18
  *  MA 02110-1301, USA.
19 19
  */
20 20
 
21
+#ifndef __MBOX_H
22
+#define __MBOX_H
23
+
21 24
 /* See RFC1521 */
22 25
 typedef	enum {
23 26
 	NOMIME, APPLICATION, AUDIO, IMAGE, MESSAGE, MULTIPART, TEXT, VIDEO, MEXTENSION
... ...
@@ -48,3 +51,5 @@ typedef enum {
48 48
 
49 49
 size_t	strstrip(char *s);	/* remove trailing white space */
50 50
 int	cli_mbox(const char *dir, int desc, cli_ctx *ctx);
51
+
52
+#endif /* __MBOX_H */
... ...
@@ -1711,7 +1711,7 @@ int messageSavePartial(message *m, const char *dir, const char *md5id, unsigned
1711 1711
 
1712 1712
 	cli_dbgmsg("messageSavePartial\n");
1713 1713
 	time_val  = time(NULL);
1714
-	snprintf(fullname, 1024, "%s/clamav-partial-%lu_%s-%u", dir, time_val, md5id, part);
1714
+	snprintf(fullname, 1024, "%s"PATHSEP"clamav-partial-%lu_%s-%u", dir, time_val, md5id, part);
1715 1715
 
1716 1716
 	fb = messageExport(m, fullname,
1717 1717
 		(void *(*)(void))fileblobCreate,
... ...
@@ -35,7 +35,9 @@
35 35
 #if HAVE_STRING_H
36 36
 #include <string.h>
37 37
 #endif
38
+#if defined(HAVE_MMAP) && defined(HAVE_SYS_MMAN_H)
38 39
 #include <sys/mman.h>
40
+#endif
39 41
 #include <stddef.h>
40 42
 
41 43
 #include "others.h"
... ...
@@ -49,7 +51,8 @@
49 49
 #define FREEPOISON 0xde
50 50
 #endif
51 51
 
52
-/* #define DEBUGMPOOL /\* DO NOT define *\/ */
52
+/* #define DEBUGMPOOL */
53
+/* #define EXIT_ON_FLUSH */
53 54
 #ifdef DEBUGMPOOL
54 55
 #define spam(...) cli_warnmsg( __VA_ARGS__)
55 56
 #else
... ...
@@ -58,247 +61,127 @@ static inline void spam(const char *fmt, ...) { fmt = fmt; } /* gcc STFU */
58 58
 
59 59
 #include "mpool.h"
60 60
 
61
-/* #define MIN_FRAGSIZE 4096	/\* 1m2.282s *\/ */
62
-/* #define MIN_FRAGSIZE 8192	/\* 0m46.652s *\/ */
63
-/* #define MIN_FRAGSIZE 16384	/\* 0m8.365s *\/ */
64
-/* #define MIN_FRAGSIZE 32768	/\* 0m3.788s *\/ */
65
-/* #define MIN_FRAGSIZE 65536	/\* 0m2.759s *\/ */
66
-/* #define MIN_FRAGSIZE 131072	/\* 0m2.445s *\/ */
67
-#define MIN_FRAGSIZE 262144	/* 0m2.343s */
68
-/* #define MIN_FRAGSIZE 524288	/\* 0m2.387s *\/ */
69
-/* #define MIN_FRAGSIZE 1048576	/\* 0m2.392s *\/ */
70
-/* #define MIN_FRAGSIZE 2097152	/\* 0m2.402s *\/ */
71
-/* #define MIN_FRAGSIZE 99688128 */
61
+#define MIN_FRAGSIZE 262144
72 62
 
73 63
 #if SIZEOF_VOID_P==8
74 64
 static const unsigned int fragsz[] = {
75
-16, /* 34660 */
76
-24, /* 99132 */
77
-32, /* 935424 */
78
-40, /* 20825 */
79
-48, /* 7338 */
80
-56, /* 536414 */
81
-64, /* 2853 */
82
-72, /* 2355 */
83
-80, /* 3701 */
84
-88, /* 2665 */
85
-96, /* 3719 */
86
-104, /* 3739 */
87
-112, /* 4104 */
88
-120, /* 5151 */
89
-128, /* 25576 */
90
-136, /* 4340 */
91
-144, /* 4308 */
92
-152, /* 12219 */
93
-160, /* 18013 */
94
-168, /* 329 */
95
-176, /* 343 */
96
-184, /* 207 */
97
-192, /* 227 */
98
-200, /* 169 */
99
-208, /* 188 */
100
-216, /* 231 */
101
-224, /* 175 */
102
-232, /* 154 */
103
-240, /* 179 */
104
-248, /* 140 */
105
-256, /* 141 */
106
-264, /* 142 */
107
-272, /* 163 */
108
-280, /* 125 */
109
-288, /* 142 */
110
-296, /* 102 */
111
-304, /* 96 */
112
-312, /* 67 */
113
-320, /* 15 */
114
-328, /* 21 */
115
-336, /* 21 */
116
-344, /* 12 */
117
-352, /* 11 */
118
-360, /* 6 */
119
-368, /* 15 */
120
-376, /* 5 */
121
-384, /* 5 */
122
-392, /* 4 */
123
-400, /* 3 */
124
-408, /* 8 */
125
-416, /* 5 */
126
-424, /* 4 */
127
-432, /* 4 */
128
-440, /* 3 */
129
-456, /* 1 */
130
-464, /* 8 */
131
-472, /* 3 */
132
-488, /* 1 */
133
-496, /* 4 */
134
-504, /* 3 */
135
-512, /* 1 */
136
-520, /* 1 */
137
-528, /* 6 */
138
-536, /* 2 */
139
-544, /* 1 */
140
-560, /* 4 */
141
-576, /* 2 */
142
-592, /* 10 */
143
-616, /* 2 */
144
-624, /* 6 */
145
-656, /* 1 */
146
-680, /* 1 */
147
-704, /* 1 */
148
-720, /* 1 */
149
-776, /* 1 */
150
-2056, /* 8545 */
151
-63504, /* 9 */
152
-144760, /* 1 */
153
-507976, /* 9 */
154
-525800, /* 1 */
155
-1051032, /* (0) */
156
-2097152
157
-/* ^^ This shouldn't be reached but it's a good fall back
158
- * MAX_ALLOCATION is 184549376 but that's really not need here */
65
+/* SIZE        PERM    TEMP    ACT! */
66
+     16, /*    7631    7189 USE/POW2 */
67
+     24, /*   81785     114      USE */
68
+     32, /* 1099428      78 USE/POW2 */
69
+     40, /*   22466      69      USE */
70
+     48, /*    7438      37      USE */
71
+     56, /*    5567      32      USE */
72
+     64, /*    2801      31 USE/POW2 */
73
+     72, /*  610137      29      USE */
74
+     80, /*    3579      28      USE */
75
+     88, /*    2603      28      USE */
76
+     96, /*    3535      27      USE */
77
+    104, /*    3669      24      USE */
78
+    112, /*    3897      23      USE */
79
+    120, /*    5105      22      USE */
80
+    128, /*    3097      22 USE/POW2 */
81
+    136, /*    3977      21      USE */
82
+    144, /*   32225      21      USE */
83
+    152, /*   12384      20      USE */
84
+    160, /*   17258      20      USE */
85
+    176, /*     504      20      USE */
86
+    192, /*     324      20      USE */
87
+    216, /*     363      20      USE */
88
+    240, /*     478      19      USE */
89
+    256, /*     516      19 USE/POW2 */
90
+    288, /*     249      19      USE */
91
+    312, /*     741      18      USE */
92
+    336, /*      47      18      USE */
93
+    512, /*       1      18     POW2 */
94
+   1024, /*       0      17     POW2 */
95
+   2048, /*       0      16     POW2 */
96
+   2056, /*   11408      16      USE */
97
+   4096, /*       0      16     POW2 */
98
+   8192, /*       0      14     POW2 */
99
+   8736, /*       1      12      USE */
100
+  10240, /*       1      11      USE */
101
+  16384, /*       0       8     POW2 */
102
+  20536, /*       1       7      USE */
103
+  33704, /*       1       6      USE */
104
+  37312, /*       1       5      USE */
105
+  43800, /*       1       3      USE */
106
+  63504, /*       9       3      USE */
107
+  65536, /*       0       3     POW2 */
108
+  89800, /*       1       2      USE */
109
+ 102624, /*       1       1      USE */
110
+ 131072, /*       0       1     POW2 */
111
+ 147296, /*       1       1      USE */
112
+ 262144, /*       0       1     POW2 */
113
+ 369280, /*       1       0      USE */
114
+ 507976, /*       9       0      USE */
115
+ 525976, /*       1       0      USE */
116
+1048576, /*       0       0 USE/POW2 */
117
+ /* MAX_ALLOCATION is 184549376 but that's really not need here */
159 118
 };
160 119
 
161 120
 #else
162 121
 
163 122
 static const unsigned int fragsz[] = {
164
-8, /* 2268 */
165
-12, /* 32386 */
166
-16, /* 59865 */
167
-20, /* 58019 */
168
-24, /* 789268 */
169
-28, /* 127523 */
170
-32, /* 539890 */
171
-36, /* 11729 */
172
-40, /* 1840 */
173
-44, /* 5492 */
174
-48, /* 1662 */
175
-52, /* 3855 */
176
-56, /* 1781 */
177
-60, /* 990 */
178
-64, /* 984 */
179
-68, /* 1370 */
180
-72, /* 1923 */
181
-76, /* 1778 */
182
-80, /* 1076 */
183
-84, /* 1591 */
184
-88, /* 2084 */
185
-92, /* 23812 */
186
-96, /* 1873 */
187
-100, /* 1863 */
188
-104, /* 1923 */
189
-108, /* 2177 */
190
-112, /* 1724 */
191
-116, /* 3424 */
192
-120, /* 2098 */
193
-124, /* 1308 */
194
-128, /* 2291 */
195
-132, /* 2032 */
196
-136, /* 2825 */
197
-140, /* 1477 */
198
-144, /* 1594 */
199
-148, /* 10617 */
200
-152, /* 2696 */
201
-156, /* 15313 */
202
-160, /* 182 */
203
-164, /* 144 */
204
-168, /* 197 */
205
-172, /* 144 */
206
-176, /* 118 */
207
-180, /* 85 */
208
-184, /* 121 */
209
-188, /* 105 */
210
-192, /* 84 */
211
-196, /* 85 */
212
-200, /* 97 */
213
-204, /* 90 */
214
-208, /* 149 */
215
-212, /* 83 */
216
-216, /* 75 */
217
-220, /* 98 */
218
-224, /* 83 */
219
-228, /* 73 */
220
-232, /* 114 */
221
-236, /* 63 */
222
-240, /* 75 */
223
-244, /* 65 */
224
-248, /* 72 */
225
-252, /* 67 */
226
-256, /* 69 */
227
-260, /* 73 */
228
-264, /* 93 */
229
-268, /* 69 */
230
-272, /* 56 */
231
-276, /* 68 */
232
-280, /* 71 */
233
-284, /* 72 */
234
-288, /* 61 */
235
-292, /* 41 */
236
-296, /* 53 */
237
-300, /* 42 */
238
-304, /* 37 */
239
-308, /* 30 */
240
-312, /* 9 */
241
-316, /* 5 */
242
-320, /* 6 */
243
-324, /* 13 */
244
-328, /* 13 */
245
-332, /* 8 */
246
-336, /* 5 */
247
-340, /* 5 */
248
-344, /* 3 */
249
-348, /* 7 */
250
-352, /* 1 */
251
-356, /* 4 */
252
-360, /* 14 */
253
-364, /* 2 */
254
-368, /* 3 */
255
-372, /* 2 */
256
-376, /* 4 */
257
-388, /* 4 */
258
-392, /* 3 */
259
-400, /* 3 */
260
-404, /* 3 */
261
-408, /* 3 */
262
-412, /* 2 */
263
-416, /* 3 */
264
-420, /* 1 */
265
-428, /* 4 */
266
-432, /* 1 */
267
-436, /* 2 */
268
-452, /* 2 */
269
-456, /* 8 */
270
-464, /* 1 */
271
-468, /* 2 */
272
-480, /* 1 */
273
-488, /* 4 */
274
-496, /* 1 */
275
-500, /* 1 */
276
-504, /* 1 */
277
-512, /* 1 */
278
-520, /* 6 */
279
-532, /* 1 */
280
-536, /* 1 */
281
-552, /* 4 */
282
-572, /* 3 */
283
-584, /* 9 */
284
-588, /* 1 */
285
-608, /* 1 */
286
-612, /* 1 */
287
-616, /* 6 */
288
-644, /* 1 */
289
-648, /* 1 */
290
-676, /* 1 */
291
-700, /* 1 */
292
-712, /* 1 */
293
-768, /* 1 */
294
-772, /* 1 */
295
-1028, /* 8545 */
296
-63500, /* 9 */
297
-144752, /* 1 */
298
-253988, /* 9 */
299
-525628, /* 1 */
300
-1051032, /* (0) */
301
-2097152
123
+/* SIZE        PERM    TEMP    ACT! */
124
+      8, /*    1992    7188 USE/POW2 */
125
+     16, /*   49976     172 USE/POW2 */
126
+     24, /*  995096     121      USE */
127
+     32, /*  151077      68 USE/POW2 */
128
+     40, /*   15175      58      USE */
129
+     48, /*    7231      55      USE */
130
+     56, /*  613432      47      USE */
131
+     64, /*    1925      44 USE/POW2 */
132
+     72, /*    3192      42      USE */
133
+     80, /*    2782      40      USE */
134
+     88, /*    3524      40      USE */
135
+     96, /*    3395      40      USE */
136
+    104, /*    3593      40      USE */
137
+    112, /*   31850      40      USE */
138
+    120, /*    5260      38      USE */
139
+    128, /*    3231      38 USE/POW2 */
140
+    136, /*    4785      38      USE */
141
+    144, /*    3000      38      USE */
142
+    152, /*   13384      38      USE */
143
+    160, /*   14915      36      USE */
144
+    168, /*     485      36      USE */
145
+    176, /*     379      36      USE */
146
+    184, /*     322      36      USE */
147
+    192, /*     260      36      USE */
148
+    200, /*     410      36      USE */
149
+    208, /*     388      36      USE */
150
+    216, /*     262      36      USE */
151
+    224, /*     256      36      USE */
152
+    232, /*     475      36      USE */
153
+    248, /*     544      36      USE */
154
+    256, /*     206      36     POW2 */
155
+    264, /*     352      36      USE */
156
+    280, /*     258      36      USE */
157
+    296, /*     283      36      USE */
158
+    304, /*     308      36      USE */
159
+    312, /*     566      36      USE */
160
+    328, /*      53      36      USE */
161
+    376, /*      18      36      USE */
162
+    616, /*       7      34      USE */
163
+   1032, /*   11408      32      USE */
164
+   2048, /*       0      32     POW2 */
165
+   4096, /*       0      28     POW2 */
166
+   5456, /*       1      20      USE */
167
+   8192, /*       0      16     POW2 */
168
+  10272, /*       1      14      USE */
169
+  18656, /*       1      11      USE */
170
+  21904, /*       1       6      USE */
171
+  32768, /*       0       6     POW2 */
172
+  44864, /*       1       4      USE */
173
+  51240, /*       1       2      USE */
174
+  65536, /*       0       2     POW2 */
175
+ 131072, /*       0       2     POW2 */
176
+ 147288, /*       1       2      USE */
177
+ 184624, /*       1       0      USE */
178
+ 253992, /*       9       0      USE */
179
+ 262144, /*       0       0     POW2 */
180
+ 525752, /*       1       0      USE */
181
+1048576, /*       0       0 USE/POW2 */
302 182
 };
303 183
 #endif
304 184
 #define FRAGSBITS (sizeof(fragsz)/sizeof(fragsz[0]))
... ...
@@ -327,7 +210,7 @@ struct FRAG {
327 327
 };
328 328
 #define FRAG_OVERHEAD (offsetof(struct FRAG, fake))
329 329
 
330
-#define align_to_voidptr(size) (((size) / sizeof(void *) + ((size) % sizeof(void *) != 0)) * sizeof(void *))
330
+#define align_to_voidptr(size) (((size) / MAX(sizeof(void *), 8) + ((size) % MAX(sizeof(void *), 8) != 0)) * MAX(sizeof(void *), 8))
331 331
 #define mpool_roundup(size) (FRAG_OVERHEAD + align_to_voidptr(size))
332 332
 
333 333
 static unsigned int align_to_pagesize(struct MP *mp, unsigned int size) {
... ...
@@ -359,7 +242,7 @@ struct MP *mpool_create() {
359 359
   memset(mpool_p, ALLOCPOISON, sz);
360 360
 #endif
361 361
   memcpy(mpool_p, &mp, sizeof(mp));
362
-  spam("Map created @ %p->%p - size %u out of %u\n", mpool_p, (char *)mpool_p + mp.mpm.size, mp.mpm.usize, mp.mpm.size);
362
+  spam("Map created @%p->%p - size %u out of %u - voidptr=%u\n", mpool_p, (char *)mpool_p + mp.mpm.size, mp.mpm.usize, mp.mpm.size, SIZEOF_VOID_P);
363 363
   return mpool_p;
364 364
 }
365 365
 
... ...
@@ -380,32 +263,40 @@ void mpool_destroy(struct MP *mp) {
380 380
   memset(mp, FREEPOISON, mpmsize + align_to_voidptr(sizeof(*mp)));
381 381
 #endif
382 382
   munmap((void *)mp, mpmsize + align_to_voidptr(sizeof(*mp)));
383
-  spam("Map destroyed @ %p\n", mp);
383
+  spam("Map destroyed @%p\n", mp);
384 384
 }
385 385
 
386 386
 void mpool_flush(struct MP *mp) {
387
-  size_t used = 0, mused;
388
-  struct MPMAP *mpm_next = mp->mpm.next, *mpm;
387
+    size_t used = 0, mused;
388
+    struct MPMAP *mpm_next = mp->mpm.next, *mpm;
389 389
 
390
-  while((mpm = mpm_next)) {
391
-    mpm_next = mpm->next;
390
+#ifdef EXIT_ON_FLUSH
391
+    exit(0);
392
+#endif
393
+
394
+    while((mpm = mpm_next)) {
395
+	mpm_next = mpm->next;
396
+	mused = align_to_pagesize(mp, mpm->usize);
397
+	if(mused < mpm->size) {
392 398
 #ifdef CL_DEBUG
393
-    memset((char *)mpm + align_to_pagesize(mp, mpm->usize), FREEPOISON, mpm->size - align_to_pagesize(mp, mpm->usize));
399
+	    memset((char *)mpm + mused, FREEPOISON, mpm->size - mused);
394 400
 #endif
395
-    munmap((char *)mpm + align_to_pagesize(mp, mpm->usize), mpm->size - align_to_pagesize(mp, mpm->usize));
396
-    mpm->size = align_to_pagesize(mp, mpm->usize);
397
-    used += mpm->size;
398
-  }
399
-  mused = align_to_pagesize(mp, mp->mpm.usize + align_to_voidptr(sizeof(*mp)));
400
-  if (mused < mp->mpm.size) {
401
+	    munmap((char *)mpm + mused, mpm->size - mused);
402
+	    mpm->size = mused;
403
+	}
404
+	used += mpm->size;
405
+    }
406
+
407
+    mused = align_to_pagesize(mp, mp->mpm.usize + align_to_voidptr(sizeof(*mp)));
408
+    if (mused < mp->mpm.size + align_to_voidptr(sizeof(*mp))) {
401 409
 #ifdef CL_DEBUG
402
-    memset((char *)&mp->mpm + mused, FREEPOISON, mp->mpm.size - mused);
410
+	memset((char *)mp + mused, FREEPOISON, mp->mpm.size + align_to_voidptr(sizeof(*mp)) - mused);
403 411
 #endif
404
-    munmap((char *)&mp->mpm + mused, mp->mpm.size - mused);
405
-    mp->mpm.size = mused;
406
-  }
407
-  used += mp->mpm.size;
408
-  spam("Map flushed @ %p, in use: %lu\n", mp, used);
412
+	munmap((char *)mp + mused, mp->mpm.size + align_to_voidptr(sizeof(*mp)) - mused);
413
+	mp->mpm.size = mused - align_to_voidptr(sizeof(*mp));
414
+    }
415
+    used += mp->mpm.size;
416
+    spam("Map flushed @%p, in use: %lu\n", mp, used);
409 417
 }
410 418
 
411 419
 int mpool_getstats(const struct cl_engine *eng, size_t *used, size_t *total)
... ...
@@ -443,7 +334,7 @@ void *mpool_malloc(struct MP *mp, size_t size) {
443 443
 
444 444
   /* Case 1: We have a free'd frag */
445 445
   if((f = mp->avail[sbits])) {
446
-    spam("malloc %p size %u (freed)\n", f, mpool_roundup(size));
446
+    spam("malloc @%p size %u (freed)\n", f, align_to_voidptr(size + FRAG_OVERHEAD));
447 447
     mp->avail[sbits] = f->u.next;
448 448
     f->u.sbits = sbits;
449 449
 #ifdef CL_DEBUG
... ...
@@ -462,7 +353,7 @@ void *mpool_malloc(struct MP *mp, size_t size) {
462 462
   while(mpm) {
463 463
     if(mpm->size - mpm->usize >= needed) {
464 464
       f = (struct FRAG *)((char *)mpm + mpm->usize);
465
-      spam("malloc %p size %u (hole)\n", f, mpool_roundup(size));
465
+      spam("malloc @%p size %u (hole)\n", f, align_to_voidptr(size + FRAG_OVERHEAD));
466 466
       mpm->usize += needed;
467 467
       f->u.sbits = sbits;
468 468
 #ifdef CL_DEBUG
... ...
@@ -493,7 +384,7 @@ void *mpool_malloc(struct MP *mp, size_t size) {
493 493
   mpm->next = mp->mpm.next;
494 494
   mp->mpm.next = mpm;
495 495
   f = (struct FRAG *)((char *)mpm + align_to_voidptr(sizeof(*mpm)));
496
-  spam("malloc %p size %u (new map)\n", f, mpool_roundup(size));
496
+  spam("malloc @%p size %u (new map)\n", f, align_to_voidptr(size + FRAG_OVERHEAD));
497 497
   f->u.sbits = sbits;
498 498
 #ifdef CL_DEBUG
499 499
   f->magic = MPOOLMAGIC;
... ...
@@ -514,7 +405,7 @@ void mpool_free(struct MP *mp, void *ptr) {
514 514
   sbits = f->u.sbits;
515 515
   f->u.next = mp->avail[sbits];
516 516
   mp->avail[sbits] = f;
517
-  spam("free @ %p\n", f);
517
+  spam("free @%p\n", f);
518 518
 }
519 519
 
520 520
 void *mpool_calloc(struct MP *mp, size_t nmemb, size_t size) {
... ...
@@ -533,14 +424,16 @@ void *mpool_realloc(struct MP *mp, void *ptr, size_t size) {
533 533
   void *new_ptr;
534 534
   if (!ptr) return mpool_malloc(mp, size);
535 535
 
536
-  spam("realloc @ %p (size %u -> %u))\n", f, from_bits(f->u.sbits), size);
537 536
   if(!size || !(csize = from_bits(f->u.sbits))) {
538 537
     cli_errmsg("mpool_realloc(): Attempt to allocate %lu bytes. Please report to http://bugs.clamav.net\n", (unsigned long int) size);
539 538
     return NULL;
540 539
   }
541 540
   csize -= FRAG_OVERHEAD;
542
-  if (csize >= size && (!f->u.sbits || from_bits(f->u.sbits-1)-FRAG_OVERHEAD < size))
541
+  if (csize >= size && (!f->u.sbits || from_bits(f->u.sbits-1)-FRAG_OVERHEAD < size)) {
542
+    spam("free @%p\n", f);
543
+    spam("malloc @%p size %u (self)\n", f, align_to_voidptr(size + FRAG_OVERHEAD));
543 544
     return ptr;
545
+  }
544 546
   if (!(new_ptr = mpool_malloc(mp, size)))
545 547
     return NULL;
546 548
   memcpy(new_ptr, ptr, csize <= size ? csize : size);
... ...
@@ -549,25 +442,11 @@ void *mpool_realloc(struct MP *mp, void *ptr, size_t size) {
549 549
 }
550 550
 
551 551
 void *mpool_realloc2(struct MP *mp, void *ptr, size_t size) {
552
-  struct FRAG *f = (struct FRAG *)((char *)ptr - FRAG_OVERHEAD);
553
-  unsigned int csize;
554
-  void *new_ptr;
555
-
556
-  if (!ptr) return mpool_malloc(mp, size);
557
-
558
-  spam("realloc @ %p (size %u -> %u))\n", f, from_bits(f->u.sbits), size);
559
-  if(!size || !(csize = from_bits(f->u.sbits))) {
560
-    cli_errmsg("mpool_realloc2(): Attempt to allocate %lu bytes. Please report to http://bugs.clamav.net\n", (unsigned long int) size);
552
+    void *new_ptr = mpool_realloc(mp, ptr, size);
553
+    if(new_ptr)
554
+	return new_ptr;
561 555
     mpool_free(mp, ptr);
562 556
     return NULL;
563
-  }
564
-  csize -= FRAG_OVERHEAD;
565
-  if (csize >= size && (!f->u.sbits || from_bits(f->u.sbits-1)-FRAG_OVERHEAD < size))
566
-    return ptr;
567
-  if ((new_ptr = mpool_malloc(mp, size)))
568
-    memcpy(new_ptr, ptr, csize);
569
-  mpool_free(mp, ptr);
570
-  return new_ptr;
571 557
 }
572 558
 
573 559
 unsigned char *cli_mpool_hex2str(mpool_t *mp, const unsigned char *hex) {
... ...
@@ -30,12 +30,9 @@
30 30
 #ifdef HAVE_UNISTD_H
31 31
 #include <unistd.h>
32 32
 #endif
33
-
34
-#if HAVE_MMAP
35
-#ifdef HAVE_SYS_MMAN_H
33
+#if defined(HAVE_MMAP) && defined(HAVE_SYS_MMAN_H)
36 34
 #include <sys/mman.h>
37 35
 #endif
38
-#endif
39 36
 
40 37
 #include "others.h"
41 38
 #include "cltypes.h"
... ...
@@ -47,10 +44,6 @@
47 47
 #include "scanners.h"
48 48
 #include "nulsft.h" /* SHUT UP GCC -Wextra */
49 49
 
50
-#ifndef O_BINARY
51
-#define O_BINARY 0
52
-#endif
53
-
54 50
 #define EC32(x) le32_to_host(x)
55 51
 
56 52
 enum {
... ...
@@ -205,9 +198,9 @@ static int nsis_unpack_next(struct nsis_st *n, cli_ctx *ctx) {
205 205
     return ret;
206 206
 
207 207
   if (n->fno)
208
-    snprintf(n->ofn, 1023, "%s/content.%.3u", n->dir, n->fno);
208
+    snprintf(n->ofn, 1023, "%s"PATHSEP"content.%.3u", n->dir, n->fno);
209 209
   else
210
-    snprintf(n->ofn, 1023, "%s/headers", n->dir);
210
+    snprintf(n->ofn, 1023, "%s"PATHSEP"headers", n->dir);
211 211
 
212 212
   n->fno++;
213 213
 
... ...
@@ -34,15 +34,10 @@
34 34
 #endif
35 35
 #include <ctype.h>
36 36
 #include <stdlib.h>
37
-#include "clamav.h"
38
-
39
-#if HAVE_MMAP
40
-#if HAVE_SYS_MMAN_H
37
+#if defined(HAVE_MMAP) && defined(HAVE_SYS_MMAN_H)
41 38
 #include <sys/mman.h>
42
-#else /* HAVE_SYS_MMAN_H */
43
-#undef HAVE_MMAP
44
-#endif
45 39
 #endif
40
+#include "clamav.h"
46 41
 
47 42
 #include "cltypes.h"
48 43
 #include "others.h"
... ...
@@ -65,11 +60,6 @@
65 65
 #pragma pack 1
66 66
 #endif
67 67
 
68
-#ifndef	O_BINARY
69
-#define	O_BINARY	0
70
-#endif
71
-
72
-
73 68
 typedef struct ole2_header_tag
74 69
 {
75 70
 	unsigned char magic[8];		/* should be: 0xd0cf11e0a1b11ae1 */
... ...
@@ -539,7 +529,7 @@ static int ole2_walk_property_tree(int fd, ole2_header_t *hdr, const char *dir,
539 539
 			if (dir) {
540 540
 				dirname = (char *) cli_malloc(strlen(dir)+8);
541 541
 				if (!dirname) return CL_BREAK;
542
-				snprintf(dirname, strlen(dir)+8, "%s/%.6d", dir, prop_index);
542
+				snprintf(dirname, strlen(dir)+8, "%s"PATHSEP"%.6d", dir, prop_index);
543 543
 				if (mkdir(dirname, 0700) != 0) {
544 544
 					free(dirname);
545 545
 					return CL_BREAK;
... ...
@@ -585,7 +575,7 @@ static int handler_writefile(int fd, ole2_header_t *hdr, property_t *prop, const
585 585
 	name = get_property_name2(prop->name, prop->name_size);
586 586
 	if (name) cnt = uniq_add(hdr->U, name, strlen(name), &hash);
587 587
 	else cnt = uniq_add(hdr->U, NULL, 0, &hash);
588
-	snprintf(newname, sizeof(newname), "%s/%s_%u", dir, hash, cnt);
588
+	snprintf(newname, sizeof(newname), "%s"PATHSEP"%s_%u", dir, hash, cnt);
589 589
 	newname[sizeof(newname)-1]='\0';
590 590
 	cli_dbgmsg("OLE2 [handler_writefile]: Dumping '%s' to '%s'\n", name ? name : "<empty>", newname);
591 591
 	if (name) free(name);
... ...
@@ -33,30 +33,24 @@
33 33
 #endif
34 34
 #include <sys/types.h>
35 35
 #include <sys/stat.h>
36
-#ifndef	C_WINDOWS
36
+#include <dirent.h>
37
+#ifndef	_WIN32
37 38
 #include <sys/wait.h>
38 39
 #include <sys/time.h>
39
-#include <dirent.h>
40 40
 #endif
41 41
 #include <time.h>
42 42
 #include <fcntl.h>
43
-#ifndef	C_WINDOWS
43
+#ifdef HAVE_PWD_H
44 44
 #include <pwd.h>
45 45
 #endif
46 46
 #include <errno.h>
47 47
 #include "target.h"
48
-#ifndef	C_WINDOWS
49
-#include <sys/time.h>
50
-#endif
51 48
 #ifdef	HAVE_SYS_PARAM_H
52 49
 #include <sys/param.h>
53 50
 #endif
54 51
 #ifdef	HAVE_MALLOC_H
55 52
 #include <malloc.h>
56 53
 #endif
57
-#if	defined(_MSC_VER) && defined(_DEBUG)
58
-#include <crtdbg.h>
59
-#endif
60 54
 
61 55
 #if defined(HAVE_READDIR_R_3) || defined(HAVE_READDIR_R_2)
62 56
 #include <limits.h>
... ...
@@ -74,15 +68,6 @@
74 74
 #include "scanners.h"
75 75
 #include "bytecode.h"
76 76
 
77
-#ifndef	O_BINARY
78
-#define	O_BINARY	0
79
-#endif
80
-
81
-#ifdef        C_WINDOWS
82
-#undef        P_tmpdir
83
-#define       P_tmpdir        "C:\\WINDOWS\\TEMP"
84
-#endif
85
-
86 77
 int (*cli_unrar_open)(int fd, const char *dirname, unrar_state_t *state);
87 78
 int (*cli_unrar_extract_next_prepare)(unrar_state_t *state, const char *dirname);
88 79
 int (*cli_unrar_extract_next)(unrar_state_t *state, const char *dirname);
... ...
@@ -572,7 +557,7 @@ int cli_checklimits(const char *who, cli_ctx *ctx, unsigned long need1, unsigned
572 572
         /* if the remaining scansize is too small... */
573 573
         if(ctx->engine->maxscansize-ctx->scansize<needed) {
574 574
 	    /* ... we tell the caller to skip this file */
575
-	    cli_dbgmsg("%s: scansize exceeded (initial: %lu, remaining: %lu, needed: %lu)\n", who, ctx->engine->maxscansize, ctx->scansize, needed);
575
+	    cli_dbgmsg("%s: scansize exceeded (initial: %lu, remaining: %lu, needed: %lu)\n", who, (unsigned long int) ctx->engine->maxscansize, (unsigned long int) ctx->scansize, needed);
576 576
 	    ret = CL_EMAXSIZE;
577 577
 	}
578 578
     }
... ...
@@ -580,7 +565,7 @@ int cli_checklimits(const char *who, cli_ctx *ctx, unsigned long need1, unsigned
580 580
     /* if we have per-file size limits, and we are overlimit... */
581 581
     if(needed && ctx->engine->maxfilesize && ctx->engine->maxfilesize<needed) {
582 582
 	/* ... we tell the caller to skip this file */
583
-        cli_dbgmsg("%s: filesize exceeded (allowed: %lu, needed: %lu)\n", who, ctx->engine->maxfilesize, needed);
583
+        cli_dbgmsg("%s: filesize exceeded (allowed: %lu, needed: %lu)\n", who, (unsigned long int) ctx->engine->maxfilesize, needed);
584 584
 	ret = CL_EMAXSIZE;
585 585
     }
586 586
 
... ...
@@ -789,9 +774,7 @@ int cli_rmdirs(const char *dirname)
789 789
 #else
790 790
 	    while((dent = readdir(dd))) {
791 791
 #endif
792
-#if	(!defined(C_INTERIX)) && (!defined(C_WINDOWS))
793 792
 		if(dent->d_ino)
794
-#endif
795 793
 		{
796 794
 		    if(strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..")) {
797 795
 			path = cli_malloc(strlen(dirname) + strlen(dent->d_name) + 2);
... ...
@@ -800,7 +783,7 @@ int cli_rmdirs(const char *dirname)
800 800
 			    return -1;
801 801
 			}
802 802
 
803
-			sprintf(path, "%s/%s", dirname, dent->d_name);
803
+			sprintf(path, "%s"PATHSEP"%s", dirname, dent->d_name);
804 804
 
805 805
 			/* stat the file */
806 806
 			if(lstat(path, &statbuf) != -1) {
... ...
@@ -906,8 +889,6 @@ int cli_dumpscan(int fd, off_t offset, size_t size, cli_ctx *ctx)
906 906
 
907 907
 #define BITS_PER_CHAR (8)
908 908
 #define BITSET_DEFAULT_SIZE (1024)
909
-#define FALSE (0)
910
-#define TRUE (1)
911 909
 
912 910
 static unsigned long nearest_power(unsigned long num)
913 911
 {
... ...
@@ -991,4 +972,3 @@ int cli_bitset_test(bitset_t *bs, unsigned long bit_offset)
991 991
 	}
992 992
 	return (bs->bitset[char_offset] & ((unsigned char)1 << bit_offset));
993 993
 }
994
-
... ...
@@ -37,6 +37,7 @@
37 37
 
38 38
 #include "clamav.h"
39 39
 #include "dconf.h"
40
+#include "filetypes.h"
40 41
 #include "libclamunrar_iface/unrar_iface.h"
41 42
 #include "regex/regex.h"
42 43
 #include "bytecode.h"
... ...
@@ -50,7 +51,7 @@
50 50
  * in re-enabling affected modules.
51 51
  */
52 52
 
53
-#define CL_FLEVEL 47
53
+#define CL_FLEVEL 49
54 54
 #define CL_FLEVEL_DCONF	CL_FLEVEL
55 55
 
56 56
 extern uint8_t cli_debug_flag;
... ...
@@ -107,6 +108,7 @@ typedef struct {
107 107
     unsigned int recursion;
108 108
     unsigned int scannedfiles;
109 109
     unsigned int found_possibly_unwanted;
110
+    cli_file_t container_type; /* FIXME: to be made into a stack or array - see bb#1579 & bb#1293 */
110 111
     struct cli_dconf *dconf;
111 112
 } cli_ctx;
112 113
 
... ...
@@ -169,7 +171,7 @@ struct cl_engine {
169 169
     struct cli_ftype *ftypes;
170 170
 
171 171
     /* Ignored signatures */
172
-    struct cli_ignored *ignored;
172
+    struct cli_matcher *ignored;
173 173
 
174 174
     /* PUA categories (to be included or excluded) */
175 175
     char *pua_cats;
... ...
@@ -324,21 +326,6 @@ static inline void cli_writeint32(char *offset, uint32_t value)
324 324
 #endif
325 325
 #define CLI_SAR(n,s) n = CLI_SRS(n,s)
326 326
 
327
-#ifndef	FALSE
328
-#define FALSE (0)
329
-#endif
330
-
331
-#ifndef	TRUE
332
-#define TRUE (1)
333
-#endif
334
-
335
-#ifndef MIN
336
-#define MIN(a, b)	(((a) < (b)) ? (a) : (b))
337
-#endif
338
-#ifndef MAX
339
-#define MAX(a,b)	(((a) > (b)) ? (a) : (b))
340
-#endif
341
-
342 327
 typedef struct bitset_tag
343 328
 {
344 329
         unsigned char *bitset;
... ...
@@ -405,6 +392,7 @@ char *cli_md5file(const char *filename);
405 405
 int cli_unlink(const char *pathname);
406 406
 int cli_readn(int fd, void *buff, unsigned int count);
407 407
 int cli_writen(int fd, const void *buff, unsigned int count);
408
+const char *cli_gettmpdir(void);
408 409
 char *cli_gentemp(const char *dir);
409 410
 int cli_gentempfd(const char *dir, char **name, int *fd);
410 411
 unsigned int cli_rndnum(unsigned int max);
... ...
@@ -419,6 +407,7 @@ int cli_checklimits(const char *, cli_ctx *, unsigned long, unsigned long, unsig
419 419
 int cli_updatelimits(cli_ctx *, unsigned long);
420 420
 unsigned long cli_getsizelimit(cli_ctx *, unsigned long);
421 421
 int cli_matchregex(const char *str, const char *regex);
422
+void cli_qsort(void *basep, size_t nelems, size_t size, int (*comp)(const void *, const void *));
422 423
 
423 424
 /* symlink behaviour */
424 425
 #define CLI_FTW_FOLLOW_FILE_SYMLINK 0x01
... ...
@@ -33,30 +33,24 @@
33 33
 #endif
34 34
 #include <sys/types.h>
35 35
 #include <sys/stat.h>
36
-#ifndef	C_WINDOWS
36
+#include <dirent.h>
37
+#ifndef	_WIN32
37 38
 #include <sys/wait.h>
38 39
 #include <sys/time.h>
39
-#include <dirent.h>
40 40
 #endif
41 41
 #include <time.h>
42 42
 #include <fcntl.h>
43
-#ifndef	C_WINDOWS
43
+#ifdef	HAVE_PWD_H
44 44
 #include <pwd.h>
45 45
 #endif
46 46
 #include <errno.h>
47 47
 #include "target.h"
48
-#ifndef	C_WINDOWS
49
-#include <sys/time.h>
50
-#endif
51 48
 #ifdef	HAVE_SYS_PARAM_H
52 49
 #include <sys/param.h>
53 50
 #endif
54 51
 #ifdef	HAVE_MALLOC_H
55 52
 #include <malloc.h>
56 53
 #endif
57
-#if	defined(_MSC_VER) && defined(_DEBUG)
58
-#include <crtdbg.h>
59
-#endif
60 54
 
61 55
 #include "clamav.h"
62 56
 #include "others.h"
... ...
@@ -67,10 +61,6 @@
67 67
 #include "matcher-ac.h"
68 68
 #include "md5.h"
69 69
 
70
-#ifndef	O_BINARY
71
-#define	O_BINARY	0
72
-#endif
73
-
74 70
 static unsigned char name_salt[16] = { 16, 38, 97, 12, 8, 4, 72, 196, 217, 144, 33, 124, 18, 11, 17, 253 };
75 71
 
76 72
 #ifdef CL_NOTHREADS
... ...
@@ -118,9 +108,11 @@ void cli_dbgmsg_internal(const char *str, ...)
118 118
 int cli_matchregex(const char *str, const char *regex)
119 119
 {
120 120
 	regex_t reg;
121
-	int match;
122
-
123
-    if(cli_regcomp(&reg, regex, REG_EXTENDED | REG_NOSUB) == 0) {
121
+	int match, flags = REG_EXTENDED | REG_NOSUB;
122
+#ifdef _WIN32
123
+    flags |= REG_ICASE;
124
+#endif
125
+    if(cli_regcomp(&reg, regex, flags) == 0) {
124 126
 	match = (cli_regexec(&reg, str, 0, NULL, 0) == REG_NOMATCH) ? 0 : 1;
125 127
 	cli_regfree(&reg);
126 128
 	return match;
... ...
@@ -138,11 +130,7 @@ void *cli_malloc(size_t size)
138 138
 	return NULL;
139 139
     }
140 140
 
141
-#if defined(_MSC_VER) && defined(_DEBUG)
142
-    alloc = _malloc_dbg(size, _NORMAL_BLOCK, __FILE__, __LINE__);
143
-#else
144 141
     alloc = malloc(size);
145
-#endif
146 142
 
147 143
     if(!alloc) {
148 144
 	cli_errmsg("cli_malloc(): Can't allocate memory (%lu bytes).\n", (unsigned long int) size);
... ...
@@ -161,11 +149,7 @@ void *cli_calloc(size_t nmemb, size_t size)
161 161
 	return NULL;
162 162
     }
163 163
 
164
-#if defined(_MSC_VER) && defined(_DEBUG)
165
-    alloc = _calloc_dbg(nmemb, size, _NORMAL_BLOCK, __FILE__, __LINE__);
166
-#else
167 164
     alloc = calloc(nmemb, size);
168
-#endif
169 165
 
170 166
     if(!alloc) {
171 167
 	cli_errmsg("cli_calloc(): Can't allocate memory (%lu bytes).\n", (unsigned long int) (nmemb * size));
... ...
@@ -224,11 +208,7 @@ char *cli_strdup(const char *s)
224 224
         return NULL;
225 225
     }
226 226
 
227
-#if defined(_MSC_VER) && defined(_DEBUG)
228
-    alloc = _strdup_dbg(s, _NORMAL_BLOCK, __FILE__, __LINE__);
229
-#else
230 227
     alloc = strdup(s);
231
-#endif
232 228
 
233 229
     if(!alloc) {
234 230
         cli_errmsg("cli_strdup(): Can't allocate memory (%u bytes).\n", (unsigned int) strlen(s));
... ...
@@ -352,6 +332,10 @@ int cli_writen(int fd, const void *buff, unsigned int count)
352 352
 
353 353
 int cli_filecopy(const char *src, const char *dest)
354 354
 {
355
+
356
+#ifdef _WIN32
357
+    return (!CopyFileA(src, dest, 0));
358
+#else
355 359
 	char *buffer;
356 360
 	int s, d, bytes;
357 361
 
... ...
@@ -377,7 +361,29 @@ int cli_filecopy(const char *src, const char *dest)
377 377
     close(s);
378 378
 
379 379
     return close(d);
380
+#endif
381
+}
382
+
383
+#ifndef P_tmpdir
384
+#ifdef _WIN32
385
+#define P_tmpdir "C:\\"
386
+#else
387
+#define P_tmpdir "/tmp"
388
+#endif /* _WIN32 */
389
+#endif /* P_tmpdir */
390
+
391
+const char *cli_gettmpdir(void) {
392
+	const char *tmpdir;
393
+    if(
394
+#ifdef _WIN32
395
+	!(tmpdir = getenv("TEMP")) && !(tmpdir = getenv("TMP"))
396
+#else
397
+	!(tmpdir = getenv("TMPDIR"))
398
+#endif
399
+    ) tmpdir = P_tmpdir;
400
+    return tmpdir;
380 401
 }
402
+
381 403
 struct dirent_data {
382 404
     char *filename;
383 405
     const char *dirname;
... ...
@@ -518,9 +524,9 @@ int cli_ftw(char *path, int flags, int maxdepth, cli_ftw_cb callback, struct cli
518 518
 	char *pathend;
519 519
 	/* trim slashes so that dir and dir/ behave the same when
520 520
 	 * they are symlinks, and we are not following symlinks */
521
-	while (path[0] == '/' && path[1] == '/') path++;
521
+	while (path[0] == *PATHSEP && path[1] == *PATHSEP) path++;
522 522
 	pathend = path + strlen(path);
523
-	while (pathend > path && pathend[-1] == '/') --pathend;
523
+	while (pathend > path && pathend[-1] == *PATHSEP) --pathend;
524 524
 	*pathend = '\0';
525 525
     }
526 526
     if(pathchk && pathchk(path, data) == 1)
... ...
@@ -613,10 +619,10 @@ static int cli_ftw_dir(const char *dirname, int flags, int maxdepth, cli_ftw_cb
613 613
 		if (ret != CL_SUCCESS)
614 614
 		    break;
615 615
 	    }
616
-            if(!strcmp(dirname, "/"))
617
-		sprintf(fname, "/%s", dent->d_name);
616
+            if(!strcmp(dirname, PATHSEP))
617
+		sprintf(fname, PATHSEP"%s", dent->d_name);
618 618
 	    else
619
-		sprintf(fname, "%s/%s", dirname, dent->d_name);
619
+		sprintf(fname, "%s"PATHSEP"%s", dirname, dent->d_name);
620 620
 
621 621
 	    if(pathchk && pathchk(fname, data) == 1) {
622 622
 		free(fname);
... ...
@@ -677,7 +683,7 @@ static int cli_ftw_dir(const char *dirname, int flags, int maxdepth, cli_ftw_cb
677 677
 	closedir(dd);
678 678
 
679 679
 	if (entries) {
680
-	    qsort(entries, entries_cnt, sizeof(*entries), ftw_compare);
680
+	    cli_qsort(entries, entries_cnt, sizeof(*entries), ftw_compare);
681 681
 	    for (i = 0; i < entries_cnt; i++) {
682 682
 		struct dirent_data *entry = &entries[i];
683 683
 		ret = handle_entry(entry, flags, maxdepth-1, callback, data, pathchk);
... ...
@@ -757,18 +763,12 @@ char *cli_gentemp(const char *dir)
757 757
         const char *mdir;
758 758
 	unsigned char salt[16 + 32];
759 759
 	int i;
760
+    size_t len;
760 761
 
761
-    if(!dir) {
762
-	if((mdir = getenv("TMPDIR")) == NULL)
763
-#ifdef P_tmpdir
764
-	    mdir = P_tmpdir;
765
-#else
766
-	    mdir = "/tmp";
767
-#endif
768
-    } else
769
-	mdir = dir;
762
+    mdir = dir ? dir : cli_gettmpdir();
770 763
 
771
-    name = (char *) cli_calloc(strlen(mdir) + 1 + 32 + 1 + 7, sizeof(char));
764
+    len = strlen(mdir) + 42;
765
+    name = (char *) cli_calloc(len, sizeof(char));
772 766
     if(!name) {
773 767
 	cli_dbgmsg("cli_gentemp('%s'): out of memory\n", mdir);
774 768
 	return NULL;
... ...
@@ -795,12 +795,7 @@ char *cli_gentemp(const char *dir)
795 795
 	return NULL;
796 796
     }
797 797
 
798
-#ifdef	C_WINDOWS
799
-	sprintf(name, "%s\\clamav-", mdir);
800
-#else
801
-	sprintf(name, "%s/clamav-", mdir);
802
-#endif
803
-    strncat(name, tmp, 32);
798
+	snprintf(name, len, "%s"PATHSEP"clamav-%s", mdir, tmp);
804 799
     free(tmp);
805 800
 
806 801
     return(name);
... ...
@@ -835,3 +830,83 @@ int cli_regcomp(regex_t *preg, const char *pattern, int cflags)
835 835
     }
836 836
     return cli_regcomp_real(preg, pattern, cflags);
837 837
 }
838
+
839
+/* Public domain qsort implementation by Raymond Gardner and Paul Edwards */
840
+#define  SWAP(a, b)  (qsort_swap((char *)(a), (char *)(b), size))
841
+#define  COMP(a, b)  ((*comp)((void *)(a), (void *)(b)))
842
+#define  T           7 /* subfiles of T or fewer elements will
843
+			* be sorted by a simple insertion sort
844
+			* T must be at least 3
845
+			*/
846
+
847
+static void qsort_swap(char *a, char *b, size_t nbytes)
848
+{
849
+	char tmp;
850
+
851
+   do {
852
+      tmp = *a;
853
+      *a++ = *b;
854
+      *b++ = tmp;
855
+   } while(--nbytes);
856
+}
857
+
858
+void cli_qsort(void *basep, size_t nelems, size_t size, int (*comp)(const void *, const void *))
859
+{
860
+	char *stack[40], **sp;
861
+	char *i, *j, *limit;
862
+	size_t thresh;
863
+	char *base;
864
+
865
+    base = (char *) basep;
866
+    thresh = T * size;
867
+    sp = stack;
868
+    limit = base + nelems * size;
869
+    while(1) {
870
+	if(limit - base > thresh) {
871
+	    SWAP(((((size_t) (limit - base)) / size) / 2) * size + base, base);
872
+	    i = base + size;
873
+	    j = limit - size;
874
+	    if(COMP(i, j) > 0)
875
+		SWAP(i, j);
876
+	    if(COMP(base, j) > 0)
877
+		SWAP(base, j);
878
+	    if(COMP(i, base) > 0)
879
+		SWAP(i, base);
880
+	    while(1) {
881
+		do
882
+		    i += size;
883
+		while(COMP(i, base) < 0);
884
+		do
885
+		    j -= size;
886
+		while(COMP(j, base) > 0);
887
+		if(i > j)
888
+		    break;
889
+		SWAP(i, j);
890
+	    }
891
+	    SWAP(base, j);
892
+	    if(j - base > limit - i) {
893
+		sp[0] = base;
894
+		sp[1] = j;
895
+		base = i;
896
+	    } else {
897
+		sp[0] = i;
898
+		sp[1] = limit;
899
+		limit = j;
900
+	    }
901
+	    sp += 2;
902
+	} else {
903
+	    for(j = base, i = j + size; i < limit; j = i, i += size)
904
+		for(; COMP(j, j + size) > 0; j -= size) {
905
+		    SWAP(j, j+size);
906
+		    if(j == base)
907
+			break;
908
+		}
909
+	    if(sp != stack) {
910
+		sp -= 2;
911
+		base = sp[0];
912
+		limit = sp[1];
913
+	    } else
914
+		break;
915
+	}
916
+    }
917
+}
... ...
@@ -41,26 +41,17 @@ static	char	const	rcsid[] = "$Id: pdf.c,v 1.61 2007/02/12 20:46:09 njh Exp $";
41 41
 #ifdef	HAVE_UNISTD_H
42 42
 #include <unistd.h>
43 43
 #endif
44
-
45
-#ifdef HAVE_SYS_MMAN_H
44
+#if defined(HAVE_MMAP) && defined(HAVE_SYS_MMAN_H)
46 45
 #include <sys/mman.h>
47 46
 #endif
48
-
49 47
 #include <zlib.h>
50 48
 
51
-#ifdef	C_WINDOWS
52
-#include <io.h>
53
-#endif
54
-
55 49
 #include "clamav.h"
56 50
 #include "others.h"
57 51
 #include "mbox.h"
58 52
 #include "pdf.h"
59 53
 #include "scanners.h"
60
-
61
-#ifndef	O_BINARY
62
-#define	O_BINARY	0
63
-#endif
54
+#include "str.h"
64 55
 
65 56
 #ifdef	CL_DEBUG
66 57
 /*#define	SAVE_TMP	
... ...
@@ -72,7 +63,6 @@ static	int	flatedecode(unsigned char *buf, off_t len, int fout, cli_ctx *ctx);
72 72
 static	int	ascii85decode(const char *buf, off_t len, unsigned char *output);
73 73
 static	const	char	*pdf_nextlinestart(const char *ptr, size_t len);
74 74
 static	const	char	*pdf_nextobject(const char *ptr, size_t len);
75
-static	const	char	*cli_pmemstr(const char *haystack, size_t hs, const char *needle, size_t ns);
76 75
 
77 76
 int
78 77
 cli_pdf(const char *dir, int desc, cli_ctx *ctx, off_t offset)
... ...
@@ -87,6 +77,7 @@ cli_pdf(const char *dir, int desc, cli_ctx *ctx, off_t offset)
87 87
 	int printed_predictor_message, printed_embedded_font_message, rc;
88 88
 	unsigned int files;
89 89
 	struct stat statb;
90
+	int opt_failed = 0;
90 91
 
91 92
 	cli_dbgmsg("in cli_pdf(%s)\n", dir);
92 93
 
... ...
@@ -145,7 +136,7 @@ cli_pdf(const char *dir, int desc, cli_ctx *ctx, off_t offset)
145 145
 	 * q points to the end of the trailer section
146 146
 	 */
147 147
 	trailerlength = (long)(q - trailerstart);
148
-	if(cli_pmemstr(trailerstart, trailerlength, "Encrypt", 7)) {
148
+	if(cli_memstr(trailerstart, trailerlength, "Encrypt", 7)) {
149 149
 		/*
150 150
 		 * This tends to mean that the file is, in effect, read-only
151 151
 		 * http://www.cs.cmu.edu/~dst/Adobe/Gallery/anon21jul01-pdf-encryption.txt
... ...
@@ -238,7 +229,7 @@ cli_pdf(const char *dir, int desc, cli_ctx *ctx, off_t offset)
238 238
 
239 239
 		bytesleft -= (off_t)((q - p) + 3);
240 240
 		objstart = p = &q[3];
241
-		objend = cli_pmemstr(p, bytesleft, "endobj", 6);
241
+		objend = cli_memstr(p, bytesleft, "endobj", 6);
242 242
 		if(objend == NULL) {
243 243
 			cli_dbgmsg("cli_pdf: No matching endobj\n");
244 244
 			break;
... ...
@@ -248,7 +239,7 @@ cli_pdf(const char *dir, int desc, cli_ctx *ctx, off_t offset)
248 248
 		objlen = (unsigned long)(objend - objstart);
249 249
 
250 250
 		/* Is this object a stream? */
251
-		streamstart = cli_pmemstr(objstart, objlen, "stream", 6);
251
+		streamstart = cli_memstr(objstart, objlen, "stream", 6);
252 252
 		if(streamstart == NULL)
253 253
 			continue;
254 254
 
... ...
@@ -274,7 +265,6 @@ cli_pdf(const char *dir, int desc, cli_ctx *ctx, off_t offset)
274 274
 					 */
275 275
 					if((bytesleft > 11) && strncmp(q, " 0 R", 4) == 0) {
276 276
 						const char *r, *nq;
277
-						int opt_failed = 0;
278 277
 						size_t len;
279 278
 						char b[14];
280 279
 
... ...
@@ -286,10 +276,15 @@ cli_pdf(const char *dir, int desc, cli_ctx *ctx, off_t offset)
286 286
 						length = (unsigned long)strlen(b);
287 287
 						/* optimization: assume objects
288 288
 						 * are sequential */
289
-						nq = q;
290
-						len = buf + size - q;
289
+						if(!opt_failed) {
290
+						    nq = q;
291
+						    len = buf + size - q;
292
+						} else {
293
+						    nq = buf;
294
+						    len = q - buf;
295
+						}
291 296
 						do {
292
-							r = cli_pmemstr(nq, len, b, length);
297
+							r = cli_memstr(nq, len, b, length);
293 298
 							if (r > nq) {
294 299
 								const char x = *(r-1);
295 300
 								if (x == '\n' || x=='\r') {
... ...
@@ -298,8 +293,8 @@ cli_pdf(const char *dir, int desc, cli_ctx *ctx, off_t offset)
298 298
 								}
299 299
 							}
300 300
 							if (r) {
301
-								len -= r+1-nq;
302
-								nq = r + 1;
301
+								len -= r + length - nq;
302
+								nq = r + length;
303 303
 							} else if (!opt_failed) {
304 304
 								/* we failed optimized match,
305 305
 								 * try matching from the beginning
... ...
@@ -381,9 +376,9 @@ cli_pdf(const char *dir, int desc, cli_ctx *ctx, off_t offset)
381 381
 			break;
382 382
 		len -= (int)(q - streamstart);
383 383
 		streamstart = q;
384
-		streamend = cli_pmemstr(streamstart, len, "endstream\n", 10);
384
+		streamend = cli_memstr(streamstart, len, "endstream\n", 10);
385 385
 		if(streamend == NULL) {
386
-			streamend = cli_pmemstr(streamstart, len, "endstream\r", 10);
386
+			streamend = cli_memstr(streamstart, len, "endstream\r", 10);
387 387
 			if(streamend == NULL) {
388 388
 				cli_dbgmsg("cli_pdf: No endstream\n");
389 389
 				break;
... ...
@@ -391,7 +386,7 @@ cli_pdf(const char *dir, int desc, cli_ctx *ctx, off_t offset)
391 391
 			has_cr = 1;
392 392
 		} else
393 393
 			has_cr = 0;
394
-		snprintf(fullname, sizeof(fullname), "%s/pdf%02u", dir, files);
394
+		snprintf(fullname, sizeof(fullname), "%s"PATHSEP"pdf%02u", dir, files);
395 395
 		fout = open(fullname, O_RDWR|O_CREAT|O_EXCL|O_TRUNC|O_BINARY, 0600);
396 396
 		if(fout < 0) {
397 397
 			char err[128];
... ...
@@ -531,6 +526,10 @@ cli_pdf(const char *dir, int desc, cli_ctx *ctx, off_t offset)
531 531
 						rc = CL_EUNLINK;
532 532
 						break;
533 533
 					}
534
+					if(cli_updatelimits(ctx, real_streamlen) != CL_SUCCESS) {
535
+						rc = CL_CLEAN;
536
+						break;
537
+					}
534 538
 					continue;
535 539
 				} else
536 540
 					tableInsert(md5table, md5str, 1);
... ...
@@ -713,7 +712,7 @@ ascii85decode(const char *buf, off_t len, unsigned char *output)
713 713
 	int quintet = 0;
714 714
 	int ret = 0;
715 715
 
716
-	if(cli_pmemstr(buf, len, "~>", 2) == NULL)
716
+	if(cli_memstr(buf, len, "~>", 2) == NULL)
717 717
 		cli_dbgmsg("cli_pdf: ascii85decode: no EOF marker found\n");
718 718
 
719 719
 	ptr = buf;
... ...
@@ -842,45 +841,6 @@ pdf_nextobject(const char *ptr, size_t len)
842 842
 	return NULL;
843 843
 }
844 844
 
845
-/*
846
- * like cli_memstr - but returns the location of the match
847
- * FIXME: need a case insensitive version
848
- */
849
-static const char *
850
-cli_pmemstr(const char *haystack, size_t hs, const char *needle, size_t ns)
851
-{
852
-	const char *pt, *hay;
853
-	size_t n;
854
-
855
-	if(haystack == needle)
856
-		return haystack;
857
-
858
-	if(hs < ns)
859
-		return NULL;
860
-
861
-	if(memcmp(haystack, needle, ns) == 0)
862
-		return haystack;
863
-
864
-	pt = hay = haystack;
865
-	n = hs;
866
-
867
-	while((pt = memchr(hay, needle[0], n)) != NULL) {
868
-		n -= (size_t)(pt - hay);
869
-		if(n < ns)
870
-			break;
871
-
872
-		if(memcmp(pt, needle, ns) == 0)
873
-			return pt;
874
-
875
-		if(hay == pt) {
876
-			n--;
877
-			hay++;
878
-		} else
879
-			hay = pt;
880
-	}
881
-
882
-	return NULL;
883
-}
884 845
 #else	/*!HAVE_MMAP*/
885 846
 
886 847
 #include "clamav.h"
... ...
@@ -59,10 +59,6 @@
59 59
 #include "special.h"
60 60
 #include "ishield.h"
61 61
 
62
-#ifndef	O_BINARY
63
-#define	O_BINARY	0
64
-#endif
65
-
66 62
 #define DCONF ctx->dconf->pe
67 63
 
68 64
 #define IMAGE_DOS_SIGNATURE	    0x5a4d	    /* MZ */
... ...
@@ -928,8 +924,8 @@ int cli_scanpe(int desc, cli_ctx *ctx)
928 928
 		for(j = 0; j < md5_sect->soff_len && md5_sect->soff[j] <= exe_sections[i].rsz; j++) {
929 929
 		    if(md5_sect->soff[j] == exe_sections[i].rsz) {
930 930
 			unsigned char md5_dig[16];
931
-			if(cli_md5sect(desc, &exe_sections[i], md5_dig) && cli_bm_scanbuff(md5_dig, 16, ctx->virname, ctx->engine->md5_mdb, 0, -1) == CL_VIRUS) {
932
-			    if(cli_bm_scanbuff(md5_dig, 16, NULL, ctx->engine->md5_fp, 0, -1) != CL_VIRUS) {
931
+			if(cli_md5sect(desc, &exe_sections[i], md5_dig) && cli_bm_scanbuff(md5_dig, 16, ctx->virname, ctx->engine->md5_mdb, 0, -1, NULL) == CL_VIRUS) {
932
+			    if(cli_bm_scanbuff(md5_dig, 16, NULL, ctx->engine->md5_fp, 0, -1, NULL) != CL_VIRUS) {
933 933
 
934 934
 				free(section_hdr);
935 935
 				free(exe_sections);
... ...
@@ -322,9 +322,6 @@ static int build_regex(regex_t* preg,const char* regex,int nosub)
322 322
 	rc = cli_regcomp(preg,regex,REG_EXTENDED|REG_ICASE|(nosub ? REG_NOSUB :0));
323 323
 	if(rc) {
324 324
 
325
-#ifdef	C_WINDOWS
326
-		cli_errmsg("Phishcheck: Error in compiling regex, disabling phishing checks\n");
327
-#else
328 325
 		size_t buflen =	cli_regerror(rc,preg,NULL,0);
329 326
 		char *errbuf = cli_malloc(buflen);
330 327
 
... ...
@@ -334,7 +331,6 @@ static int build_regex(regex_t* preg,const char* regex,int nosub)
334 334
 			free(errbuf);
335 335
 		} else
336 336
 			cli_errmsg("Phishcheck: Error in compiling regex, disabling phishing checks. Additionally an Out-of-memory error was encountered while generating a detailed error message\n");
337
-#endif
338 337
 		return 1;
339 338
 	}
340 339
 	return CL_SUCCESS;
... ...
@@ -1198,13 +1194,13 @@ static int hash_match(const struct regex_matcher *rlist, const char *host, size_
1198 1198
 	    h[64]='\0';
1199 1199
 	    cli_dbgmsg("Looking up hash %s for %s(%u)%s(%u)\n", h, host, (unsigned)hlen, path, (unsigned)plen);
1200 1200
 	    if (prefix_matched) {
1201
-		if (cli_bm_scanbuff(sha256_dig, 4, &virname, &rlist->hostkey_prefix,0,-1) == CL_VIRUS) {
1201
+		if (cli_bm_scanbuff(sha256_dig, 4, &virname, &rlist->hostkey_prefix,0,-1,NULL) == CL_VIRUS) {
1202 1202
 		    cli_dbgmsg("prefix matched\n");
1203 1203
 		    *prefix_matched = 1;
1204 1204
 		} else
1205 1205
 		    return CL_SUCCESS;
1206 1206
 	    }
1207
-	    if (cli_bm_scanbuff(sha256_dig, 32, &virname, &rlist->sha256_hashes,0,-1) == CL_VIRUS) {
1207
+	    if (cli_bm_scanbuff(sha256_dig, 32, &virname, &rlist->sha256_hashes,0,-1,NULL) == CL_VIRUS) {
1208 1208
 		cli_dbgmsg("This hash matched: %s\n", h);
1209 1209
 		switch(*virname) {
1210 1210
 		    case 'W':
... ...
@@ -29,9 +29,7 @@
29 29
 #ifdef	HAVE_UNISTD_H
30 30
 #include <unistd.h>
31 31
 #endif
32
-#ifndef C_WINDOWS
33 32
 #include <dirent.h>
34
-#endif
35 33
 #include <sys/types.h>
36 34
 #include <sys/stat.h>
37 35
 #ifdef	HAVE_SYS_PARAM_H
... ...
@@ -57,6 +55,7 @@
57 57
 #include "readdb.h"
58 58
 #include "cltypes.h"
59 59
 #include "default.h"
60
+#include "md5.h"
60 61
 
61 62
 #include "phishcheck.h"
62 63
 #include "phish_whitelist.h"
... ...
@@ -77,17 +76,6 @@
77 77
 static pthread_mutex_t cli_ref_mutex = PTHREAD_MUTEX_INITIALIZER;
78 78
 #endif
79 79
 
80
-struct cli_ignsig {
81
-    char *dbname, *signame;
82
-    unsigned int line;
83
-    struct cli_ignsig *next;
84
-};
85
-
86
-struct cli_ignored {
87
-    struct cli_hashset hs;
88
-    struct cli_ignsig *list;
89
-};
90
-
91 80
 char *cli_virname(char *virname, unsigned int official)
92 81
 {
93 82
 	char *newname, *pt;
... ...
@@ -247,7 +235,7 @@ int cli_parse_add(struct cli_matcher *root, const char *virname, const char *hex
247 247
 	    free(pt);
248 248
 	}
249 249
 
250
-    } else if(root->ac_only || type || lsigid /* || (hexlen / 2 < CLI_DEFAULT_MOVETOAC_LEN) FIXME: unit tests */ ||  strpbrk(hexsig, "?(")) {
250
+    } else if(root->ac_only || type || lsigid || strpbrk(hexsig, "?(") || (root->bm_offmode && (!strcmp(offset, "*") || strchr(offset, ',')))) {
251 251
 	if((ret = cli_ac_addsig(root, virname, hexsig, 0, 0, 0, rtype, type, 0, 0, offset, lsigid, options))) {
252 252
 	    cli_errmsg("cli_parse_add(): Problem adding signature (3).\n");
253 253
 	    return ret;
... ...
@@ -324,7 +312,7 @@ static int cli_initroots(struct cl_engine *engine, unsigned int options)
324 324
 	    }
325 325
 	}
326 326
     }
327
-
327
+    engine->root[1]->bm_offmode = 1; /* BM offset mode for PE files */
328 328
     return CL_SUCCESS;
329 329
 }
330 330
 
... ...
@@ -411,22 +399,25 @@ char *cli_dbgets(char *buff, unsigned int size, FILE *fs, struct cli_dbio *dbio)
411 411
     }
412 412
 }
413 413
 
414
-static int cli_chkign(const struct cli_ignored *ignored, const char *dbname, unsigned int line, const char *signame)
414
+static int cli_chkign(const struct cli_matcher *ignored, const char *signame, const char *entry)
415 415
 {
416
-	struct cli_ignsig *pt;
416
+	const char *md5_expected = NULL;
417
+        cli_md5_ctx md5ctx;
418
+        unsigned char digest[16];
417 419
 
418
-    if(!ignored || !dbname || !signame)
420
+    if(!ignored || !signame || !entry)
419 421
 	return 0;
420 422
 
421
-    if(cli_hashset_contains(&ignored->hs, line)) {
422
-	pt = ignored->list;
423
-	while(pt) {
424
-	    if(pt->line == line && !strcmp(pt->dbname, dbname) && !strcmp(pt->signame, signame)) {
425
-		cli_dbgmsg("Skipping signature %s @ %s:%u\n", signame, dbname, line);
426
-		return 1;
427
-	    }
428
-	    pt = pt->next;
423
+    if(cli_bm_scanbuff(signame, strlen(signame), &md5_expected, ignored, 0, -1, NULL) == CL_VIRUS) {
424
+	if(md5_expected) {
425
+	    cli_md5_init(&md5ctx);
426
+            cli_md5_update(&md5ctx, entry, strlen(entry));
427
+	    cli_md5_final(digest, &md5ctx);
428
+	    if(memcmp(digest, (const unsigned char *) md5_expected, 16))
429
+		return 0;
429 430
 	}
431
+	cli_dbgmsg("Ignoring signature %s\n", signame);
432
+	return 1;
430 433
     }
431 434
 
432 435
     return 0;
... ...
@@ -470,7 +461,7 @@ static int cli_chkpua(const char *signame, const char *pua_cats, unsigned int op
470 470
 
471 471
 static int cli_loaddb(FILE *fs, struct cl_engine *engine, unsigned int *signo, unsigned int options, struct cli_dbio *dbio, const char *dbname)
472 472
 {
473
-	char buffer[FILEBUFF], *pt, *start;
473
+	char buffer[FILEBUFF], *buffer_cpy, *pt, *start;
474 474
 	unsigned int line = 0, sigs = 0;
475 475
 	int ret = 0;
476 476
 	struct cli_matcher *root;
... ...
@@ -481,9 +472,15 @@ static int cli_loaddb(FILE *fs, struct cl_engine *engine, unsigned int *signo, u
481 481
 
482 482
     root = engine->root[0];
483 483
 
484
+    if(engine->ignored)
485
+	if(!(buffer_cpy = cli_malloc(FILEBUFF)))
486
+	    return CL_EMEM;
487
+
484 488
     while(cli_dbgets(buffer, FILEBUFF, fs, dbio)) {
485 489
 	line++;
486 490
 	cli_chomp(buffer);
491
+	if(engine->ignored)
492
+	    strcpy(buffer_cpy, buffer);
487 493
 
488 494
 	pt = strchr(buffer, '=');
489 495
 	if(!pt) {
... ...
@@ -495,7 +492,7 @@ static int cli_loaddb(FILE *fs, struct cl_engine *engine, unsigned int *signo, u
495 495
 	start = buffer;
496 496
 	*pt++ = 0;
497 497
 
498
-	if(engine->ignored && cli_chkign(engine->ignored, dbname, line, start))
498
+	if(engine->ignored && cli_chkign(engine->ignored, start, buffer_cpy))
499 499
 	    continue;
500 500
 
501 501
 	if(*pt == '=') continue;
... ...
@@ -507,6 +504,9 @@ static int cli_loaddb(FILE *fs, struct cl_engine *engine, unsigned int *signo, u
507 507
 	sigs++;
508 508
     }
509 509
 
510
+    if(engine->ignored)
511
+	free(buffer_cpy);
512
+
510 513
     if(!line) {
511 514
 	cli_errmsg("Empty database file\n");
512 515
 	return CL_EMALFDB;
... ...
@@ -569,7 +569,7 @@ static int cli_loadpdb(FILE *fs, struct cl_engine *engine, unsigned int *signo,
569 569
 static int cli_loadndb(FILE *fs, struct cl_engine *engine, unsigned int *signo, unsigned short sdb, unsigned int options, struct cli_dbio *dbio, const char *dbname)
570 570
 {
571 571
 	const char *tokens[NDB_TOKENS + 1];
572
-	char buffer[FILEBUFF];
572
+	char buffer[FILEBUFF], *buffer_cpy;
573 573
 	const char *sig, *virname, *offset, *pt;
574 574
 	struct cli_matcher *root;
575 575
 	int line = 0, sigs = 0, ret = 0, tokens_count;
... ...
@@ -580,6 +580,10 @@ static int cli_loadndb(FILE *fs, struct cl_engine *engine, unsigned int *signo,
580 580
     if((ret = cli_initroots(engine, options)))
581 581
 	return ret;
582 582
 
583
+    if(engine->ignored)
584
+	if(!(buffer_cpy = cli_malloc(FILEBUFF)))
585
+	    return CL_EMEM;
586
+
583 587
     while(cli_dbgets(buffer, FILEBUFF, fs, dbio)) {
584 588
 	line++;
585 589
 
... ...
@@ -591,6 +595,8 @@ static int cli_loadndb(FILE *fs, struct cl_engine *engine, unsigned int *signo,
591 591
 		continue;
592 592
 
593 593
 	cli_chomp(buffer);
594
+	if(engine->ignored)
595
+	    strcpy(buffer_cpy, buffer);
594 596
 
595 597
 	tokens_count = cli_strtokenize(buffer, ':', NDB_TOKENS + 1, tokens);
596 598
 	/* FIXME: re-enable after fixing invalid sig @ main.ndb:53467 */
... ...
@@ -605,7 +611,7 @@ static int cli_loadndb(FILE *fs, struct cl_engine *engine, unsigned int *signo,
605 605
 	    if(cli_chkpua(virname, engine->pua_cats, options))
606 606
 		continue;
607 607
 
608
-	if(engine->ignored && cli_chkign(engine->ignored, dbname, line, virname))
608
+	if(engine->ignored && cli_chkign(engine->ignored, virname, buffer_cpy))
609 609
 	    continue;
610 610
 
611 611
 	if(tokens_count > 4) { /* min version */
... ...
@@ -656,6 +662,8 @@ static int cli_loadndb(FILE *fs, struct cl_engine *engine, unsigned int *signo,
656 656
 	}
657 657
 	sigs++;
658 658
     }
659
+    if(engine->ignored)
660
+	free(buffer_cpy);
659 661
 
660 662
     if(!line) {
661 663
 	cli_errmsg("Empty database file\n");
... ...
@@ -848,7 +856,7 @@ static int lsigattribs(char *attribs, struct cli_lsig_tdb *tdb)
848 848
   } while(0);
849 849
 
850 850
 #define LDB_TOKENS 67
851
-static int load_oneldb(char *buffer, int chkpua, int chkign, struct cl_engine *engine, unsigned int options, const char *dbname, unsigned line, unsigned *sigs, struct cli_bc *bc)
851
+static int load_oneldb(char *buffer, int chkpua, int chkign, struct cl_engine *engine, unsigned int options, const char *dbname, unsigned line, unsigned *sigs, struct cli_bc *bc, const char *buffer_cpy)
852 852
 {
853 853
     const char *sig, *virname, *offset, *logic;
854 854
     struct cli_ac_lsig **newtable, *lsig;
... ...
@@ -870,7 +878,7 @@ static int load_oneldb(char *buffer, int chkpua, int chkign, struct cl_engine *e
870 870
     if (chkpua && cli_chkpua(virname, engine->pua_cats, options))
871 871
 	    return CL_SUCCESS;
872 872
 
873
-    if (chkign && cli_chkign(engine->ignored, dbname, line, virname))
873
+    if (chkign && cli_chkign(engine->ignored, virname, buffer_cpy))
874 874
 	return CL_SUCCESS;
875 875
 
876 876
     subsigs = cli_ac_chklsig(logic, logic + strlen(logic), NULL, NULL, NULL, 1);
... ...
@@ -947,7 +955,7 @@ static int load_oneldb(char *buffer, int chkpua, int chkign, struct cl_engine *e
947 947
     root->ac_lsigtable = newtable;
948 948
 
949 949
     for(i = 0; i < subsigs; i++) {
950
-	if(i+3 >= tokens_count) {
950
+	if(i + 3 >= tokens_count) {
951 951
 	    cli_errmsg("cli_loadldb: Missing subsignature id %u\n", i);
952 952
 	    return CL_EMALFDB;
953 953
 	}
... ...
@@ -985,7 +993,7 @@ static int load_oneldb(char *buffer, int chkpua, int chkign, struct cl_engine *e
985 985
 
986 986
 static int cli_loadldb(FILE *fs, struct cl_engine *engine, unsigned int *signo, unsigned int options, struct cli_dbio *dbio, const char *dbname)
987 987
 {
988
-	char buffer[CLI_DEFAULT_LSIG_BUFSIZE + 1];
988
+	char buffer[CLI_DEFAULT_LSIG_BUFSIZE + 1], *buffer_cpy;
989 989
 	unsigned int line = 0, sigs = 0;
990 990
 	int ret;
991 991
 
... ...
@@ -993,18 +1001,25 @@ static int cli_loadldb(FILE *fs, struct cl_engine *engine, unsigned int *signo,
993 993
     if((ret = cli_initroots(engine, options)))
994 994
 	return ret;
995 995
 
996
+    if(engine->ignored)
997
+	if(!(buffer_cpy = cli_malloc(sizeof(buffer))))
998
+	    return CL_EMEM;
996 999
     while(cli_dbgets(buffer, sizeof(buffer), fs, dbio)) {
997 1000
 	line++;
998 1001
 	sigs++;
999 1002
 	cli_chomp(buffer);
1000 1003
 
1004
+	if(engine->ignored)
1005
+	    strcpy(buffer_cpy, buffer);
1001 1006
 	ret = load_oneldb(buffer,
1002 1007
 			  engine->pua_cats && (options & CL_DB_PUA_MODE) && (options & (CL_DB_PUA_INCLUDE | CL_DB_PUA_EXCLUDE)),
1003 1008
 			  !!engine->ignored,
1004
-			  engine, options, dbname, line, &sigs, NULL);
1009
+			  engine, options, dbname, line, &sigs, NULL, buffer_cpy);
1005 1010
 	if (ret)
1006 1011
 	    break;
1007 1012
     }
1013
+    if(engine->ignored)
1014
+	free(buffer_cpy);
1008 1015
 
1009 1016
     if(!line) {
1010 1017
 	cli_errmsg("Empty database file\n");
... ...
@@ -1050,7 +1065,7 @@ static int cli_loadcbc(FILE *fs, struct cl_engine *engine, unsigned int *signo,
1050 1050
     sigs += 2;/* the bytecode itself and the logical sig */
1051 1051
     if (bc->lsig) {
1052 1052
 	cli_dbgmsg("Bytecode %s has logical signature: %s\n", dbname, bc->lsig);
1053
-	rc = load_oneldb(bc->lsig, 0, 0, engine, options, dbname, 0, &sigs, bc);
1053
+	rc = load_oneldb(bc->lsig, 0, 0, engine, options, dbname, 0, &sigs, bc, NULL);
1054 1054
 	if (rc != CL_SUCCESS) {
1055 1055
 	    fprintf(stderr,"Problem parsing logical signature %s for bytecode %s: %s\n",
1056 1056
 		    bc->lsig, dbname, cl_strerror(rc));
... ...
@@ -1185,66 +1200,82 @@ static int cli_loadftm(FILE *fs, struct cl_engine *engine, unsigned int options,
1185 1185
     return CL_SUCCESS;
1186 1186
 }
1187 1187
 
1188
-#define IGN_TOKENS 3
1188
+#define IGN_MAX_TOKENS   3
1189 1189
 static int cli_loadign(FILE *fs, struct cl_engine *engine, unsigned int options, struct cli_dbio *dbio)
1190 1190
 {
1191
-	const char *tokens[IGN_TOKENS + 1];
1191
+	const char *tokens[IGN_MAX_TOKENS + 1], *signame, *hash = NULL;
1192 1192
 	char buffer[FILEBUFF];
1193
-	unsigned int line = 0, tokens_count;
1194
-	struct cli_ignsig *new;
1193
+	unsigned int line = 0, tokens_count, i, len;
1194
+        struct cli_bm_patt *new;
1195 1195
 	int ret = CL_SUCCESS;
1196 1196
 
1197
-
1198 1197
     if(!engine->ignored) {
1199
-	engine->ignored = (struct cli_ignored *) cli_calloc(sizeof(struct cli_ignored), 1);
1200
-	if(!engine->ignored || cli_hashset_init(&engine->ignored->hs, 64, 50))
1198
+	engine->ignored = (struct cli_matcher *) mpool_calloc(engine->mempool, 1, sizeof(struct cli_matcher));
1199
+	if(!engine->ignored)
1201 1200
 	    return CL_EMEM;
1201
+#ifdef USE_MPOOL
1202
+	engine->ignored->mempool = engine->mempool;
1203
+#endif
1204
+	if((ret = cli_bm_init(engine->ignored))) {
1205
+	    cli_errmsg("cli_loadign: Can't initialise AC pattern matcher\n");
1206
+	    return ret;
1207
+	}
1202 1208
     }
1203 1209
 
1204 1210
     while(cli_dbgets(buffer, FILEBUFF, fs, dbio)) {
1205 1211
 	line++;
1206 1212
 	cli_chomp(buffer);
1207
-	tokens_count = cli_strtokenize(buffer, ':', IGN_TOKENS + 1, tokens);
1208
-	if(tokens_count != IGN_TOKENS) {
1213
+
1214
+	tokens_count = cli_strtokenize(buffer, ':', IGN_MAX_TOKENS + 1, tokens);
1215
+	if(tokens_count > IGN_MAX_TOKENS) {
1209 1216
 	    ret = CL_EMALFDB;
1210 1217
 	    break;
1211 1218
 	}
1212 1219
 
1213
-	if(!cli_isnumber(tokens[1])) {
1214
-	    cli_errmsg("cli_loadign: Invalid entry for line number\n");
1220
+	if(tokens_count == 1) {
1221
+	    signame = buffer;
1222
+	} else if(tokens_count == 2) {
1223
+	    signame = tokens[0];
1224
+	    hash = tokens[1];
1225
+	} else { /* old mode */
1226
+	    signame = tokens[2];
1227
+	}
1228
+	if(!(len = strlen(signame))) {
1229
+	    cli_errmsg("cli_loadign: No signature name provided\n");
1215 1230
 	    ret = CL_EMALFDB;
1216 1231
 	    break;
1217 1232
 	}
1218 1233
 
1219
-	new = (struct cli_ignsig *) mpool_calloc(engine->mempool, 1, sizeof(struct cli_ignsig));
1234
+        new = (struct cli_bm_patt *) mpool_calloc(engine->mempool, 1, sizeof(struct cli_bm_patt));
1220 1235
 	if(!new) {
1221 1236
 	    ret = CL_EMEM;
1222 1237
 	    break;
1223 1238
 	}
1224
-
1225
-	new->dbname = cli_mpool_strdup(engine->mempool, tokens[0]);
1226
-
1227
-	if(!new->dbname) {
1239
+	new->pattern = cli_mpool_strdup(engine->mempool, signame);
1240
+	if(!new->pattern) {
1228 1241
 	    mpool_free(engine->mempool, new);
1229
-	    ret = CL_EMALFDB;
1242
+	    ret = CL_EMEM;
1230 1243
 	    break;
1231 1244
 	}
1245
+	if(hash) {
1246
+	    if(strlen(hash) != 32 || !(new->virname = (unsigned char *) cli_mpool_hex2str(engine->mempool, hash))) {
1247
+		cli_errmsg("cli_loadign: Malformed MD5 string at line %u\n", line);
1248
+		mpool_free(engine->mempool, new->pattern);
1249
+		mpool_free(engine->mempool, new);
1250
+		ret = CL_EMALFDB;
1251
+		break;
1252
+	    }
1253
+	}
1254
+	new->length = len;
1255
+	new->boundary |= BM_BOUNDARY_EOL;
1232 1256
 
1233
-	new->line = atoi(tokens[1]);
1234
-
1235
-	if((ret = cli_hashset_addkey(&engine->ignored->hs, new->line)))
1236
-	    break;
1237
-
1238
-	new->signame = cli_mpool_strdup(engine->mempool, tokens[2]);
1239
-	if(!new->signame) {
1240
-	    mpool_free(engine->mempool, new->dbname);
1257
+        if((ret = cli_bm_addpatt(engine->ignored, new, "0"))) {
1258
+	    if(hash)
1259
+		mpool_free(engine->mempool, new->virname);
1260
+	    mpool_free(engine->mempool, new->pattern);
1241 1261
 	    mpool_free(engine->mempool, new);
1242
-	    ret = CL_EMALFDB;
1243 1262
 	    break;
1244 1263
 	}
1245
-
1246
-	new->next = engine->ignored->list;
1247
-	engine->ignored->list = new;
1248 1264
     }
1249 1265
 
1250 1266
     if(ret) {
... ...
@@ -1255,25 +1286,6 @@ static int cli_loadign(FILE *fs, struct cl_engine *engine, unsigned int options,
1255 1255
     return CL_SUCCESS;
1256 1256
 }
1257 1257
 
1258
-static void cli_freeign(struct cl_engine *engine)
1259
-{
1260
-	struct cli_ignsig *pt;
1261
-	struct cli_ignored *ignored;
1262
-
1263
-    if((ignored = engine->ignored)) {
1264
-	while(ignored->list) {
1265
-	    pt = ignored->list;
1266
-	    ignored->list = ignored->list->next;
1267
-	    mpool_free(engine->mempool, pt->dbname);
1268
-	    mpool_free(engine->mempool, pt->signame);
1269
-	    mpool_free(engine->mempool,pt);
1270
-	}
1271
-	cli_hashset_destroy(&ignored->hs);
1272
-	free(engine->ignored);
1273
-	engine->ignored = NULL;
1274
-    }
1275
-}
1276
-
1277 1258
 static int scomp(const void *a, const void *b)
1278 1259
 {
1279 1260
     return *(const uint32_t *)a - *(const uint32_t *)b;
... ...
@@ -1322,7 +1334,7 @@ static int cli_md5db_init(struct cl_engine *engine, unsigned int mode)
1322 1322
 static int cli_loadmd5(FILE *fs, struct cl_engine *engine, unsigned int *signo, unsigned int mode, unsigned int options, struct cli_dbio *dbio, const char *dbname)
1323 1323
 {
1324 1324
 	const char *tokens[MD5_TOKENS + 1];
1325
-	char buffer[FILEBUFF];
1325
+	char buffer[FILEBUFF], *buffer_cpy;
1326 1326
 	const char *pt;
1327 1327
 	int ret = CL_SUCCESS;
1328 1328
 	unsigned int size_field = 1, md5_field = 0, line = 0, sigs = 0, tokens_count;
... ...
@@ -1336,9 +1348,16 @@ static int cli_loadmd5(FILE *fs, struct cl_engine *engine, unsigned int *signo,
1336 1336
 	md5_field = 1;
1337 1337
     }
1338 1338
 
1339
+    if(engine->ignored)
1340
+	if(!(buffer_cpy = cli_malloc(FILEBUFF)))
1341
+	    return CL_EMEM;
1342
+
1339 1343
     while(cli_dbgets(buffer, FILEBUFF, fs, dbio)) {
1340 1344
 	line++;
1341 1345
 	cli_chomp(buffer);
1346
+	if(engine->ignored)
1347
+	    strcpy(buffer_cpy, buffer);
1348
+
1342 1349
 	tokens_count = cli_strtokenize(buffer, ':', MD5_TOKENS + 1, tokens);
1343 1350
 	if(tokens_count != MD5_TOKENS) {
1344 1351
 	    ret = CL_EMALFDB;
... ...
@@ -1355,7 +1374,7 @@ static int cli_loadmd5(FILE *fs, struct cl_engine *engine, unsigned int *signo,
1355 1355
 	    if(cli_chkpua(pt, engine->pua_cats, options))
1356 1356
 		continue;
1357 1357
 
1358
-	if(engine->ignored && cli_chkign(engine->ignored, dbname, line, pt))
1358
+	if(engine->ignored && cli_chkign(engine->ignored, pt, buffer_cpy))
1359 1359
 	    continue;
1360 1360
 
1361 1361
 	new = (struct cli_bm_patt *) mpool_calloc(engine->mempool, 1, sizeof(struct cli_bm_patt));
... ...
@@ -1410,6 +1429,8 @@ static int cli_loadmd5(FILE *fs, struct cl_engine *engine, unsigned int *signo,
1410 1410
 
1411 1411
 	sigs++;
1412 1412
     }
1413
+    if(engine->ignored)
1414
+	free(buffer_cpy);
1413 1415
 
1414 1416
     if(!line) {
1415 1417
 	cli_errmsg("cli_loadmd5: Empty database file\n");
... ...
@@ -1431,18 +1452,25 @@ static int cli_loadmd5(FILE *fs, struct cl_engine *engine, unsigned int *signo,
1431 1431
 static int cli_loadmd(FILE *fs, struct cl_engine *engine, unsigned int *signo, int type, unsigned int options, struct cli_dbio *dbio, const char *dbname)
1432 1432
 {
1433 1433
 	const char *tokens[MD_TOKENS + 1];
1434
-	char buffer[FILEBUFF];
1434
+	char buffer[FILEBUFF], *buffer_cpy;
1435 1435
 	unsigned int line = 0, sigs = 0, tokens_count;
1436 1436
 	int ret = CL_SUCCESS, crc;
1437 1437
 	struct cli_meta_node *new;
1438 1438
 
1439 1439
 
1440
+    if(engine->ignored)
1441
+	if(!(buffer_cpy = cli_malloc(FILEBUFF)))
1442
+	    return CL_EMEM;
1443
+
1440 1444
     while(cli_dbgets(buffer, FILEBUFF, fs, dbio)) {
1441 1445
 	line++;
1442 1446
 	if(buffer[0] == '#')
1443 1447
 	    continue;
1444 1448
 
1445 1449
 	cli_chomp(buffer);
1450
+	if(engine->ignored)
1451
+	    strcpy(buffer_cpy, buffer);
1452
+
1446 1453
 	tokens_count = cli_strtokenize(buffer, ':', MD_TOKENS + 1, tokens);
1447 1454
 	if(tokens_count != MD_TOKENS) {
1448 1455
 	    ret = CL_EMALFDB;
... ...
@@ -1493,7 +1521,7 @@ static int cli_loadmd(FILE *fs, struct cl_engine *engine, unsigned int *signo, i
1493 1493
 	    break;
1494 1494
 	}
1495 1495
 
1496
-	if(engine->ignored && cli_chkign(engine->ignored, dbname, line, new->virname)) {
1496
+	if(engine->ignored && cli_chkign(engine->ignored, new->virname, buffer/*_cpy*/)) {
1497 1497
 	    mpool_free(engine->mempool, new->virname);
1498 1498
 	    mpool_free(engine->mempool, new);
1499 1499
 	    continue;
... ...
@@ -1559,6 +1587,8 @@ static int cli_loadmd(FILE *fs, struct cl_engine *engine, unsigned int *signo, i
1559 1559
 
1560 1560
 	sigs++;
1561 1561
     }
1562
+    if(engine->ignored)
1563
+	free(buffer_cpy);
1562 1564
 
1563 1565
     if(!line) {
1564 1566
 	cli_errmsg("Empty database file\n");
... ...
@@ -1599,13 +1629,7 @@ int cli_load(const char *filename, struct cl_engine *engine, unsigned int *signo
1599 1599
 	return CL_EOPEN;
1600 1600
     }
1601 1601
 
1602
-/*
1603
-#ifdef C_WINDOWS
1604
-    if((dbname = strrchr(filename, '\\')))
1605
-#else
1606
-*/
1607
-    if((dbname = strrchr(filename, '/')))
1608
-/*#endif */
1602
+    if((dbname = strrchr(filename, *PATHSEP)))
1609 1603
 	dbname++;
1610 1604
     else
1611 1605
 	dbname = filename;
... ...
@@ -1687,7 +1711,7 @@ int cli_load(const char *filename, struct cl_engine *engine, unsigned int *signo
1687 1687
     } else if(cli_strbcasestr(dbname, ".ftm")) {
1688 1688
 	ret = cli_loadftm(fs, engine, options, 0, dbio);
1689 1689
 
1690
-    } else if(cli_strbcasestr(dbname, ".ign")) {
1690
+    } else if(cli_strbcasestr(dbname, ".ign") || cli_strbcasestr(dbname, ".ign2")) {
1691 1691
 	ret = cli_loadign(fs, engine, options, dbio);
1692 1692
 
1693 1693
     } else {
... ...
@@ -1725,51 +1749,77 @@ static int cli_loaddbdir(const char *dirname, struct cl_engine *engine, unsigned
1725 1725
 
1726 1726
 
1727 1727
     cli_dbgmsg("Loading databases from %s\n", dirname);
1728
-    dbfile = (char *) cli_malloc(strlen(dirname) + 20);
1729
-    if(!dbfile)
1730
-	return CL_EMEM;
1731 1728
 
1732
-    /* try to load local.ign and daily.cvd/daily.ign first */
1733
-    sprintf(dbfile, "%s/local.ign", dirname);
1734
-    if(!access(dbfile, R_OK) && (ret = cli_load(dbfile, engine, signo, options, NULL))) {
1735
-	free(dbfile);
1736
-	return ret;
1729
+    if((dd = opendir(dirname)) == NULL) {
1730
+        cli_errmsg("cli_loaddbdir(): Can't open directory %s\n", dirname);
1731
+        return CL_EOPEN;
1737 1732
     }
1738 1733
 
1739
-    sprintf(dbfile, "%s/daily.cld", dirname);
1740
-    if(access(dbfile, R_OK))
1741
-	sprintf(dbfile, "%s/daily.cvd", dirname);
1742
-    if(!access(dbfile, R_OK) && (ret = cli_load(dbfile, engine, signo, options, NULL))) {
1743
-	free(dbfile);
1744
-	return ret;
1734
+    /* first round - load .ign and .ign2 files */
1735
+#ifdef HAVE_READDIR_R_3
1736
+    while(!readdir_r(dd, &result.d, &dent) && dent) {
1737
+#elif defined(HAVE_READDIR_R_2)
1738
+    while((dent = (struct dirent *) readdir_r(dd, &result.d))) {
1739
+#else
1740
+    while((dent = readdir(dd))) {
1741
+#endif
1742
+	if(dent->d_ino)
1743
+	{
1744
+	    if(cli_strbcasestr(dent->d_name, ".ign") || cli_strbcasestr(dent->d_name, ".ign2")) {
1745
+		dbfile = (char *) cli_malloc(strlen(dent->d_name) + strlen(dirname) + 2);
1746
+		if(!dbfile) {
1747
+		    cli_dbgmsg("cli_loaddbdir(): dbfile == NULL\n");
1748
+		    closedir(dd);
1749
+		    return CL_EMEM;
1750
+		}
1751
+		sprintf(dbfile, "%s"PATHSEP"%s", dirname, dent->d_name);
1752
+		ret = cli_load(dbfile, engine, signo, options, NULL);
1753
+		if(ret) {
1754
+		    cli_dbgmsg("cli_loaddbdir(): error loading database %s\n", dbfile);
1755
+		    free(dbfile);
1756
+		    closedir(dd);
1757
+		    return ret;
1758
+		}
1759
+		free(dbfile);
1760
+	    }
1761
+	}
1762
+    }
1763
+
1764
+    /* the daily db must be loaded before main */
1765
+    dbfile = (char *) cli_malloc(strlen(dirname) + 20);
1766
+    if(!dbfile) {
1767
+	closedir(dd);
1768
+	return CL_EMEM;
1745 1769
     }
1746 1770
 
1747
-    sprintf(dbfile, "%s/daily.ign", dirname);
1771
+    sprintf(dbfile, "%s"PATHSEP"daily.cld", dirname);
1772
+    if(access(dbfile, R_OK))
1773
+	sprintf(dbfile, "%s"PATHSEP"daily.cvd", dirname);
1748 1774
     if(!access(dbfile, R_OK) && (ret = cli_load(dbfile, engine, signo, options, NULL))) {
1749 1775
 	free(dbfile);
1776
+	closedir(dd);
1750 1777
 	return ret;
1751 1778
     }
1752 1779
 
1753 1780
     /* try to load local.gdb next */
1754
-    sprintf(dbfile, "%s/local.gdb", dirname);
1781
+    sprintf(dbfile, "%s"PATHSEP"local.gdb", dirname);
1755 1782
     if(!access(dbfile, R_OK) && (ret = cli_load(dbfile, engine, signo, options, NULL))) {
1756 1783
 	free(dbfile);
1784
+	closedir(dd);
1757 1785
 	return ret;
1758 1786
     }
1759 1787
 
1760 1788
     /* check for and load daily.cfg */
1761
-    sprintf(dbfile, "%s/daily.cfg", dirname);
1789
+    sprintf(dbfile, "%s"PATHSEP"daily.cfg", dirname);
1762 1790
     if(!access(dbfile, R_OK) && (ret = cli_load(dbfile, engine, signo, options, NULL))) {
1763 1791
 	free(dbfile);
1792
+	closedir(dd);
1764 1793
 	return ret;
1765 1794
     }
1766 1795
     free(dbfile);
1767 1796
 
1768
-    if((dd = opendir(dirname)) == NULL) {
1769
-        cli_errmsg("cli_loaddbdir(): Can't open directory %s\n", dirname);
1770
-        return CL_EOPEN;
1771
-    }
1772
-
1797
+    /* second round - load everything else */
1798
+    rewinddir(dd);
1773 1799
 #ifdef HAVE_READDIR_R_3
1774 1800
     while(!readdir_r(dd, &result.d, &dent) && dent) {
1775 1801
 #elif defined(HAVE_READDIR_R_2)
... ...
@@ -1777,22 +1827,17 @@ static int cli_loaddbdir(const char *dirname, struct cl_engine *engine, unsigned
1777 1777
 #else
1778 1778
     while((dent = readdir(dd))) {
1779 1779
 #endif
1780
-#if	(!defined(C_INTERIX)) && (!defined(C_WINDOWS))
1781 1780
 	if(dent->d_ino)
1782
-#endif
1783 1781
 	{
1784
-	    if(strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..") && strcmp(dent->d_name, "daily.cvd") && strcmp(dent->d_name, "daily.cld") && strcmp(dent->d_name, "daily.ign") && strcmp(dent->d_name, "daily.cfg") && strcmp(dent->d_name, "local.ign") && CLI_DBEXT(dent->d_name)) {
1785
-
1782
+	    if(strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..") && strcmp(dent->d_name, "daily.cvd") && strcmp(dent->d_name, "daily.cld") && strcmp(dent->d_name, "daily.cfg") && CLI_DBEXT(dent->d_name)) {
1786 1783
 		dbfile = (char *) cli_malloc(strlen(dent->d_name) + strlen(dirname) + 2);
1787
-
1788 1784
 		if(!dbfile) {
1789 1785
 		    cli_dbgmsg("cli_loaddbdir(): dbfile == NULL\n");
1790 1786
 		    closedir(dd);
1791 1787
 		    return CL_EMEM;
1792 1788
 		}
1793
-		sprintf(dbfile, "%s/%s", dirname, dent->d_name);
1789
+		sprintf(dbfile, "%s"PATHSEP"%s", dirname, dent->d_name);
1794 1790
 		ret = cli_load(dbfile, engine, signo, options, NULL);
1795
-
1796 1791
 		if(ret) {
1797 1792
 		    cli_dbgmsg("cli_loaddbdir(): error loading database %s\n", dbfile);
1798 1793
 		    free(dbfile);
... ...
@@ -1803,7 +1848,6 @@ static int cli_loaddbdir(const char *dirname, struct cl_engine *engine, unsigned
1803 1803
 	    }
1804 1804
 	}
1805 1805
     }
1806
-
1807 1806
     closedir(dd);
1808 1807
     if(ret == CL_EOPEN)
1809 1808
 	cli_errmsg("cli_loaddb(): No supported database files found in %s\n", dirname);
... ...
@@ -1903,9 +1947,7 @@ int cl_statinidir(const char *dirname, struct cl_stat *dbstat)
1903 1903
 #else
1904 1904
     while((dent = readdir(dd))) {
1905 1905
 #endif
1906
-#if	(!defined(C_INTERIX)) && (!defined(C_WINDOWS))
1907 1906
 	if(dent->d_ino)
1908
-#endif
1909 1907
 	{
1910 1908
 	    if(strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..") && CLI_DBEXT(dent->d_name)) {
1911 1909
 		dbstat->entries++;
... ...
@@ -1916,7 +1958,7 @@ int cl_statinidir(const char *dirname, struct cl_stat *dbstat)
1916 1916
 		    return CL_EMEM;
1917 1917
 		}
1918 1918
 
1919
-#if defined(C_INTERIX) || defined(C_OS2)
1919
+#ifdef _WIN32
1920 1920
 		dbstat->statdname = (char **) cli_realloc2(dbstat->statdname, dbstat->entries * sizeof(char *));
1921 1921
 		if(!dbstat->statdname) {
1922 1922
 		    cl_statfree(dbstat);
... ...
@@ -1931,8 +1973,8 @@ int cl_statinidir(const char *dirname, struct cl_stat *dbstat)
1931 1931
 		    closedir(dd);
1932 1932
 		    return CL_EMEM;
1933 1933
 		}
1934
-		sprintf(fname, "%s/%s", dirname, dent->d_name);
1935
-#if defined(C_INTERIX) || defined(C_OS2)
1934
+		sprintf(fname, "%s"PATHSEP"%s", dirname, dent->d_name);
1935
+#ifdef _WIN32
1936 1936
 		dbstat->statdname[dbstat->entries - 1] = (char *) cli_malloc(strlen(dent->d_name) + 1);
1937 1937
 		if(!dbstat->statdname[dbstat->entries - 1]) {
1938 1938
 		    cl_statfree(dbstat);
... ...
@@ -1986,9 +2028,7 @@ int cl_statchkdir(const struct cl_stat *dbstat)
1986 1986
 #else
1987 1987
     while((dent = readdir(dd))) {
1988 1988
 #endif
1989
-#if	(!defined(C_INTERIX)) && (!defined(C_WINDOWS))
1990 1989
 	if(dent->d_ino)
1991
-#endif
1992 1990
 	{
1993 1991
 	    if(strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..") && CLI_DBEXT(dent->d_name)) {
1994 1992
                 fname = cli_malloc(strlen(dbstat->dir) + strlen(dent->d_name) + 32);
... ...
@@ -1997,13 +2037,13 @@ int cl_statchkdir(const struct cl_stat *dbstat)
1997 1997
 		    return CL_EMEM;
1998 1998
 		}
1999 1999
 
2000
-		sprintf(fname, "%s/%s", dbstat->dir, dent->d_name);
2000
+		sprintf(fname, "%s"PATHSEP"%s", dbstat->dir, dent->d_name);
2001 2001
 		stat(fname, &sb);
2002 2002
 		free(fname);
2003 2003
 
2004 2004
 		found = 0;
2005 2005
 		for(i = 0; i < dbstat->entries; i++)
2006
-#if defined(C_INTERIX) || defined(C_OS2)
2006
+#ifdef _WIN32
2007 2007
 		    if(!strcmp(dbstat->statdname[i], dent->d_name)) {
2008 2008
 #else
2009 2009
 		    if(dbstat->stattab[i].st_ino == sb.st_ino) {
... ...
@@ -2032,7 +2072,7 @@ int cl_statfree(struct cl_stat *dbstat)
2032 2032
 
2033 2033
     if(dbstat) {
2034 2034
 
2035
-#if defined(C_INTERIX) || defined(C_OS2)
2035
+#ifdef _WIN32
2036 2036
 	    int i;
2037 2037
 
2038 2038
 	if(dbstat->statdname) {
... ...
@@ -2172,7 +2212,11 @@ int cl_engine_free(struct cl_engine *engine)
2172 2172
 	mpool_free(engine->mempool, engine->tmpdir);
2173 2173
 
2174 2174
     cli_ftfree(engine);
2175
-    cli_freeign(engine);
2175
+    if(engine->ignored) {
2176
+	cli_bm_free(engine->ignored);
2177
+	mpool_free(engine->mempool, engine->ignored);
2178
+    }
2179
+
2176 2180
 #ifdef USE_MPOOL
2177 2181
     if(engine->mempool) mpool_destroy(engine->mempool);
2178 2182
 #endif
... ...
@@ -2199,7 +2243,7 @@ static void cli_md5db_build(struct cli_matcher* root)
2199 2199
 		root->soff_len = cli_hashset_toarray(&root->md5_sizes_hs, &root->soff);
2200 2200
 #endif
2201 2201
 		cli_hashset_destroy(&root->md5_sizes_hs);
2202
-		qsort(root->soff, root->soff_len, sizeof(uint32_t), scomp);
2202
+		cli_qsort(root->soff, root->soff_len, sizeof(uint32_t), scomp);
2203 2203
 	}
2204 2204
 }
2205 2205
 
... ...
@@ -2232,7 +2276,11 @@ int cl_engine_compile(struct cl_engine *engine)
2232 2232
 	    return ret;
2233 2233
     }
2234 2234
     cli_md5db_build(engine->md5_mdb);
2235
-    cli_freeign(engine);
2235
+    if(engine->ignored) {
2236
+	cli_bm_free(engine->ignored);
2237
+	mpool_free(engine->mempool, engine->ignored);
2238
+	engine->ignored = NULL;
2239
+    }
2236 2240
     cli_dconf_print(engine->dconf);
2237 2241
     mpool_flush(engine->mempool);
2238 2242
 
... ...
@@ -49,7 +49,6 @@
49 49
 	cli_strbcasestr(ext, ".wdb")   ||	\
50 50
 	cli_strbcasestr(ext, ".cbc")   ||	\
51 51
 	cli_strbcasestr(ext, ".ftm")   ||	\
52
-	cli_strbcasestr(ext, ".ign")   ||	\
53 52
 	cli_strbcasestr(ext, ".cfg")   ||	\
54 53
 	cli_strbcasestr(ext, ".cvd")   ||	\
55 54
 	cli_strbcasestr(ext, ".cld")		\
... ...
@@ -455,7 +455,7 @@ static int add_hash(struct regex_matcher *matcher, char* pattern, const char fl,
455 455
 
456 456
 	if (fl != 'W' && pat->length == 32 &&
457 457
 	    cli_hashset_contains(&matcher->sha256_pfx_set, cli_readint32(pat->pattern)) &&
458
-	    cli_bm_scanbuff(pat->pattern, 32, &vname, &matcher->sha256_hashes,0,-1) == CL_VIRUS) {
458
+	    cli_bm_scanbuff(pat->pattern, 32, &vname, &matcher->sha256_hashes,0,-1,NULL) == CL_VIRUS) {
459 459
 	    if (*vname == 'W') {
460 460
 		/* hash is whitelisted in local.gdb */
461 461
 		cli_dbgmsg("Skipping hash %s\n", pattern);
... ...
@@ -35,22 +35,7 @@
35 35
 #include <sys/param.h>
36 36
 #endif
37 37
 #include <fcntl.h>
38
-#ifndef	C_WINDOWS
39 38
 #include <dirent.h>
40
-#include <netinet/in.h>
41
-#endif
42
-
43
-#if HAVE_MMAP
44
-#if HAVE_SYS_MMAN_H
45
-#include <sys/mman.h>
46
-#else /* HAVE_SYS_MMAN_H */
47
-#undef HAVE_MMAP
48
-#endif
49
-#endif
50
-
51
-#ifndef	O_BINARY
52
-#define	O_BINARY	0
53
-#endif
54 39
 
55 40
 #define DCONF_ARCH  ctx->dconf->archive
56 41
 #define DCONF_DOC   ctx->dconf->doc
... ...
@@ -108,7 +93,7 @@
108 108
 
109 109
 static int cli_scanfile(const char *filename, cli_ctx *ctx);
110 110
 
111
-static int cli_scandir(const char *dirname, cli_ctx *ctx, cli_file_t container)
111
+static int cli_scandir(const char *dirname, cli_ctx *ctx)
112 112
 {
113 113
 	DIR *dd;
114 114
 	struct dirent *dent;
... ...
@@ -120,8 +105,6 @@ static int cli_scandir(const char *dirname, cli_ctx *ctx, cli_file_t container)
120 120
 #endif
121 121
 	struct stat statbuf;
122 122
 	char *fname;
123
-	int fd, ret = CL_CLEAN;
124
-	cli_file_t ftype;
125 123
 
126 124
 
127 125
     if((dd = opendir(dirname)) != NULL) {
... ...
@@ -132,9 +115,7 @@ static int cli_scandir(const char *dirname, cli_ctx *ctx, cli_file_t container)
132 132
 #else
133 133
 	while((dent = readdir(dd))) {
134 134
 #endif
135
-#if	(!defined(C_INTERIX)) && (!defined(C_WINDOWS))
136 135
 	    if(dent->d_ino)
137
-#endif
138 136
 	    {
139 137
 		if(strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..")) {
140 138
 		    /* build the full name */
... ...
@@ -144,12 +125,12 @@ static int cli_scandir(const char *dirname, cli_ctx *ctx, cli_file_t container)
144 144
 			return CL_EMEM;
145 145
 		    }
146 146
 
147
-		    sprintf(fname, "%s/%s", dirname, dent->d_name);
147
+		    sprintf(fname, "%s"PATHSEP"%s", dirname, dent->d_name);
148 148
 
149 149
 		    /* stat the file */
150 150
 		    if(lstat(fname, &statbuf) != -1) {
151 151
 			if(S_ISDIR(statbuf.st_mode) && !S_ISLNK(statbuf.st_mode)) {
152
-			    if(cli_scandir(fname, ctx, container) == CL_VIRUS) {
152
+			    if(cli_scandir(fname, ctx) == CL_VIRUS) {
153 153
 				free(fname);
154 154
 				closedir(dd);
155 155
 				return CL_VIRUS;
... ...
@@ -161,27 +142,6 @@ static int cli_scandir(const char *dirname, cli_ctx *ctx, cli_file_t container)
161 161
 				    closedir(dd);
162 162
 				    return CL_VIRUS;
163 163
 				}
164
-
165
-				if(container == CL_TYPE_MAIL) {
166
-				    fd = open(fname, O_RDONLY|O_BINARY);
167
-				    if(fd == -1) {
168
-					    char err[128];
169
-					    cli_warnmsg("Cannot open file %s: %s, mode: %x\n", fname, cli_strerror(errno, err, sizeof(err)), statbuf.st_mode);
170
-					    free(fname);
171
-					    continue;
172
-				    }
173
-				    ftype = cli_filetype2(fd, ctx->engine);
174
-				    if(ftype >= CL_TYPE_TEXT_ASCII && ftype <= CL_TYPE_TEXT_UTF16BE) {
175
-					lseek(fd, 0, SEEK_SET);
176
-					ret = cli_scandesc(fd, ctx, CL_TYPE_MAIL, 0, NULL, AC_SCAN_VIR);
177
-				    }
178
-				    close(fd);
179
-				    if(ret == CL_VIRUS) {
180
-					free(fname);
181
-					closedir(dd);
182
-					return CL_VIRUS;
183
-				    }
184
-				}
185 164
 			    }
186 165
 			}
187 166
 		    }
... ...
@@ -365,7 +325,7 @@ static int cli_scanrar(int desc, cli_ctx *ctx, off_t sfx_offset, uint32_t *sfx_c
365 365
 
366 366
     metadata = metadata_tmp = rar_state.metadata; 
367 367
 
368
-    if(cli_scandir(rar_state.comment_dir, ctx, 0) == CL_VIRUS)
368
+    if(cli_scandir(rar_state.comment_dir, ctx) == CL_VIRUS)
369 369
 	ret = CL_VIRUS;
370 370
 
371 371
     cli_unrar_close(&rar_state);
... ...
@@ -781,7 +741,7 @@ static int cli_vba_scandir(const char *dirname, cli_ctx *ctx, struct uniq *U)
781 781
 
782 782
 	for(i = 0; i < vba_project->count; i++) {
783 783
 	    for(j = 0; (unsigned int)j < vba_project->colls[i]; j++) {
784
-		snprintf(vbaname, 1024, "%s/%s_%u", vba_project->dir, vba_project->name[i], j);
784
+		snprintf(vbaname, 1024, "%s"PATHSEP"%s_%u", vba_project->dir, vba_project->name[i], j);
785 785
 		vbaname[sizeof(vbaname)-1] = '\0';
786 786
 		fd = open(vbaname, O_RDONLY|O_BINARY);
787 787
 		if(fd == -1) continue;
... ...
@@ -815,12 +775,12 @@ static int cli_vba_scandir(const char *dirname, cli_ctx *ctx, struct uniq *U)
815 815
 
816 816
     if(ret == CL_CLEAN && (hashcnt = uniq_get(U, "powerpoint document", 19, &hash))) {
817 817
 	while(hashcnt--) {
818
-	    snprintf(vbaname, 1024, "%s/%s_%u", dirname, hash, hashcnt);
818
+	    snprintf(vbaname, 1024, "%s"PATHSEP"%s_%u", dirname, hash, hashcnt);
819 819
 	    vbaname[sizeof(vbaname)-1] = '\0';
820 820
 	    fd = open(vbaname, O_RDONLY|O_BINARY);
821 821
 	    if (fd == -1) continue;
822 822
 	    if ((fullname = cli_ppt_vba_read(fd, ctx))) {
823
-		if(cli_scandir(fullname, ctx, 0) == CL_VIRUS) {
823
+		if(cli_scandir(fullname, ctx) == CL_VIRUS) {
824 824
 		    ret = CL_VIRUS;
825 825
 		}
826 826
 		if(!ctx->engine->keeptmp)
... ...
@@ -833,7 +793,7 @@ static int cli_vba_scandir(const char *dirname, cli_ctx *ctx, struct uniq *U)
833 833
 
834 834
     if (ret == CL_CLEAN && (hashcnt = uniq_get(U, "worddocument", 12, &hash))) {
835 835
 	while(hashcnt--) {
836
-	    snprintf(vbaname, sizeof(vbaname), "%s/%s_%u", dirname, hash, hashcnt);
836
+	    snprintf(vbaname, sizeof(vbaname), "%s"PATHSEP"%s_%u", dirname, hash, hashcnt);
837 837
 	    vbaname[sizeof(vbaname)-1] = '\0';
838 838
 	    fd = open(vbaname, O_RDONLY|O_BINARY);
839 839
 	    if (fd == -1) continue;
... ...
@@ -880,7 +840,7 @@ static int cli_vba_scandir(const char *dirname, cli_ctx *ctx, struct uniq *U)
880 880
     /* Check directory for embedded OLE objects */
881 881
     hashcnt = uniq_get(U, "_1_ole10native", 14, &hash);
882 882
     while(hashcnt--) {
883
-	snprintf(vbaname, sizeof(vbaname), "%s/%s_%u", dirname, hash, hashcnt);
883
+	snprintf(vbaname, sizeof(vbaname), "%s"PATHSEP"%s_%u", dirname, hash, hashcnt);
884 884
 	vbaname[sizeof(vbaname)-1] = '\0';
885 885
 
886 886
 	fd = open(vbaname, O_RDONLY|O_BINARY);
... ...
@@ -905,9 +865,7 @@ static int cli_vba_scandir(const char *dirname, cli_ctx *ctx, struct uniq *U)
905 905
 #else
906 906
 	while((dent = readdir(dd))) {
907 907
 #endif
908
-#if	(!defined(C_INTERIX)) && (!defined(C_WINDOWS))
909 908
 	    if(dent->d_ino)
910
-#endif
911 909
 	    {
912 910
 		if(strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..")) {
913 911
 		    /* build the full name */
... ...
@@ -916,7 +874,7 @@ static int cli_vba_scandir(const char *dirname, cli_ctx *ctx, struct uniq *U)
916 916
 			ret = CL_EMEM;
917 917
 			break;
918 918
 		    }
919
-		    sprintf(fullname, "%s/%s", dirname, dent->d_name);
919
+		    sprintf(fullname, "%s"PATHSEP"%s", dirname, dent->d_name);
920 920
 
921 921
 		    /* stat the file */
922 922
 		    if(lstat(fullname, &statbuf) != -1) {
... ...
@@ -974,7 +932,7 @@ static int cli_scanhtml(int desc, cli_ctx *ctx)
974 974
     cli_dbgmsg("cli_scanhtml: using tempdir %s\n", tempname);
975 975
 
976 976
     html_normalise_fd(desc, tempname, NULL, ctx->dconf);
977
-    snprintf(fullname, 1024, "%s/nocomment.html", tempname);
977
+    snprintf(fullname, 1024, "%s"PATHSEP"nocomment.html", tempname);
978 978
     fd = open(fullname, O_RDONLY|O_BINARY);
979 979
     if (fd >= 0) {
980 980
 	    ret = cli_scandesc(fd, ctx, CL_TYPE_HTML, 0, NULL, AC_SCAN_VIR);
... ...
@@ -984,7 +942,7 @@ static int cli_scanhtml(int desc, cli_ctx *ctx)
984 984
     if(ret == CL_CLEAN && sb.st_size < 2097152) {
985 985
 	    /* limit to 2 MB, we're not interesting in scanning large files in notags form */
986 986
 	    /* TODO: don't even create notags if file is over 2 MB */
987
-	    snprintf(fullname, 1024, "%s/notags.html", tempname);
987
+	    snprintf(fullname, 1024, "%s"PATHSEP"notags.html", tempname);
988 988
 	    fd = open(fullname, O_RDONLY|O_BINARY);
989 989
 	    if(fd >= 0) {
990 990
 		    ret = cli_scandesc(fd, ctx, CL_TYPE_HTML, 0, NULL, AC_SCAN_VIR);
... ...
@@ -993,7 +951,7 @@ static int cli_scanhtml(int desc, cli_ctx *ctx)
993 993
     }
994 994
 
995 995
     if(ret == CL_CLEAN) {
996
-	    snprintf(fullname, 1024, "%s/javascript", tempname);
996
+	    snprintf(fullname, 1024, "%s"PATHSEP"javascript", tempname);
997 997
 	    fd = open(fullname, O_RDONLY|O_BINARY);
998 998
 	    if(fd >= 0) {
999 999
 		    ret = cli_scandesc(fd, ctx, CL_TYPE_HTML, 0, NULL, AC_SCAN_VIR);
... ...
@@ -1006,8 +964,8 @@ static int cli_scanhtml(int desc, cli_ctx *ctx)
1006 1006
     }
1007 1007
 
1008 1008
     if (ret == CL_CLEAN) {
1009
-	snprintf(fullname, 1024, "%s/rfc2397", tempname);
1010
-	ret = cli_scandir(fullname, ctx, 0);
1009
+	snprintf(fullname, 1024, "%s"PATHSEP"rfc2397", tempname);
1010
+	ret = cli_scandir(fullname, ctx);
1011 1011
     }
1012 1012
 
1013 1013
     if(!ctx->engine->keeptmp)
... ...
@@ -1139,9 +1097,9 @@ static int cli_scanhtml_utf16(int desc, cli_ctx *ctx)
1139 1139
 	    if(write(fd, decoded, strlen(decoded)) == -1) {
1140 1140
 		cli_errmsg("cli_scanhtml_utf16: Can't write to file %s\n", tempname);
1141 1141
 		free(decoded);
1142
+		close(fd);
1142 1143
 		cli_unlink(tempname);
1143 1144
 		free(tempname);
1144
-		close(fd);
1145 1145
 		return CL_EWRITE;
1146 1146
 	    }
1147 1147
 	    free(decoded);
... ...
@@ -1197,7 +1155,7 @@ static int cli_scanole2(int desc, cli_ctx *ctx)
1197 1197
 	ret = cli_vba_scandir(dir, ctx, vba);
1198 1198
 	uniq_free(vba);
1199 1199
 	if(ret != CL_VIRUS)
1200
-	    if(cli_scandir(dir, ctx, 0) == CL_VIRUS)
1200
+	    if(cli_scandir(dir, ctx) == CL_VIRUS)
1201 1201
 	        ret = CL_VIRUS;
1202 1202
 	ctx->recursion--;
1203 1203
     }
... ...
@@ -1256,7 +1214,7 @@ static int cli_scanbinhex(int desc, cli_ctx *ctx)
1256 1256
     if((ret = cli_binhex(dir, desc)))
1257 1257
 	cli_dbgmsg("Binhex: %s\n", cl_strerror(ret));
1258 1258
     else
1259
-	ret = cli_scandir(dir, ctx, 0);
1259
+	ret = cli_scandir(dir, ctx);
1260 1260
 
1261 1261
     if(!ctx->engine->keeptmp)
1262 1262
 	cli_rmdirs(dir);
... ...
@@ -1342,7 +1300,7 @@ static int cli_scanscrenc(int desc, cli_ctx *ctx)
1342 1342
     }
1343 1343
 
1344 1344
     if (html_screnc_decode(desc, tempname))
1345
-	ret = cli_scandir(tempname, ctx, 0);
1345
+	ret = cli_scandir(tempname, ctx);
1346 1346
 
1347 1347
     if(!ctx->engine->keeptmp)
1348 1348
 	cli_rmdirs(tempname);
... ...
@@ -1504,7 +1462,7 @@ static int cli_scantnef(int desc, cli_ctx *ctx)
1504 1504
     ret = cli_tnef(dir, desc, ctx);
1505 1505
 
1506 1506
     if(ret == CL_CLEAN)
1507
-	ret = cli_scandir(dir, ctx, 0);
1507
+	ret = cli_scandir(dir, ctx);
1508 1508
 
1509 1509
     if(!ctx->engine->keeptmp)
1510 1510
 	cli_rmdirs(dir);
... ...
@@ -1530,7 +1488,7 @@ static int cli_scanuuencoded(int desc, cli_ctx *ctx)
1530 1530
     ret = cli_uuencode(dir, desc);
1531 1531
 
1532 1532
     if(ret == CL_CLEAN)
1533
-	ret = cli_scandir(dir, ctx, 0);
1533
+	ret = cli_scandir(dir, ctx);
1534 1534
 
1535 1535
     if(!ctx->engine->keeptmp)
1536 1536
 	cli_rmdirs(dir);
... ...
@@ -1567,7 +1525,9 @@ static int cli_scanmail(int desc, cli_ctx *ctx)
1567 1567
 	return ret;
1568 1568
     }
1569 1569
 
1570
-    ret = cli_scandir(dir, ctx, CL_TYPE_MAIL);
1570
+    ctx->container_type = CL_TYPE_MAIL;
1571
+    ret = cli_scandir(dir, ctx);
1572
+    ctx->container_type = 0;
1571 1573
 
1572 1574
     if(!ctx->engine->keeptmp)
1573 1575
 	cli_rmdirs(dir);
... ...
@@ -1881,6 +1841,7 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx)
1881 1881
 	cli_file_t type, dettype = 0;
1882 1882
 	struct stat sb;
1883 1883
 	uint8_t typercg = 1;
1884
+	cli_file_t current_container = ctx->container_type; /* TODO: container tracking code TBD - bb#1293 */
1884 1885
 
1885 1886
     if(ctx->engine->maxreclevel && ctx->recursion > ctx->engine->maxreclevel) {
1886 1887
         cli_dbgmsg("cli_magic_scandesc: Archive recursion limit exceeded (%u, max: %u)\n", ctx->recursion, ctx->engine->maxreclevel);
... ...
@@ -1934,8 +1895,8 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx)
1934 1934
 	lseek(desc, 0, SEEK_SET);
1935 1935
     }
1936 1936
 
1937
+    ctx->container_type = 0;
1937 1938
     ctx->recursion++;
1938
-
1939 1939
     switch(type) {
1940 1940
 	case CL_TYPE_IGNORED:
1941 1941
 	    break;
... ...
@@ -2131,6 +2092,7 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx)
2131 2131
 	    break;
2132 2132
     }
2133 2133
     ctx->recursion--;
2134
+    ctx->container_type = current_container;
2134 2135
 
2135 2136
     if(ret == CL_VIRUS)
2136 2137
 	return CL_VIRUS;
... ...
@@ -2157,6 +2119,10 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx)
2157 2157
 	case CL_TYPE_TEXT_UTF8:
2158 2158
 	    if((DCONF_DOC & DOC_CONF_SCRIPT) && dettype != CL_TYPE_HTML)
2159 2159
 	        ret = cli_scanscript(desc, ctx);
2160
+	    if(ret != CL_VIRUS && ctx->container_type == CL_TYPE_MAIL) {
2161
+		lseek(desc, 0, SEEK_SET);
2162
+		ret = cli_scandesc(desc, ctx, CL_TYPE_MAIL, 0, NULL, AC_SCAN_VIR);
2163
+	    }
2160 2164
 	    break;
2161 2165
 	/* Due to performance reasons all executables were first scanned
2162 2166
 	 * in raw mode. Now we will try to unpack them
... ...
@@ -2194,6 +2160,7 @@ int cl_scandesc(int desc, const char **virname, unsigned long int *scanned, cons
2194 2194
     ctx.scanned = scanned;
2195 2195
     ctx.options = scanoptions;
2196 2196
     ctx.found_possibly_unwanted = 0;
2197
+    ctx.container_type = 0;
2197 2198
     ctx.dconf = (struct cli_dconf *) engine->dconf;
2198 2199
 
2199 2200
     rc = cli_magic_scandesc(desc, &ctx);
... ...
@@ -46,11 +46,6 @@
46 46
 #define EC32(x) le32_to_host(x)
47 47
 #define EC16(x) le16_to_host(x)
48 48
 
49
-#ifndef O_BINARY
50
-#define O_BINARY 0
51
-#endif
52
-
53
-
54 49
 static int real_scansis(FILE *, cli_ctx *, const char *);
55 50
 static int real_scansis9x(FILE *, cli_ctx *, const char *);
56 51
 
... ...
@@ -175,7 +170,7 @@ enum {
175 175
 #define SKIP(N) \
176 176
   if (sleft>=(N)) sleft-=(N); \
177 177
   else { \
178
-    if ((ssize_t)((N)-sleft)<0) { \
178
+    if ((N) < sleft) { \
179 179
       cli_dbgmsg("SIS: Refusing to seek back\n"); \
180 180
       free(alangs); \
181 181
       return CL_CLEAN; \
... ...
@@ -497,7 +492,7 @@ static int real_scansis(FILE *f, cli_ctx *ctx, const char *tmpd) {
497 497
 	    olen = lens[j];
498 498
 	    decomp = comp;
499 499
 	  }
500
-	  snprintf(ofn, 1024, "%s/sis%02d", tmpd, umped);
500
+	  snprintf(ofn, 1024, "%s"PATHSEP"sis%02d", tmpd, umped);
501 501
 	  ofn[1023]='\0';
502 502
 	  if ((fd=open(ofn, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, 0600))==-1) {
503 503
 	    cli_errmsg("SIS: unable to create output file %s - aborting.", ofn);
... ...
@@ -714,7 +709,7 @@ static int real_scansis9x(FILE *f, cli_ctx *ctx, const char *tmpd) {
714 714
 	      if(getfield(s, &field) || field!=T_COMPRESSED || getd(s, &field) || getd(s, &usize) || getd(s, &usizeh) || usizeh) break;
715 715
 	      s->fsize[s->level]-=12;
716 716
 	      cli_dbgmsg("SIS: File is%s compressed - size %x -> %x\n", (field)?"":" not", s->fsize[s->level], usize);
717
-	      snprintf(tempf, 1024, "%s/sis9x%02d", tmpd, i++);
717
+	      snprintf(tempf, 1024, "%s"PATHSEP"sis9x%02d", tmpd, i++);
718 718
 	      tempf[1023]='\0';
719 719
 	      fseek(s->f, -(long)s->sleft, SEEK_CUR);
720 720
 	      s->sleft = s->smax = 0;
... ...
@@ -18,11 +18,9 @@
18 18
  *  MA 02110-1301, USA.
19 19
  */
20 20
 
21
-#ifdef	_MSC_VER
22
-#include <windows.h>
23
-#endif
24
-
21
+#if HAVE_CONFIG_H
25 22
 #include "clamav-config.h"
23
+#endif
26 24
 
27 25
 #include <sys/types.h>
28 26
 #include <sys/stat.h>
... ...
@@ -30,11 +28,11 @@
30 30
 #ifdef	HAVE_UNISTD_H
31 31
 #include <unistd.h>
32 32
 #endif
33
-#ifndef	C_WINDOWS
34
-#include <netinet/in.h>
35
-#endif
36 33
 #include <string.h>
37 34
 #include <ctype.h>
35
+#ifndef _WIN32
36
+#include <netinet/in.h>
37
+#endif
38 38
 #include "clamav.h"
39 39
 #include "others.h"
40 40
 #include "cltypes.h"
... ...
@@ -92,7 +92,7 @@ int cli_realhex2ui(const char *hex, uint16_t *ptr, unsigned int len) {
92 92
 	    val |= CLI_MATCH_NIBBLE_LOW;
93 93
 
94 94
 	} else if(hex[i] == '(') {
95
-	    val |= CLI_MATCH_ALTERNATIVE;
95
+	    val |= CLI_MATCH_SPECIAL;
96 96
 
97 97
 	} else {
98 98
 	    if((c = cli_hex2int(hex[i])) >= 0) {
... ...
@@ -369,37 +369,33 @@ char *cli_strtokbuf(const char *input, int fieldno, const char *delim, char *out
369 369
     return output;
370 370
 }
371 371
 
372
-const char *cli_memstr(const char *haystack, int hs, const char *needle, int ns)
372
+const char *cli_memstr(const char *haystack, unsigned int hs, const char *needle, unsigned int ns)
373 373
 {
374
-	const char *pt, *hay;
375
-	int n;
374
+	unsigned int i, s1, s2;
376 375
 
377
-
378
-    if(hs < ns)
376
+    if(!hs || !ns || hs < ns)
379 377
 	return NULL;
380 378
 
381
-    if(haystack == needle)
382
-	return haystack;
383
-
384
-    if(!memcmp(haystack, needle, ns))
379
+    if(needle == haystack)
385 380
 	return haystack;
386 381
 
387
-    pt = hay = haystack;
388
-    n = hs;
382
+    if(ns == 1)
383
+	return memchr(haystack, needle[0], hs);
389 384
 
390
-    while((pt = memchr(hay, needle[0], n)) != NULL) {
391
-	n -= (int) (pt - hay);
392
-	if(n < ns)
393
-	    break;
394
-
395
-	if(!memcmp(pt, needle, ns))
396
-	    return pt;
397
-
398
-	if(hay == pt) {
399
-	    n--;
400
-	    hay++;
385
+    if(needle[0] == needle[1]) {
386
+	s1 = 2;
387
+	s2 = 1;
388
+    } else {
389
+	s1 = 1;
390
+	s2 = 2;
391
+    }
392
+    for(i = 0; i <= hs - ns; ) {
393
+	if(needle[1] != haystack[i + 1]) {
394
+	    i += s1;
401 395
 	} else {
402
-	    hay = pt;
396
+	    if((needle[0] == haystack[i]) && !memcmp(needle + 2, haystack + i + 2, ns - 2))
397
+		return &haystack[i];
398
+	    i += s2;
403 399
 	}
404 400
     }
405 401
 
... ...
@@ -42,7 +42,7 @@ int cli_hex2num(const char *hex);
42 42
 char *cli_str2hex(const char *string, unsigned int len);
43 43
 char *cli_utf16toascii(const char *str, unsigned int length);
44 44
 char *cli_strtokbuf(const char *input, int fieldno, const char *delim, char *output);
45
-const char *cli_memstr(const char *haystack, int hs, const char *needle, int ns);
45
+const char *cli_memstr(const char *haystack, unsigned int hs, const char *needle, unsigned int ns);
46 46
 char *cli_strrcpy(char *dest, const char *source);
47 47
 size_t cli_strtokenize(char *buffer, const char delim, const size_t token_count, const char **tokens);
48 48
 int cli_isnumber(const char *str);
... ...
@@ -41,6 +41,9 @@
41 41
  *
42 42
  */
43 43
 
44
+#ifndef __TEXT_H
45
+#define __TEXT_H
46
+
44 47
 /* The contents could change, ONLY access in text.c */
45 48
 typedef struct text {
46 49
 	line_t	*t_line;	/* NULL if the line is empty */
... ...
@@ -54,3 +57,5 @@ text	*textAddMessage(text *aText, message *aMessage);
54 54
 text	*textMove(text *t_head, text *t);
55 55
 blob	*textToBlob(text *t, blob *b, int destroy);
56 56
 fileblob	*textToFileblob(text *t, fileblob *fb, int destroy);
57
+
58
+#endif /* __TEXT_H */
... ...
@@ -182,11 +182,7 @@ cli_tnef(const char *dir, int desc, cli_ctx *ctx)
182 182
 					char buffer[BUFSIZ];
183 183
 
184 184
 					if(filename)
185
-#ifdef	O_BINARY
186 185
 						fout = open(filename, O_WRONLY|O_CREAT|O_EXCL|O_TRUNC|O_BINARY, 0600);
187
-#else
188
-						fout = open(filename, O_WRONLY|O_CREAT|O_EXCL|O_TRUNC, 0600);
189
-#endif
190 186
 
191 187
 					if(fout >= 0) {
192 188
 						int count;
... ...
@@ -81,10 +81,6 @@
81 81
 #define NPT NP
82 82
 #endif
83 83
 
84
-#ifndef MIN
85
-#define MIN(a,b) ((a < b) ? a : b)
86
-#endif
87
-
88 84
 #define GARBLE_FLAG     0x01
89 85
 
90 86
 #ifndef HAVE_ATTRIB_PACKED
... ...
@@ -99,10 +95,6 @@
99 99
 #pragma pack 1
100 100
 #endif
101 101
 
102
-#ifndef O_BINARY
103
-#define O_BINARY        0
104
-#endif
105
-
106 102
 typedef struct arj_main_hdr_tag {
107 103
 	uint8_t first_hdr_size;		/* must be 30 bytes */
108 104
 	uint8_t version;
... ...
@@ -1061,14 +1053,14 @@ int cli_unarj_extract_file(int fd, const char *dirname, arj_metadata_t *metadata
1061 1061
 	if (metadata->encrypted) {
1062 1062
 		cli_dbgmsg("PASSWORDed file (skipping)\n");
1063 1063
 		offset = lseek(fd, 0, SEEK_CUR) + metadata->comp_size;
1064
-		cli_dbgmsg("Target offset: %ld\n", offset);
1064
+		cli_dbgmsg("Target offset: %lu\n", (unsigned long int) offset);
1065 1065
 		if (lseek(fd, offset, SEEK_SET) != offset) {
1066 1066
 			return CL_ESEEK;
1067 1067
 		}
1068 1068
 		return CL_SUCCESS;
1069 1069
 	}
1070 1070
 	
1071
-	snprintf(filename, 1024, "%s/file.uar", dirname);
1071
+	snprintf(filename, 1024, "%s"PATHSEP"file.uar", dirname);
1072 1072
 	cli_dbgmsg("Filename: %s\n", filename);
1073 1073
 	metadata->ofd = open(filename, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, 0600);
1074 1074
 	if (metadata->ofd < 0) {
... ...
@@ -45,10 +45,6 @@ static	char	const	rcsid[] = "$Id: untar.c,v 1.35 2007/02/12 20:46:09 njh Exp $";
45 45
 
46 46
 #define BLOCKSIZE 512
47 47
 
48
-#ifndef	O_BINARY
49
-#define	O_BINARY	0
50
-#endif
51
-
52 48
 static int
53 49
 octal(const char *str)
54 50
 {
... ...
@@ -184,7 +180,7 @@ cli_untar(const char *dir, int desc, unsigned int posix, cli_ctx *ctx)
184 184
 
185 185
 			strncpy(name, block, 100);
186 186
 			name[100] = '\0';
187
-			snprintf(fullname, sizeof(fullname)-1, "%s/tar%02u", dir, files);
187
+			snprintf(fullname, sizeof(fullname)-1, "%s"PATHSEP"tar%02u", dir, files);
188 188
 			fullname[sizeof(fullname)-1] = '\0';
189 189
 			fout = open(fullname, O_RDWR|O_CREAT|O_EXCL|O_TRUNC|O_BINARY, 0600);
190 190
 
... ...
@@ -34,14 +34,10 @@
34 34
 #include <string.h>
35 35
 #endif
36 36
 #include <stdlib.h>
37
-
38
-#if HAVE_MMAP
39
-#ifdef HAVE_SYS_MMAN_H
37
+#include <stdio.h>
38
+#if defined(HAVE_MMAP) && defined(HAVE_SYS_MMAN_H)
40 39
 #include <sys/mman.h>
41 40
 #endif
42
-#endif /* HAVE_MMAP */
43
-
44
-#include <stdio.h>
45 41
 
46 42
 #include <zlib.h>
47 43
 #include "inflate64.h"
... ...
@@ -58,11 +54,6 @@
58 58
 #define UNZIP_PRIVATE
59 59
 #include "unzip.h"
60 60
 
61
-#ifndef O_BINARY
62
-#define O_BINARY 0
63
-#endif
64
-
65
-
66 61
 static int wrap_inflateinit2(void *a, int b) {
67 62
   return inflateInit2(a, b);
68 63
 }
... ...
@@ -83,7 +74,7 @@ static int unz(uint8_t *src, uint32_t csize, uint32_t usize, uint16_t method, ui
83 83
   unsigned int res=1, written=0;
84 84
 
85 85
   if(tmpd) {
86
-    snprintf(name, sizeof(name), "%s/zip.%03u", tmpd, *fu);
86
+    snprintf(name, sizeof(name), "%s"PATHSEP"zip.%03u", tmpd, *fu);
87 87
     name[sizeof(name)-1]='\0';
88 88
   } else {
89 89
     if(!(tempfile = cli_gentemp(ctx->engine->tmpdir))) return CL_EMEM;
... ...
@@ -106,7 +97,7 @@ static int unz(uint8_t *src, uint32_t csize, uint32_t usize, uint16_t method, ui
106 106
     }
107 107
     if(res==1) {
108 108
       if(ctx->engine->maxfilesize && csize > ctx->engine->maxfilesize) {
109
-	cli_dbgmsg("cli_unzip: trimming output size to maxfilesize (%lu)\n", ctx->engine->maxfilesize);
109
+	cli_dbgmsg("cli_unzip: trimming output size to maxfilesize (%lu)\n", (long unsigned int) ctx->engine->maxfilesize);
110 110
 	csize = ctx->engine->maxfilesize;
111 111
       }
112 112
       if(cli_writen(of, src, csize)!=(int)csize) ret = CL_EWRITE;
... ...
@@ -167,7 +158,7 @@ static int unz(uint8_t *src, uint32_t csize, uint32_t usize, uint16_t method, ui
167 167
       if(*avail_out!=sizeof(obuf)) {
168 168
 	written+=sizeof(obuf)-(*avail_out);
169 169
 	if(ctx->engine->maxfilesize && written > ctx->engine->maxfilesize) {
170
-	  cli_dbgmsg("cli_unzip: trimming output size to maxfilesize (%lu)\n", ctx->engine->maxfilesize);
170
+	  cli_dbgmsg("cli_unzip: trimming output size to maxfilesize (%lu)\n", (long unsigned int) ctx->engine->maxfilesize);
171 171
 	  res = Z_STREAM_END;
172 172
 	  break;
173 173
 	}
... ...
@@ -211,7 +202,7 @@ static int unz(uint8_t *src, uint32_t csize, uint32_t usize, uint16_t method, ui
211 211
       if(strm.avail_out!=sizeof(obuf)) {
212 212
 	written+=sizeof(obuf)-strm.avail_out;
213 213
 	if(ctx->engine->maxfilesize && written > ctx->engine->maxfilesize) {
214
-	  cli_dbgmsg("cli_unzip: trimming output size to maxfilesize (%lu)\n", ctx->engine->maxfilesize);
214
+	  cli_dbgmsg("cli_unzip: trimming output size to maxfilesize (%lu)\n", (unsigned long int) ctx->engine->maxfilesize);
215 215
 	  res = BZ_STREAM_END;
216 216
 	  break;
217 217
 	}
... ...
@@ -248,7 +239,7 @@ static int unz(uint8_t *src, uint32_t csize, uint32_t usize, uint16_t method, ui
248 248
       if(strm.avail_out!=sizeof(obuf)) {
249 249
 	written+=sizeof(obuf)-strm.avail_out;
250 250
 	if(ctx->engine->maxfilesize && written > ctx->engine->maxfilesize) {
251
-	  cli_dbgmsg("cli_unzip: trimming output size to maxfilesize (%lu)\n", ctx->engine->maxfilesize);
251
+	  cli_dbgmsg("cli_unzip: trimming output size to maxfilesize (%lu)\n", (unsigned long int) ctx->engine->maxfilesize);
252 252
 	  res = 0;
253 253
 	  break;
254 254
 	}
... ...
@@ -39,10 +39,6 @@ static	char	const	rcsid[] = "$Id: uuencode.c,v 1.8 2006/12/11 11:55:11 njh Exp $
39 39
 #include "others.h"
40 40
 #include "str.h"
41 41
 
42
-#ifdef	C_WINDOWS
43
-#include <io.h>
44
-#endif
45
-
46 42
 #include "mbox.h"
47 43
 #include "uuencode.h"
48 44
 
... ...
@@ -44,10 +44,6 @@
44 44
 #endif
45 45
 #include "blob.h"
46 46
 
47
-#ifndef	O_BINARY
48
-#define	O_BINARY	0
49
-#endif
50
-
51 47
 #define PPT_LZW_BUFFSIZE 8192
52 48
 #define VBA_COMPRESSION_WINDOW 4096
53 49
 #define	MIDDLE_SIZE	20
... ...
@@ -269,7 +265,7 @@ cli_vba_readdir(const char *dir, struct uniq *U, uint32_t which)
269 269
 	
270 270
 	if (!uniq_get(U, "_vba_project", 12, &hash))
271 271
 		return NULL;
272
-	snprintf(fullname, sizeof(fullname), "%s/%s_%u", dir, hash, which);
272
+	snprintf(fullname, sizeof(fullname), "%s"PATHSEP"%s_%u", dir, hash, which);
273 273
 	fullname[sizeof(fullname)-1] = '\0';
274 274
 	fd = open(fullname, O_RDONLY|O_BINARY);
275 275
 
... ...
@@ -657,7 +653,7 @@ ppt_unlzw(const char *dir, int fd, uint32_t length)
657 657
 	unsigned char inbuff[PPT_LZW_BUFFSIZE], outbuff[PPT_LZW_BUFFSIZE];
658 658
 	char fullname[NAME_MAX + 1];
659 659
 
660
-	snprintf(fullname, sizeof(fullname) - 1, "%s/ppt%.8lx.doc",
660
+	snprintf(fullname, sizeof(fullname) - 1, "%s"PATHSEP"ppt%.8lx.doc",
661 661
 		dir, (long)lseek(fd, 0L, SEEK_CUR));
662 662
 
663 663
 	ofd = open(fullname, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY|O_EXCL,
... ...
@@ -15,6 +15,10 @@
15 15
  *
16 16
  */
17 17
 
18
+#if HAVE_CONFIG_H
19
+#include "clamav-config.h"
20
+#endif
21
+
18 22
 #include <stdio.h>
19 23
 #include <sys/types.h>
20 24
 #include <sys/stat.h>
... ...
@@ -35,12 +35,6 @@ struct unpack_data_tag;
35 35
 #include "libclamunrar/unrarcmd.h"
36 36
 #include "libclamunrar/unrarfilter.h"
37 37
 
38
-#define FALSE (0)
39
-#define TRUE (1)
40
-#ifndef MIN
41
-#define MIN(a,b) ((a < b) ? a : b)
42
-#endif
43
-
44 38
 #define SIZEOF_MARKHEAD 7
45 39
 #define SIZEOF_NEWMHD 13
46 40
 #define SIZEOF_NEWLHD 32
... ...
@@ -27,15 +27,10 @@ void *rar_malloc(size_t size)
27 27
 	return NULL;
28 28
     }
29 29
 
30
-#if defined(_MSC_VER) && defined(_DEBUG)
31
-    alloc = _malloc_dbg(size, _NORMAL_BLOCK, __FILE__, __LINE__);
32
-#else
33 30
     alloc = malloc(size);
34
-#endif
35 31
 
36 32
     if(!alloc) {
37 33
 	fprintf(stderr, "UNRAR: rar_malloc(): Can't allocate memory (%lu bytes).\n", size);
38
-	perror("malloc_problem");
39 34
 	return NULL;
40 35
     } else return alloc;
41 36
 }
... ...
@@ -54,7 +49,6 @@ void *rar_realloc2(void *ptr, size_t size)
54 54
 
55 55
     if(!alloc) {
56 56
 	fprintf(stderr, "UNRAR: rar_realloc2(): Can't allocate memory (%lu bytes).\n", size);
57
-	perror("rar_realloc2");
58 57
 	if(ptr)
59 58
 	    free(ptr);
60 59
 	return NULL;
... ...
@@ -14,6 +14,10 @@
14 14
  *  not be used to develop a RAR (WinRAR) compatible archiver.
15 15
  */
16 16
 
17
+#if HAVE_CONFIG_H
18
+#include "clamav-config.h"
19
+#endif
20
+
17 21
 #include <stdio.h>
18 22
 #include <string.h>
19 23
 
... ...
@@ -26,7 +30,6 @@
26 26
 static void rar_dbgmsg(const char* fmt,...){}
27 27
 #endif
28 28
 
29
-#define MAX(a,b)    (((a) > (b)) ? (a) : (b))
30 29
 #define MAX_O 64
31 30
 
32 31
 const unsigned int UNIT_SIZE=MAX(sizeof(struct ppm_context), sizeof(struct rar_mem_blk_tag));
... ...
@@ -21,12 +21,6 @@
21 21
 
22 22
 #include "libclamunrar/unrarcmd.h"
23 23
 
24
-#define FALSE (0)
25
-#define TRUE (1)
26
-#ifndef MIN
27
-#define MIN(a,b) ((a < b) ? a : b)
28
-#endif
29
-
30 24
 #define RARVM_MEMSIZE	0x40000
31 25
 #define RARVM_MEMMASK	(RARVM_MEMSIZE-1)
32 26
 
... ...
@@ -50,10 +50,6 @@ static uint32_t unrar_endian_convert_32(uint32_t v)
50 50
 }
51 51
 #endif
52 52
 
53
-#ifndef O_BINARY
54
-#define O_BINARY    0
55
-#endif
56
-
57 53
 /* FIXME: allow this to be controlled from unrar_open or so */
58 54
 #ifdef RAR_DEBUG_MODE
59 55
 #define unrar_dbgmsg printf
... ...
@@ -278,7 +274,7 @@ int unrar_open(int fd, const char *dirname, unrar_state_t *state)
278 278
 	return UNRAR_PASSWD;
279 279
     }
280 280
 
281
-    snprintf(filename,1024,"%s/comments", dirname);
281
+    snprintf(filename,1024,"%s"PATHSEP"comments", dirname);
282 282
     if(mkdir(filename,0700)) {
283 283
 	unrar_dbgmsg("UNRAR: Unable to create comment temporary directory\n");
284 284
 	free(main_hdr);
... ...
@@ -324,7 +320,7 @@ int unrar_open(int fd, const char *dirname, unrar_state_t *state)
324 324
 	    unrar_dbgmsg("UNRAR: UnPack Size: 0x%.4x\n", comment_header->unpack_size);
325 325
 	    unrar_dbgmsg("UNRAR: UnPack Version: 0x%.2x\n", comment_header->unpack_ver);
326 326
 	    unrar_dbgmsg("UNRAR: Pack Method: 0x%.2x\n", comment_header->method);
327
-	    snprintf(filename, 1024, "%s/main.cmt", state->comment_dir);
327
+	    snprintf(filename, 1024, "%s"PATHSEP"main.cmt", state->comment_dir);
328 328
 	    ofd = open(filename, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0600);
329 329
 	    if(ofd < 0) {
330 330
 		unrar_dbgmsg("UNRAR: ERROR: Failed to open output file\n");
... ...
@@ -422,7 +418,7 @@ int unrar_extract_next_prepare(unrar_state_t *state, const char *dirname)
422 422
 	    if((comment_header->unpack_ver < 15) || (comment_header->unpack_ver > 29) || (comment_header->method > 0x30)) {
423 423
 		unrar_dbgmsg("UNRAR: Can't process file comment - skipping\n");
424 424
 	    } else {
425
-		snprintf(filename, 1024, "%s/%lu.cmt", state->comment_dir, state->file_count);
425
+		snprintf(filename, 1024, "%s"PATHSEP"%lu.cmt", state->comment_dir, state->file_count);
426 426
 		ofd = open(filename, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0600);
427 427
 		if(ofd < 0) {
428 428
 		    free(comment_header);
... ...
@@ -464,7 +460,7 @@ int unrar_extract_next(unrar_state_t *state, const char *dirname)
464 464
 	unrar_dbgmsg("UNRAR: Skipping file inside multi-volume solid archive\n");
465 465
 
466 466
     } else {
467
-	snprintf(state->filename, 1024, "%s/%lu.ura", dirname, state->file_count);
467
+	snprintf(state->filename, 1024, "%s"PATHSEP"%lu.ura", dirname, state->file_count);
468 468
 	ofd = open(state->filename, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, 0600);
469 469
 	if(ofd < 0) {
470 470
 	    free(state->file_header->filename);
... ...
@@ -535,23 +531,3 @@ void unrar_close(unrar_state_t *state)
535 535
     free(state->unpack_data);
536 536
     free(state->comment_dir);
537 537
 }
538
-
539
-#ifdef	C_WINDOWS
540
-/*
541
- * A copy is needed here to avoid a cyclic dependancy libclamunrar_iface<->libclamav
542
- * e.g. see the comment in bug 775 about dropping the old internal snprintf
543
- * which didn't have this problem and bug 785
544
- */
545
-#include <stdarg.h>
546
-static int
547
-snprintf(char *str, size_t size, const char *format, ...)
548
-{
549
-	int ret;
550
-
551
-	va_list args;
552
-	va_start(args, format);
553
-	ret = _vsnprintf_s(str, size, _TRUNCATE, format, args);
554
-	va_end(args);
555
-	return ret;
556
-}
557
-#endif
558 538
new file mode 100644
... ...
@@ -0,0 +1,35 @@
0
+#ifndef _WIN32
1
+#define closesocket(s) close(s)
2
+#endif
3
+
4
+#ifndef O_BINARY
5
+#define O_BINARY 0
6
+#endif
7
+
8
+#ifndef	FALSE
9
+#define FALSE (0)
10
+#endif
11
+#ifndef	TRUE
12
+#define TRUE (1)
13
+#endif
14
+
15
+#ifndef MIN
16
+#define MIN(a, b)	(((a) < (b)) ? (a) : (b))
17
+#endif
18
+#ifndef MAX
19
+#define MAX(a,b)	(((a) > (b)) ? (a) : (b))
20
+#endif
21
+
22
+#ifndef HAVE_IN_PORT_T
23
+typedef	unsigned	short	in_port_t;
24
+#endif
25
+
26
+#ifndef HAVE_IN_ADDR_T
27
+typedef	unsigned	int	in_addr_t;
28
+#endif
29
+
30
+#ifdef _WIN32
31
+#define PATHSEP "\\"
32
+#else
33
+#define PATHSEP "/"
34
+#endif
... ...
@@ -30,7 +30,6 @@
30 30
 #include <unistd.h>
31 31
 #endif
32 32
 #include <fcntl.h>
33
-#include <utime.h>
34 33
 #include <errno.h>
35 34
 #include <libgen.h>
36 35
 
... ...
@@ -62,7 +61,7 @@ static int getdest(const char *fullpath, char **newname) {
62 62
 	free(tmps);
63 63
 	return -1;
64 64
     }
65
-    sprintf(*newname, "%s/%s", actarget, filename);
65
+    sprintf(*newname, "%s"PATHSEP"%s", actarget, filename);
66 66
     for(i=1; i<1000; i++) {
67 67
 	fd = open(*newname, O_WRONLY | O_CREAT | O_EXCL, 0600);
68 68
 	if(fd >= 0) {
... ...
@@ -70,7 +69,7 @@ static int getdest(const char *fullpath, char **newname) {
70 70
 	    return fd;
71 71
 	}
72 72
 	if(errno != EEXIST) break;
73
-	sprintf(*newname, "%s/%s.%03u", actarget, filename, i);
73
+	sprintf(*newname, "%s"PATHSEP"%s.%03u", actarget, filename, i);
74 74
     }
75 75
     free(tmps);
76 76
     free(*newname);
... ...
@@ -23,6 +23,10 @@
23 23
  *  DEALINGS IN THE SOFTWARE.
24 24
  */
25 25
 
26
+#if HAVE_CONFIG_H
27
+#include "clamav-config.h"
28
+#endif
29
+
26 30
 #include <sys/types.h>
27 31
 #include <stdlib.h>
28 32
 #include <stdio.h>
... ...
@@ -31,10 +31,10 @@
31 31
 #include <time.h>
32 32
 #include <sys/types.h>
33 33
 #include <sys/stat.h>
34
+#ifndef _WIN32
34 35
 #include <sys/socket.h>
35
-#ifndef	C_WINDOWS
36
-#include <dirent.h>
37 36
 #endif
37
+#include <dirent.h>
38 38
 #include <fcntl.h>
39 39
 #include <ctype.h>
40 40
 #include <errno.h>
... ...
@@ -49,10 +49,6 @@
49 49
 #include "libclamav/version.h"
50 50
 #include "shared/misc.h"
51 51
 
52
-#ifndef	O_BINARY
53
-#define	O_BINARY	0
54
-#endif
55
-
56 52
 #ifndef REPO_VERSION
57 53
 #define REPO_VERSION "exported"
58 54
 #endif
... ...
@@ -82,14 +78,14 @@ char *freshdbdir(void)
82 82
 	if((opt = optget(opts, "DatabaseDirectory"))->enabled) {
83 83
 	    if(strcmp(dbdir, opt->strarg)) {
84 84
 		    char *daily = (char *) malloc(strlen(opt->strarg) + strlen(dbdir) + 30);
85
-		sprintf(daily, "%s/daily.cvd", opt->strarg);
85
+		sprintf(daily, "%s"PATHSEP"daily.cvd", opt->strarg);
86 86
 		if(access(daily, R_OK))
87
-		    sprintf(daily, "%s/daily.cld", opt->strarg);
87
+		    sprintf(daily, "%s"PATHSEP"daily.cld", opt->strarg);
88 88
 
89 89
 		if(!access(daily, R_OK) && (d1 = cl_cvdhead(daily))) {
90
-		    sprintf(daily, "%s/daily.cvd", dbdir);
90
+		    sprintf(daily, "%s"PATHSEP"daily.cvd", dbdir);
91 91
 		    if(access(daily, R_OK))
92
-			sprintf(daily, "%s/daily.cld", dbdir);
92
+			sprintf(daily, "%s"PATHSEP"daily.cld", dbdir);
93 93
 
94 94
 		    if(!access(daily, R_OK) && (d2 = cl_cvdhead(daily))) {
95 95
 			free(daily);
... ...
@@ -139,9 +135,9 @@ void print_version(const char *dbdir)
139 139
 	return;
140 140
     }
141 141
 
142
-    sprintf(path, "%s/daily.cvd", pt);
142
+    sprintf(path, "%s"PATHSEP"daily.cvd", pt);
143 143
     if(access(path, R_OK))
144
-	sprintf(path, "%s/daily.cld", pt);
144
+	sprintf(path, "%s"PATHSEP"daily.cld", pt);
145 145
 
146 146
     if(!dbdir)
147 147
 	free(fdbdir);
... ...
@@ -200,7 +196,9 @@ const char *filelist(const struct optstruct *opts, int *err)
200 200
 
201 201
 int filecopy(const char *src, const char *dest)
202 202
 {
203
-#ifdef C_DARWIN
203
+#ifdef _WIN32
204
+    return (!CopyFileA(src, dest, 0));
205
+#elif defined(C_DARWIN)
204 206
 	pid_t pid;
205 207
 
206 208
     /* On Mac OS X use ditto and copy resource fork, too. */
... ...
@@ -225,7 +223,7 @@ int filecopy(const char *src, const char *dest)
225 225
 
226 226
 int daemonize(void)
227 227
 {
228
-#if defined(C_OS2) || defined(C_WINDOWS)
228
+#ifdef _WIN32
229 229
     fputs("Background mode is not supported on your operating system\n", stderr);
230 230
     return -1;
231 231
 #else
... ...
@@ -277,28 +275,15 @@ int match_regex(const char *filename, const char *pattern)
277 277
 	regex_t reg;
278 278
 	int match, flags = REG_EXTENDED | REG_NOSUB;
279 279
 	char fname[513];
280
-#if defined(C_OS2) || defined(C_WINDOWS)
281
-	size_t len;
282
-
280
+#ifdef _WIN32
283 281
 	flags |= REG_ICASE; /* case insensitive on Windows */
284 282
 #endif
285 283
 	if(cli_regcomp(&reg, pattern, flags) != 0)
286 284
 	    return 2;
287 285
 
288
-#if !defined(C_OS2) && !defined(C_WINDOWS)
289
-	if(pattern[strlen(pattern) - 1] == '/') {
290
-	    snprintf(fname, 511, "%s/", filename);
286
+	if(pattern[strlen(pattern) - 1] == *PATHSEP) {
287
+	    snprintf(fname, 511, "%s"PATHSEP, filename);
291 288
 	    fname[512] = 0;
292
-#else
293
-	if(pattern[strlen(pattern) - 1] == '\\') {
294
-	    strncpy(fname, filename, 510);
295
-	    fname[509]='\0';
296
-	    len = strlen(fname);
297
-	    if(fname[len - 1] != '\\') {
298
-		fname[len] = '\\';
299
-		fname[len + 1] = 0;
300
-	    }
301
-#endif
302 289
 	} else {
303 290
 	    strncpy(fname, filename, 513);
304 291
 	    fname[512]='\0';
... ...
@@ -331,3 +316,11 @@ int cfg_tcpsock(const struct optstruct *opts, struct sockaddr_in *tcpsock, in_ad
331 331
     return 0;
332 332
 }
333 333
 
334
+int cli_is_abspath(const char *path) {
335
+#ifdef _WIN32
336
+    int len = strlen(path);
337
+    return (len > 2 && path[0] == '\\' && path[1] == '\\') || (len > 3 && path[1] == ':' && path[2] == '\\');
338
+#else
339
+    return *path == '/';
340
+#endif
341
+}
... ...
@@ -20,8 +20,10 @@
20 20
 
21 21
 #ifndef __MISC_H
22 22
 #define __MISC_H
23
+#ifndef _WIN32
23 24
 #include <netdb.h>
24 25
 #include <netinet/in.h>
26
+#endif
25 27
 #include "optparser.h"
26 28
 /* Maximum filenames under various systems - njh */
27 29
 #ifndef	NAME_MAX	/* e.g. Linux */
... ...
@@ -34,10 +36,6 @@
34 34
 # endif
35 35
 #endif
36 36
 
37
-#ifndef HAVE_IN_ADDR_T
38
-typedef unsigned        int     in_addr_t;
39
-#endif
40
-
41 37
 #include <limits.h>
42 38
 
43 39
 #ifndef PATH_MAX
... ...
@@ -52,4 +50,6 @@ int daemonize(void);
52 52
 const char *get_version(void);
53 53
 int match_regex(const char *filename, const char *pattern);
54 54
 int cfg_tcpsock(const struct optstruct *opts, struct sockaddr_in *server, in_addr_t defaultbind);
55
+int cli_is_abspath(const char *path);
56
+
55 57
 #endif
... ...
@@ -20,11 +20,6 @@
20 20
  *
21 21
  */
22 22
 
23
-#ifdef	_MSC_VER
24
-#include <windows.h>
25
-#include <winsock.h>
26
-#endif
27
-
28 23
 #if HAVE_CONFIG_H
29 24
 #include "clamav-config.h"
30 25
 #endif
... ...
@@ -39,7 +34,7 @@
39 39
 #include <sys/types.h>
40 40
 #endif
41 41
 
42
-#ifndef C_WINDOWS
42
+#ifndef _WIN32
43 43
 #include <netdb.h>
44 44
 #endif
45 45
 
... ...
@@ -27,7 +27,7 @@
27 27
 #include <sys/types.h>
28 28
 #endif
29 29
 
30
-#ifndef	C_WINDOWS
30
+#ifndef	_WIN32
31 31
 #include <netdb.h>
32 32
 #endif
33 33
 
... ...
@@ -47,7 +47,6 @@
47 47
 #include "getopt.h"
48 48
 
49 49
 #define MAXCMDOPTS  100
50
-#define MAX(a,b) (a > b ? a : b)
51 50
 
52 51
 #define MATCH_NUMBER "^[0-9]+$"
53 52
 #define MATCH_SIZE "^[0-9]+[KM]?$"
... ...
@@ -292,6 +291,8 @@ const struct clam_option clam_options[] = {
292 292
 
293 293
     { "ClamukoScanOnAccess", NULL, 0, TYPE_BOOL, MATCH_BOOL, -1, NULL, 0, OPT_CLAMD, "This option enables Clamuko. Dazuko needs to be already configured and\nrunning.", "no" },
294 294
 
295
+    { "ClamukoScannerCount", NULL, 0, TYPE_NUMBER, MATCH_NUMBER, 3, NULL, 0, OPT_CLAMD, "The number of scanner threads that will be started (DazukoFS only).\nHaving multiple scanner threads allows Clamuko to serve multiple\nprocesses simultaneously. This is particularly beneficial on SMP machines.", "3" },
296
+
295 297
     { "ClamukoScanOnOpen", NULL, 0, TYPE_BOOL, MATCH_BOOL, -1, NULL, 0, OPT_CLAMD, "Scan files when they get opened by the system.", "yes" },
296 298
 
297 299
     { "ClamukoScanOnClose", NULL, 0, TYPE_BOOL, MATCH_BOOL, -1, NULL, 0, OPT_CLAMD, "Scan files when they get closed by the system.", "yes" },
... ...
@@ -388,6 +389,8 @@ const struct clam_option clam_options[] = {
388 388
 
389 389
     { "AddHeader", NULL, 0, TYPE_STRING, "^(No|Replace|Yes|Add)$", -1, "no", 0, OPT_MILTER, "If this option is set to \"Replace\" (or \"Yes\"), an \"X-Virus-Scanned\" and an\n\"X-Virus-Status\" headers will be attached to each processed message, possibly\nreplacing existing headers.\nIf it is set to Add, the X-Virus headers are added possibly on top of the\nexisting ones.\nNote that while \"Replace\" can potentially break DKIM signatures, \"Add\" may\nconfuse procmail and similar filters.", "Replace" },
390 390
 
391
+    { "ReportHostname", NULL, 0, TYPE_STRING, NULL, -1, NULL, 0, OPT_MILTER, "When AddHeader is in use, this option allows to arbitrary set the reported\nhostname. This may be desirable in order to avoid leaking internal names.\nIf unset the real machine name is used.", "my.mail.server.name" },
392
+
391 393
     { "Chroot", NULL, 0, TYPE_STRING, NULL, -1, NULL, 0, OPT_MILTER, "Chroot to the specified directory.\nChrooting is performed just after reading the config file and before\ndropping privileges.", "/newroot" },
392 394
 
393 395
     { "Whitelist", NULL, 0, TYPE_STRING, NULL, -1, NULL, 0, OPT_MILTER, "This option specifies a file which contains a list of basic POSIX regular\nexpressions. Addresses (sent to or from - see below) matching these regexes\nwill not be scanned.  Optionally each line can start with the string \"From:\"\nor \"To:\" (note: no whitespace after the colon) indicating if it is,\nrespectively, the sender or recipient that is to be whitelisted.\nIf the field is missing, \"To:\" is assumed.\nLines starting with #, : or ! are ignored.", "/etc/whitelisted_addresses" },
... ...
@@ -695,7 +698,7 @@ struct optstruct *optparse(const char *cfgfile, int argc, char **argv, int verbo
695 695
     }
696 696
 
697 697
     if(cfgfile) {
698
-	if((fs = fopen(cfgfile, "rb")) == NULL) {
698
+	if((fs = fopen(cfgfile, "r")) == NULL) {
699 699
 	    /* don't print error messages here! */
700 700
 	    optfree(opts);
701 701
 	    return NULL;
... ...
@@ -17,11 +17,6 @@
17 17
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18 18
  *  MA 02110-1301, USA.
19 19
  */
20
-#ifdef _MSC_VER
21
-#include <windows.h>
22
-#include <winsock.h>
23
-#endif
24
-
25 20
 
26 21
 #if HAVE_CONFIG_H
27 22
 #include "clamav-config.h"
... ...
@@ -39,7 +34,7 @@
39 39
 #include <time.h>
40 40
 #include <sys/stat.h>
41 41
 #include <errno.h>
42
-#ifndef C_WINDOWS
42
+#ifndef _WIN32
43 43
 #include <sys/time.h>
44 44
 #include <sys/socket.h>
45 45
 #endif
... ...
@@ -33,10 +33,6 @@
33 33
 
34 34
 #include "tar.h"
35 35
 
36
-#ifndef O_BINARY
37
-#define O_BINARY 0
38
-#endif
39
-
40 36
 struct tar_header {
41 37
     char name[100];	/* File name */
42 38
     char mode[8];	/* File mode */
... ...
@@ -34,11 +34,13 @@
34 34
 #include <sys/types.h>
35 35
 #include <sys/stat.h>
36 36
 #include <fcntl.h>
37
+#ifndef _WIN32
37 38
 #include <sys/socket.h>
38 39
 #include <sys/un.h>
39 40
 #include <netinet/in.h>
40 41
 #include <arpa/inet.h>
41 42
 #include <sys/wait.h>
43
+#endif
42 44
 #include <dirent.h>
43 45
 
44 46
 #ifdef HAVE_TERMIOS_H
... ...
@@ -325,7 +327,7 @@ static char *getdsig(const char *host, const char *user, const unsigned char *da
325 325
     server.sin_port = htons(33101);
326 326
 
327 327
     if(connect(sockd, (struct sockaddr *) &server, sizeof(struct sockaddr_in)) < 0) {
328
-        close(sockd);
328
+        closesocket(sockd);
329 329
 	perror("connect()");
330 330
 	mprintf("!getdsig: Can't connect to ClamAV Signing Service at %s\n", host);
331 331
 	memset(pass, 0, sizeof(pass));
... ...
@@ -343,9 +345,9 @@ static char *getdsig(const char *host, const char *user, const unsigned char *da
343 343
     memcpy(pt, data, datalen);
344 344
     len += datalen;
345 345
 
346
-    if(write(sockd, cmd, len) < 0) {
346
+    if(send(sockd, cmd, len, 0) < 0) {
347 347
 	mprintf("!getdsig: Can't write to socket\n");
348
-	close(sockd);
348
+	closesocket(sockd);
349 349
 	memset(cmd, 0, sizeof(cmd));
350 350
 	memset(pass, 0, sizeof(pass));
351 351
 	return NULL;
... ...
@@ -355,22 +357,22 @@ static char *getdsig(const char *host, const char *user, const unsigned char *da
355 355
     memset(pass, 0, sizeof(pass));
356 356
     memset(buff, 0, sizeof(buff));
357 357
 
358
-    if((bread = cli_readn(sockd, buff, sizeof(buff))) > 0) {
358
+    if((bread = recv(sockd, buff, sizeof(buff), 0)) > 0) {
359 359
 	if(!strstr(buff, "Signature:")) {
360 360
 	    mprintf("!getdsig: Error generating digital signature\n");
361 361
 	    mprintf("!getdsig: Answer from remote server: %s\n", buff);
362
-	    close(sockd);
362
+	    closesocket(sockd);
363 363
 	    return NULL;
364 364
 	} else {
365 365
 	    mprintf("Signature received (length = %lu)\n", strlen(buff) - 10);
366 366
 	}
367 367
     } else {
368 368
 	mprintf("!getdsig: Communication error with remote server\n");
369
-	close(sockd);
369
+	closesocket(sockd);
370 370
 	return NULL;
371 371
     }
372 372
 
373
-    close(sockd);
373
+    closesocket(sockd);
374 374
 
375 375
     pt = buff;
376 376
     pt += 10;
... ...
@@ -615,9 +617,9 @@ static int build(const struct optstruct *opts)
615 615
 
616 616
     } else {
617 617
 	pt = freshdbdir();
618
-	snprintf(olddb, sizeof(olddb), "%s/%s.cvd", pt, dbname);
618
+	snprintf(olddb, sizeof(olddb), "%s"PATHSEP"%s.cvd", pt, dbname);
619 619
 	if(access(olddb, R_OK))
620
-	    snprintf(olddb, sizeof(olddb), "%s/%s.cld", pt, dbname);
620
+	    snprintf(olddb, sizeof(olddb), "%s"PATHSEP"%s.cld", pt, dbname);
621 621
 	free(pt);
622 622
     }
623 623
 
... ...
@@ -908,9 +910,9 @@ static int unpack(const struct optstruct *opts)
908 908
 
909 909
     if(optget(opts, "unpack-current")->enabled) {
910 910
 	dbdir = freshdbdir();
911
-	snprintf(name, sizeof(name), "%s/%s.cvd", dbdir, optget(opts, "unpack-current")->strarg);
911
+	snprintf(name, sizeof(name), "%s"PATHSEP"%s.cvd", dbdir, optget(opts, "unpack-current")->strarg);
912 912
 	if(access(name, R_OK)) {
913
-	    snprintf(name, sizeof(name), "%s/%s.cld", dbdir, optget(opts, "unpack-current")->strarg);
913
+	    snprintf(name, sizeof(name), "%s"PATHSEP"%s.cld", dbdir, optget(opts, "unpack-current")->strarg);
914 914
 	    if(access(name, R_OK)) {
915 915
 		mprintf("!unpack: Couldn't find %s CLD/CVD database\n", optget(opts, "unpack-current")->strarg);
916 916
 		free(dbdir);
... ...
@@ -987,9 +989,7 @@ static int listdir(const char *dirname)
987 987
     }
988 988
 
989 989
     while((dent = readdir(dd))) {
990
-#ifndef C_INTERIX
991 990
 	if(dent->d_ino)
992
-#endif
993 991
 	{
994 992
 	    if(strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..") &&
995 993
 	    (cli_strbcasestr(dent->d_name, ".db")  ||
... ...
@@ -1013,7 +1013,7 @@ static int listdir(const char *dirname)
1013 1013
 		    closedir(dd);
1014 1014
 		    return -1;
1015 1015
 		}
1016
-		sprintf(dbfile, "%s/%s", dirname, dent->d_name);
1016
+		sprintf(dbfile, "%s"PATHSEP"%s", dirname, dent->d_name);
1017 1017
 
1018 1018
 		if(listdb(dbfile) == -1) {
1019 1019
 		    mprintf("!listdb: Error listing database %s\n", dbfile);
... ...
@@ -1061,15 +1061,7 @@ static int listdb(const char *filename)
1061 1061
 	free(buffer);
1062 1062
 	fclose(fh);
1063 1063
 
1064
-	tmpdir = getenv("TMPDIR");
1065
-	if(tmpdir == NULL)
1066
-#ifdef P_tmpdir
1067
-	    tmpdir = P_tmpdir;
1068
-#else
1069
-	    tmpdir = "/tmp";
1070
-#endif
1071
-
1072
-	if(!(dir = cli_gentemp(tmpdir))) {
1064
+	if(!(dir = cli_gentemp(NULL))) {
1073 1065
 	    mprintf("!listdb: Can't generate temporary name\n");
1074 1066
 	    return -1;
1075 1067
 	}
... ...
@@ -1219,7 +1211,7 @@ static int vbadump(const struct optstruct *opts)
1219 1219
 	pt = optget(opts, "vba")->strarg;
1220 1220
     }
1221 1221
  
1222
-    if((fd = open(pt, O_RDONLY)) == -1) {
1222
+    if((fd = open(pt, O_RDONLY|O_BINARY)) == -1) {
1223 1223
 	mprintf("!vbadump: Can't open file %s\n", pt);
1224 1224
 	return -1;
1225 1225
     }
... ...
@@ -1469,15 +1461,13 @@ static int dircopy(const char *src, const char *dest)
1469 1469
     }
1470 1470
 
1471 1471
     while((dent = readdir(dd))) {
1472
-#if (!defined(C_INTERIX)) && (!defined(C_WINDOWS))
1473 1472
 	if(dent->d_ino)
1474
-#endif
1475 1473
 	{
1476 1474
 	    if(!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, ".."))
1477 1475
 		continue;
1478 1476
 
1479
-	    snprintf(spath, sizeof(spath), "%s/%s", src, dent->d_name);
1480
-	    snprintf(dpath, sizeof(dpath), "%s/%s", dest, dent->d_name);
1477
+	    snprintf(spath, sizeof(spath), "%s"PATHSEP"%s", src, dent->d_name);
1478
+	    snprintf(dpath, sizeof(dpath), "%s"PATHSEP"%s", dest, dent->d_name);
1481 1479
 
1482 1480
 	    if(filecopy(spath, dpath) == -1) {
1483 1481
 		/* mprintf("!dircopy: Can't copy %s to %s\n", spath, dpath); */
... ...
@@ -1617,14 +1607,12 @@ static int diffdirs(const char *old, const char *new, const char *patch)
1617 1617
     }
1618 1618
 
1619 1619
     while((dent = readdir(dd))) {
1620
-#ifndef C_INTERIX
1621 1620
 	if(dent->d_ino)
1622
-#endif
1623 1621
 	{
1624 1622
 	    if(!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, ".."))
1625 1623
 		continue;
1626 1624
 
1627
-	    snprintf(path, sizeof(path), "%s/%s", old, dent->d_name);
1625
+	    snprintf(path, sizeof(path), "%s"PATHSEP"%s", old, dent->d_name);
1628 1626
 	    if(compare(path, dent->d_name, diff) == -1) {
1629 1627
 		if(chdir(cwd) == -1)
1630 1628
 		    mprintf("^diffdirs: Can't chdir to %s\n", cwd);
... ...
@@ -1645,14 +1633,12 @@ static int diffdirs(const char *old, const char *new, const char *patch)
1645 1645
     }
1646 1646
 
1647 1647
     while((dent = readdir(dd))) {
1648
-#ifndef C_INTERIX
1649 1648
 	if(dent->d_ino)
1650
-#endif
1651 1649
 	{
1652 1650
 	    if(!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, ".."))
1653 1651
 		continue;
1654 1652
 
1655
-	    snprintf(path, sizeof(path), "%s/%s", new, dent->d_name);
1653
+	    snprintf(path, sizeof(path), "%s"PATHSEP"%s", new, dent->d_name);
1656 1654
 	    if(access(path, R_OK))
1657 1655
 		fprintf(diff, "UNLINK %s\n", dent->d_name);
1658 1656
 	}
... ...
@@ -17,6 +17,10 @@
17 17
  *  MA 02110-1301, USA.
18 18
  */
19 19
 
20
+#if HAVE_CONFIG_H
21
+#include "clamav-config.h"
22
+#endif
23
+
20 24
 #include <stdio.h>
21 25
 #include <string.h>
22 26
 #include <stdlib.h>
... ...
@@ -32,10 +36,7 @@
32 32
 #include "libclamav/others.h"
33 33
 #include "libclamav/cltypes.h"
34 34
 #include "libclamav/ole2_extract.h"
35
-
36
-#ifndef	O_BINARY
37
-#define	O_BINARY	0
38
-#endif
35
+#include "shared/output.h"
39 36
 
40 37
 typedef struct mac_token_tag
41 38
 {
... ...
@@ -974,7 +975,7 @@ static int sigtool_scandir (const char *dirname, int hex_output)
974 974
 		if (strcmp (dent->d_name, ".") && strcmp (dent->d_name, "..")) {
975 975
 		    /* build the full name */
976 976
 		    fname = (char *) cli_calloc (strlen (dirname) + strlen (dent->d_name) + 2, sizeof (char));
977
-		    sprintf (fname, "%s/%s", dirname, dent->d_name);
977
+		    sprintf (fname, "%s"PATHSEP"%s", dirname, dent->d_name);
978 978
 
979 979
 		    /* stat the file */
980 980
 		    if (lstat (fname, &statbuf) != -1) {
... ...
@@ -987,14 +988,7 @@ static int sigtool_scandir (const char *dirname, int hex_output)
987 987
 			} else {
988 988
 			    if (S_ISREG (statbuf.st_mode)) {
989 989
 			        struct uniq *vba = NULL;
990
-				tmpdir = getenv ("TMPDIR");
991
-
992
-				if (tmpdir == NULL)
993
-#ifdef P_tmpdir
994
-				    tmpdir = P_tmpdir;
995
-#else
996
-				    tmpdir = "/tmp";
997
-#endif
990
+				tmpdir = cli_gettmpdir();
998 991
 
999 992
 				/* generate the temporary directory */
1000 993
 				dir = cli_gentemp (tmpdir);
... ...
@@ -1003,7 +997,7 @@ static int sigtool_scandir (const char *dirname, int hex_output)
1003 1003
 				    return CL_ETMPDIR;
1004 1004
 				}
1005 1005
 
1006
-				if ((desc = open (fname, O_RDONLY)) == -1) {
1006
+				if ((desc = open (fname, O_RDONLY|O_BINARY)) == -1) {
1007 1007
 				    printf ("Can't open file %s\n", fname);
1008 1008
 				    return 1;
1009 1009
 				}
... ...
@@ -1029,7 +1023,7 @@ static int sigtool_scandir (const char *dirname, int hex_output)
1029 1029
 	    }
1030 1030
 	}
1031 1031
     } else {
1032
-	cli_errmsg ("Can't open directory %s.\n", dirname);
1032
+	logg("!Can't open directory %s.\n", dirname);
1033 1033
 	return CL_EOPEN;
1034 1034
     }
1035 1035
 
... ...
@@ -1054,7 +1048,7 @@ int sigtool_vba_scandir (const char *dirname, int hex_output, struct uniq *U)
1054 1054
 
1055 1055
 	for(i = 0; i < vba_project->count; i++) {
1056 1056
 	    for(j = 0; j < vba_project->colls[i]; j++) {
1057
-		snprintf(vbaname, 1024, "%s/%s_%u", vba_project->dir, vba_project->name[i], j);
1057
+		snprintf(vbaname, 1024, "%s"PATHSEP"%s_%u", vba_project->dir, vba_project->name[i], j);
1058 1058
 		vbaname[sizeof(vbaname)-1] = '\0';
1059 1059
 		fd = open(vbaname, O_RDONLY|O_BINARY);
1060 1060
 		if(fd == -1) continue;
... ...
@@ -1080,7 +1074,7 @@ int sigtool_vba_scandir (const char *dirname, int hex_output, struct uniq *U)
1080 1080
 
1081 1081
     if((hashcnt = uniq_get(U, "powerpoint document", 19, &hash))) {
1082 1082
 	while(hashcnt--) {
1083
-	    snprintf(vbaname, 1024, "%s/%s_%u", dirname, hash, hashcnt);
1083
+	    snprintf(vbaname, 1024, "%s"PATHSEP"%s_%u", dirname, hash, hashcnt);
1084 1084
 	    vbaname[sizeof(vbaname)-1] = '\0';
1085 1085
 	    fd = open(vbaname, O_RDONLY|O_BINARY);
1086 1086
 	    if (fd == -1) continue;
... ...
@@ -1096,7 +1090,7 @@ int sigtool_vba_scandir (const char *dirname, int hex_output, struct uniq *U)
1096 1096
 
1097 1097
     if ((hashcnt = uniq_get(U, "worddocument", 12, &hash))) {
1098 1098
 	while(hashcnt--) {
1099
-	    snprintf(vbaname, sizeof(vbaname), "%s/%s_%u", dirname, hash, hashcnt);
1099
+	    snprintf(vbaname, sizeof(vbaname), "%s"PATHSEP"%s_%u", dirname, hash, hashcnt);
1100 1100
 	    vbaname[sizeof(vbaname)-1] = '\0';
1101 1101
 	    fd = open(vbaname, O_RDONLY|O_BINARY);
1102 1102
 	    if (fd == -1) continue;
... ...
@@ -1134,7 +1128,7 @@ int sigtool_vba_scandir (const char *dirname, int hex_output, struct uniq *U)
1134 1134
 		if (strcmp (dent->d_name, ".") && strcmp (dent->d_name, "..")) {
1135 1135
 		    /* build the full name */
1136 1136
 		    fullname = calloc (strlen (dirname) + strlen (dent->d_name) + 2, sizeof (char));
1137
-		    sprintf (fullname, "%s/%s", dirname, dent->d_name);
1137
+		    sprintf (fullname, "%s"PATHSEP"%s", dirname, dent->d_name);
1138 1138
 
1139 1139
 		    /* stat the file */
1140 1140
 		    if (lstat (fullname, &statbuf) != -1) {
... ...
@@ -1146,7 +1140,7 @@ int sigtool_vba_scandir (const char *dirname, int hex_output, struct uniq *U)
1146 1146
 	    }
1147 1147
 	}
1148 1148
     } else {
1149
-	cli_errmsg ("ScanDir -> Can't open directory %s.\n", dirname);
1149
+	logg("!ScanDir -> Can't open directory %s.\n", dirname);
1150 1150
 	return CL_EOPEN;
1151 1151
     }
1152 1152
 
1153 1153
new file mode 100644
... ...
@@ -0,0 +1,5 @@
0
+*.log
1
+accdenied
2
+check_clamav
3
+check_clamd
4
+clam-phish-exe
... ...
@@ -1,14 +1,22 @@
1 1
 SPLIT_DIR=$(top_srcdir)/unit_tests/.split
2 2
 FILES = clam-phish-exe
3 3
 
4
-check_clamd.sh: $(FILES)
4
+check2_clamd.sh: $(FILES)
5
+check3_clamd.sh: $(FILES)
6
+check4_clamd.sh: $(FILES)
7
+check5_clamd_vg.sh: $(FILES)
8
+check6_clamd_vg.sh: $(FILES)
9
+check7_clamd_vg.sh: $(FILES)
10
+check8_clamd_hg.sh: $(FILES)
11
+check9_clamd_hg.sh: $(FILES)
12
+check10_clamd_hg.sh: $(FILES)
5 13
 
6 14
 $(FILES) :
7 15
 	cat $(SPLIT_DIR)/split.$@aa $(SPLIT_DIR)/split.$@ab > $@
8 16
 
9 17
 programs = check_clamav
10
-scripts = check_clamd.sh check_freshclam.sh check_sigtool.sh check_clamscan.sh\
11
-	 valgrind_tests.sh efence_tests.sh duma_tests.sh
18
+scripts = check_freshclam.sh check_sigtool.sh check1_clamscan.sh check2_clamd.sh check3_clamd.sh check4_clamd.sh\
19
+	  check5_clamd_vg.sh check6_clamd_vg.sh check7_clamd_hg.sh check8_clamd_hg.sh
12 20
 TESTS_ENVIRONMENT=export abs_srcdir=$(abs_srcdir) AWK=$(AWK);
13 21
 if ENABLE_UNRAR
14 22
 else
... ...
@@ -42,8 +50,8 @@ $(top_builddir)/test/clam.exe:
42 42
 quick-check:
43 43
 	VALGRIND=no LIBEFENCE=no LIBDUMA=no $(MAKE) check
44 44
 
45
-CLEANFILES=lcov.out *.gcno *.gcda *.log $(FILES) test-stderr.log clamscan.log valgrind-*.log duma.log duma2.log clamscan2.log
46
-EXTRA_DIST=.split $(srcdir)/*.ref input test-clamd.conf test-freshclam.conf valgrind.supp virusaction-test.sh $(scripts) preload_run.sh
45
+CLEANFILES=lcov.out *.gcno *.gcda *.log $(FILES) test-stderr.log clamscan.log accdenied
46
+EXTRA_DIST=.split $(srcdir)/*.ref input test-freshclam.conf valgrind.supp virusaction-test.sh $(scripts) preload_run.sh check_common.sh
47 47
 if ENABLE_COVERAGE
48 48
 LCOV_OUTPUT = lcov.out
49 49
 LCOV_HTML = lcov_html
... ...
@@ -133,6 +133,76 @@ test "X$(AM_COLOR_TESTS)" != Xno \
133 133
   blu=''; \
134 134
   std=''; \
135 135
 }
136
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
137
+am__vpath_adj = case $$p in \
138
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
139
+    *) f=$$p;; \
140
+  esac;
141
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
142
+am__install_max = 40
143
+am__nobase_strip_setup = \
144
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
145
+am__nobase_strip = \
146
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
147
+am__nobase_list = $(am__nobase_strip_setup); \
148
+  for p in $$list; do echo "$$p $$p"; done | \
149
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
150
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
151
+    if (++n[$$2] == $(am__install_max)) \
152
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
153
+    END { for (dir in files) print dir, files[dir] }'
154
+am__base_list = \
155
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
156
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
157
+# Restructured Text title and section.
158
+am__rst_title = sed 's/.*/   &   /;h;s/./=/g;p;x;p;g;p;s/.*//'
159
+am__rst_section = sed 'p;s/./=/g;p;g'
160
+# Put stdin (possibly several lines separated by ".  ") in a box.
161
+am__text_box = $(AWK) '{				\
162
+  n = split($$0, lines, "\\.  "); max = 0;		\
163
+  for (i = 1; i <= n; ++i)				\
164
+    if (max < length(lines[i]))				\
165
+      max = length(lines[i]);				\
166
+  for (i = 0; i < max; ++i) line = line "=";		\
167
+  print line;						\
168
+  for (i = 1; i <= n; ++i) if (lines[i]) print lines[i];\
169
+  print line;						\
170
+}'
171
+# Solaris 10 'make', and several other traditional 'make' implementations,
172
+# pass "-e" to $(SHELL).  This contradicts POSIX.  Work around the problem
173
+# by disabling -e (using the XSI extension "set +e") if it's set.
174
+am__sh_e_setup = case $$- in *e*) set +e;; esac
175
+# To be inserted before the command running the test.  Creates the
176
+# directory for the log if needed.  Stores in $dir the directory
177
+# containing $f, in $tst the test, in $log the log, and passes
178
+# TESTS_ENVIRONMENT.  Save and restore TERM around use of
179
+# TESTS_ENVIRONMENT, in case that unsets it.
180
+am__check_pre = \
181
+$(am__sh_e_setup);					\
182
+$(am__vpath_adj_setup) $(am__vpath_adj)			\
183
+srcdir=$(srcdir); export srcdir;			\
184
+rm -f $@-t;						\
185
+trap 'st=$$?; rm -f '\''$(abs_builddir)/$@-t'\''; (exit $$st); exit $$st' \
186
+  1 2 13 15;						\
187
+am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;		\
188
+test "x$$am__odir" = x. || $(MKDIR_P) "$$am__odir" || exit $$?;	\
189
+if test -f "./$$f"; then dir=./;			\
190
+elif test -f "$$f"; then dir=;				\
191
+else dir="$(srcdir)/"; fi;				\
192
+tst=$$dir$$f; log='$@'; __SAVED_TERM=$$TERM;		\
193
+$(TESTS_ENVIRONMENT)
194
+RECHECK_LOGS = $(TEST_LOGS)
195
+AM_RECURSIVE_TARGETS = check check-html recheck recheck-html
196
+TEST_SUITE_LOG = test-suite.log
197
+TEST_SUITE_HTML = $(TEST_SUITE_LOG:.log=.html)
198
+TEST_EXTENSIONS = @EXEEXT@ .test
199
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
200
+am__test_logs1 = $(TESTS:=.log)
201
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
202
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
203
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
204
+	$(TEST_LOG_FLAGS)
205
+TEST_LOGS_TMP = $(TEST_LOGS:.log=.log-t)
136 206
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
137 207
 ACLOCAL = @ACLOCAL@
138 208
 AMTAR = @AMTAR@
... ...
@@ -295,8 +365,8 @@ top_srcdir = @top_srcdir@
295 295
 SPLIT_DIR = $(top_srcdir)/unit_tests/.split
296 296
 FILES = clam-phish-exe
297 297
 programs = check_clamav
298
-scripts = check_clamd.sh check_freshclam.sh check_sigtool.sh check_clamscan.sh\
299
-	 valgrind_tests.sh efence_tests.sh duma_tests.sh
298
+scripts = check_freshclam.sh check_sigtool.sh check1_clamscan.sh check2_clamd.sh check3_clamd.sh check4_clamd.sh\
299
+	  check5_clamd_vg.sh check6_clamd_vg.sh check7_clamd_hg.sh check8_clamd_hg.sh
300 300
 
301 301
 TESTS_ENVIRONMENT = export abs_srcdir=$(abs_srcdir) AWK=$(AWK); \
302 302
 	$(am__append_1)
... ...
@@ -313,8 +383,8 @@ check_SCRIPTS = $(scripts)
313 313
 @HAVE_LIBCHECK_TRUE@check_clamd_SOURCES = check_clamd.c checks_common.h
314 314
 @HAVE_LIBCHECK_TRUE@check_clamd_CPPFLAGS = -I$(top_srcdir) @CHECK_CPPFLAGS@ -DSRCDIR=\"$(abs_srcdir)\" -DBUILDDIR=\"$(abs_builddir)\"
315 315
 @HAVE_LIBCHECK_TRUE@check_clamd_LDADD = @CHECK_LIBS@ @CLAMD_LIBS@
316
-CLEANFILES = lcov.out *.gcno *.gcda *.log $(FILES) test-stderr.log clamscan.log valgrind-*.log duma.log duma2.log clamscan2.log
317
-EXTRA_DIST = .split $(srcdir)/*.ref input test-clamd.conf test-freshclam.conf valgrind.supp virusaction-test.sh $(scripts) preload_run.sh
316
+CLEANFILES = lcov.out *.gcno *.gcda *.log $(FILES) test-stderr.log clamscan.log accdenied
317
+EXTRA_DIST = .split $(srcdir)/*.ref input test-freshclam.conf valgrind.supp virusaction-test.sh $(scripts) preload_run.sh check_common.sh
318 318
 @ENABLE_COVERAGE_TRUE@LCOV_OUTPUT = lcov.out
319 319
 @ENABLE_COVERAGE_TRUE@LCOV_HTML = lcov_html
320 320
 @ENABLE_COVERAGE_TRUE@LCOV_LCOV = @LCOV@
... ...
@@ -324,7 +394,7 @@ EXTRA_DIST = .split $(srcdir)/*.ref input test-clamd.conf test-freshclam.conf va
324 324
 all: all-am
325 325
 
326 326
 .SUFFIXES:
327
-.SUFFIXES: .c .lo .o .obj
327
+.SUFFIXES: .c .html .lo .log .o .obj .test .test$(EXEEXT)
328 328
 $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
329 329
 	@for dep in $?; do \
330 330
 	  case '$(am__configure_deps)' in \
... ...
@@ -664,97 +734,183 @@ GTAGS:
664 664
 distclean-tags:
665 665
 	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
666 666
 
667
-check-TESTS: $(TESTS)
668
-	@failed=0; all=0; xfail=0; xpass=0; skip=0; \
669
-	srcdir=$(srcdir); export srcdir; \
670
-	list=' $(TESTS) '; \
671
-	$(am__tty_colors); \
672
-	if test -n "$$list"; then \
673
-	  for tst in $$list; do \
674
-	    if test -f ./$$tst; then dir=./; \
675
-	    elif test -f $$tst; then dir=; \
676
-	    else dir="$(srcdir)/"; fi; \
677
-	    if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \
678
-	      all=`expr $$all + 1`; \
679
-	      case " $(XFAIL_TESTS) " in \
680
-	      *[\ \	]$$tst[\ \	]*) \
681
-		xpass=`expr $$xpass + 1`; \
682
-		failed=`expr $$failed + 1`; \
683
-		col=$$red; res=XPASS; \
684
-	      ;; \
685
-	      *) \
686
-		col=$$grn; res=PASS; \
687
-	      ;; \
688
-	      esac; \
689
-	    elif test $$? -ne 77; then \
690
-	      all=`expr $$all + 1`; \
691
-	      case " $(XFAIL_TESTS) " in \
692
-	      *[\ \	]$$tst[\ \	]*) \
693
-		xfail=`expr $$xfail + 1`; \
694
-		col=$$lgn; res=XFAIL; \
695
-	      ;; \
696
-	      *) \
697
-		failed=`expr $$failed + 1`; \
698
-		col=$$red; res=FAIL; \
699
-	      ;; \
700
-	      esac; \
701
-	    else \
702
-	      skip=`expr $$skip + 1`; \
703
-	      col=$$blu; res=SKIP; \
704
-	    fi; \
705
-	    echo "$${col}$$res$${std}: $$tst"; \
706
-	  done; \
707
-	  if test "$$all" -eq 1; then \
708
-	    tests="test"; \
709
-	    All=""; \
710
-	  else \
711
-	    tests="tests"; \
712
-	    All="All "; \
713
-	  fi; \
714
-	  if test "$$failed" -eq 0; then \
715
-	    if test "$$xfail" -eq 0; then \
716
-	      banner="$$All$$all $$tests passed"; \
717
-	    else \
718
-	      if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \
719
-	      banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \
720
-	    fi; \
721
-	  else \
722
-	    if test "$$xpass" -eq 0; then \
723
-	      banner="$$failed of $$all $$tests failed"; \
724
-	    else \
725
-	      if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \
726
-	      banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \
727
-	    fi; \
728
-	  fi; \
729
-	  dashes="$$banner"; \
730
-	  skipped=""; \
731
-	  if test "$$skip" -ne 0; then \
732
-	    if test "$$skip" -eq 1; then \
733
-	      skipped="($$skip test was not run)"; \
734
-	    else \
735
-	      skipped="($$skip tests were not run)"; \
736
-	    fi; \
737
-	    test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
738
-	      dashes="$$skipped"; \
739
-	  fi; \
740
-	  report=""; \
741
-	  if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
742
-	    report="Please report to $(PACKAGE_BUGREPORT)"; \
743
-	    test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
744
-	      dashes="$$report"; \
745
-	  fi; \
746
-	  dashes=`echo "$$dashes" | sed s/./=/g`; \
747
-	  if test "$$failed" -eq 0; then \
748
-	    echo "$$grn$$dashes"; \
749
-	  else \
750
-	    echo "$$red$$dashes"; \
751
-	  fi; \
752
-	  echo "$$banner"; \
753
-	  test -z "$$skipped" || echo "$$skipped"; \
754
-	  test -z "$$report" || echo "$$report"; \
755
-	  echo "$$dashes$$std"; \
756
-	  test "$$failed" -eq 0; \
757
-	else :; fi
667
+# To be appended to the command running the test.  Handle the stdout
668
+# and stderr redirection, and catch the exit status.
669
+am__check_post =					\
670
+>$@-t 2>&1;						\
671
+estatus=$$?;						\
672
+if test -n '$(DISABLE_HARD_ERRORS)'			\
673
+   && test $$estatus -eq 99; then			\
674
+  estatus=1;						\
675
+fi;							\
676
+TERM=$$__SAVED_TERM; export TERM;			\
677
+$(am__tty_colors);					\
678
+xfailed=PASS;						\
679
+case " $(XFAIL_TESTS) " in				\
680
+  *[\ \	]$$f[\ \	]* | *[\ \	]$$dir$$f[\ \	]*) \
681
+    xfailed=XFAIL;;					\
682
+esac;							\
683
+case $$estatus:$$xfailed in				\
684
+    0:XFAIL) col=$$red; res=XPASS;;			\
685
+    0:*)     col=$$grn; res=PASS ;;			\
686
+    77:*)    col=$$blu; res=SKIP ;;			\
687
+    99:*)    col=$$red; res=FAIL ;;			\
688
+    *:XFAIL) col=$$lgn; res=XFAIL;;			\
689
+    *:*)     col=$$red; res=FAIL ;;			\
690
+esac;							\
691
+echo "$${col}$$res$${std}: $$f";			\
692
+echo "$$res: $$f (exit: $$estatus)" |			\
693
+  $(am__rst_section) >$@;				\
694
+cat $@-t >>$@;						\
695
+rm -f $@-t
696
+
697
+$(TEST_SUITE_LOG): $(TEST_LOGS)
698
+	@$(am__sh_e_setup);						\
699
+	list='$(TEST_LOGS)';						\
700
+	results=`for f in $$list; do					\
701
+		   read line < $$f && echo "$$line" || echo FAIL;	\
702
+		 done`;							\
703
+	all=`echo "$$results" | sed '/^$$/d' | wc -l | sed -e 's/^[	 ]*//'`; \
704
+	fail=`echo "$$results" | grep -c '^FAIL'`;			\
705
+	pass=`echo "$$results" | grep -c '^PASS'`;			\
706
+	skip=`echo "$$results" | grep -c '^SKIP'`;			\
707
+	xfail=`echo "$$results" | grep -c '^XFAIL'`;			\
708
+	xpass=`echo "$$results" | grep -c '^XPASS'`;			\
709
+	failures=`expr $$fail + $$xpass`;				\
710
+	all=`expr $$all - $$skip`;					\
711
+	if test "$$all" -eq 1; then tests=test; All=;			\
712
+	else tests=tests; All="All "; fi;				\
713
+	case fail=$$fail:xpass=$$xpass:xfail=$$xfail in			\
714
+	  fail=0:xpass=0:xfail=0)					\
715
+	    msg="$$All$$all $$tests passed.  ";				\
716
+	    exit=true;;							\
717
+	  fail=0:xpass=0:xfail=*)					\
718
+	    msg="$$All$$all $$tests behaved as expected";		\
719
+	    if test "$$xfail" -eq 1; then xfailures=failure;		\
720
+	    else xfailures=failures; fi;				\
721
+	    msg="$$msg ($$xfail expected $$xfailures).  ";		\
722
+	    exit=true;;							\
723
+	  fail=*:xpass=0:xfail=*)					\
724
+	    msg="$$fail of $$all $$tests failed.  ";			\
725
+	    exit=false;;						\
726
+	  fail=*:xpass=*:xfail=*)					\
727
+	    msg="$$failures of $$all $$tests did not behave as expected"; \
728
+	    if test "$$xpass" -eq 1; then xpasses=pass;			\
729
+	    else xpasses=passes; fi;					\
730
+	    msg="$$msg ($$xpass unexpected $$xpasses).  ";		\
731
+	    exit=false;;						\
732
+	  *)								\
733
+	    echo >&2 "incorrect case"; exit 4;;				\
734
+	esac;								\
735
+	if test "$$skip" -ne 0; then					\
736
+	  if test "$$skip" -eq 1; then					\
737
+	    msg="$$msg($$skip test was not run).  ";			\
738
+	  else								\
739
+	    msg="$$msg($$skip tests were not run).  ";			\
740
+	  fi;								\
741
+	fi;								\
742
+	{								\
743
+	  echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" |	\
744
+	    $(am__rst_title);						\
745
+	  echo "$$msg";							\
746
+	  echo;								\
747
+	  echo ".. contents:: :depth: 2";				\
748
+	  echo;								\
749
+	  for f in $$list; do						\
750
+	    read line < $$f;						\
751
+	    case $$line in						\
752
+	      PASS:*|XFAIL:*);;						\
753
+	      *) echo; cat $$f;;					\
754
+	    esac;							\
755
+	  done;								\
756
+	} >$(TEST_SUITE_LOG).tmp;					\
757
+	mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG);			\
758
+	if test "$$failures" -ne 0; then				\
759
+	  msg="$${msg}See $(subdir)/$(TEST_SUITE_LOG).  ";		\
760
+	  if test -n "$(PACKAGE_BUGREPORT)"; then			\
761
+	    msg="$${msg}Please report to $(PACKAGE_BUGREPORT).  ";	\
762
+	  fi;								\
763
+	fi;								\
764
+	test x"$$VERBOSE" = x || $$exit || cat $(TEST_SUITE_LOG);	\
765
+	$(am__tty_colors);						\
766
+	if $$exit; then							\
767
+	  echo $(ECHO_N) "$$grn$(ECHO_C)";				\
768
+	 else								\
769
+	  echo $(ECHO_N) "$$red$(ECHO_C)";				\
770
+	fi;								\
771
+	echo "$$msg" | $(am__text_box);					\
772
+	echo $(ECHO_N) "$$std$(ECHO_C)";				\
773
+	$$exit
774
+
775
+# Run all the tests.
776
+check-TESTS:
777
+	@list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
778
+	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
779
+	@set_logs=; if test "X$(TEST_LOGS)" = X.log; then		\
780
+	  set_logs=TEST_LOGS=;						\
781
+	fi;								\
782
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) $$set_logs
783
+
784
+.log.html:
785
+	@list='$(RST2HTML) $$RST2HTML rst2html rst2html.py';		\
786
+	for r2h in $$list; do						\
787
+	  if ($$r2h --version) >/dev/null 2>&1; then			\
788
+	    R2H=$$r2h;							\
789
+	  fi;								\
790
+	done;								\
791
+	if test -z "$$R2H"; then					\
792
+	  echo >&2 "cannot find rst2html, cannot create $@";		\
793
+	  exit 2;							\
794
+	fi;								\
795
+	$$R2H $< >$@.tmp
796
+	@mv $@.tmp $@
797
+
798
+# Be sure to run check first, and then to convert the result.
799
+# Beware of concurrent executions.  Run "check" not "check-TESTS", as
800
+# check-SCRIPTS and other dependencies are rebuilt by the former only.
801
+# And expect check to fail.
802
+check-html:
803
+	@if $(MAKE) $(AM_MAKEFLAGS) check; then			\
804
+	  rv=0; else rv=$$?;					\
805
+	fi;							\
806
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_HTML) || exit 4;	\
807
+	exit $$rv
808
+recheck recheck-html:
809
+	@target=`echo $@ | sed 's,^re,,'`;				\
810
+	list='$(TEST_LOGS)';						\
811
+	list=`for f in $$list; do					\
812
+	        test -f $$f || continue;				\
813
+	        if read line < $$f; then				\
814
+	          case $$line in FAIL*|XPASS*) echo $$f;; esac;		\
815
+	        else echo $$f; fi;					\
816
+	      done | tr '\012\015' '  '`;				\
817
+	$(MAKE) $(AM_MAKEFLAGS) $$target AM_MAKEFLAGS='$(AM_MAKEFLAGS) TEST_LOGS="'"$$list"'"'
818
+check_clamav.log: check_clamav$(EXEEXT)
819
+	@p='check_clamav$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
820
+check_freshclam.sh.log: check_freshclam.sh
821
+	@p='check_freshclam.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
822
+check_sigtool.sh.log: check_sigtool.sh
823
+	@p='check_sigtool.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
824
+check1_clamscan.sh.log: check1_clamscan.sh
825
+	@p='check1_clamscan.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
826
+check2_clamd.sh.log: check2_clamd.sh
827
+	@p='check2_clamd.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
828
+check3_clamd.sh.log: check3_clamd.sh
829
+	@p='check3_clamd.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
830
+check4_clamd.sh.log: check4_clamd.sh
831
+	@p='check4_clamd.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
832
+check5_clamd_vg.sh.log: check5_clamd_vg.sh
833
+	@p='check5_clamd_vg.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
834
+check6_clamd_vg.sh.log: check6_clamd_vg.sh
835
+	@p='check6_clamd_vg.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
836
+check7_clamd_hg.sh.log: check7_clamd_hg.sh
837
+	@p='check7_clamd_hg.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
838
+check8_clamd_hg.sh.log: check8_clamd_hg.sh
839
+	@p='check8_clamd_hg.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
840
+.test.log:
841
+	@p='$<'; $(am__check_pre) $(TEST_LOG_COMPILE) "$$tst" $(am__check_post)
842
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
843
+@am__EXEEXT_TRUE@	@p='$<'; $(am__check_pre) $(TEST_LOG_COMPILE) "$$tst" $(am__check_post)
758 844
 
759 845
 distdir: $(DISTFILES)
760 846
 	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
... ...
@@ -807,6 +963,10 @@ install-strip:
807 807
 	  `test -z '$(STRIP)' || \
808 808
 	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
809 809
 mostlyclean-generic:
810
+	-test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
811
+	-test -z "$(TEST_LOGS_TMP)" || rm -f $(TEST_LOGS_TMP)
812
+	-test -z "$(TEST_SUITE_HTML)" || rm -f $(TEST_SUITE_HTML)
813
+	-test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
810 814
 
811 815
 clean-generic:
812 816
 	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
... ...
@@ -890,24 +1050,33 @@ ps-am:
890 890
 
891 891
 uninstall-am:
892 892
 
893
-.MAKE: check-am install-am install-strip
894
-
895
-.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \
896
-	clean-checkPROGRAMS clean-generic clean-libtool clean-local \
897
-	ctags distclean distclean-compile distclean-generic \
898
-	distclean-libtool distclean-tags distdir dvi dvi-am html \
899
-	html-am info info-am install install-am install-data \
900
-	install-data-am install-dvi install-dvi-am install-exec \
901
-	install-exec-am install-html install-html-am install-info \
902
-	install-info-am install-man install-pdf install-pdf-am \
903
-	install-ps install-ps-am install-strip installcheck \
904
-	installcheck-am installdirs maintainer-clean \
893
+.MAKE: check-am check-html install-am install-strip recheck \
894
+	recheck-html
895
+
896
+.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am check-html \
897
+	clean clean-checkPROGRAMS clean-generic clean-libtool \
898
+	clean-local ctags distclean distclean-compile \
899
+	distclean-generic distclean-libtool distclean-tags distdir dvi \
900
+	dvi-am html html-am info info-am install install-am \
901
+	install-data install-data-am install-dvi install-dvi-am \
902
+	install-exec install-exec-am install-html install-html-am \
903
+	install-info install-info-am install-man install-pdf \
904
+	install-pdf-am install-ps install-ps-am install-strip \
905
+	installcheck installcheck-am installdirs maintainer-clean \
905 906
 	maintainer-clean-generic mostlyclean mostlyclean-compile \
906 907
 	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
907
-	tags uninstall uninstall-am
908
-
909
-
910
-check_clamd.sh: $(FILES)
908
+	recheck recheck-html tags uninstall uninstall-am
909
+
910
+
911
+check2_clamd.sh: $(FILES)
912
+check3_clamd.sh: $(FILES)
913
+check4_clamd.sh: $(FILES)
914
+check5_clamd_vg.sh: $(FILES)
915
+check6_clamd_vg.sh: $(FILES)
916
+check7_clamd_vg.sh: $(FILES)
917
+check8_clamd_hg.sh: $(FILES)
918
+check9_clamd_hg.sh: $(FILES)
919
+check10_clamd_hg.sh: $(FILES)
911 920
 
912 921
 $(FILES) :
913 922
 	cat $(SPLIT_DIR)/split.$@aa $(SPLIT_DIR)/split.$@ab > $@
914 923
new file mode 100755
... ...
@@ -0,0 +1,3 @@
0
+#!/bin/sh
1
+. $abs_srcdir/check_common.sh
2
+test_clamscan 1
0 3
new file mode 100755
... ...
@@ -0,0 +1,3 @@
0
+#!/bin/sh
1
+. $srcdir/check_common.sh
2
+test_clamd1 2
0 3
new file mode 100755
... ...
@@ -0,0 +1,3 @@
0
+#!/bin/sh
1
+. $srcdir/check_common.sh
2
+test_clamd2 3
0 3
new file mode 100755
... ...
@@ -0,0 +1,3 @@
0
+#!/bin/sh 
1
+. $srcdir/check_common.sh
2
+test_clamd3 4
0 3
new file mode 100755
... ...
@@ -0,0 +1,5 @@
0
+#!/bin/sh
1
+. $srcdir/check_common.sh
2
+init_valgrind
3
+WRAPPER="$VALGRIND $VALGRIND_FLAGS" test_clamd1 5
4
+end_valgrind
0 5
new file mode 100755
... ...
@@ -0,0 +1,5 @@
0
+#!/bin/sh
1
+. $srcdir/check_common.sh
2
+init_valgrind
3
+WRAPPER="$VALGRIND $VALGRIND_FLAGS" test_clamd2 6
4
+end_valgrind
0 5
new file mode 100755
... ...
@@ -0,0 +1,5 @@
0
+#!/bin/sh
1
+. $srcdir/check_common.sh
2
+init_helgrind
3
+WRAPPER="$VALGRIND $VALGRIND_FLAGS_RACE" test_clamd1 7
4
+end_valgrind
0 5
new file mode 100755
... ...
@@ -0,0 +1,5 @@
0
+#!/bin/sh
1
+. $srcdir/check_common.sh
2
+init_helgrind
3
+WRAPPER="$VALGRIND $VALGRIND_FLAGS_RACE" test_clamd2 8
4
+end_valgrind
0 5
deleted file mode 100755
... ...
@@ -1,289 +0,0 @@
1
-#!/bin/sh 
2
-CLAMD_WRAPPER=${CLAMD_WRAPPER-}
3
-CLAMD_TEST_UNIQ1=${CLAMD_TEST_UNIQ1-1}
4
-CLAMD_TEST_UNIQ2=${CLAMD_TEST_UNIQ2-2}
5
-TOP="../.."
6
-LTEXEC="$TOP/libtool --mode=execute"
7
-killclamd() {
8
-	test -f clamd-test.pid || return
9
-	pid=`cat clamd-test.pid 2>/dev/null`
10
-	if test "X$pid" = "X"; then
11
-		# file can be removed between the 'test' and 'cat',
12
-		# it happened a few times for me
13
-		return
14
-	fi
15
-	kill -0 $pid 2>/dev/null || return
16
-	kill $pid
17
-	pippo=0
18
-	while kill -0 $pid 2>/dev/null; do
19
-		sleep 1
20
-		pippo=`expr $pippo + 1`
21
-		if test $pippo -gt 9; then
22
-			kill -KILL $pid
23
-			echo "Clamd didn't quit";
24
-			rm -f clamd-test.pid
25
-			exit 4;
26
-		fi
27
-	done
28
-	rm -f clamd-test.pid
29
-}
30
-
31
-die()
32
-{
33
-	killclamd
34
-	exit $1
35
-}
36
-
37
-error()
38
-{
39
-	echo >&2
40
-	echo "***" >&2
41
-	echo "*** $1" >&2
42
-	echo "***" >&2
43
-}
44
-
45
-scan_failed() {
46
-	if test "X$unrar_disabled" = "X1" && test `grep -v '\.rar' $1 | grep OK | wc -l` -eq 0
47
-	then
48
-		error "UNRAR is disabled, won't be able to detect unrar files!";
49
-	else
50
-		error  $2;
51
-		die 2;
52
-	fi
53
-}
54
-
55
-start_clamd()
56
-{
57
-	rm -f clamd-test.log ../clamd-test1.log ../clamd-test2.log
58
-	$LTEXEC $CLAMD_WRAPPER $TOP/clamd/clamd -c $1 --help >clamd-test.log 2>&1 || 
59
-		{ error "Failed to start clamd --help!"; cat clamd-test.log; die 1; }
60
-	grep "Clam AntiVirus Daemon" clamd-test.log >/dev/null ||
61
-		{ error "Wrong --help reply from clamd!"; die 1; }
62
-	$LTEXEC $CLAMD_WRAPPER $TOP/clamd/clamd -c $1 >clamd-test.log 2>&1 || 
63
-		{ error "Failed to start clamd!"; cat clamd-test.log; die 1; }
64
-}
65
-
66
-run_clamdscan_fileonly() {
67
-	rm -f clamdscan.log clamdscan-multiscan.log
68
-	$TOP/clamdscan/clamdscan --version --config-file=test-clamd.conf 2>&1|grep "^ClamAV" >/dev/null || 
69
-		{ error "clamdscan can't get version of clamd!"; die 1;}
70
-	$TOP/clamdscan/clamdscan --quiet --config-file=test-clamd.conf $* --log=clamdscan.log
71
-	if test $? = 2; then 
72
-		error "Failed to run clamdscan!"
73
-		cat clamdscan.log
74
-		die 1
75
-	fi
76
-	$TOP/clamdscan/clamdscan --quiet --config-file=test-clamd.conf $* -m --log=clamdscan-multiscan.log
77
-	if test $? = 2; then 
78
-		error "Failed to run clamdscan (multiscan)!"
79
-		cat clamdscan-multiscan.log
80
-		die 1
81
-	fi
82
-}
83
-
84
-run_clamdscan() {
85
-	run_clamdscan_fileonly $*
86
-	rm -f clamdscan-fdpass.log clamdscan-multiscan-fdpass.log
87
-	$TOP/clamdscan/clamdscan --quiet --config-file=test-clamd.conf $* --fdpass --log=clamdscan-fdpass.log
88
-	if test $? = 2; then 
89
-		error "Failed to run clamdscan (fdpass)!"
90
-		cat clamdscan-fdpass.log
91
-		die 1
92
-	fi
93
-	$TOP/clamdscan/clamdscan --quiet --config-file=test-clamd.conf $* -m --fdpass --log=clamdscan-multiscan-fdpass.log
94
-	if test $? = 2; then 
95
-		error "Failed to run clamdscan (fdpass + multiscan)!"
96
-		cat clamdscan-multiscan-fdpass.log
97
-		die 1
98
-	fi
99
-	$TOP/clamdscan/clamdscan --quiet --config-file=test-clamd.conf $* --stream --log=clamdscan-stream.log
100
-	if test $? = 2; then 
101
-		error "Failed to run clamdscan (instream)!"
102
-		cat clamdscan-stream.log
103
-		die 1
104
-	fi
105
-	$TOP/clamdscan/clamdscan --quiet --config-file=test-clamd.conf $* -m --stream --log=clamdscan-multiscan-stream.log
106
-	if test $? = 2; then 
107
-		error "Failed to run clamdscan (instream + multiscan)!"
108
-		cat clamdscan-multiscan-stream.log
109
-		die 1
110
-	fi
111
-}
112
-
113
-run_reload_test()
114
-{
115
-	rm -f reload-testfile
116
-	echo "ClamAV-RELOAD-Test" >reload-testfile
117
-	run_clamdscan reload-testfile
118
-	grep "ClamAV-RELOAD-TestFile" clamdscan.log >/dev/null 2>/dev/null;
119
-	if test $? -eq 0; then
120
-		# it is not supposed to detect until we actually put the
121
-		# signature there and reload!
122
-		error "RELOAD test failed!"
123
-		cat clamdscan.log
124
-		die 10
125
-	fi
126
-	echo "ClamAV-RELOAD-TestFile:0:0:436c616d41562d52454c4f41442d54657374" >test-db/new.ndb
127
-	$TOP/clamdscan/clamdscan --reload --config-file=test-clamd.conf
128
-	if test $? -ne 0; then
129
-		error "clamdscan says reload failed!"
130
-		die 11
131
-	fi
132
-	run_clamdscan reload-testfile
133
-	grep "ClamAV-RELOAD-TestFile" clamdscan.log >/dev/null 2>/dev/null;
134
-	failed=0
135
-	if test $? -ne 0; then
136
-		error "RELOAD test failed! (after reload)"
137
-		cat clamdscan.log
138
-		failed=1
139
-	fi
140
-	grep "ClamAV-RELOAD-TestFile" clamdscan-multiscan.log >/dev/null 2>/dev/null;
141
-	if test $? -ne 0; then
142
-		error "RELOAD test failed! (after reload, multiscan)"
143
-		cat clamdscan-multiscan.log
144
-		failed=1
145
-	fi
146
-	if test "$failed" = "1"; then
147
-		echo "RELOAD tests failed!"
148
-		die 12
149
-	fi
150
-	rm -f reload-testfile
151
-}
152
-
153
-run_clamdscan_fdpass() {
154
-	rm -f clamdscan.log
155
-	$TOP/clamdscan/clamdscan --quiet --fdpass --config-file=test-clamd.conf - <$1 --log=clamdscan.log
156
-	if test $? = 2; then
157
-		error "Failed to run clamdscan (fdpass)!"
158
-		cat clamdscan.log
159
-		die 14
160
-	fi
161
-}
162
-
163
-# We run multiple clamd tests in parallel, each in its own directory
164
-prepare_clamd()
165
-{
166
-	cd clamdtest$1 
167
-	# Set up test DBdir
168
-	rm -rf test-db
169
-	mkdir -p test-db
170
-	cat <<EOF >test-db/test.hdb
171
-aa15bcf478d165efd2065190eb473bcb:544:ClamAV-Test-File
172
-EOF
173
-	cp $abs_srcdir/input/daily.pdb test-db/
174
-	$AWK "{ sub(/X/,\"$1\"); sub(/CWD/,\"`pwd`\"); print }" $abs_srcdir/test-clamd.conf >test-clamd.conf
175
-}
176
-
177
-rm -rf clamdtest$CLAMD_TEST_UNIQ1 clamdtest$CLAMD_TEST_UNIQ2
178
-mkdir clamdtest$CLAMD_TEST_UNIQ1 clamdtest$CLAMD_TEST_UNIQ2 || 
179
-	{ echo "Unable to create temporary directories!"; exit 1; }
180
-
181
-# Prepare configuration for clamd #1 and #2
182
-(prepare_clamd $CLAMD_TEST_UNIQ1)
183
-(prepare_clamd $CLAMD_TEST_UNIQ2)
184
-# Add clamd #2 specific configuration
185
-echo "VirusEvent $abs_srcdir/virusaction-test.sh `pwd`/clamdtest$CLAMD_TEST_UNIQ2 \"Virus found: %v\"" >>clamdtest$CLAMD_TEST_UNIQ2/test-clamd.conf
186
-echo "HeuristicScanPrecedence yes" >>clamdtest$CLAMD_TEST_UNIQ2/test-clamd.conf
187
-grep -v LogFile clamdtest$CLAMD_TEST_UNIQ2/test-clamd.conf >tmp__
188
-mv tmp__ clamdtest$CLAMD_TEST_UNIQ2/test-clamd.conf
189
-
190
-# Start clamd #1 tests
191
-(cd clamdtest$CLAMD_TEST_UNIQ1 
192
-start_clamd test-clamd.conf
193
-
194
-# Test that all testfiles are detected
195
-FILES=$TOP/test/clam*
196
-run_clamdscan $FILES
197
-NFILES=`ls -1 $FILES | wc -l`
198
-NINFECTED=`grep "Infected files" clamdscan.log | cut -f2 -d:|sed -e 's/ //g'`
199
-NINFECTED_MULTI=`grep "Infected files" clamdscan-multiscan.log | cut -f2 -d:|sed -e 's/ //g'`
200
-NINFECTED_FDPASS=`grep "Infected files" clamdscan-fdpass.log | cut -f2 -d:|sed -e 's/ //g'`
201
-NINFECTED_MULTI_FDPASS=`grep "Infected files" clamdscan-multiscan-fdpass.log | cut -f2 -d:|sed -e 's/ //g'`
202
-NINFECTED_STREAM=`grep "Infected files" clamdscan-stream.log | cut -f2 -d:|sed -e 's/ //g'`
203
-NINFECTED_MULTI_STREAM=`grep "Infected files" clamdscan-multiscan-stream.log | cut -f2 -d:|sed -e 's/ //g'`
204
-if test "$NFILES" -ne "0$NINFECTED"; then
205
-	grep OK clamdscan.log
206
-	scan_failed clamdscan.log "clamd did not detect all testfiles correctly!"
207
-fi
208
-if test "$NFILES" -ne "0$NINFECTED_MULTI"; then
209
-	grep OK clamdscan-multiscan.log
210
-	scan_failed clamdscan-multiscan.log "clamd did not detect all testfiles correctly in multiscan mode!"
211
-fi
212
-if test "$NFILES" -ne "0$NINFECTED_FDPASS"; then
213
-	grep OK clamdscan-fdpass.log
214
-	scan_failed clamdscan-multiscan.log "clamd did not detect all testfiles correctly in fdpass mode!"
215
-fi
216
-if test "$NFILES" -ne "0$NINFECTED_MULTI_FDPASS"; then
217
-	grep OK clamdscan-multiscan-fdpass.log
218
-	scan_failed clamdscan-multiscan.log "clamd did not detect all testfiles correctly in fdpass+multiscan mode!"
219
-fi
220
-
221
-$TOP/unit_tests/check_clamd
222
-ecode=$?
223
-if test $ecode -ne 77 && test $ecode -ne 0; then
224
-    error "Failed clamd protocol test!"
225
-    die 1
226
-fi
227
-# Test HeuristicScanPrecedence off feature
228
-run_clamdscan ../clam-phish-exe
229
-grep "ClamAV-Test-File" clamdscan.log >/dev/null 2>/dev/null;
230
-if test $? -ne 0; then
231
-	error "HeuristicScanPrecedence off test failed!"
232
-	cat clamdscan.log
233
-	die 4
234
-fi
235
-die 0
236
-)&
237
-pid1=$!
238
-
239
-# Start clamd #2 tests
240
-(cd clamdtest$CLAMD_TEST_UNIQ2
241
-start_clamd test-clamd.conf
242
-
243
-# Test VirusEvent feature
244
-run_clamdscan_fileonly $TOP/test/clam.exe
245
-grep "Virus found: ClamAV-Test-File.UNOFFICIAL" test-clamd.log >/dev/null 2>/dev/null; 
246
-if test $? -ne 0; then
247
-	error "Virusaction test failed!" 
248
-	cat test-clamd.log
249
-	die 2
250
-fi
251
-
252
-# Test HeuristicScanPrecedence feature
253
-run_clamdscan ../clam-phish-exe
254
-grep "Phishing.Heuristics.Email.SpoofedDomain" clamdscan.log >/dev/null 2>/dev/null;
255
-if test $? -ne 0; then
256
-	error "HeuristicScanPrecedence on test failed!"
257
-	cat clamdscan.log
258
-	die 3
259
-fi
260
-
261
-if grep "^#define HAVE_FD_PASSING 1" $TOP/clamav-config.h >/dev/null; then
262
-	run_clamdscan_fdpass $TOP/test/clam.exe
263
-	grep "ClamAV-Test-File" clamdscan.log >/dev/null 2>/dev/null;
264
-	if test $? -ne 0; then
265
-		error "FDpassing test failed!"
266
-		cat clamdscan.log;
267
-		die 4
268
-	fi
269
-else
270
-	echo "*** No file descriptor passing support, skipping test"
271
-fi
272
-
273
-# Test RELOAD command
274
-run_reload_test
275
-
276
-die 0
277
-)&
278
-
279
-pid2=$!
280
-
281
-wait $pid1
282
-exitcode1=$?
283
-wait $pid2
284
-exitcode2=$?
285
-rm -rf clamdtest$CLAMD_TEST_UNIQ1 clamdtest$CLAMD_TEST_UNIQ2 test-db accdenied
286
-if (test $exitcode1 -ne 0 && test $exitcode1 -ne 127) || (test $exitcode2 -ne 0	&& test $exitcode2 -ne 127); then
287
-	exit 1
288
-fi
289
-exit 0
290 1
deleted file mode 100755
... ...
@@ -1,66 +0,0 @@
1
-#!/bin/sh 
2
-CLAMSCAN_WRAPPER=${CLAMSCAN_WRAPPER-}
3
-die() {
4
-	rm -rf test-db
5
-	exit $1;
6
-}
7
-
8
-scan_failed() {
9
-	if test "X$unrar_disabled" = "X1" && test `grep -v '\.rar' $1 | grep OK | wc -l` -eq 0
10
-	then
11
-		echo "***" >&2;
12
-		echo "*** UNRAR is disabled, won't be able to detect unrar files!" >&2;
13
-		echo "***" >&2;
14
-	else
15
-		echo "clamscan did not detect all testfiles correctly!" >&2;
16
-		die 2;
17
-	fi
18
-}
19
-
20
-mkdir test-db
21
-cat <<EOF >test-db/test.hdb
22
-aa15bcf478d165efd2065190eb473bcb:544:ClamAV-Test-File
23
-EOF
24
-rm -f clamscan.log
25
-../libtool --mode=execute $CLAMSCAN_WRAPPER ../clamscan/clamscan --quiet -dtest-db/test.hdb ../test/clam* --log=clamscan.log
26
-if test $? != 1; then
27
-	echo "Error running clamscan: $?" >&2;
28
-	grep OK clamscan.log >&2;
29
-	die 1;
30
-fi
31
-NFILES=`ls -1 ../test/clam* | wc -l`
32
-NINFECTED=`grep "Infected files" clamscan.log | cut -f2 -d: |sed -e 's/ //g'`
33
-if test "$NFILES" -ne "0$NINFECTED"; then
34
-	grep OK clamscan.log >&2;
35
-	scan_failed clamscan.log
36
-fi
37
-
38
-cat <<EOF >test-db/test.pdb
39
-H:example.com
40
-EOF
41
-rm -f clamscan2.log
42
-../clamscan/clamscan  -dtest-db $abs_srcdir/input/phish-test-* --log=clamscan2.log --quiet
43
-val=$?
44
-if test $val != 0; then
45
-	if test $val = 1; then
46
-		echo "clamscan detected a file it shouldn't" >&2
47
-		grep FOUND clamscan2.log
48
-		die 3;
49
-	fi
50
-	echo "Error running clamscan: $val" >&2;
51
-	die 3;
52
-fi
53
-
54
-rm -f clamscan2.log
55
-../clamscan/clamscan --phishing-ssl --phishing-cloak -dtest-db $abs_srcdir/input/phish-test-* --log=clamscan2.log --quiet
56
-val=$?
57
-if test $val != 1; then
58
-	echo "Error running clamscan: $val" >&2;
59
-	die 3;
60
-fi
61
-grep "phish-test-ssl: Phishing.Heuristics.Email.SSL-Spoof FOUND" clamscan2.log >/dev/null && grep "phish-test-cloak: Phishing.Heuristics.Email.Cloaked.Null FOUND" clamscan2.log >/dev/null
62
-if test $? -ne 0; then
63
-	echo "Error on ssl/cloak phishing test" >&2;
64
-	die 4;
65
-fi
66
-die 0;
67 1
new file mode 100644
... ...
@@ -0,0 +1,319 @@
0
+#!/bin/sh
1
+set -e
2
+
3
+WRAPPER=${WRAPPER-}
4
+TOP=`pwd`/..
5
+CLAMSCAN=$TOP/clamscan/clamscan
6
+CLAMD=$TOP/clamd/clamd
7
+CHECK_CLAMD=$TOP/unit_tests/check_clamd
8
+CLAMDSCAN=$TOP/clamdscan/clamdscan
9
+TESTFILES=$TOP/test/clam*
10
+NFILES=`ls -1 $TESTFILES | wc -l`
11
+
12
+killclamd() {
13
+    test -f clamd-test.pid &&
14
+    pid=`cat clamd-test.pid 2>/dev/null` &&
15
+    test -n "$pid" &&
16
+    kill -0 $pid 2>/dev/null &&
17
+    kill $pid 2>/dev/null &&
18
+    kill -0 $pid 2>/dev/null &&
19
+    sleep 1 &&
20
+    kill -0 $pid 2>/dev/null &&
21
+    sleep 9 &&
22
+    kill -0 $pid 2>/dev/null &&
23
+    echo "Killing stuck clamd!" &&
24
+    kill -KILL $pid && exit 109 || true
25
+}
26
+
27
+error()
28
+{
29
+	echo >&2
30
+	echo "***" >&2
31
+	echo "*** $1" >&2
32
+	echo "***" >&2
33
+}
34
+
35
+die()
36
+{
37
+	error "$1"
38
+	test -f valgrind.log && cat valgrind.log || true
39
+	killclamd
40
+	exit 42
41
+}
42
+
43
+# Setup test directory to avoid temporary and output file clashes
44
+test_start() {
45
+    ulimit -t 120; ulimit -d 512000; ulimit -v 512000;
46
+    (cd test-$1 2>/dev/null && killclamd || true)
47
+    rm -rf test-$1
48
+    mkdir test-$1
49
+    cd test-$1
50
+    mkdir test-db
51
+    cat <<EOF >test-db/test.hdb
52
+aa15bcf478d165efd2065190eb473bcb:544:ClamAV-Test-File
53
+EOF
54
+    cat <<EOF >test-clamd.conf
55
+LogFile `pwd`/clamd-test.log
56
+LogFileMaxSize 0
57
+LogTime yes
58
+Debug yes
59
+LogClean yes
60
+LogVerbose yes
61
+PidFile `pwd`/clamd-test.pid
62
+DatabaseDirectory `pwd`/test-db
63
+LocalSocket clamd-test.socket
64
+TCPAddr 127.0.0.1
65
+# using different port here to avoid conflicts with system clamd daemon
66
+TCPSocket 331$1
67
+ExitOnOOM yes
68
+DetectPUA yes
69
+ScanPDF yes
70
+CommandReadTimeout 1
71
+MaxQueue 800
72
+MaxConnectionQueueLength 1024
73
+EOF
74
+}
75
+
76
+# arg1: expected exitcode
77
+test_run() {
78
+   expected=$1
79
+   shift
80
+   set +e
81
+   $TOP/libtool --mode=execute $WRAPPER $*
82
+   val=$?
83
+   if test $val -ne $expected; then
84
+       error "Failed to run $*, expected $expected exitcode, but was $val" >&2;
85
+       return 0;
86
+   fi
87
+   set -e
88
+   return 1;
89
+}
90
+
91
+# Run a test and return its exitcode
92
+test_run_check() {
93
+    set +e
94
+    $TOP/libtool --mode=execute $WRAPPER $*
95
+    val=$?
96
+    set -e
97
+    return $?;
98
+}
99
+
100
+# test successfully finished, remove test dir
101
+test_end() {
102
+    killclamd
103
+    cd ..
104
+    rm -rf test-$1
105
+}
106
+
107
+scan_failed() {
108
+    if test "X$unrar_disabled" = "X1" && test `grep -v '\.rar' $1 | grep OK | wc -l` -eq 0
109
+    then
110
+	error "UNRAR is disabled, won't be able to detect unrar files!"
111
+    else
112
+	cat $1
113
+    	die "$2";
114
+    fi
115
+}
116
+
117
+# ----------- valgrind wrapper 
118
+init_valgrind() {
119
+    test "x$VG" = "x1" || { echo "*** valgrind tests skipped by default, use 'make check VG=1' to activate"; exit 77; }
120
+    export VALGRIND=`which ${VALGRIND-valgrind}`
121
+    export VALGRIND_COMMON_FLAGS="-v --trace-children=yes --suppressions=$abs_srcdir/valgrind.supp --log-file=valgrind.log --error-exitcode=123 $GENSUPP"
122
+    export VALGRIND_FLAGS="$VALGRIND_COMMON_FLAGS --track-fds=yes --leak-check=full"
123
+    export VALGRIND_FLAGS_RACE="$VALGRIND_COMMON_FLAGS --tool=helgrind"
124
+    test -n "$VALGRIND" || { echo "*** valgrind not found, skipping test"; exit 77; }
125
+    test -x "$VALGRIND" || { echo "*** valgrind not executable, skipping test"; exit 77; }
126
+}
127
+
128
+init_helgrind() {
129
+    init_valgrind
130
+}
131
+
132
+end_valgrind() {
133
+    NRUNS=`grep -a "ERROR SUMMARY" valgrind.log | wc -l`
134
+    if test $NRUNS -ne `grep -a "ERROR SUMMARY: 0 errors" valgrind.log | wc -l` || 
135
+	test `grep -a "FATAL:" valgrind.log|wc -l` -ne 0; then
136
+	cat valgrind.log
137
+	die "Valgrind tests failed"
138
+    fi
139
+}
140
+
141
+# ----------- clamscan tests --------------------------------------------------------
142
+test_clamscan() {
143
+    test_start $1
144
+    if test_run 1 $CLAMSCAN --quiet -dtest-db/test.hdb $TESTFILES --log=clamscan.log; then
145
+	scan_failed clamscan.log "clamscan didn't detect all testfiles correctly"
146
+    fi
147
+    NINFECTED=`grep "Infected files" clamscan.log | cut -f2 -d: | sed -e 's/ //g'`
148
+    if test "$NFILES" -ne "0$NINFECTED"; then
149
+	scan_failed clamscan.log "clamscan didn't detect all testfiles correctly"
150
+    fi
151
+
152
+    cat <<EOF >test-db/test.pdb
153
+H:example.com
154
+EOF
155
+    if test_run 0 $CLAMSCAN --quiet -dtest-db $abs_srcdir/input/phish-test-* --log=clamscan2.log; then
156
+	cat clamscan2.log;
157
+	die "Failed to run clamscan (phish-test)";
158
+    fi
159
+
160
+    if test_run 1 $CLAMSCAN --quiet --phishing-ssl --phishing-cloak -dtest-db $abs_srcdir/input/phish-test-* --log=clamscan3.log; then
161
+	cat clamscan3.log;
162
+	die "Failed to run clamscan (phish-test2)";
163
+    fi
164
+
165
+    grep "phish-test-ssl: Phishing.Heuristics.Email.SSL-Spoof FOUND" clamscan3.log >/dev/null || die "phish-test1 failed";
166
+    grep "phish-test-cloak: Phishing.Heuristics.Email.Cloaked.Null FOUND" clamscan3.log >/dev/null || die "phish-test2 failed";
167
+    test_end $1
168
+}
169
+
170
+# ----------- clamd tests --------------------------------------------------------
171
+start_clamd()
172
+{
173
+    cp $abs_srcdir/input/daily.pdb test-db/daily.pdb
174
+    if test_run 0 $CLAMD -c test-clamd.conf --help >clamd-test.log; then
175
+	die "Failed to run clamd --help";
176
+    fi
177
+    grep "Clam AntiVirus Daemon" clamd-test.log >/dev/null || die "Wrong --help reply from clamd!";
178
+    if test_run 0 $CLAMD -c test-clamd.conf >clamd-test.log 2>&1; then
179
+	cat clamd-test.log
180
+	die "Failed to run clamd";
181
+    fi
182
+}
183
+
184
+run_clamdscan_fileonly() {
185
+    rm -f clamdscan.log clamdscan-multiscan.log
186
+    $CLAMDSCAN --version --config-file=test-clamd.conf | grep "^ClamAV" >/dev/null || die "clamdscan can't get version of clamd!";
187
+    set +e
188
+    $CLAMDSCAN --quiet --config-file=test-clamd.conf $* --log=clamdscan.log
189
+    if test $? = 2; then
190
+	die "Failed to run clamdscan!"
191
+    fi
192
+    $CLAMDSCAN --quiet --config-file=test-clamd.conf $* -m --log=clamdscan-multiscan.log
193
+    if test $? = 2; then
194
+	die "Failed to run clamdscan (multiscan)!"
195
+    fi
196
+    set -e
197
+}
198
+
199
+run_clamdscan() {
200
+    run_clamdscan_fileonly $*
201
+    rm -f clamdscan-fdpass.log clamdscan-multiscan-fdpass.log clamdscan-stream.log clamdscan-multiscan-stream.log
202
+    set +e
203
+    $CLAMDSCAN --quiet --config-file=test-clamd.conf $* --fdpass --log=clamdscan-fdpass.log
204
+    if test $? = 2; then 
205
+	die "Failed to run clamdscan (fdpass)!"
206
+    fi
207
+    $CLAMDSCAN --quiet --config-file=test-clamd.conf $* -m --fdpass --log=clamdscan-multiscan-fdpass.log
208
+    if test $? = 2; then 
209
+        die "Failed to run clamdscan (fdpass + multiscan)!"
210
+    fi
211
+    $CLAMDSCAN --quiet --config-file=test-clamd.conf $* --stream --log=clamdscan-stream.log
212
+    if test $? = 2; then 
213
+    	die "Failed to run clamdscan (instream)!"
214
+    fi
215
+    $CLAMDSCAN --quiet --config-file=test-clamd.conf $* -m --stream --log=clamdscan-multiscan-stream.log
216
+    if test $? = 2; then 
217
+	die "Failed to run clamdscan (instream + multiscan)!"
218
+    fi
219
+    set -e
220
+}
221
+
222
+run_reload_test()
223
+{
224
+	echo "ClamAV-RELOAD-Test" >reload-testfile
225
+	run_clamdscan reload-testfile
226
+	# it is not supposed to detect until we actually put the
227
+	# signature there and reload!
228
+	grep "ClamAV-RELOAD-TestFile" clamdscan.log >/dev/null 2>/dev/null && die "RELOAD test(1) failed!"
229
+	echo "ClamAV-RELOAD-TestFile:0:0:436c616d41562d52454c4f41442d54657374" >test-db/new.ndb
230
+	$CLAMDSCAN --reload --config-file=test-clamd.conf || die "clamdscan says reload failed!"
231
+	run_clamdscan reload-testfile
232
+	failed=0
233
+	grep "ClamAV-RELOAD-TestFile" clamdscan.log >/dev/null 2>/dev/null || die "RELOAD test failed! (after reload)"
234
+	grep "ClamAV-RELOAD-TestFile" clamdscan-multiscan.log >/dev/null 2>/dev/null || die "RELOAD test failed! (after reload, multiscan)"
235
+}
236
+
237
+run_clamdscan_fdpass() {
238
+    set +e
239
+    $CLAMDSCAN --quiet --fdpass --config-file=test-clamd.conf - <$1 --log=clamdscan.log
240
+    if test $? = 2; then
241
+    	die "Failed to run clamdscan (fdpass)!"
242
+    fi
243
+    set -e
244
+}
245
+
246
+test_clamd1() {
247
+    test_start $1
248
+    start_clamd
249
+    # Test that all testfiles are detected
250
+    run_clamdscan $TESTFILES
251
+    NINFECTED=`grep "Infected files" clamdscan.log | cut -f2 -d:|sed -e 's/ //g'`
252
+    NINFECTED_MULTI=`grep "Infected files" clamdscan-multiscan.log | cut -f2 -d:|sed -e 's/ //g'`
253
+    NINFECTED_FDPASS=`grep "Infected files" clamdscan-fdpass.log | cut -f2 -d:|sed -e 's/ //g'`
254
+    NINFECTED_MULTI_FDPASS=`grep "Infected files" clamdscan-multiscan-fdpass.log | cut -f2 -d:|sed -e 's/ //g'`
255
+    NINFECTED_STREAM=`grep "Infected files" clamdscan-stream.log | cut -f2 -d:|sed -e 's/ //g'`
256
+    NINFECTED_MULTI_STREAM=`grep "Infected files" clamdscan-multiscan-stream.log | cut -f2 -d:|sed -e 's/ //g'`
257
+    if test "$NFILES" -ne "0$NINFECTED"; then
258
+	scan_failed clamdscan.log "clamd did not detect all testfiles correctly!"
259
+    fi
260
+    if test "$NFILES" -ne "0$NINFECTED_MULTI"; then
261
+	scan_failed clamdscan-multiscan.log "clamd did not detect all testfiles correctly in multiscan mode!"
262
+    fi
263
+    if test "$NFILES" -ne "0$NINFECTED_FDPASS"; then
264
+	scan_failed clamdscan-multiscan.log "clamd did not detect all testfiles correctly in fdpass mode!"
265
+    fi
266
+    if test "$NFILES" -ne "0$NINFECTED_MULTI_FDPASS"; then
267
+	scan_failed clamdscan-multiscan.log "clamd did not detect all testfiles correctly in fdpass+multiscan mode!"
268
+    fi
269
+    # Test HeuristicScanPrecedence off feature
270
+    run_clamdscan ../clam-phish-exe
271
+    grep "ClamAV-Test-File" clamdscan.log >/dev/null 2>/dev/null;
272
+    if test $? -ne 0; then
273
+	cat clamdscan.log
274
+	die "HeuristicScanPrecedence off test failed!"
275
+    fi
276
+    test_end $1
277
+}
278
+
279
+test_clamd2() {
280
+    test_start $1
281
+    start_clamd
282
+    # Run clamd test suite
283
+    test_run_check $CHECK_CLAMD
284
+    val=$?
285
+
286
+    # Test RELOAD command
287
+    run_reload_test
288
+
289
+    test_end $1
290
+    exit $?
291
+}
292
+
293
+test_clamd3() {
294
+    test_start $1
295
+    echo "VirusEvent $abs_srcdir/virusaction-test.sh `pwd` \"Virus found: %v\"" >>test-clamd.conf
296
+    echo "HeuristicScanPrecedence yes" >>test-clamd.conf
297
+    start_clamd
298
+    # Test HeuristicScanPrecedence feature
299
+    run_clamdscan ../clam-phish-exe
300
+    grep "Phishing.Heuristics.Email.SpoofedDomain" clamdscan.log >/dev/null 2>/dev/null ||
301
+        { cat clamdscan.log; die "HeuristicScanPrecedence on test failed!"; }
302
+
303
+    if grep "^#define HAVE_FD_PASSING 1" $TOP/clamav-config.h >/dev/null; then
304
+	run_clamdscan_fdpass $TOP/test/clam.exe
305
+	grep "ClamAV-Test-File" clamdscan.log >/dev/null 2>/dev/null ||
306
+	{ cat clamdscan.log; die "FDpassing test failed!";}
307
+    else
308
+	echo "*** No file descriptor passing support, skipping test"
309
+    fi
310
+
311
+    # Test VirusEvent feature
312
+    run_clamdscan_fileonly $TOP/test/clam.exe
313
+    test -f test-clamd.log || sleep 1
314
+    grep "Virus found: ClamAV-Test-File.UNOFFICIAL" test-clamd.log >/dev/null 2>/dev/null ||
315
+	{ cat test-clamd.log || true; die "Virusaction test failed"; }
316
+
317
+    test_end $1
318
+}
... ...
@@ -116,7 +116,7 @@ START_TEST (test_bm_scanbuff) {
116 116
     ret = cli_parse_add(root, "Sig3", "babedead", 0, 0, "*", 0, NULL, 0);
117 117
     fail_unless(ret == CL_SUCCESS, "cli_parse_add() failed");
118 118
 
119
-    ret = cli_bm_scanbuff("blah\xde\xad\xbe\xef", 12, &virname, root, 0, -1);
119
+    ret = cli_bm_scanbuff("blah\xde\xad\xbe\xef", 12, &virname, root, 0, -1,NULL);
120 120
     fail_unless(ret == CL_VIRUS, "cli_bm_scanbuff() failed");
121 121
     fail_unless(!strncmp(virname, "Sig2", 4), "Incorrect signature matched in cli_bm_scanbuff()\n");
122 122
     cli_bm_free(root);
123 123
deleted file mode 100644
... ...
@@ -1,19 +0,0 @@
1
-# script will fill in CWD and X
2
-LogFile CWD/../clamd-testX.log
3
-LogFileMaxSize 0
4
-LogTime yes
5
-Debug yes
6
-LogClean yes
7
-LogVerbose yes
8
-PidFile CWD/clamd-test.pid
9
-DatabaseDirectory CWD/test-db
10
-LocalSocket clamd-test.socket
11
-TCPAddr 127.0.0.1
12
-# using different port here to avoid conflicts with system clamd daemon
13
-TCPSocket 331X
14
-ExitOnOOM yes
15
-DetectPUA yes
16
-ScanPDF yes
17
-CommandReadTimeout 1
18
-MaxQueue 800
19
-MaxConnectionQueueLength 1024
... ...
@@ -1,343 +0,0 @@
1
-{
2
-	glibc-freeres-dbg
3
-	Memcheck:Free
4
-	fun:free
5
-	fun:free_mem
6
-	fun:__libc_freeres
7
-}
8
-{
9
-	glibc-freeres
10
-	Memcheck:Free
11
-	fun:free
12
-	obj:/lib*/libc-*.so
13
-	fun:__libc_freeres
14
-}
15
-{
16
-	glibc-etch1
17
-	Memcheck:Free
18
-	fun:*
19
-	fun:_dl_allocate_tls
20
-}
21
-{
22
-	glibc-etch2
23
-	Memcheck:Free
24
-	obj:/lib*/ld-*.so
25
-	obj:/lib*/ld-*.so
26
-}
27
-{
28
-       glibc-etch1
29
-       Memcheck:Free
30
-       fun:*
31
-       fun:_dl_allocate_tls
32
-}
33
-{
34
-       glibc-etch2
35
-       Memcheck:Addr8
36
-       obj:/lib*/ld-*.so
37
-       obj:/lib*/ld-*.so
38
-}
39
-{
40
-       glibc-etch2
41
-       Memcheck:Addr4
42
-       obj:/lib*/ld-*.so
43
-       obj:/lib*/ld-*.so
44
-}
45
-{
46
-	helgrind-glibc27-dbg01
47
-	Helgrind:Race
48
-	fun:mythread_wrapper
49
-	fun:start_thread
50
-}
51
-{
52
-	helgrind-glibc27-dbg02
53
-	Helgrind:Race
54
-	fun:pthread_mutex_*
55
-}
56
-{
57
-	helgrind-glibc27-dbg03
58
-	Helgrind:Race
59
-	fun:pthread_create*
60
-}
61
-{
62
-	helgrind-glibc27-dbg04
63
-	Helgrind:Race
64
-	fun:pthread_create*
65
-}
66
-{
67
-	helgrind-glibc27-dbg05
68
-	Helgrind:Race
69
-	fun:__deallocate_stack
70
-	fun:start_thread
71
-}
72
-{
73
-	helgrind-glibc27-dbg05
74
-	Helgrind:Race
75
-	fun:free_stacks
76
-	fun:__deallocate_stack
77
-	fun:start_thread
78
-}
79
-{
80
-	helgrind-glibc27-dbg06
81
-	Helgrind:Race
82
-	fun:*
83
-	obj:/usr/lib/debug/libpthread-*.so
84
-}
85
-{
86
-	helgrind-glibc27-dbg06
87
-	Helgrind:Race
88
-	fun:*
89
-	obj:/lib/libpthread-*.so
90
-}
91
-{
92
-	helgrind-glibc27-dbg08
93
-	Helgrind:Race
94
-	obj:/lib/ld-*.so
95
-}
96
-{
97
-	helgrind-glibc27-dbg09
98
-	Helgrind:Race
99
-	fun:*
100
-	fun:exit
101
-}
102
-{
103
-	helgrind-glibc27-dbg10
104
-	Helgrind:Race
105
-	fun:*
106
-	fun:*
107
-	fun:exit
108
-}
109
-{
110
-	helgrind-glibc27-dbg11
111
-	Helgrind:Race
112
-	fun:*
113
-	fun:*
114
-	fun:*
115
-	fun:exit
116
-}
117
-{
118
-	helgrind-glibc27-dbg12
119
-	Helgrind:Race
120
-	fun:*
121
-	fun:*
122
-	fun:*
123
-	fun:*
124
-	fun:exit
125
-}
126
-{
127
-	helgrind-glibc27-dbg13
128
-	Helgrind:Race
129
-	fun:*
130
-	fun:*
131
-	fun:ctime_r
132
-}
133
-{
134
-	helgrind-glibc27-dbg15
135
-	Helgrind:Race
136
-	fun:*
137
-	fun:*
138
-	fun:*
139
-	fun:ctime_r
140
-}
141
-{
142
-	helgrind-glibc27-dbg14
143
-	Helgrind:Race
144
-	fun:_IO_link_in
145
-	fun:_IO_file_init*
146
-}
147
-# libc has a gconv_lock, but valgrind doesn't know that because it uses lll_lock
148
-# instead of pthread_mutex_lock
149
-{
150
-	helgrind-glibc27-dbg15
151
-	Helgrind:Race
152
-	fun:__gconv_release_shlib
153
-}
154
-{
155
-	helgrind-glibc27-dbg16
156
-	Helgrind:Race
157
-	fun:__gconv_find_shlib
158
-}
159
-{
160
-	helgrind-glibc27-dbg17
161
-	Helgrind:Race
162
-	fun:exit
163
-}
164
-
165
-{
166
-# suppress false positives, see bb 1189
167
-   chm-etch-gcc41-fp
168
-   Memcheck:Cond
169
-   fun:cli_chm_open
170
-   fun:cli_scanmschm
171
-}
172
-{
173
-   glibc-etch
174
-   Memcheck:Leak
175
-   fun:*
176
-   fun:_dl_allocate_tls
177
-}
178
-{
179
-   glibc-suse
180
-   Memcheck:Leak
181
-   fun:*
182
-   obj:*
183
-   fun:_dl_allocate_tls
184
-}
185
-{
186
-   glibc-tls3
187
-   Memcheck:Leak
188
-   fun:*
189
-   fun:allocate_dtv
190
-   fun:_dl_allocate_tls
191
-}
192
-{
193
-   glibc-tls4
194
-   Memcheck:Leak
195
-   fun:allocate_dtv
196
-   fun:_dl_allocate_tls
197
-}
198
-# glibc uses IO_lock_lock, which uses lll_lock,
199
-# and valgrind doesn't know about it, so it thinks it is unlocked
200
-{
201
-   glibc-IOlock-fp
202
-   Helgrind:Race
203
-   fun:*
204
-   fun:*
205
-   fun:fputs
206
-}
207
-{
208
-   glibc-IOlock-fp
209
-   Helgrind:Race
210
-   fun:fputs
211
-}
212
-{
213
-  glibc-fork
214
-  Helgrind:Race
215
-  fun:fork
216
-}
217
-{
218
-  glibc-fork
219
-  Helgrind:Race
220
-  fun:*
221
-  fun:fork
222
-}
223
-{
224
-  glibc-freetcb
225
-  Helgrind:Race
226
-  fun:__free_tcb
227
-}
228
-{
229
-  glibc-2.5-strcpy_chk
230
-  Memcheck:Addr8
231
-  obj:/lib64/libc-2.5.so
232
-  fun:decodeLine
233
-}
234
-{
235
-  glibc-2.5-strcpy_chk
236
-  Memcheck:Cond
237
-  obj:/lib64/libc-2.5.so
238
-  fun:decodeLine
239
-}
240
-{
241
-  glibc-2.5-strcpy_chk
242
-  Memcheck:Cond
243
-  obj:/lib64/libc-2.5.so
244
-  fun:cli_mbox
245
-}
246
-{
247
-  glibc-2.8-lll
248
-  Helgrind:Race
249
-  fun:__lll_unlock_wake
250
-}
251
-{ 
252
-   glibc-freeres
253
-   Helgrind:Race
254
-   fun: *
255
-   fun: __libc_thread_freeres
256
-}
257
-{
258
-   glibc-poll
259
-   Helgrind:Race
260
-   fun: __libc_enable_asynccancel
261
-   fun: poll
262
-}
263
-{
264
-   glibc-poll
265
-   Helgrind:Race
266
-   fun: _setjmp
267
-   fun: clone
268
-}
269
-{
270
-   glibc-ubuntu-jaunty
271
-   Helgrind:Race
272
-   fun:__fprintf_chk
273
-}
274
-# no symbols in opensuse's libs :(
275
-{	
276
-   glibc-suse
277
-   Helgrind:Race
278
-   obj:/lib*/ld-*.so
279
-   obj:/lib*/ld-*.so
280
-   obj:/lib*/ld-*.so
281
-}
282
-{	
283
-   glibc-suse2
284
-   Helgrind:Race
285
-   obj:/lib*/ld-*.so
286
-   obj:/lib*/ld-*.so
287
-   obj:/lib*/ld-*.so
288
-   obj:/lib*/ld-*.so
289
-}
290
-{
291
-   glibc-suse4
292
-   Helgrind:Race
293
-   obj:/lib*/libc-*.so
294
-   obj:/lib*/libc-*.so
295
-   obj:/lib*/libc-*.so
296
-}
297
-{
298
-   glibc-suse3
299
-   Helgrind:Race
300
-   obj:*
301
-   fun:start_thread
302
-}
303
-{
304
-   helgrind-glibc2X-005-valgrind-3.4.0
305
-   Helgrind:Race
306
-   obj:/lib*/libpthread-2.*so*
307
-}
308
-{
309
-   debian-libc-dbg
310
-   Helgrind:Race
311
-   fun:__pthread_mutex_*
312
-}
313
-{
314
-    debian-libc-dbg
315
-    Helgrind:Race
316
-    fun:pthread_create@*
317
-}
318
-{
319
-    debian-libc-dbg
320
-    Helgrind:Race
321
-    fun:close
322
-}
323
-{
324
-    debian-libc-dbg
325
-    Helgrind:Race
326
-    obj:/usr/lib*/debug/libpthread-2.*so*
327
-}
328
-{
329
-    sighandler-no-mutex
330
-    Helgrind:Race
331
-    fun:sighandler_th
332
-}
333
-{
334
-    sighandler-no-mutex
335
-    Helgrind:Race
336
-    fun:recvloop_th
337
-}
338
-#{
339
-#	helgrind-glibc27-dbg18
340
-#	Helgrind:Race
341
-#	fun:__reclaim_stacks
342
-#	fun:fork
343
-#}
... ...
@@ -17,12 +17,13 @@ parse_valgrindlog()
17 17
 	if test ! -f $1; then
18 18
 		echo "*** Logfile $1 not found. Valgrind failed to run?"
19 19
 	fi
20
-	NRUNS=`grep "ERROR SUMMARY" $1 | wc -l`
21
-	if test $NRUNS -eq `grep "ERROR SUMMARY: 0 errors" $1 | wc -l` && test `grep "FATAL:" $1|wc -l ` -eq 0; then
20
+	NRUNS=`grep -a "ERROR SUMMARY" $1 | wc -l`
21
+	if test $NRUNS -eq `grep -a "ERROR SUMMARY: 0 errors" $1 | wc -l` && test `grep -a "FATAL:" $1|wc -l ` -eq 0; then
22 22
 		if test "$1" = "valgrind-race.log" || 
23 23
 			test $NRUNS -eq `grep "no leaks are possible" $1 | wc -l` ||
24 24
 			test `grep "lost:" $1 | grep -v " 0 bytes" | wc -l` -eq 0; then 
25 25
 			if test -z "$GENSUPP"; then
26
+			        cp $1 /tmp
26 27
 				rm -f $1;
27 28
 			fi
28 29
 			return
... ...
@@ -62,24 +63,40 @@ else
62 62
 	GENSUPP=
63 63
 fi
64 64
 
65
-VALGRIND_COMMON_FLAGS="-v --trace-children=yes --suppressions=$abs_srcdir/valgrind.supp $GENSUPP"
65
+VALGRIND_COMMON_FLAGS="-v --trace-children=yes --suppressions=$abs_srcdir/valgrind.supp --error-exitcode=123 $GENSUPP"
66 66
 VALGRIND_FLAGS="$VALGRIND_COMMON_FLAGS --track-fds=yes --leak-check=full"
67 67
 VALGRIND_FLAGS_RACE="$VALGRIND_COMMON_FLAGS --tool=helgrind"
68 68
 export CK_DEFAULT_TIMEOUT=40
69 69
 echo "--- Starting check_clamav under valgrind/memcheck"
70 70
 rm -f valgrind-check.log valgrind-clamd.log valgrind-race.log
71
-CK_FORK=no ../libtool --mode=execute $VALGRIND $VALGRIND_FLAGS ./check_clamav >valgrind-check.log 2>&1 &
71
+CK_FORK=no ../libtool --mode=execute $VALGRIND $VALGRIND_FLAGS --log-file=valgrind-check.log ./check_clamav &
72 72
 pid1=$!
73 73
 
74 74
 echo "--- Starting clamd under valgrind/memcheck"
75
-CLAMD_WRAPPER="$VALGRIND $VALGRIND_FLAGS" $abs_srcdir/check_clamd.sh >valgrind-clamd.log 2>&1 &
75
+CLAMD_WRAPPER="$VALGRIND $VALGRIND_FLAGS --log-file=`pwd`/valgrind-clamd.log" $abs_srcdir/check_clamd.sh &
76 76
 pid2=$!
77 77
 
78 78
 echo "--- Starting clamd under valgrind/helgrind"
79
-CLAMD_TEST_UNIQ1=3 CLAMD_TEST_UNIQ2=4 CLAMD_WRAPPER="$VALGRIND $VALGRIND_FLAGS_RACE" $abs_srcdir/check_clamd.sh >valgrind-race.log 2>&1 &
79
+CLAMD_TEST_UNIQ1=3 CLAMD_TEST_UNIQ2=4 CLAMD_WRAPPER="$VALGRIND $VALGRIND_FLAGS_RACE --log-file=`pwd`/valgrind-race.log" $abs_srcdir/check_clamd.sh &
80 80
 pid3=$!
81 81
 
82
-wait $pid1 $pid2 $pid3
82
+errors=0
83
+wait $pid1
84
+if test $? -ne 0; then
85
+    # don't rm logs
86
+    GENSUPP=1
87
+    errors=1
88
+fi
89
+wait $pid2
90
+if test $? -ne 0; then
91
+    GENSUPP=1
92
+    errors=1
93
+fi
94
+wait $pid3
95
+if test $? -ne 0; then
96
+    GENSUPP=1
97
+    errors=1
98
+fi
83 99
 parse_valgrindlog valgrind-check.log
84 100
 parse_valgrindlog valgrind-clamd.log
85 101
 parse_valgrindlog valgrind-race.log
... ...
@@ -87,4 +104,4 @@ parse_valgrindlog valgrind-race.log
87 87
 if test -f valgrind-check.log || test -f valgrind-race.log || test -f valgrind-clamd.log; then
88 88
 	exit 1;
89 89
 fi
90
-exit 0
90
+exit $errors