示例#1
0
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;
}
示例#2
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;
}
示例#3
0
/* 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;
}