git-svn: trunk@2563
Tomasz Kojm authored on 2006/12/20 05:14:26... | ... |
@@ -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); |