/*
* Copyright (c) 2002 Wasabi Systems, Inc.
* All rights reserved.
*
* Written by Jason R. Thorpe for Wasabi Systems, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed for the NetBSD Project by
* Wasabi Systems, Inc.
* 4. The name of Wasabi Systems, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* The Gzip header parser and libz interface glue are derived from
* sys/lib/libsa/cread.c, which carries the following notice:
*
* Copyright (c) 1996
* Matthias Drochner. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* gzip flag byte */
#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */
#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
#define COMMENT 0x10 /* bit 4 set: file comment present */
#define RESERVED 0xe0 /* bits 5..7: reserved */
struct state {
z_stream stream;
int z_err; /* error code for last stream operation */
int z_eof; /* set of end of input file */
const unsigned char *srcbuf;/* source buffer */
size_t srcoff; /* source buffer offset */
size_t srcsize;/* size of source buffer */
unsigned char *inbuf; /* input buffer */
uint32_t crc; /* crc32 of uncompressed data */
int spinny; /* twiddle every N reads */
};
static uint32_t get_u8(struct state *);
static uint32_t get_u32(struct state *);
static int check_header(struct state *);
/* XXX - find a suitable header for these: */
void zmemcpy(unsigned char *, unsigned char *, unsigned int);
/*
* If md_root_size is 0, then it means that we are simply
* decompressing from an image which was concatenated onto
* the end of the gzboot binary.
*/
#ifdef GZSRCADDR
printf(">> Image address: %p\n", compressed_image);
#endif
if (md_root_size != 0)
printf(">> Image size: %u\n", md_root_size);
static uint32_t
get_u32(struct state *s)
{
uint32_t x, c;
x = get_u8(s);
x |= get_u8(s) << 8;
x |= get_u8(s) << 16;
c = get_u8(s);
if (c == EOF)
s->z_err = Z_DATA_ERROR;
x |= c << 24;
return (x);
}
static int
check_header(struct state *s)
{
int method; /* method byte */
int flags; /* flags byte */
unsigned int len;
int c;
/* Check the gzip magic header */
for (len = 0; len < 2; len++) {
c = get_u8(s);
if (c == gz_magic[len])
continue;
printf("FATAL: not a Gzip'd image\n");
return (1);
}
/* Discard time, xflags, and OS code: */
for (len = 0; len < 6; len++)
(void) get_u8(s);
if (flags & EXTRA_FIELD) {
/* skip the extra field */
len = get_u8(s);
len |= get_u8(s) << 8;
/* len is garbage if EOF, but the loop below will quit anyway */
while (len-- && get_u8(s) != EOF)
/* loop */;
}
if (flags & ORIG_NAME) {
/* skip the original file name */
while ((c = get_u8(s)) != 0 && c != EOF)
/* loop */;
}
if (flags & COMMENT) {
/* skip the file comment */
while ((c = get_u8(s)) != 0 && c != EOF)
/* loop */;
}
if (flags & HEAD_CRC) {
/* skip header CRC */
for (len = 0; len < 2; len++)
(void) get_u8(s);
}
if (s->z_eof) {
printf("FATAL: end of image encountered parsing Gzip header\n");
return (1);
}