git-svn-id: file:///var/lib/svn/clamav-devel/trunk/clamav-devel@687 77e5149b-7576-45b1-b177-96237e5ba77b
Trog authored on 2004/07/22 20:16:03... | ... |
@@ -48,6 +48,8 @@ |
48 | 48 |
#define FALSE (0) |
49 | 49 |
#define TRUE (1) |
50 | 50 |
|
51 |
+#define MIN(a,b) ((a < b) ? a : b) |
|
52 |
+ |
|
51 | 53 |
#ifndef HAVE_ATTRIB_PACKED |
52 | 54 |
#define __attribute__(x) |
53 | 55 |
#endif |
... | ... |
@@ -200,6 +202,28 @@ int chm_read_data(int fd, unsigned char *dest, off_t offset, uint32_t len, |
200 | 200 |
return TRUE; |
201 | 201 |
} |
202 | 202 |
|
203 |
+int chm_copy_file_data(int ifd, int ofd, uint64_t len) |
|
204 |
+{ |
|
205 |
+ unsigned char data[8192]; |
|
206 |
+ uint64_t count, rem; |
|
207 |
+ unsigned int todo; |
|
208 |
+ |
|
209 |
+ rem = len; |
|
210 |
+ |
|
211 |
+ while (rem > 0) { |
|
212 |
+ todo = MIN(8192, rem); |
|
213 |
+ count = cli_readn(ifd, data, todo); |
|
214 |
+ if (count != todo) { |
|
215 |
+ return len-rem; |
|
216 |
+ } |
|
217 |
+ if (cli_writen(ofd, data, count) != count) { |
|
218 |
+ return len-rem-count; |
|
219 |
+ } |
|
220 |
+ rem -= count; |
|
221 |
+ } |
|
222 |
+ return len; |
|
223 |
+} |
|
224 |
+ |
|
203 | 225 |
static void free_file_list(file_list_t *file_l) |
204 | 226 |
{ |
205 | 227 |
file_list_t *next; |
... | ... |
@@ -433,7 +457,7 @@ static int read_chunk_entries(unsigned char *chunk, uint32_t chunk_len, |
433 | 433 |
file_list_t *file_l, file_list_t *sys_file_l) |
434 | 434 |
{ |
435 | 435 |
unsigned char *current, *end; |
436 |
- uint64_t length, offset, section, name_len; |
|
436 |
+ uint64_t name_len; |
|
437 | 437 |
file_list_t *file_e; |
438 | 438 |
|
439 | 439 |
end = chunk + chunk_len; |
... | ... |
@@ -487,6 +511,7 @@ static int read_chunk_entries(unsigned char *chunk, uint32_t chunk_len, |
487 | 487 |
file_e->section, file_e->offset, |
488 | 488 |
file_e->length, file_e->name); |
489 | 489 |
} |
490 |
+ return TRUE; |
|
490 | 491 |
} |
491 | 492 |
|
492 | 493 |
static void print_chunk(chunk_header_t *chunk) |
... | ... |
@@ -797,7 +822,7 @@ abort: |
797 | 797 |
return NULL; |
798 | 798 |
} |
799 | 799 |
|
800 |
-/* ****************************************************************** |
|
800 |
+/* *****************************************************************/ |
|
801 | 801 |
/* This section interfaces to the mspack files. As such, this is a */ |
802 | 802 |
/* little bit dirty compared to my usual code */ |
803 | 803 |
|
... | ... |
@@ -822,16 +847,20 @@ static int chm_decompress_stream(int fd, const char *dirname, itsf_header_t *its |
822 | 822 |
lzx_reset_table_t *lzx_reset_table=NULL; |
823 | 823 |
lzx_control_t *lzx_control=NULL; |
824 | 824 |
int window_bits, length, ofd, retval=FALSE; |
825 |
- uint64_t offset, com_offset; |
|
825 |
+ uint64_t com_offset; |
|
826 | 826 |
struct mspack_file_p mf_in, mf_out; |
827 | 827 |
struct lzxd_stream * stream; |
828 |
- unsigned char *data, filename[1024]; |
|
828 |
+ unsigned char filename[1024]; |
|
829 | 829 |
|
830 |
- mf_in.fh = fdopen(fd, "r"); |
|
830 |
+ mf_in.desc = dup(fd); |
|
831 |
+ if (mf_in.desc < 0) { |
|
832 |
+ return FALSE; |
|
833 |
+ } |
|
834 |
+ mf_in.fh = fdopen(mf_in.desc, "r"); |
|
831 | 835 |
if (!mf_in.fh) { |
836 |
+ close(mf_in.desc); |
|
832 | 837 |
return FALSE; |
833 | 838 |
} |
834 |
- mf_in.desc = fd; |
|
835 | 839 |
mf_in.name = strdup("input"); |
836 | 840 |
|
837 | 841 |
snprintf(filename, 1024, "%s/clamav-unchm.bin", dirname); |
... | ... |
@@ -943,27 +972,21 @@ static int chm_decompress_stream(int fd, const char *dirname, itsf_header_t *its |
943 | 943 |
entry = entry->next; |
944 | 944 |
continue; |
945 | 945 |
} |
946 |
- data = (unsigned char *) cli_malloc(entry->length); |
|
947 |
- if (!data) { |
|
948 |
- goto abort; |
|
949 |
- } |
|
946 |
+ |
|
950 | 947 |
snprintf(filename, 1024, "%s/%llu.chm", dirname, entry->offset); |
951 | 948 |
ofd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, S_IRWXU); |
952 | 949 |
if (ofd < 0) { |
953 |
- free(data); |
|
954 | 950 |
entry = entry->next; |
955 | 951 |
continue; |
956 | 952 |
} |
957 |
- if ((length=cli_readn(mf_out.desc, data, entry->length)) != entry->length) { |
|
958 |
- cli_dbgmsg("read %d of %d\n", length, entry->length); |
|
953 |
+ if ((length=chm_copy_file_data(mf_out.desc, ofd, entry->length)) != entry->length) { |
|
954 |
+ cli_dbgmsg("copied %d of %d\n", length, entry->length); |
|
959 | 955 |
} |
960 |
- cli_writen(ofd, data, length); |
|
961 |
- close(ofd); |
|
962 |
- free(data); |
|
963 | 956 |
|
957 |
+ close(ofd); |
|
964 | 958 |
entry = entry->next; |
965 | 959 |
} |
966 |
- |
|
960 |
+ close(mf_out.desc); |
|
967 | 961 |
retval = TRUE; |
968 | 962 |
|
969 | 963 |
abort: |
... | ... |
@@ -982,7 +1005,6 @@ abort: |
982 | 982 |
if (mf_out.fh) { |
983 | 983 |
fclose(mf_out.fh); |
984 | 984 |
} |
985 |
- close(mf_out.desc); |
|
986 | 985 |
return retval; |
987 | 986 |
} |
988 | 987 |
|
... | ... |
@@ -992,13 +1014,12 @@ int chm_unpack(int fd, const char *dirname) |
992 | 992 |
{ |
993 | 993 |
int retval=FALSE; |
994 | 994 |
unsigned char *m_area=NULL; |
995 |
- off_t m_length, offset; |
|
995 |
+ off_t m_length=0, offset; |
|
996 | 996 |
file_list_t *file_l, *sys_file_l; |
997 | 997 |
struct stat statbuf; |
998 | 998 |
itsf_header_t itsf_hdr; |
999 | 999 |
itsp_header_t itsp_hdr; |
1000 | 1000 |
uint32_t num_chunks; |
1001 |
- chunk_header_t *chunk; |
|
1002 | 1001 |
|
1003 | 1002 |
/* These two lists contain the list of files and system files in |
1004 | 1003 |
the archive. The first entry in the list is an empty entry */ |