Browse code

extract stored files

git-svn: trunk@2563

Tomasz Kojm authored on 2006/12/20 05:14:26
Showing 4 changed files
... ...
@@ -1,3 +1,7 @@
1
+Tue Dec 19 21:13:23 CET 2006 (tk)
2
+---------------------------------
3
+  * libclamav/cab.c: extract stored files
4
+
1 5
 Tue Dec 19 15:41:35 GMT 2006 (njh)
2 6
 ----------------------------------
3 7
   * clamav-milter:	Use limits.maxmailrec (patch from TK)
... ...
@@ -540,10 +540,44 @@ static int cab_read(struct cab_file *file, unsigned char *buffer, int bytes)
540 540
     return bytes - todo;
541 541
 }
542 542
 
543
-int cab_extract(int fd, struct cab_file *file, const char *name)
543
+static int cab_unstore(struct cab_file *file, int bytes, uint8_t wflag)
544
+{
545
+	int todo;
546
+	unsigned char buff[4096];
547
+
548
+
549
+    todo = bytes;
550
+    while(1) {
551
+
552
+	if(todo <= (int) sizeof(buff)) {
553
+	    if(cab_read(file, buff, todo) == -1) {
554
+		cli_dbgmsg("cab_unstore: cab_read failed for descriptor %d\n", file->fd);
555
+		return CL_EIO;
556
+	    } else if(wflag && cli_writen(file->ofd, buff, todo) == -1) {
557
+		cli_dbgmsg("cab_unstore: Can't write to descriptor %d\n", file->ofd);
558
+		return CL_EIO;
559
+	    }
560
+	    break;
561
+
562
+	} else {
563
+	    if(cab_read(file, buff, sizeof(buff)) == -1) {
564
+		cli_dbgmsg("cab_unstore: cab_read failed for descriptor %d\n", file->fd);
565
+		return CL_EIO;
566
+	    } else if(wflag && cli_writen(file->ofd, buff, sizeof(buff)) == -1) {
567
+		cli_dbgmsg("cab_unstore: Can't write to descriptor %d\n", file->ofd);
568
+		return CL_EIO;
569
+	    }
570
+	    todo -= sizeof(buff);
571
+	}
572
+    }
573
+
574
+    return CL_SUCCESS;
575
+}
576
+
577
+int cab_extract(struct cab_file *file, const char *name)
544 578
 {
545 579
 	struct cab_folder *folder;
546
-	int ofd, ret;
580
+	int ret;
547 581
 
548 582
 
549 583
     if(!file || !name) {
... ...
@@ -556,7 +590,7 @@ int cab_extract(int fd, struct cab_file *file, const char *name)
556 556
 	return CL_ENULLARG;
557 557
     }
558 558
 
559
-    if(lseek(fd, file->folder->offset, SEEK_SET) == -1) {
559
+    if(lseek(file->fd, file->folder->offset, SEEK_SET) == -1) {
560 560
 	cli_errmsg("cab_extract: Can't lseek to %u\n", file->folder->offset);
561 561
 	return CL_EIO;
562 562
     }
... ...
@@ -567,18 +601,24 @@ int cab_extract(int fd, struct cab_file *file, const char *name)
567 567
 	return CL_EIO;
568 568
     }
569 569
 
570
-    ofd = open(name, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, S_IRWXU);
571
-    if(ofd == -1) {
570
+    file->ofd = open(name, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, S_IRWXU);
571
+    if(file->ofd == -1) {
572 572
 	cli_errmsg("cab_extract: Can't open file %s in write mode\n", name);
573 573
 	free(file->state);
574 574
 	return CL_EIO;
575 575
     }
576 576
 
577
-    /* initialize decompressors */
578 577
     switch(file->folder->cmethod & 0x000f) {
578
+	case 0x0000: /* STORE */
579
+	    if(file->offset)
580
+		cab_unstore(file, file->offset, 0);
581
+
582
+	    ret = cab_unstore(file, file->length, 1);
583
+	    break;
584
+
579 585
 	case 0x0001: /* MSZIP */
580 586
 	    cli_dbgmsg("CAB: Compression method: MSZIP\n");
581
-	    file->state->stream = (struct mszip_stream *) mszip_init(fd, ofd, 4096, 1, file, &cab_read);
587
+	    file->state->stream = (struct mszip_stream *) mszip_init(file->fd, file->ofd, 4096, 1, file, &cab_read);
582 588
 	    if(file->offset) {
583 589
 		((struct mszip_stream *) file->state->stream)->wflag = 0;
584 590
 		mszip_decompress(file->state->stream, file->offset);
... ...
@@ -590,8 +630,9 @@ int cab_extract(int fd, struct cab_file *file, const char *name)
590 590
 
591 591
 	case 0x0002: /* QUANTUM */
592 592
 	    cli_dbgmsg("CAB: Compression method: QUANTUM\n");
593
-	    file->state->stream = (struct qtm_stream *) qtm_init(fd, ofd, (int) (file->folder->cmethod >> 8) & 0x1f, 4096, file, &cab_read);
593
+	    file->state->stream = (struct qtm_stream *) qtm_init(file->fd, file->ofd, (int) (file->folder->cmethod >> 8) & 0x1f, 4096, file, &cab_read);
594 594
 	    if(file->offset) {
595
+		file->wflag = 0;
595 596
 		((struct qtm_stream *) file->state->stream)->wflag = 0;
596 597
 		qtm_decompress(file->state->stream, file->offset);
597 598
 		((struct qtm_stream *) file->state->stream)->wflag = 1;
... ...
@@ -602,7 +643,7 @@ int cab_extract(int fd, struct cab_file *file, const char *name)
602 602
 
603 603
 	case 0x0003: /* LZX */
604 604
 	    cli_dbgmsg("CAB: Compression method: LZX\n");
605
-	    file->state->stream = (struct lzx_stream *) lzx_init(fd, ofd, (int) (file->folder->cmethod >> 8) & 0x1f, 0, 4096, 0, file, &cab_read);
605
+	    file->state->stream = (struct lzx_stream *) lzx_init(file->fd, file->ofd, (int) (file->folder->cmethod >> 8) & 0x1f, 0, 4096, 0, file, &cab_read);
606 606
 	    if(file->offset) {
607 607
 		((struct lzx_stream *) file->state->stream)->wflag = 0;
608 608
 		lzx_decompress(file->state->stream, file->offset);
... ...
@@ -618,7 +659,7 @@ int cab_extract(int fd, struct cab_file *file, const char *name)
618 618
     }
619 619
 
620 620
     free(file->state);
621
-    close(ofd);
621
+    close(file->ofd);
622 622
 
623 623
     return ret;
624 624
 }
... ...
@@ -52,6 +52,7 @@ struct cab_file {
52 52
     char *name;
53 53
     int error;
54 54
     int fd;
55
+    int ofd;
55 56
     struct cab_folder *folder;
56 57
     struct cab_file *next;
57 58
     struct cab_archive *cab;
... ...
@@ -67,7 +68,7 @@ struct cab_folder {
67 67
 };
68 68
 
69 69
 int cab_open(int fd, off_t offset, struct cab_archive *cab);
70
-int cab_extract(int fd, struct cab_file *file, const char *name);
70
+int cab_extract(struct cab_file *file, const char *name);
71 71
 void cab_free(struct cab_archive *cab);
72 72
 
73 73
 #endif
... ...
@@ -834,8 +834,8 @@ static int cli_scanmscab(int desc, cli_ctx *ctx, off_t sfx_offset)
834 834
 	}
835 835
 
836 836
 	tempname = cli_gentemp(NULL);
837
-	cli_dbgmsg("CAB: Extracting file %s to %s\n, size %u", file->name, tempname, file->length);
838
-	if((ret = cab_extract(desc, file, tempname)))
837
+	cli_dbgmsg("CAB: Extracting file %s to %s, size %u\n", file->name, tempname, file->length);
838
+	if((ret = cab_extract(file, tempname)))
839 839
 	    cli_dbgmsg("CAB: Failed to extract file: %s\n", cl_strerror(ret));
840 840
 	else
841 841
 	    ret = cli_scanfile(tempname, ctx);