int gunzip(const void *src, int size, void **uncomp, long *uncomp_size) { int r; long bsize; void *tmp; long data_start; z_stream zs; memset(&zs, 0, sizeof(zs)); *uncomp = 0; bsize = 0; data_start = skip_gzip_header(src, size); if (data_start == -1) return -1; zs.next_in = (void *)(src + data_start); zs.avail_in = size - data_start; printf("monte: uncompressing..."); fflush(0); /* wackiness required for gzip */ if (inflateInit2(&zs, -MAX_WBITS) != Z_OK) return -1; do { if (zs.avail_out == 0) { tmp = realloc(*uncomp, bsize+CHUNK); if (!tmp) { if (*uncomp) free(*uncomp); inflateEnd(&zs); } *uncomp = tmp; zs.next_out = (*uncomp)+bsize; zs.avail_out = CHUNK; bsize += CHUNK; } if (zs.avail_in == 0) { /* Barf */ fprintf(stderr, "Out of data unzipping.\n"); if (*uncomp) free(*uncomp); inflateEnd(&zs); return -1; } r = inflate(&zs, Z_NO_FLUSH); } while (r == Z_OK); if (r != Z_STREAM_END) { /* Barf */ fprintf(stderr, "Decompression error.\n"); if (*uncomp) free(*uncomp); inflateEnd(&zs); return -1; } printf("done\n"); inflateEnd(&zs); *uncomp_size = zs.total_out; return 0; }
status_t TarFS::Volume::_Inflate(boot::Partition* partition, void* cookie, off_t offset, RegionDeleter& regionDeleter, size_t* inflatedBytes) { char in[2048]; z_stream zStream = { (Bytef*)in, // next in sizeof(in), // avail in 0, // total in NULL, // next out 0, // avail out 0, // total out 0, // msg 0, // state Z_NULL, // zalloc Z_NULL, // zfree Z_NULL, // opaque 0, // data type 0, // adler 0, // reserved }; int status; char* out = (char*)regionDeleter.Get(); bool headerRead = false; do { ssize_t bytesRead = partition->ReadAt(cookie, offset, in, sizeof(in)); if (bytesRead != (ssize_t)sizeof(in)) { if (bytesRead <= 0) { status = Z_STREAM_ERROR; break; } } zStream.avail_in = bytesRead; zStream.next_in = (Bytef*)in; if (!headerRead) { // check and skip gzip header if (!skip_gzip_header(&zStream)) return B_BAD_DATA; headerRead = true; if (!out) { // allocate memory for the uncompressed data if (platform_allocate_region((void**)&out, kTarRegionSize, B_READ_AREA | B_WRITE_AREA, false) != B_OK) { TRACE(("tarfs: allocating region failed!\n")); return B_NO_MEMORY; } regionDeleter.SetTo(out); } zStream.avail_out = kTarRegionSize; zStream.next_out = (Bytef*)out; status = inflateInit2(&zStream, -15); if (status != Z_OK) return B_ERROR; } status = inflate(&zStream, Z_SYNC_FLUSH); offset += bytesRead; if (zStream.avail_in != 0 && status != Z_STREAM_END) dprintf("tarfs: didn't read whole block: %s\n", zStream.msg); } while (status == Z_OK); inflateEnd(&zStream); if (status != Z_STREAM_END) { TRACE(("tarfs: inflating failed: %d!\n", status)); return B_BAD_DATA; } *inflatedBytes = zStream.total_out; return B_OK; }
/* Try to open a file for reading. If the filename ends in one of the defined compressor extensions, pipe the file through the decompressor */ struct timidity_file *try_to_open(char *name, int decompress) { struct timidity_file *tf; URL url; int len; if((url = url_arc_open(name)) == NULL) if((url = url_open(name)) == NULL) return NULL; tf = (struct timidity_file *)safe_malloc(sizeof(struct timidity_file)); tf->url = url; tf->tmpname = NULL; len = strlen(name); if(decompress && len >= 3 && strcasecmp(name + len - 3, ".gz") == 0) { int method; if(!IS_URL_SEEK_SAFE(tf->url)) { if((tf->url = url_cache_open(tf->url, 1)) == NULL) { close_file(tf); return NULL; } } method = skip_gzip_header(tf->url); if(method == ARCHIVEC_DEFLATED) { url_cache_disable(tf->url); if((tf->url = url_inflate_open(tf->url, -1, 1)) == NULL) { close_file(tf); return NULL; } /* success */ return tf; } /* fail */ url_rewind(tf->url); url_cache_disable(tf->url); } #ifdef __W32__ /* Sorry, DECOMPRESSOR_LIST and PATCH_CONVERTERS are not worked yet. */ return tf; #endif /* __W32__ */ #if defined(DECOMPRESSOR_LIST) if(decompress) { static char *decompressor_list[] = DECOMPRESSOR_LIST, **dec; char tmp[1024]; /* Check if it's a compressed file */ for(dec = decompressor_list; *dec; dec += 2) { if(!check_file_extension(name, *dec, 0)) continue; tf->tmpname = url_dumpfile(tf->url, *dec); if (tf->tmpname == NULL) { close_file(tf); return NULL; } url_close(tf->url); snprintf(tmp, sizeof(tmp), *(dec+1), tf->tmpname); if((tf->url = url_pipe_open(tmp)) == NULL) { close_file(tf); return NULL; } break; } } #endif /* DECOMPRESSOR_LIST */ #if defined(PATCH_CONVERTERS) if(decompress == 2) { static char *decompressor_list[] = PATCH_CONVERTERS, **dec; char tmp[1024]; /* Check if it's a compressed file */ for(dec = decompressor_list; *dec; dec += 2) { if(!check_file_extension(name, *dec, 0)) continue; tf->tmpname = url_dumpfile(tf->url, *dec); if (tf->tmpname == NULL) { close_file(tf); return NULL; } url_close(tf->url); sprintf(tmp, *(dec+1), tf->tmpname); if((tf->url = url_pipe_open(tmp)) == NULL) { close_file(tf); return NULL; } break; } } #endif /* PATCH_CONVERTERS */ return tf; }