#include #include /* * gzip support routine declartions.. * ========================================================= */ #ifdef DEBUG # define Trace(x) # define Tracev(x) # define Tracevv(x) # define Tracec(c,x) # define Tracecv(c,x) # define DBG(x) printf x #else # define Trace(x) # define Tracev(x) # define Tracevv(x) # define Tracec(c,x) # define Tracecv(c,x) # define DBG(x) #endif void error(char *str) { DBG(("%s\n", str)); } static unsigned char *inbuf; /* input buffer */ static unsigned int insize; /* valid bytes in inbuf */ static unsigned int inptr; /* index of next byte to be processed in inbuf */ #if !defined(DEBUG) #define get_byte() (inptr < insize ? inbuf[inptr++] : 0) #else static unsigned char get_byte(void) { static int count; unsigned char byte = (inptr < insize ? inbuf[inptr++] : 0); #if 0 printf("%02x ", byte); if ((++count & 0x0f) == 0) { printf("\n"); } #endif return byte; } #endif static void flush_window(void); static long bytes_out; /* total bytes compressed */ static unsigned outcnt; /* bytes in output buffer */ #define WSIZE 0x8000 /* Window size must be at least 32k, and a power of two */ static unsigned char window[WSIZE]; /* Sliding window buffer */ /* * gzip declarations */ #define OF(args) args #define STATIC static #define memzero(s, n) memset ((s), 0, (n)) typedef unsigned char uch; typedef unsigned short ush; typedef unsigned long ulg; #include "inflate.c" /* Variables that gunzip doesn't need to see... */ static unsigned char *output_ptr; static unsigned long end_offset; static struct unzip_region { unsigned long start; unsigned long end_offset; } unzip_region; /* Data provided by the header */ extern unsigned char zipped_data[]; extern unsigned char zipped_data_end[]; extern unsigned char entry; /* Assembly language routines */ extern void jmp_to_program_entry(void *); /* =========================================================================== * Write the output window window[0..outcnt-1] and update crc and bytes_out. * (Used for the decompressed data only.) */ static void flush_window(void) { ulg c = crc; /* temporary variable */ unsigned n; unsigned long limit; uch *in, *out, ch; limit = outcnt; n = 0; in = window; while (n < outcnt) { limit = end_offset - bytes_out +n; if (limit > outcnt) { limit = outcnt; } out = output_ptr; DBG(("flush 0x%08lx start 0x%08lx limit 0x%08lx\n", (unsigned long) out, (unsigned long)n, limit)); for (; n < limit; n++) { ch = *out++ = *in++; c = crc_32_tab[((int) c ^ ch) & 0xff] ^ (c >> 8); } crc = c; bytes_out += (out - output_ptr); output_ptr = out; if (bytes_out == end_offset) { if (output_ptr == (unsigned char *)(&unzip_region+1)) { output_ptr = (unsigned char *)(unzip_region.start); end_offset = unzip_region.end_offset; } else { output_ptr = (unsigned char *)&unzip_region; end_offset += sizeof(unzip_region); } } } outcnt = 0; } void gunzip_setup(void) { DBG(("gunzip_setup\n")); outcnt = 0; bytes_out = 0; end_offset = sizeof(unzip_region); output_ptr = (unsigned char *)&unzip_region; inbuf = &zipped_data[0]; insize = zipped_data_end - zipped_data; inptr = 0; makecrc(); DBG(("gunzip_setup_done\n")); } int kunzip(int argc, char **argv) { DBG(("kunzip\n")); gunzip_setup(); DBG(("pre_gunzip\n")); if (gunzip() != 0) { error("gunzip failed"); while(1) {} return -1; } DBG(("pre_jmp_to_program_entry: %p\n", &entry )); jmp_to_program_entry(&entry); return 0; }