int decrunch_gzip(FILE *in, FILE *out) { struct member member; int val, c; uint32 crc; crc32_init_A(); member.id1 = read8(in); member.id2 = read8(in); member.cm = read8(in); member.flg = read8(in); member.mtime = read32l(in); member.xfl = read8(in); member.os = read8(in); if (member.cm != 0x08) { return -1; } if (member.flg & FLAG_FEXTRA) { int xlen = read16l(in); fseek(in, xlen, SEEK_CUR); } if (member.flg & FLAG_FNAME) { do { c = read8(in); } while (c != 0); } if (member.flg & FLAG_FCOMMENT) { do { c = read8(in); } while (c != 0); } if (member.flg & FLAG_FHCRC) { read16l(in); } val = inflate(in, out, &crc, 1); if (val != 0) { return -1; } /* Check CRC32 */ val = read32l(in); if (val != crc) { return -1; } /* Check file size */ val = read32l(in); if (val != ftell(out)) { return -1; } return 0; }
static int decrunch_xz(FILE *in, FILE *out) { struct xz_buf b; struct xz_dec *state; unsigned char *membuf; int ret = 0; crc32_init_A(); memset(&b, 0, sizeof(b)); if ((membuf = malloc(2 * BUFFER_SIZE)) == NULL) return -1; b.in = membuf; b.out = membuf + BUFFER_SIZE; b.out_size = BUFFER_SIZE; /* Limit memory usage to 16M */ state = xz_dec_init(XZ_DYNALLOC, 16 * 1024 * 1024); while (1) { enum xz_ret r; if (b.in_pos == b.in_size) { int rd = fread(membuf, 1, BUFFER_SIZE, in); if (rd < 0) { ret = -1; break; } b.in_size = rd; b.in_pos = 0; } r = xz_dec_run(state, &b); if (b.out_pos) { fwrite(b.out, 1, b.out_pos, out); b.out_pos = 0; } if (r == XZ_STREAM_END) { break; } if (r != XZ_OK && r != XZ_UNSUPPORTED_CHECK) { ret = -1; break; } } xz_dec_end(state); free(membuf); return ret; }