160
163
static int fill_buf(arj_decode_t *decode_data, int n)
165
if (decode_data->status == CL_EFORMAT)
162
167
decode_data->bit_buf = (decode_data->bit_buf << n) & 0xFFFF;
163
168
while (n > decode_data->bit_count) {
164
169
decode_data->bit_buf |= decode_data->sub_bit_buf << (n -= decode_data->bit_count);
165
170
if (decode_data->comp_size != 0) {
166
171
decode_data->comp_size--;
167
if (cli_readn(decode_data->fd, &decode_data->sub_bit_buf, 1) != 1) {
172
if (decode_data->buf == decode_data->bufend) {
174
decode_data->buf = fmap_need_off_once_len(decode_data->map, decode_data->offset, 8192, &len);
175
if (!decode_data->buf || !len) {
168
176
/* the file is most likely corrupted, so
169
177
* we return CL_EFORMAT instead of CL_EREAD
171
179
decode_data->status = CL_EFORMAT;
172
180
return CL_EFORMAT;
182
decode_data->bufend = decode_data->buf + len;
184
decode_data->sub_bit_buf = *decode_data->buf++;
185
decode_data->offset++;
175
187
decode_data->sub_bit_buf = 0;
667
685
if (!decode_data.text) {
688
decode_data.map = metadata->map;
689
decode_data.offset = metadata->offset;
671
690
decode_data.comp_size = metadata->comp_size;
672
691
ret = init_getbits(&decode_data);
673
692
if (ret != CL_SUCCESS) {
693
metadata->offset = decode_data.offset;
676
decode_data.getlen = decode_data.getbuf = 0;
696
decode_data.getlen = decode_data.getbuf = 0;
677
697
decode_data.status = CL_SUCCESS;
679
699
while (count < metadata->orig_size) {
680
700
chr = decode_len(&decode_data);
681
701
if (decode_data.status != CL_SUCCESS) {
682
702
free(decode_data.text);
703
metadata->offset = decode_data.offset;
683
704
return decode_data.status;
686
707
ARJ_GETBITS(dd, chr, CHAR_BIT);
687
708
if (decode_data.status != CL_SUCCESS) {
688
709
free(decode_data.text);
710
metadata->offset = decode_data.offset;
689
711
return decode_data.status;
691
713
decode_data.text[out_ptr] = (unsigned char) chr;
730
755
if (out_ptr != 0) {
731
756
write_text(metadata->ofd, decode_data.text, out_ptr);
734
759
free(decode_data.text);
760
metadata->offset = decode_data.offset;
735
761
return CL_SUCCESS;
738
static uint32_t arj_unstore(int ifd, int ofd, uint32_t len)
764
static int arj_unstore(arj_metadata_t *metadata, int ofd, uint32_t len)
740
unsigned char data[8192];
766
const unsigned char *data;
742
768
unsigned int todo;
744
771
cli_dbgmsg("in arj_unstore\n");
747
774
while (rem > 0) {
748
775
todo = (unsigned int) MIN(8192, rem);
749
count = cli_readn(ifd, data, todo);
776
data = fmap_need_off_once_len(metadata->map, metadata->offset, todo, &count);
777
if (!data || !count) {
778
/* Truncated file, not enough bytes available */
781
metadata->offset += count;
753
782
if (cli_writen(ofd, data, count) != count) {
754
return len-rem-count;
783
/* File writing problem */
761
static int is_arj_archive(int fd)
791
static int is_arj_archive(arj_metadata_t *metadata)
763
793
const char header_id[2] = {0x60, 0xea};
766
if (cli_readn(fd, &mark[0], 2) != 2) {
796
mark = fmap_need_off_once(metadata->map, metadata->offset, 2);
799
metadata->offset += 2;
769
800
if (memcmp(&mark[0], &header_id[0], 2) == 0) {
776
static int arj_read_main_header(int fd)
807
static int arj_read_main_header(arj_metadata_t *metadata)
778
809
uint16_t header_size, count;
780
811
arj_main_hdr_t main_hdr;
781
char *filename, *comment;
812
const char *filename, *comment;
782
813
off_t header_offset;
784
if (cli_readn(fd, &header_size, 2) != 2) {
787
header_offset = lseek(fd, 0, SEEK_CUR);
815
if (fmap_readn(metadata->map, &header_size, metadata->offset, 2) != 2)
818
metadata->offset += 2;
819
header_offset = metadata->offset;
788
820
header_size = le16_to_host(header_size);
789
821
cli_dbgmsg("Header Size: %d\n", header_size);
790
822
if (header_size == 0) {
795
827
cli_dbgmsg("arj_read_header: invalid header_size: %u\n ", header_size);
799
if (cli_readn(fd, &main_hdr, 30) != 30) {
830
if (fmap_readn(metadata->map, &main_hdr, metadata->offset, 30) != 30)
832
metadata->offset += 30;
803
834
cli_dbgmsg("ARJ Main File Header\n");
804
835
cli_dbgmsg("First Header Size: %d\n", main_hdr.first_hdr_size);
805
836
cli_dbgmsg("Version: %d\n", main_hdr.version);
816
847
if (main_hdr.first_hdr_size > 30) {
817
if (lseek(fd, main_hdr.first_hdr_size - 30, SEEK_CUR) == -1) {
848
metadata->offset += main_hdr.first_hdr_size - 30;
822
filename = (char *) cli_malloc(header_size);
851
filename = fmap_need_offstr(metadata->map, metadata->offset, header_size);
826
for (count=0 ; count < header_size ; count++) {
827
if (cli_readn(fd, &filename[count], 1) != 1) {
831
if (filename[count] == '\0') {
835
if (count == header_size) {
839
comment = (char *) cli_malloc(header_size);
853
cli_dbgmsg("UNARJ: Unable to allocate memory for filename\n");
856
metadata->offset += strlen(filename) + 1;
858
comment = fmap_need_offstr(metadata->map, metadata->offset, header_size);
844
for (count=0 ; count < header_size ; count++) {
845
if (cli_readn(fd, &comment[count], 1) != 1) {
850
if (comment[count] == '\0') {
854
if (count == header_size) {
860
cli_dbgmsg("UNARJ: Unable to allocate memory for comment\n");
863
metadata->offset += strlen(comment) + 1;
859
864
cli_dbgmsg("Filename: %s\n", filename);
860
865
cli_dbgmsg("Comment: %s\n", comment);
865
if (cli_readn(fd, &crc, 4) != 4) {
867
metadata->offset += 4; /* crc */
869
868
/* Skip past any extended header data */
871
if (cli_readn(fd, &count, 2) != 2) {
870
const uint16_t *countp = fmap_need_off_once(metadata->map, metadata->offset, 2);
874
count = le16_to_host(count);
873
count = cli_readint16(countp);
874
metadata->offset += 2;
875
875
cli_dbgmsg("Extended header size: %d\n", count);
876
876
if (count == 0) {
879
879
/* Skip extended header + 4byte CRC */
880
if (lseek(fd, (off_t) (count + 4), SEEK_CUR) == -1) {
880
metadata->offset += count + 4;
887
static int arj_read_file_header(int fd, arj_metadata_t *metadata)
885
static int arj_read_file_header(arj_metadata_t *metadata)
889
887
uint16_t header_size, count;
890
char *filename, *comment;
888
const char *filename, *comment;
891
889
arj_file_hdr_t file_hdr;
893
if (cli_readn(fd, &header_size, 2) != 2) {
891
if (fmap_readn(metadata->map, &header_size, metadata->offset, 2) != 2)
896
893
header_size = le16_to_host(header_size);
894
metadata->offset += 2;
897
896
cli_dbgmsg("Header Size: %d\n", header_size);
898
897
if (header_size == 0) {
899
898
/* End of archive */
903
902
cli_dbgmsg("arj_read_file_header: invalid header_size: %u\n ", header_size);
904
903
return CL_EFORMAT;
907
if (cli_readn(fd, &file_hdr, 30) != 30) {
906
if (fmap_readn(metadata->map, &file_hdr, metadata->offset, 30) != 30) {
908
907
return CL_EFORMAT;
909
metadata->offset += 30;
910
910
file_hdr.comp_size = le32_to_host(file_hdr.comp_size);
911
911
file_hdr.orig_size = le32_to_host(file_hdr.orig_size);
913
913
cli_dbgmsg("ARJ File Header\n");
914
914
cli_dbgmsg("First Header Size: %d\n", file_hdr.first_hdr_size);
915
915
cli_dbgmsg("Version: %d\n", file_hdr.version);
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) {
932
metadata->offset += file_hdr.first_hdr_size - 30;
937
filename = (char *) cli_malloc(header_size);
935
filename = fmap_need_offstr(metadata->map, metadata->offset, header_size);
941
for (count=0 ; count < header_size ; count++) {
942
if (cli_readn(fd, &filename[count], 1) != 1) {
946
if (filename[count] == '\0') {
950
if (count == header_size) {
937
cli_dbgmsg("UNARJ: Unable to allocate memory for filename\n");
940
metadata->offset += strlen(filename) + 1;
955
comment = (char *) cli_malloc(header_size);
942
comment = fmap_need_offstr(metadata->map, metadata->offset, header_size);
960
for (count=0 ; count < header_size ; count++) {
961
if (cli_readn(fd, &comment[count], 1) != 1) {
966
if (comment[count] == '\0') {
970
if (count == header_size) {
944
cli_dbgmsg("UNARJ: Unable to allocate memory for comment\n");
947
metadata->offset += strlen(comment) + 1;
975
948
cli_dbgmsg("Filename: %s\n", filename);
976
949
cli_dbgmsg("Comment: %s\n", comment);
977
950
metadata->filename = cli_strdup(filename);
983
if (lseek(fd, (off_t) 4, SEEK_CUR) == -1) {
984
if(metadata->filename)
985
free(metadata->filename);
986
metadata->filename = NULL;
953
metadata->offset += 4;
990
955
/* Skip past any extended header data */
992
if (cli_readn(fd, &count, 2) != 2) {
957
const uint16_t *countp = fmap_need_off_once(metadata->map, metadata->offset, 2);
993
959
if(metadata->filename)
994
960
free(metadata->filename);
995
961
metadata->filename = NULL;
996
962
return CL_EFORMAT;
998
count = le16_to_host(count);
964
count = cli_readint16(countp);
965
metadata->offset += 2;
999
966
cli_dbgmsg("Extended header size: %d\n", count);
1000
967
if (count == 0) {
1003
970
/* 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;
971
metadata->offset += count + 4;
1011
973
metadata->comp_size = file_hdr.comp_size;
1012
974
metadata->orig_size = file_hdr.orig_size;
1016
978
if (!metadata->filename) {
1023
int cli_unarj_open(int fd, const char *dirname)
985
int cli_unarj_open(fmap_t *map, const char *dirname, arj_metadata_t *metadata, size_t off)
1026
987
cli_dbgmsg("in cli_unarj_open\n");
1028
if (!is_arj_archive(fd)) {
989
metadata->offset = off;
990
if (!is_arj_archive(metadata)) {
1029
991
cli_dbgmsg("Not in ARJ format\n");
1030
992
return CL_EFORMAT;
1032
if (!arj_read_main_header(fd)) {
994
if (!arj_read_main_header(metadata)) {
1033
995
cli_dbgmsg("Failed to read main header\n");
1034
996
return CL_EFORMAT;
1036
998
return CL_SUCCESS;
1039
int cli_unarj_prepare_file(int fd, const char *dirname, arj_metadata_t *metadata)
1001
int cli_unarj_prepare_file(const char *dirname, arj_metadata_t *metadata)
1041
1003
cli_dbgmsg("in cli_unarj_prepare_file\n");
1042
if (!metadata || !dirname || (fd < 0)) {
1004
if (!metadata || !dirname) {
1043
1005
return CL_ENULLARG;
1045
1007
/* Each file is preceeded by the ARJ file marker */
1046
if (!is_arj_archive(fd)) {
1008
if (!is_arj_archive(metadata)) {
1047
1009
cli_dbgmsg("Not in ARJ format\n");
1048
1010
return CL_EFORMAT;
1050
return arj_read_file_header(fd, metadata);
1012
return arj_read_file_header(metadata);
1053
int cli_unarj_extract_file(int fd, const char *dirname, arj_metadata_t *metadata)
1015
int cli_unarj_extract_file(const char *dirname, arj_metadata_t *metadata)
1056
1018
int ret = CL_SUCCESS;
1057
1019
char filename[1024];
1059
1021
cli_dbgmsg("in cli_unarj_extract_file\n");
1060
if (!metadata || !dirname || (fd < 0)) {
1022
if (!metadata || !dirname) {
1061
1023
return CL_ENULLARG;
1064
1026
if (metadata->encrypted) {
1065
1027
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) {
1028
metadata->offset += metadata->comp_size;
1029
cli_dbgmsg("Target offset: %lu\n", (unsigned long int) metadata->offset);
1071
1030
return CL_SUCCESS;
1074
1033
snprintf(filename, 1024, "%s"PATHSEP"file.uar", dirname);
1075
1034
cli_dbgmsg("Filename: %s\n", filename);
1076
1035
metadata->ofd = open(filename, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, 0600);
1080
1039
switch (metadata->method) {
1082
ret = arj_unstore(fd, metadata->ofd, metadata->comp_size);
1083
if (ret != metadata->comp_size) {
1041
ret = arj_unstore(metadata, metadata->ofd, metadata->comp_size);
1092
ret = decode(fd, metadata);
1046
ret = decode(metadata);
1095
ret = decode_f(fd, metadata);
1049
ret = decode_f(metadata);
1098
1052
ret = CL_EFORMAT;