0001
0002 #ifdef STATIC
0003 #define PREBOOT
0004
0005
0006
0007
0008 #define _LINUX_KERNEL_H
0009
0010 #include "zlib_inflate/inftrees.c"
0011 #include "zlib_inflate/inffast.c"
0012 #include "zlib_inflate/inflate.c"
0013 #ifdef CONFIG_ZLIB_DFLTCC
0014 #include "zlib_dfltcc/dfltcc.c"
0015 #include "zlib_dfltcc/dfltcc_inflate.c"
0016 #endif
0017
0018 #else
0019
0020
0021 #include <linux/zutil.h>
0022
0023 #include "zlib_inflate/inftrees.h"
0024 #include "zlib_inflate/inffast.h"
0025 #include "zlib_inflate/inflate.h"
0026
0027 #include "zlib_inflate/infutil.h"
0028 #include <linux/decompress/inflate.h>
0029
0030 #endif
0031
0032 #include <linux/decompress/mm.h>
0033
0034 #define GZIP_IOBUF_SIZE (16*1024)
0035
0036 static long INIT nofill(void *buffer, unsigned long len)
0037 {
0038 return -1;
0039 }
0040
0041
0042 STATIC int INIT __gunzip(unsigned char *buf, long len,
0043 long (*fill)(void*, unsigned long),
0044 long (*flush)(void*, unsigned long),
0045 unsigned char *out_buf, long out_len,
0046 long *pos,
0047 void(*error)(char *x)) {
0048 u8 *zbuf;
0049 struct z_stream_s *strm;
0050 int rc;
0051
0052 rc = -1;
0053 if (flush) {
0054 out_len = 0x8000;
0055 out_buf = malloc(out_len);
0056 } else {
0057 if (!out_len)
0058 out_len = ((size_t)~0) - (size_t)out_buf;
0059 }
0060 if (!out_buf) {
0061 error("Out of memory while allocating output buffer");
0062 goto gunzip_nomem1;
0063 }
0064
0065 if (buf)
0066 zbuf = buf;
0067 else {
0068 zbuf = malloc(GZIP_IOBUF_SIZE);
0069 len = 0;
0070 }
0071 if (!zbuf) {
0072 error("Out of memory while allocating input buffer");
0073 goto gunzip_nomem2;
0074 }
0075
0076 strm = malloc(sizeof(*strm));
0077 if (strm == NULL) {
0078 error("Out of memory while allocating z_stream");
0079 goto gunzip_nomem3;
0080 }
0081
0082 strm->workspace = malloc(flush ? zlib_inflate_workspacesize() :
0083 #ifdef CONFIG_ZLIB_DFLTCC
0084
0085 zlib_inflate_workspacesize());
0086 #else
0087 sizeof(struct inflate_state));
0088 #endif
0089 if (strm->workspace == NULL) {
0090 error("Out of memory while allocating workspace");
0091 goto gunzip_nomem4;
0092 }
0093
0094 if (!fill)
0095 fill = nofill;
0096
0097 if (len == 0)
0098 len = fill(zbuf, GZIP_IOBUF_SIZE);
0099
0100
0101 if (len < 10 ||
0102 zbuf[0] != 0x1f || zbuf[1] != 0x8b || zbuf[2] != 0x08) {
0103 if (pos)
0104 *pos = 0;
0105 error("Not a gzip file");
0106 goto gunzip_5;
0107 }
0108
0109
0110
0111
0112 strm->next_in = zbuf + 10;
0113 strm->avail_in = len - 10;
0114
0115 if (zbuf[3] & 0x8) {
0116 do {
0117
0118
0119
0120
0121
0122 if (strm->avail_in == 0) {
0123 error("header error");
0124 goto gunzip_5;
0125 }
0126 --strm->avail_in;
0127 } while (*strm->next_in++);
0128 }
0129
0130 strm->next_out = out_buf;
0131 strm->avail_out = out_len;
0132
0133 rc = zlib_inflateInit2(strm, -MAX_WBITS);
0134
0135 #ifdef CONFIG_ZLIB_DFLTCC
0136
0137 #else
0138 if (!flush) {
0139 WS(strm)->inflate_state.wsize = 0;
0140 WS(strm)->inflate_state.window = NULL;
0141 }
0142 #endif
0143
0144 while (rc == Z_OK) {
0145 if (strm->avail_in == 0) {
0146
0147 len = fill(zbuf, GZIP_IOBUF_SIZE);
0148 if (len < 0) {
0149 rc = -1;
0150 error("read error");
0151 break;
0152 }
0153 strm->next_in = zbuf;
0154 strm->avail_in = len;
0155 }
0156 rc = zlib_inflate(strm, 0);
0157
0158
0159 if (flush && strm->next_out > out_buf) {
0160 long l = strm->next_out - out_buf;
0161 if (l != flush(out_buf, l)) {
0162 rc = -1;
0163 error("write error");
0164 break;
0165 }
0166 strm->next_out = out_buf;
0167 strm->avail_out = out_len;
0168 }
0169
0170
0171 if (rc == Z_STREAM_END) {
0172 rc = 0;
0173 break;
0174 } else if (rc != Z_OK) {
0175 error("uncompression error");
0176 rc = -1;
0177 }
0178 }
0179
0180 zlib_inflateEnd(strm);
0181 if (pos)
0182
0183 *pos = strm->next_in - zbuf+8;
0184
0185 gunzip_5:
0186 free(strm->workspace);
0187 gunzip_nomem4:
0188 free(strm);
0189 gunzip_nomem3:
0190 if (!buf)
0191 free(zbuf);
0192 gunzip_nomem2:
0193 if (flush)
0194 free(out_buf);
0195 gunzip_nomem1:
0196 return rc;
0197 }
0198
0199 #ifndef PREBOOT
0200 STATIC int INIT gunzip(unsigned char *buf, long len,
0201 long (*fill)(void*, unsigned long),
0202 long (*flush)(void*, unsigned long),
0203 unsigned char *out_buf,
0204 long *pos,
0205 void (*error)(char *x))
0206 {
0207 return __gunzip(buf, len, fill, flush, out_buf, 0, pos, error);
0208 }
0209 #else
0210 STATIC int INIT __decompress(unsigned char *buf, long len,
0211 long (*fill)(void*, unsigned long),
0212 long (*flush)(void*, unsigned long),
0213 unsigned char *out_buf, long out_len,
0214 long *pos,
0215 void (*error)(char *x))
0216 {
0217 return __gunzip(buf, len, fill, flush, out_buf, out_len, pos, error);
0218 }
0219 #endif