Browse code

use mmap() when available.

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

Trog authored on 2004/05/19 17:09:50
Showing 2 changed files
... ...
@@ -1,3 +1,7 @@
1
+Wed May 19 09:10:12 BST 2004 (trog)
2
+-----------------------------------
3
+  * libclamav/ole2_extract.c: use mmap() when available.
4
+
1 5
 Tue May 18 23:14:28 CEST 2004 (tk)
2 6
 ----------------------------------
3 7
   V 0.71
... ...
@@ -34,6 +34,14 @@
34 34
 #include <stdlib.h>
35 35
 #include <clamav.h>
36 36
 
37
+#if HAVE_MMAP
38
+#if HAVE_SYS_MMAN_H
39
+#include <sys/mman.h>
40
+#else /* HAVE_SYS_MMAN_H */
41
+#undef HAVE_MMAP
42
+#endif
43
+#endif
44
+
37 45
 #include "cltypes.h"
38 46
 #include "others.h"
39 47
 
... ...
@@ -101,6 +109,8 @@ typedef struct ole2_header_tag
101 101
 	/* must take account of the size of variables below here when
102 102
 	   reading the header */
103 103
 	int32_t sbat_root_start __attribute__ ((packed));
104
+	unsigned char *m_area;
105
+	off_t m_length;
104 106
 } ole2_header_t;
105 107
 
106 108
 typedef struct property_tag
... ...
@@ -256,11 +266,19 @@ static int ole2_read_block(int fd, ole2_header_t *hdr, void *buff, int32_t block
256 256
 	
257 257
 	/* other methods: (blockno+1) * 512 or (blockno * block_size) + 512; */
258 258
 	offset = (blockno << hdr->log2_big_block_size) + 512;	/* 512 is header size */
259
-	if (lseek(fd, offset, SEEK_SET) != offset) {
260
-		return FALSE;
261
-	}
262
-	if (cli_readn(fd, buff, (1 << hdr->log2_big_block_size)) != (1 << hdr->log2_big_block_size)) {
263
-		return FALSE;
259
+	
260
+	if (hdr->m_area == NULL) {
261
+		if (lseek(fd, offset, SEEK_SET) != offset) {
262
+			return FALSE;
263
+		}
264
+		if (cli_readn(fd, buff, (1 << hdr->log2_big_block_size)) != (1 << hdr->log2_big_block_size)) {
265
+			return FALSE;
266
+		}
267
+	} else {
268
+		if ((offset + (1 << hdr->log2_big_block_size)) > hdr->m_length) {
269
+			return FALSE;
270
+		}
271
+		memcpy(buff, hdr->m_area+offset, (1 << hdr->log2_big_block_size));
264 272
 	}
265 273
 	return TRUE;
266 274
 }
... ...
@@ -673,22 +691,40 @@ int cli_ole2_extract(int fd, const char *dirname)
673 673
 {
674 674
 	ole2_header_t hdr;
675 675
 	int hdr_size;
676
+	struct stat statbuf;
676 677
 	
677 678
 	cli_dbgmsg("in cli_ole2_extract()\n");
678 679
 	
679 680
 	/* size of header - size of other values in struct */
680
-	hdr_size = sizeof(struct ole2_header_tag) - sizeof(int32_t);
681
+	hdr_size = sizeof(struct ole2_header_tag) - sizeof(int32_t) -
682
+			sizeof(unsigned char *) - sizeof(off_t);
681 683
 
682
-#if defined(HAVE_ATTRIB_PACKED) || defined(HAVE_PRAGMA_PACK)
683
-	if (cli_readn(fd, &hdr, hdr_size) != hdr_size) {
684
-		return 0;
685
-	}
686
-#else
687
-	if (!ole2_read_header(fd, &hdr)) {
688
-		return 0;
684
+	hdr.m_area = NULL;
685
+
686
+#ifdef HAVE_MMAP
687
+	if (fstat(fd, &statbuf) == 0) {
688
+		hdr.m_length = statbuf.st_size;
689
+		hdr.m_area = (unsigned char *) mmap(NULL, hdr.m_length, PROT_READ, MAP_PRIVATE, fd, 0);
690
+		if (hdr.m_area == MAP_FAILED) {
691
+			hdr.m_area = NULL;
692
+		}
693
+		cli_dbgmsg("mmap'ed file\n");
694
+		memcpy(&hdr, hdr.m_area, hdr_size);
689 695
 	}
690 696
 #endif
691 697
 
698
+	if (hdr.m_area == NULL) {
699
+#if defined(HAVE_ATTRIB_PACKED) || defined(HAVE_PRAGMA_PACK)
700
+		if (cli_readn(fd, &hdr, hdr_size) != hdr_size) {
701
+			return 0;
702
+		}
703
+#else
704
+		if (!ole2_read_header(fd, &hdr)) {
705
+			return 0;
706
+		}
707
+#endif
708
+	}
709
+	
692 710
 	hdr.minor_version = ole2_endian_convert_16(hdr.minor_version);
693 711
 	hdr.dll_version = ole2_endian_convert_16(hdr.dll_version);
694 712
 	hdr.byte_order = ole2_endian_convert_16(hdr.byte_order);
... ...
@@ -703,7 +739,7 @@ int cli_ole2_extract(int fd, const char *dirname)
703 703
 	hdr.xbat_count = ole2_endian_convert_32(hdr.xbat_count);
704 704
 
705 705
 	hdr.sbat_root_start = -1;
706
-
706
+	
707 707
 	if (strncmp(hdr.magic, magic_id, 8) != 0) {
708 708
 		cli_dbgmsg("OLE2 magic failed!\n");
709 709
 		return CL_EOLE2;
... ...
@@ -718,7 +754,7 @@ int cli_ole2_extract(int fd, const char *dirname)
718 718
 	if (hdr.sbat_cutoff != 4096) {
719 719
 		cli_dbgmsg("WARNING: untested sbat cutoff - please report\n\n");
720 720
 	}
721
-
721
+	
722 722
 	print_ole2_header(&hdr);
723 723
 
724 724
 	/* NOTE: Select only ONE of the following two methods */
... ...
@@ -728,6 +764,11 @@ int cli_ole2_extract(int fd, const char *dirname)
728 728
 	/* OR */
729 729
 	
730 730
 	ole2_walk_property_tree(fd, &hdr, dirname, 0, handler_writefile, 0, 0);
731
-	
731
+
732
+#ifdef HAVE_MMAP
733
+	if (hdr.m_area != NULL) {
734
+		munmap(hdr.m_area, hdr.m_length);
735
+	}
736
+#endif
732 737
 	return 0;
733 738
 }