... | ... |
@@ -324,7 +324,7 @@ static int cli_scanrar(int desc, cli_ctx *ctx, off_t sfx_offset, uint32_t *sfx_c |
324 | 324 |
return ret; |
325 | 325 |
} |
326 | 326 |
|
327 |
-static int cli_scanarj(int desc, cli_ctx *ctx, off_t sfx_offset, uint32_t *sfx_check) |
|
327 |
+static int cli_scanarj(cli_ctx *ctx, off_t sfx_offset, uint32_t *sfx_check) |
|
328 | 328 |
{ |
329 | 329 |
int ret = CL_CLEAN, rc, file = 0; |
330 | 330 |
arj_metadata_t metadata; |
... | ... |
@@ -342,10 +342,7 @@ static int cli_scanarj(int desc, cli_ctx *ctx, off_t sfx_offset, uint32_t *sfx_c |
342 | 342 |
return CL_ETMPDIR; |
343 | 343 |
} |
344 | 344 |
|
345 |
- if(sfx_offset) |
|
346 |
- lseek(desc, sfx_offset, SEEK_SET); |
|
347 |
- |
|
348 |
- ret = cli_unarj_open(desc, dir); |
|
345 |
+ ret = cli_unarj_open(*ctx->fmap, dir, &metadata, sfx_offset); |
|
349 | 346 |
if (ret != CL_SUCCESS) { |
350 | 347 |
if(!ctx->engine->keeptmp) |
351 | 348 |
cli_rmdirs(dir); |
... | ... |
@@ -356,7 +353,7 @@ static int cli_scanarj(int desc, cli_ctx *ctx, off_t sfx_offset, uint32_t *sfx_c |
356 | 356 |
|
357 | 357 |
do { |
358 | 358 |
metadata.filename = NULL; |
359 |
- ret = cli_unarj_prepare_file(desc, dir, &metadata); |
|
359 |
+ ret = cli_unarj_prepare_file(dir, &metadata); |
|
360 | 360 |
if (ret != CL_SUCCESS) { |
361 | 361 |
break; |
362 | 362 |
} |
... | ... |
@@ -370,7 +367,7 @@ static int cli_scanarj(int desc, cli_ctx *ctx, off_t sfx_offset, uint32_t *sfx_c |
370 | 370 |
free(metadata.filename); |
371 | 371 |
continue; |
372 | 372 |
} |
373 |
- ret = cli_unarj_extract_file(desc, dir, &metadata); |
|
373 |
+ ret = cli_unarj_extract_file(dir, &metadata); |
|
374 | 374 |
if (metadata.ofd >= 0) { |
375 | 375 |
lseek(metadata.ofd, 0, SEEK_SET); |
376 | 376 |
rc = cli_magic_scandesc(metadata.ofd, ctx); |
... | ... |
@@ -1935,7 +1932,7 @@ static int cli_scanraw(cli_ctx *ctx, cli_file_t type, uint8_t typercg, cli_file_ |
1935 | 1935 |
ctx->container_type = CL_TYPE_ARJ; |
1936 | 1936 |
ctx->container_size = map->len - fpt->offset; /* not precise */ |
1937 | 1937 |
cli_dbgmsg("ARJ-SFX signature found at %u\n", (unsigned int) fpt->offset); |
1938 |
- nret = cli_scanarj(map->fd, ctx, fpt->offset, &lastrar); |
|
1938 |
+ nret = cli_scanarj(ctx, fpt->offset, &lastrar); |
|
1939 | 1939 |
} |
1940 | 1940 |
break; |
1941 | 1941 |
|
... | ... |
@@ -2284,7 +2281,7 @@ static int magic_scandesc(int desc, cli_ctx *ctx, cli_file_t type) |
2284 | 2284 |
ctx->container_type = CL_TYPE_ARJ; |
2285 | 2285 |
ctx->container_size = sb.st_size; |
2286 | 2286 |
if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_ARJ)) |
2287 |
- ret = cli_scanarj(desc, ctx, 0, NULL); |
|
2287 |
+ ret = cli_scanarj(ctx, 0, NULL); |
|
2288 | 2288 |
break; |
2289 | 2289 |
|
2290 | 2290 |
case CL_TYPE_NULSFT: |
... | ... |
@@ -141,7 +141,10 @@ typedef struct arj_file_hdr_tag { |
141 | 141 |
|
142 | 142 |
typedef struct arj_decode_tag { |
143 | 143 |
unsigned char *text; |
144 |
- int fd; |
|
144 |
+ fmap_t *map; |
|
145 |
+ size_t offset; |
|
146 |
+ const uint8_t *buf; |
|
147 |
+ const void *bufend; |
|
145 | 148 |
uint16_t blocksize; |
146 | 149 |
uint16_t bit_buf; |
147 | 150 |
int bit_count; |
... | ... |
@@ -164,13 +167,20 @@ static int fill_buf(arj_decode_t *decode_data, int n) |
164 | 164 |
decode_data->bit_buf |= decode_data->sub_bit_buf << (n -= decode_data->bit_count); |
165 | 165 |
if (decode_data->comp_size != 0) { |
166 | 166 |
decode_data->comp_size--; |
167 |
- if (cli_readn(decode_data->fd, &decode_data->sub_bit_buf, 1) != 1) { |
|
167 |
+ if (decode_data->buf == decode_data->bufend) { |
|
168 |
+ size_t len; |
|
169 |
+ decode_data->buf = fmap_need_off_once_len(decode_data->map, decode_data->offset, 8192, &len); |
|
170 |
+ if (!decode_data->buf || !len) { |
|
168 | 171 |
/* the file is most likely corrupted, so |
169 | 172 |
* we return CL_EFORMAT instead of CL_EREAD |
170 | 173 |
*/ |
171 | 174 |
decode_data->status = CL_EFORMAT; |
172 | 175 |
return CL_EFORMAT; |
176 |
+ } |
|
177 |
+ decode_data->bufend = decode_data->buf + len; |
|
173 | 178 |
} |
179 |
+ decode_data->sub_bit_buf = *decode_data->buf++; |
|
180 |
+ decode_data->offset++; |
|
174 | 181 |
} else { |
175 | 182 |
decode_data->sub_bit_buf = 0; |
176 | 183 |
} |
... | ... |
@@ -529,7 +539,7 @@ static uint16_t decode_p(arj_decode_t *decode_data) |
529 | 529 |
return j; |
530 | 530 |
} |
531 | 531 |
|
532 |
-static int decode(int fd, arj_metadata_t *metadata) |
|
532 |
+static int decode(arj_metadata_t *metadata) |
|
533 | 533 |
{ |
534 | 534 |
int ret; |
535 | 535 |
|
... | ... |
@@ -542,11 +552,13 @@ static int decode(int fd, arj_metadata_t *metadata) |
542 | 542 |
if (!decode_data.text) { |
543 | 543 |
return CL_EMEM; |
544 | 544 |
} |
545 |
- decode_data.fd = fd; |
|
545 |
+ decode_data.map = metadata->map; |
|
546 |
+ decode_data.offset = metadata->offset; |
|
546 | 547 |
decode_data.comp_size = metadata->comp_size; |
547 | 548 |
ret = decode_start(&decode_data); |
548 | 549 |
if (ret != CL_SUCCESS) { |
549 | 550 |
free(decode_data.text); |
551 |
+ metadata->offset = decode_data.offset; |
|
550 | 552 |
return ret; |
551 | 553 |
} |
552 | 554 |
decode_data.status = CL_SUCCESS; |
... | ... |
@@ -559,6 +571,7 @@ static int decode(int fd, arj_metadata_t *metadata) |
559 | 559 |
out_ptr = 0; |
560 | 560 |
if (write_text(metadata->ofd, decode_data.text, DDICSIZ) != CL_SUCCESS) { |
561 | 561 |
free(decode_data.text); |
562 |
+ metadata->offset = decode_data.offset; |
|
562 | 563 |
return CL_EWRITE; |
563 | 564 |
} |
564 | 565 |
} |
... | ... |
@@ -584,6 +597,7 @@ static int decode(int fd, arj_metadata_t *metadata) |
584 | 584 |
out_ptr = 0; |
585 | 585 |
if (write_text(metadata->ofd, decode_data.text, DDICSIZ) != CL_SUCCESS) { |
586 | 586 |
free(decode_data.text); |
587 |
+ metadata->offset = decode_data.offset; |
|
587 | 588 |
return CL_EWRITE; |
588 | 589 |
} |
589 | 590 |
} |
... | ... |
@@ -595,14 +609,16 @@ static int decode(int fd, arj_metadata_t *metadata) |
595 | 595 |
} |
596 | 596 |
if (decode_data.status != CL_SUCCESS) { |
597 | 597 |
free(decode_data.text); |
598 |
+ metadata->offset = decode_data.offset; |
|
598 | 599 |
return decode_data.status; |
599 | 600 |
} |
600 | 601 |
} |
601 | 602 |
if (out_ptr != 0) { |
602 | 603 |
write_text(metadata->ofd, decode_data.text, out_ptr); |
603 | 604 |
} |
604 |
- |
|
605 |
+ |
|
605 | 606 |
free(decode_data.text); |
607 |
+ metadata->offset = decode_data.offset; |
|
606 | 608 |
return CL_SUCCESS; |
607 | 609 |
} |
608 | 610 |
|
... | ... |
@@ -653,7 +669,7 @@ static uint16_t decode_len(arj_decode_t *decode_data) |
653 | 653 |
return c; |
654 | 654 |
} |
655 | 655 |
|
656 |
-static int decode_f(int fd, arj_metadata_t *metadata) |
|
656 |
+static int decode_f(arj_metadata_t *metadata) |
|
657 | 657 |
{ |
658 | 658 |
int ret; |
659 | 659 |
|
... | ... |
@@ -667,25 +683,29 @@ static int decode_f(int fd, arj_metadata_t *metadata) |
667 | 667 |
if (!decode_data.text) { |
668 | 668 |
return CL_EMEM; |
669 | 669 |
} |
670 |
- decode_data.fd = fd; |
|
670 |
+ decode_data.map = metadata->map; |
|
671 |
+ decode_data.offset = metadata->offset; |
|
671 | 672 |
decode_data.comp_size = metadata->comp_size; |
672 | 673 |
ret = init_getbits(&decode_data); |
673 | 674 |
if (ret != CL_SUCCESS) { |
675 |
+ metadata->offset = decode_data.offset; |
|
674 | 676 |
return ret; |
675 | 677 |
} |
676 |
- decode_data.getlen = decode_data.getbuf = 0; |
|
678 |
+ decode_data.getlen = decode_data.getbuf = 0; |
|
677 | 679 |
decode_data.status = CL_SUCCESS; |
678 |
- |
|
680 |
+ |
|
679 | 681 |
while (count < metadata->orig_size) { |
680 | 682 |
chr = decode_len(&decode_data); |
681 | 683 |
if (decode_data.status != CL_SUCCESS) { |
682 | 684 |
free(decode_data.text); |
685 |
+ metadata->offset = decode_data.offset; |
|
683 | 686 |
return decode_data.status; |
684 |
- } |
|
687 |
+ } |
|
685 | 688 |
if (chr == 0) { |
686 | 689 |
ARJ_GETBITS(dd, chr, CHAR_BIT); |
687 | 690 |
if (decode_data.status != CL_SUCCESS) { |
688 | 691 |
free(decode_data.text); |
692 |
+ metadata->offset = decode_data.offset; |
|
689 | 693 |
return decode_data.status; |
690 | 694 |
} |
691 | 695 |
decode_data.text[out_ptr] = (unsigned char) chr; |
... | ... |
@@ -694,6 +714,7 @@ static int decode_f(int fd, arj_metadata_t *metadata) |
694 | 694 |
out_ptr = 0; |
695 | 695 |
if (write_text(metadata->ofd, decode_data.text, DDICSIZ) != CL_SUCCESS) { |
696 | 696 |
free(decode_data.text); |
697 |
+ metadata->offset = decode_data.offset; |
|
697 | 698 |
return CL_EWRITE; |
698 | 699 |
} |
699 | 700 |
} |
... | ... |
@@ -703,6 +724,7 @@ static int decode_f(int fd, arj_metadata_t *metadata) |
703 | 703 |
pos = decode_ptr(&decode_data); |
704 | 704 |
if (decode_data.status != CL_SUCCESS) { |
705 | 705 |
free(decode_data.text); |
706 |
+ metadata->offset = decode_data.offset; |
|
706 | 707 |
return decode_data.status; |
707 | 708 |
} |
708 | 709 |
if ((i = out_ptr - pos - 1) < 0) { |
... | ... |
@@ -718,6 +740,7 @@ static int decode_f(int fd, arj_metadata_t *metadata) |
718 | 718 |
out_ptr = 0; |
719 | 719 |
if (write_text(metadata->ofd, decode_data.text, DDICSIZ) != CL_SUCCESS) { |
720 | 720 |
free(decode_data.text); |
721 |
+ metadata->offset = decode_data.offset; |
|
721 | 722 |
return CL_EWRITE; |
722 | 723 |
} |
723 | 724 |
} |
... | ... |
@@ -730,26 +753,28 @@ static int decode_f(int fd, arj_metadata_t *metadata) |
730 | 730 |
if (out_ptr != 0) { |
731 | 731 |
write_text(metadata->ofd, decode_data.text, out_ptr); |
732 | 732 |
} |
733 |
- |
|
733 |
+ |
|
734 | 734 |
free(decode_data.text); |
735 |
+ metadata->offset = decode_data.offset; |
|
735 | 736 |
return CL_SUCCESS; |
736 |
-} |
|
737 |
+} |
|
737 | 738 |
|
738 |
-static uint32_t arj_unstore(int ifd, int ofd, uint32_t len) |
|
739 |
+static uint32_t arj_unstore(arj_metadata_t *metadata, int ofd, uint32_t len) |
|
739 | 740 |
{ |
740 |
- unsigned char data[8192]; |
|
741 |
- uint32_t count, rem; |
|
741 |
+ const unsigned char *data; |
|
742 |
+ uint32_t rem; |
|
742 | 743 |
unsigned int todo; |
744 |
+ size_t count; |
|
743 | 745 |
|
744 | 746 |
cli_dbgmsg("in arj_unstore\n"); |
745 | 747 |
rem = len; |
746 | 748 |
|
747 | 749 |
while (rem > 0) { |
748 | 750 |
todo = (unsigned int) MIN(8192, rem); |
749 |
- count = cli_readn(ifd, data, todo); |
|
750 |
- if (count != todo) { |
|
751 |
- return len-rem; |
|
752 |
- } |
|
751 |
+ data = fmap_need_off_once_len(metadata->map, metadata->offset, todo, &count); |
|
752 |
+ if (!data) |
|
753 |
+ return len - rem; |
|
754 |
+ metadata->offset += count; |
|
753 | 755 |
if (cli_writen(ofd, data, count) != count) { |
754 | 756 |
return len-rem-count; |
755 | 757 |
} |
... | ... |
@@ -758,14 +783,15 @@ static uint32_t arj_unstore(int ifd, int ofd, uint32_t len) |
758 | 758 |
return len; |
759 | 759 |
} |
760 | 760 |
|
761 |
-static int is_arj_archive(int fd) |
|
761 |
+static int is_arj_archive(arj_metadata_t *metadata) |
|
762 | 762 |
{ |
763 | 763 |
const char header_id[2] = {0x60, 0xea}; |
764 |
- char mark[2]; |
|
765 |
- |
|
766 |
- if (cli_readn(fd, &mark[0], 2) != 2) { |
|
767 |
- return FALSE; |
|
768 |
- } |
|
764 |
+ const char *mark; |
|
765 |
+ |
|
766 |
+ mark = fmap_need_off_once(metadata->map, metadata->offset, 2); |
|
767 |
+ if (!mark) |
|
768 |
+ return FALSE; |
|
769 |
+ metadata->offset += 2; |
|
769 | 770 |
if (memcmp(&mark[0], &header_id[0], 2) == 0) { |
770 | 771 |
return TRUE; |
771 | 772 |
} |
... | ... |
@@ -773,18 +799,19 @@ static int is_arj_archive(int fd) |
773 | 773 |
return FALSE; |
774 | 774 |
} |
775 | 775 |
|
776 |
-static int arj_read_main_header(int fd) |
|
776 |
+static int arj_read_main_header(arj_metadata_t *metadata) |
|
777 | 777 |
{ |
778 | 778 |
uint16_t header_size, count; |
779 | 779 |
uint32_t crc; |
780 | 780 |
arj_main_hdr_t main_hdr; |
781 |
- char *filename, *comment; |
|
781 |
+ const char *filename, *comment; |
|
782 | 782 |
off_t header_offset; |
783 | 783 |
|
784 |
- if (cli_readn(fd, &header_size, 2) != 2) { |
|
785 |
- return FALSE; |
|
786 |
- } |
|
787 |
- header_offset = lseek(fd, 0, SEEK_CUR); |
|
784 |
+ if (fmap_readn(metadata->map, &header_size, metadata->offset, 2) != 2) |
|
785 |
+ return FALSE; |
|
786 |
+ |
|
787 |
+ metadata->offset += 2; |
|
788 |
+ header_offset = metadata->offset; |
|
788 | 789 |
header_size = le16_to_host(header_size); |
789 | 790 |
cli_dbgmsg("Header Size: %d\n", header_size); |
790 | 791 |
if (header_size == 0) { |
... | ... |
@@ -795,11 +822,10 @@ static int arj_read_main_header(int fd) |
795 | 795 |
cli_dbgmsg("arj_read_header: invalid header_size: %u\n ", header_size); |
796 | 796 |
return FALSE; |
797 | 797 |
} |
798 |
- |
|
799 |
- if (cli_readn(fd, &main_hdr, 30) != 30) { |
|
800 |
- return FALSE; |
|
801 |
- } |
|
802 |
- |
|
798 |
+ if (fmap_readn(metadata->map, &main_hdr, metadata->offset, 30) != 30) |
|
799 |
+ return FALSE; |
|
800 |
+ metadata->offset += 30; |
|
801 |
+ |
|
803 | 802 |
cli_dbgmsg("ARJ Main File Header\n"); |
804 | 803 |
cli_dbgmsg("First Header Size: %d\n", main_hdr.first_hdr_size); |
805 | 804 |
cli_dbgmsg("Version: %d\n", main_hdr.version); |
... | ... |
@@ -814,86 +840,50 @@ static int arj_read_main_header(int fd) |
814 | 814 |
return FALSE; |
815 | 815 |
} |
816 | 816 |
if (main_hdr.first_hdr_size > 30) { |
817 |
- if (lseek(fd, main_hdr.first_hdr_size - 30, SEEK_CUR) == -1) { |
|
818 |
- return FALSE; |
|
819 |
- } |
|
817 |
+ metadata->offset += main_hdr.first_hdr_size - 30; |
|
820 | 818 |
} |
821 | 819 |
|
822 |
- filename = (char *) cli_malloc(header_size); |
|
823 |
- if (!filename) { |
|
824 |
- return FALSE; |
|
825 |
- } |
|
826 |
- for (count=0 ; count < header_size ; count++) { |
|
827 |
- if (cli_readn(fd, &filename[count], 1) != 1) { |
|
828 |
- free(filename); |
|
829 |
- return FALSE; |
|
830 |
- } |
|
831 |
- if (filename[count] == '\0') { |
|
832 |
- break; |
|
833 |
- } |
|
834 |
- } |
|
835 |
- if (count == header_size) { |
|
836 |
- free(filename); |
|
837 |
- return FALSE; |
|
838 |
- } |
|
839 |
- comment = (char *) cli_malloc(header_size); |
|
840 |
- if (!comment) { |
|
841 |
- free(filename); |
|
820 |
+ filename = fmap_need_offstr(metadata->map, metadata->offset, header_size); |
|
821 |
+ if (!filename) |
|
842 | 822 |
return FALSE; |
843 |
- } |
|
844 |
- for (count=0 ; count < header_size ; count++) { |
|
845 |
- if (cli_readn(fd, &comment[count], 1) != 1) { |
|
846 |
- free(filename); |
|
847 |
- free(comment); |
|
848 |
- return FALSE; |
|
849 |
- } |
|
850 |
- if (comment[count] == '\0') { |
|
851 |
- break; |
|
852 |
- } |
|
853 |
- } |
|
854 |
- if (count == header_size) { |
|
855 |
- free(filename); |
|
856 |
- free(comment); |
|
823 |
+ metadata->offset += strlen(filename) + 1; |
|
824 |
+ |
|
825 |
+ comment = fmap_need_offstr(metadata->map, metadata->offset, header_size); |
|
826 |
+ if (!comment) |
|
857 | 827 |
return FALSE; |
858 |
- } |
|
828 |
+ metadata->offset += strlen(comment) + 1; |
|
859 | 829 |
cli_dbgmsg("Filename: %s\n", filename); |
860 | 830 |
cli_dbgmsg("Comment: %s\n", comment); |
861 |
- |
|
862 |
- free(filename); |
|
863 |
- free(comment); |
|
864 |
- |
|
865 |
- if (cli_readn(fd, &crc, 4) != 4) { |
|
866 |
- return FALSE; |
|
867 |
- } |
|
868 |
- |
|
831 |
+ |
|
832 |
+ metadata->offset += 4; /* crc */ |
|
869 | 833 |
/* Skip past any extended header data */ |
870 | 834 |
for (;;) { |
871 |
- if (cli_readn(fd, &count, 2) != 2) { |
|
835 |
+ const uint16_t *countp = fmap_need_off_once(metadata->map, metadata->offset, 2); |
|
836 |
+ if (!countp) |
|
872 | 837 |
return FALSE; |
873 |
- } |
|
874 |
- count = le16_to_host(count); |
|
838 |
+ count = cli_readint16(countp); |
|
839 |
+ metadata->offset += 2; |
|
875 | 840 |
cli_dbgmsg("Extended header size: %d\n", count); |
876 | 841 |
if (count == 0) { |
877 | 842 |
break; |
878 | 843 |
} |
879 | 844 |
/* Skip extended header + 4byte CRC */ |
880 |
- if (lseek(fd, (off_t) (count + 4), SEEK_CUR) == -1) { |
|
881 |
- return FALSE; |
|
882 |
- } |
|
845 |
+ metadata->offset += count + 4; |
|
883 | 846 |
} |
884 | 847 |
return TRUE; |
885 | 848 |
} |
886 | 849 |
|
887 |
-static int arj_read_file_header(int fd, arj_metadata_t *metadata) |
|
850 |
+static int arj_read_file_header(arj_metadata_t *metadata) |
|
888 | 851 |
{ |
889 | 852 |
uint16_t header_size, count; |
890 |
- char *filename, *comment; |
|
853 |
+ const char *filename, *comment; |
|
891 | 854 |
arj_file_hdr_t file_hdr; |
892 |
- |
|
893 |
- if (cli_readn(fd, &header_size, 2) != 2) { |
|
894 |
- return CL_EFORMAT; |
|
895 |
- } |
|
855 |
+ |
|
856 |
+ if (fmap_readn(metadata->map, &header_size, metadata->offset, 2) != 2) |
|
857 |
+ return CL_EFORMAT; |
|
896 | 858 |
header_size = le16_to_host(header_size); |
859 |
+ metadata->offset += 2; |
|
860 |
+ |
|
897 | 861 |
cli_dbgmsg("Header Size: %d\n", header_size); |
898 | 862 |
if (header_size == 0) { |
899 | 863 |
/* End of archive */ |
... | ... |
@@ -903,13 +893,14 @@ static int arj_read_file_header(int fd, arj_metadata_t *metadata) |
903 | 903 |
cli_dbgmsg("arj_read_file_header: invalid header_size: %u\n ", header_size); |
904 | 904 |
return CL_EFORMAT; |
905 | 905 |
} |
906 |
- |
|
907 |
- if (cli_readn(fd, &file_hdr, 30) != 30) { |
|
906 |
+ |
|
907 |
+ if (fmap_readn(metadata->map, &file_hdr, metadata->offset, 30) != 30) { |
|
908 | 908 |
return CL_EFORMAT; |
909 | 909 |
} |
910 |
+ metadata->offset += 30; |
|
910 | 911 |
file_hdr.comp_size = le32_to_host(file_hdr.comp_size); |
911 | 912 |
file_hdr.orig_size = le32_to_host(file_hdr.orig_size); |
912 |
- |
|
913 |
+ |
|
913 | 914 |
cli_dbgmsg("ARJ File Header\n"); |
914 | 915 |
cli_dbgmsg("First Header Size: %d\n", file_hdr.first_hdr_size); |
915 | 916 |
cli_dbgmsg("Version: %d\n", file_hdr.version); |
... | ... |
@@ -929,84 +920,42 @@ static int arj_read_file_header(int fd, arj_metadata_t *metadata) |
929 | 929 |
|
930 | 930 |
/* Note: this skips past any extended file start position data (multi-volume) */ |
931 | 931 |
if (file_hdr.first_hdr_size > 30) { |
932 |
- if (lseek(fd, file_hdr.first_hdr_size - 30, SEEK_CUR) == -1) { |
|
933 |
- return CL_EFORMAT; |
|
934 |
- } |
|
932 |
+ metadata->offset += file_hdr.first_hdr_size - 30; |
|
935 | 933 |
} |
936 | 934 |
|
937 |
- filename = (char *) cli_malloc(header_size); |
|
938 |
- if (!filename) { |
|
939 |
- return CL_EMEM; |
|
940 |
- } |
|
941 |
- for (count=0 ; count < header_size ; count++) { |
|
942 |
- if (cli_readn(fd, &filename[count], 1) != 1) { |
|
943 |
- free(filename); |
|
944 |
- return CL_EFORMAT; |
|
945 |
- } |
|
946 |
- if (filename[count] == '\0') { |
|
947 |
- break; |
|
948 |
- } |
|
949 |
- } |
|
950 |
- if (count == header_size) { |
|
951 |
- free(filename); |
|
952 |
- return CL_EFORMAT; |
|
953 |
- } |
|
935 |
+ filename = fmap_need_offstr(metadata->map, metadata->offset, header_size); |
|
936 |
+ if (!filename) |
|
937 |
+ return FALSE; |
|
938 |
+ metadata->offset += strlen(filename) + 1; |
|
954 | 939 |
|
955 |
- comment = (char *) cli_malloc(header_size); |
|
956 |
- if (!comment) { |
|
957 |
- free(filename); |
|
958 |
- return CL_EFORMAT; |
|
959 |
- } |
|
960 |
- for (count=0 ; count < header_size ; count++) { |
|
961 |
- if (cli_readn(fd, &comment[count], 1) != 1) { |
|
962 |
- free(filename); |
|
963 |
- free(comment); |
|
964 |
- return CL_EFORMAT; |
|
965 |
- } |
|
966 |
- if (comment[count] == '\0') { |
|
967 |
- break; |
|
968 |
- } |
|
969 |
- } |
|
970 |
- if (count == header_size) { |
|
971 |
- free(filename); |
|
972 |
- free(comment); |
|
973 |
- return CL_EFORMAT; |
|
974 |
- } |
|
940 |
+ comment = fmap_need_offstr(metadata->map, metadata->offset, header_size); |
|
941 |
+ if (!comment) |
|
942 |
+ return FALSE; |
|
943 |
+ metadata->offset += strlen(comment) + 1; |
|
975 | 944 |
cli_dbgmsg("Filename: %s\n", filename); |
976 | 945 |
cli_dbgmsg("Comment: %s\n", comment); |
977 | 946 |
metadata->filename = cli_strdup(filename); |
978 | 947 |
|
979 |
- free(filename); |
|
980 |
- free(comment); |
|
981 |
- |
|
982 | 948 |
/* Skip CRC */ |
983 |
- if (lseek(fd, (off_t) 4, SEEK_CUR) == -1) { |
|
984 |
- if(metadata->filename) |
|
985 |
- free(metadata->filename); |
|
986 |
- metadata->filename = NULL; |
|
987 |
- return CL_EFORMAT; |
|
988 |
- } |
|
989 |
- |
|
949 |
+ metadata->offset += 4; |
|
950 |
+ |
|
990 | 951 |
/* Skip past any extended header data */ |
991 | 952 |
for (;;) { |
992 |
- if (cli_readn(fd, &count, 2) != 2) { |
|
953 |
+ const uint16_t *countp = fmap_need_off_once(metadata->map, metadata->offset, 2); |
|
954 |
+ if (!countp) { |
|
993 | 955 |
if(metadata->filename) |
994 | 956 |
free(metadata->filename); |
995 | 957 |
metadata->filename = NULL; |
996 | 958 |
return CL_EFORMAT; |
997 | 959 |
} |
998 |
- count = le16_to_host(count); |
|
960 |
+ count = cli_readint16(countp); |
|
961 |
+ metadata->offset += 2; |
|
999 | 962 |
cli_dbgmsg("Extended header size: %d\n", count); |
1000 | 963 |
if (count == 0) { |
1001 | 964 |
break; |
1002 | 965 |
} |
1003 | 966 |
/* Skip extended header + 4byte CRC */ |
1004 |
- if (lseek(fd, (off_t) (count + 4), SEEK_CUR) == -1) { |
|
1005 |
- if(metadata->filename) |
|
1006 |
- free(metadata->filename); |
|
1007 |
- metadata->filename = NULL; |
|
1008 |
- return CL_EFORMAT; |
|
1009 |
- } |
|
967 |
+ metadata->offset += count + 4; |
|
1010 | 968 |
} |
1011 | 969 |
metadata->comp_size = file_hdr.comp_size; |
1012 | 970 |
metadata->orig_size = file_hdr.orig_size; |
... | ... |
@@ -1016,61 +965,58 @@ static int arj_read_file_header(int fd, arj_metadata_t *metadata) |
1016 | 1016 |
if (!metadata->filename) { |
1017 | 1017 |
return CL_EMEM; |
1018 | 1018 |
} |
1019 |
- |
|
1020 |
- return CL_SUCCESS; |
|
1019 |
+ |
|
1020 |
+ return CL_SUCCESS; |
|
1021 | 1021 |
} |
1022 | 1022 |
|
1023 |
-int cli_unarj_open(int fd, const char *dirname) |
|
1023 |
+int cli_unarj_open(fmap_t *map, const char *dirname, arj_metadata_t *metadata, size_t off) |
|
1024 | 1024 |
{ |
1025 |
- |
|
1026 | 1025 |
cli_dbgmsg("in cli_unarj_open\n"); |
1027 |
- |
|
1028 |
- if (!is_arj_archive(fd)) { |
|
1026 |
+ metadata->map = map; |
|
1027 |
+ metadata->offset = off; |
|
1028 |
+ if (!is_arj_archive(metadata)) { |
|
1029 | 1029 |
cli_dbgmsg("Not in ARJ format\n"); |
1030 | 1030 |
return CL_EFORMAT; |
1031 | 1031 |
} |
1032 |
- if (!arj_read_main_header(fd)) { |
|
1032 |
+ if (!arj_read_main_header(metadata)) { |
|
1033 | 1033 |
cli_dbgmsg("Failed to read main header\n"); |
1034 | 1034 |
return CL_EFORMAT; |
1035 | 1035 |
} |
1036 | 1036 |
return CL_SUCCESS; |
1037 | 1037 |
} |
1038 | 1038 |
|
1039 |
-int cli_unarj_prepare_file(int fd, const char *dirname, arj_metadata_t *metadata) |
|
1039 |
+int cli_unarj_prepare_file(const char *dirname, arj_metadata_t *metadata) |
|
1040 | 1040 |
{ |
1041 | 1041 |
cli_dbgmsg("in cli_unarj_prepare_file\n"); |
1042 |
- if (!metadata || !dirname || (fd < 0)) { |
|
1042 |
+ if (!metadata || !dirname) { |
|
1043 | 1043 |
return CL_ENULLARG; |
1044 | 1044 |
} |
1045 | 1045 |
/* Each file is preceeded by the ARJ file marker */ |
1046 |
- if (!is_arj_archive(fd)) { |
|
1046 |
+ if (!is_arj_archive(metadata)) { |
|
1047 | 1047 |
cli_dbgmsg("Not in ARJ format\n"); |
1048 | 1048 |
return CL_EFORMAT; |
1049 | 1049 |
} |
1050 |
- return arj_read_file_header(fd, metadata); |
|
1050 |
+ return arj_read_file_header(metadata); |
|
1051 | 1051 |
} |
1052 | 1052 |
|
1053 |
-int cli_unarj_extract_file(int fd, const char *dirname, arj_metadata_t *metadata) |
|
1053 |
+int cli_unarj_extract_file(const char *dirname, arj_metadata_t *metadata) |
|
1054 | 1054 |
{ |
1055 | 1055 |
off_t offset; |
1056 | 1056 |
int ret = CL_SUCCESS; |
1057 | 1057 |
char filename[1024]; |
1058 |
- |
|
1058 |
+ |
|
1059 | 1059 |
cli_dbgmsg("in cli_unarj_extract_file\n"); |
1060 |
- if (!metadata || !dirname || (fd < 0)) { |
|
1060 |
+ if (!metadata || !dirname) { |
|
1061 | 1061 |
return CL_ENULLARG; |
1062 | 1062 |
} |
1063 | 1063 |
|
1064 | 1064 |
if (metadata->encrypted) { |
1065 | 1065 |
cli_dbgmsg("PASSWORDed file (skipping)\n"); |
1066 |
- offset = lseek(fd, 0, SEEK_CUR) + metadata->comp_size; |
|
1067 |
- cli_dbgmsg("Target offset: %lu\n", (unsigned long int) offset); |
|
1068 |
- if (lseek(fd, offset, SEEK_SET) != offset) { |
|
1069 |
- return CL_ESEEK; |
|
1070 |
- } |
|
1066 |
+ metadata->offset += metadata->comp_size; |
|
1067 |
+ cli_dbgmsg("Target offset: %lu\n", (unsigned long int) metadata->offset); |
|
1071 | 1068 |
return CL_SUCCESS; |
1072 | 1069 |
} |
1073 |
- |
|
1070 |
+ |
|
1074 | 1071 |
snprintf(filename, 1024, "%s"PATHSEP"file.uar", dirname); |
1075 | 1072 |
cli_dbgmsg("Filename: %s\n", filename); |
1076 | 1073 |
metadata->ofd = open(filename, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, 0600); |
... | ... |
@@ -1079,7 +1025,7 @@ int cli_unarj_extract_file(int fd, const char *dirname, arj_metadata_t *metadata |
1079 | 1079 |
} |
1080 | 1080 |
switch (metadata->method) { |
1081 | 1081 |
case 0: |
1082 |
- ret = arj_unstore(fd, metadata->ofd, metadata->comp_size); |
|
1082 |
+ ret = arj_unstore(metadata, metadata->ofd, metadata->comp_size); |
|
1083 | 1083 |
if (ret != metadata->comp_size) { |
1084 | 1084 |
ret = CL_EWRITE; |
1085 | 1085 |
} else { |
... | ... |
@@ -1089,10 +1035,10 @@ int cli_unarj_extract_file(int fd, const char *dirname, arj_metadata_t *metadata |
1089 | 1089 |
case 1: |
1090 | 1090 |
case 2: |
1091 | 1091 |
case 3: |
1092 |
- ret = decode(fd, metadata); |
|
1092 |
+ ret = decode(metadata); |
|
1093 | 1093 |
break; |
1094 | 1094 |
case 4: |
1095 |
- ret = decode_f(fd, metadata); |
|
1095 |
+ ret = decode_f(metadata); |
|
1096 | 1096 |
break; |
1097 | 1097 |
default: |
1098 | 1098 |
ret = CL_EFORMAT; |
... | ... |
@@ -23,6 +23,7 @@ |
23 | 23 |
#ifndef __UNARJ_H |
24 | 24 |
#define __UNARJ_H |
25 | 25 |
|
26 |
+#include "fmap.h" |
|
26 | 27 |
typedef struct arj_metadata_tag { |
27 | 28 |
char *filename; |
28 | 29 |
uint32_t comp_size; |
... | ... |
@@ -30,10 +31,12 @@ typedef struct arj_metadata_tag { |
30 | 30 |
int encrypted; |
31 | 31 |
int ofd; |
32 | 32 |
uint8_t method; |
33 |
+ fmap_t *map; |
|
34 |
+ size_t offset; |
|
33 | 35 |
} arj_metadata_t; |
34 | 36 |
|
35 |
-int cli_unarj_open(int fd, const char *dirname); |
|
36 |
-int cli_unarj_prepare_file(int fd, const char *dirname, arj_metadata_t *metadata); |
|
37 |
-int cli_unarj_extract_file(int fd, const char *dirname, arj_metadata_t *metadata); |
|
37 |
+int cli_unarj_open(fmap_t *map, const char *dirname, arj_metadata_t *metadata, size_t off); |
|
38 |
+int cli_unarj_prepare_file(const char *dirname, arj_metadata_t *metadata); |
|
39 |
+int cli_unarj_extract_file(const char *dirname, arj_metadata_t *metadata); |
|
38 | 40 |
|
39 | 41 |
#endif |