decompress.c revision 9e6e15042fe8eed186bfa123fa6d79d7728f0ade
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * CDDL HEADER START
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * The contents of this file are subject to the terms of the
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * Common Development and Distribution License (the "License").
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * You may not use this file except in compliance with the License.
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * See the License for the specific language governing permissions
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * and limitations under the License.
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * When distributing Covered Code, include this CDDL HEADER in each
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * If applicable, add the following below this CDDL HEADER, with the
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * fields enclosed by brackets "[]" replaced with your own identifying
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * information: Portions Copyright [yyyy] [name of copyright owner]
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * CDDL HEADER END
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * Use is subject to license terms.
ae115bc77f6fcde83175c75b4206dc2e50747966mrj#pragma ident "%Z%%M% %I% %E% SMI"
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * Decompression module for stand alone file systems.
ae115bc77f6fcde83175c75b4206dc2e50747966mrj#include "../common/util.h"
ae115bc77f6fcde83175c75b4206dc2e50747966mrjcaddr_t scratch_bufs[MAX_DECOMP_BUFS]; /* array of free scratch mem bufs */
ae115bc77f6fcde83175c75b4206dc2e50747966mrjint decomp_bufcnt; /* total no, of allocated decomp bufs */
ae115bc77f6fcde83175c75b4206dc2e50747966mrjcf_alloc(void *opaque, unsigned int items, unsigned int size)
ae115bc77f6fcde83175c75b4206dc2e50747966mrj unsigned int nbytes;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * Decompression scratch memory free routine, does nothing since we free
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * the entire scratch area all at once on file close.
ae115bc77f6fcde83175c75b4206dc2e50747966mrj/* ARGSUSED */
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * Read the first block of the file described by filep and determine if
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * the file is gzip-compressed. If so, the compressed flag will be set
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * in the fileid_t struct pointed to by filep and it will be initialized
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * for doing decompression on reads to the file.
ae115bc77f6fcde83175c75b4206dc2e50747966mrj unsigned char *filebytes;
9e6e15042fe8eed186bfa123fa6d79d7728f0adesmaybe * If the file is not long enough to check for a decompression header
9e6e15042fe8eed186bfa123fa6d79d7728f0adesmaybe * then return not compressed.
9e6e15042fe8eed186bfa123fa6d79d7728f0adesmaybe return (0);
ae115bc77f6fcde83175c75b4206dc2e50747966mrj return (-1);
ae115bc77f6fcde83175c75b4206dc2e50747966mrj if (filebytes[0] != GZIP_ID_BYTE_1 || filebytes[1] != GZIP_ID_BYTE_2 ||
ae115bc77f6fcde83175c75b4206dc2e50747966mrj return (0); /* not compressed */
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * Allocate decompress scratch buffer
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * Initialize the decompression stream
ae115bc77f6fcde83175c75b4206dc2e50747966mrj return (-1);
ae115bc77f6fcde83175c75b4206dc2e50747966mrj return (0);
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * If the file described by fileid_t struct at *filep is compressed
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * free any resources associated with the decompression. (decompression
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * buffer, etc.).
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * Calculate the header length of a gzip compressed file
ae115bc77f6fcde83175c75b4206dc2e50747966mrj unsigned char flag;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj hlen += strlen((char *)&hp[hlen]) + 1; /* skip file name */
ae115bc77f6fcde83175c75b4206dc2e50747966mrj hlen += strlen((char *)&hp[hlen]) + 1; /* skip comment */
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * Read at the current uncompressed offset from the compressed file described
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * by *filep. Will return decompressed data.
ae115bc77f6fcde83175c75b4206dc2e50747966mrj if (zsp->avail_in == 0 && filep->fi_cfoff < ip->i_size) {
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * read a block of the file to inflate
ae115bc77f6fcde83175c75b4206dc2e50747966mrj return (-1);
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * If we are reading the first block of the file, we
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * need to skip over the header bytes before inflating
ae115bc77f6fcde83175c75b4206dc2e50747966mrj dprintf("attempting inflate of %x bytes to buf at: %lx\n",
ae115bc77f6fcde83175c75b4206dc2e50747966mrj dprintf("inflated %x bytes, errcode=%d\n", infbytes, err);
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * break out if we hit end of the compressed file
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * or the end of the compressed byte stream
ae115bc77f6fcde83175c75b4206dc2e50747966mrj if (filep->fi_cfoff >= ip->i_size || err == Z_STREAM_END)
ae115bc77f6fcde83175c75b4206dc2e50747966mrj dprintf("cf_read: returned %lx bytes\n", count - zsp->avail_out);
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * Seek to the location specified by addr
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * To seek backwards, must rewind and seek forwards
ae115bc77f6fcde83175c75b4206dc2e50747966mrj while (addr > 0) {