1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
|
#include <string.h>
#include <stdlib.h>
/*
* 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;
}
|