115 int ignore_cksum,
int ignore_blocksize);
117 unsigned char *data,
unsigned int bytes,
unsigned int cksum);
160 self->searchbuf_size = 32768;
162 self->buf_size = 4096;
178 if (self->d->infh) sys->
close(self->d->infh);
201 if (!base)
return NULL;
247 for (fi = origcab->
files; fi; fi = nfi) {
254 for (fol = origcab->
folders; fol; fol = nfol) {
259 if (self->d->infh) sys->
close(self->d->infh);
274 for (cab = origcab; cab; cab = ncab) {
280 if (cab != origcab) sys->
free(cab);
284 for (cab = origcab->
nextcab; cab; cab = ncab) {
314 int num_folders, num_files, folder_resv,
i,
x,
err, fidx;
317 unsigned char buf[64];
351 if (num_folders == 0) {
352 if (!quiet) sys->
message(
fh,
"no folders in cabinet.");
358 if (num_files == 0) {
359 if (!quiet) sys->
message(
fh,
"no files in cabinet.");
365 if (!quiet) sys->
message(
fh,
"WARNING; cabinet version is not 1.3");
380 if (!quiet) sys->
message(
fh,
"WARNING; reserved header > 60000.");
413 for (
i = 0;
i < num_folders;
i++) {
443 for (
i = 0;
i < num_files;
i++) {
461 if (fidx < num_folders) {
463 while (fidx--)
if (ifol) ifol = ifol->
next;
467 D((
"invalid folder index"))
479 while (ifol->
next) ifol = ifol->
next;
501 file->time_h =
x >> 11;
502 file->time_m = (
x >> 5) & 0x3F;
503 file->time_s = (
x << 1) & 0x3E;
507 file->date_d =
x & 0x1F;
508 file->date_m = (
x >> 5) & 0xF;
509 file->date_y = (
x >> 9) + 1980;
518 if (salvage)
continue;
531 D((
"No files found, even though header claimed to have %d files", num_files))
555 if (
i == 0 && !permit_empty)
ok = 0;
601 if (!base)
return NULL;
605 search_buf = (
unsigned char *) sys->
alloc(sys, (
size_t)
self->searchbuf_size);
619 if (firstlen && (firstlen !=
filelen) &&
624 " extra bytes at end of file.",
628 sys->
message(
fh,
"WARNING; file possibly truncated by %" LD " bytes.",
652 unsigned char *
p, *pend,
state = 0;
653 unsigned int cablen_u32 = 0, foffset_u32 = 0;
659 sys->
message(
fh,
"library not compiled to support large files.");
669 if (
length > self->searchbuf_size) {
670 length =
self->searchbuf_size;
680 sys->
message(
fh,
"WARNING; found InstallShield header. Use unshield "
681 "(https://github.com/twogood/unshield) to unpack this file");
691 while (
p < pend && *
p != 0x4D)
p++;
693 if (
p++ < pend)
state = 1;
697 case 1:
state = (*
p++ == 0x53) ? 2 : 0;
break;
698 case 2:
state = (*
p++ == 0x43) ? 3 : 0;
break;
699 case 3:
state = (*
p++ == 0x46) ? 4 : 0;
break;
704 case 8: cablen_u32 = *
p++;
state++;
break;
705 case 9: cablen_u32 |= *
p++ << 8;
state++;
break;
706 case 10: cablen_u32 |= *
p++ << 16;
state++;
break;
707 case 11: cablen_u32 |= *
p++ << 24;
state++;
break;
712 case 16: foffset_u32 = *
p++;
state++;
break;
713 case 17: foffset_u32 |= *
p++ << 8;
state++;
break;
714 case 18: foffset_u32 |= *
p++ << 16;
state++;
break;
715 case 19: foffset_u32 |= *
p++ << 24;
726 if (caboff == 0) *firstlen = (
off_t) cablen_u32;
732 if ((foffset_u32 < cablen_u32) &&
733 ((caboff + (
off_t) foffset_u32) < (flen + 32)) &&
734 (((caboff + (
off_t) cablen_u32) < (flen + 32)) ||
self->salvage))
751 if (!
link) *firstcab = cab;
761 sys->
message(
fh,
"library not compiled to support large files.");
786 D((
"%d false cabinets found", false_cabs))
829 if (!lcab || !rcab || (lcab == rcab)) {
830 D((
"lcab NULL, rcab NULL or lcab = rcab"))
836 D((
"cabs already joined"))
850 sys->
message(
NULL,
"WARNING; merged cabinets with differing Set IDs.");
854 sys->
message(
NULL,
"WARNING; merged cabinets with odd order.");
895 while (ndata->
next) ndata = ndata->
next;
925 for (fi = lcab->
files; fi ; fi = rfi) {
929 if (lfi) lfi->
next = rfi;
else lcab->
files = rfi;
962 D((
"folder merge: compression type mismatch"))
968 D((
"folder merge: too many data blocks in merged folders"))
973 D((
"folder merge: one cabinet has no files to merge"))
981 for (l=lfi,
r=rfi; l; l=l->
next,
r=
r->next) {
988 if (matching)
return 1;
994 for (l = lfi; l; l = l->
next) {
995 for (
r = rfi;
r;
r =
r->next) {
999 "WARNING; merged file %s not listed in both cabinets", l->
filename);
1035 if (self->salvage) {
1045 sys->
message(
NULL,
"ERROR; file \"%s\" cannot be extracted, "
1046 "cabinet set is incomplete",
file->filename);
1053 if (!self->salvage) {
1056 sys->
message(
NULL,
"ERROR; file \"%s\" cannot be extracted, "
1057 "cabinet set is incomplete",
file->filename);
1066 self->d->folder =
NULL;
1067 self->d->data =
NULL;
1068 self->d->sys = *
sys;
1071 self->d->state =
NULL;
1072 self->d->infh =
NULL;
1073 self->d->incab =
NULL;
1077 if ((self->d->folder != fol) || (
self->d->offset >
file->offset) ||
1084 if (!self->d->infh || (fol->
data.
cab != self->d->incab)) {
1086 if (self->d->infh)
sys->
close(self->d->infh);
1087 self->d->incab = fol->
data.
cab;
1103 self->d->folder = fol;
1107 self->d->outlen = 0;
1108 self->d->i_ptr =
self->d->i_end = &
self->d->input[0];
1130 self->d->outfh =
NULL;
1131 if ((
bytes =
file->offset - self->d->offset)) {
1132 error =
self->d->decompress(self->d->state,
bytes);
1138 self->d->outfh =
fh;
1146 self->d->outfh =
NULL;
1165 self->d->comp_type = ct;
1170 self->d->state =
noned_init(&self->d->sys,
fh,
fh, self->buf_size);
1179 self->d->state =
qtmd_init(&self->d->sys,
fh,
fh, (
int) (ct >> 8) & 0x1f,
1184 self->d->state =
lzxd_init(&self->d->sys,
fh,
fh, (
int) (ct >> 8) & 0x1f, 0,
1185 self->buf_size, (
off_t)0,0);
1194 if (!
self || !self->d || !self->d->state)
return;
1202 self->d->decompress =
NULL;
1203 self->d->state =
NULL;
1220 unsigned char *
buf = (
unsigned char *)
buffer;
1222 int avail, todo, outlen, ignore_cksum, ignore_blocksize;
1224 ignore_cksum =
self->salvage ||
1227 ignore_blocksize =
self->salvage;
1231 avail =
self->d->i_end -
self->d->i_ptr;
1236 if (avail > todo) avail = todo;
1237 sys->
copy(self->d->i_ptr,
buf, (
size_t) avail);
1238 self->d->i_ptr += avail;
1246 if (self->d->block++ >= self->d->folder->base.num_blocks) {
1247 if (!self->salvage) {
1251 D((
"Ran out of CAB input blocks prematurely"))
1258 ignore_cksum, ignore_blocksize);
1259 if (self->read_error)
return -1;
1260 self->d->outlen += outlen;
1266 *
self->d->i_end++ = 0xFF;
1270 if (self->d->block >= self->d->folder->base.num_blocks) {
1279 return bytes - todo;
1284 self->d->offset +=
bytes;
1285 if (self->d->outfh) {
1286 return self->system->write(self->d->outfh,
buffer,
bytes);
1299 int *
out,
int ignore_cksum,
1300 int ignore_blocksize)
1307 d->i_ptr =
d->i_end = &
d->input[0];
1316 if (
d->data->cab->block_resv &&
1317 sys->
seek(
d->infh, (
off_t)
d->data->cab->block_resv,
1325 full_len = (
d->i_end -
d->i_ptr) +
len;
1327 D((
"block size %d > CAB_INPUTMAX", full_len));
1336 D((
"block size > CAB_BLOCKMAX"))
1350 sys->
message(
d->infh,
"WARNING; bad block checksum found");
1374 if (!(
d->data =
d->data->next)) {
1375 sys->
message(
d->infh,
"WARNING; ran out of cabinets in set. Are any missing?");
1380 d->incab =
d->data->cab;
1381 if (!(
d->infh = sys->
open(sys,
d->incab->base.filename,
1400 unsigned int len, ul = 0;
1403 unsigned int byte0 = data[0];
1404 unsigned int byte1 = ((
unsigned int)data[1]) << 8;
1405 unsigned int byte2 = ((
unsigned int)data[2]) << 16;
1406 unsigned int byte3 = ((
unsigned int)data[3]) << 24;
1407 cksum ^= (byte0 | byte1 | byte2 | byte3);
1410 switch (
bytes & 3) {
1411 case 3: ul |= *data++ << 16;
1412 case 2: ul |= *data++ << 8;
1413 case 1: ul |= *data;
1488 self->searchbuf_size =
value;
1491 self->fix_mszip =
value;
1495 self->buf_size =
value;
1498 self->salvage =
value;
const lzma_allocator const uint8_t * in
const lzma_allocator const uint8_t size_t uint8_t * out
unsigned char search_buf[SEARCH_SIZE]
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec struct timespec static rem const char static group const void length
static static fork const void static count static fd link
static int run(int i, const char *arg)
z_const unsigned char * next
struct mscab_decompressor base
struct mscabd_cabinet base
struct mscabd_cabinet * next
unsigned short header_resv
struct mscabd_cabinet * prevcab
struct mscabd_folder * folders
struct mscabd_file * files
struct mscabd_cabinet * nextcab
struct mscabd_file * next
struct mscabd_folder * folder
struct mscabd_cabinet_p * cab
struct mscabd_folder_data * next
struct mscabd_folder base
struct mscabd_folder_data data
struct mscabd_file * merge_next
struct mscabd_file * merge_prev
struct mscabd_folder * next
void(* copy)(void *src, void *dest, size_t bytes)
void(* close)(struct mspack_file *file)
struct mspack_file *(* open)(struct mspack_system *self, const char *filename, int mode)
void(* message)(struct mspack_file *file, const char *format,...)
int(* seek)(struct mspack_file *file, off_t offset, int mode)
int(* read)(struct mspack_file *file, void *buffer, int bytes)
off_t(* tell)(struct mspack_file *file)
void *(* alloc)(struct mspack_system *self, size_t bytes)
struct mspack_system * sys
void error(const char *msg)
if(dbg->bits==RZ_SYS_BITS_64)